@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,35 @@
1
+ /**
2
+ * Test-compatible __dirname utility
3
+ * Handles both ESM (import.meta.url) and CommonJS (__dirname) environments
4
+ */
5
+ import { fileURLToPath } from 'url';
6
+ import path from 'path';
7
+ export function getDirname(importMetaUrl) {
8
+ // In test environment (CommonJS), use __dirname if available
9
+ if (typeof __dirname !== 'undefined') {
10
+ return __dirname;
11
+ }
12
+
13
+ // In ESM environment, use import.meta.url
14
+ if (importMetaUrl) {
15
+ const __filename = fileURLToPath(importMetaUrl);
16
+ return path.dirname(__filename);
17
+ }
18
+
19
+ // Fallback
20
+ return process.cwd();
21
+ }
22
+ export function getFilename(importMetaUrl) {
23
+ // In test environment (CommonJS), use __filename if available
24
+ if (typeof __filename !== 'undefined') {
25
+ return __filename;
26
+ }
27
+
28
+ // In ESM environment, use import.meta.url
29
+ if (importMetaUrl) {
30
+ return fileURLToPath(importMetaUrl);
31
+ }
32
+
33
+ // Fallback
34
+ return '';
35
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Domain Configuration Schema Utilities
3
+ * Provides schema creation and validation for domain configurations
4
+ */
5
+
6
+ /**
7
+ * Create a domain configuration schema with validation rules
8
+ * @param {Object} options - Schema configuration options
9
+ * @returns {Object} Domain configuration schema
10
+ */
11
+ export function createDomainConfigSchema(options = {}) {
12
+ const defaultSchema = {
13
+ type: 'object',
14
+ properties: {
15
+ domains: {
16
+ type: 'array',
17
+ items: {
18
+ type: 'object',
19
+ properties: {
20
+ name: {
21
+ type: 'string',
22
+ minLength: 1
23
+ },
24
+ domain: {
25
+ type: 'string',
26
+ pattern: '^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\\.[a-zA-Z]{2,}$'
27
+ },
28
+ accountId: {
29
+ type: 'string',
30
+ minLength: 1
31
+ },
32
+ zoneId: {
33
+ type: 'string',
34
+ minLength: 1
35
+ },
36
+ environment: {
37
+ type: 'string',
38
+ enum: ['development', 'staging', 'production']
39
+ },
40
+ ssl: {
41
+ type: 'boolean'
42
+ },
43
+ cors: {
44
+ type: 'boolean'
45
+ }
46
+ },
47
+ required: ['name', 'domain', 'environment'],
48
+ additionalProperties: false
49
+ },
50
+ minItems: 1
51
+ }
52
+ },
53
+ required: ['domains'],
54
+ additionalProperties: false,
55
+ ...options
56
+ };
57
+ return {
58
+ schema: defaultSchema,
59
+ validate: function (data) {
60
+ const errors = [];
61
+ if (!data || typeof data !== 'object') {
62
+ errors.push({
63
+ field: 'root',
64
+ message: 'Data must be an object'
65
+ });
66
+ return {
67
+ valid: false,
68
+ errors
69
+ };
70
+ }
71
+ if (!Array.isArray(data.domains)) {
72
+ errors.push({
73
+ field: 'domains',
74
+ message: 'Domains must be an array'
75
+ });
76
+ return {
77
+ valid: false,
78
+ errors
79
+ };
80
+ }
81
+ if (data.domains.length === 0) {
82
+ errors.push({
83
+ field: 'domains',
84
+ message: 'At least one domain is required'
85
+ });
86
+ return {
87
+ valid: false,
88
+ errors
89
+ };
90
+ }
91
+ data.domains.forEach((domain, index) => {
92
+ if (!domain.name) {
93
+ errors.push({
94
+ field: `domains[${index}].name`,
95
+ message: 'Domain name is required'
96
+ });
97
+ }
98
+ if (!domain.domain) {
99
+ errors.push({
100
+ field: `domains[${index}].domain`,
101
+ message: 'Domain URL is required'
102
+ });
103
+ } else if (!/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.[a-zA-Z]{2,}$/.test(domain.domain)) {
104
+ errors.push({
105
+ field: `domains[${index}].domain`,
106
+ message: 'Invalid domain format'
107
+ });
108
+ }
109
+ if (!domain.environment) {
110
+ errors.push({
111
+ field: `domains[${index}].environment`,
112
+ message: 'Environment is required'
113
+ });
114
+ } else if (!['development', 'staging', 'production'].includes(domain.environment)) {
115
+ errors.push({
116
+ field: `domains[${index}].environment`,
117
+ message: 'Environment must be development, staging, or production'
118
+ });
119
+ }
120
+ });
121
+ return {
122
+ valid: errors.length === 0,
123
+ errors
124
+ };
125
+ }
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Validate domain configuration data
131
+ * @param {Object} data - Domain configuration data to validate
132
+ * @param {Object} schema - Optional custom schema
133
+ * @returns {Object} Validation result
134
+ */
135
+ export function validateDomainConfig(data, schema = null) {
136
+ const configSchema = schema || createDomainConfigSchema();
137
+ return configSchema.validate(data);
138
+ }
139
+
140
+ /**
141
+ * Create a default domain configuration
142
+ * @param {string} serviceName - Name of the service
143
+ * @param {string} domainName - Primary domain name
144
+ * @param {string} environment - Target environment
145
+ * @returns {Object} Default domain configuration
146
+ */
147
+ export function createDefaultDomainConfig(serviceName, domainName, environment = 'development') {
148
+ return {
149
+ domains: [{
150
+ name: serviceName,
151
+ domain: domainName,
152
+ accountId: 'your-account-id',
153
+ zoneId: 'your-zone-id',
154
+ environment,
155
+ ssl: true,
156
+ cors: environment !== 'production'
157
+ }]
158
+ };
159
+ }
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Error Recovery Module
3
+ * Implements circuit breakers, retries, and graceful degradation
4
+ */
5
+
6
+ export class ErrorRecoveryManager {
7
+ constructor(options = {}) {
8
+ this.options = options;
9
+ this.config = null;
10
+ this.circuitStates = new Map(); // service -> { failures, lastFailure, state }
11
+ this.retryStates = new Map(); // operation -> retry count
12
+ }
13
+
14
+ /**
15
+ * Initialize with framework configuration
16
+ */
17
+ async initialize() {
18
+ // Import framework config for consistent timing and retry settings
19
+ const {
20
+ frameworkConfig
21
+ } = await import('./framework-config.js');
22
+ const timing = frameworkConfig.getTiming();
23
+ this.config = {
24
+ maxRetries: this.options.maxRetries || timing.retryAttempts,
25
+ retryDelay: this.options.retryDelay || timing.retryDelay,
26
+ circuitBreakerThreshold: this.options.circuitBreakerThreshold || timing.circuitBreakerThreshold,
27
+ circuitBreakerTimeout: this.options.circuitBreakerTimeout || timing.circuitBreakerTimeout,
28
+ gracefulDegradation: this.options.gracefulDegradation !== false,
29
+ ...this.options
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Execute operation with error recovery
35
+ */
36
+ async executeWithRecovery(operation, options = {}) {
37
+ const config = {
38
+ ...this.config,
39
+ ...options
40
+ };
41
+ const operationId = this.getOperationId(operation);
42
+
43
+ // Check circuit breaker
44
+ if (this.isCircuitOpen(operationId)) {
45
+ if (config.gracefulDegradation) {
46
+ return this.executeGracefulFallback(operation, config);
47
+ }
48
+ throw new Error(`Circuit breaker open for operation: ${operationId}`);
49
+ }
50
+ let lastError;
51
+ for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
52
+ try {
53
+ const result = await operation();
54
+ this.recordSuccess(operationId);
55
+ return result;
56
+ } catch (error) {
57
+ lastError = error;
58
+ this.recordFailure(operationId, error);
59
+ if (attempt < config.maxRetries) {
60
+ const delay = this.calculateRetryDelay(attempt, config.retryDelay);
61
+ await this.delay(delay);
62
+ }
63
+ }
64
+ }
65
+
66
+ // All retries exhausted
67
+ if (config.gracefulDegradation) {
68
+ return this.executeGracefulFallback(operation, config);
69
+ }
70
+ throw lastError;
71
+ }
72
+
73
+ /**
74
+ * Check if circuit breaker is open
75
+ */
76
+ isCircuitOpen(operationId) {
77
+ const state = this.circuitStates.get(operationId);
78
+ if (!state) return false;
79
+ if (state.state === 'open') {
80
+ // Check if timeout has passed
81
+ if (Date.now() - state.lastFailure > this.config.circuitBreakerTimeout) {
82
+ state.state = 'half-open';
83
+ state.failures = 0;
84
+ return false;
85
+ }
86
+ return true;
87
+ }
88
+ return false;
89
+ }
90
+
91
+ /**
92
+ * Record operation success
93
+ */
94
+ recordSuccess(operationId) {
95
+ const state = this.circuitStates.get(operationId);
96
+ if (state) {
97
+ if (state.state === 'half-open') {
98
+ state.state = 'closed';
99
+ state.failures = 0;
100
+ }
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Record operation failure
106
+ */
107
+ recordFailure(operationId, error) {
108
+ let state = this.circuitStates.get(operationId);
109
+ if (!state) {
110
+ state = {
111
+ failures: 0,
112
+ lastFailure: 0,
113
+ state: 'closed'
114
+ };
115
+ this.circuitStates.set(operationId, state);
116
+ }
117
+ state.failures++;
118
+ state.lastFailure = Date.now();
119
+ if (state.failures >= this.config.circuitBreakerThreshold) {
120
+ state.state = 'open';
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Calculate retry delay with exponential backoff
126
+ */
127
+ calculateRetryDelay(attempt, baseDelay) {
128
+ const exponentialDelay = baseDelay * Math.pow(2, attempt);
129
+ const jitter = Math.random() * 0.1 * exponentialDelay;
130
+ return Math.min(exponentialDelay + jitter, 30000); // Max 30 seconds
131
+ }
132
+
133
+ /**
134
+ * Execute graceful fallback
135
+ */
136
+ async executeGracefulFallback(operation, config) {
137
+ console.warn(`Executing graceful fallback for operation`);
138
+
139
+ // Try to execute with reduced functionality
140
+ try {
141
+ // For deployment operations, try a simplified version
142
+ if (operation.name && operation.name.includes('deploy')) {
143
+ return {
144
+ success: false,
145
+ degraded: true,
146
+ message: 'Operation executed in degraded mode'
147
+ };
148
+ }
149
+
150
+ // For data operations, return cached or default data
151
+ if (operation.name && operation.name.includes('fetch')) {
152
+ return {
153
+ data: [],
154
+ cached: true,
155
+ degraded: true
156
+ };
157
+ }
158
+
159
+ // Default fallback
160
+ return {
161
+ success: false,
162
+ degraded: true,
163
+ fallback: true
164
+ };
165
+ } catch (fallbackError) {
166
+ console.error('Graceful fallback also failed:', fallbackError);
167
+ throw fallbackError;
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Get unique operation ID
173
+ */
174
+ getOperationId(operation) {
175
+ if (typeof operation === 'function' && operation.name) {
176
+ return operation.name;
177
+ }
178
+ return `operation_${Date.now()}_${Math.random()}`;
179
+ }
180
+
181
+ /**
182
+ * Utility delay function
183
+ */
184
+ delay(ms) {
185
+ return new Promise(resolve => setTimeout(resolve, ms));
186
+ }
187
+
188
+ /**
189
+ * Get circuit breaker status
190
+ */
191
+ getCircuitStatus(operationId) {
192
+ const state = this.circuitStates.get(operationId);
193
+ if (!state) {
194
+ return {
195
+ state: 'closed',
196
+ failures: 0
197
+ };
198
+ }
199
+ return {
200
+ state: state.state,
201
+ failures: state.failures,
202
+ lastFailure: state.lastFailure,
203
+ timeSinceLastFailure: Date.now() - state.lastFailure
204
+ };
205
+ }
206
+
207
+ /**
208
+ * Reset circuit breaker
209
+ */
210
+ resetCircuit(operationId) {
211
+ this.circuitStates.delete(operationId);
212
+ }
213
+
214
+ /**
215
+ * Get all circuit statuses
216
+ */
217
+ getAllCircuitStatuses() {
218
+ const statuses = {};
219
+ for (const [operationId, state] of this.circuitStates) {
220
+ statuses[operationId] = this.getCircuitStatus(operationId);
221
+ }
222
+ return statuses;
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Retry wrapper for functions
228
+ */
229
+ export function withRetry(fn, options = {}) {
230
+ const recovery = new ErrorRecoveryManager(options);
231
+ return (...args) => recovery.executeWithRecovery(() => fn(...args), options);
232
+ }
233
+
234
+ /**
235
+ * Circuit breaker wrapper for functions
236
+ */
237
+ export function withCircuitBreaker(fn, options = {}) {
238
+ const recovery = new ErrorRecoveryManager(options);
239
+ return (...args) => recovery.executeWithRecovery(() => fn(...args), options);
240
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * ESM Helper - Provides __dirname and __filename for ES modules
3
+ * Handles both normal ESM environment and test environment transformation
4
+ */
5
+
6
+ import { fileURLToPath } from 'url';
7
+ import { dirname, join } from 'path';
8
+
9
+ /**
10
+ * Get __filename and __dirname for current module
11
+ * @param {string} importMetaUrl - import.meta.url from calling module
12
+ * @param {string} fallbackPath - fallback path relative to project root for tests
13
+ * @returns {Object} - {__filename, __dirname}
14
+ */
15
+ export function getFileInfo(importMetaUrl, fallbackPath) {
16
+ try {
17
+ const __filename = fileURLToPath(importMetaUrl);
18
+ const __dirname = dirname(__filename);
19
+ return {
20
+ __filename,
21
+ __dirname
22
+ };
23
+ } catch (error) {
24
+ // Fallback for test environment where import.meta is transformed
25
+ const __dirname = join(process.cwd(), fallbackPath);
26
+ const __filename = join(__dirname, 'index.js'); // Generic filename
27
+ return {
28
+ __filename,
29
+ __dirname
30
+ };
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Get just __dirname for current module
36
+ * @param {string} importMetaUrl - import.meta.url from calling module
37
+ * @param {string} fallbackPath - fallback path relative to project root for tests
38
+ * @returns {string} - __dirname
39
+ */
40
+ export function getDirname(importMetaUrl, fallbackPath) {
41
+ return getFileInfo(importMetaUrl, fallbackPath).__dirname;
42
+ }
43
+
44
+ /**
45
+ * Get just __filename for current module
46
+ * @param {string} importMetaUrl - import.meta.url from calling module
47
+ * @param {string} fallbackPath - fallback path relative to project root for tests
48
+ * @returns {string} - __filename
49
+ */
50
+ export function getFilename(importMetaUrl, fallbackPath) {
51
+ return getFileInfo(importMetaUrl, fallbackPath).__filename;
52
+ }