UNPKG

codesnap-analyzer

Version:

Create comprehensive snapshots of your codebase with token counting for LLMs

121 lines (120 loc) 4.69 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OutputFormatter = void 0; // src/services/formatter.ts const path_1 = __importDefault(require("path")); const token_counter_1 = require("../utils/token-counter"); const inspector_1 = require("inspector"); class OutputFormatter { static createSummary(directory, stats, tokenCounts) { const summary = token_counter_1.TokenCounter.formatTokenCounts(tokenCounts); const lines = [ `Project Directory: ${path_1.default.basename(directory)}`, `Total Files Analyzed: ${stats.totalFiles}`, `Total Size: ${(stats.totalSize / 1024 / 1024).toFixed(2)} MB`, `Date: ${new Date().toISOString()}`, "", summary, ]; return lines.join("\n"); } static formatNumber(num) { if (num >= 1000000) { return `${(num / 1000000).toFixed(2)}M`; } if (num >= 1000) { return `${(num / 1000).toFixed(1)}K`; } return num.toString(); } static createTree(files) { const tree = this.buildFileTree(files); const lines = ["Directory structure:", ...this.renderTree(tree)]; return lines.join("\n"); } static buildFileTree(files) { const root = { name: "", type: "directory", children: [], path: "", }; // Sort files to ensure consistent ordering const sortedFiles = [...files].sort((a, b) => a.path.localeCompare(b.path)); for (const file of sortedFiles) { const parts = file.path.split(/[\\/]/); let currentNode = root; // Process each part of the path for (let i = 0; i < parts.length; i++) { const part = parts[i]; const isFile = i === parts.length - 1; const nodePath = parts.slice(0, i + 1).join("/"); // Find existing node or create new one let node = currentNode.children.find((n) => n.name === part); if (!node) { node = { name: part, type: isFile ? "file" : "directory", children: [], path: nodePath, }; currentNode.children.push(node); // Sort children after adding new node currentNode.children.sort((a, b) => { // Directories come first if (a.type !== b.type) { return a.type === "directory" ? -1 : 1; } // Then sort alphabetically return a.name.localeCompare(b.name); }); } currentNode = node; } } return root; } static renderTree(node, prefix = "", isLast = true, level = 0) { const lines = []; if (node.name) { const line = prefix + (isLast ? "└── " : "├── ") + node.name + (node.type === "directory" ? "/" : ""); lines.push(line); } const childPrefix = node.name ? prefix + (isLast ? " " : "│ ") : ""; if (node.type === "directory") { node.children.forEach((child, index) => { const isLastChild = index === node.children.length - 1; lines.push(...this.renderTree(child, childPrefix, isLastChild, level + 1)); }); } return lines; } static createContent(files) { const output = []; const separator = "=" + "=".repeat(47) + "\n"; // Add README.md first if it exists const readme = files.find((f) => f.path.toLowerCase() === "readme.md"); if (readme?.content) { output.push(separator + `File: ${readme.path}\n` + separator + readme.content + "\n"); } // Add all other files files.forEach((file) => { inspector_1.console.log("createContent from", file.path); if (file.content && file.path.toLowerCase() !== "readme.md") { output.push(separator + `File: ${file.path}\n` + separator + file.content + "\n"); } }); return output.join("\n"); } } exports.OutputFormatter = OutputFormatter;