UNPKG

datapilot-cli

Version:

Enterprise-grade streaming multi-format data analysis with comprehensive statistical insights and intelligent relationship detection - supports CSV, JSON, Excel, TSV, Parquet - memory-efficient, cross-platform

283 lines (225 loc) • 7.65 kB
#!/usr/bin/env node /** * NPM Package Validation Script * Validates package structure, metadata, and functionality before publishing */ const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); function validatePackageJson() { console.log('šŸ“¦ Validating package.json...'); const packagePath = path.resolve('./package.json'); const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')); const requiredFields = ['name', 'version', 'description', 'main', 'bin', 'keywords', 'author', 'license']; const missingFields = requiredFields.filter(field => !packageJson[field]); if (missingFields.length > 0) { console.error(`āŒ Missing required fields: ${missingFields.join(', ')}`); return false; } // Check version format const versionRegex = /^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$/; if (!versionRegex.test(packageJson.version)) { console.error(`āŒ Invalid version format: ${packageJson.version}`); return false; } // Check required files const requiredFiles = ['README.md', 'LICENSE', 'CHANGELOG.md']; const missingFiles = requiredFiles.filter(file => !fs.existsSync(path.resolve(file))); if (missingFiles.length > 0) { console.error(`āŒ Missing required files: ${missingFiles.join(', ')}`); return false; } console.log('āœ… package.json validation passed'); return true; } function validateDistDirectory() { console.log('šŸ“ Validating dist directory...'); const distPath = path.resolve('./dist'); if (!fs.existsSync(distPath)) { console.error('āŒ dist directory not found. Run "npm run build" first.'); return false; } const requiredFiles = [ 'index.js', 'index.d.ts', 'cli/index.js' ]; const missingFiles = requiredFiles.filter(file => !fs.existsSync(path.join(distPath, file)) ); if (missingFiles.length > 0) { console.error(`āŒ Missing dist files: ${missingFiles.join(', ')}`); return false; } console.log('āœ… dist directory validation passed'); return true; } function validateCLI() { console.log('šŸ”Ø Validating CLI functionality...'); const cliPath = path.resolve('./dist/cli/index.js'); try { // Test version command const version = execSync(`node "${cliPath}" --version`, { encoding: 'utf8' }).trim(); if (!version.match(/^\d+\.\d+\.\d+/)) { console.error(`āŒ Invalid version output: ${version}`); return false; } // Test help command const help = execSync(`node "${cliPath}" --help`, { encoding: 'utf8' }); if (!help.includes('Usage:') || !help.includes('datapilot')) { console.error('āŒ Help output missing required content'); return false; } console.log('āœ… CLI validation passed'); return true; } catch (error) { console.error(`āŒ CLI validation failed: ${error.message}`); return false; } } function validateDependencies() { console.log('šŸ”— Validating dependencies...'); try { // Check for security vulnerabilities execSync('npm audit --audit-level moderate', { stdio: 'inherit' }); // Check for outdated dependencies const outdated = execSync('npm outdated --json', { encoding: 'utf8' }); const outdatedPackages = JSON.parse(outdated || '{}'); if (Object.keys(outdatedPackages).length > 0) { console.log('āš ļø Outdated dependencies found:'); console.log(JSON.stringify(outdatedPackages, null, 2)); } console.log('āœ… Dependencies validation passed'); return true; } catch (error) { console.error(`āŒ Dependencies validation failed: ${error.message}`); return false; } } function validateLicense() { console.log('šŸ“„ Validating license...'); const licensePath = path.resolve('./LICENSE'); if (!fs.existsSync(licensePath)) { console.error('āŒ LICENSE file not found'); return false; } const license = fs.readFileSync(licensePath, 'utf8'); if (license.length < 100) { console.error('āŒ LICENSE file appears to be incomplete'); return false; } console.log('āœ… License validation passed'); return true; } function validateReadme() { console.log('šŸ“ Validating README...'); const readmePath = path.resolve('./README.md'); if (!fs.existsSync(readmePath)) { console.error('āŒ README.md not found'); return false; } const readme = fs.readFileSync(readmePath, 'utf8'); const requiredSections = [ '# DataPilot', '## Installation', '## Usage', '## Features' ]; const missingSections = requiredSections.filter(section => !readme.includes(section) ); if (missingSections.length > 0) { console.error(`āŒ README missing sections: ${missingSections.join(', ')}`); return false; } if (readme.length < 1000) { console.error('āŒ README appears to be too short'); return false; } console.log('āœ… README validation passed'); return true; } function validateChangelog() { console.log('šŸ“… Validating CHANGELOG...'); const changelogPath = path.resolve('./CHANGELOG.md'); if (!fs.existsSync(changelogPath)) { console.error('āŒ CHANGELOG.md not found'); return false; } const changelog = fs.readFileSync(changelogPath, 'utf8'); if (!changelog.includes('# Changelog')) { console.error('āŒ CHANGELOG missing main heading'); return false; } // Check for version entries const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const currentVersion = packageJson.version; if (!changelog.includes(`[${currentVersion}]`)) { console.log(`āš ļø Current version ${currentVersion} not found in CHANGELOG`); } console.log('āœ… CHANGELOG validation passed'); return true; } function validateFileSize() { console.log('šŸ“Š Validating package size...'); try { // Create a test pack const packResult = execSync('npm pack --dry-run --json', { encoding: 'utf8' }); const packData = JSON.parse(packResult); const packageSize = packData[0].size; const maxSize = 50 * 1024 * 1024; // 50MB limit if (packageSize > maxSize) { console.error(`āŒ Package too large: ${(packageSize / 1024 / 1024).toFixed(2)}MB > 50MB`); return false; } console.log(`āœ… Package size OK: ${(packageSize / 1024 / 1024).toFixed(2)}MB`); return true; } catch (error) { console.error(`āŒ Package size validation failed: ${error.message}`); return false; } } function main() { console.log('šŸ” DataPilot Package Validation\n'); const validations = [ validatePackageJson, validateDistDirectory, validateCLI, validateDependencies, validateLicense, validateReadme, validateChangelog, validateFileSize ]; const results = validations.map(validation => { try { return validation(); } catch (error) { console.error(`āŒ Validation error: ${error.message}`); return false; } }); const passed = results.filter(Boolean).length; const total = results.length; console.log(`\nšŸ“ˆ Validation Results: ${passed}/${total} passed`); if (passed === total) { console.log('āœ… Package validation successful! Ready for publishing.'); process.exit(0); } else { console.log('āŒ Package validation failed. Please fix the issues above.'); process.exit(1); } } if (require.main === module) { main(); } module.exports = { validatePackageJson, validateDistDirectory, validateCLI, validateDependencies, validateLicense, validateReadme, validateChangelog, validateFileSize };