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>

Changed files
+93 -58
.changeset
packages
example-tada
graphqlsp
src
ast
test
e2e
fixture-project-tada
fixture-project-tada-multi-schema
+5
.changeset/silver-elephants-suffer.md
···
+
---
+
'@0no-co/graphqlsp': patch
+
---
+
+
Fix schema name being determined incorrectly when calling `graphql` from namespace/property-access.
+1 -1
packages/example-tada/package.json
···
"license": "ISC",
"dependencies": {
"@graphql-typed-document-node/core": "^3.2.0",
-
"gql.tada": "1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b",
+
"gql.tada": "1.6.0",
"@urql/core": "^3.0.0",
"graphql": "^16.8.1",
"urql": "^4.0.6"
+1 -4
packages/graphqlsp/src/ast/checks.ts
···
typeChecker: ts.TypeChecker | undefined
): string | null => {
if (!typeChecker) return null;
-
const expression = ts.isPropertyAccessExpression(node.expression)
-
? node.expression.expression
-
: node.expression;
-
const type = typeChecker.getTypeAtLocation(expression);
+
const type = typeChecker.getTypeAtLocation(node.expression);
if (type) {
const brandTypeSymbol = type.getProperty('__name');
if (brandTypeSymbol) {
+26 -51
pnpm-lock.yaml
···
specifier: ^3.0.0
version: 3.2.2(graphql@16.8.1)
gql.tada:
-
specifier: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b
-
version: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3)
+
specifier: 1.6.0
+
version: 1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3)
graphql:
specifier: ^16.8.1
version: 16.8.1
···
specifier: ^4.0.4
version: 4.2.2(graphql@16.8.1)
gql.tada:
-
specifier: ^1.2.1
-
version: 1.2.1(graphql@16.8.1)
+
specifier: ^1.6.0
+
version: 1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3)
graphql:
specifier: ^16.0.0
version: 16.8.1
···
specifier: ^4.0.4
version: 4.2.2(graphql@16.8.1)
gql.tada:
-
specifier: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b
-
version: 1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3)
+
specifier: 1.6.0
+
version: 1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3)
graphql:
specifier: ^16.0.0
version: 16.8.1
···
optional: true
dependencies:
graphql: 16.8.1
+
dev: true
/@0no-co/graphql.web@1.0.6(graphql@16.8.1):
resolution: {integrity: sha512-KZ7TnwMcQJcFgzjoY623AVxtlDQonkqp3rSz0wb15/jHPyU1v5gynUibEpuutDeoyGJ5Tp+FwxjGyDGDwq3vIw==}
···
dependencies:
graphql: 16.8.1
-
/@0no-co/graphqlsp@1.11.0(typescript@5.3.3):
-
resolution: {integrity: sha512-P8DRsT+pRgXXZ+8szO1ISUXLxtaL9ukKddjLqSh+oBvWVCzUDyUM4Une0Co0Y7XC017wI4pdcrR/3hWqw9uuDg==}
+
/@0no-co/graphqlsp@1.12.0(typescript@5.3.3):
+
resolution: {integrity: sha512-UkU8JETdH6jVi7O2FqTYBfCqlbfgRiAJoTD/sfmHyy8YdGC199n43S5d3qlKSYaZp/w+iihjFZYtJ9snhbfUWQ==}
peerDependencies:
typescript: ^5.0.0
dependencies:
-
'@gql.tada/internal': 0.1.3(graphql@16.8.1)(typescript@5.3.3)
+
'@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3)
graphql: 16.8.1
node-fetch: 2.6.7
typescript: 5.3.3
···
dependencies:
'@babel/core': 7.23.7
'@babel/generator': 7.23.6
-
'@babel/parser': 7.23.6
+
'@babel/parser': 7.24.4
'@babel/runtime': 7.20.6
'@babel/traverse': 7.23.7
'@babel/types': 7.23.6
···
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7)
'@babel/helpers': 7.23.8
-
'@babel/parser': 7.23.6
+
'@babel/parser': 7.24.4
'@babel/template': 7.22.15
'@babel/traverse': 7.23.7
'@babel/types': 7.23.6
···
hasBin: true
dependencies:
'@babel/types': 7.23.6
-
dev: false
/@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.23.7):
resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
···
'@babel/helper-function-name': 7.23.0
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
-
'@babel/parser': 7.23.6
+
'@babel/parser': 7.24.4
'@babel/types': 7.23.6
debug: 4.3.4
globals: 11.12.0
···
engines: {node: '>=14'}
dev: true
-
/@gql.tada/cli-utils@1.2.3-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(svelte@4.2.15)(typescript@5.3.3):
-
resolution: {integrity: sha512-tCKCGD4VmdSrnt7wvvzuJ1dtDf0nB6rBlYkOAvgmwDzDQgkWnwP97Xv6t6i1HAWiE9f9uzMl8y1eAr4IbySPrQ==}
+
/@gql.tada/cli-utils@1.3.0(svelte@4.2.15)(typescript@5.3.3):
+
resolution: {integrity: sha512-TSf8x9zDndI+u+US1Hy/cndlHI7OvanttnfIHcm0ha6/Nnx/WcuAsprJ17ymaDVbh9CpnSz0aL8/F6IZfVBFNw==}
peerDependencies:
typescript: ^5.0.0
dependencies:
-
'@0no-co/graphqlsp': 1.11.0(typescript@5.3.3)
-
'@gql.tada/internal': 0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3)
+
'@0no-co/graphqlsp': 1.12.0(typescript@5.3.3)
+
'@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3)
'@vue/compiler-dom': 3.4.25
'@vue/language-core': 2.0.14(typescript@5.3.3)
graphql: 16.8.1
···
- svelte
dev: false
-
/@gql.tada/internal@0.1.3(graphql@16.8.1)(typescript@5.3.3):
-
resolution: {integrity: sha512-wIvykBId7O0gaizmSl5n5AhbQsgJVLTUsFBm3RsfQ9dVfpmT+Fhy2yHX+yNgiVECg2EimXMhs4ltcE4EuZ2WOA==}
-
peerDependencies:
-
graphql: ^16.8.1
-
typescript: ^5.0.0
-
dependencies:
-
'@0no-co/graphql.web': 1.0.6(graphql@16.8.1)
-
graphql: 16.8.1
-
typescript: 5.3.3
-
dev: false
-
/@gql.tada/internal@0.3.0(graphql@16.8.1)(typescript@5.3.3):
resolution: {integrity: sha512-blWnLfkJwR4xpCO3NIpUJ99Y/AIz1tvmZGW/ygOWZwLqzUaZ2pUxGvnmDPrqHFyVVLsJUAhP+3xHSC5qRqR5bg==}
peerDependencies:
···
'@0no-co/graphql.web': 1.0.6(graphql@16.8.1)
graphql: 16.8.1
typescript: 5.3.3
+
dev: false
-
/@gql.tada/internal@0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3):
-
resolution: {integrity: sha512-CPx00hSOue+XK1KUZhovuN0sZ3sCcUx99Y/iv9obL8ea2rLJ7HbehJ1uI8zwLVtfPoX/tLz+Cc34TFF1znSR7Q==}
+
/@gql.tada/internal@0.3.1(graphql@16.8.1)(typescript@5.3.3):
+
resolution: {integrity: sha512-orrU83yh9OoeJdmn1LTOTAOYECOHXautiHLzlNuZFOTkmvSlX+W/y2TzHg28+SR/z3XDWoB6U+fIFPX/RA1qCg==}
peerDependencies:
graphql: ^16.8.1
typescript: ^5.0.0
···
'@0no-co/graphql.web': 1.0.6(graphql@16.8.1)
graphql: 16.8.1
typescript: 5.3.3
-
dev: false
/@graphql-codegen/add@5.0.0(graphql@16.8.1):
resolution: {integrity: sha512-ynWDOsK2yxtFHwcJTB9shoSkUd7YXd6ZE57f0nk7W5cu/nAgxZZpEsnTPEpZB/Mjf14YRGe2uJHQ7AfElHjqUQ==}
···
get-intrinsic: 1.2.2
dev: true
-
/gql.tada@1.2.1(graphql@16.8.1):
-
resolution: {integrity: sha512-Nx8x3g9WLT23eu9aL/4TTFDBwm7CBGVd4F2Jp2H5oOjDpuWv12i1mTLKReQwn2V1ZP+jG8V0ATXzFQZt1pxSgw==}
-
dependencies:
-
'@0no-co/graphql.web': 1.0.4(graphql@16.8.1)
-
transitivePeerDependencies:
-
- graphql
-
dev: false
-
-
/gql.tada@1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3):
-
resolution: {integrity: sha512-3tglGLiGY1zyMyZAow2kpy8GBi35xGAGiEDiPAIPXOUyU35B0HpY0lmMZhf5jEs0fv2FTMgWvFXO6Z3378B6FA==}
+
/gql.tada@1.6.0(graphql@16.8.1)(svelte@4.2.15)(typescript@5.3.3):
+
resolution: {integrity: sha512-FmC0fNuSDqEzRnG0K+tSAdG9G9uvZdVhtdAGbmrqmesrGs+1YfKgbQXeKSSduhO9BKRoA3sn/XZ413tyshL6Fg==}
hasBin: true
peerDependencies:
typescript: ^5.0.0
dependencies:
'@0no-co/graphql.web': 1.0.6(graphql@16.8.1)
-
'@gql.tada/cli-utils': 1.2.3-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(svelte@4.2.15)(typescript@5.3.3)
-
'@gql.tada/internal': 0.3.0-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b(graphql@16.8.1)(typescript@5.3.3)
+
'@gql.tada/cli-utils': 1.3.0(svelte@4.2.15)(typescript@5.3.3)
+
'@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
- encoding
···
dependencies:
nanoid: 3.3.7
picocolors: 1.0.0
-
source-map-js: 1.0.2
+
source-map-js: 1.2.0
dev: true
/preferred-pm@3.0.3:
···
tslib: 2.6.2
dev: true
-
/source-map-js@1.0.2:
-
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
-
engines: {node: '>=0.10.0'}
-
dev: true
-
/source-map-js@1.2.0:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
-
dev: false
/source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
···
peerDependencies:
typescript: ^5.0.0
dependencies:
-
'@gql.tada/internal': 0.3.0(graphql@16.8.1)(typescript@5.3.3)
+
'@gql.tada/internal': 0.3.1(graphql@16.8.1)(typescript@5.3.3)
graphql: 16.8.1
node-fetch: 2.6.7
typescript: 5.3.3
+14
test/e2e/fixture-project-tada-multi-schema/fixtures/star-import.ts
···
+
import * as pokemon from './pokemon';
+
+
// prettier-ignore
+
const x = pokemon.graphql(`
+
query Pokemons($limit: Int!) {
+
pokemons(limit: $limit) {
+
id
+
name
+
fleeRate
+
classification
+
__typename
+
}
+
}
+
`);
+1 -1
test/e2e/fixture-project-tada-multi-schema/package.json
···
"private": true,
"dependencies": {
"graphql": "^16.0.0",
-
"gql.tada": "1.5.9-canary-8711af177005f46fa3e06d990b6ba28e353e7f9b",
+
"gql.tada": "1.6.0",
"@graphql-typed-document-node/core": "^3.0.0",
"@0no-co/graphqlsp": "workspace:*",
"@urql/core": "^4.0.4"
+1 -1
test/e2e/fixture-project-tada/package.json
···
"private": true,
"dependencies": {
"graphql": "^16.0.0",
-
"gql.tada": "^1.2.1",
+
"gql.tada": "^1.6.0",
"@graphql-typed-document-node/core": "^3.0.0",
"@0no-co/graphqlsp": "workspace:*",
"@urql/core": "^4.0.4"
+44
test/e2e/multi-schema-tada.test.ts
···
describe('Multiple schemas', () => {
const outfilePokemonTest = path.join(projectPath, 'simple-pokemon.ts');
const outfileTodoTest = path.join(projectPath, 'simple-todo.ts');
+
const outfileStarImport = path.join(projectPath, 'star-import.ts');
let server: TSServer;
beforeAll(async () => {
···
} satisfies ts.server.protocol.OpenRequestArgs);
server.sendCommand('open', {
file: outfileTodoTest,
+
fileContent: '// empty',
+
scriptKindName: 'TS',
+
} satisfies ts.server.protocol.OpenRequestArgs);
+
server.sendCommand('open', {
+
file: outfileStarImport,
fileContent: '// empty',
scriptKindName: 'TS',
} satisfies ts.server.protocol.OpenRequestArgs);
···
'utf-8'
),
},
+
{
+
file: outfileStarImport,
+
fileContent: fs.readFileSync(
+
path.join(projectPath, 'fixtures/star-import.ts'),
+
'utf-8'
+
),
+
},
],
} satisfies ts.server.protocol.UpdateOpenRequestArgs);
···
file: outfileTodoTest,
tmpfile: outfileTodoTest,
} satisfies ts.server.protocol.SavetoRequestArgs);
+
server.sendCommand('saveto', {
+
file: outfileStarImport,
+
tmpfile: outfileStarImport,
+
} satisfies ts.server.protocol.SavetoRequestArgs);
// Give TS some time to figure this out...
await new Promise(resolve => setTimeout(resolve, 1000));
···
try {
fs.unlinkSync(outfilePokemonTest);
fs.unlinkSync(outfileTodoTest);
+
fs.unlinkSync(outfileStarImport);
} catch {}
});
···
file: outfilePokemonTest,
line: 8,
offset: 8,
+
},
+
});
+
+
await server.waitForResponse(
+
response =>
+
response.type === 'response' && response.command === 'quickinfo'
+
);
+
+
const res = server.responses
+
.reverse()
+
.find(resp => resp.type === 'response' && resp.command === 'quickinfo');
+
+
expect(res).toBeDefined();
+
expect(typeof res?.body).toEqual('object');
+
expect(res?.body.documentation).toEqual(`Pokemon.name: String!`);
+
}, 30000);
+
+
it('gives quick-info for the pokemon document namespace', async () => {
+
server.send({
+
seq: 20,
+
type: 'request',
+
command: 'quickinfo',
+
arguments: {
+
file: outfileStarImport,
+
line: 8,
+
offset: 9,
},
});