fast-json-stringify 2.7.8 → 2.7.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/benchmark.yml +111 -0
- package/.github/workflows/ci.yml +2 -2
- package/README.md +13 -10
- package/bench.js +28 -0
- package/index.d.ts +1 -0
- package/index.js +48 -17
- package/package.json +1 -1
- package/test/recursion.test.js +180 -0
- package/test/types/test.ts +8 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
name: Benchmark
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request_target:
|
|
5
|
+
types: [labeled]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
benchmark:
|
|
9
|
+
if: ${{ github.event.label.name == 'benchmark' }}
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
outputs:
|
|
12
|
+
PR-BENCH-12: ${{ steps.benchmark-pr.outputs.BENCH_RESULT12 }}
|
|
13
|
+
PR-BENCH-14: ${{ steps.benchmark-pr.outputs.BENCH_RESULT14 }}
|
|
14
|
+
PR-BENCH-16: ${{ steps.benchmark-pr.outputs.BENCH_RESULT16 }}
|
|
15
|
+
MAIN-BENCH-12: ${{ steps.benchmark-main.outputs.BENCH_RESULT12 }}
|
|
16
|
+
MAIN-BENCH-14: ${{ steps.benchmark-main.outputs.BENCH_RESULT14 }}
|
|
17
|
+
MAIN-BENCH-16: ${{ steps.benchmark-main.outputs.BENCH_RESULT16 }}
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
node-version: [12, 14, 16]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v2
|
|
23
|
+
with:
|
|
24
|
+
ref: ${{github.event.pull_request.head.ref}}
|
|
25
|
+
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
26
|
+
|
|
27
|
+
- uses: actions/setup-node@v2
|
|
28
|
+
with:
|
|
29
|
+
node-version: ${{ matrix.node-version }}
|
|
30
|
+
|
|
31
|
+
- name: Install
|
|
32
|
+
run: |
|
|
33
|
+
npm install --ignore-scripts
|
|
34
|
+
|
|
35
|
+
- name: Run benchmark
|
|
36
|
+
id: benchmark-pr
|
|
37
|
+
run: |
|
|
38
|
+
npm run --silent benchmark > ./bench-result
|
|
39
|
+
content=$(cat ./bench-result)
|
|
40
|
+
content="${content//'%'/'%25'}"
|
|
41
|
+
content="${content//$'\n'/'%0A'}"
|
|
42
|
+
content="${content//$'\r'/'%0D'}"
|
|
43
|
+
echo "::set-output name=BENCH_RESULT${{matrix.node-version}}::$content"
|
|
44
|
+
|
|
45
|
+
# main benchmark
|
|
46
|
+
- uses: actions/checkout@v2
|
|
47
|
+
with:
|
|
48
|
+
ref: 'master'
|
|
49
|
+
|
|
50
|
+
- name: Install
|
|
51
|
+
run: |
|
|
52
|
+
npm install --ignore-scripts
|
|
53
|
+
|
|
54
|
+
- name: Run benchmark
|
|
55
|
+
id: benchmark-master
|
|
56
|
+
run: |
|
|
57
|
+
npm run --silent benchmark > ./bench-result
|
|
58
|
+
content=$(cat ./bench-result)
|
|
59
|
+
content="${content//'%'/'%25'}"
|
|
60
|
+
content="${content//$'\n'/'%0A'}"
|
|
61
|
+
content="${content//$'\r'/'%0D'}"
|
|
62
|
+
echo "::set-output name=BENCH_RESULT${{matrix.node-version}}::$content"
|
|
63
|
+
|
|
64
|
+
output-benchmark:
|
|
65
|
+
needs: [benchmark]
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
steps:
|
|
68
|
+
- name: Comment PR
|
|
69
|
+
uses: thollander/actions-comment-pull-request@v1
|
|
70
|
+
with:
|
|
71
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
72
|
+
message: |
|
|
73
|
+
**Node**: 12
|
|
74
|
+
**PR**:
|
|
75
|
+
```
|
|
76
|
+
${{ needs.benchmark.outputs.PR-BENCH-12 }}
|
|
77
|
+
```
|
|
78
|
+
**MAIN**:
|
|
79
|
+
```
|
|
80
|
+
${{ needs.benchmark.outputs.MAIN-BENCH-12 }}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
**Node**: 14
|
|
86
|
+
**PR**:
|
|
87
|
+
```
|
|
88
|
+
${{ needs.benchmark.outputs.PR-BENCH-14 }}
|
|
89
|
+
```
|
|
90
|
+
**MAIN**:
|
|
91
|
+
```
|
|
92
|
+
${{ needs.benchmark.outputs.MAIN-BENCH-14 }}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
**Node**: 16
|
|
98
|
+
**PR**:
|
|
99
|
+
```
|
|
100
|
+
${{ needs.benchmark.outputs.PR-BENCH-16 }}
|
|
101
|
+
```
|
|
102
|
+
**MAIN**:
|
|
103
|
+
```
|
|
104
|
+
${{ needs.benchmark.outputs.MAIN-BENCH-16 }}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- uses: actions-ecosystem/action-remove-labels@v1
|
|
108
|
+
with:
|
|
109
|
+
labels: |
|
|
110
|
+
benchmark
|
|
111
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
- uses: actions/checkout@v2.3.4
|
|
23
23
|
|
|
24
24
|
- name: Use Node.js
|
|
25
|
-
uses: actions/setup-node@v2.
|
|
25
|
+
uses: actions/setup-node@v2.4.0
|
|
26
26
|
with:
|
|
27
27
|
node-version: ${{ matrix.node-version }}
|
|
28
28
|
|
|
@@ -38,6 +38,6 @@ jobs:
|
|
|
38
38
|
needs: test
|
|
39
39
|
runs-on: ubuntu-latest
|
|
40
40
|
steps:
|
|
41
|
-
- uses: fastify/github-action-merge-dependabot@v2.
|
|
41
|
+
- uses: fastify/github-action-merge-dependabot@v2.5.0
|
|
42
42
|
with:
|
|
43
43
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
package/README.md
CHANGED
|
@@ -12,22 +12,25 @@ __fast-json-stringify__ is significantly faster than `JSON.stringify()` for smal
|
|
|
12
12
|
##### Benchmarks
|
|
13
13
|
|
|
14
14
|
- Machine: `EX41S-SSD, Intel Core i7, 4Ghz, 64GB RAM, 4C/8T, SSD`.
|
|
15
|
-
- Node.js `
|
|
15
|
+
- Node.js `v16.9.1`
|
|
16
16
|
|
|
17
17
|
```
|
|
18
|
-
FJS creation x
|
|
18
|
+
FJS creation x 6,040 ops/sec ±1.17% (91 runs sampled)
|
|
19
19
|
|
|
20
|
-
JSON.stringify array x 5,
|
|
21
|
-
fast-json-stringify array x
|
|
20
|
+
JSON.stringify array x 5,519 ops/sec ±0.08% (99 runs sampled)
|
|
21
|
+
fast-json-stringify array x 7,143 ops/sec ±0.14% (97 runs sampled)
|
|
22
22
|
|
|
23
|
-
JSON.stringify long string x
|
|
24
|
-
fast-json-stringify long string x
|
|
23
|
+
JSON.stringify long string x 16,438 ops/sec ±0.32% (98 runs sampled)
|
|
24
|
+
fast-json-stringify long string x 16,457 ops/sec ±0.09% (97 runs sampled)
|
|
25
25
|
|
|
26
|
-
JSON.stringify short string x
|
|
27
|
-
fast-json-stringify short string x
|
|
26
|
+
JSON.stringify short string x 12,061,258 ops/sec ±0.32% (97 runs sampled)
|
|
27
|
+
fast-json-stringify short string x 35,531,071 ops/sec ±0.17% (94 runs sampled)
|
|
28
28
|
|
|
29
|
-
JSON.stringify obj x 3,
|
|
30
|
-
fast-json-stringify obj x
|
|
29
|
+
JSON.stringify obj x 3,079,746 ops/sec ±0.09% (95 runs sampled)
|
|
30
|
+
fast-json-stringify obj x 7,721,569 ops/sec ±0.12% (98 runs sampled)
|
|
31
|
+
|
|
32
|
+
JSON stringify date x 1,149,786 ops/sec ±0.10% (99 runs sampled)
|
|
33
|
+
fast-json-stringify date format x 1,674,498 ops/sec ±0.12% (99 runs sampled)
|
|
31
34
|
```
|
|
32
35
|
|
|
33
36
|
#### Table of contents:
|
package/bench.js
CHANGED
|
@@ -50,22 +50,38 @@ const arraySchemaCJS = {
|
|
|
50
50
|
items: schemaCJS
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
const dateFormatSchema = {
|
|
54
|
+
description: 'Date of birth',
|
|
55
|
+
type: 'string',
|
|
56
|
+
format: 'date'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const dateFormatSchemaCJS = {
|
|
60
|
+
description: 'Date of birth',
|
|
61
|
+
type: 'string',
|
|
62
|
+
format: 'date'
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
const obj = {
|
|
54
66
|
firstName: 'Matteo',
|
|
55
67
|
lastName: 'Collina',
|
|
56
68
|
age: 32
|
|
57
69
|
}
|
|
58
70
|
|
|
71
|
+
const date = new Date()
|
|
72
|
+
|
|
59
73
|
const multiArray = []
|
|
60
74
|
|
|
61
75
|
const CJS = require('compile-json-stringify')
|
|
62
76
|
const CJSStringify = CJS(schemaCJS)
|
|
63
77
|
const CJSStringifyArray = CJS(arraySchemaCJS)
|
|
78
|
+
const CJSStringifyDate = CJS(dateFormatSchemaCJS)
|
|
64
79
|
const CJSStringifyString = CJS({ type: 'string' })
|
|
65
80
|
|
|
66
81
|
const FJS = require('.')
|
|
67
82
|
const stringify = FJS(schema)
|
|
68
83
|
const stringifyArray = FJS(arraySchema)
|
|
84
|
+
const stringifyDate = FJS(dateFormatSchema)
|
|
69
85
|
const stringifyString = FJS({ type: 'string' })
|
|
70
86
|
let str = ''
|
|
71
87
|
|
|
@@ -138,6 +154,18 @@ suite.add('compile-json-stringify obj', function () {
|
|
|
138
154
|
CJSStringify(obj)
|
|
139
155
|
})
|
|
140
156
|
|
|
157
|
+
suite.add('JSON stringify date', function () {
|
|
158
|
+
JSON.stringify(date)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
suite.add('fast-json-stringify date format', function () {
|
|
162
|
+
stringifyDate(date)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
suite.add('compile-json-stringify date format', function () {
|
|
166
|
+
CJSStringifyDate(date)
|
|
167
|
+
})
|
|
168
|
+
|
|
141
169
|
suite.on('cycle', cycle)
|
|
142
170
|
|
|
143
171
|
suite.run()
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -47,7 +47,12 @@ function mergeLocation (source, dest) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
const arrayItemsReferenceSerializersMap = new Map()
|
|
51
|
+
const objectReferenceSerializersMap = new Map()
|
|
52
|
+
|
|
50
53
|
function build (schema, options) {
|
|
54
|
+
arrayItemsReferenceSerializersMap.clear()
|
|
55
|
+
objectReferenceSerializersMap.clear()
|
|
51
56
|
options = options || {}
|
|
52
57
|
isValidSchema(schema)
|
|
53
58
|
if (options.schema) {
|
|
@@ -144,6 +149,9 @@ function build (schema, options) {
|
|
|
144
149
|
return dependenciesName
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
arrayItemsReferenceSerializersMap.clear()
|
|
153
|
+
objectReferenceSerializersMap.clear()
|
|
154
|
+
|
|
147
155
|
return (Function.apply(null, dependenciesName).apply(null, dependencies))
|
|
148
156
|
}
|
|
149
157
|
|
|
@@ -285,10 +293,7 @@ function $asDatetime (date, skipQuotes) {
|
|
|
285
293
|
function $asDate (date, skipQuotes) {
|
|
286
294
|
const quotes = skipQuotes === true ? '' : '"'
|
|
287
295
|
if (date instanceof Date) {
|
|
288
|
-
|
|
289
|
-
const month = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(date)
|
|
290
|
-
const day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date)
|
|
291
|
-
return quotes + year + '-' + month + '-' + day + quotes
|
|
296
|
+
return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )).toISOString().slice(0, 10) + quotes
|
|
292
297
|
} else if (date && typeof date.format === 'function') {
|
|
293
298
|
return quotes + date.format('YYYY-MM-DD') + quotes
|
|
294
299
|
} else {
|
|
@@ -397,51 +402,60 @@ function addPatternProperties (location) {
|
|
|
397
402
|
} catch (err) {
|
|
398
403
|
throw new Error(`${err.message}. Found at ${regex} matching ${JSON.stringify(pp[regex])}`)
|
|
399
404
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
405
|
+
|
|
406
|
+
const ifPpKeyExists = `if (/${regex.replace(/\\*\//g, '\\/')}/.test(keys[i])) {`
|
|
407
|
+
|
|
403
408
|
if (type === 'object') {
|
|
404
409
|
code += `${buildObject(ppLocation, '', 'buildObjectPP' + index)}
|
|
410
|
+
${ifPpKeyExists}
|
|
405
411
|
${addComma}
|
|
406
412
|
json += $asString(keys[i]) + ':' + buildObjectPP${index}(obj[keys[i]])
|
|
407
413
|
`
|
|
408
414
|
} else if (type === 'array') {
|
|
409
415
|
code += `${buildArray(ppLocation, '', 'buildArrayPP' + index)}
|
|
416
|
+
${ifPpKeyExists}
|
|
410
417
|
${addComma}
|
|
411
418
|
json += $asString(keys[i]) + ':' + buildArrayPP${index}(obj[keys[i]])
|
|
412
419
|
`
|
|
413
420
|
} else if (type === 'null') {
|
|
414
421
|
code += `
|
|
422
|
+
${ifPpKeyExists}
|
|
415
423
|
${addComma}
|
|
416
424
|
json += $asString(keys[i]) +':null'
|
|
417
425
|
`
|
|
418
426
|
} else if (type === 'string') {
|
|
419
427
|
code += `
|
|
428
|
+
${ifPpKeyExists}
|
|
420
429
|
${addComma}
|
|
421
430
|
json += $asString(keys[i]) + ':' + ${stringSerializer}(obj[keys[i]])
|
|
422
431
|
`
|
|
423
432
|
} else if (type === 'integer') {
|
|
424
433
|
code += `
|
|
434
|
+
${ifPpKeyExists}
|
|
425
435
|
${addComma}
|
|
426
436
|
json += $asString(keys[i]) + ':' + $asInteger(obj[keys[i]])
|
|
427
437
|
`
|
|
428
438
|
} else if (type === 'number') {
|
|
429
439
|
code += `
|
|
440
|
+
${ifPpKeyExists}
|
|
430
441
|
${addComma}
|
|
431
442
|
json += $asString(keys[i]) + ':' + $asNumber(obj[keys[i]])
|
|
432
443
|
`
|
|
433
444
|
} else if (type === 'boolean') {
|
|
434
445
|
code += `
|
|
446
|
+
${ifPpKeyExists}
|
|
435
447
|
${addComma}
|
|
436
448
|
json += $asString(keys[i]) + ':' + $asBoolean(obj[keys[i]])
|
|
437
449
|
`
|
|
438
450
|
} else if (type === undefined) {
|
|
439
451
|
code += `
|
|
452
|
+
${ifPpKeyExists}
|
|
440
453
|
${addComma}
|
|
441
454
|
json += $asString(keys[i]) + ':' + $asAny(obj[keys[i]])
|
|
442
455
|
`
|
|
443
456
|
} else {
|
|
444
457
|
code += `
|
|
458
|
+
${ifPpKeyExists}
|
|
445
459
|
throw new Error('Cannot coerce ' + obj[keys[i]] + ' to ' + ${JSON.stringify(type)})
|
|
446
460
|
`
|
|
447
461
|
}
|
|
@@ -920,6 +934,16 @@ function buildObject (location, code, name) {
|
|
|
920
934
|
}
|
|
921
935
|
`
|
|
922
936
|
}
|
|
937
|
+
|
|
938
|
+
if (objectReferenceSerializersMap.has(schema)) {
|
|
939
|
+
code += `
|
|
940
|
+
return ${objectReferenceSerializersMap.get(schema)}(input)
|
|
941
|
+
}
|
|
942
|
+
`
|
|
943
|
+
return code
|
|
944
|
+
}
|
|
945
|
+
objectReferenceSerializersMap.set(schema, name)
|
|
946
|
+
|
|
923
947
|
code += `
|
|
924
948
|
var obj = ${toJSON('input')}
|
|
925
949
|
var json = '{'
|
|
@@ -959,9 +983,6 @@ function buildArray (location, code, name, key = null) {
|
|
|
959
983
|
}
|
|
960
984
|
`
|
|
961
985
|
}
|
|
962
|
-
code += `
|
|
963
|
-
var json = '['
|
|
964
|
-
`
|
|
965
986
|
const laterCode = ''
|
|
966
987
|
|
|
967
988
|
// default to any items type
|
|
@@ -975,8 +996,18 @@ function buildArray (location, code, name, key = null) {
|
|
|
975
996
|
schema = location.schema
|
|
976
997
|
schema[fjsCloned] = true
|
|
977
998
|
}
|
|
999
|
+
|
|
978
1000
|
location = refFinder(schema.items.$ref, location)
|
|
979
1001
|
schema.items = location.schema
|
|
1002
|
+
|
|
1003
|
+
if (arrayItemsReferenceSerializersMap.has(schema.items)) {
|
|
1004
|
+
code += `
|
|
1005
|
+
return ${arrayItemsReferenceSerializersMap.get(schema.items)}(obj)
|
|
1006
|
+
}
|
|
1007
|
+
`
|
|
1008
|
+
return code
|
|
1009
|
+
}
|
|
1010
|
+
arrayItemsReferenceSerializersMap.set(schema.items, name)
|
|
980
1011
|
}
|
|
981
1012
|
|
|
982
1013
|
let result = { code: '', laterCode: '' }
|
|
@@ -1023,17 +1054,17 @@ function buildArray (location, code, name, key = null) {
|
|
|
1023
1054
|
|
|
1024
1055
|
code += `
|
|
1025
1056
|
var l = obj.length
|
|
1026
|
-
|
|
1057
|
+
var jsonOutput= ''
|
|
1027
1058
|
for (var i = 0; i < l; i++) {
|
|
1028
|
-
var
|
|
1059
|
+
var json = ''
|
|
1060
|
+
${result.code}
|
|
1061
|
+
jsonOutput += json
|
|
1029
1062
|
|
|
1030
|
-
if (
|
|
1031
|
-
|
|
1063
|
+
if (json.length > 0 && i < l - 1) {
|
|
1064
|
+
jsonOutput += ','
|
|
1032
1065
|
}
|
|
1033
|
-
${result.code}
|
|
1034
1066
|
}
|
|
1035
|
-
|
|
1036
|
-
return json
|
|
1067
|
+
return \`[\${jsonOutput}]\`
|
|
1037
1068
|
}
|
|
1038
1069
|
${result.laterCode}
|
|
1039
1070
|
`
|
package/package.json
CHANGED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('tap').test
|
|
4
|
+
const build = require('..')
|
|
5
|
+
|
|
6
|
+
test('can stringify recursive directory tree (issue #181)', (t) => {
|
|
7
|
+
t.plan(1)
|
|
8
|
+
|
|
9
|
+
const schema = {
|
|
10
|
+
definitions: {
|
|
11
|
+
directory: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
name: { type: 'string' },
|
|
15
|
+
subDirectories: {
|
|
16
|
+
type: 'array',
|
|
17
|
+
items: { $ref: '#/definitions/directory' },
|
|
18
|
+
default: []
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
type: 'array',
|
|
24
|
+
items: { $ref: '#/definitions/directory' }
|
|
25
|
+
}
|
|
26
|
+
const stringify = build(schema)
|
|
27
|
+
|
|
28
|
+
t.equal(stringify([
|
|
29
|
+
{ name: 'directory 1', subDirectories: [] },
|
|
30
|
+
{
|
|
31
|
+
name: 'directory 2',
|
|
32
|
+
subDirectories: [
|
|
33
|
+
{ name: 'directory 2.1', subDirectories: [] },
|
|
34
|
+
{ name: 'directory 2.2', subDirectories: [] }
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
]), '[{"name":"directory 1","subDirectories":[]},{"name":"directory 2","subDirectories":[{"name":"directory 2.1","subDirectories":[]},{"name":"directory 2.2","subDirectories":[]}]}]')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('can stringify when recursion in external schema', t => {
|
|
41
|
+
t.plan(1)
|
|
42
|
+
|
|
43
|
+
const referenceSchema = {
|
|
44
|
+
$id: 'person',
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: {
|
|
47
|
+
name: { type: 'string' },
|
|
48
|
+
children: {
|
|
49
|
+
type: 'array',
|
|
50
|
+
items: { $ref: '#' }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const schema = {
|
|
56
|
+
$id: 'mainSchema',
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
people: {
|
|
60
|
+
$ref: 'person'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const stringify = build(schema, {
|
|
65
|
+
schema: {
|
|
66
|
+
[referenceSchema.$id]: referenceSchema
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const value = stringify({ people: { name: 'Elizabeth', children: [{ name: 'Charles' }] } })
|
|
71
|
+
t.equal(value, '{"people":{"name":"Elizabeth","children":[{"name":"Charles"}]}}')
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
test('use proper serialize function', t => {
|
|
75
|
+
t.plan(1)
|
|
76
|
+
|
|
77
|
+
const personSchema = {
|
|
78
|
+
$id: 'person',
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {
|
|
81
|
+
name: { type: 'string' },
|
|
82
|
+
children: {
|
|
83
|
+
type: 'array',
|
|
84
|
+
items: { $ref: '#' }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const directorySchema = {
|
|
90
|
+
$id: 'directory',
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
name: { type: 'string' },
|
|
94
|
+
subDirectories: {
|
|
95
|
+
type: 'array',
|
|
96
|
+
items: { $ref: '#' },
|
|
97
|
+
default: []
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const schema = {
|
|
103
|
+
$id: 'mainSchema',
|
|
104
|
+
type: 'object',
|
|
105
|
+
properties: {
|
|
106
|
+
people: { $ref: 'person' },
|
|
107
|
+
directory: { $ref: 'directory' }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const stringify = build(schema, {
|
|
111
|
+
schema: {
|
|
112
|
+
[personSchema.$id]: personSchema,
|
|
113
|
+
[directorySchema.$id]: directorySchema
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const value = stringify({
|
|
118
|
+
people: {
|
|
119
|
+
name: 'Elizabeth',
|
|
120
|
+
children: [{
|
|
121
|
+
name: 'Charles',
|
|
122
|
+
children: [{ name: 'William', children: [{ name: 'George' }, { name: 'Charlotte' }] }, { name: 'Harry' }]
|
|
123
|
+
}]
|
|
124
|
+
},
|
|
125
|
+
directory: {
|
|
126
|
+
name: 'directory 1',
|
|
127
|
+
subDirectories: [
|
|
128
|
+
{ name: 'directory 1.1', subDirectories: [] },
|
|
129
|
+
{
|
|
130
|
+
name: 'directory 1.2',
|
|
131
|
+
subDirectories: [{ name: 'directory 1.2.1' }, { name: 'directory 1.2.2' }]
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
t.equal(value, '{"people":{"name":"Elizabeth","children":[{"name":"Charles","children":[{"name":"William","children":[{"name":"George"},{"name":"Charlotte"}]},{"name":"Harry"}]}]},"directory":{"name":"directory 1","subDirectories":[{"name":"directory 1.1","subDirectories":[]},{"name":"directory 1.2","subDirectories":[{"name":"directory 1.2.1","subDirectories":[]},{"name":"directory 1.2.2","subDirectories":[]}]}]}}')
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
test('can stringify recursive references in object types (issue #365)', t => {
|
|
140
|
+
t.plan(1)
|
|
141
|
+
|
|
142
|
+
const schema = {
|
|
143
|
+
type: 'object',
|
|
144
|
+
definitions: {
|
|
145
|
+
parentCategory: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
parent: {
|
|
149
|
+
$ref: '#/definitions/parentCategory'
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
properties: {
|
|
155
|
+
category: {
|
|
156
|
+
type: 'object',
|
|
157
|
+
properties: {
|
|
158
|
+
parent: {
|
|
159
|
+
$ref: '#/definitions/parentCategory'
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const stringify = build(schema)
|
|
167
|
+
const data = {
|
|
168
|
+
category: {
|
|
169
|
+
parent: {
|
|
170
|
+
parent: {
|
|
171
|
+
parent: {
|
|
172
|
+
parent: {}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const value = stringify(data)
|
|
179
|
+
t.equal(value, '{"category":{"parent":{"parent":{"parent":{"parent":{}}}}}}')
|
|
180
|
+
})
|
package/test/types/test.ts
CHANGED
|
@@ -135,3 +135,11 @@ const schema11: Schema = {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
build(schema11)({ something: 'a string', somethingElse: 42 })
|
|
138
|
+
|
|
139
|
+
// String schema with format
|
|
140
|
+
const schema12: Schema = {
|
|
141
|
+
type: 'string',
|
|
142
|
+
format: 'date-time'
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
build(schema12)(new Date())
|