graphql-language-service
Version:
The official, runtime independent Language Service for GraphQL
109 lines • 4.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOutline = void 0;
const graphql_1 = require("graphql");
const utils_1 = require("../utils");
function getOutline(documentText) {
let ast;
try {
ast = (0, graphql_1.parse)(documentText);
}
catch (_a) {
return null;
}
const visitorFns = outlineTreeConverter(documentText);
const outlineTrees = (0, graphql_1.visit)(ast, {
leave(node) {
if (visitorFns !== undefined && node.kind in visitorFns) {
return visitorFns[node.kind](node);
}
return null;
},
});
return { outlineTrees };
}
exports.getOutline = getOutline;
function outlineTreeConverter(docText) {
const meta = (node) => {
return {
representativeName: node.name,
startPosition: (0, utils_1.offsetToPosition)(docText, node.loc.start),
endPosition: (0, utils_1.offsetToPosition)(docText, node.loc.end),
kind: node.kind,
children: node.selectionSet || node.fields || node.values || node.arguments || [],
};
};
return {
Field(node) {
const tokenizedText = node.alias
? [buildToken('plain', node.alias), buildToken('plain', ': ')]
: [];
tokenizedText.push(buildToken('plain', node.name));
return Object.assign({ tokenizedText }, meta(node));
},
OperationDefinition: (node) => (Object.assign({ tokenizedText: [
buildToken('keyword', node.operation),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
] }, meta(node))),
Document: (node) => node.definitions,
SelectionSet: (node) => concatMap(node.selections, (child) => {
return child.kind === graphql_1.Kind.INLINE_FRAGMENT ? child.selectionSet : child;
}),
Name: (node) => node.value,
FragmentDefinition: (node) => (Object.assign({ tokenizedText: [
buildToken('keyword', 'fragment'),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
] }, meta(node))),
InterfaceTypeDefinition: (node) => (Object.assign({ tokenizedText: [
buildToken('keyword', 'interface'),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
] }, meta(node))),
EnumTypeDefinition: (node) => (Object.assign({ tokenizedText: [
buildToken('keyword', 'enum'),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
] }, meta(node))),
EnumValueDefinition: (node) => (Object.assign({ tokenizedText: [buildToken('plain', node.name)] }, meta(node))),
ObjectTypeDefinition: (node) => (Object.assign({ tokenizedText: [
buildToken('keyword', 'type'),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
] }, meta(node))),
InputObjectTypeDefinition: (node) => (Object.assign({ tokenizedText: [
buildToken('keyword', 'input'),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
] }, meta(node))),
FragmentSpread: (node) => (Object.assign({ tokenizedText: [
buildToken('plain', '...'),
buildToken('class-name', node.name),
] }, meta(node))),
InputValueDefinition(node) {
return Object.assign({ tokenizedText: [buildToken('plain', node.name)] }, meta(node));
},
FieldDefinition(node) {
return Object.assign({ tokenizedText: [buildToken('plain', node.name)] }, meta(node));
},
InlineFragment: (node) => node.selectionSet,
};
}
function buildToken(kind, value) {
return { kind, value };
}
function concatMap(arr, fn) {
const res = [];
for (let i = 0; i < arr.length; i++) {
const x = fn(arr[i], i);
if (Array.isArray(x)) {
res.push(...x);
}
else {
res.push(x);
}
}
return res;
}
//# sourceMappingURL=getOutline.js.map