additionalProperties.js 4.2 KB

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