repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
pi/agent/skillz/nushell/scripts/check.mjs
Raw#!/usr/bin/env node
import { spawnSync } from "node:child_process";
import { statSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
// IDE diagnostics may contain source literals. Only check reviewed, non-secret inputs.
export function checkFile(file, run = spawnSync) {
const report = { file: resolve(file), version: null, ok: false, diagnostics: [] };
try {
if (!statSync(report.file).isFile()) throw new Error("Target must be a regular file");
const options = {
cwd: dirname(report.file), encoding: "utf8", shell: false,
timeout: 30_000, maxBuffer: 1_048_576, windowsHide: true,
};
function invoke(args) {
const process = run("nu", ["--no-config-file", ...args], options);
if (process.error || process.status !== 0 || process.signal) {
// Do not echo stderr or spawn errors: either can contain sensitive data.
throw new Error("Nu failed, was unavailable, or exceeded time/output limits");
}
if (process.stderr?.trim()) throw new Error("Nu emitted stderr; validation is incomplete");
return process.stdout;
}
const version = invoke(["--version"]).trim();
if (!/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/.test(version)) {
throw new Error("Unrecognized Nu version output");
}
report.version = version;
const output = invoke(["--ide-check", "100", report.file]);
for (const line of output.split(/\r?\n/).filter((line) => line.trim())) {
let entry;
try { entry = JSON.parse(line); }
catch { throw new Error("Malformed Nu diagnostic JSON"); }
if (entry?.type === "hint") continue;
if (entry?.type !== "diagnostic" || typeof entry.message !== "string"
|| !["Error", "Warning", "Information", "Hint"].includes(entry.severity)) {
throw new Error("Unsupported Nu diagnostic output");
}
report.diagnostics.push(entry);
}
report.ok = !report.diagnostics.some((entry) => entry.severity === "Error");
} catch (error) {
report.error = error.code ? "Cannot inspect target file" : error.message;
}
return report;
}
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
const args = process.argv.slice(2);
const report = args.length === 1
? checkFile(args[0])
: { ok: false, error: "Usage: node check.mjs <file.nu>" };
console.log(JSON.stringify(report, null, 2));
process.exitCode = args.length !== 1 ? 2 : report.ok ? 0 : 1;
}