@scalar/json-magic 0.8.0 β†’ 0.8.2

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.
@@ -1,10 +1,10 @@
1
1
 
2
- > @scalar/json-magic@0.8.0 build /home/runner/work/scalar/scalar/packages/json-magic
2
+ > @scalar/json-magic@0.8.2 build /home/runner/work/scalar/scalar/packages/json-magic
3
3
  > scalar-build-esbuild
4
4
 
5
- @scalar/json-magic: Build completed in 31.84ms
5
+ @scalar/json-magic: Build completed in 42.51ms
6
6
 
7
- > @scalar/json-magic@0.8.0 types:build /home/runner/work/scalar/scalar/packages/json-magic
7
+ > @scalar/json-magic@0.8.2 types:build /home/runner/work/scalar/scalar/packages/json-magic
8
8
  > scalar-types-build
9
9
 
10
- Types build completed in 1.68s
10
+ Types build completed in 2.81s
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @scalar/json-magic
2
2
 
3
+ ## 0.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#7392](https://github.com/scalar/scalar/pull/7392) [`d86f1d6`](https://github.com/scalar/scalar/commit/d86f1d6911ecbca70b011a2a0efb6d6e0eca59bb) Thanks [@amritk](https://github.com/amritk)! - fix: move away from wasm hashing algo
8
+
9
+ - Updated dependencies [[`d86f1d6`](https://github.com/scalar/scalar/commit/d86f1d6911ecbca70b011a2a0efb6d6e0eca59bb), [`cded2d6`](https://github.com/scalar/scalar/commit/cded2d6c087418c3c44731d344d0827a87b78b74)]:
10
+ - @scalar/helpers@0.1.2
11
+
12
+ ## 0.8.1
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies [[`9c9dbba`](https://github.com/scalar/scalar/commit/9c9dbbaa940667303f0ace59469fd78c2a741937), [`4bec1ba`](https://github.com/scalar/scalar/commit/4bec1ba332e919c4ee32dcfbfb07bd8ee42c4d74)]:
17
+ - @scalar/helpers@0.1.1
18
+
3
19
  ## 0.8.0
4
20
 
5
21
  ### Minor Changes
@@ -11,9 +11,9 @@
11
11
  * @returns A Promise that resolves to a 7-character hexadecimal hash with at least one letter
12
12
  * @example
13
13
  * // Returns "2ae91d7"
14
- * await getHash("https://example.com/schema.json")
14
+ * getHash("https://example.com/schema.json")
15
15
  */
16
- export declare function getHash(value: string): Promise<string>;
16
+ export declare function getHash(value: string): string;
17
17
  /**
18
18
  * Generates a unique compressed value for a string, handling collisions by recursively compressing
19
19
  * until a unique value is found. This is used to create unique identifiers for external
@@ -1 +1 @@
1
- {"version":3,"file":"value-generator.d.ts","sourceRoot":"","sources":["../../src/bundle/value-generator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EACrD,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,mBAAmB,CAAC,EAAE,MAAM,EAC5B,KAAK,SAAI,mBAoBV;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EACrD,mBAAmB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMvC;;;;;;;;;;;;OAYG;sBACqB,MAAM;CAqBjC,CAAA"}
1
+ {"version":3,"file":"value-generator.d.ts","sourceRoot":"","sources":["../../src/bundle/value-generator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EACrD,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,mBAAmB,CAAC,EAAE,MAAM,EAC5B,KAAK,SAAI,mBAoBV;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EACrD,mBAAmB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMvC;;;;;;;;;;;;OAYG;sBACqB,MAAM;CAqBjC,CAAA"}
@@ -1,6 +1,6 @@
1
- import { generateHash } from "../helpers/generate-hash.js";
2
- async function getHash(value) {
3
- const hashHex = await generateHash(value);
1
+ import { generateHash } from "@scalar/helpers/string/generate-hash";
2
+ function getHash(value) {
3
+ const hashHex = generateHash(value);
4
4
  const hash = hashHex.substring(0, 7);
5
5
  return hash.match(/^\d+$/) ? "a" + hash.substring(1) : hash;
6
6
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/bundle/value-generator.ts"],
4
- "sourcesContent": ["import { generateHash } from '@/helpers/generate-hash'\n\n/**\n * Generates a short hash from a string value using xxhash.\n *\n * This function is used to create unique identifiers for external references\n * while keeping the hash length manageable. It uses xxhash-wasm instead of\n * crypto.subtle because crypto.subtle is only available in secure contexts (HTTPS) or on localhost.\n * Returns the first 7 characters of the hash string.\n * If the hash would be all numbers, it ensures at least one letter is included.\n *\n * @param value - The string to hash\n * @returns A Promise that resolves to a 7-character hexadecimal hash with at least one letter\n * @example\n * // Returns \"2ae91d7\"\n * await getHash(\"https://example.com/schema.json\")\n */\nexport async function getHash(value: string): Promise<string> {\n // Hash the data using xxhash\n const hashHex = await generateHash(value)\n\n // Return first 7 characters of the hash, ensuring at least one letter\n const hash = hashHex.substring(0, 7)\n return hash.match(/^\\d+$/) ? 'a' + hash.substring(1) : hash\n}\n\n/**\n * Generates a unique compressed value for a string, handling collisions by recursively compressing\n * until a unique value is found. This is used to create unique identifiers for external\n * references in the bundled OpenAPI document.\n *\n * @param compress - Function that generates a compressed value from a string\n * @param value - The original string value to compress\n * @param compressedToValue - Object mapping compressed values to their original values\n * @param prevCompressedValue - Optional previous compressed value to use as input for generating a new value\n * @param depth - Current recursion depth to prevent infinite loops\n * @returns A unique compressed value that doesn't conflict with existing values\n *\n * @example\n * const valueMap = {}\n * // First call generates compressed value for \"example.com/schema.json\"\n * const value1 = await generateUniqueValue(compress, \"example.com/schema.json\", valueMap)\n * // Returns something like \"2ae91d7\"\n *\n * // Second call with same value returns same compressed value\n * const value2 = await generateUniqueValue(compress, \"example.com/schema.json\", valueMap)\n * // Returns same value as value1\n *\n * // Call with different value generates new unique compressed value\n * const value3 = await generateUniqueValue(compress, \"example.com/other.json\", valueMap)\n * // Returns different value like \"3bf82e9\"\n */\nexport async function generateUniqueValue(\n compress: (value: string) => Promise<string> | string,\n value: string,\n compressedToValue: Record<string, string>,\n prevCompressedValue?: string,\n depth = 0,\n) {\n // Prevent infinite recursion by limiting depth\n const MAX_DEPTH = 100\n\n if (depth >= MAX_DEPTH) {\n throw 'Can not generate unique compressed values'\n }\n\n // Compress the value, using previous compressed value if provided\n const compressedValue = await compress(prevCompressedValue ?? value)\n\n // Handle collision by recursively trying with compressed value as input\n if (compressedToValue[compressedValue] !== undefined && compressedToValue[compressedValue] !== value) {\n return generateUniqueValue(compress, value, compressedToValue, compressedValue, depth + 1)\n }\n\n // Store mapping and return unique compressed value\n compressedToValue[compressedValue] = value\n return compressedValue\n}\n\n/**\n * Factory function that creates a value generator with caching capabilities.\n * The generator maintains a bidirectional mapping between original values and their compressed forms.\n *\n * @param compress - Function that generates a compressed value from a string\n * @param compressedToValue - Initial mapping of compressed values to their original values\n * @returns An object with a generate method that produces unique compressed values\n *\n * @example\n * const compress = (value) => value.substring(0, 6) // Simple compression example\n * const initialMap = { 'abc123': 'example.com/schema.json' }\n * const generator = uniqueValueGeneratorFactory(compress, initialMap)\n *\n * // Generate compressed value for new string\n * const compressed = await generator.generate('example.com/other.json')\n * // Returns something like 'example'\n *\n * // Generate compressed value for existing string\n * const cached = await generator.generate('example.com/schema.json')\n * // Returns 'abc123' from cache\n */\nexport const uniqueValueGeneratorFactory = (\n compress: (value: string) => Promise<string> | string,\n compressedToValue: Record<string, string>,\n) => {\n // Create a reverse mapping from original values to their compressed forms\n const valueToCompressed = Object.fromEntries(Object.entries(compressedToValue).map(([key, value]) => [value, key]))\n\n return {\n /**\n * Generates a unique compressed value for the given input string.\n * First checks if a compressed value already exists in the cache.\n * If not, generates a new unique compressed value and stores it in the cache.\n *\n * @param value - The original string value to compress\n * @returns A Promise that resolves to the compressed string value\n *\n * @example\n * const generator = uniqueValueGeneratorFactory(compress, {})\n * const compressed = await generator.generate('example.com/schema.json')\n * // Returns a unique compressed value like 'example'\n */\n generate: async (value: string) => {\n // Check if we already have a compressed value for this input\n const cache = valueToCompressed[value]\n if (cache) {\n return cache\n }\n\n // Generate a new unique compressed value\n const generatedValue = await generateUniqueValue(compress, value, compressedToValue)\n\n // Ensure the generated string contains at least one non-numeric character\n // This prevents the `setValueAtPath` function from interpreting the value as an array index\n // by forcing it to be treated as an object property name\n const compressedValue = generatedValue.match(/^\\d+$/) ? `a${generatedValue}` : generatedValue\n\n // Store the new mapping in our cache\n valueToCompressed[value] = compressedValue\n\n return compressedValue\n },\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAiB7B,eAAsB,QAAQ,OAAgC;AAE5D,QAAM,UAAU,MAAM,aAAa,KAAK;AAGxC,QAAM,OAAO,QAAQ,UAAU,GAAG,CAAC;AACnC,SAAO,KAAK,MAAM,OAAO,IAAI,MAAM,KAAK,UAAU,CAAC,IAAI;AACzD;AA4BA,eAAsB,oBACpB,UACA,OACA,mBACA,qBACA,QAAQ,GACR;AAEA,QAAM,YAAY;AAElB,MAAI,SAAS,WAAW;AACtB,UAAM;AAAA,EACR;AAGA,QAAM,kBAAkB,MAAM,SAAS,uBAAuB,KAAK;AAGnE,MAAI,kBAAkB,eAAe,MAAM,UAAa,kBAAkB,eAAe,MAAM,OAAO;AACpG,WAAO,oBAAoB,UAAU,OAAO,mBAAmB,iBAAiB,QAAQ,CAAC;AAAA,EAC3F;AAGA,oBAAkB,eAAe,IAAI;AACrC,SAAO;AACT;AAuBO,MAAM,8BAA8B,CACzC,UACA,sBACG;AAEH,QAAM,oBAAoB,OAAO,YAAY,OAAO,QAAQ,iBAAiB,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;AAElH,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcL,UAAU,OAAO,UAAkB;AAEjC,YAAM,QAAQ,kBAAkB,KAAK;AACrC,UAAI,OAAO;AACT,eAAO;AAAA,MACT;AAGA,YAAM,iBAAiB,MAAM,oBAAoB,UAAU,OAAO,iBAAiB;AAKnF,YAAM,kBAAkB,eAAe,MAAM,OAAO,IAAI,IAAI,cAAc,KAAK;AAG/E,wBAAkB,KAAK,IAAI;AAE3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { generateHash } from '@scalar/helpers/string/generate-hash'\n\n/**\n * Generates a short hash from a string value using xxhash.\n *\n * This function is used to create unique identifiers for external references\n * while keeping the hash length manageable. It uses xxhash-wasm instead of\n * crypto.subtle because crypto.subtle is only available in secure contexts (HTTPS) or on localhost.\n * Returns the first 7 characters of the hash string.\n * If the hash would be all numbers, it ensures at least one letter is included.\n *\n * @param value - The string to hash\n * @returns A Promise that resolves to a 7-character hexadecimal hash with at least one letter\n * @example\n * // Returns \"2ae91d7\"\n * getHash(\"https://example.com/schema.json\")\n */\nexport function getHash(value: string): string {\n // Hash the data using xxhash\n const hashHex = generateHash(value)\n\n // Return first 7 characters of the hash, ensuring at least one letter\n const hash = hashHex.substring(0, 7)\n return hash.match(/^\\d+$/) ? 'a' + hash.substring(1) : hash\n}\n\n/**\n * Generates a unique compressed value for a string, handling collisions by recursively compressing\n * until a unique value is found. This is used to create unique identifiers for external\n * references in the bundled OpenAPI document.\n *\n * @param compress - Function that generates a compressed value from a string\n * @param value - The original string value to compress\n * @param compressedToValue - Object mapping compressed values to their original values\n * @param prevCompressedValue - Optional previous compressed value to use as input for generating a new value\n * @param depth - Current recursion depth to prevent infinite loops\n * @returns A unique compressed value that doesn't conflict with existing values\n *\n * @example\n * const valueMap = {}\n * // First call generates compressed value for \"example.com/schema.json\"\n * const value1 = await generateUniqueValue(compress, \"example.com/schema.json\", valueMap)\n * // Returns something like \"2ae91d7\"\n *\n * // Second call with same value returns same compressed value\n * const value2 = await generateUniqueValue(compress, \"example.com/schema.json\", valueMap)\n * // Returns same value as value1\n *\n * // Call with different value generates new unique compressed value\n * const value3 = await generateUniqueValue(compress, \"example.com/other.json\", valueMap)\n * // Returns different value like \"3bf82e9\"\n */\nexport async function generateUniqueValue(\n compress: (value: string) => Promise<string> | string,\n value: string,\n compressedToValue: Record<string, string>,\n prevCompressedValue?: string,\n depth = 0,\n) {\n // Prevent infinite recursion by limiting depth\n const MAX_DEPTH = 100\n\n if (depth >= MAX_DEPTH) {\n throw 'Can not generate unique compressed values'\n }\n\n // Compress the value, using previous compressed value if provided\n const compressedValue = await compress(prevCompressedValue ?? value)\n\n // Handle collision by recursively trying with compressed value as input\n if (compressedToValue[compressedValue] !== undefined && compressedToValue[compressedValue] !== value) {\n return generateUniqueValue(compress, value, compressedToValue, compressedValue, depth + 1)\n }\n\n // Store mapping and return unique compressed value\n compressedToValue[compressedValue] = value\n return compressedValue\n}\n\n/**\n * Factory function that creates a value generator with caching capabilities.\n * The generator maintains a bidirectional mapping between original values and their compressed forms.\n *\n * @param compress - Function that generates a compressed value from a string\n * @param compressedToValue - Initial mapping of compressed values to their original values\n * @returns An object with a generate method that produces unique compressed values\n *\n * @example\n * const compress = (value) => value.substring(0, 6) // Simple compression example\n * const initialMap = { 'abc123': 'example.com/schema.json' }\n * const generator = uniqueValueGeneratorFactory(compress, initialMap)\n *\n * // Generate compressed value for new string\n * const compressed = await generator.generate('example.com/other.json')\n * // Returns something like 'example'\n *\n * // Generate compressed value for existing string\n * const cached = await generator.generate('example.com/schema.json')\n * // Returns 'abc123' from cache\n */\nexport const uniqueValueGeneratorFactory = (\n compress: (value: string) => Promise<string> | string,\n compressedToValue: Record<string, string>,\n) => {\n // Create a reverse mapping from original values to their compressed forms\n const valueToCompressed = Object.fromEntries(Object.entries(compressedToValue).map(([key, value]) => [value, key]))\n\n return {\n /**\n * Generates a unique compressed value for the given input string.\n * First checks if a compressed value already exists in the cache.\n * If not, generates a new unique compressed value and stores it in the cache.\n *\n * @param value - The original string value to compress\n * @returns A Promise that resolves to the compressed string value\n *\n * @example\n * const generator = uniqueValueGeneratorFactory(compress, {})\n * const compressed = await generator.generate('example.com/schema.json')\n * // Returns a unique compressed value like 'example'\n */\n generate: async (value: string) => {\n // Check if we already have a compressed value for this input\n const cache = valueToCompressed[value]\n if (cache) {\n return cache\n }\n\n // Generate a new unique compressed value\n const generatedValue = await generateUniqueValue(compress, value, compressedToValue)\n\n // Ensure the generated string contains at least one non-numeric character\n // This prevents the `setValueAtPath` function from interpreting the value as an array index\n // by forcing it to be treated as an object property name\n const compressedValue = generatedValue.match(/^\\d+$/) ? `a${generatedValue}` : generatedValue\n\n // Store the new mapping in our cache\n valueToCompressed[value] = compressedValue\n\n return compressedValue\n },\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAiBtB,SAAS,QAAQ,OAAuB;AAE7C,QAAM,UAAU,aAAa,KAAK;AAGlC,QAAM,OAAO,QAAQ,UAAU,GAAG,CAAC;AACnC,SAAO,KAAK,MAAM,OAAO,IAAI,MAAM,KAAK,UAAU,CAAC,IAAI;AACzD;AA4BA,eAAsB,oBACpB,UACA,OACA,mBACA,qBACA,QAAQ,GACR;AAEA,QAAM,YAAY;AAElB,MAAI,SAAS,WAAW;AACtB,UAAM;AAAA,EACR;AAGA,QAAM,kBAAkB,MAAM,SAAS,uBAAuB,KAAK;AAGnE,MAAI,kBAAkB,eAAe,MAAM,UAAa,kBAAkB,eAAe,MAAM,OAAO;AACpG,WAAO,oBAAoB,UAAU,OAAO,mBAAmB,iBAAiB,QAAQ,CAAC;AAAA,EAC3F;AAGA,oBAAkB,eAAe,IAAI;AACrC,SAAO;AACT;AAuBO,MAAM,8BAA8B,CACzC,UACA,sBACG;AAEH,QAAM,oBAAoB,OAAO,YAAY,OAAO,QAAQ,iBAAiB,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;AAElH,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcL,UAAU,OAAO,UAAkB;AAEjC,YAAM,QAAQ,kBAAkB,KAAK;AACrC,UAAI,OAAO;AACT,eAAO;AAAA,MACT;AAGA,YAAM,iBAAiB,MAAM,oBAAoB,UAAU,OAAO,iBAAiB;AAKnF,YAAM,kBAAkB,eAAe,MAAM,OAAO,IAAI,IAAI,cAAc,KAAK;AAG/E,wBAAkB,KAAK,IAAI;AAE3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "git+https://github.com/scalar/scalar.git",
11
11
  "directory": "packages/json-magic"
12
12
  },
13
- "version": "0.8.0",
13
+ "version": "0.8.2",
14
14
  "engines": {
15
15
  "node": ">=20"
16
16
  },
@@ -58,14 +58,13 @@
58
58
  }
59
59
  },
60
60
  "dependencies": {
61
- "xxhash-wasm": "^1.1.0",
62
61
  "yaml": "2.8.0",
63
- "@scalar/helpers": "0.1.0"
62
+ "@scalar/helpers": "0.1.2"
64
63
  },
65
64
  "devDependencies": {
66
65
  "fastify": "^5.3.3",
67
66
  "vite": "7.1.11",
68
- "@scalar/build-tooling": "0.2.8"
67
+ "@scalar/build-tooling": "0.3.0"
69
68
  },
70
69
  "scripts": {
71
70
  "build": "scalar-build-esbuild",
@@ -1,6 +1,5 @@
1
1
  import { randomUUID } from 'node:crypto'
2
2
  import fs from 'node:fs/promises'
3
- import { setTimeout } from 'node:timers/promises'
4
3
 
5
4
  import { consoleWarnSpy, resetConsoleSpies } from '@scalar/helpers/testing/console-spies'
6
5
  import fastify, { type FastifyInstance } from 'fastify'
@@ -35,7 +34,6 @@ describe('bundle', () => {
35
34
 
36
35
  return async () => {
37
36
  await server.close()
38
- await setTimeout(100)
39
37
  }
40
38
  })
41
39
 
@@ -69,7 +67,7 @@ describe('bundle', () => {
69
67
 
70
68
  expect(input).toEqual({
71
69
  'x-ext': {
72
- [await getHash(url)]: {
70
+ [getHash(url)]: {
73
71
  ...external,
74
72
  },
75
73
  },
@@ -79,7 +77,7 @@ describe('bundle', () => {
79
77
  },
80
78
  },
81
79
  d: {
82
- $ref: `#/x-ext/${await getHash(url)}/prop`,
80
+ $ref: `#/x-ext/${getHash(url)}/prop`,
83
81
  },
84
82
  })
85
83
  })
@@ -126,13 +124,13 @@ describe('bundle', () => {
126
124
 
127
125
  expect(input).toEqual({
128
126
  'x-ext': {
129
- [await getHash(`${url}/chunk1`)]: {
127
+ [getHash(`${url}/chunk1`)]: {
130
128
  ...chunk1,
131
129
  b: {
132
- $ref: `#/x-ext/${await getHash(`${url}/chunk2`)}`,
130
+ $ref: `#/x-ext/${getHash(`${url}/chunk2`)}`,
133
131
  },
134
132
  },
135
- [await getHash(`${url}/chunk2`)]: {
133
+ [getHash(`${url}/chunk2`)]: {
136
134
  ...chunk2,
137
135
  internal: '#/nested/key',
138
136
  },
@@ -140,7 +138,7 @@ describe('bundle', () => {
140
138
  a: {
141
139
  b: {
142
140
  c: {
143
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
141
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
144
142
  },
145
143
  },
146
144
  },
@@ -170,13 +168,13 @@ describe('bundle', () => {
170
168
 
171
169
  expect(input).toEqual({
172
170
  'x-ext': {
173
- [await getHash(url)]: {
171
+ [getHash(url)]: {
174
172
  a: 'a',
175
173
  },
176
174
  },
177
175
  a: {
178
176
  b: {
179
- $ref: `#/x-ext/${await getHash(url)}`,
177
+ $ref: `#/x-ext/${getHash(url)}`,
180
178
  },
181
179
  },
182
180
  })
@@ -209,16 +207,16 @@ describe('bundle', () => {
209
207
 
210
208
  expect(input).toEqual({
211
209
  'x-ext': {
212
- [await getHash(url)]: {
210
+ [getHash(url)]: {
213
211
  a: 'a',
214
212
  b: 'b',
215
213
  },
216
214
  },
217
215
  a: {
218
- $ref: `#/x-ext/${await getHash(url)}/a`,
216
+ $ref: `#/x-ext/${getHash(url)}/a`,
219
217
  },
220
218
  b: {
221
- $ref: `#/x-ext/${await getHash(url)}/b`,
219
+ $ref: `#/x-ext/${getHash(url)}/b`,
222
220
  },
223
221
  })
224
222
 
@@ -255,17 +253,17 @@ describe('bundle', () => {
255
253
 
256
254
  expect(input).toEqual({
257
255
  'x-ext': {
258
- [await getHash(`${url}/nested/another-file.json`)]: {
256
+ [getHash(`${url}/nested/another-file.json`)]: {
259
257
  c: 'c',
260
258
  },
261
- [await getHash(`${url}/nested/chunk1.json`)]: {
259
+ [getHash(`${url}/nested/chunk1.json`)]: {
262
260
  b: {
263
- $ref: `#/x-ext/${await getHash(`${url}/nested/another-file.json`)}`,
261
+ $ref: `#/x-ext/${getHash(`${url}/nested/another-file.json`)}`,
264
262
  },
265
263
  },
266
264
  },
267
265
  a: {
268
- $ref: `#/x-ext/${await getHash(`${url}/nested/chunk1.json`)}`,
266
+ $ref: `#/x-ext/${getHash(`${url}/nested/chunk1.json`)}`,
269
267
  },
270
268
  })
271
269
  })
@@ -299,17 +297,17 @@ describe('bundle', () => {
299
297
 
300
298
  expect(input).toEqual({
301
299
  'x-ext': {
302
- [await getHash(`${url}/top-level`)]: {
300
+ [getHash(`${url}/top-level`)]: {
303
301
  c: 'c',
304
302
  },
305
- [await getHash(`${url}/nested/chunk1.json`)]: {
303
+ [getHash(`${url}/nested/chunk1.json`)]: {
306
304
  b: {
307
- $ref: `#/x-ext/${await getHash(`${url}/top-level`)}`,
305
+ $ref: `#/x-ext/${getHash(`${url}/top-level`)}`,
308
306
  },
309
307
  },
310
308
  },
311
309
  a: {
312
- $ref: `#/x-ext/${await getHash(`${url}/nested/chunk1.json`)}`,
310
+ $ref: `#/x-ext/${getHash(`${url}/nested/chunk1.json`)}`,
313
311
  },
314
312
  })
315
313
  })
@@ -345,17 +343,17 @@ describe('bundle', () => {
345
343
 
346
344
  expect(output).toEqual({
347
345
  'x-ext': {
348
- [await getHash(`${url}/top-level`)]: {
346
+ [getHash(`${url}/top-level`)]: {
349
347
  c: 'c',
350
348
  },
351
- [await getHash(`${url}/nested/chunk1.json`)]: {
349
+ [getHash(`${url}/nested/chunk1.json`)]: {
352
350
  b: {
353
- $ref: `#/x-ext/${await getHash(`${url}/top-level`)}`,
351
+ $ref: `#/x-ext/${getHash(`${url}/top-level`)}`,
354
352
  },
355
353
  },
356
354
  },
357
355
  a: {
358
- $ref: `#/x-ext/${await getHash(`${url}/nested/chunk1.json`)}`,
356
+ $ref: `#/x-ext/${getHash(`${url}/nested/chunk1.json`)}`,
359
357
  },
360
358
  })
361
359
  })
@@ -395,21 +393,21 @@ describe('bundle', () => {
395
393
 
396
394
  expect(output).toEqual({
397
395
  'x-ext': {
398
- [await getHash(`${url}/top-level`)]: {
396
+ [getHash(`${url}/top-level`)]: {
399
397
  c: 'c',
400
398
  },
401
- [await getHash(`${url}/nested/chunk1.json`)]: {
399
+ [getHash(`${url}/nested/chunk1.json`)]: {
402
400
  b: {
403
- $ref: `#/x-ext/${await getHash(`${url}/top-level`)}`,
401
+ $ref: `#/x-ext/${getHash(`${url}/top-level`)}`,
404
402
  },
405
403
  },
406
404
  },
407
405
  'x-ext-urls': {
408
- [await getHash(`${url}/top-level`)]: `${url}/top-level`,
409
- [await getHash(`${url}/nested/chunk1.json`)]: `${url}/nested/chunk1.json`,
406
+ [getHash(`${url}/top-level`)]: `${url}/top-level`,
407
+ [getHash(`${url}/nested/chunk1.json`)]: `${url}/nested/chunk1.json`,
410
408
  },
411
409
  a: {
412
- $ref: `#/x-ext/${await getHash(`${url}/nested/chunk1.json`)}`,
410
+ $ref: `#/x-ext/${getHash(`${url}/nested/chunk1.json`)}`,
413
411
  },
414
412
  })
415
413
  })
@@ -466,13 +464,13 @@ describe('bundle', () => {
466
464
  a: {
467
465
  b: {
468
466
  c: {
469
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
467
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
470
468
  },
471
469
  d: {
472
470
  e: {
473
471
  f: {
474
472
  g: {
475
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
473
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
476
474
  },
477
475
  },
478
476
  },
@@ -480,18 +478,18 @@ describe('bundle', () => {
480
478
  },
481
479
  },
482
480
  'x-ext': {
483
- [await getHash(`${url}/chunk1`)]: {
481
+ [getHash(`${url}/chunk1`)]: {
484
482
  a: {
485
483
  hello: 'hello',
486
484
  },
487
485
  b: {
488
- $ref: `#/x-ext/${await getHash(`${url}/chunk2`)}`,
486
+ $ref: `#/x-ext/${getHash(`${url}/chunk2`)}`,
489
487
  },
490
488
  },
491
- [await getHash(`${url}/chunk2`)]: {
489
+ [getHash(`${url}/chunk2`)]: {
492
490
  a: 'a',
493
491
  b: {
494
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
492
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
495
493
  },
496
494
  },
497
495
  },
@@ -528,11 +526,11 @@ describe('bundle', () => {
528
526
  expect(input).toEqual({
529
527
  a: [
530
528
  {
531
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
529
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
532
530
  },
533
531
  ],
534
532
  'x-ext': {
535
- [await getHash(`${url}/chunk1`)]: {
533
+ [getHash(`${url}/chunk1`)]: {
536
534
  a: {
537
535
  hello: 'hello',
538
536
  },
@@ -586,20 +584,20 @@ describe('bundle', () => {
586
584
  $ref: `${url}/chunk1#`,
587
585
  },
588
586
  b: {
589
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
587
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
590
588
  },
591
589
  c: {
592
590
  $ref: `${url}/chunk1#`,
593
591
  },
594
592
  'x-ext': {
595
- [await getHash(`${url}/chunk1`)]: {
593
+ [getHash(`${url}/chunk1`)]: {
596
594
  a: {
597
595
  hello: 'hello',
598
596
  },
599
597
  },
600
598
  },
601
599
  'x-ext-urls': {
602
- [await getHash(`${url}/chunk1`)]: `${url}/chunk1`,
600
+ [getHash(`${url}/chunk1`)]: `${url}/chunk1`,
603
601
  },
604
602
  })
605
603
 
@@ -616,20 +614,20 @@ describe('bundle', () => {
616
614
  $ref: `${url}/chunk1#`,
617
615
  },
618
616
  b: {
619
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
617
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
620
618
  },
621
619
  c: {
622
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
620
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
623
621
  },
624
622
  'x-ext': {
625
- [await getHash(`${url}/chunk1`)]: {
623
+ [getHash(`${url}/chunk1`)]: {
626
624
  a: {
627
625
  hello: 'hello',
628
626
  },
629
627
  },
630
628
  },
631
629
  'x-ext-urls': {
632
- [await getHash(`${url}/chunk1`)]: `${url}/chunk1`,
630
+ [getHash(`${url}/chunk1`)]: `${url}/chunk1`,
633
631
  },
634
632
  })
635
633
 
@@ -679,13 +677,13 @@ describe('bundle', () => {
679
677
  $ref: `${url}/chunk1#`,
680
678
  },
681
679
  b: {
682
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
680
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
683
681
  },
684
682
  c: {
685
683
  $ref: `${url}/chunk1#`,
686
684
  },
687
685
  'x-ext': {
688
- [await getHash(`${url}/chunk1`)]: {
686
+ [getHash(`${url}/chunk1`)]: {
689
687
  a: {
690
688
  hello: 'hello',
691
689
  },
@@ -693,7 +691,7 @@ describe('bundle', () => {
693
691
  },
694
692
  // It should still inject the mappings on the output document
695
693
  'x-ext-urls': {
696
- [await getHash(`${url}/chunk1`)]: `${url}/chunk1`,
694
+ [getHash(`${url}/chunk1`)]: `${url}/chunk1`,
697
695
  },
698
696
  })
699
697
  })
@@ -733,14 +731,14 @@ describe('bundle', () => {
733
731
 
734
732
  expect(input).toEqual({
735
733
  a: {
736
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/a/b`,
734
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/a/b`,
737
735
  },
738
736
  'x-ext': {
739
- [await getHash(`${url}/chunk1`)]: {
737
+ [getHash(`${url}/chunk1`)]: {
740
738
  a: {
741
739
  b: {
742
740
  g: {
743
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/d/e`,
741
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/d/e`,
744
742
  },
745
743
  hello: 'hello',
746
744
  },
@@ -804,20 +802,20 @@ describe('bundle', () => {
804
802
 
805
803
  expect(input).toEqual({
806
804
  a: {
807
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/a`,
805
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/a`,
808
806
  },
809
807
  'x-ext': {
810
- [await getHash(`${url}/chunk1`)]: {
808
+ [getHash(`${url}/chunk1`)]: {
811
809
  a: {
812
810
  b: {
813
811
  g: {
814
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/d/e`,
812
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/d/e`,
815
813
  },
816
814
  hello: 'hello',
817
815
  },
818
816
  c: 'c',
819
817
  'external': {
820
- $ref: `#/x-ext/${await getHash(`${url}/chunk2`)}/a/b`,
818
+ $ref: `#/x-ext/${getHash(`${url}/chunk2`)}/a/b`,
821
819
  },
822
820
  },
823
821
  d: {
@@ -826,7 +824,7 @@ describe('bundle', () => {
826
824
  },
827
825
  },
828
826
  },
829
- [await getHash(`${url}/chunk2`)]: {
827
+ [getHash(`${url}/chunk2`)]: {
830
828
  a: {
831
829
  b: {
832
830
  hello: 'hello',
@@ -871,20 +869,20 @@ describe('bundle', () => {
871
869
 
872
870
  expect(input).toEqual({
873
871
  a: {
874
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/a`,
872
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/a`,
875
873
  },
876
874
  'x-ext': {
877
- [await getHash(`${url}/chunk1`)]: {
875
+ [getHash(`${url}/chunk1`)]: {
878
876
  a: {
879
877
  b: {
880
878
  g: {
881
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/a/external`,
879
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/a/external`,
882
880
  },
883
881
  hello: 'hello',
884
882
  },
885
883
  c: 'c',
886
884
  external: {
887
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}/a/b`,
885
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}/a/b`,
888
886
  },
889
887
  },
890
888
  },
@@ -951,11 +949,11 @@ describe('bundle', () => {
951
949
  expect(input).toEqual({
952
950
  a: {
953
951
  $global: true,
954
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
952
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
955
953
  },
956
954
  b: {
957
955
  $global: true,
958
- $ref: `#/x-ext/${await getHash(`${url}/chunk2`)}`,
956
+ $ref: `#/x-ext/${getHash(`${url}/chunk2`)}`,
959
957
  },
960
958
  c: {
961
959
  $global: true,
@@ -973,19 +971,19 @@ describe('bundle', () => {
973
971
  },
974
972
  },
975
973
  'x-ext': {
976
- [await getHash(`${url}/chunk1`)]: {
974
+ [getHash(`${url}/chunk1`)]: {
977
975
  description: 'Chunk 1',
978
976
  someRef: {
979
977
  $ref: '#/components/User',
980
978
  },
981
979
  },
982
- [await getHash(`${url}/chunk2`)]: {
980
+ [getHash(`${url}/chunk2`)]: {
983
981
  description: 'Chunk 2',
984
982
  },
985
983
  },
986
984
  'x-ext-urls': {
987
- [await getHash(`${url}/chunk2`)]: `${url}/chunk2`,
988
- [await getHash(`${url}/chunk1`)]: `${url}/chunk1`,
985
+ [getHash(`${url}/chunk2`)]: `${url}/chunk2`,
986
+ [getHash(`${url}/chunk1`)]: `${url}/chunk1`,
989
987
  },
990
988
  })
991
989
  })
@@ -1031,7 +1029,7 @@ describe('bundle', () => {
1031
1029
 
1032
1030
  expect(input).toEqual({
1033
1031
  a: {
1034
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
1032
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
1035
1033
  },
1036
1034
  b: {
1037
1035
  a: 'a',
@@ -1043,14 +1041,14 @@ describe('bundle', () => {
1043
1041
  $ref: `${url}/chunk2#`,
1044
1042
  },
1045
1043
  'x-ext': {
1046
- [await getHash(`${url}/chunk1`)]: {
1044
+ [getHash(`${url}/chunk1`)]: {
1047
1045
  a: {
1048
1046
  hello: 'hello',
1049
1047
  },
1050
1048
  },
1051
1049
  },
1052
1050
  'x-ext-urls': {
1053
- [await getHash(`${url}/chunk1`)]: 'http://localhost:7289/chunk1',
1051
+ [getHash(`${url}/chunk1`)]: 'http://localhost:7289/chunk1',
1054
1052
  },
1055
1053
  })
1056
1054
  })
@@ -1134,14 +1132,14 @@ describe('bundle', () => {
1134
1132
  expect(input).toEqual({
1135
1133
  a: {
1136
1134
  $global: true,
1137
- $ref: `#/x-ext/${await getHash(`${url}/chunk1`)}`,
1135
+ $ref: `#/x-ext/${getHash(`${url}/chunk1`)}`,
1138
1136
  },
1139
1137
  b: {
1140
1138
  $global: true,
1141
- $ref: `#/x-ext/${await getHash(`${url}/chunk2`)}`,
1139
+ $ref: `#/x-ext/${getHash(`${url}/chunk2`)}`,
1142
1140
  },
1143
1141
  c: {
1144
- $ref: `#/x-ext/${await getHash(`${url}/external/document.json`)}`,
1142
+ $ref: `#/x-ext/${getHash(`${url}/external/document.json`)}`,
1145
1143
  },
1146
1144
 
1147
1145
  entry: {
@@ -1151,34 +1149,34 @@ describe('bundle', () => {
1151
1149
  $ref: `http://localhost:${port}/chunk1`,
1152
1150
  },
1153
1151
  'x-ext': {
1154
- [await getHash(`${url}/external/document.json`)]: {
1152
+ [getHash(`${url}/external/document.json`)]: {
1155
1153
  external: 'external',
1156
1154
  someChunk: {
1157
- $ref: `#/x-ext/${await getHash(`${url}/chunk3`)}`,
1155
+ $ref: `#/x-ext/${getHash(`${url}/chunk3`)}`,
1158
1156
  $global: true,
1159
1157
  },
1160
1158
  },
1161
- [await getHash(`${url}/chunk1`)]: {
1159
+ [getHash(`${url}/chunk1`)]: {
1162
1160
  chunk1: 'chunk1',
1163
1161
  someRef: {
1164
1162
  $ref: '#/b',
1165
1163
  },
1166
1164
  },
1167
- [await getHash(`${url}/chunk2`)]: {
1165
+ [getHash(`${url}/chunk2`)]: {
1168
1166
  chunk2: 'chunk2',
1169
1167
  someRef: {
1170
1168
  $ref: '#/c',
1171
1169
  },
1172
1170
  },
1173
- [await getHash(`${url}/chunk3`)]: {
1171
+ [getHash(`${url}/chunk3`)]: {
1174
1172
  chunk3: 'chunk3',
1175
1173
  },
1176
1174
  },
1177
1175
  'x-ext-urls': {
1178
- [await getHash(`${url}/chunk1`)]: `${url}/chunk1`,
1179
- [await getHash(`${url}/chunk2`)]: `${url}/chunk2`,
1180
- [await getHash(`${url}/chunk3`)]: `${url}/chunk3`,
1181
- [await getHash(`${url}/external/document.json`)]: `${url}/external/document.json`,
1176
+ [getHash(`${url}/chunk1`)]: `${url}/chunk1`,
1177
+ [getHash(`${url}/chunk2`)]: `${url}/chunk2`,
1178
+ [getHash(`${url}/chunk3`)]: `${url}/chunk3`,
1179
+ [getHash(`${url}/external/document.json`)]: `${url}/external/document.json`,
1182
1180
  },
1183
1181
  })
1184
1182
  })
@@ -1296,10 +1294,10 @@ describe('bundle', () => {
1296
1294
 
1297
1295
  expect(result).toEqual({
1298
1296
  'a': {
1299
- '$ref': '#/x-ext/8706c8f',
1297
+ '$ref': '#/x-ext/814f1d7',
1300
1298
  },
1301
1299
  'x-ext': {
1302
- '8706c8f': {
1300
+ '814f1d7': {
1303
1301
  'message': 'some resolved external reference',
1304
1302
  },
1305
1303
  },
@@ -1324,8 +1322,8 @@ describe('bundle', () => {
1324
1322
  })
1325
1323
 
1326
1324
  expect(result).toEqual({
1327
- a: { '$ref': '#/x-ext/6b07652' },
1328
- 'x-ext': { '6b07652': { message: 'some resolved external reference' } },
1325
+ a: { '$ref': '#/x-ext/220f104' },
1326
+ 'x-ext': { '220f104': { message: 'some resolved external reference' } },
1329
1327
  })
1330
1328
  })
1331
1329
 
@@ -1543,12 +1541,12 @@ describe('bundle', () => {
1543
1541
  'a': {
1544
1542
  'b': {
1545
1543
  'c': {
1546
- '$ref': '#/x-ext/1c26e20',
1544
+ '$ref': '#/x-ext/ce08d76',
1547
1545
  },
1548
1546
  },
1549
1547
  },
1550
1548
  'x-ext': {
1551
- '1c26e20': {
1549
+ 'ce08d76': {
1552
1550
  'message': 'resolved value',
1553
1551
  },
1554
1552
  },
@@ -1599,12 +1597,12 @@ describe('bundle', () => {
1599
1597
  'a': {
1600
1598
  'b': {
1601
1599
  'c': {
1602
- '$ref': '#/x-ext/19ac1c5',
1600
+ '$ref': '#/x-ext/b9d44e3',
1603
1601
  },
1604
1602
  },
1605
1603
  },
1606
1604
  'x-ext': {
1607
- '19ac1c5': {
1605
+ 'b9d44e3': {
1608
1606
  'message': 'resolved value',
1609
1607
  },
1610
1608
  },
@@ -1665,12 +1663,12 @@ describe('bundle', () => {
1665
1663
  'a': {
1666
1664
  'b': {
1667
1665
  'c': {
1668
- '$ref': '#/x-ext/8f7df4f',
1666
+ '$ref': '#/x-ext/c3654f1',
1669
1667
  },
1670
1668
  },
1671
1669
  },
1672
1670
  'x-ext': {
1673
- '8f7df4f': {
1671
+ 'c3654f1': {
1674
1672
  'message': 'resolved value',
1675
1673
  },
1676
1674
  },
@@ -1744,16 +1742,16 @@ describe('bundle', () => {
1744
1742
  '$ref': '#my-anchor',
1745
1743
  },
1746
1744
  'g': {
1747
- '$ref': '#/x-ext/0a9e8c9',
1745
+ '$ref': '#/x-ext/e71bf65',
1748
1746
  },
1749
1747
  },
1750
1748
  'x-ext': {
1751
- '0a9e8c9': {
1749
+ 'e71bf65': {
1752
1750
  'message': 'resolved value',
1753
1751
  },
1754
1752
  },
1755
1753
  'x-ext-urls': {
1756
- '0a9e8c9': 'http://example.com',
1754
+ 'e71bf65': 'http://example.com',
1757
1755
  },
1758
1756
  })
1759
1757
  })
@@ -1798,12 +1796,12 @@ describe('bundle', () => {
1798
1796
 
1799
1797
  expect(input).toEqual({
1800
1798
  'x-ext': {
1801
- [await getHash(chunk1Path)]: {
1799
+ [getHash(chunk1Path)]: {
1802
1800
  ...chunk1,
1803
1801
  },
1804
1802
  },
1805
1803
  a: {
1806
- $ref: `#/x-ext/${await getHash(chunk1Path)}/a`,
1804
+ $ref: `#/x-ext/${getHash(chunk1Path)}/a`,
1807
1805
  },
1808
1806
  })
1809
1807
  })
@@ -1831,15 +1829,15 @@ describe('bundle', () => {
1831
1829
 
1832
1830
  expect(input).toEqual({
1833
1831
  'x-ext': {
1834
- [await getHash(chunk1Path)]: {
1832
+ [getHash(chunk1Path)]: {
1835
1833
  ...chunk1,
1836
1834
  },
1837
- [await getHash(chunk2Path)]: {
1838
- a: { $ref: `#/x-ext/${await getHash(chunk1Path)}` },
1835
+ [getHash(chunk2Path)]: {
1836
+ a: { $ref: `#/x-ext/${getHash(chunk1Path)}` },
1839
1837
  },
1840
1838
  },
1841
1839
  a: {
1842
- $ref: `#/x-ext/${await getHash(chunk2Path)}`,
1840
+ $ref: `#/x-ext/${getHash(chunk2Path)}`,
1843
1841
  },
1844
1842
  })
1845
1843
  })
@@ -1877,15 +1875,15 @@ describe('bundle', () => {
1877
1875
 
1878
1876
  expect(input).toEqual({
1879
1877
  'x-ext': {
1880
- [await getHash(`nested/${cName}`)]: {
1878
+ [getHash(`nested/${cName}`)]: {
1881
1879
  c: 'c',
1882
1880
  },
1883
- [await getHash(`nested/${bName}`)]: {
1884
- b: { $ref: `#/x-ext/${await getHash(`nested/${cName}`)}` },
1881
+ [getHash(`nested/${bName}`)]: {
1882
+ b: { $ref: `#/x-ext/${getHash(`nested/${cName}`)}` },
1885
1883
  },
1886
1884
  },
1887
1885
  a: {
1888
- $ref: `#/x-ext/${await getHash(`nested/${bName}`)}`,
1886
+ $ref: `#/x-ext/${getHash(`nested/${bName}`)}`,
1889
1887
  },
1890
1888
  })
1891
1889
  })
@@ -1926,10 +1924,10 @@ describe('bundle', () => {
1926
1924
 
1927
1925
  expect(result).toEqual({
1928
1926
  'b': {
1929
- '$ref': `#/x-ext/${await getHash(`nested/${cName}`)}`,
1927
+ '$ref': `#/x-ext/${getHash(`nested/${cName}`)}`,
1930
1928
  },
1931
1929
  'x-ext': {
1932
- [await getHash(`nested/${cName}`)]: {
1930
+ [getHash(`nested/${cName}`)]: {
1933
1931
  'c': 'c',
1934
1932
  },
1935
1933
  },
@@ -1971,12 +1969,12 @@ describe('bundle', () => {
1971
1969
 
1972
1970
  expect(result).toEqual({
1973
1971
  'x-ext': {
1974
- [await getHash(chunk1Path)]: {
1972
+ [getHash(chunk1Path)]: {
1975
1973
  ...chunk1,
1976
1974
  },
1977
1975
  },
1978
1976
  a: {
1979
- $ref: `#/x-ext/${await getHash(chunk1Path)}/a`,
1977
+ $ref: `#/x-ext/${getHash(chunk1Path)}/a`,
1980
1978
  },
1981
1979
  })
1982
1980
  })
@@ -1992,7 +1990,6 @@ describe('bundle', () => {
1992
1990
 
1993
1991
  return async () => {
1994
1992
  await server.close()
1995
- await setTimeout(100)
1996
1993
  }
1997
1994
  })
1998
1995
 
@@ -2029,12 +2026,12 @@ describe('bundle', () => {
2029
2026
 
2030
2027
  expect(result).toEqual({
2031
2028
  'x-ext': {
2032
- [await getHash(chunk1Path)]: {
2029
+ [getHash(chunk1Path)]: {
2033
2030
  ...chunk1,
2034
2031
  },
2035
2032
  },
2036
2033
  a: {
2037
- $ref: `#/x-ext/${await getHash(chunk1Path)}/a`,
2034
+ $ref: `#/x-ext/${getHash(chunk1Path)}/a`,
2038
2035
  },
2039
2036
  })
2040
2037
  })
@@ -2071,7 +2068,6 @@ describe('bundle', () => {
2071
2068
 
2072
2069
  return async () => {
2073
2070
  await server.close()
2074
- await setTimeout(100)
2075
2071
  }
2076
2072
  })
2077
2073
 
@@ -2113,12 +2109,12 @@ describe('bundle', () => {
2113
2109
 
2114
2110
  expect(input).toEqual({
2115
2111
  'x-ext': {
2116
- [await getHash(url)]: {
2112
+ [getHash(url)]: {
2117
2113
  ...external,
2118
2114
  },
2119
2115
  },
2120
2116
  'x-ext-urls': {
2121
- [await getHash(url)]: url,
2117
+ [getHash(url)]: url,
2122
2118
  },
2123
2119
  a: {
2124
2120
  b: {
@@ -2133,7 +2129,7 @@ describe('bundle', () => {
2133
2129
  },
2134
2130
  d: {
2135
2131
  e: {
2136
- $ref: `#/x-ext/${await getHash(url)}/prop`,
2132
+ $ref: `#/x-ext/${getHash(url)}/prop`,
2137
2133
  },
2138
2134
  },
2139
2135
  })
@@ -2180,12 +2176,12 @@ describe('bundle', () => {
2180
2176
 
2181
2177
  expect(input).toEqual({
2182
2178
  'x-ext': {
2183
- [await getHash(url)]: {
2179
+ [getHash(url)]: {
2184
2180
  ...external,
2185
2181
  },
2186
2182
  },
2187
2183
  'x-ext-urls': {
2188
- [await getHash(url)]: url,
2184
+ [getHash(url)]: url,
2189
2185
  },
2190
2186
  a: {
2191
2187
  b: {
@@ -2200,7 +2196,7 @@ describe('bundle', () => {
2200
2196
  },
2201
2197
  d: {
2202
2198
  e: {
2203
- $ref: `#/x-ext/${await getHash(url)}/prop`,
2199
+ $ref: `#/x-ext/${getHash(url)}/prop`,
2204
2200
  },
2205
2201
  },
2206
2202
  })
@@ -2217,12 +2213,12 @@ describe('bundle', () => {
2217
2213
  // because we are reusing the same hash set
2218
2214
  expect(input).toEqual({
2219
2215
  'x-ext': {
2220
- [await getHash(url)]: {
2216
+ [getHash(url)]: {
2221
2217
  ...external,
2222
2218
  },
2223
2219
  },
2224
2220
  'x-ext-urls': {
2225
- [await getHash(url)]: url,
2221
+ [getHash(url)]: url,
2226
2222
  },
2227
2223
  a: {
2228
2224
  b: {
@@ -2237,7 +2233,7 @@ describe('bundle', () => {
2237
2233
  },
2238
2234
  d: {
2239
2235
  e: {
2240
- $ref: `#/x-ext/${await getHash(url)}/prop`,
2236
+ $ref: `#/x-ext/${getHash(url)}/prop`,
2241
2237
  },
2242
2238
  },
2243
2239
  })
@@ -2251,19 +2247,19 @@ describe('bundle', () => {
2251
2247
 
2252
2248
  expect(input).toEqual({
2253
2249
  'x-ext': {
2254
- [await getHash(url)]: {
2250
+ [getHash(url)]: {
2255
2251
  ...external,
2256
2252
  },
2257
2253
  },
2258
2254
  'x-ext-urls': {
2259
- [await getHash(url)]: url,
2255
+ [getHash(url)]: url,
2260
2256
  },
2261
2257
  a: {
2262
2258
  b: {
2263
2259
  c: {
2264
2260
  d: {
2265
2261
  e: {
2266
- $ref: `#/x-ext/${await getHash(url)}/prop`,
2262
+ $ref: `#/x-ext/${getHash(url)}/prop`,
2267
2263
  },
2268
2264
  },
2269
2265
  },
@@ -2271,7 +2267,7 @@ describe('bundle', () => {
2271
2267
  },
2272
2268
  d: {
2273
2269
  e: {
2274
- $ref: `#/x-ext/${await getHash(url)}/prop`,
2270
+ $ref: `#/x-ext/${getHash(url)}/prop`,
2275
2271
  },
2276
2272
  },
2277
2273
  })
@@ -2439,9 +2435,9 @@ describe('bundle', () => {
2439
2435
  expect(exec).toHaveBeenLastCalledWith('hello')
2440
2436
 
2441
2437
  expect(result).toEqual({
2442
- $ref: '#/x-ext/26c7827',
2438
+ $ref: '#/x-ext/f265832',
2443
2439
  'x-ext': {
2444
- '26c7827': {
2440
+ 'f265832': {
2445
2441
  message: 'Resolved document',
2446
2442
  },
2447
2443
  },
@@ -2638,13 +2634,13 @@ describe('bundle', () => {
2638
2634
 
2639
2635
  expect(onResolveStart).toHaveBeenCalledTimes(2)
2640
2636
  expect(onResolveStart).nthCalledWith(1, { $ref: 'some-value' })
2641
- expect(onResolveStart).nthCalledWith(2, { $ref: '#/x-ext/2a57507' })
2637
+ expect(onResolveStart).nthCalledWith(2, { $ref: '#/x-ext/908a515' })
2642
2638
 
2643
2639
  expect(onResolveError).toHaveBeenCalledTimes(1)
2644
2640
  expect(onResolveError).lastCalledWith({ $ref: 'some-value' })
2645
2641
 
2646
2642
  expect(onResolveSuccess).toHaveBeenCalledTimes(1)
2647
- expect(onResolveSuccess).lastCalledWith({ $ref: '#/x-ext/2a57507' })
2643
+ expect(onResolveSuccess).lastCalledWith({ $ref: '#/x-ext/908a515' })
2648
2644
  })
2649
2645
 
2650
2646
  it('correctly provides the parent node in different levels', async () => {
@@ -1,5 +1,3 @@
1
- import { setTimeout } from 'node:timers/promises'
2
-
3
1
  import { type FastifyInstance, fastify } from 'fastify'
4
2
  import { assert, beforeEach, describe, expect, it, vi } from 'vitest'
5
3
 
@@ -16,7 +14,6 @@ describe('fetchUrl', () => {
16
14
 
17
15
  return async () => {
18
16
  await server.close()
19
- await setTimeout(100)
20
17
  }
21
18
  })
22
19
 
@@ -1,4 +1,4 @@
1
- import { generateHash } from '@/helpers/generate-hash'
1
+ import { generateHash } from '@scalar/helpers/string/generate-hash'
2
2
 
3
3
  /**
4
4
  * Generates a short hash from a string value using xxhash.
@@ -13,11 +13,11 @@ import { generateHash } from '@/helpers/generate-hash'
13
13
  * @returns A Promise that resolves to a 7-character hexadecimal hash with at least one letter
14
14
  * @example
15
15
  * // Returns "2ae91d7"
16
- * await getHash("https://example.com/schema.json")
16
+ * getHash("https://example.com/schema.json")
17
17
  */
18
- export async function getHash(value: string): Promise<string> {
18
+ export function getHash(value: string): string {
19
19
  // Hash the data using xxhash
20
- const hashHex = await generateHash(value)
20
+ const hashHex = generateHash(value)
21
21
 
22
22
  // Return first 7 characters of the hash, ensuring at least one letter
23
23
  const hash = hashHex.substring(0, 7)
@@ -1,7 +1,5 @@
1
- import { setTimeout } from 'node:timers/promises'
2
-
3
1
  import { type FastifyInstance, fastify } from 'fastify'
4
- import { afterEach, beforeEach, describe, expect, it } from 'vitest'
2
+ import { beforeEach, describe, expect, it } from 'vitest'
5
3
 
6
4
  import { dereference } from '@/dereference/dereference'
7
5
 
@@ -68,11 +66,10 @@ describe('dereference', () => {
68
66
 
69
67
  beforeEach(() => {
70
68
  server = fastify({ logger: false })
71
- })
72
69
 
73
- afterEach(async () => {
74
- await server.close()
75
- await setTimeout(100)
70
+ return async () => {
71
+ await server.close()
72
+ }
76
73
  })
77
74
 
78
75
  it('should dereference JSON pointers asynchronously', async () => {
@@ -101,7 +98,7 @@ describe('dereference', () => {
101
98
  success: true,
102
99
  data: {
103
100
  profile: {
104
- '$ref': '#/x-ext/f87db7e',
101
+ '$ref': '#/x-ext/f053c6d',
105
102
  '$ref-value': {
106
103
  name: 'Jane Doe',
107
104
  age: 25,
@@ -112,17 +109,17 @@ describe('dereference', () => {
112
109
  },
113
110
  },
114
111
  address: {
115
- '$ref': '#/x-ext/f87db7e/address',
112
+ '$ref': '#/x-ext/f053c6d/address',
116
113
  '$ref-value': {
117
114
  city: 'Los Angeles',
118
115
  street: 'Sunset Boulevard',
119
116
  },
120
117
  },
121
118
  'x-ext': {
122
- 'f87db7e': userProfile,
119
+ 'f053c6d': userProfile,
123
120
  },
124
121
  'x-ext-urls': {
125
- 'f87db7e': `${url}/users`,
122
+ 'f053c6d': `${url}/users`,
126
123
  },
127
124
  },
128
125
  })
package/vite.config.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { alias } from '@scalar/build-tooling'
1
+ import { alias } from '@scalar/build-tooling/vite'
2
2
  import { defineConfig } from 'vite'
3
3
 
4
4
  export default defineConfig({
@@ -1,11 +0,0 @@
1
- /**
2
- * Generate a hash from a string using the xxhash algorithm
3
- *
4
- * We cannot use crypto.subtle because it is only available in secure contexts (HTTPS) or on localhost.
5
- * So this is just a wrapper around the xxhash-wasm library instead.
6
- *
7
- * @param input - The string to hash
8
- * @returns A Promise that resolves to the hash of the input string
9
- */
10
- export declare const generateHash: (input: string) => Promise<string>;
11
- //# sourceMappingURL=generate-hash.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-hash.d.ts","sourceRoot":"","sources":["../../src/helpers/generate-hash.ts"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,CAGhE,CAAA"}
@@ -1,16 +0,0 @@
1
- import xxhash from "xxhash-wasm";
2
- let hasherInstance = null;
3
- const getHasher = async () => {
4
- if (!hasherInstance) {
5
- hasherInstance = await xxhash();
6
- }
7
- return hasherInstance;
8
- };
9
- const generateHash = async (input) => {
10
- const { h64ToString } = await getHasher();
11
- return h64ToString(input);
12
- };
13
- export {
14
- generateHash
15
- };
16
- //# sourceMappingURL=generate-hash.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/helpers/generate-hash.ts"],
4
- "sourcesContent": ["import xxhash from 'xxhash-wasm'\n\nlet hasherInstance: Awaited<ReturnType<typeof xxhash>> | null = null\n\n/**\n * Initialize the xxhash hasher instance lazily\n *\n * This is just a workaround because we cannot use top level await in a UMD module (standalone references)\n */\nconst getHasher = async () => {\n if (!hasherInstance) {\n hasherInstance = await xxhash()\n }\n return hasherInstance\n}\n\n/**\n * Generate a hash from a string using the xxhash algorithm\n *\n * We cannot use crypto.subtle because it is only available in secure contexts (HTTPS) or on localhost.\n * So this is just a wrapper around the xxhash-wasm library instead.\n *\n * @param input - The string to hash\n * @returns A Promise that resolves to the hash of the input string\n */\nexport const generateHash = async (input: string): Promise<string> => {\n const { h64ToString } = await getHasher()\n return h64ToString(input)\n}\n"],
5
- "mappings": "AAAA,OAAO,YAAY;AAEnB,IAAI,iBAA4D;AAOhE,MAAM,YAAY,YAAY;AAC5B,MAAI,CAAC,gBAAgB;AACnB,qBAAiB,MAAM,OAAO;AAAA,EAChC;AACA,SAAO;AACT;AAWO,MAAM,eAAe,OAAO,UAAmC;AACpE,QAAM,EAAE,YAAY,IAAI,MAAM,UAAU;AACxC,SAAO,YAAY,KAAK;AAC1B;",
6
- "names": []
7
- }
@@ -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
- }