feat: add Ekklesia doctor command
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { diagnoseEkklesia, doctorExitCode, formatDoctorReport } from "../diagnostics/index.js";
|
||||
|
||||
interface ModuleSdkPackageDocument {
|
||||
readonly version?: unknown;
|
||||
}
|
||||
|
||||
interface RootPackageDocument extends ModuleSdkPackageDocument {
|
||||
readonly engines?: {
|
||||
readonly node?: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
async function readJson(pathname: string): Promise<unknown> {
|
||||
return JSON.parse(await readFile(pathname, "utf8")) as unknown;
|
||||
}
|
||||
|
||||
function rootPackageDocument(value: unknown): RootPackageDocument {
|
||||
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
||||
throw new TypeError("Invalid workspace package metadata.");
|
||||
}
|
||||
return value as RootPackageDocument;
|
||||
}
|
||||
|
||||
function requiredString(value: unknown): string {
|
||||
if (typeof value !== "string" || value.length === 0) {
|
||||
throw new TypeError("Missing workspace package metadata.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function runDoctorCommand(repositoryRoot = process.cwd()): Promise<number> {
|
||||
const [rootValue, moduleSdkValue] = await Promise.all([
|
||||
readJson(path.join(repositoryRoot, "package.json")),
|
||||
readJson(path.join(repositoryRoot, "packages", "module-sdk", "package.json")),
|
||||
]);
|
||||
const rootPackage = rootPackageDocument(rootValue);
|
||||
const moduleSdkPackage = rootPackageDocument(moduleSdkValue);
|
||||
|
||||
const report = await diagnoseEkklesia({
|
||||
databaseUrl: process.env.DATABASE_URL,
|
||||
moduleDiscovery: {
|
||||
moduleSdkVersion: requiredString(moduleSdkPackage.version),
|
||||
modulesDirectory: path.join(repositoryRoot, "modules"),
|
||||
platformVersion: requiredString(rootPackage.version),
|
||||
},
|
||||
runtimeRange: requiredString(rootPackage.engines?.node),
|
||||
runtimeVersion: process.versions.node,
|
||||
});
|
||||
|
||||
console.log(formatDoctorReport(report).join("\n"));
|
||||
return doctorExitCode(report);
|
||||
}
|
||||
|
||||
function isDirectExecution(): boolean {
|
||||
const entrypoint = process.argv[1];
|
||||
return (
|
||||
entrypoint !== undefined && import.meta.url === pathToFileURL(path.resolve(entrypoint)).href
|
||||
);
|
||||
}
|
||||
|
||||
if (isDirectExecution()) {
|
||||
runDoctorCommand()
|
||||
.then((exitCode) => {
|
||||
process.exitCode = exitCode;
|
||||
})
|
||||
.catch(() => {
|
||||
console.error("Ekklesia Doctor failed before diagnostics could be composed.");
|
||||
process.exitCode = 1;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user