22
33const fastSafeStringify = require ( 'fast-safe-stringify' )
44
5- function build ( schema ) {
5+ function build ( schema , options ) {
6+ options = options || { }
67 /* eslint no-new-func: "off" */
78 var code = `
89 'use strict'
@@ -26,7 +27,7 @@ function build (schema) {
2627 switch ( schema . type ) {
2728 case 'object' :
2829 main = '$main'
29- code = buildObject ( schema , code , main )
30+ code = buildObject ( schema , code , main , options . schema )
3031 break
3132 case 'string' :
3233 main = $asString . name
@@ -43,7 +44,7 @@ function build (schema) {
4344 break
4445 case 'array' :
4546 main = '$main'
46- code = buildArray ( schema , code , main )
47+ code = buildArray ( schema , code , main , options . schema )
4748 break
4849 default :
4950 throw new Error ( `${ schema . type } unsupported` )
@@ -141,24 +142,28 @@ function $asRegExp (reg) {
141142 return '"' + reg + '"'
142143}
143144
144- function addPatternProperties ( pp , ap ) {
145+ function addPatternProperties ( schema , externalSchema ) {
146+ var pp = schema . patternProperties
145147 let code = `
146148 var keys = Object.keys(obj)
147149 for (var i = 0; i < keys.length; i++) {
148150 if (properties[keys[i]]) continue
149151 `
150152 Object . keys ( pp ) . forEach ( ( regex , index ) => {
153+ if ( pp [ regex ] [ '$ref' ] ) {
154+ pp [ regex ] = refFinder ( pp [ regex ] [ '$ref' ] , schema , externalSchema )
155+ }
151156 var type = pp [ regex ] . type
152157 code += `
153158 if (/${ regex } /.test(keys[i])) {
154159 `
155160 if ( type === 'object' ) {
156- code += buildObject ( pp [ regex ] , '' , 'buildObjectPP' + index )
161+ code += buildObject ( pp [ regex ] , '' , 'buildObjectPP' + index , externalSchema )
157162 code += `
158163 json += $asString(keys[i]) + ':' + buildObjectPP${ index } (obj[keys[i]]) + ','
159164 `
160165 } else if ( type === 'array' ) {
161- code += buildArray ( pp [ regex ] , '' , 'buildArrayPP' + index )
166+ code += buildArray ( pp [ regex ] , '' , 'buildArrayPP' + index , externalSchema )
162167 code += `
163168 json += $asString(keys[i]) + ':' + buildArrayPP${ index } (obj[keys[i]]) + ','
164169 `
@@ -189,8 +194,8 @@ function addPatternProperties (pp, ap) {
189194 }
190195 `
191196 } )
192- if ( ap ) {
193- code += additionalProperty ( ap )
197+ if ( schema . additionalProperties ) {
198+ code += additionalProperty ( schema , externalSchema )
194199 }
195200
196201 code += `
@@ -199,21 +204,26 @@ function addPatternProperties (pp, ap) {
199204 return code
200205}
201206
202- function additionalProperty ( ap ) {
207+ function additionalProperty ( schema , externalSchema ) {
208+ var ap = schema . additionalProperties
203209 let code = ''
204210 if ( ap === true ) {
205211 return `
206212 json += $asString(keys[i]) + ':' + fastSafeStringify(obj[keys[i]]) + ','
207213 `
208214 }
215+ if ( ap [ '$ref' ] ) {
216+ ap = refFinder ( ap [ '$ref' ] , schema , externalSchema )
217+ }
218+
209219 let type = ap . type
210220 if ( type === 'object' ) {
211- code += buildObject ( ap , '' , 'buildObjectAP' )
221+ code += buildObject ( ap , '' , 'buildObjectAP' , externalSchema )
212222 code += `
213223 json += $asString(keys[i]) + ':' + buildObjectAP(obj[keys[i]]) + ','
214224 `
215225 } else if ( type === 'array' ) {
216- code += buildArray ( ap , '' , 'buildArrayAP' )
226+ code += buildArray ( ap , '' , 'buildArrayAP' , externalSchema )
217227 code += `
218228 json += $asString(keys[i]) + ':' + buildArrayAP(obj[keys[i]]) + ','
219229 `
@@ -241,26 +251,41 @@ function additionalProperty (ap) {
241251 return code
242252}
243253
244- function addAdditionalProperties ( ap ) {
254+ function addAdditionalProperties ( schema , externalSchema ) {
245255 return `
246256 var keys = Object.keys(obj)
247257 for (var i = 0; i < keys.length; i++) {
248258 if (properties[keys[i]]) continue
249- ${ additionalProperty ( ap ) }
259+ ${ additionalProperty ( schema , externalSchema ) }
250260 }
251261 `
252262}
253263
254- function buildObject ( schema , code , name ) {
264+ function refFinder ( ref , schema , externalSchema ) {
265+ // Split file from walk
266+ ref = ref . split ( '#' )
267+ // If external file
268+ if ( ref [ 0 ] ) {
269+ schema = externalSchema [ ref [ 0 ] ]
270+ }
271+ const walk = ref [ 1 ] . split ( '/' )
272+ let code = 'return schema'
273+ for ( let i = 1 ; i < walk . length ; i ++ ) {
274+ code += `['${ walk [ i ] } ']`
275+ }
276+ return ( new Function ( 'schema' , code ) ) ( schema )
277+ }
278+
279+ function buildObject ( schema , code , name , externalSchema ) {
255280 code += `
256281 function ${ name } (obj) {
257282 var json = '{'
258283 `
259284
260285 if ( schema . patternProperties ) {
261- code += addPatternProperties ( schema . patternProperties , schema . additionalProperties )
286+ code += addPatternProperties ( schema , externalSchema )
262287 } else if ( schema . additionalProperties && ! schema . patternProperties ) {
263- code += addAdditionalProperties ( schema . additionalProperties )
288+ code += addAdditionalProperties ( schema , externalSchema )
264289 }
265290
266291 var laterCode = ''
@@ -273,7 +298,11 @@ function buildObject (schema, code, name) {
273298 json += '${ $asString ( key ) } :'
274299 `
275300
276- const result = nested ( laterCode , name , '.' + key , schema . properties [ key ] )
301+ if ( schema . properties [ key ] [ '$ref' ] ) {
302+ schema . properties [ key ] = refFinder ( schema . properties [ key ] [ '$ref' ] , schema , externalSchema )
303+ }
304+
305+ const result = nested ( laterCode , name , '.' + key , schema . properties [ key ] , externalSchema )
277306
278307 code += result . code
279308 laterCode = result . laterCode
@@ -308,15 +337,15 @@ function buildObject (schema, code, name) {
308337 return code
309338}
310339
311- function buildArray ( schema , code , name ) {
340+ function buildArray ( schema , code , name , externalSchema ) {
312341 code += `
313342 function ${ name } (obj) {
314343 var json = '['
315344 `
316345
317346 var laterCode = ''
318347
319- const result = nested ( laterCode , name , '[i]' , schema . items )
348+ const result = nested ( laterCode , name , '[i]' , schema . items , externalSchema )
320349
321350 code += `
322351 const l = obj.length
@@ -342,7 +371,7 @@ function buildArray (schema, code, name) {
342371 return code
343372}
344373
345- function nested ( laterCode , name , key , schema ) {
374+ function nested ( laterCode , name , key , schema , externalSchema ) {
346375 var code = ''
347376 var funcName
348377 const type = schema . type
@@ -370,14 +399,14 @@ function nested (laterCode, name, key, schema) {
370399 break
371400 case 'object' :
372401 funcName = ( name + key ) . replace ( / [ - . \[ \] ] / g, '' )
373- laterCode = buildObject ( schema , laterCode , funcName )
402+ laterCode = buildObject ( schema , laterCode , funcName , externalSchema )
374403 code += `
375404 json += ${ funcName } (obj${ key } )
376405 `
377406 break
378407 case 'array' :
379408 funcName = ( name + key ) . replace ( / [ - . \[ \] ] / g, '' )
380- laterCode = buildArray ( schema , laterCode , funcName )
409+ laterCode = buildArray ( schema , laterCode , funcName , externalSchema )
381410 code += `
382411 json += ${ funcName } (obj${ key } )
383412 `
0 commit comments