diff --git a/src/generators/legacy-html/index.mjs b/src/generators/legacy-html/index.mjs
index c100967b..36b1e8d9 100644
--- a/src/generators/legacy-html/index.mjs
+++ b/src/generators/legacy-html/index.mjs
@@ -1,6 +1,6 @@
'use strict';
-import { readFile, rm, writeFile, mkdir } from 'node:fs/promises';
+import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import HTMLMinifier from '@minify-html/node';
@@ -176,11 +176,6 @@ export default {
// Define the output folder for API docs assets
const assetsFolder = join(output, 'assets');
- // Removes the current assets directory to copy the new assets
- // and prevent stale assets from existing in the output directory
- // If the path does not exists, it will simply ignore and continue
- await rm(assetsFolder, { recursive: true, force: true, maxRetries: 10 });
-
// Creates the assets folder if it does not exist
await mkdir(assetsFolder, { recursive: true });
diff --git a/src/generators/legacy-html/utils/__tests__/safeCopy.test.mjs b/src/generators/legacy-html/utils/__tests__/safeCopy.test.mjs
index 12a8736f..186020a8 100644
--- a/src/generators/legacy-html/utils/__tests__/safeCopy.test.mjs
+++ b/src/generators/legacy-html/utils/__tests__/safeCopy.test.mjs
@@ -102,10 +102,6 @@ describe('safeCopy', () => {
it('should handle empty source directory', async () => {
// Don't create any files in source
await safeCopy(srcDir, targetDir);
-
- // Verify no error occurred and target is still empty
- const files = await readFile(targetDir).catch(() => []);
- assert.ok(Array.isArray(files) || files === undefined);
});
it('should copy files with same size but different content when mtime is newer', async () => {
diff --git a/src/generators/legacy-html/utils/safeCopy.mjs b/src/generators/legacy-html/utils/safeCopy.mjs
index e96b62ed..e429912f 100644
--- a/src/generators/legacy-html/utils/safeCopy.mjs
+++ b/src/generators/legacy-html/utils/safeCopy.mjs
@@ -1,11 +1,12 @@
'use strict';
-import { readFile, writeFile, stat, readdir } from 'node:fs/promises';
+import { statSync, constants } from 'node:fs';
+import { copyFile, readdir } from 'node:fs/promises';
import { join } from 'node:path';
/**
- * Safely copies files from source to target directory, skipping files that haven't changed
- * based on file stats (size and modification time)
+ * Copies files from source to target directory, skipping files that haven't changed.
+ * Uses synchronous stat checks for simplicity and copyFile for atomic operations.
*
* @param {string} srcDir - Source directory path
* @param {string} targetDir - Target directory path
@@ -13,26 +14,22 @@ import { join } from 'node:path';
export async function safeCopy(srcDir, targetDir) {
const files = await readdir(srcDir);
- for (const file of files) {
+ const promises = files.map(file => {
const sourcePath = join(srcDir, file);
const targetPath = join(targetDir, file);
- const [sStat, tStat] = await Promise.allSettled([
- stat(sourcePath),
- stat(targetPath),
- ]);
+ const tStat = statSync(targetPath, { throwIfNoEntry: false });
- const shouldWrite =
- tStat.status === 'rejected' ||
- sStat.value.size !== tStat.value.size ||
- sStat.value.mtimeMs > tStat.value.mtimeMs;
-
- if (!shouldWrite) {
- continue;
+ if (tStat === undefined) {
+ return copyFile(sourcePath, targetPath, constants.COPYFILE_FICLONE);
}
- const fileContent = await readFile(sourcePath);
+ const sStat = statSync(sourcePath);
+
+ if (sStat.size !== tStat.size || sStat.mtimeMs > tStat.mtimeMs) {
+ return copyFile(sourcePath, targetPath, constants.COPYFILE_FICLONE);
+ }
+ });
- await writeFile(targetPath, fileContent);
- }
+ await Promise.all(promises);
}