Files
pikasTech-unidesk/scripts/src/platform-infra-sub2api-ops/index.ts
T
2026-07-14 11:10:29 +02:00

76 lines
4.0 KiB
TypeScript

import type { UniDeskConfig } from "../config";
import type { RenderedCliResult } from "../output";
import { defaultSub2ApiTargetId } from "../platform-infra/config";
import { projectSub2ApiOps } from "./projection";
import { querySub2ApiOps } from "./query";
import { renderSub2ApiOps } from "./render";
import type { Sub2ApiOpsOptions } from "./types";
export async function runSub2ApiOpsCommand(config: UniDeskConfig, args: string[]): Promise<Record<string, unknown> | RenderedCliResult> {
const options = parseSub2ApiOpsOptions(args);
const raw = await querySub2ApiOps(config, options);
const projected = projectSub2ApiOps(raw, options);
return options.json ? projected : renderSub2ApiOps(projected);
}
export function parseSub2ApiOpsOptions(args: string[]): Sub2ApiOpsOptions {
const [actionRaw, ...rest] = args;
if (actionRaw !== "diagnosis" && actionRaw !== "channels") {
throw new Error("sub2api ops usage: diagnosis|channels [--target <id>] [--platform <name>] [--json]");
}
let targetId = defaultSub2ApiTargetId();
let json = false;
let platform: string | null = null;
let group: string | null = null;
let diagnosisId: string | null = null;
let timeRange = "1h" as Sub2ApiOpsOptions["timeRange"];
let channel: string | null = null;
let model: string | null = null;
let window = "7d" as Sub2ApiOpsOptions["window"];
let pageToken: string | null = null;
let recordId: string | null = null;
for (let index = 0; index < rest.length; index += 1) {
const arg = rest[index]!;
const readValue = (name: string): string => {
const value = rest[index + 1];
if (value === undefined || value.startsWith("--")) throw new Error(`${name} requires a value`);
index += 1;
return value.trim();
};
if (arg === "--json") json = true;
else if (arg === "--target") targetId = readValue(arg);
else if (arg === "--platform") platform = readValue(arg);
else if (arg === "--group") group = readValue(arg);
else if (arg === "--id") diagnosisId = readValue(arg);
else if (arg === "--time-range") timeRange = parseTimeRange(readValue(arg));
else if (arg === "--channel") channel = readValue(arg);
else if (arg === "--model") model = readValue(arg);
else if (arg === "--window") window = parseWindow(readValue(arg));
else if (arg === "--page-token") pageToken = parseRecordId(readValue(arg), arg);
else if (arg === "--record") recordId = parseRecordId(readValue(arg), arg);
else throw new Error(`unknown sub2api ops option: ${arg}`);
}
if (actionRaw === "diagnosis" && (channel !== null || model !== null || window !== "7d" || pageToken !== null || recordId !== null)) throw new Error("ops diagnosis does not accept channel history options");
if (actionRaw === "channels" && (group !== null || diagnosisId !== null || timeRange !== "1h")) throw new Error("ops channels does not accept --group, --id, or --time-range");
if (actionRaw === "channels" && model !== null && channel === null) throw new Error("--model requires --channel");
if (actionRaw === "channels" && (pageToken !== null || recordId !== null) && channel === null) throw new Error("--page-token and --record require --channel");
if (pageToken !== null && recordId !== null) throw new Error("use only one of --page-token or --record");
return { action: actionRaw, targetId, json, platform, group, diagnosisId, timeRange, channel, model, window, pageToken, recordId };
}
function parseTimeRange(value: string): Sub2ApiOpsOptions["timeRange"] {
if (value === "5m" || value === "30m" || value === "1h" || value === "6h" || value === "24h") return value;
throw new Error("--time-range must be one of 5m, 30m, 1h, 6h, 24h");
}
function parseWindow(value: string): Sub2ApiOpsOptions["window"] {
if (value === "7d" || value === "15d" || value === "30d") return value;
throw new Error("--window must be one of 7d, 15d, 30d");
}
function parseRecordId(value: string, option: string): string {
if (/^[1-9][0-9]*$/u.test(value)) return value;
throw new Error(`${option} must be a positive native history record ID`);
}