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.

chore(workspaace): add multi schema tests (#307)

authored by

Jovi De Croock and committed by
GitHub
e314fd2d 474ca19d

+689 -434
+34 -12
pnpm-lock.yaml
··· 260 260 specifier: ^5.3.3 261 261 version: 5.3.3 262 262 263 + test/e2e/fixture-project-tada-multi-schema: 264 + dependencies: 265 + '@0no-co/graphqlsp': 266 + specifier: workspace:* 267 + version: link:../../../packages/graphqlsp 268 + '@graphql-typed-document-node/core': 269 + specifier: ^3.0.0 270 + version: 3.2.0(graphql@16.8.1) 271 + '@urql/core': 272 + specifier: ^4.0.4 273 + version: 4.2.2(graphql@16.8.1) 274 + gql.tada: 275 + specifier: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b 276 + version: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3) 277 + graphql: 278 + specifier: ^16.0.0 279 + version: 16.8.1 280 + devDependencies: 281 + typescript: 282 + specifier: ^5.3.3 283 + version: 5.3.3 284 + 263 285 test/e2e/fixture-project-unused-fields: 264 286 dependencies: 265 287 '@0no-co/graphqlsp': ··· 310 332 /@0no-co/graphqlsp@1.11.0(typescript@5.3.3): 311 333 resolution: {integrity: sha512-P8DRsT+pRgXXZ+8szO1ISUXLxtaL9ukKddjLqSh+oBvWVCzUDyUM4Une0Co0Y7XC017wI4pdcrR/3hWqw9uuDg==} 312 334 peerDependencies: 313 - typescript: ^5.0.0 335 + typescript: ^5.3.3 314 336 dependencies: 315 337 '@gql.tada/internal': 0.1.3(graphql@16.8.1)(typescript@5.3.3) 316 338 graphql: 16.8.1 ··· 1379 1401 /@gql.tada/cli-utils@1.2.3-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(svelte@4.2.15)(typescript@5.3.3): 1380 1402 resolution: {integrity: sha512-tCKCGD4VmdSrnt7wvvzuJ1dtDf0nB6rBlYkOAvgmwDzDQgkWnwP97Xv6t6i1HAWiE9f9uzMl8y1eAr4IbySPrQ==} 1381 1403 peerDependencies: 1382 - typescript: ^5.0.0 1404 + typescript: ^5.3.3 1383 1405 dependencies: 1384 1406 '@0no-co/graphqlsp': 1.11.0(typescript@5.3.3) 1385 1407 '@gql.tada/internal': 0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3) ··· 1397 1419 resolution: {integrity: sha512-wIvykBId7O0gaizmSl5n5AhbQsgJVLTUsFBm3RsfQ9dVfpmT+Fhy2yHX+yNgiVECg2EimXMhs4ltcE4EuZ2WOA==} 1398 1420 peerDependencies: 1399 1421 graphql: ^16.8.1 1400 - typescript: ^5.0.0 1422 + typescript: ^5.3.3 1401 1423 dependencies: 1402 1424 '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 1403 1425 graphql: 16.8.1 ··· 1408 1430 resolution: {integrity: sha512-CPx00hSOue+XK1KUZhovuN0sZ3sCcUx99Y/iv9obL8ea2rLJ7HbehJ1uI8zwLVtfPoX/tLz+Cc34TFF1znSR7Q==} 1409 1431 peerDependencies: 1410 1432 graphql: ^16.8.1 1411 - typescript: ^5.0.0 1433 + typescript: ^5.3.3 1412 1434 dependencies: 1413 1435 '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 1414 1436 graphql: 16.8.1 ··· 2294 2316 peerDependencies: 2295 2317 rollup: ^2.14.0||^3.0.0||^4.0.0 2296 2318 tslib: '*' 2297 - typescript: '>=3.7.0' 2319 + typescript: ^5.3.3 2298 2320 peerDependenciesMeta: 2299 2321 rollup: 2300 2322 optional: true ··· 2628 2650 /@vue/language-core@2.0.14(typescript@5.3.3): 2629 2651 resolution: {integrity: sha512-3q8mHSNcGTR7sfp2X6jZdcb4yt8AjBXAfKk0qkZIh7GAJxOnoZ10h5HToZglw4ToFvAnq+xu/Z2FFbglh9Icag==} 2630 2652 peerDependencies: 2631 - typescript: '*' 2653 + typescript: ^5.3.3 2632 2654 peerDependenciesMeta: 2633 2655 typescript: 2634 2656 optional: true ··· 3282 3304 resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} 3283 3305 engines: {node: '>=14'} 3284 3306 peerDependencies: 3285 - typescript: '>=4.9.5' 3307 + typescript: ^5.3.3 3286 3308 peerDependenciesMeta: 3287 3309 typescript: 3288 3310 optional: true ··· 3956 3978 resolution: {integrity: sha512-3tglGLiGY1zyMyZAow2kpy8GBi35xGAGiEDiPAIPXOUyU35B0HpY0lmMZhf5jEs0fv2FTMgWvFXO6Z3378B6FA==} 3957 3979 hasBin: true 3958 3980 peerDependencies: 3959 - typescript: ^5.0.0 3981 + typescript: ^5.3.3 3960 3982 dependencies: 3961 3983 '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 3962 3984 '@gql.tada/cli-utils': 1.2.3-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(svelte@4.2.15)(typescript@5.3.3) ··· 5483 5505 engines: {node: '>=16'} 5484 5506 peerDependencies: 5485 5507 rollup: ^3.29.4 || ^4 5486 - typescript: ^4.5 || ^5.0 5508 + typescript: ^5.3.3 5487 5509 dependencies: 5488 5510 magic-string: 0.30.5 5489 5511 rollup: 4.9.5 ··· 5908 5930 resolution: {integrity: sha512-HAIxtk5TUHXvCRKApKfxoh1BGT85S/17lS3DvbfxRKFd+Ghr5YScqBvd+sU+p7vJFw48LNkzdFk+ooNVk3e4kA==} 5909 5931 peerDependencies: 5910 5932 svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 5911 - typescript: ^4.9.4 || ^5.0.0 5933 + typescript: ^5.3.3 5912 5934 dependencies: 5913 5935 dedent-js: 1.0.1 5914 5936 pascal-case: 3.1.2 ··· 6019 6041 '@swc/core': '>=1.2.50' 6020 6042 '@swc/wasm': '>=1.2.50' 6021 6043 '@types/node': '*' 6022 - typescript: '>=2.7' 6044 + typescript: ^5.3.3 6023 6045 peerDependenciesMeta: 6024 6046 '@swc/core': 6025 6047 optional: true ··· 6588 6610 id: file:packages/graphqlsp 6589 6611 name: '@0no-co/graphqlsp' 6590 6612 peerDependencies: 6591 - typescript: ^5.0.0 6613 + typescript: ^5.3.3 6592 6614 dependencies: 6593 6615 '@gql.tada/internal': 0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3) 6594 6616 graphql: 16.8.1
+3
test/e2e/fixture-project-tada-multi-schema/.vscode/settings.json
··· 1 + { 2 + "typescript.tsdk": "node_modules/typescript/lib" 3 + }
+9
test/e2e/fixture-project-tada-multi-schema/fixtures/pokemon.ts
··· 1 + import { initGraphQLTada } from 'gql.tada'; 2 + import type { introspection } from '../pokemons'; 3 + 4 + export const graphql = initGraphQLTada<{ 5 + introspection: introspection; 6 + }>(); 7 + 8 + export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada'; 9 + export { readFragment } from 'gql.tada';
+15
test/e2e/fixture-project-tada-multi-schema/fixtures/simple-pokemon.ts
··· 1 + import { graphql } from './pokemon'; 2 + 3 + // prettier-ignore 4 + const x = graphql(` 5 + query Pokemons($limit: Int!) { 6 + pokemons(limit: $limit) { 7 + id 8 + name 9 + 10 + fleeRate 11 + classification 12 + __typename 13 + } 14 + } 15 + `);
+11
test/e2e/fixture-project-tada-multi-schema/fixtures/simple-todo.ts
··· 1 + import { graphql } from './todo'; 2 + 3 + // prettier-ignore 4 + const x = graphql(` 5 + query Todo($id: ID!) { 6 + todo(id: $id) { 7 + id 8 + 9 + } 10 + } 11 + `);
+9
test/e2e/fixture-project-tada-multi-schema/fixtures/todo.ts
··· 1 + import { initGraphQLTada } from 'gql.tada'; 2 + import type { introspection } from '../todos'; 3 + 4 + export const graphql = initGraphQLTada<{ 5 + introspection: introspection; 6 + }>(); 7 + 8 + export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada'; 9 + export { readFragment } from 'gql.tada';
+14
test/e2e/fixture-project-tada-multi-schema/package.json
··· 1 + { 2 + "name": "fixtures", 3 + "private": true, 4 + "dependencies": { 5 + "graphql": "^16.0.0", 6 + "gql.tada": "1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b", 7 + "@graphql-typed-document-node/core": "^3.0.0", 8 + "@0no-co/graphqlsp": "workspace:*", 9 + "@urql/core": "^4.0.4" 10 + }, 11 + "devDependencies": { 12 + "typescript": "^5.3.3" 13 + } 14 + }
+9
test/e2e/fixture-project-tada-multi-schema/pokemon.ts
··· 1 + import { initGraphQLTada } from 'gql.tada'; 2 + import type { introspection } from './pokemons'; 3 + 4 + export const graphql = initGraphQLTada<{ 5 + introspection: introspection; 6 + }>(); 7 + 8 + export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada'; 9 + export { readFragment } from 'gql.tada';
+33
test/e2e/fixture-project-tada-multi-schema/pokemons.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 + name: 'pokemons'; 14 + query: 'Query'; 15 + mutation: never; 16 + subscription: never; 17 + types: { 18 + '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; } }; }; }; 19 + '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; }; } }; }; }; 20 + 'Boolean': unknown; 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 + 'Float': unknown; 23 + 'ID': unknown; 24 + 'Int': unknown; 25 + '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; } }; }; }; 26 + '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; } }; }; }; 27 + 'PokemonType': { name: 'PokemonType'; enumValues: 'Bug' | 'Dark' | 'Dragon' | 'Electric' | 'Fairy' | 'Fighting' | 'Fire' | 'Flying' | 'Ghost' | 'Grass' | 'Ground' | 'Ice' | 'Normal' | 'Poison' | 'Psychic' | 'Rock' | 'Steel' | 'Water'; }; 28 + '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; }; } }; }; }; 29 + 'String': unknown; 30 + }; 31 + }; 32 + 33 + import * as gqlTada from 'gql.tada';
+94
test/e2e/fixture-project-tada-multi-schema/pokemons.graphql
··· 1 + ### This file was generated by Nexus Schema 2 + ### Do not make changes to this file directly 3 + 4 + """ 5 + Move a Pokémon can perform with the associated damage and type. 6 + """ 7 + type Attack { 8 + damage: Int 9 + name: String 10 + type: PokemonType 11 + } 12 + 13 + type AttacksConnection { 14 + fast: [Attack] 15 + special: [Attack] 16 + } 17 + 18 + """ 19 + Requirement that prevents an evolution through regular means of levelling up. 20 + """ 21 + type EvolutionRequirement { 22 + amount: Int 23 + name: String 24 + } 25 + 26 + type Pokemon { 27 + attacks: AttacksConnection 28 + classification: String @deprecated(reason: "And this is the reason why") 29 + evolutionRequirements: [EvolutionRequirement] 30 + evolutions: [Pokemon] 31 + 32 + """ 33 + Likelihood of an attempt to catch a Pokémon to fail. 34 + """ 35 + fleeRate: Float 36 + height: PokemonDimension 37 + id: ID! 38 + 39 + """ 40 + Maximum combat power a Pokémon may achieve at max level. 41 + """ 42 + maxCP: Int 43 + 44 + """ 45 + Maximum health points a Pokémon may achieve at max level. 46 + """ 47 + maxHP: Int 48 + name: String! 49 + resistant: [PokemonType] 50 + types: [PokemonType] 51 + weaknesses: [PokemonType] 52 + weight: PokemonDimension 53 + } 54 + 55 + type PokemonDimension { 56 + maximum: String 57 + minimum: String 58 + } 59 + 60 + """ 61 + Elemental property associated with either a Pokémon or one of their moves. 62 + """ 63 + enum PokemonType { 64 + Bug 65 + Dark 66 + Dragon 67 + Electric 68 + Fairy 69 + Fighting 70 + Fire 71 + Flying 72 + Ghost 73 + Grass 74 + Ground 75 + Ice 76 + Normal 77 + Poison 78 + Psychic 79 + Rock 80 + Steel 81 + Water 82 + } 83 + 84 + type Query { 85 + """ 86 + Get a single Pokémon by its ID, a three character long identifier padded with zeroes 87 + """ 88 + pokemon(id: ID!): Pokemon 89 + 90 + """ 91 + List out all Pokémon, optionally in pages 92 + """ 93 + pokemons(limit: Int, skip: Int): [Pokemon] 94 + }
+10
test/e2e/fixture-project-tada-multi-schema/todo.ts
··· 1 + import { initGraphQLTada } from 'gql.tada'; 2 + // @ts-ignore 3 + import type { introspection } from './todos'; 4 + 5 + export const graphql = initGraphQLTada<{ 6 + introspection: introspection; 7 + }>(); 8 + 9 + export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada'; 10 + export { readFragment } from 'gql.tada';
+26
test/e2e/fixture-project-tada-multi-schema/todos.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 + name: 'todos'; 14 + query: 'Query'; 15 + mutation: never; 16 + subscription: never; 17 + types: { 18 + 'Boolean': unknown; 19 + 'ID': unknown; 20 + 'Query': { kind: 'OBJECT'; name: 'Query'; fields: { 'todo': { name: 'todo'; type: { kind: 'OBJECT'; name: 'Todo'; ofType: null; } }; }; }; 21 + 'String': unknown; 22 + 'Todo': { kind: 'OBJECT'; name: 'Todo'; fields: { 'completed': { name: 'completed'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'text': { name: 'text'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; }; 23 + }; 24 + }; 25 + 26 + import * as gqlTada from 'gql.tada';
+12
test/e2e/fixture-project-tada-multi-schema/todos.graphql
··· 1 + type Todo { 2 + id: ID! 3 + text: String! 4 + completed: Boolean! 5 + } 6 + 7 + type Query { 8 + """ 9 + Get a single Todo by its ID 10 + """ 11 + todo(id: ID!): Todo 12 + }
+28
test/e2e/fixture-project-tada-multi-schema/tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "plugins": [ 4 + { 5 + "name": "@0no-co/graphqlsp", 6 + "schemas": [ 7 + { 8 + "name": "pokemons", 9 + "schema": "./pokemons.graphql", 10 + "tadaOutputLocation": "./pokemons.d.ts" 11 + }, 12 + { 13 + "name": "todos", 14 + "schema": "./todos.graphql", 15 + "tadaOutputLocation": "./todos.d.ts" 16 + } 17 + ] 18 + } 19 + ], 20 + "target": "es2016", 21 + "esModuleInterop": true, 22 + "moduleResolution": "node", 23 + "forceConsistentCasingInFileNames": true, 24 + "strict": true, 25 + "skipLibCheck": true 26 + }, 27 + "exclude": ["node_modules", "fixtures"] 28 + }
+18 -422
test/e2e/fixture-project-tada/introspection.d.ts
··· 10 10 * instead save to a .ts instead of a .d.ts file. 11 11 */ 12 12 export type introspection = { 13 - "__schema": { 14 - "queryType": { 15 - "name": "Query" 16 - }, 17 - "mutationType": null, 18 - "subscriptionType": null, 19 - "types": [ 20 - { 21 - "kind": "OBJECT", 22 - "name": "Attack", 23 - "fields": [ 24 - { 25 - "name": "damage", 26 - "type": { 27 - "kind": "SCALAR", 28 - "name": "Int", 29 - "ofType": null 30 - }, 31 - "args": [] 32 - }, 33 - { 34 - "name": "name", 35 - "type": { 36 - "kind": "SCALAR", 37 - "name": "String", 38 - "ofType": null 39 - }, 40 - "args": [] 41 - }, 42 - { 43 - "name": "type", 44 - "type": { 45 - "kind": "ENUM", 46 - "name": "PokemonType", 47 - "ofType": null 48 - }, 49 - "args": [] 50 - } 51 - ], 52 - "interfaces": [] 53 - }, 54 - { 55 - "kind": "SCALAR", 56 - "name": "Int" 57 - }, 58 - { 59 - "kind": "SCALAR", 60 - "name": "String" 61 - }, 62 - { 63 - "kind": "OBJECT", 64 - "name": "AttacksConnection", 65 - "fields": [ 66 - { 67 - "name": "fast", 68 - "type": { 69 - "kind": "LIST", 70 - "ofType": { 71 - "kind": "OBJECT", 72 - "name": "Attack", 73 - "ofType": null 74 - } 75 - }, 76 - "args": [] 77 - }, 78 - { 79 - "name": "special", 80 - "type": { 81 - "kind": "LIST", 82 - "ofType": { 83 - "kind": "OBJECT", 84 - "name": "Attack", 85 - "ofType": null 86 - } 87 - }, 88 - "args": [] 89 - } 90 - ], 91 - "interfaces": [] 92 - }, 93 - { 94 - "kind": "OBJECT", 95 - "name": "EvolutionRequirement", 96 - "fields": [ 97 - { 98 - "name": "amount", 99 - "type": { 100 - "kind": "SCALAR", 101 - "name": "Int", 102 - "ofType": null 103 - }, 104 - "args": [] 105 - }, 106 - { 107 - "name": "name", 108 - "type": { 109 - "kind": "SCALAR", 110 - "name": "String", 111 - "ofType": null 112 - }, 113 - "args": [] 114 - } 115 - ], 116 - "interfaces": [] 117 - }, 118 - { 119 - "kind": "OBJECT", 120 - "name": "Pokemon", 121 - "fields": [ 122 - { 123 - "name": "attacks", 124 - "type": { 125 - "kind": "OBJECT", 126 - "name": "AttacksConnection", 127 - "ofType": null 128 - }, 129 - "args": [] 130 - }, 131 - { 132 - "name": "classification", 133 - "type": { 134 - "kind": "SCALAR", 135 - "name": "String", 136 - "ofType": null 137 - }, 138 - "args": [] 139 - }, 140 - { 141 - "name": "evolutionRequirements", 142 - "type": { 143 - "kind": "LIST", 144 - "ofType": { 145 - "kind": "OBJECT", 146 - "name": "EvolutionRequirement", 147 - "ofType": null 148 - } 149 - }, 150 - "args": [] 151 - }, 152 - { 153 - "name": "evolutions", 154 - "type": { 155 - "kind": "LIST", 156 - "ofType": { 157 - "kind": "OBJECT", 158 - "name": "Pokemon", 159 - "ofType": null 160 - } 161 - }, 162 - "args": [] 163 - }, 164 - { 165 - "name": "fleeRate", 166 - "type": { 167 - "kind": "SCALAR", 168 - "name": "Float", 169 - "ofType": null 170 - }, 171 - "args": [] 172 - }, 173 - { 174 - "name": "height", 175 - "type": { 176 - "kind": "OBJECT", 177 - "name": "PokemonDimension", 178 - "ofType": null 179 - }, 180 - "args": [] 181 - }, 182 - { 183 - "name": "id", 184 - "type": { 185 - "kind": "NON_NULL", 186 - "ofType": { 187 - "kind": "SCALAR", 188 - "name": "ID", 189 - "ofType": null 190 - } 191 - }, 192 - "args": [] 193 - }, 194 - { 195 - "name": "maxCP", 196 - "type": { 197 - "kind": "SCALAR", 198 - "name": "Int", 199 - "ofType": null 200 - }, 201 - "args": [] 202 - }, 203 - { 204 - "name": "maxHP", 205 - "type": { 206 - "kind": "SCALAR", 207 - "name": "Int", 208 - "ofType": null 209 - }, 210 - "args": [] 211 - }, 212 - { 213 - "name": "name", 214 - "type": { 215 - "kind": "NON_NULL", 216 - "ofType": { 217 - "kind": "SCALAR", 218 - "name": "String", 219 - "ofType": null 220 - } 221 - }, 222 - "args": [] 223 - }, 224 - { 225 - "name": "resistant", 226 - "type": { 227 - "kind": "LIST", 228 - "ofType": { 229 - "kind": "ENUM", 230 - "name": "PokemonType", 231 - "ofType": null 232 - } 233 - }, 234 - "args": [] 235 - }, 236 - { 237 - "name": "types", 238 - "type": { 239 - "kind": "LIST", 240 - "ofType": { 241 - "kind": "ENUM", 242 - "name": "PokemonType", 243 - "ofType": null 244 - } 245 - }, 246 - "args": [] 247 - }, 248 - { 249 - "name": "weaknesses", 250 - "type": { 251 - "kind": "LIST", 252 - "ofType": { 253 - "kind": "ENUM", 254 - "name": "PokemonType", 255 - "ofType": null 256 - } 257 - }, 258 - "args": [] 259 - }, 260 - { 261 - "name": "weight", 262 - "type": { 263 - "kind": "OBJECT", 264 - "name": "PokemonDimension", 265 - "ofType": null 266 - }, 267 - "args": [] 268 - } 269 - ], 270 - "interfaces": [] 271 - }, 272 - { 273 - "kind": "SCALAR", 274 - "name": "Float" 275 - }, 276 - { 277 - "kind": "SCALAR", 278 - "name": "ID" 279 - }, 280 - { 281 - "kind": "OBJECT", 282 - "name": "PokemonDimension", 283 - "fields": [ 284 - { 285 - "name": "maximum", 286 - "type": { 287 - "kind": "SCALAR", 288 - "name": "String", 289 - "ofType": null 290 - }, 291 - "args": [] 292 - }, 293 - { 294 - "name": "minimum", 295 - "type": { 296 - "kind": "SCALAR", 297 - "name": "String", 298 - "ofType": null 299 - }, 300 - "args": [] 301 - } 302 - ], 303 - "interfaces": [] 304 - }, 305 - { 306 - "kind": "ENUM", 307 - "name": "PokemonType", 308 - "enumValues": [ 309 - { 310 - "name": "Bug" 311 - }, 312 - { 313 - "name": "Dark" 314 - }, 315 - { 316 - "name": "Dragon" 317 - }, 318 - { 319 - "name": "Electric" 320 - }, 321 - { 322 - "name": "Fairy" 323 - }, 324 - { 325 - "name": "Fighting" 326 - }, 327 - { 328 - "name": "Fire" 329 - }, 330 - { 331 - "name": "Flying" 332 - }, 333 - { 334 - "name": "Ghost" 335 - }, 336 - { 337 - "name": "Grass" 338 - }, 339 - { 340 - "name": "Ground" 341 - }, 342 - { 343 - "name": "Ice" 344 - }, 345 - { 346 - "name": "Normal" 347 - }, 348 - { 349 - "name": "Poison" 350 - }, 351 - { 352 - "name": "Psychic" 353 - }, 354 - { 355 - "name": "Rock" 356 - }, 357 - { 358 - "name": "Steel" 359 - }, 360 - { 361 - "name": "Water" 362 - } 363 - ] 364 - }, 365 - { 366 - "kind": "OBJECT", 367 - "name": "Query", 368 - "fields": [ 369 - { 370 - "name": "pokemon", 371 - "type": { 372 - "kind": "OBJECT", 373 - "name": "Pokemon", 374 - "ofType": null 375 - }, 376 - "args": [ 377 - { 378 - "name": "id", 379 - "type": { 380 - "kind": "NON_NULL", 381 - "ofType": { 382 - "kind": "SCALAR", 383 - "name": "ID", 384 - "ofType": null 385 - } 386 - } 387 - } 388 - ] 389 - }, 390 - { 391 - "name": "pokemons", 392 - "type": { 393 - "kind": "LIST", 394 - "ofType": { 395 - "kind": "OBJECT", 396 - "name": "Pokemon", 397 - "ofType": null 398 - } 399 - }, 400 - "args": [ 401 - { 402 - "name": "limit", 403 - "type": { 404 - "kind": "SCALAR", 405 - "name": "Int", 406 - "ofType": null 407 - } 408 - }, 409 - { 410 - "name": "skip", 411 - "type": { 412 - "kind": "SCALAR", 413 - "name": "Int", 414 - "ofType": null 415 - } 416 - } 417 - ] 418 - } 419 - ], 420 - "interfaces": [] 421 - }, 422 - { 423 - "kind": "SCALAR", 424 - "name": "Boolean" 425 - } 426 - ], 427 - "directives": [] 428 - } 13 + name: never; 14 + query: 'Query'; 15 + mutation: never; 16 + subscription: never; 17 + types: { 18 + '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; } }; }; }; 19 + '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; }; } }; }; }; 20 + 'Boolean': unknown; 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 + 'Float': unknown; 23 + 'ID': unknown; 24 + 'Int': unknown; 25 + '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; } }; }; }; 26 + '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; } }; }; }; 27 + 'PokemonType': { name: 'PokemonType'; enumValues: 'Bug' | 'Dark' | 'Dragon' | 'Electric' | 'Fairy' | 'Fighting' | 'Fire' | 'Flying' | 'Ghost' | 'Grass' | 'Ground' | 'Ice' | 'Normal' | 'Poison' | 'Psychic' | 'Rock' | 'Steel' | 'Water'; }; 28 + '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; }; } }; }; }; 29 + 'String': unknown; 30 + }; 429 31 }; 430 32 431 33 import * as gqlTada from 'gql.tada'; 432 - 433 - declare module 'gql.tada' { 434 - interface setupSchema { 435 - introspection: introspection; 436 - } 437 - }
+364
test/e2e/multi-schema-tada.test.ts
··· 1 + import { expect, afterAll, beforeAll, it, describe } from 'vitest'; 2 + import { TSServer } from './server'; 3 + import path from 'node:path'; 4 + import fs from 'node:fs'; 5 + import url from 'node:url'; 6 + import ts from 'typescript/lib/tsserverlibrary'; 7 + 8 + const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); 9 + 10 + const projectPath = path.resolve( 11 + __dirname, 12 + 'fixture-project-tada-multi-schema' 13 + ); 14 + describe('Multiple schemas', () => { 15 + const outfilePokemonTest = path.join(projectPath, 'simple-pokemon.ts'); 16 + const outfileTodoTest = path.join(projectPath, 'simple-todo.ts'); 17 + 18 + let server: TSServer; 19 + beforeAll(async () => { 20 + server = new TSServer(projectPath, { debugLog: false }); 21 + 22 + server.sendCommand('open', { 23 + file: outfilePokemonTest, 24 + fileContent: '// empty', 25 + scriptKindName: 'TS', 26 + } satisfies ts.server.protocol.OpenRequestArgs); 27 + server.sendCommand('open', { 28 + file: outfileTodoTest, 29 + fileContent: '// empty', 30 + scriptKindName: 'TS', 31 + } satisfies ts.server.protocol.OpenRequestArgs); 32 + 33 + server.sendCommand('updateOpen', { 34 + openFiles: [ 35 + { 36 + file: outfilePokemonTest, 37 + fileContent: fs.readFileSync( 38 + path.join(projectPath, 'fixtures/simple-pokemon.ts'), 39 + 'utf-8' 40 + ), 41 + }, 42 + { 43 + file: outfileTodoTest, 44 + fileContent: fs.readFileSync( 45 + path.join(projectPath, 'fixtures/simple-todo.ts'), 46 + 'utf-8' 47 + ), 48 + }, 49 + ], 50 + } satisfies ts.server.protocol.UpdateOpenRequestArgs); 51 + 52 + server.sendCommand('saveto', { 53 + file: outfilePokemonTest, 54 + tmpfile: outfilePokemonTest, 55 + } satisfies ts.server.protocol.SavetoRequestArgs); 56 + server.sendCommand('saveto', { 57 + file: outfileTodoTest, 58 + tmpfile: outfileTodoTest, 59 + } satisfies ts.server.protocol.SavetoRequestArgs); 60 + 61 + // Give TS some time to figure this out... 62 + await new Promise(resolve => setTimeout(resolve, 1000)); 63 + }); 64 + 65 + afterAll(() => { 66 + try { 67 + fs.unlinkSync(outfilePokemonTest); 68 + fs.unlinkSync(outfileTodoTest); 69 + } catch {} 70 + }); 71 + 72 + it('gives diagnostics about unused fields', async () => { 73 + await server.waitForResponse( 74 + e => e.type === 'event' && e.event === 'semanticDiag' 75 + ); 76 + const res = server.responses.filter( 77 + resp => 78 + resp.type === 'event' && 79 + resp.event === 'semanticDiag' && 80 + resp.body?.file === outfilePokemonTest 81 + ); 82 + 83 + expect(res).toBeDefined(); 84 + expect(res).toHaveLength(1); 85 + expect(res[0].body.diagnostics).toHaveLength(1); 86 + expect(res[0].body.diagnostics[0]).toMatchInlineSnapshot(` 87 + { 88 + "category": "warning", 89 + "code": 52004, 90 + "end": { 91 + "line": 12, 92 + "offset": 1, 93 + }, 94 + "start": { 95 + "line": 11, 96 + "offset": 7, 97 + }, 98 + "text": "The field Pokemon.classification is deprecated. And this is the reason why", 99 + } 100 + `); 101 + }, 30000); 102 + 103 + it('gives quick-info for the pokemon document', async () => { 104 + server.send({ 105 + seq: 9, 106 + type: 'request', 107 + command: 'quickinfo', 108 + arguments: { 109 + file: outfilePokemonTest, 110 + line: 8, 111 + offset: 8, 112 + }, 113 + }); 114 + 115 + await server.waitForResponse( 116 + response => 117 + response.type === 'response' && response.command === 'quickinfo' 118 + ); 119 + 120 + const res = server.responses 121 + .reverse() 122 + .find(resp => resp.type === 'response' && resp.command === 'quickinfo'); 123 + 124 + expect(res).toBeDefined(); 125 + expect(typeof res?.body).toEqual('object'); 126 + expect(res?.body.documentation).toEqual(`Pokemon.name: String!`); 127 + }, 30000); 128 + 129 + it('gives quick-info for the todo document', async () => { 130 + server.send({ 131 + seq: 10, 132 + type: 'request', 133 + command: 'quickinfo', 134 + arguments: { 135 + file: outfileTodoTest, 136 + line: 7, 137 + offset: 8, 138 + }, 139 + }); 140 + 141 + await server.waitForResponse( 142 + response => 143 + response.type === 'response' && response.command === 'quickinfo' 144 + ); 145 + 146 + const res = server.responses 147 + .reverse() 148 + .find(resp => resp.type === 'response' && resp.command === 'quickinfo'); 149 + 150 + expect(res).toBeDefined(); 151 + expect(typeof res?.body).toEqual('object'); 152 + expect(res?.body.documentation).toEqual(`Todo.id: ID!`); 153 + }, 30000); 154 + 155 + it('gives completion-info for the pokemon document', async () => { 156 + server.send({ 157 + seq: 11, 158 + type: 'request', 159 + command: 'completionInfo', 160 + arguments: { 161 + file: outfilePokemonTest, 162 + line: 9, 163 + offset: 7, 164 + includeExternalModuleExports: true, 165 + includeInsertTextCompletions: true, 166 + triggerKind: 1, 167 + }, 168 + }); 169 + 170 + await server.waitForResponse( 171 + response => 172 + response.type === 'response' && response.command === 'completionInfo' 173 + ); 174 + 175 + const res = server.responses 176 + .reverse() 177 + .find( 178 + resp => resp.type === 'response' && resp.command === 'completionInfo' 179 + ); 180 + 181 + expect(res).toBeDefined(); 182 + expect(res).toMatchInlineSnapshot(` 183 + { 184 + "body": { 185 + "entries": [ 186 + { 187 + "kind": "var", 188 + "kindModifiers": "declare", 189 + "labelDetails": { 190 + "detail": " AttacksConnection", 191 + }, 192 + "name": "attacks", 193 + "sortText": "0attacks", 194 + }, 195 + { 196 + "kind": "var", 197 + "kindModifiers": "declare", 198 + "labelDetails": { 199 + "detail": " [EvolutionRequirement]", 200 + }, 201 + "name": "evolutionRequirements", 202 + "sortText": "2evolutionRequirements", 203 + }, 204 + { 205 + "kind": "var", 206 + "kindModifiers": "declare", 207 + "labelDetails": { 208 + "detail": " [Pokemon]", 209 + }, 210 + "name": "evolutions", 211 + "sortText": "3evolutions", 212 + }, 213 + { 214 + "kind": "var", 215 + "kindModifiers": "declare", 216 + "labelDetails": { 217 + "detail": " PokemonDimension", 218 + }, 219 + "name": "height", 220 + "sortText": "5height", 221 + }, 222 + { 223 + "kind": "var", 224 + "kindModifiers": "declare", 225 + "labelDetails": { 226 + "description": "Maximum combat power a Pokémon may achieve at max level.", 227 + "detail": " Int", 228 + }, 229 + "name": "maxCP", 230 + "sortText": "7maxCP", 231 + }, 232 + { 233 + "kind": "var", 234 + "kindModifiers": "declare", 235 + "labelDetails": { 236 + "description": "Maximum health points a Pokémon may achieve at max level.", 237 + "detail": " Int", 238 + }, 239 + "name": "maxHP", 240 + "sortText": "8maxHP", 241 + }, 242 + { 243 + "kind": "var", 244 + "kindModifiers": "declare", 245 + "labelDetails": { 246 + "detail": " [PokemonType]", 247 + }, 248 + "name": "resistant", 249 + "sortText": "10resistant", 250 + }, 251 + { 252 + "kind": "var", 253 + "kindModifiers": "declare", 254 + "labelDetails": { 255 + "detail": " [PokemonType]", 256 + }, 257 + "name": "types", 258 + "sortText": "11types", 259 + }, 260 + { 261 + "kind": "var", 262 + "kindModifiers": "declare", 263 + "labelDetails": { 264 + "detail": " [PokemonType]", 265 + }, 266 + "name": "weaknesses", 267 + "sortText": "12weaknesses", 268 + }, 269 + { 270 + "kind": "var", 271 + "kindModifiers": "declare", 272 + "labelDetails": { 273 + "detail": " PokemonDimension", 274 + }, 275 + "name": "weight", 276 + "sortText": "13weight", 277 + }, 278 + ], 279 + "isGlobalCompletion": false, 280 + "isMemberCompletion": false, 281 + "isNewIdentifierLocation": false, 282 + }, 283 + "command": "completionInfo", 284 + "request_seq": 11, 285 + "seq": 0, 286 + "success": true, 287 + "type": "response", 288 + } 289 + `); 290 + }, 30000); 291 + 292 + it('gives completion-info for the todo document', async () => { 293 + server.send({ 294 + seq: 11, 295 + type: 'request', 296 + command: 'completionInfo', 297 + arguments: { 298 + file: outfileTodoTest, 299 + line: 8, 300 + offset: 7, 301 + includeExternalModuleExports: true, 302 + includeInsertTextCompletions: true, 303 + triggerKind: 1, 304 + }, 305 + }); 306 + 307 + await server.waitForResponse( 308 + response => 309 + response.type === 'response' && response.command === 'completionInfo' 310 + ); 311 + 312 + const res = server.responses 313 + .reverse() 314 + .find( 315 + resp => resp.type === 'response' && resp.command === 'completionInfo' 316 + ); 317 + 318 + expect(res).toBeDefined(); 319 + expect(res).toMatchInlineSnapshot(` 320 + { 321 + "body": { 322 + "entries": [ 323 + { 324 + "kind": "var", 325 + "kindModifiers": "declare", 326 + "labelDetails": { 327 + "detail": " String!", 328 + }, 329 + "name": "text", 330 + "sortText": "1text", 331 + }, 332 + { 333 + "kind": "var", 334 + "kindModifiers": "declare", 335 + "labelDetails": { 336 + "detail": " Boolean!", 337 + }, 338 + "name": "completed", 339 + "sortText": "2completed", 340 + }, 341 + { 342 + "kind": "var", 343 + "kindModifiers": "declare", 344 + "labelDetails": { 345 + "description": "The name of the current Object type at runtime.", 346 + "detail": " String!", 347 + }, 348 + "name": "__typename", 349 + "sortText": "3__typename", 350 + }, 351 + ], 352 + "isGlobalCompletion": false, 353 + "isMemberCompletion": false, 354 + "isNewIdentifierLocation": false, 355 + }, 356 + "command": "completionInfo", 357 + "request_seq": 11, 358 + "seq": 0, 359 + "success": true, 360 + "type": "response", 361 + } 362 + `); 363 + }, 30000); 364 + });