UNPKG

aico-pack

Version:

A tool to pack repository contents to single file for AI consumption

199 lines 7.76 kB
import path from 'node:path'; import strip from 'strip-comments'; const rtrimLines = (content) => content .split('\n') .map((line) => line.trimEnd()) .join('\n'); class BaseManipulator { removeComments(content) { return content; } removeEmptyLines(content) { return content .split('\n') .filter((line) => line.trim() !== '') .join('\n'); } } class StripCommentsManipulator extends BaseManipulator { constructor(language) { super(); this.language = language; } removeComments(content) { const result = strip(content, { language: this.language, preserveNewlines: true, }); return rtrimLines(result); } } class CppManipulator extends BaseManipulator { removeComments(content) { let result = strip(content, { language: 'c', preserveNewlines: true, }); result = result .split('\n') .map((line) => { const tripleSlashIndex = line.indexOf('///'); if (tripleSlashIndex !== -1) { return line.substring(0, tripleSlashIndex).trimEnd(); } return line; }) .join('\n'); return rtrimLines(result); } } class PythonManipulator extends BaseManipulator { removeDocStrings(content) { if (!content) return ''; const lines = content.split('\n'); let result = ''; let buffer = ''; let quoteType = ''; let tripleQuotes = 0; const doubleQuoteRegex = /^\s*(?<!\\)(?:""")\s*(?:\n)?[\s\S]*?(?<!("""))(?<!\\)(?:""")/gm; const singleQuoteRegex = /^\s*(?<!\\)(?:''')\s*(?:\n)?[\s\S]*?(?<!('''))(?<!\\)(?:''')/gm; const sz = lines.length; for (let i = 0; i < sz; i++) { const line = lines[i] + (i !== sz - 1 ? '\n' : ''); buffer += line; if (quoteType === '') { const indexSingle = line.search(/(?<![\"])(?<!\\)'''(?![\"])/g); const indexDouble = line.search(/(?<![\'])(?<!\\)"""(?![\'])/g); if (indexSingle !== -1 && (indexDouble === -1 || indexSingle < indexDouble)) { quoteType = "'"; } else if (indexDouble !== -1 && (indexSingle === -1 || indexDouble < indexSingle)) { quoteType = '"'; } } if (quoteType === "'") { tripleQuotes += (line.match(/(?<![\"])(?<!\\)'''(?!["])/g) || []).length; } if (quoteType === '"') { tripleQuotes += (line.match(/(?<![\'])(?<!\\)"""(?![\'])/g) || []).length; } if (tripleQuotes % 2 === 0) { const docstringRegex = quoteType === '"' ? doubleQuoteRegex : singleQuoteRegex; buffer = buffer.replace(docstringRegex, ''); result += buffer; buffer = ''; tripleQuotes = 0; quoteType = ''; } } result += buffer; return result; } removeHashComments(content) { const searchInPairs = (pairs, hashIndex) => { return pairs.some(([start, end]) => hashIndex > start && hashIndex < end); }; let result = ''; const pairs = []; let prevQuote = 0; while (prevQuote < content.length) { const openingQuote = content.slice(prevQuote + 1).search(/(?<!\\)(?:"|'|'''|""")/g) + prevQuote + 1; if (openingQuote === prevQuote) break; let closingQuote = -1; if (content.startsWith('"""', openingQuote) || content.startsWith("'''", openingQuote)) { const quoteType = content.slice(openingQuote, openingQuote + 3); closingQuote = content.indexOf(quoteType, openingQuote + 3); } else { const quoteType = content[openingQuote]; closingQuote = content.indexOf(quoteType, openingQuote + 1); } if (closingQuote === -1) break; pairs.push([openingQuote, closingQuote]); prevQuote = closingQuote; } let prevHash = 0; while (prevHash < content.length) { const hashIndex = content.slice(prevHash).search(/(?<!\\)#/g) + prevHash; if (hashIndex === prevHash - 1) { result += content.slice(prevHash); break; } const isInsideString = searchInPairs(pairs, hashIndex); const nextNewLine = content.indexOf('\n', hashIndex); if (!isInsideString) { if (nextNewLine === -1) { result += content.slice(prevHash); break; } result += `${content.slice(prevHash, hashIndex)}\n`; } else { if (nextNewLine === -1) { result += content.slice(prevHash); break; } result += `${content.slice(prevHash, nextNewLine)}\n`; } prevHash = nextNewLine + 1; } return result; } removeComments(content) { let result = this.removeDocStrings(content); result = this.removeHashComments(result); return rtrimLines(result); } } class CompositeManipulator extends BaseManipulator { constructor(...manipulators) { super(); this.manipulators = manipulators; } removeComments(content) { return this.manipulators.reduce((acc, manipulator) => manipulator.removeComments(acc), content); } } const manipulators = { '.c': new StripCommentsManipulator('c'), '.h': new StripCommentsManipulator('c'), '.hpp': new CppManipulator(), '.cpp': new CppManipulator(), '.cc': new CppManipulator(), '.cxx': new CppManipulator(), '.cs': new StripCommentsManipulator('csharp'), '.css': new StripCommentsManipulator('css'), '.dart': new StripCommentsManipulator('c'), '.go': new StripCommentsManipulator('c'), '.html': new StripCommentsManipulator('html'), '.java': new StripCommentsManipulator('java'), '.js': new StripCommentsManipulator('javascript'), '.jsx': new StripCommentsManipulator('javascript'), '.kt': new StripCommentsManipulator('c'), '.less': new StripCommentsManipulator('less'), '.php': new StripCommentsManipulator('php'), '.rb': new StripCommentsManipulator('ruby'), '.rs': new StripCommentsManipulator('c'), '.sass': new StripCommentsManipulator('sass'), '.scss': new StripCommentsManipulator('sass'), '.sh': new StripCommentsManipulator('perl'), '.sol': new StripCommentsManipulator('c'), '.sql': new StripCommentsManipulator('sql'), '.swift': new StripCommentsManipulator('swift'), '.ts': new StripCommentsManipulator('javascript'), '.tsx': new StripCommentsManipulator('javascript'), '.xml': new StripCommentsManipulator('xml'), '.yaml': new StripCommentsManipulator('perl'), '.yml': new StripCommentsManipulator('perl'), '.py': new PythonManipulator(), '.vue': new CompositeManipulator(new StripCommentsManipulator('html'), new StripCommentsManipulator('css'), new StripCommentsManipulator('javascript')), '.svelte': new CompositeManipulator(new StripCommentsManipulator('html'), new StripCommentsManipulator('css'), new StripCommentsManipulator('javascript')), }; export const getFileManipulator = (filePath) => { const ext = path.extname(filePath); return manipulators[ext] || null; }; //# sourceMappingURL=fileManipulate.js.map