From 95f7156fd4a0681f8021559657bd97f29ebc73ae Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Fri, 9 Dec 2022 17:37:01 +0100 Subject: [PATCH] fix(core): Fix regression causing stringifyDocument to not reprint after formatDocument (#2871) Co-authored-by: Phil Pluckthun --- .changeset/large-eggs-cough.md | 5 +++ packages/core/src/utils/request.test.ts | 39 ++++++++++++++++++- packages/core/src/utils/request.ts | 21 +++++----- .../svelte-urql/src/mutationStore.test.ts | 3 +- 4 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 .changeset/large-eggs-cough.md diff --git a/.changeset/large-eggs-cough.md b/.changeset/large-eggs-cough.md new file mode 100644 index 0000000000..0809304ea6 --- /dev/null +++ b/.changeset/large-eggs-cough.md @@ -0,0 +1,5 @@ +--- +'@urql/core': patch +--- + +Fix regression in `@urql/core`'s `stringifyDocument` that caused some formatted documents to not be reprinted. diff --git a/packages/core/src/utils/request.test.ts b/packages/core/src/utils/request.test.ts index 0d0142685d..1ef3cdd145 100644 --- a/packages/core/src/utils/request.test.ts +++ b/packages/core/src/utils/request.test.ts @@ -92,6 +92,43 @@ describe('stringifyDocument ', () => { expect(stringifyDocument(formatted)).toBe(print(formatted)); }); + it('should reprint request documents', () => { + const request = createRequest(`query { test { field } }`, {}); + const formatted = formatDocument(request.query); + expect(print(formatted)).toMatchInlineSnapshot(` + "{ + test { + field + __typename + } + }" + `); + expect(stringifyDocument(formatted)).toBe(print(formatted)); + }); + + it('should reprint gql documents', () => { + const request = createRequest( + gql` + query { + test { + field + } + } + `, + {} + ); + const formatted = formatDocument(request.query); + expect(print(formatted)).toMatchInlineSnapshot(` + "{ + test { + field + __typename + } + }" + `); + expect(stringifyDocument(formatted)).toBe(print(formatted)); + }); + it('should remove comments', () => { const doc = ` { #query @@ -132,7 +169,6 @@ describe('stringifyDocument ', () => { .toMatchInlineSnapshot(` "{ field(arg: - \\"test #1\\") }" `); @@ -153,7 +189,6 @@ describe('stringifyDocument ', () => { .toMatchInlineSnapshot(` "{ field(arg: - \\"\\"\\" hello #hello diff --git a/packages/core/src/utils/request.ts b/packages/core/src/utils/request.ts index 8c3d77e278..3b9d907103 100644 --- a/packages/core/src/utils/request.ts +++ b/packages/core/src/utils/request.ts @@ -29,16 +29,21 @@ const replaceOutsideStrings = (str: string, idx: number) => const sanitizeDocument = (node: string): string => node.split(GRAPHQL_STRING_RE).map(replaceOutsideStrings).join('').trim(); +const prints = new Map(); +const docs = new Map(); + export const stringifyDocument = ( node: string | DefinitionNode | DocumentNode ): string => { - const printed = sanitizeDocument( - typeof node === 'string' - ? node - : node.loc && node.loc.source.name === SOURCE_NAME - ? node.loc.source.body - : print(node) - ); + let printed: string; + if (typeof node === 'string') { + printed = sanitizeDocument(node); + } else if (node.loc && docs.get((node as KeyedDocumentNode).__key) === node) { + printed = node.loc.source.body; + } else { + printed = prints.get(node) || sanitizeDocument(print(node)); + prints.set(node, printed); + } if (typeof node !== 'string' && !node.loc) { (node as WritableLocation).loc = { @@ -67,8 +72,6 @@ const hashDocument = ( return key; }; -const docs = new Map(); - export const keyDocument = (node: string | DocumentNode): KeyedDocumentNode => { let key: HashValue; let query: DocumentNode; diff --git a/packages/svelte-urql/src/mutationStore.test.ts b/packages/svelte-urql/src/mutationStore.test.ts index 8c47ab39ce..4fb129d5af 100644 --- a/packages/svelte-urql/src/mutationStore.test.ts +++ b/packages/svelte-urql/src/mutationStore.test.ts @@ -1,3 +1,4 @@ +import { print } from 'graphql'; import { createClient } from '@urql/core'; import { get } from 'svelte/store'; import { vi, expect, it, describe } from 'vitest'; @@ -28,7 +29,7 @@ describe('mutationStore', () => { expect(get(store).operation.context.url).toBe('https://example.com'); expect(get(store).operation.variables).toBe(variables); - expect(get(store).operation.query.loc?.source.body).toMatchInlineSnapshot(` + expect(print(get(store).operation.query)).toMatchInlineSnapshot(` "mutation ($input: Example!) { doExample(input: $input) { id