UNPKG

@catalystlabs/awm

Version:

Appwrite Migration Tool - Schema management and code generation for Appwrite databases

194 lines (167 loc) 6.42 kB
#!/usr/bin/env node import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; import { execSync } from 'child_process'; import os from 'os'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const colors = { reset: '\x1b[0m', bright: '\x1b[1m', dim: '\x1b[2m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', cyan: '\x1b[36m' }; async function checkAppwriteCLI() { try { execSync('appwrite --version', { stdio: 'pipe' }); return true; } catch { return false; } } async function checkAppwriteProject() { try { // Check if appwrite.config.json exists (created by appwrite init project) await fs.access(path.join(process.cwd(), 'appwrite.config.json')); return true; } catch { return false; } } async function getAppwriteConfig() { try { const configPath = path.join(os.homedir(), '.appwrite', 'prefs.json'); const configContent = await fs.readFile(configPath, 'utf-8'); const config = JSON.parse(configContent); return { endpoint: config.endpoint || 'http://localhost/v1', projectId: config.projectId || null }; } catch { return null; } } export async function initProject() { console.log(`\n${colors.cyan}🚀 Initializing AWM in your project...${colors.reset}\n`); // Check for Appwrite CLI const hasAppwriteCLI = await checkAppwriteCLI(); if (!hasAppwriteCLI) { console.log(`${colors.yellow}⚠️ Appwrite CLI not found${colors.reset}`); console.log(`${colors.dim} Install it with: npm install -g appwrite-cli${colors.reset}\n`); } else { console.log(`${colors.green}${colors.reset} Appwrite CLI detected\n`); } // Check for Appwrite project initialization const hasAppwriteProject = await checkAppwriteProject(); if (!hasAppwriteProject && hasAppwriteCLI) { console.log(`${colors.yellow}⚠️ No Appwrite project found${colors.reset}`); console.log(`${colors.dim} Initialize with: appwrite init project${colors.reset}\n`); } else if (hasAppwriteProject) { console.log(`${colors.green}${colors.reset} Appwrite project initialized\n`); } // Get Appwrite config if available const appwriteConfig = await getAppwriteConfig(); let defaultConfig = { projectId: "your-project-id", endpoint: "http://localhost/v1", databaseId: "your-database", schemaPath: "schema/appwrite.schema" }; if (appwriteConfig) { console.log(`${colors.green}${colors.reset} Found Appwrite CLI configuration\n`); defaultConfig.endpoint = appwriteConfig.endpoint; if (appwriteConfig.projectId) { defaultConfig.projectId = appwriteConfig.projectId; } } // Create schema directory if it doesn't exist const schemaDir = path.join(process.cwd(), 'schema'); try { await fs.access(schemaDir); console.log(`${colors.green}${colors.reset} Schema directory exists\n`); } catch { await fs.mkdir(schemaDir, { recursive: true }); console.log(`${colors.green}${colors.reset} Created schema directory\n`); } // Create types directory if it doesn't exist const typesDir = path.join(process.cwd(), 'types'); try { await fs.access(typesDir); console.log(`${colors.green}${colors.reset} Types directory exists\n`); } catch { await fs.mkdir(typesDir, { recursive: true }); console.log(`${colors.green}${colors.reset} Created types directory\n`); } const files = { '.env.example': await fs.readFile(path.join(__dirname, '.env.example'), 'utf-8'), 'schema/appwrite.schema': await fs.readFile(path.join(__dirname, 'appwrite.schema.example'), 'utf-8'), '.awm.json': JSON.stringify(defaultConfig, null, 2) }; const created = []; const skipped = []; for (const [filename, content] of Object.entries(files)) { const targetPath = path.join(process.cwd(), filename); try { // Check if file exists await fs.access(targetPath); skipped.push(filename); } catch { // Ensure parent directory exists const parentDir = path.dirname(targetPath); await fs.mkdir(parentDir, { recursive: true }); // File doesn't exist, create it await fs.writeFile(targetPath, content); created.push(filename); } } // Add .awm-state.db to .gitignore try { const gitignorePath = path.join(process.cwd(), '.gitignore'); let gitignore = ''; try { gitignore = await fs.readFile(gitignorePath, 'utf-8'); } catch { // .gitignore doesn't exist } if (!gitignore.includes('.awm-state.db')) { gitignore += '\n# AWM state database\n.awm-state.db\n.awm-state.db-journal\n'; await fs.writeFile(gitignorePath, gitignore); created.push('.gitignore (updated)'); } } catch (error) { console.warn(`${colors.yellow}Warning: Could not update .gitignore${colors.reset}`); } // Print results if (created.length > 0) { console.log(`${colors.green}✅ Created files:${colors.reset}`); created.forEach(file => console.log(` - ${file}`)); } if (skipped.length > 0) { console.log(`\n${colors.yellow}⏭️ Skipped existing files:${colors.reset}`); skipped.forEach(file => console.log(` - ${file}`)); } console.log(` ${colors.bright}Next steps:${colors.reset}`); if (!hasAppwriteCLI) { console.log(`1. ${colors.cyan}Install Appwrite CLI:${colors.reset} npm install -g appwrite-cli`); } if (!hasAppwriteProject && hasAppwriteCLI) { console.log(`2. ${colors.cyan}Initialize Appwrite project:${colors.reset} appwrite init project`); } console.log(`3. Edit ${colors.cyan}.env.example${colors.reset} with your Appwrite credentials`); console.log(`4. Rename it to ${colors.cyan}.env${colors.reset}`); console.log(`5. Customize ${colors.cyan}schema/appwrite.schema${colors.reset} for your database`); console.log(`6. Run ${colors.cyan}awm plan${colors.reset} to preview changes`); console.log(`7. Run ${colors.cyan}awm apply${colors.reset} to create collections`); console.log(`8. Run ${colors.cyan}awm relationships${colors.reset} to add relationships`); console.log(`9. Run ${colors.cyan}awm generate${colors.reset} to create TypeScript types`); console.log(` ${colors.dim}For more information, see the README or run 'awm --help'${colors.reset} `); } // Export for use as module export default initProject;