Skip to content

Commit 28db9e3

Browse files
authored
Merge pull request #43 from elliotttf/schema-items
fix(buildArray): Support tuple arrays
2 parents f6f2f86 + 881cbf6 commit 28db9e3

File tree

2 files changed

+142
-4
lines changed

2 files changed

+142
-4
lines changed

index.js

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,49 @@ function buildArray (schema, code, name, externalSchema, fullSchema) {
402402
schema.items = refFinder(schema.items['$ref'], fullSchema, externalSchema)
403403
}
404404

405-
var result = nested(laterCode, name, '[i]', schema.items, externalSchema, fullSchema)
405+
var result = {code: '', laterCode: ''}
406+
if (Array.isArray(schema.items)) {
407+
result = schema.items.reduce((res, item, i) => {
408+
var accessor = '[i]'
409+
const tmpRes = nested(laterCode, name, accessor, item, externalSchema, fullSchema, i)
410+
var condition
411+
switch (item.type) {
412+
case 'null':
413+
condition = `obj${accessor} === null`
414+
break
415+
case 'string':
416+
condition = `typeof obj${accessor} === 'string'`
417+
break
418+
case 'integer':
419+
condition = `Number.isInteger(obj${accessor})`
420+
break
421+
case 'number':
422+
condition = `!Number.isInteger(obj${accessor}) && Number.isFinite(obj${accessor})`
423+
break
424+
case 'boolean':
425+
condition = `typeof obj${accessor} === 'boolean'`
426+
break
427+
case 'object':
428+
condition = `obj${accessor} && typeof obj${accessor} === 'object' && obj${accessor}.constructor === Object`
429+
break
430+
case 'array':
431+
condition = `Array.isArray(obj${accessor})`
432+
break
433+
default:
434+
throw new Error(`${item.type} unsupported`)
435+
}
436+
return {
437+
code: `${res.code}
438+
if (${condition}) {
439+
${tmpRes.code}
440+
}`,
441+
laterCode: `${res.laterCode}
442+
${tmpRes.laterCode}`
443+
}
444+
}, result)
445+
} else {
446+
result = nested(laterCode, name, '[i]', schema.items, externalSchema, fullSchema)
447+
}
406448

407449
code += `
408450
var l = obj.length
@@ -428,7 +470,7 @@ function buildArray (schema, code, name, externalSchema, fullSchema) {
428470
return code
429471
}
430472

431-
function nested (laterCode, name, key, schema, externalSchema, fullSchema) {
473+
function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKey) {
432474
var code = ''
433475
var funcName
434476
var type = schema.type
@@ -460,14 +502,14 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema) {
460502
`
461503
break
462504
case 'object':
463-
funcName = (name + key).replace(/[-.\[\]]/g, '') // eslint-disable-line
505+
funcName = (name + key + subKey).replace(/[-.\[\]]/g, '') // eslint-disable-line
464506
laterCode = buildObject(schema, laterCode, funcName, externalSchema, fullSchema)
465507
code += `
466508
json += ${funcName}(obj${accessor})
467509
`
468510
break
469511
case 'array':
470-
funcName = (name + key).replace(/[-.\[\]]/g, '') // eslint-disable-line
512+
funcName = (name + key + subKey).replace(/[-.\[\]]/g, '') // eslint-disable-line
471513
laterCode = buildArray(schema, laterCode, funcName, externalSchema, fullSchema)
472514
code += `
473515
json += ${funcName}(obj${accessor})

test/array.test.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use strict'
2+
3+
const test = require('tap').test
4+
const validator = require('is-my-json-valid')
5+
const build = require('..')
6+
7+
function buildTest (schema, toStringify) {
8+
test(`render a ${schema.title} as JSON`, (t) => {
9+
t.plan(5)
10+
11+
const validate = validator(schema)
12+
const stringify = build(schema)
13+
const stringifyUgly = build(schema, {uglify: true})
14+
const output = stringify(toStringify)
15+
const outputUglify = stringifyUgly(toStringify)
16+
17+
t.deepEqual(JSON.parse(output), toStringify)
18+
t.deepEqual(JSON.parse(outputUglify), toStringify)
19+
t.equal(output, JSON.stringify(toStringify))
20+
t.equal(outputUglify, JSON.stringify(toStringify))
21+
t.ok(validate(JSON.parse(output)), 'valid schema')
22+
})
23+
}
24+
25+
buildTest({
26+
'title': 'string array',
27+
'type': 'object',
28+
'properties': {
29+
'ids': {
30+
'type': 'array',
31+
'items': {
32+
'type': 'string'
33+
}
34+
}
35+
}
36+
}, {
37+
ids: ['test']
38+
})
39+
40+
buildTest({
41+
'title': 'number array',
42+
'type': 'object',
43+
'properties': {
44+
'ids': {
45+
'type': 'array',
46+
'items': {
47+
'type': 'number'
48+
}
49+
}
50+
}
51+
}, {
52+
ids: [1]
53+
})
54+
55+
buildTest({
56+
'title': 'mixed array',
57+
'type': 'object',
58+
'properties': {
59+
'ids': {
60+
'type': 'array',
61+
'items': [
62+
{
63+
'type': 'null'
64+
},
65+
{
66+
'type': 'string'
67+
},
68+
{
69+
'type': 'integer'
70+
},
71+
{
72+
'type': 'number'
73+
},
74+
{
75+
'type': 'boolean'
76+
},
77+
{
78+
'type': 'object',
79+
'properties': {
80+
'a': {
81+
'type': 'string'
82+
}
83+
}
84+
},
85+
{
86+
'type': 'array',
87+
'items': {
88+
'type': 'string'
89+
}
90+
}
91+
]
92+
}
93+
}
94+
}, {
95+
ids: [null, 'test', 1, 1.1, true, {a: 'test'}, ['test']]
96+
})

0 commit comments

Comments
 (0)