UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

255 lines (253 loc) • 12.9 kB
const require_load = require('../../services/resolution/load.cjs'); const require_theme = require('../../utils/theme.cjs'); const require_status = require('../../services/status.cjs'); const require_exit_codes = require('../exit-codes.cjs'); const require_config = require('../render/config.cjs'); const require_logs = require('../render/logs.cjs'); const require_processes = require('../render/processes.cjs'); let node_fs = require("node:fs"); let node_path = require("node:path"); let node_fs_promises = require("node:fs/promises"); //#region src/cli/commands/inspect.ts const inspectRenderers = { config: async (result, _ctx) => { if (!result.config) { console.error(require_load.MISSING_CONFIG_MESSAGE); process.exit(1); } require_config.printConfigView(result.config); process.stdout.write(`${JSON.stringify(result.config, null, 2)}\n`); }, status: async (result, _ctx) => { console.log(); if (require_exit_codes.exitCodeFor(result) === 1) { console.error(`[CLI] ${result.error || "Unknown error"}`); process.exit(1); } console.log(require_theme.colors.cyan(require_theme.frames.top(52))); console.log(` ${require_theme.icons.app} ${require_theme.gradients.cyber("STATUS")}`); console.log(require_theme.colors.cyan(require_theme.frames.bottom(52))); console.log(); if (result.extends) console.log(` ${require_theme.colors.dim("Extends:")} ${result.extends}`); if (result.account) console.log(` ${require_theme.colors.dim("Account:")} ${result.account}`); if (result.domain) console.log(` ${require_theme.colors.dim("Domain:")} ${result.domain}`); console.log(); console.log(` ${require_theme.colors.dim("Packages:")}`); for (const pkg of result.packages) { const hasUpdate = pkg.installed && pkg.latest && require_status.compareSemver(pkg.installed, pkg.latest) < 0; const versionStr = hasUpdate ? `${pkg.installed} → ${pkg.latest}` : pkg.installed || "not installed"; const label = hasUpdate ? require_theme.colors.yellow(versionStr) : require_theme.colors.dim(versionStr); console.log(` ${require_theme.colors.dim(`${pkg.name}`)} ${label}`); } console.log(); if (result.lastSync) { const ago = require_logs.formatTimeAgo(result.lastSync); console.log(` ${require_theme.colors.dim("Last sync:")} ${ago}`); } else console.log(` ${require_theme.colors.dim("Last sync:")} never`); const envLabel = result.envFile === "found" ? require_theme.colors.green("found") : result.envFile === "example-only" ? require_theme.colors.yellow("missing (only .env.example found)") : require_theme.colors.error("missing"); console.log(` ${require_theme.colors.dim(".env:")} ${envLabel}`); if (result.parentReachable !== void 0) { const parentLabel = result.parentReachable ? require_theme.colors.green("reachable") : require_theme.colors.error("unreachable"); console.log(` ${require_theme.colors.dim("Parent:")} ${parentLabel}`); } if (result.packages.some((p) => p.installed && p.latest && require_status.compareSemver(p.installed, p.latest) < 0)) { console.log(); console.log(require_theme.colors.dim(` Run ${require_theme.colors.cyan("bos upgrade")} to update packages and sync template files.`)); } console.log(); }, ps: async (result, _ctx) => { require_processes.renderPs(result); }, logs: async (result, ctx) => { const input = ctx.input; const logsResult = result; const opts = input; for (const line of logsResult.lines) console.log(line); if (logsResult.lines.length === 0) console.log(require_theme.colors.dim(` No matching log lines in ${logsResult.logFile}.`)); if (opts.follow) { if (logsResult.logFile === "unknown" || !(0, node_fs.existsSync)(logsResult.logFile)) console.log(require_theme.colors.dim(" No log file to follow — nothing was found on disk.")); else { const filter = opts.service; let byteOffset = 0; for (const line of logsResult.lines) byteOffset += Buffer.byteLength(line, "utf8") + 1; const followMatch = (line) => { if (!filter) return true; const source = /\] \[([^\]]+)\] \[(?:OUT|ERR)\] /.exec(line)?.[1]; return source === filter || source === `plugin:${filter}`; }; const watcher = (0, node_fs.watch)(logsResult.logFile, (event) => { if (event !== "change") return; (0, node_fs_promises.readFile)(logsResult.logFile, "utf8").then((text) => { const newLines = text.slice(byteOffset).split("\n").filter((line) => line.length > 0 && followMatch(line)); byteOffset = Buffer.byteLength(text, "utf8"); for (const line of newLines) console.log(line); }).catch(() => { watcher.close(); }); }); console.log(require_theme.colors.dim(" Following — Ctrl+C to stop.")); process.on("SIGINT", () => { watcher.close(); process.exit(0); }); } } }, kill: async (result, ctx) => { const input = ctx.input; const killResult = result; console.log(); if (killResult.status === "error") { console.error(`[CLI] ${killResult.error || "Unknown error"}`); process.exit(1); } if (killResult.killed.length > 0) { console.log(require_theme.colors.green(`${require_theme.icons.ok} Sent ${killResult.killed.length} kill signal(s)`)); for (const k of killResult.killed) console.log(` ${require_theme.colors.dim("pid")} ${k.pid} ${require_theme.colors.dim(k.configDir)}`); } if (killResult.skipped.length > 0) { console.log(require_theme.colors.yellow(`${require_theme.icons.err} ${killResult.skipped.length} skipped`)); for (const s of killResult.skipped) console.log(` ${require_theme.colors.dim("pid")} ${s.pid} ${require_theme.colors.dim(s.reason)}`); } if (killResult.killed.length === 0 && killResult.skipped.length === 0) { const opts = input; if (opts.all) console.log(require_theme.colors.dim(" No tracked processes to kill.")); else { const configPath = require_load.findConfigPath(); const dir = opts.configDir ?? (configPath ? (0, node_path.resolve)((0, node_path.dirname)(configPath)) : process.cwd()); console.log(require_theme.colors.dim(` No tracked processes for ${dir}`)); console.log(require_theme.colors.dim(` Use ${require_theme.colors.cyan("--all")} to kill across all directories.`)); } } console.log(); }, typesGen: async (result, _ctx) => { console.log(); if (require_exit_codes.exitCodeFor(result) === 1) { console.error(`[CLI] ${result.error || "Unknown error"}`); process.exit(1); } console.log(require_theme.colors.green(`${require_theme.icons.ok} Types generated`)); if (result.generated.length > 0) { console.log(` ${require_theme.colors.dim("Written:")}`); for (const f of result.generated) console.log(` ${require_theme.colors.dim(f)}`); } if (result.fetched.length > 0 || result.skipped.length > 0 || result.failed.length > 0) { console.log(` ${require_theme.colors.dim("Contract sources:")}`); for (const entry of result.fetched) { const space = entry.indexOf(" "); const key = space !== -1 ? entry.slice(0, space) : entry; const rest = space !== -1 ? entry.slice(space + 1) : ""; const restSpace = rest.indexOf(" "); const detail = restSpace !== -1 ? rest.slice(restSpace + 1) : ""; console.log(` ${key} ${require_theme.colors.cyan("remote")}${detail ? ` ${require_theme.colors.dim(detail)}` : ""}`); } for (const entry of result.skipped) { const space = entry.indexOf(" "); const key = space !== -1 ? entry.slice(0, space) : entry; const rest = space !== -1 ? entry.slice(space + 1) : ""; if (rest === "no URL resolved") { console.log(` ${key} ${require_theme.colors.dim("no URL resolved")}`); continue; } const restSpace = rest.indexOf(" "); const detail = restSpace !== -1 ? rest.slice(restSpace + 1) : ""; console.log(` ${key} ${require_theme.colors.dim("local")}${detail ? ` ${require_theme.colors.dim(detail)}` : ""}`); } } if (result.failed.length > 0) { console.log(` ${require_theme.colors.yellow("Failed:")}`); for (const f of result.failed) { const colon = f.indexOf(": "); if (colon !== -1) console.log(` ${require_theme.colors.error(f.slice(0, colon))}${require_theme.colors.dim(f.slice(colon))}`); else console.log(` ${require_theme.colors.error(f)}`); } } console.log(); }, typecheck: async (result, _ctx) => { console.log(); if (require_exit_codes.exitCodeFor(result) === 1) { console.error(`[CLI] ${result.error || "Unknown error"}`); process.exit(1); } const failed = result.results.filter((r) => !r.passed); const passed = result.results.filter((r) => r.passed); console.log(require_theme.colors.cyan(require_theme.frames.top(52))); console.log(` ${require_theme.icons.app} ${require_theme.gradients.cyber("TYPECHECK")}`); console.log(require_theme.colors.cyan(require_theme.frames.bottom(52))); console.log(); for (const r of result.results) { const icon = r.passed ? require_theme.colors.green("✓") : require_theme.colors.error("✗"); console.log(` ${icon} ${r.workspace}`); } if (result.skipped.length > 0) console.log(` ${require_theme.colors.dim(`Skipped: ${result.skipped.join(", ")}`)}`); console.log(); if (failed.length > 0) { console.log(` ${require_theme.colors.error(`${failed.length} failed`)}`); for (const f of failed) if (f.error) console.log(` ${require_theme.colors.dim(f.error)}`); console.log(); process.exit(1); } console.log(` ${require_theme.colors.green(`${passed.length} passed`)}`); console.log(); }, mfCheck: async (result, _ctx) => { console.log(); console.log(` ${require_theme.colors.dim("Host")} ${result.hostReachable ? require_theme.colors.green("OK ") : require_theme.colors.error("FAIL")} ${result.hostVersion ?? "unreachable"}${result.hostReason ? ` (${result.hostReason})` : ""}`); for (const r of result.remotes) { const tag = r.ok ? require_theme.colors.green("OK ") : require_theme.colors.error("FAIL"); console.log(` ${require_theme.colors.dim(r.role.padEnd(10))} ${tag} ${r.url} pluginVersion=${r.pluginVersion ?? "?"}${r.reason ? ` ↳ ${r.reason}` : ""}`); } if (result.ui) for (const slot of result.ui.slots) { const tag = slot.ok ? require_theme.colors.green("OK ") : require_theme.colors.error("FAIL"); console.log(` ${require_theme.colors.dim(`ui:${slot.slot}`.padEnd(10))} ${tag} ${slot.url}${slot.reason ? ` ↳ ${slot.reason}` : ""}`); } if (result.platform) { for (const v of result.platform.violations) console.log(` ${require_theme.colors.dim("platform".padEnd(10))} ${require_theme.colors.error("FAIL")} ${v.message}`); if (result.platform.ok) console.log(` ${require_theme.colors.dim("platform".padEnd(10))} ${require_theme.colors.green("OK ")} release contract satisfied`); } console.log(); if (result.status !== "ok") { console.log(require_theme.colors.error(" mf-compat: ✗ federation manifests NOT compatible — redeploy affected plugin(s) so pluginVersion and shared versions match host")); console.log(); process.exit(1); } console.log(require_theme.colors.green(" mf-compat: ✓ all federation manifests compatible")); console.log(); }, platformManifest: async (result, _ctx) => { console.log(); if (result.status === "fail") { console.error(`[CLI] ${result.error || "platform manifest resolution failed"}`); if (result.drift) { console.log(); console.log(require_theme.colors.error(` parent platform is ${result.drift.published} (published), you pinned ${result.drift.pinned} — run \`bos upgrade\` to realign`)); } console.log(); process.exit(1); } if (result.status === "absent") { console.log(require_theme.colors.yellow(` ${require_theme.icons.err} No platform release manifest resolves${result.error ? ` — ${result.error}` : ""}.`)); console.log(require_theme.colors.dim(" Children fall back to the parent-repo tarball walk (ADR 0034 pt 7).")); console.log(); return; } console.log(` ${require_theme.colors.dim("Platform")} ${require_theme.colors.green(result.version ?? "?")} ${require_theme.colors.dim(`(${result.source}${result.fromCache ? ", cached" : ""})`)}`); if (result.compat) { for (const v of result.compat.violations) console.log(` ${require_theme.colors.error("FAIL")} ${v.message}`); console.log(); if (!result.compat.ok) { console.log(require_theme.colors.error(" platform-compat: ✗ the workspace does not satisfy this release's compat contract — bump the framework or clear the pin")); console.log(); process.exit(1); } console.log(require_theme.colors.green(" platform-compat: ✓ workspace satisfies the release contract")); } console.log(); } }; //#endregion exports.inspectRenderers = inspectRenderers; //# sourceMappingURL=inspect.cjs.map