@@ -10,6 +10,7 @@ const validate = require('./lib/schema-validator')
1010const Serializer = require ( './lib/serializer' )
1111const Validator = require ( './lib/validator' )
1212const RefResolver = require ( './lib/ref-resolver' )
13+ const Location = require ( './lib/location' )
1314
1415let largeArraySize = 2e4
1516let largeArrayMechanism = 'default'
@@ -40,22 +41,13 @@ function isValidSchema (schema, name) {
4041 }
4142}
4243
43- function mergeLocation ( location , key ) {
44- return {
45- schema : location . schema [ key ] ,
46- schemaId : location . schemaId ,
47- jsonPointer : location . jsonPointer + '/' + key ,
48- isValidated : location . isValidated
49- }
50- }
51-
5244function resolveRef ( location , ref ) {
5345 let hashIndex = ref . indexOf ( '#' )
5446 if ( hashIndex === - 1 ) {
5547 hashIndex = ref . length
5648 }
5749
58- const schemaId = ref . slice ( 0 , hashIndex ) || location . schemaId
50+ const schemaId = ref . slice ( 0 , hashIndex ) || location . getOriginSchemaId ( )
5951 const jsonPointer = ref . slice ( hashIndex ) || '#'
6052
6153 const schema = refResolver . getSchema ( schemaId , jsonPointer )
@@ -68,11 +60,12 @@ function resolveRef (location, ref) {
6860 validatorSchemasIds . add ( schemaId )
6961 }
7062
63+ const newLocation = new Location ( schema , schemaId , jsonPointer , location . isValidated )
7164 if ( schema . $ref !== undefined ) {
72- return resolveRef ( { schema , schemaId , jsonPointer } , schema . $ref )
65+ return resolveRef ( newLocation , schema . $ref )
7366 }
7467
75- return { schema , schemaId , jsonPointer , isValidated : location . isValidated }
68+ return newLocation
7669}
7770
7871const contextFunctionsNamesBySchema = new Map ( )
@@ -125,7 +118,7 @@ function build (schema, options) {
125118 }
126119 }
127120
128- const location = { schema, schemaId : rootSchemaId , jsonPointer : '#' , isValidated : false }
121+ const location = new Location ( schema , rootSchemaId )
129122 const code = buildValue ( location , 'input' )
130123
131124 const contextFunctionCode = `
@@ -253,17 +246,17 @@ function buildExtraObjectPropertiesSerializer (location) {
253246 ) continue
254247 `
255248
256- const patternPropertiesLocation = mergeLocation ( location , 'patternProperties' )
249+ const patternPropertiesLocation = location . getPropertyLocation ( 'patternProperties' )
257250 const patternPropertiesSchema = patternPropertiesLocation . schema
258251
259252 if ( patternPropertiesSchema !== undefined ) {
260253 for ( const propertyKey in patternPropertiesSchema ) {
261- const propertyLocation = mergeLocation ( patternPropertiesLocation , propertyKey )
254+ const propertyLocation = patternPropertiesLocation . getPropertyLocation ( propertyKey )
262255
263256 try {
264257 RegExp ( propertyKey )
265258 } catch ( err ) {
266- const jsonPointer = propertyLocation . schema + propertyLocation . jsonPointer
259+ const jsonPointer = propertyLocation . getSchemaRef ( )
267260 throw new Error ( `${ err . message } . Invalid pattern property regexp key ${ propertyKey } at ${ jsonPointer } ` )
268261 }
269262
@@ -278,7 +271,7 @@ function buildExtraObjectPropertiesSerializer (location) {
278271 }
279272 }
280273
281- const additionalPropertiesLocation = mergeLocation ( location , 'additionalProperties' )
274+ const additionalPropertiesLocation = location . getPropertyLocation ( 'additionalProperties' )
282275 const additionalPropertiesSchema = additionalPropertiesLocation . schema
283276
284277 if ( additionalPropertiesSchema !== undefined ) {
@@ -288,7 +281,7 @@ function buildExtraObjectPropertiesSerializer (location) {
288281 json += serializer.asString(key) + ':' + JSON.stringify(value)
289282 `
290283 } else {
291- const propertyLocation = mergeLocation ( location , 'additionalProperties' )
284+ const propertyLocation = location . getPropertyLocation ( 'additionalProperties' )
292285 code += `
293286 ${ addComma }
294287 json += serializer.asString(key) + ':'
@@ -309,9 +302,9 @@ function buildInnerObject (location) {
309302
310303 let code = ''
311304
312- const propertiesLocation = mergeLocation ( location , 'properties' )
305+ const propertiesLocation = location . getPropertyLocation ( 'properties' )
313306 Object . keys ( schema . properties || { } ) . forEach ( ( key ) => {
314- let propertyLocation = mergeLocation ( propertiesLocation , key )
307+ let propertyLocation = propertiesLocation . getPropertyLocation ( key )
315308 if ( propertyLocation . schema . $ref ) {
316309 propertyLocation = resolveRef ( location , propertyLocation . schema . $ref )
317310 }
@@ -362,13 +355,13 @@ function buildInnerObject (location) {
362355}
363356
364357function mergeAllOfSchema ( location , schema , mergedSchema ) {
365- const allOfLocation = mergeLocation ( location , 'allOf' )
358+ const allOfLocation = location . getPropertyLocation ( 'allOf' )
366359
367360 for ( let i = 0 ; i < schema . allOf . length ; i ++ ) {
368361 let allOfSchema = schema . allOf [ i ]
369362
370363 if ( allOfSchema . $ref ) {
371- const allOfSchemaLocation = mergeLocation ( allOfLocation , i )
364+ const allOfSchemaLocation = allOfLocation . getPropertyLocation ( i )
372365 allOfSchema = resolveRef ( allOfSchemaLocation , allOfSchema . $ref ) . schema
373366 }
374367
@@ -457,13 +450,12 @@ function mergeAllOfSchema (location, schema, mergedSchema) {
457450
458451 mergedSchema . $id = `merged_${ randomUUID ( ) } `
459452 refResolver . addSchema ( mergedSchema )
460- location . schemaId = mergedSchema . $id
461- location . jsonPointer = '#'
453+ location . addMergedSchema ( mergedSchema , mergedSchema . $id )
462454}
463455
464456function addIfThenElse ( location , input ) {
465457 location . isValidated = true
466- validatorSchemasIds . add ( location . schemaId )
458+ validatorSchemasIds . add ( location . getSchemaId ( ) )
467459
468460 const schema = merge ( { } , location . schema )
469461 const thenSchema = schema . then
@@ -473,13 +465,13 @@ function addIfThenElse (location, input) {
473465 delete schema . then
474466 delete schema . else
475467
476- const ifLocation = mergeLocation ( location , 'if' )
477- const ifSchemaRef = ifLocation . schemaId + ifLocation . jsonPointer
468+ const ifLocation = location . getPropertyLocation ( 'if' )
469+ const ifSchemaRef = ifLocation . getSchemaRef ( )
478470
479- const thenLocation = mergeLocation ( location , 'then' )
471+ const thenLocation = location . getPropertyLocation ( 'then' )
480472 thenLocation . schema = merge ( schema , thenSchema )
481473
482- const elseLocation = mergeLocation ( location , 'else' )
474+ const elseLocation = location . getPropertyLocation ( 'else' )
483475 elseLocation . schema = merge ( schema , elseSchema )
484476
485477 return `
@@ -508,10 +500,14 @@ function buildObject (location) {
508500 const functionName = generateFuncName ( )
509501 contextFunctionsNamesBySchema . set ( schema , functionName )
510502
511- const schemaId = location . schemaId === rootSchemaId ? '' : location . schemaId
503+ let schemaRef = location . getSchemaRef ( )
504+ if ( schemaRef . startsWith ( rootSchemaId ) ) {
505+ schemaRef = schemaRef . replace ( rootSchemaId , '' )
506+ }
507+
512508 let functionCode = `
513509 function ${ functionName } (input) {
514- // ${ schemaId + location . jsonPointer }
510+ // ${ schemaRef }
515511 `
516512
517513 functionCode += `
@@ -534,7 +530,7 @@ function buildObject (location) {
534530function buildArray ( location ) {
535531 const schema = location . schema
536532
537- let itemsLocation = mergeLocation ( location , 'items' )
533+ let itemsLocation = location . getPropertyLocation ( 'items' )
538534 itemsLocation . schema = itemsLocation . schema || { }
539535
540536 if ( itemsLocation . schema . $ref ) {
@@ -550,10 +546,14 @@ function buildArray (location) {
550546 const functionName = generateFuncName ( )
551547 contextFunctionsNamesBySchema . set ( schema , functionName )
552548
553- const schemaId = location . schemaId === rootSchemaId ? '' : location . schemaId
549+ let schemaRef = location . getSchemaRef ( )
550+ if ( schemaRef . startsWith ( rootSchemaId ) ) {
551+ schemaRef = schemaRef . replace ( rootSchemaId , '' )
552+ }
553+
554554 let functionCode = `
555555 function ${ functionName } (obj) {
556- // ${ schemaId + location . jsonPointer }
556+ // ${ schemaRef }
557557 `
558558
559559 functionCode += `
@@ -586,7 +586,7 @@ function buildArray (location) {
586586 if ( Array . isArray ( itemsSchema ) ) {
587587 for ( let i = 0 ; i < itemsSchema . length ; i ++ ) {
588588 const item = itemsSchema [ i ]
589- const tmpRes = buildValue ( mergeLocation ( itemsLocation , i ) , `obj[${ i } ]` )
589+ const tmpRes = buildValue ( itemsLocation . getPropertyLocation ( i ) , `obj[${ i } ]` )
590590 functionCode += `
591591 if (${ i } < arrayLength) {
592592 if (${ buildArrayTypeCondition ( item . type , `[${ i } ]` ) } ) {
@@ -682,11 +682,11 @@ function buildMultiTypeSerializer (location, input) {
682682
683683 let code = ''
684684
685- const locationClone = clone ( location )
686685 types . forEach ( ( type , index ) => {
686+ location . schema = { ...location . schema , type }
687+ const nestedResult = buildSingleTypeSerializer ( location , input )
688+
687689 const statement = index === 0 ? 'if' : 'else if'
688- locationClone . schema . type = type
689- const nestedResult = buildSingleTypeSerializer ( locationClone , input )
690690 switch ( type ) {
691691 case 'null' :
692692 code += `
@@ -831,10 +831,8 @@ function buildValue (location, input) {
831831 }
832832
833833 if ( schema . allOf ) {
834- const mergedSchema = clone ( schema )
835- mergeAllOfSchema ( location , schema , mergedSchema )
836- schema = mergedSchema
837- location . schema = mergedSchema
834+ mergeAllOfSchema ( location , schema , clone ( schema ) )
835+ schema = location . schema
838836 }
839837
840838 const type = schema . type
@@ -843,14 +841,14 @@ function buildValue (location, input) {
843841
844842 if ( type === undefined && ( schema . anyOf || schema . oneOf ) ) {
845843 location . isValidated = true
846- validatorSchemasIds . add ( location . schemaId )
844+ validatorSchemasIds . add ( location . getSchemaId ( ) )
847845
848846 const type = schema . anyOf ? 'anyOf' : 'oneOf'
849- const anyOfLocation = mergeLocation ( location , type )
847+ const anyOfLocation = location . getPropertyLocation ( type )
850848
851849 for ( let index = 0 ; index < location . schema [ type ] . length ; index ++ ) {
852- const optionLocation = mergeLocation ( anyOfLocation , index )
853- const schemaRef = optionLocation . schemaId + optionLocation . jsonPointer
850+ const optionLocation = anyOfLocation . getPropertyLocation ( index )
851+ const schemaRef = optionLocation . getSchemaRef ( )
854852 const nestedResult = buildValue ( optionLocation , input )
855853 code += `
856854 ${ index === 0 ? 'if' : 'else if' } (validator.validate("${ schemaRef } ", ${ input } ))
0 commit comments