Skip to main content
Glama

Convex MCP server

Official
by get-convex
analyze.ts3.33 kB
import { Identifier, LineNumber } from "./convex"; // Match the original declaration of a variable. const definitionRegex = /^var ([a-zA-Z0-9_]+) =/; // Match a one line export. const onelineExportRegex = /^export \{([a-zA-Z0-9_, ]+)\};$/; const onelineItemRegex = /^([a-zA-Z0-9_]+)( as [a-zA-Z0-9_]+)?$/; // Match a line in the `export` block at the end of an esbuild bundle. const exportRegex = /^([a-zA-Z0-9_]+)( as [a-zA-Z0-9_]+)?,?$/; export function findLineNumbers( source: string, expectedExports: Identifier[], ): Map<Identifier, LineNumber> { const lines = source.split("\n").map((l) => l.trim()); // First, find the `export` block at the end of the bundle. For example, // ``` // export { // a_default as default, // b, // }; // ``` /// We also have to handle the case where esbuild decides to emit a oneline export. // ``` // export { a as b, b }; let foundExport = false; const exportMap = new Map<string, string>(); for (const line of lines) { const onelineMatch = line.match(onelineExportRegex); if (onelineMatch) { const pieces = onelineMatch[1].split(",").map((l) => l.trim()); for (const piece of pieces) { const itemMatch = piece.match(onelineItemRegex); if (!itemMatch) { console.warn(`Item ${piece} in ${line} didn't match item regex`); continue; } const origIdentifier = itemMatch[1]; const exportIdentifier = itemMatch[2] ? itemMatch[2].slice(" as ".length) : origIdentifier; exportMap.set(exportIdentifier, origIdentifier); } break; } if (line === "export {") { foundExport = true; continue; } if (foundExport && line === "};") { foundExport = false; break; } if (!foundExport) { continue; } const exportMatch = line.match(exportRegex); if (!exportMatch) { console.warn(`Line ${line} did not match export regex`); continue; } const origIdentifier = exportMatch[1]; const exportIdentifier = exportMatch[2] ? exportMatch[2].slice(" as ".length) : origIdentifier; exportMap.set(exportIdentifier, origIdentifier); } // Do a second pass where we try to find `esbuild`'s original declarations. // ``` // var a_default = action(() => { ... }); // ``` const lineNumbers = new Map<string, number>(); for (const [index, line] of lines.entries()) { const lineno = index + 1; const definitionMatch = line.match(definitionRegex); if (!definitionMatch) { continue; } const origIdentifier = definitionMatch[1]; lineNumbers.set(origIdentifier, lineno); } // Stitch the two relations together to map exported name to line number. const result = new Map<string, number>(); for (const exported of expectedExports) { const origIdentifier = exportMap.get(exported); if (origIdentifier === undefined) { console.warn(`Couldn't find export ${exported} in `, exportMap); continue; } const lineNumber = lineNumbers.get(origIdentifier); if (lineNumber === undefined) { console.warn( `Couldn't find line number for ${exported} -> ${origIdentifier} in `, lineNumbers, ); continue; } result.set(exported, lineNumber); } return result; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-convex/convex-backend'

If you have feedback or need assistance with the MCP directory API, please join our Discord server