UNPKG

@matatbread/typia

Version:

Superfast runtime validators with only one line

229 lines (228 loc) 9.02 kB
import ts from "typescript"; import { MetadataCollection } from "../factories/MetadataCollection"; import { Metadata } from "../schemas/metadata/Metadata"; import { MetadataArray } from "../schemas/metadata/MetadataArray"; import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType"; import { ITypiaContext } from "../transformers/ITypiaContext"; import { CheckerProgrammer } from "./CheckerProgrammer"; import { FunctionProgrammer } from "./helpers/FunctionProgrammer"; import { IExpressionEntry } from "./helpers/IExpressionEntry"; export declare namespace FeatureProgrammer { interface IConfig<Output extends ts.ConciseBody = ts.ConciseBody> { types: IConfig.ITypes; /** Prefix name of internal functions for specific types. */ prefix: string; /** Whether to archive access path or not. */ path: boolean; /** Whether to trace exception or not. */ trace: boolean; addition?: undefined | ((collection: MetadataCollection) => ts.Statement[]); /** Initializer of metadata. */ initializer: (props: { context: ITypiaContext; functor: FunctionProgrammer; type: ts.Type; }) => { collection: MetadataCollection; metadata: Metadata; }; /** Decoder, station of every types. */ decoder: (props: { metadata: Metadata; input: ts.Expression; explore: IExplore; }) => Output; /** Object configurator. */ objector: IConfig.IObjector<Output>; /** Generator of functions for object types. */ generator: IConfig.IGenerator; } namespace IConfig { interface ITypes { input: (type: ts.Type, name?: undefined | string) => ts.TypeNode; output: (type: ts.Type, name?: undefined | string) => ts.TypeNode; } interface IObjector<Output extends ts.ConciseBody = ts.ConciseBody> { /** Type checker when union object type comes. */ checker: (props: { metadata: Metadata; input: ts.Expression; explore: IExplore; }) => ts.Expression; /** Decoder, function call expression generator of specific typed objects. */ decoder: (props: { input: ts.Expression; object: MetadataObjectType; explore: IExplore; }) => ts.Expression; /** Joiner of expressions from properties. */ joiner(props: { entries: IExpressionEntry<Output>[]; input?: ts.Expression; object?: MetadataObjectType; }): ts.ConciseBody; /** * Union type specificator. * * Expression of an algorithm specifying object type and calling the * `decoder` function of the specified object type. */ unionizer: (props: { objects: MetadataObjectType[]; input: ts.Expression; explore: IExplore; }) => ts.Expression; /** * Handler of union type specification failure. * * @param props Properties of failure * @returns Statement of failure */ failure(props: { input: ts.Expression; expected: string; explore?: undefined | IExplore; }): ts.Statement; /** * Transformer of type checking expression by discrimination. * * When an object type has been specified by a discrimination without full * iteration, the `unionizer` will decode the object instance after the * last type checking. * * In such circumtance, you can transform the last type checking function. * * @deprecated * @param exp Current expression about type checking * @returns Transformed expression */ is?: undefined | ((exp: ts.Expression) => ts.Expression); /** * Transformer of non-undefined type checking by discrimination. * * When specifying an union type of objects, `typia` tries to find * discrimination way just by checking only one property type. If * succeeded to find the discrimination way, `typia` will check the target * property type and in the checking, non-undefined type checking would be * done. * * In such process, you can transform the non-undefined type checking. * * @deprecated * @param exp * @returns Transformed expression */ required?: undefined | ((exp: ts.Expression) => ts.Expression); /** * Condition wrapper when unable to specify any object type. * * When failed to specify an object type through discrimination, full * iteration type checking would be happened. In such circumstance, you * can wrap the condition with additional function. * * @param props Properties of condition * @returns The wrapper expression */ full?: undefined | ((props: { condition: ts.Expression; input: ts.Expression; expected: string; explore: IExplore; }) => ts.Expression); /** Return type. */ type?: undefined | ts.TypeNode; } interface IGenerator { objects?: undefined | ((collection: MetadataCollection) => ts.VariableStatement[]); unions?: undefined | ((collection: MetadataCollection) => ts.VariableStatement[]); arrays: (collection: MetadataCollection) => ts.VariableStatement[]; tuples: (collection: MetadataCollection) => ts.VariableStatement[]; } } interface IExplore { tracable: boolean; source: "top" | "function"; from: "top" | "array" | "object"; postfix: string; start?: undefined | number; } type Decoder<T, Output extends ts.ConciseBody = ts.ConciseBody> = (props: { input: ts.Expression; definition: T; explore: IExplore; }) => Output; interface IComposed { body: ts.ConciseBody; parameters: ts.ParameterDeclaration[]; functions: Record<string, ts.VariableStatement>; statements: ts.Statement[]; response: ts.TypeNode; } interface IDecomposed { functions: Record<string, ts.VariableStatement>; statements: ts.Statement[]; arrow: ts.ArrowFunction; } const compose: (props: { context: ITypiaContext; config: IConfig; functor: FunctionProgrammer; type: ts.Type; name: string | undefined; }) => IComposed; const writeDecomposed: (props: { modulo: ts.LeftHandSideExpression; functor: FunctionProgrammer; result: IDecomposed; returnWrapper?: (arrow: ts.ArrowFunction) => ts.Expression; }) => ts.CallExpression; const write: (props: { context: ITypiaContext; config: IConfig; functor: FunctionProgrammer; type: ts.Type; name?: string | undefined; }) => ts.ArrowFunction; const write_object_functions: (props: { config: IConfig; context: ITypiaContext; collection: MetadataCollection; }) => ts.VariableStatement[]; const write_union_functions: (props: { config: IConfig; collection: MetadataCollection; }) => ts.VariableStatement[]; const decode_array: (props: { config: Pick<IConfig, "trace" | "path" | "decoder" | "prefix">; functor: FunctionProgrammer; combiner: (next: { input: ts.Expression; arrow: ts.ArrowFunction; }) => ts.Expression; array: MetadataArray; input: ts.Expression; explore: IExplore; }) => ts.Expression; const decode_object: (props: { config: Pick<IConfig, "trace" | "path" | "prefix">; functor: FunctionProgrammer; object: MetadataObjectType; input: ts.Expression; explore: IExplore; }) => ts.CallExpression; const index: (props: { start: number | null; postfix: string; rand: string; }) => string; const argumentsArray: (props: { config: Pick<IConfig, "path" | "trace">; input: ts.Expression; explore: FeatureProgrammer.IExplore; }) => ts.Expression[]; const parameterDeclarations: (props: { config: Pick<CheckerProgrammer.IConfig, "path" | "trace">; type: ts.TypeNode; input: ts.Identifier; }) => ts.ParameterDeclaration[]; }