Skip to content

Commit 4ce46fb

Browse files
author
Jean-Baptiste RICHARDET
committed
Adds anyOf support
1 parent e8696fd commit 4ce46fb

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

index.js

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
var fastSafeStringify = require('fast-safe-stringify')
4+
var Ajv = require('ajv')
45

56
var uglify = null
67
var isLong
@@ -87,8 +88,18 @@ function build (schema, options) {
8788
code = uglifyCode(code)
8889
}
8990

91+
var dependencies = []
92+
var dependenciesName = []
9093
if (hasAdditionalPropertiesTrue(schema)) {
91-
return (new Function('fastSafeStringify', code))(fastSafeStringify)
94+
dependencies.push(fastSafeStringify)
95+
dependenciesName.push('fastSafeStringify')
96+
}
97+
if (hasAnyOf(schema)) {
98+
dependencies.push(new Ajv())
99+
dependenciesName.push('ajv')
100+
}
101+
if (dependencies.length > 0) {
102+
return (new Function(...dependenciesName, code))(...dependencies)
92103
}
93104
return (new Function(code))()
94105
}
@@ -107,6 +118,20 @@ function hasAdditionalPropertiesTrue (schema) {
107118
return false
108119
}
109120

121+
function hasAnyOf (schema) {
122+
if ('anyOf' in schema) { return true }
123+
124+
var objectKeys = Object.keys(schema)
125+
for (var i = 0; i < objectKeys.length; i++) {
126+
var value = schema[objectKeys[i]]
127+
if (typeof value === 'object') {
128+
if (hasAnyOf(value)) { return true }
129+
}
130+
}
131+
132+
return false
133+
}
134+
110135
function $asNull () {
111136
return 'null'
112137
}
@@ -517,8 +542,22 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
517542
funcName = (name + key + subKey).replace(/[-.\[\]]/g, '') // eslint-disable-line
518543
laterCode = buildArray(schema, laterCode, funcName, externalSchema, fullSchema)
519544
code += `
520-
json += ${funcName}(obj${accessor})
521-
`
545+
json += ${funcName}(obj${accessor})
546+
`
547+
break
548+
549+
case undefined:
550+
if ('anyOf' in schema) {
551+
schema.anyOf.forEach((s, index) => {
552+
code += `
553+
${index === 0 ? 'if' : 'else if'}(ajv.validate(${require('util').inspect(s, {depth: null})}, obj${accessor}))
554+
${nested(laterCode, name, key, s, externalSchema, fullSchema, subKey).code}
555+
`
556+
})
557+
code += `
558+
else json+= null
559+
`
560+
} else throw new Error(`${schema} unsupported`)
522561
break
523562
default:
524563
throw new Error(`${type} unsupported`)

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"uglify-es": "^3.1.1"
3434
},
3535
"dependencies": {
36+
"ajv": "^5.2.3",
3637
"fast-safe-stringify": "^1.2.0"
3738
}
3839
}

test/anyof.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict'
2+
3+
const test = require('tap').test
4+
const build = require('..')
5+
6+
test('object with multiple types field', (t) => {
7+
t.plan(2)
8+
9+
const schema = {
10+
title: 'object with multiple types field',
11+
type: 'object',
12+
properties: {
13+
str: {
14+
'anyOf': [{
15+
type: 'string'
16+
}, {
17+
type: 'boolean'
18+
}]
19+
}
20+
}
21+
}
22+
const stringify = build(schema)
23+
24+
try {
25+
const value = stringify({
26+
str: 'string'
27+
})
28+
t.is(value, '{"str":"string"}')
29+
} catch (e) {
30+
t.fail()
31+
}
32+
33+
try {
34+
const value = stringify({
35+
str: true
36+
})
37+
t.is(value, '{"str":true}')
38+
} catch (e) {
39+
t.fail()
40+
}
41+
})

0 commit comments

Comments
 (0)