Skip to main content
Glama
prepublish.cjs4.67 kB
const fs = require('fs'); const path = require('path'); console.log('🔍 Validating package before publishing...\n'); const projectRoot = path.join(__dirname, '..'); // Required files for npm package const requiredFiles = [ 'bin/index.js', 'scripts/install.cjs', 'src/server.py', 'src/__init__.py', 'requirements.txt', 'create_templates.py', 'package.json', 'README.md' ]; // Optional but recommended files const optionalFiles = [ 'LICENSE', '.npmignore', 'templates/invoice.docx', 'templates/report.docx', 'templates/contract.docx', 'templates/letter.docx' ]; let hasError = false; let warnings = []; console.log('Checking required files:'); console.log('------------------------'); // Check required files for (const file of requiredFiles) { const filePath = path.join(projectRoot, file); if (!fs.existsSync(filePath)) { console.error(`❌ Missing required file: ${file}`); hasError = true; } else { const stats = fs.statSync(filePath); const size = (stats.size / 1024).toFixed(1); console.log(`✅ Found: ${file} (${size} KB)`); } } console.log('\nChecking optional files:'); console.log('------------------------'); // Check optional files for (const file of optionalFiles) { const filePath = path.join(projectRoot, file); if (!fs.existsSync(filePath)) { console.log(`⚠️ Missing optional file: ${file}`); warnings.push(`Missing ${file}`); } else { console.log(`✅ Found: ${file}`); } } // Check bin file shebang console.log('\nChecking executable configuration:'); console.log('-----------------------------------'); const binFile = path.join(projectRoot, 'bin/index.js'); if (fs.existsSync(binFile)) { const binContent = fs.readFileSync(binFile, 'utf8'); if (!binContent.startsWith('#!/usr/bin/env node')) { console.error('❌ bin/index.js must start with shebang: #!/usr/bin/env node'); hasError = true; } else { console.log('✅ Shebang line present in bin/index.js'); } // Check if file is executable (Unix-like systems) try { fs.accessSync(binFile, fs.constants.X_OK); console.log('✅ bin/index.js is executable'); } catch (e) { console.log('⚠️ bin/index.js may not be executable (this is OK on Windows)'); } } // Check package.json configuration console.log('\nChecking package.json:'); console.log('----------------------'); const packageJsonPath = path.join(projectRoot, 'package.json'); if (fs.existsSync(packageJsonPath)) { const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); if (!packageJson.name) { console.error('❌ package.json missing "name" field'); hasError = true; } else { console.log(`✅ Package name: ${packageJson.name}`); } if (!packageJson.version) { console.error('❌ package.json missing "version" field'); hasError = true; } else { console.log(`✅ Package version: ${packageJson.version}`); } if (!packageJson.bin || !packageJson.bin['docxtpl-mcp']) { console.error('❌ package.json missing bin configuration'); hasError = true; } else { console.log('✅ Bin entry configured'); } if (!packageJson.type || packageJson.type !== 'module') { console.log('⚠️ package.json "type" should be "module" for ES6 imports'); warnings.push('Consider setting "type": "module" in package.json'); } else { console.log('✅ ES6 module type configured'); } } // Check Python files console.log('\nChecking Python components:'); console.log('---------------------------'); const serverPath = path.join(projectRoot, 'src/server.py'); if (fs.existsSync(serverPath)) { const serverContent = fs.readFileSync(serverPath, 'utf8'); if (serverContent.includes('async def main()')) { console.log('✅ MCP server main function found'); } else { console.log('⚠️ Could not verify MCP server main function'); } } // Summary console.log('\n' + '='.repeat(50)); if (hasError) { console.error('\n❌ VALIDATION FAILED'); console.error('Please fix the errors above before publishing.\n'); process.exit(1); } else if (warnings.length > 0) { console.log('\n⚠️ VALIDATION PASSED WITH WARNINGS:'); warnings.forEach(w => console.log(` - ${w}`)); console.log('\n✅ Package can be published, but consider addressing the warnings.\n'); } else { console.log('\n✅ VALIDATION SUCCESSFUL'); console.log('Package is ready to publish!\n'); console.log('Next steps:'); console.log(' 1. Test locally: npm link && npx docxtpl-mcp'); console.log(' 2. Login to npm: npm login'); console.log(' 3. Publish: npm publish'); console.log(' 4. Test published: npx docxtpl-mcp@latest\n'); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/z1w2r3/doc-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server