refactor: reuse common ops primitives

This commit is contained in:
Codex
2026-06-14 17:59:45 +00:00
parent aa90eadfb2
commit 0c9735024e
4 changed files with 53 additions and 64 deletions
+36 -2
View File
@@ -72,6 +72,18 @@ export function fingerprintValues(values: Record<string, string>, keys: string[]
return `sha256:${hash.digest("hex")}`;
}
export function sha256Hex(value: string): string {
return createHash("sha256").update(value).digest("hex");
}
export function sha256Fingerprint(value: string): string {
return `sha256:${sha256Hex(value)}`;
}
export function shortSha256Fingerprint(value: string, chars = 12): string {
return sha256Hex(value).slice(0, chars);
}
export function fingerprintEnvValues(values: Record<string, string>, keys: string[]): string {
const material = keys
.slice()
@@ -178,14 +190,14 @@ export function recordField(obj: Record<string, unknown>, key: string, path: str
export function stringField(obj: Record<string, unknown>, key: string, path: string): string {
const value = obj[key];
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${path}.${key} must be a non-empty string`);
return value;
return value.trim();
}
export function optionalStringField(obj: Record<string, unknown>, key: string, path: string): string | undefined {
const value = obj[key];
if (value === undefined || value === null) return undefined;
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${path}.${key} must be a non-empty string when set`);
return value;
return value.trim();
}
export function booleanField(obj: Record<string, unknown>, key: string, path: string): boolean {
@@ -200,6 +212,19 @@ export function numberField(obj: Record<string, unknown>, key: string, path: str
return value;
}
export function integerField(obj: Record<string, unknown>, key: string, path: string): number {
const value = obj[key];
if (!Number.isInteger(value)) throw new Error(`${path}.${key} must be an integer`);
return Number(value);
}
export function optionalIntegerField(obj: Record<string, unknown>, key: string, path: string): number | undefined {
const value = obj[key];
if (value === undefined || value === null) return undefined;
if (!Number.isInteger(value)) throw new Error(`${path}.${key} must be an integer when set`);
return Number(value);
}
export function arrayField(obj: Record<string, unknown>, key: string, path: string): Record<string, unknown>[] {
const value = obj[key];
if (!Array.isArray(value)) throw new Error(`${path}.${key} must be an array`);
@@ -212,6 +237,15 @@ export function stringListField(obj: Record<string, unknown>, key: string, path:
return value as string[];
}
export function stringArrayField(obj: Record<string, unknown>, key: string, path: string): string[] {
const value = obj[key];
if (!Array.isArray(value)) throw new Error(`${path}.${key} must be an array`);
return value.map((item, index) => {
if (typeof item !== "string" || item.trim().length === 0) throw new Error(`${path}.${key}[${index}] must be a non-empty string`);
return item.trim();
});
}
export function yamlFieldLabel(configLabel: string, path: string, key: string): string {
const prefix = path.length > 0 ? `${path}.` : "";
return `${configLabel}.${prefix}${key}`;