graphorama-mcp
Version:
High-performance MCP server for code validation and service orchestration
208 lines (171 loc) โข 6.54 kB
JavaScript
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 };