58 lines
3.9 KiB
TypeScript
58 lines
3.9 KiB
TypeScript
import type { RenderedCliResult } from "../output";
|
|
import { isRecord, stringValue } from "./config-utils";
|
|
import { renderTable } from "./render";
|
|
import type { RuntimeOptions } from "./runtime-options";
|
|
|
|
export function renderRuntimeMutationResult(ok: boolean, options: RuntimeOptions, parsed: Record<string, unknown> | null, exitCode: number): RenderedCliResult {
|
|
const summary = parsed !== null && isRecord(parsed.summary) ? parsed.summary : {};
|
|
const items = parsed !== null && Array.isArray(parsed.items) ? parsed.items.filter(isRecord) : [];
|
|
const lines = [[
|
|
"SUB2API RUNTIME", `operation=${options.action}`, `mode=${stringValue(parsed?.mode) ?? (options.confirm ? "confirmed" : "dry-run")}`,
|
|
`ok=${ok ? "true" : "false"}`, `selected=${summary.selected ?? items.length}`, `changed=${summary.changed ?? "?"}`,
|
|
`writeSucceeded=${summary.writeSucceeded ?? "?"}`, `writeFailed=${summary.writeFailed ?? "?"}`,
|
|
`reconciled=${summary.reconciled ?? "?"}`, `mismatched=${summary.mismatched ?? "?"}`,
|
|
].join(" ")];
|
|
if (items.length > 0) {
|
|
const fields = items.map((item) => ({
|
|
item,
|
|
write: isRecord(item.write) ? item.write : {},
|
|
before: isRecord(item.before) ? item.before : {},
|
|
desired: isRecord(item.desired) ? item.desired : {},
|
|
actual: isRecord(item.actual) ? item.actual : {},
|
|
}));
|
|
if (options.kind === "priority") lines.push(renderTable([
|
|
["ACCOUNT", "ID", "CHANGE", "WRITE", "RECONCILED", "BEFORE_PRIORITY", "DESIRED_PRIORITY", "ACTUAL_PRIORITY", "FAILURE"],
|
|
...fields.map(({ item, write, before, desired, actual }) => [
|
|
stringValue(item.accountName) ?? "-", String(item.accountId ?? "-"), stringValue(item.change) ?? "-",
|
|
stringValue(write.status) ?? "-", item.reconciled === true ? "true" : item.reconciled === false ? "false" : "-",
|
|
String(before.priority ?? "-"), String(desired.priority ?? "-"), String(actual.priority ?? "-"),
|
|
stringValue(write.error) ?? stringValue(item.reconcileError) ?? "-",
|
|
]),
|
|
]));
|
|
else if (options.kind === "account-name") lines.push(renderTable([
|
|
["ACCOUNT", "ID", "CHANGE", "WRITE", "RECONCILED", "BEFORE_NAME", "DESIRED_NAME", "ACTUAL_NAME", "FAILURE"],
|
|
...fields.map(({ item, write, before, desired, actual }) => [
|
|
stringValue(item.accountName) ?? "-", String(item.accountId ?? "-"), stringValue(item.change) ?? "-",
|
|
stringValue(write.status) ?? "-", item.reconciled === true ? "true" : item.reconciled === false ? "false" : "-",
|
|
stringValue(before.name) ?? "-", stringValue(desired.name) ?? "-", stringValue(actual.name) ?? "-",
|
|
stringValue(write.error) ?? stringValue(item.reconcileError) ?? "-",
|
|
]),
|
|
]));
|
|
else lines.push(renderTable([
|
|
["ACCOUNT", "ID", "CHANGE", "WRITE", "RECONCILED", "BEFORE", "DESIRED", "ACTUAL", "BEFORE_CODES", "DESIRED_CODES", "ACTUAL_CODES", "FAILURE"],
|
|
...fields.map(({ item, write, before, desired, actual }) => {
|
|
const codes = (value: unknown): string => Array.isArray(value) ? value.join(",") || "-" : "-";
|
|
return [
|
|
stringValue(item.accountName) ?? "-", String(item.accountId ?? "-"), stringValue(item.change) ?? "-",
|
|
stringValue(write.status) ?? "-", item.reconciled === true ? "true" : item.reconciled === false ? "false" : "-",
|
|
String(before.ruleCount ?? "-"), String(desired.ruleCount ?? "-"), String(actual.ruleCount ?? "-"),
|
|
codes(before.statusCodes), codes(desired.statusCodes), codes(actual.statusCodes),
|
|
stringValue(write.error) ?? stringValue(item.reconcileError) ?? "-",
|
|
];
|
|
}),
|
|
]));
|
|
} else if (parsed !== null && typeof parsed.error === "string") lines.push(`ERROR ${parsed.error}`);
|
|
else if (parsed === null) lines.push(`ERROR runtime output unavailable remote_exit=${exitCode}`);
|
|
return { ok, command: "platform-infra sub2api codex-pool runtime", renderedText: lines.join("\n"), contentType: "text/plain", projection: parsed ?? undefined };
|
|
}
|