Skip to content

Commit 4b81cd6

Browse files
authored
fix: support anyOf inside allOf (#630)
* fix: support anyOf inside allOf * CR * fix nested objects * fix nested objects
1 parent 93b3491 commit 4b81cd6

File tree

2 files changed

+92
-3
lines changed

2 files changed

+92
-3
lines changed

index.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ function build (schema, options) {
7676
functionsCounter: 0,
7777
functionsNamesBySchema: new Map(),
7878
options,
79+
wrapObjects: true,
7980
refResolver: new RefResolver(),
8081
rootSchemaId: schema.$id || randomUUID(),
8182
validatorSchemasIds: new Set()
@@ -510,13 +511,16 @@ function buildObject (context, location) {
510511

511512
functionCode += `
512513
const obj = ${toJSON('input')}
513-
let json = '{'
514+
let json = '${context.wrapObjects ? '{' : ''}'
514515
let addComma = false
515516
`
516517

518+
const wrapObjects = context.wrapObjects
519+
context.wrapObjects = true
517520
functionCode += buildInnerObject(context, location)
521+
context.wrapObjects = wrapObjects
518522
functionCode += `
519-
return json + '}'
523+
return json${context.wrapObjects ? ' + \'}\'' : ''}
520524
}
521525
`
522526

@@ -832,9 +836,19 @@ function buildValue (context, location, input) {
832836

833837
let code = ''
834838

835-
if (type === undefined && (schema.anyOf || schema.oneOf)) {
839+
if ((type === undefined || type === 'object') && (schema.anyOf || schema.oneOf)) {
836840
context.validatorSchemasIds.add(location.getSchemaId())
837841

842+
if (schema.type === 'object') {
843+
context.wrapObjects = false
844+
const funcName = buildObject(context, location)
845+
code += `
846+
json += '{'
847+
json += ${funcName}(${input})
848+
json += ','
849+
`
850+
}
851+
838852
const type = schema.anyOf ? 'anyOf' : 'oneOf'
839853
const anyOfLocation = location.getPropertyLocation(type)
840854

@@ -856,6 +870,12 @@ function buildValue (context, location, input) {
856870
code += `
857871
else throw new TypeError(\`The value of '${schemaRef}' does not match schema definition.\`)
858872
`
873+
if (schema.type === 'object') {
874+
code += `
875+
json += '}'
876+
`
877+
context.wrapObjects = true
878+
}
859879
return code
860880
}
861881

test/allof.test.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,75 @@ test('object with nested allOfs', (t) => {
220220
t.equal(value, '{"id1":1,"id2":2,"id3":3}')
221221
})
222222

223+
test('object with anyOf nested inside allOf', (t) => {
224+
t.plan(1)
225+
226+
const schema = {
227+
title: 'object with anyOf nested inside allOf',
228+
type: 'object',
229+
allOf: [
230+
{
231+
required: ['id1', 'obj'],
232+
type: 'object',
233+
properties: {
234+
id1: {
235+
type: 'integer'
236+
},
237+
obj: {
238+
type: 'object',
239+
properties: {
240+
nested: { type: 'string' }
241+
}
242+
}
243+
}
244+
},
245+
{
246+
anyOf: [
247+
{
248+
type: 'object',
249+
properties: {
250+
id2: { type: 'string' }
251+
},
252+
required: ['id2']
253+
},
254+
{
255+
type: 'object',
256+
properties: {
257+
id3: {
258+
type: 'integer'
259+
},
260+
nestedObj: {
261+
type: 'object',
262+
properties: {
263+
nested: { type: 'string' }
264+
}
265+
}
266+
},
267+
required: ['id3']
268+
},
269+
{
270+
type: 'object',
271+
properties: {
272+
id4: { type: 'integer' }
273+
},
274+
required: ['id4']
275+
}
276+
]
277+
}
278+
]
279+
}
280+
281+
const stringify = build(schema)
282+
const value = stringify({
283+
id1: 1,
284+
id3: 3,
285+
id4: 4, // extra prop shouldn't be in result
286+
obj: { nested: 'yes' },
287+
nestedObj: { nested: 'yes' }
288+
})
289+
t.equal(value, '{"id1":1,"obj":{"nested":"yes"},"id3":3,"nestedObj":{"nested":"yes"}}')
290+
})
291+
223292
test('object with $ref in allOf', (t) => {
224293
t.plan(1)
225294

0 commit comments

Comments
 (0)