UNPKG

graphql-language-service-server

Version:
178 lines 6.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findGraphQLTags = void 0; const graphql_language_service_1 = require("graphql-language-service"); const constants_1 = require("./constants"); const parsers_1 = require("./parsers"); async function findGraphQLTags(text, ext, uri, logger) { const result = []; let rangeMapper = (range) => range; const parser = parsers_1.parserMap[ext]; const parserResult = await parser(text, uri, logger); if (!parserResult) { return []; } if (parserResult === null || parserResult === void 0 ? void 0 : parserResult.rangeMapper) { rangeMapper = parserResult.rangeMapper; } const { asts } = parserResult; if (!(asts === null || asts === void 0 ? void 0 : asts.length)) { return []; } const visitors = { CallExpression(node) { if (!('callee' in node)) { return; } const { callee } = node; if (callee.type === 'Identifier' && getGraphQLTagName(callee) && 'arguments' in node) { const templateLiteral = node.arguments[0]; if (templateLiteral && (templateLiteral.type === 'TemplateLiteral' || templateLiteral.type === 'TaggedTemplateExpression')) { const parsed = parseTemplateLiteral(templateLiteral, rangeMapper); if (parsed) { result.push(parsed); } } } traverse(node, visitors); }, TaggedTemplateExpression(node) { var _a; const tagName = getGraphQLTagName(node.tag); if (tagName) { const { loc } = node.quasi.quasis[0]; const template = node.quasi.quasis.length > 1 ? node.quasi.quasis .map((quasi, i) => { var _a; return i === ((_a = node.quasi.quasis) === null || _a === void 0 ? void 0 : _a.length) - 1 ? quasi.value.raw : getReplacementString(quasi.value.raw, node.quasi.quasis[i + 1].value.raw); }) .join('') : node.quasi.quasis[0].value.raw; if (loc && node.quasi.quasis.length > 1) { const last = node.quasi.quasis.pop(); if ((_a = last === null || last === void 0 ? void 0 : last.loc) === null || _a === void 0 ? void 0 : _a.end) { loc.end = last.loc.end; } } if (loc) { const range = rangeMapper(new graphql_language_service_1.Range(new graphql_language_service_1.Position(loc.start.line - 1, loc.start.column), new graphql_language_service_1.Position(loc.end.line - 1, loc.end.column))); result.push({ tag: tagName, template: template.endsWith('\n') ? template.slice(0, template.length - 1) : template, range, }); } } }, TemplateLiteral(node) { var _a, _b; const hasGraphQLPrefix = node.quasis[0].value.raw.startsWith('#graphql\n'); const hasGraphQLComment = Boolean((_b = (_a = node.leadingComments) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.value.match(/^\s*GraphQL\s*$/)); if (hasGraphQLPrefix || hasGraphQLComment) { const parsed = parseTemplateLiteral(node, rangeMapper); if (parsed) { result.push(parsed); } } }, }; for (const ast of asts) { visit(ast, visitors); } return result; } exports.findGraphQLTags = findGraphQLTags; const getReplacementString = (quasi, nextQuasi) => { const trimmed = quasi.trimEnd(); const trimmedNext = nextQuasi.trimStart(); if (trimmed.endsWith('{') && trimmedNext.startsWith('}')) { return quasi + '__typename'; } return quasi; }; function parseTemplateLiteral(node, rangeMapper) { var _a; const { loc } = node.quasis[0]; if (loc) { if (node.quasis.length > 1) { const quasis = [...node.quasis]; const last = quasis.pop(); if ((_a = last === null || last === void 0 ? void 0 : last.loc) === null || _a === void 0 ? void 0 : _a.end) { loc.end = last.loc.end; } } const template = node.quasis .map((quasi, i) => { var _a; return i === ((_a = node.quasis) === null || _a === void 0 ? void 0 : _a.length) - 1 ? quasi.value.raw : getReplacementString(quasi.value.raw, node.quasis[i + 1].value.raw); }) .join(''); const range = rangeMapper(new graphql_language_service_1.Range(new graphql_language_service_1.Position(loc.start.line - 1, loc.start.column), new graphql_language_service_1.Position(loc.end.line - 1, loc.end.column))); return { tag: '', template, range, }; } } function getGraphQLTagName(tag) { if (tag.type === 'Identifier' && constants_1.TAG_MAP[tag.name]) { return tag.name; } if (tag.type === 'MemberExpression' && tag.object.type === 'Identifier' && tag.object.name === 'graphql' && tag.property.type === 'Identifier' && tag.property.name === 'experimental') { return 'graphql.experimental'; } return null; } function visit(node, visitors) { const fn = visitors[node.type]; if (fn && fn != null) { fn(node); return; } traverse(node, visitors); } const IGNORED_KEYS = { comments: true, end: true, leadingComments: true, loc: true, name: true, start: true, trailingComments: true, type: true, }; function traverse(node, visitors) { for (const key in node) { if (IGNORED_KEYS[key]) { continue; } const prop = node[key]; if (prop && typeof prop === 'object' && typeof prop.type === 'string') { visit(prop, visitors); } else if (Array.isArray(prop)) { for (const item of prop) { if (item && typeof item === 'object' && typeof item.type === 'string') { visit(item, visitors); } } } } } //# sourceMappingURL=findGraphQLTags.js.map