@matatbread/typia
Version:
Superfast runtime validators with only one line
229 lines (228 loc) • 9.02 kB
TypeScript
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[];
}