@@ -378,6 +378,11 @@ function addPatternProperties (schema, externalSchema, fullSchema) {
378
378
var type = pp [ regex ] . type
379
379
var format = pp [ regex ] . format
380
380
var stringSerializer = getStringSerializer ( format )
381
+ try {
382
+ RegExp ( regex )
383
+ } catch ( err ) {
384
+ throw new Error ( `${ err . message } . Found at ${ regex } matching ${ JSON . stringify ( pp [ regex ] ) } ` )
385
+ }
381
386
code += `
382
387
if (/${ regex . replace ( / \\ * \/ / g, '\\/' ) } /.test(keys[i])) {
383
388
`
@@ -420,7 +425,7 @@ function addPatternProperties (schema, externalSchema, fullSchema) {
420
425
`
421
426
} else {
422
427
code += `
423
- throw new Error('Cannot coerce ' + obj[keys[i]] + ' to ${ type } ' )
428
+ throw new Error('Cannot coerce ' + obj[keys[i]] + ' to ' + ${ JSON . stringify ( type ) } )
424
429
`
425
430
}
426
431
@@ -513,7 +518,7 @@ function additionalProperty (schema, externalSchema, fullSchema) {
513
518
`
514
519
} else {
515
520
code += `
516
- throw new Error('Cannot coerce ' + obj[keys[i]] + ' to ${ type } ' )
521
+ throw new Error('Cannot coerce ' + obj[keys[i]] + ' to ' + ${ JSON . stringify ( type ) } )
517
522
`
518
523
}
519
524
return code
@@ -582,7 +587,7 @@ function refFinder (ref, schema, externalSchema) {
582
587
return dereferenced
583
588
} else {
584
589
for ( var i = 1 ; i < walk . length ; i ++ ) {
585
- code += `[' ${ sanitizeKey ( walk [ i ] ) } ' ]`
590
+ code += `[${ JSON . stringify ( walk [ i ] ) } ]`
586
591
}
587
592
}
588
593
}
@@ -598,34 +603,20 @@ function refFinder (ref, schema, externalSchema) {
598
603
599
604
function findBadKey ( obj , keys ) {
600
605
if ( keys . length === 0 ) return null
601
- const key = sanitizeKey ( keys . shift ( ) )
606
+ const key = keys . shift ( )
602
607
if ( obj [ key ] === undefined ) {
603
608
stringSimilarity = stringSimilarity || require ( 'string-similarity' )
604
609
const { bestMatch } = stringSimilarity . findBestMatch ( key , Object . keys ( obj ) )
605
610
if ( bestMatch . rating >= 0.5 ) {
606
- throw new Error ( `Cannot find reference ' ${ key } ' , did you mean ' ${ bestMatch . target } ' ?` )
611
+ throw new Error ( `Cannot find reference ${ JSON . stringify ( key ) } , did you mean ${ JSON . stringify ( bestMatch . target ) } ?` )
607
612
} else {
608
- throw new Error ( `Cannot find reference ' ${ key } ' ` )
613
+ throw new Error ( `Cannot find reference ${ JSON . stringify ( key ) } ` )
609
614
}
610
615
}
611
616
return findBadKey ( obj [ key ] , keys )
612
617
}
613
618
}
614
619
615
- function sanitizeKey ( key ) {
616
- const rep = key . replace ( / ( \\ * ) ' / g, function ( match , p1 ) {
617
- var base = ''
618
- if ( p1 . length % 2 === 1 ) {
619
- base = p1 . slice ( 2 )
620
- } else {
621
- base = p1
622
- }
623
- var rep = base + '\\\''
624
- return rep
625
- } )
626
- return rep
627
- }
628
-
629
620
function buildCode ( schema , code , laterCode , name , externalSchema , fullSchema ) {
630
621
if ( schema . $ref ) {
631
622
schema = refFinder ( schema . $ref , fullSchema , externalSchema )
@@ -645,51 +636,51 @@ function buildCode (schema, code, laterCode, name, externalSchema, fullSchema) {
645
636
646
637
var type = schema . properties [ key ] . type
647
638
var nullable = schema . properties [ key ] . nullable
648
- var sanitized = sanitizeKey ( key )
649
- var asString = sanitizeKey ( $asString ( key ) . replace ( / \\ / g , '\\\\' ) )
639
+ var sanitized = JSON . stringify ( key )
640
+ var asString = JSON . stringify ( sanitized )
650
641
651
642
if ( nullable ) {
652
643
code += `
653
- if (obj[' ${ sanitized } ' ] === null) {
644
+ if (obj[${ sanitized } ] === null) {
654
645
${ addComma }
655
- json += ' ${ asString } :null'
646
+ json += ${ asString } + ' :null'
656
647
var rendered = true
657
648
} else {
658
649
`
659
650
}
660
651
661
652
if ( type === 'number' ) {
662
653
code += `
663
- var t = Number(obj[' ${ sanitized } ' ])
654
+ var t = Number(obj[${ sanitized } ])
664
655
if (!isNaN(t)) {
665
656
${ addComma }
666
- json += ' ${ asString } :' + t
657
+ json += ${ asString } + ' :' + t
667
658
`
668
659
} else if ( type === 'integer' ) {
669
660
code += `
670
661
var rendered = false
671
662
`
672
663
if ( isLong ) {
673
664
code += `
674
- if (isLong(obj[' ${ sanitized } ' ])) {
665
+ if (isLong(obj[${ sanitized } ])) {
675
666
${ addComma }
676
- json += ' ${ asString } :' + obj[' ${ sanitized } ' ].toString()
667
+ json += ${ asString } + ' :' + obj[${ sanitized } ].toString()
677
668
rendered = true
678
669
} else {
679
- var t = Number(obj[' ${ sanitized } ' ])
670
+ var t = Number(obj[${ sanitized } ])
680
671
if (!isNaN(t)) {
681
672
${ addComma }
682
- json += ' ${ asString } :' + t
673
+ json += ${ asString } + ' :' + t
683
674
rendered = true
684
675
}
685
676
}
686
677
`
687
678
} else {
688
679
code += `
689
- var t = Number(obj[' ${ sanitized } ' ])
680
+ var t = Number(obj[${ sanitized } ])
690
681
if (!isNaN(t)) {
691
682
${ addComma }
692
- json += ' ${ asString } :' + t
683
+ json += ${ asString } + ' :' + t
693
684
rendered = true
694
685
}
695
686
`
@@ -699,12 +690,12 @@ function buildCode (schema, code, laterCode, name, externalSchema, fullSchema) {
699
690
`
700
691
} else {
701
692
code += `
702
- if (obj[' ${ sanitized } ' ] !== undefined) {
693
+ if (obj[${ sanitized } ] !== undefined) {
703
694
${ addComma }
704
- json += ' ${ asString } :'
695
+ json += ${ asString } + ' :'
705
696
`
706
697
707
- var result = nested ( laterCode , name , key , schema . properties [ key ] , externalSchema , fullSchema )
698
+ var result = nested ( laterCode , name , key , schema . properties [ key ] , externalSchema , fullSchema , undefined , false )
708
699
code += result . code
709
700
laterCode = result . laterCode
710
701
}
@@ -715,7 +706,7 @@ function buildCode (schema, code, laterCode, name, externalSchema, fullSchema) {
715
706
code += `
716
707
} else {
717
708
${ addComma }
718
- json += ' ${ asString } : ${ sanitizeKey ( JSON . stringify ( defaultValue ) . replace ( / \\ / g , '\\\\' ) ) } '
709
+ json += ${ asString } + ':' + ${ JSON . stringify ( JSON . stringify ( defaultValue ) ) }
719
710
`
720
711
} else if ( schema . required && schema . required . indexOf ( key ) !== - 1 ) {
721
712
required = filterRequired ( schema . required , key )
@@ -742,12 +733,12 @@ function buildCode (schema, code, laterCode, name, externalSchema, fullSchema) {
742
733
if ( i > 0 ) {
743
734
code += ','
744
735
}
745
- code += `${ $asString ( required [ i ] ) . replace ( / \\ / g , '\\\\' ) } `
736
+ code += `${ JSON . stringify ( required [ i ] ) } `
746
737
}
747
738
code += ']'
748
739
code += `
749
740
for (var i = 0; i < required.length; i++) {
750
- if (obj[required[i]] === undefined) throw new Error(required[i] + ' is required!')
741
+ if (obj[required[i]] === undefined) throw new Error('"' + required[i] + '" is required!')
751
742
}
752
743
`
753
744
}
@@ -922,7 +913,7 @@ function buildArray (schema, code, name, externalSchema, fullSchema) {
922
913
if ( Array . isArray ( schema . items ) ) {
923
914
result = schema . items . reduce ( ( res , item , i ) => {
924
915
var accessor = '[i]'
925
- const tmpRes = nested ( laterCode , name , accessor , item , externalSchema , fullSchema , i )
916
+ const tmpRes = nested ( laterCode , name , accessor , item , externalSchema , fullSchema , i , true )
926
917
var condition = `i === ${ i } && ${ buildArrayTypeCondition ( item . type , accessor ) } `
927
918
return {
928
919
code : `${ res . code }
@@ -939,7 +930,7 @@ function buildArray (schema, code, name, externalSchema, fullSchema) {
939
930
}
940
931
`
941
932
} else {
942
- result = nested ( laterCode , name , '[i]' , schema . items , externalSchema , fullSchema )
933
+ result = nested ( laterCode , name , '[i]' , schema . items , externalSchema , fullSchema , undefined , true )
943
934
}
944
935
945
936
code += `
@@ -1013,7 +1004,21 @@ function dereferenceOfRefs (schema, externalSchema, fullSchema, type) {
1013
1004
} )
1014
1005
}
1015
1006
1016
- function nested ( laterCode , name , key , schema , externalSchema , fullSchema , subKey ) {
1007
+ var strNameCounter = 0
1008
+ function asFuncName ( str ) {
1009
+ // only allow chars that can work
1010
+ var rep = str . replace ( / [ ^ a - z A - Z 0 - 9 $ _ ] / g, '' )
1011
+
1012
+ if ( rep . length === 0 ) {
1013
+ return 'anan' + strNameCounter ++
1014
+ } else if ( rep !== str ) {
1015
+ rep += strNameCounter ++
1016
+ }
1017
+
1018
+ return rep
1019
+ }
1020
+
1021
+ function nested ( laterCode , name , key , schema , externalSchema , fullSchema , subKey , isArray ) {
1017
1022
var code = ''
1018
1023
var funcName
1019
1024
@@ -1033,7 +1038,8 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
1033
1038
var type = schema . type
1034
1039
var nullable = schema . nullable === true
1035
1040
1036
- var accessor = key . indexOf ( '[' ) === 0 ? sanitizeKey ( key ) : `['${ sanitizeKey ( key ) } ']`
1041
+ var accessor = isArray ? key : `[${ JSON . stringify ( key ) } ]`
1042
+
1037
1043
switch ( type ) {
1038
1044
case 'null' :
1039
1045
code += `
@@ -1054,14 +1060,14 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
1054
1060
code += nullable ? `json += obj${ accessor } === null ? null : $asBoolean(obj${ accessor } )` : `json += $asBoolean(obj${ accessor } )`
1055
1061
break
1056
1062
case 'object' :
1057
- funcName = ( name + key + subKey ) . replace ( / [ - . \[ \] ] / g , '' ) . replace ( / [ @ ] / g , 'AT_SYMBOL' ) // eslint-disable-line
1063
+ funcName = asFuncName ( name + key + subKey )
1058
1064
laterCode = buildObject ( schema , laterCode , funcName , externalSchema , fullSchema )
1059
1065
code += `
1060
1066
json += ${ funcName } (obj${ accessor } )
1061
1067
`
1062
1068
break
1063
1069
case 'array' :
1064
- funcName = '$arr' + ( name + key + subKey ) . replace ( / [ - . \[ \] ] / g , '' ) . replace ( / [ @ ] / g , 'AT_SYMBOL' ) // eslint-disable-line
1070
+ funcName = asFuncName ( '$arr' + name + key + subKey ) // eslint-disable-line
1065
1071
laterCode = buildArray ( schema , laterCode , funcName , externalSchema , fullSchema )
1066
1072
code += `
1067
1073
json += ${ funcName } (obj${ accessor } )
@@ -1071,7 +1077,7 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
1071
1077
if ( 'anyOf' in schema ) {
1072
1078
dereferenceOfRefs ( schema , externalSchema , fullSchema , 'anyOf' )
1073
1079
schema . anyOf . forEach ( ( s , index ) => {
1074
- var nestedResult = nested ( laterCode , name , key , s , externalSchema , fullSchema , subKey !== '' ? subKey : 'i' + index )
1080
+ var nestedResult = nested ( laterCode , name , key , s , externalSchema , fullSchema , subKey !== '' ? subKey : 'i' + index , isArray )
1075
1081
code += `
1076
1082
${ index === 0 ? 'if' : 'else if' } (ajv.validate(${ require ( 'util' ) . inspect ( s , { depth : null } ) } , obj${ accessor } ))
1077
1083
${ nestedResult . code }
@@ -1084,7 +1090,7 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
1084
1090
} else if ( 'oneOf' in schema ) {
1085
1091
dereferenceOfRefs ( schema , externalSchema , fullSchema , 'oneOf' )
1086
1092
schema . oneOf . forEach ( ( s , index ) => {
1087
- var nestedResult = nested ( laterCode , name , key , s , externalSchema , fullSchema , subKey !== '' ? subKey : 'i' + index )
1093
+ var nestedResult = nested ( laterCode , name , key , s , externalSchema , fullSchema , subKey !== '' ? subKey : 'i' + index , isArray )
1088
1094
code += `
1089
1095
${ index === 0 ? 'if' : 'else if' } (ajv.validate(${ require ( 'util' ) . inspect ( s , { depth : null } ) } , obj${ accessor } ))
1090
1096
${ nestedResult . code }
@@ -1108,7 +1114,7 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
1108
1114
const sortedTypes = nullIndex !== - 1 ? [ type [ nullIndex ] ] . concat ( type . slice ( 0 , nullIndex ) ) . concat ( type . slice ( nullIndex + 1 ) ) : type
1109
1115
sortedTypes . forEach ( ( type , index ) => {
1110
1116
var tempSchema = Object . assign ( { } , schema , { type } )
1111
- var nestedResult = nested ( laterCode , name , key , tempSchema , externalSchema , fullSchema , subKey )
1117
+ var nestedResult = nested ( laterCode , name , key , tempSchema , externalSchema , fullSchema , subKey , isArray )
1112
1118
1113
1119
if ( type === 'string' ) {
1114
1120
code += `
0 commit comments