fast-json-stringify 2.7.5 → 2.7.9

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.
@@ -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.1.5
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.0.0
41
+ - uses: fastify/github-action-merge-dependabot@v2.4.0
42
42
  with:
43
43
  github-token: ${{ secrets.GITHUB_TOKEN }}
package/README.md CHANGED
@@ -342,7 +342,7 @@ const stringify = fastJson({
342
342
  savedId: { type: 'string' }
343
343
  },
344
344
  // without "required" validation any object will match
345
- required: ['saveId']
345
+ required: ['savedId']
346
346
  },
347
347
  {
348
348
  type: 'object',
package/index.d.ts CHANGED
@@ -64,6 +64,7 @@ declare namespace build {
64
64
 
65
65
  export interface StringSchema extends BaseSchema {
66
66
  type: "string";
67
+ format?: string;
67
68
  }
68
69
 
69
70
  export interface IntegerSchema extends BaseSchema {
package/index.js CHANGED
@@ -72,21 +72,7 @@ function build (schema, options) {
72
72
  `
73
73
 
74
74
  code += `
75
- ${$pad2Zeros.toString()}
76
- ${$asAny.toString()}
77
- ${$asString.toString()}
78
- ${$asStringNullable.toString()}
79
- ${$asStringSmall.toString()}
80
- ${$asDatetime.toString()}
81
- ${$asDate.toString()}
82
- ${$asTime.toString()}
83
- ${$asNumber.toString()}
84
- ${$asNumberNullable.toString()}
85
- ${$asInteger.toString()}
86
- ${$asIntegerNullable.toString()}
87
- ${$asNull.toString()}
88
- ${$asBoolean.toString()}
89
- ${$asBooleanNullable.toString()}
75
+ ${asFunctions}
90
76
 
91
77
  var isLong = ${isLong ? isLong.toString() : false}
92
78
 
@@ -116,19 +102,19 @@ function build (schema, options) {
116
102
  code = buildObject(location, code, main)
117
103
  break
118
104
  case 'string':
119
- main = schema.nullable ? $asStringNullable.name : getStringSerializer(schema.format)
105
+ main = schema.nullable ? '$asStringNullable' : getStringSerializer(schema.format)
120
106
  break
121
107
  case 'integer':
122
- main = schema.nullable ? $asIntegerNullable.name : $asInteger.name
108
+ main = schema.nullable ? '$asIntegerNullable' : '$asInteger'
123
109
  break
124
110
  case 'number':
125
- main = schema.nullable ? $asNumberNullable.name : $asNumber.name
111
+ main = schema.nullable ? '$asNumberNullable' : '$asNumber'
126
112
  break
127
113
  case 'boolean':
128
- main = schema.nullable ? $asBooleanNullable.name : $asBoolean.name
114
+ main = schema.nullable ? '$asBooleanNullable' : '$asBoolean'
129
115
  break
130
116
  case 'null':
131
- main = $asNull.name
117
+ main = '$asNull'
132
118
  break
133
119
  case 'array':
134
120
  main = '$main'
@@ -233,6 +219,7 @@ function getTestSerializer (format) {
233
219
  return stringSerializerMap[format]
234
220
  }
235
221
 
222
+ const asFunctions = `
236
223
  function $pad2Zeros (num) {
237
224
  const s = '00' + num
238
225
  return s[s.length - 2] + s[s.length - 1]
@@ -254,9 +241,8 @@ function $asInteger (i) {
254
241
  } else if (Number.isInteger(i)) {
255
242
  return $asNumber(i)
256
243
  } else {
257
- // if the output is NaN the type is coerced to int 0
258
244
  /* eslint no-undef: "off" */
259
- return $asNumber(parseInteger(i) || 0)
245
+ return $asNumber(parseInteger(i))
260
246
  }
261
247
  }
262
248
 
@@ -373,7 +359,7 @@ function $asStringSmall (str) {
373
359
  surrogateFound = true
374
360
  }
375
361
  if (point === 34 || point === 92) {
376
- result += str.slice(last, i) + '\\'
362
+ result += str.slice(last, i) + '\\\\'
377
363
  last = i
378
364
  found = true
379
365
  }
@@ -386,6 +372,7 @@ function $asStringSmall (str) {
386
372
  }
387
373
  return ((point < 32) || (surrogateFound === true)) ? JSON.stringify(str) : '"' + result + '"'
388
374
  }
375
+ `
389
376
 
390
377
  function addPatternProperties (location) {
391
378
  const schema = location.schema
@@ -929,7 +916,7 @@ function buildObject (location, code, name) {
929
916
  if (schema.nullable) {
930
917
  code += `
931
918
  if(input === null) {
932
- return '${$asNull()}';
919
+ return 'null';
933
920
  }
934
921
  `
935
922
  }
@@ -968,7 +955,7 @@ function buildArray (location, code, name, key = null) {
968
955
  if (schema.nullable) {
969
956
  code += `
970
957
  if(obj === null) {
971
- return '${$asNull()}';
958
+ return 'null';
972
959
  }
973
960
  `
974
961
  }
@@ -1036,9 +1023,11 @@ function buildArray (location, code, name, key = null) {
1036
1023
 
1037
1024
  code += `
1038
1025
  var l = obj.length
1039
- var w = l - 1
1026
+
1040
1027
  for (var i = 0; i < l; i++) {
1041
- if (i > 0) {
1028
+ var jsonLastChar = json[json.length - 1]
1029
+
1030
+ if (i > 0 && jsonLastChar !== '[' && jsonLastChar !== ',') {
1042
1031
  json += ','
1043
1032
  }
1044
1033
  ${result.code}
@@ -1227,9 +1216,12 @@ function nested (laterCode, name, key, location, subKey, isArray) {
1227
1216
  `
1228
1217
  laterCode = nestedResult.laterCode
1229
1218
  })
1230
- code += `
1231
- else json+= null
1232
- `
1219
+
1220
+ if (!isArray) {
1221
+ code += `
1222
+ else json+= null
1223
+ `
1224
+ }
1233
1225
  } else if (isEmpty(schema)) {
1234
1226
  code += `
1235
1227
  json += JSON.stringify(obj${accessor})
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fast-json-stringify",
3
- "version": "2.7.5",
3
+ "version": "2.7.9",
4
4
  "description": "Stringify your JSON at max speed",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -41,7 +41,8 @@
41
41
  "semver": "^7.1.0",
42
42
  "standard": "^16.0.1",
43
43
  "tap": "^15.0.0",
44
- "typescript": "^4.0.2"
44
+ "typescript": "^4.0.2",
45
+ "webpack": "^5.40.0"
45
46
  },
46
47
  "dependencies": {
47
48
  "ajv": "^6.11.0",
package/test/date.test.js CHANGED
@@ -76,7 +76,7 @@ test('verify padding for rendered date in a string when format is date', (t) =>
76
76
  t.ok(validate(JSON.parse(output)), 'valid schema')
77
77
  })
78
78
 
79
- test('render a date in a string when format is time as HH:mm:ss', (t) => {
79
+ test('render a date in a string when format is time as kk:mm:ss', (t) => {
80
80
  t.plan(3)
81
81
 
82
82
  const schema = {
@@ -6,6 +6,7 @@ const semver = require('semver')
6
6
  const validator = require('is-my-json-valid')
7
7
  const proxyquire = require('proxyquire')
8
8
  const build = proxyquire('..', { long: null })
9
+ const ROUNDING_TYPES = ['ceil', 'floor', 'round']
9
10
 
10
11
  test('render an integer as JSON', (t) => {
11
12
  t.plan(2)
@@ -40,6 +41,10 @@ test('render a float as an integer', (t) => {
40
41
  const cases = [
41
42
  { input: Math.PI, output: '3' },
42
43
  { input: 5.0, output: '5' },
44
+ { input: null, output: '0' },
45
+ { input: 0, output: '0' },
46
+ { input: 0.0, output: '0' },
47
+ { input: 42, output: '42' },
43
48
  { input: 1.99999, output: '1' },
44
49
  { input: -45.05, output: '-45' },
45
50
  { input: 0.95, output: '1', rounding: 'ceil' },
@@ -138,7 +143,7 @@ if (semver.gt(process.versions.node, '10.3.0')) {
138
143
  t.end()
139
144
  }
140
145
 
141
- test('should round interger object parameter ', t => {
146
+ test('should round integer object parameter', t => {
142
147
  t.plan(2)
143
148
 
144
149
  const schema = { type: 'object', properties: { magic: { type: 'integer' } } }
@@ -149,3 +154,29 @@ test('should round interger object parameter ', t => {
149
154
  t.equal(output, '{"magic":5}')
150
155
  t.ok(validate(JSON.parse(output)), 'valid schema')
151
156
  })
157
+
158
+ test('should not stringify a property if it does not exist', t => {
159
+ t.plan(2)
160
+
161
+ const schema = { title: 'Example Schema', type: 'object', properties: { age: { type: 'integer' } } }
162
+ const validate = validator(schema)
163
+ const stringify = build(schema)
164
+ const output = stringify({})
165
+
166
+ t.equal(output, '{}')
167
+ t.ok(validate(JSON.parse(output)), 'valid schema')
168
+ })
169
+
170
+ ROUNDING_TYPES.forEach((rounding) => {
171
+ test(`should not stringify a property if it does not exist (rounding: ${rounding})`, t => {
172
+ t.plan(2)
173
+
174
+ const schema = { type: 'object', properties: { magic: { type: 'integer' } } }
175
+ const validate = validator(schema)
176
+ const stringify = build(schema, { rounding })
177
+ const output = stringify({})
178
+
179
+ t.equal(output, '{}')
180
+ t.ok(validate(JSON.parse(output)), 'valid schema')
181
+ })
182
+ })
@@ -401,3 +401,105 @@ test('oneOf object with field of type string with format or null', (t) => {
401
401
  prop: toStringify
402
402
  }), `{"prop":"${toStringify.toISOString()}"}`)
403
403
  })
404
+
405
+ test('one array item match oneOf types', (t) => {
406
+ t.plan(1)
407
+
408
+ const schema = {
409
+ type: 'object',
410
+ additionalProperties: false,
411
+ required: ['data'],
412
+ properties: {
413
+ data: {
414
+ type: 'array',
415
+ minItems: 1,
416
+ items: {
417
+ oneOf: [
418
+ {
419
+ type: 'string'
420
+ },
421
+ {
422
+ type: 'number'
423
+ }
424
+ ]
425
+ }
426
+ }
427
+ }
428
+ }
429
+
430
+ const stringify = build(schema)
431
+
432
+ const responseWithMappedType = stringify({
433
+ data: [false, 'foo']
434
+ })
435
+
436
+ t.equal('{"data":["foo"]}', responseWithMappedType)
437
+ })
438
+
439
+ test('some array items match oneOf types', (t) => {
440
+ t.plan(1)
441
+
442
+ const schema = {
443
+ type: 'object',
444
+ additionalProperties: false,
445
+ required: ['data'],
446
+ properties: {
447
+ data: {
448
+ type: 'array',
449
+ minItems: 1,
450
+ items: {
451
+ oneOf: [
452
+ {
453
+ type: 'string'
454
+ },
455
+ {
456
+ type: 'number'
457
+ }
458
+ ]
459
+ }
460
+ }
461
+ }
462
+ }
463
+
464
+ const stringify = build(schema)
465
+
466
+ const responseWithMappedTypes = stringify({
467
+ data: [false, 'foo', true, 5]
468
+ })
469
+
470
+ t.equal('{"data":["foo",5]}', responseWithMappedTypes)
471
+ })
472
+
473
+ test('all array items does not match oneOf types', (t) => {
474
+ t.plan(1)
475
+
476
+ const schema = {
477
+ type: 'object',
478
+ additionalProperties: false,
479
+ required: ['data'],
480
+ properties: {
481
+ data: {
482
+ type: 'array',
483
+ minItems: 1,
484
+ items: {
485
+ oneOf: [
486
+ {
487
+ type: 'string'
488
+ },
489
+ {
490
+ type: 'number'
491
+ }
492
+ ]
493
+ }
494
+ }
495
+ }
496
+ }
497
+
498
+ const stringify = build(schema)
499
+
500
+ const emptyResponse = stringify({
501
+ data: [null, false, true, undefined, [], {}]
502
+ })
503
+
504
+ t.equal('{"data":[]}', emptyResponse)
505
+ })
@@ -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())
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ const test = require('tap').test
4
+ const webpack = require('webpack')
5
+ const path = require('path')
6
+
7
+ test('the library should work with webpack', async (t) => {
8
+ t.plan(1)
9
+ const targetdir = path.resolve(__dirname, '..', '.cache')
10
+ const targetname = path.join(targetdir, 'webpacktest.js')
11
+ const wopts = {
12
+ entry: path.resolve(__dirname, '..', 'index.js'),
13
+ mode: 'production',
14
+ target: 'node',
15
+ output: {
16
+ path: targetdir,
17
+ filename: 'webpacktest.js',
18
+ library: {
19
+ name: 'fastJsonStringify',
20
+ type: 'umd'
21
+ }
22
+ }
23
+ }
24
+ await new Promise((resolve, reject) => {
25
+ webpack(wopts, (err, stats) => {
26
+ if (err) { reject(err) } else { resolve(stats) };
27
+ })
28
+ })
29
+ const build = require(targetname)
30
+ const stringify = build({
31
+ title: 'webpack should not rename code to be executed',
32
+ type: 'object',
33
+ properties: {
34
+ foo: {
35
+ type: 'string'
36
+ },
37
+ bar: {
38
+ type: 'boolean'
39
+ }
40
+ },
41
+ patternProperties: {
42
+ foo: {
43
+ type: 'number'
44
+ }
45
+ }
46
+ })
47
+
48
+ const obj = { foo: '42', bar: true }
49
+ t.equal(stringify(obj), '{"foo":"42","bar":true}')
50
+ })