additionalProperties.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const code_1 = require("../code");
  4. const codegen_1 = require("../../compile/codegen");
  5. const names_1 = require("../../compile/names");
  6. const util_1 = require("../../compile/util");
  7. const error = {
  8. message: "must NOT have additional properties",
  9. params: ({ params }) => (0, codegen_1._) `{additionalProperty: ${params.additionalProperty}}`,
  10. };
  11. const def = {
  12. keyword: "additionalProperties",
  13. type: ["object"],
  14. schemaType: ["boolean", "object"],
  15. allowUndefined: true,
  16. trackErrors: true,
  17. error,
  18. code(cxt) {
  19. const { gen, schema, parentSchema, data, errsCount, it } = cxt;
  20. /* istanbul ignore if */
  21. if (!errsCount)
  22. throw new Error("ajv implementation error");
  23. const { allErrors, opts } = it;
  24. it.props = true;
  25. if (opts.removeAdditional !== "all" && (0, util_1.alwaysValidSchema)(it, schema))
  26. return;
  27. const props = (0, code_1.allSchemaProperties)(parentSchema.properties);
  28. const patProps = (0, code_1.allSchemaProperties)(parentSchema.patternProperties);
  29. checkAdditionalProperties();
  30. cxt.ok((0, codegen_1._) `${errsCount} === ${names_1.default.errors}`);
  31. function checkAdditionalProperties() {
  32. gen.forIn("key", data, (key) => {
  33. if (!props.length && !patProps.length)
  34. additionalPropertyCode(key);
  35. else
  36. gen.if(isAdditional(key), () => additionalPropertyCode(key));
  37. });
  38. }
  39. function isAdditional(key) {
  40. let definedProp;
  41. if (props.length > 8) {
  42. // TODO maybe an option instead of hard-coded 8?
  43. const propsSchema = (0, util_1.schemaRefOrVal)(it, parentSchema.properties, "properties");
  44. definedProp = (0, code_1.isOwnProperty)(gen, propsSchema, key);
  45. }
  46. else if (props.length) {
  47. definedProp = (0, codegen_1.or)(...props.map((p) => (0, codegen_1._) `${key} === ${p}`));
  48. }
  49. else {
  50. definedProp = codegen_1.nil;
  51. }
  52. if (patProps.length) {
  53. definedProp = (0, codegen_1.or)(definedProp, ...patProps.map((p) => (0, codegen_1._) `${(0, code_1.usePattern)(cxt, p)}.test(${key})`));
  54. }
  55. return (0, codegen_1.not)(definedProp);
  56. }
  57. function deleteAdditional(key) {
  58. gen.code((0, codegen_1._) `delete ${data}[${key}]`);
  59. }
  60. function additionalPropertyCode(key) {
  61. if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) {
  62. deleteAdditional(key);
  63. return;
  64. }
  65. if (schema === false) {
  66. cxt.setParams({ additionalProperty: key });
  67. cxt.error();
  68. if (!allErrors)
  69. gen.break();
  70. return;
  71. }
  72. if (typeof schema == "object" && !(0, util_1.alwaysValidSchema)(it, schema)) {
  73. const valid = gen.name("valid");
  74. if (opts.removeAdditional === "failing") {
  75. applyAdditionalSchema(key, valid, false);
  76. gen.if((0, codegen_1.not)(valid), () => {
  77. cxt.reset();
  78. deleteAdditional(key);
  79. });
  80. }
  81. else {
  82. applyAdditionalSchema(key, valid);
  83. if (!allErrors)
  84. gen.if((0, codegen_1.not)(valid), () => gen.break());
  85. }
  86. }
  87. }
  88. function applyAdditionalSchema(key, valid, errors) {
  89. const subschema = {
  90. keyword: "additionalProperties",
  91. dataProp: key,
  92. dataPropType: util_1.Type.Str,
  93. };
  94. if (errors === false) {
  95. Object.assign(subschema, {
  96. compositeRule: true,
  97. createErrors: false,
  98. allErrors: false,
  99. });
  100. }
  101. cxt.subschema(subschema, valid);
  102. }
  103. },
  104. };
  105. exports.default = def;
  106. //# sourceMappingURL=additionalProperties.js.map