fast-json-stringify 2.7.6 → 2.7.10

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.1.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
@@ -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 `v12.16.2`
15
+ - Node.js `v16.9.1`
16
16
 
17
17
  ```
18
- FJS creation x 59,805 ops/sec ±0.23% (91 runs sampled)
18
+ FJS creation x 6,040 ops/sec ±1.17% (91 runs sampled)
19
19
 
20
- JSON.stringify array x 5,330 ops/sec ±0.54% (97 runs sampled)
21
- fast-json-stringify array x 6,995 ops/sec ±0.24% (94 runs sampled)
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 15,108 ops/sec ±0.13% (100 runs sampled)
24
- fast-json-stringify long string x 15,089 ops/sec ±0.15% (98 runs sampled)
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 13,214,696 ops/sec ±0.19% (97 runs sampled)
27
- fast-json-stringify short string x 33,378,500 ops/sec ±0.27% (95 runs sampled)
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,172,653 ops/sec ±0.15% (98 runs sampled)
30
- fast-json-stringify obj x 13,537,123 ops/sec ±0.19% (95 runs sampled)
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:
@@ -342,7 +345,7 @@ const stringify = fastJson({
342
345
  savedId: { type: 'string' }
343
346
  },
344
347
  // without "required" validation any object will match
345
- required: ['saveId']
348
+ required: ['savedId']
346
349
  },
347
350
  {
348
351
  type: 'object',
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
@@ -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]
@@ -298,10 +285,7 @@ function $asDatetime (date, skipQuotes) {
298
285
  function $asDate (date, skipQuotes) {
299
286
  const quotes = skipQuotes === true ? '' : '"'
300
287
  if (date instanceof Date) {
301
- const year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date)
302
- const month = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(date)
303
- const day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date)
304
- return quotes + year + '-' + month + '-' + day + quotes
288
+ return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )).toISOString().slice(0, 10) + quotes
305
289
  } else if (date && typeof date.format === 'function') {
306
290
  return quotes + date.format('YYYY-MM-DD') + quotes
307
291
  } else {
@@ -372,7 +356,7 @@ function $asStringSmall (str) {
372
356
  surrogateFound = true
373
357
  }
374
358
  if (point === 34 || point === 92) {
375
- result += str.slice(last, i) + '\\'
359
+ result += str.slice(last, i) + '\\\\'
376
360
  last = i
377
361
  found = true
378
362
  }
@@ -385,6 +369,7 @@ function $asStringSmall (str) {
385
369
  }
386
370
  return ((point < 32) || (surrogateFound === true)) ? JSON.stringify(str) : '"' + result + '"'
387
371
  }
372
+ `
388
373
 
389
374
  function addPatternProperties (location) {
390
375
  const schema = location.schema
@@ -928,7 +913,7 @@ function buildObject (location, code, name) {
928
913
  if (schema.nullable) {
929
914
  code += `
930
915
  if(input === null) {
931
- return '${$asNull()}';
916
+ return 'null';
932
917
  }
933
918
  `
934
919
  }
@@ -967,13 +952,10 @@ function buildArray (location, code, name, key = null) {
967
952
  if (schema.nullable) {
968
953
  code += `
969
954
  if(obj === null) {
970
- return '${$asNull()}';
955
+ return 'null';
971
956
  }
972
957
  `
973
958
  }
974
- code += `
975
- var json = '['
976
- `
977
959
  const laterCode = ''
978
960
 
979
961
  // default to any items type
@@ -1035,15 +1017,17 @@ function buildArray (location, code, name, key = null) {
1035
1017
 
1036
1018
  code += `
1037
1019
  var l = obj.length
1038
- var w = l - 1
1020
+ var jsonOutput= ''
1039
1021
  for (var i = 0; i < l; i++) {
1040
- if (i > 0) {
1041
- json += ','
1042
- }
1022
+ var json = ''
1043
1023
  ${result.code}
1024
+ jsonOutput += json
1025
+
1026
+ if (json.length > 0 && i < l - 1) {
1027
+ jsonOutput += ','
1028
+ }
1044
1029
  }
1045
- json += ']'
1046
- return json
1030
+ return \`[\${jsonOutput}]\`
1047
1031
  }
1048
1032
  ${result.laterCode}
1049
1033
  `
@@ -1226,9 +1210,12 @@ function nested (laterCode, name, key, location, subKey, isArray) {
1226
1210
  `
1227
1211
  laterCode = nestedResult.laterCode
1228
1212
  })
1229
- code += `
1230
- else json+= null
1231
- `
1213
+
1214
+ if (!isArray) {
1215
+ code += `
1216
+ else json+= null
1217
+ `
1218
+ }
1232
1219
  } else if (isEmpty(schema)) {
1233
1220
  code += `
1234
1221
  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.6",
3
+ "version": "2.7.10",
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",
@@ -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
+ })