exact-mirror
Version:
Mirror exact value to TypeBox/OpenAPI model
146 lines (145 loc) • 4.04 kB
TypeScript
import { Static, TModule, TSchema } from "typebox";
import { Compile, Validator } from "typebox/compile";
//#region src/index.d.ts
declare const copySchema: <T>(node: T) => T;
interface BaseSchema {
'~kind': string;
id?: string;
$id?: string;
type?: string;
$schema?: string;
const?: unknown[];
pattern?: string;
additionalItems?: boolean | AnySchema;
items?: AnySchema | AnySchema[];
required?: string[];
additionalProperties?: boolean | AnySchema;
definitions?: {
[]: AnySchema;
};
properties?: {
[]: AnySchema;
};
patternProperties?: {
[]: AnySchema;
};
dependencies?: {
[]: AnySchema | string[];
};
enum?: any[];
allOf?: AnySchema[];
anyOf?: AnySchema[];
oneOf?: AnySchema[];
not?: AnySchema;
$ref?: string;
$defs?: Record<string, AnySchema>;
}
type AnySchema = TSchema & BaseSchema;
declare const mergeObjectIntersection: (schema: AnySchema) => AnySchema;
type MaybeArray<T> = T | T[];
interface Instruction<Emit extends boolean = false> {
optionals: string[];
optionalsInArray: string[][];
parentIsOptional: boolean;
array: number;
unions: Validator<any>[][];
unionKeys: Record<string, 1>;
sanitize: MaybeArray<(v: string) => string> | undefined;
fromUnion?: boolean;
emit?: Emit;
/**
* Apply a TypeBox codec's `~codec` transform at codec leaves during the
* mirror walk, instead of only cleaning the value.
*
* @default undefined — pure clean, no transform
*/
transform?: 'decode' | 'encode';
/**
* Codec transform functions collected during codegen, referenced from the
* generated source by index as `d.codecs[i]`
*/
codecs: Function[];
/**
* TypeCompiler is required when using Union
*
* Left as opt-in to reduce bundle size
* many end-user doesn't use Union
*
* @default undefined
*/
Compile?: typeof Compile;
typeCompilerWanred?: boolean;
modules?: TModule<{}>;
definitions: Record<string, AnySchema>;
/**
* Shared cyclic codegen state: generated per-definition mirror
* functions, grouped by `$defs` object identity
*/
cyclic: CyclicContext;
/**
* `$defs` group the current cyclic definition body is generated
* against, used to resolve `Ref` nodes to function calls
*/
cyclicDefs?: CyclicGroup;
recursion: number;
/**
* @default 8
*/
recursionLimit: number;
/**
* If incorrect type is passed to Union value, should it be removed?
*
* If you check a value later, it's recommended to set this to `false`
* otherwise, set this to true
*
* @default false
*/
removeUnknownUnionType: boolean;
}
declare function deepClone<T>(source: T, weak?: WeakMap<object, any>): T;
interface CyclicGroup {
defs: Record<string, AnySchema>;
names: Record<string, string>;
}
interface CyclicContext {
groups: Map<object, CyclicGroup>;
fns: string[];
count: number;
}
interface Manifest {
source: string;
externals: {
unions: Validator<any, TSchema, unknown, unknown>[][];
codecs?: Function[];
hof?: Record<string, Function>;
};
}
declare const createMirror: <T extends TSchema, Emit extends boolean = false>(schema: T, {
Compile,
modules,
definitions,
sanitize,
recursionLimit,
removeUnknownUnionType,
emit,
decode,
encode
}?: Partial<Pick<Instruction<Emit>, "Compile" | "definitions" | "sanitize" | "modules" | "recursionLimit" | "removeUnknownUnionType" | "emit">> & {
/**
* Apply each codec's `~codec.decode` at codec leaves (parse input,
* e.g. numeric string → number) on top of the clean walk
*
* The value is assumed to have already passed `Check`
*
* @default false
*/
decode?: boolean;
/**
* Apply each codec's `~codec.encode` at codec leaves
*
* @default false
*/
encode?: boolean;
}) => Emit extends true ? Manifest : (v: Static<T>) => Static<T>;
//#endregion
export { Instruction, Manifest, copySchema, createMirror, createMirror as default, deepClone, mergeObjectIntersection };