@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,293 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Customer Configuration Management CLI
5
+ * Manages multi-environment, multi-customer configuration structure
6
+ * Integrates with Clodo Framework domain and feature flag systems
7
+ */
8
+
9
+ import { CustomerConfigCLI } from '../../../src/config/CustomerConfigCLI.js';
10
+
11
+ const command = process.argv[2];
12
+ const args = process.argv.slice(3);
13
+
14
+ async function main() {
15
+ const cli = new CustomerConfigCLI();
16
+ await cli.initialize();
17
+
18
+ try {
19
+ switch (command) {
20
+ case 'create-customer':
21
+ const [customerName, domain] = args;
22
+ const result = await cli.createCustomer(customerName, domain);
23
+ if (result.success) {
24
+ console.log(`\n🎉 Customer ${customerName} configuration created successfully!`);
25
+ console.log(`\n📋 Customer Details:`);
26
+ console.log(` Name: ${result.customer.name}`);
27
+ console.log(` Domain: ${result.customer.domain || 'Not specified'}`);
28
+ console.log(` Config Path: ${result.customer.configPath}`);
29
+ console.log(` Environments: ${result.customer.environments.join(', ')}`);
30
+ console.log(`\n📋 Next steps:`);
31
+ console.log(`1. Review generated configs in: config/customers/${customerName}/`);
32
+ console.log(`2. Update domain-specific URLs if needed`);
33
+ console.log(`3. Generate production secrets: npm run security:generate-key ${customerName}`);
34
+ console.log(`4. Set production secrets: wrangler secret put KEY_NAME --env production`);
35
+ } else {
36
+ console.error(`❌ Failed to create customer: ${result.error}`);
37
+ process.exit(1);
38
+ }
39
+ break;
40
+
41
+ case 'validate':
42
+ const validateResult = await cli.validateConfigurations();
43
+ if (validateResult.valid) {
44
+ console.log('✅ All customer configurations are valid');
45
+ } else {
46
+ console.log('❌ Configuration validation failed');
47
+ validateResult.errors.forEach(error => console.log(` - ${error}`));
48
+ process.exit(1);
49
+ }
50
+ break;
51
+
52
+ case 'show':
53
+ const [customerNameShow, environment] = args;
54
+ const showResult = cli.showConfiguration(customerNameShow, environment);
55
+ if (showResult.success) {
56
+ console.log(`🔍 Effective configuration: ${customerNameShow}/${environment}\n`);
57
+ if (showResult.config.variables?.base) {
58
+ console.log('📋 Base variables:');
59
+ Object.entries(showResult.config.variables.base).slice(0, 10).forEach(([key, value]) => {
60
+ console.log(` ${key}=${value}`);
61
+ });
62
+ if (Object.keys(showResult.config.variables.base).length > 10) {
63
+ console.log(' ...');
64
+ }
65
+ console.log('');
66
+ }
67
+ if (showResult.config.variables?.customer) {
68
+ console.log(`📋 Customer ${environment} variables:`);
69
+ Object.entries(showResult.config.variables.customer).slice(0, 15).forEach(([key, value]) => {
70
+ console.log(` ${key}=${value}`);
71
+ });
72
+ if (Object.keys(showResult.config.variables.customer).length > 15) {
73
+ console.log(' ...');
74
+ }
75
+ console.log('');
76
+ }
77
+ if (showResult.config.features && Object.keys(showResult.config.features).length > 0) {
78
+ console.log('🚩 Customer features:');
79
+ Object.entries(showResult.config.features).forEach(([feature, enabled]) => {
80
+ console.log(` ${feature}: ${enabled ? '✅' : '❌'}`);
81
+ });
82
+ }
83
+ } else {
84
+ console.error(`❌ Failed to show configuration: ${showResult.error}`);
85
+ process.exit(1);
86
+ }
87
+ break;
88
+
89
+ case 'deploy-command':
90
+ const [customerNameDeploy, environmentDeploy] = args;
91
+ const deployResult = cli.getDeployCommand(customerNameDeploy, environmentDeploy);
92
+ if (deployResult.success) {
93
+ console.log(`📋 Deploy command for ${customerNameDeploy}/${environmentDeploy}:`);
94
+ console.log(` ${deployResult.command}`);
95
+ console.log(`\n💡 Ensure customer config is loaded: ${deployResult.configPath}`);
96
+ } else {
97
+ console.error(`❌ Failed to get deploy command: ${deployResult.error}`);
98
+ process.exit(1);
99
+ }
100
+ break;
101
+
102
+ case 'list':
103
+ const listResult = cli.listCustomers();
104
+ if (listResult.success && listResult.customers.length > 0) {
105
+ console.log('📋 Configured customers:\n');
106
+ listResult.customers.forEach(customer => {
107
+ console.log(`🏢 ${customer.name}`);
108
+ console.log(` Domain: ${customer.domain || 'Not specified'}`);
109
+ console.log(` Environments: ${customer.environments.join(', ')}`);
110
+ console.log(` Created: ${customer.createdAt}`);
111
+ console.log(` Config: config/customers/${customer.name}/`);
112
+ console.log('');
113
+ });
114
+ } else if (listResult.success) {
115
+ console.log('📋 No customers configured');
116
+ } else {
117
+ console.error(`❌ Failed to list customers: ${listResult.error}`);
118
+ process.exit(1);
119
+ }
120
+ break;
121
+
122
+ default:
123
+ console.log('Customer Configuration Management Tool\n');
124
+ console.log('Available commands:');
125
+ console.log(' create-customer <name> [domain] - Create new customer config from template');
126
+ console.log(' validate - Validate configuration structure');
127
+ console.log(' show <customer> <environment> - Show effective configuration');
128
+ console.log(' deploy-command <customer> <env> - Get deployment command');
129
+ console.log(' list - List all configured customers');
130
+ console.log('\nExamples:');
131
+ console.log(' clodo-customer-config create-customer acmecorp acmecorp.com');
132
+ console.log(' clodo-customer-config validate');
133
+ console.log(' clodo-customer-config show acmecorp production');
134
+ console.log(' clodo-customer-config list');
135
+ console.log('\nIntegration:');
136
+ console.log(' This tool integrates with Clodo Framework domain and feature flag systems.');
137
+ console.log(' Customer configurations are automatically registered as domains.');
138
+ break;
139
+ }
140
+ } catch (error) {
141
+ console.error(`❌ Error: ${error.message}`);
142
+ process.exit(1);
143
+ }
144
+ }
145
+
146
+ main().catch(error => {
147
+ console.error(`❌ Unexpected error: ${error.message}`);
148
+ process.exit(1);
149
+ });
150
+
151
+ async function handleCreateCustomer(args) {
152
+ const [customerName, domain] = args;
153
+
154
+ if (!customerName) {
155
+ console.error('Usage: customer-config create-customer <customer-name> [domain]');
156
+ process.exit(1);
157
+ }
158
+
159
+ console.log(`🏗️ Creating customer configuration: ${customerName}`);
160
+
161
+ // Pass framework mode flag to skip strict validation
162
+ const customerInfo = await customerManager.createCustomer(customerName, domain, {
163
+ skipValidation: true,
164
+ isFrameworkMode: true
165
+ });
166
+
167
+ console.log(`\n🎉 Customer ${customerName} configuration created successfully!`);
168
+ console.log(`\n📋 Customer Details:`);
169
+ console.log(` Name: ${customerInfo.name}`);
170
+ console.log(` Domain: ${customerInfo.domain || 'Not specified'}`);
171
+ console.log(` Config Path: ${customerInfo.configPath}`);
172
+ console.log(` Environments: ${customerInfo.environments.join(', ')}`);
173
+
174
+ console.log(`\n📋 Next steps:`);
175
+ console.log(`1. Review generated configs in: config/customers/${customerName}/`);
176
+ console.log(`2. Update domain-specific URLs if needed`);
177
+ console.log(`3. Generate production secrets: npm run security:generate-key ${customerName}`);
178
+ console.log(`4. Set production secrets: wrangler secret put KEY_NAME --env production`);
179
+ }
180
+
181
+ async function handleValidate() {
182
+ console.log('🔍 Validating customer configuration structure...\n');
183
+
184
+ const result = await customerManager.validateConfigs();
185
+
186
+ if (result.valid) {
187
+ console.log('✅ All customer configurations are valid');
188
+ } else {
189
+ console.log('❌ Configuration validation failed');
190
+ result.errors.forEach(error => console.log(` - ${error}`));
191
+ process.exit(1);
192
+ }
193
+ }
194
+
195
+ async function handleShow(args) {
196
+ const [customerName, environment] = args;
197
+
198
+ if (!customerName || !environment) {
199
+ console.error('Usage: customer-config show <customer> <environment>');
200
+ process.exit(1);
201
+ }
202
+
203
+ const config = customerManager.showConfig(customerName, environment);
204
+
205
+ console.log(`🔍 Effective configuration: ${customerName}/${environment}\n`);
206
+
207
+ if (config.variables.base) {
208
+ console.log('📋 Base variables:');
209
+ Object.entries(config.variables.base).slice(0, 10).forEach(([key, value]) => {
210
+ console.log(` ${key}=${value}`);
211
+ });
212
+ if (Object.keys(config.variables.base).length > 10) {
213
+ console.log(' ...');
214
+ }
215
+ console.log('');
216
+ }
217
+
218
+ if (config.variables.customer) {
219
+ console.log(`📋 Customer ${environment} variables:`);
220
+ Object.entries(config.variables.customer).slice(0, 15).forEach(([key, value]) => {
221
+ console.log(` ${key}=${value}`);
222
+ });
223
+ if (Object.keys(config.variables.customer).length > 15) {
224
+ console.log(' ...');
225
+ }
226
+ console.log('');
227
+ }
228
+
229
+ if (config.features && Object.keys(config.features).length > 0) {
230
+ console.log('🚩 Customer features:');
231
+ Object.entries(config.features).forEach(([feature, enabled]) => {
232
+ console.log(` ${feature}: ${enabled ? '✅' : '❌'}`);
233
+ });
234
+ }
235
+ }
236
+
237
+ async function handleDeployCommand(args) {
238
+ const [customerName, environment] = args;
239
+
240
+ if (!customerName || !environment) {
241
+ console.error('Usage: customer-config deploy-command <customer> <environment>');
242
+ process.exit(1);
243
+ }
244
+
245
+ const deployInfo = customerManager.getDeployCommand(customerName, environment);
246
+
247
+ console.log(`📋 Deploy command for ${customerName}/${environment}:`);
248
+ console.log(` ${deployInfo.command}`);
249
+ console.log(`\n💡 Ensure customer config is loaded: ${deployInfo.configPath}`);
250
+ }
251
+
252
+ async function handleList() {
253
+ const customers = customerManager.listCustomers();
254
+
255
+ if (customers.length === 0) {
256
+ console.log('📋 No customers configured');
257
+ return;
258
+ }
259
+
260
+ console.log('📋 Configured customers:\n');
261
+
262
+ customers.forEach(customer => {
263
+ console.log(`🏢 ${customer.name}`);
264
+ console.log(` Domain: ${customer.domain || 'Not specified'}`);
265
+ console.log(` Environments: ${customer.environments.join(', ')}`);
266
+ console.log(` Created: ${customer.createdAt}`);
267
+ console.log(` Config: config/customers/${customer.name}/`);
268
+ console.log('');
269
+ });
270
+ }
271
+
272
+ function showHelp() {
273
+ console.log('Customer Configuration Management Tool\n');
274
+ console.log('Available commands:');
275
+ console.log(' create-customer <name> [domain] - Create new customer config from template');
276
+ console.log(' validate - Validate configuration structure');
277
+ console.log(' show <customer> <environment> - Show effective configuration');
278
+ console.log(' deploy-command <customer> <env> - Get deployment command');
279
+ console.log(' list - List all configured customers');
280
+ console.log('\nExamples:');
281
+ console.log(' customer-config create-customer acmecorp acmecorp.com');
282
+ console.log(' customer-config validate');
283
+ console.log(' customer-config show acmecorp production');
284
+ console.log(' customer-config list');
285
+ console.log('\nIntegration:');
286
+ console.log(' This tool integrates with Clodo Framework domain and feature flag systems.');
287
+ console.log(' Customer configurations are automatically registered as domains.');
288
+ }
289
+
290
+ main().catch(error => {
291
+ console.error(`❌ Unexpected error: ${error.message}`);
292
+ process.exit(1);
293
+ });
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Interactive Deployment Configuration Manager
3
+ * User input-driven configuration setup for deployment workflows
4
+ */
5
+
6
+ import { askChoice, askUser } from '../utils/deployment/interactive-prompts.js';
7
+ export class InteractiveDeploymentConfigurator {
8
+ /**
9
+ * Generate configuration from user input
10
+ * @param {Object} defaults - Default values
11
+ * @returns {Promise<Object>} User-configured settings
12
+ */
13
+ static async generateFromUserInput(defaults = {}) {
14
+ console.log('🔧 Configuration Setup');
15
+ console.log('======================');
16
+ const config = {
17
+ ...defaults
18
+ };
19
+
20
+ // Environment selection
21
+ config.environment = await askChoice('Select deployment environment:', ['development', 'staging', 'production'], 2 // Default to production
22
+ );
23
+
24
+ // Customer/domain input
25
+ config.customer = await askUser('Enter customer name:', defaults.customer || '');
26
+ config.domain = await askUser('Enter domain:', defaults.domain || '');
27
+
28
+ // Security settings
29
+ config.enableSecurityValidation = (await askChoice('Enable security validation?', ['yes', 'no'], 0)) === 'yes';
30
+
31
+ // Deployment options
32
+ config.runTests = (await askChoice('Run post-deployment tests?', ['yes', 'no'], 0)) === 'yes';
33
+
34
+ // Additional deployment settings
35
+ config.dryRun = (await askChoice('Perform dry run first?', ['yes', 'no'], 1 // Default to no
36
+ )) === 'yes';
37
+ config.allowInsecure = (await askChoice('Allow insecure deployment (not recommended)?', ['yes', 'no'], 1 // Default to no
38
+ )) === 'yes';
39
+ return config;
40
+ }
41
+
42
+ /**
43
+ * Validate user-provided configuration
44
+ * @param {Object} config - Configuration to validate
45
+ * @returns {Object} Validation result
46
+ */
47
+ static validateConfiguration(config) {
48
+ const errors = [];
49
+ const warnings = [];
50
+ if (!config.customer) {
51
+ errors.push('Customer name is required');
52
+ } else if (config.customer.length < 2) {
53
+ errors.push('Customer name must be at least 2 characters');
54
+ }
55
+ if (!config.domain) {
56
+ errors.push('Domain is required');
57
+ } else if (!this.isValidDomain(config.domain)) {
58
+ errors.push('Domain format is invalid');
59
+ }
60
+ if (!['development', 'staging', 'production'].includes(config.environment)) {
61
+ errors.push('Invalid environment selection');
62
+ }
63
+
64
+ // Warnings for potentially risky settings
65
+ if (config.allowInsecure) {
66
+ warnings.push('Insecure deployment allowed - security validations will be bypassed');
67
+ }
68
+ if (!config.enableSecurityValidation) {
69
+ warnings.push('Security validation disabled - deployment may be vulnerable');
70
+ }
71
+ return {
72
+ valid: errors.length === 0,
73
+ errors,
74
+ warnings,
75
+ hasWarnings: warnings.length > 0
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Validate domain format
81
+ * @param {string} domain - Domain to validate
82
+ * @returns {boolean} True if valid domain format
83
+ */
84
+ static isValidDomain(domain) {
85
+ // Basic domain validation regex
86
+ const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
87
+ return domainRegex.test(domain);
88
+ }
89
+
90
+ /**
91
+ * Generate deployment URL from configuration
92
+ * @param {Object} config - Configuration object
93
+ * @returns {string} Generated deployment URL
94
+ */
95
+ static generateDeploymentUrl(config) {
96
+ const {
97
+ customer,
98
+ environment,
99
+ domain
100
+ } = config;
101
+ if (domain) {
102
+ return `https://${customer}.${domain}`;
103
+ }
104
+
105
+ // Fallback to Cloudflare Workers pattern
106
+ return `https://${customer}-${environment}.workers.dev`;
107
+ }
108
+
109
+ /**
110
+ * Create deployment configuration summary
111
+ * @param {Object} config - Configuration object
112
+ * @returns {string} Formatted configuration summary
113
+ */
114
+ static createConfigurationSummary(config) {
115
+ const lines = ['📋 Deployment Configuration Summary', '====================================', '', `👤 Customer: ${config.customer}`, `🌍 Environment: ${config.environment}`, `🔗 Domain: ${config.domain || 'Auto-generated'}`, `🔒 Security Validation: ${config.enableSecurityValidation ? 'Enabled' : 'Disabled'}`, `🧪 Post-deployment Tests: ${config.runTests ? 'Enabled' : 'Disabled'}`, `🧪 Dry Run: ${config.dryRun ? 'Yes' : 'No'}`, `⚠️ Allow Insecure: ${config.allowInsecure ? 'Yes' : 'No'}`, '', `🚀 Deployment URL: ${this.generateDeploymentUrl(config)}`];
116
+ return lines.join('\n');
117
+ }
118
+
119
+ /**
120
+ * Interactive configuration wizard
121
+ * @param {Object} defaults - Default configuration values
122
+ * @returns {Promise<Object>} Complete configuration object
123
+ */
124
+ static async runConfigurationWizard(defaults = {}) {
125
+ console.log('\n🚀 CLODO Framework Deployment Configuration Wizard');
126
+ console.log('================================================\n');
127
+ let config;
128
+ let isValid = false;
129
+ do {
130
+ config = await this.generateFromUserInput(defaults);
131
+ const validation = this.validateConfiguration(config);
132
+ if (!validation.valid) {
133
+ console.log('\n❌ Configuration Validation Failed:');
134
+ validation.errors.forEach(error => console.log(` - ${error}`));
135
+ console.log('\nPlease correct the errors and try again.\n');
136
+ continue;
137
+ }
138
+ if (validation.hasWarnings) {
139
+ console.log('\n⚠️ Configuration Warnings:');
140
+ validation.warnings.forEach(warning => console.log(` - ${warning}`));
141
+ const proceed = await askChoice('\nProceed with deployment despite warnings?', ['yes', 'no'], 1 // Default to no
142
+ );
143
+ if (proceed === 'no') {
144
+ console.log('Configuration cancelled. Please adjust settings.\n');
145
+ continue;
146
+ }
147
+ }
148
+ isValid = true;
149
+ } while (!isValid);
150
+ console.log('\n✅ Configuration Complete!');
151
+ console.log(this.createConfigurationSummary(config));
152
+ const confirm = await askChoice('\nDeploy with this configuration?', ['yes', 'no'], 0 // Default to yes
153
+ );
154
+ if (confirm === 'no') {
155
+ throw new Error('Deployment cancelled by user');
156
+ }
157
+ return config;
158
+ }
159
+ }
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Clodo Framework - Customer Configuration CLI
3
+ * Programmatic API for customer configuration management
4
+ */
5
+
6
+ import { CustomerConfigurationManager } from '../config/customers.js';
7
+ export class CustomerConfigCLI {
8
+ constructor() {
9
+ this.customerManager = new CustomerConfigurationManager();
10
+ }
11
+
12
+ /**
13
+ * Initialize the customer manager by loading existing customers
14
+ * @returns {Promise<Object>} Initialization result
15
+ */
16
+ async initialize() {
17
+ try {
18
+ await this.customerManager.loadExistingCustomers();
19
+ return {
20
+ success: true,
21
+ message: 'Customer manager initialized successfully'
22
+ };
23
+ } catch (error) {
24
+ return {
25
+ success: false,
26
+ error: error.message
27
+ };
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Create a new customer configuration
33
+ * @param {string} customerName - Customer name
34
+ * @param {string} domain - Customer domain (optional)
35
+ * @param {Object} options - Creation options
36
+ * @returns {Promise<Object>} Creation result
37
+ */
38
+ async createCustomer(customerName, domain, options = {}) {
39
+ try {
40
+ if (!customerName) {
41
+ throw new Error('Customer name is required');
42
+ }
43
+ const customerInfo = await this.customerManager.createCustomer(customerName, domain, {
44
+ skipValidation: true,
45
+ isFrameworkMode: true,
46
+ ...options
47
+ });
48
+ return {
49
+ success: true,
50
+ customer: customerInfo
51
+ };
52
+ } catch (error) {
53
+ return {
54
+ success: false,
55
+ customerName,
56
+ error: error.message
57
+ };
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Validate customer configuration structure
63
+ * @returns {Promise<Object>} Validation result
64
+ */
65
+ async validateConfigurations() {
66
+ try {
67
+ const result = await this.customerManager.validateConfigs();
68
+ return {
69
+ success: result.valid,
70
+ valid: result.valid,
71
+ errors: result.errors || []
72
+ };
73
+ } catch (error) {
74
+ return {
75
+ success: false,
76
+ error: error.message
77
+ };
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Show effective configuration for a customer and environment
83
+ * @param {string} customerName - Customer name
84
+ * @param {string} environment - Environment name
85
+ * @returns {Object} Configuration display result
86
+ */
87
+ showConfiguration(customerName, environment) {
88
+ try {
89
+ if (!customerName || !environment) {
90
+ throw new Error('Customer name and environment are required');
91
+ }
92
+ const config = this.customerManager.showConfig(customerName, environment);
93
+ return {
94
+ success: true,
95
+ customer: customerName,
96
+ environment,
97
+ config
98
+ };
99
+ } catch (error) {
100
+ return {
101
+ success: false,
102
+ customer: customerName,
103
+ environment,
104
+ error: error.message
105
+ };
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Get deployment command for a customer and environment
111
+ * @param {string} customerName - Customer name
112
+ * @param {string} environment - Environment name
113
+ * @returns {Object} Deployment command result
114
+ */
115
+ getDeployCommand(customerName, environment) {
116
+ try {
117
+ if (!customerName || !environment) {
118
+ throw new Error('Customer name and environment are required');
119
+ }
120
+ const deployInfo = this.customerManager.getDeployCommand(customerName, environment);
121
+ return {
122
+ success: true,
123
+ customer: customerName,
124
+ environment,
125
+ command: deployInfo.command,
126
+ configPath: deployInfo.configPath
127
+ };
128
+ } catch (error) {
129
+ return {
130
+ success: false,
131
+ customer: customerName,
132
+ environment,
133
+ error: error.message
134
+ };
135
+ }
136
+ }
137
+
138
+ /**
139
+ * List all configured customers
140
+ * @returns {Object} Customer list result
141
+ */
142
+ listCustomers() {
143
+ try {
144
+ const customers = this.customerManager.listCustomers();
145
+ return {
146
+ success: true,
147
+ customers
148
+ };
149
+ } catch (error) {
150
+ return {
151
+ success: false,
152
+ error: error.message
153
+ };
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Get available commands
159
+ * @returns {string[]} Array of available commands
160
+ */
161
+ getAvailableCommands() {
162
+ return ['create-customer', 'validate', 'show', 'deploy-command', 'list'];
163
+ }
164
+
165
+ /**
166
+ * Get command help
167
+ * @param {string} command - Command name (optional)
168
+ * @returns {string} Help text
169
+ */
170
+ getHelp(command) {
171
+ const help = {
172
+ 'create-customer': 'create-customer <name> [domain] - Create new customer config from template',
173
+ 'validate': 'validate - Validate configuration structure',
174
+ 'show': 'show <customer> <environment> - Show effective configuration',
175
+ 'deploy-command': 'deploy-command <customer> <environment> - Get deployment command',
176
+ 'list': 'list - List all configured customers'
177
+ };
178
+ if (command && help[command]) {
179
+ return help[command];
180
+ }
181
+ return `Customer Configuration Management Tool
182
+
183
+ Available commands:
184
+ ${Object.values(help).map(cmd => ` ${cmd}`).join('\n')}
185
+
186
+ Examples:
187
+ create-customer acmecorp acmecorp.com
188
+ validate
189
+ show acmecorp production
190
+ list
191
+
192
+ Integration:
193
+ This tool integrates with Clodo Framework domain and feature flag systems.
194
+ Customer configurations are automatically registered as domains.`;
195
+ }
196
+ }
197
+
198
+ // Convenience functions for direct use
199
+ export async function createCustomer(customerName, domain, options = {}) {
200
+ const cli = new CustomerConfigCLI();
201
+ await cli.initialize();
202
+ return await cli.createCustomer(customerName, domain, options);
203
+ }
204
+ export async function validateCustomerConfigs() {
205
+ const cli = new CustomerConfigCLI();
206
+ await cli.initialize();
207
+ return await cli.validateConfigurations();
208
+ }
209
+ export function showCustomerConfig(customerName, environment) {
210
+ const cli = new CustomerConfigCLI();
211
+ return cli.showConfiguration(customerName, environment);
212
+ }
213
+ export function getCustomerDeployCommand(customerName, environment) {
214
+ const cli = new CustomerConfigCLI();
215
+ return cli.getDeployCommand(customerName, environment);
216
+ }
217
+ export function listConfiguredCustomers() {
218
+ const cli = new CustomerConfigCLI();
219
+ return cli.listCustomers();
220
+ }