@@ -228,6 +228,10 @@ function getStringSerializer (format) {
228
228
'$asString'
229
229
}
230
230
231
+ function getTestSerializer ( format ) {
232
+ return stringSerializerMap [ format ]
233
+ }
234
+
231
235
function $pad2Zeros ( num ) {
232
236
const s = '00' + num
233
237
return s [ s . length - 2 ] + s [ s . length - 1 ]
@@ -280,37 +284,40 @@ function $asBooleanNullable (bool) {
280
284
return bool === null ? null : $asBoolean ( bool )
281
285
}
282
286
283
- function $asDatetime ( date ) {
287
+ function $asDatetime ( date , skipQuotes ) {
288
+ const quotes = skipQuotes === true ? '' : '"'
284
289
if ( date instanceof Date ) {
285
- return '"' + date . toISOString ( ) + '"'
290
+ return quotes + date . toISOString ( ) + quotes
286
291
} else if ( date && typeof date . toISOString === 'function' ) {
287
- return '"' + date . toISOString ( ) + '"'
292
+ return quotes + date . toISOString ( ) + quotes
288
293
} else {
289
294
return $asString ( date )
290
295
}
291
296
}
292
297
293
- function $asDate ( date ) {
298
+ function $asDate ( date , skipQuotes ) {
299
+ const quotes = skipQuotes === true ? '' : '"'
294
300
if ( date instanceof Date ) {
295
301
const year = new Intl . DateTimeFormat ( 'en' , { year : 'numeric' } ) . format ( date )
296
302
const month = new Intl . DateTimeFormat ( 'en' , { month : '2-digit' } ) . format ( date )
297
303
const day = new Intl . DateTimeFormat ( 'en' , { day : '2-digit' } ) . format ( date )
298
- return '"' + year + '-' + month + '-' + day + '"'
304
+ return quotes + year + '-' + month + '-' + day + quotes
299
305
} else if ( date && typeof date . format === 'function' ) {
300
- return '"' + date . format ( 'YYYY-MM-DD' ) + '"'
306
+ return quotes + date . format ( 'YYYY-MM-DD' ) + quotes
301
307
} else {
302
308
return $asString ( date )
303
309
}
304
310
}
305
311
306
- function $asTime ( date ) {
312
+ function $asTime ( date , skipQuotes ) {
313
+ const quotes = skipQuotes === true ? '' : '"'
307
314
if ( date instanceof Date ) {
308
315
const hour = new Intl . DateTimeFormat ( 'en' , { hour : 'numeric' , hour12 : false } ) . format ( date )
309
316
const minute = new Intl . DateTimeFormat ( 'en' , { minute : 'numeric' } ) . format ( date )
310
317
const second = new Intl . DateTimeFormat ( 'en' , { second : 'numeric' } ) . format ( date )
311
- return '"' + $pad2Zeros ( hour ) + ':' + $pad2Zeros ( minute ) + ':' + $pad2Zeros ( second ) + '"'
318
+ return quotes + $pad2Zeros ( hour ) + ':' + $pad2Zeros ( minute ) + ':' + $pad2Zeros ( second ) + quotes
312
319
} else if ( date && typeof date . format === 'function' ) {
313
- return '"' + date . format ( 'HH:mm:ss' ) + '"'
320
+ return quotes + date . format ( 'HH:mm:ss' ) + quotes
314
321
} else {
315
322
return $asString ( date )
316
323
}
@@ -1177,6 +1184,11 @@ function nested (laterCode, name, key, location, subKey, isArray) {
1177
1184
const anyOfLocations = dereferenceOfRefs ( location , 'anyOf' )
1178
1185
anyOfLocations . forEach ( ( location , index ) => {
1179
1186
const nestedResult = nested ( laterCode , name , key , location , subKey !== '' ? subKey : 'i' + index , isArray )
1187
+ // We need a test serializer as the String serializer will not work with
1188
+ // date/time ajv validations
1189
+ // see: https://github.com/fastify/fast-json-stringify/issues/325
1190
+ const testSerializer = getTestSerializer ( location . schema . format )
1191
+ const testValue = testSerializer !== undefined ? `${ testSerializer } (obj${ accessor } , true)` : `obj${ accessor } `
1180
1192
1181
1193
// Since we are only passing the relevant schema to ajv.validate, it needs to be full dereferenced
1182
1194
// otherwise any $ref pointing to an external schema would result in an error.
@@ -1186,7 +1198,7 @@ function nested (laterCode, name, key, location, subKey, isArray) {
1186
1198
// 2. `nested`, through `buildCode`, replaces any reference in object properties with the actual schema
1187
1199
// (see https://github.com/fastify/fast-json-stringify/blob/6da3b3e8ac24b1ca5578223adedb4083b7adf8db/index.js#L631)
1188
1200
code += `
1189
- ${ index === 0 ? 'if' : 'else if' } (ajv.validate(${ JSON . stringify ( location . schema ) } , obj ${ accessor } ))
1201
+ ${ index === 0 ? 'if' : 'else if' } (ajv.validate(${ JSON . stringify ( location . schema ) } , ${ testValue } ))
1190
1202
${ nestedResult . code }
1191
1203
`
1192
1204
laterCode = nestedResult . laterCode
@@ -1199,10 +1211,11 @@ function nested (laterCode, name, key, location, subKey, isArray) {
1199
1211
const oneOfLocations = dereferenceOfRefs ( location , 'oneOf' )
1200
1212
oneOfLocations . forEach ( ( location , index ) => {
1201
1213
const nestedResult = nested ( laterCode , name , key , location , subKey !== '' ? subKey : 'i' + index , isArray )
1202
-
1203
- // see comment on anyOf about derefencing the schema before calling ajv.validate
1214
+ const testSerializer = getTestSerializer ( location . schema . format )
1215
+ const testValue = testSerializer !== undefined ? `${ testSerializer } (obj${ accessor } , true)` : `obj${ accessor } `
1216
+ // see comment on anyOf about dereferencing the schema before calling ajv.validate
1204
1217
code += `
1205
- ${ index === 0 ? 'if' : 'else if' } (ajv.validate(${ JSON . stringify ( location . schema ) } , obj ${ accessor } ))
1218
+ ${ index === 0 ? 'if' : 'else if' } (ajv.validate(${ JSON . stringify ( location . schema ) } , ${ testValue } ))
1206
1219
${ nestedResult . code }
1207
1220
`
1208
1221
laterCode = nestedResult . laterCode
0 commit comments