@@ -243,15 +243,6 @@ function inferTypeByKeyword (schema) {
243
243
return schema . type
244
244
}
245
245
246
- function getStringSerializer ( format , nullable ) {
247
- switch ( format ) {
248
- case 'date-time' : return nullable ? 'serializer.asDatetimeNullable.bind(serializer)' : 'serializer.asDatetime.bind(serializer)'
249
- case 'date' : return nullable ? 'serializer.asDateNullable.bind(serializer)' : 'serializer.asDate.bind(serializer)'
250
- case 'time' : return nullable ? 'serializer.asTimeNullable.bind(serializer)' : 'serializer.asTime.bind(serializer)'
251
- default : return nullable ? 'serializer.asStringNullable.bind(serializer)' : 'serializer.asString.bind(serializer)'
252
- }
253
- }
254
-
255
246
function addPatternProperties ( location ) {
256
247
const schema = location . schema
257
248
const pp = schema . patternProperties
@@ -484,6 +475,16 @@ function mergeAllOfSchema (location, schema, mergedSchema) {
484
475
mergedSchema . anyOf . push ( ...allOfSchema . anyOf )
485
476
}
486
477
478
+ if ( allOfSchema . fjs_type !== undefined ) {
479
+ if (
480
+ mergedSchema . fjs_type !== undefined &&
481
+ mergedSchema . fjs_type !== allOfSchema . fjs_type
482
+ ) {
483
+ throw new Error ( 'allOf schemas have different fjs_type values' )
484
+ }
485
+ mergedSchema . fjs_type = allOfSchema . fjs_type
486
+ }
487
+
487
488
if ( allOfSchema . allOf !== undefined ) {
488
489
mergeAllOfSchema ( location , allOfSchema , mergedSchema )
489
490
}
@@ -790,20 +791,22 @@ function buildValue (location, input) {
790
791
location . schema = mergedSchema
791
792
}
792
793
793
- const type = schema . type
794
+ let type = schema . type
794
795
const nullable = schema . nullable === true
795
796
796
797
let code = ''
797
798
let funcName
798
799
800
+ if ( schema . fjs_type === 'string' && schema . format === undefined && Array . isArray ( schema . type ) && schema . type . length === 2 ) {
801
+ type = 'string'
802
+ }
803
+
799
804
switch ( type ) {
800
805
case 'null' :
801
- code += `
802
- json += serializer.asNull()
803
- `
806
+ code += 'json += serializer.asNull()'
804
807
break
805
808
case 'string' : {
806
- funcName = getStringSerializer ( schema . format , nullable )
809
+ funcName = nullable ? 'serializer.asStringNullable.bind(serializer)' : 'serializer.asString.bind(serializer)'
807
810
code += `json += ${ funcName } (${ input } )`
808
811
break
809
812
}
@@ -820,19 +823,23 @@ function buildValue (location, input) {
820
823
code += `json += ${ funcName } (${ input } )`
821
824
break
822
825
case 'object' :
823
- funcName = buildObject ( location )
826
+ if ( schema . format === 'date-time' ) {
827
+ funcName = nullable ? 'serializer.asDateTimeNullable.bind(serializer)' : 'serializer.asDateTime.bind(serializer)'
828
+ } else if ( schema . format === 'date' ) {
829
+ funcName = nullable ? 'serializer.asDateNullable.bind(serializer)' : 'serializer.asDate.bind(serializer)'
830
+ } else if ( schema . format === 'time' ) {
831
+ funcName = nullable ? 'serializer.asTimeNullable.bind(serializer)' : 'serializer.asTime.bind(serializer)'
832
+ } else {
833
+ funcName = buildObject ( location )
834
+ }
824
835
code += `json += ${ funcName } (${ input } )`
825
836
break
826
837
case 'array' :
827
838
funcName = buildArray ( location )
828
839
code += `json += ${ funcName } (${ input } )`
829
840
break
830
841
case undefined :
831
- if ( schema . fjs_date_type ) {
832
- funcName = getStringSerializer ( schema . fjs_date_type , nullable )
833
- code += `json += ${ funcName } (${ input } )`
834
- break
835
- } else if ( schema . anyOf || schema . oneOf ) {
842
+ if ( schema . anyOf || schema . oneOf ) {
836
843
// beware: dereferenceOfRefs has side effects and changes schema.anyOf
837
844
const type = schema . anyOf ? 'anyOf' : 'oneOf'
838
845
const anyOfLocation = mergeLocation ( location , type )
@@ -890,7 +897,7 @@ function buildValue (location, input) {
890
897
switch ( type ) {
891
898
case 'string' : {
892
899
code += `
893
- ${ statement } (${ input } === null || typeof ${ input } === "${ type } " || ${ input } instanceof Date || ${ input } instanceof RegExp || (typeof ${ input } === "object" && Object.hasOwnProperty.call(${ input } , "toString")))
900
+ ${ statement } (${ input } === null || typeof ${ input } === "${ type } " || ${ input } instanceof RegExp || (typeof ${ input } === "object" && Object.hasOwnProperty.call(${ input } , "toString")))
894
901
${ nestedResult }
895
902
`
896
903
break
@@ -909,6 +916,20 @@ function buildValue (location, input) {
909
916
`
910
917
break
911
918
}
919
+ case 'object' : {
920
+ if ( schema . fjs_type ) {
921
+ code += `
922
+ ${ statement } (${ input } instanceof Date || ${ input } === null)
923
+ ${ nestedResult }
924
+ `
925
+ } else {
926
+ code += `
927
+ ${ statement } (typeof ${ input } === "object" || ${ input } === null)
928
+ ${ nestedResult }
929
+ `
930
+ }
931
+ break
932
+ }
912
933
default : {
913
934
code += `
914
935
${ statement } (typeof ${ input } === "${ type } " || ${ input } === null)
@@ -936,15 +957,21 @@ function buildValue (location, input) {
936
957
}
937
958
938
959
// Ajv does not support js date format. In order to properly validate objects containing a date,
939
- // it needs to replace all occurrences of the string date format with a custom keyword fjs_date_type .
960
+ // it needs to replace all occurrences of the string date format with a custom keyword fjs_type .
940
961
// (see https://github.com/fastify/fast-json-stringify/pull/441)
941
962
function extendDateTimeType ( schema ) {
942
963
if ( schema === null ) return
943
964
944
- if ( schema . type === 'string' && [ 'date-time' , 'date' , 'time' ] . includes ( schema . format ) ) {
945
- schema . fjs_date_type = schema . format
946
- delete schema . type
947
- delete schema . format
965
+ if ( schema . type === 'string' ) {
966
+ schema . fjs_type = 'string'
967
+ schema . type = [ 'string' , 'object' ]
968
+ } else if (
969
+ Array . isArray ( schema . type ) &&
970
+ schema . type . includes ( 'string' ) &&
971
+ ! schema . type . includes ( 'object' )
972
+ ) {
973
+ schema . fjs_type = 'string'
974
+ schema . type . push ( 'object' )
948
975
}
949
976
for ( const property in schema ) {
950
977
if ( typeof schema [ property ] === 'object' ) {
0 commit comments