UNPKG

apisurf

Version:

Analyze API surface changes between npm package versions to catch breaking changes

140 lines (139 loc) 5.45 kB
import chalk from 'chalk'; /** * Formats inspect results for console output with colors and structure. */ export function formatInspectConsoleOutput(result, verbose = false) { const lines = []; // Header lines.push(chalk.bold.blue(`📦 ${result.packageName}@${result.version}`)); if (result.repositoryUrl) { lines.push(chalk.gray(` Repository: ${result.repositoryUrl}`)); } lines.push(''); // Summary if (result.success) { lines.push(chalk.green(`✓ ${result.summary}`)); } else { lines.push(chalk.red(`✗ ${result.summary}`)); } // Errors if (result.errors && result.errors.length > 0) { lines.push(''); lines.push(chalk.red('Errors:')); result.errors.forEach(error => { lines.push(chalk.red(` - ${error}`)); }); } if (!result.success) { return lines.join('\n'); } // API Surfaces for (const [entryPoint, surface] of result.apiSurfaces) { lines.push(''); lines.push(chalk.bold.cyan(entryPoint === 'main' ? '📄 Main Export' : `📄 Export: ${entryPoint}`)); lines.push(chalk.gray('─'.repeat(50))); // Default export if (surface.defaultExport) { lines.push(''); lines.push(chalk.yellow('Default Export:')); lines.push(' ✓ Has default export'); } // Named exports if (surface.namedExports.size > 0) { lines.push(''); lines.push(chalk.yellow(`Named Exports (${surface.namedExports.size}):`)); const exports = Array.from(surface.namedExports).sort(); exports.forEach(name => { const typeDef = surface.typeDefinitions?.get(name); if (typeDef) { lines.push(` ${chalk.green('●')} ${chalk.cyan(name)} ${chalk.gray(`(${typeDef.kind})`)}`); if (verbose) { lines.push(formatTypeDefinition(typeDef, ' ')); } } else { lines.push(` ${chalk.green('●')} ${chalk.cyan(name)}`); } }); } // Type-only exports if (surface.typeOnlyExports.size > 0) { lines.push(''); lines.push(chalk.yellow(`Type Exports (${surface.typeOnlyExports.size}):`)); const typeExports = Array.from(surface.typeOnlyExports).sort(); typeExports.forEach(name => { const typeDef = surface.typeDefinitions?.get(name); if (typeDef) { lines.push(` ${chalk.blue('○')} ${chalk.cyan(name)} ${chalk.gray(`(${typeDef.kind})`)}`); if (verbose) { lines.push(formatTypeDefinition(typeDef, ' ')); } } else { lines.push(` ${chalk.blue('○')} ${chalk.cyan(name)}`); } }); } // Star exports if (surface.starExports.length > 0) { lines.push(''); lines.push(chalk.yellow(`Re-exports (${surface.starExports.length}):`)); surface.starExports.forEach(module => { lines.push(` ${chalk.magenta('*')} ${chalk.gray(`from "${module}"`)}`); }); } } return lines.join('\n'); } /** * Formats a type definition for console output. */ function formatTypeDefinition(def, indent) { const lines = []; if (def.signature) { // For simple signatures, show them inline if (def.signature.length < 80 && !def.signature.includes('\n')) { lines.push(`${indent}${chalk.gray(def.signature)}`); } else if (def.kind === 'function') { // Format function signature lines.push(`${indent}${chalk.gray(formatFunctionSignature(def))}`); } else { // For complex types, show a summary if (def.properties && def.properties.size > 0) { lines.push(`${indent}${chalk.gray('Properties:')}`); const props = Array.from(def.properties.entries()).slice(0, 5); props.forEach(([name, type]) => { const truncatedType = type.length > 50 ? type.substring(0, 47) + '...' : type; lines.push(`${indent} - ${name}: ${chalk.gray(truncatedType)}`); }); if (def.properties.size > 5) { lines.push(`${indent} ${chalk.gray(`... and ${def.properties.size - 5} more`)}`); } } if (def.members && def.members.length > 0) { lines.push(`${indent}${chalk.gray('Members:')}`); const members = def.members.slice(0, 5); members.forEach(member => { lines.push(`${indent} - ${member}`); }); if (def.members.length > 5) { lines.push(`${indent} ${chalk.gray(`... and ${def.members.length - 5} more`)}`); } } } } return lines.join('\n'); } /** * Formats a function signature for display. */ function formatFunctionSignature(def) { if (def.parameters && def.returnType) { const params = def.parameters.join(', '); return `(${params}) => ${def.returnType}`; } return def.signature || 'function'; }