Skip to content

Commit 85f1e0e

Browse files
authored
Merge pull request #50 from JbIPS/master
Adds anyOf support
2 parents e8696fd + dd56c80 commit 85f1e0e

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

index.js

Lines changed: 42 additions & 4 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,10 +88,19 @@ 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')
9296
}
93-
return (new Function(code))()
97+
if (hasAnyOf(schema)) {
98+
dependencies.push(new Ajv())
99+
dependenciesName.push('ajv')
100+
}
101+
102+
dependenciesName.push(code)
103+
return (Function.apply(null, dependenciesName).apply(null, dependencies))
94104
}
95105

96106
function hasAdditionalPropertiesTrue (schema) {
@@ -107,6 +117,20 @@ function hasAdditionalPropertiesTrue (schema) {
107117
return false
108118
}
109119

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

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"description": "Stringify your JSON at max speed",
55
"main": "index.js",
66
"scripts": {
7+
"benchmark": "node bench.js",
78
"test": "standard && tap test/*.test.js"
89
},
910
"precommit": "test",
@@ -33,6 +34,7 @@
3334
"uglify-es": "^3.1.1"
3435
},
3536
"dependencies": {
37+
"ajv": "^5.2.3",
3638
"fast-safe-stringify": "^1.2.0"
3739
}
3840
}

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)