Files
openclaw/packages/gateway-protocol/src/protocol-validator.ts
Peter Steinberger 3b84a55d99 refactor(protocol): pre-publish cheat-window cleanup and vintage tracking (#111041)
* fix(codex): drain dynamic-tool handlers before side-thread cleanup

* refactor(protocol): rename question ids to questionId and flatten answer maps

* refactor(protocol): slim worker stack and unify session-catalog shapes

* refactor(protocol): delete dead public surface and polish packaging

* feat(protocol): track release-train vintage on gateway methods and schemas

* fix(apps): align question surfaces merged from main with reshaped protocol

* test(health): shape secret fixtures to scanner-safe token names

* test(health): use scanner-safe token fixtures

* fix(apps): align question surfaces merged from main with reshaped protocol

* fix(ci): prove reshaped protocol in shallow checks

* fix(ui): align sidebar question fixtures with protocol

* fix(apps): read flat Swift question answers

* fix(apps): align question surfaces merged from main with reshaped protocol

* fix(apps): refresh native question inventory

* fix(apps): align macOS snapshot fixtures with protocol

* fix(ui): align narration question fixture with protocol
2026-07-19 04:07:15 -07:00

66 lines
2.2 KiB
TypeScript

import type { Static, TSchema } from "typebox";
import { Compile, type Validator as TypeBoxValidator } from "typebox/compile";
import type { ValidationError } from "./validation-errors.js";
/** Runtime validator shape shared by gateway clients and server handlers. */
export type ProtocolValidator<T = unknown> = ((data: unknown) => data is T) & {
errors: ValidationError[] | null; // Ajv-style last validation errors.
/** Original schema used by the validator, exposed for diagnostics/tests. */
schema: unknown;
};
// Defer TypeBox compilation because the protocol entrypoint is common on startup paths.
export function lazyCompile<const Schema extends TSchema>(
schema: Schema,
precheck?: (data: unknown) => ValidationError | undefined,
): ProtocolValidator<Static<Schema>>;
// Keep compact hand-authored public types where schema-derived declarations are intentionally avoided.
export function lazyCompile<T>(
schema: TSchema,
precheck?: (data: unknown) => ValidationError | undefined,
): ProtocolValidator<T>;
/* @__NO_SIDE_EFFECTS__ */
export function lazyCompile<T = unknown>(
schema: TSchema,
precheck?: (data: unknown) => ValidationError | undefined,
): ProtocolValidator<T> {
let compiled: TypeBoxValidator | undefined;
let errors: ValidationError[] | null = null;
const getCompiled = () => {
compiled ??= Compile(schema as never);
return compiled;
};
const validate = ((data: unknown): data is T => {
const precheckError = precheck?.(data);
if (precheckError) {
errors = [precheckError];
return false;
}
const current = getCompiled();
const valid = current.Check(data);
errors = valid ? null : ([...current.Errors(data)] as ValidationError[]);
return valid;
}) as ProtocolValidator<T>;
Object.defineProperties(validate, {
errors: {
configurable: true,
enumerable: true,
get: () => errors,
set: (nextErrors: ValidationError[] | null | undefined) => {
// Preserve Ajv-compatible mutability for callers/tests that clear errors.
errors = nextErrors ?? null;
},
},
schema: {
configurable: true,
enumerable: true,
get: () => schema,
},
});
return validate;
}