@yabasha/gex 0.1.0 → 0.3.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/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) {
@@ -298,25 +349,7 @@ ${ASCII_BANNER}`);
298
349
  }
299
350
  return cmd;
300
351
  };
301
- addCommonOptions(program, { allowOmitDev: true });
302
- program.action(async (opts) => {
303
- const outputFormat = opts.outputFormat ?? "json";
304
- const outFile = opts.outFile;
305
- const fullTree = Boolean(opts.fullTree);
306
- const omitDev = Boolean(opts.omitDev);
307
- let finalOutFile = outFile;
308
- if (!outFile && opts.outputFormat && typeof opts.outputFormat === "string") {
309
- finalOutFile = `gex-report.${outputFormat}`;
310
- }
311
- const { report, markdownExtras } = await produceReport("local", {
312
- outputFormat,
313
- outFile: finalOutFile,
314
- fullTree,
315
- omitDev
316
- });
317
- await outputReport(report, outputFormat, finalOutFile, markdownExtras);
318
- });
319
- const localCmd = program.command("local").description("Generate a report for the current project's dependencies");
352
+ const localCmd = program.command("local", { isDefault: true }).description("Generate a report for the current project's dependencies");
320
353
  addCommonOptions(localCmd, { allowOmitDev: true });
321
354
  localCmd.action(async (opts) => {
322
355
  const outputFormat = opts.outputFormat ?? "json";
@@ -352,6 +385,22 @@ ${ASCII_BANNER}`);
352
385
  });
353
386
  await outputReport(report, outputFormat, finalOutFile, markdownExtras);
354
387
  });
388
+ const readCmd = program.command("read").description(
389
+ "Read a previously generated JSON report and either print package names or install them"
390
+ ).option("-r, --report <path>", "Path to report JSON", "gex-report.json").option("-p, --print", "Print package names/versions from the report (default)", false).option("-i, --install", "Install packages from the report", false);
391
+ readCmd.action(async (opts) => {
392
+ const reportPath = import_node_path2.default.resolve(process.cwd(), opts.report);
393
+ const raw = await (0, import_promises2.readFile)(reportPath, "utf8");
394
+ const parsed = JSON.parse(raw);
395
+ const doInstall = Boolean(opts.install);
396
+ const doPrint = Boolean(opts.print) || !doInstall;
397
+ if (doPrint) {
398
+ printFromReport(parsed);
399
+ }
400
+ if (doInstall) {
401
+ await installFromReport(parsed, process.cwd());
402
+ }
403
+ });
355
404
  await program.parseAsync(argv);
356
405
  }
357
406
  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 \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 // Root behaves like `local` by default\n addCommonOptions(program as unknown as Command, { allowOmitDev: true })\n program.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 local\n const localCmd = program\n .command('local')\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\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 JSON report and either print package names or install them',\n )\n .option('-r, --report <path>', 'Path to report JSON', 'gex-report.json')\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 (opts) => {\n const reportPath = path.resolve(process.cwd(), opts.report as string)\n const raw = await readFile(reportPath, 'utf8')\n const parsed = JSON.parse(raw) as Report\n\n // default behavior: print if --install not provided\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 })\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) {
@@ -270,25 +321,7 @@ ${ASCII_BANNER}`);
270
321
  }
271
322
  return cmd;
272
323
  };
273
- addCommonOptions(program, { allowOmitDev: true });
274
- program.action(async (opts) => {
275
- const outputFormat = opts.outputFormat ?? "json";
276
- const outFile = opts.outFile;
277
- const fullTree = Boolean(opts.fullTree);
278
- const omitDev = Boolean(opts.omitDev);
279
- let finalOutFile = outFile;
280
- if (!outFile && opts.outputFormat && typeof opts.outputFormat === "string") {
281
- finalOutFile = `gex-report.${outputFormat}`;
282
- }
283
- const { report, markdownExtras } = await produceReport("local", {
284
- outputFormat,
285
- outFile: finalOutFile,
286
- fullTree,
287
- omitDev
288
- });
289
- await outputReport(report, outputFormat, finalOutFile, markdownExtras);
290
- });
291
- const localCmd = program.command("local").description("Generate a report for the current project's dependencies");
324
+ const localCmd = program.command("local", { isDefault: true }).description("Generate a report for the current project's dependencies");
292
325
  addCommonOptions(localCmd, { allowOmitDev: true });
293
326
  localCmd.action(async (opts) => {
294
327
  const outputFormat = opts.outputFormat ?? "json";
@@ -324,6 +357,22 @@ ${ASCII_BANNER}`);
324
357
  });
325
358
  await outputReport(report, outputFormat, finalOutFile, markdownExtras);
326
359
  });
360
+ const readCmd = program.command("read").description(
361
+ "Read a previously generated JSON report and either print package names or install them"
362
+ ).option("-r, --report <path>", "Path to report JSON", "gex-report.json").option("-p, --print", "Print package names/versions from the report (default)", false).option("-i, --install", "Install packages from the report", false);
363
+ readCmd.action(async (opts) => {
364
+ const reportPath = path2.resolve(process.cwd(), opts.report);
365
+ const raw = await readFile2(reportPath, "utf8");
366
+ const parsed = JSON.parse(raw);
367
+ const doInstall = Boolean(opts.install);
368
+ const doPrint = Boolean(opts.print) || !doInstall;
369
+ if (doPrint) {
370
+ printFromReport(parsed);
371
+ }
372
+ if (doInstall) {
373
+ await installFromReport(parsed, process.cwd());
374
+ }
375
+ });
327
376
  await program.parseAsync(argv);
328
377
  }
329
378
  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 \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 // Root behaves like `local` by default\n addCommonOptions(program as unknown as Command, { allowOmitDev: true })\n program.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 local\n const localCmd = program\n .command('local')\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\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 JSON report and either print package names or install them',\n )\n .option('-r, --report <path>', 'Path to report JSON', 'gex-report.json')\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 (opts) => {\n const reportPath = path.resolve(process.cwd(), opts.report as string)\n const raw = await readFile(reportPath, 'utf8')\n const parsed = JSON.parse(raw) as Report\n\n // default behavior: print if --install not provided\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 })\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.1.0",
3
+ "version": "0.3.0",
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",
@@ -45,6 +45,7 @@
45
45
  "author": "",
46
46
  "license": "MIT",
47
47
  "devDependencies": {
48
+ "@changesets/changelog-github": "^0.5.1",
48
49
  "@changesets/cli": "^2.27.8",
49
50
  "@types/node": "^22.5.4",
50
51
  "@typescript-eslint/eslint-plugin": "^8.6.0",