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.

feat: add tada-output pre-processing (#273)

authored by

Jovi De Croock and committed by
GitHub
7aba1414 8542b146

+97 -586
+5
.changeset/proud-taxis-rhyme.md
··· 1 + --- 2 + '@0no-co/graphqlsp': minor 3 + --- 4 + 5 + Introduce option to pre-process the introspection file, this improves the performance of `gql.tada`. This will be enabled by default and can be turned off by leveraging `tadaDisablePreprocessing: true` in the `tsconfig`
+3 -1
README.md
··· 59 59 you can opt into the object notation i.e. `{ "schema": { "url": "x", "headers": { "Authorization": "y" } }}` 60 60 61 61 **Optional** 62 + 62 63 - `template` add an additional template to the defaults `gql` and `graphql` 63 64 - `templateIsCallExpression` this tells our client that you are using `graphql('doc')` (default: true) 64 65 when using `false` it will look for tagged template literals 65 66 - `shouldCheckForColocatedFragments` when turned on, this will scan your imports to find 66 67 unused fragments and provide a message notifying you about them (only works with call-expressions, default: true) 67 68 - `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 + unused fields within the same file. (only works with call-expressions, default: true) 69 70 - `tadaOutputLocation` when using `gql.tada` this can be convenient as it automatically generates 70 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. 71 73 72 74 ## Tracking unused fields 73 75
+38
packages/example-tada/introspection.d.ts
··· 1 + /* eslint-disable */ 2 + /* prettier-ignore */ 3 + 4 + /** An IntrospectionQuery representation of your schema. 5 + * 6 + * @remarks 7 + * This is an introspection of your schema saved as a file by GraphQLSP. 8 + * It will automatically be used by `gql.tada` to infer the types of your GraphQL documents. 9 + * If you need to reuse this data or update your `scalars`, update `tadaOutputLocation` to 10 + * instead save to a .ts instead of a .d.ts file. 11 + */ 12 + export type introspection = { 13 + query: 'Query'; 14 + mutation: never; 15 + subscription: never; 16 + types: { 17 + 'Attack': { kind: 'OBJECT'; name: 'Attack'; fields: { 'damage': { name: 'damage'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'type': { name: 'type'; type: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; } }; }; }; 18 + 'Int': unknown; 19 + 'String': unknown; 20 + 'AttacksConnection': { kind: 'OBJECT'; name: 'AttacksConnection'; fields: { 'fast': { name: 'fast'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Attack'; ofType: null; }; } }; 'special': { name: 'special'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Attack'; ofType: null; }; } }; }; }; 21 + 'EvolutionRequirement': { kind: 'OBJECT'; name: 'EvolutionRequirement'; fields: { 'amount': { name: 'amount'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; 22 + 'Pokemon': { kind: 'OBJECT'; name: 'Pokemon'; fields: { 'attacks': { name: 'attacks'; type: { kind: 'OBJECT'; name: 'AttacksConnection'; ofType: null; } }; 'classification': { name: 'classification'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'evolutionRequirements': { name: 'evolutionRequirements'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'EvolutionRequirement'; ofType: null; }; } }; 'evolutions': { name: 'evolutions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Pokemon'; ofType: null; }; } }; 'fleeRate': { name: 'fleeRate'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'height': { name: 'height'; type: { kind: 'OBJECT'; name: 'PokemonDimension'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'maxCP': { name: 'maxCP'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'maxHP': { name: 'maxHP'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'resistant': { name: 'resistant'; type: { kind: 'LIST'; name: never; ofType: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; }; } }; 'types': { name: 'types'; type: { kind: 'LIST'; name: never; ofType: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; }; } }; 'weaknesses': { name: 'weaknesses'; type: { kind: 'LIST'; name: never; ofType: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; }; } }; 'weight': { name: 'weight'; type: { kind: 'OBJECT'; name: 'PokemonDimension'; ofType: null; } }; }; }; 23 + 'Float': unknown; 24 + 'ID': unknown; 25 + 'PokemonDimension': { kind: 'OBJECT'; name: 'PokemonDimension'; fields: { 'maximum': { name: 'maximum'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'minimum': { name: 'minimum'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; 26 + 'PokemonType': { kind: 'ENUM'; name: 'PokemonType'; type: 'Bug' | 'Dark' | 'Dragon' | 'Electric' | 'Fairy' | 'Fighting' | 'Fire' | 'Flying' | 'Ghost' | 'Grass' | 'Ground' | 'Ice' | 'Normal' | 'Poison' | 'Psychic' | 'Rock' | 'Steel' | 'Water'; }; 27 + 'Query': { kind: 'OBJECT'; name: 'Query'; fields: { 'pokemon': { name: 'pokemon'; type: { kind: 'OBJECT'; name: 'Pokemon'; ofType: null; } }; 'pokemons': { name: 'pokemons'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Pokemon'; ofType: null; }; } }; }; }; 28 + 'Boolean': unknown; 29 + }; 30 + }; 31 + 32 + import * as gqlTada from 'gql.tada'; 33 + 34 + declare module 'gql.tada' { 35 + interface setupSchema { 36 + introspection: introspection; 37 + } 38 + }
-448
packages/example-tada/introspection.ts
··· 1 - /* eslint-disable */ 2 - /* prettier-ignore */ 3 - 4 - /** An IntrospectionQuery representation of your schema. 5 - * 6 - * @remarks 7 - * This is an introspection of your schema saved as a file by GraphQLSP. 8 - * You may import it to create a `graphql()` tag function with `gql.tada` 9 - * by importing it and passing it to `initGraphQLTada<>()`. 10 - * 11 - * @example 12 - * ``` 13 - * import { initGraphQLTada } from 'gql.tada'; 14 - * import type { introspection } from './introspection'; 15 - * 16 - * export const graphql = initGraphQLTada<{ 17 - * introspection: typeof introspection; 18 - * scalars: { 19 - * DateTime: string; 20 - * Json: any; 21 - * }; 22 - * }>(); 23 - * ``` 24 - */ 25 - const introspection = { 26 - "__schema": { 27 - "queryType": { 28 - "name": "Query" 29 - }, 30 - "mutationType": null, 31 - "subscriptionType": null, 32 - "types": [ 33 - { 34 - "kind": "OBJECT", 35 - "name": "Attack", 36 - "fields": [ 37 - { 38 - "name": "damage", 39 - "type": { 40 - "kind": "SCALAR", 41 - "name": "Int", 42 - "ofType": null 43 - }, 44 - "args": [] 45 - }, 46 - { 47 - "name": "name", 48 - "type": { 49 - "kind": "SCALAR", 50 - "name": "String", 51 - "ofType": null 52 - }, 53 - "args": [] 54 - }, 55 - { 56 - "name": "type", 57 - "type": { 58 - "kind": "ENUM", 59 - "name": "PokemonType", 60 - "ofType": null 61 - }, 62 - "args": [] 63 - } 64 - ], 65 - "interfaces": [] 66 - }, 67 - { 68 - "kind": "SCALAR", 69 - "name": "Int" 70 - }, 71 - { 72 - "kind": "SCALAR", 73 - "name": "String" 74 - }, 75 - { 76 - "kind": "OBJECT", 77 - "name": "AttacksConnection", 78 - "fields": [ 79 - { 80 - "name": "fast", 81 - "type": { 82 - "kind": "LIST", 83 - "ofType": { 84 - "kind": "OBJECT", 85 - "name": "Attack", 86 - "ofType": null 87 - } 88 - }, 89 - "args": [] 90 - }, 91 - { 92 - "name": "special", 93 - "type": { 94 - "kind": "LIST", 95 - "ofType": { 96 - "kind": "OBJECT", 97 - "name": "Attack", 98 - "ofType": null 99 - } 100 - }, 101 - "args": [] 102 - } 103 - ], 104 - "interfaces": [] 105 - }, 106 - { 107 - "kind": "OBJECT", 108 - "name": "EvolutionRequirement", 109 - "fields": [ 110 - { 111 - "name": "amount", 112 - "type": { 113 - "kind": "SCALAR", 114 - "name": "Int", 115 - "ofType": null 116 - }, 117 - "args": [] 118 - }, 119 - { 120 - "name": "name", 121 - "type": { 122 - "kind": "SCALAR", 123 - "name": "String", 124 - "ofType": null 125 - }, 126 - "args": [] 127 - } 128 - ], 129 - "interfaces": [] 130 - }, 131 - { 132 - "kind": "OBJECT", 133 - "name": "Pokemon", 134 - "fields": [ 135 - { 136 - "name": "attacks", 137 - "type": { 138 - "kind": "OBJECT", 139 - "name": "AttacksConnection", 140 - "ofType": null 141 - }, 142 - "args": [] 143 - }, 144 - { 145 - "name": "classification", 146 - "type": { 147 - "kind": "SCALAR", 148 - "name": "String", 149 - "ofType": null 150 - }, 151 - "args": [] 152 - }, 153 - { 154 - "name": "evolutionRequirements", 155 - "type": { 156 - "kind": "LIST", 157 - "ofType": { 158 - "kind": "OBJECT", 159 - "name": "EvolutionRequirement", 160 - "ofType": null 161 - } 162 - }, 163 - "args": [] 164 - }, 165 - { 166 - "name": "evolutions", 167 - "type": { 168 - "kind": "LIST", 169 - "ofType": { 170 - "kind": "OBJECT", 171 - "name": "Pokemon", 172 - "ofType": null 173 - } 174 - }, 175 - "args": [] 176 - }, 177 - { 178 - "name": "fleeRate", 179 - "type": { 180 - "kind": "SCALAR", 181 - "name": "Float", 182 - "ofType": null 183 - }, 184 - "args": [] 185 - }, 186 - { 187 - "name": "height", 188 - "type": { 189 - "kind": "OBJECT", 190 - "name": "PokemonDimension", 191 - "ofType": null 192 - }, 193 - "args": [] 194 - }, 195 - { 196 - "name": "id", 197 - "type": { 198 - "kind": "NON_NULL", 199 - "ofType": { 200 - "kind": "SCALAR", 201 - "name": "ID", 202 - "ofType": null 203 - } 204 - }, 205 - "args": [] 206 - }, 207 - { 208 - "name": "maxCP", 209 - "type": { 210 - "kind": "SCALAR", 211 - "name": "Int", 212 - "ofType": null 213 - }, 214 - "args": [] 215 - }, 216 - { 217 - "name": "maxHP", 218 - "type": { 219 - "kind": "SCALAR", 220 - "name": "Int", 221 - "ofType": null 222 - }, 223 - "args": [] 224 - }, 225 - { 226 - "name": "name", 227 - "type": { 228 - "kind": "NON_NULL", 229 - "ofType": { 230 - "kind": "SCALAR", 231 - "name": "String", 232 - "ofType": null 233 - } 234 - }, 235 - "args": [] 236 - }, 237 - { 238 - "name": "resistant", 239 - "type": { 240 - "kind": "LIST", 241 - "ofType": { 242 - "kind": "ENUM", 243 - "name": "PokemonType", 244 - "ofType": null 245 - } 246 - }, 247 - "args": [] 248 - }, 249 - { 250 - "name": "types", 251 - "type": { 252 - "kind": "LIST", 253 - "ofType": { 254 - "kind": "ENUM", 255 - "name": "PokemonType", 256 - "ofType": null 257 - } 258 - }, 259 - "args": [] 260 - }, 261 - { 262 - "name": "weaknesses", 263 - "type": { 264 - "kind": "LIST", 265 - "ofType": { 266 - "kind": "ENUM", 267 - "name": "PokemonType", 268 - "ofType": null 269 - } 270 - }, 271 - "args": [] 272 - }, 273 - { 274 - "name": "weight", 275 - "type": { 276 - "kind": "OBJECT", 277 - "name": "PokemonDimension", 278 - "ofType": null 279 - }, 280 - "args": [] 281 - } 282 - ], 283 - "interfaces": [] 284 - }, 285 - { 286 - "kind": "SCALAR", 287 - "name": "Float" 288 - }, 289 - { 290 - "kind": "SCALAR", 291 - "name": "ID" 292 - }, 293 - { 294 - "kind": "OBJECT", 295 - "name": "PokemonDimension", 296 - "fields": [ 297 - { 298 - "name": "maximum", 299 - "type": { 300 - "kind": "SCALAR", 301 - "name": "String", 302 - "ofType": null 303 - }, 304 - "args": [] 305 - }, 306 - { 307 - "name": "minimum", 308 - "type": { 309 - "kind": "SCALAR", 310 - "name": "String", 311 - "ofType": null 312 - }, 313 - "args": [] 314 - } 315 - ], 316 - "interfaces": [] 317 - }, 318 - { 319 - "kind": "ENUM", 320 - "name": "PokemonType", 321 - "enumValues": [ 322 - { 323 - "name": "Bug" 324 - }, 325 - { 326 - "name": "Dark" 327 - }, 328 - { 329 - "name": "Dragon" 330 - }, 331 - { 332 - "name": "Electric" 333 - }, 334 - { 335 - "name": "Fairy" 336 - }, 337 - { 338 - "name": "Fighting" 339 - }, 340 - { 341 - "name": "Fire" 342 - }, 343 - { 344 - "name": "Flying" 345 - }, 346 - { 347 - "name": "Ghost" 348 - }, 349 - { 350 - "name": "Grass" 351 - }, 352 - { 353 - "name": "Ground" 354 - }, 355 - { 356 - "name": "Ice" 357 - }, 358 - { 359 - "name": "Normal" 360 - }, 361 - { 362 - "name": "Poison" 363 - }, 364 - { 365 - "name": "Psychic" 366 - }, 367 - { 368 - "name": "Rock" 369 - }, 370 - { 371 - "name": "Steel" 372 - }, 373 - { 374 - "name": "Water" 375 - } 376 - ] 377 - }, 378 - { 379 - "kind": "OBJECT", 380 - "name": "Query", 381 - "fields": [ 382 - { 383 - "name": "pokemon", 384 - "type": { 385 - "kind": "OBJECT", 386 - "name": "Pokemon", 387 - "ofType": null 388 - }, 389 - "args": [ 390 - { 391 - "name": "id", 392 - "type": { 393 - "kind": "NON_NULL", 394 - "ofType": { 395 - "kind": "SCALAR", 396 - "name": "ID", 397 - "ofType": null 398 - } 399 - } 400 - } 401 - ] 402 - }, 403 - { 404 - "name": "pokemons", 405 - "type": { 406 - "kind": "LIST", 407 - "ofType": { 408 - "kind": "OBJECT", 409 - "name": "Pokemon", 410 - "ofType": null 411 - } 412 - }, 413 - "args": [ 414 - { 415 - "name": "limit", 416 - "type": { 417 - "kind": "SCALAR", 418 - "name": "Int", 419 - "ofType": null 420 - } 421 - }, 422 - { 423 - "name": "skip", 424 - "type": { 425 - "kind": "SCALAR", 426 - "name": "Int", 427 - "ofType": null 428 - } 429 - } 430 - ] 431 - } 432 - ], 433 - "interfaces": [] 434 - }, 435 - { 436 - "kind": "SCALAR", 437 - "name": "Boolean" 438 - }, 439 - { 440 - "kind": "SCALAR", 441 - "name": "Any" 442 - } 443 - ], 444 - "directives": [] 445 - } 446 - } as const; 447 - 448 - export { introspection };
+1 -1
packages/example-tada/package.json
··· 11 11 "license": "ISC", 12 12 "dependencies": { 13 13 "@graphql-typed-document-node/core": "^3.2.0", 14 - "gql.tada": "^1.0.0", 14 + "gql.tada": "^1.4.0", 15 15 "@urql/core": "^3.0.0", 16 16 "graphql": "^16.8.1", 17 17 "urql": "^4.0.6"
+2 -2
packages/example-tada/src/graphql.ts
··· 1 1 import { initGraphQLTada } from 'gql.tada'; 2 - import type { introspection } from '../introspection'; 2 + import type { introspection } from '../introspection.d.ts'; 3 3 4 4 export const graphql = initGraphQLTada<{ 5 - introspection: typeof introspection; 5 + introspection: introspection; 6 6 }>(); 7 7 8 8 export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';
+1 -1
packages/example-tada/tsconfig.json
··· 4 4 { 5 5 "name": "@0no-co/graphqlsp", 6 6 "schema": "./schema.graphql", 7 - "tadaOutputLocation": "./introspection.ts" 7 + "tadaOutputLocation": "./introspection.d.ts" 8 8 } 9 9 ], 10 10 "jsx": "react-jsx",
+1
packages/graphqlsp/README.md
··· 72 72 - `reservedKeys` this setting will affect `trackFieldUsage`, you can enter keys here that will be ignored 73 73 from usage tracking, so when they are unused in the component but used in i.e. the normalised cache you 74 74 won't get annoying warnings. (default `id`, `_id` and `__typename`, example: ['slug']) 75 + - `tadaDisablePreprocessing` this setting disables the optimisation of `tadaOutput` to a pre-processed TypeScript type, this is off by default. 75 76 76 77 ## Tracking unused fields 77 78
+1 -3
packages/graphqlsp/package.json
··· 40 40 "@sindresorhus/fnv1a": "^2.0.0", 41 41 "@types/node": "^18.15.11", 42 42 "@types/node-fetch": "^2.6.3", 43 - "@urql/introspection": "^1.0.3", 44 43 "graphql": "^16.8.1", 45 44 "graphql-language-service": "^5.2.0", 46 45 "lru-cache": "^10.0.1", 47 - "type-fest": "^4.11.1", 48 46 "typescript": "^5.3.3" 49 47 }, 50 48 "dependencies": { 51 - "json5": "^2.2.3", 49 + "@gql.tada/internal": "^0.1.0", 52 50 "node-fetch": "^2.0.0" 53 51 }, 54 52 "publishConfig": {
+17 -101
packages/graphqlsp/src/graphql/getSchema.ts
··· 7 7 introspectionFromSchema, 8 8 } from 'graphql'; 9 9 import path from 'path'; 10 - import JSON5 from 'json5'; 11 - import { minifyIntrospectionQuery } from '@urql/introspection'; 12 10 import fetch from 'node-fetch'; 13 11 import fs from 'fs'; 14 - import type { TsConfigJson } from 'type-fest'; 12 + import { 13 + resolveTypeScriptRootDir, 14 + minifyIntrospection, 15 + outputIntrospectionFile, 16 + } from '@gql.tada/internal'; 15 17 16 18 import { ts } from '../ts'; 17 19 import { Logger } from '../index'; 18 20 19 - const preambleComments = 20 - ['/* eslint-disable */', '/* prettier-ignore */'].join('\n') + '\n'; 21 - 22 - const dtsAnnotationComment = [ 23 - '/** An IntrospectionQuery representation of your schema.', 24 - ' *', 25 - ' * @remarks', 26 - ' * This is an introspection of your schema saved as a file by GraphQLSP.', 27 - ' * It will automatically be used by `gql.tada` to infer the types of your GraphQL documents.', 28 - ' * If you need to reuse this data or update your `scalars`, update `tadaOutputLocation` to', 29 - ' * instead save to a .ts instead of a .d.ts file.', 30 - ' */', 31 - ].join('\n'); 32 - 33 - const tsAnnotationComment = [ 34 - '/** An IntrospectionQuery representation of your schema.', 35 - ' *', 36 - ' * @remarks', 37 - ' * This is an introspection of your schema saved as a file by GraphQLSP.', 38 - ' * You may import it to create a `graphql()` tag function with `gql.tada`', 39 - ' * by importing it and passing it to `initGraphQLTada<>()`.', 40 - ' *', 41 - ' * @example', 42 - ' * ```', 43 - " * import { initGraphQLTada } from 'gql.tada';", 44 - " * import type { introspection } from './introspection';", 45 - ' *', 46 - ' * export const graphql = initGraphQLTada<{', 47 - ' * introspection: typeof introspection;', 48 - ' * scalars: {', 49 - ' * DateTime: string;', 50 - ' * Json: any;', 51 - ' * };', 52 - ' * }>();', 53 - ' * ```', 54 - ' */', 55 - ].join('\n'); 56 - 57 21 async function saveTadaIntrospection( 58 22 root: string, 59 23 schema: GraphQLSchema | IntrospectionQuery, 60 24 tadaOutputLocation: string, 25 + disablePreprocessing: boolean, 61 26 logger: Logger 62 27 ) { 63 28 const introspection = !('__schema' in schema) 64 29 ? introspectionFromSchema(schema, { descriptions: false }) 65 30 : schema; 66 31 67 - const minified = minifyIntrospectionQuery(introspection, { 68 - includeDirectives: false, 69 - includeEnums: true, 70 - includeInputs: true, 71 - includeScalars: true, 32 + const minified = minifyIntrospection(introspection); 33 + 34 + const contents = await outputIntrospectionFile(minified, { 35 + fileType: tadaOutputLocation, 36 + shouldPreprocess: !disablePreprocessing, 72 37 }); 73 - 74 - const json = JSON.stringify(minified, null, 2); 75 38 76 39 let output = path.resolve(root, tadaOutputLocation); 77 40 let stat: fs.Stats | undefined; 78 - let contents = ''; 79 41 80 42 try { 81 43 stat = await fs.promises.stat(output); ··· 101 63 return; 102 64 } 103 65 104 - if (/\.d\.ts$/.test(output)) { 105 - contents = [ 106 - preambleComments, 107 - dtsAnnotationComment, 108 - `export type introspection = ${json};\n`, 109 - "import * as gqlTada from 'gql.tada';\n", 110 - "declare module 'gql.tada' {", 111 - ' interface setupSchema {', 112 - ' introspection: introspection', 113 - ' }', 114 - '}', 115 - ].join('\n'); 116 - } else if (path.extname(output) === '.ts') { 117 - contents = [ 118 - preambleComments, 119 - tsAnnotationComment, 120 - `const introspection = ${json} as const;\n`, 121 - 'export { introspection };', 122 - ].join('\n'); 123 - } else { 124 - logger(`Unknown file type on path @ ${output}`); 125 - return; 126 - } 127 - 128 66 await fs.promises.writeFile(output, contents); 129 67 logger(`Introspection saved to path @ ${output}`); 130 68 } ··· 134 72 headers: Record<string, unknown>; 135 73 }; 136 74 137 - const getRootDir = ( 138 - info: ts.server.PluginCreateInfo, 139 - tsconfigPath: string 140 - ): string | undefined => { 141 - const tsconfigContents = info.project.readFile(tsconfigPath); 142 - const parsed = JSON5.parse<TsConfigJson>(tsconfigContents!); 143 - 144 - if ( 145 - parsed.compilerOptions?.plugins?.find(x => x.name === '@0no-co/graphqlsp') 146 - ) { 147 - return path.dirname(tsconfigPath); 148 - } else if (Array.isArray(parsed.extends)) { 149 - return parsed.extends.find(p => { 150 - const resolved = require.resolve(p, { 151 - paths: [path.dirname(tsconfigPath)], 152 - }); 153 - return getRootDir(info, resolved); 154 - }); 155 - } else if (parsed.extends) { 156 - const resolved = require.resolve(parsed.extends, { 157 - paths: [path.dirname(tsconfigPath)], 158 - }); 159 - return getRootDir(info, resolved); 160 - } 161 - }; 162 - 163 75 export const loadSchema = ( 164 76 info: ts.server.PluginCreateInfo, 165 77 schema: SchemaOrigin | string, ··· 167 79 logger: Logger 168 80 ): { current: GraphQLSchema | null; version: number } => { 169 81 const root = 170 - getRootDir(info, info.project.getProjectName()) || 171 - path.dirname(info.project.getProjectName()); 82 + resolveTypeScriptRootDir( 83 + path => info.project.readFile(path), 84 + info.project.getProjectName() 85 + ) || path.dirname(info.project.getProjectName()); 172 86 logger('Got root-directory to resolve schema from: ' + root); 173 87 const ref: { 174 88 current: GraphQLSchema | null; ··· 236 150 root, 237 151 introspection, 238 152 tadaOutputLocation, 153 + info.config.tadaDisablePreprocessing ?? false, 239 154 logger 240 155 ); 241 156 } ··· 280 195 root, 281 196 schemaOrIntrospection, 282 197 tadaOutputLocation, 198 + info.config.tadaDisablePreprocessing ?? false, 283 199 logger 284 200 ); 285 201 }
+1
packages/graphqlsp/src/index.ts
··· 22 22 23 23 type Config = { 24 24 schema: SchemaOrigin | string; 25 + tadaDisablePreprocessing?: boolean; 25 26 templateIsCallExpression?: boolean; 26 27 shouldCheckForColocatedFragments?: boolean; 27 28 template?: string;
+27 -29
pnpm-lock.yaml
··· 137 137 specifier: ^3.0.0 138 138 version: 3.2.2(graphql@16.8.1) 139 139 gql.tada: 140 - specifier: ^1.0.0 141 - version: 1.0.0(graphql@16.8.1) 140 + specifier: ^1.4.0 141 + version: 1.4.0(graphql@16.8.1) 142 142 graphql: 143 143 specifier: ^16.8.1 144 144 version: 16.8.1 ··· 167 167 168 168 packages/graphqlsp: 169 169 dependencies: 170 - json5: 171 - specifier: ^2.2.3 172 - version: 2.2.3 170 + '@gql.tada/internal': 171 + specifier: ^0.1.0 172 + version: 0.1.0 173 173 node-fetch: 174 174 specifier: ^2.0.0 175 175 version: 2.6.7 ··· 186 186 '@types/node-fetch': 187 187 specifier: ^2.6.3 188 188 version: 2.6.3 189 - '@urql/introspection': 190 - specifier: ^1.0.3 191 - version: 1.0.3(graphql@16.8.1) 192 189 graphql: 193 190 specifier: ^16.8.1 194 191 version: 16.8.1 ··· 198 195 lru-cache: 199 196 specifier: ^10.0.1 200 197 version: 10.0.1 201 - type-fest: 202 - specifier: ^4.11.1 203 - version: 4.11.1 204 198 typescript: 205 199 specifier: ^5.3.3 206 200 version: 5.3.3 ··· 1318 1312 dev: true 1319 1313 optional: true 1320 1314 1315 + /@gql.tada/cli-utils@0.3.0: 1316 + resolution: {integrity: sha512-kDebLVuM5r3/bI1MmlhHr9VKHxXeq8Gxy1wHVTPva4R5ObfbhzxnHsTCvR6MUp8ziy9Pg9MESb8S1YZW8ohM3A==} 1317 + dependencies: 1318 + '@gql.tada/internal': 0.1.0 1319 + graphql: 16.8.1 1320 + dev: false 1321 + 1322 + /@gql.tada/internal@0.1.0: 1323 + resolution: {integrity: sha512-FTvBVXVvt0xUo8hvRlwFoyeNXpUDqc+e20MzFkF8ozbsa5PoYb/gksmmnHMjUphsIq1H3Hq8o4RGstFN5LKH4w==} 1324 + dependencies: 1325 + graphql: 16.8.1 1326 + typescript: 5.3.3 1327 + 1321 1328 /@graphql-codegen/add@5.0.0(graphql@16.8.1): 1322 1329 resolution: {integrity: sha512-ynWDOsK2yxtFHwcJTB9shoSkUd7YXd6ZE57f0nk7W5cu/nAgxZZpEsnTPEpZB/Mjf14YRGe2uJHQ7AfElHjqUQ==} 1323 1330 peerDependencies: ··· 2370 2377 transitivePeerDependencies: 2371 2378 - graphql 2372 2379 dev: false 2373 - 2374 - /@urql/introspection@1.0.3(graphql@16.8.1): 2375 - resolution: {integrity: sha512-5zgnfUDV10c3qudqYvfZ/rOtWVB2QvqanmoDMttqpt+TCCPkSUZdb2qcLCEB6DL7ph8mQRTZhXI29J57nTnqKg==} 2376 - peerDependencies: 2377 - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 2378 - dependencies: 2379 - graphql: 16.8.1 2380 - dev: true 2381 2380 2382 2381 /@vitest/expect@0.34.6: 2383 2382 resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} ··· 3652 3651 get-intrinsic: 1.2.2 3653 3652 dev: true 3654 3653 3655 - /gql.tada@1.0.0(graphql@16.8.1): 3656 - resolution: {integrity: sha512-bmZUHxXGXJNW8fPtXyWIwbLKbEjnKK3PF6XinZFK2PgcxSFJ/9p5fVDseE1xiCkf3nOA4aiSxY5OQ3xWNjCzvg==} 3654 + /gql.tada@1.2.1(graphql@16.8.1): 3655 + resolution: {integrity: sha512-Nx8x3g9WLT23eu9aL/4TTFDBwm7CBGVd4F2Jp2H5oOjDpuWv12i1mTLKReQwn2V1ZP+jG8V0ATXzFQZt1pxSgw==} 3657 3656 dependencies: 3658 3657 '@0no-co/graphql.web': 1.0.4(graphql@16.8.1) 3659 3658 transitivePeerDependencies: 3660 3659 - graphql 3661 3660 dev: false 3662 3661 3663 - /gql.tada@1.2.1(graphql@16.8.1): 3664 - resolution: {integrity: sha512-Nx8x3g9WLT23eu9aL/4TTFDBwm7CBGVd4F2Jp2H5oOjDpuWv12i1mTLKReQwn2V1ZP+jG8V0ATXzFQZt1pxSgw==} 3662 + /gql.tada@1.4.0(graphql@16.8.1): 3663 + resolution: {integrity: sha512-/LZJmInJQESn0QafOrDCJRk9ASeI65caU/HmarPtcSNitNWBrH7UfNOsHtISnTTA/CS80eUYqy3M4ogasFZWPQ==} 3664 + hasBin: true 3665 3665 dependencies: 3666 3666 '@0no-co/graphql.web': 1.0.4(graphql@16.8.1) 3667 + '@gql.tada/cli-utils': 0.3.0 3668 + '@gql.tada/internal': 0.1.0 3667 3669 transitivePeerDependencies: 3668 3670 - graphql 3669 3671 dev: false ··· 4233 4235 resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 4234 4236 engines: {node: '>=6'} 4235 4237 hasBin: true 4238 + dev: true 4236 4239 4237 4240 /jsonc-parser@3.2.0: 4238 4241 resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} ··· 5715 5718 engines: {node: '>=10'} 5716 5719 dev: true 5717 5720 5718 - /type-fest@4.11.1: 5719 - resolution: {integrity: sha512-MFMf6VkEVZAETidGGSYW2B1MjXbGX+sWIywn2QPEaJ3j08V+MwVRHMXtf2noB8ENJaD0LIun9wh5Z6OPNf1QzQ==} 5720 - engines: {node: '>=16'} 5721 - dev: true 5722 - 5723 5721 /typed-array-length@1.0.4: 5724 5722 resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} 5725 5723 dependencies: ··· 5732 5730 resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} 5733 5731 engines: {node: '>=14.17'} 5734 5732 hasBin: true 5735 - dev: true 5736 5733 5737 5734 /ua-parser-js@0.7.37: 5738 5735 resolution: {integrity: sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==} ··· 6186 6183 resolution: {directory: packages/graphqlsp, type: directory} 6187 6184 name: '@0no-co/graphqlsp' 6188 6185 dependencies: 6186 + '@gql.tada/internal': 0.1.0 6189 6187 json5: 2.2.3 6190 6188 node-fetch: 2.6.7 6191 6189 transitivePeerDependencies: