Skip to content

Commit

Permalink
fix unknown fragment error
Browse files Browse the repository at this point in the history
  • Loading branch information
motemen committed Feb 5, 2025
1 parent d217a65 commit af052d7
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 10 deletions.
20 changes: 12 additions & 8 deletions packages/graphql-language-service-server/src/MessageProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1223,25 +1223,29 @@ export class MessageProcessor {
private async _cacheDocumentFilesforProject(project: GraphQLProjectConfig) {
try {
const documents = await project.getDocuments();
return Promise.all(
documents.map(async document => {
if (!document.location || !document.rawSDL) {
return;
}
const documentLocations = new Set(
documents
.filter(doc => doc.location && doc.rawSDL)
.map(doc => doc.location!),
);

let filePath = document.location;
return Promise.all(
Array.from(documentLocations).map(async loc => {
let filePath = loc;
if (!path.isAbsolute(filePath)) {
filePath = path.join(project.dirpath, document.location);
filePath = path.join(project.dirpath, loc);
}

// build full system URI path with protocol
const uri = URI.file(filePath).toString();

const fileContent = await readFile(filePath, 'utf-8');
// I would use the already existing graphql-config AST, but there are a few reasons we can't yet
const contents = await this._parser(document.rawSDL, uri);
const contents = await parseDocument(fileContent, uri);
if (!contents[0]?.query) {
return;
}

await this._updateObjectTypeDefinition(uri, contents);
await this._updateFragmentDefinition(uri, contents);
await this._invalidateCache({ version: 1, uri }, uri, contents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ describe('MessageProcessor with config', () => {
character: 0,
},
end: {
line: 2,
character: 1,
line: 0,
character: 25,
},
});

Expand Down Expand Up @@ -542,6 +542,9 @@ describe('MessageProcessor with config', () => {

expect(project.lsp._logger.error).not.toHaveBeenCalled();
expect(await project.lsp._graphQLCache.getSchema('a')).toBeDefined();
expect(project.lsp._logger.info).not.toHaveBeenCalledWith(
expect.stringMatching(/SyntaxError: Unexpected token/),
);

fetchMock.restore();
mockSchema(
Expand Down Expand Up @@ -636,4 +639,65 @@ describe('MessageProcessor with config', () => {
expect(project.lsp._logger.error).not.toHaveBeenCalled();
project.lsp.handleShutdownRequest();
});

it('correctly handles a fragment inside a TypeScript file', async () => {
const project = new MockProject({
files: [
[
'schema.graphql',
`
type Item {
foo: String
bar: Int
}
type Query {
items: [Item]
}
`,
],
[
'query.ts',
`
import gql from 'graphql-tag'
const query = gql\`
query {
items {
...ItemFragment
}
}
\`
`,
],
[
'fragments.ts',
`
import gql from 'graphql-tag'
export const ItemFragment = gql\`
fragment ItemFragment on Item {
foo
bar
}
\`
`,
],
[
'graphql.config.json',
'{ "schema": "./schema.graphql", "documents": "./**.{graphql,ts}" }',
],
],
});

const initParams = await project.init('query.ts');
expect(initParams.diagnostics).toEqual([]);

const fragmentDefinition = await project.lsp.handleDefinitionRequest({
textDocument: { uri: project.uri('query.ts') },
position: { character: 10, line: 6 },
});

expect(fragmentDefinition[0]?.uri).toEqual(project.uri('fragments.ts'));
});
});

0 comments on commit af052d7

Please sign in to comment.