@zuplo/cli 6.71.23 → 6.71.25
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/node_modules/@fastify/fast-json-stringify-compiler/.github/dependabot.yml +42 -2
- package/node_modules/@fastify/fast-json-stringify-compiler/.github/workflows/ci.yml +6 -1
- package/node_modules/@fastify/fast-json-stringify-compiler/.github/workflows/lock-threads.yml +19 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/LICENSE +1 -1
- package/node_modules/@fastify/fast-json-stringify-compiler/README.md +1 -1
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.gitattributes +2 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.github/dependabot.yml +13 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.github/workflows/ci.yml +33 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.github/workflows/lock-threads.yml +19 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/LICENSE +22 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/README.md +742 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench-cmp-branch.js +116 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench-cmp-lib.js +339 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench-thread.js +33 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench.js +391 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/build/build-schema-validator.js +26 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/eslint.config.js +9 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/examples/example.js +81 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/examples/server.js +42 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/index.js +1308 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/location.js +24 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/merge-schemas.js +9 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/schema-validator.js +1134 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/serializer.js +141 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/standalone.js +34 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/validator.js +96 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/package.json +89 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/additionalProperties.test.js +332 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/allof.test.js +751 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/any.test.js +231 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/anyof.test.js +812 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/array.test.js +688 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/asNumber.test.js +13 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/basic.test.js +400 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/bigint.test.js +76 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/clean-cache.test.js +47 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/const.test.js +314 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/date.test.js +639 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/debug-mode.test.js +130 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/defaults.test.js +376 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/enum.test.js +37 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/fix-604.test.js +25 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/fixtures/.keep +0 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/if-then-else.test.js +540 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/inferType.test.js +92 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/infinity.test.js +55 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/integer.test.js +194 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/invalidSchema.test.js +38 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-479.test.js +57 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-793.test.js +107 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-794.test.js +177 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-836.test.js +183 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-add-comma.test.js +57 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/README.md +10 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft4/required.json +54 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft4.test.js +12 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft6/required.json +70 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft6.test.js +12 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft7/required.json +70 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft7.test.js +12 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/util.js +31 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/missing-values.test.js +88 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/multi-type-serializer.test.js +19 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/nestedObjects.test.js +63 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/nullable.test.js +543 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/oneof.test.js +510 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/patternProperties.test.js +168 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/recursion.test.js +245 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/ref.json +12 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/ref.test.js +2077 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/regex.test.js +32 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/required.test.js +204 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/requiresAjv.test.js +50 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize.test.js +141 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize2.test.js +18 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize3.test.js +17 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize4.test.js +16 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize5.test.js +16 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize6.test.js +22 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize7.test.js +68 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/side-effect.test.js +196 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/standalone-mode.test.js +219 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/string.test.js +84 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/surrogate.test.js +67 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/toJSON.test.js +203 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/typebox.test.js +36 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/typesArray.test.js +550 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/unknownFormats.test.js +27 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/webpack.test.js +50 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/types/index.d.ts +219 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/types/index.tst.ts +259 -0
- package/node_modules/@fastify/fast-json-stringify-compiler/package.json +6 -11
- package/node_modules/@fastify/fast-json-stringify-compiler/types/{index.test-d.ts → index.tst.ts} +34 -32
- package/node_modules/@protobufjs/utf8/CHANGELOG.md +8 -0
- package/node_modules/@protobufjs/utf8/index.js +29 -18
- package/node_modules/@protobufjs/utf8/package.json +2 -2
- package/node_modules/@protobufjs/utf8/tests/index.js +5 -0
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/{chunk-5CYWMN74.js → chunk-MJWTZPC2.js} +90 -90
- package/node_modules/@zuplo/runtime/out/esm/chunk-MJWTZPC2.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +154 -0
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -1
- package/node_modules/hono/dist/adapter/bun/websocket.js +3 -1
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +3 -1
- package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +1 -1
- package/node_modules/hono/dist/cjs/utils/body.js +12 -4
- package/node_modules/hono/dist/cjs/utils/buffer.js +2 -1
- package/node_modules/hono/dist/cjs/validator/validator.js +3 -3
- package/node_modules/hono/dist/middleware/serve-static/index.js +1 -1
- package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +2 -2
- package/node_modules/hono/dist/types/utils/body.d.ts +1 -1
- package/node_modules/hono/dist/utils/body.js +12 -4
- package/node_modules/hono/dist/utils/buffer.js +2 -1
- package/node_modules/hono/dist/validator/validator.js +3 -3
- package/node_modules/hono/package.json +8 -7
- package/package.json +6 -6
- package/node_modules/@fastify/fast-json-stringify-compiler/.eslintrc +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-5CYWMN74.js.map +0 -1
- package/node_modules/hono/dist/tsconfig.build.tsbuildinfo +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-5CYWMN74.js.LEGAL.txt → chunk-MJWTZPC2.js.LEGAL.txt} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line
|
|
4
|
+
const STR_ESCAPE = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/
|
|
5
|
+
|
|
6
|
+
module.exports = class Serializer {
|
|
7
|
+
constructor (options) {
|
|
8
|
+
switch (options && options.rounding) {
|
|
9
|
+
case 'floor':
|
|
10
|
+
this.parseInteger = Math.floor
|
|
11
|
+
break
|
|
12
|
+
case 'ceil':
|
|
13
|
+
this.parseInteger = Math.ceil
|
|
14
|
+
break
|
|
15
|
+
case 'round':
|
|
16
|
+
this.parseInteger = Math.round
|
|
17
|
+
break
|
|
18
|
+
case 'trunc':
|
|
19
|
+
default:
|
|
20
|
+
this.parseInteger = Math.trunc
|
|
21
|
+
break
|
|
22
|
+
}
|
|
23
|
+
this._options = options
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
asInteger (i) {
|
|
27
|
+
if (Number.isInteger(i)) {
|
|
28
|
+
return '' + i
|
|
29
|
+
} else if (typeof i === 'bigint') {
|
|
30
|
+
return i.toString()
|
|
31
|
+
}
|
|
32
|
+
/* eslint no-undef: "off" */
|
|
33
|
+
const integer = this.parseInteger(i)
|
|
34
|
+
// check if number is Infinity or NaN
|
|
35
|
+
// eslint-disable-next-line no-self-compare
|
|
36
|
+
if (integer === Infinity || integer === -Infinity || integer !== integer) {
|
|
37
|
+
throw new Error(`The value "${i}" cannot be converted to an integer.`)
|
|
38
|
+
}
|
|
39
|
+
return '' + integer
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
asNumber (i) {
|
|
43
|
+
// fast cast to number
|
|
44
|
+
const num = Number(i)
|
|
45
|
+
// check if number is NaN
|
|
46
|
+
// eslint-disable-next-line no-self-compare
|
|
47
|
+
if (num !== num) {
|
|
48
|
+
throw new Error(`The value "${i}" cannot be converted to a number.`)
|
|
49
|
+
} else if (num === Infinity || num === -Infinity) {
|
|
50
|
+
return 'null'
|
|
51
|
+
} else {
|
|
52
|
+
return '' + num
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
asBoolean (bool) {
|
|
57
|
+
return bool && 'true' || 'false' // eslint-disable-line
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
asDateTime (date) {
|
|
61
|
+
if (date === null) return '""'
|
|
62
|
+
if (date instanceof Date) {
|
|
63
|
+
return '"' + date.toISOString() + '"'
|
|
64
|
+
}
|
|
65
|
+
if (typeof date === 'string') {
|
|
66
|
+
return '"' + date + '"'
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`The value "${date}" cannot be converted to a date-time.`)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
asDate (date) {
|
|
72
|
+
if (date === null) return '""'
|
|
73
|
+
if (date instanceof Date) {
|
|
74
|
+
return '"' + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) + '"'
|
|
75
|
+
}
|
|
76
|
+
if (typeof date === 'string') {
|
|
77
|
+
return '"' + date + '"'
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`The value "${date}" cannot be converted to a date.`)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
asTime (date) {
|
|
83
|
+
if (date === null) return '""'
|
|
84
|
+
if (date instanceof Date) {
|
|
85
|
+
return '"' + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(11, 19) + '"'
|
|
86
|
+
}
|
|
87
|
+
if (typeof date === 'string') {
|
|
88
|
+
return '"' + date + '"'
|
|
89
|
+
}
|
|
90
|
+
throw new Error(`The value "${date}" cannot be converted to a time.`)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
asString (str) {
|
|
94
|
+
const len = str.length
|
|
95
|
+
if (len === 0) {
|
|
96
|
+
return '""'
|
|
97
|
+
} else if (len < 42) {
|
|
98
|
+
// magically escape strings for json
|
|
99
|
+
// relying on their charCodeAt
|
|
100
|
+
// everything below 32 needs JSON.stringify()
|
|
101
|
+
// every string that contain surrogate needs JSON.stringify()
|
|
102
|
+
// 34 and 92 happens all the time, so we
|
|
103
|
+
// have a fast case for them
|
|
104
|
+
let result = ''
|
|
105
|
+
let last = -1
|
|
106
|
+
let point = 255
|
|
107
|
+
for (let i = 0; i < len; i++) {
|
|
108
|
+
point = str.charCodeAt(i)
|
|
109
|
+
if (
|
|
110
|
+
point === 0x22 || // '"'
|
|
111
|
+
point === 0x5c // '\'
|
|
112
|
+
) {
|
|
113
|
+
last === -1 && (last = 0)
|
|
114
|
+
result += str.slice(last, i) + '\\'
|
|
115
|
+
last = i
|
|
116
|
+
} else if (point < 32 || (point >= 0xD800 && point <= 0xDFFF)) {
|
|
117
|
+
// The current character is non-printable characters or a surrogate.
|
|
118
|
+
return JSON.stringify(str)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return (last === -1 && ('"' + str + '"')) || ('"' + result + str.slice(last) + '"')
|
|
122
|
+
} else if (len < 5000 && STR_ESCAPE.test(str) === false) {
|
|
123
|
+
// Only use the regular expression for shorter input. The overhead is otherwise too much.
|
|
124
|
+
return '"' + str + '"'
|
|
125
|
+
} else {
|
|
126
|
+
return JSON.stringify(str)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
asUnsafeString (str) {
|
|
131
|
+
return '"' + str + '"'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
getState () {
|
|
135
|
+
return this._options
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static restoreFromState (state) {
|
|
139
|
+
return new Serializer(state)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
function buildStandaloneCode (contextFunc, context, serializer, validator) {
|
|
4
|
+
let ajvDependencyCode = ''
|
|
5
|
+
if (context.validatorSchemasIds.size > 0) {
|
|
6
|
+
ajvDependencyCode += 'const Validator = require(\'fast-json-stringify/lib/validator\')\n'
|
|
7
|
+
ajvDependencyCode += `const validatorState = ${JSON.stringify(validator.getState())}\n`
|
|
8
|
+
ajvDependencyCode += 'const validator = Validator.restoreFromState(validatorState)\n'
|
|
9
|
+
} else {
|
|
10
|
+
ajvDependencyCode += 'const validator = null\n'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Don't need to keep external schemas once compiled
|
|
14
|
+
// validatorState will hold external schemas if it needs them
|
|
15
|
+
const { schema, ...serializerState } = serializer.getState()
|
|
16
|
+
|
|
17
|
+
return `
|
|
18
|
+
'use strict'
|
|
19
|
+
|
|
20
|
+
const Serializer = require('fast-json-stringify/lib/serializer')
|
|
21
|
+
const serializerState = ${JSON.stringify(serializerState)}
|
|
22
|
+
const serializer = Serializer.restoreFromState(serializerState)
|
|
23
|
+
|
|
24
|
+
${ajvDependencyCode}
|
|
25
|
+
|
|
26
|
+
module.exports = ${contextFunc.toString()}(validator, serializer)`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = buildStandaloneCode
|
|
30
|
+
|
|
31
|
+
module.exports.dependencies = {
|
|
32
|
+
Serializer: require('./serializer'),
|
|
33
|
+
Validator: require('./validator')
|
|
34
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Ajv = require('ajv')
|
|
4
|
+
const fastUri = require('fast-uri')
|
|
5
|
+
const ajvFormats = require('ajv-formats')
|
|
6
|
+
const clone = require('rfdc')({ proto: true })
|
|
7
|
+
|
|
8
|
+
class Validator {
|
|
9
|
+
constructor (ajvOptions) {
|
|
10
|
+
this.ajv = new Ajv({
|
|
11
|
+
...ajvOptions,
|
|
12
|
+
strictSchema: false,
|
|
13
|
+
validateSchema: false,
|
|
14
|
+
allowUnionTypes: true,
|
|
15
|
+
uriResolver: fastUri
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
ajvFormats(this.ajv)
|
|
19
|
+
|
|
20
|
+
this.ajv.addKeyword({
|
|
21
|
+
keyword: 'fjs_type',
|
|
22
|
+
type: 'object',
|
|
23
|
+
errors: false,
|
|
24
|
+
validate: (_type, data) => {
|
|
25
|
+
return data && typeof data.toJSON === 'function'
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
this._ajvSchemas = {}
|
|
30
|
+
this._ajvOptions = ajvOptions || {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
addSchema (schema, schemaName) {
|
|
34
|
+
let schemaKey = schema.$id || schemaName
|
|
35
|
+
if (schema.$id !== undefined && schema.$id[0] === '#') {
|
|
36
|
+
schemaKey = schemaName + schema.$id // relative URI
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
this.ajv.refs[schemaKey] === undefined &&
|
|
41
|
+
this.ajv.schemas[schemaKey] === undefined
|
|
42
|
+
) {
|
|
43
|
+
const ajvSchema = clone(schema)
|
|
44
|
+
this.convertSchemaToAjvFormat(ajvSchema)
|
|
45
|
+
this.ajv.addSchema(ajvSchema, schemaKey)
|
|
46
|
+
this._ajvSchemas[schemaKey] = schema
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
validate (schemaRef, data) {
|
|
51
|
+
return this.ajv.validate(schemaRef, data)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Ajv does not natively support JavaScript objects like Date or other types
|
|
55
|
+
// that rely on a custom .toJSON() representation. To properly validate schemas
|
|
56
|
+
// that may contain such objects (e.g. Date, ObjectId, etc.), we replace all
|
|
57
|
+
// occurrences of the string type with a custom keyword fjs_type
|
|
58
|
+
// (see https://github.com/fastify/fast-json-stringify/pull/441)
|
|
59
|
+
convertSchemaToAjvFormat (schema) {
|
|
60
|
+
if (schema === null) return
|
|
61
|
+
|
|
62
|
+
if (schema.type === 'string') {
|
|
63
|
+
schema.fjs_type = 'string'
|
|
64
|
+
schema.type = ['string', 'object']
|
|
65
|
+
} else if (
|
|
66
|
+
Array.isArray(schema.type) &&
|
|
67
|
+
schema.type.includes('string') &&
|
|
68
|
+
!schema.type.includes('object')
|
|
69
|
+
) {
|
|
70
|
+
schema.fjs_type = 'string'
|
|
71
|
+
schema.type.push('object')
|
|
72
|
+
}
|
|
73
|
+
for (const property in schema) {
|
|
74
|
+
if (typeof schema[property] === 'object') {
|
|
75
|
+
this.convertSchemaToAjvFormat(schema[property])
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
getState () {
|
|
81
|
+
return {
|
|
82
|
+
ajvOptions: this._ajvOptions,
|
|
83
|
+
ajvSchemas: this._ajvSchemas
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static restoreFromState (state) {
|
|
88
|
+
const validator = new Validator(state.ajvOptions)
|
|
89
|
+
for (const [id, ajvSchema] of Object.entries(state.ajvSchemas)) {
|
|
90
|
+
validator.ajv.addSchema(ajvSchema, id)
|
|
91
|
+
}
|
|
92
|
+
return validator
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = Validator
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fast-json-stringify",
|
|
3
|
+
"version": "7.0.0",
|
|
4
|
+
"description": "Stringify your JSON at max speed",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"types": "types/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"bench": "node --expose-gc ./benchmark/bench.js",
|
|
10
|
+
"bench:cmp": "node ./benchmark/bench-cmp-branch.js",
|
|
11
|
+
"bench:cmp:ci": "node ./benchmark/bench-cmp-branch.js --ci",
|
|
12
|
+
"benchmark": "node --expose-gc ./benchmark/bench-cmp-lib.js",
|
|
13
|
+
"lint": "eslint",
|
|
14
|
+
"lint:fix": "eslint --fix",
|
|
15
|
+
"test:typescript": "tstyche",
|
|
16
|
+
"test:unit": "c8 node --test",
|
|
17
|
+
"test": "npm run test:unit && npm run test:typescript"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/fastify/fast-json-stringify.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"json",
|
|
25
|
+
"stringify",
|
|
26
|
+
"schema",
|
|
27
|
+
"fast"
|
|
28
|
+
],
|
|
29
|
+
"author": "Matteo Collina <hello@matteocollina.com>",
|
|
30
|
+
"contributors": [
|
|
31
|
+
{
|
|
32
|
+
"name": "Tomas Della Vedova",
|
|
33
|
+
"url": "http://delved.org"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "Aras Abbasi",
|
|
37
|
+
"email": "aras.abbasi@gmail.com"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "Manuel Spigolon",
|
|
41
|
+
"email": "behemoth89@gmail.com"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "Frazer Smith",
|
|
45
|
+
"email": "frazer.dev@icloud.com",
|
|
46
|
+
"url": "https://github.com/fdawgs"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/fastify/fast-json-stringify/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/fastify/fast-json-stringify#readme",
|
|
54
|
+
"funding": [
|
|
55
|
+
{
|
|
56
|
+
"type": "github",
|
|
57
|
+
"url": "https://github.com/sponsors/fastify"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "opencollective",
|
|
61
|
+
"url": "https://opencollective.com/fastify"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"c8": "^11.0.0",
|
|
66
|
+
"cli-select": "^1.1.2",
|
|
67
|
+
"compile-json-stringify": "^0.1.2",
|
|
68
|
+
"eslint": "^9.39.2",
|
|
69
|
+
"fast-json-stringify": ".",
|
|
70
|
+
"is-my-json-valid": "^2.20.6",
|
|
71
|
+
"json-accelerator": "^0.1.7",
|
|
72
|
+
"neostandard": "^0.13.0",
|
|
73
|
+
"simple-git": "^3.30.0",
|
|
74
|
+
"tinybench": "^6.0.0",
|
|
75
|
+
"tstyche": "^7.1.0",
|
|
76
|
+
"typebox": "^1.0.81",
|
|
77
|
+
"typescript": "~6.0.2",
|
|
78
|
+
"webpack": "^5.104.1"
|
|
79
|
+
},
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"@fastify/merge-json-schemas": "^0.2.0",
|
|
82
|
+
"ajv": "^8.12.0",
|
|
83
|
+
"ajv-formats": "^3.0.1",
|
|
84
|
+
"fast-uri": "^3.0.0",
|
|
85
|
+
"json-schema-ref-resolver": "^3.0.0",
|
|
86
|
+
"rfdc": "^1.2.0"
|
|
87
|
+
},
|
|
88
|
+
"runkitExampleFilename": "./examples/example.js"
|
|
89
|
+
}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('node:test')
|
|
4
|
+
const build = require('..')
|
|
5
|
+
|
|
6
|
+
test('additionalProperties', (t) => {
|
|
7
|
+
t.plan(1)
|
|
8
|
+
const stringify = build({
|
|
9
|
+
title: 'additionalProperties',
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
str: {
|
|
13
|
+
type: 'string'
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
additionalProperties: {
|
|
17
|
+
type: 'string'
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const obj = { str: 'test', foo: 42, ofoo: true, foof: 'string', objfoo: { a: true } }
|
|
22
|
+
t.assert.equal(stringify(obj), '{"str":"test","foo":"42","ofoo":"true","foof":"string","objfoo":"[object Object]"}')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('additionalProperties should not change properties', (t) => {
|
|
26
|
+
t.plan(1)
|
|
27
|
+
const stringify = build({
|
|
28
|
+
title: 'patternProperties should not change properties',
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
foo: {
|
|
32
|
+
type: 'string'
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
additionalProperties: {
|
|
36
|
+
type: 'number'
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const obj = { foo: '42', ofoo: 42 }
|
|
41
|
+
t.assert.equal(stringify(obj), '{"foo":"42","ofoo":42}')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('additionalProperties should not change properties and patternProperties', (t) => {
|
|
45
|
+
t.plan(1)
|
|
46
|
+
const stringify = build({
|
|
47
|
+
title: 'patternProperties should not change properties',
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
foo: {
|
|
51
|
+
type: 'string'
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
patternProperties: {
|
|
55
|
+
foo: {
|
|
56
|
+
type: 'string'
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
additionalProperties: {
|
|
60
|
+
type: 'number'
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const obj = { foo: '42', ofoo: 42, test: '42' }
|
|
65
|
+
t.assert.equal(stringify(obj), '{"foo":"42","ofoo":"42","test":42}')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('additionalProperties set to true, use of fast-safe-stringify', (t) => {
|
|
69
|
+
t.plan(1)
|
|
70
|
+
const stringify = build({
|
|
71
|
+
title: 'check string coerce',
|
|
72
|
+
type: 'object',
|
|
73
|
+
properties: {},
|
|
74
|
+
additionalProperties: true
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const obj = { foo: true, ofoo: 42, arrfoo: ['array', 'test'], objfoo: { a: 'world' } }
|
|
78
|
+
t.assert.equal(stringify(obj), '{"foo":true,"ofoo":42,"arrfoo":["array","test"],"objfoo":{"a":"world"}}')
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('additionalProperties - string coerce', (t) => {
|
|
82
|
+
t.plan(1)
|
|
83
|
+
const stringify = build({
|
|
84
|
+
title: 'check string coerce',
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {},
|
|
87
|
+
additionalProperties: {
|
|
88
|
+
type: 'string'
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
const obj = { foo: true, ofoo: 42, arrfoo: ['array', 'test'], objfoo: { a: 'world' } }
|
|
93
|
+
t.assert.equal(stringify(obj), '{"foo":"true","ofoo":"42","arrfoo":"array,test","objfoo":"[object Object]"}')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('additionalProperties - number skip', (t) => {
|
|
97
|
+
t.plan(1)
|
|
98
|
+
const stringify = build({
|
|
99
|
+
title: 'check number coerce',
|
|
100
|
+
type: 'object',
|
|
101
|
+
properties: {},
|
|
102
|
+
additionalProperties: {
|
|
103
|
+
type: 'number'
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// const obj = { foo: true, ofoo: '42', xfoo: 'string', arrfoo: [1, 2], objfoo: { num: 42 } }
|
|
108
|
+
const obj = { foo: true, ofoo: '42' }
|
|
109
|
+
t.assert.equal(stringify(obj), '{"foo":1,"ofoo":42}')
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test('additionalProperties - boolean coerce', (t) => {
|
|
113
|
+
t.plan(1)
|
|
114
|
+
const stringify = build({
|
|
115
|
+
title: 'check boolean coerce',
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {},
|
|
118
|
+
additionalProperties: {
|
|
119
|
+
type: 'boolean'
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const obj = { foo: 'true', ofoo: 0, arrfoo: [1, 2], objfoo: { a: true } }
|
|
124
|
+
t.assert.equal(stringify(obj), '{"foo":true,"ofoo":false,"arrfoo":true,"objfoo":true}')
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
test('additionalProperties - object coerce', (t) => {
|
|
128
|
+
t.plan(1)
|
|
129
|
+
const stringify = build({
|
|
130
|
+
title: 'check object coerce',
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {},
|
|
133
|
+
additionalProperties: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: {
|
|
136
|
+
answer: {
|
|
137
|
+
type: 'number'
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const obj = { objfoo: { answer: 42 } }
|
|
144
|
+
t.assert.equal(stringify(obj), '{"objfoo":{"answer":42}}')
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
test('additionalProperties - array coerce', (t) => {
|
|
148
|
+
t.plan(2)
|
|
149
|
+
const stringify = build({
|
|
150
|
+
title: 'check array coerce',
|
|
151
|
+
type: 'object',
|
|
152
|
+
properties: {},
|
|
153
|
+
additionalProperties: {
|
|
154
|
+
type: 'array',
|
|
155
|
+
items: {
|
|
156
|
+
type: 'string'
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const coercibleValues = { arrfoo: [1, 2] }
|
|
162
|
+
t.assert.equal(stringify(coercibleValues), '{"arrfoo":["1","2"]}')
|
|
163
|
+
|
|
164
|
+
const incoercibleValues = { foo: 'true', ofoo: 0, objfoo: { tyrion: 'lannister' } }
|
|
165
|
+
t.assert.throws(() => stringify(incoercibleValues))
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
test('additionalProperties with empty schema', (t) => {
|
|
169
|
+
t.plan(1)
|
|
170
|
+
const stringify = build({
|
|
171
|
+
type: 'object',
|
|
172
|
+
additionalProperties: {}
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
const obj = { a: 1, b: true, c: null }
|
|
176
|
+
t.assert.equal(stringify(obj), '{"a":1,"b":true,"c":null}')
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('additionalProperties with nested empty schema', (t) => {
|
|
180
|
+
t.plan(1)
|
|
181
|
+
const stringify = build({
|
|
182
|
+
type: 'object',
|
|
183
|
+
properties: {
|
|
184
|
+
data: { type: 'object', additionalProperties: {} }
|
|
185
|
+
},
|
|
186
|
+
required: ['data']
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
const obj = { data: { a: 1, b: true, c: null } }
|
|
190
|
+
t.assert.equal(stringify(obj), '{"data":{"a":1,"b":true,"c":null}}')
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
test('nested additionalProperties', (t) => {
|
|
194
|
+
t.plan(1)
|
|
195
|
+
const stringify = build({
|
|
196
|
+
title: 'additionalProperties',
|
|
197
|
+
type: 'array',
|
|
198
|
+
items: {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
ap: {
|
|
202
|
+
type: 'object',
|
|
203
|
+
additionalProperties: { type: 'string' }
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
const obj = [{ ap: { value: 'string' } }]
|
|
210
|
+
t.assert.equal(stringify(obj), '[{"ap":{"value":"string"}}]')
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
test('very nested additionalProperties', (t) => {
|
|
214
|
+
t.plan(1)
|
|
215
|
+
const stringify = build({
|
|
216
|
+
title: 'additionalProperties',
|
|
217
|
+
type: 'array',
|
|
218
|
+
items: {
|
|
219
|
+
type: 'object',
|
|
220
|
+
properties: {
|
|
221
|
+
ap: {
|
|
222
|
+
type: 'object',
|
|
223
|
+
properties: {
|
|
224
|
+
nested: {
|
|
225
|
+
type: 'object',
|
|
226
|
+
properties: {
|
|
227
|
+
moarNested: {
|
|
228
|
+
type: 'object',
|
|
229
|
+
properties: {
|
|
230
|
+
finally: {
|
|
231
|
+
type: 'object',
|
|
232
|
+
additionalProperties: {
|
|
233
|
+
type: 'string'
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
const obj = [{ ap: { nested: { moarNested: { finally: { value: 'str' } } } } }]
|
|
247
|
+
t.assert.equal(stringify(obj), '[{"ap":{"nested":{"moarNested":{"finally":{"value":"str"}}}}}]')
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
test('nested additionalProperties set to true', (t) => {
|
|
251
|
+
t.plan(1)
|
|
252
|
+
const stringify = build({
|
|
253
|
+
title: 'nested additionalProperties=true',
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: {
|
|
256
|
+
ap: {
|
|
257
|
+
type: 'object',
|
|
258
|
+
additionalProperties: true
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
const obj = { ap: { value: 'string', someNumber: 42 } }
|
|
264
|
+
t.assert.equal(stringify(obj), '{"ap":{"value":"string","someNumber":42}}')
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
test('field passed to fastSafeStringify as undefined should be removed', (t) => {
|
|
268
|
+
t.plan(1)
|
|
269
|
+
const stringify = build({
|
|
270
|
+
title: 'nested additionalProperties=true',
|
|
271
|
+
type: 'object',
|
|
272
|
+
properties: {
|
|
273
|
+
ap: {
|
|
274
|
+
type: 'object',
|
|
275
|
+
additionalProperties: true
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
const obj = { ap: { value: 'string', someNumber: undefined } }
|
|
281
|
+
t.assert.equal(stringify(obj), '{"ap":{"value":"string"}}')
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
test('property without type but with enum, will acts as additionalProperties', (t) => {
|
|
285
|
+
t.plan(1)
|
|
286
|
+
const stringify = build({
|
|
287
|
+
title: 'automatic additionalProperties',
|
|
288
|
+
type: 'object',
|
|
289
|
+
properties: {
|
|
290
|
+
ap: {
|
|
291
|
+
enum: ['foobar', 42, ['foo', 'bar'], {}]
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
const obj = { ap: { additional: 'field' } }
|
|
297
|
+
t.assert.equal(stringify(obj), '{"ap":{"additional":"field"}}')
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
test('property without type but with enum, will acts as additionalProperties without overwriting', (t) => {
|
|
301
|
+
t.plan(1)
|
|
302
|
+
const stringify = build({
|
|
303
|
+
title: 'automatic additionalProperties',
|
|
304
|
+
type: 'object',
|
|
305
|
+
properties: {
|
|
306
|
+
ap: {
|
|
307
|
+
additionalProperties: false,
|
|
308
|
+
enum: ['foobar', 42, ['foo', 'bar'], {}]
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
const obj = { ap: { additional: 'field' } }
|
|
314
|
+
t.assert.equal(stringify(obj), '{"ap":{}}')
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
test('function and symbol references are not serialized as undefined', (t) => {
|
|
318
|
+
t.plan(1)
|
|
319
|
+
const stringify = build({
|
|
320
|
+
title: 'additionalProperties',
|
|
321
|
+
type: 'object',
|
|
322
|
+
additionalProperties: true,
|
|
323
|
+
properties: {
|
|
324
|
+
str: {
|
|
325
|
+
type: 'string'
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
const obj = { str: 'x', test: 'test', meth: () => 'x', sym: Symbol('x') }
|
|
331
|
+
t.assert.equal(stringify(obj), '{"str":"x","test":"test"}')
|
|
332
|
+
})
|