Skip to main content
Glama

NervusDB MCP Server

Official
by nervusdb
multiLanguageParser.ts6.06 kB
/** * 多语言解析器(基于 ADR-005) * * 支持语言: * - TypeScript/JavaScript * - Python * - Go * - Rust * - Java * - C/C++ (基础支持) */ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { createRequire } from 'node:module'; // 加载 native module(支持从 src 和 dist 运行) function loadNativeModule() { const require = createRequire(import.meta.url); const currentDir = path.dirname(fileURLToPath(import.meta.url)); // 尝试不同的相对路径 const possiblePaths = [ path.resolve(currentDir, '../../../target/release/synapse_parser_napi.node'), // 本地开发 (src/ 或 dist/) path.resolve(currentDir, '../../native/synapse_parser_napi.node'), // npm 发布后 (dist/domain/parsing/ → dist/native/) ]; const errors: string[] = []; for (const nativePath of possiblePaths) { try { return require(nativePath); } catch (err) { errors.push(`${nativePath}: ${err instanceof Error ? err.message : String(err)}`); // 继续尝试下一个路径 } } throw new Error(`Native module not found. Tried paths:\n${errors.join('\n')}`); } interface ImportExportItem { name: string; path?: string; [key: string]: unknown; } interface ParseError { message: string; line?: number; [key: string]: unknown; } export interface ParseResult { filePath: string; language: string; entities: string[]; imports: ImportExportItem[]; exports: ImportExportItem[]; errors: ParseError[]; } export interface ParseStats { functions: number; classes: number; interfaces: number; imports: number; exports: number; errors: number; } export type SupportedLanguage = | 'TypeScript' | 'JavaScript' | 'Python' | 'Go' | 'Rust' | 'Java' | 'C' | 'C++'; /** * 多语言解析器 */ interface NativeLanguageManager { parseFile(filePath: string, content: string): string; parseFilesBatch(files: Array<[string, string]>): string[]; guessLanguage(filePath: string): string | null; } export class MultiLanguageParser { private manager: NativeLanguageManager; // NAPI LanguageManager constructor() { try { // 动态加载 Rust native module // 路径解析:支持从 src 和 dist 目录运行 const nativeModule = loadNativeModule(); this.manager = new nativeModule.LanguageManager(); } catch (error) { throw new Error( `Failed to load multi-language parser: ${error}\n` + 'Please run "pnpm build:rust" first.\n' + 'Or check if the native module was built successfully.', ); } } /** * 根据文件路径自动检测语言并解析 * * @param filePath - 文件路径 * @param content - 文件内容 * @returns 解析结果 */ async parseFile(filePath: string, content: string): Promise<ParseResult> { try { const jsonResult = this.manager.parseFile(filePath, content); return JSON.parse(jsonResult) as ParseResult; } catch (error) { throw new Error(`Failed to parse ${filePath}: ${error}`); } } /** * 批量解析文件(性能优化版本) * * 内部会按语言分组处理,提升性能约 30% * * @param files - 文件列表 [filePath, content][] * @returns 解析结果数组 */ async parseFilesInBatch(files: Array<[string, string]>): Promise<ParseResult[]> { try { // 转换为 NAPI 期望的格式 const filesArray = files.map(([path, content]) => [path, content] as [string, string]); const jsonResults = this.manager.parseFilesBatch(filesArray); return jsonResults.map((json: string) => JSON.parse(json) as ParseResult); } catch (error) { throw new Error(`Batch parsing failed: ${error}`); } } /** * 检测文件语言 * * @param filePath - 文件路径 * @returns 语言名称或 null(不支持的文件类型) */ detectLanguage(filePath: string): SupportedLanguage | null { try { return this.manager.guessLanguage(filePath) as SupportedLanguage | null; } catch { return null; } } /** * 获取支持的语言列表 * * @returns 语言名称数组 */ getSupportedLanguages(): SupportedLanguage[] { const nativeModule = loadNativeModule(); return nativeModule.LanguageManager.getSupportedLanguages() as SupportedLanguage[]; } /** * 检查多语言解析器是否可用 */ static isAvailable(): boolean { try { loadNativeModule(); return true; } catch { return false; } } /** * 性能基准测试 * * @param sourceCode - 源代码 * @param language - 语言类型 * @param iterations - 迭代次数 * @returns 平均每次解析耗时(毫秒) */ static async benchmark( sourceCode: string, language: SupportedLanguage, iterations: number = 100, ): Promise<number> { const parser = new MultiLanguageParser(); const filePath = `test.${getExtension(language)}`; const start = Date.now(); for (let i = 0; i < iterations; i++) { await parser.parseFile(filePath, sourceCode); } const duration = Date.now() - start; return duration / iterations; } } /** * 创建多语言解析器(工厂函数) * * @returns 解析器实例或 null(不可用) */ export function createMultiLanguageParser(): MultiLanguageParser | null { if (!MultiLanguageParser.isAvailable()) { console.warn( '⚠️ Multi-language parser not available.\n' + ' Please run "pnpm build:rust" to build the native module.\n' + ' Falling back to legacy parser (TypeScript only).', ); return null; } return new MultiLanguageParser(); } /** * 获取语言对应的文件扩展名 */ function getExtension(language: SupportedLanguage): string { const map: Record<SupportedLanguage, string> = { TypeScript: 'ts', JavaScript: 'js', Python: 'py', Go: 'go', Rust: 'rs', Java: 'java', C: 'c', 'C++': 'cpp', }; return map[language] || 'txt'; }

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/nervusdb/nervusdb-mcp'

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