@mayurgodhani/ecomtools-cli
Version:
E-commerce tools MCP server for Shopify development
122 lines (102 loc) • 3.61 kB
JavaScript
/**
* 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
};