uniqueItems.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const dataType_1 = require("../../compile/validate/dataType");
  4. const codegen_1 = require("../../compile/codegen");
  5. const util_1 = require("../../compile/util");
  6. const equal_1 = require("../../runtime/equal");
  7. const error = {
  8. message: ({ params: { i, j } }) => (0, codegen_1.str) `must NOT have duplicate items (items ## ${j} and ${i} are identical)`,
  9. params: ({ params: { i, j } }) => (0, codegen_1._) `{i: ${i}, j: ${j}}`,
  10. };
  11. const def = {
  12. keyword: "uniqueItems",
  13. type: "array",
  14. schemaType: "boolean",
  15. $data: true,
  16. error,
  17. code(cxt) {
  18. const { gen, data, $data, schema, parentSchema, schemaCode, it } = cxt;
  19. if (!$data && !schema)
  20. return;
  21. const valid = gen.let("valid");
  22. const itemTypes = parentSchema.items ? (0, dataType_1.getSchemaTypes)(parentSchema.items) : [];
  23. cxt.block$data(valid, validateUniqueItems, (0, codegen_1._) `${schemaCode} === false`);
  24. cxt.ok(valid);
  25. function validateUniqueItems() {
  26. const i = gen.let("i", (0, codegen_1._) `${data}.length`);
  27. const j = gen.let("j");
  28. cxt.setParams({ i, j });
  29. gen.assign(valid, true);
  30. gen.if((0, codegen_1._) `${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j));
  31. }
  32. function canOptimize() {
  33. return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array");
  34. }
  35. function loopN(i, j) {
  36. const item = gen.name("item");
  37. const wrongType = (0, dataType_1.checkDataTypes)(itemTypes, item, it.opts.strictNumbers, dataType_1.DataType.Wrong);
  38. const indices = gen.const("indices", (0, codegen_1._) `{}`);
  39. gen.for((0, codegen_1._) `;${i}--;`, () => {
  40. gen.let(item, (0, codegen_1._) `${data}[${i}]`);
  41. gen.if(wrongType, (0, codegen_1._) `continue`);
  42. if (itemTypes.length > 1)
  43. gen.if((0, codegen_1._) `typeof ${item} == "string"`, (0, codegen_1._) `${item} += "_"`);
  44. gen
  45. .if((0, codegen_1._) `typeof ${indices}[${item}] == "number"`, () => {
  46. gen.assign(j, (0, codegen_1._) `${indices}[${item}]`);
  47. cxt.error();
  48. gen.assign(valid, false).break();
  49. })
  50. .code((0, codegen_1._) `${indices}[${item}] = ${i}`);
  51. });
  52. }
  53. function loopN2(i, j) {
  54. const eql = (0, util_1.useFunc)(gen, equal_1.default);
  55. const outer = gen.name("outer");
  56. gen.label(outer).for((0, codegen_1._) `;${i}--;`, () => gen.for((0, codegen_1._) `${j} = ${i}; ${j}--;`, () => gen.if((0, codegen_1._) `${eql}(${data}[${i}], ${data}[${j}])`, () => {
  57. cxt.error();
  58. gen.assign(valid, false).break(outer);
  59. })));
  60. }
  61. },
  62. };
  63. exports.default = def;
  64. //# sourceMappingURL=uniqueItems.js.map