contains.js 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const codegen_1 = require("../../compile/codegen");
  4. const subschema_1 = require("../../compile/subschema");
  5. const util_1 = require("../../compile/util");
  6. const validate_1 = require("../../compile/validate");
  7. const error = {
  8. message: ({ params: { min, max } }) => max === undefined
  9. ? codegen_1.str `should contain at least ${min} valid item(s)`
  10. : codegen_1.str `should contain at least ${min} and no more than ${max} valid item(s)`,
  11. params: ({ params: { min, max } }) => max === undefined ? codegen_1._ `{minContains: ${min}}` : codegen_1._ `{minContains: ${min}, maxContains: ${max}}`,
  12. };
  13. const def = {
  14. keyword: "contains",
  15. type: "array",
  16. schemaType: ["object", "boolean"],
  17. before: "uniqueItems",
  18. trackErrors: true,
  19. error,
  20. code(cxt) {
  21. const { gen, schema, parentSchema, data, it } = cxt;
  22. let min;
  23. let max;
  24. const { minContains, maxContains } = parentSchema;
  25. if (it.opts.next) {
  26. min = minContains === undefined ? 1 : minContains;
  27. max = maxContains;
  28. }
  29. else {
  30. min = 1;
  31. }
  32. const len = gen.const("len", codegen_1._ `${data}.length`);
  33. cxt.setParams({ min, max });
  34. if (max === undefined && min === 0) {
  35. validate_1.checkStrictMode(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`);
  36. return;
  37. }
  38. if (max !== undefined && min > max) {
  39. validate_1.checkStrictMode(it, `"minContains" > "maxContains" is always invalid`);
  40. cxt.fail();
  41. return;
  42. }
  43. if (util_1.alwaysValidSchema(it, schema)) {
  44. let cond = codegen_1._ `${len} >= ${min}`;
  45. if (max !== undefined)
  46. cond = codegen_1._ `${cond} && ${len} <= ${max}`;
  47. cxt.pass(cond);
  48. return;
  49. }
  50. it.items = true;
  51. const valid = gen.name("valid");
  52. if (max === undefined && min === 1) {
  53. validateItems(valid, () => gen.if(valid, () => gen.break()));
  54. }
  55. else {
  56. gen.let(valid, false);
  57. const schValid = gen.name("_valid");
  58. const count = gen.let("count", 0);
  59. validateItems(schValid, () => gen.if(schValid, () => checkLimits(count)));
  60. }
  61. cxt.result(valid, () => cxt.reset());
  62. function validateItems(_valid, block) {
  63. gen.forRange("i", 0, len, (i) => {
  64. cxt.subschema({
  65. keyword: "contains",
  66. dataProp: i,
  67. dataPropType: subschema_1.Type.Num,
  68. compositeRule: true,
  69. }, _valid);
  70. block();
  71. });
  72. }
  73. function checkLimits(count) {
  74. gen.code(codegen_1._ `${count}++`);
  75. if (max === undefined) {
  76. gen.if(codegen_1._ `${count} >= ${min}`, () => gen.assign(valid, true).break());
  77. }
  78. else {
  79. gen.if(codegen_1._ `${count} > ${max}`, () => gen.assign(valid, false).break());
  80. if (min === 1)
  81. gen.assign(valid, true);
  82. else
  83. gen.if(codegen_1._ `${count} >= ${min}`, () => gen.assign(valid, true));
  84. }
  85. }
  86. },
  87. };
  88. exports.default = def;
  89. //# sourceMappingURL=contains.js.map