mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-05 00:52:56 +00:00
refactor: share ACP metadata readers
This commit is contained in:
24
src/acp/meta.test.ts
Normal file
24
src/acp/meta.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readBool, readNonNegativeInteger, readNumber, readString } from "./meta.js";
|
||||
|
||||
describe("ACP metadata readers", () => {
|
||||
it("returns the first normalized string value", () => {
|
||||
expect(readString({ old: " ", current: " session-1 " }, ["old", "current"])).toBe("session-1");
|
||||
});
|
||||
|
||||
it("preserves false boolean values", () => {
|
||||
expect(readBool({ enabled: false, fallback: true }, ["enabled", "fallback"])).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts finite numbers and rejects non-numeric values", () => {
|
||||
expect(readNumber({ first: "1", second: 0 }, ["first", "second"])).toBe(0);
|
||||
expect(readNumber({ first: Number.POSITIVE_INFINITY }, ["first"])).toBeUndefined();
|
||||
});
|
||||
|
||||
it("accepts zero as a non-negative integer", () => {
|
||||
expect(readNonNegativeInteger({ count: 0, fallback: 2 }, ["count", "fallback"])).toBe(0);
|
||||
expect(
|
||||
readNonNegativeInteger({ count: -1, fallback: 2.5 }, ["count", "fallback"]),
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -1,65 +1,50 @@
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
|
||||
function readMetaValue<T>(
|
||||
meta: Record<string, unknown> | null | undefined,
|
||||
keys: string[],
|
||||
normalize: (value: unknown) => T | undefined,
|
||||
): T | undefined {
|
||||
if (!meta) {
|
||||
return undefined;
|
||||
}
|
||||
for (const key of keys) {
|
||||
const normalized = normalize(meta[key]);
|
||||
if (normalized !== undefined) {
|
||||
return normalized;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function readString(
|
||||
meta: Record<string, unknown> | null | undefined,
|
||||
keys: string[],
|
||||
): string | undefined {
|
||||
if (!meta) {
|
||||
return undefined;
|
||||
}
|
||||
for (const key of keys) {
|
||||
const value = normalizeOptionalString(meta[key]);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
return readMetaValue(meta, keys, normalizeOptionalString);
|
||||
}
|
||||
|
||||
export function readBool(
|
||||
meta: Record<string, unknown> | null | undefined,
|
||||
keys: string[],
|
||||
): boolean | undefined {
|
||||
if (!meta) {
|
||||
return undefined;
|
||||
}
|
||||
for (const key of keys) {
|
||||
const value = meta[key];
|
||||
if (typeof value === "boolean") {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
return readMetaValue(meta, keys, (value) => (typeof value === "boolean" ? value : undefined));
|
||||
}
|
||||
|
||||
export function readNumber(
|
||||
meta: Record<string, unknown> | null | undefined,
|
||||
keys: string[],
|
||||
): number | undefined {
|
||||
if (!meta) {
|
||||
return undefined;
|
||||
}
|
||||
for (const key of keys) {
|
||||
const value = meta[key];
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
return readMetaValue(meta, keys, (value) =>
|
||||
typeof value === "number" && Number.isFinite(value) ? value : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
export function readNonNegativeInteger(
|
||||
meta: Record<string, unknown> | null | undefined,
|
||||
keys: string[],
|
||||
): number | undefined {
|
||||
if (!meta) {
|
||||
return undefined;
|
||||
}
|
||||
for (const key of keys) {
|
||||
const value = meta[key];
|
||||
if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
return readMetaValue(meta, keys, (value) =>
|
||||
typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user