fast-json-stringify 2.7.10 → 3.0.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.
@@ -108,7 +108,7 @@ test('object with allOf and no schema on the allOf', (t) => {
108
108
  build(schema)
109
109
  t.fail()
110
110
  } catch (e) {
111
- t.equal(e.message, 'schema is invalid: data.allOf should NOT have fewer than 1 items')
111
+ t.equal(e.message, 'schema is invalid: data/allOf must NOT have fewer than 1 items')
112
112
  }
113
113
  })
114
114
 
@@ -277,6 +277,58 @@ test('object with multiple $refs in allOf', (t) => {
277
277
  t.equal(value, '{"id1":1,"id2":2}')
278
278
  })
279
279
 
280
+ test('allOf with nested allOf in $ref', (t) => {
281
+ t.plan(1)
282
+
283
+ const schema = {
284
+ title: 'allOf with nested allOf in $ref',
285
+ type: 'object',
286
+ definitions: {
287
+ group: {
288
+ type: 'object',
289
+ allOf: [{
290
+ properties: {
291
+ id2: {
292
+ type: 'integer'
293
+ }
294
+ }
295
+ }, {
296
+ properties: {
297
+ id3: {
298
+ type: 'integer'
299
+ }
300
+ }
301
+ }]
302
+ }
303
+ },
304
+ allOf: [
305
+ {
306
+ type: 'object',
307
+ properties: {
308
+ id1: {
309
+ type: 'integer'
310
+ }
311
+ },
312
+ required: [
313
+ 'id1'
314
+ ]
315
+ },
316
+ {
317
+ $ref: '#/definitions/group'
318
+ }
319
+ ]
320
+ }
321
+
322
+ const stringify = build(schema)
323
+ const value = stringify({
324
+ id1: 1,
325
+ id2: 2,
326
+ id3: 3,
327
+ id4: 4 // extra prop shouldn't be in result
328
+ })
329
+ t.equal(value, '{"id1":1,"id2":2,"id3":3}')
330
+ })
331
+
280
332
  test('object with external $refs in allOf', (t) => {
281
333
  t.plan(1)
282
334
 
@@ -0,0 +1,76 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const test = t.test
5
+ const build = require('..')
6
+
7
+ test('render a bigint as JSON', (t) => {
8
+ t.plan(1)
9
+
10
+ const schema = {
11
+ title: 'bigint',
12
+ type: 'integer'
13
+ }
14
+
15
+ const stringify = build(schema)
16
+ const output = stringify(1615n)
17
+
18
+ t.equal(output, '1615')
19
+ })
20
+
21
+ test('render an object with a bigint as JSON', (t) => {
22
+ t.plan(1)
23
+
24
+ const schema = {
25
+ title: 'object with bigint',
26
+ type: 'object',
27
+ properties: {
28
+ id: {
29
+ type: 'integer'
30
+ }
31
+ }
32
+ }
33
+
34
+ const stringify = build(schema)
35
+ const output = stringify({
36
+ id: 1615n
37
+ })
38
+
39
+ t.equal(output, '{"id":1615}')
40
+ })
41
+
42
+ test('render an array with a bigint as JSON', (t) => {
43
+ t.plan(1)
44
+
45
+ const schema = {
46
+ title: 'array with bigint',
47
+ type: 'array',
48
+ items: {
49
+ type: 'integer'
50
+ }
51
+ }
52
+
53
+ const stringify = build(schema)
54
+ const output = stringify([1615n])
55
+
56
+ t.equal(output, '[1615]')
57
+ })
58
+
59
+ test('render an object with an additionalProperty of type bigint as JSON', (t) => {
60
+ t.plan(1)
61
+
62
+ const schema = {
63
+ title: 'object with bigint',
64
+ type: 'object',
65
+ additionalProperties: {
66
+ type: 'integer'
67
+ }
68
+ }
69
+
70
+ const stringify = build(schema)
71
+ const output = stringify({
72
+ num: 1615n
73
+ })
74
+
75
+ t.equal(output, '{"num":1615}')
76
+ })
@@ -63,3 +63,29 @@ test('to string auto-consistent with ajv', t => {
63
63
  const tobe = JSON.stringify({ str: 'Foo' })
64
64
  t.same(compiled({ str: 'Foo', void: 'me' }), tobe)
65
65
  })
66
+
67
+ test('to string auto-consistent with ajv-formats', t => {
68
+ t.plan(3)
69
+ const debugMode = fjs({
70
+ title: 'object with multiple types field and format keyword',
71
+ type: 'object',
72
+ properties: {
73
+ str: {
74
+ anyOf: [{
75
+ type: 'string',
76
+ format: 'email'
77
+ }, {
78
+ type: 'boolean'
79
+ }]
80
+ }
81
+ }
82
+ }, { debugMode: 1 })
83
+ t.type(debugMode, Array)
84
+
85
+ const str = debugMode.toString()
86
+
87
+ const compiled = fjs.restore(str)
88
+ const tobe = JSON.stringify({ str: 'foo@bar.com' })
89
+ t.same(compiled({ str: 'foo@bar.com' }), tobe)
90
+ t.same(compiled({ str: 'foo' }), JSON.stringify({ str: null }), 'invalid format is ignored')
91
+ })
@@ -8,11 +8,13 @@ const schema = {
8
8
  properties: {
9
9
  },
10
10
  if: {
11
+ type: 'object',
11
12
  properties: {
12
13
  kind: { type: 'string', enum: ['foobar'] }
13
14
  }
14
15
  },
15
16
  then: {
17
+ type: 'object',
16
18
  properties: {
17
19
  kind: { type: 'string', enum: ['foobar'] },
18
20
  foo: { type: 'string' },
@@ -30,6 +32,7 @@ const schema = {
30
32
  }
31
33
  },
32
34
  else: {
35
+ type: 'object',
33
36
  properties: {
34
37
  kind: { type: 'string', enum: ['greeting'] },
35
38
  hi: { type: 'string' },
@@ -52,17 +55,20 @@ const nestedIfSchema = {
52
55
  type: 'object',
53
56
  properties: { },
54
57
  if: {
58
+ type: 'object',
55
59
  properties: {
56
60
  kind: { type: 'string', enum: ['foobar', 'greeting'] }
57
61
  }
58
62
  },
59
63
  then: {
60
64
  if: {
65
+ type: 'object',
61
66
  properties: {
62
67
  kind: { type: 'string', enum: ['foobar'] }
63
68
  }
64
69
  },
65
70
  then: {
71
+ type: 'object',
66
72
  properties: {
67
73
  kind: { type: 'string', enum: ['foobar'] },
68
74
  foo: { type: 'string' },
@@ -80,6 +86,7 @@ const nestedIfSchema = {
80
86
  }
81
87
  },
82
88
  else: {
89
+ type: 'object',
83
90
  properties: {
84
91
  kind: { type: 'string', enum: ['greeting'] },
85
92
  hi: { type: 'string' },
@@ -88,6 +95,7 @@ const nestedIfSchema = {
88
95
  }
89
96
  },
90
97
  else: {
98
+ type: 'object',
91
99
  properties: {
92
100
  kind: { type: 'string', enum: ['alphabet'] },
93
101
  a: { type: 'string' },
@@ -100,11 +108,13 @@ const nestedElseSchema = {
100
108
  type: 'object',
101
109
  properties: { },
102
110
  if: {
111
+ type: 'object',
103
112
  properties: {
104
113
  kind: { type: 'string', enum: ['foobar'] }
105
114
  }
106
115
  },
107
116
  then: {
117
+ type: 'object',
108
118
  properties: {
109
119
  kind: { type: 'string', enum: ['foobar'] },
110
120
  foo: { type: 'string' },
@@ -123,11 +133,13 @@ const nestedElseSchema = {
123
133
  },
124
134
  else: {
125
135
  if: {
136
+ type: 'object',
126
137
  properties: {
127
138
  kind: { type: 'string', enum: ['greeting'] }
128
139
  }
129
140
  },
130
141
  then: {
142
+ type: 'object',
131
143
  properties: {
132
144
  kind: { type: 'string', enum: ['greeting'] },
133
145
  hi: { type: 'string' },
@@ -135,6 +147,7 @@ const nestedElseSchema = {
135
147
  }
136
148
  },
137
149
  else: {
150
+ type: 'object',
138
151
  properties: {
139
152
  kind: { type: 'string', enum: ['alphabet'] },
140
153
  a: { type: 'string' },
@@ -154,11 +167,13 @@ const noElseSchema = {
154
167
  properties: {
155
168
  },
156
169
  if: {
170
+ type: 'object',
157
171
  properties: {
158
172
  kind: { type: 'string', enum: ['foobar'] }
159
173
  }
160
174
  },
161
175
  then: {
176
+ type: 'object',
162
177
  properties: {
163
178
  kind: { type: 'string', enum: ['foobar'] },
164
179
  foo: { type: 'string' },
@@ -310,7 +325,7 @@ t.test('if-then-else', t => {
310
325
  t.test(test.name + ' - normal', t => {
311
326
  t.plan(1)
312
327
 
313
- const stringify = build(JSON.parse(JSON.stringify(test.schema)))
328
+ const stringify = build(JSON.parse(JSON.stringify(test.schema)), { ajv: { strictTypes: false } })
314
329
  const serialized = stringify(test.input)
315
330
  t.equal(serialized, test.expected)
316
331
  })
@@ -2,10 +2,8 @@
2
2
 
3
3
  const t = require('tap')
4
4
  const test = t.test
5
- const semver = require('semver')
6
5
  const validator = require('is-my-json-valid')
7
- const proxyquire = require('proxyquire')
8
- const build = proxyquire('..', { long: null })
6
+ const build = require('..')
9
7
  const ROUNDING_TYPES = ['ceil', 'floor', 'round']
10
8
 
11
9
  test('render an integer as JSON', (t) => {
@@ -136,13 +134,6 @@ test('render an object with an additionalProperty of type integer as JSON', (t)
136
134
  t.ok(validate(JSON.parse(output)), 'valid schema')
137
135
  })
138
136
 
139
- if (semver.gt(process.versions.node, '10.3.0')) {
140
- require('./bigint')(t.test, build)
141
- } else {
142
- t.pass('Skip because Node version < 10.4')
143
- t.end()
144
- }
145
-
146
137
  test('should round integer object parameter', t => {
147
138
  t.plan(2)
148
139
 
@@ -97,16 +97,21 @@ const testSet = {
97
97
  items: {}
98
98
  }, null, null],
99
99
  nullableObject: [{ type: 'object', nullable: true }, null, null],
100
- complexObject: [complexObject, complexData, complexExpectedResult]
100
+ complexObject: [complexObject, complexData, complexExpectedResult, { ajv: { allowUnionTypes: true } }]
101
101
  }
102
102
 
103
103
  Object.keys(testSet).forEach(key => {
104
104
  test(`handle nullable:true in ${key} correctly`, (t) => {
105
105
  t.plan(1)
106
106
 
107
- const stringifier = build(testSet[key][0])
108
- const data = testSet[key][1]
109
- const expected = testSet[key][2]
107
+ const [
108
+ schema,
109
+ data,
110
+ expected,
111
+ extraOptions
112
+ ] = testSet[key]
113
+
114
+ const stringifier = build(schema, extraOptions)
110
115
  const result = stringifier(data)
111
116
  t.same(JSON.parse(result), expected)
112
117
  })
@@ -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
+ })
@@ -155,3 +155,42 @@ test('must not mutate items $ref', t => {
155
155
  t.equal(value, '[{"name":"foo"}]')
156
156
  t.same(schema, clonedSchema)
157
157
  })
158
+
159
+ test('must not mutate items referred by $ref', t => {
160
+ t.plan(2)
161
+
162
+ const firstSchema = {
163
+ $id: 'example1',
164
+ type: 'object',
165
+ properties: {
166
+ name: {
167
+ type: 'string'
168
+ }
169
+ }
170
+ }
171
+
172
+ const reusedSchema = {
173
+ $id: 'example2',
174
+ type: 'object',
175
+ properties: {
176
+ name: {
177
+ oneOf: [
178
+ {
179
+ $ref: 'example1'
180
+ }
181
+ ]
182
+ }
183
+ }
184
+ }
185
+
186
+ const clonedSchema = clone(firstSchema)
187
+ const stringify = build(reusedSchema, {
188
+ schema: {
189
+ [firstSchema.$id]: firstSchema
190
+ }
191
+ })
192
+
193
+ const value = stringify({ name: { name: 'foo' } })
194
+ t.equal(value, '{"name":{"name":"foo"}}')
195
+ t.same(firstSchema, clonedSchema)
196
+ })
@@ -3,7 +3,9 @@
3
3
  "esModuleInterop": true,
4
4
  "noEmit": true,
5
5
  "rootDir": "../..",
6
- "strict": true
6
+ "strict": true,
7
+ "target": "ES2015",
8
+ "moduleResolution": "node"
7
9
  },
8
10
  "include": [
9
11
  "./test.ts"
@@ -17,7 +17,7 @@ test('possibly nullable integer primitive alternative', (t) => {
17
17
  }
18
18
  }
19
19
 
20
- const stringify = build(schema)
20
+ const stringify = build(schema, { ajv: { allowUnionTypes: true } })
21
21
 
22
22
  const value = stringify({
23
23
  data: 4
@@ -328,7 +328,7 @@ test('object with anyOf and multiple types', (t) => {
328
328
  }
329
329
  }
330
330
  }
331
- const stringify = build(schema)
331
+ const stringify = build(schema, { ajv: { allowUnionTypes: true } })
332
332
 
333
333
  try {
334
334
  const value = stringify({
package/test/bigint.js DELETED
@@ -1,74 +0,0 @@
1
- 'use strict'
2
-
3
- module.exports = function (test, build) {
4
- test('render a bigint as JSON', (t) => {
5
- t.plan(1)
6
-
7
- const schema = {
8
- title: 'bigint',
9
- type: 'integer'
10
- }
11
-
12
- const stringify = build(schema)
13
- const output = stringify(1615n)
14
-
15
- t.equal(output, '1615')
16
- })
17
-
18
- test('render an object with a bigint as JSON', (t) => {
19
- t.plan(1)
20
-
21
- const schema = {
22
- title: 'object with bigint',
23
- type: 'object',
24
- properties: {
25
- id: {
26
- type: 'integer'
27
- }
28
- }
29
- }
30
-
31
- const stringify = build(schema)
32
- const output = stringify({
33
- id: 1615n
34
- })
35
-
36
- t.equal(output, '{"id":1615}')
37
- })
38
-
39
- test('render an array with a bigint as JSON', (t) => {
40
- t.plan(1)
41
-
42
- const schema = {
43
- title: 'array with bigint',
44
- type: 'array',
45
- items: {
46
- type: 'integer'
47
- }
48
- }
49
-
50
- const stringify = build(schema)
51
- const output = stringify([1615n])
52
-
53
- t.equal(output, '[1615]')
54
- })
55
-
56
- test('render an object with an additionalProperty of type bigint as JSON', (t) => {
57
- t.plan(1)
58
-
59
- const schema = {
60
- title: 'object with bigint',
61
- type: 'object',
62
- additionalProperties: {
63
- type: 'integer'
64
- }
65
- }
66
-
67
- const stringify = build(schema)
68
- const output = stringify({
69
- num: 1615n
70
- })
71
-
72
- t.equal(output, '{"num":1615}')
73
- })
74
- }