js-dev-tool 1.2.20 → 1.2.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-dev-tool",
3
- "version": "1.2.20",
3
+ "version": "1.2.22",
4
4
  "type": "commonjs",
5
5
  "bin": {
6
6
  "jstool": "tools.js",
package/progress/index.js CHANGED
@@ -14,6 +14,7 @@ const {
14
14
  wppHandlerV4,
15
15
  isWebpackV5later,
16
16
  } = require("./progress-extras");
17
+ const _log = console.log;
17
18
  /**
18
19
  *
19
20
  * @param {string[]} frames progress frame.
@@ -106,7 +107,7 @@ const createProgressObject = (frames, formatOpt, messageEmitter) => {
106
107
  * adjust to next line
107
108
  */
108
109
  newLine() {
109
- console.log();
110
+ _log();
110
111
  },
111
112
  /**
112
113
  * change the fps rate
@@ -204,7 +205,7 @@ function createWebpackProgressPluginHandler(
204
205
  {
205
206
  const shortenProgress = (/** @type {number} */ pct) => {
206
207
  renderer(formatPercentage(pct));
207
- pct === 1 && (console.log(), (dotted = 0));
208
+ pct === 1 && (_log(), (dotted = 0));
208
209
  };
209
210
  if (logFilePath !== void 0) {
210
211
  const wppLogger = lib.createLogStreamAndResolvePath(logFilePath);
@@ -8,6 +8,7 @@
8
8
  /// <reference path="./index.d.ts"/>
9
9
  "use strict";
10
10
  const lib = require("../common");
11
+ const _log = console.log;
11
12
  const checkENV = () => {
12
13
  const env = process.env;
13
14
  if (env.CI) return "ci";
@@ -32,7 +33,7 @@ const wppHandlerV4 = ((renderer, cwd) => {
32
33
  message +
33
34
  ` [${modules}, ${actives}] ${path}`,
34
35
  );
35
- percentage === 1 && console.log();
36
+ percentage === 1 && _log();
36
37
  };
37
38
  })(lib.renderLine, process.cwd());
38
39
  /** @type {TWebpackProgressHandler} */
@@ -46,7 +47,7 @@ const wppHandlerV5 = ((renderer/*, cwd*/) => {
46
47
  renderer(
47
48
  `pct: ${(percentage * 100).toFixed(4)}%, process: [${message}]${pathOrPluginName ? `, info: [${pathOrPluginName}]` : ""}${args.length ? " - " : ""}${args[0]?.slice(args[0].length - maxLen) || ""}`,
48
49
  );
49
- percentage === 1 && console.log();
50
+ percentage === 1 && _log();
50
51
  };
51
52
  })(lib.renderLine/*, process.cwd()*/);
52
53
  /** @type {boolean} */
package/tool-lib/cjbm.js CHANGED
@@ -109,8 +109,9 @@ function getReplacer(ext) {
109
109
  }
110
110
  /**
111
111
  * @param {string} ext
112
+ * @param {NsJsTool.TDevConsole} logger
112
113
  */
113
- const emitProcessCallback = (ext) => {
114
+ const emitProcessCallback = (ext, logger) => {
114
115
  /**
115
116
  * @param {string[]} sourceFiles
116
117
  */
@@ -126,7 +127,7 @@ const emitProcessCallback = (ext) => {
126
127
  fs.rename(sourceFile, afterPath, err => {
127
128
  if (err) console.error(err);
128
129
  else {
129
- console.log(`renamed: ${sourceFile} => ${afterPath}`);
130
+ logger.log(`renamed: ${sourceFile} => ${afterPath}`);
130
131
  }
131
132
  });
132
133
  }
@@ -143,7 +144,7 @@ module.exports = () => {
143
144
  /**
144
145
  * about regex: see [[tools.js] regex - (C)onvert (J)S to (B)rowser (M)odule](https://regex101.com/r/EpuQLT/37)
145
146
  */
146
- fn() {
147
+ fn(logger) {
147
148
  const bases = getBasePaths();
148
149
  const ext = params.ext || "js";
149
150
  /**
@@ -157,22 +158,25 @@ module.exports = () => {
157
158
  return data.replace(reImportExportDetection, getReplacer(ext));
158
159
  }, {
159
160
  bases,
160
- cb: emitProcessCallback(ext)
161
+ cb: emitProcessCallback(ext, logger)
161
162
  },
162
163
  );
163
164
  },
164
165
  get help() {
165
- return `${this.taskName}
166
- ex - jstool -cmd cjbm [-root ./build | -basePath "./dist/esm,extra-tests/mini-semaphore"] [-ext js] [-test /\\.js$/] [-targets "['core.js', 'object.js']"]
167
- note:
168
- root - Recursively searches for files.
169
- This option is useful, but if there are directories that need to be avoided, use the 'basePath' option
170
- basePath - can be "<path>,<path>,..." (array type arg)
171
- ext - specifies the module extension for import/export clauses. default is "js"
172
- test - Any file extension can be specified. (The default is /\\.js$/)
173
- targets - specify this if you want to apply it only to a specific file.
174
- the file specified here should be directly under \`basePath\`!
175
- value must be array type arg, "['<path>', '<path>',...]" or "<path>,<path>,..."
166
+ const level = 16;
167
+ return `jstool -cmd cjbm [-root "./build" | -basePath "./dist/esm,extra-tests/mini-semaphore"] [-ext "js"] [-test "/\\.js$/"] [-targets "['core.js', 'object.js']"]
168
+
169
+ ${" Example:".red}
170
+ ${"jstool".yellow} ${"-cmd".green} ${"cjbm".cyan} ${"-basePath".green} ${"dist/esm,extra-tests/mini-semaphore".gray(level)} ${"-targets".green} ${"core.js,object.js".gray(level)}
171
+
172
+ ${" Options:".red}
173
+ ${" root".cyan} ${`: Recursively scan a single root directory.`.gray(level)}
174
+ ${" basePath".cyan} ${`: Source directory path(s). Use this when you want tighter scan control.`.gray(level)}
175
+ ${" ext".cyan} ${`: Module extension used in import/export clauses. default is "js".`.gray(level)}
176
+ ${" test".cyan} ${`: Target file matcher. default is /\\.js$/.`.gray(level)}
177
+ ${" targets".cyan} ${`: Limit processing to specific files directly under basePath.`.gray(level)}
178
+
179
+ ${" Note:".magenta} ${`targets accepts comma-separated values or array type arg such as "['core.js','object.js']".`.gray(level)}
176
180
  `;
177
181
  },
178
182
  };
@@ -12,10 +12,10 @@
12
12
  * @file comment trick toggle
13
13
  */
14
14
  /**
15
- *
16
15
  * @param {string} code
16
+ * @param {NsJsTool.TDevConsole} logger
17
17
  */
18
- function cleanup(code) {
18
+ function cleanup(code, logger) {
19
19
  const reCleanUp = new RegExp(
20
20
  "\s*\/(?:\s*\/+\*\s+(?:ctt|comment-toggle-trick|https:\/\/coderwall)([\s\S]+?)(?:\s+)\/\*\/[\s\S]+|\s*\*\s+(?:ctt|comment-toggle-trick|https:\/\/coderwall)[\s\S]+\/\*\/([\s\S]+?))\s*\/{2,}\*\/", "g"
21
21
  );
@@ -25,12 +25,13 @@ function cleanup(code) {
25
25
  }
26
26
  /**
27
27
  * @param {string} code
28
+ * @param {NsJsTool.TDevConsole} logger
28
29
  */
29
- function doIt(code) {
30
+ function doIt(code, logger) {
30
31
  return code.replace(
31
32
  /\/+(?=\*\s?(ctt|comment-toggle-trick|https:\/\/coderwall))/g, ($0) => {
32
33
  const slashes = $0.length === 2 ? "/" : "//";
33
- console.log(
34
+ logger.log(
34
35
  "the-comment-toggle-trick: %s",
35
36
  /*enableBefore*/ slashes.length === 2
36
37
  ? "-->enable before<--, mute after"
@@ -47,24 +48,28 @@ function doIt(code) {
47
48
  module.exports = () => {
48
49
  return {
49
50
  taskName: "comment trick toggle",
50
- fn(mode) {
51
+ fn(logger, mode) {
51
52
  processSources(
52
53
  /** @type {string} */ (this.taskName), (code) => {
53
- return mode === "clean" ? cleanup(code) : doIt(code);
54
+ return mode === "clean" ? cleanup(code, logger) : doIt(code, logger);
54
55
  }, {
55
56
  ...params,
56
57
  },
57
58
  );
58
59
  },
59
60
  get help() {
60
- return `Do comment trick toggle
61
- It recognizes three markers: \`ctt | comment-toggle-trick | https://coderwall\`
62
- jstool -cmd cmtTrick[:clean] (-base <source dir> | -bases "<source dir>,<source dir>,...") [-test re/\\\\.js$/]
63
- note:
64
- :clean - remove comment token etc leaving the currently enabled code
65
- base (or root) - scan single source folder
66
- bases - must be array type arg, "['<path>', '<path>',...]" or "<path>,<path>,..."
67
- test - terget extension, default is /\\\\.js$/
61
+ const level = 16;
62
+ return `jstool -cmd cmtTrick[:clean] (-basePath "<source dir>" | -basePath "<source dir>,<source dir>,...") [-test "re/\\\\.js$/"]
63
+
64
+ ${" Example:".red}
65
+ ${"jstool".yellow} ${"-cmd".green} ${"cmtTrick:clean".cyan} ${"-basePath".green} ${"src,examples".gray(level)} ${"-test".green} ${"re/\\\\.js$/".gray(level)}
66
+
67
+ ${" Options:".red}
68
+ ${" :clean".cyan} ${`: Remove comment tokens and leave the currently enabled code.`.gray(level)}
69
+ ${" basePath".cyan} ${`: Source directory path(s). Comma-separated or array type arg is accepted.`.gray(level)}
70
+ ${" test".cyan} ${`: Target file matcher. default is /\\\\.js$/.`.gray(level)}
71
+
72
+ ${" Note:".magenta} ${`Recognized markers: ctt | comment-toggle-trick | https://coderwall`.gray(level)}
68
73
  `;
69
74
  },
70
75
  };
package/tool-lib/ps.js CHANGED
@@ -21,8 +21,9 @@ module.exports = {
21
21
  /**
22
22
  * @param {import("fs")} fs
23
23
  * @param {import("../utils")} utils
24
+ * @param {NsJsTool.TDevConsole} logger
24
25
  */
25
- globalize: (fs, utils) => {
26
+ globalize: (fs, utils, logger) => {
26
27
  /**
27
28
  * @param {string} dir
28
29
  * @param {string[]} sourceFiles
@@ -32,12 +33,12 @@ module.exports = {
32
33
  const visitDirectory = (dir, sourceFiles, testRe, recurse) => {
33
34
  if (dir.length) {
34
35
  if (!fs.existsSync(dir)) {
35
- console.info(`directory: [${dir}] is not found`);
36
+ console.warn(`directory: [${dir}] is not found`);
36
37
  } else {
37
38
  utils.walkDirSync(dir, (dirent) => {
38
39
  const currentPath = `${dir}/${dirent.name}`;
39
40
  if (dirent.isFile() && testRe.test(dirent.name)) {
40
- DEBUG && console.log("processSources::", dirent.name);
41
+ DEBUG && logger.log("processSources::", dirent.name);
41
42
  sourceFiles.push(currentPath);
42
43
  } else if (recurse && dirent.isDirectory()) {
43
44
  visitDirectory(currentPath, sourceFiles, testRe, true);
@@ -72,8 +73,8 @@ module.exports = {
72
73
  sourceFiles = [];
73
74
  const reFile = params.test || test;
74
75
  const actualBases = isArray(bases) ? bases : [base];
75
- DEBUG && console.log("processSources::", actualBases, reFile);
76
- DEBUG && console.log("processSources::re", reFile, reFile.constructor);
76
+ DEBUG && logger.log("processSources::", actualBases, reFile);
77
+ DEBUG && logger.log("processSources::re", reFile, reFile.constructor);
77
78
  if (root) {
78
79
  visitDirectory(root.trim(), sourceFiles, reFile, true);
79
80
  } else {
@@ -88,7 +89,7 @@ module.exports = {
88
89
  }
89
90
  }
90
91
  sourceFiles = sourceFiles.filter(Boolean);
91
- DEBUG && console.log("processSources::processSources:", sourceFiles);
92
+ DEBUG && logger.log("processSources::processSources:", sourceFiles);
92
93
  let count = sourceFiles.length;
93
94
  let written = 0;
94
95
  /** @type {() => void} */
package/tool-lib/rws.js CHANGED
@@ -49,18 +49,29 @@ const decrementVersion = (nversionArray) => {
49
49
  * + Too many record entries can be hard to see,
50
50
  * so if there are more than 10 entries, they will be truncated.
51
51
  * @param {TVersionRecords} record
52
+ * @param {number=} [max=5]
52
53
  */
53
- const shortenRecord = (record) => {
54
+ const shortenRecord = (record, max = 5) => {
54
55
  let keys = /** @type {TVersionString[]} */ (Object.keys(record));
55
- if (keys.length > 10) {
56
- keys = keys.slice(keys.length - 10);
56
+ if (typeof max !== "number") {
57
+ console.warn(`rws::shortenRecord - "max" parameter is invalid, force set 5. (max: ${max})`);
58
+ max = 5;
59
+ } else {
60
+ if (!Number.isFinite(max)) max = 5;
61
+ else {
62
+ if (max < 1) max = 1;
63
+ else if (max > keys.length) max = keys.length;
64
+ }
65
+ }
66
+ if (keys.length > max) {
67
+ keys = keys.slice(keys.length - max);
57
68
  /** @type {TVersionRecords} */
58
- const newRecord = {};
69
+ const shortRecord = {};
59
70
  for (let i = 0; i < keys.length; ) {
60
71
  const key = keys[i++];
61
- newRecord[key] = record[key];
72
+ shortRecord[key] = record[key];
62
73
  }
63
- return newRecord;
74
+ return shortRecord;
64
75
  }
65
76
  return record;
66
77
  };
@@ -72,7 +83,7 @@ const shortenRecord = (record) => {
72
83
  module.exports = (fs, utils) => {
73
84
  return {
74
85
  taskName: "(R)ecord(W)ebpack(S)ize",
75
- fn() {
86
+ fn(logger) {
76
87
  const versionSourcePath = params.versionSource || "./package.json";
77
88
  /** @type {{ version: TVersionString }} */
78
89
  const thisPackage = utils.readJson(versionSourcePath);
@@ -139,7 +150,7 @@ module.exports = (fs, utils) => {
139
150
  if (prevEntry) {
140
151
  if (isDiff(prevEntry, entry)) {
141
152
  sizeRecord[versionStr] = entry;
142
- utils.log(shortenRecord(sizeRecord));
153
+ utils.log(shortenRecord(sizeRecord, params.printMax));
143
154
  msg = "[%s] is updated";
144
155
  } else {
145
156
  needWrite = false;
@@ -163,15 +174,21 @@ module.exports = (fs, utils) => {
163
174
  }
164
175
  },
165
176
  get help() {
166
- return `${this.taskName}
167
- ex - jstool -cmd rws [-versionSource "<version source path>"] [-webpack lib/webpack.js -umd umd/webpack.js -dest "./dev-extras/webpack-size.json"] [-rws-tags "web/login:./dist/es/web/login.mjs,webpack-esm:./dist/webpack-esm/index.mjs"]
168
- note:
169
- versionSource - JSON file path used to read the "version" field. if not specified then apply "./package.json"
170
- webpack - if not specified then apply "./dist/webpack/index.js"
171
- umd - if not specified then apply "./dist/umd/index.js"
172
- bin - if not specified then apply "./dist/bin/index.js"
173
- rws-tags - It is treated as parameter array separated by ":", e.g - "web/login:./dist/es/web/login.mjs,webpack-esm:./dist/webpack-esm/index.mjs"
174
- dest - if not specified then apply "./logs/webpack-size.json"
177
+ const level = 16;
178
+ return `jstool -cmd rws [-versionSource "./package.json"] [-webpack "./dist/webpack/index.js" -umd "./dist/umd/index.js" -bin "./dist/bin/index.js"]\\
179
+ [-dest "./logs/webpack-size.json"] [-printMax 5] [-rws-tags "web/login:./dist/es/web/login.mjs,webpack-esm:./dist/webpack-esm/index.mjs"]
180
+
181
+ ${" Example:".red}
182
+ ${"jstool".yellow} ${"-cmd".green} ${"rws".cyan} ${"-versionSource".green} ${"packages/web/package.json".gray(level)} ${"-dest".green} ${"./dev-extras/webpack-size.json".gray(level)}
183
+
184
+ ${" Options:".red}
185
+ ${" versionSource".cyan} ${`: JSON file path used to read the "version" field. default is "./package.json"`.gray(level)}
186
+ ${" webpack".cyan} ${`: Source path for the webpack bundle. default is "./dist/webpack/index.js"`.gray(level)}
187
+ ${" umd".cyan} ${`: Source path for the UMD bundle. default is "./dist/umd/index.js"`.gray(level)}
188
+ ${" bin".cyan} ${`: Source path for the bin bundle. default is "./dist/bin/index.js"`.gray(level)}
189
+ ${" dest".cyan} ${`: Output path of the size record JSON. default is "./logs/webpack-size.json"`.gray(level)}
190
+ ${" printMax".cyan} ${`: Max number of record entries shown in the preview log. default is 5`.gray(level)}
191
+ ${" rws-tags".cyan} ${`: Extra tag:path pairs separated by ",". e.g. "web/login:./dist/es/web/login.mjs,webpack-esm:./dist/webpack-esm/index.mjs"`.gray(level)}
175
192
  `;
176
193
  },
177
194
  };
@@ -6,6 +6,7 @@
6
6
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
8
  /// <reference types="literate-regex/global"/>
9
+ /// <reference types="tin-args" preserve="true"/>
9
10
  /**
10
11
  * @date 2023-10-25
11
12
  */
@@ -19,7 +20,7 @@ declare global {
19
20
  declare type TStringReplacer = (matchs: string, ...args: any[]) => string;
20
21
  /** use `(R)ecord(W)ebpack(S)ize` */
21
22
  declare type TRwsTags = "webpack" | "umd" | "bin";
22
- declare var params: ReturnType<typeof import("tin-args")<TToolArgs>>;
23
+ declare var params: NsTinArgs.TTinArgsReturnType<TToolArgs>;
23
24
  declare var isArray: typeof Array.isArray;
24
25
  /**
25
26
  * @date 2025/2/18 0:46:03
@@ -65,6 +66,8 @@ declare global {
65
66
  minor?: true;
66
67
  patch?: true;
67
68
  extras: string[];
69
+ /** rws */
70
+ printMax?: number;
68
71
  /** rws, backup */
69
72
  dest: string;
70
73
  /** backup */
@@ -135,7 +138,7 @@ declare global {
135
138
  cb?: (sourceFiles: string[]) => void
136
139
  }
137
140
  declare type TJSToolEntry = {
138
- fn: (mode?: string) => void;
141
+ fn: (logger: NsJsTool.TDevConsole, mode?: string) => void;
139
142
  help: string;
140
143
  taskName: string;
141
144
  }
@@ -145,5 +148,13 @@ declare global {
145
148
  declare type TVersionString = `${number}.${number}.${number}${string}`;
146
149
  declare type TVersionRecords = Record<TVersionString, Partial<Record<TRwsTags, number>>>;
147
150
  declare type TSizeRecordEntry = TVersionRecords["0.0.0"];
151
+ declare namespace NsJsTool {
152
+ type TDevConsole = {
153
+ log: Console["log"];
154
+ warn: Console["warn"];
155
+ error: Console["error"];
156
+ info: Console["info"];
157
+ };
158
+ }
148
159
  }
149
- export = {};
160
+ export {};
@@ -19,7 +19,7 @@ module.exports =
19
19
  (utils) => {
20
20
  return {
21
21
  taskName: "zip",
22
- fn() {
22
+ fn(logger) {
23
23
  const comment = params.comment;
24
24
  const paths = params.args;
25
25
  if (Array.isArray(paths)) {
@@ -29,8 +29,18 @@ module.exports =
29
29
  }
30
30
  }
31
31
  },
32
- help: `jstool -cmd zip [-comment "the comment"] lib/webpack.js lib/type-ids.js
33
- It is possible to create zip files with comments
34
- `,
32
+ get help() {
33
+ const level = 16;
34
+ return `jstool -cmd zip [-comment "the comment"] lib/webpack.js lib/type-ids.js
35
+
36
+ ${" Example:".red}
37
+ ${"jstool".yellow} ${"-cmd".green} ${"zip".cyan} ${"-comment".green} ${"release artifact".gray(level)} ${"lib/webpack.js lib/type-ids.js".gray(level)}
38
+
39
+ ${" Options:".red}
40
+ ${" comment".cyan} ${`: ZIP comment string embedded into the output archive.`.gray(level)}
41
+
42
+ ${" Note:".magenta} ${`Pass target file paths as args after the options.`.gray(level)}
43
+ `;
44
+ },
35
45
  };
36
46
  };
package/tools.js CHANGED
@@ -18,8 +18,25 @@ const utils = require("./utils");
18
18
  global.params = require("tin-args")();
19
19
  global.verbose = params.verb;
20
20
  global.isArray = Array.isArray;
21
- require("./tool-lib/ps").globalize(fs, utils);
22
- utils.log(params);
21
+ /**
22
+ * @date 2026/06/27 15:59:10
23
+ * @since v1.5.23-dev
24
+ * @type {NsJsTool.TDevConsole}
25
+ */
26
+ const devLogger = (() => {
27
+ const emptyLogger = /** @type {NsJsTool.TDevConsole} */({
28
+ log() {},
29
+ info() {},
30
+ warn() {},
31
+ error() {},
32
+ });
33
+ if (process.env.CI) return emptyLogger;
34
+ return params.verb ? console : emptyLogger;
35
+ })();
36
+ /** shorthand of __`console.log`__ */
37
+ const _log = console.log;
38
+ if (verbose) utils.log(params);
39
+ require("./tool-lib/ps").globalize(fs, utils, devLogger);
23
40
  /**
24
41
  * how to config terser, see {@link https://github.com/terser/terser#minify-options-structure Minify options structure}
25
42
  *
@@ -78,7 +95,7 @@ const ToolFunctions = {
78
95
  */
79
96
  replace: {
80
97
  taskName: "replace",
81
- fn() {
98
+ fn(logger) {
82
99
  const re = params.regex;
83
100
  const after = params.after || "";
84
101
  let targets = params.args || params.targets
@@ -91,26 +108,27 @@ const ToolFunctions = {
91
108
  }
92
109
  },
93
110
  get help() {
111
+ const level = 16;
94
112
  return `jstool -cmd replace [-after <replacement>] -regex \"/^\\s+<!--[\\s\\S]+?-->(?:\\r?\\n)?/gm\" [-targets "<path>,<path>,..." | <args: file, file file...>]
95
113
 
96
114
  ${" Options:".red}
97
- ${" after".cyan} ${`: If omitted, "" (empty string) is used, meaning that the matched string is deleted.`.gray(16)}
98
- ${" targets".cyan}${`: Single path string or Array type arg, "['<path>', '<path>',...]" or "<path>,<path>,..."`.gray(16)}
115
+ ${" after".cyan} ${`: If omitted, "" (empty string) is used, meaning that the matched string is deleted.`.gray(level)}
116
+ ${" targets".cyan}${`: Single path string or Array type arg, "['<path>', '<path>',...]" or "<path>,<path>,..."`.gray(level)}
99
117
 
100
- ${" remarks".magenta}${": targets - can use args parameter instead".gray(16)}${`
118
+ ${" remarks".magenta}${": targets - can use args parameter instead".gray(level)}${`
101
119
  It is better to use the <args: file, file file...>
102
- e.g - ${"jstool".yellow} ${"-cmd".green} ${"replace".cyan} ${"-after".green} ${`".."`.red} ${"-regex".green} ${String.raw`'re/(?<=reference path=")(\.)(?=\/index.d.ts")/'`.magenta} ${"build/**/*.js".gray(16)}
120
+ e.g - ${"jstool".yellow} ${"-cmd".green} ${"replace".cyan} ${"-after".green} ${`".."`.red} ${"-regex".green}=${String.raw`'r/(?<=reference path=")(\.)(?=\/index.d.ts")/'`.magenta} ${"build/**/*.js".gray(level)}
103
121
  ^^^^^^^^^^^^^
104
- `.gray(16)}`;
122
+ `.gray(level)}`;
105
123
  },
106
124
  },
107
125
  version: {
108
126
  taskName: "version",
109
- fn() {
127
+ fn(logger) {
110
128
  let { major, minor /*, patch*/, pkgJsons = ["./package.json"] } = params;
111
129
  /** @type {string} */
112
130
  let currentVersion;
113
- /** @type {string} */
131
+ /** @type {string=} */
114
132
  let nextVersion;
115
133
  !isArray(pkgJsons) && (pkgJsons = [pkgJsons]);
116
134
  utils.fireReplace(
@@ -156,18 +174,28 @@ ${" remarks".magenta}${": targets - can use args parameter instead".gray(16)}${
156
174
  paths,
157
175
  );
158
176
  }
159
- // @ts-ignore
160
177
  console.log("version updated: %s", nextVersion);
161
178
  },
162
- help: `jstool -cmd version [-major | -minor] [-pkgJsons "./package.json,../package.json"] [-extras "test/web/index.html"]
163
- bump top level package.json version(can specify "package.json" paths by \`pkgJsons\` option if need), specify patch version is unnecessary.
164
- note:
165
- extras - can be "<path>,<path>,..." (array type arg)
166
- `,
179
+ get help() {
180
+ const level = 16;
181
+ return `jstool -cmd version [-major | -minor] [-pkgJsons "./package.json,../package.json"] [-extras "test/web/index.html"]
182
+
183
+ ${" Example:".red}
184
+ ${"jstool".yellow} ${"-cmd".green} ${"version".cyan} ${"-minor".green} ${"-extras".green} ${"README.md,test/web/index.html".gray(level)}
185
+
186
+ ${" Options:".red}
187
+ ${" major".cyan} ${`: Bump major version and reset minor/patch to 0.`.gray(level)}
188
+ ${" minor".cyan} ${`: Bump minor version and reset patch to 0.`.gray(level)}
189
+ ${" pkgJsons".cyan} ${`: Target package.json path(s). Comma-separated or array type arg is accepted.`.gray(level)}
190
+ ${" extras".cyan} ${`: Additional files whose version strings should be replaced too.`.gray(level)}
191
+
192
+ ${" Note:".magenta} ${`If neither -major nor -minor is specified, patch version is bumped.`.gray(level)}
193
+ `;
194
+ },
167
195
  },
168
196
  minify: {
169
197
  taskName: "minify",
170
- fn() {
198
+ fn(logger) {
171
199
  const Terser = require("terser");
172
200
  const sx = params.suffix;
173
201
  let suffix = ".mini";
@@ -195,12 +223,19 @@ ${" remarks".magenta}${": targets - can use args parameter instead".gray(16)}${
195
223
  opt,
196
224
  );
197
225
  },
198
- help: `jstool -cmd minify -basePath extra-tests/web/mini-semaphore [-test "re/\\.js$/"] [-suffix ".mini"]
199
- note:
200
- basePath - can be "<path>,<path>,..." (array type arg)
201
- test - can be omit, default is \`/\\.js$/\`
202
- suffix - can be omit, default is ".mini"
203
- `,
226
+ get help() {
227
+ const level = 16;
228
+ return `jstool -cmd minify -basePath "extra-tests/web/mini-semaphore" [-test "re/\\.js$/"] [-suffix ".mini"]
229
+
230
+ ${" Example:".red}
231
+ ${"jstool".yellow} ${"-cmd".green} ${"minify".cyan} ${"-basePath".green} ${"dist/esm,dist/cjs".gray(level)} ${"-suffix".green} ${".min".gray(level)}
232
+
233
+ ${" Options:".red}
234
+ ${" basePath".cyan} ${`: Source directory path(s). Comma-separated or array type arg is accepted.`.gray(level)}
235
+ ${" test".cyan} ${`: Target file matcher. default is /\\.js$/.`.gray(level)}
236
+ ${" suffix".cyan} ${`: Output suffix inserted before ".js". default is ".mini".`.gray(level)}
237
+ `;
238
+ },
204
239
  },
205
240
  /**
206
241
  * NOTE: keep comment that start with "/&#42;" when "&#42;/" end mark appears in same line.
@@ -209,12 +244,12 @@ ${" remarks".magenta}${": targets - can use args parameter instead".gray(16)}${
209
244
  */
210
245
  rmc: {
211
246
  taskName: "rm-cstyle-cmts",
212
- fn() {
247
+ fn(logger) {
213
248
  rmc.reset();
214
249
  if (params.rmc4ts) {
215
250
  const keepBangLine = params.rmc4ts === "keepBangLine";
216
251
  const reMultiLineChcker = /^\/\*(\*|!)\s|^\/\*(?!-).+\*\/$/;
217
- const reSingleLineChecer = /^\/\/+!/;
252
+ const reSingleLineChecer = /^(?:\/\/+!)/;
218
253
  rmc.setListener(({ event, fragment }) => {
219
254
  if (event === /*EScannerEvent.MultiLineComment*/ 1) {
220
255
  return reMultiLineChcker.test(fragment);
@@ -240,16 +275,23 @@ ${" remarks".magenta}${": targets - can use args parameter instead".gray(16)}${
240
275
  },
241
276
  );
242
277
  },
243
- help: `$ jstool -cmd rmc [-rmc4ts[:keepBangLine]] -basePath "./dist/cjs,./dist/cjs/gulp" -test "/\\.(js|d\\.ts)$/"
244
- note: basePath - can be "<path>,<path>,..." (array type arg)
245
- test - can be omit, defulat \`/\.js$/\`
246
- rmc4ts- for typescript source.
247
- keep comment that start with "/*" when "*/" end mark appears in same line.
248
- if start with "/*-" remove it
249
- keep leading "/// <reference ...>" directives above a top-level "use strict" line in CJS emit.(2026/02/03)
250
- rmc4ts=keepBangLine (2025/12/24)
251
- - In addition to the "rmc4ts" processing, it also preserves line comments that start with "//!".
252
- `,
278
+ get help() {
279
+ const level = 16;
280
+ return `jstool -cmd rmc [-rmc4ts[:keepBangLine]] -basePath "./dist/cjs,./dist/cjs/gulp" [-test "/\\.(js|d\\.ts)$/"] [-suffix ".clean"]
281
+
282
+ ${" Example:".red}
283
+ ${"jstool".yellow} ${"-cmd".green} ${"rmc".cyan} ${"-rmc4ts:keepBangLine".green} ${"-basePath".green} ${"dist/cjs,dist/cjs/gulp".gray(level)} ${"-test".green} ${"/\\.(js|d\\.ts)$/".gray(level)}
284
+
285
+ ${" Options:".red}
286
+ ${" basePath".cyan} ${`: Source directory path(s). Comma-separated or array type arg is accepted.`.gray(level)}
287
+ ${" test".cyan} ${`: Target file matcher. default is /\\.js$/.`.gray(level)}
288
+ ${" suffix".cyan} ${`: Output suffix inserted before ".js" when needed.`.gray(level)}
289
+ ${" rmc4ts".cyan} ${`: TypeScript-oriented mode. Preserves single-line /* */ comments except ones that start with "/*-".`.gray(level)}
290
+
291
+ ${" Extra:".magenta} ${`rmc4ts:keepBangLine also preserves line comments that start with "//!".`.gray(level)}
292
+ ${" Extra:".magenta} ${`Leading /// <reference ...> directives are kept above a top-level "use strict" line in CJS output.`.gray(level)}
293
+ `;
294
+ },
253
295
  },
254
296
  zip: require("./tool-lib/zip-task")(utils),
255
297
  };
@@ -298,25 +340,25 @@ function isJSToolEntry(entry) {
298
340
  */
299
341
  function printHelp(cmd) {
300
342
  const entry = ToolFunctions[cmd];
301
- console.log(`${cmd.yellow + " help:".green} ${entry.help.gray(8)}`);
343
+ _log(`${cmd.yellow + " help:".green} ${entry.help.gray(8)}`);
302
344
  }
303
345
  if (params.cmd) {
304
346
  const [task, mode] = params.cmd.split(":");
305
347
  const entry = ToolFunctions[task];
306
- isJSToolEntry(entry) && entry.fn(mode);
348
+ isJSToolEntry(entry) && entry.fn(devLogger, mode);
307
349
  } else if (params.shell) {
308
350
  const SCRIPT_DIR = path.dirname(process.argv[1]);
309
351
  const arg = `${params.major ? "-major" : params.minor ? "-minor" : ""}`;
310
352
  utils.execWithOutputResult(
311
353
  `bash ${SCRIPT_DIR}/scripts/tool.sh ${params.shell} ${arg}`,
312
354
  (result) => {
313
- console.log(result);
355
+ _log(result);
314
356
  },
315
357
  process.cwd(),
316
358
  );
317
359
  } else if (params.v) {
318
360
  const thisVersion = require("./package.json").version;
319
- console.log(
361
+ _log(
320
362
  `${"jstool".magenta} in "js-dev-scripts", version: ${thisVersion.green}
321
363
  more details see ${"https://github.com/jeffy-g/js-dev-scripts".blue}`,
322
364
  );
@@ -327,7 +369,7 @@ more details see ${"https://github.com/jeffy-g/js-dev-scripts".blue}`,
327
369
  printHelp(cmdName);
328
370
  } else {
329
371
  const commands = Object.keys(ToolFunctions);
330
- console.log(`
372
+ _log(`
331
373
  Usage: node jstool -cmd <command name>
332
374
  - - - - available commands:`);
333
375
  for (const cmd of commands) {
package/utils.d.ts CHANGED
@@ -165,11 +165,11 @@ export function copyText(content: string, message?: string, chcp65001?: boolean)
165
165
  * @param regex
166
166
  * @param replacement
167
167
  * @param paths Paths that do not exist are ignored
168
- * @param [async]
168
+ * @param [opt]
169
169
  *
170
170
  * @date 2019-4-26
171
171
  */
172
- export function fireReplace(regex: RegExp, replacement: string | Function, paths: string[], async?: boolean): void;
172
+ export function fireReplace(regex: RegExp, replacement: string | Function, paths: string[], opt?: { async?: boolean; verbose?: boolean }): void;
173
173
  export const CI: boolean;
174
174
  /**
175
175
  * Nothing is logged in a CI environment.
package/utils.js CHANGED
@@ -27,6 +27,7 @@ const lib = require("./common");
27
27
  const tinArgs = require("tin-args");
28
28
  const { listDependenciesOf } = require("./extras/list-deps-of");
29
29
  const CI = !!process.env.CI;
30
+ const _log = console.log;
30
31
  /**
31
32
  * Nothing is logged in a CI environment.
32
33
  */
@@ -53,7 +54,6 @@ function extractVersion(versionString = process.version) {
53
54
  const [major = 0, minor = 0, patch = 0] = pv ? pv.map((value, i) => {
54
55
  return (i > 0 && +value) || void 0;
55
56
  }).slice(1) : [];
56
- console.log("result:", major, minor, patch);
57
57
  return { major, minor, patch };
58
58
  }
59
59
  /**
@@ -208,13 +208,14 @@ let nodeReplace;
208
208
  * @param {RegExp} regex
209
209
  * @param {string | Function} replacement
210
210
  * @param {string[]} paths Paths that do not exist are ignored
211
- * @param {boolean} [async]
211
+ * @param {{ async?: boolean; verbose?: boolean }} [opt]
212
212
  *
213
213
  * @date 2019-4-26
214
214
  */
215
- function fireReplace(regex, replacement, paths, async = false) {
215
+ function fireReplace(regex, replacement, paths, opt) {
216
216
  // @ts-ignore "replace" is peerDependencies
217
217
  nodeReplace === void 0 && (nodeReplace = require("replace"));
218
+ opt = { async: false, verbose: false, ...opt };
218
219
  if (Array.isArray(paths)) {
219
220
  paths = paths.filter((path) => fs.existsSync(path));
220
221
  nodeReplace({
@@ -222,9 +223,9 @@ function fireReplace(regex, replacement, paths, async = false) {
222
223
  replacement,
223
224
  paths,
224
225
  recursive: false,
225
- silent: false,
226
+ silent: !opt.verbose,
226
227
  preview: false,
227
- async,
228
+ async: opt.async,
228
229
  ignoreCase: false,
229
230
  multiline: false,
230
231
  });
@@ -257,16 +258,16 @@ function compressScript(scriptPath, comment = "") {
257
258
  compressionMethod: zlibZip.CompressionMethod.DEFLATE,
258
259
  os: zlibZip.OperatingSystem.MSDOS,
259
260
  });
260
- console.log(`added ${scriptPath} to zip`);
261
- console.log("start compress...");
261
+ _log(`added ${scriptPath} to zip`);
262
+ _log("start compress...");
262
263
  console.time("zip:compress");
263
264
  const compressed = zip.compress();
264
265
  console.timeEnd("zip:compress");
265
- console.log("compress done.\n");
266
+ _log("compress done.\n");
266
267
  const pp = path.parse(scriptPath);
267
268
  const output = `${pp.dir ? pp.dir + "/" : ""}${pp.name}.zip`;
268
269
  fs.writeFile(output, compressed, (err) => {
269
- console.log(`\nzip file created, error: ${err}\n => ${output}`);
270
+ _log(`\nzip file created, error: ${err}\n => ${output}`);
270
271
  });
271
272
  }
272
273
  /**
@@ -283,16 +284,16 @@ function compressScript2(scriptPath, comment = "") {
283
284
  const pp = path.parse(scriptPath);
284
285
  const output = fs.createWriteStream(`${pp.dir}/${pp.name}.zip`);
285
286
  output.on("close", function () {
286
- console.log(archive.pointer() + " total bytes");
287
- console.log(
287
+ _log(archive.pointer() + " total bytes");
288
+ _log(
288
289
  "archiver has been finalized and the output file descriptor has closed.",
289
290
  );
290
291
  });
291
292
  output.on("end", function () {
292
- console.log("Data has been drained");
293
+ _log("Data has been drained");
293
294
  });
294
295
  archive.on("progress", (progress) => {
295
- console.log(progress.entries.processed);
296
+ _log(progress.entries.processed);
296
297
  });
297
298
  archive.pipe(output);
298
299
  archive.file(scriptPath, {
@@ -313,7 +314,7 @@ function compressScript2(scriptPath, comment = "") {
313
314
  * @param {(result: string) => void} doneCallbackWithArgs gulp callback function.
314
315
  */
315
316
  function execWithOutputResult(command, doneCallbackWithArgs, cwd) {
316
- console.log();
317
+ _log();
317
318
  const { exec } = require("child_process");
318
319
  return exec(command, { cwd }, (err, stdout /* , stderr */) => {
319
320
  if (err) {
@@ -423,7 +424,7 @@ function copyText(content, message = "text copied!", chcp65001 = true) {
423
424
  if (err) {
424
425
  console.error(err);
425
426
  } else {
426
- console.log(message, stdout);
427
+ _log(message, stdout);
427
428
  }
428
429
  });
429
430
  // @ts-ignore