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/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 "/&#42;" when "&#42;/" end mark appears in same line.
273
+ *
274
+ * + if start with "/&#42;-" 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;