2
2
3
3
const fastSafeStringify = require ( 'fast-safe-stringify' )
4
4
5
- function build ( schema ) {
5
+ function build ( schema , options ) {
6
+ options = options || { }
6
7
/* eslint no-new-func: "off" */
7
8
var code = `
8
9
'use strict'
@@ -26,7 +27,7 @@ function build (schema) {
26
27
switch ( schema . type ) {
27
28
case 'object' :
28
29
main = '$main'
29
- code = buildObject ( schema , code , main )
30
+ code = buildObject ( schema , code , main , options . schema )
30
31
break
31
32
case 'string' :
32
33
main = $asString . name
@@ -43,7 +44,7 @@ function build (schema) {
43
44
break
44
45
case 'array' :
45
46
main = '$main'
46
- code = buildArray ( schema , code , main )
47
+ code = buildArray ( schema , code , main , options . schema )
47
48
break
48
49
default :
49
50
throw new Error ( `${ schema . type } unsupported` )
@@ -141,24 +142,28 @@ function $asRegExp (reg) {
141
142
return '"' + reg + '"'
142
143
}
143
144
144
- function addPatternProperties ( pp , ap ) {
145
+ function addPatternProperties ( schema , externalSchema ) {
146
+ var pp = schema . patternProperties
145
147
let code = `
146
148
var keys = Object.keys(obj)
147
149
for (var i = 0; i < keys.length; i++) {
148
150
if (properties[keys[i]]) continue
149
151
`
150
152
Object . keys ( pp ) . forEach ( ( regex , index ) => {
153
+ if ( pp [ regex ] [ '$ref' ] ) {
154
+ pp [ regex ] = refFinder ( pp [ regex ] [ '$ref' ] , schema , externalSchema )
155
+ }
151
156
var type = pp [ regex ] . type
152
157
code += `
153
158
if (/${ regex } /.test(keys[i])) {
154
159
`
155
160
if ( type === 'object' ) {
156
- code += buildObject ( pp [ regex ] , '' , 'buildObjectPP' + index )
161
+ code += buildObject ( pp [ regex ] , '' , 'buildObjectPP' + index , externalSchema )
157
162
code += `
158
163
json += $asString(keys[i]) + ':' + buildObjectPP${ index } (obj[keys[i]]) + ','
159
164
`
160
165
} else if ( type === 'array' ) {
161
- code += buildArray ( pp [ regex ] , '' , 'buildArrayPP' + index )
166
+ code += buildArray ( pp [ regex ] , '' , 'buildArrayPP' + index , externalSchema )
162
167
code += `
163
168
json += $asString(keys[i]) + ':' + buildArrayPP${ index } (obj[keys[i]]) + ','
164
169
`
@@ -189,8 +194,8 @@ function addPatternProperties (pp, ap) {
189
194
}
190
195
`
191
196
} )
192
- if ( ap ) {
193
- code += additionalProperty ( ap )
197
+ if ( schema . additionalProperties ) {
198
+ code += additionalProperty ( schema , externalSchema )
194
199
}
195
200
196
201
code += `
@@ -199,21 +204,26 @@ function addPatternProperties (pp, ap) {
199
204
return code
200
205
}
201
206
202
- function additionalProperty ( ap ) {
207
+ function additionalProperty ( schema , externalSchema ) {
208
+ var ap = schema . additionalProperties
203
209
let code = ''
204
210
if ( ap === true ) {
205
211
return `
206
212
json += $asString(keys[i]) + ':' + fastSafeStringify(obj[keys[i]]) + ','
207
213
`
208
214
}
215
+ if ( ap [ '$ref' ] ) {
216
+ ap = refFinder ( ap [ '$ref' ] , schema , externalSchema )
217
+ }
218
+
209
219
let type = ap . type
210
220
if ( type === 'object' ) {
211
- code += buildObject ( ap , '' , 'buildObjectAP' )
221
+ code += buildObject ( ap , '' , 'buildObjectAP' , externalSchema )
212
222
code += `
213
223
json += $asString(keys[i]) + ':' + buildObjectAP(obj[keys[i]]) + ','
214
224
`
215
225
} else if ( type === 'array' ) {
216
- code += buildArray ( ap , '' , 'buildArrayAP' )
226
+ code += buildArray ( ap , '' , 'buildArrayAP' , externalSchema )
217
227
code += `
218
228
json += $asString(keys[i]) + ':' + buildArrayAP(obj[keys[i]]) + ','
219
229
`
@@ -241,26 +251,41 @@ function additionalProperty (ap) {
241
251
return code
242
252
}
243
253
244
- function addAdditionalProperties ( ap ) {
254
+ function addAdditionalProperties ( schema , externalSchema ) {
245
255
return `
246
256
var keys = Object.keys(obj)
247
257
for (var i = 0; i < keys.length; i++) {
248
258
if (properties[keys[i]]) continue
249
- ${ additionalProperty ( ap ) }
259
+ ${ additionalProperty ( schema , externalSchema ) }
250
260
}
251
261
`
252
262
}
253
263
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 ) {
255
280
code += `
256
281
function ${ name } (obj) {
257
282
var json = '{'
258
283
`
259
284
260
285
if ( schema . patternProperties ) {
261
- code += addPatternProperties ( schema . patternProperties , schema . additionalProperties )
286
+ code += addPatternProperties ( schema , externalSchema )
262
287
} else if ( schema . additionalProperties && ! schema . patternProperties ) {
263
- code += addAdditionalProperties ( schema . additionalProperties )
288
+ code += addAdditionalProperties ( schema , externalSchema )
264
289
}
265
290
266
291
var laterCode = ''
@@ -273,7 +298,11 @@ function buildObject (schema, code, name) {
273
298
json += '${ $asString ( key ) } :'
274
299
`
275
300
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 )
277
306
278
307
code += result . code
279
308
laterCode = result . laterCode
@@ -308,15 +337,15 @@ function buildObject (schema, code, name) {
308
337
return code
309
338
}
310
339
311
- function buildArray ( schema , code , name ) {
340
+ function buildArray ( schema , code , name , externalSchema ) {
312
341
code += `
313
342
function ${ name } (obj) {
314
343
var json = '['
315
344
`
316
345
317
346
var laterCode = ''
318
347
319
- const result = nested ( laterCode , name , '[i]' , schema . items )
348
+ const result = nested ( laterCode , name , '[i]' , schema . items , externalSchema )
320
349
321
350
code += `
322
351
const l = obj.length
@@ -342,7 +371,7 @@ function buildArray (schema, code, name) {
342
371
return code
343
372
}
344
373
345
- function nested ( laterCode , name , key , schema ) {
374
+ function nested ( laterCode , name , key , schema , externalSchema ) {
346
375
var code = ''
347
376
var funcName
348
377
const type = schema . type
@@ -370,14 +399,14 @@ function nested (laterCode, name, key, schema) {
370
399
break
371
400
case 'object' :
372
401
funcName = ( name + key ) . replace ( / [ - . \[ \] ] / g, '' )
373
- laterCode = buildObject ( schema , laterCode , funcName )
402
+ laterCode = buildObject ( schema , laterCode , funcName , externalSchema )
374
403
code += `
375
404
json += ${ funcName } (obj${ key } )
376
405
`
377
406
break
378
407
case 'array' :
379
408
funcName = ( name + key ) . replace ( / [ - . \[ \] ] / g, '' )
380
- laterCode = buildArray ( schema , laterCode , funcName )
409
+ laterCode = buildArray ( schema , laterCode , funcName , externalSchema )
381
410
code += `
382
411
json += ${ funcName } (obj${ key } )
383
412
`
0 commit comments