refactor(cli): split tjwater cli modules
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { CliError } from "./errors.js";
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
|
||||
export function readJsonFile(path: string, label: string): unknown {
|
||||
try {
|
||||
return JSON.parse(readFileSync(path, "utf8"));
|
||||
} catch (error) {
|
||||
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
||||
throw new CliError("CLI 参数错误", "INPUT_NOT_FOUND", `${label} file not found: ${path}`, 2);
|
||||
}
|
||||
if (error instanceof SyntaxError) throw new CliError("CLI 参数错误", "INPUT_INVALID_JSON", `${label} file must be valid JSON: ${path}`, 2);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export function parseBurstFile(path: string): [string[], number[]] {
|
||||
let raw = readJsonFile(path, "burst");
|
||||
if (isRecord(raw) && "bursts" in raw) raw = raw.bursts;
|
||||
if (isRecord(raw) && "burst_ID" in raw && "burst_size" in raw && Array.isArray(raw.burst_ID) && Array.isArray(raw.burst_size)) {
|
||||
const ids = raw.burst_ID.map(String);
|
||||
const sizes = raw.burst_size.map(Number);
|
||||
if (ids.length !== sizes.length) throw new CliError("CLI 参数错误", "BURST_FILE_INVALID", "burst file burst_ID and burst_size must have the same length", 2);
|
||||
return [ids, sizes];
|
||||
}
|
||||
if (Array.isArray(raw)) {
|
||||
return [
|
||||
raw.map((item) => {
|
||||
if (!isRecord(item) || !("id" in item) || !("size" in item)) throw new CliError("CLI 参数错误", "BURST_FILE_INVALID", "burst file items must contain id and size", 2);
|
||||
return String(item.id);
|
||||
}),
|
||||
raw.map((item) => Number((item as Record<string, unknown>).size)),
|
||||
];
|
||||
}
|
||||
throw new CliError("CLI 参数错误", "BURST_FILE_INVALID", "burst file must be a JSON array or object with burst_ID/burst_size", 2);
|
||||
}
|
||||
|
||||
export function parseValveSettingFile(path: string): [string[], number[]] {
|
||||
const raw = readJsonFile(path, "valve-setting");
|
||||
if (isRecord(raw) && "valves" in raw && "valves_k" in raw && Array.isArray(raw.valves) && Array.isArray(raw.valves_k)) {
|
||||
const valves = raw.valves.map(String);
|
||||
const openings = raw.valves_k.map(Number);
|
||||
if (valves.length !== openings.length) throw new CliError("CLI 参数错误", "VALVE_SETTING_INVALID", "valves and valves_k must have the same length", 2);
|
||||
return [valves, openings];
|
||||
}
|
||||
if (Array.isArray(raw)) {
|
||||
return [
|
||||
raw.map((item) => {
|
||||
if (!isRecord(item) || !("valve" in item) || !("opening" in item)) throw new CliError("CLI 参数错误", "VALVE_SETTING_INVALID", "valve-setting items must contain valve and opening", 2);
|
||||
return String(item.valve);
|
||||
}),
|
||||
raw.map((item) => Number((item as Record<string, unknown>).opening)),
|
||||
];
|
||||
}
|
||||
throw new CliError("CLI 参数错误", "VALVE_SETTING_INVALID", "valve-setting file must be a JSON array or object with valves/valves_k", 2);
|
||||
}
|
||||
|
||||
export function assignDatasetKeys(target: Record<string, unknown>, path: string, keys: string[], label: string): void {
|
||||
const payload = readJsonFile(path, label);
|
||||
if (isRecord(payload)) {
|
||||
for (const key of keys) {
|
||||
if (key in payload) target[key] = payload[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user