Files
operations/src/from_schema.ts
glm-5.1 29f0dd7af0 Initial package implementation: operations registry, call protocol, and adapters
Extracted from alkhub_ts packages/core/operations/ and packages/core/mcp/.
- Runtime-agnostic (injected fs/env deps, no Deno globals)
- Direct @logtape/logtape import instead of logger wrapper
- PendingRequestMap with pubsub-wired call protocol
- Peer-dep isolation for MCP adapter (sub-path export)
- Schema const naming convention (XSchema + X type alias)
- 68 tests passing, build + lint + test all green
2026-04-30 12:34:26 +00:00

115 lines
5.4 KiB
TypeScript

import * as Type from "@alkdev/typebox";
const IsExact = (value: unknown, expect: unknown) => value === expect;
const IsSValue = (value: unknown): value is SValue =>
Type.ValueGuard.IsString(value) || Type.ValueGuard.IsNumber(value) || Type.ValueGuard.IsBoolean(value);
const IsSEnum = (value: unknown): value is SEnum =>
Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.enum) && value.enum.every((v) => IsSValue(v));
const IsSAllOf = (value: unknown): value is SAllOf => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.allOf);
const IsSAnyOf = (value: unknown): value is SAnyOf => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.anyOf);
const IsSOneOf = (value: unknown): value is SOneOf => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.oneOf);
const IsSTuple = (value: unknown): value is STuple =>
Type.ValueGuard.IsObject(value) && IsExact(value.type, "array") && Type.ValueGuard.IsArray(value.items);
const IsSArray = (value: unknown): value is SArray =>
Type.ValueGuard.IsObject(value) && IsExact(value.type, "array") && !Type.ValueGuard.IsArray(value.items) && Type.ValueGuard.IsObject(value.items);
const IsSConst = (value: unknown): value is SConst => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsObject(value["const"]);
const IsSString = (value: unknown): value is SString => Type.ValueGuard.IsObject(value) && IsExact(value.type, "string");
const IsSRef = (value: unknown): value is SRef => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsString(value.$ref);
const IsSNumber = (value: unknown): value is SNumber => Type.ValueGuard.IsObject(value) && IsExact(value.type, "number");
const IsSInteger = (value: unknown): value is SInteger => Type.ValueGuard.IsObject(value) && IsExact(value.type, "integer");
const IsSBoolean = (value: unknown): value is SBoolean => Type.ValueGuard.IsObject(value) && IsExact(value.type, "boolean");
const IsSNull = (value: unknown): value is SNull => Type.ValueGuard.IsObject(value) && IsExact(value.type, "null");
const IsSProperties = (value: unknown): value is SProperties => Type.ValueGuard.IsObject(value);
const IsSObject = (value: unknown): value is SObject =>
Type.ValueGuard.IsObject(value) &&
IsExact(value.type, "object") &&
IsSProperties(value.properties) &&
(value.required === undefined || (Type.ValueGuard.IsArray(value.required) && value.required.every((v: unknown) => Type.ValueGuard.IsString(v))));
type SValue = string | number | boolean;
type SEnum = Readonly<{ enum: readonly SValue[] }>;
type SAllOf = Readonly<{ allOf: readonly unknown[] }>;
type SAnyOf = Readonly<{ anyOf: readonly unknown[] }>;
type SOneOf = Readonly<{ oneOf: readonly unknown[] }>;
type SProperties = Record<PropertyKey, unknown>;
type SObject = Readonly<{ type: "object"; properties: SProperties; required?: readonly string[] }>;
type STuple = Readonly<{ type: "array"; items: readonly unknown[] }>;
type SArray = Readonly<{ type: "array"; items: unknown }>;
type SConst = Readonly<{ const: SValue }>;
type SRef = Readonly<{ $ref: string }>;
type SString = Readonly<{ type: "string" }>;
type SNumber = Readonly<{ type: "number" }>;
type SInteger = Readonly<{ type: "integer" }>;
type SBoolean = Readonly<{ type: "boolean" }>;
type SNull = Readonly<{ type: "null" }>;
function FromRest<T extends readonly unknown[]>(T: T): Type.TSchema[] {
return T.map((L) => FromSchema(L)) as never;
}
function FromEnumRest<T extends readonly SValue[]>(T: T): Type.TSchema[] {
return T.map((L) => Type.Literal(L)) as never;
}
function FromAllOf<T extends SAllOf>(T: T): Type.TSchema {
return Type.IntersectEvaluated(FromRest(T.allOf), T);
}
function FromAnyOf<T extends SAnyOf>(T: T): Type.TSchema {
return Type.UnionEvaluated(FromRest(T.anyOf), T);
}
function FromOneOf<T extends SOneOf>(T: T): Type.TSchema {
return Type.UnionEvaluated(FromRest(T.oneOf), T);
}
function FromEnum<T extends SEnum>(T: T): Type.TSchema {
return Type.UnionEvaluated(FromEnumRest(T.enum));
}
function FromTuple<T extends STuple>(T: T): Type.TSchema {
return Type.Tuple(FromRest(T.items), T) as never;
}
function FromArray<T extends SArray>(T: T): Type.TSchema {
return Type.Array(FromSchema(T.items), T) as never;
}
function FromConst<T extends SConst>(T: T): Type.TSchema {
return Type.Literal(T.const, T);
}
function FromRef<T extends SRef>(T: T): Type.TSchema {
return Type.Ref(T.$ref);
}
function FromObject<T extends SObject>(T: T): Type.TSchema {
const properties = globalThis.Object.getOwnPropertyNames(T.properties).reduce(
(Acc, K) => {
return {
...Acc,
[K]: T.required && T.required.includes(K) ? FromSchema(T.properties[K]) : Type.Optional(FromSchema(T.properties[K])),
};
},
{} as Type.TProperties,
);
return Type.Object(properties, T) as never;
}
export function FromSchema<T>(T: T): Type.TSchema {
if (IsSAllOf(T)) return FromAllOf(T);
if (IsSAnyOf(T)) return FromAnyOf(T);
if (IsSOneOf(T)) return FromOneOf(T);
if (IsSEnum(T)) return FromEnum(T);
if (IsSObject(T)) return FromObject(T);
if (IsSTuple(T)) return FromTuple(T);
if (IsSArray(T)) return FromArray(T);
if (IsSConst(T)) return FromConst(T);
if (IsSRef(T)) return FromRef(T);
if (IsSString(T)) return Type.String(T);
if (IsSNumber(T)) return Type.Number(T);
if (IsSInteger(T)) return Type.Integer(T);
if (IsSBoolean(T)) return Type.Boolean(T);
if (IsSNull(T)) return Type.Null(T);
return Type.Unknown(T || {});
}