js-dev-tool 1.0.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/LICENSE +21 -0
- package/README.md +150 -0
- package/basic-types.d.ts +279 -0
- package/common/index.d.ts +43 -0
- package/common/index.js +101 -0
- package/extras/tiny-progress.d.ts +14 -0
- package/extras/tiny-progress.js +74 -0
- package/index.d.ts +27 -0
- package/index.js +15 -0
- package/lib/unzip.min.js +812 -0
- package/lib/zip.min.js +1036 -0
- package/lib/zlibjs.d.ts +34 -0
- package/package.json +51 -0
- package/progress/index.d.ts +92 -0
- package/progress/index.js +305 -0
- package/progress/progress-extras.js +90 -0
- package/progress/rnd-spinner.js +55 -0
- package/progress/spinners.d.ts +74 -0
- package/progress/spinners.json +805 -0
- package/progress/test.js +94 -0
- package/regex.d.ts +154 -0
- package/scripts/publish-version.json +3 -0
- package/scripts/unzip.js +30 -0
- package/scripts/zip.js +138 -0
- package/tool-lib/cjbm.js +239 -0
- package/tool-lib/cjmb-regex-latest.svg +366 -0
- package/tool-lib/cjmb-regex.svg +90 -0
- package/tool-lib/cmt-trick.js +125 -0
- package/tool-lib/ps.js +158 -0
- package/tool-lib/rws.js +181 -0
- package/tool-lib/tools.d.ts +245 -0
- package/tool-lib/zip-task.js +34 -0
- package/tools.d.ts +7 -0
- package/tools.js +450 -0
- package/tsconfig.json +25 -0
- package/utils.d.ts +194 -0
- package/utils.js +643 -0
package/tools.js
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/// <reference path="./tool-lib/tools.d.ts"/>
|
|
3
|
+
/*!
|
|
4
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
5
|
+
Copyright (C) 2019 jeffy-g <hirotom1107@gmail.com>
|
|
6
|
+
Released under the MIT license
|
|
7
|
+
https://opensource.org/licenses/mit-license.php
|
|
8
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
9
|
+
*/
|
|
10
|
+
// @ts-check
|
|
11
|
+
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
/* utilities module by own. */
|
|
15
|
+
const utils = require("./utils");
|
|
16
|
+
|
|
17
|
+
require("./tool-lib/ps").globalize(fs, utils);
|
|
18
|
+
|
|
19
|
+
// /**
|
|
20
|
+
// * @type {ReturnType<typeof utils.getExtraArgs<TToolArgs>>}
|
|
21
|
+
// */
|
|
22
|
+
// @ts-expect-error
|
|
23
|
+
global.params = require("tin-args")();
|
|
24
|
+
// @ts-expect-error
|
|
25
|
+
global.verbose = params.verb;
|
|
26
|
+
|
|
27
|
+
utils.log(params);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* how to config terser, see {@link https://github.com/terser/terser#minify-options-structure Minify options structure}
|
|
31
|
+
*
|
|
32
|
+
* how to fast minify, see {@link https://github.com/terser/terser#terser-fast-minify-mode Terser Fast Minify Mode}
|
|
33
|
+
*
|
|
34
|
+
* @type {import("terser").MinifyOptions}
|
|
35
|
+
*/
|
|
36
|
+
// DEVNOTE: 2020/3/4 - https://terser.org/docs/api-reference
|
|
37
|
+
const terserOptions = {
|
|
38
|
+
ecma: 2019,
|
|
39
|
+
// sourceMap: true,
|
|
40
|
+
parse: {
|
|
41
|
+
shebang: true,
|
|
42
|
+
},
|
|
43
|
+
mangle: true,
|
|
44
|
+
// DEVNOTE: 2020/9/12 - terser latest version is "format"
|
|
45
|
+
output: {
|
|
46
|
+
comments: /@license|@preserve|^(?:!|\*)/,
|
|
47
|
+
indent_level: 1,
|
|
48
|
+
max_line_len: 1500,
|
|
49
|
+
/**
|
|
50
|
+
* @example
|
|
51
|
+
* export enum OutputQuoteStyle {
|
|
52
|
+
* PreferDouble = 0,
|
|
53
|
+
* AlwaysSingle = 1,
|
|
54
|
+
* AlwaysDouble = 2,
|
|
55
|
+
* AlwaysOriginal = 3
|
|
56
|
+
* }
|
|
57
|
+
*/
|
|
58
|
+
quote_style: 3,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const isArray = Array.isArray;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @type {Record<string, TJSToolEntry>}
|
|
66
|
+
*/
|
|
67
|
+
const ToolFunctions = {
|
|
68
|
+
// jstool -cmd zip [-comment "the comment"] lib/webpack.js lib/type-ids.js
|
|
69
|
+
zip: require("./tool-lib/zip-task")(utils),
|
|
70
|
+
/** (r)ecord(W)ebpack(S)ize */
|
|
71
|
+
// jstool -cmd rws [-webpack lib/webpack.js -dest "./dev-extras/webpack-size.json"]
|
|
72
|
+
rws: require("./tool-lib/rws")(fs, utils),
|
|
73
|
+
|
|
74
|
+
//
|
|
75
|
+
// (C)onvert (J)S to (B)rowser (M)odule
|
|
76
|
+
// basePath <js source base directory>
|
|
77
|
+
// jstool -cmd cjbm -basePath extra-tests/mini-semaphore [-targets "['core.js', 'object.js']"]
|
|
78
|
+
//
|
|
79
|
+
cjbm: require("./tool-lib/cjbm")(),
|
|
80
|
+
|
|
81
|
+
// jstool -cmd cmtTrick -targets "['core.js', 'object.js']" [-basePath extra-tests/mini-semaphore]
|
|
82
|
+
cmtTrick: require("./tool-lib/cmt-trick")(),
|
|
83
|
+
|
|
84
|
+
// // jstool -cmd stripWebpack -targets "['dist/umd/index.js', 'dist/webpack/index.js']"
|
|
85
|
+
// stripWebpack: () => {
|
|
86
|
+
// /** @type {string[]} */
|
|
87
|
+
// const targets = params.targets || [];
|
|
88
|
+
// if (params.basePath) {
|
|
89
|
+
// utils.prependStringTo(targets, params.basePath, "/");
|
|
90
|
+
// }
|
|
91
|
+
// // regex - https://regex101.com/r/9E6ssx/2/ [eve-oauth - strip webpack regex]
|
|
92
|
+
// const RE_XXX = params.test || /,\s?\w\.t\s?=\s?function\(\w,\s?\w\s?\)\s?\{[\s\S]+?(?=,\s?r\.o)/;
|
|
93
|
+
// utils.fireReplace(RE_XXX, "", targets); // old: targets.map(name => `./${OUTPUT}/${name}.js`)
|
|
94
|
+
// },
|
|
95
|
+
|
|
96
|
+
// jstool -cmd stripWebpack -regex \"%npm_package_defs_regex%\""
|
|
97
|
+
stripWebpack: {
|
|
98
|
+
taskName: "stripWebpack",
|
|
99
|
+
fn() {
|
|
100
|
+
// https://regex101.com/r/CmraG0/1 // umd only
|
|
101
|
+
const re =
|
|
102
|
+
params.regex ||
|
|
103
|
+
/!function\s*\((.+?)\)(?:(.+?=.\(\)\})|([^]+)(?=\(.\.restrictor\s*\|\|))/g;
|
|
104
|
+
if (re) {
|
|
105
|
+
processSources(this.taskName, (data) => data.replace(re, ""), {
|
|
106
|
+
base: "",
|
|
107
|
+
targets: [
|
|
108
|
+
"./dist/umd/index.js",
|
|
109
|
+
"./dist/webpack/index.js",
|
|
110
|
+
"./dist/webpack-esm/index.mjs",
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
// processSources(
|
|
114
|
+
// this.taskName, data => {
|
|
115
|
+
// const result = data.replace(re, ($0, $1, $2, $3) => {
|
|
116
|
+
// console.log("[stripWebpack] hit!");
|
|
117
|
+
// return `((${$1})=>${$2 || $3})`;
|
|
118
|
+
// });
|
|
119
|
+
// return result;
|
|
120
|
+
// }, {
|
|
121
|
+
// base: "",
|
|
122
|
+
// // specify default targets when user omitted
|
|
123
|
+
// // DEVNOTE: 2023/10/23 - match `umd` only...
|
|
124
|
+
// targets: ["./dist/umd/index.js", "./dist/webpack/index.js", "./dist/webpack-esm/index.mjs"]
|
|
125
|
+
// }
|
|
126
|
+
// );
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
help: 'jstool -cmd stripWebpack -regex "%npm_package_defs_regex%"',
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Performs string substitutions on various file contents
|
|
134
|
+
*
|
|
135
|
+
* + Rquired params - `regex`, `targets` or params.args
|
|
136
|
+
*
|
|
137
|
+
* @date 2020/6/11
|
|
138
|
+
*/
|
|
139
|
+
// jstool -cmd stripSome -regex \"/^\\s+<!--[\\s\\S]+?-->(?:\\r?\\n)?/gm\""
|
|
140
|
+
stripSome: {
|
|
141
|
+
taskName: "stripSome",
|
|
142
|
+
fn() {
|
|
143
|
+
const re = params.regex;
|
|
144
|
+
const after = params.after || "";
|
|
145
|
+
if (re) {
|
|
146
|
+
processSources(this.taskName, (data) => data.replace(re, after), {
|
|
147
|
+
base: "",
|
|
148
|
+
targets: params.args || params.targets,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
help: `jstool -cmd stripSome [-after <replacement>] -regex \"/^\\s+<!--[\\s\\S]+?-->(?:\\r?\\n)?/gm\" [-targets "<path>,<path>,..." | <args: file, file file...>]
|
|
153
|
+
note:
|
|
154
|
+
targets - must be array type arg, "['<path>', '<path>',...]" or "<path>,<path>,..."
|
|
155
|
+
note: targets - can use args parameter instead
|
|
156
|
+
It is better to use the <args: file, file file...>
|
|
157
|
+
e.g - jstool -cmd stripSome -after ".." -regex "re/(?<=reference path=\")(\\.)(?=\\/index.d.ts\")/" build/**/*.js
|
|
158
|
+
^^^^^^^^^^^^^
|
|
159
|
+
`,
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// jstool -cmd version -extras "test/web/index.html,"
|
|
163
|
+
version: {
|
|
164
|
+
taskName: "version",
|
|
165
|
+
fn() {
|
|
166
|
+
let { major, minor /*, patch*/, pkgJsons = ["./package.json"] } = params;
|
|
167
|
+
/** @type {string} */
|
|
168
|
+
let currentVersion;
|
|
169
|
+
/** @type {string} */
|
|
170
|
+
let nextVersion;
|
|
171
|
+
// DEVNOTE: 2025/02/07 - see https://regex101.com/r/xXl3eC/3
|
|
172
|
+
utils.fireReplace(
|
|
173
|
+
/"?version("\s*:\s*)?\s"?(\d+)\.(\d+)\.(\d+)(-\w+)?"?/,
|
|
174
|
+
/** @type {TStringReplacer} */($0, isJson, $major, $minor, $patch, tag) => {
|
|
175
|
+
/** @type {string | number} */
|
|
176
|
+
let _major = $major;
|
|
177
|
+
/** @type {string | number} */
|
|
178
|
+
let _minor = $minor;
|
|
179
|
+
/** @type {string | number} */
|
|
180
|
+
let _patch = $patch;
|
|
181
|
+
if (major) {
|
|
182
|
+
_minor = 0;
|
|
183
|
+
_major = +_major + 1;
|
|
184
|
+
} else if (minor) {
|
|
185
|
+
_minor = +_minor + 1;
|
|
186
|
+
}
|
|
187
|
+
if (major || minor) {
|
|
188
|
+
_patch = 0;
|
|
189
|
+
} else {
|
|
190
|
+
_patch = +_patch + 1;
|
|
191
|
+
}
|
|
192
|
+
// keep current version string, usage for replace extras
|
|
193
|
+
currentVersion = `${$major}.${$minor}.${$patch}${tag ? tag : ""}`;
|
|
194
|
+
nextVersion = `${_major}.${_minor}.${_patch}${tag ? tag : ""}`;
|
|
195
|
+
return isJson ? `"version": "${nextVersion}"` : `version ${nextVersion}`;
|
|
196
|
+
},
|
|
197
|
+
pkgJsons,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const paths = isArray(params.extras)
|
|
201
|
+
? params.extras
|
|
202
|
+
: typeof params.extras === "string"
|
|
203
|
+
? [params.extras]
|
|
204
|
+
: [];
|
|
205
|
+
if (paths.length) {
|
|
206
|
+
utils.fireReplace(/(v)?(\d+\.\d+\.\d+)(-\w+)?/g, /** @type {TStringReplacer} */($0, $prefix, $1, $2) => {
|
|
207
|
+
if ($1 === currentVersion && $prefix) {
|
|
208
|
+
return "v" + nextVersion; // + ($2? $2: "");
|
|
209
|
+
}
|
|
210
|
+
return $0;
|
|
211
|
+
},
|
|
212
|
+
paths,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
console.log("version updated: %s", nextVersion);
|
|
217
|
+
},
|
|
218
|
+
help: `jstool -cmd version [-major | -minor] [-pkgJsons "./package.json,../package.json"] [-extras "test/web/index.html"]
|
|
219
|
+
bump top level package.json version(can specify "package.json" paths by \`pkgJsons\` option if need), specify patch version is unnecessary.
|
|
220
|
+
note:
|
|
221
|
+
extras - can be "<path>,<path>,..." (array type arg)
|
|
222
|
+
`,
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
// jstool -cmd minify -basePath extra-tests/web/mini-semaphore
|
|
226
|
+
minify: {
|
|
227
|
+
taskName: "minify",
|
|
228
|
+
fn() {
|
|
229
|
+
// DEVNOTE: 12:05 2020/03/04 - minify with `terser`
|
|
230
|
+
// DEVNOTE: 2020/9/12 - terser(since v5.3.1? "minify" is now returns promise
|
|
231
|
+
const Terser = require("terser");
|
|
232
|
+
const sx = params.suffix;
|
|
233
|
+
let suffix = ".mini";
|
|
234
|
+
if (typeof sx === "string") {
|
|
235
|
+
suffix = sx.length ? sx : "";
|
|
236
|
+
}
|
|
237
|
+
/** @type {TProcessSourcesOpt} */
|
|
238
|
+
const opt = {
|
|
239
|
+
test: params.test || /\.js$/,
|
|
240
|
+
suffix,
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
if (isArray(params.basePath)) {
|
|
244
|
+
opt.bases = params.basePath;
|
|
245
|
+
} else {
|
|
246
|
+
opt.base = params.basePath;
|
|
247
|
+
}
|
|
248
|
+
processSources(
|
|
249
|
+
// @ts- ignore
|
|
250
|
+
this.taskName,
|
|
251
|
+
async (data) => {
|
|
252
|
+
// console.log(data);
|
|
253
|
+
const p = /** @type {Promise<import("terser").MinifyOutput>} */ (
|
|
254
|
+
Terser.minify(data, terserOptions)
|
|
255
|
+
);
|
|
256
|
+
// console.log({}.toString.call(p)); // [object Promise]
|
|
257
|
+
return /** @type {string} */ ((await p).code);
|
|
258
|
+
},
|
|
259
|
+
opt,
|
|
260
|
+
);
|
|
261
|
+
},
|
|
262
|
+
help: `jstool -cmd minify -basePath extra-tests/web/mini-semaphore [-test "re/\\.js$/"] [-suffix ".mini"]
|
|
263
|
+
note:
|
|
264
|
+
basePath - can be "<path>,<path>,..." (array type arg)
|
|
265
|
+
test - can be omit, default is \`/\\.js$/\`
|
|
266
|
+
suffix - can be omit, default is ".mini"
|
|
267
|
+
`,
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// rmc version 3.x
|
|
271
|
+
/**
|
|
272
|
+
* NOTE: keep comment that start with "/*" when "*/" end mark appears in same line.
|
|
273
|
+
*
|
|
274
|
+
* + if start with "/*-" remove it
|
|
275
|
+
*/
|
|
276
|
+
rmc: {
|
|
277
|
+
taskName: "rm-cstyle-cmts",
|
|
278
|
+
fn() {
|
|
279
|
+
const rmc = require("rm-cstyle-cmts");
|
|
280
|
+
if (params.rmc4ts) {
|
|
281
|
+
rmc.setListener(({ event, fragment }) => {
|
|
282
|
+
if (event === /*EScannerEvent.MultiLineComment*/ 1) {
|
|
283
|
+
// DEVNOTE: \b is not contained LF
|
|
284
|
+
return /^\/\*(\*|!)\s|^\/\*(?!-).+\*\/$/.test(fragment);
|
|
285
|
+
}
|
|
286
|
+
// DEVNOTE: this detection is rmc default
|
|
287
|
+
// else if (event === /*ScannerEvent.SingleLineComment*/0) {
|
|
288
|
+
// return /(?:\/\/\/?\s+@ts-\w+|\/\/\/\s*<reference)/.test(fragment);
|
|
289
|
+
// }
|
|
290
|
+
// else if (event === /*ScannerEvent.ES6Template*/2) {
|
|
291
|
+
// ;
|
|
292
|
+
// }
|
|
293
|
+
return false;
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
const targets = params.targets;
|
|
297
|
+
const basePaths = isArray(params.basePath)
|
|
298
|
+
? params.basePath
|
|
299
|
+
: [params.basePath];
|
|
300
|
+
processSources(
|
|
301
|
+
/** @type {string} */ (this.taskName),
|
|
302
|
+
(data) => {
|
|
303
|
+
/*
|
|
304
|
+
const after = rmc(data);
|
|
305
|
+
return after.replace(/"use strict";\s/m, "");
|
|
306
|
+
// // purge typescript v3.9.x extra statement
|
|
307
|
+
// return after.replace(/\s(exports\.\w+\s=\s)+void 0;/m, "");
|
|
308
|
+
/*/
|
|
309
|
+
return rmc(data);
|
|
310
|
+
//*/
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
bases: basePaths,
|
|
314
|
+
targets,
|
|
315
|
+
suffix: params.suffix,
|
|
316
|
+
test: params.test || /\.js$/,
|
|
317
|
+
},
|
|
318
|
+
);
|
|
319
|
+
},
|
|
320
|
+
help: `$ jstool -cmd rmc -basePath "./dist/cjs,./dist/cjs/gulp" -test "/\\.(js|d\\.ts)$/"
|
|
321
|
+
note: basePath - can be "<path>,<path>,..." (array type arg)
|
|
322
|
+
test - can be omit, defulat \`/\.js$/\`
|
|
323
|
+
rmc4ts - for typescript source.
|
|
324
|
+
keep comment that start with "/*" when "*/" end mark appears in same line.
|
|
325
|
+
if start with "/*-" remove it
|
|
326
|
+
`,
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
// 2020/2/21
|
|
330
|
+
backup: {
|
|
331
|
+
taskName: "backup",
|
|
332
|
+
fn() {
|
|
333
|
+
// @ts-ignore
|
|
334
|
+
const archiver = require("archiver");
|
|
335
|
+
const archive = archiver("zip", {
|
|
336
|
+
// comment, deplicated, unzip.min will fail decompress...
|
|
337
|
+
zlib: { level: 9 }, // Sets the compression level.
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// TODO: Parameterize these settings
|
|
341
|
+
// node backup-session -dest "../tmp" -projectName cerebral-web-dev
|
|
342
|
+
const destDir = params.dest || "../tmp";
|
|
343
|
+
const projectName = params.projectName || "anonymouse";
|
|
344
|
+
const prefix = utils.dateStringForFile(true);
|
|
345
|
+
|
|
346
|
+
/* [https://nodejs.org/api/repl.html]
|
|
347
|
+
* Accessing Core Node.js Modules#
|
|
348
|
+
* The default evaluator will automatically load Node.js core modules into the REPL environment when used.
|
|
349
|
+
* For instance, unless otherwise declared as a global or scoped variable, the input fs will be evaluated on-demand as global.fs = require('fs').
|
|
350
|
+
*/
|
|
351
|
+
// @ts- ignore fs is already imported at node REPL
|
|
352
|
+
const output = fs.createWriteStream(`${destDir}/${prefix}-${projectName}-backup.zip`)
|
|
353
|
+
.on("close", function () {
|
|
354
|
+
console.log(archive.pointer() + " total bytes");
|
|
355
|
+
console.log(
|
|
356
|
+
"archiver has been finalized and the output file descriptor has closed.",
|
|
357
|
+
);
|
|
358
|
+
})
|
|
359
|
+
.on("end", function () {
|
|
360
|
+
console.log("Data has been drained");
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
archive.on("progress", (progress) => {
|
|
364
|
+
// console.log(progress); too many infos...
|
|
365
|
+
console.log(progress.entries.processed);
|
|
366
|
+
});
|
|
367
|
+
archive.pipe(output);
|
|
368
|
+
archive.glob("{*,*/**/.*,*/**/*,.*,.*/**/*,.*/**/.*}", {
|
|
369
|
+
cwd: `${destDir}/${projectName}/`,
|
|
370
|
+
// root: "../tmp/cerebral-web-dev/",
|
|
371
|
+
// dot: true,
|
|
372
|
+
});
|
|
373
|
+
archive.finalize();
|
|
374
|
+
},
|
|
375
|
+
help: 'npx cpx "./{*,*/.*,.*,.*/**/*,!(node_modules|lib)/**/!(eve.db*|etag.json)}" ../tmp/my-project -v -u && npx rimraf ../tmp/my-project/node_modules && jstool -cmd backup -projectName my-project\n\
|
|
376
|
+
\ \ result zip name form: <date string>-<projectName>-backup.zip',
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* @param {TJSToolEntry} entry
|
|
382
|
+
* @returns {entry is TJSToolEntry}
|
|
383
|
+
*/
|
|
384
|
+
function isJSToolEntry(entry) {
|
|
385
|
+
if (typeof entry !== "object") return false;
|
|
386
|
+
return typeof entry.fn === "function" && typeof entry.help === "string";
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
let colorEnable = false;
|
|
390
|
+
function enableColors() {
|
|
391
|
+
if (!colorEnable) {
|
|
392
|
+
require("colors.ts");
|
|
393
|
+
colorEnable = true;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* @param {string} cmd
|
|
398
|
+
* @returns {void}
|
|
399
|
+
*/
|
|
400
|
+
function printHelp(cmd) {
|
|
401
|
+
enableColors();
|
|
402
|
+
const entry = ToolFunctions[cmd];
|
|
403
|
+
console.log(`${cmd.yellow + " help:".green} ${entry.help.gray(8)}`);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (params.cmd) {
|
|
407
|
+
// DEVNOTE: 2023/10/27 - new feature `mode`
|
|
408
|
+
const [task, mode] = params.cmd.split(":");
|
|
409
|
+
const entry = ToolFunctions[task];
|
|
410
|
+
isJSToolEntry(entry) && entry.fn(mode);
|
|
411
|
+
} else if (params.shell) {
|
|
412
|
+
// DEVNOTE: 2025/2/1 23:40:24 new feature shell
|
|
413
|
+
// const [task, mode] = params.shell.split(":");
|
|
414
|
+
const SCRIPT_DIR = path.dirname(process.argv[1]);
|
|
415
|
+
// console.log(process.cwd());
|
|
416
|
+
// console.log(process.argv);
|
|
417
|
+
// console.log(`SCRIPT_DIR: ${SCRIPT_DIR}`);
|
|
418
|
+
const arg = `${params.major ? "-major" : params.minor ? "-minor" : ""}`;
|
|
419
|
+
utils.execWithOutputResult(
|
|
420
|
+
// DEVNOTE: 2025/5/16 11:42:05 - 現在, version command の arg のみ support
|
|
421
|
+
`bash ${SCRIPT_DIR}/scripts/tool.sh ${params.shell} ${arg}`,
|
|
422
|
+
(result) => {
|
|
423
|
+
console.log(result);
|
|
424
|
+
},
|
|
425
|
+
process.cwd(),
|
|
426
|
+
);
|
|
427
|
+
} else if (params.v) {
|
|
428
|
+
// show version
|
|
429
|
+
enableColors();
|
|
430
|
+
const thisVersion = require("./package.json").version;
|
|
431
|
+
console.log(
|
|
432
|
+
`${"jstool".magenta} in "js-dev-scripts", version: ${thisVersion.green}
|
|
433
|
+
more details see ${"https://github.com/jeffy-g/js-dev-scripts".blue}`,
|
|
434
|
+
);
|
|
435
|
+
} else {
|
|
436
|
+
if (params.help) {
|
|
437
|
+
const cmdName = params.help;
|
|
438
|
+
if (typeof cmdName === "string") {
|
|
439
|
+
printHelp(cmdName);
|
|
440
|
+
} else {
|
|
441
|
+
const commands = Object.keys(ToolFunctions);
|
|
442
|
+
console.log(`
|
|
443
|
+
Usage: node jstool -cmd <command name>
|
|
444
|
+
- - - - available commands:`);
|
|
445
|
+
for (const cmd of commands) {
|
|
446
|
+
printHelp(cmd);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"newLine": "LF",
|
|
4
|
+
"skipDefaultLibCheck": true,
|
|
5
|
+
"skipLibCheck": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"removeComments": false,
|
|
8
|
+
"moduleResolution": "nodenext",
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"baseUrl": "./",
|
|
11
|
+
"allowJs": true,
|
|
12
|
+
"checkJs": true,
|
|
13
|
+
"target": "es2019",
|
|
14
|
+
"module": "node18",
|
|
15
|
+
"outDir": "./build"
|
|
16
|
+
},
|
|
17
|
+
"include": [
|
|
18
|
+
"./*.js",
|
|
19
|
+
"./**/*.js",
|
|
20
|
+
"./**/*.d.ts"
|
|
21
|
+
],
|
|
22
|
+
"exclude": [
|
|
23
|
+
// "./extras/**/*.js",
|
|
24
|
+
]
|
|
25
|
+
}
|
package/utils.d.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
Copyright (C) 2022 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
Released under the MIT license
|
|
5
|
+
https://opensource.org/licenses/mit-license.php
|
|
6
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
8
|
+
/// <reference types="node"/>
|
|
9
|
+
/// <reference path="./basic-types.d.ts"/>
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
Dirent
|
|
13
|
+
} from "fs";
|
|
14
|
+
|
|
15
|
+
export const getExtraArgs: typeof import("tin-args");
|
|
16
|
+
|
|
17
|
+
export type TFsCallback = (err: any, data: string) => void;
|
|
18
|
+
/**
|
|
19
|
+
* <T>
|
|
20
|
+
*/
|
|
21
|
+
export type TypedRecord<T> = {
|
|
22
|
+
[x: string]: T;
|
|
23
|
+
};
|
|
24
|
+
export type TReadJsonCallback<T> = (err: any, data: Record<string, T>) => void;
|
|
25
|
+
export type TExtraArgsValue = string | boolean | RegExp | string[];
|
|
26
|
+
/**
|
|
27
|
+
* prepend `content` to the beginning of each element of `str_array`
|
|
28
|
+
*
|
|
29
|
+
* form:
|
|
30
|
+
* ```js
|
|
31
|
+
* `${content}${suffix}${<str_array element>}`
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @param {string[]} str_array the string array
|
|
35
|
+
* @param {string} content prepend content
|
|
36
|
+
* @param {string} [suffix]
|
|
37
|
+
* @date 2020/2/16
|
|
38
|
+
* @version 2.0 rename `appendStringTo` -> `prependStringTo`
|
|
39
|
+
*/
|
|
40
|
+
export function prependStringTo(str_array: string[], content: string, suffix?: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* get node version at runtime.
|
|
43
|
+
*
|
|
44
|
+
* format must be `v\d+.\d+.\d+`
|
|
45
|
+
*
|
|
46
|
+
* ex:
|
|
47
|
+
* ```
|
|
48
|
+
* const utils = require("./utils");
|
|
49
|
+
* const nv = utils.extractVersion();
|
|
50
|
+
* console.log(nv); // => {major: 10, minor: 9, patch: 0}
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @param {string} versionString default is process.version
|
|
54
|
+
*/
|
|
55
|
+
export function extractVersion(versionString?: string): {
|
|
56
|
+
major: number;
|
|
57
|
+
minor: number;
|
|
58
|
+
patch: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* use toLocaleString
|
|
62
|
+
* @param {any} ymd use simple year month day formant? default `false`
|
|
63
|
+
* + should be truthy/falsy value
|
|
64
|
+
*/
|
|
65
|
+
export function dateStringForFile(ymd?: any): string;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* use "rm-cstyle-cmts"
|
|
69
|
+
*
|
|
70
|
+
* @param {string} source
|
|
71
|
+
*/
|
|
72
|
+
export function removeJsonComments(source: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* write text content to dest path.
|
|
75
|
+
* when not exists parent directory, creat it.
|
|
76
|
+
*
|
|
77
|
+
* @param {string|NodeJS.ReadableStream|Buffer} content text? content.
|
|
78
|
+
* @param {string} dest content output path
|
|
79
|
+
* @param {() => void} [callback] the callback function
|
|
80
|
+
*/
|
|
81
|
+
export function writeTextUTF8(content: string | NodeJS.ReadableStream | Buffer, dest: string, callback?: () => void): void;
|
|
82
|
+
/**
|
|
83
|
+
* @typedef {(err: any, data: string) => void} TFsCallback
|
|
84
|
+
*/
|
|
85
|
+
/**
|
|
86
|
+
* @param {string} from file path.
|
|
87
|
+
* @param [callback]
|
|
88
|
+
*/
|
|
89
|
+
export function readTextUTF8<C extends TBD<TFsCallback>, R extends undefined extends C ? string : void>(from: string, callback?: C): R;
|
|
90
|
+
/**
|
|
91
|
+
* @template T
|
|
92
|
+
* @typedef {Record<string, T>} TypedRecord<T>
|
|
93
|
+
*/
|
|
94
|
+
/**
|
|
95
|
+
* @template T
|
|
96
|
+
* @typedef {(err: any, data: TypedRecord<T>) => void} TReadJsonCallback
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* NOTE: when callback specified, returns undefined
|
|
100
|
+
*
|
|
101
|
+
* @param {string} path
|
|
102
|
+
* @param [callback]
|
|
103
|
+
*/
|
|
104
|
+
export function readJson<T, C extends TBD<TReadJsonCallback<string>>, R extends undefined extends C ? TypedRecord<T> : void>(path: string, callback?: C): R;
|
|
105
|
+
/**
|
|
106
|
+
*
|
|
107
|
+
* @param {string} path
|
|
108
|
+
* @param {(dirent: Dirent) => void} handler
|
|
109
|
+
*/
|
|
110
|
+
export function walkDirSync(path: string, handler: (dirent: Dirent) => void): void;
|
|
111
|
+
/**
|
|
112
|
+
* create sourceName zip. (using zip.min.js
|
|
113
|
+
*
|
|
114
|
+
* @param {string} scriptPath simple script file name. e.g - webpack (original path are "./lib/webpack.js")
|
|
115
|
+
* @param {string} comment the zip file comment.
|
|
116
|
+
*/
|
|
117
|
+
export function compressScript(scriptPath: string, comment?: string): void;
|
|
118
|
+
/**
|
|
119
|
+
* DEVNOTE: 10/21/2018, 9:15:00 PM - using "archiver" package, this is too fast!.
|
|
120
|
+
*
|
|
121
|
+
* @param {string} scriptPath
|
|
122
|
+
* @param {string} comment
|
|
123
|
+
*/
|
|
124
|
+
export function compressScript2(scriptPath: string, comment?: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* it is bundled in webpack.js, other code becomes unnecessary.(at webpack
|
|
127
|
+
*
|
|
128
|
+
* + 📝 using "exec" internally
|
|
129
|
+
* * 🆗️ can use pipe command
|
|
130
|
+
*
|
|
131
|
+
* @param {string} command
|
|
132
|
+
* @param {(result: string) => void} doneCallbackWithArgs gulp callback function.
|
|
133
|
+
* @param {string=} cwd 2025/2/1 current working directory
|
|
134
|
+
*/
|
|
135
|
+
export function execWithOutputResult(command: string, doneCallbackWithArgs: (result: string) => void, cwd?: string): any;
|
|
136
|
+
/**
|
|
137
|
+
* ### generate npm global package update script (windows command)
|
|
138
|
+
*
|
|
139
|
+
* ```js
|
|
140
|
+
* const utils = require("./utils");
|
|
141
|
+
* // ...
|
|
142
|
+
* // execute normally
|
|
143
|
+
* utils.genGlobalNpmUpdateScript("electron", "workbox-cli");
|
|
144
|
+
* // debug
|
|
145
|
+
* utils.genGlobalNpmUpdateScript("--debug", "electron", "workbox-cli");
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @param {string[]} excludes
|
|
149
|
+
*/
|
|
150
|
+
export function genGlobalNpmUpdateScript(...excludes: string[]): void;
|
|
151
|
+
/**
|
|
152
|
+
* use for gulp.dest(...)
|
|
153
|
+
*
|
|
154
|
+
* **useful when glob pattern can not be used (when path must be explicitly specified).**
|
|
155
|
+
*
|
|
156
|
+
* ```js
|
|
157
|
+
* gulp.src([
|
|
158
|
+
* "./src/app-config.ts",
|
|
159
|
+
* "./src/auth/{eve-sso,eve-sso-v2e}.php"
|
|
160
|
+
* ]).pipe(
|
|
161
|
+
* ...
|
|
162
|
+
* ).pipe(gulp.dest((vinyl) => {
|
|
163
|
+
* return convertRelativeDir(vinyl);
|
|
164
|
+
* })).on("end", () => {
|
|
165
|
+
* console.log("done");
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
* @param {import("vinyl")} vinyl
|
|
169
|
+
* @param {string} dest default is "." -> node launched directory. (cwd?)
|
|
170
|
+
*/
|
|
171
|
+
export function convertRelativeDir(vinyl: any, dest?: string): string;
|
|
172
|
+
/**
|
|
173
|
+
* ### command:
|
|
174
|
+
*
|
|
175
|
+
* + windows - chcp 65001 && clip
|
|
176
|
+
* + others - xclip
|
|
177
|
+
*
|
|
178
|
+
* @param {string} content the copy terget content as string.
|
|
179
|
+
* @param {string} [message] default: "text copied!"
|
|
180
|
+
* @param {boolean} [chcp65001] default `true`
|
|
181
|
+
*/
|
|
182
|
+
export function copyText(content: string, message?: string, chcp65001?: boolean): void;
|
|
183
|
+
/**
|
|
184
|
+
* @param {RegExp} regex
|
|
185
|
+
* @param {string | Function} replacement
|
|
186
|
+
* @param {string[]} paths Paths that do not exist are ignored
|
|
187
|
+
* @param {boolean} [async]
|
|
188
|
+
*
|
|
189
|
+
* @date 2019-4-26
|
|
190
|
+
*/
|
|
191
|
+
export function fireReplace(regex: RegExp, replacement: string | Function, paths: string[], async?: boolean): void;
|
|
192
|
+
|
|
193
|
+
export const CI: boolean;
|
|
194
|
+
export const log: typeof console.log;
|