diff --git a/.eslintrc.yml b/.eslintrc.yml index 1cc804d7b5..bef6869a55 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -509,84 +509,80 @@ overrides: # Supported Rules # https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#supported-rules - '@typescript-eslint/adjacent-overload-signatures': error - '@typescript-eslint/array-type': [error, { default: generic }] - '@typescript-eslint/await-thenable': error - '@typescript-eslint/ban-ts-comment': [error, { 'ts-expect-error': false }] - '@typescript-eslint/ban-tslint-comment': error - '@typescript-eslint/ban-types': error - '@typescript-eslint/class-literal-property-style': off # TODO enable after TS conversion - '@typescript-eslint/consistent-indexed-object-style': off # TODO enable after TS conversion - '@typescript-eslint/consistent-type-assertions': - [error, { assertionStyle: as, objectLiteralTypeAssertions: never }] + '@typescript-eslint/adjacent-overload-signatures': off #TODO temporarily disabled + '@typescript-eslint/array-type': off #TODO temporarily disabled + '@typescript-eslint/await-thenable': off #TODO temporarily disabled + '@typescript-eslint/ban-ts-comment': off #TODO temporarily disabled + '@typescript-eslint/ban-tslint-comment': off #TODO temporarily disabled + '@typescript-eslint/ban-types': off #TODO temporarily disabled + '@typescript-eslint/class-literal-property-style': off + '@typescript-eslint/consistent-type-assertions': off #TODO temporarily disabled '@typescript-eslint/consistent-type-definitions': off # TODO consider '@typescript-eslint/consistent-type-imports': off # TODO enable after TS conversion '@typescript-eslint/explicit-function-return-type': off # TODO consider '@typescript-eslint/explicit-member-accessibility': off # TODO consider '@typescript-eslint/explicit-module-boundary-types': off # TODO consider '@typescript-eslint/member-ordering': off # TODO consider - '@typescript-eslint/method-signature-style': error + '@typescript-eslint/method-signature-style': off #TODO temporarily disabled '@typescript-eslint/naming-convention': off # TODO consider - '@typescript-eslint/no-base-to-string': error - '@typescript-eslint/no-confusing-non-null-assertion': error + '@typescript-eslint/no-base-to-string': off #TODO temporarily disabled + '@typescript-eslint/no-confusing-non-null-assertion': off #TODO temporarily disabled '@typescript-eslint/no-dynamic-delete': off - '@typescript-eslint/no-empty-interface': error + '@typescript-eslint/no-empty-interface': off #TODO temporarily disabled '@typescript-eslint/no-explicit-any': off # TODO error - '@typescript-eslint/no-extra-non-null-assertion': error + '@typescript-eslint/no-extra-non-null-assertion': off #TODO temporarily disabled '@typescript-eslint/no-extraneous-class': off # TODO consider - '@typescript-eslint/no-floating-promises': error - '@typescript-eslint/no-for-in-array': error + '@typescript-eslint/no-floating-promises': off #TODO temporarily disabled + '@typescript-eslint/no-for-in-array': off #TODO temporarily disabled '@typescript-eslint/no-implicit-any-catch': off # TODO: Enable after TS convertion - '@typescript-eslint/no-implied-eval': error - '@typescript-eslint/no-inferrable-types': - [error, { ignoreParameters: true, ignoreProperties: true }] - '@typescript-eslint/no-misused-new': error - '@typescript-eslint/no-misused-promises': error - '@typescript-eslint/no-namespace': error - '@typescript-eslint/no-non-null-asserted-optional-chain': error - '@typescript-eslint/no-non-null-assertion': error - '@typescript-eslint/no-parameter-properties': error - '@typescript-eslint/no-invalid-void-type': error - '@typescript-eslint/no-require-imports': error - '@typescript-eslint/no-this-alias': error - '@typescript-eslint/no-throw-literal': error + '@typescript-eslint/no-implied-eval': off #TODO temporarily disabled + '@typescript-eslint/no-inferrable-types': off #TODO temporarily disabled + '@typescript-eslint/no-misused-new': off #TODO temporarily disabled + '@typescript-eslint/no-misused-promises': off #TODO temporarily disabled + '@typescript-eslint/no-namespace': off #TODO temporarily disabled + '@typescript-eslint/no-non-null-asserted-optional-chain': off #TODO temporarily disabled + '@typescript-eslint/no-non-null-assertion': off #TODO temporarily disabled + '@typescript-eslint/no-parameter-properties': off #TODO temporarily disabled + '@typescript-eslint/no-invalid-void-type': off #TODO temporarily disabled + '@typescript-eslint/no-require-imports': off #TODO temporarily disabled + '@typescript-eslint/no-this-alias': off #TODO temporarily disabled + '@typescript-eslint/no-throw-literal': off #TODO temporarily disabled '@typescript-eslint/no-type-alias': off # TODO consider - '@typescript-eslint/no-unnecessary-boolean-literal-compare': error - '@typescript-eslint/no-unnecessary-condition': error - '@typescript-eslint/no-unnecessary-qualifier': error - '@typescript-eslint/no-unnecessary-type-arguments': error - '@typescript-eslint/no-unnecessary-type-assertion': error + '@typescript-eslint/no-unnecessary-boolean-literal-compare': off #TODO temporarily disabled + '@typescript-eslint/no-unnecessary-condition': off #TODO temporarily disabled + '@typescript-eslint/no-unnecessary-qualifier': off #TODO temporarily disabled + '@typescript-eslint/no-unnecessary-type-arguments': off #TODO temporarily disabled + '@typescript-eslint/no-unnecessary-type-assertion': off #TODO temporarily disabled '@typescript-eslint/no-unsafe-assignment': off # TODO consider '@typescript-eslint/no-unsafe-call': off # TODO consider '@typescript-eslint/no-unsafe-member-access': off # TODO consider '@typescript-eslint/no-unsafe-return': off # TODO consider - '@typescript-eslint/no-var-requires': error + '@typescript-eslint/no-var-requires': off #TODO temporarily disabled '@typescript-eslint/prefer-as-const': off # TODO consider '@typescript-eslint/prefer-enum-initializers': off # TODO consider '@typescript-eslint/prefer-for-of': off # TODO switch to error after TS migration - '@typescript-eslint/prefer-function-type': error + '@typescript-eslint/prefer-function-type': off #TODO temporarily disabled '@typescript-eslint/prefer-includes': off # TODO switch to error after IE11 drop - '@typescript-eslint/prefer-literal-enum-member': error - '@typescript-eslint/prefer-namespace-keyword': error - '@typescript-eslint/prefer-nullish-coalescing': error - '@typescript-eslint/prefer-optional-chain': error - '@typescript-eslint/prefer-readonly': error + '@typescript-eslint/prefer-literal-enum-member': off #TODO temporarily disabled + '@typescript-eslint/prefer-namespace-keyword': off #TODO temporarily disabled + '@typescript-eslint/prefer-nullish-coalescing': off #TODO temporarily disabled + '@typescript-eslint/prefer-optional-chain': off #TODO temporarily disabled + '@typescript-eslint/prefer-readonly': off #TODO temporarily disabled '@typescript-eslint/prefer-readonly-parameter-types': off # TODO consider - '@typescript-eslint/prefer-reduce-type-parameter': error - '@typescript-eslint/prefer-regexp-exec': error - '@typescript-eslint/prefer-ts-expect-error': error + '@typescript-eslint/prefer-reduce-type-parameter': off #TODO temporarily disabled + '@typescript-eslint/prefer-regexp-exec': off #TODO temporarily disabled + '@typescript-eslint/prefer-ts-expect-error': off #TODO temporarily disabled '@typescript-eslint/prefer-string-starts-ends-with': off # TODO switch to error after IE11 drop '@typescript-eslint/promise-function-async': off - '@typescript-eslint/require-array-sort-compare': error - '@typescript-eslint/restrict-plus-operands': - [error, { checkCompoundAssignments: true }] - '@typescript-eslint/restrict-template-expressions': error + '@typescript-eslint/require-array-sort-compare': off #TODO temporarily disabled + '@typescript-eslint/restrict-plus-operands': off #TODO temporarily disabled + '@typescript-eslint/restrict-template-expressions': off #TODO temporarily disabled '@typescript-eslint/strict-boolean-expressions': off # TODO consider - '@typescript-eslint/switch-exhaustiveness-check': error - '@typescript-eslint/triple-slash-reference': error + '@typescript-eslint/switch-exhaustiveness-check': off #TODO temporarily disabled + '@typescript-eslint/triple-slash-reference': off #TODO temporarily disabled '@typescript-eslint/typedef': off '@typescript-eslint/unbound-method': off # TODO consider - '@typescript-eslint/unified-signatures': error + '@typescript-eslint/unified-signatures': off #TODO temporarily disabled # Extension Rules # https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#extension-rules @@ -608,32 +604,22 @@ overrides: no-useless-constructor: off require-await: off no-return-await: off - '@typescript-eslint/default-param-last': error - '@typescript-eslint/dot-notation': error - '@typescript-eslint/lines-between-class-members': - [error, always, { exceptAfterSingleLine: true }] - '@typescript-eslint/no-array-constructor': error - '@typescript-eslint/no-dupe-class-members': error - '@typescript-eslint/no-empty-function': error - '@typescript-eslint/no-invalid-this': error - '@typescript-eslint/no-loop-func': error - '@typescript-eslint/no-loss-of-precision': error - '@typescript-eslint/no-redeclare': error - '@typescript-eslint/no-shadow': error - '@typescript-eslint/no-unused-expressions': error - '@typescript-eslint/no-unused-vars': - [ - error, - { - vars: all, - args: all, - argsIgnorePattern: '^_', - varsIgnorePattern: '^_T', - }, - ] - '@typescript-eslint/no-useless-constructor': error - '@typescript-eslint/require-await': error - '@typescript-eslint/return-await': error + '@typescript-eslint/default-param-last': off #TODO temporarily disabled + '@typescript-eslint/dot-notation': off #TODO temporarily disabled + '@typescript-eslint/lines-between-class-members': off #TODO temporarily disabled + '@typescript-eslint/no-array-constructor': off #TODO temporarily disabled + '@typescript-eslint/no-dupe-class-members': off #TODO temporarily disabled + '@typescript-eslint/no-empty-function': off #TODO temporarily disabled + '@typescript-eslint/no-invalid-this': off #TODO temporarily disabled + '@typescript-eslint/no-loop-func': off #TODO temporarily disabled + '@typescript-eslint/no-loss-of-precision': off #TODO temporarily disabled + '@typescript-eslint/no-redeclare': off #TODO temporarily disabled + '@typescript-eslint/no-shadow': off #TODO temporarily disabled + '@typescript-eslint/no-unused-expressions': off #TODO temporarily disabled + '@typescript-eslint/no-unused-vars': off #TODO temporarily disabled + '@typescript-eslint/no-useless-constructor': off #TODO temporarily disabled + '@typescript-eslint/require-await': off #TODO temporarily disabled + '@typescript-eslint/return-await': off #TODO temporarily disabled # Disable for JS, Flow and TS '@typescript-eslint/init-declarations': off diff --git a/package-lock.json b/package-lock.json index e3a749b128..491c018953 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4972,6 +4972,11 @@ "punycode": "^2.1.0" } }, + "utility-types": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", + "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", diff --git a/package.json b/package.json index 48cadf00f2..86b73141b7 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,9 @@ "gitpublish:npm": "bash ./resources/gitpublish.sh npm npmDist", "gitpublish:deno": "bash ./resources/gitpublish.sh deno denoDist" }, - "dependencies": {}, + "dependencies": { + "utility-types": "^3.10.0" + }, "devDependencies": { "@babel/core": "7.12.3", "@babel/plugin-transform-flow-strip-types": "7.12.1", diff --git a/src/__testUtils__/__tests__/dedent-test.js b/src/__testUtils__/__tests__/dedent-test.ts similarity index 100% rename from src/__testUtils__/__tests__/dedent-test.js rename to src/__testUtils__/__tests__/dedent-test.ts diff --git a/src/__testUtils__/__tests__/genFuzzStrings-test.js b/src/__testUtils__/__tests__/genFuzzStrings-test.ts similarity index 94% rename from src/__testUtils__/__tests__/genFuzzStrings-test.js rename to src/__testUtils__/__tests__/genFuzzStrings-test.ts index 75da1b63cc..92ea5c592d 100644 --- a/src/__testUtils__/__tests__/genFuzzStrings-test.js +++ b/src/__testUtils__/__tests__/genFuzzStrings-test.ts @@ -3,10 +3,10 @@ import { describe, it } from 'mocha'; import genFuzzStrings from '../genFuzzStrings'; -function expectFuzzStrings(options: {| - allowedChars: Array, - maxLength: number, -|}) { +function expectFuzzStrings(options: { + allowedChars: Array; + maxLength: number; +}) { return expect(Array.from(genFuzzStrings(options))); } diff --git a/src/__testUtils__/__tests__/inspectStr-test.js b/src/__testUtils__/__tests__/inspectStr-test.ts similarity index 100% rename from src/__testUtils__/__tests__/inspectStr-test.js rename to src/__testUtils__/__tests__/inspectStr-test.ts diff --git a/src/__testUtils__/__tests__/resolveOnNextTick-test.js b/src/__testUtils__/__tests__/resolveOnNextTick-test.ts similarity index 100% rename from src/__testUtils__/__tests__/resolveOnNextTick-test.js rename to src/__testUtils__/__tests__/resolveOnNextTick-test.ts diff --git a/src/__testUtils__/dedent.js b/src/__testUtils__/dedent.ts similarity index 93% rename from src/__testUtils__/dedent.js rename to src/__testUtils__/dedent.ts index c4b8e8da7b..15c89cadbb 100644 --- a/src/__testUtils__/dedent.js +++ b/src/__testUtils__/dedent.ts @@ -11,8 +11,8 @@ * str === "{\n test\n}\n"; */ export default function dedent( - strings: $ReadOnlyArray, - ...values: $ReadOnlyArray + strings: ReadonlyArray, + ...values: ReadonlyArray ): string { let str = ''; diff --git a/src/__testUtils__/genFuzzStrings.js b/src/__testUtils__/genFuzzStrings.ts similarity index 83% rename from src/__testUtils__/genFuzzStrings.js rename to src/__testUtils__/genFuzzStrings.ts index 4ead99080c..b9e4a0af7e 100644 --- a/src/__testUtils__/genFuzzStrings.js +++ b/src/__testUtils__/genFuzzStrings.ts @@ -1,10 +1,10 @@ /** * Generator that produces all possible combinations of allowed characters. */ -export default function* genFuzzStrings(options: {| - allowedChars: Array, - maxLength: number, -|}): Generator { +export default function* genFuzzStrings(options: { + allowedChars: Array; + maxLength: number; +}): Generator { const { allowedChars, maxLength } = options; const numAllowedChars = allowedChars.length; diff --git a/src/__testUtils__/inspectStr.js b/src/__testUtils__/inspectStr.ts similarity index 76% rename from src/__testUtils__/inspectStr.js rename to src/__testUtils__/inspectStr.ts index a99a28150a..2fce34558e 100644 --- a/src/__testUtils__/inspectStr.js +++ b/src/__testUtils__/inspectStr.ts @@ -1,7 +1,7 @@ /** * Special inspect function to produce readable string literal for error messages in tests */ -export default function inspectStr(str: ?string): string { +export default function inspectStr(str: string | null | undefined): string { if (str == null) { return 'null'; } diff --git a/src/__testUtils__/kitchenSinkQuery.js b/src/__testUtils__/kitchenSinkQuery.ts similarity index 97% rename from src/__testUtils__/kitchenSinkQuery.js rename to src/__testUtils__/kitchenSinkQuery.ts index 2ccdc9dc92..a7c9cf9d02 100644 --- a/src/__testUtils__/kitchenSinkQuery.js +++ b/src/__testUtils__/kitchenSinkQuery.ts @@ -1,4 +1,3 @@ -// $FlowFixMe[incompatible-call] const kitchenSinkQuery: string = String.raw` query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery { whoever123is: node(id: [123, 456]) { diff --git a/src/__testUtils__/kitchenSinkSDL.js b/src/__testUtils__/kitchenSinkSDL.ts similarity index 100% rename from src/__testUtils__/kitchenSinkSDL.js rename to src/__testUtils__/kitchenSinkSDL.ts diff --git a/src/__testUtils__/resolveOnNextTick.js b/src/__testUtils__/resolveOnNextTick.ts similarity index 100% rename from src/__testUtils__/resolveOnNextTick.js rename to src/__testUtils__/resolveOnNextTick.ts diff --git a/src/__tests__/starWarsData.js b/src/__tests__/starWarsData.ts similarity index 84% rename from src/__tests__/starWarsData.js rename to src/__tests__/starWarsData.ts index 7e1917b8bd..a1263bff2b 100644 --- a/src/__tests__/starWarsData.js +++ b/src/__tests__/starWarsData.ts @@ -3,30 +3,29 @@ * They represent the shape of the data visited during field resolution. */ export type Character = { - id: string, - name: string, - friends: Array, - appearsIn: Array, - ... + id: string; + name: string; + friends: Array; + appearsIn: Array; }; -export type Human = {| - type: 'Human', - id: string, - name: string, - friends: Array, - appearsIn: Array, - homePlanet?: string, -|}; - -export type Droid = {| - type: 'Droid', - id: string, - name: string, - friends: Array, - appearsIn: Array, - primaryFunction: string, -|}; +export type Human = { + type: 'Human'; + id: string; + name: string; + friends: Array; + appearsIn: Array; + homePlanet?: string; +}; + +export type Droid = { + type: 'Droid'; + id: string; + name: string; + friends: Array; + appearsIn: Array; + primaryFunction: string; +}; /** * This defines a basic set of data for our Star Wars Schema. @@ -35,7 +34,6 @@ export type Droid = {| * fetching this data from a backend service rather than from hardcoded * JSON objects in a more complex demo. */ - const luke: Human = { type: 'Human', id: '1000', @@ -79,7 +77,9 @@ const tarkin: Human = { appearsIn: [4], }; -const humanData: {| [id: string]: Human |} = { +const humanData: { + [id: string]: Human; +} = { [luke.id]: luke, [vader.id]: vader, [han.id]: han, @@ -105,7 +105,9 @@ const artoo: Droid = { primaryFunction: 'Astromech', }; -const droidData: {| [id: string]: Droid |} = { +const droidData: { + [id: string]: Droid; +} = { [threepio.id]: threepio, [artoo.id]: artoo, }; diff --git a/src/__tests__/starWarsIntrospection-test.js b/src/__tests__/starWarsIntrospection-test.ts similarity index 100% rename from src/__tests__/starWarsIntrospection-test.js rename to src/__tests__/starWarsIntrospection-test.ts diff --git a/src/__tests__/starWarsQuery-test.js b/src/__tests__/starWarsQuery-test.ts similarity index 100% rename from src/__tests__/starWarsQuery-test.js rename to src/__tests__/starWarsQuery-test.ts diff --git a/src/__tests__/starWarsSchema.js b/src/__tests__/starWarsSchema.ts similarity index 100% rename from src/__tests__/starWarsSchema.js rename to src/__tests__/starWarsSchema.ts diff --git a/src/__tests__/starWarsValidation-test.js b/src/__tests__/starWarsValidation-test.ts similarity index 100% rename from src/__tests__/starWarsValidation-test.js rename to src/__tests__/starWarsValidation-test.ts diff --git a/src/__tests__/version-test.js b/src/__tests__/version-test.ts similarity index 89% rename from src/__tests__/version-test.js rename to src/__tests__/version-test.ts index 7d9a0acf0c..94c9e93ad1 100644 --- a/src/__tests__/version-test.js +++ b/src/__tests__/version-test.ts @@ -30,8 +30,7 @@ describe('Version', () => { } expect( - `${major}.${minor}.${patch}` + - // istanbul ignore next (Can't be verified on all versions) + `${major}.${minor}.${patch}` + // istanbul ignore next (Can't be verified on all versions) (preReleaseTag !== null ? '-' + preReleaseTag : ''), ).to.equal(version); }); diff --git a/src/error/GraphQLError.js b/src/error/GraphQLError.ts similarity index 87% rename from src/error/GraphQLError.js rename to src/error/GraphQLError.ts index e3c397679f..1cf1e2dff4 100644 --- a/src/error/GraphQLError.js +++ b/src/error/GraphQLError.ts @@ -3,9 +3,9 @@ import isObjectLike from '../jsutils/isObjectLike'; -import type { ASTNode } from '../language/ast'; -import type { Source } from '../language/source'; -import type { SourceLocation } from '../language/location'; +import { ASTNode } from '../language/ast'; +import { Source } from '../language/source'; +import { SourceLocation } from '../language/location'; import { getLocation } from '../language/location'; import { printLocation, printSourceLocation } from '../language/printLocation'; @@ -35,7 +35,7 @@ export class GraphQLError extends Error { * * Enumerable, and appears in the result of JSON.stringify(). */ - +locations: $ReadOnlyArray | void; + readonly locations: ReadonlyArray | void; /** * An array describing the JSON-path into the execution response which @@ -43,12 +43,12 @@ export class GraphQLError extends Error { * * Enumerable, and appears in the result of JSON.stringify(). */ - +path: $ReadOnlyArray | void; + readonly path: ReadonlyArray | void; /** * An array of GraphQL AST Nodes corresponding to this error. */ - +nodes: $ReadOnlyArray | void; + readonly nodes: ReadonlyArray | void; /** * The source GraphQL document for the first location of this error. @@ -56,33 +56,43 @@ export class GraphQLError extends Error { * Note that if this Error represents more than one node, the source may not * represent nodes after the first node. */ - +source: Source | void; + readonly source: Source | void; /** * An array of character offsets within the source GraphQL document * which correspond to this error. */ - +positions: $ReadOnlyArray | void; + readonly positions: ReadonlyArray | void; /** * The original error thrown from a field resolver during execution. */ - +originalError: ?Error; + readonly originalError: Error | null | undefined; /** * Extension fields to add to the formatted error. */ - +extensions: { [key: string]: mixed, ... } | void; + readonly extensions: { + [key: string]: unknown; + } | void; constructor( message: string, - nodes?: $ReadOnlyArray | ASTNode | void | null, - source?: ?Source, - positions?: ?$ReadOnlyArray, - path?: ?$ReadOnlyArray, - originalError?: ?(Error & { +extensions?: mixed, ... }), - extensions?: ?{ [key: string]: mixed, ... }, - ): void { + nodes?: ReadonlyArray | ASTNode | void | null, + source?: Source | null | undefined, + positions?: ReadonlyArray | null | undefined, + path?: ReadonlyArray | null | undefined, + originalError?: + | (Error & { readonly extensions?: unknown }) + | null + | undefined, + extensions?: + | { + [key: string]: unknown; + } + | null + | undefined, + ) { super(message); // Compute list of blame nodes. @@ -133,7 +143,7 @@ export class GraphQLError extends Error { } } - Object.defineProperties((this: any), { + Object.defineProperties(this as any, { name: { value: 'GraphQLError' }, message: { value: message, diff --git a/src/error/__tests__/GraphQLError-test.js b/src/error/__tests__/GraphQLError-test.ts similarity index 100% rename from src/error/__tests__/GraphQLError-test.js rename to src/error/__tests__/GraphQLError-test.ts diff --git a/src/error/__tests__/formatError-test.js b/src/error/__tests__/formatError-test.ts similarity index 100% rename from src/error/__tests__/formatError-test.js rename to src/error/__tests__/formatError-test.ts diff --git a/src/error/__tests__/locatedError-test.js b/src/error/__tests__/locatedError-test.ts similarity index 77% rename from src/error/__tests__/locatedError-test.js rename to src/error/__tests__/locatedError-test.ts index 3de473b4c9..a8cf8318d6 100644 --- a/src/error/__tests__/locatedError-test.js +++ b/src/error/__tests__/locatedError-test.ts @@ -18,19 +18,19 @@ describe('locatedError', () => { it('passes GraphQLError-ish through', () => { const e = new Error('I have a different prototype chain'); - (e: any).locations = []; - (e: any).path = []; - (e: any).nodes = []; - (e: any).source = null; - (e: any).positions = []; - (e: any).name = 'GraphQLError'; + (e as any).locations = []; + (e as any).path = []; + (e as any).nodes = []; + (e as any).source = null; + (e as any).positions = []; + (e as any).name = 'GraphQLError'; expect(locatedError(e, [], [])).to.deep.equal(e); }); it('does not pass through elasticsearch-like errors', () => { const e = new Error('I am from elasticsearch'); - (e: any).path = '/something/feed/_search'; + (e as any).path = '/something/feed/_search'; expect(locatedError(e, [], [])).to.not.deep.equal(e); }); diff --git a/src/error/formatError.js b/src/error/formatError.ts similarity index 81% rename from src/error/formatError.js rename to src/error/formatError.ts index d73cc897b0..fe637a2931 100644 --- a/src/error/formatError.js +++ b/src/error/formatError.ts @@ -1,8 +1,8 @@ import devAssert from '../jsutils/devAssert'; -import type { SourceLocation } from '../language/location'; +import { SourceLocation } from '../language/location'; -import type { GraphQLError } from './GraphQLError'; +import { GraphQLError } from './GraphQLError'; /** * Given a GraphQLError, format it according to the rules described by the @@ -23,28 +23,33 @@ export function formatError(error: GraphQLError): GraphQLFormattedError { /** * @see https://github.com/graphql/graphql-spec/blob/master/spec/Section%207%20--%20Response.md#errors */ -export type GraphQLFormattedError = {| +export type GraphQLFormattedError = { /** * A short, human-readable summary of the problem that **SHOULD NOT** change * from occurrence to occurrence of the problem, except for purposes of * localization. */ - +message: string, + readonly message: string; + /** * If an error can be associated to a particular point in the requested * GraphQL document, it should contain a list of locations. */ - +locations: $ReadOnlyArray | void, + readonly locations: ReadonlyArray | void; + /** * If an error can be associated to a particular field in the GraphQL result, * it _must_ contain an entry with the key `path` that details the path of * the response field which experienced the error. This allows clients to * identify whether a null result is intentional or caused by a runtime error. */ - +path: $ReadOnlyArray | void, + readonly path: ReadonlyArray | void; + /** * Reserved for implementors to extend the protocol however they see fit, * and hence there are no additional restrictions on its contents. */ - +extensions?: { [key: string]: mixed, ... }, -|}; + readonly extensions?: { + [key: string]: unknown; + }; +}; diff --git a/src/error/index.js b/src/error/index.ts similarity index 76% rename from src/error/index.js rename to src/error/index.ts index 914a6dbe46..5b69ce096c 100644 --- a/src/error/index.js +++ b/src/error/index.ts @@ -5,4 +5,4 @@ export { syntaxError } from './syntaxError'; export { locatedError } from './locatedError'; export { formatError } from './formatError'; -export type { GraphQLFormattedError } from './formatError'; +export { GraphQLFormattedError } from './formatError'; diff --git a/src/error/locatedError.js b/src/error/locatedError.ts similarity index 72% rename from src/error/locatedError.js rename to src/error/locatedError.ts index 1b7c335070..259332073b 100644 --- a/src/error/locatedError.js +++ b/src/error/locatedError.ts @@ -1,6 +1,6 @@ import inspect from '../jsutils/inspect'; -import type { ASTNode } from '../language/ast'; +import { ASTNode } from '../language/ast'; import { GraphQLError } from './GraphQLError'; @@ -10,9 +10,9 @@ import { GraphQLError } from './GraphQLError'; * document responsible for the original Error. */ export function locatedError( - rawOriginalError: mixed, - nodes: ASTNode | $ReadOnlyArray | void | null, - path?: ?$ReadOnlyArray, + rawOriginalError: unknown, + nodes: ASTNode | ReadonlyArray | void | null, + path?: ReadonlyArray | null | undefined, ): GraphQLError { // Sometimes a non-error is thrown, wrap it as an Error instance to ensure a consistent Error interface. const originalError: Error | GraphQLError = @@ -22,14 +22,14 @@ export function locatedError( // Note: this uses a brand-check to support GraphQL errors originating from other contexts. if (Array.isArray(originalError.path)) { - return (originalError: any); + return originalError as any; } return new GraphQLError( originalError.message, - (originalError: any).nodes ?? nodes, - (originalError: any).source, - (originalError: any).positions, + (originalError as any).nodes ?? nodes, + (originalError as any).source, + (originalError as any).positions, path, originalError, ); diff --git a/src/error/syntaxError.js b/src/error/syntaxError.ts similarity index 89% rename from src/error/syntaxError.js rename to src/error/syntaxError.ts index 21a2dc18e4..87cba885c3 100644 --- a/src/error/syntaxError.js +++ b/src/error/syntaxError.ts @@ -1,4 +1,4 @@ -import type { Source } from '../language/source'; +import { Source } from '../language/source'; import { GraphQLError } from './GraphQLError'; diff --git a/src/execution/__tests__/abstract-test.js b/src/execution/__tests__/abstract-test.ts similarity index 97% rename from src/execution/__tests__/abstract-test.js rename to src/execution/__tests__/abstract-test.ts index 519585af0f..dbb57c3f89 100644 --- a/src/execution/__tests__/abstract-test.js +++ b/src/execution/__tests__/abstract-test.ts @@ -16,11 +16,11 @@ import { buildSchema } from '../../utilities/buildASTSchema'; import { executeSync, execute } from '../execute'; -async function executeQuery(args: {| - schema: GraphQLSchema, - query: string, - rootValue?: mixed, -|}) { +async function executeQuery(args: { + schema: GraphQLSchema; + query: string; + rootValue?: unknown; +}) { const { schema, query, rootValue } = args; const document = parse(query); const result = executeSync({ @@ -533,7 +533,7 @@ describe('Execute: Handles execution of abstract types', () => { } `); - function expectError({ forTypeName }: {| forTypeName: mixed |}) { + function expectError({ forTypeName }: { forTypeName: unknown }) { const rootValue = { pet: { __typename: forTypeName } }; const result = executeSync({ schema, document, rootValue }); return { @@ -569,13 +569,13 @@ describe('Execute: Handles execution of abstract types', () => { ); // FIXME: workaround since we can't inject resolveType into SDL - (schema.getType('Pet'): any).resolveType = () => []; + (schema.getType('Pet') as any).resolveType = () => []; expectError({ forTypeName: undefined }).toEqual( 'Abstract type "Pet" must resolve to an Object type at runtime for field "Query.pet" with value { __typename: undefined }, received "[]".', ); // FIXME: workaround since we can't inject resolveType into SDL - (schema.getType('Pet'): any).resolveType = () => schema.getType('Cat'); + (schema.getType('Pet') as any).resolveType = () => schema.getType('Cat'); expectError({ forTypeName: undefined }).toEqual( 'Support for returning GraphQLObjectType from resolveType was removed in graphql-js@16.0.0 please return type name instead.', ); diff --git a/src/execution/__tests__/directives-test.js b/src/execution/__tests__/directives-test.ts similarity index 100% rename from src/execution/__tests__/directives-test.js rename to src/execution/__tests__/directives-test.ts diff --git a/src/execution/__tests__/executor-test.js b/src/execution/__tests__/executor-test.ts similarity index 99% rename from src/execution/__tests__/executor-test.js rename to src/execution/__tests__/executor-test.ts index d1ea9bb49f..d3aba46bc7 100644 --- a/src/execution/__tests__/executor-test.js +++ b/src/execution/__tests__/executor-test.ts @@ -489,7 +489,7 @@ describe('Execute: Handles basic execution tasks', () => { }, asyncReturnErrorWithExtensions() { const error = new Error('Error getting asyncReturnErrorWithExtensions'); - (error: any).extensions = { foo: 'bar' }; + (error as any).extensions = { foo: 'bar' }; return Promise.resolve(error); }, diff --git a/src/execution/__tests__/lists-test.js b/src/execution/__tests__/lists-test.ts similarity index 96% rename from src/execution/__tests__/lists-test.js rename to src/execution/__tests__/lists-test.ts index 926802a51b..2b04d604c1 100644 --- a/src/execution/__tests__/lists-test.js +++ b/src/execution/__tests__/lists-test.ts @@ -8,7 +8,7 @@ import { buildSchema } from '../../utilities/buildASTSchema'; import { execute, executeSync } from '../execute'; describe('Execute: Accepts any iterable as list value', () => { - function complete(rootValue: mixed) { + function complete(rootValue: unknown) { return executeSync({ schema: buildSchema('type Query { listField: [String] }'), document: parse('{ listField }'), @@ -65,7 +65,7 @@ describe('Execute: Accepts any iterable as list value', () => { }); describe('Execute: Handles list nullability', () => { - async function complete(args: {| listField: mixed, as: string |}) { + async function complete(args: { listField: unknown; as: string }) { const { listField, as } = args; const schema = buildSchema(`type Query { listField: ${as} }`); const document = parse('{ listField }'); @@ -85,11 +85,11 @@ describe('Execute: Handles list nullability', () => { } return result; - function executeQuery(listValue: mixed) { + function executeQuery(listValue: unknown) { return execute({ schema, document, rootValue: { listField: listValue } }); } - function promisify(value: mixed): Promise { + function promisify(value: unknown): Promise { return value instanceof Error ? Promise.reject(value) : Promise.resolve(value); diff --git a/src/execution/__tests__/mutations-test.js b/src/execution/__tests__/mutations-test.ts similarity index 100% rename from src/execution/__tests__/mutations-test.js rename to src/execution/__tests__/mutations-test.ts diff --git a/src/execution/__tests__/nonnull-test.js b/src/execution/__tests__/nonnull-test.ts similarity index 99% rename from src/execution/__tests__/nonnull-test.js rename to src/execution/__tests__/nonnull-test.ts index 4eb38f12b6..3e770e0530 100644 --- a/src/execution/__tests__/nonnull-test.js +++ b/src/execution/__tests__/nonnull-test.ts @@ -9,7 +9,7 @@ import { GraphQLNonNull, GraphQLObjectType } from '../../type/definition'; import { buildSchema } from '../../utilities/buildASTSchema'; -import type { ExecutionResult } from '../execute'; +import { ExecutionResult } from '../execute'; import { execute, executeSync } from '../execute'; const syncError = new Error('sync'); @@ -106,7 +106,7 @@ const schema = buildSchema(` function executeQuery( query: string, - rootValue: mixed, + rootValue: unknown, ): ExecutionResult | Promise { return execute({ schema, document: parse(query), rootValue }); } @@ -122,7 +122,7 @@ function patchData(data: ExecutionResult): ExecutionResult { return JSON.parse(patch(JSON.stringify(data))); } -async function executeSyncAndAsync(query: string, rootValue: mixed) { +async function executeSyncAndAsync(query: string, rootValue: unknown) { const syncResult = executeSync({ schema, document: parse(query), rootValue }); const asyncResult = await execute({ schema, diff --git a/src/execution/__tests__/resolve-test.js b/src/execution/__tests__/resolve-test.ts similarity index 93% rename from src/execution/__tests__/resolve-test.js rename to src/execution/__tests__/resolve-test.ts index afe911e7bc..63c206c41e 100644 --- a/src/execution/__tests__/resolve-test.js +++ b/src/execution/__tests__/resolve-test.ts @@ -3,7 +3,7 @@ import { describe, it } from 'mocha'; import { parse } from '../../language/parser'; -import type { GraphQLFieldConfig } from '../../type/definition'; +import { GraphQLFieldConfig } from '../../type/definition'; import { GraphQLSchema } from '../../type/schema'; import { GraphQLInt, GraphQLString } from '../../type/scalars'; import { GraphQLObjectType } from '../../type/definition'; @@ -64,7 +64,7 @@ describe('Execute: resolve function', () => { this._num = num; } - test(args: {| addend1: number |}, context: {| addend2: number |}) { + test(args: { addend1: number }, context: { addend2: number }) { return this._num + args.addend1 + context.addend2; } } @@ -95,7 +95,7 @@ describe('Execute: resolve function', () => { resolve: (source, args) => JSON.stringify([source, args]), }); - function executeQuery(query: string, rootValue?: mixed) { + function executeQuery(query: string, rootValue?: unknown) { const document = parse(query); return executeSync({ schema, document, rootValue }); } diff --git a/src/execution/__tests__/schema-test.js b/src/execution/__tests__/schema-test.ts similarity index 100% rename from src/execution/__tests__/schema-test.js rename to src/execution/__tests__/schema-test.ts diff --git a/src/execution/__tests__/sync-test.js b/src/execution/__tests__/sync-test.ts similarity index 100% rename from src/execution/__tests__/sync-test.js rename to src/execution/__tests__/sync-test.ts diff --git a/src/execution/__tests__/union-interface-test.js b/src/execution/__tests__/union-interface-test.ts similarity index 100% rename from src/execution/__tests__/union-interface-test.js rename to src/execution/__tests__/union-interface-test.ts diff --git a/src/execution/__tests__/variables-test.js b/src/execution/__tests__/variables-test.ts similarity index 99% rename from src/execution/__tests__/variables-test.js rename to src/execution/__tests__/variables-test.ts index 9f637dd7ed..5048a13185 100644 --- a/src/execution/__tests__/variables-test.js +++ b/src/execution/__tests__/variables-test.ts @@ -7,7 +7,7 @@ import invariant from '../../jsutils/invariant'; import { Kind } from '../../language/kinds'; import { parse } from '../../language/parser'; -import type { GraphQLArgumentConfig } from '../../type/definition'; +import { GraphQLArgumentConfig } from '../../type/definition'; import { GraphQLSchema } from '../../type/schema'; import { GraphQLString } from '../../type/scalars'; import { @@ -119,7 +119,9 @@ const schema = new GraphQLSchema({ query: TestType }); function executeQuery( query: string, - variableValues?: { [variable: string]: mixed, ... }, + variableValues?: { + [variable: string]: unknown; + }, ) { const document = parse(query); return executeSync({ schema, document, variableValues }); diff --git a/src/execution/execute.js b/src/execution/execute.ts similarity index 90% rename from src/execution/execute.js rename to src/execution/execute.ts index c9c2c6a809..3ba15de046 100644 --- a/src/execution/execute.js +++ b/src/execution/execute.ts @@ -1,6 +1,6 @@ -import type { Path } from '../jsutils/Path'; -import type { ObjMap } from '../jsutils/ObjMap'; -import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; +import { Path } from '../jsutils/Path'; +import { ObjMap } from '../jsutils/ObjMap'; +import { PromiseOrValue } from '../jsutils/PromiseOrValue'; import inspect from '../jsutils/inspect'; import memoize3 from '../jsutils/memoize3'; import invariant from '../jsutils/invariant'; @@ -12,11 +12,11 @@ import promiseReduce from '../jsutils/promiseReduce'; import promiseForObject from '../jsutils/promiseForObject'; import { addPath, pathToArray } from '../jsutils/Path'; -import type { GraphQLFormattedError } from '../error/formatError'; +import { GraphQLFormattedError } from '../error/formatError'; import { GraphQLError } from '../error/GraphQLError'; import { locatedError } from '../error/locatedError'; -import type { +import { DocumentNode, OperationDefinitionNode, SelectionSetNode, @@ -27,8 +27,8 @@ import type { } from '../language/ast'; import { Kind } from '../language/kinds'; -import type { GraphQLSchema } from '../type/schema'; -import type { +import { GraphQLSchema } from '../type/schema'; +import { GraphQLObjectType, GraphQLOutputType, GraphQLLeafType, @@ -92,17 +92,19 @@ import { * Namely, schema of the type system that is currently executing, * and the fragments defined in the query document */ -export type ExecutionContext = {| - schema: GraphQLSchema, - fragments: ObjMap, - rootValue: mixed, - contextValue: mixed, - operation: OperationDefinitionNode, - variableValues: { [variable: string]: mixed, ... }, - fieldResolver: GraphQLFieldResolver, - typeResolver: GraphQLTypeResolver, - errors: Array, -|}; +export type ExecutionContext = { + schema: GraphQLSchema; + fragments: ObjMap; + rootValue: unknown; + contextValue: unknown; + operation: OperationDefinitionNode; + variableValues: { + [variable: string]: unknown; + }; + fieldResolver: GraphQLFieldResolver; + typeResolver: GraphQLTypeResolver; + errors: Array; +}; /** * The result of GraphQL execution. @@ -111,28 +113,33 @@ export type ExecutionContext = {| * - `data` is the result of a successful execution of the query. * - `extensions` is reserved for adding non-standard properties. */ -export type ExecutionResult = {| - errors?: $ReadOnlyArray, - data?: ObjMap | null, - extensions?: ObjMap, -|}; - -export type FormattedExecutionResult = {| - errors?: $ReadOnlyArray, - data?: ObjMap | null, - extensions?: ObjMap, -|}; - -export type ExecutionArgs = {| - schema: GraphQLSchema, - document: DocumentNode, - rootValue?: mixed, - contextValue?: mixed, - variableValues?: ?{ +[variable: string]: mixed, ... }, - operationName?: ?string, - fieldResolver?: ?GraphQLFieldResolver, - typeResolver?: ?GraphQLTypeResolver, -|}; +export type ExecutionResult = { + errors?: ReadonlyArray; + data?: ObjMap | null; + extensions?: ObjMap; +}; + +export type FormattedExecutionResult = { + errors?: ReadonlyArray; + data?: ObjMap | null; + extensions?: ObjMap; +}; + +export type ExecutionArgs = { + schema: GraphQLSchema; + document: DocumentNode; + rootValue?: unknown; + contextValue?: unknown; + variableValues?: + | { + readonly [variable: string]: unknown; + } + | null + | undefined; + operationName?: string | null | undefined; + fieldResolver?: GraphQLFieldResolver | null | undefined; + typeResolver?: GraphQLTypeResolver | null | undefined; +}; /** * Implements the "Evaluating requests" section of the GraphQL specification. @@ -210,7 +217,7 @@ export function executeSync(args: ExecutionArgs): ExecutionResult { */ function buildResponse( exeContext: ExecutionContext, - data: PromiseOrValue | null>, + data: PromiseOrValue | null>, ): PromiseOrValue { if (isPromise(data)) { return data.then((resolved) => buildResponse(exeContext, resolved)); @@ -229,7 +236,12 @@ function buildResponse( export function assertValidExecutionArguments( schema: GraphQLSchema, document: DocumentNode, - rawVariableValues: ?{ +[variable: string]: mixed, ... }, + rawVariableValues: + | { + readonly [variable: string]: unknown; + } + | null + | undefined, ): void { devAssert(document, 'Must provide document.'); @@ -254,13 +266,18 @@ export function assertValidExecutionArguments( export function buildExecutionContext( schema: GraphQLSchema, document: DocumentNode, - rootValue: mixed, - contextValue: mixed, - rawVariableValues: ?{ +[variable: string]: mixed, ... }, - operationName: ?string, - fieldResolver: ?GraphQLFieldResolver, - typeResolver?: ?GraphQLTypeResolver, -): $ReadOnlyArray | ExecutionContext { + rootValue: unknown, + contextValue: unknown, + rawVariableValues: + | { + readonly [variable: string]: unknown; + } + | null + | undefined, + operationName: string | null | undefined, + fieldResolver: GraphQLFieldResolver | null | undefined, + typeResolver?: GraphQLTypeResolver | null | undefined, +): ReadonlyArray | ExecutionContext { let operation: OperationDefinitionNode | void; const fragments: ObjMap = Object.create(null); for (const definition of document.definitions) { @@ -278,6 +295,7 @@ export function buildExecutionContext( } else if (definition.name?.value === operationName) { operation = definition; } + break; case Kind.FRAGMENT_DEFINITION: fragments[definition.name.value] = definition; @@ -325,8 +343,8 @@ export function buildExecutionContext( function executeOperation( exeContext: ExecutionContext, operation: OperationDefinitionNode, - rootValue: mixed, -): PromiseOrValue | null> { + rootValue: unknown, +): PromiseOrValue | null> { const type = getOperationRootType(exeContext.schema, operation); const fields = collectFields( exeContext, @@ -366,10 +384,10 @@ function executeOperation( function executeFieldsSerially( exeContext: ExecutionContext, parentType: GraphQLObjectType, - sourceValue: mixed, + sourceValue: unknown, path: Path | void, fields: ObjMap>, -): PromiseOrValue> { +): PromiseOrValue> { return promiseReduce( Object.keys(fields), (results, responseName) => { @@ -405,10 +423,10 @@ function executeFieldsSerially( function executeFields( exeContext: ExecutionContext, parentType: GraphQLObjectType, - sourceValue: mixed, + sourceValue: unknown, path: Path | void, fields: ObjMap>, -): PromiseOrValue> { +): PromiseOrValue> { const results = Object.create(null); let containsPromise = false; @@ -584,10 +602,10 @@ function getFieldEntryKey(node: FieldNode): string { function resolveField( exeContext: ExecutionContext, parentType: GraphQLObjectType, - source: mixed, - fieldNodes: $ReadOnlyArray, + source: unknown, + fieldNodes: ReadonlyArray, path: Path, -): PromiseOrValue { +): PromiseOrValue { const fieldNode = fieldNodes[0]; const fieldName = fieldNode.name.value; @@ -661,8 +679,8 @@ function resolveField( */ export function buildResolveInfo( exeContext: ExecutionContext, - fieldDef: GraphQLField, - fieldNodes: $ReadOnlyArray, + fieldDef: GraphQLField, + fieldNodes: ReadonlyArray, parentType: GraphQLObjectType, path: Path, ): GraphQLResolveInfo { @@ -723,11 +741,11 @@ function handleFieldError( function completeValue( exeContext: ExecutionContext, returnType: GraphQLOutputType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, info: GraphQLResolveInfo, path: Path, - result: mixed, -): PromiseOrValue { + result: unknown, +): PromiseOrValue { // If result is an Error, throw a located error. if (result instanceof Error) { throw result; @@ -805,7 +823,7 @@ function completeValue( invariant( false, 'Cannot complete value of unexpected output type: ' + - inspect((returnType: empty)), + inspect(returnType as never), ); } @@ -816,11 +834,11 @@ function completeValue( function completeListValue( exeContext: ExecutionContext, returnType: GraphQLList, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, info: GraphQLResolveInfo, path: Path, - result: mixed, -): PromiseOrValue<$ReadOnlyArray> { + result: unknown, +): PromiseOrValue> { if (!isCollection(result)) { throw new GraphQLError( `Expected Iterable, but did not find one for field "${info.parentType.name}.${info.fieldName}".`, @@ -886,7 +904,10 @@ function completeListValue( * Complete a Scalar or Enum by serializing to a valid value, returning * null if serialization is not possible. */ -function completeLeafValue(returnType: GraphQLLeafType, result: mixed): mixed { +function completeLeafValue( + returnType: GraphQLLeafType, + result: unknown, +): unknown { const serializedResult = returnType.serialize(result); if (serializedResult === undefined) { throw new Error( @@ -904,11 +925,11 @@ function completeLeafValue(returnType: GraphQLLeafType, result: mixed): mixed { function completeAbstractValue( exeContext: ExecutionContext, returnType: GraphQLAbstractType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, info: GraphQLResolveInfo, path: Path, - result: mixed, -): PromiseOrValue> { + result: unknown, +): PromiseOrValue> { const resolveTypeFn = returnType.resolveType ?? exeContext.typeResolver; const contextValue = exeContext.contextValue; const runtimeType = resolveTypeFn(result, contextValue, info, returnType); @@ -951,12 +972,12 @@ function completeAbstractValue( } function ensureValidRuntimeType( - runtimeTypeName: mixed, + runtimeTypeName: unknown, exeContext: ExecutionContext, returnType: GraphQLAbstractType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, info: GraphQLResolveInfo, - result: mixed, + result: unknown, ): GraphQLObjectType { if (runtimeTypeName == null) { throw new GraphQLError( @@ -1011,11 +1032,11 @@ function ensureValidRuntimeType( function completeObjectValue( exeContext: ExecutionContext, returnType: GraphQLObjectType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, info: GraphQLResolveInfo, path: Path, - result: mixed, -): PromiseOrValue> { + result: unknown, +): PromiseOrValue> { // If there is an isTypeOf predicate function, call it with the // current result. If isTypeOf returns false, then raise an error rather // than continuing execution. @@ -1053,8 +1074,8 @@ function completeObjectValue( function invalidReturnTypeError( returnType: GraphQLObjectType, - result: mixed, - fieldNodes: $ReadOnlyArray, + result: unknown, + fieldNodes: ReadonlyArray, ): GraphQLError { return new GraphQLError( `Expected value of type "${returnType.name}" but got: ${inspect(result)}.`, @@ -1065,10 +1086,10 @@ function invalidReturnTypeError( function collectAndExecuteSubfields( exeContext: ExecutionContext, returnType: GraphQLObjectType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, path: Path, - result: mixed, -): PromiseOrValue> { + result: unknown, +): PromiseOrValue> { // Collect sub-fields to execute to complete this value. const subFieldNodes = collectSubfields(exeContext, returnType, fieldNodes); return executeFields(exeContext, returnType, result, path, subFieldNodes); @@ -1083,7 +1104,7 @@ const collectSubfields = memoize3(_collectSubfields); function _collectSubfields( exeContext: ExecutionContext, returnType: GraphQLObjectType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, ): ObjMap> { let subFieldNodes = Object.create(null); const visitedFragmentNames = Object.create(null); @@ -1111,12 +1132,10 @@ function _collectSubfields( * Otherwise, test each possible type for the abstract type by calling * isTypeOf for the object being coerced, returning the first type that matches. */ -export const defaultTypeResolver: GraphQLTypeResolver = function ( - value, - contextValue, - info, - abstractType, -) { +export const defaultTypeResolver: GraphQLTypeResolver< + unknown, + unknown +> = function (value, contextValue, info, abstractType) { // First, look for `__typename`. if (isObjectLike(value) && typeof value.__typename === 'string') { return value.__typename; @@ -1158,8 +1177,8 @@ export const defaultTypeResolver: GraphQLTypeResolver = function ( * of calling that function while passing along args and context value. */ export const defaultFieldResolver: GraphQLFieldResolver< - mixed, - mixed, + unknown, + unknown > = function (source: any, args, contextValue, info) { // ensure source is a value for which property access is acceptable. if (isObjectLike(source) || typeof source === 'function') { @@ -1186,7 +1205,7 @@ export function getFieldDef( schema: GraphQLSchema, parentType: GraphQLObjectType, fieldName: string, -): ?GraphQLField { +): GraphQLField | null | undefined { if ( fieldName === SchemaMetaFieldDef.name && schema.getQueryType() === parentType diff --git a/src/execution/index.js b/src/execution/index.ts similarity index 95% rename from src/execution/index.js rename to src/execution/index.ts index 5ae0706ec9..f7812501cc 100644 --- a/src/execution/index.js +++ b/src/execution/index.ts @@ -7,7 +7,7 @@ export { defaultTypeResolver, } from './execute'; -export type { +export { ExecutionArgs, ExecutionResult, FormattedExecutionResult, diff --git a/src/execution/values.js b/src/execution/values.ts similarity index 87% rename from src/execution/values.js rename to src/execution/values.ts index 51c0678098..f7accac8d1 100644 --- a/src/execution/values.js +++ b/src/execution/values.ts @@ -1,11 +1,11 @@ -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; import keyMap from '../jsutils/keyMap'; import inspect from '../jsutils/inspect'; import printPathArray from '../jsutils/printPathArray'; import { GraphQLError } from '../error/GraphQLError'; -import type { +import { FieldNode, DirectiveNode, VariableDefinitionNode, @@ -13,9 +13,9 @@ import type { import { Kind } from '../language/kinds'; import { print } from '../language/printer'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLField } from '../type/definition'; -import type { GraphQLDirective } from '../type/directives'; +import { GraphQLSchema } from '../type/schema'; +import { GraphQLField } from '../type/definition'; +import { GraphQLDirective } from '../type/directives'; import { isInputType, isNonNullType } from '../type/definition'; import { typeFromAST } from '../utilities/typeFromAST'; @@ -23,8 +23,12 @@ import { valueFromAST } from '../utilities/valueFromAST'; import { coerceInputValue } from '../utilities/coerceInputValue'; type CoercedVariableValues = - | {| errors: $ReadOnlyArray |} - | {| coerced: { [variable: string]: mixed, ... } |}; + | { errors: ReadonlyArray } + | { + coerced: { + [variable: string]: unknown; + }; + }; /** * Prepares an object map of variableValues of the correct type based on the @@ -39,9 +43,11 @@ type CoercedVariableValues = */ export function getVariableValues( schema: GraphQLSchema, - varDefNodes: $ReadOnlyArray, - inputs: { +[variable: string]: mixed, ... }, - options?: {| maxErrors?: number |}, + varDefNodes: ReadonlyArray, + inputs: { + readonly [variable: string]: unknown; + }, + options?: { maxErrors?: number }, ): CoercedVariableValues { const errors = []; const maxErrors = options?.maxErrors; @@ -72,10 +78,14 @@ export function getVariableValues( function coerceVariableValues( schema: GraphQLSchema, - varDefNodes: $ReadOnlyArray, - inputs: { +[variable: string]: mixed, ... }, - onError: (GraphQLError) => void, -): { [variable: string]: mixed, ... } { + varDefNodes: ReadonlyArray, + inputs: { + readonly [variable: string]: unknown; + }, + onError: (arg0: GraphQLError) => void, +): { + [variable: string]: unknown; +} { const coercedValues = {}; for (const varDefNode of varDefNodes) { const varName = varDefNode.variable.name.value; @@ -157,10 +167,12 @@ function coerceVariableValues( * @internal */ export function getArgumentValues( - def: GraphQLField | GraphQLDirective, + def: GraphQLField | GraphQLDirective, node: FieldNode | DirectiveNode, - variableValues?: ?ObjMap, -): { [argument: string]: mixed, ... } { + variableValues?: ObjMap | null | undefined, +): { + [argument: string]: unknown; +} { const coercedValues = {}; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') @@ -244,9 +256,11 @@ export function getArgumentValues( */ export function getDirectiveValues( directiveDef: GraphQLDirective, - node: { +directives?: $ReadOnlyArray, ... }, - variableValues?: ?ObjMap, -): void | { [argument: string]: mixed, ... } { + node: { readonly directives?: ReadonlyArray }, + variableValues?: ObjMap | null | undefined, +): void | { + [argument: string]: unknown; +} { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') const directiveNode = node.directives?.find( (directive) => directive.name.value === directiveDef.name, @@ -257,6 +271,6 @@ export function getDirectiveValues( } } -function hasOwnProperty(obj: mixed, prop: string): boolean { +function hasOwnProperty(obj: unknown, prop: string): boolean { return Object.prototype.hasOwnProperty.call(obj, prop); } diff --git a/src/graphql.js b/src/graphql.ts similarity index 84% rename from src/graphql.js rename to src/graphql.ts index 622be10cd5..38e65c5c8f 100644 --- a/src/graphql.js +++ b/src/graphql.ts @@ -1,19 +1,16 @@ -import type { PromiseOrValue } from './jsutils/PromiseOrValue'; +import { PromiseOrValue } from './jsutils/PromiseOrValue'; import isPromise from './jsutils/isPromise'; -import type { Source } from './language/source'; +import { Source } from './language/source'; import { parse } from './language/parser'; import { validate } from './validation/validate'; -import type { - GraphQLFieldResolver, - GraphQLTypeResolver, -} from './type/definition'; -import type { GraphQLSchema } from './type/schema'; +import { GraphQLFieldResolver, GraphQLTypeResolver } from './type/definition'; +import { GraphQLSchema } from './type/schema'; import { validateSchema } from './type/validate'; -import type { ExecutionResult } from './execution/execute'; +import { ExecutionResult } from './execution/execute'; import { execute } from './execution/execute'; /** @@ -55,16 +52,21 @@ import { execute } from './execution/execute'; * If not provided, the default type resolver is used (which looks for a * `__typename` field or alternatively calls the `isTypeOf` method). */ -export type GraphQLArgs = {| - schema: GraphQLSchema, - source: string | Source, - rootValue?: mixed, - contextValue?: mixed, - variableValues?: ?{ +[variable: string]: mixed, ... }, - operationName?: ?string, - fieldResolver?: ?GraphQLFieldResolver, - typeResolver?: ?GraphQLTypeResolver, -|}; +export type GraphQLArgs = { + schema: GraphQLSchema; + source: string | Source; + rootValue?: unknown; + contextValue?: unknown; + variableValues?: + | { + readonly [variable: string]: unknown; + } + | null + | undefined; + operationName?: string | null | undefined; + fieldResolver?: GraphQLFieldResolver | null | undefined; + typeResolver?: GraphQLTypeResolver | null | undefined; +}; export function graphql(args: GraphQLArgs): Promise { // Always return a Promise for a consistent API. diff --git a/src/index.js b/src/index.ts similarity index 71% rename from src/index.js rename to src/index.ts index 873a374ba2..0907f72d02 100644 --- a/src/index.js +++ b/src/index.ts @@ -26,7 +26,7 @@ export { version, versionInfo } from './version'; // The primary entry point into fulfilling a GraphQL request. -export type { GraphQLArgs } from './graphql'; +export { GraphQLArgs } from './graphql'; export { graphql, graphqlSync } from './graphql'; // Create and operate on GraphQL type definitions and schema. @@ -41,25 +41,20 @@ export { GraphQLEnumType, GraphQLInputObjectType, GraphQLList, - GraphQLNonNull, - // Standard GraphQL Scalars + GraphQLNonNull, // Standard GraphQL Scalars specifiedScalarTypes, GraphQLInt, GraphQLFloat, GraphQLString, GraphQLBoolean, - GraphQLID, - // Built-in Directives defined by the Spec + GraphQLID, // Built-in Directives defined by the Spec specifiedDirectives, GraphQLIncludeDirective, GraphQLSkipDirective, GraphQLDeprecatedDirective, - GraphQLSpecifiedByDirective, - // "Enum" of Type Kinds - TypeKind, - // Constant Deprecation Reason - DEFAULT_DEPRECATION_REASON, - // GraphQL Types for introspection. + GraphQLSpecifiedByDirective, // "Enum" of Type Kinds + TypeKind, // Constant Deprecation Reason + DEFAULT_DEPRECATION_REASON, // GraphQL Types for introspection. introspectionTypes, __Schema, __Directive, @@ -68,12 +63,10 @@ export { __Field, __InputValue, __EnumValue, - __TypeKind, - // Meta-field definitions. + __TypeKind, // Meta-field definitions. SchemaMetaFieldDef, TypeMetaFieldDef, - TypeNameMetaFieldDef, - // Predicates + TypeNameMetaFieldDef, // Predicates isSchema, isDirective, isType, @@ -97,8 +90,7 @@ export { isRequiredInputField, isSpecifiedScalarType, isIntrospectionType, - isSpecifiedDirective, - // Assertions + isSpecifiedDirective, // Assertions assertSchema, assertDirective, assertType, @@ -117,16 +109,14 @@ export { assertAbstractType, assertWrappingType, assertNullableType, - assertNamedType, - // Un-modifiers + assertNamedType, // Un-modifiers getNullableType, - getNamedType, - // Validate GraphQL schema. + getNamedType, // Validate GraphQL schema. validateSchema, assertValidSchema, } from './type/index'; -export type { +export { GraphQLType, GraphQLInputType, GraphQLOutputType, @@ -174,27 +164,21 @@ export { Token, Source, Location, - getLocation, - // Print source location + getLocation, // Print source location printLocation, - printSourceLocation, - // Lex + printSourceLocation, // Lex Lexer, - TokenKind, - // Parse + TokenKind, // Parse parse, parseValue, - parseType, - // Print - print, - // Visit + parseType, // Print + print, // Visit visit, visitInParallel, getVisitFn, BREAK, Kind, - DirectiveLocation, - // Predicates + DirectiveLocation, // Predicates isDefinitionNode, isExecutableDefinitionNode, isSelectionNode, @@ -206,21 +190,18 @@ export { isTypeExtensionNode, } from './language/index'; -export type { +export { ParseOptions, SourceLocation, TokenKindEnum, KindEnum, - DirectiveLocationEnum, - // Visitor utilities + DirectiveLocationEnum, // Visitor utilities ASTVisitor, Visitor, VisitFn, - VisitorKeyMap, - // AST nodes + VisitorKeyMap, // AST nodes ASTNode, - ASTKindToNode, - // Each kind of AST node + ASTKindToNode, // Each kind of AST node NameNode, DocumentNode, DefinitionNode, @@ -286,22 +267,20 @@ export { getDirectiveValues, } from './execution/index'; -export type { +export { ExecutionArgs, ExecutionResult, FormattedExecutionResult, } from './execution/index'; export { subscribe, createSourceEventStream } from './subscription/index'; -export type { SubscriptionArgs } from './subscription/index'; +export { SubscriptionArgs } from './subscription/index'; // Validate GraphQL documents. export { validate, - ValidationContext, - // All validation rules in the GraphQL Specification. - specifiedRules, - // Individual validation rules. + ValidationContext, // All validation rules in the GraphQL Specification. + specifiedRules, // Individual validation rules. ExecutableDefinitionsRule, FieldsOnCorrectTypeRule, FragmentsOnCompositeTypesRule, @@ -327,21 +306,19 @@ export { UniqueVariableNamesRule, ValuesOfCorrectTypeRule, VariablesAreInputTypesRule, - VariablesInAllowedPositionRule, - // SDL-specific validation rules + VariablesInAllowedPositionRule, // SDL-specific validation rules LoneSchemaDefinitionRule, UniqueOperationTypesRule, UniqueTypeNamesRule, UniqueEnumValueNamesRule, UniqueFieldDefinitionNamesRule, UniqueDirectiveNamesRule, - PossibleTypeExtensionsRule, - // Custom validation rules + PossibleTypeExtensionsRule, // Custom validation rules NoDeprecatedCustomRule, NoSchemaIntrospectionCustomRule, } from './validation/index'; -export type { ValidationRule } from './validation/index'; +export { ValidationRule } from './validation/index'; // Create, format, and print GraphQL errors. export { @@ -352,74 +329,50 @@ export { formatError, } from './error/index'; -export type { GraphQLFormattedError } from './error/index'; +export { GraphQLFormattedError } from './error/index'; // Utilities for operating on GraphQL type schema and parsed sources. export { // Produce the GraphQL query recommended for a full schema introspection. // Accepts optional IntrospectionOptions. - getIntrospectionQuery, - // Gets the target Operation from a Document. - getOperationAST, - // Gets the Type for the target Operation AST. - getOperationRootType, - // Convert a GraphQLSchema to an IntrospectionQuery. - introspectionFromSchema, - // Build a GraphQLSchema from an introspection result. - buildClientSchema, - // Build a GraphQLSchema from a parsed GraphQL Schema language AST. - buildASTSchema, - // Build a GraphQLSchema from a GraphQL schema language document. - buildSchema, - // Extends an existing GraphQLSchema from a parsed GraphQL Schema + getIntrospectionQuery, // Gets the target Operation from a Document. + getOperationAST, // Gets the Type for the target Operation AST. + getOperationRootType, // Convert a GraphQLSchema to an IntrospectionQuery. + introspectionFromSchema, // Build a GraphQLSchema from an introspection result. + buildClientSchema, // Build a GraphQLSchema from a parsed GraphQL Schema language AST. + buildASTSchema, // Build a GraphQLSchema from a GraphQL schema language document. + buildSchema, // Extends an existing GraphQLSchema from a parsed GraphQL Schema // language AST. - extendSchema, - // Sort a GraphQLSchema. - lexicographicSortSchema, - // Print a GraphQLSchema to GraphQL Schema language. - printSchema, - // Print a GraphQLType to GraphQL Schema language. - printType, - // Prints the built-in introspection schema in the Schema Language + extendSchema, // Sort a GraphQLSchema. + lexicographicSortSchema, // Print a GraphQLSchema to GraphQL Schema language. + printSchema, // Print a GraphQLType to GraphQL Schema language. + printType, // Prints the built-in introspection schema in the Schema Language // format. - printIntrospectionSchema, - // Create a GraphQLType from a GraphQL language AST. - typeFromAST, - // Create a JavaScript value from a GraphQL language AST with a Type. - valueFromAST, - // Create a JavaScript value from a GraphQL language AST without a Type. - valueFromASTUntyped, - // Create a GraphQL language AST from a JavaScript value. - astFromValue, - // A helper to use within recursive-descent visitors which need to be aware of + printIntrospectionSchema, // Create a GraphQLType from a GraphQL language AST. + typeFromAST, // Create a JavaScript value from a GraphQL language AST with a Type. + valueFromAST, // Create a JavaScript value from a GraphQL language AST without a Type. + valueFromASTUntyped, // Create a GraphQL language AST from a JavaScript value. + astFromValue, // A helper to use within recursive-descent visitors which need to be aware of // the GraphQL type system. TypeInfo, - visitWithTypeInfo, - // Coerces a JavaScript value to a GraphQL type, or produces errors. - coerceInputValue, - // Concatenates multiple AST together. - concatAST, - // Separates an AST into an AST per Operation. - separateOperations, - // Strips characters that are not significant to the validity or execution + visitWithTypeInfo, // Coerces a JavaScript value to a GraphQL type, or produces errors. + coerceInputValue, // Concatenates multiple AST together. + concatAST, // Separates an AST into an AST per Operation. + separateOperations, // Strips characters that are not significant to the validity or execution // of a GraphQL document. - stripIgnoredCharacters, - // Comparators for types + stripIgnoredCharacters, // Comparators for types isEqualType, isTypeSubTypeOf, - doTypesOverlap, - // Asserts a string is a valid GraphQL name. - assertValidName, - // Determine if a string is a valid GraphQL name. - isValidNameError, - // Compares two GraphQLSchemas and detects breaking changes. + doTypesOverlap, // Asserts a string is a valid GraphQL name. + assertValidName, // Determine if a string is a valid GraphQL name. + isValidNameError, // Compares two GraphQLSchemas and detects breaking changes. BreakingChangeType, DangerousChangeType, findBreakingChanges, findDangerousChanges, } from './utilities/index'; -export type { +export { IntrospectionOptions, IntrospectionQuery, IntrospectionSchema, diff --git a/src/jsutils/ObjMap.js b/src/jsutils/ObjMap.js deleted file mode 100644 index 9b6ef5e16e..0000000000 --- a/src/jsutils/ObjMap.js +++ /dev/null @@ -1,7 +0,0 @@ -export type ObjMap = { [key: string]: T, __proto__: null, ... }; -export type ObjMapLike = ObjMap | { [key: string]: T, ... }; - -export type ReadOnlyObjMap = { +[key: string]: T, __proto__: null, ... }; -export type ReadOnlyObjMapLike = - | ReadOnlyObjMap - | { +[key: string]: T, ... }; diff --git a/src/jsutils/ObjMap.ts b/src/jsutils/ObjMap.ts new file mode 100644 index 0000000000..07330fc834 --- /dev/null +++ b/src/jsutils/ObjMap.ts @@ -0,0 +1,13 @@ +export type ObjMap = { __proto__: null; [key: string]: T }; +export type ObjMapLike = + | ObjMap + | { + [key: string]: T; + }; + +export type ReadOnlyObjMap = { __proto__: null; readonly [key: string]: T }; +export type ReadOnlyObjMapLike = + | ReadOnlyObjMap + | { + readonly [key: string]: T; + }; diff --git a/src/jsutils/Path.js b/src/jsutils/Path.ts similarity index 62% rename from src/jsutils/Path.js rename to src/jsutils/Path.ts index 47e8c7693c..0703b6bf9b 100644 --- a/src/jsutils/Path.js +++ b/src/jsutils/Path.ts @@ -1,8 +1,9 @@ -export type Path = {| - +prev: Path | void, - +key: string | number, - +typename: string | void, -|}; +import { $ReadOnly } from 'utility-types'; +export type Path = { + readonly prev: Path | void; + readonly key: string | number; + readonly typename: string | void; +}; /** * Given a Path and a key, return a new Path containing the new key. @@ -18,7 +19,9 @@ export function addPath( /** * Given a Path, return an Array of the path keys. */ -export function pathToArray(path: ?$ReadOnly): Array { +export function pathToArray( + path: $ReadOnly | null | undefined, +): Array { const flattened = []; let curr = path; while (curr) { diff --git a/src/jsutils/PromiseOrValue.js b/src/jsutils/PromiseOrValue.js deleted file mode 100644 index e493c87e06..0000000000 --- a/src/jsutils/PromiseOrValue.js +++ /dev/null @@ -1 +0,0 @@ -export type PromiseOrValue<+T> = Promise | T; diff --git a/src/jsutils/PromiseOrValue.ts b/src/jsutils/PromiseOrValue.ts new file mode 100644 index 0000000000..6b2517ee62 --- /dev/null +++ b/src/jsutils/PromiseOrValue.ts @@ -0,0 +1 @@ +export type PromiseOrValue = Promise | T; diff --git a/src/jsutils/__tests__/didYouMean-test.js b/src/jsutils/__tests__/didYouMean-test.ts similarity index 100% rename from src/jsutils/__tests__/didYouMean-test.js rename to src/jsutils/__tests__/didYouMean-test.ts diff --git a/src/jsutils/__tests__/identityFunc-test.js b/src/jsutils/__tests__/identityFunc-test.ts similarity index 100% rename from src/jsutils/__tests__/identityFunc-test.js rename to src/jsutils/__tests__/identityFunc-test.ts diff --git a/src/jsutils/__tests__/inspect-test.js b/src/jsutils/__tests__/inspect-test.ts similarity index 98% rename from src/jsutils/__tests__/inspect-test.js rename to src/jsutils/__tests__/inspect-test.ts index ba7ca9a86c..7b48339c3e 100644 --- a/src/jsutils/__tests__/inspect-test.js +++ b/src/jsutils/__tests__/inspect-test.ts @@ -166,7 +166,7 @@ describe('inspect', () => { expect(inspect([[new Foo()]])).to.equal('[[[Foo]]]'); - (Foo.prototype: any)[Symbol.toStringTag] = 'Bar'; + (Foo.prototype as any)[Symbol.toStringTag] = 'Bar'; expect(inspect([[new Foo()]])).to.equal('[[[Bar]]]'); const objectWithoutClassName = new (function () { diff --git a/src/jsutils/__tests__/instanceOf-test.js b/src/jsutils/__tests__/instanceOf-test.ts similarity index 100% rename from src/jsutils/__tests__/instanceOf-test.js rename to src/jsutils/__tests__/instanceOf-test.ts diff --git a/src/jsutils/__tests__/invariant-test.js b/src/jsutils/__tests__/invariant-test.ts similarity index 100% rename from src/jsutils/__tests__/invariant-test.js rename to src/jsutils/__tests__/invariant-test.ts diff --git a/src/jsutils/__tests__/isAsyncIterable-test.js b/src/jsutils/__tests__/isAsyncIterable-test.ts similarity index 100% rename from src/jsutils/__tests__/isAsyncIterable-test.js rename to src/jsutils/__tests__/isAsyncIterable-test.ts diff --git a/src/jsutils/__tests__/isCollection-test.js b/src/jsutils/__tests__/isCollection-test.ts similarity index 100% rename from src/jsutils/__tests__/isCollection-test.js rename to src/jsutils/__tests__/isCollection-test.ts diff --git a/src/jsutils/__tests__/isObjectLike-test.js b/src/jsutils/__tests__/isObjectLike-test.ts similarity index 100% rename from src/jsutils/__tests__/isObjectLike-test.js rename to src/jsutils/__tests__/isObjectLike-test.ts diff --git a/src/jsutils/__tests__/suggestionList-test.js b/src/jsutils/__tests__/suggestionList-test.ts similarity index 100% rename from src/jsutils/__tests__/suggestionList-test.js rename to src/jsutils/__tests__/suggestionList-test.ts diff --git a/src/jsutils/__tests__/toObjMap-test.js b/src/jsutils/__tests__/toObjMap-test.ts similarity index 96% rename from src/jsutils/__tests__/toObjMap-test.js rename to src/jsutils/__tests__/toObjMap-test.ts index 3f5ab924f5..faab3caef5 100644 --- a/src/jsutils/__tests__/toObjMap-test.js +++ b/src/jsutils/__tests__/toObjMap-test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import type { ObjMapLike } from '../ObjMap'; +import { ObjMapLike } from '../ObjMap'; import toObjMap from '../toObjMap'; // Workaround to make both ESLint and Flow happy diff --git a/src/jsutils/devAssert.js b/src/jsutils/devAssert.ts similarity index 71% rename from src/jsutils/devAssert.js rename to src/jsutils/devAssert.ts index da2adfcd00..f8364cee32 100644 --- a/src/jsutils/devAssert.js +++ b/src/jsutils/devAssert.ts @@ -1,4 +1,4 @@ -export default function devAssert(condition: mixed, message: string): void { +export default function devAssert(condition: unknown, message: string): void { const booleanCondition = Boolean(condition); // istanbul ignore else (See transformation done in './resources/inlineInvariant.js') if (!booleanCondition) { diff --git a/src/jsutils/didYouMean.js b/src/jsutils/didYouMean.ts similarity index 73% rename from src/jsutils/didYouMean.js rename to src/jsutils/didYouMean.ts index 45e1a93c83..c511fdee6d 100644 --- a/src/jsutils/didYouMean.js +++ b/src/jsutils/didYouMean.ts @@ -3,15 +3,15 @@ const MAX_SUGGESTIONS = 5; /** * Given [ A, B, C ] return ' Did you mean A, B, or C?'. */ -declare function didYouMean(suggestions: $ReadOnlyArray): string; -// eslint-disable-next-line no-redeclare -declare function didYouMean( +function didYouMean(suggestions: ReadonlyArray): string; +function didYouMean( subMessage: string, - suggestions: $ReadOnlyArray, + suggestions: ReadonlyArray, ): string; - -// eslint-disable-next-line no-redeclare -export default function didYouMean(firstArg, secondArg) { +function didYouMean( + firstArg: string | ReadonlyArray, + secondArg?: ReadonlyArray, +): string { const [subMessage, suggestionsArg] = typeof firstArg === 'string' ? [firstArg, secondArg] @@ -36,3 +36,5 @@ export default function didYouMean(firstArg, secondArg) { const lastItem = selected.pop(); return message + selected.join(', ') + ', or ' + lastItem + '?'; } + +export default didYouMean diff --git a/src/jsutils/identityFunc.js b/src/jsutils/identityFunc.ts similarity index 100% rename from src/jsutils/identityFunc.js rename to src/jsutils/identityFunc.ts diff --git a/src/jsutils/inspect.js b/src/jsutils/inspect.ts similarity index 87% rename from src/jsutils/inspect.js rename to src/jsutils/inspect.ts index f841f7da8d..728023d9d9 100644 --- a/src/jsutils/inspect.js +++ b/src/jsutils/inspect.ts @@ -6,11 +6,11 @@ const MAX_RECURSIVE_DEPTH = 2; /** * Used to print values in error messages. */ -export default function inspect(value: mixed): string { +export default function inspect(value: unknown): string { return formatValue(value, []); } -function formatValue(value: mixed, seenValues: Array): string { +function formatValue(value: unknown, seenValues: Array): string { switch (typeof value) { case 'string': return JSON.stringify(value); @@ -20,6 +20,7 @@ function formatValue(value: mixed, seenValues: Array): string { if (value === null) { return 'null'; } + return formatObjectValue(value, seenValues); default: return String(value); @@ -28,7 +29,7 @@ function formatValue(value: mixed, seenValues: Array): string { function formatObjectValue( value: Object, - previouslySeenValues: Array, + previouslySeenValues: Array, ): string { if (previouslySeenValues.indexOf(value) !== -1) { return '[Circular]'; @@ -52,7 +53,7 @@ function formatObjectValue( return formatObject(value, seenValues); } -function formatObject(object: Object, seenValues: Array): string { +function formatObject(object: Object, seenValues: Array): string { const keys = Object.keys(object); if (keys.length === 0) { return '{}'; @@ -70,7 +71,10 @@ function formatObject(object: Object, seenValues: Array): string { return '{ ' + properties.join(', ') + ' }'; } -function formatArray(array: Array, seenValues: Array): string { +function formatArray( + array: Array, + seenValues: Array, +): string { if (array.length === 0) { return '[]'; } diff --git a/src/jsutils/instanceOf.js b/src/jsutils/instanceOf.ts similarity index 64% rename from src/jsutils/instanceOf.js rename to src/jsutils/instanceOf.ts index e55cd13f73..4aeccf7e6b 100644 --- a/src/jsutils/instanceOf.js +++ b/src/jsutils/instanceOf.ts @@ -2,21 +2,16 @@ * A replacement for instanceof which includes an error warning when multi-realm * constructors are detected. */ -declare function instanceOf( - value: mixed, - constructor: mixed, -): boolean %checks(value instanceof constructor); +declare function instanceOf(value: unknown, constructor: unknown): boolean; // See: https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production // See: https://webpack.js.org/guides/production/ -export default process.env.NODE_ENV === 'production' - ? // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317') - // eslint-disable-next-line no-shadow - function instanceOf(value: mixed, constructor: mixed): boolean { +export default process.env.NODE_ENV === 'production' // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317') + ? // eslint-disable-next-line no-shadow + function instanceOf(value: unknown, constructor: unknown): boolean { return value instanceof constructor; - } - : // eslint-disable-next-line no-shadow - function instanceOf(value: any, constructor: any): boolean { + } // eslint-disable-next-line no-shadow + : function instanceOf(value: any, constructor: any): boolean { if (value instanceof constructor) { return true; } @@ -24,8 +19,7 @@ export default process.env.NODE_ENV === 'production' const valueClass = value.constructor; const className = constructor.name; if (className && valueClass && valueClass.name === className) { - throw new Error( - `Cannot use ${className} "${value}" from another module or realm. + throw new Error(`Cannot use ${className} "${value}" from another module or realm. Ensure that there is only one instance of "graphql" in the node_modules directory. If different versions of "graphql" are the dependencies of other @@ -36,8 +30,7 @@ https://yarnpkg.com/en/docs/selective-version-resolutions Duplicate "graphql" modules cannot be used at the same time since different versions may have different capabilities and behavior. The data from one version used in the function from another could produce confusing and -spurious results.`, - ); +spurious results.`); } } return false; diff --git a/src/jsutils/invariant.js b/src/jsutils/invariant.ts similarity index 76% rename from src/jsutils/invariant.js rename to src/jsutils/invariant.ts index 668f6ea426..ea99078976 100644 --- a/src/jsutils/invariant.js +++ b/src/jsutils/invariant.ts @@ -1,4 +1,4 @@ -export default function invariant(condition: mixed, message?: string): void { +export default function invariant(condition: unknown, message?: string): void { const booleanCondition = Boolean(condition); // istanbul ignore else (See transformation done in './resources/inlineInvariant.js') if (!booleanCondition) { diff --git a/src/jsutils/isAsyncIterable.js b/src/jsutils/isAsyncIterable.ts similarity index 81% rename from src/jsutils/isAsyncIterable.js rename to src/jsutils/isAsyncIterable.ts index 39a90bd346..9bd2900ec4 100644 --- a/src/jsutils/isAsyncIterable.js +++ b/src/jsutils/isAsyncIterable.ts @@ -2,8 +2,7 @@ * Returns true if the provided object implements the AsyncIterator protocol via * either implementing a `Symbol.asyncIterator` or `"@@asyncIterator"` method. */ -declare function isAsyncIterable(value: mixed): boolean %checks(value instanceof - AsyncIterable); +declare function isAsyncIterable(value: unknown): boolean; // eslint-disable-next-line no-redeclare export default function isAsyncIterable(maybeAsyncIterable) { diff --git a/src/jsutils/isCollection.js b/src/jsutils/isCollection.ts similarity index 92% rename from src/jsutils/isCollection.js rename to src/jsutils/isCollection.ts index b120bda73d..9956f9160f 100644 --- a/src/jsutils/isCollection.js +++ b/src/jsutils/isCollection.ts @@ -19,8 +19,7 @@ * An Object value which might implement the Iterable or Array-like protocols. * @return {boolean} true if Iterable or Array-like Object. */ -declare function isCollection(value: mixed): boolean %checks(value instanceof - Iterable); +declare function isCollection(value: unknown): boolean; // eslint-disable-next-line no-redeclare export default function isCollection(obj) { diff --git a/src/jsutils/isObjectLike.js b/src/jsutils/isObjectLike.ts similarity index 72% rename from src/jsutils/isObjectLike.js rename to src/jsutils/isObjectLike.ts index a5f9754dd7..d7c48e39a4 100644 --- a/src/jsutils/isObjectLike.js +++ b/src/jsutils/isObjectLike.ts @@ -2,6 +2,6 @@ * Return true if `value` is object-like. A value is object-like if it's not * `null` and has a `typeof` result of "object". */ -export default function isObjectLike(value: mixed): boolean %checks { +export default function isObjectLike(value: unknown): boolean { return typeof value == 'object' && value !== null; } diff --git a/src/jsutils/isPromise.js b/src/jsutils/isPromise.ts similarity index 73% rename from src/jsutils/isPromise.js rename to src/jsutils/isPromise.ts index 4bbb5768e1..f0df139456 100644 --- a/src/jsutils/isPromise.js +++ b/src/jsutils/isPromise.ts @@ -2,8 +2,7 @@ * Returns true if the value acts like a Promise, i.e. has a "then" function, * otherwise returns false. */ -declare function isPromise(value: mixed): boolean %checks(value instanceof - Promise); +declare function isPromise(value: unknown): boolean; // eslint-disable-next-line no-redeclare export default function isPromise(value) { diff --git a/src/jsutils/keyMap.js b/src/jsutils/keyMap.ts similarity index 92% rename from src/jsutils/keyMap.js rename to src/jsutils/keyMap.ts index eb847d02c9..670726a1e8 100644 --- a/src/jsutils/keyMap.js +++ b/src/jsutils/keyMap.ts @@ -1,4 +1,4 @@ -import type { ObjMap } from './ObjMap'; +import { ObjMap } from './ObjMap'; /** * Creates a keyed JS object from an array, given a function to produce the keys @@ -24,7 +24,7 @@ import type { ObjMap } from './ObjMap'; * */ export default function keyMap( - list: $ReadOnlyArray, + list: ReadonlyArray, keyFn: (item: T) => string, ): ObjMap { return list.reduce((map, item) => { diff --git a/src/jsutils/keyValMap.js b/src/jsutils/keyValMap.ts similarity index 91% rename from src/jsutils/keyValMap.js rename to src/jsutils/keyValMap.ts index a91e90b447..b73ad8276d 100644 --- a/src/jsutils/keyValMap.js +++ b/src/jsutils/keyValMap.ts @@ -1,4 +1,4 @@ -import type { ObjMap } from './ObjMap'; +import { ObjMap } from './ObjMap'; /** * Creates a keyed JS object from an array, given a function to produce the keys @@ -18,7 +18,7 @@ import type { ObjMap } from './ObjMap'; * */ export default function keyValMap( - list: $ReadOnlyArray, + list: ReadonlyArray, keyFn: (item: T) => string, valFn: (item: T) => V, ): ObjMap { diff --git a/src/jsutils/mapValue.js b/src/jsutils/mapValue.ts similarity index 91% rename from src/jsutils/mapValue.js rename to src/jsutils/mapValue.ts index a2b91be2dd..c0f1cbd7b7 100644 --- a/src/jsutils/mapValue.js +++ b/src/jsutils/mapValue.ts @@ -1,6 +1,6 @@ import objectEntries from '../polyfills/objectEntries'; -import type { ObjMap } from './ObjMap'; +import { ObjMap } from './ObjMap'; /** * Creates an object map with the same keys as `map` and values generated by diff --git a/src/jsutils/memoize3.js b/src/jsutils/memoize3.ts similarity index 75% rename from src/jsutils/memoize3.js rename to src/jsutils/memoize3.ts index be73a96fb2..3b62e3e20b 100644 --- a/src/jsutils/memoize3.js +++ b/src/jsutils/memoize3.ts @@ -2,11 +2,13 @@ * Memoizes the provided three-argument function. */ export default function memoize3< - A1: { ... } | $ReadOnlyArray, - A2: { ... } | $ReadOnlyArray, - A3: { ... } | $ReadOnlyArray, - R: mixed, ->(fn: (A1, A2, A3) => R): (A1, A2, A3) => R { + A1 extends {} | ReadonlyArray, + A2 extends {} | ReadonlyArray, + A3 extends {} | ReadonlyArray, + R extends unknown +>( + fn: (arg0: A1, arg1: A2, arg2: A3) => R, +): (arg0: A1, arg1: A2, arg2: A3) => R { let cache0; return function memoized(a1, a2, a3) { diff --git a/src/jsutils/printPathArray.js b/src/jsutils/printPathArray.ts similarity index 84% rename from src/jsutils/printPathArray.js rename to src/jsutils/printPathArray.ts index 34ab13daa0..fe98a4115e 100644 --- a/src/jsutils/printPathArray.js +++ b/src/jsutils/printPathArray.ts @@ -2,7 +2,7 @@ * Build a string describing the path. */ export default function printPathArray( - path: $ReadOnlyArray, + path: ReadonlyArray, ): string { return path .map((key) => diff --git a/src/jsutils/promiseForObject.js b/src/jsutils/promiseForObject.ts similarity index 94% rename from src/jsutils/promiseForObject.js rename to src/jsutils/promiseForObject.ts index bf07e4a3f0..e86b08f2b2 100644 --- a/src/jsutils/promiseForObject.js +++ b/src/jsutils/promiseForObject.ts @@ -1,4 +1,4 @@ -import type { ObjMap } from './ObjMap'; +import { ObjMap } from './ObjMap'; /** * This function transforms a JS object `ObjMap>` into diff --git a/src/jsutils/promiseReduce.js b/src/jsutils/promiseReduce.ts similarity index 82% rename from src/jsutils/promiseReduce.js rename to src/jsutils/promiseReduce.ts index 43d905283e..a529f44c64 100644 --- a/src/jsutils/promiseReduce.js +++ b/src/jsutils/promiseReduce.ts @@ -1,4 +1,4 @@ -import type { PromiseOrValue } from './PromiseOrValue'; +import { PromiseOrValue } from './PromiseOrValue'; import isPromise from './isPromise'; @@ -10,8 +10,8 @@ import isPromise from './isPromise'; * return a Promise. */ export default function promiseReduce( - values: $ReadOnlyArray, - callback: (U, T) => PromiseOrValue, + values: ReadonlyArray, + callback: (arg0: U, arg1: T) => PromiseOrValue, initialValue: PromiseOrValue, ): PromiseOrValue { return values.reduce( diff --git a/src/jsutils/suggestionList.js b/src/jsutils/suggestionList.ts similarity index 99% rename from src/jsutils/suggestionList.js rename to src/jsutils/suggestionList.ts index 4128e24b07..d7aa2b6ea9 100644 --- a/src/jsutils/suggestionList.js +++ b/src/jsutils/suggestionList.ts @@ -4,7 +4,7 @@ */ export default function suggestionList( input: string, - options: $ReadOnlyArray, + options: ReadonlyArray, ): Array { const optionsByDistance = Object.create(null); const lexicalDistance = new LexicalDistance(input); diff --git a/src/jsutils/toObjMap.js b/src/jsutils/toObjMap.ts similarity index 97% rename from src/jsutils/toObjMap.js rename to src/jsutils/toObjMap.ts index c0dc9e2fdb..83cb5e9571 100644 --- a/src/jsutils/toObjMap.js +++ b/src/jsutils/toObjMap.ts @@ -1,6 +1,6 @@ import objectEntries from '../polyfills/objectEntries'; -import type { +import { ObjMap, ObjMapLike, ReadOnlyObjMap, diff --git a/src/language/__tests__/blockString-fuzz.js b/src/language/__tests__/blockString-fuzz.ts similarity index 100% rename from src/language/__tests__/blockString-fuzz.js rename to src/language/__tests__/blockString-fuzz.ts diff --git a/src/language/__tests__/blockString-test.js b/src/language/__tests__/blockString-test.ts similarity index 100% rename from src/language/__tests__/blockString-test.js rename to src/language/__tests__/blockString-test.ts diff --git a/src/language/__tests__/lexer-test.js b/src/language/__tests__/lexer-test.ts similarity index 100% rename from src/language/__tests__/lexer-test.js rename to src/language/__tests__/lexer-test.ts diff --git a/src/language/__tests__/parser-test.js b/src/language/__tests__/parser-test.ts similarity index 100% rename from src/language/__tests__/parser-test.js rename to src/language/__tests__/parser-test.ts diff --git a/src/language/__tests__/predicates-test.js b/src/language/__tests__/predicates-test.ts similarity index 95% rename from src/language/__tests__/predicates-test.js rename to src/language/__tests__/predicates-test.ts index eb620abd61..4e0a4c028c 100644 --- a/src/language/__tests__/predicates-test.js +++ b/src/language/__tests__/predicates-test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import type { ASTNode } from '../ast'; +import { ASTNode } from '../ast'; import { Kind } from '../kinds'; import { isDefinitionNode, @@ -16,10 +16,10 @@ import { } from '../predicates'; const allASTNodes: Array = Object.values(Kind).map( - (kind) => ({ kind }: any), + (kind) => ({ kind } as any), ); -function filterNodes(predicate: (ASTNode) => boolean): Array { +function filterNodes(predicate: (arg0: ASTNode) => boolean): Array { return allASTNodes.filter(predicate).map(({ kind }) => kind); } diff --git a/src/language/__tests__/printLocation-test.js b/src/language/__tests__/printLocation-test.ts similarity index 100% rename from src/language/__tests__/printLocation-test.js rename to src/language/__tests__/printLocation-test.ts diff --git a/src/language/__tests__/printer-test.js b/src/language/__tests__/printer-test.ts similarity index 97% rename from src/language/__tests__/printer-test.js rename to src/language/__tests__/printer-test.ts index 55adc17a78..b6d205139b 100644 --- a/src/language/__tests__/printer-test.js +++ b/src/language/__tests__/printer-test.ts @@ -83,15 +83,13 @@ describe('Printer: Query document', () => { parse('{trip(wheelchair:false arriveBy:false){dateTime}}'), ); - expect(printed).to.equal( - dedent` + expect(printed).to.equal(dedent` { trip(wheelchair: false, arriveBy: false) { dateTime } } - `, - ); + `); }); it('puts arguments on multiple lines if line is long (> 80 chars)', () => { @@ -101,8 +99,7 @@ describe('Printer: Query document', () => { ), ); - expect(printed).to.equal( - dedent` + expect(printed).to.equal(dedent` { trip( wheelchair: false @@ -113,8 +110,7 @@ describe('Printer: Query document', () => { dateTime } } - `, - ); + `); }); it('Experimental: prints fragment with variable directives', () => { diff --git a/src/language/__tests__/schema-parser-test.js b/src/language/__tests__/schema-parser-test.ts similarity index 98% rename from src/language/__tests__/schema-parser-test.js rename to src/language/__tests__/schema-parser-test.ts index 2e6ffbd745..043693bb65 100644 --- a/src/language/__tests__/schema-parser-test.js +++ b/src/language/__tests__/schema-parser-test.ts @@ -12,7 +12,7 @@ function expectSyntaxError(text: string) { return expect(() => parse(text)).to.throw(); } -function typeNode(name: mixed, loc: mixed) { +function typeNode(name: unknown, loc: unknown) { return { kind: 'NamedType', name: nameNode(name, loc), @@ -20,7 +20,7 @@ function typeNode(name: mixed, loc: mixed) { }; } -function nameNode(name: mixed, loc: mixed) { +function nameNode(name: unknown, loc: unknown) { return { kind: 'Name', value: name, @@ -28,11 +28,16 @@ function nameNode(name: mixed, loc: mixed) { }; } -function fieldNode(name: mixed, type: mixed, loc: mixed) { +function fieldNode(name: unknown, type: unknown, loc: unknown) { return fieldNodeWithArgs(name, type, [], loc); } -function fieldNodeWithArgs(name: mixed, type: mixed, args: mixed, loc: mixed) { +function fieldNodeWithArgs( + name: unknown, + type: unknown, + args: unknown, + loc: unknown, +) { return { kind: 'FieldDefinition', description: undefined, @@ -44,7 +49,7 @@ function fieldNodeWithArgs(name: mixed, type: mixed, args: mixed, loc: mixed) { }; } -function enumValueNode(name: mixed, loc: mixed) { +function enumValueNode(name: unknown, loc: unknown) { return { kind: 'EnumValueDefinition', name: nameNode(name, loc), @@ -55,10 +60,10 @@ function enumValueNode(name: mixed, loc: mixed) { } function inputValueNode( - name: mixed, - type: mixed, - defaultValue: mixed, - loc: mixed, + name: unknown, + type: unknown, + defaultValue: unknown, + loc: unknown, ) { return { kind: 'InputValueDefinition', diff --git a/src/language/__tests__/schema-printer-test.js b/src/language/__tests__/schema-printer-test.ts similarity index 100% rename from src/language/__tests__/schema-printer-test.js rename to src/language/__tests__/schema-printer-test.ts diff --git a/src/language/__tests__/source-test.js b/src/language/__tests__/source-test.ts similarity index 94% rename from src/language/__tests__/source-test.js rename to src/language/__tests__/source-test.ts index 31a34aa16d..5510bf1fc6 100644 --- a/src/language/__tests__/source-test.js +++ b/src/language/__tests__/source-test.ts @@ -25,7 +25,7 @@ describe('Source', () => { }); it('rejects invalid locationOffset', () => { - function createSource(locationOffset: {| line: number, column: number |}) { + function createSource(locationOffset: { line: number; column: number }) { return new Source('', '', locationOffset); } diff --git a/src/language/__tests__/toJSONDeep.js b/src/language/__tests__/toJSONDeep.ts similarity index 90% rename from src/language/__tests__/toJSONDeep.js rename to src/language/__tests__/toJSONDeep.ts index 3c3fae57f3..9c84554ce8 100644 --- a/src/language/__tests__/toJSONDeep.js +++ b/src/language/__tests__/toJSONDeep.ts @@ -4,7 +4,7 @@ import isObjectLike from '../../jsutils/isObjectLike'; * Deeply transforms an arbitrary value to a JSON-safe value by calling toJSON * on any nested value which defines it. */ -export default function toJSONDeep(value: mixed): mixed { +export default function toJSONDeep(value: unknown): unknown { if (!isObjectLike(value)) { return value; } diff --git a/src/language/__tests__/visitor-test.js b/src/language/__tests__/visitor-test.ts similarity index 97% rename from src/language/__tests__/visitor-test.js rename to src/language/__tests__/visitor-test.ts index 1dfce965b8..fe2f549542 100644 --- a/src/language/__tests__/visitor-test.js +++ b/src/language/__tests__/visitor-test.ts @@ -5,7 +5,7 @@ import kitchenSinkQuery from '../../__testUtils__/kitchenSinkQuery'; import invariant from '../../jsutils/invariant'; -import type { ASTNode } from '../ast'; +import { ASTNode } from '../ast'; import { Kind } from '../kinds'; import { parse } from '../parser'; import { visit, visitInParallel, BREAK, QueryDocumentKeys } from '../visitor'; @@ -157,7 +157,12 @@ describe('Visitor', () => { }; }, leave(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); return { ...node, selectionSet, @@ -195,7 +200,12 @@ describe('Visitor', () => { }; }, leave(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); return { ...node, definitions, @@ -236,7 +246,12 @@ describe('Visitor', () => { const ast = parse('{ a, b, c { a, b, c } }', { noLocation: true }); const editedAST = visit(ast, { leave(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); if (node.kind === 'Field' && node.name.value === 'b') { return null; } @@ -279,7 +294,12 @@ describe('Visitor', () => { const ast = parse('{ a { x } }', { noLocation: true }); visit(ast, { enter(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); if (node.kind === 'Field' && node.name.value === 'a') { return { kind: 'Field', @@ -867,7 +887,7 @@ describe('Visitor', () => { describe('Support for custom AST nodes', () => { const customAST = parse('{ a }'); - (customAST: any).definitions[0].selectionSet.selections.push({ + (customAST as any).definitions[0].selectionSet.selections.push({ kind: 'CustomField', name: { kind: 'Name', @@ -916,7 +936,7 @@ describe('Visitor', () => { it('does traverse unknown node kinds with visitor keys', () => { const customQueryDocumentKeys = { ...QueryDocumentKeys }; - (customQueryDocumentKeys: any).CustomField = ['name', 'selectionSet']; + (customQueryDocumentKeys as any).CustomField = ['name', 'selectionSet']; const visited = []; const visitor = { @@ -1316,7 +1336,12 @@ describe('Visitor', () => { visited.push(['enter', node.kind, getValue(node)]); }, leave(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); visited.push(['leave', node.kind, getValue(node)]); }, }, @@ -1368,7 +1393,12 @@ describe('Visitor', () => { visitInParallel([ { leave(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); if (node.kind === 'Field' && node.name.value === 'b') { return null; } @@ -1380,7 +1410,12 @@ describe('Visitor', () => { visited.push(['enter', node.kind, getValue(node)]); }, leave(node) { - checkVisitorFnArgs(ast, arguments, /* isEdited */ true); + checkVisitorFnArgs( + ast, + arguments, + /* isEdited */ + true, + ); visited.push(['leave', node.kind, getValue(node)]); }, }, diff --git a/src/language/ast.js b/src/language/ast.js deleted file mode 100644 index 1816ed3433..0000000000 --- a/src/language/ast.js +++ /dev/null @@ -1,640 +0,0 @@ -import type { Source } from './source'; -import type { TokenKindEnum } from './tokenKind'; - -/** - * Contains a range of UTF-8 character offsets and token references that - * identify the region of the source from which the AST derived. - */ -export class Location { - /** - * The character offset at which this Node begins. - */ - +start: number; - - /** - * The character offset at which this Node ends. - */ - +end: number; - - /** - * The Token at which this Node begins. - */ - +startToken: Token; - - /** - * The Token at which this Node ends. - */ - +endToken: Token; - - /** - * The Source document the AST represents. - */ - +source: Source; - - constructor(startToken: Token, endToken: Token, source: Source) { - this.start = startToken.start; - this.end = endToken.end; - this.startToken = startToken; - this.endToken = endToken; - this.source = source; - } - - toJSON(): {| start: number, end: number |} { - return { start: this.start, end: this.end }; - } - - // @deprecated: Will be removed in v17 - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet - [Symbol.for('nodejs.util.inspect.custom')](): mixed { - return this.toJSON(); - } -} - -/** - * Represents a range of characters represented by a lexical token - * within a Source. - */ -export class Token { - /** - * The kind of Token. - */ - +kind: TokenKindEnum; - - /** - * The character offset at which this Node begins. - */ - +start: number; - - /** - * The character offset at which this Node ends. - */ - +end: number; - - /** - * The 1-indexed line number on which this Token appears. - */ - +line: number; - - /** - * The 1-indexed column number at which this Token begins. - */ - +column: number; - - /** - * For non-punctuation tokens, represents the interpreted value of the token. - */ - +value: string | void; - - /** - * Tokens exist as nodes in a double-linked-list amongst all tokens - * including ignored tokens. is always the first node and - * the last. - */ - +prev: Token | null; - +next: Token | null; - - constructor( - kind: TokenKindEnum, - start: number, - end: number, - line: number, - column: number, - prev: Token | null, - value?: string, - ) { - this.kind = kind; - this.start = start; - this.end = end; - this.line = line; - this.column = column; - this.value = value; - this.prev = prev; - this.next = null; - } - - toJSON(): {| - kind: TokenKindEnum, - value: string | void, - line: number, - column: number, - |} { - return { - kind: this.kind, - value: this.value, - line: this.line, - column: this.column, - }; - } - - // @deprecated: Will be removed in v17 - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet - [Symbol.for('nodejs.util.inspect.custom')](): mixed { - return this.toJSON(); - } -} - -/** - * @internal - */ -export function isNode(maybeNode: mixed): boolean %checks { - return maybeNode != null && typeof maybeNode.kind === 'string'; -} - -/** - * The list of all possible AST node types. - */ -export type ASTNode = - | NameNode - | DocumentNode - | OperationDefinitionNode - | VariableDefinitionNode - | VariableNode - | SelectionSetNode - | FieldNode - | ArgumentNode - | FragmentSpreadNode - | InlineFragmentNode - | FragmentDefinitionNode - | IntValueNode - | FloatValueNode - | StringValueNode - | BooleanValueNode - | NullValueNode - | EnumValueNode - | ListValueNode - | ObjectValueNode - | ObjectFieldNode - | DirectiveNode - | NamedTypeNode - | ListTypeNode - | NonNullTypeNode - | SchemaDefinitionNode - | OperationTypeDefinitionNode - | ScalarTypeDefinitionNode - | ObjectTypeDefinitionNode - | FieldDefinitionNode - | InputValueDefinitionNode - | InterfaceTypeDefinitionNode - | UnionTypeDefinitionNode - | EnumTypeDefinitionNode - | EnumValueDefinitionNode - | InputObjectTypeDefinitionNode - | DirectiveDefinitionNode - | SchemaExtensionNode - | ScalarTypeExtensionNode - | ObjectTypeExtensionNode - | InterfaceTypeExtensionNode - | UnionTypeExtensionNode - | EnumTypeExtensionNode - | InputObjectTypeExtensionNode; - -/** - * Utility type listing all nodes indexed by their kind. - */ -export type ASTKindToNode = {| - Name: NameNode, - Document: DocumentNode, - OperationDefinition: OperationDefinitionNode, - VariableDefinition: VariableDefinitionNode, - Variable: VariableNode, - SelectionSet: SelectionSetNode, - Field: FieldNode, - Argument: ArgumentNode, - FragmentSpread: FragmentSpreadNode, - InlineFragment: InlineFragmentNode, - FragmentDefinition: FragmentDefinitionNode, - IntValue: IntValueNode, - FloatValue: FloatValueNode, - StringValue: StringValueNode, - BooleanValue: BooleanValueNode, - NullValue: NullValueNode, - EnumValue: EnumValueNode, - ListValue: ListValueNode, - ObjectValue: ObjectValueNode, - ObjectField: ObjectFieldNode, - Directive: DirectiveNode, - NamedType: NamedTypeNode, - ListType: ListTypeNode, - NonNullType: NonNullTypeNode, - SchemaDefinition: SchemaDefinitionNode, - OperationTypeDefinition: OperationTypeDefinitionNode, - ScalarTypeDefinition: ScalarTypeDefinitionNode, - ObjectTypeDefinition: ObjectTypeDefinitionNode, - FieldDefinition: FieldDefinitionNode, - InputValueDefinition: InputValueDefinitionNode, - InterfaceTypeDefinition: InterfaceTypeDefinitionNode, - UnionTypeDefinition: UnionTypeDefinitionNode, - EnumTypeDefinition: EnumTypeDefinitionNode, - EnumValueDefinition: EnumValueDefinitionNode, - InputObjectTypeDefinition: InputObjectTypeDefinitionNode, - DirectiveDefinition: DirectiveDefinitionNode, - SchemaExtension: SchemaExtensionNode, - ScalarTypeExtension: ScalarTypeExtensionNode, - ObjectTypeExtension: ObjectTypeExtensionNode, - InterfaceTypeExtension: InterfaceTypeExtensionNode, - UnionTypeExtension: UnionTypeExtensionNode, - EnumTypeExtension: EnumTypeExtensionNode, - InputObjectTypeExtension: InputObjectTypeExtensionNode, -|}; - -// Name - -export type NameNode = {| - +kind: 'Name', - +loc?: Location, - +value: string, -|}; - -// Document - -export type DocumentNode = {| - +kind: 'Document', - +loc?: Location, - +definitions: $ReadOnlyArray, -|}; - -export type DefinitionNode = - | ExecutableDefinitionNode - | TypeSystemDefinitionNode - | TypeSystemExtensionNode; - -export type ExecutableDefinitionNode = - | OperationDefinitionNode - | FragmentDefinitionNode; - -export type OperationDefinitionNode = {| - +kind: 'OperationDefinition', - +loc?: Location, - +operation: OperationTypeNode, - +name?: NameNode, - +variableDefinitions?: $ReadOnlyArray, - +directives?: $ReadOnlyArray, - +selectionSet: SelectionSetNode, -|}; - -export type OperationTypeNode = 'query' | 'mutation' | 'subscription'; - -export type VariableDefinitionNode = {| - +kind: 'VariableDefinition', - +loc?: Location, - +variable: VariableNode, - +type: TypeNode, - +defaultValue?: ValueNode, - +directives?: $ReadOnlyArray, -|}; - -export type VariableNode = {| - +kind: 'Variable', - +loc?: Location, - +name: NameNode, -|}; - -export type SelectionSetNode = {| - kind: 'SelectionSet', - loc?: Location, - selections: $ReadOnlyArray, -|}; - -export type SelectionNode = FieldNode | FragmentSpreadNode | InlineFragmentNode; - -export type FieldNode = {| - +kind: 'Field', - +loc?: Location, - +alias?: NameNode, - +name: NameNode, - +arguments?: $ReadOnlyArray, - +directives?: $ReadOnlyArray, - +selectionSet?: SelectionSetNode, -|}; - -export type ArgumentNode = {| - +kind: 'Argument', - +loc?: Location, - +name: NameNode, - +value: ValueNode, -|}; - -// Fragments - -export type FragmentSpreadNode = {| - +kind: 'FragmentSpread', - +loc?: Location, - +name: NameNode, - +directives?: $ReadOnlyArray, -|}; - -export type InlineFragmentNode = {| - +kind: 'InlineFragment', - +loc?: Location, - +typeCondition?: NamedTypeNode, - +directives?: $ReadOnlyArray, - +selectionSet: SelectionSetNode, -|}; - -export type FragmentDefinitionNode = {| - +kind: 'FragmentDefinition', - +loc?: Location, - +name: NameNode, - // Note: fragment variable definitions are experimental and may be changed - // or removed in the future. - +variableDefinitions?: $ReadOnlyArray, - +typeCondition: NamedTypeNode, - +directives?: $ReadOnlyArray, - +selectionSet: SelectionSetNode, -|}; - -// Values - -export type ValueNode = - | VariableNode - | IntValueNode - | FloatValueNode - | StringValueNode - | BooleanValueNode - | NullValueNode - | EnumValueNode - | ListValueNode - | ObjectValueNode; - -export type IntValueNode = {| - +kind: 'IntValue', - +loc?: Location, - +value: string, -|}; - -export type FloatValueNode = {| - +kind: 'FloatValue', - +loc?: Location, - +value: string, -|}; - -export type StringValueNode = {| - +kind: 'StringValue', - +loc?: Location, - +value: string, - +block?: boolean, -|}; - -export type BooleanValueNode = {| - +kind: 'BooleanValue', - +loc?: Location, - +value: boolean, -|}; - -export type NullValueNode = {| - +kind: 'NullValue', - +loc?: Location, -|}; - -export type EnumValueNode = {| - +kind: 'EnumValue', - +loc?: Location, - +value: string, -|}; - -export type ListValueNode = {| - +kind: 'ListValue', - +loc?: Location, - +values: $ReadOnlyArray, -|}; - -export type ObjectValueNode = {| - +kind: 'ObjectValue', - +loc?: Location, - +fields: $ReadOnlyArray, -|}; - -export type ObjectFieldNode = {| - +kind: 'ObjectField', - +loc?: Location, - +name: NameNode, - +value: ValueNode, -|}; - -// Directives - -export type DirectiveNode = {| - +kind: 'Directive', - +loc?: Location, - +name: NameNode, - +arguments?: $ReadOnlyArray, -|}; - -// Type Reference - -export type TypeNode = NamedTypeNode | ListTypeNode | NonNullTypeNode; - -export type NamedTypeNode = {| - +kind: 'NamedType', - +loc?: Location, - +name: NameNode, -|}; - -export type ListTypeNode = {| - +kind: 'ListType', - +loc?: Location, - +type: TypeNode, -|}; - -export type NonNullTypeNode = {| - +kind: 'NonNullType', - +loc?: Location, - +type: NamedTypeNode | ListTypeNode, -|}; - -// Type System Definition - -export type TypeSystemDefinitionNode = - | SchemaDefinitionNode - | TypeDefinitionNode - | DirectiveDefinitionNode; - -export type SchemaDefinitionNode = {| - +kind: 'SchemaDefinition', - +loc?: Location, - +description?: StringValueNode, - +directives?: $ReadOnlyArray, - +operationTypes: $ReadOnlyArray, -|}; - -export type OperationTypeDefinitionNode = {| - +kind: 'OperationTypeDefinition', - +loc?: Location, - +operation: OperationTypeNode, - +type: NamedTypeNode, -|}; - -// Type Definition - -export type TypeDefinitionNode = - | ScalarTypeDefinitionNode - | ObjectTypeDefinitionNode - | InterfaceTypeDefinitionNode - | UnionTypeDefinitionNode - | EnumTypeDefinitionNode - | InputObjectTypeDefinitionNode; - -export type ScalarTypeDefinitionNode = {| - +kind: 'ScalarTypeDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +directives?: $ReadOnlyArray, -|}; - -export type ObjectTypeDefinitionNode = {| - +kind: 'ObjectTypeDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +interfaces?: $ReadOnlyArray, - +directives?: $ReadOnlyArray, - +fields?: $ReadOnlyArray, -|}; - -export type FieldDefinitionNode = {| - +kind: 'FieldDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +arguments?: $ReadOnlyArray, - +type: TypeNode, - +directives?: $ReadOnlyArray, -|}; - -export type InputValueDefinitionNode = {| - +kind: 'InputValueDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +type: TypeNode, - +defaultValue?: ValueNode, - +directives?: $ReadOnlyArray, -|}; - -export type InterfaceTypeDefinitionNode = {| - +kind: 'InterfaceTypeDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +interfaces?: $ReadOnlyArray, - +directives?: $ReadOnlyArray, - +fields?: $ReadOnlyArray, -|}; - -export type UnionTypeDefinitionNode = {| - +kind: 'UnionTypeDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +directives?: $ReadOnlyArray, - +types?: $ReadOnlyArray, -|}; - -export type EnumTypeDefinitionNode = {| - +kind: 'EnumTypeDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +directives?: $ReadOnlyArray, - +values?: $ReadOnlyArray, -|}; - -export type EnumValueDefinitionNode = {| - +kind: 'EnumValueDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +directives?: $ReadOnlyArray, -|}; - -export type InputObjectTypeDefinitionNode = {| - +kind: 'InputObjectTypeDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +directives?: $ReadOnlyArray, - +fields?: $ReadOnlyArray, -|}; - -// Directive Definitions - -export type DirectiveDefinitionNode = {| - +kind: 'DirectiveDefinition', - +loc?: Location, - +description?: StringValueNode, - +name: NameNode, - +arguments?: $ReadOnlyArray, - +repeatable: boolean, - +locations: $ReadOnlyArray, -|}; - -// Type System Extensions - -export type TypeSystemExtensionNode = SchemaExtensionNode | TypeExtensionNode; - -export type SchemaExtensionNode = {| - +kind: 'SchemaExtension', - +loc?: Location, - +directives?: $ReadOnlyArray, - +operationTypes?: $ReadOnlyArray, -|}; - -// Type Extensions - -export type TypeExtensionNode = - | ScalarTypeExtensionNode - | ObjectTypeExtensionNode - | InterfaceTypeExtensionNode - | UnionTypeExtensionNode - | EnumTypeExtensionNode - | InputObjectTypeExtensionNode; - -export type ScalarTypeExtensionNode = {| - +kind: 'ScalarTypeExtension', - +loc?: Location, - +name: NameNode, - +directives?: $ReadOnlyArray, -|}; - -export type ObjectTypeExtensionNode = {| - +kind: 'ObjectTypeExtension', - +loc?: Location, - +name: NameNode, - +interfaces?: $ReadOnlyArray, - +directives?: $ReadOnlyArray, - +fields?: $ReadOnlyArray, -|}; - -export type InterfaceTypeExtensionNode = {| - +kind: 'InterfaceTypeExtension', - +loc?: Location, - +name: NameNode, - +interfaces?: $ReadOnlyArray, - +directives?: $ReadOnlyArray, - +fields?: $ReadOnlyArray, -|}; - -export type UnionTypeExtensionNode = {| - +kind: 'UnionTypeExtension', - +loc?: Location, - +name: NameNode, - +directives?: $ReadOnlyArray, - +types?: $ReadOnlyArray, -|}; - -export type EnumTypeExtensionNode = {| - +kind: 'EnumTypeExtension', - +loc?: Location, - +name: NameNode, - +directives?: $ReadOnlyArray, - +values?: $ReadOnlyArray, -|}; - -export type InputObjectTypeExtensionNode = {| - +kind: 'InputObjectTypeExtension', - +loc?: Location, - +name: NameNode, - +directives?: $ReadOnlyArray, - +fields?: $ReadOnlyArray, -|}; diff --git a/src/language/ast.ts b/src/language/ast.ts new file mode 100644 index 0000000000..72c2a5322b --- /dev/null +++ b/src/language/ast.ts @@ -0,0 +1,640 @@ +import { Source } from './source'; +import { TokenKindEnum } from './tokenKind'; + +/** + * Contains a range of UTF-8 character offsets and token references that + * identify the region of the source from which the AST derived. + */ +export class Location { + /** + * The character offset at which this Node begins. + */ + readonly start: number; + + /** + * The character offset at which this Node ends. + */ + readonly end: number; + + /** + * The Token at which this Node begins. + */ + readonly startToken: Token; + + /** + * The Token at which this Node ends. + */ + readonly endToken: Token; + + /** + * The Source document the AST represents. + */ + readonly source: Source; + + constructor(startToken: Token, endToken: Token, source: Source) { + this.start = startToken.start; + this.end = endToken.end; + this.startToken = startToken; + this.endToken = endToken; + this.source = source; + } + + toJSON(): { start: number; end: number } { + return { start: this.start, end: this.end }; + } + + // @deprecated: Will be removed in v17 + // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet + [Symbol.for('nodejs.util.inspect.custom')](): unknown { + return this.toJSON(); + } +} + +/** + * Represents a range of characters represented by a lexical token + * within a Source. + */ +export class Token { + /** + * The kind of Token. + */ + readonly kind: TokenKindEnum; + + /** + * The character offset at which this Node begins. + */ + readonly start: number; + + /** + * The character offset at which this Node ends. + */ + readonly end: number; + + /** + * The 1-indexed line number on which this Token appears. + */ + readonly line: number; + + /** + * The 1-indexed column number at which this Token begins. + */ + readonly column: number; + + /** + * For non-punctuation tokens, represents the interpreted value of the token. + */ + readonly value: string | void; + + /** + * Tokens exist as nodes in a double-linked-list amongst all tokens + * including ignored tokens. is always the first node and + * the last. + */ + readonly prev: Token | null; + readonly next: Token | null; + + constructor( + kind: TokenKindEnum, + start: number, + end: number, + line: number, + column: number, + prev: Token | null, + value?: string, + ) { + this.kind = kind; + this.start = start; + this.end = end; + this.line = line; + this.column = column; + this.value = value; + this.prev = prev; + this.next = null; + } + + toJSON(): { + kind: TokenKindEnum; + value: string | void; + line: number; + column: number; + } { + return { + kind: this.kind, + value: this.value, + line: this.line, + column: this.column, + }; + } + + // @deprecated: Will be removed in v17 + // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet + [Symbol.for('nodejs.util.inspect.custom')](): unknown { + return this.toJSON(); + } +} + +/** + * @internal + */ +export function isNode(maybeNode: unknown): boolean { + return maybeNode != null && typeof maybeNode.kind === 'string'; +} + +/** + * The list of all possible AST node types. + */ +export type ASTNode = + | NameNode + | DocumentNode + | OperationDefinitionNode + | VariableDefinitionNode + | VariableNode + | SelectionSetNode + | FieldNode + | ArgumentNode + | FragmentSpreadNode + | InlineFragmentNode + | FragmentDefinitionNode + | IntValueNode + | FloatValueNode + | StringValueNode + | BooleanValueNode + | NullValueNode + | EnumValueNode + | ListValueNode + | ObjectValueNode + | ObjectFieldNode + | DirectiveNode + | NamedTypeNode + | ListTypeNode + | NonNullTypeNode + | SchemaDefinitionNode + | OperationTypeDefinitionNode + | ScalarTypeDefinitionNode + | ObjectTypeDefinitionNode + | FieldDefinitionNode + | InputValueDefinitionNode + | InterfaceTypeDefinitionNode + | UnionTypeDefinitionNode + | EnumTypeDefinitionNode + | EnumValueDefinitionNode + | InputObjectTypeDefinitionNode + | DirectiveDefinitionNode + | SchemaExtensionNode + | ScalarTypeExtensionNode + | ObjectTypeExtensionNode + | InterfaceTypeExtensionNode + | UnionTypeExtensionNode + | EnumTypeExtensionNode + | InputObjectTypeExtensionNode; + +/** + * Utility type listing all nodes indexed by their kind. + */ +export type ASTKindToNode = { + Name: NameNode; + Document: DocumentNode; + OperationDefinition: OperationDefinitionNode; + VariableDefinition: VariableDefinitionNode; + Variable: VariableNode; + SelectionSet: SelectionSetNode; + Field: FieldNode; + Argument: ArgumentNode; + FragmentSpread: FragmentSpreadNode; + InlineFragment: InlineFragmentNode; + FragmentDefinition: FragmentDefinitionNode; + IntValue: IntValueNode; + FloatValue: FloatValueNode; + StringValue: StringValueNode; + BooleanValue: BooleanValueNode; + NullValue: NullValueNode; + EnumValue: EnumValueNode; + ListValue: ListValueNode; + ObjectValue: ObjectValueNode; + ObjectField: ObjectFieldNode; + Directive: DirectiveNode; + NamedType: NamedTypeNode; + ListType: ListTypeNode; + NonNullType: NonNullTypeNode; + SchemaDefinition: SchemaDefinitionNode; + OperationTypeDefinition: OperationTypeDefinitionNode; + ScalarTypeDefinition: ScalarTypeDefinitionNode; + ObjectTypeDefinition: ObjectTypeDefinitionNode; + FieldDefinition: FieldDefinitionNode; + InputValueDefinition: InputValueDefinitionNode; + InterfaceTypeDefinition: InterfaceTypeDefinitionNode; + UnionTypeDefinition: UnionTypeDefinitionNode; + EnumTypeDefinition: EnumTypeDefinitionNode; + EnumValueDefinition: EnumValueDefinitionNode; + InputObjectTypeDefinition: InputObjectTypeDefinitionNode; + DirectiveDefinition: DirectiveDefinitionNode; + SchemaExtension: SchemaExtensionNode; + ScalarTypeExtension: ScalarTypeExtensionNode; + ObjectTypeExtension: ObjectTypeExtensionNode; + InterfaceTypeExtension: InterfaceTypeExtensionNode; + UnionTypeExtension: UnionTypeExtensionNode; + EnumTypeExtension: EnumTypeExtensionNode; + InputObjectTypeExtension: InputObjectTypeExtensionNode; +}; + +// Name + +export type NameNode = { + readonly kind: 'Name'; + readonly loc?: Location; + readonly value: string; +}; + +// Document + +export type DocumentNode = { + readonly kind: 'Document'; + readonly loc?: Location; + readonly definitions: ReadonlyArray; +}; + +export type DefinitionNode = + | ExecutableDefinitionNode + | TypeSystemDefinitionNode + | TypeSystemExtensionNode; + +export type ExecutableDefinitionNode = + | OperationDefinitionNode + | FragmentDefinitionNode; + +export type OperationDefinitionNode = { + readonly kind: 'OperationDefinition'; + readonly loc?: Location; + readonly operation: OperationTypeNode; + readonly name?: NameNode; + readonly variableDefinitions?: ReadonlyArray; + readonly directives?: ReadonlyArray; + readonly selectionSet: SelectionSetNode; +}; + +export type OperationTypeNode = 'query' | 'mutation' | 'subscription'; + +export type VariableDefinitionNode = { + readonly kind: 'VariableDefinition'; + readonly loc?: Location; + readonly variable: VariableNode; + readonly type: TypeNode; + readonly defaultValue?: ValueNode; + readonly directives?: ReadonlyArray; +}; + +export type VariableNode = { + readonly kind: 'Variable'; + readonly loc?: Location; + readonly name: NameNode; +}; + +export type SelectionSetNode = { + kind: 'SelectionSet'; + loc?: Location; + selections: ReadonlyArray; +}; + +export type SelectionNode = FieldNode | FragmentSpreadNode | InlineFragmentNode; + +export type FieldNode = { + readonly kind: 'Field'; + readonly loc?: Location; + readonly alias?: NameNode; + readonly name: NameNode; + readonly arguments?: ReadonlyArray; + readonly directives?: ReadonlyArray; + readonly selectionSet?: SelectionSetNode; +}; + +export type ArgumentNode = { + readonly kind: 'Argument'; + readonly loc?: Location; + readonly name: NameNode; + readonly value: ValueNode; +}; + +// Fragments + +export type FragmentSpreadNode = { + readonly kind: 'FragmentSpread'; + readonly loc?: Location; + readonly name: NameNode; + readonly directives?: ReadonlyArray; +}; + +export type InlineFragmentNode = { + readonly kind: 'InlineFragment'; + readonly loc?: Location; + readonly typeCondition?: NamedTypeNode; + readonly directives?: ReadonlyArray; + readonly selectionSet: SelectionSetNode; +}; + +export type FragmentDefinitionNode = { + readonly kind: 'FragmentDefinition'; + readonly loc?: Location; + readonly name: NameNode; + // Note: fragment variable definitions are experimental and may be changed + // or removed in the future. + readonly variableDefinitions?: ReadonlyArray; + readonly typeCondition: NamedTypeNode; + readonly directives?: ReadonlyArray; + readonly selectionSet: SelectionSetNode; +}; + +// Values + +export type ValueNode = + | VariableNode + | IntValueNode + | FloatValueNode + | StringValueNode + | BooleanValueNode + | NullValueNode + | EnumValueNode + | ListValueNode + | ObjectValueNode; + +export type IntValueNode = { + readonly kind: 'IntValue'; + readonly loc?: Location; + readonly value: string; +}; + +export type FloatValueNode = { + readonly kind: 'FloatValue'; + readonly loc?: Location; + readonly value: string; +}; + +export type StringValueNode = { + readonly kind: 'StringValue'; + readonly loc?: Location; + readonly value: string; + readonly block?: boolean; +}; + +export type BooleanValueNode = { + readonly kind: 'BooleanValue'; + readonly loc?: Location; + readonly value: boolean; +}; + +export type NullValueNode = { + readonly kind: 'NullValue'; + readonly loc?: Location; +}; + +export type EnumValueNode = { + readonly kind: 'EnumValue'; + readonly loc?: Location; + readonly value: string; +}; + +export type ListValueNode = { + readonly kind: 'ListValue'; + readonly loc?: Location; + readonly values: ReadonlyArray; +}; + +export type ObjectValueNode = { + readonly kind: 'ObjectValue'; + readonly loc?: Location; + readonly fields: ReadonlyArray; +}; + +export type ObjectFieldNode = { + readonly kind: 'ObjectField'; + readonly loc?: Location; + readonly name: NameNode; + readonly value: ValueNode; +}; + +// Directives + +export type DirectiveNode = { + readonly kind: 'Directive'; + readonly loc?: Location; + readonly name: NameNode; + readonly arguments?: ReadonlyArray; +}; + +// Type Reference + +export type TypeNode = NamedTypeNode | ListTypeNode | NonNullTypeNode; + +export type NamedTypeNode = { + readonly kind: 'NamedType'; + readonly loc?: Location; + readonly name: NameNode; +}; + +export type ListTypeNode = { + readonly kind: 'ListType'; + readonly loc?: Location; + readonly type: TypeNode; +}; + +export type NonNullTypeNode = { + readonly kind: 'NonNullType'; + readonly loc?: Location; + readonly type: NamedTypeNode | ListTypeNode; +}; + +// Type System Definition + +export type TypeSystemDefinitionNode = + | SchemaDefinitionNode + | TypeDefinitionNode + | DirectiveDefinitionNode; + +export type SchemaDefinitionNode = { + readonly kind: 'SchemaDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly directives?: ReadonlyArray; + readonly operationTypes: ReadonlyArray; +}; + +export type OperationTypeDefinitionNode = { + readonly kind: 'OperationTypeDefinition'; + readonly loc?: Location; + readonly operation: OperationTypeNode; + readonly type: NamedTypeNode; +}; + +// Type Definition + +export type TypeDefinitionNode = + | ScalarTypeDefinitionNode + | ObjectTypeDefinitionNode + | InterfaceTypeDefinitionNode + | UnionTypeDefinitionNode + | EnumTypeDefinitionNode + | InputObjectTypeDefinitionNode; + +export type ScalarTypeDefinitionNode = { + readonly kind: 'ScalarTypeDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly directives?: ReadonlyArray; +}; + +export type ObjectTypeDefinitionNode = { + readonly kind: 'ObjectTypeDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly interfaces?: ReadonlyArray; + readonly directives?: ReadonlyArray; + readonly fields?: ReadonlyArray; +}; + +export type FieldDefinitionNode = { + readonly kind: 'FieldDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly arguments?: ReadonlyArray; + readonly type: TypeNode; + readonly directives?: ReadonlyArray; +}; + +export type InputValueDefinitionNode = { + readonly kind: 'InputValueDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly type: TypeNode; + readonly defaultValue?: ValueNode; + readonly directives?: ReadonlyArray; +}; + +export type InterfaceTypeDefinitionNode = { + readonly kind: 'InterfaceTypeDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly interfaces?: ReadonlyArray; + readonly directives?: ReadonlyArray; + readonly fields?: ReadonlyArray; +}; + +export type UnionTypeDefinitionNode = { + readonly kind: 'UnionTypeDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly directives?: ReadonlyArray; + readonly types?: ReadonlyArray; +}; + +export type EnumTypeDefinitionNode = { + readonly kind: 'EnumTypeDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly directives?: ReadonlyArray; + readonly values?: ReadonlyArray; +}; + +export type EnumValueDefinitionNode = { + readonly kind: 'EnumValueDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly directives?: ReadonlyArray; +}; + +export type InputObjectTypeDefinitionNode = { + readonly kind: 'InputObjectTypeDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly directives?: ReadonlyArray; + readonly fields?: ReadonlyArray; +}; + +// Directive Definitions + +export type DirectiveDefinitionNode = { + readonly kind: 'DirectiveDefinition'; + readonly loc?: Location; + readonly description?: StringValueNode; + readonly name: NameNode; + readonly arguments?: ReadonlyArray; + readonly repeatable: boolean; + readonly locations: ReadonlyArray; +}; + +// Type System Extensions + +export type TypeSystemExtensionNode = SchemaExtensionNode | TypeExtensionNode; + +export type SchemaExtensionNode = { + readonly kind: 'SchemaExtension'; + readonly loc?: Location; + readonly directives?: ReadonlyArray; + readonly operationTypes?: ReadonlyArray; +}; + +// Type Extensions + +export type TypeExtensionNode = + | ScalarTypeExtensionNode + | ObjectTypeExtensionNode + | InterfaceTypeExtensionNode + | UnionTypeExtensionNode + | EnumTypeExtensionNode + | InputObjectTypeExtensionNode; + +export type ScalarTypeExtensionNode = { + readonly kind: 'ScalarTypeExtension'; + readonly loc?: Location; + readonly name: NameNode; + readonly directives?: ReadonlyArray; +}; + +export type ObjectTypeExtensionNode = { + readonly kind: 'ObjectTypeExtension'; + readonly loc?: Location; + readonly name: NameNode; + readonly interfaces?: ReadonlyArray; + readonly directives?: ReadonlyArray; + readonly fields?: ReadonlyArray; +}; + +export type InterfaceTypeExtensionNode = { + readonly kind: 'InterfaceTypeExtension'; + readonly loc?: Location; + readonly name: NameNode; + readonly interfaces?: ReadonlyArray; + readonly directives?: ReadonlyArray; + readonly fields?: ReadonlyArray; +}; + +export type UnionTypeExtensionNode = { + readonly kind: 'UnionTypeExtension'; + readonly loc?: Location; + readonly name: NameNode; + readonly directives?: ReadonlyArray; + readonly types?: ReadonlyArray; +}; + +export type EnumTypeExtensionNode = { + readonly kind: 'EnumTypeExtension'; + readonly loc?: Location; + readonly name: NameNode; + readonly directives?: ReadonlyArray; + readonly values?: ReadonlyArray; +}; + +export type InputObjectTypeExtensionNode = { + readonly kind: 'InputObjectTypeExtension'; + readonly loc?: Location; + readonly name: NameNode; + readonly directives?: ReadonlyArray; + readonly fields?: ReadonlyArray; +}; diff --git a/src/language/blockString.js b/src/language/blockString.ts similarity index 94% rename from src/language/blockString.js rename to src/language/blockString.ts index 65b70ba696..fbdb2124a9 100644 --- a/src/language/blockString.js +++ b/src/language/blockString.ts @@ -55,18 +55,22 @@ export function getBlockStringIndentation(value: string): number { for (let i = 0; i < value.length; ++i) { switch (value.charCodeAt(i)) { - case 13: // \r + case 13: + // \r if (value.charCodeAt(i + 1) === 10) { ++i; // skip \r\n as one symbol } + // falls through - case 10: // \n + case 10: + // \n isFirstLine = false; isEmptyLine = true; indent = 0; break; - case 9: // \t - case 32: // + case 9: + case 32: + // ++indent; break; default: @@ -77,6 +81,7 @@ export function getBlockStringIndentation(value: string): number { ) { commonIndent = indent; } + isEmptyLine = false; } } @@ -93,8 +98,8 @@ export function getBlockStringIndentation(value: string): number { */ export function printBlockString( value: string, - indentation?: string = '', - preferMultipleLines?: boolean = false, + indentation: string = '', + preferMultipleLines: boolean = false, ): string { const isSingleLine = value.indexOf('\n') === -1; const hasLeadingSpace = value[0] === ' ' || value[0] === '\t'; diff --git a/src/language/directiveLocation.js b/src/language/directiveLocation.ts similarity index 95% rename from src/language/directiveLocation.js rename to src/language/directiveLocation.ts index 9fa1348cf8..943fffd84d 100644 --- a/src/language/directiveLocation.js +++ b/src/language/directiveLocation.ts @@ -1,3 +1,5 @@ +import { $Values } from 'utility-types'; + /** * The set of allowed directive location values. */ diff --git a/src/language/experimentalOnlineParser/grammar.js b/src/language/experimentalOnlineParser/grammar.ts similarity index 98% rename from src/language/experimentalOnlineParser/grammar.js rename to src/language/experimentalOnlineParser/grammar.ts index 0ab7788534..6d44dc7487 100644 --- a/src/language/experimentalOnlineParser/grammar.js +++ b/src/language/experimentalOnlineParser/grammar.ts @@ -1,6 +1,6 @@ -export type GraphQLGrammarType = {| - [name: string]: GraphQLGrammarRule, -|}; +export type GraphQLGrammarType = { + [name: string]: GraphQLGrammarRule; +}; export type GraphQLGrammarRuleName = string; export type GraphQLGrammarRuleConstraint = | GraphQLGrammarTokenConstraint @@ -8,7 +8,7 @@ export type GraphQLGrammarRuleConstraint = | GraphQLGrammarListOfTypeConstraint | GraphQLGrammarPeekConstraint; export type GraphQLGrammarConstraintsSet = Array< - GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint, + GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint >; export type GraphQLGrammarRule = | GraphQLGrammarRuleName @@ -16,8 +16,8 @@ export type GraphQLGrammarRule = | GraphQLGrammarConstraintsSet; export interface GraphQLGrammarBaseRuleConstraint { butNot?: - | ?GraphQLGrammarTokenConstraint - | ?Array; + | (GraphQLGrammarTokenConstraint | null | undefined) + | (Array | null | undefined); optional?: boolean; eatNextOnFail?: boolean; } @@ -44,8 +44,8 @@ export interface GraphQLGrammarTokenConstraint | 'String' | 'BlockString' | 'Comment'; - ofValue?: ?string; - oneOf?: ?Array; + ofValue?: string | null | undefined; + oneOf?: Array | null | undefined; tokenName?: string; definitionName?: boolean; typeName?: boolean; @@ -69,7 +69,7 @@ export interface GraphQLGrammarPeekConstraintCondition { end?: boolean; } -const grammar: GraphQLGrammarType = ({ +const grammar: GraphQLGrammarType = { Name: { token: 'Name' }, String: { token: 'String' }, BlockString: { token: 'BlockString' }, @@ -994,6 +994,6 @@ const grammar: GraphQLGrammarType = ({ tokenName: 'EnumValue', }, // FIXME: enforce proper typing -}: any); +} as any; export default grammar; diff --git a/src/language/experimentalOnlineParser/index.js b/src/language/experimentalOnlineParser/index.ts similarity index 100% rename from src/language/experimentalOnlineParser/index.js rename to src/language/experimentalOnlineParser/index.ts diff --git a/src/language/experimentalOnlineParser/onlineParser.js b/src/language/experimentalOnlineParser/onlineParser.ts similarity index 94% rename from src/language/experimentalOnlineParser/onlineParser.js rename to src/language/experimentalOnlineParser/onlineParser.ts index f296d1c8e2..0dabca86f4 100644 --- a/src/language/experimentalOnlineParser/onlineParser.js +++ b/src/language/experimentalOnlineParser/onlineParser.ts @@ -2,7 +2,7 @@ import { Lexer } from '../lexer'; import { Source } from '../source'; import GraphQLGrammar from './grammar'; -import type { +import { GraphQLGrammarRule, GraphQLGrammarRuleName, GraphQLGrammarRuleConstraint, @@ -73,35 +73,35 @@ type OnlineParserRule = | PeekOnlineParserRule | ConstraintsSetOnlineParserRule; -export type OnlineParserState = {| - rules: Array, - kind: () => string, - step: () => number, - levels: Array, - indentLevel: number, - name: string | null, - type: string | null, -|}; - -type Token = {| - kind: string, - value: string, - tokenName?: ?string, - ruleName?: ?string, -|}; - -type LexerToken = {| - kind: string, - value: ?string, -|}; - -type OnlineParserConfig = {| - tabSize: number, -|}; - -type OnlineParserConfigOption = {| - tabSize: ?number, -|}; +export type OnlineParserState = { + rules: Array; + kind: () => string; + step: () => number; + levels: Array; + indentLevel: number; + name: string | null; + type: string | null; +}; + +type Token = { + kind: string; + value: string; + tokenName?: string | null | undefined; + ruleName?: string | null | undefined; +}; + +type LexerToken = { + kind: string; + value: string | null | undefined; +}; + +type OnlineParserConfig = { + tabSize: number; +}; + +type OnlineParserConfigOption = { + tabSize: number | null | undefined; +}; export class OnlineParser { state: OnlineParserState; @@ -171,7 +171,7 @@ export class OnlineParser { } parseToken(): Token { - const rule = (this._getNextRule(): any); + const rule = this._getNextRule() as any; if (this.sol()) { this.state.indentLevel = Math.floor( @@ -452,7 +452,7 @@ export class OnlineParser { return this.state.rules[this.state.rules.length - 1] || null; } - _popMatchedRule(token: ?Token) { + _popMatchedRule(token: Token | null | undefined) { const rule = this.state.rules.pop(); if (!rule) { return; @@ -550,7 +550,8 @@ export class OnlineParser { switch (this._getRuleKind(rule)) { case RuleKind.RULE_NAME: - rule = (rule: GraphQLGrammarRuleName); + rule = rule as GraphQLGrammarRuleName; + this._pushRule( GraphQLGrammar[rule], depth, @@ -558,9 +559,10 @@ export class OnlineParser { step, state, ); + break; case RuleKind.CONSTRAINTS_SET: - rule = (rule: GraphQLGrammarConstraintsSet); + rule = rule as GraphQLGrammarConstraintsSet; this.state.rules.push({ name: name || '', depth, @@ -580,7 +582,7 @@ export class OnlineParser { }); break; case RuleKind.OF_TYPE_CONSTRAINT: - rule = (rule: GraphQLGrammarOfTypeConstraint); + rule = rule as GraphQLGrammarOfTypeConstraint; this.state.rules.push({ name: name || '', ofType: rule.ofType, @@ -603,7 +605,7 @@ export class OnlineParser { }); break; case RuleKind.LIST_OF_TYPE_CONSTRAINT: - rule = (rule: GraphQLGrammarListOfTypeConstraint); + rule = rule as GraphQLGrammarListOfTypeConstraint; this.state.rules.push({ listOfType: rule.listOfType, optional: Boolean(rule.optional), @@ -625,7 +627,7 @@ export class OnlineParser { }); break; case RuleKind.TOKEN_CONSTRAINT: - rule = (rule: GraphQLGrammarTokenConstraint); + rule = rule as GraphQLGrammarTokenConstraint; this.state.rules.push({ token: rule.token, ofValue: rule.ofValue, @@ -651,7 +653,7 @@ export class OnlineParser { }); break; case RuleKind.PEEK_CONSTRAINT: - rule = (rule: GraphQLGrammarPeekConstraint); + rule = rule as GraphQLGrammarPeekConstraint; this.state.rules.push({ peek: rule.peek, optional: Boolean(rule.optional), @@ -709,12 +711,12 @@ export class OnlineParser { } _advanceToken(): LexerToken { - return (this._lexer.advance(): any); + return this._lexer.advance() as any; } _lookAhead(): LexerToken { try { - return (this._lexer.lookahead(): any); + return this._lexer.lookahead() as any; } catch (err) { return { kind: TokenKind.INVALID, value: '' }; } diff --git a/src/language/index.js b/src/language/index.ts similarity index 83% rename from src/language/index.js rename to src/language/index.ts index 6055ff4fe3..81dd086b30 100644 --- a/src/language/index.js +++ b/src/language/index.ts @@ -1,31 +1,30 @@ export { Source } from './source'; export { getLocation } from './location'; -export type { SourceLocation } from './location'; +export { SourceLocation } from './location'; export { printLocation, printSourceLocation } from './printLocation'; export { Kind } from './kinds'; -export type { KindEnum } from './kinds'; +export { KindEnum } from './kinds'; export { TokenKind } from './tokenKind'; -export type { TokenKindEnum } from './tokenKind'; +export { TokenKindEnum } from './tokenKind'; export { Lexer } from './lexer'; export { parse, parseValue, parseType } from './parser'; -export type { ParseOptions } from './parser'; +export { ParseOptions } from './parser'; export { print } from './printer'; export { visit, visitInParallel, getVisitFn, BREAK } from './visitor'; -export type { ASTVisitor, Visitor, VisitFn, VisitorKeyMap } from './visitor'; +export { ASTVisitor, Visitor, VisitFn, VisitorKeyMap } from './visitor'; export { Location, Token } from './ast'; -export type { +export { ASTNode, - ASTKindToNode, - // Each kind of AST node + ASTKindToNode, // Each kind of AST node NameNode, DocumentNode, DefinitionNode, @@ -94,4 +93,4 @@ export { } from './predicates'; export { DirectiveLocation } from './directiveLocation'; -export type { DirectiveLocationEnum } from './directiveLocation'; +export { DirectiveLocationEnum } from './directiveLocation'; diff --git a/src/language/kinds.js b/src/language/kinds.ts similarity index 97% rename from src/language/kinds.js rename to src/language/kinds.ts index 99e3e4a9ea..56c9bd9a8a 100644 --- a/src/language/kinds.js +++ b/src/language/kinds.ts @@ -1,3 +1,5 @@ +import { $Values } from 'utility-types'; + /** * The set of allowed kind values for AST nodes. */ diff --git a/src/language/lexer.js b/src/language/lexer.ts similarity index 86% rename from src/language/lexer.js rename to src/language/lexer.ts index ad42ce9897..4178752452 100644 --- a/src/language/lexer.js +++ b/src/language/lexer.ts @@ -1,7 +1,7 @@ import { syntaxError } from '../error/syntaxError'; -import type { Source } from './source'; -import type { TokenKindEnum } from './tokenKind'; +import { Source } from './source'; +import { TokenKindEnum } from './tokenKind'; import { Token } from './ast'; import { TokenKind } from './tokenKind'; import { dedentBlockStringValue } from './blockString'; @@ -65,7 +65,7 @@ export class Lexer { if (token.kind !== TokenKind.EOF) { do { // Note: next is only mutable during parsing, so we cast to allow this. - token = token.next ?? ((token: any).next = readToken(this, token)); + token = token.next ?? ((token as any).next = readToken(this, token)); } while (token.kind === TokenKind.COMMENT); } return token; @@ -75,7 +75,7 @@ export class Lexer { /** * @internal */ -export function isPunctuatorTokenKind(kind: TokenKindEnum): boolean %checks { +export function isPunctuatorTokenKind(kind: TokenKindEnum): boolean { return ( kind === TokenKind.BANG || kind === TokenKind.DOLLAR || @@ -98,12 +98,10 @@ function printCharCode(code: number): string { return ( // NaN/undefined represents access beyond the end of the file. isNaN(code) - ? TokenKind.EOF - : // Trust JSON for ASCII. - code < 0x007f - ? JSON.stringify(String.fromCharCode(code)) - : // Otherwise print the escaped form. - `"\\u${('00' + code.toString(16).toUpperCase()).slice(-4)}"` + ? TokenKind.EOF // Trust JSON for ASCII. + : code < 0x007f + ? JSON.stringify(String.fromCharCode(code)) // Otherwise print the escaped form. + : `"\\u${('00' + code.toString(16).toUpperCase()).slice(-4)}"` ); } @@ -128,135 +126,159 @@ function readToken(lexer: Lexer, prev: Token): Token { // SourceCharacter switch (code) { - case 0xfeff: // - case 9: // \t - case 32: // - case 44: // , + case 0xfeff: + case 9: + case 32: + case 44: + // , ++pos; continue; - case 10: // \n + case 10: + // \n ++pos; ++lexer.line; lexer.lineStart = pos; continue; - case 13: // \r + case 13: + // \r if (body.charCodeAt(pos + 1) === 10) { pos += 2; } else { ++pos; } + ++lexer.line; lexer.lineStart = pos; continue; - case 33: // ! + case 33: + // ! return new Token(TokenKind.BANG, pos, pos + 1, line, col, prev); - case 35: // # + case 35: + // # return readComment(source, pos, line, col, prev); - case 36: // $ + case 36: + // $ return new Token(TokenKind.DOLLAR, pos, pos + 1, line, col, prev); - case 38: // & + case 38: + // & return new Token(TokenKind.AMP, pos, pos + 1, line, col, prev); - case 40: // ( + case 40: + // ( return new Token(TokenKind.PAREN_L, pos, pos + 1, line, col, prev); - case 41: // ) + case 41: + // ) return new Token(TokenKind.PAREN_R, pos, pos + 1, line, col, prev); - case 46: // . + case 46: + // . if ( body.charCodeAt(pos + 1) === 46 && body.charCodeAt(pos + 2) === 46 ) { return new Token(TokenKind.SPREAD, pos, pos + 3, line, col, prev); } + break; - case 58: // : + case 58: + // : return new Token(TokenKind.COLON, pos, pos + 1, line, col, prev); - case 61: // = + case 61: + // = return new Token(TokenKind.EQUALS, pos, pos + 1, line, col, prev); - case 64: // @ + case 64: + // @ return new Token(TokenKind.AT, pos, pos + 1, line, col, prev); - case 91: // [ + case 91: + // [ return new Token(TokenKind.BRACKET_L, pos, pos + 1, line, col, prev); - case 93: // ] + case 93: + // ] return new Token(TokenKind.BRACKET_R, pos, pos + 1, line, col, prev); - case 123: // { + case 123: + // { return new Token(TokenKind.BRACE_L, pos, pos + 1, line, col, prev); - case 124: // | + case 124: + // | return new Token(TokenKind.PIPE, pos, pos + 1, line, col, prev); - case 125: // } + case 125: + // } return new Token(TokenKind.BRACE_R, pos, pos + 1, line, col, prev); - case 34: // " + case 34: + // " if ( body.charCodeAt(pos + 1) === 34 && body.charCodeAt(pos + 2) === 34 ) { return readBlockString(source, pos, line, col, prev, lexer); } + return readString(source, pos, line, col, prev); - case 45: // - - case 48: // 0 - case 49: // 1 - case 50: // 2 - case 51: // 3 - case 52: // 4 - case 53: // 5 - case 54: // 6 - case 55: // 7 - case 56: // 8 - case 57: // 9 + case 45: + case 48: + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + // 9 return readNumber(source, pos, code, line, col, prev); - case 65: // A - case 66: // B - case 67: // C - case 68: // D - case 69: // E - case 70: // F - case 71: // G - case 72: // H - case 73: // I - case 74: // J - case 75: // K - case 76: // L - case 77: // M - case 78: // N - case 79: // O - case 80: // P - case 81: // Q - case 82: // R - case 83: // S - case 84: // T - case 85: // U - case 86: // V - case 87: // W - case 88: // X - case 89: // Y - case 90: // Z - case 95: // _ - case 97: // a - case 98: // b - case 99: // c - case 100: // d - case 101: // e - case 102: // f - case 103: // g - case 104: // h - case 105: // i - case 106: // j - case 107: // k - case 108: // l - case 109: // m - case 110: // n - case 111: // o - case 112: // p - case 113: // q - case 114: // r - case 115: // s - case 116: // t - case 117: // u - case 118: // v - case 119: // w - case 120: // x - case 121: // y - case 122: // z + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 84: + case 85: + case 86: + case 87: + case 88: + case 89: + case 90: + case 95: + case 97: + case 98: + case 99: + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: + case 108: + case 109: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + case 119: + case 120: + case 121: + case 122: + // z return readName(source, pos, line, col, prev); } @@ -303,8 +325,7 @@ function readComment( do { code = body.charCodeAt(++position); } while ( - !isNaN(code) && - // SourceCharacter but not LineTerminator + !isNaN(code) && // SourceCharacter but not LineTerminator (code > 0x001f || code === 0x0009) ); @@ -442,8 +463,7 @@ function readString( while ( position < body.length && - !isNaN((code = body.charCodeAt(position))) && - // not LineTerminator + !isNaN((code = body.charCodeAt(position))) && // not LineTerminator code !== 0x000a && code !== 0x000d ) { diff --git a/src/language/location.js b/src/language/location.ts similarity index 81% rename from src/language/location.js rename to src/language/location.ts index 8da175d4f2..56b3b197c9 100644 --- a/src/language/location.js +++ b/src/language/location.ts @@ -1,12 +1,12 @@ -import type { Source } from './source'; +import { Source } from './source'; /** * Represents a location in a Source. */ -export type SourceLocation = {| - +line: number, - +column: number, -|}; +export type SourceLocation = { + readonly line: number; + readonly column: number; +}; /** * Takes a Source and a UTF-8 character offset, and returns the corresponding diff --git a/src/language/parser.js b/src/language/parser.ts similarity index 98% rename from src/language/parser.js rename to src/language/parser.ts index 2f1ff29828..d30d7a327e 100644 --- a/src/language/parser.js +++ b/src/language/parser.ts @@ -1,8 +1,8 @@ -import type { GraphQLError } from '../error/GraphQLError'; +import { GraphQLError } from '../error/GraphQLError'; import { syntaxError } from '../error/syntaxError'; -import type { TokenKindEnum } from './tokenKind'; -import type { +import { TokenKindEnum } from './tokenKind'; +import { Token, NameNode, VariableNode, @@ -58,13 +58,13 @@ import { Lexer, isPunctuatorTokenKind } from './lexer'; /** * Configuration options to control parser behavior */ -export type ParseOptions = {| +export type ParseOptions = { /** * By default, the parser creates AST nodes that know the location * in the source that they correspond to. This configuration flag * disables that behavior for performance or testing. */ - noLocation?: boolean, + noLocation?: boolean; /** * EXPERIMENTAL: @@ -82,8 +82,8 @@ export type ParseOptions = {| * Note: this feature is experimental and may change or be removed in the * future. */ - experimentalFragmentVariables?: boolean, -|}; + experimentalFragmentVariables?: boolean; +}; /** * Given a GraphQL source, parses it into a Document. @@ -151,7 +151,7 @@ export function parseType( * @internal */ export class Parser { - _options: ?ParseOptions; + _options: ParseOptions | null | undefined; _lexer: Lexer; constructor(source: string | Source, options?: ParseOptions) { @@ -168,7 +168,7 @@ export class Parser { const token = this.expectToken(TokenKind.NAME); return { kind: Kind.NAME, - value: ((token.value: any): string), + value: (token.value as any) as string, loc: this.loc(token), }; } @@ -521,16 +521,18 @@ export class Parser { return this.parseObject(isConst); case TokenKind.INT: this._lexer.advance(); + return { kind: Kind.INT, - value: ((token.value: any): string), + value: (token.value as any) as string, loc: this.loc(token), }; case TokenKind.FLOAT: this._lexer.advance(); + return { kind: Kind.FLOAT, - value: ((token.value: any): string), + value: (token.value as any) as string, loc: this.loc(token), }; case TokenKind.STRING: @@ -538,6 +540,7 @@ export class Parser { return this.parseStringLiteral(); case TokenKind.NAME: this._lexer.advance(); + switch (token.value) { case 'true': return { kind: Kind.BOOLEAN, value: true, loc: this.loc(token) }; @@ -548,14 +551,16 @@ export class Parser { default: return { kind: Kind.ENUM, - value: ((token.value: any): string), + value: (token.value as any) as string, loc: this.loc(token), }; } + case TokenKind.DOLLAR: if (!isConst) { return this.parseVariable(); } + break; } throw this.unexpected(); @@ -566,7 +571,7 @@ export class Parser { this._lexer.advance(); return { kind: Kind.STRING, - value: ((token.value: any): string), + value: (token.value as any) as string, block: token.kind === TokenKind.BLOCK_STRING, loc: this.loc(token), }; @@ -1382,7 +1387,7 @@ export class Parser { * If the next token is of the given kind, return that token after advancing the lexer. * Otherwise, do not change the parser state and return undefined. */ - expectOptionalToken(kind: TokenKindEnum): ?Token { + expectOptionalToken(kind: TokenKindEnum): Token | null | undefined { const token = this._lexer.token; if (token.kind === kind) { this._lexer.advance(); @@ -1424,7 +1429,7 @@ export class Parser { /** * Helper function for creating an error when an unexpected lexed token is encountered. */ - unexpected(atToken?: ?Token): GraphQLError { + unexpected(atToken?: Token | null | undefined): GraphQLError { const token = atToken ?? this._lexer.token; return syntaxError( this._lexer.source, diff --git a/src/language/predicates.js b/src/language/predicates.ts similarity index 79% rename from src/language/predicates.js rename to src/language/predicates.ts index b9108f87ad..bf7736ec49 100644 --- a/src/language/predicates.js +++ b/src/language/predicates.ts @@ -1,7 +1,7 @@ -import type { ASTNode } from './ast'; +import { ASTNode } from './ast'; import { Kind } from './kinds'; -export function isDefinitionNode(node: ASTNode): boolean %checks { +export function isDefinitionNode(node: ASTNode): boolean { return ( isExecutableDefinitionNode(node) || isTypeSystemDefinitionNode(node) || @@ -9,14 +9,14 @@ export function isDefinitionNode(node: ASTNode): boolean %checks { ); } -export function isExecutableDefinitionNode(node: ASTNode): boolean %checks { +export function isExecutableDefinitionNode(node: ASTNode): boolean { return ( node.kind === Kind.OPERATION_DEFINITION || node.kind === Kind.FRAGMENT_DEFINITION ); } -export function isSelectionNode(node: ASTNode): boolean %checks { +export function isSelectionNode(node: ASTNode): boolean { return ( node.kind === Kind.FIELD || node.kind === Kind.FRAGMENT_SPREAD || @@ -24,7 +24,7 @@ export function isSelectionNode(node: ASTNode): boolean %checks { ); } -export function isValueNode(node: ASTNode): boolean %checks { +export function isValueNode(node: ASTNode): boolean { return ( node.kind === Kind.VARIABLE || node.kind === Kind.INT || @@ -38,7 +38,7 @@ export function isValueNode(node: ASTNode): boolean %checks { ); } -export function isTypeNode(node: ASTNode): boolean %checks { +export function isTypeNode(node: ASTNode): boolean { return ( node.kind === Kind.NAMED_TYPE || node.kind === Kind.LIST_TYPE || @@ -46,7 +46,7 @@ export function isTypeNode(node: ASTNode): boolean %checks { ); } -export function isTypeSystemDefinitionNode(node: ASTNode): boolean %checks { +export function isTypeSystemDefinitionNode(node: ASTNode): boolean { return ( node.kind === Kind.SCHEMA_DEFINITION || isTypeDefinitionNode(node) || @@ -54,7 +54,7 @@ export function isTypeSystemDefinitionNode(node: ASTNode): boolean %checks { ); } -export function isTypeDefinitionNode(node: ASTNode): boolean %checks { +export function isTypeDefinitionNode(node: ASTNode): boolean { return ( node.kind === Kind.SCALAR_TYPE_DEFINITION || node.kind === Kind.OBJECT_TYPE_DEFINITION || @@ -65,11 +65,11 @@ export function isTypeDefinitionNode(node: ASTNode): boolean %checks { ); } -export function isTypeSystemExtensionNode(node: ASTNode): boolean %checks { +export function isTypeSystemExtensionNode(node: ASTNode): boolean { return node.kind === Kind.SCHEMA_EXTENSION || isTypeExtensionNode(node); } -export function isTypeExtensionNode(node: ASTNode): boolean %checks { +export function isTypeExtensionNode(node: ASTNode): boolean { return ( node.kind === Kind.SCALAR_TYPE_EXTENSION || node.kind === Kind.OBJECT_TYPE_EXTENSION || diff --git a/src/language/printLocation.js b/src/language/printLocation.ts similarity index 92% rename from src/language/printLocation.js rename to src/language/printLocation.ts index fbf3504634..135e779eef 100644 --- a/src/language/printLocation.js +++ b/src/language/printLocation.ts @@ -1,6 +1,6 @@ -import type { Source } from './source'; -import type { Location } from './ast'; -import type { SourceLocation } from './location'; +import { Source } from './source'; +import { Location } from './ast'; +import { SourceLocation } from './location'; import { getLocation } from './location'; /** @@ -66,7 +66,7 @@ export function printSourceLocation( ); } -function printPrefixedLines(lines: $ReadOnlyArray<[string, string]>): string { +function printPrefixedLines(lines: ReadonlyArray<[string, string]>): string { const existingLines = lines.filter(([_, line]) => line !== undefined); const padLen = Math.max(...existingLines.map(([prefix]) => prefix.length)); diff --git a/src/language/printer.js b/src/language/printer.ts similarity index 93% rename from src/language/printer.js rename to src/language/printer.ts index 8ca8fb2dad..c524281fec 100644 --- a/src/language/printer.js +++ b/src/language/printer.ts @@ -1,4 +1,4 @@ -import type { ASTNode } from './ast'; +import { ASTNode } from './ast'; import { visit } from './visitor'; import { printBlockString } from './blockString'; @@ -67,14 +67,9 @@ const printDocASTReducer: any = { ' ', ), - FragmentDefinition: ({ - name, - typeCondition, - variableDefinitions, - directives, - selectionSet, - }) => - // Note: fragment variable definitions are experimental and may be changed + FragmentDefinition: ( + { name, typeCondition, variableDefinitions, directives, selectionSet }, // Note: fragment variable definitions are experimental and may be changed + ) => // or removed in the future. `fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` + `on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` + @@ -257,7 +252,10 @@ function addDescription(cb) { * Given maybeArray, print an empty string if it is null or empty, otherwise * print all items together separated by separator if provided */ -function join(maybeArray: ?Array, separator = ''): string { +function join( + maybeArray: Array | null | undefined, + separator = '', +): string { return maybeArray?.filter((x) => x).join(separator) ?? ''; } @@ -265,14 +263,18 @@ function join(maybeArray: ?Array, separator = ''): string { * Given array, print each item on its own line, wrapped in an * indented "{ }" block. */ -function block(array: ?Array): string { +function block(array: Array | null | undefined): string { return wrap('{\n', indent(join(array, '\n')), '\n}'); } /** * If maybeString is not null or empty, then wrap with start and end, otherwise print an empty string. */ -function wrap(start: string, maybeString: ?string, end: string = ''): string { +function wrap( + start: string, + maybeString: string | null | undefined, + end: string = '', +): string { return maybeString != null && maybeString !== '' ? start + maybeString + end : ''; @@ -286,6 +288,8 @@ function isMultiline(str: string): boolean { return str.indexOf('\n') !== -1; } -function hasMultilineItems(maybeArray: ?Array): boolean { +function hasMultilineItems( + maybeArray: Array | null | undefined, +): boolean { return maybeArray != null && maybeArray.some(isMultiline); } diff --git a/src/language/source.js b/src/language/source.ts similarity index 91% rename from src/language/source.js rename to src/language/source.ts index 01f45fba44..e737bf7ec8 100644 --- a/src/language/source.js +++ b/src/language/source.ts @@ -2,10 +2,10 @@ import inspect from '../jsutils/inspect'; import devAssert from '../jsutils/devAssert'; import instanceOf from '../jsutils/instanceOf'; -type Location = {| - line: number, - column: number, -|}; +type Location = { + line: number; + column: number; +}; /** * A representation of source input to GraphQL. The `name` and `locationOffset` parameters are @@ -23,7 +23,7 @@ export class Source { body: string, name: string = 'GraphQL request', locationOffset: Location = { line: 1, column: 1 }, - ): void { + ) { devAssert( typeof body === 'string', `Body must be a string. Received: ${inspect(body)}.`, @@ -53,8 +53,7 @@ export class Source { * * @internal */ -declare function isSource(source: mixed): boolean %checks(source instanceof - Source); +declare function isSource(source: unknown): boolean; // eslint-disable-next-line no-redeclare export function isSource(source) { return instanceOf(source, Source); diff --git a/src/language/tokenKind.js b/src/language/tokenKind.ts similarity index 93% rename from src/language/tokenKind.js rename to src/language/tokenKind.ts index b4f5248c13..c8015737b6 100644 --- a/src/language/tokenKind.js +++ b/src/language/tokenKind.ts @@ -1,3 +1,5 @@ +import { $Values } from 'utility-types'; + /** * An exported enum describing the different kinds of tokens that the * lexer emits. diff --git a/src/language/visitor.js b/src/language/visitor.ts similarity index 89% rename from src/language/visitor.js rename to src/language/visitor.ts index 5e367ce4a9..69b80a29b0 100644 --- a/src/language/visitor.js +++ b/src/language/visitor.ts @@ -1,6 +1,7 @@ +import { $Values, $Shape, $Keys } from 'utility-types'; import inspect from '../jsutils/inspect'; -import type { ASTNode, ASTKindToNode } from './ast'; +import { ASTNode, ASTKindToNode } from './ast'; import { isNode } from './ast'; /** @@ -11,32 +12,30 @@ export type ASTVisitor = Visitor; export type Visitor> = | EnterLeave< | VisitFn - | ShapeMap(Node) => VisitFn>, + | ShapeMap(arg0: Node) => VisitFn> > | ShapeMap< KindToNode, - (Node) => VisitFn | EnterLeave>, + ( + arg0: Node, + ) => VisitFn | EnterLeave> >; -type EnterLeave = {| +enter?: T, +leave?: T |}; +type EnterLeave = { readonly enter?: T; readonly leave?: T }; type ShapeMap = $Shape<$ObjMap>; /** * A visitor is comprised of visit functions, which are called on each node * during the visitor's traversal. */ -export type VisitFn = ( +export type VisitFn = ( // The current node being visiting. - node: TVisitedNode, - // The index or key to this node from the parent node or Array. - key: string | number | void, - // The parent immediately above this node, which may be an Array. - parent: TAnyNode | $ReadOnlyArray | void, - // The key path to get to this node from the root node. - path: $ReadOnlyArray, - // All nodes and Arrays visited before reaching parent of this node. + node: TVisitedNode, // The index or key to this node from the parent node or Array. + key: string | number | void, // The parent immediately above this node, which may be an Array. + parent: TAnyNode | ReadonlyArray | void, // The key path to get to this node from the root node. + path: ReadonlyArray, // All nodes and Arrays visited before reaching parent of this node. // These correspond to array indices in `path`. // Note: ancestors includes arrays which contain the parent of visited node. - ancestors: $ReadOnlyArray>, + ancestors: ReadonlyArray>, ) => any; /** @@ -44,7 +43,7 @@ export type VisitFn = ( */ export type VisitorKeyMap = $ObjMap< KindToNode, - (T) => $ReadOnlyArray<$Keys>, + (arg0: T) => ReadonlyArray<$Keys> >; export const QueryDocumentKeys: VisitorKeyMap = { @@ -66,8 +65,7 @@ export const QueryDocumentKeys: VisitorKeyMap = { FragmentSpread: ['name', 'directives'], InlineFragment: ['typeCondition', 'directives', 'selectionSet'], FragmentDefinition: [ - 'name', - // Note: fragment variable definitions are experimental and may be changed + 'name', // Note: fragment variable definitions are experimental and may be changed // or removed in the future. 'variableDefinitions', 'typeCondition', @@ -134,7 +132,7 @@ export const QueryDocumentKeys: VisitorKeyMap = { InputObjectTypeExtension: ['name', 'directives', 'fields'], }; -export const BREAK: { ... } = Object.freeze({}); +export const BREAK: {} = Object.freeze({}); /** * visit() will walk through an AST using a depth-first traversal, calling @@ -239,6 +237,7 @@ export function visit( const path: any = []; const ancestors = []; let newRoot = root; + /* eslint-enable no-undef-init */ do { @@ -355,7 +354,7 @@ export function visit( * If a prior visitor edits a node, no following visitors will see that node. */ export function visitInParallel( - visitors: $ReadOnlyArray>, + visitors: ReadonlyArray>, ): Visitor { const skipping = new Array(visitors.length); @@ -363,7 +362,12 @@ export function visitInParallel( enter(node) { for (let i = 0; i < visitors.length; i++) { if (skipping[i] == null) { - const fn = getVisitFn(visitors[i], node.kind, /* isLeaving */ false); + const fn = getVisitFn( + visitors[i], + node.kind, + /* isLeaving */ + false, + ); if (fn) { const result = fn.apply(visitors[i], arguments); if (result === false) { @@ -380,7 +384,12 @@ export function visitInParallel( leave(node) { for (let i = 0; i < visitors.length; i++) { if (skipping[i] == null) { - const fn = getVisitFn(visitors[i], node.kind, /* isLeaving */ true); + const fn = getVisitFn( + visitors[i], + node.kind, + /* isLeaving */ + true, + ); if (fn) { const result = fn.apply(visitors[i], arguments); if (result === BREAK) { @@ -405,7 +414,7 @@ export function getVisitFn( visitor: Visitor, kind: string, isLeaving: boolean, -): ?VisitFn { +): VisitFn | null | undefined { const kindVisitor = visitor[kind]; if (kindVisitor) { if (!isLeaving && typeof kindVisitor === 'function') { diff --git a/src/polyfills/objectEntries.js b/src/polyfills/objectEntries.ts similarity index 62% rename from src/polyfills/objectEntries.js rename to src/polyfills/objectEntries.ts index 30e5585272..6c41ad18be 100644 --- a/src/polyfills/objectEntries.js +++ b/src/polyfills/objectEntries.ts @@ -1,9 +1,9 @@ -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; declare function objectEntries(obj: ObjMap): Array<[string, T]>; /* eslint-disable no-redeclare */ -// $FlowFixMe[name-already-bound] workaround for: https://github.com/facebook/flow/issues/4441 + const objectEntries = Object.entries || ((obj) => Object.keys(obj).map((key) => [key, obj[key]])); diff --git a/src/polyfills/objectValues.js b/src/polyfills/objectValues.ts similarity index 60% rename from src/polyfills/objectValues.js rename to src/polyfills/objectValues.ts index 943362a640..cafb7c8575 100644 --- a/src/polyfills/objectValues.js +++ b/src/polyfills/objectValues.ts @@ -1,9 +1,9 @@ -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; declare function objectValues(obj: ObjMap): Array; /* eslint-disable no-redeclare */ -// $FlowFixMe[name-already-bound] workaround for: https://github.com/facebook/flow/issues/4441 + const objectValues = Object.values || ((obj) => Object.keys(obj).map((key) => obj[key])); export default objectValues; diff --git a/src/subscription/__tests__/mapAsyncIterator-test.js b/src/subscription/__tests__/mapAsyncIterator-test.ts similarity index 98% rename from src/subscription/__tests__/mapAsyncIterator-test.js rename to src/subscription/__tests__/mapAsyncIterator-test.ts index 4af866f20a..c47555397c 100644 --- a/src/subscription/__tests__/mapAsyncIterator-test.js +++ b/src/subscription/__tests__/mapAsyncIterator-test.ts @@ -298,7 +298,7 @@ describe('mapAsyncIterator', () => { }); }); - async function testClosesSourceWithMapper(mapper: (number) => T) { + async function testClosesSourceWithMapper(mapper: (arg0: number) => T) { let didVisitFinally = false; async function* source() { @@ -354,7 +354,9 @@ describe('mapAsyncIterator', () => { ); }); - async function testClosesSourceWithRejectMapper(mapper: (Error) => T) { + async function testClosesSourceWithRejectMapper( + mapper: (arg0: Error) => T, + ) { async function* source() { yield 1; throw new Error(2); diff --git a/src/subscription/__tests__/simplePubSub-test.js b/src/subscription/__tests__/simplePubSub-test.ts similarity index 100% rename from src/subscription/__tests__/simplePubSub-test.js rename to src/subscription/__tests__/simplePubSub-test.ts diff --git a/src/subscription/__tests__/simplePubSub.js b/src/subscription/__tests__/simplePubSub.ts similarity index 90% rename from src/subscription/__tests__/simplePubSub.js rename to src/subscription/__tests__/simplePubSub.ts index e12c93d0b9..a02a9def01 100644 --- a/src/subscription/__tests__/simplePubSub.js +++ b/src/subscription/__tests__/simplePubSub.ts @@ -3,7 +3,7 @@ * PubSub system for tests. */ export default class SimplePubSub { - _subscribers: Set<(T) => void>; + _subscribers: Set<(arg0: T) => void>; constructor() { this._subscribers = new Set(); @@ -16,7 +16,7 @@ export default class SimplePubSub { return this._subscribers.size > 0; } - getSubscriber(transform?: (T) => R): AsyncGenerator { + getSubscriber(transform?: (arg0: T) => R): AsyncGenerator { const pullQueue = []; const pushQueue = []; let listening = true; @@ -34,7 +34,7 @@ export default class SimplePubSub { /* TODO: Flow doesn't support symbols as keys: https://github.com/facebook/flow/issues/3258 */ - return ({ + return { next() { if (!listening) { return Promise.resolve({ value: undefined, done: true }); @@ -49,14 +49,14 @@ export default class SimplePubSub { emptyQueue(); return Promise.resolve({ value: undefined, done: true }); }, - throw(error: mixed) { + throw(error: unknown) { emptyQueue(); return Promise.reject(error); }, [Symbol.asyncIterator]() { return this; }, - }: any); + } as any; function pushValue(event: T): void { const value = transform != null ? transform(event) : event; diff --git a/src/subscription/__tests__/subscribe-test.js b/src/subscription/__tests__/subscribe-test.ts similarity index 98% rename from src/subscription/__tests__/subscribe-test.js rename to src/subscription/__tests__/subscribe-test.ts index c0cc0ce851..f7e09679cd 100644 --- a/src/subscription/__tests__/subscribe-test.js +++ b/src/subscription/__tests__/subscribe-test.ts @@ -6,7 +6,7 @@ import resolveOnNextTick from '../../__testUtils__/resolveOnNextTick'; import invariant from '../../jsutils/invariant'; import isAsyncIterable from '../../jsutils/isAsyncIterable'; -import type { DocumentNode } from '../../language/ast'; +import { DocumentNode } from '../../language/ast'; import { parse } from '../../language/parser'; import { GraphQLError } from '../../error/GraphQLError'; @@ -19,12 +19,12 @@ import { createSourceEventStream, subscribe } from '../subscribe'; import SimplePubSub from './simplePubSub'; -type Email = {| - from: string, - subject: string, - message: string, - unread: boolean, -|}; +type Email = { + from: string; + subject: string; + message: string; + unread: boolean; +}; const EmailType = new GraphQLObjectType({ name: 'Email', @@ -68,9 +68,9 @@ const EmailEventType = new GraphQLObjectType({ const emailSchema = emailSchemaWithResolvers(); -function emailSchemaWithResolvers( - subscribeFn?: (T) => mixed, - resolveFn?: (T) => mixed, +function emailSchemaWithResolvers( + subscribeFn?: (arg0: T) => unknown, + resolveFn?: (arg0: T) => unknown, ) { return new GraphQLSchema({ query: QueryType, @@ -137,7 +137,7 @@ function createSubscription( } async function expectPromiseToThrow( - promise: () => Promise, + promise: () => Promise, message: string, ) { try { diff --git a/src/subscription/index.js b/src/subscription/index.ts similarity index 55% rename from src/subscription/index.js rename to src/subscription/index.ts index 899e443b6b..971b34dbbb 100644 --- a/src/subscription/index.js +++ b/src/subscription/index.ts @@ -1,2 +1,2 @@ export { subscribe, createSourceEventStream } from './subscribe'; -export type { SubscriptionArgs } from './subscribe'; +export { SubscriptionArgs } from './subscribe'; diff --git a/src/subscription/mapAsyncIterator.js b/src/subscription/mapAsyncIterator.ts similarity index 83% rename from src/subscription/mapAsyncIterator.js rename to src/subscription/mapAsyncIterator.ts index 5a64de54f1..247c63f1cc 100644 --- a/src/subscription/mapAsyncIterator.js +++ b/src/subscription/mapAsyncIterator.ts @@ -1,4 +1,4 @@ -import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; +import { PromiseOrValue } from '../jsutils/PromiseOrValue'; /** * Given an AsyncIterable and a callback function, return an AsyncIterator @@ -6,8 +6,8 @@ import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; */ export default function mapAsyncIterator( iterable: AsyncIterable | AsyncGenerator, - callback: (T) => PromiseOrValue, - rejectCallback?: (any) => PromiseOrValue, + callback: (arg0: T) => PromiseOrValue, + rejectCallback?: (arg0: any) => PromiseOrValue, ): AsyncGenerator { // $FlowFixMe[prop-missing] const iteratorMethod = iterable[Symbol.asyncIterator]; @@ -16,7 +16,7 @@ export default function mapAsyncIterator( let abruptClose; if (typeof iterator.return === 'function') { $return = iterator.return; - abruptClose = (error: mixed) => { + abruptClose = (error: unknown) => { const rethrow = () => Promise.reject(error); return $return.call(iterator).then(rethrow, rethrow); }; @@ -32,13 +32,13 @@ export default function mapAsyncIterator( if (rejectCallback) { // Capture rejectCallback to ensure it cannot be null. const reject = rejectCallback; - mapReject = (error: mixed) => + mapReject = (error: unknown) => asyncMapValue(error, reject).then(iteratorResult, abruptClose); } /* TODO: Flow doesn't support symbols as keys: https://github.com/facebook/flow/issues/3258 */ - return ({ + return { next(): Promise> { return iterator.next().then(mapResult, mapReject); }, @@ -47,7 +47,7 @@ export default function mapAsyncIterator( ? $return.call(iterator).then(mapResult, mapReject) : Promise.resolve({ value: undefined, done: true }); }, - throw(error?: mixed): Promise> { + throw(error?: unknown): Promise> { if (typeof iterator.throw === 'function') { return iterator.throw(error).then(mapResult, mapReject); } @@ -56,12 +56,12 @@ export default function mapAsyncIterator( [Symbol.asyncIterator]() { return this; }, - }: $FlowFixMe); + } as $FlowFixMe; } function asyncMapValue( value: T, - callback: (T) => PromiseOrValue, + callback: (arg0: T) => PromiseOrValue, ): Promise { return new Promise((resolve) => resolve(callback(value))); } diff --git a/src/subscription/subscribe.js b/src/subscription/subscribe.ts similarity index 86% rename from src/subscription/subscribe.js rename to src/subscription/subscribe.ts index 4ff1b9d72a..3ba09d91dc 100644 --- a/src/subscription/subscribe.js +++ b/src/subscription/subscribe.ts @@ -5,9 +5,9 @@ import { addPath, pathToArray } from '../jsutils/Path'; import { GraphQLError } from '../error/GraphQLError'; import { locatedError } from '../error/locatedError'; -import type { DocumentNode } from '../language/ast'; +import { DocumentNode } from '../language/ast'; -import type { ExecutionResult, ExecutionContext } from '../execution/execute'; +import { ExecutionResult, ExecutionContext } from '../execution/execute'; import { getArgumentValues } from '../execution/values'; import { assertValidExecutionArguments, @@ -18,23 +18,28 @@ import { getFieldDef, } from '../execution/execute'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLFieldResolver } from '../type/definition'; +import { GraphQLSchema } from '../type/schema'; +import { GraphQLFieldResolver } from '../type/definition'; import { getOperationRootType } from '../utilities/getOperationRootType'; import mapAsyncIterator from './mapAsyncIterator'; -export type SubscriptionArgs = {| - schema: GraphQLSchema, - document: DocumentNode, - rootValue?: mixed, - contextValue?: mixed, - variableValues?: ?{ +[variable: string]: mixed, ... }, - operationName?: ?string, - fieldResolver?: ?GraphQLFieldResolver, - subscribeFieldResolver?: ?GraphQLFieldResolver, -|}; +export type SubscriptionArgs = { + schema: GraphQLSchema; + document: DocumentNode; + rootValue?: unknown; + contextValue?: unknown; + variableValues?: + | { + readonly [variable: string]: unknown; + } + | null + | undefined; + operationName?: string | null | undefined; + fieldResolver?: GraphQLFieldResolver | null | undefined; + subscribeFieldResolver?: GraphQLFieldResolver | null | undefined; +}; /** * Implements the "Subscribe" algorithm described in the GraphQL specification. @@ -100,15 +105,16 @@ export function subscribe( // Resolve the Source Stream, then map every source value to a // ExecutionResult value as described above. - return sourcePromise.then((resultOrStream) => - // Note: Flow can't refine isAsyncIterable, so explicit casts are used. + return sourcePromise.then(( + resultOrStream, // Note: Flow can't refine isAsyncIterable, so explicit casts are used. + ) => isAsyncIterable(resultOrStream) ? mapAsyncIterator( resultOrStream, mapSourceToResponse, reportGraphQLError, ) - : ((resultOrStream: any): ExecutionResult), + : ((resultOrStream as any) as ExecutionResult), ); } @@ -117,7 +123,7 @@ export function subscribe( * an ExecutionResult, containing only errors and no data. Otherwise treat the * error as a system-class error and re-throw it. */ -function reportGraphQLError(error: mixed): ExecutionResult { +function reportGraphQLError(error: unknown): ExecutionResult { if (error instanceof GraphQLError) { return { errors: [error] }; } @@ -155,12 +161,17 @@ function reportGraphQLError(error: mixed): ExecutionResult { export function createSourceEventStream( schema: GraphQLSchema, document: DocumentNode, - rootValue?: mixed, - contextValue?: mixed, - variableValues?: ?{ +[variable: string]: mixed, ... }, - operationName?: ?string, - fieldResolver?: ?GraphQLFieldResolver, -): Promise | ExecutionResult> { + rootValue?: unknown, + contextValue?: unknown, + variableValues?: + | { + readonly [variable: string]: unknown; + } + | null + | undefined, + operationName?: string | null | undefined, + fieldResolver?: GraphQLFieldResolver | null | undefined, +): Promise | ExecutionResult> { // If arguments are missing or incorrectly typed, this is an internal // developer mistake which should throw an early error. assertValidExecutionArguments(schema, document, variableValues); @@ -189,7 +200,7 @@ export function createSourceEventStream( function executeSubscription( exeContext: ExecutionContext, -): Promise> { +): Promise> { const { schema, operation, variableValues, rootValue } = exeContext; const type = getOperationRootType(schema, operation); const fields = collectFields( diff --git a/src/type/__tests__/definition-test.js b/src/type/__tests__/definition-test.ts similarity index 99% rename from src/type/__tests__/definition-test.js rename to src/type/__tests__/definition-test.ts index 65b176d150..4b4bba7874 100644 --- a/src/type/__tests__/definition-test.js +++ b/src/type/__tests__/definition-test.ts @@ -6,7 +6,7 @@ import identityFunc from '../../jsutils/identityFunc'; import { parseValue } from '../../language/parser'; -import type { GraphQLType, GraphQLNullableType } from '../definition'; +import { GraphQLType, GraphQLNullableType } from '../definition'; import { GraphQLList, GraphQLNonNull, @@ -922,7 +922,7 @@ describe('Type System: test utility methods', () => { }); it('Object.toStringifies types', () => { - function toString(obj: mixed): string { + function toString(obj: unknown): string { return Object.prototype.toString.call(obj); } diff --git a/src/type/__tests__/directive-test.js b/src/type/__tests__/directive-test.ts similarity index 100% rename from src/type/__tests__/directive-test.js rename to src/type/__tests__/directive-test.ts diff --git a/src/type/__tests__/enumType-test.js b/src/type/__tests__/enumType-test.ts similarity index 99% rename from src/type/__tests__/enumType-test.js rename to src/type/__tests__/enumType-test.ts index 0145657733..f083b84592 100644 --- a/src/type/__tests__/enumType-test.js +++ b/src/type/__tests__/enumType-test.ts @@ -114,7 +114,9 @@ const schema = new GraphQLSchema({ function executeQuery( source: string, - variableValues?: { +[variable: string]: mixed, ... }, + variableValues?: { + readonly [variable: string]: unknown; + }, ) { return graphqlSync({ schema, source, variableValues }); } diff --git a/src/type/__tests__/extensions-test.js b/src/type/__tests__/extensions-test.ts similarity index 99% rename from src/type/__tests__/extensions-test.js rename to src/type/__tests__/extensions-test.ts index 76dd0ee233..792e962b7d 100644 --- a/src/type/__tests__/extensions-test.js +++ b/src/type/__tests__/extensions-test.ts @@ -16,7 +16,7 @@ import { const dummyType = new GraphQLScalarType({ name: 'DummyScalar' }); -function expectObjMap(value: mixed) { +function expectObjMap(value: unknown) { invariant(value != null && typeof value === 'object'); expect(Object.getPrototypeOf(value)).to.equal(null); return expect(value); diff --git a/src/type/__tests__/introspection-test.js b/src/type/__tests__/introspection-test.ts similarity index 100% rename from src/type/__tests__/introspection-test.js rename to src/type/__tests__/introspection-test.ts diff --git a/src/type/__tests__/predicate-test.js b/src/type/__tests__/predicate-test.ts similarity index 98% rename from src/type/__tests__/predicate-test.js rename to src/type/__tests__/predicate-test.ts index 33c2c49f57..83d9858068 100644 --- a/src/type/__tests__/predicate-test.js +++ b/src/type/__tests__/predicate-test.ts @@ -1,7 +1,8 @@ +import { $Shape } from 'utility-types'; import { expect } from 'chai'; import { describe, it } from 'mocha'; -import type { GraphQLArgument, GraphQLInputField } from '../definition'; +import { GraphQLArgument, GraphQLInputField } from '../definition'; import { GraphQLDirective, GraphQLSkipDirective, @@ -296,7 +297,7 @@ describe('Type predicates', () => { }); describe('isInputType', () => { - function expectInputType(type: mixed) { + function expectInputType(type: unknown) { expect(isInputType(type)).to.equal(true); expect(() => assertInputType(type)).to.not.throw(); } @@ -317,7 +318,7 @@ describe('Type predicates', () => { expectInputType(new GraphQLNonNull(InputObjectType)); }); - function expectNonInputType(type: mixed) { + function expectNonInputType(type: unknown) { expect(isInputType(type)).to.equal(false); expect(() => assertInputType(type)).to.throw(); } @@ -340,7 +341,7 @@ describe('Type predicates', () => { }); describe('isOutputType', () => { - function expectOutputType(type: mixed) { + function expectOutputType(type: unknown) { expect(isOutputType(type)).to.equal(true); expect(() => assertOutputType(type)).to.not.throw(); } @@ -367,7 +368,7 @@ describe('Type predicates', () => { expectOutputType(new GraphQLNonNull(EnumType)); }); - function expectNonOutputType(type: mixed) { + function expectNonOutputType(type: unknown) { expect(isOutputType(type)).to.equal(false); expect(() => assertOutputType(type)).to.throw(); } diff --git a/src/type/__tests__/scalars-test.js b/src/type/__tests__/scalars-test.ts similarity index 98% rename from src/type/__tests__/scalars-test.js rename to src/type/__tests__/scalars-test.ts index 6e901c3fb0..67b1610c28 100644 --- a/src/type/__tests__/scalars-test.js +++ b/src/type/__tests__/scalars-test.ts @@ -14,7 +14,7 @@ import { describe('Type System: Specified scalar types', () => { describe('GraphQLInt', () => { it('parseValue', () => { - function parseValue(value: mixed) { + function parseValue(value: unknown) { return GraphQLInt.parseValue(value); } @@ -110,7 +110,7 @@ describe('Type System: Specified scalar types', () => { }); it('serialize', () => { - function serialize(value: mixed) { + function serialize(value: unknown) { return GraphQLInt.serialize(value); } @@ -183,7 +183,7 @@ describe('Type System: Specified scalar types', () => { describe('GraphQLFloat', () => { it('parseValue', () => { - function parseValue(value: mixed) { + function parseValue(value: unknown) { return GraphQLFloat.parseValue(value); } @@ -270,7 +270,7 @@ describe('Type System: Specified scalar types', () => { }); it('serialize', () => { - function serialize(value: mixed) { + function serialize(value: unknown) { return GraphQLFloat.serialize(value); } @@ -313,7 +313,7 @@ describe('Type System: Specified scalar types', () => { describe('GraphQLString', () => { it('parseValue', () => { - function parseValue(value: mixed) { + function parseValue(value: unknown) { return GraphQLString.parseValue(value); } @@ -377,7 +377,7 @@ describe('Type System: Specified scalar types', () => { }); it('serialize', () => { - function serialize(value: mixed) { + function serialize(value: unknown) { return GraphQLString.serialize(value); } @@ -418,7 +418,7 @@ describe('Type System: Specified scalar types', () => { describe('GraphQLBoolean', () => { it('parseValue', () => { - function parseValue(value: mixed) { + function parseValue(value: unknown) { return GraphQLBoolean.parseValue(value); } @@ -495,7 +495,7 @@ describe('Type System: Specified scalar types', () => { }); it('serialize', () => { - function serialize(value: mixed) { + function serialize(value: unknown) { return GraphQLBoolean.serialize(value); } @@ -532,7 +532,7 @@ describe('Type System: Specified scalar types', () => { describe('GraphQLID', () => { it('parseValue', () => { - function parseValue(value: mixed) { + function parseValue(value: unknown) { return GraphQLID.parseValue(value); } @@ -610,7 +610,7 @@ describe('Type System: Specified scalar types', () => { }); it('serialize', () => { - function serialize(value: mixed) { + function serialize(value: unknown) { return GraphQLID.serialize(value); } diff --git a/src/type/__tests__/schema-test.js b/src/type/__tests__/schema-test.ts similarity index 100% rename from src/type/__tests__/schema-test.js rename to src/type/__tests__/schema-test.ts diff --git a/src/type/__tests__/validation-test.js b/src/type/__tests__/validation-test.ts similarity index 99% rename from src/type/__tests__/validation-test.js rename to src/type/__tests__/validation-test.ts index a3e35443da..824abe8f04 100644 --- a/src/type/__tests__/validation-test.js +++ b/src/type/__tests__/validation-test.ts @@ -10,7 +10,7 @@ import { parse } from '../../language/parser'; import { extendSchema } from '../../utilities/extendSchema'; import { buildSchema } from '../../utilities/buildASTSchema'; -import type { +import { GraphQLNamedType, GraphQLInputType, GraphQLOutputType, @@ -68,7 +68,7 @@ const SomeInputObjectType = assertInputObjectType( const SomeDirective = assertDirective(SomeSchema.getDirective('SomeDirective')); -function withModifiers( +function withModifiers( type: T, ): Array | GraphQLNonNull>> { return [ @@ -1007,7 +1007,7 @@ describe('Type System: Enum types must be well defined', () => { describe('Type System: Object fields must have output types', () => { function schemaWithObjectField( - fieldConfig: GraphQLFieldConfig, + fieldConfig: GraphQLFieldConfig, ): GraphQLSchema { const BadObjectType = new GraphQLObjectType({ name: 'BadObject', @@ -1322,7 +1322,7 @@ describe('Type System: Interface extensions should be valid', () => { describe('Type System: Interface fields must have output types', () => { function schemaWithInterfaceField( - fieldConfig: GraphQLFieldConfig, + fieldConfig: GraphQLFieldConfig, ): GraphQLSchema { const fields = { badField: fieldConfig }; diff --git a/src/type/definition.js b/src/type/definition.ts similarity index 70% rename from src/type/definition.js rename to src/type/definition.ts index 0a125cd832..c7a545260a 100644 --- a/src/type/definition.js +++ b/src/type/definition.ts @@ -1,12 +1,9 @@ +import { $ReadOnly } from 'utility-types'; import objectEntries from '../polyfills/objectEntries'; -import type { Path } from '../jsutils/Path'; -import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; -import type { - ObjMap, - ReadOnlyObjMap, - ReadOnlyObjMapLike, -} from '../jsutils/ObjMap'; +import { Path } from '../jsutils/Path'; +import { PromiseOrValue } from '../jsutils/PromiseOrValue'; +import { ObjMap, ReadOnlyObjMap, ReadOnlyObjMapLike } from '../jsutils/ObjMap'; import inspect from '../jsutils/inspect'; import keyMap from '../jsutils/keyMap'; import mapValue from '../jsutils/mapValue'; @@ -23,7 +20,7 @@ import { GraphQLError } from '../error/GraphQLError'; import { Kind } from '../language/kinds'; import { print } from '../language/printer'; -import type { +import { ScalarTypeDefinitionNode, ObjectTypeDefinitionNode, FieldDefinitionNode, @@ -47,7 +44,7 @@ import type { import { valueFromASTUntyped } from '../utilities/valueFromASTUntyped'; -import type { GraphQLSchema } from './schema'; +import { GraphQLSchema } from './schema'; // Predicates & Assertions @@ -64,7 +61,7 @@ export type GraphQLType = | GraphQLList | GraphQLNonNull; -export function isType(type: mixed): boolean %checks { +export function isType(type: unknown): boolean { return ( isScalarType(type) || isObjectType(type) || @@ -77,7 +74,7 @@ export function isType(type: mixed): boolean %checks { ); } -export function assertType(type: mixed): GraphQLType { +export function assertType(type: unknown): GraphQLType { if (!isType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL type.`); } @@ -87,43 +84,39 @@ export function assertType(type: mixed): GraphQLType { /** * There are predicates for each kind of GraphQL type. */ - -declare function isScalarType(type: mixed): boolean %checks(type instanceof - GraphQLScalarType); +declare function isScalarType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isScalarType(type) { return instanceOf(type, GraphQLScalarType); } -export function assertScalarType(type: mixed): GraphQLScalarType { +export function assertScalarType(type: unknown): GraphQLScalarType { if (!isScalarType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL Scalar type.`); } return type; } -declare function isObjectType(type: mixed): boolean %checks(type instanceof - GraphQLObjectType); +declare function isObjectType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isObjectType(type) { return instanceOf(type, GraphQLObjectType); } -export function assertObjectType(type: mixed): GraphQLObjectType { +export function assertObjectType(type: unknown): GraphQLObjectType { if (!isObjectType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL Object type.`); } return type; } -declare function isInterfaceType(type: mixed): boolean %checks(type instanceof - GraphQLInterfaceType); +declare function isInterfaceType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isInterfaceType(type) { return instanceOf(type, GraphQLInterfaceType); } -export function assertInterfaceType(type: mixed): GraphQLInterfaceType { +export function assertInterfaceType(type: unknown): GraphQLInterfaceType { if (!isInterfaceType(type)) { throw new Error( `Expected ${inspect(type)} to be a GraphQL Interface type.`, @@ -132,42 +125,39 @@ export function assertInterfaceType(type: mixed): GraphQLInterfaceType { return type; } -declare function isUnionType(type: mixed): boolean %checks(type instanceof - GraphQLUnionType); +declare function isUnionType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isUnionType(type) { return instanceOf(type, GraphQLUnionType); } -export function assertUnionType(type: mixed): GraphQLUnionType { +export function assertUnionType(type: unknown): GraphQLUnionType { if (!isUnionType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL Union type.`); } return type; } -declare function isEnumType(type: mixed): boolean %checks(type instanceof - GraphQLEnumType); +declare function isEnumType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isEnumType(type) { return instanceOf(type, GraphQLEnumType); } -export function assertEnumType(type: mixed): GraphQLEnumType { +export function assertEnumType(type: unknown): GraphQLEnumType { if (!isEnumType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL Enum type.`); } return type; } -declare function isInputObjectType(type: mixed): boolean %checks(type instanceof - GraphQLInputObjectType); +declare function isInputObjectType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isInputObjectType(type) { return instanceOf(type, GraphQLInputObjectType); } -export function assertInputObjectType(type: mixed): GraphQLInputObjectType { +export function assertInputObjectType(type: unknown): GraphQLInputObjectType { if (!isInputObjectType(type)) { throw new Error( `Expected ${inspect(type)} to be a GraphQL Input Object type.`, @@ -176,28 +166,26 @@ export function assertInputObjectType(type: mixed): GraphQLInputObjectType { return type; } -declare function isListType(type: mixed): boolean %checks(type instanceof - GraphQLList); +declare function isListType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isListType(type) { return instanceOf(type, GraphQLList); } -export function assertListType(type: mixed): GraphQLList { +export function assertListType(type: unknown): GraphQLList { if (!isListType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL List type.`); } return type; } -declare function isNonNullType(type: mixed): boolean %checks(type instanceof - GraphQLNonNull); +declare function isNonNullType(type: unknown): boolean; // eslint-disable-next-line no-redeclare export function isNonNullType(type) { return instanceOf(type, GraphQLNonNull); } -export function assertNonNullType(type: mixed): GraphQLNonNull { +export function assertNonNullType(type: unknown): GraphQLNonNull { if (!isNonNullType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL Non-Null type.`); } @@ -216,10 +204,10 @@ export type GraphQLInputType = | GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType - | GraphQLList, + | GraphQLList >; -export function isInputType(type: mixed): boolean %checks { +export function isInputType(type: unknown): boolean { return ( isScalarType(type) || isEnumType(type) || @@ -228,7 +216,7 @@ export function isInputType(type: mixed): boolean %checks { ); } -export function assertInputType(type: mixed): GraphQLInputType { +export function assertInputType(type: unknown): GraphQLInputType { if (!isInputType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL input type.`); } @@ -251,10 +239,10 @@ export type GraphQLOutputType = | GraphQLInterfaceType | GraphQLUnionType | GraphQLEnumType - | GraphQLList, + | GraphQLList >; -export function isOutputType(type: mixed): boolean %checks { +export function isOutputType(type: unknown): boolean { return ( isScalarType(type) || isObjectType(type) || @@ -265,7 +253,7 @@ export function isOutputType(type: mixed): boolean %checks { ); } -export function assertOutputType(type: mixed): GraphQLOutputType { +export function assertOutputType(type: unknown): GraphQLOutputType { if (!isOutputType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL output type.`); } @@ -277,11 +265,11 @@ export function assertOutputType(type: mixed): GraphQLOutputType { */ export type GraphQLLeafType = GraphQLScalarType | GraphQLEnumType; -export function isLeafType(type: mixed): boolean %checks { +export function isLeafType(type: unknown): boolean { return isScalarType(type) || isEnumType(type); } -export function assertLeafType(type: mixed): GraphQLLeafType { +export function assertLeafType(type: unknown): GraphQLLeafType { if (!isLeafType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL leaf type.`); } @@ -296,11 +284,11 @@ export type GraphQLCompositeType = | GraphQLInterfaceType | GraphQLUnionType; -export function isCompositeType(type: mixed): boolean %checks { +export function isCompositeType(type: unknown): boolean { return isObjectType(type) || isInterfaceType(type) || isUnionType(type); } -export function assertCompositeType(type: mixed): GraphQLCompositeType { +export function assertCompositeType(type: unknown): GraphQLCompositeType { if (!isCompositeType(type)) { throw new Error( `Expected ${inspect(type)} to be a GraphQL composite type.`, @@ -314,11 +302,11 @@ export function assertCompositeType(type: mixed): GraphQLCompositeType { */ export type GraphQLAbstractType = GraphQLInterfaceType | GraphQLUnionType; -export function isAbstractType(type: mixed): boolean %checks { +export function isAbstractType(type: unknown): boolean { return isInterfaceType(type) || isUnionType(type); } -export function assertAbstractType(type: mixed): GraphQLAbstractType { +export function assertAbstractType(type: unknown): GraphQLAbstractType { if (!isAbstractType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL abstract type.`); } @@ -343,8 +331,8 @@ export function assertAbstractType(type: mixed): GraphQLAbstractType { * }) * */ -export class GraphQLList<+T: GraphQLType> { - +ofType: T; +export class GraphQLList { + readonly ofType: T; constructor(ofType: T) { devAssert( @@ -389,8 +377,8 @@ export class GraphQLList<+T: GraphQLType> { * * Note: the enforcement of non-nullability occurs within the executor. */ -export class GraphQLNonNull<+T: GraphQLNullableType> { - +ofType: T; +export class GraphQLNonNull { + readonly ofType: T; constructor(ofType: T) { devAssert( @@ -418,14 +406,13 @@ export class GraphQLNonNull<+T: GraphQLNullableType> { /** * These types wrap and modify other types */ - export type GraphQLWrappingType = GraphQLList | GraphQLNonNull; -export function isWrappingType(type: mixed): boolean %checks { +export function isWrappingType(type: unknown): boolean { return isListType(type) || isNonNullType(type); } -export function assertWrappingType(type: mixed): GraphQLWrappingType { +export function assertWrappingType(type: unknown): GraphQLWrappingType { if (!isWrappingType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL wrapping type.`); } @@ -444,11 +431,11 @@ export type GraphQLNullableType = | GraphQLInputObjectType | GraphQLList; -export function isNullableType(type: mixed): boolean %checks { +export function isNullableType(type: unknown): boolean { return isType(type) && !isNonNullType(type); } -export function assertNullableType(type: mixed): GraphQLNullableType { +export function assertNullableType(type: unknown): GraphQLNullableType { if (!isNullableType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL nullable type.`); } @@ -457,7 +444,7 @@ export function assertNullableType(type: mixed): GraphQLNullableType { /* eslint-disable no-redeclare */ declare function getNullableType(type: void | null): void; -declare function getNullableType(type: T): T; +declare function getNullableType(type: T): T; declare function getNullableType(type: GraphQLNonNull): T; export function getNullableType(type) { /* eslint-enable no-redeclare */ @@ -477,7 +464,7 @@ export type GraphQLNamedType = | GraphQLEnumType | GraphQLInputObjectType; -export function isNamedType(type: mixed): boolean %checks { +export function isNamedType(type: unknown): boolean { return ( isScalarType(type) || isObjectType(type) || @@ -488,7 +475,7 @@ export function isNamedType(type: mixed): boolean %checks { ); } -export function assertNamedType(type: mixed): GraphQLNamedType { +export function assertNamedType(type: unknown): GraphQLNamedType { if (!isNamedType(type)) { throw new Error(`Expected ${inspect(type)} to be a GraphQL named type.`); } @@ -513,14 +500,16 @@ export function getNamedType(type) { * Used while defining GraphQL types to allow for circular references in * otherwise immutable type definitions. */ -export type Thunk<+T> = (() => T) | T; +export type Thunk = (() => T) | T; -function resolveThunk<+T>(thunk: Thunk): T { +function resolveThunk(thunk: Thunk): T { // $FlowFixMe[incompatible-use] return typeof thunk === 'function' ? thunk() : thunk; } -function undefineIfEmpty(arr: ?$ReadOnlyArray): ?$ReadOnlyArray { +function undefineIfEmpty( + arr: ReadonlyArray | null | undefined, +): ReadonlyArray | null | undefined { return arr && arr.length > 0 ? arr : undefined; } @@ -550,16 +539,18 @@ function undefineIfEmpty(arr: ?$ReadOnlyArray): ?$ReadOnlyArray { */ export class GraphQLScalarType { name: string; - description: ?string; - specifiedByUrl: ?string; - serialize: GraphQLScalarSerializer; - parseValue: GraphQLScalarValueParser; - parseLiteral: GraphQLScalarLiteralParser; - extensions: ?ReadOnlyObjMap; - astNode: ?ScalarTypeDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; - - constructor(config: $ReadOnly>): void { + description: string | null | undefined; + specifiedByUrl: string | null | undefined; + serialize: GraphQLScalarSerializer; + parseValue: GraphQLScalarValueParser; + parseLiteral: GraphQLScalarLiteralParser; + extensions: ReadOnlyObjMap | null | undefined; + astNode: ScalarTypeDefinitionNode | null | undefined; + extensionASTNodes: ReadonlyArray | null | undefined; + + constructor( + config: $ReadOnly>, + ): void { const parseValue = config.parseValue ?? identityFunc; this.name = config.name; this.description = config.description; @@ -596,14 +587,13 @@ export class GraphQLScalarType { } } - toConfig(): {| - ...GraphQLScalarTypeConfig, - serialize: GraphQLScalarSerializer, - parseValue: GraphQLScalarValueParser, - parseLiteral: GraphQLScalarLiteralParser, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - |} { + toConfig(): GraphQLScalarTypeConfig & { + serialize: GraphQLScalarSerializer; + parseValue: GraphQLScalarValueParser; + parseLiteral: GraphQLScalarLiteralParser; + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + } { return { name: this.name, description: this.description, @@ -632,32 +622,32 @@ export class GraphQLScalarType { } export type GraphQLScalarSerializer = ( - outputValue: mixed, -) => ?TExternal; + outputValue: unknown, +) => TExternal | null | undefined; export type GraphQLScalarValueParser = ( - inputValue: mixed, -) => ?TInternal; + inputValue: unknown, +) => TInternal | null | undefined; export type GraphQLScalarLiteralParser = ( valueNode: ValueNode, - variables: ?ObjMap, -) => ?TInternal; + variables: ObjMap | null | undefined, +) => TInternal | null | undefined; -export type GraphQLScalarTypeConfig = {| - name: string, - description?: ?string, - specifiedByUrl?: ?string, +export type GraphQLScalarTypeConfig = { + name: string; + description?: string | null | undefined; + specifiedByUrl?: string | null | undefined; // Serializes an internal value to include in a response. - serialize?: GraphQLScalarSerializer, + serialize?: GraphQLScalarSerializer; // Parses an externally provided value to use as an input. - parseValue?: GraphQLScalarValueParser, + parseValue?: GraphQLScalarValueParser; // Parses an externally provided literal value to use as an input. - parseLiteral?: GraphQLScalarLiteralParser, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?ScalarTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -|}; + parseLiteral?: GraphQLScalarLiteralParser; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: ScalarTypeDefinitionNode | null | undefined; + extensionASTNodes?: ReadonlyArray | null | undefined; +}; /** * Object Type Definition @@ -698,16 +688,16 @@ export type GraphQLScalarTypeConfig = {| */ export class GraphQLObjectType { name: string; - description: ?string; - isTypeOf: ?GraphQLIsTypeOfFn; - extensions: ?ReadOnlyObjMap; - astNode: ?ObjectTypeDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; + description: string | null | undefined; + isTypeOf: GraphQLIsTypeOfFn | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: ObjectTypeDefinitionNode | null | undefined; + extensionASTNodes: ReadonlyArray | null | undefined; _fields: Thunk>; _interfaces: Thunk>; - constructor(config: $ReadOnly>): void { + constructor(config: $ReadOnly>) { this.name = config.name; this.description = config.description; this.isTypeOf = config.isTypeOf; @@ -739,13 +729,12 @@ export class GraphQLObjectType { return this._interfaces; } - toConfig(): {| - ...GraphQLObjectTypeConfig, - interfaces: Array, - fields: GraphQLFieldConfigMap, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - |} { + toConfig(): GraphQLObjectTypeConfig & { + interfaces: Array; + fields: GraphQLFieldConfigMap; + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + } { return { name: this.name, description: this.description, @@ -774,8 +763,8 @@ export class GraphQLObjectType { function defineInterfaces( config: $ReadOnly< - | GraphQLObjectTypeConfig - | GraphQLInterfaceTypeConfig, + | GraphQLObjectTypeConfig + | GraphQLInterfaceTypeConfig >, ): Array { const interfaces = resolveThunk(config.interfaces) ?? []; @@ -789,7 +778,7 @@ function defineInterfaces( function defineFieldMap( config: $ReadOnly< | GraphQLObjectTypeConfig - | GraphQLInterfaceTypeConfig, + | GraphQLInterfaceTypeConfig >, ): GraphQLFieldMap { const fieldMap = resolveThunk(config.fields); @@ -839,13 +828,13 @@ function defineFieldMap( }); } -function isPlainObj(obj: mixed): boolean { +function isPlainObj(obj: unknown): boolean { return isObjectLike(obj) && !Array.isArray(obj); } function fieldsToFieldsConfig( - fields: GraphQLFieldMap, -): GraphQLFieldConfigMap { + fields: GraphQLFieldMap, +): GraphQLFieldConfigMap { return mapValue(fields, (field) => ({ description: field.description, type: field.type, @@ -862,7 +851,7 @@ function fieldsToFieldsConfig( * @internal */ export function argsToArgsConfig( - args: $ReadOnlyArray, + args: ReadonlyArray, ): GraphQLFieldConfigArgumentMap { return keyValMap( args, @@ -878,16 +867,16 @@ export function argsToArgsConfig( ); } -export type GraphQLObjectTypeConfig = {| - name: string, - description?: ?string, - interfaces?: Thunk>, - fields: Thunk>, - isTypeOf?: ?GraphQLIsTypeOfFn, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?ObjectTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -|}; +export type GraphQLObjectTypeConfig = { + name: string; + description?: string | null | undefined; + interfaces?: Thunk | null | undefined>; + fields: Thunk>; + isTypeOf?: GraphQLIsTypeOfFn | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: ObjectTypeDefinitionNode | null | undefined; + extensionASTNodes?: ReadonlyArray | null | undefined; +}; /** * Note: returning GraphQLObjectType is deprecated and will be removed in v16.0.0 @@ -908,89 +897,97 @@ export type GraphQLIsTypeOfFn = ( export type GraphQLFieldResolver< TSource, TContext, - TArgs = { [argument: string]: any, ... }, + TArgs = { + [argument: string]: any; + } > = ( source: TSource, args: TArgs, context: TContext, info: GraphQLResolveInfo, -) => mixed; - -export type GraphQLResolveInfo = {| - +fieldName: string, - +fieldNodes: $ReadOnlyArray, - +returnType: GraphQLOutputType, - +parentType: GraphQLObjectType, - +path: Path, - +schema: GraphQLSchema, - +fragments: ObjMap, - +rootValue: mixed, - +operation: OperationDefinitionNode, - +variableValues: { [variable: string]: mixed, ... }, -|}; +) => unknown; + +export type GraphQLResolveInfo = { + readonly fieldName: string; + readonly fieldNodes: ReadonlyArray; + readonly returnType: GraphQLOutputType; + readonly parentType: GraphQLObjectType; + readonly path: Path; + readonly schema: GraphQLSchema; + readonly fragments: ObjMap; + readonly rootValue: unknown; + readonly operation: OperationDefinitionNode; + readonly variableValues: { + [variable: string]: unknown; + }; +}; export type GraphQLFieldConfig< TSource, TContext, - TArgs = { [argument: string]: any, ... }, -> = {| - description?: ?string, - type: GraphQLOutputType, - args?: GraphQLFieldConfigArgumentMap, - resolve?: GraphQLFieldResolver, - subscribe?: GraphQLFieldResolver, - deprecationReason?: ?string, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?FieldDefinitionNode, -|}; + TArgs = { + [argument: string]: any; + } +> = { + description?: string | null | undefined; + type: GraphQLOutputType; + args?: GraphQLFieldConfigArgumentMap; + resolve?: GraphQLFieldResolver; + subscribe?: GraphQLFieldResolver; + deprecationReason?: string | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: FieldDefinitionNode | null | undefined; +}; export type GraphQLFieldConfigArgumentMap = ObjMap; -export type GraphQLArgumentConfig = {| - description?: ?string, - type: GraphQLInputType, - defaultValue?: mixed, - extensions?: ?ReadOnlyObjMapLike, - deprecationReason?: ?string, - astNode?: ?InputValueDefinitionNode, -|}; +export type GraphQLArgumentConfig = { + description?: string | null | undefined; + type: GraphQLInputType; + defaultValue?: unknown; + extensions?: ReadOnlyObjMapLike | null | undefined; + deprecationReason?: string | null | undefined; + astNode?: InputValueDefinitionNode | null | undefined; +}; export type GraphQLFieldConfigMap = ObjMap< - GraphQLFieldConfig, + GraphQLFieldConfig >; export type GraphQLField< TSource, TContext, - TArgs = { [argument: string]: any, ... }, -> = {| - name: string, - description: ?string, - type: GraphQLOutputType, - args: Array, - resolve?: GraphQLFieldResolver, - subscribe?: GraphQLFieldResolver, - deprecationReason: ?string, - extensions: ?ReadOnlyObjMap, - astNode: ?FieldDefinitionNode, -|}; - -export type GraphQLArgument = {| - name: string, - description: ?string, - type: GraphQLInputType, - defaultValue: mixed, - deprecationReason: ?string, - extensions: ?ReadOnlyObjMap, - astNode: ?InputValueDefinitionNode, -|}; - -export function isRequiredArgument(arg: GraphQLArgument): boolean %checks { + TArgs = { + [argument: string]: any; + } +> = { + name: string; + description: string | null | undefined; + type: GraphQLOutputType; + args: Array; + resolve?: GraphQLFieldResolver; + subscribe?: GraphQLFieldResolver; + deprecationReason: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: FieldDefinitionNode | null | undefined; +}; + +export type GraphQLArgument = { + name: string; + description: string | null | undefined; + type: GraphQLInputType; + defaultValue: unknown; + deprecationReason: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: InputValueDefinitionNode | null | undefined; +}; + +export function isRequiredArgument(arg: GraphQLArgument): boolean { return isNonNullType(arg.type) && arg.defaultValue === undefined; } export type GraphQLFieldMap = ObjMap< - GraphQLField, + GraphQLField >; /** @@ -1013,16 +1010,19 @@ export type GraphQLFieldMap = ObjMap< */ export class GraphQLInterfaceType { name: string; - description: ?string; - resolveType: ?GraphQLTypeResolver; - extensions: ?ReadOnlyObjMap; - astNode: ?InterfaceTypeDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; + description: string | null | undefined; + resolveType: GraphQLTypeResolver | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: InterfaceTypeDefinitionNode | null | undefined; + extensionASTNodes: + | ReadonlyArray + | null + | undefined; _fields: Thunk>; _interfaces: Thunk>; - constructor(config: $ReadOnly>): void { + constructor(config: $ReadOnly>) { this.name = config.name; this.description = config.description; this.resolveType = config.resolveType; @@ -1054,13 +1054,12 @@ export class GraphQLInterfaceType { return this._interfaces; } - toConfig(): {| - ...GraphQLInterfaceTypeConfig, - interfaces: Array, - fields: GraphQLFieldConfigMap, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - |} { + toConfig(): GraphQLInterfaceTypeConfig & { + interfaces: Array; + fields: GraphQLFieldConfigMap; + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + } { return { name: this.name, description: this.description, @@ -1087,21 +1086,25 @@ export class GraphQLInterfaceType { } } -export type GraphQLInterfaceTypeConfig = {| - name: string, - description?: ?string, - interfaces?: Thunk>, - fields: Thunk>, +export type GraphQLInterfaceTypeConfig = { + name: string; + description?: string | null | undefined; + interfaces?: Thunk | null | undefined>; + fields: Thunk>; + /** * Optionally provide a custom type resolver function. If one is not provided, * the default implementation will call `isTypeOf` on each implementing * Object type. */ - resolveType?: ?GraphQLTypeResolver, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?InterfaceTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -|}; + resolveType?: GraphQLTypeResolver | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: InterfaceTypeDefinitionNode | null | undefined; + extensionASTNodes?: + | ReadonlyArray + | null + | undefined; +}; /** * Union Type Definition @@ -1128,15 +1131,15 @@ export type GraphQLInterfaceTypeConfig = {| */ export class GraphQLUnionType { name: string; - description: ?string; - resolveType: ?GraphQLTypeResolver; - extensions: ?ReadOnlyObjMap; - astNode: ?UnionTypeDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; + description: string | null | undefined; + resolveType: GraphQLTypeResolver | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: UnionTypeDefinitionNode | null | undefined; + extensionASTNodes: ReadonlyArray | null | undefined; _types: Thunk>; - constructor(config: $ReadOnly>): void { + constructor(config: $ReadOnly>) { this.name = config.name; this.description = config.description; this.resolveType = config.resolveType; @@ -1160,12 +1163,11 @@ export class GraphQLUnionType { return this._types; } - toConfig(): {| - ...GraphQLUnionTypeConfig, - types: Array, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - |} { + toConfig(): GraphQLUnionTypeConfig & { + types: Array; + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + } { return { name: this.name, description: this.description, @@ -1192,7 +1194,7 @@ export class GraphQLUnionType { } function defineTypes( - config: $ReadOnly>, + config: $ReadOnly>, ): Array { const types = resolveThunk(config.types); devAssert( @@ -1202,20 +1204,21 @@ function defineTypes( return types; } -export type GraphQLUnionTypeConfig = {| - name: string, - description?: ?string, - types: Thunk>, +export type GraphQLUnionTypeConfig = { + name: string; + description?: string | null | undefined; + types: Thunk>; + /** * Optionally provide a custom type resolver function. If one is not provided, * the default implementation will call `isTypeOf` on each implementing * Object type. */ - resolveType?: ?GraphQLTypeResolver, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?UnionTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -|}; + resolveType?: GraphQLTypeResolver | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: UnionTypeDefinitionNode | null | undefined; + extensionASTNodes?: ReadonlyArray | null | undefined; +}; /** * Enum Type Definition @@ -1238,18 +1241,31 @@ export type GraphQLUnionTypeConfig = {| * Note: If a value is not provided in a definition, the name of the enum value * will be used as its internal value. */ -export class GraphQLEnumType /* */ { +export class GraphQLEnumType { + /* */ name: string; - description: ?string; - extensions: ?ReadOnlyObjMap; - astNode: ?EnumTypeDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; - - _values: Array */>; - _valueLookup: Map; + description: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: EnumTypeDefinitionNode | null | undefined; + extensionASTNodes: ReadonlyArray | null | undefined; + + _values: Array< + GraphQLEnumValue + /* */ + >; + _valueLookup: Map< + any, + /* T */ + GraphQLEnumValue + >; _nameLookup: ObjMap; - constructor(config: $ReadOnly */>): void { + constructor( + config: $ReadOnly< + GraphQLEnumTypeConfig + /* */ + >, + ) { this.name = config.name; this.description = config.description; this.extensions = config.extensions && toObjMap(config.extensions); @@ -1265,15 +1281,21 @@ export class GraphQLEnumType /* */ { devAssert(typeof config.name === 'string', 'Must provide name.'); } - getValues(): Array */> { + getValues(): Array< + GraphQLEnumValue + /* */ + > { return this._values; } - getValue(name: string): ?GraphQLEnumValue { + getValue(name: string): GraphQLEnumValue | null | undefined { return this._nameLookup[name]; } - serialize(outputValue: mixed /* T */): ?string { + serialize( + outputValue: unknown, + /* T */ + ): string | null | undefined { const enumValue = this._valueLookup.get(outputValue); if (enumValue === undefined) { throw new GraphQLError( @@ -1283,7 +1305,7 @@ export class GraphQLEnumType /* */ { return enumValue.name; } - parseValue(inputValue: mixed): ?any /* T */ { + parseValue(inputValue: unknown): any | null | undefined /* T */ { if (typeof inputValue !== 'string') { const valueStr = inspect(inputValue); throw new GraphQLError( @@ -1302,7 +1324,10 @@ export class GraphQLEnumType /* */ { return enumValue.value; } - parseLiteral(valueNode: ValueNode, _variables: ?ObjMap): ?any /* T */ { + parseLiteral( + valueNode: ValueNode, + _variables: ObjMap | null | undefined, + ): any | null | undefined /* T */ { // Note: variables will be resolved to a value before calling this function. if (valueNode.kind !== Kind.ENUM) { const valueStr = print(valueNode); @@ -1325,11 +1350,10 @@ export class GraphQLEnumType /* */ { return enumValue.value; } - toConfig(): {| - ...GraphQLEnumTypeConfig, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - |} { + toConfig(): GraphQLEnumTypeConfig & { + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + } { const values = keyValMap( this.getValues(), (value) => value.name, @@ -1378,8 +1402,12 @@ function didYouMeanEnumValue( function defineEnumValues( typeName: string, - valueMap: GraphQLEnumValueConfigMap /* */, -): Array */> { + valueMap: GraphQLEnumValueConfigMap, + /* */ +): Array< + GraphQLEnumValue + /* */ +> { devAssert( isPlainObj(valueMap), `${typeName} values must be an object with value names as keys.`, @@ -1401,33 +1429,46 @@ function defineEnumValues( }); } -export type GraphQLEnumTypeConfig /* */ = {| - name: string, - description?: ?string, - values: GraphQLEnumValueConfigMap /* */, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?EnumTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -|}; - -export type GraphQLEnumValueConfigMap /* */ = ObjMap */>; - -export type GraphQLEnumValueConfig /* */ = {| - description?: ?string, - value?: any /* T */, - deprecationReason?: ?string, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?EnumValueDefinitionNode, -|}; - -export type GraphQLEnumValue /* */ = {| - name: string, - description: ?string, - value: any /* T */, - deprecationReason: ?string, - extensions: ?ReadOnlyObjMap, - astNode: ?EnumValueDefinitionNode, -|}; +export type GraphQLEnumTypeConfig = + /* */ + { + name: string; + description?: string | null | undefined; + values: GraphQLEnumValueConfigMap; + /* */ + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: EnumTypeDefinitionNode | null | undefined; + extensionASTNodes?: ReadonlyArray | null | undefined; + }; + +export type GraphQLEnumValueConfigMap = + /* */ + ObjMap< + GraphQLEnumValueConfig + /* */ + >; +export type GraphQLEnumValueConfig = + /* */ + { + description?: string | null | undefined; + value?: any; + /* T */ + deprecationReason?: string | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: EnumValueDefinitionNode | null | undefined; + }; + +export type GraphQLEnumValue = + /* */ + { + name: string; + description: string | null | undefined; + value: any; + /* T */ + deprecationReason: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: EnumValueDefinitionNode | null | undefined; + }; /** * Input Object Type Definition @@ -1451,14 +1492,17 @@ export type GraphQLEnumValue /* */ = {| */ export class GraphQLInputObjectType { name: string; - description: ?string; - extensions: ?ReadOnlyObjMap; - astNode: ?InputObjectTypeDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; + description: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: InputObjectTypeDefinitionNode | null | undefined; + extensionASTNodes: + | ReadonlyArray + | null + | undefined; _fields: Thunk; - constructor(config: $ReadOnly): void { + constructor(config: $ReadOnly) { this.name = config.name; this.description = config.description; this.extensions = config.extensions && toObjMap(config.extensions); @@ -1476,12 +1520,11 @@ export class GraphQLInputObjectType { return this._fields; } - toConfig(): {| - ...GraphQLInputObjectTypeConfig, - fields: GraphQLInputFieldConfigMap, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - |} { + toConfig(): GraphQLInputObjectTypeConfig & { + fields: GraphQLInputFieldConfigMap; + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + } { const fields = mapValue(this.getFields(), (field) => ({ description: field.description, type: field.type, @@ -1540,39 +1583,40 @@ function defineInputFieldMap( }); } -export type GraphQLInputObjectTypeConfig = {| - name: string, - description?: ?string, - fields: Thunk, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?InputObjectTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -|}; - -export type GraphQLInputFieldConfig = {| - description?: ?string, - type: GraphQLInputType, - defaultValue?: mixed, - deprecationReason?: ?string, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?InputValueDefinitionNode, -|}; +export type GraphQLInputObjectTypeConfig = { + name: string; + description?: string | null | undefined; + fields: Thunk; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: InputObjectTypeDefinitionNode | null | undefined; + extensionASTNodes?: + | ReadonlyArray + | null + | undefined; +}; + +export type GraphQLInputFieldConfig = { + description?: string | null | undefined; + type: GraphQLInputType; + defaultValue?: unknown; + deprecationReason?: string | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: InputValueDefinitionNode | null | undefined; +}; export type GraphQLInputFieldConfigMap = ObjMap; -export type GraphQLInputField = {| - name: string, - description: ?string, - type: GraphQLInputType, - defaultValue: mixed, - deprecationReason: ?string, - extensions: ?ReadOnlyObjMap, - astNode: ?InputValueDefinitionNode, -|}; - -export function isRequiredInputField( - field: GraphQLInputField, -): boolean %checks { +export type GraphQLInputField = { + name: string; + description: string | null | undefined; + type: GraphQLInputType; + defaultValue: unknown; + deprecationReason: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: InputValueDefinitionNode | null | undefined; +}; + +export function isRequiredInputField(field: GraphQLInputField): boolean { return isNonNullType(field.type) && field.defaultValue === undefined; } diff --git a/src/type/directives.js b/src/type/directives.ts similarity index 80% rename from src/type/directives.js rename to src/type/directives.ts index 83f21864b2..2eabe53101 100644 --- a/src/type/directives.js +++ b/src/type/directives.ts @@ -1,35 +1,31 @@ +import { $ReadOnly } from 'utility-types'; import objectEntries from '../polyfills/objectEntries'; -import type { ReadOnlyObjMap, ReadOnlyObjMapLike } from '../jsutils/ObjMap'; +import { ReadOnlyObjMap, ReadOnlyObjMapLike } from '../jsutils/ObjMap'; import inspect from '../jsutils/inspect'; import toObjMap from '../jsutils/toObjMap'; import devAssert from '../jsutils/devAssert'; import instanceOf from '../jsutils/instanceOf'; import isObjectLike from '../jsutils/isObjectLike'; -import type { DirectiveDefinitionNode } from '../language/ast'; -import type { DirectiveLocationEnum } from '../language/directiveLocation'; +import { DirectiveDefinitionNode } from '../language/ast'; +import { DirectiveLocationEnum } from '../language/directiveLocation'; import { DirectiveLocation } from '../language/directiveLocation'; -import type { - GraphQLArgument, - GraphQLFieldConfigArgumentMap, -} from './definition'; +import { GraphQLArgument, GraphQLFieldConfigArgumentMap } from './definition'; import { GraphQLString, GraphQLBoolean } from './scalars'; import { argsToArgsConfig, GraphQLNonNull } from './definition'; /** * Test if the given value is a GraphQL directive. */ -declare function isDirective( - directive: mixed, -): boolean %checks(directive instanceof GraphQLDirective); +declare function isDirective(directive: unknown): boolean; // eslint-disable-next-line no-redeclare export function isDirective(directive) { return instanceOf(directive, GraphQLDirective); } -export function assertDirective(directive: mixed): GraphQLDirective { +export function assertDirective(directive: unknown): GraphQLDirective { if (!isDirective(directive)) { throw new Error( `Expected ${inspect(directive)} to be a GraphQL directive.`, @@ -44,14 +40,14 @@ export function assertDirective(directive: mixed): GraphQLDirective { */ export class GraphQLDirective { name: string; - description: ?string; + description: string | null | undefined; locations: Array; args: Array; isRepeatable: boolean; - extensions: ?ReadOnlyObjMap; - astNode: ?DirectiveDefinitionNode; + extensions: ReadOnlyObjMap | null | undefined; + astNode: DirectiveDefinitionNode | null | undefined; - constructor(config: $ReadOnly): void { + constructor(config: $ReadOnly) { this.name = config.name; this.description = config.description; this.locations = config.locations; @@ -82,12 +78,11 @@ export class GraphQLDirective { })); } - toConfig(): {| - ...GraphQLDirectiveConfig, - args: GraphQLFieldConfigArgumentMap, - isRepeatable: boolean, - extensions: ?ReadOnlyObjMap, - |} { + toConfig(): GraphQLDirectiveConfig & { + args: GraphQLFieldConfigArgumentMap; + isRepeatable: boolean; + extensions: ReadOnlyObjMap | null | undefined; + } { return { name: this.name, description: this.description, @@ -113,15 +108,15 @@ export class GraphQLDirective { } } -export type GraphQLDirectiveConfig = {| - name: string, - description?: ?string, - locations: Array, - args?: ?GraphQLFieldConfigArgumentMap, - isRepeatable?: ?boolean, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?DirectiveDefinitionNode, -|}; +export type GraphQLDirectiveConfig = { + name: string; + description?: string | null | undefined; + locations: Array; + args?: GraphQLFieldConfigArgumentMap | null | undefined; + isRepeatable?: boolean | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: DirectiveDefinitionNode | null | undefined; +}; /** * Used to conditionally include fields or fragments. @@ -215,8 +210,6 @@ export const specifiedDirectives = Object.freeze([ GraphQLSpecifiedByDirective, ]); -export function isSpecifiedDirective( - directive: GraphQLDirective, -): boolean %checks { +export function isSpecifiedDirective(directive: GraphQLDirective): boolean { return specifiedDirectives.some(({ name }) => name === directive.name); } diff --git a/src/type/index.js b/src/type/index.ts similarity index 75% rename from src/type/index.js rename to src/type/index.ts index 811d50247a..2d18cd9f8d 100644 --- a/src/type/index.js +++ b/src/type/index.ts @@ -1,14 +1,12 @@ -export type { Path as ResponsePath } from '../jsutils/Path'; +export { Path as ResponsePath } from '../jsutils/Path'; export { // Predicate - isSchema, - // Assertion - assertSchema, - // GraphQL Schema definition + isSchema, // Assertion + assertSchema, // GraphQL Schema definition GraphQLSchema, } from './schema'; -export type { GraphQLSchemaConfig } from './schema'; +export { GraphQLSchemaConfig } from './schema'; export { // Predicates @@ -30,8 +28,7 @@ export { isNullableType, isNamedType, isRequiredArgument, - isRequiredInputField, - // Assertions + isRequiredInputField, // Assertions assertType, assertScalarType, assertObjectType, @@ -48,47 +45,39 @@ export { assertAbstractType, assertWrappingType, assertNullableType, - assertNamedType, - // Un-modifiers + assertNamedType, // Un-modifiers getNullableType, - getNamedType, - // Definitions + getNamedType, // Definitions GraphQLScalarType, GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType, GraphQLEnumType, - GraphQLInputObjectType, - // Type Wrappers + GraphQLInputObjectType, // Type Wrappers GraphQLList, GraphQLNonNull, } from './definition'; export { // Predicate - isDirective, - // Assertion - assertDirective, - // Directives Definition - GraphQLDirective, - // Built-in Directives defined by the Spec + isDirective, // Assertion + assertDirective, // Directives Definition + GraphQLDirective, // Built-in Directives defined by the Spec isSpecifiedDirective, specifiedDirectives, GraphQLIncludeDirective, GraphQLSkipDirective, GraphQLDeprecatedDirective, - GraphQLSpecifiedByDirective, - // Constant Deprecation Reason + GraphQLSpecifiedByDirective, // Constant Deprecation Reason DEFAULT_DEPRECATION_REASON, } from './directives'; -export type { GraphQLDirectiveConfig } from './directives'; +export { GraphQLDirectiveConfig } from './directives'; // Common built-in scalar instances. export { // Predicate - isSpecifiedScalarType, - // Standard GraphQL Scalars + isSpecifiedScalarType, // Standard GraphQL Scalars specifiedScalarTypes, GraphQLInt, GraphQLFloat, @@ -99,8 +88,7 @@ export { export { // Predicate - isIntrospectionType, - // GraphQL Types for introspection. + isIntrospectionType, // GraphQL Types for introspection. introspectionTypes, __Schema, __Directive, @@ -109,16 +97,14 @@ export { __Field, __InputValue, __EnumValue, - __TypeKind, - // "Enum" of Type Kinds - TypeKind, - // Meta-field definitions. + __TypeKind, // "Enum" of Type Kinds + TypeKind, // Meta-field definitions. SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, } from './introspection'; -export type { +export { GraphQLType, GraphQLInputType, GraphQLOutputType, diff --git a/src/type/introspection.js b/src/type/introspection.ts similarity index 95% rename from src/type/introspection.js rename to src/type/introspection.ts index 4963bd9674..9e65a97e8d 100644 --- a/src/type/introspection.js +++ b/src/type/introspection.ts @@ -7,9 +7,9 @@ import { print } from '../language/printer'; import { DirectiveLocation } from '../language/directiveLocation'; import { astFromValue } from '../utilities/astFromValue'; -import type { GraphQLSchema } from './schema'; -import type { GraphQLDirective } from './directives'; -import type { +import { GraphQLSchema } from './schema'; +import { GraphQLDirective } from './directives'; +import { GraphQLType, GraphQLNamedType, GraphQLInputField, @@ -75,7 +75,7 @@ export const __Schema = new GraphQLObjectType({ ), resolve: (schema) => schema.getDirectives(), }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __Directive = new GraphQLObjectType({ @@ -108,7 +108,7 @@ export const __Directive = new GraphQLObjectType({ ), resolve: (directive) => directive.args, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __DirectiveLocation = new GraphQLEnumType({ @@ -231,7 +231,7 @@ export const __Type = new GraphQLObjectType({ } // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false, `Unexpected type: "${inspect((type: empty))}".`); + invariant(false, `Unexpected type: "${inspect(type as never)}".`); }, }, name: { @@ -314,7 +314,7 @@ export const __Type = new GraphQLObjectType({ resolve: (type) => type.ofType !== undefined ? type.ofType : undefined, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __Field = new GraphQLObjectType({ @@ -359,7 +359,7 @@ export const __Field = new GraphQLObjectType({ type: GraphQLString, resolve: (field) => field.deprecationReason, }, - }: GraphQLFieldConfigMap, mixed>), + } as GraphQLFieldConfigMap, unknown>), }); export const __InputValue = new GraphQLObjectType({ @@ -398,7 +398,7 @@ export const __InputValue = new GraphQLObjectType({ type: GraphQLString, resolve: (obj) => obj.deprecationReason, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __EnumValue = new GraphQLObjectType({ @@ -423,7 +423,7 @@ export const __EnumValue = new GraphQLObjectType({ type: GraphQLString, resolve: (enumValue) => enumValue.deprecationReason, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const TypeKind = Object.freeze({ @@ -486,8 +486,7 @@ export const __TypeKind = new GraphQLEnumType({ * Note that these are GraphQLField and not GraphQLFieldConfig, * so the format for args is different. */ - -export const SchemaMetaFieldDef: GraphQLField = { +export const SchemaMetaFieldDef: GraphQLField = { name: '__schema', type: new GraphQLNonNull(__Schema), description: 'Access the current type schema of this server.', @@ -498,7 +497,7 @@ export const SchemaMetaFieldDef: GraphQLField = { astNode: undefined, }; -export const TypeMetaFieldDef: GraphQLField = { +export const TypeMetaFieldDef: GraphQLField = { name: '__type', type: __Type, description: 'Request the type information of a single type.', @@ -519,7 +518,7 @@ export const TypeMetaFieldDef: GraphQLField = { astNode: undefined, }; -export const TypeNameMetaFieldDef: GraphQLField = { +export const TypeNameMetaFieldDef: GraphQLField = { name: '__typename', type: new GraphQLNonNull(GraphQLString), description: 'The name of the current Object type at runtime.', @@ -541,6 +540,6 @@ export const introspectionTypes = Object.freeze([ __TypeKind, ]); -export function isIntrospectionType(type: GraphQLNamedType): boolean %checks { +export function isIntrospectionType(type: GraphQLNamedType): boolean { return introspectionTypes.some(({ name }) => type.name === name); } diff --git a/src/type/scalars.js b/src/type/scalars.ts similarity index 92% rename from src/type/scalars.js rename to src/type/scalars.ts index e02d2e5c6c..5cb2fbac31 100644 --- a/src/type/scalars.js +++ b/src/type/scalars.ts @@ -6,7 +6,7 @@ import { print } from '../language/printer'; import { GraphQLError } from '../error/GraphQLError'; -import type { GraphQLNamedType } from './definition'; +import { GraphQLNamedType } from './definition'; import { GraphQLScalarType } from './definition'; // As per the GraphQL Spec, Integers are only treated as valid when a valid @@ -17,7 +17,7 @@ import { GraphQLScalarType } from './definition'; const MAX_INT = 2147483647; const MIN_INT = -2147483648; -function serializeInt(outputValue: mixed): number { +function serializeInt(outputValue: unknown): number { const coercedValue = serializeObject(outputValue); if (typeof coercedValue === 'boolean') { @@ -43,7 +43,7 @@ function serializeInt(outputValue: mixed): number { return num; } -function coerceInt(inputValue: mixed): number { +function coerceInt(inputValue: unknown): number { if (typeof inputValue !== 'number' || !Number.isInteger(inputValue)) { throw new GraphQLError( `Int cannot represent non-integer value: ${inspect(inputValue)}`, @@ -81,7 +81,7 @@ export const GraphQLInt = new GraphQLScalarType({ }, }); -function serializeFloat(outputValue: mixed): number { +function serializeFloat(outputValue: unknown): number { const coercedValue = serializeObject(outputValue); if (typeof coercedValue === 'boolean') { @@ -101,7 +101,7 @@ function serializeFloat(outputValue: mixed): number { return num; } -function coerceFloat(inputValue: mixed): number { +function coerceFloat(inputValue: unknown): number { if (typeof inputValue !== 'number' || !Number.isFinite(inputValue)) { throw new GraphQLError( `Float cannot represent non numeric value: ${inspect(inputValue)}`, @@ -130,7 +130,7 @@ export const GraphQLFloat = new GraphQLScalarType({ // Support serializing objects with custom valueOf() or toJSON() functions - // a common way to represent a complex value which can be represented as // a string (ex: MongoDB id objects). -function serializeObject(outputValue: mixed): mixed { +function serializeObject(outputValue: unknown): unknown { if (isObjectLike(outputValue)) { if (typeof outputValue.valueOf === 'function') { const valueOfResult = outputValue.valueOf(); @@ -146,7 +146,7 @@ function serializeObject(outputValue: mixed): mixed { return outputValue; } -function serializeString(outputValue: mixed): string { +function serializeString(outputValue: unknown): string { const coercedValue = serializeObject(outputValue); // Serialize string, boolean and number values to a string, but do not @@ -165,7 +165,7 @@ function serializeString(outputValue: mixed): string { ); } -function coerceString(inputValue: mixed): string { +function coerceString(inputValue: unknown): string { if (typeof inputValue !== 'string') { throw new GraphQLError( `String cannot represent a non string value: ${inspect(inputValue)}`, @@ -191,7 +191,7 @@ export const GraphQLString = new GraphQLScalarType({ }, }); -function serializeBoolean(outputValue: mixed): boolean { +function serializeBoolean(outputValue: unknown): boolean { const coercedValue = serializeObject(outputValue); if (typeof coercedValue === 'boolean') { @@ -205,7 +205,7 @@ function serializeBoolean(outputValue: mixed): boolean { ); } -function coerceBoolean(inputValue: mixed): boolean { +function coerceBoolean(inputValue: unknown): boolean { if (typeof inputValue !== 'boolean') { throw new GraphQLError( `Boolean cannot represent a non boolean value: ${inspect(inputValue)}`, @@ -230,7 +230,7 @@ export const GraphQLBoolean = new GraphQLScalarType({ }, }); -function serializeID(outputValue: mixed): string { +function serializeID(outputValue: unknown): string { const coercedValue = serializeObject(outputValue); if (typeof coercedValue === 'string') { @@ -242,7 +242,7 @@ function serializeID(outputValue: mixed): string { throw new GraphQLError(`ID cannot represent value: ${inspect(outputValue)}`); } -function coerceID(inputValue: mixed): string { +function coerceID(inputValue: unknown): string { if (typeof inputValue === 'string') { return inputValue; } @@ -278,6 +278,6 @@ export const specifiedScalarTypes = Object.freeze([ GraphQLID, ]); -export function isSpecifiedScalarType(type: GraphQLNamedType): boolean %checks { +export function isSpecifiedScalarType(type: GraphQLNamedType): boolean { return specifiedScalarTypes.some(({ name }) => type.name === name); } diff --git a/src/type/schema.js b/src/type/schema.ts similarity index 80% rename from src/type/schema.js rename to src/type/schema.ts index 521540c185..c8a10149e7 100644 --- a/src/type/schema.js +++ b/src/type/schema.ts @@ -1,24 +1,18 @@ +import { $ReadOnly } from 'utility-types'; import objectValues from '../polyfills/objectValues'; -import type { - ObjMap, - ReadOnlyObjMap, - ReadOnlyObjMapLike, -} from '../jsutils/ObjMap'; +import { ObjMap, ReadOnlyObjMap, ReadOnlyObjMapLike } from '../jsutils/ObjMap'; import inspect from '../jsutils/inspect'; import toObjMap from '../jsutils/toObjMap'; import devAssert from '../jsutils/devAssert'; import instanceOf from '../jsutils/instanceOf'; import isObjectLike from '../jsutils/isObjectLike'; -import type { GraphQLError } from '../error/GraphQLError'; +import { GraphQLError } from '../error/GraphQLError'; -import type { - SchemaDefinitionNode, - SchemaExtensionNode, -} from '../language/ast'; +import { SchemaDefinitionNode, SchemaExtensionNode } from '../language/ast'; -import type { +import { GraphQLType, GraphQLNamedType, GraphQLAbstractType, @@ -42,14 +36,13 @@ import { /** * Test if the given value is a GraphQL schema. */ -declare function isSchema(schema: mixed): boolean %checks(schema instanceof - GraphQLSchema); +declare function isSchema(schema: unknown): boolean; // eslint-disable-next-line no-redeclare export function isSchema(schema) { return instanceOf(schema, GraphQLSchema); } -export function assertSchema(schema: mixed): GraphQLSchema { +export function assertSchema(schema: unknown): GraphQLSchema { if (!isSchema(schema)) { throw new Error(`Expected ${inspect(schema)} to be a GraphQL schema.`); } @@ -120,26 +113,26 @@ export function assertSchema(schema: mixed): GraphQLSchema { * */ export class GraphQLSchema { - description: ?string; - extensions: ?ReadOnlyObjMap; - astNode: ?SchemaDefinitionNode; - extensionASTNodes: ?$ReadOnlyArray; - - _queryType: ?GraphQLObjectType; - _mutationType: ?GraphQLObjectType; - _subscriptionType: ?GraphQLObjectType; - _directives: $ReadOnlyArray; + description: string | null | undefined; + extensions: ReadOnlyObjMap | null | undefined; + astNode: SchemaDefinitionNode | null | undefined; + extensionASTNodes: ReadonlyArray | null | undefined; + + _queryType: GraphQLObjectType | null | undefined; + _mutationType: GraphQLObjectType | null | undefined; + _subscriptionType: GraphQLObjectType | null | undefined; + _directives: ReadonlyArray; _typeMap: TypeMap; _subTypeMap: ObjMap>; - _implementationsMap: ObjMap<{| - objects: Array, - interfaces: Array, - |}>; + _implementationsMap: ObjMap<{ + objects: Array; + interfaces: Array; + }>; // Used as a cache for validateSchema(). - __validationErrors: ?$ReadOnlyArray; + __validationErrors: ReadonlyArray | null | undefined; - constructor(config: $ReadOnly): void { + constructor(config: $ReadOnly) { // If this schema was built from a source known to be valid, then it may be // marked with assumeValid to avoid an additional type system validation. this.__validationErrors = config.assumeValid === true ? [] : undefined; @@ -256,15 +249,15 @@ export class GraphQLSchema { } } - getQueryType(): ?GraphQLObjectType { + getQueryType(): GraphQLObjectType | null | undefined { return this._queryType; } - getMutationType(): ?GraphQLObjectType { + getMutationType(): GraphQLObjectType | null | undefined { return this._mutationType; } - getSubscriptionType(): ?GraphQLObjectType { + getSubscriptionType(): GraphQLObjectType | null | undefined { return this._subscriptionType; } @@ -272,13 +265,13 @@ export class GraphQLSchema { return this._typeMap; } - getType(name: string): ?GraphQLNamedType { + getType(name: string): GraphQLNamedType | null | undefined { return this.getTypeMap()[name]; } getPossibleTypes( abstractType: GraphQLAbstractType, - ): $ReadOnlyArray { + ): ReadonlyArray { return isUnionType(abstractType) ? abstractType.getTypes() : this.getImplementations(abstractType).objects; @@ -286,10 +279,10 @@ export class GraphQLSchema { getImplementations( interfaceType: GraphQLInterfaceType, - ): {| - objects: /* $ReadOnly */ Array, - interfaces: /* $ReadOnly */ Array, - |} { + ): { + objects: /* $ReadOnly */ Array; + interfaces: /* $ReadOnly */ Array; + } { const implementations = this._implementationsMap[interfaceType.name]; return implementations ?? { objects: [], interfaces: [] }; } @@ -321,11 +314,11 @@ export class GraphQLSchema { return map[maybeSubType.name] !== undefined; } - getDirectives(): $ReadOnlyArray { + getDirectives(): ReadonlyArray { return this._directives; } - getDirective(name: string): ?GraphQLDirective { + getDirective(name: string): GraphQLDirective | null | undefined { return this.getDirectives().find((directive) => directive.name === name); } @@ -352,7 +345,7 @@ export class GraphQLSchema { type TypeMap = ObjMap; -export type GraphQLSchemaValidationOptions = {| +export type GraphQLSchemaValidationOptions = { /** * When building a schema from a GraphQL service's introspection result, it * might be safe to assume the schema is valid. Set to true to assume the @@ -360,34 +353,32 @@ export type GraphQLSchemaValidationOptions = {| * * Default: false */ - assumeValid?: boolean, -|}; - -export type GraphQLSchemaConfig = {| - description?: ?string, - query?: ?GraphQLObjectType, - mutation?: ?GraphQLObjectType, - subscription?: ?GraphQLObjectType, - types?: ?Array, - directives?: ?Array, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?SchemaDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, - ...GraphQLSchemaValidationOptions, -|}; + assumeValid?: boolean; +}; + +export type GraphQLSchemaConfig = GraphQLSchemaValidationOptions & { + description?: string | null | undefined; + query?: GraphQLObjectType | null | undefined; + mutation?: GraphQLObjectType | null | undefined; + subscription?: GraphQLObjectType | null | undefined; + types?: Array | null | undefined; + directives?: Array | null | undefined; + extensions?: ReadOnlyObjMapLike | null | undefined; + astNode?: SchemaDefinitionNode | null | undefined; + extensionASTNodes?: ReadonlyArray | null | undefined; +}; /** * @internal */ -export type GraphQLSchemaNormalizedConfig = {| - ...GraphQLSchemaConfig, - description: ?string, - types: Array, - directives: Array, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - assumeValid: boolean, -|}; +export type GraphQLSchemaNormalizedConfig = GraphQLSchemaConfig & { + description: string | null | undefined; + types: Array; + directives: Array; + extensions: ReadOnlyObjMap | null | undefined; + extensionASTNodes: ReadonlyArray; + assumeValid: boolean; +}; function collectReferencedTypes( type: GraphQLType, diff --git a/src/type/validate.js b/src/type/validate.ts similarity index 92% rename from src/type/validate.js rename to src/type/validate.ts index f0075e2b9e..213ef21444 100644 --- a/src/type/validate.js +++ b/src/type/validate.ts @@ -5,7 +5,7 @@ import inspect from '../jsutils/inspect'; import { GraphQLError } from '../error/GraphQLError'; import { locatedError } from '../error/locatedError'; -import type { +import { ASTNode, NamedTypeNode, DirectiveNode, @@ -15,8 +15,8 @@ import type { import { isValidNameError } from '../utilities/assertValidName'; import { isEqualType, isTypeSubTypeOf } from '../utilities/typeComparators'; -import type { GraphQLSchema } from './schema'; -import type { +import { GraphQLSchema } from './schema'; +import { GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType, @@ -49,7 +49,7 @@ import { */ export function validateSchema( schema: GraphQLSchema, -): $ReadOnlyArray { +): ReadonlyArray { // First check to ensure the provided value is in fact a GraphQLSchema. assertSchema(schema); @@ -83,8 +83,8 @@ export function assertValidSchema(schema: GraphQLSchema): void { } class SchemaValidationContext { - +_errors: Array; - +schema: GraphQLSchema; + readonly _errors: Array; + readonly schema: GraphQLSchema; constructor(schema) { this._errors = []; @@ -93,7 +93,9 @@ class SchemaValidationContext { reportError( message: string, - nodes?: $ReadOnlyArray | ?ASTNode, + nodes?: + | ReadonlyArray + | (ASTNode | null | undefined), ): void { const _nodes = Array.isArray(nodes) ? nodes.filter(Boolean) : nodes; this.addError(new GraphQLError(message, _nodes)); @@ -103,7 +105,7 @@ class SchemaValidationContext { this._errors.push(error); } - getErrors(): $ReadOnlyArray { + getErrors(): ReadonlyArray { return this._errors; } } @@ -144,7 +146,7 @@ function validateRootTypes(context: SchemaValidationContext): void { function getOperationTypeNode( schema: GraphQLSchema, operation: OperationTypeNode, -): ?ASTNode { +): ASTNode | null | undefined { const operationNodes = getAllSubNodes(schema, (node) => node.operationTypes); for (const node of operationNodes) { if (node.operation === operation) { @@ -188,8 +190,7 @@ function validateDirectives(context: SchemaValidationContext): void { context.reportError( `Required argument @${directive.name}(${arg.name}:) cannot be deprecated.`, [ - getDeprecatedDirectiveNode(arg.astNode), - // istanbul ignore next (TODO need to write coverage tests) + getDeprecatedDirectiveNode(arg.astNode), // istanbul ignore next (TODO need to write coverage tests) arg.astNode?.type, ], ); @@ -200,7 +201,7 @@ function validateDirectives(context: SchemaValidationContext): void { function validateName( context: SchemaValidationContext, - node: { +name: string, +astNode: ?ASTNode, ... }, + node: { readonly name: string; readonly astNode: ASTNode | null | undefined }, ): void { // Ensure names are valid, however introspection types opt out. const error = isValidNameError(node.name); @@ -304,8 +305,7 @@ function validateFields( context.reportError( `Required argument ${type.name}.${field.name}(${argName}:) cannot be deprecated.`, [ - getDeprecatedDirectiveNode(arg.astNode), - // istanbul ignore next (TODO need to write coverage tests) + getDeprecatedDirectiveNode(arg.astNode), // istanbul ignore next (TODO need to write coverage tests) arg.astNode?.type, ], ); @@ -382,8 +382,7 @@ function validateTypeImplementsInterface( `is type ${inspect(typeField.type)}.`, [ // istanbul ignore next (TODO need to write coverage tests) - ifaceField.astNode?.type, - // istanbul ignore next (TODO need to write coverage tests) + ifaceField.astNode?.type, // istanbul ignore next (TODO need to write coverage tests) typeField.astNode?.type, ], ); @@ -414,8 +413,7 @@ function validateTypeImplementsInterface( `${inspect(typeArg.type)}.`, [ // istanbul ignore next (TODO need to write coverage tests) - ifaceArg.astNode?.type, - // istanbul ignore next (TODO need to write coverage tests) + ifaceArg.astNode?.type, // istanbul ignore next (TODO need to write coverage tests) typeArg.astNode?.type, ], ); @@ -550,8 +548,7 @@ function validateInputFields( context.reportError( `Required input field ${inputObj.name}.${field.name} cannot be deprecated.`, [ - getDeprecatedDirectiveNode(field.astNode), - // istanbul ignore next (TODO need to write coverage tests) + getDeprecatedDirectiveNode(field.astNode), // istanbul ignore next (TODO need to write coverage tests) field.astNode?.type, ], ); @@ -561,7 +558,7 @@ function validateInputFields( function createInputObjectCircularRefsValidator( context: SchemaValidationContext, -): (GraphQLInputObjectType) => void { +): (arg0: GraphQLInputObjectType) => void { // Modified copy of algorithm from 'src/validation/rules/NoFragmentCycles.js'. // Tracks already visited types to maintain O(N) and to ensure that cycles // are not redundantly reported. @@ -612,14 +609,13 @@ function createInputObjectCircularRefsValidator( } type SDLDefinedObject = { - +astNode: ?T, - +extensionASTNodes?: ?$ReadOnlyArray, - ... + readonly astNode: T | null | undefined; + readonly extensionASTNodes?: ReadonlyArray | null | undefined; }; -function getAllNodes( +function getAllNodes( object: SDLDefinedObject, -): $ReadOnlyArray { +): ReadonlyArray { const { astNode, extensionASTNodes } = object; return astNode ? extensionASTNodes @@ -628,10 +624,14 @@ function getAllNodes( : extensionASTNodes ?? []; } -function getAllSubNodes( +function getAllSubNodes< + T extends ASTNode, + K extends ASTNode, + L extends ASTNode +>( object: SDLDefinedObject, - getter: (T | K) => ?(L | $ReadOnlyArray), -): $ReadOnlyArray { + getter: (arg0: T | K) => (L | ReadonlyArray) | null | undefined, +): ReadonlyArray { let subNodes = []; for (const node of getAllNodes(object)) { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') @@ -643,7 +643,7 @@ function getAllSubNodes( function getAllImplementsInterfaceNodes( type: GraphQLObjectType | GraphQLInterfaceType, iface: GraphQLInterfaceType, -): $ReadOnlyArray { +): ReadonlyArray { return getAllSubNodes(type, (typeNode) => typeNode.interfaces).filter( (ifaceNode) => ifaceNode.name.value === iface.name, ); @@ -652,15 +652,18 @@ function getAllImplementsInterfaceNodes( function getUnionMemberTypeNodes( union: GraphQLUnionType, typeName: string, -): ?$ReadOnlyArray { +): ReadonlyArray | null | undefined { return getAllSubNodes(union, (unionNode) => unionNode.types).filter( (typeNode) => typeNode.name.value === typeName, ); } function getDeprecatedDirectiveNode( - definitionNode: ?{ +directives?: $ReadOnlyArray, ... }, -): ?DirectiveNode { + definitionNode: + | { readonly directives?: ReadonlyArray } + | null + | undefined, +): DirectiveNode | null | undefined { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') return definitionNode?.directives?.find( (node) => node.name.value === GraphQLDeprecatedDirective.name, diff --git a/src/utilities/TypeInfo.js b/src/utilities/TypeInfo.ts similarity index 79% rename from src/utilities/TypeInfo.js rename to src/utilities/TypeInfo.ts index 4fdbef2015..4a31b74b9e 100644 --- a/src/utilities/TypeInfo.js +++ b/src/utilities/TypeInfo.ts @@ -1,12 +1,12 @@ -import type { Visitor } from '../language/visitor'; -import type { ASTNode, ASTKindToNode, FieldNode } from '../language/ast'; +import { Visitor } from '../language/visitor'; +import { ASTNode, ASTKindToNode, FieldNode } from '../language/ast'; import { Kind } from '../language/kinds'; import { isNode } from '../language/ast'; import { getVisitFn } from '../language/visitor'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLDirective } from '../type/directives'; -import type { +import { GraphQLSchema } from '../type/schema'; +import { GraphQLDirective } from '../type/directives'; +import { GraphQLType, GraphQLInputType, GraphQLOutputType, @@ -43,26 +43,24 @@ import { typeFromAST } from './typeFromAST'; */ export class TypeInfo { _schema: GraphQLSchema; - _typeStack: Array; - _parentTypeStack: Array; - _inputTypeStack: Array; - _fieldDefStack: Array>; - _defaultValueStack: Array; - _directive: ?GraphQLDirective; - _argument: ?GraphQLArgument; - _enumValue: ?GraphQLEnumValue; + _typeStack: Array; + _parentTypeStack: Array; + _inputTypeStack: Array; + _fieldDefStack: Array | null | undefined>; + _defaultValueStack: Array; + _directive: GraphQLDirective | null | undefined; + _argument: GraphQLArgument | null | undefined; + _enumValue: GraphQLEnumValue | null | undefined; _getFieldDef: typeof getFieldDef; constructor( - schema: GraphQLSchema, - // NOTE: this experimental optional second parameter is only needed in order + schema: GraphQLSchema, // NOTE: this experimental optional second parameter is only needed in order // to support non-spec-compliant code bases. You should never need to use it. // It may disappear in the future. - getFieldDefFn?: typeof getFieldDef, - // Initial type may be provided in rare cases to facilitate traversals + getFieldDefFn?: typeof getFieldDef, // Initial type may be provided in rare cases to facilitate traversals // beginning somewhere other than documents. initialType?: GraphQLType, - ): void { + ) { this._schema = schema; this._typeStack = []; this._parentTypeStack = []; @@ -86,51 +84,51 @@ export class TypeInfo { } } - getType(): ?GraphQLOutputType { + getType(): GraphQLOutputType | null | undefined { if (this._typeStack.length > 0) { return this._typeStack[this._typeStack.length - 1]; } } - getParentType(): ?GraphQLCompositeType { + getParentType(): GraphQLCompositeType | null | undefined { if (this._parentTypeStack.length > 0) { return this._parentTypeStack[this._parentTypeStack.length - 1]; } } - getInputType(): ?GraphQLInputType { + getInputType(): GraphQLInputType | null | undefined { if (this._inputTypeStack.length > 0) { return this._inputTypeStack[this._inputTypeStack.length - 1]; } } - getParentInputType(): ?GraphQLInputType { + getParentInputType(): GraphQLInputType | null | undefined { if (this._inputTypeStack.length > 1) { return this._inputTypeStack[this._inputTypeStack.length - 2]; } } - getFieldDef(): ?GraphQLField { + getFieldDef(): GraphQLField | null | undefined { if (this._fieldDefStack.length > 0) { return this._fieldDefStack[this._fieldDefStack.length - 1]; } } - getDefaultValue(): ?mixed { + getDefaultValue(): unknown | null | undefined { if (this._defaultValueStack.length > 0) { return this._defaultValueStack[this._defaultValueStack.length - 1]; } } - getDirective(): ?GraphQLDirective { + getDirective(): GraphQLDirective | null | undefined { return this._directive; } - getArgument(): ?GraphQLArgument { + getArgument(): GraphQLArgument | null | undefined { return this._argument; } - getEnumValue(): ?GraphQLEnumValue { + getEnumValue(): GraphQLEnumValue | null | undefined { return this._enumValue; } @@ -142,7 +140,7 @@ export class TypeInfo { // which occurs before guarantees of schema and document validity. switch (node.kind) { case Kind.SELECTION_SET: { - const namedType: mixed = getNamedType(this.getType()); + const namedType: unknown = getNamedType(this.getType()); this._parentTypeStack.push( isCompositeType(namedType) ? namedType : undefined, ); @@ -151,7 +149,7 @@ export class TypeInfo { case Kind.FIELD: { const parentType = this.getParentType(); let fieldDef; - let fieldType: mixed; + let fieldType: unknown; if (parentType) { fieldDef = this._getFieldDef(schema, parentType, node); if (fieldDef) { @@ -166,7 +164,7 @@ export class TypeInfo { this._directive = schema.getDirective(node.name.value); break; case Kind.OPERATION_DEFINITION: { - let type: mixed; + let type: unknown; switch (node.operation) { case 'query': type = schema.getQueryType(); @@ -184,14 +182,14 @@ export class TypeInfo { case Kind.INLINE_FRAGMENT: case Kind.FRAGMENT_DEFINITION: { const typeConditionAST = node.typeCondition; - const outputType: mixed = typeConditionAST + const outputType: unknown = typeConditionAST ? typeFromAST(schema, typeConditionAST) : getNamedType(this.getType()); this._typeStack.push(isOutputType(outputType) ? outputType : undefined); break; } case Kind.VARIABLE_DEFINITION: { - const inputType: mixed = typeFromAST(schema, node.type); + const inputType: unknown = typeFromAST(schema, node.type); this._inputTypeStack.push( isInputType(inputType) ? inputType : undefined, ); @@ -199,7 +197,7 @@ export class TypeInfo { } case Kind.ARGUMENT: { let argDef; - let argType: mixed; + let argType: unknown; const fieldOrDirective = this.getDirective() ?? this.getFieldDef(); if (fieldOrDirective) { argDef = fieldOrDirective.args.find( @@ -215,8 +213,8 @@ export class TypeInfo { break; } case Kind.LIST: { - const listType: mixed = getNullableType(this.getInputType()); - const itemType: mixed = isListType(listType) + const listType: unknown = getNullableType(this.getInputType()); + const itemType: unknown = isListType(listType) ? listType.ofType : listType; // List positions never have a default value. @@ -225,7 +223,7 @@ export class TypeInfo { break; } case Kind.OBJECT_FIELD: { - const objectType: mixed = getNamedType(this.getInputType()); + const objectType: unknown = getNamedType(this.getInputType()); let inputFieldType: GraphQLInputType | void; let inputField: GraphQLInputField | void; if (isInputObjectType(objectType)) { @@ -243,7 +241,7 @@ export class TypeInfo { break; } case Kind.ENUM: { - const enumType: mixed = getNamedType(this.getInputType()); + const enumType: unknown = getNamedType(this.getInputType()); let enumValue; if (isEnumType(enumType)) { enumValue = enumType.getValue(node.value); @@ -258,10 +256,13 @@ export class TypeInfo { switch (node.kind) { case Kind.SELECTION_SET: this._parentTypeStack.pop(); + break; case Kind.FIELD: this._fieldDefStack.pop(); + this._typeStack.pop(); + break; case Kind.DIRECTIVE: this._directive = null; @@ -270,19 +271,26 @@ export class TypeInfo { case Kind.INLINE_FRAGMENT: case Kind.FRAGMENT_DEFINITION: this._typeStack.pop(); + break; case Kind.VARIABLE_DEFINITION: this._inputTypeStack.pop(); + break; case Kind.ARGUMENT: this._argument = null; + this._defaultValueStack.pop(); + this._inputTypeStack.pop(); + break; case Kind.LIST: case Kind.OBJECT_FIELD: this._defaultValueStack.pop(); + this._inputTypeStack.pop(); + break; case Kind.ENUM: this._enumValue = null; @@ -300,7 +308,7 @@ function getFieldDef( schema: GraphQLSchema, parentType: GraphQLType, fieldNode: FieldNode, -): ?GraphQLField { +): GraphQLField | null | undefined { const name = fieldNode.name.value; if ( name === SchemaMetaFieldDef.name && @@ -330,7 +338,12 @@ export function visitWithTypeInfo( return { enter(node) { typeInfo.enter(node); - const fn = getVisitFn(visitor, node.kind, /* isLeaving */ false); + const fn = getVisitFn( + visitor, + node.kind, + /* isLeaving */ + false, + ); if (fn) { const result = fn.apply(visitor, arguments); if (result !== undefined) { @@ -343,7 +356,12 @@ export function visitWithTypeInfo( } }, leave(node) { - const fn = getVisitFn(visitor, node.kind, /* isLeaving */ true); + const fn = getVisitFn( + visitor, + node.kind, + /* isLeaving */ + true, + ); let result; if (fn) { result = fn.apply(visitor, arguments); diff --git a/src/utilities/__tests__/TypeInfo-test.js b/src/utilities/__tests__/TypeInfo-test.ts similarity index 100% rename from src/utilities/__tests__/TypeInfo-test.js rename to src/utilities/__tests__/TypeInfo-test.ts diff --git a/src/utilities/__tests__/assertValidName-test.js b/src/utilities/__tests__/assertValidName-test.ts similarity index 100% rename from src/utilities/__tests__/assertValidName-test.js rename to src/utilities/__tests__/assertValidName-test.ts diff --git a/src/utilities/__tests__/astFromValue-test.js b/src/utilities/__tests__/astFromValue-test.ts similarity index 100% rename from src/utilities/__tests__/astFromValue-test.js rename to src/utilities/__tests__/astFromValue-test.ts diff --git a/src/utilities/__tests__/buildASTSchema-test.js b/src/utilities/__tests__/buildASTSchema-test.ts similarity index 99% rename from src/utilities/__tests__/buildASTSchema-test.js rename to src/utilities/__tests__/buildASTSchema-test.ts index cb1794bd7a..31d3268fd4 100644 --- a/src/utilities/__tests__/buildASTSchema-test.js +++ b/src/utilities/__tests__/buildASTSchema-test.ts @@ -5,12 +5,12 @@ import dedent from '../../__testUtils__/dedent'; import invariant from '../../jsutils/invariant'; -import type { ASTNode } from '../../language/ast'; +import { ASTNode } from '../../language/ast'; import { Kind } from '../../language/kinds'; import { parse } from '../../language/parser'; import { print } from '../../language/printer'; -import type { GraphQLNamedType } from '../../type/definition'; +import { GraphQLNamedType } from '../../type/definition'; import { GraphQLSchema } from '../../type/schema'; import { validateSchema } from '../../type/validate'; import { __Schema, __EnumValue } from '../../type/introspection'; @@ -51,7 +51,9 @@ function cycleSDL(sdl: string): string { return printSchema(buildSchema(sdl)); } -function printASTNode(obj: ?{ +astNode: ?ASTNode, ... }): string { +function printASTNode( + obj: { readonly astNode: ASTNode | null | undefined } | null | undefined, +): string { invariant(obj?.astNode != null); return print(obj.astNode); } diff --git a/src/utilities/__tests__/buildClientSchema-test.js b/src/utilities/__tests__/buildClientSchema-test.ts similarity index 96% rename from src/utilities/__tests__/buildClientSchema-test.js rename to src/utilities/__tests__/buildClientSchema-test.ts index 7be8a72640..d33095553d 100644 --- a/src/utilities/__tests__/buildClientSchema-test.js +++ b/src/utilities/__tests__/buildClientSchema-test.ts @@ -77,7 +77,7 @@ describe('Type System: build schema from introspection', () => { const schema = buildSchema(sdl); const introspection = introspectionFromSchema(schema); - delete (introspection: any).__schema.queryType; + delete (introspection as any).__schema.queryType; const clientSchema = buildClientSchema(introspection); expect(clientSchema.getQueryType()).to.equal(null); @@ -477,7 +477,7 @@ describe('Type System: build schema from introspection', () => { const schema = buildSchema(sdl); const introspection = introspectionFromSchema(schema); - delete (introspection: any).__schema.directives; + delete (introspection as any).__schema.directives; const clientSchema = buildClientSchema(introspection); @@ -611,7 +611,7 @@ describe('Type System: build schema from introspection', () => { it('throws when referenced unknown type', () => { const introspection = introspectionFromSchema(dummySchema); - (introspection: any).__schema.types = introspection.__schema.types.filter( + (introspection as any).__schema.types = introspection.__schema.types.filter( ({ name }) => name !== 'Query', ); @@ -628,7 +628,7 @@ describe('Type System: build schema from introspection', () => { `); const introspection = introspectionFromSchema(schema); - (introspection: any).__schema.types = introspection.__schema.types.filter( + (introspection as any).__schema.types = introspection.__schema.types.filter( ({ name }) => name !== 'Float', ); @@ -642,7 +642,7 @@ describe('Type System: build schema from introspection', () => { expect(introspection).to.have.nested.property('__schema.queryType.name'); - delete (introspection: any).__schema.queryType.name; + delete (introspection as any).__schema.queryType.name; expect(() => buildClientSchema(introspection)).to.throw( 'Unknown type reference: {}.', @@ -657,7 +657,7 @@ describe('Type System: build schema from introspection', () => { expect(queryTypeIntrospection).to.have.property('kind'); - delete (queryTypeIntrospection: any).kind; + delete (queryTypeIntrospection as any).kind; expect(() => buildClientSchema(introspection)).to.throw( /Invalid or incomplete introspection result. Ensure that a full introspection query is used in order to build a client schema: { name: "Query", .* }\./, @@ -672,7 +672,7 @@ describe('Type System: build schema from introspection', () => { expect(queryTypeIntrospection).to.have.property('interfaces'); - delete (queryTypeIntrospection: any).interfaces; + delete (queryTypeIntrospection as any).interfaces; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing interfaces: { kind: "OBJECT", name: "Query", .* }\./, @@ -686,7 +686,7 @@ describe('Type System: build schema from introspection', () => { ); expect(someInterfaceIntrospection).to.have.property('interfaces'); - (someInterfaceIntrospection: any).interfaces = null; + (someInterfaceIntrospection as any).interfaces = null; const clientSchema = buildClientSchema(introspection); expect(printSchema(clientSchema)).to.equal(printSchema(dummySchema)); @@ -699,7 +699,7 @@ describe('Type System: build schema from introspection', () => { ); expect(queryTypeIntrospection).to.have.property('fields'); - delete (queryTypeIntrospection: any).fields; + delete (queryTypeIntrospection as any).fields; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing fields: { kind: "OBJECT", name: "Query", .* }\./, @@ -713,7 +713,7 @@ describe('Type System: build schema from introspection', () => { ); expect(queryTypeIntrospection).to.have.nested.property('fields[0].args'); - delete (queryTypeIntrospection: any).fields[0].args; + delete (queryTypeIntrospection as any).fields[0].args; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing field args: { name: "foo", .* }\./, @@ -730,7 +730,7 @@ describe('Type System: build schema from introspection', () => { 'fields[0].args[0].type.name', 'String', ); - (queryTypeIntrospection: any).fields[0].args[0].type.name = 'SomeUnion'; + (queryTypeIntrospection as any).fields[0].args[0].type.name = 'SomeUnion'; expect(() => buildClientSchema(introspection)).to.throw( 'Introspection must provide input type for arguments, but received: SomeUnion.', @@ -747,7 +747,7 @@ describe('Type System: build schema from introspection', () => { 'fields[0].type.name', 'String', ); - (queryTypeIntrospection: any).fields[0].type.name = 'SomeInputObject'; + (queryTypeIntrospection as any).fields[0].type.name = 'SomeInputObject'; expect(() => buildClientSchema(introspection)).to.throw( 'Introspection must provide output type for fields, but received: SomeInputObject.', @@ -761,7 +761,7 @@ describe('Type System: build schema from introspection', () => { ); expect(someUnionIntrospection).to.have.property('possibleTypes'); - delete (someUnionIntrospection: any).possibleTypes; + delete (someUnionIntrospection as any).possibleTypes; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing possibleTypes: { kind: "UNION", name: "SomeUnion",.* }\./, @@ -775,7 +775,7 @@ describe('Type System: build schema from introspection', () => { ); expect(someEnumIntrospection).to.have.property('enumValues'); - delete (someEnumIntrospection: any).enumValues; + delete (someEnumIntrospection as any).enumValues; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing enumValues: { kind: "ENUM", name: "SomeEnum", .* }\./, @@ -789,7 +789,7 @@ describe('Type System: build schema from introspection', () => { ); expect(someInputObjectIntrospection).to.have.property('inputFields'); - delete (someInputObjectIntrospection: any).inputFields; + delete (someInputObjectIntrospection as any).inputFields; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing inputFields: { kind: "INPUT_OBJECT", name: "SomeInputObject", .* }\./, @@ -804,7 +804,7 @@ describe('Type System: build schema from introspection', () => { name: 'SomeDirective', locations: ['QUERY'], }); - delete (someDirectiveIntrospection: any).locations; + delete (someDirectiveIntrospection as any).locations; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing directive locations: { name: "SomeDirective", .* }\./, @@ -819,7 +819,7 @@ describe('Type System: build schema from introspection', () => { name: 'SomeDirective', args: [], }); - delete (someDirectiveIntrospection: any).args; + delete (someDirectiveIntrospection as any).args; expect(() => buildClientSchema(introspection)).to.throw( /Introspection result missing directive args: { name: "SomeDirective", .* }\./, diff --git a/src/utilities/__tests__/coerceInputValue-test.js b/src/utilities/__tests__/coerceInputValue-test.ts similarity index 98% rename from src/utilities/__tests__/coerceInputValue-test.js rename to src/utilities/__tests__/coerceInputValue-test.ts index 4da5636769..f184d44705 100644 --- a/src/utilities/__tests__/coerceInputValue-test.js +++ b/src/utilities/__tests__/coerceInputValue-test.ts @@ -3,7 +3,7 @@ import { describe, it } from 'mocha'; import invariant from '../../jsutils/invariant'; -import type { GraphQLInputType } from '../../type/definition'; +import { GraphQLInputType } from '../../type/definition'; import { GraphQLInt } from '../../type/scalars'; import { GraphQLList, @@ -25,7 +25,7 @@ function expectErrors(result: any) { } describe('coerceInputValue', () => { - function coerceValue(inputValue: mixed, type: GraphQLInputType) { + function coerceValue(inputValue: unknown, type: GraphQLInputType) { const errors = []; const value = coerceInputValue( inputValue, diff --git a/src/utilities/__tests__/concatAST-test.js b/src/utilities/__tests__/concatAST-test.ts similarity index 100% rename from src/utilities/__tests__/concatAST-test.js rename to src/utilities/__tests__/concatAST-test.ts diff --git a/src/utilities/__tests__/extendSchema-test.js b/src/utilities/__tests__/extendSchema-test.ts similarity index 99% rename from src/utilities/__tests__/extendSchema-test.js rename to src/utilities/__tests__/extendSchema-test.ts index 64ac885c4b..675486109b 100644 --- a/src/utilities/__tests__/extendSchema-test.js +++ b/src/utilities/__tests__/extendSchema-test.ts @@ -5,14 +5,14 @@ import dedent from '../../__testUtils__/dedent'; import invariant from '../../jsutils/invariant'; -import type { ASTNode } from '../../language/ast'; +import { ASTNode } from '../../language/ast'; import { Kind } from '../../language/kinds'; import { parse } from '../../language/parser'; import { print } from '../../language/printer'; import { graphqlSync } from '../../graphql'; -import type { GraphQLNamedType } from '../../type/definition'; +import { GraphQLNamedType } from '../../type/definition'; import { GraphQLSchema } from '../../type/schema'; import { validateSchema } from '../../type/validate'; import { assertDirective } from '../../type/directives'; @@ -37,7 +37,9 @@ import { printSchema } from '../printSchema'; import { extendSchema } from '../extendSchema'; import { buildSchema } from '../buildASTSchema'; -function printExtensionNodes(obj: ?GraphQLNamedType | GraphQLSchema): string { +function printExtensionNodes( + obj: (GraphQLNamedType | null | undefined) | GraphQLSchema, +): string { invariant(obj?.extensionASTNodes != null); return print({ kind: Kind.DOCUMENT, @@ -59,7 +61,9 @@ function printSchemaChanges( }); } -function printASTNode(obj: ?{ +astNode: ?ASTNode, ... }): string { +function printASTNode( + obj: { readonly astNode: ASTNode | null | undefined } | null | undefined, +): string { invariant(obj?.astNode != null); return print(obj.astNode); } diff --git a/src/utilities/__tests__/findBreakingChanges-test.js b/src/utilities/__tests__/findBreakingChanges-test.ts similarity index 100% rename from src/utilities/__tests__/findBreakingChanges-test.js rename to src/utilities/__tests__/findBreakingChanges-test.ts diff --git a/src/utilities/__tests__/getIntrospectionQuery-test.js b/src/utilities/__tests__/getIntrospectionQuery-test.ts similarity index 100% rename from src/utilities/__tests__/getIntrospectionQuery-test.js rename to src/utilities/__tests__/getIntrospectionQuery-test.ts diff --git a/src/utilities/__tests__/getOperationAST-test.js b/src/utilities/__tests__/getOperationAST-test.ts similarity index 100% rename from src/utilities/__tests__/getOperationAST-test.js rename to src/utilities/__tests__/getOperationAST-test.ts diff --git a/src/utilities/__tests__/getOperationRootType-test.js b/src/utilities/__tests__/getOperationRootType-test.ts similarity index 98% rename from src/utilities/__tests__/getOperationRootType-test.js rename to src/utilities/__tests__/getOperationRootType-test.ts index 8ebdcdfd8b..b2b3b7a87d 100644 --- a/src/utilities/__tests__/getOperationRootType-test.js +++ b/src/utilities/__tests__/getOperationRootType-test.ts @@ -3,7 +3,7 @@ import { describe, it } from 'mocha'; import invariant from '../../jsutils/invariant'; -import type { DocumentNode } from '../../language/ast'; +import { DocumentNode } from '../../language/ast'; import { Kind } from '../../language/kinds'; import { parse } from '../../language/parser'; diff --git a/src/utilities/__tests__/introspectionFromSchema-test.js b/src/utilities/__tests__/introspectionFromSchema-test.ts similarity index 95% rename from src/utilities/__tests__/introspectionFromSchema-test.js rename to src/utilities/__tests__/introspectionFromSchema-test.ts index 2aacbfce2b..bd31296ab1 100644 --- a/src/utilities/__tests__/introspectionFromSchema-test.js +++ b/src/utilities/__tests__/introspectionFromSchema-test.ts @@ -7,7 +7,7 @@ import { GraphQLSchema } from '../../type/schema'; import { GraphQLString } from '../../type/scalars'; import { GraphQLObjectType } from '../../type/definition'; -import type { IntrospectionQuery } from '../getIntrospectionQuery'; +import { IntrospectionQuery } from '../getIntrospectionQuery'; import { printSchema } from '../printSchema'; import { buildClientSchema } from '../buildClientSchema'; import { introspectionFromSchema } from '../introspectionFromSchema'; diff --git a/src/utilities/__tests__/lexicographicSortSchema-test.js b/src/utilities/__tests__/lexicographicSortSchema-test.ts similarity index 100% rename from src/utilities/__tests__/lexicographicSortSchema-test.js rename to src/utilities/__tests__/lexicographicSortSchema-test.ts diff --git a/src/utilities/__tests__/printSchema-test.js b/src/utilities/__tests__/printSchema-test.ts similarity index 99% rename from src/utilities/__tests__/printSchema-test.js rename to src/utilities/__tests__/printSchema-test.ts index 2bedc1478f..7d20534f2f 100644 --- a/src/utilities/__tests__/printSchema-test.js +++ b/src/utilities/__tests__/printSchema-test.ts @@ -5,7 +5,7 @@ import dedent from '../../__testUtils__/dedent'; import { DirectiveLocation } from '../../language/directiveLocation'; -import type { GraphQLFieldConfig } from '../../type/definition'; +import { GraphQLFieldConfig } from '../../type/definition'; import { GraphQLSchema } from '../../type/schema'; import { GraphQLDirective } from '../../type/directives'; import { GraphQLInt, GraphQLString, GraphQLBoolean } from '../../type/scalars'; @@ -30,7 +30,9 @@ function expectPrintedSchema(schema: GraphQLSchema) { return expect(schemaText); } -function buildSingleFieldSchema(fieldConfig: GraphQLFieldConfig) { +function buildSingleFieldSchema( + fieldConfig: GraphQLFieldConfig, +) { const Query = new GraphQLObjectType({ name: 'Query', fields: { singleField: fieldConfig }, diff --git a/src/utilities/__tests__/separateOperations-test.js b/src/utilities/__tests__/separateOperations-test.ts similarity index 100% rename from src/utilities/__tests__/separateOperations-test.js rename to src/utilities/__tests__/separateOperations-test.ts diff --git a/src/utilities/__tests__/stripIgnoredCharacters-fuzz.js b/src/utilities/__tests__/stripIgnoredCharacters-fuzz.ts similarity index 100% rename from src/utilities/__tests__/stripIgnoredCharacters-fuzz.js rename to src/utilities/__tests__/stripIgnoredCharacters-fuzz.ts diff --git a/src/utilities/__tests__/stripIgnoredCharacters-test.js b/src/utilities/__tests__/stripIgnoredCharacters-test.ts similarity index 99% rename from src/utilities/__tests__/stripIgnoredCharacters-test.js rename to src/utilities/__tests__/stripIgnoredCharacters-test.ts index fdc7d907d6..6bad509e85 100644 --- a/src/utilities/__tests__/stripIgnoredCharacters-test.js +++ b/src/utilities/__tests__/stripIgnoredCharacters-test.ts @@ -17,19 +17,15 @@ import { stripIgnoredCharacters } from '../stripIgnoredCharacters'; const ignoredTokens = [ // UnicodeBOM :: '\uFEFF', // Byte Order Mark (U+FEFF) - // WhiteSpace :: '\t', // Horizontal Tab (U+0009) ' ', // Space (U+0020) - // LineTerminator :: '\n', // "New Line (U+000A)" '\r', // "Carriage Return (U+000D)" [ lookahead ! "New Line (U+000A)" ] '\r\n', // "Carriage Return (U+000D)" "New Line (U+000A)" - // Comment :: '# "Comment" string\n', // `#` CommentChar* - // Comma :: ',', // , ]; @@ -58,7 +54,7 @@ const nonPunctuatorTokens = [ '"""block\nstring\nvalue"""', // StringValue(BlockString) ]; -function lexValue(str: string): ?string { +function lexValue(str: string): string | null | undefined { const lexer = new Lexer(new Source(str)); const value = lexer.advance().value; diff --git a/src/utilities/__tests__/typeComparators-test.js b/src/utilities/__tests__/typeComparators-test.ts similarity index 97% rename from src/utilities/__tests__/typeComparators-test.js rename to src/utilities/__tests__/typeComparators-test.ts index 3f2a87ae78..0a3f1adfa0 100644 --- a/src/utilities/__tests__/typeComparators-test.js +++ b/src/utilities/__tests__/typeComparators-test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import type { GraphQLFieldConfigMap } from '../../type/definition'; +import { GraphQLFieldConfigMap } from '../../type/definition'; import { GraphQLSchema } from '../../type/schema'; import { GraphQLString, GraphQLInt, GraphQLFloat } from '../../type/scalars'; import { @@ -53,7 +53,7 @@ describe('typeComparators', () => { }); describe('isTypeSubTypeOf', () => { - function testSchema(fields: GraphQLFieldConfigMap) { + function testSchema(fields: GraphQLFieldConfigMap) { return new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Query', diff --git a/src/utilities/__tests__/valueFromAST-test.js b/src/utilities/__tests__/valueFromAST-test.ts similarity index 98% rename from src/utilities/__tests__/valueFromAST-test.js rename to src/utilities/__tests__/valueFromAST-test.ts index f4dc325206..5bfef80230 100644 --- a/src/utilities/__tests__/valueFromAST-test.js +++ b/src/utilities/__tests__/valueFromAST-test.ts @@ -1,13 +1,13 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import type { ObjMap } from '../../jsutils/ObjMap'; +import { ObjMap } from '../../jsutils/ObjMap'; import invariant from '../../jsutils/invariant'; import identityFunc from '../../jsutils/identityFunc'; import { parseValue } from '../../language/parser'; -import type { GraphQLInputType } from '../../type/definition'; +import { GraphQLInputType } from '../../type/definition'; import { GraphQLInt, GraphQLFloat, @@ -29,7 +29,7 @@ describe('valueFromAST', () => { function expectValueFrom( valueText: string, type: GraphQLInputType, - variables: ?ObjMap, + variables: ObjMap | null | undefined, ) { const ast = parseValue(valueText); const value = valueFromAST(ast, type, variables); diff --git a/src/utilities/__tests__/valueFromASTUntyped-test.js b/src/utilities/__tests__/valueFromASTUntyped-test.ts similarity index 93% rename from src/utilities/__tests__/valueFromASTUntyped-test.js rename to src/utilities/__tests__/valueFromASTUntyped-test.ts index 5e971a43f6..3eb79104c0 100644 --- a/src/utilities/__tests__/valueFromASTUntyped-test.js +++ b/src/utilities/__tests__/valueFromASTUntyped-test.ts @@ -1,14 +1,17 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import type { ObjMap } from '../../jsutils/ObjMap'; +import { ObjMap } from '../../jsutils/ObjMap'; import { parseValue } from '../../language/parser'; import { valueFromASTUntyped } from '../valueFromASTUntyped'; describe('valueFromASTUntyped', () => { - function expectValueFrom(valueText: string, variables?: ?ObjMap) { + function expectValueFrom( + valueText: string, + variables?: ObjMap | null | undefined, + ) { const ast = parseValue(valueText); const value = valueFromASTUntyped(ast, variables); return expect(value); diff --git a/src/utilities/assertValidName.js b/src/utilities/assertValidName.ts similarity index 100% rename from src/utilities/assertValidName.js rename to src/utilities/assertValidName.ts diff --git a/src/utilities/astFromValue.js b/src/utilities/astFromValue.ts similarity index 94% rename from src/utilities/astFromValue.js rename to src/utilities/astFromValue.ts index da5ad95051..4a57672141 100644 --- a/src/utilities/astFromValue.js +++ b/src/utilities/astFromValue.ts @@ -5,10 +5,10 @@ import invariant from '../jsutils/invariant'; import isObjectLike from '../jsutils/isObjectLike'; import isCollection from '../jsutils/isCollection'; -import type { ValueNode } from '../language/ast'; +import { ValueNode } from '../language/ast'; import { Kind } from '../language/kinds'; -import type { GraphQLInputType } from '../type/definition'; +import { GraphQLInputType } from '../type/definition'; import { GraphQLID } from '../type/scalars'; import { isLeafType, @@ -39,7 +39,10 @@ import { * | null | NullValue | * */ -export function astFromValue(value: mixed, type: GraphQLInputType): ?ValueNode { +export function astFromValue( + value: unknown, + type: GraphQLInputType, +): ValueNode | null | undefined { if (isNonNullType(type)) { const astValue = astFromValue(value, type.ofType); if (astValue?.kind === Kind.NULL) { @@ -140,7 +143,7 @@ export function astFromValue(value: mixed, type: GraphQLInputType): ?ValueNode { } // istanbul ignore next (Not reachable. All possible input types have been considered) - invariant(false, 'Unexpected input type: ' + inspect((type: empty))); + invariant(false, 'Unexpected input type: ' + inspect(type as never)); } /** diff --git a/src/utilities/buildASTSchema.js b/src/utilities/buildASTSchema.ts similarity index 83% rename from src/utilities/buildASTSchema.js rename to src/utilities/buildASTSchema.ts index 7f72cb6114..fe3584920c 100644 --- a/src/utilities/buildASTSchema.js +++ b/src/utilities/buildASTSchema.ts @@ -1,29 +1,27 @@ import devAssert from '../jsutils/devAssert'; -import type { Source } from '../language/source'; -import type { DocumentNode } from '../language/ast'; -import type { ParseOptions } from '../language/parser'; +import { Source } from '../language/source'; +import { DocumentNode } from '../language/ast'; +import { ParseOptions } from '../language/parser'; import { Kind } from '../language/kinds'; import { parse } from '../language/parser'; import { assertValidSDL } from '../validation/validate'; -import type { GraphQLSchemaValidationOptions } from '../type/schema'; +import { GraphQLSchemaValidationOptions } from '../type/schema'; import { GraphQLSchema } from '../type/schema'; import { specifiedDirectives } from '../type/directives'; import { extendSchemaImpl } from './extendSchema'; -export type BuildSchemaOptions = {| - ...GraphQLSchemaValidationOptions, - +export type BuildSchemaOptions = GraphQLSchemaValidationOptions & { /** * Set to true to assume the SDL is valid. * * Default: false */ - assumeValidSDL?: boolean, -|}; + assumeValidSDL?: boolean; +}; /** * This takes the ast of a schema document produced by the parse function in @@ -65,13 +63,13 @@ export function buildASTSchema( // typed values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable results. case 'Query': - config.query = (type: any); + config.query = type as any; break; case 'Mutation': - config.mutation = (type: any); + config.mutation = type as any; break; case 'Subscription': - config.subscription = (type: any); + config.subscription = type as any; break; } } @@ -94,7 +92,7 @@ export function buildASTSchema( */ export function buildSchema( source: string | Source, - options?: {| ...BuildSchemaOptions, ...ParseOptions |}, + options?: BuildSchemaOptions & ParseOptions, ): GraphQLSchema { const document = parse(source, { noLocation: options?.noLocation, diff --git a/src/utilities/buildClientSchema.js b/src/utilities/buildClientSchema.ts similarity index 98% rename from src/utilities/buildClientSchema.js rename to src/utilities/buildClientSchema.ts index 59498e849b..2a7925dd05 100644 --- a/src/utilities/buildClientSchema.js +++ b/src/utilities/buildClientSchema.ts @@ -7,8 +7,8 @@ import isObjectLike from '../jsutils/isObjectLike'; import { parseValue } from '../language/parser'; -import type { GraphQLSchemaValidationOptions } from '../type/schema'; -import type { +import { GraphQLSchemaValidationOptions } from '../type/schema'; +import { GraphQLType, GraphQLNamedType, GraphQLFieldConfig, @@ -34,7 +34,7 @@ import { assertInterfaceType, } from '../type/definition'; -import type { +import { IntrospectionQuery, IntrospectionDirective, IntrospectionField, @@ -310,7 +310,7 @@ export function buildClientSchema( function buildFieldDefMap( typeIntrospection: IntrospectionObjectType | IntrospectionInterfaceType, - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { if (!typeIntrospection.fields) { throw new Error( `Introspection result missing fields: ${inspect(typeIntrospection)}.`, @@ -326,7 +326,7 @@ export function buildClientSchema( function buildField( fieldIntrospection: IntrospectionField, - ): GraphQLFieldConfig { + ): GraphQLFieldConfig { const type = getType(fieldIntrospection.type); if (!isOutputType(type)) { const typeStr = inspect(type); @@ -351,7 +351,7 @@ export function buildClientSchema( } function buildInputValueDefMap( - inputValueIntrospections: $ReadOnlyArray, + inputValueIntrospections: ReadonlyArray, ) { return keyValMap( inputValueIntrospections, diff --git a/src/utilities/coerceInputValue.js b/src/utilities/coerceInputValue.ts similarity index 92% rename from src/utilities/coerceInputValue.js rename to src/utilities/coerceInputValue.ts index e7b40e952e..c409a827e1 100644 --- a/src/utilities/coerceInputValue.js +++ b/src/utilities/coerceInputValue.ts @@ -1,6 +1,6 @@ import objectValues from '../polyfills/objectValues'; -import type { Path } from '../jsutils/Path'; +import { Path } from '../jsutils/Path'; import inspect from '../jsutils/inspect'; import invariant from '../jsutils/invariant'; import didYouMean from '../jsutils/didYouMean'; @@ -12,7 +12,7 @@ import { addPath, pathToArray } from '../jsutils/Path'; import { GraphQLError } from '../error/GraphQLError'; -import type { GraphQLInputType } from '../type/definition'; +import { GraphQLInputType } from '../type/definition'; import { isLeafType, isInputObjectType, @@ -21,8 +21,8 @@ import { } from '../type/definition'; type OnErrorCB = ( - path: $ReadOnlyArray, - invalidValue: mixed, + path: ReadonlyArray, + invalidValue: unknown, error: GraphQLError, ) => void; @@ -30,16 +30,16 @@ type OnErrorCB = ( * Coerces a JavaScript value given a GraphQL Input Type. */ export function coerceInputValue( - inputValue: mixed, + inputValue: unknown, type: GraphQLInputType, - onError?: OnErrorCB = defaultOnError, -): mixed { + onError: OnErrorCB = defaultOnError, +): unknown { return coerceInputValueImpl(inputValue, type, onError); } function defaultOnError( - path: $ReadOnlyArray, - invalidValue: mixed, + path: ReadonlyArray, + invalidValue: unknown, error: GraphQLError, ): void { let errorPrefix = 'Invalid value ' + inspect(invalidValue); @@ -51,11 +51,11 @@ function defaultOnError( } function coerceInputValueImpl( - inputValue: mixed, + inputValue: unknown, type: GraphQLInputType, onError: OnErrorCB, path: Path | void, -): mixed { +): unknown { if (isNonNullType(type)) { if (inputValue != null) { return coerceInputValueImpl(inputValue, type.ofType, onError, path); @@ -186,5 +186,5 @@ function coerceInputValueImpl( } // istanbul ignore next (Not reachable. All possible input types have been considered) - invariant(false, 'Unexpected input type: ' + inspect((type: empty))); + invariant(false, 'Unexpected input type: ' + inspect(type as never)); } diff --git a/src/utilities/concatAST.js b/src/utilities/concatAST.ts similarity index 82% rename from src/utilities/concatAST.js rename to src/utilities/concatAST.ts index b7a0ea4726..074d6c5a4c 100644 --- a/src/utilities/concatAST.js +++ b/src/utilities/concatAST.ts @@ -1,4 +1,4 @@ -import type { DocumentNode } from '../language/ast'; +import { DocumentNode } from '../language/ast'; /** * Provided a collection of ASTs, presumably each from different files, @@ -6,7 +6,7 @@ import type { DocumentNode } from '../language/ast'; * GraphQL source files which together represent one conceptual application. */ export function concatAST( - documents: $ReadOnlyArray, + documents: ReadonlyArray, ): DocumentNode { let definitions = []; for (const doc of documents) { diff --git a/src/utilities/extendSchema.js b/src/utilities/extendSchema.ts similarity index 91% rename from src/utilities/extendSchema.js rename to src/utilities/extendSchema.ts index 5bdf49e03b..7feb6d6bdf 100644 --- a/src/utilities/extendSchema.js +++ b/src/utilities/extendSchema.ts @@ -6,8 +6,8 @@ import mapValue from '../jsutils/mapValue'; import invariant from '../jsutils/invariant'; import devAssert from '../jsutils/devAssert'; -import type { DirectiveLocationEnum } from '../language/directiveLocation'; -import type { +import { DirectiveLocationEnum } from '../language/directiveLocation'; +import { DocumentNode, TypeNode, NamedTypeNode, @@ -41,11 +41,11 @@ import { assertValidSDLExtension } from '../validation/validate'; import { getDirectiveValues } from '../execution/values'; -import type { +import { GraphQLSchemaValidationOptions, GraphQLSchemaNormalizedConfig, } from '../type/schema'; -import type { +import { GraphQLType, GraphQLNamedType, GraphQLFieldConfig, @@ -84,16 +84,14 @@ import { import { valueFromAST } from './valueFromAST'; -type Options = {| - ...GraphQLSchemaValidationOptions, - +type Options = GraphQLSchemaValidationOptions & { /** * Set to true to assume the SDL is valid. * * Default: false */ - assumeValidSDL?: boolean, -|}; + assumeValidSDL?: boolean; +}; /** * Produces a new schema given an existing schema and a document which may @@ -146,7 +144,7 @@ export function extendSchemaImpl( // have the same name. For example, a type named "skip". const directiveDefs: Array = []; - let schemaDef: ?SchemaDefinitionNode; + let schemaDef: SchemaDefinitionNode | null | undefined; // Schema extensions are collected which may add additional operation types. const schemaExtensions: Array = []; @@ -219,7 +217,7 @@ export function extendSchemaImpl( // Below are functions used for producing this schema that have closed over // this scope and have access to the schema, cache, and newly defined types. - function replaceType(type: T): T { + function replaceType(type: T): T { if (isListType(type)) { // $FlowFixMe[incompatible-return] return new GraphQLList(replaceType(type.ofType)); @@ -231,11 +229,11 @@ export function extendSchemaImpl( return replaceNamedType(type); } - function replaceNamedType(type: T): T { + function replaceNamedType(type: T): T { // Note: While this could make early assertions to get the correctly // typed values, that would throw immediately while type system // validation with validateSchema() will produce more actionable results. - return ((typeMap[type.name]: any): T); + return (typeMap[type.name] as any) as T; } function replaceDirective(directive: GraphQLDirective): GraphQLDirective { @@ -272,7 +270,7 @@ export function extendSchemaImpl( } // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false, 'Unexpected type: ' + inspect((type: empty))); + invariant(false, 'Unexpected type: ' + inspect(type as never)); } function extendInputObjectType( @@ -377,8 +375,8 @@ export function extendSchemaImpl( } function extendField( - field: GraphQLFieldConfig, - ): GraphQLFieldConfig { + field: GraphQLFieldConfig, + ): GraphQLFieldConfig { return { ...field, type: replaceType(field.type), @@ -395,12 +393,12 @@ export function extendSchemaImpl( } function getOperationTypes( - nodes: $ReadOnlyArray, - ): {| - query: ?GraphQLObjectType, - mutation: ?GraphQLObjectType, - subscription: ?GraphQLObjectType, - |} { + nodes: ReadonlyArray, + ): { + query: GraphQLObjectType | null | undefined; + mutation: GraphQLObjectType | null | undefined; + subscription: GraphQLObjectType | null | undefined; + } { const opTypes = {}; for (const node of nodes) { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') @@ -414,7 +412,7 @@ export function extendSchemaImpl( // Note: While this could make early assertions to get the correctly // typed values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable results. - return (opTypes: any); + return opTypes as any; } function getNamedType(node: NamedTypeNode): GraphQLNamedType { @@ -440,7 +438,7 @@ export function extendSchemaImpl( function buildDirective(node: DirectiveDefinitionNode): GraphQLDirective { const locations = node.locations.map( - ({ value }) => ((value: any): DirectiveLocationEnum), + ({ value }) => (value as any) as DirectiveLocationEnum, ); return new GraphQLDirective({ @@ -454,13 +452,13 @@ export function extendSchemaImpl( } function buildFieldMap( - nodes: $ReadOnlyArray< + nodes: ReadonlyArray< | InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode | ObjectTypeDefinitionNode - | ObjectTypeExtensionNode, + | ObjectTypeExtensionNode >, - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { const fieldConfigMap = Object.create(null); for (const node of nodes) { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') @@ -471,7 +469,7 @@ export function extendSchemaImpl( // Note: While this could make assertions to get the correctly typed // value, that would throw immediately while type system validation // with validateSchema() will produce more actionable results. - type: (getWrappedType(field.type): any), + type: getWrappedType(field.type) as any, description: field.description?.value, args: buildArgumentMap(field.arguments), deprecationReason: getDeprecationReason(field), @@ -483,7 +481,7 @@ export function extendSchemaImpl( } function buildArgumentMap( - args: ?$ReadOnlyArray, + args: ReadonlyArray | null | undefined, ): GraphQLFieldConfigArgumentMap { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') const argsNodes = args ?? []; @@ -507,8 +505,8 @@ export function extendSchemaImpl( } function buildInputFieldMap( - nodes: $ReadOnlyArray< - InputObjectTypeDefinitionNode | InputObjectTypeExtensionNode, + nodes: ReadonlyArray< + InputObjectTypeDefinitionNode | InputObjectTypeExtensionNode >, ): GraphQLInputFieldConfigMap { const inputFieldMap = Object.create(null); @@ -535,7 +533,7 @@ export function extendSchemaImpl( } function buildEnumValueMap( - nodes: $ReadOnlyArray, + nodes: ReadonlyArray, ): GraphQLEnumValueConfigMap { const enumValueMap = Object.create(null); for (const node of nodes) { @@ -554,11 +552,11 @@ export function extendSchemaImpl( } function buildInterfaces( - nodes: $ReadOnlyArray< + nodes: ReadonlyArray< | InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode | ObjectTypeDefinitionNode - | ObjectTypeExtensionNode, + | ObjectTypeExtensionNode >, ): Array { const interfaces = []; @@ -571,14 +569,14 @@ export function extendSchemaImpl( // values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable // results. - interfaces.push((getNamedType(type): any)); + interfaces.push(getNamedType(type) as any); } } return interfaces; } function buildUnionTypes( - nodes: $ReadOnlyArray, + nodes: ReadonlyArray, ): Array { const types = []; for (const node of nodes) { @@ -590,7 +588,7 @@ export function extendSchemaImpl( // values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable // results. - types.push((getNamedType(type): any)); + types.push(getNamedType(type) as any); } } return types; @@ -602,7 +600,7 @@ export function extendSchemaImpl( switch (astNode.kind) { case Kind.OBJECT_TYPE_DEFINITION: { - const extensionASTNodes = (extensionNodes: any); + const extensionASTNodes = extensionNodes as any; const allNodes = [astNode, ...extensionASTNodes]; return new GraphQLObjectType({ @@ -615,7 +613,7 @@ export function extendSchemaImpl( }); } case Kind.INTERFACE_TYPE_DEFINITION: { - const extensionASTNodes = (extensionNodes: any); + const extensionASTNodes = extensionNodes as any; const allNodes = [astNode, ...extensionASTNodes]; return new GraphQLInterfaceType({ @@ -628,7 +626,7 @@ export function extendSchemaImpl( }); } case Kind.ENUM_TYPE_DEFINITION: { - const extensionASTNodes = (extensionNodes: any); + const extensionASTNodes = extensionNodes as any; const allNodes = [astNode, ...extensionASTNodes]; return new GraphQLEnumType({ @@ -640,7 +638,7 @@ export function extendSchemaImpl( }); } case Kind.UNION_TYPE_DEFINITION: { - const extensionASTNodes = (extensionNodes: any); + const extensionASTNodes = extensionNodes as any; const allNodes = [astNode, ...extensionASTNodes]; return new GraphQLUnionType({ @@ -652,7 +650,7 @@ export function extendSchemaImpl( }); } case Kind.SCALAR_TYPE_DEFINITION: { - const extensionASTNodes = (extensionNodes: any); + const extensionASTNodes = extensionNodes as any; return new GraphQLScalarType({ name, @@ -663,7 +661,7 @@ export function extendSchemaImpl( }); } case Kind.INPUT_OBJECT_TYPE_DEFINITION: { - const extensionASTNodes = (extensionNodes: any); + const extensionASTNodes = extensionNodes as any; const allNodes = [astNode, ...extensionASTNodes]; return new GraphQLInputObjectType({ @@ -679,7 +677,7 @@ export function extendSchemaImpl( // istanbul ignore next (Not reachable. All possible type definition nodes have been considered) invariant( false, - 'Unexpected type definition node: ' + inspect((astNode: empty)), + 'Unexpected type definition node: ' + inspect(astNode as never), ); } } @@ -698,9 +696,9 @@ function getDeprecationReason( | EnumValueDefinitionNode | FieldDefinitionNode | InputValueDefinitionNode, -): ?string { +): string | null | undefined { const deprecated = getDirectiveValues(GraphQLDeprecatedDirective, node); - return (deprecated?.reason: any); + return deprecated?.reason as any; } /** @@ -708,7 +706,7 @@ function getDeprecationReason( */ function getSpecifiedByUrl( node: ScalarTypeDefinitionNode | ScalarTypeExtensionNode, -): ?string { +): string | null | undefined { const specifiedBy = getDirectiveValues(GraphQLSpecifiedByDirective, node); - return (specifiedBy?.url: any); + return specifiedBy?.url as any; } diff --git a/src/utilities/findBreakingChanges.js b/src/utilities/findBreakingChanges.ts similarity index 93% rename from src/utilities/findBreakingChanges.js rename to src/utilities/findBreakingChanges.ts index 999f93feb9..9bf90fc410 100644 --- a/src/utilities/findBreakingChanges.js +++ b/src/utilities/findBreakingChanges.ts @@ -1,3 +1,4 @@ +import { $Keys } from 'utility-types'; import objectValues from '../polyfills/objectValues'; import keyMap from '../jsutils/keyMap'; @@ -7,8 +8,8 @@ import invariant from '../jsutils/invariant'; import { print } from '../language/printer'; import { visit } from '../language/visitor'; -import type { GraphQLSchema } from '../type/schema'; -import type { +import { GraphQLSchema } from '../type/schema'; +import { GraphQLField, GraphQLType, GraphQLInputType, @@ -64,15 +65,15 @@ export const DangerousChangeType = Object.freeze({ ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE', }); -export type BreakingChange = {| - type: $Keys, - description: string, -|}; +export type BreakingChange = { + type: $Keys; + description: string; +}; -export type DangerousChange = {| - type: $Keys, - description: string, -|}; +export type DangerousChange = { + type: $Keys; + description: string; +}; /** * Given two schemas, returns an Array containing descriptions of all the types @@ -85,7 +86,7 @@ export function findBreakingChanges( const breakingChanges = findSchemaChanges(oldSchema, newSchema).filter( (change) => change.type in BreakingChangeType, ); - return ((breakingChanges: any): Array); + return (breakingChanges as any) as Array; } /** @@ -99,7 +100,7 @@ export function findDangerousChanges( const dangerousChanges = findSchemaChanges(oldSchema, newSchema).filter( (change) => change.type in DangerousChangeType, ); - return ((dangerousChanges: any): Array); + return (dangerousChanges as any) as Array; } function findSchemaChanges( @@ -379,8 +380,8 @@ function findFieldChanges( function findArgChanges( oldType: GraphQLObjectType | GraphQLInterfaceType, - oldField: GraphQLField, - newField: GraphQLField, + oldField: GraphQLField, + newField: GraphQLField, ): Array { const schemaChanges = []; const argsDiff = diff(oldField.args, newField.args); @@ -455,8 +456,7 @@ function isChangeSafeForObjectOrInterfaceField( isChangeSafeForObjectOrInterfaceField( oldType.ofType, newType.ofType, - )) || - // moving from nullable to non-null of the same underlying type is safe + )) || // moving from nullable to non-null of the same underlying type is safe (isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType, newType.ofType)) ); @@ -472,8 +472,7 @@ function isChangeSafeForObjectOrInterfaceField( return ( // if they're both named types, see if their names are equivalent - (isNamedType(newType) && oldType.name === newType.name) || - // moving from nullable to non-null of the same underlying type is safe + (isNamedType(newType) && oldType.name === newType.name) || // moving from nullable to non-null of the same underlying type is safe (isNonNullType(newType) && isChangeSafeForObjectOrInterfaceField(oldType, newType.ofType)) ); @@ -499,8 +498,7 @@ function isChangeSafeForInputObjectFieldOrFieldArg( isChangeSafeForInputObjectFieldOrFieldArg( oldType.ofType, newType.ofType, - )) || - // moving from non-null to nullable of the same underlying type is safe + )) || // moving from non-null to nullable of the same underlying type is safe (!isNonNullType(newType) && isChangeSafeForInputObjectFieldOrFieldArg(oldType.ofType, newType)) ); @@ -532,10 +530,10 @@ function typeKindName(type: GraphQLNamedType): string { } // istanbul ignore next (Not reachable. All possible named types have been considered) - invariant(false, 'Unexpected type: ' + inspect((type: empty))); + invariant(false, 'Unexpected type: ' + inspect(type as never)); } -function stringifyValue(value: mixed, type: GraphQLInputType): string { +function stringifyValue(value: unknown, type: GraphQLInputType): string { const ast = astFromValue(value, type); invariant(ast != null); @@ -551,14 +549,14 @@ function stringifyValue(value: mixed, type: GraphQLInputType): string { return print(sortedAST); } -function diff( - oldArray: $ReadOnlyArray, - newArray: $ReadOnlyArray, -): {| - added: Array, - removed: Array, - persisted: Array<[T, T]>, -|} { +function diff( + oldArray: ReadonlyArray, + newArray: ReadonlyArray, +): { + added: Array; + removed: Array; + persisted: Array<[T, T]>; +} { const added = []; const removed = []; const persisted = []; diff --git a/src/utilities/getIntrospectionQuery.js b/src/utilities/getIntrospectionQuery.js deleted file mode 100644 index d54e77e510..0000000000 --- a/src/utilities/getIntrospectionQuery.js +++ /dev/null @@ -1,298 +0,0 @@ -import type { DirectiveLocationEnum } from '../language/directiveLocation'; - -export type IntrospectionOptions = {| - // Whether to include descriptions in the introspection result. - // Default: true - descriptions?: boolean, - - // Whether to include `specifiedByUrl` in the introspection result. - // Default: false - specifiedByUrl?: boolean, - - // Whether to include `isRepeatable` field on directives. - // Default: false - directiveIsRepeatable?: boolean, - - // Whether to include `description` field on schema. - // Default: false - schemaDescription?: boolean, -|}; - -export function getIntrospectionQuery(options?: IntrospectionOptions): string { - const optionsWithDefault = { - descriptions: true, - specifiedByUrl: false, - directiveIsRepeatable: false, - schemaDescription: false, - ...options, - }; - - const descriptions = optionsWithDefault.descriptions ? 'description' : ''; - const specifiedByUrl = optionsWithDefault.specifiedByUrl - ? 'specifiedByUrl' - : ''; - const directiveIsRepeatable = optionsWithDefault.directiveIsRepeatable - ? 'isRepeatable' - : ''; - const schemaDescription = optionsWithDefault.schemaDescription - ? descriptions - : ''; - - return ` - query IntrospectionQuery { - __schema { - ${schemaDescription} - queryType { name } - mutationType { name } - subscriptionType { name } - types { - ...FullType - } - directives { - name - ${descriptions} - ${directiveIsRepeatable} - locations - args { - ...InputValue - } - } - } - } - - fragment FullType on __Type { - kind - name - ${descriptions} - ${specifiedByUrl} - fields(includeDeprecated: true) { - name - ${descriptions} - args { - ...InputValue - } - type { - ...TypeRef - } - isDeprecated - deprecationReason - } - inputFields { - ...InputValue - } - interfaces { - ...TypeRef - } - enumValues(includeDeprecated: true) { - name - ${descriptions} - isDeprecated - deprecationReason - } - possibleTypes { - ...TypeRef - } - } - - fragment InputValue on __InputValue { - name - ${descriptions} - type { ...TypeRef } - defaultValue - } - - fragment TypeRef on __Type { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - } - } - } - } - } - } - } - } - `; -} - -export type IntrospectionQuery = {| - +__schema: IntrospectionSchema, -|}; - -export type IntrospectionSchema = {| - +description?: ?string, - +queryType: IntrospectionNamedTypeRef, - +mutationType: ?IntrospectionNamedTypeRef, - +subscriptionType: ?IntrospectionNamedTypeRef, - +types: $ReadOnlyArray, - +directives: $ReadOnlyArray, -|}; - -export type IntrospectionType = - | IntrospectionScalarType - | IntrospectionObjectType - | IntrospectionInterfaceType - | IntrospectionUnionType - | IntrospectionEnumType - | IntrospectionInputObjectType; - -export type IntrospectionOutputType = - | IntrospectionScalarType - | IntrospectionObjectType - | IntrospectionInterfaceType - | IntrospectionUnionType - | IntrospectionEnumType; - -export type IntrospectionInputType = - | IntrospectionScalarType - | IntrospectionEnumType - | IntrospectionInputObjectType; - -export type IntrospectionScalarType = {| - +kind: 'SCALAR', - +name: string, - +description?: ?string, - +specifiedByUrl?: ?string, -|}; - -export type IntrospectionObjectType = {| - +kind: 'OBJECT', - +name: string, - +description?: ?string, - +fields: $ReadOnlyArray, - +interfaces: $ReadOnlyArray< - IntrospectionNamedTypeRef, - >, -|}; - -export type IntrospectionInterfaceType = {| - +kind: 'INTERFACE', - +name: string, - +description?: ?string, - +fields: $ReadOnlyArray, - +interfaces: $ReadOnlyArray< - IntrospectionNamedTypeRef, - >, - +possibleTypes: $ReadOnlyArray< - IntrospectionNamedTypeRef, - >, -|}; - -export type IntrospectionUnionType = {| - +kind: 'UNION', - +name: string, - +description?: ?string, - +possibleTypes: $ReadOnlyArray< - IntrospectionNamedTypeRef, - >, -|}; - -export type IntrospectionEnumType = {| - +kind: 'ENUM', - +name: string, - +description?: ?string, - +enumValues: $ReadOnlyArray, -|}; - -export type IntrospectionInputObjectType = {| - +kind: 'INPUT_OBJECT', - +name: string, - +description?: ?string, - +inputFields: $ReadOnlyArray, -|}; - -export type IntrospectionListTypeRef< - T: IntrospectionTypeRef = IntrospectionTypeRef, -> = {| - +kind: 'LIST', - +ofType: T, -|}; - -export type IntrospectionNonNullTypeRef< - T: IntrospectionTypeRef = IntrospectionTypeRef, -> = {| - +kind: 'NON_NULL', - +ofType: T, -|}; - -export type IntrospectionTypeRef = - | IntrospectionNamedTypeRef<> - | IntrospectionListTypeRef<> - | IntrospectionNonNullTypeRef< - IntrospectionNamedTypeRef<> | IntrospectionListTypeRef<>, - >; - -export type IntrospectionOutputTypeRef = - | IntrospectionNamedTypeRef - | IntrospectionListTypeRef - | IntrospectionNonNullTypeRef< - | IntrospectionNamedTypeRef - | IntrospectionListTypeRef, - >; - -export type IntrospectionInputTypeRef = - | IntrospectionNamedTypeRef - | IntrospectionListTypeRef - | IntrospectionNonNullTypeRef< - | IntrospectionNamedTypeRef - | IntrospectionListTypeRef, - >; - -export type IntrospectionNamedTypeRef< - T: IntrospectionType = IntrospectionType, -> = {| - +kind: $PropertyType, - +name: string, -|}; - -export type IntrospectionField = {| - +name: string, - +description?: ?string, - +args: $ReadOnlyArray, - +type: IntrospectionOutputTypeRef, - +isDeprecated: boolean, - +deprecationReason: ?string, -|}; - -export type IntrospectionInputValue = {| - +name: string, - +description?: ?string, - +type: IntrospectionInputTypeRef, - +defaultValue: ?string, -|}; - -export type IntrospectionEnumValue = {| - +name: string, - +description?: ?string, - +isDeprecated: boolean, - +deprecationReason: ?string, -|}; - -export type IntrospectionDirective = {| - +name: string, - +description?: ?string, - +isRepeatable?: boolean, - +locations: $ReadOnlyArray, - +args: $ReadOnlyArray, -|}; diff --git a/src/utilities/getIntrospectionQuery.ts b/src/utilities/getIntrospectionQuery.ts new file mode 100644 index 0000000000..ab683a0b61 --- /dev/null +++ b/src/utilities/getIntrospectionQuery.ts @@ -0,0 +1,305 @@ +import { $PropertyType } from 'utility-types'; +import { DirectiveLocationEnum } from '../language/directiveLocation'; + +export type IntrospectionOptions = { + // Whether to include descriptions in the introspection result. + // Default: true + descriptions?: boolean; + + // Whether to include `specifiedByUrl` in the introspection result. + // Default: false + specifiedByUrl?: boolean; + + // Whether to include `isRepeatable` field on directives. + // Default: false + directiveIsRepeatable?: boolean; + + // Whether to include `description` field on schema. + // Default: false + schemaDescription?: boolean; +}; + +export function getIntrospectionQuery(options?: IntrospectionOptions): string { + const optionsWithDefault = { + descriptions: true, + specifiedByUrl: false, + directiveIsRepeatable: false, + schemaDescription: false, + ...options, + }; + + const descriptions = optionsWithDefault.descriptions ? 'description' : ''; + const specifiedByUrl = optionsWithDefault.specifiedByUrl + ? 'specifiedByUrl' + : ''; + const directiveIsRepeatable = optionsWithDefault.directiveIsRepeatable + ? 'isRepeatable' + : ''; + const schemaDescription = optionsWithDefault.schemaDescription + ? descriptions + : ''; + + return ` + query IntrospectionQuery { + __schema { + ${schemaDescription} + queryType { name } + mutationType { name } + subscriptionType { name } + types { + ...FullType + } + directives { + name + ${descriptions} + ${directiveIsRepeatable} + locations + args { + ...InputValue + } + } + } + } + + fragment FullType on __Type { + kind + name + ${descriptions} + ${specifiedByUrl} + fields(includeDeprecated: true) { + name + ${descriptions} + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + ${descriptions} + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } + } + + fragment InputValue on __InputValue { + name + ${descriptions} + type { ...TypeRef } + defaultValue + } + + fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + } + } + } + } + } + `; +} + +export type IntrospectionQuery = { + readonly __schema: IntrospectionSchema; +}; + +export type IntrospectionSchema = { + readonly description?: string | null | undefined; + readonly queryType: IntrospectionNamedTypeRef; + readonly mutationType: + | IntrospectionNamedTypeRef + | null + | undefined; + readonly subscriptionType: + | IntrospectionNamedTypeRef + | null + | undefined; + readonly types: ReadonlyArray; + readonly directives: ReadonlyArray; +}; + +export type IntrospectionType = + | IntrospectionScalarType + | IntrospectionObjectType + | IntrospectionInterfaceType + | IntrospectionUnionType + | IntrospectionEnumType + | IntrospectionInputObjectType; + +export type IntrospectionOutputType = + | IntrospectionScalarType + | IntrospectionObjectType + | IntrospectionInterfaceType + | IntrospectionUnionType + | IntrospectionEnumType; + +export type IntrospectionInputType = + | IntrospectionScalarType + | IntrospectionEnumType + | IntrospectionInputObjectType; + +export type IntrospectionScalarType = { + readonly kind: 'SCALAR'; + readonly name: string; + readonly description?: string | null | undefined; + readonly specifiedByUrl?: string | null | undefined; +}; + +export type IntrospectionObjectType = { + readonly kind: 'OBJECT'; + readonly name: string; + readonly description?: string | null | undefined; + readonly fields: ReadonlyArray; + readonly interfaces: ReadonlyArray< + IntrospectionNamedTypeRef + >; +}; + +export type IntrospectionInterfaceType = { + readonly kind: 'INTERFACE'; + readonly name: string; + readonly description?: string | null | undefined; + readonly fields: ReadonlyArray; + readonly interfaces: ReadonlyArray< + IntrospectionNamedTypeRef + >; + readonly possibleTypes: ReadonlyArray< + IntrospectionNamedTypeRef + >; +}; + +export type IntrospectionUnionType = { + readonly kind: 'UNION'; + readonly name: string; + readonly description?: string | null | undefined; + readonly possibleTypes: ReadonlyArray< + IntrospectionNamedTypeRef + >; +}; + +export type IntrospectionEnumType = { + readonly kind: 'ENUM'; + readonly name: string; + readonly description?: string | null | undefined; + readonly enumValues: ReadonlyArray; +}; + +export type IntrospectionInputObjectType = { + readonly kind: 'INPUT_OBJECT'; + readonly name: string; + readonly description?: string | null | undefined; + readonly inputFields: ReadonlyArray; +}; + +export type IntrospectionListTypeRef< + T extends IntrospectionTypeRef = IntrospectionTypeRef +> = { + readonly kind: 'LIST'; + readonly ofType: T; +}; + +export type IntrospectionNonNullTypeRef< + T extends IntrospectionTypeRef = IntrospectionTypeRef +> = { + readonly kind: 'NON_NULL'; + readonly ofType: T; +}; + +export type IntrospectionTypeRef = + | IntrospectionNamedTypeRef + | IntrospectionListTypeRef + | IntrospectionNonNullTypeRef< + IntrospectionNamedTypeRef | IntrospectionListTypeRef + >; + +export type IntrospectionOutputTypeRef = + | IntrospectionNamedTypeRef + | IntrospectionListTypeRef + | IntrospectionNonNullTypeRef< + | IntrospectionNamedTypeRef + | IntrospectionListTypeRef + >; + +export type IntrospectionInputTypeRef = + | IntrospectionNamedTypeRef + | IntrospectionListTypeRef + | IntrospectionNonNullTypeRef< + | IntrospectionNamedTypeRef + | IntrospectionListTypeRef + >; + +export type IntrospectionNamedTypeRef< + T extends IntrospectionType = IntrospectionType +> = { + readonly kind: $PropertyType; + readonly name: string; +}; + +export type IntrospectionField = { + readonly name: string; + readonly description?: string | null | undefined; + readonly args: ReadonlyArray; + readonly type: IntrospectionOutputTypeRef; + readonly isDeprecated: boolean; + readonly deprecationReason: string | null | undefined; +}; + +export type IntrospectionInputValue = { + readonly name: string; + readonly description?: string | null | undefined; + readonly type: IntrospectionInputTypeRef; + readonly defaultValue: string | null | undefined; +}; + +export type IntrospectionEnumValue = { + readonly name: string; + readonly description?: string | null | undefined; + readonly isDeprecated: boolean; + readonly deprecationReason: string | null | undefined; +}; + +export type IntrospectionDirective = { + readonly name: string; + readonly description?: string | null | undefined; + readonly isRepeatable?: boolean; + readonly locations: ReadonlyArray; + readonly args: ReadonlyArray; +}; diff --git a/src/utilities/getOperationAST.js b/src/utilities/getOperationAST.ts similarity index 83% rename from src/utilities/getOperationAST.js rename to src/utilities/getOperationAST.ts index 259d2f05c5..31a448dc47 100644 --- a/src/utilities/getOperationAST.js +++ b/src/utilities/getOperationAST.ts @@ -1,4 +1,4 @@ -import type { DocumentNode, OperationDefinitionNode } from '../language/ast'; +import { DocumentNode, OperationDefinitionNode } from '../language/ast'; import { Kind } from '../language/kinds'; /** @@ -8,8 +8,8 @@ import { Kind } from '../language/kinds'; */ export function getOperationAST( documentAST: DocumentNode, - operationName?: ?string, -): ?OperationDefinitionNode { + operationName?: string | null | undefined, +): OperationDefinitionNode | null | undefined { let operation = null; for (const definition of documentAST.definitions) { if (definition.kind === Kind.OPERATION_DEFINITION) { diff --git a/src/utilities/getOperationRootType.js b/src/utilities/getOperationRootType.ts similarity index 90% rename from src/utilities/getOperationRootType.js rename to src/utilities/getOperationRootType.ts index 039cefaa40..b9a94436cd 100644 --- a/src/utilities/getOperationRootType.js +++ b/src/utilities/getOperationRootType.ts @@ -1,12 +1,12 @@ import { GraphQLError } from '../error/GraphQLError'; -import type { +import { OperationDefinitionNode, OperationTypeDefinitionNode, } from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLObjectType } from '../type/definition'; +import { GraphQLSchema } from '../type/schema'; +import { GraphQLObjectType } from '../type/definition'; /** * Extracts the root type of the operation from the schema. diff --git a/src/utilities/index.js b/src/utilities/index.ts similarity index 95% rename from src/utilities/index.js rename to src/utilities/index.ts index b4c8372f04..49addf3e4e 100644 --- a/src/utilities/index.js +++ b/src/utilities/index.ts @@ -2,7 +2,7 @@ // Accepts optional IntrospectionOptions. export { getIntrospectionQuery } from './getIntrospectionQuery'; -export type { +export { IntrospectionOptions, IntrospectionQuery, IntrospectionSchema, @@ -41,7 +41,7 @@ export { buildClientSchema } from './buildClientSchema'; // Build a GraphQLSchema from GraphQL Schema language. export { buildASTSchema, buildSchema } from './buildASTSchema'; -export type { BuildSchemaOptions } from './buildASTSchema'; +export { BuildSchemaOptions } from './buildASTSchema'; // Extends an existing GraphQLSchema from a parsed GraphQL Schema language AST. export { extendSchema } from './extendSchema'; @@ -102,4 +102,4 @@ export { findBreakingChanges, findDangerousChanges, } from './findBreakingChanges'; -export type { BreakingChange, DangerousChange } from './findBreakingChanges'; +export { BreakingChange, DangerousChange } from './findBreakingChanges'; diff --git a/src/utilities/introspectionFromSchema.js b/src/utilities/introspectionFromSchema.ts similarity index 91% rename from src/utilities/introspectionFromSchema.js rename to src/utilities/introspectionFromSchema.ts index e880b82995..613dbed46a 100644 --- a/src/utilities/introspectionFromSchema.js +++ b/src/utilities/introspectionFromSchema.ts @@ -2,11 +2,11 @@ import invariant from '../jsutils/invariant'; import { parse } from '../language/parser'; -import type { GraphQLSchema } from '../type/schema'; +import { GraphQLSchema } from '../type/schema'; import { executeSync } from '../execution/execute'; -import type { +import { IntrospectionQuery, IntrospectionOptions, } from './getIntrospectionQuery'; @@ -34,5 +34,5 @@ export function introspectionFromSchema( const document = parse(getIntrospectionQuery(optionsWithDefaults)); const result = executeSync({ schema, document }); invariant(!result.errors && result.data); - return (result.data: any); + return result.data as any; } diff --git a/src/utilities/lexicographicSortSchema.js b/src/utilities/lexicographicSortSchema.ts similarity index 84% rename from src/utilities/lexicographicSortSchema.js rename to src/utilities/lexicographicSortSchema.ts index 57cbff0c48..8e63e78db1 100644 --- a/src/utilities/lexicographicSortSchema.js +++ b/src/utilities/lexicographicSortSchema.ts @@ -1,11 +1,11 @@ import objectValues from '../polyfills/objectValues'; -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; import inspect from '../jsutils/inspect'; import invariant from '../jsutils/invariant'; import keyValMap from '../jsutils/keyValMap'; -import type { +import { GraphQLType, GraphQLNamedType, GraphQLFieldConfigMap, @@ -55,7 +55,7 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { subscription: replaceMaybeType(schemaConfig.subscription), }); - function replaceType(type: T): T { + function replaceType(type: T): T { if (isListType(type)) { // $FlowFixMe[incompatible-return] return new GraphQLList(replaceType(type.ofType)); @@ -66,11 +66,13 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { return replaceNamedType(type); } - function replaceNamedType(type: T): T { - return ((typeMap[type.name]: any): T); + function replaceNamedType(type: T): T { + return (typeMap[type.name] as any) as T; } - function replaceMaybeType(maybeType: T): T { + function replaceMaybeType( + maybeType: T, + ): T { return maybeType && replaceNamedType(maybeType); } @@ -90,7 +92,7 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { })); } - function sortFields(fieldsMap: GraphQLFieldConfigMap) { + function sortFields(fieldsMap: GraphQLFieldConfigMap) { return sortObjMap(fieldsMap, (field) => ({ ...field, type: replaceType(field.type), @@ -105,11 +107,13 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { })); } - function sortTypes(arr: $ReadOnlyArray): Array { + function sortTypes( + arr: ReadonlyArray, + ): Array { return sortByName(arr).map(replaceNamedType); } - function sortNamedType(type: T) { + function sortNamedType(type: T) { if (isScalarType(type) || isIntrospectionType(type)) { return type; } @@ -153,11 +157,14 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { } // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false, 'Unexpected type: ' + inspect((type: empty))); + invariant(false, 'Unexpected type: ' + inspect(type as never)); } } -function sortObjMap(map: ObjMap, sortValueFn?: (T) => R): ObjMap { +function sortObjMap( + map: ObjMap, + sortValueFn?: (arg0: T) => R, +): ObjMap { const sortedMap = Object.create(null); const sortedKeys = sortBy(Object.keys(map), (x) => x); for (const key of sortedKeys) { @@ -167,15 +174,15 @@ function sortObjMap(map: ObjMap, sortValueFn?: (T) => R): ObjMap { return sortedMap; } -function sortByName( - array: $ReadOnlyArray, +function sortByName( + array: ReadonlyArray, ): Array { return sortBy(array, (obj) => obj.name); } function sortBy( - array: $ReadOnlyArray, - mapToKey: (T) => string, + array: ReadonlyArray, + mapToKey: (arg0: T) => string, ): Array { return array.slice().sort((obj1, obj2) => { const key1 = mapToKey(obj1); diff --git a/src/utilities/printSchema.js b/src/utilities/printSchema.ts similarity index 94% rename from src/utilities/printSchema.js rename to src/utilities/printSchema.ts index 2d02ef6fd1..b1dfab460f 100644 --- a/src/utilities/printSchema.js +++ b/src/utilities/printSchema.ts @@ -6,9 +6,9 @@ import invariant from '../jsutils/invariant'; import { print } from '../language/printer'; import { printBlockString } from '../language/blockString'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLDirective } from '../type/directives'; -import type { +import { GraphQLSchema } from '../type/schema'; +import { GraphQLDirective } from '../type/directives'; +import { GraphQLNamedType, GraphQLArgument, GraphQLInputField, @@ -71,7 +71,9 @@ function printFilteredSchema( ); } -function printSchemaDefinition(schema: GraphQLSchema): ?string { +function printSchemaDefinition( + schema: GraphQLSchema, +): string | null | undefined { if (schema.description == null && isSchemaOfCommonNames(schema)) { return; } @@ -149,7 +151,7 @@ export function printType(type: GraphQLNamedType): string { } // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false, 'Unexpected type: ' + inspect((type: empty))); + invariant(false, 'Unexpected type: ' + inspect(type as never)); } function printScalar(type: GraphQLScalarType): string { @@ -226,7 +228,7 @@ function printFields(type: GraphQLObjectType | GraphQLInterfaceType): string { return printBlock(fields); } -function printBlock(items: $ReadOnlyArray): string { +function printBlock(items: ReadonlyArray): string { return items.length !== 0 ? ' {\n' + items.join('\n') + '\n}' : ''; } @@ -281,7 +283,7 @@ function printDirective(directive: GraphQLDirective): string { ); } -function printDeprecated(reason: ?string): string { +function printDeprecated(reason: string | null | undefined): string { if (reason == null) { return ''; } @@ -306,7 +308,7 @@ function printSpecifiedByUrl(scalar: GraphQLScalarType): string { } function printDescription( - def: { +description: ?string, ... }, + def: { readonly description: string | null | undefined }, indentation: string = '', firstInBlock: boolean = true, ): string { diff --git a/src/utilities/separateOperations.js b/src/utilities/separateOperations.ts similarity index 95% rename from src/utilities/separateOperations.js rename to src/utilities/separateOperations.ts index f7be8f5cb9..e4e9fb9f7c 100644 --- a/src/utilities/separateOperations.js +++ b/src/utilities/separateOperations.ts @@ -1,6 +1,6 @@ -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; -import type { DocumentNode, OperationDefinitionNode } from '../language/ast'; +import { DocumentNode, OperationDefinitionNode } from '../language/ast'; import { Kind } from '../language/kinds'; import { visit } from '../language/visitor'; diff --git a/src/utilities/stripIgnoredCharacters.js b/src/utilities/stripIgnoredCharacters.ts similarity index 100% rename from src/utilities/stripIgnoredCharacters.js rename to src/utilities/stripIgnoredCharacters.ts diff --git a/src/utilities/typeComparators.js b/src/utilities/typeComparators.ts similarity index 96% rename from src/utilities/typeComparators.js rename to src/utilities/typeComparators.ts index 99f84d2e7a..eb088da3d0 100644 --- a/src/utilities/typeComparators.js +++ b/src/utilities/typeComparators.ts @@ -1,5 +1,5 @@ -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLType, GraphQLCompositeType } from '../type/definition'; +import { GraphQLSchema } from '../type/schema'; +import { GraphQLType, GraphQLCompositeType } from '../type/definition'; import { isInterfaceType, isObjectType, diff --git a/src/utilities/typeFromAST.js b/src/utilities/typeFromAST.ts similarity index 85% rename from src/utilities/typeFromAST.js rename to src/utilities/typeFromAST.ts index 6903c5287a..44ccc1c255 100644 --- a/src/utilities/typeFromAST.js +++ b/src/utilities/typeFromAST.ts @@ -1,16 +1,12 @@ import inspect from '../jsutils/inspect'; import invariant from '../jsutils/invariant'; -import type { - NamedTypeNode, - ListTypeNode, - NonNullTypeNode, -} from '../language/ast'; +import { NamedTypeNode, ListTypeNode, NonNullTypeNode } from '../language/ast'; import { Kind } from '../language/kinds'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLNamedType } from '../type/definition'; +import { GraphQLSchema } from '../type/schema'; +import { GraphQLNamedType } from '../type/definition'; import { GraphQLList, GraphQLNonNull } from '../type/definition'; /** @@ -20,6 +16,7 @@ import { GraphQLList, GraphQLNonNull } from '../type/definition'; * the type called "User" found in the schema. If a type called "User" is not * found in the schema, then undefined will be returned. */ + /* eslint-disable no-redeclare */ declare function typeFromAST( schema: GraphQLSchema, @@ -50,5 +47,5 @@ export function typeFromAST(schema, typeNode) { } // istanbul ignore next (Not reachable. All possible type nodes have been considered) - invariant(false, 'Unexpected type node: ' + inspect((typeNode: empty))); + invariant(false, 'Unexpected type node: ' + inspect(typeNode as never)); } diff --git a/src/utilities/valueFromAST.js b/src/utilities/valueFromAST.ts similarity index 93% rename from src/utilities/valueFromAST.js rename to src/utilities/valueFromAST.ts index 7afed42282..cb5c08bb22 100644 --- a/src/utilities/valueFromAST.js +++ b/src/utilities/valueFromAST.ts @@ -1,14 +1,14 @@ import objectValues from '../polyfills/objectValues'; -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; import keyMap from '../jsutils/keyMap'; import inspect from '../jsutils/inspect'; import invariant from '../jsutils/invariant'; -import type { ValueNode } from '../language/ast'; +import { ValueNode } from '../language/ast'; import { Kind } from '../language/kinds'; -import type { GraphQLInputType } from '../type/definition'; +import { GraphQLInputType } from '../type/definition'; import { isLeafType, isInputObjectType, @@ -37,10 +37,10 @@ import { * */ export function valueFromAST( - valueNode: ?ValueNode, + valueNode: ValueNode | null | undefined, type: GraphQLInputType, - variables?: ?ObjMap, -): mixed | void { + variables?: ObjMap | null | undefined, +): unknown | void { if (!valueNode) { // When there is no node, then there is also no value. // Importantly, this is different from returning the value null. @@ -147,14 +147,14 @@ export function valueFromAST( } // istanbul ignore next (Not reachable. All possible input types have been considered) - invariant(false, 'Unexpected input type: ' + inspect((type: empty))); + invariant(false, 'Unexpected input type: ' + inspect(type as never)); } // Returns true if the provided valueNode is a variable which is not defined // in the set of variables. function isMissingVariable( valueNode: ValueNode, - variables: ?ObjMap, + variables: ObjMap | null | undefined, ): boolean { return ( valueNode.kind === Kind.VARIABLE && diff --git a/src/utilities/valueFromASTUntyped.js b/src/utilities/valueFromASTUntyped.ts similarity index 87% rename from src/utilities/valueFromASTUntyped.js rename to src/utilities/valueFromASTUntyped.ts index 3b70329bda..5ac3098134 100644 --- a/src/utilities/valueFromASTUntyped.js +++ b/src/utilities/valueFromASTUntyped.ts @@ -1,10 +1,10 @@ -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; import inspect from '../jsutils/inspect'; import invariant from '../jsutils/invariant'; import keyValMap from '../jsutils/keyValMap'; import { Kind } from '../language/kinds'; -import type { ValueNode } from '../language/ast'; +import { ValueNode } from '../language/ast'; /** * Produces a JavaScript value given a GraphQL Value AST. @@ -24,8 +24,8 @@ import type { ValueNode } from '../language/ast'; */ export function valueFromASTUntyped( valueNode: ValueNode, - variables?: ?ObjMap, -): mixed { + variables?: ObjMap | null | undefined, +): unknown { switch (valueNode.kind) { case Kind.NULL: return null; @@ -52,5 +52,5 @@ export function valueFromASTUntyped( } // istanbul ignore next (Not reachable. All possible value nodes have been considered) - invariant(false, 'Unexpected value node: ' + inspect((valueNode: empty))); + invariant(false, 'Unexpected value node: ' + inspect(valueNode as never)); } diff --git a/src/validation/ValidationContext.js b/src/validation/ValidationContext.ts similarity index 74% rename from src/validation/ValidationContext.js rename to src/validation/ValidationContext.ts index 9bb3dbab6b..473ae21aba 100644 --- a/src/validation/ValidationContext.js +++ b/src/validation/ValidationContext.ts @@ -1,9 +1,9 @@ -import type { ObjMap } from '../jsutils/ObjMap'; +import { ObjMap } from '../jsutils/ObjMap'; -import type { GraphQLError } from '../error/GraphQLError'; +import { GraphQLError } from '../error/GraphQLError'; -import type { ASTVisitor } from '../language/visitor'; -import type { +import { ASTVisitor } from '../language/visitor'; +import { DocumentNode, OperationDefinitionNode, VariableNode, @@ -15,9 +15,9 @@ import type { import { Kind } from '../language/kinds'; import { visit } from '../language/visitor'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLDirective } from '../type/directives'; -import type { +import { GraphQLSchema } from '../type/schema'; +import { GraphQLDirective } from '../type/directives'; +import { GraphQLInputType, GraphQLOutputType, GraphQLCompositeType, @@ -29,11 +29,11 @@ import type { import { TypeInfo, visitWithTypeInfo } from '../utilities/TypeInfo'; type NodeWithSelectionSet = OperationDefinitionNode | FragmentDefinitionNode; -type VariableUsage = {| - +node: VariableNode, - +type: ?GraphQLInputType, - +defaultValue: ?mixed, -|}; +type VariableUsage = { + readonly node: VariableNode; + readonly type: GraphQLInputType | null | undefined; + readonly defaultValue: unknown | null | undefined; +}; /** * An instance of this class is passed as the "this" context to all validators, @@ -43,14 +43,14 @@ type VariableUsage = {| export class ASTValidationContext { _ast: DocumentNode; _onError: (err: GraphQLError) => void; - _fragments: ?ObjMap; - _fragmentSpreads: Map>; + _fragments: ObjMap | null | undefined; + _fragmentSpreads: Map>; _recursivelyReferencedFragments: Map< OperationDefinitionNode, - $ReadOnlyArray, + ReadonlyArray >; - constructor(ast: DocumentNode, onError: (err: GraphQLError) => void): void { + constructor(ast: DocumentNode, onError: (err: GraphQLError) => void) { this._ast = ast; this._fragments = undefined; this._fragmentSpreads = new Map(); @@ -66,7 +66,7 @@ export class ASTValidationContext { return this._ast; } - getFragment(name: string): ?FragmentDefinitionNode { + getFragment(name: string): FragmentDefinitionNode | null | undefined { let fragments = this._fragments; if (!fragments) { this._fragments = fragments = this.getDocument().definitions.reduce( @@ -84,7 +84,7 @@ export class ASTValidationContext { getFragmentSpreads( node: SelectionSetNode, - ): $ReadOnlyArray { + ): ReadonlyArray { let spreads = this._fragmentSpreads.get(node); if (!spreads) { spreads = []; @@ -106,7 +106,7 @@ export class ASTValidationContext { getRecursivelyReferencedFragments( operation: OperationDefinitionNode, - ): $ReadOnlyArray { + ): ReadonlyArray { let fragments = this._recursivelyReferencedFragments.get(operation); if (!fragments) { fragments = []; @@ -132,34 +132,34 @@ export class ASTValidationContext { } } -export type ASTValidationRule = (ASTValidationContext) => ASTVisitor; +export type ASTValidationRule = (arg0: ASTValidationContext) => ASTVisitor; export class SDLValidationContext extends ASTValidationContext { - _schema: ?GraphQLSchema; + _schema: GraphQLSchema | null | undefined; constructor( ast: DocumentNode, - schema: ?GraphQLSchema, + schema: GraphQLSchema | null | undefined, onError: (err: GraphQLError) => void, - ): void { + ) { super(ast, onError); this._schema = schema; } - getSchema(): ?GraphQLSchema { + getSchema(): GraphQLSchema | null | undefined { return this._schema; } } -export type SDLValidationRule = (SDLValidationContext) => ASTVisitor; +export type SDLValidationRule = (arg0: SDLValidationContext) => ASTVisitor; export class ValidationContext extends ASTValidationContext { _schema: GraphQLSchema; _typeInfo: TypeInfo; - _variableUsages: Map>; + _variableUsages: Map>; _recursiveVariableUsages: Map< OperationDefinitionNode, - $ReadOnlyArray, + ReadonlyArray >; constructor( @@ -167,7 +167,7 @@ export class ValidationContext extends ASTValidationContext { ast: DocumentNode, typeInfo: TypeInfo, onError: (err: GraphQLError) => void, - ): void { + ) { super(ast, onError); this._schema = schema; this._typeInfo = typeInfo; @@ -179,7 +179,7 @@ export class ValidationContext extends ASTValidationContext { return this._schema; } - getVariableUsages(node: NodeWithSelectionSet): $ReadOnlyArray { + getVariableUsages(node: NodeWithSelectionSet): ReadonlyArray { let usages = this._variableUsages.get(node); if (!usages) { const newUsages = []; @@ -205,7 +205,7 @@ export class ValidationContext extends ASTValidationContext { getRecursiveVariableUsages( operation: OperationDefinitionNode, - ): $ReadOnlyArray { + ): ReadonlyArray { let usages = this._recursiveVariableUsages.get(operation); if (!usages) { usages = this.getVariableUsages(operation); @@ -217,37 +217,37 @@ export class ValidationContext extends ASTValidationContext { return usages; } - getType(): ?GraphQLOutputType { + getType(): GraphQLOutputType | null | undefined { return this._typeInfo.getType(); } - getParentType(): ?GraphQLCompositeType { + getParentType(): GraphQLCompositeType | null | undefined { return this._typeInfo.getParentType(); } - getInputType(): ?GraphQLInputType { + getInputType(): GraphQLInputType | null | undefined { return this._typeInfo.getInputType(); } - getParentInputType(): ?GraphQLInputType { + getParentInputType(): GraphQLInputType | null | undefined { return this._typeInfo.getParentInputType(); } - getFieldDef(): ?GraphQLField { + getFieldDef(): GraphQLField | null | undefined { return this._typeInfo.getFieldDef(); } - getDirective(): ?GraphQLDirective { + getDirective(): GraphQLDirective | null | undefined { return this._typeInfo.getDirective(); } - getArgument(): ?GraphQLArgument { + getArgument(): GraphQLArgument | null | undefined { return this._typeInfo.getArgument(); } - getEnumValue(): ?GraphQLEnumValue { + getEnumValue(): GraphQLEnumValue | null | undefined { return this._typeInfo.getEnumValue(); } } -export type ValidationRule = (ValidationContext) => ASTVisitor; +export type ValidationRule = (arg0: ValidationContext) => ASTVisitor; diff --git a/src/validation/__tests__/ExecutableDefinitionsRule-test.js b/src/validation/__tests__/ExecutableDefinitionsRule-test.ts similarity index 100% rename from src/validation/__tests__/ExecutableDefinitionsRule-test.js rename to src/validation/__tests__/ExecutableDefinitionsRule-test.ts diff --git a/src/validation/__tests__/FieldsOnCorrectTypeRule-test.js b/src/validation/__tests__/FieldsOnCorrectTypeRule-test.ts similarity index 99% rename from src/validation/__tests__/FieldsOnCorrectTypeRule-test.js rename to src/validation/__tests__/FieldsOnCorrectTypeRule-test.ts index 6ec857a683..6ea5893e55 100644 --- a/src/validation/__tests__/FieldsOnCorrectTypeRule-test.js +++ b/src/validation/__tests__/FieldsOnCorrectTypeRule-test.ts @@ -3,7 +3,7 @@ import { describe, it } from 'mocha'; import { parse } from '../../language/parser'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/FragmentsOnCompositeTypesRule-test.js b/src/validation/__tests__/FragmentsOnCompositeTypesRule-test.ts similarity index 100% rename from src/validation/__tests__/FragmentsOnCompositeTypesRule-test.js rename to src/validation/__tests__/FragmentsOnCompositeTypesRule-test.ts diff --git a/src/validation/__tests__/KnownArgumentNamesRule-test.js b/src/validation/__tests__/KnownArgumentNamesRule-test.ts similarity index 99% rename from src/validation/__tests__/KnownArgumentNamesRule-test.js rename to src/validation/__tests__/KnownArgumentNamesRule-test.ts index 8bf7567c50..3ba96e7b49 100644 --- a/src/validation/__tests__/KnownArgumentNamesRule-test.js +++ b/src/validation/__tests__/KnownArgumentNamesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/KnownDirectivesRule-test.js b/src/validation/__tests__/KnownDirectivesRule-test.ts similarity index 99% rename from src/validation/__tests__/KnownDirectivesRule-test.js rename to src/validation/__tests__/KnownDirectivesRule-test.ts index 13491bc6c5..8af53915b5 100644 --- a/src/validation/__tests__/KnownDirectivesRule-test.js +++ b/src/validation/__tests__/KnownDirectivesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/KnownFragmentNamesRule-test.js b/src/validation/__tests__/KnownFragmentNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/KnownFragmentNamesRule-test.js rename to src/validation/__tests__/KnownFragmentNamesRule-test.ts diff --git a/src/validation/__tests__/KnownTypeNamesRule-test.js b/src/validation/__tests__/KnownTypeNamesRule-test.ts similarity index 99% rename from src/validation/__tests__/KnownTypeNamesRule-test.js rename to src/validation/__tests__/KnownTypeNamesRule-test.ts index f56ef4ceab..2488570925 100644 --- a/src/validation/__tests__/KnownTypeNamesRule-test.js +++ b/src/validation/__tests__/KnownTypeNamesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/LoneAnonymousOperationRule-test.js b/src/validation/__tests__/LoneAnonymousOperationRule-test.ts similarity index 100% rename from src/validation/__tests__/LoneAnonymousOperationRule-test.js rename to src/validation/__tests__/LoneAnonymousOperationRule-test.ts diff --git a/src/validation/__tests__/LoneSchemaDefinitionRule-test.js b/src/validation/__tests__/LoneSchemaDefinitionRule-test.ts similarity index 98% rename from src/validation/__tests__/LoneSchemaDefinitionRule-test.js rename to src/validation/__tests__/LoneSchemaDefinitionRule-test.ts index 6e040576b2..caedbca92b 100644 --- a/src/validation/__tests__/LoneSchemaDefinitionRule-test.js +++ b/src/validation/__tests__/LoneSchemaDefinitionRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/NoDeprecatedCustomRule-test.js b/src/validation/__tests__/NoDeprecatedCustomRule-test.ts similarity index 100% rename from src/validation/__tests__/NoDeprecatedCustomRule-test.js rename to src/validation/__tests__/NoDeprecatedCustomRule-test.ts diff --git a/src/validation/__tests__/NoFragmentCyclesRule-test.js b/src/validation/__tests__/NoFragmentCyclesRule-test.ts similarity index 100% rename from src/validation/__tests__/NoFragmentCyclesRule-test.js rename to src/validation/__tests__/NoFragmentCyclesRule-test.ts diff --git a/src/validation/__tests__/NoSchemaIntrospectionCustomRule-test.js b/src/validation/__tests__/NoSchemaIntrospectionCustomRule-test.ts similarity index 100% rename from src/validation/__tests__/NoSchemaIntrospectionCustomRule-test.js rename to src/validation/__tests__/NoSchemaIntrospectionCustomRule-test.ts diff --git a/src/validation/__tests__/NoUndefinedVariablesRule-test.js b/src/validation/__tests__/NoUndefinedVariablesRule-test.ts similarity index 100% rename from src/validation/__tests__/NoUndefinedVariablesRule-test.js rename to src/validation/__tests__/NoUndefinedVariablesRule-test.ts diff --git a/src/validation/__tests__/NoUnusedFragmentsRule-test.js b/src/validation/__tests__/NoUnusedFragmentsRule-test.ts similarity index 100% rename from src/validation/__tests__/NoUnusedFragmentsRule-test.js rename to src/validation/__tests__/NoUnusedFragmentsRule-test.ts diff --git a/src/validation/__tests__/NoUnusedVariablesRule-test.js b/src/validation/__tests__/NoUnusedVariablesRule-test.ts similarity index 100% rename from src/validation/__tests__/NoUnusedVariablesRule-test.js rename to src/validation/__tests__/NoUnusedVariablesRule-test.ts diff --git a/src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.js b/src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.ts similarity index 99% rename from src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.js rename to src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.ts index 080f859b89..309e098c51 100644 --- a/src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.js +++ b/src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/PossibleFragmentSpreadsRule-test.js b/src/validation/__tests__/PossibleFragmentSpreadsRule-test.ts similarity index 100% rename from src/validation/__tests__/PossibleFragmentSpreadsRule-test.js rename to src/validation/__tests__/PossibleFragmentSpreadsRule-test.ts diff --git a/src/validation/__tests__/PossibleTypeExtensionsRule-test.js b/src/validation/__tests__/PossibleTypeExtensionsRule-test.ts similarity index 99% rename from src/validation/__tests__/PossibleTypeExtensionsRule-test.js rename to src/validation/__tests__/PossibleTypeExtensionsRule-test.ts index 932f7ccef6..4f1e488c76 100644 --- a/src/validation/__tests__/PossibleTypeExtensionsRule-test.js +++ b/src/validation/__tests__/PossibleTypeExtensionsRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.js b/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts similarity index 99% rename from src/validation/__tests__/ProvidedRequiredArgumentsRule-test.js rename to src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts index 7976f46bd2..5803027ddc 100644 --- a/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.js +++ b/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/ScalarLeafsRule-test.js b/src/validation/__tests__/ScalarLeafsRule-test.ts similarity index 100% rename from src/validation/__tests__/ScalarLeafsRule-test.js rename to src/validation/__tests__/ScalarLeafsRule-test.ts diff --git a/src/validation/__tests__/SingleFieldSubscriptionsRule-test.js b/src/validation/__tests__/SingleFieldSubscriptionsRule-test.ts similarity index 100% rename from src/validation/__tests__/SingleFieldSubscriptionsRule-test.js rename to src/validation/__tests__/SingleFieldSubscriptionsRule-test.ts diff --git a/src/validation/__tests__/UniqueArgumentNamesRule-test.js b/src/validation/__tests__/UniqueArgumentNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueArgumentNamesRule-test.js rename to src/validation/__tests__/UniqueArgumentNamesRule-test.ts diff --git a/src/validation/__tests__/UniqueDirectiveNamesRule-test.js b/src/validation/__tests__/UniqueDirectiveNamesRule-test.ts similarity index 97% rename from src/validation/__tests__/UniqueDirectiveNamesRule-test.js rename to src/validation/__tests__/UniqueDirectiveNamesRule-test.ts index 5e898998ed..d8737a8498 100644 --- a/src/validation/__tests__/UniqueDirectiveNamesRule-test.js +++ b/src/validation/__tests__/UniqueDirectiveNamesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/UniqueDirectivesPerLocationRule-test.js b/src/validation/__tests__/UniqueDirectivesPerLocationRule-test.ts similarity index 99% rename from src/validation/__tests__/UniqueDirectivesPerLocationRule-test.js rename to src/validation/__tests__/UniqueDirectivesPerLocationRule-test.ts index 79a7522419..87d45da44e 100644 --- a/src/validation/__tests__/UniqueDirectivesPerLocationRule-test.js +++ b/src/validation/__tests__/UniqueDirectivesPerLocationRule-test.ts @@ -2,7 +2,7 @@ import { describe, it } from 'mocha'; import { parse } from '../../language/parser'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { extendSchema } from '../../utilities/extendSchema'; diff --git a/src/validation/__tests__/UniqueEnumValueNamesRule-test.js b/src/validation/__tests__/UniqueEnumValueNamesRule-test.ts similarity index 98% rename from src/validation/__tests__/UniqueEnumValueNamesRule-test.js rename to src/validation/__tests__/UniqueEnumValueNamesRule-test.ts index a97ac3b687..e4d08a4649 100644 --- a/src/validation/__tests__/UniqueEnumValueNamesRule-test.js +++ b/src/validation/__tests__/UniqueEnumValueNamesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.js b/src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.ts similarity index 99% rename from src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.js rename to src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.ts index c27182d1ac..e678b6a57f 100644 --- a/src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.js +++ b/src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/UniqueFragmentNamesRule-test.js b/src/validation/__tests__/UniqueFragmentNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueFragmentNamesRule-test.js rename to src/validation/__tests__/UniqueFragmentNamesRule-test.ts diff --git a/src/validation/__tests__/UniqueInputFieldNamesRule-test.js b/src/validation/__tests__/UniqueInputFieldNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueInputFieldNamesRule-test.js rename to src/validation/__tests__/UniqueInputFieldNamesRule-test.ts diff --git a/src/validation/__tests__/UniqueOperationNamesRule-test.js b/src/validation/__tests__/UniqueOperationNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueOperationNamesRule-test.js rename to src/validation/__tests__/UniqueOperationNamesRule-test.ts diff --git a/src/validation/__tests__/UniqueOperationTypesRule-test.js b/src/validation/__tests__/UniqueOperationTypesRule-test.ts similarity index 99% rename from src/validation/__tests__/UniqueOperationTypesRule-test.js rename to src/validation/__tests__/UniqueOperationTypesRule-test.ts index fd73040c44..e5fecfe3fb 100644 --- a/src/validation/__tests__/UniqueOperationTypesRule-test.js +++ b/src/validation/__tests__/UniqueOperationTypesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/UniqueTypeNamesRule-test.js b/src/validation/__tests__/UniqueTypeNamesRule-test.ts similarity index 98% rename from src/validation/__tests__/UniqueTypeNamesRule-test.js rename to src/validation/__tests__/UniqueTypeNamesRule-test.ts index 6525275e92..884decbdc9 100644 --- a/src/validation/__tests__/UniqueTypeNamesRule-test.js +++ b/src/validation/__tests__/UniqueTypeNamesRule-test.ts @@ -1,6 +1,6 @@ import { describe, it } from 'mocha'; -import type { GraphQLSchema } from '../../type/schema'; +import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; diff --git a/src/validation/__tests__/UniqueVariableNamesRule-test.js b/src/validation/__tests__/UniqueVariableNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueVariableNamesRule-test.js rename to src/validation/__tests__/UniqueVariableNamesRule-test.ts diff --git a/src/validation/__tests__/ValuesOfCorrectTypeRule-test.js b/src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts similarity index 100% rename from src/validation/__tests__/ValuesOfCorrectTypeRule-test.js rename to src/validation/__tests__/ValuesOfCorrectTypeRule-test.ts diff --git a/src/validation/__tests__/VariablesAreInputTypesRule-test.js b/src/validation/__tests__/VariablesAreInputTypesRule-test.ts similarity index 100% rename from src/validation/__tests__/VariablesAreInputTypesRule-test.js rename to src/validation/__tests__/VariablesAreInputTypesRule-test.ts diff --git a/src/validation/__tests__/VariablesInAllowedPositionRule-test.js b/src/validation/__tests__/VariablesInAllowedPositionRule-test.ts similarity index 100% rename from src/validation/__tests__/VariablesInAllowedPositionRule-test.js rename to src/validation/__tests__/VariablesInAllowedPositionRule-test.ts diff --git a/src/validation/__tests__/harness.js b/src/validation/__tests__/harness.ts similarity index 97% rename from src/validation/__tests__/harness.js rename to src/validation/__tests__/harness.ts index 99683412d8..021d73be35 100644 --- a/src/validation/__tests__/harness.js +++ b/src/validation/__tests__/harness.ts @@ -7,7 +7,7 @@ import { GraphQLSchema } from '../../type/schema'; import { buildSchema } from '../../utilities/buildASTSchema'; import { validate, validateSDL } from '../validate'; -import type { ValidationRule, SDLValidationRule } from '../ValidationContext'; +import { ValidationRule, SDLValidationRule } from '../ValidationContext'; export const testSchema = buildSchema(` interface Being { @@ -160,7 +160,7 @@ export function expectValidationErrors( } export function expectSDLValidationErrors( - schema: ?GraphQLSchema, + schema: GraphQLSchema | null | undefined, rule: SDLValidationRule, sdlStr: string, ): any { diff --git a/src/validation/__tests__/validation-test.js b/src/validation/__tests__/validation-test.ts similarity index 97% rename from src/validation/__tests__/validation-test.js rename to src/validation/__tests__/validation-test.ts index b1113d2d01..dfe2be28a0 100644 --- a/src/validation/__tests__/validation-test.js +++ b/src/validation/__tests__/validation-test.ts @@ -8,7 +8,7 @@ import { parse } from '../../language/parser'; import { TypeInfo } from '../../utilities/TypeInfo'; import { buildSchema } from '../../utilities/buildASTSchema'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; import { validate } from '../validate'; import { testSchema } from './harness'; @@ -129,7 +129,7 @@ describe('Validate: Limit maximum number of validation errors', () => { `; const doc = parse(query, { noLocation: true }); - function validateDocument(options: {| maxErrors?: number |}) { + function validateDocument(options: { maxErrors?: number }) { return validate(testSchema, doc, undefined, undefined, options); } diff --git a/src/validation/index.js b/src/validation/index.ts similarity index 98% rename from src/validation/index.js rename to src/validation/index.ts index c0f24a0316..a5c806a574 100644 --- a/src/validation/index.js +++ b/src/validation/index.ts @@ -1,7 +1,7 @@ export { validate } from './validate'; export { ValidationContext } from './ValidationContext'; -export type { ValidationRule } from './ValidationContext'; +export { ValidationRule } from './ValidationContext'; // All validation rules in the GraphQL Specification. export { specifiedRules } from './specifiedRules'; diff --git a/src/validation/rules/ExecutableDefinitionsRule.js b/src/validation/rules/ExecutableDefinitionsRule.ts similarity index 89% rename from src/validation/rules/ExecutableDefinitionsRule.js rename to src/validation/rules/ExecutableDefinitionsRule.ts index c446e000e1..d1f3a81052 100644 --- a/src/validation/rules/ExecutableDefinitionsRule.js +++ b/src/validation/rules/ExecutableDefinitionsRule.ts @@ -1,10 +1,10 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; import { Kind } from '../../language/kinds'; import { isExecutableDefinitionNode } from '../../language/predicates'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Executable definitions diff --git a/src/validation/rules/FieldsOnCorrectTypeRule.js b/src/validation/rules/FieldsOnCorrectTypeRule.ts similarity index 93% rename from src/validation/rules/FieldsOnCorrectTypeRule.js rename to src/validation/rules/FieldsOnCorrectTypeRule.ts index 734667028a..eb60453c8e 100644 --- a/src/validation/rules/FieldsOnCorrectTypeRule.js +++ b/src/validation/rules/FieldsOnCorrectTypeRule.ts @@ -3,11 +3,11 @@ import suggestionList from '../../jsutils/suggestionList'; import { GraphQLError } from '../../error/GraphQLError'; -import type { FieldNode } from '../../language/ast'; -import type { ASTVisitor } from '../../language/visitor'; +import { FieldNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; -import type { GraphQLSchema } from '../../type/schema'; -import type { +import { GraphQLSchema } from '../../type/schema'; +import { GraphQLOutputType, GraphQLObjectType, GraphQLInterfaceType, @@ -18,7 +18,7 @@ import { isAbstractType, } from '../../type/definition'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Fields on correct type @@ -80,7 +80,7 @@ function getSuggestedTypeNames( } const suggestedTypes: Set< - GraphQLObjectType | GraphQLInterfaceType, + GraphQLObjectType | GraphQLInterfaceType > = new Set(); const usageCount = Object.create(null); for (const possibleType of schema.getPossibleTypes(type)) { diff --git a/src/validation/rules/FragmentsOnCompositeTypesRule.js b/src/validation/rules/FragmentsOnCompositeTypesRule.ts similarity index 92% rename from src/validation/rules/FragmentsOnCompositeTypesRule.js rename to src/validation/rules/FragmentsOnCompositeTypesRule.ts index 75f49158c7..1fa4b1595d 100644 --- a/src/validation/rules/FragmentsOnCompositeTypesRule.js +++ b/src/validation/rules/FragmentsOnCompositeTypesRule.ts @@ -1,13 +1,13 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; import { print } from '../../language/printer'; import { isCompositeType } from '../../type/definition'; import { typeFromAST } from '../../utilities/typeFromAST'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Fragments on composite type diff --git a/src/validation/rules/KnownArgumentNamesRule.js b/src/validation/rules/KnownArgumentNamesRule.ts similarity index 94% rename from src/validation/rules/KnownArgumentNamesRule.js rename to src/validation/rules/KnownArgumentNamesRule.ts index b1fd082463..de9c3641e5 100644 --- a/src/validation/rules/KnownArgumentNamesRule.js +++ b/src/validation/rules/KnownArgumentNamesRule.ts @@ -3,15 +3,12 @@ import suggestionList from '../../jsutils/suggestionList'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; import { Kind } from '../../language/kinds'; import { specifiedDirectives } from '../../type/directives'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; +import { ValidationContext, SDLValidationContext } from '../ValidationContext'; /** * Known argument names diff --git a/src/validation/rules/KnownDirectivesRule.js b/src/validation/rules/KnownDirectivesRule.ts similarity index 90% rename from src/validation/rules/KnownDirectivesRule.js rename to src/validation/rules/KnownDirectivesRule.ts index 8c2e60de88..ce7babe5e6 100644 --- a/src/validation/rules/KnownDirectivesRule.js +++ b/src/validation/rules/KnownDirectivesRule.ts @@ -3,18 +3,15 @@ import invariant from '../../jsutils/invariant'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTNode, OperationTypeNode } from '../../language/ast'; -import type { DirectiveLocationEnum } from '../../language/directiveLocation'; +import { ASTVisitor } from '../../language/visitor'; +import { ASTNode, OperationTypeNode } from '../../language/ast'; +import { DirectiveLocationEnum } from '../../language/directiveLocation'; import { Kind } from '../../language/kinds'; import { DirectiveLocation } from '../../language/directiveLocation'; import { specifiedDirectives } from '../../type/directives'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; +import { ValidationContext, SDLValidationContext } from '../ValidationContext'; /** * Known directives @@ -68,7 +65,7 @@ export function KnownDirectivesRule( } function getDirectiveLocationForASTPath( - ancestors: $ReadOnlyArray>, + ancestors: ReadonlyArray>, ): DirectiveLocationEnum | void { const appliedTo = ancestors[ancestors.length - 1]; invariant(!Array.isArray(appliedTo)); @@ -133,5 +130,5 @@ function getDirectiveLocationForOperation( } // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false, 'Unexpected operation: ' + inspect((operation: empty))); + invariant(false, 'Unexpected operation: ' + inspect(operation as never)); } diff --git a/src/validation/rules/KnownFragmentNamesRule.js b/src/validation/rules/KnownFragmentNamesRule.ts similarity index 83% rename from src/validation/rules/KnownFragmentNamesRule.js rename to src/validation/rules/KnownFragmentNamesRule.ts index 0f3412bb45..f059523479 100644 --- a/src/validation/rules/KnownFragmentNamesRule.js +++ b/src/validation/rules/KnownFragmentNamesRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Known fragment names diff --git a/src/validation/rules/KnownTypeNamesRule.js b/src/validation/rules/KnownTypeNamesRule.ts similarity index 88% rename from src/validation/rules/KnownTypeNamesRule.js rename to src/validation/rules/KnownTypeNamesRule.ts index 38efd5a603..214bbccf69 100644 --- a/src/validation/rules/KnownTypeNamesRule.js +++ b/src/validation/rules/KnownTypeNamesRule.ts @@ -3,8 +3,8 @@ import suggestionList from '../../jsutils/suggestionList'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTNode } from '../../language/ast'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; import { isTypeDefinitionNode, isTypeSystemDefinitionNode, @@ -14,10 +14,7 @@ import { import { specifiedScalarTypes } from '../../type/scalars'; import { introspectionTypes } from '../../type/introspection'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; +import { ValidationContext, SDLValidationContext } from '../ValidationContext'; /** * Known type names @@ -75,7 +72,7 @@ function isStandardTypeName(typeName: string): boolean { return standardTypeNames.indexOf(typeName) !== -1; } -function isSDLNode(value: ASTNode | $ReadOnlyArray): boolean { +function isSDLNode(value: ASTNode | ReadonlyArray): boolean { return ( !Array.isArray(value) && (isTypeSystemDefinitionNode(value) || isTypeSystemExtensionNode(value)) diff --git a/src/validation/rules/LoneAnonymousOperationRule.js b/src/validation/rules/LoneAnonymousOperationRule.ts similarity index 87% rename from src/validation/rules/LoneAnonymousOperationRule.js rename to src/validation/rules/LoneAnonymousOperationRule.ts index 617c80639f..0178bc48eb 100644 --- a/src/validation/rules/LoneAnonymousOperationRule.js +++ b/src/validation/rules/LoneAnonymousOperationRule.ts @@ -1,9 +1,9 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; import { Kind } from '../../language/kinds'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Lone anonymous operation diff --git a/src/validation/rules/LoneSchemaDefinitionRule.js b/src/validation/rules/LoneSchemaDefinitionRule.ts similarity index 88% rename from src/validation/rules/LoneSchemaDefinitionRule.js rename to src/validation/rules/LoneSchemaDefinitionRule.ts index 1c2b02371e..9652caf6a6 100644 --- a/src/validation/rules/LoneSchemaDefinitionRule.js +++ b/src/validation/rules/LoneSchemaDefinitionRule.ts @@ -1,7 +1,7 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Lone Schema definition diff --git a/src/validation/rules/NoFragmentCyclesRule.js b/src/validation/rules/NoFragmentCyclesRule.ts similarity index 91% rename from src/validation/rules/NoFragmentCyclesRule.js rename to src/validation/rules/NoFragmentCyclesRule.ts index 54fba26e43..628a540667 100644 --- a/src/validation/rules/NoFragmentCyclesRule.js +++ b/src/validation/rules/NoFragmentCyclesRule.ts @@ -1,9 +1,9 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { FragmentDefinitionNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { FragmentDefinitionNode } from '../../language/ast'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; export function NoFragmentCyclesRule( context: ASTValidationContext, diff --git a/src/validation/rules/NoUndefinedVariablesRule.js b/src/validation/rules/NoUndefinedVariablesRule.ts similarity index 90% rename from src/validation/rules/NoUndefinedVariablesRule.js rename to src/validation/rules/NoUndefinedVariablesRule.ts index de1a84807f..10c4d765e7 100644 --- a/src/validation/rules/NoUndefinedVariablesRule.js +++ b/src/validation/rules/NoUndefinedVariablesRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * No undefined variables diff --git a/src/validation/rules/NoUnusedFragmentsRule.js b/src/validation/rules/NoUnusedFragmentsRule.ts similarity index 91% rename from src/validation/rules/NoUnusedFragmentsRule.js rename to src/validation/rules/NoUnusedFragmentsRule.ts index d69bf241cf..f3854e02a2 100644 --- a/src/validation/rules/NoUnusedFragmentsRule.js +++ b/src/validation/rules/NoUnusedFragmentsRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * No unused fragments diff --git a/src/validation/rules/NoUnusedVariablesRule.js b/src/validation/rules/NoUnusedVariablesRule.ts similarity index 91% rename from src/validation/rules/NoUnusedVariablesRule.js rename to src/validation/rules/NoUnusedVariablesRule.ts index 70bc81c941..dc368d72bc 100644 --- a/src/validation/rules/NoUnusedVariablesRule.js +++ b/src/validation/rules/NoUnusedVariablesRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * No unused variables diff --git a/src/validation/rules/OverlappingFieldsCanBeMergedRule.js b/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts similarity index 97% rename from src/validation/rules/OverlappingFieldsCanBeMergedRule.js rename to src/validation/rules/OverlappingFieldsCanBeMergedRule.ts index 983f69099d..e74b2b7bd9 100644 --- a/src/validation/rules/OverlappingFieldsCanBeMergedRule.js +++ b/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts @@ -1,12 +1,12 @@ import objectEntries from '../../polyfills/objectEntries'; -import type { ObjMap } from '../../jsutils/ObjMap'; +import { ObjMap } from '../../jsutils/ObjMap'; import inspect from '../../jsutils/inspect'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { +import { ASTVisitor } from '../../language/visitor'; +import { SelectionSetNode, ValueNode, FieldNode, @@ -16,7 +16,7 @@ import type { import { Kind } from '../../language/kinds'; import { print } from '../../language/printer'; -import type { +import { GraphQLNamedType, GraphQLOutputType, GraphQLCompositeType, @@ -33,7 +33,7 @@ import { import { typeFromAST } from '../../utilities/typeFromAST'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; function reasonMessage(reason: ConflictReasonMessage): string { if (Array.isArray(reason)) { @@ -99,7 +99,7 @@ type ConflictReasonMessage = string | Array; type NodeAndDef = [ GraphQLCompositeType, FieldNode, - ?GraphQLField, + GraphQLField | null | undefined, ]; // Map of array of those. type NodeAndDefCollection = ObjMap>; @@ -158,7 +158,6 @@ type NodeAndDefCollection = ObjMap>; * comparison is made "between" the two fragments. * */ - // Find all conflicts found "within" a selection set, including those found // via spreading in fragments. Called when visiting each SelectionSet in the // GraphQL Document. @@ -166,7 +165,7 @@ function findConflictsWithinSelectionSet( context: ValidationContext, cachedFieldsAndFragmentNames, comparedFragmentPairs: PairSet, - parentType: ?GraphQLNamedType, + parentType: GraphQLNamedType | null | undefined, selectionSet: SelectionSetNode, ): Array { const conflicts = []; @@ -369,9 +368,9 @@ function findConflictsBetweenSubSelectionSets( cachedFieldsAndFragmentNames, comparedFragmentPairs: PairSet, areMutuallyExclusive: boolean, - parentType1: ?GraphQLNamedType, + parentType1: GraphQLNamedType | null | undefined, selectionSet1: SelectionSetNode, - parentType2: ?GraphQLNamedType, + parentType2: GraphQLNamedType | null | undefined, selectionSet2: SelectionSetNode, ): Array { const conflicts = []; @@ -541,7 +540,7 @@ function findConflict( responseName: string, field1: NodeAndDef, field2: NodeAndDef, -): ?Conflict { +): Conflict | null | undefined { const [parentType1, node1, def1] = field1; const [parentType2, node2, def2] = field2; @@ -623,8 +622,8 @@ function findConflict( } function sameArguments( - arguments1: $ReadOnlyArray, - arguments2: $ReadOnlyArray, + arguments1: ReadonlyArray, + arguments2: ReadonlyArray, ): boolean { if (arguments1.length !== arguments2.length) { return false; @@ -679,7 +678,7 @@ function doTypesConflict( function getFieldsAndFragmentNames( context: ValidationContext, cachedFieldsAndFragmentNames, - parentType: ?GraphQLNamedType, + parentType: GraphQLNamedType | null | undefined, selectionSet: SelectionSetNode, ): [NodeAndDefCollection, Array] { let cached = cachedFieldsAndFragmentNames.get(selectionSet); @@ -723,7 +722,7 @@ function getReferencedFieldsAndFragmentNames( function _collectFieldsAndFragmentNames( context: ValidationContext, - parentType: ?GraphQLNamedType, + parentType: GraphQLNamedType | null | undefined, selectionSet: SelectionSetNode, nodeAndDefs, fragmentNames, @@ -769,11 +768,11 @@ function _collectFieldsAndFragmentNames( // Given a series of Conflicts which occurred between two sub-fields, generate // a single Conflict. function subfieldConflicts( - conflicts: $ReadOnlyArray, + conflicts: ReadonlyArray, responseName: string, node1: FieldNode, node2: FieldNode, -): ?Conflict { +): Conflict | null | undefined { if (conflicts.length > 0) { return [ [responseName, conflicts.map(([reason]) => reason)], diff --git a/src/validation/rules/PossibleFragmentSpreadsRule.js b/src/validation/rules/PossibleFragmentSpreadsRule.ts similarity index 90% rename from src/validation/rules/PossibleFragmentSpreadsRule.js rename to src/validation/rules/PossibleFragmentSpreadsRule.ts index ba4e9ca5ef..8995a43180 100644 --- a/src/validation/rules/PossibleFragmentSpreadsRule.js +++ b/src/validation/rules/PossibleFragmentSpreadsRule.ts @@ -2,15 +2,15 @@ import inspect from '../../jsutils/inspect'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { GraphQLCompositeType } from '../../type/definition'; +import { GraphQLCompositeType } from '../../type/definition'; import { isCompositeType } from '../../type/definition'; import { typeFromAST } from '../../utilities/typeFromAST'; import { doTypesOverlap } from '../../utilities/typeComparators'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Possible fragment spread @@ -66,7 +66,7 @@ export function PossibleFragmentSpreadsRule( function getFragmentType( context: ValidationContext, name: string, -): ?GraphQLCompositeType { +): GraphQLCompositeType | null | undefined { const frag = context.getFragment(name); if (frag) { const type = typeFromAST(context.getSchema(), frag.typeCondition); diff --git a/src/validation/rules/PossibleTypeExtensionsRule.js b/src/validation/rules/PossibleTypeExtensionsRule.ts similarity index 91% rename from src/validation/rules/PossibleTypeExtensionsRule.js rename to src/validation/rules/PossibleTypeExtensionsRule.ts index 2f098191ef..eb1dfc663c 100644 --- a/src/validation/rules/PossibleTypeExtensionsRule.js +++ b/src/validation/rules/PossibleTypeExtensionsRule.ts @@ -5,13 +5,13 @@ import suggestionList from '../../jsutils/suggestionList'; import { GraphQLError } from '../../error/GraphQLError'; -import type { KindEnum } from '../../language/kinds'; -import type { ASTVisitor } from '../../language/visitor'; -import type { TypeExtensionNode } from '../../language/ast'; +import { KindEnum } from '../../language/kinds'; +import { ASTVisitor } from '../../language/visitor'; +import { TypeExtensionNode } from '../../language/ast'; import { Kind } from '../../language/kinds'; import { isTypeDefinitionNode } from '../../language/predicates'; -import type { GraphQLNamedType } from '../../type/definition'; +import { GraphQLNamedType } from '../../type/definition'; import { isScalarType, isObjectType, @@ -21,7 +21,7 @@ import { isInputObjectType, } from '../../type/definition'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Possible type extension @@ -120,7 +120,7 @@ function typeToExtKind(type: GraphQLNamedType): KindEnum { } // istanbul ignore next (Not reachable. All possible types have been considered) - invariant(false, 'Unexpected type: ' + inspect((type: empty))); + invariant(false, 'Unexpected type: ' + inspect(type as never)); } function extensionKindToTypeName(kind: KindEnum): string { diff --git a/src/validation/rules/ProvidedRequiredArgumentsRule.js b/src/validation/rules/ProvidedRequiredArgumentsRule.ts similarity index 94% rename from src/validation/rules/ProvidedRequiredArgumentsRule.js rename to src/validation/rules/ProvidedRequiredArgumentsRule.ts index b9ff7a032b..f516f1015d 100644 --- a/src/validation/rules/ProvidedRequiredArgumentsRule.js +++ b/src/validation/rules/ProvidedRequiredArgumentsRule.ts @@ -3,18 +3,15 @@ import keyMap from '../../jsutils/keyMap'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { InputValueDefinitionNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { InputValueDefinitionNode } from '../../language/ast'; import { Kind } from '../../language/kinds'; import { print } from '../../language/printer'; import { specifiedDirectives } from '../../type/directives'; import { isType, isRequiredArgument } from '../../type/definition'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; +import { ValidationContext, SDLValidationContext } from '../ValidationContext'; /** * Provided required arguments diff --git a/src/validation/rules/ScalarLeafsRule.js b/src/validation/rules/ScalarLeafsRule.ts similarity index 88% rename from src/validation/rules/ScalarLeafsRule.js rename to src/validation/rules/ScalarLeafsRule.ts index a0c0c6cc40..7dfec23839 100644 --- a/src/validation/rules/ScalarLeafsRule.js +++ b/src/validation/rules/ScalarLeafsRule.ts @@ -2,12 +2,12 @@ import inspect from '../../jsutils/inspect'; import { GraphQLError } from '../../error/GraphQLError'; -import type { FieldNode } from '../../language/ast'; -import type { ASTVisitor } from '../../language/visitor'; +import { FieldNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; import { getNamedType, isLeafType } from '../../type/definition'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Scalar leafs diff --git a/src/validation/rules/SingleFieldSubscriptionsRule.js b/src/validation/rules/SingleFieldSubscriptionsRule.ts similarity index 81% rename from src/validation/rules/SingleFieldSubscriptionsRule.js rename to src/validation/rules/SingleFieldSubscriptionsRule.ts index 760fe3c144..b427c76ee5 100644 --- a/src/validation/rules/SingleFieldSubscriptionsRule.js +++ b/src/validation/rules/SingleFieldSubscriptionsRule.ts @@ -1,9 +1,9 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { OperationDefinitionNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { OperationDefinitionNode } from '../../language/ast'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Subscriptions must only include one field. diff --git a/src/validation/rules/UniqueArgumentNamesRule.js b/src/validation/rules/UniqueArgumentNamesRule.ts similarity index 87% rename from src/validation/rules/UniqueArgumentNamesRule.js rename to src/validation/rules/UniqueArgumentNamesRule.ts index 73289efd2f..b88b04b8d1 100644 --- a/src/validation/rules/UniqueArgumentNamesRule.js +++ b/src/validation/rules/UniqueArgumentNamesRule.ts @@ -1,7 +1,7 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Unique argument names diff --git a/src/validation/rules/UniqueDirectiveNamesRule.js b/src/validation/rules/UniqueDirectiveNamesRule.ts similarity index 89% rename from src/validation/rules/UniqueDirectiveNamesRule.js rename to src/validation/rules/UniqueDirectiveNamesRule.ts index 0d87d9deb4..da638630f9 100644 --- a/src/validation/rules/UniqueDirectiveNamesRule.js +++ b/src/validation/rules/UniqueDirectiveNamesRule.ts @@ -1,7 +1,7 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Unique directive names diff --git a/src/validation/rules/UniqueDirectivesPerLocationRule.js b/src/validation/rules/UniqueDirectivesPerLocationRule.ts similarity index 94% rename from src/validation/rules/UniqueDirectivesPerLocationRule.js rename to src/validation/rules/UniqueDirectivesPerLocationRule.ts index a21c081790..8f070468cb 100644 --- a/src/validation/rules/UniqueDirectivesPerLocationRule.js +++ b/src/validation/rules/UniqueDirectivesPerLocationRule.ts @@ -1,7 +1,7 @@ import { GraphQLError } from '../../error/GraphQLError'; import { Kind } from '../../language/kinds'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; import { isTypeDefinitionNode, isTypeExtensionNode, @@ -9,10 +9,7 @@ import { import { specifiedDirectives } from '../../type/directives'; -import type { - SDLValidationContext, - ValidationContext, -} from '../ValidationContext'; +import { SDLValidationContext, ValidationContext } from '../ValidationContext'; /** * Unique directive names per location diff --git a/src/validation/rules/UniqueEnumValueNamesRule.js b/src/validation/rules/UniqueEnumValueNamesRule.ts similarity index 93% rename from src/validation/rules/UniqueEnumValueNamesRule.js rename to src/validation/rules/UniqueEnumValueNamesRule.ts index 28ba114248..20a8547cb5 100644 --- a/src/validation/rules/UniqueEnumValueNamesRule.js +++ b/src/validation/rules/UniqueEnumValueNamesRule.ts @@ -1,14 +1,14 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { +import { ASTVisitor } from '../../language/visitor'; +import { EnumTypeDefinitionNode, EnumTypeExtensionNode, } from '../../language/ast'; import { isEnumType } from '../../type/definition'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Unique enum value names diff --git a/src/validation/rules/UniqueFieldDefinitionNamesRule.js b/src/validation/rules/UniqueFieldDefinitionNamesRule.ts similarity index 88% rename from src/validation/rules/UniqueFieldDefinitionNamesRule.js rename to src/validation/rules/UniqueFieldDefinitionNamesRule.ts index f912a8489f..8f40365460 100644 --- a/src/validation/rules/UniqueFieldDefinitionNamesRule.js +++ b/src/validation/rules/UniqueFieldDefinitionNamesRule.ts @@ -1,20 +1,20 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { +import { ASTVisitor } from '../../language/visitor'; +import { NameNode, FieldDefinitionNode, InputValueDefinitionNode, } from '../../language/ast'; -import type { GraphQLNamedType } from '../../type/definition'; +import { GraphQLNamedType } from '../../type/definition'; import { isObjectType, isInterfaceType, isInputObjectType, } from '../../type/definition'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Unique field definition names @@ -38,9 +38,10 @@ export function UniqueFieldDefinitionNamesRule( }; function checkFieldUniqueness(node: { - +name: NameNode, - +fields?: $ReadOnlyArray, - ... + readonly name: NameNode; + readonly fields?: ReadonlyArray< + InputValueDefinitionNode | FieldDefinitionNode + >; }) { const typeName = node.name.value; diff --git a/src/validation/rules/UniqueFragmentNamesRule.js b/src/validation/rules/UniqueFragmentNamesRule.ts similarity index 86% rename from src/validation/rules/UniqueFragmentNamesRule.js rename to src/validation/rules/UniqueFragmentNamesRule.ts index 144e0e94d5..8af86b0b83 100644 --- a/src/validation/rules/UniqueFragmentNamesRule.js +++ b/src/validation/rules/UniqueFragmentNamesRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Unique fragment names diff --git a/src/validation/rules/UniqueInputFieldNamesRule.js b/src/validation/rules/UniqueInputFieldNamesRule.ts similarity index 88% rename from src/validation/rules/UniqueInputFieldNamesRule.js rename to src/validation/rules/UniqueInputFieldNamesRule.ts index 413783e930..afe105d155 100644 --- a/src/validation/rules/UniqueInputFieldNamesRule.js +++ b/src/validation/rules/UniqueInputFieldNamesRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Unique input field names diff --git a/src/validation/rules/UniqueOperationNamesRule.js b/src/validation/rules/UniqueOperationNamesRule.ts similarity index 87% rename from src/validation/rules/UniqueOperationNamesRule.js rename to src/validation/rules/UniqueOperationNamesRule.ts index 6051e91978..7ad12e8a25 100644 --- a/src/validation/rules/UniqueOperationNamesRule.js +++ b/src/validation/rules/UniqueOperationNamesRule.ts @@ -1,8 +1,8 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; +import { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Unique operation names diff --git a/src/validation/rules/UniqueOperationTypesRule.js b/src/validation/rules/UniqueOperationTypesRule.ts similarity index 88% rename from src/validation/rules/UniqueOperationTypesRule.js rename to src/validation/rules/UniqueOperationTypesRule.ts index 5b0d2b32cf..b953f37347 100644 --- a/src/validation/rules/UniqueOperationTypesRule.js +++ b/src/validation/rules/UniqueOperationTypesRule.ts @@ -1,12 +1,9 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { - SchemaDefinitionNode, - SchemaExtensionNode, -} from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { SchemaDefinitionNode, SchemaExtensionNode } from '../../language/ast'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Unique operation types diff --git a/src/validation/rules/UniqueTypeNamesRule.js b/src/validation/rules/UniqueTypeNamesRule.ts similarity index 87% rename from src/validation/rules/UniqueTypeNamesRule.js rename to src/validation/rules/UniqueTypeNamesRule.ts index fed280c446..11cda5549e 100644 --- a/src/validation/rules/UniqueTypeNamesRule.js +++ b/src/validation/rules/UniqueTypeNamesRule.ts @@ -1,9 +1,9 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { TypeDefinitionNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { TypeDefinitionNode } from '../../language/ast'; -import type { SDLValidationContext } from '../ValidationContext'; +import { SDLValidationContext } from '../ValidationContext'; /** * Unique type names diff --git a/src/validation/rules/UniqueVariableNamesRule.js b/src/validation/rules/UniqueVariableNamesRule.ts similarity index 82% rename from src/validation/rules/UniqueVariableNamesRule.js rename to src/validation/rules/UniqueVariableNamesRule.ts index 6035cdfa3e..e745a46973 100644 --- a/src/validation/rules/UniqueVariableNamesRule.js +++ b/src/validation/rules/UniqueVariableNamesRule.ts @@ -1,9 +1,9 @@ import { GraphQLError } from '../../error/GraphQLError'; -import type { ASTVisitor } from '../../language/visitor'; -import type { VariableDefinitionNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { VariableDefinitionNode } from '../../language/ast'; -import type { ASTValidationContext } from '../ValidationContext'; +import { ASTValidationContext } from '../ValidationContext'; /** * Unique variable names diff --git a/src/validation/rules/ValuesOfCorrectTypeRule.js b/src/validation/rules/ValuesOfCorrectTypeRule.ts similarity index 93% rename from src/validation/rules/ValuesOfCorrectTypeRule.js rename to src/validation/rules/ValuesOfCorrectTypeRule.ts index d97647a000..878fb11fe6 100644 --- a/src/validation/rules/ValuesOfCorrectTypeRule.js +++ b/src/validation/rules/ValuesOfCorrectTypeRule.ts @@ -7,8 +7,8 @@ import suggestionList from '../../jsutils/suggestionList'; import { GraphQLError } from '../../error/GraphQLError'; -import type { ValueNode } from '../../language/ast'; -import type { ASTVisitor } from '../../language/visitor'; +import { ValueNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; import { print } from '../../language/printer'; import { @@ -21,7 +21,7 @@ import { getNamedType, } from '../../type/definition'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Value literals of correct type @@ -126,7 +126,11 @@ function isValidValueNode(context: ValidationContext, node: ValueNode): void { // Scalars and Enums determine if a literal value is valid via parseLiteral(), // which may throw or return an invalid value to indicate failure. try { - const parseResult = type.parseLiteral(node, undefined /* variables */); + const parseResult = type.parseLiteral( + node, + undefined, + /* variables */ + ); if (parseResult === undefined) { const typeStr = inspect(locationType); context.reportError( @@ -149,7 +153,7 @@ function isValidValueNode(context: ValidationContext, node: ValueNode): void { undefined, undefined, undefined, - error, // Ensure a reference to the original error is maintained. + error, ), ); } diff --git a/src/validation/rules/VariablesAreInputTypesRule.js b/src/validation/rules/VariablesAreInputTypesRule.ts similarity index 76% rename from src/validation/rules/VariablesAreInputTypesRule.js rename to src/validation/rules/VariablesAreInputTypesRule.ts index f16cb7461d..52f9d10c6b 100644 --- a/src/validation/rules/VariablesAreInputTypesRule.js +++ b/src/validation/rules/VariablesAreInputTypesRule.ts @@ -1,14 +1,14 @@ import { GraphQLError } from '../../error/GraphQLError'; import { print } from '../../language/printer'; -import type { ASTVisitor } from '../../language/visitor'; -import type { VariableDefinitionNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; +import { VariableDefinitionNode } from '../../language/ast'; import { isInputType } from '../../type/definition'; import { typeFromAST } from '../../utilities/typeFromAST'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Variables are input types @@ -20,7 +20,9 @@ export function VariablesAreInputTypesRule( context: ValidationContext, ): ASTVisitor { return { - VariableDefinition(node: VariableDefinitionNode): ?GraphQLError { + VariableDefinition( + node: VariableDefinitionNode, + ): GraphQLError | null | undefined { const type = typeFromAST(context.getSchema(), node.type); if (type && !isInputType(type)) { diff --git a/src/validation/rules/VariablesInAllowedPositionRule.js b/src/validation/rules/VariablesInAllowedPositionRule.ts similarity index 89% rename from src/validation/rules/VariablesInAllowedPositionRule.js rename to src/validation/rules/VariablesInAllowedPositionRule.ts index 8d0cbbf26c..d30ca70557 100644 --- a/src/validation/rules/VariablesInAllowedPositionRule.js +++ b/src/validation/rules/VariablesInAllowedPositionRule.ts @@ -3,17 +3,17 @@ import inspect from '../../jsutils/inspect'; import { GraphQLError } from '../../error/GraphQLError'; import { Kind } from '../../language/kinds'; -import type { ValueNode } from '../../language/ast'; -import type { ASTVisitor } from '../../language/visitor'; +import { ValueNode } from '../../language/ast'; +import { ASTVisitor } from '../../language/visitor'; -import type { GraphQLSchema } from '../../type/schema'; -import type { GraphQLType } from '../../type/definition'; +import { GraphQLSchema } from '../../type/schema'; +import { GraphQLType } from '../../type/definition'; import { isNonNullType } from '../../type/definition'; import { typeFromAST } from '../../utilities/typeFromAST'; import { isTypeSubTypeOf } from '../../utilities/typeComparators'; -import type { ValidationContext } from '../ValidationContext'; +import { ValidationContext } from '../ValidationContext'; /** * Variables passed to field arguments conform to type @@ -79,9 +79,9 @@ export function VariablesInAllowedPositionRule( function allowedVariableUsage( schema: GraphQLSchema, varType: GraphQLType, - varDefaultValue: ?ValueNode, + varDefaultValue: ValueNode | null | undefined, locationType: GraphQLType, - locationDefaultValue: ?mixed, + locationDefaultValue: unknown | null | undefined, ): boolean { if (isNonNullType(locationType) && !isNonNullType(varType)) { const hasNonNullVariableDefaultValue = diff --git a/src/validation/rules/custom/NoDeprecatedCustomRule.js b/src/validation/rules/custom/NoDeprecatedCustomRule.ts similarity index 96% rename from src/validation/rules/custom/NoDeprecatedCustomRule.js rename to src/validation/rules/custom/NoDeprecatedCustomRule.ts index 7fe6598bc4..2355dbc6f9 100644 --- a/src/validation/rules/custom/NoDeprecatedCustomRule.js +++ b/src/validation/rules/custom/NoDeprecatedCustomRule.ts @@ -2,11 +2,11 @@ import invariant from '../../../jsutils/invariant'; import { GraphQLError } from '../../../error/GraphQLError'; -import type { ASTVisitor } from '../../../language/visitor'; +import { ASTVisitor } from '../../../language/visitor'; import { getNamedType, isInputObjectType } from '../../../type/definition'; -import type { ValidationContext } from '../../ValidationContext'; +import { ValidationContext } from '../../ValidationContext'; /** * No deprecated diff --git a/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.js b/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.ts similarity index 85% rename from src/validation/rules/custom/NoSchemaIntrospectionCustomRule.js rename to src/validation/rules/custom/NoSchemaIntrospectionCustomRule.ts index 7a1c1f2ab9..a8f7013f74 100644 --- a/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.js +++ b/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.ts @@ -1,12 +1,12 @@ import { GraphQLError } from '../../../error/GraphQLError'; -import type { FieldNode } from '../../../language/ast'; -import type { ASTVisitor } from '../../../language/visitor'; +import { FieldNode } from '../../../language/ast'; +import { ASTVisitor } from '../../../language/visitor'; import { getNamedType } from '../../../type/definition'; import { isIntrospectionType } from '../../../type/introspection'; -import type { ValidationContext } from '../../ValidationContext'; +import { ValidationContext } from '../../ValidationContext'; /** * Prohibit introspection queries diff --git a/src/validation/specifiedRules.js b/src/validation/specifiedRules.ts similarity index 100% rename from src/validation/specifiedRules.js rename to src/validation/specifiedRules.ts diff --git a/src/validation/validate.js b/src/validation/validate.ts similarity index 86% rename from src/validation/validate.js rename to src/validation/validate.ts index 8cb11a5bcd..e390903bd0 100644 --- a/src/validation/validate.js +++ b/src/validation/validate.ts @@ -2,15 +2,15 @@ import devAssert from '../jsutils/devAssert'; import { GraphQLError } from '../error/GraphQLError'; -import type { DocumentNode } from '../language/ast'; +import { DocumentNode } from '../language/ast'; import { visit, visitInParallel } from '../language/visitor'; -import type { GraphQLSchema } from '../type/schema'; +import { GraphQLSchema } from '../type/schema'; import { assertValidSchema } from '../type/validate'; import { TypeInfo, visitWithTypeInfo } from '../utilities/TypeInfo'; -import type { SDLValidationRule, ValidationRule } from './ValidationContext'; +import { SDLValidationRule, ValidationRule } from './ValidationContext'; import { specifiedRules, specifiedSDLRules } from './specifiedRules'; import { SDLValidationContext, ValidationContext } from './ValidationContext'; @@ -33,10 +33,10 @@ import { SDLValidationContext, ValidationContext } from './ValidationContext'; export function validate( schema: GraphQLSchema, documentAST: DocumentNode, - rules?: $ReadOnlyArray = specifiedRules, - typeInfo?: TypeInfo = new TypeInfo(schema), - options?: {| maxErrors?: number |} = { maxErrors: undefined }, -): $ReadOnlyArray { + rules: ReadonlyArray = specifiedRules, + typeInfo: TypeInfo = new TypeInfo(schema), + options: { maxErrors?: number } = { maxErrors: undefined }, +): ReadonlyArray { devAssert(documentAST, 'Must provide document.'); // If the schema used for validation is invalid, throw an error. assertValidSchema(schema); @@ -80,9 +80,9 @@ export function validate( */ export function validateSDL( documentAST: DocumentNode, - schemaToExtend?: ?GraphQLSchema, - rules?: $ReadOnlyArray = specifiedSDLRules, -): $ReadOnlyArray { + schemaToExtend?: GraphQLSchema | null | undefined, + rules: ReadonlyArray = specifiedSDLRules, +): ReadonlyArray { const errors = []; const context = new SDLValidationContext( documentAST, diff --git a/src/version.js b/src/version.ts similarity index 100% rename from src/version.js rename to src/version.ts diff --git a/tsconfig.json b/tsconfig.json index d25aa26463..ecf27a4bed 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,12 +2,13 @@ "compilerOptions": { "module": "commonjs", "lib": ["es6", "esnext.asynciterable"], - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, - "strictFunctionTypes": true, + "noImplicitAny": false, + "noImplicitThis": false, + "strictNullChecks": false, + "strictFunctionTypes": false, "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true - } + }, + "exclude": ["integrationTests/*/**"] }