From 368d5a19c09fe97aadf8de13bc9bc881c7980e86 Mon Sep 17 00:00:00 2001 From: jdecroock Date: Fri, 1 Nov 2024 13:56:56 +0100 Subject: [PATCH] Allow for parse to return a Promise --- src/language/__tests__/parser-test.ts | 23 +++++++++++++------- src/language/__tests__/visitor-test.ts | 2 +- src/language/parser.ts | 15 ++++++++++++- src/utilities/__tests__/extendSchema-test.ts | 2 +- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/language/__tests__/parser-test.ts b/src/language/__tests__/parser-test.ts index d98b6a6f41..93d89b8568 100644 --- a/src/language/__tests__/parser-test.ts +++ b/src/language/__tests__/parser-test.ts @@ -11,7 +11,13 @@ import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery.js'; import { inspect } from '../../jsutils/inspect.js'; import { Kind } from '../kinds.js'; -import { parse, parseConstValue, parseType, parseValue } from '../parser.js'; +import { + parse, + parseConstValue, + parseSync, + parseType, + parseValue, +} from '../parser.js'; import { Source } from '../source.js'; import { TokenKind } from '../tokenKind.js'; @@ -23,7 +29,7 @@ describe('Parser', () => { it('parse provides useful errors', () => { let caughtError; try { - parse('{'); + parseSync('{'); } catch (error) { caughtError = error; } @@ -74,7 +80,7 @@ describe('Parser', () => { it('parse provides useful error when using source', () => { let caughtError; try { - parse(new Source('query', 'MyQuery.graphql')); + parseSync(new Source('query', 'MyQuery.graphql')); } catch (error) { caughtError = error; } @@ -100,9 +106,10 @@ describe('Parser', () => { ); }); - it('exposes the tokenCount', () => { - expect(parse('{ foo }').tokenCount).to.equal(3); - expect(parse('{ foo(bar: "baz") }').tokenCount).to.equal(8); + it('exposes the tokenCount', async () => { + expect(parseSync('{ foo }').tokenCount).to.equal(3); + expect((await parse('{ foo }')).tokenCount).to.equal(3); + expect((await parse('{ foo(bar: "baz") }')).tokenCount).to.equal(8); }); it('parses variable inline values', () => { @@ -431,8 +438,8 @@ describe('Parser', () => { expect(() => parse(document)).to.throw(); }); - it('contains location that can be Object.toStringified, JSON.stringified, or jsutils.inspected', () => { - const { loc } = parse('{ id }'); + it('contains location that can be Object.toStringified, JSON.stringified, or jsutils.inspected', async () => { + const { loc } = await parse('{ id }'); expect(Object.prototype.toString.call(loc)).to.equal('[object Location]'); expect(JSON.stringify(loc)).to.equal('{"start":0,"end":6}'); diff --git a/src/language/__tests__/visitor-test.ts b/src/language/__tests__/visitor-test.ts index 6aceec88b6..f58d6d83e2 100644 --- a/src/language/__tests__/visitor-test.ts +++ b/src/language/__tests__/visitor-test.ts @@ -6,7 +6,7 @@ import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery.js'; import type { ASTNode, SelectionSetNode } from '../ast.js'; import { isNode } from '../ast.js'; import { Kind } from '../kinds.js'; -import { parse } from '../parser.js'; +import { parseSync as parse } from '../parser.js'; import type { ASTVisitor, ASTVisitorKeyMap } from '../visitor.js'; import { BREAK, visit, visitInParallel } from '../visitor.js'; diff --git a/src/language/parser.ts b/src/language/parser.ts index 3d2018ba4b..1645ebf92c 100644 --- a/src/language/parser.ts +++ b/src/language/parser.ts @@ -1,3 +1,4 @@ +import { isPromise } from '../jsutils/isPromise.js'; import type { Maybe } from '../jsutils/Maybe.js'; import type { GraphQLError } from '../error/GraphQLError.js'; @@ -117,7 +118,7 @@ export interface ParseOptions { export function parse( source: string | Source, options?: ParseOptions | undefined, -): DocumentNode { +): Promise | DocumentNode { const parser = new Parser(source, options); const document = parser.parseDocument(); Object.defineProperty(document, 'tokenCount', { @@ -127,6 +128,18 @@ export function parse( return document; } +export function parseSync( + source: string | Source, + options?: ParseOptions | undefined, +): DocumentNode { + const result = parse(source, options); + /* c8 ignore next 3 */ + if (isPromise(result)) { + throw new Error('GraphQL parsing failed to complete synchronously.'); + } + return result; +} + /** * Given a string containing a GraphQL value (ex. `[42]`), parse the AST for * that value. diff --git a/src/utilities/__tests__/extendSchema-test.ts b/src/utilities/__tests__/extendSchema-test.ts index 5e2d786f22..357c657105 100644 --- a/src/utilities/__tests__/extendSchema-test.ts +++ b/src/utilities/__tests__/extendSchema-test.ts @@ -6,7 +6,7 @@ import { dedent } from '../../__testUtils__/dedent.js'; import type { Maybe } from '../../jsutils/Maybe.js'; import type { ASTNode } from '../../language/ast.js'; -import { parse } from '../../language/parser.js'; +import { parseSync as parse } from '../../language/parser.js'; import { print } from '../../language/printer.js'; import {