UNPKG

embedia

Version:

Zero-configuration AI chatbot integration CLI - direct file copy with embedded API keys

163 lines (124 loc) 4.55 kB
const fs = require('fs-extra'); const path = require('path'); const SafeASTModifier = require('../ast/safeModifier'); class BaseAdapter { constructor(projectPath, framework, projectAnalysis) { this.projectPath = projectPath; this.framework = framework; this.projectAnalysis = projectAnalysis; this.safeModifier = new SafeASTModifier(); } // Abstract method - must be implemented by subclasses async integrate(embediaFiles) { throw new Error('integrate() method must be implemented by subclass'); } // Common helper methods async createFile(relativePath, content) { const fullPath = path.join(this.projectPath, relativePath); await fs.ensureDir(path.dirname(fullPath)); await fs.writeFile(fullPath, content); return relativePath; } async findFile(possiblePaths) { for (const filePath of possiblePaths) { const fullPath = path.join(this.projectPath, filePath); if (await fs.pathExists(fullPath)) { return filePath; } } return null; } async modifyFile(filePath, modifier) { const fullPath = path.join(this.projectPath, filePath); return await this.safeModifier.modifyWithRollback(fullPath, modifier); } async fileExists(relativePath) { return await fs.pathExists(path.join(this.projectPath, relativePath)); } async readFile(relativePath) { return await fs.readFile(path.join(this.projectPath, relativePath), 'utf-8'); } async createComponentFiles(embediaFiles) { const componentDir = path.join(this.projectPath, 'components/generated/embedia-chat'); await fs.ensureDir(componentDir); // Create all component files const files = [ { path: 'index.js', content: embediaFiles.component }, { path: 'config.json', content: JSON.stringify(embediaFiles.config, null, 2) }, { path: 'index.d.ts', content: embediaFiles.types }, { path: 'README.md', content: embediaFiles.readme || this.generateReadme(embediaFiles.config) } ]; // Create API directory const apiDir = path.join(componentDir, 'api/chat'); await fs.ensureDir(apiDir); // Add API route files.push({ path: 'api/chat/route.js', content: embediaFiles.apiRoute }); // Write all files for (const file of files) { await fs.writeFile( path.join(componentDir, file.path), file.content ); } return 'components/generated/embedia-chat'; } generateReadme(config) { return `# Embedia Chat Component This is a pre-compiled, isolated chat component generated by Embedia CLI. ## Configuration Edit \`config.json\` to customize the chat widget: - **chatbotName**: Display name of your chatbot - **themeColors**: Color scheme customization - **position**: Widget position on screen - **systemPrompt**: AI behavior configuration ## Integration This component works with simple script inclusion. ## API Endpoint The chat API handler is located at \`api/chat/route.js\`. Configure your environment variables for AI provider access. ## Support For help, visit: https://docs.embedia.ai `; } getIntegrationInstructions(frameworkName) { return ` # Embedia Chat Integration - ${frameworkName} The Embedia Chat component has been successfully installed! ## Next Steps 1. **Set up your API key**: Add to \`.env.local\`: \`\`\` GEMINI_API_KEY=your_api_key_here \`\`\` 2. **Start your development server** and look for the chat widget 3. **Customize**: Edit \`components/generated/embedia-chat/config.json\` ## Troubleshooting If the chat doesn't appear: - Check the browser console for errors - Verify the integration in your layout file - Ensure API routes are properly configured Need help? Run \`npx embedia doctor\` for diagnostics. `; } // Helper for manual integration instructions getManualIntegrationInstructions() { return `To manually integrate Embedia Chat, add this to your layout or root component: 1. Import and render the component: import EmbediaChat from '/components/generated/embedia-chat'; 2. Add it to your JSX: <EmbediaChat />`; } // Check if we're in a TypeScript project async isTypeScriptProject() { return await this.fileExists('tsconfig.json'); } // Get the appropriate file extension async getFileExtension(isComponent = true) { const isTS = await this.isTypeScriptProject(); if (!isTS) return isComponent ? '.jsx' : '.js'; return isComponent ? '.tsx' : '.ts'; } } module.exports = BaseAdapter;