Skip to content

Commit 1c6b4da

Browse files
authored
support for empty schemas (#283)
1 parent f8bcbe6 commit 1c6b4da

File tree

3 files changed

+106
-1
lines changed

3 files changed

+106
-1
lines changed

index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ declare namespace build {
5858
*/
5959
$ref: string;
6060
}
61+
62+
export interface AnySchema extends BaseSchema {
63+
}
6164

6265
export interface StringSchema extends BaseSchema {
6366
type: "string";
@@ -157,6 +160,7 @@ declare namespace build {
157160
* @param schema The schema used to stringify values
158161
* @param options The options to use (optional)
159162
*/
163+
declare function build(schema: build.AnySchema, options?: build.Options): (doc: any) => any;
160164
declare function build(schema: build.StringSchema, options?: build.Options): (doc: string) => string;
161165
declare function build(schema: build.IntegerSchema | build.NumberSchema, options?: build.Options): (doc: number) => string;
162166
declare function build(schema: build.NullSchema, options?: build.Options): (doc: null) => "null";

index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ function build (schema, options) {
7070

7171
code += `
7272
${$pad2Zeros.toString()}
73+
${$asAny.toString()}
7374
${$asString.toString()}
7475
${$asStringNullable.toString()}
7576
${$asStringSmall.toString()}
@@ -130,6 +131,9 @@ function build (schema, options) {
130131
main = '$main'
131132
code = buildArray(location, code, main)
132133
break
134+
case undefined:
135+
main = '$asAny'
136+
break
133137
default:
134138
throw new Error(`${schema.type} unsupported`)
135139
}
@@ -237,6 +241,10 @@ function $pad2Zeros (num) {
237241
return s[s.length - 2] + s[s.length - 1]
238242
}
239243

244+
function $asAny (i) {
245+
return JSON.stringify(i)
246+
}
247+
240248
function $asNull () {
241249
return 'null'
242250
}
@@ -890,7 +898,7 @@ function addIfThenElse (location, name) {
890898
}
891899

892900
function toJSON (variableName) {
893-
return `typeof ${variableName}.toJSON === 'function'
901+
return `(${variableName} && typeof ${variableName}.toJSON === 'function')
894902
? ${variableName}.toJSON()
895903
: ${variableName}
896904
`
@@ -1194,6 +1202,10 @@ function nested (laterCode, name, key, location, subKey, isArray) {
11941202
else
11951203
throw new Error(\`Item $\{JSON.stringify(obj${accessor})} does not match schema definition.\`)
11961204
`
1205+
} else if (schema.type === undefined) {
1206+
code += `
1207+
json += JSON.stringify(obj${accessor})
1208+
`
11971209
} else {
11981210
throw new Error(`${schema.type} unsupported`)
11991211
}

test/any.test.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,92 @@ test('array with random items', (t) => {
6363
const value = stringify([1, 'string', null])
6464
t.is(value, '[1,"string",null]')
6565
})
66+
67+
test('empty schema', (t) => {
68+
t.plan(7)
69+
70+
const schema = { }
71+
72+
const stringify = build(schema)
73+
74+
t.is(stringify(null), 'null')
75+
t.is(stringify(1), '1')
76+
t.is(stringify(true), 'true')
77+
t.is(stringify('hello'), '"hello"')
78+
t.is(stringify({}), '{}')
79+
t.is(stringify({ x: 10 }), '{"x":10}')
80+
t.is(stringify([true, 1, 'hello']), '[true,1,"hello"]')
81+
})
82+
83+
test('empty schema on nested object', (t) => {
84+
t.plan(7)
85+
86+
const schema = {
87+
type: 'object',
88+
properties: {
89+
x: {}
90+
}
91+
}
92+
93+
const stringify = build(schema)
94+
95+
t.is(stringify({ x: null }), '{"x":null}')
96+
t.is(stringify({ x: 1 }), '{"x":1}')
97+
t.is(stringify({ x: true }), '{"x":true}')
98+
t.is(stringify({ x: 'hello' }), '{"x":"hello"}')
99+
t.is(stringify({ x: {} }), '{"x":{}}')
100+
t.is(stringify({ x: { x: 10 } }), '{"x":{"x":10}}')
101+
t.is(stringify({ x: [true, 1, 'hello'] }), '{"x":[true,1,"hello"]}')
102+
})
103+
104+
test('empty schema on array', (t) => {
105+
t.plan(1)
106+
107+
const schema = {
108+
type: 'array',
109+
items: {}
110+
}
111+
112+
const stringify = build(schema)
113+
114+
t.is(stringify([1, true, 'hello', [], { x: 1 }]), '[1,true,"hello",[],{"x":1}]')
115+
})
116+
117+
test('empty schema on anyOf', (t) => {
118+
t.plan(4)
119+
120+
// any on Foo codepath.
121+
const schema = {
122+
anyOf: [
123+
{
124+
type: 'object',
125+
properties: {
126+
kind: {
127+
type: 'string',
128+
enum: ['Foo']
129+
},
130+
value: {}
131+
}
132+
},
133+
{
134+
type: 'object',
135+
properties: {
136+
kind: {
137+
type: 'string',
138+
enum: ['Bar']
139+
},
140+
value: {
141+
type: 'number'
142+
}
143+
}
144+
}
145+
]
146+
}
147+
148+
const stringify = build(schema)
149+
150+
t.is(stringify({ kind: 'Bar', value: 1 }), '{"kind":"Bar","value":1}')
151+
t.is(stringify({ kind: 'Foo', value: 1 }), '{"kind":"Foo","value":1}')
152+
t.is(stringify({ kind: 'Foo', value: true }), '{"kind":"Foo","value":true}')
153+
t.is(stringify({ kind: 'Foo', value: 'hello' }), '{"kind":"Foo","value":"hello"}')
154+
})

0 commit comments

Comments
 (0)