@vanillaes/esmtk 0.15.1 → 0.16.1

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.
@@ -241,7 +241,43 @@
241
241
  "args": ["rm", "./test/cp2/test1.txt"],
242
242
  "console": "integratedTerminal",
243
243
  },
244
- {
244
+ {
245
+ "name": "RemoveFile - Error file is a directory",
246
+ "type": "node",
247
+ "request": "launch",
248
+ "skipFiles": [
249
+ "<node_internals>/**"
250
+ ],
251
+ "program": "${workspaceFolder}/bin/esmtk.js",
252
+ "cwd": "${workspaceFolder}",
253
+ "args": ["rm", "./test/cp2/"],
254
+ "console": "integratedTerminal",
255
+ },
256
+ {
257
+ "name": "RemoveGlob",
258
+ "type": "node",
259
+ "request": "launch",
260
+ "skipFiles": [
261
+ "<node_internals>/**"
262
+ ],
263
+ "program": "${workspaceFolder}/bin/esmtk.js",
264
+ "cwd": "${workspaceFolder}",
265
+ "args": ["rm", "./test/cp2/*.js"],
266
+ "console": "integratedTerminal",
267
+ },
268
+ {
269
+ "name": "RemoveGlob - Error glob not found",
270
+ "type": "node",
271
+ "request": "launch",
272
+ "skipFiles": [
273
+ "<node_internals>/**"
274
+ ],
275
+ "program": "${workspaceFolder}/bin/esmtk.js",
276
+ "cwd": "${workspaceFolder}",
277
+ "args": ["rm", "./test/cp2/*.ts"],
278
+ "console": "integratedTerminal",
279
+ },
280
+ {
245
281
  "name": "RemoveDirectory",
246
282
  "type": "node",
247
283
  "request": "launch",
@@ -252,6 +288,54 @@
252
288
  "cwd": "${workspaceFolder}",
253
289
  "args": ["rm", "-r", "./test/cp2/"],
254
290
  "console": "integratedTerminal",
291
+ },
292
+ {
293
+ "name": "RemoveMultipleFiles",
294
+ "type": "node",
295
+ "request": "launch",
296
+ "skipFiles": [
297
+ "<node_internals>/**"
298
+ ],
299
+ "program": "${workspaceFolder}/bin/esmtk.js",
300
+ "cwd": "${workspaceFolder}",
301
+ "args": ["rm", "./test/cp2/test1.txt", "./test/cp2/test2.txt"],
302
+ "console": "integratedTerminal",
303
+ },
304
+ {
305
+ "name": "RemoveMultipleGlobs",
306
+ "type": "node",
307
+ "request": "launch",
308
+ "skipFiles": [
309
+ "<node_internals>/**"
310
+ ],
311
+ "program": "${workspaceFolder}/bin/esmtk.js",
312
+ "cwd": "${workspaceFolder}",
313
+ "args": ["rm", "./test/cp2/*.txt", "./test/cp2/*.js"],
314
+ "console": "integratedTerminal",
315
+ },
316
+ {
317
+ "name": "RemoveMultipleGlobs - Error glob not found",
318
+ "type": "node",
319
+ "request": "launch",
320
+ "skipFiles": [
321
+ "<node_internals>/**"
322
+ ],
323
+ "program": "${workspaceFolder}/bin/esmtk.js",
324
+ "cwd": "${workspaceFolder}",
325
+ "args": ["rm", "./test/cp2/*.txt", "./test/cp2/*.ts"],
326
+ "console": "integratedTerminal",
327
+ },
328
+ {
329
+ "name": "RemoveMultipleMixed",
330
+ "type": "node",
331
+ "request": "launch",
332
+ "skipFiles": [
333
+ "<node_internals>/**"
334
+ ],
335
+ "program": "${workspaceFolder}/bin/esmtk.js",
336
+ "cwd": "${workspaceFolder}",
337
+ "args": ["rm", "./test/cp2/test1.txt", "./test/cp2/*.js"],
338
+ "console": "integratedTerminal",
255
339
  }
256
340
  ]
257
341
  }
package/README.md CHANGED
@@ -119,16 +119,19 @@ Copy is a cross-platform clone of the `cp` command in Linux
119
119
 
120
120
  ### Arguments
121
121
 
122
- `esmtk cp [-rf] [source] [destination]`
122
+ `esmtk cp [-r] [source...] [destination]`
123
123
 
124
- - `[source]` - the source file/glob
124
+ - `[source...]` - the source file(s)/glob(s)
125
125
  - `[destination]` - the destination file/directory
126
- - `-f --force` - ignore exceptions if the file doesn't exist
127
126
  - `-r, --recursive` - copy files/directories recursively
128
127
 
129
128
  ### Usage
130
129
 
131
130
  ```sh
131
+ esmtk cp file1.txt dest/file1.txt
132
+ esmtk cp file1.txt file2.txt file3.txt dest/
133
+ esmtk cp *.txt dest/
134
+ esmtk cp *.txt *.js *.ts dest/
132
135
  esmtk cp -r src/ dest/
133
136
  ```
134
137
 
@@ -138,14 +141,17 @@ Remove is a cross-platform clone of the `rm` command in Linux
138
141
 
139
142
  ### Arguments
140
143
 
141
- `esmtk rm [-rf] [file|directory]`
144
+ `esmtk rm [-r] [path(s)...]`
142
145
 
143
- - `[file|directory]` - the source file/glob
144
- - `-f --force` - force remove existing file(s)
145
- - `-r, --recursive` - remove files/directories recursively
146
+ - `[path(s)...]` - the source file(s)/glob(s)
147
+ - `-r, --recursive` - remove directory recursively
146
148
 
147
149
  ### Usage
148
150
 
149
151
  ```sh
152
+ esmtk rm file1.txt
153
+ esmtk rm file1.txt file3.txt file3.txt
154
+ esmtk rm *.txt
155
+ esmtk rm *.txt *.js *.ts
150
156
  esmtk rm -r src/
151
157
  ```
@@ -26,11 +26,11 @@ export async function cp (paths, options) {
26
26
 
27
27
  if (source.includes('*')) {
28
28
  const sources = await expandSource(source)
29
- await copyMultipleAsync(sources, target)
29
+ await copyMultipleAsync(sources, target, options?.force)
30
30
  }
31
31
  }
32
32
 
33
- if (paths.length >= 2) {
33
+ if (paths.length > 2) {
34
34
  let sources = paths.slice(0, -1)
35
35
  sources = await await Promise.all(sources.map(source => expandSource(source)))
36
36
  sources = sources.flat()
@@ -1,16 +1,34 @@
1
- import { removeAsync, removeRecursiveAsync } from '../../src/rm.js'
1
+ import { removeAsync, removeMultipleAsync, removeRecursiveAsync } from '../../src/rm.js'
2
+ import { expandSource } from '../../src/util.js'
2
3
 
3
4
  /**
4
5
  * POSIX rm Implemented in Node
5
- * @param {string} path path of file(s)/directorie(s) to remove
6
+ * @param {string[]} paths Variadic of file paths
6
7
  * @param {any} options rm options
7
8
  */
8
- export async function rm (path, options) {
9
- if (!options?.recursive) {
10
- await removeAsync(path, options?.force)
9
+ export async function rm (paths, options) {
10
+ if (paths.length === 1) {
11
+ if (!options?.recursive && !paths[0].includes('*')) {
12
+ const file = paths[0]
13
+ await removeAsync(file, options?.force)
14
+ }
15
+
16
+ if (options?.recursive) {
17
+ const directory = paths[0]
18
+ await removeRecursiveAsync(directory, options?.force)
19
+ }
20
+
21
+ if (paths[0].includes('*')) {
22
+ const glob = paths[0]
23
+ const files = await expandSource(glob)
24
+ await removeMultipleAsync(files, options?.force)
25
+ }
11
26
  }
12
27
 
13
- if (options?.recursive) {
14
- await removeRecursiveAsync(path, options?.force)
28
+ if (paths.length > 1) {
29
+ let files = await await Promise.all(paths.map(path => expandSource(path)))
30
+ files = files.flat()
31
+
32
+ await removeMultipleAsync(files, options?.force)
15
33
  }
16
34
  }
package/bin/esmtk.js CHANGED
@@ -52,7 +52,6 @@ program.command('minify <input> <output>')
52
52
  })
53
53
 
54
54
  program.command('cp')
55
- .argument('[paths...]')
56
55
  .usage(`[-r] source target
57
56
 
58
57
  Examples:
@@ -62,18 +61,27 @@ program.command('cp')
62
61
  $ cp -r SOURCEDIR DIRECTORY
63
62
  `)
64
63
  .description('Copy files and directories')
64
+ .argument('[paths...]')
65
65
  .option('-r, --recursive', 'Copy directories recursively', false)
66
66
  .action((paths, options) => {
67
67
  cp(paths, options)
68
68
  })
69
69
 
70
- program.command('rm <path>')
71
- .usage('[-rf] file|directory')
72
- .description('Remove a file|directory')
70
+ program.command('rm')
71
+ .usage(`[-r] path/glob
72
+
73
+ Examples:
74
+ $ rm FILE
75
+ $ rm FILES...
76
+ $ rm GLOB...
77
+ $ rm -r DIRECTORY
78
+ `)
79
+ .description('Remove files or directories')
80
+ .argument('[paths...]')
73
81
  .option('-f, --force', 'Do not prompt before overwriting', false)
74
82
  .option('-r, --recursive', 'Remove directories recursively', false)
75
- .action((path, options) => {
76
- rm(path, options)
83
+ .action((paths, options) => {
84
+ rm(paths, options)
77
85
  })
78
86
 
79
87
  program.parse(process.argv)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanillaes/esmtk",
3
- "version": "0.15.1",
3
+ "version": "0.16.1",
4
4
  "description": "ES Module Toolkit",
5
5
  "keywords": [
6
6
  "esm",
@@ -45,6 +45,7 @@
45
45
  "standard": "^17.1.2"
46
46
  },
47
47
  "devDependencies": {
48
- "@types/node": "^25.3.5"
48
+ "@types/json5": "^0.0.30",
49
+ "@types/node": "^25.5.0"
49
50
  }
50
51
  }
package/src/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { copyAsync, copyRecursiveAsync } from "./cp.js";
2
- export { removeAsync, removeRecursiveAsync } from "./rm.js";
2
+ export { removeAsync, removeMultipleAsync, removeRecursiveAsync } from "./rm.js";
3
3
  export { expandSource, fileExists, installed, match, which } from "./util.js";
package/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { copyAsync, copyRecursiveAsync } from './cp.js'
2
- export { removeAsync, removeRecursiveAsync } from './rm.js'
2
+ export { removeAsync, removeMultipleAsync, removeRecursiveAsync } from './rm.js'
3
3
  export { expandSource, fileExists, installed, match, which } from './util.js'
package/src/rm.d.ts CHANGED
@@ -4,6 +4,13 @@
4
4
  * @param {boolean} force Ignore exceptions if the file doesn't exist (default false)
5
5
  */
6
6
  export function removeAsync(path: string, force?: boolean): Promise<void>;
7
+ /**
8
+ * Remove a multiple files/globs asynchronously
9
+ *
10
+ * @param {string[]} files The files/globs to delete
11
+ * @param {boolean} force If the file already exists, overwrite it (default false)
12
+ */
13
+ export function removeMultipleAsync(files: string[], force?: boolean): Promise<void>;
7
14
  /**
8
15
  * Recursively remove a file|directory asynchronously
9
16
  * @param {string} path The file|directory to remove
package/src/rm.js CHANGED
@@ -9,22 +9,42 @@ import { rm, stat } from 'node:fs/promises'
9
9
  export async function removeAsync (path, force = false) {
10
10
  const exists = await fileExists(path)
11
11
  if (!exists) {
12
- console.error(`rm: path ${path} does not exist`)
12
+ console.error(`rm: ${path} No such file or directory`)
13
13
  process.exit(1)
14
14
  }
15
15
  const stats = await stat(path)
16
16
  if (stats.isSymbolicLink()) {
17
- console.error(`rm: path ${path} is a sybolic link`)
17
+ console.error(`rm: ${path} is a sybolic link`)
18
+ process.exit(1)
19
+ }
20
+ if (!stats.isFile()) {
21
+ console.error(`rm: ${path} is a directory`)
18
22
  process.exit(1)
19
23
  }
20
24
 
21
25
  try {
22
- await rm(path, { force })
26
+ await rm(path, { force: true })
23
27
  } catch (err) {
24
28
  console.error(`rm: error ${err.message}`)
25
29
  }
26
30
  }
27
31
 
32
+ /**
33
+ * Remove a multiple files/globs asynchronously
34
+ *
35
+ * @param {string[]} files The files/globs to delete
36
+ * @param {boolean} force If the file already exists, overwrite it (default false)
37
+ */
38
+ export async function removeMultipleAsync (files, force = false) {
39
+ try {
40
+ for (const file of files) {
41
+ await rm(file, { force: true })
42
+ }
43
+ } catch (err) {
44
+ console.error(`cp": error ${err.message}`)
45
+ }
46
+ }
47
+
28
48
  /**
29
49
  * Recursively remove a file|directory asynchronously
30
50
  * @param {string} path The file|directory to remove
@@ -33,17 +53,17 @@ export async function removeAsync (path, force = false) {
33
53
  export async function removeRecursiveAsync (path, force = false) {
34
54
  const exists = await fileExists(path)
35
55
  if (!exists) {
36
- console.error(`rm: path ${path} does not exist`)
56
+ console.error(`rm: ${path} No such file or directory`)
37
57
  process.exit(1)
38
58
  }
39
59
  const stats = await stat(path)
40
60
  if (stats.isSymbolicLink()) {
41
- console.error(`rm: path ${path} is a sybolic link`)
61
+ console.error(`rm: ${path} is a sybolic link`)
42
62
  process.exit(1)
43
63
  }
44
64
 
45
65
  try {
46
- await rm(path, { force, recursive: true })
66
+ await rm(path, { force: true, recursive: true })
47
67
  } catch (err) {
48
68
  console.error(`rm": error ${err.message}`)
49
69
  }
package/src/util.js CHANGED
@@ -15,7 +15,7 @@ export async function expandSource (source) {
15
15
  if (isGlob) {
16
16
  const paths = await match(source)
17
17
  if (paths.length === 0) {
18
- console.error(`cp: ${paths} no matches found`)
18
+ console.error(`cp: ${source} no matches found`)
19
19
  process.exit(1)
20
20
  }
21
21
  return paths