@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.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 =
|
|
446
|
-
!this.options.
|
|
447
|
-
!this.options.coerceTypes
|
|
444
|
+
const varName = accessPattern === "rootData" ||
|
|
445
|
+
(inlined && (schema.default === undefined || !this.options.useDefaults))
|
|
448
446
|
? accessPattern
|
|
449
|
-
: "
|
|
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 (
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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)
|
|
616
|
+
src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);`}}`);
|
|
614
617
|
}
|
|
615
618
|
else {
|
|
616
|
-
|
|
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)
|
|
655
|
+
src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);`}}`);
|
|
643
656
|
}
|
|
644
657
|
else {
|
|
645
|
-
|
|
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 =
|
|
704
|
-
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
800
|
-
refAfter: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors} = ${oneOfErrors}.concat(${this.mainFunctionName}.errors);`}`,
|
|
838
|
+
after: `${branch} = false;`,
|
|
801
839
|
}, true);
|
|
802
840
|
}
|
|
803
|
-
|
|
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};}
|
|
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
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
}
|
|
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
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1543
|
-
src.push(`
|
|
1544
|
-
|
|
1545
|
-
src.push(`
|
|
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:
|
|
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
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
1668
|
-
|
|
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((
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
}, {},
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|