UNPKG

n8n-mcp

Version:

Integration between n8n workflow automation and Model Context Protocol (MCP)

192 lines 7.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeRepository = void 0; class NodeRepository { constructor(dbOrService) { if ('db' in dbOrService) { this.db = dbOrService.db; } else { this.db = dbOrService; } } saveNode(node) { const stmt = this.db.prepare(` INSERT OR REPLACE INTO nodes ( node_type, package_name, display_name, description, category, development_style, is_ai_tool, is_trigger, is_webhook, is_versioned, version, documentation, properties_schema, operations, credentials_required, outputs, output_names ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `); stmt.run(node.nodeType, node.packageName, node.displayName, node.description, node.category, node.style, node.isAITool ? 1 : 0, node.isTrigger ? 1 : 0, node.isWebhook ? 1 : 0, node.isVersioned ? 1 : 0, node.version, node.documentation || null, JSON.stringify(node.properties, null, 2), JSON.stringify(node.operations, null, 2), JSON.stringify(node.credentials, null, 2), node.outputs ? JSON.stringify(node.outputs, null, 2) : null, node.outputNames ? JSON.stringify(node.outputNames, null, 2) : null); } getNode(nodeType) { const row = this.db.prepare(` SELECT * FROM nodes WHERE node_type = ? `).get(nodeType); if (!row) return null; return { nodeType: row.node_type, displayName: row.display_name, description: row.description, category: row.category, developmentStyle: row.development_style, package: row.package_name, isAITool: Number(row.is_ai_tool) === 1, isTrigger: Number(row.is_trigger) === 1, isWebhook: Number(row.is_webhook) === 1, isVersioned: Number(row.is_versioned) === 1, version: row.version, properties: this.safeJsonParse(row.properties_schema, []), operations: this.safeJsonParse(row.operations, []), credentials: this.safeJsonParse(row.credentials_required, []), hasDocumentation: !!row.documentation, outputs: row.outputs ? this.safeJsonParse(row.outputs, null) : null, outputNames: row.output_names ? this.safeJsonParse(row.output_names, null) : null }; } getAITools() { const rows = this.db.prepare(` SELECT node_type, display_name, description, package_name FROM nodes WHERE is_ai_tool = 1 ORDER BY display_name `).all(); return rows.map(row => ({ nodeType: row.node_type, displayName: row.display_name, description: row.description, package: row.package_name })); } safeJsonParse(json, defaultValue) { try { return JSON.parse(json); } catch { return defaultValue; } } upsertNode(node) { this.saveNode(node); } getNodeByType(nodeType) { return this.getNode(nodeType); } getNodesByCategory(category) { const rows = this.db.prepare(` SELECT * FROM nodes WHERE category = ? ORDER BY display_name `).all(category); return rows.map(row => this.parseNodeRow(row)); } searchNodes(query, mode = 'OR', limit = 20) { let sql = ''; const params = []; if (mode === 'FUZZY') { sql = ` SELECT * FROM nodes WHERE node_type LIKE ? OR display_name LIKE ? OR description LIKE ? ORDER BY display_name LIMIT ? `; const fuzzyQuery = `%${query}%`; params.push(fuzzyQuery, fuzzyQuery, fuzzyQuery, limit); } else { const words = query.split(/\s+/).filter(w => w.length > 0); const conditions = words.map(() => '(node_type LIKE ? OR display_name LIKE ? OR description LIKE ?)'); const operator = mode === 'AND' ? ' AND ' : ' OR '; sql = ` SELECT * FROM nodes WHERE ${conditions.join(operator)} ORDER BY display_name LIMIT ? `; for (const word of words) { const searchTerm = `%${word}%`; params.push(searchTerm, searchTerm, searchTerm); } params.push(limit); } const rows = this.db.prepare(sql).all(...params); return rows.map(row => this.parseNodeRow(row)); } getAllNodes(limit) { let sql = 'SELECT * FROM nodes ORDER BY display_name'; if (limit) { sql += ` LIMIT ${limit}`; } const rows = this.db.prepare(sql).all(); return rows.map(row => this.parseNodeRow(row)); } getNodeCount() { const result = this.db.prepare('SELECT COUNT(*) as count FROM nodes').get(); return result.count; } getAIToolNodes() { return this.getAITools(); } getNodesByPackage(packageName) { const rows = this.db.prepare(` SELECT * FROM nodes WHERE package_name = ? ORDER BY display_name `).all(packageName); return rows.map(row => this.parseNodeRow(row)); } searchNodeProperties(nodeType, query, maxResults = 20) { const node = this.getNode(nodeType); if (!node || !node.properties) return []; const results = []; const searchLower = query.toLowerCase(); function searchProperties(properties, path = []) { for (const prop of properties) { if (results.length >= maxResults) break; const currentPath = [...path, prop.name || prop.displayName]; const pathString = currentPath.join('.'); if (prop.name?.toLowerCase().includes(searchLower) || prop.displayName?.toLowerCase().includes(searchLower) || prop.description?.toLowerCase().includes(searchLower)) { results.push({ path: pathString, property: prop, description: prop.description }); } if (prop.options) { searchProperties(prop.options, currentPath); } } } searchProperties(node.properties); return results; } parseNodeRow(row) { return { nodeType: row.node_type, displayName: row.display_name, description: row.description, category: row.category, developmentStyle: row.development_style, package: row.package_name, isAITool: Number(row.is_ai_tool) === 1, isTrigger: Number(row.is_trigger) === 1, isWebhook: Number(row.is_webhook) === 1, isVersioned: Number(row.is_versioned) === 1, version: row.version, properties: this.safeJsonParse(row.properties_schema, []), operations: this.safeJsonParse(row.operations, []), credentials: this.safeJsonParse(row.credentials_required, []), hasDocumentation: !!row.documentation, outputs: row.outputs ? this.safeJsonParse(row.outputs, null) : null, outputNames: row.output_names ? this.safeJsonParse(row.output_names, null) : null }; } } exports.NodeRepository = NodeRepository; //# sourceMappingURL=node-repository.js.map