chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { rmSync } from "node:fs";
|
||||
import { t } from "../i18n.mjs";
|
||||
import { emit } from "../output.mjs";
|
||||
import { withSpinner } from "../spinner.mjs";
|
||||
import {
|
||||
getRuntimeNodeModules,
|
||||
hasModule,
|
||||
isBetterSqliteBinaryValid,
|
||||
ensureBetterSqliteRuntime,
|
||||
} from "../runtime/nativeDeps.mjs";
|
||||
|
||||
async function confirm(msg) {
|
||||
const readline = await import("node:readline");
|
||||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||||
const answer = await new Promise((r) => rl.question(`${msg} [y/N] `, r));
|
||||
rl.close();
|
||||
return /^y(es)?$/i.test(answer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared repair action used by both `omniroute runtime repair` and the
|
||||
* top-level `omniroute repair` alias. Reinstalls better-sqlite3 into the
|
||||
* user-writable runtime directory via the existing engine — no hand-rolled
|
||||
* npm-rebuild spawn. Exits with code 1 on failure.
|
||||
*/
|
||||
async function runRepairAction(opts, cmd) {
|
||||
const globalOpts = cmd.optsWithGlobals();
|
||||
await withSpinner(
|
||||
"Repairing native deps",
|
||||
async () => ensureBetterSqliteRuntime({ silent: true, force: opts.force }),
|
||||
globalOpts
|
||||
);
|
||||
const ok = hasModule("better-sqlite3") && isBetterSqliteBinaryValid();
|
||||
if (ok) {
|
||||
process.stdout.write("✓ better-sqlite3 repaired OK\n");
|
||||
} else {
|
||||
process.stderr.write("✗ Repair failed — check npm availability\n");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerRuntime(program) {
|
||||
const runtime = program
|
||||
.command("runtime")
|
||||
.description(t("runtime.description") || "Manage native runtime dependencies");
|
||||
|
||||
runtime
|
||||
.command("check")
|
||||
.description("Check status of native deps in runtime directory")
|
||||
.action(async (opts, cmd) => {
|
||||
const globalOpts = cmd.optsWithGlobals();
|
||||
const status = {
|
||||
runtimeDir: getRuntimeNodeModules(),
|
||||
betterSqlite3: {
|
||||
installed: hasModule("better-sqlite3"),
|
||||
valid: isBetterSqliteBinaryValid(),
|
||||
},
|
||||
};
|
||||
emit(status, globalOpts);
|
||||
});
|
||||
|
||||
runtime
|
||||
.command("repair")
|
||||
.description("Reinstall native deps in runtime directory")
|
||||
.option("--force", "Force reinstall even if valid")
|
||||
.action(runRepairAction);
|
||||
|
||||
// Top-level discoverability alias: `omniroute repair` invokes the SAME action
|
||||
// as `omniroute runtime repair` (no duplicated logic). Surfaced in the
|
||||
// native-error / startup hints so users with a broken better-sqlite3 binding
|
||||
// have a single self-heal command that works without a C++ toolchain.
|
||||
program
|
||||
.command("repair")
|
||||
.description("Repair native deps (alias for `runtime repair`)")
|
||||
.option("--force", "Force reinstall even if valid")
|
||||
.action(runRepairAction);
|
||||
|
||||
runtime
|
||||
.command("clean")
|
||||
.description("Remove runtime directory (frees disk space)")
|
||||
.option("--yes", "Skip confirmation")
|
||||
.action(async (opts) => {
|
||||
if (!opts.yes) {
|
||||
const ok = await confirm(`Remove ${getRuntimeNodeModules()}?`);
|
||||
if (!ok) {
|
||||
process.stdout.write("Cancelled.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
rmSync(getRuntimeNodeModules(), { recursive: true, force: true });
|
||||
process.stdout.write("Cleaned runtime directory.\n");
|
||||
} catch (e) {
|
||||
process.stderr.write(`Failed: ${e instanceof Error ? e.message : String(e)}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user