UNPKG

typia

Version:

Superfast runtime validators with only one line

240 lines 14.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidateProgrammer = void 0; const typescript_1 = __importDefault(require("typescript")); const ExpressionFactory_1 = require("../factories/ExpressionFactory"); const IdentifierFactory_1 = require("../factories/IdentifierFactory"); const StatementFactory_1 = require("../factories/StatementFactory"); const TypeFactory_1 = require("../factories/TypeFactory"); const CheckerProgrammer_1 = require("./CheckerProgrammer"); const FeatureProgrammer_1 = require("./FeatureProgrammer"); const IsProgrammer_1 = require("./IsProgrammer"); const FunctionProgrammer_1 = require("./helpers/FunctionProgrammer"); const OptionPredicator_1 = require("./helpers/OptionPredicator"); const check_everything_1 = require("./internal/check_everything"); const check_object_1 = require("./internal/check_object"); var ValidateProgrammer; (function (ValidateProgrammer) { ValidateProgrammer.decompose = (props) => { var _a; const is = IsProgrammer_1.IsProgrammer.decompose(props); const composed = CheckerProgrammer_1.CheckerProgrammer.compose(Object.assign(Object.assign({}, props), { config: { prefix: "_v", path: true, trace: true, numeric: OptionPredicator_1.OptionPredicator.numeric(props.context.options), equals: props.config.equals, atomist: (next) => [ ...(next.entry.expression ? [next.entry.expression] : []), ...(next.entry.conditions.length === 0 ? [] : next.entry.conditions.length === 1 ? next.entry.conditions[0].map((cond) => typescript_1.default.factory.createLogicalOr(cond.expression, create_report_call({ exceptionable: next.explore.from === "top" ? typescript_1.default.factory.createTrue() : typescript_1.default.factory.createIdentifier("_exceptionable"), path: typescript_1.default.factory.createIdentifier(next.explore.postfix ? `_path + ${next.explore.postfix}` : "_path"), expected: cond.expected, value: next.input, }))) : [ typescript_1.default.factory.createLogicalOr(next.entry.conditions .map((set) => set .map((s) => s.expression) .reduce((a, b) => typescript_1.default.factory.createLogicalAnd(a, b))) .reduce((a, b) => typescript_1.default.factory.createLogicalOr(a, b)), create_report_call({ exceptionable: next.explore.from === "top" ? typescript_1.default.factory.createTrue() : typescript_1.default.factory.createIdentifier("_exceptionable"), path: typescript_1.default.factory.createIdentifier(next.explore.postfix ? `_path + ${next.explore.postfix}` : "_path"), expected: next.entry.expected, value: next.input, })), ]), ].reduce((x, y) => typescript_1.default.factory.createLogicalAnd(x, y)), combiner: combine(props), joiner: joiner(props), success: typescript_1.default.factory.createTrue(), } })); const arrow = typescript_1.default.factory.createArrowFunction(undefined, undefined, [IdentifierFactory_1.IdentifierFactory.parameter("input", TypeFactory_1.TypeFactory.keyword("any"))], props.context.importer.type({ file: "typia", name: "IValidation", arguments: [ typescript_1.default.factory.createTypeReferenceNode((_a = props.name) !== null && _a !== void 0 ? _a : TypeFactory_1.TypeFactory.getFullName({ checker: props.context.checker, type: props.type, })), ], }), undefined, typescript_1.default.factory.createBlock([ // validate when false === is<T>(input) typescript_1.default.factory.createIfStatement(typescript_1.default.factory.createStrictEquality(typescript_1.default.factory.createFalse(), typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier("__is"), undefined, [typescript_1.default.factory.createIdentifier("input")])), typescript_1.default.factory.createBlock([ // prepare errors typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createBinaryExpression(typescript_1.default.factory.createIdentifier("errors"), typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.EqualsToken), typescript_1.default.factory.createArrayLiteralExpression([]))), typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createBinaryExpression(typescript_1.default.factory.createIdentifier("_report"), typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.EqualsToken), typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createAsExpression(props.context.importer.internal("validateReport"), TypeFactory_1.TypeFactory.keyword("any")), [], [typescript_1.default.factory.createIdentifier("errors")]))), typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createArrowFunction(undefined, undefined, composed.parameters, undefined, undefined, composed.body), undefined, [ typescript_1.default.factory.createIdentifier("input"), typescript_1.default.factory.createStringLiteral("$input"), typescript_1.default.factory.createTrue(), ])), StatementFactory_1.StatementFactory.constant({ name: "success", value: typescript_1.default.factory.createStrictEquality(ExpressionFactory_1.ExpressionFactory.number(0), typescript_1.default.factory.createIdentifier("errors.length")), }), typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createAsExpression(create_output(), TypeFactory_1.TypeFactory.keyword("any"))), ])), typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createAsExpression(typescript_1.default.factory.createObjectLiteralExpression([ typescript_1.default.factory.createPropertyAssignment("success", typescript_1.default.factory.createTrue()), typescript_1.default.factory.createPropertyAssignment("data", typescript_1.default.factory.createIdentifier("input")), ], true), TypeFactory_1.TypeFactory.keyword("any"))), ], true)); return { functions: Object.assign(Object.assign({}, is.functions), composed.functions), statements: [ ...is.statements, ...composed.statements, StatementFactory_1.StatementFactory.constant({ name: "__is", value: is.arrow, }), StatementFactory_1.StatementFactory.mut({ name: "errors" }), StatementFactory_1.StatementFactory.mut({ name: "_report" }), ], arrow, }; }; ValidateProgrammer.write = (props) => { const functor = new FunctionProgrammer_1.FunctionProgrammer(props.modulo.getText()); const result = ValidateProgrammer.decompose({ config: props.config, context: props.context, modulo: props.modulo, functor, type: props.type, name: props.name, }); return FeatureProgrammer_1.FeatureProgrammer.writeDecomposed({ modulo: props.modulo, functor, result, returnWrapper: props.config.standardSchema ? (arrow) => typescript_1.default.factory.createCallExpression(props.context.importer.internal("createStandardSchema"), undefined, [arrow]) : undefined, }); }; })(ValidateProgrammer || (exports.ValidateProgrammer = ValidateProgrammer = {})); const combine = (props) => (next) => { if (next.explore.tracable === false) return IsProgrammer_1.IsProgrammer.configure({ options: { object: (v) => validate_object({ context: props.context, functor: props.functor, config: props.config, entries: v.entries, input: v.input, }), numeric: true, }, context: props.context, functor: props.functor, }).combiner(next); const path = next.explore.postfix ? `_path + ${next.explore.postfix}` : "_path"; return next.logic === "and" ? next.binaries .map((binary) => binary.combined ? binary.expression : typescript_1.default.factory.createLogicalOr(binary.expression, create_report_call({ exceptionable: next.explore.source === "top" ? typescript_1.default.factory.createTrue() : typescript_1.default.factory.createIdentifier("_exceptionable"), path: typescript_1.default.factory.createIdentifier(path), expected: next.expected, value: next.input, }))) .reduce(typescript_1.default.factory.createLogicalAnd) : typescript_1.default.factory.createLogicalOr(next.binaries .map((binary) => binary.expression) .reduce(typescript_1.default.factory.createLogicalOr), create_report_call({ exceptionable: next.explore.source === "top" ? typescript_1.default.factory.createTrue() : typescript_1.default.factory.createIdentifier("_exceptionable"), path: typescript_1.default.factory.createIdentifier(path), expected: next.expected, value: next.input, })); }; const validate_object = (props) => (0, check_object_1.check_object)({ config: { equals: props.config.equals, undefined: true, assert: false, reduce: typescript_1.default.factory.createLogicalAnd, positive: typescript_1.default.factory.createTrue(), superfluous: (input, description) => create_report_call({ path: typescript_1.default.factory.createAdd(typescript_1.default.factory.createIdentifier("_path"), typescript_1.default.factory.createCallExpression(props.context.importer.internal("accessExpressionAsString"), undefined, [typescript_1.default.factory.createIdentifier("key")])), expected: "undefined", value: input, description, }), halt: (expr) => typescript_1.default.factory.createLogicalOr(typescript_1.default.factory.createStrictEquality(typescript_1.default.factory.createFalse(), typescript_1.default.factory.createIdentifier("_exceptionable")), expr), }, context: props.context, entries: props.entries, input: props.input, }); const joiner = (props) => ({ object: (v) => validate_object({ context: props.context, functor: props.functor, config: props.config, entries: v.entries, input: v.input, }), array: (props) => (0, check_everything_1.check_everything)(typescript_1.default.factory.createCallExpression(IdentifierFactory_1.IdentifierFactory.access(props.input, "map"), undefined, [props.arrow])), failure: (next) => { var _a, _b; return create_report_call({ exceptionable: ((_a = next.explore) === null || _a === void 0 ? void 0 : _a.from) === "top" ? typescript_1.default.factory.createTrue() : typescript_1.default.factory.createIdentifier("_exceptionable"), path: typescript_1.default.factory.createIdentifier(((_b = next.explore) === null || _b === void 0 ? void 0 : _b.postfix) ? `_path + ${next.explore.postfix}` : "_path"), expected: next.expected, value: next.input, }); }, tuple: (binaries) => (0, check_everything_1.check_everything)(typescript_1.default.factory.createArrayLiteralExpression(binaries, true)), }); const create_output = () => typescript_1.default.factory.createConditionalExpression(typescript_1.default.factory.createIdentifier("success"), undefined, typescript_1.default.factory.createObjectLiteralExpression([ typescript_1.default.factory.createShorthandPropertyAssignment("success"), typescript_1.default.factory.createPropertyAssignment("data", typescript_1.default.factory.createIdentifier("input")), ], true), undefined, typescript_1.default.factory.createObjectLiteralExpression([ typescript_1.default.factory.createShorthandPropertyAssignment("success"), typescript_1.default.factory.createShorthandPropertyAssignment("errors"), typescript_1.default.factory.createPropertyAssignment("data", typescript_1.default.factory.createIdentifier("input")), ], true)); const create_report_call = (props) => { var _a; return typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier("_report"), undefined, [ (_a = props.exceptionable) !== null && _a !== void 0 ? _a : typescript_1.default.factory.createIdentifier("_exceptionable"), typescript_1.default.factory.createObjectLiteralExpression([ typescript_1.default.factory.createPropertyAssignment("path", props.path), typescript_1.default.factory.createPropertyAssignment("expected", typescript_1.default.factory.createStringLiteral(props.expected)), typescript_1.default.factory.createPropertyAssignment("value", props.value), ...(props.description ? [ typescript_1.default.factory.createPropertyAssignment("description", props.description), ] : []), ], true), ]); }; //# sourceMappingURL=ValidateProgrammer.js.map