@vanillaes/esmtk 0.13.0 → 0.15.0
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/.vscode/launch.json +109 -1
- package/README.md +1 -0
- package/bin/commands/commonjs.js +12 -2
- package/bin/commands/cp.js +28 -8
- package/bin/esmtk.js +16 -8
- package/package.json +4 -1
- package/src/cp.d.ts +10 -0
- package/src/cp.js +56 -22
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/util.d.ts +13 -0
- package/src/util.js +35 -1
package/.vscode/launch.json
CHANGED
|
@@ -73,6 +73,18 @@
|
|
|
73
73
|
"args": ["minify", "--sourcemap", "--platform=node", "./src/index.js", "./dist/index.min.js"],
|
|
74
74
|
"console": "integratedTerminal",
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
"name": "CommonJS",
|
|
78
|
+
"type": "node",
|
|
79
|
+
"request": "launch",
|
|
80
|
+
"skipFiles": [
|
|
81
|
+
"<node_internals>/**"
|
|
82
|
+
],
|
|
83
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
84
|
+
"cwd": "${workspaceFolder}",
|
|
85
|
+
"args": ["commonjs", "--platform=node", "./src/index.js", "./dist/index.cjs"],
|
|
86
|
+
"console": "integratedTerminal",
|
|
87
|
+
},
|
|
76
88
|
{
|
|
77
89
|
"name": "CopyFileToFile",
|
|
78
90
|
"type": "node",
|
|
@@ -94,7 +106,43 @@
|
|
|
94
106
|
],
|
|
95
107
|
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
96
108
|
"cwd": "${workspaceFolder}",
|
|
97
|
-
"args": ["cp", "./test/cp/test1.txt", "./test/cp2"],
|
|
109
|
+
"args": ["cp", "./test/cp/test1.txt", "./test/cp2/test1.txt"],
|
|
110
|
+
"console": "integratedTerminal",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "CopyFileToFile - Error source doesn't exist",
|
|
114
|
+
"type": "node",
|
|
115
|
+
"request": "launch",
|
|
116
|
+
"skipFiles": [
|
|
117
|
+
"<node_internals>/**"
|
|
118
|
+
],
|
|
119
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
120
|
+
"cwd": "${workspaceFolder}",
|
|
121
|
+
"args": ["cp", "./test/cp/testx.txt", "./test/cp2/"],
|
|
122
|
+
"console": "integratedTerminal",
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "CopyFileToFile - Error source is a directory",
|
|
126
|
+
"type": "node",
|
|
127
|
+
"request": "launch",
|
|
128
|
+
"skipFiles": [
|
|
129
|
+
"<node_internals>/**"
|
|
130
|
+
],
|
|
131
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
132
|
+
"cwd": "${workspaceFolder}",
|
|
133
|
+
"args": ["cp", "./test/cp/", "./test/cp2/test1.txt"],
|
|
134
|
+
"console": "integratedTerminal",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "CopyFileToFile - Error target directory doesn't exist",
|
|
138
|
+
"type": "node",
|
|
139
|
+
"request": "launch",
|
|
140
|
+
"skipFiles": [
|
|
141
|
+
"<node_internals>/**"
|
|
142
|
+
],
|
|
143
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
144
|
+
"cwd": "${workspaceFolder}",
|
|
145
|
+
"args": ["cp", "./test/cp/test1.txt", "./test/cpx/"],
|
|
98
146
|
"console": "integratedTerminal",
|
|
99
147
|
},
|
|
100
148
|
{
|
|
@@ -109,6 +157,66 @@
|
|
|
109
157
|
"args": ["cp", "-r", "./test/cp/", "./test/cp2"],
|
|
110
158
|
"console": "integratedTerminal",
|
|
111
159
|
},
|
|
160
|
+
{
|
|
161
|
+
"name": "CopyMultipleFiles",
|
|
162
|
+
"type": "node",
|
|
163
|
+
"request": "launch",
|
|
164
|
+
"skipFiles": [
|
|
165
|
+
"<node_internals>/**"
|
|
166
|
+
],
|
|
167
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
168
|
+
"cwd": "${workspaceFolder}",
|
|
169
|
+
"args": ["cp", "./test/cp/test1.txt", "./test/cp/test1.js", "./test/cp/test2.txt", "./test/cp/test2.js", "./test/cp2/"],
|
|
170
|
+
"console": "integratedTerminal",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "CopyMultipleFiles - Error file doesn't exist",
|
|
174
|
+
"type": "node",
|
|
175
|
+
"request": "launch",
|
|
176
|
+
"skipFiles": [
|
|
177
|
+
"<node_internals>/**"
|
|
178
|
+
],
|
|
179
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
180
|
+
"cwd": "${workspaceFolder}",
|
|
181
|
+
"args": ["cp", "./test/cp/test1.ts", "./test/cp/test1.js", "./test/cp/test2.txt", "./test/cp/test2.js", "./test/cp2/"],
|
|
182
|
+
"console": "integratedTerminal",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"name": "CopyMultipleGlobs",
|
|
186
|
+
"type": "node",
|
|
187
|
+
"request": "launch",
|
|
188
|
+
"skipFiles": [
|
|
189
|
+
"<node_internals>/**"
|
|
190
|
+
],
|
|
191
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
192
|
+
"cwd": "${workspaceFolder}",
|
|
193
|
+
"args": ["cp", "./test/cp/*.txt", "./test/cp/*.js", "./test/cp2/"],
|
|
194
|
+
"console": "integratedTerminal",
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"name": "CopyMultipleGlobs - Error glob not found",
|
|
198
|
+
"type": "node",
|
|
199
|
+
"request": "launch",
|
|
200
|
+
"skipFiles": [
|
|
201
|
+
"<node_internals>/**"
|
|
202
|
+
],
|
|
203
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
204
|
+
"cwd": "${workspaceFolder}",
|
|
205
|
+
"args": ["cp", "./test/cp/*.ts", "./test/cp/*.js", "./test/cp2/"],
|
|
206
|
+
"console": "integratedTerminal",
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"name": "CopyMultipleMixed",
|
|
210
|
+
"type": "node",
|
|
211
|
+
"request": "launch",
|
|
212
|
+
"skipFiles": [
|
|
213
|
+
"<node_internals>/**"
|
|
214
|
+
],
|
|
215
|
+
"program": "${workspaceFolder}/bin/esmtk.js",
|
|
216
|
+
"cwd": "${workspaceFolder}",
|
|
217
|
+
"args": ["cp", "./test/cp/test1.txt", "./test/cp/test2.txt", "./test/cp/*.js", "./test/cp2/"],
|
|
218
|
+
"console": "integratedTerminal",
|
|
219
|
+
},
|
|
112
220
|
{
|
|
113
221
|
"name": "RemoveFile",
|
|
114
222
|
"type": "node",
|
package/README.md
CHANGED
package/bin/commands/commonjs.js
CHANGED
|
@@ -5,8 +5,9 @@ import { spawn } from 'child_process'
|
|
|
5
5
|
* Bundle CJS (CommonJS) code
|
|
6
6
|
* @param {string} input the input path
|
|
7
7
|
* @param {string} output the output path
|
|
8
|
+
* @param {any} options commonjs options
|
|
8
9
|
*/
|
|
9
|
-
export async function commonjs (input, output) {
|
|
10
|
+
export async function commonjs (input, output, options) {
|
|
10
11
|
const npmExists = await which('npm')
|
|
11
12
|
if (!npmExists) {
|
|
12
13
|
console.error('npm not found')
|
|
@@ -21,7 +22,16 @@ export async function commonjs (input, output) {
|
|
|
21
22
|
process.exit(1)
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
const args = []
|
|
26
|
+
args.push('--bundle')
|
|
27
|
+
args.push('--format=cjs')
|
|
28
|
+
if (options?.platform) {
|
|
29
|
+
args.push(`--platform=${options?.platform}`)
|
|
30
|
+
}
|
|
31
|
+
args.push(input)
|
|
32
|
+
args.push(`--outfile=${output}`)
|
|
33
|
+
|
|
34
|
+
spawn('esbuild', args, {
|
|
25
35
|
cwd: process.cwd(),
|
|
26
36
|
stdio: ['pipe', process.stdout, process.stderr]
|
|
27
37
|
}).on('error', err => {
|
package/bin/commands/cp.js
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
import { copyAsync, copyRecursiveAsync } from '../../src/cp.js'
|
|
1
|
+
import { copyAsync, copyMultipleAsync, copyRecursiveAsync } from '../../src/cp.js'
|
|
2
|
+
import { expandSource } from '../../src/index.js'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* POSIX cp Implemented in Node
|
|
5
|
-
*
|
|
6
|
-
* @param {
|
|
6
|
+
*
|
|
7
|
+
* @param {string[]} paths Variadic of source/destination paths
|
|
8
|
+
* @param {any} options 'cp' options
|
|
7
9
|
*/
|
|
8
|
-
export async function cp (
|
|
9
|
-
if (
|
|
10
|
-
|
|
10
|
+
export async function cp (paths, options) {
|
|
11
|
+
if (paths.length < 2) {
|
|
12
|
+
console.error('cp: Not enough arguments')
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
+
if (paths.length === 2) {
|
|
16
|
+
const source = paths[0]
|
|
17
|
+
const target = paths[1]
|
|
18
|
+
|
|
19
|
+
if (!options?.recursive) {
|
|
20
|
+
await copyAsync(source, target, options?.force)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (options?.recursive) {
|
|
24
|
+
await copyRecursiveAsync(source, target, options?.force)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (paths.length >= 2) {
|
|
29
|
+
let sources = paths.slice(0, -1)
|
|
30
|
+
sources = await await Promise.all(sources.map(source => expandSource(source)))
|
|
31
|
+
sources = sources.flat()
|
|
32
|
+
const target = paths.slice(-1)[0]
|
|
33
|
+
|
|
34
|
+
await copyMultipleAsync(sources, target, options?.force)
|
|
15
35
|
}
|
|
16
36
|
}
|
package/bin/esmtk.js
CHANGED
|
@@ -38,8 +38,9 @@ program.command('bundle <input> <output>')
|
|
|
38
38
|
|
|
39
39
|
program.command('commonjs <input> <output>')
|
|
40
40
|
.description('Transpile the source to CommonJS using ESBuild')
|
|
41
|
-
.
|
|
42
|
-
|
|
41
|
+
.option('--platform <platform>', 'Target a specific platform (ex node)')
|
|
42
|
+
.action((input, output, options) => {
|
|
43
|
+
commonjs(input, output, options)
|
|
43
44
|
})
|
|
44
45
|
|
|
45
46
|
program.command('minify <input> <output>')
|
|
@@ -50,13 +51,20 @@ program.command('minify <input> <output>')
|
|
|
50
51
|
minify(input, output, options)
|
|
51
52
|
})
|
|
52
53
|
|
|
53
|
-
program.command('cp
|
|
54
|
-
.
|
|
55
|
-
.
|
|
56
|
-
|
|
54
|
+
program.command('cp')
|
|
55
|
+
.argument('[paths...]')
|
|
56
|
+
.usage(`[-r] source target
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
$ cp SOURCE DEST
|
|
60
|
+
$ cp SOURCE... DIRECTORY
|
|
61
|
+
$ cp SOURCEGLOB... DIRECTORY
|
|
62
|
+
$ cp -r SOURCEDIR DIRECTORY
|
|
63
|
+
`)
|
|
64
|
+
.description('Copy files and directories')
|
|
57
65
|
.option('-r, --recursive', 'Copy directories recursively', false)
|
|
58
|
-
.action((
|
|
59
|
-
cp(
|
|
66
|
+
.action((paths, options) => {
|
|
67
|
+
cp(paths, options)
|
|
60
68
|
})
|
|
61
69
|
|
|
62
70
|
program.command('rm <path>')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vanillaes/esmtk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "ES Module Toolkit",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"esm",
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"preversion": "npm run lint && npm run types",
|
|
38
38
|
"postversion": "git push --follow-tags"
|
|
39
39
|
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=22"
|
|
42
|
+
},
|
|
40
43
|
"dependencies": {
|
|
41
44
|
"commander": "^14.0.3",
|
|
42
45
|
"standard": "^17.1.2"
|
package/src/cp.d.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Copy a single file asynchronously
|
|
3
|
+
*
|
|
3
4
|
* @param {string} source The source file
|
|
4
5
|
* @param {string} target The target file
|
|
5
6
|
* @param {boolean} force If the file already exists, overwrite it (default false)
|
|
6
7
|
*/
|
|
7
8
|
export function copyAsync(source: string, target: string, force?: boolean): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Copy a multiple files/globs asynchronously
|
|
11
|
+
*
|
|
12
|
+
* @param {string[]} sources The source files/globs
|
|
13
|
+
* @param {string} target The target file
|
|
14
|
+
* @param {boolean} force If the file already exists, overwrite it (default false)
|
|
15
|
+
*/
|
|
16
|
+
export function copyMultipleAsync(sources: string[], target: string, force?: boolean): Promise<void>;
|
|
8
17
|
/**
|
|
9
18
|
* Recursively copy a directory asynchronously
|
|
19
|
+
*
|
|
10
20
|
* @param {string} source The source directory
|
|
11
21
|
* @param {string} target The target directory
|
|
12
22
|
* @param {boolean} force If the file already exists, overwrite it (default false)
|
package/src/cp.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { fileExists } from './index.js'
|
|
2
|
-
import { basename,
|
|
2
|
+
import { basename, sep } from 'node:path'
|
|
3
3
|
import { cp, stat } from 'node:fs/promises'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Copy a single file asynchronously
|
|
7
|
+
*
|
|
7
8
|
* @param {string} source The source file
|
|
8
9
|
* @param {string} target The target file
|
|
9
10
|
* @param {boolean} force If the file already exists, overwrite it (default false)
|
|
@@ -11,45 +12,78 @@ import { cp, stat } from 'node:fs/promises'
|
|
|
11
12
|
export async function copyAsync (source, target, force = false) {
|
|
12
13
|
const sExists = await fileExists(source)
|
|
13
14
|
if (!sExists) {
|
|
14
|
-
console.error(`cp:
|
|
15
|
+
console.error(`cp: ${source} No such file or directory`)
|
|
15
16
|
process.exit(1)
|
|
16
17
|
}
|
|
17
18
|
const sStats = await stat(source)
|
|
18
19
|
if (sStats.isSymbolicLink()) {
|
|
19
|
-
console.error(`cp:
|
|
20
|
+
console.error(`cp: ${source} is a sybolic link (not copied)`)
|
|
20
21
|
process.exit(1)
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const tDirExists = await fileExists(tDir)
|
|
25
|
-
if (!tDirExists) {
|
|
26
|
-
console.error(`cp: target directory ${tDir} does not exist`)
|
|
23
|
+
if (!sStats.isFile()) {
|
|
24
|
+
console.error(`cp: ${source} is a directory (not copied)`)
|
|
27
25
|
process.exit(1)
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
const tExists = await fileExists(target)
|
|
31
|
-
|
|
29
|
+
const tIsDir = target.endsWith(sep)
|
|
30
|
+
// copy file-to-directory
|
|
31
|
+
if (tIsDir) {
|
|
32
|
+
if (!tExists) {
|
|
33
|
+
console.error(`cp: ${target} No such file or directory`)
|
|
34
|
+
process.exit(1)
|
|
35
|
+
}
|
|
32
36
|
const tStats = await stat(target)
|
|
33
37
|
if (tStats.isSymbolicLink()) {
|
|
34
|
-
console.error(`cp:
|
|
38
|
+
console.error(`cp: ${target} is a sybolic link (not copied)`)
|
|
35
39
|
process.exit(1)
|
|
36
40
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
41
|
+
|
|
42
|
+
// append source file name to target directory
|
|
43
|
+
const sourceFile = basename(source)
|
|
44
|
+
target = target.endsWith('/') ? target.slice(0, -1) : target
|
|
45
|
+
target = `${target}/${sourceFile}`
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
try {
|
|
45
|
-
await cp(source, target, { force })
|
|
49
|
+
await cp(source, target, { force: true })
|
|
46
50
|
} catch (err) {
|
|
47
51
|
console.error(`cp: error ${err.message}`)
|
|
48
52
|
}
|
|
49
53
|
}
|
|
50
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Copy a multiple files/globs asynchronously
|
|
57
|
+
*
|
|
58
|
+
* @param {string[]} sources The source files/globs
|
|
59
|
+
* @param {string} target The target file
|
|
60
|
+
* @param {boolean} force If the file already exists, overwrite it (default false)
|
|
61
|
+
*/
|
|
62
|
+
export async function copyMultipleAsync (sources, target, force = false) {
|
|
63
|
+
const tExists = await fileExists(target)
|
|
64
|
+
if (!tExists) {
|
|
65
|
+
console.error(`cp: ${target} No such file or directory`)
|
|
66
|
+
process.exit(1)
|
|
67
|
+
}
|
|
68
|
+
const tStats = await stat(target)
|
|
69
|
+
if (tStats.isSymbolicLink()) {
|
|
70
|
+
console.error(`cp: ${target} is a sybolic link (not copied)`)
|
|
71
|
+
process.exit(1)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
target = target.endsWith('/') ? target.slice(0, -1) : target
|
|
76
|
+
for (const source of sources) {
|
|
77
|
+
await cp(source, `${target}/${basename(source)}`, { force: true })
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error(`cp": error ${err.message}`)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
51
84
|
/**
|
|
52
85
|
* Recursively copy a directory asynchronously
|
|
86
|
+
*
|
|
53
87
|
* @param {string} source The source directory
|
|
54
88
|
* @param {string} target The target directory
|
|
55
89
|
* @param {boolean} force If the file already exists, overwrite it (default false)
|
|
@@ -57,32 +91,32 @@ export async function copyAsync (source, target, force = false) {
|
|
|
57
91
|
export async function copyRecursiveAsync (source, target, force = false) {
|
|
58
92
|
const sExists = await fileExists(source)
|
|
59
93
|
if (!sExists) {
|
|
60
|
-
console.error(`cp:
|
|
94
|
+
console.error(`cp: ${source} No such file or directory`)
|
|
61
95
|
process.exit(1)
|
|
62
96
|
}
|
|
63
97
|
const sStats = await stat(source)
|
|
64
98
|
if (sStats.isSymbolicLink()) {
|
|
65
|
-
console.error(`cp:
|
|
99
|
+
console.error(`cp: ${source} is a sybolic link (not copied)`)
|
|
66
100
|
process.exit(1)
|
|
67
101
|
}
|
|
68
102
|
|
|
69
103
|
const tExists = await fileExists(target)
|
|
70
104
|
if (!tExists) {
|
|
71
|
-
console.error(`cp:
|
|
105
|
+
console.error(`cp: ${target} No such file or directory`)
|
|
72
106
|
process.exit(1)
|
|
73
107
|
}
|
|
74
108
|
const tStats = await stat(target)
|
|
75
109
|
if (tStats.isSymbolicLink()) {
|
|
76
|
-
console.error(`cp:
|
|
110
|
+
console.error(`cp: ${target} is a sybolic link (not copied)`)
|
|
77
111
|
process.exit(1)
|
|
78
112
|
}
|
|
79
113
|
if (!tStats.isDirectory()) {
|
|
80
|
-
console.error(`cp: target ${target}
|
|
114
|
+
console.error(`cp: target ${target} Not a directory`)
|
|
81
115
|
process.exit(1)
|
|
82
116
|
}
|
|
83
117
|
|
|
84
118
|
try {
|
|
85
|
-
await cp(source, target, { force, recursive: true })
|
|
119
|
+
await cp(source, target, { force: true, recursive: true })
|
|
86
120
|
} catch (err) {
|
|
87
121
|
console.error(`cp": error ${err.message}`)
|
|
88
122
|
}
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
package/src/util.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expand source file/glob into a list of paths
|
|
3
|
+
*
|
|
4
|
+
* @param {*} source the source file/glob
|
|
5
|
+
* @returns {Promise<string[]>} an array of paths
|
|
6
|
+
*/
|
|
7
|
+
export function expandSource(source: any): Promise<string[]>;
|
|
1
8
|
/**
|
|
2
9
|
* Check if a file/folder exists
|
|
3
10
|
* @param {string} path the path to the file/folder
|
|
@@ -10,6 +17,12 @@ export function fileExists(path: string): Promise<boolean>;
|
|
|
10
17
|
* @returns {Promise<boolean>} true if the package is installed, false otherwise
|
|
11
18
|
*/
|
|
12
19
|
export function installed(pkg: string): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Description
|
|
22
|
+
* @param {string} pattern glob pattern(s) to match
|
|
23
|
+
* @returns {Promise<string[]>} an array of paths
|
|
24
|
+
*/
|
|
25
|
+
export function match(pattern: string): Promise<string[]>;
|
|
13
26
|
/**
|
|
14
27
|
* Check to see if an application is installed globally
|
|
15
28
|
* @param {string} program the name of the application
|
package/src/util.js
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import { exec } from 'child_process'
|
|
2
|
-
import { access, constants } from 'node:fs/promises'
|
|
2
|
+
import { access, constants, glob } from 'node:fs/promises'
|
|
3
3
|
import { promisify } from 'node:util'
|
|
4
4
|
|
|
5
5
|
const execAsync = promisify(exec)
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Expand source file/glob into a list of paths
|
|
9
|
+
*
|
|
10
|
+
* @param {*} source the source file/glob
|
|
11
|
+
* @returns {Promise<string[]>} an array of paths
|
|
12
|
+
*/
|
|
13
|
+
export async function expandSource (source) {
|
|
14
|
+
const isGlob = source.includes('*')
|
|
15
|
+
if (isGlob) {
|
|
16
|
+
const paths = await match(source)
|
|
17
|
+
if (paths.length === 0) {
|
|
18
|
+
console.error(`cp: ${paths} no matches found`)
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
21
|
+
return paths
|
|
22
|
+
} else {
|
|
23
|
+
const exists = await fileExists(source)
|
|
24
|
+
if (!exists) {
|
|
25
|
+
console.error(`cp: ${source} No such file or directory`)
|
|
26
|
+
process.exit(1)
|
|
27
|
+
}
|
|
28
|
+
return [source]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
7
32
|
/**
|
|
8
33
|
* Check if a file/folder exists
|
|
9
34
|
* @param {string} path the path to the file/folder
|
|
@@ -32,6 +57,15 @@ export async function installed (pkg) {
|
|
|
32
57
|
}
|
|
33
58
|
}
|
|
34
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Description
|
|
62
|
+
* @param {string} pattern glob pattern(s) to match
|
|
63
|
+
* @returns {Promise<string[]>} an array of paths
|
|
64
|
+
*/
|
|
65
|
+
export async function match (pattern) {
|
|
66
|
+
return await Array.fromAsync(glob(pattern))
|
|
67
|
+
}
|
|
68
|
+
|
|
35
69
|
/**
|
|
36
70
|
* Check to see if an application is installed globally
|
|
37
71
|
* @param {string} program the name of the application
|