@scalar/json-magic 0.8.1 β 0.8.3
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/CHANGELOG.md +22 -0
- package/dist/bundle/index.d.ts +1 -0
- package/dist/bundle/index.d.ts.map +1 -1
- package/dist/bundle/index.js.map +1 -1
- package/dist/bundle/plugins/browser.js.map +1 -1
- package/dist/bundle/plugins/node.d.ts +1 -1
- package/dist/bundle/plugins/node.js +1 -1
- package/dist/bundle/plugins/node.js.map +1 -1
- package/dist/bundle/value-generator.d.ts +2 -2
- package/dist/bundle/value-generator.d.ts.map +1 -1
- package/dist/bundle/value-generator.js +3 -3
- package/dist/bundle/value-generator.js.map +2 -2
- package/dist/dereference/index.d.ts.map +1 -1
- package/dist/dereference/index.js.map +2 -2
- package/dist/diff/index.d.ts +1 -1
- package/dist/diff/index.d.ts.map +1 -1
- package/dist/diff/index.js +1 -1
- package/dist/diff/index.js.map +2 -2
- package/dist/helpers/escape-json-pointer.d.ts +1 -1
- package/dist/helpers/escape-json-pointer.js.map +1 -1
- package/dist/magic-proxy/index.d.ts.map +1 -1
- package/dist/magic-proxy/index.js.map +2 -2
- package/dist/magic-proxy/proxy.d.ts +0 -1
- package/dist/magic-proxy/proxy.d.ts.map +1 -1
- package/dist/magic-proxy/proxy.js +1 -2
- package/dist/magic-proxy/proxy.js.map +2 -2
- package/package.json +12 -14
- package/.turbo/turbo-build.log +0 -10
- package/dist/helpers/generate-hash.d.ts +0 -11
- package/dist/helpers/generate-hash.d.ts.map +0 -1
- package/dist/helpers/generate-hash.js +0 -16
- package/dist/helpers/generate-hash.js.map +0 -7
- package/esbuild.ts +0 -15
- package/src/bundle/bundle.test.ts +0 -2921
- package/src/bundle/bundle.ts +0 -916
- package/src/bundle/create-limiter.test.ts +0 -28
- package/src/bundle/create-limiter.ts +0 -52
- package/src/bundle/index.ts +0 -3
- package/src/bundle/plugins/browser.ts +0 -4
- package/src/bundle/plugins/fetch-urls/index.test.ts +0 -144
- package/src/bundle/plugins/fetch-urls/index.ts +0 -105
- package/src/bundle/plugins/node.ts +0 -5
- package/src/bundle/plugins/parse-json/index.test.ts +0 -24
- package/src/bundle/plugins/parse-json/index.ts +0 -32
- package/src/bundle/plugins/parse-yaml/index.test.ts +0 -26
- package/src/bundle/plugins/parse-yaml/index.ts +0 -34
- package/src/bundle/plugins/read-files/index.test.ts +0 -36
- package/src/bundle/plugins/read-files/index.ts +0 -58
- package/src/bundle/value-generator.test.ts +0 -165
- package/src/bundle/value-generator.ts +0 -143
- package/src/dereference/dereference.test.ts +0 -145
- package/src/dereference/dereference.ts +0 -84
- package/src/dereference/index.ts +0 -2
- package/src/diff/apply.test.ts +0 -262
- package/src/diff/apply.ts +0 -83
- package/src/diff/diff.test.ts +0 -328
- package/src/diff/diff.ts +0 -93
- package/src/diff/index.test.ts +0 -150
- package/src/diff/index.ts +0 -5
- package/src/diff/merge.test.ts +0 -1109
- package/src/diff/merge.ts +0 -136
- package/src/diff/trie.test.ts +0 -30
- package/src/diff/trie.ts +0 -113
- package/src/diff/utils.test.ts +0 -169
- package/src/diff/utils.ts +0 -111
- package/src/helpers/convert-to-local-ref.test.ts +0 -211
- package/src/helpers/convert-to-local-ref.ts +0 -43
- package/src/helpers/escape-json-pointer.test.ts +0 -13
- package/src/helpers/escape-json-pointer.ts +0 -8
- package/src/helpers/generate-hash.test.ts +0 -74
- package/src/helpers/generate-hash.ts +0 -29
- package/src/helpers/get-schemas.test.ts +0 -356
- package/src/helpers/get-schemas.ts +0 -80
- package/src/helpers/get-segments-from-path.test.ts +0 -17
- package/src/helpers/get-segments-from-path.ts +0 -17
- package/src/helpers/get-value-by-path.test.ts +0 -338
- package/src/helpers/get-value-by-path.ts +0 -44
- package/src/helpers/is-json-object.ts +0 -31
- package/src/helpers/is-object.test.ts +0 -27
- package/src/helpers/is-object.ts +0 -4
- package/src/helpers/is-yaml.ts +0 -18
- package/src/helpers/json-path-utils.test.ts +0 -57
- package/src/helpers/json-path-utils.ts +0 -50
- package/src/helpers/normalize.test.ts +0 -92
- package/src/helpers/normalize.ts +0 -35
- package/src/helpers/unescape-json-pointer.test.ts +0 -23
- package/src/helpers/unescape-json-pointer.ts +0 -9
- package/src/magic-proxy/index.ts +0 -2
- package/src/magic-proxy/proxy.test.ts +0 -1987
- package/src/magic-proxy/proxy.ts +0 -323
- package/src/types.ts +0 -1
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -16
- package/vite.config.ts +0 -8
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { convertToLocalRef } from './convert-to-local-ref'
|
|
4
|
-
|
|
5
|
-
describe('convertToLocalRef', () => {
|
|
6
|
-
const schemas = new Map([
|
|
7
|
-
['https://example.com/schema1.json', '/components/schemas/Schema1'],
|
|
8
|
-
['https://example.com/schema2.json', '/components/schemas/Schema2'],
|
|
9
|
-
['https://example.com/schema1.json#anchor1', '/components/schemas/Schema1/definitions/Anchor1'],
|
|
10
|
-
['https://example.com/schema2.json#anchor2', '/components/schemas/Schema2/definitions/Anchor2'],
|
|
11
|
-
['https://example.com/current.json#currentAnchor', '/components/schemas/Current/definitions/CurrentAnchor'],
|
|
12
|
-
])
|
|
13
|
-
|
|
14
|
-
const currentContext = 'https://example.com/current.json'
|
|
15
|
-
|
|
16
|
-
describe('external references with baseUrl', () => {
|
|
17
|
-
it('should resolve external reference without path or anchor', () => {
|
|
18
|
-
const result = convertToLocalRef('https://example.com/schema1.json', currentContext, schemas)
|
|
19
|
-
|
|
20
|
-
expect(result).toBe('/components/schemas/Schema1')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('should resolve external reference with JSON pointer path', () => {
|
|
24
|
-
const result = convertToLocalRef('https://example.com/schema1.json#/definitions/User', currentContext, schemas)
|
|
25
|
-
|
|
26
|
-
expect(result).toBe('/components/schemas/Schema1/definitions/User')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('should resolve external reference with anchor', () => {
|
|
30
|
-
const result = convertToLocalRef('https://example.com/schema1.json#anchor1', currentContext, schemas)
|
|
31
|
-
|
|
32
|
-
expect(result).toBe('/components/schemas/Schema1/definitions/Anchor1')
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('should return undefined for external reference not in schemas', () => {
|
|
36
|
-
const result = convertToLocalRef('https://example.com/unknown.json', currentContext, schemas)
|
|
37
|
-
|
|
38
|
-
expect(result).toBeUndefined()
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('should return undefined for external reference with unknown anchor', () => {
|
|
42
|
-
const result = convertToLocalRef('https://example.com/schema1.json#unknownAnchor', currentContext, schemas)
|
|
43
|
-
|
|
44
|
-
expect(result).toBeUndefined()
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
describe('local references without baseUrl', () => {
|
|
49
|
-
it('should resolve local JSON pointer path', () => {
|
|
50
|
-
const result = convertToLocalRef('#/definitions/User', currentContext, schemas)
|
|
51
|
-
|
|
52
|
-
expect(result).toBe('definitions/User')
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should resolve local JSON pointer path with multiple segments', () => {
|
|
56
|
-
const result = convertToLocalRef('#/components/schemas/User/properties/name', currentContext, schemas)
|
|
57
|
-
|
|
58
|
-
expect(result).toBe('components/schemas/User/properties/name')
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('should resolve local anchor reference', () => {
|
|
62
|
-
const result = convertToLocalRef('#currentAnchor', currentContext, schemas)
|
|
63
|
-
|
|
64
|
-
expect(result).toBe('/components/schemas/Current/definitions/CurrentAnchor')
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('should return undefined for local anchor not in schemas', () => {
|
|
68
|
-
const result = convertToLocalRef('#unknownAnchor', currentContext, schemas)
|
|
69
|
-
|
|
70
|
-
expect(result).toBeUndefined()
|
|
71
|
-
})
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
describe('edge cases', () => {
|
|
75
|
-
it('should return undefined for empty reference', () => {
|
|
76
|
-
const result = convertToLocalRef('', currentContext, schemas)
|
|
77
|
-
|
|
78
|
-
expect(result).toBeUndefined()
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('should return undefined for reference with only hash', () => {
|
|
82
|
-
const result = convertToLocalRef('#', currentContext, schemas)
|
|
83
|
-
|
|
84
|
-
expect(result).toBeUndefined()
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('should return undefined for reference with only baseUrl and hash', () => {
|
|
88
|
-
const result = convertToLocalRef('https://example.com/schema1.json#', currentContext, schemas)
|
|
89
|
-
|
|
90
|
-
expect(result).toBe('/components/schemas/Schema1')
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('should handle empty currentContext', () => {
|
|
94
|
-
const result = convertToLocalRef('#anchor', '', schemas)
|
|
95
|
-
|
|
96
|
-
expect(result).toBeUndefined()
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it('should handle empty schemas map', () => {
|
|
100
|
-
const emptySchemas = new Map()
|
|
101
|
-
const result = convertToLocalRef('https://example.com/schema1.json', currentContext, emptySchemas)
|
|
102
|
-
|
|
103
|
-
expect(result).toBeUndefined()
|
|
104
|
-
})
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
describe('complex scenarios', () => {
|
|
108
|
-
it('should handle nested JSON pointer paths', () => {
|
|
109
|
-
const result = convertToLocalRef(
|
|
110
|
-
'https://example.com/schema1.json#/definitions/User/properties/address/properties/street',
|
|
111
|
-
currentContext,
|
|
112
|
-
schemas,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
expect(result).toBe('/components/schemas/Schema1/definitions/User/properties/address/properties/street')
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it('should handle anchor with special characters', () => {
|
|
119
|
-
const schemasWithSpecialChars = new Map([
|
|
120
|
-
['https://example.com/schema1.json', '/components/schemas/Schema1'],
|
|
121
|
-
[
|
|
122
|
-
'https://example.com/schema1.json#anchor-with-dashes',
|
|
123
|
-
'/components/schemas/Schema1/definitions/AnchorWithDashes',
|
|
124
|
-
],
|
|
125
|
-
[
|
|
126
|
-
'https://example.com/schema1.json#anchor_with_underscores',
|
|
127
|
-
'/components/schemas/Schema1/definitions/AnchorWithUnderscores',
|
|
128
|
-
],
|
|
129
|
-
])
|
|
130
|
-
|
|
131
|
-
const result1 = convertToLocalRef(
|
|
132
|
-
'https://example.com/schema1.json#anchor-with-dashes',
|
|
133
|
-
currentContext,
|
|
134
|
-
schemasWithSpecialChars,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
const result2 = convertToLocalRef(
|
|
138
|
-
'https://example.com/schema1.json#anchor_with_underscores',
|
|
139
|
-
currentContext,
|
|
140
|
-
schemasWithSpecialChars,
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
expect(result1).toBe('/components/schemas/Schema1/definitions/AnchorWithDashes')
|
|
144
|
-
expect(result2).toBe('/components/schemas/Schema1/definitions/AnchorWithUnderscores')
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
it('should handle different schema contexts', () => {
|
|
148
|
-
const differentContext = 'https://example.com/different.json'
|
|
149
|
-
const schemasWithDifferentContext = new Map([
|
|
150
|
-
[
|
|
151
|
-
'https://example.com/different.json#differentAnchor',
|
|
152
|
-
'/components/schemas/Different/definitions/DifferentAnchor',
|
|
153
|
-
],
|
|
154
|
-
])
|
|
155
|
-
|
|
156
|
-
const result = convertToLocalRef('#differentAnchor', differentContext, schemasWithDifferentContext)
|
|
157
|
-
|
|
158
|
-
expect(result).toBe('/components/schemas/Different/definitions/DifferentAnchor')
|
|
159
|
-
})
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
describe('real-world examples', () => {
|
|
163
|
-
it('should handle OpenAPI component references', () => {
|
|
164
|
-
const openApiSchemas = new Map([
|
|
165
|
-
['https://api.example.com/schemas/user.json', '/components/schemas/User'],
|
|
166
|
-
['https://api.example.com/schemas/user.json#/properties/id', '/components/schemas/User/properties/id'],
|
|
167
|
-
['https://api.example.com/schemas/user.json#userProfile', '/components/schemas/User/definitions/UserProfile'],
|
|
168
|
-
])
|
|
169
|
-
|
|
170
|
-
const result1 = convertToLocalRef(
|
|
171
|
-
'https://api.example.com/schemas/user.json',
|
|
172
|
-
'https://api.example.com/openapi.json',
|
|
173
|
-
openApiSchemas,
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
const result2 = convertToLocalRef(
|
|
177
|
-
'https://api.example.com/schemas/user.json#/properties/name',
|
|
178
|
-
'https://api.example.com/openapi.json',
|
|
179
|
-
openApiSchemas,
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
const result3 = convertToLocalRef(
|
|
183
|
-
'https://api.example.com/schemas/user.json#userProfile',
|
|
184
|
-
'https://api.example.com/openapi.json',
|
|
185
|
-
openApiSchemas,
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
expect(result1).toBe('/components/schemas/User')
|
|
189
|
-
expect(result2).toBe('/components/schemas/User/properties/name')
|
|
190
|
-
expect(result3).toBe('/components/schemas/User/definitions/UserProfile')
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
it('should handle local component references in OpenAPI', () => {
|
|
194
|
-
const openApiSchemas = new Map([
|
|
195
|
-
['https://api.example.com/openapi.json#userSchema', '/components/schemas/User'],
|
|
196
|
-
['https://api.example.com/openapi.json#addressSchema', '/components/schemas/Address'],
|
|
197
|
-
])
|
|
198
|
-
|
|
199
|
-
const result1 = convertToLocalRef('#userSchema', 'https://api.example.com/openapi.json', openApiSchemas)
|
|
200
|
-
|
|
201
|
-
const result2 = convertToLocalRef(
|
|
202
|
-
'#/components/schemas/User/properties/name',
|
|
203
|
-
'https://api.example.com/openapi.json',
|
|
204
|
-
openApiSchemas,
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
expect(result1).toBe('/components/schemas/User')
|
|
208
|
-
expect(result2).toBe('components/schemas/User/properties/name')
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
})
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Translates a JSON Reference ($ref) to a local object path within the root schema.
|
|
3
|
-
*
|
|
4
|
-
* @param ref - The JSON Reference string (e.g., "#/foo/bar", "other.json#/baz", "other.json#anchor")
|
|
5
|
-
* @param currentContext - The current base context (usually the $id of the current schema or parent)
|
|
6
|
-
* @param schemas - A map of schema identifiers ($id, $anchor) to their local object paths
|
|
7
|
-
* @returns The local object path as a string, or undefined if the reference cannot be resolved
|
|
8
|
-
*/
|
|
9
|
-
export const convertToLocalRef = (
|
|
10
|
-
ref: string,
|
|
11
|
-
currentContext: string,
|
|
12
|
-
schemas: Map<string, string>,
|
|
13
|
-
): string | undefined => {
|
|
14
|
-
// Split the reference into base URL and path/anchor (e.g., "foo.json#/bar" => ["foo.json", "/bar"])
|
|
15
|
-
const [baseUrl, pathOrAnchor] = ref.split('#', 2)
|
|
16
|
-
|
|
17
|
-
if (baseUrl) {
|
|
18
|
-
if (!schemas.has(baseUrl)) {
|
|
19
|
-
return undefined
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!pathOrAnchor) {
|
|
23
|
-
return schemas.get(baseUrl)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// If the pathOrAnchor is a JSON pointer, we need to append it to the baseUrl
|
|
27
|
-
if (pathOrAnchor.startsWith('/')) {
|
|
28
|
-
return `${schemas.get(baseUrl)}${pathOrAnchor}`
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// If the pathOrAnchor is an anchor, we need to return the anchor
|
|
32
|
-
return schemas.get(`${baseUrl}#${pathOrAnchor}`)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (pathOrAnchor) {
|
|
36
|
-
if (pathOrAnchor.startsWith('/')) {
|
|
37
|
-
return pathOrAnchor.slice(1)
|
|
38
|
-
}
|
|
39
|
-
return schemas.get(`${currentContext}#${pathOrAnchor}`)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return undefined
|
|
43
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { escapeJsonPointer } from './escape-json-pointer'
|
|
4
|
-
|
|
5
|
-
describe('escapeJsonPointer', () => {
|
|
6
|
-
it('should escape a slash', () => {
|
|
7
|
-
expect(escapeJsonPointer('application/json')).toBe('application~1json')
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
it('should escape multiple slashes', () => {
|
|
11
|
-
expect(escapeJsonPointer('/api/users/{id}/reports')).toBe('~1api~1users~1{id}~1reports')
|
|
12
|
-
})
|
|
13
|
-
})
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { generateHash } from './generate-hash'
|
|
4
|
-
|
|
5
|
-
describe('generateHash', () => {
|
|
6
|
-
it('generates a hash from a simple string', async () => {
|
|
7
|
-
const result = await generateHash('hello world')
|
|
8
|
-
|
|
9
|
-
// Should return a non-empty string
|
|
10
|
-
expect(result).toBeTruthy()
|
|
11
|
-
expect(typeof result).toBe('string')
|
|
12
|
-
expect(result.length).toBeGreaterThan(0)
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('produces consistent hashes for the same input', async () => {
|
|
16
|
-
const input = 'consistent-test-string'
|
|
17
|
-
const hash1 = await generateHash(input)
|
|
18
|
-
const hash2 = await generateHash(input)
|
|
19
|
-
const hash3 = await generateHash(input)
|
|
20
|
-
|
|
21
|
-
// Same input should always produce the same hash
|
|
22
|
-
expect(hash1).toBe(hash2)
|
|
23
|
-
expect(hash2).toBe(hash3)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('produces different hashes for different inputs', async () => {
|
|
27
|
-
const hash1 = await generateHash('first string')
|
|
28
|
-
const hash2 = await generateHash('second string')
|
|
29
|
-
const hash3 = await generateHash('first strinG') // Case-sensitive
|
|
30
|
-
|
|
31
|
-
// Different inputs should produce different hashes
|
|
32
|
-
expect(hash1).not.toBe(hash2)
|
|
33
|
-
expect(hash1).not.toBe(hash3)
|
|
34
|
-
expect(hash2).not.toBe(hash3)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('handles empty string', async () => {
|
|
38
|
-
const result = await generateHash('')
|
|
39
|
-
|
|
40
|
-
// Should handle empty strings without throwing
|
|
41
|
-
expect(result).toBeTruthy()
|
|
42
|
-
expect(typeof result).toBe('string')
|
|
43
|
-
|
|
44
|
-
// Empty string should produce a consistent hash
|
|
45
|
-
const result2 = await generateHash('')
|
|
46
|
-
expect(result).toBe(result2)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('handles special characters and unicode', async () => {
|
|
50
|
-
const inputs = [
|
|
51
|
-
'π emoji test',
|
|
52
|
-
'special chars: !@#$%^&*()',
|
|
53
|
-
'unicode: γγγ«γ‘γ―δΈη',
|
|
54
|
-
'newlines\nand\ttabs',
|
|
55
|
-
'mixed: πΎ special!@# unicode: δ½ ε₯½',
|
|
56
|
-
]
|
|
57
|
-
|
|
58
|
-
const hashes = await Promise.all(inputs.map((input) => generateHash(input)))
|
|
59
|
-
|
|
60
|
-
// All should produce valid hashes
|
|
61
|
-
hashes.forEach((hash) => {
|
|
62
|
-
expect(hash).toBeTruthy()
|
|
63
|
-
expect(typeof hash).toBe('string')
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
// All should be unique
|
|
67
|
-
const uniqueHashes = new Set(hashes)
|
|
68
|
-
expect(uniqueHashes.size).toBe(inputs.length)
|
|
69
|
-
|
|
70
|
-
// Should be consistent on repeated calls
|
|
71
|
-
const repeatedHash = await generateHash('π emoji test')
|
|
72
|
-
expect(repeatedHash).toBe(hashes[0])
|
|
73
|
-
})
|
|
74
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import xxhash from 'xxhash-wasm'
|
|
2
|
-
|
|
3
|
-
let hasherInstance: Awaited<ReturnType<typeof xxhash>> | null = null
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Initialize the xxhash hasher instance lazily
|
|
7
|
-
*
|
|
8
|
-
* This is just a workaround because we cannot use top level await in a UMD module (standalone references)
|
|
9
|
-
*/
|
|
10
|
-
const getHasher = async () => {
|
|
11
|
-
if (!hasherInstance) {
|
|
12
|
-
hasherInstance = await xxhash()
|
|
13
|
-
}
|
|
14
|
-
return hasherInstance
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Generate a hash from a string using the xxhash algorithm
|
|
19
|
-
*
|
|
20
|
-
* We cannot use crypto.subtle because it is only available in secure contexts (HTTPS) or on localhost.
|
|
21
|
-
* So this is just a wrapper around the xxhash-wasm library instead.
|
|
22
|
-
*
|
|
23
|
-
* @param input - The string to hash
|
|
24
|
-
* @returns A Promise that resolves to the hash of the input string
|
|
25
|
-
*/
|
|
26
|
-
export const generateHash = async (input: string): Promise<string> => {
|
|
27
|
-
const { h64ToString } = await getHasher()
|
|
28
|
-
return h64ToString(input)
|
|
29
|
-
}
|