Skip to main content
Glama
NextJSIntegrationToolInterface.ts11.3 kB
import express from 'express'; import NextJSIntegrationTool from './NextJSIntegrationTool.js'; import fs from 'fs'; import path from 'path'; /** * Interface pour l'outil d'intégration NextJS * Expose les fonctionnalités de l'outil via une API REST */ export class NextJSIntegrationToolInterface { private tool: NextJSIntegrationTool; private outputBaseDir: string; constructor() { this.tool = new NextJSIntegrationTool(); this.outputBaseDir = process.env.NEXTJS_OUTPUT_DIR || path.join(process.cwd(), 'output', 'nextjs-integrations'); // Créer le répertoire de sortie s'il n'existe pas if (!fs.existsSync(this.outputBaseDir)) { fs.mkdirSync(this.outputBaseDir, { recursive: true }); } } /** * Enregistre les routes de l'API pour l'outil * @param app Application Express */ registerRoutes(app: express.Application): void { // Route pour générer une intégration NextJS app.post('/api/nextjs-integration/generate', async (req: express.Request, res: express.Response) => { try { const { workflowId, workflowName, apiBasePath = '/api', generateOpenAPI = true, generateTypes = true, includeWebhooks = true } = req.body; // Valider les paramètres requis if (!workflowId) { return res.status(400).json({ success: false, message: 'Le paramètre workflowId est requis' }); } if (!workflowName) { return res.status(400).json({ success: false, message: 'Le paramètre workflowName est requis' }); } // Créer le répertoire de sortie spécifique au workflow const outputDir = path.join(this.outputBaseDir, this.slugify(workflowName)); // Exécuter l'outil const result = await this.tool.execute({ workflowId, workflowName, apiBasePath, outputDir, generateOpenAPI, generateTypes, includeWebhooks }); // Retourner le résultat return res.json(result); } catch (error: unknown) { console.error('Erreur lors de la génération de l\'intégration NextJS:', error); const errorMessage = error instanceof Error ? error.message : String(error); return res.status(500).json({ success: false, message: `Erreur: ${errorMessage}` }); } }); // Route pour lister les intégrations NextJS générées app.get('/api/nextjs-integration/list', (req: express.Request, res: express.Response) => { try { // Lire le contenu du répertoire de sortie const integrations = fs.readdirSync(this.outputBaseDir) .filter(item => fs.statSync(path.join(this.outputBaseDir, item)).isDirectory()) .map(dir => { const integrationPath = path.join(this.outputBaseDir, dir); // Vérifier si l'intégration contient une spécification OpenAPI const hasOpenAPI = fs.existsSync(path.join(integrationPath, 'openapi.json')); // Vérifier si l'intégration contient des types TypeScript const hasTypes = fs.existsSync(path.join(integrationPath, 'types.ts')); // Vérifier si l'intégration contient un client API const hasApiClient = fs.existsSync(path.join(integrationPath, 'api-client.ts')); // Vérifier si l'intégration contient des routes API const hasApiRoutes = fs.existsSync(path.join(integrationPath, 'api')); return { name: dir, path: integrationPath, features: { openapi: hasOpenAPI, types: hasTypes, apiClient: hasApiClient, apiRoutes: hasApiRoutes }, createdAt: fs.statSync(integrationPath).birthtime }; }) .sort((a: any, b: any) => b.createdAt.getTime() - a.createdAt.getTime()); return res.json({ success: true, integrations }); } catch (error: unknown) { console.error('Erreur lors de la liste des intégrations NextJS:', error); const errorMessage = error instanceof Error ? error.message : String(error); return res.status(500).json({ success: false, message: `Erreur: ${errorMessage}` }); } }); // Route pour télécharger une intégration NextJS app.get('/api/nextjs-integration/download/:name', (req: express.Request, res: express.Response) => { try { const { name } = req.params; const integrationPath = path.join(this.outputBaseDir, name); // Vérifier si l'intégration existe if (!fs.existsSync(integrationPath)) { return res.status(404).json({ success: false, message: `L'intégration ${name} n'existe pas` }); } // Créer une archive ZIP de l'intégration const archiver = require('archiver'); const archive = archiver('zip', { zlib: { level: 9 } }); // Configurer la réponse HTTP res.attachment(`${name}.zip`); archive.pipe(res); // Ajouter les fichiers à l'archive archive.directory(integrationPath, name); // Finaliser l'archive archive.finalize(); // Retourner explicitement undefined pour satisfaire TypeScript return; } catch (error: unknown) { console.error('Erreur lors du téléchargement de l\'intégration NextJS:', error); const errorMessage = error instanceof Error ? error.message : String(error); return res.status(500).json({ success: false, message: `Erreur: ${errorMessage}` }); } }); // Route pour supprimer une intégration NextJS app.delete('/api/nextjs-integration/:name', (req: express.Request, res: express.Response) => { try { const { name } = req.params; const integrationPath = path.join(this.outputBaseDir, name); // Vérifier si l'intégration existe if (!fs.existsSync(integrationPath)) { return res.status(404).json({ success: false, message: `L'intégration ${name} n'existe pas` }); } // Supprimer le répertoire de l'intégration fs.rmSync(integrationPath, { recursive: true, force: true }); return res.json({ success: true, message: `L'intégration ${name} a été supprimée avec succès` }); } catch (error: unknown) { console.error('Erreur lors de la suppression de l\'intégration NextJS:', error); const errorMessage = error instanceof Error ? error.message : String(error); return res.status(500).json({ success: false, message: `Erreur: ${errorMessage}` }); } }); // Route pour accéder à la documentation OpenAPI d'une intégration app.get('/api/nextjs-integration/:name/openapi', (req: express.Request, res: express.Response) => { try { const { name } = req.params; const openApiPath = path.join(this.outputBaseDir, name, 'openapi.json'); // Vérifier si la spécification OpenAPI existe if (!fs.existsSync(openApiPath)) { return res.status(404).json({ success: false, message: `La spécification OpenAPI pour l'intégration ${name} n'existe pas` }); } // Lire la spécification OpenAPI const openApiSpec = JSON.parse(fs.readFileSync(openApiPath, 'utf8')); return res.json(openApiSpec); } catch (error: unknown) { console.error('Erreur lors de l\'accès à la spécification OpenAPI:', error); const errorMessage = error instanceof Error ? error.message : String(error); return res.status(500).json({ success: false, message: `Erreur: ${errorMessage}` }); } }); // Route pour la documentation Swagger UI app.get('/api/nextjs-integration/:name/swagger', (req: express.Request, res: express.Response) => { try { const { name } = req.params; const openApiPath = path.join(this.outputBaseDir, name, 'openapi.json'); // Vérifier si la spécification OpenAPI existe if (!fs.existsSync(openApiPath)) { return res.status(404).send(`<html> <body> <h1>Erreur 404</h1> <p>La spécification OpenAPI pour l'intégration ${name} n'existe pas</p> </body> </html>`); } // Générer la page Swagger UI const swaggerHtml = ` <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>API ${name} - Documentation Swagger</title> <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@4.5.0/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.5.0/swagger-ui-bundle.js"></script> <script src="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-standalone-preset.js"></script> <script> window.onload = function() { const ui = SwaggerUIBundle({ url: "/api/nextjs-integration/${name}/openapi", dom_id: '#swagger-ui', deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl ], layout: "BaseLayout" }); window.ui = ui; }; </script> </body> </html> `; return res.send(swaggerHtml); } catch (error: unknown) { console.error('Erreur lors de l\'accès à Swagger UI:', error); const errorMessage = error instanceof Error ? error.message : String(error); return res.status(500).send(`<html> <body> <h1>Erreur 500</h1> <p>Erreur lors de l'accès à Swagger UI: ${errorMessage}</p> </body> </html>`); } }); } /** * Convertit une chaîne en format slug * @param text Chaîne à convertir * @returns Chaîne en format slug */ private slugify(text: string): string { return text .toString() .toLowerCase() .replace(/\s+/g, '-') .replace(/[^\w\-]+/g, '') .replace(/\-\-+/g, '-') .replace(/^-+/, '') .replace(/-+$/, ''); } }

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/lowprofix/n8n-mcp-server'

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