"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateKeywordUsage = exports.validSchemaType = exports.funcKeywordCode = exports.macroKeywordCode = void 0; const codegen_1 = require("../codegen"); const names_1 = require("../names"); const code_1 = require("../../vocabularies/code"); const errors_1 = require("../errors"); function macroKeywordCode(cxt, def) { const { gen, keyword, schema, parentSchema, it } = cxt; const macroSchema = def.macro.call(it.self, schema, parentSchema, it); const schemaRef = useKeyword(gen, keyword, macroSchema); if (it.opts.validateSchema !== false) it.self.validateSchema(macroSchema, true); const valid = gen.name("valid"); cxt.subschema({ schema: macroSchema, schemaPath: codegen_1.nil, errSchemaPath: `${it.errSchemaPath}/${keyword}`, topSchemaRef: schemaRef, compositeRule: true, }, valid); cxt.pass(valid, () => cxt.error(true)); } exports.macroKeywordCode = macroKeywordCode; function funcKeywordCode(cxt, def) { var _a; const { gen, keyword, schema, parentSchema, $data, it } = cxt; checkAsyncKeyword(it, def); const validate = !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate; const validateRef = useKeyword(gen, keyword, validate); const valid = gen.let("valid"); cxt.block$data(valid, validateKeyword); cxt.ok((_a = def.valid) !== null && _a !== void 0 ? _a : valid); function validateKeyword() { if (def.errors === false) { assignValid(); if (def.modifying) modifyData(cxt); reportErrs(() => cxt.error()); } else { const ruleErrs = def.async ? validateAsync() : validateSync(); if (def.modifying) modifyData(cxt); reportErrs(() => addErrs(cxt, ruleErrs)); } } function validateAsync() { const ruleErrs = gen.let("ruleErrs", null); gen.try(() => assignValid((0, codegen_1._) `await `), (e) => gen.assign(valid, false).if((0, codegen_1._) `${e} instanceof ${it.ValidationError}`, () => gen.assign(ruleErrs, (0, codegen_1._) `${e}.errors`), () => gen.throw(e))); return ruleErrs; } function validateSync() { const validateErrs = (0, codegen_1._) `${validateRef}.errors`; gen.assign(validateErrs, null); assignValid(codegen_1.nil); return validateErrs; } function assignValid(_await = def.async ? (0, codegen_1._) `await ` : codegen_1.nil) { const passCxt = it.opts.passContext ? names_1.default.this : names_1.default.self; const passSchema = !(("compile" in def && !$data) || def.schema === false); gen.assign(valid, (0, codegen_1._) `${_await}${(0, code_1.callValidateCode)(cxt, validateRef, passCxt, passSchema)}`, def.modifying); } function reportErrs(errors) { var _a; gen.if((0, codegen_1.not)((_a = def.valid) !== null && _a !== void 0 ? _a : valid), errors); } } exports.funcKeywordCode = funcKeywordCode; function modifyData(cxt) { const { gen, data, it } = cxt; gen.if(it.parentData, () => gen.assign(data, (0, codegen_1._) `${it.parentData}[${it.parentDataProperty}]`)); } function addErrs(cxt, errs) { const { gen } = cxt; gen.if((0, codegen_1._) `Array.isArray(${errs})`, () => { gen .assign(names_1.default.vErrors, (0, codegen_1._) `${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`) .assign(names_1.default.errors, (0, codegen_1._) `${names_1.default.vErrors}.length`); (0, errors_1.extendErrors)(cxt); }, () => cxt.error()); } function checkAsyncKeyword({ schemaEnv }, def) { if (def.async && !schemaEnv.$async) throw new Error("async keyword in sync schema"); } function useKeyword(gen, keyword, result) { if (result === undefined) throw new Error(`keyword "${keyword}" failed to compile`); return gen.scopeValue("keyword", typeof result == "function" ? { ref: result } : { ref: result, code: (0, codegen_1.stringify)(result) }); } function validSchemaType(schema, schemaType, allowUndefined = false) { // TODO add tests return (!schemaType.length || schemaType.some((st) => st === "array" ? Array.isArray(schema) : st === "object" ? schema && typeof schema == "object" && !Array.isArray(schema) : typeof schema == st || (allowUndefined && typeof schema == "undefined"))); } exports.validSchemaType = validSchemaType; function validateKeywordUsage({ schema, opts, self, errSchemaPath }, def, keyword) { /* istanbul ignore if */ if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { throw new Error("ajv implementation error"); } const deps = def.dependencies; if (deps === null || deps === void 0 ? void 0 : deps.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { throw new Error(`parent schema must have dependencies of ${keyword}: ${deps.join(",")}`); } if (def.validateSchema) { const valid = def.validateSchema(schema[keyword]); if (!valid) { const msg = `keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` + self.errorsText(def.validateSchema.errors); if (opts.validateSchema === "log") self.logger.error(msg); else throw new Error(msg); } } } exports.validateKeywordUsage = validateKeywordUsage; //# sourceMappingURL=keyword.js.map