contains.js 3.6 KB

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