fast-json-stringify
Advanced tools
Comparing version 2.7.13 to 3.0.0
44
bench.js
@@ -41,2 +41,17 @@ 'use strict' | ||
const schemaAJVJTD = { | ||
properties: { | ||
firstName: { | ||
type: 'string' | ||
}, | ||
lastName: { | ||
type: 'string', | ||
nullable: true | ||
}, | ||
age: { | ||
type: 'uint8' | ||
} | ||
} | ||
} | ||
const arraySchema = { | ||
@@ -54,2 +69,6 @@ title: 'array schema', | ||
const arraySchemaAJVJTD = { | ||
elements: schemaAJVJTD | ||
} | ||
const dateFormatSchema = { | ||
@@ -90,2 +109,8 @@ description: 'Date of birth', | ||
const Ajv = require('ajv/dist/jtd') | ||
const ajv = new Ajv() | ||
const ajvSerialize = ajv.compileSerializer(schemaAJVJTD) | ||
const ajvSerializeArray = ajv.compileSerializer(arraySchemaAJVJTD) | ||
const ajvSerializeString = ajv.compileSerializer({ type: 'string' }) | ||
// eslint-disable-next-line | ||
@@ -111,2 +136,5 @@ for (var i = 0; i < 10000; i++) { | ||
}) | ||
suite.add('AJV Serialize creation', function () { | ||
ajv.compileSerializer(schemaAJVJTD) | ||
}) | ||
@@ -125,2 +153,6 @@ suite.add('JSON.stringify array', function () { | ||
suite.add('AJV Serialize array', function () { | ||
ajvSerializeArray(multiArray) | ||
}) | ||
suite.add('JSON.stringify long string', function () { | ||
@@ -138,2 +170,6 @@ JSON.stringify(str) | ||
suite.add('AJV Serialize long string', function () { | ||
ajvSerializeString(str) | ||
}) | ||
suite.add('JSON.stringify short string', function () { | ||
@@ -151,2 +187,6 @@ JSON.stringify('hello world') | ||
suite.add('AJV Serialize short string', function () { | ||
ajvSerializeString('hello world') | ||
}) | ||
suite.add('JSON.stringify obj', function () { | ||
@@ -164,2 +204,6 @@ JSON.stringify(obj) | ||
suite.add('AJV Serialize obj', function () { | ||
ajvSerialize(obj) | ||
}) | ||
suite.add('JSON stringify date', function () { | ||
@@ -166,0 +210,0 @@ JSON.stringify(date) |
'use strict' | ||
const Ajv = require('ajv') | ||
const standaloneCode = require('ajv/dist/standalone').default | ||
const ajvFormats = require('ajv-formats') | ||
const fs = require('fs') | ||
const path = require('path') | ||
const pack = require('ajv-pack') | ||
const ajv = new Ajv({ | ||
sourceCode: true // this option is required by ajv-pack | ||
addUsedSchema: false, | ||
allowUnionTypes: true, | ||
code: { | ||
source: true, | ||
lines: true, | ||
optimize: 3 | ||
} | ||
}) | ||
ajvFormats(ajv) | ||
const validate = ajv.compile(require('ajv/lib/refs/json-schema-draft-07.json')) | ||
const schema = require('ajv/lib/refs/json-schema-draft-07.json') | ||
const validate = ajv.compile(schema) | ||
const validationCode = standaloneCode(ajv, validate) | ||
const moduleCode = `// This file is autogenerated by ${path.basename(__filename)}, do not edit | ||
const moduleCode = `/* CODE GENERATED BY '${path.basename(__filename)}' DO NOT EDIT! */\n${validationCode}` | ||
function nop () { return true } | ||
${pack(ajv, validate).replace(/root\.refVal\[0\]/gm, 'nop')} | ||
` | ||
fs.writeFileSync(path.join(__dirname, 'schema-validator.js'), moduleCode) |
114
index.js
@@ -6,2 +6,3 @@ 'use strict' | ||
const Ajv = require('ajv') | ||
const ajvFormats = require('ajv-formats') | ||
const merge = require('deepmerge') | ||
@@ -14,9 +15,2 @@ const clone = require('rfdc')({ proto: true }) | ||
let isLong | ||
try { | ||
isLong = require('long').isLong | ||
} catch (e) { | ||
isLong = null | ||
} | ||
const addComma = ` | ||
@@ -38,3 +32,3 @@ if (addComma) { | ||
const first = validate.errors[0] | ||
const err = new Error(`${name}schema is invalid: data${first.dataPath} ${first.message}`) | ||
const err = new Error(`${name}schema is invalid: data${first.instancePath} ${first.message}`) | ||
err.errors = isValidSchema.errors | ||
@@ -85,4 +79,36 @@ throw err | ||
var isLong = ${isLong ? isLong.toString() : false} | ||
/** | ||
* Used by schemas that are dependant on calling 'ajv.validate' during runtime, | ||
* it stores the value of the '$id' property of the schema (if it has it) inside | ||
* a cache which is used to figure out if the schema was compiled into a validator | ||
* by ajv on a previous call, if it was then the '$id' string will be used to | ||
* invoke 'ajv.validate', this allows: | ||
* | ||
* 1. Schemas that depend on ajv.validate calls to leverage ajv caching system. | ||
* 2. To avoid errors, since directly invoking 'ajv.validate' with the same | ||
* schema (that contains an '$id' property) twice will throw an error. | ||
*/ | ||
const $validateWithAjv = (function() { | ||
const cache = new Set() | ||
return function (schema, target) { | ||
const id = schema.$id | ||
if (!id) { | ||
return ajv.validate(schema, target) | ||
} | ||
const cached = cache.has(id) | ||
if (cached) { | ||
return ajv.validate(id, target) | ||
} else { | ||
cache.add(id) | ||
return ajv.validate(schema, target) | ||
} | ||
} | ||
})() | ||
function parseInteger(int) { return Math.${intParseFunctionName}(int) } | ||
@@ -145,3 +171,5 @@ ` | ||
const dependencies = [new Ajv(options.ajv)] | ||
const ajvInstance = new Ajv(options.ajv) | ||
ajvFormats(ajvInstance) | ||
const dependencies = [ajvInstance] | ||
const dependenciesName = ['ajv'] | ||
@@ -250,6 +278,4 @@ dependenciesName.push(code) | ||
function $asInteger (i) { | ||
if (isLong && isLong(i)) { | ||
if (typeof i === 'bigint') { | ||
return i.toString() | ||
} else if (typeof i === 'bigint') { | ||
return i.toString() | ||
} else if (Number.isInteger(i)) { | ||
@@ -527,18 +553,7 @@ return $asNumber(i) | ||
var t = Number(obj[keys[i]]) | ||
if (!isNaN(t)) { | ||
${addComma} | ||
json += $asString(keys[i]) + ':' + t | ||
} | ||
` | ||
if (isLong) { | ||
code += ` | ||
if (isLong(obj[keys[i]]) || !isNaN(t)) { | ||
${addComma} | ||
json += $asString(keys[i]) + ':' + $asInteger(obj[keys[i]]) | ||
} | ||
` | ||
} else { | ||
code += ` | ||
if (!isNaN(t)) { | ||
${addComma} | ||
json += $asString(keys[i]) + ':' + t | ||
} | ||
` | ||
} | ||
} else if (type === 'number') { | ||
@@ -745,29 +760,8 @@ code += ` | ||
var rendered = false | ||
` | ||
if (isLong) { | ||
code += ` | ||
if (isLong(obj[${sanitized}])) { | ||
${addComma} | ||
json += ${asString} + ':' + obj[${sanitized}].toString() | ||
rendered = true | ||
} else { | ||
var t = Number(obj[${sanitized}]) | ||
if (!isNaN(t)) { | ||
${addComma} | ||
json += ${asString} + ':' + t | ||
rendered = true | ||
} | ||
} | ||
` | ||
} else { | ||
code += ` | ||
var t = $asInteger(obj[${sanitized}]) | ||
if (!isNaN(t)) { | ||
${addComma} | ||
json += ${asString} + ':' + t | ||
rendered = true | ||
} | ||
` | ||
} | ||
code += ` | ||
var t = $asInteger(obj[${sanitized}]) | ||
if (!isNaN(t)) { | ||
${addComma} | ||
json += ${asString} + ':' + t | ||
rendered = true | ||
} | ||
if (rendered) { | ||
@@ -892,3 +886,3 @@ ` | ||
code += ` | ||
valid = ajv.validate(${JSON.stringify(i)}, obj) | ||
valid = $validateWithAjv(${JSON.stringify(i)}, obj) | ||
if (valid) { | ||
@@ -1243,3 +1237,3 @@ ` | ||
code += ` | ||
${index === 0 ? 'if' : 'else if'}(ajv.validate(${JSON.stringify(location.schema)}, ${testValue})) | ||
${index === 0 ? 'if' : 'else if'}($validateWithAjv(${JSON.stringify(location.schema)}, ${testValue})) | ||
${nestedResult.code} | ||
@@ -1261,3 +1255,3 @@ ` | ||
code += ` | ||
${index === 0 ? 'if' : 'else if'}(ajv.validate(${JSON.stringify(location.schema)}, ${testValue})) | ||
${index === 0 ? 'if' : 'else if'}($validateWithAjv(${JSON.stringify(location.schema)}, ${testValue})) | ||
${nestedResult.code} | ||
@@ -1377,3 +1371,5 @@ ` | ||
dependencies.unshift('ajv') | ||
args.push(new Ajv(options.ajv)) | ||
const ajvInstance = new Ajv(options.ajv) | ||
ajvFormats(ajvInstance) | ||
args.push(ajvInstance) | ||
} | ||
@@ -1380,0 +1376,0 @@ |
{ | ||
"name": "fast-json-stringify", | ||
"version": "2.7.13", | ||
"version": "3.0.0", | ||
"description": "Stringify your JSON at max speed", | ||
@@ -33,7 +33,5 @@ "main": "index.js", | ||
"devDependencies": { | ||
"ajv-pack": "^0.3.1", | ||
"benchmark": "^2.1.4", | ||
"compile-json-stringify": "^0.1.2", | ||
"is-my-json-valid": "^2.20.0", | ||
"long": "^4.0.0", | ||
"moment": "^2.24.0", | ||
@@ -49,3 +47,4 @@ "pre-commit": "^1.2.2", | ||
"dependencies": { | ||
"ajv": "^6.11.0", | ||
"ajv": "^8.6.2", | ||
"ajv-formats": "^2.1.1", | ||
"deepmerge": "^4.2.2", | ||
@@ -52,0 +51,0 @@ "rfdc": "^1.2.0", |
@@ -10,4 +10,11 @@ # fast-json-stringify | ||
__fast-json-stringify__ is significantly faster than `JSON.stringify()` for small payloads. Its performance advantage shrinks as your payload grows. It pairs well with [__flatstr__](https://www.npmjs.com/package/flatstr), which triggers a V8 optimization that improves performance when eventually converting the string to a `Buffer`. | ||
__fast-json-stringify__ is significantly faster than `JSON.stringify()` for small payloads. | ||
Its performance advantage shrinks as your payload grows. | ||
It pairs well with [__flatstr__](https://www.npmjs.com/package/flatstr), which triggers a V8 optimization that improves performance when eventually converting the string to a `Buffer`. | ||
### How it works | ||
fast-json-stringify requires a [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7) input to generate a fast `stringify` function. | ||
##### Benchmarks | ||
@@ -19,18 +26,24 @@ | ||
``` | ||
FJS creation x 6,040 ops/sec ±1.17% (91 runs sampled) | ||
JSON.stringify array x 5,519 ops/sec ±0.08% (99 runs sampled) | ||
fast-json-stringify array x 7,143 ops/sec ±0.14% (97 runs sampled) | ||
JSON.stringify long string x 16,438 ops/sec ±0.32% (98 runs sampled) | ||
fast-json-stringify long string x 16,457 ops/sec ±0.09% (97 runs sampled) | ||
JSON.stringify short string x 12,061,258 ops/sec ±0.32% (97 runs sampled) | ||
fast-json-stringify short string x 35,531,071 ops/sec ±0.17% (94 runs sampled) | ||
JSON.stringify obj x 3,079,746 ops/sec ±0.09% (95 runs sampled) | ||
fast-json-stringify obj x 7,721,569 ops/sec ±0.12% (98 runs sampled) | ||
JSON stringify date x 1,149,786 ops/sec ±0.10% (99 runs sampled) | ||
fast-json-stringify date format x 1,674,498 ops/sec ±0.12% (99 runs sampled) | ||
FJS creation x 8,443 ops/sec ±1.01% (90 runs sampled) | ||
CJS creation x 183,219 ops/sec ±0.13% (96 runs sampled) | ||
AJV Serialize creation x 83,541,848 ops/sec ±0.24% (98 runs sampled) | ||
JSON.stringify array x 5,363 ops/sec ±0.11% (100 runs sampled) | ||
fast-json-stringify array x 6,747 ops/sec ±0.13% (98 runs sampled) | ||
compile-json-stringify array x 7,121 ops/sec ±0.42% (98 runs sampled) | ||
AJV Serialize array x 7,533 ops/sec ±0.13% (98 runs sampled) | ||
JSON.stringify long string x 16,461 ops/sec ±0.12% (98 runs sampled) | ||
fast-json-stringify long string x 16,443 ops/sec ±0.37% (99 runs sampled) | ||
compile-json-stringify long string x 16,458 ops/sec ±0.09% (98 runs sampled) | ||
AJV Serialize long string x 21,433 ops/sec ±0.08% (95 runs sampled) | ||
JSON.stringify short string x 12,035,664 ops/sec ±0.62% (96 runs sampled) | ||
fast-json-stringify short string x 38,281,060 ops/sec ±0.24% (98 runs sampled) | ||
compile-json-stringify short string x 32,388,037 ops/sec ±0.27% (97 runs sampled) | ||
AJV Serialize short string x 32,288,612 ops/sec ±0.32% (95 runs sampled) | ||
JSON.stringify obj x 3,068,185 ops/sec ±0.16% (98 runs sampled) | ||
fast-json-stringify obj x 10,082,694 ops/sec ±0.10% (97 runs sampled) | ||
compile-json-stringify obj x 17,037,963 ops/sec ±1.17% (97 runs sampled) | ||
AJV Serialize obj x 9,660,041 ops/sec ±0.11% (97 runs sampled) | ||
JSON stringify date x 1,084,008 ops/sec ±0.16% (98 runs sampled) | ||
fast-json-stringify date format x 1,781,044 ops/sec ±0.48% (99 runs sampled) | ||
compile-json-stringify date format x 1,086,187 ops/sec ±0.16% (99 runs sampled) | ||
``` | ||
@@ -107,3 +120,3 @@ | ||
- `schema`: external schemas references by $ref property. [More details](#ref) | ||
- `ajv`: ajv instance's settings for those properties that require `ajv`. [More details](#anyof) | ||
- `ajv`: [ajv v8 instance's settings](https://ajv.js.org/options.html) for those properties that require `ajv`. [More details](#anyof) | ||
- `rounding`: setup how the `integer` types will be rounded when not integers. [More details](#integer) | ||
@@ -117,3 +130,3 @@ | ||
Build a `stringify()` function based on [jsonschema](https://json-schema.org/). | ||
Build a `stringify()` function based on [jsonschema draft 7 spec](https://json-schema.org/specification-links.html#draft-7). | ||
@@ -528,43 +541,4 @@ Supported types: | ||
#### Long integers | ||
By default the library will automatically handle [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) from Node.js v10.3 and above. | ||
If you can't use BigInts in your environment, long integers (64-bit) are also supported using the [long](https://github.com/dcodeIO/long.js) module. | ||
Example: | ||
```javascript | ||
// => using native BigInt | ||
const stringify = fastJson({ | ||
title: 'Example Schema', | ||
type: 'object', | ||
properties: { | ||
id: { | ||
type: 'integer' | ||
} | ||
} | ||
}) | ||
By default the library will handle automatically [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). | ||
const obj = { | ||
id: 18446744073709551615n | ||
} | ||
console.log(stringify(obj)) // '{"id":18446744073709551615}' | ||
// => using the long library | ||
const Long = require('long') | ||
const stringify = fastJson({ | ||
title: 'Example Schema', | ||
type: 'object', | ||
properties: { | ||
id: { | ||
type: 'integer' | ||
} | ||
} | ||
}) | ||
const obj = { | ||
id: Long.fromString('18446744073709551615', true) | ||
} | ||
console.log(stringify(obj)) // '{"id":18446744073709551615}' | ||
``` | ||
<a name="integer"></a> | ||
@@ -571,0 +545,0 @@ #### Integers |
@@ -111,3 +111,3 @@ 'use strict' | ||
} catch (e) { | ||
t.equal(e.message, 'schema is invalid: data.allOf should NOT have fewer than 1 items') | ||
t.equal(e.message, 'schema is invalid: data/allOf must NOT have fewer than 1 items') | ||
} | ||
@@ -114,0 +114,0 @@ }) |
@@ -66,1 +66,27 @@ 'use strict' | ||
}) | ||
test('to string auto-consistent with ajv-formats', t => { | ||
t.plan(3) | ||
const debugMode = fjs({ | ||
title: 'object with multiple types field and format keyword', | ||
type: 'object', | ||
properties: { | ||
str: { | ||
anyOf: [{ | ||
type: 'string', | ||
format: 'email' | ||
}, { | ||
type: 'boolean' | ||
}] | ||
} | ||
} | ||
}, { debugMode: 1 }) | ||
t.type(debugMode, Array) | ||
const str = debugMode.toString() | ||
const compiled = fjs.restore(str) | ||
const tobe = JSON.stringify({ str: 'foo@bar.com' }) | ||
t.same(compiled({ str: 'foo@bar.com' }), tobe) | ||
t.same(compiled({ str: 'foo' }), JSON.stringify({ str: null }), 'invalid format is ignored') | ||
}) |
@@ -11,2 +11,3 @@ 'use strict' | ||
if: { | ||
type: 'object', | ||
properties: { | ||
@@ -17,2 +18,3 @@ kind: { type: 'string', enum: ['foobar'] } | ||
then: { | ||
type: 'object', | ||
properties: { | ||
@@ -35,2 +37,3 @@ kind: { type: 'string', enum: ['foobar'] }, | ||
else: { | ||
type: 'object', | ||
properties: { | ||
@@ -58,2 +61,3 @@ kind: { type: 'string', enum: ['greeting'] }, | ||
if: { | ||
type: 'object', | ||
properties: { | ||
@@ -65,2 +69,3 @@ kind: { type: 'string', enum: ['foobar', 'greeting'] } | ||
if: { | ||
type: 'object', | ||
properties: { | ||
@@ -71,2 +76,3 @@ kind: { type: 'string', enum: ['foobar'] } | ||
then: { | ||
type: 'object', | ||
properties: { | ||
@@ -89,2 +95,3 @@ kind: { type: 'string', enum: ['foobar'] }, | ||
else: { | ||
type: 'object', | ||
properties: { | ||
@@ -98,2 +105,3 @@ kind: { type: 'string', enum: ['greeting'] }, | ||
else: { | ||
type: 'object', | ||
properties: { | ||
@@ -111,2 +119,3 @@ kind: { type: 'string', enum: ['alphabet'] }, | ||
if: { | ||
type: 'object', | ||
properties: { | ||
@@ -117,2 +126,3 @@ kind: { type: 'string', enum: ['foobar'] } | ||
then: { | ||
type: 'object', | ||
properties: { | ||
@@ -136,2 +146,3 @@ kind: { type: 'string', enum: ['foobar'] }, | ||
if: { | ||
type: 'object', | ||
properties: { | ||
@@ -142,2 +153,3 @@ kind: { type: 'string', enum: ['greeting'] } | ||
then: { | ||
type: 'object', | ||
properties: { | ||
@@ -150,2 +162,3 @@ kind: { type: 'string', enum: ['greeting'] }, | ||
else: { | ||
type: 'object', | ||
properties: { | ||
@@ -170,2 +183,3 @@ kind: { type: 'string', enum: ['alphabet'] }, | ||
if: { | ||
type: 'object', | ||
properties: { | ||
@@ -176,2 +190,3 @@ kind: { type: 'string', enum: ['foobar'] } | ||
then: { | ||
type: 'object', | ||
properties: { | ||
@@ -328,3 +343,3 @@ kind: { type: 'string', enum: ['foobar'] }, | ||
const stringify = build(JSON.parse(JSON.stringify(test.schema))) | ||
const stringify = build(JSON.parse(JSON.stringify(test.schema)), { ajv: { strictTypes: false } }) | ||
const serialized = stringify(test.input) | ||
@@ -331,0 +346,0 @@ t.equal(serialized, test.expected) |
@@ -5,6 +5,4 @@ 'use strict' | ||
const test = t.test | ||
const semver = require('semver') | ||
const validator = require('is-my-json-valid') | ||
const proxyquire = require('proxyquire') | ||
const build = proxyquire('..', { long: null }) | ||
const build = require('..') | ||
const ROUNDING_TYPES = ['ceil', 'floor', 'round'] | ||
@@ -140,9 +138,2 @@ | ||
if (semver.gt(process.versions.node, '10.3.0')) { | ||
require('./bigint')(t.test, build) | ||
} else { | ||
t.pass('Skip because Node version < 10.4') | ||
t.end() | ||
} | ||
test('should round integer object parameter', t => { | ||
@@ -149,0 +140,0 @@ t.plan(2) |
@@ -100,3 +100,3 @@ 'use strict' | ||
nullableObject: [{ type: 'object', nullable: true }, null, null], | ||
complexObject: [complexObject, complexData, complexExpectedResult] | ||
complexObject: [complexObject, complexData, complexExpectedResult, { ajv: { allowUnionTypes: true } }] | ||
} | ||
@@ -108,5 +108,10 @@ | ||
const stringifier = build(testSet[key][0]) | ||
const data = testSet[key][1] | ||
const expected = testSet[key][2] | ||
const [ | ||
schema, | ||
data, | ||
expected, | ||
extraOptions | ||
] = testSet[key] | ||
const stringifier = build(schema, extraOptions) | ||
const result = stringifier(data) | ||
@@ -113,0 +118,0 @@ t.same(JSON.parse(result), expected) |
@@ -158,1 +158,40 @@ 'use strict' | ||
}) | ||
test('must not mutate items referred by $ref', t => { | ||
t.plan(2) | ||
const firstSchema = { | ||
$id: 'example1', | ||
type: 'object', | ||
properties: { | ||
name: { | ||
type: 'string' | ||
} | ||
} | ||
} | ||
const reusedSchema = { | ||
$id: 'example2', | ||
type: 'object', | ||
properties: { | ||
name: { | ||
oneOf: [ | ||
{ | ||
$ref: 'example1' | ||
} | ||
] | ||
} | ||
} | ||
} | ||
const clonedSchema = clone(firstSchema) | ||
const stringify = build(reusedSchema, { | ||
schema: { | ||
[firstSchema.$id]: firstSchema | ||
} | ||
}) | ||
const value = stringify({ name: { name: 'foo' } }) | ||
t.equal(value, '{"name":{"name":"foo"}}') | ||
t.same(firstSchema, clonedSchema) | ||
}) |
@@ -6,3 +6,5 @@ { | ||
"rootDir": "../..", | ||
"strict": true | ||
"strict": true, | ||
"target": "ES2015", | ||
"moduleResolution": "node" | ||
}, | ||
@@ -9,0 +11,0 @@ "include": [ |
@@ -20,3 +20,3 @@ 'use strict' | ||
const stringify = build(schema) | ||
const stringify = build(schema, { ajv: { allowUnionTypes: true } }) | ||
@@ -332,3 +332,3 @@ const value = stringify({ | ||
} | ||
const stringify = build(schema) | ||
const stringify = build(schema, { ajv: { allowUnionTypes: true } }) | ||
@@ -335,0 +335,0 @@ try { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11
268898
5
65
9919
631
+ Addedajv-formats@^2.1.1
+ Addedajv@8.17.1(transitive)
+ Addedajv-formats@2.1.1(transitive)
+ Addedfast-uri@3.0.1(transitive)
+ Addedjson-schema-traverse@1.0.0(transitive)
+ Addedrequire-from-string@2.0.2(transitive)
- Removedajv@6.12.6(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removedpunycode@2.3.1(transitive)
- Removeduri-js@4.4.1(transitive)
Updatedajv@^8.6.2