@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/README.md +25 -59
- package/dist/compileSchema.d.ts +0 -1
- package/dist/compileSchema.js +177 -100
- package/dist/compileSchema.js.map +1 -1
- package/dist/index.cjs.js +213 -117
- package/dist/index.esm.js +213 -117
- package/dist/jet-validator.js +36 -16
- package/dist/jet-validator.js.map +1 -1
- package/dist/resolver.js +1 -1
- package/dist/resolver.js.map +1 -1
- package/dist/src/compileSchema.d.ts +0 -1
- package/dist/validator.umd.js +213 -121
- package/package.json +16 -4
package/dist/index.esm.js
CHANGED
|
@@ -245,7 +245,6 @@ class Compiler {
|
|
|
245
245
|
this.validateKeywords = new Set();
|
|
246
246
|
this.notLogic = false;
|
|
247
247
|
this.noreturn = false;
|
|
248
|
-
this.neutralError = false;
|
|
249
248
|
this.standAlone = false;
|
|
250
249
|
this.hasCompileKeyword = false;
|
|
251
250
|
this.needslen_of = false;
|
|
@@ -438,11 +437,10 @@ class Compiler {
|
|
|
438
437
|
return src.join("");
|
|
439
438
|
}
|
|
440
439
|
const schema = rootSchema;
|
|
441
|
-
const varName =
|
|
442
|
-
!this.options.
|
|
443
|
-
!this.options.coerceTypes
|
|
440
|
+
const varName = accessPattern === "rootData" ||
|
|
441
|
+
(inlined && (schema.default === undefined || !this.options.useDefaults))
|
|
444
442
|
? accessPattern
|
|
445
|
-
: "
|
|
443
|
+
: "jv" + counter++;
|
|
446
444
|
this.initializeDefault(src, schema, varName, accessPattern, inlined);
|
|
447
445
|
let shouldTrackProps;
|
|
448
446
|
let shouldTrackItems;
|
|
@@ -486,11 +484,16 @@ class Compiler {
|
|
|
486
484
|
return src.join("");
|
|
487
485
|
}
|
|
488
486
|
initializeDefault(src, schema, varName, accessPattern, inlined) {
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
487
|
+
if (accessPattern !== "rootData") {
|
|
488
|
+
if (schema.default !== undefined && this.options.useDefaults) {
|
|
489
|
+
src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
|
|
490
|
+
}
|
|
491
|
+
else if (!inlined) {
|
|
492
|
+
const keyword = this.options.removeAdditional || this.options.coerceTypes
|
|
493
|
+
? "let"
|
|
494
|
+
: "const";
|
|
495
|
+
src.push(`${keyword} ${varName} = ${accessPattern};`);
|
|
496
|
+
}
|
|
494
497
|
}
|
|
495
498
|
if (this.options.coerceTypes) {
|
|
496
499
|
if (schema.type === "number" || schema.type === "integer") {
|
|
@@ -606,10 +609,20 @@ class Compiler {
|
|
|
606
609
|
src.push(`if(${extra.before} true){`);
|
|
607
610
|
src.push(`const ${funcValidator}Result = ${awaitPrefix}${schema.__functionName}${callArgs};`);
|
|
608
611
|
if (this.options.allErrors) {
|
|
609
|
-
src.push(`if (!${funcValidator}Result)
|
|
612
|
+
src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);`}}`);
|
|
610
613
|
}
|
|
611
614
|
else {
|
|
612
|
-
|
|
615
|
+
if (this.noreturn) {
|
|
616
|
+
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]);`}}`);
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
if (this.mainFunctionName === schema.__functionName) {
|
|
620
|
+
src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${schema.__functionName}.errors;return false;`}}`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
613
626
|
}
|
|
614
627
|
if (extra.before != "")
|
|
615
628
|
src.push(`}`);
|
|
@@ -635,10 +648,20 @@ class Compiler {
|
|
|
635
648
|
src.push(`if(${extra.before} true){`);
|
|
636
649
|
src.push(`const ${refValidator}Result = ${awaitPrefix}${functionName}${callArgs};`);
|
|
637
650
|
if (this.options.allErrors) {
|
|
638
|
-
src.push(`if (!${refValidator}Result)
|
|
651
|
+
src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);`}}`);
|
|
639
652
|
}
|
|
640
653
|
else {
|
|
641
|
-
|
|
654
|
+
if (this.noreturn) {
|
|
655
|
+
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]);`}}`);
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
if (this.mainFunctionName === functionName) {
|
|
659
|
+
src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${functionName}.errors;return false;`}}`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
642
665
|
}
|
|
643
666
|
if (extra.before != "")
|
|
644
667
|
src.push(`}`);
|
|
@@ -657,12 +680,12 @@ class Compiler {
|
|
|
657
680
|
return `(${args.join(", ")})`;
|
|
658
681
|
}
|
|
659
682
|
handleLogicalOperators(src, schema, varName, pathContext, trackingState, extra) {
|
|
683
|
+
if (schema.allOf)
|
|
684
|
+
this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
660
685
|
if (schema.not)
|
|
661
686
|
this.handleNotOperator(src, schema, varName, pathContext, extra);
|
|
662
687
|
if (schema.anyOf)
|
|
663
688
|
this.handleAnyOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
664
|
-
if (schema.allOf)
|
|
665
|
-
this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
666
689
|
if (schema.oneOf)
|
|
667
690
|
this.handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
668
691
|
}
|
|
@@ -696,9 +719,12 @@ class Compiler {
|
|
|
696
719
|
let firstLength = "";
|
|
697
720
|
const anyOfValid = "anyOfValid" + counter++;
|
|
698
721
|
src.push(`let ${anyOfValid} = false;`);
|
|
699
|
-
const anyOfError =
|
|
700
|
-
|
|
722
|
+
const anyOfError = this.noreturn
|
|
723
|
+
? this.errorVariable
|
|
724
|
+
: "anyOfErr" + counter++;
|
|
725
|
+
if (!this.options.allErrors && !this.noreturn)
|
|
701
726
|
src.push(`let ${anyOfError} = [];`);
|
|
727
|
+
const error = this.errorVariable;
|
|
702
728
|
schema.anyOf.forEach((subSchema, index) => {
|
|
703
729
|
const branch = `branch${counter++}Valid`;
|
|
704
730
|
if (!this.options.allErrors)
|
|
@@ -709,24 +735,27 @@ class Compiler {
|
|
|
709
735
|
const configs = this.createSubschemaOptions(trackingState, pathContext, `anyOf/${index}`, schema);
|
|
710
736
|
configs.pathContext.alt = `${pathContext.schema}/anyOf/${index}`;
|
|
711
737
|
configs.pathContext.alt2 = `${pathContext.schema}/anyOf`;
|
|
738
|
+
let errorCountVar = "anyErrCnt" + counter++;
|
|
712
739
|
if (this.options.allErrors) {
|
|
713
740
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
|
|
714
741
|
}
|
|
715
742
|
else {
|
|
743
|
+
this.errorVariable = anyOfError;
|
|
716
744
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
|
|
717
745
|
before: `${branch} && `,
|
|
718
|
-
after: `${branch} = false
|
|
719
|
-
refAfter: `${branch} = false;${this.notLogic ? "" : `${anyOfError} = ${anyOfError}.concat(${this.mainFunctionName}.errors);`}`,
|
|
746
|
+
after: `${branch} = false;`,
|
|
720
747
|
}, true);
|
|
721
748
|
}
|
|
722
|
-
this.noreturn = noreturn;
|
|
723
|
-
let errorCountVar;
|
|
724
749
|
if (this.options.allErrors) {
|
|
725
|
-
errorCountVar = "anyErrCnt" + counter++;
|
|
726
750
|
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
727
751
|
if (index === 0)
|
|
728
752
|
firstLength = errorCountVar;
|
|
729
753
|
}
|
|
754
|
+
else if (index === 0) {
|
|
755
|
+
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
756
|
+
firstLength = errorCountVar;
|
|
757
|
+
}
|
|
758
|
+
this.noreturn = noreturn;
|
|
730
759
|
if (index > 0 &&
|
|
731
760
|
!trackingState.shouldTrackEvaluatedProperties &&
|
|
732
761
|
!trackingState.shouldTrackEvaluatedItems) {
|
|
@@ -761,27 +790,36 @@ class Compiler {
|
|
|
761
790
|
}
|
|
762
791
|
});
|
|
763
792
|
if (this.options.allErrors) {
|
|
764
|
-
src.push(`if (${anyOfValid}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else{${extra.after}}` : ""}`);
|
|
793
|
+
src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else if(!${anyOfValid}){${extra.after}}` : ""}`);
|
|
765
794
|
}
|
|
766
795
|
else {
|
|
767
|
-
|
|
796
|
+
if (this.noreturn) {
|
|
797
|
+
src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(!${anyOfValid}){${extra.after}}`);
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
800
|
+
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;`}}`);
|
|
801
|
+
}
|
|
802
|
+
this.errorVariable = error;
|
|
768
803
|
}
|
|
769
804
|
}
|
|
770
805
|
handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra) {
|
|
771
806
|
if (!schema.oneOf)
|
|
772
807
|
return;
|
|
773
808
|
let firstLength = "";
|
|
774
|
-
const oneOfErrors =
|
|
809
|
+
const oneOfErrors = this.noreturn
|
|
810
|
+
? this.errorVariable
|
|
811
|
+
: `oneOfErrors${counter++}`;
|
|
775
812
|
const validSchemaCount = "validSchemaCount" + counter++;
|
|
776
813
|
src.push(`let ${validSchemaCount} = 0;`);
|
|
777
|
-
if (!this.options.allErrors)
|
|
814
|
+
if (!this.options.allErrors && !this.noreturn)
|
|
778
815
|
src.push(`let ${oneOfErrors} = [];`);
|
|
816
|
+
const noreturn = this.noreturn;
|
|
817
|
+
const error = this.errorVariable;
|
|
779
818
|
schema.oneOf.forEach((subSchema, index) => {
|
|
780
819
|
const branch = `branch${counter++}Valid`;
|
|
781
|
-
if (!this.options.allErrors
|
|
820
|
+
if (!this.options.allErrors)
|
|
782
821
|
src.push(`let ${branch} = true;`);
|
|
783
822
|
let validatorFn;
|
|
784
|
-
const noreturn = this.noreturn;
|
|
785
823
|
this.noreturn = true;
|
|
786
824
|
const configs = this.createSubschemaOptions(trackingState, pathContext, `oneOf/${index}`, schema);
|
|
787
825
|
configs.pathContext.alt = `${pathContext.schema}/oneOf/${index}`;
|
|
@@ -790,20 +828,22 @@ class Compiler {
|
|
|
790
828
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
|
|
791
829
|
}
|
|
792
830
|
else {
|
|
831
|
+
this.errorVariable = oneOfErrors;
|
|
793
832
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
|
|
794
833
|
before: `${branch} && `,
|
|
795
|
-
after: `${branch} = false
|
|
796
|
-
refAfter: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors} = ${oneOfErrors}.concat(${this.mainFunctionName}.errors);`}`,
|
|
834
|
+
after: `${branch} = false;`,
|
|
797
835
|
}, true);
|
|
798
836
|
}
|
|
799
|
-
|
|
800
|
-
let errorCountVar;
|
|
837
|
+
let errorCountVar = "oneErrCnt" + counter++;
|
|
801
838
|
if (this.options.allErrors) {
|
|
802
|
-
errorCountVar = "oneErrCnt" + counter;
|
|
803
839
|
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
804
840
|
if (index === 0)
|
|
805
841
|
firstLength = errorCountVar;
|
|
806
842
|
}
|
|
843
|
+
else if (index === 0) {
|
|
844
|
+
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
845
|
+
firstLength = errorCountVar;
|
|
846
|
+
}
|
|
807
847
|
if (index > 0 &&
|
|
808
848
|
!trackingState.shouldTrackEvaluatedProperties &&
|
|
809
849
|
!trackingState.shouldTrackEvaluatedItems) {
|
|
@@ -838,7 +878,7 @@ class Compiler {
|
|
|
838
878
|
}
|
|
839
879
|
});
|
|
840
880
|
if (this.options.allErrors) {
|
|
841
|
-
src.push(`if (${validSchemaCount} == 1) {${this.errorVariable}.length = ${firstLength};}
|
|
881
|
+
src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
|
|
842
882
|
keyword: "oneOf",
|
|
843
883
|
value: varName,
|
|
844
884
|
message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
|
|
@@ -846,14 +886,23 @@ class Compiler {
|
|
|
846
886
|
})}${extra.after}}`);
|
|
847
887
|
}
|
|
848
888
|
else {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
889
|
+
if (noreturn) {
|
|
890
|
+
src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
|
|
891
|
+
keyword: "oneOf",
|
|
892
|
+
value: varName,
|
|
893
|
+
message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
|
|
894
|
+
expected: '"exactly one schema"',
|
|
895
|
+
})}${extra.after}}`);
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
|
|
899
|
+
keyword: "oneOf",
|
|
900
|
+
value: varName,
|
|
901
|
+
message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
|
|
902
|
+
expected: '"exactly one schema"',
|
|
903
|
+
})}${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${this.errorVariable};return false;`}}`);
|
|
904
|
+
}
|
|
905
|
+
this.errorVariable = error;
|
|
857
906
|
this.noreturn = noreturn;
|
|
858
907
|
}
|
|
859
908
|
}
|
|
@@ -1319,11 +1368,15 @@ class Compiler {
|
|
|
1319
1368
|
else {
|
|
1320
1369
|
comparisonTarget = schema.multipleOf;
|
|
1321
1370
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1371
|
+
const multipleOfVar = "multipleOf" + counter++;
|
|
1372
|
+
const quotientVar = "quotient" + counter++;
|
|
1373
|
+
const roundedVar = "rounded" + counter++;
|
|
1374
|
+
const toleranceVar = "tolerance" + counter++;
|
|
1375
|
+
src.push(`const ${multipleOfVar} = ${comparisonTarget};
|
|
1376
|
+
const ${quotientVar} = ${varName} / ${multipleOfVar};
|
|
1377
|
+
const ${roundedVar} = Math.round(${quotientVar});
|
|
1378
|
+
const ${toleranceVar} = Math.abs(${quotientVar}) * Number.EPSILON;
|
|
1379
|
+
if (${extra.before}${multipleOfVar} === 0 || !isFinite(${quotientVar}) || Math.abs(${quotientVar} - ${roundedVar}) > ${toleranceVar}) {${this.buildErrorReturn(pathContext, {
|
|
1327
1380
|
keyword: "multipleOf",
|
|
1328
1381
|
value: varName,
|
|
1329
1382
|
message: `"Value must be a multiple of " + ${comparisonTarget}`,
|
|
@@ -1426,7 +1479,8 @@ class Compiler {
|
|
|
1426
1479
|
else {
|
|
1427
1480
|
src.push(`const formatValidator = formatValidators[${formatKeyVar}].validate ?? formatValidators[${formatKeyVar}];`);
|
|
1428
1481
|
}
|
|
1429
|
-
|
|
1482
|
+
const isValid = "isValid" + counter++;
|
|
1483
|
+
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, {
|
|
1430
1484
|
keyword: "format",
|
|
1431
1485
|
value: varName,
|
|
1432
1486
|
message: `"Failed to validate value against format "+${formatKeyVar}`,
|
|
@@ -1436,7 +1490,7 @@ class Compiler {
|
|
|
1436
1490
|
else {
|
|
1437
1491
|
const data = this.jetValidator.getFormat(schema.format);
|
|
1438
1492
|
if (!data) {
|
|
1439
|
-
|
|
1493
|
+
console.warn(`Format '${schema.format}' not found will be ignored`);
|
|
1440
1494
|
}
|
|
1441
1495
|
const format = typeof data === "object" && "validate" in data ? data.validate : data;
|
|
1442
1496
|
const formatType = typeof data === "object" &&
|
|
@@ -1535,14 +1589,16 @@ class Compiler {
|
|
|
1535
1589
|
const resolvedPath = resolveDataPointerAtCompileTime(pointer, pathContext.$data, this.refCall);
|
|
1536
1590
|
const requiredArrayExpr = generateArrayDataRef(src, resolvedPath, extra);
|
|
1537
1591
|
src.push(`if (${extra.before}${requiredArrayExpr}) {`);
|
|
1538
|
-
|
|
1539
|
-
src.push(`
|
|
1540
|
-
|
|
1541
|
-
src.push(`
|
|
1592
|
+
const i = "i" + counter++;
|
|
1593
|
+
src.push(`for (let ${i} = 0; ${i} < ${requiredArrayExpr}.length; ${i}++) {`);
|
|
1594
|
+
const prop = "prop" + counter++;
|
|
1595
|
+
src.push(`const ${prop} = ${requiredArrayExpr}[${i}];`);
|
|
1596
|
+
addEvaluatedProperty(src, prop, trackingState);
|
|
1597
|
+
src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
|
|
1542
1598
|
keyword: "required",
|
|
1543
1599
|
value: varName,
|
|
1544
|
-
message: `"Missing required field: " + prop + " in data."`,
|
|
1545
|
-
expected:
|
|
1600
|
+
message: `"Missing required field: " + ${prop} + " in data."`,
|
|
1601
|
+
expected: `${prop}`,
|
|
1546
1602
|
schemaPath: `${pathContext.schema}`,
|
|
1547
1603
|
})}${extra.after}}`);
|
|
1548
1604
|
src.push(`}`);
|
|
@@ -1556,23 +1612,39 @@ class Compiler {
|
|
|
1556
1612
|
if (Array.isArray(schema.required)) {
|
|
1557
1613
|
if (this.options.allErrors ||
|
|
1558
1614
|
schema.required.length > this.options.loopRequired) {
|
|
1559
|
-
const arr = JSON.stringify(schema.required);
|
|
1560
|
-
const arrVar = `arr${src.length}${counter++}`;
|
|
1561
|
-
const iVar = `i${src.length}${counter++}`;
|
|
1562
|
-
src.push(`const ${arrVar} = ${arr};`);
|
|
1563
1615
|
if (extra.before != "")
|
|
1564
1616
|
src.push(`if(${extra.before} true){`);
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1617
|
+
if (schema.required.length > this.options.loopRequired) {
|
|
1618
|
+
const arr = JSON.stringify(schema.required);
|
|
1619
|
+
const arrVar = `arr${src.length}${counter++}`;
|
|
1620
|
+
const iVar = `i${src.length}${counter++}`;
|
|
1621
|
+
src.push(`const ${arrVar} = ${arr};`);
|
|
1622
|
+
src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
|
|
1623
|
+
const prop = "prop" + counter++;
|
|
1624
|
+
src.push(`const ${prop} = ${arrVar}[${iVar}];`);
|
|
1625
|
+
addEvaluatedProperty(src, prop, trackingState);
|
|
1626
|
+
src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
|
|
1627
|
+
keyword: "required",
|
|
1628
|
+
value: varName,
|
|
1629
|
+
message: `"Missing required field: " + ${prop} + " in data."`,
|
|
1630
|
+
expected: `${prop}`,
|
|
1631
|
+
schemaPath: `${pathContext.schema}`,
|
|
1632
|
+
})}${extra.after}}`);
|
|
1633
|
+
src.push(`}`);
|
|
1634
|
+
}
|
|
1635
|
+
else {
|
|
1636
|
+
for (const prop of schema.required) {
|
|
1637
|
+
const errorMessage = JSON.stringify(`Missing required field: ${prop} in data.`);
|
|
1638
|
+
const pstring = JSON.stringify(prop);
|
|
1639
|
+
src.push(`if (${extra.before}${varName}[${pstring}] === undefined) {${this.buildErrorReturn(pathContext, {
|
|
1640
|
+
keyword: "required",
|
|
1641
|
+
value: varName,
|
|
1642
|
+
message: errorMessage,
|
|
1643
|
+
expected: `${pstring}`,
|
|
1644
|
+
schemaPath: `${pathContext.schema}`,
|
|
1645
|
+
})}${extra.after}}`);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1576
1648
|
if (extra.before != "")
|
|
1577
1649
|
src.push(`}`);
|
|
1578
1650
|
}
|
|
@@ -1625,21 +1697,22 @@ class Compiler {
|
|
|
1625
1697
|
handlePatternProperties(src, schema, varName, pathContext, trackingState, extra) {
|
|
1626
1698
|
if (extra.before != "")
|
|
1627
1699
|
src.push(`if(${extra.before} true){`);
|
|
1628
|
-
|
|
1700
|
+
const key = "key" + counter++;
|
|
1701
|
+
src.push(`for (const ${key} in ${varName}) {`);
|
|
1629
1702
|
Object.getOwnPropertyNames(schema.patternProperties).forEach((pattern) => {
|
|
1630
1703
|
let pname = this.regexCache.get(pattern);
|
|
1631
1704
|
if (!pname) {
|
|
1632
1705
|
pname = "patternProp" + counter++;
|
|
1633
1706
|
this.regexCache.set(pattern, pname);
|
|
1634
1707
|
}
|
|
1635
|
-
src.push(`if (${pname}.test(key)) {`);
|
|
1636
|
-
addEvaluatedProperty(src,
|
|
1708
|
+
src.push(`if (${pname}.test(${key})) {`);
|
|
1709
|
+
addEvaluatedProperty(src, key, trackingState);
|
|
1637
1710
|
const parent = trackingState.parentHasUnevaluatedProperties ||
|
|
1638
1711
|
trackingState.hasOwnUnevaluatedProperties;
|
|
1639
1712
|
const patternValidation = this.compileSchema(schema.patternProperties[pattern], {
|
|
1640
1713
|
schema: `${pathContext.schema}/patternProperties/${JSON.stringify(pattern)}`,
|
|
1641
|
-
data: `${pathContext.data}/\${key}`,
|
|
1642
|
-
$data: `${pathContext.$data}/\${key}`,
|
|
1714
|
+
data: `${pathContext.data}/\${${key}}`,
|
|
1715
|
+
$data: `${pathContext.$data}/\${${key}}`,
|
|
1643
1716
|
alt: pathContext.alt,
|
|
1644
1717
|
alt2: pathContext.alt2,
|
|
1645
1718
|
}, {
|
|
@@ -1648,7 +1721,7 @@ class Compiler {
|
|
|
1648
1721
|
parentUnevaluatedPropVar: parent
|
|
1649
1722
|
? trackingState.unevaluatedPropVar
|
|
1650
1723
|
: undefined,
|
|
1651
|
-
}, `${varName}[key]`, extra);
|
|
1724
|
+
}, `${varName}[${key}]`, extra);
|
|
1652
1725
|
src.push(patternValidation, "}");
|
|
1653
1726
|
});
|
|
1654
1727
|
src.push("}");
|
|
@@ -1660,12 +1733,13 @@ class Compiler {
|
|
|
1660
1733
|
const explicitProps = Array.from(allowedProperties);
|
|
1661
1734
|
if (extra.before != "")
|
|
1662
1735
|
src.push(`if(${extra.before} true){`);
|
|
1663
|
-
|
|
1664
|
-
|
|
1736
|
+
const key = "key" + counter++;
|
|
1737
|
+
src.push(`for (const ${key} in ${varName}) {`);
|
|
1738
|
+
addEvaluatedProperty(src, key, trackingState);
|
|
1665
1739
|
let checks = [];
|
|
1666
1740
|
if (explicitProps.length > 0) {
|
|
1667
1741
|
const allowedCheck = explicitProps
|
|
1668
|
-
.map((
|
|
1742
|
+
.map((keyItem) => `${key} === ${JSON.stringify(keyItem)}`)
|
|
1669
1743
|
.join(" || ");
|
|
1670
1744
|
checks.push(allowedCheck);
|
|
1671
1745
|
}
|
|
@@ -1677,7 +1751,7 @@ class Compiler {
|
|
|
1677
1751
|
pname = "patternProp" + counter++;
|
|
1678
1752
|
this.regexCache.set(pattern, pname);
|
|
1679
1753
|
}
|
|
1680
|
-
return `${pname}.test(key)`;
|
|
1754
|
+
return `${pname}.test(${key})`;
|
|
1681
1755
|
})
|
|
1682
1756
|
.join(" || ");
|
|
1683
1757
|
checks.push(patternCheck);
|
|
@@ -1688,17 +1762,18 @@ class Compiler {
|
|
|
1688
1762
|
}
|
|
1689
1763
|
const additionalPropValidation = this.compileSchema(schema.additionalProperties, {
|
|
1690
1764
|
schema: `${pathContext.schema}/additionalProperties`,
|
|
1691
|
-
data: `${pathContext.data}/\${key}`,
|
|
1692
|
-
$data: `${pathContext.$data}/\${key}`,
|
|
1765
|
+
data: `${pathContext.data}/\${${key}}`,
|
|
1766
|
+
$data: `${pathContext.$data}/\${${key}}`,
|
|
1693
1767
|
alt: pathContext.alt,
|
|
1694
1768
|
alt2: pathContext.alt2,
|
|
1695
|
-
}, {}, `${varName}[key]`, extra);
|
|
1769
|
+
}, {}, `${varName}[${key}]`, extra);
|
|
1696
1770
|
src.push(additionalPropValidation, "}");
|
|
1697
1771
|
if (extra.before != "")
|
|
1698
1772
|
src.push(`}`);
|
|
1699
1773
|
}
|
|
1700
1774
|
handlePropertyConstraints(src, schema, varName, pathContext, extra) {
|
|
1701
|
-
|
|
1775
|
+
const objKeys = "objKeys" + counter++;
|
|
1776
|
+
src.push(`const ${objKeys} = Object.keys(${varName});`);
|
|
1702
1777
|
if (schema.minProperties !== undefined) {
|
|
1703
1778
|
const isDataRef = this.options.$data && isDataReference(schema.minProperties);
|
|
1704
1779
|
let comparisonTarget;
|
|
@@ -1710,9 +1785,9 @@ class Compiler {
|
|
|
1710
1785
|
else {
|
|
1711
1786
|
comparisonTarget = schema.minProperties;
|
|
1712
1787
|
}
|
|
1713
|
-
src.push(`if (${extra.before}objKeys.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1788
|
+
src.push(`if (${extra.before}${objKeys}.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1714
1789
|
keyword: "minProperties",
|
|
1715
|
-
value:
|
|
1790
|
+
value: `${objKeys}.length`,
|
|
1716
1791
|
message: `"Object must have at least " + ${comparisonTarget} + " properties."`,
|
|
1717
1792
|
expected: comparisonTarget,
|
|
1718
1793
|
})}${extra.after}}`);
|
|
@@ -1731,9 +1806,9 @@ class Compiler {
|
|
|
1731
1806
|
else {
|
|
1732
1807
|
comparisonTarget = schema.maxProperties;
|
|
1733
1808
|
}
|
|
1734
|
-
src.push(`if (${extra.before}objKeys.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1809
|
+
src.push(`if (${extra.before}${objKeys}.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1735
1810
|
keyword: "maxProperties",
|
|
1736
|
-
value:
|
|
1811
|
+
value: `${objKeys}.length`,
|
|
1737
1812
|
message: `"Object must have at most " + ${comparisonTarget} + " properties."`,
|
|
1738
1813
|
expected: comparisonTarget,
|
|
1739
1814
|
})}${extra.after}}`);
|
|
@@ -1745,14 +1820,15 @@ class Compiler {
|
|
|
1745
1820
|
handlePropertyNames(src, schema, varName, pathContext, extra) {
|
|
1746
1821
|
if (extra.before != "")
|
|
1747
1822
|
src.push(`if(${extra.before} true){`);
|
|
1748
|
-
|
|
1823
|
+
const key = "key" + counter++;
|
|
1824
|
+
src.push(`for (const ${key} in ${varName}) {`);
|
|
1749
1825
|
const propertyNameValidation = this.compileSchema(schema.propertyNames, {
|
|
1750
1826
|
schema: `${pathContext.schema}/propertyNames`,
|
|
1751
|
-
data: `${pathContext.data}/\${key}`,
|
|
1752
|
-
$data: `${pathContext.$data}/\${key}`,
|
|
1827
|
+
data: `${pathContext.data}/\${${key}}`,
|
|
1828
|
+
$data: `${pathContext.$data}/\${${key}}`,
|
|
1753
1829
|
alt: pathContext.alt,
|
|
1754
1830
|
alt2: pathContext.alt2,
|
|
1755
|
-
}, {},
|
|
1831
|
+
}, {}, key, extra);
|
|
1756
1832
|
src.push(propertyNameValidation, "}");
|
|
1757
1833
|
if (extra.before != "")
|
|
1758
1834
|
src.push(`}`);
|
|
@@ -1864,7 +1940,8 @@ class Compiler {
|
|
|
1864
1940
|
const evalSet = trackingState.unevaluatedPropVar;
|
|
1865
1941
|
if (extra.before != "")
|
|
1866
1942
|
src.push(`if(${extra.before} true){`);
|
|
1867
|
-
|
|
1943
|
+
const key = "key" + counter++;
|
|
1944
|
+
src.push(`const ${unName} = [];`, `for (const ${key} in ${varName}) {`, `if (!${evalSet}.has(${key})) {`, `${unName}.push(${key});`, `}`, `}`);
|
|
1868
1945
|
if (schema.unevaluatedProperties === false) {
|
|
1869
1946
|
src.push(`if (${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
|
|
1870
1947
|
keyword: "unevaluatedProperties",
|
|
@@ -1877,7 +1954,8 @@ class Compiler {
|
|
|
1877
1954
|
}
|
|
1878
1955
|
else if (schema.unevaluatedProperties === true) {
|
|
1879
1956
|
if (trackingState.parentHasUnevaluatedProperties) {
|
|
1880
|
-
|
|
1957
|
+
const key = "key" + counter++;
|
|
1958
|
+
src.push(`for(const ${key} in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(${key})}`);
|
|
1881
1959
|
}
|
|
1882
1960
|
}
|
|
1883
1961
|
else {
|
|
@@ -2195,7 +2273,8 @@ class Compiler {
|
|
|
2195
2273
|
const evalSet = trackingState.unevaluatedItemVar;
|
|
2196
2274
|
if (extra.before != "")
|
|
2197
2275
|
src.push(`if(${extra.before} true){`);
|
|
2198
|
-
|
|
2276
|
+
const i = "i" + counter++;
|
|
2277
|
+
src.push(`const ${unName} = [];`, `for (let ${i} = 0; ${i} < ${varName}.length; ${i}++) {`, `if (!${evalSet}.has(${i})) {`, `${unName}.push(${i});`, `}`, `}`);
|
|
2199
2278
|
if (schema.unevaluatedItems === false) {
|
|
2200
2279
|
src.push(`if (${extra.before}${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
|
|
2201
2280
|
keyword: "unevaluatedItems",
|
|
@@ -2233,9 +2312,7 @@ class Compiler {
|
|
|
2233
2312
|
buildErrorReturn(pathContext, error, spreads) {
|
|
2234
2313
|
if (this.notLogic)
|
|
2235
2314
|
return "";
|
|
2236
|
-
|
|
2237
|
-
return "return false;";
|
|
2238
|
-
let result = this.options.allErrors
|
|
2315
|
+
let result = this.options.allErrors || this.noreturn
|
|
2239
2316
|
? `${this.errorVariable}.push({`
|
|
2240
2317
|
: `${this.mainFunctionName}.errors = [{`;
|
|
2241
2318
|
const escapedDataPath = escapeTemplateString(error.dataPath || pathContext.data || "/");
|
|
@@ -2316,7 +2393,7 @@ class Compiler {
|
|
|
2316
2393
|
result += `,${spreads}`;
|
|
2317
2394
|
}
|
|
2318
2395
|
result += "}";
|
|
2319
|
-
if (this.options.allErrors) {
|
|
2396
|
+
if (this.options.allErrors || this.noreturn) {
|
|
2320
2397
|
result += ");";
|
|
2321
2398
|
}
|
|
2322
2399
|
else {
|
|
@@ -5063,7 +5140,7 @@ class SchemaResolver {
|
|
|
5063
5140
|
throw Error(`[${mode}] Unknown type ${type}`);
|
|
5064
5141
|
}
|
|
5065
5142
|
}
|
|
5066
|
-
for (const keyword of allPossibleIncompatible) {
|
|
5143
|
+
for (const keyword of Array.from(allPossibleIncompatible)) {
|
|
5067
5144
|
const incompatibleWithAll = types.every((type) => incompatibleKeywords[type]?.includes(keyword));
|
|
5068
5145
|
if (incompatibleWithAll && schema[keyword] !== undefined) {
|
|
5069
5146
|
throw Error(`[${mode}] Keyword "${keyword}" is incompatible with ${types.length > 1 ? "all types" : "type"} "${types.join(", ")}"`);
|
|
@@ -5625,6 +5702,7 @@ class JetValidator {
|
|
|
5625
5702
|
const fconfig = {
|
|
5626
5703
|
...config,
|
|
5627
5704
|
};
|
|
5705
|
+
const has$Data = compileContext.uses$Data;
|
|
5628
5706
|
if (typeof resolvedSchema === "boolean")
|
|
5629
5707
|
fconfig.allErrors = false;
|
|
5630
5708
|
const compiler = new Compiler(refables, mainSchema, fconfig, this, allKeywords, compileContext, false);
|
|
@@ -5657,22 +5735,6 @@ class JetValidator {
|
|
|
5657
5735
|
if (validate)
|
|
5658
5736
|
customKeywords.set(keywordDef, validate);
|
|
5659
5737
|
}
|
|
5660
|
-
if (typeof resolvedSchema !== "boolean") {
|
|
5661
|
-
if (allFormats.size > 0) {
|
|
5662
|
-
for (const validatorKey of allFormats) {
|
|
5663
|
-
const validator = this.formatValidators[validatorKey];
|
|
5664
|
-
if (validator) {
|
|
5665
|
-
if (typeof validator === "function" ||
|
|
5666
|
-
validator instanceof RegExp) {
|
|
5667
|
-
formatValidators[validatorKey] = validator;
|
|
5668
|
-
}
|
|
5669
|
-
else {
|
|
5670
|
-
formatValidators[validatorKey] = validator.validate;
|
|
5671
|
-
}
|
|
5672
|
-
}
|
|
5673
|
-
}
|
|
5674
|
-
}
|
|
5675
|
-
}
|
|
5676
5738
|
const asyncPrefix = config.async ? "async " : "";
|
|
5677
5739
|
let functionDeclaration = "validate(rootData";
|
|
5678
5740
|
if (compileContext.hasRootReference) {
|
|
@@ -5705,6 +5767,40 @@ class JetValidator {
|
|
|
5705
5767
|
regexArgs.push(new RegExp(key));
|
|
5706
5768
|
}
|
|
5707
5769
|
}
|
|
5770
|
+
if (typeof resolvedSchema !== "boolean") {
|
|
5771
|
+
if (has$Data) {
|
|
5772
|
+
const formatKeys = Array.isArray(fconfig.formats) && fconfig.formats.length > 0
|
|
5773
|
+
? fconfig.formats
|
|
5774
|
+
: Object.keys(this.formatValidators);
|
|
5775
|
+
for (const validatorKey of formatKeys) {
|
|
5776
|
+
const validator = this.formatValidators[validatorKey];
|
|
5777
|
+
if (validator) {
|
|
5778
|
+
if (typeof validator === "function" ||
|
|
5779
|
+
validator instanceof RegExp) {
|
|
5780
|
+
formatValidators[validatorKey] = validator;
|
|
5781
|
+
}
|
|
5782
|
+
else {
|
|
5783
|
+
formatValidators[validatorKey] = validator.validate;
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5787
|
+
}
|
|
5788
|
+
else if (allFormats.size > 0) {
|
|
5789
|
+
for (const validatorKey of allFormats) {
|
|
5790
|
+
const validator = this.formatValidators[validatorKey];
|
|
5791
|
+
if (validator) {
|
|
5792
|
+
if (typeof validator === "function" ||
|
|
5793
|
+
validator instanceof RegExp) {
|
|
5794
|
+
formatValidators[validatorKey] = validator;
|
|
5795
|
+
}
|
|
5796
|
+
else {
|
|
5797
|
+
formatValidators[validatorKey] = validator.validate;
|
|
5798
|
+
}
|
|
5799
|
+
}
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5802
|
+
}
|
|
5803
|
+
Object.values(formatValidators);
|
|
5708
5804
|
return new Function("formatValidators", "deepEqual", "canonicalStringify", "customKeywords", "len_of", ...regexParams, finalSource)(formatValidators, deepEqual, canonicalStringify, customKeywords, len_of, ...regexArgs);
|
|
5709
5805
|
}
|
|
5710
5806
|
compile(fschema, config) {
|