@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,8 @@
1
+ /**
2
+ * Cloudflare Integration Module
3
+ * Exports all Cloudflare-related utilities and managers
4
+ */
5
+
6
+ export { CloudflareDomainManager } from './domain-manager.js';
7
+ export { DomainDiscovery } from './domain-discovery.js';
8
+ export { CloudflareOps } from './ops.js';
@@ -0,0 +1,387 @@
1
+ /**
2
+ * Cloudflare Operations Module
3
+ * Standardized Cloudflare Workers and D1 operations
4
+ *
5
+ * Consolidates cloudflare operations across 14+ scripts
6
+ */
7
+
8
+ import { exec } from 'child_process';
9
+ import { promisify } from 'util';
10
+ import { executeWithRateLimit } from '../utils/rate-limiter.js';
11
+ import { ErrorRecoveryManager } from '../utils/error-recovery.js';
12
+ import { SecureTokenManager } from '../security/secure-token-manager.js';
13
+ import { ProductionMonitor } from '../monitoring/production-monitor.js';
14
+ import { DatabaseConnectionManager } from '../database/connection-manager.js';
15
+ import { startMemoryMonitoring } from '../monitoring/memory-manager.js';
16
+ import { initializeGracefulShutdown } from '../utils/graceful-shutdown-manager.js';
17
+ const execAsync = promisify(exec);
18
+
19
+ // Error recovery for critical operations
20
+ const errorRecovery = new ErrorRecoveryManager({
21
+ maxRetries: 2,
22
+ retryDelay: 2000,
23
+ circuitBreakerThreshold: 3,
24
+ gracefulDegradation: true
25
+ });
26
+
27
+ // Secure token management
28
+ const tokenManager = new SecureTokenManager();
29
+
30
+ // Production monitoring
31
+ const monitor = new ProductionMonitor({
32
+ logLevel: 'info',
33
+ enableMetrics: true,
34
+ enableAlerts: true
35
+ });
36
+
37
+ // Database connection management
38
+ const dbManager = new DatabaseConnectionManager({
39
+ maxRetries: 2,
40
+ retryDelay: 1000,
41
+ connectionTimeout: 30000,
42
+ queryTimeout: 60000,
43
+ enableConnectionPooling: true,
44
+ maxPoolSize: 5
45
+ });
46
+
47
+ // Memory management
48
+ const memoryManager = startMemoryMonitoring({
49
+ gcInterval: 300000,
50
+ // 5 minutes
51
+ memoryThreshold: 0.8,
52
+ cleanupInterval: 60000,
53
+ // 1 minute
54
+ leakDetection: true
55
+ });
56
+
57
+ // Graceful shutdown handling (async initialization)
58
+ let shutdownManager = null;
59
+ (async () => {
60
+ shutdownManager = await initializeGracefulShutdown({
61
+ dbManager,
62
+ monitor,
63
+ tokenManager,
64
+ memoryManager
65
+ }, {
66
+ shutdownTimeout: 30000,
67
+ forceShutdownTimeout: 5000
68
+ });
69
+ })().catch(console.error);
70
+
71
+ // Initialize monitoring
72
+ let monitoringInitialized = false;
73
+ async function ensureMonitoringInitialized() {
74
+ if (!monitoringInitialized) {
75
+ await monitor.startMonitoring();
76
+ monitoringInitialized = true;
77
+ }
78
+ }
79
+
80
+ // Initialize secure token manager
81
+ let tokenManagerInitialized = false;
82
+ async function ensureTokenManagerInitialized() {
83
+ if (!tokenManagerInitialized) {
84
+ await tokenManager.initialize();
85
+ tokenManagerInitialized = true;
86
+ }
87
+ }
88
+ export async function checkAuth() {
89
+ try {
90
+ await ensureTokenManagerInitialized();
91
+ // Try to get a valid token for Cloudflare API
92
+ const tokens = tokenManager.listTokens('cloudflare');
93
+ if (tokens.length === 0) {
94
+ return false;
95
+ }
96
+
97
+ // Check if we have a non-expired token
98
+ const validToken = tokens.find(token => new Date() < token.expires);
99
+ return !!validToken;
100
+ } catch (error) {
101
+ return false;
102
+ }
103
+ }
104
+ export async function authenticate() {
105
+ try {
106
+ // Use wrangler auth login for initial authentication
107
+ await execAsync('npx wrangler auth login', {
108
+ stdio: 'inherit'
109
+ });
110
+
111
+ // After successful login, we could extract and store the token securely
112
+ // For now, rely on wrangler's built-in token management
113
+ console.log('Authentication successful. Use storeCloudflareToken() to store API tokens securely.');
114
+ } catch (error) {
115
+ throw new Error(`Authentication failed: ${error.message}`);
116
+ }
117
+ }
118
+ export async function storeCloudflareToken(token, metadata = {}) {
119
+ await ensureTokenManagerInitialized();
120
+ const fingerprint = await tokenManager.storeToken('cloudflare', token, {
121
+ permissions: ['api_access', 'deployment'],
122
+ environment: metadata.environment || 'production',
123
+ ...metadata
124
+ });
125
+ console.log(`Cloudflare API token stored securely with fingerprint: ${fingerprint}`);
126
+ return fingerprint;
127
+ }
128
+ export async function getCloudflareToken(requiredPermissions = ['api_access']) {
129
+ await ensureTokenManagerInitialized();
130
+ const tokens = tokenManager.listTokens('cloudflare');
131
+
132
+ // Find a valid token with required permissions
133
+ for (const tokenInfo of tokens) {
134
+ if (new Date() < tokenInfo.expires && tokenManager.validatePermissions(tokenInfo.permissions, requiredPermissions)) {
135
+ return await tokenManager.retrieveToken('cloudflare', tokenInfo.fingerprint, requiredPermissions);
136
+ }
137
+ }
138
+ throw new Error('No valid Cloudflare API token found with required permissions');
139
+ }
140
+ export async function listWorkers() {
141
+ try {
142
+ const {
143
+ stdout: list
144
+ } = await executeWithRateLimit('npx wrangler list', 'workers');
145
+ return list;
146
+ } catch (error) {
147
+ throw new Error(`Failed to list workers: ${error.message}`);
148
+ }
149
+ }
150
+ export async function workerExists(workerName) {
151
+ try {
152
+ const list = await listWorkers();
153
+ return list.includes(workerName);
154
+ } catch (error) {
155
+ return false; // Assume doesn't exist if can't check
156
+ }
157
+ }
158
+ export async function deployWorker(env = 'production') {
159
+ const startTime = Date.now();
160
+ try {
161
+ await ensureMonitoringInitialized();
162
+ const result = await errorRecovery.executeWithRecovery(async () => {
163
+ await executeWithRateLimit(`npm run deploy:${env}`, 'workers');
164
+ return true;
165
+ }, {
166
+ operationId: `deployWorker_${env}`
167
+ });
168
+ const duration = Date.now() - startTime;
169
+ monitor.recordRequest(true, duration, {
170
+ operation: 'deployWorker',
171
+ env
172
+ });
173
+ await monitor.log('info', 'Worker deployment successful', {
174
+ env,
175
+ duration
176
+ });
177
+ return result;
178
+ } catch (error) {
179
+ const duration = Date.now() - startTime;
180
+ monitor.recordRequest(false, duration, {
181
+ operation: 'deployWorker',
182
+ env,
183
+ error: error.message
184
+ });
185
+ await monitor.log('error', 'Worker deployment failed', {
186
+ env,
187
+ duration,
188
+ error: error.message
189
+ });
190
+ throw new Error(`Worker deployment failed after retries: ${error.message}`);
191
+ }
192
+ }
193
+ export async function deploySecret(key, value, env = 'production') {
194
+ const command = process.platform === 'win32' ? `powershell -Command "Write-Output '${value}' | npx wrangler secret put ${key} --env ${env}"` : `echo "${value}" | npx wrangler secret put ${key} --env ${env}`;
195
+ try {
196
+ await executeWithRateLimit(command, 'workers', 3); // Lower retries for secrets
197
+ } catch (error) {
198
+ throw new Error(`Secret deployment failed: ${error.message}`);
199
+ }
200
+ }
201
+ export async function deleteSecret(key, env = 'production') {
202
+ try {
203
+ await executeWithRateLimit(`npx wrangler secret delete ${key} --env ${env}`, 'workers');
204
+ } catch (error) {
205
+ throw new Error(`Secret deletion failed: ${error.message}`);
206
+ }
207
+ }
208
+ export async function listSecrets(env = 'production') {
209
+ try {
210
+ const {
211
+ stdout: list
212
+ } = await executeWithRateLimit(`npx wrangler secret list --env ${env}`, 'workers');
213
+ return list;
214
+ } catch (error) {
215
+ throw new Error(`Failed to list secrets: ${error.message}`);
216
+ }
217
+ }
218
+ export async function listDatabases() {
219
+ try {
220
+ const {
221
+ stdout: list
222
+ } = await executeWithRateLimit('npx wrangler d1 list', 'd1');
223
+ return list;
224
+ } catch (error) {
225
+ throw new Error(`Failed to list databases: ${error.message}`);
226
+ }
227
+ }
228
+ export async function databaseExists(databaseName) {
229
+ try {
230
+ const list = await listDatabases();
231
+ return list.includes(databaseName);
232
+ } catch (error) {
233
+ return false; // Assume doesn't exist if can't check
234
+ }
235
+ }
236
+ export async function createDatabase(name) {
237
+ try {
238
+ const {
239
+ stdout: output
240
+ } = await executeWithRateLimit(`npx wrangler d1 create ${name}`, 'd1');
241
+ const idMatch = output.match(/database_id = "([^"]+)"/);
242
+ if (!idMatch) {
243
+ throw new Error('Could not extract database ID from creation output');
244
+ }
245
+ return idMatch[1];
246
+ } catch (error) {
247
+ throw new Error(`Database creation failed: ${error.message}`);
248
+ }
249
+ }
250
+ export async function deleteDatabase(name) {
251
+ try {
252
+ await executeWithRateLimit(`npx wrangler d1 delete ${name} --skip-confirmation`, 'd1');
253
+ } catch (error) {
254
+ throw new Error(`Database deletion failed: ${error.message}`);
255
+ }
256
+ }
257
+ export async function runMigrations(databaseName, env = 'production') {
258
+ const startTime = Date.now();
259
+ try {
260
+ await ensureMonitoringInitialized();
261
+ const result = await errorRecovery.executeWithRecovery(async () => {
262
+ await executeWithRateLimit(`npx wrangler d1 migrations apply ${databaseName} --env ${env} --remote`, 'd1');
263
+ return true;
264
+ }, {
265
+ operationId: `runMigrations_${databaseName}_${env}`
266
+ });
267
+ const duration = Date.now() - startTime;
268
+ monitor.recordRequest(true, duration, {
269
+ operation: 'runMigrations',
270
+ databaseName,
271
+ env
272
+ });
273
+ await monitor.log('info', 'Database migrations completed', {
274
+ databaseName,
275
+ env,
276
+ duration
277
+ });
278
+ return result;
279
+ } catch (error) {
280
+ const duration = Date.now() - startTime;
281
+ monitor.recordRequest(false, duration, {
282
+ operation: 'runMigrations',
283
+ databaseName,
284
+ env,
285
+ error: error.message
286
+ });
287
+ await monitor.log('warn', 'Database migrations had warnings', {
288
+ databaseName,
289
+ env,
290
+ duration,
291
+ error: error.message
292
+ });
293
+ return false; // Warnings are often OK
294
+ }
295
+ }
296
+ export async function executeSql(databaseName, sql, env = 'production') {
297
+ const startTime = Date.now();
298
+ try {
299
+ await ensureMonitoringInitialized();
300
+ const result = await dbManager.executeQuery(databaseName, sql, {
301
+ env
302
+ });
303
+ const duration = Date.now() - startTime;
304
+ monitor.recordRequest(true, duration, {
305
+ operation: 'executeSql',
306
+ databaseName,
307
+ env
308
+ });
309
+ await monitor.log('info', 'Database query executed successfully', {
310
+ databaseName,
311
+ env,
312
+ duration,
313
+ resultLength: result.result ? result.result.length : 0
314
+ });
315
+ return result.result;
316
+ } catch (error) {
317
+ const duration = Date.now() - startTime;
318
+ monitor.recordRequest(false, duration, {
319
+ operation: 'executeSql',
320
+ databaseName,
321
+ env,
322
+ error: error.message
323
+ });
324
+ await monitor.log('error', 'Database query failed', {
325
+ databaseName,
326
+ env,
327
+ duration,
328
+ error: error.message
329
+ });
330
+ throw new Error(`SQL execution failed after retries: ${error.message}`);
331
+ }
332
+ }
333
+
334
+ // Get database ID from list output
335
+ export async function getDatabaseId(databaseName) {
336
+ try {
337
+ const list = await listDatabases();
338
+ const lines = list.split('\n');
339
+ for (const line of lines) {
340
+ if (line.includes(databaseName)) {
341
+ const match = line.match(/([a-f0-9-]{36})/);
342
+ if (match) {
343
+ return match[1];
344
+ }
345
+ }
346
+ }
347
+ return null;
348
+ } catch (error) {
349
+ return null;
350
+ }
351
+ }
352
+
353
+ // Validate prerequisites
354
+ export async function validatePrerequisites() {
355
+ const checks = [{
356
+ name: 'Node.js',
357
+ command: 'node --version'
358
+ }, {
359
+ name: 'NPM',
360
+ command: 'npm --version'
361
+ }, {
362
+ name: 'Wrangler',
363
+ command: 'npx wrangler --version'
364
+ }];
365
+ const results = [];
366
+ for (const check of checks) {
367
+ try {
368
+ const {
369
+ stdout: version
370
+ } = await execAsync(check.command, {
371
+ encoding: 'utf8'
372
+ });
373
+ results.push({
374
+ name: check.name,
375
+ status: 'ok',
376
+ version: version.trim()
377
+ });
378
+ } catch (error) {
379
+ results.push({
380
+ name: check.name,
381
+ status: 'failed',
382
+ error: error.message
383
+ });
384
+ }
385
+ }
386
+ return results;
387
+ }