@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.
@@ -251,7 +251,6 @@
251
251
  this.validateKeywords = new Set();
252
252
  this.notLogic = false;
253
253
  this.noreturn = false;
254
- this.neutralError = false;
255
254
  this.standAlone = false;
256
255
  this.hasCompileKeyword = false;
257
256
  this.needslen_of = false;
@@ -444,11 +443,10 @@
444
443
  return src.join("");
445
444
  }
446
445
  const schema = rootSchema;
447
- const varName = (schema.default === undefined || !this.options.useDefaults) &&
448
- !this.options.removeAdditional &&
449
- !this.options.coerceTypes
446
+ const varName = accessPattern === "rootData" ||
447
+ (inlined && (schema.default === undefined || !this.options.useDefaults))
450
448
  ? accessPattern
451
- : "var" + counter++;
449
+ : "jv" + counter++;
452
450
  this.initializeDefault(src, schema, varName, accessPattern, inlined);
453
451
  let shouldTrackProps;
454
452
  let shouldTrackItems;
@@ -492,11 +490,16 @@
492
490
  return src.join("");
493
491
  }
494
492
  initializeDefault(src, schema, varName, accessPattern, inlined) {
495
- if (schema.default !== undefined && this.options.useDefaults) {
496
- src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
497
- }
498
- else if (this.options.removeAdditional || this.options.coerceTypes) {
499
- src.push(`let ${varName} = ${accessPattern};`);
493
+ if (accessPattern !== "rootData") {
494
+ if (schema.default !== undefined && this.options.useDefaults) {
495
+ src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
496
+ }
497
+ else if (!inlined) {
498
+ const keyword = this.options.removeAdditional || this.options.coerceTypes
499
+ ? "let"
500
+ : "const";
501
+ src.push(`${keyword} ${varName} = ${accessPattern};`);
502
+ }
500
503
  }
501
504
  if (this.options.coerceTypes) {
502
505
  if (schema.type === "number" || schema.type === "integer") {
@@ -605,7 +608,6 @@
605
608
  }
606
609
  }
607
610
  initializeSchemaRefables(src, schema, varName, pathContext, trackingState, extra) {
608
- var _a;
609
611
  const funcValidator = "func" + counter++;
610
612
  const callArgs = this.buildRefCallArgs(varName, pathContext, trackingState, "#");
611
613
  const awaitPrefix = this.options.async ? "await " : "";
@@ -613,16 +615,25 @@
613
615
  src.push(`if(${extra.before} true){`);
614
616
  src.push(`const ${funcValidator}Result = ${awaitPrefix}${schema.__functionName}${callArgs};`);
615
617
  if (this.options.allErrors) {
616
- src.push(`if (!${funcValidator}Result) {${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);${extra.refAfter || extra.after}}`);
618
+ src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);`}}`);
617
619
  }
618
620
  else {
619
- src.push(`if (!${funcValidator}Result){${this.mainFunctionName}.errors = ${schema.__functionName}.errors;${(_a = extra.refAfter) !== null && _a !== void 0 ? _a : extra.after}${this.noreturn ? "" : "return false;"}}`);
621
+ if (this.noreturn) {
622
+ 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]);`}}`);
623
+ }
624
+ else {
625
+ if (this.mainFunctionName === schema.__functionName) {
626
+ src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
627
+ }
628
+ else {
629
+ src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${schema.__functionName}.errors;return false;`}}`);
630
+ }
631
+ }
620
632
  }
621
633
  if (extra.before != "")
622
634
  src.push(`}`);
623
635
  }
624
636
  handleReference(src, schema, varName, pathContext, trackingState, extra) {
625
- var _a;
626
637
  const refType = schema.$ref ? "$ref" : "$dynamicRef";
627
638
  const refValue = schema.$ref || schema.$dynamicRef;
628
639
  if (refValue === "*unavailable") {
@@ -643,10 +654,20 @@
643
654
  src.push(`if(${extra.before} true){`);
644
655
  src.push(`const ${refValidator}Result = ${awaitPrefix}${functionName}${callArgs};`);
645
656
  if (this.options.allErrors) {
646
- src.push(`if (!${refValidator}Result) {${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);${extra.refAfter || extra.after}}`);
657
+ src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);`}}`);
647
658
  }
648
659
  else {
649
- src.push(`if (!${refValidator}Result){${this.mainFunctionName}.errors = ${functionName}.errors;${(_a = extra.refAfter) !== null && _a !== void 0 ? _a : extra.after}${this.noreturn ? "" : "return false;"}}`);
660
+ if (this.noreturn) {
661
+ 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]);`}}`);
662
+ }
663
+ else {
664
+ if (this.mainFunctionName === functionName) {
665
+ src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
666
+ }
667
+ else {
668
+ src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${functionName}.errors;return false;`}}`);
669
+ }
670
+ }
650
671
  }
651
672
  if (extra.before != "")
652
673
  src.push(`}`);
@@ -665,12 +686,12 @@
665
686
  return `(${args.join(", ")})`;
666
687
  }
667
688
  handleLogicalOperators(src, schema, varName, pathContext, trackingState, extra) {
689
+ if (schema.allOf)
690
+ this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
668
691
  if (schema.not)
669
692
  this.handleNotOperator(src, schema, varName, pathContext, extra);
670
693
  if (schema.anyOf)
671
694
  this.handleAnyOfOperator(src, schema, varName, pathContext, trackingState, extra);
672
- if (schema.allOf)
673
- this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
674
695
  if (schema.oneOf)
675
696
  this.handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra);
676
697
  }
@@ -699,15 +720,17 @@
699
720
  })}${extra.after}};`);
700
721
  }
701
722
  handleAnyOfOperator(src, schema, varName, pathContext, trackingState, extra) {
702
- var _a;
703
723
  if (!schema.anyOf)
704
724
  return;
705
725
  let firstLength = "";
706
726
  const anyOfValid = "anyOfValid" + counter++;
707
727
  src.push(`let ${anyOfValid} = false;`);
708
- const anyOfError = "anyOfErr" + counter++;
709
- if (!this.options.allErrors && !this.notLogic)
728
+ const anyOfError = this.noreturn
729
+ ? this.errorVariable
730
+ : "anyOfErr" + counter++;
731
+ if (!this.options.allErrors && !this.noreturn)
710
732
  src.push(`let ${anyOfError} = [];`);
733
+ const error = this.errorVariable;
711
734
  schema.anyOf.forEach((subSchema, index) => {
712
735
  const branch = `branch${counter++}Valid`;
713
736
  if (!this.options.allErrors)
@@ -718,24 +741,27 @@
718
741
  const configs = this.createSubschemaOptions(trackingState, pathContext, `anyOf/${index}`, schema);
719
742
  configs.pathContext.alt = `${pathContext.schema}/anyOf/${index}`;
720
743
  configs.pathContext.alt2 = `${pathContext.schema}/anyOf`;
744
+ let errorCountVar = "anyErrCnt" + counter++;
721
745
  if (this.options.allErrors) {
722
746
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
723
747
  }
724
748
  else {
749
+ this.errorVariable = anyOfError;
725
750
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
726
751
  before: `${branch} && `,
727
- after: `${branch} = false;${this.notLogic ? "" : `${anyOfError}.push(${this.mainFunctionName}.errors[0]);`}`,
728
- refAfter: `${branch} = false;${this.notLogic ? "" : `${anyOfError} = ${anyOfError}.concat(${this.mainFunctionName}.errors);`}`,
752
+ after: `${branch} = false;`,
729
753
  }, true);
730
754
  }
731
- this.noreturn = noreturn;
732
- let errorCountVar;
733
755
  if (this.options.allErrors) {
734
- errorCountVar = "anyErrCnt" + counter++;
735
756
  src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
736
757
  if (index === 0)
737
758
  firstLength = errorCountVar;
738
759
  }
760
+ else if (index === 0) {
761
+ src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
762
+ firstLength = errorCountVar;
763
+ }
764
+ this.noreturn = noreturn;
739
765
  if (index > 0 &&
740
766
  !trackingState.shouldTrackEvaluatedProperties &&
741
767
  !trackingState.shouldTrackEvaluatedItems) {
@@ -770,28 +796,36 @@
770
796
  }
771
797
  });
772
798
  if (this.options.allErrors) {
773
- src.push(`if (${anyOfValid}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else{${extra.after}}` : ""}`);
799
+ src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else if(!${anyOfValid}){${extra.after}}` : ""}`);
774
800
  }
775
801
  else {
776
- src.push(`if (${anyOfValid}){${this.mainFunctionName}.errors = undefined}else {${this.notLogic ? "" : `${this.mainFunctionName}.errors = ${anyOfError};`}${(_a = extra.refAfter) !== null && _a !== void 0 ? _a : extra.after}${this.noreturn ? "" : "return false;"}}`);
802
+ if (this.noreturn) {
803
+ src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(!${anyOfValid}){${extra.after}}`);
804
+ }
805
+ else {
806
+ 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;`}}`);
807
+ }
808
+ this.errorVariable = error;
777
809
  }
778
810
  }
779
811
  handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra) {
780
- var _a;
781
812
  if (!schema.oneOf)
782
813
  return;
783
814
  let firstLength = "";
784
- const oneOfErrors = `oneOfErrors${counter++}`;
815
+ const oneOfErrors = this.noreturn
816
+ ? this.errorVariable
817
+ : `oneOfErrors${counter++}`;
785
818
  const validSchemaCount = "validSchemaCount" + counter++;
786
819
  src.push(`let ${validSchemaCount} = 0;`);
787
- if (!this.options.allErrors)
820
+ if (!this.options.allErrors && !this.noreturn)
788
821
  src.push(`let ${oneOfErrors} = [];`);
822
+ const noreturn = this.noreturn;
823
+ const error = this.errorVariable;
789
824
  schema.oneOf.forEach((subSchema, index) => {
790
825
  const branch = `branch${counter++}Valid`;
791
- if (!this.options.allErrors && !this.notLogic)
826
+ if (!this.options.allErrors)
792
827
  src.push(`let ${branch} = true;`);
793
828
  let validatorFn;
794
- const noreturn = this.noreturn;
795
829
  this.noreturn = true;
796
830
  const configs = this.createSubschemaOptions(trackingState, pathContext, `oneOf/${index}`, schema);
797
831
  configs.pathContext.alt = `${pathContext.schema}/oneOf/${index}`;
@@ -800,20 +834,22 @@
800
834
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
801
835
  }
802
836
  else {
837
+ this.errorVariable = oneOfErrors;
803
838
  validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
804
839
  before: `${branch} && `,
805
- after: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors}.push(${this.mainFunctionName}.errors[0]);`}`,
806
- refAfter: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors} = ${oneOfErrors}.concat(${this.mainFunctionName}.errors);`}`,
840
+ after: `${branch} = false;`,
807
841
  }, true);
808
842
  }
809
- this.noreturn = noreturn;
810
- let errorCountVar;
843
+ let errorCountVar = "oneErrCnt" + counter++;
811
844
  if (this.options.allErrors) {
812
- errorCountVar = "oneErrCnt" + counter;
813
845
  src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
814
846
  if (index === 0)
815
847
  firstLength = errorCountVar;
816
848
  }
849
+ else if (index === 0) {
850
+ src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
851
+ firstLength = errorCountVar;
852
+ }
817
853
  if (index > 0 &&
818
854
  !trackingState.shouldTrackEvaluatedProperties &&
819
855
  !trackingState.shouldTrackEvaluatedItems) {
@@ -848,7 +884,7 @@
848
884
  }
849
885
  });
850
886
  if (this.options.allErrors) {
851
- src.push(`if (${validSchemaCount} == 1) {${this.errorVariable}.length = ${firstLength};} else{${this.buildErrorReturn(pathContext, {
887
+ src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
852
888
  keyword: "oneOf",
853
889
  value: varName,
854
890
  message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
@@ -856,14 +892,23 @@
856
892
  })}${extra.after}}`);
857
893
  }
858
894
  else {
859
- const noreturn = this.noreturn;
860
- this.noreturn = true;
861
- src.push(`if (${validSchemaCount} == 1){${this.mainFunctionName}.errors = undefined}else {${this.buildErrorReturn(pathContext, {
862
- keyword: "oneOf",
863
- value: varName,
864
- message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
865
- expected: '"exactly one schema"',
866
- })}${this.notLogic ? "" : `${oneOfErrors}.push(${this.mainFunctionName}.errors[0]);${this.mainFunctionName}.errors = ${oneOfErrors};`}${(_a = extra.refAfter) !== null && _a !== void 0 ? _a : extra.after}${noreturn ? "" : "return false;"}}`);
895
+ if (noreturn) {
896
+ src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
897
+ keyword: "oneOf",
898
+ value: varName,
899
+ message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
900
+ expected: '"exactly one schema"',
901
+ })}${extra.after}}`);
902
+ }
903
+ else {
904
+ src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
905
+ keyword: "oneOf",
906
+ value: varName,
907
+ message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
908
+ expected: '"exactly one schema"',
909
+ })}${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${this.errorVariable};return false;`}}`);
910
+ }
911
+ this.errorVariable = error;
867
912
  this.noreturn = noreturn;
868
913
  }
869
914
  }
@@ -1329,11 +1374,15 @@
1329
1374
  else {
1330
1375
  comparisonTarget = schema.multipleOf;
1331
1376
  }
1332
- src.push(`const multipleOf = ${comparisonTarget};
1333
- const quotient = ${varName} / multipleOf;
1334
- const rounded = Math.round(quotient);
1335
- const tolerance = Math.abs(quotient) * Number.EPSILON;
1336
- if (${extra.before}multipleOf === 0 || !isFinite(quotient) || Math.abs(quotient - rounded) > tolerance) {${this.buildErrorReturn(pathContext, {
1377
+ const multipleOfVar = "multipleOf" + counter++;
1378
+ const quotientVar = "quotient" + counter++;
1379
+ const roundedVar = "rounded" + counter++;
1380
+ const toleranceVar = "tolerance" + counter++;
1381
+ src.push(`const ${multipleOfVar} = ${comparisonTarget};
1382
+ const ${quotientVar} = ${varName} / ${multipleOfVar};
1383
+ const ${roundedVar} = Math.round(${quotientVar});
1384
+ const ${toleranceVar} = Math.abs(${quotientVar}) * Number.EPSILON;
1385
+ if (${extra.before}${multipleOfVar} === 0 || !isFinite(${quotientVar}) || Math.abs(${quotientVar} - ${roundedVar}) > ${toleranceVar}) {${this.buildErrorReturn(pathContext, {
1337
1386
  keyword: "multipleOf",
1338
1387
  value: varName,
1339
1388
  message: `"Value must be a multiple of " + ${comparisonTarget}`,
@@ -1437,7 +1486,8 @@
1437
1486
  else {
1438
1487
  src.push(`const formatValidator = formatValidators[${formatKeyVar}].validate ?? formatValidators[${formatKeyVar}];`);
1439
1488
  }
1440
- 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, {
1489
+ const isValid = "isValid" + counter++;
1490
+ 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, {
1441
1491
  keyword: "format",
1442
1492
  value: varName,
1443
1493
  message: `"Failed to validate value against format "+${formatKeyVar}`,
@@ -1447,7 +1497,7 @@
1447
1497
  else {
1448
1498
  const data = this.jetValidator.getFormat(schema.format);
1449
1499
  if (!data) {
1450
- throw new Error(`Format '${schema.format}' not found`);
1500
+ console.warn(`Format '${schema.format}' not found will be ignored`);
1451
1501
  }
1452
1502
  const format = typeof data === "object" && "validate" in data ? data.validate : data;
1453
1503
  const formatType = typeof data === "object" &&
@@ -1546,14 +1596,16 @@
1546
1596
  const resolvedPath = resolveDataPointerAtCompileTime(pointer, pathContext.$data, this.refCall);
1547
1597
  const requiredArrayExpr = generateArrayDataRef(src, resolvedPath, extra);
1548
1598
  src.push(`if (${extra.before}${requiredArrayExpr}) {`);
1549
- src.push(`for (let i = 0; i < ${requiredArrayExpr}.length; i++) {`);
1550
- src.push(`const prop = ${requiredArrayExpr}[i];`);
1551
- addEvaluatedProperty(src, "prop", trackingState);
1552
- src.push(`if (${extra.before}${varName}[prop] === undefined) {${this.buildErrorReturn(pathContext, {
1599
+ const i = "i" + counter++;
1600
+ src.push(`for (let ${i} = 0; ${i} < ${requiredArrayExpr}.length; ${i}++) {`);
1601
+ const prop = "prop" + counter++;
1602
+ src.push(`const ${prop} = ${requiredArrayExpr}[${i}];`);
1603
+ addEvaluatedProperty(src, prop, trackingState);
1604
+ src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
1553
1605
  keyword: "required",
1554
1606
  value: varName,
1555
- message: `"Missing required field: " + prop + " in data."`,
1556
- expected: "prop",
1607
+ message: `"Missing required field: " + ${prop} + " in data."`,
1608
+ expected: `${prop}`,
1557
1609
  schemaPath: `${pathContext.schema}`,
1558
1610
  })}${extra.after}}`);
1559
1611
  src.push(`}`);
@@ -1567,23 +1619,39 @@
1567
1619
  if (Array.isArray(schema.required)) {
1568
1620
  if (this.options.allErrors ||
1569
1621
  schema.required.length > this.options.loopRequired) {
1570
- const arr = JSON.stringify(schema.required);
1571
- const arrVar = `arr${src.length}${counter++}`;
1572
- const iVar = `i${src.length}${counter++}`;
1573
- src.push(`const ${arrVar} = ${arr};`);
1574
1622
  if (extra.before != "")
1575
1623
  src.push(`if(${extra.before} true){`);
1576
- src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
1577
- src.push(`const prop = ${arrVar}[${iVar}];`);
1578
- addEvaluatedProperty(src, "prop", trackingState);
1579
- src.push(`if (${extra.before}${varName}[prop] === undefined) {${this.buildErrorReturn(pathContext, {
1580
- keyword: "required",
1581
- value: varName,
1582
- message: `"Missing required field: " + prop + " in data."`,
1583
- expected: "prop",
1584
- schemaPath: `${pathContext.schema}`,
1585
- })}${extra.after}}`);
1586
- src.push(`}`);
1624
+ if (schema.required.length > this.options.loopRequired) {
1625
+ const arr = JSON.stringify(schema.required);
1626
+ const arrVar = `arr${src.length}${counter++}`;
1627
+ const iVar = `i${src.length}${counter++}`;
1628
+ src.push(`const ${arrVar} = ${arr};`);
1629
+ src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
1630
+ const prop = "prop" + counter++;
1631
+ src.push(`const ${prop} = ${arrVar}[${iVar}];`);
1632
+ addEvaluatedProperty(src, prop, trackingState);
1633
+ src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
1634
+ keyword: "required",
1635
+ value: varName,
1636
+ message: `"Missing required field: " + ${prop} + " in data."`,
1637
+ expected: `${prop}`,
1638
+ schemaPath: `${pathContext.schema}`,
1639
+ })}${extra.after}}`);
1640
+ src.push(`}`);
1641
+ }
1642
+ else {
1643
+ for (const prop of schema.required) {
1644
+ const errorMessage = JSON.stringify(`Missing required field: ${prop} in data.`);
1645
+ const pstring = JSON.stringify(prop);
1646
+ src.push(`if (${extra.before}${varName}[${pstring}] === undefined) {${this.buildErrorReturn(pathContext, {
1647
+ keyword: "required",
1648
+ value: varName,
1649
+ message: errorMessage,
1650
+ expected: `${pstring}`,
1651
+ schemaPath: `${pathContext.schema}`,
1652
+ })}${extra.after}}`);
1653
+ }
1654
+ }
1587
1655
  if (extra.before != "")
1588
1656
  src.push(`}`);
1589
1657
  }
@@ -1636,21 +1704,22 @@
1636
1704
  handlePatternProperties(src, schema, varName, pathContext, trackingState, extra) {
1637
1705
  if (extra.before != "")
1638
1706
  src.push(`if(${extra.before} true){`);
1639
- src.push(`for (const key in ${varName}) {`);
1707
+ const key = "key" + counter++;
1708
+ src.push(`for (const ${key} in ${varName}) {`);
1640
1709
  Object.getOwnPropertyNames(schema.patternProperties).forEach((pattern) => {
1641
1710
  let pname = this.regexCache.get(pattern);
1642
1711
  if (!pname) {
1643
1712
  pname = "patternProp" + counter++;
1644
1713
  this.regexCache.set(pattern, pname);
1645
1714
  }
1646
- src.push(`if (${pname}.test(key)) {`);
1647
- addEvaluatedProperty(src, "key", trackingState);
1715
+ src.push(`if (${pname}.test(${key})) {`);
1716
+ addEvaluatedProperty(src, key, trackingState);
1648
1717
  const parent = trackingState.parentHasUnevaluatedProperties ||
1649
1718
  trackingState.hasOwnUnevaluatedProperties;
1650
1719
  const patternValidation = this.compileSchema(schema.patternProperties[pattern], {
1651
1720
  schema: `${pathContext.schema}/patternProperties/${JSON.stringify(pattern)}`,
1652
- data: `${pathContext.data}/\${key}`,
1653
- $data: `${pathContext.$data}/\${key}`,
1721
+ data: `${pathContext.data}/\${${key}}`,
1722
+ $data: `${pathContext.$data}/\${${key}}`,
1654
1723
  alt: pathContext.alt,
1655
1724
  alt2: pathContext.alt2,
1656
1725
  }, {
@@ -1659,7 +1728,7 @@
1659
1728
  parentUnevaluatedPropVar: parent
1660
1729
  ? trackingState.unevaluatedPropVar
1661
1730
  : undefined,
1662
- }, `${varName}[key]`, extra);
1731
+ }, `${varName}[${key}]`, extra);
1663
1732
  src.push(patternValidation, "}");
1664
1733
  });
1665
1734
  src.push("}");
@@ -1671,12 +1740,13 @@
1671
1740
  const explicitProps = Array.from(allowedProperties);
1672
1741
  if (extra.before != "")
1673
1742
  src.push(`if(${extra.before} true){`);
1674
- src.push(`for (const key in ${varName}) {`);
1675
- addEvaluatedProperty(src, "key", trackingState);
1743
+ const key = "key" + counter++;
1744
+ src.push(`for (const ${key} in ${varName}) {`);
1745
+ addEvaluatedProperty(src, key, trackingState);
1676
1746
  let checks = [];
1677
1747
  if (explicitProps.length > 0) {
1678
1748
  const allowedCheck = explicitProps
1679
- .map((key) => `key === ${JSON.stringify(key)}`)
1749
+ .map((keyItem) => `${key} === ${JSON.stringify(keyItem)}`)
1680
1750
  .join(" || ");
1681
1751
  checks.push(allowedCheck);
1682
1752
  }
@@ -1688,7 +1758,7 @@
1688
1758
  pname = "patternProp" + counter++;
1689
1759
  this.regexCache.set(pattern, pname);
1690
1760
  }
1691
- return `${pname}.test(key)`;
1761
+ return `${pname}.test(${key})`;
1692
1762
  })
1693
1763
  .join(" || ");
1694
1764
  checks.push(patternCheck);
@@ -1699,17 +1769,18 @@
1699
1769
  }
1700
1770
  const additionalPropValidation = this.compileSchema(schema.additionalProperties, {
1701
1771
  schema: `${pathContext.schema}/additionalProperties`,
1702
- data: `${pathContext.data}/\${key}`,
1703
- $data: `${pathContext.$data}/\${key}`,
1772
+ data: `${pathContext.data}/\${${key}}`,
1773
+ $data: `${pathContext.$data}/\${${key}}`,
1704
1774
  alt: pathContext.alt,
1705
1775
  alt2: pathContext.alt2,
1706
- }, {}, `${varName}[key]`, extra);
1776
+ }, {}, `${varName}[${key}]`, extra);
1707
1777
  src.push(additionalPropValidation, "}");
1708
1778
  if (extra.before != "")
1709
1779
  src.push(`}`);
1710
1780
  }
1711
1781
  handlePropertyConstraints(src, schema, varName, pathContext, extra) {
1712
- src.push(`const objKeys = Object.keys(${varName});`);
1782
+ const objKeys = "objKeys" + counter++;
1783
+ src.push(`const ${objKeys} = Object.keys(${varName});`);
1713
1784
  if (schema.minProperties !== undefined) {
1714
1785
  const isDataRef = this.options.$data && isDataReference(schema.minProperties);
1715
1786
  let comparisonTarget;
@@ -1721,9 +1792,9 @@
1721
1792
  else {
1722
1793
  comparisonTarget = schema.minProperties;
1723
1794
  }
1724
- src.push(`if (${extra.before}objKeys.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1795
+ src.push(`if (${extra.before}${objKeys}.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1725
1796
  keyword: "minProperties",
1726
- value: "objKeys.length",
1797
+ value: `${objKeys}.length`,
1727
1798
  message: `"Object must have at least " + ${comparisonTarget} + " properties."`,
1728
1799
  expected: comparisonTarget,
1729
1800
  })}${extra.after}}`);
@@ -1742,9 +1813,9 @@
1742
1813
  else {
1743
1814
  comparisonTarget = schema.maxProperties;
1744
1815
  }
1745
- src.push(`if (${extra.before}objKeys.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1816
+ src.push(`if (${extra.before}${objKeys}.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
1746
1817
  keyword: "maxProperties",
1747
- value: "objKeys.length",
1818
+ value: `${objKeys}.length`,
1748
1819
  message: `"Object must have at most " + ${comparisonTarget} + " properties."`,
1749
1820
  expected: comparisonTarget,
1750
1821
  })}${extra.after}}`);
@@ -1756,14 +1827,15 @@
1756
1827
  handlePropertyNames(src, schema, varName, pathContext, extra) {
1757
1828
  if (extra.before != "")
1758
1829
  src.push(`if(${extra.before} true){`);
1759
- src.push(`for (const key in ${varName}) {`);
1830
+ const key = "key" + counter++;
1831
+ src.push(`for (const ${key} in ${varName}) {`);
1760
1832
  const propertyNameValidation = this.compileSchema(schema.propertyNames, {
1761
1833
  schema: `${pathContext.schema}/propertyNames`,
1762
- data: `${pathContext.data}/\${key}`,
1763
- $data: `${pathContext.$data}/\${key}`,
1834
+ data: `${pathContext.data}/\${${key}}`,
1835
+ $data: `${pathContext.$data}/\${${key}}`,
1764
1836
  alt: pathContext.alt,
1765
1837
  alt2: pathContext.alt2,
1766
- }, {}, `key`, extra);
1838
+ }, {}, key, extra);
1767
1839
  src.push(propertyNameValidation, "}");
1768
1840
  if (extra.before != "")
1769
1841
  src.push(`}`);
@@ -1876,7 +1948,8 @@
1876
1948
  const evalSet = trackingState.unevaluatedPropVar;
1877
1949
  if (extra.before != "")
1878
1950
  src.push(`if(${extra.before} true){`);
1879
- src.push(`const ${unName} = [];`, `for (const key in ${varName}) {`, `if (!${evalSet}.has(key)) {`, `${unName}.push(key);`, `}`, `}`);
1951
+ const key = "key" + counter++;
1952
+ src.push(`const ${unName} = [];`, `for (const ${key} in ${varName}) {`, `if (!${evalSet}.has(${key})) {`, `${unName}.push(${key});`, `}`, `}`);
1880
1953
  if (schema.unevaluatedProperties === false) {
1881
1954
  src.push(`if (${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
1882
1955
  keyword: "unevaluatedProperties",
@@ -1889,7 +1962,8 @@
1889
1962
  }
1890
1963
  else if (schema.unevaluatedProperties === true) {
1891
1964
  if (trackingState.parentHasUnevaluatedProperties) {
1892
- src.push(`for(const key in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(key)}`);
1965
+ const key = "key" + counter++;
1966
+ src.push(`for(const ${key} in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(${key})}`);
1893
1967
  }
1894
1968
  }
1895
1969
  else {
@@ -2207,7 +2281,8 @@
2207
2281
  const evalSet = trackingState.unevaluatedItemVar;
2208
2282
  if (extra.before != "")
2209
2283
  src.push(`if(${extra.before} true){`);
2210
- src.push(`const ${unName} = [];`, `for (let i = 0; i < ${varName}.length; i++) {`, `if (!${evalSet}.has(i)) {`, `${unName}.push(i);`, `}`, `}`);
2284
+ const i = "i" + counter++;
2285
+ src.push(`const ${unName} = [];`, `for (let ${i} = 0; ${i} < ${varName}.length; ${i}++) {`, `if (!${evalSet}.has(${i})) {`, `${unName}.push(${i});`, `}`, `}`);
2211
2286
  if (schema.unevaluatedItems === false) {
2212
2287
  src.push(`if (${extra.before}${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
2213
2288
  keyword: "unevaluatedItems",
@@ -2246,9 +2321,7 @@
2246
2321
  var _a;
2247
2322
  if (this.notLogic)
2248
2323
  return "";
2249
- if (this.neutralError)
2250
- return "return false;";
2251
- let result = this.options.allErrors
2324
+ let result = this.options.allErrors || this.noreturn
2252
2325
  ? `${this.errorVariable}.push({`
2253
2326
  : `${this.mainFunctionName}.errors = [{`;
2254
2327
  const escapedDataPath = escapeTemplateString(error.dataPath || pathContext.data || "/");
@@ -2329,7 +2402,7 @@
2329
2402
  result += `,${spreads}`;
2330
2403
  }
2331
2404
  result += "}";
2332
- if (this.options.allErrors) {
2405
+ if (this.options.allErrors || this.noreturn) {
2333
2406
  result += ");";
2334
2407
  }
2335
2408
  else {
@@ -5083,7 +5156,7 @@
5083
5156
  throw Error(`[${mode}] Unknown type ${type}`);
5084
5157
  }
5085
5158
  }
5086
- for (const keyword of allPossibleIncompatible) {
5159
+ for (const keyword of Array.from(allPossibleIncompatible)) {
5087
5160
  const incompatibleWithAll = types.every((type) => { var _a; return (_a = incompatibleKeywords[type]) === null || _a === void 0 ? void 0 : _a.includes(keyword); });
5088
5161
  if (incompatibleWithAll && schema[keyword] !== undefined) {
5089
5162
  throw Error(`[${mode}] Keyword "${keyword}" is incompatible with ${types.length > 1 ? "all types" : "type"} "${types.join(", ")}"`);
@@ -5651,6 +5724,7 @@
5651
5724
  const fconfig = {
5652
5725
  ...config,
5653
5726
  };
5727
+ const has$Data = compileContext.uses$Data;
5654
5728
  if (typeof resolvedSchema === "boolean")
5655
5729
  fconfig.allErrors = false;
5656
5730
  const compiler = new Compiler(refables, mainSchema, fconfig, this, allKeywords, compileContext, false);
@@ -5683,22 +5757,6 @@
5683
5757
  if (validate)
5684
5758
  customKeywords.set(keywordDef, validate);
5685
5759
  }
5686
- if (typeof resolvedSchema !== "boolean") {
5687
- if (allFormats.size > 0) {
5688
- for (const validatorKey of allFormats) {
5689
- const validator = this.formatValidators[validatorKey];
5690
- if (validator) {
5691
- if (typeof validator === "function" ||
5692
- validator instanceof RegExp) {
5693
- formatValidators[validatorKey] = validator;
5694
- }
5695
- else {
5696
- formatValidators[validatorKey] = validator.validate;
5697
- }
5698
- }
5699
- }
5700
- }
5701
- }
5702
5760
  const asyncPrefix = config.async ? "async " : "";
5703
5761
  let functionDeclaration = "validate(rootData";
5704
5762
  if (compileContext.hasRootReference) {
@@ -5731,6 +5789,40 @@
5731
5789
  regexArgs.push(new RegExp(key));
5732
5790
  }
5733
5791
  }
5792
+ if (typeof resolvedSchema !== "boolean") {
5793
+ if (has$Data) {
5794
+ const formatKeys = Array.isArray(fconfig.formats) && fconfig.formats.length > 0
5795
+ ? fconfig.formats
5796
+ : Object.keys(this.formatValidators);
5797
+ for (const validatorKey of formatKeys) {
5798
+ const validator = this.formatValidators[validatorKey];
5799
+ if (validator) {
5800
+ if (typeof validator === "function" ||
5801
+ validator instanceof RegExp) {
5802
+ formatValidators[validatorKey] = validator;
5803
+ }
5804
+ else {
5805
+ formatValidators[validatorKey] = validator.validate;
5806
+ }
5807
+ }
5808
+ }
5809
+ }
5810
+ else if (allFormats.size > 0) {
5811
+ for (const validatorKey of allFormats) {
5812
+ const validator = this.formatValidators[validatorKey];
5813
+ if (validator) {
5814
+ if (typeof validator === "function" ||
5815
+ validator instanceof RegExp) {
5816
+ formatValidators[validatorKey] = validator;
5817
+ }
5818
+ else {
5819
+ formatValidators[validatorKey] = validator.validate;
5820
+ }
5821
+ }
5822
+ }
5823
+ }
5824
+ }
5825
+ Object.values(formatValidators);
5734
5826
  return new Function("formatValidators", "deepEqual", "canonicalStringify", "customKeywords", "len_of", ...regexParams, finalSource)(formatValidators, deepEqual, canonicalStringify, customKeywords, len_of, ...regexArgs);
5735
5827
  }
5736
5828
  compile(fschema, config) {