fast-json-stringify 5.8.0 → 5.9.1

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/.gitattributes ADDED
@@ -0,0 +1,2 @@
1
+ # Set default behavior to automatically convert line endings
2
+ * text=auto eol=lf
@@ -14,13 +14,13 @@ jobs:
14
14
  PR-BENCH: ${{ steps.benchmark-pr.outputs.BENCH_RESULT }}
15
15
  MASTER-BENCH: ${{ steps.benchmark-master.outputs.BENCH_RESULT }}
16
16
  steps:
17
- - uses: actions/checkout@v3
17
+ - uses: actions/checkout@v4
18
18
  with:
19
19
  persist-credentials: false
20
20
  ref: ${{github.event.pull_request.head.sha}}
21
21
  repository: ${{github.event.pull_request.head.repo.full_name}}
22
22
 
23
- - uses: actions/setup-node@v3
23
+ - uses: actions/setup-node@v4
24
24
  with:
25
25
  node-version: 18
26
26
 
@@ -39,7 +39,7 @@ jobs:
39
39
  echo "::set-output name=BENCH_RESULT::$content"
40
40
 
41
41
  # master benchmark
42
- - uses: actions/checkout@v3
42
+ - uses: actions/checkout@v4
43
43
  with:
44
44
  ref: 'master'
45
45
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  const fastJson = require('..')
2
4
  const stringify = fastJson({
3
5
  title: 'Example Schema',
package/index.js CHANGED
@@ -5,13 +5,15 @@
5
5
  const merge = require('@fastify/deepmerge')()
6
6
  const clone = require('rfdc')({ proto: true })
7
7
  const { randomUUID } = require('crypto')
8
+ const { RefResolver } = require('json-schema-ref-resolver')
8
9
 
9
10
  const validate = require('./lib/schema-validator')
10
11
  const Serializer = require('./lib/serializer')
11
12
  const Validator = require('./lib/validator')
12
- const RefResolver = require('./lib/ref-resolver')
13
13
  const Location = require('./lib/location')
14
14
 
15
+ const SINGLE_TICK = /'/g
16
+
15
17
  let largeArraySize = 2e4
16
18
  let largeArrayMechanism = 'default'
17
19
 
@@ -53,8 +55,7 @@ function resolveRef (context, location, ref) {
53
55
  const jsonPointer = ref.slice(hashIndex) || '#'
54
56
 
55
57
  const schema = context.refResolver.getSchema(schemaId, jsonPointer)
56
-
57
- if (schema === undefined) {
58
+ if (schema === null) {
58
59
  throw new Error(`Cannot find reference "${ref}"`)
59
60
  }
60
61
 
@@ -66,6 +67,13 @@ function resolveRef (context, location, ref) {
66
67
  return newLocation
67
68
  }
68
69
 
70
+ function getSchemaId (schema, rootSchemaId) {
71
+ if (schema.$id && schema.$id.charAt(0) !== '#') {
72
+ return schema.$id
73
+ }
74
+ return rootSchemaId
75
+ }
76
+
69
77
  function build (schema, options) {
70
78
  isValidSchema(schema)
71
79
 
@@ -82,12 +90,19 @@ function build (schema, options) {
82
90
  validatorSchemasIds: new Set()
83
91
  }
84
92
 
85
- context.refResolver.addSchema(schema, context.rootSchemaId)
93
+ const schemaId = getSchemaId(schema, context.rootSchemaId)
94
+ if (!context.refResolver.hasSchema(schemaId)) {
95
+ context.refResolver.addSchema(schema, context.rootSchemaId)
96
+ }
86
97
 
87
98
  if (options.schema) {
88
- for (const key of Object.keys(options.schema)) {
89
- isValidSchema(options.schema[key], key)
90
- context.refResolver.addSchema(options.schema[key], key)
99
+ for (const key in options.schema) {
100
+ const schema = options.schema[key]
101
+ const schemaId = getSchemaId(schema, key)
102
+ if (!context.refResolver.hasSchema(schemaId)) {
103
+ isValidSchema(schema, key)
104
+ context.refResolver.addSchema(schema, key)
105
+ }
91
106
  }
92
107
  }
93
108
 
@@ -821,7 +836,7 @@ function buildConstSerializer (location, input) {
821
836
  `
822
837
  }
823
838
 
824
- code += `json += '${JSON.stringify(schema.const)}'`
839
+ code += `json += '${JSON.stringify(schema.const).replace(SINGLE_TICK, "\\'")}'`
825
840
 
826
841
  if (hasNullType) {
827
842
  code += `
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "fast-json-stringify",
3
- "version": "5.8.0",
3
+ "version": "5.9.1",
4
4
  "description": "Stringify your JSON at max speed",
5
5
  "main": "index.js",
6
+ "type": "commonjs",
6
7
  "types": "types/index.d.ts",
7
8
  "scripts": {
8
9
  "bench": "node ./benchmark/bench.js",
@@ -34,7 +35,7 @@
34
35
  "homepage": "https://github.com/fastify/fast-json-stringify#readme",
35
36
  "devDependencies": {
36
37
  "@fastify/pre-commit": "^2.0.2",
37
- "@sinclair/typebox": "^0.29.1",
38
+ "@sinclair/typebox": "^0.31.1",
38
39
  "benchmark": "^2.1.4",
39
40
  "cli-select": "^1.1.2",
40
41
  "compile-json-stringify": "^0.1.2",
@@ -42,7 +43,7 @@
42
43
  "simple-git": "^3.7.1",
43
44
  "standard": "^17.0.0",
44
45
  "tap": "^16.0.1",
45
- "tsd": "^0.28.0",
46
+ "tsd": "^0.29.0",
46
47
  "webpack": "^5.40.0",
47
48
  "fast-json-stringify": "."
48
49
  },
@@ -52,7 +53,8 @@
52
53
  "ajv-formats": "^2.1.1",
53
54
  "fast-deep-equal": "^3.1.3",
54
55
  "fast-uri": "^2.1.0",
55
- "rfdc": "^1.2.0"
56
+ "rfdc": "^1.2.0",
57
+ "json-schema-ref-resolver": "^1.0.1"
56
58
  },
57
59
  "standard": {
58
60
  "ignore": [
@@ -82,6 +82,26 @@ test('schema with const string and no input', (t) => {
82
82
  t.ok(validate(JSON.parse(output)), 'valid schema')
83
83
  })
84
84
 
85
+ test('schema with const string that contains \'', (t) => {
86
+ t.plan(2)
87
+
88
+ const schema = {
89
+ type: 'object',
90
+ properties: {
91
+ foo: { const: "'bar'" }
92
+ }
93
+ }
94
+
95
+ const validate = validator(schema)
96
+ const stringify = build(schema)
97
+ const output = stringify({
98
+ foo: "'bar'"
99
+ })
100
+
101
+ t.equal(output, '{"foo":"\'bar\'"}')
102
+ t.ok(validate(JSON.parse(output)), 'valid schema')
103
+ })
104
+
85
105
  test('schema with const number', (t) => {
86
106
  t.plan(2)
87
107
 
package/test/ref.test.js CHANGED
@@ -1377,7 +1377,10 @@ test('Bad key', t => {
1377
1377
  })
1378
1378
  t.fail('Should throw')
1379
1379
  } catch (err) {
1380
- t.equal(err.message, 'Cannot find reference "extrenal#/definitions/projectId"')
1380
+ t.equal(
1381
+ err.message,
1382
+ 'Cannot resolve ref "extrenal#/definitions/projectId". Schema with id "extrenal" is not found.'
1383
+ )
1381
1384
  }
1382
1385
  })
1383
1386
 
@@ -2076,7 +2079,11 @@ test('should throw an Error if two non-identical schemas with same id are provid
2076
2079
  ]
2077
2080
  }
2078
2081
 
2079
- t.throws(() => build(schema), new Error('There is already another schema with id inner_schema'))
2082
+ try {
2083
+ build(schema)
2084
+ } catch (err) {
2085
+ t.equal(err.message, 'There is already another schema with id "inner_schema".')
2086
+ }
2080
2087
  })
2081
2088
 
2082
2089
  test('ref internal - throw if schema has definition twice with different shape', (t) => {
@@ -2115,5 +2122,9 @@ test('ref internal - throw if schema has definition twice with different shape',
2115
2122
  }
2116
2123
  }
2117
2124
 
2118
- t.throws(() => build(schema), Error('There is already another schema with id test##uri'))
2125
+ try {
2126
+ build(schema)
2127
+ } catch (err) {
2128
+ t.equal(err.message, 'There is already another anchor "#uri" in a schema "test".')
2129
+ }
2119
2130
  })
@@ -1,104 +0,0 @@
1
- 'use strict'
2
-
3
- const deepEqual = require('fast-deep-equal')
4
-
5
- class RefResolver {
6
- constructor () {
7
- this.schemas = {}
8
- }
9
-
10
- addSchema (schema, schemaId) {
11
- if (schema.$id !== undefined && schema.$id.charAt(0) !== '#') {
12
- schemaId = schema.$id
13
- }
14
- if (this.getSchema(schemaId) === undefined) {
15
- this.insertSchemaBySchemaId(schema, schemaId)
16
- this.insertSchemaSubschemas(schema, schemaId)
17
- }
18
- }
19
-
20
- getSchema (schemaId, jsonPointer = '#') {
21
- const schema = this.schemas[schemaId]
22
- if (schema === undefined) {
23
- return undefined
24
- }
25
- if (schema.anchors[jsonPointer] !== undefined) {
26
- return schema.anchors[jsonPointer]
27
- }
28
- return getDataByJSONPointer(schema.schema, jsonPointer)
29
- }
30
-
31
- getSchemaDependencies (schemaId, dependencies = {}) {
32
- const schema = this.schemas[schemaId]
33
-
34
- for (const dependencySchemaId of schema.dependencies) {
35
- if (dependencies[dependencySchemaId] !== undefined) continue
36
- dependencies[dependencySchemaId] = this.getSchema(dependencySchemaId)
37
- this.getSchemaDependencies(dependencySchemaId, dependencies)
38
- }
39
-
40
- return dependencies
41
- }
42
-
43
- insertSchemaBySchemaId (schema, schemaId) {
44
- if (
45
- this.schemas[schemaId] !== undefined &&
46
- !deepEqual(schema, this.schemas[schemaId].schema)
47
- ) {
48
- throw new Error(`There is already another schema with id ${schemaId}`)
49
- }
50
- this.schemas[schemaId] = { schema, anchors: {}, dependencies: [] }
51
- }
52
-
53
- insertSchemaByAnchor (schema, schemaId, anchor) {
54
- const { anchors } = this.schemas[schemaId]
55
- if (
56
- anchors[anchor] !== undefined &&
57
- !deepEqual(schema, anchors[anchor])
58
- ) {
59
- throw new Error(`There is already another schema with id ${schemaId}#${anchor}`)
60
- }
61
- anchors[anchor] = schema
62
- }
63
-
64
- insertSchemaSubschemas (schema, rootSchemaId) {
65
- const schemaId = schema.$id
66
- if (schemaId !== undefined && typeof schemaId === 'string') {
67
- if (schemaId.charAt(0) === '#') {
68
- this.insertSchemaByAnchor(schema, rootSchemaId, schemaId)
69
- } else {
70
- this.insertSchemaBySchemaId(schema, schemaId)
71
- rootSchemaId = schemaId
72
- }
73
- }
74
-
75
- const ref = schema.$ref
76
- if (ref !== undefined && typeof ref === 'string') {
77
- if (ref.charAt(0) !== '#') {
78
- const dependencySchemaId = ref.split('#')[0]
79
- this.schemas[rootSchemaId].dependencies.push(dependencySchemaId)
80
- }
81
- }
82
-
83
- for (const key in schema) {
84
- if (typeof schema[key] === 'object' && schema[key] !== null) {
85
- this.insertSchemaSubschemas(schema[key], rootSchemaId)
86
- }
87
- }
88
- }
89
- }
90
-
91
- function getDataByJSONPointer (data, jsonPointer) {
92
- const parts = jsonPointer.split('/')
93
- let current = data
94
- for (const part of parts) {
95
- if (part === '' || part === '#') continue
96
- if (typeof current !== 'object' || current === null) {
97
- return undefined
98
- }
99
- current = current[part]
100
- }
101
- return current
102
- }
103
-
104
- module.exports = RefResolver