@tamyla/clodo-framework 3.1.10 → 3.1.12

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