fast-json-stringify 2.7.2 → 2.7.6
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/ci.yml +2 -2
- package/README.md +2 -0
- package/index.js +60 -41
- package/package.json +1 -1
- package/test/anyof.test.js +47 -1
- package/test/date.test.js +1 -1
- package/test/integer.test.js +43 -0
package/.github/workflows/ci.yml
CHANGED
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
os: [macos-latest, ubuntu-latest, windows-latest]
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@v2
|
|
22
|
+
- uses: actions/checkout@v2.3.4
|
|
23
23
|
|
|
24
24
|
- name: Use Node.js
|
|
25
25
|
uses: actions/setup-node@v2.1.5
|
|
@@ -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.
|
|
41
|
+
- uses: fastify/github-action-merge-dependabot@v2.1.0
|
|
42
42
|
with:
|
|
43
43
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
package/README.md
CHANGED
|
@@ -139,6 +139,8 @@ And nested ones, too.
|
|
|
139
139
|
| `date` | `2020-04-03` |
|
|
140
140
|
| `time` | `09:11:08` |
|
|
141
141
|
|
|
142
|
+
**Note**: In the case of string formatted Date and not Date Object, there will be no manipulation on it. It should be properly formatted.
|
|
143
|
+
|
|
142
144
|
Example with a MomentJS object:
|
|
143
145
|
|
|
144
146
|
```javascript
|
package/index.js
CHANGED
|
@@ -20,8 +20,9 @@ try {
|
|
|
20
20
|
const addComma = `
|
|
21
21
|
if (addComma) {
|
|
22
22
|
json += ','
|
|
23
|
+
} else {
|
|
24
|
+
addComma = true
|
|
23
25
|
}
|
|
24
|
-
addComma = true
|
|
25
26
|
`
|
|
26
27
|
|
|
27
28
|
function isValidSchema (schema, name) {
|
|
@@ -253,9 +254,8 @@ function $asInteger (i) {
|
|
|
253
254
|
} else if (Number.isInteger(i)) {
|
|
254
255
|
return $asNumber(i)
|
|
255
256
|
} else {
|
|
256
|
-
// if the output is NaN the type is coerced to int 0
|
|
257
257
|
/* eslint no-undef: "off" */
|
|
258
|
-
return $asNumber(parseInteger(i)
|
|
258
|
+
return $asNumber(parseInteger(i))
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
|
|
@@ -291,7 +291,7 @@ function $asDatetime (date, skipQuotes) {
|
|
|
291
291
|
} else if (date && typeof date.toISOString === 'function') {
|
|
292
292
|
return quotes + date.toISOString() + quotes
|
|
293
293
|
} else {
|
|
294
|
-
return $asString(date)
|
|
294
|
+
return $asString(date, skipQuotes)
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
|
|
@@ -305,7 +305,7 @@ function $asDate (date, skipQuotes) {
|
|
|
305
305
|
} else if (date && typeof date.format === 'function') {
|
|
306
306
|
return quotes + date.format('YYYY-MM-DD') + quotes
|
|
307
307
|
} else {
|
|
308
|
-
return $asString(date)
|
|
308
|
+
return $asString(date, skipQuotes)
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
|
|
@@ -319,20 +319,26 @@ function $asTime (date, skipQuotes) {
|
|
|
319
319
|
} else if (date && typeof date.format === 'function') {
|
|
320
320
|
return quotes + date.format('HH:mm:ss') + quotes
|
|
321
321
|
} else {
|
|
322
|
-
return $asString(date)
|
|
322
|
+
return $asString(date, skipQuotes)
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
function $asString (str) {
|
|
326
|
+
function $asString (str, skipQuotes) {
|
|
327
|
+
const quotes = skipQuotes === true ? '' : '"'
|
|
327
328
|
if (str instanceof Date) {
|
|
328
|
-
return
|
|
329
|
+
return quotes + str.toISOString() + quotes
|
|
329
330
|
} else if (str === null) {
|
|
330
|
-
return
|
|
331
|
+
return quotes + quotes
|
|
331
332
|
} else if (str instanceof RegExp) {
|
|
332
333
|
str = str.source
|
|
333
334
|
} else if (typeof str !== 'string') {
|
|
334
335
|
str = str.toString()
|
|
335
336
|
}
|
|
337
|
+
// If we skipQuotes it means that we are using it as test
|
|
338
|
+
// no need to test the string length for the render
|
|
339
|
+
if (skipQuotes) {
|
|
340
|
+
return str
|
|
341
|
+
}
|
|
336
342
|
|
|
337
343
|
if (str.length < 42) {
|
|
338
344
|
return $asStringSmall(str)
|
|
@@ -745,7 +751,7 @@ function buildCode (location, code, laterCode, name) {
|
|
|
745
751
|
`
|
|
746
752
|
} else {
|
|
747
753
|
code += `
|
|
748
|
-
var t =
|
|
754
|
+
var t = $asInteger(obj[${sanitized}])
|
|
749
755
|
if (!isNaN(t)) {
|
|
750
756
|
${addComma}
|
|
751
757
|
json += ${asString} + ':' + t
|
|
@@ -1247,39 +1253,52 @@ function nested (laterCode, name, key, location, subKey, isArray) {
|
|
|
1247
1253
|
const nullIndex = type.indexOf('null')
|
|
1248
1254
|
const sortedTypes = nullIndex !== -1 ? [type[nullIndex]].concat(type.slice(0, nullIndex)).concat(type.slice(nullIndex + 1)) : type
|
|
1249
1255
|
sortedTypes.forEach((type, index) => {
|
|
1256
|
+
const statement = index === 0 ? 'if' : 'else if'
|
|
1250
1257
|
const tempSchema = Object.assign({}, schema, { type })
|
|
1251
1258
|
const nestedResult = nested(laterCode, name, key, mergeLocation(location, { schema: tempSchema }), subKey, isArray)
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1259
|
+
switch (type) {
|
|
1260
|
+
case 'string': {
|
|
1261
|
+
code += `
|
|
1262
|
+
${statement}(obj${accessor} === null || typeof obj${accessor} === "${type}" || obj${accessor} instanceof Date || typeof obj${accessor}.toISOString === "function" || obj${accessor} instanceof RegExp || (typeof obj${accessor} === "object" && Object.hasOwnProperty.call(obj${accessor}, "toString")))
|
|
1263
|
+
${nestedResult.code}
|
|
1264
|
+
`
|
|
1265
|
+
break
|
|
1266
|
+
}
|
|
1267
|
+
case 'null': {
|
|
1268
|
+
code += `
|
|
1269
|
+
${statement}(obj${accessor} == null)
|
|
1270
|
+
${nestedResult.code}
|
|
1271
|
+
`
|
|
1272
|
+
break
|
|
1273
|
+
}
|
|
1274
|
+
case 'array': {
|
|
1275
|
+
code += `
|
|
1276
|
+
${statement}(Array.isArray(obj${accessor}))
|
|
1277
|
+
${nestedResult.code}
|
|
1278
|
+
`
|
|
1279
|
+
break
|
|
1280
|
+
}
|
|
1281
|
+
case 'integer': {
|
|
1282
|
+
code += `
|
|
1283
|
+
${statement}(Number.isInteger(obj${accessor}) || obj${accessor} === null)
|
|
1284
|
+
${nestedResult.code}
|
|
1285
|
+
`
|
|
1286
|
+
break
|
|
1287
|
+
}
|
|
1288
|
+
case 'number': {
|
|
1289
|
+
code += `
|
|
1290
|
+
${statement}(isNaN(obj${accessor}) === false)
|
|
1291
|
+
${nestedResult.code}
|
|
1292
|
+
`
|
|
1293
|
+
break
|
|
1294
|
+
}
|
|
1295
|
+
default: {
|
|
1296
|
+
code += `
|
|
1297
|
+
${statement}(typeof obj${accessor} === "${type}")
|
|
1298
|
+
${nestedResult.code}
|
|
1299
|
+
`
|
|
1300
|
+
break
|
|
1301
|
+
}
|
|
1283
1302
|
}
|
|
1284
1303
|
laterCode = nestedResult.laterCode
|
|
1285
1304
|
})
|
package/package.json
CHANGED
package/test/anyof.test.js
CHANGED
|
@@ -448,7 +448,7 @@ test('anyOf with enum with more than 100 entries', (t) => {
|
|
|
448
448
|
t.equal(value, '["EUR","USD",null]')
|
|
449
449
|
})
|
|
450
450
|
|
|
451
|
-
test('anyOf object with field of type string with format or null', (t) => {
|
|
451
|
+
test('anyOf object with field date-time of type string with format or null', (t) => {
|
|
452
452
|
t.plan(1)
|
|
453
453
|
const toStringify = new Date()
|
|
454
454
|
const withOneOfSchema = {
|
|
@@ -471,3 +471,49 @@ test('anyOf object with field of type string with format or null', (t) => {
|
|
|
471
471
|
prop: toStringify
|
|
472
472
|
}), `{"prop":"${toStringify.toISOString()}"}`)
|
|
473
473
|
})
|
|
474
|
+
|
|
475
|
+
test('anyOf object with field date of type string with format or null', (t) => {
|
|
476
|
+
t.plan(1)
|
|
477
|
+
const toStringify = '2011-01-01'
|
|
478
|
+
const withOneOfSchema = {
|
|
479
|
+
type: 'object',
|
|
480
|
+
properties: {
|
|
481
|
+
prop: {
|
|
482
|
+
anyOf: [{
|
|
483
|
+
type: 'string',
|
|
484
|
+
format: 'date'
|
|
485
|
+
}, {
|
|
486
|
+
type: 'null'
|
|
487
|
+
}]
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const withOneOfStringify = build(withOneOfSchema)
|
|
493
|
+
t.equal(withOneOfStringify({
|
|
494
|
+
prop: toStringify
|
|
495
|
+
}), '{"prop":"2011-01-01"}')
|
|
496
|
+
})
|
|
497
|
+
|
|
498
|
+
test('anyOf object with invalid field date of type string with format or null', (t) => {
|
|
499
|
+
t.plan(1)
|
|
500
|
+
const toStringify = 'foo bar'
|
|
501
|
+
const withOneOfSchema = {
|
|
502
|
+
type: 'object',
|
|
503
|
+
properties: {
|
|
504
|
+
prop: {
|
|
505
|
+
anyOf: [{
|
|
506
|
+
type: 'string',
|
|
507
|
+
format: 'date'
|
|
508
|
+
}, {
|
|
509
|
+
type: 'null'
|
|
510
|
+
}]
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const withOneOfStringify = build(withOneOfSchema)
|
|
516
|
+
t.equal(withOneOfStringify({
|
|
517
|
+
prop: toStringify
|
|
518
|
+
}), '{"prop":null}')
|
|
519
|
+
})
|
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
|
|
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 = {
|
package/test/integer.test.js
CHANGED
|
@@ -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' },
|
|
@@ -137,3 +142,41 @@ if (semver.gt(process.versions.node, '10.3.0')) {
|
|
|
137
142
|
t.pass('Skip because Node version < 10.4')
|
|
138
143
|
t.end()
|
|
139
144
|
}
|
|
145
|
+
|
|
146
|
+
test('should round integer object parameter', t => {
|
|
147
|
+
t.plan(2)
|
|
148
|
+
|
|
149
|
+
const schema = { type: 'object', properties: { magic: { type: 'integer' } } }
|
|
150
|
+
const validate = validator(schema)
|
|
151
|
+
const stringify = build(schema, { rounding: 'ceil' })
|
|
152
|
+
const output = stringify({ magic: 4.2 })
|
|
153
|
+
|
|
154
|
+
t.equal(output, '{"magic":5}')
|
|
155
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
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
|
+
})
|