Skip to main content
Glama
generate-svg-samples.js11.4 kB
#!/usr/bin/env node /** * Generate Sample Architecture SVG Files * Uses Puppeteer for browser-based rendering (workaround for DOMPurify issues) */ import puppeteer from 'puppeteer'; import fs from 'fs/promises'; import path from 'path'; // Sample architecture diagrams const samples = [ { name: 'microservices-architecture', title: 'Microservices Architecture', code: `graph TB subgraph "Client Layer" Web[Web Application] Mobile[Mobile App] end subgraph "API Gateway" Gateway[API Gateway<br/>Load Balancer] end subgraph "Microservices" Auth[Authentication<br/>Service] User[User<br/>Service] Order[Order<br/>Service] Payment[Payment<br/>Service] Notification[Notification<br/>Service] end subgraph "Data Layer" AuthDB[(Auth DB)] UserDB[(User DB)] OrderDB[(Order DB)] PaymentDB[(Payment DB)] end subgraph "Infrastructure" Cache[Redis Cache] Queue[Message Queue] Storage[Object Storage] end Web --> Gateway Mobile --> Gateway Gateway --> Auth Gateway --> User Gateway --> Order Gateway --> Payment Auth --> AuthDB User --> UserDB Order --> OrderDB Payment --> PaymentDB Order --> Queue Payment --> Queue Queue --> Notification User --> Cache Order --> Cache Payment --> Storage style Gateway fill:#e1f5fe style Auth fill:#fff3e0 style User fill:#fff3e0 style Order fill:#fff3e0 style Payment fill:#fff3e0 style Notification fill:#fff3e0` }, { name: 'cloud-infrastructure', title: 'Cloud Infrastructure', code: `flowchart TB subgraph Users_Layer["Users"] Users[End Users] end subgraph CDN_Layer["CDN & DNS"] CDN[CDN<br/>CloudFront] DNS[Route 53<br/>DNS] end subgraph LB_Layer["Load Balancing"] ALB[Application<br/>Load Balancer] end subgraph AZ1["Compute - Availability Zone 1"] EC2_1A[EC2 Instance] EC2_1B[EC2 Instance] end subgraph AZ2["Compute - Availability Zone 2"] EC2_2A[EC2 Instance] EC2_2B[EC2 Instance] end subgraph DB_Layer["Database"] RDS_Primary[(RDS Primary)] RDS_Standby[(RDS Standby)] end subgraph Storage_Layer["Storage"] S3[S3 Bucket] EBS[EBS Volumes] end subgraph Monitor_Layer["Monitoring"] CloudWatch[CloudWatch] CloudTrail[CloudTrail] end Users --> DNS DNS --> CDN CDN --> ALB ALB --> EC2_1A ALB --> EC2_1B ALB --> EC2_2A ALB --> EC2_2B EC2_1A --> RDS_Primary EC2_1B --> RDS_Primary EC2_2A --> RDS_Primary EC2_2B --> RDS_Primary RDS_Primary -.->|Replication| RDS_Standby EC2_1A --> S3 EC2_2A --> S3 EC2_1A --> EBS EC2_2A --> EBS EC2_1A --> CloudWatch EC2_2A --> CloudWatch ALB --> CloudWatch RDS_Primary --> CloudWatch style CDN fill:#e1f5fe style ALB fill:#c8e6c9 style RDS_Primary fill:#fff3e0 style S3 fill:#f3e5f5` }, { name: 'cicd-pipeline', title: 'CI/CD Pipeline', code: `graph LR subgraph "Source Control" Git[Git Repository<br/>GitHub] end subgraph "CI Pipeline" Trigger[Webhook Trigger] Build[Build<br/>Compile Code] Test[Run Tests<br/>Unit & Integration] Security[Security Scan<br/>SAST/DAST] Quality[Code Quality<br/>SonarQube] end subgraph "Artifact Management" Registry[Container Registry<br/>Docker Hub/ECR] end subgraph "CD Pipeline" Deploy_Dev[Deploy to Dev] Test_Dev[Test Dev] Deploy_Staging[Deploy to Staging] Test_Staging[Test Staging] Approval[Manual Approval] Deploy_Prod[Deploy to Production] end subgraph "Monitoring" Monitor[Application<br/>Monitoring] Alerts[Alerts &<br/>Notifications] end Git -->|Push/PR| Trigger Trigger --> Build Build --> Test Test --> Security Security --> Quality Quality -->|Pass| Registry Registry --> Deploy_Dev Deploy_Dev --> Test_Dev Test_Dev -->|Pass| Deploy_Staging Deploy_Staging --> Test_Staging Test_Staging -->|Pass| Approval Approval -->|Approved| Deploy_Prod Deploy_Prod --> Monitor Monitor --> Alerts Quality -->|Fail| Git Test_Dev -->|Fail| Git Test_Staging -->|Fail| Git style Build fill:#e1f5fe style Test fill:#c8e6c9 style Security fill:#ffebee style Deploy_Prod fill:#fff3e0 style Approval fill:#f3e5f5` }, { name: 'data-pipeline', title: 'Data Pipeline Architecture', code: `graph LR subgraph "Data Sources" API[External APIs] DB[Databases] Files[File Systems] Stream[Event Streams] end subgraph "Data Ingestion" Kafka[Apache Kafka] Kinesis[AWS Kinesis] end subgraph "Data Processing" Spark[Apache Spark<br/>Batch Processing] Flink[Apache Flink<br/>Stream Processing] end subgraph "Data Storage" Lake[Data Lake<br/>S3] Warehouse[Data Warehouse<br/>Redshift] Cache[Redis Cache] end subgraph "Analytics & ML" BI[BI Tools<br/>Tableau/PowerBI] ML[ML Models<br/>SageMaker] Analytics[Analytics Engine<br/>Athena] end API --> Kafka DB --> Kafka Files --> Kafka Stream --> Kinesis Kafka --> Spark Kinesis --> Flink Spark --> Lake Flink --> Warehouse Spark --> Warehouse Lake --> Analytics Warehouse --> BI Warehouse --> ML ML --> Cache Analytics --> Cache style Kafka fill:#e1f5fe style Spark fill:#c8e6c9 style Lake fill:#fff3e0 style Warehouse fill:#f3e5f5 style ML fill:#ffebee` }, { name: 'serverless-architecture', title: 'Serverless Architecture', code: `flowchart TB subgraph Client_Layer["Client"] Client[Web/Mobile Client] end subgraph API_Layer["API & Auth"] API[API Gateway] Cognito[AWS Cognito<br/>Authentication] end subgraph Lambda_Layer["Lambda Functions"] Auth_Lambda[Auth Lambda] User_Lambda[User Lambda] Data_Lambda[Data Lambda] Process_Lambda[Process Lambda] end subgraph Data_Layer["Data Storage"] DynamoDB[(DynamoDB)] S3[S3 Storage] RDS[(RDS Aurora<br/>Serverless)] end subgraph Async_Layer["Async Processing"] SQS[SQS Queue] SNS[SNS Topics] EventBridge[EventBridge] end subgraph Monitor_Layer["Monitoring"] CloudWatch[CloudWatch<br/>Logs & Metrics] XRay[X-Ray<br/>Tracing] end Client --> API API --> Cognito Cognito --> Auth_Lambda API --> User_Lambda API --> Data_Lambda User_Lambda --> DynamoDB Data_Lambda --> S3 Data_Lambda --> RDS Data_Lambda --> SQS SQS --> Process_Lambda Process_Lambda --> SNS User_Lambda --> EventBridge EventBridge --> Process_Lambda Auth_Lambda --> CloudWatch User_Lambda --> CloudWatch Data_Lambda --> CloudWatch Process_Lambda --> CloudWatch API --> XRay User_Lambda --> XRay style API fill:#e1f5fe style Auth_Lambda fill:#fff3e0 style User_Lambda fill:#fff3e0 style Data_Lambda fill:#fff3e0 style Process_Lambda fill:#fff3e0 style DynamoDB fill:#c8e6c9` } ]; async function generateSVG(diagram) { const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] }); try { const page = await browser.newPage(); // Create HTML with Mermaid using script tag (not module) const html = ` <!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script> <style> body { margin: 0; padding: 20px; background: white; } </style> </head> <body> <pre class="mermaid"> ${diagram.code} </pre> <script> mermaid.initialize({ startOnLoad: true, theme: 'default', securityLevel: 'loose', logLevel: 'debug' }); </script> </body> </html> `; await page.setContent(html); // Wait for Mermaid to fully render await new Promise(resolve => setTimeout(resolve, 3000)); // Get the SVG content const svgContent = await page.evaluate(() => { const svg = document.querySelector('svg'); if (!svg) return null; // Get computed dimensions const bbox = svg.getBoundingClientRect(); // Set proper dimensions if (!svg.hasAttribute('width') || svg.getAttribute('width') === '100%') { svg.setAttribute('width', Math.ceil(bbox.width)); } if (!svg.hasAttribute('height') || svg.getAttribute('height') === '100%') { svg.setAttribute('height', Math.ceil(bbox.height)); } // Add viewBox if missing if (!svg.hasAttribute('viewBox')) { svg.setAttribute('viewBox', `0 0 ${Math.ceil(bbox.width)} ${Math.ceil(bbox.height)}`); } return svg.outerHTML; }); if (!svgContent || svgContent.length < 200) { throw new Error('SVG generation failed or produced empty result'); } // Clean up the SVG: // 1. Fix self-closing br tags (Mermaid outputs <br> instead of <br/>) // 2. Remove any trailing whitespace let cleanedSvg = svgContent .replace(/<br>/g, '<br/>') // Fix HTML br tags to XML self-closing format .trim(); return cleanedSvg; } finally { await browser.close(); } } async function main() { console.log('🎨 Generating Sample Architecture SVG Files...\n'); // Create output directory const outputDir = path.join(process.cwd(), 'examples', 'architectures'); await fs.mkdir(outputDir, { recursive: true }); let successCount = 0; let failCount = 0; for (const sample of samples) { try { console.log(`📊 Generating: ${sample.title}...`); const svg = await generateSVG(sample); const filename = `${sample.name}.svg`; const filepath = path.join(outputDir, filename); await fs.writeFile(filepath, svg, 'utf-8'); console.log(`✅ Created: ${filename}`); console.log(` Path: ${filepath}\n`); successCount++; } catch (error) { console.error(`❌ Failed: ${sample.title}`); console.error(` Error: ${error.message}\n`); failCount++; } } console.log('═'.repeat(60)); console.log('📈 Generation Summary:'); console.log(` ✅ Successful: ${successCount}/${samples.length}`); console.log(` ❌ Failed: ${failCount}/${samples.length}`); console.log(` 📁 Output: ${outputDir}`); console.log('═'.repeat(60)); if (successCount > 0) { console.log('\n🎉 SVG files generated successfully!'); console.log('📂 Check the examples/architectures/ folder'); } } main().catch(console.error);

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/Narasimhaponnada/mcp-mermiad'

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