UNPKG

url-builder-mcp

Version:

URL Builder MCP Server - Professional URL construction with intelligent parameter handling for Claude Desktop

170 lines (142 loc) • 4.55 kB
#!/usr/bin/env node /** * Pre-publish verification script * Ensures zero errors, warnings, and test failures before NPM publication */ const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); // ANSI color codes const colors = { reset: '\x1b[0m', bright: '\x1b[1m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', cyan: '\x1b[36m' }; function log(message, color = 'reset') { console.log(`${colors[color]}${message}${colors.reset}`); } function runCommand(command, description) { log(`\nšŸ” ${description}...`, 'cyan'); try { const output = execSync(command, { encoding: 'utf8', stdio: 'pipe', cwd: process.cwd() }); log(`āœ… ${description} passed`, 'green'); return { success: true, output }; } catch (error) { log(`āŒ ${description} failed`, 'red'); log(`Error: ${error.message}`, 'red'); if (error.stdout) { log(`Output: ${error.stdout}`, 'yellow'); } if (error.stderr) { log(`Error output: ${error.stderr}`, 'red'); } return { success: false, error }; } } function checkPackageJson() { log('\nšŸ“¦ Checking package.json...', 'cyan'); const packagePath = path.join(process.cwd(), 'package.json'); if (!fs.existsSync(packagePath)) { log('āŒ package.json not found', 'red'); return false; } const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8')); // Check required fields const requiredFields = ['name', 'version', 'description', 'main', 'bin']; for (const field of requiredFields) { if (!pkg[field]) { log(`āŒ Missing required field: ${field}`, 'red'); return false; } } // Check bin file exists if (pkg.bin && typeof pkg.bin === 'object') { for (const [name, binPath] of Object.entries(pkg.bin)) { const fullPath = path.join(process.cwd(), binPath); if (!fs.existsSync(fullPath)) { log(`āŒ Bin file not found: ${binPath}`, 'red'); return false; } } } log('āœ… package.json validation passed', 'green'); return true; } function checkFiles() { log('\nšŸ“ Checking required files...', 'cyan'); const requiredFiles = [ 'README.md', 'LICENSE', 'dist/index.js', 'bin/url-builder-mcp.js' ]; for (const file of requiredFiles) { const filePath = path.join(process.cwd(), file); if (!fs.existsSync(filePath)) { log(`āŒ Required file not found: ${file}`, 'red'); return false; } } log('āœ… All required files present', 'green'); return true; } async function main() { log('šŸš€ Pre-Publish Quality Gate - Zero Defects Policy', 'bright'); log('═'.repeat(60), 'blue'); const checks = [ // Package validation () => checkPackageJson(), () => checkFiles(), // Code quality checks () => runCommand('npm run type-check', 'TypeScript type checking').success, () => runCommand('npm run lint', 'ESLint validation (zero warnings)').success, () => runCommand('npm run format:check', 'Prettier format checking').success, // Testing () => runCommand('npm run test', 'Unit tests').success, () => runCommand('npm run test:coverage', 'Test coverage').success, // Build verification () => runCommand('npm run build', 'TypeScript compilation').success, // Package verification () => runCommand('npm pack --dry-run', 'NPM package validation').success, // Launcher verification () => runCommand('node bin/url-builder-mcp.js --help', 'Launcher functionality').success ]; let allPassed = true; for (let i = 0; i < checks.length; i++) { const checkPassed = checks[i](); if (!checkPassed) { allPassed = false; break; } } log('\n' + '═'.repeat(60), 'blue'); if (allPassed) { log('šŸŽ‰ ALL QUALITY GATES PASSED!', 'green'); log('āœ… Zero errors, zero warnings, zero test failures', 'green'); log('šŸš€ Package is ready for NPM publication', 'green'); log('\nTo publish:', 'cyan'); log(' npm publish', 'bright'); process.exit(0); } else { log('āŒ QUALITY GATE FAILED!', 'red'); log('🚫 Cannot publish with errors or warnings', 'red'); log('šŸ”§ Please fix all issues before publishing', 'yellow'); process.exit(1); } } // Run if called directly if (require.main === module) { main().catch(error => { log(`šŸ’„ Unexpected error: ${error.message}`, 'red'); process.exit(1); }); } module.exports = { main };