@yabasha/gex 1.0.1 → 1.1.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/dist/cli-bun.mjs +660 -0
- package/dist/cli-bun.mjs.map +1 -0
- package/dist/cli-node.cjs +572 -0
- package/dist/cli-node.cjs.map +1 -0
- package/dist/cli-node.mjs +540 -0
- package/dist/cli-node.mjs.map +1 -0
- package/dist/cli.cjs +173 -310
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +171 -309
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +18 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +18 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/cli.cjs
CHANGED
|
@@ -31,40 +31,60 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/cli.ts
|
|
32
32
|
var cli_exports = {};
|
|
33
33
|
__export(cli_exports, {
|
|
34
|
-
run: () =>
|
|
34
|
+
run: () => run2
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(cli_exports);
|
|
37
37
|
|
|
38
|
-
// src/
|
|
38
|
+
// src/runtimes/node/commands.ts
|
|
39
39
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
40
40
|
var import_commander = require("commander");
|
|
41
41
|
|
|
42
|
-
// src/cli/install.ts
|
|
42
|
+
// src/shared/cli/install.ts
|
|
43
|
+
var INSTALL_COMMANDS = {
|
|
44
|
+
npm: {
|
|
45
|
+
global: ["i", "-g"],
|
|
46
|
+
local: ["i"],
|
|
47
|
+
dev: ["i", "-D"]
|
|
48
|
+
},
|
|
49
|
+
bun: {
|
|
50
|
+
global: ["add", "-g"],
|
|
51
|
+
local: ["add"],
|
|
52
|
+
dev: ["add", "-d"]
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
var MAX_BUFFER = 10 * 1024 * 1024;
|
|
56
|
+
function formatSpec(pkg) {
|
|
57
|
+
return pkg.version ? `${pkg.name}@${pkg.version}` : pkg.name;
|
|
58
|
+
}
|
|
43
59
|
async function getExecFileAsync() {
|
|
44
60
|
const { execFile } = await import("child_process");
|
|
45
61
|
const { promisify } = await import("util");
|
|
46
62
|
return promisify(execFile);
|
|
47
63
|
}
|
|
48
|
-
async function installFromReport(report,
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
64
|
+
async function installFromReport(report, options) {
|
|
65
|
+
const opts = typeof options === "string" ? { cwd: options } : options;
|
|
66
|
+
const { cwd, packageManager = "npm" } = opts;
|
|
67
|
+
const globalPkgs = report.global_packages.map(formatSpec).filter(Boolean);
|
|
68
|
+
const localPkgs = report.local_dependencies.map(formatSpec).filter(Boolean);
|
|
69
|
+
const devPkgs = report.local_dev_dependencies.map(formatSpec).filter(Boolean);
|
|
52
70
|
if (globalPkgs.length === 0 && localPkgs.length === 0 && devPkgs.length === 0) {
|
|
53
71
|
console.log("No packages to install from report.");
|
|
54
72
|
return;
|
|
55
73
|
}
|
|
56
74
|
const execFileAsync = await getExecFileAsync();
|
|
75
|
+
const cmd = INSTALL_COMMANDS[packageManager];
|
|
76
|
+
const binary = packageManager === "bun" ? "bun" : "npm";
|
|
57
77
|
if (globalPkgs.length > 0) {
|
|
58
78
|
console.log(`Installing global: ${globalPkgs.join(" ")}`);
|
|
59
|
-
await execFileAsync(
|
|
79
|
+
await execFileAsync(binary, [...cmd.global, ...globalPkgs], { cwd, maxBuffer: MAX_BUFFER });
|
|
60
80
|
}
|
|
61
81
|
if (localPkgs.length > 0) {
|
|
62
82
|
console.log(`Installing local deps: ${localPkgs.join(" ")}`);
|
|
63
|
-
await execFileAsync(
|
|
83
|
+
await execFileAsync(binary, [...cmd.local, ...localPkgs], { cwd, maxBuffer: MAX_BUFFER });
|
|
64
84
|
}
|
|
65
85
|
if (devPkgs.length > 0) {
|
|
66
86
|
console.log(`Installing local devDeps: ${devPkgs.join(" ")}`);
|
|
67
|
-
await execFileAsync(
|
|
87
|
+
await execFileAsync(binary, [...cmd.dev, ...devPkgs], { cwd, maxBuffer: MAX_BUFFER });
|
|
68
88
|
}
|
|
69
89
|
}
|
|
70
90
|
function printFromReport(report) {
|
|
@@ -95,10 +115,10 @@ function printFromReport(report) {
|
|
|
95
115
|
console.log(lines.join("\n"));
|
|
96
116
|
}
|
|
97
117
|
|
|
98
|
-
// src/cli/output.ts
|
|
118
|
+
// src/shared/cli/output.ts
|
|
99
119
|
var import_node_path = __toESM(require("path"), 1);
|
|
100
120
|
|
|
101
|
-
// src/report/json.ts
|
|
121
|
+
// src/shared/report/json.ts
|
|
102
122
|
function renderJson(report) {
|
|
103
123
|
const r = {
|
|
104
124
|
...report,
|
|
@@ -111,7 +131,7 @@ function renderJson(report) {
|
|
|
111
131
|
return JSON.stringify(r, null, 2);
|
|
112
132
|
}
|
|
113
133
|
|
|
114
|
-
// src/report/md.ts
|
|
134
|
+
// src/shared/report/md.ts
|
|
115
135
|
function table(headers, rows) {
|
|
116
136
|
const header = `| ${headers.join(" | ")} |`;
|
|
117
137
|
const sep = `| ${headers.map(() => "---").join(" | ")} |`;
|
|
@@ -164,211 +184,9 @@ function renderMarkdown(report) {
|
|
|
164
184
|
return lines.join("\n");
|
|
165
185
|
}
|
|
166
186
|
|
|
167
|
-
// src/
|
|
168
|
-
function table2(headers, rows) {
|
|
169
|
-
const headerHtml = `<tr>${headers.map((h) => `<th>${h}</th>`).join("")}</tr>`;
|
|
170
|
-
const bodyHtml = rows.map((row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join("")}</tr>`).join("");
|
|
171
|
-
return `<table><thead>${headerHtml}</thead><tbody>${bodyHtml}</tbody></table>`;
|
|
172
|
-
}
|
|
173
|
-
function escapeHtml(text) {
|
|
174
|
-
const htmlEntities = {
|
|
175
|
-
"&": "&",
|
|
176
|
-
"<": "<",
|
|
177
|
-
">": ">",
|
|
178
|
-
'"': """,
|
|
179
|
-
"'": "'"
|
|
180
|
-
};
|
|
181
|
-
return text.replace(/[&<>"']/g, (char) => htmlEntities[char]);
|
|
182
|
-
}
|
|
183
|
-
function renderHtml(report) {
|
|
184
|
-
const hasProjectMeta = report.project_name || report.project_version || report.project_description || report.project_homepage || report.project_bugs;
|
|
185
|
-
return `<!DOCTYPE html>
|
|
186
|
-
<html lang="en">
|
|
187
|
-
<head>
|
|
188
|
-
<meta charset="UTF-8">
|
|
189
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
190
|
-
<title>GEX Report - ${report.project_name || "Dependency Audit"}</title>
|
|
191
|
-
<style>
|
|
192
|
-
body {
|
|
193
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
194
|
-
line-height: 1.6;
|
|
195
|
-
color: #333;
|
|
196
|
-
max-width: 1200px;
|
|
197
|
-
margin: 0 auto;
|
|
198
|
-
padding: 20px;
|
|
199
|
-
background-color: #f5f5f5;
|
|
200
|
-
}
|
|
201
|
-
.container {
|
|
202
|
-
background: white;
|
|
203
|
-
border-radius: 8px;
|
|
204
|
-
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
205
|
-
padding: 30px;
|
|
206
|
-
}
|
|
207
|
-
h1 {
|
|
208
|
-
color: #2c3e50;
|
|
209
|
-
border-bottom: 3px solid #3498db;
|
|
210
|
-
padding-bottom: 10px;
|
|
211
|
-
margin-top: 0;
|
|
212
|
-
}
|
|
213
|
-
h2 {
|
|
214
|
-
color: #34495e;
|
|
215
|
-
border-bottom: 2px solid #bdc3c7;
|
|
216
|
-
padding-bottom: 8px;
|
|
217
|
-
margin-top: 40px;
|
|
218
|
-
margin-bottom: 20px;
|
|
219
|
-
}
|
|
220
|
-
.metadata {
|
|
221
|
-
background: #ecf0f1;
|
|
222
|
-
border-radius: 6px;
|
|
223
|
-
padding: 20px;
|
|
224
|
-
margin-bottom: 20px;
|
|
225
|
-
}
|
|
226
|
-
.metadata dl {
|
|
227
|
-
margin: 0;
|
|
228
|
-
}
|
|
229
|
-
.metadata dt {
|
|
230
|
-
font-weight: bold;
|
|
231
|
-
color: #2c3e50;
|
|
232
|
-
margin-top: 10px;
|
|
233
|
-
}
|
|
234
|
-
.metadata dt:first-child {
|
|
235
|
-
margin-top: 0;
|
|
236
|
-
}
|
|
237
|
-
.metadata dd {
|
|
238
|
-
margin: 5px 0 0 20px;
|
|
239
|
-
color: #555;
|
|
240
|
-
}
|
|
241
|
-
.metadata dd a {
|
|
242
|
-
color: #3498db;
|
|
243
|
-
text-decoration: none;
|
|
244
|
-
}
|
|
245
|
-
.metadata dd a:hover {
|
|
246
|
-
text-decoration: underline;
|
|
247
|
-
}
|
|
248
|
-
table {
|
|
249
|
-
width: 100%;
|
|
250
|
-
border-collapse: collapse;
|
|
251
|
-
margin-bottom: 30px;
|
|
252
|
-
background: white;
|
|
253
|
-
border-radius: 6px;
|
|
254
|
-
overflow: hidden;
|
|
255
|
-
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
256
|
-
}
|
|
257
|
-
th {
|
|
258
|
-
background: #3498db;
|
|
259
|
-
color: white;
|
|
260
|
-
padding: 12px;
|
|
261
|
-
text-align: left;
|
|
262
|
-
font-weight: 600;
|
|
263
|
-
}
|
|
264
|
-
td {
|
|
265
|
-
padding: 12px;
|
|
266
|
-
border-bottom: 1px solid #ecf0f1;
|
|
267
|
-
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
268
|
-
font-size: 14px;
|
|
269
|
-
}
|
|
270
|
-
tr:nth-child(even) {
|
|
271
|
-
background: #f8f9fa;
|
|
272
|
-
}
|
|
273
|
-
tr:hover {
|
|
274
|
-
background: #e8f4fd;
|
|
275
|
-
}
|
|
276
|
-
.footer {
|
|
277
|
-
text-align: center;
|
|
278
|
-
color: #7f8c8d;
|
|
279
|
-
font-size: 14px;
|
|
280
|
-
margin-top: 40px;
|
|
281
|
-
padding-top: 20px;
|
|
282
|
-
border-top: 1px solid #ecf0f1;
|
|
283
|
-
}
|
|
284
|
-
.footer strong {
|
|
285
|
-
color: #2c3e50;
|
|
286
|
-
}
|
|
287
|
-
.no-data {
|
|
288
|
-
text-align: center;
|
|
289
|
-
color: #7f8c8d;
|
|
290
|
-
font-style: italic;
|
|
291
|
-
padding: 40px;
|
|
292
|
-
}
|
|
293
|
-
.timestamp {
|
|
294
|
-
color: #95a5a6;
|
|
295
|
-
font-size: 14px;
|
|
296
|
-
margin-top: 10px;
|
|
297
|
-
}
|
|
298
|
-
</style>
|
|
299
|
-
</head>
|
|
300
|
-
<body>
|
|
301
|
-
<div class="container">
|
|
302
|
-
<h1>GEX Dependency Report</h1>
|
|
303
|
-
|
|
304
|
-
${hasProjectMeta ? `
|
|
305
|
-
<section class="metadata">
|
|
306
|
-
<h2>Project Information</h2>
|
|
307
|
-
<dl>
|
|
308
|
-
${report.project_name ? `<dt>Project Name</dt><dd>${escapeHtml(report.project_name)}</dd>` : ""}
|
|
309
|
-
${report.project_version ? `<dt>Version</dt><dd>${escapeHtml(report.project_version)}</dd>` : ""}
|
|
310
|
-
${report.project_description ? `<dt>Description</dt><dd>${escapeHtml(report.project_description)}</dd>` : ""}
|
|
311
|
-
${report.project_homepage ? `<dt>Homepage</dt><dd><a href="${escapeHtml(report.project_homepage)}" target="_blank">${escapeHtml(report.project_homepage)}</a></dd>` : ""}
|
|
312
|
-
${report.project_bugs ? `<dt>Bugs</dt><dd><a href="${escapeHtml(report.project_bugs)}" target="_blank">${escapeHtml(report.project_bugs)}</a></dd>` : ""}
|
|
313
|
-
<dt>Report Generated</dt><dd>${new Date(report.timestamp).toLocaleString()}</dd>
|
|
314
|
-
</dl>
|
|
315
|
-
</section>
|
|
316
|
-
` : ""}
|
|
317
|
-
|
|
318
|
-
${report.global_packages.length > 0 ? `
|
|
319
|
-
<section>
|
|
320
|
-
<h2>Global Packages <small>(${report.global_packages.length})</small></h2>
|
|
321
|
-
${table2(
|
|
322
|
-
["Name", "Version", "Path"],
|
|
323
|
-
report.global_packages.map((p) => [
|
|
324
|
-
escapeHtml(p.name),
|
|
325
|
-
escapeHtml(p.version || ""),
|
|
326
|
-
escapeHtml(p.resolved_path || "")
|
|
327
|
-
])
|
|
328
|
-
)}
|
|
329
|
-
</section>
|
|
330
|
-
` : '<section><h2>Global Packages</h2><div class="no-data">No global packages found</div></section>'}
|
|
331
|
-
|
|
332
|
-
${report.local_dependencies.length > 0 ? `
|
|
333
|
-
<section>
|
|
334
|
-
<h2>Local Dependencies <small>(${report.local_dependencies.length})</small></h2>
|
|
335
|
-
${table2(
|
|
336
|
-
["Name", "Version", "Path"],
|
|
337
|
-
report.local_dependencies.map((p) => [
|
|
338
|
-
escapeHtml(p.name),
|
|
339
|
-
escapeHtml(p.version || ""),
|
|
340
|
-
escapeHtml(p.resolved_path || "")
|
|
341
|
-
])
|
|
342
|
-
)}
|
|
343
|
-
</section>
|
|
344
|
-
` : '<section><h2>Local Dependencies</h2><div class="no-data">No local dependencies found</div></section>'}
|
|
345
|
-
|
|
346
|
-
${report.local_dev_dependencies.length > 0 ? `
|
|
347
|
-
<section>
|
|
348
|
-
<h2>Local Dev Dependencies <small>(${report.local_dev_dependencies.length})</small></h2>
|
|
349
|
-
${table2(
|
|
350
|
-
["Name", "Version", "Path"],
|
|
351
|
-
report.local_dev_dependencies.map((p) => [
|
|
352
|
-
escapeHtml(p.name),
|
|
353
|
-
escapeHtml(p.version || ""),
|
|
354
|
-
escapeHtml(p.resolved_path || "")
|
|
355
|
-
])
|
|
356
|
-
)}
|
|
357
|
-
</section>
|
|
358
|
-
` : '<section><h2>Local Dev Dependencies</h2><div class="no-data">No local dev dependencies found</div></section>'}
|
|
359
|
-
|
|
360
|
-
<footer class="footer">
|
|
361
|
-
<p>Generated by <strong>GEX v${escapeHtml(report.tool_version)}</strong> on ${new Date(report.timestamp).toLocaleString()}</p>
|
|
362
|
-
<p>Report format version: ${escapeHtml(report.report_version)}</p>
|
|
363
|
-
</footer>
|
|
364
|
-
</div>
|
|
365
|
-
</body>
|
|
366
|
-
</html>`;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// src/cli/output.ts
|
|
187
|
+
// src/shared/cli/output.ts
|
|
370
188
|
async function outputReport(report, format, outFile, markdownExtras) {
|
|
371
|
-
const content = format === "json" ? renderJson(report) :
|
|
189
|
+
const content = format === "json" ? renderJson(report) : renderMarkdown({ ...report, ...markdownExtras || {} });
|
|
372
190
|
if (outFile) {
|
|
373
191
|
const outDir = import_node_path.default.dirname(outFile);
|
|
374
192
|
const { mkdir, writeFile } = await import("fs/promises");
|
|
@@ -380,7 +198,7 @@ async function outputReport(report, format, outFile, markdownExtras) {
|
|
|
380
198
|
}
|
|
381
199
|
}
|
|
382
200
|
|
|
383
|
-
// src/cli/parser.ts
|
|
201
|
+
// src/shared/cli/parser.ts
|
|
384
202
|
var import_promises = require("fs/promises");
|
|
385
203
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
386
204
|
function isMarkdownReportFile(filePath) {
|
|
@@ -429,60 +247,63 @@ async function loadReportFromFile(reportPath) {
|
|
|
429
247
|
return JSON.parse(raw);
|
|
430
248
|
}
|
|
431
249
|
|
|
432
|
-
// src/cli/
|
|
433
|
-
var
|
|
434
|
-
var
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
return promisify(execFile);
|
|
441
|
-
}
|
|
442
|
-
async function npmLs(options = {}) {
|
|
443
|
-
const args = ["ls", "--json"];
|
|
444
|
-
if (options.global) args.push("--global");
|
|
445
|
-
if (options.omitDev) args.push("--omit=dev");
|
|
446
|
-
if (options.depth0) args.push("--depth=0");
|
|
250
|
+
// src/shared/cli/utils.ts
|
|
251
|
+
var import_node_fs = require("fs");
|
|
252
|
+
var import_promises2 = require("fs/promises");
|
|
253
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
254
|
+
var import_node_url = require("url");
|
|
255
|
+
var import_meta = {};
|
|
256
|
+
function getPkgJsonPath() {
|
|
257
|
+
let startDir;
|
|
447
258
|
try {
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
console.warn("npm ls stdout parse failed:", parseErr);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
259
|
+
const __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
|
|
260
|
+
startDir = import_node_path3.default.dirname(__filename);
|
|
261
|
+
} catch {
|
|
262
|
+
startDir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
263
|
+
}
|
|
264
|
+
return findPackageJson(startDir);
|
|
265
|
+
}
|
|
266
|
+
function findPackageJson(startDir) {
|
|
267
|
+
let current = startDir;
|
|
268
|
+
const maxDepth = 6;
|
|
269
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
270
|
+
const candidate = import_node_path3.default.resolve(current, "package.json");
|
|
271
|
+
if ((0, import_node_fs.existsSync)(candidate)) {
|
|
272
|
+
return candidate;
|
|
465
273
|
}
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
274
|
+
const parent = import_node_path3.default.dirname(current);
|
|
275
|
+
if (parent === current) break;
|
|
276
|
+
current = parent;
|
|
469
277
|
}
|
|
278
|
+
return import_node_path3.default.resolve(process.cwd(), "package.json");
|
|
470
279
|
}
|
|
471
|
-
async function
|
|
280
|
+
async function getToolVersion() {
|
|
472
281
|
try {
|
|
473
|
-
const
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
throw new Error(`npm root -g failed: ${msg}`);
|
|
282
|
+
const pkgPath = getPkgJsonPath();
|
|
283
|
+
const raw = await (0, import_promises2.readFile)(pkgPath, "utf8");
|
|
284
|
+
const pkg = JSON.parse(raw);
|
|
285
|
+
return pkg.version || "0.0.0";
|
|
286
|
+
} catch {
|
|
287
|
+
return "0.0.0";
|
|
480
288
|
}
|
|
481
289
|
}
|
|
290
|
+
var ASCII_BANNER = String.raw`
|
|
291
|
+
________ __
|
|
292
|
+
/ _____/ ____ _____/ |_ ____ ____
|
|
293
|
+
/ \ ___ / _ \ / _ \ __\/ __ \ / \
|
|
294
|
+
\ \_\ ( <_> | <_> ) | \ ___/| | \
|
|
295
|
+
\______ /\____/ \____/|__| \___ >___| /
|
|
296
|
+
\/ \/ \/
|
|
297
|
+
GEX
|
|
298
|
+
`;
|
|
482
299
|
|
|
483
|
-
// src/
|
|
484
|
-
var
|
|
485
|
-
var
|
|
300
|
+
// src/runtimes/node/report.ts
|
|
301
|
+
var import_promises4 = require("fs/promises");
|
|
302
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
303
|
+
|
|
304
|
+
// src/shared/transform.ts
|
|
305
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
306
|
+
var import_promises3 = require("fs/promises");
|
|
486
307
|
function toPkgArray(obj) {
|
|
487
308
|
if (!obj) return [];
|
|
488
309
|
return Object.keys(obj).map((name) => ({ name, node: obj[name] })).filter((p) => p && p.node);
|
|
@@ -500,21 +321,30 @@ async function buildReportFromNpmTree(tree, opts) {
|
|
|
500
321
|
if (opts.context === "local") {
|
|
501
322
|
let pkgMeta = null;
|
|
502
323
|
try {
|
|
503
|
-
const pkgJsonPath =
|
|
504
|
-
const raw = await (0,
|
|
324
|
+
const pkgJsonPath = import_node_path4.default.join(opts.cwd || process.cwd(), "package.json");
|
|
325
|
+
const raw = await (0, import_promises3.readFile)(pkgJsonPath, "utf8");
|
|
505
326
|
pkgMeta = JSON.parse(raw);
|
|
506
327
|
} catch {
|
|
507
328
|
}
|
|
508
329
|
if (pkgMeta?.name) report.project_name = pkgMeta.name;
|
|
509
330
|
if (pkgMeta?.version) report.project_version = pkgMeta.version;
|
|
510
331
|
const depsObj = tree?.dependencies;
|
|
511
|
-
const
|
|
512
|
-
const
|
|
513
|
-
|
|
332
|
+
const devDepsObj = tree?.devDependencies;
|
|
333
|
+
const prodItems = toPkgArray(depsObj);
|
|
334
|
+
const treeDevItems = toPkgArray(devDepsObj);
|
|
335
|
+
if (treeDevItems.length > 0) {
|
|
336
|
+
for (const { name, node } of treeDevItems) {
|
|
337
|
+
const version = node && node.version || "";
|
|
338
|
+
const resolvedPath = node && node.path || import_node_path4.default.join(opts.cwd || process.cwd(), "node_modules", name);
|
|
339
|
+
report.local_dev_dependencies.push({ name, version, resolved_path: resolvedPath });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const devKeys = treeDevItems.length > 0 ? new Set(treeDevItems.map((entry) => entry.name)) : new Set(Object.keys(pkgMeta?.devDependencies || {}));
|
|
343
|
+
for (const { name, node } of prodItems) {
|
|
514
344
|
const version = node && node.version || "";
|
|
515
|
-
const resolvedPath = node && node.path ||
|
|
345
|
+
const resolvedPath = node && node.path || import_node_path4.default.join(opts.cwd || process.cwd(), "node_modules", name);
|
|
516
346
|
const pkg = { name, version, resolved_path: resolvedPath };
|
|
517
|
-
if (devKeys.has(name)) {
|
|
347
|
+
if (!treeDevItems.length && devKeys.has(name)) {
|
|
518
348
|
report.local_dev_dependencies.push(pkg);
|
|
519
349
|
} else {
|
|
520
350
|
report.local_dependencies.push(pkg);
|
|
@@ -527,7 +357,7 @@ async function buildReportFromNpmTree(tree, opts) {
|
|
|
527
357
|
const items = toPkgArray(depsObj);
|
|
528
358
|
for (const { name, node } of items) {
|
|
529
359
|
const version = node && node.version || "";
|
|
530
|
-
const resolvedPath = node && node.path ||
|
|
360
|
+
const resolvedPath = node && node.path || import_node_path4.default.join(opts.globalRoot || "", name);
|
|
531
361
|
const pkg = { name, version, resolved_path: resolvedPath };
|
|
532
362
|
report.global_packages.push(pkg);
|
|
533
363
|
}
|
|
@@ -539,42 +369,54 @@ async function buildReportFromNpmTree(tree, opts) {
|
|
|
539
369
|
return report;
|
|
540
370
|
}
|
|
541
371
|
|
|
542
|
-
// src/
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
372
|
+
// src/runtimes/node/package-manager.ts
|
|
373
|
+
async function getExecFileAsync2() {
|
|
374
|
+
const { execFile } = await import("child_process");
|
|
375
|
+
const { promisify } = await import("util");
|
|
376
|
+
return promisify(execFile);
|
|
377
|
+
}
|
|
378
|
+
async function npmLs(options = {}) {
|
|
379
|
+
const args = ["ls", "--json"];
|
|
380
|
+
if (options.global) args.push("--global");
|
|
381
|
+
if (options.omitDev) args.push("--omit=dev");
|
|
382
|
+
if (options.depth0) args.push("--depth=0");
|
|
548
383
|
try {
|
|
549
|
-
const
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
384
|
+
const execFileAsync = await getExecFileAsync2();
|
|
385
|
+
const { stdout } = await execFileAsync("npm", args, {
|
|
386
|
+
cwd: options.cwd,
|
|
387
|
+
maxBuffer: 10 * 1024 * 1024
|
|
388
|
+
});
|
|
389
|
+
if (stdout && stdout.trim()) return JSON.parse(stdout);
|
|
390
|
+
return {};
|
|
391
|
+
} catch (err) {
|
|
392
|
+
const stdout = err?.stdout;
|
|
393
|
+
if (typeof stdout === "string" && stdout.trim()) {
|
|
394
|
+
try {
|
|
395
|
+
return JSON.parse(stdout);
|
|
396
|
+
} catch (parseErr) {
|
|
397
|
+
if (process.env.DEBUG?.includes("gex")) {
|
|
398
|
+
console.warn("npm ls stdout parse failed:", parseErr);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const stderr = err?.stderr;
|
|
403
|
+
const msg = typeof stderr === "string" && stderr.trim() || err?.message || "npm ls failed";
|
|
404
|
+
throw new Error(`npm ls failed: ${msg}`);
|
|
555
405
|
}
|
|
556
406
|
}
|
|
557
|
-
async function
|
|
407
|
+
async function npmRootGlobal() {
|
|
558
408
|
try {
|
|
559
|
-
const
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
409
|
+
const execFileAsync = await getExecFileAsync2();
|
|
410
|
+
const { stdout } = await execFileAsync("npm", ["root", "-g"]);
|
|
411
|
+
return stdout.trim();
|
|
412
|
+
} catch (err) {
|
|
413
|
+
const stderr = err?.stderr;
|
|
414
|
+
const msg = typeof stderr === "string" && stderr.trim() || err?.message || "npm root -g failed";
|
|
415
|
+
throw new Error(`npm root -g failed: ${msg}`);
|
|
565
416
|
}
|
|
566
417
|
}
|
|
567
|
-
var ASCII_BANNER = String.raw`
|
|
568
|
-
________ __
|
|
569
|
-
/ _____/ ____ _____/ |_ ____ ____
|
|
570
|
-
/ \ ___ / _ \ / _ \ __\/ __ \ / \
|
|
571
|
-
\ \_\ ( <_> | <_> ) | \ ___/| | \
|
|
572
|
-
\______ /\____/ \____/|__| \___ >___| /
|
|
573
|
-
\/ \/ \/
|
|
574
|
-
GEX
|
|
575
|
-
`;
|
|
576
418
|
|
|
577
|
-
// src/
|
|
419
|
+
// src/runtimes/node/report.ts
|
|
578
420
|
async function produceReport(ctx, options) {
|
|
579
421
|
const toolVersion = await getToolVersion();
|
|
580
422
|
const depth0 = !options.fullTree;
|
|
@@ -612,16 +454,12 @@ async function produceReport(ctx, options) {
|
|
|
612
454
|
return { report, markdownExtras };
|
|
613
455
|
}
|
|
614
456
|
|
|
615
|
-
// src/
|
|
457
|
+
// src/runtimes/node/commands.ts
|
|
616
458
|
function addCommonOptions(cmd, { allowOmitDev }) {
|
|
617
459
|
cmd.option(
|
|
618
460
|
"-f, --output-format <format>",
|
|
619
|
-
"Output format:
|
|
620
|
-
(val) =>
|
|
621
|
-
if (val === "md") return "md";
|
|
622
|
-
if (val === "html") return "html";
|
|
623
|
-
return "json";
|
|
624
|
-
},
|
|
461
|
+
"Output format: md or json",
|
|
462
|
+
(val) => val === "md" ? "md" : "json",
|
|
625
463
|
"json"
|
|
626
464
|
).option("-o, --out-file <path>", "Write report to file").option("--full-tree", "Include full npm ls tree (omit depth=0 default)", false);
|
|
627
465
|
if (allowOmitDev) {
|
|
@@ -680,7 +518,7 @@ function createReadCommand(program) {
|
|
|
680
518
|
printFromReport(parsed);
|
|
681
519
|
}
|
|
682
520
|
if (doInstall) {
|
|
683
|
-
await installFromReport(parsed, process.cwd());
|
|
521
|
+
await installFromReport(parsed, { cwd: process.cwd(), packageManager: "npm" });
|
|
684
522
|
}
|
|
685
523
|
} catch (err) {
|
|
686
524
|
const isMd = isMarkdownReportFile(reportPath);
|
|
@@ -702,7 +540,7 @@ ${ASCII_BANNER}`);
|
|
|
702
540
|
return program;
|
|
703
541
|
}
|
|
704
542
|
|
|
705
|
-
// src/cli.ts
|
|
543
|
+
// src/runtimes/node/cli.ts
|
|
706
544
|
var import_meta2 = {};
|
|
707
545
|
async function run(argv = process.argv) {
|
|
708
546
|
const program = await createProgram();
|
|
@@ -727,6 +565,31 @@ if (isMainModule) {
|
|
|
727
565
|
process.exitCode = 1;
|
|
728
566
|
});
|
|
729
567
|
}
|
|
568
|
+
|
|
569
|
+
// src/cli.ts
|
|
570
|
+
var import_meta3 = {};
|
|
571
|
+
async function run2(argv = process.argv) {
|
|
572
|
+
return run(argv);
|
|
573
|
+
}
|
|
574
|
+
var isMainModule2 = (() => {
|
|
575
|
+
try {
|
|
576
|
+
if (typeof require !== "undefined" && typeof module !== "undefined") {
|
|
577
|
+
return require.main === module;
|
|
578
|
+
}
|
|
579
|
+
if (typeof import_meta3 !== "undefined") {
|
|
580
|
+
return import_meta3.url === `file://${process.argv[1]}`;
|
|
581
|
+
}
|
|
582
|
+
return false;
|
|
583
|
+
} catch {
|
|
584
|
+
return false;
|
|
585
|
+
}
|
|
586
|
+
})();
|
|
587
|
+
if (isMainModule2) {
|
|
588
|
+
run2().catch((error) => {
|
|
589
|
+
console.error("CLI error:", error);
|
|
590
|
+
process.exitCode = 1;
|
|
591
|
+
});
|
|
592
|
+
}
|
|
730
593
|
// Annotate the CommonJS export names for ESM import in node:
|
|
731
594
|
0 && (module.exports = {
|
|
732
595
|
run
|