@tamyla/clodo-framework 3.1.21 → 3.1.23
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 +17 -0
- package/README.md +283 -1
- package/dist/{bin → cli}/clodo-service.js +47 -15
- package/dist/cli/commands/assess.js +183 -0
- package/dist/{bin → cli}/commands/create.js +5 -5
- package/dist/{bin → cli}/commands/deploy.js +122 -90
- package/dist/{bin → cli}/commands/diagnose.js +5 -5
- package/dist/cli/commands/helpers/deployment-ui.js +138 -0
- package/dist/cli/commands/helpers/deployment-verification.js +250 -0
- package/dist/cli/commands/helpers/error-recovery.js +80 -0
- package/dist/cli/commands/helpers/resource-detection.js +113 -0
- package/dist/{bin → cli}/commands/helpers.js +0 -28
- package/dist/cli/commands/init-config.js +57 -0
- package/dist/{bin → cli}/commands/update.js +5 -5
- package/dist/{bin → cli}/commands/validate.js +5 -5
- package/dist/cli/security-cli.js +118 -0
- package/dist/config/FeatureManager.js +6 -0
- package/dist/config/clodo-create.example.json +26 -0
- package/dist/config/clodo-deploy.example.json +41 -0
- package/dist/config/clodo-update.example.json +46 -0
- package/dist/config/clodo-validate.example.json +41 -0
- package/dist/config/customers/template/development.env.template +37 -0
- package/dist/config/customers/template/production.env.template +39 -0
- package/dist/config/customers/template/staging.env.template +37 -0
- package/dist/config/customers.js +28 -26
- package/dist/config/domain-examples/README.md +464 -0
- package/dist/config/domain-examples/environment-mapped.json +168 -0
- package/dist/config/domain-examples/multi-domain.json +144 -0
- package/dist/config/domain-examples/single-domain.json +50 -0
- package/dist/config/examples +12 -0
- package/dist/config/features.js +61 -0
- package/dist/config/staging-deployment.json +60 -0
- package/dist/config/validation-config.json +347 -0
- package/dist/deployment/wrangler-deployer.js +1 -1
- package/dist/{bin → lib}/deployment/modules/DeploymentOrchestrator.js +2 -2
- package/dist/{bin → lib}/deployment/modules/EnvironmentManager.js +2 -2
- package/dist/lib/deployment/orchestration/EnterpriseOrchestrator.js +21 -0
- package/dist/lib/shared/cache/configuration-cache.js +82 -0
- package/dist/{bin → lib}/shared/cloudflare/domain-discovery.js +1 -1
- package/dist/{bin → lib}/shared/cloudflare/domain-manager.js +1 -1
- package/dist/{bin → lib}/shared/cloudflare/index.js +1 -1
- package/dist/{bin → lib}/shared/cloudflare/ops.js +10 -8
- package/dist/{bin → lib}/shared/config/ConfigurationManager.js +23 -1
- package/dist/{bin → lib}/shared/config/command-config-manager.js +19 -3
- package/dist/{bin → lib}/shared/config/index.js +1 -1
- package/dist/{bin → lib}/shared/deployment/credential-collector.js +30 -7
- package/dist/lib/shared/deployment/index.js +10 -0
- package/dist/lib/shared/deployment/rollback-manager.js +7 -0
- package/dist/lib/shared/deployment/utilities/d1-error-recovery.js +177 -0
- package/dist/{bin → lib}/shared/deployment/validator.js +40 -10
- package/dist/lib/shared/deployment/workflows/deployment-summary.js +214 -0
- package/dist/lib/shared/deployment/workflows/interactive-confirmation.js +188 -0
- package/dist/lib/shared/deployment/workflows/interactive-database-workflow.js +234 -0
- package/dist/lib/shared/deployment/workflows/interactive-domain-info-gatherer.js +240 -0
- package/dist/lib/shared/deployment/workflows/interactive-secret-workflow.js +228 -0
- package/dist/lib/shared/deployment/workflows/interactive-testing-workflow.js +235 -0
- package/dist/lib/shared/deployment/workflows/interactive-validation.js +218 -0
- package/dist/lib/shared/error-handling/error-classifier.js +46 -0
- package/dist/{bin → lib}/shared/monitoring/health-checker.js +129 -1
- package/dist/{bin → lib}/shared/monitoring/memory-manager.js +17 -6
- package/dist/{bin → lib}/shared/routing/domain-router.js +1 -1
- package/dist/lib/shared/utils/deployment-validator.js +97 -0
- package/dist/{bin → lib}/shared/utils/formatters.js +10 -0
- package/dist/{bin → lib}/shared/utils/index.js +13 -1
- package/dist/{bin → lib}/shared/utils/interactive-prompts.js +34 -18
- package/dist/{bin → lib}/shared/utils/progress-manager.js +2 -2
- package/dist/lib/shared/utils/progress-spinner.js +53 -0
- package/dist/lib/shared/utils/sensitive-redactor.js +91 -0
- package/dist/{bin → lib}/shared/validation/ValidationRegistry.js +1 -1
- package/dist/migration/MigrationAdapters.js +50 -4
- package/dist/orchestration/cross-domain-coordinator.js +5 -5
- package/dist/orchestration/multi-domain-orchestrator.js +63 -22
- package/dist/security/index.js +2 -2
- package/dist/security/patterns/insecure-patterns.js +1 -1
- package/dist/service-management/ConfirmationEngine.js +1 -1
- package/dist/service-management/ErrorTracker.js +1 -1
- package/dist/service-management/InputCollector.js +1 -1
- package/dist/service-management/ServiceCreator.js +11 -255
- package/dist/service-management/ServiceOrchestrator.js +0 -2
- package/dist/service-management/generators/testing/UnitTestsGenerator.js +4 -4
- package/dist/service-management/index.js +1 -1
- package/dist/utils/cloudflare/ops.js +1 -1
- package/dist/utils/constants.js +102 -0
- package/dist/utils/deployment/wrangler-config-manager.js +215 -48
- package/dist/utils/file-manager.js +1 -1
- package/dist/utils/formatters.js +1 -1
- package/dist/utils/framework-config.js +2 -2
- package/dist/utils/interactive-prompts.js +10 -59
- package/dist/utils/logger.js +1 -1
- package/dist/version/VersionDetector.js +99 -9
- package/dist/worker/integration.js +1 -1
- package/package.json +10 -10
- package/dist/bin/clodo-service-old.js +0 -868
- package/dist/bin/clodo-service-test.js +0 -10
- package/dist/bin/commands/assess.js +0 -91
- package/dist/bin/database/enterprise-db-manager.js +0 -457
- package/dist/bin/deployment/enterprise-deploy.js +0 -877
- package/dist/bin/deployment/master-deploy.js +0 -1376
- package/dist/bin/deployment/modular-enterprise-deploy.js +0 -466
- package/dist/bin/deployment/orchestration/EnterpriseOrchestrator.js +0 -401
- package/dist/bin/deployment/test-interactive-utils.js +0 -66
- package/dist/bin/portfolio/portfolio-manager.js +0 -487
- package/dist/bin/security/security-cli.js +0 -108
- package/dist/bin/service-management/create-service.js +0 -122
- package/dist/bin/service-management/init-service.js +0 -79
- package/dist/bin/shared/deployment/index.js +0 -10
- package/dist/bin/shared/deployment/rollback-manager.js +0 -523
- package/dist/deployment/orchestration/EnterpriseOrchestrator.js +0 -401
- package/dist/service-management/ServiceInitializer.js +0 -453
- /package/dist/{bin → lib}/database/deployment-db-manager.js +0 -0
- /package/dist/{bin → lib}/database/wrangler-d1-manager.js +0 -0
- /package/dist/{bin → lib}/deployment/modules/DeploymentConfiguration.js +0 -0
- /package/dist/{bin → lib}/deployment/modules/MonitoringIntegration.js +0 -0
- /package/dist/{bin → lib}/deployment/modules/ValidationManager.js +0 -0
- /package/dist/{bin → lib}/deployment/orchestration/BaseDeploymentOrchestrator.js +0 -0
- /package/dist/{bin → lib}/deployment/orchestration/PortfolioOrchestrator.js +0 -0
- /package/dist/{bin → lib}/deployment/orchestration/SingleServiceOrchestrator.js +0 -0
- /package/dist/{bin → lib}/deployment/orchestration/UnifiedDeploymentOrchestrator.js +0 -0
- /package/dist/{bin → lib}/shared/config/cache.js +0 -0
- /package/dist/{bin → lib}/shared/config/cloudflare-service-validator.js +0 -0
- /package/dist/{bin → lib}/shared/config/manager.js +0 -0
- /package/dist/{bin → lib}/shared/config/manifest-loader.js +0 -0
- /package/dist/{bin → lib}/shared/database/connection-manager.js +0 -0
- /package/dist/{bin → lib}/shared/database/index.js +0 -0
- /package/dist/{bin → lib}/shared/database/orchestrator.js +0 -0
- /package/dist/{bin → lib}/shared/deployment/auditor.js +0 -0
- /package/dist/{bin → lib}/shared/index.js +0 -0
- /package/dist/{bin → lib}/shared/logging/Logger.js +0 -0
- /package/dist/{bin → lib}/shared/monitoring/index.js +0 -0
- /package/dist/{bin → lib}/shared/monitoring/production-monitor.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/api-tester.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/auth-tester.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/core.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/database-tester.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/index.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/load-tester.js +0 -0
- /package/dist/{bin → lib}/shared/production-tester/performance-tester.js +0 -0
- /package/dist/{bin → lib}/shared/security/api-token-manager.js +0 -0
- /package/dist/{bin → lib}/shared/security/index.js +0 -0
- /package/dist/{bin → lib}/shared/security/secret-generator.js +0 -0
- /package/dist/{bin → lib}/shared/security/secure-token-manager.js +0 -0
- /package/dist/{bin → lib}/shared/utils/ErrorHandler.js +0 -0
- /package/dist/{bin → lib}/shared/utils/cli-options.js +0 -0
- /package/dist/{bin → lib}/shared/utils/config-loader.js +0 -0
- /package/dist/{bin → lib}/shared/utils/error-recovery.js +0 -0
- /package/dist/{bin → lib}/shared/utils/file-manager.js +0 -0
- /package/dist/{bin → lib}/shared/utils/graceful-shutdown-manager.js +0 -0
- /package/dist/{bin → lib}/shared/utils/interactive-utils.js +0 -0
- /package/dist/{bin → lib}/shared/utils/output-formatter.js +0 -0
- /package/dist/{bin → lib}/shared/utils/rate-limiter.js +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { SecurityCLI } from '../security/SecurityCLI.js';
|
|
3
|
+
const command = process.argv[2];
|
|
4
|
+
const args = process.argv.slice(3);
|
|
5
|
+
async function main() {
|
|
6
|
+
const cli = new SecurityCLI();
|
|
7
|
+
switch (command) {
|
|
8
|
+
case 'validate':
|
|
9
|
+
{
|
|
10
|
+
const [customer, environment] = args;
|
|
11
|
+
const result = await cli.validateConfiguration(customer, environment);
|
|
12
|
+
if (result.valid) {
|
|
13
|
+
console.log('✅ Security validation passed');
|
|
14
|
+
} else {
|
|
15
|
+
console.log('❌ Security issues found');
|
|
16
|
+
result.securityIssues.forEach(issue => {
|
|
17
|
+
console.log(` ${issue.severity.toUpperCase()}: ${issue.message}`);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
process.exit(result.valid ? 0 : 1);
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
case 'generate-key':
|
|
24
|
+
{
|
|
25
|
+
const [type, lengthStr] = args;
|
|
26
|
+
const length = lengthStr ? parseInt(lengthStr) : undefined;
|
|
27
|
+
const keyResult = cli.generateKey(type, length);
|
|
28
|
+
if (keyResult.success) {
|
|
29
|
+
console.log(`Generated ${keyResult.type}: ${keyResult.key}`);
|
|
30
|
+
} else {
|
|
31
|
+
console.error(`Key generation failed: ${keyResult.error}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'deploy':
|
|
37
|
+
{
|
|
38
|
+
// Check for help flag first
|
|
39
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
40
|
+
console.log('Deploy with security validation');
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log('Usage:');
|
|
43
|
+
console.log(' clodo-security deploy <customer> <environment> [options]');
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log('Arguments:');
|
|
46
|
+
console.log(' customer Customer name (e.g., wetechfounders)');
|
|
47
|
+
console.log(' environment Target environment (development, staging, production)');
|
|
48
|
+
console.log('');
|
|
49
|
+
console.log('Options:');
|
|
50
|
+
console.log(' --dry-run Simulate deployment without making changes');
|
|
51
|
+
console.log(' --help, -h Display this help message');
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log('Examples:');
|
|
54
|
+
console.log(' clodo-security deploy wetechfounders development');
|
|
55
|
+
console.log(' clodo-security deploy greatidude production --dry-run');
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
const [deployCustomer, deployEnvironment] = args.filter(arg => !arg.startsWith('--'));
|
|
59
|
+
const dryRun = args.includes('--dry-run');
|
|
60
|
+
const deployResult = await cli.deployWithSecurity(deployCustomer, deployEnvironment, {
|
|
61
|
+
dryRun
|
|
62
|
+
});
|
|
63
|
+
if (deployResult.success) {
|
|
64
|
+
console.log(`✅ Deployment ${dryRun ? 'validation' : 'completed'} successfully`);
|
|
65
|
+
} else {
|
|
66
|
+
console.error(`Deployment failed: ${deployResult.error}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'generate-config':
|
|
72
|
+
{
|
|
73
|
+
const [configCustomer, configEnvironment] = args;
|
|
74
|
+
const configResult = cli.generateSecureConfig(configCustomer, configEnvironment);
|
|
75
|
+
if (configResult.success) {
|
|
76
|
+
console.log('Generated secure configuration:');
|
|
77
|
+
console.log(JSON.stringify(configResult.config, null, 2));
|
|
78
|
+
} else {
|
|
79
|
+
console.error(`Config generation failed: ${configResult.error}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'check-readiness':
|
|
85
|
+
{
|
|
86
|
+
const [readyCustomer, readyEnvironment] = args;
|
|
87
|
+
const readinessResult = cli.checkDeploymentReadiness(readyCustomer, readyEnvironment);
|
|
88
|
+
if (readinessResult.ready) {
|
|
89
|
+
console.log('✅ Deployment ready');
|
|
90
|
+
} else {
|
|
91
|
+
console.log('❌ Deployment not ready:');
|
|
92
|
+
readinessResult.issues.forEach(issue => console.log(` - ${issue}`));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
default:
|
|
98
|
+
console.log('Clodo Framework Security CLI');
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log('Commands:');
|
|
101
|
+
console.log(' validate <customer> <environment> - Validate configuration security');
|
|
102
|
+
console.log(' generate-key [type] [length] - Generate secure key (api/jwt)');
|
|
103
|
+
console.log(' deploy <customer> <environment> - Deploy with security validation');
|
|
104
|
+
console.log(' generate-config <customer> <env> - Generate secure configuration');
|
|
105
|
+
console.log(' check-readiness <customer> <env> - Check deployment readiness');
|
|
106
|
+
console.log('');
|
|
107
|
+
console.log('Examples:');
|
|
108
|
+
console.log(' clodo-security validate tamyla production');
|
|
109
|
+
console.log(' clodo-security generate-key jwt 64');
|
|
110
|
+
console.log(' clodo-security generate-key content-skimmer');
|
|
111
|
+
console.log(' clodo-security deploy tamyla staging --dry-run');
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
main().catch(error => {
|
|
116
|
+
console.error(`Unexpected error: ${error.message}`);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Comment": "Example configuration for 'npx clodo-service create' command",
|
|
3
|
+
"// Instructions": "Copy this file and customize for your needs, then use: npx clodo-service create --config-file your-config.json",
|
|
4
|
+
"// CLI Override": "Any CLI options passed on command line will override values from this config file",
|
|
5
|
+
|
|
6
|
+
"projectName": "my-cloudflare-worker",
|
|
7
|
+
"description": "A sample Cloudflare Worker project",
|
|
8
|
+
"environment": "development",
|
|
9
|
+
"region": "us-west-1",
|
|
10
|
+
"template": "basic",
|
|
11
|
+
"typescript": true,
|
|
12
|
+
"installDependencies": true,
|
|
13
|
+
|
|
14
|
+
"advanced": {
|
|
15
|
+
"nodeVersion": "18.x",
|
|
16
|
+
"packageManager": "npm",
|
|
17
|
+
"outputDir": "./dist",
|
|
18
|
+
"sourceDir": "./src"
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
"metadata": {
|
|
22
|
+
"author": "your-name",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"version": "0.1.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Comment": "Example configuration for 'npx clodo-service deploy' command",
|
|
3
|
+
"// Instructions": "Copy this file and customize for your needs, then use: npx clodo-service deploy --config-file your-config.json",
|
|
4
|
+
"// EnvVars": "You can use environment variable substitution: ${ENV_VAR_NAME} will be replaced with the value of ENV_VAR_NAME",
|
|
5
|
+
|
|
6
|
+
"domain": "api.example.com",
|
|
7
|
+
"environment": "production",
|
|
8
|
+
"cloudflareToken": "${CLOUDFLARE_TOKEN}",
|
|
9
|
+
"cloudflareZoneId": "${CLOUDFLARE_ZONE_ID}",
|
|
10
|
+
|
|
11
|
+
"deployment": {
|
|
12
|
+
"strategy": "blue-green",
|
|
13
|
+
"replicas": 3,
|
|
14
|
+
"maxConcurrency": 100,
|
|
15
|
+
"timeout": 30000,
|
|
16
|
+
"healthCheckInterval": 5000,
|
|
17
|
+
"rollbackOnFailure": true
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
"routing": {
|
|
21
|
+
"enableLoadBalancing": true,
|
|
22
|
+
"loadBalancingPolicy": "round-robin",
|
|
23
|
+
"corsEnabled": true,
|
|
24
|
+
"corsOrigins": ["https://example.com", "https://app.example.com"]
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
"monitoring": {
|
|
28
|
+
"enableMetrics": true,
|
|
29
|
+
"metricsEndpoint": "https://metrics.example.com",
|
|
30
|
+
"alertOnFailure": true,
|
|
31
|
+
"alertEmail": "alerts@example.com"
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
"security": {
|
|
35
|
+
"enableSSL": true,
|
|
36
|
+
"minTLSVersion": "1.2",
|
|
37
|
+
"enableWAF": true,
|
|
38
|
+
"rateLimit": 1000,
|
|
39
|
+
"rateLimitWindow": 60
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Comment": "Example configuration for 'npx clodo-service update' command",
|
|
3
|
+
"// Instructions": "Copy this file and customize for your needs, then use: npx clodo-service update --config-file your-config.json",
|
|
4
|
+
|
|
5
|
+
"domain": "api.example.com",
|
|
6
|
+
"environment": "production",
|
|
7
|
+
"cloudflareToken": "${CLOUDFLARE_TOKEN}",
|
|
8
|
+
|
|
9
|
+
"preview": true,
|
|
10
|
+
"force": false,
|
|
11
|
+
|
|
12
|
+
"updates": {
|
|
13
|
+
"updateDependencies": true,
|
|
14
|
+
"updateConfiguration": true,
|
|
15
|
+
"updateScripts": true,
|
|
16
|
+
"updateWorkerConfig": true
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"migration": {
|
|
20
|
+
"runMigrations": true,
|
|
21
|
+
"backupBeforeUpdate": true,
|
|
22
|
+
"backupLocation": "./backups",
|
|
23
|
+
"rollbackOnError": true
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
"validation": {
|
|
27
|
+
"validateBeforeUpdate": true,
|
|
28
|
+
"validateAfterUpdate": true,
|
|
29
|
+
"runTests": true
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"notification": {
|
|
33
|
+
"notifyOnStart": true,
|
|
34
|
+
"notifyOnComplete": true,
|
|
35
|
+
"notifyEmail": "admin@example.com",
|
|
36
|
+
"notifySlack": false,
|
|
37
|
+
"slackWebhook": ""
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
"performance": {
|
|
41
|
+
"parallelUpdates": 2,
|
|
42
|
+
"timeout": 60000,
|
|
43
|
+
"retryOnFailure": true,
|
|
44
|
+
"maxRetries": 3
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Comment": "Example configuration for 'npx clodo-service validate' command",
|
|
3
|
+
"// Instructions": "Copy this file and customize for your needs, then use: npx clodo-service validate --config-file your-config.json",
|
|
4
|
+
|
|
5
|
+
"environment": "production",
|
|
6
|
+
"deepScan": true,
|
|
7
|
+
"exportReport": "validation-report.json",
|
|
8
|
+
|
|
9
|
+
"checks": {
|
|
10
|
+
"validateDependencies": true,
|
|
11
|
+
"validateScripts": true,
|
|
12
|
+
"validateConfiguration": true,
|
|
13
|
+
"validateDeploymentConfig": true,
|
|
14
|
+
"validateEnvironmentVariables": true,
|
|
15
|
+
"validateSecuritySettings": true,
|
|
16
|
+
"validateNetworkConnectivity": true,
|
|
17
|
+
"validateCloudflareConfig": true
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
"validation": {
|
|
21
|
+
"strict": true,
|
|
22
|
+
"allowWarnings": false,
|
|
23
|
+
"checkVersionCompatibility": true,
|
|
24
|
+
"checkSecurityIssues": true,
|
|
25
|
+
"checkDummySecrets": true
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
"requirements": {
|
|
29
|
+
"minNodeVersion": "16.x",
|
|
30
|
+
"requiredFiles": ["package.json", "wrangler.toml", "src/index.js"],
|
|
31
|
+
"requiredDependencies": ["@cloudflare/wrangler"],
|
|
32
|
+
"requiredEnvironmentVars": ["CLOUDFLARE_TOKEN"]
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
"reporting": {
|
|
36
|
+
"verbose": false,
|
|
37
|
+
"includePassedChecks": true,
|
|
38
|
+
"includeDependencyTree": true,
|
|
39
|
+
"includeSuggestions": true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Customer Development Environment Variables
|
|
2
|
+
# Template for {{CUSTOMER_NAME}} development environment
|
|
3
|
+
|
|
4
|
+
# Customer Information
|
|
5
|
+
CUSTOMER_NAME={{CUSTOMER_NAME}}
|
|
6
|
+
CUSTOMER_DOMAIN={{CUSTOMER_DOMAIN}}
|
|
7
|
+
ENVIRONMENT={{ENVIRONMENT}}
|
|
8
|
+
|
|
9
|
+
# Domain Configuration
|
|
10
|
+
DOMAIN={{DOMAIN}}
|
|
11
|
+
API_DOMAIN=api-dev.{{DOMAIN}}
|
|
12
|
+
AUTH_DOMAIN=auth-dev.{{DOMAIN}}
|
|
13
|
+
|
|
14
|
+
# Database Configuration
|
|
15
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/{{CUSTOMER_NAME}}_dev
|
|
16
|
+
REDIS_URL=redis://localhost:6379/0
|
|
17
|
+
|
|
18
|
+
# Feature Flags
|
|
19
|
+
ENABLE_DEBUG_LOGGING=true
|
|
20
|
+
ENABLE_DEVELOPMENT_MODE=true
|
|
21
|
+
ENABLE_STRICT_VALIDATION=false
|
|
22
|
+
|
|
23
|
+
# Security
|
|
24
|
+
JWT_SECRET=dev-jwt-secret-{{CUSTOMER_NAME}}
|
|
25
|
+
API_KEY=dev-api-key-{{CUSTOMER_NAME}}
|
|
26
|
+
|
|
27
|
+
# External Services
|
|
28
|
+
STRIPE_PUBLIC_KEY=pk_test_...
|
|
29
|
+
STRIPE_SECRET_KEY=sk_test_...
|
|
30
|
+
|
|
31
|
+
# Logging
|
|
32
|
+
LOG_LEVEL=debug
|
|
33
|
+
LOG_FORMAT=json
|
|
34
|
+
|
|
35
|
+
# Performance
|
|
36
|
+
CACHE_TTL=300
|
|
37
|
+
RATE_LIMIT=1000
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Customer Production Environment Variables
|
|
2
|
+
# Template for {{CUSTOMER_NAME}} production environment
|
|
3
|
+
|
|
4
|
+
# Customer Information
|
|
5
|
+
CUSTOMER_NAME={{CUSTOMER_NAME}}
|
|
6
|
+
CUSTOMER_DOMAIN={{CUSTOMER_DOMAIN}}
|
|
7
|
+
ENVIRONMENT={{ENVIRONMENT}}
|
|
8
|
+
|
|
9
|
+
# Domain Configuration
|
|
10
|
+
DOMAIN={{DOMAIN}}
|
|
11
|
+
API_DOMAIN=api.{{DOMAIN}}
|
|
12
|
+
AUTH_DOMAIN=auth.{{DOMAIN}}
|
|
13
|
+
|
|
14
|
+
# Database Configuration
|
|
15
|
+
DATABASE_URL=postgresql://user:password@prod-db:5432/{{CUSTOMER_NAME}}_prod
|
|
16
|
+
REDIS_URL=redis://prod-redis:6379/0
|
|
17
|
+
|
|
18
|
+
# Feature Flags
|
|
19
|
+
ENABLE_DEBUG_LOGGING=false
|
|
20
|
+
ENABLE_DEVELOPMENT_MODE=false
|
|
21
|
+
ENABLE_STRICT_VALIDATION=true
|
|
22
|
+
ENABLE_ERROR_REPORTING=true
|
|
23
|
+
ENABLE_MONITORING=true
|
|
24
|
+
|
|
25
|
+
# Security
|
|
26
|
+
JWT_SECRET={{PRODUCTION_JWT_SECRET}}
|
|
27
|
+
API_KEY={{PRODUCTION_API_KEY}}
|
|
28
|
+
|
|
29
|
+
# External Services
|
|
30
|
+
STRIPE_PUBLIC_KEY={{PRODUCTION_STRIPE_PUBLIC_KEY}}
|
|
31
|
+
STRIPE_SECRET_KEY={{PRODUCTION_STRIPE_SECRET_KEY}}
|
|
32
|
+
|
|
33
|
+
# Logging
|
|
34
|
+
LOG_LEVEL=warn
|
|
35
|
+
LOG_FORMAT=json
|
|
36
|
+
|
|
37
|
+
# Performance
|
|
38
|
+
CACHE_TTL=3600
|
|
39
|
+
RATE_LIMIT=10000
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Customer Staging Environment Variables
|
|
2
|
+
# Template for {{CUSTOMER_NAME}} staging environment
|
|
3
|
+
|
|
4
|
+
# Customer Information
|
|
5
|
+
CUSTOMER_NAME={{CUSTOMER_NAME}}
|
|
6
|
+
CUSTOMER_DOMAIN={{CUSTOMER_DOMAIN}}
|
|
7
|
+
ENVIRONMENT={{ENVIRONMENT}}
|
|
8
|
+
|
|
9
|
+
# Domain Configuration
|
|
10
|
+
DOMAIN={{DOMAIN}}
|
|
11
|
+
API_DOMAIN=api-staging.{{DOMAIN}}
|
|
12
|
+
AUTH_DOMAIN=auth-staging.{{DOMAIN}}
|
|
13
|
+
|
|
14
|
+
# Database Configuration
|
|
15
|
+
DATABASE_URL=postgresql://user:password@staging-db:5432/{{CUSTOMER_NAME}}_staging
|
|
16
|
+
REDIS_URL=redis://staging-redis:6379/0
|
|
17
|
+
|
|
18
|
+
# Feature Flags
|
|
19
|
+
ENABLE_DEBUG_LOGGING=false
|
|
20
|
+
ENABLE_DEVELOPMENT_MODE=false
|
|
21
|
+
ENABLE_STRICT_VALIDATION=true
|
|
22
|
+
|
|
23
|
+
# Security
|
|
24
|
+
JWT_SECRET=staging-jwt-secret-{{CUSTOMER_NAME}}
|
|
25
|
+
API_KEY=staging-api-key-{{CUSTOMER_NAME}}
|
|
26
|
+
|
|
27
|
+
# External Services
|
|
28
|
+
STRIPE_PUBLIC_KEY=pk_test_...
|
|
29
|
+
STRIPE_SECRET_KEY=sk_test_...
|
|
30
|
+
|
|
31
|
+
# Logging
|
|
32
|
+
LOG_LEVEL=info
|
|
33
|
+
LOG_FORMAT=json
|
|
34
|
+
|
|
35
|
+
# Performance
|
|
36
|
+
CACHE_TTL=600
|
|
37
|
+
RATE_LIMIT=5000
|
package/dist/config/customers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from 'fs';
|
|
2
2
|
// eslint-disable-next-line no-unused-vars
|
|
3
3
|
import { resolve, join } from 'path';
|
|
4
4
|
import toml from '@iarna/toml';
|
|
@@ -38,8 +38,10 @@ export class CustomerConfigurationManager {
|
|
|
38
38
|
const customerDir = resolve(this.configDir, 'customers', customerName);
|
|
39
39
|
|
|
40
40
|
// Create customer directory structure
|
|
41
|
-
if
|
|
42
|
-
|
|
41
|
+
console.log(`DEBUG: Checking if directory exists: ${customerDir}`);
|
|
42
|
+
if (!fs.existsSync(customerDir)) {
|
|
43
|
+
console.log(`DEBUG: Creating directory: ${customerDir}`);
|
|
44
|
+
fs.mkdirSync(customerDir, {
|
|
43
45
|
recursive: true
|
|
44
46
|
});
|
|
45
47
|
logger.info(`Created customer directory: ${customerDir}`);
|
|
@@ -120,19 +122,19 @@ export class CustomerConfigurationManager {
|
|
|
120
122
|
const outputPath = resolve(this.configDir, 'customers', customerName, `${environment}.env`);
|
|
121
123
|
|
|
122
124
|
// Check if template exists
|
|
123
|
-
if (!existsSync(templatePath)) {
|
|
125
|
+
if (!fs.existsSync(templatePath)) {
|
|
124
126
|
logger.warn(`Template not found: ${templatePath}, skipping ${environment} config`);
|
|
125
127
|
return;
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
// Skip if config already exists
|
|
129
|
-
if (existsSync(outputPath)) {
|
|
131
|
+
if (fs.existsSync(outputPath)) {
|
|
130
132
|
logger.info(`Config already exists: ${outputPath}, skipping`);
|
|
131
133
|
return;
|
|
132
134
|
}
|
|
133
135
|
try {
|
|
134
136
|
// Read template and replace placeholders
|
|
135
|
-
let template = readFileSync(templatePath, 'utf8');
|
|
137
|
+
let template = fs.readFileSync(templatePath, 'utf8');
|
|
136
138
|
|
|
137
139
|
// Replace customer-specific placeholders
|
|
138
140
|
template = template.replace(/\{\{CUSTOMER_NAME\}\}/g, customerName);
|
|
@@ -144,7 +146,7 @@ export class CustomerConfigurationManager {
|
|
|
144
146
|
template = template.replace(/\{\{DOMAIN\}\}/g, envDomains[environment]);
|
|
145
147
|
|
|
146
148
|
// Write customer config
|
|
147
|
-
writeFileSync(outputPath, template);
|
|
149
|
+
fs.writeFileSync(outputPath, template);
|
|
148
150
|
logger.info(`Created customer config: ${environment}.env for ${customerName}`);
|
|
149
151
|
} catch (error) {
|
|
150
152
|
logger.error(`Failed to create ${environment} config for ${customerName}:`, error.message);
|
|
@@ -176,7 +178,7 @@ export class CustomerConfigurationManager {
|
|
|
176
178
|
const baseFiles = ['wrangler.base.toml', 'variables.base.env'];
|
|
177
179
|
for (const file of baseFiles) {
|
|
178
180
|
const path = resolve(this.configDir, 'base', file);
|
|
179
|
-
if (!existsSync(path)) {
|
|
181
|
+
if (!fs.existsSync(path)) {
|
|
180
182
|
errors.push(`Missing base config: ${file}`);
|
|
181
183
|
valid = false;
|
|
182
184
|
}
|
|
@@ -186,7 +188,7 @@ export class CustomerConfigurationManager {
|
|
|
186
188
|
for (const env of this.environments) {
|
|
187
189
|
const envFile = `${env}.toml`;
|
|
188
190
|
const path = resolve(this.configDir, 'environments', envFile);
|
|
189
|
-
if (!existsSync(path)) {
|
|
191
|
+
if (!fs.existsSync(path)) {
|
|
190
192
|
errors.push(`Missing environment config: ${envFile}`);
|
|
191
193
|
valid = false;
|
|
192
194
|
}
|
|
@@ -194,7 +196,7 @@ export class CustomerConfigurationManager {
|
|
|
194
196
|
|
|
195
197
|
// Validate customer configs
|
|
196
198
|
const customersDir = resolve(this.configDir, 'customers');
|
|
197
|
-
if (existsSync(customersDir)) {
|
|
199
|
+
if (fs.existsSync(customersDir)) {
|
|
198
200
|
const customerDirs = this.getCustomerDirectories();
|
|
199
201
|
for (const customerName of customerDirs) {
|
|
200
202
|
const customerValid = await this.validateCustomerConfig(customerName);
|
|
@@ -223,7 +225,7 @@ export class CustomerConfigurationManager {
|
|
|
223
225
|
// Check environment files exist
|
|
224
226
|
for (const env of this.environments) {
|
|
225
227
|
const envFile = resolve(customerDir, `${env}.env`);
|
|
226
|
-
if (!existsSync(envFile)) {
|
|
228
|
+
if (!fs.existsSync(envFile)) {
|
|
227
229
|
logger.error(`Missing ${env}.env for customer ${customerName}`);
|
|
228
230
|
valid = false;
|
|
229
231
|
}
|
|
@@ -274,13 +276,13 @@ export class CustomerConfigurationManager {
|
|
|
274
276
|
|
|
275
277
|
// Load base variables
|
|
276
278
|
const baseVarsPath = resolve(this.configDir, 'base', 'variables.base.env');
|
|
277
|
-
if (existsSync(baseVarsPath)) {
|
|
279
|
+
if (fs.existsSync(baseVarsPath)) {
|
|
278
280
|
config.variables.base = this.parseEnvFile(baseVarsPath);
|
|
279
281
|
}
|
|
280
282
|
|
|
281
283
|
// Load customer environment variables
|
|
282
284
|
const customerConfigPath = resolve(this.configDir, 'customers', customerName, `${environment}.env`);
|
|
283
|
-
if (existsSync(customerConfigPath)) {
|
|
285
|
+
if (fs.existsSync(customerConfigPath)) {
|
|
284
286
|
config.variables.customer = this.parseEnvFile(customerConfigPath);
|
|
285
287
|
}
|
|
286
288
|
|
|
@@ -339,7 +341,7 @@ export class CustomerConfigurationManager {
|
|
|
339
341
|
*/
|
|
340
342
|
async loadExistingCustomers() {
|
|
341
343
|
const customersDir = resolve(this.configDir, 'customers');
|
|
342
|
-
if (!existsSync(customersDir)) {
|
|
344
|
+
if (!fs.existsSync(customersDir)) {
|
|
343
345
|
return;
|
|
344
346
|
}
|
|
345
347
|
try {
|
|
@@ -347,9 +349,9 @@ export class CustomerConfigurationManager {
|
|
|
347
349
|
const rootWranglerPath = resolve(this.configDir, '..', 'wrangler.toml');
|
|
348
350
|
let wranglerConfig = null;
|
|
349
351
|
let globalAccountId = null;
|
|
350
|
-
if (existsSync(rootWranglerPath)) {
|
|
352
|
+
if (fs.existsSync(rootWranglerPath)) {
|
|
351
353
|
try {
|
|
352
|
-
const wranglerContent = readFileSync(rootWranglerPath, 'utf8');
|
|
354
|
+
const wranglerContent = fs.readFileSync(rootWranglerPath, 'utf8');
|
|
353
355
|
wranglerConfig = toml.parse(wranglerContent);
|
|
354
356
|
globalAccountId = wranglerConfig.account_id;
|
|
355
357
|
logger.info(`Loaded wrangler.toml with account_id: ${globalAccountId ? globalAccountId.substring(0, 8) + '...' : 'not found'}`);
|
|
@@ -407,7 +409,7 @@ export class CustomerConfigurationManager {
|
|
|
407
409
|
|
|
408
410
|
// Read customer-specific env file to get CUSTOMER_DOMAIN and other info
|
|
409
411
|
const prodConfigPath = resolve(customerDir, 'production.env');
|
|
410
|
-
if (existsSync(prodConfigPath)) {
|
|
412
|
+
if (fs.existsSync(prodConfigPath)) {
|
|
411
413
|
try {
|
|
412
414
|
const prodConfig = this.parseEnvFile(prodConfigPath);
|
|
413
415
|
|
|
@@ -466,15 +468,15 @@ export class CustomerConfigurationManager {
|
|
|
466
468
|
*/
|
|
467
469
|
getCustomerDirectories() {
|
|
468
470
|
const customersDir = resolve(this.configDir, 'customers');
|
|
469
|
-
if (!existsSync(customersDir)) {
|
|
471
|
+
if (!fs.existsSync(customersDir)) {
|
|
470
472
|
return [];
|
|
471
473
|
}
|
|
472
474
|
try {
|
|
473
475
|
// Read directory contents
|
|
474
|
-
const items = readdirSync(customersDir);
|
|
476
|
+
const items = fs.readdirSync(customersDir);
|
|
475
477
|
return items.filter(item => {
|
|
476
478
|
const itemPath = resolve(customersDir, item);
|
|
477
|
-
return statSync(itemPath).isDirectory() && item !== 'template';
|
|
479
|
+
return fs.statSync(itemPath).isDirectory() && item !== 'template';
|
|
478
480
|
});
|
|
479
481
|
} catch (error) {
|
|
480
482
|
logger.error('Error reading customer directories:', error.message);
|
|
@@ -486,7 +488,7 @@ export class CustomerConfigurationManager {
|
|
|
486
488
|
* Parse environment file
|
|
487
489
|
*/
|
|
488
490
|
parseEnvFile(filePath) {
|
|
489
|
-
const content = readFileSync(filePath, 'utf8');
|
|
491
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
490
492
|
const variables = {};
|
|
491
493
|
content.split('\n').forEach(line => {
|
|
492
494
|
const trimmed = line.trim();
|
|
@@ -511,8 +513,8 @@ export class CustomerConfigurationManager {
|
|
|
511
513
|
let existingConfig = {};
|
|
512
514
|
|
|
513
515
|
// Read existing config if file exists
|
|
514
|
-
if (existsSync(wranglerPath)) {
|
|
515
|
-
const content = readFileSync(wranglerPath, 'utf8');
|
|
516
|
+
if (fs.existsSync(wranglerPath)) {
|
|
517
|
+
const content = fs.readFileSync(wranglerPath, 'utf8');
|
|
516
518
|
existingConfig = toml.parse(content);
|
|
517
519
|
}
|
|
518
520
|
|
|
@@ -521,7 +523,7 @@ export class CustomerConfigurationManager {
|
|
|
521
523
|
|
|
522
524
|
// Write back to file
|
|
523
525
|
const tomlContent = toml.stringify(mergedConfig);
|
|
524
|
-
writeFileSync(wranglerPath, tomlContent, 'utf8');
|
|
526
|
+
fs.writeFileSync(wranglerPath, tomlContent, 'utf8');
|
|
525
527
|
logger.info(`Updated wrangler.toml: ${wranglerPath}`);
|
|
526
528
|
return true;
|
|
527
529
|
} catch (error) {
|
|
@@ -575,7 +577,7 @@ export class CustomerConfigurationManager {
|
|
|
575
577
|
*/
|
|
576
578
|
addD1Database(wranglerPath, environment, databaseConfig) {
|
|
577
579
|
try {
|
|
578
|
-
const content = readFileSync(wranglerPath, 'utf8');
|
|
580
|
+
const content = fs.readFileSync(wranglerPath, 'utf8');
|
|
579
581
|
const config = toml.parse(content);
|
|
580
582
|
|
|
581
583
|
// Ensure env section exists
|
|
@@ -596,7 +598,7 @@ export class CustomerConfigurationManager {
|
|
|
596
598
|
}
|
|
597
599
|
|
|
598
600
|
// Write back
|
|
599
|
-
writeFileSync(wranglerPath, toml.stringify(config), 'utf8');
|
|
601
|
+
fs.writeFileSync(wranglerPath, toml.stringify(config), 'utf8');
|
|
600
602
|
logger.info(`Added D1 database to ${environment} environment`);
|
|
601
603
|
return true;
|
|
602
604
|
} catch (error) {
|