@jetio/validator 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -249,7 +249,6 @@ class Compiler {
249
249
  this.validateKeywords = new Set();
250
250
  this.notLogic = false;
251
251
  this.noreturn = false;
252
- this.neutralError = false;
253
252
  this.standAlone = false;
254
253
  this.hasCompileKeyword = false;
255
254
  this.needslen_of = false;
@@ -442,11 +441,10 @@ class Compiler {
442
441
  return src.join("");
443
442
  }
444
443
  const schema = rootSchema;
445
- const varName = (schema.default === undefined || !this.options.useDefaults) &&
446
- !this.options.removeAdditional &&
447
- !this.options.coerceTypes
444
+ const varName = accessPattern === "rootData" ||
445
+ (inlined && (schema.default === undefined || !this.options.useDefaults))
448
446
  ? accessPattern
449
- : "var" + counter++;
447
+ : "jv" + counter++;
450
448
  this.initializeDefault(src, schema, varName, accessPattern, inlined);
451
449
  let shouldTrackProps;
452
450
  let shouldTrackItems;
@@ -490,11 +488,16 @@ class Compiler {
490
488
  return src.join("");
491
489
  }
492
490
  initializeDefault(src, schema, varName, accessPattern, inlined) {
493
- if (schema.default !== undefined && this.options.useDefaults) {
494
- src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
495
- }
496
- else if (this.options.removeAdditional || this.options.coerceTypes) {
497
- src.push(`let ${varName} = ${accessPattern};`);
491
+ if (accessPattern !== "rootData") {
492
+ if (schema.default !== undefined && this.options.useDefaults) {
493
+ src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
494
+ }
495
+ else if (!inlined) {
496
+ const keyword = this.options.removeAdditional || this.options.coerceTypes
497
+ ? "let"
498
+ : "const";
499
+ src.push(`${keyword} ${varName} = ${accessPattern};`);
500
+ }
498
501
  }
499
502
  if (this.options.coerceTypes) {
500
503
  if (schema.type === "number" || schema.type === "integer") {
@@ -610,10 +613,20 @@ class Compiler {
610
613
  src.push(`if(${extra.before} true){`);
611
614
  src.push(`const ${funcValidator}Result = ${awaitPrefix}${schema.__functionName}${callArgs};`);
612
615
  if (this.options.allErrors) {
613
- src.push(`if (!${funcValidator}Result) {${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);${extra.refAfter || extra.after}}`);
616
+ src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);`}}`);
614
617
  }
615
618
  else {
616
- src.push(`if (!${funcValidator}Result){${this.mainFunctionName}.errors = ${schema.__functionName}.errors;${extra.refAfter ?? extra.after}${this.noreturn ? "" : "return false;"}}`);
619
+ if (this.noreturn) {
620
+ src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${schema.__functionName}.errors.length > 1 ? (${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors)) : ${this.errorVariable}.push(${schema.__functionName}.errors[0]);`}}`);
621
+ }
622
+ else {
623
+ if (this.mainFunctionName === schema.__functionName) {
624
+ src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
625
+ }
626
+ else {
627
+ src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${schema.__functionName}.errors;return false;`}}`);
628
+ }
629
+ }
617
630
  }
618
631
  if (extra.before != "")
619
632
  src.push(`}`);
@@ -639,10 +652,20 @@ class Compiler {
639
652
  src.push(`if(${extra.before} true){`);
640
653
  src.push(`const ${refValidator}Result = ${awaitPrefix}${functionName}${callArgs};`);
641
654
  if (this.options.allErrors) {
642
- src.push(`if (!${refValidator}Result) {${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);${extra.refAfter || extra.after}}`);
655
+ src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);`}}`);
643
656
  }
644
657
  else {
645
- src.push(`if (!${refValidator}Result){${this.mainFunctionName}.errors = ${functionName}.errors;${extra.refAfter ?? extra.after}${this.noreturn ? "" : "return false;"}}`);
658
+ if (this.noreturn) {
659
+ src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${functionName}.errors.length > 1 ? (${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors)) : ${this.errorVariable}.push(${functionName}.errors[0]);`}}`);
660
+ }
661
+ else {
662
+ if (this.mainFunctionName === functionName) {
663
+ src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
664
+ }
665
+ else {
666
+ src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${functionName}.errors;return false;`}}`);
667
+ }
668
+ }
646
669
  }
647
670
  if (extra.before != "")
648
671
  src.push(`}`);
@@ -661,12 +684,12 @@ class Compiler {
661
684
  return `(${args.join(", ")})`;
662
685
  }
663
686
  handleLogicalOperators(src, schema, varName, pathContext, trackingState, extra) {
687
+ if (schema.allOf)
688
+ this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
664
689
  if (schema.not)
665
690
  this.handleNotOperator(src, schema, varName, pathContext, extra);
666
691
  if (schema.anyOf)
667
692
  this.handleAnyOfOperator(src, schema, varName, pathContext, trackingState, extra);
668
- if (schema.allOf)
669
- this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
670
693
  if (schema.oneOf)
671
694
  this.handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra);
672
695
  }
@@ -700,9 +723,12 @@ class Compiler {
700
723
  let firstLength = "";
701
724
  const anyOfValid = "anyOfValid" + counter++;
702
725
  src.push(`let ${anyOfValid} = false;`);
703
- const anyOfError = "anyOfErr" + counter++;
704
- if (!this.options.allErrors && !this.notLogic)
726
+ const anyOfError = this.noreturn
727
+ ? this.errorVariable
728
+ : "anyOfErr" + counter++;
729
+ if (!this.options.allErrors && !this.noreturn)
705
730
  src.push(`let ${anyOfError} = [];`);
731
+ const error = this.errorVariable;
706
732
  schema.anyOf.forEach((subSchema, index) => {
707
733
  const branch = `branch${counter++}Valid`;
708
734
  if (!this.options.allErrors)
@@ -713,24 +739,27 @@ class Compiler {
713
739
  const configs = this.createSubschemaOptions(trackingState, pathContext, `anyOf/${index}`, schema);
714
740
  configs.pathContext.alt = `${pathContext.schema}/anyOf/${index}`;
715
741
  configs.pathContext.alt2 = `${pathContext.schema}/anyOf`;
742
+ let errorCountVar = "anyErrCnt" + counter++;
716
743
  if (this.options.allErrors) {
717
744
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
718
745
  }
719
746
  else {
747
+ this.errorVariable = anyOfError;
720
748
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
721
749
  before: `${branch} && `,
722
- after: `${branch} = false;${this.notLogic ? "" : `${anyOfError}.push(${this.mainFunctionName}.errors[0]);`}`,
723
- refAfter: `${branch} = false;${this.notLogic ? "" : `${anyOfError} = ${anyOfError}.concat(${this.mainFunctionName}.errors);`}`,
750
+ after: `${branch} = false;`,
724
751
  }, true);
725
752
  }
726
- this.noreturn = noreturn;
727
- let errorCountVar;
728
753
  if (this.options.allErrors) {
729
- errorCountVar = "anyErrCnt" + counter++;
730
754
  src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
731
755
  if (index === 0)
732
756
  firstLength = errorCountVar;
733
757
  }
758
+ else if (index === 0) {
759
+ src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
760
+ firstLength = errorCountVar;
761
+ }
762
+ this.noreturn = noreturn;
734
763
  if (index > 0 &&
735
764
  !trackingState.shouldTrackEvaluatedProperties &&
736
765
  !trackingState.shouldTrackEvaluatedItems) {
@@ -765,27 +794,36 @@ class Compiler {
765
794
  }
766
795
  });
767
796
  if (this.options.allErrors) {
768
- src.push(`if (${anyOfValid}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else{${extra.after}}` : ""}`);
797
+ src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else if(!${anyOfValid}){${extra.after}}` : ""}`);
769
798
  }
770
799
  else {
771
- src.push(`if (${anyOfValid}){${this.mainFunctionName}.errors = undefined}else {${this.notLogic ? "" : `${this.mainFunctionName}.errors = ${anyOfError};`}${extra.refAfter ?? extra.after}${this.noreturn ? "" : "return false;"}}`);
800
+ if (this.noreturn) {
801
+ src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(!${anyOfValid}){${extra.after}}`);
802
+ }
803
+ else {
804
+ src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(!${anyOfValid}){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${this.errorVariable};return false;`}}`);
805
+ }
806
+ this.errorVariable = error;
772
807
  }
773
808
  }
774
809
  handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra) {
775
810
  if (!schema.oneOf)
776
811
  return;
777
812
  let firstLength = "";
778
- const oneOfErrors = `oneOfErrors${counter++}`;
813
+ const oneOfErrors = this.noreturn
814
+ ? this.errorVariable
815
+ : `oneOfErrors${counter++}`;
779
816
  const validSchemaCount = "validSchemaCount" + counter++;
780
817
  src.push(`let ${validSchemaCount} = 0;`);
781
- if (!this.options.allErrors)
818
+ if (!this.options.allErrors && !this.noreturn)
782
819
  src.push(`let ${oneOfErrors} = [];`);
820
+ const noreturn = this.noreturn;
821
+ const error = this.errorVariable;
783
822
  schema.oneOf.forEach((subSchema, index) => {
784
823
  const branch = `branch${counter++}Valid`;
785
- if (!this.options.allErrors && !this.notLogic)
824
+ if (!this.options.allErrors)
786
825
  src.push(`let ${branch} = true;`);
787
826
  let validatorFn;
788
- const noreturn = this.noreturn;
789
827
  this.noreturn = true;
790
828
  const configs = this.createSubschemaOptions(trackingState, pathContext, `oneOf/${index}`, schema);
791
829
  configs.pathContext.alt = `${pathContext.schema}/oneOf/${index}`;
@@ -794,20 +832,22 @@ class Compiler {
794
832
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
795
833
  }
796
834
  else {
835
+ this.errorVariable = oneOfErrors;
797
836
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
798
837
  before: `${branch} && `,
799
- after: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors}.push(${this.mainFunctionName}.errors[0]);`}`,
800
- refAfter: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors} = ${oneOfErrors}.concat(${this.mainFunctionName}.errors);`}`,
838
+ after: `${branch} = false;`,
801
839
  }, true);
802
840
  }
803
- this.noreturn = noreturn;
804
- let errorCountVar;
841
+ let errorCountVar = "oneErrCnt" + counter++;
805
842
  if (this.options.allErrors) {
806
- errorCountVar = "oneErrCnt" + counter;
807
843
  src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
808
844
  if (index === 0)
809
845
  firstLength = errorCountVar;
810
846
  }
847
+ else if (index === 0) {
848
+ src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
849
+ firstLength = errorCountVar;
850
+ }
811
851
  if (index > 0 &&
812
852
  !trackingState.shouldTrackEvaluatedProperties &&
813
853
  !trackingState.shouldTrackEvaluatedItems) {
@@ -842,7 +882,7 @@ class Compiler {
842
882
  }
843
883
  });
844
884
  if (this.options.allErrors) {
845
- src.push(`if (${validSchemaCount} == 1) {${this.errorVariable}.length = ${firstLength};} else{${this.buildErrorReturn(pathContext, {
885
+ src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
846
886
  keyword: "oneOf",
847
887
  value: varName,
848
888
  message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
@@ -850,14 +890,23 @@ class Compiler {
850
890
  })}${extra.after}}`);
851
891
  }
852
892
  else {
853
- const noreturn = this.noreturn;
854
- this.noreturn = true;
855
- src.push(`if (${validSchemaCount} == 1){${this.mainFunctionName}.errors = undefined}else {${this.buildErrorReturn(pathContext, {
856
- keyword: "oneOf",
857
- value: varName,
858
- message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
859
- expected: '"exactly one schema"',
860
- })}${this.notLogic ? "" : `${oneOfErrors}.push(${this.mainFunctionName}.errors[0]);${this.mainFunctionName}.errors = ${oneOfErrors};`}${extra.refAfter ?? extra.after}${noreturn ? "" : "return false;"}}`);
893
+ if (noreturn) {
894
+ src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
895
+ keyword: "oneOf",
896
+ value: varName,
897
+ message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
898
+ expected: '"exactly one schema"',
899
+ })}${extra.after}}`);
900
+ }
901
+ else {
902
+ src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
903
+ keyword: "oneOf",
904
+ value: varName,
905
+ message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
906
+ expected: '"exactly one schema"',
907
+ })}${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${this.errorVariable};return false;`}}`);
908
+ }
909
+ this.errorVariable = error;
861
910
  this.noreturn = noreturn;
862
911
  }
863
912
  }
@@ -1323,11 +1372,15 @@ class Compiler {
1323
1372
  else {
1324
1373
  comparisonTarget = schema.multipleOf;
1325
1374
  }
1326
- src.push(`const multipleOf = ${comparisonTarget};
1327
- const quotient = ${varName} / multipleOf;
1328
- const rounded = Math.round(quotient);
1329
- const tolerance = Math.abs(quotient) * Number.EPSILON;
1330
- if (${extra.before}multipleOf === 0 || !isFinite(quotient) || Math.abs(quotient - rounded) > tolerance) {${this.buildErrorReturn(pathContext, {
1375
+ const multipleOfVar = "multipleOf" + counter++;
1376
+ const quotientVar = "quotient" + counter++;
1377
+ const roundedVar = "rounded" + counter++;
1378
+ const toleranceVar = "tolerance" + counter++;
1379
+ src.push(`const ${multipleOfVar} = ${comparisonTarget};
1380
+ const ${quotientVar} = ${varName} / ${multipleOfVar};
1381
+ const ${roundedVar} = Math.round(${quotientVar});
1382
+ const ${toleranceVar} = Math.abs(${quotientVar}) * Number.EPSILON;
1383
+ if (${extra.before}${multipleOfVar} === 0 || !isFinite(${quotientVar}) || Math.abs(${quotientVar} - ${roundedVar}) > ${toleranceVar}) {${this.buildErrorReturn(pathContext, {
1331
1384
  keyword: "multipleOf",
1332
1385
  value: varName,
1333
1386
  message: `"Value must be a multiple of " + ${comparisonTarget}`,
@@ -1430,7 +1483,8 @@ class Compiler {
1430
1483
  else {
1431
1484
  src.push(`const formatValidator = formatValidators[${formatKeyVar}].validate ?? formatValidators[${formatKeyVar}];`);
1432
1485
  }
1433
- src.push(`if (${extra.before}formatValidator && typeof ${varName} === 'string') {`, ` const isValid = typeof formatValidator === 'function' ? ${this.options.async ? "async" : ""}formatValidator(${varName}) : formatValidator.test(${varName});`, ` if (!isValid) {${this.buildErrorReturn(pathContext, {
1486
+ const isValid = "isValid" + counter++;
1487
+ src.push(`if (${extra.before}formatValidator && typeof ${varName} === 'string') {`, ` const ${isValid} = typeof formatValidator === 'function' ? ${this.options.async ? "async" : ""}formatValidator(${varName}) : formatValidator.test(${varName});`, ` if (!${isValid}) {${this.buildErrorReturn(pathContext, {
1434
1488
  keyword: "format",
1435
1489
  value: varName,
1436
1490
  message: `"Failed to validate value against format "+${formatKeyVar}`,
@@ -1440,7 +1494,7 @@ class Compiler {
1440
1494
  else {
1441
1495
  const data = this.jetValidator.getFormat(schema.format);
1442
1496
  if (!data) {
1443
- throw new Error(`Format '${schema.format}' not found`);
1497
+ console.warn(`Format '${schema.format}' not found will be ignored`);
1444
1498
  }
1445
1499
  const format = typeof data === "object" && "validate" in data ? data.validate : data;
1446
1500
  const formatType = typeof data === "object" &&
@@ -1539,14 +1593,16 @@ class Compiler {
1539
1593
  const resolvedPath = resolveDataPointerAtCompileTime(pointer, pathContext.$data, this.refCall);
1540
1594
  const requiredArrayExpr = generateArrayDataRef(src, resolvedPath, extra);
1541
1595
  src.push(`if (${extra.before}${requiredArrayExpr}) {`);
1542
- src.push(`for (let i = 0; i < ${requiredArrayExpr}.length; i++) {`);
1543
- src.push(`const prop = ${requiredArrayExpr}[i];`);
1544
- addEvaluatedProperty(src, "prop", trackingState);
1545
- src.push(`if (${extra.before}${varName}[prop] === undefined) {${this.buildErrorReturn(pathContext, {
1596
+ const i = "i" + counter++;
1597
+ src.push(`for (let ${i} = 0; ${i} < ${requiredArrayExpr}.length; ${i}++) {`);
1598
+ const prop = "prop" + counter++;
1599
+ src.push(`const ${prop} = ${requiredArrayExpr}[${i}];`);
1600
+ addEvaluatedProperty(src, prop, trackingState);
1601
+ src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
1546
1602
  keyword: "required",
1547
1603
  value: varName,
1548
- message: `"Missing required field: " + prop + " in data."`,
1549
- expected: "prop",
1604
+ message: `"Missing required field: " + ${prop} + " in data."`,
1605
+ expected: `${prop}`,
1550
1606
  schemaPath: `${pathContext.schema}`,
1551
1607
  })}${extra.after}}`);
1552
1608
  src.push(`}`);
@@ -1560,23 +1616,39 @@ class Compiler {
1560
1616
  if (Array.isArray(schema.required)) {
1561
1617
  if (this.options.allErrors ||
1562
1618
  schema.required.length > this.options.loopRequired) {
1563
- const arr = JSON.stringify(schema.required);
1564
- const arrVar = `arr${src.length}${counter++}`;
1565
- const iVar = `i${src.length}${counter++}`;
1566
- src.push(`const ${arrVar} = ${arr};`);
1567
1619
  if (extra.before != "")
1568
1620
  src.push(`if(${extra.before} true){`);
1569
- src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
1570
- src.push(`const prop = ${arrVar}[${iVar}];`);
1571
- addEvaluatedProperty(src, "prop", trackingState);
1572
- src.push(`if (${extra.before}${varName}[prop] === undefined) {${this.buildErrorReturn(pathContext, {
1573
- keyword: "required",
1574
- value: varName,
1575
- message: `"Missing required field: " + prop + " in data."`,
1576
- expected: "prop",
1577
- schemaPath: `${pathContext.schema}`,
1578
- })}${extra.after}}`);
1579
- src.push(`}`);
1621
+ if (schema.required.length > this.options.loopRequired) {
1622
+ const arr = JSON.stringify(schema.required);
1623
+ const arrVar = `arr${src.length}${counter++}`;
1624
+ const iVar = `i${src.length}${counter++}`;
1625
+ src.push(`const ${arrVar} = ${arr};`);
1626
+ src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
1627
+ const prop = "prop" + counter++;
1628
+ src.push(`const ${prop} = ${arrVar}[${iVar}];`);
1629
+ addEvaluatedProperty(src, prop, trackingState);
1630
+ src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
1631
+ keyword: "required",
1632
+ value: varName,
1633
+ message: `"Missing required field: " + ${prop} + " in data."`,
1634
+ expected: `${prop}`,
1635
+ schemaPath: `${pathContext.schema}`,
1636
+ })}${extra.after}}`);
1637
+ src.push(`}`);
1638
+ }
1639
+ else {
1640
+ for (const prop of schema.required) {
1641
+ const errorMessage = JSON.stringify(`Missing required field: ${prop} in data.`);
1642
+ const pstring = JSON.stringify(prop);
1643
+ src.push(`if (${extra.before}${varName}[${pstring}] === undefined) {${this.buildErrorReturn(pathContext, {
1644
+ keyword: "required",
1645
+ value: varName,
1646
+ message: errorMessage,
1647
+ expected: `${pstring}`,
1648
+ schemaPath: `${pathContext.schema}`,
1649
+ })}${extra.after}}`);
1650
+ }
1651
+ }
1580
1652
  if (extra.before != "")
1581
1653
  src.push(`}`);
1582
1654
  }
@@ -1629,21 +1701,22 @@ class Compiler {
1629
1701
  handlePatternProperties(src, schema, varName, pathContext, trackingState, extra) {
1630
1702
  if (extra.before != "")
1631
1703
  src.push(`if(${extra.before} true){`);
1632
- src.push(`for (const key in ${varName}) {`);
1704
+ const key = "key" + counter++;
1705
+ src.push(`for (const ${key} in ${varName}) {`);
1633
1706
  Object.getOwnPropertyNames(schema.patternProperties).forEach((pattern) => {
1634
1707
  let pname = this.regexCache.get(pattern);
1635
1708
  if (!pname) {
1636
1709
  pname = "patternProp" + counter++;
1637
1710
  this.regexCache.set(pattern, pname);
1638
1711
  }
1639
- src.push(`if (${pname}.test(key)) {`);
1640
- addEvaluatedProperty(src, "key", trackingState);
1712
+ src.push(`if (${pname}.test(${key})) {`);
1713
+ addEvaluatedProperty(src, key, trackingState);
1641
1714
  const parent = trackingState.parentHasUnevaluatedProperties ||
1642
1715
  trackingState.hasOwnUnevaluatedProperties;
1643
1716
  const patternValidation = this.compileSchema(schema.patternProperties[pattern], {
1644
1717
  schema: `${pathContext.schema}/patternProperties/${JSON.stringify(pattern)}`,
1645
- data: `${pathContext.data}/\${key}`,
1646
- $data: `${pathContext.$data}/\${key}`,
1718
+ data: `${pathContext.data}/\${${key}}`,
1719
+ $data: `${pathContext.$data}/\${${key}}`,
1647
1720
  alt: pathContext.alt,
1648
1721
  alt2: pathContext.alt2,
1649
1722
  }, {
@@ -1652,7 +1725,7 @@ class Compiler {
1652
1725
  parentUnevaluatedPropVar: parent
1653
1726
  ? trackingState.unevaluatedPropVar
1654
1727
  : undefined,
1655
- }, `${varName}[key]`, extra);
1728
+ }, `${varName}[${key}]`, extra);
1656
1729
  src.push(patternValidation, "}");
1657
1730
  });
1658
1731
  src.push("}");
@@ -1664,12 +1737,13 @@ class Compiler {
1664
1737
  const explicitProps = Array.from(allowedProperties);
1665
1738
  if (extra.before != "")
1666
1739
  src.push(`if(${extra.before} true){`);
1667
- src.push(`for (const key in ${varName}) {`);
1668
- addEvaluatedProperty(src, "key", trackingState);
1740
+ const key = "key" + counter++;
1741
+ src.push(`for (const ${key} in ${varName}) {`);
1742
+ addEvaluatedProperty(src, key, trackingState);
1669
1743
  let checks = [];
1670
1744
  if (explicitProps.length > 0) {
1671
1745
  const allowedCheck = explicitProps
1672
- .map((key) => `key === ${JSON.stringify(key)}`)
1746
+ .map((keyItem) => `${key} === ${JSON.stringify(keyItem)}`)
1673
1747
  .join(" || ");
1674
1748
  checks.push(allowedCheck);
1675
1749
  }
@@ -1681,7 +1755,7 @@ class Compiler {
1681
1755
  pname = "patternProp" + counter++;
1682
1756
  this.regexCache.set(pattern, pname);
1683
1757
  }
1684
- return `${pname}.test(key)`;
1758
+ return `${pname}.test(${key})`;
1685
1759
  })
1686
1760
  .join(" || ");
1687
1761
  checks.push(patternCheck);
@@ -1692,17 +1766,18 @@ class Compiler {
1692
1766
  }
1693
1767
  const additionalPropValidation = this.compileSchema(schema.additionalProperties, {
1694
1768
  schema: `${pathContext.schema}/additionalProperties`,
1695
- data: `${pathContext.data}/\${key}`,
1696
- $data: `${pathContext.$data}/\${key}`,
1769
+ data: `${pathContext.data}/\${${key}}`,
1770
+ $data: `${pathContext.$data}/\${${key}}`,
1697
1771
  alt: pathContext.alt,
1698
1772
  alt2: pathContext.alt2,
1699
- }, {}, `${varName}[key]`, extra);
1773
+ }, {}, `${varName}[${key}]`, extra);
1700
1774
  src.push(additionalPropValidation, "}");
1701
1775
  if (extra.before != "")
1702
1776
  src.push(`}`);
1703
1777
  }
1704
1778
  handlePropertyConstraints(src, schema, varName, pathContext, extra) {
1705
- src.push(`const objKeys = Object.keys(${varName});`);
1779
+ const objKeys = "objKeys" + counter++;
1780
+ src.push(`const ${objKeys} = Object.keys(${varName});`);
1706
1781
  if (schema.minProperties !== undefined) {
1707
1782
  const isDataRef = this.options.$data && isDataReference(schema.minProperties);
1708
1783
  let comparisonTarget;
@@ -1714,9 +1789,9 @@ class Compiler {
1714
1789
  else {
1715
1790
  comparisonTarget = schema.minProperties;
1716
1791
  }
1717
- src.push(`if (${extra.before}objKeys.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1792
+ src.push(`if (${extra.before}${objKeys}.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1718
1793
  keyword: "minProperties",
1719
- value: "objKeys.length",
1794
+ value: `${objKeys}.length`,
1720
1795
  message: `"Object must have at least " + ${comparisonTarget} + " properties."`,
1721
1796
  expected: comparisonTarget,
1722
1797
  })}${extra.after}}`);
@@ -1735,9 +1810,9 @@ class Compiler {
1735
1810
  else {
1736
1811
  comparisonTarget = schema.maxProperties;
1737
1812
  }
1738
- src.push(`if (${extra.before}objKeys.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1813
+ src.push(`if (${extra.before}${objKeys}.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1739
1814
  keyword: "maxProperties",
1740
- value: "objKeys.length",
1815
+ value: `${objKeys}.length`,
1741
1816
  message: `"Object must have at most " + ${comparisonTarget} + " properties."`,
1742
1817
  expected: comparisonTarget,
1743
1818
  })}${extra.after}}`);
@@ -1749,14 +1824,15 @@ class Compiler {
1749
1824
  handlePropertyNames(src, schema, varName, pathContext, extra) {
1750
1825
  if (extra.before != "")
1751
1826
  src.push(`if(${extra.before} true){`);
1752
- src.push(`for (const key in ${varName}) {`);
1827
+ const key = "key" + counter++;
1828
+ src.push(`for (const ${key} in ${varName}) {`);
1753
1829
  const propertyNameValidation = this.compileSchema(schema.propertyNames, {
1754
1830
  schema: `${pathContext.schema}/propertyNames`,
1755
- data: `${pathContext.data}/\${key}`,
1756
- $data: `${pathContext.$data}/\${key}`,
1831
+ data: `${pathContext.data}/\${${key}}`,
1832
+ $data: `${pathContext.$data}/\${${key}}`,
1757
1833
  alt: pathContext.alt,
1758
1834
  alt2: pathContext.alt2,
1759
- }, {}, `key`, extra);
1835
+ }, {}, key, extra);
1760
1836
  src.push(propertyNameValidation, "}");
1761
1837
  if (extra.before != "")
1762
1838
  src.push(`}`);
@@ -1868,7 +1944,8 @@ class Compiler {
1868
1944
  const evalSet = trackingState.unevaluatedPropVar;
1869
1945
  if (extra.before != "")
1870
1946
  src.push(`if(${extra.before} true){`);
1871
- src.push(`const ${unName} = [];`, `for (const key in ${varName}) {`, `if (!${evalSet}.has(key)) {`, `${unName}.push(key);`, `}`, `}`);
1947
+ const key = "key" + counter++;
1948
+ src.push(`const ${unName} = [];`, `for (const ${key} in ${varName}) {`, `if (!${evalSet}.has(${key})) {`, `${unName}.push(${key});`, `}`, `}`);
1872
1949
  if (schema.unevaluatedProperties === false) {
1873
1950
  src.push(`if (${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
1874
1951
  keyword: "unevaluatedProperties",
@@ -1881,7 +1958,8 @@ class Compiler {
1881
1958
  }
1882
1959
  else if (schema.unevaluatedProperties === true) {
1883
1960
  if (trackingState.parentHasUnevaluatedProperties) {
1884
- src.push(`for(const key in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(key)}`);
1961
+ const key = "key" + counter++;
1962
+ src.push(`for(const ${key} in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(${key})}`);
1885
1963
  }
1886
1964
  }
1887
1965
  else {
@@ -2199,7 +2277,8 @@ class Compiler {
2199
2277
  const evalSet = trackingState.unevaluatedItemVar;
2200
2278
  if (extra.before != "")
2201
2279
  src.push(`if(${extra.before} true){`);
2202
- src.push(`const ${unName} = [];`, `for (let i = 0; i < ${varName}.length; i++) {`, `if (!${evalSet}.has(i)) {`, `${unName}.push(i);`, `}`, `}`);
2280
+ const i = "i" + counter++;
2281
+ src.push(`const ${unName} = [];`, `for (let ${i} = 0; ${i} < ${varName}.length; ${i}++) {`, `if (!${evalSet}.has(${i})) {`, `${unName}.push(${i});`, `}`, `}`);
2203
2282
  if (schema.unevaluatedItems === false) {
2204
2283
  src.push(`if (${extra.before}${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
2205
2284
  keyword: "unevaluatedItems",
@@ -2237,9 +2316,7 @@ class Compiler {
2237
2316
  buildErrorReturn(pathContext, error, spreads) {
2238
2317
  if (this.notLogic)
2239
2318
  return "";
2240
- if (this.neutralError)
2241
- return "return false;";
2242
- let result = this.options.allErrors
2319
+ let result = this.options.allErrors || this.noreturn
2243
2320
  ? `${this.errorVariable}.push({`
2244
2321
  : `${this.mainFunctionName}.errors = [{`;
2245
2322
  const escapedDataPath = escapeTemplateString(error.dataPath || pathContext.data || "/");
@@ -2320,7 +2397,7 @@ class Compiler {
2320
2397
  result += `,${spreads}`;
2321
2398
  }
2322
2399
  result += "}";
2323
- if (this.options.allErrors) {
2400
+ if (this.options.allErrors || this.noreturn) {
2324
2401
  result += ");";
2325
2402
  }
2326
2403
  else {
@@ -5067,7 +5144,7 @@ class SchemaResolver {
5067
5144
  throw Error(`[${mode}] Unknown type ${type}`);
5068
5145
  }
5069
5146
  }
5070
- for (const keyword of allPossibleIncompatible) {
5147
+ for (const keyword of Array.from(allPossibleIncompatible)) {
5071
5148
  const incompatibleWithAll = types.every((type) => incompatibleKeywords[type]?.includes(keyword));
5072
5149
  if (incompatibleWithAll && schema[keyword] !== undefined) {
5073
5150
  throw Error(`[${mode}] Keyword "${keyword}" is incompatible with ${types.length > 1 ? "all types" : "type"} "${types.join(", ")}"`);
@@ -5629,6 +5706,7 @@ class JetValidator {
5629
5706
  const fconfig = {
5630
5707
  ...config,
5631
5708
  };
5709
+ const has$Data = compileContext.uses$Data;
5632
5710
  if (typeof resolvedSchema === "boolean")
5633
5711
  fconfig.allErrors = false;
5634
5712
  const compiler = new Compiler(refables, mainSchema, fconfig, this, allKeywords, compileContext, false);
@@ -5661,22 +5739,6 @@ class JetValidator {
5661
5739
  if (validate)
5662
5740
  customKeywords.set(keywordDef, validate);
5663
5741
  }
5664
- if (typeof resolvedSchema !== "boolean") {
5665
- if (allFormats.size > 0) {
5666
- for (const validatorKey of allFormats) {
5667
- const validator = this.formatValidators[validatorKey];
5668
- if (validator) {
5669
- if (typeof validator === "function" ||
5670
- validator instanceof RegExp) {
5671
- formatValidators[validatorKey] = validator;
5672
- }
5673
- else {
5674
- formatValidators[validatorKey] = validator.validate;
5675
- }
5676
- }
5677
- }
5678
- }
5679
- }
5680
5742
  const asyncPrefix = config.async ? "async " : "";
5681
5743
  let functionDeclaration = "validate(rootData";
5682
5744
  if (compileContext.hasRootReference) {
@@ -5709,6 +5771,40 @@ class JetValidator {
5709
5771
  regexArgs.push(new RegExp(key));
5710
5772
  }
5711
5773
  }
5774
+ if (typeof resolvedSchema !== "boolean") {
5775
+ if (has$Data) {
5776
+ const formatKeys = Array.isArray(fconfig.formats) && fconfig.formats.length > 0
5777
+ ? fconfig.formats
5778
+ : Object.keys(this.formatValidators);
5779
+ for (const validatorKey of formatKeys) {
5780
+ const validator = this.formatValidators[validatorKey];
5781
+ if (validator) {
5782
+ if (typeof validator === "function" ||
5783
+ validator instanceof RegExp) {
5784
+ formatValidators[validatorKey] = validator;
5785
+ }
5786
+ else {
5787
+ formatValidators[validatorKey] = validator.validate;
5788
+ }
5789
+ }
5790
+ }
5791
+ }
5792
+ else if (allFormats.size > 0) {
5793
+ for (const validatorKey of allFormats) {
5794
+ const validator = this.formatValidators[validatorKey];
5795
+ if (validator) {
5796
+ if (typeof validator === "function" ||
5797
+ validator instanceof RegExp) {
5798
+ formatValidators[validatorKey] = validator;
5799
+ }
5800
+ else {
5801
+ formatValidators[validatorKey] = validator.validate;
5802
+ }
5803
+ }
5804
+ }
5805
+ }
5806
+ }
5807
+ Object.values(formatValidators);
5712
5808
  return new Function("formatValidators", "deepEqual", "canonicalStringify", "customKeywords", "len_of", ...regexParams, finalSource)(formatValidators, deepEqual, canonicalStringify, customKeywords, len_of, ...regexArgs);
5713
5809
  }
5714
5810
  compile(fschema, config) {