@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.
- package/CHANGELOG.md +564 -0
- package/LICENSE +21 -0
- package/README.md +1393 -0
- package/bin/README.md +71 -0
- package/bin/clodo-service.js +416 -0
- package/bin/security/security-cli.js +96 -0
- package/bin/service-management/README.md +74 -0
- package/bin/service-management/create-service.js +129 -0
- package/bin/service-management/init-service.js +102 -0
- package/bin/service-management/init-service.js.backup +889 -0
- package/bin/shared/config/customer-cli.js +293 -0
- package/dist/config/ConfigurationManager.js +159 -0
- package/dist/config/CustomerConfigCLI.js +220 -0
- package/dist/config/FeatureManager.js +426 -0
- package/dist/config/customers.js +441 -0
- package/dist/config/domains.js +180 -0
- package/dist/config/features.js +225 -0
- package/dist/config/index.js +6 -0
- package/dist/database/database-orchestrator.js +730 -0
- package/dist/database/index.js +4 -0
- package/dist/deployment/auditor.js +971 -0
- package/dist/deployment/index.js +10 -0
- package/dist/deployment/rollback-manager.js +523 -0
- package/dist/deployment/testers/api-tester.js +80 -0
- package/dist/deployment/testers/auth-tester.js +129 -0
- package/dist/deployment/testers/core.js +217 -0
- package/dist/deployment/testers/database-tester.js +105 -0
- package/dist/deployment/testers/index.js +74 -0
- package/dist/deployment/testers/load-tester.js +120 -0
- package/dist/deployment/testers/performance-tester.js +105 -0
- package/dist/deployment/validator.js +558 -0
- package/dist/deployment/wrangler-deployer.js +574 -0
- package/dist/handlers/GenericRouteHandler.js +532 -0
- package/dist/index.js +39 -0
- package/dist/migration/MigrationAdapters.js +562 -0
- package/dist/modules/ModuleManager.js +668 -0
- package/dist/modules/security.js +98 -0
- package/dist/orchestration/cross-domain-coordinator.js +1083 -0
- package/dist/orchestration/index.js +5 -0
- package/dist/orchestration/modules/DeploymentCoordinator.js +258 -0
- package/dist/orchestration/modules/DomainResolver.js +196 -0
- package/dist/orchestration/modules/StateManager.js +332 -0
- package/dist/orchestration/multi-domain-orchestrator.js +255 -0
- package/dist/routing/EnhancedRouter.js +158 -0
- package/dist/schema/SchemaManager.js +778 -0
- package/dist/security/ConfigurationValidator.js +490 -0
- package/dist/security/DeploymentManager.js +208 -0
- package/dist/security/SecretGenerator.js +142 -0
- package/dist/security/SecurityCLI.js +228 -0
- package/dist/security/index.js +51 -0
- package/dist/security/patterns/environment-rules.js +66 -0
- package/dist/security/patterns/insecure-patterns.js +21 -0
- package/dist/service-management/ConfirmationEngine.js +411 -0
- package/dist/service-management/ErrorTracker.js +294 -0
- package/dist/service-management/GenerationEngine.js +3109 -0
- package/dist/service-management/InputCollector.js +237 -0
- package/dist/service-management/ServiceCreator.js +229 -0
- package/dist/service-management/ServiceInitializer.js +448 -0
- package/dist/service-management/ServiceOrchestrator.js +638 -0
- package/dist/service-management/handlers/ConfigMutator.js +130 -0
- package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
- package/dist/service-management/handlers/GenerationHandler.js +80 -0
- package/dist/service-management/handlers/InputHandler.js +59 -0
- package/dist/service-management/handlers/ValidationHandler.js +203 -0
- package/dist/service-management/index.js +7 -0
- package/dist/services/GenericDataService.js +488 -0
- package/dist/shared/cloudflare/domain-discovery.js +562 -0
- package/dist/shared/cloudflare/domain-manager.js +912 -0
- package/dist/shared/cloudflare/index.js +8 -0
- package/dist/shared/cloudflare/ops.js +387 -0
- package/dist/shared/config/cache.js +1167 -0
- package/dist/shared/config/command-config-manager.js +174 -0
- package/dist/shared/config/customer-cli.js +258 -0
- package/dist/shared/config/index.js +9 -0
- package/dist/shared/config/manager.js +289 -0
- package/dist/shared/database/connection-manager.js +338 -0
- package/dist/shared/database/index.js +7 -0
- package/dist/shared/database/orchestrator.js +632 -0
- package/dist/shared/deployment/auditor.js +971 -0
- package/dist/shared/deployment/index.js +10 -0
- package/dist/shared/deployment/rollback-manager.js +523 -0
- package/dist/shared/deployment/validator.js +558 -0
- package/dist/shared/index.js +32 -0
- package/dist/shared/monitoring/health-checker.js +250 -0
- package/dist/shared/monitoring/index.js +8 -0
- package/dist/shared/monitoring/memory-manager.js +382 -0
- package/dist/shared/monitoring/production-monitor.js +390 -0
- package/dist/shared/production-tester/api-tester.js +80 -0
- package/dist/shared/production-tester/auth-tester.js +129 -0
- package/dist/shared/production-tester/core.js +217 -0
- package/dist/shared/production-tester/database-tester.js +105 -0
- package/dist/shared/production-tester/index.js +74 -0
- package/dist/shared/production-tester/load-tester.js +120 -0
- package/dist/shared/production-tester/performance-tester.js +105 -0
- package/dist/shared/security/api-token-manager.js +296 -0
- package/dist/shared/security/index.js +8 -0
- package/dist/shared/security/secret-generator.js +918 -0
- package/dist/shared/security/secure-token-manager.js +379 -0
- package/dist/shared/utils/error-recovery.js +240 -0
- package/dist/shared/utils/graceful-shutdown-manager.js +380 -0
- package/dist/shared/utils/index.js +9 -0
- package/dist/shared/utils/interactive-prompts.js +134 -0
- package/dist/shared/utils/rate-limiter.js +249 -0
- package/dist/utils/ErrorHandler.js +173 -0
- package/dist/utils/deployment/config-cache.js +1160 -0
- package/dist/utils/deployment/index.js +6 -0
- package/dist/utils/deployment/interactive-prompts.js +97 -0
- package/dist/utils/deployment/secret-generator.js +896 -0
- package/dist/utils/dirname-helper.js +35 -0
- package/dist/utils/domain-config.js +159 -0
- package/dist/utils/error-recovery.js +240 -0
- package/dist/utils/esm-helper.js +52 -0
- package/dist/utils/framework-config.js +481 -0
- package/dist/utils/graceful-shutdown-manager.js +379 -0
- package/dist/utils/health-checker.js +114 -0
- package/dist/utils/index.js +36 -0
- package/dist/utils/prompt-handler.js +98 -0
- package/dist/utils/usage-tracker.js +252 -0
- package/dist/utils/validation.js +112 -0
- package/dist/version/VersionDetector.js +723 -0
- package/dist/worker/index.js +4 -0
- package/dist/worker/integration.js +332 -0
- package/docs/FRAMEWORK-ARCHITECTURE-OVERVIEW.md +206 -0
- package/docs/INTEGRATION_GUIDE.md +2045 -0
- package/docs/README.md +82 -0
- package/docs/SECURITY.md +242 -0
- package/docs/deployment/deployment-guide.md +540 -0
- package/docs/overview.md +280 -0
- package/package.json +176 -0
- package/types/index.d.ts +575 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Configuration Manager
|
|
3
|
+
* Loads and manages configurable system commands from validation-config.json
|
|
4
|
+
*
|
|
5
|
+
* Ensures all commands are configurable and platform-specific
|
|
6
|
+
* No hardcoded commands in the codebase
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFileSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
export class CommandConfigManager {
|
|
12
|
+
constructor(configPath = null) {
|
|
13
|
+
this.configPath = configPath || join(process.cwd(), 'validation-config.json');
|
|
14
|
+
this.config = null;
|
|
15
|
+
this.loadConfig();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Load configuration from JSON file
|
|
20
|
+
*/
|
|
21
|
+
loadConfig() {
|
|
22
|
+
try {
|
|
23
|
+
const configData = readFileSync(this.configPath, 'utf-8');
|
|
24
|
+
this.config = JSON.parse(configData);
|
|
25
|
+
console.log('š Loaded command configuration from validation-config.json');
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.log('ā ļø Could not load command config, using defaults');
|
|
28
|
+
this.config = this.getDefaultConfig();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get default configuration fallback
|
|
34
|
+
*/
|
|
35
|
+
getDefaultConfig() {
|
|
36
|
+
return {
|
|
37
|
+
requiredCommands: {
|
|
38
|
+
npx: 'npx',
|
|
39
|
+
node: 'node',
|
|
40
|
+
npm: 'npm',
|
|
41
|
+
wrangler: 'npx wrangler'
|
|
42
|
+
},
|
|
43
|
+
cloudflareCommands: {
|
|
44
|
+
whoami: 'npx wrangler whoami',
|
|
45
|
+
auth_login: 'npx wrangler auth login',
|
|
46
|
+
deployments_list: 'npx wrangler deployments list',
|
|
47
|
+
list_workers: 'npx wrangler dev --help',
|
|
48
|
+
deploy: 'npx wrangler deploy',
|
|
49
|
+
list_zones: 'npx wrangler zone list',
|
|
50
|
+
worker_status: 'npx wrangler status'
|
|
51
|
+
},
|
|
52
|
+
systemCommands: {
|
|
53
|
+
powershell_web_request: 'powershell -Command "try { Invoke-WebRequest -Uri \'{url}\' -TimeoutSec 10 -UseBasicParsing | Out-Null } catch { exit 1 }"',
|
|
54
|
+
curl_test: 'curl -s --connect-timeout 10 {url} -o /dev/null'
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get a Cloudflare command
|
|
61
|
+
*/
|
|
62
|
+
getCloudflareCommand(commandName, params = {}) {
|
|
63
|
+
const command = this.config?.cloudflareCommands?.[commandName];
|
|
64
|
+
if (!command) {
|
|
65
|
+
throw new Error(`Cloudflare command '${commandName}' not found in configuration`);
|
|
66
|
+
}
|
|
67
|
+
return this.interpolateParams(command, params);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get a system command
|
|
72
|
+
*/
|
|
73
|
+
getSystemCommand(commandName, params = {}) {
|
|
74
|
+
const command = this.config?.systemCommands?.[commandName];
|
|
75
|
+
if (!command) {
|
|
76
|
+
throw new Error(`System command '${commandName}' not found in configuration`);
|
|
77
|
+
}
|
|
78
|
+
return this.interpolateParams(command, params);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get a required command
|
|
83
|
+
*/
|
|
84
|
+
getRequiredCommand(commandName) {
|
|
85
|
+
const command = this.config?.requiredCommands?.[commandName];
|
|
86
|
+
if (!command) {
|
|
87
|
+
throw new Error(`Required command '${commandName}' not found in configuration`);
|
|
88
|
+
}
|
|
89
|
+
return command;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get network test command for current platform
|
|
94
|
+
*/
|
|
95
|
+
getNetworkTestCommand(url) {
|
|
96
|
+
const isWindows = process.platform === 'win32';
|
|
97
|
+
const commandName = isWindows ? 'powershell_web_request' : 'curl_test';
|
|
98
|
+
return this.getSystemCommand(commandName, {
|
|
99
|
+
url
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Interpolate parameters in command strings
|
|
105
|
+
*/
|
|
106
|
+
interpolateParams(command, params) {
|
|
107
|
+
let result = command;
|
|
108
|
+
for (const [key, value] of Object.entries(params)) {
|
|
109
|
+
const placeholder = `{${key}}`;
|
|
110
|
+
result = result.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g'), value);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get all available commands for debugging
|
|
117
|
+
*/
|
|
118
|
+
getAllCommands() {
|
|
119
|
+
return {
|
|
120
|
+
requiredCommands: this.config?.requiredCommands || {},
|
|
121
|
+
cloudflareCommands: this.config?.cloudflareCommands || {},
|
|
122
|
+
systemCommands: this.config?.systemCommands || {}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Validate command configuration
|
|
128
|
+
*/
|
|
129
|
+
validateConfig() {
|
|
130
|
+
const errors = [];
|
|
131
|
+
|
|
132
|
+
// Check required sections
|
|
133
|
+
const requiredSections = ['requiredCommands', 'cloudflareCommands', 'systemCommands'];
|
|
134
|
+
for (const section of requiredSections) {
|
|
135
|
+
if (!this.config[section] || typeof this.config[section] !== 'object') {
|
|
136
|
+
errors.push(`Missing or invalid section: ${section}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check essential Cloudflare commands
|
|
141
|
+
const essentialCfCommands = ['whoami', 'auth_login', 'deployments_list'];
|
|
142
|
+
for (const cmd of essentialCfCommands) {
|
|
143
|
+
if (!this.config?.cloudflareCommands?.[cmd]) {
|
|
144
|
+
errors.push(`Missing essential Cloudflare command: ${cmd}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (errors.length > 0) {
|
|
148
|
+
throw new Error(`Command configuration validation failed:\\n${errors.join('\\n')}`);
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Reload configuration
|
|
155
|
+
*/
|
|
156
|
+
reload() {
|
|
157
|
+
this.loadConfig();
|
|
158
|
+
this.validateConfig();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Singleton instance
|
|
163
|
+
let commandConfigInstance = null;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get singleton instance of command config manager
|
|
167
|
+
*/
|
|
168
|
+
export function getCommandConfig(configPath = null) {
|
|
169
|
+
if (!commandConfigInstance || configPath) {
|
|
170
|
+
commandConfigInstance = new CommandConfigManager(configPath);
|
|
171
|
+
}
|
|
172
|
+
return commandConfigInstance;
|
|
173
|
+
}
|
|
174
|
+
export default CommandConfigManager;
|
|
@@ -0,0 +1,258 @@
|
|
|
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
|
+
import { CustomerConfigCLI } from '../../../src/config/CustomerConfigCLI.js';
|
|
9
|
+
const command = process.argv[2];
|
|
10
|
+
const args = process.argv.slice(3);
|
|
11
|
+
async function main() {
|
|
12
|
+
const cli = new CustomerConfigCLI();
|
|
13
|
+
await cli.initialize();
|
|
14
|
+
try {
|
|
15
|
+
switch (command) {
|
|
16
|
+
case 'create-customer':
|
|
17
|
+
const [customerName, domain] = args;
|
|
18
|
+
const result = await cli.createCustomer(customerName, domain);
|
|
19
|
+
if (result.success) {
|
|
20
|
+
console.log(`\nš Customer ${customerName} configuration created successfully!`);
|
|
21
|
+
console.log(`\nš Customer Details:`);
|
|
22
|
+
console.log(` Name: ${result.customer.name}`);
|
|
23
|
+
console.log(` Domain: ${result.customer.domain || 'Not specified'}`);
|
|
24
|
+
console.log(` Config Path: ${result.customer.configPath}`);
|
|
25
|
+
console.log(` Environments: ${result.customer.environments.join(', ')}`);
|
|
26
|
+
console.log(`\nš Next steps:`);
|
|
27
|
+
console.log(`1. Review generated configs in: config/customers/${customerName}/`);
|
|
28
|
+
console.log(`2. Update domain-specific URLs if needed`);
|
|
29
|
+
console.log(`3. Generate production secrets: npm run security:generate-key ${customerName}`);
|
|
30
|
+
console.log(`4. Set production secrets: wrangler secret put KEY_NAME --env production`);
|
|
31
|
+
} else {
|
|
32
|
+
console.error(`ā Failed to create customer: ${result.error}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case 'validate':
|
|
37
|
+
const validateResult = await cli.validateConfigurations();
|
|
38
|
+
if (validateResult.valid) {
|
|
39
|
+
console.log('ā
All customer configurations are valid');
|
|
40
|
+
} else {
|
|
41
|
+
console.log('ā Configuration validation failed');
|
|
42
|
+
validateResult.errors.forEach(error => console.log(` - ${error}`));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
case 'show':
|
|
47
|
+
const [customerNameShow, environment] = args;
|
|
48
|
+
const showResult = cli.showConfiguration(customerNameShow, environment);
|
|
49
|
+
if (showResult.success) {
|
|
50
|
+
console.log(`š Effective configuration: ${customerNameShow}/${environment}\n`);
|
|
51
|
+
if (showResult.config.variables?.base) {
|
|
52
|
+
console.log('š Base variables:');
|
|
53
|
+
Object.entries(showResult.config.variables.base).slice(0, 10).forEach(([key, value]) => {
|
|
54
|
+
console.log(` ${key}=${value}`);
|
|
55
|
+
});
|
|
56
|
+
if (Object.keys(showResult.config.variables.base).length > 10) {
|
|
57
|
+
console.log(' ...');
|
|
58
|
+
}
|
|
59
|
+
console.log('');
|
|
60
|
+
}
|
|
61
|
+
if (showResult.config.variables?.customer) {
|
|
62
|
+
console.log(`š Customer ${environment} variables:`);
|
|
63
|
+
Object.entries(showResult.config.variables.customer).slice(0, 15).forEach(([key, value]) => {
|
|
64
|
+
console.log(` ${key}=${value}`);
|
|
65
|
+
});
|
|
66
|
+
if (Object.keys(showResult.config.variables.customer).length > 15) {
|
|
67
|
+
console.log(' ...');
|
|
68
|
+
}
|
|
69
|
+
console.log('');
|
|
70
|
+
}
|
|
71
|
+
if (showResult.config.features && Object.keys(showResult.config.features).length > 0) {
|
|
72
|
+
console.log('š© Customer features:');
|
|
73
|
+
Object.entries(showResult.config.features).forEach(([feature, enabled]) => {
|
|
74
|
+
console.log(` ${feature}: ${enabled ? 'ā
' : 'ā'}`);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
console.error(`ā Failed to show configuration: ${showResult.error}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case 'deploy-command':
|
|
83
|
+
const [customerNameDeploy, environmentDeploy] = args;
|
|
84
|
+
const deployResult = cli.getDeployCommand(customerNameDeploy, environmentDeploy);
|
|
85
|
+
if (deployResult.success) {
|
|
86
|
+
console.log(`š Deploy command for ${customerNameDeploy}/${environmentDeploy}:`);
|
|
87
|
+
console.log(` ${deployResult.command}`);
|
|
88
|
+
console.log(`\nš” Ensure customer config is loaded: ${deployResult.configPath}`);
|
|
89
|
+
} else {
|
|
90
|
+
console.error(`ā Failed to get deploy command: ${deployResult.error}`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
case 'list':
|
|
95
|
+
const listResult = cli.listCustomers();
|
|
96
|
+
if (listResult.success && listResult.customers.length > 0) {
|
|
97
|
+
console.log('š Configured customers:\n');
|
|
98
|
+
listResult.customers.forEach(customer => {
|
|
99
|
+
console.log(`š¢ ${customer.name}`);
|
|
100
|
+
console.log(` Domain: ${customer.domain || 'Not specified'}`);
|
|
101
|
+
console.log(` Environments: ${customer.environments.join(', ')}`);
|
|
102
|
+
console.log(` Created: ${customer.createdAt}`);
|
|
103
|
+
console.log(` Config: config/customers/${customer.name}/`);
|
|
104
|
+
console.log('');
|
|
105
|
+
});
|
|
106
|
+
} else if (listResult.success) {
|
|
107
|
+
console.log('š No customers configured');
|
|
108
|
+
} else {
|
|
109
|
+
console.error(`ā Failed to list customers: ${listResult.error}`);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
console.log('Customer Configuration Management Tool\n');
|
|
115
|
+
console.log('Available commands:');
|
|
116
|
+
console.log(' create-customer <name> [domain] - Create new customer config from template');
|
|
117
|
+
console.log(' validate - Validate configuration structure');
|
|
118
|
+
console.log(' show <customer> <environment> - Show effective configuration');
|
|
119
|
+
console.log(' deploy-command <customer> <env> - Get deployment command');
|
|
120
|
+
console.log(' list - List all configured customers');
|
|
121
|
+
console.log('\nExamples:');
|
|
122
|
+
console.log(' clodo-customer-config create-customer acmecorp acmecorp.com');
|
|
123
|
+
console.log(' clodo-customer-config validate');
|
|
124
|
+
console.log(' clodo-customer-config show acmecorp production');
|
|
125
|
+
console.log(' clodo-customer-config list');
|
|
126
|
+
console.log('\nIntegration:');
|
|
127
|
+
console.log(' This tool integrates with Clodo Framework domain and feature flag systems.');
|
|
128
|
+
console.log(' Customer configurations are automatically registered as domains.');
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error(`ā Error: ${error.message}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
main().catch(error => {
|
|
137
|
+
console.error(`ā Unexpected error: ${error.message}`);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
});
|
|
140
|
+
async function handleCreateCustomer(args) {
|
|
141
|
+
const [customerName, domain] = args;
|
|
142
|
+
if (!customerName) {
|
|
143
|
+
console.error('Usage: customer-config create-customer <customer-name> [domain]');
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
console.log(`šļø Creating customer configuration: ${customerName}`);
|
|
147
|
+
|
|
148
|
+
// Pass framework mode flag to skip strict validation
|
|
149
|
+
const customerInfo = await customerManager.createCustomer(customerName, domain, {
|
|
150
|
+
skipValidation: true,
|
|
151
|
+
isFrameworkMode: true
|
|
152
|
+
});
|
|
153
|
+
console.log(`\nš Customer ${customerName} configuration created successfully!`);
|
|
154
|
+
console.log(`\nš Customer Details:`);
|
|
155
|
+
console.log(` Name: ${customerInfo.name}`);
|
|
156
|
+
console.log(` Domain: ${customerInfo.domain || 'Not specified'}`);
|
|
157
|
+
console.log(` Config Path: ${customerInfo.configPath}`);
|
|
158
|
+
console.log(` Environments: ${customerInfo.environments.join(', ')}`);
|
|
159
|
+
console.log(`\nš Next steps:`);
|
|
160
|
+
console.log(`1. Review generated configs in: config/customers/${customerName}/`);
|
|
161
|
+
console.log(`2. Update domain-specific URLs if needed`);
|
|
162
|
+
console.log(`3. Generate production secrets: npm run security:generate-key ${customerName}`);
|
|
163
|
+
console.log(`4. Set production secrets: wrangler secret put KEY_NAME --env production`);
|
|
164
|
+
}
|
|
165
|
+
async function handleValidate() {
|
|
166
|
+
console.log('š Validating customer configuration structure...\n');
|
|
167
|
+
const result = await customerManager.validateConfigs();
|
|
168
|
+
if (result.valid) {
|
|
169
|
+
console.log('ā
All customer configurations are valid');
|
|
170
|
+
} else {
|
|
171
|
+
console.log('ā Configuration validation failed');
|
|
172
|
+
result.errors.forEach(error => console.log(` - ${error}`));
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async function handleShow(args) {
|
|
177
|
+
const [customerName, environment] = args;
|
|
178
|
+
if (!customerName || !environment) {
|
|
179
|
+
console.error('Usage: customer-config show <customer> <environment>');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
const config = customerManager.showConfig(customerName, environment);
|
|
183
|
+
console.log(`š Effective configuration: ${customerName}/${environment}\n`);
|
|
184
|
+
if (config.variables.base) {
|
|
185
|
+
console.log('š Base variables:');
|
|
186
|
+
Object.entries(config.variables.base).slice(0, 10).forEach(([key, value]) => {
|
|
187
|
+
console.log(` ${key}=${value}`);
|
|
188
|
+
});
|
|
189
|
+
if (Object.keys(config.variables.base).length > 10) {
|
|
190
|
+
console.log(' ...');
|
|
191
|
+
}
|
|
192
|
+
console.log('');
|
|
193
|
+
}
|
|
194
|
+
if (config.variables.customer) {
|
|
195
|
+
console.log(`š Customer ${environment} variables:`);
|
|
196
|
+
Object.entries(config.variables.customer).slice(0, 15).forEach(([key, value]) => {
|
|
197
|
+
console.log(` ${key}=${value}`);
|
|
198
|
+
});
|
|
199
|
+
if (Object.keys(config.variables.customer).length > 15) {
|
|
200
|
+
console.log(' ...');
|
|
201
|
+
}
|
|
202
|
+
console.log('');
|
|
203
|
+
}
|
|
204
|
+
if (config.features && Object.keys(config.features).length > 0) {
|
|
205
|
+
console.log('š© Customer features:');
|
|
206
|
+
Object.entries(config.features).forEach(([feature, enabled]) => {
|
|
207
|
+
console.log(` ${feature}: ${enabled ? 'ā
' : 'ā'}`);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async function handleDeployCommand(args) {
|
|
212
|
+
const [customerName, environment] = args;
|
|
213
|
+
if (!customerName || !environment) {
|
|
214
|
+
console.error('Usage: customer-config deploy-command <customer> <environment>');
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
const deployInfo = customerManager.getDeployCommand(customerName, environment);
|
|
218
|
+
console.log(`š Deploy command for ${customerName}/${environment}:`);
|
|
219
|
+
console.log(` ${deployInfo.command}`);
|
|
220
|
+
console.log(`\nš” Ensure customer config is loaded: ${deployInfo.configPath}`);
|
|
221
|
+
}
|
|
222
|
+
async function handleList() {
|
|
223
|
+
const customers = customerManager.listCustomers();
|
|
224
|
+
if (customers.length === 0) {
|
|
225
|
+
console.log('š No customers configured');
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
console.log('š Configured customers:\n');
|
|
229
|
+
customers.forEach(customer => {
|
|
230
|
+
console.log(`š¢ ${customer.name}`);
|
|
231
|
+
console.log(` Domain: ${customer.domain || 'Not specified'}`);
|
|
232
|
+
console.log(` Environments: ${customer.environments.join(', ')}`);
|
|
233
|
+
console.log(` Created: ${customer.createdAt}`);
|
|
234
|
+
console.log(` Config: config/customers/${customer.name}/`);
|
|
235
|
+
console.log('');
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function showHelp() {
|
|
239
|
+
console.log('Customer Configuration Management Tool\n');
|
|
240
|
+
console.log('Available commands:');
|
|
241
|
+
console.log(' create-customer <name> [domain] - Create new customer config from template');
|
|
242
|
+
console.log(' validate - Validate configuration structure');
|
|
243
|
+
console.log(' show <customer> <environment> - Show effective configuration');
|
|
244
|
+
console.log(' deploy-command <customer> <env> - Get deployment command');
|
|
245
|
+
console.log(' list - List all configured customers');
|
|
246
|
+
console.log('\nExamples:');
|
|
247
|
+
console.log(' customer-config create-customer acmecorp acmecorp.com');
|
|
248
|
+
console.log(' customer-config validate');
|
|
249
|
+
console.log(' customer-config show acmecorp production');
|
|
250
|
+
console.log(' customer-config list');
|
|
251
|
+
console.log('\nIntegration:');
|
|
252
|
+
console.log(' This tool integrates with Clodo Framework domain and feature flag systems.');
|
|
253
|
+
console.log(' Customer configurations are automatically registered as domains.');
|
|
254
|
+
}
|
|
255
|
+
main().catch(error => {
|
|
256
|
+
console.error(`ā Unexpected error: ${error.message}`);
|
|
257
|
+
process.exit(1);
|
|
258
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Module
|
|
3
|
+
* Exports all configuration management utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { ConfigCache } from './cache.js';
|
|
7
|
+
export { ConfigManager } from './manager.js';
|
|
8
|
+
export { CommandConfigManager } from './command-config-manager.js';
|
|
9
|
+
export { CustomerConfigurationManager } from '../../../src/config/customers.js';
|