Skip to content

Commit 0e16052

Browse files
authored
Support inline $id references (#411)
* support inline references * lint
1 parent 9947893 commit 0e16052

File tree

3 files changed

+91
-3
lines changed

3 files changed

+91
-3
lines changed

index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { Options as AjvOptions } from "ajv"
22
declare namespace build {
33
interface BaseSchema {
4+
/**
5+
* Schema id
6+
*/
7+
$id?: string
48
/**
59
* Schema title
610
*/

index.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ function mergeLocation (source, dest) {
5252

5353
const arrayItemsReferenceSerializersMap = new Map()
5454
const objectReferenceSerializersMap = new Map()
55+
const schemaReferenceMap = new Map()
56+
5557
let ajvInstance = null
5658

5759
function build (schema, options) {
5860
arrayItemsReferenceSerializersMap.clear()
5961
objectReferenceSerializersMap.clear()
62+
schemaReferenceMap.clear()
6063

6164
options = options || {}
6265

@@ -174,6 +177,7 @@ function build (schema, options) {
174177

175178
arrayItemsReferenceSerializersMap.clear()
176179
objectReferenceSerializersMap.clear()
180+
schemaReferenceMap.clear()
177181

178182
return (Function.apply(null, dependenciesName).apply(null, dependencies))
179183
}
@@ -612,8 +616,18 @@ function refFinder (ref, location) {
612616
// Split file from walk
613617
ref = ref.split('#')
614618

615-
// If external file
616-
if (ref[0]) {
619+
// Check schemaReferenceMap for $id entry
620+
if (ref[0] && schemaReferenceMap.has(ref[0])) {
621+
schema = schemaReferenceMap.get(ref[0])
622+
root = schemaReferenceMap.get(ref[0])
623+
if (schema.$ref) {
624+
return refFinder(schema.$ref, {
625+
schema: schema,
626+
root: root,
627+
externalSchema: externalSchema
628+
})
629+
}
630+
} else if (ref[0]) { // If external file
617631
schema = externalSchema[ref[0]]
618632
root = externalSchema[ref[0]]
619633

@@ -921,7 +935,9 @@ function toJSON (variableName) {
921935

922936
function buildObject (location, code, name) {
923937
const schema = location.schema
924-
938+
if (schema.$id !== undefined) {
939+
schemaReferenceMap.set(schema.$id, schema)
940+
}
925941
code += `
926942
function ${name} (input) {
927943
`
@@ -971,6 +987,9 @@ function buildObject (location, code, name) {
971987

972988
function buildArray (location, code, name, key = null) {
973989
let schema = location.schema
990+
if (schema.$id !== undefined) {
991+
schemaReferenceMap.set(schema.$id, schema)
992+
}
974993
code += `
975994
function ${name} (obj) {
976995
`

test/recursion.test.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,68 @@ test('can stringify recursive references in object types (issue #365)', t => {
178178
const value = stringify(data)
179179
t.equal(value, '{"category":{"parent":{"parent":{"parent":{"parent":{}}}}}}')
180180
})
181+
182+
test('can stringify recursive inline $id references (issue #410)', t => {
183+
t.plan(1)
184+
const schema = {
185+
$id: 'Node',
186+
type: 'object',
187+
properties: {
188+
id: {
189+
type: 'string'
190+
},
191+
nodes: {
192+
type: 'array',
193+
items: {
194+
$ref: 'Node'
195+
}
196+
}
197+
},
198+
required: [
199+
'id',
200+
'nodes'
201+
]
202+
}
203+
204+
const stringify = build(schema)
205+
const data = {
206+
id: '0',
207+
nodes: [
208+
{
209+
id: '1',
210+
nodes: [{
211+
id: '2',
212+
nodes: [
213+
{ id: '3', nodes: [] },
214+
{ id: '4', nodes: [] },
215+
{ id: '5', nodes: [] }
216+
]
217+
}]
218+
},
219+
{
220+
id: '6',
221+
nodes: [{
222+
id: '7',
223+
nodes: [
224+
{ id: '8', nodes: [] },
225+
{ id: '9', nodes: [] },
226+
{ id: '10', nodes: [] }
227+
]
228+
}]
229+
},
230+
{
231+
id: '11',
232+
nodes: [{
233+
id: '12',
234+
nodes: [
235+
{ id: '13', nodes: [] },
236+
{ id: '14', nodes: [] },
237+
{ id: '15', nodes: [] }
238+
]
239+
}]
240+
}
241+
]
242+
}
243+
const value = stringify(data)
244+
t.equal(value, '{"id":"0","nodes":[{"id":"1","nodes":[{"id":"2","nodes":[{"id":"3","nodes":[]},{"id":"4","nodes":[]},{"id":"5","nodes":[]}]}]},{"id":"6","nodes":[{"id":"7","nodes":[{"id":"8","nodes":[]},{"id":"9","nodes":[]},{"id":"10","nodes":[]}]}]},{"id":"11","nodes":[{"id":"12","nodes":[{"id":"13","nodes":[]},{"id":"14","nodes":[]},{"id":"15","nodes":[]}]}]}]}')
245+
})

0 commit comments

Comments
 (0)