js-dev-tool 1.2.1 → 1.2.3
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/basic-types.d.ts +4 -4
- package/common/index.js +1 -0
- package/extras/list-deps-of.js +213 -0
- package/extras/list-deps-of.sh +18 -0
- package/extras/tiny-progress.js +1 -0
- package/index.js +1 -0
- package/package.json +5 -5
- package/progress/index.js +1 -0
- package/progress/progress-extras.js +1 -0
- package/progress/rnd-spinner.js +1 -0
- package/progress/test.js +1 -0
- package/tool-lib/cjbm.js +2 -1
- package/tool-lib/cmt-trick.js +1 -0
- package/tool-lib/ps.js +1 -0
- package/tool-lib/rws.js +1 -0
- package/tool-lib/tools.d.ts +1 -1
- package/tool-lib/zip-task.js +1 -0
- package/tools.js +42 -4
- package/utils.d.ts +2 -1
- package/utils.js +3 -0
package/basic-types.d.ts
CHANGED
|
@@ -85,10 +85,10 @@ type Constructor<T> = new (...args: any[]) => T;
|
|
|
85
85
|
* - If it is **1**, the types are displayed concatenated.
|
|
86
86
|
* - If it is **0**, the types are displayed separated by "&".
|
|
87
87
|
*/
|
|
88
|
-
type RequireThese<
|
|
89
|
-
Merge extends 1
|
|
90
|
-
T & Required<Pick<T, K>>
|
|
91
|
-
>
|
|
88
|
+
type RequireThese<
|
|
89
|
+
T, K extends keyof T, Merge extends 1 | 0 = 0,
|
|
90
|
+
Intersected = T & Required<Pick<T, K>>
|
|
91
|
+
> = Merge extends 1 ? Prettify<Intersected> : Intersected;
|
|
92
92
|
/**
|
|
93
93
|
* pick any `property` as excludes
|
|
94
94
|
*/
|
package/common/index.js
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
// Copyright (C) 2026 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
// Released under the MIT license
|
|
5
|
+
// https://opensource.org/licenses/mit-license.php
|
|
6
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
8
|
+
"use strict";
|
|
9
|
+
/**
|
|
10
|
+
* @file list-deps-of.js
|
|
11
|
+
* @command node list-deps-of.mjs typescript-jsdoctag-completions-plugin
|
|
12
|
+
*
|
|
13
|
+
* CAVEAT: yarn v1.x lock file 専用
|
|
14
|
+
*/
|
|
15
|
+
const fs = require("fs");
|
|
16
|
+
const path = require("path");
|
|
17
|
+
/** @param {string} raw */
|
|
18
|
+
function parseSelectors(raw) {
|
|
19
|
+
if (raw.includes("\"")) {
|
|
20
|
+
const selectors = [];
|
|
21
|
+
const regex = /"([^"]+)"/g;
|
|
22
|
+
let match = regex.exec(raw);
|
|
23
|
+
while (match) {
|
|
24
|
+
selectors.push(match[1]);
|
|
25
|
+
match = regex.exec(raw);
|
|
26
|
+
}
|
|
27
|
+
if (selectors.length > 0) {
|
|
28
|
+
return selectors;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return raw.split(/\s?,\s?/)
|
|
32
|
+
}
|
|
33
|
+
/** @param {string} selector */
|
|
34
|
+
function selectorToName(selector) {
|
|
35
|
+
const npmIndex = selector.indexOf("@npm:");
|
|
36
|
+
if (npmIndex !== -1) {
|
|
37
|
+
return selector.slice(0, npmIndex);
|
|
38
|
+
}
|
|
39
|
+
const lastAt = selector.lastIndexOf("@");
|
|
40
|
+
if (lastAt > 0) {
|
|
41
|
+
return selector.slice(0, lastAt);
|
|
42
|
+
}
|
|
43
|
+
return selector;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* ```
|
|
47
|
+
* /^[^\s].+:/;
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
const re_ModuleStart = /^[^\s].+:/;
|
|
51
|
+
/**
|
|
52
|
+
* ```
|
|
53
|
+
* /^\x20{2}(?:(?:optionalD|d)ependencies):$/;
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
const re_DepsStart = /^\x20{2}(?:(?:optionalD|d)ependencies):$/;
|
|
57
|
+
/**
|
|
58
|
+
* ```
|
|
59
|
+
* /\x20{4}/;
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
const re_DepsEntryIndent = /^\x20{4}[^\s]/;
|
|
63
|
+
/**
|
|
64
|
+
* @typedef {{
|
|
65
|
+
* name?: string;
|
|
66
|
+
* selectors: string[];
|
|
67
|
+
* deps: { name: string; range: string; }[]
|
|
68
|
+
* }} TDependenciesEntry
|
|
69
|
+
*/
|
|
70
|
+
/** @param {string} yarnLockSource */
|
|
71
|
+
function parseLockfile(yarnLockSource) {
|
|
72
|
+
/** @type {TDependenciesEntry[]} */
|
|
73
|
+
const entries = [];
|
|
74
|
+
const lines = yarnLockSource.split(/\r?\n/);
|
|
75
|
+
/** @type {TDependenciesEntry | null} */
|
|
76
|
+
let current = null;
|
|
77
|
+
let inDepsSection = false;
|
|
78
|
+
const modEntryChecker = re_ModuleStart;
|
|
79
|
+
const depsStartChecker = re_DepsStart;
|
|
80
|
+
const depsEntryChecker = re_DepsEntryIndent;
|
|
81
|
+
const reDepsExtractor = /(?:"([^"]+)"|([^"\s]+))\s+"([^"]+)"\s*$/;
|
|
82
|
+
const commitCurrent = () => {
|
|
83
|
+
if (current) {
|
|
84
|
+
entries.push(current);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
if (line.length === 0) {
|
|
89
|
+
inDepsSection = false;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (line.startsWith("#")) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (modEntryChecker.test(line)) {
|
|
96
|
+
commitCurrent();
|
|
97
|
+
const rawKeys = line.slice(0, -1);
|
|
98
|
+
const selectors = parseSelectors(rawKeys);
|
|
99
|
+
current = { selectors, deps: [] };
|
|
100
|
+
inDepsSection = false;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (!current) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (depsStartChecker.test(line)) {
|
|
107
|
+
inDepsSection = true;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (inDepsSection && depsEntryChecker.test(line)) {
|
|
111
|
+
const trimmed = line.trim();
|
|
112
|
+
const match = reDepsExtractor.exec(trimmed);
|
|
113
|
+
if (match) {
|
|
114
|
+
const name = match[1] || match[2];
|
|
115
|
+
const range = match[3];
|
|
116
|
+
current.deps.push({ name, range });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
commitCurrent();
|
|
121
|
+
/** @type {Map<string, TDependenciesEntry>} */
|
|
122
|
+
const selectorToEntry = new Map();
|
|
123
|
+
/** @type {Map<string, TDependenciesEntry[]>} */
|
|
124
|
+
const nameToEntries = new Map();
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
if (entry.selectors.length === 0) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const name = selectorToName(entry.selectors[0]);
|
|
130
|
+
entry.name = name;
|
|
131
|
+
for (const selector of entry.selectors) {
|
|
132
|
+
selectorToEntry.set(selector, entry);
|
|
133
|
+
}
|
|
134
|
+
if (!nameToEntries.has(name)) {
|
|
135
|
+
nameToEntries.set(name, []);
|
|
136
|
+
}
|
|
137
|
+
// @ts-expect-error
|
|
138
|
+
nameToEntries.get(name).push(entry);
|
|
139
|
+
}
|
|
140
|
+
return { entries, selectorToEntry, nameToEntries };
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* @param {string} depName
|
|
144
|
+
* @param {string} depRange
|
|
145
|
+
* @param {Map<string, TDependenciesEntry>} selectorToEntry
|
|
146
|
+
* @param {Map<string, TDependenciesEntry[]>} nameToEntries
|
|
147
|
+
*/
|
|
148
|
+
function resolveEntries(depName, depRange, selectorToEntry, nameToEntries) {
|
|
149
|
+
const exactSelector = depName + "@" + depRange;
|
|
150
|
+
const exactEntry = selectorToEntry.get(exactSelector);
|
|
151
|
+
if (exactEntry) {
|
|
152
|
+
return [exactEntry];
|
|
153
|
+
}
|
|
154
|
+
const entries = nameToEntries.get(depName);
|
|
155
|
+
if (entries) {
|
|
156
|
+
return entries;
|
|
157
|
+
}
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* @param {TDependenciesEntry[]} startEntries
|
|
162
|
+
* @param {Map<string, TDependenciesEntry>} selectorToEntry
|
|
163
|
+
* @param {Map<string, TDependenciesEntry[]>} nameToEntries
|
|
164
|
+
*/
|
|
165
|
+
function collectDependencies(startEntries, selectorToEntry, nameToEntries) {
|
|
166
|
+
/** @type {Set<string>} */
|
|
167
|
+
const result = new Set();
|
|
168
|
+
/** @type {Set<TDependenciesEntry>} */
|
|
169
|
+
const visitedEntries = new Set();
|
|
170
|
+
const stack = [...startEntries];
|
|
171
|
+
while (stack.length > 0) {
|
|
172
|
+
const entry = stack.pop();
|
|
173
|
+
if (!entry || visitedEntries.has(entry)) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
visitedEntries.add(entry);
|
|
177
|
+
for (const dep of entry.deps) {
|
|
178
|
+
result.add(dep.name);
|
|
179
|
+
const resolvedEntries = resolveEntries(
|
|
180
|
+
dep.name,
|
|
181
|
+
dep.range,
|
|
182
|
+
selectorToEntry,
|
|
183
|
+
nameToEntries
|
|
184
|
+
);
|
|
185
|
+
for (const resolvedEntry of resolvedEntries) {
|
|
186
|
+
if (!visitedEntries.has(resolvedEntry)) {
|
|
187
|
+
stack.push(resolvedEntry);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
const lockfilePath = "yarn.lock";
|
|
195
|
+
/**
|
|
196
|
+
* @param {string} targetName
|
|
197
|
+
* @returns {string[]}
|
|
198
|
+
*/
|
|
199
|
+
function listDependenciesOf(targetName) {
|
|
200
|
+
const resolvedLockfilePath = path.resolve(process.cwd(), lockfilePath);
|
|
201
|
+
if (!fs.existsSync(resolvedLockfilePath)) {
|
|
202
|
+
console.error("Lockfile not found: " + resolvedLockfilePath);
|
|
203
|
+
}
|
|
204
|
+
const lockText = fs.readFileSync(resolvedLockfilePath, "utf8");
|
|
205
|
+
const { selectorToEntry, nameToEntries } = parseLockfile(lockText);
|
|
206
|
+
const startEntries = nameToEntries.get(targetName) || [];
|
|
207
|
+
if (startEntries.length === 0) {
|
|
208
|
+
console.error("Module not found in yarn.lock: " + targetName);
|
|
209
|
+
}
|
|
210
|
+
const deps = collectDependencies(startEntries, selectorToEntry, nameToEntries);
|
|
211
|
+
return Array.from(deps).sort();
|
|
212
|
+
}
|
|
213
|
+
module.exports = { listDependenciesOf };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
list-deps-of() {
|
|
5
|
+
local module_name="${1:-}"
|
|
6
|
+
if [ -z "${module_name}" ]; then
|
|
7
|
+
echo "Usage: list-deps-of <module-name> [--lockfile <path>]" >&2
|
|
8
|
+
return 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
local script_dir
|
|
12
|
+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
node "${script_dir}/list-deps-of.js" "$@"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
|
17
|
+
list-deps-of "$@"
|
|
18
|
+
fi
|
package/extras/tiny-progress.js
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-dev-tool",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"bin": {
|
|
5
5
|
"jstool": "tools.js"
|
|
6
6
|
},
|
|
@@ -85,11 +85,11 @@
|
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"colors.ts": "^1.0.20",
|
|
87
87
|
"fflate": "^0.8.2",
|
|
88
|
-
"literate-regex": "^0.
|
|
89
|
-
"mini-semaphore": "^1.
|
|
88
|
+
"literate-regex": "^0.6.9",
|
|
89
|
+
"mini-semaphore": "^1.5.1",
|
|
90
90
|
"replace": "^1.2.2",
|
|
91
|
-
"rm-cstyle-cmts": "^3.
|
|
92
|
-
"terser": "^5.
|
|
91
|
+
"rm-cstyle-cmts": "^3.4.2",
|
|
92
|
+
"terser": "^5.46.0",
|
|
93
93
|
"tin-args": "^0.1.1"
|
|
94
94
|
}
|
|
95
95
|
}
|
package/progress/index.js
CHANGED
package/progress/rnd-spinner.js
CHANGED
package/progress/test.js
CHANGED
package/tool-lib/cjbm.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
7
|
*/
|
|
8
8
|
/// <reference path="./tools.d.ts"/>
|
|
9
|
+
"use strict";
|
|
9
10
|
// @ts-check
|
|
10
11
|
/**
|
|
11
12
|
* @file (C)onvert (J)S to (B)rowser (M)odule
|
|
@@ -56,7 +57,7 @@ const reImportExportDetection = compilePCREStyleRegExpLiteral(RE_TEXT);
|
|
|
56
57
|
/**
|
|
57
58
|
* @typedef {typeof reImportExportDetection} TImportExportDetectorRegex
|
|
58
59
|
* @typedef {TImportExportDetectorRegex["types"]["exec"]} TImportExportDetectorRegexExecResult
|
|
59
|
-
* @typedef {XRegex.
|
|
60
|
+
* @typedef {XRegex.StringReplacerType<TImportExportDetectorRegex>} TImportExportDetectRegexReplacer
|
|
60
61
|
*/
|
|
61
62
|
/**
|
|
62
63
|
* Generates a replacer function to update import/export statements with a new file extension.
|
package/tool-lib/cmt-trick.js
CHANGED
package/tool-lib/ps.js
CHANGED
package/tool-lib/rws.js
CHANGED
package/tool-lib/tools.d.ts
CHANGED
package/tool-lib/zip-task.js
CHANGED
package/tools.js
CHANGED
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
9
9
|
*/
|
|
10
10
|
// @ts-check
|
|
11
|
+
"use strict";
|
|
11
12
|
const fs = require("fs");
|
|
12
13
|
const path = require("path");
|
|
14
|
+
const rmc = require("rm-cstyle-cmts");
|
|
13
15
|
/* utilities module by own. */
|
|
14
16
|
const utils = require("./utils");
|
|
15
17
|
// @ts-expect- error
|
|
@@ -203,14 +205,16 @@ const ToolFunctions = {
|
|
|
203
205
|
rmc: {
|
|
204
206
|
taskName: "rm-cstyle-cmts",
|
|
205
207
|
fn() {
|
|
206
|
-
|
|
208
|
+
rmc.reset();
|
|
207
209
|
if (params.rmc4ts) {
|
|
208
210
|
const keepBangLine = params.rmc4ts === "keepBangLine";
|
|
211
|
+
const reMultiLineChcker = /^\/\*(\*|!)\s|^\/\*(?!-).+\*\/$/;
|
|
212
|
+
const reSingleLineChecer = /^\/\/+!/;
|
|
209
213
|
rmc.setListener(({ event, fragment }) => {
|
|
210
214
|
if (event === /*EScannerEvent.MultiLineComment*/ 1) {
|
|
211
|
-
return
|
|
215
|
+
return reMultiLineChcker.test(fragment);
|
|
212
216
|
} else if (keepBangLine && event === /*EScannerEvent.SingleLineComment*/0) {
|
|
213
|
-
return
|
|
217
|
+
return reSingleLineChecer.test(fragment);
|
|
214
218
|
}
|
|
215
219
|
return false;
|
|
216
220
|
});
|
|
@@ -220,7 +224,8 @@ const ToolFunctions = {
|
|
|
220
224
|
processSources(
|
|
221
225
|
/** @type {string} */ (this.taskName),
|
|
222
226
|
(data) => {
|
|
223
|
-
|
|
227
|
+
let result = rmc(data);
|
|
228
|
+
return preserveTsReferenceDirectives(result);
|
|
224
229
|
},
|
|
225
230
|
{
|
|
226
231
|
bases: basePaths,
|
|
@@ -236,12 +241,45 @@ const ToolFunctions = {
|
|
|
236
241
|
rmc4ts- for typescript source.
|
|
237
242
|
keep comment that start with "/*" when "*/" end mark appears in same line.
|
|
238
243
|
if start with "/*-" remove it
|
|
244
|
+
keep leading "/// <reference ...>" directives above a top-level "use strict" line in CJS emit.(2026/02/03)
|
|
239
245
|
rmc4ts=keepBangLine (2025/12/24)
|
|
240
246
|
- In addition to the "rmc4ts" processing, it also preserves line comments that start with "//!".
|
|
241
247
|
`,
|
|
242
248
|
},
|
|
243
249
|
zip: require("./tool-lib/zip-task")(utils),
|
|
244
250
|
};
|
|
251
|
+
/**
|
|
252
|
+
* Preserve TypeScript `/// <reference ...>` directives when a leading
|
|
253
|
+
* "use strict" line would otherwise push them below the directive zone
|
|
254
|
+
* after C-style comment stripping.
|
|
255
|
+
*
|
|
256
|
+
* It hoists any header reference directives back above "use strict" so the
|
|
257
|
+
* TypeScript compiler can still see them in CommonJS outputs.
|
|
258
|
+
*
|
|
259
|
+
* @param {string} jsSource - JavaScript source after comment removal.
|
|
260
|
+
* @param {true=} debug - Log when code is executed.
|
|
261
|
+
* @returns {string} Source with reference directives restored to the header.
|
|
262
|
+
* @date 2026/02/03 14:45:49
|
|
263
|
+
*/
|
|
264
|
+
function preserveTsReferenceDirectives(jsSource, debug) {
|
|
265
|
+
const m = /^(["'])use strict\1;?[\r\n]/.exec(jsSource);
|
|
266
|
+
if (m) {
|
|
267
|
+
const usLen = m[0].length;
|
|
268
|
+
const usLine = jsSource.slice(m.index, usLen);
|
|
269
|
+
/** @type {string[]} */
|
|
270
|
+
const knownDirectives = [];
|
|
271
|
+
const reReferenceDirectiveChecker = /^\/\/\/\s*<reference.+[\r\n]/gm;
|
|
272
|
+
let purgedSource = jsSource.slice(usLen).replace(reReferenceDirectiveChecker, (match) => {
|
|
273
|
+
knownDirectives.push(match);
|
|
274
|
+
return "";
|
|
275
|
+
});
|
|
276
|
+
if (knownDirectives.length) {
|
|
277
|
+
debug && utils.log("preserveTsReferenceDirectives applied");
|
|
278
|
+
return knownDirectives.join("") + usLine + purgedSource;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return jsSource;
|
|
282
|
+
}
|
|
245
283
|
/**
|
|
246
284
|
* @param {TJSToolEntry} entry
|
|
247
285
|
* @returns {entry is TJSToolEntry}
|
package/utils.d.ts
CHANGED
|
@@ -159,4 +159,5 @@ export const CI: boolean;
|
|
|
159
159
|
/**
|
|
160
160
|
* Nothing is logged in a CI environment.
|
|
161
161
|
*/
|
|
162
|
-
export const log: typeof console.log;
|
|
162
|
+
export const log: typeof console.log;
|
|
163
|
+
export const listDependenciesOf: typeof import("./extras/list-deps-of").listDependenciesOf;
|
package/utils.js
CHANGED
|
@@ -20,10 +20,12 @@
|
|
|
20
20
|
/// <reference types="./basic-types"/>
|
|
21
21
|
/// <reference types="./lib/zlibjs.d.ts"/>
|
|
22
22
|
// @ts-check
|
|
23
|
+
"use strict";
|
|
23
24
|
const fs = require("fs");
|
|
24
25
|
const path = require("path");
|
|
25
26
|
const lib = require("./common");
|
|
26
27
|
const tinArgs = require("tin-args");
|
|
28
|
+
const { listDependenciesOf } = require("./extras/list-deps-of");
|
|
27
29
|
const CI = !!process.env.CI;
|
|
28
30
|
/**
|
|
29
31
|
* Nothing is logged in a CI environment.
|
|
@@ -406,4 +408,5 @@ module.exports = {
|
|
|
406
408
|
fireReplace,
|
|
407
409
|
CI,
|
|
408
410
|
log,
|
|
411
|
+
listDependenciesOf
|
|
409
412
|
};
|