@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.
@@ -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 = (schema.default === undefined || !this.options.useDefaults) &&
310
- !this.options.removeAdditional &&
311
- !this.options.coerceTypes
308
+ const varName = accessPattern === "rootData" ||
309
+ (inlined && (schema.default === undefined || !this.options.useDefaults))
312
310
  ? accessPattern
313
- : "var" + counter++;
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 (schema.default !== undefined && this.options.useDefaults) {
358
- src.push(`let ${varName} = ${accessPattern};`, `if (${varName} === undefined || ${varName} === null) {`, `${varName} = ${JSON.stringify(schema.default)};`, "}");
359
- }
360
- else if (this.options.removeAdditional || this.options.coerceTypes) {
361
- src.push(`let ${varName} = ${accessPattern};`);
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) {${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);${extra.refAfter || extra.after}}`);
480
+ src.push(`if (!${funcValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${schema.__functionName}.errors);`}}`);
478
481
  }
479
482
  else {
480
- src.push(`if (!${funcValidator}Result){${this.mainFunctionName}.errors = ${schema.__functionName}.errors;${extra.refAfter ?? extra.after}${this.noreturn ? "" : "return false;"}}`);
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) {${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);${extra.refAfter || extra.after}}`);
519
+ src.push(`if (!${refValidator}Result){${extra.after}${this.notLogic ? "" : `${this.errorVariable} = ${this.errorVariable}.concat(${functionName}.errors);`}}`);
507
520
  }
508
521
  else {
509
- src.push(`if (!${refValidator}Result){${this.mainFunctionName}.errors = ${functionName}.errors;${extra.refAfter ?? extra.after}${this.noreturn ? "" : "return false;"}}`);
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 = "anyOfErr" + counter++;
568
- if (!this.options.allErrors && !this.notLogic)
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;${this.notLogic ? "" : `${anyOfError}.push(${this.mainFunctionName}.errors[0]);`}`,
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
- src.push(`if (${anyOfValid}){${this.mainFunctionName}.errors = undefined}else {${this.notLogic ? "" : `${this.mainFunctionName}.errors = ${anyOfError};`}${extra.refAfter ?? extra.after}${this.noreturn ? "" : "return false;"}}`);
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 = `oneOfErrors${counter++}`;
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 && !this.notLogic)
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;${this.notLogic ? "" : `${oneOfErrors}.push(${this.mainFunctionName}.errors[0]);`}`,
664
- refAfter: `${branch} = false;${this.notLogic ? "" : `${oneOfErrors} = ${oneOfErrors}.concat(${this.mainFunctionName}.errors);`}`,
702
+ after: `${branch} = false;`,
665
703
  }, true);
666
704
  }
667
- this.noreturn = noreturn;
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};} else{${this.buildErrorReturn(pathContext, {
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
- const noreturn = this.noreturn;
718
- this.noreturn = true;
719
- src.push(`if (${validSchemaCount} == 1){${this.mainFunctionName}.errors = undefined}else {${this.buildErrorReturn(pathContext, {
720
- keyword: "oneOf",
721
- value: varName,
722
- message: `"Data must validate against exactly one schema, but matched "+ ${validSchemaCount}`,
723
- expected: '"exactly one schema"',
724
- })}${this.notLogic ? "" : `${oneOfErrors}.push(${this.mainFunctionName}.errors[0]);${this.mainFunctionName}.errors = ${oneOfErrors};`}${extra.refAfter ?? extra.after}${noreturn ? "" : "return false;"}}`);
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
- src.push(`const multipleOf = ${comparisonTarget};
1191
- const quotient = ${varName} / multipleOf;
1192
- const rounded = Math.round(quotient);
1193
- const tolerance = Math.abs(quotient) * Number.EPSILON;
1194
- if (${extra.before}multipleOf === 0 || !isFinite(quotient) || Math.abs(quotient - rounded) > tolerance) {${this.buildErrorReturn(pathContext, {
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
- 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, {
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
- throw new Error(`Format '${schema.format}' not found`);
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
- src.push(`for (let i = 0; i < ${requiredArrayExpr}.length; i++) {`);
1407
- src.push(`const prop = ${requiredArrayExpr}[i];`);
1408
- addEvaluatedProperty(src, "prop", trackingState);
1409
- src.push(`if (${extra.before}${varName}[prop] === undefined) {${this.buildErrorReturn(pathContext, {
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: "prop",
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
- src.push(`for (let ${iVar} = 0; ${iVar} < ${arrVar}.length; ${iVar}++) {`);
1434
- src.push(`const prop = ${arrVar}[${iVar}];`);
1435
- addEvaluatedProperty(src, "prop", trackingState);
1436
- src.push(`if (${extra.before}${varName}[prop] === undefined) {${this.buildErrorReturn(pathContext, {
1437
- keyword: "required",
1438
- value: varName,
1439
- message: `"Missing required field: " + prop + " in data."`,
1440
- expected: "prop",
1441
- schemaPath: `${pathContext.schema}`,
1442
- })}${extra.after}}`);
1443
- src.push(`}`);
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
- src.push(`for (const key in ${varName}) {`);
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, "key", trackingState);
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
- src.push(`for (const key in ${varName}) {`);
1532
- addEvaluatedProperty(src, "key", trackingState);
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((key) => `key === ${JSON.stringify(key)}`)
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
- src.push(`const objKeys = Object.keys(${varName});`);
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: "objKeys.length",
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: "objKeys.length",
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
- src.push(`for (const key in ${varName}) {`);
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
- }, {}, `key`, extra);
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
- src.push(`const ${unName} = [];`, `for (const key in ${varName}) {`, `if (!${evalSet}.has(key)) {`, `${unName}.push(key);`, `}`, `}`);
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
- src.push(`for(const key in ${varName}){${trackingState.parentUnevaluatedPropVar}.add(key)}`);
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
- src.push(`const ${unName} = [];`, `for (let i = 0; i < ${varName}.length; i++) {`, `if (!${evalSet}.has(i)) {`, `${unName}.push(i);`, `}`, `}`);
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
- if (this.neutralError)
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 {