From 6a0bc136f9fa67c912b332ae79a1bcd3ccbf5be6 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 10 Jun 2022 18:57:07 +0200 Subject: [PATCH] Make sure to actually await the move --- packages/core/fs/src/NodeFS.js | 35 +++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/core/fs/src/NodeFS.js b/packages/core/fs/src/NodeFS.js index 8b58b369a08..263d036fc05 100644 --- a/packages/core/fs/src/NodeFS.js +++ b/packages/core/fs/src/NodeFS.js @@ -60,18 +60,15 @@ export class NodeFS implements FileSystem { createWriteStream(filePath: string, options: any): Writable { // Make createWriteStream atomic let tmpFilePath = getTempFilePath(filePath); - let writeStream = fs.createWriteStream(tmpFilePath, options); - let failed = false; - writeStream.once('error', () => { - failed = true; - fs.unlinkSync(tmpFilePath); - }); - writeStream.once('close', async () => { + + const move = async () => { if (!failed) { try { await fs.promises.rename(tmpFilePath, filePath); } catch (e) { + // This is adapted from fs-write-stream-atomic. Apparently + // Windows doesn't like renaming when the target already exists. if ( process.platform === 'win32' && e.syscall && @@ -92,6 +89,30 @@ export class NodeFS implements FileSystem { } } } + }; + + let writeStream = fs.createWriteStream(tmpFilePath, { + ...options, + fs: { + ...fs, + close: (fd, cb) => { + fs.close(fd, err => { + if (err) { + cb(err); + } else { + move().then( + () => cb(), + err => cb(err), + ); + } + }); + }, + }, + }); + + writeStream.once('error', () => { + failed = true; + fs.unlinkSync(tmpFilePath); }); return writeStream;