@platformos/pos-cli
Version:
Manage your platformOS application
96 lines • 2.93 kB
JavaScript
import { Kind, parse, visit, } from 'graphql';
import { offsetToPosition } from 'graphql-language-service-utils';
const { INLINE_FRAGMENT } = Kind;
const OUTLINEABLE_KINDS = {
Field: true,
OperationDefinition: true,
Document: true,
SelectionSet: true,
Name: true,
FragmentDefinition: true,
FragmentSpread: true,
InlineFragment: true,
};
export function getOutline(queryText) {
let ast;
try {
ast = parse(queryText);
}
catch (error) {
return null;
}
const visitorFns = outlineTreeConverter(queryText);
const outlineTrees = visit(ast, {
leave(node) {
if (OUTLINEABLE_KINDS.hasOwnProperty(node.kind) &&
visitorFns[node.kind]) {
return visitorFns[node.kind](node);
}
return null;
},
});
return { outlineTrees };
}
function outlineTreeConverter(docText) {
const meta = (node) => ({
representativeName: node.name,
startPosition: offsetToPosition(docText, node.loc.start),
endPosition: offsetToPosition(docText, node.loc.end),
children: node.selectionSet || [],
});
return {
Field: (node) => {
const tokenizedText = node.alias
? [buildToken('plain', node.alias), buildToken('plain', ': ')]
: [];
tokenizedText.push(buildToken('plain', node.name));
return { tokenizedText, ...meta(node) };
},
OperationDefinition: (node) => ({
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 === INLINE_FRAGMENT ? child.selectionSet : child;
}),
Name: (node) => node.value,
FragmentDefinition: (node) => ({
tokenizedText: [
buildToken('keyword', 'fragment'),
buildToken('whitespace', ' '),
buildToken('class-name', node.name),
],
...meta(node),
}),
FragmentSpread: (node) => ({
tokenizedText: [
buildToken('plain', '...'),
buildToken('class-name', 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