@kogs/utils
Advanced tools
+7
-2
@@ -7,2 +7,5 @@ /// <reference types="node" /> | ||
| type FileFilter = (entryPath: string) => boolean; | ||
| type CopyOptions = { | ||
| overwrite?: 'always' | 'never' | 'newer' | true | false; | ||
| }; | ||
| /** | ||
@@ -12,4 +15,5 @@ * Recursively copies the given source file or directory to the given destination. | ||
| * @param dest - Destination file or directory. | ||
| * @param options - Additional options. | ||
| */ | ||
| export declare function copy(src: string, dest: string): Promise<void>; | ||
| export declare function copy(src: string, dest: string, options?: CopyOptions): Promise<void>; | ||
| /** | ||
@@ -19,4 +23,5 @@ * Recursively copies the given source file or directory to the given destination. | ||
| * @param dest - Destination file or directory. | ||
| * @param options - Additional options. | ||
| */ | ||
| export declare function copySync(src: string, dest: string): void; | ||
| export declare function copySync(src: string, dest: string, options?: CopyOptions): void; | ||
| /** | ||
@@ -23,0 +28,0 @@ * Generates a new error class with the given name. |
+60
-8
@@ -8,9 +8,35 @@ import stream from 'node:stream'; | ||
| * @param dest - Destination file or directory. | ||
| * @param options - Additional options. | ||
| */ | ||
| export async function copy(src, dest) { | ||
| const stat = await fs.promises.stat(src); | ||
| if (stat.isFile()) { | ||
| export async function copy(src, dest, options) { | ||
| const srcStat = await fs.promises.stat(src); | ||
| const destStat = await fs.promises.stat(dest).catch(() => null); | ||
| let overwrite = options?.overwrite === 'always' || options?.overwrite === true; | ||
| if (options?.overwrite === 'newer') { | ||
| if (srcStat.mtimeMs > destStat?.mtimeMs) | ||
| overwrite = true; | ||
| } | ||
| if (srcStat.isFile()) { | ||
| // If source is a file but a directory exists at the destintation, we recursively | ||
| // delete it if `overwrite` is true, otherwise leave it and return. | ||
| if (destStat) { | ||
| if (overwrite) { | ||
| if (destStat?.isDirectory()) | ||
| await fs.promises.rm(dest, { recursive: true }); | ||
| } | ||
| else { | ||
| return; | ||
| } | ||
| } | ||
| await fs.promises.copyFile(src, dest); | ||
| } | ||
| else if (stat.isDirectory()) { | ||
| else if (srcStat.isDirectory()) { | ||
| // If source is a directory but a file exists at the destintation, we delete | ||
| // it if `overwrite` is true, otherwise leave it and return. | ||
| if (destStat?.isFile()) { | ||
| if (overwrite) | ||
| await fs.promises.unlink(dest); | ||
| else | ||
| return; | ||
| } | ||
| await fs.promises.mkdir(dest, { recursive: true }); | ||
@@ -26,9 +52,35 @@ const files = await fs.promises.readdir(src); | ||
| * @param dest - Destination file or directory. | ||
| * @param options - Additional options. | ||
| */ | ||
| export function copySync(src, dest) { | ||
| const stat = fs.statSync(src); | ||
| if (stat.isFile()) { | ||
| export function copySync(src, dest, options) { | ||
| const srcStat = fs.statSync(src); | ||
| const destStat = fs.statSync(dest, { throwIfNoEntry: false }); | ||
| let overwrite = options?.overwrite === 'always' || options?.overwrite === true; | ||
| if (options?.overwrite === 'newer') { | ||
| if (srcStat.mtimeMs > destStat?.mtimeMs) | ||
| overwrite = true; | ||
| } | ||
| if (srcStat.isFile()) { | ||
| // If source is a file but a directory exists at the destintation, we recursively | ||
| // delete it if `overwrite` is true, otherwise leave it and return. | ||
| if (destStat) { | ||
| if (overwrite) { | ||
| if (destStat?.isDirectory()) | ||
| fs.rmSync(dest, { recursive: true }); | ||
| } | ||
| else { | ||
| return; | ||
| } | ||
| } | ||
| fs.copyFileSync(src, dest); | ||
| } | ||
| else if (stat.isDirectory()) { | ||
| else if (srcStat.isDirectory()) { | ||
| // If source is a directory but a file exists at the destintation, we delete | ||
| // it if `overwrite` is true, otherwise leave it and return. | ||
| if (destStat?.isFile()) { | ||
| if (overwrite) | ||
| fs.unlinkSync(dest); | ||
| else | ||
| return; | ||
| } | ||
| fs.mkdirSync(dest, { recursive: true }); | ||
@@ -35,0 +87,0 @@ const files = fs.readdirSync(src); |
+1
-1
| { | ||
| "name": "@kogs/utils", | ||
| "version": "1.4.7", | ||
| "version": "1.4.9", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "description": "A collection of standalone utility functions.", |
+28
-1
@@ -41,3 +41,5 @@ # @kogs/utils | ||
| If given a directory, the directory and all of its contents will be copied recursively. | ||
| - If given a directory, the directory and all of its contents will be copied recursively to the new location. | ||
| - If given a directory, but a file exists at the destination, the file will be unlinked and replaced with the directory. | ||
| - If given a file, but a directory exists at the destination, the directory will be recursively deleted and replaced with the file. | ||
@@ -48,2 +50,13 @@ ```js | ||
| The default behavior of overwriting can be controlled by passing an options object as the third argument with the `overwrite` property set to `true`, `false`, `always`, `never` or `newer`. | ||
| - `true` or `always` - Overwrite the destination if it already exists. | ||
| - `false` or `never` - Do not overwrite the destination if it already exists. | ||
| - `newer` - Only overwrite the destination tgat already exists if the source is newer. | ||
| ```js | ||
| await copy('/path/to/src', '/path/to/dest', { overwrite: 'newer' }); | ||
| ``` | ||
| ### copySync | ||
@@ -56,2 +69,6 @@ `copySync(src: string, dest: string): void` | ||
| - If given a directory, the directory and all of its contents will be copied recursively to the new location. | ||
| - If given a directory, but a file exists at the destination, the file will be unlinked and replaced with the directory. | ||
| - If given a file, but a directory exists at the destination, the directory will be recursively deleted and replaced with the file. | ||
| ```js | ||
@@ -61,2 +78,12 @@ copySync('/path/to/src', '/path/to/dest'); | ||
| The default behavior of overwriting can be controlled by passing an options object as the third argument with the `overwrite` property set to `true`, `false`, `always`, `never` or `newer`. | ||
| - `true` or `always` - Overwrite the destination if it already exists. | ||
| - `false` or `never` - Do not overwrite the destination if it already exists. | ||
| - `newer` - Only overwrite the destination tgat already exists if the source is newer. | ||
| ```js | ||
| copySync('/path/to/src', '/path/to/dest', { overwrite: 'newer' }); | ||
| ``` | ||
| ### collectFiles | ||
@@ -63,0 +90,0 @@ `collectFiles(dir: string, filter?: FileFilter): Promise<string[]>` |
22390
21.56%299
23.55%242
12.56%