copy-file-util 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/bin/cli.js +3 -39
- package/dist/copy-file.d.ts +7 -5
- package/dist/copy-file.js +50 -12
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ Command-line flags:
|
|
|
55
55
|
| `--platform-eol` | Save target file with OS dependent line endings. | N/A |
|
|
56
56
|
| `--quiet` | Suppress informational messages. | N/A |
|
|
57
57
|
|
|
58
|
-
Examples
|
|
58
|
+
### 4. Examples
|
|
59
59
|
- `copy-file app.js app.mjs --quiet`<br>
|
|
60
60
|
Displays no output.
|
|
61
61
|
|
|
@@ -77,7 +77,7 @@ Examples:
|
|
|
77
77
|
|
|
78
78
|
_**Note:** Single quotes in commands are normalized so they work cross-platform and avoid the errors often encountered on Microsoft Windows._
|
|
79
79
|
|
|
80
|
-
###
|
|
80
|
+
### 5. Template variables
|
|
81
81
|
The *target* parameter can contain template variables, like `{{package.version}}` and `{{package.name}}`, which will be replaced with values with values from your project's **package.json** file.
|
|
82
82
|
|
|
83
83
|
Example:
|
|
@@ -92,7 +92,7 @@ Example:
|
|
|
92
92
|
import { copyFile } from 'copy-file-util';
|
|
93
93
|
|
|
94
94
|
const result = copyFile.cp('src/web/api.html' { targetFile: 'docs/api-manual.html' });
|
|
95
|
-
console.
|
|
95
|
+
console.info('Execution time:', result.duration, 'ms');
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
See the **TypeScript Declarations** at the top of [copy-file.ts](src/copy-file.ts) for documentation.
|
package/bin/cli.js
CHANGED
|
@@ -17,45 +17,9 @@
|
|
|
17
17
|
// $ cd copy-file-util
|
|
18
18
|
// $ npm install
|
|
19
19
|
// $ npm test
|
|
20
|
-
// $ node bin/cli.js --cd=spec/fixtures
|
|
21
|
-
// $ node bin/cli.js --cd=spec/fixtures
|
|
20
|
+
// $ node bin/cli.js --cd=spec/fixtures mock.html --folder target/to-folder
|
|
21
|
+
// $ node bin/cli.js --cd=spec/fixtures mock.html target/{{package.type}}/{{package.name}}-v{{package.version}}.html
|
|
22
22
|
|
|
23
|
-
// Imports
|
|
24
|
-
import { cliArgvUtil } from 'cli-argv-util';
|
|
25
23
|
import { copyFile } from '../dist/copy-file.js';
|
|
26
|
-
import { dna } from 'dna-engine';
|
|
27
|
-
import fs from 'fs';
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
const validFlags = ['cd', 'folder', 'move', 'no-overwrite', 'note', 'platform-eol', 'quiet'];
|
|
31
|
-
const cli = cliArgvUtil.parse(validFlags);
|
|
32
|
-
const source = cli.params[0];
|
|
33
|
-
const target = cli.params[1];
|
|
34
|
-
|
|
35
|
-
// Utilities
|
|
36
|
-
const readPackage = () => JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
|
37
|
-
const getPackageField = (match) => //example: '{{package.version}}' --> '3.1.4'
|
|
38
|
-
dna.util.value({ package: readPackage() }, match.replace(/[{}]/g, '')) ?? 'MISSING-FIELD-ERROR';
|
|
39
|
-
|
|
40
|
-
// Copy File
|
|
41
|
-
const error =
|
|
42
|
-
cli.invalidFlag ? cli.invalidFlagMsg :
|
|
43
|
-
cli.paramCount > 2 ? 'Extraneous parameter: ' + cli.params[2] :
|
|
44
|
-
!source ? 'Missing source file.' :
|
|
45
|
-
!target && cli.flagOn.folder ? 'Missing target folder.' :
|
|
46
|
-
!target ? 'Missing target file.' :
|
|
47
|
-
null;
|
|
48
|
-
if (error)
|
|
49
|
-
throw new Error('[copy-file-util] ' + error);
|
|
50
|
-
const targetKey = cli.flagOn.folder ? 'targetFolder' : 'targetFile';
|
|
51
|
-
const templateVariables = /{{[^{}]*}}/g; //example match: "{{package.version}}"
|
|
52
|
-
const options = {
|
|
53
|
-
cd: cli.flagMap.cd ?? null,
|
|
54
|
-
move: cli.flagOn.move,
|
|
55
|
-
overwrite: !cli.flagOn.noOverwrite,
|
|
56
|
-
platformEol: cli.flagOn.platformEol,
|
|
57
|
-
[targetKey]: target.replace(templateVariables, getPackageField),
|
|
58
|
-
};
|
|
59
|
-
const result = copyFile.cp(source, options);
|
|
60
|
-
if (!cli.flagOn.quiet)
|
|
61
|
-
copyFile.reporter(result);
|
|
25
|
+
copyFile.cli();
|
package/dist/copy-file.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
//! copy-file-util v1.3.
|
|
1
|
+
//! copy-file-util v1.3.2 ~~ https://github.com/center-key/copy-file-util ~~ MIT License
|
|
2
2
|
|
|
3
3
|
export type Settings = {
|
|
4
|
-
cd: string;
|
|
5
|
-
targetFile: string;
|
|
6
|
-
targetFolder: string;
|
|
7
|
-
fileExtension: string;
|
|
4
|
+
cd: string | null;
|
|
5
|
+
targetFile: string | null;
|
|
6
|
+
targetFolder: string | null;
|
|
7
|
+
fileExtension: string | null;
|
|
8
8
|
move: boolean;
|
|
9
9
|
overwrite: boolean;
|
|
10
10
|
platformEol: boolean;
|
|
@@ -17,6 +17,8 @@ export type Result = {
|
|
|
17
17
|
skipped: boolean;
|
|
18
18
|
};
|
|
19
19
|
declare const copyFile: {
|
|
20
|
+
assert(condition: unknown, errorMessage: unknown): void;
|
|
21
|
+
cli(): void;
|
|
20
22
|
cp(sourceFile: string, options?: Partial<Settings>): Result;
|
|
21
23
|
reporter(result: Result): Result;
|
|
22
24
|
};
|
package/dist/copy-file.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
//! copy-file-util v1.3.
|
|
1
|
+
//! copy-file-util v1.3.2 ~~ https://github.com/center-key/copy-file-util ~~ MIT License
|
|
2
2
|
|
|
3
|
+
import { cliArgvUtil } from 'cli-argv-util';
|
|
4
|
+
import { dna } from 'dna-engine';
|
|
3
5
|
import { EOL } from 'node:os';
|
|
4
6
|
import chalk from 'chalk';
|
|
5
7
|
import fs from 'fs';
|
|
@@ -7,6 +9,42 @@ import log from 'fancy-log';
|
|
|
7
9
|
import path from 'path';
|
|
8
10
|
import slash from 'slash';
|
|
9
11
|
const copyFile = {
|
|
12
|
+
assert(condition, errorMessage) {
|
|
13
|
+
if (!condition)
|
|
14
|
+
throw new Error('[copy-file-util] ' + String(errorMessage));
|
|
15
|
+
},
|
|
16
|
+
cli() {
|
|
17
|
+
const validFlags = ['cd', 'folder', 'move', 'no-overwrite', 'note', 'platform-eol', 'quiet'];
|
|
18
|
+
const cli = cliArgvUtil.parse(validFlags);
|
|
19
|
+
const source = cli.params[0];
|
|
20
|
+
const target = cli.params[1];
|
|
21
|
+
const getPkgField = (substring) => {
|
|
22
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
|
23
|
+
const value = dna.util.value({ package: pkg }, substring.replace(/[{}]/g, ''));
|
|
24
|
+
return value ?? 'MISSING-FIELD-ERROR';
|
|
25
|
+
};
|
|
26
|
+
const errorMessage = cli.invalidFlag ? cli.invalidFlagMsg :
|
|
27
|
+
cli.paramCount > 2 ? 'Extraneous parameter: ' + cli.params[2] :
|
|
28
|
+
!source ? 'Missing source file.' :
|
|
29
|
+
!target && cli.flagOn.folder ? 'Missing target folder.' :
|
|
30
|
+
!target ? 'Missing target file.' :
|
|
31
|
+
null;
|
|
32
|
+
copyFile.assert(!errorMessage, errorMessage);
|
|
33
|
+
const templateVariables = /{{[^{}]*}}/g;
|
|
34
|
+
const targetValue = target.replace(templateVariables, getPkgField);
|
|
35
|
+
const options = {
|
|
36
|
+
cd: cli.flagMap.cd ?? null,
|
|
37
|
+
targetFile: !cli.flagOn.folder ? targetValue : null,
|
|
38
|
+
targetFolder: cli.flagOn.folder ? targetValue : null,
|
|
39
|
+
fileExtension: null,
|
|
40
|
+
move: !!cli.flagOn.move,
|
|
41
|
+
overwrite: !cli.flagOn.noOverwrite,
|
|
42
|
+
platformEol: !!cli.flagOn.platformEol,
|
|
43
|
+
};
|
|
44
|
+
const result = copyFile.cp(source, options);
|
|
45
|
+
if (!cli.flagOn.quiet)
|
|
46
|
+
copyFile.reporter(result);
|
|
47
|
+
},
|
|
10
48
|
cp(sourceFile, options) {
|
|
11
49
|
const defaults = {
|
|
12
50
|
cd: null,
|
|
@@ -20,17 +58,18 @@ const copyFile = {
|
|
|
20
58
|
const settings = { ...defaults, ...options };
|
|
21
59
|
const startTime = Date.now();
|
|
22
60
|
const missingTarget = !settings.targetFile && !settings.targetFolder;
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
61
|
+
const doubleTarget = !!settings.targetFile && !!settings.targetFolder;
|
|
62
|
+
const cleanUp = (folder) => slash(path.normalize(folder)).replace(/\/$/, '');
|
|
63
|
+
const cleanPath = (folder) => !folder ? '' : cleanUp(folder);
|
|
64
|
+
const startFolder = settings.cd ? cleanPath(settings.cd) + '/' : '';
|
|
65
|
+
const source = sourceFile ? cleanPath(startFolder + sourceFile) : '';
|
|
27
66
|
const sourceExists = source && fs.existsSync(source);
|
|
28
67
|
const sourceIsFile = sourceExists && fs.statSync(source).isFile();
|
|
29
68
|
const sourceFilename = sourceIsFile ? path.basename(source) : null;
|
|
30
69
|
const targetPath = settings.targetFile ? path.dirname(settings.targetFile) : settings.targetFolder;
|
|
31
|
-
const targetFolder = targetPath ?
|
|
70
|
+
const targetFolder = targetPath ? cleanPath(startFolder + targetPath) : null;
|
|
32
71
|
const targetFile = settings.targetFile ?? `${settings.targetFolder}/${sourceFilename}`;
|
|
33
|
-
const target =
|
|
72
|
+
const target = cleanPath(startFolder + targetFile);
|
|
34
73
|
const targetExists = !missingTarget && fs.existsSync(target);
|
|
35
74
|
const skip = targetExists && !settings.overwrite;
|
|
36
75
|
if (targetFolder)
|
|
@@ -41,19 +80,18 @@ const copyFile = {
|
|
|
41
80
|
!sourceExists ? 'Source file does not exist: ' + source :
|
|
42
81
|
!sourceIsFile ? 'Source is not a file: ' + source :
|
|
43
82
|
missingTarget ? 'Must specify a target file or folder.' :
|
|
44
|
-
|
|
83
|
+
doubleTarget ? 'Target cannot be both a file and a folder.' :
|
|
45
84
|
badTargetFolder ? 'Target folder cannot be written to: ' + String(targetFolder) :
|
|
46
85
|
null;
|
|
47
|
-
|
|
48
|
-
throw new Error('[copy-file-util] ' + errorMessage);
|
|
86
|
+
copyFile.assert(!errorMessage, errorMessage);
|
|
49
87
|
const createTarget = () => {
|
|
50
88
|
if (settings.move)
|
|
51
89
|
fs.renameSync(source, target);
|
|
52
90
|
else
|
|
53
91
|
fs.copyFileSync(source, target);
|
|
54
|
-
const
|
|
92
|
+
const platformEol = (text) => text.replace(/\r?\n/g, EOL);
|
|
55
93
|
if (settings.platformEol)
|
|
56
|
-
fs.writeFileSync(target,
|
|
94
|
+
fs.writeFileSync(target, platformEol(fs.readFileSync(target, 'utf-8')));
|
|
57
95
|
};
|
|
58
96
|
if (!skip)
|
|
59
97
|
createTarget();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "copy-file-util",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Copy or rename a file with optional package version number (CLI tool designed for use in npm package.json scripts)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"runScriptsConfig": {
|
|
44
44
|
"clean": [
|
|
45
|
-
"rimraf build dist spec/
|
|
45
|
+
"rimraf build dist spec/target"
|
|
46
46
|
],
|
|
47
47
|
"lint": [
|
|
48
48
|
"jshint . --exclude-path .gitignore",
|
|
@@ -55,27 +55,27 @@
|
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"pretest": "run-scripts clean lint build",
|
|
58
|
-
"test": "mocha spec
|
|
58
|
+
"test": "mocha spec"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"chalk": "~5.
|
|
61
|
+
"chalk": "~5.6",
|
|
62
62
|
"cli-argv-util": "~1.3",
|
|
63
|
-
"dna-engine": "~3.
|
|
63
|
+
"dna-engine": "~3.3",
|
|
64
64
|
"fancy-log": "~2.0",
|
|
65
65
|
"slash": "~5.1"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@eslint/js": "~9.
|
|
68
|
+
"@eslint/js": "~9.39",
|
|
69
69
|
"@types/fancy-log": "~2.0",
|
|
70
|
-
"@types/node": "~24.
|
|
71
|
-
"add-dist-header": "~1.
|
|
70
|
+
"@types/node": "~24.10",
|
|
71
|
+
"add-dist-header": "~1.6",
|
|
72
72
|
"assert-deep-strict-equal": "~1.2",
|
|
73
|
-
"eslint": "~9.
|
|
73
|
+
"eslint": "~9.39",
|
|
74
74
|
"jshint": "~2.13",
|
|
75
75
|
"mocha": "~11.7",
|
|
76
|
-
"rimraf": "~6.
|
|
76
|
+
"rimraf": "~6.1",
|
|
77
77
|
"run-scripts-util": "~1.3",
|
|
78
|
-
"typescript": "~5.
|
|
79
|
-
"typescript-eslint": "~8.
|
|
78
|
+
"typescript": "~5.9",
|
|
79
|
+
"typescript-eslint": "~8.46"
|
|
80
80
|
}
|
|
81
81
|
}
|