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
This commit is contained in:
115
src/from_schema.ts
Normal file
115
src/from_schema.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
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 || {});
|
||||
}
|
||||
Reference in New Issue
Block a user