UNPKG

@platformos/pos-cli

Version:

Manage your platformOS application

96 lines 2.93 kB
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