UNPKG

@matatbread/typia

Version:

Superfast runtime validators with only one line

102 lines (99 loc) 5.34 kB
import ts from 'typescript'; import { ExpressionFactory } from '../../factories/ExpressionFactory.mjs'; import { IdentifierFactory } from '../../factories/IdentifierFactory.mjs'; import { StatementFactory } from '../../factories/StatementFactory.mjs'; import { check_dynamic_key } from './check_dynamic_key.mjs'; import { check_everything } from './check_everything.mjs'; /** @internal */ const check_dynamic_properties = (props) => { const length = IdentifierFactory.access(ts.factory.createCallExpression(ts.factory.createIdentifier("Object.keys"), undefined, [props.input]), "length"); const left = props.config.equals === true && props.dynamic.length === 0 ? props.config.undefined === true || props.regular.every((r) => r.meta.isRequired()) ? ts.factory.createStrictEquality(ExpressionFactory.number(props.regular.filter((r) => r.meta.isRequired()).length), length) : ts.factory.createCallExpression(props.context.importer.internal("isBetween"), [], [ length, ExpressionFactory.number(props.regular.filter((r) => r.meta.isRequired()).length), ExpressionFactory.number(props.regular.length), ]) : null; if (left !== null && props.config.undefined === false && props.regular.every((r) => r.meta.isRequired())) return left; const criteria = props.config.entries ? ts.factory.createCallExpression(props.config.entries, undefined, [ ts.factory.createCallExpression(ts.factory.createIdentifier("Object.keys"), undefined, [props.input]), check_dynamic_property(props), ]) : ts.factory.createCallExpression(IdentifierFactory.access(ts.factory.createCallExpression(ts.factory.createIdentifier("Object.keys"), undefined, [props.input]), props.config.assert ? "every" : "map"), undefined, [check_dynamic_property(props)]); const right = (props.config.halt || ((elem) => elem))(props.config.assert ? criteria : check_everything(criteria)); return left ? (props.config.undefined ? ts.factory.createLogicalOr : ts.factory.createLogicalAnd)(left, right) : right; }; /** @internal */ const check_dynamic_property = (props) => { //---- // IF CONDITIONS //---- // PREPARE ASSETS const key = ts.factory.createIdentifier("key"); const value = ts.factory.createIdentifier("value"); const statements = []; const add = (expression, output) => statements.push(ts.factory.createIfStatement(expression, ts.factory.createReturnStatement(output))); const broken = { value: false }; // GATHER CONDITIONS if (props.regular.length) add(is_regular_property(props.regular), props.config.positive); statements.push(StatementFactory.constant({ name: "value", value: ts.factory.createElementAccessExpression(props.input, key), })); if (props.config.undefined === true) add(ts.factory.createStrictEquality(ts.factory.createIdentifier("undefined"), value), props.config.positive); for (const entry of props.dynamic) { const condition = check_dynamic_key({ context: props.context, metadata: entry.key, input: key, }); if (condition.kind === ts.SyntaxKind.TrueKeyword) { statements.push(ts.factory.createReturnStatement(entry.expression)); broken.value = true; break; } else add(condition, entry.expression); } //---- // FUNCTION BODY //---- // CLOSURE BLOCK const block = ts.factory.createBlock([ ...statements, ...(broken.value ? [] : [ ts.factory.createReturnStatement(props.config.equals === true ? props.config.superfluous(value, ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createArrayLiteralExpression([ ts.factory.createTemplateExpression(ts.factory.createTemplateHead("The property `"), [ ts.factory.createTemplateSpan(ts.factory.createIdentifier("key"), ts.factory.createTemplateTail("` is not defined in the object type.")), ]), ts.factory.createStringLiteral(""), ts.factory.createStringLiteral("Please remove the property next time."), ], true), "join"), undefined, [ts.factory.createStringLiteral("\n")])) : props.config.positive), ]), ], true); // RETURNS return ts.factory.createArrowFunction(undefined, undefined, [IdentifierFactory.parameter("key")], undefined, undefined, block); }; /** @internal */ const is_regular_property = (regular) => ts.factory.createCallExpression(IdentifierFactory.access(ts.factory.createArrayLiteralExpression(regular.map((entry) => ts.factory.createStringLiteral(entry.key.getSoleLiteral()))), "some"), undefined, [ ts.factory.createArrowFunction(undefined, undefined, [IdentifierFactory.parameter("prop")], undefined, undefined, ts.factory.createStrictEquality(ts.factory.createIdentifier("key"), ts.factory.createIdentifier("prop"))), ]); export { check_dynamic_properties }; //# sourceMappingURL=check_dynamic_properties.mjs.map