Socket
Socket
Sign inDemoInstall

graphql-language-service

Package Overview
Dependencies
3
Maintainers
14
Versions
237
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.2.1-canary-36f0bac1.0 to 5.2.1

dist/parser/api.d.ts

4

dist/index.d.ts

@@ -1,3 +0,3 @@

export { getAutocompleteSuggestions, getDefinitionQueryResultForDefinitionNode, getDefinitionQueryResultForFragmentSpread, getDefinitionQueryResultForNamedType, getDefinitionQueryResultForField, getDefinitionState, getDiagnostics, getFieldDef, getFragmentDefinitions, getHoverInformation, getOutline, getRange, getTokenAtPosition, getTypeInfo, getVariableCompletions, SEVERITY, Severity, HoverConfig, SeverityEnum, DIAGNOSTIC_SEVERITY, DefinitionQueryResult, canUseDirective, SuggestionCommand, AutocompleteSuggestionOptions, validateQuery, } from './interface';
export { onlineParser, ParseRules, CharacterStream, RuleKinds, LexRules, isIgnored, p, list, t, opt, } from './parser';
export { getAutocompleteSuggestions, getDefinitionQueryResultForDefinitionNode, getDefinitionQueryResultForFragmentSpread, getDefinitionQueryResultForNamedType, getDefinitionQueryResultForField, getDefinitionQueryResultForArgument, getDiagnostics, getFragmentDefinitions, getHoverInformation, getOutline, getRange, getTypeInfo, getVariableCompletions, SEVERITY, Severity, HoverConfig, SeverityEnum, DIAGNOSTIC_SEVERITY, DefinitionQueryResult, DefinitionQueryResponse, canUseDirective, SuggestionCommand, AutocompleteSuggestionOptions, validateQuery, } from './interface';
export { onlineParser, ParseRules, CharacterStream, RuleKinds, LexRules, isIgnored, p, list, t, opt, getTokenAtPosition, GraphQLDocumentMode, getDefinitionState, getFieldDef, } from './parser';
export type { RuleOrString, ParserOptions, ParseRule, TokenPattern, State, CharacterStreamInterface, RuleKindEnum, Token, ContextToken, ContextTokenForCodeMirror, ContextTokenUnion, RuleKind, } from './parser';

@@ -4,0 +4,0 @@ export type { CompletionItem, GraphQLProjectConfig, Maybe, IPosition, Diagnostic, IRange, Definition, CachedContent, GraphQLConfig, GraphQLFileMetadata, Uri, ObjectTypeInfo, Outline, OutlineTree, FragmentInfo, GraphQLFileInfo, FileChangeType, GraphQLCache, GraphQLExtensionDeclaration, } from './types';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Range = exports.validateWithCustomRules = exports.collectVariables = exports.Position = exports.pointToOffset = exports.offsetToPosition = exports.getVariablesJSONSchema = exports.getQueryFacts = exports.getOperationFacts = exports.getOperationASTFacts = exports.getFragmentDependenciesForAST = exports.getFragmentDependencies = exports.getASTNodeAtPosition = exports.FileChangeTypeKind = exports.CompletionItemKind = exports.opt = exports.t = exports.list = exports.p = exports.isIgnored = exports.LexRules = exports.RuleKinds = exports.CharacterStream = exports.ParseRules = exports.onlineParser = exports.validateQuery = exports.SuggestionCommand = exports.canUseDirective = exports.DIAGNOSTIC_SEVERITY = exports.SEVERITY = exports.getVariableCompletions = exports.getTypeInfo = exports.getTokenAtPosition = exports.getRange = exports.getOutline = exports.getHoverInformation = exports.getFragmentDefinitions = exports.getFieldDef = exports.getDiagnostics = exports.getDefinitionState = exports.getDefinitionQueryResultForField = exports.getDefinitionQueryResultForNamedType = exports.getDefinitionQueryResultForFragmentSpread = exports.getDefinitionQueryResultForDefinitionNode = exports.getAutocompleteSuggestions = void 0;
exports.Range = exports.validateWithCustomRules = exports.collectVariables = exports.Position = exports.pointToOffset = exports.offsetToPosition = exports.getVariablesJSONSchema = exports.getQueryFacts = exports.getOperationFacts = exports.getOperationASTFacts = exports.getFragmentDependenciesForAST = exports.getFragmentDependencies = exports.getASTNodeAtPosition = exports.FileChangeTypeKind = exports.CompletionItemKind = exports.getFieldDef = exports.getDefinitionState = exports.GraphQLDocumentMode = exports.getTokenAtPosition = exports.opt = exports.t = exports.list = exports.p = exports.isIgnored = exports.LexRules = exports.RuleKinds = exports.CharacterStream = exports.ParseRules = exports.onlineParser = exports.validateQuery = exports.SuggestionCommand = exports.canUseDirective = exports.DIAGNOSTIC_SEVERITY = exports.SEVERITY = exports.getVariableCompletions = exports.getTypeInfo = exports.getRange = exports.getOutline = exports.getHoverInformation = exports.getFragmentDefinitions = exports.getDiagnostics = exports.getDefinitionQueryResultForArgument = exports.getDefinitionQueryResultForField = exports.getDefinitionQueryResultForNamedType = exports.getDefinitionQueryResultForFragmentSpread = exports.getDefinitionQueryResultForDefinitionNode = exports.getAutocompleteSuggestions = void 0;
var interface_1 = require("./interface");

@@ -10,5 +10,4 @@ Object.defineProperty(exports, "getAutocompleteSuggestions", { enumerable: true, get: function () { return interface_1.getAutocompleteSuggestions; } });

Object.defineProperty(exports, "getDefinitionQueryResultForField", { enumerable: true, get: function () { return interface_1.getDefinitionQueryResultForField; } });
Object.defineProperty(exports, "getDefinitionState", { enumerable: true, get: function () { return interface_1.getDefinitionState; } });
Object.defineProperty(exports, "getDefinitionQueryResultForArgument", { enumerable: true, get: function () { return interface_1.getDefinitionQueryResultForArgument; } });
Object.defineProperty(exports, "getDiagnostics", { enumerable: true, get: function () { return interface_1.getDiagnostics; } });
Object.defineProperty(exports, "getFieldDef", { enumerable: true, get: function () { return interface_1.getFieldDef; } });
Object.defineProperty(exports, "getFragmentDefinitions", { enumerable: true, get: function () { return interface_1.getFragmentDefinitions; } });

@@ -18,3 +17,2 @@ Object.defineProperty(exports, "getHoverInformation", { enumerable: true, get: function () { return interface_1.getHoverInformation; } });

Object.defineProperty(exports, "getRange", { enumerable: true, get: function () { return interface_1.getRange; } });
Object.defineProperty(exports, "getTokenAtPosition", { enumerable: true, get: function () { return interface_1.getTokenAtPosition; } });
Object.defineProperty(exports, "getTypeInfo", { enumerable: true, get: function () { return interface_1.getTypeInfo; } });

@@ -38,2 +36,6 @@ Object.defineProperty(exports, "getVariableCompletions", { enumerable: true, get: function () { return interface_1.getVariableCompletions; } });

Object.defineProperty(exports, "opt", { enumerable: true, get: function () { return parser_1.opt; } });
Object.defineProperty(exports, "getTokenAtPosition", { enumerable: true, get: function () { return parser_1.getTokenAtPosition; } });
Object.defineProperty(exports, "GraphQLDocumentMode", { enumerable: true, get: function () { return parser_1.GraphQLDocumentMode; } });
Object.defineProperty(exports, "getDefinitionState", { enumerable: true, get: function () { return parser_1.getDefinitionState; } });
Object.defineProperty(exports, "getFieldDef", { enumerable: true, get: function () { return parser_1.getFieldDef; } });
var types_1 = require("./types");

@@ -40,0 +42,0 @@ Object.defineProperty(exports, "CompletionItemKind", { enumerable: true, get: function () { return types_1.CompletionItemKind; } });

@@ -1,9 +0,9 @@

import { GraphQLField, GraphQLSchema, GraphQLType } from 'graphql';
import { CompletionItemBase, AllTypeInfo } from '../types';
import { ContextTokenUnion, State } from '../parser';
export declare function getDefinitionState(tokenState: State): State | null | undefined;
export declare function getFieldDef(schema: GraphQLSchema, type: GraphQLType, fieldName: string): GraphQLField<any, any> | null | undefined;
export declare function forEachState(stack: State, fn: (state: State) => AllTypeInfo | null | void): void;
import { GraphQLField, GraphQLType } from 'graphql';
import { CompletionItemBase } from '../types';
import { ContextTokenUnion } from '../parser';
export declare function objectValues<T>(object: Record<string, T>): Array<T>;
export declare function hintList<T extends CompletionItemBase>(token: ContextTokenUnion, list: Array<T>): Array<T>;
export declare const getInsertText: (prefix: string, type?: GraphQLType | undefined, fallback?: string | undefined) => string;
export declare const getInputInsertText: (prefix: string, type: GraphQLType, fallback?: string | undefined) => string;
export declare const getFieldInsertText: (field: GraphQLField<null, null>) => string | undefined;
//# sourceMappingURL=autocompleteUtils.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hintList = exports.objectValues = exports.forEachState = exports.getFieldDef = exports.getDefinitionState = void 0;
exports.getFieldInsertText = exports.getInputInsertText = exports.getInsertText = exports.hintList = exports.objectValues = void 0;
const graphql_1 = require("graphql");
function getDefinitionState(tokenState) {
let definitionState;
forEachState(tokenState, (state) => {
switch (state.kind) {
case 'Query':
case 'ShortQuery':
case 'Mutation':
case 'Subscription':
case 'FragmentDefinition':
definitionState = state;
break;
}
});
return definitionState;
}
exports.getDefinitionState = getDefinitionState;
function getFieldDef(schema, type, fieldName) {
if (fieldName === graphql_1.SchemaMetaFieldDef.name && schema.getQueryType() === type) {
return graphql_1.SchemaMetaFieldDef;
}
if (fieldName === graphql_1.TypeMetaFieldDef.name && schema.getQueryType() === type) {
return graphql_1.TypeMetaFieldDef;
}
if (fieldName === graphql_1.TypeNameMetaFieldDef.name && (0, graphql_1.isCompositeType)(type)) {
return graphql_1.TypeNameMetaFieldDef;
}
if ('getFields' in type) {
return type.getFields()[fieldName];
}
return null;
}
exports.getFieldDef = getFieldDef;
function forEachState(stack, fn) {
const reverseStateStack = [];
let state = stack;
while (state === null || state === void 0 ? void 0 : state.kind) {
reverseStateStack.push(state);
state = state.prevState;
}
for (let i = reverseStateStack.length - 1; i >= 0; i--) {
fn(reverseStateStack[i]);
}
}
exports.forEachState = forEachState;
function objectValues(object) {

@@ -64,3 +20,6 @@ const keys = Object.keys(object);

function filterAndSortList(list, text) {
if (!text) {
if (!text ||
text.trim() === '' ||
text.trim() === ':' ||
text.trim() === '{') {
return filterNonEmpty(list, entry => !entry.isDeprecated);

@@ -116,2 +75,34 @@ }

}
const insertSuffix = (n) => ` {\n $${n !== null && n !== void 0 ? n : 1}\n}`;
const getInsertText = (prefix, type, fallback) => {
if (!type) {
return fallback !== null && fallback !== void 0 ? fallback : prefix;
}
const namedType = (0, graphql_1.getNamedType)(type);
if ((0, graphql_1.isObjectType)(namedType) ||
(0, graphql_1.isInputObjectType)(namedType) ||
(0, graphql_1.isListType)(namedType) ||
(0, graphql_1.isAbstractType)(namedType)) {
return prefix + insertSuffix();
}
return fallback !== null && fallback !== void 0 ? fallback : prefix;
};
exports.getInsertText = getInsertText;
const getInputInsertText = (prefix, type, fallback) => {
if ((0, graphql_1.isListType)(type)) {
const baseType = (0, graphql_1.getNamedType)(type.ofType);
return prefix + `[${(0, exports.getInsertText)('', baseType, '$1')}]`;
}
return (0, exports.getInsertText)(prefix, type, fallback);
};
exports.getInputInsertText = getInputInsertText;
const getFieldInsertText = (field) => {
const requiredArgs = field.args.filter(arg => arg.type.toString().endsWith('!'));
if (!requiredArgs.length) {
return;
}
return (field.name +
`(${requiredArgs.map((arg, i) => `${arg.name}: $${i + 1}`)}) ${(0, exports.getInsertText)('', field.type, '\n')}`);
};
exports.getFieldInsertText = getFieldInsertText;
//# sourceMappingURL=autocompleteUtils.js.map
import { FragmentDefinitionNode, GraphQLDirective, GraphQLSchema } from 'graphql';
import { CompletionItem, AllTypeInfo, IPosition } from '../types';
import { CharacterStream, ContextToken, State, ContextTokenForCodeMirror } from '../parser';
import { CompletionItem, IPosition } from '../types';
import type { ContextToken, State, ContextTokenForCodeMirror } from '../parser';
import { getTypeInfo, runOnlineParser, GraphQLDocumentMode } from '../parser';
export { runOnlineParser, getTypeInfo };
export declare const SuggestionCommand: {

@@ -10,3 +12,2 @@ command: string;

fillLeafsOnComplete?: boolean;
schema?: GraphQLSchema;
uri?: string;

@@ -18,12 +19,3 @@ mode?: GraphQLDocumentMode;

export declare function getFragmentDefinitions(queryText: string): Array<FragmentDefinitionNode>;
export declare function getTokenAtPosition(queryText: string, cursor: IPosition, offset?: number): ContextToken;
declare type callbackFnType = (stream: CharacterStream, state: State, style: string, index: number) => void | 'BREAK';
export declare function runOnlineParser(queryText: string, callback: callbackFnType): ContextToken;
export declare function canUseDirective(state: State['prevState'], directive: GraphQLDirective): boolean;
export declare function getTypeInfo(schema: GraphQLSchema, tokenState: State): AllTypeInfo;
export declare enum GraphQLDocumentMode {
TYPE_SYSTEM = "TYPE_SYSTEM",
EXECUTABLE = "EXECUTABLE"
}
export {};
//# sourceMappingURL=getAutocompleteSuggestions.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphQLDocumentMode = exports.getTypeInfo = exports.canUseDirective = exports.runOnlineParser = exports.getTokenAtPosition = exports.getFragmentDefinitions = exports.getVariableCompletions = exports.getAutocompleteSuggestions = exports.SuggestionCommand = void 0;
exports.canUseDirective = exports.getFragmentDefinitions = exports.getVariableCompletions = exports.getAutocompleteSuggestions = exports.SuggestionCommand = exports.getTypeInfo = exports.runOnlineParser = void 0;
const graphql_1 = require("graphql");
const types_1 = require("../types");
const parser_1 = require("../parser");
Object.defineProperty(exports, "getTypeInfo", { enumerable: true, get: function () { return parser_1.getTypeInfo; } });
Object.defineProperty(exports, "runOnlineParser", { enumerable: true, get: function () { return parser_1.runOnlineParser; } });
const autocompleteUtils_1 = require("./autocompleteUtils");
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
exports.SuggestionCommand = {

@@ -28,59 +31,19 @@ command: 'editor.action.triggerSuggest',

};
const typeSystemKinds = [
graphql_1.Kind.SCHEMA_DEFINITION,
graphql_1.Kind.OPERATION_TYPE_DEFINITION,
graphql_1.Kind.SCALAR_TYPE_DEFINITION,
graphql_1.Kind.OBJECT_TYPE_DEFINITION,
graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
graphql_1.Kind.UNION_TYPE_DEFINITION,
graphql_1.Kind.ENUM_TYPE_DEFINITION,
graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION,
graphql_1.Kind.DIRECTIVE_DEFINITION,
graphql_1.Kind.SCHEMA_EXTENSION,
graphql_1.Kind.SCALAR_TYPE_EXTENSION,
graphql_1.Kind.OBJECT_TYPE_EXTENSION,
graphql_1.Kind.INTERFACE_TYPE_EXTENSION,
graphql_1.Kind.UNION_TYPE_EXTENSION,
graphql_1.Kind.ENUM_TYPE_EXTENSION,
graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION,
];
const hasTypeSystemDefinitions = (sdl) => {
let hasTypeSystemDef = false;
if (sdl) {
try {
(0, graphql_1.visit)((0, graphql_1.parse)(sdl), {
enter(node) {
if (node.kind === 'Document') {
return;
}
if (typeSystemKinds.includes(node.kind)) {
hasTypeSystemDef = true;
return graphql_1.BREAK;
}
return false;
},
});
}
catch (_a) {
return hasTypeSystemDef;
}
}
return hasTypeSystemDef;
};
function getAutocompleteSuggestions(schema, queryText, cursor, contextToken, fragmentDefs, options) {
var _a;
const opts = Object.assign(Object.assign({}, options), { schema });
const token = contextToken || getTokenAtPosition(queryText, cursor, 1);
const state = token.state.kind === 'Invalid' ? token.state.prevState : token.state;
const mode = (options === null || options === void 0 ? void 0 : options.mode) || getDocumentMode(queryText, options === null || options === void 0 ? void 0 : options.uri);
if (!state) {
const context = (0, parser_1.getContextAtPosition)(queryText, cursor, schema, contextToken, options);
if (!context) {
return [];
}
const { state, typeInfo, mode, token } = context;
const { kind, step, prevState } = state;
const typeInfo = getTypeInfo(schema, token.state);
if (kind === parser_1.RuleKinds.DOCUMENT) {
if (mode === GraphQLDocumentMode.TYPE_SYSTEM) {
if (mode === parser_1.GraphQLDocumentMode.TYPE_SYSTEM) {
return getSuggestionsForTypeSystemDefinitions(token);
}
return getSuggestionsForExecutableDefinitions(token);
if (mode === parser_1.GraphQLDocumentMode.EXECUTABLE) {
return getSuggestionsForExecutableDefinitions(token);
}
return getSuggestionsForUnknownDocumentMode(token);
}

@@ -159,5 +122,9 @@ if (kind === parser_1.RuleKinds.EXTEND_DEF) {

label: argDef.name,
insertText: argDef.name + ': ',
insertText: (0, autocompleteUtils_1.getInputInsertText)(argDef.name + ': ', argDef.type),
insertTextMode: vscode_languageserver_types_1.InsertTextMode.adjustIndentation,
insertTextFormat: types_1.InsertTextFormat.Snippet,
command: exports.SuggestionCommand,
detail: String(argDef.type),
labelDetails: {
detail: ' ' + String(argDef.type),
},
documentation: (_a = argDef.description) !== null && _a !== void 0 ? _a : undefined,

@@ -182,5 +149,9 @@ kind: types_1.CompletionItemKind.Variable,

detail: String(field.type),
documentation: (_a = field.description) !== null && _a !== void 0 ? _a : undefined,
documentation: (_a = field === null || field === void 0 ? void 0 : field.description) !== null && _a !== void 0 ? _a : undefined,
kind: completionKind,
type: field.type,
insertText: (0, autocompleteUtils_1.getInputInsertText)(field.name + ': ', field.type),
insertTextMode: vscode_languageserver_types_1.InsertTextMode.adjustIndentation,
insertTextFormat: types_1.InsertTextFormat.Snippet,
command: exports.SuggestionCommand,
});

@@ -212,23 +183,27 @@ }));

const unwrappedState = unwrapType(state);
if ((mode === GraphQLDocumentMode.TYPE_SYSTEM &&
!unwrappedState.needsAdvance &&
kind === parser_1.RuleKinds.NAMED_TYPE) ||
kind === parser_1.RuleKinds.LIST_TYPE) {
if (unwrappedState.kind === parser_1.RuleKinds.FIELD_DEF) {
return (0, autocompleteUtils_1.hintList)(token, Object.values(schema.getTypeMap())
.filter(type => (0, graphql_1.isOutputType)(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: types_1.CompletionItemKind.Function,
})));
}
if (unwrappedState.kind === parser_1.RuleKinds.INPUT_VALUE_DEF) {
return (0, autocompleteUtils_1.hintList)(token, Object.values(schema.getTypeMap())
.filter(type => (0, graphql_1.isInputType)(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: types_1.CompletionItemKind.Function,
})));
}
if (unwrappedState.kind === parser_1.RuleKinds.FIELD_DEF) {
return (0, autocompleteUtils_1.hintList)(token, Object.values(schema.getTypeMap())
.filter(type => (0, graphql_1.isOutputType)(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: types_1.CompletionItemKind.Function,
insertText: (options === null || options === void 0 ? void 0 : options.fillLeafsOnComplete)
? type.name + '\n'
: type.name,
insertTextMode: vscode_languageserver_types_1.InsertTextMode.adjustIndentation,
})));
}
if (unwrappedState.kind === parser_1.RuleKinds.INPUT_VALUE_DEF && step === 2) {
return (0, autocompleteUtils_1.hintList)(token, Object.values(schema.getTypeMap())
.filter(type => (0, graphql_1.isInputType)(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: types_1.CompletionItemKind.Function,
insertText: (options === null || options === void 0 ? void 0 : options.fillLeafsOnComplete)
? type.name + '\n$1'
: type.name,
insertTextMode: vscode_languageserver_types_1.InsertTextMode.adjustIndentation,
insertTextFormat: types_1.InsertTextFormat.Snippet,
})));
}
if ((kind === parser_1.RuleKinds.VARIABLE_DEFINITION && step === 2) ||

@@ -246,53 +221,41 @@ (kind === parser_1.RuleKinds.LIST_TYPE && step === 1) ||

}
if (kind === parser_1.RuleKinds.DIRECTIVE_DEF) {
return getSuggestionsForDirectiveArguments(token, state, schema, kind);
}
return [];
}
exports.getAutocompleteSuggestions = getAutocompleteSuggestions;
const insertSuffix = ' {\n $1\n}';
const getInsertText = (field) => {
const { type } = field;
if ((0, graphql_1.isCompositeType)(type)) {
return insertSuffix;
}
if ((0, graphql_1.isListType)(type) && (0, graphql_1.isCompositeType)(type.ofType)) {
return insertSuffix;
}
if ((0, graphql_1.isNonNullType)(type)) {
if ((0, graphql_1.isCompositeType)(type.ofType)) {
return insertSuffix;
}
if ((0, graphql_1.isListType)(type.ofType) && (0, graphql_1.isCompositeType)(type.ofType.ofType)) {
return insertSuffix;
}
}
return null;
};
const typeSystemCompletionItems = [
{ label: 'type', kind: types_1.CompletionItemKind.Function },
{ label: 'interface', kind: types_1.CompletionItemKind.Function },
{ label: 'union', kind: types_1.CompletionItemKind.Function },
{ label: 'input', kind: types_1.CompletionItemKind.Function },
{ label: 'scalar', kind: types_1.CompletionItemKind.Function },
{ label: 'schema', kind: types_1.CompletionItemKind.Function },
];
const executableCompletionItems = [
{ label: 'query', kind: types_1.CompletionItemKind.Function },
{ label: 'mutation', kind: types_1.CompletionItemKind.Function },
{ label: 'subscription', kind: types_1.CompletionItemKind.Function },
{ label: 'fragment', kind: types_1.CompletionItemKind.Function },
{ label: '{', kind: types_1.CompletionItemKind.Constructor },
];
function getSuggestionsForTypeSystemDefinitions(token) {
return (0, autocompleteUtils_1.hintList)(token, [
{ label: 'extend', kind: types_1.CompletionItemKind.Function },
{ label: 'type', kind: types_1.CompletionItemKind.Function },
{ label: 'interface', kind: types_1.CompletionItemKind.Function },
{ label: 'union', kind: types_1.CompletionItemKind.Function },
{ label: 'input', kind: types_1.CompletionItemKind.Function },
{ label: 'scalar', kind: types_1.CompletionItemKind.Function },
{ label: 'schema', kind: types_1.CompletionItemKind.Function },
...typeSystemCompletionItems,
]);
}
function getSuggestionsForExecutableDefinitions(token) {
return (0, autocompleteUtils_1.hintList)(token, executableCompletionItems);
}
function getSuggestionsForUnknownDocumentMode(token) {
return (0, autocompleteUtils_1.hintList)(token, [
{ label: 'query', kind: types_1.CompletionItemKind.Function },
{ label: 'mutation', kind: types_1.CompletionItemKind.Function },
{ label: 'subscription', kind: types_1.CompletionItemKind.Function },
{ label: 'fragment', kind: types_1.CompletionItemKind.Function },
{ label: '{', kind: types_1.CompletionItemKind.Constructor },
{ label: 'extend', kind: types_1.CompletionItemKind.Function },
...executableCompletionItems,
...typeSystemCompletionItems,
]);
}
function getSuggestionsForExtensionDefinitions(token) {
return (0, autocompleteUtils_1.hintList)(token, [
{ label: 'type', kind: types_1.CompletionItemKind.Function },
{ label: 'interface', kind: types_1.CompletionItemKind.Function },
{ label: 'union', kind: types_1.CompletionItemKind.Function },
{ label: 'input', kind: types_1.CompletionItemKind.Function },
{ label: 'scalar', kind: types_1.CompletionItemKind.Function },
{ label: 'schema', kind: types_1.CompletionItemKind.Function },
]);
return (0, autocompleteUtils_1.hintList)(token, typeSystemCompletionItems);
}

@@ -324,9 +287,15 @@ function getSuggestionsForFieldNames(token, typeInfo, options) {

kind: types_1.CompletionItemKind.Field,
labelDetails: {
detail: ' ' + field.type.toString(),
},
type: field.type,
};
if (options === null || options === void 0 ? void 0 : options.fillLeafsOnComplete) {
const insertText = getInsertText(field);
if (insertText) {
suggestion.insertText = field.name + insertText;
suggestion.insertText = (0, autocompleteUtils_1.getFieldInsertText)(field);
if (!suggestion.insertText) {
suggestion.insertText = (0, autocompleteUtils_1.getInsertText)(field.name, field.type, field.name + (token.state.needsAdvance ? '' : '\n'));
}
if (suggestion.insertText) {
suggestion.insertTextFormat = types_1.InsertTextFormat.Snippet;
suggestion.insertTextMode = vscode_languageserver_types_1.InsertTextMode.adjustIndentation;
suggestion.command = exports.SuggestionCommand;

@@ -342,3 +311,3 @@ }

const namedInputType = (0, graphql_1.getNamedType)(typeInfo.inputType);
const queryVariables = getVariableCompletions(queryText, schema, token).filter(v => v.detail === namedInputType.name);
const queryVariables = getVariableCompletions(queryText, schema, token).filter(v => v.detail === (namedInputType === null || namedInputType === void 0 ? void 0 : namedInputType.name));
if (namedInputType instanceof graphql_1.GraphQLEnumType) {

@@ -390,3 +359,3 @@ const values = namedInputType.getValues();

const inlineInterfaces = new Set();
runOnlineParser(documentText, (_, state) => {
(0, parser_1.runOnlineParser)(documentText, (_, state) => {
var _a, _b, _c, _d, _e;

@@ -484,3 +453,3 @@ if (state.name) {

const typeMap = schema.getTypeMap();
const defState = (0, autocompleteUtils_1.getDefinitionState)(token.state);
const defState = (0, parser_1.getDefinitionState)(token.state);
const fragments = getFragmentDefinitions(queryText);

@@ -501,2 +470,5 @@ if (fragmentDefs && fragmentDefs.length > 0) {

documentation: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
labelDetails: {
detail: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
},
kind: types_1.CompletionItemKind.Field,

@@ -525,3 +497,4 @@ type: typeMap[frag.typeCondition.name.value],

const definitions = Object.create({});
runOnlineParser(queryText, (_, state) => {
(0, parser_1.runOnlineParser)(queryText, (_, state) => {
var _a;
if ((state === null || state === void 0 ? void 0 : state.kind) === parser_1.RuleKinds.VARIABLE && state.name) {

@@ -537,6 +510,10 @@ variableName = state.name;

if (variableName && variableType && !definitions[variableName]) {
const replaceString = token.string === '$' || ((_a = token === null || token === void 0 ? void 0 : token.state) === null || _a === void 0 ? void 0 : _a.kind) === 'Variable'
? variableName
: '$' + variableName;
definitions[variableName] = {
detail: variableType.toString(),
insertText: token.string === '$' ? variableName : '$' + variableName,
label: variableName,
insertText: replaceString,
label: '$' + variableName,
rawInsert: replaceString,
type: variableType,

@@ -554,3 +531,3 @@ kind: types_1.CompletionItemKind.Variable,

const fragmentDefs = [];
runOnlineParser(queryText, (_, state) => {
(0, parser_1.runOnlineParser)(queryText, (_, state) => {
if (state.kind === parser_1.RuleKinds.FRAGMENT_DEFINITION &&

@@ -587,3 +564,3 @@ state.name &&

label: type.name,
documentation: type.description,
documentation: (type === null || type === void 0 ? void 0 : type.description) || '',
kind: types_1.CompletionItemKind.Variable,

@@ -600,3 +577,3 @@ })));

label: directive.name,
documentation: directive.description || '',
documentation: (directive === null || directive === void 0 ? void 0 : directive.description) || '',
kind: types_1.CompletionItemKind.Function,

@@ -607,54 +584,10 @@ })));

}
function getTokenAtPosition(queryText, cursor, offset = 0) {
let styleAtCursor = null;
let stateAtCursor = null;
let stringAtCursor = null;
const token = runOnlineParser(queryText, (stream, state, style, index) => {
if (index !== cursor.line ||
stream.getCurrentPosition() + offset < cursor.character + 1) {
return;
}
styleAtCursor = style;
stateAtCursor = Object.assign({}, state);
stringAtCursor = stream.current();
return 'BREAK';
});
return {
start: token.start,
end: token.end,
string: stringAtCursor || token.string,
state: stateAtCursor || token.state,
style: styleAtCursor || token.style,
};
function getSuggestionsForDirectiveArguments(token, state, schema, _kind) {
const directive = schema.getDirectives().find(d => d.name === state.name);
return (0, autocompleteUtils_1.hintList)(token, (directive === null || directive === void 0 ? void 0 : directive.args.map(arg => ({
label: arg.name,
documentation: arg.description || '',
kind: types_1.CompletionItemKind.Field,
}))) || []);
}
exports.getTokenAtPosition = getTokenAtPosition;
function runOnlineParser(queryText, callback) {
const lines = queryText.split('\n');
const parser = (0, parser_1.onlineParser)();
let state = parser.startState();
let style = '';
let stream = new parser_1.CharacterStream('');
for (let i = 0; i < lines.length; i++) {
stream = new parser_1.CharacterStream(lines[i]);
while (!stream.eol()) {
style = parser.token(stream, state);
const code = callback(stream, state, style, i);
if (code === 'BREAK') {
break;
}
}
callback(stream, state, style, i);
if (!state.kind) {
state = parser.startState();
}
}
return {
start: stream.getStartOfToken(),
end: stream.getCurrentPosition(),
string: stream.current(),
state,
style,
};
}
exports.runOnlineParser = runOnlineParser;
function canUseDirective(state, directive) {

@@ -712,179 +645,2 @@ if (!(state === null || state === void 0 ? void 0 : state.kind)) {

exports.canUseDirective = canUseDirective;
function getTypeInfo(schema, tokenState) {
let argDef;
let argDefs;
let directiveDef;
let enumValue;
let fieldDef;
let inputType;
let objectTypeDef;
let objectFieldDefs;
let parentType;
let type;
let interfaceDef;
(0, autocompleteUtils_1.forEachState)(tokenState, state => {
var _a;
switch (state.kind) {
case parser_1.RuleKinds.QUERY:
case 'ShortQuery':
type = schema.getQueryType();
break;
case parser_1.RuleKinds.MUTATION:
type = schema.getMutationType();
break;
case parser_1.RuleKinds.SUBSCRIPTION:
type = schema.getSubscriptionType();
break;
case parser_1.RuleKinds.INLINE_FRAGMENT:
case parser_1.RuleKinds.FRAGMENT_DEFINITION:
if (state.type) {
type = schema.getType(state.type);
}
break;
case parser_1.RuleKinds.FIELD:
case parser_1.RuleKinds.ALIASED_FIELD: {
if (!type || !state.name) {
fieldDef = null;
}
else {
fieldDef = parentType
? (0, autocompleteUtils_1.getFieldDef)(schema, parentType, state.name)
: null;
type = fieldDef ? fieldDef.type : null;
}
break;
}
case parser_1.RuleKinds.SELECTION_SET:
parentType = (0, graphql_1.getNamedType)(type);
break;
case parser_1.RuleKinds.DIRECTIVE:
directiveDef = state.name ? schema.getDirective(state.name) : null;
break;
case parser_1.RuleKinds.INTERFACE_DEF:
if (state.name) {
objectTypeDef = null;
interfaceDef = new graphql_1.GraphQLInterfaceType({
name: state.name,
interfaces: [],
fields: {},
});
}
break;
case parser_1.RuleKinds.OBJECT_TYPE_DEF:
if (state.name) {
interfaceDef = null;
objectTypeDef = new graphql_1.GraphQLObjectType({
name: state.name,
interfaces: [],
fields: {},
});
}
break;
case parser_1.RuleKinds.ARGUMENTS: {
if (state.prevState) {
switch (state.prevState.kind) {
case parser_1.RuleKinds.FIELD:
argDefs = fieldDef && fieldDef.args;
break;
case parser_1.RuleKinds.DIRECTIVE:
argDefs =
directiveDef && directiveDef.args;
break;
case parser_1.RuleKinds.ALIASED_FIELD: {
const name = (_a = state.prevState) === null || _a === void 0 ? void 0 : _a.name;
if (!name) {
argDefs = null;
break;
}
const field = parentType
? (0, autocompleteUtils_1.getFieldDef)(schema, parentType, name)
: null;
if (!field) {
argDefs = null;
break;
}
argDefs = field.args;
break;
}
default:
argDefs = null;
break;
}
}
else {
argDefs = null;
}
break;
}
case parser_1.RuleKinds.ARGUMENT:
if (argDefs) {
for (let i = 0; i < argDefs.length; i++) {
if (argDefs[i].name === state.name) {
argDef = argDefs[i];
break;
}
}
}
inputType = argDef === null || argDef === void 0 ? void 0 : argDef.type;
break;
case parser_1.RuleKinds.ENUM_VALUE:
const enumType = (0, graphql_1.getNamedType)(inputType);
enumValue =
enumType instanceof graphql_1.GraphQLEnumType
? enumType
.getValues()
.find((val) => val.value === state.name)
: null;
break;
case parser_1.RuleKinds.LIST_VALUE:
const nullableType = (0, graphql_1.getNullableType)(inputType);
inputType =
nullableType instanceof graphql_1.GraphQLList ? nullableType.ofType : null;
break;
case parser_1.RuleKinds.OBJECT_VALUE:
const objectType = (0, graphql_1.getNamedType)(inputType);
objectFieldDefs =
objectType instanceof graphql_1.GraphQLInputObjectType
? objectType.getFields()
: null;
break;
case parser_1.RuleKinds.OBJECT_FIELD:
const objectField = state.name && objectFieldDefs ? objectFieldDefs[state.name] : null;
inputType = objectField === null || objectField === void 0 ? void 0 : objectField.type;
break;
case parser_1.RuleKinds.NAMED_TYPE:
if (state.name) {
type = schema.getType(state.name);
}
break;
}
});
return {
argDef,
argDefs,
directiveDef,
enumValue,
fieldDef,
inputType,
objectFieldDefs,
parentType,
type,
interfaceDef,
objectTypeDef,
};
}
exports.getTypeInfo = getTypeInfo;
var GraphQLDocumentMode;
(function (GraphQLDocumentMode) {
GraphQLDocumentMode["TYPE_SYSTEM"] = "TYPE_SYSTEM";
GraphQLDocumentMode["EXECUTABLE"] = "EXECUTABLE";
})(GraphQLDocumentMode = exports.GraphQLDocumentMode || (exports.GraphQLDocumentMode = {}));
function getDocumentMode(documentText, uri) {
if (uri === null || uri === void 0 ? void 0 : uri.endsWith('.graphqls')) {
return GraphQLDocumentMode.TYPE_SYSTEM;
}
return hasTypeSystemDefinitions(documentText)
? GraphQLDocumentMode.TYPE_SYSTEM
: GraphQLDocumentMode.EXECUTABLE;
}
function unwrapType(state) {

@@ -891,0 +647,0 @@ if (state.prevState &&

@@ -1,2 +0,2 @@

import { FragmentSpreadNode, FragmentDefinitionNode, OperationDefinitionNode, NamedTypeNode } from 'graphql';
import { ASTNode, FragmentSpreadNode, FragmentDefinitionNode, OperationDefinitionNode, NamedTypeNode, GraphQLType } from 'graphql';
import { Definition, FragmentInfo, Uri, ObjectTypeInfo } from '../types';

@@ -7,8 +7,14 @@ import { Range } from '../utils';

definitions: Definition[];
printedName?: string;
};
export declare type DefinitionQueryResponse = DefinitionQueryResult & {
node?: ASTNode | null;
type?: GraphQLType | null;
};
export declare const LANGUAGE = "GraphQL";
export declare function getDefinitionQueryResultForNamedType(text: string, node: NamedTypeNode, dependencies: Array<ObjectTypeInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForField(fieldName: string, typeName: string, dependencies: Array<ObjectTypeInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForArgument(argumentName: string, fieldName: string, typeName: string, dependencies: Array<ObjectTypeInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForFragmentSpread(text: string, fragment: FragmentSpreadNode, dependencies: Array<FragmentInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForDefinitionNode(path: Uri, text: string, definition: FragmentDefinitionNode | OperationDefinitionNode): DefinitionQueryResult;
//# sourceMappingURL=getDefinition.d.ts.map

@@ -12,3 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getDefinitionQueryResultForDefinitionNode = exports.getDefinitionQueryResultForFragmentSpread = exports.getDefinitionQueryResultForField = exports.getDefinitionQueryResultForNamedType = exports.LANGUAGE = void 0;
exports.getDefinitionQueryResultForDefinitionNode = exports.getDefinitionQueryResultForFragmentSpread = exports.getDefinitionQueryResultForArgument = exports.getDefinitionQueryResultForField = exports.getDefinitionQueryResultForNamedType = exports.LANGUAGE = void 0;
const utils_1 = require("../utils");

@@ -42,2 +42,3 @@ exports.LANGUAGE = 'GraphQL';

queryRange: definitions.map(_ => getRange(text, node)),
printedName: name,
};

@@ -65,2 +66,3 @@ });

queryRange: [],
printedName: [typeName, fieldName].join('.'),
};

@@ -70,2 +72,22 @@ });

exports.getDefinitionQueryResultForField = getDefinitionQueryResultForField;
function getDefinitionQueryResultForArgument(argumentName, fieldName, typeName, dependencies) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
dependencies.filter(({ definition }) => definition.name && definition.name.value === typeName);
const definitions = [];
for (const { filePath, content, definition } of dependencies) {
const argDefinition = (_c = (_b = (_a = definition.fields) === null || _a === void 0 ? void 0 : _a.find(item => item.name.value === fieldName)) === null || _b === void 0 ? void 0 : _b.arguments) === null || _c === void 0 ? void 0 : _c.find(item => item.name.value === argumentName);
if (argDefinition == null) {
continue;
}
definitions.push(getDefinitionForArgumentDefinition(filePath || '', content, argDefinition));
}
return {
definitions,
queryRange: [],
printedName: `${[typeName, fieldName].join('.')}(${argumentName})`,
};
});
}
exports.getDefinitionQueryResultForArgument = getDefinitionQueryResultForArgument;
function getDefinitionQueryResultForFragmentSpread(text, fragment, dependencies) {

@@ -82,2 +104,3 @@ return __awaiter(this, void 0, void 0, function* () {

queryRange: definitions.map(_ => getRange(text, fragment)),
printedName: name,
};

@@ -88,5 +111,7 @@ });

function getDefinitionQueryResultForDefinitionNode(path, text, definition) {
var _a;
return {
definitions: [getDefinitionForFragmentDefinition(path, text, definition)],
queryRange: definition.name ? [getRange(text, definition.name)] : [],
printedName: (_a = definition.name) === null || _a === void 0 ? void 0 : _a.value,
};

@@ -133,2 +158,14 @@ }

}
function getDefinitionForArgumentDefinition(path, text, definition) {
const { name } = definition;
assert(name, 'Expected ASTNode to have a Name.');
return {
path,
position: getPosition(text, definition),
range: getRange(text, definition),
name: name.value || '',
language: exports.LANGUAGE,
projectRoot: path,
};
}
//# sourceMappingURL=getDefinition.js.map

@@ -1,4 +0,4 @@

import { GraphQLSchema } from 'graphql';
import { ContextToken } from '../parser';
import { IPosition } from '../types';
import { GraphQLSchema, GraphQLType } from 'graphql';
import type { ContextToken } from '../parser';
import { AllTypeInfo, IPosition } from '../types';
import { Hover } from 'vscode-languageserver-types';

@@ -9,2 +9,7 @@ export declare type HoverConfig = {

export declare function getHoverInformation(schema: GraphQLSchema, queryText: string, cursor: IPosition, contextToken?: ContextToken, config?: HoverConfig): Hover['contents'];
export declare function renderField(into: string[], typeInfo: AllTypeInfo, options: any): void;
export declare function renderDirective(into: string[], typeInfo: AllTypeInfo, _options: any): void;
export declare function renderArg(into: string[], typeInfo: AllTypeInfo, options: any): void;
export declare function renderEnumValue(into: string[], typeInfo: AllTypeInfo, options: any): void;
export declare function renderType(into: string[], typeInfo: AllTypeInfo, options: any, t: GraphQLType): void;
//# sourceMappingURL=getHoverInformation.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHoverInformation = void 0;
exports.renderType = exports.renderEnumValue = exports.renderArg = exports.renderDirective = exports.renderField = exports.getHoverInformation = void 0;
const graphql_1 = require("graphql");
const getAutocompleteSuggestions_1 = require("./getAutocompleteSuggestions");
const parser_1 = require("../parser");
function getHoverInformation(schema, queryText, cursor, contextToken, config) {
const token = contextToken || (0, getAutocompleteSuggestions_1.getTokenAtPosition)(queryText, cursor);
if (!schema || !token || !token.state) {
const options = Object.assign(Object.assign({}, config), { schema });
const context = (0, parser_1.getContextAtPosition)(queryText, cursor, schema, contextToken);
if (!context) {
return '';
}
const { typeInfo, token } = context;
const { kind, step } = token.state;
const typeInfo = (0, getAutocompleteSuggestions_1.getTypeInfo)(schema, token.state);
const options = Object.assign(Object.assign({}, config), { schema });
if ((kind === 'Field' && step === 0 && typeInfo.fieldDef) ||
(kind === 'AliasedField' && step === 2 && typeInfo.fieldDef)) {
(kind === 'AliasedField' && step === 2 && typeInfo.fieldDef) ||
(kind === 'ObjectField' && step === 0 && typeInfo.fieldDef)) {
const into = [];

@@ -31,2 +32,10 @@ renderMdCodeStart(into, options);

}
if (kind === 'Variable' && typeInfo.type) {
const into = [];
renderMdCodeStart(into, options);
renderType(into, typeInfo, options, typeInfo.type);
renderMdCodeEnd(into, options);
renderDescription(into, options, typeInfo.type);
return into.join('').trim();
}
if (kind === 'Argument' && step === 0 && typeInfo.argDef) {

@@ -75,2 +84,3 @@ const into = [];

}
exports.renderField = renderField;
function renderQualifiedField(into, typeInfo, options) {

@@ -94,2 +104,3 @@ if (!typeInfo.fieldDef) {

}
exports.renderDirective = renderDirective;
function renderArg(into, typeInfo, options) {

@@ -111,2 +122,3 @@ if (typeInfo.directiveDef) {

}
exports.renderArg = renderArg;
function renderTypeAnnotation(into, typeInfo, options, t) {

@@ -125,2 +137,3 @@ text(into, ': ');

}
exports.renderEnumValue = renderEnumValue;
function renderType(into, typeInfo, options, t) {

@@ -143,2 +156,3 @@ if (!t) {

}
exports.renderType = renderType;
function renderDescription(into, options, def) {

@@ -145,0 +159,0 @@ if (!def) {

@@ -5,3 +5,5 @@ export { default as CharacterStream } from './CharacterStream';

export { default as onlineParser, ParserOptions } from './onlineParser';
export { runOnlineParser, type ParserCallbackFn, getTokenAtPosition, getContextAtPosition, GraphQLDocumentMode, getDocumentMode, } from './api';
export { getTypeInfo, getDefinitionState, getFieldDef } from './getTypeInfo';
export * from './types';
//# sourceMappingURL=index.d.ts.map

@@ -20,3 +20,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.onlineParser = exports.t = exports.p = exports.opt = exports.list = exports.butNot = exports.isIgnored = exports.ParseRules = exports.LexRules = exports.CharacterStream = void 0;
exports.getFieldDef = exports.getDefinitionState = exports.getTypeInfo = exports.getDocumentMode = exports.GraphQLDocumentMode = exports.getContextAtPosition = exports.getTokenAtPosition = exports.runOnlineParser = exports.onlineParser = exports.t = exports.p = exports.opt = exports.list = exports.butNot = exports.isIgnored = exports.ParseRules = exports.LexRules = exports.CharacterStream = void 0;
var CharacterStream_1 = require("./CharacterStream");

@@ -36,3 +36,13 @@ Object.defineProperty(exports, "CharacterStream", { enumerable: true, get: function () { return __importDefault(CharacterStream_1).default; } });

Object.defineProperty(exports, "onlineParser", { enumerable: true, get: function () { return __importDefault(onlineParser_1).default; } });
var api_1 = require("./api");
Object.defineProperty(exports, "runOnlineParser", { enumerable: true, get: function () { return api_1.runOnlineParser; } });
Object.defineProperty(exports, "getTokenAtPosition", { enumerable: true, get: function () { return api_1.getTokenAtPosition; } });
Object.defineProperty(exports, "getContextAtPosition", { enumerable: true, get: function () { return api_1.getContextAtPosition; } });
Object.defineProperty(exports, "GraphQLDocumentMode", { enumerable: true, get: function () { return api_1.GraphQLDocumentMode; } });
Object.defineProperty(exports, "getDocumentMode", { enumerable: true, get: function () { return api_1.getDocumentMode; } });
var getTypeInfo_1 = require("./getTypeInfo");
Object.defineProperty(exports, "getTypeInfo", { enumerable: true, get: function () { return getTypeInfo_1.getTypeInfo; } });
Object.defineProperty(exports, "getDefinitionState", { enumerable: true, get: function () { return getTypeInfo_1.getDefinitionState; } });
Object.defineProperty(exports, "getFieldDef", { enumerable: true, get: function () { return getTypeInfo_1.getFieldDef; } });
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map

@@ -77,2 +77,3 @@ import { Kind } from 'graphql';

TYPE: 'Type';
VARIABLE: 'Variable';
};

@@ -108,2 +109,3 @@ export declare const RuleKinds: {

TYPE: 'Type';
VARIABLE: 'Variable';
NAME: Kind.NAME;

@@ -119,3 +121,2 @@ DOCUMENT: Kind.DOCUMENT;

FRAGMENT_DEFINITION: Kind.FRAGMENT_DEFINITION;
VARIABLE: Kind.VARIABLE;
INT: Kind.INT;

@@ -154,3 +155,3 @@ FLOAT: Kind.FLOAT;

};
export declare type _RuleKinds = typeof Kind & typeof AdditionalRuleKinds;
export declare type _RuleKinds = Omit<typeof Kind, 'VARIABLE'> & typeof AdditionalRuleKinds;
export declare type RuleKind = _RuleKinds[keyof _RuleKinds];

@@ -157,0 +158,0 @@ export declare type RuleKindEnum = RuleKind;

@@ -34,4 +34,5 @@ "use strict";

TYPE: 'Type',
VARIABLE: 'Variable',
};
exports.RuleKinds = Object.assign(Object.assign({}, graphql_1.Kind), exports.AdditionalRuleKinds);
//# sourceMappingURL=types.js.map

@@ -6,2 +6,3 @@ import type { Diagnostic as DiagnosticType, CompletionItem as CompletionItemType } from 'vscode-languageserver-types';

import type { GraphQLConfig, GraphQLProjectConfig, GraphQLExtensionDeclaration } from 'graphql-config';
export { GraphQLDocumentMode } from './parser';
export type { GraphQLConfig, GraphQLProjectConfig, GraphQLExtensionDeclaration, };

@@ -11,7 +12,5 @@ export interface GraphQLCache {

getProjectForFile: (uri: string) => GraphQLProjectConfig | void;
getObjectTypeDependencies: (query: string, fragmentDefinitions: Map<string, ObjectTypeInfo>) => Promise<ObjectTypeInfo[]>;
getObjectTypeDependenciesForAST: (parsedQuery: ASTNode, fragmentDefinitions: Map<string, ObjectTypeInfo>) => Promise<ObjectTypeInfo[]>;
getObjectTypeDefinitions: (graphQLConfig: GraphQLProjectConfig) => Promise<Map<string, ObjectTypeInfo>>;
updateObjectTypeDefinition: (rootDir: Uri, filePath: Uri, contents: CachedContent[]) => Promise<void>;
updateObjectTypeDefinitionCache: (rootDir: Uri, filePath: Uri, exists: boolean) => Promise<void>;
getFragmentDependencies: (query: string, fragmentDefinitions: Maybe<Map<string, FragmentInfo>>) => Promise<FragmentInfo[]>;

@@ -21,4 +20,3 @@ getFragmentDependenciesForAST: (parsedQuery: ASTNode, fragmentDefinitions: Map<string, FragmentInfo>) => Promise<FragmentInfo[]>;

updateFragmentDefinition: (rootDir: Uri, filePath: Uri, contents: CachedContent[]) => Promise<void>;
updateFragmentDefinitionCache: (rootDir: Uri, filePath: Uri, exists: boolean) => Promise<void>;
getSchema: (appName?: string, queryHasExtensions?: boolean) => Promise<GraphQLSchema | null>;
getSchema: (appName: string, queryHasExtensions?: boolean) => Promise<GraphQLSchema | null>;
}

@@ -96,2 +94,3 @@ export interface IPosition {

command?: CompletionItemType['command'];
rawInsert?: string;
};

@@ -106,2 +105,3 @@ export declare type Definition = {

projectRoot?: Uri;
locator?: string;
};

@@ -108,0 +108,0 @@ export declare type TokenKind = 'keyword' | 'class-name' | 'constructor' | 'method' | 'param' | 'string' | 'whitespace' | 'plain' | 'type';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompletionItemKind = exports.FileChangeTypeKind = exports.InsertTextFormat = void 0;
exports.CompletionItemKind = exports.FileChangeTypeKind = exports.GraphQLDocumentMode = exports.InsertTextFormat = void 0;
var vscode_languageserver_types_1 = require("vscode-languageserver-types");
Object.defineProperty(exports, "InsertTextFormat", { enumerable: true, get: function () { return vscode_languageserver_types_1.InsertTextFormat; } });
var parser_1 = require("./parser");
Object.defineProperty(exports, "GraphQLDocumentMode", { enumerable: true, get: function () { return parser_1.GraphQLDocumentMode; } });
exports.FileChangeTypeKind = {

@@ -7,0 +9,0 @@ Created: 1,

@@ -18,2 +18,5 @@ "use strict";

graphql_1.UniqueInputFieldNamesRule,
graphql_1.UniqueVariableNamesRule,
graphql_1.FragmentsOnCompositeTypesRule,
graphql_1.ProvidedRequiredArgumentsRule,
];

@@ -20,0 +23,0 @@ function validateWithCustomRules(schema, ast, customRules, isRelayCompatMode, isSchemaDocument) {

@@ -1,3 +0,3 @@

export { getAutocompleteSuggestions, getDefinitionQueryResultForDefinitionNode, getDefinitionQueryResultForFragmentSpread, getDefinitionQueryResultForNamedType, getDefinitionQueryResultForField, getDefinitionState, getDiagnostics, getFieldDef, getFragmentDefinitions, getHoverInformation, getOutline, getRange, getTokenAtPosition, getTypeInfo, getVariableCompletions, SEVERITY, Severity, HoverConfig, SeverityEnum, DIAGNOSTIC_SEVERITY, DefinitionQueryResult, canUseDirective, SuggestionCommand, AutocompleteSuggestionOptions, validateQuery, } from './interface';
export { onlineParser, ParseRules, CharacterStream, RuleKinds, LexRules, isIgnored, p, list, t, opt, } from './parser';
export { getAutocompleteSuggestions, getDefinitionQueryResultForDefinitionNode, getDefinitionQueryResultForFragmentSpread, getDefinitionQueryResultForNamedType, getDefinitionQueryResultForField, getDefinitionQueryResultForArgument, getDiagnostics, getFragmentDefinitions, getHoverInformation, getOutline, getRange, getTypeInfo, getVariableCompletions, SEVERITY, Severity, HoverConfig, SeverityEnum, DIAGNOSTIC_SEVERITY, DefinitionQueryResult, DefinitionQueryResponse, canUseDirective, SuggestionCommand, AutocompleteSuggestionOptions, validateQuery, } from './interface';
export { onlineParser, ParseRules, CharacterStream, RuleKinds, LexRules, isIgnored, p, list, t, opt, getTokenAtPosition, GraphQLDocumentMode, getDefinitionState, getFieldDef, } from './parser';
export type { RuleOrString, ParserOptions, ParseRule, TokenPattern, State, CharacterStreamInterface, RuleKindEnum, Token, ContextToken, ContextTokenForCodeMirror, ContextTokenUnion, RuleKind, } from './parser';

@@ -4,0 +4,0 @@ export type { CompletionItem, GraphQLProjectConfig, Maybe, IPosition, Diagnostic, IRange, Definition, CachedContent, GraphQLConfig, GraphQLFileMetadata, Uri, ObjectTypeInfo, Outline, OutlineTree, FragmentInfo, GraphQLFileInfo, FileChangeType, GraphQLCache, GraphQLExtensionDeclaration, } from './types';

@@ -1,5 +0,5 @@

export { getAutocompleteSuggestions, getDefinitionQueryResultForDefinitionNode, getDefinitionQueryResultForFragmentSpread, getDefinitionQueryResultForNamedType, getDefinitionQueryResultForField, getDefinitionState, getDiagnostics, getFieldDef, getFragmentDefinitions, getHoverInformation, getOutline, getRange, getTokenAtPosition, getTypeInfo, getVariableCompletions, SEVERITY, DIAGNOSTIC_SEVERITY, canUseDirective, SuggestionCommand, validateQuery, } from './interface';
export { onlineParser, ParseRules, CharacterStream, RuleKinds, LexRules, isIgnored, p, list, t, opt, } from './parser';
export { getAutocompleteSuggestions, getDefinitionQueryResultForDefinitionNode, getDefinitionQueryResultForFragmentSpread, getDefinitionQueryResultForNamedType, getDefinitionQueryResultForField, getDefinitionQueryResultForArgument, getDiagnostics, getFragmentDefinitions, getHoverInformation, getOutline, getRange, getTypeInfo, getVariableCompletions, SEVERITY, DIAGNOSTIC_SEVERITY, canUseDirective, SuggestionCommand, validateQuery, } from './interface';
export { onlineParser, ParseRules, CharacterStream, RuleKinds, LexRules, isIgnored, p, list, t, opt, getTokenAtPosition, GraphQLDocumentMode, getDefinitionState, getFieldDef, } from './parser';
export { CompletionItemKind, FileChangeTypeKind } from './types';
export { getASTNodeAtPosition, getFragmentDependencies, getFragmentDependenciesForAST, getOperationASTFacts, getOperationFacts, getQueryFacts, getVariablesJSONSchema, offsetToPosition, pointToOffset, Position, collectVariables, validateWithCustomRules, Range, } from './utils';
//# sourceMappingURL=index.js.map

@@ -1,9 +0,9 @@

import { GraphQLField, GraphQLSchema, GraphQLType } from 'graphql';
import { CompletionItemBase, AllTypeInfo } from '../types';
import { ContextTokenUnion, State } from '../parser';
export declare function getDefinitionState(tokenState: State): State | null | undefined;
export declare function getFieldDef(schema: GraphQLSchema, type: GraphQLType, fieldName: string): GraphQLField<any, any> | null | undefined;
export declare function forEachState(stack: State, fn: (state: State) => AllTypeInfo | null | void): void;
import { GraphQLField, GraphQLType } from 'graphql';
import { CompletionItemBase } from '../types';
import { ContextTokenUnion } from '../parser';
export declare function objectValues<T>(object: Record<string, T>): Array<T>;
export declare function hintList<T extends CompletionItemBase>(token: ContextTokenUnion, list: Array<T>): Array<T>;
export declare const getInsertText: (prefix: string, type?: GraphQLType | undefined, fallback?: string | undefined) => string;
export declare const getInputInsertText: (prefix: string, type: GraphQLType, fallback?: string | undefined) => string;
export declare const getFieldInsertText: (field: GraphQLField<null, null>) => string | undefined;
//# sourceMappingURL=autocompleteUtils.d.ts.map

@@ -1,43 +0,2 @@

import { isCompositeType, SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, } from 'graphql';
export function getDefinitionState(tokenState) {
let definitionState;
forEachState(tokenState, (state) => {
switch (state.kind) {
case 'Query':
case 'ShortQuery':
case 'Mutation':
case 'Subscription':
case 'FragmentDefinition':
definitionState = state;
break;
}
});
return definitionState;
}
export function getFieldDef(schema, type, fieldName) {
if (fieldName === SchemaMetaFieldDef.name && schema.getQueryType() === type) {
return SchemaMetaFieldDef;
}
if (fieldName === TypeMetaFieldDef.name && schema.getQueryType() === type) {
return TypeMetaFieldDef;
}
if (fieldName === TypeNameMetaFieldDef.name && isCompositeType(type)) {
return TypeNameMetaFieldDef;
}
if ('getFields' in type) {
return type.getFields()[fieldName];
}
return null;
}
export function forEachState(stack, fn) {
const reverseStateStack = [];
let state = stack;
while (state === null || state === void 0 ? void 0 : state.kind) {
reverseStateStack.push(state);
state = state.prevState;
}
for (let i = reverseStateStack.length - 1; i >= 0; i--) {
fn(reverseStateStack[i]);
}
}
import { isListType, isObjectType, isInputObjectType, getNamedType, isAbstractType, } from 'graphql';
export function objectValues(object) {

@@ -56,3 +15,6 @@ const keys = Object.keys(object);

function filterAndSortList(list, text) {
if (!text) {
if (!text ||
text.trim() === '' ||
text.trim() === ':' ||
text.trim() === '{') {
return filterNonEmpty(list, entry => !entry.isDeprecated);

@@ -108,2 +70,31 @@ }

}
const insertSuffix = (n) => ` {\n $${n !== null && n !== void 0 ? n : 1}\n}`;
export const getInsertText = (prefix, type, fallback) => {
if (!type) {
return fallback !== null && fallback !== void 0 ? fallback : prefix;
}
const namedType = getNamedType(type);
if (isObjectType(namedType) ||
isInputObjectType(namedType) ||
isListType(namedType) ||
isAbstractType(namedType)) {
return prefix + insertSuffix();
}
return fallback !== null && fallback !== void 0 ? fallback : prefix;
};
export const getInputInsertText = (prefix, type, fallback) => {
if (isListType(type)) {
const baseType = getNamedType(type.ofType);
return prefix + `[${getInsertText('', baseType, '$1')}]`;
}
return getInsertText(prefix, type, fallback);
};
export const getFieldInsertText = (field) => {
const requiredArgs = field.args.filter(arg => arg.type.toString().endsWith('!'));
if (!requiredArgs.length) {
return;
}
return (field.name +
`(${requiredArgs.map((arg, i) => `${arg.name}: $${i + 1}`)}) ${getInsertText('', field.type, '\n')}`);
};
//# sourceMappingURL=autocompleteUtils.js.map
import { FragmentDefinitionNode, GraphQLDirective, GraphQLSchema } from 'graphql';
import { CompletionItem, AllTypeInfo, IPosition } from '../types';
import { CharacterStream, ContextToken, State, ContextTokenForCodeMirror } from '../parser';
import { CompletionItem, IPosition } from '../types';
import type { ContextToken, State, ContextTokenForCodeMirror } from '../parser';
import { getTypeInfo, runOnlineParser, GraphQLDocumentMode } from '../parser';
export { runOnlineParser, getTypeInfo };
export declare const SuggestionCommand: {

@@ -10,3 +12,2 @@ command: string;

fillLeafsOnComplete?: boolean;
schema?: GraphQLSchema;
uri?: string;

@@ -18,12 +19,3 @@ mode?: GraphQLDocumentMode;

export declare function getFragmentDefinitions(queryText: string): Array<FragmentDefinitionNode>;
export declare function getTokenAtPosition(queryText: string, cursor: IPosition, offset?: number): ContextToken;
declare type callbackFnType = (stream: CharacterStream, state: State, style: string, index: number) => void | 'BREAK';
export declare function runOnlineParser(queryText: string, callback: callbackFnType): ContextToken;
export declare function canUseDirective(state: State['prevState'], directive: GraphQLDirective): boolean;
export declare function getTypeInfo(schema: GraphQLSchema, tokenState: State): AllTypeInfo;
export declare enum GraphQLDocumentMode {
TYPE_SYSTEM = "TYPE_SYSTEM",
EXECUTABLE = "EXECUTABLE"
}
export {};
//# sourceMappingURL=getAutocompleteSuggestions.d.ts.map

@@ -1,5 +0,7 @@

import { isInterfaceType, GraphQLInterfaceType, GraphQLObjectType, Kind, DirectiveLocation, isListType, isNonNullType, isScalarType, isObjectType, isUnionType, isEnumType, isInputObjectType, isOutputType, GraphQLBoolean, GraphQLEnumType, GraphQLInputObjectType, GraphQLList, SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, assertAbstractType, doTypesOverlap, getNamedType, getNullableType, isAbstractType, isCompositeType, isInputType, visit, BREAK, parse, } from 'graphql';
import { isInterfaceType, GraphQLInterfaceType, GraphQLObjectType, Kind, DirectiveLocation, isScalarType, isObjectType, isUnionType, isEnumType, isInputObjectType, isOutputType, GraphQLBoolean, GraphQLEnumType, SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, assertAbstractType, doTypesOverlap, getNamedType, isAbstractType, isCompositeType, isInputType, visit, parse, } from 'graphql';
import { CompletionItemKind, InsertTextFormat, } from '../types';
import { CharacterStream, onlineParser, RuleKinds, } from '../parser';
import { forEachState, getDefinitionState, getFieldDef, hintList, objectValues, } from './autocompleteUtils';
import { getTypeInfo, runOnlineParser, RuleKinds, getContextAtPosition, getDefinitionState, GraphQLDocumentMode, } from '../parser';
import { hintList, objectValues, getInputInsertText, getFieldInsertText, getInsertText, } from './autocompleteUtils';
import { InsertTextMode } from 'vscode-languageserver-types';
export { runOnlineParser, getTypeInfo };
export const SuggestionCommand = {

@@ -25,54 +27,11 @@ command: 'editor.action.triggerSuggest',

};
const typeSystemKinds = [
Kind.SCHEMA_DEFINITION,
Kind.OPERATION_TYPE_DEFINITION,
Kind.SCALAR_TYPE_DEFINITION,
Kind.OBJECT_TYPE_DEFINITION,
Kind.INTERFACE_TYPE_DEFINITION,
Kind.UNION_TYPE_DEFINITION,
Kind.ENUM_TYPE_DEFINITION,
Kind.INPUT_OBJECT_TYPE_DEFINITION,
Kind.DIRECTIVE_DEFINITION,
Kind.SCHEMA_EXTENSION,
Kind.SCALAR_TYPE_EXTENSION,
Kind.OBJECT_TYPE_EXTENSION,
Kind.INTERFACE_TYPE_EXTENSION,
Kind.UNION_TYPE_EXTENSION,
Kind.ENUM_TYPE_EXTENSION,
Kind.INPUT_OBJECT_TYPE_EXTENSION,
];
const hasTypeSystemDefinitions = (sdl) => {
let hasTypeSystemDef = false;
if (sdl) {
try {
visit(parse(sdl), {
enter(node) {
if (node.kind === 'Document') {
return;
}
if (typeSystemKinds.includes(node.kind)) {
hasTypeSystemDef = true;
return BREAK;
}
return false;
},
});
}
catch (_a) {
return hasTypeSystemDef;
}
}
return hasTypeSystemDef;
};
export function getAutocompleteSuggestions(schema, queryText, cursor, contextToken, fragmentDefs, options) {
var _a;
const opts = Object.assign(Object.assign({}, options), { schema });
const token = contextToken || getTokenAtPosition(queryText, cursor, 1);
const state = token.state.kind === 'Invalid' ? token.state.prevState : token.state;
const mode = (options === null || options === void 0 ? void 0 : options.mode) || getDocumentMode(queryText, options === null || options === void 0 ? void 0 : options.uri);
if (!state) {
const context = getContextAtPosition(queryText, cursor, schema, contextToken, options);
if (!context) {
return [];
}
const { state, typeInfo, mode, token } = context;
const { kind, step, prevState } = state;
const typeInfo = getTypeInfo(schema, token.state);
if (kind === RuleKinds.DOCUMENT) {

@@ -82,3 +41,6 @@ if (mode === GraphQLDocumentMode.TYPE_SYSTEM) {

}
return getSuggestionsForExecutableDefinitions(token);
if (mode === GraphQLDocumentMode.EXECUTABLE) {
return getSuggestionsForExecutableDefinitions(token);
}
return getSuggestionsForUnknownDocumentMode(token);
}

@@ -157,5 +119,9 @@ if (kind === RuleKinds.EXTEND_DEF) {

label: argDef.name,
insertText: argDef.name + ': ',
insertText: getInputInsertText(argDef.name + ': ', argDef.type),
insertTextMode: InsertTextMode.adjustIndentation,
insertTextFormat: InsertTextFormat.Snippet,
command: SuggestionCommand,
detail: String(argDef.type),
labelDetails: {
detail: ' ' + String(argDef.type),
},
documentation: (_a = argDef.description) !== null && _a !== void 0 ? _a : undefined,

@@ -180,5 +146,9 @@ kind: CompletionItemKind.Variable,

detail: String(field.type),
documentation: (_a = field.description) !== null && _a !== void 0 ? _a : undefined,
documentation: (_a = field === null || field === void 0 ? void 0 : field.description) !== null && _a !== void 0 ? _a : undefined,
kind: completionKind,
type: field.type,
insertText: getInputInsertText(field.name + ': ', field.type),
insertTextMode: InsertTextMode.adjustIndentation,
insertTextFormat: InsertTextFormat.Snippet,
command: SuggestionCommand,
});

@@ -210,23 +180,27 @@ }));

const unwrappedState = unwrapType(state);
if ((mode === GraphQLDocumentMode.TYPE_SYSTEM &&
!unwrappedState.needsAdvance &&
kind === RuleKinds.NAMED_TYPE) ||
kind === RuleKinds.LIST_TYPE) {
if (unwrappedState.kind === RuleKinds.FIELD_DEF) {
return hintList(token, Object.values(schema.getTypeMap())
.filter(type => isOutputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
})));
}
if (unwrappedState.kind === RuleKinds.INPUT_VALUE_DEF) {
return hintList(token, Object.values(schema.getTypeMap())
.filter(type => isInputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
})));
}
if (unwrappedState.kind === RuleKinds.FIELD_DEF) {
return hintList(token, Object.values(schema.getTypeMap())
.filter(type => isOutputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
insertText: (options === null || options === void 0 ? void 0 : options.fillLeafsOnComplete)
? type.name + '\n'
: type.name,
insertTextMode: InsertTextMode.adjustIndentation,
})));
}
if (unwrappedState.kind === RuleKinds.INPUT_VALUE_DEF && step === 2) {
return hintList(token, Object.values(schema.getTypeMap())
.filter(type => isInputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
insertText: (options === null || options === void 0 ? void 0 : options.fillLeafsOnComplete)
? type.name + '\n$1'
: type.name,
insertTextMode: InsertTextMode.adjustIndentation,
insertTextFormat: InsertTextFormat.Snippet,
})));
}
if ((kind === RuleKinds.VARIABLE_DEFINITION && step === 2) ||

@@ -244,52 +218,40 @@ (kind === RuleKinds.LIST_TYPE && step === 1) ||

}
if (kind === RuleKinds.DIRECTIVE_DEF) {
return getSuggestionsForDirectiveArguments(token, state, schema, kind);
}
return [];
}
const insertSuffix = ' {\n $1\n}';
const getInsertText = (field) => {
const { type } = field;
if (isCompositeType(type)) {
return insertSuffix;
}
if (isListType(type) && isCompositeType(type.ofType)) {
return insertSuffix;
}
if (isNonNullType(type)) {
if (isCompositeType(type.ofType)) {
return insertSuffix;
}
if (isListType(type.ofType) && isCompositeType(type.ofType.ofType)) {
return insertSuffix;
}
}
return null;
};
const typeSystemCompletionItems = [
{ label: 'type', kind: CompletionItemKind.Function },
{ label: 'interface', kind: CompletionItemKind.Function },
{ label: 'union', kind: CompletionItemKind.Function },
{ label: 'input', kind: CompletionItemKind.Function },
{ label: 'scalar', kind: CompletionItemKind.Function },
{ label: 'schema', kind: CompletionItemKind.Function },
];
const executableCompletionItems = [
{ label: 'query', kind: CompletionItemKind.Function },
{ label: 'mutation', kind: CompletionItemKind.Function },
{ label: 'subscription', kind: CompletionItemKind.Function },
{ label: 'fragment', kind: CompletionItemKind.Function },
{ label: '{', kind: CompletionItemKind.Constructor },
];
function getSuggestionsForTypeSystemDefinitions(token) {
return hintList(token, [
{ label: 'extend', kind: CompletionItemKind.Function },
{ label: 'type', kind: CompletionItemKind.Function },
{ label: 'interface', kind: CompletionItemKind.Function },
{ label: 'union', kind: CompletionItemKind.Function },
{ label: 'input', kind: CompletionItemKind.Function },
{ label: 'scalar', kind: CompletionItemKind.Function },
{ label: 'schema', kind: CompletionItemKind.Function },
...typeSystemCompletionItems,
]);
}
function getSuggestionsForExecutableDefinitions(token) {
return hintList(token, executableCompletionItems);
}
function getSuggestionsForUnknownDocumentMode(token) {
return hintList(token, [
{ label: 'query', kind: CompletionItemKind.Function },
{ label: 'mutation', kind: CompletionItemKind.Function },
{ label: 'subscription', kind: CompletionItemKind.Function },
{ label: 'fragment', kind: CompletionItemKind.Function },
{ label: '{', kind: CompletionItemKind.Constructor },
{ label: 'extend', kind: CompletionItemKind.Function },
...executableCompletionItems,
...typeSystemCompletionItems,
]);
}
function getSuggestionsForExtensionDefinitions(token) {
return hintList(token, [
{ label: 'type', kind: CompletionItemKind.Function },
{ label: 'interface', kind: CompletionItemKind.Function },
{ label: 'union', kind: CompletionItemKind.Function },
{ label: 'input', kind: CompletionItemKind.Function },
{ label: 'scalar', kind: CompletionItemKind.Function },
{ label: 'schema', kind: CompletionItemKind.Function },
]);
return hintList(token, typeSystemCompletionItems);
}

@@ -321,9 +283,15 @@ function getSuggestionsForFieldNames(token, typeInfo, options) {

kind: CompletionItemKind.Field,
labelDetails: {
detail: ' ' + field.type.toString(),
},
type: field.type,
};
if (options === null || options === void 0 ? void 0 : options.fillLeafsOnComplete) {
const insertText = getInsertText(field);
if (insertText) {
suggestion.insertText = field.name + insertText;
suggestion.insertText = getFieldInsertText(field);
if (!suggestion.insertText) {
suggestion.insertText = getInsertText(field.name, field.type, field.name + (token.state.needsAdvance ? '' : '\n'));
}
if (suggestion.insertText) {
suggestion.insertTextFormat = InsertTextFormat.Snippet;
suggestion.insertTextMode = InsertTextMode.adjustIndentation;
suggestion.command = SuggestionCommand;

@@ -339,3 +307,3 @@ }

const namedInputType = getNamedType(typeInfo.inputType);
const queryVariables = getVariableCompletions(queryText, schema, token).filter(v => v.detail === namedInputType.name);
const queryVariables = getVariableCompletions(queryText, schema, token).filter(v => v.detail === (namedInputType === null || namedInputType === void 0 ? void 0 : namedInputType.name));
if (namedInputType instanceof GraphQLEnumType) {

@@ -496,2 +464,5 @@ const values = namedInputType.getValues();

documentation: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
labelDetails: {
detail: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
},
kind: CompletionItemKind.Field,

@@ -521,2 +492,3 @@ type: typeMap[frag.typeCondition.name.value],

runOnlineParser(queryText, (_, state) => {
var _a;
if ((state === null || state === void 0 ? void 0 : state.kind) === RuleKinds.VARIABLE && state.name) {

@@ -532,6 +504,10 @@ variableName = state.name;

if (variableName && variableType && !definitions[variableName]) {
const replaceString = token.string === '$' || ((_a = token === null || token === void 0 ? void 0 : token.state) === null || _a === void 0 ? void 0 : _a.kind) === 'Variable'
? variableName
: '$' + variableName;
definitions[variableName] = {
detail: variableType.toString(),
insertText: token.string === '$' ? variableName : '$' + variableName,
label: variableName,
insertText: replaceString,
label: '$' + variableName,
rawInsert: replaceString,
type: variableType,

@@ -579,3 +555,3 @@ kind: CompletionItemKind.Variable,

label: type.name,
documentation: type.description,
documentation: (type === null || type === void 0 ? void 0 : type.description) || '',
kind: CompletionItemKind.Variable,

@@ -592,3 +568,3 @@ })));

label: directive.name,
documentation: directive.description || '',
documentation: (directive === null || directive === void 0 ? void 0 : directive.description) || '',
kind: CompletionItemKind.Function,

@@ -599,52 +575,10 @@ })));

}
export function getTokenAtPosition(queryText, cursor, offset = 0) {
let styleAtCursor = null;
let stateAtCursor = null;
let stringAtCursor = null;
const token = runOnlineParser(queryText, (stream, state, style, index) => {
if (index !== cursor.line ||
stream.getCurrentPosition() + offset < cursor.character + 1) {
return;
}
styleAtCursor = style;
stateAtCursor = Object.assign({}, state);
stringAtCursor = stream.current();
return 'BREAK';
});
return {
start: token.start,
end: token.end,
string: stringAtCursor || token.string,
state: stateAtCursor || token.state,
style: styleAtCursor || token.style,
};
function getSuggestionsForDirectiveArguments(token, state, schema, _kind) {
const directive = schema.getDirectives().find(d => d.name === state.name);
return hintList(token, (directive === null || directive === void 0 ? void 0 : directive.args.map(arg => ({
label: arg.name,
documentation: arg.description || '',
kind: CompletionItemKind.Field,
}))) || []);
}
export function runOnlineParser(queryText, callback) {
const lines = queryText.split('\n');
const parser = onlineParser();
let state = parser.startState();
let style = '';
let stream = new CharacterStream('');
for (let i = 0; i < lines.length; i++) {
stream = new CharacterStream(lines[i]);
while (!stream.eol()) {
style = parser.token(stream, state);
const code = callback(stream, state, style, i);
if (code === 'BREAK') {
break;
}
}
callback(stream, state, style, i);
if (!state.kind) {
state = parser.startState();
}
}
return {
start: stream.getStartOfToken(),
end: stream.getCurrentPosition(),
string: stream.current(),
state,
style,
};
}
export function canUseDirective(state, directive) {

@@ -701,178 +635,2 @@ if (!(state === null || state === void 0 ? void 0 : state.kind)) {

}
export function getTypeInfo(schema, tokenState) {
let argDef;
let argDefs;
let directiveDef;
let enumValue;
let fieldDef;
let inputType;
let objectTypeDef;
let objectFieldDefs;
let parentType;
let type;
let interfaceDef;
forEachState(tokenState, state => {
var _a;
switch (state.kind) {
case RuleKinds.QUERY:
case 'ShortQuery':
type = schema.getQueryType();
break;
case RuleKinds.MUTATION:
type = schema.getMutationType();
break;
case RuleKinds.SUBSCRIPTION:
type = schema.getSubscriptionType();
break;
case RuleKinds.INLINE_FRAGMENT:
case RuleKinds.FRAGMENT_DEFINITION:
if (state.type) {
type = schema.getType(state.type);
}
break;
case RuleKinds.FIELD:
case RuleKinds.ALIASED_FIELD: {
if (!type || !state.name) {
fieldDef = null;
}
else {
fieldDef = parentType
? getFieldDef(schema, parentType, state.name)
: null;
type = fieldDef ? fieldDef.type : null;
}
break;
}
case RuleKinds.SELECTION_SET:
parentType = getNamedType(type);
break;
case RuleKinds.DIRECTIVE:
directiveDef = state.name ? schema.getDirective(state.name) : null;
break;
case RuleKinds.INTERFACE_DEF:
if (state.name) {
objectTypeDef = null;
interfaceDef = new GraphQLInterfaceType({
name: state.name,
interfaces: [],
fields: {},
});
}
break;
case RuleKinds.OBJECT_TYPE_DEF:
if (state.name) {
interfaceDef = null;
objectTypeDef = new GraphQLObjectType({
name: state.name,
interfaces: [],
fields: {},
});
}
break;
case RuleKinds.ARGUMENTS: {
if (state.prevState) {
switch (state.prevState.kind) {
case RuleKinds.FIELD:
argDefs = fieldDef && fieldDef.args;
break;
case RuleKinds.DIRECTIVE:
argDefs =
directiveDef && directiveDef.args;
break;
case RuleKinds.ALIASED_FIELD: {
const name = (_a = state.prevState) === null || _a === void 0 ? void 0 : _a.name;
if (!name) {
argDefs = null;
break;
}
const field = parentType
? getFieldDef(schema, parentType, name)
: null;
if (!field) {
argDefs = null;
break;
}
argDefs = field.args;
break;
}
default:
argDefs = null;
break;
}
}
else {
argDefs = null;
}
break;
}
case RuleKinds.ARGUMENT:
if (argDefs) {
for (let i = 0; i < argDefs.length; i++) {
if (argDefs[i].name === state.name) {
argDef = argDefs[i];
break;
}
}
}
inputType = argDef === null || argDef === void 0 ? void 0 : argDef.type;
break;
case RuleKinds.ENUM_VALUE:
const enumType = getNamedType(inputType);
enumValue =
enumType instanceof GraphQLEnumType
? enumType
.getValues()
.find((val) => val.value === state.name)
: null;
break;
case RuleKinds.LIST_VALUE:
const nullableType = getNullableType(inputType);
inputType =
nullableType instanceof GraphQLList ? nullableType.ofType : null;
break;
case RuleKinds.OBJECT_VALUE:
const objectType = getNamedType(inputType);
objectFieldDefs =
objectType instanceof GraphQLInputObjectType
? objectType.getFields()
: null;
break;
case RuleKinds.OBJECT_FIELD:
const objectField = state.name && objectFieldDefs ? objectFieldDefs[state.name] : null;
inputType = objectField === null || objectField === void 0 ? void 0 : objectField.type;
break;
case RuleKinds.NAMED_TYPE:
if (state.name) {
type = schema.getType(state.name);
}
break;
}
});
return {
argDef,
argDefs,
directiveDef,
enumValue,
fieldDef,
inputType,
objectFieldDefs,
parentType,
type,
interfaceDef,
objectTypeDef,
};
}
export var GraphQLDocumentMode;
(function (GraphQLDocumentMode) {
GraphQLDocumentMode["TYPE_SYSTEM"] = "TYPE_SYSTEM";
GraphQLDocumentMode["EXECUTABLE"] = "EXECUTABLE";
})(GraphQLDocumentMode || (GraphQLDocumentMode = {}));
function getDocumentMode(documentText, uri) {
if (uri === null || uri === void 0 ? void 0 : uri.endsWith('.graphqls')) {
return GraphQLDocumentMode.TYPE_SYSTEM;
}
return hasTypeSystemDefinitions(documentText)
? GraphQLDocumentMode.TYPE_SYSTEM
: GraphQLDocumentMode.EXECUTABLE;
}
function unwrapType(state) {

@@ -879,0 +637,0 @@ if (state.prevState &&

@@ -1,2 +0,2 @@

import { FragmentSpreadNode, FragmentDefinitionNode, OperationDefinitionNode, NamedTypeNode } from 'graphql';
import { ASTNode, FragmentSpreadNode, FragmentDefinitionNode, OperationDefinitionNode, NamedTypeNode, GraphQLType } from 'graphql';
import { Definition, FragmentInfo, Uri, ObjectTypeInfo } from '../types';

@@ -7,8 +7,14 @@ import { Range } from '../utils';

definitions: Definition[];
printedName?: string;
};
export declare type DefinitionQueryResponse = DefinitionQueryResult & {
node?: ASTNode | null;
type?: GraphQLType | null;
};
export declare const LANGUAGE = "GraphQL";
export declare function getDefinitionQueryResultForNamedType(text: string, node: NamedTypeNode, dependencies: Array<ObjectTypeInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForField(fieldName: string, typeName: string, dependencies: Array<ObjectTypeInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForArgument(argumentName: string, fieldName: string, typeName: string, dependencies: Array<ObjectTypeInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForFragmentSpread(text: string, fragment: FragmentSpreadNode, dependencies: Array<FragmentInfo>): Promise<DefinitionQueryResult>;
export declare function getDefinitionQueryResultForDefinitionNode(path: Uri, text: string, definition: FragmentDefinitionNode | OperationDefinitionNode): DefinitionQueryResult;
//# sourceMappingURL=getDefinition.d.ts.map

@@ -38,2 +38,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

queryRange: definitions.map(_ => getRange(text, node)),
printedName: name,
};

@@ -60,5 +61,25 @@ });

queryRange: [],
printedName: [typeName, fieldName].join('.'),
};
});
}
export function getDefinitionQueryResultForArgument(argumentName, fieldName, typeName, dependencies) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
dependencies.filter(({ definition }) => definition.name && definition.name.value === typeName);
const definitions = [];
for (const { filePath, content, definition } of dependencies) {
const argDefinition = (_c = (_b = (_a = definition.fields) === null || _a === void 0 ? void 0 : _a.find(item => item.name.value === fieldName)) === null || _b === void 0 ? void 0 : _b.arguments) === null || _c === void 0 ? void 0 : _c.find(item => item.name.value === argumentName);
if (argDefinition == null) {
continue;
}
definitions.push(getDefinitionForArgumentDefinition(filePath || '', content, argDefinition));
}
return {
definitions,
queryRange: [],
printedName: `${[typeName, fieldName].join('.')}(${argumentName})`,
};
});
}
export function getDefinitionQueryResultForFragmentSpread(text, fragment, dependencies) {

@@ -75,2 +96,3 @@ return __awaiter(this, void 0, void 0, function* () {

queryRange: definitions.map(_ => getRange(text, fragment)),
printedName: name,
};

@@ -80,5 +102,7 @@ });

export function getDefinitionQueryResultForDefinitionNode(path, text, definition) {
var _a;
return {
definitions: [getDefinitionForFragmentDefinition(path, text, definition)],
queryRange: definition.name ? [getRange(text, definition.name)] : [],
printedName: (_a = definition.name) === null || _a === void 0 ? void 0 : _a.value,
};

@@ -124,2 +148,14 @@ }

}
function getDefinitionForArgumentDefinition(path, text, definition) {
const { name } = definition;
assert(name, 'Expected ASTNode to have a Name.');
return {
path,
position: getPosition(text, definition),
range: getRange(text, definition),
name: name.value || '',
language: LANGUAGE,
projectRoot: path,
};
}
//# sourceMappingURL=getDefinition.js.map

@@ -1,4 +0,4 @@

import { GraphQLSchema } from 'graphql';
import { ContextToken } from '../parser';
import { IPosition } from '../types';
import { GraphQLSchema, GraphQLType } from 'graphql';
import type { ContextToken } from '../parser';
import { AllTypeInfo, IPosition } from '../types';
import { Hover } from 'vscode-languageserver-types';

@@ -9,2 +9,7 @@ export declare type HoverConfig = {

export declare function getHoverInformation(schema: GraphQLSchema, queryText: string, cursor: IPosition, contextToken?: ContextToken, config?: HoverConfig): Hover['contents'];
export declare function renderField(into: string[], typeInfo: AllTypeInfo, options: any): void;
export declare function renderDirective(into: string[], typeInfo: AllTypeInfo, _options: any): void;
export declare function renderArg(into: string[], typeInfo: AllTypeInfo, options: any): void;
export declare function renderEnumValue(into: string[], typeInfo: AllTypeInfo, options: any): void;
export declare function renderType(into: string[], typeInfo: AllTypeInfo, options: any, t: GraphQLType): void;
//# sourceMappingURL=getHoverInformation.d.ts.map
import { GraphQLNonNull, GraphQLList, } from 'graphql';
import { getTokenAtPosition, getTypeInfo } from './getAutocompleteSuggestions';
import { getContextAtPosition } from '../parser';
export function getHoverInformation(schema, queryText, cursor, contextToken, config) {
const token = contextToken || getTokenAtPosition(queryText, cursor);
if (!schema || !token || !token.state) {
const options = Object.assign(Object.assign({}, config), { schema });
const context = getContextAtPosition(queryText, cursor, schema, contextToken);
if (!context) {
return '';
}
const { typeInfo, token } = context;
const { kind, step } = token.state;
const typeInfo = getTypeInfo(schema, token.state);
const options = Object.assign(Object.assign({}, config), { schema });
if ((kind === 'Field' && step === 0 && typeInfo.fieldDef) ||
(kind === 'AliasedField' && step === 2 && typeInfo.fieldDef)) {
(kind === 'AliasedField' && step === 2 && typeInfo.fieldDef) ||
(kind === 'ObjectField' && step === 0 && typeInfo.fieldDef)) {
const into = [];

@@ -28,2 +29,10 @@ renderMdCodeStart(into, options);

}
if (kind === 'Variable' && typeInfo.type) {
const into = [];
renderMdCodeStart(into, options);
renderType(into, typeInfo, options, typeInfo.type);
renderMdCodeEnd(into, options);
renderDescription(into, options, typeInfo.type);
return into.join('').trim();
}
if (kind === 'Argument' && step === 0 && typeInfo.argDef) {

@@ -67,3 +76,3 @@ const into = [];

}
function renderField(into, typeInfo, options) {
export function renderField(into, typeInfo, options) {
renderQualifiedField(into, typeInfo, options);

@@ -83,3 +92,3 @@ renderTypeAnnotation(into, typeInfo, options, typeInfo.type);

}
function renderDirective(into, typeInfo, _options) {
export function renderDirective(into, typeInfo, _options) {
if (!typeInfo.directiveDef) {

@@ -91,3 +100,3 @@ return;

}
function renderArg(into, typeInfo, options) {
export function renderArg(into, typeInfo, options) {
if (typeInfo.directiveDef) {

@@ -112,3 +121,3 @@ renderDirective(into, typeInfo, options);

}
function renderEnumValue(into, typeInfo, options) {
export function renderEnumValue(into, typeInfo, options) {
if (!typeInfo.enumValue) {

@@ -122,3 +131,3 @@ return;

}
function renderType(into, typeInfo, options, t) {
export function renderType(into, typeInfo, options, t) {
if (!t) {

@@ -125,0 +134,0 @@ return;

@@ -5,3 +5,5 @@ export { default as CharacterStream } from './CharacterStream';

export { default as onlineParser, ParserOptions } from './onlineParser';
export { runOnlineParser, type ParserCallbackFn, getTokenAtPosition, getContextAtPosition, GraphQLDocumentMode, getDocumentMode, } from './api';
export { getTypeInfo, getDefinitionState, getFieldDef } from './getTypeInfo';
export * from './types';
//# sourceMappingURL=index.d.ts.map

@@ -5,3 +5,5 @@ export { default as CharacterStream } from './CharacterStream';

export { default as onlineParser } from './onlineParser';
export { runOnlineParser, getTokenAtPosition, getContextAtPosition, GraphQLDocumentMode, getDocumentMode, } from './api';
export { getTypeInfo, getDefinitionState, getFieldDef } from './getTypeInfo';
export * from './types';
//# sourceMappingURL=index.js.map

@@ -77,2 +77,3 @@ import { Kind } from 'graphql';

TYPE: 'Type';
VARIABLE: 'Variable';
};

@@ -108,2 +109,3 @@ export declare const RuleKinds: {

TYPE: 'Type';
VARIABLE: 'Variable';
NAME: Kind.NAME;

@@ -119,3 +121,2 @@ DOCUMENT: Kind.DOCUMENT;

FRAGMENT_DEFINITION: Kind.FRAGMENT_DEFINITION;
VARIABLE: Kind.VARIABLE;
INT: Kind.INT;

@@ -154,3 +155,3 @@ FLOAT: Kind.FLOAT;

};
export declare type _RuleKinds = typeof Kind & typeof AdditionalRuleKinds;
export declare type _RuleKinds = Omit<typeof Kind, 'VARIABLE'> & typeof AdditionalRuleKinds;
export declare type RuleKind = _RuleKinds[keyof _RuleKinds];

@@ -157,0 +158,0 @@ export declare type RuleKindEnum = RuleKind;

@@ -31,4 +31,5 @@ import { Kind } from 'graphql';

TYPE: 'Type',
VARIABLE: 'Variable',
};
export const RuleKinds = Object.assign(Object.assign({}, Kind), AdditionalRuleKinds);
//# sourceMappingURL=types.js.map

@@ -6,2 +6,3 @@ import type { Diagnostic as DiagnosticType, CompletionItem as CompletionItemType } from 'vscode-languageserver-types';

import type { GraphQLConfig, GraphQLProjectConfig, GraphQLExtensionDeclaration } from 'graphql-config';
export { GraphQLDocumentMode } from './parser';
export type { GraphQLConfig, GraphQLProjectConfig, GraphQLExtensionDeclaration, };

@@ -11,7 +12,5 @@ export interface GraphQLCache {

getProjectForFile: (uri: string) => GraphQLProjectConfig | void;
getObjectTypeDependencies: (query: string, fragmentDefinitions: Map<string, ObjectTypeInfo>) => Promise<ObjectTypeInfo[]>;
getObjectTypeDependenciesForAST: (parsedQuery: ASTNode, fragmentDefinitions: Map<string, ObjectTypeInfo>) => Promise<ObjectTypeInfo[]>;
getObjectTypeDefinitions: (graphQLConfig: GraphQLProjectConfig) => Promise<Map<string, ObjectTypeInfo>>;
updateObjectTypeDefinition: (rootDir: Uri, filePath: Uri, contents: CachedContent[]) => Promise<void>;
updateObjectTypeDefinitionCache: (rootDir: Uri, filePath: Uri, exists: boolean) => Promise<void>;
getFragmentDependencies: (query: string, fragmentDefinitions: Maybe<Map<string, FragmentInfo>>) => Promise<FragmentInfo[]>;

@@ -21,4 +20,3 @@ getFragmentDependenciesForAST: (parsedQuery: ASTNode, fragmentDefinitions: Map<string, FragmentInfo>) => Promise<FragmentInfo[]>;

updateFragmentDefinition: (rootDir: Uri, filePath: Uri, contents: CachedContent[]) => Promise<void>;
updateFragmentDefinitionCache: (rootDir: Uri, filePath: Uri, exists: boolean) => Promise<void>;
getSchema: (appName?: string, queryHasExtensions?: boolean) => Promise<GraphQLSchema | null>;
getSchema: (appName: string, queryHasExtensions?: boolean) => Promise<GraphQLSchema | null>;
}

@@ -96,2 +94,3 @@ export interface IPosition {

command?: CompletionItemType['command'];
rawInsert?: string;
};

@@ -106,2 +105,3 @@ export declare type Definition = {

projectRoot?: Uri;
locator?: string;
};

@@ -108,0 +108,0 @@ export declare type TokenKind = 'keyword' | 'class-name' | 'constructor' | 'method' | 'param' | 'string' | 'whitespace' | 'plain' | 'type';

export { InsertTextFormat } from 'vscode-languageserver-types';
export { GraphQLDocumentMode } from './parser';
export const FileChangeTypeKind = {

@@ -3,0 +4,0 @@ Created: 1,

@@ -1,2 +0,2 @@

import { specifiedRules, validate, NoUnusedFragmentsRule, KnownFragmentNamesRule, Kind, ExecutableDefinitionsRule, LoneSchemaDefinitionRule, UniqueOperationTypesRule, UniqueTypeNamesRule, UniqueEnumValueNamesRule, UniqueFieldDefinitionNamesRule, UniqueDirectiveNamesRule, KnownTypeNamesRule, KnownDirectivesRule, UniqueDirectivesPerLocationRule, PossibleTypeExtensionsRule, UniqueArgumentNamesRule, UniqueInputFieldNamesRule, } from 'graphql';
import { specifiedRules, validate, NoUnusedFragmentsRule, KnownFragmentNamesRule, Kind, ExecutableDefinitionsRule, LoneSchemaDefinitionRule, UniqueOperationTypesRule, UniqueTypeNamesRule, UniqueEnumValueNamesRule, UniqueFieldDefinitionNamesRule, UniqueDirectiveNamesRule, KnownTypeNamesRule, KnownDirectivesRule, UniqueDirectivesPerLocationRule, PossibleTypeExtensionsRule, UniqueArgumentNamesRule, UniqueInputFieldNamesRule, UniqueVariableNamesRule, FragmentsOnCompositeTypesRule, ProvidedRequiredArgumentsRule, } from 'graphql';
const specifiedSDLRules = [

@@ -15,2 +15,5 @@ LoneSchemaDefinitionRule,

UniqueInputFieldNamesRule,
UniqueVariableNamesRule,
FragmentsOnCompositeTypesRule,
ProvidedRequiredArgumentsRule,
];

@@ -17,0 +20,0 @@ export function validateWithCustomRules(schema, ast, customRules, isRelayCompatMode, isSchemaDocument) {

{
"name": "graphql-language-service",
"version": "5.2.1-canary-36f0bac1.0",
"version": "5.2.1",
"description": "The official, runtime independent Language Service for GraphQL",

@@ -46,4 +46,4 @@ "contributors": [

"benchmark": "^2.1.4",
"graphql": "^16.4.0",
"graphql-config": "5.0.2",
"graphql": "^16.8.1",
"graphql-config": "5.0.3",
"lodash": "^4.17.15",

@@ -50,0 +50,0 @@ "platform": "^1.3.5",

@@ -24,5 +24,4 @@ /**

getDefinitionQueryResultForField,
getDefinitionState,
getDefinitionQueryResultForArgument,
getDiagnostics,
getFieldDef,
getFragmentDefinitions,

@@ -32,3 +31,2 @@ getHoverInformation,

getRange,
getTokenAtPosition,
getTypeInfo,

@@ -42,2 +40,3 @@ getVariableCompletions,

DefinitionQueryResult,
DefinitionQueryResponse,
canUseDirective,

@@ -63,2 +62,6 @@ SuggestionCommand,

opt,
getTokenAtPosition,
GraphQLDocumentMode,
getDefinitionState,
getFieldDef,
} from './parser';

@@ -65,0 +68,0 @@

@@ -22,2 +22,8 @@ /**

version as graphQLVersion,
GraphQLString,
GraphQLInt,
GraphQLBoolean,
GraphQLDeprecatedDirective,
GraphQLSkipDirective,
GraphQLIncludeDirective,
} from 'graphql';

@@ -28,2 +34,3 @@ import { Position } from '../../utils';

import { getAutocompleteSuggestions } from '../getAutocompleteSuggestions';
// import { InsertTextFormat } from 'vscode-languageserver-types';

@@ -55,2 +62,11 @@ const expectedResults = {

},
union: {
label: 'union',
detail: 'TestUnion',
},
__typename: {
label: '__typename',
detail: 'String!',
documentation: 'The name of the current Object type at runtime.',
},
};

@@ -80,3 +96,3 @@

externalFragments?: FragmentDefinitionNode[],
options?: AutocompleteSuggestionOptions,
options?: AutocompleteSuggestionOptions & { ignoreInsert?: boolean },
): Array<CompletionItem> {

@@ -100,11 +116,18 @@ return getAutocompleteSuggestions(

}
if (suggestion.insertText) {
if (suggestion.insertText && !options?.ignoreInsert) {
response.insertText = suggestion.insertText;
}
if (suggestion.insertTextFormat) {
if (suggestion.insertTextFormat && !options?.ignoreInsert) {
response.insertTextFormat = suggestion.insertTextFormat;
}
if (suggestion.command) {
if (suggestion.command && !options?.ignoreInsert) {
response.command = suggestion.command;
}
if (suggestion.documentation?.length) {
response.documentation = suggestion.documentation;
}
if (suggestion.labelDetails && !options?.ignoreInsert) {
response.labelDetails = suggestion.labelDetails;
}
return response;

@@ -115,4 +138,4 @@ });

const expectedDirectiveSuggestions = [
{ label: 'include' },
{ label: 'skip' },
{ label: 'include', documentation: GraphQLIncludeDirective.description },
{ label: 'skip', documentation: GraphQLSkipDirective.description },
];

@@ -122,6 +145,9 @@

if (graphQLVersion.startsWith('16.0.0-experimental-stream-defer')) {
// @ts-expect-error
expectedDirectiveSuggestions.push({ label: 'stream' }, { label: 'test' });
} else {
// @ts-expect-error
expectedDirectiveSuggestions.push({ label: 'test' });
}
it('provides correct sortText response', () => {

@@ -147,3 +173,3 @@ const result = getAutocompleteSuggestions(

{
sortText: '6__schema',
sortText: '7__schema',
label: '__schema',

@@ -158,6 +184,13 @@ detail: '__Schema!',

{ label: '{' },
{ label: 'extend' },
{ label: 'fragment' },
{ label: 'input' },
{ label: 'interface' },
{ label: 'mutation' },
{ label: 'query' },
{ label: 'scalar' },
{ label: 'schema' },
{ label: 'subscription' },
{ label: 'type' },
{ label: 'union' },
]);

@@ -171,5 +204,5 @@

it('provides correct suggestions at where the cursor is', () => {
it('provides correct top level suggestions when a simple query is already present', () => {
// Below should provide initial keywords
expect(testSuggestions(' {}', new Position(0, 0))).toEqual([
expect(testSuggestions(' { id }', new Position(0, 0))).toEqual([
{ label: '{' },

@@ -183,4 +216,8 @@ { label: 'fragment' },

// Below should provide root field names
expect(testSuggestions(' {}', new Position(0, 2))).toEqual([
{ label: '__typename', detail: 'String!' },
expect(
testSuggestions(' {}', new Position(0, 2), [], {
ignoreInsert: true,
}),
).toEqual([
expectedResults.__typename,
expectedResults.droid,

@@ -190,2 +227,3 @@ expectedResults.hero,

expectedResults.inputTypeTest,
expectedResults.union,
]);

@@ -202,5 +240,9 @@

new Position(2, 0),
[],
{
ignoreInsert: true,
},
),
).toEqual([
{ label: '__typename', detail: 'String!' },
expectedResults.__typename,
expectedResults.droid,

@@ -210,2 +252,3 @@ expectedResults.hero,

expectedResults.inputTypeTest,
expectedResults.union,
]);

@@ -215,5 +258,7 @@ });

it('provides correct field name suggestions', () => {
const result = testSuggestions('{ ', new Position(0, 2));
const result = testSuggestions('{ ', new Position(0, 2), [], {
ignoreInsert: true,
});
expect(result).toEqual([
{ label: '__typename', detail: 'String!' },
expectedResults.__typename,
expectedResults.droid,

@@ -223,2 +268,3 @@ expectedResults.hero,

expectedResults.inputTypeTest,
expectedResults.union,
]);

@@ -228,3 +274,5 @@ });

it('provides correct field name suggestions after filtered', () => {
const result = testSuggestions('{ h ', new Position(0, 3));
const result = testSuggestions('{ h ', new Position(0, 3), [], {
ignoreInsert: true,
});
expect(result).toEqual([expectedResults.hero, expectedResults.human]);

@@ -237,6 +285,10 @@ });

new Position(0, 26),
[],
{
ignoreInsert: true,
},
);
expect(result).toEqual([
{ label: '__typename', detail: 'String!' },
expectedResults.__typename,
expectedResults.appearsIn,

@@ -250,2 +302,55 @@ expectedResults.friends,

it('provides correct field name suggestions with insertText', () => {
const result = testSuggestions('{ ', new Position(0, 2), [], {
ignoreInsert: false,
fillLeafsOnComplete: true,
});
expect(result).toEqual([
{
...expectedResults.__typename,
command: suggestionCommand,
insertTextFormat: 2,
insertText: '__typename\n',
labelDetails: { detail: ' String!' },
},
{
...expectedResults.droid,
command: suggestionCommand,
insertTextFormat: 2,
insertText: 'droid(id: $1) {\n $1\n}',
labelDetails: { detail: ' Droid' },
},
{
...expectedResults.hero,
command: suggestionCommand,
insertTextFormat: 2,
insertText: 'hero {\n $1\n}',
labelDetails: { detail: ' Character' },
},
{
...expectedResults.human,
command: suggestionCommand,
insertTextFormat: 2,
insertText: 'human(id: $1) {\n $1\n}',
labelDetails: { detail: ' Human' },
},
{
...expectedResults.inputTypeTest,
command: suggestionCommand,
insertTextFormat: 2,
insertText: 'inputTypeTest {\n $1\n}',
labelDetails: { detail: ' TestType' },
},
{
label: 'union',
insertTextFormat: 2,
insertText: 'union {\n $1\n}',
detail: 'TestUnion',
command: suggestionCommand,
labelDetails: {
detail: ' TestUnion',
},
},
]);
});
it('provides correct type suggestions for fragments', () => {

@@ -270,6 +375,10 @@ const result = testSuggestions('fragment test on ', new Position(0, 17));

new Position(0, 25),
[],
{
ignoreInsert: true,
},
);
expect(result).toEqual([
{ label: '__typename', detail: 'String!' },
expectedResults.__typename,
expectedResults.appearsIn,

@@ -288,5 +397,6 @@ expectedResults.friends,

label: 'id',
detail: 'String!',
insertText: 'id: ',
command: suggestionCommand,
insertTextFormat: 2,
labelDetails: { detail: ' String!' },
},

@@ -304,9 +414,21 @@ ]);

label: 'id',
detail: 'String!',
command: suggestionCommand,
insertText: 'id: ',
insertTextFormat: 2,
labelDetails: { detail: ' String!' },
},
]);
});
const metaArgs = [
{
label: '__DirectiveLocation',
documentation:
'A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.',
},
{
label: '__TypeKind',
documentation:
'An enum describing what kind of type a given `__Type` is.',
},
];
it('provides correct input type suggestions', () => {

@@ -318,9 +440,8 @@ const result = testSuggestions(

expect(result).toEqual([
{ label: '__DirectiveLocation' },
{ label: '__TypeKind' },
{ label: 'Boolean' },
...metaArgs,
{ label: 'Boolean', documentation: GraphQLBoolean.description },
{ label: 'Episode' },
{ label: 'InputType' },
{ label: 'Int' },
{ label: 'String' },
{ label: 'Int', documentation: GraphQLInt.description },
{ label: 'String', documentation: GraphQLString.description },
]);

@@ -335,7 +456,7 @@ });

expect(result).toEqual([
{ label: '__DirectiveLocation' },
{ label: '__TypeKind' },
...metaArgs,
{ label: 'InputType' },
{ label: 'Int' },
{ label: 'String' },
{ label: 'Int', documentation: GraphQLInt.description },
{ label: 'String', documentation: GraphQLString.description },
]);

@@ -405,3 +526,3 @@ });

expect(result).toEqual([
{ label: 'ep', insertText: '$ep', detail: 'Episode' },
{ label: '$ep', insertText: 'ep', detail: 'Episode' },
]);

@@ -416,4 +537,5 @@ });

expect(result).toEqual([
{ label: '$episode', detail: 'Episode', insertText: '$episode' },
{ label: 'EMPIRE', detail: 'Episode' },
{ label: 'episode', detail: 'Episode', insertText: '$episode' },
{ label: 'JEDI', detail: 'Episode' },

@@ -434,3 +556,10 @@ { label: 'NEWHOPE', detail: 'Episode' },

),
).toEqual([{ label: 'Foo', detail: 'Human' }]);
).toEqual([
{
label: 'Foo',
detail: 'Human',
documentation: 'fragment Foo on Human',
labelDetails: { detail: 'fragment Foo on Human' },
},
]);
expect(

@@ -441,3 +570,10 @@ testSuggestions(

),
).toEqual([{ label: 'Foo', detail: 'Human' }]);
).toEqual([
{
label: 'Foo',
detail: 'Human',
documentation: 'fragment Foo on Human',
labelDetails: { detail: 'fragment Foo on Human' },
},
]);

@@ -450,3 +586,10 @@ // Test on abstract type

),
).toEqual([{ label: 'Foo', detail: 'Human' }]);
).toEqual([
{
label: 'Foo',
detail: 'Human',
documentation: 'fragment Foo on Human',
labelDetails: { detail: 'fragment Foo on Human' },
},
]);
});

@@ -471,4 +614,14 @@

expect(result).toEqual([
{ label: 'CharacterDetails', detail: 'Human' },
{ label: 'CharacterDetails2', detail: 'Human' },
{
label: 'CharacterDetails',
detail: 'Human',
documentation: 'fragment CharacterDetails on Human',
labelDetails: { detail: 'fragment CharacterDetails on Human' },
},
{
label: 'CharacterDetails2',
detail: 'Human',
documentation: 'fragment CharacterDetails2 on Human',
labelDetails: { detail: 'fragment CharacterDetails2 on Human' },
},
]);

@@ -493,11 +646,53 @@ });

it('provides correct testInput suggestions', () => {
it('provides correct directive field suggestions', () => {
expect(
testSuggestions('{ inputTypeTest(args: {', new Position(0, 23)),
testSuggestions('{ test @deprecated(', new Position(0, 19)),
).toEqual([
{ label: 'key', detail: 'String!' },
{ label: 'value', detail: 'Int' },
{
command: suggestionCommand,
label: 'reason',
insertTextFormat: 2,
insertText: 'reason: ',
documentation: GraphQLDeprecatedDirective.args[0].description,
labelDetails: {
detail: ' String',
},
},
]);
});
const inputArgs = [
{
label: 'key',
detail: 'String!',
insertText: 'key: ',
insertTextFormat: 2,
command: suggestionCommand,
},
{
detail: 'InputType',
label: 'obj',
insertText: 'obj: {\n $1\n}',
command: suggestionCommand,
insertTextFormat: 2,
},
{
label: 'value',
detail: 'Int',
insertText: 'value: ',
insertTextFormat: 2,
command: suggestionCommand,
},
];
it('provides correct testInput type field suggestions', () => {
expect(
testSuggestions('{ inputTypeTest(args: {', new Position(0, 23)),
).toEqual(inputArgs);
});
it('provides correct nested testInput type field suggestions', () => {
expect(
testSuggestions('{ inputTypeTest(args: { obj: {', new Position(0, 30)),
).toEqual(inputArgs);
});
it('provides correct field name suggestion inside inline fragment', () => {

@@ -508,5 +703,9 @@ expect(

new Position(0, 42),
[],
{
ignoreInsert: true,
},
),
).toEqual([
{ label: '__typename', detail: 'String!' },
expectedResults.__typename,
expectedResults.appearsIn,

@@ -521,5 +720,12 @@ expectedResults.friends,

expect(
testSuggestions('fragment Foo on Droid { ... { ', new Position(0, 30)),
testSuggestions(
'fragment Foo on Droid { ... { ',
new Position(0, 30),
[],
{
ignoreInsert: true,
},
),
).toEqual([
{ label: '__typename', detail: 'String!' },
expectedResults.__typename,
expectedResults.appearsIn,

@@ -537,3 +743,3 @@ expectedResults.friends,

describe('with SDL types', () => {
it('provides correct initial keywords', () => {
it('provides correct initial keywords w/ graphqls', () => {
expect(

@@ -552,2 +758,21 @@ testSuggestions('', new Position(0, 0), [], { uri: 'schema.graphqls' }),

it('provides correct initial keywords w/out graphqls', () => {
expect(
testSuggestions('', new Position(0, 0), [], { uri: 'schema.graphql' }),
).toEqual([
{ label: '{' },
{ label: 'extend' },
{ label: 'fragment' },
{ label: 'input' },
{ label: 'interface' },
{ label: 'mutation' },
{ label: 'query' },
{ label: 'scalar' },
{ label: 'schema' },
{ label: 'subscription' },
{ label: 'type' },
{ label: 'union' },
]);
});
it('provides correct initial definition keywords', () => {

@@ -633,6 +858,7 @@ expect(

]));
it('provides correct suggestions on object fields', () =>
it('provides correct suggestions on object field w/ .graphqls', () =>
expect(
testSuggestions('type Type {\n aField: s', new Position(0, 23), [], {
uri: 'schema.graphqls',
ignoreInsert: true,
}),

@@ -646,2 +872,69 @@ ).toEqual([

]));
it('provides correct argument type suggestions on directive definitions', () =>
expect(
testSuggestions(
'directive @skip(if: ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT',
new Position(0, 19),
[],
{
ignoreInsert: true,
},
),
).toEqual([
{ label: 'Boolean' },
{ label: 'Episode' },
{ label: 'InputType' },
{ label: 'Int' },
{ label: 'String' },
]));
it('provides correct suggestions on object fields', () =>
expect(
testSuggestions('type Type {\n aField: s', new Position(0, 23), [], {
uri: 'schema.graphql',
ignoreInsert: true,
}),
).toEqual([
{ label: 'Episode' },
{ label: 'String' },
{ label: 'TestInterface' },
{ label: 'TestType' },
{ label: 'TestUnion' },
]));
// TODO: shouldn't TestType and TestUnion be available here?
it('provides correct filtered suggestions on object fields in regular SDL files', () =>
expect(
testSuggestions('type Type {\n aField: s', new Position(0, 23), [], {
uri: 'schema.graphql',
ignoreInsert: true,
}),
).toEqual([
{ label: 'Episode' },
{ label: 'String' },
{ label: 'TestInterface' },
{ label: 'TestType' },
{ label: 'TestUnion' },
]));
it('provides correct unfiltered suggestions on object fields in regular SDL files', () =>
expect(
testSuggestions('type Type {\n aField: ', new Position(0, 22), [], {
uri: 'schema.graphql',
ignoreInsert: true,
}),
).toEqual([
{ label: 'AnotherInterface' },
{ label: 'Boolean' },
{ label: 'Character' },
{ label: 'Droid' },
{ label: 'Episode' },
{ label: 'Human' },
{ label: 'Int' },
// TODO: maybe filter out types attached to top level schema?
{ label: 'Query' },
{ label: 'String' },
{ label: 'TestInterface' },
{ label: 'TestType' },
{ label: 'TestUnion' },
]));
it('provides correct suggestions on object fields that are arrays', () =>

@@ -651,2 +944,3 @@ expect(

uri: 'schema.graphqls',
ignoreInsert: true,
}),

@@ -667,2 +961,22 @@ ).toEqual([

]));
it('provides correct suggestions on object fields that are arrays in SDL context', () =>
expect(
testSuggestions('type Type {\n aField: []', new Position(0, 25), [], {
uri: 'schema.graphql',
ignoreInsert: true,
}),
).toEqual([
{ label: 'AnotherInterface' },
{ label: 'Boolean' },
{ label: 'Character' },
{ label: 'Droid' },
{ label: 'Episode' },
{ label: 'Human' },
{ label: 'Int' },
{ label: 'Query' },
{ label: 'String' },
{ label: 'TestInterface' },
{ label: 'TestType' },
{ label: 'TestUnion' },
]));
it('provides correct suggestions on input object fields', () =>

@@ -673,3 +987,6 @@ expect(

}),
).toEqual([{ label: 'Episode' }, { label: 'String' }]));
).toEqual([
{ label: 'Episode' },
{ label: 'String', documentation: GraphQLString.description },
]));
it('provides correct directive suggestions on args definitions', () =>

@@ -679,3 +996,6 @@ expect(

).toEqual([
{ label: 'deprecated' },
{
label: 'deprecated',
documentation: GraphQLDeprecatedDirective.description,
},
{ label: 'onAllDefs' },

@@ -682,0 +1002,0 @@ { label: 'onArg' },

@@ -104,2 +104,18 @@ /**

it('provides enum parameter type information', () => {
const actual = testHover(
'query { parameterizedField(id: "foo", enum: GREEN) { testField } }',
new Position(0, 46),
);
expect(actual).toEqual('Color.GREEN');
});
it('provides variable type information', () => {
const actual = testHover(
'query($who: String!) { parameterizedField(id: $who) { testField } }',
new Position(0, 48),
);
expect(actual).toEqual('String!');
});
it('provides directive information', () => {

@@ -106,0 +122,0 @@ const actual = testHover(

@@ -12,73 +12,12 @@ /**

GraphQLField,
GraphQLSchema,
GraphQLType,
isCompositeType,
SchemaMetaFieldDef,
TypeMetaFieldDef,
TypeNameMetaFieldDef,
isListType,
isObjectType,
isInputObjectType,
getNamedType,
isAbstractType,
} from 'graphql';
import { CompletionItemBase, AllTypeInfo } from '../types';
import { ContextTokenUnion, State } from '../parser';
import { CompletionItemBase } from '../types';
import { ContextTokenUnion } from '../parser';
// Utility for returning the state representing the Definition this token state
// is within, if any.
export function getDefinitionState(
tokenState: State,
): State | null | undefined {
let definitionState;
// TODO - couldn't figure this one out
forEachState(tokenState, (state: State): void => {
switch (state.kind) {
case 'Query':
case 'ShortQuery':
case 'Mutation':
case 'Subscription':
case 'FragmentDefinition':
definitionState = state;
break;
}
});
return definitionState;
}
// Gets the field definition given a type and field name
export function getFieldDef(
schema: GraphQLSchema,
type: GraphQLType,
fieldName: string,
): GraphQLField<any, any> | null | undefined {
if (fieldName === SchemaMetaFieldDef.name && schema.getQueryType() === type) {
return SchemaMetaFieldDef;
}
if (fieldName === TypeMetaFieldDef.name && schema.getQueryType() === type) {
return TypeMetaFieldDef;
}
if (fieldName === TypeNameMetaFieldDef.name && isCompositeType(type)) {
return TypeNameMetaFieldDef;
}
if ('getFields' in type) {
return type.getFields()[fieldName] as any;
}
return null;
}
// Utility for iterating through a CodeMirror parse state stack bottom-up.
export function forEachState(
stack: State,
fn: (state: State) => AllTypeInfo | null | void,
): void {
const reverseStateStack = [];
let state: State | null | undefined = stack;
while (state?.kind) {
reverseStateStack.push(state);
state = state.prevState;
}
for (let i = reverseStateStack.length - 1; i >= 0; i--) {
fn(reverseStateStack[i]);
}
}
export function objectValues<T>(object: Record<string, T>): Array<T> {

@@ -108,3 +47,8 @@ const keys = Object.keys(object);

): Array<T> {
if (!text) {
if (
!text ||
text.trim() === '' ||
text.trim() === ':' ||
text.trim() === '{'
) {
return filterNonEmpty<T>(list, entry => !entry.isDeprecated);

@@ -205,1 +149,61 @@ }

}
const insertSuffix = (n?: number) => ` {\n $${n ?? 1}\n}`;
export const getInsertText = (
prefix: string,
type?: GraphQLType,
fallback?: string,
): string => {
if (!type) {
return fallback ?? prefix;
}
const namedType = getNamedType(type);
if (
isObjectType(namedType) ||
isInputObjectType(namedType) ||
isListType(namedType) ||
isAbstractType(namedType)
) {
return prefix + insertSuffix();
}
return fallback ?? prefix;
};
export const getInputInsertText = (
prefix: string,
type: GraphQLType,
fallback?: string,
): string => {
// if (isScalarType(type) && type.name === GraphQLString.name) {
// return prefix + '"$1"';
// }
if (isListType(type)) {
const baseType = getNamedType(type.ofType);
return prefix + `[${getInsertText('', baseType, '$1')}]`;
}
return getInsertText(prefix, type, fallback);
};
/**
* generates a TextSnippet for a field with possible required arguments
* that dynamically adjusts to the number of required arguments
* @param field
* @returns
*/
export const getFieldInsertText = (field: GraphQLField<null, null>) => {
const requiredArgs = field.args.filter(arg =>
arg.type.toString().endsWith('!'),
);
if (!requiredArgs.length) {
return;
}
return (
field.name +
`(${requiredArgs.map(
(arg, i) => `${arg.name}: $${i + 1}`,
)}) ${getInsertText('', field.type, '\n')}`
);
};

@@ -26,4 +26,3 @@ /**

GraphQLArgument,
isListType,
isNonNullType,
// isNonNullType,
isScalarType,

@@ -38,3 +37,2 @@ isObjectType,

GraphQLInputObjectType,
GraphQLList,
SchemaMetaFieldDef,

@@ -46,3 +44,2 @@ TypeMetaFieldDef,

getNamedType,
getNullableType,
isAbstractType,

@@ -52,3 +49,2 @@ isCompositeType,

visit,
BREAK,
parse,

@@ -65,20 +61,28 @@ } from 'graphql';

import {
CharacterStream,
onlineParser,
import type {
ContextToken,
State,
RuleKinds,
RuleKind,
ContextTokenForCodeMirror,
} from '../parser';
import {
forEachState,
getTypeInfo,
runOnlineParser,
RuleKinds,
getContextAtPosition,
getDefinitionState,
getFieldDef,
GraphQLDocumentMode,
} from '../parser';
import {
hintList,
objectValues,
getInputInsertText,
getFieldInsertText,
getInsertText,
} from './autocompleteUtils';
import { InsertTextMode } from 'vscode-languageserver-types';
export { runOnlineParser, getTypeInfo };
export const SuggestionCommand = {

@@ -105,49 +109,18 @@ command: 'editor.action.triggerSuggest',

const typeSystemKinds: Kind[] = [
// TypeSystemDefinition
Kind.SCHEMA_DEFINITION,
Kind.OPERATION_TYPE_DEFINITION,
Kind.SCALAR_TYPE_DEFINITION,
Kind.OBJECT_TYPE_DEFINITION,
Kind.INTERFACE_TYPE_DEFINITION,
Kind.UNION_TYPE_DEFINITION,
Kind.ENUM_TYPE_DEFINITION,
Kind.INPUT_OBJECT_TYPE_DEFINITION,
Kind.DIRECTIVE_DEFINITION,
// TypeSystemExtension
Kind.SCHEMA_EXTENSION,
Kind.SCALAR_TYPE_EXTENSION,
Kind.OBJECT_TYPE_EXTENSION,
Kind.INTERFACE_TYPE_EXTENSION,
Kind.UNION_TYPE_EXTENSION,
Kind.ENUM_TYPE_EXTENSION,
Kind.INPUT_OBJECT_TYPE_EXTENSION,
];
const hasTypeSystemDefinitions = (sdl: string | undefined) => {
let hasTypeSystemDef = false;
if (sdl) {
try {
visit(parse(sdl), {
enter(node) {
if (node.kind === 'Document') {
return;
}
if (typeSystemKinds.includes(node.kind)) {
hasTypeSystemDef = true;
return BREAK;
}
return false;
},
});
} catch {
return hasTypeSystemDef;
}
}
return hasTypeSystemDef;
};
export type AutocompleteSuggestionOptions = {
/**
* EXPERIMENTAL: Automatically fill required leaf nodes recursively
* upon triggering code completion events.
*
*
* - [x] fills required nodes
* - [x] automatically expands relay-style node/edge fields
* - [ ] automatically jumps to first required argument field
* - then, continues to prompt for required argument fields
* - (fixing this will make it non-experimental)
* - when it runs out of arguments, or you choose `{` as a completion option
* that appears when all required arguments are supplied, the argument
* selection closes `)` and the leaf field expands again `{ \n| }`
*/
fillLeafsOnComplete?: boolean;
schema?: GraphQLSchema;
uri?: string;

@@ -157,2 +130,6 @@ mode?: GraphQLDocumentMode;

type InternalAutocompleteOptions = AutocompleteSuggestionOptions & {
schema?: GraphQLSchema;
};
/**

@@ -173,18 +150,17 @@ * Given GraphQLSchema, queryText, and context of the current position within

schema,
};
const token: ContextToken =
contextToken || getTokenAtPosition(queryText, cursor, 1);
} as InternalAutocompleteOptions;
const state =
token.state.kind === 'Invalid' ? token.state.prevState : token.state;
const mode = options?.mode || getDocumentMode(queryText, options?.uri);
// relieve flow errors by checking if `state` exists
if (!state) {
const context = getContextAtPosition(
queryText,
cursor,
schema,
contextToken,
options,
);
if (!context) {
return [];
}
const { state, typeInfo, mode, token } = context;
const { kind, step, prevState } = state;
const typeInfo = getTypeInfo(schema, token.state);

@@ -196,3 +172,6 @@ // Definition kinds

}
return getSuggestionsForExecutableDefinitions(token);
if (mode === GraphQLDocumentMode.EXECUTABLE) {
return getSuggestionsForExecutableDefinitions(token);
}
return getSuggestionsForUnknownDocumentMode(token);
}

@@ -323,5 +302,9 @@

label: argDef.name,
insertText: argDef.name + ': ',
insertText: getInputInsertText(argDef.name + ': ', argDef.type),
insertTextMode: InsertTextMode.adjustIndentation,
insertTextFormat: InsertTextFormat.Snippet,
command: SuggestionCommand,
detail: String(argDef.type),
labelDetails: {
detail: ' ' + String(argDef.type),
},
documentation: argDef.description ?? undefined,

@@ -352,5 +335,9 @@ kind: CompletionItemKind.Variable,

detail: String(field.type),
documentation: field.description ?? undefined,
documentation: field?.description ?? undefined,
kind: completionKind,
type: field.type,
insertText: getInputInsertText(field.name + ': ', field.type),
insertTextMode: InsertTextMode.adjustIndentation,
insertTextFormat: InsertTextFormat.Snippet,
command: SuggestionCommand,
})),

@@ -369,3 +356,3 @@ );

}
// complete for all variables available in the query
// complete for all variables available in the query scoped to this
if (kind === RuleKinds.VARIABLE && step === 1) {

@@ -414,31 +401,33 @@ const namedInputType = getNamedType(typeInfo.inputType!);

if (
(mode === GraphQLDocumentMode.TYPE_SYSTEM &&
!unwrappedState.needsAdvance &&
kind === RuleKinds.NAMED_TYPE) ||
kind === RuleKinds.LIST_TYPE
) {
if (unwrappedState.kind === RuleKinds.FIELD_DEF) {
return hintList(
token,
Object.values(schema.getTypeMap())
.filter(type => isOutputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
})),
);
}
if (unwrappedState.kind === RuleKinds.INPUT_VALUE_DEF) {
return hintList(
token,
Object.values(schema.getTypeMap())
.filter(type => isInputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
})),
);
}
if (unwrappedState.kind === RuleKinds.FIELD_DEF) {
return hintList(
token,
Object.values(schema.getTypeMap())
.filter(type => isOutputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
insertText: options?.fillLeafsOnComplete
? type.name + '\n'
: type.name,
insertTextMode: InsertTextMode.adjustIndentation,
})),
);
}
if (unwrappedState.kind === RuleKinds.INPUT_VALUE_DEF && step === 2) {
return hintList(
token,
Object.values(schema.getTypeMap())
.filter(type => isInputType(type) && !type.name.startsWith('__'))
.map(type => ({
label: type.name,
kind: CompletionItemKind.Function,
insertText: options?.fillLeafsOnComplete
? type.name + '\n$1'
: type.name,
insertTextMode: InsertTextMode.adjustIndentation,
insertTextFormat: InsertTextFormat.Snippet,
})),
);
}

@@ -462,2 +451,5 @@ // Variable definition types

}
if (kind === RuleKinds.DIRECTIVE_DEF) {
return getSuggestionsForDirectiveArguments(token, state, schema, kind);
}

@@ -467,27 +459,18 @@ return [];

const insertSuffix = ' {\n $1\n}';
const typeSystemCompletionItems = [
{ label: 'type', kind: CompletionItemKind.Function },
{ label: 'interface', kind: CompletionItemKind.Function },
{ label: 'union', kind: CompletionItemKind.Function },
{ label: 'input', kind: CompletionItemKind.Function },
{ label: 'scalar', kind: CompletionItemKind.Function },
{ label: 'schema', kind: CompletionItemKind.Function },
];
/**
* Choose carefully when to insert the `insertText`!
* @param field
* @returns
*/
const getInsertText = (field: GraphQLField<null, null>) => {
const { type } = field;
if (isCompositeType(type)) {
return insertSuffix;
}
if (isListType(type) && isCompositeType(type.ofType)) {
return insertSuffix;
}
if (isNonNullType(type)) {
if (isCompositeType(type.ofType)) {
return insertSuffix;
}
if (isListType(type.ofType) && isCompositeType(type.ofType.ofType)) {
return insertSuffix;
}
}
return null;
};
const executableCompletionItems = [
{ label: 'query', kind: CompletionItemKind.Function },
{ label: 'mutation', kind: CompletionItemKind.Function },
{ label: 'subscription', kind: CompletionItemKind.Function },
{ label: 'fragment', kind: CompletionItemKind.Function },
{ label: '{', kind: CompletionItemKind.Constructor },
];

@@ -498,8 +481,3 @@ // Helper functions to get suggestions for each kinds

{ label: 'extend', kind: CompletionItemKind.Function },
{ label: 'type', kind: CompletionItemKind.Function },
{ label: 'interface', kind: CompletionItemKind.Function },
{ label: 'union', kind: CompletionItemKind.Function },
{ label: 'input', kind: CompletionItemKind.Function },
{ label: 'scalar', kind: CompletionItemKind.Function },
{ label: 'schema', kind: CompletionItemKind.Function },
...typeSystemCompletionItems,
]);

@@ -509,8 +487,10 @@ }

function getSuggestionsForExecutableDefinitions(token: ContextToken) {
return hintList(token, executableCompletionItems);
}
function getSuggestionsForUnknownDocumentMode(token: ContextToken) {
return hintList(token, [
{ label: 'query', kind: CompletionItemKind.Function },
{ label: 'mutation', kind: CompletionItemKind.Function },
{ label: 'subscription', kind: CompletionItemKind.Function },
{ label: 'fragment', kind: CompletionItemKind.Function },
{ label: '{', kind: CompletionItemKind.Constructor },
{ label: 'extend', kind: CompletionItemKind.Function },
...executableCompletionItems,
...typeSystemCompletionItems,
]);

@@ -520,10 +500,3 @@ }

function getSuggestionsForExtensionDefinitions(token: ContextToken) {
return hintList(token, [
{ label: 'type', kind: CompletionItemKind.Function },
{ label: 'interface', kind: CompletionItemKind.Function },
{ label: 'union', kind: CompletionItemKind.Function },
{ label: 'input', kind: CompletionItemKind.Function },
{ label: 'scalar', kind: CompletionItemKind.Function },
{ label: 'schema', kind: CompletionItemKind.Function },
]);
return hintList(token, typeSystemCompletionItems);
}

@@ -534,6 +507,7 @@

typeInfo: AllTypeInfo,
options?: AutocompleteSuggestionOptions,
options?: InternalAutocompleteOptions,
): Array<CompletionItem> {
if (typeInfo.parentType) {
const { parentType } = typeInfo;
// const { parentType, fieldDef, argDefs } = typeInfo;
let fields: GraphQLField<null, null>[] = [];

@@ -553,2 +527,3 @@ if ('getFields' in parentType) {

}
return hintList(

@@ -562,2 +537,3 @@ token,

detail: String(field.type),
documentation: field.description ?? undefined,

@@ -568,11 +544,29 @@ deprecated: Boolean(field.deprecationReason),

kind: CompletionItemKind.Field,
labelDetails: {
detail: ' ' + field.type.toString(),
},
type: field.type,
};
if (options?.fillLeafsOnComplete) {
// const hasArgs =
// // token.state.needsAdvance &&
// // @ts-expect-error
// parentType?._fields[field?.name];
if (options?.fillLeafsOnComplete) {
// TODO: fillLeafs capability
const insertText = getInsertText(field);
if (insertText) {
suggestion.insertText = field.name + insertText;
suggestion.insertText = getFieldInsertText(field);
// eslint-disable-next-line logical-assignment-operators
if (!suggestion.insertText) {
suggestion.insertText = getInsertText(
field.name,
field.type,
// if we are replacing a field with arguments, we don't want the extra line
field.name + (token.state.needsAdvance ? '' : '\n'),
);
}
if (suggestion.insertText) {
suggestion.insertTextFormat = InsertTextFormat.Snippet;
suggestion.insertTextMode = InsertTextMode.adjustIndentation;
suggestion.command = SuggestionCommand;

@@ -601,3 +595,3 @@ }

token,
).filter(v => v.detail === namedInputType.name);
).filter(v => v.detail === namedInputType?.name);

@@ -795,3 +789,3 @@ if (namedInputType instanceof GraphQLEnumType) {

label: String(type),
documentation: namedType?.description || '',
documentation: (namedType?.description as string | undefined) || '',
kind: CompletionItemKind.Field,

@@ -848,2 +842,5 @@ };

documentation: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
labelDetails: {
detail: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
},
kind: CompletionItemKind.Field,

@@ -879,2 +876,3 @@ type: typeMap[frag.typeCondition.name.value],

const definitions: Record<string, any> = Object.create({});
runOnlineParser(queryText, (_, state: State) => {

@@ -895,8 +893,13 @@ // TODO: gather this as part of `AllTypeInfo`, as I don't think it's optimal to re-run the parser like this

if (variableName && variableType && !definitions[variableName]) {
// append `$` if the `token.string` is not already `$`
// append `$` if the `token.string` is not already `$`, or describing a variable
// this appears to take care of it everywhere
const replaceString =
token.string === '$' || token?.state?.kind === 'Variable'
? variableName
: '$' + variableName;
definitions[variableName] = {
detail: variableType.toString(),
insertText: token.string === '$' ? variableName : '$' + variableName,
label: variableName, // keep label the same for `codemirror-graphql`
insertText: replaceString,
label: '$' + variableName,
rawInsert: replaceString,
type: variableType,

@@ -962,3 +965,3 @@ kind: CompletionItemKind.Variable,

label: type.name,
documentation: type.description!,
documentation: type?.description || '',
kind: CompletionItemKind.Variable,

@@ -983,3 +986,3 @@ })),

label: directive.name,
documentation: directive.description || '',
documentation: directive?.description || '',
kind: CompletionItemKind.Function,

@@ -992,85 +995,19 @@ })),

export function getTokenAtPosition(
queryText: string,
cursor: IPosition,
offset = 0,
): ContextToken {
let styleAtCursor = null;
let stateAtCursor = null;
let stringAtCursor = null;
const token = runOnlineParser(queryText, (stream, state, style, index) => {
if (
index !== cursor.line ||
stream.getCurrentPosition() + offset < cursor.character + 1
) {
return;
}
styleAtCursor = style;
stateAtCursor = { ...state };
stringAtCursor = stream.current();
return 'BREAK';
});
// Return the state/style of parsed token in case those at cursor aren't
// available.
return {
start: token.start,
end: token.end,
string: stringAtCursor || token.string,
state: stateAtCursor || token.state,
style: styleAtCursor || token.style,
};
}
/**
* Provides an utility function to parse a given query text and construct a
* `token` context object.
* A token context provides useful information about the token/style that
* CharacterStream currently possesses, as well as the end state and style
* of the token.
*/
type callbackFnType = (
stream: CharacterStream,
// I thought this added functionality somewhere, but I couldn't write any tests
// to execute it. I think it's handled as Arguments
function getSuggestionsForDirectiveArguments(
token: ContextToken,
state: State,
style: string,
index: number,
) => void | 'BREAK';
export function runOnlineParser(
queryText: string,
callback: callbackFnType,
): ContextToken {
const lines = queryText.split('\n');
const parser = onlineParser();
let state = parser.startState();
let style = '';
let stream: CharacterStream = new CharacterStream('');
for (let i = 0; i < lines.length; i++) {
stream = new CharacterStream(lines[i]);
while (!stream.eol()) {
style = parser.token(stream, state);
const code = callback(stream, state, style, i);
if (code === 'BREAK') {
break;
}
}
// Above while loop won't run if there is an empty line.
// Run the callback one more time to catch this.
callback(stream, state, style, i);
if (!state.kind) {
state = parser.startState();
}
}
return {
start: stream.getStartOfToken(),
end: stream.getCurrentPosition(),
string: stream.current(),
state,
style,
};
schema: GraphQLSchema,
_kind: string,
): Array<CompletionItem> {
const directive = schema.getDirectives().find(d => d.name === state.name);
return hintList(
token,
directive?.args.map(arg => ({
label: arg.name,
documentation: arg.description || '',
kind: CompletionItemKind.Field,
})) || [],
);
}

@@ -1136,200 +1073,2 @@

// Utility for collecting rich type information given any token's state
// from the graphql-mode parser.
export function getTypeInfo(
schema: GraphQLSchema,
tokenState: State,
): AllTypeInfo {
let argDef: AllTypeInfo['argDef'];
let argDefs: AllTypeInfo['argDefs'];
let directiveDef: AllTypeInfo['directiveDef'];
let enumValue: AllTypeInfo['enumValue'];
let fieldDef: AllTypeInfo['fieldDef'];
let inputType: AllTypeInfo['inputType'];
let objectTypeDef: AllTypeInfo['objectTypeDef'];
let objectFieldDefs: AllTypeInfo['objectFieldDefs'];
let parentType: AllTypeInfo['parentType'];
let type: AllTypeInfo['type'];
let interfaceDef: AllTypeInfo['interfaceDef'];
forEachState(tokenState, state => {
switch (state.kind) {
case RuleKinds.QUERY:
case 'ShortQuery':
type = schema.getQueryType();
break;
case RuleKinds.MUTATION:
type = schema.getMutationType();
break;
case RuleKinds.SUBSCRIPTION:
type = schema.getSubscriptionType();
break;
case RuleKinds.INLINE_FRAGMENT:
case RuleKinds.FRAGMENT_DEFINITION:
if (state.type) {
type = schema.getType(state.type);
}
break;
case RuleKinds.FIELD:
case RuleKinds.ALIASED_FIELD: {
if (!type || !state.name) {
fieldDef = null;
} else {
fieldDef = parentType
? getFieldDef(schema, parentType, state.name)
: null;
type = fieldDef ? fieldDef.type : null;
}
break;
}
case RuleKinds.SELECTION_SET:
parentType = getNamedType(type!);
break;
case RuleKinds.DIRECTIVE:
directiveDef = state.name ? schema.getDirective(state.name) : null;
break;
case RuleKinds.INTERFACE_DEF:
if (state.name) {
objectTypeDef = null;
interfaceDef = new GraphQLInterfaceType({
name: state.name,
interfaces: [],
fields: {},
});
}
break;
case RuleKinds.OBJECT_TYPE_DEF:
if (state.name) {
interfaceDef = null;
objectTypeDef = new GraphQLObjectType({
name: state.name,
interfaces: [],
fields: {},
});
}
break;
case RuleKinds.ARGUMENTS: {
if (state.prevState) {
switch (state.prevState.kind) {
case RuleKinds.FIELD:
argDefs = fieldDef && (fieldDef.args as GraphQLArgument[]);
break;
case RuleKinds.DIRECTIVE:
argDefs =
directiveDef && (directiveDef.args as GraphQLArgument[]);
break;
// TODO: needs more tests
case RuleKinds.ALIASED_FIELD: {
const name = state.prevState?.name;
if (!name) {
argDefs = null;
break;
}
const field = parentType
? getFieldDef(schema, parentType, name)
: null;
if (!field) {
argDefs = null;
break;
}
argDefs = field.args as GraphQLArgument[];
break;
}
default:
argDefs = null;
break;
}
} else {
argDefs = null;
}
break;
}
case RuleKinds.ARGUMENT:
if (argDefs) {
for (let i = 0; i < argDefs.length; i++) {
if (argDefs[i].name === state.name) {
argDef = argDefs[i];
break;
}
}
}
inputType = argDef?.type;
break;
// TODO: needs tests
case RuleKinds.ENUM_VALUE:
const enumType = getNamedType(inputType!);
enumValue =
enumType instanceof GraphQLEnumType
? enumType
.getValues()
.find((val: GraphQLEnumValue) => val.value === state.name)
: null;
break;
// TODO: needs tests
case RuleKinds.LIST_VALUE:
const nullableType = getNullableType(inputType!);
inputType =
nullableType instanceof GraphQLList ? nullableType.ofType : null;
break;
case RuleKinds.OBJECT_VALUE:
const objectType = getNamedType(inputType!);
objectFieldDefs =
objectType instanceof GraphQLInputObjectType
? objectType.getFields()
: null;
break;
// TODO: needs tests
case RuleKinds.OBJECT_FIELD:
const objectField =
state.name && objectFieldDefs ? objectFieldDefs[state.name] : null;
inputType = objectField?.type;
break;
case RuleKinds.NAMED_TYPE:
if (state.name) {
type = schema.getType(state.name);
}
// TODO: collect already extended interfaces of the type/interface we're extending
// here to eliminate them from the completion list
// because "type A extends B & C &" should not show completion options for B & C still.
break;
}
});
return {
argDef,
argDefs,
directiveDef,
enumValue,
fieldDef,
inputType,
objectFieldDefs,
parentType,
type,
interfaceDef,
objectTypeDef,
};
}
export enum GraphQLDocumentMode {
TYPE_SYSTEM = 'TYPE_SYSTEM',
EXECUTABLE = 'EXECUTABLE',
}
function getDocumentMode(
documentText: string,
uri?: string,
): GraphQLDocumentMode {
if (uri?.endsWith('.graphqls')) {
return GraphQLDocumentMode.TYPE_SYSTEM;
}
return hasTypeSystemDefinitions(documentText)
? GraphQLDocumentMode.TYPE_SYSTEM
: GraphQLDocumentMode.EXECUTABLE;
}
function unwrapType(state: State): State {

@@ -1336,0 +1075,0 @@ if (

@@ -19,2 +19,7 @@ /**

FieldDefinitionNode,
// printType,
// isNamedType,
// ArgumentNode,
InputValueDefinitionNode,
GraphQLType,
} from 'graphql';

@@ -25,2 +30,3 @@

import { locToRange, offsetToPosition, Range, Position } from '../utils';
// import { getTypeInfo } from './getAutocompleteSuggestions';

@@ -30,4 +36,10 @@ export type DefinitionQueryResult = {

definitions: Definition[];
printedName?: string;
};
export type DefinitionQueryResponse = DefinitionQueryResult & {
node?: ASTNode | null;
type?: GraphQLType | null;
};
export const LANGUAGE = 'GraphQL';

@@ -74,2 +86,3 @@

queryRange: definitions.map(_ => getRange(text, node)),
printedName: name,
};

@@ -111,5 +124,42 @@ }

queryRange: [],
printedName: [typeName, fieldName].join('.'),
};
}
export async function getDefinitionQueryResultForArgument(
argumentName: string,
fieldName: string,
typeName: string,
dependencies: Array<ObjectTypeInfo>,
): Promise<DefinitionQueryResult> {
dependencies.filter(
({ definition }) => definition.name && definition.name.value === typeName,
);
const definitions: Array<Definition> = [];
for (const { filePath, content, definition } of dependencies) {
const argDefinition = (definition as ObjectTypeDefinitionNode).fields
?.find(item => item.name.value === fieldName)
?.arguments?.find(item => item.name.value === argumentName);
if (argDefinition == null) {
continue;
}
definitions.push(
getDefinitionForArgumentDefinition(
filePath || '',
content,
argDefinition,
),
);
}
return {
definitions,
// TODO: seems like it's not using
queryRange: [],
printedName: `${[typeName, fieldName].join('.')}(${argumentName})`,
};
}
export async function getDefinitionQueryResultForFragmentSpread(

@@ -132,6 +182,6 @@ text: string,

);
return {
definitions,
queryRange: definitions.map(_ => getRange(text, fragment)),
printedName: name,
};

@@ -148,2 +198,3 @@ }

queryRange: definition.name ? [getRange(text, definition.name)] : [],
printedName: definition.name?.value,
};

@@ -211,1 +262,21 @@ }

}
// GraphQLString,
// eslint-disable-next-line sonarjs/no-identical-functions
function getDefinitionForArgumentDefinition(
path: Uri,
text: string,
definition: InputValueDefinitionNode,
): Definition {
const { name } = definition;
assert(name, 'Expected ASTNode to have a Name.');
return {
path,
position: getPosition(text, definition),
range: getRange(text, definition),
name: name.value || '',
language: LANGUAGE,
// This is a file inside the project root, good enough for now
projectRoot: path,
};
}
// GraphQLString,

@@ -78,3 +78,2 @@ /**

const enhancedQuery = fragments ? `${query}\n\n${fragments}` : query;
try {

@@ -81,0 +80,0 @@ ast = parse(enhancedQuery);

@@ -23,7 +23,7 @@ /**

} from 'graphql';
import { ContextToken } from '../parser';
import type { ContextToken } from '../parser';
import { AllTypeInfo, IPosition } from '../types';
import { Hover } from 'vscode-languageserver-types';
import { getTokenAtPosition, getTypeInfo } from './getAutocompleteSuggestions';
import { getContextAtPosition } from '../parser';

@@ -39,11 +39,9 @@ export type HoverConfig = { useMarkdown?: boolean };

): Hover['contents'] {
const token = contextToken || getTokenAtPosition(queryText, cursor);
if (!schema || !token || !token.state) {
const options = { ...config, schema };
const context = getContextAtPosition(queryText, cursor, schema, contextToken);
if (!context) {
return '';
}
const { typeInfo, token } = context;
const { kind, step } = token.state;
const typeInfo = getTypeInfo(schema, token.state);
const options = { ...config, schema };

@@ -55,3 +53,4 @@ // Given a Schema and a Token, produce the contents of an info tooltip.

(kind === 'Field' && step === 0 && typeInfo.fieldDef) ||
(kind === 'AliasedField' && step === 2 && typeInfo.fieldDef)
(kind === 'AliasedField' && step === 2 && typeInfo.fieldDef) ||
(kind === 'ObjectField' && step === 0 && typeInfo.fieldDef)
) {

@@ -73,2 +72,10 @@ const into: string[] = [];

}
if (kind === 'Variable' && typeInfo.type) {
const into: string[] = [];
renderMdCodeStart(into, options);
renderType(into, typeInfo, options, typeInfo.type);
renderMdCodeEnd(into, options);
renderDescription(into, options, typeInfo.type);
return into.join('').trim();
}
if (kind === 'Argument' && step === 0 && typeInfo.argDef) {

@@ -116,3 +123,7 @@ const into: string[] = [];

function renderField(into: string[], typeInfo: AllTypeInfo, options: any) {
export function renderField(
into: string[],
typeInfo: AllTypeInfo,
options: any,
) {
renderQualifiedField(into, typeInfo, options);

@@ -138,3 +149,7 @@ renderTypeAnnotation(into, typeInfo, options, typeInfo.type!);

function renderDirective(into: string[], typeInfo: AllTypeInfo, _options: any) {
export function renderDirective(
into: string[],
typeInfo: AllTypeInfo,
_options: any,
) {
if (!typeInfo.directiveDef) {

@@ -147,3 +162,3 @@ return;

function renderArg(into: string[], typeInfo: AllTypeInfo, options: any) {
export function renderArg(into: string[], typeInfo: AllTypeInfo, options: any) {
if (typeInfo.directiveDef) {

@@ -176,3 +191,7 @@ renderDirective(into, typeInfo, options);

function renderEnumValue(into: string[], typeInfo: AllTypeInfo, options: any) {
export function renderEnumValue(
into: string[],
typeInfo: AllTypeInfo,
options: any,
) {
if (!typeInfo.enumValue) {

@@ -187,3 +206,3 @@ return;

function renderType(
export function renderType(
into: string[],

@@ -190,0 +209,0 @@ typeInfo: AllTypeInfo,

@@ -18,2 +18,13 @@ /**

export {
runOnlineParser,
type ParserCallbackFn,
getTokenAtPosition,
getContextAtPosition,
GraphQLDocumentMode,
getDocumentMode,
} from './api';
export { getTypeInfo, getDefinitionState, getFieldDef } from './getTypeInfo';
export * from './types';

@@ -87,2 +87,3 @@ import { Kind } from 'graphql';

TYPE: 'Type',
VARIABLE: 'Variable',
};

@@ -119,2 +120,3 @@

TYPE: 'Type';
VARIABLE: 'Variable';
};

@@ -127,3 +129,4 @@

export type _RuleKinds = typeof Kind & typeof AdditionalRuleKinds;
export type _RuleKinds = Omit<typeof Kind, 'VARIABLE'> &
typeof AdditionalRuleKinds;

@@ -130,0 +133,0 @@ export type RuleKind = _RuleKinds[keyof _RuleKinds];

@@ -42,2 +42,4 @@ /**

export { GraphQLDocumentMode } from './parser';
export type {

@@ -54,7 +56,2 @@ GraphQLConfig,

getObjectTypeDependencies: (
query: string,
fragmentDefinitions: Map<string, ObjectTypeInfo>,
) => Promise<ObjectTypeInfo[]>;
getObjectTypeDependenciesForAST: (

@@ -75,8 +72,2 @@ parsedQuery: ASTNode,

updateObjectTypeDefinitionCache: (
rootDir: Uri,
filePath: Uri,
exists: boolean,
) => Promise<void>;
getFragmentDependencies: (

@@ -101,11 +92,4 @@ query: string,

) => Promise<void>;
updateFragmentDefinitionCache: (
rootDir: Uri,
filePath: Uri,
exists: boolean,
) => Promise<void>;
getSchema: (
appName?: string,
appName: string,
queryHasExtensions?: boolean,

@@ -199,2 +183,4 @@ ) => Promise<GraphQLSchema | null>;

command?: CompletionItemType['command'];
// if label differs from what should be inserted
rawInsert?: string;
};

@@ -212,2 +198,3 @@ // Below are basically a copy-paste from Nuclide rpc types for definitions.

projectRoot?: Uri;
locator?: string;
};

@@ -214,0 +201,0 @@

@@ -35,3 +35,5 @@ /**

UniqueInputFieldNamesRule,
// ProvidedRequiredArgumentsOnDirectivesRule,
UniqueVariableNamesRule,
FragmentsOnCompositeTypesRule,
ProvidedRequiredArgumentsRule,
} from 'graphql';

@@ -53,3 +55,5 @@

UniqueInputFieldNamesRule,
// ProvidedRequiredArgumentsOnDirectivesRule,
UniqueVariableNamesRule,
FragmentsOnCompositeTypesRule,
ProvidedRequiredArgumentsRule,
];

@@ -56,0 +60,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc