0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-03-11 02:15:57 -05:00

fix: error when writing tarball (missing folder) (#4594)

* fix: error when writing tarball (missing folder)

* changeset
This commit is contained in:
Marc Bernard 2024-04-25 19:06:51 +02:00 committed by GitHub
parent 4ac3aead4f
commit 1bae121dc2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 41 additions and 6 deletions

View file

@ -0,0 +1,5 @@
---
'@verdaccio/local-storage': patch
---
fix: error when writing tarball (missing folder)

View file

@ -237,6 +237,7 @@ export default class LocalFS implements ILocalFSPackageManager {
public async writeTarball(fileName: string, { signal }): Promise<Writable> {
debug('write a tarball %o', fileName);
const pathName: string = this._getStorage(fileName);
await this.checkCreateFolder(pathName);
// create a temporary file to avoid conflicts or prev corruption files
const temporalName = path.join(
this.path,
@ -352,8 +353,8 @@ export default class LocalFS implements ILocalFSPackageManager {
private async writeTempFileAndRename(dest: string, fileContent: string): Promise<any> {
const tempFilePath = tempFile(dest);
try {
// write file on temp locatio
// TODO: we need to handle when directory does not exist
// write file on temp location
await this.checkCreateFolder(tempFilePath);
await writeFilePromise(tempFilePath, fileContent);
debug('creating a new file:: %o', dest);
// rename tmp file to original
@ -370,10 +371,7 @@ export default class LocalFS implements ILocalFSPackageManager {
debug('write file success %s', destiny);
} catch (err: any) {
if (err && err.code === noSuchFile) {
const dir = path.dirname(destiny);
// if fails, we create the folder for the package
debug('write file has failed, creating folder %s', dir);
await mkdirPromise(dir, { recursive: true });
await this.checkCreateFolder(destiny);
// we try again create the temp file
debug('writing a temp file %s', destiny);
await this.writeTempFileAndRename(destiny, fileContent);
@ -385,6 +383,23 @@ export default class LocalFS implements ILocalFSPackageManager {
}
}
private async checkCreateFolder(pathName: string): Promise<void> {
// Check if folder exists and create it if not
const dir = path.dirname(pathName);
try {
await accessPromise(dir);
} catch (err: any) {
if (err.code === noSuchFile) {
debug('folder does not exist %o', dir);
await mkdirPromise(dir, { recursive: true });
debug('folder %o created', dir);
} else {
debug('error on check folder %o', dir);
throw err;
}
}
}
private async _lockAndReadJSON(name: string): Promise<Manifest> {
const fileName: string = this._getStorage(name);
debug('lock and read a file %o', fileName);

View file

@ -93,6 +93,21 @@ describe('Local FS test', () => {
});
});
describe('writeTarballNextNoFolder', () => {
test('should write a tarball even if folder does not exist', (done) => {
const abort = new AbortController();
const tmp = path.join(localTempStorage, 'local-fs-write-tarball-new-folder');
const localFs = new LocalDriver(tmp, logger);
const readableStream = Readable.from('foooo');
localFs.writeTarball('juan-1.0.0.tgz', { signal: abort.signal }).then((stream) => {
stream.on('finish', () => {
done();
});
readableStream.pipe(stream);
});
});
});
describe('readTarballNext', () => {
test('should read a tarball', (done) => {
const abort = new AbortController();