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 63- `template` add an additional template to the defaults `gql` and `graphql` 64- `templateIsCallExpression` this tells our client that you are using `graphql('doc')` (default: true) 65 when using `false` it will look for tagged template literals 66- `shouldCheckForColocatedFragments` when turned on, this will scan your imports to find 67 unused fragments and provide a message notifying you about them (only works with call-expressions, default: true) 68- `trackFieldUsage` this only works with the client-preset, when turned on it will warn you about 69 unused fields within the same file. (only works with call-expressions, default: true) 70- `tadaOutputLocation` when using `gql.tada` this can be convenient as it automatically generates 71 an `introspection.ts` file for you, just give it the directory to output to and you're done 72- `tadaDisablePreprocessing` this setting disables the optimisation of `tadaOutput` to a pre-processed TypeScript type, this is off by default. 73- `clientDirectives` this setting allows you to specify additional `clientDirectives` which won't be seen as a missing schema-directive. 74 75## Tracking unused fields 76 77Currently the tracking unused fields feature has a few caveats with regards to tracking, first and foremost 78it will only track the result and the accessed properties in the same file to encourage 79[fragment co-location](https://www.apollographql.com/docs/react/data/fragments/#colocating-fragments). 80 81Secondly, we don't track mutations/subscriptions as some folks will add additional fields to properly support 82normalised cache updates. 83 84## Fragment masking 85 86When we use a `useQuery` that supports `TypedDocumentNode` it will automatically pick up the typings 87from the `query` you provide it. However for fragments this could become a bit more troublesome, the 88minimal way of providing typings for a fragment would be the following: 89 90```tsx 91import { TypedDocumentNode } from '@graphql-typed-document-node/core'; 92 93export const PokemonFields = gql` 94 fragment pokemonFields on Pokemon { 95 id 96 name 97 } 98` as typeof import('./Pokemon.generated').PokemonFieldsFragmentDoc; 99 100export const Pokemon = props => { 101 const pokemon = useFragment(props.pokemon, PokemonFields); 102}; 103 104export function useFragment<Type>( 105 data: any, 106 _fragment: TypedDocumentNode<Type> 107): Type { 108 return data; 109} 110``` 111 112This is mainly needed in cases where this isn't supported out of the box and mainly serves as a way 113for you to case your types. 114 115## 💙 [Sponsors](https://github.com/sponsors/urql-graphql) 116 117<table> 118 <tr> 119 <td align="center"><a href="https://bigcommerce.com/"><img src="https://avatars.githubusercontent.com/u/186342?s=150&v=4" width="150" alt="BigCommerce"/><br />BigCommerce</a></td> 120 <td align="center"><a href="https://wundergraph.com/"><img src="https://avatars.githubusercontent.com/u/64281914?s=200&v=4" width="150" alt="WunderGraph"/><br />WunderGraph</a></td> 121 <td align="center"><a href="https://the-guild.dev/"><img src="https://avatars.githubusercontent.com/u/42573040?s=200&v=4" width="150" alt="The Guild "/><br />The Guild</a></td> 122 </tr> 123</table> 124 125<table> 126 <tr> 127 <td align="center"><a href="https://beatgig.com/"><img src="https://avatars.githubusercontent.com/u/51333382?s=200&v=4" width="100" alt="BeatGig"/><br />BeatGig</a></td> 128 </tr> 129</table> 130 131## Local development 132 133Run `pnpm i` at the root. Open `packages/example` by running `code packages/example` or if you want to leverage 134breakpoints do it with the `TSS_DEBUG_BRK=9559` prefix. When you make changes in `packages/graphqlsp` all you need 135to do is run `pnpm i` in your other editor and restart the `TypeScript server` for the changes to apply. 136 137> Ensure that both instances of your editor are using the Workspace Version of TypeScript