UNPKG

@lunora/cli

Version:

The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands

117 lines (114 loc) 3.94 kB
import { mkdtempSync, rmSync, existsSync, readdirSync, statSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, relative } from 'node:path'; import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs'; import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-v4hHpQd0.mjs'; import { defaultSpawner } from '../packem_shared/createRecordingSpawner-WuSn20kb.mjs'; const walk = (root) => { const entries = []; const recurse = (directory) => { for (const name of readdirSync(directory)) { const full = join(directory, name); const info = statSync(full); if (info.isDirectory()) { recurse(full); } else if (info.isFile()) { entries.push({ path: relative(root, full), sizeBytes: info.size }); } } }; recurse(root); return entries; }; const formatBytes = (bytes) => { if (bytes < 1024) { return `${String(bytes)} B`; } if (bytes < 1024 * 1024) { return `${(bytes / 1024).toFixed(1)} KiB`; } return `${(bytes / (1024 * 1024)).toFixed(2)} MiB`; }; const buildReport = (outdir) => { const all = walk(outdir); const sorted = all.toSorted((a, b) => b.sizeBytes - a.sizeBytes); const totalBytes = all.reduce((sum, entry) => sum + entry.sizeBytes, 0); const generatedFiles = all.filter((entry) => entry.path.includes("_generated")); return { generatedFiles, outdir, topModules: sorted.slice(0, 10), totalBytes, totalFiles: all.length }; }; const renderText = (report, logger) => { logger.info(`outdir: ${report.outdir}`); logger.info(`total: ${String(report.totalFiles)} files, ${formatBytes(report.totalBytes)}`); if (report.topModules.length > 0) { logger.info(""); logger.info("top modules by size:"); for (const entry of report.topModules) { logger.info(` ${formatBytes(entry.sizeBytes).padStart(10, " ")} ${entry.path}`); } } if (report.generatedFiles.length > 0) { logger.info(""); logger.info(`_generated/ files: ${String(report.generatedFiles.length)}`); for (const entry of report.generatedFiles) { logger.info(` ${formatBytes(entry.sizeBytes).padStart(10, " ")} ${entry.path}`); } } }; const runAnalyzeCommand = async (options) => { const cwd = options.cwd ?? process.cwd(); const { logger } = options; let outdir; let descriptor; let temporary = false; if (options.inspectOnly) { outdir = options.inspectOnly; } else { outdir = mkdtempSync(join(tmpdir(), "lunora-analyze-")); temporary = true; const exec = execArgsFor(detectPackageManager(cwd), "wrangler", ["deploy", "--dry-run", "--outdir", outdir]); descriptor = { args: exec.args, command: exec.command, cwd }; logger.info(`analyze: building via ${descriptor.command} ${descriptor.args.join(" ")}`); const spawner = options.spawner ?? defaultSpawner; const spawned = await spawner(descriptor); if (spawned.code !== 0) { logger.error(`analyze: wrangler dry-run failed (exit ${String(spawned.code)})`); rmSync(outdir, { force: true, recursive: true }); return { code: spawned.code, descriptor, report: void 0 }; } } try { if (!existsSync(outdir)) { logger.error(`analyze: outdir not found at ${outdir}`); return { code: 1, descriptor, report: void 0 }; } const report = buildReport(outdir); if (options.json) { process.stdout.write(`${JSON.stringify(report, void 0, 2)} `); } else { renderText(report, logger); } return { code: 0, descriptor, report }; } finally { if (temporary && existsSync(outdir)) { try { rmSync(outdir, { force: true, recursive: true }); } catch { } } } }; const execute = defineHandler( ({ cwd, logger, options }) => runAnalyzeCommand({ cwd, json: options.json === true, logger }) ); export { execute, runAnalyzeCommand };