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 74## Tracking unused fields 75 76Currently the tracking unused fields feature has a few caveats with regards to tracking, first and foremost 77it will only track the result and the accessed properties in the same file to encourage 78[fragment co-location](https://www.apollographql.com/docs/react/data/fragments/#colocating-fragments). 79 80Secondly, we don't track mutations/subscriptions as some folks will add additional fields to properly support 81normalised cache updates. 82 83## Fragment masking 84 85When we use a `useQuery` that supports `TypedDocumentNode` it will automatically pick up the typings 86from the `query` you provide it. However for fragments this could become a bit more troublesome, the 87minimal way of providing typings for a fragment would be the following: 88 89```tsx 90import { TypedDocumentNode } from '@graphql-typed-document-node/core'; 91 92export const PokemonFields = gql` 93 fragment pokemonFields on Pokemon { 94 id 95 name 96 } 97` as typeof import('./Pokemon.generated').PokemonFieldsFragmentDoc; 98 99export const Pokemon = props => { 100 const pokemon = useFragment(props.pokemon, PokemonFields); 101}; 102 103export function useFragment<Type>( 104 data: any, 105 _fragment: TypedDocumentNode<Type> 106): Type { 107 return data; 108} 109``` 110 111This is mainly needed in cases where this isn't supported out of the box and mainly serves as a way 112for you to case your types. 113 114## 💙 [Sponsors](https://github.com/sponsors/urql-graphql) 115 116<table> 117 <tr> 118 <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> 119 <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> 120 <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> 121 </tr> 122</table> 123 124<table> 125 <tr> 126 <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> 127 </tr> 128</table> 129 130## Local development 131 132Run `pnpm i` at the root. Open `packages/example` by running `code packages/example` or if you want to leverage 133breakpoints do it with the `TSS_DEBUG_BRK=9559` prefix. When you make changes in `packages/graphqlsp` all you need 134to do is run `pnpm i` in your other editor and restart the `TypeScript server` for the changes to apply. 135 136> Ensure that both instances of your editor are using the Workspace Version of TypeScript