Skip to content

Commit e3df63a

Browse files
Eommmcollina
authored andcommitted
Fix/ref to (#137)
* add: quick and dirty solution for $ref with plan name fragment $id * add: test with multiple $ref formats * fix: search for ids in plain format when needed * fix: finder for JSON schema id as top level function
1 parent 321bc3f commit e3df63a

File tree

2 files changed

+120
-2
lines changed

2 files changed

+120
-2
lines changed

index.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,19 +424,42 @@ function addAdditionalProperties (schema, externalSchema, fullSchema) {
424424
`
425425
}
426426

427+
function idFinder (schema, searchedId) {
428+
let objSchema
429+
const explore = (schema, searchedId) => {
430+
Object.keys(schema || {}).forEach((key, i, a) => {
431+
if (key === '$id' && schema[key] === searchedId) {
432+
objSchema = schema
433+
} else if (objSchema === undefined && typeof schema[key] === 'object') {
434+
explore(schema[key], searchedId)
435+
}
436+
})
437+
}
438+
explore(schema, searchedId)
439+
return objSchema
440+
}
441+
427442
function refFinder (ref, schema, externalSchema) {
428443
// Split file from walk
429444
ref = ref.split('#')
445+
430446
// If external file
431447
if (ref[0]) {
432448
schema = externalSchema[ref[0]]
433449
}
450+
434451
var code = 'return schema'
435452
// If it has a path
436453
if (ref[1]) {
454+
// ref[1] could contain a JSON pointer - ex: /definitions/num
455+
// or plan name fragment id without suffix # - ex: customId
437456
var walk = ref[1].split('/')
438-
for (var i = 1; i < walk.length; i++) {
439-
code += `['${walk[i]}']`
457+
if (walk.length === 1) {
458+
return idFinder(schema, `#${ref[1]}`)
459+
} else {
460+
for (var i = 1; i < walk.length; i++) {
461+
code += `['${walk[i]}']`
462+
}
440463
}
441464
}
442465
return (new Function('schema', code))(schema)

test/ref.test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,98 @@ test('ref internal - deepObject schema', (t) => {
389389

390390
t.equal(output, '{"winter":{"is":{"coming":{"where":"to town"}}}}')
391391
})
392+
393+
test('ref internal - plain name fragment', (t) => {
394+
t.plan(2)
395+
396+
const schema = {
397+
title: 'object with $ref',
398+
definitions: {
399+
def: {
400+
$id: '#uri',
401+
type: 'object',
402+
properties: {
403+
str: {
404+
type: 'string'
405+
}
406+
},
407+
required: ['str']
408+
}
409+
},
410+
type: 'object',
411+
properties: {
412+
obj: {
413+
$ref: '#uri'
414+
}
415+
}
416+
}
417+
418+
const object = {
419+
obj: {
420+
str: 'test'
421+
}
422+
}
423+
424+
const stringify = build(schema)
425+
const output = stringify(object)
426+
427+
try {
428+
JSON.parse(output)
429+
t.pass()
430+
} catch (e) {
431+
t.fail()
432+
}
433+
434+
t.equal(output, '{"obj":{"str":"test"}}')
435+
})
436+
437+
test('ref internal - multiple $ref format', (t) => {
438+
t.plan(2)
439+
440+
const schema = {
441+
type: 'object',
442+
definitions: {
443+
one: {
444+
type: 'string',
445+
definitions: {
446+
two: {
447+
$id: '#twos',
448+
type: 'string'
449+
}
450+
}
451+
}
452+
},
453+
properties: {
454+
zero: {
455+
$id: '#three',
456+
type: 'string'
457+
},
458+
a: { $ref: '#/definitions/one' },
459+
b: { $ref: '#three' },
460+
c: { $ref: '#/properties/zero' },
461+
d: { $ref: '#twos' },
462+
e: { $ref: '#/definitions/one/definitions/two' }
463+
}
464+
}
465+
466+
const object = {
467+
zero: 'test',
468+
a: 'test',
469+
b: 'test',
470+
c: 'test',
471+
d: 'test',
472+
e: 'test'
473+
}
474+
475+
const stringify = build(schema)
476+
const output = stringify(object)
477+
478+
try {
479+
JSON.parse(output)
480+
t.pass()
481+
} catch (e) {
482+
t.fail()
483+
}
484+
485+
t.equal(output, '{"zero":"test","a":"test","b":"test","c":"test","d":"test","e":"test"}')
486+
})

0 commit comments

Comments
 (0)