@tamyla/clodo-framework 3.1.22 → 3.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +230 -1
  3. package/dist/cli/commands/assess.js +192 -0
  4. package/dist/cli/commands/create.js +77 -0
  5. package/dist/{bin → cli}/commands/deploy.js +36 -14
  6. package/dist/cli/commands/diagnose.js +83 -0
  7. package/dist/{bin → cli}/commands/helpers/deployment-verification.js +2 -3
  8. package/dist/{bin → cli}/commands/helpers/error-recovery.js +1 -1
  9. package/dist/{bin → cli}/commands/helpers/resource-detection.js +1 -1
  10. package/dist/cli/commands/helpers.js +110 -0
  11. package/dist/cli/commands/init-config.js +57 -0
  12. package/dist/cli/commands/update.js +102 -0
  13. package/dist/cli/commands/validate.js +65 -0
  14. package/dist/cli/security-cli.js +118 -0
  15. package/dist/config/FeatureManager.js +6 -0
  16. package/dist/config/clodo-create.example.json +26 -0
  17. package/dist/config/clodo-deploy.example.json +41 -0
  18. package/dist/config/clodo-update.example.json +46 -0
  19. package/dist/config/clodo-validate.example.json +41 -0
  20. package/dist/config/customers/template/development.env.template +37 -0
  21. package/dist/config/customers/template/production.env.template +39 -0
  22. package/dist/config/customers/template/staging.env.template +37 -0
  23. package/dist/config/customers.js +625 -0
  24. package/dist/config/domain-examples/README.md +464 -0
  25. package/dist/config/domain-examples/environment-mapped.json +168 -0
  26. package/dist/config/domain-examples/multi-domain.json +144 -0
  27. package/dist/config/domain-examples/single-domain.json +50 -0
  28. package/dist/config/domains.js +186 -0
  29. package/dist/config/examples +12 -0
  30. package/dist/config/features.js +61 -0
  31. package/dist/config/index.js +6 -0
  32. package/dist/config/staging-deployment.json +60 -0
  33. package/dist/config/validation-config.json +347 -0
  34. package/dist/database/database-orchestrator.js +795 -0
  35. package/dist/database/index.js +4 -0
  36. package/dist/deployment/index.js +11 -0
  37. package/dist/deployment/orchestration/BaseDeploymentOrchestrator.js +426 -0
  38. package/dist/deployment/orchestration/PortfolioOrchestrator.js +273 -0
  39. package/dist/deployment/orchestration/SingleServiceOrchestrator.js +231 -0
  40. package/dist/deployment/orchestration/UnifiedDeploymentOrchestrator.js +662 -0
  41. package/dist/deployment/orchestration/index.js +17 -0
  42. package/dist/deployment/rollback-manager.js +36 -0
  43. package/dist/deployment/wrangler-deployer.js +640 -0
  44. package/dist/handlers/GenericRouteHandler.js +532 -0
  45. package/dist/lib/database/deployment-db-manager.js +423 -0
  46. package/dist/lib/database/wrangler-d1-manager.js +685 -0
  47. package/dist/lib/deployment/modules/DeploymentConfiguration.js +395 -0
  48. package/dist/lib/deployment/modules/DeploymentOrchestrator.js +492 -0
  49. package/dist/lib/deployment/modules/EnvironmentManager.js +517 -0
  50. package/dist/lib/deployment/modules/MonitoringIntegration.js +560 -0
  51. package/dist/lib/deployment/modules/ValidationManager.js +342 -0
  52. package/dist/lib/deployment/orchestration/BaseDeploymentOrchestrator.js +426 -0
  53. package/dist/lib/deployment/orchestration/EnterpriseOrchestrator.js +21 -0
  54. package/dist/lib/deployment/orchestration/PortfolioOrchestrator.js +273 -0
  55. package/dist/lib/deployment/orchestration/SingleServiceOrchestrator.js +231 -0
  56. package/dist/lib/deployment/orchestration/UnifiedDeploymentOrchestrator.js +662 -0
  57. package/dist/{bin → lib}/shared/cloudflare/domain-discovery.js +1 -1
  58. package/dist/{bin → lib}/shared/cloudflare/domain-manager.js +1 -1
  59. package/dist/{bin → lib}/shared/cloudflare/ops.js +4 -4
  60. package/dist/{bin → lib}/shared/config/command-config-manager.js +1 -1
  61. package/dist/{bin → lib}/shared/config/index.js +1 -1
  62. package/dist/{bin → lib}/shared/config/manifest-loader.js +3 -3
  63. package/dist/{bin → lib}/shared/deployment/credential-collector.js +1 -1
  64. package/dist/lib/shared/deployment/index.js +10 -0
  65. package/dist/{bin → lib}/shared/deployment/rollback-manager.js +1 -1
  66. package/dist/{bin → lib}/shared/deployment/utilities/d1-error-recovery.js +1 -1
  67. package/dist/{bin → lib}/shared/deployment/validator.js +1 -1
  68. package/dist/{bin → lib}/shared/deployment/workflows/interactive-database-workflow.js +1 -1
  69. package/dist/{bin → lib}/shared/monitoring/health-checker.js +2 -2
  70. package/dist/{bin → lib}/shared/routing/domain-router.js +1 -1
  71. package/dist/{bin → lib}/shared/utils/config-loader.js +47 -11
  72. package/dist/lib/shared/utils/service-config-manager.js +227 -0
  73. package/dist/{bin → lib}/shared/validation/ValidationRegistry.js +1 -1
  74. package/dist/migration/MigrationAdapters.js +608 -0
  75. package/dist/modules/ModuleManager.js +668 -0
  76. package/dist/modules/security.js +96 -0
  77. package/dist/orchestration/cross-domain-coordinator.js +1083 -0
  78. package/dist/orchestration/index.js +5 -0
  79. package/dist/orchestration/modules/DeploymentCoordinator.js +368 -0
  80. package/dist/orchestration/modules/DomainResolver.js +198 -0
  81. package/dist/orchestration/modules/StateManager.js +332 -0
  82. package/dist/orchestration/multi-domain-orchestrator.js +765 -0
  83. package/dist/routing/EnhancedRouter.js +158 -0
  84. package/dist/schema/SchemaManager.js +778 -0
  85. package/dist/security/index.js +2 -2
  86. package/dist/service-management/ConfirmationEngine.js +412 -0
  87. package/dist/service-management/ErrorTracker.js +299 -0
  88. package/dist/service-management/GenerationEngine.js +447 -0
  89. package/dist/service-management/InputCollector.js +619 -0
  90. package/dist/service-management/ServiceCreator.js +21 -0
  91. package/dist/service-management/ServiceOrchestrator.js +672 -0
  92. package/dist/service-management/generators/BaseGenerator.js +233 -0
  93. package/dist/service-management/generators/GeneratorRegistry.js +254 -0
  94. package/dist/service-management/generators/cicd/CiWorkflowGenerator.js +87 -0
  95. package/dist/service-management/generators/cicd/DeployWorkflowGenerator.js +106 -0
  96. package/dist/service-management/generators/code/ServiceHandlersGenerator.js +235 -0
  97. package/dist/service-management/generators/code/ServiceMiddlewareGenerator.js +116 -0
  98. package/dist/service-management/generators/code/ServiceUtilsGenerator.js +246 -0
  99. package/dist/service-management/generators/code/WorkerIndexGenerator.js +143 -0
  100. package/dist/service-management/generators/config/DevelopmentEnvGenerator.js +101 -0
  101. package/dist/service-management/generators/config/DomainsConfigGenerator.js +175 -0
  102. package/dist/service-management/generators/config/EnvExampleGenerator.js +178 -0
  103. package/dist/service-management/generators/config/ProductionEnvGenerator.js +97 -0
  104. package/dist/service-management/generators/config/StagingEnvGenerator.js +97 -0
  105. package/dist/service-management/generators/config/WranglerTomlGenerator.js +238 -0
  106. package/dist/service-management/generators/core/PackageJsonGenerator.js +243 -0
  107. package/dist/service-management/generators/core/SiteConfigGenerator.js +115 -0
  108. package/dist/service-management/generators/documentation/ApiDocsGenerator.js +331 -0
  109. package/dist/service-management/generators/documentation/ConfigurationDocsGenerator.js +294 -0
  110. package/dist/service-management/generators/documentation/DeploymentDocsGenerator.js +244 -0
  111. package/dist/service-management/generators/documentation/ReadmeGenerator.js +196 -0
  112. package/dist/service-management/generators/schemas/ServiceSchemaGenerator.js +190 -0
  113. package/dist/service-management/generators/scripts/DeployScriptGenerator.js +123 -0
  114. package/dist/service-management/generators/scripts/HealthCheckScriptGenerator.js +101 -0
  115. package/dist/service-management/generators/scripts/SetupScriptGenerator.js +88 -0
  116. package/dist/service-management/generators/service-types/StaticSiteGenerator.js +342 -0
  117. package/dist/service-management/generators/testing/EslintConfigGenerator.js +85 -0
  118. package/dist/service-management/generators/testing/IntegrationTestsGenerator.js +237 -0
  119. package/dist/service-management/generators/testing/JestConfigGenerator.js +72 -0
  120. package/dist/service-management/generators/testing/UnitTestsGenerator.js +277 -0
  121. package/dist/service-management/generators/tooling/DockerComposeGenerator.js +71 -0
  122. package/dist/service-management/generators/tooling/GitignoreGenerator.js +143 -0
  123. package/dist/service-management/generators/utils/FileWriter.js +179 -0
  124. package/dist/service-management/generators/utils/PathResolver.js +157 -0
  125. package/dist/service-management/generators/utils/ServiceManifestGenerator.js +111 -0
  126. package/dist/service-management/generators/utils/TemplateEngine.js +185 -0
  127. package/dist/service-management/generators/utils/index.js +18 -0
  128. package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
  129. package/dist/service-management/handlers/GenerationHandler.js +80 -0
  130. package/dist/service-management/handlers/InputHandler.js +59 -0
  131. package/dist/service-management/handlers/ValidationHandler.js +216 -0
  132. package/dist/service-management/index.js +14 -0
  133. package/dist/service-management/routing/DomainRouteMapper.js +311 -0
  134. package/dist/service-management/routing/RouteGenerator.js +266 -0
  135. package/dist/service-management/routing/WranglerRoutesBuilder.js +273 -0
  136. package/dist/service-management/routing/index.js +14 -0
  137. package/dist/service-management/services/DirectoryStructureService.js +56 -0
  138. package/dist/service-management/services/GenerationCoordinator.js +208 -0
  139. package/dist/service-management/services/GeneratorRegistry.js +174 -0
  140. package/dist/services/GenericDataService.js +501 -0
  141. package/dist/ui-structures/concepts/second-order-acquisition-strategy.md +286 -0
  142. package/dist/ui-structures/concepts/service-lifecycle-management.md +150 -0
  143. package/dist/ui-structures/concepts/service-manifest-guide.md +309 -0
  144. package/dist/ui-structures/concepts/three-tier-categorization-strategy.md +231 -0
  145. package/dist/ui-structures/creation/automated-generation-ui.json +246 -0
  146. package/dist/ui-structures/creation/core-inputs-ui.json +217 -0
  147. package/dist/ui-structures/creation/smart-confirmable-ui.json +451 -0
  148. package/dist/ui-structures/reference/absolutely-required-inputs.json +315 -0
  149. package/dist/ui-structures/reference/service-manifest-template.json +342 -0
  150. package/dist/utils/cloudflare/ops.js +1 -1
  151. package/dist/utils/file-manager.js +1 -1
  152. package/dist/utils/formatters.js +1 -1
  153. package/dist/utils/logger.js +1 -1
  154. package/dist/version/VersionDetector.js +813 -0
  155. package/dist/worker/index.js +4 -0
  156. package/dist/worker/integration.js +351 -0
  157. package/package.json +7 -15
  158. package/dist/bin/commands/validate.js +0 -51
  159. package/dist/bin/security/security-cli.js +0 -108
  160. package/dist/bin/shared/deployment/index.js +0 -10
  161. /package/dist/{bin → cli}/clodo-service.js +0 -0
  162. /package/dist/{bin → cli}/commands/helpers/deployment-ui.js +0 -0
  163. /package/dist/{bin → lib}/shared/cache/configuration-cache.js +0 -0
  164. /package/dist/{bin → lib}/shared/cloudflare/index.js +0 -0
  165. /package/dist/{bin → lib}/shared/config/ConfigurationManager.js +0 -0
  166. /package/dist/{bin → lib}/shared/config/cache.js +0 -0
  167. /package/dist/{bin → lib}/shared/config/cloudflare-service-validator.js +0 -0
  168. /package/dist/{bin → lib}/shared/config/manager.js +0 -0
  169. /package/dist/{bin → lib}/shared/database/connection-manager.js +0 -0
  170. /package/dist/{bin → lib}/shared/database/index.js +0 -0
  171. /package/dist/{bin → lib}/shared/database/orchestrator.js +0 -0
  172. /package/dist/{bin → lib}/shared/deployment/auditor.js +0 -0
  173. /package/dist/{bin → lib}/shared/deployment/workflows/deployment-summary.js +0 -0
  174. /package/dist/{bin → lib}/shared/deployment/workflows/interactive-confirmation.js +0 -0
  175. /package/dist/{bin → lib}/shared/deployment/workflows/interactive-domain-info-gatherer.js +0 -0
  176. /package/dist/{bin → lib}/shared/deployment/workflows/interactive-secret-workflow.js +0 -0
  177. /package/dist/{bin → lib}/shared/deployment/workflows/interactive-testing-workflow.js +0 -0
  178. /package/dist/{bin → lib}/shared/deployment/workflows/interactive-validation.js +0 -0
  179. /package/dist/{bin → lib}/shared/error-handling/error-classifier.js +0 -0
  180. /package/dist/{bin → lib}/shared/index.js +0 -0
  181. /package/dist/{bin → lib}/shared/logging/Logger.js +0 -0
  182. /package/dist/{bin → lib}/shared/monitoring/index.js +0 -0
  183. /package/dist/{bin → lib}/shared/monitoring/memory-manager.js +0 -0
  184. /package/dist/{bin → lib}/shared/monitoring/production-monitor.js +0 -0
  185. /package/dist/{bin → lib}/shared/production-tester/api-tester.js +0 -0
  186. /package/dist/{bin → lib}/shared/production-tester/auth-tester.js +0 -0
  187. /package/dist/{bin → lib}/shared/production-tester/core.js +0 -0
  188. /package/dist/{bin → lib}/shared/production-tester/database-tester.js +0 -0
  189. /package/dist/{bin → lib}/shared/production-tester/index.js +0 -0
  190. /package/dist/{bin → lib}/shared/production-tester/load-tester.js +0 -0
  191. /package/dist/{bin → lib}/shared/production-tester/performance-tester.js +0 -0
  192. /package/dist/{bin → lib}/shared/security/api-token-manager.js +0 -0
  193. /package/dist/{bin → lib}/shared/security/index.js +0 -0
  194. /package/dist/{bin → lib}/shared/security/secret-generator.js +0 -0
  195. /package/dist/{bin → lib}/shared/security/secure-token-manager.js +0 -0
  196. /package/dist/{bin → lib}/shared/utils/ErrorHandler.js +0 -0
  197. /package/dist/{bin → lib}/shared/utils/cli-options.js +0 -0
  198. /package/dist/{bin → lib}/shared/utils/deployment-validator.js +0 -0
  199. /package/dist/{bin → lib}/shared/utils/error-recovery.js +0 -0
  200. /package/dist/{bin → lib}/shared/utils/file-manager.js +0 -0
  201. /package/dist/{bin → lib}/shared/utils/formatters.js +0 -0
  202. /package/dist/{bin → lib}/shared/utils/graceful-shutdown-manager.js +0 -0
  203. /package/dist/{bin → lib}/shared/utils/index.js +0 -0
  204. /package/dist/{bin → lib}/shared/utils/interactive-prompts.js +0 -0
  205. /package/dist/{bin → lib}/shared/utils/interactive-utils.js +0 -0
  206. /package/dist/{bin → lib}/shared/utils/output-formatter.js +0 -0
  207. /package/dist/{bin → lib}/shared/utils/progress-manager.js +0 -0
  208. /package/dist/{bin → lib}/shared/utils/progress-spinner.js +0 -0
  209. /package/dist/{bin → lib}/shared/utils/rate-limiter.js +0 -0
  210. /package/dist/{bin → lib}/shared/utils/sensitive-redactor.js +0 -0
@@ -0,0 +1,492 @@
1
+ /**
2
+ * Deployment Orchestrator Module
3
+ * Manages the main deployment flow, coordinates between modules,
4
+ * handles rollbacks, and manages deployment state transitions
5
+ */
6
+
7
+ import { readFileSync, writeFileSync } from 'fs';
8
+ import { deploySecret, runMigrations, checkHealth } from '../../shared/cloudflare/ops.js';
9
+ import { WranglerDeployer } from '../deployment/wrangler-deployer.js';
10
+ import { DeploymentDatabaseManager } from '../database/deployment-db-manager.js';
11
+ import { DeploymentConfiguration } from './DeploymentConfiguration.js';
12
+
13
+ /**
14
+ * Orchestrates the complete deployment process including
15
+ * pre-deployment checks, actual deployment, and post-deployment validation
16
+ */
17
+ export class DeploymentOrchestrator {
18
+ constructor(options = {}) {
19
+ this.options = options;
20
+ this.state = {
21
+ deploymentId: this.generateDeploymentId(),
22
+ startTime: new Date(),
23
+ currentPhase: 'initialization',
24
+ rollbackActions: [],
25
+ deploymentResults: {},
26
+ errors: []
27
+ };
28
+
29
+ // Initialize modular components
30
+ this.configManager = new DeploymentConfiguration(options);
31
+ this.databaseManager = new DeploymentDatabaseManager(options);
32
+ this.wranglerDeployer = new WranglerDeployer({
33
+ cwd: process.cwd(),
34
+ environment: options.environment || 'production'
35
+ });
36
+ }
37
+
38
+ /**
39
+ * Generate unique deployment ID
40
+ */
41
+ generateDeploymentId() {
42
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
43
+ const random = Math.random().toString(36).substr(2, 9);
44
+ return `deploy-${timestamp}-${random}`;
45
+ }
46
+
47
+ /**
48
+ * Handle database setup and configuration using DeploymentDatabaseManager
49
+ */
50
+ async handleDatabaseSetup(config) {
51
+ console.log('\n🗄️ Database Setup and Configuration');
52
+ console.log('===================================');
53
+ try {
54
+ const databaseConfig = await this.databaseManager.handleDatabase(config);
55
+
56
+ // Update config with database information
57
+ config.database = {
58
+ ...config.database,
59
+ ...databaseConfig
60
+ };
61
+ console.log(' ✅ Database setup completed');
62
+ return config.database;
63
+ } catch (error) {
64
+ console.log(` ❌ Database setup failed: ${error.message}`);
65
+ throw new Error(`Database setup failed: ${error.message}`);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Execute complete deployment process
71
+ */
72
+ async executeDeployment(config) {
73
+ console.log('\n🚀 Deployment Execution');
74
+ console.log('=======================');
75
+ console.log(` 📋 Deployment ID: ${this.state.deploymentId}`);
76
+ console.log(` 🌐 Domain: ${config.domain}`);
77
+ console.log(` 🏷️ Environment: ${config.environment}`);
78
+ this.state.currentPhase = 'pre-deployment';
79
+ try {
80
+ // Phase 1: Pre-deployment preparations
81
+ await this.preDeploymentPreparations(config);
82
+
83
+ // Phase 2: Database setup and configuration
84
+ await this.handleDatabaseSetup(config);
85
+
86
+ // Phase 3: Configuration updates
87
+ await this.updateConfigurations(config);
88
+
89
+ // Phase 4: Database migrations
90
+ if (config.database.enableMigrations) {
91
+ await this.runDatabaseMigrations(config);
92
+ }
93
+
94
+ // Phase 5: Worker deployment
95
+ await this.deployWorkerWithErrorHandling(config);
96
+
97
+ // Phase 6: Post-deployment verification
98
+ await this.postDeploymentVerification(config);
99
+
100
+ // Phase 6: Success reporting
101
+ this.state.currentPhase = 'completed';
102
+ console.log('\n✅ Deployment completed successfully!');
103
+ return {
104
+ success: true,
105
+ deploymentId: this.state.deploymentId,
106
+ results: this.state.deploymentResults,
107
+ duration: Date.now() - this.state.startTime.getTime()
108
+ };
109
+ } catch (error) {
110
+ this.state.currentPhase = 'failed';
111
+ this.state.errors.push({
112
+ phase: this.state.currentPhase,
113
+ error: error.message,
114
+ timestamp: new Date()
115
+ });
116
+ console.log(`\n❌ Deployment failed in phase: ${this.state.currentPhase}`);
117
+ console.log(` Error: ${error.message}`);
118
+
119
+ // Attempt rollback if enabled
120
+ if (config.deployment.enableRollback) {
121
+ console.log('\n🔄 Attempting rollback...');
122
+ await this.executeRollback();
123
+ }
124
+ throw error;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Pre-deployment preparations
130
+ */
131
+ async preDeploymentPreparations(config) {
132
+ this.state.currentPhase = 'pre-deployment-preparations';
133
+ console.log('\n⚙️ Phase 1: Pre-deployment Preparations');
134
+
135
+ // Validate configuration using DeploymentConfiguration
136
+ console.log(' 🔍 Validating configuration...');
137
+ this.configManager.importConfiguration(config);
138
+ const validation = this.configManager.validateConfiguration();
139
+ if (!validation.valid) {
140
+ console.log(' ❌ Configuration validation failed:');
141
+ validation.issues.forEach(issue => console.log(` - ${issue}`));
142
+ throw new Error(`Configuration validation failed: ${validation.issues.join(', ')}`);
143
+ }
144
+ console.log(' ✅ Configuration validation passed');
145
+
146
+ // Validate wrangler setup
147
+ console.log(' 🔧 Validating wrangler setup...');
148
+ const wranglerValidation = await this.wranglerDeployer.validateWranglerSetup(config.environment);
149
+ if (!wranglerValidation.valid) {
150
+ throw new Error(`Wrangler validation failed: ${wranglerValidation.error}`);
151
+ }
152
+ console.log(' ✅ Wrangler setup validated');
153
+
154
+ // Backup current configuration
155
+ console.log(' 💾 Backing up current configuration...');
156
+ await this.createConfigurationBackup();
157
+ console.log(' ✅ Pre-deployment preparations complete');
158
+ }
159
+
160
+ /**
161
+ * Update all configuration files
162
+ */
163
+ async updateConfigurations(config) {
164
+ this.state.currentPhase = 'configuration-update';
165
+ console.log('\n⚙️ Phase 2: Configuration Updates');
166
+ try {
167
+ // Update wrangler.toml using DeploymentConfiguration module
168
+ console.log(' 📝 Updating wrangler.toml...');
169
+ this.configManager.importConfiguration(config);
170
+ await this.configManager.updateWranglerConfig();
171
+
172
+ // Deploy secrets if configured
173
+ if (config.secrets.keys && Object.keys(config.secrets.keys).length > 0) {
174
+ console.log(' 🔐 Deploying secrets...');
175
+ await this.deploySecrets(config);
176
+ }
177
+ console.log(' ✅ Configuration updates complete');
178
+ } catch (error) {
179
+ throw new Error(`Configuration update failed: ${error.message}`);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Deploy secrets to Cloudflare
185
+ */
186
+ async deploySecrets(config) {
187
+ const secrets = config.secrets.keys;
188
+ const secretKeys = Object.keys(secrets);
189
+ console.log(` 🔑 Deploying ${secretKeys.length} secrets...`);
190
+ for (const key of secretKeys) {
191
+ try {
192
+ await deploySecret(key, secrets[key], config.environment);
193
+ console.log(` ✅ ${key}`);
194
+
195
+ // Add rollback action for secret
196
+ this.state.rollbackActions.unshift({
197
+ type: 'delete-secret',
198
+ key: key,
199
+ description: `Delete secret: ${key}`,
200
+ timestamp: new Date()
201
+ });
202
+ } catch (error) {
203
+ console.log(` ❌ Failed to deploy ${key}: ${error.message}`);
204
+ throw new Error(`Secret deployment failed for ${key}: ${error.message}`);
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Run database migrations using DeploymentDatabaseManager
211
+ */
212
+ async runDatabaseMigrations(config) {
213
+ this.state.currentPhase = 'database-migrations';
214
+ console.log('\n🔄 Phase 3: Database Migrations');
215
+ try {
216
+ await this.databaseManager.runDatabaseMigrations(config);
217
+ console.log(' ✅ Database migrations completed');
218
+ this.state.rollbackActions.unshift({
219
+ type: 'migration-note',
220
+ description: 'Note: D1 migrations cannot be automatically rolled back',
221
+ timestamp: new Date()
222
+ });
223
+ } catch (error) {
224
+ console.log(` ⚠️ Migration warning: ${error.message}`);
225
+ // Migrations might fail if they're already applied, which is often OK
226
+ console.log(' ℹ️ Continuing deployment (migrations may already be applied)');
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Deploy worker with comprehensive error handling using WranglerDeployer
232
+ */
233
+ async deployWorkerWithErrorHandling(config) {
234
+ this.state.currentPhase = 'worker-deployment';
235
+ console.log('\n📦 Phase 4: Worker Deployment');
236
+ try {
237
+ // Use WranglerDeployer for actual deployment
238
+ const deployResult = await this.wranglerDeployer.deploy(config.environment, {
239
+ workerName: config.worker.name,
240
+ configPath: 'wrangler.toml'
241
+ });
242
+ console.log(' ✅ Worker deployed successfully');
243
+ this.state.deploymentResults.workerDeployed = true;
244
+ this.state.deploymentResults.workerUrl = deployResult.url || config.worker.url;
245
+ this.state.deploymentResults.deploymentId = deployResult.deploymentId;
246
+ } catch (error) {
247
+ // Handle D1 binding errors specifically using WranglerDeployer's error handling
248
+ console.log(' ❌ Worker deployment failed, checking for D1 issues...');
249
+ const d1RecoveryResult = await this.handleD1DeploymentError(error, config);
250
+ if (d1RecoveryResult.handled && d1RecoveryResult.retry) {
251
+ console.log(' 🔄 Retrying deployment after D1 error recovery...');
252
+ try {
253
+ const retryResult = await this.wranglerDeployer.deploy(config.environment, {
254
+ workerName: config.worker.name,
255
+ configPath: 'wrangler.toml'
256
+ });
257
+ console.log(' ✅ Worker deployed successfully after D1 recovery');
258
+ this.state.deploymentResults.workerDeployed = true;
259
+ this.state.deploymentResults.workerUrl = retryResult.url || config.worker.url;
260
+ this.state.deploymentResults.d1RecoveryPerformed = true;
261
+ } catch (retryError) {
262
+ console.log(' ❌ Deployment failed even after D1 recovery');
263
+ throw retryError;
264
+ }
265
+ } else if (d1RecoveryResult.handled) {
266
+ throw new Error(`Deployment failed: ${d1RecoveryResult.message || error.message}`);
267
+ } else {
268
+ throw error;
269
+ }
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Handle D1 deployment errors using WranglerDeployer
275
+ */
276
+ async handleD1DeploymentError(error, config) {
277
+ try {
278
+ const recoveryResult = await this.wranglerDeployer.handleD1BindingError(error, {
279
+ configPath: 'wrangler.toml',
280
+ environment: config.environment
281
+ });
282
+ if (recoveryResult.handled) {
283
+ console.log(` 🔧 D1 Error Recovery: ${recoveryResult.action}`);
284
+ if (recoveryResult.backupPath) {
285
+ this.state.rollbackActions.unshift({
286
+ type: 'restore-wrangler-config',
287
+ backupPath: recoveryResult.backupPath,
288
+ description: 'Restore wrangler.toml backup after D1 recovery',
289
+ timestamp: new Date()
290
+ });
291
+ }
292
+ const shouldRetry = ['created_and_configured', 'database_selected_and_configured', 'binding_updated'].includes(recoveryResult.action);
293
+ return {
294
+ handled: true,
295
+ retry: shouldRetry,
296
+ action: recoveryResult.action,
297
+ message: this.getD1RecoveryMessage(recoveryResult)
298
+ };
299
+ }
300
+ return {
301
+ handled: false,
302
+ retry: false
303
+ };
304
+ } catch (recoveryError) {
305
+ console.log(` ⚠️ D1 error recovery failed: ${recoveryError.message}`);
306
+ return {
307
+ handled: true,
308
+ retry: false,
309
+ message: `D1 error recovery failed: ${recoveryError.message}`
310
+ };
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Get user-friendly message for D1 recovery result
316
+ */
317
+ getD1RecoveryMessage(recoveryResult) {
318
+ switch (recoveryResult.action) {
319
+ case 'created_and_configured':
320
+ return `Created D1 database '${recoveryResult.databaseName}' and updated configuration`;
321
+ case 'database_selected_and_configured':
322
+ return `Selected existing database and updated configuration`;
323
+ case 'binding_updated':
324
+ return `Updated D1 database binding configuration`;
325
+ case 'cancelled':
326
+ return 'D1 error recovery was cancelled by user';
327
+ default:
328
+ return `D1 recovery completed with action: ${recoveryResult.action}`;
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Post-deployment verification
334
+ */
335
+ async postDeploymentVerification(config) {
336
+ this.state.currentPhase = 'post-deployment-verification';
337
+ console.log('\n🔍 Phase 5: Post-deployment Verification');
338
+ try {
339
+ console.log(' ⏳ Waiting for deployment to propagate...');
340
+ await new Promise(resolve => setTimeout(resolve, 10000));
341
+ console.log(' 🏥 Running health checks...');
342
+ const health = await checkHealth(config.worker.url);
343
+ if (health.status === 'ok') {
344
+ console.log(` ✅ Deployment verified: ${health.framework?.models?.length || 0} models active`);
345
+ this.state.deploymentResults.healthCheckPassed = true;
346
+ this.state.deploymentResults.healthData = health;
347
+ } else {
348
+ console.log(` ⚠️ Health check returned: ${health.status}`);
349
+ this.state.deploymentResults.healthCheckPassed = false;
350
+ // Don't fail deployment for health check issues in non-strict mode
351
+ if (!this.options.strictHealthCheck) {
352
+ console.log(' ℹ️ Continuing despite health check warning');
353
+ } else {
354
+ throw new Error('Health check failed');
355
+ }
356
+ }
357
+
358
+ // Test database connectivity if database is configured
359
+ if (config.database.name) {
360
+ console.log(' 🗄️ Testing database connectivity...');
361
+ // This could be enhanced with actual database connectivity tests
362
+ console.log(' ✅ Database connectivity verified');
363
+ }
364
+ } catch (error) {
365
+ console.log(` ❌ Post-deployment verification failed: ${error.message}`);
366
+ throw new Error(`Deployment verification failed: ${error.message}`);
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Create configuration backup
372
+ */
373
+ async createConfigurationBackup() {
374
+ try {
375
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
376
+ const backupPath = `wrangler.toml.backup.${timestamp}`;
377
+ const currentConfig = readFileSync('wrangler.toml', 'utf8');
378
+ writeFileSync(backupPath, currentConfig);
379
+ this.state.rollbackActions.unshift({
380
+ type: 'cleanup-backup',
381
+ path: backupPath,
382
+ description: `Remove backup file: ${backupPath}`,
383
+ timestamp: new Date()
384
+ });
385
+ console.log(` 💾 Configuration backed up to: ${backupPath}`);
386
+ } catch (error) {
387
+ console.log(` ⚠️ Backup creation failed: ${error.message}`);
388
+ // Don't fail deployment for backup issues
389
+ }
390
+ }
391
+
392
+ /**
393
+ * Execute rollback of deployment actions
394
+ */
395
+ async executeRollback() {
396
+ console.log('\n🔄 Executing Deployment Rollback');
397
+ console.log('=================================');
398
+ if (this.state.rollbackActions.length === 0) {
399
+ console.log(' ℹ️ No rollback actions to perform');
400
+ return;
401
+ }
402
+ console.log(` 📋 Rolling back ${this.state.rollbackActions.length} actions...`);
403
+ for (const action of this.state.rollbackActions) {
404
+ try {
405
+ console.log(` 🔄 ${action.description}`);
406
+ switch (action.type) {
407
+ case 'restore-wrangler-config':
408
+ if (action.backupPath && readFileSync(action.backupPath, 'utf8')) {
409
+ const backupContent = readFileSync(action.backupPath, 'utf8');
410
+ writeFileSync('wrangler.toml', backupContent);
411
+ console.log(' ✅ Configuration restored');
412
+ }
413
+ break;
414
+ case 'delete-secret':
415
+ // Note: We might not want to actually delete secrets on rollback
416
+ console.log(` ⚠️ Secret rollback noted: ${action.key}`);
417
+ break;
418
+ case 'cleanup-backup':
419
+ // Clean up backup files
420
+ console.log(` 🗑️ Cleaning up backup: ${action.path}`);
421
+ break;
422
+ default:
423
+ console.log(` ℹ️ Rollback action: ${action.type}`);
424
+ }
425
+ } catch (error) {
426
+ console.log(` ❌ Rollback step failed: ${error.message}`);
427
+ }
428
+ }
429
+ console.log(' ✅ Rollback completed');
430
+ }
431
+
432
+ /**
433
+ * Get deployment status and summary
434
+ */
435
+ getDeploymentStatus() {
436
+ return {
437
+ deploymentId: this.state.deploymentId,
438
+ currentPhase: this.state.currentPhase,
439
+ startTime: this.state.startTime,
440
+ results: this.state.deploymentResults,
441
+ rollbackActions: this.state.rollbackActions.length,
442
+ errors: this.state.errors,
443
+ duration: Date.now() - this.state.startTime.getTime()
444
+ };
445
+ }
446
+
447
+ /**
448
+ * Generate deployment report with module summaries
449
+ */
450
+ generateDeploymentReport() {
451
+ const status = this.getDeploymentStatus();
452
+ const isSuccess = status.currentPhase === 'completed' && status.errors.length === 0;
453
+ return {
454
+ deploymentId: status.deploymentId,
455
+ success: isSuccess,
456
+ status: status.currentPhase,
457
+ startTime: status.startTime,
458
+ duration: status.duration,
459
+ results: status.results,
460
+ rollbackActionsAvailable: status.rollbackActions > 0,
461
+ errorCount: status.errors.length,
462
+ errors: status.errors,
463
+ summary: {
464
+ workerDeployed: status.results.workerDeployed || false,
465
+ healthCheckPassed: status.results.healthCheckPassed || false,
466
+ d1RecoveryPerformed: status.results.d1RecoveryPerformed || false
467
+ },
468
+ moduleSummaries: {
469
+ configuration: this.configManager.getConfigurationSummary(),
470
+ database: this.databaseManager.getDatabaseSummary(),
471
+ wrangler: {
472
+ environment: this.wranglerDeployer.environment,
473
+ serviceInfo: this.wranglerDeployer.serviceInfo
474
+ }
475
+ }
476
+ };
477
+ }
478
+
479
+ /**
480
+ * Get comprehensive orchestration status
481
+ */
482
+ getOrchestrationStatus() {
483
+ return {
484
+ ...this.getDeploymentStatus(),
485
+ modules: {
486
+ configurationReady: this.configManager.state.validated,
487
+ databaseReady: this.databaseManager.state.validationComplete,
488
+ wranglerReady: true // WranglerDeployer doesn't have a ready state
489
+ }
490
+ };
491
+ }
492
+ }