@yabasha/gex 0.2.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) {
@@ -334,6 +385,22 @@ ${ASCII_BANNER}`);
334
385
  });
335
386
  await outputReport(report, outputFormat, finalOutFile, markdownExtras);
336
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
+ });
337
404
  await program.parseAsync(argv);
338
405
  }
339
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 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\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) {
@@ -306,6 +357,22 @@ ${ASCII_BANNER}`);
306
357
  });
307
358
  await outputReport(report, outputFormat, finalOutFile, markdownExtras);
308
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
+ });
309
376
  await program.parseAsync(argv);
310
377
  }
311
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 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\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.2.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",