typia
Version:
Superfast runtime validators with only one line
109 lines (103 loc) • 3.6 kB
text/typescript
import ts from "typescript";
import { ExpressionFactory } from "../../factories/ExpressionFactory";
import { StatementFactory } from "../../factories/StatementFactory";
import { TypeFactory } from "../../factories/TypeFactory";
import { IProject } from "../../transformers/IProject";
import { AssertProgrammer } from "../AssertProgrammer";
import { FunctionalAssertFunctionProgrammer } from "./FunctionalAssertFunctionProgrammer";
import { FunctionalGeneralProgrammer } from "./internal/FunctionalGeneralProgrammer";
export namespace FunctionalAssertParametersProgrammer {
export const write =
(project: IProject) =>
(modulo: ts.LeftHandSideExpression) =>
(equals: boolean) =>
(
expression: ts.Expression,
declaration: ts.FunctionDeclaration,
init?: ts.Expression,
): ts.CallExpression => {
const wrapper = FunctionalAssertFunctionProgrammer.errorFactoryWrapper(
modulo,
)(declaration.parameters)(init);
const { async } = FunctionalGeneralProgrammer.getReturnType(
project.checker,
)(declaration);
const result = decompose(project)(modulo)(equals)(
declaration.parameters,
wrapper.name,
);
return ExpressionFactory.selfCall(
ts.factory.createBlock(
[
wrapper.variable,
...result.functions,
ts.factory.createReturnStatement(
ts.factory.createArrowFunction(
async
? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)]
: undefined,
undefined,
declaration.parameters,
declaration.type,
undefined,
ts.factory.createBlock(
[
...result.expressions.map(
ts.factory.createExpressionStatement,
),
ts.factory.createReturnStatement(
ts.factory.createCallExpression(
expression,
undefined,
declaration.parameters.map((p) =>
ts.factory.createIdentifier(p.name.getText()),
),
),
),
],
true,
),
),
),
],
true,
),
);
};
export const decompose =
(project: IProject) =>
(modulo: ts.LeftHandSideExpression) =>
(equals: boolean) =>
(
parameters: readonly ts.ParameterDeclaration[],
wrapper: string,
): {
functions: ts.Statement[];
expressions: ts.Expression[];
} => ({
functions: parameters.map((p, i) =>
StatementFactory.constant(
`__assert_param_${i}`,
AssertProgrammer.write(project)(modulo)(equals)(
p.type
? project.checker.getTypeFromTypeNode(p.type)
: project.checker.getTypeFromTypeNode(TypeFactory.keyword("any")),
undefined,
FunctionalAssertFunctionProgrammer.hookPath({
wrapper,
replacer: `$input.parameters[${i}]`,
}),
),
// undefined,
// [ts.factory.createIdentifier(p.name.getText())],
),
),
expressions: parameters.map((p, i) =>
ts.factory.createCallExpression(
ts.factory.createIdentifier(`__assert_param_${i}`),
undefined,
[ts.factory.createIdentifier(p.name.getText())],
),
),
});
}