From 0ab6a367f81bfd782b093b739d06ad677f6c43f4 Mon Sep 17 00:00:00 2001 From: Vicary A Date: Fri, 31 Jan 2025 15:26:35 +0800 Subject: [PATCH] feat(package/gqty): reduce bundle size with ohash over object-hash --- .changeset/wicked-vans-move.md | 5 + packages/cli/package.json | 2 +- packages/gqty/package.json | 3 +- packages/gqty/src/Client/compat/resolved.ts | 2 +- packages/gqty/src/Utils/hash.ts | 4 +- packages/gqty/test/buildQuery.test.ts | 8 +- packages/gqty/test/client.test.ts | 224 +++++++++---------- packages/gqty/test/interfaces-unions.test.ts | 84 +++---- packages/gqty/test/persistence.test.ts | 4 +- packages/gqty/test/playground.test.ts | 2 +- packages/gqty/test/selection.test.ts | 14 +- packages/react/test/useQuery.test.tsx | 14 +- packages/solid/src/query.test.tsx | 12 +- pnpm-lock.yaml | 36 ++- 14 files changed, 205 insertions(+), 209 deletions(-) create mode 100644 .changeset/wicked-vans-move.md diff --git a/.changeset/wicked-vans-move.md b/.changeset/wicked-vans-move.md new file mode 100644 index 000000000..ec453012c --- /dev/null +++ b/.changeset/wicked-vans-move.md @@ -0,0 +1,5 @@ +--- +'gqty': minor +--- + +reduce bundle size with ohash over object-hash diff --git a/packages/cli/package.json b/packages/cli/package.json index 39109f941..b7fd4cc79 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -79,7 +79,7 @@ "@graphql-tools/wrap": "^10.0.29", "@inquirer/prompts": "^5.5.0", "chalk": "^4.1.2", - "commander": "^12.1.0", + "commander": "^13.1.0", "cosmiconfig": "^9.0.0", "cross-fetch": "^4.1.0", "fast-glob": "^3.3.3", diff --git a/packages/gqty/package.json b/packages/gqty/package.json index 2e2da9149..97e48f243 100644 --- a/packages/gqty/package.json +++ b/packages/gqty/package.json @@ -78,12 +78,10 @@ "just-safe-get": "^4.2.0", "just-safe-set": "^4.2.1", "multidict": "^1.0.9", - "object-hash": "^3.0.0", "p-defer": "^3.0.0" }, "devDependencies": { "@types/node": "^22.13.1", - "@types/object-hash": "^3.0.6", "@types/ws": "^8.5.14", "@typescript-eslint/eslint-plugin": "^8.23.0", "@typescript-eslint/parser": "^8.23.0", @@ -97,6 +95,7 @@ "graphql-ws": "^5.16.2", "jest": "^30.0.0-alpha.7", "just-memoize": "^2.2.0", + "ohash": "^1.1.4", "p-lazy": "^3.1.0", "test-utils": "workspace:^", "tsc-watch": "^6.2.1", diff --git a/packages/gqty/src/Client/compat/resolved.ts b/packages/gqty/src/Client/compat/resolved.ts index 90ce5a53a..8601a4946 100644 --- a/packages/gqty/src/Client/compat/resolved.ts +++ b/packages/gqty/src/Client/compat/resolved.ts @@ -110,7 +110,7 @@ export const createLegacyResolved = < { fetchOptions, noCache = false, // prevent cache writes after fetch - //nonSerializableVariables, // Ignored, object-hash can handle files + //nonSerializableVariables, // Ignored since our hasher can handle files onCacheData, onEmptyResolve, onNoCacheFound, diff --git a/packages/gqty/src/Utils/hash.ts b/packages/gqty/src/Utils/hash.ts index e2a771964..7818901a9 100644 --- a/packages/gqty/src/Utils/hash.ts +++ b/packages/gqty/src/Utils/hash.ts @@ -1,9 +1,9 @@ import memoize from 'just-memoize'; -import objectHash from 'object-hash'; +import { objectHash, sha256 } from 'ohash'; /** * Memoized hash function, with a prefix to avoid starting with a number. */ export const hash = memoize((...args: unknown[]) => - objectHash(args, { unorderedObjects: false }).replace(/^(\d)/, 'a$1') + sha256(objectHash(args, { unorderedObjects: false })).replace(/^(\d)/, 'a$1') ); diff --git a/packages/gqty/test/buildQuery.test.ts b/packages/gqty/test/buildQuery.test.ts index b4971d998..816070e94 100644 --- a/packages/gqty/test/buildQuery.test.ts +++ b/packages/gqty/test/buildQuery.test.ts @@ -77,10 +77,10 @@ describe('buildQuery()', () => { ); expect(query).toMatchInlineSnapshot( - `"query($a03b9b:Int!$ad2f8d:String!){d gqtyAlias_1:a(a:$a03b9b b:$ad2f8d){a_b a_c}}"` + `"query($a1968d:String!$a93e62:Int!){d gqtyAlias_1:a(a:$a93e62 b:$a1968d){a_b a_c}}"` ); expect(() => parse(query)).not.toThrow(); - expect(variables).toEqual({ a03b9b: 1, ad2f8d: 1 }); + expect(variables).toEqual({ a1968d: 1, a93e62: 1 }); expect(officialStripIgnoredCharacters(query)).toBe(query); }); @@ -104,14 +104,14 @@ describe('buildQuery()', () => { const [{ query, variables }] = buildQuery(new Set([selectionA])); expect(query).toMatchInlineSnapshot( - `"mutation($a03b9b:Int!$ad2f8d:String!){gqtyAlias_1:a(a:$a03b9b b:$ad2f8d)}"` + `"mutation($a1968d:String!$a93e62:Int!){gqtyAlias_1:a(a:$a93e62 b:$a1968d)}"` ); expect(() => { parse(query); }).not.toThrow(); - expect(variables).toEqual({ a03b9b: 1, ad2f8d: 1 }); + expect(variables).toEqual({ a1968d: 1, a93e62: 1 }); expect(officialStripIgnoredCharacters(query)).toBe(query); }); diff --git a/packages/gqty/test/client.test.ts b/packages/gqty/test/client.test.ts index 1b3a01eb9..95bded906 100644 --- a/packages/gqty/test/client.test.ts +++ b/packages/gqty/test/client.test.ts @@ -180,38 +180,38 @@ describe('core#resolve', () => { // 2. Ensure selections made expect([...selections].map((v) => v.cacheKeys.join('.'))) .toMatchInlineSnapshot(` - [ - "query.dogs.__typename", - "query.dogs.id", - "query.dogs.e61ad2", - ] - `); + [ + "query.dogs.__typename", + "query.dogs.id", + "query.dogs.a10168", + ] + `); // 3. resolve() await expect(resolve()).resolves.toMatchInlineSnapshot(` - [ - { - "data": { - "dogs": [ - { - "__typename": "Dog", - "e61ad2": "arf!", - "id": "1", - }, - { - "__typename": "Dog", - "e61ad2": "arf!", - "id": "2", - }, - ], - }, - "extensions": { - "hash": "a242b05e35ff15857d32ed1a1eeb07500b5138f16", - "type": "query", - }, - }, - ] - `); + [ + { + "data": { + "dogs": [ + { + "__typename": "Dog", + "a10168": "arf!", + "id": "1", + }, + { + "__typename": "Dog", + "a10168": "arf!", + "id": "2", + }, + ], + }, + "extensions": { + "hash": "a4049161dd3fbeed6f5c5658ae5aeb067002147bed201698119cf6fa3c93f6f8d", + "type": "query", + }, + }, + ] + `); // 4. Make selections again query.dogs = []; @@ -220,12 +220,12 @@ describe('core#resolve', () => { // 5. Expect previous sub-selections expect([...selections].map((v) => v.cacheKeys.join('.'))) .toMatchInlineSnapshot(` - [ - "query.dogs.__typename", - "query.dogs.id", - "query.dogs.e61ad2", - ] - `); + [ + "query.dogs.__typename", + "query.dogs.id", + "query.dogs.a10168", + ] + `); await expect(resolve()).resolves.toMatchInlineSnapshot(`undefined`); @@ -237,37 +237,37 @@ describe('core#resolve', () => { expect([...selections].map((v) => v.cacheKeys.join('.'))) .toMatchInlineSnapshot(` - [ - "query.dogs.__typename", - "query.dogs.id", - "query.dogs.a27c8c", - ] - `); + [ + "query.dogs.__typename", + "query.dogs.id", + "query.dogs.a516ab", + ] + `); await expect(resolve()).resolves.toMatchInlineSnapshot(` - [ - { - "data": { - "dogs": [ - { - "__typename": "Dog", - "a27c8c": "arf!arf!arf!", - "id": "1", - }, - { - "__typename": "Dog", - "a27c8c": "arf!arf!arf!", - "id": "2", - }, - ], - }, - "extensions": { - "hash": "ec6389bde813c1b5cb4b5b294e573082ec4270e1", - "type": "query", - }, - }, - ] - `); + [ + { + "data": { + "dogs": [ + { + "__typename": "Dog", + "a516ab": "arf!arf!arf!", + "id": "1", + }, + { + "__typename": "Dog", + "a516ab": "arf!arf!arf!", + "id": "2", + }, + ], + }, + "extensions": { + "hash": "a559a7f6482e7959e433f04f7274247f7cf5661540c3af47424ee1446027a816", + "type": "query", + }, + }, + ] + `); }); it('should retain previous sub-selections on caches with null objects', async () => { @@ -291,9 +291,9 @@ describe('core#resolve', () => { expect([...selections].map((v) => v.cacheKeys.join('.'))) .toMatchInlineSnapshot(` [ - "query.a7f6f9.__typename", - "query.a7f6f9.id", - "query.a7f6f9.a7a17c", + "query.a6c916.__typename", + "query.a6c916.id", + "query.a6c916.e61179", ] `); @@ -302,14 +302,14 @@ describe('core#resolve', () => { [ { "data": { - "a7f6f9": { + "a6c916": { "__typename": "Human", - "a7a17c": "Now you see me...", + "e61179": "Now you see me...", "id": "1", }, }, "extensions": { - "hash": "be79c4bae3a49b23d4beb0bbdbf9023ba0ca4898", + "hash": "a10b43bf9c52ee5bbc996198f56cc4f89f203199bfb6ad6f13b1082a5bcc1eae7", "type": "query", }, }, @@ -322,26 +322,26 @@ describe('core#resolve', () => { // 5. Expect sub-selections expect([...selections].map((v) => v.cacheKeys.join('.'))) .toMatchInlineSnapshot(` - [ - "query.a3f697.__typename", - "query.a3f697.id", - "query.a3f697.bad514", - ] - `); + [ + "query.a1cda9.__typename", + "query.a1cda9.id", + "query.a1cda9.a2ce8c", + ] + `); await expect(resolve()).resolves.toMatchInlineSnapshot(` - [ - { - "data": { - "a3f697": null, - }, - "extensions": { - "hash": "fc1b66218d65d51732ed66b85bb5450d0332ba44", - "type": "query", - }, - }, - ] - `); + [ + { + "data": { + "a1cda9": null, + }, + "extensions": { + "hash": "b9ae5a3dfdf2c9949d51bdf555c8eecc4c4c091d5d11cf0734853c4ba10bdd34", + "type": "query", + }, + }, + ] + `); // 6. Ensure previous selections of no more than the last 1 fetch is reused. context.cache.clear(); @@ -350,30 +350,30 @@ describe('core#resolve', () => { expect([...selections].map((v) => v.cacheKeys.join('.'))) .toMatchInlineSnapshot(` - [ - "query.a4fd2c.__typename", - "query.a4fd2c.id", - "query.a4fd2c.eb7f1d", - ] - `); + [ + "query.a7816d.__typename", + "query.a7816d.id", + "query.a7816d.a0564a", + ] + `); await expect(resolve()).resolves.toMatchInlineSnapshot(` - [ - { - "data": { - "a4fd2c": { - "__typename": "Human", - "eb7f1d": "I am Jane.", - "id": "2", - }, - }, - "extensions": { - "hash": "a1fac2bb2a1052821915362495c678811cb296e09", - "type": "query", - }, - }, - ] - `); + [ + { + "data": { + "a7816d": { + "__typename": "Human", + "a0564a": "I am Jane.", + "id": "2", + }, + }, + "extensions": { + "hash": "a9df6d7b05fcef74f68db84388ccac8b33b9b3766e859e764b0e626741628bcd2", + "type": "query", + }, + }, + ] + `); }); }); @@ -549,8 +549,8 @@ describe('compat', () => { expect(queries.map(({ query }) => query)).toMatchInlineSnapshot(` [ - "query TestQueryA($e8a374:String){a5b434:human(name:$e8a374){__typename}}", - "mutation TestMutation($ef3ee3:String!){a133ff:humanMutation(nameArg:$ef3ee3){__typename}}", + "query TestQueryA($a860ed:String){a1c0de:human(name:$a860ed){__typename}}", + "mutation TestMutation($de937b:String!){eed53f:humanMutation(nameArg:$de937b){__typename}}", "query TestQueryB{hello}", ] `); diff --git a/packages/gqty/test/interfaces-unions.test.ts b/packages/gqty/test/interfaces-unions.test.ts index 4bd6f3175..0fa91eeda 100644 --- a/packages/gqty/test/interfaces-unions.test.ts +++ b/packages/gqty/test/interfaces-unions.test.ts @@ -122,23 +122,23 @@ describe('interfaces and unions', () => { `); expect(queries).toMatchInlineSnapshot(` - [ - { - "query": "query($a18aa4:NodeType!){a0b55f:node(type:$a18aa4){__typename ...on A{a}...on B{b}id}}", - "result": { - "data": { - "a0b55f": { - "__typename": "A", - "a": 1, - "id": "1", - }, - }, - }, - "variables": { - "a18aa4": "A", - }, - }, - ] + [ + { + "query": "query($a156f2:NodeType!){a5c0e6:node(type:$a156f2){__typename ...on A{a}...on B{b}id}}", + "result": { + "data": { + "a5c0e6": { + "__typename": "A", + "a": 1, + "id": "1", + }, + }, + }, + "variables": { + "a156f2": "A", + }, + }, + ] `); expect(nodeResult).toStrictEqual({ @@ -185,31 +185,31 @@ describe('interfaces and unions', () => { } `); expect(queries).toMatchInlineSnapshot(` - [ - { - "query": "query($a18aa4:NodeType!){a0b55f:node(type:$a18aa4){__typename ...on A{a node{__typename ...on A{id node{__typename ...on C{node{__typename ...on A{id}id}}id}}id}}...on B{b}id}}", - "result": { - "data": { - "a0b55f": { - "__typename": "A", - "a": 1, - "id": "1", - "node": { - "__typename": "A", - "id": "1", - "node": { - "__typename": "A", - "id": "1", - }, - }, - }, - }, - }, - "variables": { - "a18aa4": "A", - }, - }, - ] + [ + { + "query": "query($a156f2:NodeType!){a5c0e6:node(type:$a156f2){__typename ...on A{a node{__typename ...on A{id node{__typename ...on C{node{__typename ...on A{id}id}}id}}id}}...on B{b}id}}", + "result": { + "data": { + "a5c0e6": { + "__typename": "A", + "a": 1, + "id": "1", + "node": { + "__typename": "A", + "id": "1", + "node": { + "__typename": "A", + "id": "1", + }, + }, + }, + }, + }, + "variables": { + "a156f2": "A", + }, + }, + ] `); }); }); diff --git a/packages/gqty/test/persistence.test.ts b/packages/gqty/test/persistence.test.ts index 244bcf086..a737ca537 100644 --- a/packages/gqty/test/persistence.test.ts +++ b/packages/gqty/test/persistence.test.ts @@ -123,7 +123,7 @@ test('basic functionality', async () => { const dataBackup1 = client1.persist(); expect(JSON.stringify(dataBackup1)).toMatchInlineSnapshot( - `"{"query":{"a7b306":{"__typename":"Human","id":"1","name":"asd"}}}"` + `"{"query":{"be710e":{"__typename":"Human","id":"1","name":"asd"}}}"` ); const client2 = await createTestClient(); @@ -220,7 +220,7 @@ test('version check', async () => { const cacheBackupv1 = client1.persist('v1'); expect(JSON.stringify(cacheBackupv1)).toMatchInlineSnapshot( - `"{"query":{"a7b306":{"__typename":"Human","id":"1","name":"asd"}},"version":"v1"}"` + `"{"query":{"be710e":{"__typename":"Human","id":"1","name":"asd"}},"version":"v1"}"` ); const client2 = await createTestClient(); diff --git a/packages/gqty/test/playground.test.ts b/packages/gqty/test/playground.test.ts index 4c136fab0..467756a87 100644 --- a/packages/gqty/test/playground.test.ts +++ b/packages/gqty/test/playground.test.ts @@ -89,7 +89,7 @@ describe('playground', () => { }, }, "query": { - "a7b306": { + "be710e": { "__ref": "Human:1", }, }, diff --git a/packages/gqty/test/selection.test.ts b/packages/gqty/test/selection.test.ts index b3425dbe5..2f460fb13 100644 --- a/packages/gqty/test/selection.test.ts +++ b/packages/gqty/test/selection.test.ts @@ -40,9 +40,9 @@ describe('selection creation', () => { 'a', 'b', 0, - 'a07b42', + 'a04687', ]); - expect(selectionD.alias).toBe('a07b42'); + expect(selectionD.alias).toBe('a04687'); const repeatSelectionD = selectionC.getChild('d', { input: { @@ -56,9 +56,9 @@ describe('selection creation', () => { 'a', 'b', 0, - 'a07b42', + 'a04687', ]); - expect(repeatSelectionD.alias).toBe('a07b42'); + expect(repeatSelectionD.alias).toBe('a04687'); const selectionE = selectionD.getChild('e'); @@ -67,7 +67,7 @@ describe('selection creation', () => { 'a', 'b', 0, - 'a07b42', + 'a04687', 'e', ]); @@ -106,7 +106,7 @@ describe('selection creation', () => { aliasLength: Infinity, }).getChild('b', { input: { types: { a: 'Int!' }, values: { a: 1 } } }); - // Future proof: object-hash defaults to SHA1, check against that or above. - expect(selectionB.alias?.length).toBeGreaterThanOrEqual(40); + // Future proof: ohash uses SHA256, check against that or above. + expect(selectionB.alias?.length).toBeGreaterThanOrEqual(64); }); }); diff --git a/packages/react/test/useQuery.test.tsx b/packages/react/test/useQuery.test.tsx index c439a8285..a96240b37 100644 --- a/packages/react/test/useQuery.test.tsx +++ b/packages/react/test/useQuery.test.tsx @@ -186,16 +186,16 @@ describe('useQuery', () => { [ { "operationName": undefined, - "query": "query($a00425:String){a2c936:human(name:$a00425){__typename id name}}", + "query": "query($a2ccff:String){ffcf6a:human(name:$a2ccff){__typename id name}}", "variables": { - "a00425": "1", + "a2ccff": "1", }, }, { "operationName": undefined, - "query": "query($dd0895:String){a657eb:human(name:$dd0895){__typename id name}}", + "query": "query($a9f80d:String){a7be6c:human(name:$a9f80d){__typename id name}}", "variables": { - "dd0895": "2", + "a9f80d": "2", }, }, ] @@ -341,7 +341,7 @@ describe('useQuery', () => { expect(queries).toMatchInlineSnapshot(` [ - "query($a2a039:ID!){eb2884:pet(id:$a2a039){__typename id owner{__typename id name}}now peoples{__typename id name}}", + "query($a16193:ID!){a7c8bb:pet(id:$a16193){__typename id owner{__typename id name}}now peoples{__typename id name}}", ] `); @@ -353,8 +353,8 @@ describe('useQuery', () => { expect(queries).toMatchInlineSnapshot(` [ - "query($a2a039:ID!){eb2884:pet(id:$a2a039){__typename id owner{__typename id name}}now peoples{__typename id name}}", - "query($a2a039:ID!){eb2884:pet(id:$a2a039){__typename id owner{__typename id name}}now peoples{__typename id name}}", + "query($a16193:ID!){a7c8bb:pet(id:$a16193){__typename id owner{__typename id name}}now peoples{__typename id name}}", + "query($a16193:ID!){a7c8bb:pet(id:$a16193){__typename id owner{__typename id name}}now peoples{__typename id name}}", ] `); }); diff --git a/packages/solid/src/query.test.tsx b/packages/solid/src/query.test.tsx index d2167ab4a..0357cd12d 100644 --- a/packages/solid/src/query.test.tsx +++ b/packages/solid/src/query.test.tsx @@ -184,23 +184,23 @@ describe('createQuery', () => { [ { "operationName": undefined, - "query": "query($e61a8e:ID!){a02d2c:people(id:$e61a8e){__typename id name}}", + "query": "query($d40f1c:ID!){a6f839:people(id:$d40f1c){__typename id name}}", "variables": { - "e61a8e": "1", + "d40f1c": "1", }, }, { "operationName": undefined, - "query": "query($d6d931:ID!){e084c7:people(id:$d6d931){__typename id name}}", + "query": "query($a38a2e:ID!){c21a0f:people(id:$a38a2e){__typename id name}}", "variables": { - "d6d931": "2", + "a38a2e": "2", }, }, { "operationName": undefined, - "query": "query($a60dd8:ID!){d2f785:people(id:$a60dd8){__typename id name}}", + "query": "query($bb76c4:ID!){b377ac:people(id:$bb76c4){__typename id name}}", "variables": { - "a60dd8": "3", + "bb76c4": "3", }, }, ] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 57da374cc..25db388c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -444,7 +444,7 @@ importers: dependencies: '@commander-js/extra-typings': specifier: ^13.1.0 - version: 13.1.0(commander@12.1.0) + version: 13.1.0(commander@13.1.0) '@graphql-codegen/core': specifier: ^4.0.2 version: 4.0.2(graphql@16.10.0) @@ -464,8 +464,8 @@ importers: specifier: ^4.1.2 version: 4.1.2 commander: - specifier: ^12.1.0 - version: 12.1.0 + specifier: ^13.1.0 + version: 13.1.0 cosmiconfig: specifier: ^9.0.0 version: 9.0.0(typescript@5.7.3) @@ -561,9 +561,6 @@ importers: multidict: specifier: ^1.0.9 version: 1.0.9 - object-hash: - specifier: ^3.0.0 - version: 3.0.0 p-defer: specifier: ^3.0.0 version: 3.0.0 @@ -571,9 +568,6 @@ importers: '@types/node': specifier: ^22.13.1 version: 22.13.1 - '@types/object-hash': - specifier: ^3.0.6 - version: 3.0.6 '@types/ws': specifier: ^8.5.14 version: 8.5.14 @@ -610,6 +604,9 @@ importers: jest: specifier: ^30.0.0-alpha.7 version: 30.0.0-alpha.7(@types/node@22.13.1)(ts-node@10.9.2) + ohash: + specifier: ^1.1.4 + version: 1.1.4 p-lazy: specifier: ^3.1.0 version: 3.1.0 @@ -2453,12 +2450,12 @@ packages: prettier: 2.8.8 dev: true - /@commander-js/extra-typings@13.1.0(commander@12.1.0): + /@commander-js/extra-typings@13.1.0(commander@13.1.0): resolution: {integrity: sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==} peerDependencies: commander: ~13.1.0 dependencies: - commander: 12.1.0 + commander: 13.1.0 dev: false /@cspotcode/source-map-support@0.8.1: @@ -5808,10 +5805,6 @@ packages: dependencies: undici-types: 6.20.0 - /@types/object-hash@3.0.6: - resolution: {integrity: sha512-fOBV8C1FIu2ELinoILQ+ApxcUKz4ngq+IWUYrxSGjXzzjUALijilampwkMgEtJ+h2njAW3pi853QpzNVCHB73w==} - dev: true - /@types/parse-json@4.0.2: resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} dev: false @@ -7122,8 +7115,8 @@ packages: dependencies: delayed-stream: 1.0.0 - /commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + /commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} dev: false @@ -11073,11 +11066,6 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - /object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - dev: false - /object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} @@ -11147,6 +11135,10 @@ packages: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} dev: false + /ohash@1.1.4: + resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} + dev: true + /on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'}