esmtk 0.5.13 → 0.6.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.
@@ -0,0 +1,44 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "CopyFileToFile",
9
+ "type": "node",
10
+ "request": "launch",
11
+ "skipFiles": [
12
+ "<node_internals>/**"
13
+ ],
14
+ "program": "${workspaceFolder}/bin/esmtk.js",
15
+ "cwd": "${workspaceFolder}",
16
+ "args": ["cp", "./test/cp/test1.txt", "./test/cp2/test1.txt"],
17
+ "console": "integratedTerminal",
18
+ },
19
+ {
20
+ "name": "CopyFileToFolder",
21
+ "type": "node",
22
+ "request": "launch",
23
+ "skipFiles": [
24
+ "<node_internals>/**"
25
+ ],
26
+ "program": "${workspaceFolder}/bin/esmtk.js",
27
+ "cwd": "${workspaceFolder}",
28
+ "args": ["cp", "./test/cp/test1.txt", "./test/cp2"],
29
+ "console": "integratedTerminal",
30
+ },
31
+ {
32
+ "name": "CopyFolderRecursively",
33
+ "type": "node",
34
+ "request": "launch",
35
+ "skipFiles": [
36
+ "<node_internals>/**"
37
+ ],
38
+ "program": "${workspaceFolder}/bin/esmtk.js",
39
+ "cwd": "${workspaceFolder}",
40
+ "args": ["cp", "-r", "./test/cp/", "./test/cp2"],
41
+ "console": "integratedTerminal",
42
+ }
43
+ ]
44
+ }
@@ -1,159 +1,97 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import os from 'os'
4
- import glob from 'glob'
1
+ import { basename, dirname } from 'node:path'
2
+ import { access, constants, cp as nodeCp, stat } from 'node:fs/promises'
5
3
 
6
- export async function cp (opt) {
7
- const self = this
8
- const options = {}
9
- options.noclobber = opt.force === true ? false : opt.noclobber
10
- options.recursive = opt.R === true ? true : opt.recursive
11
-
12
- const dest = opt.args.pop()
4
+ export async function cp (source, target, options) {
5
+ if (!options.recursive) {
6
+ await copyAsync(source, target, options.force)
7
+ }
13
8
 
14
- let sources = opt.args
15
- const exists = fs.existsSync(dest)
16
- const stats = exists && fs.statSync(dest)
9
+ if (options.recursive) {
10
+ await copyRecursiveAsync(source, target, options.force)
11
+ }
12
+ }
17
13
 
18
- // Dest is not existing dir, but multiple sources given
19
- if ((!exists || !stats.isDirectory()) && sources.length > 1) {
20
- console.error(`cp: target ${dest} is not a directory`)
14
+ // copy a single file
15
+ async function copyAsync (source, target, force = false) {
16
+ const sExists = await fileExists(source)
17
+ if (!sExists) {
18
+ console.error(`cp: source ${source} does not exist`)
21
19
  process.exit(1)
22
20
  }
23
-
24
- // Dest is an existing file, but no -f given
25
- if (exists && stats.isFile() && options.noclobber) {
26
- process.exit(0)
21
+ const sStats = await stat(source)
22
+ if (sStats.isSymbolicLink()) {
23
+ console.error(`cp: source ${source} is a sybolic link`)
24
+ process.exit(1)
27
25
  }
28
26
 
29
- if (options.recursive) {
30
- sources = sources.reduce((acc, src) => {
31
- if (src.endsWith('/')) {
32
- return [...acc, `${src}*`]
33
- }
34
- if (fs.statSync(src).isDirectory() && !exists) {
35
- return [...acc, `${src}/*`]
36
- }
37
- return [...acc, src]
38
- }, [])
39
-
40
- try {
41
- fs.mkdirSync(dest, parseInt('0777', 8))
42
- } catch (e) {
43
- // like Unix's cp, keep going even if we can't create dest dir
44
- }
27
+ const tDir = dirname(target)
28
+ const tDirExists = await fileExists(tDir)
29
+ if (!tDirExists) {
30
+ console.error(`cp: target directory ${tDir} does not exist`)
31
+ process.exit(1)
45
32
  }
46
- sources = sources.reduce((acc, curr) => {
47
- return [...acc, ...glob.sync(curr)]
48
- }, [])
49
33
 
50
- sources.forEach(function (src) {
51
- if (!fs.existsSync(src)) {
52
- console.error(`cp: cannot stat ${src}: No such file or directory`)
53
- return
34
+ const tExists = await fileExists(target)
35
+ if (tExists) {
36
+ const tStats = await stat(target)
37
+ if (tStats.isSymbolicLink()) {
38
+ console.error(`cp: target ${target} is a sybolic link`)
39
+ process.exit(1)
54
40
  }
55
-
56
- if (fs.statSync(src).isDirectory()) {
57
- if (!options.recursive) {
58
- console.log(`cp: -r not specified; omitting directory ${src}`)
59
- } else {
60
- // 'cp /a/source dest' should create 'source' in 'dest'
61
- const newDest = path.join(dest, path.basename(src))
62
- const checkDir = fs.statSync(src)
63
- try {
64
- fs.mkdirSync(newDest, checkDir.mode)
65
- } catch (e) {
66
- if (e.code !== 'EEXIST') {
67
- throw new Error()
68
- }
69
- }
70
- cpdirSyncRecursive.call(self, src, newDest, options)
71
- }
72
- return
73
- }
74
-
75
- // If here, src is a file
76
- // When copying to '/path/dir', iDest = '/path/dir/file1'
77
- let iDest = dest
78
- if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) {
79
- iDest = path.normalize(`${dest}/${path.basename(src)}`)
41
+ if (tStats.isDirectory()) {
42
+ const sourceFile = basename(source)
43
+ target = target.endsWith('/') ? target.slice(0, -1) : target
44
+ target = `${target}/${sourceFile}`
80
45
  }
81
-
82
- if (fs.existsSync(iDest) && options.no_force) {
83
- return
84
- }
85
-
86
- copyFileSync.call(self, src, iDest)
87
- })
88
- }
89
-
90
- function cpdirSyncRecursive (sourceDir, destDir, options) {
91
- const self = this
92
- if (!options) {
93
- options = {}
94
46
  }
95
- const checkDir = fs.statSync(sourceDir)
47
+
96
48
  try {
97
- fs.mkdirSync(destDir, checkDir.mode)
98
- } catch (e) {
99
- if (e.code !== 'EEXIST') {
100
- throw e
101
- }
102
- }
103
- const files = fs.readdirSync(sourceDir)
104
- for (let i = 0; i < files.length; i++) {
105
- const srcFile = `${sourceDir}/${files[i]}`
106
- const destFile = `${destDir}/${files[i]}`
107
- const srcFileStat = fs.lstatSync(srcFile)
108
- if (srcFileStat.isDirectory()) {
109
- // recursion this thing right on back.
110
- cpdirSyncRecursive.call(self, srcFile, destFile, options)
111
- } else if (srcFileStat.isSymbolicLink()) {
112
- const symlinkFull = fs.readlinkSync(srcFile)
113
- fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null)
114
- // At this point, we've hit a file actually worth copying... so copy it on over.
115
- } else if (fs.existsSync(destFile) && options.noclobber) {
116
- // be silent
117
- } else {
118
- copyFileSync.call(self, srcFile, destFile)
119
- }
49
+ await nodeCp(source, target, { force })
50
+ } catch (err) {
51
+ console.error(`cp: error ${err.message}`)
120
52
  }
121
53
  }
122
54
 
123
- function copyFileSync (src, dest) {
124
- if (!fs.existsSync(src)) {
125
- console.error(`cp: cannot stat ${src}: No such file or directory`)
126
- return
55
+ // copy a directory recursively
56
+ async function copyRecursiveAsync (source, target, force = false) {
57
+ const sExists = await fileExists(source)
58
+ if (!sExists) {
59
+ console.error(`cp: source ${source} does not exist`)
60
+ process.exit(1)
61
+ }
62
+ const sStats = await stat(source)
63
+ if (sStats.isSymbolicLink()) {
64
+ console.error(`cp: source ${source} is a sybolic link`)
65
+ process.exit(1)
127
66
  }
128
67
 
129
- const BUF_LENGTH = 64 * 1024
130
- const buf = Buffer.alloc(BUF_LENGTH)
131
- let bytesRead = BUF_LENGTH
132
- let pos = 0
133
- let fdr = null
134
- let fdw = null
135
-
136
- try {
137
- fdr = fs.openSync(src, 'r')
138
- } catch (e) {
139
- console.error(`cp: cannot open ${src}: ${e.code}`)
140
- return
68
+ const tExists = await fileExists(target)
69
+ if (!tExists) {
70
+ console.error(`cp: target directory ${target} does not exist`)
71
+ process.exit(1)
72
+ }
73
+ const tStats = await stat(target)
74
+ if (tStats.isSymbolicLink()) {
75
+ console.error(`cp: target ${target} is a sybolic link`)
76
+ process.exit(1)
77
+ }
78
+ if (!tStats.isDirectory()) {
79
+ console.error(`cp: target ${target} is not a directory`)
80
+ process.exit(1)
141
81
  }
142
82
 
143
83
  try {
144
- fdw = fs.openSync(dest, 'w')
145
- } catch (e) {
146
- console.error(`cp: cannot write to destination file ${dest}: ${e.code}`)
147
- return
84
+ await nodeCp(source, target, { force, recursive: true })
85
+ } catch (err) {
86
+ console.error(`cp": error ${err.message}`)
148
87
  }
88
+ }
149
89
 
150
- while (bytesRead === BUF_LENGTH) {
151
- bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos)
152
- fs.writeSync(fdw, buf, 0, bytesRead)
153
- pos += bytesRead
90
+ async function fileExists (file) {
91
+ try {
92
+ await access(file, constants.F_OK)
93
+ return true
94
+ } catch (error) {
95
+ return false
154
96
  }
155
-
156
- fs.closeSync(fdr)
157
- fs.closeSync(fdw)
158
- fs.chmodSync(dest, fs.statSync(src).mode)
159
97
  }
package/bin/esmtk.js CHANGED
@@ -1,39 +1,46 @@
1
1
  #!/usr/bin/env node
2
- import cli from 'commander'
3
2
  import { bundle, cp, commonjs, lint, minify } from './commands/index.js'
3
+ import { Command } from 'commander'
4
4
  import { createRequire } from 'module'
5
+ const program = new Command()
5
6
  const require = createRequire(import.meta.url)
6
7
  const pkg = require('../package.json')
7
8
 
8
- cli.version(pkg.version, '-v, --version')
9
- cli.command('lint')
10
- .description('Lint the package using StandardJS')
9
+ program.version(pkg.version, '-v, --version')
10
+
11
+ program.command('lint')
12
+ .description('Lint the source using StandardJS')
11
13
  .option('--fix', 'Automatically fix problems')
12
- .action(opt => {
13
- const flags = opt.fix ? ['--fix'] : []
14
+ .action(options => {
15
+ const flags = options.fix ? ['--fix'] : []
14
16
  lint(flags)
15
17
  })
16
- cli.command('bundle <input> <output>')
18
+
19
+ program.command('bundle <input> <output>')
17
20
  .description('Bundle the source using ESBuild')
18
21
  .action((input, output) => {
19
22
  bundle(input, output)
20
23
  })
21
- cli.command('commonjs <input> <output>')
24
+
25
+ program.command('commonjs <input> <output>')
22
26
  .description('Transpile the source to CommonJS using ESBuild')
23
27
  .action((input, output) => {
24
28
  commonjs(input, output)
25
29
  })
26
- cli.command('minify <input> <output>')
30
+
31
+ program.command('minify <input> <output>')
27
32
  .description('Minify the source using ESBuild')
28
33
  .action((input, output) => {
29
34
  minify(input, output)
30
35
  })
31
- cli.command('cp')
32
- .description('Copy files from the source to the destination')
33
- .usage('[options] [source] [destination]')
36
+
37
+ program.command('cp <source> <target>')
38
+ .usage('[-rf] source target')
39
+ .description('Copy files from the source to the target')
34
40
  .option('-f, --force', 'do not prompt before overwriting')
35
41
  .option('-r, --recursive', 'copy directories recursively')
36
- .action((opt) => {
37
- cp(opt)
42
+ .action((source, target, options) => {
43
+ cp(source, target, options)
38
44
  })
39
- cli.parse(process.argv)
45
+
46
+ program.parse(process.argv)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esmtk",
3
- "version": "0.5.13",
3
+ "version": "0.6.0",
4
4
  "description": "ES Module Toolkit",
5
5
  "keywords": [
6
6
  "esm",
@@ -17,17 +17,17 @@
17
17
  "esmtk": "bin/esmtk.js"
18
18
  },
19
19
  "scripts": {
20
- "lint": "standard",
20
+ "lint": "./bin/esmtk.js lint",
21
21
  "preversion": "npm run lint",
22
22
  "postversion": "git push --follow-tags"
23
23
  },
24
24
  "dependencies": {
25
- "commander": "^8.3.0",
25
+ "commander": "^14.0.3",
26
26
  "esbuild": "^0.13.13",
27
- "glob": "^7.2.0",
28
- "standard": "^16.0.4"
27
+ "glob": "^13.0.6",
28
+ "standard": "^17.1.2"
29
29
  },
30
30
  "engines": {
31
- "node": ">=14"
31
+ "node": ">=17"
32
32
  }
33
33
  }