| "use strict"; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.callRef = exports.getValidate = void 0; |
| const ref_error_1 = require("../../compile/ref_error"); |
| const code_1 = require("../code"); |
| const codegen_1 = require("../../compile/codegen"); |
| const names_1 = require("../../compile/names"); |
| const compile_1 = require("../../compile"); |
| const util_1 = require("../../compile/util"); |
| const def = { |
| keyword: "$ref", |
| schemaType: "string", |
| code(cxt) { |
| const { gen, schema: $ref, it } = cxt; |
| const { baseId, schemaEnv: env, validateName, opts, self } = it; |
| const { root } = env; |
| if (($ref === "#" || $ref === "#/") && baseId === root.baseId) |
| return callRootRef(); |
| const schOrEnv = compile_1.resolveRef.call(self, root, baseId, $ref); |
| if (schOrEnv === undefined) |
| throw new ref_error_1.default(baseId, $ref); |
| if (schOrEnv instanceof compile_1.SchemaEnv) |
| return callValidate(schOrEnv); |
| return inlineRefSchema(schOrEnv); |
| function callRootRef() { |
| if (env === root) |
| return callRef(cxt, validateName, env, env.$async); |
| const rootName = gen.scopeValue("root", { ref: root }); |
| return callRef(cxt, (0, codegen_1._) `${rootName}.validate`, root, root.$async); |
| } |
| function callValidate(sch) { |
| const v = getValidate(cxt, sch); |
| callRef(cxt, v, sch, sch.$async); |
| } |
| function inlineRefSchema(sch) { |
| const schName = gen.scopeValue("schema", opts.code.source === true ? { ref: sch, code: (0, codegen_1.stringify)(sch) } : { ref: sch }); |
| const valid = gen.name("valid"); |
| const schCxt = cxt.subschema({ |
| schema: sch, |
| dataTypes: [], |
| schemaPath: codegen_1.nil, |
| topSchemaRef: schName, |
| errSchemaPath: $ref, |
| }, valid); |
| cxt.mergeEvaluated(schCxt); |
| cxt.ok(valid); |
| } |
| }, |
| }; |
| function getValidate(cxt, sch) { |
| const { gen } = cxt; |
| return sch.validate |
| ? gen.scopeValue("validate", { ref: sch.validate }) |
| : (0, codegen_1._) `${gen.scopeValue("wrapper", { ref: sch })}.validate`; |
| } |
| exports.getValidate = getValidate; |
| function callRef(cxt, v, sch, $async) { |
| const { gen, it } = cxt; |
| const { allErrors, schemaEnv: env, opts } = it; |
| const passCxt = opts.passContext ? names_1.default.this : codegen_1.nil; |
| if ($async) |
| callAsyncRef(); |
| else |
| callSyncRef(); |
| function callAsyncRef() { |
| if (!env.$async) |
| throw new Error("async schema referenced by sync schema"); |
| const valid = gen.let("valid"); |
| gen.try(() => { |
| gen.code((0, codegen_1._) `await ${(0, code_1.callValidateCode)(cxt, v, passCxt)}`); |
| addEvaluatedFrom(v); // TODO will not work with async, it has to be returned with the result |
| if (!allErrors) |
| gen.assign(valid, true); |
| }, (e) => { |
| gen.if((0, codegen_1._) `!(${e} instanceof ${it.ValidationError})`, () => gen.throw(e)); |
| addErrorsFrom(e); |
| if (!allErrors) |
| gen.assign(valid, false); |
| }); |
| cxt.ok(valid); |
| } |
| function callSyncRef() { |
| cxt.result((0, code_1.callValidateCode)(cxt, v, passCxt), () => addEvaluatedFrom(v), () => addErrorsFrom(v)); |
| } |
| function addErrorsFrom(source) { |
| const errs = (0, codegen_1._) `${source}.errors`; |
| gen.assign(names_1.default.vErrors, (0, codegen_1._) `${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`); // TODO tagged |
| gen.assign(names_1.default.errors, (0, codegen_1._) `${names_1.default.vErrors}.length`); |
| } |
| function addEvaluatedFrom(source) { |
| var _a; |
| if (!it.opts.unevaluated) |
| return; |
| const schEvaluated = (_a = sch === null || sch === void 0 ? void 0 : sch.validate) === null || _a === void 0 ? void 0 : _a.evaluated; |
| // TODO refactor |
| if (it.props !== true) { |
| if (schEvaluated && !schEvaluated.dynamicProps) { |
| if (schEvaluated.props !== undefined) { |
| it.props = util_1.mergeEvaluated.props(gen, schEvaluated.props, it.props); |
| } |
| } |
| else { |
| const props = gen.var("props", (0, codegen_1._) `${source}.evaluated.props`); |
| it.props = util_1.mergeEvaluated.props(gen, props, it.props, codegen_1.Name); |
| } |
| } |
| if (it.items !== true) { |
| if (schEvaluated && !schEvaluated.dynamicItems) { |
| if (schEvaluated.items !== undefined) { |
| it.items = util_1.mergeEvaluated.items(gen, schEvaluated.items, it.items); |
| } |
| } |
| else { |
| const items = gen.var("items", (0, codegen_1._) `${source}.evaluated.items`); |
| it.items = util_1.mergeEvaluated.items(gen, items, it.items, codegen_1.Name); |
| } |
| } |
| } |
| } |
| exports.callRef = callRef; |
| exports.default = def; |
| //# sourceMappingURL=ref.js.map |