You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					124 lines
				
				5.6 KiB
			
		
		
			
		
	
	
					124 lines
				
				5.6 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"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
							 |