UNPKG

ixp-server

Version:

A comprehensive SDK for building Intent Exchange Protocol (IXP) servers with ease

488 lines 24.2 kB
/** * Built-in Plugins for IXP Server */ /** * Swagger Documentation Plugin * Automatically generates OpenAPI/Swagger documentation for IXP endpoints */ export function createSwaggerPlugin(options) { const { title = 'IXP Server API', version = '1.0.0', description = 'Intent Exchange Protocol Server API Documentation', endpoint = '/api-docs.json', uiEndpoint = '/api-docs' } = options; return { name: 'swagger-docs', version: '1.0.0', install: async (server) => { // Generate OpenAPI specification const generateSpec = () => { const intents = server.intentRegistry.getAll(); const components = server.componentRegistry.getAll(); const spec = { openapi: '3.0.0', info: { title, version, description }, servers: [ { url: `http://localhost:${server.config.port || 3001}/ixp`, description: 'Development server' } ], paths: { '/intents': { get: { summary: 'Get all available intents', description: 'Returns a list of all intents supported by this server', responses: { '200': { description: 'List of intents', content: { 'application/json': { schema: { type: 'object', properties: { intents: { type: 'array', items: { $ref: '#/components/schemas/Intent' } }, version: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' } } } } } } } } }, '/components': { get: { summary: 'Get all available components', description: 'Returns a list of all components registered with this server', responses: { '200': { description: 'List of components', content: { 'application/json': { schema: { type: 'object', properties: { components: { type: 'array', items: { $ref: '#/components/schemas/Component' } }, version: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' } } } } } } } } }, '/render': { post: { summary: 'Render component for intent', description: 'Resolves an intent request to a component descriptor', requestBody: { required: true, content: { 'application/json': { schema: { type: 'object', properties: { intent: { type: 'object', properties: { name: { type: 'string' }, parameters: { type: 'object' } }, required: ['name'] }, options: { type: 'object' } }, required: ['intent'] } } } }, responses: { '200': { description: 'Component descriptor', content: { 'application/json': { schema: { $ref: '#/components/schemas/IntentResponse' } } } }, '400': { description: 'Invalid request', content: { 'application/json': { schema: { $ref: '#/components/schemas/Error' } } } }, '404': { description: 'Intent or component not found', content: { 'application/json': { schema: { $ref: '#/components/schemas/Error' } } } } } } }, '/crawler_content': { get: { summary: 'Get crawlable content', description: 'Returns public content for search engine indexing', parameters: [ { name: 'cursor', in: 'query', description: 'Pagination cursor', schema: { type: 'string' } }, { name: 'limit', in: 'query', description: 'Maximum number of items to return', schema: { type: 'integer', minimum: 1, maximum: 1000, default: 100 } } ], responses: { '200': { description: 'Crawlable content', content: { 'application/json': { schema: { $ref: '#/components/schemas/CrawlerContent' } } } } } } }, '/health': { get: { summary: 'Health check', description: 'Returns server health status', responses: { '200': { description: 'Server is healthy', content: { 'application/json': { schema: { $ref: '#/components/schemas/HealthCheck' } } } }, '503': { description: 'Server is unhealthy', content: { 'application/json': { schema: { $ref: '#/components/schemas/HealthCheck' } } } } } } } }, components: { schemas: { Intent: { type: 'object', properties: { name: { type: 'string' }, description: { type: 'string' }, parameters: { type: 'object' }, component: { type: 'string' }, version: { type: 'string' }, deprecated: { type: 'boolean' }, crawlable: { type: 'boolean' } } }, Component: { type: 'object', properties: { name: { type: 'string' }, framework: { type: 'string' }, remoteUrl: { type: 'string' }, exportName: { type: 'string' }, propsSchema: { type: 'object' }, version: { type: 'string' }, deprecated: { type: 'boolean' }, allowedOrigins: { type: 'array', items: { type: 'string' } }, bundleSize: { type: 'string' }, performance: { type: 'object' }, securityPolicy: { type: 'object' } } }, IntentResponse: { type: 'object', properties: { record: { type: 'object', properties: { moduleUrl: { type: 'string' }, exportName: { type: 'string' }, props: { type: 'object' } } }, component: { $ref: '#/components/schemas/Component' }, ttl: { type: 'number' } } }, CrawlerContent: { type: 'object', properties: { contents: { type: 'array', items: { type: 'object', properties: { type: { type: 'string' }, id: { type: 'string' }, title: { type: 'string' }, description: { type: 'string' }, lastUpdated: { type: 'string', format: 'date-time' } } } }, pagination: { type: 'object', properties: { nextCursor: { type: 'string', nullable: true }, hasMore: { type: 'boolean' } } }, lastUpdated: { type: 'string', format: 'date-time' } } }, HealthCheck: { type: 'object', properties: { status: { type: 'string', enum: ['healthy', 'unhealthy', 'degraded'] }, service: { type: 'string' }, version: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' }, uptime: { type: 'number' }, checks: { type: 'object' } } }, Error: { type: 'object', properties: { error: { type: 'object', properties: { code: { type: 'string' }, message: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' }, details: { type: 'object' } } } } } } } }; return spec; }; // Add API documentation endpoint server.app.get(endpoint, (req, res) => { try { const spec = generateSpec(); res.setHeader('Content-Type', 'application/json'); res.json(spec); } catch (error) { console.error('Error generating OpenAPI spec:', error); res.status(500).json({ error: 'Failed to generate API documentation' }); } }); // Add Swagger UI endpoint server.app.get(uiEndpoint, (req, res) => { const html = ` <!DOCTYPE html> <html> <head> <title>${title}</title> <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@4.15.5/swagger-ui.css" /> <style> html { box-sizing: border-box; overflow: -moz-scrollbars-vertical; overflow-y: scroll; } *, *:before, *:after { box-sizing: inherit; } body { margin:0; background: #fafafa; } </style> </head> <body> <div id="swagger-ui"></div> <script src="https://unpkg.com/swagger-ui-dist@4.15.5/swagger-ui-bundle.js"></script> <script src="https://unpkg.com/swagger-ui-dist@4.15.5/swagger-ui-standalone-preset.js"></script> <script> window.onload = function() { SwaggerUIBundle({ url: '/ixp${endpoint}', dom_id: '#swagger-ui', deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl ], layout: "StandaloneLayout" }); }; </script> </body> </html> `; res.send(html); }); console.log(`📚 Swagger documentation available at ${uiEndpoint}`); } }; } /** * Health Monitoring Plugin * Provides detailed health checks and monitoring capabilities */ export function createHealthMonitoringPlugin(options) { const { endpoint = '/health/detailed', checks = {} } = options; return { name: 'health-monitoring', version: '1.0.0', install: async (server) => { // Add detailed health check endpoint server.app.get(endpoint, async (req, res) => { const results = {}; // Run custom checks for (const [name, checkFn] of Object.entries(checks)) { try { const start = Date.now(); const result = await checkFn(); results[name] = { ...result, duration: result.duration || (Date.now() - start) }; } catch (error) { results[name] = { status: 'fail', message: error instanceof Error ? error.message : 'Check failed', duration: Date.now() - Date.now() }; } } // Add default system checks results.memory = { status: 'pass', message: `Memory usage: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB`, duration: 0 }; results.uptime = { status: 'pass', message: `Uptime: ${Math.floor(process.uptime())}s`, duration: 0 }; // Determine overall status const hasFailures = Object.values(results).some((check) => check.status === 'fail'); const hasWarnings = Object.values(results).some((check) => check.status === 'warn'); const overallStatus = hasFailures ? 'unhealthy' : hasWarnings ? 'degraded' : 'healthy'; const statusCode = overallStatus === 'healthy' ? 200 : overallStatus === 'degraded' ? 200 : 503; res.status(statusCode).json({ status: overallStatus, service: 'IXP Server', version: '1.0.0', timestamp: new Date().toISOString(), uptime: process.uptime(), checks: results }); }); console.log(`🏥 Health monitoring available at ${endpoint}`); } }; } /** * Metrics Collection Plugin * Provides detailed metrics collection and reporting */ export function createMetricsPlugin(options) { const { endpoint = '/metrics/detailed', format = 'json', includeSystemMetrics = true } = options; return { name: 'metrics-collection', version: '1.0.0', install: async (server) => { server.app.get(endpoint, (req, res) => { const metrics = {}; // Get basic metrics (this would be enhanced with actual metrics collection) metrics.requests = { total: 0, byIntent: {}, byStatus: {} }; metrics.performance = { averageResponseTime: 0, p95ResponseTime: 0, p99ResponseTime: 0 }; if (includeSystemMetrics) { const memUsage = process.memoryUsage(); metrics.system = { memory: { heapUsed: memUsage.heapUsed, heapTotal: memUsage.heapTotal, external: memUsage.external, rss: memUsage.rss }, uptime: process.uptime(), cpuUsage: process.cpuUsage() }; } metrics.intents = server.intentRegistry.getStats(); metrics.components = server.componentRegistry.getStats(); if (format === 'prometheus') { // Convert to Prometheus format const lines = []; lines.push('# HELP ixp_intents_total Total number of intents'); lines.push('# TYPE ixp_intents_total gauge'); lines.push(`ixp_intents_total ${metrics.intents.total}`); lines.push('# HELP ixp_components_total Total number of components'); lines.push('# TYPE ixp_components_total gauge'); lines.push(`ixp_components_total ${metrics.components.total}`); if (includeSystemMetrics) { lines.push('# HELP ixp_memory_heap_used_bytes Memory heap used in bytes'); lines.push('# TYPE ixp_memory_heap_used_bytes gauge'); lines.push(`ixp_memory_heap_used_bytes ${metrics.system.memory.heapUsed}`); lines.push('# HELP ixp_uptime_seconds Server uptime in seconds'); lines.push('# TYPE ixp_uptime_seconds gauge'); lines.push(`ixp_uptime_seconds ${metrics.system.uptime}`); } res.set('Content-Type', 'text/plain'); res.send(lines.join('\n')); } else { res.json({ ...metrics, timestamp: new Date().toISOString() }); } }); console.log(`📊 Detailed metrics available at ${endpoint}`); } }; } // Export plugin factory functions export const PluginFactory = { swagger: createSwaggerPlugin, healthMonitoring: createHealthMonitoringPlugin, metrics: createMetricsPlugin }; //# sourceMappingURL=index.js.map