@tamyla/clodo-framework 1.0.0

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 (130) hide show
  1. package/CHANGELOG.md +564 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1393 -0
  4. package/bin/README.md +71 -0
  5. package/bin/clodo-service.js +416 -0
  6. package/bin/security/security-cli.js +96 -0
  7. package/bin/service-management/README.md +74 -0
  8. package/bin/service-management/create-service.js +129 -0
  9. package/bin/service-management/init-service.js +102 -0
  10. package/bin/service-management/init-service.js.backup +889 -0
  11. package/bin/shared/config/customer-cli.js +293 -0
  12. package/dist/config/ConfigurationManager.js +159 -0
  13. package/dist/config/CustomerConfigCLI.js +220 -0
  14. package/dist/config/FeatureManager.js +426 -0
  15. package/dist/config/customers.js +441 -0
  16. package/dist/config/domains.js +180 -0
  17. package/dist/config/features.js +225 -0
  18. package/dist/config/index.js +6 -0
  19. package/dist/database/database-orchestrator.js +730 -0
  20. package/dist/database/index.js +4 -0
  21. package/dist/deployment/auditor.js +971 -0
  22. package/dist/deployment/index.js +10 -0
  23. package/dist/deployment/rollback-manager.js +523 -0
  24. package/dist/deployment/testers/api-tester.js +80 -0
  25. package/dist/deployment/testers/auth-tester.js +129 -0
  26. package/dist/deployment/testers/core.js +217 -0
  27. package/dist/deployment/testers/database-tester.js +105 -0
  28. package/dist/deployment/testers/index.js +74 -0
  29. package/dist/deployment/testers/load-tester.js +120 -0
  30. package/dist/deployment/testers/performance-tester.js +105 -0
  31. package/dist/deployment/validator.js +558 -0
  32. package/dist/deployment/wrangler-deployer.js +574 -0
  33. package/dist/handlers/GenericRouteHandler.js +532 -0
  34. package/dist/index.js +39 -0
  35. package/dist/migration/MigrationAdapters.js +562 -0
  36. package/dist/modules/ModuleManager.js +668 -0
  37. package/dist/modules/security.js +98 -0
  38. package/dist/orchestration/cross-domain-coordinator.js +1083 -0
  39. package/dist/orchestration/index.js +5 -0
  40. package/dist/orchestration/modules/DeploymentCoordinator.js +258 -0
  41. package/dist/orchestration/modules/DomainResolver.js +196 -0
  42. package/dist/orchestration/modules/StateManager.js +332 -0
  43. package/dist/orchestration/multi-domain-orchestrator.js +255 -0
  44. package/dist/routing/EnhancedRouter.js +158 -0
  45. package/dist/schema/SchemaManager.js +778 -0
  46. package/dist/security/ConfigurationValidator.js +490 -0
  47. package/dist/security/DeploymentManager.js +208 -0
  48. package/dist/security/SecretGenerator.js +142 -0
  49. package/dist/security/SecurityCLI.js +228 -0
  50. package/dist/security/index.js +51 -0
  51. package/dist/security/patterns/environment-rules.js +66 -0
  52. package/dist/security/patterns/insecure-patterns.js +21 -0
  53. package/dist/service-management/ConfirmationEngine.js +411 -0
  54. package/dist/service-management/ErrorTracker.js +294 -0
  55. package/dist/service-management/GenerationEngine.js +3109 -0
  56. package/dist/service-management/InputCollector.js +237 -0
  57. package/dist/service-management/ServiceCreator.js +229 -0
  58. package/dist/service-management/ServiceInitializer.js +448 -0
  59. package/dist/service-management/ServiceOrchestrator.js +638 -0
  60. package/dist/service-management/handlers/ConfigMutator.js +130 -0
  61. package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
  62. package/dist/service-management/handlers/GenerationHandler.js +80 -0
  63. package/dist/service-management/handlers/InputHandler.js +59 -0
  64. package/dist/service-management/handlers/ValidationHandler.js +203 -0
  65. package/dist/service-management/index.js +7 -0
  66. package/dist/services/GenericDataService.js +488 -0
  67. package/dist/shared/cloudflare/domain-discovery.js +562 -0
  68. package/dist/shared/cloudflare/domain-manager.js +912 -0
  69. package/dist/shared/cloudflare/index.js +8 -0
  70. package/dist/shared/cloudflare/ops.js +387 -0
  71. package/dist/shared/config/cache.js +1167 -0
  72. package/dist/shared/config/command-config-manager.js +174 -0
  73. package/dist/shared/config/customer-cli.js +258 -0
  74. package/dist/shared/config/index.js +9 -0
  75. package/dist/shared/config/manager.js +289 -0
  76. package/dist/shared/database/connection-manager.js +338 -0
  77. package/dist/shared/database/index.js +7 -0
  78. package/dist/shared/database/orchestrator.js +632 -0
  79. package/dist/shared/deployment/auditor.js +971 -0
  80. package/dist/shared/deployment/index.js +10 -0
  81. package/dist/shared/deployment/rollback-manager.js +523 -0
  82. package/dist/shared/deployment/validator.js +558 -0
  83. package/dist/shared/index.js +32 -0
  84. package/dist/shared/monitoring/health-checker.js +250 -0
  85. package/dist/shared/monitoring/index.js +8 -0
  86. package/dist/shared/monitoring/memory-manager.js +382 -0
  87. package/dist/shared/monitoring/production-monitor.js +390 -0
  88. package/dist/shared/production-tester/api-tester.js +80 -0
  89. package/dist/shared/production-tester/auth-tester.js +129 -0
  90. package/dist/shared/production-tester/core.js +217 -0
  91. package/dist/shared/production-tester/database-tester.js +105 -0
  92. package/dist/shared/production-tester/index.js +74 -0
  93. package/dist/shared/production-tester/load-tester.js +120 -0
  94. package/dist/shared/production-tester/performance-tester.js +105 -0
  95. package/dist/shared/security/api-token-manager.js +296 -0
  96. package/dist/shared/security/index.js +8 -0
  97. package/dist/shared/security/secret-generator.js +918 -0
  98. package/dist/shared/security/secure-token-manager.js +379 -0
  99. package/dist/shared/utils/error-recovery.js +240 -0
  100. package/dist/shared/utils/graceful-shutdown-manager.js +380 -0
  101. package/dist/shared/utils/index.js +9 -0
  102. package/dist/shared/utils/interactive-prompts.js +134 -0
  103. package/dist/shared/utils/rate-limiter.js +249 -0
  104. package/dist/utils/ErrorHandler.js +173 -0
  105. package/dist/utils/deployment/config-cache.js +1160 -0
  106. package/dist/utils/deployment/index.js +6 -0
  107. package/dist/utils/deployment/interactive-prompts.js +97 -0
  108. package/dist/utils/deployment/secret-generator.js +896 -0
  109. package/dist/utils/dirname-helper.js +35 -0
  110. package/dist/utils/domain-config.js +159 -0
  111. package/dist/utils/error-recovery.js +240 -0
  112. package/dist/utils/esm-helper.js +52 -0
  113. package/dist/utils/framework-config.js +481 -0
  114. package/dist/utils/graceful-shutdown-manager.js +379 -0
  115. package/dist/utils/health-checker.js +114 -0
  116. package/dist/utils/index.js +36 -0
  117. package/dist/utils/prompt-handler.js +98 -0
  118. package/dist/utils/usage-tracker.js +252 -0
  119. package/dist/utils/validation.js +112 -0
  120. package/dist/version/VersionDetector.js +723 -0
  121. package/dist/worker/index.js +4 -0
  122. package/dist/worker/integration.js +332 -0
  123. package/docs/FRAMEWORK-ARCHITECTURE-OVERVIEW.md +206 -0
  124. package/docs/INTEGRATION_GUIDE.md +2045 -0
  125. package/docs/README.md +82 -0
  126. package/docs/SECURITY.md +242 -0
  127. package/docs/deployment/deployment-guide.md +540 -0
  128. package/docs/overview.md +280 -0
  129. package/package.json +176 -0
  130. package/types/index.d.ts +575 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Rate Limiter for Cloudflare API calls
3
+ * Implements exponential backoff and request queuing to prevent rate limit violations
4
+ */
5
+
6
+ import { promisify } from 'util';
7
+ import { exec } from 'child_process';
8
+ const execAsync = promisify(exec);
9
+
10
+ /**
11
+ * Rate limiter configuration for different Cloudflare API endpoints
12
+ */
13
+ const RATE_LIMITS = {
14
+ // Workers API limits (1000/hour, 100/minute)
15
+ workers: {
16
+ maxRequestsPerMinute: 100,
17
+ maxRequestsPerHour: 1000,
18
+ baseDelay: 1000,
19
+ // 1 second
20
+ maxDelay: 300000 // 5 minutes
21
+ },
22
+ // D1 Database API limits (1000/hour)
23
+ d1: {
24
+ maxRequestsPerMinute: 50,
25
+ maxRequestsPerHour: 1000,
26
+ baseDelay: 2000,
27
+ // 2 seconds
28
+ maxDelay: 600000 // 10 minutes
29
+ },
30
+ // General API limits
31
+ general: {
32
+ maxRequestsPerMinute: 30,
33
+ maxRequestsPerHour: 500,
34
+ baseDelay: 3000,
35
+ // 3 seconds
36
+ maxDelay: 900000 // 15 minutes
37
+ }
38
+ };
39
+
40
+ /**
41
+ * Request queue for each API type
42
+ */
43
+ const requestQueues = {
44
+ workers: [],
45
+ d1: [],
46
+ general: []
47
+ };
48
+
49
+ /**
50
+ * Current request counts and timestamps
51
+ */
52
+ const requestCounts = {
53
+ workers: {
54
+ minute: 0,
55
+ hour: 0,
56
+ lastMinuteReset: Date.now(),
57
+ lastHourReset: Date.now()
58
+ },
59
+ d1: {
60
+ minute: 0,
61
+ hour: 0,
62
+ lastMinuteReset: Date.now(),
63
+ lastHourReset: Date.now()
64
+ },
65
+ general: {
66
+ minute: 0,
67
+ hour: 0,
68
+ lastMinuteReset: Date.now(),
69
+ lastHourReset: Date.now()
70
+ }
71
+ };
72
+
73
+ /**
74
+ * Reset counters based on time windows
75
+ */
76
+ function resetCounters() {
77
+ const now = Date.now();
78
+ Object.keys(requestCounts).forEach(apiType => {
79
+ const counts = requestCounts[apiType];
80
+
81
+ // Reset minute counter if needed
82
+ if (now - counts.lastMinuteReset >= 60000) {
83
+ // 1 minute
84
+ counts.minute = 0;
85
+ counts.lastMinuteReset = now;
86
+ }
87
+
88
+ // Reset hour counter if needed
89
+ if (now - counts.lastHourReset >= 3600000) {
90
+ // 1 hour
91
+ counts.hour = 0;
92
+ counts.lastHourReset = now;
93
+ }
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Calculate delay based on exponential backoff
99
+ */
100
+ function calculateDelay(apiType, attempt = 0) {
101
+ const config = RATE_LIMITS[apiType];
102
+ const delay = Math.min(config.baseDelay * Math.pow(2, attempt), config.maxDelay);
103
+ return delay + Math.random() * 1000; // Add jitter
104
+ }
105
+
106
+ /**
107
+ * Check if we can make a request without violating rate limits
108
+ */
109
+ function canMakeRequest(apiType) {
110
+ resetCounters();
111
+ const counts = requestCounts[apiType];
112
+ const limits = RATE_LIMITS[apiType];
113
+ return counts.minute < limits.maxRequestsPerMinute && counts.hour < limits.maxRequestsPerHour;
114
+ }
115
+
116
+ /**
117
+ * Execute a Cloudflare API command with rate limiting
118
+ */
119
+ async function executeWithRateLimit(command, apiType = 'general', maxRetries = 5) {
120
+ return new Promise((resolve, reject) => {
121
+ const attemptRequest = async (attempt = 0) => {
122
+ try {
123
+ // Check if we can make the request
124
+ if (!canMakeRequest(apiType)) {
125
+ const delay = calculateDelay(apiType, attempt);
126
+ console.log(`Rate limit approaching for ${apiType} API. Waiting ${delay}ms before retry...`);
127
+ await new Promise(resolve => setTimeout(resolve, delay));
128
+ return attemptRequest(attempt);
129
+ }
130
+
131
+ // Execute the command
132
+ console.log(`Executing ${apiType} API command (attempt ${attempt + 1}/${maxRetries + 1})`);
133
+ const result = await execAsync(command);
134
+
135
+ // Update counters on success
136
+ requestCounts[apiType].minute++;
137
+ requestCounts[apiType].hour++;
138
+ resolve(result);
139
+ } catch (error) {
140
+ // Check if it's a rate limit error
141
+ if (error.stderr && (error.stderr.includes('rate limit') || error.stderr.includes('429') || error.stderr.includes('Too Many Requests'))) {
142
+ if (attempt < maxRetries) {
143
+ const delay = calculateDelay(apiType, attempt);
144
+ console.log(`Rate limit hit for ${apiType} API. Retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries + 1})`);
145
+ setTimeout(() => attemptRequest(attempt + 1), delay);
146
+ } else {
147
+ reject(new Error(`Rate limit exceeded for ${apiType} API after ${maxRetries + 1} attempts: ${error.message}`));
148
+ }
149
+ } else {
150
+ // Not a rate limit error, reject immediately
151
+ reject(error);
152
+ }
153
+ }
154
+ };
155
+ attemptRequest();
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Queue a request for execution with rate limiting
161
+ */
162
+ async function queueRequest(command, apiType = 'general', priority = 'normal') {
163
+ return new Promise((resolve, reject) => {
164
+ const request = {
165
+ command,
166
+ apiType,
167
+ priority,
168
+ resolve,
169
+ reject,
170
+ timestamp: Date.now()
171
+ };
172
+
173
+ // Add to appropriate queue
174
+ requestQueues[apiType].push(request);
175
+
176
+ // Sort by priority (high priority first)
177
+ requestQueues[apiType].sort((a, b) => {
178
+ const priorityOrder = {
179
+ high: 3,
180
+ normal: 2,
181
+ low: 1
182
+ };
183
+ return priorityOrder[b.priority] - priorityOrder[a.priority];
184
+ });
185
+
186
+ // Process the queue
187
+ processQueue(apiType);
188
+ });
189
+ }
190
+
191
+ /**
192
+ * Process the request queue for a specific API type
193
+ */
194
+ async function processQueue(apiType) {
195
+ const queue = requestQueues[apiType];
196
+ if (queue.length === 0) return;
197
+
198
+ // Only process one request at a time per API type
199
+ if (queue.processing) return;
200
+ queue.processing = true;
201
+ try {
202
+ while (queue.length > 0) {
203
+ const request = queue.shift();
204
+ try {
205
+ const result = await executeWithRateLimit(request.command, request.apiType);
206
+ request.resolve(result);
207
+ } catch (error) {
208
+ request.reject(error);
209
+ }
210
+
211
+ // Small delay between requests to be respectful
212
+ await new Promise(resolve => setTimeout(resolve, 100));
213
+ }
214
+ } finally {
215
+ queue.processing = false;
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Get current rate limit status
221
+ */
222
+ function getRateLimitStatus(apiType) {
223
+ resetCounters();
224
+ const counts = requestCounts[apiType];
225
+ const limits = RATE_LIMITS[apiType];
226
+ return {
227
+ minute: {
228
+ used: counts.minute,
229
+ limit: limits.maxRequestsPerMinute,
230
+ remaining: Math.max(0, limits.maxRequestsPerMinute - counts.minute)
231
+ },
232
+ hour: {
233
+ used: counts.hour,
234
+ limit: limits.maxRequestsPerHour,
235
+ remaining: Math.max(0, limits.maxRequestsPerHour - counts.hour)
236
+ }
237
+ };
238
+ }
239
+
240
+ /**
241
+ * Clear all queues (useful for testing or emergency situations)
242
+ */
243
+ function clearQueues() {
244
+ Object.keys(requestQueues).forEach(apiType => {
245
+ requestQueues[apiType].length = 0;
246
+ requestQueues[apiType].processing = false;
247
+ });
248
+ }
249
+ export { executeWithRateLimit, queueRequest, getRateLimitStatus, clearQueues, RATE_LIMITS };
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Enhanced Error Handler
3
+ * Comprehensive error reporting and handling utilities
4
+ */
5
+
6
+ export class ErrorHandler {
7
+ /**
8
+ * Handle deployment errors with detailed reporting
9
+ * @param {Error} error - The error object
10
+ * @param {Object} context - Additional context (customer, environment, etc.)
11
+ */
12
+ static handleDeploymentError(error, context = {}) {
13
+ const {
14
+ customer,
15
+ environment,
16
+ phase
17
+ } = context;
18
+ console.error(`\n❌ Deployment Error in phase: ${phase || 'unknown'}`);
19
+ console.error(` Customer: ${customer || 'unknown'}`);
20
+ console.error(` Environment: ${environment || 'unknown'}`);
21
+ console.error(` Message: ${error.message}`);
22
+ if (error.stack) {
23
+ console.error(` Stack: ${error.stack}`);
24
+ }
25
+
26
+ // Log additional context if available
27
+ if (context.deploymentUrl) {
28
+ console.error(` Deployment URL: ${context.deploymentUrl}`);
29
+ }
30
+
31
+ // Provide actionable suggestions
32
+ this.provideErrorSuggestions(error, context);
33
+ }
34
+
35
+ /**
36
+ * Provide actionable error suggestions
37
+ * @param {Error} error - The error object
38
+ * @param {Object} context - Context information
39
+ */
40
+ static provideErrorSuggestions(error, context) {
41
+ console.error('\n💡 Suggestions:');
42
+ if (error.message.includes('security')) {
43
+ console.error(' - Run security validation: npx clodo-security validate <customer> <environment>');
44
+ console.error(' - Generate secure keys: npx clodo-security generate-key api');
45
+ }
46
+ if (error.message.includes('health check')) {
47
+ console.error(' - Check deployment URL accessibility');
48
+ console.error(' - Verify service is running and responding');
49
+ }
50
+ if (error.message.includes('authentication')) {
51
+ console.error(' - Re-authenticate with Cloudflare: wrangler auth login');
52
+ console.error(' - Check API token validity');
53
+ }
54
+ if (error.message.includes('timeout')) {
55
+ console.error(' - Increase timeout values in configuration');
56
+ console.error(' - Check network connectivity');
57
+ }
58
+ if (error.message.includes('validation')) {
59
+ console.error(' - Review configuration files for errors');
60
+ console.error(' - Run validation checks: npx clodo-config validate');
61
+ }
62
+ console.error(' - Review logs for more details');
63
+ }
64
+
65
+ /**
66
+ * Wrap async operations with error handling
67
+ * @param {Function} fn - Async function to wrap
68
+ * @param {Object} context - Context for error reporting
69
+ */
70
+ static async withErrorHandling(fn, context = {}) {
71
+ try {
72
+ return await fn();
73
+ } catch (error) {
74
+ this.handleDeploymentError(error, context);
75
+ throw error;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Handle health check errors specifically
81
+ * @param {Error} error - The health check error
82
+ * @param {string} url - The URL that was checked
83
+ */
84
+ static handleHealthCheckError(error, url) {
85
+ console.error(`\n❌ Health Check Failed`);
86
+ console.error(` URL: ${url}`);
87
+ console.error(` Error: ${error.message}`);
88
+ console.error('\n💡 Health Check Troubleshooting:');
89
+ console.error(' - Verify the service is deployed and running');
90
+ console.error(' - Check if the /health endpoint exists');
91
+ console.error(' - Ensure the service responds with valid JSON');
92
+ console.error(' - Check network connectivity and firewall rules');
93
+ console.error(' - Review service logs for startup errors');
94
+ }
95
+
96
+ /**
97
+ * Handle configuration errors
98
+ * @param {Error} error - The configuration error
99
+ * @param {Object} config - The configuration object that failed
100
+ */
101
+ static handleConfigurationError(error, config = {}) {
102
+ console.error(`\n❌ Configuration Error`);
103
+ console.error(` Message: ${error.message}`);
104
+ if (config.customer) {
105
+ console.error(` Customer: ${config.customer}`);
106
+ }
107
+ if (config.environment) {
108
+ console.error(` Environment: ${config.environment}`);
109
+ }
110
+ console.error('\n💡 Configuration Troubleshooting:');
111
+ console.error(' - Validate configuration schema');
112
+ console.error(' - Check for missing required fields');
113
+ console.error(' - Verify environment variables are set');
114
+ console.error(' - Review configuration file syntax');
115
+ }
116
+
117
+ /**
118
+ * Create a standardized error report
119
+ * @param {Error} error - The error object
120
+ * @param {Object} context - Additional context
121
+ * @returns {Object} Standardized error report
122
+ */
123
+ static createErrorReport(error, context = {}) {
124
+ return {
125
+ timestamp: new Date().toISOString(),
126
+ error: {
127
+ message: error.message,
128
+ stack: error.stack,
129
+ name: error.name
130
+ },
131
+ context,
132
+ suggestions: this.generateSuggestions(error, context)
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Generate error suggestions based on error type and context
138
+ * @param {Error} error - The error object
139
+ * @param {Object} context - Context information
140
+ * @returns {string[]} Array of suggestion strings
141
+ */
142
+ static generateSuggestions(error, context) {
143
+ const suggestions = [];
144
+ const errorMessage = error.message.toLowerCase();
145
+ if (errorMessage.includes('security') || errorMessage.includes('validation')) {
146
+ suggestions.push('Run security validation: npx clodo-security validate');
147
+ suggestions.push('Generate secure keys: npx clodo-security generate-key api');
148
+ }
149
+ if (errorMessage.includes('health') || errorMessage.includes('connection')) {
150
+ suggestions.push('Check deployment URL accessibility');
151
+ suggestions.push('Verify service is running and responding');
152
+ suggestions.push('Check network connectivity and firewall rules');
153
+ }
154
+ if (errorMessage.includes('auth') || errorMessage.includes('token')) {
155
+ suggestions.push('Re-authenticate with Cloudflare: wrangler auth login');
156
+ suggestions.push('Check API token validity and permissions');
157
+ }
158
+ if (errorMessage.includes('timeout')) {
159
+ suggestions.push('Increase timeout values in configuration');
160
+ suggestions.push('Check network connectivity');
161
+ }
162
+ if (errorMessage.includes('config') || errorMessage.includes('missing')) {
163
+ suggestions.push('Review configuration files for errors');
164
+ suggestions.push('Run configuration validation: npx clodo-config validate');
165
+ suggestions.push('Check environment variables are properly set');
166
+ }
167
+ if (suggestions.length === 0) {
168
+ suggestions.push('Review logs for more details');
169
+ suggestions.push('Check system resources and dependencies');
170
+ }
171
+ return suggestions;
172
+ }
173
+ }