Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.
1# GraphQLSP 2 3This is a TypeScript LSP Plugin that will recognise documents in your 4TypeScript code and help you out with hover-information, diagnostics and 5auto-complete. 6 7## Features 8 9- Hover information showing the decriptions of fields 10- Diagnostics for adding fields that don't exist, are deprecated, missmatched argument types, ... 11- Auto-complete inside your editor for fields 12- Will warn you when you are importing from a file that is exporting fragments that you're not using 13 14> Note that this plugin does not do syntax highlighting, for that you still need something like 15> [the VSCode/... plugin](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql-syntax) 16 17## Installation 18 19```sh 20npm install -D @0no-co/graphqlsp 21``` 22 23## Usage 24 25Go to your `tsconfig.json` and add 26 27```json 28{ 29 "compilerOptions": { 30 "plugins": [ 31 { 32 "name": "@0no-co/graphqlsp", 33 "schema": "./schema.graphql" 34 } 35 ] 36 } 37} 38``` 39 40now restart your TS-server and you should be good to go, ensure you are using the 41workspace version of TypeScript. In VSCode you can do so by clicking the bottom right 42when on a TypeScript file or adding a file like [this](https://github.com/0no-co/GraphQLSP/blob/main/packages/example/.vscode/settings.json). 43 44> If you are using VSCode ensure that your editor is using [the Workspace Version of TypeScript](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript) 45> this can be done by manually selecting it or adding a `.vscode/config.json` with the contents of 46> 47> ```json 48> { 49> "typescript.tsdk": "node_modules/typescript/lib", 50> "typescript.enablePromptUseWorkspaceTsdk": true 51> } 52> ``` 53 54### Configuration 55 56**Required** 57 58- `schema` allows you to specify a url, `.json` or `.graphql` file as your schema. If you need to specify headers for your introspection 59 you can opt into the object notation i.e. `{ "schema": { "url": "x", "headers": { "Authorization": "y" } }}` 60 61**Optional** 62- `template` add an additional template to the defaults `gql` and `graphql` 63- `templateIsCallExpression` this tells our client that you are using `graphql('doc')` (default: true) 64 when using `false` it will look for tagged template literals 65- `shouldCheckForColocatedFragments` when turned on, this will scan your imports to find 66 unused fragments and provide a message notifying you about them (only works with call-expressions, default: true) 67- `trackFieldUsage` this only works with the client-preset, when turned on it will warn you about 68 unused fields within the same file. (only works with call-expressions, default: true) 69- `tadaOutputLocation` when using `gql.tada` this can be convenient as it automatically generates 70 an `introspection.ts` file for you, just give it the directory to output to and you're done 71 72## Tracking unused fields 73 74Currently the tracking unused fields feature has a few caveats with regards to tracking, first and foremost 75it will only track the result and the accessed properties in the same file to encourage 76[fragment co-location](https://www.apollographql.com/docs/react/data/fragments/#colocating-fragments). 77 78Secondly, we don't track mutations/subscriptions as some folks will add additional fields to properly support 79normalised cache updates. 80 81## Fragment masking 82 83When we use a `useQuery` that supports `TypedDocumentNode` it will automatically pick up the typings 84from the `query` you provide it. However for fragments this could become a bit more troublesome, the 85minimal way of providing typings for a fragment would be the following: 86 87```tsx 88import { TypedDocumentNode } from '@graphql-typed-document-node/core'; 89 90export const PokemonFields = gql` 91 fragment pokemonFields on Pokemon { 92 id 93 name 94 } 95` as typeof import('./Pokemon.generated').PokemonFieldsFragmentDoc; 96 97export const Pokemon = props => { 98 const pokemon = useFragment(props.pokemon, PokemonFields); 99}; 100 101export function useFragment<Type>( 102 data: any, 103 _fragment: TypedDocumentNode<Type> 104): Type { 105 return data; 106} 107``` 108 109This is mainly needed in cases where this isn't supported out of the box and mainly serves as a way 110for you to case your types. 111 112## Local development 113 114Run `pnpm i` at the root. Open `packages/example` by running `code packages/example` or if you want to leverage 115breakpoints do it with the `TSS_DEBUG_BRK=9559` prefix. When you make changes in `packages/graphqlsp` all you need 116to do is run `pnpm i` in your other editor and restart the `TypeScript server` for the changes to apply. 117 118> Ensure that both instances of your editor are using the Workspace Version of TypeScript