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

fix: Fix schema name not being determined for `graphql` calls on property-access (#312)

Co-authored-by: Jovi De Croock <decroockjovi@gmail.com>

authored by kitten.sh

Jovi De Croock and committed by
GitHub
0035f2df 847a476c

+93 -58
+5
.changeset/silver-elephants-suffer.md
··· 1 + --- 2 + '@0no-co/graphqlsp': patch 3 + --- 4 + 5 + Fix schema name being determined incorrectly when calling `graphql` from namespace/property-access.
+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.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b", 14 + "gql.tada": "1.6.0", 15 15 "@urql/core": "^3.0.0", 16 16 "graphql": "^16.8.1", 17 17 "urql": "^4.0.6"
+1 -4
packages/graphqlsp/src/ast/checks.ts
··· 96 96 typeChecker: ts.TypeChecker | undefined 97 97 ): string | null => { 98 98 if (!typeChecker) return null; 99 - const expression = ts.isPropertyAccessExpression(node.expression) 100 - ? node.expression.expression 101 - : node.expression; 102 - const type = typeChecker.getTypeAtLocation(expression); 99 + const type = typeChecker.getTypeAtLocation(node.expression); 103 100 if (type) { 104 101 const brandTypeSymbol = type.getProperty('__name'); 105 102 if (brandTypeSymbol) {
+26 -51
pnpm-lock.yaml
··· 144 144 specifier: ^3.0.0 145 145 version: 3.2.2(graphql@16.8.1) 146 146 gql.tada: 147 - specifier: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b 148 - version: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3) 147 + specifier: 1.6.0 148 + version: 1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3) 149 149 graphql: 150 150 specifier: ^16.8.1 151 151 version: 16.8.1 ··· 250 250 specifier: ^4.0.4 251 251 version: 4.2.2(graphql@16.8.1) 252 252 gql.tada: 253 - specifier: ^1.2.1 254 - version: 1.2.1(graphql@16.8.1) 253 + specifier: ^1.6.0 254 + version: 1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3) 255 255 graphql: 256 256 specifier: ^16.0.0 257 257 version: 16.8.1 ··· 272 272 specifier: ^4.0.4 273 273 version: 4.2.2(graphql@16.8.1) 274 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) 275 + specifier: 1.6.0 276 + version: 1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3) 277 277 graphql: 278 278 specifier: ^16.0.0 279 279 version: 16.8.1 ··· 318 318 optional: true 319 319 dependencies: 320 320 graphql: 16.8.1 321 + dev: true 321 322 322 323 /@0no-co/graphql.web@1.0.6(graphql@16.8.1): 323 324 resolution: {integrity: sha512-KZ7TnwMcQJcFgzjoY623AVxtlDQonkqp3rSz0wb15/jHPyU1v5gynUibEpuutDeoyGJ5Tp+FwxjGyDGDwq3vIw==} ··· 329 330 dependencies: 330 331 graphql: 16.8.1 331 332 332 - /@0no-co/graphqlsp@1.11.0(typescript@5.3.3): 333 - resolution: {integrity: sha512-P8DRsT+pRgXXZ+8szO1ISUXLxtaL9ukKddjLqSh+oBvWVCzUDyUM4Une0Co0Y7XC017wI4pdcrR/3hWqw9uuDg==} 333 + /@0no-co/graphqlsp@1.12.0(typescript@5.3.3): 334 + resolution: {integrity: sha512-UkU8JETdH6jVi7O2FqTYBfCqlbfgRiAJoTD/sfmHyy8YdGC199n43S5d3qlKSYaZp/w+iihjFZYtJ9snhbfUWQ==} 334 335 peerDependencies: 335 336 typescript: ^5.0.0 336 337 dependencies: 337 - '@gql.tada/internal': 0.1.3(graphql@16.8.1)(typescript@5.3.3) 338 + '@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3) 338 339 graphql: 16.8.1 339 340 node-fetch: 2.6.7 340 341 typescript: 5.3.3 ··· 382 383 dependencies: 383 384 '@babel/core': 7.23.7 384 385 '@babel/generator': 7.23.6 385 - '@babel/parser': 7.23.6 386 + '@babel/parser': 7.24.4 386 387 '@babel/runtime': 7.20.6 387 388 '@babel/traverse': 7.23.7 388 389 '@babel/types': 7.23.6 ··· 435 436 '@babel/helper-compilation-targets': 7.23.6 436 437 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) 437 438 '@babel/helpers': 7.23.8 438 - '@babel/parser': 7.23.6 439 + '@babel/parser': 7.24.4 439 440 '@babel/template': 7.22.15 440 441 '@babel/traverse': 7.23.7 441 442 '@babel/types': 7.23.6 ··· 634 635 hasBin: true 635 636 dependencies: 636 637 '@babel/types': 7.23.6 637 - dev: false 638 638 639 639 /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.23.7): 640 640 resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} ··· 979 979 '@babel/helper-function-name': 7.23.0 980 980 '@babel/helper-hoist-variables': 7.22.5 981 981 '@babel/helper-split-export-declaration': 7.22.6 982 - '@babel/parser': 7.23.6 982 + '@babel/parser': 7.24.4 983 983 '@babel/types': 7.23.6 984 984 debug: 4.3.4 985 985 globals: 11.12.0 ··· 1398 1398 engines: {node: '>=14'} 1399 1399 dev: true 1400 1400 1401 - /@gql.tada/cli-utils@1.2.3-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(svelte@4.2.15)(typescript@5.3.3): 1402 - resolution: {integrity: sha512-tCKCGD4VmdSrnt7wvvzuJ1dtDf0nB6rBlYkOAvgmwDzDQgkWnwP97Xv6t6i1HAWiE9f9uzMl8y1eAr4IbySPrQ==} 1401 + /@gql.tada/cli-utils@1.3.0(svelte@4.2.15)(typescript@5.3.3): 1402 + resolution: {integrity: sha512-TSf8x9zDndI+u+US1Hy/cndlHI7OvanttnfIHcm0ha6/Nnx/WcuAsprJ17ymaDVbh9CpnSz0aL8/F6IZfVBFNw==} 1403 1403 peerDependencies: 1404 1404 typescript: ^5.0.0 1405 1405 dependencies: 1406 - '@0no-co/graphqlsp': 1.11.0(typescript@5.3.3) 1407 - '@gql.tada/internal': 0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3) 1406 + '@0no-co/graphqlsp': 1.12.0(typescript@5.3.3) 1407 + '@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3) 1408 1408 '@vue/compiler-dom': 3.4.25 1409 1409 '@vue/language-core': 2.0.14(typescript@5.3.3) 1410 1410 graphql: 16.8.1 ··· 1415 1415 - svelte 1416 1416 dev: false 1417 1417 1418 - /@gql.tada/internal@0.1.3(graphql@16.8.1)(typescript@5.3.3): 1419 - resolution: {integrity: sha512-wIvykBId7O0gaizmSl5n5AhbQsgJVLTUsFBm3RsfQ9dVfpmT+Fhy2yHX+yNgiVECg2EimXMhs4ltcE4EuZ2WOA==} 1420 - peerDependencies: 1421 - graphql: ^16.8.1 1422 - typescript: ^5.0.0 1423 - dependencies: 1424 - '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 1425 - graphql: 16.8.1 1426 - typescript: 5.3.3 1427 - dev: false 1428 - 1429 1418 /@gql.tada/internal@0.3.0(graphql@16.8.1)(typescript@5.3.3): 1430 1419 resolution: {integrity: sha512-blWnLfkJwR4xpCO3NIpUJ99Y/AIz1tvmZGW/ygOWZwLqzUaZ2pUxGvnmDPrqHFyVVLsJUAhP+3xHSC5qRqR5bg==} 1431 1420 peerDependencies: ··· 1435 1424 '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 1436 1425 graphql: 16.8.1 1437 1426 typescript: 5.3.3 1427 + dev: false 1438 1428 1439 - /@gql.tada/internal@0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3): 1440 - resolution: {integrity: sha512-CPx00hSOue+XK1KUZhovuN0sZ3sCcUx99Y/iv9obL8ea2rLJ7HbehJ1uI8zwLVtfPoX/tLz+Cc34TFF1znSR7Q==} 1429 + /@gql.tada/internal@0.3.1(graphql@16.8.1)(typescript@5.3.3): 1430 + resolution: {integrity: sha512-orrU83yh9OoeJdmn1LTOTAOYECOHXautiHLzlNuZFOTkmvSlX+W/y2TzHg28+SR/z3XDWoB6U+fIFPX/RA1qCg==} 1441 1431 peerDependencies: 1442 1432 graphql: ^16.8.1 1443 1433 typescript: ^5.0.0 ··· 1445 1435 '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 1446 1436 graphql: 16.8.1 1447 1437 typescript: 5.3.3 1448 - dev: false 1449 1438 1450 1439 /@graphql-codegen/add@5.0.0(graphql@16.8.1): 1451 1440 resolution: {integrity: sha512-ynWDOsK2yxtFHwcJTB9shoSkUd7YXd6ZE57f0nk7W5cu/nAgxZZpEsnTPEpZB/Mjf14YRGe2uJHQ7AfElHjqUQ==} ··· 3968 3957 get-intrinsic: 1.2.2 3969 3958 dev: true 3970 3959 3971 - /gql.tada@1.2.1(graphql@16.8.1): 3972 - resolution: {integrity: sha512-Nx8x3g9WLT23eu9aL/4TTFDBwm7CBGVd4F2Jp2H5oOjDpuWv12i1mTLKReQwn2V1ZP+jG8V0ATXzFQZt1pxSgw==} 3973 - dependencies: 3974 - '@0no-co/graphql.web': 1.0.4(graphql@16.8.1) 3975 - transitivePeerDependencies: 3976 - - graphql 3977 - dev: false 3978 - 3979 - /gql.tada@1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3): 3980 - resolution: {integrity: sha512-3tglGLiGY1zyMyZAow2kpy8GBi35xGAGiEDiPAIPXOUyU35B0HpY0lmMZhf5jEs0fv2FTMgWvFXO6Z3378B6FA==} 3960 + /gql.tada@1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3): 3961 + resolution: {integrity: sha512-FmC0fNuSDqEzRnG0K+tSAdG9G9uvZdVhtdAGbmrqmesrGs+1YfKgbQXeKSSduhO9BKRoA3sn/XZ413tyshL6Fg==} 3981 3962 hasBin: true 3982 3963 peerDependencies: 3983 3964 typescript: ^5.0.0 3984 3965 dependencies: 3985 3966 '@0no-co/graphql.web': 1.0.6(graphql@16.8.1) 3986 - '@gql.tada/cli-utils': 1.2.3-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(svelte@4.2.15)(typescript@5.3.3) 3987 - '@gql.tada/internal': 0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3) 3967 + '@gql.tada/cli-utils': 1.3.0(svelte@4.2.15)(typescript@5.3.3) 3968 + '@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3) 3988 3969 typescript: 5.3.3 3989 3970 transitivePeerDependencies: 3990 3971 - encoding ··· 5278 5259 dependencies: 5279 5260 nanoid: 3.3.7 5280 5261 picocolors: 1.0.0 5281 - source-map-js: 1.0.2 5262 + source-map-js: 1.2.0 5282 5263 dev: true 5283 5264 5284 5265 /preferred-pm@3.0.3: ··· 5734 5715 tslib: 2.6.2 5735 5716 dev: true 5736 5717 5737 - /source-map-js@1.0.2: 5738 - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 5739 - engines: {node: '>=0.10.0'} 5740 - dev: true 5741 - 5742 5718 /source-map-js@1.2.0: 5743 5719 resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} 5744 5720 engines: {node: '>=0.10.0'} 5745 - dev: false 5746 5721 5747 5722 /source-map-support@0.5.21: 5748 5723 resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} ··· 6614 6589 peerDependencies: 6615 6590 typescript: ^5.0.0 6616 6591 dependencies: 6617 - '@gql.tada/internal': 0.3.0(graphql@16.8.1)(typescript@5.3.3) 6592 + '@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3) 6618 6593 graphql: 16.8.1 6619 6594 node-fetch: 2.6.7 6620 6595 typescript: 5.3.3
+14
test/e2e/fixture-project-tada-multi-schema/fixtures/star-import.ts
··· 1 + import * as pokemon from './pokemon'; 2 + 3 + // prettier-ignore 4 + const x = pokemon.graphql(` 5 + query Pokemons($limit: Int!) { 6 + pokemons(limit: $limit) { 7 + id 8 + name 9 + fleeRate 10 + classification 11 + __typename 12 + } 13 + } 14 + `);
+1 -1
test/e2e/fixture-project-tada-multi-schema/package.json
··· 3 3 "private": true, 4 4 "dependencies": { 5 5 "graphql": "^16.0.0", 6 - "gql.tada": "1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b", 6 + "gql.tada": "1.6.0", 7 7 "@graphql-typed-document-node/core": "^3.0.0", 8 8 "@0no-co/graphqlsp": "workspace:*", 9 9 "@urql/core": "^4.0.4"
+1 -1
test/e2e/fixture-project-tada/package.json
··· 3 3 "private": true, 4 4 "dependencies": { 5 5 "graphql": "^16.0.0", 6 - "gql.tada": "^1.2.1", 6 + "gql.tada": "^1.6.0", 7 7 "@graphql-typed-document-node/core": "^3.0.0", 8 8 "@0no-co/graphqlsp": "workspace:*", 9 9 "@urql/core": "^4.0.4"
+44
test/e2e/multi-schema-tada.test.ts
··· 14 14 describe('Multiple schemas', () => { 15 15 const outfilePokemonTest = path.join(projectPath, 'simple-pokemon.ts'); 16 16 const outfileTodoTest = path.join(projectPath, 'simple-todo.ts'); 17 + const outfileStarImport = path.join(projectPath, 'star-import.ts'); 17 18 18 19 let server: TSServer; 19 20 beforeAll(async () => { ··· 26 27 } satisfies ts.server.protocol.OpenRequestArgs); 27 28 server.sendCommand('open', { 28 29 file: outfileTodoTest, 30 + fileContent: '// empty', 31 + scriptKindName: 'TS', 32 + } satisfies ts.server.protocol.OpenRequestArgs); 33 + server.sendCommand('open', { 34 + file: outfileStarImport, 29 35 fileContent: '// empty', 30 36 scriptKindName: 'TS', 31 37 } satisfies ts.server.protocol.OpenRequestArgs); ··· 46 52 'utf-8' 47 53 ), 48 54 }, 55 + { 56 + file: outfileStarImport, 57 + fileContent: fs.readFileSync( 58 + path.join(projectPath, 'fixtures/star-import.ts'), 59 + 'utf-8' 60 + ), 61 + }, 49 62 ], 50 63 } satisfies ts.server.protocol.UpdateOpenRequestArgs); 51 64 ··· 57 70 file: outfileTodoTest, 58 71 tmpfile: outfileTodoTest, 59 72 } satisfies ts.server.protocol.SavetoRequestArgs); 73 + server.sendCommand('saveto', { 74 + file: outfileStarImport, 75 + tmpfile: outfileStarImport, 76 + } satisfies ts.server.protocol.SavetoRequestArgs); 60 77 61 78 // Give TS some time to figure this out... 62 79 await new Promise(resolve => setTimeout(resolve, 1000)); ··· 66 83 try { 67 84 fs.unlinkSync(outfilePokemonTest); 68 85 fs.unlinkSync(outfileTodoTest); 86 + fs.unlinkSync(outfileStarImport); 69 87 } catch {} 70 88 }); 71 89 ··· 109 127 file: outfilePokemonTest, 110 128 line: 8, 111 129 offset: 8, 130 + }, 131 + }); 132 + 133 + await server.waitForResponse( 134 + response => 135 + response.type === 'response' && response.command === 'quickinfo' 136 + ); 137 + 138 + const res = server.responses 139 + .reverse() 140 + .find(resp => resp.type === 'response' && resp.command === 'quickinfo'); 141 + 142 + expect(res).toBeDefined(); 143 + expect(typeof res?.body).toEqual('object'); 144 + expect(res?.body.documentation).toEqual(`Pokemon.name: String!`); 145 + }, 30000); 146 + 147 + it('gives quick-info for the pokemon document namespace', async () => { 148 + server.send({ 149 + seq: 20, 150 + type: 'request', 151 + command: 'quickinfo', 152 + arguments: { 153 + file: outfileStarImport, 154 + line: 8, 155 + offset: 9, 112 156 }, 113 157 }); 114 158