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