UNPKG

cube-ms

Version:

Production-ready microservice framework with health monitoring, validation, error handling, and Docker Swarm support

258 lines (207 loc) • 8.34 kB
#!/usr/bin/env node /** * Setup .npmrc for CCN Platform Registry * * This script helps developers setup .npmrc with their own token * to avoid token expiration issues in version control. */ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import readline from 'readline'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const colors = { red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', magenta: '\x1b[35m', cyan: '\x1b[36m', reset: '\x1b[0m', bold: '\x1b[1m' }; function log(message, color = colors.reset) { console.log(`${color}${message}${colors.reset}`); } function createInterface() { return readline.createInterface({ input: process.stdin, output: process.stdout }); } async function askQuestion(question) { const rl = createInterface(); return new Promise((resolve) => { rl.question(question, (answer) => { rl.close(); resolve(answer.trim()); }); }); } async function checkExistingNpmrc() { const npmrcPath = path.join(process.cwd(), '.npmrc'); if (fs.existsSync(npmrcPath)) { log('\nšŸ“‹ .npmrc file already exists', colors.yellow); const content = fs.readFileSync(npmrcPath, 'utf-8'); const hasToken = content.includes('_password=') && !content.includes('YOUR_TOKEN_HERE'); const hasValidToken = hasToken && !content.includes('cnZxbW91a3NwcWEyZ3d0YmlmdTczNW9kYnBucGJ2ZnRreWxseGpvaXF4bmoyZGFqYmhtYQ=='); if (hasValidToken) { log('āœ… .npmrc already configured with custom token', colors.green); return true; } else if (hasToken) { log('āš ļø .npmrc contains old/expired token', colors.yellow); const answer = await askQuestion('Do you want to update it? (y/n): '); return answer.toLowerCase() !== 'y'; } else { log('āš ļø .npmrc exists but no token configured', colors.yellow); } } return false; } function createNpmrcFromTemplate(token) { const templatePath = path.join(process.cwd(), '.npmrc.template'); const npmrcPath = path.join(process.cwd(), '.npmrc'); if (!fs.existsSync(templatePath)) { log('āŒ .npmrc.template not found', colors.red); log('Please make sure you are in the correct directory', colors.yellow); return false; } try { let content = fs.readFileSync(templatePath, 'utf-8'); content = content.replace(/YOUR_TOKEN_HERE/g, token); fs.writeFileSync(npmrcPath, content); log('āœ… .npmrc created successfully', colors.green); return true; } catch (error) { log(`āŒ Error creating .npmrc: ${error.message}`, colors.red); return false; } } async function validateNpmrcToken() { const npmrcPath = path.join(process.cwd(), '.npmrc'); if (!fs.existsSync(npmrcPath)) { log('āŒ .npmrc file not found', colors.red); return false; } try { const content = fs.readFileSync(npmrcPath, 'utf-8'); // Check if token is configured if (content.includes('YOUR_TOKEN_HERE')) { log('āŒ .npmrc token not configured (still contains YOUR_TOKEN_HERE)', colors.red); return false; } // Check for old hardcoded template tokens (but allow valid user tokens) // Previous validation was too restrictive and blocked legitimate tokens // Check if token exists const hasToken = content.includes('_password=') && content.match(/_password=([^\s\n]+)/); if (hasToken) { log('āœ… .npmrc token is configured', colors.green); // Try to test the token by checking registry access log('šŸ” Testing registry access...', colors.cyan); try { const { execSync } = await import('child_process'); // Test npm registry access execSync('npm ping --registry http://devops.ccn/CCN%20Platform%20Collection/_packaging/CCN.Platform/npm/registry/', { stdio: 'pipe' }); log('āœ… Registry access successful', colors.green); return true; } catch (error) { log('āš ļø Registry access failed - token might be expired', colors.yellow); log('Please check your token validity', colors.yellow); return false; } } else { log('āŒ No token found in .npmrc', colors.red); return false; } } catch (error) { log(`āŒ Error validating .npmrc: ${error.message}`, colors.red); return false; } } function addToGitignore() { const gitignorePath = path.join(process.cwd(), '.gitignore'); const npmrcEntry = '.npmrc\n'; if (fs.existsSync(gitignorePath)) { const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8'); if (!gitignoreContent.includes('.npmrc')) { fs.appendFileSync(gitignorePath, `\n# NPM Configuration with sensitive tokens\n${npmrcEntry}`); log('āœ… Added .npmrc to .gitignore', colors.green); } } else { fs.writeFileSync(gitignorePath, `# NPM Configuration with sensitive tokens\n${npmrcEntry}`); log('āœ… Created .gitignore with .npmrc entry', colors.green); } } function showInstructions() { log('\n' + '='.repeat(60), colors.cyan); log('šŸ“‹ HOW TO GET YOUR CCN PLATFORM TOKEN', colors.bold + colors.cyan); log('='.repeat(60), colors.cyan); log('\n1. Go to CCN DevOps Portal:', colors.yellow); log(' http://devops.ccn/', colors.blue); log('\n2. Navigate to your project:', colors.yellow); log(' → CCN Platform Collection → _packaging → CCN.Platform', colors.blue); log('\n3. Click "Connect to Feed" or "Generate Token"', colors.yellow); log('\n4. Select "npm" and copy the _password value', colors.yellow); log(' Example: cnZxbW91a3NwcWEyZ3d0YmlmdTczNW9kYnBucGJ2ZnRreWxseGpvaXF4bmoyZGFqYmhtYQ==', colors.blue); log('\n5. Paste the token when prompted below', colors.yellow); log('\n' + '='.repeat(60), colors.cyan); } async function main() { log('\nšŸš€ CCN Platform .npmrc Setup', colors.bold + colors.magenta); log('This tool helps you configure .npmrc for CCN registry access\n', colors.cyan); const command = process.argv[2]; if (command === 'validate' || command === 'check') { log('šŸ” Validating .npmrc configuration...', colors.cyan); const isValid = await validateNpmrcToken(); process.exit(isValid ? 0 : 1); } if (command === 'help' || command === '--help' || command === '-h') { showInstructions(); log('\nšŸ“‹ Usage:', colors.yellow); log(' node scripts/setup-npmrc.js # Interactive setup', colors.blue); log(' node scripts/setup-npmrc.js validate # Validate existing .npmrc', colors.blue); log(' node scripts/setup-npmrc.js help # Show this help', colors.blue); return; } // Check if already configured if (await checkExistingNpmrc()) { return; } showInstructions(); const token = await askQuestion('\nšŸ“ Enter your CCN Platform token (_password value): '); if (!token || token.length < 20) { log('āŒ Invalid token provided', colors.red); log('Token should be a long base64 string', colors.yellow); process.exit(1); } // Validate token format (should be base64 encoded and reasonable length) if (token.length < 40) { log('āš ļø Token appears too short to be valid', colors.yellow); log('Please verify your token from CCN DevOps Portal', colors.yellow); process.exit(1); } if (createNpmrcFromTemplate(token)) { addToGitignore(); log('\nāœ… Setup completed successfully!', colors.bold + colors.green); log('\nšŸ“‹ Next steps:', colors.yellow); log(' 1. Run: npm install', colors.blue); log(' 2. Your .npmrc is now configured for CCN registry', colors.blue); log(' 3. The .npmrc file is added to .gitignore for security', colors.blue); log('\nšŸ”’ Security Notes:', colors.yellow); log(' • Never commit .npmrc to version control', colors.red); log(' • Update your token before expiration', colors.red); log(' • Run "npm run validate-npmrc" to check token validity', colors.blue); } } // Handle Ctrl+C gracefully process.on('SIGINT', () => { log('\n\nšŸ‘‹ Setup cancelled', colors.yellow); process.exit(0); }); main().catch(error => { log(`\nāŒ Setup failed: ${error.message}`, colors.red); process.exit(1); });