fast-json-stringify 3.1.0 → 4.1.0
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 +3 -3
- package/.github/workflows/ci.yml +3 -33
- package/README.md +37 -13
- package/ajv.js +37 -0
- package/benchmark/bench-cmp-branch.js +114 -0
- package/{bench.js → benchmark/bench-cmp-lib.js} +4 -4
- package/benchmark/bench-thread.js +21 -0
- package/benchmark/bench.js +251 -0
- package/example.js +0 -3
- package/index.d.ts +4 -0
- package/index.js +402 -691
- package/package.json +11 -5
- package/serializer.js +168 -0
- package/test/additionalProperties.test.js +23 -19
- package/test/allof.test.js +56 -0
- package/test/anyof.test.js +88 -9
- package/test/array.test.js +110 -23
- package/test/basic.test.js +8 -8
- package/test/date.test.js +62 -35
- package/test/debug-mode.test.js +1 -1
- package/test/fixtures/.keep +0 -0
- package/test/if-then-else.test.js +2 -2
- package/test/nestedObjects.test.js +31 -0
- package/test/nullable.test.js +343 -15
- package/test/oneof.test.js +9 -22
- package/test/patternProperties.test.js +17 -6
- package/test/recursion.test.js +65 -0
- package/test/required.test.js +1 -1
- package/test/sanitize3.test.js +9 -11
- package/test/standalone-mode.test.js +38 -0
- package/test/typesArray.test.js +40 -3
package/test/array.test.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const moment = require('moment')
|
|
4
3
|
const test = require('tap').test
|
|
5
4
|
const validator = require('is-my-json-valid')
|
|
6
5
|
const build = require('..')
|
|
@@ -177,27 +176,6 @@ test('invalid items throw', (t) => {
|
|
|
177
176
|
t.throws(() => stringify({ args: ['invalid'] }))
|
|
178
177
|
})
|
|
179
178
|
|
|
180
|
-
test('moment array', (t) => {
|
|
181
|
-
t.plan(1)
|
|
182
|
-
const schema = {
|
|
183
|
-
type: 'object',
|
|
184
|
-
properties: {
|
|
185
|
-
times: {
|
|
186
|
-
type: 'array',
|
|
187
|
-
items: {
|
|
188
|
-
type: 'string',
|
|
189
|
-
format: 'date-time'
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
const stringify = build(schema)
|
|
195
|
-
const value = stringify({
|
|
196
|
-
times: [moment('2018-04-21T07:52:31.017Z')]
|
|
197
|
-
})
|
|
198
|
-
t.equal(value, '{"times":["2018-04-21T07:52:31.017Z"]}')
|
|
199
|
-
})
|
|
200
|
-
|
|
201
179
|
buildTest({
|
|
202
180
|
title: 'item types in array default to any',
|
|
203
181
|
type: 'object',
|
|
@@ -240,6 +218,35 @@ test('array items is a list of schema and additionalItems is true, just the desc
|
|
|
240
218
|
t.equal(result, '{"foo":["foo","bar",1]}')
|
|
241
219
|
})
|
|
242
220
|
|
|
221
|
+
test('array items is a list of schema and additionalItems is true, just the described item is validated', (t) => {
|
|
222
|
+
t.plan(1)
|
|
223
|
+
|
|
224
|
+
const schema = {
|
|
225
|
+
type: 'object',
|
|
226
|
+
properties: {
|
|
227
|
+
foo: {
|
|
228
|
+
type: 'array',
|
|
229
|
+
items: [
|
|
230
|
+
{
|
|
231
|
+
type: 'string'
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
type: 'number'
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
additionalItems: true
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const stringify = build(schema)
|
|
243
|
+
const result = stringify({
|
|
244
|
+
foo: ['foo']
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
t.equal(result, '{"foo":["foo"]}')
|
|
248
|
+
})
|
|
249
|
+
|
|
243
250
|
test('array items is a list of schema and additionalItems is false', (t) => {
|
|
244
251
|
t.plan(1)
|
|
245
252
|
|
|
@@ -344,7 +351,7 @@ buildTest({
|
|
|
344
351
|
})
|
|
345
352
|
|
|
346
353
|
buildTest({
|
|
347
|
-
title: 'large array with json-stringify mechanism',
|
|
354
|
+
title: 'large array of objects with json-stringify mechanism',
|
|
348
355
|
type: 'object',
|
|
349
356
|
properties: {
|
|
350
357
|
ids: {
|
|
@@ -363,3 +370,83 @@ buildTest({
|
|
|
363
370
|
}, {
|
|
364
371
|
largeArrayMechanism: 'json-stringify'
|
|
365
372
|
})
|
|
373
|
+
|
|
374
|
+
buildTest({
|
|
375
|
+
title: 'large array of strings with default mechanism',
|
|
376
|
+
type: 'object',
|
|
377
|
+
properties: {
|
|
378
|
+
ids: {
|
|
379
|
+
type: 'array',
|
|
380
|
+
items: { type: 'string' }
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}, {
|
|
384
|
+
ids: new Array(2e4).fill('string')
|
|
385
|
+
}, {
|
|
386
|
+
largeArraySize: 2e4,
|
|
387
|
+
largeArrayMechanism: 'default'
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
buildTest({
|
|
391
|
+
title: 'large array of numbers with default mechanism',
|
|
392
|
+
type: 'object',
|
|
393
|
+
properties: {
|
|
394
|
+
ids: {
|
|
395
|
+
type: 'array',
|
|
396
|
+
items: { type: 'number' }
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}, {
|
|
400
|
+
ids: new Array(2e4).fill(42)
|
|
401
|
+
}, {
|
|
402
|
+
largeArraySize: 2e4,
|
|
403
|
+
largeArrayMechanism: 'default'
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
buildTest({
|
|
407
|
+
title: 'large array of integers with default mechanism',
|
|
408
|
+
type: 'object',
|
|
409
|
+
properties: {
|
|
410
|
+
ids: {
|
|
411
|
+
type: 'array',
|
|
412
|
+
items: { type: 'integer' }
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}, {
|
|
416
|
+
ids: new Array(2e4).fill(42)
|
|
417
|
+
}, {
|
|
418
|
+
largeArraySize: 2e4,
|
|
419
|
+
largeArrayMechanism: 'default'
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
buildTest({
|
|
423
|
+
title: 'large array of booleans with default mechanism',
|
|
424
|
+
type: 'object',
|
|
425
|
+
properties: {
|
|
426
|
+
ids: {
|
|
427
|
+
type: 'array',
|
|
428
|
+
items: { type: 'boolean' }
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}, {
|
|
432
|
+
ids: new Array(2e4).fill(true)
|
|
433
|
+
}, {
|
|
434
|
+
largeArraySize: 2e4,
|
|
435
|
+
largeArrayMechanism: 'default'
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
buildTest({
|
|
439
|
+
title: 'large array of null values with default mechanism',
|
|
440
|
+
type: 'object',
|
|
441
|
+
properties: {
|
|
442
|
+
ids: {
|
|
443
|
+
type: 'array',
|
|
444
|
+
items: { type: 'null' }
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}, {
|
|
448
|
+
ids: new Array(2e4).fill(null)
|
|
449
|
+
}, {
|
|
450
|
+
largeArraySize: 2e4,
|
|
451
|
+
largeArrayMechanism: 'default'
|
|
452
|
+
})
|
package/test/basic.test.js
CHANGED
|
@@ -261,7 +261,7 @@ buildTest({
|
|
|
261
261
|
readonly: true
|
|
262
262
|
})
|
|
263
263
|
|
|
264
|
-
test('
|
|
264
|
+
test('throw an error or coerce numbers and integers that are not numbers', (t) => {
|
|
265
265
|
const stringify = build({
|
|
266
266
|
title: 'basic',
|
|
267
267
|
type: 'object',
|
|
@@ -275,14 +275,14 @@ test('skip or coerce numbers and integers that are not numbers', (t) => {
|
|
|
275
275
|
}
|
|
276
276
|
})
|
|
277
277
|
|
|
278
|
-
|
|
279
|
-
age: 'hello ',
|
|
280
|
-
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
|
|
278
|
+
try {
|
|
279
|
+
stringify({ age: 'hello ', distance: 'long' })
|
|
280
|
+
t.fail('should throw an error')
|
|
281
|
+
} catch (err) {
|
|
282
|
+
t.ok(err)
|
|
283
|
+
}
|
|
284
284
|
|
|
285
|
-
result = stringify({
|
|
285
|
+
const result = stringify({
|
|
286
286
|
age: '42',
|
|
287
287
|
distance: true
|
|
288
288
|
})
|
package/test/date.test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const test = require('tap').test
|
|
4
|
-
const
|
|
4
|
+
const { DateTime } = require('luxon')
|
|
5
5
|
const validator = require('is-my-json-valid')
|
|
6
6
|
const build = require('..')
|
|
7
7
|
|
|
@@ -40,13 +40,14 @@ test('render a date in a string when format is date-format as ISOString', (t) =>
|
|
|
40
40
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
test('render a date in a string when format is date as
|
|
43
|
+
test('render a nullable date in a string when format is date-format as ISOString', (t) => {
|
|
44
44
|
t.plan(2)
|
|
45
45
|
|
|
46
46
|
const schema = {
|
|
47
47
|
title: 'a date in a string',
|
|
48
48
|
type: 'string',
|
|
49
|
-
format: 'date'
|
|
49
|
+
format: 'date-time',
|
|
50
|
+
nullable: true
|
|
50
51
|
}
|
|
51
52
|
const toStringify = new Date()
|
|
52
53
|
|
|
@@ -54,11 +55,11 @@ test('render a date in a string when format is date as YYYY-MM-DD', (t) => {
|
|
|
54
55
|
const stringify = build(schema)
|
|
55
56
|
const output = stringify(toStringify)
|
|
56
57
|
|
|
57
|
-
t.equal(output,
|
|
58
|
+
t.equal(output, JSON.stringify(toStringify))
|
|
58
59
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
59
60
|
})
|
|
60
61
|
|
|
61
|
-
test('
|
|
62
|
+
test('render a date in a string when format is date as YYYY-MM-DD', (t) => {
|
|
62
63
|
t.plan(2)
|
|
63
64
|
|
|
64
65
|
const schema = {
|
|
@@ -66,23 +67,24 @@ test('verify padding for rendered date in a string when format is date', (t) =>
|
|
|
66
67
|
type: 'string',
|
|
67
68
|
format: 'date'
|
|
68
69
|
}
|
|
69
|
-
const toStringify = new Date(
|
|
70
|
+
const toStringify = new Date()
|
|
70
71
|
|
|
71
72
|
const validate = validator(schema)
|
|
72
73
|
const stringify = build(schema)
|
|
73
74
|
const output = stringify(toStringify)
|
|
74
75
|
|
|
75
|
-
t.equal(output, `"${
|
|
76
|
+
t.equal(output, `"${DateTime.fromJSDate(toStringify).toISODate()}"`)
|
|
76
77
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
77
78
|
})
|
|
78
79
|
|
|
79
|
-
test('render a date in a string when format is
|
|
80
|
-
t.plan(
|
|
80
|
+
test('render a nullable date in a string when format is date as YYYY-MM-DD', (t) => {
|
|
81
|
+
t.plan(2)
|
|
81
82
|
|
|
82
83
|
const schema = {
|
|
83
84
|
title: 'a date in a string',
|
|
84
85
|
type: 'string',
|
|
85
|
-
format: '
|
|
86
|
+
format: 'date',
|
|
87
|
+
nullable: true
|
|
86
88
|
}
|
|
87
89
|
const toStringify = new Date()
|
|
88
90
|
|
|
@@ -90,14 +92,29 @@ test('render a date in a string when format is time as kk:mm:ss', (t) => {
|
|
|
90
92
|
const stringify = build(schema)
|
|
91
93
|
const output = stringify(toStringify)
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
t.
|
|
95
|
+
t.equal(output, `"${DateTime.fromJSDate(toStringify).toISODate()}"`)
|
|
96
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
97
|
+
})
|
|
95
98
|
|
|
96
|
-
|
|
99
|
+
test('verify padding for rendered date in a string when format is date', (t) => {
|
|
100
|
+
t.plan(2)
|
|
101
|
+
|
|
102
|
+
const schema = {
|
|
103
|
+
title: 'a date in a string',
|
|
104
|
+
type: 'string',
|
|
105
|
+
format: 'date'
|
|
106
|
+
}
|
|
107
|
+
const toStringify = new Date(2020, 0, 1, 0, 0, 0, 0)
|
|
108
|
+
|
|
109
|
+
const validate = validator(schema)
|
|
110
|
+
const stringify = build(schema)
|
|
111
|
+
const output = stringify(toStringify)
|
|
112
|
+
|
|
113
|
+
t.equal(output, `"${DateTime.fromJSDate(toStringify).toISODate()}"`)
|
|
97
114
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
98
115
|
})
|
|
99
116
|
|
|
100
|
-
test('
|
|
117
|
+
test('render a date in a string when format is time as kk:mm:ss', (t) => {
|
|
101
118
|
t.plan(3)
|
|
102
119
|
|
|
103
120
|
const schema = {
|
|
@@ -105,7 +122,7 @@ test('verify padding for rendered date in a string when format is time', (t) =>
|
|
|
105
122
|
type: 'string',
|
|
106
123
|
format: 'time'
|
|
107
124
|
}
|
|
108
|
-
const toStringify = new Date(
|
|
125
|
+
const toStringify = new Date()
|
|
109
126
|
|
|
110
127
|
const validate = validator(schema)
|
|
111
128
|
const stringify = build(schema)
|
|
@@ -114,61 +131,71 @@ test('verify padding for rendered date in a string when format is time', (t) =>
|
|
|
114
131
|
validate(JSON.parse(output))
|
|
115
132
|
t.equal(validate.errors, null)
|
|
116
133
|
|
|
117
|
-
t.equal(output, `"${
|
|
134
|
+
t.equal(output, `"${DateTime.fromJSDate(toStringify).toFormat('HH:mm:ss')}"`)
|
|
118
135
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
119
136
|
})
|
|
120
137
|
|
|
121
|
-
test('render a
|
|
122
|
-
t.plan(
|
|
138
|
+
test('render a nullable date in a string when format is time as kk:mm:ss', (t) => {
|
|
139
|
+
t.plan(3)
|
|
123
140
|
|
|
124
141
|
const schema = {
|
|
125
|
-
title: 'a
|
|
142
|
+
title: 'a date in a string',
|
|
126
143
|
type: 'string',
|
|
127
|
-
format: '
|
|
144
|
+
format: 'time',
|
|
145
|
+
nullable: true
|
|
128
146
|
}
|
|
129
|
-
const toStringify =
|
|
147
|
+
const toStringify = new Date()
|
|
130
148
|
|
|
131
149
|
const validate = validator(schema)
|
|
132
150
|
const stringify = build(schema)
|
|
133
151
|
const output = stringify(toStringify)
|
|
134
152
|
|
|
135
|
-
|
|
153
|
+
validate(JSON.parse(output))
|
|
154
|
+
t.equal(validate.errors, null)
|
|
155
|
+
|
|
156
|
+
t.equal(output, `"${DateTime.fromJSDate(toStringify).toFormat('HH:mm:ss')}"`)
|
|
136
157
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
137
158
|
})
|
|
138
159
|
|
|
139
|
-
test('render a
|
|
140
|
-
t.plan(
|
|
160
|
+
test('render a midnight time', (t) => {
|
|
161
|
+
t.plan(3)
|
|
141
162
|
|
|
142
163
|
const schema = {
|
|
143
|
-
title: 'a
|
|
164
|
+
title: 'a date in a string',
|
|
144
165
|
type: 'string',
|
|
145
|
-
format: '
|
|
166
|
+
format: 'time'
|
|
146
167
|
}
|
|
147
|
-
const
|
|
168
|
+
const midnight = new Date(new Date().setHours(24))
|
|
148
169
|
|
|
149
170
|
const validate = validator(schema)
|
|
150
171
|
const stringify = build(schema)
|
|
151
|
-
const output = stringify(
|
|
172
|
+
const output = stringify(midnight)
|
|
152
173
|
|
|
153
|
-
|
|
174
|
+
validate(JSON.parse(output))
|
|
175
|
+
t.equal(validate.errors, null)
|
|
176
|
+
|
|
177
|
+
t.equal(output, `"${DateTime.fromJSDate(midnight).toFormat('HH:mm:ss')}"`)
|
|
154
178
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
155
179
|
})
|
|
156
180
|
|
|
157
|
-
test('
|
|
158
|
-
t.plan(
|
|
181
|
+
test('verify padding for rendered date in a string when format is time', (t) => {
|
|
182
|
+
t.plan(3)
|
|
159
183
|
|
|
160
184
|
const schema = {
|
|
161
|
-
title: 'a
|
|
185
|
+
title: 'a date in a string',
|
|
162
186
|
type: 'string',
|
|
163
187
|
format: 'time'
|
|
164
188
|
}
|
|
165
|
-
const toStringify =
|
|
189
|
+
const toStringify = new Date(2020, 0, 1, 1, 1, 1, 1)
|
|
166
190
|
|
|
167
191
|
const validate = validator(schema)
|
|
168
192
|
const stringify = build(schema)
|
|
169
193
|
const output = stringify(toStringify)
|
|
170
194
|
|
|
171
|
-
|
|
195
|
+
validate(JSON.parse(output))
|
|
196
|
+
t.equal(validate.errors, null)
|
|
197
|
+
|
|
198
|
+
t.equal(output, `"${DateTime.fromJSDate(toStringify).toFormat('HH:mm:ss')}"`)
|
|
172
199
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
173
200
|
})
|
|
174
201
|
|
|
@@ -185,7 +212,7 @@ test('render a nested object in a string when type is date-format as ISOString',
|
|
|
185
212
|
}
|
|
186
213
|
}
|
|
187
214
|
}
|
|
188
|
-
const toStringify = { date:
|
|
215
|
+
const toStringify = { date: new Date() }
|
|
189
216
|
|
|
190
217
|
const validate = validator(schema)
|
|
191
218
|
const stringify = build(schema)
|
package/test/debug-mode.test.js
CHANGED
|
@@ -98,5 +98,5 @@ test('to string auto-consistent with ajv-formats', t => {
|
|
|
98
98
|
const compiled = fjs.restore(debugMode)
|
|
99
99
|
const tobe = JSON.stringify({ str: 'foo@bar.com' })
|
|
100
100
|
t.same(compiled({ str: 'foo@bar.com' }), tobe)
|
|
101
|
-
t.
|
|
101
|
+
t.throws(() => compiled({ str: 'foo' }))
|
|
102
102
|
})
|
|
File without changes
|
|
@@ -261,13 +261,13 @@ t.test('if-then-else', t => {
|
|
|
261
261
|
const tests = [
|
|
262
262
|
{
|
|
263
263
|
name: 'foobar',
|
|
264
|
-
schema
|
|
264
|
+
schema,
|
|
265
265
|
input: fooBarInput,
|
|
266
266
|
expected: foobarOutput
|
|
267
267
|
},
|
|
268
268
|
{
|
|
269
269
|
name: 'greeting',
|
|
270
|
-
schema
|
|
270
|
+
schema,
|
|
271
271
|
input: greetingInput,
|
|
272
272
|
expected: greetingOutput
|
|
273
273
|
},
|
|
@@ -30,3 +30,34 @@ test('nested objects with same properties', (t) => {
|
|
|
30
30
|
})
|
|
31
31
|
t.equal(value, '{"stringProperty":"string1","objectProperty":{"stringProperty":"string2","numberProperty":42}}')
|
|
32
32
|
})
|
|
33
|
+
|
|
34
|
+
test('names collision', (t) => {
|
|
35
|
+
t.plan(1)
|
|
36
|
+
|
|
37
|
+
const schema = {
|
|
38
|
+
title: 'nested objects with same properties',
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
test: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
a: { type: 'string' }
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
tes: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
b: { type: 'string' },
|
|
51
|
+
t: { type: 'object' }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const stringify = build(schema)
|
|
57
|
+
const data = {
|
|
58
|
+
test: { a: 'a' },
|
|
59
|
+
tes: { b: 'b', t: {} }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
t.equal(stringify(data), JSON.stringify(data))
|
|
63
|
+
})
|