Skip to content

Commit 6eec05d

Browse files
authored
Merge pull request #19 from fastify/array-ref
Array ref
2 parents dc3ef4f + beb1ddc commit 6eec05d

File tree

2 files changed

+119
-23
lines changed

2 files changed

+119
-23
lines changed

index.js

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function build (schema, options) {
2525
switch (schema.type) {
2626
case 'object':
2727
main = '$main'
28-
code = buildObject(schema, code, main, options.schema)
28+
code = buildObject(schema, code, main, options.schema, schema)
2929
break
3030
case 'string':
3131
main = $asString.name
@@ -42,7 +42,7 @@ function build (schema, options) {
4242
break
4343
case 'array':
4444
main = '$main'
45-
code = buildArray(schema, code, main, options.schema)
45+
code = buildArray(schema, code, main, options.schema, schema)
4646
break
4747
default:
4848
throw new Error(`${schema.type} unsupported`)
@@ -72,7 +72,7 @@ function $asNumber (i) {
7272
}
7373

7474
function $asBoolean (bool) {
75-
return bool && 'true' || 'false'
75+
return bool && 'true' || 'false' // eslint-disable-line
7676
}
7777

7878
function $asString (str) {
@@ -116,7 +116,7 @@ function $asStringSmall (str) {
116116
return point < 32 ? JSON.stringify(str) : '"' + result + '"'
117117
}
118118

119-
function addPatternProperties (schema, externalSchema) {
119+
function addPatternProperties (schema, externalSchema, fullSchema) {
120120
var pp = schema.patternProperties
121121
let code = `
122122
var keys = Object.keys(obj)
@@ -125,19 +125,19 @@ function addPatternProperties (schema, externalSchema) {
125125
`
126126
Object.keys(pp).forEach((regex, index) => {
127127
if (pp[regex]['$ref']) {
128-
pp[regex] = refFinder(pp[regex]['$ref'], schema, externalSchema)
128+
pp[regex] = refFinder(pp[regex]['$ref'], fullSchema, externalSchema, fullSchema)
129129
}
130130
var type = pp[regex].type
131131
code += `
132132
if (/${regex}/.test(keys[i])) {
133133
`
134134
if (type === 'object') {
135-
code += buildObject(pp[regex], '', 'buildObjectPP' + index, externalSchema)
135+
code += buildObject(pp[regex], '', 'buildObjectPP' + index, externalSchema, fullSchema)
136136
code += `
137137
json += $asString(keys[i]) + ':' + buildObjectPP${index}(obj[keys[i]]) + ','
138138
`
139139
} else if (type === 'array') {
140-
code += buildArray(pp[regex], '', 'buildArrayPP' + index, externalSchema)
140+
code += buildArray(pp[regex], '', 'buildArrayPP' + index, externalSchema, fullSchema)
141141
code += `
142142
json += $asString(keys[i]) + ':' + buildArrayPP${index}(obj[keys[i]]) + ','
143143
`
@@ -169,7 +169,7 @@ function addPatternProperties (schema, externalSchema) {
169169
`
170170
})
171171
if (schema.additionalProperties) {
172-
code += additionalProperty(schema, externalSchema)
172+
code += additionalProperty(schema, externalSchema, fullSchema)
173173
}
174174

175175
code += `
@@ -178,7 +178,7 @@ function addPatternProperties (schema, externalSchema) {
178178
return code
179179
}
180180

181-
function additionalProperty (schema, externalSchema) {
181+
function additionalProperty (schema, externalSchema, fullSchema) {
182182
var ap = schema.additionalProperties
183183
let code = ''
184184
if (ap === true) {
@@ -187,7 +187,7 @@ function additionalProperty (schema, externalSchema) {
187187
`
188188
}
189189
if (ap['$ref']) {
190-
ap = refFinder(ap['$ref'], schema, externalSchema)
190+
ap = refFinder(ap['$ref'], fullSchema, externalSchema)
191191
}
192192

193193
let type = ap.type
@@ -197,7 +197,7 @@ function additionalProperty (schema, externalSchema) {
197197
json += $asString(keys[i]) + ':' + buildObjectAP(obj[keys[i]]) + ','
198198
`
199199
} else if (type === 'array') {
200-
code += buildArray(ap, '', 'buildArrayAP', externalSchema)
200+
code += buildArray(ap, '', 'buildArrayAP', externalSchema, fullSchema)
201201
code += `
202202
json += $asString(keys[i]) + ':' + buildArrayAP(obj[keys[i]]) + ','
203203
`
@@ -225,12 +225,12 @@ function additionalProperty (schema, externalSchema) {
225225
return code
226226
}
227227

228-
function addAdditionalProperties (schema, externalSchema) {
228+
function addAdditionalProperties (schema, externalSchema, fullSchema) {
229229
return `
230230
var keys = Object.keys(obj)
231231
for (var i = 0; i < keys.length; i++) {
232232
if (properties[keys[i]]) continue
233-
${additionalProperty(schema, externalSchema)}
233+
${additionalProperty(schema, externalSchema, fullSchema)}
234234
}
235235
`
236236
}
@@ -250,16 +250,16 @@ function refFinder (ref, schema, externalSchema) {
250250
return (new Function('schema', code))(schema)
251251
}
252252

253-
function buildObject (schema, code, name, externalSchema) {
253+
function buildObject (schema, code, name, externalSchema, fullSchema) {
254254
code += `
255255
function ${name} (obj) {
256256
var json = '{'
257257
`
258258

259259
if (schema.patternProperties) {
260-
code += addPatternProperties(schema, externalSchema)
260+
code += addPatternProperties(schema, externalSchema, fullSchema)
261261
} else if (schema.additionalProperties && !schema.patternProperties) {
262-
code += addAdditionalProperties(schema, externalSchema)
262+
code += addAdditionalProperties(schema, externalSchema, fullSchema)
263263
}
264264

265265
var laterCode = ''
@@ -273,10 +273,10 @@ function buildObject (schema, code, name, externalSchema) {
273273
`
274274

275275
if (schema.properties[key]['$ref']) {
276-
schema.properties[key] = refFinder(schema.properties[key]['$ref'], schema, externalSchema)
276+
schema.properties[key] = refFinder(schema.properties[key]['$ref'], fullSchema, externalSchema)
277277
}
278278

279-
const result = nested(laterCode, name, '.' + key, schema.properties[key], externalSchema)
279+
const result = nested(laterCode, name, '.' + key, schema.properties[key], externalSchema, fullSchema)
280280

281281
code += result.code
282282
laterCode = result.laterCode
@@ -312,15 +312,19 @@ function buildObject (schema, code, name, externalSchema) {
312312
return code
313313
}
314314

315-
function buildArray (schema, code, name, externalSchema) {
315+
function buildArray (schema, code, name, externalSchema, fullSchema) {
316316
code += `
317317
function ${name} (obj) {
318318
var json = '['
319319
`
320320

321321
var laterCode = ''
322322

323-
const result = nested(laterCode, name, '[i]', schema.items, externalSchema)
323+
if (schema.items['$ref']) {
324+
schema.items = refFinder(schema.items['$ref'], fullSchema, externalSchema)
325+
}
326+
327+
const result = nested(laterCode, name, '[i]', schema.items, externalSchema, fullSchema)
324328

325329
code += `
326330
const l = obj.length
@@ -346,7 +350,7 @@ function buildArray (schema, code, name, externalSchema) {
346350
return code
347351
}
348352

349-
function nested (laterCode, name, key, schema, externalSchema) {
353+
function nested (laterCode, name, key, schema, externalSchema, fullSchema) {
350354
var code = ''
351355
var funcName
352356
const type = schema.type
@@ -374,14 +378,14 @@ function nested (laterCode, name, key, schema, externalSchema) {
374378
break
375379
case 'object':
376380
funcName = (name + key).replace(/[-.\[\]]/g, '') // eslint-disable-line
377-
laterCode = buildObject(schema, laterCode, funcName, externalSchema)
381+
laterCode = buildObject(schema, laterCode, funcName, externalSchema, fullSchema)
378382
code += `
379383
json += ${funcName}(obj${key})
380384
`
381385
break
382386
case 'array':
383387
funcName = (name + key).replace(/[-.\[\]]/g, '') // eslint-disable-line
384-
laterCode = buildArray(schema, laterCode, funcName, externalSchema)
388+
laterCode = buildArray(schema, laterCode, funcName, externalSchema, fullSchema)
385389
code += `
386390
json += ${funcName}(obj${key})
387391
`

test/ref.test.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,42 @@ test('ref internal - properties', (t) => {
4545
t.equal('{"obj":{"str":"test"}}', output)
4646
})
4747

48+
test('ref internal - items', (t) => {
49+
t.plan(2)
50+
51+
const schema = {
52+
title: 'array with $ref',
53+
definitions: {
54+
def: {
55+
type: 'object',
56+
properties: {
57+
str: {
58+
type: 'string'
59+
}
60+
}
61+
}
62+
},
63+
type: 'array',
64+
items: { $ref: '#/definitions/def' }
65+
}
66+
67+
const array = [{
68+
str: 'test'
69+
}]
70+
71+
const stringify = build(schema)
72+
const output = stringify(array)
73+
74+
try {
75+
JSON.parse(output)
76+
t.pass()
77+
} catch (e) {
78+
t.fail()
79+
}
80+
81+
t.equal('[{"str":"test"}]', output)
82+
})
83+
4884
test('ref external - properties', (t) => {
4985
t.plan(2)
5086

@@ -286,3 +322,59 @@ test('ref external - pattern-additional Properties', (t) => {
286322

287323
t.equal('{"reg":{"str":"test"},"obj":{"int":42}}', output)
288324
})
325+
326+
test('ref internal - deepObject schema', (t) => {
327+
t.plan(2)
328+
329+
const schema = {
330+
title: 'object with $ref',
331+
definitions: {
332+
def: {
333+
type: 'object',
334+
properties: {
335+
coming: {
336+
type: 'object',
337+
properties: {
338+
where: {
339+
type: 'string'
340+
}
341+
}
342+
}
343+
}
344+
}
345+
},
346+
type: 'object',
347+
properties: {
348+
winter: {
349+
type: 'object',
350+
properties: {
351+
is: {
352+
$ref: '#/definitions/def'
353+
}
354+
}
355+
}
356+
}
357+
}
358+
359+
const object = {
360+
winter: {
361+
is: {
362+
coming: {
363+
where: 'to town'
364+
}
365+
}
366+
}
367+
}
368+
369+
const stringify = build(schema)
370+
const output = stringify(object)
371+
372+
try {
373+
JSON.parse(output)
374+
t.pass()
375+
} catch (e) {
376+
t.fail()
377+
}
378+
379+
t.equal('{"winter":{"is":{"coming":{"where":"to town"}}}}', output)
380+
})

0 commit comments

Comments
 (0)