UNPKG

@matatbread/typia

Version:

Superfast runtime validators with only one line

105 lines (102 loc) 6.51 kB
import ts from 'typescript'; import { ExpressionFactory } from '../../factories/ExpressionFactory.mjs'; import { IdentifierFactory } from '../../factories/IdentifierFactory.mjs'; import { StatementFactory } from '../../factories/StatementFactory.mjs'; import { TypeFactory } from '../../factories/TypeFactory.mjs'; import { MetadataArray } from '../../schemas/metadata/MetadataArray.mjs'; import { MetadataArrayType } from '../../schemas/metadata/MetadataArrayType.mjs'; import { MetadataTuple } from '../../schemas/metadata/MetadataTuple.mjs'; /** @internal */ const check_union_array_like = (props) => { // ONLY ONE TYPE const targets = props.definitions.map(props.accessor.transform); if (targets.length === 1) return ts.factory.createArrowFunction(undefined, undefined, props.parameters, undefined, undefined, props.config.decoder({ input: props.accessor.array(props.input), definition: targets[0], explore: props.explore, })); const array = ts.factory.createIdentifier("array"); const top = ts.factory.createIdentifier("top"); const statements = []; const tupleList = targets.filter((t) => t instanceof MetadataTuple); const arrayList = targets.filter((t) => t instanceof MetadataArray); const predicate = (meta) => ts.factory.createAsExpression(ts.factory.createArrayLiteralExpression([ ts.factory.createArrowFunction(undefined, undefined, [ IdentifierFactory.parameter("top", meta instanceof MetadataArrayType ? TypeFactory.keyword("any") : ts.factory.createTypeReferenceNode("any[]")), ], TypeFactory.keyword("any"), undefined, props.config.checker({ input: ts.factory.createIdentifier("top"), definition: props.accessor.element(meta), explore: { ...props.explore, tracable: false, postfix: meta instanceof MetadataArrayType ? `"[0]"` : "", }, container: array, })), ts.factory.createArrowFunction(undefined, undefined, [ IdentifierFactory.parameter("entire", ts.factory.createTypeReferenceNode("any[]")), ], TypeFactory.keyword("any"), undefined, props.config.decoder({ input: ts.factory.createIdentifier("entire"), definition: meta, explore: { ...props.explore, tracable: true, }, })), ], true), ts.factory.createTypeReferenceNode("const")); const iterate = (props) => ts.factory.createForOfStatement(undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(props.init)], ts.NodeFlags.Const), props.from, props.if); if (tupleList.length) statements.push(StatementFactory.constant({ name: "array", value: props.accessor.array(props.input), }), StatementFactory.constant({ name: "tuplePredicators", value: ts.factory.createArrayLiteralExpression(tupleList.map((x) => predicate(x)), true), }), iterate({ init: "pred", from: ts.factory.createIdentifier("tuplePredicators"), if: ts.factory.createIfStatement(ts.factory.createCallExpression(ts.factory.createIdentifier("pred[0]"), undefined, [array]), ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier(`pred[1]`), undefined, [array]))), })); if (arrayList.length) { if (tupleList.length === 0) statements.push(StatementFactory.constant({ name: "array", value: props.accessor.array(props.input), })); statements.push(StatementFactory.constant({ name: "top", value: props.accessor.front(props.input), }), ts.factory.createIfStatement(ts.factory.createStrictEquality(ExpressionFactory.number(0), props.accessor.size(props.input)), ts.isReturnStatement(props.config.empty) ? props.config.empty : ts.factory.createReturnStatement(props.config.empty)), StatementFactory.constant({ name: "arrayPredicators", value: ts.factory.createArrayLiteralExpression(arrayList.map((x) => predicate(x)), true), }), StatementFactory.constant({ name: "passed", value: ts.factory.createCallExpression(IdentifierFactory.access(ts.factory.createIdentifier("arrayPredicators"), "filter"), undefined, [ ts.factory.createArrowFunction(undefined, undefined, [IdentifierFactory.parameter("pred")], undefined, undefined, ts.factory.createCallExpression(ts.factory.createIdentifier("pred[0]"), undefined, [top])), ]), }), ts.factory.createIfStatement(ts.factory.createStrictEquality(ExpressionFactory.number(1), ts.factory.createIdentifier("passed.length")), ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createElementAccessExpression(ts.factory.createNonNullExpression(ts.factory.createIdentifier("passed[0]")), 1), undefined, [array])), ts.factory.createIfStatement(ts.factory.createLessThan(ExpressionFactory.number(1), ts.factory.createIdentifier("passed.length")), iterate({ init: "pred", from: ts.factory.createIdentifier("passed"), if: ts.factory.createIfStatement(ts.factory.createCallExpression(IdentifierFactory.access(array, "every"), undefined, [ ts.factory.createArrowFunction(undefined, undefined, [ IdentifierFactory.parameter("value", TypeFactory.keyword("any")), ], undefined, undefined, ts.factory.createStrictEquality(props.config.success, ts.factory.createCallExpression(ts.factory.createIdentifier("pred[0]"), undefined, [ts.factory.createIdentifier("value")]))), ]), ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier(`pred[1]`), undefined, [ts.factory.createIdentifier("array")]))), })))); } statements.push(props.config.failure({ input: props.input, expected: `(${targets .map((t) => props.accessor.name(t, props.accessor.element(t))) .join(" | ")})`, explore: props.explore, })); return ts.factory.createArrowFunction(undefined, undefined, props.parameters, undefined, undefined, ts.factory.createBlock(statements, true)); }; export { check_union_array_like }; //# sourceMappingURL=check_union_array_like.mjs.map