Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

only when file is changed

+29 -2
+9 -1
example/src/index.generated.ts
··· 114 114 115 115 export type PokemonQuery = { __typename?: 'Query', pokemon?: { __typename?: 'Pokemon', id: string, name: string } | null }; 116 116 117 + export type DonkemonQueryVariables = Exact<{ 118 + id: Scalars['ID']; 119 + }>; 120 + 121 + 122 + export type DonkemonQuery = { __typename?: 'Query', pokemon?: { __typename?: 'Pokemon', id: string } | null }; 123 + 117 124 export const PokemonFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"pokemonFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Pokemon"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode<PokemonFieldsFragment, unknown>; 118 125 export const PokemonsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Pokemons"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pokemons"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode<PokemonsQuery, PokemonsQueryVariables>; 119 - export const PokemonDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Pokemon"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pokemon"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"StringValue","value":"1","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"pokemonFields"}}]}}]}},...PokemonFieldsFragmentDoc.definitions]} as unknown as DocumentNode<PokemonQuery, PokemonQueryVariables>; 126 + export const PokemonDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Pokemon"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pokemon"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"StringValue","value":"1","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"pokemonFields"}}]}}]}},...PokemonFieldsFragmentDoc.definitions]} as unknown as DocumentNode<PokemonQuery, PokemonQueryVariables>; 127 + export const DonkemonDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Donkemon"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pokemon"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode<DonkemonQuery, DonkemonQueryVariables>;
+8 -1
example/src/index.ts
··· 7 7 query Pokemons { 8 8 pokemons { 9 9 id 10 - name 10 + name 11 11 } 12 12 } 13 13 ··· 26 26 ${PokemonFields} 27 27 ` as typeof import('./index.generated').PokemonDocument 28 28 29 + const Donkemon = gql` 30 + query Donkemon ($id: ID!) { 31 + pokemon(id: $id) { 32 + id 33 + } 34 + } 35 + ` as typeof import('./index.generated').DonkemonDocument 29 36 const urqlClient = createClient({ 30 37 url: '', 31 38 exchanges: []
+12
src/index.ts
··· 2 2 import { isNoSubstitutionTemplateLiteral, ScriptElementKind, isIdentifier, isTaggedTemplateExpression, isToken, isTemplateExpression, isImportTypeNode, ImportTypeNode } from "typescript"; 3 3 import { getHoverInformation, getAutocompleteSuggestions, getDiagnostics, Diagnostic } from 'graphql-language-service' 4 4 import { parse, Kind, FragmentDefinitionNode, OperationDefinitionNode } from 'graphql' 5 + import fs from 'fs'; 5 6 6 7 import { Cursor } from "./cursor"; 7 8 import { loadSchema } from "./getSchema"; ··· 116 117 const nameParts = name.split('.'); 117 118 nameParts[nameParts.length - 1] = 'generated.ts' 118 119 parts[parts.length - 1] = nameParts.join('.') 120 + const contents = fs.readFileSync(filename, 'utf-8'); 121 + const currentText = source.getFullText(); 119 122 123 + if (contents !== currentText) { 124 + return [ 125 + ...newDiagnostics, 126 + ...originalDiagnostics 127 + ] 128 + } 129 + 120 130 generateTypedDocumentNodes(schema.current, parts.join('/'), texts.join('\n')).then(() => { 121 131 nodes.forEach((node, i) => { 122 132 const queryText = texts[i] || ''; 123 133 const parsed = parse(queryText); 124 134 const isFragment = parsed.definitions.every(x => x.kind === Kind.FRAGMENT_DEFINITION); 125 135 let name = ''; 136 + 126 137 if (isFragment) { 127 138 const fragmentNode = parsed.definitions[0] as FragmentDefinitionNode; 128 139 name = fragmentNode.name.value; ··· 214 225 isGlobalCompletion: false, 215 226 isMemberCompletion: false, 216 227 isNewIdentifierLocation: false, 228 + // TODO: check whether we can add descriptions to the entries 217 229 entries: [...suggestions.map(suggestion => ({ 218 230 kind: ScriptElementKind.variableElement, 219 231 name: suggestion.label,