UNPKG

@mayurgodhani/ecomtools-cli

Version:

E-commerce tools MCP server for Shopify development

122 lines (102 loc) 3.61 kB
/** * File Utilities * Functions for managing and working with code snippet files */ const fs = require('fs'); const path = require('path'); /** * Parse a code snippet file and extract its components * @param {string} content - The file content * @returns {Object} - Parsed data with title, description and code */ function parseCodeFile(content) { const lines = content.split('\n'); let title = ''; let description = ''; let codeStartIndex = 0; // Parse title if (lines[0].startsWith('Title:')) { title = lines[0].substring('Title:'.length).trim(); codeStartIndex = 1; } // Parse description if (lines[1].startsWith('Description:')) { description = lines[1].substring('Description:'.length).trim(); codeStartIndex = 2; } // Parse code (everything after the title and description) if (lines[codeStartIndex].startsWith('Code:')) { codeStartIndex += 1; } const code = lines.slice(codeStartIndex).join('\n'); return { title, description, code }; } /** * Load code snippet files from a directory * @param {string} dataDir - Path to the data directory * @returns {Promise<Array>} - Array of parsed code snippets */ async function loadCodeFiles(dataDir) { try { const files = await fs.promises.readdir(dataDir); const codeSnippets = []; for (const file of files) { if (file.endsWith('.txt')) { const filePath = path.join(dataDir, file); try { const stats = await fs.promises.stat(filePath); if (stats.isFile()) { const content = await fs.promises.readFile(filePath, 'utf8'); const parsed = parseCodeFile(content); // Add filename and handle (for resource URI) parsed.filename = file; parsed.handle = file.replace(/\.txt$/, '').toLowerCase(); codeSnippets.push(parsed); } } catch (err) { console.error(`Error reading file ${file}:`, err); } } } return codeSnippets; } catch (err) { console.error('Error loading code files:', err); return []; } } /** * Find code snippets matching provided keywords * @param {Array} snippets - Array of code snippets * @param {string} keywords - Keywords to search for * @returns {Object|null} - Best matching snippet or null */ function findMatchingSnippet(snippets, keywords) { // Convert keywords to lowercase for case-insensitive matching const normalizedKeywords = keywords.toLowerCase().split(/\s+/); // Score each snippet based on keyword matches const scoredSnippets = snippets.map(snippet => { let score = 0; const titleLower = snippet.title.toLowerCase(); const descLower = snippet.description.toLowerCase(); // Check title and description for keyword matches normalizedKeywords.forEach(keyword => { if (titleLower.includes(keyword)) score += 3; // Higher weight for title matches if (descLower.includes(keyword)) score += 1; // Lower weight for description matches if (snippet.handle.includes(keyword)) score += 2; // Good weight for filename matches }); return { snippet, score }; }); // Sort by score (descending) scoredSnippets.sort((a, b) => b.score - a.score); // Return the best match if it has a reasonable score (at least one keyword matched in title or handle) return scoredSnippets.length > 0 && scoredSnippets[0].score >= 2 ? scoredSnippets[0].snippet : null; } module.exports = { parseCodeFile, loadCodeFiles, findMatchingSnippet };