repomix
Version:
A tool to pack repository contents to single file for AI consumption
134 lines (133 loc) • 4.07 kB
JavaScript
import path from 'node:path';
const EXTENSION_TO_LANGUAGE = {
'.js': 'JavaScript',
'.jsx': 'JavaScript (JSX)',
'.ts': 'TypeScript',
'.tsx': 'TypeScript (TSX)',
'.mjs': 'JavaScript (ESM)',
'.cjs': 'JavaScript (CJS)',
'.html': 'HTML',
'.htm': 'HTML',
'.css': 'CSS',
'.scss': 'SCSS',
'.sass': 'Sass',
'.less': 'Less',
'.vue': 'Vue',
'.svelte': 'Svelte',
'.json': 'JSON',
'.yaml': 'YAML',
'.yml': 'YAML',
'.toml': 'TOML',
'.xml': 'XML',
'.ini': 'INI',
'.env': 'Environment',
'.md': 'Markdown',
'.mdx': 'MDX',
'.rst': 'reStructuredText',
'.txt': 'Text',
'.py': 'Python',
'.rb': 'Ruby',
'.php': 'PHP',
'.java': 'Java',
'.kt': 'Kotlin',
'.kts': 'Kotlin Script',
'.scala': 'Scala',
'.go': 'Go',
'.rs': 'Rust',
'.c': 'C',
'.cpp': 'C++',
'.cc': 'C++',
'.h': 'C/C++ Header',
'.hpp': 'C++ Header',
'.cs': 'C#',
'.swift': 'Swift',
'.m': 'Objective-C',
'.mm': 'Objective-C++',
'.sh': 'Shell',
'.bash': 'Bash',
'.zsh': 'Zsh',
'.fish': 'Fish',
'.ps1': 'PowerShell',
'.bat': 'Batch',
'.cmd': 'Batch',
'.sql': 'SQL',
'.graphql': 'GraphQL',
'.gql': 'GraphQL',
'.proto': 'Protocol Buffers',
'.dockerfile': 'Dockerfile',
'.lua': 'Lua',
'.r': 'R',
'.ex': 'Elixir',
'.exs': 'Elixir Script',
'.erl': 'Erlang',
'.clj': 'Clojure',
'.hs': 'Haskell',
'.ml': 'OCaml',
'.nim': 'Nim',
'.zig': 'Zig',
'.dart': 'Dart',
'.v': 'V',
'.sol': 'Solidity',
};
const getLanguageFromExtension = (ext) => {
return EXTENSION_TO_LANGUAGE[ext.toLowerCase()] || ext.slice(1).toUpperCase() || 'Unknown';
};
export const calculateStatistics = (processedFiles, fileLineCounts) => {
const statsByExt = {};
let totalLines = 0;
for (const file of processedFiles) {
const ext = path.extname(file.path).toLowerCase() || '(no ext)';
const lines = fileLineCounts[file.path] || file.content.split('\n').length;
if (!statsByExt[ext]) {
statsByExt[ext] = { fileCount: 0, lineCount: 0 };
}
statsByExt[ext].fileCount++;
statsByExt[ext].lineCount += lines;
totalLines += lines;
}
const byFileType = Object.entries(statsByExt)
.map(([ext, stats]) => ({
extension: ext,
language: ext === '(no ext)' ? 'No Extension' : getLanguageFromExtension(ext),
fileCount: stats.fileCount,
lineCount: stats.lineCount,
}))
.sort((a, b) => b.fileCount - a.fileCount);
const largestFiles = processedFiles
.map((file) => ({
path: file.path,
lines: fileLineCounts[file.path] || file.content.split('\n').length,
}))
.sort((a, b) => b.lines - a.lines)
.slice(0, 10);
return {
totalFiles: processedFiles.length,
totalLines,
byFileType,
largestFiles,
};
};
export const generateStatisticsSection = (stats) => {
const lines = ['## Statistics', ''];
lines.push(`${stats.totalFiles} files | ${stats.totalLines.toLocaleString()} lines`);
lines.push('');
lines.push('| Language | Files | Lines |');
lines.push('|----------|------:|------:|');
const topTypes = stats.byFileType.slice(0, 10);
for (const type of topTypes) {
lines.push(`| ${type.language} | ${type.fileCount} | ${type.lineCount.toLocaleString()} |`);
}
if (stats.byFileType.length > 10) {
const otherFiles = stats.byFileType.slice(10).reduce((sum, t) => sum + t.fileCount, 0);
const otherLines = stats.byFileType.slice(10).reduce((sum, t) => sum + t.lineCount, 0);
lines.push(`| Other | ${otherFiles} | ${otherLines.toLocaleString()} |`);
}
lines.push('');
if (stats.largestFiles.length > 0) {
lines.push('**Largest files:**');
for (const file of stats.largestFiles) {
lines.push(`- \`${file.path}\` (${file.lines.toLocaleString()} lines)`);
}
}
return lines.join('\n');
};