Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

language support for @oneOf #3769

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
better context detection
  • Loading branch information
acao committed Sep 10, 2024
commit 4c500249950c8c8a9f29c8b0e2aa913dad0aa28a
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ input InputType {
}

input OneOfInputType @oneOf {
key: String!
key: String
value: Int
obj: InputType
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -683,9 +683,14 @@ describe('getAutocompleteSuggestions', () => {
});

it('provides correct oneOf input type field suggestions', () => {
const args = [
{ ...inputArgs[0], detail: 'String' },
inputArgs[1],
inputArgs[2],
];
expect(
testSuggestions('{ oneOfInputTypeTest(oneOf: {', new Position(0, 29)),
).toEqual(inputArgs);
).toEqual(args);
});

it('provides no more field suggestions once a oneOf field is chosen', () => {
Expand All @@ -697,6 +702,17 @@ describe('getAutocompleteSuggestions', () => {
).toEqual([]);
});

// TODO: decide if we want this. Discussing with @benjie, we might want to actually give the user flexibility here,
// instead of being strict
// it('provides no more field suggestions once a oneOf field is chose and a user begins typing another field', () => {
// expect(
// testSuggestions(
// '{ oneOfInputTypeTest(oneOf: { value: 2 d',
// new Position(0, 40),
// ),
// ).toEqual([]);
// });

it('provides correct field name suggestion inside inline fragment', () => {
expect(
testSuggestions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,20 +312,21 @@ export function getAutocompleteSuggestions(
(kind === RuleKinds.OBJECT_FIELD && step === 0)) &&
typeInfo.objectFieldDefs
) {
const objectFields = objectValues(typeInfo.objectFieldDefs);
const completionKind =
kind === RuleKinds.OBJECT_VALUE
? CompletionItemKind.Value
: CompletionItemKind.Field;
// @oneOf logic!
console.log(state.prevState?.prevState?.kind, !!typeInfo.inputType);
if (
typeInfo?.inputType &&
'isOneOf' in typeInfo.inputType &&
typeInfo.inputType.isOneOf === true &&
context.token.string !== '{'
typeInfo?.inputType?.isOneOf === true &&
(state.prevState?.prevState?.kind !== 'Argument' || token.string !== '{')
) {
// return empty array early if a oneOf field has already been provided
return [];
}
const objectFields = objectValues(typeInfo.objectFieldDefs);
const completionKind =
kind === RuleKinds.OBJECT_VALUE
? CompletionItemKind.Value
: CompletionItemKind.Field;

return hintList(
token,
objectFields.map(field => ({
Expand Down
7 changes: 6 additions & 1 deletion packages/graphql-language-service/src/parser/getTypeInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,11 @@ export function getTypeInfo(
}
}
}
inputType = argDef?.type;
if (argDef?.type) {
inputType = argDef.type;
}
break;

case RuleKinds.VARIABLE_DEFINITION:
case RuleKinds.VARIABLE:
type = inputType;
Expand All @@ -241,6 +244,8 @@ export function getTypeInfo(
objectType instanceof GraphQLInputObjectType
? objectType.getFields()
: null;
inputType = objectType;
console.log(inputType);
break;
// TODO: needs tests
case RuleKinds.OBJECT_FIELD:
Expand Down
2 changes: 2 additions & 0 deletions packages/graphql-language-service/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import type {
GraphQLObjectType,
GraphQLType,
GraphQLDirective,
GraphQLInputType,
GraphQLInputObjectType,
} from 'graphql';

export type Maybe<T> = T | null | undefined;
Expand Down