@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/compileSchema.js
CHANGED
|
@@ -113,7 +113,6 @@ class Compiler {
|
|
|
113
113
|
this.validateKeywords = new Set();
|
|
114
114
|
this.notLogic = false;
|
|
115
115
|
this.noreturn = false;
|
|
116
|
-
this.neutralError = false;
|
|
117
116
|
this.standAlone = false;
|
|
118
117
|
this.hasCompileKeyword = false;
|
|
119
118
|
this.needslen_of = false;
|
|
@@ -306,11 +305,10 @@ class Compiler {
|
|
|
306
305
|
return src.join("");
|
|
307
306
|
}
|
|
308
307
|
const schema = rootSchema;
|
|
309
|
-
const varName =
|
|
310
|
-
!this.options.
|
|
311
|
-
!this.options.coerceTypes
|
|
308
|
+
const varName = accessPattern === "rootData" ||
|
|
309
|
+
(inlined && (schema.default === undefined || !this.options.useDefaults))
|
|
312
310
|
? accessPattern
|
|
313
|
-
: "
|
|
311
|
+
: "jv" + counter++;
|
|
314
312
|
this.initializeDefault(src, schema, varName, accessPattern, inlined);
|
|
315
313
|
let shouldTrackProps;
|
|
316
314
|
let shouldTrackItems;
|
|
@@ -354,11 +352,16 @@ class Compiler {
|
|
|
354
352
|
return src.join("");
|
|
355
353
|
}
|
|
356
354
|
initializeDefault(src, schema, varName, accessPattern, inlined) {
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
if (accessPattern !== "rootData") {
|
|
356
|
+
if (schema.default !== undefined && this.options.useDefaults) {
|
|
357
|
+
src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
|
|
358
|
+
}
|
|
359
|
+
else if (!inlined) {
|
|
360
|
+
const keyword = this.options.removeAdditional || this.options.coerceTypes
|
|
361
|
+
? "let"
|
|
362
|
+
: "const";
|
|
363
|
+
src.push(`${keyword} ${varName} = ${accessPattern};`);
|
|
364
|
+
}
|
|
362
365
|
}
|
|
363
366
|
if (this.options.coerceTypes) {
|
|
364
367
|
if (schema.type === "number" || schema.type === "integer") {
|
|
@@ -474,10 +477,20 @@ class Compiler {
|
|
|
474
477
|
src.push(`if(${extra.before} true){`);
|
|
475
478
|
src.push(`const ${funcValidator}Result = ${awaitPrefix}${schema.__functionName}${callArgs};`);
|
|
476
479
|
if (this.options.allErrors) {
|
|
477
|
-
src.push(`if (!${funcValidator}Result)
|
|
480
|
+
src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);`}}`);
|
|
478
481
|
}
|
|
479
482
|
else {
|
|
480
|
-
|
|
483
|
+
if (this.noreturn) {
|
|
484
|
+
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]);`}}`);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
if (this.mainFunctionName === schema.__functionName) {
|
|
488
|
+
src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
src.push(`if (!${funcValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${schema.__functionName}.errors;return false;`}}`);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
481
494
|
}
|
|
482
495
|
if (extra.before != "")
|
|
483
496
|
src.push(`}`);
|
|
@@ -503,10 +516,20 @@ class Compiler {
|
|
|
503
516
|
src.push(`if(${extra.before} true){`);
|
|
504
517
|
src.push(`const ${refValidator}Result = ${awaitPrefix}${functionName}${callArgs};`);
|
|
505
518
|
if (this.options.allErrors) {
|
|
506
|
-
src.push(`if (!${refValidator}Result)
|
|
519
|
+
src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);`}}`);
|
|
507
520
|
}
|
|
508
521
|
else {
|
|
509
|
-
|
|
522
|
+
if (this.noreturn) {
|
|
523
|
+
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]);`}}`);
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
if (this.mainFunctionName === functionName) {
|
|
527
|
+
src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `return false;`}}`);
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
src.push(`if (!${refValidator}Result){${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${functionName}.errors;return false;`}}`);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
510
533
|
}
|
|
511
534
|
if (extra.before != "")
|
|
512
535
|
src.push(`}`);
|
|
@@ -525,12 +548,12 @@ class Compiler {
|
|
|
525
548
|
return `(${args.join(", ")})`;
|
|
526
549
|
}
|
|
527
550
|
handleLogicalOperators(src, schema, varName, pathContext, trackingState, extra) {
|
|
551
|
+
if (schema.allOf)
|
|
552
|
+
this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
528
553
|
if (schema.not)
|
|
529
554
|
this.handleNotOperator(src, schema, varName, pathContext, extra);
|
|
530
555
|
if (schema.anyOf)
|
|
531
556
|
this.handleAnyOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
532
|
-
if (schema.allOf)
|
|
533
|
-
this.handleAllOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
534
557
|
if (schema.oneOf)
|
|
535
558
|
this.handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra);
|
|
536
559
|
}
|
|
@@ -564,9 +587,12 @@ class Compiler {
|
|
|
564
587
|
let firstLength = "";
|
|
565
588
|
const anyOfValid = "anyOfValid" + counter++;
|
|
566
589
|
src.push(`let ${anyOfValid} = false;`);
|
|
567
|
-
const anyOfError =
|
|
568
|
-
|
|
590
|
+
const anyOfError = this.noreturn
|
|
591
|
+
? this.errorVariable
|
|
592
|
+
: "anyOfErr" + counter++;
|
|
593
|
+
if (!this.options.allErrors && !this.noreturn)
|
|
569
594
|
src.push(`let ${anyOfError} = [];`);
|
|
595
|
+
const error = this.errorVariable;
|
|
570
596
|
schema.anyOf.forEach((subSchema, index) => {
|
|
571
597
|
const branch = `branch${counter++}Valid`;
|
|
572
598
|
if (!this.options.allErrors)
|
|
@@ -577,24 +603,27 @@ class Compiler {
|
|
|
577
603
|
const configs = this.createSubschemaOptions(trackingState, pathContext, `anyOf/${index}`, schema);
|
|
578
604
|
configs.pathContext.alt = `${pathContext.schema}/anyOf/${index}`;
|
|
579
605
|
configs.pathContext.alt2 = `${pathContext.schema}/anyOf`;
|
|
606
|
+
let errorCountVar = "anyErrCnt" + counter++;
|
|
580
607
|
if (this.options.allErrors) {
|
|
581
608
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
|
|
582
609
|
}
|
|
583
610
|
else {
|
|
611
|
+
this.errorVariable = anyOfError;
|
|
584
612
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
|
|
585
613
|
before: `${branch} && `,
|
|
586
|
-
after: `${branch} = false
|
|
587
|
-
refAfter: `${branch} = false;${this.notLogic ? "" : `${anyOfError} = ${anyOfError}.concat(${this.mainFunctionName}.errors);`}`,
|
|
614
|
+
after: `${branch} = false;`,
|
|
588
615
|
}, true);
|
|
589
616
|
}
|
|
590
|
-
this.noreturn = noreturn;
|
|
591
|
-
let errorCountVar;
|
|
592
617
|
if (this.options.allErrors) {
|
|
593
|
-
errorCountVar = "anyErrCnt" + counter++;
|
|
594
618
|
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
595
619
|
if (index === 0)
|
|
596
620
|
firstLength = errorCountVar;
|
|
597
621
|
}
|
|
622
|
+
else if (index === 0) {
|
|
623
|
+
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
624
|
+
firstLength = errorCountVar;
|
|
625
|
+
}
|
|
626
|
+
this.noreturn = noreturn;
|
|
598
627
|
if (index > 0 &&
|
|
599
628
|
!trackingState.shouldTrackEvaluatedProperties &&
|
|
600
629
|
!trackingState.shouldTrackEvaluatedItems) {
|
|
@@ -629,27 +658,36 @@ class Compiler {
|
|
|
629
658
|
}
|
|
630
659
|
});
|
|
631
660
|
if (this.options.allErrors) {
|
|
632
|
-
src.push(`if (${anyOfValid}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else{${extra.after}}` : ""}`);
|
|
661
|
+
src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}${extra.after != "" ? `else if(!${anyOfValid}){${extra.after}}` : ""}`);
|
|
633
662
|
}
|
|
634
663
|
else {
|
|
635
|
-
|
|
664
|
+
if (this.noreturn) {
|
|
665
|
+
src.push(`if (${anyOfValid} && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(!${anyOfValid}){${extra.after}}`);
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
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;`}}`);
|
|
669
|
+
}
|
|
670
|
+
this.errorVariable = error;
|
|
636
671
|
}
|
|
637
672
|
}
|
|
638
673
|
handleOneOfOperator(src, schema, varName, pathContext, trackingState, extra) {
|
|
639
674
|
if (!schema.oneOf)
|
|
640
675
|
return;
|
|
641
676
|
let firstLength = "";
|
|
642
|
-
const oneOfErrors =
|
|
677
|
+
const oneOfErrors = this.noreturn
|
|
678
|
+
? this.errorVariable
|
|
679
|
+
: `oneOfErrors${counter++}`;
|
|
643
680
|
const validSchemaCount = "validSchemaCount" + counter++;
|
|
644
681
|
src.push(`let ${validSchemaCount} = 0;`);
|
|
645
|
-
if (!this.options.allErrors)
|
|
682
|
+
if (!this.options.allErrors && !this.noreturn)
|
|
646
683
|
src.push(`let ${oneOfErrors} = [];`);
|
|
684
|
+
const noreturn = this.noreturn;
|
|
685
|
+
const error = this.errorVariable;
|
|
647
686
|
schema.oneOf.forEach((subSchema, index) => {
|
|
648
687
|
const branch = `branch${counter++}Valid`;
|
|
649
|
-
if (!this.options.allErrors
|
|
688
|
+
if (!this.options.allErrors)
|
|
650
689
|
src.push(`let ${branch} = true;`);
|
|
651
690
|
let validatorFn;
|
|
652
|
-
const noreturn = this.noreturn;
|
|
653
691
|
this.noreturn = true;
|
|
654
692
|
const configs = this.createSubschemaOptions(trackingState, pathContext, `oneOf/${index}`, schema);
|
|
655
693
|
configs.pathContext.alt = `${pathContext.schema}/oneOf/${index}`;
|
|
@@ -658,20 +696,22 @@ class Compiler {
|
|
|
658
696
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, extra, true);
|
|
659
697
|
}
|
|
660
698
|
else {
|
|
699
|
+
this.errorVariable = oneOfErrors;
|
|
661
700
|
validatorFn = this.compileSchema(subSchema, configs.pathContext, configs.trackingState, varName, {
|
|
662
701
|
before: `${branch} && `,
|
|
663
|
-
after: `${branch} = false
|
|
664
|
-
refAfter: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors} = ${oneOfErrors}.concat(${this.mainFunctionName}.errors);`}`,
|
|
702
|
+
after: `${branch} = false;`,
|
|
665
703
|
}, true);
|
|
666
704
|
}
|
|
667
|
-
|
|
668
|
-
let errorCountVar;
|
|
705
|
+
let errorCountVar = "oneErrCnt" + counter++;
|
|
669
706
|
if (this.options.allErrors) {
|
|
670
|
-
errorCountVar = "oneErrCnt" + counter;
|
|
671
707
|
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
672
708
|
if (index === 0)
|
|
673
709
|
firstLength = errorCountVar;
|
|
674
710
|
}
|
|
711
|
+
else if (index === 0) {
|
|
712
|
+
src.push(`const ${errorCountVar} = ${this.errorVariable}.length;`);
|
|
713
|
+
firstLength = errorCountVar;
|
|
714
|
+
}
|
|
675
715
|
if (index > 0 &&
|
|
676
716
|
!trackingState.shouldTrackEvaluatedProperties &&
|
|
677
717
|
!trackingState.shouldTrackEvaluatedItems) {
|
|
@@ -706,7 +746,7 @@ class Compiler {
|
|
|
706
746
|
}
|
|
707
747
|
});
|
|
708
748
|
if (this.options.allErrors) {
|
|
709
|
-
src.push(`if (${validSchemaCount} == 1) {${this.errorVariable}.length = ${firstLength};}
|
|
749
|
+
src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}) {${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
|
|
710
750
|
keyword: "oneOf",
|
|
711
751
|
value: varName,
|
|
712
752
|
message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
|
|
@@ -714,14 +754,23 @@ class Compiler {
|
|
|
714
754
|
})}${extra.after}}`);
|
|
715
755
|
}
|
|
716
756
|
else {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
}
|
|
757
|
+
if (noreturn) {
|
|
758
|
+
src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
|
|
759
|
+
keyword: "oneOf",
|
|
760
|
+
value: varName,
|
|
761
|
+
message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
|
|
762
|
+
expected: '"exactly one schema"',
|
|
763
|
+
})}${extra.after}}`);
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
src.push(`if (${validSchemaCount} == 1 && ${this.errorVariable}.length != ${firstLength}){${this.errorVariable}.length = ${firstLength};}else if(${validSchemaCount} != 1){${this.buildErrorReturn(pathContext, {
|
|
767
|
+
keyword: "oneOf",
|
|
768
|
+
value: varName,
|
|
769
|
+
message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
|
|
770
|
+
expected: '"exactly one schema"',
|
|
771
|
+
})}${this.notLogic ? extra.after : `${this.mainFunctionName}.errors = ${this.errorVariable};return false;`}}`);
|
|
772
|
+
}
|
|
773
|
+
this.errorVariable = error;
|
|
725
774
|
this.noreturn = noreturn;
|
|
726
775
|
}
|
|
727
776
|
}
|
|
@@ -1187,11 +1236,15 @@ class Compiler {
|
|
|
1187
1236
|
else {
|
|
1188
1237
|
comparisonTarget = schema.multipleOf;
|
|
1189
1238
|
}
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1239
|
+
const multipleOfVar = "multipleOf" + counter++;
|
|
1240
|
+
const quotientVar = "quotient" + counter++;
|
|
1241
|
+
const roundedVar = "rounded" + counter++;
|
|
1242
|
+
const toleranceVar = "tolerance" + counter++;
|
|
1243
|
+
src.push(`const ${multipleOfVar} = ${comparisonTarget};
|
|
1244
|
+
const ${quotientVar} = ${varName} / ${multipleOfVar};
|
|
1245
|
+
const ${roundedVar} = Math.round(${quotientVar});
|
|
1246
|
+
const ${toleranceVar} = Math.abs(${quotientVar}) * Number.EPSILON;
|
|
1247
|
+
if (${extra.before}${multipleOfVar} === 0 || !isFinite(${quotientVar}) || Math.abs(${quotientVar} - ${roundedVar}) > ${toleranceVar}) {${this.buildErrorReturn(pathContext, {
|
|
1195
1248
|
keyword: "multipleOf",
|
|
1196
1249
|
value: varName,
|
|
1197
1250
|
message: `"Value must be a multiple of " + ${comparisonTarget}`,
|
|
@@ -1294,7 +1347,8 @@ class Compiler {
|
|
|
1294
1347
|
else {
|
|
1295
1348
|
src.push(`const formatValidator = formatValidators[${formatKeyVar}].validate ?? formatValidators[${formatKeyVar}];`);
|
|
1296
1349
|
}
|
|
1297
|
-
|
|
1350
|
+
const isValid = "isValid" + counter++;
|
|
1351
|
+
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, {
|
|
1298
1352
|
keyword: "format",
|
|
1299
1353
|
value: varName,
|
|
1300
1354
|
message: `"Failed to validate value against format "+${formatKeyVar}`,
|
|
@@ -1304,7 +1358,7 @@ class Compiler {
|
|
|
1304
1358
|
else {
|
|
1305
1359
|
const data = this.jetValidator.getFormat(schema.format);
|
|
1306
1360
|
if (!data) {
|
|
1307
|
-
|
|
1361
|
+
console.warn(`Format '${schema.format}' not found will be ignored`);
|
|
1308
1362
|
}
|
|
1309
1363
|
const format = typeof data === "object" && "validate" in data ? data.validate : data;
|
|
1310
1364
|
const formatType = typeof data === "object" &&
|
|
@@ -1403,14 +1457,16 @@ class Compiler {
|
|
|
1403
1457
|
const resolvedPath = resolveDataPointerAtCompileTime(pointer, pathContext.$data, this.refCall);
|
|
1404
1458
|
const requiredArrayExpr = generateArrayDataRef(src, resolvedPath, extra);
|
|
1405
1459
|
src.push(`if (${extra.before}${requiredArrayExpr}) {`);
|
|
1406
|
-
|
|
1407
|
-
src.push(`
|
|
1408
|
-
|
|
1409
|
-
src.push(`
|
|
1460
|
+
const i = "i" + counter++;
|
|
1461
|
+
src.push(`for (let ${i} = 0; ${i} < ${requiredArrayExpr}.length; ${i}++) {`);
|
|
1462
|
+
const prop = "prop" + counter++;
|
|
1463
|
+
src.push(`const ${prop} = ${requiredArrayExpr}[${i}];`);
|
|
1464
|
+
addEvaluatedProperty(src, prop, trackingState);
|
|
1465
|
+
src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
|
|
1410
1466
|
keyword: "required",
|
|
1411
1467
|
value: varName,
|
|
1412
|
-
message: `"Missing required field: " + prop + " in data."`,
|
|
1413
|
-
expected:
|
|
1468
|
+
message: `"Missing required field: " + ${prop} + " in data."`,
|
|
1469
|
+
expected: `${prop}`,
|
|
1414
1470
|
schemaPath: `${pathContext.schema}`,
|
|
1415
1471
|
})}${extra.after}}`);
|
|
1416
1472
|
src.push(`}`);
|
|
@@ -1424,23 +1480,39 @@ class Compiler {
|
|
|
1424
1480
|
if (Array.isArray(schema.required)) {
|
|
1425
1481
|
if (this.options.allErrors ||
|
|
1426
1482
|
schema.required.length > this.options.loopRequired) {
|
|
1427
|
-
const arr = JSON.stringify(schema.required);
|
|
1428
|
-
const arrVar = `arr${src.length}${counter++}`;
|
|
1429
|
-
const iVar = `i${src.length}${counter++}`;
|
|
1430
|
-
src.push(`const ${arrVar} = ${arr};`);
|
|
1431
1483
|
if (extra.before != "")
|
|
1432
1484
|
src.push(`if(${extra.before} true){`);
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1485
|
+
if (schema.required.length > this.options.loopRequired) {
|
|
1486
|
+
const arr = JSON.stringify(schema.required);
|
|
1487
|
+
const arrVar = `arr${src.length}${counter++}`;
|
|
1488
|
+
const iVar = `i${src.length}${counter++}`;
|
|
1489
|
+
src.push(`const ${arrVar} = ${arr};`);
|
|
1490
|
+
src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
|
|
1491
|
+
const prop = "prop" + counter++;
|
|
1492
|
+
src.push(`const ${prop} = ${arrVar}[${iVar}];`);
|
|
1493
|
+
addEvaluatedProperty(src, prop, trackingState);
|
|
1494
|
+
src.push(`if (${extra.before}${varName}[${prop}] === undefined) {${this.buildErrorReturn(pathContext, {
|
|
1495
|
+
keyword: "required",
|
|
1496
|
+
value: varName,
|
|
1497
|
+
message: `"Missing required field: " + ${prop} + " in data."`,
|
|
1498
|
+
expected: `${prop}`,
|
|
1499
|
+
schemaPath: `${pathContext.schema}`,
|
|
1500
|
+
})}${extra.after}}`);
|
|
1501
|
+
src.push(`}`);
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
for (const prop of schema.required) {
|
|
1505
|
+
const errorMessage = JSON.stringify(`Missing required field: ${prop} in data.`);
|
|
1506
|
+
const pstring = JSON.stringify(prop);
|
|
1507
|
+
src.push(`if (${extra.before}${varName}[${pstring}] === undefined) {${this.buildErrorReturn(pathContext, {
|
|
1508
|
+
keyword: "required",
|
|
1509
|
+
value: varName,
|
|
1510
|
+
message: errorMessage,
|
|
1511
|
+
expected: `${pstring}`,
|
|
1512
|
+
schemaPath: `${pathContext.schema}`,
|
|
1513
|
+
})}${extra.after}}`);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1444
1516
|
if (extra.before != "")
|
|
1445
1517
|
src.push(`}`);
|
|
1446
1518
|
}
|
|
@@ -1493,21 +1565,22 @@ class Compiler {
|
|
|
1493
1565
|
handlePatternProperties(src, schema, varName, pathContext, trackingState, extra) {
|
|
1494
1566
|
if (extra.before != "")
|
|
1495
1567
|
src.push(`if(${extra.before} true){`);
|
|
1496
|
-
|
|
1568
|
+
const key = "key" + counter++;
|
|
1569
|
+
src.push(`for (const ${key} in ${varName}) {`);
|
|
1497
1570
|
Object.getOwnPropertyNames(schema.patternProperties).forEach((pattern) => {
|
|
1498
1571
|
let pname = this.regexCache.get(pattern);
|
|
1499
1572
|
if (!pname) {
|
|
1500
1573
|
pname = "patternProp" + counter++;
|
|
1501
1574
|
this.regexCache.set(pattern, pname);
|
|
1502
1575
|
}
|
|
1503
|
-
src.push(`if (${pname}.test(key)) {`);
|
|
1504
|
-
addEvaluatedProperty(src,
|
|
1576
|
+
src.push(`if (${pname}.test(${key})) {`);
|
|
1577
|
+
addEvaluatedProperty(src, key, trackingState);
|
|
1505
1578
|
const parent = trackingState.parentHasUnevaluatedProperties ||
|
|
1506
1579
|
trackingState.hasOwnUnevaluatedProperties;
|
|
1507
1580
|
const patternValidation = this.compileSchema(schema.patternProperties[pattern], {
|
|
1508
1581
|
schema: `${pathContext.schema}/patternProperties/${JSON.stringify(pattern)}`,
|
|
1509
|
-
data: `${pathContext.data}/\${key}`,
|
|
1510
|
-
$data: `${pathContext.$data}/\${key}`,
|
|
1582
|
+
data: `${pathContext.data}/\${${key}}`,
|
|
1583
|
+
$data: `${pathContext.$data}/\${${key}}`,
|
|
1511
1584
|
alt: pathContext.alt,
|
|
1512
1585
|
alt2: pathContext.alt2,
|
|
1513
1586
|
}, {
|
|
@@ -1516,7 +1589,7 @@ class Compiler {
|
|
|
1516
1589
|
parentUnevaluatedPropVar: parent
|
|
1517
1590
|
? trackingState.unevaluatedPropVar
|
|
1518
1591
|
: undefined,
|
|
1519
|
-
}, `${varName}[key]`, extra);
|
|
1592
|
+
}, `${varName}[${key}]`, extra);
|
|
1520
1593
|
src.push(patternValidation, "}");
|
|
1521
1594
|
});
|
|
1522
1595
|
src.push("}");
|
|
@@ -1528,12 +1601,13 @@ class Compiler {
|
|
|
1528
1601
|
const explicitProps = Array.from(allowedProperties);
|
|
1529
1602
|
if (extra.before != "")
|
|
1530
1603
|
src.push(`if(${extra.before} true){`);
|
|
1531
|
-
|
|
1532
|
-
|
|
1604
|
+
const key = "key" + counter++;
|
|
1605
|
+
src.push(`for (const ${key} in ${varName}) {`);
|
|
1606
|
+
addEvaluatedProperty(src, key, trackingState);
|
|
1533
1607
|
let checks = [];
|
|
1534
1608
|
if (explicitProps.length > 0) {
|
|
1535
1609
|
const allowedCheck = explicitProps
|
|
1536
|
-
.map((
|
|
1610
|
+
.map((keyItem) => `${key} === ${JSON.stringify(keyItem)}`)
|
|
1537
1611
|
.join(" || ");
|
|
1538
1612
|
checks.push(allowedCheck);
|
|
1539
1613
|
}
|
|
@@ -1545,7 +1619,7 @@ class Compiler {
|
|
|
1545
1619
|
pname = "patternProp" + counter++;
|
|
1546
1620
|
this.regexCache.set(pattern, pname);
|
|
1547
1621
|
}
|
|
1548
|
-
return `${pname}.test(key)`;
|
|
1622
|
+
return `${pname}.test(${key})`;
|
|
1549
1623
|
})
|
|
1550
1624
|
.join(" || ");
|
|
1551
1625
|
checks.push(patternCheck);
|
|
@@ -1556,17 +1630,18 @@ class Compiler {
|
|
|
1556
1630
|
}
|
|
1557
1631
|
const additionalPropValidation = this.compileSchema(schema.additionalProperties, {
|
|
1558
1632
|
schema: `${pathContext.schema}/additionalProperties`,
|
|
1559
|
-
data: `${pathContext.data}/\${key}`,
|
|
1560
|
-
$data: `${pathContext.$data}/\${key}`,
|
|
1633
|
+
data: `${pathContext.data}/\${${key}}`,
|
|
1634
|
+
$data: `${pathContext.$data}/\${${key}}`,
|
|
1561
1635
|
alt: pathContext.alt,
|
|
1562
1636
|
alt2: pathContext.alt2,
|
|
1563
|
-
}, {}, `${varName}[key]`, extra);
|
|
1637
|
+
}, {}, `${varName}[${key}]`, extra);
|
|
1564
1638
|
src.push(additionalPropValidation, "}");
|
|
1565
1639
|
if (extra.before != "")
|
|
1566
1640
|
src.push(`}`);
|
|
1567
1641
|
}
|
|
1568
1642
|
handlePropertyConstraints(src, schema, varName, pathContext, extra) {
|
|
1569
|
-
|
|
1643
|
+
const objKeys = "objKeys" + counter++;
|
|
1644
|
+
src.push(`const ${objKeys} = Object.keys(${varName});`);
|
|
1570
1645
|
if (schema.minProperties !== undefined) {
|
|
1571
1646
|
const isDataRef = this.options.$data && isDataReference(schema.minProperties);
|
|
1572
1647
|
let comparisonTarget;
|
|
@@ -1578,9 +1653,9 @@ class Compiler {
|
|
|
1578
1653
|
else {
|
|
1579
1654
|
comparisonTarget = schema.minProperties;
|
|
1580
1655
|
}
|
|
1581
|
-
src.push(`if (${extra.before}objKeys.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1656
|
+
src.push(`if (${extra.before}${objKeys}.length < ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1582
1657
|
keyword: "minProperties",
|
|
1583
|
-
value:
|
|
1658
|
+
value: `${objKeys}.length`,
|
|
1584
1659
|
message: `"Object must have at least " + ${comparisonTarget} + " properties."`,
|
|
1585
1660
|
expected: comparisonTarget,
|
|
1586
1661
|
})}${extra.after}}`);
|
|
@@ -1599,9 +1674,9 @@ class Compiler {
|
|
|
1599
1674
|
else {
|
|
1600
1675
|
comparisonTarget = schema.maxProperties;
|
|
1601
1676
|
}
|
|
1602
|
-
src.push(`if (${extra.before}objKeys.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1677
|
+
src.push(`if (${extra.before}${objKeys}.length > ${comparisonTarget}) {${this.buildErrorReturn(pathContext, {
|
|
1603
1678
|
keyword: "maxProperties",
|
|
1604
|
-
value:
|
|
1679
|
+
value: `${objKeys}.length`,
|
|
1605
1680
|
message: `"Object must have at most " + ${comparisonTarget} + " properties."`,
|
|
1606
1681
|
expected: comparisonTarget,
|
|
1607
1682
|
})}${extra.after}}`);
|
|
@@ -1613,14 +1688,15 @@ class Compiler {
|
|
|
1613
1688
|
handlePropertyNames(src, schema, varName, pathContext, extra) {
|
|
1614
1689
|
if (extra.before != "")
|
|
1615
1690
|
src.push(`if(${extra.before} true){`);
|
|
1616
|
-
|
|
1691
|
+
const key = "key" + counter++;
|
|
1692
|
+
src.push(`for (const ${key} in ${varName}) {`);
|
|
1617
1693
|
const propertyNameValidation = this.compileSchema(schema.propertyNames, {
|
|
1618
1694
|
schema: `${pathContext.schema}/propertyNames`,
|
|
1619
|
-
data: `${pathContext.data}/\${key}`,
|
|
1620
|
-
$data: `${pathContext.$data}/\${key}`,
|
|
1695
|
+
data: `${pathContext.data}/\${${key}}`,
|
|
1696
|
+
$data: `${pathContext.$data}/\${${key}}`,
|
|
1621
1697
|
alt: pathContext.alt,
|
|
1622
1698
|
alt2: pathContext.alt2,
|
|
1623
|
-
}, {},
|
|
1699
|
+
}, {}, key, extra);
|
|
1624
1700
|
src.push(propertyNameValidation, "}");
|
|
1625
1701
|
if (extra.before != "")
|
|
1626
1702
|
src.push(`}`);
|
|
@@ -1732,7 +1808,8 @@ class Compiler {
|
|
|
1732
1808
|
const evalSet = trackingState.unevaluatedPropVar;
|
|
1733
1809
|
if (extra.before != "")
|
|
1734
1810
|
src.push(`if(${extra.before} true){`);
|
|
1735
|
-
|
|
1811
|
+
const key = "key" + counter++;
|
|
1812
|
+
src.push(`const ${unName} = [];`, `for (const ${key} in ${varName}) {`, `if (!${evalSet}.has(${key})) {`, `${unName}.push(${key});`, `}`, `}`);
|
|
1736
1813
|
if (schema.unevaluatedProperties === false) {
|
|
1737
1814
|
src.push(`if (${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
|
|
1738
1815
|
keyword: "unevaluatedProperties",
|
|
@@ -1745,7 +1822,8 @@ class Compiler {
|
|
|
1745
1822
|
}
|
|
1746
1823
|
else if (schema.unevaluatedProperties === true) {
|
|
1747
1824
|
if (trackingState.parentHasUnevaluatedProperties) {
|
|
1748
|
-
|
|
1825
|
+
const key = "key" + counter++;
|
|
1826
|
+
src.push(`for(const ${key} in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(${key})}`);
|
|
1749
1827
|
}
|
|
1750
1828
|
}
|
|
1751
1829
|
else {
|
|
@@ -2063,7 +2141,8 @@ class Compiler {
|
|
|
2063
2141
|
const evalSet = trackingState.unevaluatedItemVar;
|
|
2064
2142
|
if (extra.before != "")
|
|
2065
2143
|
src.push(`if(${extra.before} true){`);
|
|
2066
|
-
|
|
2144
|
+
const i = "i" + counter++;
|
|
2145
|
+
src.push(`const ${unName} = [];`, `for (let ${i} = 0; ${i} < ${varName}.length; ${i}++) {`, `if (!${evalSet}.has(${i})) {`, `${unName}.push(${i});`, `}`, `}`);
|
|
2067
2146
|
if (schema.unevaluatedItems === false) {
|
|
2068
2147
|
src.push(`if (${extra.before}${unName}.length > 0) {${this.buildErrorReturn(pathContext, {
|
|
2069
2148
|
keyword: "unevaluatedItems",
|
|
@@ -2101,9 +2180,7 @@ class Compiler {
|
|
|
2101
2180
|
buildErrorReturn(pathContext, error, spreads) {
|
|
2102
2181
|
if (this.notLogic)
|
|
2103
2182
|
return "";
|
|
2104
|
-
|
|
2105
|
-
return "return false;";
|
|
2106
|
-
let result = this.options.allErrors
|
|
2183
|
+
let result = this.options.allErrors || this.noreturn
|
|
2107
2184
|
? `${this.errorVariable}.push({`
|
|
2108
2185
|
: `${this.mainFunctionName}.errors = [{`;
|
|
2109
2186
|
const escapedDataPath = (0, utilities_1.escapeTemplateString)(error.dataPath || pathContext.data || "/");
|
|
@@ -2184,7 +2261,7 @@ class Compiler {
|
|
|
2184
2261
|
result += `,${spreads}`;
|
|
2185
2262
|
}
|
|
2186
2263
|
result += "}";
|
|
2187
|
-
if (this.options.allErrors) {
|
|
2264
|
+
if (this.options.allErrors || this.noreturn) {
|
|
2188
2265
|
result += ");";
|
|
2189
2266
|
}
|
|
2190
2267
|
else {
|