fast-json-stringify 4.0.0 → 5.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fast-json-stringify",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Stringify your JSON at max speed",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "benchmark": "^2.1.4",
38
38
  "chalk": "^4.1.2",
39
39
  "compile-json-stringify": "^0.1.2",
40
- "inquirer": "^8.2.4",
40
+ "inquirer": "^9.0.0",
41
41
  "is-my-json-valid": "^2.20.0",
42
42
  "luxon": "^2.4.0",
43
43
  "pre-commit": "^1.2.2",
@@ -53,12 +53,8 @@
53
53
  "ajv": "^8.10.0",
54
54
  "ajv-formats": "^2.1.1",
55
55
  "deepmerge": "^4.2.2",
56
- "fast-uri": "^2.0.0",
57
- "rfdc": "^1.2.0",
58
- "string-similarity": "^4.0.1"
59
- },
60
- "engines": {
61
- "node": ">= 10.0.0"
56
+ "fast-uri": "^2.1.0",
57
+ "rfdc": "^1.2.0"
62
58
  },
63
59
  "standard": {
64
60
  "ignore": [
package/serializer.js ADDED
@@ -0,0 +1,163 @@
1
+ 'use strict'
2
+
3
+ module.exports = class Serializer {
4
+ constructor (options = {}) {
5
+ switch (options.rounding) {
6
+ case 'floor':
7
+ this.parseInteger = Math.floor
8
+ break
9
+ case 'ceil':
10
+ this.parseInteger = Math.ceil
11
+ break
12
+ case 'round':
13
+ this.parseInteger = Math.round
14
+ break
15
+ default:
16
+ this.parseInteger = Math.trunc
17
+ break
18
+ }
19
+ }
20
+
21
+ asAny (i) {
22
+ return JSON.stringify(i)
23
+ }
24
+
25
+ asNull () {
26
+ return 'null'
27
+ }
28
+
29
+ asInteger (i) {
30
+ if (typeof i === 'bigint') {
31
+ return i.toString()
32
+ } else if (Number.isInteger(i)) {
33
+ return '' + i
34
+ } else {
35
+ /* eslint no-undef: "off" */
36
+ const integer = this.parseInteger(i)
37
+ if (Number.isNaN(integer)) {
38
+ throw new Error(`The value "${i}" cannot be converted to an integer.`)
39
+ } else {
40
+ return '' + integer
41
+ }
42
+ }
43
+ }
44
+
45
+ asIntegerNullable (i) {
46
+ return i === null ? 'null' : this.asInteger(i)
47
+ }
48
+
49
+ asNumber (i) {
50
+ const num = Number(i)
51
+ if (Number.isNaN(num)) {
52
+ throw new Error(`The value "${i}" cannot be converted to a number.`)
53
+ } else {
54
+ return '' + num
55
+ }
56
+ }
57
+
58
+ asNumberNullable (i) {
59
+ return i === null ? 'null' : this.asNumber(i)
60
+ }
61
+
62
+ asBoolean (bool) {
63
+ return bool && 'true' || 'false' // eslint-disable-line
64
+ }
65
+
66
+ asBooleanNullable (bool) {
67
+ return bool === null ? 'null' : this.asBoolean(bool)
68
+ }
69
+
70
+ asDatetime (date) {
71
+ const quotes = '"'
72
+ if (date instanceof Date) {
73
+ return quotes + date.toISOString() + quotes
74
+ }
75
+ return this.asString(date)
76
+ }
77
+
78
+ asDatetimeNullable (date) {
79
+ return date === null ? 'null' : this.asDatetime(date)
80
+ }
81
+
82
+ asDate (date) {
83
+ const quotes = '"'
84
+ if (date instanceof Date) {
85
+ return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) + quotes
86
+ }
87
+ return this.asString(date)
88
+ }
89
+
90
+ asDateNullable (date) {
91
+ return date === null ? 'null' : this.asDate(date)
92
+ }
93
+
94
+ asTime (date) {
95
+ const quotes = '"'
96
+ if (date instanceof Date) {
97
+ return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(11, 19) + quotes
98
+ }
99
+ return this.asString(date)
100
+ }
101
+
102
+ asTimeNullable (date) {
103
+ return date === null ? 'null' : this.asTime(date)
104
+ }
105
+
106
+ asString (str) {
107
+ const quotes = '"'
108
+ if (str instanceof Date) {
109
+ return quotes + str.toISOString() + quotes
110
+ } else if (str === null) {
111
+ return quotes + quotes
112
+ } else if (str instanceof RegExp) {
113
+ str = str.source
114
+ } else if (typeof str !== 'string') {
115
+ str = str.toString()
116
+ }
117
+
118
+ if (str.length < 42) {
119
+ return this.asStringSmall(str)
120
+ } else {
121
+ return JSON.stringify(str)
122
+ }
123
+ }
124
+
125
+ asStringNullable (str) {
126
+ return str === null ? 'null' : this.asString(str)
127
+ }
128
+
129
+ // magically escape strings for json
130
+ // relying on their charCodeAt
131
+ // everything below 32 needs JSON.stringify()
132
+ // every string that contain surrogate needs JSON.stringify()
133
+ // 34 and 92 happens all the time, so we
134
+ // have a fast case for them
135
+ asStringSmall (str) {
136
+ const l = str.length
137
+ let result = ''
138
+ let last = 0
139
+ let found = false
140
+ let surrogateFound = false
141
+ let point = 255
142
+ // eslint-disable-next-line
143
+ for (var i = 0; i < l && point >= 32; i++) {
144
+ point = str.charCodeAt(i)
145
+ if (point >= 0xD800 && point <= 0xDFFF) {
146
+ // The current character is a surrogate.
147
+ surrogateFound = true
148
+ }
149
+ if (point === 34 || point === 92) {
150
+ result += str.slice(last, i) + '\\'
151
+ last = i
152
+ found = true
153
+ }
154
+ }
155
+
156
+ if (!found) {
157
+ result = str
158
+ } else {
159
+ result += str.slice(last)
160
+ }
161
+ return ((point < 32) || (surrogateFound === true)) ? JSON.stringify(str) : '"' + result + '"'
162
+ }
163
+ }
package/standalone.js ADDED
@@ -0,0 +1,42 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+
4
+ function buildStandaloneCode (options, ajvInstance, contextFunctionCode) {
5
+ const serializerCode = fs.readFileSync(path.join(__dirname, 'serializer.js')).toString()
6
+ let buildAjvCode = ''
7
+ let defaultAjvSchema = ''
8
+ const defaultMeta = ajvInstance.defaultMeta()
9
+ if (typeof defaultMeta === 'string') {
10
+ defaultAjvSchema = defaultMeta
11
+ } else {
12
+ defaultAjvSchema = defaultMeta.$id || defaultMeta.id
13
+ }
14
+ const shouldUseAjv = contextFunctionCode.indexOf('ajv') !== -1
15
+ // we need to export the custom json schema
16
+ let ajvSchemasCode = ''
17
+ if (shouldUseAjv) {
18
+ ajvSchemasCode += `const ajv = buildAjv(${JSON.stringify(options.ajv || {})})\n`
19
+ for (const [id, schema] of Object.entries(ajvInstance.schemas)) {
20
+ // should skip ajv default schema
21
+ if (id === defaultAjvSchema) continue
22
+ ajvSchemasCode += `ajv.addSchema(${JSON.stringify(schema.schema)}, "${id}")\n`
23
+ }
24
+ buildAjvCode = fs.readFileSync(path.join(__dirname, 'ajv.js')).toString()
25
+ buildAjvCode = buildAjvCode.replace("'use strict'", '').replace('module.exports = buildAjv', '')
26
+ }
27
+ return `
28
+ 'use strict'
29
+
30
+ ${serializerCode.replace("'use strict'", '').replace('module.exports = ', '')}
31
+ ${buildAjvCode}
32
+
33
+ const serializer = new Serializer(${JSON.stringify(options || {})})
34
+ ${ajvSchemasCode}
35
+
36
+ ${contextFunctionCode.replace('return main', '')}
37
+
38
+ module.exports = main
39
+ `
40
+ }
41
+
42
+ module.exports = buildStandaloneCode
@@ -402,12 +402,14 @@ test('object with external $refs in allOf', (t) => {
402
402
  }
403
403
  },
404
404
  second: {
405
- id2: {
406
- $id: '#id2',
407
- type: 'object',
408
- properties: {
409
- id2: {
410
- type: 'integer'
405
+ definitions: {
406
+ id2: {
407
+ $id: '#id2',
408
+ type: 'object',
409
+ properties: {
410
+ id2: {
411
+ type: 'integer'
412
+ }
411
413
  }
412
414
  }
413
415
  }
@@ -422,7 +424,7 @@ test('object with external $refs in allOf', (t) => {
422
424
  $ref: 'first#/definitions/id1'
423
425
  },
424
426
  {
425
- $ref: 'second#id2'
427
+ $ref: 'second#/definitions/id2'
426
428
  }
427
429
  ]
428
430
  }
@@ -218,6 +218,35 @@ test('array items is a list of schema and additionalItems is true, just the desc
218
218
  t.equal(result, '{"foo":["foo","bar",1]}')
219
219
  })
220
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
+
221
250
  test('array items is a list of schema and additionalItems is false', (t) => {
222
251
  t.plan(1)
223
252
 
File without changes