@yabasha/gex 0.2.0 → 0.3.1

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/README.md CHANGED
@@ -64,6 +64,12 @@ gex local --omit-dev -f json -o deps.json
64
64
 
65
65
  # Global packages
66
66
  gex global -f md -o global.md
67
+
68
+ # Read a previous report (default prints names@versions; -i installs)
69
+ # from default gex-report.json
70
+ gex read
71
+ # or specify a file and install
72
+ gex read -r path/to/report.json -i
67
73
  ```
68
74
 
69
75
  ## JSON schema (summary)
package/dist/cli.cjs CHANGED
@@ -37,6 +37,8 @@ module.exports = __toCommonJS(cli_exports);
37
37
  var import_promises2 = require("fs/promises");
38
38
  var import_node_path2 = __toESM(require("path"), 1);
39
39
  var import_node_url = require("url");
40
+ var import_node_child_process2 = require("child_process");
41
+ var import_node_util2 = require("util");
40
42
  var import_commander = require("commander");
41
43
 
42
44
  // src/npm.ts
@@ -226,6 +228,7 @@ async function getToolVersion() {
226
228
  return "0.0.0";
227
229
  }
228
230
  }
231
+ var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
229
232
  var ASCII_BANNER = String.raw`
230
233
  ________ __
231
234
  / _____/ ____ _____/ |_ ____ ____
@@ -271,6 +274,54 @@ async function produceReport(ctx, options) {
271
274
  const markdownExtras = { project_description, project_homepage, project_bugs };
272
275
  return { report, markdownExtras };
273
276
  }
277
+ function printFromReport(report) {
278
+ const lines = [];
279
+ if (report.global_packages.length > 0) {
280
+ lines.push("Global Packages:");
281
+ for (const p of report.global_packages) {
282
+ lines.push(`- ${p.name}@${p.version}`);
283
+ }
284
+ }
285
+ if (report.local_dependencies.length > 0) {
286
+ if (lines.length) lines.push("");
287
+ lines.push("Local Dependencies:");
288
+ for (const p of report.local_dependencies) {
289
+ lines.push(`- ${p.name}@${p.version}`);
290
+ }
291
+ }
292
+ if (report.local_dev_dependencies.length > 0) {
293
+ if (lines.length) lines.push("");
294
+ lines.push("Local Dev Dependencies:");
295
+ for (const p of report.local_dev_dependencies) {
296
+ lines.push(`- ${p.name}@${p.version}`);
297
+ }
298
+ }
299
+ if (lines.length === 0) {
300
+ lines.push("(no packages found in report)");
301
+ }
302
+ console.log(lines.join("\n"));
303
+ }
304
+ async function installFromReport(report, cwd) {
305
+ const globalPkgs = report.global_packages.map((p) => `${p.name}@${p.version}`).filter(Boolean);
306
+ const localPkgs = report.local_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean);
307
+ const devPkgs = report.local_dev_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean);
308
+ if (globalPkgs.length === 0 && localPkgs.length === 0 && devPkgs.length === 0) {
309
+ console.log("No packages to install from report.");
310
+ return;
311
+ }
312
+ if (globalPkgs.length > 0) {
313
+ console.log(`Installing global: ${globalPkgs.join(" ")}`);
314
+ await execFileAsync2("npm", ["i", "-g", ...globalPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 });
315
+ }
316
+ if (localPkgs.length > 0) {
317
+ console.log(`Installing local deps: ${localPkgs.join(" ")}`);
318
+ await execFileAsync2("npm", ["i", ...localPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 });
319
+ }
320
+ if (devPkgs.length > 0) {
321
+ console.log(`Installing local devDeps: ${devPkgs.join(" ")}`);
322
+ await execFileAsync2("npm", ["i", "-D", ...devPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 });
323
+ }
324
+ }
274
325
  async function outputReport(report, format, outFile, markdownExtras) {
275
326
  const content = format === "json" ? renderJson(report) : renderMarkdown({ ...report, ...markdownExtras || {} });
276
327
  if (outFile) {
@@ -282,6 +333,51 @@ async function outputReport(report, format, outFile, markdownExtras) {
282
333
  console.log(content);
283
334
  }
284
335
  }
336
+ function isMarkdownReportFile(filePath) {
337
+ const ext = import_node_path2.default.extname(filePath).toLowerCase();
338
+ return ext === ".md" || ext === ".markdown";
339
+ }
340
+ function parseMarkdownPackagesTable(lines, startIndex) {
341
+ const rows = [];
342
+ if (!lines[startIndex] || !lines[startIndex].trim().startsWith("|")) return rows;
343
+ let i = startIndex + 2;
344
+ while (i < lines.length && lines[i].trim().startsWith("|")) {
345
+ const cols = lines[i].split("|").map((c) => c.trim()).filter((_, idx, arr) => !(idx === 0 || idx === arr.length - 1));
346
+ const [name = "", version = "", resolved_path = ""] = cols;
347
+ if (name) rows.push({ name, version, resolved_path });
348
+ i++;
349
+ }
350
+ return rows;
351
+ }
352
+ function parseMarkdownReport(md) {
353
+ const lines = md.split(/\r?\n/);
354
+ const findSection = (title) => lines.findIndex((l) => l.trim().toLowerCase() === `## ${title}`.toLowerCase());
355
+ const parseSection = (idx) => {
356
+ if (idx < 0) return [];
357
+ let i = idx + 1;
358
+ while (i < lines.length && !lines[i].trim().startsWith("|")) i++;
359
+ return parseMarkdownPackagesTable(lines, i);
360
+ };
361
+ const global_packages = parseSection(findSection("Global Packages"));
362
+ const local_dependencies = parseSection(findSection("Local Dependencies"));
363
+ const local_dev_dependencies = parseSection(findSection("Local Dev Dependencies"));
364
+ const report = {
365
+ report_version: "1.0",
366
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
367
+ tool_version: "unknown",
368
+ global_packages,
369
+ local_dependencies,
370
+ local_dev_dependencies
371
+ };
372
+ return report;
373
+ }
374
+ async function loadReportFromFile(reportPath) {
375
+ const raw = await (0, import_promises2.readFile)(reportPath, "utf8");
376
+ if (isMarkdownReportFile(reportPath) || raw.startsWith("# GEX Report")) {
377
+ return parseMarkdownReport(raw);
378
+ }
379
+ return JSON.parse(raw);
380
+ }
285
381
  async function run(argv = process.argv) {
286
382
  const program = new import_commander.Command().name("gex").description("GEX: Dependency auditing and documentation for Node.js (local and global).").version(await getToolVersion());
287
383
  program.addHelpText("beforeAll", `
@@ -334,6 +430,30 @@ ${ASCII_BANNER}`);
334
430
  });
335
431
  await outputReport(report, outputFormat, finalOutFile, markdownExtras);
336
432
  });
433
+ const readCmd = program.command("read").description(
434
+ "Read a previously generated report (JSON or Markdown) and either print package names or install them"
435
+ ).argument("[report]", "Path to report file (JSON or Markdown)", "gex-report.json").option("-r, --report <path>", "Path to report file (JSON or Markdown)").option("-p, --print", "Print package names/versions from the report (default)", false).option("-i, --install", "Install packages from the report", false);
436
+ readCmd.action(async (reportArg, opts) => {
437
+ const chosen = opts.report || reportArg || "gex-report.json";
438
+ const reportPath = import_node_path2.default.resolve(process.cwd(), chosen);
439
+ try {
440
+ const parsed = await loadReportFromFile(reportPath);
441
+ const doInstall = Boolean(opts.install);
442
+ const doPrint = Boolean(opts.print) || !doInstall;
443
+ if (doPrint) {
444
+ printFromReport(parsed);
445
+ }
446
+ if (doInstall) {
447
+ await installFromReport(parsed, process.cwd());
448
+ }
449
+ } catch (err) {
450
+ const isMd = isMarkdownReportFile(reportPath);
451
+ const hint = isMd ? "Try generating a JSON report with: gex global -f json -o global.json, then: gex read global.json" : "Specify a report path with: gex read <path-to-report.json>";
452
+ console.error(`Failed to read report at ${reportPath}: ${err?.message || err}`);
453
+ console.error(hint);
454
+ process.exitCode = 1;
455
+ }
456
+ });
337
457
  await program.parseAsync(argv);
338
458
  }
339
459
  var isCjsMain = typeof require !== "undefined" && require.main === module;
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/npm.ts","../src/transform.ts","../src/report/json.ts","../src/report/md.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { Command } from 'commander'\n\nimport { npmLs, npmRootGlobal } from './npm.js'\nimport { buildReportFromNpmTree } from './transform.js'\nimport { renderJson } from './report/json.js'\nimport { renderMarkdown } from './report/md.js'\nimport type { OutputFormat, Report } from './types.js'\n\nfunction getPkgJsonPath(): string {\n // Resolve package.json relative to this file for both ESM and CJS bundles\n try {\n const __filename = fileURLToPath((import.meta as any).url)\n const __dirnameLocal = path.dirname(__filename)\n return path.resolve(__dirnameLocal, '..', 'package.json')\n } catch {\n const dir = typeof __dirname !== 'undefined' ? __dirname : process.cwd()\n return path.resolve(dir, '..', 'package.json')\n }\n}\n\nasync function getToolVersion(): Promise<string> {\n try {\n const pkgPath = getPkgJsonPath()\n const raw = await readFile(pkgPath, 'utf8')\n const pkg = JSON.parse(raw)\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nconst ASCII_BANNER = String.raw`\n ________ __\n / _____/ ____ _____/ |_ ____ ____ \n/ \\ ___ / _ \\ / _ \\ __\\/ __ \\ / \\\n\\ \\_\\ ( <_> | <_> ) | \\ ___/| | \\\n \\______ /\\____/ \\____/|__| \\___ >___| /\n \\/ \\/ \\/ \n GEX\n`\n\nasync function produceReport(\n ctx: 'local' | 'global',\n options: {\n outputFormat: OutputFormat\n outFile?: string\n fullTree?: boolean\n omitDev?: boolean\n cwd?: string\n },\n): Promise<{ report: Report; markdownExtras?: any }> {\n const toolVersion = await getToolVersion()\n const depth0 = !options.fullTree\n const cwd = options.cwd || process.cwd()\n\n const tree = await npmLs({\n global: ctx === 'global',\n omitDev: ctx === 'local' ? Boolean(options.omitDev) : false,\n depth0,\n cwd,\n })\n\n // Get extra metadata for markdown rendering when local\n let project_description: string | undefined\n let project_homepage: string | undefined\n let project_bugs: string | undefined\n if (ctx === 'local') {\n try {\n const pkgRaw = await readFile(path.join(cwd, 'package.json'), 'utf8')\n const pkg = JSON.parse(pkgRaw)\n project_description = pkg.description\n project_homepage = pkg.homepage\n if (typeof pkg.bugs === 'string') project_bugs = pkg.bugs\n else if (pkg.bugs && typeof pkg.bugs.url === 'string') project_bugs = pkg.bugs.url\n } catch {\n // ignore\n }\n }\n\n const globalRoot = ctx === 'global' ? await npmRootGlobal().catch(() => undefined) : undefined\n\n const report = await buildReportFromNpmTree(tree, {\n context: ctx,\n includeTree: Boolean(options.fullTree),\n omitDev: Boolean(options.omitDev),\n cwd,\n toolVersion,\n globalRoot,\n })\n\n const markdownExtras = { project_description, project_homepage, project_bugs }\n return { report, markdownExtras }\n}\n\nasync function outputReport(\n report: Report,\n format: OutputFormat,\n outFile?: string,\n markdownExtras?: any,\n) {\n const content =\n format === 'json'\n ? renderJson(report)\n : renderMarkdown({ ...report, ...(markdownExtras || {}) })\n if (outFile) {\n const outDir = path.dirname(outFile)\n await (await import('node:fs/promises')).mkdir(outDir, { recursive: true })\n await (await import('node:fs/promises')).writeFile(outFile, content, 'utf8')\n\n console.log(`Wrote report to ${outFile}`)\n } else {\n console.log(content)\n }\n}\n\nexport async function run(argv = process.argv) {\n const program = new Command()\n .name('gex')\n .description('GEX: Dependency auditing and documentation for Node.js (local and global).')\n .version(await getToolVersion())\n\n program.addHelpText('beforeAll', `\\n${ASCII_BANNER}`)\n\n const addCommonOptions = (cmd: Command, { allowOmitDev }: { allowOmitDev: boolean }) => {\n cmd\n .option(\n '-f, --output-format <format>',\n 'Output format: md or json',\n (val) => (val === 'md' ? 'md' : 'json'),\n 'json',\n )\n .option('-o, --out-file <path>', 'Write report to file')\n .option('--full-tree', 'Include full npm ls tree (omit depth=0 default)', false)\n if (allowOmitDev) {\n cmd.option('--omit-dev', 'Exclude devDependencies (local only)', false)\n }\n return cmd\n }\n\n // gex local (default command)\n const localCmd = program\n .command('local', { isDefault: true })\n .description(\"Generate a report for the current project's dependencies\")\n addCommonOptions(localCmd, { allowOmitDev: true })\n localCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n const omitDev = Boolean(opts.omitDev)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('local', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n omitDev,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n // gex global\n const globalCmd = program\n .command('global')\n .description('Generate a report of globally installed packages')\n addCommonOptions(globalCmd, { allowOmitDev: false })\n globalCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('global', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n await program.parseAsync(argv)\n}\n\nconst isCjsMain = typeof require !== 'undefined' && (require as any).main === module\nconst isEsmMain =\n typeof import.meta !== 'undefined' && (import.meta as any).url === `file://${process.argv[1]}`\nif (isCjsMain || isEsmMain) {\n run()\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport type NpmLsOptions = {\n global?: boolean\n omitDev?: boolean\n depth0?: boolean\n cwd?: string\n}\n\nexport async function npmLs(options: NpmLsOptions = {}): Promise<any> {\n const args = ['ls', '--json']\n if (options.global) args.push('--global')\n if (options.omitDev) args.push('--omit=dev')\n if (options.depth0) args.push('--depth=0')\n\n try {\n const { stdout } = await execFileAsync('npm', args, {\n cwd: options.cwd,\n maxBuffer: 10 * 1024 * 1024,\n })\n if (stdout && stdout.trim()) return JSON.parse(stdout)\n return {}\n } catch (err: any) {\n const stdout = err?.stdout\n if (typeof stdout === 'string' && stdout.trim()) {\n try {\n return JSON.parse(stdout)\n } catch {\n // fallthrough\n }\n }\n const stderr = err?.stderr\n const msg = (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm ls failed'\n throw new Error(`npm ls failed: ${msg}`)\n }\n}\n\nexport async function npmRootGlobal(): Promise<string> {\n try {\n const { stdout } = await execFileAsync('npm', ['root', '-g'])\n return stdout.trim()\n } catch (err: any) {\n const stderr = err?.stderr\n const msg =\n (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm root -g failed'\n throw new Error(`npm root -g failed: ${msg}`)\n }\n}\n","import path from 'node:path'\nimport { readFile } from 'node:fs/promises'\n\nimport type { PackageInfo, Report } from './types.js'\n\nexport type NormalizeOptions = {\n context: 'local' | 'global'\n includeTree?: boolean\n omitDev?: boolean\n cwd?: string\n toolVersion: string\n globalRoot?: string\n}\n\nfunction toPkgArray(obj: Record<string, any> | undefined | null): { name: string; node: any }[] {\n if (!obj) return []\n return Object.keys(obj)\n .map((name) => ({ name, node: obj[name] }))\n .filter((p) => p && p.node)\n}\n\nexport async function buildReportFromNpmTree(tree: any, opts: NormalizeOptions): Promise<Report> {\n const timestamp = new Date().toISOString()\n const report: Report = {\n report_version: '1.0',\n timestamp,\n tool_version: opts.toolVersion,\n global_packages: [],\n local_dependencies: [],\n local_dev_dependencies: [],\n }\n\n if (opts.context === 'local') {\n let pkgMeta: any = null\n try {\n const pkgJsonPath = path.join(opts.cwd || process.cwd(), 'package.json')\n const raw = await readFile(pkgJsonPath, 'utf8')\n pkgMeta = JSON.parse(raw)\n } catch {\n // ignore; project metadata optional\n }\n if (pkgMeta?.name) report.project_name = pkgMeta.name\n if (pkgMeta?.version) report.project_version = pkgMeta.version\n\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n const devKeys = new Set(Object.keys((pkgMeta?.devDependencies as Record<string, string>) || {}))\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath =\n (node && node.path) || path.join(opts.cwd || process.cwd(), 'node_modules', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n if (devKeys.has(name)) {\n // Only categorize as dev if present in the tree; with --omit-dev they won't appear\n report.local_dev_dependencies.push(pkg)\n } else {\n report.local_dependencies.push(pkg)\n }\n }\n\n // sort\n report.local_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n report.local_dev_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n } else if (opts.context === 'global') {\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath = (node && node.path) || path.join(opts.globalRoot || '', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n report.global_packages.push(pkg)\n }\n\n report.global_packages.sort((a, b) => a.name.localeCompare(b.name))\n }\n\n if (opts.includeTree) {\n report.tree = tree\n }\n\n return report\n}\n","import type { Report } from '../types.js'\n\nexport function renderJson(report: Report): string {\n // Ensure stable ordering (defensive; arrays already sorted)\n const r: Report = {\n ...report,\n global_packages: [...report.global_packages].sort((a, b) => a.name.localeCompare(b.name)),\n local_dependencies: [...report.local_dependencies].sort((a, b) => a.name.localeCompare(b.name)),\n local_dev_dependencies: [...report.local_dev_dependencies].sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n }\n return JSON.stringify(r, null, 2)\n}\n","import type { Report } from '../types.js'\n\nfunction table(headers: string[], rows: string[][]): string {\n const header = `| ${headers.join(' | ')} |`\n const sep = `| ${headers.map(() => '---').join(' | ')} |`\n const body = rows.map((r) => `| ${r.join(' | ')} |`).join('\\n')\n return [header, sep, body].filter(Boolean).join('\\n')\n}\n\nexport function renderMarkdown(\n report: Report & {\n project_description?: string\n project_homepage?: string\n project_bugs?: string\n },\n): string {\n const lines: string[] = []\n lines.push('# GEX Report')\n lines.push('')\n\n if (report.project_name || report.project_version) {\n lines.push('## Project Metadata')\n if (report.project_name) lines.push(`- Name: ${report.project_name}`)\n if (report.project_version) lines.push(`- Version: ${report.project_version}`)\n if ((report as any).project_description)\n lines.push(`- Description: ${(report as any).project_description}`)\n if ((report as any).project_homepage)\n lines.push(`- Homepage: ${(report as any).project_homepage}`)\n if ((report as any).project_bugs) lines.push(`- Bugs: ${(report as any).project_bugs}`)\n lines.push('')\n }\n\n if (report.global_packages.length > 0) {\n lines.push('## Global Packages')\n const rows = report.global_packages.map((p) => [p.name, p.version || '', p.resolved_path || ''])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dependencies.length > 0) {\n lines.push('## Local Dependencies')\n const rows = report.local_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dev_dependencies.length > 0) {\n lines.push('## Local Dev Dependencies')\n const rows = report.local_dev_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n lines.push('---')\n lines.push('_Generated by GEX_')\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":["import_promises","import_node_path","path","path"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/npm.ts","../src/transform.ts","../src/report/json.ts","../src/report/md.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nimport { Command } from 'commander'\n\nimport { npmLs, npmRootGlobal } from './npm.js'\nimport { buildReportFromNpmTree } from './transform.js'\nimport { renderJson } from './report/json.js'\nimport { renderMarkdown } from './report/md.js'\nimport type { OutputFormat, Report } from './types.js'\n\nfunction getPkgJsonPath(): string {\n // Resolve package.json relative to this file for both ESM and CJS bundles\n try {\n const __filename = fileURLToPath((import.meta as any).url)\n const __dirnameLocal = path.dirname(__filename)\n return path.resolve(__dirnameLocal, '..', 'package.json')\n } catch {\n const dir = typeof __dirname !== 'undefined' ? __dirname : process.cwd()\n return path.resolve(dir, '..', 'package.json')\n }\n}\n\nasync function getToolVersion(): Promise<string> {\n try {\n const pkgPath = getPkgJsonPath()\n const raw = await readFile(pkgPath, 'utf8')\n const pkg = JSON.parse(raw)\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nconst execFileAsync = promisify(execFile)\n\nconst ASCII_BANNER = String.raw`\n ________ __\n / _____/ ____ _____/ |_ ____ ____ \n/ \\ ___ / _ \\ / _ \\ __\\/ __ \\ / \\\n\\ \\_\\ ( <_> | <_> ) | \\ ___/| | \\\n \\______ /\\____/ \\____/|__| \\___ >___| /\n \\/ \\/ \\/ \n GEX\n`\n\nasync function produceReport(\n ctx: 'local' | 'global',\n options: {\n outputFormat: OutputFormat\n outFile?: string\n fullTree?: boolean\n omitDev?: boolean\n cwd?: string\n },\n): Promise<{ report: Report; markdownExtras?: any }> {\n const toolVersion = await getToolVersion()\n const depth0 = !options.fullTree\n const cwd = options.cwd || process.cwd()\n\n const tree = await npmLs({\n global: ctx === 'global',\n omitDev: ctx === 'local' ? Boolean(options.omitDev) : false,\n depth0,\n cwd,\n })\n\n // Get extra metadata for markdown rendering when local\n let project_description: string | undefined\n let project_homepage: string | undefined\n let project_bugs: string | undefined\n if (ctx === 'local') {\n try {\n const pkgRaw = await readFile(path.join(cwd, 'package.json'), 'utf8')\n const pkg = JSON.parse(pkgRaw)\n project_description = pkg.description\n project_homepage = pkg.homepage\n if (typeof pkg.bugs === 'string') project_bugs = pkg.bugs\n else if (pkg.bugs && typeof pkg.bugs.url === 'string') project_bugs = pkg.bugs.url\n } catch {\n // ignore\n }\n }\n\n const globalRoot = ctx === 'global' ? await npmRootGlobal().catch(() => undefined) : undefined\n\n const report = await buildReportFromNpmTree(tree, {\n context: ctx,\n includeTree: Boolean(options.fullTree),\n omitDev: Boolean(options.omitDev),\n cwd,\n toolVersion,\n globalRoot,\n })\n\n const markdownExtras = { project_description, project_homepage, project_bugs }\n return { report, markdownExtras }\n}\n\nfunction printFromReport(report: Report) {\n const lines: string[] = []\n if (report.global_packages.length > 0) {\n lines.push('Global Packages:')\n for (const p of report.global_packages) {\n lines.push(`- ${p.name}@${p.version}`)\n }\n }\n if (report.local_dependencies.length > 0) {\n if (lines.length) lines.push('')\n lines.push('Local Dependencies:')\n for (const p of report.local_dependencies) {\n lines.push(`- ${p.name}@${p.version}`)\n }\n }\n if (report.local_dev_dependencies.length > 0) {\n if (lines.length) lines.push('')\n lines.push('Local Dev Dependencies:')\n for (const p of report.local_dev_dependencies) {\n lines.push(`- ${p.name}@${p.version}`)\n }\n }\n if (lines.length === 0) {\n lines.push('(no packages found in report)')\n }\n console.log(lines.join('\\n'))\n}\n\nasync function installFromReport(report: Report, cwd: string) {\n const globalPkgs = report.global_packages.map((p) => `${p.name}@${p.version}`).filter(Boolean)\n const localPkgs = report.local_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean)\n const devPkgs = report.local_dev_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean)\n\n if (globalPkgs.length === 0 && localPkgs.length === 0 && devPkgs.length === 0) {\n console.log('No packages to install from report.')\n return\n }\n\n if (globalPkgs.length > 0) {\n console.log(`Installing global: ${globalPkgs.join(' ')}`)\n await execFileAsync('npm', ['i', '-g', ...globalPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 })\n }\n if (localPkgs.length > 0) {\n console.log(`Installing local deps: ${localPkgs.join(' ')}`)\n await execFileAsync('npm', ['i', ...localPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 })\n }\n if (devPkgs.length > 0) {\n console.log(`Installing local devDeps: ${devPkgs.join(' ')}`)\n await execFileAsync('npm', ['i', '-D', ...devPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 })\n }\n}\n\nasync function outputReport(\n report: Report,\n format: OutputFormat,\n outFile?: string,\n markdownExtras?: any,\n) {\n const content =\n format === 'json'\n ? renderJson(report)\n : renderMarkdown({ ...report, ...(markdownExtras || {}) })\n if (outFile) {\n const outDir = path.dirname(outFile)\n await (await import('node:fs/promises')).mkdir(outDir, { recursive: true })\n await (await import('node:fs/promises')).writeFile(outFile, content, 'utf8')\n\n console.log(`Wrote report to ${outFile}`)\n } else {\n console.log(content)\n }\n}\n\nfunction isMarkdownReportFile(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase()\n return ext === '.md' || ext === '.markdown'\n}\n\nfunction parseMarkdownPackagesTable(lines: string[], startIndex: number) {\n // startIndex points to the header line beginning with '|'\n const rows: { name: string; version: string; resolved_path: string }[] = []\n if (!lines[startIndex] || !lines[startIndex].trim().startsWith('|')) return rows\n // Skip header and separator\n let i = startIndex + 2\n while (i < lines.length && lines[i].trim().startsWith('|')) {\n const cols = lines[i]\n .split('|')\n .map((c) => c.trim())\n .filter((_, idx, arr) => !(idx === 0 || idx === arr.length - 1))\n const [name = '', version = '', resolved_path = ''] = cols\n if (name) rows.push({ name, version, resolved_path })\n i++\n }\n return rows\n}\n\nfunction parseMarkdownReport(md: string): Report {\n const lines = md.split(/\\r?\\n/)\n const findSection = (title: string) =>\n lines.findIndex((l) => l.trim().toLowerCase() === `## ${title}`.toLowerCase())\n const parseSection = (idx: number) => {\n if (idx < 0) return [] as { name: string; version: string; resolved_path: string }[]\n // Find the first table row after header\n let i = idx + 1\n while (i < lines.length && !lines[i].trim().startsWith('|')) i++\n return parseMarkdownPackagesTable(lines, i)\n }\n\n const global_packages = parseSection(findSection('Global Packages'))\n const local_dependencies = parseSection(findSection('Local Dependencies'))\n const local_dev_dependencies = parseSection(findSection('Local Dev Dependencies'))\n\n const report: Report = {\n report_version: '1.0',\n timestamp: new Date().toISOString(),\n tool_version: 'unknown',\n global_packages,\n local_dependencies,\n local_dev_dependencies,\n }\n return report\n}\n\nasync function loadReportFromFile(reportPath: string): Promise<Report> {\n const raw = await readFile(reportPath, 'utf8')\n if (isMarkdownReportFile(reportPath) || raw.startsWith('# GEX Report')) {\n return parseMarkdownReport(raw)\n }\n // assume JSON\n return JSON.parse(raw) as Report\n}\nexport async function run(argv = process.argv) {\n const program = new Command()\n .name('gex')\n .description('GEX: Dependency auditing and documentation for Node.js (local and global).')\n .version(await getToolVersion())\n\n program.addHelpText('beforeAll', `\\n${ASCII_BANNER}`)\n\n const addCommonOptions = (cmd: Command, { allowOmitDev }: { allowOmitDev: boolean }) => {\n cmd\n .option(\n '-f, --output-format <format>',\n 'Output format: md or json',\n (val) => (val === 'md' ? 'md' : 'json'),\n 'json',\n )\n .option('-o, --out-file <path>', 'Write report to file')\n .option('--full-tree', 'Include full npm ls tree (omit depth=0 default)', false)\n if (allowOmitDev) {\n cmd.option('--omit-dev', 'Exclude devDependencies (local only)', false)\n }\n return cmd\n }\n\n // gex local (default command)\n const localCmd = program\n .command('local', { isDefault: true })\n .description(\"Generate a report for the current project's dependencies\")\n addCommonOptions(localCmd, { allowOmitDev: true })\n localCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n const omitDev = Boolean(opts.omitDev)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('local', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n omitDev,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n // gex global\n const globalCmd = program\n .command('global')\n .description('Generate a report of globally installed packages')\n addCommonOptions(globalCmd, { allowOmitDev: false })\n globalCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('global', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n // gex read (consume a previous JSON report)\n const readCmd = program\n .command('read')\n .description(\n 'Read a previously generated report (JSON or Markdown) and either print package names or install them',\n )\n .argument('[report]', 'Path to report file (JSON or Markdown)', 'gex-report.json')\n .option('-r, --report <path>', 'Path to report file (JSON or Markdown)')\n .option('-p, --print', 'Print package names/versions from the report (default)', false)\n .option('-i, --install', 'Install packages from the report', false)\n readCmd.action(async (reportArg: string | undefined, opts: any) => {\n const chosen = (opts.report as string | undefined) || reportArg || 'gex-report.json'\n const reportPath = path.resolve(process.cwd(), chosen)\n try {\n const parsed = await loadReportFromFile(reportPath)\n\n const doInstall = Boolean(opts.install)\n const doPrint = Boolean(opts.print) || !doInstall\n\n if (doPrint) {\n printFromReport(parsed)\n }\n if (doInstall) {\n await installFromReport(parsed, process.cwd())\n }\n } catch (err: any) {\n const isMd = isMarkdownReportFile(reportPath)\n const hint = isMd\n ? 'Try generating a JSON report with: gex global -f json -o global.json, then: gex read global.json'\n : 'Specify a report path with: gex read <path-to-report.json>'\n console.error(`Failed to read report at ${reportPath}: ${err?.message || err}`)\n console.error(hint)\n process.exitCode = 1\n }\n })\n\n await program.parseAsync(argv)\n}\n\nconst isCjsMain = typeof require !== 'undefined' && (require as any).main === module\nconst isEsmMain =\n typeof import.meta !== 'undefined' && (import.meta as any).url === `file://${process.argv[1]}`\nif (isCjsMain || isEsmMain) {\n run()\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport type NpmLsOptions = {\n global?: boolean\n omitDev?: boolean\n depth0?: boolean\n cwd?: string\n}\n\nexport async function npmLs(options: NpmLsOptions = {}): Promise<any> {\n const args = ['ls', '--json']\n if (options.global) args.push('--global')\n if (options.omitDev) args.push('--omit=dev')\n if (options.depth0) args.push('--depth=0')\n\n try {\n const { stdout } = await execFileAsync('npm', args, {\n cwd: options.cwd,\n maxBuffer: 10 * 1024 * 1024,\n })\n if (stdout && stdout.trim()) return JSON.parse(stdout)\n return {}\n } catch (err: any) {\n const stdout = err?.stdout\n if (typeof stdout === 'string' && stdout.trim()) {\n try {\n return JSON.parse(stdout)\n } catch {\n // fallthrough\n }\n }\n const stderr = err?.stderr\n const msg = (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm ls failed'\n throw new Error(`npm ls failed: ${msg}`)\n }\n}\n\nexport async function npmRootGlobal(): Promise<string> {\n try {\n const { stdout } = await execFileAsync('npm', ['root', '-g'])\n return stdout.trim()\n } catch (err: any) {\n const stderr = err?.stderr\n const msg =\n (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm root -g failed'\n throw new Error(`npm root -g failed: ${msg}`)\n }\n}\n","import path from 'node:path'\nimport { readFile } from 'node:fs/promises'\n\nimport type { PackageInfo, Report } from './types.js'\n\nexport type NormalizeOptions = {\n context: 'local' | 'global'\n includeTree?: boolean\n omitDev?: boolean\n cwd?: string\n toolVersion: string\n globalRoot?: string\n}\n\nfunction toPkgArray(obj: Record<string, any> | undefined | null): { name: string; node: any }[] {\n if (!obj) return []\n return Object.keys(obj)\n .map((name) => ({ name, node: obj[name] }))\n .filter((p) => p && p.node)\n}\n\nexport async function buildReportFromNpmTree(tree: any, opts: NormalizeOptions): Promise<Report> {\n const timestamp = new Date().toISOString()\n const report: Report = {\n report_version: '1.0',\n timestamp,\n tool_version: opts.toolVersion,\n global_packages: [],\n local_dependencies: [],\n local_dev_dependencies: [],\n }\n\n if (opts.context === 'local') {\n let pkgMeta: any = null\n try {\n const pkgJsonPath = path.join(opts.cwd || process.cwd(), 'package.json')\n const raw = await readFile(pkgJsonPath, 'utf8')\n pkgMeta = JSON.parse(raw)\n } catch {\n // ignore; project metadata optional\n }\n if (pkgMeta?.name) report.project_name = pkgMeta.name\n if (pkgMeta?.version) report.project_version = pkgMeta.version\n\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n const devKeys = new Set(Object.keys((pkgMeta?.devDependencies as Record<string, string>) || {}))\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath =\n (node && node.path) || path.join(opts.cwd || process.cwd(), 'node_modules', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n if (devKeys.has(name)) {\n // Only categorize as dev if present in the tree; with --omit-dev they won't appear\n report.local_dev_dependencies.push(pkg)\n } else {\n report.local_dependencies.push(pkg)\n }\n }\n\n // sort\n report.local_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n report.local_dev_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n } else if (opts.context === 'global') {\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath = (node && node.path) || path.join(opts.globalRoot || '', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n report.global_packages.push(pkg)\n }\n\n report.global_packages.sort((a, b) => a.name.localeCompare(b.name))\n }\n\n if (opts.includeTree) {\n report.tree = tree\n }\n\n return report\n}\n","import type { Report } from '../types.js'\n\nexport function renderJson(report: Report): string {\n // Ensure stable ordering (defensive; arrays already sorted)\n const r: Report = {\n ...report,\n global_packages: [...report.global_packages].sort((a, b) => a.name.localeCompare(b.name)),\n local_dependencies: [...report.local_dependencies].sort((a, b) => a.name.localeCompare(b.name)),\n local_dev_dependencies: [...report.local_dev_dependencies].sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n }\n return JSON.stringify(r, null, 2)\n}\n","import type { Report } from '../types.js'\n\nfunction table(headers: string[], rows: string[][]): string {\n const header = `| ${headers.join(' | ')} |`\n const sep = `| ${headers.map(() => '---').join(' | ')} |`\n const body = rows.map((r) => `| ${r.join(' | ')} |`).join('\\n')\n return [header, sep, body].filter(Boolean).join('\\n')\n}\n\nexport function renderMarkdown(\n report: Report & {\n project_description?: string\n project_homepage?: string\n project_bugs?: string\n },\n): string {\n const lines: string[] = []\n lines.push('# GEX Report')\n lines.push('')\n\n if (report.project_name || report.project_version) {\n lines.push('## Project Metadata')\n if (report.project_name) lines.push(`- Name: ${report.project_name}`)\n if (report.project_version) lines.push(`- Version: ${report.project_version}`)\n if ((report as any).project_description)\n lines.push(`- Description: ${(report as any).project_description}`)\n if ((report as any).project_homepage)\n lines.push(`- Homepage: ${(report as any).project_homepage}`)\n if ((report as any).project_bugs) lines.push(`- Bugs: ${(report as any).project_bugs}`)\n lines.push('')\n }\n\n if (report.global_packages.length > 0) {\n lines.push('## Global Packages')\n const rows = report.global_packages.map((p) => [p.name, p.version || '', p.resolved_path || ''])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dependencies.length > 0) {\n lines.push('## Local Dependencies')\n const rows = report.local_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dev_dependencies.length > 0) {\n lines.push('## Local Dev Dependencies')\n const rows = report.local_dev_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n lines.push('---')\n lines.push('_Generated by GEX_')\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":["import_promises","import_node_path","import_node_child_process","import_node_util","path","path","execFileAsync"]}
package/dist/cli.mjs CHANGED
@@ -10,6 +10,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
10
10
  import { readFile as readFile2 } from "fs/promises";
11
11
  import path2 from "path";
12
12
  import { fileURLToPath } from "url";
13
+ import { execFile as execFile2 } from "child_process";
14
+ import { promisify as promisify2 } from "util";
13
15
  import { Command } from "commander";
14
16
 
15
17
  // src/npm.ts
@@ -198,6 +200,7 @@ async function getToolVersion() {
198
200
  return "0.0.0";
199
201
  }
200
202
  }
203
+ var execFileAsync2 = promisify2(execFile2);
201
204
  var ASCII_BANNER = String.raw`
202
205
  ________ __
203
206
  / _____/ ____ _____/ |_ ____ ____
@@ -243,6 +246,54 @@ async function produceReport(ctx, options) {
243
246
  const markdownExtras = { project_description, project_homepage, project_bugs };
244
247
  return { report, markdownExtras };
245
248
  }
249
+ function printFromReport(report) {
250
+ const lines = [];
251
+ if (report.global_packages.length > 0) {
252
+ lines.push("Global Packages:");
253
+ for (const p of report.global_packages) {
254
+ lines.push(`- ${p.name}@${p.version}`);
255
+ }
256
+ }
257
+ if (report.local_dependencies.length > 0) {
258
+ if (lines.length) lines.push("");
259
+ lines.push("Local Dependencies:");
260
+ for (const p of report.local_dependencies) {
261
+ lines.push(`- ${p.name}@${p.version}`);
262
+ }
263
+ }
264
+ if (report.local_dev_dependencies.length > 0) {
265
+ if (lines.length) lines.push("");
266
+ lines.push("Local Dev Dependencies:");
267
+ for (const p of report.local_dev_dependencies) {
268
+ lines.push(`- ${p.name}@${p.version}`);
269
+ }
270
+ }
271
+ if (lines.length === 0) {
272
+ lines.push("(no packages found in report)");
273
+ }
274
+ console.log(lines.join("\n"));
275
+ }
276
+ async function installFromReport(report, cwd) {
277
+ const globalPkgs = report.global_packages.map((p) => `${p.name}@${p.version}`).filter(Boolean);
278
+ const localPkgs = report.local_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean);
279
+ const devPkgs = report.local_dev_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean);
280
+ if (globalPkgs.length === 0 && localPkgs.length === 0 && devPkgs.length === 0) {
281
+ console.log("No packages to install from report.");
282
+ return;
283
+ }
284
+ if (globalPkgs.length > 0) {
285
+ console.log(`Installing global: ${globalPkgs.join(" ")}`);
286
+ await execFileAsync2("npm", ["i", "-g", ...globalPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 });
287
+ }
288
+ if (localPkgs.length > 0) {
289
+ console.log(`Installing local deps: ${localPkgs.join(" ")}`);
290
+ await execFileAsync2("npm", ["i", ...localPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 });
291
+ }
292
+ if (devPkgs.length > 0) {
293
+ console.log(`Installing local devDeps: ${devPkgs.join(" ")}`);
294
+ await execFileAsync2("npm", ["i", "-D", ...devPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 });
295
+ }
296
+ }
246
297
  async function outputReport(report, format, outFile, markdownExtras) {
247
298
  const content = format === "json" ? renderJson(report) : renderMarkdown({ ...report, ...markdownExtras || {} });
248
299
  if (outFile) {
@@ -254,6 +305,51 @@ async function outputReport(report, format, outFile, markdownExtras) {
254
305
  console.log(content);
255
306
  }
256
307
  }
308
+ function isMarkdownReportFile(filePath) {
309
+ const ext = path2.extname(filePath).toLowerCase();
310
+ return ext === ".md" || ext === ".markdown";
311
+ }
312
+ function parseMarkdownPackagesTable(lines, startIndex) {
313
+ const rows = [];
314
+ if (!lines[startIndex] || !lines[startIndex].trim().startsWith("|")) return rows;
315
+ let i = startIndex + 2;
316
+ while (i < lines.length && lines[i].trim().startsWith("|")) {
317
+ const cols = lines[i].split("|").map((c) => c.trim()).filter((_, idx, arr) => !(idx === 0 || idx === arr.length - 1));
318
+ const [name = "", version = "", resolved_path = ""] = cols;
319
+ if (name) rows.push({ name, version, resolved_path });
320
+ i++;
321
+ }
322
+ return rows;
323
+ }
324
+ function parseMarkdownReport(md) {
325
+ const lines = md.split(/\r?\n/);
326
+ const findSection = (title) => lines.findIndex((l) => l.trim().toLowerCase() === `## ${title}`.toLowerCase());
327
+ const parseSection = (idx) => {
328
+ if (idx < 0) return [];
329
+ let i = idx + 1;
330
+ while (i < lines.length && !lines[i].trim().startsWith("|")) i++;
331
+ return parseMarkdownPackagesTable(lines, i);
332
+ };
333
+ const global_packages = parseSection(findSection("Global Packages"));
334
+ const local_dependencies = parseSection(findSection("Local Dependencies"));
335
+ const local_dev_dependencies = parseSection(findSection("Local Dev Dependencies"));
336
+ const report = {
337
+ report_version: "1.0",
338
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
339
+ tool_version: "unknown",
340
+ global_packages,
341
+ local_dependencies,
342
+ local_dev_dependencies
343
+ };
344
+ return report;
345
+ }
346
+ async function loadReportFromFile(reportPath) {
347
+ const raw = await readFile2(reportPath, "utf8");
348
+ if (isMarkdownReportFile(reportPath) || raw.startsWith("# GEX Report")) {
349
+ return parseMarkdownReport(raw);
350
+ }
351
+ return JSON.parse(raw);
352
+ }
257
353
  async function run(argv = process.argv) {
258
354
  const program = new Command().name("gex").description("GEX: Dependency auditing and documentation for Node.js (local and global).").version(await getToolVersion());
259
355
  program.addHelpText("beforeAll", `
@@ -306,6 +402,30 @@ ${ASCII_BANNER}`);
306
402
  });
307
403
  await outputReport(report, outputFormat, finalOutFile, markdownExtras);
308
404
  });
405
+ const readCmd = program.command("read").description(
406
+ "Read a previously generated report (JSON or Markdown) and either print package names or install them"
407
+ ).argument("[report]", "Path to report file (JSON or Markdown)", "gex-report.json").option("-r, --report <path>", "Path to report file (JSON or Markdown)").option("-p, --print", "Print package names/versions from the report (default)", false).option("-i, --install", "Install packages from the report", false);
408
+ readCmd.action(async (reportArg, opts) => {
409
+ const chosen = opts.report || reportArg || "gex-report.json";
410
+ const reportPath = path2.resolve(process.cwd(), chosen);
411
+ try {
412
+ const parsed = await loadReportFromFile(reportPath);
413
+ const doInstall = Boolean(opts.install);
414
+ const doPrint = Boolean(opts.print) || !doInstall;
415
+ if (doPrint) {
416
+ printFromReport(parsed);
417
+ }
418
+ if (doInstall) {
419
+ await installFromReport(parsed, process.cwd());
420
+ }
421
+ } catch (err) {
422
+ const isMd = isMarkdownReportFile(reportPath);
423
+ const hint = isMd ? "Try generating a JSON report with: gex global -f json -o global.json, then: gex read global.json" : "Specify a report path with: gex read <path-to-report.json>";
424
+ console.error(`Failed to read report at ${reportPath}: ${err?.message || err}`);
425
+ console.error(hint);
426
+ process.exitCode = 1;
427
+ }
428
+ });
309
429
  await program.parseAsync(argv);
310
430
  }
311
431
  var isCjsMain = typeof __require !== "undefined" && __require.main === module;
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/npm.ts","../src/transform.ts","../src/report/json.ts","../src/report/md.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { Command } from 'commander'\n\nimport { npmLs, npmRootGlobal } from './npm.js'\nimport { buildReportFromNpmTree } from './transform.js'\nimport { renderJson } from './report/json.js'\nimport { renderMarkdown } from './report/md.js'\nimport type { OutputFormat, Report } from './types.js'\n\nfunction getPkgJsonPath(): string {\n // Resolve package.json relative to this file for both ESM and CJS bundles\n try {\n const __filename = fileURLToPath((import.meta as any).url)\n const __dirnameLocal = path.dirname(__filename)\n return path.resolve(__dirnameLocal, '..', 'package.json')\n } catch {\n const dir = typeof __dirname !== 'undefined' ? __dirname : process.cwd()\n return path.resolve(dir, '..', 'package.json')\n }\n}\n\nasync function getToolVersion(): Promise<string> {\n try {\n const pkgPath = getPkgJsonPath()\n const raw = await readFile(pkgPath, 'utf8')\n const pkg = JSON.parse(raw)\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nconst ASCII_BANNER = String.raw`\n ________ __\n / _____/ ____ _____/ |_ ____ ____ \n/ \\ ___ / _ \\ / _ \\ __\\/ __ \\ / \\\n\\ \\_\\ ( <_> | <_> ) | \\ ___/| | \\\n \\______ /\\____/ \\____/|__| \\___ >___| /\n \\/ \\/ \\/ \n GEX\n`\n\nasync function produceReport(\n ctx: 'local' | 'global',\n options: {\n outputFormat: OutputFormat\n outFile?: string\n fullTree?: boolean\n omitDev?: boolean\n cwd?: string\n },\n): Promise<{ report: Report; markdownExtras?: any }> {\n const toolVersion = await getToolVersion()\n const depth0 = !options.fullTree\n const cwd = options.cwd || process.cwd()\n\n const tree = await npmLs({\n global: ctx === 'global',\n omitDev: ctx === 'local' ? Boolean(options.omitDev) : false,\n depth0,\n cwd,\n })\n\n // Get extra metadata for markdown rendering when local\n let project_description: string | undefined\n let project_homepage: string | undefined\n let project_bugs: string | undefined\n if (ctx === 'local') {\n try {\n const pkgRaw = await readFile(path.join(cwd, 'package.json'), 'utf8')\n const pkg = JSON.parse(pkgRaw)\n project_description = pkg.description\n project_homepage = pkg.homepage\n if (typeof pkg.bugs === 'string') project_bugs = pkg.bugs\n else if (pkg.bugs && typeof pkg.bugs.url === 'string') project_bugs = pkg.bugs.url\n } catch {\n // ignore\n }\n }\n\n const globalRoot = ctx === 'global' ? await npmRootGlobal().catch(() => undefined) : undefined\n\n const report = await buildReportFromNpmTree(tree, {\n context: ctx,\n includeTree: Boolean(options.fullTree),\n omitDev: Boolean(options.omitDev),\n cwd,\n toolVersion,\n globalRoot,\n })\n\n const markdownExtras = { project_description, project_homepage, project_bugs }\n return { report, markdownExtras }\n}\n\nasync function outputReport(\n report: Report,\n format: OutputFormat,\n outFile?: string,\n markdownExtras?: any,\n) {\n const content =\n format === 'json'\n ? renderJson(report)\n : renderMarkdown({ ...report, ...(markdownExtras || {}) })\n if (outFile) {\n const outDir = path.dirname(outFile)\n await (await import('node:fs/promises')).mkdir(outDir, { recursive: true })\n await (await import('node:fs/promises')).writeFile(outFile, content, 'utf8')\n\n console.log(`Wrote report to ${outFile}`)\n } else {\n console.log(content)\n }\n}\n\nexport async function run(argv = process.argv) {\n const program = new Command()\n .name('gex')\n .description('GEX: Dependency auditing and documentation for Node.js (local and global).')\n .version(await getToolVersion())\n\n program.addHelpText('beforeAll', `\\n${ASCII_BANNER}`)\n\n const addCommonOptions = (cmd: Command, { allowOmitDev }: { allowOmitDev: boolean }) => {\n cmd\n .option(\n '-f, --output-format <format>',\n 'Output format: md or json',\n (val) => (val === 'md' ? 'md' : 'json'),\n 'json',\n )\n .option('-o, --out-file <path>', 'Write report to file')\n .option('--full-tree', 'Include full npm ls tree (omit depth=0 default)', false)\n if (allowOmitDev) {\n cmd.option('--omit-dev', 'Exclude devDependencies (local only)', false)\n }\n return cmd\n }\n\n // gex local (default command)\n const localCmd = program\n .command('local', { isDefault: true })\n .description(\"Generate a report for the current project's dependencies\")\n addCommonOptions(localCmd, { allowOmitDev: true })\n localCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n const omitDev = Boolean(opts.omitDev)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('local', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n omitDev,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n // gex global\n const globalCmd = program\n .command('global')\n .description('Generate a report of globally installed packages')\n addCommonOptions(globalCmd, { allowOmitDev: false })\n globalCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('global', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n await program.parseAsync(argv)\n}\n\nconst isCjsMain = typeof require !== 'undefined' && (require as any).main === module\nconst isEsmMain =\n typeof import.meta !== 'undefined' && (import.meta as any).url === `file://${process.argv[1]}`\nif (isCjsMain || isEsmMain) {\n run()\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport type NpmLsOptions = {\n global?: boolean\n omitDev?: boolean\n depth0?: boolean\n cwd?: string\n}\n\nexport async function npmLs(options: NpmLsOptions = {}): Promise<any> {\n const args = ['ls', '--json']\n if (options.global) args.push('--global')\n if (options.omitDev) args.push('--omit=dev')\n if (options.depth0) args.push('--depth=0')\n\n try {\n const { stdout } = await execFileAsync('npm', args, {\n cwd: options.cwd,\n maxBuffer: 10 * 1024 * 1024,\n })\n if (stdout && stdout.trim()) return JSON.parse(stdout)\n return {}\n } catch (err: any) {\n const stdout = err?.stdout\n if (typeof stdout === 'string' && stdout.trim()) {\n try {\n return JSON.parse(stdout)\n } catch {\n // fallthrough\n }\n }\n const stderr = err?.stderr\n const msg = (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm ls failed'\n throw new Error(`npm ls failed: ${msg}`)\n }\n}\n\nexport async function npmRootGlobal(): Promise<string> {\n try {\n const { stdout } = await execFileAsync('npm', ['root', '-g'])\n return stdout.trim()\n } catch (err: any) {\n const stderr = err?.stderr\n const msg =\n (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm root -g failed'\n throw new Error(`npm root -g failed: ${msg}`)\n }\n}\n","import path from 'node:path'\nimport { readFile } from 'node:fs/promises'\n\nimport type { PackageInfo, Report } from './types.js'\n\nexport type NormalizeOptions = {\n context: 'local' | 'global'\n includeTree?: boolean\n omitDev?: boolean\n cwd?: string\n toolVersion: string\n globalRoot?: string\n}\n\nfunction toPkgArray(obj: Record<string, any> | undefined | null): { name: string; node: any }[] {\n if (!obj) return []\n return Object.keys(obj)\n .map((name) => ({ name, node: obj[name] }))\n .filter((p) => p && p.node)\n}\n\nexport async function buildReportFromNpmTree(tree: any, opts: NormalizeOptions): Promise<Report> {\n const timestamp = new Date().toISOString()\n const report: Report = {\n report_version: '1.0',\n timestamp,\n tool_version: opts.toolVersion,\n global_packages: [],\n local_dependencies: [],\n local_dev_dependencies: [],\n }\n\n if (opts.context === 'local') {\n let pkgMeta: any = null\n try {\n const pkgJsonPath = path.join(opts.cwd || process.cwd(), 'package.json')\n const raw = await readFile(pkgJsonPath, 'utf8')\n pkgMeta = JSON.parse(raw)\n } catch {\n // ignore; project metadata optional\n }\n if (pkgMeta?.name) report.project_name = pkgMeta.name\n if (pkgMeta?.version) report.project_version = pkgMeta.version\n\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n const devKeys = new Set(Object.keys((pkgMeta?.devDependencies as Record<string, string>) || {}))\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath =\n (node && node.path) || path.join(opts.cwd || process.cwd(), 'node_modules', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n if (devKeys.has(name)) {\n // Only categorize as dev if present in the tree; with --omit-dev they won't appear\n report.local_dev_dependencies.push(pkg)\n } else {\n report.local_dependencies.push(pkg)\n }\n }\n\n // sort\n report.local_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n report.local_dev_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n } else if (opts.context === 'global') {\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath = (node && node.path) || path.join(opts.globalRoot || '', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n report.global_packages.push(pkg)\n }\n\n report.global_packages.sort((a, b) => a.name.localeCompare(b.name))\n }\n\n if (opts.includeTree) {\n report.tree = tree\n }\n\n return report\n}\n","import type { Report } from '../types.js'\n\nexport function renderJson(report: Report): string {\n // Ensure stable ordering (defensive; arrays already sorted)\n const r: Report = {\n ...report,\n global_packages: [...report.global_packages].sort((a, b) => a.name.localeCompare(b.name)),\n local_dependencies: [...report.local_dependencies].sort((a, b) => a.name.localeCompare(b.name)),\n local_dev_dependencies: [...report.local_dev_dependencies].sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n }\n return JSON.stringify(r, null, 2)\n}\n","import type { Report } from '../types.js'\n\nfunction table(headers: string[], rows: string[][]): string {\n const header = `| ${headers.join(' | ')} |`\n const sep = `| ${headers.map(() => '---').join(' | ')} |`\n const body = rows.map((r) => `| ${r.join(' | ')} |`).join('\\n')\n return [header, sep, body].filter(Boolean).join('\\n')\n}\n\nexport function renderMarkdown(\n report: Report & {\n project_description?: string\n project_homepage?: string\n project_bugs?: string\n },\n): string {\n const lines: string[] = []\n lines.push('# GEX Report')\n lines.push('')\n\n if (report.project_name || report.project_version) {\n lines.push('## Project Metadata')\n if (report.project_name) lines.push(`- Name: ${report.project_name}`)\n if (report.project_version) lines.push(`- Version: ${report.project_version}`)\n if ((report as any).project_description)\n lines.push(`- Description: ${(report as any).project_description}`)\n if ((report as any).project_homepage)\n lines.push(`- Homepage: ${(report as any).project_homepage}`)\n if ((report as any).project_bugs) lines.push(`- Bugs: ${(report as any).project_bugs}`)\n lines.push('')\n }\n\n if (report.global_packages.length > 0) {\n lines.push('## Global Packages')\n const rows = report.global_packages.map((p) => [p.name, p.version || '', p.resolved_path || ''])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dependencies.length > 0) {\n lines.push('## Local Dependencies')\n const rows = report.local_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dev_dependencies.length > 0) {\n lines.push('## Local Dev Dependencies')\n const rows = report.local_dev_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n lines.push('---')\n lines.push('_Generated by GEX_')\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":["readFile","path","path","readFile"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/npm.ts","../src/transform.ts","../src/report/json.ts","../src/report/md.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nimport { Command } from 'commander'\n\nimport { npmLs, npmRootGlobal } from './npm.js'\nimport { buildReportFromNpmTree } from './transform.js'\nimport { renderJson } from './report/json.js'\nimport { renderMarkdown } from './report/md.js'\nimport type { OutputFormat, Report } from './types.js'\n\nfunction getPkgJsonPath(): string {\n // Resolve package.json relative to this file for both ESM and CJS bundles\n try {\n const __filename = fileURLToPath((import.meta as any).url)\n const __dirnameLocal = path.dirname(__filename)\n return path.resolve(__dirnameLocal, '..', 'package.json')\n } catch {\n const dir = typeof __dirname !== 'undefined' ? __dirname : process.cwd()\n return path.resolve(dir, '..', 'package.json')\n }\n}\n\nasync function getToolVersion(): Promise<string> {\n try {\n const pkgPath = getPkgJsonPath()\n const raw = await readFile(pkgPath, 'utf8')\n const pkg = JSON.parse(raw)\n return pkg.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nconst execFileAsync = promisify(execFile)\n\nconst ASCII_BANNER = String.raw`\n ________ __\n / _____/ ____ _____/ |_ ____ ____ \n/ \\ ___ / _ \\ / _ \\ __\\/ __ \\ / \\\n\\ \\_\\ ( <_> | <_> ) | \\ ___/| | \\\n \\______ /\\____/ \\____/|__| \\___ >___| /\n \\/ \\/ \\/ \n GEX\n`\n\nasync function produceReport(\n ctx: 'local' | 'global',\n options: {\n outputFormat: OutputFormat\n outFile?: string\n fullTree?: boolean\n omitDev?: boolean\n cwd?: string\n },\n): Promise<{ report: Report; markdownExtras?: any }> {\n const toolVersion = await getToolVersion()\n const depth0 = !options.fullTree\n const cwd = options.cwd || process.cwd()\n\n const tree = await npmLs({\n global: ctx === 'global',\n omitDev: ctx === 'local' ? Boolean(options.omitDev) : false,\n depth0,\n cwd,\n })\n\n // Get extra metadata for markdown rendering when local\n let project_description: string | undefined\n let project_homepage: string | undefined\n let project_bugs: string | undefined\n if (ctx === 'local') {\n try {\n const pkgRaw = await readFile(path.join(cwd, 'package.json'), 'utf8')\n const pkg = JSON.parse(pkgRaw)\n project_description = pkg.description\n project_homepage = pkg.homepage\n if (typeof pkg.bugs === 'string') project_bugs = pkg.bugs\n else if (pkg.bugs && typeof pkg.bugs.url === 'string') project_bugs = pkg.bugs.url\n } catch {\n // ignore\n }\n }\n\n const globalRoot = ctx === 'global' ? await npmRootGlobal().catch(() => undefined) : undefined\n\n const report = await buildReportFromNpmTree(tree, {\n context: ctx,\n includeTree: Boolean(options.fullTree),\n omitDev: Boolean(options.omitDev),\n cwd,\n toolVersion,\n globalRoot,\n })\n\n const markdownExtras = { project_description, project_homepage, project_bugs }\n return { report, markdownExtras }\n}\n\nfunction printFromReport(report: Report) {\n const lines: string[] = []\n if (report.global_packages.length > 0) {\n lines.push('Global Packages:')\n for (const p of report.global_packages) {\n lines.push(`- ${p.name}@${p.version}`)\n }\n }\n if (report.local_dependencies.length > 0) {\n if (lines.length) lines.push('')\n lines.push('Local Dependencies:')\n for (const p of report.local_dependencies) {\n lines.push(`- ${p.name}@${p.version}`)\n }\n }\n if (report.local_dev_dependencies.length > 0) {\n if (lines.length) lines.push('')\n lines.push('Local Dev Dependencies:')\n for (const p of report.local_dev_dependencies) {\n lines.push(`- ${p.name}@${p.version}`)\n }\n }\n if (lines.length === 0) {\n lines.push('(no packages found in report)')\n }\n console.log(lines.join('\\n'))\n}\n\nasync function installFromReport(report: Report, cwd: string) {\n const globalPkgs = report.global_packages.map((p) => `${p.name}@${p.version}`).filter(Boolean)\n const localPkgs = report.local_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean)\n const devPkgs = report.local_dev_dependencies.map((p) => `${p.name}@${p.version}`).filter(Boolean)\n\n if (globalPkgs.length === 0 && localPkgs.length === 0 && devPkgs.length === 0) {\n console.log('No packages to install from report.')\n return\n }\n\n if (globalPkgs.length > 0) {\n console.log(`Installing global: ${globalPkgs.join(' ')}`)\n await execFileAsync('npm', ['i', '-g', ...globalPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 })\n }\n if (localPkgs.length > 0) {\n console.log(`Installing local deps: ${localPkgs.join(' ')}`)\n await execFileAsync('npm', ['i', ...localPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 })\n }\n if (devPkgs.length > 0) {\n console.log(`Installing local devDeps: ${devPkgs.join(' ')}`)\n await execFileAsync('npm', ['i', '-D', ...devPkgs], { cwd, maxBuffer: 10 * 1024 * 1024 })\n }\n}\n\nasync function outputReport(\n report: Report,\n format: OutputFormat,\n outFile?: string,\n markdownExtras?: any,\n) {\n const content =\n format === 'json'\n ? renderJson(report)\n : renderMarkdown({ ...report, ...(markdownExtras || {}) })\n if (outFile) {\n const outDir = path.dirname(outFile)\n await (await import('node:fs/promises')).mkdir(outDir, { recursive: true })\n await (await import('node:fs/promises')).writeFile(outFile, content, 'utf8')\n\n console.log(`Wrote report to ${outFile}`)\n } else {\n console.log(content)\n }\n}\n\nfunction isMarkdownReportFile(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase()\n return ext === '.md' || ext === '.markdown'\n}\n\nfunction parseMarkdownPackagesTable(lines: string[], startIndex: number) {\n // startIndex points to the header line beginning with '|'\n const rows: { name: string; version: string; resolved_path: string }[] = []\n if (!lines[startIndex] || !lines[startIndex].trim().startsWith('|')) return rows\n // Skip header and separator\n let i = startIndex + 2\n while (i < lines.length && lines[i].trim().startsWith('|')) {\n const cols = lines[i]\n .split('|')\n .map((c) => c.trim())\n .filter((_, idx, arr) => !(idx === 0 || idx === arr.length - 1))\n const [name = '', version = '', resolved_path = ''] = cols\n if (name) rows.push({ name, version, resolved_path })\n i++\n }\n return rows\n}\n\nfunction parseMarkdownReport(md: string): Report {\n const lines = md.split(/\\r?\\n/)\n const findSection = (title: string) =>\n lines.findIndex((l) => l.trim().toLowerCase() === `## ${title}`.toLowerCase())\n const parseSection = (idx: number) => {\n if (idx < 0) return [] as { name: string; version: string; resolved_path: string }[]\n // Find the first table row after header\n let i = idx + 1\n while (i < lines.length && !lines[i].trim().startsWith('|')) i++\n return parseMarkdownPackagesTable(lines, i)\n }\n\n const global_packages = parseSection(findSection('Global Packages'))\n const local_dependencies = parseSection(findSection('Local Dependencies'))\n const local_dev_dependencies = parseSection(findSection('Local Dev Dependencies'))\n\n const report: Report = {\n report_version: '1.0',\n timestamp: new Date().toISOString(),\n tool_version: 'unknown',\n global_packages,\n local_dependencies,\n local_dev_dependencies,\n }\n return report\n}\n\nasync function loadReportFromFile(reportPath: string): Promise<Report> {\n const raw = await readFile(reportPath, 'utf8')\n if (isMarkdownReportFile(reportPath) || raw.startsWith('# GEX Report')) {\n return parseMarkdownReport(raw)\n }\n // assume JSON\n return JSON.parse(raw) as Report\n}\nexport async function run(argv = process.argv) {\n const program = new Command()\n .name('gex')\n .description('GEX: Dependency auditing and documentation for Node.js (local and global).')\n .version(await getToolVersion())\n\n program.addHelpText('beforeAll', `\\n${ASCII_BANNER}`)\n\n const addCommonOptions = (cmd: Command, { allowOmitDev }: { allowOmitDev: boolean }) => {\n cmd\n .option(\n '-f, --output-format <format>',\n 'Output format: md or json',\n (val) => (val === 'md' ? 'md' : 'json'),\n 'json',\n )\n .option('-o, --out-file <path>', 'Write report to file')\n .option('--full-tree', 'Include full npm ls tree (omit depth=0 default)', false)\n if (allowOmitDev) {\n cmd.option('--omit-dev', 'Exclude devDependencies (local only)', false)\n }\n return cmd\n }\n\n // gex local (default command)\n const localCmd = program\n .command('local', { isDefault: true })\n .description(\"Generate a report for the current project's dependencies\")\n addCommonOptions(localCmd, { allowOmitDev: true })\n localCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n const omitDev = Boolean(opts.omitDev)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('local', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n omitDev,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n // gex global\n const globalCmd = program\n .command('global')\n .description('Generate a report of globally installed packages')\n addCommonOptions(globalCmd, { allowOmitDev: false })\n globalCmd.action(async (opts) => {\n const outputFormat = (opts.outputFormat ?? 'json') as OutputFormat\n const outFile = opts.outFile as string | undefined\n const fullTree = Boolean(opts.fullTree)\n\n let finalOutFile = outFile\n if (!outFile && opts.outputFormat && typeof opts.outputFormat === 'string') {\n finalOutFile = `gex-report.${outputFormat}`\n }\n\n const { report, markdownExtras } = await produceReport('global', {\n outputFormat,\n outFile: finalOutFile,\n fullTree,\n })\n await outputReport(report, outputFormat, finalOutFile, markdownExtras)\n })\n\n // gex read (consume a previous JSON report)\n const readCmd = program\n .command('read')\n .description(\n 'Read a previously generated report (JSON or Markdown) and either print package names or install them',\n )\n .argument('[report]', 'Path to report file (JSON or Markdown)', 'gex-report.json')\n .option('-r, --report <path>', 'Path to report file (JSON or Markdown)')\n .option('-p, --print', 'Print package names/versions from the report (default)', false)\n .option('-i, --install', 'Install packages from the report', false)\n readCmd.action(async (reportArg: string | undefined, opts: any) => {\n const chosen = (opts.report as string | undefined) || reportArg || 'gex-report.json'\n const reportPath = path.resolve(process.cwd(), chosen)\n try {\n const parsed = await loadReportFromFile(reportPath)\n\n const doInstall = Boolean(opts.install)\n const doPrint = Boolean(opts.print) || !doInstall\n\n if (doPrint) {\n printFromReport(parsed)\n }\n if (doInstall) {\n await installFromReport(parsed, process.cwd())\n }\n } catch (err: any) {\n const isMd = isMarkdownReportFile(reportPath)\n const hint = isMd\n ? 'Try generating a JSON report with: gex global -f json -o global.json, then: gex read global.json'\n : 'Specify a report path with: gex read <path-to-report.json>'\n console.error(`Failed to read report at ${reportPath}: ${err?.message || err}`)\n console.error(hint)\n process.exitCode = 1\n }\n })\n\n await program.parseAsync(argv)\n}\n\nconst isCjsMain = typeof require !== 'undefined' && (require as any).main === module\nconst isEsmMain =\n typeof import.meta !== 'undefined' && (import.meta as any).url === `file://${process.argv[1]}`\nif (isCjsMain || isEsmMain) {\n run()\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport type NpmLsOptions = {\n global?: boolean\n omitDev?: boolean\n depth0?: boolean\n cwd?: string\n}\n\nexport async function npmLs(options: NpmLsOptions = {}): Promise<any> {\n const args = ['ls', '--json']\n if (options.global) args.push('--global')\n if (options.omitDev) args.push('--omit=dev')\n if (options.depth0) args.push('--depth=0')\n\n try {\n const { stdout } = await execFileAsync('npm', args, {\n cwd: options.cwd,\n maxBuffer: 10 * 1024 * 1024,\n })\n if (stdout && stdout.trim()) return JSON.parse(stdout)\n return {}\n } catch (err: any) {\n const stdout = err?.stdout\n if (typeof stdout === 'string' && stdout.trim()) {\n try {\n return JSON.parse(stdout)\n } catch {\n // fallthrough\n }\n }\n const stderr = err?.stderr\n const msg = (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm ls failed'\n throw new Error(`npm ls failed: ${msg}`)\n }\n}\n\nexport async function npmRootGlobal(): Promise<string> {\n try {\n const { stdout } = await execFileAsync('npm', ['root', '-g'])\n return stdout.trim()\n } catch (err: any) {\n const stderr = err?.stderr\n const msg =\n (typeof stderr === 'string' && stderr.trim()) || err?.message || 'npm root -g failed'\n throw new Error(`npm root -g failed: ${msg}`)\n }\n}\n","import path from 'node:path'\nimport { readFile } from 'node:fs/promises'\n\nimport type { PackageInfo, Report } from './types.js'\n\nexport type NormalizeOptions = {\n context: 'local' | 'global'\n includeTree?: boolean\n omitDev?: boolean\n cwd?: string\n toolVersion: string\n globalRoot?: string\n}\n\nfunction toPkgArray(obj: Record<string, any> | undefined | null): { name: string; node: any }[] {\n if (!obj) return []\n return Object.keys(obj)\n .map((name) => ({ name, node: obj[name] }))\n .filter((p) => p && p.node)\n}\n\nexport async function buildReportFromNpmTree(tree: any, opts: NormalizeOptions): Promise<Report> {\n const timestamp = new Date().toISOString()\n const report: Report = {\n report_version: '1.0',\n timestamp,\n tool_version: opts.toolVersion,\n global_packages: [],\n local_dependencies: [],\n local_dev_dependencies: [],\n }\n\n if (opts.context === 'local') {\n let pkgMeta: any = null\n try {\n const pkgJsonPath = path.join(opts.cwd || process.cwd(), 'package.json')\n const raw = await readFile(pkgJsonPath, 'utf8')\n pkgMeta = JSON.parse(raw)\n } catch {\n // ignore; project metadata optional\n }\n if (pkgMeta?.name) report.project_name = pkgMeta.name\n if (pkgMeta?.version) report.project_version = pkgMeta.version\n\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n const devKeys = new Set(Object.keys((pkgMeta?.devDependencies as Record<string, string>) || {}))\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath =\n (node && node.path) || path.join(opts.cwd || process.cwd(), 'node_modules', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n if (devKeys.has(name)) {\n // Only categorize as dev if present in the tree; with --omit-dev they won't appear\n report.local_dev_dependencies.push(pkg)\n } else {\n report.local_dependencies.push(pkg)\n }\n }\n\n // sort\n report.local_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n report.local_dev_dependencies.sort((a, b) => a.name.localeCompare(b.name))\n } else if (opts.context === 'global') {\n const depsObj = tree?.dependencies as Record<string, any> | undefined\n const items = toPkgArray(depsObj)\n\n for (const { name, node } of items) {\n const version = (node && node.version) || ''\n const resolvedPath = (node && node.path) || path.join(opts.globalRoot || '', name)\n const pkg: PackageInfo = { name, version, resolved_path: resolvedPath }\n report.global_packages.push(pkg)\n }\n\n report.global_packages.sort((a, b) => a.name.localeCompare(b.name))\n }\n\n if (opts.includeTree) {\n report.tree = tree\n }\n\n return report\n}\n","import type { Report } from '../types.js'\n\nexport function renderJson(report: Report): string {\n // Ensure stable ordering (defensive; arrays already sorted)\n const r: Report = {\n ...report,\n global_packages: [...report.global_packages].sort((a, b) => a.name.localeCompare(b.name)),\n local_dependencies: [...report.local_dependencies].sort((a, b) => a.name.localeCompare(b.name)),\n local_dev_dependencies: [...report.local_dev_dependencies].sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n }\n return JSON.stringify(r, null, 2)\n}\n","import type { Report } from '../types.js'\n\nfunction table(headers: string[], rows: string[][]): string {\n const header = `| ${headers.join(' | ')} |`\n const sep = `| ${headers.map(() => '---').join(' | ')} |`\n const body = rows.map((r) => `| ${r.join(' | ')} |`).join('\\n')\n return [header, sep, body].filter(Boolean).join('\\n')\n}\n\nexport function renderMarkdown(\n report: Report & {\n project_description?: string\n project_homepage?: string\n project_bugs?: string\n },\n): string {\n const lines: string[] = []\n lines.push('# GEX Report')\n lines.push('')\n\n if (report.project_name || report.project_version) {\n lines.push('## Project Metadata')\n if (report.project_name) lines.push(`- Name: ${report.project_name}`)\n if (report.project_version) lines.push(`- Version: ${report.project_version}`)\n if ((report as any).project_description)\n lines.push(`- Description: ${(report as any).project_description}`)\n if ((report as any).project_homepage)\n lines.push(`- Homepage: ${(report as any).project_homepage}`)\n if ((report as any).project_bugs) lines.push(`- Bugs: ${(report as any).project_bugs}`)\n lines.push('')\n }\n\n if (report.global_packages.length > 0) {\n lines.push('## Global Packages')\n const rows = report.global_packages.map((p) => [p.name, p.version || '', p.resolved_path || ''])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dependencies.length > 0) {\n lines.push('## Local Dependencies')\n const rows = report.local_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n if (report.local_dev_dependencies.length > 0) {\n lines.push('## Local Dev Dependencies')\n const rows = report.local_dev_dependencies.map((p) => [\n p.name,\n p.version || '',\n p.resolved_path || '',\n ])\n lines.push(table(['Name', 'Version', 'Path'], rows))\n lines.push('')\n }\n\n lines.push('---')\n lines.push('_Generated by GEX_')\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":["readFile","path","execFile","promisify","path","readFile","execFileAsync","promisify","execFile"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yabasha/gex",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "description": "A CLI tool for auditing and documenting your Node.js package environment, generating comprehensive reports of global and local dependencies.",
6
6
  "type": "module",