UNPKG

graphorama-mcp

Version:

High-performance MCP server for code validation and service orchestration

208 lines (171 loc) โ€ข 6.54 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); // Build script for NPM package preparation function buildPackage() { console.log('๐Ÿ”จ Building Graphorama NPM package...'); console.log(''); try { const projectRoot = path.join(__dirname, '..'); const packageJson = require('../package.json'); console.log(`๐Ÿ“ฆ Package: ${packageJson.name}@${packageJson.version}`); console.log(''); // Step 1: Validate package structure console.log('๐Ÿ” Validating package structure...'); const requiredFiles = [ 'package.json', 'lib/install.js', 'lib/test.js', 'bin/graphorama', 'README.md' ]; const requiredDirs = [ 'lib', 'bin' ]; // Check required directories for (const dir of requiredDirs) { const dirPath = path.join(projectRoot, dir); if (!fs.existsSync(dirPath)) { throw new Error(`Required directory missing: ${dir}`); } } console.log(' โœ… Required directories exist'); // Check required files for (const file of requiredFiles) { const filePath = path.join(projectRoot, file); if (!fs.existsSync(filePath)) { console.log(` โš ๏ธ Optional file missing: ${file}`); } } console.log(' โœ… Package structure validated'); // Step 2: Validate JavaScript files console.log('๐Ÿ” Validating JavaScript files...'); const jsFiles = [ 'lib/install.js', 'lib/test.js', 'bin/graphorama', 'scripts/build.js' ]; for (const file of jsFiles) { const filePath = path.join(projectRoot, file); if (fs.existsSync(filePath)) { try { // Basic syntax check by requiring the file if (file.endsWith('.js')) { require(filePath); } console.log(` โœ… ${file} - syntax OK`); } catch (error) { console.log(` โŒ ${file} - syntax error: ${error.message}`); } } } // Step 3: Check executability console.log('๐Ÿ” Checking file permissions...'); const executableFiles = ['bin/graphorama']; for (const file of executableFiles) { const filePath = path.join(projectRoot, file); if (fs.existsSync(filePath)) { try { fs.accessSync(filePath, fs.constants.X_OK); console.log(` โœ… ${file} - executable`); } catch (error) { console.log(` โŒ ${file} - not executable`); } } } // Step 4: Update version consistency console.log('๐Ÿ” Checking version consistency...'); // Read Cargo.toml version const cargoTomlPath = path.join(projectRoot, 'Cargo.toml'); if (fs.existsSync(cargoTomlPath)) { const cargoToml = fs.readFileSync(cargoTomlPath, 'utf8'); const cargoVersionMatch = cargoToml.match(/version = "([^"]+)"/); if (cargoVersionMatch) { const cargoVersion = cargoVersionMatch[1]; if (cargoVersion !== packageJson.version) { console.log(` โš ๏ธ Version mismatch: Cargo.toml=${cargoVersion}, package.json=${packageJson.version}`); } else { console.log(` โœ… Versions match: ${packageJson.version}`); } } } // Step 5: Generate NPM package files list console.log('๐Ÿ” Generating package files list...'); const packageFiles = []; function scanDirectory(dir, relativePath = '') { const fullPath = path.join(projectRoot, relativePath); const items = fs.readdirSync(fullPath); for (const item of items) { const itemPath = path.join(fullPath, item); const relativeItemPath = path.join(relativePath, item).replace(/\\/g, '/'); if (fs.statSync(itemPath).isDirectory()) { if (['lib', 'bin'].includes(item) || relativePath.startsWith('lib/') || relativePath.startsWith('bin/')) { scanDirectory(item, relativeItemPath); } } else { if (relativePath.startsWith('lib/') || relativePath.startsWith('bin/') || ['README.md', 'LICENSE', 'package.json'].includes(item)) { packageFiles.push(relativeItemPath); } } } } scanDirectory(''); console.log(' ๐Ÿ“„ Package will include:'); packageFiles.sort().forEach(file => console.log(` ${file}`)); // Step 6: Test installation script console.log('๐Ÿงช Testing installation logic...'); try { const installer = require('../lib/install.js'); const platform = installer.detectPlatform(); const binaryName = installer.getBinaryName(platform); console.log(` โœ… Platform detection: ${platform}`); console.log(` โœ… Binary name: ${binaryName}`); // Test shouldInstall logic const shouldInstall = installer.shouldInstall(); console.log(` โœ… Install check: ${shouldInstall ? 'will install' : 'skip install'}`); } catch (error) { console.log(` โŒ Installation test failed: ${error.message}`); } // Step 7: Size check console.log('๐Ÿ” Package size analysis...'); let totalSize = 0; for (const file of packageFiles) { const filePath = path.join(projectRoot, file); if (fs.existsSync(filePath)) { const stats = fs.statSync(filePath); totalSize += stats.size; } } const sizeKB = Math.round(totalSize / 1024); console.log(` ๐Ÿ“ Total package size: ${sizeKB} KB`); if (sizeKB > 1024) { console.log(' โš ๏ธ Package is large (>1MB) - consider optimizing'); } else { console.log(' โœ… Package size is reasonable'); } console.log(''); console.log('๐ŸŽ‰ Build validation complete!'); console.log(''); console.log('๐Ÿ“ฆ Ready to publish:'); console.log(' npm pack # Test package creation'); console.log(' npm login # Login to NPM'); console.log(' npm publish # Publish to NPM registry'); console.log(''); console.log('๐Ÿงช Test locally first:'); console.log(' npm pack'); console.log(' npm install -g ./graphorama-*.tgz'); console.log(' graphorama --version'); } catch (error) { console.error('โŒ Build failed:', error.message); process.exit(1); } } // Main execution if (require.main === module) { buildPackage(); } module.exports = { buildPackage };