Mirror: The spec-compliant minimum of client-side GraphQL.

Backport GraphQL-Tag fix (#38)

authored by Jovi De Croock and committed by GitHub a5fd37d1 0e929304

Changed files
+41 -5
.changeset
src
+5
.changeset/tiny-gifts-exercise.md
··· 1 + --- 2 + '@0no-co/graphql.web': patch 3 + --- 4 + 5 + Add `loc` getter to parsed `DocumentNode` fragment outputs to ensure that using fragments created by `gql.tada`'s `graphql()` function with `graphql-tag` doesn't crash. `graphql-tag` does not treat the `DocumentNode.loc` property as optional on interpolations, which leads to intercompatibility issues.
+1 -1
src/__tests__/parser.test.ts
··· 6 6 7 7 describe('parse', () => { 8 8 it('parses the kitchen sink document like graphql.js does', () => { 9 - const doc = parse(kitchenSinkDocument); 9 + const doc = parse(kitchenSinkDocument, { noLocation: true }); 10 10 expect(doc).toMatchSnapshot(); 11 11 }); 12 12
+35 -4
src/parser.ts
··· 6 6 */ 7 7 import type { Kind, OperationTypeNode } from './kind'; 8 8 import { GraphQLError } from './error'; 9 - import type { Source } from './types'; 9 + import type { Location, Source } from './types'; 10 10 import type * as ast from './ast'; 11 11 12 12 let input: string; ··· 483 483 } 484 484 } 485 485 486 - function document(): ast.DocumentNode { 486 + function document(input: string, noLoc: boolean): ast.DocumentNode { 487 487 let match: string | undefined; 488 488 let definition: ast.OperationDefinitionNode | undefined; 489 489 ignored(); ··· 498 498 throw error('Document'); 499 499 } 500 500 } while (idx < input.length); 501 + 502 + if (!noLoc) { 503 + let loc: Location | undefined; 504 + return { 505 + kind: 'Document' as Kind.DOCUMENT, 506 + definitions, 507 + /* v8 ignore start */ 508 + set loc(_loc: Location) { 509 + loc = _loc; 510 + }, 511 + /* v8 ignore stop */ 512 + // @ts-ignore 513 + get loc() { 514 + if (!loc) { 515 + loc = { 516 + start: 0, 517 + end: input.length, 518 + startToken: undefined, 519 + endToken: undefined, 520 + source: { 521 + body: input, 522 + name: 'graphql.web', 523 + locationOffset: { line: 1, column: 1 }, 524 + }, 525 + }; 526 + } 527 + return loc; 528 + }, 529 + }; 530 + } 531 + 501 532 return { 502 533 kind: 'Document' as Kind.DOCUMENT, 503 534 definitions, ··· 510 541 511 542 export function parse( 512 543 string: string | Source, 513 - _options?: ParseOptions | undefined 544 + options?: ParseOptions | undefined 514 545 ): ast.DocumentNode { 515 546 input = typeof string.body === 'string' ? string.body : string; 516 547 idx = 0; 517 - return document(); 548 + return document(input, options && options.noLocation); 518 549 } 519 550 520 551 export function parseValue(