diff --git a/.babelrc-deno.json b/.babelrc-deno.json index 7363f79d12..0e173bfb4e 100644 --- a/.babelrc-deno.json +++ b/.babelrc-deno.json @@ -1,7 +1,7 @@ { "plugins": [ - "@babel/plugin-transform-flow-strip-types", - ["./resources/add-extension-to-import-paths", { "extension": "js" }], + "@babel/plugin-syntax-typescript", + ["./resources/add-extension-to-import-paths", { "extension": "ts" }], "./resources/inline-invariant" ] } diff --git a/.babelrc-npm.json b/.babelrc-npm.json index 16b40d26a9..357c91dbc0 100644 --- a/.babelrc-npm.json +++ b/.babelrc-npm.json @@ -1,6 +1,6 @@ { "plugins": [ - "@babel/plugin-transform-flow-strip-types", + "@babel/plugin-transform-typescript", "./resources/inline-invariant" ], "env": { diff --git a/.babelrc.json b/.babelrc.json index d6bcc04649..caa5300ad7 100644 --- a/.babelrc.json +++ b/.babelrc.json @@ -1,5 +1,5 @@ { - "plugins": ["@babel/plugin-transform-flow-strip-types"], + "plugins": ["@babel/plugin-transform-typescript"], "presets": [ [ "@babel/preset-env", diff --git a/.eslintignore b/.eslintignore index 258461b7bf..ec6a952fa7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,7 +7,5 @@ /npm /deno -# Ignore Flow typings for 3rd-party libraries -/flow-typed # Ignore TS files inside integration test /integrationTests/ts/*.ts diff --git a/.eslintrc.yml b/.eslintrc.yml index 0e6d224c86..17f9c63f26 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -436,64 +436,6 @@ rules: yield-star-spacing: off overrides: - - files: 'src/**/*.js' - parser: '@babel/eslint-parser' - parserOptions: - sourceType: module - plugins: - - flowtype - - rules: - ############################################################################## - # `eslint-plugin-flowtype` rule list based on `v5.7.x` - # https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype - ############################################################################## - - flowtype/array-style-complex-type: error - flowtype/array-style-simple-type: error - flowtype/define-flow-type: error - flowtype/newline-after-flow-annotation: error - flowtype/no-dupe-keys: error - flowtype/no-existential-type: off # checked by Flow - flowtype/no-flow-fix-me-comments: off - flowtype/no-internal-flow-type: error - flowtype/no-mixed: off - flowtype/no-mutable-array: off - flowtype/no-primitive-constructor-types: error - flowtype/no-types-missing-file-annotation: off - flowtype/no-unused-expressions: off - flowtype/no-weak-types: [error, { any: false }] - flowtype/require-compound-type-alias: off - flowtype/require-exact-type: [error, never] - flowtype/require-indexer-name: error - flowtype/require-inexact-type: off # checked by Flow - flowtype/require-parameter-type: off - flowtype/require-readonly-react-props: off - flowtype/require-return-type: off - flowtype/require-types-at-top: off - flowtype/require-valid-file-annotation: off - flowtype/require-variable-type: off - flowtype/sort-keys: off - flowtype/spread-exact-type: off - flowtype/type-id-match: [error, '^[A-Z]'] - flowtype/type-import-style: [error, declaration] - flowtype/use-read-only-spread: error - flowtype/use-flow-type: error - - # Bellow rules are disabled because coflicts with Prettier, see: - # https://github.com/prettier/eslint-config-prettier/blob/master/flowtype.js - flowtype/arrow-parens: off - flowtype/boolean-style: off - flowtype/delimiter-dangle: off - flowtype/generic-spacing: off - flowtype/object-type-curly-spacing: off - flowtype/object-type-delimiter: off - flowtype/quotes: off - flowtype/semi: off - flowtype/space-after-type-colon: off - flowtype/space-before-generic-bracket: off - flowtype/space-before-type-colon: off - flowtype/union-intersection-spacing: off - files: '**/*.ts' parser: '@typescript-eslint/parser' parserOptions: @@ -515,22 +457,21 @@ overrides: '@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/ban-types': off # TODO temporarily disabled '@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/consistent-type-definitions': off # TODO consider - '@typescript-eslint/consistent-type-imports': off # TODO enable after TS conversion + '@typescript-eslint/consistent-type-assertions': off # TODO temporarily disable + '@typescript-eslint/consistent-type-definitions': error + '@typescript-eslint/consistent-type-imports': error '@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/member-ordering': error '@typescript-eslint/method-signature-style': error '@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-confusing-void-expression': error + '@typescript-eslint/no-confusing-void-expression': off # TODO enable with ignoreArrowShorthand '@typescript-eslint/no-dynamic-delete': off '@typescript-eslint/no-empty-interface': error '@typescript-eslint/no-explicit-any': off # TODO error @@ -552,21 +493,21 @@ overrides: '@typescript-eslint/no-require-imports': error '@typescript-eslint/no-this-alias': error '@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-boolean-literal-compare': off # FIXME requires on strictNullChecks + '@typescript-eslint/no-unnecessary-condition': off # TODO temporary disable '@typescript-eslint/no-unnecessary-qualifier': error '@typescript-eslint/no-unnecessary-type-arguments': error '@typescript-eslint/no-unnecessary-type-assertion': error - '@typescript-eslint/no-unnecessary-type-constraint': off # TODO consider + '@typescript-eslint/no-unnecessary-type-constraint': error '@typescript-eslint/no-unsafe-argument': off # TODO consider '@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/non-nullable-type-assertion-style': error - '@typescript-eslint/prefer-as-const': off # TODO consider - '@typescript-eslint/prefer-enum-initializers': off # TODO consider + '@typescript-eslint/non-nullable-type-assertion-style': off #TODO temporarily disabled + '@typescript-eslint/prefer-as-const': error + '@typescript-eslint/prefer-enum-initializers': error '@typescript-eslint/prefer-for-of': off # TODO switch to error after TS migration '@typescript-eslint/prefer-function-type': error '@typescript-eslint/prefer-includes': off # TODO switch to error after IE11 drop @@ -582,12 +523,11 @@ overrides: '@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/restrict-plus-operands': off #TODO temporarily disabled + '@typescript-eslint/restrict-template-expressions': off #TODO temporarily disabled '@typescript-eslint/sort-type-union-intersection-members': off # TODO consider '@typescript-eslint/strict-boolean-expressions': off # TODO consider - '@typescript-eslint/switch-exhaustiveness-check': error + '@typescript-eslint/switch-exhaustiveness-check': off #TODO temporarily disabled '@typescript-eslint/triple-slash-reference': error '@typescript-eslint/typedef': off '@typescript-eslint/unbound-method': off # TODO consider @@ -642,7 +582,7 @@ overrides: '@typescript-eslint/require-await': error '@typescript-eslint/return-await': error - # Disable for JS, Flow and TS + # Disable for JS and TS '@typescript-eslint/init-declarations': off '@typescript-eslint/no-magic-numbers': off '@typescript-eslint/no-use-before-define': off @@ -665,10 +605,6 @@ overrides: '@typescript-eslint/space-before-function-paren': off '@typescript-eslint/space-infix-ops': off '@typescript-eslint/type-annotation-spacing': off - - files: 'src/**/*.d.ts' - rules: - import/order: off - import/newline-after-import: off - files: 'src/**/__*__/**' rules: node/no-unpublished-import: [error, { allowModules: ['chai', 'mocha'] }] diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 519988aff5..0000000000 --- a/.flowconfig +++ /dev/null @@ -1,39 +0,0 @@ -[ignore] -.* -!/src - -[include] - -[lints] -sketchy-null=error -sketchy-number=error -untyped-type-import=error -nonstrict-import=off -untyped-import=error -unclear-type=off -deprecated-type=error -deprecated-utility=error -unsafe-getters-setters=error -unnecessary-optional-chain=error -unnecessary-invariant=error -signature-verification-failure=error -implicit-inexact-object=off -ambiguous-object-type=off -uninitialized-instance-property=error -default-import-access=error -invalid-import-star-use=error -non-const-var-export=error -this-in-exported-function=error -mixed-import-and-require=error -export-renamed-default=error - -[options] -all=true -module.use_strict=true -exact_by_default=true -experimental.const_params=true -include_warnings=true -no_flowlib=true - -[version] -^0.150.0 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d3e9f32397..28e8ef3261 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -73,7 +73,7 @@ ensure your pull request matches the style guides, run `npm run prettier`. - 80 character line length strongly preferred. - Prefer `'` over `"` - ES6 syntax when possible. However do not rely on ES6-specific functions to be available. -- Use [Flow types](https://flowtype.org/). +- Use [TypeScript](https://www.typescriptlang.org). - Use semicolons; - Trailing commas, - Avd abbr wrds. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 063422c189..f36f980482 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: - name: Lint ESLint run: npm run lint - - name: Lint Flow + - name: Check Types run: npm run check - name: Lint Prettier diff --git a/.mocharc.yml b/.mocharc.yml index 5e75d26389..51cae89f42 100644 --- a/.mocharc.yml +++ b/.mocharc.yml @@ -1,4 +1,4 @@ throw-deprecation: true check-leaks: true require: - - '@babel/register' + - 'resources/ts-register.js' diff --git a/.prettierignore b/.prettierignore index f15fd04838..475f5e22fd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,3 @@ -/flow-typed - # Copied from '.gitignore', please keep it in sync. /.eslintcache /node_modules diff --git a/cspell.yml b/cspell.yml index 8ba853e25e..36a6cf6e0c 100644 --- a/cspell.yml +++ b/cspell.yml @@ -24,7 +24,6 @@ words: - graphiql - sublinks - instanceof - - flowtype # Different names used inside tests - Skywalker diff --git a/flow-typed/core.js b/flow-typed/core.js deleted file mode 100644 index a321a64c56..0000000000 --- a/flow-typed/core.js +++ /dev/null @@ -1,2564 +0,0 @@ -// Various hacks applied to Flow core definitions -// All hacks are marked with '// graphql-js HACK' comment - -/* cSpell:disable */ - -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Modifications copyright (C) Facebook, Inc. and its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use - * this file except in compliance with the License. You may obtain a copy of the - * License at http://www.apache.org/licenses/LICENSE-2.0 - * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED - * WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, - * MERCHANTABLITY OR NON-INFRINGEMENT. - * See the Apache Version 2.0 License for specific language governing permissions - * and limitations under the License. - */ -// @lint-ignore-every LICENSELINT - -declare var NaN: number; -declare var Infinity: number; -declare var undefined: void; - -/** - * Converts a string to an integer. - * @param string A string to convert into a number. - * @param radix A value between 2 and 36 that specifies the base of the number in numString. - * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. - * All other strings are considered decimal. - */ -declare function parseInt(string: mixed, radix?: number): number; -/** - * Converts a string to a floating-point number. - * @param string A string that contains a floating-point number. - */ -declare function parseFloat(string: mixed): number; - -/** - * Returns a boolean value that indicates whether a value is the reserved value NaN (not a number). - * @param number A numeric value. - */ -declare function isNaN(number: mixed): boolean; -/** - * Determines whether a supplied number is finite. - * @param number Any numeric value. - */ -declare function isFinite(number: mixed): boolean; -/** - * Gets the unencoded version of an encoded Uniform Resource Identifier (URI). - * @param encodedURI A value representing an encoded URI. - */ -declare function decodeURI(encodedURI: string): string; -/** - * Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI). - * @param encodedURIComponent A value representing an encoded URI component. - */ -declare function decodeURIComponent(encodedURIComponent: string): string; -/** - * Encodes a text string as a valid Uniform Resource Identifier (URI) - * @param uri A value representing an encoded URI. - */ -declare function encodeURI(uri: string): string; -/** - * Encodes a text string as a valid component of a Uniform Resource Identifier (URI). - * @param uriComponent A value representing an encoded URI component. - */ -declare function encodeURIComponent(uriComponent: string): string; - -type PropertyDescriptor = { - enumerable?: boolean, - configurable?: boolean, - writable?: boolean, - value?: T, - get?: () => T, - set?: (value: T) => void, - ... -}; - -type PropertyDescriptorMap = { [s: string]: PropertyDescriptor, ... } - -type $NotNullOrVoid = -| number -| string -| boolean -| {...} -| $ReadOnlyArray; - -declare class Object { - static (o: ?void): { [key: any]: any, ... }; - static (o: boolean): Boolean; - static (o: number): Number; - static (o: string): String; - static (o: T): T; - /** - * Copy the values of all of the enumerable own properties from one or more source objects to a - * target object. Returns the target object. - * @param target The target object to copy to. - * @param sources The source object from which to copy properties. - */ - static assign: Object$Assign; - /** - * Creates an object that has the specified prototype, and that optionally contains specified properties. - * @param o Object to use as a prototype. May be null - * @param properties JavaScript object that contains one or more property descriptors. - */ - static create(o: any, properties?: PropertyDescriptorMap): any; // compiler magic - /** - * Adds one or more properties to an object, and/or modifies attributes of existing properties. - * @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object. - * @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property. - */ - static defineProperties(o: any, properties: PropertyDescriptorMap): any; - /** - * Adds a property to an object, or modifies attributes of an existing property. - * @param o Object on which to add or modify the property. This can be a native JavaScript object (that is, a user-defined object or a built in object) or a DOM object. - * @param p The property name. - * @param attributes Descriptor for the property. It can be for a data property or an accessor property. - */ - static defineProperty(o: any, p: any, attributes: PropertyDescriptor): any; - /** - * Returns an array of key/values of the enumerable properties of an object - * @param object Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. - */ - static entries(obj: { +[key: string]: T, __proto__: null }): Array<[string, T]>; // graphql-js HACK - static entries(object: $NotNullOrVoid): Array<[string, mixed]>; - /** - * Prevents the modification of existing property attributes and values, and prevents the addition of new properties. - * @param o Object on which to lock the attributes. - */ - static freeze(o: T): T; - /** - * Returns an object created by key-value entries for properties and methods - * @param entries An iterable object that contains key-value entries for properties and methods. - */ - static fromEntries(entries: Iterable<[K, V] | { - '0': K, - '1': V, - ... - }>): { [K]: V, ... }; - - /** - * Gets the own property descriptor of the specified object. - * An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype. - * @param o Object that contains the property. - * @param p Name of the property. - */ - static getOwnPropertyDescriptor(o: $NotNullOrVoid, p: any): PropertyDescriptor | void; - /** - * Gets the own property descriptors of the specified object. - * An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype. - * @param o Object that contains the properties. - */ - static getOwnPropertyDescriptors(o: {...}): PropertyDescriptorMap; - // This is documentation only. Object.getOwnPropertyNames is implemented in OCaml code - // https://github.com/facebook/flow/blob/8ac01bc604a6827e6ee9a71b197bb974f8080049/src/typing/statement.ml#L6308 - /** - * Returns the names of the own properties of an object. The own properties of an object are those that are defined directly - * on that object, and are not inherited from the object's prototype. The properties of an object include both fields (objects) and functions. - * @param o Object that contains the own properties. - */ - static getOwnPropertyNames(o: $NotNullOrVoid): Array; - /** - * Returns an array of all symbol properties found directly on object o. - * @param o Object to retrieve the symbols from. - */ - static getOwnPropertySymbols(o: $NotNullOrVoid): Array; - /** - * Returns the prototype of an object. - * @param o The object that references the prototype. - */ - static getPrototypeOf: Object$GetPrototypeOf; - /** - * Returns true if the values are the same value, false otherwise. - * @param a The first value. - * @param b The second value. - */ - static is(a: T, b: T): boolean; - /** - * Returns a value that indicates whether new properties can be added to an object. - * @param o Object to test. - */ - static isExtensible(o: $NotNullOrVoid): boolean; - /** - * Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object. - * @param o Object to test. - */ - static isFrozen(o: $NotNullOrVoid): boolean; - static isSealed(o: $NotNullOrVoid): boolean; - // This is documentation only. Object.keys is implemented in OCaml code. - // https://github.com/facebook/flow/blob/8ac01bc604a6827e6ee9a71b197bb974f8080049/src/typing/statement.ml#L6308 - /** - * Returns the names of the enumerable string properties and methods of an object. - * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. - */ - static keys(o: $NotNullOrVoid): Array; - /** - * Prevents the addition of new properties to an object. - * @param o Object to make non-extensible. - */ - static preventExtensions(o: T): T; - /** - * Prevents the modification of attributes of existing properties, and prevents the addition of new properties. - * @param o Object on which to lock the attributes. - */ - static seal(o: T): T; - /** - * Sets the prototype of a specified object o to object proto or null. Returns the object o. - * @param o The object to change its prototype. - * @param proto The value of the new prototype or null. - */ - static setPrototypeOf(o: T, proto: ?{...}): T; - /** - * Returns an array of values of the enumerable properties of an object - * @param object Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. - */ - static values(obj: { +[key: string]: T, __proto__: null }): Array; // graphql-js HACK - static values(object: $NotNullOrVoid): Array; - /** - * Determines whether an object has a property with the specified name. - * @param prop A property name. - */ - hasOwnProperty(prop: mixed): boolean; - /** - * Determines whether an object exists in another object's prototype chain. - * @param o Another object whose prototype chain is to be checked. - */ - isPrototypeOf(o: mixed): boolean; - /** - * Determines whether a specified property is enumerable. - * @param prop A property name. - */ - propertyIsEnumerable(prop: mixed): boolean; - /** Returns a date converted to a string using the current locale. */ - toLocaleString(): string; - /** Returns a string representation of an object. */ - toString(): string; - /** Returns the primitive value of the specified object. */ - valueOf(): mixed; -} - -// Well known Symbols. -declare opaque type $SymbolHasInstance: symbol; -declare opaque type $SymboIsConcatSpreadable: symbol; -declare opaque type $SymbolIterator: symbol; -declare opaque type $SymbolMatch: symbol; -declare opaque type $SymbolMatchAll: symbol; -declare opaque type $SymbolReplace: symbol; -declare opaque type $SymbolSearch: symbol; -declare opaque type $SymbolSpecies: symbol; -declare opaque type $SymbolSplit: symbol; -declare opaque type $SymbolToPrimitive: symbol; -declare opaque type $SymbolToStringTag: symbol; -declare opaque type $SymbolUnscopables: symbol; - -declare class Symbol { - static asyncIterator: '@@asyncIterator'; // graphql-js HACK - - /** - * Returns a new unique Symbol value. - * @param value Description of the new Symbol object. - */ - static (value?:any): symbol; - /** - * Returns a Symbol object from the global symbol registry matching the given key if found. - * Otherwise, returns a new symbol with this key. - * @param key key to search for. - */ - static for(key: string): symbol; - /** - * Expose the [[Description]] internal slot of a symbol directly. - */ - +description: string | void; - /** - * A method that determines if a constructor object recognizes an object as one of the - * constructor's instances. Called by the semantics of the instanceof operator. - */ - static hasInstance: $SymbolHasInstance; - /** - * A Boolean value that if true indicates that an object should flatten to its array elements - * by Array.prototype.concat. - */ - static isConcatSpreadable: $SymboIsConcatSpreadable; - static iterator: '@@iterator'; - /** - * Returns a key from the global symbol registry matching the given Symbol if found. - * Otherwise, returns a undefined. - * @param sym Symbol to find the key for. - */ - static keyFor(sym: symbol): ?string; - static length: 0; - /** - * A regular expression method that matches the regular expression against a string. Called - * by the String.prototype.match method. - */ - static match: $SymbolMatch; - /** - * A regular expression method that matches the regular expression against a string. Called - * by the String.prototype.matchAll method. - */ - static matchAll: $SymbolMatchAll; - /** - * A regular expression method that replaces matched substrings of a string. Called by the - * String.prototype.replace method. - */ - static replace: $SymbolReplace; - /** - * A regular expression method that returns the index within a string that matches the - * regular expression. Called by the String.prototype.search method. - */ - static search: $SymbolSearch; - /** - * A function valued property that is the constructor function that is used to create - * derived objects. - */ - static species: $SymbolSpecies; - /** - * A regular expression method that splits a string at the indices that match the regular - * expression. Called by the String.prototype.split method. - */ - static split: $SymbolSplit; - /** - * A method that converts an object to a corresponding primitive value. - * Called by the ToPrimitive abstract operation. - */ - static toPrimitive: $SymbolToPrimitive; - /** - * A String value that is used in the creation of the default string description of an object. - * Called by the built-in method Object.prototype.toString. - */ - static toStringTag: $SymbolToStringTag; - /** - * An Object whose own property names are property names that are excluded from the 'with' - * environment bindings of the associated objects. - */ - static unscopables: $SymbolUnscopables; - toString(): string; - valueOf(): ?symbol; -} - -// TODO: instance, static -declare class Function { - proto apply: Function$Prototype$Apply; // (thisArg: any, argArray?: any) => any - proto bind: Function$Prototype$Bind; // (thisArg: any, ...argArray: Array) => any; - proto call: Function$Prototype$Call; // (thisArg: any, ...argArray: Array) => any - /** Returns a string representation of a function. */ - toString(): string; - arguments: any; - caller: any | null; - length: number; - /** - * Returns the name of the function. Function names are read-only and can not be changed. - */ - name: string; -} - -declare class Boolean { - constructor(value?: mixed): void; - static (value:mixed):boolean; - /** Returns the primitive value of the specified object. */ - valueOf(): boolean; - toString(): string; -} - -/** An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers. */ -declare class Number { - /** - * The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1 - * that is representable as a Number value, which is approximately: - * 2.2204460492503130808472633361816 x 10^-16. - */ - static EPSILON: number; - /** - * The value of the largest integer n such that n and n + 1 are both exactly representable as - * a Number value. - * The value of Number.MAX_SAFE_INTEGER is 9007199254740991 2^53 - 1. - */ - static MAX_SAFE_INTEGER: number; - /** The largest number that can be represented in JavaScript. Equal to approximately 1.79E+308. */ - static MAX_VALUE: number; - /** - * The value of the smallest integer n such that n and n - 1 are both exactly representable as - * a Number value. - * The value of Number.MIN_SAFE_INTEGER is -9007199254740991 (-(2^53 - 1)). - */ - static MIN_SAFE_INTEGER: number; - /** The closest number to zero that can be represented in JavaScript. Equal to approximately 5.00E-324. */ - static MIN_VALUE: number; - /** - * A value that is not a number. - * In equality comparisons, NaN does not equal any value, including itself. To test whether a value is equivalent to NaN, use the isNaN function. - */ - static NaN: number; - /** - * A value that is less than the largest negative number that can be represented in JavaScript. - * JavaScript displays NEGATIVE_INFINITY values as -infinity. - */ - static NEGATIVE_INFINITY: number; - /** - * A value greater than the largest number that can be represented in JavaScript. - * JavaScript displays POSITIVE_INFINITY values as infinity. - */ - static POSITIVE_INFINITY: number; - static (value:mixed):number; - /** - * Returns true if passed value is finite. - * Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a - * number. Only finite values of the type number, result in true. - * @param value A numeric value. - */ - static isFinite(value: mixed): boolean; - /** - * Returns true if the value passed is an integer, false otherwise. - * @param value A numeric value. - */ - static isInteger(value: mixed): boolean; - /** - * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a - * number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter - * to a number. Only values of the type number, that are also NaN, result in true. - * @param value A numeric value. - */ - static isNaN(value: mixed): boolean; - /** - * Returns true if the value passed is a safe integer. - * @param value A numeric value. - */ - static isSafeInteger(value: mixed): boolean; - /** - * Converts a string to a floating-point number. - * @param value A string that contains a floating-point number. - */ - static parseFloat(value: string): number; - /** - * Converts A string to an integer. - * @param value A string to convert into a number. - * @param radix A value between 2 and 36 that specifies the base of the number in numString. - * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. - * All other strings are considered decimal. - */ - static parseInt(value: string, radix?: number): number; - constructor(value?: mixed): void; - /** - * Returns a string containing a number represented in exponential notation. - * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive. - */ - toExponential(fractionDigits?: number): string; - /** - * Returns a string representing a number in fixed-point notation. - * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive. - */ - toFixed(fractionDigits?: number): string; - /** - * Converts a number to a string by using the current or specified locale. - * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. - * @param options An object that contains one or more properties that specify comparison options. - */ - toLocaleString(locales?: string | Array, options?: Intl$NumberFormatOptions): string; - /** - * Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits. - * @param precision Number of significant digits. Must be in the range 1 - 21, inclusive. - */ - toPrecision(precision?: number): string; - /** - * Returns a string representation of an object. - * @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers. - */ - toString(radix?: number): string; - /** Returns the primitive value of the specified object. */ - valueOf(): number; -} - -/** An intrinsic object that provides basic mathematics functionality and constants. */ -declare var Math: { - /** The mathematical constant e. This is Euler's number, the base of natural logarithms. */ - E: number, - /** The natural logarithm of 10. */ - LN10: number, - /** The natural logarithm of 2. */ - LN2: number, - /** The base-10 logarithm of e. */ - LOG10E: number, - /** The base-2 logarithm of e. */ - LOG2E: number, - /** Pi. This is the ratio of the circumference of a circle to its diameter. */ - PI: number, - /** The square root of 0.5, or, equivalently, one divided by the square root of 2. */ - SQRT1_2: number, - /** The square root of 2. */ - SQRT2: number, - /** - * Returns the absolute value of a number (the value without regard to whether it is positive or negative). - * For example, the absolute value of -5 is the same as the absolute value of 5. - * @param x A numeric expression for which the absolute value is needed. - */ - abs(x: number): number, - /** - * Returns the arc cosine (or inverse cosine) of a number. - * @param x A numeric expression. - */ - acos(x: number): number, - /** - * Returns the inverse hyperbolic cosine of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - acosh(x: number): number, - /** - * Returns the arcsine of a number. - * @param x A numeric expression. - */ - asin(x: number): number, - /** - * Returns the inverse hyperbolic sine of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - asinh(x: number): number, - /** - * Returns the arctangent of a number. - * @param x A numeric expression for which the arctangent is needed. - */ - atan(x: number): number, - /** - * Returns the angle (in radians) from the X axis to a point. - * @param y A numeric expression representing the cartesian y-coordinate. - * @param x A numeric expression representing the cartesian x-coordinate. - */ - atan2(y: number, x: number): number, - /** - * Returns the inverse hyperbolic tangent of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - atanh(x: number): number, - /** - * Returns an implementation-dependent approximation to the cube root of number. - * @param x A numeric expression. - */ - cbrt(x: number): number, - /** - * Returns the smallest integer greater than or equal to its numeric argument. - * @param x A numeric expression. - */ - ceil(x: number): number, - /** - * Returns the number of leading zero bits in the 32-bit binary representation of a number. - * @param x A numeric expression. - */ - clz32(x: number): number, - /** - * Returns the cosine of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - cos(x: number): number, - /** - * Returns the hyperbolic cosine of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - cosh(x: number): number, - /** - * Returns e (the base of natural logarithms) raised to a power. - * @param x A numeric expression representing the power of e. - */ - exp(x: number): number, - /** - * Returns the result of (e^x - 1), which is an implementation-dependent approximation to - * subtracting 1 from the exponential function of x (e raised to the power of x, where e - * is the base of the natural logarithms). - * @param x A numeric expression. - */ - expm1(x: number): number, - /** - * Returns the greatest integer less than or equal to its numeric argument. - * @param x A numeric expression. - */ - floor(x: number): number, - /** - * Returns the nearest single precision float representation of a number. - * @param x A numeric expression. - */ - fround(x: number): number, - /** - * Returns the square root of the sum of squares of its arguments. - * @param values Values to compute the square root for. - * If no arguments are passed, the result is +0. - * If there is only one argument, the result is the absolute value. - * If any argument is +Infinity or -Infinity, the result is +Infinity. - * If any argument is NaN, the result is NaN. - * If all arguments are either +0 or -0, the result is +0. - */ - hypot(...values: Array): number, - /** - * Returns the result of 32-bit multiplication of two numbers. - * @param x First number - * @param y Second number - */ - imul(x: number, y: number): number, - /** - * Returns the natural logarithm (base e) of a number. - * @param x A numeric expression. - */ - log(x: number): number, - /** - * Returns the base 10 logarithm of a number. - * @param x A numeric expression. - */ - log10(x: number): number, - /** - * Returns the natural logarithm of 1 + x. - * @param x A numeric expression. - */ - log1p(x: number): number, - /** - * Returns the base 2 logarithm of a number. - * @param x A numeric expression. - */ - log2(x: number): number, - /** - * Returns the larger of a set of supplied numeric expressions. - * @param values Numeric expressions to be evaluated. - */ - max(...values: Array): number, - /** - * Returns the smaller of a set of supplied numeric expressions. - * @param values Numeric expressions to be evaluated. - */ - min(...values: Array): number, - /** - * Returns the value of a base expression taken to a specified power. - * @param x The base value of the expression. - * @param y The exponent value of the expression. - */ - pow(x: number, y: number): number, - /** Returns a pseudorandom number between 0 and 1. */ - random(): number, - /** - * Returns a supplied numeric expression rounded to the nearest integer. - * @param x The value to be rounded to the nearest integer. - */ - round(x: number): number, - /** - * Returns the sign of the x, indicating whether x is positive, negative or zero. - * @param x The numeric expression to test - */ - sign(x: number): number, - /** - * Returns the sine of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - sin(x: number): number, - /** - * Returns the hyperbolic sine of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - sinh(x: number): number, - /** - * Returns the square root of a number. - * @param x A numeric expression. - */ - sqrt(x: number): number, - /** - * Returns the tangent of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - tan(x: number): number, - /** - * Returns the hyperbolic tangent of a number. - * @param x A numeric expression that contains an angle measured in radians. - */ - tanh(x: number): number, - /** - * Returns the integral part of the a numeric expression, x, removing any fractional digits. - * If x is already an integer, the result is x. - * @param x A numeric expression. - */ - trunc(x: number): number, - ... -}; - -/** - * A class of Array methods and properties that don't mutate the array. - */ -declare class $ReadOnlyArray<+T> { - @@iterator(): Iterator; - /** - * Returns a string representation of an array. The elements are converted to string using their toLocalString methods. - */ - toLocaleString(): string; - // concat creates a new array - /** - * Combines two or more arrays. - * @param items Additional items to add to the end of array1. - */ - concat | S>(...items: Array): Array; - /** - * Returns an iterable of key, value pairs for every entry in the array - */ - entries(): Iterator<[number, T]>; - /** - * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the predicate function for each element in the array until the predicate returns a value - * which is coercible to the Boolean value false, or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. - * If thisArg is omitted, undefined is used as the this value. - */ - every(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => mixed, thisArg?: mixed): boolean; - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. - */ - filter(callbackfn: typeof Boolean): Array<$NonMaybeType>; - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. - */ - filter(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => mixed, thisArg?: mixed): Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param callbackfn find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - find(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => mixed, thisArg?: mixed): T | void; - /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param callbackfn find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - findIndex(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => mixed, thisArg?: mixed): number; - /** - * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. - */ - forEach(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => mixed, thisArg?: mixed): void; - /** - * Determines whether an array includes a certain element, returning true or false as appropriate. - * @param searchElement The element to search for. - * @param fromIndex The position in this array at which to begin searching for searchElement. - */ - includes(searchElement: mixed, fromIndex?: number): boolean; - /** - * Returns the index of the first occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0. - */ - indexOf(searchElement: mixed, fromIndex?: number): number; - /** - * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. - */ - join(separator?: string): string; - /** - * Returns an iterable of keys in the array - */ - keys(): Iterator; - /** - * Returns the index of the last occurrence of a specified value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array. - */ - lastIndexOf(searchElement: mixed, fromIndex?: number): number; - /** - * Calls a defined callback function on each element of an array, and returns an array that contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. - */ - map(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => U, thisArg?: mixed): Array; - /** - * Calls a defined callback function on each element of an array. Then, flattens the result into - * a new array. - * This is identical to a map followed by flat with depth 1. - * - * @param callbackfn A function that accepts up to three arguments. The flatMap method calls the - * callback function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callback function. If - * thisArg is omitted, undefined is used as the this value. - */ - flatMap(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => $ReadOnlyArray | U, thisArg?: mixed): Array; - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(depth: 0): Array; - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(depth: void | 1): Array<$Call<(($ReadOnlyArray) => X) & ((X) => X), T>>; - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(depth: number): Array; - /** - * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. - */ - reduce( - callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: $ReadOnlyArray) => T, - ): T; - /** - * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. - */ - reduce( - callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: $ReadOnlyArray) => U, - initialValue: U - ): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. - */ - reduceRight( - callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: $ReadOnlyArray) => T, - ): T; - /** - * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. - */ - reduceRight( - callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: $ReadOnlyArray) => U, - initialValue: U - ): U; - /** - * Returns a section of an array. - * @param start The beginning of the specified portion of the array. - * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'. - */ - slice(start?: number, end?: number): Array; - /** - * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls - * the predicate function for each element in the array until the predicate returns a value - * which is coercible to the Boolean value true, or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. - * If thisArg is omitted, undefined is used as the this value. - */ - some(callbackfn: (value: T, index: number, array: $ReadOnlyArray) => mixed, thisArg?: mixed): boolean; - /** - * Returns an iterable of values in the array - */ - values(): Iterator; - +[key: number]: T; - /** - * Gets the length of the array. This is a number one higher than the highest element defined in an array. - */ - +length: number; -} - -declare class Array extends $ReadOnlyArray { - /** - * Returns the this object after copying a section of the array identified by start and end - * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it - * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. - */ - copyWithin(target: number, start: number, end?: number): T[]; - /** - * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the predicate function for each element in the array until the predicate returns a value - * which is coercible to the Boolean value false, or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. - * If thisArg is omitted, undefined is used as the this value. - */ - every(callbackfn: (value: T, index: number, array: Array) => mixed, thisArg?: mixed): boolean; - /** - * Returns the this object after filling the section identified by start and end with value - * @param value value to fill array section with - * @param begin index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as - * length+end. - */ - fill(value: T, begin?: number, end?: number): Array; - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. - */ - filter(callbackfn: typeof Boolean): Array<$NonMaybeType>; - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. - */ - filter(callbackfn: (value: T, index: number, array: Array) => mixed, thisArg?: mixed): Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param callbackfn find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - find(callbackfn: (value: T, index: number, array: Array) => mixed, thisArg?: mixed): T | void; - /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param callbackfn find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - findIndex(callbackfn: (value: T, index: number, array: Array) => mixed, thisArg?: mixed): number; - /** - * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. - */ - forEach(callbackfn: (value: T, index: number, array: Array) => mixed, thisArg?: mixed): void; - /** - * Calls a defined callback function on each element of an array, and returns an array that contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. - */ - map(callbackfn: (value: T, index: number, array: Array) => U, thisArg?: mixed): Array; - /** - * Calls a defined callback function on each element of an array. Then, flattens the result into - * a new array. - * This is identical to a map followed by flat with depth 1. - * - * @param callbackfn A function that accepts up to three arguments. The flatMap method calls the - * callback function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callback function. If - * thisArg is omitted, undefined is used as the this value. - */ - flatMap(callbackfn: (value: T, index: number, array: Array) => $ReadOnlyArray | U, thisArg?: mixed): Array; - /** - * Removes the last element from an array and returns it. - */ - pop(): T; - /** - * Appends new elements to an array, and returns the new length of the array. - * @param items New elements of the Array. - */ - push(...items: Array): number; - /** - * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. - */ - reduce( - callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: Array) => T, - ): T; - /** - * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. - */ - reduce( - callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: Array) => U, - initialValue: U - ): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. - */ - reduceRight( - callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: Array) => T, - ): T; - /** - * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. - */ - reduceRight( - callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: Array) => U, - initialValue: U - ): U; - /** - * Reverses the elements in an Array. - */ - reverse(): Array; - /** - * Removes the first element from an array and returns it. - */ - shift(): T; - some(callbackfn: (value: T, index: number, array: Array) => mixed, thisArg?: mixed): boolean; - sort(compareFn?: (a: T, b: T) => number): Array; - splice(start: number, deleteCount?: number, ...items: Array): Array; - unshift(...items: Array): number; - - - [key: number]: T; - /** - * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array. - */ - length: number; - static (...values:Array): Array; - static isArray(obj: mixed): bool; - /** - * Creates an array from an iterable object. - * @param iter An iterable object to convert to an array. - * @param mapFn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ - static from(iter: Iterable, mapFn: (elem: A, index: number) => B, thisArg?: mixed): Array; - /** - * Creates an array from an iterable object. - * @param iter An iterable object to convert to an array. - */ - static from(iter: Iterable, mapFn: void): Array; - /** - * Creates an array from an iterable object. - * @param iter An iterable object to convert to an array. - * @param mapFn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ - static from(iter: Iterator, mapFn: (elem: A, index: number) => B, thisArg?: mixed): Array; - /** - * Creates an array from an iterable object. - * @param iter An array-like object to convert to an array. - */ - static from(iter: Iterator, mapFn: void): Array; - /** - * Creates an array from an array-like object. - * @param arrayLike An array-like object to convert to an array. - * @param mapFn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ - static from(arrayLike: { length: number, ... }, mapFn: (elem: void, index: number) => A, thisArg?: mixed): Array; - /** - * Creates an array from an array-like object. - * @param arrayLike An array-like object to convert to an array. - */ - static from(arrayLike: { length: number, ... }, mapFn: void): Array; - /** - * Returns a new array from a set of elements. - * @param values A set of elements to include in the new array object. - */ - static of(...values: Array): Array; -} - -type $ArrayLike = { - [indexer: number]: T, - length: number, - ... -} - -type RegExp$flags = $CharSet<"gimsuy">; -type RegExp$matchResult = Array & { - index: number, - input: string, - groups: ?{ [name: string]: string, ... }, - ... -}; - -/** - * Allows manipulation and formatting of text strings and determination and location of substrings within strings. - */ -declare class String { - @@iterator(): Iterator; - /** - * Returns an `` HTML anchor element and sets the name attribute to the text value - * @param name - */ - anchor(name: string): string; - /** - * Returns the character at the specified index. - * @param pos The zero-based index of the desired character. - */ - charAt(pos: number): string; - /** - * Returns the Unicode value of the character at the specified location. - * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned. - */ - charCodeAt(index: number): number; - /** - * Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point - * value of the UTF-16 encoded code point starting at the string element at position index in - * the String resulting from converting this object to a String. - * If there is no element at that position, the result is undefined. - * If a valid UTF-16 surrogate pair does not begin at index, the result is the code unit at index. - */ - codePointAt(index: number): number; - /** - * Returns a string that contains the concatenation of two or more strings. - * @param strings The strings to append to the end of the string. - */ - concat(...strings: Array): string; - constructor(value?: mixed): void; - /** - * Returns true if the sequence of elements of searchString converted to a String is the - * same as the corresponding elements of this object (converted to a String) starting at - * position - length(this). Otherwise returns false. - */ - endsWith(searchString: string, position?: number): boolean; - /** - * Returns true if searchString appears as a substring of the result of converting this - * object to a String, at one or more positions that are - * greater than or equal to position; otherwise, returns false. - * @param searchString search string - * @param position If position is undefined, 0 is assumed, so as to search all of the String. - */ - includes(searchString: string, position?: number): boolean; - /** - * Returns the position of the first occurrence of a substring. - * @param searchString The substring to search for in the string - * @param position The index at which to begin searching the String object. If omitted, search starts at the beginning of the string. - */ - indexOf(searchString: string, position?: number): number; - /** - * Returns the last occurrence of a substring in the string. - * @param searchString The substring to search for. - * @param position The index at which to begin searching. If omitted, the search begins at the end of the string. - */ - lastIndexOf(searchString: string, position?: number): number; - /** Returns an `` HTML element and sets the href attribute value */ - link(href: string): string; - /** - * Determines whether two strings are equivalent in the current or specified locale. - * @param that String to compare to target string - * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details. - * @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details. - */ - localeCompare(that: string, locales?: string | Array, options?: Intl$CollatorOptions): number; - /** - * Matches a string with a regular expression, and returns an array containing the results of that search. - * @param regexp A variable name or string literal containing the regular expression pattern and flags. - */ - match(regexp: string | RegExp): RegExp$matchResult | null; - /** - * Matches a string with a regular expression, and returns an iterable of matches - * containing the results of that search. - * @param regexp A variable name or string literal containing the regular expression pattern and flags. - */ - matchAll(regexp: string | RegExp): Iterator; - /** - * Returns the String value result of normalizing the string into the normalization form - * named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms. - * @param format Applicable values: "NFC", "NFD", "NFKC", or "NFKD", If not specified default - * is "NFC" - */ - normalize(format?: string): string; - /** - * Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length. - * The padding is applied from the end (right) of the current string. - * - * @param targetLength The length of the resulting string once the current string has been padded. - * If this parameter is smaller than the current string's length, the current string will be returned as it is. - * - * @param padString The string to pad the current string with. - * If this string is too long, it will be truncated and the left-most part will be applied. - * The default value for this parameter is " " (U+0020). - */ - padEnd(targetLength: number, padString?: string): string; - /** - * Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length. - * The padding is applied from the start (left) of the current string. - * - * @param targetLength The length of the resulting string once the current string has been padded. - * If this parameter is smaller than the current string's length, the current string will be returned as it is. - * - * @param padString The string to pad the current string with. - * If this string is too long, it will be truncated and the left-most part will be applied. - * The default value for this parameter is " " (U+0020). - */ - padStart(targetLength: number, padString?: string): string; - /** - * Returns a String value that is made from count copies appended together. If count is 0, - * the empty string is returned. - * @param count number of copies to append - */ - repeat(count: number): string; - /** - * Replaces text in a string, using a regular expression or search string. - * @param searchValue A string to search for. - * @param replaceValue A string containing the text to replace for every successful match of searchValue in this string or a function that returns the replacement text. - */ - replace(searchValue: string | RegExp, replaceValue: string | (substring: string, ...args: Array) => string): string; - /** - * Finds the first substring match in a regular expression search. - * @param regexp The regular expression pattern and applicable flags. - */ - search(regexp: string | RegExp): number; - /** - * Returns a section of a string. - * @param start The index to the beginning of the specified portion of stringObj. - * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end. - * If this value is not specified, the substring continues to the end of stringObj. - */ - slice(start?: number, end?: number): string; - /** - * Split a string into substrings using the specified separator and return them as an array. - * @param separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. - * @param limit A value used to limit the number of elements returned in the array. - */ - split(separator?: string | RegExp, limit?: number): Array; - /** - * Returns true if the sequence of elements of searchString converted to a String is the - * same as the corresponding elements of this object (converted to a String) starting at - * position. Otherwise returns false. - */ - startsWith(searchString: string, position?: number): boolean; - /** - * Gets a substring beginning at the specified location and having the specified length. - * @param from The starting position of the desired substring. The index of the first character in the string is zero. - * @param length The number of characters to include in the returned substring. - */ - substr(from: number, length?: number): string; - /** - * Returns the substring at the specified location within a String object. - * @param start The zero-based index number indicating the beginning of the substring. - * @param end Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end. - * If end is omitted, the characters from start through the end of the original string are returned. - */ - substring(start: number, end?: number): string; - /** Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. */ - toLocaleLowerCase(locale?: string | Array): string; - /** Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale. */ - toLocaleUpperCase(locale?: string | Array): string; - /** Converts all the alphabetic characters in a string to lowercase. */ - toLowerCase(): string; - /** Converts all the alphabetic characters in a string to uppercase. */ - toUpperCase(): string; - /** Removes the leading and trailing white space and line terminator characters from a string. */ - trim(): string; - /** Removes the trailing white space and line terminator characters from a string. */ - trimEnd(): string; - /** Removes the leading white space and line terminator characters from a string. */ - trimLeft(): string; - /** Removes the trailing white space and line terminator characters from a string. */ - trimRight(): string; - /** Removes the leading white space and line terminator characters from a string. */ - trimStart(): string; - /** Returns the primitive value of the specified object. */ - valueOf(): string; - /** Returns a string representation of a string. */ - toString(): string; - /** Returns the length of a String object. */ - length: number; - [key: number]: string; - static (value:mixed):string; - static fromCharCode(...codes: Array): string; - /** - * Return the String value whose elements are, in order, the elements in the List elements. - * If length is 0, the empty string is returned. - */ - static fromCodePoint(...codes: Array): string; - /** - * String.raw is intended for use as a tag function of a Tagged Template String. When called - * as such the first argument will be a well formed template call site object and the rest - * parameter will contain the substitution values. - * @param templateString A well-formed template string call site representation. - */ - static raw(templateString: string): string; - /** - * String.raw is intended for use as a tag function of a Tagged Template String. When called - * as such the first argument will be a well formed template call site object and the rest - * parameter will contain the substitution values. - * @param callSite A well-formed template string call site representation. - * @param substitutions A set of substitution values. - */ - static raw(callSite: string[], ...substitutions: any[]): string; // graphql-js HACK -} - -declare class RegExp { - static (pattern: string | RegExp, flags?: RegExp$flags): RegExp; - compile(): RegExp; - constructor(pattern: string | RegExp, flags?: RegExp$flags): void; - /** - * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search. - * @param string The String object or string literal on which to perform the search. - */ - exec(string: string): RegExp$matchResult | null; - /** - * Returns a string indicating the flags of the regular expression in question. This field is read-only. - * The characters in this string are sequenced and concatenated in the following order: - * - * - "g" for global - * - "i" for ignoreCase - * - "m" for multiline - * - "u" for unicode - * - "y" for sticky - * - * If no flags are set, the value is the empty string. - */ - flags: string; - /** Returns a Boolean value indicating the state of the global flag (g) used with a regular expression. Default is false. Read-only. */ - global: boolean; - /** Returns a Boolean value indicating the state of the ignoreCase flag (i) used with a regular expression. Default is false. Read-only. */ - ignoreCase: boolean; - lastIndex: number; - /** Returns a Boolean value indicating the state of the multiline flag (m) used with a regular expression. Default is false. Read-only. */ - multiline: boolean; - /** Returns a copy of the text of the regular expression pattern. Read-only. The regExp argument is a Regular expression object. It can be a variable name or a literal. */ - source: string; - /** - * Returns a Boolean value indicating the state of the sticky flag (y) used with a regular - * expression. Default is false. Read-only. - */ - sticky: boolean; - /** - * Returns a Boolean value indicating the state of the Unicode flag (u) used with a regular - * expression. Default is false. Read-only. - */ - unicode: boolean; - /** - * Returns a Boolean value indicating the state of the dotAll flag (s) used with a regular expression. - * Default is false. Read-only. - */ - dotAll: boolean; - /** - * Returns a Boolean value that indicates whether or not a pattern exists in a searched string. - * @param string String on which to perform the search. - */ - test(string: string): boolean; - toString(): string; - +[key: $SymbolMatch | $SymbolMatchAll]: (str: string) => Iterator -} - -/** Enables basic storage and retrieval of dates and times. */ -declare class Date { - constructor(): void; - constructor(timestamp: number): void; - constructor(date: Date): void; - constructor(dateString: string): void; - constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void; - /** Gets the day-of-the-month, using local time. */ - getDate(): number; - /** Gets the day of the week, using local time. */ - getDay(): number; - /** Gets the year, using local time. */ - getFullYear(): number; - /** Gets the hours in a date, using local time. */ - getHours(): number; - /** Gets the milliseconds of a Date, using local time. */ - getMilliseconds(): number; - /** Gets the minutes of a Date object, using local time. */ - getMinutes(): number; - /** Gets the month, using local time. */ - getMonth(): number; - /** Gets the seconds of a Date object, using local time. */ - getSeconds(): number; - /** Gets the time value in milliseconds. */ - getTime(): number; - /** Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). */ - getTimezoneOffset(): number; - /** Gets the day-of-the-month, using Universal Coordinated Time (UTC). */ - getUTCDate(): number; - /** Gets the day of the week using Universal Coordinated Time (UTC). */ - getUTCDay(): number; - /** Gets the year using Universal Coordinated Time (UTC). */ - getUTCFullYear(): number; - /** Gets the hours value in a Date object using Universal Coordinated Time (UTC). */ - getUTCHours(): number; - /** Gets the milliseconds of a Date object using Universal Coordinated Time (UTC). */ - getUTCMilliseconds(): number; - /** Gets the minutes of a Date object using Universal Coordinated Time (UTC). */ - getUTCMinutes(): number; - /** Gets the month of a Date object using Universal Coordinated Time (UTC). */ - getUTCMonth(): number; - /** Gets the seconds of a Date object using Universal Coordinated Time (UTC). */ - getUTCSeconds(): number; - /** - * Sets the numeric day-of-the-month value of the Date object using local time. - * @param date A numeric value equal to the day of the month. - */ - setDate(date: number): number; - /** - * Sets the year of the Date object using local time. - * @param year A numeric value for the year. - * @param month A zero-based numeric value for the month (0 for January, 11 for December). Must be specified if numDate is specified. - * @param date A numeric value equal for the day of the month. - */ - setFullYear(year: number, month?: number, date?: number): number; - /** - * Sets the hour value in the Date object using local time. - * @param hours A numeric value equal to the hours value. - * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. - * @param ms A numeric value equal to the milliseconds value. - */ - setHours(hours: number, min?: number, sec?: number, ms?: number): number; - /** - * Sets the milliseconds value in the Date object using local time. - * @param ms A numeric value equal to the millisecond value. - */ - setMilliseconds(ms: number): number; - /** - * Sets the minutes value in the Date object using local time. - * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. - * @param ms A numeric value equal to the milliseconds value. - */ - setMinutes(min: number, sec?: number, ms?: number): number; - /** - * Sets the month value in the Date object using local time. - * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. - * @param date A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used. - */ - setMonth(month: number, date?: number): number; - /** - * Sets the seconds value in the Date object using local time. - * @param sec A numeric value equal to the seconds value. - * @param ms A numeric value equal to the milliseconds value. - */ - setSeconds(sec: number, ms?: number): number; - /** - * Sets the date and time value in the Date object. - * @param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT. - */ - setTime(time: number): number; - /** - * Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC). - * @param date A numeric value equal to the day of the month. - */ - setUTCDate(date: number): number; - /** - * Sets the year value in the Date object using Universal Coordinated Time (UTC). - * @param year A numeric value equal to the year. - * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. Must be supplied if numDate is supplied. - * @param date A numeric value equal to the day of the month. - */ - setUTCFullYear(year: number, month?: number, date?: number): number; - /** - * Sets the hours value in the Date object using Universal Coordinated Time (UTC). - * @param hours A numeric value equal to the hours value. - * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. - * @param ms A numeric value equal to the milliseconds value. - */ - setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number; - /** - * Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC). - * @param ms A numeric value equal to the millisecond value. - */ - setUTCMilliseconds(ms: number): number; - /** - * Sets the minutes value in the Date object using Universal Coordinated Time (UTC). - * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. - * @param ms A numeric value equal to the milliseconds value. - */ - setUTCMinutes(min: number, sec?: number, ms?: number): number; - /** - * Sets the month value in the Date object using Universal Coordinated Time (UTC). - * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. - * @param date A numeric value representing the day of the month. If it is not supplied, the value from a call to the getUTCDate method is used. - */ - setUTCMonth(month: number, date?: number): number; - /** - * Sets the seconds value in the Date object using Universal Coordinated Time (UTC). - * @param sec A numeric value equal to the seconds value. - * @param ms A numeric value equal to the milliseconds value. - */ - setUTCSeconds(sec: number, ms?: number): number; - /** Returns a date as a string value. */ - toDateString(): string; - /** Returns a date as a string value in ISO format. */ - toISOString(): string; - /** Used by the JSON.stringify method to enable the transformation of an object's data for JavaScript Object Notation (JSON) serialization. */ - toJSON(key?: mixed): string; - /** - * Converts a date to a string by using the current or specified locale. - * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. - * @param options An object that contains one or more properties that specify comparison options. - */ - toLocaleDateString(locales?: string | Array, options?: Intl$DateTimeFormatOptions): string; - /** - * Converts a date and time to a string by using the current or specified locale. - * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. - * @param options An object that contains one or more properties that specify comparison options. - */ - toLocaleString(locales?: string | Array, options?: Intl$DateTimeFormatOptions): string; - /** - * Converts a time to a string by using the current or specified locale. - * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. - * @param options An object that contains one or more properties that specify comparison options. - */ - toLocaleTimeString(locales?: string | Array, options?: Intl$DateTimeFormatOptions): string; - /** Returns a time as a string value. */ - toTimeString(): string; - /** Returns a date converted to a string using Universal Coordinated Time (UTC). */ - toUTCString(): string; - /** Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. */ - valueOf(): number; - - static ():string; - static now(): number; - /** - * Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970. - * @param s A date string - */ - static parse(s: string): number; - /** - * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date. - * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year. - * @param month The month as a number between 0 and 11 (January to December). - * @param date The date as a number between 1 and 31. - * @param hours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour. - * @param minutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes. - * @param seconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds. - * @param ms A number from 0 to 999 that specifies the milliseconds. - */ - static UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number; - // multiple indexers not yet supported - [key: $SymbolToPrimitive]: (hint: 'string' | 'default' | 'number') => string | number; -} - -declare class CallSite { - getThis(): any; - getTypeName(): string; - getFunction(): ?((...any) => any); - getFunctionName(): string; - getMethodName(): string; - getFileName(): ?string; - getLineNumber(): ?number; - getColumnNumber(): ?number; - getEvalOrigin(): ?CallSite; - getScriptNameOrSourceURL(): ?string; - isToplevel(): bool; - isEval(): bool; - isNative(): bool; - isConstructor(): bool; - toString(): string; -} - -declare class Error { - static (message?:string):Error; - constructor (message?: mixed): void; - name: string; - message: string; - stack: string; - toString(): string; - - // note: microsoft only - description?: string; - number?: number; - - // note: mozilla only - fileName?: string; - lineNumber?: number; - columnNumber?: number; - - // note: v8 only (node/chrome) - static captureStackTrace(target: {[any] : any, ...}, constructor?: any): void; - - static stackTraceLimit: number; - static prepareStackTrace: (err: Error, stack: CallSite[]) => mixed; -} - -declare class EvalError extends Error { - static (message?:string):Error; -} - -declare class RangeError extends Error { - static (message?:string):Error; -} - -declare class ReferenceError extends Error { - static (message?:string):Error; -} - -declare class SyntaxError extends Error { - static (message?:string):Error; -} - -declare class TypeError extends Error { - static (message?:string):Error; -} - -declare class URIError extends Error { - static (message?:string):Error; -} - -/** - * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format. - */ -declare class JSON { - /** - * Converts a JavaScript Object Notation (JSON) string into an object. - * @param text A valid JSON string. - * @param reviver A function that transforms the results. This function is called for each member of the object. - * If a member contains nested objects, the nested objects are transformed before the parent object is. - */ - static parse(text: string, reviver?: (key: any, value: any) => any): any; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer A function that transforms the results or an array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified. - * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. - */ - static stringify( - value: null | string | number | boolean | {...} | $ReadOnlyArray, - replacer?: ?((key: string, value: any) => any) | Array, - space?: string | number - ): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer A function that transforms the results or an array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified. - * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. - */ - static stringify( - value: mixed, - replacer?: ?((key: string, value: any) => any) | Array, - space?: string | number - ): string | void; -} - -/* Iterable/Iterator/Generator */ - -type IteratorResult<+Yield,+Return> = - | { - done: true, - +value?: Return, - ... -} - | { - done: false, - +value: Yield, - ... -}; - -interface $Iterator<+Yield,+Return,-Next> { - @@iterator(): $Iterator; - next(value?: Next): IteratorResult; -} -type Iterator<+T> = $Iterator; - -interface $Iterable<+Yield,+Return,-Next> { - @@iterator(): $Iterator; -} -type Iterable<+T> = $Iterable; - -interface Generator<+Yield,+Return,-Next> { - @@iterator(): $Iterator; - next(value?: Next): IteratorResult; - return(value: R): IteratorResult; - throw(error?: any): IteratorResult; -} - -declare function $iterate(p: Iterable): T; - -/* Async Iterable/Iterator/Generator */ - -interface $AsyncIterator<+Yield,+Return,-Next> { - @@asyncIterator(): $AsyncIterator; - next(value?: Next): Promise>; -} -type AsyncIterator<+T> = $AsyncIterator; - -interface $AsyncIterable<+Yield,+Return,-Next> { - @@asyncIterator(): $AsyncIterator; -} -type AsyncIterable<+T> = $AsyncIterable; - -interface AsyncGenerator<+Yield,+Return,-Next> { - @@asyncIterator(): $AsyncIterator; - next(value?: Next): Promise>; - return(value: R): Promise>; - throw(error?: any): Promise>; -} - -declare function $asyncIterator(p: AsyncIterable): T; - -/* Maps and Sets */ - -declare class $ReadOnlyMap { - @@iterator(): Iterator<[K, V]>; - /** - * Returns an iterable of key, value pairs for every entry in the map. - */ - entries(): Iterator<[K, V]>; - forEach(callbackfn: (value: V, index: K, map: $ReadOnlyMap) => mixed, thisArg?: mixed): void; - get(key: K): V | void; - has(key: K): boolean; - /** - * Returns an iterable of keys in the map - */ - keys(): Iterator; - size: number; - /** - * Returns an iterable of values in the map - */ - values(): Iterator; -} - -declare class Map extends $ReadOnlyMap { - @@iterator(): Iterator<[K, V]>; - constructor(iterable: ?Iterable<[K, V]>): void; - clear(): void; - delete(key: K): boolean; - /** - * Returns an iterable of key, value pairs for every entry in the map. - */ - entries(): Iterator<[K, V]>; - forEach(callbackfn: (value: V, index: K, map: Map) => mixed, thisArg?: mixed): void; - get(key: K): V | void; - has(key: K): boolean; - /** - * Returns an iterable of keys in the map - */ - keys(): Iterator; - set(key: K, value: V): Map; - size: number; - /** - * Returns an iterable of values in the map - */ - values(): Iterator; - // Multiple Indexers not yet supported - +[key: $SymbolToStringTag]: any; - static +[key: $SymbolSpecies]: any; -} - -declare class $ReadOnlyWeakMap, +V> { - get(key: K): V | void; - has(key: K): boolean; -} - -declare class WeakMap, V> extends $ReadOnlyWeakMap { - constructor(iterable: ?Iterable<[K, V]>): void; - delete(key: K): boolean; - get(key: K): V | void; - has(key: K): boolean; - set(key: K, value: V): WeakMap; -} - -declare class $ReadOnlySet { - @@iterator(): Iterator; - /** - * Returns an iterable of [v,v] pairs for every value `v` in the set. - */ - entries(): Iterator<[T, T]>; - forEach(callbackfn: (value: T, index: T, set: $ReadOnlySet) => mixed, thisArg?: mixed): void; - has(value: T): boolean; - /** - * Despite its name, returns an iterable of the values in the set, - */ - keys(): Iterator; - size: number; - /** - * Returns an iterable of values in the set. - */ - values(): Iterator; -} - -declare class Set extends $ReadOnlySet { - @@iterator(): Iterator; - constructor(iterable: ?Iterable): void; - add(value: T): Set; - clear(): void; - delete(value: T): boolean; - /** - * Returns an iterable of [v,v] pairs for every value `v` in the set. - */ - entries(): Iterator<[T, T]>; - forEach(callbackfn: (value: T, index: T, set: Set) => mixed, thisArg?: mixed): void; - has(value: T): boolean; - /** - * Despite its name, returns an iterable of the values in the set, - */ - keys(): Iterator; - size: number; - /** - * Returns an iterable of values in the set. - */ - values(): Iterator; - +[key: $SymbolToStringTag]: (...any) => any; - static +[key: $SymbolSpecies]: (...any) => any; // This would the Set constructor, can't think of a way to correctly type this -} - -declare class $ReadOnlyWeakSet> { - has(value: T): boolean; -} - -declare class WeakSet> extends $ReadOnlyWeakSet { - constructor(iterable?: Iterable): void; - add(value: T): WeakSet; - delete(value: T): boolean; - has(value: T): boolean; -} - -/* Promises - cf. https://github.com/borisyankov/DefinitelyTyped/blob/master/es6-promises/es6-promises.d.ts -*/ -/** - * Represents the completion of an asynchronous operation - */ -declare class Promise<+R> { - constructor(callback: ( - resolve: (result: Promise | R) => void, - reject: (error: any) => void - ) => mixed): void; - - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onFulfill The callback to execute when the Promise is resolved. - * @param onReject The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onFulfill: null | void, onReject: null | void): Promise; - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onFulfill The callback to execute when the Promise is resolved. - * @param onReject The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then( - onFulfill: null | void, - onReject: (error: any) => Promise | U - ): Promise; - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onFulfill The callback to execute when the Promise is resolved. - * @param onReject The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then( - onFulfill: (value: R) => Promise | U, - onReject: null | void | ((error: any) => Promise | U) - ): Promise; - - /** - * Attaches a callback for only the rejection of the Promise. - * @param onReject The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch(onReject: null | void): Promise; - /** - * Attaches a callback for only the rejection of the Promise. - * @param onReject The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch( - onReject: (error: any) => Promise | U - ): Promise; - - /** - * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The - * resolved value cannot be modified from the callback. - * @param onFinally The callback to execute when the Promise is settled (fulfilled or rejected). - * @returns A Promise for the completion of the callback. - */ - finally(onFinally: () => mixed): Promise; - - /** - * Creates a new resolved promise for the provided value. - * @param object A promise. - * @returns A promise whose internal state matches the provided promise. - */ - static resolve(object: Promise | T): Promise; - /** - * Creates a new rejected promise for the provided reason. - * @param error The reason the promise was rejected. - * @returns A new rejected Promise. - */ - static reject(error: any): Promise; - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param promises An iterable of Promises. - * @returns A new Promise. - */ - static all>(promises: T): Promise<$TupleMap>; - /** - * Creates a Promise that is resolved with an array of results when all - * of the provided Promises resolve or reject. - * @param promises An array of Promises. - * @returns A new Promise. - */ - static allSettled>(promises: T): Promise<$TupleMap(p: Promise | T) => $SettledPromiseResult>>; - /** - * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved - * or rejected. - * @param promises An iterable of Promises. - * @returns A new Promise. - */ - static race | T>(promises: Iterable): Promise; -} - -type $SettledPromiseResult<+T> = {| - +status: 'fulfilled', - +value: T, -|} | {| - +status: 'rejected', - +reason: any, -|}; - -// we use this signature when typing await expressions -declare function $await(p: Promise | T): T; - -/* Binary data */ - -declare class ArrayBuffer { - static isView(arg: mixed): boolean; - constructor(byteLength: number): void; - byteLength: number; - slice(begin: number, end?: number): this; - static +[key: $SymbolSpecies]: Class; -} - -// This is a helper type to simplify the specification, it isn't an interface -// and there are no objects implementing it. -// https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView -type $ArrayBufferView = $TypedArray | DataView; - -// The TypedArray intrinsic object is a constructor function, but does not have -// a global name or appear as a property of the global object. -// http://www.ecma-international.org/ecma-262/6.0/#sec-%typedarray%-intrinsic-object -declare class $TypedArray { - /** - * The size in bytes of each element in the array. - */ - static BYTES_PER_ELEMENT: number; - static from(iterable: Iterable, mapFn?: (element: number) => number, thisArg?: mixed): this; - static of(...values: number[]): this; - - constructor(length: number): void; - constructor(typedArray: $TypedArray): void; - constructor(iterable: Iterable): void; - constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number): void; - - [index: number]: number; - - @@iterator(): Iterator; - - /** - * The ArrayBuffer instance referenced by the array. - */ - buffer: ArrayBuffer; - /** - * The length in bytes of the array. - */ - byteLength: number; - /** - * The offset in bytes of the array. - */ - byteOffset: number; - /** - * The length of the array. - */ - length: number; - - /** - * Returns the this object after copying a section of the array identified by start and end - * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it - * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. - */ - copyWithin(target: number, start: number, end?: number): void; - /** - * Returns an array of key, value pairs for every entry in the array - */ - entries(): Iterator<[number, number]>; - /** - * Determines whether all the members of an array satisfy the specified test. - * @param callback A function that accepts up to three arguments. The every method calls - * the predicate function for each element in the array until the predicate returns a value - * which is coercible to the Boolean value false, or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. - * If thisArg is omitted, undefined is used as the this value. - */ - every(callback: (value: number, index: number, array: this) => mixed, thisArg?: mixed): boolean; - /** - * Returns the this object after filling the section identified by start and end with value - * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as - * length+end. - */ - fill(value: number, start?: number, end?: number): this; - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callback A function that accepts up to three arguments. The filter method calls - * the predicate function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. - * If thisArg is omitted, undefined is used as the this value. - */ - filter(callback: (value: number, index: number, array: this) => mixed, thisArg?: mixed): this; - /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param callback find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - find(callback: (value: number, index: number, array: this) => mixed, thisArg?: mixed): number | void; - /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param callback find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - findIndex(callback: (value: number, index: number, array: this) => mixed, thisArg?: mixed): number; - /** - * Performs the specified action for each element in an array. - * @param callback A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - forEach(callback: (value: number, index: number, array: this) => mixed, thisArg?: mixed): void; - /** - * Determines whether an array includes a certain element, returning true or false as appropriate. - * @param searchElement The element to search for. - * @param fromIndex The position in this array at which to begin searching for searchElement. - */ - includes(searchElement: number, fromIndex?: number): boolean; - /** - * Returns the index of the first occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ - indexOf(searchElement: number, fromIndex?: number): number; // -1 if not present - /** - * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the - * resulting String. If omitted, the array elements are separated with a comma. - */ - join(separator?: string): string; - /** - * Returns an list of keys in the array - */ - keys(): Iterator; - /** - * Returns the index of the last occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ - lastIndexOf(searchElement: number, fromIndex?: number): number; // -1 if not present - /** - * Calls a defined callback function on each element of an array, and returns an array that - * contains the results. - * @param callback A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - map(callback: (currentValue: number, index: number, array: this) => number, thisArg?: mixed): this; - /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callback A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduce( - callback: (previousValue: number, currentValue: number, index: number, array: this) => number, - initialValue: void - ): number; - /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callback A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduce( - callback: (previousValue: U, currentValue: number, index: number, array: this) => U, - initialValue: U - ): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callback A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an - * argument instead of an array value. - */ - reduceRight( - callback: (previousValue: number, currentValue: number, index: number, array: this) => number, - initialValue: void - ): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callback A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an - * argument instead of an array value. - */ - reduceRight( - callback: (previousValue: U, currentValue: number, index: number, array: this) => U, - initialValue: U - ): U; - /** - * Reverses the elements in an Array. - */ - reverse(): this; - /** - * Sets a value or an array of values. - * @param array A typed or untyped array of values to set. - * @param offset The index in the current array at which the values are to be written. - */ - set(array: Array | $TypedArray, offset?: number): void; - /** - * Returns a section of an array. - * @param start The beginning of the specified portion of the array. - * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'. - */ - slice(begin?: number, end?: number): this; - /** - * Determines whether the specified callback function returns true for any element of an array. - * @param callback A function that accepts up to three arguments. The some method calls - * the predicate function for each element in the array until the predicate returns a value - * which is coercible to the Boolean value true, or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the predicate function. - * If thisArg is omitted, undefined is used as the this value. - */ - some(callback: (value: number, index: number, array: this) => mixed, thisArg?: mixed): boolean; - /** - * Sorts an array. - * @param compareFn Function used to determine the order of the elements. It is expected to return - * a negative value if first argument is less than second argument, zero if they're equal and a positive - * value otherwise. If omitted, the elements are sorted in ascending, ASCII character order. - * ```ts - * [11,2,22,1].sort((a, b) => a - b) - * ``` - */ - sort(compare?: (a: number, b: number) => number): void; - /** - * Gets a new Int8Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. - * @param begin The index of the beginning of the array. - * @param end The index of the end of the array. - */ - subarray(begin?: number, end?: number): this; - /** - * Returns an list of values in the array - */ - values(): Iterator; -} - -/** - * A typed array of 8-bit integer values. The contents are initialized to 0. If the requested - * number of bytes could not be allocated an exception is raised. - */ -declare class Int8Array extends $TypedArray {} -/** - * A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated an exception is raised. - */ -declare class Uint8Array extends $TypedArray {} -/** - * A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0. - * If the requested number of bytes could not be allocated an exception is raised. - */ -declare class Uint8ClampedArray extends $TypedArray {} -/** - * A typed array of 16-bit signed integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated an exception is raised. - */ -declare class Int16Array extends $TypedArray {} -/** - * A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated an exception is raised. - */ -declare class Uint16Array extends $TypedArray {} -/** - * A typed array of 32-bit signed integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated an exception is raised. - */ -declare class Int32Array extends $TypedArray {} -/** - * A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated an exception is raised. - */ -declare class Uint32Array extends $TypedArray {} -/** - * A typed array of 32-bit float values. The contents are initialized to 0. If the requested number - * of bytes could not be allocated an exception is raised. - */ -declare class Float32Array extends $TypedArray {} -/** - * A typed array of 64-bit float values. The contents are initialized to 0. If the requested - * number of bytes could not be allocated an exception is raised. - */ -declare class Float64Array extends $TypedArray {} - -declare class DataView { - constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number): void; - buffer: ArrayBuffer; - byteLength: number; - byteOffset: number; - /** - * Gets the Int8 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getInt8(byteOffset: number): number; - /** - * Gets the Uint8 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getUint8(byteOffset: number): number; - /** - * Gets the Int16 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getInt16(byteOffset: number, littleEndian?: boolean): number; - /** - * Gets the Uint16 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getUint16(byteOffset: number, littleEndian?: boolean): number; - /** - * Gets the Int32 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getInt32(byteOffset: number, littleEndian?: boolean): number; - /** - * Gets the Uint32 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getUint32(byteOffset: number, littleEndian?: boolean): number; - /** - * Gets the Float32 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getFloat32(byteOffset: number, littleEndian?: boolean): number; - /** - * Gets the Float64 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getFloat64(byteOffset: number, littleEndian?: boolean): number; - /** - * Stores an Int8 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - */ - setInt8(byteOffset: number, value: number): void; - /** - * Stores an Uint8 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - */ - setUint8(byteOffset: number, value: number): void; - /** - * Stores an Int16 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setInt16(byteOffset: number, value: number, littleEndian?: boolean): void; - /** - * Stores an Uint16 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setUint16(byteOffset: number, value: number, littleEndian?: boolean): void; - /** - * Stores an Int32 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setInt32(byteOffset: number, value: number, littleEndian?: boolean): void; - /** - * Stores an Uint32 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setUint32(byteOffset: number, value: number, littleEndian?: boolean): void; - /** - * Stores an Float32 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void; - /** - * Stores an Float64 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void; -} - -declare function btoa(rawString: string): string; -declare function atob(encodedString: string): string; - -declare function escape(str: string): string; -declare function unescape(str: string): string; - -declare opaque type TimeoutID; -declare opaque type IntervalID; -declare function clearInterval(intervalId: ?IntervalID): void; -declare function clearTimeout(timeoutId: ?TimeoutID): void; -declare function setTimeout>( - callback: (...args: TArguments) => mixed, - ms?: number, - ...args: TArguments -): TimeoutID; -declare function setInterval>( - callback: (...args: TArguments) => mixed, - ms?: number, - ...args: TArguments -): IntervalID; - -/* Reflect API */ - -declare var Reflect: { - apply(target: (...any) => any, thisArg?: any, argumentsList?: Array): any, - construct(target: (...any) => any, argumentsList?: Array, newTarget?: any): any, - defineProperty(o: any, p: any, attributes: any): boolean, - deleteProperty(o: any, p: any): boolean, - get(o: any, p: any, receiver?: any): any, - getOwnPropertyDescriptor(o: any, p: any): any, - getPrototypeOf: Object$GetPrototypeOf, - setPrototypeOf: Object$SetPrototypeOf, - has(o: any, p: any): boolean, - isExtensible(o: any): boolean, - ownKeys(o: any): Array, - preventExtensions(o: any): boolean, - set(o: any, p: any, value: any, receiver?: any): boolean, - ... -} - -/* Proxy */ - -type Proxy$traps = { - getPrototypeOf?: (target: T) => {[any] : any, ...} | null, - setPrototypeOf?: (target: T, prototype: {[any] : any, ...} | null) => boolean, - isExtensible?: (target: T) => boolean, - preventExtensions?: (target: T) => boolean, - getOwnPropertyDescriptor?: (target: T, property: string) => void | PropertyDescriptor, - defineProperty?: (target: T, property: string, descriptor: PropertyDescriptor) => boolean, - has?: (target: T, key: string) => boolean, - get?: (target: T, property: string, receiver: Proxy) => any, - set?: (target: T, property: string, value: any, receiver: Proxy) => boolean, - deleteProperty?: (target: T, property: string) => boolean, - ownKeys?: (target: T) => Array, - apply?: (target: T, context: any, args: Array) => any, - construct?: (target: T, args: Array, newTarget: (...any) => any) => {[any] : any, ...}, - ... -}; - -type Proxy$revocable = T & { revoke(): void, ... }; - -declare class Proxy { - constructor(target: T, handler: Proxy$traps): T; - - static revocable(target: T, handler: Proxy$traps): Proxy$revocable; -} - -/* CommonJS */ - -declare var global: any; - -declare var module: { - exports: any, - require(id: string): any, - id: string, - filename: string, - loaded: boolean, - parent: any, - children: Array, - builtinModules: Array, - ... -}; -declare var require: { - (id: string): any, - resolve: (id: string) => string, - cache: any, - main: typeof module, - ... -}; -declare var exports: any; - -/* Opaque type for module reference magic strings */ -declare opaque type $Flow$ModuleRef<+T>; - -/* Commonly available, shared between node and dom */ -declare var console: { - assert(condition: mixed, ...data: Array): void, - clear(): void, - count(label?: string): void, - countReset(label?: string): void, - debug(...data: Array): void, - dir(...data: Array): void, - dirxml(...data: Array): void, - error(...data: Array): void, - _exception(...data: Array): void, - group(...data: Array): void, - groupCollapsed(...data: Array): void, - groupEnd(): void, - info(...data: Array): void, - log(...data: Array): void, - profile(name?: string): void, - profileEnd(name?: string): void, - table(tabularData: { [key: string]: any, ... } | Array<{ [key: string]: any, ... }> | Array>): void, - time(label?: string): void, - timeEnd(label: string): void, - timeStamp(label?: string): void, - timeLog(label?: string, ...data?: Array): void, - trace(...data: Array): void, - warn(...data: Array): void, - ... -}; - -type $EnumProto = {| - cast(input: ?TRepresentation): void | TEnum, - isValid(input: ?TRepresentation): boolean, - members(): Iterable, - __proto__: null, -|} - -declare class SharedArrayBuffer { - constructor(byteLength: number): void; - - /** - * Read-only. The length of the ArrayBuffer (in bytes). - */ - +byteLength: number; - /** - * Returns a section of an SharedArrayBuffer. - */ - slice(begin?: number, end?: number): this; - - +[key: $SymbolToStringTag]: 'SharedArrayBuffer'; -} - -type $SharedIntegerTypedArray = - | Int8Array - | Uint8Array - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - -declare var Atomics: { - /** - * Adds a value to the value at the given position in the array, returning the original value. - * Until this atomic operation completes, any other read or write operation against the array - * will block. - */ - add(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - /** - * Stores the bitwise AND of a value with the value at the given position in the array, - * returning the original value. Until this atomic operation completes, any other read or - * write operation against the array will block. - */ - and(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - /** - * Replaces the value at the given position in the array if the original value equals the given - * expected value, returning the original value. Until this atomic operation completes, any - * other read or write operation against the array will block. - */ - compareExchange(typedArray: $SharedIntegerTypedArray, index: number, expectedValue: number, replacementValue: number): number, - /** - * Replaces the value at the given position in the array, returning the original value. Until - * this atomic operation completes, any other read or write operation against the array will - * block. - */ - exchange(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - /** - * Returns the value at the given position in the array. Until this atomic operation completes, - * any other read or write operation against the array will block. - */ - load(typedArray: $SharedIntegerTypedArray, index: number): number, - /** - * Stores the bitwise OR of a value with the value at the given position in the array, - * returning the original value. Until this atomic operation completes, any other read or write - * operation against the array will block. - */ - or(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - /** - * Stores a value at the given position in the array, returning the new value. Until this - * atomic operation completes, any other read or write operation against the array will block. - */ - store(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - /** - * Subtracts a value from the value at the given position in the array, returning the original - * value. Until this atomic operation completes, any other read or write operation against the - * array will block. - */ - sub(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - /** - * Stores the bitwise XOR of a value with the value at the given position in the array, - * returning the original value. Until this atomic operation completes, any other read or write - * operation against the array will block. - */ - xor(typedArray: $SharedIntegerTypedArray, index: number, value: number): number, - - /** - * Returns a value indicating whether high-performance algorithms can use atomic operations - * (`true`) or must use locks (`false`) for the given number of bytes-per-element of a typed - * array. - */ - isLockFree(size: number): boolean, - /** - * If the value at the given position in the array is equal to the provided value, the current - * agent is put to sleep causing execution to suspend until the timeout expires (returning - * `"timed-out"`) or until the agent is awoken (returning `"ok"`); otherwise, returns - * `"not-equal"`. - */ - wait(typedArray: Int32Array, index: number, value: number, timeout?: number): 'ok' | 'not-equal' | 'timed-out', - /** - * Wakes up sleeping agents that are waiting on the given index of the array, returning the - * number of agents that were awoken. - * @param typedArray A shared Int32Array. - * @param index The position in the typedArray to wake up on. - * @param count The number of sleeping agents to notify. Defaults to +Infinity. - */ - notify(typedArray: Int32Array, index: number, count: number): number, - - +[key: $SymbolToStringTag]: 'Atomics', - ... -}; diff --git a/flow-typed/intl.js b/flow-typed/intl.js deleted file mode 100644 index 275502858f..0000000000 --- a/flow-typed/intl.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -declare var Intl: { - Collator: Class, - DateTimeFormat: Class, - NumberFormat: Class, - PluralRules: ?Class, - getCanonicalLocales?: (locales?: Intl$Locales) => Intl$Locale[], - ... -} - -type Intl$Locale = string -type Intl$Locales = Intl$Locale | Intl$Locale[] - -declare class Intl$Collator { - constructor ( - locales?: Intl$Locales, - options?: Intl$CollatorOptions - ): Intl$Collator; - - static ( - locales?: Intl$Locales, - options?: Intl$CollatorOptions - ): Intl$Collator; - - compare (string, string): number; - - resolvedOptions (): { - locale: Intl$Locale, - usage: 'sort' | 'search', - sensitivity: 'base' | 'accent' | 'case' | 'variant', - ignorePunctuation: boolean, - collation: string, - numeric: boolean, - caseFirst?: 'upper' | 'lower' | 'false', - ... - }; - - static supportedLocalesOf (locales?: Intl$Locales): Intl$Locale[]; -} - -declare type Intl$CollatorOptions = { - localeMatcher?: 'lookup' | 'best fit', - usage?: 'sort' | 'search', - sensitivity?: 'base' | 'accent' | 'case' | 'variant', - ignorePunctuation?: boolean, - numeric?: boolean, - caseFirst?: 'upper' | 'lower' | 'false', - ... -} - -type FormatToPartsType = | 'day' | 'dayPeriod' | 'era' | 'hour' | 'literal' - | 'minute' | 'month' | 'second' | 'timeZoneName' | 'weekday' | 'year'; - -declare class Intl$DateTimeFormat { - constructor ( - locales?: Intl$Locales, - options?: Intl$DateTimeFormatOptions - ): Intl$DateTimeFormat; - - static ( - locales?: Intl$Locales, - options?: Intl$DateTimeFormatOptions - ): Intl$DateTimeFormat; - - format (value?: Date | number): string; - - formatToParts (value?: Date | number): Array<{ - type: FormatToPartsType, - value: string, - ... - }>; - - resolvedOptions (): { - locale: Intl$Locale, - calendar: string, - numberingSystem: string, - timeZone?: string, - hour12: boolean, - weekday?: 'narrow' | 'short' | 'long', - era?: 'narrow' | 'short' | 'long', - year?: 'numeric' | '2-digit', - month?: 'numeric' | '2-digit' | 'narrow' | 'short' | 'long', - day?: 'numeric' | '2-digit', - hour?: 'numeric' | '2-digit', - minute?: 'numeric' | '2-digit', - second?: 'numeric' | '2-digit', - timeZoneName?: 'short' | 'long', - ... - }; - - static supportedLocalesOf (locales?: Intl$Locales): Intl$Locale[]; -} - -declare type Intl$DateTimeFormatOptions = { - localeMatcher?: 'lookup' | 'best fit', - timeZone?: string, - hour12?: boolean, - formatMatcher?: 'basic' | 'best fit', - weekday?: 'narrow' | 'short' | 'long', - era?: 'narrow' | 'short' | 'long', - year?: 'numeric' | '2-digit', - month?: 'numeric' | '2-digit' | 'narrow' | 'short' | 'long', - day?: 'numeric' | '2-digit', - hour?: 'numeric' | '2-digit', - minute?: 'numeric' | '2-digit', - second?: 'numeric' | '2-digit', - timeZoneName?: 'short' | 'long', - ... -} - -declare class Intl$NumberFormat { - constructor ( - locales?: Intl$Locales, - options?: Intl$NumberFormatOptions - ): Intl$NumberFormat; - - static ( - locales?: Intl$Locales, - options?: Intl$NumberFormatOptions - ): Intl$NumberFormat; - - format (number): string; - - resolvedOptions (): { - locale: Intl$Locale, - numberingSystem: string, - style: 'decimal' | 'currency' | 'percent', - currency?: string, - currencyDisplay?: 'symbol' | 'code' | 'name', - useGrouping: boolean, - minimumIntegerDigits?: number, - minimumFractionDigits?: number, - maximumFractionDigits?: number, - minimumSignificantDigits?: number, - maximumSignificantDigits?: number, - ... - }; - - static supportedLocalesOf (locales?: Intl$Locales): Intl$Locale[]; -} - -declare type Intl$NumberFormatOptions = { - localeMatcher?: 'lookup' | 'best fit', - style?: 'decimal' | 'currency' | 'percent', - currency?: string, - currencyDisplay?: 'symbol' | 'code' | 'name', - useGrouping?: boolean, - minimumIntegerDigits?: number, - minimumFractionDigits?: number, - maximumFractionDigits?: number, - minimumSignificantDigits?: number, - maximumSignificantDigits?: number, - ... -} - -declare class Intl$PluralRules { - constructor ( - locales?: Intl$Locales, - options?: Intl$PluralRulesOptions - ): Intl$PluralRules; - - select (number): Intl$PluralRule; - - resolvedOptions (): { - locale: Intl$Locale, - type: 'cardinal' | 'ordinal', - minimumIntegerDigits?: number, - minimumFractionDigits?: number, - maximumFractionDigits?: number, - minimumSignificantDigits?: number, - maximumSignificantDigits?: number, - pluralCategories: Intl$PluralRule[], - ... - }; - - static supportedLocalesOf (locales?: Intl$Locales): Intl$Locale[]; -} - -type Intl$PluralRule = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other' - -declare type Intl$PluralRulesOptions = { - localeMatcher?: 'lookup' | 'best fit', - type?: 'cardinal' | 'ordinal', - minimumIntegerDigits?: number, - minimumFractionDigits?: number, - maximumFractionDigits?: number, - minimumSignificantDigits?: number, - maximumSignificantDigits?: number, - ... -} diff --git a/flow-typed/node.js b/flow-typed/node.js deleted file mode 100644 index 590d9bf18e..0000000000 --- a/flow-typed/node.js +++ /dev/null @@ -1,5 +0,0 @@ -declare class Process { - env : { [key: string] : string | void, ... }; -} - -declare var process: Process; diff --git a/flow-typed/npm/chai_vx.x.x.js b/flow-typed/npm/chai_vx.x.x.js deleted file mode 100644 index aa4cbe8e4f..0000000000 --- a/flow-typed/npm/chai_vx.x.x.js +++ /dev/null @@ -1,331 +0,0 @@ -declare module 'chai' { - declare type ExpectChain = { - and: ExpectChain, - at: ExpectChain, - be: ExpectChain, - been: ExpectChain, - have: ExpectChain, - has: ExpectChain, - is: ExpectChain, - of: ExpectChain, - same: ExpectChain, - that: ExpectChain, - to: ExpectChain, - which: ExpectChain, - with: ExpectChain, - not: ExpectChain, - deep: ExpectChain, - any: ExpectChain, - all: ExpectChain, - own: ExpectChain, - a: ExpectChain & ((type: string, message?: string) => ExpectChain), - an: ExpectChain & ((type: string, message?: string) => ExpectChain), - include: ExpectChain & - ((value: mixed, message?: string) => ExpectChain), - includes: ExpectChain & - ((value: mixed, message?: string) => ExpectChain), - contain: ExpectChain & - ((value: mixed, message?: string) => ExpectChain), - contains: ExpectChain & - ((value: mixed, message?: string) => ExpectChain), - eq: (value: T, message?: string) => ExpectChain, - eql: (value: T, message?: string) => ExpectChain, - equal: (value: T, message?: string) => ExpectChain, - equals: (value: T, message?: string) => ExpectChain, - above: (value: T & number, message?: string) => ExpectChain, - gt: (value: T & number, message?: string) => ExpectChain, - greaterThan: (value: T & number, message?: string) => ExpectChain, - least: (value: T & number, message?: string) => ExpectChain, - below: (value: T & number, message?: string) => ExpectChain, - lessThan: (value: T & number, message?: string) => ExpectChain, - lt: (value: T & number, message?: string) => ExpectChain, - most: (value: T & number, message?: string) => ExpectChain, - within: ( - start: T & number, - finish: T & number, - message?: string, - ) => ExpectChain, - instanceof: (constructor: mixed, message?: string) => ExpectChain, - instanceOf: (constructor: mixed, message?: string) => ExpectChain, - nested: ExpectChain, - property:

( - name: string, - value?: P, - message?: string, - ) => ExpectChain

& ((name: string) => ExpectChain), - length: ExpectChain & - ((value: number, message?: string) => ExpectChain), - lengthOf: ExpectChain & - ((value: number, message?: string) => ExpectChain), - match: (regex: RegExp, message?: string) => ExpectChain, - matches: (regex: RegExp, message?: string) => ExpectChain, - string: (string: string, message?: string) => ExpectChain, - key: (key: string) => ExpectChain, - keys: ( - key: string | Array, - ...keys: Array - ) => ExpectChain, - throw: ( - err?: Class | Error | RegExp | string, - errMsgMatcher?: RegExp | string, - msg?: string, - ) => ExpectChain, - respondTo: (method: string, message?: string) => ExpectChain, - itself: ExpectChain, - satisfy: ( - method: (value: T) => boolean, - message?: string, - ) => ExpectChain, - closeTo: ( - expected: T & number, - delta: number, - message?: string, - ) => ExpectChain, - members: (set: mixed, message?: string) => ExpectChain, - oneOf: (list: Array, message?: string) => ExpectChain, - change: (obj: mixed, key: string, message?: string) => ExpectChain, - increase: (obj: mixed, key: string, message?: string) => ExpectChain, - decrease: (obj: mixed, key: string, message?: string) => ExpectChain, - by: (delta: number, message?: string) => ExpectChain, - ordered: ExpectChain, - // dirty-chai - ok: () => ExpectChain, - true: () => ExpectChain, - false: () => ExpectChain, - null: () => ExpectChain, - undefined: () => ExpectChain, - exist: () => ExpectChain, - empty: () => ExpectChain, - extensible: () => ExpectChain, - sealed: () => ExpectChain, - frozen: () => ExpectChain, - NaN: () => ExpectChain, - // chai-immutable - size: (n: number) => ExpectChain, - // sinon-chai - called: () => ExpectChain, - callCount: (n: number) => ExpectChain, - calledOnce: () => ExpectChain, - calledTwice: () => ExpectChain, - calledThrice: () => ExpectChain, - calledBefore: (spy: mixed) => ExpectChain, - calledAfter: (spy: mixed) => ExpectChain, - calledImmediatelyBefore: (spy: mixed) => ExpectChain, - calledImmediatelyAfter: (spy: mixed) => ExpectChain, - calledWith: (...args: Array) => ExpectChain, - calledOnceWith: (...args: Array) => ExpectChain, - calledWithMatch: (...args: Array) => ExpectChain, - calledWithExactly: (...args: Array) => ExpectChain, - calledOnceWithExactly: (...args: Array) => ExpectChain, - returned: (returnVal: mixed) => ExpectChain, - alwaysReturned: (returnVal: mixed) => ExpectChain, - // chai-as-promised - eventually: ExpectChain, - resolvedWith: (value: mixed) => Promise & ExpectChain, - resolved: () => Promise & ExpectChain, - rejectedWith: ( - value: mixed, - errMsgMatcher?: RegExp | string, - msg?: string, - ) => Promise & ExpectChain, - rejected: () => Promise & ExpectChain, - notify: (callback: () => mixed) => ExpectChain, - fulfilled: () => Promise & ExpectChain, - // chai-subset - containSubset: (obj: { ... } | Array<{ ... }>) => ExpectChain, - // chai-redux-mock-store - dispatchedActions: ( - actions: Array<{ ... } | ((action: { ... }) => any)>, - ) => ExpectChain, - dispatchedTypes: (actions: Array) => ExpectChain, - // chai-enzyme - attr: (key: string, val?: any) => ExpectChain, - data: (key: string, val?: any) => ExpectChain, - prop: (key: string, val?: any) => ExpectChain, - state: (key: string, val?: any) => ExpectChain, - value: (val: string) => ExpectChain, - className: (val: string) => ExpectChain, - text: (val: string) => ExpectChain, - // chai-karma-snapshot - matchSnapshot: (lang?: any, update?: boolean, msg?: any) => ExpectChain, - ... - }; - - declare var expect: { - (actual: T, message?: string): ExpectChain, - fail: ((message?: string) => void) & - (( - actual: any, - expected: any, - message?: string, - operator?: string, - ) => void), - ... - }; - - declare function use(plugin: (chai: Object, utils: Object) => void): void; - - declare class assert { - static (expression: mixed, message?: string): void; - static fail( - actual: mixed, - expected: mixed, - message?: string, - operator?: string, - ): void; - - static isOk(object: mixed, message?: string): void; - static isNotOk(object: mixed, message?: string): void; - - static empty(object: mixed, message?: string): void; - static isEmpty(object: mixed, message?: string): void; - static notEmpty(object: mixed, message?: string): void; - static isNotEmpty(object: mixed, message?: string): void; - - static equal(actual: mixed, expected: mixed, message?: string): void; - static notEqual(actual: mixed, expected: mixed, message?: string): void; - - static strictEqual(act: mixed, exp: mixed, msg?: string): void; - static notStrictEqual(act: mixed, exp: mixed, msg?: string): void; - - static deepEqual(act: mixed, exp: mixed, msg?: string): void; - static notDeepEqual(act: mixed, exp: mixed, msg?: string): void; - - static ok(val: mixed, msg?: string): void; - static isTrue(val: mixed, msg?: string): void; - static isNotTrue(val: mixed, msg?: string): void; - static isFalse(val: mixed, msg?: string): void; - static isNotFalse(val: mixed, msg?: string): void; - - static isNull(val: mixed, msg?: string): void; - static isNotNull(val: mixed, msg?: string): void; - - static isUndefined(val: mixed, msg?: string): void; - static isDefined(val: mixed, msg?: string): void; - - static isNaN(val: mixed, msg?: string): void; - static isNotNaN(val: mixed, msg?: string): void; - - static isAbove(val: number, abv: number, msg?: string): void; - static isBelow(val: number, blw: number, msg?: string): void; - - static exists(val: mixed, msg?: string): void; - static notExists(val: mixed, msg?: string): void; - - static isAtMost(val: number, atmst: number, msg?: string): void; - static isAtLeast(val: number, atlst: number, msg?: string): void; - - static isFunction(val: mixed, msg?: string): void; - static isNotFunction(val: mixed, msg?: string): void; - - static isObject(val: mixed, msg?: string): void; - static isNotObject(val: mixed, msg?: string): void; - - static isArray(val: mixed, msg?: string): void; - static isNotArray(val: mixed, msg?: string): void; - - static isString(val: mixed, msg?: string): void; - static isNotString(val: mixed, msg?: string): void; - - static isNumber(val: mixed, msg?: string): void; - static isNotNumber(val: mixed, msg?: string): void; - - static isBoolean(val: mixed, msg?: string): void; - static isNotBoolean(val: mixed, msg?: string): void; - - static typeOf(val: mixed, type: string, msg?: string): void; - static notTypeOf(val: mixed, type: string, msg?: string): void; - - static instanceOf(val: mixed, constructor: Class<*>, msg?: string): void; - static notInstanceOf(val: mixed, constructor: Class<*>, msg?: string): void; - - static include(exp: string, inc: mixed, msg?: string): void; - static include(exp: Array, inc: T, msg?: string): void; - - static notInclude(exp: string, inc: mixed, msg?: string): void; - static notInclude(exp: Array, inc: T, msg?: string): void; - - static deepInclude( - haystack: T[] | string, - needle: $Shape, - msg?: string, - ): void; - static notDeepInclude( - haystack: T[] | string, - needle: $Shape, - msg?: string, - ): void; - - static match(exp: mixed, re: RegExp, msg?: string): void; - static notMatch(exp: mixed, re: RegExp, msg?: string): void; - - static property(obj: Object, prop: string, msg?: string): void; - static notProperty(obj: Object, prop: string, msg?: string): void; - static deepProperty(obj: Object, prop: string, msg?: string): void; - static notDeepProperty(obj: Object, prop: string, msg?: string): void; - - static propertyVal( - obj: Object, - prop: string, - val: mixed, - msg?: string, - ): void; - static propertyNotVal( - obj: Object, - prop: string, - val: mixed, - msg?: string, - ): void; - - static deepPropertyVal( - obj: Object, - prop: string, - val: mixed, - msg?: string, - ): void; - static deepPropertyNotVal( - obj: Object, - prop: string, - val: mixed, - msg?: string, - ): void; - - static lengthOf(exp: mixed, len: number, msg?: string): void; - - static throws( - func: () => any, - err?: Class | Error | RegExp | string, - errorMsgMatcher?: string | RegExp, - msg?: string, - ): void; - static doesNotThrow( - func: () => any, - err?: Class | Error | RegExp | string, - errorMsgMatcher?: string | RegExp, - msg?: string, - ): void; - - static closeTo( - actual: number, - expected: number, - delta: number, - msg?: string, - ): void; - static approximately( - actual: number, - expected: number, - delta: number, - msg?: string, - ): void; - - // chai-immutable - static sizeOf(val: mixed, length: number): void; - } - - declare var config: { - includeStack: boolean, - showDiff: boolean, - truncateThreshold: number, - ... - }; -} diff --git a/flow-typed/npm/mocha_vx.x.x.js b/flow-typed/npm/mocha_vx.x.x.js deleted file mode 100644 index f83b48a0b1..0000000000 --- a/flow-typed/npm/mocha_vx.x.x.js +++ /dev/null @@ -1,316 +0,0 @@ -declare interface $npm$mocha$SetupOptions { - slow?: number; - timeout?: number; - ui?: string; - globals?: Array; - reporter?: any; - bail?: boolean; - ignoreLeaks?: boolean; - grep?: any; -} - -declare type $npm$mocha$done = (error?: any) => any; - -// declare interface $npm$mocha$SuiteCallbackContext { -// timeout(ms: number): void; -// retries(n: number): void; -// slow(ms: number): void; -// } - -// declare interface $npm$mocha$TestCallbackContext { -// skip(): void; -// timeout(ms: number): void; -// retries(n: number): void; -// slow(ms: number): void; -// [index: string]: any; -// } - -declare interface $npm$mocha$Suite { - parent: $npm$mocha$Suite; - title: string; - fullTitle(): string; -} - -declare type $npm$mocha$ContextDefinition = {| - ( - description: string, - callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void, - ): $npm$mocha$Suite, - only( - description: string, - callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void, - ): $npm$mocha$Suite, - skip( - description: string, - callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void, - ): void, - timeout(ms: number): void, -|}; - -declare type $npm$mocha$TestDefinition = {| - ( - expectation: string, - callback?: ( - /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done, - ) => mixed, - ): $npm$mocha$Test, - only( - expectation: string, - callback?: ( - /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done, - ) => mixed, - ): $npm$mocha$Test, - skip( - expectation: string, - callback?: ( - /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done, - ) => mixed, - ): void, - timeout(ms: number): void, - state: 'failed' | 'passed', -|}; - -declare interface $npm$mocha$Runner {} - -declare class $npm$mocha$BaseReporter { - stats: { - suites: number, - tests: number, - passes: number, - pending: number, - failures: number, - ... - }; - - constructor(runner: $npm$mocha$Runner): $npm$mocha$BaseReporter; -} - -declare class $npm$mocha$DocReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$DotReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$HTMLReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$HTMLCovReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$JSONReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$JSONCovReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$JSONStreamReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$LandingReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$ListReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$MarkdownReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$MinReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$NyanReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$ProgressReporter extends $npm$mocha$BaseReporter { - constructor( - runner: $npm$mocha$Runner, - options?: { - open?: string, - complete?: string, - incomplete?: string, - close?: string, - ... - }, - ): $npm$mocha$ProgressReporter; -} -declare class $npm$mocha$SpecReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$TAPReporter extends $npm$mocha$BaseReporter {} -declare class $npm$mocha$XUnitReporter extends $npm$mocha$BaseReporter { - constructor( - runner: $npm$mocha$Runner, - options?: any, - ): $npm$mocha$XUnitReporter; -} - -declare class $npm$mocha$Mocha { - currentTest: $npm$mocha$TestDefinition; - constructor(options?: { - grep?: RegExp, - ui?: string, - reporter?: string, - timeout?: number, - reporterOptions?: any, - slow?: number, - bail?: boolean, - ... - }): $npm$mocha$Mocha; - setup(options: $npm$mocha$SetupOptions): this; - bail(value?: boolean): this; - addFile(file: string): this; - reporter(name: string): this; - reporter(reporter: (runner: $npm$mocha$Runner, options: any) => any): this; - ui(value: string): this; - grep(value: string): this; - grep(value: RegExp): this; - invert(): this; - ignoreLeaks(value: boolean): this; - checkLeaks(): this; - throwError(error: Error): void; - growl(): this; - globals(value: string): this; - globals(values: Array): this; - useColors(value: boolean): this; - useInlineDiffs(value: boolean): this; - timeout(value: number): this; - slow(value: number): this; - enableTimeouts(value: boolean): this; - asyncOnly(value: boolean): this; - noHighlighting(value: boolean): this; - run(onComplete?: (failures: number) => void): $npm$mocha$Runner; - - static reporters: { - Doc: $npm$mocha$DocReporter, - Dot: $npm$mocha$DotReporter, - HTML: $npm$mocha$HTMLReporter, - HTMLCov: $npm$mocha$HTMLCovReporter, - JSON: $npm$mocha$JSONReporter, - JSONCov: $npm$mocha$JSONCovReporter, - JSONStream: $npm$mocha$JSONStreamReporter, - Landing: $npm$mocha$LandingReporter, - List: $npm$mocha$ListReporter, - Markdown: $npm$mocha$MarkdownReporter, - Min: $npm$mocha$MinReporter, - Nyan: $npm$mocha$NyanReporter, - Progress: $npm$mocha$ProgressReporter, - ... - }; -} - -// declare interface $npm$mocha$HookCallbackContext { -// skip(): void; -// timeout(ms: number): void; -// [index: string]: any; -// } - -declare interface $npm$mocha$Runnable { - title: string; - fn: Function; - async: boolean; - sync: boolean; - timedOut: boolean; -} - -declare interface $npm$mocha$Test extends $npm$mocha$Runnable { - parent: $npm$mocha$Suite; - pending: boolean; - state: 'failed' | 'passed' | void; - fullTitle(): string; - timeout(ms: number): void; -} - -// declare interface $npm$mocha$BeforeAndAfterContext extends $npm$mocha$HookCallbackContext { -// currentTest: $npm$mocha$Test; -// } - -declare var mocha: $npm$mocha$Mocha; -declare var describe: $npm$mocha$ContextDefinition; -declare var xdescribe: $npm$mocha$ContextDefinition; -declare var context: $npm$mocha$ContextDefinition; -declare var suite: $npm$mocha$ContextDefinition; -declare var it: $npm$mocha$TestDefinition; -declare var xit: $npm$mocha$TestDefinition; -declare var test: $npm$mocha$TestDefinition; -declare var specify: $npm$mocha$TestDefinition; - -type Run = () => void; - -declare var run: Run; - -type Setup = ( - callback: ( - /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done, - ) => mixed, -) => void; -type Teardown = ( - callback: ( - /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done, - ) => mixed, -) => void; -type SuiteSetup = ( - callback: ( - /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done, - ) => mixed, -) => void; -type SuiteTeardown = ( - callback: ( - /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done, - ) => mixed, -) => void; -type Before = ( - callback: ( - /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done, - ) => mixed, -) => - | void - | (( - description: string, - callback: ( - /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done, - ) => mixed, - ) => void); -type After = ( - callback: ( - /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done, - ) => mixed, -) => - | void - | (( - description: string, - callback: ( - /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done, - ) => mixed, - ) => void); -type BeforeEach = ( - callback: ( - /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done, - ) => mixed, -) => - | void - | (( - description: string, - callback: ( - /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done, - ) => mixed, - ) => void); -type AfterEach = ( - callback: ( - /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done, - ) => mixed, -) => - | void - | (( - description: string, - callback: ( - /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done, - ) => mixed, - ) => void); - -declare var setup: Setup; -declare var teardown: Teardown; -declare var suiteSetup: SuiteSetup; -declare var suiteTeardown; -declare var before: Before; -declare var after: After; -declare var beforeEach: BeforeEach; -declare var afterEach: AfterEach; - -declare module 'mocha' { - declare export var mocha: $npm$mocha$TestDefinition; - declare export var describe: $npm$mocha$ContextDefinition; - declare export var xdescribe: $npm$mocha$ContextDefinition; - declare export var context: $npm$mocha$ContextDefinition; - declare export var suite: $npm$mocha$ContextDefinition; - declare export var it: $npm$mocha$TestDefinition; - declare export var xit: $npm$mocha$TestDefinition; - declare export var test: $npm$mocha$TestDefinition; - declare export var specify: $npm$mocha$TestDefinition; - - declare export var run: Run; - - declare export var setup: Setup; - declare export var teardown: Teardown; - declare export var suiteSetup: SuiteSetup; - declare export var suiteTeardown: SuiteTeardown; - declare export var before: Before; - declare export var after: After; - declare export var beforeEach: BeforeEach; - declare export var afterEach: AfterEach; - - declare export default $npm$mocha$Mocha; -} diff --git a/integrationTests/flow/.flowconfig b/integrationTests/flow/.flowconfig deleted file mode 100644 index 872c3947a6..0000000000 --- a/integrationTests/flow/.flowconfig +++ /dev/null @@ -1,8 +0,0 @@ -[include] -./index.mjs - -[declarations] -.*/node_modules/.* - -[options] -include_warnings=true diff --git a/integrationTests/flow/index.mjs b/integrationTests/flow/index.mjs deleted file mode 100644 index ee14390b35..0000000000 --- a/integrationTests/flow/index.mjs +++ /dev/null @@ -1,54 +0,0 @@ -// @flow strict - -import { parse } from 'graphql/language'; -import { GraphQLString, GraphQLSchema, GraphQLObjectType } from 'graphql/type'; -import { type ExecutionResult, execute } from 'graphql/execution'; -import { graphqlSync } from 'graphql'; - -interface SomeExtension { - number: number; - string: string; -} - -const example: SomeExtension = { - number: 42, - string: 'Meaning of life', -}; - -const queryType: GraphQLObjectType = new GraphQLObjectType({ - name: 'Query', - fields: { - sayHi: { - type: GraphQLString, - args: { - who: { - type: GraphQLString, - extensions: { - someArgumentExtension: example, - }, - }, - }, - resolve: (_root, args) => 'Hello ' + (args.who || 'World'), - extensions: { - someFieldExtension: example, - }, - }, - }, - extensions: { - someObjectExtension: example, - }, -}); - -const schema: GraphQLSchema = new GraphQLSchema({ - query: queryType, -}); - -const result: ExecutionResult = graphqlSync({ - schema, - source: ` - query helloWho($who: String){ - test(who: $who) - } - `, - variableValues: { who: 'Dolly' }, -}); diff --git a/integrationTests/flow/package.json b/integrationTests/flow/package.json deleted file mode 100644 index 8a87590458..0000000000 --- a/integrationTests/flow/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "private": true, - "scripts": { - "test": "flow check" - }, - "dependencies": { - "graphql": "file:../graphql.tgz", - "flow-bin": "0.135.0" - } -} diff --git a/integrationTests/integration-test.js b/integrationTests/integration-test.js index 9c6ca461be..df27b801a7 100644 --- a/integrationTests/integration-test.js +++ b/integrationTests/integration-test.js @@ -39,10 +39,6 @@ describe('Integration Tests', () => { testOnNodeProject('ts'); }).timeout(40000); - it('Should compile with Flow', () => { - testOnNodeProject('flow'); - }).timeout(10000); - it('Should work on all supported node versions', () => { testOnNodeProject('node'); }).timeout(40000); diff --git a/package-lock.json b/package-lock.json index 5695d63c7c..5d2571de7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,20 +11,22 @@ "devDependencies": { "@babel/core": "7.14.0", "@babel/eslint-parser": "7.13.14", - "@babel/plugin-transform-flow-strip-types": "7.13.0", + "@babel/plugin-syntax-typescript": "7.12.13", + "@babel/plugin-transform-typescript": "7.13.0", "@babel/preset-env": "7.14.1", "@babel/register": "7.13.16", + "@types/chai": "4.2.18", + "@types/mocha": "8.2.2", + "@types/node": "15.3.0", "@typescript-eslint/eslint-plugin": "4.22.1", "@typescript-eslint/parser": "4.22.1", "chai": "4.3.4", "cspell": "5.4.0", "eslint": "7.25.0", - "eslint-plugin-flowtype": "5.6.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-internal-rules": "file:./resources/eslint-internal-rules", "eslint-plugin-istanbul": "0.1.2", "eslint-plugin-node": "11.1.0", - "flow-bin": "0.150.0", "mocha": "8.3.2", "nyc": "15.1.0", "prettier": "2.3.0", @@ -666,18 +668,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz", - "integrity": "sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -786,6 +776,18 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz", + "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", @@ -916,19 +918,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.13.0.tgz", - "integrity": "sha512-EXAGFMJgSX8gxWD7PZtW/P6M+z74jpx3wm/+9pn+c2dOawPpBkUX7BrfyPvo6ZpXbgRIEuwgwDb/MGlKvu2pOg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-flow": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", @@ -1182,6 +1171,20 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz", + "integrity": "sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-typescript": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", @@ -1771,6 +1774,12 @@ "node": ">= 8" } }, + "node_modules/@types/chai": { + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.18.tgz", + "integrity": "sha512-rS27+EkB/RE1Iz3u0XtVL5q36MGDWbgYe7zWiodyKNUnthxY0rukK5V36eiUCtCisB7NN8zKYH6DO2M37qxFEQ==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", @@ -1783,6 +1792,18 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "node_modules/@types/mocha": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", + "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", + "dev": true + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -3149,22 +3170,6 @@ "eslint": ">=4.19.1" } }, - "node_modules/eslint-plugin-flowtype": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.6.0.tgz", - "integrity": "sha512-XbeDejiL+SecDInj9On/9D4EM31kUp6B3uWYsBH6Vsb2CfaFWiUHvosAZx1TafVjp6izLC7D3kpix1DIpDF4Qw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15", - "string-natural-compare": "^3.0.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.1.0" - } - }, "node_modules/eslint-plugin-import": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", @@ -3718,18 +3723,6 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "node_modules/flow-bin": { - "version": "0.150.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.150.0.tgz", - "integrity": "sha512-s+0dcKJnZZO6mkS92YtJzBZ6vq7i1o77+NggEiiefPpCVsehwPlyRLmEnb6XN9OI5OfXp+kFnZt4q8a3zLNuUg==", - "dev": true, - "bin": { - "flow": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -6346,12 +6339,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "node_modules/string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", - "dev": true - }, "node_modules/string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -7567,15 +7554,6 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, - "@babel/plugin-syntax-flow": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz", - "integrity": "sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -7657,6 +7635,15 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-syntax-typescript": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz", + "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, "@babel/plugin-transform-arrow-functions": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", @@ -7757,16 +7744,6 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.13.0.tgz", - "integrity": "sha512-EXAGFMJgSX8gxWD7PZtW/P6M+z74jpx3wm/+9pn+c2dOawPpBkUX7BrfyPvo6ZpXbgRIEuwgwDb/MGlKvu2pOg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-flow": "^7.12.13" - } - }, "@babel/plugin-transform-for-of": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", @@ -7960,6 +7937,17 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-transform-typescript": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz", + "integrity": "sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-typescript": "^7.12.13" + } + }, "@babel/plugin-transform-unicode-escapes": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", @@ -8496,6 +8484,12 @@ "fastq": "^1.6.0" } }, + "@types/chai": { + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.18.tgz", + "integrity": "sha512-rS27+EkB/RE1Iz3u0XtVL5q36MGDWbgYe7zWiodyKNUnthxY0rukK5V36eiUCtCisB7NN8zKYH6DO2M37qxFEQ==", + "dev": true + }, "@types/json-schema": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", @@ -8508,6 +8502,18 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/mocha": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "@types/node": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", + "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", + "dev": true + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -9626,16 +9632,6 @@ "regexpp": "^3.0.0" } }, - "eslint-plugin-flowtype": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.6.0.tgz", - "integrity": "sha512-XbeDejiL+SecDInj9On/9D4EM31kUp6B3uWYsBH6Vsb2CfaFWiUHvosAZx1TafVjp6izLC7D3kpix1DIpDF4Qw==", - "dev": true, - "requires": { - "lodash": "^4.17.15", - "string-natural-compare": "^3.0.1" - } - }, "eslint-plugin-import": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", @@ -9960,12 +9956,6 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "flow-bin": { - "version": "0.150.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.150.0.tgz", - "integrity": "sha512-s+0dcKJnZZO6mkS92YtJzBZ6vq7i1o77+NggEiiefPpCVsehwPlyRLmEnb6XN9OI5OfXp+kFnZt4q8a3zLNuUg==", - "dev": true - }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -11904,12 +11894,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", - "dev": true - }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", diff --git a/package.json b/package.json index 83a417541f..a8f39a4495 100644 --- a/package.json +++ b/package.json @@ -26,13 +26,13 @@ "scripts": { "preversion": ". ./resources/checkgit.sh && npm ci", "version": "node resources/gen-version.js && npm test && git add src/version.js", - "fuzzonly": "mocha --full-trace src/**/__tests__/**/*-fuzz.js", + "fuzzonly": "mocha --full-trace src/**/__tests__/**/*-fuzz.ts", "changelog": "node resources/gen-changelog.js", "benchmark": "node benchmark/benchmark.js", "test": "npm run lint && npm run check && npm run testonly && npm run prettier:check && npm run check:spelling && npm run check:integrations", "lint": "eslint --cache .", - "check": "flow check", - "testonly": "mocha --full-trace src/**/__tests__/**/*-test.js", + "check": "tsc --pretty", + "testonly": "mocha --full-trace src/**/__tests__/**/*-test.ts", "testonly:cover": "nyc npm run testonly", "prettier": "prettier --write --list-different .", "prettier:check": "prettier --check .", @@ -46,20 +46,22 @@ "devDependencies": { "@babel/core": "7.14.0", "@babel/eslint-parser": "7.13.14", - "@babel/plugin-transform-flow-strip-types": "7.13.0", + "@babel/plugin-syntax-typescript": "7.12.13", + "@babel/plugin-transform-typescript": "7.13.0", "@babel/preset-env": "7.14.1", "@babel/register": "7.13.16", + "@types/chai": "4.2.18", + "@types/mocha": "8.2.2", + "@types/node": "15.3.0", "@typescript-eslint/eslint-plugin": "4.22.1", "@typescript-eslint/parser": "4.22.1", "chai": "4.3.4", "cspell": "5.4.0", "eslint": "7.25.0", - "eslint-plugin-flowtype": "5.6.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-internal-rules": "file:./resources/eslint-internal-rules", "eslint-plugin-istanbul": "0.1.2", "eslint-plugin-node": "11.1.0", - "flow-bin": "0.150.0", "mocha": "8.3.2", "nyc": "15.1.0", "prettier": "2.3.0", diff --git a/resources/build-deno.js b/resources/build-deno.js index 83c352b01b..66f3c3e3a1 100644 --- a/resources/build-deno.js +++ b/resources/build-deno.js @@ -22,12 +22,10 @@ if (require.main === module) { const destPath = path.join('./denoDist', filepath); fs.mkdirSync(path.dirname(destPath), { recursive: true }); - if (filepath.endsWith('.js')) { + if (filepath.endsWith('.ts')) { const options = { babelrc: false, configFile: './.babelrc-deno.json' }; const output = babel.transformFileSync(srcPath, options).code + '\n'; writeGeneratedFile(destPath, output); - } else if (filepath.endsWith('.d.ts')) { - fs.copyFileSync(srcPath, destPath); } } diff --git a/resources/build-npm.js b/resources/build-npm.js index cc168fed9d..f5faf818b0 100644 --- a/resources/build-npm.js +++ b/resources/build-npm.js @@ -4,6 +4,7 @@ const fs = require('fs'); const path = require('path'); const assert = require('assert'); +const ts = require('typescript'); const babel = require('@babel/core'); const prettier = require('prettier'); @@ -23,21 +24,30 @@ if (require.main === module) { const destPath = path.join('./npmDist', filepath); fs.mkdirSync(path.dirname(destPath), { recursive: true }); - if (filepath.endsWith('.js')) { - const flowBody = - '// @flow strict\n\n' + fs.readFileSync(srcPath, 'utf-8'); - fs.writeFileSync(destPath + '.flow', flowBody); - + if (filepath.endsWith('.ts')) { const cjs = babelBuild(srcPath, { envName: 'cjs' }); - writeGeneratedFile(destPath, cjs); + writeGeneratedFile(destPath.replace(/\.ts$/, '.js'), cjs); const mjs = babelBuild(srcPath, { envName: 'mjs' }); - writeGeneratedFile(destPath.replace(/\.js$/, '.mjs'), mjs); - } else if (filepath.endsWith('.d.ts')) { - fs.copyFileSync(srcPath, destPath); + writeGeneratedFile(destPath.replace(/\.ts$/, '.mjs'), mjs); } } + const tsProgram = ts.createProgram(['src/index.ts'], { + ...ts.getDefaultCompilerOptions(), + declaration: true, + declarationDir: './npmDist', + emitDeclarationOnly: true, + }); + + const tsResult = tsProgram.emit(undefined, (filepath, body) => { + writeGeneratedFile(filepath, body); + }); + assert( + !tsResult.emitSkipped, + 'Fail to generate `*.d.ts` files, please run `npm run check`', + ); + fs.copyFileSync('./LICENSE', './npmDist/LICENSE'); fs.copyFileSync('./README.md', './npmDist/README.md'); diff --git a/resources/check-cycles.js b/resources/check-cycles.js deleted file mode 100644 index e5f0385d5f..0000000000 --- a/resources/check-cycles.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; - -const os = require('os'); -const fs = require('fs'); -const path = require('path'); -const assert = require('assert'); - -const { exec } = require('./utils'); - -const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'flow-dep-graph')); -const tmpFile = path.join(tmpDir, 'out.dot'); - -exec(`npx flow graph dep-graph --quiet --strip-root --out ${tmpFile}`); -const dot = fs.readFileSync(tmpFile, 'utf-8'); -assert(dot.startsWith('digraph {\n') && dot.endsWith('\n}')); -const dotLines = dot.split('\n').slice(1, -1); - -let depGraph = []; -for (const line of dotLines) { - const [, from, to] = line.trim().match(/^"(.*?)" -> "(.*?)"$/); - assert(from && to); - depGraph.push([from, to]); -} - -for (const [from, to] of depGraph) { - if ( - path.basename(to) === 'index.js' && - !path.dirname(to).endsWith('__fixtures__') && - path.basename(from) !== 'index.js' - ) { - console.log(from); - } -} - -let removedEdges; -do { - removedEdges = 0; - const fromFiles = new Set(); - const toFiles = new Set(); - - for (const [from, to] of depGraph) { - fromFiles.add(from); - toFiles.add(to); - } - - console.log(depGraph.length); - // eslint-disable-next-line no-loop-func - depGraph = depGraph.filter(([from, to]) => { - if (!toFiles.has(from) || !fromFiles.has(to)) { - ++removedEdges; - return false; - } - return true; - }); -} while (removedEdges > 0); - -console.log('digraph {'); -for (const [from, to] of depGraph) { - console.log(` "${from}" -> "${to}"`); -} -console.log('}'); diff --git a/resources/gen-version.js b/resources/gen-version.js index 8bea08bcd3..e4219d5cf5 100644 --- a/resources/gen-version.js +++ b/resources/gen-version.js @@ -32,5 +32,5 @@ export const versionInfo = Object.freeze({ `; if (require.main === module) { - fs.writeFileSync('./src/version.js', body.trim() + '\n'); + fs.writeFileSync('./src/version.ts', body.trim() + '\n'); } diff --git a/resources/ts-register.js b/resources/ts-register.js new file mode 100644 index 0000000000..649eb5fdd2 --- /dev/null +++ b/resources/ts-register.js @@ -0,0 +1,3 @@ +'use strict'; + +require('@babel/register')({ extensions: ['.ts'] }); 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 96% rename from src/__testUtils__/__tests__/genFuzzStrings-test.js rename to src/__testUtils__/__tests__/genFuzzStrings-test.ts index 05077ca057..c4961625e0 100644 --- a/src/__testUtils__/__tests__/genFuzzStrings-test.js +++ b/src/__testUtils__/__tests__/genFuzzStrings-test.ts @@ -4,8 +4,8 @@ import { describe, it } from 'mocha'; import { genFuzzStrings } from '../genFuzzStrings'; function expectFuzzStrings(options: { - allowedChars: Array, - maxLength: number, + allowedChars: Array; + maxLength: number; }) { return expect([...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 92% rename from src/__testUtils__/dedent.js rename to src/__testUtils__/dedent.ts index fca583865a..6a5e51b622 100644 --- a/src/__testUtils__/dedent.js +++ b/src/__testUtils__/dedent.ts @@ -27,8 +27,8 @@ export function dedentString(string: string): string { * str === "{\n test\n}"; */ export function dedent( - strings: $ReadOnlyArray, - ...values: $ReadOnlyArray + strings: ReadonlyArray, + ...values: ReadonlyArray ): string { let str = strings[0]; diff --git a/src/__testUtils__/genFuzzStrings.js b/src/__testUtils__/genFuzzStrings.ts similarity index 93% rename from src/__testUtils__/genFuzzStrings.js rename to src/__testUtils__/genFuzzStrings.ts index 9b44946440..9a9ffeac99 100644 --- a/src/__testUtils__/genFuzzStrings.js +++ b/src/__testUtils__/genFuzzStrings.ts @@ -2,8 +2,8 @@ * Generator that produces all possible combinations of allowed characters. */ export function* genFuzzStrings(options: { - allowedChars: Array, - maxLength: number, + 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 70% rename from src/__testUtils__/inspectStr.js rename to src/__testUtils__/inspectStr.ts index 52e7d7f78c..721d6e673a 100644 --- a/src/__testUtils__/inspectStr.js +++ b/src/__testUtils__/inspectStr.ts @@ -1,7 +1,9 @@ +import type { Maybe } from '../jsutils/Maybe'; + /** * Special inspect function to produce readable string literal for error messages in tests */ -export function inspectStr(str: ?string): string { +export function inspectStr(str: Maybe): string { if (str == null) { return 'null'; } diff --git a/src/__testUtils__/kitchenSinkQuery.js b/src/__testUtils__/kitchenSinkQuery.ts similarity index 100% rename from src/__testUtils__/kitchenSinkQuery.js rename to src/__testUtils__/kitchenSinkQuery.ts 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 87% rename from src/__tests__/starWarsData.js rename to src/__tests__/starWarsData.ts index 45fed55edd..04cd648546 100644 --- a/src/__tests__/starWarsData.js +++ b/src/__tests__/starWarsData.ts @@ -2,31 +2,30 @@ * These are types which correspond to the schema. * They represent the shape of the data visited during field resolution. */ -export type Character = { - id: string, - name: string, - friends: Array, - appearsIn: Array, - ... -}; +export interface Character { + id: string; + name: string; + friends: Array; + appearsIn: Array; +} -export type Human = { - type: 'Human', - id: string, - name: string, - friends: Array, - appearsIn: Array, - homePlanet?: string, -}; +export interface 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 interface 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. 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 100% rename from src/__tests__/version-test.js rename to src/__tests__/version-test.ts diff --git a/src/error/GraphQLError.d.ts b/src/error/GraphQLError.d.ts deleted file mode 100644 index 4bdcfd27c7..0000000000 --- a/src/error/GraphQLError.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { ASTNode } from '../language/ast'; -import type { Source } from '../language/source'; -import type { SourceLocation } from '../language/location'; -/** - * A GraphQLError describes an Error found during the parse, validate, or - * execute phases of performing a GraphQL operation. In addition to a message - * and stack trace, it also includes information about the locations in a - * GraphQL document and/or execution result that correspond to the Error. - */ -export class GraphQLError extends Error { - /** - * A message describing the Error for debugging purposes. - * - * Enumerable, and appears in the result of JSON.stringify(). - * - * Note: should be treated as readonly, despite invariant usage. - */ - message: string; - /** - * An array of { line, column } locations within the source GraphQL document - * which correspond to this error. - * - * Errors during validation often contain multiple locations, for example to - * point out two things with the same name. Errors during execution include a - * single location, the field which produced the error. - * - * Enumerable, and appears in the result of JSON.stringify(). - */ - readonly locations?: ReadonlyArray; - /** - * An array describing the JSON-path into the execution response which - * corresponds to this error. Only included for errors during execution. - * - * Enumerable, and appears in the result of JSON.stringify(). - */ - readonly path?: ReadonlyArray; - /** - * An array of GraphQL AST Nodes corresponding to this error. - */ - readonly nodes?: ReadonlyArray; - /** - * The source GraphQL document for the first location of this error. - * - * Note that if this Error represents more than one node, the source may not - * represent nodes after the first node. - */ - readonly source?: Source; - /** - * An array of character offsets within the source GraphQL document - * which correspond to this error. - */ - readonly positions?: ReadonlyArray; - /** - * The original error thrown from a field resolver during execution. - */ - readonly originalError: Maybe; - /** - * Extension fields to add to the formatted error. - */ - readonly extensions?: { - [key: string]: unknown; - }; - constructor( - message: string, - nodes?: ReadonlyArray | ASTNode | null, - source?: Maybe, - positions?: Maybe>, - path?: Maybe>, - originalError?: Maybe< - Error & { - readonly extensions?: unknown; - } - >, - extensions?: Maybe<{ - [key: string]: unknown; - }>, - ); - toString(): string; - get [Symbol.toStringTag](): string; -} -/** - * Prints a GraphQLError to a string, representing useful location information - * about the error's position in the source. - */ -export function printError(error: GraphQLError): string; diff --git a/src/error/GraphQLError.js b/src/error/GraphQLError.ts similarity index 89% rename from src/error/GraphQLError.js rename to src/error/GraphQLError.ts index 6ea6a54206..68ddeda702 100644 --- a/src/error/GraphQLError.js +++ b/src/error/GraphQLError.ts @@ -1,7 +1,5 @@ -// FIXME: -// flowlint uninitialized-instance-property:off - import { isObjectLike } from '../jsutils/isObjectLike'; +import type { Maybe } from '../jsutils/Maybe'; import type { ASTNode } from '../language/ast'; import type { Source } from '../language/source'; @@ -35,7 +33,7 @@ export class GraphQLError extends Error { * * Enumerable, and appears in the result of JSON.stringify(). */ - +locations: $ReadOnlyArray | void; + readonly locations?: ReadonlyArray; /** * An array describing the JSON-path into the execution response which @@ -43,12 +41,12 @@ export class GraphQLError extends Error { * * Enumerable, and appears in the result of JSON.stringify(). */ - +path: $ReadOnlyArray | void; + readonly path?: ReadonlyArray; /** * An array of GraphQL AST Nodes corresponding to this error. */ - +nodes: $ReadOnlyArray | void; + readonly nodes?: ReadonlyArray; /** * The source GraphQL document for the first location of this error. @@ -56,32 +54,32 @@ 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; /** * An array of character offsets within the source GraphQL document * which correspond to this error. */ - +positions: $ReadOnlyArray | void; + readonly positions?: ReadonlyArray; /** * The original error thrown from a field resolver during execution. */ - +originalError: ?Error; + readonly originalError: Maybe; /** * Extension fields to add to the formatted error. */ - +extensions: { [key: string]: mixed, ... } | void; + readonly extensions?: { [key: string]: unknown }; constructor( message: string, - nodes?: $ReadOnlyArray | ASTNode | void | null, - source?: ?Source, - positions?: ?$ReadOnlyArray, - path?: ?$ReadOnlyArray, - originalError?: ?(Error & { +extensions?: mixed, ... }), - extensions?: ?{ [key: string]: mixed, ... }, + nodes?: ReadonlyArray | ASTNode | null, + source?: Maybe, + positions?: Maybe>, + path?: Maybe>, + originalError?: Maybe, + extensions?: Maybe<{ [key: string]: unknown }>, ) { super(message); @@ -100,8 +98,10 @@ export class GraphQLError extends Error { _source = _nodes[0].loc?.source; } - let _positions = positions; - if (!_positions && _nodes) { + let _positions; + if (positions) { + _positions = positions; + } else if (_nodes) { _positions = []; for (const node of _nodes) { if (node.loc) { @@ -133,7 +133,6 @@ export class GraphQLError extends Error { } } - // $FlowFixMe[cannot-write] FIXME Object.defineProperties(this, { name: { value: 'GraphQLError' }, message: { @@ -212,7 +211,6 @@ export class GraphQLError extends Error { } // FIXME: workaround to not break chai comparisons, should be remove in v16 - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag](): string { return 'Object'; } 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 90% rename from src/error/__tests__/formatError-test.js rename to src/error/__tests__/formatError-test.ts index d6c8e17e8d..d618f8d2d0 100644 --- a/src/error/__tests__/formatError-test.js +++ b/src/error/__tests__/formatError-test.ts @@ -6,7 +6,7 @@ import { GraphQLError } from '../GraphQLError'; describe('formatError: default error formatter', () => { it('uses default message', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const e = new GraphQLError(); expect(formatError(e)).to.deep.equal({ @@ -45,12 +45,10 @@ describe('formatError: default error formatter', () => { }); it('rejects null and undefined errors', () => { - // $FlowExpectedError[incompatible-call] expect(() => formatError(undefined)).to.throw( 'Received null or undefined error.', ); - // $FlowExpectedError[incompatible-call] expect(() => formatError(null)).to.throw( 'Received null or undefined error.', ); diff --git a/src/error/__tests__/locatedError-test.js b/src/error/__tests__/locatedError-test.ts similarity index 79% rename from src/error/__tests__/locatedError-test.js rename to src/error/__tests__/locatedError-test.ts index 37d829998b..21e858e95e 100644 --- a/src/error/__tests__/locatedError-test.js +++ b/src/error/__tests__/locatedError-test.ts @@ -18,15 +18,15 @@ describe('locatedError', () => { it('passes GraphQLError-ish through', () => { const e = new Error(); - // $FlowExpectedError[prop-missing] + // @ts-expect-error e.locations = []; - // $FlowExpectedError[prop-missing] + // @ts-expect-error e.path = []; - // $FlowExpectedError[prop-missing] + // @ts-expect-error e.nodes = []; - // $FlowExpectedError[prop-missing] + // @ts-expect-error e.source = null; - // $FlowExpectedError[prop-missing] + // @ts-expect-error e.positions = []; e.name = 'GraphQLError'; @@ -35,7 +35,7 @@ describe('locatedError', () => { it('does not pass through elasticsearch-like errors', () => { const e = new Error('I am from elasticsearch'); - // $FlowExpectedError[prop-missing] + // @ts-expect-error e.path = '/something/feed/_search'; expect(locatedError(e, [], [])).to.not.deep.equal(e); diff --git a/src/error/formatError.d.ts b/src/error/formatError.d.ts deleted file mode 100644 index db7acf73a0..0000000000 --- a/src/error/formatError.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { SourceLocation } from '../language/location'; -import type { GraphQLError } from './GraphQLError'; -/** - * Given a GraphQLError, format it according to the rules described by the - * Response Format, Errors section of the GraphQL Specification. - */ -export function formatError(error: GraphQLError): GraphQLFormattedError; -/** - * @see https://github.com/graphql/graphql-spec/blob/master/spec/Section%207%20--%20Response.md#errors - */ -export interface 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. - */ - 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. - */ - readonly locations?: ReadonlyArray; - /** - * 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. - */ - readonly path?: ReadonlyArray; - /** - * Reserved for implementors to extend the protocol however they see fit, - * and hence there are no additional restrictions on its contents. - */ - readonly extensions?: { - [key: string]: unknown; - }; -} diff --git a/src/error/formatError.js b/src/error/formatError.ts similarity index 87% rename from src/error/formatError.js rename to src/error/formatError.ts index 520c7be76c..bc4cfed85c 100644 --- a/src/error/formatError.js +++ b/src/error/formatError.ts @@ -23,28 +23,28 @@ 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 interface 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; /** * 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; /** * 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.d.ts b/src/error/index.d.ts deleted file mode 100644 index e69dacf43a..0000000000 --- a/src/error/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { GraphQLError, printError } from './GraphQLError'; -export { syntaxError } from './syntaxError'; -export { locatedError } from './locatedError'; -export { formatError } from './formatError'; -export type { GraphQLFormattedError } from './formatError'; diff --git a/src/error/index.js b/src/error/index.ts similarity index 100% rename from src/error/index.js rename to src/error/index.ts diff --git a/src/error/locatedError.d.ts b/src/error/locatedError.d.ts deleted file mode 100644 index ef1460d66a..0000000000 --- a/src/error/locatedError.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { ASTNode } from '../language/ast'; -import { GraphQLError } from './GraphQLError'; -/** - * Given an arbitrary value, presumably thrown while attempting to execute a - * GraphQL operation, produce a new GraphQLError aware of the location in the - * document responsible for the original Error. - */ -export function locatedError( - rawOriginalError: unknown, - nodes: ASTNode | ReadonlyArray | undefined | null, - path?: Maybe>, -): GraphQLError; diff --git a/src/error/locatedError.js b/src/error/locatedError.ts similarity index 75% rename from src/error/locatedError.js rename to src/error/locatedError.ts index 31799defcd..286408f792 100644 --- a/src/error/locatedError.js +++ b/src/error/locatedError.ts @@ -1,4 +1,5 @@ import { inspect } from '../jsutils/inspect'; +import type { Maybe } from '../jsutils/Maybe'; import type { ASTNode } from '../language/ast'; @@ -10,9 +11,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 | undefined | null, + path?: Maybe>, ): GraphQLError { // Sometimes a non-error is thrown, wrap it as an Error instance to ensure a consistent Error interface. const originalError: Error | GraphQLError = @@ -21,18 +22,19 @@ export function locatedError( : new Error('Unexpected error value: ' + inspect(rawOriginalError)); // Note: this uses a brand-check to support GraphQL errors originating from other contexts. + // @ts-expect-error FIXME: TS Conversion if (Array.isArray(originalError.path)) { - // $FlowExpectedError[incompatible-return] + // @ts-expect-error return originalError; } return new GraphQLError( originalError.message, - // $FlowFixMe[prop-missing] FIXME + // @ts-expect-error FIXME originalError.nodes ?? nodes, - // $FlowFixMe[prop-missing] FIXME + // @ts-expect-error FIXME originalError.source, - // $FlowFixMe[prop-missing] FIXME + // @ts-expect-error FIXME originalError.positions, path, originalError, diff --git a/src/error/syntaxError.d.ts b/src/error/syntaxError.d.ts deleted file mode 100644 index 6df94d4cd7..0000000000 --- a/src/error/syntaxError.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Source } from '../language/source'; -import { GraphQLError } from './GraphQLError'; -/** - * Produces a GraphQLError representing a syntax error, containing useful - * descriptive information about the syntax error's position in the source. - */ -export function syntaxError( - source: Source, - position: number, - description: string, -): GraphQLError; diff --git a/src/error/syntaxError.js b/src/error/syntaxError.ts similarity index 100% rename from src/error/syntaxError.js rename to src/error/syntaxError.ts diff --git a/src/execution/__tests__/abstract-test.js b/src/execution/__tests__/abstract-test.ts similarity index 98% rename from src/execution/__tests__/abstract-test.js rename to src/execution/__tests__/abstract-test.ts index 2d1423e002..bfbd666b08 100644 --- a/src/execution/__tests__/abstract-test.js +++ b/src/execution/__tests__/abstract-test.ts @@ -18,9 +18,9 @@ import { buildSchema } from '../../utilities/buildASTSchema'; import { executeSync, execute } from '../execute'; async function executeQuery(args: { - schema: GraphQLSchema, - query: string, - rootValue?: mixed, + schema: GraphQLSchema; + query: string; + rootValue?: unknown; }) { const { schema, query, rootValue } = args; const document = parse(query); @@ -534,7 +534,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 { @@ -570,7 +570,7 @@ describe('Execute: Handles execution of abstract types', () => { ); // FIXME: workaround since we can't inject resolveType into SDL - // $FlowExpectedError[incompatible-type] + // @ts-expect-error assertInterfaceType(schema.getType('Pet')).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 "[]".', @@ -578,7 +578,7 @@ describe('Execute: Handles execution of abstract types', () => { // FIXME: workaround since we can't inject resolveType into SDL assertInterfaceType(schema.getType('Pet')).resolveType = - // $FlowExpectedError[incompatible-type] + // @ts-expect-error () => 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 689151c587..b886270978 100644 --- a/src/execution/__tests__/executor-test.js +++ b/src/execution/__tests__/executor-test.ts @@ -31,14 +31,14 @@ describe('Execute: Handles basic execution tasks', () => { }), }); - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => executeSync({ schema })).to.throw('Must provide document.'); }); it('throws if no schema is provided', () => { const document = parse('{ field }'); - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => executeSync({ document })).to.throw( 'Expected undefined to be a GraphQL schema.', ); @@ -63,7 +63,7 @@ describe('Execute: Handles basic execution tasks', () => { `); const variableValues = '{ "a": 1 }'; - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => executeSync({ schema, document, variableValues })).to.throw( 'Variables must be provided as an Object where each property is a variable value. Perhaps look to see if an unparsed JSON string was provided.', ); @@ -443,7 +443,7 @@ describe('Execute: Handles basic execution tasks', () => { throw new Error('Error getting syncError'); }, syncRawError() { - // eslint-disable-next-line no-throw-literal + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw 'Error getting syncRawError'; }, syncReturnError() { @@ -480,7 +480,7 @@ describe('Execute: Handles basic execution tasks', () => { }, asyncRawError() { return new Promise(() => { - // eslint-disable-next-line no-throw-literal + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw 'Error getting asyncRawError'; }); }, @@ -489,7 +489,7 @@ describe('Execute: Handles basic execution tasks', () => { }, asyncReturnErrorWithExtensions() { const error = new Error('Error getting asyncReturnErrorWithExtensions'); - // $FlowExpectedError[prop-missing] + // @ts-expect-error error.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 9d1215f483..e5efd74db5 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..223c552c33 100644 --- a/src/execution/__tests__/nonnull-test.js +++ b/src/execution/__tests__/nonnull-test.ts @@ -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 97% rename from src/execution/__tests__/resolve-test.js rename to src/execution/__tests__/resolve-test.ts index b8d28a615b..f62314f8dc 100644 --- a/src/execution/__tests__/resolve-test.js +++ b/src/execution/__tests__/resolve-test.ts @@ -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 98% rename from src/execution/__tests__/union-interface-test.js rename to src/execution/__tests__/union-interface-test.ts index 6e8d1f98b1..d65ada60c5 100644 --- a/src/execution/__tests__/union-interface-test.js +++ b/src/execution/__tests__/union-interface-test.ts @@ -17,8 +17,8 @@ import { executeSync } from '../execute'; class Dog { name: string; barks: boolean; - mother: Dog | void; - father: Dog | void; + mother?: Dog; + father?: Dog; progeny: Array; constructor(name: string, barks: boolean) { @@ -31,8 +31,8 @@ class Dog { class Cat { name: string; meows: boolean; - mother: Cat | void; - father: Cat | void; + mother?: Cat; + father?: Cat; progeny: Array; constructor(name: string, meows: boolean) { @@ -44,13 +44,13 @@ class Cat { class Person { name: string; - pets: Array | void; - friends: Array | void; + pets?: Array; + friends?: Array; constructor( name: string, pets?: Array, - friends?: Array | void, + friends?: Array, ) { this.name = name; this.pets = pets; 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 1c45e2bc9d..ad71465568 100644 --- a/src/execution/__tests__/variables-test.js +++ b/src/execution/__tests__/variables-test.ts @@ -119,7 +119,7 @@ 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.d.ts b/src/execution/execute.d.ts deleted file mode 100644 index d2f87bb32d..0000000000 --- a/src/execution/execute.d.ts +++ /dev/null @@ -1,205 +0,0 @@ -import type { Path } from '../jsutils/Path'; -import type { ObjMap } from '../jsutils/ObjMap'; -import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; -import type { Maybe } from '../jsutils/Maybe'; -import type { GraphQLFormattedError } from '../error/formatError'; -import { GraphQLError } from '../error/GraphQLError'; -import type { - DocumentNode, - OperationDefinitionNode, - SelectionSetNode, - FieldNode, - FragmentDefinitionNode, -} from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import type { - GraphQLObjectType, - GraphQLField, - GraphQLFieldResolver, - GraphQLResolveInfo, - GraphQLTypeResolver, -} from '../type/definition'; -/** - * Terminology - * - * "Definitions" are the generic name for top-level statements in the document. - * Examples of this include: - * 1) Operations (such as a query) - * 2) Fragments - * - * "Operations" are a generic name for requests in the document. - * Examples of this include: - * 1) query, - * 2) mutation - * - * "Selections" are the definitions that can appear legally and at - * single level of the query. These include: - * 1) field references e.g "a" - * 2) fragment "spreads" e.g. "...c" - * 3) inline fragment "spreads" e.g. "...on Type { a }" - */ -/** - * Data that must be available at all points during query execution. - * - * Namely, schema of the type system that is currently executing, - * and the fragments defined in the query document - */ -export interface 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. - * - * - `errors` is included when any errors occurred as a non-empty array. - * - `data` is the result of a successful execution of the query. - * - `extensions` is reserved for adding non-standard properties. - */ -export interface ExecutionResult< - TData = ObjMap, - TExtensions = ObjMap, -> { - errors?: ReadonlyArray; - data?: TData | null; - extensions?: TExtensions; -} -export interface FormattedExecutionResult< - TData = ObjMap, - TExtensions = ObjMap, -> { - errors?: ReadonlyArray; - data?: TData | null; - extensions?: TExtensions; -} -export interface ExecutionArgs { - schema: GraphQLSchema; - document: DocumentNode; - rootValue?: unknown; - contextValue?: unknown; - variableValues?: Maybe<{ - readonly [variable: string]: unknown; - }>; - operationName?: Maybe; - fieldResolver?: Maybe>; - typeResolver?: Maybe>; -} -/** - * Implements the "Evaluating requests" section of the GraphQL specification. - * - * Returns either a synchronous ExecutionResult (if all encountered resolvers - * are synchronous), or a Promise of an ExecutionResult that will eventually be - * resolved and never rejected. - * - * If the arguments to this function do not result in a legal execution context, - * a GraphQLError will be thrown immediately explaining the invalid input. - */ -export function execute(args: ExecutionArgs): PromiseOrValue; -/** - * Also implements the "Evaluating requests" section of the GraphQL specification. - * However, it guarantees to complete synchronously (or throw an error) assuming - * that all field resolvers are also synchronous. - */ -export function executeSync(args: ExecutionArgs): ExecutionResult; -/** - * Essential assertions before executing to provide developer feedback for - * improper use of the GraphQL library. - * - * @internal - */ -export function assertValidExecutionArguments( - schema: GraphQLSchema, - document: DocumentNode, - rawVariableValues: Maybe<{ - readonly [variable: string]: unknown; - }>, -): void; -/** - * Constructs a ExecutionContext object from the arguments passed to - * execute, which we will pass throughout the other execution methods. - * - * Throws a GraphQLError if a valid execution context cannot be created. - * - * @internal - */ -export function buildExecutionContext( - schema: GraphQLSchema, - document: DocumentNode, - rootValue: unknown, - contextValue: unknown, - rawVariableValues: Maybe<{ - readonly [variable: string]: unknown; - }>, - operationName: Maybe, - fieldResolver: Maybe>, - typeResolver?: Maybe>, -): ReadonlyArray | ExecutionContext; -/** - * Given a selectionSet, adds all of the fields in that selection to - * the passed in map of fields, and returns it at the end. - * - * CollectFields requires the "runtime type" of an object. For a field which - * returns an Interface or Union type, the "runtime type" will be the actual - * Object type returned by that field. - * - * @internal - */ -export function collectFields( - exeContext: ExecutionContext, - runtimeType: GraphQLObjectType, - selectionSet: SelectionSetNode, - fields: Map>, - visitedFragmentNames: Set, -): Map>; -/** - * @internal - */ -export function buildResolveInfo( - exeContext: ExecutionContext, - fieldDef: GraphQLField, - fieldNodes: ReadonlyArray, - parentType: GraphQLObjectType, - path: Path, -): GraphQLResolveInfo; -/** - * If a resolveType function is not given, then a default resolve behavior is - * used which attempts two strategies: - * - * First, See if the provided value has a `__typename` field defined, if so, use - * that value as name of the resolved type. - * - * 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; -/** - * If a resolve function is not given, then a default resolve behavior is used - * which takes the property of the source object of the same name as the field - * and returns it as the result, or if it's a function, returns the result - * of calling that function while passing along args and context value. - */ -export const defaultFieldResolver: GraphQLFieldResolver; -/** - * This method looks up the field on the given type definition. - * It has special casing for the three introspection fields, - * __schema, __type and __typename. __typename is special because - * it can always be queried as a field, even in situations where no - * other fields are allowed, like on a Union. __schema and __type - * could get automatically added to the query type, but that would - * require mutating type definitions, which would cause issues. - * - * @internal - */ -export function getFieldDef( - schema: GraphQLSchema, - parentType: GraphQLObjectType, - fieldNode: FieldNode, -): Maybe>; diff --git a/src/execution/execute.js b/src/execution/execute.ts similarity index 88% rename from src/execution/execute.js rename to src/execution/execute.ts index 0d7f0f7a12..923d018d1a 100644 --- a/src/execution/execute.js +++ b/src/execution/execute.ts @@ -1,6 +1,7 @@ import type { Path } from '../jsutils/Path'; import type { ObjMap } from '../jsutils/ObjMap'; import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; +import type { Maybe } from '../jsutils/Maybe'; import { inspect } from '../jsutils/inspect'; import { memoize3 } from '../jsutils/memoize3'; import { invariant } from '../jsutils/invariant'; @@ -92,17 +93,17 @@ 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 interface 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 +112,34 @@ 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 interface ExecutionResult< + TData = ObjMap, + TExtensions = ObjMap, +> { + errors?: ReadonlyArray; + data?: TData | null; + extensions?: TExtensions; +} + +export interface FormattedExecutionResult< + TData = ObjMap, + TExtensions = ObjMap, +> { + errors?: ReadonlyArray; + data?: TData | null; + extensions?: TExtensions; +} + +export interface ExecutionArgs { + schema: GraphQLSchema; + document: DocumentNode; + rootValue?: unknown; + contextValue?: unknown; + variableValues?: Maybe<{ readonly [variable: string]: unknown }>; + operationName?: Maybe; + fieldResolver?: Maybe>; + typeResolver?: Maybe>; +} /** * Implements the "Evaluating requests" section of the GraphQL specification. @@ -184,7 +191,9 @@ export function execute(args: ExecutionArgs): PromiseOrValue { // field and its descendants will be omitted, and sibling fields will still // be executed. An execution which encounters errors will still result in a // resolved Promise. + // @ts-expect-error FIXME: TS Conversion const data = executeOperation(exeContext, exeContext.operation, rootValue); + // @ts-expect-error FIXME: TS Conversion return buildResponse(exeContext, data); } @@ -210,7 +219,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 +238,7 @@ function buildResponse( export function assertValidExecutionArguments( schema: GraphQLSchema, document: DocumentNode, - rawVariableValues: ?{ +[variable: string]: mixed, ... }, + rawVariableValues: Maybe<{ readonly [variable: string]: unknown }>, ): void { devAssert(document, 'Must provide document.'); @@ -254,14 +263,14 @@ 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 { - let operation: OperationDefinitionNode | void; + rootValue: unknown, + contextValue: unknown, + rawVariableValues: Maybe<{ readonly [variable: string]: unknown }>, + operationName: Maybe, + fieldResolver: Maybe>, + typeResolver?: Maybe>, +): ReadonlyArray | ExecutionContext { + let operation: OperationDefinitionNode | undefined; const fragments: ObjMap = Object.create(null); for (const definition of document.definitions) { switch (definition.kind) { @@ -306,7 +315,6 @@ export function buildExecutionContext( return coercedVariableValues.errors; } - // $FlowFixMe[incompatible-return] return { schema, fragments, @@ -326,8 +334,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, @@ -367,10 +375,10 @@ function executeOperation( function executeFieldsSerially( exeContext: ExecutionContext, parentType: GraphQLObjectType, - sourceValue: mixed, - path: Path | void, + sourceValue: unknown, + path: Path | undefined, fields: Map>, -): PromiseOrValue> { +): PromiseOrValue> { return promiseReduce( fields.entries(), (results, [responseName, fieldNodes]) => { @@ -405,10 +413,10 @@ function executeFieldsSerially( function executeFields( exeContext: ExecutionContext, parentType: GraphQLObjectType, - sourceValue: mixed, - path: Path | void, + sourceValue: unknown, + path: Path | undefined, fields: Map>, -): PromiseOrValue> { +): PromiseOrValue> { const results = Object.create(null); let containsPromise = false; @@ -585,10 +593,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 fieldDef = getFieldDef(exeContext.schema, parentType, fieldNodes[0]); if (!fieldDef) { return; @@ -659,8 +667,8 @@ function resolveField( */ export function buildResolveInfo( exeContext: ExecutionContext, - fieldDef: GraphQLField, - fieldNodes: $ReadOnlyArray, + fieldDef: GraphQLField, + fieldNodes: ReadonlyArray, parentType: GraphQLObjectType, path: Path, ): GraphQLResolveInfo { @@ -721,11 +729,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; @@ -802,8 +810,7 @@ function completeValue( // istanbul ignore next (Not reachable. All possible output types have been considered) invariant( false, - 'Cannot complete value of unexpected output type: ' + - inspect((returnType: empty)), + 'Cannot complete value of unexpected output type: ' + inspect(returnType), ); } @@ -814,11 +821,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 (!isIterableObject(result)) { throw new GraphQLError( `Expected Iterable, but did not find one for field "${info.parentType.name}.${info.fieldName}".`, @@ -884,7 +891,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( @@ -902,11 +912,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); @@ -949,12 +959,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( @@ -1009,11 +1019,11 @@ function ensureValidRuntimeType( function completeObjectValue( exeContext: ExecutionContext, returnType: GraphQLObjectType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, info: GraphQLResolveInfo, path: Path, - result: mixed, -): PromiseOrValue> { + result: unknown, +): PromiseOrValue> { // Collect sub-fields to execute to complete this value. const subFieldNodes = collectSubfields(exeContext, returnType, fieldNodes); @@ -1048,8 +1058,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)}.`, @@ -1066,10 +1076,10 @@ const collectSubfields = memoize3(_collectSubfields); function _collectSubfields( exeContext: ExecutionContext, returnType: GraphQLObjectType, - fieldNodes: $ReadOnlyArray, + fieldNodes: ReadonlyArray, ): Map> { let subFieldNodes = new Map(); - const visitedFragmentNames = new Set(); + const visitedFragmentNames = new Set(); for (const node of fieldNodes) { if (node.selectionSet) { subFieldNodes = collectFields( @@ -1094,45 +1104,41 @@ 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, -) { - // First, look for `__typename`. - if (isObjectLike(value) && typeof value.__typename === 'string') { - return value.__typename; - } +export const defaultTypeResolver: GraphQLTypeResolver = + function (value, contextValue, info, abstractType) { + // First, look for `__typename`. + if (isObjectLike(value) && typeof value.__typename === 'string') { + return value.__typename; + } - // Otherwise, test each possible type. - const possibleTypes = info.schema.getPossibleTypes(abstractType); - const promisedIsTypeOfResults = []; + // Otherwise, test each possible type. + const possibleTypes = info.schema.getPossibleTypes(abstractType); + const promisedIsTypeOfResults = []; - for (let i = 0; i < possibleTypes.length; i++) { - const type = possibleTypes[i]; + for (let i = 0; i < possibleTypes.length; i++) { + const type = possibleTypes[i]; - if (type.isTypeOf) { - const isTypeOfResult = type.isTypeOf(value, contextValue, info); + if (type.isTypeOf) { + const isTypeOfResult = type.isTypeOf(value, contextValue, info); - if (isPromise(isTypeOfResult)) { - promisedIsTypeOfResults[i] = isTypeOfResult; - } else if (isTypeOfResult) { - return type.name; + if (isPromise(isTypeOfResult)) { + promisedIsTypeOfResults[i] = isTypeOfResult; + } else if (isTypeOfResult) { + return type.name; + } } } - } - if (promisedIsTypeOfResults.length) { - return Promise.all(promisedIsTypeOfResults).then((isTypeOfResults) => { - for (let i = 0; i < isTypeOfResults.length; i++) { - if (isTypeOfResults[i]) { - return possibleTypes[i].name; + if (promisedIsTypeOfResults.length) { + return Promise.all(promisedIsTypeOfResults).then((isTypeOfResults) => { + for (let i = 0; i < isTypeOfResults.length; i++) { + if (isTypeOfResults[i]) { + return possibleTypes[i].name; + } } - } - }); - } -}; + }); + } + }; /** * If a resolve function is not given, then a default resolve behavior is used @@ -1140,7 +1146,7 @@ export const defaultTypeResolver: GraphQLTypeResolver = function ( * and returns it as the result, or if it's a function, returns the result * of calling that function while passing along args and context value. */ -export const defaultFieldResolver: GraphQLFieldResolver = +export const defaultFieldResolver: GraphQLFieldResolver = function (source: any, args, contextValue, info) { // ensure source is a value for which property access is acceptable. if (isObjectLike(source) || typeof source === 'function') { @@ -1167,7 +1173,7 @@ export function getFieldDef( schema: GraphQLSchema, parentType: GraphQLObjectType, fieldNode: FieldNode, -): ?GraphQLField { +): Maybe> { const fieldName = fieldNode.name.value; if ( diff --git a/src/execution/index.d.ts b/src/execution/index.d.ts deleted file mode 100644 index 674aeb30cf..0000000000 --- a/src/execution/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -export { pathToArray as responsePathAsArray } from '../jsutils/Path'; -export { - execute, - executeSync, - defaultFieldResolver, - defaultTypeResolver, -} from './execute'; -export type { - ExecutionArgs, - ExecutionResult, - FormattedExecutionResult, -} from './execute'; -export { getDirectiveValues } from './values'; diff --git a/src/execution/index.js b/src/execution/index.ts similarity index 100% rename from src/execution/index.js rename to src/execution/index.ts diff --git a/src/execution/values.d.ts b/src/execution/values.d.ts deleted file mode 100644 index 6150727e0e..0000000000 --- a/src/execution/values.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import type { ObjMap } from '../jsutils/ObjMap'; -import type { Maybe } from '../jsutils/Maybe'; -import { GraphQLError } from '../error/GraphQLError'; -import type { - FieldNode, - DirectiveNode, - VariableDefinitionNode, -} from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLField } from '../type/definition'; -import type { GraphQLDirective } from '../type/directives'; -type CoercedVariableValues = - | { - errors: ReadonlyArray; - coerced?: never; - } - | { - coerced: { - [variable: string]: unknown; - }; - errors?: never; - }; -/** - * Prepares an object map of variableValues of the correct type based on the - * provided variable definitions and arbitrary input. If the input cannot be - * parsed to match the variable definitions, a GraphQLError will be thrown. - * - * Note: The returned value is a plain Object with a prototype, since it is - * exposed to user code. Care should be taken to not pull values from the - * Object prototype. - * - * @internal - */ -export function getVariableValues( - schema: GraphQLSchema, - varDefNodes: ReadonlyArray, - inputs: { - readonly [variable: string]: unknown; - }, - options?: { - maxErrors?: number; - }, -): CoercedVariableValues; -/** - * Prepares an object map of argument values given a list of argument - * definitions and list of argument AST nodes. - * - * Note: The returned value is a plain Object with a prototype, since it is - * exposed to user code. Care should be taken to not pull values from the - * Object prototype. - * - * @internal - */ -export function getArgumentValues( - def: GraphQLField | GraphQLDirective, - node: FieldNode | DirectiveNode, - variableValues?: Maybe>, -): { - [argument: string]: unknown; -}; -/** - * Prepares an object map of argument values given a directive definition - * and a AST node which may contain directives. Optionally also accepts a map - * of variable values. - * - * If the directive does not exist on the node, returns undefined. - * - * Note: The returned value is a plain Object with a prototype, since it is - * exposed to user code. Care should be taken to not pull values from the - * Object prototype. - */ -export function getDirectiveValues( - directiveDef: GraphQLDirective, - node: { - readonly directives?: ReadonlyArray; - }, - variableValues?: Maybe>, -): - | undefined - | { - [argument: string]: unknown; - }; diff --git a/src/execution/values.js b/src/execution/values.ts similarity index 90% rename from src/execution/values.js rename to src/execution/values.ts index 781dc30bfc..05277f3827 100644 --- a/src/execution/values.js +++ b/src/execution/values.ts @@ -1,4 +1,5 @@ import type { ObjMap } from '../jsutils/ObjMap'; +import type { Maybe } from '../jsutils/Maybe'; import { keyMap } from '../jsutils/keyMap'; import { inspect } from '../jsutils/inspect'; import { printPathArray } from '../jsutils/printPathArray'; @@ -23,8 +24,8 @@ import { valueFromAST } from '../utilities/valueFromAST'; import { coerceInputValue } from '../utilities/coerceInputValue'; type CoercedVariableValues = - | { errors: $ReadOnlyArray } - | { coerced: { [variable: string]: mixed, ... } }; + | { errors: ReadonlyArray; coerced?: never } + | { coerced: { [variable: string]: unknown }; errors?: never }; /** * Prepares an object map of variableValues of the correct type based on the @@ -39,8 +40,8 @@ type CoercedVariableValues = */ export function getVariableValues( schema: GraphQLSchema, - varDefNodes: $ReadOnlyArray, - inputs: { +[variable: string]: mixed, ... }, + varDefNodes: ReadonlyArray, + inputs: { readonly [variable: string]: unknown }, options?: { maxErrors?: number }, ): CoercedVariableValues { const errors = []; @@ -72,10 +73,10 @@ export function getVariableValues( function coerceVariableValues( schema: GraphQLSchema, - varDefNodes: $ReadOnlyArray, - inputs: { +[variable: string]: mixed, ... }, + varDefNodes: ReadonlyArray, + inputs: { readonly [variable: string]: unknown }, onError: (error: GraphQLError) => void, -): { [variable: string]: mixed, ... } { +): { [variable: string]: unknown } { const coercedValues = {}; for (const varDefNode of varDefNodes) { const varName = varDefNode.variable.name.value; @@ -157,10 +158,10 @@ function coerceVariableValues( * @internal */ export function getArgumentValues( - def: GraphQLField | GraphQLDirective, + def: GraphQLField | GraphQLDirective, node: FieldNode | DirectiveNode, - variableValues?: ?ObjMap, -): { [argument: string]: mixed, ... } { + variableValues?: Maybe>, +): { [argument: string]: unknown } { const coercedValues = {}; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') @@ -244,9 +245,9 @@ export function getArgumentValues( */ export function getDirectiveValues( directiveDef: GraphQLDirective, - node: { +directives?: $ReadOnlyArray, ... }, - variableValues?: ?ObjMap, -): void | { [argument: string]: mixed, ... } { + node: { readonly directives?: ReadonlyArray }, + variableValues?: Maybe>, +): undefined | { [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 +258,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.d.ts b/src/graphql.d.ts deleted file mode 100644 index 92dd8b2b68..0000000000 --- a/src/graphql.d.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { Maybe } from './jsutils/Maybe'; -import type { Source } from './language/source'; -import type { - GraphQLFieldResolver, - GraphQLTypeResolver, -} from './type/definition'; -import type { GraphQLSchema } from './type/schema'; -import type { ExecutionResult } from './execution/execute'; -/** - * This is the primary entry point function for fulfilling GraphQL operations - * by parsing, validating, and executing a GraphQL document along side a - * GraphQL schema. - * - * More sophisticated GraphQL servers, such as those which persist queries, - * may wish to separate the validation and execution phases to a static time - * tooling step, and a server runtime step. - * - * Accepts either an object with named arguments, or individual arguments: - * - * schema: - * The GraphQL type system to use when validating and executing a query. - * source: - * A GraphQL language formatted string representing the requested operation. - * rootValue: - * The value provided as the first argument to resolver functions on the top - * level type (e.g. the query object type). - * contextValue: - * The context value is provided as an argument to resolver functions after - * field arguments. It is used to pass shared information useful at any point - * during executing this query, for example the currently logged in user and - * connections to databases or other services. - * variableValues: - * A mapping of variable name to runtime value to use for all variables - * defined in the requestString. - * operationName: - * The name of the operation to use if requestString contains multiple - * possible operations. Can be omitted if requestString contains only - * one operation. - * fieldResolver: - * A resolver function to use when one is not provided by the schema. - * If not provided, the default field resolver is used (which looks for a - * value or method on the source value with the field's name). - * typeResolver: - * A type resolver function to use when none is provided by the schema. - * If not provided, the default type resolver is used (which looks for a - * `__typename` field or alternatively calls the `isTypeOf` method). - */ -export interface GraphQLArgs { - schema: GraphQLSchema; - source: string | Source; - rootValue?: unknown; - contextValue?: unknown; - variableValues?: Maybe<{ - readonly [variable: string]: unknown; - }>; - operationName?: Maybe; - fieldResolver?: Maybe>; - typeResolver?: Maybe>; -} -export function graphql(args: GraphQLArgs): Promise; -/** - * The graphqlSync function also fulfills GraphQL operations by parsing, - * validating, and executing a GraphQL document along side a GraphQL schema. - * However, it guarantees to complete synchronously (or throw an error) assuming - * that all field resolvers are also synchronous. - */ -export function graphqlSync(args: GraphQLArgs): ExecutionResult; diff --git a/src/graphql.js b/src/graphql.ts similarity index 91% rename from src/graphql.js rename to src/graphql.ts index 1aaf5e11bd..03e6b95882 100644 --- a/src/graphql.js +++ b/src/graphql.ts @@ -1,5 +1,6 @@ import type { PromiseOrValue } from './jsutils/PromiseOrValue'; import { isPromise } from './jsutils/isPromise'; +import type { Maybe } from './jsutils/Maybe'; import type { Source } from './language/source'; import { parse } from './language/parser'; @@ -55,16 +56,16 @@ 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 interface GraphQLArgs { + schema: GraphQLSchema; + source: string | Source; + rootValue?: unknown; + contextValue?: unknown; + variableValues?: Maybe<{ readonly [variable: string]: unknown }>; + operationName?: Maybe; + fieldResolver?: Maybe>; + typeResolver?: Maybe>; +} export function graphql(args: GraphQLArgs): Promise { // Always return a Promise for a consistent API. diff --git a/src/index.js b/src/index.js deleted file mode 100644 index c4be819449..0000000000 --- a/src/index.js +++ /dev/null @@ -1,455 +0,0 @@ -/** - * GraphQL.js provides a reference implementation for the GraphQL specification - * but is also a useful utility for operating on GraphQL files and building - * sophisticated tools. - * - * This primary module exports a general purpose function for fulfilling all - * steps of the GraphQL specification in a single operation, but also includes - * utilities for every part of the GraphQL specification: - * - * - Parsing the GraphQL language. - * - Building a GraphQL type schema. - * - Validating a GraphQL request against a type schema. - * - Executing a GraphQL request against a type schema. - * - * This also includes utility functions for operating on GraphQL types and - * GraphQL documents to facilitate building tools. - * - * You may also import from each sub-directory directly. For example, the - * following two import statements are equivalent: - * - * import { parse } from 'graphql'; - * import { parse } from 'graphql/language'; - */ - -/** The GraphQL.js version info. */ -export { version, versionInfo } from './version'; - -/** The primary entry point into fulfilling a GraphQL request. */ -export type { GraphQLArgs } from './graphql'; -export { graphql, graphqlSync } from './graphql'; - -/** Create and operate on GraphQL type definitions and schema. */ -export { - /** Definitions */ - GraphQLSchema, - GraphQLDirective, - GraphQLScalarType, - GraphQLObjectType, - GraphQLInterfaceType, - GraphQLUnionType, - GraphQLEnumType, - GraphQLInputObjectType, - GraphQLList, - GraphQLNonNull, - /** Standard GraphQL Scalars */ - specifiedScalarTypes, - GraphQLInt, - GraphQLFloat, - GraphQLString, - GraphQLBoolean, - 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. */ - introspectionTypes, - __Schema, - __Directive, - __DirectiveLocation, - __Type, - __Field, - __InputValue, - __EnumValue, - __TypeKind, - /** Meta-field definitions. */ - SchemaMetaFieldDef, - TypeMetaFieldDef, - TypeNameMetaFieldDef, - /** Predicates */ - isSchema, - isDirective, - isType, - isScalarType, - isObjectType, - isInterfaceType, - isUnionType, - isEnumType, - isInputObjectType, - isListType, - isNonNullType, - isInputType, - isOutputType, - isLeafType, - isCompositeType, - isAbstractType, - isWrappingType, - isNullableType, - isNamedType, - isRequiredArgument, - isRequiredInputField, - isSpecifiedScalarType, - isIntrospectionType, - isSpecifiedDirective, - /** Assertions */ - assertSchema, - assertDirective, - assertType, - assertScalarType, - assertObjectType, - assertInterfaceType, - assertUnionType, - assertEnumType, - assertInputObjectType, - assertListType, - assertNonNullType, - assertInputType, - assertOutputType, - assertLeafType, - assertCompositeType, - assertAbstractType, - assertWrappingType, - assertNullableType, - assertNamedType, - /** Un-modifiers */ - getNullableType, - getNamedType, - /** Validate GraphQL schema. */ - validateSchema, - assertValidSchema, -} from './type/index'; - -export type { - GraphQLType, - GraphQLInputType, - GraphQLOutputType, - GraphQLLeafType, - GraphQLCompositeType, - GraphQLAbstractType, - GraphQLWrappingType, - GraphQLNullableType, - GraphQLNamedType, - GraphQLNamedInputType, - GraphQLNamedOutputType, - ThunkArray, - ThunkObjMap, - GraphQLSchemaConfig, - GraphQLDirectiveConfig, - GraphQLArgument, - GraphQLArgumentConfig, - GraphQLEnumTypeConfig, - GraphQLEnumValue, - GraphQLEnumValueConfig, - GraphQLEnumValueConfigMap, - GraphQLField, - GraphQLFieldConfig, - GraphQLFieldConfigArgumentMap, - GraphQLFieldConfigMap, - GraphQLFieldMap, - GraphQLFieldResolver, - GraphQLInputField, - GraphQLInputFieldConfig, - GraphQLInputFieldConfigMap, - GraphQLInputFieldMap, - GraphQLInputObjectTypeConfig, - GraphQLInterfaceTypeConfig, - GraphQLIsTypeOfFn, - GraphQLObjectTypeConfig, - GraphQLResolveInfo, - ResponsePath, - GraphQLScalarTypeConfig, - GraphQLTypeResolver, - GraphQLUnionTypeConfig, - GraphQLScalarSerializer, - GraphQLScalarValueParser, - GraphQLScalarLiteralParser, -} from './type/index'; - -/** Parse and operate on GraphQL language source files. */ -export { - Token, - Source, - Location, - getLocation, - /** Print source location */ - printLocation, - printSourceLocation, - /** Lex */ - Lexer, - TokenKind, - /** Parse */ - parse, - parseValue, - parseConstValue, - parseType, - /** Print */ - print, - /** Visit */ - visit, - visitInParallel, - getVisitFn, - BREAK, - Kind, - DirectiveLocation, - /** Predicates */ - isDefinitionNode, - isExecutableDefinitionNode, - isSelectionNode, - isValueNode, - isConstValueNode, - isTypeNode, - isTypeSystemDefinitionNode, - isTypeDefinitionNode, - isTypeSystemExtensionNode, - isTypeExtensionNode, -} from './language/index'; - -export type { - ParseOptions, - SourceLocation, - TokenKindEnum, - KindEnum, - DirectiveLocationEnum, - /** Visitor utilities */ - ASTVisitor, - ASTVisitFn, - /** AST nodes */ - ASTNode, - ASTKindToNode, - /** Each kind of AST node */ - NameNode, - DocumentNode, - DefinitionNode, - ExecutableDefinitionNode, - OperationDefinitionNode, - OperationTypeNode, - VariableDefinitionNode, - VariableNode, - SelectionSetNode, - SelectionNode, - FieldNode, - ArgumentNode, - ConstArgumentNode, - FragmentSpreadNode, - InlineFragmentNode, - FragmentDefinitionNode, - ValueNode, - ConstValueNode, - IntValueNode, - FloatValueNode, - StringValueNode, - BooleanValueNode, - NullValueNode, - EnumValueNode, - ListValueNode, - ConstListValueNode, - ObjectValueNode, - ConstObjectValueNode, - ObjectFieldNode, - ConstObjectFieldNode, - DirectiveNode, - ConstDirectiveNode, - TypeNode, - NamedTypeNode, - ListTypeNode, - NonNullTypeNode, - TypeSystemDefinitionNode, - SchemaDefinitionNode, - OperationTypeDefinitionNode, - TypeDefinitionNode, - ScalarTypeDefinitionNode, - ObjectTypeDefinitionNode, - FieldDefinitionNode, - InputValueDefinitionNode, - InterfaceTypeDefinitionNode, - UnionTypeDefinitionNode, - EnumTypeDefinitionNode, - EnumValueDefinitionNode, - InputObjectTypeDefinitionNode, - DirectiveDefinitionNode, - TypeSystemExtensionNode, - SchemaExtensionNode, - TypeExtensionNode, - ScalarTypeExtensionNode, - ObjectTypeExtensionNode, - InterfaceTypeExtensionNode, - UnionTypeExtensionNode, - EnumTypeExtensionNode, - InputObjectTypeExtensionNode, -} from './language/index'; - -/** Execute GraphQL queries. */ -export { - execute, - executeSync, - defaultFieldResolver, - defaultTypeResolver, - responsePathAsArray, - getDirectiveValues, -} from './execution/index'; - -export type { - ExecutionArgs, - ExecutionResult, - FormattedExecutionResult, -} from './execution/index'; - -export { subscribe, createSourceEventStream } from './subscription/index'; -export type { SubscriptionArgs } from './subscription/index'; - -/** Validate GraphQL documents. */ -export { - validate, - ValidationContext, - /** All validation rules in the GraphQL Specification. */ - specifiedRules, - /** Individual validation rules. */ - ExecutableDefinitionsRule, - FieldsOnCorrectTypeRule, - FragmentsOnCompositeTypesRule, - KnownArgumentNamesRule, - KnownDirectivesRule, - KnownFragmentNamesRule, - KnownTypeNamesRule, - LoneAnonymousOperationRule, - NoFragmentCyclesRule, - NoUndefinedVariablesRule, - NoUnusedFragmentsRule, - NoUnusedVariablesRule, - OverlappingFieldsCanBeMergedRule, - PossibleFragmentSpreadsRule, - ProvidedRequiredArgumentsRule, - ScalarLeafsRule, - SingleFieldSubscriptionsRule, - UniqueArgumentNamesRule, - UniqueDirectivesPerLocationRule, - UniqueFragmentNamesRule, - UniqueInputFieldNamesRule, - UniqueOperationNamesRule, - UniqueVariableNamesRule, - ValuesOfCorrectTypeRule, - VariablesAreInputTypesRule, - VariablesInAllowedPositionRule, - /** SDL-specific validation rules */ - LoneSchemaDefinitionRule, - UniqueOperationTypesRule, - UniqueTypeNamesRule, - UniqueEnumValueNamesRule, - UniqueFieldDefinitionNamesRule, - UniqueDirectiveNamesRule, - PossibleTypeExtensionsRule, - /** Custom validation rules */ - NoDeprecatedCustomRule, - NoSchemaIntrospectionCustomRule, -} from './validation/index'; - -export type { ValidationRule } from './validation/index'; - -/** Create, format, and print GraphQL errors. */ -export { - GraphQLError, - syntaxError, - locatedError, - printError, - formatError, -} from './error/index'; - -export type { 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 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 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 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 of a GraphQL document. */ - 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. */ - BreakingChangeType, - DangerousChangeType, - findBreakingChanges, - findDangerousChanges, -} from './utilities/index'; - -export type { - IntrospectionOptions, - IntrospectionQuery, - IntrospectionSchema, - IntrospectionType, - IntrospectionInputType, - IntrospectionOutputType, - IntrospectionScalarType, - IntrospectionObjectType, - IntrospectionInterfaceType, - IntrospectionUnionType, - IntrospectionEnumType, - IntrospectionInputObjectType, - IntrospectionTypeRef, - IntrospectionInputTypeRef, - IntrospectionOutputTypeRef, - IntrospectionNamedTypeRef, - IntrospectionListTypeRef, - IntrospectionNonNullTypeRef, - IntrospectionField, - IntrospectionInputValue, - IntrospectionEnumValue, - IntrospectionDirective, - BuildSchemaOptions, - BreakingChange, - DangerousChange, -} from './utilities/index'; diff --git a/src/index.d.ts b/src/index.ts similarity index 99% rename from src/index.d.ts rename to src/index.ts index 6a1733c97c..d9d02c9245 100644 --- a/src/index.d.ts +++ b/src/index.ts @@ -21,11 +21,14 @@ * import { parse } from 'graphql'; * import { parse } from 'graphql/language'; */ + /** The GraphQL.js version info. */ export { version, versionInfo } from './version'; + /** The primary entry point into fulfilling a GraphQL request. */ export type { GraphQLArgs } from './graphql'; export { graphql, graphqlSync } from './graphql'; + /** Create and operate on GraphQL type definitions and schema. */ export { /** Definitions */ @@ -122,6 +125,7 @@ export { validateSchema, assertValidSchema, } from './type/index'; + export type { GraphQLType, GraphQLInputType, @@ -179,6 +183,7 @@ export type { GraphQLScalarValueParser, GraphQLScalarLiteralParser, } from './type/index'; + /** Parse and operate on GraphQL language source files. */ export { Token, @@ -217,6 +222,7 @@ export { isTypeSystemExtensionNode, isTypeExtensionNode, } from './language/index'; + export type { ParseOptions, SourceLocation, @@ -290,6 +296,7 @@ export type { EnumTypeExtensionNode, InputObjectTypeExtensionNode, } from './language/index'; + /** Execute GraphQL queries. */ export { execute, @@ -299,13 +306,16 @@ export { responsePathAsArray, getDirectiveValues, } from './execution/index'; + export type { ExecutionArgs, ExecutionResult, FormattedExecutionResult, } from './execution/index'; + export { subscribe, createSourceEventStream } from './subscription/index'; export type { SubscriptionArgs } from './subscription/index'; + /** Validate GraphQL documents. */ export { validate, @@ -351,7 +361,9 @@ export { NoDeprecatedCustomRule, NoSchemaIntrospectionCustomRule, } from './validation/index'; + export type { ValidationRule } from './validation/index'; + /** Create, format, and print GraphQL errors. */ export { GraphQLError, @@ -360,7 +372,9 @@ export { printError, formatError, } from './error/index'; + export type { GraphQLFormattedError } from './error/index'; + /** Utilities for operating on GraphQL type schema and parsed sources. */ export { /** @@ -423,6 +437,7 @@ export { findBreakingChanges, findDangerousChanges, } from './utilities/index'; + export type { IntrospectionOptions, IntrospectionQuery, diff --git a/src/jsutils/Maybe.d.ts b/src/jsutils/Maybe.ts similarity index 100% rename from src/jsutils/Maybe.d.ts rename to src/jsutils/Maybe.ts 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.d.ts b/src/jsutils/ObjMap.ts similarity index 58% rename from src/jsutils/ObjMap.d.ts rename to src/jsutils/ObjMap.ts index fa87afb12d..2c20282187 100644 --- a/src/jsutils/ObjMap.d.ts +++ b/src/jsutils/ObjMap.ts @@ -1,16 +1,13 @@ export interface ObjMap { [key: string]: T; } -export type ObjMapLike = - | ObjMap - | { - [key: string]: T; - }; + +export type ObjMapLike = ObjMap | { [key: string]: T }; + export interface ReadOnlyObjMap { readonly [key: string]: T; } + export type ReadOnlyObjMapLike = | ReadOnlyObjMap - | { - readonly [key: string]: T; - }; + | { readonly [key: string]: T }; diff --git a/src/jsutils/Path.js b/src/jsutils/Path.js deleted file mode 100644 index f7888ae027..0000000000 --- a/src/jsutils/Path.js +++ /dev/null @@ -1,29 +0,0 @@ -export type Path = { - +prev: Path | void, - +key: string | number, - +typename: string | void, -}; - -/** - * Given a Path and a key, return a new Path containing the new key. - */ -export function addPath( - prev: $ReadOnly | void, - key: string | number, - typename: string | void, -): Path { - return { prev, key, typename }; -} - -/** - * Given a Path, return an Array of the path keys. - */ -export function pathToArray(path: ?$ReadOnly): Array { - const flattened = []; - let curr = path; - while (curr) { - flattened.push(curr.key); - curr = curr.prev; - } - return flattened.reverse(); -} diff --git a/src/jsutils/Path.d.ts b/src/jsutils/Path.ts similarity index 68% rename from src/jsutils/Path.d.ts rename to src/jsutils/Path.ts index 943c3a5dc7..64f6c78358 100644 --- a/src/jsutils/Path.d.ts +++ b/src/jsutils/Path.ts @@ -1,9 +1,11 @@ import type { Maybe } from './Maybe'; + export interface Path { readonly prev: Path | undefined; readonly key: string | number; readonly typename: string | undefined; } + /** * Given a Path and a key, return a new Path containing the new key. */ @@ -11,10 +13,21 @@ export function addPath( prev: Readonly | undefined, key: string | number, typename: string | undefined, -): Path; +): Path { + return { prev, key, typename }; +} + /** * Given a Path, return an Array of the path keys. */ export function pathToArray( path: Maybe>, -): Array; +): Array { + const flattened = []; + let curr = path; + while (curr) { + flattened.push(curr.key); + curr = curr.prev; + } + return flattened.reverse(); +} 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.d.ts b/src/jsutils/PromiseOrValue.ts similarity index 100% rename from src/jsutils/PromiseOrValue.d.ts rename to src/jsutils/PromiseOrValue.ts 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 90% rename from src/jsutils/__tests__/identityFunc-test.js rename to src/jsutils/__tests__/identityFunc-test.ts index 82a6c914d8..625e20c457 100644 --- a/src/jsutils/__tests__/identityFunc-test.js +++ b/src/jsutils/__tests__/identityFunc-test.ts @@ -5,6 +5,7 @@ import { identityFunc } from '../identityFunc'; describe('identityFunc', () => { it('returns the first argument it receives', () => { + // @ts-expect-error FIXME: TS Conversion expect(identityFunc()).to.equal(undefined); expect(identityFunc(undefined)).to.equal(undefined); expect(identityFunc(null)).to.equal(null); diff --git a/src/jsutils/__tests__/inspect-test.js b/src/jsutils/__tests__/inspect-test.ts similarity index 97% rename from src/jsutils/__tests__/inspect-test.js rename to src/jsutils/__tests__/inspect-test.ts index 3db57fbe92..a4f17177ac 100644 --- a/src/jsutils/__tests__/inspect-test.js +++ b/src/jsutils/__tests__/inspect-test.ts @@ -124,7 +124,7 @@ describe('inspect', () => { }); it('detect circular objects', () => { - const obj = {}; + const obj: { [name: string]: unknown } = {}; obj.self = obj; obj.deepSelf = { self: obj }; @@ -165,13 +165,12 @@ describe('inspect', () => { expect(inspect([[new Foo()]])).to.equal('[[[Foo]]]'); - // $FlowExpectedError[prop-missing] Foo.prototype[Symbol.toStringTag] = 'Bar'; expect(inspect([[new Foo()]])).to.equal('[[[Bar]]]'); // eslint-disable-next-line func-names const objectWithoutClassName = new (function () { - // eslint-disable-next-line no-invalid-this + // eslint-disable-next-line @typescript-eslint/no-invalid-this this.foo = 1; })(); expect(inspect([[objectWithoutClassName]])).to.equal('[[[Object]]]'); 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__/isIterableObject-test.js b/src/jsutils/__tests__/isIterableObject-test.ts similarity index 97% rename from src/jsutils/__tests__/isIterableObject-test.js rename to src/jsutils/__tests__/isIterableObject-test.ts index 3338638de5..3997a69e09 100644 --- a/src/jsutils/__tests__/isIterableObject-test.js +++ b/src/jsutils/__tests__/isIterableObject-test.ts @@ -60,7 +60,7 @@ describe('isIterableObject', () => { }; expect(isIterableObject(invalidIterable)).to.equal(false); - const arrayLike = {}; + const arrayLike: { [key: string]: unknown } = {}; arrayLike[0] = 'Alpha'; arrayLike[1] = 'Bravo'; arrayLike[2] = 'Charlie'; 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__/naturalCompare-test.js b/src/jsutils/__tests__/naturalCompare-test.ts similarity index 100% rename from src/jsutils/__tests__/naturalCompare-test.js rename to src/jsutils/__tests__/naturalCompare-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 a1993324af..8086193dbd 100644 --- a/src/jsutils/__tests__/toObjMap-test.js +++ b/src/jsutils/__tests__/toObjMap-test.ts @@ -4,7 +4,7 @@ import { describe, it } from 'mocha'; import type { ObjMapLike } from '../ObjMap'; import { toObjMap } from '../toObjMap'; -// Workaround to make both ESLint and Flow happy +// Workaround to make both ESLint happy const __proto__ = '__proto__'; describe('toObjMap', () => { diff --git a/src/jsutils/devAssert.d.ts b/src/jsutils/devAssert.d.ts deleted file mode 100644 index 451b6ef3e0..0000000000 --- a/src/jsutils/devAssert.d.ts +++ /dev/null @@ -1 +0,0 @@ -export function devAssert(condition: unknown, message: string): void; diff --git a/src/jsutils/devAssert.js b/src/jsutils/devAssert.ts similarity index 73% rename from src/jsutils/devAssert.js rename to src/jsutils/devAssert.ts index 5fcbc16eb7..aeaad3b0f1 100644 --- a/src/jsutils/devAssert.js +++ b/src/jsutils/devAssert.ts @@ -1,4 +1,4 @@ -export function devAssert(condition: mixed, message: string): void { +export 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.d.ts b/src/jsutils/didYouMean.d.ts deleted file mode 100644 index a4b8a5bb7d..0000000000 --- a/src/jsutils/didYouMean.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Given [ A, B, C ] return ' Did you mean A, B, or C?'. - */ -export function didYouMean(suggestions: ReadonlyArray): string; -export function didYouMean( - subMessage: string, - suggestions: ReadonlyArray, -): string; 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 ad1ef1203e..4f15678975 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( +export function didYouMean(suggestions: ReadonlyArray): string; +export function didYouMean( subMessage: string, - suggestions: $ReadOnlyArray, + suggestions: ReadonlyArray, ): string; - -// eslint-disable-next-line no-redeclare -export function didYouMean(firstArg, secondArg) { +export function didYouMean( + firstArg: string | ReadonlyArray, + secondArg?: ReadonlyArray, +) { const [subMessage, suggestionsArg] = typeof firstArg === 'string' ? [firstArg, secondArg] diff --git a/src/jsutils/identityFunc.d.ts b/src/jsutils/identityFunc.d.ts deleted file mode 100644 index 55854eb493..0000000000 --- a/src/jsutils/identityFunc.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Returns the first argument it receives. - */ -export function identityFunc(x: T): T; 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.d.ts b/src/jsutils/inspect.d.ts deleted file mode 100644 index 29c96a1542..0000000000 --- a/src/jsutils/inspect.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Used to print values in error messages. - */ -export function inspect(value: unknown): string; diff --git a/src/jsutils/inspect.js b/src/jsutils/inspect.ts similarity index 82% rename from src/jsutils/inspect.js rename to src/jsutils/inspect.ts index 2c90dc4ca2..4616edc316 100644 --- a/src/jsutils/inspect.js +++ b/src/jsutils/inspect.ts @@ -1,16 +1,14 @@ -/* eslint-disable flowtype/no-weak-types */ - const MAX_ARRAY_LENGTH = 10; const MAX_RECURSIVE_DEPTH = 2; /** * Used to print values in error messages. */ -export function inspect(value: mixed): string { +export 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); @@ -25,7 +23,7 @@ function formatValue(value: mixed, seenValues: Array): string { function formatObjectValue( value: Object, - previouslySeenValues: Array, + previouslySeenValues: Array, ): string { if (value === null) { return 'null'; @@ -37,8 +35,10 @@ function formatObjectValue( const seenValues = [...previouslySeenValues, value]; + // @ts-expect-error FIXME: TS Conversion if (typeof value.toJSON === 'function') { - const jsonValue = (value.toJSON: () => mixed)(); + // @ts-expect-error FIXME: TS Conversion + const jsonValue = (value.toJSON as () => unknown)(); // check for infinite recursion if (jsonValue !== value) { @@ -53,7 +53,7 @@ function formatObjectValue( return formatObject(value, seenValues); } -function formatObject(object: Object, seenValues: Array): string { +function formatObject(object: Object, seenValues: Array): string { const entries = Object.entries(object); if (entries.length === 0) { return '{}'; @@ -69,7 +69,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.d.ts b/src/jsutils/instanceOf.d.ts deleted file mode 100644 index 03221d907b..0000000000 --- a/src/jsutils/instanceOf.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * A replacement for instanceof which includes an error warning when multi-realm - * constructors are detected. - * See: https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production - * See: https://webpack.js.org/guides/production/ - */ -export const instanceOf: (value: unknown, constructor: Constructor) => boolean; -interface Constructor extends Function { - name: string; -} diff --git a/src/jsutils/instanceOf.js b/src/jsutils/instanceOf.ts similarity index 87% rename from src/jsutils/instanceOf.js rename to src/jsutils/instanceOf.ts index 1f2df36707..26b6c16d1b 100644 --- a/src/jsutils/instanceOf.js +++ b/src/jsutils/instanceOf.ts @@ -4,10 +4,10 @@ * See: https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production * See: https://webpack.js.org/guides/production/ */ -export const instanceOf: (value: mixed, constructor: Constructor) => boolean = +export const instanceOf: (value: unknown, constructor: Constructor) => boolean = process.env.NODE_ENV === 'production' ? // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317') - function instanceOf(value: mixed, constructor: Constructor): boolean { + function instanceOf(value: unknown, constructor: Constructor): boolean { return value instanceof constructor; } : function instanceOf(value: any, constructor: Constructor): boolean { @@ -37,7 +37,6 @@ spurious results.`, return false; }; -type Constructor = { - name: string, - ... -}; +interface Constructor extends Function { + name: string; +} diff --git a/src/jsutils/invariant.d.ts b/src/jsutils/invariant.d.ts deleted file mode 100644 index f6ab910bd4..0000000000 --- a/src/jsutils/invariant.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function invariant( - condition: unknown, - message?: string, -): asserts condition; diff --git a/src/jsutils/invariant.js b/src/jsutils/invariant.ts similarity index 74% rename from src/jsutils/invariant.js rename to src/jsutils/invariant.ts index 099ffd801a..47561cbb3c 100644 --- a/src/jsutils/invariant.js +++ b/src/jsutils/invariant.ts @@ -1,4 +1,7 @@ -export function invariant(condition: mixed, message?: string): void { +export function invariant( + condition: unknown, + message?: string, +): asserts condition { 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.js deleted file mode 100644 index cebbda4feb..0000000000 --- a/src/jsutils/isAsyncIterable.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Returns true if the provided object implements the AsyncIterator protocol via - * implementing a `Symbol.asyncIterator` method. - */ -declare function isAsyncIterable( - value: mixed, - // $FlowFixMe[invalid-in-rhs] -): boolean %checks(value instanceof AsyncIterable); - -// eslint-disable-next-line no-redeclare -export function isAsyncIterable(maybeAsyncIterable) { - return typeof maybeAsyncIterable?.[Symbol.asyncIterator] === 'function'; -} diff --git a/src/jsutils/isAsyncIterable.d.ts b/src/jsutils/isAsyncIterable.ts similarity index 61% rename from src/jsutils/isAsyncIterable.d.ts rename to src/jsutils/isAsyncIterable.ts index df7e0564f1..8f26130003 100644 --- a/src/jsutils/isAsyncIterable.d.ts +++ b/src/jsutils/isAsyncIterable.ts @@ -4,4 +4,6 @@ */ export function isAsyncIterable( maybeAsyncIterable: unknown, -): maybeAsyncIterable is AsyncIterable; +): maybeAsyncIterable is AsyncIterable { + return typeof maybeAsyncIterable?.[Symbol.asyncIterator] === 'function'; +} diff --git a/src/jsutils/isIterableObject.js b/src/jsutils/isIterableObject.js deleted file mode 100644 index c60f0f84ce..0000000000 --- a/src/jsutils/isIterableObject.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Returns true if the provided object is an Object (i.e. not a string literal) - * and implements the Iterator protocol. - * - * This may be used in place of [Array.isArray()][isArray] to determine if - * an object should be iterated-over e.g. Array, Map, Set, Int8Array, - * TypedArray, etc. but excludes string literals. - * - * @example - * - * isIterableObject([ 1, 2, 3 ]) // true - * isIterableObject(new Map()) // true - * isIterableObject('ABC') // false - * isIterableObject({ key: 'value' }) // false - * isIterableObject({ length: 1, 0: 'Alpha' }) // false - */ -declare function isIterableObject( - value: mixed, - // $FlowFixMe[invalid-in-rhs] -): boolean %checks(value instanceof Iterable); - -// eslint-disable-next-line no-redeclare -export function isIterableObject(maybeIterable: mixed): boolean { - return ( - typeof maybeIterable === 'object' && - typeof maybeIterable?.[Symbol.iterator] === 'function' - ); -} diff --git a/src/jsutils/isIterableObject.d.ts b/src/jsutils/isIterableObject.ts similarity index 79% rename from src/jsutils/isIterableObject.d.ts rename to src/jsutils/isIterableObject.ts index 0529d67f86..032b28ae51 100644 --- a/src/jsutils/isIterableObject.d.ts +++ b/src/jsutils/isIterableObject.ts @@ -16,4 +16,9 @@ */ export function isIterableObject( maybeIterable: unknown, -): maybeIterable is Iterable; +): maybeIterable is Iterable { + return ( + typeof maybeIterable === 'object' && + typeof maybeIterable?.[Symbol.iterator] === 'function' + ); +} diff --git a/src/jsutils/isObjectLike.d.ts b/src/jsutils/isObjectLike.d.ts deleted file mode 100644 index 6e58c1145f..0000000000 --- a/src/jsutils/isObjectLike.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * 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 function isObjectLike(value: unknown): value is { - [key: string]: unknown; -}; diff --git a/src/jsutils/isObjectLike.js b/src/jsutils/isObjectLike.ts similarity index 67% rename from src/jsutils/isObjectLike.js rename to src/jsutils/isObjectLike.ts index 9c182ac38d..1d43e26718 100644 --- a/src/jsutils/isObjectLike.js +++ b/src/jsutils/isObjectLike.ts @@ -2,6 +2,8 @@ * 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 function isObjectLike(value: mixed): boolean %checks { +export function isObjectLike( + value: unknown, +): value is { [key: string]: unknown } { return typeof value == 'object' && value !== null; } diff --git a/src/jsutils/isPromise.js b/src/jsutils/isPromise.js deleted file mode 100644 index 41998354a3..0000000000 --- a/src/jsutils/isPromise.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * 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); - -// eslint-disable-next-line no-redeclare -export function isPromise(value) { - return typeof value?.then === 'function'; -} diff --git a/src/jsutils/isPromise.d.ts b/src/jsutils/isPromise.ts similarity index 59% rename from src/jsutils/isPromise.d.ts rename to src/jsutils/isPromise.ts index 884f39afb1..69b0a9910e 100644 --- a/src/jsutils/isPromise.d.ts +++ b/src/jsutils/isPromise.ts @@ -2,4 +2,7 @@ * Returns true if the value acts like a Promise, i.e. has a "then" function, * otherwise returns false. */ -export function isPromise(value: unknown): value is Promise; +export function isPromise(value: unknown): value is Promise { + // eslint-disable-next-line @typescript-eslint/dot-notation + return typeof value?.['then'] === 'function'; +} diff --git a/src/jsutils/keyMap.d.ts b/src/jsutils/keyMap.d.ts deleted file mode 100644 index 60faa82e71..0000000000 --- a/src/jsutils/keyMap.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { ObjMap } from './ObjMap'; -/** - * Creates a keyed JS object from an array, given a function to produce the keys - * for each value in the array. - * - * This provides a convenient lookup for the array items if the key function - * produces unique results. - * - * const phoneBook = [ - * { name: 'Jon', num: '555-1234' }, - * { name: 'Jenny', num: '867-5309' } - * ] - * - * // { Jon: { name: 'Jon', num: '555-1234' }, - * // Jenny: { name: 'Jenny', num: '867-5309' } } - * const entriesByName = keyMap( - * phoneBook, - * entry => entry.name - * ) - * - * // { name: 'Jenny', num: '857-6309' } - * const jennyEntry = entriesByName['Jenny'] - * - */ -export function keyMap( - list: ReadonlyArray, - keyFn: (item: T) => string, -): ObjMap; diff --git a/src/jsutils/keyMap.js b/src/jsutils/keyMap.ts similarity index 97% rename from src/jsutils/keyMap.js rename to src/jsutils/keyMap.ts index 8bfaf2727c..2425850b06 100644 --- a/src/jsutils/keyMap.js +++ b/src/jsutils/keyMap.ts @@ -24,7 +24,7 @@ import type { ObjMap } from './ObjMap'; * */ export function keyMap( - list: $ReadOnlyArray, + list: ReadonlyArray, keyFn: (item: T) => string, ): ObjMap { const result = Object.create(null); diff --git a/src/jsutils/keyValMap.d.ts b/src/jsutils/keyValMap.d.ts deleted file mode 100644 index 634d099be1..0000000000 --- a/src/jsutils/keyValMap.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ObjMap } from './ObjMap'; -/** - * Creates a keyed JS object from an array, given a function to produce the keys - * and a function to produce the values from each item in the array. - * - * const phoneBook = [ - * { name: 'Jon', num: '555-1234' }, - * { name: 'Jenny', num: '867-5309' } - * ] - * - * // { Jon: '555-1234', Jenny: '867-5309' } - * const phonesByName = keyValMap( - * phoneBook, - * entry => entry.name, - * entry => entry.num - * ) - * - */ -export function keyValMap( - list: ReadonlyArray, - keyFn: (item: T) => string, - valFn: (item: T) => V, -): ObjMap; diff --git a/src/jsutils/keyValMap.js b/src/jsutils/keyValMap.ts similarity index 96% rename from src/jsutils/keyValMap.js rename to src/jsutils/keyValMap.ts index d046cbd5e3..c6013aaa16 100644 --- a/src/jsutils/keyValMap.js +++ b/src/jsutils/keyValMap.ts @@ -18,7 +18,7 @@ import type { ObjMap } from './ObjMap'; * */ export function keyValMap( - list: $ReadOnlyArray, + list: ReadonlyArray, keyFn: (item: T) => string, valFn: (item: T) => V, ): ObjMap { diff --git a/src/jsutils/mapValue.d.ts b/src/jsutils/mapValue.d.ts deleted file mode 100644 index 31bb779e93..0000000000 --- a/src/jsutils/mapValue.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ObjMap, ReadOnlyObjMap } from './ObjMap'; -/** - * Creates an object map with the same keys as `map` and values generated by - * running each value of `map` thru `fn`. - */ -export function mapValue( - map: ReadOnlyObjMap, - fn: (value: T, key: string) => V, -): ObjMap; diff --git a/src/jsutils/mapValue.js b/src/jsutils/mapValue.ts similarity index 100% rename from src/jsutils/mapValue.js rename to src/jsutils/mapValue.ts diff --git a/src/jsutils/memoize3.d.ts b/src/jsutils/memoize3.d.ts deleted file mode 100644 index f4254cd9f9..0000000000 --- a/src/jsutils/memoize3.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-types */ -/** - * Memoizes the provided three-argument function. - */ -export function memoize3< - A1 extends object, - A2 extends object, - A3 extends object, - R, ->(fn: (a1: A1, a2: A2, a3: A3) => R): (a1: A1, a2: A2, a3: A3) => R; diff --git a/src/jsutils/memoize3.js b/src/jsutils/memoize3.ts similarity index 85% rename from src/jsutils/memoize3.js rename to src/jsutils/memoize3.ts index fe7f9a4d79..e6ac2faf1d 100644 --- a/src/jsutils/memoize3.js +++ b/src/jsutils/memoize3.ts @@ -2,9 +2,9 @@ * Memoizes the provided three-argument function. */ export function memoize3< - A1: { ... } | $ReadOnlyArray, - A2: { ... } | $ReadOnlyArray, - A3: { ... } | $ReadOnlyArray, + A1 extends object, + A2 extends object, + A3 extends object, R, >(fn: (a1: A1, a2: A2, a3: A3) => R): (a1: A1, a2: A2, a3: A3) => R { let cache0; diff --git a/src/jsutils/naturalCompare.d.ts b/src/jsutils/naturalCompare.d.ts deleted file mode 100644 index a5fe31be1e..0000000000 --- a/src/jsutils/naturalCompare.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Returns a number indicating whether a reference string comes before, or after, - * or is the same as the given string in natural sort order. - * - * See: https://en.wikipedia.org/wiki/Natural_sort_order - * - */ -export function naturalCompare(aStr: string, bStr: string): number; diff --git a/src/jsutils/naturalCompare.js b/src/jsutils/naturalCompare.ts similarity index 100% rename from src/jsutils/naturalCompare.js rename to src/jsutils/naturalCompare.ts diff --git a/src/jsutils/printPathArray.d.ts b/src/jsutils/printPathArray.d.ts deleted file mode 100644 index 69bc1606e1..0000000000 --- a/src/jsutils/printPathArray.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Build a string describing the path. - */ -export function printPathArray(path: ReadonlyArray): string; diff --git a/src/jsutils/printPathArray.js b/src/jsutils/printPathArray.ts similarity index 68% rename from src/jsutils/printPathArray.js rename to src/jsutils/printPathArray.ts index 4e9e773afa..0d9fcc2b19 100644 --- a/src/jsutils/printPathArray.js +++ b/src/jsutils/printPathArray.ts @@ -1,7 +1,7 @@ /** * Build a string describing the path. */ -export function printPathArray(path: $ReadOnlyArray): string { +export function printPathArray(path: ReadonlyArray): string { return path .map((key) => typeof key === 'number' ? '[' + key.toString() + ']' : '.' + key, diff --git a/src/jsutils/promiseForObject.d.ts b/src/jsutils/promiseForObject.d.ts deleted file mode 100644 index 4f67802622..0000000000 --- a/src/jsutils/promiseForObject.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ObjMap } from './ObjMap'; -/** - * This function transforms a JS object `ObjMap>` into - * a `Promise>` - * - * This is akin to bluebird's `Promise.props`, but implemented only using - * `Promise.all` so it will work with any implementation of ES6 promises. - */ -export function promiseForObject( - object: ObjMap>, -): Promise>; diff --git a/src/jsutils/promiseForObject.js b/src/jsutils/promiseForObject.ts similarity index 100% rename from src/jsutils/promiseForObject.js rename to src/jsutils/promiseForObject.ts diff --git a/src/jsutils/promiseReduce.d.ts b/src/jsutils/promiseReduce.d.ts deleted file mode 100644 index 85ad5f2ff5..0000000000 --- a/src/jsutils/promiseReduce.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { PromiseOrValue } from './PromiseOrValue'; -/** - * Similar to Array.prototype.reduce(), however the reducing callback may return - * a Promise, in which case reduction will continue after each promise resolves. - * - * If the callback does not return a Promise, then this function will also not - * return a Promise. - */ -export function promiseReduce( - values: Iterable, - callbackFn: (accumulator: U, currentValue: T) => PromiseOrValue, - initialValue: PromiseOrValue, -): PromiseOrValue; diff --git a/src/jsutils/promiseReduce.js b/src/jsutils/promiseReduce.ts similarity index 100% rename from src/jsutils/promiseReduce.js rename to src/jsutils/promiseReduce.ts diff --git a/src/jsutils/suggestionList.d.ts b/src/jsutils/suggestionList.d.ts deleted file mode 100644 index 6b255c244f..0000000000 --- a/src/jsutils/suggestionList.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Given an invalid input string and a list of valid options, returns a filtered - * list of valid options sorted based on their similarity with the input. - */ -export function suggestionList( - input: string, - options: ReadonlyArray, -): Array; diff --git a/src/jsutils/suggestionList.js b/src/jsutils/suggestionList.ts similarity index 97% rename from src/jsutils/suggestionList.js rename to src/jsutils/suggestionList.ts index d500648031..53ad685c8c 100644 --- a/src/jsutils/suggestionList.js +++ b/src/jsutils/suggestionList.ts @@ -6,7 +6,7 @@ import { naturalCompare } from './naturalCompare'; */ export function suggestionList( input: string, - options: $ReadOnlyArray, + options: ReadonlyArray, ): Array { const optionsByDistance = Object.create(null); const lexicalDistance = new LexicalDistance(input); @@ -57,7 +57,7 @@ class LexicalDistance { ]; } - measure(option: string, threshold: number): number | void { + measure(option: string, threshold: number): number | undefined { if (this._input === option) { return 0; } diff --git a/src/jsutils/toObjMap.d.ts b/src/jsutils/toObjMap.d.ts deleted file mode 100644 index 951b995c4f..0000000000 --- a/src/jsutils/toObjMap.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { - ObjMap, - ObjMapLike, - ReadOnlyObjMap, - ReadOnlyObjMapLike, -} from './ObjMap'; -export function toObjMap(obj: ObjMapLike): ObjMap; -export function toObjMap(obj: ReadOnlyObjMapLike): ReadOnlyObjMap; diff --git a/src/jsutils/toObjMap.js b/src/jsutils/toObjMap.ts similarity index 54% rename from src/jsutils/toObjMap.js rename to src/jsutils/toObjMap.ts index 69ac0d06ad..63d6c27eed 100644 --- a/src/jsutils/toObjMap.js +++ b/src/jsutils/toObjMap.ts @@ -5,12 +5,9 @@ import type { ReadOnlyObjMapLike, } from './ObjMap'; -/* eslint-disable no-redeclare */ -declare function toObjMap(obj: ObjMapLike): ObjMap; -declare function toObjMap(obj: ReadOnlyObjMapLike): ReadOnlyObjMap; - -export function toObjMap(obj) { - /* eslint-enable no-redeclare */ +export function toObjMap(obj: ObjMapLike): ObjMap; +export function toObjMap(obj: ReadOnlyObjMapLike): ReadOnlyObjMap; +export function toObjMap(obj: ObjMapLike | ReadOnlyObjMapLike) { if (Object.getPrototypeOf(obj) === null) { return obj; } 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 98% rename from src/language/__tests__/predicates-test.js rename to src/language/__tests__/predicates-test.ts index 860cd33026..b90e2b31e9 100644 --- a/src/language/__tests__/predicates-test.js +++ b/src/language/__tests__/predicates-test.ts @@ -19,7 +19,7 @@ import { function filterNodes(predicate: (node: ASTNode) => boolean): Array { return Object.values(Kind).filter( - // $FlowExpectedError[speculation-ambiguous] create node only with kind + // @ts-expect-error create node only with kind (kind) => predicate({ 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 fefbdec157..cfa1e14052 100644 --- a/src/language/__tests__/printer-test.js +++ b/src/language/__tests__/printer-test.ts @@ -9,14 +9,17 @@ import { print } from '../printer'; describe('Printer: Query document', () => { it('prints minimal ast', () => { - const ast = { kind: 'Field', name: { kind: 'Name', value: 'foo' } }; + const ast = { + kind: 'Field', + name: { kind: 'Name', value: 'foo' }, + } as const; expect(print(ast)).to.equal('foo'); }); it('produces helpful error messages', () => { const badAST = { random: 'Data' }; - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => print(badAST)).to.throw( 'Invalid AST Node: { random: "Data" }.', ); 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 38dd13ebbf..e596bba35d 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 98% rename from src/language/__tests__/schema-printer-test.js rename to src/language/__tests__/schema-printer-test.ts index 26311144cb..9ad0339394 100644 --- a/src/language/__tests__/schema-printer-test.js +++ b/src/language/__tests__/schema-printer-test.ts @@ -12,14 +12,14 @@ describe('Printer: SDL document', () => { const ast = { kind: 'ScalarTypeDefinition', name: { kind: 'Name', value: 'foo' }, - }; + } as const; expect(print(ast)).to.equal('scalar foo'); }); it('produces helpful error messages', () => { const badAST = { random: 'Data' }; - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => print(badAST)).to.throw( 'Invalid AST Node: { random: "Data" }.', ); diff --git a/src/language/__tests__/source-test.js b/src/language/__tests__/source-test.ts similarity index 89% rename from src/language/__tests__/source-test.js rename to src/language/__tests__/source-test.ts index 1ea59c506d..6bf8a93e6d 100644 --- a/src/language/__tests__/source-test.js +++ b/src/language/__tests__/source-test.ts @@ -5,14 +5,14 @@ import { Source } from '../source'; describe('Source', () => { it('asserts that a body was provided', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => new Source()).to.throw( 'Body must be a string. Received: undefined.', ); }); it('asserts that a valid body was provided', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => new Source({})).to.throw( 'Body must be a string. Received: {}.', ); @@ -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 84% rename from src/language/__tests__/toJSONDeep.js rename to src/language/__tests__/toJSONDeep.ts index abd4f50b84..a82606252a 100644 --- a/src/language/__tests__/toJSONDeep.js +++ b/src/language/__tests__/toJSONDeep.ts @@ -5,13 +5,12 @@ 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 function toJSONDeep(value: mixed): mixed { +export function toJSONDeep(value: unknown): unknown { if (!isObjectLike(value)) { return value; } if (typeof value.toJSON === 'function') { - // $FlowFixMe[incompatible-use] return value.toJSON(); } diff --git a/src/language/__tests__/visitor-test.js b/src/language/__tests__/visitor-test.ts similarity index 99% rename from src/language/__tests__/visitor-test.js rename to src/language/__tests__/visitor-test.ts index 1f7455cbda..7b6820d676 100644 --- a/src/language/__tests__/visitor-test.js +++ b/src/language/__tests__/visitor-test.ts @@ -4,6 +4,7 @@ import { describe, it } from 'mocha'; import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery'; import type { ASTNode } from '../ast'; +import { isNode } from '../ast'; import { Kind } from '../kinds'; import { parse } from '../parser'; import { visit, visitInParallel, BREAK } from '../visitor'; @@ -50,6 +51,7 @@ function checkVisitorFnArgs(ast: any, args: any, isEdited: boolean = false) { } function getValue(node: ASTNode) { + // @ts-expect-error FIXME: TS Conversion return node.value != null ? node.value : undefined; } @@ -263,6 +265,7 @@ describe('Visitor', () => { if (node.kind === 'Field' && node.name.value === 'a') { return { kind: 'Field', + // @ts-expect-error FIXME: TS Conversion selectionSet: [addedField].concat(node.selectionSet), }; } @@ -420,7 +423,7 @@ describe('Visitor', () => { it('visit nodes with unknown kinds but does not traverse deeper', () => { const customAST = parse('{ a }'); - // $FlowExpectedError[prop-missing] + // @ts-expect-error customAST.definitions[0].selectionSet.selections.push({ kind: 'CustomField', name: { kind: 'Name', value: 'NamedNodeToBeSkipped' }, @@ -522,7 +525,7 @@ describe('Visitor', () => { 'enter', node.kind, key, - parent?.kind != null ? parent.kind : undefined, + isNode(parent) ? parent.kind : undefined, ]); checkVisitorFnArgs(ast, arguments); @@ -534,7 +537,7 @@ describe('Visitor', () => { 'leave', node.kind, key, - parent?.kind != null ? parent.kind : undefined, + isNode(parent) ? parent.kind : undefined, ]); expect(argsStack.pop()).to.deep.equal([...arguments]); diff --git a/src/language/ast.js b/src/language/ast.js deleted file mode 100644 index efb6ef5a87..0000000000 --- a/src/language/ast.js +++ /dev/null @@ -1,670 +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 }; - } -} - -/** - * 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, - }; - } -} - -/** - * @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?: ConstValueNode, - +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, -}; - -export type ConstArgumentNode = { - +kind: 'Argument', - +loc?: Location, - +name: NameNode, - +value: ConstValueNode, -}; - -/** 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, - /** @deprecated variableDefinitions will be removed in v17.0.0 */ - +variableDefinitions?: $ReadOnlyArray, - +typeCondition: NamedTypeNode, - +directives?: $ReadOnlyArray, - +selectionSet: SelectionSetNode, -}; - -/** Values */ - -export type ValueNode = - | VariableNode - | IntValueNode - | FloatValueNode - | StringValueNode - | BooleanValueNode - | NullValueNode - | EnumValueNode - | ListValueNode - | ObjectValueNode; - -export type ConstValueNode = - | IntValueNode - | FloatValueNode - | StringValueNode - | BooleanValueNode - | NullValueNode - | EnumValueNode - | ConstListValueNode - | ConstObjectValueNode; - -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 ConstListValueNode = { - +kind: 'ListValue', - +loc?: Location, - +values: $ReadOnlyArray, -}; - -export type ObjectValueNode = { - +kind: 'ObjectValue', - +loc?: Location, - +fields: $ReadOnlyArray, -}; - -export type ConstObjectValueNode = { - +kind: 'ObjectValue', - +loc?: Location, - +fields: $ReadOnlyArray, -}; - -export type ObjectFieldNode = { - +kind: 'ObjectField', - +loc?: Location, - +name: NameNode, - +value: ValueNode, -}; - -export type ConstObjectFieldNode = { - +kind: 'ObjectField', - +loc?: Location, - +name: NameNode, - +value: ConstValueNode, -}; - -/** Directives */ - -export type DirectiveNode = { - +kind: 'Directive', - +loc?: Location, - +name: NameNode, - +arguments?: $ReadOnlyArray, -}; - -export type ConstDirectiveNode = { - +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?: ConstValueNode, - +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.d.ts b/src/language/ast.ts similarity index 95% rename from src/language/ast.d.ts rename to src/language/ast.ts index eb1941c726..02c7370340 100644 --- a/src/language/ast.d.ts +++ b/src/language/ast.ts @@ -1,5 +1,6 @@ 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. @@ -9,28 +10,40 @@ 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); - toJSON(): { - start: number; - end: number; - }; -} + + 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 }; + } +} + /** * Represents a range of characters represented by a lexical token * within a Source. @@ -40,26 +53,32 @@ 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; + /** * Tokens exist as nodes in a double-linked-list amongst all tokens * including ignored tokens. is always the first node and @@ -67,6 +86,7 @@ export class Token { */ readonly prev: Token | null; readonly next: Token | null; + constructor( kind: TokenKindEnum, start: number, @@ -75,18 +95,40 @@ export class Token { 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; line: number; column: number; - }; -} + } { + return { + kind: this.kind, + value: this.value, + line: this.line, + column: this.column, + }; + } +} + /** * @internal */ -export function isNode(maybeNode: unknown): maybeNode is ASTNode; +export function isNode(maybeNode: unknown): maybeNode is ASTNode { + // eslint-disable-next-line @typescript-eslint/dot-notation + return typeof maybeNode?.['kind'] === 'string'; +} + /** * The list of all possible AST node types. */ @@ -134,6 +176,7 @@ export type ASTNode = | UnionTypeExtensionNode | EnumTypeExtensionNode | InputObjectTypeExtensionNode; + /** * Utility type listing all nodes indexed by their kind. */ @@ -182,25 +225,32 @@ export interface ASTKindToNode { EnumTypeExtension: EnumTypeExtensionNode; InputObjectTypeExtension: InputObjectTypeExtensionNode; } + /** Name */ + export interface NameNode { readonly kind: 'Name'; readonly loc?: Location; readonly value: string; } + /** Document */ + export interface DocumentNode { readonly kind: 'Document'; readonly loc?: Location; readonly definitions: ReadonlyArray; } + export type DefinitionNode = | ExecutableDefinitionNode | TypeSystemDefinitionNode | TypeSystemExtensionNode; + export type ExecutableDefinitionNode = | OperationDefinitionNode | FragmentDefinitionNode; + export interface OperationDefinitionNode { readonly kind: 'OperationDefinition'; readonly loc?: Location; @@ -210,7 +260,9 @@ export interface OperationDefinitionNode { readonly directives?: ReadonlyArray; readonly selectionSet: SelectionSetNode; } + export type OperationTypeNode = 'query' | 'mutation' | 'subscription'; + export interface VariableDefinitionNode { readonly kind: 'VariableDefinition'; readonly loc?: Location; @@ -219,17 +271,21 @@ export interface VariableDefinitionNode { readonly defaultValue?: ConstValueNode; readonly directives?: ReadonlyArray; } + export interface VariableNode { readonly kind: 'Variable'; readonly loc?: Location; readonly name: NameNode; } + export interface SelectionSetNode { kind: 'SelectionSet'; loc?: Location; selections: ReadonlyArray; } + export type SelectionNode = FieldNode | FragmentSpreadNode | InlineFragmentNode; + export interface FieldNode { readonly kind: 'Field'; readonly loc?: Location; @@ -239,25 +295,30 @@ export interface FieldNode { readonly directives?: ReadonlyArray; readonly selectionSet?: SelectionSetNode; } + export interface ArgumentNode { readonly kind: 'Argument'; readonly loc?: Location; readonly name: NameNode; readonly value: ValueNode; } + export interface ConstArgumentNode { readonly kind: 'Argument'; readonly loc?: Location; readonly name: NameNode; readonly value: ConstValueNode; } + /** Fragments */ + export interface FragmentSpreadNode { readonly kind: 'FragmentSpread'; readonly loc?: Location; readonly name: NameNode; readonly directives?: ReadonlyArray; } + export interface InlineFragmentNode { readonly kind: 'InlineFragment'; readonly loc?: Location; @@ -265,6 +326,7 @@ export interface InlineFragmentNode { readonly directives?: ReadonlyArray; readonly selectionSet: SelectionSetNode; } + export interface FragmentDefinitionNode { readonly kind: 'FragmentDefinition'; readonly loc?: Location; @@ -275,7 +337,9 @@ export interface FragmentDefinitionNode { readonly directives?: ReadonlyArray; readonly selectionSet: SelectionSetNode; } + /** Values */ + export type ValueNode = | VariableNode | IntValueNode @@ -286,6 +350,7 @@ export type ValueNode = | EnumValueNode | ListValueNode | ObjectValueNode; + export type ConstValueNode = | IntValueNode | FloatValueNode @@ -295,103 +360,126 @@ export type ConstValueNode = | EnumValueNode | ConstListValueNode | ConstObjectValueNode; + export interface IntValueNode { readonly kind: 'IntValue'; readonly loc?: Location; readonly value: string; } + export interface FloatValueNode { readonly kind: 'FloatValue'; readonly loc?: Location; readonly value: string; } + export interface StringValueNode { readonly kind: 'StringValue'; readonly loc?: Location; readonly value: string; readonly block?: boolean; } + export interface BooleanValueNode { readonly kind: 'BooleanValue'; readonly loc?: Location; readonly value: boolean; } + export interface NullValueNode { readonly kind: 'NullValue'; readonly loc?: Location; } + export interface EnumValueNode { readonly kind: 'EnumValue'; readonly loc?: Location; readonly value: string; } + export interface ListValueNode { readonly kind: 'ListValue'; readonly loc?: Location; readonly values: ReadonlyArray; } + export interface ConstListValueNode { readonly kind: 'ListValue'; readonly loc?: Location; readonly values: ReadonlyArray; } + export interface ObjectValueNode { readonly kind: 'ObjectValue'; readonly loc?: Location; readonly fields: ReadonlyArray; } + export interface ConstObjectValueNode { readonly kind: 'ObjectValue'; readonly loc?: Location; readonly fields: ReadonlyArray; } + export interface ObjectFieldNode { readonly kind: 'ObjectField'; readonly loc?: Location; readonly name: NameNode; readonly value: ValueNode; } + export interface ConstObjectFieldNode { readonly kind: 'ObjectField'; readonly loc?: Location; readonly name: NameNode; readonly value: ConstValueNode; } + /** Directives */ + export interface DirectiveNode { readonly kind: 'Directive'; readonly loc?: Location; readonly name: NameNode; readonly arguments?: ReadonlyArray; } + export interface ConstDirectiveNode { readonly kind: 'Directive'; readonly loc?: Location; readonly name: NameNode; readonly arguments?: ReadonlyArray; } + /** Type Reference */ + export type TypeNode = NamedTypeNode | ListTypeNode | NonNullTypeNode; + export interface NamedTypeNode { readonly kind: 'NamedType'; readonly loc?: Location; readonly name: NameNode; } + export interface ListTypeNode { readonly kind: 'ListType'; readonly loc?: Location; readonly type: TypeNode; } + export interface NonNullTypeNode { readonly kind: 'NonNullType'; readonly loc?: Location; readonly type: NamedTypeNode | ListTypeNode; } + /** Type System Definition */ + export type TypeSystemDefinitionNode = | SchemaDefinitionNode | TypeDefinitionNode | DirectiveDefinitionNode; + export interface SchemaDefinitionNode { readonly kind: 'SchemaDefinition'; readonly loc?: Location; @@ -399,13 +487,16 @@ export interface SchemaDefinitionNode { readonly directives?: ReadonlyArray; readonly operationTypes: ReadonlyArray; } + export interface OperationTypeDefinitionNode { readonly kind: 'OperationTypeDefinition'; readonly loc?: Location; readonly operation: OperationTypeNode; readonly type: NamedTypeNode; } + /** Type Definition */ + export type TypeDefinitionNode = | ScalarTypeDefinitionNode | ObjectTypeDefinitionNode @@ -413,6 +504,7 @@ export type TypeDefinitionNode = | UnionTypeDefinitionNode | EnumTypeDefinitionNode | InputObjectTypeDefinitionNode; + export interface ScalarTypeDefinitionNode { readonly kind: 'ScalarTypeDefinition'; readonly loc?: Location; @@ -420,6 +512,7 @@ export interface ScalarTypeDefinitionNode { readonly name: NameNode; readonly directives?: ReadonlyArray; } + export interface ObjectTypeDefinitionNode { readonly kind: 'ObjectTypeDefinition'; readonly loc?: Location; @@ -429,6 +522,7 @@ export interface ObjectTypeDefinitionNode { readonly directives?: ReadonlyArray; readonly fields?: ReadonlyArray; } + export interface FieldDefinitionNode { readonly kind: 'FieldDefinition'; readonly loc?: Location; @@ -438,6 +532,7 @@ export interface FieldDefinitionNode { readonly type: TypeNode; readonly directives?: ReadonlyArray; } + export interface InputValueDefinitionNode { readonly kind: 'InputValueDefinition'; readonly loc?: Location; @@ -447,6 +542,7 @@ export interface InputValueDefinitionNode { readonly defaultValue?: ConstValueNode; readonly directives?: ReadonlyArray; } + export interface InterfaceTypeDefinitionNode { readonly kind: 'InterfaceTypeDefinition'; readonly loc?: Location; @@ -456,6 +552,7 @@ export interface InterfaceTypeDefinitionNode { readonly directives?: ReadonlyArray; readonly fields?: ReadonlyArray; } + export interface UnionTypeDefinitionNode { readonly kind: 'UnionTypeDefinition'; readonly loc?: Location; @@ -464,6 +561,7 @@ export interface UnionTypeDefinitionNode { readonly directives?: ReadonlyArray; readonly types?: ReadonlyArray; } + export interface EnumTypeDefinitionNode { readonly kind: 'EnumTypeDefinition'; readonly loc?: Location; @@ -472,6 +570,7 @@ export interface EnumTypeDefinitionNode { readonly directives?: ReadonlyArray; readonly values?: ReadonlyArray; } + export interface EnumValueDefinitionNode { readonly kind: 'EnumValueDefinition'; readonly loc?: Location; @@ -479,6 +578,7 @@ export interface EnumValueDefinitionNode { readonly name: NameNode; readonly directives?: ReadonlyArray; } + export interface InputObjectTypeDefinitionNode { readonly kind: 'InputObjectTypeDefinition'; readonly loc?: Location; @@ -487,7 +587,9 @@ export interface InputObjectTypeDefinitionNode { readonly directives?: ReadonlyArray; readonly fields?: ReadonlyArray; } + /** Directive Definitions */ + export interface DirectiveDefinitionNode { readonly kind: 'DirectiveDefinition'; readonly loc?: Location; @@ -497,15 +599,20 @@ export interface DirectiveDefinitionNode { readonly repeatable: boolean; readonly locations: ReadonlyArray; } + /** Type System Extensions */ + export type TypeSystemExtensionNode = SchemaExtensionNode | TypeExtensionNode; + export interface SchemaExtensionNode { readonly kind: 'SchemaExtension'; readonly loc?: Location; readonly directives?: ReadonlyArray; readonly operationTypes?: ReadonlyArray; } + /** Type Extensions */ + export type TypeExtensionNode = | ScalarTypeExtensionNode | ObjectTypeExtensionNode @@ -513,12 +620,14 @@ export type TypeExtensionNode = | UnionTypeExtensionNode | EnumTypeExtensionNode | InputObjectTypeExtensionNode; + export interface ScalarTypeExtensionNode { readonly kind: 'ScalarTypeExtension'; readonly loc?: Location; readonly name: NameNode; readonly directives?: ReadonlyArray; } + export interface ObjectTypeExtensionNode { readonly kind: 'ObjectTypeExtension'; readonly loc?: Location; @@ -527,6 +636,7 @@ export interface ObjectTypeExtensionNode { readonly directives?: ReadonlyArray; readonly fields?: ReadonlyArray; } + export interface InterfaceTypeExtensionNode { readonly kind: 'InterfaceTypeExtension'; readonly loc?: Location; @@ -535,6 +645,7 @@ export interface InterfaceTypeExtensionNode { readonly directives?: ReadonlyArray; readonly fields?: ReadonlyArray; } + export interface UnionTypeExtensionNode { readonly kind: 'UnionTypeExtension'; readonly loc?: Location; @@ -542,6 +653,7 @@ export interface UnionTypeExtensionNode { readonly directives?: ReadonlyArray; readonly types?: ReadonlyArray; } + export interface EnumTypeExtensionNode { readonly kind: 'EnumTypeExtension'; readonly loc?: Location; @@ -549,6 +661,7 @@ export interface EnumTypeExtensionNode { readonly directives?: ReadonlyArray; readonly values?: ReadonlyArray; } + export interface InputObjectTypeExtensionNode { readonly kind: 'InputObjectTypeExtension'; readonly loc?: Location; diff --git a/src/language/blockString.d.ts b/src/language/blockString.d.ts deleted file mode 100644 index 1ef70f9074..0000000000 --- a/src/language/blockString.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Produces the value of a block string from its parsed raw value, similar to - * CoffeeScript's block string, Python's docstring trim or Ruby's strip_heredoc. - * - * This implements the GraphQL spec's BlockStringValue() static algorithm. - * - * @internal - */ -export function dedentBlockStringValue(rawString: string): string; -/** - * @internal - */ -export function getBlockStringIndentation(value: string): number; -/** - * Print a block string in the indented block form by adding a leading and - * trailing blank line. However, if a block string starts with whitespace and is - * a single-line, adding a leading blank line would strip that whitespace. - * - * @internal - */ -export function printBlockString( - value: string, - preferMultipleLines?: boolean, -): string; diff --git a/src/language/blockString.js b/src/language/blockString.ts similarity index 100% rename from src/language/blockString.js rename to src/language/blockString.ts diff --git a/src/language/directiveLocation.d.ts b/src/language/directiveLocation.d.ts deleted file mode 100644 index a6ae437f08..0000000000 --- a/src/language/directiveLocation.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * The set of allowed directive location values. - */ -export const DirectiveLocation: Readonly<{ - /** Request Definitions */ - readonly QUERY: 'QUERY'; - readonly MUTATION: 'MUTATION'; - readonly SUBSCRIPTION: 'SUBSCRIPTION'; - readonly FIELD: 'FIELD'; - readonly FRAGMENT_DEFINITION: 'FRAGMENT_DEFINITION'; - readonly FRAGMENT_SPREAD: 'FRAGMENT_SPREAD'; - readonly INLINE_FRAGMENT: 'INLINE_FRAGMENT'; - readonly VARIABLE_DEFINITION: 'VARIABLE_DEFINITION'; - /** Type System Definitions */ - readonly SCHEMA: 'SCHEMA'; - readonly SCALAR: 'SCALAR'; - readonly OBJECT: 'OBJECT'; - readonly FIELD_DEFINITION: 'FIELD_DEFINITION'; - readonly ARGUMENT_DEFINITION: 'ARGUMENT_DEFINITION'; - readonly INTERFACE: 'INTERFACE'; - readonly UNION: 'UNION'; - readonly ENUM: 'ENUM'; - readonly ENUM_VALUE: 'ENUM_VALUE'; - readonly INPUT_OBJECT: 'INPUT_OBJECT'; - readonly INPUT_FIELD_DEFINITION: 'INPUT_FIELD_DEFINITION'; -}>; -/** - * The enum type representing the directive location values. - */ -export type DirectiveLocationEnum = - typeof DirectiveLocation[keyof typeof DirectiveLocation]; diff --git a/src/language/directiveLocation.js b/src/language/directiveLocation.ts similarity index 88% rename from src/language/directiveLocation.js rename to src/language/directiveLocation.ts index fcc91aa17d..702b459102 100644 --- a/src/language/directiveLocation.js +++ b/src/language/directiveLocation.ts @@ -23,9 +23,10 @@ export const DirectiveLocation = Object.freeze({ ENUM_VALUE: 'ENUM_VALUE', INPUT_OBJECT: 'INPUT_OBJECT', INPUT_FIELD_DEFINITION: 'INPUT_FIELD_DEFINITION', -}); +} as const); /** * The enum type representing the directive location values. */ -export type DirectiveLocationEnum = $Values; +export type DirectiveLocationEnum = + typeof DirectiveLocation[keyof typeof DirectiveLocation]; diff --git a/src/language/index.d.ts b/src/language/index.d.ts deleted file mode 100644 index db2ffaff33..0000000000 --- a/src/language/index.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -export { Source } from './source'; -export { getLocation } from './location'; -export type { SourceLocation } from './location'; -export { printLocation, printSourceLocation } from './printLocation'; -export { Kind } from './kinds'; -export type { KindEnum } from './kinds'; -export { TokenKind } from './tokenKind'; -export type { TokenKindEnum } from './tokenKind'; -export { Lexer } from './lexer'; -export { parse, parseValue, parseConstValue, parseType } from './parser'; -export type { ParseOptions } from './parser'; -export { print } from './printer'; -export { visit, visitInParallel, getVisitFn, BREAK } from './visitor'; -export type { ASTVisitor, ASTVisitFn } from './visitor'; -export { Location, Token } from './ast'; -export type { - ASTNode, - ASTKindToNode, - /** Each kind of AST node */ - NameNode, - DocumentNode, - DefinitionNode, - ExecutableDefinitionNode, - OperationDefinitionNode, - OperationTypeNode, - VariableDefinitionNode, - VariableNode, - SelectionSetNode, - SelectionNode, - FieldNode, - ArgumentNode, - ConstArgumentNode, - FragmentSpreadNode, - InlineFragmentNode, - FragmentDefinitionNode, - ValueNode, - ConstValueNode, - IntValueNode, - FloatValueNode, - StringValueNode, - BooleanValueNode, - NullValueNode, - EnumValueNode, - ListValueNode, - ConstListValueNode, - ObjectValueNode, - ConstObjectValueNode, - ObjectFieldNode, - ConstObjectFieldNode, - DirectiveNode, - ConstDirectiveNode, - TypeNode, - NamedTypeNode, - ListTypeNode, - NonNullTypeNode, - TypeSystemDefinitionNode, - SchemaDefinitionNode, - OperationTypeDefinitionNode, - TypeDefinitionNode, - ScalarTypeDefinitionNode, - ObjectTypeDefinitionNode, - FieldDefinitionNode, - InputValueDefinitionNode, - InterfaceTypeDefinitionNode, - UnionTypeDefinitionNode, - EnumTypeDefinitionNode, - EnumValueDefinitionNode, - InputObjectTypeDefinitionNode, - DirectiveDefinitionNode, - TypeSystemExtensionNode, - SchemaExtensionNode, - TypeExtensionNode, - ScalarTypeExtensionNode, - ObjectTypeExtensionNode, - InterfaceTypeExtensionNode, - UnionTypeExtensionNode, - EnumTypeExtensionNode, - InputObjectTypeExtensionNode, -} from './ast'; -export { - isDefinitionNode, - isExecutableDefinitionNode, - isSelectionNode, - isValueNode, - isConstValueNode, - isTypeNode, - isTypeSystemDefinitionNode, - isTypeDefinitionNode, - isTypeSystemExtensionNode, - isTypeExtensionNode, -} from './predicates'; -export { DirectiveLocation } from './directiveLocation'; -export type { DirectiveLocationEnum } from './directiveLocation'; diff --git a/src/language/index.js b/src/language/index.ts similarity index 100% rename from src/language/index.js rename to src/language/index.ts diff --git a/src/language/kinds.d.ts b/src/language/kinds.d.ts deleted file mode 100644 index 17570caa24..0000000000 --- a/src/language/kinds.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * The set of allowed kind values for AST nodes. - */ -export const Kind: Readonly<{ - /** Name */ - readonly NAME: 'Name'; - /** Document */ - readonly DOCUMENT: 'Document'; - readonly OPERATION_DEFINITION: 'OperationDefinition'; - readonly VARIABLE_DEFINITION: 'VariableDefinition'; - readonly SELECTION_SET: 'SelectionSet'; - readonly FIELD: 'Field'; - readonly ARGUMENT: 'Argument'; - /** Fragments */ - readonly FRAGMENT_SPREAD: 'FragmentSpread'; - readonly INLINE_FRAGMENT: 'InlineFragment'; - readonly FRAGMENT_DEFINITION: 'FragmentDefinition'; - /** Values */ - readonly VARIABLE: 'Variable'; - readonly INT: 'IntValue'; - readonly FLOAT: 'FloatValue'; - readonly STRING: 'StringValue'; - readonly BOOLEAN: 'BooleanValue'; - readonly NULL: 'NullValue'; - readonly ENUM: 'EnumValue'; - readonly LIST: 'ListValue'; - readonly OBJECT: 'ObjectValue'; - readonly OBJECT_FIELD: 'ObjectField'; - /** Directives */ - readonly DIRECTIVE: 'Directive'; - /** Types */ - readonly NAMED_TYPE: 'NamedType'; - readonly LIST_TYPE: 'ListType'; - readonly NON_NULL_TYPE: 'NonNullType'; - /** Type System Definitions */ - readonly SCHEMA_DEFINITION: 'SchemaDefinition'; - readonly OPERATION_TYPE_DEFINITION: 'OperationTypeDefinition'; - /** Type Definitions */ - readonly SCALAR_TYPE_DEFINITION: 'ScalarTypeDefinition'; - readonly OBJECT_TYPE_DEFINITION: 'ObjectTypeDefinition'; - readonly FIELD_DEFINITION: 'FieldDefinition'; - readonly INPUT_VALUE_DEFINITION: 'InputValueDefinition'; - readonly INTERFACE_TYPE_DEFINITION: 'InterfaceTypeDefinition'; - readonly UNION_TYPE_DEFINITION: 'UnionTypeDefinition'; - readonly ENUM_TYPE_DEFINITION: 'EnumTypeDefinition'; - readonly ENUM_VALUE_DEFINITION: 'EnumValueDefinition'; - readonly INPUT_OBJECT_TYPE_DEFINITION: 'InputObjectTypeDefinition'; - /** Directive Definitions */ - readonly DIRECTIVE_DEFINITION: 'DirectiveDefinition'; - /** Type System Extensions */ - readonly SCHEMA_EXTENSION: 'SchemaExtension'; - /** Type Extensions */ - readonly SCALAR_TYPE_EXTENSION: 'ScalarTypeExtension'; - readonly OBJECT_TYPE_EXTENSION: 'ObjectTypeExtension'; - readonly INTERFACE_TYPE_EXTENSION: 'InterfaceTypeExtension'; - readonly UNION_TYPE_EXTENSION: 'UnionTypeExtension'; - readonly ENUM_TYPE_EXTENSION: 'EnumTypeExtension'; - readonly INPUT_OBJECT_TYPE_EXTENSION: 'InputObjectTypeExtension'; -}>; -/** - * The enum type representing the possible kind values of AST nodes. - */ -export type KindEnum = typeof Kind[keyof typeof Kind]; diff --git a/src/language/kinds.js b/src/language/kinds.ts similarity index 96% rename from src/language/kinds.js rename to src/language/kinds.ts index ac905372f8..b5c0058827 100644 --- a/src/language/kinds.js +++ b/src/language/kinds.ts @@ -66,9 +66,9 @@ export const Kind = Object.freeze({ UNION_TYPE_EXTENSION: 'UnionTypeExtension', ENUM_TYPE_EXTENSION: 'EnumTypeExtension', INPUT_OBJECT_TYPE_EXTENSION: 'InputObjectTypeExtension', -}); +} as const); /** * The enum type representing the possible kind values of AST nodes. */ -export type KindEnum = $Values; +export type KindEnum = typeof Kind[keyof typeof Kind]; diff --git a/src/language/lexer.d.ts b/src/language/lexer.d.ts deleted file mode 100644 index ad08397cc8..0000000000 --- a/src/language/lexer.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { Source } from './source'; -import type { TokenKindEnum } from './tokenKind'; -import { Token } from './ast'; -/** - * Given a Source object, creates a Lexer for that source. - * A Lexer is a stateful stream generator in that every time - * it is advanced, it returns the next token in the Source. Assuming the - * source lexes, the final Token emitted by the lexer will be of kind - * EOF, after which the lexer will repeatedly return the same EOF token - * whenever called. - */ -export class Lexer { - source: Source; - /** - * The previously focused non-ignored token. - */ - lastToken: Token; - /** - * The currently focused non-ignored token. - */ - token: Token; - /** - * The (1-indexed) line containing the current token. - */ - line: number; - /** - * The character offset at which the current line begins. - */ - lineStart: number; - constructor(source: Source); - /** - * Advances the token stream to the next non-ignored token. - */ - advance(): Token; - /** - * Looks ahead and returns the next non-ignored token, but does not change - * the state of Lexer. - */ - lookahead(): Token; -} -/** - * @internal - */ -export function isPunctuatorTokenKind(kind: TokenKindEnum): boolean; diff --git a/src/language/lexer.js b/src/language/lexer.ts similarity index 99% rename from src/language/lexer.js rename to src/language/lexer.ts index ba70047ae4..c435a02bd8 100644 --- a/src/language/lexer.js +++ b/src/language/lexer.ts @@ -64,7 +64,7 @@ export class Lexer { let token = this.token; if (token.kind !== TokenKind.EOF) { do { - // $FlowFixMe[cannot-write] next is only mutable during parsing, so we cast to allow this. + // @ts-expect-error next is only mutable during parsing, so we cast to allow this. token = token.next ?? (token.next = readToken(this, token)); } while (token.kind === TokenKind.COMMENT); } diff --git a/src/language/location.d.ts b/src/language/location.d.ts deleted file mode 100644 index b70eea7735..0000000000 --- a/src/language/location.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Source } from './source'; -/** - * Represents a location in a Source. - */ -export interface SourceLocation { - readonly line: number; - readonly column: number; -} -/** - * Takes a Source and a UTF-8 character offset, and returns the corresponding - * line and column as a SourceLocation. - */ -export function getLocation(source: Source, position: number): SourceLocation; diff --git a/src/language/location.js b/src/language/location.ts similarity index 87% rename from src/language/location.js rename to src/language/location.ts index b4d4fa4bb6..ee24dbfcc1 100644 --- a/src/language/location.js +++ b/src/language/location.ts @@ -5,10 +5,10 @@ const LineRegExp = /\r\n|[\n\r]/g; /** * Represents a location in a Source. */ -export type SourceLocation = { - +line: number, - +column: number, -}; +export interface 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.d.ts b/src/language/parser.d.ts deleted file mode 100644 index 9d4ef028be..0000000000 --- a/src/language/parser.d.ts +++ /dev/null @@ -1,540 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { GraphQLError } from '../error/GraphQLError'; -import type { TokenKindEnum } from './tokenKind'; -import type { - Token, - NameNode, - VariableNode, - DocumentNode, - DefinitionNode, - OperationDefinitionNode, - OperationTypeNode, - VariableDefinitionNode, - SelectionSetNode, - SelectionNode, - FieldNode, - ArgumentNode, - ConstArgumentNode, - FragmentSpreadNode, - InlineFragmentNode, - FragmentDefinitionNode, - ValueNode, - ConstValueNode, - StringValueNode, - ListValueNode, - ConstListValueNode, - ObjectValueNode, - ConstObjectValueNode, - ObjectFieldNode, - ConstObjectFieldNode, - DirectiveNode, - ConstDirectiveNode, - TypeNode, - NamedTypeNode, - TypeSystemDefinitionNode, - SchemaDefinitionNode, - OperationTypeDefinitionNode, - ScalarTypeDefinitionNode, - ObjectTypeDefinitionNode, - FieldDefinitionNode, - InputValueDefinitionNode, - InterfaceTypeDefinitionNode, - UnionTypeDefinitionNode, - EnumTypeDefinitionNode, - EnumValueDefinitionNode, - InputObjectTypeDefinitionNode, - DirectiveDefinitionNode, - TypeSystemExtensionNode, - SchemaExtensionNode, - ScalarTypeExtensionNode, - ObjectTypeExtensionNode, - InterfaceTypeExtensionNode, - UnionTypeExtensionNode, - EnumTypeExtensionNode, - InputObjectTypeExtensionNode, -} from './ast'; -import { Location } from './ast'; -import { Source } from './source'; -/** - * Configuration options to control parser behavior - */ -export interface 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; - /** - * @deprecated will be removed in the v17.0.0 - * - * If enabled, the parser will understand and parse variable definitions - * contained in a fragment definition. They'll be represented in the - * `variableDefinitions` field of the FragmentDefinitionNode. - * - * The syntax is identical to normal, query-defined variables. For example: - * - * fragment A($var: Boolean = false) on T { - * ... - * } - * - */ - allowLegacyFragmentVariables?: boolean; -} -/** - * Given a GraphQL source, parses it into a Document. - * Throws GraphQLError if a syntax error is encountered. - */ -export function parse( - source: string | Source, - options?: ParseOptions, -): DocumentNode; -/** - * Given a string containing a GraphQL value (ex. `[42]`), parse the AST for - * that value. - * Throws GraphQLError if a syntax error is encountered. - * - * This is useful within tools that operate upon GraphQL Values directly and - * in isolation of complete GraphQL documents. - * - * Consider providing the results to the utility function: valueFromAST(). - */ -export function parseValue( - source: string | Source, - options?: ParseOptions, -): ValueNode; -/** - * Similar to parseValue(), but raises a parse error if it encounters a - * variable. The return type will be a constant value. - */ -export function parseConstValue( - source: string | Source, - options?: ParseOptions, -): ConstValueNode; -/** - * Given a string containing a GraphQL Type (ex. `[Int!]`), parse the AST for - * that type. - * Throws GraphQLError if a syntax error is encountered. - * - * This is useful within tools that operate upon GraphQL Types directly and - * in isolation of complete GraphQL documents. - * - * Consider providing the results to the utility function: typeFromAST(). - */ -export function parseType( - source: string | Source, - options?: ParseOptions, -): TypeNode; -/** - * This class is exported only to assist people in implementing their own parsers - * without duplicating too much code and should be used only as last resort for cases - * such as experimental syntax or if certain features could not be contributed upstream. - * - * It is still part of the internal API and is versioned, so any changes to it are never - * considered breaking changes. If you still need to support multiple versions of the - * library, please use the `versionInfo` variable for version detection. - * - * @internal - */ -export class Parser { - private _options; - private _lexer; - constructor(source: string | Source, options?: ParseOptions); - /** - * Converts a name lex token into a name parse node. - */ - parseName(): NameNode; - /** - * Document : Definition+ - */ - parseDocument(): DocumentNode; - /** - * Definition : - * - ExecutableDefinition - * - TypeSystemDefinition - * - TypeSystemExtension - * - * ExecutableDefinition : - * - OperationDefinition - * - FragmentDefinition - */ - parseDefinition(): DefinitionNode; - /** - * OperationDefinition : - * - SelectionSet - * - OperationType Name? VariableDefinitions? Directives? SelectionSet - */ - parseOperationDefinition(): OperationDefinitionNode; - /** - * OperationType : one of query mutation subscription - */ - parseOperationType(): OperationTypeNode; - /** - * VariableDefinitions : ( VariableDefinition+ ) - */ - parseVariableDefinitions(): Array; - /** - * VariableDefinition : Variable : Type DefaultValue? Directives[Const]? - */ - parseVariableDefinition(): VariableDefinitionNode; - /** - * Variable : $ Name - */ - parseVariable(): VariableNode; - /** - * SelectionSet : { Selection+ } - */ - parseSelectionSet(): SelectionSetNode; - /** - * Selection : - * - Field - * - FragmentSpread - * - InlineFragment - */ - parseSelection(): SelectionNode; - /** - * Field : Alias? Name Arguments? Directives? SelectionSet? - * - * Alias : Name : - */ - parseField(): FieldNode; - /** - * Arguments[Const] : ( Argument[?Const]+ ) - */ - parseArguments(isConst: true): Array; - parseArguments(isConst: boolean): Array; - /** - * Argument[Const] : Name : Value[?Const] - */ - parseArgument(isConst: true): ConstArgumentNode; - parseArgument(isConst?: boolean): ArgumentNode; - parseConstArgument(): ConstArgumentNode; - /** - * Corresponds to both FragmentSpread and InlineFragment in the spec. - * - * FragmentSpread : ... FragmentName Directives? - * - * InlineFragment : ... TypeCondition? Directives? SelectionSet - */ - parseFragment(): FragmentSpreadNode | InlineFragmentNode; - /** - * FragmentDefinition : - * - fragment FragmentName on TypeCondition Directives? SelectionSet - * - * TypeCondition : NamedType - */ - parseFragmentDefinition(): FragmentDefinitionNode; - /** - * FragmentName : Name but not `on` - */ - parseFragmentName(): NameNode; - /** - * Value[Const] : - * - [~Const] Variable - * - IntValue - * - FloatValue - * - StringValue - * - BooleanValue - * - NullValue - * - EnumValue - * - ListValue[?Const] - * - ObjectValue[?Const] - * - * BooleanValue : one of `true` `false` - * - * NullValue : `null` - * - * EnumValue : Name but not `true`, `false` or `null` - */ - parseValueLiteral(isConst: true): ConstValueNode; - parseValueLiteral(isConst: boolean): ValueNode; - parseConstValueLiteral(): ConstValueNode; - parseStringLiteral(): StringValueNode; - /** - * ListValue[Const] : - * - [ ] - * - [ Value[?Const]+ ] - */ - parseList(isConst: true): ConstListValueNode; - parseList(isConst: boolean): ListValueNode; - /** - * ObjectValue[Const] : - * - { } - * - { ObjectField[?Const]+ } - */ - parseObject(isConst: true): ConstObjectValueNode; - parseObject(isConst: boolean): ObjectValueNode; - /** - * ObjectField[Const] : Name : Value[?Const] - */ - parseObjectField(isConst: true): ConstObjectFieldNode; - parseObjectField(isConst: boolean): ObjectFieldNode; - /** - * Directives[Const] : Directive[?Const]+ - */ - parseDirectives(isConst: true): Array; - parseDirectives(isConst: boolean): Array; - parseConstDirectives(): Array; - /** - * Directive[Const] : @ Name Arguments[?Const]? - */ - parseDirective(isConst: true): ConstDirectiveNode; - parseDirective(isConst: boolean): DirectiveNode; - /** - * Type : - * - NamedType - * - ListType - * - NonNullType - */ - parseTypeReference(): TypeNode; - /** - * NamedType : Name - */ - parseNamedType(): NamedTypeNode; - /** - * TypeSystemDefinition : - * - SchemaDefinition - * - TypeDefinition - * - DirectiveDefinition - * - * TypeDefinition : - * - ScalarTypeDefinition - * - ObjectTypeDefinition - * - InterfaceTypeDefinition - * - UnionTypeDefinition - * - EnumTypeDefinition - * - InputObjectTypeDefinition - */ - parseTypeSystemDefinition(): TypeSystemDefinitionNode; - peekDescription(): boolean; - /** - * Description : StringValue - */ - parseDescription(): undefined | StringValueNode; - /** - * SchemaDefinition : Description? schema Directives[Const]? { OperationTypeDefinition+ } - */ - parseSchemaDefinition(): SchemaDefinitionNode; - /** - * OperationTypeDefinition : OperationType : NamedType - */ - parseOperationTypeDefinition(): OperationTypeDefinitionNode; - /** - * ScalarTypeDefinition : Description? scalar Name Directives[Const]? - */ - parseScalarTypeDefinition(): ScalarTypeDefinitionNode; - /** - * ObjectTypeDefinition : - * Description? - * type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition? - */ - parseObjectTypeDefinition(): ObjectTypeDefinitionNode; - /** - * ImplementsInterfaces : - * - implements `&`? NamedType - * - ImplementsInterfaces & NamedType - */ - parseImplementsInterfaces(): Array; - /** - * FieldsDefinition : { FieldDefinition+ } - */ - parseFieldsDefinition(): Array; - /** - * FieldDefinition : - * - Description? Name ArgumentsDefinition? : Type Directives[Const]? - */ - parseFieldDefinition(): FieldDefinitionNode; - /** - * ArgumentsDefinition : ( InputValueDefinition+ ) - */ - parseArgumentDefs(): Array; - /** - * InputValueDefinition : - * - Description? Name : Type DefaultValue? Directives[Const]? - */ - parseInputValueDef(): InputValueDefinitionNode; - /** - * InterfaceTypeDefinition : - * - Description? interface Name Directives[Const]? FieldsDefinition? - */ - parseInterfaceTypeDefinition(): InterfaceTypeDefinitionNode; - /** - * UnionTypeDefinition : - * - Description? union Name Directives[Const]? UnionMemberTypes? - */ - parseUnionTypeDefinition(): UnionTypeDefinitionNode; - /** - * UnionMemberTypes : - * - = `|`? NamedType - * - UnionMemberTypes | NamedType - */ - parseUnionMemberTypes(): Array; - /** - * EnumTypeDefinition : - * - Description? enum Name Directives[Const]? EnumValuesDefinition? - */ - parseEnumTypeDefinition(): EnumTypeDefinitionNode; - /** - * EnumValuesDefinition : { EnumValueDefinition+ } - */ - parseEnumValuesDefinition(): Array; - /** - * EnumValueDefinition : Description? EnumValue Directives[Const]? - * - * EnumValue : Name - */ - parseEnumValueDefinition(): EnumValueDefinitionNode; - /** - * InputObjectTypeDefinition : - * - Description? input Name Directives[Const]? InputFieldsDefinition? - */ - parseInputObjectTypeDefinition(): InputObjectTypeDefinitionNode; - /** - * InputFieldsDefinition : { InputValueDefinition+ } - */ - parseInputFieldsDefinition(): Array; - /** - * TypeSystemExtension : - * - SchemaExtension - * - TypeExtension - * - * TypeExtension : - * - ScalarTypeExtension - * - ObjectTypeExtension - * - InterfaceTypeExtension - * - UnionTypeExtension - * - EnumTypeExtension - * - InputObjectTypeDefinition - */ - parseTypeSystemExtension(): TypeSystemExtensionNode; - /** - * SchemaExtension : - * - extend schema Directives[Const]? { OperationTypeDefinition+ } - * - extend schema Directives[Const] - */ - parseSchemaExtension(): SchemaExtensionNode; - /** - * ScalarTypeExtension : - * - extend scalar Name Directives[Const] - */ - parseScalarTypeExtension(): ScalarTypeExtensionNode; - /** - * ObjectTypeExtension : - * - extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition - * - extend type Name ImplementsInterfaces? Directives[Const] - * - extend type Name ImplementsInterfaces - */ - parseObjectTypeExtension(): ObjectTypeExtensionNode; - /** - * InterfaceTypeExtension : - * - extend interface Name ImplementsInterfaces? Directives[Const]? FieldsDefinition - * - extend interface Name ImplementsInterfaces? Directives[Const] - * - extend interface Name ImplementsInterfaces - */ - parseInterfaceTypeExtension(): InterfaceTypeExtensionNode; - /** - * UnionTypeExtension : - * - extend union Name Directives[Const]? UnionMemberTypes - * - extend union Name Directives[Const] - */ - parseUnionTypeExtension(): UnionTypeExtensionNode; - /** - * EnumTypeExtension : - * - extend enum Name Directives[Const]? EnumValuesDefinition - * - extend enum Name Directives[Const] - */ - parseEnumTypeExtension(): EnumTypeExtensionNode; - /** - * InputObjectTypeExtension : - * - extend input Name Directives[Const]? InputFieldsDefinition - * - extend input Name Directives[Const] - */ - parseInputObjectTypeExtension(): InputObjectTypeExtensionNode; - /** - * DirectiveDefinition : - * - Description? directive @ Name ArgumentsDefinition? `repeatable`? on DirectiveLocations - */ - parseDirectiveDefinition(): DirectiveDefinitionNode; - /** - * DirectiveLocations : - * - `|`? DirectiveLocation - * - DirectiveLocations | DirectiveLocation - */ - parseDirectiveLocations(): Array; - parseDirectiveLocation(): NameNode; - /** - * Returns a node that, if configured to do so, sets a "loc" field as a - * location object, used to identify the place in the source that created a - * given parsed object. - */ - node< - T extends { - loc?: Location; - }, - >(startToken: Token, node: T): T; - /** - * Determines if the next token is of a given kind - */ - peek(kind: TokenKindEnum): boolean; - /** - * If the next token is of the given kind, return that token after advancing the lexer. - * Otherwise, do not change the parser state and throw an error. - */ - expectToken(kind: TokenKindEnum): Token; - /** - * 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): Maybe; - /** - * If the next token is a given keyword, advance the lexer. - * Otherwise, do not change the parser state and throw an error. - */ - expectKeyword(value: string): void; - /** - * If the next token is a given keyword, return "true" after advancing the lexer. - * Otherwise, do not change the parser state and return "false". - */ - expectOptionalKeyword(value: string): boolean; - /** - * Helper function for creating an error when an unexpected lexed token is encountered. - */ - unexpected(atToken?: Maybe): GraphQLError; - /** - * Returns a possibly empty list of parse nodes, determined by the parseFn. - * This list begins with a lex token of openKind and ends with a lex token of closeKind. - * Advances the parser to the next lex token after the closing token. - */ - any( - openKind: TokenKindEnum, - parseFn: () => T, - closeKind: TokenKindEnum, - ): Array; - /** - * Returns a list of parse nodes, determined by the parseFn. - * It can be empty only if open token is missing otherwise it will always return non-empty list - * that begins with a lex token of openKind and ends with a lex token of closeKind. - * Advances the parser to the next lex token after the closing token. - */ - optionalMany( - openKind: TokenKindEnum, - parseFn: () => T, - closeKind: TokenKindEnum, - ): Array; - /** - * Returns a non-empty list of parse nodes, determined by the parseFn. - * This list begins with a lex token of openKind and ends with a lex token of closeKind. - * Advances the parser to the next lex token after the closing token. - */ - many( - openKind: TokenKindEnum, - parseFn: () => T, - closeKind: TokenKindEnum, - ): Array; - /** - * Returns a non-empty list of parse nodes, determined by the parseFn. - * This list may begin with a lex token of delimiterKind followed by items separated by lex tokens of tokenKind. - * Advances the parser to the next lex token after last item in the list. - */ - delimitedMany(delimiterKind: TokenKindEnum, parseFn: () => T): Array; -} diff --git a/src/language/parser.js b/src/language/parser.ts similarity index 88% rename from src/language/parser.js rename to src/language/parser.ts index 9205382228..0477bf9d49 100644 --- a/src/language/parser.js +++ b/src/language/parser.ts @@ -1,3 +1,5 @@ +import type { Maybe } from '../jsutils/Maybe'; + import type { GraphQLError } from '../error/GraphQLError'; import { syntaxError } from '../error/syntaxError'; @@ -23,8 +25,11 @@ import type { ConstValueNode, StringValueNode, ListValueNode, + ConstListValueNode, ObjectValueNode, + ConstObjectValueNode, ObjectFieldNode, + ConstObjectFieldNode, DirectiveNode, ConstDirectiveNode, TypeNode, @@ -61,13 +66,13 @@ import { Lexer, isPunctuatorTokenKind } from './lexer'; /** * Configuration options to control parser behavior */ -export type ParseOptions = { +export interface 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; /** * @deprecated will be removed in the v17.0.0 @@ -83,8 +88,8 @@ export type ParseOptions = { * } * */ - allowLegacyFragmentVariables?: boolean, -}; + allowLegacyFragmentVariables?: boolean; +} /** * Given a GraphQL source, parses it into a Document. @@ -167,8 +172,8 @@ export function parseType( * @internal */ export class Parser { - _options: ?ParseOptions; - _lexer: Lexer; + private _options: Maybe; + private _lexer: Lexer; constructor(source: string | Source, options?: ParseOptions) { const sourceObj = isSource(source) ? source : new Source(source); @@ -182,9 +187,10 @@ export class Parser { */ parseName(): NameNode { const token = this.expectToken(TokenKind.NAME); + // @ts-expect-error FIXME: TS Conversion return this.node(token, { + // @ts-expect-error FIXME kind: Kind.NAME, - // $FlowFixMe[incompatible-return] FIXME value: token.value, }); } @@ -195,7 +201,9 @@ export class Parser { * Document : Definition+ */ parseDocument(): DocumentNode { + // @ts-expect-error FIXME: TS Conversion return this.node(this._lexer.token, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.DOCUMENT, definitions: this.many( TokenKind.SOF, @@ -255,7 +263,9 @@ export class Parser { parseOperationDefinition(): OperationDefinitionNode { const start = this._lexer.token; if (this.peek(TokenKind.BRACE_L)) { + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OPERATION_DEFINITION, operation: 'query', name: undefined, @@ -269,7 +279,9 @@ export class Parser { if (this.peek(TokenKind.NAME)) { name = this.parseName(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OPERATION_DEFINITION, operation, name, @@ -311,7 +323,9 @@ export class Parser { * VariableDefinition : Variable : Type DefaultValue? Directives[Const]? */ parseVariableDefinition(): VariableDefinitionNode { + // @ts-expect-error FIXME: TS Conversion return this.node(this._lexer.token, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.VARIABLE_DEFINITION, variable: this.parseVariable(), type: (this.expectToken(TokenKind.COLON), this.parseTypeReference()), @@ -328,7 +342,9 @@ export class Parser { parseVariable(): VariableNode { const start = this._lexer.token; this.expectToken(TokenKind.DOLLAR); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.VARIABLE, name: this.parseName(), }); @@ -338,7 +354,9 @@ export class Parser { * SelectionSet : { Selection+ } */ parseSelectionSet(): SelectionSetNode { + // @ts-expect-error FIXME: TS Conversion return this.node(this._lexer.token, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.SELECTION_SET, selections: this.many( TokenKind.BRACE_L, @@ -378,7 +396,9 @@ export class Parser { name = nameOrAlias; } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.FIELD, alias, name, @@ -393,6 +413,8 @@ export class Parser { /** * Arguments[Const] : ( Argument[?Const]+ ) */ + parseArguments(isConst: true): Array; + parseArguments(isConst: boolean): Array; parseArguments(isConst: boolean): Array { const item = isConst ? this.parseConstArgument : this.parseArgument; return this.optionalMany(TokenKind.PAREN_L, item, TokenKind.PAREN_R); @@ -401,12 +423,16 @@ export class Parser { /** * Argument[Const] : Name : Value[?Const] */ + parseArgument(isConst: true): ConstArgumentNode; + parseArgument(isConst?: boolean): ArgumentNode; parseArgument(isConst: boolean = false): ArgumentNode { const start = this._lexer.token; const name = this.parseName(); this.expectToken(TokenKind.COLON); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.ARGUMENT, name, value: this.parseValueLiteral(isConst), @@ -414,7 +440,6 @@ export class Parser { } parseConstArgument(): ConstArgumentNode { - // $FlowFixMe[incompatible-return] FIXME during TS conversion return this.parseArgument(true); } @@ -433,13 +458,17 @@ export class Parser { const hasTypeCondition = this.expectOptionalKeyword('on'); if (!hasTypeCondition && this.peek(TokenKind.NAME)) { + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.FRAGMENT_SPREAD, name: this.parseFragmentName(), directives: this.parseDirectives(false), }); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.INLINE_FRAGMENT, typeCondition: hasTypeCondition ? this.parseNamedType() : undefined, directives: this.parseDirectives(false), @@ -460,7 +489,9 @@ export class Parser { // the grammar of FragmentDefinition: // - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet if (this._options?.allowLegacyFragmentVariables === true) { + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.FRAGMENT_DEFINITION, name: this.parseFragmentName(), variableDefinitions: this.parseVariableDefinitions(), @@ -469,7 +500,9 @@ export class Parser { selectionSet: this.parseSelectionSet(), }); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.FRAGMENT_DEFINITION, name: this.parseFragmentName(), typeCondition: (this.expectKeyword('on'), this.parseNamedType()), @@ -508,6 +541,8 @@ export class Parser { * * EnumValue : Name but not `true`, `false` or `null` */ + parseValueLiteral(isConst: true): ConstValueNode; + parseValueLiteral(isConst: boolean): ValueNode; parseValueLiteral(isConst: boolean): ValueNode { const token = this._lexer.token; switch (token.kind) { @@ -517,16 +552,18 @@ export class Parser { return this.parseObject(isConst); case TokenKind.INT: this._lexer.advance(); + // @ts-expect-error FIXME: TS Conversion return this.node(token, { + // @ts-expect-error FIXME kind: Kind.INT, - // $FlowFixMe[incompatible-return] FIXME value: token.value, }); case TokenKind.FLOAT: this._lexer.advance(); + // @ts-expect-error FIXME: TS Conversion return this.node(token, { + // @ts-expect-error FIXME kind: Kind.FLOAT, - // $FlowFixMe[incompatible-return] FIXME value: token.value, }); case TokenKind.STRING: @@ -536,15 +573,19 @@ export class Parser { this._lexer.advance(); switch (token.value) { case 'true': + // @ts-expect-error FIXME: TS Conversion return this.node(token, { kind: Kind.BOOLEAN, value: true }); case 'false': + // @ts-expect-error FIXME: TS Conversion return this.node(token, { kind: Kind.BOOLEAN, value: false }); case 'null': + // @ts-expect-error FIXME: TS Conversion return this.node(token, { kind: Kind.NULL }); default: + // @ts-expect-error FIXME: TS Conversion return this.node(token, { + // @ts-expect-error FIXME kind: Kind.ENUM, - // $FlowFixMe[incompatible-return] FIXME value: token.value, }); } @@ -568,16 +609,16 @@ export class Parser { } parseConstValueLiteral(): ConstValueNode { - // $FlowFixMe[incompatible-return] FIXME during TS conversion return this.parseValueLiteral(true); } parseStringLiteral(): StringValueNode { const token = this._lexer.token; this._lexer.advance(); + // @ts-expect-error FIXME: TS Conversion return this.node(token, { + // @ts-expect-error FIXME kind: Kind.STRING, - // $FlowFixMe[incompatible-return] FIXME value: token.value, block: token.kind === TokenKind.BLOCK_STRING, }); @@ -588,9 +629,13 @@ export class Parser { * - [ ] * - [ Value[?Const]+ ] */ + parseList(isConst: true): ConstListValueNode; + parseList(isConst: boolean): ListValueNode; parseList(isConst: boolean): ListValueNode { const item = () => this.parseValueLiteral(isConst); + // @ts-expect-error FIXME: TS Conversion return this.node(this._lexer.token, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.LIST, values: this.any(TokenKind.BRACKET_L, item, TokenKind.BRACKET_R), }); @@ -601,9 +646,13 @@ export class Parser { * - { } * - { ObjectField[?Const]+ } */ + parseObject(isConst: true): ConstObjectValueNode; + parseObject(isConst: boolean): ObjectValueNode; parseObject(isConst: boolean): ObjectValueNode { const item = () => this.parseObjectField(isConst); + // @ts-expect-error FIXME: TS Conversion return this.node(this._lexer.token, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OBJECT, fields: this.any(TokenKind.BRACE_L, item, TokenKind.BRACE_R), }); @@ -612,12 +661,16 @@ export class Parser { /** * ObjectField[Const] : Name : Value[?Const] */ + parseObjectField(isConst: true): ConstObjectFieldNode; + parseObjectField(isConst: boolean): ObjectFieldNode; parseObjectField(isConst: boolean): ObjectFieldNode { const start = this._lexer.token; const name = this.parseName(); this.expectToken(TokenKind.COLON); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OBJECT_FIELD, name, value: this.parseValueLiteral(isConst), @@ -629,6 +682,8 @@ export class Parser { /** * Directives[Const] : Directive[?Const]+ */ + parseDirectives(isConst: true): Array; + parseDirectives(isConst: boolean): Array; parseDirectives(isConst: boolean): Array { const directives = []; while (this.peek(TokenKind.AT)) { @@ -638,17 +693,20 @@ export class Parser { } parseConstDirectives(): Array { - // $FlowFixMe[incompatible-return] FIXME during TS conversion return this.parseDirectives(true); } /** * Directive[Const] : @ Name Arguments[?Const]? */ + parseDirective(isConst: true): ConstDirectiveNode; + parseDirective(isConst: boolean): DirectiveNode; parseDirective(isConst: boolean): DirectiveNode { const start = this._lexer.token; this.expectToken(TokenKind.AT); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.DIRECTIVE, name: this.parseName(), arguments: this.parseArguments(isConst), @@ -670,6 +728,7 @@ export class Parser { const innerType = this.parseTypeReference(); this.expectToken(TokenKind.BRACKET_R); type = this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.LIST_TYPE, type: innerType, }); @@ -678,7 +737,9 @@ export class Parser { } if (this.expectOptionalToken(TokenKind.BANG)) { + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.NON_NULL_TYPE, type, }); @@ -690,7 +751,9 @@ export class Parser { * NamedType : Name */ parseNamedType(): NamedTypeNode { + // @ts-expect-error FIXME: TS Conversion return this.node(this._lexer.token, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.NAMED_TYPE, name: this.parseName(), }); @@ -749,7 +812,7 @@ export class Parser { /** * Description : StringValue */ - parseDescription(): void | StringValueNode { + parseDescription(): undefined | StringValueNode { if (this.peekDescription()) { return this.parseStringLiteral(); } @@ -768,7 +831,9 @@ export class Parser { this.parseOperationTypeDefinition, TokenKind.BRACE_R, ); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.SCHEMA_DEFINITION, description, directives, @@ -784,7 +849,9 @@ export class Parser { const operation = this.parseOperationType(); this.expectToken(TokenKind.COLON); const type = this.parseNamedType(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OPERATION_TYPE_DEFINITION, operation, type, @@ -800,7 +867,9 @@ export class Parser { this.expectKeyword('scalar'); const name = this.parseName(); const directives = this.parseConstDirectives(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.SCALAR_TYPE_DEFINITION, description, name, @@ -821,7 +890,9 @@ export class Parser { const interfaces = this.parseImplementsInterfaces(); const directives = this.parseConstDirectives(); const fields = this.parseFieldsDefinition(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OBJECT_TYPE_DEFINITION, description, name, @@ -865,7 +936,9 @@ export class Parser { this.expectToken(TokenKind.COLON); const type = this.parseTypeReference(); const directives = this.parseConstDirectives(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.FIELD_DEFINITION, description, name, @@ -901,7 +974,9 @@ export class Parser { defaultValue = this.parseConstValueLiteral(); } const directives = this.parseConstDirectives(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.INPUT_VALUE_DEFINITION, description, name, @@ -923,7 +998,9 @@ export class Parser { const interfaces = this.parseImplementsInterfaces(); const directives = this.parseConstDirectives(); const fields = this.parseFieldsDefinition(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.INTERFACE_TYPE_DEFINITION, description, name, @@ -944,7 +1021,9 @@ export class Parser { const name = this.parseName(); const directives = this.parseConstDirectives(); const types = this.parseUnionMemberTypes(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.UNION_TYPE_DEFINITION, description, name, @@ -975,7 +1054,9 @@ export class Parser { const name = this.parseName(); const directives = this.parseConstDirectives(); const values = this.parseEnumValuesDefinition(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.ENUM_TYPE_DEFINITION, description, name, @@ -1005,7 +1086,9 @@ export class Parser { const description = this.parseDescription(); const name = this.parseName(); const directives = this.parseConstDirectives(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.ENUM_VALUE_DEFINITION, description, name, @@ -1024,7 +1107,9 @@ export class Parser { const name = this.parseName(); const directives = this.parseConstDirectives(); const fields = this.parseInputFieldsDefinition(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, description, name, @@ -1100,7 +1185,9 @@ export class Parser { if (directives.length === 0 && operationTypes.length === 0) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.SCHEMA_EXTENSION, directives, operationTypes, @@ -1120,7 +1207,9 @@ export class Parser { if (directives.length === 0) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.SCALAR_TYPE_EXTENSION, name, directives, @@ -1148,7 +1237,9 @@ export class Parser { ) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.OBJECT_TYPE_EXTENSION, name, interfaces, @@ -1178,7 +1269,9 @@ export class Parser { ) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.INTERFACE_TYPE_EXTENSION, name, interfaces, @@ -1202,7 +1295,9 @@ export class Parser { if (directives.length === 0 && types.length === 0) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.UNION_TYPE_EXTENSION, name, directives, @@ -1225,7 +1320,9 @@ export class Parser { if (directives.length === 0 && values.length === 0) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.ENUM_TYPE_EXTENSION, name, directives, @@ -1248,7 +1345,9 @@ export class Parser { if (directives.length === 0 && fields.length === 0) { throw this.unexpected(); } + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.INPUT_OBJECT_TYPE_EXTENSION, name, directives, @@ -1270,7 +1369,9 @@ export class Parser { const repeatable = this.expectOptionalKeyword('repeatable'); this.expectKeyword('on'); const locations = this.parseDirectiveLocations(); + // @ts-expect-error FIXME: TS Conversion return this.node(start, { + // @ts-expect-error FIXME: TS Conversion kind: Kind.DIRECTIVE_DEFINITION, description, name, @@ -1332,7 +1433,7 @@ export class Parser { * location object, used to identify the place in the source that created a * given parsed object. */ - node(startToken: Token, node: T): T { + node(startToken: Token, node: T): T { if (this._options?.noLocation !== true) { node.loc = new Location( startToken, @@ -1372,7 +1473,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): Maybe { const token = this._lexer.token; if (token.kind === kind) { this._lexer.advance(); @@ -1414,7 +1515,7 @@ export class Parser { /** * Helper function for creating an error when an unexpected lexed token is encountered. */ - unexpected(atToken?: ?Token): GraphQLError { + unexpected(atToken?: Maybe): GraphQLError { const token = atToken ?? this._lexer.token; return syntaxError( this._lexer.source, diff --git a/src/language/predicates.d.ts b/src/language/predicates.d.ts deleted file mode 100644 index c1108dd435..0000000000 --- a/src/language/predicates.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { - ASTNode, - DefinitionNode, - ExecutableDefinitionNode, - SelectionNode, - ValueNode, - ConstValueNode, - TypeNode, - TypeSystemDefinitionNode, - TypeDefinitionNode, - TypeSystemExtensionNode, - TypeExtensionNode, -} from './ast'; -export function isDefinitionNode(node: ASTNode): node is DefinitionNode; -export function isExecutableDefinitionNode( - node: ASTNode, -): node is ExecutableDefinitionNode; -export function isSelectionNode(node: ASTNode): node is SelectionNode; -export function isValueNode(node: ASTNode): node is ValueNode; -export function isConstValueNode(node: ASTNode): node is ConstValueNode; -export function isTypeNode(node: ASTNode): node is TypeNode; -export function isTypeSystemDefinitionNode( - node: ASTNode, -): node is TypeSystemDefinitionNode; -export function isTypeDefinitionNode(node: ASTNode): node is TypeDefinitionNode; -export function isTypeSystemExtensionNode( - node: ASTNode, -): node is TypeSystemExtensionNode; -export function isTypeExtensionNode(node: ASTNode): node is TypeExtensionNode; diff --git a/src/language/predicates.js b/src/language/predicates.ts similarity index 64% rename from src/language/predicates.js rename to src/language/predicates.ts index 8be57aaa7d..29e4984d5e 100644 --- a/src/language/predicates.js +++ b/src/language/predicates.ts @@ -1,7 +1,19 @@ -import type { ASTNode } from './ast'; +import type { + ASTNode, + DefinitionNode, + ExecutableDefinitionNode, + SelectionNode, + ValueNode, + ConstValueNode, + TypeNode, + TypeSystemDefinitionNode, + TypeDefinitionNode, + TypeSystemExtensionNode, + TypeExtensionNode, +} from './ast'; import { Kind } from './kinds'; -export function isDefinitionNode(node: ASTNode): boolean %checks { +export function isDefinitionNode(node: ASTNode): node is DefinitionNode { return ( isExecutableDefinitionNode(node) || isTypeSystemDefinitionNode(node) || @@ -9,14 +21,16 @@ export function isDefinitionNode(node: ASTNode): boolean %checks { ); } -export function isExecutableDefinitionNode(node: ASTNode): boolean %checks { +export function isExecutableDefinitionNode( + node: ASTNode, +): node is ExecutableDefinitionNode { return ( node.kind === Kind.OPERATION_DEFINITION || node.kind === Kind.FRAGMENT_DEFINITION ); } -export function isSelectionNode(node: ASTNode): boolean %checks { +export function isSelectionNode(node: ASTNode): node is SelectionNode { return ( node.kind === Kind.FIELD || node.kind === Kind.FRAGMENT_SPREAD || @@ -24,7 +38,7 @@ export function isSelectionNode(node: ASTNode): boolean %checks { ); } -export function isValueNode(node: ASTNode): boolean %checks { +export function isValueNode(node: ASTNode): node is ValueNode { return ( node.kind === Kind.VARIABLE || node.kind === Kind.INT || @@ -38,7 +52,7 @@ export function isValueNode(node: ASTNode): boolean %checks { ); } -export function isConstValueNode(node: ASTNode): boolean %checks { +export function isConstValueNode(node: ASTNode): node is ConstValueNode { return ( isValueNode(node) && (node.kind === Kind.LIST @@ -49,7 +63,7 @@ export function isConstValueNode(node: ASTNode): boolean %checks { ); } -export function isTypeNode(node: ASTNode): boolean %checks { +export function isTypeNode(node: ASTNode): node is TypeNode { return ( node.kind === Kind.NAMED_TYPE || node.kind === Kind.LIST_TYPE || @@ -57,7 +71,9 @@ export function isTypeNode(node: ASTNode): boolean %checks { ); } -export function isTypeSystemDefinitionNode(node: ASTNode): boolean %checks { +export function isTypeSystemDefinitionNode( + node: ASTNode, +): node is TypeSystemDefinitionNode { return ( node.kind === Kind.SCHEMA_DEFINITION || isTypeDefinitionNode(node) || @@ -65,7 +81,9 @@ export function isTypeSystemDefinitionNode(node: ASTNode): boolean %checks { ); } -export function isTypeDefinitionNode(node: ASTNode): boolean %checks { +export function isTypeDefinitionNode( + node: ASTNode, +): node is TypeDefinitionNode { return ( node.kind === Kind.SCALAR_TYPE_DEFINITION || node.kind === Kind.OBJECT_TYPE_DEFINITION || @@ -76,11 +94,13 @@ export function isTypeDefinitionNode(node: ASTNode): boolean %checks { ); } -export function isTypeSystemExtensionNode(node: ASTNode): boolean %checks { +export function isTypeSystemExtensionNode( + node: ASTNode, +): node is TypeSystemExtensionNode { return node.kind === Kind.SCHEMA_EXTENSION || isTypeExtensionNode(node); } -export function isTypeExtensionNode(node: ASTNode): boolean %checks { +export function isTypeExtensionNode(node: ASTNode): node is TypeExtensionNode { return ( node.kind === Kind.SCALAR_TYPE_EXTENSION || node.kind === Kind.OBJECT_TYPE_EXTENSION || diff --git a/src/language/printLocation.d.ts b/src/language/printLocation.d.ts deleted file mode 100644 index 57aaf1ae9f..0000000000 --- a/src/language/printLocation.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Source } from './source'; -import type { Location } from './ast'; -import type { SourceLocation } from './location'; -/** - * Render a helpful description of the location in the GraphQL Source document. - */ -export function printLocation(location: Location): string; -/** - * Render a helpful description of the location in the GraphQL Source document. - */ -export function printSourceLocation( - source: Source, - sourceLocation: SourceLocation, -): string; diff --git a/src/language/printLocation.js b/src/language/printLocation.ts similarity index 89% rename from src/language/printLocation.js rename to src/language/printLocation.ts index 62f1276da4..4e1c926447 100644 --- a/src/language/printLocation.js +++ b/src/language/printLocation.ts @@ -38,7 +38,7 @@ export function printSourceLocation( if (locationLine.length > 120) { const subLineIndex = Math.floor(columnNum / 80); const subLineColumnNum = columnNum % 80; - const subLines = []; + const subLines: Array = []; for (let i = 0; i < locationLine.length; i += 80) { subLines.push(locationLine.slice(i, i + 80)); } @@ -47,8 +47,11 @@ export function printSourceLocation( locationStr + printPrefixedLines([ [`${lineNum} |`, subLines[0]], + // @ts-expect-error FIXME: TS Conversion ...subLines.slice(1, subLineIndex + 1).map((subLine) => ['|', subLine]), + // @ts-expect-error FIXME: TS Conversion ['|', '^'.padStart(subLineColumnNum)], + // @ts-expect-error FIXME: TS Conversion ['|', subLines[subLineIndex + 1]], ]) ); @@ -66,7 +69,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.d.ts b/src/language/printer.d.ts deleted file mode 100644 index d64f92e91a..0000000000 --- a/src/language/printer.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { ASTNode } from './ast'; -/** - * Converts an AST into a string, using one set of reasonable - * formatting rules. - */ -export function print(ast: ASTNode): string; diff --git a/src/language/printer.js b/src/language/printer.ts similarity index 96% rename from src/language/printer.js rename to src/language/printer.ts index 43bd627195..eae84d7fe3 100644 --- a/src/language/printer.js +++ b/src/language/printer.ts @@ -1,3 +1,5 @@ +import type { Maybe } from '../jsutils/Maybe'; + import type { ASTNode } from './ast'; import { visit } from './visitor'; @@ -307,7 +309,7 @@ const printDocASTReducer: any = { * 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: Maybe>, separator = ''): string { return maybeArray?.filter((x) => x).join(separator) ?? ''; } @@ -315,14 +317,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: Maybe>): 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: Maybe, + end: string = '', +): string { return maybeString != null && maybeString !== '' ? start + maybeString + end : ''; @@ -332,7 +338,7 @@ function indent(str: string): string { return wrap(' ', str.replace(/\n/g, '\n ')); } -function hasMultilineItems(maybeArray: ?Array): boolean { +function hasMultilineItems(maybeArray: Maybe>): boolean { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') return maybeArray?.some((str) => str.includes('\n')) ?? false; } diff --git a/src/language/source.d.ts b/src/language/source.d.ts deleted file mode 100644 index 01b0e6a470..0000000000 --- a/src/language/source.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -interface Location { - line: number; - column: number; -} -/** - * A representation of source input to GraphQL. The `name` and `locationOffset` parameters are - * optional, but they are useful for clients who store GraphQL documents in source files. - * For example, if the GraphQL input starts at line 40 in a file named `Foo.graphql`, it might - * be useful for `name` to be `"Foo.graphql"` and location to be `{ line: 40, column: 1 }`. - * The `line` and `column` properties in `locationOffset` are 1-indexed. - */ -export class Source { - body: string; - name: string; - locationOffset: Location; - constructor(body: string, name?: string, locationOffset?: Location); - get [Symbol.toStringTag](): string; -} -/** - * Test if the given value is a Source object. - * - * @internal - */ -export function isSource(source: unknown): source is Source; diff --git a/src/language/source.js b/src/language/source.ts similarity index 82% rename from src/language/source.js rename to src/language/source.ts index a3bfd14f92..202d04b33d 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, -}; +interface Location { + line: number; + column: number; +} /** * A representation of source input to GraphQL. The `name` and `locationOffset` parameters are @@ -42,7 +42,6 @@ export class Source { ); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'Source'; } @@ -53,9 +52,6 @@ export class Source { * * @internal */ -declare function isSource(source: mixed): boolean %checks(source instanceof - Source); -// eslint-disable-next-line no-redeclare -export function isSource(source) { +export function isSource(source: unknown): source is Source { return instanceOf(source, Source); } diff --git a/src/language/tokenKind.d.ts b/src/language/tokenKind.d.ts deleted file mode 100644 index b96022906d..0000000000 --- a/src/language/tokenKind.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * An exported enum describing the different kinds of tokens that the - * lexer emits. - */ -export const TokenKind: Readonly<{ - readonly SOF: ''; - readonly EOF: ''; - readonly BANG: '!'; - readonly DOLLAR: '$'; - readonly AMP: '&'; - readonly PAREN_L: '('; - readonly PAREN_R: ')'; - readonly SPREAD: '...'; - readonly COLON: ':'; - readonly EQUALS: '='; - readonly AT: '@'; - readonly BRACKET_L: '['; - readonly BRACKET_R: ']'; - readonly BRACE_L: '{'; - readonly PIPE: '|'; - readonly BRACE_R: '}'; - readonly NAME: 'Name'; - readonly INT: 'Int'; - readonly FLOAT: 'Float'; - readonly STRING: 'String'; - readonly BLOCK_STRING: 'BlockString'; - readonly COMMENT: 'Comment'; -}>; -/** - * The enum type representing the token kinds values. - */ -export type TokenKindEnum = typeof TokenKind[keyof typeof TokenKind]; diff --git a/src/language/tokenKind.js b/src/language/tokenKind.ts similarity index 87% rename from src/language/tokenKind.js rename to src/language/tokenKind.ts index b4f5248c13..10e1e66a80 100644 --- a/src/language/tokenKind.js +++ b/src/language/tokenKind.ts @@ -25,9 +25,9 @@ export const TokenKind = Object.freeze({ STRING: 'String', BLOCK_STRING: 'BlockString', COMMENT: 'Comment', -}); +} as const); /** * The enum type representing the token kinds values. */ -export type TokenKindEnum = $Values; +export type TokenKindEnum = typeof TokenKind[keyof typeof TokenKind]; diff --git a/src/language/visitor.d.ts b/src/language/visitor.d.ts deleted file mode 100644 index c19126b1d8..0000000000 --- a/src/language/visitor.d.ts +++ /dev/null @@ -1,127 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { ASTNode, ASTKindToNode } from './ast'; -/** - * A visitor is provided to visit, it contains the collection of - * relevant functions to be called during the visitor's traversal. - */ -export type ASTVisitor = EnterLeaveVisitor & KindVisitor; -type KindVisitor = { - readonly [K in keyof ASTKindToNode]?: - | ASTVisitFn - | EnterLeaveVisitor; -}; -interface EnterLeaveVisitor { - readonly enter?: ASTVisitFn; - readonly leave?: ASTVisitFn; -} -/** - * A visitor is comprised of visit functions, which are called on each node - * during the visitor's traversal. - */ -export type ASTVisitFn = ( - /** The current node being visiting. */ - node: TVisitedNode, - /** The index or key to this node from the parent node or Array. */ - key: string | number | undefined, - /** The parent immediately above this node, which may be an Array. */ - parent: ASTNode | ReadonlyArray | undefined, - /** 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>, -) => any; -export const BREAK: unknown; -/** - * visit() will walk through an AST using a depth-first traversal, calling - * the visitor's enter function at each node in the traversal, and calling the - * leave function after visiting that node and all of its child nodes. - * - * By returning different values from the enter and leave functions, the - * behavior of the visitor can be altered, including skipping over a sub-tree of - * the AST (by returning false), editing the AST by returning a value or null - * to remove the value, or to stop the whole traversal by returning BREAK. - * - * When using visit() to edit an AST, the original AST will not be modified, and - * a new version of the AST with the changes applied will be returned from the - * visit function. - * - * const editedAST = visit(ast, { - * enter(node, key, parent, path, ancestors) { - * // @return - * // undefined: no action - * // false: skip visiting this node - * // visitor.BREAK: stop visiting altogether - * // null: delete this node - * // any value: replace this node with the returned value - * }, - * leave(node, key, parent, path, ancestors) { - * // @return - * // undefined: no action - * // false: no action - * // visitor.BREAK: stop visiting altogether - * // null: delete this node - * // any value: replace this node with the returned value - * } - * }); - * - * Alternatively to providing enter() and leave() functions, a visitor can - * instead provide functions named the same as the kinds of AST nodes, or - * enter/leave visitors at a named key, leading to three permutations of the - * visitor API: - * - * 1) Named visitors triggered when entering a node of a specific kind. - * - * visit(ast, { - * Kind(node) { - * // enter the "Kind" node - * } - * }) - * - * 2) Named visitors that trigger upon entering and leaving a node of - * a specific kind. - * - * visit(ast, { - * Kind: { - * enter(node) { - * // enter the "Kind" node - * } - * leave(node) { - * // leave the "Kind" node - * } - * } - * }) - * - * 3) Generic visitors that trigger upon entering and leaving any node. - * - * visit(ast, { - * enter(node) { - * // enter any node - * }, - * leave(node) { - * // leave any node - * } - * }) - */ -export function visit(root: ASTNode, visitor: ASTVisitor): any; -/** - * Creates a new visitor instance which delegates to many visitors to run in - * parallel. Each visitor will be visited for each node before moving on. - * - * If a prior visitor edits a node, no following visitors will see that node. - */ -export function visitInParallel( - visitors: ReadonlyArray, -): ASTVisitor; -/** - * Given a visitor instance, if it is leaving or not, and a node kind, return - * the function the visitor runtime should call. - */ -export function getVisitFn( - visitor: ASTVisitor, - kind: string, - isLeaving: boolean, -): Maybe>; diff --git a/src/language/visitor.js b/src/language/visitor.ts similarity index 93% rename from src/language/visitor.js rename to src/language/visitor.ts index 7b4d77a008..c4cd8d422f 100644 --- a/src/language/visitor.js +++ b/src/language/visitor.ts @@ -1,4 +1,5 @@ import { inspect } from '../jsutils/inspect'; +import type { Maybe } from '../jsutils/Maybe'; import type { ASTNode, ASTKindToNode } from './ast'; import { isNode } from './ast'; @@ -7,37 +8,38 @@ import { isNode } from './ast'; * A visitor is provided to visit, it contains the collection of * relevant functions to be called during the visitor's traversal. */ -export type ASTVisitor = $Shape & KindVisitor>; +export type ASTVisitor = EnterLeaveVisitor & KindVisitor; -type KindVisitor = $ObjMap< - ASTKindToNode, - (node: Node) => ASTVisitFn | EnterLeaveVisitor, ->; - -type EnterLeaveVisitor = { - +enter?: ASTVisitFn, - +leave?: ASTVisitFn, +type KindVisitor = { + readonly [K in keyof ASTKindToNode]?: + | ASTVisitFn + | EnterLeaveVisitor; }; +interface EnterLeaveVisitor { + readonly enter?: ASTVisitFn; + readonly leave?: ASTVisitFn; +} + /** * A visitor is comprised of visit functions, which are called on each node * during the visitor's traversal. */ -export type ASTVisitFn = ( +export type ASTVisitFn = ( /** The current node being visiting. */ node: TVisitedNode, /** The index or key to this node from the parent node or Array. */ - key: string | number | void, + key: string | number | undefined, /** The parent immediately above this node, which may be an Array. */ - parent: ASTNode | $ReadOnlyArray | void, + parent: ASTNode | ReadonlyArray | undefined, /** The key path to get to this node from the root node. */ - path: $ReadOnlyArray, + 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; const QueryDocumentKeys = { @@ -126,7 +128,7 @@ const QueryDocumentKeys = { InputObjectTypeExtension: ['name', 'directives', 'fields'], }; -export const BREAK: { ... } = Object.freeze({}); +export const BREAK: unknown = Object.freeze({}); /** * visit() will walk through an AST using a depth-first traversal, calling @@ -322,7 +324,7 @@ export function visit(root: ASTNode, visitor: ASTVisitor): any { * If a prior visitor edits a node, no following visitors will see that node. */ export function visitInParallel( - visitors: $ReadOnlyArray, + visitors: ReadonlyArray, ): ASTVisitor { const skipping = new Array(visitors.length); @@ -372,7 +374,7 @@ export function getVisitFn( visitor: ASTVisitor, kind: string, isLeaving: boolean, -): ?ASTVisitFn { +): Maybe> { const kindVisitor = visitor[kind]; if (kindVisitor) { if (!isLeaving && typeof kindVisitor === 'function') { diff --git a/src/subscription/__tests__/mapAsyncIterator-test.js b/src/subscription/__tests__/mapAsyncIterator-test.ts similarity index 95% rename from src/subscription/__tests__/mapAsyncIterator-test.js rename to src/subscription/__tests__/mapAsyncIterator-test.ts index d030521050..e5e374e256 100644 --- a/src/subscription/__tests__/mapAsyncIterator-test.js +++ b/src/subscription/__tests__/mapAsyncIterator-test.ts @@ -3,6 +3,7 @@ import { describe, it } from 'mocha'; import { mapAsyncIterator } from '../mapAsyncIterator'; +/* eslint-disable @typescript-eslint/require-await */ describe('mapAsyncIterator', () => { it('maps over async generator', async () => { async function* source() { @@ -104,6 +105,7 @@ describe('mapAsyncIterator', () => { expect(await doubles.next()).to.deep.equal({ value: 4, done: false }); // Early return + // @ts-expect-error FIXME: TS Conversion expect(await doubles.return()).to.deep.equal({ value: 'The End', done: true, @@ -141,6 +143,7 @@ describe('mapAsyncIterator', () => { expect(await doubles.next()).to.deep.equal({ value: 4, done: false }); // Early return + // @ts-expect-error FIXME: TS Conversion expect(await doubles.return()).to.deep.equal({ value: undefined, done: true, @@ -150,11 +153,11 @@ describe('mapAsyncIterator', () => { it('passes through early return from async values', async () => { async function* source() { try { - yield 1; - yield 2; + yield 'a'; + yield 'b'; // istanbul ignore next (Shouldn't be reached) - yield 3; + yield 'c'; } finally { yield 'Done'; yield 'Last'; @@ -163,8 +166,8 @@ describe('mapAsyncIterator', () => { const doubles = mapAsyncIterator(source(), (x) => x + x); - expect(await doubles.next()).to.deep.equal({ value: 2, done: false }); - expect(await doubles.next()).to.deep.equal({ value: 4, done: false }); + expect(await doubles.next()).to.deep.equal({ value: 'aa', done: false }); + expect(await doubles.next()).to.deep.equal({ value: 'bb', done: false }); // Early return expect(await doubles.return()).to.deep.equal({ 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 95% rename from src/subscription/__tests__/simplePubSub.js rename to src/subscription/__tests__/simplePubSub.ts index f11f9d6b24..e4d3c5569a 100644 --- a/src/subscription/__tests__/simplePubSub.js +++ b/src/subscription/__tests__/simplePubSub.ts @@ -3,7 +3,7 @@ * PubSub system for tests. */ export class SimplePubSub { - _subscribers: Set<(value: T) => void>; + private _subscribers: Set<(value: T) => void>; constructor() { this._subscribers = new Set(); @@ -47,7 +47,7 @@ export class SimplePubSub { emptyQueue(); return Promise.resolve({ value: undefined, done: true }); }, - throw(error: mixed) { + throw(error: unknown) { emptyQueue(); return Promise.reject(error); }, diff --git a/src/subscription/__tests__/subscribe-test.js b/src/subscription/__tests__/subscribe-test.ts similarity index 97% rename from src/subscription/__tests__/subscribe-test.js rename to src/subscription/__tests__/subscribe-test.ts index e102d08c08..85a0a7e574 100644 --- a/src/subscription/__tests__/subscribe-test.js +++ b/src/subscription/__tests__/subscribe-test.ts @@ -16,12 +16,12 @@ import { createSourceEventStream, subscribe } from '../subscribe'; import { SimplePubSub } from './simplePubSub'; -type Email = { - from: string, - subject: string, - message: string, - unread: boolean, -}; +interface Email { + from: string; + subject: string; + message: string; + unread: boolean; +} const EmailType = new GraphQLObjectType({ name: 'Email', @@ -121,7 +121,7 @@ function createSubscription(pubsub: SimplePubSub) { return subscribe({ schema: emailSchema, document, rootValue: data }); } -async function expectPromise(promise: Promise) { +async function expectPromise(promise: Promise) { let caughtError; try { @@ -150,6 +150,7 @@ const DummyQueryType = new GraphQLObjectType({ }, }); +/* eslint-disable @typescript-eslint/require-await */ // Check all error cases when initializing the subscription. describe('Subscription Initialization Phase', () => { it('accepts multiple subscription fields defined in schema', async () => { @@ -311,22 +312,20 @@ describe('Subscription Initialization Phase', () => { }), }); - // $FlowExpectedError[incompatible-call] (await expectPromise(subscribe({ schema: null, document }))).toRejectWith( 'Expected null to be a GraphQL schema.', ); - // $FlowExpectedError[prop-missing] + // @ts-expect-error (await expectPromise(subscribe({ document }))).toRejectWith( 'Expected undefined to be a GraphQL schema.', ); - // $FlowExpectedError[incompatible-call] (await expectPromise(subscribe({ schema, document: null }))).toRejectWith( 'Must provide document.', ); - // $FlowExpectedError[prop-missing] + // @ts-expect-error (await expectPromise(subscribe({ schema }))).toRejectWith( 'Must provide document.', ); @@ -366,7 +365,7 @@ describe('Subscription Initialization Phase', () => { }), }); - // $FlowExpectedError[prop-missing] + // @ts-expect-error (await expectPromise(subscribe({ schema, document: {} }))).toReject(); }); @@ -392,7 +391,7 @@ describe('Subscription Initialization Phase', () => { }); it('resolves to an error for subscription resolver errors', async () => { - async function subscribeWithFn(subscribeFn: () => mixed) { + async function subscribeWithFn(subscribeFn: () => unknown) { const schema = new GraphQLSchema({ query: DummyQueryType, subscription: new GraphQLObjectType({ @@ -483,7 +482,7 @@ describe('Subscription Initialization Phase', () => { // Once a subscription returns a valid AsyncIterator, it can still yield errors. describe('Subscription Publish Phase', () => { it('produces a payload for multiple subscribe in same subscription', async () => { - const pubsub = new SimplePubSub(); + const pubsub = new SimplePubSub(); const subscription = await createSubscription(pubsub); invariant(isAsyncIterable(subscription)); @@ -526,7 +525,7 @@ describe('Subscription Publish Phase', () => { }); it('produces a payload per subscription event', async () => { - const pubsub = new SimplePubSub(); + const pubsub = new SimplePubSub(); const subscription = await createSubscription(pubsub); invariant(isAsyncIterable(subscription)); @@ -615,7 +614,7 @@ describe('Subscription Publish Phase', () => { }); it('produces a payload when there are multiple events', async () => { - const pubsub = new SimplePubSub(); + const pubsub = new SimplePubSub(); const subscription = await createSubscription(pubsub); invariant(isAsyncIterable(subscription)); @@ -681,7 +680,7 @@ describe('Subscription Publish Phase', () => { }); it('should not trigger when subscription is already done', async () => { - const pubsub = new SimplePubSub(); + const pubsub = new SimplePubSub(); const subscription = await createSubscription(pubsub); invariant(isAsyncIterable(subscription)); @@ -735,7 +734,7 @@ describe('Subscription Publish Phase', () => { }); it('should not trigger when subscription is thrown', async () => { - const pubsub = new SimplePubSub(); + const pubsub = new SimplePubSub(); const subscription = await createSubscription(pubsub); invariant(isAsyncIterable(subscription)); @@ -787,7 +786,7 @@ describe('Subscription Publish Phase', () => { }); it('event order is correct for multiple publishes', async () => { - const pubsub = new SimplePubSub(); + const pubsub = new SimplePubSub(); const subscription = await createSubscription(pubsub); invariant(isAsyncIterable(subscription)); diff --git a/src/subscription/index.js b/src/subscription/index.js deleted file mode 100644 index 899e443b6b..0000000000 --- a/src/subscription/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { subscribe, createSourceEventStream } from './subscribe'; -export type { SubscriptionArgs } from './subscribe'; diff --git a/src/subscription/index.d.ts b/src/subscription/index.ts similarity index 100% rename from src/subscription/index.d.ts rename to src/subscription/index.ts diff --git a/src/subscription/mapAsyncIterator.d.ts b/src/subscription/mapAsyncIterator.d.ts deleted file mode 100644 index a625837eb1..0000000000 --- a/src/subscription/mapAsyncIterator.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; -/** - * Given an AsyncIterable and a callback function, return an AsyncIterator - * which produces values mapped via calling the callback function. - */ -export function mapAsyncIterator( - iterable: AsyncGenerator | AsyncIterable, - callback: (value: T) => PromiseOrValue, -): AsyncGenerator; diff --git a/src/subscription/mapAsyncIterator.js b/src/subscription/mapAsyncIterator.ts similarity index 91% rename from src/subscription/mapAsyncIterator.js rename to src/subscription/mapAsyncIterator.ts index 1c5c670b8a..4e9563c752 100644 --- a/src/subscription/mapAsyncIterator.js +++ b/src/subscription/mapAsyncIterator.ts @@ -4,7 +4,7 @@ import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; * Given an AsyncIterable and a callback function, return an AsyncIterator * which produces values mapped via calling the callback function. */ -export function mapAsyncIterator( +export function mapAsyncIterator( iterable: AsyncGenerator | AsyncIterable, callback: (value: T) => PromiseOrValue, ): AsyncGenerator { @@ -19,6 +19,7 @@ export function mapAsyncIterator( } try { + // @ts-expect-error FIXME: TS Conversion return { value: await callback(result.value), done: false }; } catch (error) { // istanbul ignore else (FIXME: add test case) @@ -42,7 +43,7 @@ export function mapAsyncIterator( ? mapResult(await iterator.return()) : { value: undefined, done: true }; }, - async throw(error?: mixed) { + async throw(error?: unknown) { return typeof iterator.throw === 'function' ? mapResult(await iterator.throw(error)) : Promise.reject(error); diff --git a/src/subscription/subscribe.d.ts b/src/subscription/subscribe.d.ts deleted file mode 100644 index 29349b19d3..0000000000 --- a/src/subscription/subscribe.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { DocumentNode } from '../language/ast'; -import type { ExecutionResult } from '../execution/execute'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLFieldResolver } from '../type/definition'; -export interface SubscriptionArgs { - schema: GraphQLSchema; - document: DocumentNode; - rootValue?: unknown; - contextValue?: unknown; - variableValues?: Maybe<{ - readonly [variable: string]: unknown; - }>; - operationName?: Maybe; - fieldResolver?: Maybe>; - subscribeFieldResolver?: Maybe>; -} -/** - * Implements the "Subscribe" algorithm described in the GraphQL specification. - * - * Returns a Promise which resolves to either an AsyncIterator (if successful) - * or an ExecutionResult (error). The promise will be rejected if the schema or - * other arguments to this function are invalid, or if the resolved event stream - * is not an async iterable. - * - * If the client-provided arguments to this function do not result in a - * compliant subscription, a GraphQL Response (ExecutionResult) with - * descriptive errors and no data will be returned. - * - * If the source stream could not be created due to faulty subscription - * resolver logic or underlying systems, the promise will resolve to a single - * ExecutionResult containing `errors` and no `data`. - * - * If the operation succeeded, the promise resolves to an AsyncIterator, which - * yields a stream of ExecutionResults representing the response stream. - * - * Accepts either an object with named arguments, or individual arguments. - */ -export function subscribe( - args: SubscriptionArgs, -): Promise | ExecutionResult>; -/** - * Implements the "CreateSourceEventStream" algorithm described in the - * GraphQL specification, resolving the subscription source event stream. - * - * Returns a Promise which resolves to either an AsyncIterable (if successful) - * or an ExecutionResult (error). The promise will be rejected if the schema or - * other arguments to this function are invalid, or if the resolved event stream - * is not an async iterable. - * - * If the client-provided arguments to this function do not result in a - * compliant subscription, a GraphQL Response (ExecutionResult) with - * descriptive errors and no data will be returned. - * - * If the the source stream could not be created due to faulty subscription - * resolver logic or underlying systems, the promise will resolve to a single - * ExecutionResult containing `errors` and no `data`. - * - * If the operation succeeded, the promise resolves to the AsyncIterable for the - * event stream returned by the resolver. - * - * A Source Event Stream represents a sequence of events, each of which triggers - * a GraphQL execution for that event. - * - * This may be useful when hosting the stateful subscription service in a - * different process or machine than the stateless GraphQL execution engine, - * or otherwise separating these two steps. For more on this, see the - * "Supporting Subscriptions at Scale" information in the GraphQL specification. - */ -export function createSourceEventStream( - schema: GraphQLSchema, - document: DocumentNode, - rootValue?: unknown, - contextValue?: unknown, - variableValues?: Maybe<{ - readonly [variable: string]: unknown; - }>, - operationName?: Maybe, - fieldResolver?: Maybe>, -): Promise | ExecutionResult>; diff --git a/src/subscription/subscribe.js b/src/subscription/subscribe.ts similarity index 91% rename from src/subscription/subscribe.js rename to src/subscription/subscribe.ts index b9a2d63bfb..4d194d894c 100644 --- a/src/subscription/subscribe.js +++ b/src/subscription/subscribe.ts @@ -1,6 +1,7 @@ import { inspect } from '../jsutils/inspect'; import { isAsyncIterable } from '../jsutils/isAsyncIterable'; import { addPath, pathToArray } from '../jsutils/Path'; +import type { Maybe } from '../jsutils/Maybe'; import { GraphQLError } from '../error/GraphQLError'; import { locatedError } from '../error/locatedError'; @@ -25,16 +26,16 @@ 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 interface SubscriptionArgs { + schema: GraphQLSchema; + document: DocumentNode; + rootValue?: unknown; + contextValue?: unknown; + variableValues?: Maybe<{ readonly [variable: string]: unknown }>; + operationName?: Maybe; + fieldResolver?: Maybe>; + subscribeFieldResolver?: Maybe>; +} /** * Implements the "Subscribe" algorithm described in the GraphQL specification. @@ -71,7 +72,6 @@ export async function subscribe( subscribeFieldResolver, } = args; - // $FlowFixMe[incompatible-call] const resultOrStream = await createSourceEventStream( schema, document, @@ -138,12 +138,12 @@ export async function subscribe( export async 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?: Maybe<{ readonly [variable: string]: unknown }>, + operationName?: Maybe, + fieldResolver?: Maybe>, +): 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); @@ -165,6 +165,7 @@ export async function createSourceEventStream( return { errors: exeContext }; } + // @ts-expect-error FIXME: TS Conversion const eventStream = await executeSubscription(exeContext); // Assert field returned an event stream, otherwise yield an error. @@ -188,7 +189,7 @@ export async function createSourceEventStream( async 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 93% rename from src/type/__tests__/definition-test.js rename to src/type/__tests__/definition-test.ts index 809e7007d3..12ef0aebf4 100644 --- a/src/type/__tests__/definition-test.js +++ b/src/type/__tests__/definition-test.ts @@ -83,9 +83,11 @@ describe('Type System: Scalars', () => { }, }); + // @ts-expect-error FIXME: TS Conversion expect(scalar.parseLiteral(parseValue('null'))).to.equal( 'parseValue: null', ); + // @ts-expect-error FIXME: TS Conversion expect(scalar.parseLiteral(parseValue('{ foo: "bar" }'))).to.equal( 'parseValue: { foo: "bar" }', ); @@ -95,7 +97,7 @@ describe('Type System: Scalars', () => { }); it('rejects a Scalar type without name', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLScalarType({})).to.throw('Must provide name.'); }); @@ -104,7 +106,7 @@ describe('Type System: Scalars', () => { () => new GraphQLScalarType({ name: 'SomeScalar', - // $FlowExpectedError[prop-missing] + // @ts-expect-error serialize: {}, }), ).to.throw( @@ -129,9 +131,9 @@ describe('Type System: Scalars', () => { () => new GraphQLScalarType({ name: 'SomeScalar', - // $FlowExpectedError[prop-missing] + // @ts-expect-error parseValue: {}, - // $FlowExpectedError[prop-missing] + // @ts-expect-error parseLiteral: {}, }), ).to.throw( @@ -144,7 +146,7 @@ describe('Type System: Scalars', () => { () => new GraphQLScalarType({ name: 'SomeScalar', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error specifiedByURL: {}, }), ).to.throw( @@ -325,7 +327,7 @@ describe('Type System: Objects', () => { }); it('rejects an Object type without name', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLObjectType({})).to.throw('Must provide name.'); }); @@ -333,7 +335,6 @@ describe('Type System: Objects', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', fields: { - // $FlowExpectedError[incompatible-call] f: undefined, }, }); @@ -345,7 +346,7 @@ describe('Type System: Objects', () => { it('rejects an Object type with incorrectly typed fields', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error fields: [{ field: ScalarType }], }); expect(() => objType.getFields()).to.throw( @@ -356,8 +357,8 @@ describe('Type System: Objects', () => { it('rejects an Object type with a field function that returns incorrect type', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', + // @ts-expect-error FIXME: TS Conversion fields() { - // $FlowExpectedError[incompatible-call] return [{ field: ScalarType }]; }, }); @@ -370,7 +371,7 @@ describe('Type System: Objects', () => { fields: { badField: { type: ScalarType, - // $FlowExpectedError[incompatible-call] + // @ts-expect-error args: [{ badArg: ScalarType }], }, }, @@ -384,7 +385,7 @@ describe('Type System: Objects', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', fields: {}, - // $FlowExpectedError[incompatible-call] + // @ts-expect-error interfaces: {}, }); expect(() => objType.getInterfaces()).to.throw( @@ -396,8 +397,8 @@ describe('Type System: Objects', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', fields: {}, + // @ts-expect-error FIXME: TS Conversion interfaces() { - // $FlowExpectedError[incompatible-call] return {}; }, }); @@ -409,8 +410,8 @@ describe('Type System: Objects', () => { it('rejects an empty Object field resolver', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', - // $FlowExpectedError[incompatible-call] fields: { + // @ts-expect-error FIXME: TS Conversion field: { type: ScalarType, resolve: {} }, }, }); @@ -423,8 +424,8 @@ describe('Type System: Objects', () => { it('rejects a constant scalar value resolver', () => { const objType = new GraphQLObjectType({ name: 'SomeObject', - // $FlowExpectedError[incompatible-call] fields: { + // @ts-expect-error FIXME: TS Conversion field: { type: ScalarType, resolve: 0 }, }, }); @@ -440,7 +441,7 @@ describe('Type System: Objects', () => { new GraphQLObjectType({ name: 'AnotherObject', fields: {}, - // $FlowExpectedError[prop-missing] + // @ts-expect-error isTypeOf: {}, }), ).to.throw( @@ -479,7 +480,7 @@ describe('Type System: Interfaces', () => { }); it('rejects an Interface type without name', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLInterfaceType({})).to.throw('Must provide name.'); }); @@ -487,7 +488,7 @@ describe('Type System: Interfaces', () => { const objType = new GraphQLInterfaceType({ name: 'AnotherInterface', fields: {}, - // $FlowExpectedError[incompatible-call] + // @ts-expect-error interfaces: {}, }); expect(() => objType.getInterfaces()).to.throw( @@ -499,8 +500,8 @@ describe('Type System: Interfaces', () => { const objType = new GraphQLInterfaceType({ name: 'AnotherInterface', fields: {}, + // @ts-expect-error FIXME: TS Conversion interfaces() { - // $FlowExpectedError[incompatible-call] return {}; }, }); @@ -515,7 +516,7 @@ describe('Type System: Interfaces', () => { new GraphQLInterfaceType({ name: 'AnotherInterface', fields: {}, - // $FlowExpectedError[prop-missing] + // @ts-expect-error resolveType: {}, }), ).to.throw( @@ -560,7 +561,7 @@ describe('Type System: Unions', () => { }); it('rejects an Union type without name', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLUnionType({})).to.throw('Must provide name.'); }); @@ -570,7 +571,7 @@ describe('Type System: Unions', () => { new GraphQLUnionType({ name: 'SomeUnion', types: [], - // $FlowExpectedError[prop-missing] + // @ts-expect-error resolveType: {}, }), ).to.throw( @@ -581,7 +582,7 @@ describe('Type System: Unions', () => { it('rejects a Union type with incorrectly typed types', () => { const unionType = new GraphQLUnionType({ name: 'SomeUnion', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error types: { ObjectType }, }); @@ -675,7 +676,7 @@ describe('Type System: Enums', () => { }); it('rejects an Enum type without name', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLEnumType({ values: {} })).to.throw( 'Must provide name.', ); @@ -686,7 +687,7 @@ describe('Type System: Enums', () => { () => new GraphQLEnumType({ name: 'SomeEnum', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error values: [{ FOO: 10 }], }), ).to.throw('SomeEnum values must be an object with value names as keys.'); @@ -697,7 +698,6 @@ describe('Type System: Enums', () => { () => new GraphQLEnumType({ name: 'SomeEnum', - // $FlowExpectedError[incompatible-call] values: { FOO: null }, }), ).to.throw( @@ -710,7 +710,7 @@ describe('Type System: Enums', () => { () => new GraphQLEnumType({ name: 'SomeEnum', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error values: { FOO: 10 }, }), ).to.throw( @@ -762,7 +762,7 @@ describe('Type System: Input Objects', () => { }); it('rejects an Input Object type without name', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLInputObjectType({})).to.throw( 'Must provide name.', ); @@ -771,7 +771,7 @@ describe('Type System: Input Objects', () => { it('rejects an Input Object type with incorrect fields', () => { const inputObjType = new GraphQLInputObjectType({ name: 'SomeInputObject', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error fields: [], }); expect(() => inputObjType.getFields()).to.throw( @@ -782,7 +782,7 @@ describe('Type System: Input Objects', () => { it('rejects an Input Object type with fields function that returns incorrect type', () => { const inputObjType = new GraphQLInputObjectType({ name: 'SomeInputObject', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error fields: () => [], }); expect(() => inputObjType.getFields()).to.throw( @@ -795,8 +795,8 @@ describe('Type System: Input Objects', () => { it('rejects an Input Object type with resolvers', () => { const inputObjType = new GraphQLInputObjectType({ name: 'SomeInputObject', - // $FlowExpectedError[incompatible-call] fields: { + // @ts-expect-error FIXME: TS Conversion f: { type: ScalarType, resolve: dummyFunc }, }, }); @@ -808,8 +808,8 @@ describe('Type System: Input Objects', () => { it('rejects an Input Object type with resolver constant', () => { const inputObjType = new GraphQLInputObjectType({ name: 'SomeInputObject', - // $FlowExpectedError[incompatible-call] fields: { + // @ts-expect-error FIXME: TS Conversion f: { type: ScalarType, resolve: {} }, }, }); @@ -837,15 +837,13 @@ describe('Type System: List', () => { }); it('rejects a non-type as item type of list', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expectList({}).to.throw('Expected {} to be a GraphQL type.'); - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expectList(String).to.throw( 'Expected [function String] to be a GraphQL type.', ); - // $FlowExpectedError[incompatible-call] expectList(null).to.throw('Expected null to be a GraphQL type.'); - // $FlowExpectedError[incompatible-call] expectList(undefined).to.throw('Expected undefined to be a GraphQL type.'); }); }); @@ -867,21 +865,18 @@ describe('Type System: Non-Null', () => { }); it('rejects a non-type as nullable type of non-null', () => { - // $FlowExpectedError[incompatible-call] expectNonNull(NonNullScalarType).to.throw( 'Expected Scalar! to be a GraphQL nullable type.', ); - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expectNonNull({}).to.throw('Expected {} to be a GraphQL nullable type.'); - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expectNonNull(String).to.throw( 'Expected [function String] to be a GraphQL nullable type.', ); - // $FlowExpectedError[incompatible-call] expectNonNull(null).to.throw( 'Expected null to be a GraphQL nullable type.', ); - // $FlowExpectedError[incompatible-call] expectNonNull(undefined).to.throw( 'Expected undefined to be a GraphQL nullable type.', ); @@ -922,7 +917,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 94% rename from src/type/__tests__/directive-test.js rename to src/type/__tests__/directive-test.ts index 0dc7de5132..19249b3b14 100644 --- a/src/type/__tests__/directive-test.js +++ b/src/type/__tests__/directive-test.ts @@ -85,7 +85,7 @@ describe('Type System: Directive', () => { }); it('rejects an unnamed directive', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLDirective({ locations: ['QUERY'] })).to.throw( 'Directive must be named.', ); @@ -97,21 +97,21 @@ describe('Type System: Directive', () => { new GraphQLDirective({ name: 'Foo', locations: ['QUERY'], - // $FlowExpectedError[incompatible-call] + // @ts-expect-error args: [], }), ).to.throw('@Foo args must be an object with argument names as keys.'); }); it('rejects a directive with undefined locations', () => { - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => new GraphQLDirective({ name: 'Foo' })).to.throw( '@Foo locations must be an Array.', ); }); it('rejects a directive with incorrectly typed locations', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => new GraphQLDirective({ name: 'Foo', locations: {} })).to.throw( '@Foo locations must be an Array.', ); 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..c3cf23cd1c 100644 --- a/src/type/__tests__/enumType-test.js +++ b/src/type/__tests__/enumType-test.ts @@ -114,7 +114,7 @@ const schema = new GraphQLSchema({ function executeQuery( source: string, - variableValues?: { +[variable: string]: mixed, ... }, + variableValues?: { readonly [variable: string]: unknown }, ) { return graphqlSync({ schema, source, variableValues }); } @@ -364,7 +364,7 @@ describe('Type System: Enum Values', () => { const oneValue = ComplexEnum.getValue('ONE'); expect(oneValue).to.include({ name: 'ONE', value: Complex1 }); - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const badUsage = ComplexEnum.getValue(Complex1); expect(badUsage).to.equal(undefined); }); 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 de218c3db3..93cdedcb6b 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 99% rename from src/type/__tests__/introspection-test.js rename to src/type/__tests__/introspection-test.ts index 9db9470e97..3a01af5a52 100644 --- a/src/type/__tests__/introspection-test.js +++ b/src/type/__tests__/introspection-test.ts @@ -1566,12 +1566,12 @@ describe('Introspection', () => { }); // istanbul ignore next (Called only to fail test) - function fieldResolver(_1, _2, _3, info) { + function fieldResolver(_1, _2, _3, info): never { expect.fail(`Called on ${info.parentType.name}::${info.fieldName}`); } // istanbul ignore next (Called only to fail test) - function typeResolver(_1, _2, info) { + function typeResolver(_1, _2, info): never { expect.fail(`Called on ${info.parentType.name}::${info.fieldName}`); } 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 9c011a240c..94e152e1aa 100644 --- a/src/type/__tests__/predicate-test.js +++ b/src/type/__tests__/predicate-test.ts @@ -300,7 +300,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(); } @@ -321,7 +321,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(); } @@ -344,7 +344,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(); } @@ -371,7 +371,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(); } @@ -564,8 +564,8 @@ describe('Type predicates', () => { describe('isRequiredArgument', () => { function buildArg(config: { - type: GraphQLInputType, - defaultValue?: mixed, + type: GraphQLInputType; + defaultValue?: unknown; }): GraphQLArgument { return { name: 'someArg', @@ -612,8 +612,8 @@ describe('Type predicates', () => { describe('isRequiredInputField', () => { function buildInputField(config: { - type: GraphQLInputType, - defaultValue?: mixed, + type: GraphQLInputType; + defaultValue?: unknown; }): GraphQLInputField { return { name: 'someInputField', 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 8eac0f6266..bdfa337585 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 98% rename from src/type/__tests__/schema-test.js rename to src/type/__tests__/schema-test.ts index 958614cf0a..44ace12c11 100644 --- a/src/type/__tests__/schema-test.js +++ b/src/type/__tests__/schema-test.ts @@ -328,11 +328,11 @@ describe('Type System: Schema', () => { }); it('checks the configuration for mistakes', () => { - // $FlowExpectedError[incompatible-exact] + // @ts-expect-error expect(() => new GraphQLSchema(JSON.parse)).to.throw(); - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => new GraphQLSchema({ types: {} })).to.throw(); - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => new GraphQLSchema({ directives: {} })).to.throw(); }); }); @@ -361,7 +361,7 @@ describe('Type System: Schema', () => { }); const types = [{}, query, {}]; - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => new GraphQLSchema({ query, types })).to.throw( 'One of the provided types for building the Schema is missing a name.', ); diff --git a/src/type/__tests__/validation-test.js b/src/type/__tests__/validation-test.ts similarity index 98% rename from src/type/__tests__/validation-test.js rename to src/type/__tests__/validation-test.ts index 34939afe93..1e2548c047 100644 --- a/src/type/__tests__/validation-test.js +++ b/src/type/__tests__/validation-test.ts @@ -68,7 +68,7 @@ const SomeInputObjectType = assertInputObjectType( const SomeDirective = assertDirective(SomeSchema.getDirective('SomeDirective')); -function withModifiers( +function withModifiers( type: T, ): Array | GraphQLNonNull>> { return [ @@ -391,7 +391,7 @@ describe('Type System: A Schema must have Object root types', () => { it('rejects a Schema whose types are incorrectly typed', () => { const schema = new GraphQLSchema({ query: SomeObjectType, - // $FlowExpectedError[incompatible-call] + // @ts-expect-error types: [{ name: 'SomeType' }, SomeDirective], }); expect(validateSchema(schema)).to.deep.equal([ @@ -408,7 +408,7 @@ describe('Type System: A Schema must have Object root types', () => { it('rejects a Schema whose directives are incorrectly typed', () => { const schema = new GraphQLSchema({ query: SomeObjectType, - // $FlowExpectedError[incompatible-call] + // @ts-expect-error directives: [null, 'SomeDirective', SomeScalarType], }); expect(validateSchema(schema)).to.deep.equal([ @@ -688,7 +688,7 @@ describe('Type System: Union types must be valid', () => { for (const memberType of badUnionMemberTypes) { const badUnion = new GraphQLUnionType({ name: 'BadUnion', - // $FlowExpectedError[incompatible-call] + // @ts-expect-error types: [memberType], }); const badSchema = schemaWithFieldType(badUnion); @@ -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', @@ -1036,7 +1036,6 @@ describe('Type System: Object fields must have output types', () => { } it('rejects an empty Object field type', () => { - // $FlowExpectedError[incompatible-call] const schema = schemaWithObjectField({ type: undefined }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1049,7 +1048,7 @@ describe('Type System: Object fields must have output types', () => { for (const type of notOutputTypes) { const typeStr = inspect(type); it(`rejects a non-output type as an Object field type: ${typeStr}`, () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithObjectField({ type }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1060,7 +1059,7 @@ describe('Type System: Object fields must have output types', () => { } it('rejects a non-type value as an Object field type', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithObjectField({ type: Number }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1098,7 +1097,6 @@ describe('Type System: Objects can only implement unique interfaces', () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'BadObject', - // $FlowExpectedError[incompatible-call] interfaces: [undefined], fields: { f: { type: GraphQLString } }, }), @@ -1322,7 +1320,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 }; @@ -1357,7 +1355,6 @@ describe('Type System: Interface fields must have output types', () => { } it('rejects an empty Interface field type', () => { - // $FlowExpectedError[incompatible-call] const schema = schemaWithInterfaceField({ type: undefined }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1374,7 +1371,7 @@ describe('Type System: Interface fields must have output types', () => { for (const type of notOutputTypes) { const typeStr = inspect(type); it(`rejects a non-output type as an Interface field type: ${typeStr}`, () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithInterfaceField({ type }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1388,7 +1385,7 @@ describe('Type System: Interface fields must have output types', () => { } it('rejects a non-type value as an Interface field type', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithInterfaceField({ type: Number }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1493,7 +1490,6 @@ describe('Type System: Arguments must have input types', () => { } it('rejects an empty field arg type', () => { - // $FlowExpectedError[incompatible-call] const schema = schemaWithArg({ type: undefined }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1510,7 +1506,7 @@ describe('Type System: Arguments must have input types', () => { for (const type of notInputTypes) { const typeStr = inspect(type); it(`rejects a non-input type as a field arg type: ${typeStr}`, () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithArg({ type }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1524,7 +1520,7 @@ describe('Type System: Arguments must have input types', () => { } it('rejects a non-type value as a field arg type', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithArg({ type: Number }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1631,7 +1627,6 @@ describe('Type System: Input Object fields must have input types', () => { } it('rejects an empty input field type', () => { - // $FlowExpectedError[incompatible-call] const schema = schemaWithInputField({ type: undefined }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1644,7 +1639,7 @@ describe('Type System: Input Object fields must have input types', () => { for (const type of notInputTypes) { const typeStr = inspect(type); it(`rejects a non-input type as an input field type: ${typeStr}`, () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithInputField({ type }); expect(validateSchema(schema)).to.deep.equal([ { @@ -1655,7 +1650,7 @@ describe('Type System: Input Object fields must have input types', () => { } it('rejects a non-type value as an input field type', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error const schema = schemaWithInputField({ type: Number }); expect(validateSchema(schema)).to.deep.equal([ { diff --git a/src/type/definition.d.ts b/src/type/definition.d.ts deleted file mode 100644 index 3f5be271e4..0000000000 --- a/src/type/definition.d.ts +++ /dev/null @@ -1,879 +0,0 @@ -import type { Path } from '../jsutils/Path'; -import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; -import type { ObjMap } from '../jsutils/ObjMap'; -import type { Maybe } from '../jsutils/Maybe'; -import type { - FieldNode, - ValueNode, - OperationDefinitionNode, - FragmentDefinitionNode, - ScalarTypeDefinitionNode, - ScalarTypeExtensionNode, - ObjectTypeDefinitionNode, - ObjectTypeExtensionNode, - FieldDefinitionNode, - InputValueDefinitionNode, - InterfaceTypeDefinitionNode, - InterfaceTypeExtensionNode, - UnionTypeDefinitionNode, - UnionTypeExtensionNode, - EnumTypeDefinitionNode, - EnumValueDefinitionNode, - EnumTypeExtensionNode, - InputObjectTypeDefinitionNode, - InputObjectTypeExtensionNode, -} from '../language/ast'; -import type { GraphQLSchema } from './schema'; -/** - * These are all of the possible kinds of types. - */ -export type GraphQLType = - | GraphQLScalarType - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType - | GraphQLEnumType - | GraphQLInputObjectType - | GraphQLList - | GraphQLNonNull< - | GraphQLScalarType - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType - | GraphQLEnumType - | GraphQLInputObjectType - | GraphQLList - >; -export function isType(type: unknown): type is GraphQLType; -export function assertType(type: unknown): GraphQLType; -/** - * There are predicates for each kind of GraphQL type. - */ -export function isScalarType(type: unknown): type is GraphQLScalarType; -export function assertScalarType(type: unknown): GraphQLScalarType; -export function isObjectType(type: unknown): type is GraphQLObjectType; -export function assertObjectType(type: unknown): GraphQLObjectType; -export function isInterfaceType(type: unknown): type is GraphQLInterfaceType; -export function assertInterfaceType(type: unknown): GraphQLInterfaceType; -export function isUnionType(type: unknown): type is GraphQLUnionType; -export function assertUnionType(type: unknown): GraphQLUnionType; -export function isEnumType(type: unknown): type is GraphQLEnumType; -export function assertEnumType(type: unknown): GraphQLEnumType; -export function isInputObjectType( - type: unknown, -): type is GraphQLInputObjectType; -export function assertInputObjectType(type: unknown): GraphQLInputObjectType; -export function isListType( - type: GraphQLInputType, -): type is GraphQLList; -export function isListType( - type: GraphQLOutputType, -): type is GraphQLList; -export function isListType(type: unknown): type is GraphQLList; -export function assertListType(type: unknown): GraphQLList; -export function isNonNullType( - type: GraphQLInputType, -): type is GraphQLNonNull; -export function isNonNullType( - type: GraphQLOutputType, -): type is GraphQLNonNull; -export function isNonNullType( - type: unknown, -): type is GraphQLNonNull; -export function assertNonNullType(type: unknown): GraphQLNonNull; -/** - * These types may be used as input types for arguments and directives. - */ -export type GraphQLInputType = - | GraphQLScalarType - | GraphQLEnumType - | GraphQLInputObjectType - | GraphQLList - | GraphQLNonNull< - | GraphQLScalarType - | GraphQLEnumType - | GraphQLInputObjectType - | GraphQLList - >; -export function isInputType(type: unknown): type is GraphQLInputType; -export function assertInputType(type: unknown): GraphQLInputType; -/** - * These types may be used as output types as the result of fields. - */ -export type GraphQLOutputType = - | GraphQLScalarType - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType - | GraphQLEnumType - | GraphQLList - | GraphQLNonNull< - | GraphQLScalarType - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType - | GraphQLEnumType - | GraphQLList - >; -export function isOutputType(type: unknown): type is GraphQLOutputType; -export function assertOutputType(type: unknown): GraphQLOutputType; -/** - * These types may describe types which may be leaf values. - */ -export type GraphQLLeafType = GraphQLScalarType | GraphQLEnumType; -export function isLeafType(type: unknown): type is GraphQLLeafType; -export function assertLeafType(type: unknown): GraphQLLeafType; -/** - * These types may describe the parent context of a selection set. - */ -export type GraphQLCompositeType = - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType; -export function isCompositeType(type: unknown): type is GraphQLCompositeType; -export function assertCompositeType(type: unknown): GraphQLCompositeType; -/** - * These types may describe the parent context of a selection set. - */ -export type GraphQLAbstractType = GraphQLInterfaceType | GraphQLUnionType; -export function isAbstractType(type: unknown): type is GraphQLAbstractType; -export function assertAbstractType(type: unknown): GraphQLAbstractType; -/** - * List Type Wrapper - * - * A list is a wrapping type which points to another type. - * Lists are often created within the context of defining the fields of - * an object type. - * - * Example: - * - * const PersonType = new GraphQLObjectType({ - * name: 'Person', - * fields: () => ({ - * parents: { type: new GraphQLList(PersonType) }, - * children: { type: new GraphQLList(PersonType) }, - * }) - * }) - * - */ -export class GraphQLList { - readonly ofType: T; - constructor(ofType: T); - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -/** - * Non-Null Type Wrapper - * - * A non-null is a wrapping type which points to another type. - * Non-null types enforce that their values are never null and can ensure - * an error is raised if this ever occurs during a request. It is useful for - * fields which you can make a strong guarantee on non-nullability, for example - * usually the id field of a database row will never be null. - * - * Example: - * - * const RowType = new GraphQLObjectType({ - * name: 'Row', - * fields: () => ({ - * id: { type: new GraphQLNonNull(GraphQLString) }, - * }) - * }) - * - * Note: the enforcement of non-nullability occurs within the executor. - */ -export class GraphQLNonNull { - readonly ofType: T; - constructor(ofType: T); - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -/** - * These types wrap and modify other types - */ -export type GraphQLWrappingType = - | GraphQLList - | GraphQLNonNull; -export function isWrappingType(type: unknown): type is GraphQLWrappingType; -export function assertWrappingType(type: unknown): GraphQLWrappingType; -/** - * These types can all accept null as a value. - */ -export type GraphQLNullableType = - | GraphQLScalarType - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType - | GraphQLEnumType - | GraphQLInputObjectType - | GraphQLList; -export function isNullableType(type: unknown): type is GraphQLNullableType; -export function assertNullableType(type: unknown): GraphQLNullableType; -export function getNullableType(type: undefined | null): void; -export function getNullableType( - type: T | GraphQLNonNull, -): T; -/** - * These named types do not include modifiers like List or NonNull. - */ -export type GraphQLNamedType = GraphQLNamedInputType | GraphQLNamedOutputType; -export type GraphQLNamedInputType = - | GraphQLScalarType - | GraphQLEnumType - | GraphQLInputObjectType; -export type GraphQLNamedOutputType = - | GraphQLScalarType - | GraphQLObjectType - | GraphQLInterfaceType - | GraphQLUnionType - | GraphQLEnumType; -export function isNamedType(type: unknown): type is GraphQLNamedType; -export function assertNamedType(type: unknown): GraphQLNamedType; -export function getNamedType(type: undefined | null): void; -export function getNamedType(type: GraphQLInputType): GraphQLNamedInputType; -export function getNamedType(type: GraphQLOutputType): GraphQLNamedOutputType; -export function getNamedType(type: GraphQLType): GraphQLNamedType; -/** - * Used while defining GraphQL types to allow for circular references in - * otherwise immutable type definitions. - */ -export type ThunkArray = (() => Array) | Array; -export type ThunkObjMap = (() => ObjMap) | ObjMap; -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLScalarTypeExtensions { - [attributeName: string]: unknown; -} -/** - * Scalar Type Definition - * - * The leaf values of any request and input values to arguments are - * Scalars (or Enums) and are defined with a name and a series of functions - * used to parse input from ast or variables and to ensure validity. - * - * If a type's serialize function does not return a value (i.e. it returns - * `undefined`) then an error will be raised and a `null` value will be returned - * in the response. If the serialize function returns `null`, then no error will - * be included in the response. - * - * Example: - * - * const OddType = new GraphQLScalarType({ - * name: 'Odd', - * serialize(value) { - * if (value % 2 === 1) { - * return value; - * } - * } - * }); - * - */ -export class GraphQLScalarType { - name: string; - description: Maybe; - specifiedByURL: Maybe; - serialize: GraphQLScalarSerializer; - parseValue: GraphQLScalarValueParser; - parseLiteral: GraphQLScalarLiteralParser; - extensions: Maybe>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - constructor(config: Readonly>); - toConfig(): GraphQLScalarTypeNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export type GraphQLScalarSerializer = ( - outputValue: unknown, -) => Maybe; -export type GraphQLScalarValueParser = ( - inputValue: unknown, -) => Maybe; -export type GraphQLScalarLiteralParser = ( - valueNode: ValueNode, - variables: Maybe>, -) => Maybe; -export interface GraphQLScalarTypeConfig { - name: string; - description?: Maybe; - specifiedByURL?: Maybe; - /** Serializes an internal value to include in a response. */ - serialize?: GraphQLScalarSerializer; - /** Parses an externally provided value to use as an input. */ - parseValue?: GraphQLScalarValueParser; - /** Parses an externally provided literal value to use as an input. */ - parseLiteral?: GraphQLScalarLiteralParser; - extensions?: Maybe>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -interface GraphQLScalarTypeNormalizedConfig - extends GraphQLScalarTypeConfig { - serialize: GraphQLScalarSerializer; - parseValue: GraphQLScalarValueParser; - parseLiteral: GraphQLScalarLiteralParser; - extensions: Maybe>; - extensionASTNodes: ReadonlyArray; -} -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - * - * We've provided these template arguments because this is an open type and - * you may find them useful. - */ -export interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> { - [attributeName: string]: unknown; -} -/** - * Object Type Definition - * - * Almost all of the GraphQL types you define will be object types. Object types - * have a name, but most importantly describe their fields. - * - * Example: - * - * const AddressType = new GraphQLObjectType({ - * name: 'Address', - * fields: { - * street: { type: GraphQLString }, - * number: { type: GraphQLInt }, - * formatted: { - * type: GraphQLString, - * resolve(obj) { - * return obj.number + ' ' + obj.street - * } - * } - * } - * }); - * - * When two types need to refer to each other, or a type needs to refer to - * itself in a field, you can use a function expression (aka a closure or a - * thunk) to supply the fields lazily. - * - * Example: - * - * const PersonType = new GraphQLObjectType({ - * name: 'Person', - * fields: () => ({ - * name: { type: GraphQLString }, - * bestFriend: { type: PersonType }, - * }) - * }); - * - */ -export class GraphQLObjectType { - name: string; - description: Maybe; - isTypeOf: Maybe>; - extensions: Maybe>>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - private _fields; - private _interfaces; - constructor(config: Readonly>); - getFields(): GraphQLFieldMap; - getInterfaces(): Array; - toConfig(): GraphQLObjectTypeNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export function defineArguments( - config: GraphQLFieldConfigArgumentMap, -): ReadonlyArray; -/** - * @internal - */ -export function argsToArgsConfig( - args: ReadonlyArray, -): GraphQLFieldConfigArgumentMap; -export interface GraphQLObjectTypeConfig { - name: string; - description?: Maybe; - interfaces?: ThunkArray; - fields: ThunkObjMap>; - isTypeOf?: Maybe>; - extensions?: Maybe>>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -interface GraphQLObjectTypeNormalizedConfig - extends GraphQLObjectTypeConfig { - interfaces: Array; - fields: GraphQLFieldConfigMap; - extensions: Maybe>>; - extensionASTNodes: ReadonlyArray; -} -export type GraphQLTypeResolver = ( - value: TSource, - context: TContext, - info: GraphQLResolveInfo, - abstractType: GraphQLAbstractType, -) => PromiseOrValue; -export type GraphQLIsTypeOfFn = ( - source: TSource, - context: TContext, - info: GraphQLResolveInfo, -) => PromiseOrValue; -export type GraphQLFieldResolver< - TSource, - TContext, - TArgs = { - [argument: string]: any; - }, -> = ( - source: TSource, - args: TArgs, - context: TContext, - info: GraphQLResolveInfo, -) => unknown; -export interface 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; - }; -} -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - * - * We've provided these template arguments because this is an open type and - * you may find them useful. - */ -export interface GraphQLFieldExtensions< - _TSource, - _TContext, - _TArgs = { - [argName: string]: any; - }, -> { - [attributeName: string]: unknown; -} -export interface GraphQLFieldConfig< - TSource, - TContext, - TArgs = { - [argument: string]: any; - }, -> { - description?: Maybe; - type: GraphQLOutputType; - args?: GraphQLFieldConfigArgumentMap; - resolve?: GraphQLFieldResolver; - subscribe?: GraphQLFieldResolver; - deprecationReason?: Maybe; - extensions?: Maybe< - Readonly> - >; - astNode?: Maybe; -} -export type GraphQLFieldConfigArgumentMap = ObjMap; -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLArgumentExtensions { - [attributeName: string]: unknown; -} -export interface GraphQLArgumentConfig { - description?: Maybe; - type: GraphQLInputType; - defaultValue?: unknown; - deprecationReason?: Maybe; - extensions?: Maybe>; - astNode?: Maybe; -} -export type GraphQLFieldConfigMap = ObjMap< - GraphQLFieldConfig ->; -export interface GraphQLField< - TSource, - TContext, - TArgs = { - [argument: string]: any; - }, -> { - name: string; - description: Maybe; - type: GraphQLOutputType; - args: Array; - resolve?: GraphQLFieldResolver; - subscribe?: GraphQLFieldResolver; - deprecationReason: Maybe; - extensions: Maybe>>; - astNode: Maybe; -} -export interface GraphQLArgument { - name: string; - description: Maybe; - type: GraphQLInputType; - defaultValue: unknown; - deprecationReason: Maybe; - extensions: Maybe>; - astNode: Maybe; -} -export function isRequiredArgument(arg: GraphQLArgument): boolean; -export type GraphQLFieldMap = ObjMap< - GraphQLField ->; -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLInterfaceTypeExtensions { - [attributeName: string]: unknown; -} -/** - * Interface Type Definition - * - * When a field can return one of a heterogeneous set of types, a Interface type - * is used to describe what types are possible, what fields are in common across - * all types, as well as a function to determine which type is actually used - * when the field is resolved. - * - * Example: - * - * const EntityType = new GraphQLInterfaceType({ - * name: 'Entity', - * fields: { - * name: { type: GraphQLString } - * } - * }); - * - */ -export class GraphQLInterfaceType { - name: string; - description: Maybe; - resolveType: Maybe>; - extensions: Maybe>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - private _fields; - private _interfaces; - constructor(config: Readonly>); - getFields(): GraphQLFieldMap; - getInterfaces(): Array; - toConfig(): GraphQLInterfaceTypeNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export interface GraphQLInterfaceTypeConfig { - name: string; - description?: Maybe; - interfaces?: ThunkArray; - fields: ThunkObjMap>; - /** - * Optionally provide a custom type resolver function. If one is not provided, - * the default implementation will call `isTypeOf` on each implementing - * Object type. - */ - resolveType?: Maybe>; - extensions?: Maybe>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -export interface GraphQLInterfaceTypeNormalizedConfig - extends GraphQLInterfaceTypeConfig { - interfaces: Array; - fields: GraphQLFieldConfigMap; - extensions: Maybe>; - extensionASTNodes: ReadonlyArray; -} -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLUnionTypeExtensions { - [attributeName: string]: unknown; -} -/** - * Union Type Definition - * - * When a field can return one of a heterogeneous set of types, a Union type - * is used to describe what types are possible as well as providing a function - * to determine which type is actually used when the field is resolved. - * - * Example: - * - * const PetType = new GraphQLUnionType({ - * name: 'Pet', - * types: [ DogType, CatType ], - * resolveType(value) { - * if (value instanceof Dog) { - * return DogType; - * } - * if (value instanceof Cat) { - * return CatType; - * } - * } - * }); - * - */ -export class GraphQLUnionType { - name: string; - description: Maybe; - resolveType: Maybe>; - extensions: Maybe>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - private _types; - constructor(config: Readonly>); - getTypes(): Array; - toConfig(): GraphQLUnionTypeNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export interface GraphQLUnionTypeConfig { - name: string; - description?: Maybe; - types: ThunkArray; - /** - * Optionally provide a custom type resolver function. If one is not provided, - * the default implementation will call `isTypeOf` on each implementing - * Object type. - */ - resolveType?: Maybe>; - extensions?: Maybe>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -interface GraphQLUnionTypeNormalizedConfig - extends GraphQLUnionTypeConfig { - types: Array; - extensions: Maybe>; - extensionASTNodes: ReadonlyArray; -} -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLEnumTypeExtensions { - [attributeName: string]: unknown; -} -/** - * Enum Type Definition - * - * Some leaf values of requests and input values are Enums. GraphQL serializes - * Enum values as strings, however internally Enums can be represented by any - * kind of type, often integers. - * - * Example: - * - * const RGBType = new GraphQLEnumType({ - * name: 'RGB', - * values: { - * RED: { value: 0 }, - * GREEN: { value: 1 }, - * BLUE: { value: 2 } - * } - * }); - * - * 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 { - name: string; - description: Maybe; - extensions: Maybe>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - private _values; - private _valueLookup; - private _nameLookup; - constructor(config: Readonly); - getValues(): Array; - getValue(name: string): Maybe; - serialize(outputValue: unknown): Maybe; - parseValue(inputValue: unknown): Maybe; - parseLiteral( - valueNode: ValueNode, - _variables: Maybe>, - ): Maybe; - toConfig(): GraphQLEnumTypeNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export interface GraphQLEnumTypeConfig { - name: string; - description?: Maybe; - values: GraphQLEnumValueConfigMap; - extensions?: Maybe>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -interface GraphQLEnumTypeNormalizedConfig extends GraphQLEnumTypeConfig { - extensions: Maybe>; - extensionASTNodes: ReadonlyArray; -} -export type GraphQLEnumValueConfigMap = ObjMap; -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLEnumValueExtensions { - [attributeName: string]: unknown; -} -export interface GraphQLEnumValueConfig { - description?: Maybe; - value?: any; - deprecationReason?: Maybe; - extensions?: Maybe>; - astNode?: Maybe; -} -export interface GraphQLEnumValue { - name: string; - description: Maybe; - value: any; - deprecationReason: Maybe; - extensions: Maybe>; - astNode: Maybe; -} -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLInputObjectTypeExtensions { - [attributeName: string]: unknown; -} -/** - * Input Object Type Definition - * - * An input object defines a structured collection of fields which may be - * supplied to a field argument. - * - * Using `NonNull` will ensure that a value must be provided by the query - * - * Example: - * - * const GeoPoint = new GraphQLInputObjectType({ - * name: 'GeoPoint', - * fields: { - * lat: { type: new GraphQLNonNull(GraphQLFloat) }, - * lon: { type: new GraphQLNonNull(GraphQLFloat) }, - * alt: { type: GraphQLFloat, defaultValue: 0 }, - * } - * }); - * - */ -export class GraphQLInputObjectType { - name: string; - description: Maybe; - extensions: Maybe>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - private _fields; - constructor(config: Readonly); - getFields(): GraphQLInputFieldMap; - toConfig(): GraphQLInputObjectTypeNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export interface GraphQLInputObjectTypeConfig { - name: string; - description?: Maybe; - fields: ThunkObjMap; - extensions?: Maybe>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -interface GraphQLInputObjectTypeNormalizedConfig - extends GraphQLInputObjectTypeConfig { - fields: GraphQLInputFieldConfigMap; - extensions: Maybe>; - extensionASTNodes: ReadonlyArray; -} -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLInputFieldExtensions { - [attributeName: string]: unknown; -} -export interface GraphQLInputFieldConfig { - description?: Maybe; - type: GraphQLInputType; - defaultValue?: unknown; - deprecationReason?: Maybe; - extensions?: Maybe>; - astNode?: Maybe; -} -export type GraphQLInputFieldConfigMap = ObjMap; -export interface GraphQLInputField { - name: string; - description: Maybe; - type: GraphQLInputType; - defaultValue: unknown; - deprecationReason: Maybe; - extensions: Maybe>; - astNode: Maybe; -} -export function isRequiredInputField(field: GraphQLInputField): boolean; -export type GraphQLInputFieldMap = ObjMap; diff --git a/src/type/definition.js b/src/type/definition.ts similarity index 61% rename from src/type/definition.js rename to src/type/definition.ts index 82387ac459..3d38a43d5a 100644 --- a/src/type/definition.js +++ b/src/type/definition.ts @@ -1,10 +1,6 @@ import type { Path } from '../jsutils/Path'; import type { PromiseOrValue } from '../jsutils/PromiseOrValue'; -import type { - ObjMap, - ReadOnlyObjMap, - ReadOnlyObjMapLike, -} from '../jsutils/ObjMap'; +import type { ObjMap } from '../jsutils/ObjMap'; import { inspect } from '../jsutils/inspect'; import { keyMap } from '../jsutils/keyMap'; import { mapValue } from '../jsutils/mapValue'; @@ -16,6 +12,7 @@ import { didYouMean } from '../jsutils/didYouMean'; import { isObjectLike } from '../jsutils/isObjectLike'; import { identityFunc } from '../jsutils/identityFunc'; import { suggestionList } from '../jsutils/suggestionList'; +import type { Maybe } from '../jsutils/Maybe'; import { GraphQLError } from '../error/GraphQLError'; @@ -59,10 +56,18 @@ export type GraphQLType = | GraphQLUnionType | GraphQLEnumType | GraphQLInputObjectType - | GraphQLList - | GraphQLNonNull; + | GraphQLList + | GraphQLNonNull< + | GraphQLScalarType + | GraphQLObjectType + | GraphQLInterfaceType + | GraphQLUnionType + | GraphQLEnumType + | GraphQLInputObjectType + | GraphQLList + >; -export function isType(type: mixed): boolean %checks { +export function isType(type: unknown): type is GraphQLType { return ( isScalarType(type) || isObjectType(type) || @@ -75,7 +80,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.`); } @@ -85,43 +90,33 @@ 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); -// eslint-disable-next-line no-redeclare -export function isScalarType(type) { +export function isScalarType(type: unknown): type is GraphQLScalarType { 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); -// eslint-disable-next-line no-redeclare -export function isObjectType(type) { +export function isObjectType(type: unknown): type is GraphQLObjectType { 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); -// eslint-disable-next-line no-redeclare -export function isInterfaceType(type) { +export function isInterfaceType(type: unknown): type is GraphQLInterfaceType { 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.`, @@ -130,42 +125,35 @@ export function assertInterfaceType(type: mixed): GraphQLInterfaceType { return type; } -declare function isUnionType(type: mixed): boolean %checks(type instanceof - GraphQLUnionType); -// eslint-disable-next-line no-redeclare -export function isUnionType(type) { +export function isUnionType(type: unknown): type is GraphQLUnionType { 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); -// eslint-disable-next-line no-redeclare -export function isEnumType(type) { +export function isEnumType(type: unknown): type is GraphQLEnumType { 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); -// eslint-disable-next-line no-redeclare -export function isInputObjectType(type) { +export function isInputObjectType( + type: unknown, +): type is GraphQLInputObjectType { 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.`, @@ -174,28 +162,40 @@ export function assertInputObjectType(type: mixed): GraphQLInputObjectType { return type; } -declare function isListType(type: mixed): boolean %checks(type instanceof - GraphQLList); -// eslint-disable-next-line no-redeclare -export function isListType(type) { +export function isListType( + type: GraphQLInputType, +): type is GraphQLList; +export function isListType( + type: GraphQLOutputType, +): type is GraphQLList; +export function isListType(type: unknown): type is GraphQLList; +export function isListType(type: unknown): type is GraphQLList { 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); -// eslint-disable-next-line no-redeclare -export function isNonNullType(type) { +export function isNonNullType( + type: GraphQLInputType, +): type is GraphQLNonNull; +export function isNonNullType( + type: GraphQLOutputType, +): type is GraphQLNonNull; +export function isNonNullType( + type: unknown, +): type is GraphQLNonNull; +export function isNonNullType( + type: unknown, +): type is GraphQLNonNull { 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.`); } @@ -214,10 +214,10 @@ export type GraphQLInputType = | GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType - | GraphQLList, + | GraphQLList >; -export function isInputType(type: mixed): boolean %checks { +export function isInputType(type: unknown): type is GraphQLInputType { return ( isScalarType(type) || isEnumType(type) || @@ -226,7 +226,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.`); } @@ -249,10 +249,10 @@ export type GraphQLOutputType = | GraphQLInterfaceType | GraphQLUnionType | GraphQLEnumType - | GraphQLList, + | GraphQLList >; -export function isOutputType(type: mixed): boolean %checks { +export function isOutputType(type: unknown): type is GraphQLOutputType { return ( isScalarType(type) || isObjectType(type) || @@ -263,7 +263,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.`); } @@ -275,11 +275,11 @@ export function assertOutputType(type: mixed): GraphQLOutputType { */ export type GraphQLLeafType = GraphQLScalarType | GraphQLEnumType; -export function isLeafType(type: mixed): boolean %checks { +export function isLeafType(type: unknown): type is GraphQLLeafType { 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.`); } @@ -294,11 +294,11 @@ export type GraphQLCompositeType = | GraphQLInterfaceType | GraphQLUnionType; -export function isCompositeType(type: mixed): boolean %checks { +export function isCompositeType(type: unknown): type is GraphQLCompositeType { 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.`, @@ -312,11 +312,11 @@ export function assertCompositeType(type: mixed): GraphQLCompositeType { */ export type GraphQLAbstractType = GraphQLInterfaceType | GraphQLUnionType; -export function isAbstractType(type: mixed): boolean %checks { +export function isAbstractType(type: unknown): type is GraphQLAbstractType { 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.`); } @@ -341,8 +341,8 @@ export function assertAbstractType(type: mixed): GraphQLAbstractType { * }) * */ -export class GraphQLList<+T: GraphQLType> { - +ofType: T; +export class GraphQLList { + readonly ofType: T; constructor(ofType: T) { devAssert( @@ -361,7 +361,6 @@ export class GraphQLList<+T: GraphQLType> { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLList'; } @@ -387,8 +386,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( @@ -407,7 +406,6 @@ export class GraphQLNonNull<+T: GraphQLNullableType> { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLNonNull'; } @@ -417,13 +415,15 @@ export class GraphQLNonNull<+T: GraphQLNullableType> { * These types wrap and modify other types */ -export type GraphQLWrappingType = GraphQLList | GraphQLNonNull; +export type GraphQLWrappingType = + | GraphQLList + | GraphQLNonNull; -export function isWrappingType(type: mixed): boolean %checks { +export function isWrappingType(type: unknown): type is GraphQLWrappingType { 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.`); } @@ -440,25 +440,26 @@ export type GraphQLNullableType = | GraphQLUnionType | GraphQLEnumType | GraphQLInputObjectType - | GraphQLList; + | GraphQLList; -export function isNullableType(type: mixed): boolean %checks { +export function isNullableType(type: unknown): type is GraphQLNullableType { 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.`); } return type; } -/* eslint-disable no-redeclare */ -declare function getNullableType(type: void | null): void; -declare function getNullableType(type: T): T; -declare function getNullableType(type: GraphQLNonNull): T; -export function getNullableType(type) { - /* eslint-enable no-redeclare */ +export function getNullableType(type: undefined | null): void; +export function getNullableType( + type: T | GraphQLNonNull, +): T; +export function getNullableType( + type: Maybe, +): GraphQLNullableType | undefined { if (type) { return isNonNullType(type) ? type.ofType : type; } @@ -481,7 +482,7 @@ export type GraphQLNamedOutputType = | GraphQLUnionType | GraphQLEnumType; -export function isNamedType(type: mixed): boolean %checks { +export function isNamedType(type: unknown): type is GraphQLNamedType { return ( isScalarType(type) || isObjectType(type) || @@ -492,20 +493,20 @@ 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.`); } return type; } -/* eslint-disable no-redeclare */ -declare function getNamedType(type: void | null): void; -declare function getNamedType(type: GraphQLInputType): GraphQLNamedInputType; -declare function getNamedType(type: GraphQLOutputType): GraphQLNamedOutputType; -declare function getNamedType(type: GraphQLType): GraphQLNamedType; -export function getNamedType(type) { - /* eslint-enable no-redeclare */ +export function getNamedType(type: undefined | null): void; +export function getNamedType(type: GraphQLInputType): GraphQLNamedInputType; +export function getNamedType(type: GraphQLOutputType): GraphQLNamedOutputType; +export function getNamedType(type: GraphQLType): GraphQLNamedType; +export function getNamedType( + type: Maybe, +): GraphQLNamedType | undefined { if (type) { let unwrappedType = type; while (isWrappingType(unwrappedType)) { @@ -530,6 +531,19 @@ function resolveObjMapThunk(thunk: ThunkObjMap): ObjMap { return typeof thunk === 'function' ? thunk() : thunk; } +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLScalarTypeExtensions { + [attributeName: string]: unknown; +} + /** * Scalar Type Definition * @@ -556,16 +570,16 @@ function resolveObjMapThunk(thunk: ThunkObjMap): ObjMap { */ export class GraphQLScalarType { name: string; - description: ?string; - specifiedByURL: ?string; - serialize: GraphQLScalarSerializer; - parseValue: GraphQLScalarValueParser; - parseLiteral: GraphQLScalarLiteralParser; - extensions: ?ReadOnlyObjMap; - astNode: ?ScalarTypeDefinitionNode; - extensionASTNodes: $ReadOnlyArray; - - constructor(config: $ReadOnly>) { + description: Maybe; + specifiedByURL: Maybe; + serialize: GraphQLScalarSerializer; + parseValue: GraphQLScalarValueParser; + parseLiteral: GraphQLScalarLiteralParser; + extensions: Maybe>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; + + constructor(config: Readonly>) { const parseValue = config.parseValue ?? identityFunc; this.name = config.name; this.description = config.description; @@ -624,48 +638,63 @@ export class GraphQLScalarType { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLScalarType'; } } export type GraphQLScalarSerializer = ( - outputValue: mixed, -) => ?TExternal; + outputValue: unknown, +) => Maybe; export type GraphQLScalarValueParser = ( - inputValue: mixed, -) => ?TInternal; + inputValue: unknown, +) => Maybe; export type GraphQLScalarLiteralParser = ( valueNode: ValueNode, - variables: ?ObjMap, -) => ?TInternal; + variables: Maybe>, +) => Maybe; -export type GraphQLScalarTypeConfig = { - name: string, - description?: ?string, - specifiedByURL?: ?string, +export interface GraphQLScalarTypeConfig { + name: string; + description?: Maybe; + specifiedByURL?: Maybe; /** 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, -}; - -type GraphQLScalarTypeNormalizedConfig = { - ...GraphQLScalarTypeConfig, - serialize: GraphQLScalarSerializer, - parseValue: GraphQLScalarValueParser, - parseLiteral: GraphQLScalarLiteralParser, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, -}; + parseLiteral?: GraphQLScalarLiteralParser; + extensions?: Maybe>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} + +interface GraphQLScalarTypeNormalizedConfig + extends GraphQLScalarTypeConfig { + serialize: GraphQLScalarSerializer; + parseValue: GraphQLScalarValueParser; + parseLiteral: GraphQLScalarLiteralParser; + extensions: Maybe>; + extensionASTNodes: ReadonlyArray; +} + +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + * + * We've provided these template arguments because this is an open type and + * you may find them useful. + */ +export interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> { + [attributeName: string]: unknown; +} /** * Object Type Definition @@ -704,18 +733,18 @@ type GraphQLScalarTypeNormalizedConfig = { * }); * */ -export class GraphQLObjectType { +export class GraphQLObjectType { name: string; - description: ?string; - isTypeOf: ?GraphQLIsTypeOfFn; - extensions: ?ReadOnlyObjMap; - astNode: ?ObjectTypeDefinitionNode; - extensionASTNodes: $ReadOnlyArray; + description: Maybe; + isTypeOf: Maybe>; + extensions: Maybe>>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; - _fields: ThunkObjMap>; - _interfaces: ThunkArray; + private _fields: ThunkObjMap>; + private _interfaces: ThunkArray; - constructor(config: $ReadOnly>) { + constructor(config: Readonly>) { this.name = config.name; this.description = config.description; this.isTypeOf = config.isTypeOf; @@ -733,7 +762,7 @@ export class GraphQLObjectType { ); } - getFields(): GraphQLFieldMap { + getFields(): GraphQLFieldMap { if (typeof this._fields === 'function') { this._fields = this._fields(); } @@ -747,7 +776,7 @@ export class GraphQLObjectType { return this._interfaces; } - toConfig(): GraphQLObjectTypeNormalizedConfig { + toConfig(): GraphQLObjectTypeNormalizedConfig { return { name: this.name, description: this.description, @@ -768,16 +797,15 @@ export class GraphQLObjectType { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLObjectType'; } } function defineInterfaces( - config: $ReadOnly< - | GraphQLObjectTypeConfig - | GraphQLInterfaceTypeConfig, + config: Readonly< + | GraphQLObjectTypeConfig + | GraphQLInterfaceTypeConfig >, ): Array { const interfaces = resolveArrayThunk(config.interfaces ?? []); @@ -789,9 +817,9 @@ function defineInterfaces( } function defineFieldMap( - config: $ReadOnly< + config: Readonly< | GraphQLObjectTypeConfig - | GraphQLInterfaceTypeConfig, + | GraphQLInterfaceTypeConfig >, ): GraphQLFieldMap { const fieldMap = resolveObjMapThunk(config.fields); @@ -800,6 +828,7 @@ function defineFieldMap( `${config.name} fields must be an object with field names as keys or a function which returns such an object.`, ); + // @ts-expect-error FIXME: TS Conversion return mapValue(fieldMap, (fieldConfig, fieldName) => { devAssert( isPlainObj(fieldConfig), @@ -833,7 +862,7 @@ function defineFieldMap( export function defineArguments( config: GraphQLFieldConfigArgumentMap, -): $ReadOnlyArray { +): ReadonlyArray { return Object.entries(config).map(([argName, argConfig]) => ({ name: argName, description: argConfig.description, @@ -845,13 +874,13 @@ export function defineArguments( })); } -function isPlainObj(obj: mixed): boolean { +function isPlainObj(obj: unknown): boolean { return isObjectLike(obj) && !Array.isArray(obj); } -function fieldsToFieldsConfig( - fields: GraphQLFieldMap, -): GraphQLFieldConfigMap { +function fieldsToFieldsConfig( + fields: GraphQLFieldMap, +): GraphQLFieldConfigMap { return mapValue(fields, (field) => ({ description: field.description, type: field.type, @@ -868,7 +897,7 @@ function fieldsToFieldsConfig( * @internal */ export function argsToArgsConfig( - args: $ReadOnlyArray, + args: ReadonlyArray, ): GraphQLFieldConfigArgumentMap { return keyValMap( args, @@ -884,31 +913,31 @@ export function argsToArgsConfig( ); } -export type GraphQLObjectTypeConfig = { - name: string, - description?: ?string, - interfaces?: ThunkArray, - fields: ThunkObjMap>, - isTypeOf?: ?GraphQLIsTypeOfFn, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?ObjectTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -}; - -type GraphQLObjectTypeNormalizedConfig = { - ...GraphQLObjectTypeConfig, - interfaces: Array, - fields: GraphQLFieldConfigMap, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, -}; +export interface GraphQLObjectTypeConfig { + name: string; + description?: Maybe; + interfaces?: ThunkArray; + fields: ThunkObjMap>; + isTypeOf?: Maybe>; + extensions?: Maybe>>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} + +interface GraphQLObjectTypeNormalizedConfig + extends GraphQLObjectTypeConfig { + interfaces: Array; + fields: GraphQLFieldConfigMap; + extensions: Maybe>>; + extensionASTNodes: ReadonlyArray; +} export type GraphQLTypeResolver = ( value: TSource, context: TContext, info: GraphQLResolveInfo, abstractType: GraphQLAbstractType, -) => PromiseOrValue; +) => PromiseOrValue; export type GraphQLIsTypeOfFn = ( source: TSource, @@ -919,91 +948,139 @@ 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, ... }, -}; - -export type GraphQLFieldConfig< +) => unknown; + +export interface 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 }; +} + +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + * + * We've provided these template arguments because this is an open type and + * you may find them useful. + */ +export interface GraphQLFieldExtensions< + _TSource, + _TContext, + _TArgs = { [argName: string]: any }, +> { + [attributeName: string]: unknown; +} + +export interface 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?: Maybe; + type: GraphQLOutputType; + args?: GraphQLFieldConfigArgumentMap; + resolve?: GraphQLFieldResolver; + subscribe?: GraphQLFieldResolver; + deprecationReason?: Maybe; + extensions?: Maybe< + Readonly> + >; + astNode?: Maybe; +} export type GraphQLFieldConfigArgumentMap = ObjMap; -export type GraphQLArgumentConfig = { - description?: ?string, - type: GraphQLInputType, - defaultValue?: mixed, - extensions?: ?ReadOnlyObjMapLike, - deprecationReason?: ?string, - astNode?: ?InputValueDefinitionNode, -}; +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLArgumentExtensions { + [attributeName: string]: unknown; +} + +export interface GraphQLArgumentConfig { + description?: Maybe; + type: GraphQLInputType; + defaultValue?: unknown; + deprecationReason?: Maybe; + extensions?: Maybe>; + astNode?: Maybe; +} export type GraphQLFieldConfigMap = ObjMap< - GraphQLFieldConfig, + GraphQLFieldConfig >; -export type GraphQLField< +export interface 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, -}; + TArgs = { [argument: string]: any }, +> { + name: string; + description: Maybe; + type: GraphQLOutputType; + args: Array; + resolve?: GraphQLFieldResolver; + subscribe?: GraphQLFieldResolver; + deprecationReason: Maybe; + extensions: Maybe>>; + astNode: Maybe; +} + +export interface GraphQLArgument { + name: string; + description: Maybe; + type: GraphQLInputType; + defaultValue: unknown; + deprecationReason: Maybe; + extensions: Maybe>; + astNode: Maybe; +} export function isRequiredArgument(arg: GraphQLArgument): boolean { return isNonNullType(arg.type) && arg.defaultValue === undefined; } export type GraphQLFieldMap = ObjMap< - GraphQLField, + GraphQLField >; +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLInterfaceTypeExtensions { + [attributeName: string]: unknown; +} + /** * Interface Type Definition * @@ -1024,16 +1101,16 @@ export type GraphQLFieldMap = ObjMap< */ export class GraphQLInterfaceType { name: string; - description: ?string; - resolveType: ?GraphQLTypeResolver; - extensions: ?ReadOnlyObjMap; - astNode: ?InterfaceTypeDefinitionNode; - extensionASTNodes: $ReadOnlyArray; + description: Maybe; + resolveType: Maybe>; + extensions: Maybe>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; - _fields: ThunkObjMap>; - _interfaces: ThunkArray; + private _fields: ThunkObjMap>; + private _interfaces: ThunkArray; - constructor(config: $ReadOnly>) { + constructor(config: Readonly>) { this.name = config.name; this.description = config.description; this.resolveType = config.resolveType; @@ -1086,35 +1163,47 @@ export class GraphQLInterfaceType { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLInterfaceType'; } } -export type GraphQLInterfaceTypeConfig = { - name: string, - description?: ?string, - interfaces?: ThunkArray, - fields: ThunkObjMap>, +export interface GraphQLInterfaceTypeConfig { + name: string; + description?: Maybe; + interfaces?: ThunkArray; + fields: ThunkObjMap>; /** * 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, -}; - -export type GraphQLInterfaceTypeNormalizedConfig = { - ...GraphQLInterfaceTypeConfig, - interfaces: Array, - fields: GraphQLFieldConfigMap, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, -}; + resolveType?: Maybe>; + extensions?: Maybe>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} + +export interface GraphQLInterfaceTypeNormalizedConfig + extends GraphQLInterfaceTypeConfig { + interfaces: Array; + fields: GraphQLFieldConfigMap; + extensions: Maybe>; + extensionASTNodes: ReadonlyArray; +} + +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLUnionTypeExtensions { + [attributeName: string]: unknown; +} /** * Union Type Definition @@ -1141,15 +1230,15 @@ export type GraphQLInterfaceTypeNormalizedConfig = { */ export class GraphQLUnionType { name: string; - description: ?string; - resolveType: ?GraphQLTypeResolver; - extensions: ?ReadOnlyObjMap; - astNode: ?UnionTypeDefinitionNode; - extensionASTNodes: $ReadOnlyArray; + description: Maybe; + resolveType: Maybe>; + extensions: Maybe>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; - _types: ThunkArray; + private _types: ThunkArray; - constructor(config: $ReadOnly>) { + constructor(config: Readonly>) { this.name = config.name; this.description = config.description; this.resolveType = config.resolveType; @@ -1193,14 +1282,13 @@ export class GraphQLUnionType { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLUnionType'; } } function defineTypes( - config: $ReadOnly>, + config: Readonly>, ): Array { const types = resolveArrayThunk(config.types); devAssert( @@ -1210,27 +1298,40 @@ function defineTypes( return types; } -export type GraphQLUnionTypeConfig = { - name: string, - description?: ?string, - types: ThunkArray, +export interface GraphQLUnionTypeConfig { + name: string; + description?: Maybe; + types: ThunkArray; /** * 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, -}; - -type GraphQLUnionTypeNormalizedConfig = { - ...GraphQLUnionTypeConfig, - types: Array, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, -}; + resolveType?: Maybe>; + extensions?: Maybe>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} + +interface GraphQLUnionTypeNormalizedConfig + extends GraphQLUnionTypeConfig { + types: Array; + extensions: Maybe>; + extensionASTNodes: ReadonlyArray; +} + +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLEnumTypeExtensions { + [attributeName: string]: unknown; +} /** * Enum Type Definition @@ -1255,16 +1356,16 @@ type GraphQLUnionTypeNormalizedConfig = { */ export class GraphQLEnumType /* */ { name: string; - description: ?string; - extensions: ?ReadOnlyObjMap; - astNode: ?EnumTypeDefinitionNode; - extensionASTNodes: $ReadOnlyArray; + description: Maybe; + extensions: Maybe>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; - _values: Array */>; - _valueLookup: Map; - _nameLookup: ObjMap; + private _values: Array */>; + private _valueLookup: Map; + private _nameLookup: ObjMap; - constructor(config: $ReadOnly */>) { + constructor(config: Readonly */>) { this.name = config.name; this.description = config.description; this.extensions = config.extensions && toObjMap(config.extensions); @@ -1284,11 +1385,11 @@ export class GraphQLEnumType /* */ { return this._values; } - getValue(name: string): ?GraphQLEnumValue { + getValue(name: string): Maybe { return this._nameLookup[name]; } - serialize(outputValue: mixed /* T */): ?string { + serialize(outputValue: unknown /* T */): Maybe { const enumValue = this._valueLookup.get(outputValue); if (enumValue === undefined) { throw new GraphQLError( @@ -1298,7 +1399,7 @@ export class GraphQLEnumType /* */ { return enumValue.name; } - parseValue(inputValue: mixed): ?any /* T */ { + parseValue(inputValue: unknown): Maybe /* T */ { if (typeof inputValue !== 'string') { const valueStr = inspect(inputValue); throw new GraphQLError( @@ -1317,7 +1418,10 @@ export class GraphQLEnumType /* */ { return enumValue.value; } - parseLiteral(valueNode: ValueNode, _variables: ?ObjMap): ?any /* T */ { + parseLiteral( + valueNode: ValueNode, + _variables: Maybe>, + ): Maybe /* T */ { // Note: variables will be resolved to a value before calling this function. if (valueNode.kind !== Kind.ENUM) { const valueStr = print(valueNode); @@ -1371,7 +1475,6 @@ export class GraphQLEnumType /* */ { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLEnumType'; } @@ -1412,40 +1515,65 @@ function defineEnumValues( }); } -export type GraphQLEnumTypeConfig /* */ = { - name: string, - description?: ?string, - values: GraphQLEnumValueConfigMap /* */, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?EnumTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -}; +export interface GraphQLEnumTypeConfig { + name: string; + description?: Maybe; + values: GraphQLEnumValueConfigMap /* */; + extensions?: Maybe>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} -type GraphQLEnumTypeNormalizedConfig = { - ...GraphQLEnumTypeConfig, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, -}; +interface GraphQLEnumTypeNormalizedConfig extends GraphQLEnumTypeConfig { + extensions: Maybe>; + 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, -}; +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLEnumValueExtensions { + [attributeName: string]: unknown; +} + +export interface GraphQLEnumValueConfig { + description?: Maybe; + value?: any /* T */; + deprecationReason?: Maybe; + extensions?: Maybe>; + astNode?: Maybe; +} + +export interface GraphQLEnumValue { + name: string; + description: Maybe; + value: any /* T */; + deprecationReason: Maybe; + extensions: Maybe>; + astNode: Maybe; +} + +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLInputObjectTypeExtensions { + [attributeName: string]: unknown; +} /** * Input Object Type Definition @@ -1469,14 +1597,14 @@ export type GraphQLEnumValue /* */ = { */ export class GraphQLInputObjectType { name: string; - description: ?string; - extensions: ?ReadOnlyObjMap; - astNode: ?InputObjectTypeDefinitionNode; - extensionASTNodes: $ReadOnlyArray; + description: Maybe; + extensions: Maybe>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; - _fields: ThunkObjMap; + private _fields: ThunkObjMap; - constructor(config: $ReadOnly) { + constructor(config: Readonly) { this.name = config.name; this.description = config.description; this.extensions = config.extensions && toObjMap(config.extensions); @@ -1521,14 +1649,13 @@ export class GraphQLInputObjectType { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLInputObjectType'; } } function defineInputFieldMap( - config: $ReadOnly, + config: Readonly, ): GraphQLInputFieldMap { const fieldMap = resolveObjMapThunk(config.fields); devAssert( @@ -1553,42 +1680,55 @@ function defineInputFieldMap( }); } -export type GraphQLInputObjectTypeConfig = { - name: string, - description?: ?string, - fields: ThunkObjMap, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?InputObjectTypeDefinitionNode, - extensionASTNodes?: ?$ReadOnlyArray, -}; - -type GraphQLInputObjectTypeNormalizedConfig = { - ...GraphQLInputObjectTypeConfig, - fields: GraphQLInputFieldConfigMap, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, -}; - -export type GraphQLInputFieldConfig = { - description?: ?string, - type: GraphQLInputType, - defaultValue?: mixed, - deprecationReason?: ?string, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?InputValueDefinitionNode, -}; +export interface GraphQLInputObjectTypeConfig { + name: string; + description?: Maybe; + fields: ThunkObjMap; + extensions?: Maybe>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} + +interface GraphQLInputObjectTypeNormalizedConfig + extends GraphQLInputObjectTypeConfig { + fields: GraphQLInputFieldConfigMap; + extensions: Maybe>; + extensionASTNodes: ReadonlyArray; +} + +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLInputFieldExtensions { + [attributeName: string]: unknown; +} + +export interface GraphQLInputFieldConfig { + description?: Maybe; + type: GraphQLInputType; + defaultValue?: unknown; + deprecationReason?: Maybe; + extensions?: Maybe>; + astNode?: Maybe; +} export type GraphQLInputFieldConfigMap = ObjMap; -export type GraphQLInputField = { - name: string, - description: ?string, - type: GraphQLInputType, - defaultValue: mixed, - deprecationReason: ?string, - extensions: ?ReadOnlyObjMap, - astNode: ?InputValueDefinitionNode, -}; +export interface GraphQLInputField { + name: string; + description: Maybe; + type: GraphQLInputType; + defaultValue: unknown; + deprecationReason: Maybe; + extensions: Maybe>; + astNode: Maybe; +} export function isRequiredInputField(field: GraphQLInputField): boolean { return isNonNullType(field.type) && field.defaultValue === undefined; diff --git a/src/type/directives.d.ts b/src/type/directives.d.ts deleted file mode 100644 index 576da63fbc..0000000000 --- a/src/type/directives.d.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { DirectiveDefinitionNode } from '../language/ast'; -import type { DirectiveLocationEnum } from '../language/directiveLocation'; -import type { - GraphQLArgument, - GraphQLFieldConfigArgumentMap, -} from './definition'; -/** - * Test if the given value is a GraphQL directive. - */ -export function isDirective(directive: unknown): directive is GraphQLDirective; -export function assertDirective(directive: unknown): GraphQLDirective; -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLDirectiveExtensions { - [attributeName: string]: unknown; -} -/** - * Directives are used by the GraphQL runtime as a way of modifying execution - * behavior. Type system creators will usually not create these directly. - */ -export class GraphQLDirective { - name: string; - description: Maybe; - locations: Array; - args: ReadonlyArray; - isRepeatable: boolean; - extensions: Maybe>; - astNode: Maybe; - constructor(config: Readonly); - toConfig(): GraphQLDirectiveNormalizedConfig; - toString(): string; - toJSON(): string; - get [Symbol.toStringTag](): string; -} -export interface GraphQLDirectiveConfig { - name: string; - description?: Maybe; - locations: Array; - args?: Maybe; - isRepeatable?: Maybe; - extensions?: Maybe>; - astNode?: Maybe; -} -interface GraphQLDirectiveNormalizedConfig extends GraphQLDirectiveConfig { - args: GraphQLFieldConfigArgumentMap; - isRepeatable: boolean; - extensions: Maybe>; -} -/** - * Used to conditionally include fields or fragments. - */ -export const GraphQLIncludeDirective: GraphQLDirective; -/** - * Used to conditionally skip (exclude) fields or fragments. - */ -export const GraphQLSkipDirective: GraphQLDirective; -/** - * Constant string used for default reason for a deprecation. - */ -export const DEFAULT_DEPRECATION_REASON = 'No longer supported'; -/** - * Used to declare element of a GraphQL schema as deprecated. - */ -export const GraphQLDeprecatedDirective: GraphQLDirective; -/** - * Used to provide a URL for specifying the behaviour of custom scalar definitions. - */ -export const GraphQLSpecifiedByDirective: GraphQLDirective; -/** - * The full list of specified directives. - */ -export const specifiedDirectives: ReadonlyArray; -export function isSpecifiedDirective(directive: GraphQLDirective): boolean; diff --git a/src/type/directives.js b/src/type/directives.ts similarity index 78% rename from src/type/directives.js rename to src/type/directives.ts index 2af25d9fc0..3dff8298bb 100644 --- a/src/type/directives.js +++ b/src/type/directives.ts @@ -1,9 +1,9 @@ -import type { 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 { Maybe } from '../jsutils/Maybe'; import type { DirectiveDefinitionNode } from '../language/ast'; import type { DirectiveLocationEnum } from '../language/directiveLocation'; @@ -23,15 +23,11 @@ import { /** * Test if the given value is a GraphQL directive. */ -declare function isDirective( - directive: mixed, -): boolean %checks(directive instanceof GraphQLDirective); -// eslint-disable-next-line no-redeclare -export function isDirective(directive) { +export function isDirective(directive: unknown): directive is GraphQLDirective { 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.`, @@ -40,20 +36,33 @@ export function assertDirective(directive: mixed): GraphQLDirective { return directive; } +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLDirectiveExtensions { + [attributeName: string]: unknown; +} + /** * Directives are used by the GraphQL runtime as a way of modifying execution * behavior. Type system creators will usually not create these directly. */ export class GraphQLDirective { name: string; - description: ?string; + description: Maybe; locations: Array; - args: $ReadOnlyArray; + args: ReadonlyArray; isRepeatable: boolean; - extensions: ?ReadOnlyObjMap; - astNode: ?DirectiveDefinitionNode; + extensions: Maybe>; + astNode: Maybe; - constructor(config: $ReadOnly) { + constructor(config: Readonly) { this.name = config.name; this.description = config.description; this.locations = config.locations; @@ -96,28 +105,26 @@ export class GraphQLDirective { return this.toString(); } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLDirective'; } } -export type GraphQLDirectiveConfig = { - name: string, - description?: ?string, - locations: Array, - args?: ?GraphQLFieldConfigArgumentMap, - isRepeatable?: ?boolean, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?DirectiveDefinitionNode, -}; - -type GraphQLDirectiveNormalizedConfig = { - ...GraphQLDirectiveConfig, - args: GraphQLFieldConfigArgumentMap, - isRepeatable: boolean, - extensions: ?ReadOnlyObjMap, -}; +export interface GraphQLDirectiveConfig { + name: string; + description?: Maybe; + locations: Array; + args?: Maybe; + isRepeatable?: Maybe; + extensions?: Maybe>; + astNode?: Maybe; +} + +interface GraphQLDirectiveNormalizedConfig extends GraphQLDirectiveConfig { + args: GraphQLFieldConfigArgumentMap; + isRepeatable: boolean; + extensions: Maybe>; +} /** * Used to conditionally include fields or fragments. @@ -206,7 +213,7 @@ export const GraphQLSpecifiedByDirective: GraphQLDirective = /** * The full list of specified directives. */ -export const specifiedDirectives: $ReadOnlyArray = +export const specifiedDirectives: ReadonlyArray = Object.freeze([ GraphQLIncludeDirective, GraphQLSkipDirective, diff --git a/src/type/index.js b/src/type/index.js deleted file mode 100644 index 0befc307c0..0000000000 --- a/src/type/index.js +++ /dev/null @@ -1,168 +0,0 @@ -export type { Path as ResponsePath } from '../jsutils/Path'; - -export { - /** Predicate */ - isSchema, - /** Assertion */ - assertSchema, - /** GraphQL Schema definition */ - GraphQLSchema, -} from './schema'; -export type { GraphQLSchemaConfig } from './schema'; - -export { - /** Predicates */ - isType, - isScalarType, - isObjectType, - isInterfaceType, - isUnionType, - isEnumType, - isInputObjectType, - isListType, - isNonNullType, - isInputType, - isOutputType, - isLeafType, - isCompositeType, - isAbstractType, - isWrappingType, - isNullableType, - isNamedType, - isRequiredArgument, - isRequiredInputField, - /** Assertions */ - assertType, - assertScalarType, - assertObjectType, - assertInterfaceType, - assertUnionType, - assertEnumType, - assertInputObjectType, - assertListType, - assertNonNullType, - assertInputType, - assertOutputType, - assertLeafType, - assertCompositeType, - assertAbstractType, - assertWrappingType, - assertNullableType, - assertNamedType, - /** Un-modifiers */ - getNullableType, - getNamedType, - /** Definitions */ - GraphQLScalarType, - GraphQLObjectType, - GraphQLInterfaceType, - GraphQLUnionType, - GraphQLEnumType, - GraphQLInputObjectType, - /** Type Wrappers */ - GraphQLList, - GraphQLNonNull, -} from './definition'; - -export type { - GraphQLType, - GraphQLInputType, - GraphQLOutputType, - GraphQLLeafType, - GraphQLCompositeType, - GraphQLAbstractType, - GraphQLWrappingType, - GraphQLNullableType, - GraphQLNamedType, - GraphQLNamedInputType, - GraphQLNamedOutputType, - ThunkArray, - ThunkObjMap, - GraphQLArgument, - GraphQLArgumentConfig, - GraphQLEnumTypeConfig, - GraphQLEnumValue, - GraphQLEnumValueConfig, - GraphQLEnumValueConfigMap, - GraphQLField, - GraphQLFieldConfig, - GraphQLFieldConfigArgumentMap, - GraphQLFieldConfigMap, - GraphQLFieldMap, - GraphQLFieldResolver, - GraphQLInputField, - GraphQLInputFieldConfig, - GraphQLInputFieldConfigMap, - GraphQLInputFieldMap, - GraphQLInputObjectTypeConfig, - GraphQLInterfaceTypeConfig, - GraphQLIsTypeOfFn, - GraphQLObjectTypeConfig, - GraphQLResolveInfo, - GraphQLScalarTypeConfig, - GraphQLTypeResolver, - GraphQLUnionTypeConfig, - GraphQLScalarSerializer, - GraphQLScalarValueParser, - GraphQLScalarLiteralParser, -} from './definition'; - -export { - /** Predicate */ - isDirective, - /** Assertion */ - assertDirective, - /** Directives Definition */ - GraphQLDirective, - /** Built-in Directives defined by the Spec */ - isSpecifiedDirective, - specifiedDirectives, - GraphQLIncludeDirective, - GraphQLSkipDirective, - GraphQLDeprecatedDirective, - GraphQLSpecifiedByDirective, - /** Constant Deprecation Reason */ - DEFAULT_DEPRECATION_REASON, -} from './directives'; - -export type { GraphQLDirectiveConfig } from './directives'; - -/** Common built-in scalar instances. */ -export { - /** Predicate */ - isSpecifiedScalarType, - /** Standard GraphQL Scalars */ - specifiedScalarTypes, - GraphQLInt, - GraphQLFloat, - GraphQLString, - GraphQLBoolean, - GraphQLID, -} from './scalars'; - -export { - /** Predicate */ - isIntrospectionType, - /** GraphQL Types for introspection. */ - introspectionTypes, - __Schema, - __Directive, - __DirectiveLocation, - __Type, - __Field, - __InputValue, - __EnumValue, - __TypeKind, - /** Meta-field definitions. */ - SchemaMetaFieldDef, - TypeMetaFieldDef, - TypeNameMetaFieldDef, -} from './introspection'; - -export type { - /** "Enum" of Type Kinds */ - TypeKind, -} from './introspection'; - -/** Validate GraphQL schema. */ -export { validateSchema, assertValidSchema } from './validate'; diff --git a/src/type/index.d.ts b/src/type/index.ts similarity index 99% rename from src/type/index.d.ts rename to src/type/index.ts index bc104e6872..fab8bb65dc 100644 --- a/src/type/index.d.ts +++ b/src/type/index.ts @@ -1,4 +1,5 @@ export type { Path as ResponsePath } from '../jsutils/Path'; + export { /** Predicate */ isSchema, @@ -8,6 +9,7 @@ export { GraphQLSchema, } from './schema'; export type { GraphQLSchemaConfig, GraphQLSchemaExtensions } from './schema'; + export { /** Predicates */ isType, @@ -61,6 +63,7 @@ export { GraphQLList, GraphQLNonNull, } from './definition'; + export type { GraphQLType, GraphQLInputType, @@ -113,6 +116,7 @@ export type { GraphQLScalarValueParser, GraphQLScalarLiteralParser, } from './definition'; + export { /** Predicate */ isDirective, @@ -130,10 +134,12 @@ export { /** Constant Deprecation Reason */ DEFAULT_DEPRECATION_REASON, } from './directives'; + export type { GraphQLDirectiveConfig, GraphQLDirectiveExtensions, } from './directives'; + /** Common built-in scalar instances. */ export { /** Predicate */ @@ -146,6 +152,7 @@ export { GraphQLBoolean, GraphQLID, } from './scalars'; + export { /** Predicate */ isIntrospectionType, @@ -164,9 +171,11 @@ export { TypeMetaFieldDef, TypeNameMetaFieldDef, } from './introspection'; + export type { /** "Enum" of Type Kinds */ TypeKind, } from './introspection'; + /** Validate GraphQL schema. */ export { validateSchema, assertValidSchema } from './validate'; diff --git a/src/type/introspection.d.ts b/src/type/introspection.d.ts deleted file mode 100644 index eb4a6a05e3..0000000000 --- a/src/type/introspection.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { GraphQLNamedType, GraphQLField } from './definition'; -import { GraphQLObjectType, GraphQLEnumType } from './definition'; -export const __Schema: GraphQLObjectType; -export const __Directive: GraphQLObjectType; -export const __DirectiveLocation: GraphQLEnumType; -export const __Type: GraphQLObjectType; -export const __Field: GraphQLObjectType; -export const __InputValue: GraphQLObjectType; -export const __EnumValue: GraphQLObjectType; -export const TypeKind: Readonly<{ - readonly SCALAR: 'SCALAR'; - readonly OBJECT: 'OBJECT'; - readonly INTERFACE: 'INTERFACE'; - readonly UNION: 'UNION'; - readonly ENUM: 'ENUM'; - readonly INPUT_OBJECT: 'INPUT_OBJECT'; - readonly LIST: 'LIST'; - readonly NON_NULL: 'NON_NULL'; -}>; -export const __TypeKind: GraphQLEnumType; -/** - * Note that these are GraphQLField and not GraphQLFieldConfig, - * so the format for args is different. - */ -export const SchemaMetaFieldDef: GraphQLField; -export const TypeMetaFieldDef: GraphQLField; -export const TypeNameMetaFieldDef: GraphQLField; -export const introspectionTypes: ReadonlyArray; -export function isIntrospectionType(type: GraphQLNamedType): boolean; diff --git a/src/type/introspection.js b/src/type/introspection.ts similarity index 94% rename from src/type/introspection.js rename to src/type/introspection.ts index 30dae56b9a..1a9a655b91 100644 --- a/src/type/introspection.js +++ b/src/type/introspection.ts @@ -73,7 +73,7 @@ export const __Schema: GraphQLObjectType = new GraphQLObjectType({ ), resolve: (schema) => schema.getDirectives(), }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __Directive: GraphQLObjectType = new GraphQLObjectType({ @@ -106,7 +106,7 @@ export const __Directive: GraphQLObjectType = new GraphQLObjectType({ ), resolve: (directive) => directive.args, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __DirectiveLocation: GraphQLEnumType = new GraphQLEnumType({ @@ -229,21 +229,24 @@ export const __Type: GraphQLObjectType = 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)}".`); }, }, name: { type: GraphQLString, + // @ts-expect-error FIXME: TS Conversion resolve: (type) => (type.name !== undefined ? type.name : undefined), }, description: { type: GraphQLString, resolve: (type) => + // @ts-expect-error FIXME: TS Conversion type.description !== undefined ? type.description : undefined, }, specifiedByURL: { type: GraphQLString, resolve: (obj) => + // @ts-expect-error FIXME: TS Conversion obj.specifiedByURL !== undefined ? obj.specifiedByURL : undefined, }, fields: { @@ -310,9 +313,10 @@ export const __Type: GraphQLObjectType = new GraphQLObjectType({ ofType: { type: __Type, resolve: (type) => + // @ts-expect-error FIXME: TS Conversion type.ofType !== undefined ? type.ofType : undefined, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __Field: GraphQLObjectType = new GraphQLObjectType({ @@ -357,7 +361,7 @@ export const __Field: GraphQLObjectType = new GraphQLObjectType({ type: GraphQLString, resolve: (field) => field.deprecationReason, }, - }: GraphQLFieldConfigMap, mixed>), + } as GraphQLFieldConfigMap, unknown>), }); export const __InputValue: GraphQLObjectType = new GraphQLObjectType({ @@ -396,7 +400,7 @@ export const __InputValue: GraphQLObjectType = new GraphQLObjectType({ type: GraphQLString, resolve: (obj) => obj.deprecationReason, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const __EnumValue: GraphQLObjectType = new GraphQLObjectType({ @@ -421,7 +425,7 @@ export const __EnumValue: GraphQLObjectType = new GraphQLObjectType({ type: GraphQLString, resolve: (enumValue) => enumValue.deprecationReason, }, - }: GraphQLFieldConfigMap), + } as GraphQLFieldConfigMap), }); export const TypeKind = Object.freeze({ @@ -433,7 +437,7 @@ export const TypeKind = Object.freeze({ INPUT_OBJECT: 'INPUT_OBJECT', LIST: 'LIST', NON_NULL: 'NON_NULL', -}); +} as const); export const __TypeKind: GraphQLEnumType = new GraphQLEnumType({ name: '__TypeKind', @@ -485,7 +489,7 @@ export const __TypeKind: GraphQLEnumType = new GraphQLEnumType({ * 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.', @@ -496,7 +500,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.', @@ -517,7 +521,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.', @@ -528,7 +532,7 @@ export const TypeNameMetaFieldDef: GraphQLField = { astNode: undefined, }; -export const introspectionTypes: $ReadOnlyArray = +export const introspectionTypes: ReadonlyArray = Object.freeze([ __Schema, __Directive, diff --git a/src/type/scalars.d.ts b/src/type/scalars.d.ts deleted file mode 100644 index 6a33adb8b9..0000000000 --- a/src/type/scalars.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { GraphQLNamedType } from './definition'; -import { GraphQLScalarType } from './definition'; -export const GraphQLInt: GraphQLScalarType; -export const GraphQLFloat: GraphQLScalarType; -export const GraphQLString: GraphQLScalarType; -export const GraphQLBoolean: GraphQLScalarType; -export const GraphQLID: GraphQLScalarType; -export const specifiedScalarTypes: ReadonlyArray; -export function isSpecifiedScalarType(type: GraphQLNamedType): boolean; 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 1b31b9e01f..b8a4ee11f4 100644 --- a/src/type/scalars.js +++ b/src/type/scalars.ts @@ -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: GraphQLScalarType = 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: GraphQLScalarType = 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(); @@ -139,14 +139,13 @@ function serializeObject(outputValue: mixed): mixed { } } if (typeof outputValue.toJSON === 'function') { - // $FlowFixMe[incompatible-use] return outputValue.toJSON(); } } 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 +164,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 +190,7 @@ export const GraphQLString: GraphQLScalarType = new GraphQLScalarType({ }, }); -function serializeBoolean(outputValue: mixed): boolean { +function serializeBoolean(outputValue: unknown): boolean { const coercedValue = serializeObject(outputValue); if (typeof coercedValue === 'boolean') { @@ -205,7 +204,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 +229,7 @@ export const GraphQLBoolean: GraphQLScalarType = new GraphQLScalarType({ }, }); -function serializeID(outputValue: mixed): string { +function serializeID(outputValue: unknown): string { const coercedValue = serializeObject(outputValue); if (typeof coercedValue === 'string') { @@ -242,7 +241,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; } @@ -270,7 +269,7 @@ export const GraphQLID: GraphQLScalarType = new GraphQLScalarType({ }, }); -export const specifiedScalarTypes: $ReadOnlyArray = +export const specifiedScalarTypes: ReadonlyArray = Object.freeze([ GraphQLString, GraphQLInt, diff --git a/src/type/schema.d.ts b/src/type/schema.d.ts deleted file mode 100644 index b6b99d9e25..0000000000 --- a/src/type/schema.d.ts +++ /dev/null @@ -1,162 +0,0 @@ -import type { ObjMap } from '../jsutils/ObjMap'; -import type { Maybe } from '../jsutils/Maybe'; -import type { GraphQLError } from '../error/GraphQLError'; -import type { - SchemaDefinitionNode, - SchemaExtensionNode, -} from '../language/ast'; -import type { - GraphQLNamedType, - GraphQLAbstractType, - GraphQLObjectType, - GraphQLInterfaceType, -} from './definition'; -import type { GraphQLDirective } from './directives'; -/** - * Test if the given value is a GraphQL schema. - */ -export function isSchema(schema: unknown): schema is GraphQLSchema; -export function assertSchema(schema: unknown): GraphQLSchema; -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLSchemaExtensions { - [attributeName: string]: unknown; -} -/** - * Schema Definition - * - * A Schema is created by supplying the root types of each type of operation, - * query and mutation (optional). A schema definition is then supplied to the - * validator and executor. - * - * Example: - * - * const MyAppSchema = new GraphQLSchema({ - * query: MyAppQueryRootType, - * mutation: MyAppMutationRootType, - * }) - * - * Note: When the schema is constructed, by default only the types that are - * reachable by traversing the root types are included, other types must be - * explicitly referenced. - * - * Example: - * - * const characterInterface = new GraphQLInterfaceType({ - * name: 'Character', - * ... - * }); - * - * const humanType = new GraphQLObjectType({ - * name: 'Human', - * interfaces: [characterInterface], - * ... - * }); - * - * const droidType = new GraphQLObjectType({ - * name: 'Droid', - * interfaces: [characterInterface], - * ... - * }); - * - * const schema = new GraphQLSchema({ - * query: new GraphQLObjectType({ - * name: 'Query', - * fields: { - * hero: { type: characterInterface, ... }, - * } - * }), - * ... - * // Since this schema references only the `Character` interface it's - * // necessary to explicitly list the types that implement it if - * // you want them to be included in the final schema. - * types: [humanType, droidType], - * }) - * - * Note: If an array of `directives` are provided to GraphQLSchema, that will be - * the exact list of directives represented and allowed. If `directives` is not - * provided then a default set of the specified directives (e.g. @include and - * @skip) will be used. If you wish to provide *additional* directives to these - * specified directives, you must explicitly declare them. Example: - * - * const MyAppSchema = new GraphQLSchema({ - * ... - * directives: specifiedDirectives.concat([ myCustomDirective ]), - * }) - * - */ -export class GraphQLSchema { - description: Maybe; - extensions: Maybe>; - astNode: Maybe; - extensionASTNodes: ReadonlyArray; - __validationErrors: Maybe>; - private _queryType; - private _mutationType; - private _subscriptionType; - private _directives; - private _typeMap; - private _subTypeMap; - private _implementationsMap; - constructor(config: Readonly); - getQueryType(): Maybe; - getMutationType(): Maybe; - getSubscriptionType(): Maybe; - getTypeMap(): TypeMap; - getType(name: string): Maybe; - getPossibleTypes( - abstractType: GraphQLAbstractType, - ): ReadonlyArray; - getImplementations(interfaceType: GraphQLInterfaceType): { - objects: Array; - interfaces: Array; - }; - isSubType( - abstractType: GraphQLAbstractType, - maybeSubType: GraphQLObjectType | GraphQLInterfaceType, - ): boolean; - getDirectives(): ReadonlyArray; - getDirective(name: string): Maybe; - toConfig(): GraphQLSchemaNormalizedConfig; - get [Symbol.toStringTag](): string; -} -type TypeMap = ObjMap; -export interface 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 - * produced schema is valid. - * - * Default: false - */ - assumeValid?: boolean; -} -export interface GraphQLSchemaConfig extends GraphQLSchemaValidationOptions { - description?: Maybe; - query?: Maybe; - mutation?: Maybe; - subscription?: Maybe; - types?: Maybe>; - directives?: Maybe>; - extensions?: Maybe>; - astNode?: Maybe; - extensionASTNodes?: Maybe>; -} -/** - * @internal - */ -export interface GraphQLSchemaNormalizedConfig extends GraphQLSchemaConfig { - description: Maybe; - types: Array; - directives: Array; - extensions: Maybe>; - extensionASTNodes: ReadonlyArray; - assumeValid: boolean; -} 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 d37fda1f79..46015b0020 100644 --- a/src/type/schema.js +++ b/src/type/schema.ts @@ -1,13 +1,10 @@ -import type { - ObjMap, - ReadOnlyObjMap, - ReadOnlyObjMapLike, -} from '../jsutils/ObjMap'; +import type { ObjMap } 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 { Maybe } from '../jsutils/Maybe'; import type { GraphQLError } from '../error/GraphQLError'; @@ -37,20 +34,30 @@ import { /** * Test if the given value is a GraphQL schema. */ -declare function isSchema(schema: mixed): boolean %checks(schema instanceof - GraphQLSchema); -// eslint-disable-next-line no-redeclare -export function isSchema(schema) { +export function isSchema(schema: unknown): schema is GraphQLSchema { 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.`); } return schema; } +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLSchemaExtensions { + [attributeName: string]: unknown; +} + /** * Schema Definition * @@ -115,26 +122,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; - _typeMap: TypeMap; - _subTypeMap: ObjMap>; - _implementationsMap: ObjMap<{ - objects: Array, - interfaces: Array, - }>; + description: Maybe; + extensions: Maybe>; + astNode: Maybe; + extensionASTNodes: ReadonlyArray; // Used as a cache for validateSchema(). - __validationErrors: ?$ReadOnlyArray; + __validationErrors: Maybe>; + + private _queryType: Maybe; + private _mutationType: Maybe; + private _subscriptionType: Maybe; + private _directives: ReadonlyArray; + private _typeMap: TypeMap; + private _subTypeMap: ObjMap>; + private _implementationsMap: ObjMap<{ + objects: Array; + interfaces: Array; + }>; - constructor(config: $ReadOnly) { + 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; @@ -251,15 +258,15 @@ export class GraphQLSchema { } } - getQueryType(): ?GraphQLObjectType { + getQueryType(): Maybe { return this._queryType; } - getMutationType(): ?GraphQLObjectType { + getMutationType(): Maybe { return this._mutationType; } - getSubscriptionType(): ?GraphQLObjectType { + getSubscriptionType(): Maybe { return this._subscriptionType; } @@ -267,21 +274,21 @@ export class GraphQLSchema { return this._typeMap; } - getType(name: string): ?GraphQLNamedType { + getType(name: string): Maybe { return this.getTypeMap()[name]; } getPossibleTypes( abstractType: GraphQLAbstractType, - ): $ReadOnlyArray { + ): ReadonlyArray { return isUnionType(abstractType) ? abstractType.getTypes() : this.getImplementations(abstractType).objects; } 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: [] }; @@ -314,11 +321,11 @@ export class GraphQLSchema { return map[maybeSubType.name] !== undefined; } - getDirectives(): $ReadOnlyArray { + getDirectives(): ReadonlyArray { return this._directives; } - getDirective(name: string): ?GraphQLDirective { + getDirective(name: string): Maybe { return this.getDirectives().find((directive) => directive.name === name); } @@ -337,7 +344,6 @@ export class GraphQLSchema { }; } - // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet get [Symbol.toStringTag]() { return 'GraphQLSchema'; } @@ -345,7 +351,7 @@ export class GraphQLSchema { type TypeMap = ObjMap; -export type GraphQLSchemaValidationOptions = { +export interface 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 @@ -353,34 +359,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 interface GraphQLSchemaConfig extends GraphQLSchemaValidationOptions { + description?: Maybe; + query?: Maybe; + mutation?: Maybe; + subscription?: Maybe; + types?: Maybe>; + directives?: Maybe>; + extensions?: Maybe>; + astNode?: Maybe; + extensionASTNodes?: Maybe>; +} /** * @internal */ -export type GraphQLSchemaNormalizedConfig = { - ...GraphQLSchemaConfig, - description: ?string, - types: Array, - directives: Array, - extensions: ?ReadOnlyObjMap, - extensionASTNodes: $ReadOnlyArray, - assumeValid: boolean, -}; +export interface GraphQLSchemaNormalizedConfig extends GraphQLSchemaConfig { + description: Maybe; + types: Array; + directives: Array; + extensions: Maybe>; + extensionASTNodes: ReadonlyArray; + assumeValid: boolean; +} function collectReferencedTypes( type: GraphQLType, diff --git a/src/type/validate.d.ts b/src/type/validate.d.ts deleted file mode 100644 index b07bc0c11a..0000000000 --- a/src/type/validate.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { GraphQLError } from '../error/GraphQLError'; -import type { GraphQLSchema } from './schema'; -/** - * Implements the "Type Validation" sub-sections of the specification's - * "Type System" section. - * - * Validation runs synchronously, returning an array of encountered errors, or - * an empty array if no errors were encountered and the Schema is valid. - */ -export function validateSchema( - schema: GraphQLSchema, -): ReadonlyArray; -/** - * Utility function which asserts a schema is valid by throwing an error if - * it is invalid. - */ -export function assertValidSchema(schema: GraphQLSchema): void; diff --git a/src/type/validate.js b/src/type/validate.ts similarity index 94% rename from src/type/validate.js rename to src/type/validate.ts index fff65f90d5..65062401c7 100644 --- a/src/type/validate.js +++ b/src/type/validate.ts @@ -1,4 +1,5 @@ import { inspect } from '../jsutils/inspect'; +import type { Maybe } from '../jsutils/Maybe'; import { GraphQLError } from '../error/GraphQLError'; import { locatedError } from '../error/locatedError'; @@ -47,7 +48,7 @@ import { */ export function validateSchema( schema: GraphQLSchema, -): $ReadOnlyArray { +): ReadonlyArray { // First check to ensure the provided value is in fact a GraphQLSchema. assertSchema(schema); @@ -81,8 +82,8 @@ export function assertValidSchema(schema: GraphQLSchema): void { } class SchemaValidationContext { - +_errors: Array; - +schema: GraphQLSchema; + readonly _errors: Array; + readonly schema: GraphQLSchema; constructor(schema) { this._errors = []; @@ -91,7 +92,7 @@ class SchemaValidationContext { reportError( message: string, - nodes?: $ReadOnlyArray | ?ASTNode, + nodes?: ReadonlyArray> | Maybe, ): void { const _nodes = Array.isArray(nodes) ? nodes.filter(Boolean) : nodes; this.addError(new GraphQLError(message, _nodes)); @@ -101,7 +102,7 @@ class SchemaValidationContext { this._errors.push(error); } - getErrors(): $ReadOnlyArray { + getErrors(): ReadonlyArray { return this._errors; } } @@ -116,6 +117,7 @@ function validateRootTypes(context: SchemaValidationContext): void { `Query root type must be Object type, it cannot be ${inspect( queryType, )}.`, + // @ts-expect-error FIXME: TS Conversion getOperationTypeNode(schema, 'query') ?? queryType.astNode, ); } @@ -125,6 +127,7 @@ function validateRootTypes(context: SchemaValidationContext): void { context.reportError( 'Mutation root type must be Object type if provided, it cannot be ' + `${inspect(mutationType)}.`, + // @ts-expect-error FIXME: TS Conversion getOperationTypeNode(schema, 'mutation') ?? mutationType.astNode, ); } @@ -134,6 +137,7 @@ function validateRootTypes(context: SchemaValidationContext): void { context.reportError( 'Subscription root type must be Object type if provided, it cannot be ' + `${inspect(subscriptionType)}.`, + // @ts-expect-error FIXME: TS Conversion getOperationTypeNode(schema, 'subscription') ?? subscriptionType.astNode, ); } @@ -142,12 +146,15 @@ function validateRootTypes(context: SchemaValidationContext): void { function getOperationTypeNode( schema: GraphQLSchema, operation: OperationTypeNode, -): ?ASTNode { +): Maybe { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') - return [schema.astNode] - .concat(schema.extensionASTNodes) - .flatMap((schemaNode) => schemaNode?.operationTypes ?? []) - .find((operationNode) => operationNode.operation === operation)?.type; + return ( + [schema.astNode] + // @ts-expect-error FIXME: TS Conversion + .concat(schema.extensionASTNodes) + .flatMap((schemaNode) => schemaNode?.operationTypes ?? []) + .find((operationNode) => operationNode.operation === operation)?.type + ); } function validateDirectives(context: SchemaValidationContext): void { @@ -156,6 +163,7 @@ function validateDirectives(context: SchemaValidationContext): void { if (!isDirective(directive)) { context.reportError( `Expected directive but got: ${inspect(directive)}.`, + // @ts-expect-error FIXME: TS Conversion directive?.astNode, ); continue; @@ -192,7 +200,7 @@ function validateDirectives(context: SchemaValidationContext): void { function validateName( context: SchemaValidationContext, - node: { +name: string, +astNode: ?ASTNode, ... }, + node: { readonly name: string; readonly astNode: Maybe }, ): void { // Ensure names are valid, however introspection types opt out. const error = isValidNameError(node.name); @@ -210,6 +218,7 @@ function validateTypes(context: SchemaValidationContext): void { if (!isNamedType(type)) { context.reportError( `Expected GraphQL named type but got: ${inspect(type)}.`, + // @ts-expect-error FIXME: TS Conversion type.astNode, ); continue; @@ -596,7 +605,7 @@ function createInputObjectCircularRefsValidator( function getAllImplementsInterfaceNodes( type: GraphQLObjectType | GraphQLInterfaceType, iface: GraphQLInterfaceType, -): $ReadOnlyArray { +): ReadonlyArray { const { astNode, extensionASTNodes } = type; const nodes = astNode != null ? [astNode, ...extensionASTNodes] : extensionASTNodes; @@ -610,7 +619,7 @@ function getAllImplementsInterfaceNodes( function getUnionMemberTypeNodes( union: GraphQLUnionType, typeName: string, -): ?$ReadOnlyArray { +): Maybe> { const { astNode, extensionASTNodes } = union; const nodes = astNode != null ? [astNode, ...extensionASTNodes] : extensionASTNodes; @@ -622,8 +631,8 @@ function getUnionMemberTypeNodes( } function getDeprecatedDirectiveNode( - definitionNode: ?{ +directives?: $ReadOnlyArray, ... }, -): ?DirectiveNode { + definitionNode: Maybe<{ readonly directives?: ReadonlyArray }>, +): Maybe { // 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.d.ts b/src/utilities/TypeInfo.d.ts deleted file mode 100644 index fa1d01944a..0000000000 --- a/src/utilities/TypeInfo.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { ASTVisitor } from '../language/visitor'; -import type { ASTNode, FieldNode } from '../language/ast'; -import type { Maybe } from '../jsutils/Maybe'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLDirective } from '../type/directives'; -import type { - GraphQLType, - GraphQLInputType, - GraphQLOutputType, - GraphQLCompositeType, - GraphQLField, - GraphQLArgument, - GraphQLEnumValue, -} from '../type/definition'; -/** - * TypeInfo is a utility class which, given a GraphQL schema, can keep track - * of the current field and type definitions at any point in a GraphQL document - * AST during a recursive descent by calling `enter(node)` and `leave(node)`. - */ -export class TypeInfo { - private _schema; - private _typeStack; - private _parentTypeStack; - private _inputTypeStack; - private _fieldDefStack; - private _defaultValueStack; - private _directive; - private _argument; - private _enumValue; - private _getFieldDef; - constructor( - schema: GraphQLSchema, - /** - * Initial type may be provided in rare cases to facilitate traversals - * beginning somewhere other than documents. - */ - initialType?: Maybe, - /** @deprecated will be removed in 17.0.0 */ - getFieldDefFn?: GetFieldDefFn, - ); - getType(): Maybe; - getParentType(): Maybe; - getInputType(): Maybe; - getParentInputType(): Maybe; - getFieldDef(): Maybe>; - getDefaultValue(): Maybe; - getDirective(): Maybe; - getArgument(): Maybe; - getEnumValue(): Maybe; - enter(node: ASTNode): void; - leave(node: ASTNode): void; -} -type GetFieldDefFn = ( - schema: GraphQLSchema, - parentType: GraphQLType, - fieldNode: FieldNode, -) => Maybe>; -/** - * Creates a new visitor instance which maintains a provided TypeInfo instance - * along with visiting visitor. - */ -export function visitWithTypeInfo( - typeInfo: TypeInfo, - visitor: ASTVisitor, -): ASTVisitor; diff --git a/src/utilities/TypeInfo.js b/src/utilities/TypeInfo.ts similarity index 83% rename from src/utilities/TypeInfo.js rename to src/utilities/TypeInfo.ts index 05af99d0f6..ac220a7f30 100644 --- a/src/utilities/TypeInfo.js +++ b/src/utilities/TypeInfo.ts @@ -4,6 +4,8 @@ import { Kind } from '../language/kinds'; import { isNode } from '../language/ast'; import { getVisitFn } from '../language/visitor'; +import type { Maybe } from '../jsutils/Maybe'; + import type { GraphQLSchema } from '../type/schema'; import type { GraphQLDirective } from '../type/directives'; import type { @@ -42,16 +44,16 @@ import { typeFromAST } from './typeFromAST'; * AST during a recursive descent by calling `enter(node)` and `leave(node)`. */ export class TypeInfo { - _schema: GraphQLSchema; - _typeStack: Array; - _parentTypeStack: Array; - _inputTypeStack: Array; - _fieldDefStack: Array>; - _defaultValueStack: Array; - _directive: ?GraphQLDirective; - _argument: ?GraphQLArgument; - _enumValue: ?GraphQLEnumValue; - _getFieldDef: GetFieldDefFn; + private _schema: GraphQLSchema; + private _typeStack: Array>; + private _parentTypeStack: Array>; + private _inputTypeStack: Array>; + private _fieldDefStack: Array>>; + private _defaultValueStack: Array>; + private _directive: Maybe; + private _argument: Maybe; + private _enumValue: Maybe; + private _getFieldDef: GetFieldDefFn; constructor( schema: GraphQLSchema, @@ -59,7 +61,7 @@ export class TypeInfo { * Initial type may be provided in rare cases to facilitate traversals * beginning somewhere other than documents. */ - initialType?: ?GraphQLType, + initialType?: Maybe, /** @deprecated will be removed in 17.0.0 */ getFieldDefFn?: GetFieldDefFn, @@ -87,63 +89,63 @@ export class TypeInfo { } } - getType(): ?GraphQLOutputType { + getType(): Maybe { if (this._typeStack.length > 0) { return this._typeStack[this._typeStack.length - 1]; } } - getParentType(): ?GraphQLCompositeType { + getParentType(): Maybe { if (this._parentTypeStack.length > 0) { return this._parentTypeStack[this._parentTypeStack.length - 1]; } } - getInputType(): ?GraphQLInputType { + getInputType(): Maybe { if (this._inputTypeStack.length > 0) { return this._inputTypeStack[this._inputTypeStack.length - 1]; } } - getParentInputType(): ?GraphQLInputType { + getParentInputType(): Maybe { if (this._inputTypeStack.length > 1) { return this._inputTypeStack[this._inputTypeStack.length - 2]; } } - getFieldDef(): ?GraphQLField { + getFieldDef(): Maybe> { if (this._fieldDefStack.length > 0) { return this._fieldDefStack[this._fieldDefStack.length - 1]; } } - getDefaultValue(): ?mixed { + getDefaultValue(): Maybe { if (this._defaultValueStack.length > 0) { return this._defaultValueStack[this._defaultValueStack.length - 1]; } } - getDirective(): ?GraphQLDirective { + getDirective(): Maybe { return this._directive; } - getArgument(): ?GraphQLArgument { + getArgument(): Maybe { return this._argument; } - getEnumValue(): ?GraphQLEnumValue { + getEnumValue(): Maybe { return this._enumValue; } enter(node: ASTNode) { const schema = this._schema; - // Note: many of the types below are explicitly typed as "mixed" to drop + // Note: many of the types below are explicitly typed as "unknown" to drop // any assumptions of a valid schema to ensure runtime types are properly // checked before continuing since TypeInfo is used as part of validation // 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, ); @@ -152,7 +154,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) { @@ -167,7 +169,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(); @@ -185,14 +187,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, ); @@ -200,7 +202,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( @@ -216,8 +218,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. @@ -226,9 +228,9 @@ export class TypeInfo { break; } case Kind.OBJECT_FIELD: { - const objectType: mixed = getNamedType(this.getInputType()); - let inputFieldType: GraphQLInputType | void; - let inputField: GraphQLInputField | void; + const objectType: unknown = getNamedType(this.getInputType()); + let inputFieldType: GraphQLInputType | undefined; + let inputField: GraphQLInputField | undefined; if (isInputObjectType(objectType)) { inputField = objectType.getFields()[node.name.value]; if (inputField) { @@ -244,7 +246,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); @@ -296,7 +298,7 @@ type GetFieldDefFn = ( schema: GraphQLSchema, parentType: GraphQLType, fieldNode: FieldNode, -) => ?GraphQLField; +) => Maybe>; /** * Not exactly the same as the executor's definition of getFieldDef, in this @@ -307,7 +309,7 @@ function getFieldDef( schema: GraphQLSchema, parentType: GraphQLType, fieldNode: FieldNode, -): ?GraphQLField { +): Maybe> { const name = fieldNode.name.value; if ( name === SchemaMetaFieldDef.name && 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 94% rename from src/utilities/__tests__/assertValidName-test.js rename to src/utilities/__tests__/assertValidName-test.ts index 40f9d2e398..a794d5fb68 100644 --- a/src/utilities/__tests__/assertValidName-test.js +++ b/src/utilities/__tests__/assertValidName-test.ts @@ -15,7 +15,7 @@ describe('assertValidName()', () => { }); it('throws for non-strings', () => { - // $FlowExpectedError[incompatible-call] + // @ts-expect-error expect(() => assertValidName({})).to.throw('Expected name to be a string.'); }); 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 828ffa1abf..6503f6a02e 100644 --- a/src/utilities/__tests__/buildASTSchema-test.js +++ b/src/utilities/__tests__/buildASTSchema-test.ts @@ -40,6 +40,7 @@ import { graphqlSync } from '../../graphql'; import { printType, printSchema } from '../printSchema'; import { buildASTSchema, buildSchema } from '../buildASTSchema'; +import type { Maybe } from '../../jsutils/Maybe'; /** * This function does a full cycle of going from a string with the contents of @@ -50,14 +51,13 @@ function cycleSDL(sdl: string): string { return printSchema(buildSchema(sdl)); } -function expectASTNode(obj: ?{ +astNode: ?ASTNode, ... }) { +function expectASTNode(obj: Maybe<{ readonly astNode: Maybe }>) { invariant(obj?.astNode != null); return expect(print(obj.astNode)); } function expectExtensionASTNodes(obj: { - +extensionASTNodes: $ReadOnlyArray, - ... + readonly extensionASTNodes: ReadonlyArray; }) { return expect(obj.extensionASTNodes.map(print).join('\n\n')); } @@ -1095,12 +1095,11 @@ describe('Schema Builder', () => { }); it('Rejects invalid AST', () => { - // $FlowExpectedError[incompatible-call] expect(() => buildASTSchema(null)).to.throw( 'Must provide valid Document AST', ); - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => buildASTSchema({})).to.throw( 'Must provide valid Document AST', ); diff --git a/src/utilities/__tests__/buildClientSchema-test.js b/src/utilities/__tests__/buildClientSchema-test.ts similarity index 97% rename from src/utilities/__tests__/buildClientSchema-test.js rename to src/utilities/__tests__/buildClientSchema-test.ts index d3d0be8899..49c4253b53 100644 --- a/src/utilities/__tests__/buildClientSchema-test.js +++ b/src/utilities/__tests__/buildClientSchema-test.ts @@ -74,7 +74,7 @@ describe('Type System: build schema from introspection', () => { const schema = buildSchema(sdl); const introspection = introspectionFromSchema(schema); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete introspection.__schema.queryType; const clientSchema = buildClientSchema(introspection); @@ -475,7 +475,7 @@ describe('Type System: build schema from introspection', () => { const schema = buildSchema(sdl); const introspection = introspectionFromSchema(schema); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete introspection.__schema.directives; const clientSchema = buildClientSchema(introspection); @@ -629,12 +629,11 @@ describe('Type System: build schema from introspection', () => { `); it('throws when introspection is missing __schema property', () => { - // $FlowExpectedError[incompatible-call] expect(() => buildClientSchema(null)).to.throw( 'Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: null.', ); - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => buildClientSchema({})).to.throw( 'Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: {}.', ); @@ -643,7 +642,7 @@ describe('Type System: build schema from introspection', () => { it('throws when referenced unknown type', () => { const introspection = introspectionFromSchema(dummySchema); - // $FlowExpectedError[cannot-write] + // @ts-expect-error introspection.__schema.types = introspection.__schema.types.filter( ({ name }) => name !== 'Query', ); @@ -661,7 +660,7 @@ describe('Type System: build schema from introspection', () => { `); const introspection = introspectionFromSchema(schema); - // $FlowExpectedError[cannot-write] + // @ts-expect-error introspection.__schema.types = introspection.__schema.types.filter( ({ name }) => name !== 'Float', ); @@ -676,7 +675,7 @@ describe('Type System: build schema from introspection', () => { expect(introspection).to.have.nested.property('__schema.queryType.name'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete introspection.__schema.queryType.name; expect(() => buildClientSchema(introspection)).to.throw( @@ -691,7 +690,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(queryTypeIntrospection?.kind === 'OBJECT'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete queryTypeIntrospection.kind; expect(() => buildClientSchema(introspection)).to.throw( @@ -708,7 +707,7 @@ describe('Type System: build schema from introspection', () => { expect(queryTypeIntrospection).to.have.property('interfaces'); invariant(queryTypeIntrospection?.kind === 'OBJECT'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete queryTypeIntrospection.interfaces; expect(() => buildClientSchema(introspection)).to.throw( @@ -723,7 +722,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(someInterfaceIntrospection?.kind === 'INTERFACE'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error someInterfaceIntrospection.interfaces = null; const clientSchema = buildClientSchema(introspection); @@ -737,7 +736,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(queryTypeIntrospection?.kind === 'OBJECT'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete queryTypeIntrospection.fields; expect(() => buildClientSchema(introspection)).to.throw( @@ -752,7 +751,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(queryTypeIntrospection?.kind === 'OBJECT'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete queryTypeIntrospection.fields[0].args; expect(() => buildClientSchema(introspection)).to.throw( @@ -771,7 +770,7 @@ describe('Type System: build schema from introspection', () => { invariant(argType.kind === 'SCALAR'); expect(argType).to.have.property('name', 'String'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error argType.name = 'SomeUnion'; expect(() => buildClientSchema(introspection)).to.throw( @@ -790,7 +789,7 @@ describe('Type System: build schema from introspection', () => { invariant(fieldType.kind === 'SCALAR'); expect(fieldType).to.have.property('name', 'String'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error fieldType.name = 'SomeInputObject'; expect(() => buildClientSchema(introspection)).to.throw( @@ -805,7 +804,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(someUnionIntrospection?.kind === 'UNION'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete someUnionIntrospection.possibleTypes; expect(() => buildClientSchema(introspection)).to.throw( @@ -820,7 +819,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(someEnumIntrospection?.kind === 'ENUM'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete someEnumIntrospection.enumValues; expect(() => buildClientSchema(introspection)).to.throw( @@ -835,7 +834,7 @@ describe('Type System: build schema from introspection', () => { ); invariant(someInputObjectIntrospection?.kind === 'INPUT_OBJECT'); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete someInputObjectIntrospection.inputFields; expect(() => buildClientSchema(introspection)).to.throw( @@ -852,7 +851,7 @@ describe('Type System: build schema from introspection', () => { locations: ['QUERY'], }); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete someDirectiveIntrospection.locations; expect(() => buildClientSchema(introspection)).to.throw( @@ -869,7 +868,7 @@ describe('Type System: build schema from introspection', () => { args: [], }); - // $FlowExpectedError[cannot-write] + // @ts-expect-error delete someDirectiveIntrospection.args; expect(() => buildClientSchema(introspection)).to.throw( diff --git a/src/utilities/__tests__/coerceInputValue-test.js b/src/utilities/__tests__/coerceInputValue-test.ts similarity index 96% rename from src/utilities/__tests__/coerceInputValue-test.js rename to src/utilities/__tests__/coerceInputValue-test.ts index 978297c3b1..79ee43de23 100644 --- a/src/utilities/__tests__/coerceInputValue-test.js +++ b/src/utilities/__tests__/coerceInputValue-test.ts @@ -1,8 +1,6 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import { invariant } from '../../jsutils/invariant'; - import type { GraphQLInputType } from '../../type/definition'; import { GraphQLInt } from '../../type/scalars'; import { @@ -15,16 +13,19 @@ import { import { coerceInputValue } from '../coerceInputValue'; -type CoerceResult = { - value: mixed, - errors: $ReadOnlyArray<{ - path: $ReadOnlyArray, - value: mixed, - error: string, - }>, -}; +interface CoerceResult { + value: unknown; + errors: ReadonlyArray<{ + path: ReadonlyArray; + value: unknown; + error: string; + }>; +} -function coerceValue(inputValue: mixed, type: GraphQLInputType): CoerceResult { +function coerceValue( + inputValue: unknown, + type: GraphQLInputType, +): CoerceResult { const errors = []; const value = coerceInputValue( inputValue, @@ -81,8 +82,7 @@ describe('coerceInputValue', () => { describe('for GraphQLScalar', () => { const TestScalar = new GraphQLScalarType({ name: 'TestScalar', - parseValue(input) { - invariant(typeof input === 'object' && input !== null); + parseValue(input: { error?: string; value?: unknown }) { if (input.error != null) { throw new Error(input.error); } 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 67703c07e2..085752dcc4 100644 --- a/src/utilities/__tests__/extendSchema-test.js +++ b/src/utilities/__tests__/extendSchema-test.ts @@ -4,6 +4,7 @@ import { describe, it } from 'mocha'; import { dedent } from '../../__testUtils__/dedent'; import { invariant } from '../../jsutils/invariant'; +import type { Maybe } from '../../jsutils/Maybe'; import type { ASTNode } from '../../language/ast'; import { parse } from '../../language/parser'; @@ -36,13 +37,12 @@ import { extendSchema } from '../extendSchema'; import { buildSchema } from '../buildASTSchema'; function expectExtensionASTNodes(obj: { - +extensionASTNodes: $ReadOnlyArray, - ... + readonly extensionASTNodes: ReadonlyArray; }) { return expect(obj.extensionASTNodes.map(print).join('\n\n')); } -function expectASTNode(obj: ?{ +astNode: ?ASTNode, ... }) { +function expectASTNode(obj: Maybe<{ readonly astNode: Maybe }>) { invariant(obj?.astNode != null); return expect(print(obj.astNode)); } @@ -1143,12 +1143,11 @@ describe('extendSchema', () => { it('Rejects invalid AST', () => { const schema = new GraphQLSchema({}); - // $FlowExpectedError[incompatible-call] expect(() => extendSchema(schema, null)).to.throw( 'Must provide valid Document AST', ); - // $FlowExpectedError[prop-missing] + // @ts-expect-error expect(() => extendSchema(schema, {})).to.throw( 'Must provide valid Document AST', ); 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 95% rename from src/utilities/__tests__/getOperationRootType-test.js rename to src/utilities/__tests__/getOperationRootType-test.ts index 8bc87d7d2f..f730e7810a 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 type { DocumentNode, OperationDefinitionNode } from '../../language/ast'; import { Kind } from '../../language/kinds'; import { parse } from '../../language/parser'; @@ -34,7 +34,7 @@ const subscriptionType = new GraphQLObjectType({ }), }); -function getOperationNode(doc: DocumentNode) { +function getOperationNode(doc: DocumentNode): OperationDefinitionNode { const operationNode = doc.definitions[0]; invariant(operationNode.kind === Kind.OPERATION_DEFINITION); return operationNode; @@ -146,12 +146,12 @@ describe('getOperationRootType', () => { it('Throws when operation not a valid operation kind', () => { const testSchema = new GraphQLSchema({}); const doc = parse('{ field }'); - const operationNode = { + const operationNode: OperationDefinitionNode = { ...getOperationNode(doc), + // @ts-expect-error operation: 'non_existent_operation', }; - // $FlowExpectedError[incompatible-call] expect(() => getOperationRootType(testSchema, operationNode)).to.throw( 'Can only have query, mutation and subscription operations.', ); diff --git a/src/utilities/__tests__/introspectionFromSchema-test.js b/src/utilities/__tests__/introspectionFromSchema-test.ts similarity index 100% rename from src/utilities/__tests__/introspectionFromSchema-test.js rename to src/utilities/__tests__/introspectionFromSchema-test.ts 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 f108094616..89aefc03d8 100644 --- a/src/utilities/__tests__/printSchema-test.js +++ b/src/utilities/__tests__/printSchema-test.ts @@ -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 594b3ffea0..a1fb74dc05 100644 --- a/src/utilities/__tests__/stripIgnoredCharacters-test.js +++ b/src/utilities/__tests__/stripIgnoredCharacters-test.ts @@ -7,6 +7,7 @@ import { kitchenSinkSDL } from '../../__testUtils__/kitchenSinkSDL'; import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery'; import { invariant } from '../../jsutils/invariant'; +import type { Maybe } from '../../jsutils/Maybe'; import { Lexer } from '../../language/lexer'; import { parse } from '../../language/parser'; @@ -58,7 +59,7 @@ const nonPunctuatorTokens = [ '"""block\nstring\nvalue"""', // StringValue(BlockString) ]; -function lexValue(str: string): ?string { +function lexValue(str: string): Maybe { 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 98% rename from src/utilities/__tests__/typeComparators-test.js rename to src/utilities/__tests__/typeComparators-test.ts index 3f2a87ae78..adf830b461 100644 --- a/src/utilities/__tests__/typeComparators-test.js +++ b/src/utilities/__tests__/typeComparators-test.ts @@ -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 99% rename from src/utilities/__tests__/valueFromAST-test.js rename to src/utilities/__tests__/valueFromAST-test.ts index a444392777..6c08ccf15c 100644 --- a/src/utilities/__tests__/valueFromAST-test.js +++ b/src/utilities/__tests__/valueFromAST-test.ts @@ -29,7 +29,7 @@ describe('valueFromAST', () => { function expectValueFrom( valueText: string, type: GraphQLInputType, - variables?: ObjMap, + variables?: ObjMap, ) { 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..9ad004c42e 100644 --- a/src/utilities/__tests__/valueFromASTUntyped-test.js +++ b/src/utilities/__tests__/valueFromASTUntyped-test.ts @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; +import type { Maybe } from '../../jsutils/Maybe'; import type { ObjMap } from '../../jsutils/ObjMap'; import { parseValue } from '../../language/parser'; @@ -8,7 +9,10 @@ import { parseValue } from '../../language/parser'; import { valueFromASTUntyped } from '../valueFromASTUntyped'; describe('valueFromASTUntyped', () => { - function expectValueFrom(valueText: string, variables?: ?ObjMap) { + function expectValueFrom( + valueText: string, + variables?: Maybe>, + ) { const ast = parseValue(valueText); const value = valueFromASTUntyped(ast, variables); return expect(value); diff --git a/src/utilities/assertValidName.d.ts b/src/utilities/assertValidName.d.ts deleted file mode 100644 index 9abf64cadd..0000000000 --- a/src/utilities/assertValidName.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { GraphQLError } from '../error/GraphQLError'; -/** - * Upholds the spec rules about naming. - */ -export function assertValidName(name: string): string; -/** - * Returns an Error if a name is invalid. - */ -export function isValidNameError(name: string): GraphQLError | undefined; diff --git a/src/utilities/assertValidName.js b/src/utilities/assertValidName.ts similarity index 91% rename from src/utilities/assertValidName.js rename to src/utilities/assertValidName.ts index 3f294da39d..355780e7df 100644 --- a/src/utilities/assertValidName.js +++ b/src/utilities/assertValidName.ts @@ -18,7 +18,7 @@ export function assertValidName(name: string): string { /** * Returns an Error if a name is invalid. */ -export function isValidNameError(name: string): GraphQLError | void { +export function isValidNameError(name: string): GraphQLError | undefined { devAssert(typeof name === 'string', 'Expected name to be a string.'); if (name.length > 1 && name[0] === '_' && name[1] === '_') { return new GraphQLError( diff --git a/src/utilities/astFromValue.d.ts b/src/utilities/astFromValue.d.ts deleted file mode 100644 index 390ecdf571..0000000000 --- a/src/utilities/astFromValue.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { ValueNode } from '../language/ast'; -import type { GraphQLInputType } from '../type/definition'; -/** - * Produces a GraphQL Value AST given a JavaScript object. - * Function will match JavaScript/JSON values to GraphQL AST schema format - * by using suggested GraphQLInputType. For example: - * - * astFromValue("value", GraphQLString) - * - * A GraphQL type must be provided, which will be used to interpret different - * JavaScript values. - * - * | JSON Value | GraphQL Value | - * | ------------- | -------------------- | - * | Object | Input Object | - * | Array | List | - * | Boolean | Boolean | - * | String | String / Enum Value | - * | Number | Int / Float | - * | Mixed | Enum Value | - * | null | NullValue | - * - */ -export function astFromValue( - value: unknown, - type: GraphQLInputType, -): Maybe; 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 5621659f73..6ba9cff68e 100644 --- a/src/utilities/astFromValue.js +++ b/src/utilities/astFromValue.ts @@ -2,6 +2,7 @@ import { inspect } from '../jsutils/inspect'; import { invariant } from '../jsutils/invariant'; import { isObjectLike } from '../jsutils/isObjectLike'; import { isIterableObject } from '../jsutils/isIterableObject'; +import type { Maybe } from '../jsutils/Maybe'; import type { ValueNode } from '../language/ast'; import { Kind } from '../language/kinds'; @@ -33,11 +34,14 @@ import { * | Boolean | Boolean | * | String | String / Enum Value | * | Number | Int / Float | - * | Mixed | Enum Value | + * | Unknown | Enum Value | * | null | NullValue | * */ -export function astFromValue(value: mixed, type: GraphQLInputType): ?ValueNode { +export function astFromValue( + value: unknown, + type: GraphQLInputType, +): Maybe { if (isNonNullType(type)) { const astValue = astFromValue(value, type.ofType); if (astValue?.kind === Kind.NULL) { @@ -136,7 +140,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)); } /** diff --git a/src/utilities/buildASTSchema.d.ts b/src/utilities/buildASTSchema.d.ts deleted file mode 100644 index fe36c9dc94..0000000000 --- a/src/utilities/buildASTSchema.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Source } from '../language/source'; -import type { DocumentNode } from '../language/ast'; -import type { ParseOptions } from '../language/parser'; -import type { GraphQLSchemaValidationOptions } from '../type/schema'; -import { GraphQLSchema } from '../type/schema'; -export interface BuildSchemaOptions extends GraphQLSchemaValidationOptions { - /** - * Set to true to assume the SDL is valid. - * - * Default: false - */ - assumeValidSDL?: boolean; -} -/** - * This takes the ast of a schema document produced by the parse function in - * src/language/parser.js. - * - * If no schema definition is provided, then it will look for types named Query - * and Mutation. - * - * Given that AST it constructs a GraphQLSchema. The resulting schema - * has no resolve methods, so execution will use default resolvers. - */ -export function buildASTSchema( - documentAST: DocumentNode, - options?: BuildSchemaOptions, -): GraphQLSchema; -/** - * A helper function to build a GraphQLSchema directly from a source - * document. - */ -export function buildSchema( - source: string | Source, - options?: BuildSchemaOptions & ParseOptions, -): GraphQLSchema; diff --git a/src/utilities/buildASTSchema.js b/src/utilities/buildASTSchema.ts similarity index 88% rename from src/utilities/buildASTSchema.js rename to src/utilities/buildASTSchema.ts index d6e56a4bf2..6aa872c085 100644 --- a/src/utilities/buildASTSchema.js +++ b/src/utilities/buildASTSchema.ts @@ -14,16 +14,14 @@ import { specifiedDirectives } from '../type/directives'; import { extendSchemaImpl } from './extendSchema'; -export type BuildSchemaOptions = { - ...GraphQLSchemaValidationOptions, - +export interface BuildSchemaOptions extends 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,15 +63,15 @@ export function buildASTSchema( // typed values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable results. case 'Query': - // $FlowExpectedError[incompatible-type] validated in `validateSchema` + // @ts-expect-error validated in `validateSchema` config.query = type; break; case 'Mutation': - // $FlowExpectedError[incompatible-type] validated in `validateSchema` + // @ts-expect-error validated in `validateSchema` config.mutation = type; break; case 'Subscription': - // $FlowExpectedError[incompatible-type] validated in `validateSchema` + // @ts-expect-error validated in `validateSchema` config.subscription = type; break; } @@ -97,7 +95,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.d.ts b/src/utilities/buildClientSchema.d.ts deleted file mode 100644 index 2cb46834b4..0000000000 --- a/src/utilities/buildClientSchema.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { GraphQLSchemaValidationOptions } from '../type/schema'; -import { GraphQLSchema } from '../type/schema'; -import type { IntrospectionQuery } from './getIntrospectionQuery'; -/** - * Build a GraphQLSchema for use by client tools. - * - * Given the result of a client running the introspection query, creates and - * returns a GraphQLSchema instance which can be then used with all graphql-js - * tools, but cannot be used to execute a query, as introspection does not - * represent the "resolver", "parse" or "serialize" functions or any other - * server-internal mechanisms. - * - * This function expects a complete introspection result. Don't forget to check - * the "errors" field of a server response before calling this function. - */ -export function buildClientSchema( - introspection: IntrospectionQuery, - options?: GraphQLSchemaValidationOptions, -): GraphQLSchema; diff --git a/src/utilities/buildClientSchema.js b/src/utilities/buildClientSchema.ts similarity index 97% rename from src/utilities/buildClientSchema.js rename to src/utilities/buildClientSchema.ts index 487ee6d16e..e2d55eecb1 100644 --- a/src/utilities/buildClientSchema.js +++ b/src/utilities/buildClientSchema.ts @@ -140,9 +140,7 @@ export function buildClientSchema( return getNamedType(typeRef); } - function getNamedType( - typeRef: IntrospectionNamedTypeRef<>, - ): GraphQLNamedType { + function getNamedType(typeRef: IntrospectionNamedTypeRef): GraphQLNamedType { const typeName = typeRef.name; if (!typeName) { throw new Error(`Unknown type reference: ${inspect(typeRef)}.`); @@ -173,6 +171,7 @@ export function buildClientSchema( // Given a type's introspection result, construct the correct // GraphQLType instance. function buildType(type: IntrospectionType): GraphQLNamedType { + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain if (type != null && type.name != null && type.kind != null) { switch (type.kind) { case TypeKind.SCALAR: @@ -308,7 +307,7 @@ export function buildClientSchema( function buildFieldDefMap( typeIntrospection: IntrospectionObjectType | IntrospectionInterfaceType, - ): GraphQLFieldConfigMap { + ): GraphQLFieldConfigMap { if (!typeIntrospection.fields) { throw new Error( `Introspection result missing fields: ${inspect(typeIntrospection)}.`, @@ -324,7 +323,7 @@ export function buildClientSchema( function buildField( fieldIntrospection: IntrospectionField, - ): GraphQLFieldConfig { + ): GraphQLFieldConfig { const type = getType(fieldIntrospection.type); if (!isOutputType(type)) { const typeStr = inspect(type); @@ -349,7 +348,7 @@ export function buildClientSchema( } function buildInputValueDefMap( - inputValueIntrospections: $ReadOnlyArray, + inputValueIntrospections: ReadonlyArray, ) { return keyValMap( inputValueIntrospections, diff --git a/src/utilities/coerceInputValue.d.ts b/src/utilities/coerceInputValue.d.ts deleted file mode 100644 index 54ed99bc97..0000000000 --- a/src/utilities/coerceInputValue.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { GraphQLError } from '../error/GraphQLError'; -import type { GraphQLInputType } from '../type/definition'; -type OnErrorCB = ( - path: ReadonlyArray, - invalidValue: unknown, - error: GraphQLError, -) => void; -/** - * Coerces a JavaScript value given a GraphQL Input Type. - */ -export function coerceInputValue( - inputValue: unknown, - type: GraphQLInputType, - onError?: OnErrorCB, -): unknown; diff --git a/src/utilities/coerceInputValue.js b/src/utilities/coerceInputValue.ts similarity index 94% rename from src/utilities/coerceInputValue.js rename to src/utilities/coerceInputValue.ts index 8a9b946a7f..1c115f3b99 100644 --- a/src/utilities/coerceInputValue.js +++ b/src/utilities/coerceInputValue.ts @@ -19,8 +19,8 @@ import { } from '../type/definition'; type OnErrorCB = ( - path: $ReadOnlyArray, - invalidValue: mixed, + path: ReadonlyArray, + invalidValue: unknown, error: GraphQLError, ) => void; @@ -28,16 +28,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 { +): unknown { return coerceInputValueImpl(inputValue, type, onError, undefined); } function defaultOnError( - path: $ReadOnlyArray, - invalidValue: mixed, + path: ReadonlyArray, + invalidValue: unknown, error: GraphQLError, ): void { let errorPrefix = 'Invalid value ' + inspect(invalidValue); @@ -49,11 +49,11 @@ function defaultOnError( } function coerceInputValueImpl( - inputValue: mixed, + inputValue: unknown, type: GraphQLInputType, onError: OnErrorCB, - path: Path | void, -): mixed { + path: Path | undefined, +): unknown { if (isNonNullType(type)) { if (inputValue != null) { return coerceInputValueImpl(inputValue, type.ofType, onError, path); @@ -184,5 +184,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)); } diff --git a/src/utilities/concatAST.d.ts b/src/utilities/concatAST.d.ts deleted file mode 100644 index d289766f1d..0000000000 --- a/src/utilities/concatAST.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { DocumentNode } from '../language/ast'; -/** - * Provided a collection of ASTs, presumably each from different files, - * concatenate the ASTs together into batched AST, useful for validating many - * GraphQL source files which together represent one conceptual application. - */ -export function concatAST(documents: ReadonlyArray): DocumentNode; diff --git a/src/utilities/concatAST.js b/src/utilities/concatAST.ts similarity index 92% rename from src/utilities/concatAST.js rename to src/utilities/concatAST.ts index b7a0ea4726..f3ce0614f7 100644 --- a/src/utilities/concatAST.js +++ b/src/utilities/concatAST.ts @@ -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.d.ts b/src/utilities/extendSchema.d.ts deleted file mode 100644 index 2a6cec7f49..0000000000 --- a/src/utilities/extendSchema.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { DocumentNode } from '../language/ast'; -import type { - GraphQLSchemaValidationOptions, - GraphQLSchemaNormalizedConfig, -} from '../type/schema'; -import { GraphQLSchema } from '../type/schema'; -interface Options extends GraphQLSchemaValidationOptions { - /** - * Set to true to assume the SDL is valid. - * - * Default: false - */ - assumeValidSDL?: boolean; -} -/** - * Produces a new schema given an existing schema and a document which may - * contain GraphQL type extensions and definitions. The original schema will - * remain unaltered. - * - * Because a schema represents a graph of references, a schema cannot be - * extended without effectively making an entire copy. We do not know until it's - * too late if subgraphs remain unchanged. - * - * This algorithm copies the provided schema, applying extensions while - * producing the copy. The original schema remains unaltered. - */ -export function extendSchema( - schema: GraphQLSchema, - documentAST: DocumentNode, - options?: Options, -): GraphQLSchema; -/** - * @internal - */ -export function extendSchemaImpl( - schemaConfig: GraphQLSchemaNormalizedConfig, - documentAST: DocumentNode, - options?: Options, -): GraphQLSchemaNormalizedConfig; diff --git a/src/utilities/extendSchema.js b/src/utilities/extendSchema.ts similarity index 92% rename from src/utilities/extendSchema.js rename to src/utilities/extendSchema.ts index dcc46438c6..98eb8a2083 100644 --- a/src/utilities/extendSchema.js +++ b/src/utilities/extendSchema.ts @@ -3,6 +3,7 @@ import { inspect } from '../jsutils/inspect'; import { mapValue } from '../jsutils/mapValue'; import { invariant } from '../jsutils/invariant'; import { devAssert } from '../jsutils/devAssert'; +import type { Maybe } from '../jsutils/Maybe'; import type { DocumentNode, @@ -81,16 +82,14 @@ import { import { valueFromAST } from './valueFromAST'; -type Options = { - ...GraphQLSchemaValidationOptions, - +interface Options extends 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 @@ -143,7 +142,7 @@ export function extendSchemaImpl( // have the same name. For example, a type named "skip". const directiveDefs: Array = []; - let schemaDef: ?SchemaDefinitionNode; + let schemaDef: Maybe; // Schema extensions are collected which may add additional operation types. const schemaExtensions: Array = []; @@ -216,19 +215,20 @@ 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] + // @ts-expect-error return new GraphQLList(replaceType(type.ofType)); } if (isNonNullType(type)) { - // $FlowFixMe[incompatible-return] + // @ts-expect-error return new GraphQLNonNull(replaceType(type.ofType)); } + // @ts-expect-error FIXME 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. @@ -269,7 +269,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)); } function extendInputObjectType( @@ -374,12 +374,11 @@ export function extendSchemaImpl( } function extendField( - field: GraphQLFieldConfig, - ): GraphQLFieldConfig { + field: GraphQLFieldConfig, + ): GraphQLFieldConfig { return { ...field, type: replaceType(field.type), - // $FlowFixMe[incompatible-call] args: mapValue(field.args, extendArg), }; } @@ -392,11 +391,11 @@ export function extendSchemaImpl( } function getOperationTypes( - nodes: $ReadOnlyArray, + nodes: ReadonlyArray, ): { - query: ?GraphQLObjectType, - mutation: ?GraphQLObjectType, - subscription: ?GraphQLObjectType, + query: Maybe; + mutation: Maybe; + subscription: Maybe; } { const opTypes = {}; for (const node of nodes) { @@ -411,8 +410,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. - // $FlowFixMe[incompatible-return] - // $FlowFixMe[incompatible-exact] + // @ts-expect-error return opTypes; } @@ -431,7 +429,6 @@ export function extendSchemaImpl( return new GraphQLList(getWrappedType(node.type)); } if (node.kind === Kind.NON_NULL_TYPE) { - // $FlowFixMe[incompatible-call] return new GraphQLNonNull(getWrappedType(node.type)); } return getNamedType(node); @@ -441,7 +438,7 @@ export function extendSchemaImpl( return new GraphQLDirective({ name: node.name.value, description: node.description?.value, - // $FlowFixMe[incompatible-call] + // @ts-expect-error locations: node.locations.map(({ value }) => value), isRepeatable: node.repeatable, args: buildArgumentMap(node.arguments), @@ -450,13 +447,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') @@ -479,7 +476,7 @@ export function extendSchemaImpl( } function buildArgumentMap( - args: ?$ReadOnlyArray, + args: Maybe>, ): GraphQLFieldConfigArgumentMap { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') const argsNodes = args ?? []; @@ -503,8 +500,8 @@ export function extendSchemaImpl( } function buildInputFieldMap( - nodes: $ReadOnlyArray< - InputObjectTypeDefinitionNode | InputObjectTypeExtensionNode, + nodes: ReadonlyArray< + InputObjectTypeDefinitionNode | InputObjectTypeExtensionNode >, ): GraphQLInputFieldConfigMap { const inputFieldMap = Object.create(null); @@ -531,7 +528,7 @@ export function extendSchemaImpl( } function buildEnumValueMap( - nodes: $ReadOnlyArray, + nodes: ReadonlyArray, ): GraphQLEnumValueConfigMap { const enumValueMap = Object.create(null); for (const node of nodes) { @@ -550,17 +547,17 @@ export function extendSchemaImpl( } function buildInterfaces( - nodes: $ReadOnlyArray< + nodes: ReadonlyArray< | InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode | ObjectTypeDefinitionNode - | ObjectTypeExtensionNode, + | ObjectTypeExtensionNode >, ): Array { // Note: While this could make assertions to get the correctly typed // values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable results. - // $FlowFixMe[incompatible-return] + // @ts-expect-error return nodes.flatMap( // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') (node) => node.interfaces?.map(getNamedType) ?? [], @@ -568,12 +565,12 @@ export function extendSchemaImpl( } function buildUnionTypes( - nodes: $ReadOnlyArray, + nodes: ReadonlyArray, ): Array { // Note: While this could make assertions to get the correctly typed // values below, that would throw immediately while type system // validation with validateSchema() will produce more actionable results. - // $FlowFixMe[incompatible-return] + // @ts-expect-error return nodes.flatMap( // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') (node) => node.types?.map(getNamedType) ?? [], @@ -654,14 +651,12 @@ 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)), - ); + invariant(false, 'Unexpected type definition node: ' + inspect(astNode)); } } const stdTypeMap = keyMap( + // @ts-expect-error FIXME: TS Conversion specifiedScalarTypes.concat(introspectionTypes), (type) => type.name, ); @@ -675,9 +670,9 @@ function getDeprecationReason( | EnumValueDefinitionNode | FieldDefinitionNode | InputValueDefinitionNode, -): ?string { +): Maybe { const deprecated = getDirectiveValues(GraphQLDeprecatedDirective, node); - // $FlowExpectedError[incompatible-return] validated by `getDirectiveValues` + // @ts-expect-error validated by `getDirectiveValues` return deprecated?.reason; } @@ -686,8 +681,8 @@ function getDeprecationReason( */ function getSpecifiedByURL( node: ScalarTypeDefinitionNode | ScalarTypeExtensionNode, -): ?string { +): Maybe { const specifiedBy = getDirectiveValues(GraphQLSpecifiedByDirective, node); - // $FlowExpectedError[incompatible-return] validated by `getDirectiveValues` + // @ts-expect-error validated by `getDirectiveValues` return specifiedBy?.url; } diff --git a/src/utilities/findBreakingChanges.d.ts b/src/utilities/findBreakingChanges.d.ts deleted file mode 100644 index 8149251bb9..0000000000 --- a/src/utilities/findBreakingChanges.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { GraphQLSchema } from '../type/schema'; -export const BreakingChangeType: Readonly<{ - readonly TYPE_REMOVED: 'TYPE_REMOVED'; - readonly TYPE_CHANGED_KIND: 'TYPE_CHANGED_KIND'; - readonly TYPE_REMOVED_FROM_UNION: 'TYPE_REMOVED_FROM_UNION'; - readonly VALUE_REMOVED_FROM_ENUM: 'VALUE_REMOVED_FROM_ENUM'; - readonly REQUIRED_INPUT_FIELD_ADDED: 'REQUIRED_INPUT_FIELD_ADDED'; - readonly IMPLEMENTED_INTERFACE_REMOVED: 'IMPLEMENTED_INTERFACE_REMOVED'; - readonly FIELD_REMOVED: 'FIELD_REMOVED'; - readonly FIELD_CHANGED_KIND: 'FIELD_CHANGED_KIND'; - readonly REQUIRED_ARG_ADDED: 'REQUIRED_ARG_ADDED'; - readonly ARG_REMOVED: 'ARG_REMOVED'; - readonly ARG_CHANGED_KIND: 'ARG_CHANGED_KIND'; - readonly DIRECTIVE_REMOVED: 'DIRECTIVE_REMOVED'; - readonly DIRECTIVE_ARG_REMOVED: 'DIRECTIVE_ARG_REMOVED'; - readonly REQUIRED_DIRECTIVE_ARG_ADDED: 'REQUIRED_DIRECTIVE_ARG_ADDED'; - readonly DIRECTIVE_REPEATABLE_REMOVED: 'DIRECTIVE_REPEATABLE_REMOVED'; - readonly DIRECTIVE_LOCATION_REMOVED: 'DIRECTIVE_LOCATION_REMOVED'; -}>; -export const DangerousChangeType: Readonly<{ - readonly VALUE_ADDED_TO_ENUM: 'VALUE_ADDED_TO_ENUM'; - readonly TYPE_ADDED_TO_UNION: 'TYPE_ADDED_TO_UNION'; - readonly OPTIONAL_INPUT_FIELD_ADDED: 'OPTIONAL_INPUT_FIELD_ADDED'; - readonly OPTIONAL_ARG_ADDED: 'OPTIONAL_ARG_ADDED'; - readonly IMPLEMENTED_INTERFACE_ADDED: 'IMPLEMENTED_INTERFACE_ADDED'; - readonly ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE'; -}>; -export interface BreakingChange { - type: keyof typeof BreakingChangeType; - description: string; -} -export interface DangerousChange { - type: keyof typeof DangerousChangeType; - description: string; -} -/** - * Given two schemas, returns an Array containing descriptions of all the types - * of breaking changes covered by the other functions down below. - */ -export function findBreakingChanges( - oldSchema: GraphQLSchema, - newSchema: GraphQLSchema, -): Array; -/** - * Given two schemas, returns an Array containing descriptions of all the types - * of potentially dangerous changes covered by the other functions down below. - */ -export function findDangerousChanges( - oldSchema: GraphQLSchema, - newSchema: GraphQLSchema, -): Array; diff --git a/src/utilities/findBreakingChanges.js b/src/utilities/findBreakingChanges.ts similarity index 96% rename from src/utilities/findBreakingChanges.js rename to src/utilities/findBreakingChanges.ts index 03e9933fcd..4d9ee699ef 100644 --- a/src/utilities/findBreakingChanges.js +++ b/src/utilities/findBreakingChanges.ts @@ -52,7 +52,7 @@ export const BreakingChangeType = Object.freeze({ REQUIRED_DIRECTIVE_ARG_ADDED: 'REQUIRED_DIRECTIVE_ARG_ADDED', DIRECTIVE_REPEATABLE_REMOVED: 'DIRECTIVE_REPEATABLE_REMOVED', DIRECTIVE_LOCATION_REMOVED: 'DIRECTIVE_LOCATION_REMOVED', -}); +} as const); export const DangerousChangeType = Object.freeze({ VALUE_ADDED_TO_ENUM: 'VALUE_ADDED_TO_ENUM', @@ -61,17 +61,17 @@ export const DangerousChangeType = Object.freeze({ OPTIONAL_ARG_ADDED: 'OPTIONAL_ARG_ADDED', IMPLEMENTED_INTERFACE_ADDED: 'IMPLEMENTED_INTERFACE_ADDED', ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE', -}); +} as const); -export type BreakingChange = { - type: $Keys, - description: string, -}; +export interface BreakingChange { + type: keyof typeof BreakingChangeType; + description: string; +} -export type DangerousChange = { - type: $Keys, - description: string, -}; +export interface DangerousChange { + type: keyof typeof DangerousChangeType; + description: string; +} /** * Given two schemas, returns an Array containing descriptions of all the types @@ -81,7 +81,7 @@ export function findBreakingChanges( oldSchema: GraphQLSchema, newSchema: GraphQLSchema, ): Array { - // $FlowFixMe[prop-missing] + // @ts-expect-error return findSchemaChanges(oldSchema, newSchema).filter( (change) => change.type in BreakingChangeType, ); @@ -95,7 +95,7 @@ export function findDangerousChanges( oldSchema: GraphQLSchema, newSchema: GraphQLSchema, ): Array { - // $FlowFixMe[prop-missing] + // @ts-expect-error return findSchemaChanges(oldSchema, newSchema).filter( (change) => change.type in DangerousChangeType, ); @@ -378,8 +378,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); @@ -531,10 +531,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)); } -function stringifyValue(value: mixed, type: GraphQLInputType): string { +function stringifyValue(value: unknown, type: GraphQLInputType): string { const ast = astFromValue(value, type); invariant(ast != null); @@ -553,13 +553,13 @@ function stringifyValue(value: mixed, type: GraphQLInputType): string { return print(sortedAST); } -function diff( - oldArray: $ReadOnlyArray, - newArray: $ReadOnlyArray, +function diff( + oldArray: ReadonlyArray, + newArray: ReadonlyArray, ): { - added: Array, - removed: Array, - persisted: Array<[T, T]>, + added: Array; + removed: Array; + persisted: Array<[T, T]>; } { const added = []; const removed = []; diff --git a/src/utilities/getIntrospectionQuery.js b/src/utilities/getIntrospectionQuery.js deleted file mode 100644 index 4f7259abfc..0000000000 --- a/src/utilities/getIntrospectionQuery.js +++ /dev/null @@ -1,321 +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` flag on directives. - * Default: false - */ - directiveIsRepeatable?: boolean, - - /** - * Whether to include `description` field on schema. - * Default: false - */ - schemaDescription?: boolean, - - /** - * Whether target GraphQL server support deprecation of input values. - * Default: false - */ - inputValueDeprecation?: boolean, -}; - -export function getIntrospectionQuery(options?: IntrospectionOptions): string { - const optionsWithDefault = { - descriptions: true, - specifiedByUrl: false, - directiveIsRepeatable: false, - schemaDescription: false, - inputValueDeprecation: false, - ...options, - }; - - const descriptions = optionsWithDefault.descriptions ? 'description' : ''; - const specifiedByUrl = optionsWithDefault.specifiedByUrl - ? 'specifiedByURL' - : ''; - const directiveIsRepeatable = optionsWithDefault.directiveIsRepeatable - ? 'isRepeatable' - : ''; - const schemaDescription = optionsWithDefault.schemaDescription - ? descriptions - : ''; - - function inputDeprecation(str) { - return optionsWithDefault.inputValueDeprecation ? str : ''; - } - - return ` - query IntrospectionQuery { - __schema { - ${schemaDescription} - queryType { name } - mutationType { name } - subscriptionType { name } - types { - ...FullType - } - directives { - name - ${descriptions} - ${directiveIsRepeatable} - locations - args${inputDeprecation('(includeDeprecated: true)')} { - ...InputValue - } - } - } - } - - fragment FullType on __Type { - kind - name - ${descriptions} - ${specifiedByUrl} - fields(includeDeprecated: true) { - name - ${descriptions} - args${inputDeprecation('(includeDeprecated: true)')} { - ...InputValue - } - type { - ...TypeRef - } - isDeprecated - deprecationReason - } - inputFields${inputDeprecation('(includeDeprecated: true)')} { - ...InputValue - } - interfaces { - ...TypeRef - } - enumValues(includeDeprecated: true) { - name - ${descriptions} - isDeprecated - deprecationReason - } - possibleTypes { - ...TypeRef - } - } - - fragment InputValue on __InputValue { - name - ${descriptions} - type { ...TypeRef } - defaultValue - ${inputDeprecation('isDeprecated')} - ${inputDeprecation('deprecationReason')} - } - - 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, - +isDeprecated?: boolean, - +deprecationReason?: ?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.d.ts b/src/utilities/getIntrospectionQuery.ts similarity index 67% rename from src/utilities/getIntrospectionQuery.d.ts rename to src/utilities/getIntrospectionQuery.ts index d8a4f1fcfe..0482031495 100644 --- a/src/utilities/getIntrospectionQuery.d.ts +++ b/src/utilities/getIntrospectionQuery.ts @@ -1,36 +1,167 @@ import type { Maybe } from '../jsutils/Maybe'; import type { DirectiveLocationEnum } from '../language/directiveLocation'; + export interface 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` flag on directives. * Default: false */ directiveIsRepeatable?: boolean; + /** * Whether to include `description` field on schema. * Default: false */ schemaDescription?: boolean; + /** * Whether target GraphQL server support deprecation of input values. * Default: false */ inputValueDeprecation?: boolean; } -export function getIntrospectionQuery(options?: IntrospectionOptions): string; + +export function getIntrospectionQuery(options?: IntrospectionOptions): string { + const optionsWithDefault = { + descriptions: true, + specifiedByUrl: false, + directiveIsRepeatable: false, + schemaDescription: false, + inputValueDeprecation: false, + ...options, + }; + + const descriptions = optionsWithDefault.descriptions ? 'description' : ''; + const specifiedByUrl = optionsWithDefault.specifiedByUrl + ? 'specifiedByURL' + : ''; + const directiveIsRepeatable = optionsWithDefault.directiveIsRepeatable + ? 'isRepeatable' + : ''; + const schemaDescription = optionsWithDefault.schemaDescription + ? descriptions + : ''; + + function inputDeprecation(str) { + return optionsWithDefault.inputValueDeprecation ? str : ''; + } + + return ` + query IntrospectionQuery { + __schema { + ${schemaDescription} + queryType { name } + mutationType { name } + subscriptionType { name } + types { + ...FullType + } + directives { + name + ${descriptions} + ${directiveIsRepeatable} + locations + args${inputDeprecation('(includeDeprecated: true)')} { + ...InputValue + } + } + } + } + + fragment FullType on __Type { + kind + name + ${descriptions} + ${specifiedByUrl} + fields(includeDeprecated: true) { + name + ${descriptions} + args${inputDeprecation('(includeDeprecated: true)')} { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields${inputDeprecation('(includeDeprecated: true)')} { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + ${descriptions} + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } + } + + fragment InputValue on __InputValue { + name + ${descriptions} + type { ...TypeRef } + defaultValue + ${inputDeprecation('isDeprecated')} + ${inputDeprecation('deprecationReason')} + } + + 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 interface IntrospectionQuery { readonly __schema: IntrospectionSchema; } + export interface IntrospectionSchema { readonly description?: Maybe; readonly queryType: IntrospectionNamedTypeRef; @@ -43,6 +174,7 @@ export interface IntrospectionSchema { readonly types: ReadonlyArray; readonly directives: ReadonlyArray; } + export type IntrospectionType = | IntrospectionScalarType | IntrospectionObjectType @@ -50,22 +182,26 @@ export type IntrospectionType = | IntrospectionUnionType | IntrospectionEnumType | IntrospectionInputObjectType; + export type IntrospectionOutputType = | IntrospectionScalarType | IntrospectionObjectType | IntrospectionInterfaceType | IntrospectionUnionType | IntrospectionEnumType; + export type IntrospectionInputType = | IntrospectionScalarType | IntrospectionEnumType | IntrospectionInputObjectType; + export interface IntrospectionScalarType { readonly kind: 'SCALAR'; readonly name: string; readonly description?: Maybe; readonly specifiedByURL?: Maybe; } + export interface IntrospectionObjectType { readonly kind: 'OBJECT'; readonly name: string; @@ -75,6 +211,7 @@ export interface IntrospectionObjectType { IntrospectionNamedTypeRef >; } + export interface IntrospectionInterfaceType { readonly kind: 'INTERFACE'; readonly name: string; @@ -87,6 +224,7 @@ export interface IntrospectionInterfaceType { IntrospectionNamedTypeRef >; } + export interface IntrospectionUnionType { readonly kind: 'UNION'; readonly name: string; @@ -95,36 +233,42 @@ export interface IntrospectionUnionType { IntrospectionNamedTypeRef >; } + export interface IntrospectionEnumType { readonly kind: 'ENUM'; readonly name: string; readonly description?: Maybe; readonly enumValues: ReadonlyArray; } + export interface IntrospectionInputObjectType { readonly kind: 'INPUT_OBJECT'; readonly name: string; readonly description?: Maybe; readonly inputFields: ReadonlyArray; } + export interface IntrospectionListTypeRef< T extends IntrospectionTypeRef = IntrospectionTypeRef, > { readonly kind: 'LIST'; readonly ofType: T; } + export interface 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 @@ -132,6 +276,7 @@ export type IntrospectionOutputTypeRef = | IntrospectionNamedTypeRef | IntrospectionListTypeRef >; + export type IntrospectionInputTypeRef = | IntrospectionNamedTypeRef | IntrospectionListTypeRef @@ -139,12 +284,14 @@ export type IntrospectionInputTypeRef = | IntrospectionNamedTypeRef | IntrospectionListTypeRef >; + export interface IntrospectionNamedTypeRef< T extends IntrospectionType = IntrospectionType, > { readonly kind: T['kind']; readonly name: string; } + export interface IntrospectionField { readonly name: string; readonly description?: Maybe; @@ -153,6 +300,7 @@ export interface IntrospectionField { readonly isDeprecated: boolean; readonly deprecationReason: Maybe; } + export interface IntrospectionInputValue { readonly name: string; readonly description?: Maybe; @@ -161,12 +309,14 @@ export interface IntrospectionInputValue { readonly isDeprecated?: boolean; readonly deprecationReason?: Maybe; } + export interface IntrospectionEnumValue { readonly name: string; readonly description?: Maybe; readonly isDeprecated: boolean; readonly deprecationReason: Maybe; } + export interface IntrospectionDirective { readonly name: string; readonly description?: Maybe; diff --git a/src/utilities/getOperationAST.d.ts b/src/utilities/getOperationAST.d.ts deleted file mode 100644 index 3728c9a308..0000000000 --- a/src/utilities/getOperationAST.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { DocumentNode, OperationDefinitionNode } from '../language/ast'; -/** - * Returns an operation AST given a document AST and optionally an operation - * name. If a name is not provided, an operation is only returned if only one is - * provided in the document. - */ -export function getOperationAST( - documentAST: DocumentNode, - operationName?: Maybe, -): Maybe; diff --git a/src/utilities/getOperationAST.js b/src/utilities/getOperationAST.ts similarity index 89% rename from src/utilities/getOperationAST.js rename to src/utilities/getOperationAST.ts index 259d2f05c5..9e6d85dd9f 100644 --- a/src/utilities/getOperationAST.js +++ b/src/utilities/getOperationAST.ts @@ -1,3 +1,4 @@ +import type { Maybe } from '../jsutils/Maybe'; import type { DocumentNode, OperationDefinitionNode } from '../language/ast'; import { Kind } from '../language/kinds'; @@ -8,8 +9,8 @@ import { Kind } from '../language/kinds'; */ export function getOperationAST( documentAST: DocumentNode, - operationName?: ?string, -): ?OperationDefinitionNode { + operationName?: Maybe, +): Maybe { let operation = null; for (const definition of documentAST.definitions) { if (definition.kind === Kind.OPERATION_DEFINITION) { diff --git a/src/utilities/getOperationRootType.d.ts b/src/utilities/getOperationRootType.d.ts deleted file mode 100644 index 759436ae89..0000000000 --- a/src/utilities/getOperationRootType.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { - OperationDefinitionNode, - OperationTypeDefinitionNode, -} from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLObjectType } from '../type/definition'; -/** - * Extracts the root type of the operation from the schema. - */ -export function getOperationRootType( - schema: GraphQLSchema, - operation: OperationDefinitionNode | OperationTypeDefinitionNode, -): GraphQLObjectType; diff --git a/src/utilities/getOperationRootType.js b/src/utilities/getOperationRootType.ts similarity index 100% rename from src/utilities/getOperationRootType.js rename to src/utilities/getOperationRootType.ts diff --git a/src/utilities/index.js b/src/utilities/index.js deleted file mode 100644 index 92a4d58289..0000000000 --- a/src/utilities/index.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Produce the GraphQL query recommended for a full schema introspection. - * Accepts optional IntrospectionOptions. - */ -export { getIntrospectionQuery } from './getIntrospectionQuery'; - -export type { - IntrospectionOptions, - IntrospectionQuery, - IntrospectionSchema, - IntrospectionType, - IntrospectionInputType, - IntrospectionOutputType, - IntrospectionScalarType, - IntrospectionObjectType, - IntrospectionInterfaceType, - IntrospectionUnionType, - IntrospectionEnumType, - IntrospectionInputObjectType, - IntrospectionTypeRef, - IntrospectionInputTypeRef, - IntrospectionOutputTypeRef, - IntrospectionNamedTypeRef, - IntrospectionListTypeRef, - IntrospectionNonNullTypeRef, - IntrospectionField, - IntrospectionInputValue, - IntrospectionEnumValue, - IntrospectionDirective, -} from './getIntrospectionQuery'; - -/** Gets the target Operation from a Document. */ -export { getOperationAST } from './getOperationAST'; - -/** Gets the Type for the target Operation AST. */ -export { getOperationRootType } from './getOperationRootType'; - -/** Convert a GraphQLSchema to an IntrospectionQuery. */ -export { introspectionFromSchema } from './introspectionFromSchema'; - -/** Build a GraphQLSchema from an introspection result. */ -export { buildClientSchema } from './buildClientSchema'; - -/** Build a GraphQLSchema from GraphQL Schema language. */ -export { buildASTSchema, buildSchema } from './buildASTSchema'; -export type { BuildSchemaOptions } from './buildASTSchema'; - -/** Extends an existing GraphQLSchema from a parsed GraphQL Schema language AST. */ -export { extendSchema } from './extendSchema'; - -/** Sort a GraphQLSchema. */ -export { lexicographicSortSchema } from './lexicographicSortSchema'; - -/** Print a GraphQLSchema to GraphQL Schema language. */ -export { - printSchema, - printType, - printIntrospectionSchema, -} from './printSchema'; - -/** Create a GraphQLType from a GraphQL language AST. */ -export { typeFromAST } from './typeFromAST'; - -/** Create a JavaScript value from a GraphQL language AST with a type. */ -export { valueFromAST } from './valueFromAST'; - -/** Create a JavaScript value from a GraphQL language AST without a type. */ -export { valueFromASTUntyped } from './valueFromASTUntyped'; - -/** Create a GraphQL language AST from a JavaScript value. */ -export { astFromValue } from './astFromValue'; - -/** A helper to use within recursive-descent visitors which need to be aware of the GraphQL type system. */ -export { TypeInfo, visitWithTypeInfo } from './TypeInfo'; - -/** Coerces a JavaScript value to a GraphQL type, or produces errors. */ -export { coerceInputValue } from './coerceInputValue'; - -/** Concatenates multiple AST together. */ -export { concatAST } from './concatAST'; - -/** Separates an AST into an AST per Operation. */ -export { separateOperations } from './separateOperations'; - -/** Strips characters that are not significant to the validity or execution of a GraphQL document. */ -export { stripIgnoredCharacters } from './stripIgnoredCharacters'; - -/** Comparators for types */ -export { - isEqualType, - isTypeSubTypeOf, - doTypesOverlap, -} from './typeComparators'; - -/** Asserts that a string is a valid GraphQL name */ -export { assertValidName, isValidNameError } from './assertValidName'; - -/** Compares two GraphQLSchemas and detects breaking changes. */ -export { - BreakingChangeType, - DangerousChangeType, - findBreakingChanges, - findDangerousChanges, -} from './findBreakingChanges'; -export type { BreakingChange, DangerousChange } from './findBreakingChanges'; diff --git a/src/utilities/index.d.ts b/src/utilities/index.ts similarity index 99% rename from src/utilities/index.d.ts rename to src/utilities/index.ts index f2d9ebe28b..982779c773 100644 --- a/src/utilities/index.d.ts +++ b/src/utilities/index.ts @@ -3,6 +3,7 @@ * Accepts optional IntrospectionOptions. */ export { getIntrospectionQuery } from './getIntrospectionQuery'; + export type { IntrospectionOptions, IntrospectionQuery, @@ -27,53 +28,73 @@ export type { IntrospectionEnumValue, IntrospectionDirective, } from './getIntrospectionQuery'; + /** Gets the target Operation from a Document. */ export { getOperationAST } from './getOperationAST'; + /** Gets the Type for the target Operation AST. */ export { getOperationRootType } from './getOperationRootType'; + /** Convert a GraphQLSchema to an IntrospectionQuery. */ export { introspectionFromSchema } from './introspectionFromSchema'; + /** Build a GraphQLSchema from an introspection result. */ export { buildClientSchema } from './buildClientSchema'; + /** Build a GraphQLSchema from GraphQL Schema language. */ export { buildASTSchema, buildSchema } from './buildASTSchema'; export type { BuildSchemaOptions } from './buildASTSchema'; + /** Extends an existing GraphQLSchema from a parsed GraphQL Schema language AST. */ export { extendSchema } from './extendSchema'; + /** Sort a GraphQLSchema. */ export { lexicographicSortSchema } from './lexicographicSortSchema'; + /** Print a GraphQLSchema to GraphQL Schema language. */ export { printSchema, printType, printIntrospectionSchema, } from './printSchema'; + /** Create a GraphQLType from a GraphQL language AST. */ export { typeFromAST } from './typeFromAST'; + /** Create a JavaScript value from a GraphQL language AST with a type. */ export { valueFromAST } from './valueFromAST'; + /** Create a JavaScript value from a GraphQL language AST without a type. */ export { valueFromASTUntyped } from './valueFromASTUntyped'; + /** Create a GraphQL language AST from a JavaScript value. */ export { astFromValue } from './astFromValue'; + /** A helper to use within recursive-descent visitors which need to be aware of the GraphQL type system. */ export { TypeInfo, visitWithTypeInfo } from './TypeInfo'; + /** Coerces a JavaScript value to a GraphQL type, or produces errors. */ export { coerceInputValue } from './coerceInputValue'; + /** Concatenates multiple AST together. */ export { concatAST } from './concatAST'; + /** Separates an AST into an AST per Operation. */ export { separateOperations } from './separateOperations'; + /** Strips characters that are not significant to the validity or execution of a GraphQL document. */ export { stripIgnoredCharacters } from './stripIgnoredCharacters'; + /** Comparators for types */ export { isEqualType, isTypeSubTypeOf, doTypesOverlap, } from './typeComparators'; + /** Asserts that a string is a valid GraphQL name */ export { assertValidName, isValidNameError } from './assertValidName'; + /** Compares two GraphQLSchemas and detects breaking changes. */ export { BreakingChangeType, @@ -82,5 +103,6 @@ export { findDangerousChanges, } from './findBreakingChanges'; export type { BreakingChange, DangerousChange } from './findBreakingChanges'; + /** Wrapper type that contains DocumentNode and types that can be deduced from it. */ export { TypedQueryDocumentNode } from './typedQueryDocumentNode'; diff --git a/src/utilities/introspectionFromSchema.d.ts b/src/utilities/introspectionFromSchema.d.ts deleted file mode 100644 index db68d93985..0000000000 --- a/src/utilities/introspectionFromSchema.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { GraphQLSchema } from '../type/schema'; -import type { - IntrospectionQuery, - IntrospectionOptions, -} from './getIntrospectionQuery'; -/** - * Build an IntrospectionQuery from a GraphQLSchema - * - * IntrospectionQuery is useful for utilities that care about type and field - * relationships, but do not need to traverse through those relationships. - * - * This is the inverse of buildClientSchema. The primary use case is outside - * of the server context, for instance when doing schema comparisons. - */ -export function introspectionFromSchema( - schema: GraphQLSchema, - options?: IntrospectionOptions, -): IntrospectionQuery; diff --git a/src/utilities/introspectionFromSchema.js b/src/utilities/introspectionFromSchema.ts similarity index 94% rename from src/utilities/introspectionFromSchema.js rename to src/utilities/introspectionFromSchema.ts index 8d30e9bce6..105f5bc055 100644 --- a/src/utilities/introspectionFromSchema.js +++ b/src/utilities/introspectionFromSchema.ts @@ -36,7 +36,6 @@ export function introspectionFromSchema( const document = parse(getIntrospectionQuery(optionsWithDefaults)); const result = executeSync({ schema, document }); invariant(!result.errors && result.data); - // $FlowIgnore[incompatible-indexer] - // $FlowIgnore[incompatible-return] + // @ts-expect-error FIXME return result.data; } diff --git a/src/utilities/lexicographicSortSchema.d.ts b/src/utilities/lexicographicSortSchema.d.ts deleted file mode 100644 index 45d749d5d2..0000000000 --- a/src/utilities/lexicographicSortSchema.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GraphQLSchema } from '../type/schema'; -/** - * Sort GraphQLSchema. - * - * This function returns a sorted copy of the given GraphQLSchema. - */ -export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema; diff --git a/src/utilities/lexicographicSortSchema.js b/src/utilities/lexicographicSortSchema.ts similarity index 85% rename from src/utilities/lexicographicSortSchema.js rename to src/utilities/lexicographicSortSchema.ts index 291248ec1a..7b015f20a4 100644 --- a/src/utilities/lexicographicSortSchema.js +++ b/src/utilities/lexicographicSortSchema.ts @@ -3,6 +3,7 @@ import { inspect } from '../jsutils/inspect'; import { invariant } from '../jsutils/invariant'; import { keyValMap } from '../jsutils/keyValMap'; import { naturalCompare } from '../jsutils/naturalCompare'; +import type { Maybe } from '../jsutils/Maybe'; import type { GraphQLType, @@ -54,23 +55,26 @@ 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] + // @ts-expect-error return new GraphQLList(replaceType(type.ofType)); } else if (isNonNullType(type)) { - // $FlowFixMe[incompatible-return] + // @ts-expect-error return new GraphQLNonNull(replaceType(type.ofType)); } - return replaceNamedType(type); + // @ts-expect-error FIXME: TS Conversion + return replaceNamedType(type); } - function replaceNamedType(type: T): T { - // $FlowFixMe[incompatible-return] + function replaceNamedType(type: T): T { + // @ts-expect-error return typeMap[type.name]; } - function replaceMaybeType(maybeType: T): T { + function replaceMaybeType>( + maybeType: T, + ): T { return maybeType && replaceNamedType(maybeType); } @@ -90,7 +94,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,7 +109,9 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { })); } - function sortTypes(array: $ReadOnlyArray): Array { + function sortTypes( + array: ReadonlyArray, + ): Array { return sortByName(array).map(replaceNamedType); } @@ -153,7 +159,7 @@ 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)); } } @@ -169,14 +175,14 @@ function sortObjMap( return sortedMap; } -function sortByName( - array: $ReadOnlyArray, +function sortByName( + array: ReadonlyArray, ): Array { return sortBy(array, (obj) => obj.name); } function sortBy( - array: $ReadOnlyArray, + array: ReadonlyArray, mapToKey: (item: T) => string, ): Array { return array.slice().sort((obj1, obj2) => { diff --git a/src/utilities/printSchema.d.ts b/src/utilities/printSchema.d.ts deleted file mode 100644 index 793503c85b..0000000000 --- a/src/utilities/printSchema.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLNamedType } from '../type/definition'; -export function printSchema(schema: GraphQLSchema): string; -export function printIntrospectionSchema(schema: GraphQLSchema): string; -export function printType(type: GraphQLNamedType): string; diff --git a/src/utilities/printSchema.js b/src/utilities/printSchema.ts similarity index 95% rename from src/utilities/printSchema.js rename to src/utilities/printSchema.ts index cc41725368..42d48c6a6c 100644 --- a/src/utilities/printSchema.js +++ b/src/utilities/printSchema.ts @@ -1,5 +1,6 @@ import { inspect } from '../jsutils/inspect'; import { invariant } from '../jsutils/invariant'; +import type { Maybe } from '../jsutils/Maybe'; import { print } from '../language/printer'; import { printBlockString } from '../language/blockString'; @@ -67,7 +68,7 @@ function printFilteredSchema( .join('\n\n'); } -function printSchemaDefinition(schema: GraphQLSchema): ?string { +function printSchemaDefinition(schema: GraphQLSchema): Maybe { if (schema.description == null && isSchemaOfCommonNames(schema)) { return; } @@ -146,7 +147,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)); } function printScalar(type: GraphQLScalarType): string { @@ -223,12 +224,12 @@ 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}' : ''; } function printArgs( - args: $ReadOnlyArray, + args: ReadonlyArray, indentation: string = '', ): string { if (args.length === 0) { @@ -278,7 +279,7 @@ function printDirective(directive: GraphQLDirective): string { ); } -function printDeprecated(reason: ?string): string { +function printDeprecated(reason: Maybe): string { if (reason == null) { return ''; } @@ -298,7 +299,7 @@ function printSpecifiedByURL(scalar: GraphQLScalarType): string { } function printDescription( - def: { +description: ?string, ... }, + def: { readonly description: Maybe }, indentation: string = '', firstInBlock: boolean = true, ): string { diff --git a/src/utilities/separateOperations.d.ts b/src/utilities/separateOperations.d.ts deleted file mode 100644 index 3fbc026a39..0000000000 --- a/src/utilities/separateOperations.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ObjMap } from '../jsutils/ObjMap'; -import type { DocumentNode } from '../language/ast'; -/** - * separateOperations accepts a single AST document which may contain many - * operations and fragments and returns a collection of AST documents each of - * which contains a single operation as well the fragment definitions it - * refers to. - */ -export function separateOperations( - documentAST: DocumentNode, -): ObjMap; diff --git a/src/utilities/separateOperations.js b/src/utilities/separateOperations.ts similarity index 98% rename from src/utilities/separateOperations.js rename to src/utilities/separateOperations.ts index 5da3c1d1ea..6f33d4a234 100644 --- a/src/utilities/separateOperations.js +++ b/src/utilities/separateOperations.ts @@ -38,7 +38,7 @@ export function separateOperations( // is necessary for completing that operation. const separatedDocumentASTs = Object.create(null); for (const operation of operations) { - const dependencies = new Set(); + const dependencies = new Set(); for (const fragmentName of collectDependencies(operation.selectionSet)) { collectTransitiveDependencies(dependencies, depGraph, fragmentName); diff --git a/src/utilities/stripIgnoredCharacters.d.ts b/src/utilities/stripIgnoredCharacters.d.ts deleted file mode 100644 index 3ea3397f8f..0000000000 --- a/src/utilities/stripIgnoredCharacters.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Source } from '../language/source'; -/** - * Strips characters that are not significant to the validity or execution - * of a GraphQL document: - * - UnicodeBOM - * - WhiteSpace - * - LineTerminator - * - Comment - * - Comma - * - BlockString indentation - * - * Note: It is required to have a delimiter character between neighboring - * non-punctuator tokens and this function always uses single space as delimiter. - * - * It is guaranteed that both input and output documents if parsed would result - * in the exact same AST except for nodes location. - * - * Warning: It is guaranteed that this function will always produce stable results. - * However, it's not guaranteed that it will stay the same between different - * releases due to bugfixes or changes in the GraphQL specification. - * - * Query example: - * - * query SomeQuery($foo: String!, $bar: String) { - * someField(foo: $foo, bar: $bar) { - * a - * b { - * c - * d - * } - * } - * } - * - * Becomes: - * - * query SomeQuery($foo:String!$bar:String){someField(foo:$foo bar:$bar){a b{c d}}} - * - * SDL example: - * - * """ - * Type description - * """ - * type Foo { - * """ - * Field description - * """ - * bar: String - * } - * - * Becomes: - * - * """Type description""" type Foo{"""Field description""" bar:String} - */ -export function stripIgnoredCharacters(source: string | Source): string; 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.d.ts b/src/utilities/typeComparators.d.ts deleted file mode 100644 index b6a045b884..0000000000 --- a/src/utilities/typeComparators.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLType, GraphQLCompositeType } from '../type/definition'; -/** - * Provided two types, return true if the types are equal (invariant). - */ -export function isEqualType(typeA: GraphQLType, typeB: GraphQLType): boolean; -/** - * Provided a type and a super type, return true if the first type is either - * equal or a subset of the second super type (covariant). - */ -export function isTypeSubTypeOf( - schema: GraphQLSchema, - maybeSubType: GraphQLType, - superType: GraphQLType, -): boolean; -/** - * Provided two composite types, determine if they "overlap". Two composite - * types overlap when the Sets of possible concrete types for each intersect. - * - * This is often used to determine if a fragment of a given type could possibly - * be visited in a context of another type. - * - * This function is commutative. - */ -export function doTypesOverlap( - schema: GraphQLSchema, - typeA: GraphQLCompositeType, - typeB: GraphQLCompositeType, -): boolean; diff --git a/src/utilities/typeComparators.js b/src/utilities/typeComparators.ts similarity index 100% rename from src/utilities/typeComparators.js rename to src/utilities/typeComparators.ts diff --git a/src/utilities/typeFromAST.d.ts b/src/utilities/typeFromAST.d.ts deleted file mode 100644 index cbd45d429c..0000000000 --- a/src/utilities/typeFromAST.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { - TypeNode, - NamedTypeNode, - ListTypeNode, - NonNullTypeNode, -} from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLType, GraphQLNamedType } from '../type/definition'; -import { GraphQLList, GraphQLNonNull } from '../type/definition'; -/** - * Given a Schema and an AST node describing a type, return a GraphQLType - * definition which applies to that type. For example, if provided the parsed - * AST node for `[User]`, a GraphQLList instance will be returned, containing - * the type called "User" found in the schema. If a type called "User" is not - * found in the schema, then undefined will be returned. - */ -export function typeFromAST( - schema: GraphQLSchema, - typeNode: NamedTypeNode, -): GraphQLNamedType | undefined; -export function typeFromAST( - schema: GraphQLSchema, - typeNode: ListTypeNode, -): GraphQLList | undefined; -export function typeFromAST( - schema: GraphQLSchema, - typeNode: NonNullTypeNode, -): GraphQLNonNull | undefined; -export function typeFromAST( - schema: GraphQLSchema, - typeNode: TypeNode, -): GraphQLType | undefined; diff --git a/src/utilities/typeFromAST.js b/src/utilities/typeFromAST.ts similarity index 72% rename from src/utilities/typeFromAST.js rename to src/utilities/typeFromAST.ts index 0337e98420..5b3b3f2086 100644 --- a/src/utilities/typeFromAST.js +++ b/src/utilities/typeFromAST.ts @@ -2,6 +2,7 @@ import { inspect } from '../jsutils/inspect'; import { invariant } from '../jsutils/invariant'; import type { + TypeNode, NamedTypeNode, ListTypeNode, NonNullTypeNode, @@ -10,7 +11,7 @@ import type { import { Kind } from '../language/kinds'; import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLNamedType } from '../type/definition'; +import type { GraphQLType, GraphQLNamedType } from '../type/definition'; import { GraphQLList, GraphQLNonNull } from '../type/definition'; /** @@ -20,21 +21,26 @@ 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( +export function typeFromAST( schema: GraphQLSchema, typeNode: NamedTypeNode, -): GraphQLNamedType | void; -declare function typeFromAST( +): GraphQLNamedType | undefined; +export function typeFromAST( schema: GraphQLSchema, typeNode: ListTypeNode, -): GraphQLList | void; -declare function typeFromAST( +): GraphQLList | undefined; +export function typeFromAST( schema: GraphQLSchema, typeNode: NonNullTypeNode, -): GraphQLNonNull | void; -export function typeFromAST(schema, typeNode) { - /* eslint-enable no-redeclare */ +): GraphQLNonNull | undefined; +export function typeFromAST( + schema: GraphQLSchema, + typeNode: TypeNode, +): GraphQLType | undefined; +export function typeFromAST( + schema: GraphQLSchema, + typeNode: TypeNode, +): GraphQLType | undefined { let innerType; if (typeNode.kind === Kind.LIST_TYPE) { innerType = typeFromAST(schema, typeNode.type); @@ -50,5 +56,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)); } diff --git a/src/utilities/typedQueryDocumentNode.d.ts b/src/utilities/typedQueryDocumentNode.ts similarity index 100% rename from src/utilities/typedQueryDocumentNode.d.ts rename to src/utilities/typedQueryDocumentNode.ts diff --git a/src/utilities/valueFromAST.d.ts b/src/utilities/valueFromAST.d.ts deleted file mode 100644 index 084f98c1ac..0000000000 --- a/src/utilities/valueFromAST.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { ObjMap } from '../jsutils/ObjMap'; -import type { ValueNode } from '../language/ast'; -import type { GraphQLInputType } from '../type/definition'; -import type { Maybe } from '../jsutils/Maybe'; -/** - * Produces a JavaScript value given a GraphQL Value AST. - * - * A GraphQL type must be provided, which will be used to interpret different - * GraphQL Value literals. - * - * Returns `undefined` when the value could not be validly coerced according to - * the provided type. - * - * | GraphQL Value | JSON Value | - * | -------------------- | ------------- | - * | Input Object | Object | - * | List | Array | - * | Boolean | Boolean | - * | String | String | - * | Int / Float | Number | - * | Enum Value | Mixed | - * | NullValue | null | - * - */ -export function valueFromAST( - valueNode: Maybe, - type: GraphQLInputType, - variables?: Maybe>, -): unknown; diff --git a/src/utilities/valueFromAST.js b/src/utilities/valueFromAST.ts similarity index 94% rename from src/utilities/valueFromAST.js rename to src/utilities/valueFromAST.ts index 00e133e92e..359d2145bc 100644 --- a/src/utilities/valueFromAST.js +++ b/src/utilities/valueFromAST.ts @@ -14,6 +14,8 @@ import { isNonNullType, } from '../type/definition'; +import type { Maybe } from '../jsutils/Maybe'; + /** * Produces a JavaScript value given a GraphQL Value AST. * @@ -30,15 +32,15 @@ import { * | Boolean | Boolean | * | String | String | * | Int / Float | Number | - * | Enum Value | Mixed | + * | Enum Value | Unknown | * | NullValue | null | * */ export function valueFromAST( - valueNode: ?ValueNode, + valueNode: Maybe, type: GraphQLInputType, - variables?: ?ObjMap, -): mixed { + variables?: Maybe>, +): unknown { if (!valueNode) { // When there is no node, then there is also no value. // Importantly, this is different from returning the value null. @@ -145,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)); } // 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: Maybe>, ): boolean { return ( valueNode.kind === Kind.VARIABLE && diff --git a/src/utilities/valueFromASTUntyped.d.ts b/src/utilities/valueFromASTUntyped.d.ts deleted file mode 100644 index e21fe785cb..0000000000 --- a/src/utilities/valueFromASTUntyped.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ObjMap } from '../jsutils/ObjMap'; -import type { Maybe } from '../jsutils/Maybe'; -import type { ValueNode } from '../language/ast'; -/** - * Produces a JavaScript value given a GraphQL Value AST. - * - * Unlike `valueFromAST()`, no type is provided. The resulting JavaScript value - * will reflect the provided GraphQL value AST. - * - * | GraphQL Value | JavaScript Value | - * | -------------------- | ---------------- | - * | Input Object | Object | - * | List | Array | - * | Boolean | Boolean | - * | String / Enum | String | - * | Int / Float | Number | - * | Null | null | - * - */ -export function valueFromASTUntyped( - valueNode: ValueNode, - variables?: Maybe>, -): unknown; diff --git a/src/utilities/valueFromASTUntyped.js b/src/utilities/valueFromASTUntyped.ts similarity index 91% rename from src/utilities/valueFromASTUntyped.js rename to src/utilities/valueFromASTUntyped.ts index 05f5db71b2..c3e2e92e49 100644 --- a/src/utilities/valueFromASTUntyped.js +++ b/src/utilities/valueFromASTUntyped.ts @@ -2,6 +2,7 @@ import type { ObjMap } from '../jsutils/ObjMap'; import { inspect } from '../jsutils/inspect'; import { invariant } from '../jsutils/invariant'; import { keyValMap } from '../jsutils/keyValMap'; +import type { Maybe } from '../jsutils/Maybe'; import { Kind } from '../language/kinds'; import type { ValueNode } from '../language/ast'; @@ -24,8 +25,8 @@ import type { ValueNode } from '../language/ast'; */ export function valueFromASTUntyped( valueNode: ValueNode, - variables?: ?ObjMap, -): mixed { + variables?: Maybe>, +): unknown { switch (valueNode.kind) { case Kind.NULL: return null; @@ -52,5 +53,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)); } diff --git a/src/validation/ValidationContext.d.ts b/src/validation/ValidationContext.d.ts deleted file mode 100644 index ce14c494e9..0000000000 --- a/src/validation/ValidationContext.d.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import type { GraphQLError } from '../error/GraphQLError'; -import type { ASTVisitor } from '../language/visitor'; -import type { - DocumentNode, - OperationDefinitionNode, - VariableNode, - SelectionSetNode, - FragmentSpreadNode, - FragmentDefinitionNode, -} from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import type { GraphQLDirective } from '../type/directives'; -import type { - GraphQLInputType, - GraphQLOutputType, - GraphQLCompositeType, - GraphQLField, - GraphQLArgument, - GraphQLEnumValue, -} from '../type/definition'; -import { TypeInfo } from '../utilities/TypeInfo'; -type NodeWithSelectionSet = OperationDefinitionNode | FragmentDefinitionNode; -interface VariableUsage { - readonly node: VariableNode; - readonly type: Maybe; - readonly defaultValue: Maybe; -} -/** - * An instance of this class is passed as the "this" context to all validators, - * allowing access to commonly useful contextual information from within a - * validation rule. - */ -export class ASTValidationContext { - private _ast; - private _onError; - private _fragments; - private _fragmentSpreads; - private _recursivelyReferencedFragments; - constructor(ast: DocumentNode, onError: (error: GraphQLError) => void); - reportError(error: GraphQLError): void; - getDocument(): DocumentNode; - getFragment(name: string): Maybe; - getFragmentSpreads(node: SelectionSetNode): ReadonlyArray; - getRecursivelyReferencedFragments( - operation: OperationDefinitionNode, - ): ReadonlyArray; -} -export type ASTValidationRule = (context: ASTValidationContext) => ASTVisitor; -export class SDLValidationContext extends ASTValidationContext { - private _schema; - constructor( - ast: DocumentNode, - schema: Maybe, - onError: (error: GraphQLError) => void, - ); - getSchema(): Maybe; -} -export type SDLValidationRule = (context: SDLValidationContext) => ASTVisitor; -export class ValidationContext extends ASTValidationContext { - private _schema; - private _typeInfo; - private _variableUsages; - private _recursiveVariableUsages; - constructor( - schema: GraphQLSchema, - ast: DocumentNode, - typeInfo: TypeInfo, - onError: (error: GraphQLError) => void, - ); - getSchema(): GraphQLSchema; - getVariableUsages(node: NodeWithSelectionSet): ReadonlyArray; - getRecursiveVariableUsages( - operation: OperationDefinitionNode, - ): ReadonlyArray; - getType(): Maybe; - getParentType(): Maybe; - getInputType(): Maybe; - getParentInputType(): Maybe; - getFieldDef(): Maybe>; - getDirective(): Maybe; - getArgument(): Maybe; - getEnumValue(): Maybe; -} -export type ValidationRule = (context: ValidationContext) => ASTVisitor; diff --git a/src/validation/ValidationContext.js b/src/validation/ValidationContext.ts similarity index 78% rename from src/validation/ValidationContext.js rename to src/validation/ValidationContext.ts index ece2c0a62f..0479318b2a 100644 --- a/src/validation/ValidationContext.js +++ b/src/validation/ValidationContext.ts @@ -1,3 +1,4 @@ +import type { Maybe } from '../jsutils/Maybe'; import type { ObjMap } from '../jsutils/ObjMap'; import type { GraphQLError } from '../error/GraphQLError'; @@ -29,11 +30,11 @@ import type { import { TypeInfo, visitWithTypeInfo } from '../utilities/TypeInfo'; type NodeWithSelectionSet = OperationDefinitionNode | FragmentDefinitionNode; -type VariableUsage = { - +node: VariableNode, - +type: ?GraphQLInputType, - +defaultValue: ?mixed, -}; +interface VariableUsage { + readonly node: VariableNode; + readonly type: Maybe; + readonly defaultValue: Maybe; +} /** * An instance of this class is passed as the "this" context to all validators, @@ -41,13 +42,17 @@ type VariableUsage = { * validation rule. */ export class ASTValidationContext { - _ast: DocumentNode; - _onError: (error: GraphQLError) => void; - _fragments: ?ObjMap; - _fragmentSpreads: Map>; - _recursivelyReferencedFragments: Map< + private _ast: DocumentNode; + private _onError: (error: GraphQLError) => void; + private _fragments: Maybe>; + private _fragmentSpreads: Map< + SelectionSetNode, + ReadonlyArray + >; + + private _recursivelyReferencedFragments: Map< OperationDefinitionNode, - $ReadOnlyArray, + ReadonlyArray >; constructor(ast: DocumentNode, onError: (error: GraphQLError) => void) { @@ -66,7 +71,7 @@ export class ASTValidationContext { return this._ast; } - getFragment(name: string): ?FragmentDefinitionNode { + getFragment(name: string): Maybe { if (!this._fragments) { const fragments = (this._fragments = Object.create(null)); for (const defNode of this.getDocument().definitions) { @@ -80,7 +85,7 @@ export class ASTValidationContext { getFragmentSpreads( node: SelectionSetNode, - ): $ReadOnlyArray { + ): ReadonlyArray { let spreads = this._fragmentSpreads.get(node); if (!spreads) { spreads = []; @@ -89,6 +94,7 @@ export class ASTValidationContext { const set = setsToVisit.pop(); for (const selection of set.selections) { if (selection.kind === Kind.FRAGMENT_SPREAD) { + // @ts-expect-error FIXME: TS Conversion spreads.push(selection); } else if (selection.selectionSet) { setsToVisit.push(selection.selectionSet); @@ -102,7 +108,7 @@ export class ASTValidationContext { getRecursivelyReferencedFragments( operation: OperationDefinitionNode, - ): $ReadOnlyArray { + ): ReadonlyArray { let fragments = this._recursivelyReferencedFragments.get(operation); if (!fragments) { fragments = []; @@ -116,6 +122,7 @@ export class ASTValidationContext { collectedNames[fragName] = true; const fragment = this.getFragment(fragName); if (fragment) { + // @ts-expect-error FIXME: TS Conversion fragments.push(fragment); nodesToVisit.push(fragment.selectionSet); } @@ -131,18 +138,18 @@ export class ASTValidationContext { export type ASTValidationRule = (context: ASTValidationContext) => ASTVisitor; export class SDLValidationContext extends ASTValidationContext { - _schema: ?GraphQLSchema; + private _schema: Maybe; constructor( ast: DocumentNode, - schema: ?GraphQLSchema, + schema: Maybe, onError: (error: GraphQLError) => void, ) { super(ast, onError); this._schema = schema; } - getSchema(): ?GraphQLSchema { + getSchema(): Maybe { return this._schema; } } @@ -150,12 +157,16 @@ export class SDLValidationContext extends ASTValidationContext { export type SDLValidationRule = (context: SDLValidationContext) => ASTVisitor; export class ValidationContext extends ASTValidationContext { - _schema: GraphQLSchema; - _typeInfo: TypeInfo; - _variableUsages: Map>; - _recursiveVariableUsages: Map< + private _schema: GraphQLSchema; + private _typeInfo: TypeInfo; + private _variableUsages: Map< + NodeWithSelectionSet, + ReadonlyArray + >; + + private _recursiveVariableUsages: Map< OperationDefinitionNode, - $ReadOnlyArray, + ReadonlyArray >; constructor( @@ -175,7 +186,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 = []; @@ -201,7 +212,7 @@ export class ValidationContext extends ASTValidationContext { getRecursiveVariableUsages( operation: OperationDefinitionNode, - ): $ReadOnlyArray { + ): ReadonlyArray { let usages = this._recursiveVariableUsages.get(operation); if (!usages) { usages = this.getVariableUsages(operation); @@ -213,35 +224,35 @@ export class ValidationContext extends ASTValidationContext { return usages; } - getType(): ?GraphQLOutputType { + getType(): Maybe { return this._typeInfo.getType(); } - getParentType(): ?GraphQLCompositeType { + getParentType(): Maybe { return this._typeInfo.getParentType(); } - getInputType(): ?GraphQLInputType { + getInputType(): Maybe { return this._typeInfo.getInputType(); } - getParentInputType(): ?GraphQLInputType { + getParentInputType(): Maybe { return this._typeInfo.getParentInputType(); } - getFieldDef(): ?GraphQLField { + getFieldDef(): Maybe> { return this._typeInfo.getFieldDef(); } - getDirective(): ?GraphQLDirective { + getDirective(): Maybe { return this._typeInfo.getDirective(); } - getArgument(): ?GraphQLArgument { + getArgument(): Maybe { return this._typeInfo.getArgument(); } - getEnumValue(): ?GraphQLEnumValue { + getEnumValue(): Maybe { return this._typeInfo.getEnumValue(); } } 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 100% rename from src/validation/__tests__/FieldsOnCorrectTypeRule-test.js rename to src/validation/__tests__/FieldsOnCorrectTypeRule-test.ts 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 100% rename from src/validation/__tests__/KnownArgumentNamesRule-test.js rename to src/validation/__tests__/KnownArgumentNamesRule-test.ts diff --git a/src/validation/__tests__/KnownDirectivesRule-test.js b/src/validation/__tests__/KnownDirectivesRule-test.ts similarity index 100% rename from src/validation/__tests__/KnownDirectivesRule-test.js rename to src/validation/__tests__/KnownDirectivesRule-test.ts 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 100% rename from src/validation/__tests__/KnownTypeNamesRule-test.js rename to src/validation/__tests__/KnownTypeNamesRule-test.ts 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 100% rename from src/validation/__tests__/LoneSchemaDefinitionRule-test.js rename to src/validation/__tests__/LoneSchemaDefinitionRule-test.ts 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 100% rename from src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.js rename to src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.ts 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 100% rename from src/validation/__tests__/PossibleTypeExtensionsRule-test.js rename to src/validation/__tests__/PossibleTypeExtensionsRule-test.ts diff --git a/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.js b/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts similarity index 100% rename from src/validation/__tests__/ProvidedRequiredArgumentsRule-test.js rename to src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts 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 100% rename from src/validation/__tests__/UniqueDirectiveNamesRule-test.js rename to src/validation/__tests__/UniqueDirectiveNamesRule-test.ts diff --git a/src/validation/__tests__/UniqueDirectivesPerLocationRule-test.js b/src/validation/__tests__/UniqueDirectivesPerLocationRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueDirectivesPerLocationRule-test.js rename to src/validation/__tests__/UniqueDirectivesPerLocationRule-test.ts diff --git a/src/validation/__tests__/UniqueEnumValueNamesRule-test.js b/src/validation/__tests__/UniqueEnumValueNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueEnumValueNamesRule-test.js rename to src/validation/__tests__/UniqueEnumValueNamesRule-test.ts diff --git a/src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.js b/src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.js rename to src/validation/__tests__/UniqueFieldDefinitionNamesRule-test.ts 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 100% rename from src/validation/__tests__/UniqueOperationTypesRule-test.js rename to src/validation/__tests__/UniqueOperationTypesRule-test.ts diff --git a/src/validation/__tests__/UniqueTypeNamesRule-test.js b/src/validation/__tests__/UniqueTypeNamesRule-test.ts similarity index 100% rename from src/validation/__tests__/UniqueTypeNamesRule-test.js rename to src/validation/__tests__/UniqueTypeNamesRule-test.ts 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 b22f757841..711ea91a6e 100644 --- a/src/validation/__tests__/harness.js +++ b/src/validation/__tests__/harness.ts @@ -1,5 +1,7 @@ import { expect } from 'chai'; +import type { Maybe } from '../../jsutils/Maybe'; + import { parse } from '../../language/parser'; import type { GraphQLSchema } from '../../type/schema'; @@ -160,7 +162,7 @@ export function expectValidationErrors( } export function expectSDLValidationErrors( - schema: ?GraphQLSchema, + schema: Maybe, rule: SDLValidationRule, sdlStr: string, ): any { diff --git a/src/validation/__tests__/validation-test.js b/src/validation/__tests__/validation-test.ts similarity index 99% rename from src/validation/__tests__/validation-test.js rename to src/validation/__tests__/validation-test.ts index d2eb64bbb1..a015bb9bd4 100644 --- a/src/validation/__tests__/validation-test.js +++ b/src/validation/__tests__/validation-test.ts @@ -15,7 +15,6 @@ import { testSchema } from './harness'; describe('Validate: Supports full validation', () => { it('rejects invalid documents', () => { - // $FlowExpectedError[incompatible-call] expect(() => validate(testSchema, null)).to.throw('Must provide document.'); }); diff --git a/src/validation/index.d.ts b/src/validation/index.d.ts deleted file mode 100644 index f06ebaeadf..0000000000 --- a/src/validation/index.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -export { validate } from './validate'; -export { ValidationContext } from './ValidationContext'; -export type { ValidationRule } from './ValidationContext'; -/** All validation rules in the GraphQL Specification. */ -export { specifiedRules } from './specifiedRules'; -/** Spec Section: "Executable Definitions" */ -export { ExecutableDefinitionsRule } from './rules/ExecutableDefinitionsRule'; -/** Spec Section: "Field Selections on Objects, Interfaces, and Unions Types" */ -export { FieldsOnCorrectTypeRule } from './rules/FieldsOnCorrectTypeRule'; -/** Spec Section: "Fragments on Composite Types" */ -export { FragmentsOnCompositeTypesRule } from './rules/FragmentsOnCompositeTypesRule'; -/** Spec Section: "Argument Names" */ -export { KnownArgumentNamesRule } from './rules/KnownArgumentNamesRule'; -/** Spec Section: "Directives Are Defined" */ -export { KnownDirectivesRule } from './rules/KnownDirectivesRule'; -/** Spec Section: "Fragment spread target defined" */ -export { KnownFragmentNamesRule } from './rules/KnownFragmentNamesRule'; -/** Spec Section: "Fragment Spread Type Existence" */ -export { KnownTypeNamesRule } from './rules/KnownTypeNamesRule'; -/** Spec Section: "Lone Anonymous Operation" */ -export { LoneAnonymousOperationRule } from './rules/LoneAnonymousOperationRule'; -/** Spec Section: "Fragments must not form cycles" */ -export { NoFragmentCyclesRule } from './rules/NoFragmentCyclesRule'; -/** Spec Section: "All Variable Used Defined" */ -export { NoUndefinedVariablesRule } from './rules/NoUndefinedVariablesRule'; -/** Spec Section: "Fragments must be used" */ -export { NoUnusedFragmentsRule } from './rules/NoUnusedFragmentsRule'; -/** Spec Section: "All Variables Used" */ -export { NoUnusedVariablesRule } from './rules/NoUnusedVariablesRule'; -/** Spec Section: "Field Selection Merging" */ -export { OverlappingFieldsCanBeMergedRule } from './rules/OverlappingFieldsCanBeMergedRule'; -/** Spec Section: "Fragment spread is possible" */ -export { PossibleFragmentSpreadsRule } from './rules/PossibleFragmentSpreadsRule'; -/** Spec Section: "Argument Optionality" */ -export { ProvidedRequiredArgumentsRule } from './rules/ProvidedRequiredArgumentsRule'; -/** Spec Section: "Leaf Field Selections" */ -export { ScalarLeafsRule } from './rules/ScalarLeafsRule'; -/** Spec Section: "Subscriptions with Single Root Field" */ -export { SingleFieldSubscriptionsRule } from './rules/SingleFieldSubscriptionsRule'; -/** Spec Section: "Argument Uniqueness" */ -export { UniqueArgumentNamesRule } from './rules/UniqueArgumentNamesRule'; -/** Spec Section: "Directives Are Unique Per Location" */ -export { UniqueDirectivesPerLocationRule } from './rules/UniqueDirectivesPerLocationRule'; -/** Spec Section: "Fragment Name Uniqueness" */ -export { UniqueFragmentNamesRule } from './rules/UniqueFragmentNamesRule'; -/** Spec Section: "Input Object Field Uniqueness" */ -export { UniqueInputFieldNamesRule } from './rules/UniqueInputFieldNamesRule'; -/** Spec Section: "Operation Name Uniqueness" */ -export { UniqueOperationNamesRule } from './rules/UniqueOperationNamesRule'; -/** Spec Section: "Variable Uniqueness" */ -export { UniqueVariableNamesRule } from './rules/UniqueVariableNamesRule'; -/** Spec Section: "Values Type Correctness" */ -export { ValuesOfCorrectTypeRule } from './rules/ValuesOfCorrectTypeRule'; -/** Spec Section: "Variables are Input Types" */ -export { VariablesAreInputTypesRule } from './rules/VariablesAreInputTypesRule'; -/** Spec Section: "All Variable Usages Are Allowed" */ -export { VariablesInAllowedPositionRule } from './rules/VariablesInAllowedPositionRule'; -/** SDL-specific validation rules */ -export { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule'; -export { UniqueOperationTypesRule } from './rules/UniqueOperationTypesRule'; -export { UniqueTypeNamesRule } from './rules/UniqueTypeNamesRule'; -export { UniqueEnumValueNamesRule } from './rules/UniqueEnumValueNamesRule'; -export { UniqueFieldDefinitionNamesRule } from './rules/UniqueFieldDefinitionNamesRule'; -export { UniqueDirectiveNamesRule } from './rules/UniqueDirectiveNamesRule'; -export { PossibleTypeExtensionsRule } from './rules/PossibleTypeExtensionsRule'; -/** Optional rules not defined by the GraphQL Specification */ -export { NoDeprecatedCustomRule } from './rules/custom/NoDeprecatedCustomRule'; -export { NoSchemaIntrospectionCustomRule } from './rules/custom/NoSchemaIntrospectionCustomRule'; diff --git a/src/validation/index.js b/src/validation/index.ts similarity index 100% rename from src/validation/index.js rename to src/validation/index.ts diff --git a/src/validation/rules/ExecutableDefinitionsRule.d.ts b/src/validation/rules/ExecutableDefinitionsRule.d.ts deleted file mode 100644 index 6ac3795676..0000000000 --- a/src/validation/rules/ExecutableDefinitionsRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Executable definitions - * - * A GraphQL document is only valid for execution if all definitions are either - * operation or fragment definitions. - */ -export function ExecutableDefinitionsRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/ExecutableDefinitionsRule.js b/src/validation/rules/ExecutableDefinitionsRule.ts similarity index 100% rename from src/validation/rules/ExecutableDefinitionsRule.js rename to src/validation/rules/ExecutableDefinitionsRule.ts diff --git a/src/validation/rules/FieldsOnCorrectTypeRule.d.ts b/src/validation/rules/FieldsOnCorrectTypeRule.d.ts deleted file mode 100644 index b0e22b3315..0000000000 --- a/src/validation/rules/FieldsOnCorrectTypeRule.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Fields on correct type - * - * A GraphQL document is only valid if all fields selected are defined by the - * parent type, or are an allowed meta field such as __typename. - */ -export function FieldsOnCorrectTypeRule(context: ValidationContext): ASTVisitor; diff --git a/src/validation/rules/FieldsOnCorrectTypeRule.js b/src/validation/rules/FieldsOnCorrectTypeRule.ts similarity index 100% rename from src/validation/rules/FieldsOnCorrectTypeRule.js rename to src/validation/rules/FieldsOnCorrectTypeRule.ts diff --git a/src/validation/rules/FragmentsOnCompositeTypesRule.d.ts b/src/validation/rules/FragmentsOnCompositeTypesRule.d.ts deleted file mode 100644 index 29495abee9..0000000000 --- a/src/validation/rules/FragmentsOnCompositeTypesRule.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Fragments on composite type - * - * Fragments use a type condition to determine if they apply, since fragments - * can only be spread into a composite type (object, interface, or union), the - * type condition must also be a composite type. - */ -export function FragmentsOnCompositeTypesRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/FragmentsOnCompositeTypesRule.js b/src/validation/rules/FragmentsOnCompositeTypesRule.ts similarity index 100% rename from src/validation/rules/FragmentsOnCompositeTypesRule.js rename to src/validation/rules/FragmentsOnCompositeTypesRule.ts diff --git a/src/validation/rules/KnownArgumentNamesRule.d.ts b/src/validation/rules/KnownArgumentNamesRule.d.ts deleted file mode 100644 index 97e98376a8..0000000000 --- a/src/validation/rules/KnownArgumentNamesRule.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; -/** - * Known argument names - * - * A GraphQL field is only valid if all supplied arguments are defined by - * that field. - */ -export function KnownArgumentNamesRule(context: ValidationContext): ASTVisitor; -/** - * @internal - */ -export function KnownArgumentNamesOnDirectivesRule( - context: ValidationContext | SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/KnownArgumentNamesRule.js b/src/validation/rules/KnownArgumentNamesRule.ts similarity index 100% rename from src/validation/rules/KnownArgumentNamesRule.js rename to src/validation/rules/KnownArgumentNamesRule.ts diff --git a/src/validation/rules/KnownDirectivesRule.d.ts b/src/validation/rules/KnownDirectivesRule.d.ts deleted file mode 100644 index dc1b57bf9b..0000000000 --- a/src/validation/rules/KnownDirectivesRule.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; -/** - * Known directives - * - * A GraphQL document is only valid if all `@directives` are known by the - * schema and legally positioned. - */ -export function KnownDirectivesRule( - context: ValidationContext | SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/KnownDirectivesRule.js b/src/validation/rules/KnownDirectivesRule.ts similarity index 93% rename from src/validation/rules/KnownDirectivesRule.js rename to src/validation/rules/KnownDirectivesRule.ts index 8c1e9191d1..7418e570e1 100644 --- a/src/validation/rules/KnownDirectivesRule.js +++ b/src/validation/rules/KnownDirectivesRule.ts @@ -68,13 +68,15 @@ export function KnownDirectivesRule( } function getDirectiveLocationForASTPath( - ancestors: $ReadOnlyArray>, -): DirectiveLocationEnum | void { + ancestors: ReadonlyArray>, +): DirectiveLocationEnum | undefined { const appliedTo = ancestors[ancestors.length - 1]; invariant(!Array.isArray(appliedTo)); + // @ts-expect-error FIXME: TS Conversion switch (appliedTo.kind) { case Kind.OPERATION_DEFINITION: + // @ts-expect-error FIXME: TS Conversion return getDirectiveLocationForOperation(appliedTo.operation); case Kind.FIELD: return DirectiveLocation.FIELD; @@ -113,6 +115,7 @@ function getDirectiveLocationForASTPath( return DirectiveLocation.INPUT_OBJECT; case Kind.INPUT_VALUE_DEFINITION: { const parentNode = ancestors[ancestors.length - 3]; + // @ts-expect-error FIXME: TS Conversion return parentNode.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION ? DirectiveLocation.INPUT_FIELD_DEFINITION : DirectiveLocation.ARGUMENT_DEFINITION; @@ -133,5 +136,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)); } diff --git a/src/validation/rules/KnownFragmentNamesRule.d.ts b/src/validation/rules/KnownFragmentNamesRule.d.ts deleted file mode 100644 index 2e4b18ddba..0000000000 --- a/src/validation/rules/KnownFragmentNamesRule.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Known fragment names - * - * A GraphQL document is only valid if all `...Fragment` fragment spreads refer - * to fragments defined in the same document. - */ -export function KnownFragmentNamesRule(context: ValidationContext): ASTVisitor; diff --git a/src/validation/rules/KnownFragmentNamesRule.js b/src/validation/rules/KnownFragmentNamesRule.ts similarity index 100% rename from src/validation/rules/KnownFragmentNamesRule.js rename to src/validation/rules/KnownFragmentNamesRule.ts diff --git a/src/validation/rules/KnownTypeNamesRule.d.ts b/src/validation/rules/KnownTypeNamesRule.d.ts deleted file mode 100644 index 3f9c17ada3..0000000000 --- a/src/validation/rules/KnownTypeNamesRule.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; -/** - * Known type names - * - * A GraphQL document is only valid if referenced types (specifically - * variable definitions and fragment conditions) are defined by the type schema. - */ -export function KnownTypeNamesRule( - context: ValidationContext | SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/KnownTypeNamesRule.js b/src/validation/rules/KnownTypeNamesRule.ts similarity index 95% rename from src/validation/rules/KnownTypeNamesRule.js rename to src/validation/rules/KnownTypeNamesRule.ts index 86046484d1..8593e9a5a2 100644 --- a/src/validation/rules/KnownTypeNamesRule.js +++ b/src/validation/rules/KnownTypeNamesRule.ts @@ -72,9 +72,10 @@ const standardTypeNames = [...specifiedScalarTypes, ...introspectionTypes].map( (type) => type.name, ); -function isSDLNode(value: ASTNode | $ReadOnlyArray): boolean { +function isSDLNode(value: ASTNode | ReadonlyArray): boolean { return ( !Array.isArray(value) && + // @ts-expect-error FIXME: TS Conversion (isTypeSystemDefinitionNode(value) || isTypeSystemExtensionNode(value)) ); } diff --git a/src/validation/rules/LoneAnonymousOperationRule.d.ts b/src/validation/rules/LoneAnonymousOperationRule.d.ts deleted file mode 100644 index be7510b70e..0000000000 --- a/src/validation/rules/LoneAnonymousOperationRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Lone anonymous operation - * - * A GraphQL document is only valid if when it contains an anonymous operation - * (the query short-hand) that it contains only that one operation definition. - */ -export function LoneAnonymousOperationRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/LoneAnonymousOperationRule.js b/src/validation/rules/LoneAnonymousOperationRule.ts similarity index 100% rename from src/validation/rules/LoneAnonymousOperationRule.js rename to src/validation/rules/LoneAnonymousOperationRule.ts diff --git a/src/validation/rules/LoneSchemaDefinitionRule.d.ts b/src/validation/rules/LoneSchemaDefinitionRule.d.ts deleted file mode 100644 index 2d7c2ed742..0000000000 --- a/src/validation/rules/LoneSchemaDefinitionRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Lone Schema definition - * - * A GraphQL document is only valid if it contains only one schema definition. - */ -export function LoneSchemaDefinitionRule( - context: SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/LoneSchemaDefinitionRule.js b/src/validation/rules/LoneSchemaDefinitionRule.ts similarity index 100% rename from src/validation/rules/LoneSchemaDefinitionRule.js rename to src/validation/rules/LoneSchemaDefinitionRule.ts diff --git a/src/validation/rules/NoFragmentCyclesRule.d.ts b/src/validation/rules/NoFragmentCyclesRule.d.ts deleted file mode 100644 index de3c3bedb1..0000000000 --- a/src/validation/rules/NoFragmentCyclesRule.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -export function NoFragmentCyclesRule(context: ASTValidationContext): ASTVisitor; diff --git a/src/validation/rules/NoFragmentCyclesRule.js b/src/validation/rules/NoFragmentCyclesRule.ts similarity index 100% rename from src/validation/rules/NoFragmentCyclesRule.js rename to src/validation/rules/NoFragmentCyclesRule.ts diff --git a/src/validation/rules/NoUndefinedVariablesRule.d.ts b/src/validation/rules/NoUndefinedVariablesRule.d.ts deleted file mode 100644 index 7eb5a29e15..0000000000 --- a/src/validation/rules/NoUndefinedVariablesRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * No undefined variables - * - * A GraphQL operation is only valid if all variables encountered, both directly - * and via fragment spreads, are defined by that operation. - */ -export function NoUndefinedVariablesRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/NoUndefinedVariablesRule.js b/src/validation/rules/NoUndefinedVariablesRule.ts similarity index 100% rename from src/validation/rules/NoUndefinedVariablesRule.js rename to src/validation/rules/NoUndefinedVariablesRule.ts diff --git a/src/validation/rules/NoUnusedFragmentsRule.d.ts b/src/validation/rules/NoUnusedFragmentsRule.d.ts deleted file mode 100644 index dc24956092..0000000000 --- a/src/validation/rules/NoUnusedFragmentsRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * No unused fragments - * - * A GraphQL document is only valid if all fragment definitions are spread - * within operations, or spread within other fragments spread within operations. - */ -export function NoUnusedFragmentsRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/NoUnusedFragmentsRule.js b/src/validation/rules/NoUnusedFragmentsRule.ts similarity index 100% rename from src/validation/rules/NoUnusedFragmentsRule.js rename to src/validation/rules/NoUnusedFragmentsRule.ts diff --git a/src/validation/rules/NoUnusedVariablesRule.d.ts b/src/validation/rules/NoUnusedVariablesRule.d.ts deleted file mode 100644 index ba0f2a5fc0..0000000000 --- a/src/validation/rules/NoUnusedVariablesRule.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * No unused variables - * - * A GraphQL operation is only valid if all variables defined by an operation - * are used, either directly or within a spread fragment. - */ -export function NoUnusedVariablesRule(context: ValidationContext): ASTVisitor; diff --git a/src/validation/rules/NoUnusedVariablesRule.js b/src/validation/rules/NoUnusedVariablesRule.ts similarity index 100% rename from src/validation/rules/NoUnusedVariablesRule.js rename to src/validation/rules/NoUnusedVariablesRule.ts diff --git a/src/validation/rules/OverlappingFieldsCanBeMergedRule.d.ts b/src/validation/rules/OverlappingFieldsCanBeMergedRule.d.ts deleted file mode 100644 index adf452f8c9..0000000000 --- a/src/validation/rules/OverlappingFieldsCanBeMergedRule.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Overlapping fields can be merged - * - * A selection set is only valid if all fields (including spreading any - * fragments) either correspond to distinct response names or can be merged - * without ambiguity. - */ -export function OverlappingFieldsCanBeMergedRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/OverlappingFieldsCanBeMergedRule.js b/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts similarity index 98% rename from src/validation/rules/OverlappingFieldsCanBeMergedRule.js rename to src/validation/rules/OverlappingFieldsCanBeMergedRule.ts index a203b0abef..2ae5468cbf 100644 --- a/src/validation/rules/OverlappingFieldsCanBeMergedRule.js +++ b/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts @@ -31,6 +31,8 @@ import { import { typeFromAST } from '../../utilities/typeFromAST'; +import type { Maybe } from '../../jsutils/Maybe'; + import type { ValidationContext } from '../ValidationContext'; function reasonMessage(reason: ConflictReasonMessage): string { @@ -97,7 +99,7 @@ type ConflictReasonMessage = string | Array; type NodeAndDef = [ GraphQLCompositeType, FieldNode, - ?GraphQLField, + Maybe>, ]; // Map of array of those. type NodeAndDefCollection = ObjMap>; @@ -164,7 +166,7 @@ function findConflictsWithinSelectionSet( context: ValidationContext, cachedFieldsAndFragmentNames, comparedFragmentPairs: PairSet, - parentType: ?GraphQLNamedType, + parentType: Maybe, selectionSet: SelectionSetNode, ): Array { const conflicts = []; @@ -367,9 +369,9 @@ function findConflictsBetweenSubSelectionSets( cachedFieldsAndFragmentNames, comparedFragmentPairs: PairSet, areMutuallyExclusive: boolean, - parentType1: ?GraphQLNamedType, + parentType1: Maybe, selectionSet1: SelectionSetNode, - parentType2: ?GraphQLNamedType, + parentType2: Maybe, selectionSet2: SelectionSetNode, ): Array { const conflicts = []; @@ -538,7 +540,7 @@ function findConflict( responseName: string, field1: NodeAndDef, field2: NodeAndDef, -): ?Conflict { +): Maybe { const [parentType1, node1, def1] = field1; const [parentType2, node2, def2] = field2; @@ -620,8 +622,8 @@ function findConflict( } function sameArguments( - arguments1: $ReadOnlyArray, - arguments2: $ReadOnlyArray, + arguments1: ReadonlyArray, + arguments2: ReadonlyArray, ): boolean { if (arguments1.length !== arguments2.length) { return false; @@ -676,7 +678,7 @@ function doTypesConflict( function getFieldsAndFragmentNames( context: ValidationContext, cachedFieldsAndFragmentNames, - parentType: ?GraphQLNamedType, + parentType: Maybe, selectionSet: SelectionSetNode, ): [NodeAndDefCollection, Array] { let cached = cachedFieldsAndFragmentNames.get(selectionSet); @@ -720,7 +722,7 @@ function getReferencedFieldsAndFragmentNames( function _collectFieldsAndFragmentNames( context: ValidationContext, - parentType: ?GraphQLNamedType, + parentType: Maybe, selectionSet: SelectionSetNode, nodeAndDefs, fragmentNames, @@ -766,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 { +): Maybe { if (conflicts.length > 0) { return [ [responseName, conflicts.map(([reason]) => reason)], diff --git a/src/validation/rules/PossibleFragmentSpreadsRule.d.ts b/src/validation/rules/PossibleFragmentSpreadsRule.d.ts deleted file mode 100644 index bb44787adc..0000000000 --- a/src/validation/rules/PossibleFragmentSpreadsRule.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Possible fragment spread - * - * A fragment spread is only valid if the type condition could ever possibly - * be true: if there is a non-empty intersection of the possible parent types, - * and possible types which pass the type condition. - */ -export function PossibleFragmentSpreadsRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/PossibleFragmentSpreadsRule.js b/src/validation/rules/PossibleFragmentSpreadsRule.ts similarity index 96% rename from src/validation/rules/PossibleFragmentSpreadsRule.js rename to src/validation/rules/PossibleFragmentSpreadsRule.ts index caf8575f22..d83355a99e 100644 --- a/src/validation/rules/PossibleFragmentSpreadsRule.js +++ b/src/validation/rules/PossibleFragmentSpreadsRule.ts @@ -1,4 +1,5 @@ import { inspect } from '../../jsutils/inspect'; +import type { Maybe } from '../../jsutils/Maybe'; import { GraphQLError } from '../../error/GraphQLError'; @@ -66,7 +67,7 @@ export function PossibleFragmentSpreadsRule( function getFragmentType( context: ValidationContext, name: string, -): ?GraphQLCompositeType { +): Maybe { const frag = context.getFragment(name); if (frag) { const type = typeFromAST(context.getSchema(), frag.typeCondition); diff --git a/src/validation/rules/PossibleTypeExtensionsRule.d.ts b/src/validation/rules/PossibleTypeExtensionsRule.d.ts deleted file mode 100644 index e79cb46a2e..0000000000 --- a/src/validation/rules/PossibleTypeExtensionsRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Possible type extension - * - * A type extension is only valid if the type is defined and has the same kind. - */ -export function PossibleTypeExtensionsRule( - context: SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/PossibleTypeExtensionsRule.js b/src/validation/rules/PossibleTypeExtensionsRule.ts similarity index 98% rename from src/validation/rules/PossibleTypeExtensionsRule.js rename to src/validation/rules/PossibleTypeExtensionsRule.ts index c342e20e87..ab7db3105b 100644 --- a/src/validation/rules/PossibleTypeExtensionsRule.js +++ b/src/validation/rules/PossibleTypeExtensionsRule.ts @@ -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)); } function extensionKindToTypeName(kind: KindEnum): string { diff --git a/src/validation/rules/ProvidedRequiredArgumentsRule.d.ts b/src/validation/rules/ProvidedRequiredArgumentsRule.d.ts deleted file mode 100644 index a9126c7d55..0000000000 --- a/src/validation/rules/ProvidedRequiredArgumentsRule.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { - ValidationContext, - SDLValidationContext, -} from '../ValidationContext'; -/** - * Provided required arguments - * - * A field or directive is only valid if all required (non-null without a - * default value) field arguments have been provided. - */ -export function ProvidedRequiredArgumentsRule( - context: ValidationContext, -): ASTVisitor; -/** - * @internal - */ -export function ProvidedRequiredArgumentsOnDirectivesRule( - context: ValidationContext | SDLValidationContext, -): ASTVisitor; 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 0ddc8f784d..e5c970d24f 100644 --- a/src/validation/rules/ProvidedRequiredArgumentsRule.js +++ b/src/validation/rules/ProvidedRequiredArgumentsRule.ts @@ -1,5 +1,6 @@ import { inspect } from '../../jsutils/inspect'; import { keyMap } from '../../jsutils/keyMap'; +import type { ObjMap } from '../../jsutils/ObjMap'; import { GraphQLError } from '../../error/GraphQLError'; @@ -10,6 +11,7 @@ import { print } from '../../language/printer'; import { specifiedDirectives } from '../../type/directives'; import { isType, isRequiredArgument } from '../../type/definition'; +import type { GraphQLArgument } from '../../type/definition'; import type { ValidationContext, @@ -62,7 +64,9 @@ export function ProvidedRequiredArgumentsRule( export function ProvidedRequiredArgumentsOnDirectivesRule( context: ValidationContext | SDLValidationContext, ): ASTVisitor { - const requiredArgsMap = Object.create(null); + const requiredArgsMap: ObjMap< + ObjMap + > = Object.create(null); const schema = context.getSchema(); const definedDirectives = schema?.getDirectives() ?? specifiedDirectives; diff --git a/src/validation/rules/ScalarLeafsRule.d.ts b/src/validation/rules/ScalarLeafsRule.d.ts deleted file mode 100644 index 109ce6cb0f..0000000000 --- a/src/validation/rules/ScalarLeafsRule.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Scalar leafs - * - * A GraphQL document is valid only if all leaf fields (fields without - * sub selections) are of scalar or enum types. - */ -export function ScalarLeafsRule(context: ValidationContext): ASTVisitor; diff --git a/src/validation/rules/ScalarLeafsRule.js b/src/validation/rules/ScalarLeafsRule.ts similarity index 100% rename from src/validation/rules/ScalarLeafsRule.js rename to src/validation/rules/ScalarLeafsRule.ts diff --git a/src/validation/rules/SingleFieldSubscriptionsRule.d.ts b/src/validation/rules/SingleFieldSubscriptionsRule.d.ts deleted file mode 100644 index 0c7c215f8b..0000000000 --- a/src/validation/rules/SingleFieldSubscriptionsRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Subscriptions must only include one field. - * - * A GraphQL subscription is valid only if it contains a single root field. - */ -export function SingleFieldSubscriptionsRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/SingleFieldSubscriptionsRule.js b/src/validation/rules/SingleFieldSubscriptionsRule.ts similarity index 100% rename from src/validation/rules/SingleFieldSubscriptionsRule.js rename to src/validation/rules/SingleFieldSubscriptionsRule.ts diff --git a/src/validation/rules/UniqueArgumentNamesRule.d.ts b/src/validation/rules/UniqueArgumentNamesRule.d.ts deleted file mode 100644 index 86ef5cddf1..0000000000 --- a/src/validation/rules/UniqueArgumentNamesRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Unique argument names - * - * A GraphQL field or directive is only valid if all supplied arguments are - * uniquely named. - */ -export function UniqueArgumentNamesRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueArgumentNamesRule.js b/src/validation/rules/UniqueArgumentNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueArgumentNamesRule.js rename to src/validation/rules/UniqueArgumentNamesRule.ts diff --git a/src/validation/rules/UniqueDirectiveNamesRule.d.ts b/src/validation/rules/UniqueDirectiveNamesRule.d.ts deleted file mode 100644 index 437cb0433b..0000000000 --- a/src/validation/rules/UniqueDirectiveNamesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Unique directive names - * - * A GraphQL document is only valid if all defined directives have unique names. - */ -export function UniqueDirectiveNamesRule( - context: SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueDirectiveNamesRule.js b/src/validation/rules/UniqueDirectiveNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueDirectiveNamesRule.js rename to src/validation/rules/UniqueDirectiveNamesRule.ts diff --git a/src/validation/rules/UniqueDirectivesPerLocationRule.d.ts b/src/validation/rules/UniqueDirectivesPerLocationRule.d.ts deleted file mode 100644 index fd3f0787d7..0000000000 --- a/src/validation/rules/UniqueDirectivesPerLocationRule.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { - SDLValidationContext, - ValidationContext, -} from '../ValidationContext'; -/** - * Unique directive names per location - * - * A GraphQL document is only valid if all non-repeatable directives at - * a given location are uniquely named. - */ -export function UniqueDirectivesPerLocationRule( - context: ValidationContext | SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueDirectivesPerLocationRule.js b/src/validation/rules/UniqueDirectivesPerLocationRule.ts similarity index 96% rename from src/validation/rules/UniqueDirectivesPerLocationRule.js rename to src/validation/rules/UniqueDirectivesPerLocationRule.ts index a21c081790..8bdff5de24 100644 --- a/src/validation/rules/UniqueDirectivesPerLocationRule.js +++ b/src/validation/rules/UniqueDirectivesPerLocationRule.ts @@ -48,6 +48,7 @@ export function UniqueDirectivesPerLocationRule( // them all, just listen for entering any node, and check to see if it // defines any directives. enter(node) { + // @ts-expect-error FIXME: TS Conversion if (node.directives == null) { return; } @@ -68,6 +69,7 @@ export function UniqueDirectivesPerLocationRule( seenDirectives = Object.create(null); } + // @ts-expect-error FIXME: TS Conversion for (const directive of node.directives) { const directiveName = directive.name.value; diff --git a/src/validation/rules/UniqueEnumValueNamesRule.d.ts b/src/validation/rules/UniqueEnumValueNamesRule.d.ts deleted file mode 100644 index 347716352d..0000000000 --- a/src/validation/rules/UniqueEnumValueNamesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Unique enum value names - * - * A GraphQL enum type is only valid if all its values are uniquely named. - */ -export function UniqueEnumValueNamesRule( - context: SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueEnumValueNamesRule.js b/src/validation/rules/UniqueEnumValueNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueEnumValueNamesRule.js rename to src/validation/rules/UniqueEnumValueNamesRule.ts diff --git a/src/validation/rules/UniqueFieldDefinitionNamesRule.d.ts b/src/validation/rules/UniqueFieldDefinitionNamesRule.d.ts deleted file mode 100644 index 62e533af7f..0000000000 --- a/src/validation/rules/UniqueFieldDefinitionNamesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Unique field definition names - * - * A GraphQL complex type is only valid if all its fields are uniquely named. - */ -export function UniqueFieldDefinitionNamesRule( - context: SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueFieldDefinitionNamesRule.js b/src/validation/rules/UniqueFieldDefinitionNamesRule.ts similarity index 95% rename from src/validation/rules/UniqueFieldDefinitionNamesRule.js rename to src/validation/rules/UniqueFieldDefinitionNamesRule.ts index f912a8489f..9ef1d50f5c 100644 --- a/src/validation/rules/UniqueFieldDefinitionNamesRule.js +++ b/src/validation/rules/UniqueFieldDefinitionNamesRule.ts @@ -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.d.ts b/src/validation/rules/UniqueFragmentNamesRule.d.ts deleted file mode 100644 index 819ecba118..0000000000 --- a/src/validation/rules/UniqueFragmentNamesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Unique fragment names - * - * A GraphQL document is only valid if all defined fragments have unique names. - */ -export function UniqueFragmentNamesRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueFragmentNamesRule.js b/src/validation/rules/UniqueFragmentNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueFragmentNamesRule.js rename to src/validation/rules/UniqueFragmentNamesRule.ts diff --git a/src/validation/rules/UniqueInputFieldNamesRule.d.ts b/src/validation/rules/UniqueInputFieldNamesRule.d.ts deleted file mode 100644 index 83c8250cc7..0000000000 --- a/src/validation/rules/UniqueInputFieldNamesRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Unique input field names - * - * A GraphQL input object value is only valid if all supplied fields are - * uniquely named. - */ -export function UniqueInputFieldNamesRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueInputFieldNamesRule.js b/src/validation/rules/UniqueInputFieldNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueInputFieldNamesRule.js rename to src/validation/rules/UniqueInputFieldNamesRule.ts diff --git a/src/validation/rules/UniqueOperationNamesRule.d.ts b/src/validation/rules/UniqueOperationNamesRule.d.ts deleted file mode 100644 index 380b8a3831..0000000000 --- a/src/validation/rules/UniqueOperationNamesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Unique operation names - * - * A GraphQL document is only valid if all defined operations have unique names. - */ -export function UniqueOperationNamesRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueOperationNamesRule.js b/src/validation/rules/UniqueOperationNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueOperationNamesRule.js rename to src/validation/rules/UniqueOperationNamesRule.ts diff --git a/src/validation/rules/UniqueOperationTypesRule.d.ts b/src/validation/rules/UniqueOperationTypesRule.d.ts deleted file mode 100644 index 17e8641cba..0000000000 --- a/src/validation/rules/UniqueOperationTypesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Unique operation types - * - * A GraphQL document is only valid if it has only one type per operation. - */ -export function UniqueOperationTypesRule( - context: SDLValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueOperationTypesRule.js b/src/validation/rules/UniqueOperationTypesRule.ts similarity index 100% rename from src/validation/rules/UniqueOperationTypesRule.js rename to src/validation/rules/UniqueOperationTypesRule.ts diff --git a/src/validation/rules/UniqueTypeNamesRule.d.ts b/src/validation/rules/UniqueTypeNamesRule.d.ts deleted file mode 100644 index 4e9e233d4e..0000000000 --- a/src/validation/rules/UniqueTypeNamesRule.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { SDLValidationContext } from '../ValidationContext'; -/** - * Unique type names - * - * A GraphQL document is only valid if all defined types have unique names. - */ -export function UniqueTypeNamesRule(context: SDLValidationContext): ASTVisitor; diff --git a/src/validation/rules/UniqueTypeNamesRule.js b/src/validation/rules/UniqueTypeNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueTypeNamesRule.js rename to src/validation/rules/UniqueTypeNamesRule.ts diff --git a/src/validation/rules/UniqueVariableNamesRule.d.ts b/src/validation/rules/UniqueVariableNamesRule.d.ts deleted file mode 100644 index 16383066f3..0000000000 --- a/src/validation/rules/UniqueVariableNamesRule.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ASTValidationContext } from '../ValidationContext'; -/** - * Unique variable names - * - * A GraphQL operation is only valid if all its variables are uniquely named. - */ -export function UniqueVariableNamesRule( - context: ASTValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/UniqueVariableNamesRule.js b/src/validation/rules/UniqueVariableNamesRule.ts similarity index 100% rename from src/validation/rules/UniqueVariableNamesRule.js rename to src/validation/rules/UniqueVariableNamesRule.ts diff --git a/src/validation/rules/ValuesOfCorrectTypeRule.d.ts b/src/validation/rules/ValuesOfCorrectTypeRule.d.ts deleted file mode 100644 index a90610e103..0000000000 --- a/src/validation/rules/ValuesOfCorrectTypeRule.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Value literals of correct type - * - * A GraphQL document is only valid if all value literals are of the type - * expected at their position. - */ -export function ValuesOfCorrectTypeRule(context: ValidationContext): ASTVisitor; diff --git a/src/validation/rules/ValuesOfCorrectTypeRule.js b/src/validation/rules/ValuesOfCorrectTypeRule.ts similarity index 100% rename from src/validation/rules/ValuesOfCorrectTypeRule.js rename to src/validation/rules/ValuesOfCorrectTypeRule.ts diff --git a/src/validation/rules/VariablesAreInputTypesRule.d.ts b/src/validation/rules/VariablesAreInputTypesRule.d.ts deleted file mode 100644 index ace31684f7..0000000000 --- a/src/validation/rules/VariablesAreInputTypesRule.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Variables are input types - * - * A GraphQL operation is only valid if all the variables it defines are of - * input types (scalar, enum, or input object). - */ -export function VariablesAreInputTypesRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/VariablesAreInputTypesRule.js b/src/validation/rules/VariablesAreInputTypesRule.ts similarity index 100% rename from src/validation/rules/VariablesAreInputTypesRule.js rename to src/validation/rules/VariablesAreInputTypesRule.ts diff --git a/src/validation/rules/VariablesInAllowedPositionRule.d.ts b/src/validation/rules/VariablesInAllowedPositionRule.d.ts deleted file mode 100644 index 6d121bb2fa..0000000000 --- a/src/validation/rules/VariablesInAllowedPositionRule.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { ASTVisitor } from '../../language/visitor'; -import type { ValidationContext } from '../ValidationContext'; -/** - * Variables passed to field arguments conform to type - */ -export function VariablesInAllowedPositionRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/VariablesInAllowedPositionRule.js b/src/validation/rules/VariablesInAllowedPositionRule.ts similarity index 96% rename from src/validation/rules/VariablesInAllowedPositionRule.js rename to src/validation/rules/VariablesInAllowedPositionRule.ts index 1070190876..bf4c8f8f7c 100644 --- a/src/validation/rules/VariablesInAllowedPositionRule.js +++ b/src/validation/rules/VariablesInAllowedPositionRule.ts @@ -1,4 +1,5 @@ import { inspect } from '../../jsutils/inspect'; +import type { Maybe } from '../../jsutils/Maybe'; import { GraphQLError } from '../../error/GraphQLError'; @@ -79,9 +80,9 @@ export function VariablesInAllowedPositionRule( function allowedVariableUsage( schema: GraphQLSchema, varType: GraphQLType, - varDefaultValue: ?ValueNode, + varDefaultValue: Maybe, locationType: GraphQLType, - locationDefaultValue: ?mixed, + locationDefaultValue: Maybe, ): boolean { if (isNonNullType(locationType) && !isNonNullType(varType)) { const hasNonNullVariableDefaultValue = diff --git a/src/validation/rules/custom/NoDeprecatedCustomRule.d.ts b/src/validation/rules/custom/NoDeprecatedCustomRule.d.ts deleted file mode 100644 index 46ed454fbb..0000000000 --- a/src/validation/rules/custom/NoDeprecatedCustomRule.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { ASTVisitor } from '../../../language/visitor'; -import type { ValidationContext } from '../../ValidationContext'; -/** - * No deprecated - * - * A GraphQL document is only valid if all selected fields and all used enum values have not been - * deprecated. - * - * Note: This rule is optional and is not part of the Validation section of the GraphQL - * Specification. The main purpose of this rule is detection of deprecated usages and not - * necessarily to forbid their use when querying a service. - */ -export function NoDeprecatedCustomRule(context: ValidationContext): ASTVisitor; diff --git a/src/validation/rules/custom/NoDeprecatedCustomRule.js b/src/validation/rules/custom/NoDeprecatedCustomRule.ts similarity index 98% rename from src/validation/rules/custom/NoDeprecatedCustomRule.js rename to src/validation/rules/custom/NoDeprecatedCustomRule.ts index fd86ff0975..38b688a203 100644 --- a/src/validation/rules/custom/NoDeprecatedCustomRule.js +++ b/src/validation/rules/custom/NoDeprecatedCustomRule.ts @@ -63,7 +63,6 @@ export function NoDeprecatedCustomRule(context: ValidationContext): ASTVisitor { const inputObjectDef = getNamedType(context.getParentInputType()); if (isInputObjectType(inputObjectDef)) { const inputFieldDef = inputObjectDef.getFields()[node.name.value]; - // flowlint-next-line unnecessary-optional-chain:off const deprecationReason = inputFieldDef?.deprecationReason; if (deprecationReason != null) { context.reportError( diff --git a/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.d.ts b/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.d.ts deleted file mode 100644 index 2f657236de..0000000000 --- a/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ASTVisitor } from '../../../language/visitor'; -import type { ValidationContext } from '../../ValidationContext'; -/** - * Prohibit introspection queries - * - * A GraphQL document is only valid if all fields selected are not fields that - * return an introspection type. - * - * Note: This rule is optional and is not part of the Validation section of the - * GraphQL Specification. This rule effectively disables introspection, which - * does not reflect best practices and should only be done if absolutely necessary. - */ -export function NoSchemaIntrospectionCustomRule( - context: ValidationContext, -): ASTVisitor; diff --git a/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.js b/src/validation/rules/custom/NoSchemaIntrospectionCustomRule.ts similarity index 100% rename from src/validation/rules/custom/NoSchemaIntrospectionCustomRule.js rename to src/validation/rules/custom/NoSchemaIntrospectionCustomRule.ts diff --git a/src/validation/specifiedRules.d.ts b/src/validation/specifiedRules.d.ts deleted file mode 100644 index 447d10f57e..0000000000 --- a/src/validation/specifiedRules.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ValidationRule, SDLValidationRule } from './ValidationContext'; -/** - * This set includes all validation rules defined by the GraphQL spec. - * - * The order of the rules in this list has been adjusted to lead to the - * most clear output when encountering multiple validation errors. - */ -export const specifiedRules: ReadonlyArray; -/** - * @internal - */ -export const specifiedSDLRules: ReadonlyArray; diff --git a/src/validation/specifiedRules.js b/src/validation/specifiedRules.ts similarity index 97% rename from src/validation/specifiedRules.js rename to src/validation/specifiedRules.ts index 1440f5b37a..083c9f63f5 100644 --- a/src/validation/specifiedRules.js +++ b/src/validation/specifiedRules.ts @@ -99,7 +99,7 @@ import { PossibleTypeExtensionsRule } from './rules/PossibleTypeExtensionsRule'; * The order of the rules in this list has been adjusted to lead to the * most clear output when encountering multiple validation errors. */ -export const specifiedRules: $ReadOnlyArray = Object.freeze([ +export const specifiedRules: ReadonlyArray = Object.freeze([ ExecutableDefinitionsRule, UniqueOperationNamesRule, LoneAnonymousOperationRule, @@ -131,7 +131,7 @@ export const specifiedRules: $ReadOnlyArray = Object.freeze([ /** * @internal */ -export const specifiedSDLRules: $ReadOnlyArray = +export const specifiedSDLRules: ReadonlyArray = Object.freeze([ LoneSchemaDefinitionRule, UniqueOperationTypesRule, diff --git a/src/validation/validate.d.ts b/src/validation/validate.d.ts deleted file mode 100644 index 732f40750f..0000000000 --- a/src/validation/validate.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { Maybe } from '../jsutils/Maybe'; -import { GraphQLError } from '../error/GraphQLError'; -import type { DocumentNode } from '../language/ast'; -import type { GraphQLSchema } from '../type/schema'; -import { TypeInfo } from '../utilities/TypeInfo'; -import type { SDLValidationRule, ValidationRule } from './ValidationContext'; -/** - * Implements the "Validation" section of the spec. - * - * Validation runs synchronously, returning an array of encountered errors, or - * an empty array if no errors were encountered and the document is valid. - * - * A list of specific validation rules may be provided. If not provided, the - * default list of rules defined by the GraphQL specification will be used. - * - * Each validation rules is a function which returns a visitor - * (see the language/visitor API). Visitor methods are expected to return - * GraphQLErrors, or Arrays of GraphQLErrors when invalid. - * - * Optionally a custom TypeInfo instance may be provided. If not provided, one - * will be created from the provided schema. - */ -export function validate( - schema: GraphQLSchema, - documentAST: DocumentNode, - rules?: ReadonlyArray, - options?: { - maxErrors?: number; - }, - /** @deprecate will be removed in 17.0.0 */ - typeInfo?: TypeInfo, -): ReadonlyArray; -/** - * @internal - */ -export function validateSDL( - documentAST: DocumentNode, - schemaToExtend?: Maybe, - rules?: ReadonlyArray, -): ReadonlyArray; -/** - * Utility function which asserts a SDL document is valid by throwing an error - * if it is invalid. - * - * @internal - */ -export function assertValidSDL(documentAST: DocumentNode): void; -/** - * Utility function which asserts a SDL document is valid by throwing an error - * if it is invalid. - * - * @internal - */ -export function assertValidSDLExtension( - documentAST: DocumentNode, - schema: GraphQLSchema, -): void; diff --git a/src/validation/validate.js b/src/validation/validate.ts similarity index 91% rename from src/validation/validate.js rename to src/validation/validate.ts index 14ecc0973e..5988115aae 100644 --- a/src/validation/validate.js +++ b/src/validation/validate.ts @@ -1,4 +1,5 @@ import { devAssert } from '../jsutils/devAssert'; +import type { Maybe } from '../jsutils/Maybe'; import { GraphQLError } from '../error/GraphQLError'; @@ -33,12 +34,12 @@ import { SDLValidationContext, ValidationContext } from './ValidationContext'; export function validate( schema: GraphQLSchema, documentAST: DocumentNode, - rules: $ReadOnlyArray = specifiedRules, + rules: ReadonlyArray = specifiedRules, options: { maxErrors?: number } = { maxErrors: undefined }, /** @deprecate will be removed in 17.0.0 */ typeInfo: TypeInfo = new TypeInfo(schema), -): $ReadOnlyArray { +): ReadonlyArray { devAssert(documentAST, 'Must provide document.'); // If the schema used for validation is invalid, throw an error. assertValidSchema(schema); @@ -56,6 +57,7 @@ export function validate( 'Too many validation errors, error limit reached. Validation aborted.', ), ); + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw abortObj; } errors.push(error); @@ -82,9 +84,9 @@ export function validate( */ export function validateSDL( documentAST: DocumentNode, - schemaToExtend?: ?GraphQLSchema, - rules: $ReadOnlyArray = specifiedSDLRules, -): $ReadOnlyArray { + schemaToExtend?: Maybe, + rules: ReadonlyArray = specifiedSDLRules, +): ReadonlyArray { const errors = []; const context = new SDLValidationContext( documentAST, diff --git a/src/version.d.ts b/src/version.d.ts deleted file mode 100644 index 675618f252..0000000000 --- a/src/version.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A string containing the version of the GraphQL.js library - */ -export const version: string; -/** - * An object containing the components of the GraphQL.js version string - */ -export const versionInfo: Readonly<{ - major: number; - minor: number; - patch: number; - preReleaseTag: string | null; -}>; 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 6db5760f10..d160d317ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,11 +4,10 @@ "module": "commonjs", "lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string"], "target": "es2019", - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, + "noImplicitAny": false, + "noImplicitThis": false, + "strictNullChecks": false, "strictFunctionTypes": true, - "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true }