| "use strict"; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| const code_1 = require("../code"); |
| const codegen_1 = require("../../compile/codegen"); |
| const names_1 = require("../../compile/names"); |
| const util_1 = require("../../compile/util"); |
| const error = { |
| message: "must NOT have additional properties", |
| params: ({ params }) => (0, codegen_1._) `{additionalProperty: ${params.additionalProperty}}`, |
| }; |
| const def = { |
| keyword: "additionalProperties", |
| type: ["object"], |
| schemaType: ["boolean", "object"], |
| allowUndefined: true, |
| trackErrors: true, |
| error, |
| code(cxt) { |
| const { gen, schema, parentSchema, data, errsCount, it } = cxt; |
| /* istanbul ignore if */ |
| if (!errsCount) |
| throw new Error("ajv implementation error"); |
| const { allErrors, opts } = it; |
| it.props = true; |
| if (opts.removeAdditional !== "all" && (0, util_1.alwaysValidSchema)(it, schema)) |
| return; |
| const props = (0, code_1.allSchemaProperties)(parentSchema.properties); |
| const patProps = (0, code_1.allSchemaProperties)(parentSchema.patternProperties); |
| checkAdditionalProperties(); |
| cxt.ok((0, codegen_1._) `${errsCount} === ${names_1.default.errors}`); |
| function checkAdditionalProperties() { |
| gen.forIn("key", data, (key) => { |
| if (!props.length && !patProps.length) |
| additionalPropertyCode(key); |
| else |
| gen.if(isAdditional(key), () => additionalPropertyCode(key)); |
| }); |
| } |
| function isAdditional(key) { |
| let definedProp; |
| if (props.length > 8) { |
| // TODO maybe an option instead of hard-coded 8? |
| const propsSchema = (0, util_1.schemaRefOrVal)(it, parentSchema.properties, "properties"); |
| definedProp = (0, code_1.isOwnProperty)(gen, propsSchema, key); |
| } |
| else if (props.length) { |
| definedProp = (0, codegen_1.or)(...props.map((p) => (0, codegen_1._) `${key} === ${p}`)); |
| } |
| else { |
| definedProp = codegen_1.nil; |
| } |
| if (patProps.length) { |
| definedProp = (0, codegen_1.or)(definedProp, ...patProps.map((p) => (0, codegen_1._) `${(0, code_1.usePattern)(cxt, p)}.test(${key})`)); |
| } |
| return (0, codegen_1.not)(definedProp); |
| } |
| function deleteAdditional(key) { |
| gen.code((0, codegen_1._) `delete ${data}[${key}]`); |
| } |
| function additionalPropertyCode(key) { |
| if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) { |
| deleteAdditional(key); |
| return; |
| } |
| if (schema === false) { |
| cxt.setParams({ additionalProperty: key }); |
| cxt.error(); |
| if (!allErrors) |
| gen.break(); |
| return; |
| } |
| if (typeof schema == "object" && !(0, util_1.alwaysValidSchema)(it, schema)) { |
| const valid = gen.name("valid"); |
| if (opts.removeAdditional === "failing") { |
| applyAdditionalSchema(key, valid, false); |
| gen.if((0, codegen_1.not)(valid), () => { |
| cxt.reset(); |
| deleteAdditional(key); |
| }); |
| } |
| else { |
| applyAdditionalSchema(key, valid); |
| if (!allErrors) |
| gen.if((0, codegen_1.not)(valid), () => gen.break()); |
| } |
| } |
| } |
| function applyAdditionalSchema(key, valid, errors) { |
| const subschema = { |
| keyword: "additionalProperties", |
| dataProp: key, |
| dataPropType: util_1.Type.Str, |
| }; |
| if (errors === false) { |
| Object.assign(subschema, { |
| compositeRule: true, |
| createErrors: false, |
| allErrors: false, |
| }); |
| } |
| cxt.subschema(subschema, valid); |
| } |
| }, |
| }; |
| exports.default = def; |
| //# sourceMappingURL=additionalProperties.js.map |