Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@0no-co/graphqlsp

0no-co1.4mMIT1.12.16TypeScript support: included

TypeScript LSP plugin that finds GraphQL documents in your code and provides hints and auto-generates types.

GraphQL, TypeScript, LSP, Typed-document-node

readme

GraphQLSP

This is a TypeScript LSP Plugin that will recognise documents in your TypeScript code and help you out with hover-information, diagnostics and auto-complete.

Features

  • Hover information showing the decriptions of fields
  • Diagnostics for adding fields that don't exist, are deprecated, missmatched argument types, ...
  • Auto-complete inside your editor for fields
  • Will warn you when you are importing from a file that is exporting fragments that you're not using

Note that this plugin does not do syntax highlighting, for that you still need something like the VSCode/... plugin

Installation

npm install -D @0no-co/graphqlsp

Usage

Go to your tsconfig.json and add

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql"
      }
    ]
  }
}

now restart your TS-server and you should be good to go, ensure you are using the workspace version of TypeScript. In VSCode you can do so by clicking the bottom right when on a TypeScript file or adding a file like this.

If you are using VSCode ensure that your editor is using the Workspace Version of TypeScript this can be done by manually selecting it or adding a .vscode/config.json with the contents of

{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true
}

Configuration

Required

  • schema allows you to specify a url, .json or .graphql file as your schema. If you need to specify headers for your introspection you can opt into the object notation i.e. { "schema": { "url": "x", "headers": { "Authorization": "y" } }}

Optional

  • template add an additional template to the defaults gql and graphql
  • templateIsCallExpression this tells our client that you are using graphql('doc') (default: true) when using false it will look for tagged template literals
  • shouldCheckForColocatedFragments when turned on, this will scan your imports to find unused fragments and provide a message notifying you about them (only works with call-expressions, default: true)
  • trackFieldUsage this only works with the client-preset, when turned on it will warn you about unused fields within the same file. (only works with call-expressions, default: true)
  • tadaOutputLocation when using gql.tada this can be convenient as it automatically generates an introspection.ts file for you, just give it the directory to output to and you're done
  • tadaDisablePreprocessing this setting disables the optimisation of tadaOutput to a pre-processed TypeScript type, this is off by default.

Tracking unused fields

Currently the tracking unused fields feature has a few caveats with regards to tracking, first and foremost it will only track the result and the accessed properties in the same file to encourage fragment co-location.

Secondly, we don't track mutations/subscriptions as some folks will add additional fields to properly support normalised cache updates.

Fragment masking

When we use a useQuery that supports TypedDocumentNode it will automatically pick up the typings from the query you provide it. However for fragments this could become a bit more troublesome, the minimal way of providing typings for a fragment would be the following:

import { TypedDocumentNode } from '@graphql-typed-document-node/core';

export const PokemonFields = gql`
  fragment pokemonFields on Pokemon {
    id
    name
  }
` as typeof import('./Pokemon.generated').PokemonFieldsFragmentDoc;

export const Pokemon = props => {
  const pokemon = useFragment(props.pokemon, PokemonFields);
};

export function useFragment<Type>(
  data: any,
  _fragment: TypedDocumentNode<Type>
): Type {
  return data;
}

This is mainly needed in cases where this isn't supported out of the box and mainly serves as a way for you to case your types.

💙 Sponsors

BigCommerce
BigCommerce
WunderGraph
WunderGraph
The Guild
The Guild
BeatGig
BeatGig

Local development

Run pnpm i at the root. Open packages/example by running code packages/example or if you want to leverage breakpoints do it with the TSS_DEBUG_BRK=9559 prefix. When you make changes in packages/graphqlsp all you need to do is run pnpm i in your other editor and restart the TypeScript server for the changes to apply.

Ensure that both instances of your editor are using the Workspace Version of TypeScript

changelog

@0no-co/graphqlsp

1.12.16

Patch Changes

  • Extract inlined fragments for the non-tada route Submitted by @JoviDeCroock (See #360)

1.12.15

Patch Changes

  • Handle chained expressions while crawling scopes Submitted by @JoviDeCroock (See #356)

1.12.14

Patch Changes

  • Strip our internal @_unmask directive from fragment-definitions when creating hashes for persisted-operations Submitted by @JoviDeCroock (See #354)
  • Prevent resolution loop when resolving GraphQL fragments Submitted by @kitten (See #350)

1.12.13

Patch Changes

  • ⚠️ Fix wrong fileType diagnostic error when introspection is disabled Submitted by @FyndetNeo (See #348)

1.12.12

Patch Changes

  • Bail on dots, when there's one or two dots we are leading up to a fragment-spread and should avoid giving suggestions Submitted by @JoviDeCroock (See #344)

1.12.11

Patch Changes

  • ⚠️ Fixed duplicate fragments in persisted document hash generator Submitted by @felamaslen (See #342)

1.12.10

Patch Changes

  • ⚠️ Fix unexpected case of persisted calls resolving to undefined AST nodes Submitted by @kitten (See #337)

1.12.9

Patch Changes

  • Address potential crashes on malformed TypeScript AST input (such as missing function arguments where they were previously assumed to be passed) Submitted by @kitten (See #335)

1.12.8

Patch Changes

  • ⚠️ Fix schema derivation when using graphql.persisted, we used the wrong expression in the ast Submitted by @felamaslen (See #333)

1.12.7

Patch Changes

  • ⚠️ Fix nested fragment resolution during persisted traversal Submitted by @JoviDeCroock (See #330)

1.12.6

Patch Changes

  • Use resolved document text when generating the persisted hash Submitted by @felamaslen (See #327)

1.12.5

Patch Changes

  • Support property-access-chain in binary-expression assignment Submitted by @JoviDeCroock (See #324)

1.12.4

Patch Changes

  • ⚠️ Fix fragments not being resolved when they're assigned to a property on an arbitrary identifier as an identifier Submitted by @kitten (See #322)

1.12.3

Patch Changes

1.12.2

Patch Changes

  • Update graphql to variably support ^15.5.0 and include future support for v17. The graphql package is now marked as a peer dependency in addition to a regular dependency Submitted by @kitten (See #314)

1.12.1

Patch Changes

  • ⚠️ Fix schema name being determined incorrectly when calling graphql from namespace/property-access Submitted by @kitten (See #312)

1.12.0

Minor Changes

  • Add support for defining multiple indepenent schemas through a new config property called schemas, you can pass a config like the following:
    {
      "name": "@0no-co/graphqlsp",
      "schemas": [
        {
          "name": "pokemons",
          "schema": "./pokemons.graphql",
          "tadaOutputLocation": "./pokemons-introspection.d.ts"
        },
        {
          "name": "weather",
          "schema": "./weather.graphql",
          "tadaOutputLocation": "./weather-introspection.d.ts"
        }
      ]
    }
    The LSP will depending on what graphql() template you use figure out what API you are reaching out to. Submitted by @JoviDeCroock (See #303)
  • Expose findAllCallExpressions on @0no-co/graphqlsp/api Submitted by @kitten (See #308)
  • Expand support for gql.tada API. GraphQLSP will now recognize graphql()/graphql.persisted() calls regardless of variable naming and support more obscure usage patterns Submitted by @kitten (See #309)

1.11.0

Minor Changes

  • Add validation step to check that the persisted-operations hash has been updated when the document changes Submitted by @JoviDeCroock (See #301)

1.10.3

Patch Changes

  • Correctly identify unused fields on a fragment-definition, these have no parent to group by so we display them as unused leaves Submitted by @JoviDeCroock (See #299)

1.10.2

Patch Changes

  • ⚠️ Fix crash due to typeArguments being undefined Submitted by @JoviDeCroock (See #297)

1.10.1

Patch Changes

  • switch error message for missing operation-name to not allude to typegen Submitted by @JoviDeCroock (See #290)
  • Swap-write introspection file instead of overwriting it directly Submitted by @kitten (See #291)
  • ⚠️ Fix directives being misreported due to globally declared regex maintaining state Submitted by @JoviDeCroock (See #293)

1.10.0

Minor Changes

  • Support passing GraphQL documents by value to graphql.persisted’s second argument Submitted by @JoviDeCroock (See #287)

1.9.1

Patch Changes

1.9.0

Minor Changes

Patch Changes

  • Expose persisted helper to translate typeQuery to the corresponding document Submitted by @JoviDeCroock (See #284)

1.8.0

Minor Changes

  • Expose the init and getGraphQLDiagnostics methods Submitted by @JoviDeCroock (See #279)

Patch Changes

1.7.1

Patch Changes

  • Add typescript to peerDependencies Submitted by @kitten (See #275)

1.7.0

Minor Changes

  • Introduce option to pre-process the introspection file, this improves the performance of gql.tada. This will be enabled by default and can be turned off by leveraging tadaDisablePreprocessing: true in the tsconfig Submitted by @JoviDeCroock (See #273)

1.6.1

Patch Changes

  • ⚠️ Fix case where our fragments is an empty array Submitted by @JoviDeCroock (See #271)

1.6.0

Minor Changes

  • Leverage require.resolve when following tsconfig.extends so we support node_modules Submitted by @JoviDeCroock (See #266)

1.5.1

Patch Changes

1.5.0

Minor Changes

  • Add a bail for fieldUsage where we return a property from a function Submitted by @JoviDeCroock (See #260)

Patch Changes

  • Bubble up unused fields to their closest parent Submitted by @JoviDeCroock (See #258)

1.4.3

Patch Changes

  • Add support for alternative root directories, when your tsconfig does not define GraphQLSP we'll traverse up until we find the extends that does and resolve the schema from there Submitted by @JoviDeCroock (See #257)
  • Change setInterval to setTimeout Submitted by @JoviDeCroock (See #255)

1.4.2

Patch Changes

  • ⚠️ fix case where the hover-information would target the wrong TypeScript node by one character Submitted by @llllvvuu (See #244)
  • Update ESM build output to be written to a .mjs file extension rather than .js Submitted by @kitten (See #250)

1.4.1

Patch Changes

  • ⚠️ Fix unused fields detection not respecting field aliases in GraphQL documents Submitted by @kitten (See #238)

1.4.0

Minor Changes

  • Expand support of tracking field usage to more edge cases by matching a defined GraphQL document’s type against variables in-scope with said type Submitted by @kitten (See #235)

Patch Changes

  • Only warn for fragments that are exported Submitted by @JoviDeCroock (See #230)
  • ⚠️ Fix issue where a missing argument 2 for a call-expression would make us erase prior found fragment-definitions Submitted by @JoviDeCroock (See #233)

1.3.5

Patch Changes

  • Add bail for field-usage when we can't find anything Submitted by @JoviDeCroock (See #226)

1.3.4

Patch Changes

1.3.3

Patch Changes

1.3.2

Patch Changes

1.3.1

Patch Changes

  • ⚠️ Fix case for call-expression where index would go out of bounds due to fragments being external to the document. In tagged-templates we resolve this by adding it in to the original text Submitted by @JoviDeCroock (See #207)

1.3.0

Minor Changes

1.2.0

Minor Changes

  • support property assignment/objectAccessPattern Submitted by @JoviDeCroock (See #202)

1.1.2

Patch Changes

  • Automatically disable Prettier and ESLint on tadaOutputLocation output files Submitted by @kitten (See #199)

1.1.1

Patch Changes

  • Add @_unmask to known client directive list Submitted by @kitten (See #197)

1.1.0

Minor Changes

  • Add way to provide additional reserved keys for field-usage tracking by means of the reservedKeys config property which accepts an array of strings Submitted by @JoviDeCroock (See #195)

1.0.7

Patch Changes

  • Avoid bailing out of the cache for identical introspections Submitted by @JoviDeCroock (See #193)
  • Account for empty lines when asking for completions Submitted by @JoviDeCroock (See #191)

1.0.6

Patch Changes

  • Catch errors in field-usage as we have been seeing TS fail to resolve references Submitted by @JoviDeCroock (See #188)

1.0.5

Patch Changes

  • When creating a d.ts file, export the introspection type to make it reusable Submitted by @kitten (See #184)
  • Upgrade to @urql/introspection@1.0.3 Submitted by @kitten (See #185)

1.0.4

Patch Changes

  • When we have a query like the following

    query {
      pokemon(id: 1) {
        id
        name
      }
      pokemons {
        id
        fleeRate
      }
    }

    and we perform

    const Pokemons = () => {
      const [result] = useQuery({
        query: PokemonQuery,
      });
    
      return result.data.pokemons.map(pokemon => pokemon.fleeRate);
    };

    Then it will see pokemon the variable inside our function closure as an allowed field due to Query.pokemon this PR fixes that by refining our search algorithm to only include valid built paths. Submitted by @JoviDeCroock (See #182)

1.0.3

Patch Changes

  • Stop caching diagnostics for fragment imports and field-usage as these can be controlled externally Submitted by @JoviDeCroock (See #174)
  • Add fix for nonNullAssertion and using Array.at Submitted by @JoviDeCroock (See #177)

1.0.2

Patch Changes

  • Use @0no-co/graphql.web for better visit perf Submitted by @JoviDeCroock (See #172)

1.0.1

Patch Changes

1.0.0

Major Changes

  • Look for gql and graphql by default as well as change the default for call-expressions to true. If you are using TaggedTemplateExpressions you can migrate by adding the following to your tsconfig file
    {
      "plugins": [
        {
          "name": "@0no-co/graphqlsp",
          "schema": "...",
          "templateIsCallExpression": false
        }
      ]
    }
    Submitted by @JoviDeCroock (See #162)
  • Retire automatic typegen with tagged-templates, we encourage folks to either try out gql.tada or the client-preset Submitted by @JoviDeCroock (See #148)
  • Remove fragment-checking from tagged-templates due to issues with barrel-file exports and flip defaults for field usage and import tracking with call-expressions Submitted by @JoviDeCroock (See #166)

Minor Changes

  • Add option named tadaOutputLocation to automatically write the introspection.ts file Submitted by @JoviDeCroock (See #165)
  • Update build process to output typings and to bundle more dependencies Submitted by @kitten (See #167)
  • Use ts namespace passed to plugin by TypeScript instance, rather than re-requiring/importing it Submitted by @kitten (See #167)
  • Allow tadaOutputLocation to contain filename targets and switch between a .d.ts and .ts output mode Submitted by @kitten (See #169)

0.15.0

Minor Changes

0.14.1

Patch Changes

  • Check whether we are on the correct template tag Submitted by @JoviDeCroock (See #157)

0.14.0

Minor Changes

  • Warn when an import defines a fragment that is unused in the current file Submitted by @JoviDeCroock (See #152)

0.13.0

Minor Changes

  • Track field usage and warn when a field goes unused Submitted by @JoviDeCroock (See #146)

Patch Changes

0.12.1

Patch Changes

  • Upgrade TypeScript dependency, this would normally not result in a changeset but it had us remove the normal auto-complete and quick-info and only do that logic when ours ends up in no results Submitted by @JoviDeCroock (See #136)
  • Don't error on known client-side directives Submitted by @JoviDeCroock (See #144)

0.12.0

Minor Changes

  • Use our internal suggestions algo for better arugments and spread-suggestions Submitted by @JoviDeCroock (See #132)

Patch Changes

  • Add fragments to the cache-key when using call-expressions Submitted by @JoviDeCroock (See #134)

0.11.2

Patch Changes

  • ⚠️ Fix crash during fragment aggregation step Submitted by @JoviDeCroock (See #119)

0.11.1

Patch Changes

0.11.0

Minor Changes

  • Support the GraphQL Code Generator client preset Submitted by @JoviDeCroock (See #109)

0.10.1

Patch Changes

  • Resolve parsed AST nodes being interpolated into an operation Submitted by @JoviDeCroock (See #105)
  • add caching for gql-diagnostics Submitted by @JoviDeCroock (See #104)
  • Correctly bail when file has typescript errors Submitted by @JoviDeCroock (See #107)

0.10.0

Minor Changes

  • Change default config to not check for co-located fragments by default Submitted by @JoviDeCroock (See #99)

Patch Changes

  • Prevent duplicate async file-generation processes from happening Submitted by @JoviDeCroock (See #100)

0.9.2

Patch Changes

  • ⚠️ Fix setting shouldCheckForColocatedFragments to false falling back to true Submitted by @dan-lee (See #96)

0.9.1

Patch Changes

0.9.0

Minor Changes

0.8.0

Minor Changes

  • Allow specifying headers for fetching the introspection Submitted by @JoviDeCroock (See #87)

Patch Changes

  • Guard against no schema or errored codegen attempts Submitted by @JoviDeCroock (See #89)
  • catch more schema errors and improve logging Submitted by @JoviDeCroock (See #84)

0.7.4

Patch Changes

  • Correctly replace with identical replacement strings Submitted by @JoviDeCroock (See #82)
  • Account for offsets in auto-complete as well Submitted by @JoviDeCroock (See #81)
  • ⚠️ Fix quick-info getting offset by preceding fragments Submitted by @JoviDeCroock (See #78)

0.7.3

Patch Changes

  • Avoid polluting with diagnostics not in current file Submitted by @JoviDeCroock (See #73)

0.7.2

Patch Changes

  • ⚠️ Fix multiple selection-set updates Submitted by @JoviDeCroock (See #69)

0.7.1

Patch Changes

0.7.0

Minor Changes

0.6.2

Patch Changes

0.6.1

Patch Changes

  • Add nonOptionalTypename: true as this allows for easier type matching Submitted by @JoviDeCroock (See #60)

0.6.0

Minor Changes

  • Add new option named extraTypes which can be used to define an additional set of types to help with the scalar definitions Submitted by @JoviDeCroock (See #58)
  • Change avoidOptionals to false in the base type generation Submitted by @JoviDeCroock (See #58)

0.5.2

Patch Changes

  • dont perform file additions when we have ts-errors Submitted by @JoviDeCroock (See #56)

0.5.1

Patch Changes

  • First perform the graphqlsp operations and only after do the TypeScript ones, this to account for changed lines from semantic-diagnostics Submitted by @JoviDeCroock (See #53)

0.5.0

Minor Changes

  • Do not suggest fields/fragments/input vars that are already present Submitted by @TheMightyPenguin (See #48)

0.4.2

Patch Changes

0.4.1

Patch Changes

0.4.0

Minor Changes

  • Add a message diagnostic when we see an import from a file that has fragment exports we'll warn you when they are not imported, this because of the assumption that to use this file one would have to adhere to the data requirements of said file. You can choose to disable this setting by setting shouldCheckForColocatedFragments to false Submitted by @JoviDeCroock (See #42)

0.3.0

Minor Changes

  • only run the typescript plugin once to generate a set of types that we'll reference from our typescript-operations, this to reduce lengthy generated files Submitted by @JoviDeCroock (See #39)

0.2.1

Patch Changes

  • Bump the graphql-code-generator and graphiql-utils dependencies Submitted by @JoviDeCroock (See #35)

0.2.0

Minor Changes

  • Add ability to specify a URL for your schema, GraphQLSP will then fetch the introspection from the specified URL Submitted by @JoviDeCroock (See #26)
  • Display some documentation alongside fields and fragments, for fields it will show the documentation or the type and for fragmentSpreads the typeCondition will be displayed Submitted by @JoviDeCroock (See #31)

Patch Changes

  • Check the dirty state of the file an additional time to prevent writing to the file when the user types directly after saving Submitted by @JoviDeCroock (See #27)
  • Enforce the correct type on FragmentSpread suggestions Submitted by @JoviDeCroock (See #32)