Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

codemirror-graphql

Package Overview
Dependencies
Maintainers
10
Versions
249
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

codemirror-graphql - npm Package Compare versions

Comparing version 0.13.1 to 0.14.0

6

CHANGELOG.md

@@ -6,2 +6,8 @@ # Change Log

# [0.14.0](https://github.com/graphql/graphiql/compare/codemirror-graphql@0.13.1...codemirror-graphql@0.14.0) (2021-01-03)
### Features
- merge completion logic (for implements &, variables) ([#1747](https://github.com/graphql/graphiql/issues/1747)) ([0ac0a85](https://github.com/graphql/graphiql/commit/0ac0a856cfc715d7885a9965a9a9114ef2ca4b1a))
## [0.13.1](https://github.com/graphql/graphiql/compare/codemirror-graphql@0.13.0...codemirror-graphql@0.13.1) (2020-12-28)

@@ -8,0 +14,0 @@

239

hint.esm.js

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

import CodeMirror from 'codemirror';
import { canUseDirective, getDefinitionState, getFragmentDefinitions, getTypeInfo, hintList, objectValues } from 'graphql-language-service-interface';
import { assertAbstractType, doTypesOverlap, getNamedType, isAbstractType, isCompositeType, isInputType, isObjectType, GraphQLBoolean, GraphQLEnumType, GraphQLInterfaceType, GraphQLSchema, SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, isInterfaceType } from 'graphql';
import { getAutocompleteSuggestions } from 'graphql-language-service-interface';
import { Position } from 'graphql-language-service-utils';
/**

@@ -34,2 +33,3 @@ * Registers a "hint" helper for CodeMirror.

*/
CodeMirror.registerHelper('hint', 'graphql', (editor, options) => {

@@ -44,4 +44,5 @@ const schema = options.schema;

const token = editor.getTokenAt(cur);
const rawResults = getAutocompleteSuggestions(schema, editor.getValue(), token);
const tokenStart = token.type !== null && /"|\w/.test(token.string[0]) ? token.start : token.end;
const position = new Position(cur.line, tokenStart);
const rawResults = getAutocompleteSuggestions(schema, editor.getValue(), position, token);
const results = {

@@ -72,230 +73,2 @@ list: rawResults.map(item => ({

return results;
});
/**
* Given GraphQLSchema, queryText, and context of the current position within
* the source text, provide a list of typeahead entries.
*/
function getAutocompleteSuggestions(schema, queryText, token) {
const state = token.state.kind === 'Invalid' ? token.state.prevState : token.state; // relieve flow errors by checking if `state` exists
if (!state) {
return [];
}
const kind = state.kind;
const step = state.step;
const typeInfo = getTypeInfo(schema, token.state); // Definition kinds
if (kind === 'Document') {
return hintList(token, [{
label: 'query'
}, {
label: 'mutation'
}, {
label: 'subscription'
}, {
label: 'fragment'
}, {
label: '{'
}]);
} // Field names
if (kind === 'SelectionSet' || kind === 'Field' || kind === 'AliasedField') {
return getSuggestionsForFieldNames(token, typeInfo, schema);
} // Argument names
if (kind === 'Arguments' || kind === 'Argument' && step === 0) {
const argDefs = typeInfo.argDefs;
if (argDefs) {
return hintList(token, argDefs.map(argDef => {
var _argDef$description;
return {
label: argDef.name,
type: argDef.type,
documentation: (_argDef$description = argDef.description) !== null && _argDef$description !== void 0 ? _argDef$description : undefined
};
}));
}
} // Input Object fields
if (kind === 'ObjectValue' || kind === 'ObjectField' && step === 0) {
if (typeInfo.objectFieldDefs) {
const objectFields = objectValues(typeInfo.objectFieldDefs);
return hintList(token, objectFields.map(field => {
var _field$description;
return {
label: field.name,
type: field.type,
documentation: (_field$description = field.description) !== null && _field$description !== void 0 ? _field$description : undefined
};
}));
}
} // Input values: Enum and Boolean
if (kind === 'EnumValue' || kind === 'ListValue' && step === 1 || kind === 'ObjectField' && step === 2 || kind === 'Argument' && step === 2) {
return getSuggestionsForInputValues(token, typeInfo);
} // Fragment type conditions
if (kind === 'TypeCondition' && step === 1 || kind === 'NamedType' && state.prevState != null && state.prevState.kind === 'TypeCondition') {
return getSuggestionsForFragmentTypeConditions(token, typeInfo, schema);
} // Fragment spread names
if (kind === 'FragmentSpread' && step === 1) {
return getSuggestionsForFragmentSpread(token, typeInfo, schema, queryText);
} // Variable definition types
if (kind === 'VariableDefinition' && step === 2 || kind === 'ListType' && step === 1 || kind === 'NamedType' && state.prevState && (state.prevState.kind === 'VariableDefinition' || state.prevState.kind === 'ListType')) {
return getSuggestionsForVariableDefinition(token, schema);
} // Directive names
if (kind === 'Directive') {
return getSuggestionsForDirective(token, state, schema);
}
return [];
} // Helper functions to get suggestions for each kinds
function getSuggestionsForFieldNames(token, typeInfo, schema) {
if (typeInfo.parentType) {
const parentType = typeInfo.parentType;
const fields = isObjectType(parentType) || isInterfaceType(parentType) ? objectValues(parentType.getFields()) : [];
if (isCompositeType(parentType)) {
fields.push(TypeNameMetaFieldDef);
}
if (parentType === schema.getQueryType()) {
fields.push(SchemaMetaFieldDef, TypeMetaFieldDef);
}
return hintList(token, fields.map(field => {
var _field$description2;
return {
label: field.name,
type: field.type,
documentation: (_field$description2 = field.description) !== null && _field$description2 !== void 0 ? _field$description2 : undefined,
isDeprecated: field.isDeprecated,
deprecationReason: field.deprecationReason
};
}));
}
return [];
}
function getSuggestionsForInputValues(token, typeInfo) {
const namedInputType = getNamedType(typeInfo.inputType);
if (namedInputType instanceof GraphQLEnumType) {
const values = namedInputType.getValues();
return hintList(token, values.map(value => {
var _value$description;
return {
label: value.name,
type: namedInputType,
documentation: (_value$description = value.description) !== null && _value$description !== void 0 ? _value$description : undefined,
isDeprecated: value.isDeprecated,
deprecationReason: value.deprecationReason
};
}));
} else if (namedInputType === GraphQLBoolean) {
return hintList(token, [{
label: 'true',
type: GraphQLBoolean,
documentation: 'Not false.'
}, {
label: 'false',
type: GraphQLBoolean,
documentation: 'Not true.'
}]);
}
return [];
}
function getSuggestionsForFragmentTypeConditions(token, typeInfo, schema) {
let possibleTypes;
if (typeInfo.parentType) {
if (isAbstractType(typeInfo.parentType)) {
const abstractType = assertAbstractType(typeInfo.parentType); // Collect both the possible Object types as well as the interfaces
// they implement.
const possibleObjTypes = schema.getPossibleTypes(abstractType);
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 hintList(token, possibleTypes.map(type => {
const namedType = getNamedType(type);
return {
label: String(type),
documentation: namedType && namedType.description || ''
};
}));
}
function getSuggestionsForFragmentSpread(token, typeInfo, schema, queryText) {
const typeMap = schema.getTypeMap();
const defState = getDefinitionState(token.state);
const fragments = getFragmentDefinitions(queryText); // Filter down to only the fragments which may exist here.
const relevantFrags = fragments.filter(frag => // Only include fragments with known types.
typeMap[frag.typeCondition.name.value] && // Only include fragments which are not cyclic.
!(defState && defState.kind === 'FragmentDefinition' && defState.name === frag.name.value) && // Only include fragments which could possibly be spread here.
isCompositeType(typeInfo.parentType) && isCompositeType(typeMap[frag.typeCondition.name.value]) && doTypesOverlap(schema, typeInfo.parentType, typeMap[frag.typeCondition.name.value]));
return hintList(token, relevantFrags.map(frag => ({
label: frag.name.value,
type: typeMap[frag.typeCondition.name.value],
documentation: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`
})));
}
function getSuggestionsForVariableDefinition(token, schema) {
const inputTypeMap = schema.getTypeMap();
const inputTypes = objectValues(inputTypeMap).filter(isInputType);
return hintList(token, inputTypes.map(type => ({
label: type.name,
documentation: type.description
})));
}
function getSuggestionsForDirective(token, state, schema) {
if (state.prevState && state.prevState.kind) {
const directives = schema.getDirectives().filter(directive => canUseDirective(state.prevState, directive));
return hintList(token, directives.map(directive => ({
label: directive.name,
documentation: directive.description || ''
})));
}
return [];
}
});

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

var _graphql = require("graphql");
var _graphqlLanguageServiceUtils = require("graphql-language-service-utils");

@@ -50,4 +50,5 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const token = editor.getTokenAt(cur);
const rawResults = getAutocompleteSuggestions(schema, editor.getValue(), token);
const tokenStart = token.type !== null && /"|\w/.test(token.string[0]) ? token.start : token.end;
const position = new _graphqlLanguageServiceUtils.Position(cur.line, tokenStart);
const rawResults = (0, _graphqlLanguageServiceInterface.getAutocompleteSuggestions)(schema, editor.getValue(), position, token);
const results = {

@@ -79,231 +80,2 @@ list: rawResults.map(item => ({

return results;
});
/**
* Given GraphQLSchema, queryText, and context of the current position within
* the source text, provide a list of typeahead entries.
*/
function getAutocompleteSuggestions(schema, queryText, token) {
const state = token.state.kind === 'Invalid' ? token.state.prevState : token.state; // relieve flow errors by checking if `state` exists
if (!state) {
return [];
}
const kind = state.kind;
const step = state.step;
const typeInfo = (0, _graphqlLanguageServiceInterface.getTypeInfo)(schema, token.state); // Definition kinds
if (kind === 'Document') {
return (0, _graphqlLanguageServiceInterface.hintList)(token, [{
label: 'query'
}, {
label: 'mutation'
}, {
label: 'subscription'
}, {
label: 'fragment'
}, {
label: '{'
}]);
} // Field names
if (kind === 'SelectionSet' || kind === 'Field' || kind === 'AliasedField') {
return getSuggestionsForFieldNames(token, typeInfo, schema);
} // Argument names
if (kind === 'Arguments' || kind === 'Argument' && step === 0) {
const argDefs = typeInfo.argDefs;
if (argDefs) {
return (0, _graphqlLanguageServiceInterface.hintList)(token, argDefs.map(argDef => {
var _argDef$description;
return {
label: argDef.name,
type: argDef.type,
documentation: (_argDef$description = argDef.description) !== null && _argDef$description !== void 0 ? _argDef$description : undefined
};
}));
}
} // Input Object fields
if (kind === 'ObjectValue' || kind === 'ObjectField' && step === 0) {
if (typeInfo.objectFieldDefs) {
const objectFields = (0, _graphqlLanguageServiceInterface.objectValues)(typeInfo.objectFieldDefs);
return (0, _graphqlLanguageServiceInterface.hintList)(token, objectFields.map(field => {
var _field$description;
return {
label: field.name,
type: field.type,
documentation: (_field$description = field.description) !== null && _field$description !== void 0 ? _field$description : undefined
};
}));
}
} // Input values: Enum and Boolean
if (kind === 'EnumValue' || kind === 'ListValue' && step === 1 || kind === 'ObjectField' && step === 2 || kind === 'Argument' && step === 2) {
return getSuggestionsForInputValues(token, typeInfo);
} // Fragment type conditions
if (kind === 'TypeCondition' && step === 1 || kind === 'NamedType' && state.prevState != null && state.prevState.kind === 'TypeCondition') {
return getSuggestionsForFragmentTypeConditions(token, typeInfo, schema);
} // Fragment spread names
if (kind === 'FragmentSpread' && step === 1) {
return getSuggestionsForFragmentSpread(token, typeInfo, schema, queryText);
} // Variable definition types
if (kind === 'VariableDefinition' && step === 2 || kind === 'ListType' && step === 1 || kind === 'NamedType' && state.prevState && (state.prevState.kind === 'VariableDefinition' || state.prevState.kind === 'ListType')) {
return getSuggestionsForVariableDefinition(token, schema);
} // Directive names
if (kind === 'Directive') {
return getSuggestionsForDirective(token, state, schema);
}
return [];
} // Helper functions to get suggestions for each kinds
function getSuggestionsForFieldNames(token, typeInfo, schema) {
if (typeInfo.parentType) {
const parentType = typeInfo.parentType;
const fields = (0, _graphql.isObjectType)(parentType) || (0, _graphql.isInterfaceType)(parentType) ? (0, _graphqlLanguageServiceInterface.objectValues)(parentType.getFields()) : [];
if ((0, _graphql.isCompositeType)(parentType)) {
fields.push(_graphql.TypeNameMetaFieldDef);
}
if (parentType === schema.getQueryType()) {
fields.push(_graphql.SchemaMetaFieldDef, _graphql.TypeMetaFieldDef);
}
return (0, _graphqlLanguageServiceInterface.hintList)(token, fields.map(field => {
var _field$description2;
return {
label: field.name,
type: field.type,
documentation: (_field$description2 = field.description) !== null && _field$description2 !== void 0 ? _field$description2 : undefined,
isDeprecated: field.isDeprecated,
deprecationReason: field.deprecationReason
};
}));
}
return [];
}
function getSuggestionsForInputValues(token, typeInfo) {
const namedInputType = (0, _graphql.getNamedType)(typeInfo.inputType);
if (namedInputType instanceof _graphql.GraphQLEnumType) {
const values = namedInputType.getValues();
return (0, _graphqlLanguageServiceInterface.hintList)(token, values.map(value => {
var _value$description;
return {
label: value.name,
type: namedInputType,
documentation: (_value$description = value.description) !== null && _value$description !== void 0 ? _value$description : undefined,
isDeprecated: value.isDeprecated,
deprecationReason: value.deprecationReason
};
}));
} else if (namedInputType === _graphql.GraphQLBoolean) {
return (0, _graphqlLanguageServiceInterface.hintList)(token, [{
label: 'true',
type: _graphql.GraphQLBoolean,
documentation: 'Not false.'
}, {
label: 'false',
type: _graphql.GraphQLBoolean,
documentation: 'Not true.'
}]);
}
return [];
}
function getSuggestionsForFragmentTypeConditions(token, typeInfo, schema) {
let possibleTypes;
if (typeInfo.parentType) {
if ((0, _graphql.isAbstractType)(typeInfo.parentType)) {
const abstractType = (0, _graphql.assertAbstractType)(typeInfo.parentType); // Collect both the possible Object types as well as the interfaces
// they implement.
const possibleObjTypes = schema.getPossibleTypes(abstractType);
const possibleIfaceMap = Object.create(null);
possibleObjTypes.forEach(type => {
type.getInterfaces().forEach(iface => {
possibleIfaceMap[iface.name] = iface;
});
});
possibleTypes = possibleObjTypes.concat((0, _graphqlLanguageServiceInterface.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 = (0, _graphqlLanguageServiceInterface.objectValues)(typeMap).filter(_graphql.isCompositeType);
}
return (0, _graphqlLanguageServiceInterface.hintList)(token, possibleTypes.map(type => {
const namedType = (0, _graphql.getNamedType)(type);
return {
label: String(type),
documentation: namedType && namedType.description || ''
};
}));
}
function getSuggestionsForFragmentSpread(token, typeInfo, schema, queryText) {
const typeMap = schema.getTypeMap();
const defState = (0, _graphqlLanguageServiceInterface.getDefinitionState)(token.state);
const fragments = (0, _graphqlLanguageServiceInterface.getFragmentDefinitions)(queryText); // Filter down to only the fragments which may exist here.
const relevantFrags = fragments.filter(frag => // Only include fragments with known types.
typeMap[frag.typeCondition.name.value] && // Only include fragments which are not cyclic.
!(defState && defState.kind === 'FragmentDefinition' && defState.name === frag.name.value) && // Only include fragments which could possibly be spread here.
(0, _graphql.isCompositeType)(typeInfo.parentType) && (0, _graphql.isCompositeType)(typeMap[frag.typeCondition.name.value]) && (0, _graphql.doTypesOverlap)(schema, typeInfo.parentType, typeMap[frag.typeCondition.name.value]));
return (0, _graphqlLanguageServiceInterface.hintList)(token, relevantFrags.map(frag => ({
label: frag.name.value,
type: typeMap[frag.typeCondition.name.value],
documentation: `fragment ${frag.name.value} on ${frag.typeCondition.name.value}`
})));
}
function getSuggestionsForVariableDefinition(token, schema) {
const inputTypeMap = schema.getTypeMap();
const inputTypes = (0, _graphqlLanguageServiceInterface.objectValues)(inputTypeMap).filter(_graphql.isInputType);
return (0, _graphqlLanguageServiceInterface.hintList)(token, inputTypes.map(type => ({
label: type.name,
documentation: type.description
})));
}
function getSuggestionsForDirective(token, state, schema) {
if (state.prevState && state.prevState.kind) {
const directives = schema.getDirectives().filter(directive => (0, _graphqlLanguageServiceInterface.canUseDirective)(state.prevState, directive));
return (0, _graphqlLanguageServiceInterface.hintList)(token, directives.map(directive => ({
label: directive.name,
documentation: directive.description || ''
})));
}
return [];
}
});
{
"name": "codemirror-graphql",
"version": "0.13.1",
"version": "0.14.0",
"description": "GraphQL mode and helpers for CodeMirror.",

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

"dependencies": {
"graphql-language-service-interface": "^2.6.0",
"graphql-language-service-parser": "^1.7.0"
"graphql-language-service-interface": "^2.7.0",
"graphql-language-service-parser": "^1.8.0"
},

@@ -66,3 +66,3 @@ "devDependencies": {

},
"gitHead": "ed6c94cb8240fd89324104f0a9a40ce80a2dd71c"
"gitHead": "4038cf235b71eaf9a576c86800707f204ded8865"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc