Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
return [
{
text: 'fragment',
},
];
}
// Argument names
// console.log(kind, step, position);
// Field names
if (kind === 'SelectionSet' || kind === 'Field' || kind === 'AliasedField') {
if (typeInfo.parentType) {
const fields = typeInfo.parentType.getFields
// $FlowDisableNextLine
? objectValues(typeInfo.parentType.getFields())
: [];
if (isAbstractType(typeInfo.parentType)) {
fields.push(TypeNameMetaFieldDef);
}
if (typeInfo.parentType === schema.getQueryType()) {
fields.push(SchemaMetaFieldDef, TypeMetaFieldDef);
}
return fields.map((field) => ({
text: field.name,
type: field.type.toString(),
description: field.description,
}));
}
}
if (kind === 'Arguments' || (kind === 'Argument' && step === 0)) {
if (!this._schema) return delegate(fileName, position, options);
const node = this._helper.getNode(fileName, position);
if (!node || node.kind !== ts.SyntaxKind.NoSubstitutionTemplateLiteral) {
return delegate(fileName, position, options);
}
if (this._tagCondition && !isTagged(node, this._tagCondition)) {
return delegate(fileName, position, options);
}
const cursor = position - node.getStart();
const baseLC = this._helper.getLineAndChar(fileName, node.getStart());
const cursorLC = this._helper.getLineAndChar(fileName, position);
const relativeLC = { line: cursorLC.line - baseLC.line, character: cursorLC.character - baseLC.character + 1 };
const p = new SimplePosition(relativeLC);
const text = node.getText().slice(1, cursor + 1); // remove the backquote char
this._logger('Search text: "' + text + '" at ' + cursor + ' position');
const gqlCompletionItems = getAutocompleteSuggestions(this._schema, text, p);
this._logger(JSON.stringify(gqlCompletionItems));
return translateCompletionItems(gqlCompletionItems);
}
CodeMirror.registerHelper('hint', 'graphql', (editor, options) => {
const schema = options.schema;
if (!schema) {
return;
}
const cur = editor.getCursor();
const token = editor.getTokenAt(cur);
const rawResults = getAutocompleteSuggestions(
schema,
editor.getValue(),
cur,
token,
);
/**
* GraphQL language service responds to the autocompletion request with
* a different format:
* type CompletionItem = {
* label: string,
* kind?: number,
* detail?: string,
* documentation?: string,
* // GraphQL Deprecation information
* isDeprecated?: ?string,
* deprecationReason?: ?string,
export async function provideCompletionItems({
position,
model,
schema
}: ProviderItemInput): Promise<
languages.ProviderResult
> {
const graphQLPosition = new GraphQLPosition(
position.lineNumber - 1,
position.column - 1,
);
graphQLPosition.setCharacter(position.column - 1);
graphQLPosition.line = position.lineNumber - 1;
const suggestions = await getAutocompleteSuggestions(
schema,
model.getValue(),
graphQLPosition,
);
// @ts-ignore wants range
return {
// TODO: possibly return different kinds of completion items?
// TODO: (optionally?) show all completion items at first?
suggestions: suggestions.map(s => ({
label: s.label,
kind: s.kind,
detail: s.detail,
documentation: s.documentation,
insertText: s.label,
})),
};
function _getDiagnostics(
filePath: string,
queryText: string,
schemaPath?: string,
): EXIT_CODE {
try {
// `schema` is not strictly requied as GraphQL diagnostics may still notify
// whether the query text is syntactically valid.
const schema = schemaPath ? generateSchema(schemaPath) : null;
const resultArray = getDiagnostics(queryText, schema);
const resultObject = resultArray.reduce((prev, cur, index) => {
prev[index] = cur;
return prev;
}, {});
process.stdout.write(JSON.stringify(resultObject, null, 2));
return GRAPHQL_SUCCESS_CODE;
} catch (error) {
process.stderr.write(error);
return GRAPHQL_FAILURE_CODE;
}
}
const diagnoseQueryValue = async (
model: editor.ITextModel, // query or schema
schema: GraphQLSchema,
): Promise<{
valid: boolean;
formattedDiagnostics: editor.IMarkerData[];
diagnostics: any[];
}> => {
let valid = false;
const diagnostics = await getDiagnostics(model.getValue(), schema);
const formattedDiagnostics: editor.IMarkerData[] = diagnostics.map(
d => ({
startLineNumber: d.range.start.line + 1,
endLineNumber: d.range.end.line + 1,
startColumn: d.range.start.character + 1,
endColumn: d.range.end.character + 1,
message: d.message,
severity: MarkerSeverity.Error,
}),
);
if (diagnostics.length < 1) {
valid = true;
}
editor.setModelMarkers(model, 'linter', formattedDiagnostics);
return {
(kind === 'TypeCondition' && step === 1) ||
(kind === 'NamedType' && state.prevState.kind === 'TypeCondition')
) {
let possibleTypes = null;
if (typeInfo.parentType) {
if (isAbstractType(typeInfo.parentType)) {
// Collect both the possible Object types as well as the interfaces
// they implement.
const possibleObjTypes = schema.getPossibleTypes(typeInfo.parentType);
const possibleIfaceMap = Object.create(null);
possibleObjTypes.forEach((type) => {
type.getInterfaces().forEach((iface) => {
possibleIfaceMap[iface.name] = iface;
});
});
possibleTypes = possibleObjTypes.concat(objectValues(possibleIfaceMap));
} else {
// The parent type is a non-abstract Object type, so the only possible
// type that can be used is that same type.
possibleTypes = [typeInfo.parentType];
}
} else {
const typeMap = schema.getTypeMap();
possibleTypes = objectValues(typeMap).filter(isCompositeType);
}
return possibleTypes.map((type) => ({
text: type.name,
type: typeName[type.constructor.name],
description: type.description,
}));
}
description: field.description,
})));
}
}
// Input values: Enum and Boolean
if (
(kind === 'EnumValue') ||
(kind === 'ListValue' && step === 1) ||
(kind === 'ObjectField' && step === 2) ||
(kind === 'Argument' && step === 2)
) {
const namedInputType = getNamedType(typeInfo.inputType);
if (namedInputType instanceof GQLEnumType) {
const valueMap = namedInputType.getValues();
const values = objectValues(valueMap);
return (values.map((value) => ({
text: value.name,
type: namedInputType.toString(),
description: value.description,
})));
} else if (namedInputType === GraphQLBoolean) {
return [
{ text: 'true', type: GraphQLBoolean, description: 'Not false.' },
{ text: 'false', type: GraphQLBoolean, description: 'Not true.' },
];
}
}
// Fragment type conditions
if (
(kind === 'TypeCondition' && step === 1) ||
// description:
// `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`,
// }));
// }
// Variable definition types
if (
(kind === 'VariableDefinition' && step === 2) ||
(kind === 'ListType' && step === 1) ||
(kind === 'NamedType' && (
state.prevState.kind === 'VariableDefinition' ||
state.prevState.kind === 'ListType'
))
) {
const inputTypeMap = schema.getTypeMap();
const inputTypes = objectValues(inputTypeMap).filter(isInputType);
return inputTypes.map((type) => ({
text: type.name,
description: type.description,
}));
}
// Directive names
if (kind === 'Directive') {
const directives = schema.getDirectives().filter(
(directive) => canUseDirective(state.prevState.kind, directive),
);
return directives.map((directive) => ({
text: directive.name,
description: directive.description,
}));
}
if (kind === 'Arguments' || (kind === 'Argument' && step === 0)) {
const { argDefs } = typeInfo;
if (argDefs) {
return (argDefs.map((argDef) => ({
text: argDef.name,
type: argDef.type.toString(),
description: argDef.description,
})));
}
}
// Input Object fields
if (kind === 'ObjectValue' || (kind === 'ObjectField' && step === 0)) {
if (typeInfo.objectFieldDefs) {
const objectFields = objectValues(typeInfo.objectFieldDefs);
return (objectFields.map((field) => ({
text: field.name,
type: field.type.toString(),
description: field.description,
})));
}
}
// Input values: Enum and Boolean
if (
(kind === 'EnumValue') ||
(kind === 'ListValue' && step === 1) ||
(kind === 'ObjectField' && step === 2) ||
(kind === 'Argument' && step === 2)
) {
const namedInputType = getNamedType(typeInfo.inputType);