@tamyla/clodo-framework 2.0.17 → 2.0.19
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 +16 -0
- package/dist/database/database-orchestrator.js +10 -2
- package/dist/modules/security.js +24 -22
- package/dist/orchestration/modules/DeploymentCoordinator.js +108 -9
- package/dist/orchestration/multi-domain-orchestrator.js +125 -14
- package/dist/security/SecurityCLI.js +9 -66
- package/dist/security/index.js +7 -6
- package/dist/service-management/ServiceOrchestrator.js +14 -19
- package/dist/utils/config/unified-config-manager.js +448 -0
- package/dist/utils/deployment/index.js +1 -1
- package/dist/utils/deployment/wrangler-config-manager.js +363 -0
- package/package.json +1 -1
- package/dist/config/ConfigurationManager.js +0 -159
- package/dist/config/CustomerConfigCLI.js +0 -226
- package/dist/config/customer-config-loader.js +0 -247
- package/dist/security/DeploymentManager.js +0 -208
- package/dist/service-management/handlers/ConfigMutator.js +0 -130
- package/dist/utils/deployment/config-persistence.js +0 -347
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## [2.0.19](https://github.com/tamylaa/clodo-framework/compare/v2.0.18...v2.0.19) (2025-10-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Add comprehensive deployment configuration implementation status ([025fe82](https://github.com/tamylaa/clodo-framework/commit/025fe821a76ba9ac8cb87d14f2a116a5e8e58c43))
|
|
7
|
+
* Consolidate configuration management and organize documentation ([e3a3d44](https://github.com/tamylaa/clodo-framework/commit/e3a3d448a74b214d75ae669f3a17e3a6ddb36ac4))
|
|
8
|
+
* Resolve ESLint errors in security and config modules ([1080cdb](https://github.com/tamylaa/clodo-framework/commit/1080cdbb69b3ae29158b6af705d8fd376c95da7b))
|
|
9
|
+
|
|
10
|
+
## [2.0.18](https://github.com/tamylaa/clodo-framework/compare/v2.0.17...v2.0.18) (2025-10-12)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **deployment:** Critical deployment fixes - migrations, worker deployment, status tracking ([23c07e9](https://github.com/tamylaa/clodo-framework/commit/23c07e9a68fa4eb52ccd0df9421eff7d91919cb1)), closes [#2](https://github.com/tamylaa/clodo-framework/issues/2) [#3](https://github.com/tamylaa/clodo-framework/issues/3) [#4](https://github.com/tamylaa/clodo-framework/issues/4)
|
|
16
|
+
|
|
1
17
|
## [2.0.17](https://github.com/tamylaa/clodo-framework/compare/v2.0.16...v2.0.17) (2025-10-12)
|
|
2
18
|
|
|
3
19
|
|
|
@@ -628,8 +628,16 @@ export class DatabaseOrchestrator {
|
|
|
628
628
|
// Command builders and utility methods
|
|
629
629
|
|
|
630
630
|
buildMigrationCommand(databaseName, environment, isRemote) {
|
|
631
|
-
|
|
632
|
-
|
|
631
|
+
let command = `npx wrangler d1 migrations apply ${databaseName}`;
|
|
632
|
+
|
|
633
|
+
// For remote environments, add --env flag
|
|
634
|
+
// For local development, use --local WITHOUT --env (wrangler requirement)
|
|
635
|
+
if (isRemote) {
|
|
636
|
+
command += ` --env ${environment} --remote`;
|
|
637
|
+
} else {
|
|
638
|
+
command += ` --local`;
|
|
639
|
+
}
|
|
640
|
+
return command;
|
|
633
641
|
}
|
|
634
642
|
buildBackupCommand(databaseName, environment, backupFile, isRemote) {
|
|
635
643
|
const remoteFlag = isRemote ? '--remote' : '--local';
|
package/dist/modules/security.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ConfigurationValidator } from '../security/ConfigurationValidator.js';
|
|
2
|
-
|
|
2
|
+
// DeploymentManager removed - was simulated deployment only
|
|
3
|
+
// Use MultiDomainOrchestrator for real deployments
|
|
3
4
|
import { SecretGenerator } from '../security/SecretGenerator.js';
|
|
4
5
|
import { isValidEnvironment } from '../security/patterns/environment-rules.js';
|
|
5
6
|
|
|
@@ -17,10 +18,16 @@ export const securityModule = {
|
|
|
17
18
|
generateSecureKey: prefix => SecretGenerator.generateSecureApiKey(32, prefix),
|
|
18
19
|
generateSecureJwtSecret: length => SecretGenerator.generateSecureJwtSecret(length || 64),
|
|
19
20
|
generateServiceKey: (serviceName, env, length) => SecretGenerator.generateServiceKey(serviceName, env, length),
|
|
20
|
-
// Secure deployment
|
|
21
|
-
deployWithSecurity:
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
// Secure deployment (DEPRECATED)
|
|
22
|
+
deployWithSecurity: () => {
|
|
23
|
+
throw new Error('deployWithSecurity is deprecated. Use MultiDomainOrchestrator for real deployments.');
|
|
24
|
+
},
|
|
25
|
+
generateSecureConfig: () => {
|
|
26
|
+
throw new Error('generateSecureConfig is deprecated. Use UnifiedConfigManager for configuration.');
|
|
27
|
+
},
|
|
28
|
+
validateDeploymentReadiness: () => {
|
|
29
|
+
throw new Error('validateDeploymentReadiness is deprecated. Use MultiDomainOrchestrator validation.');
|
|
30
|
+
},
|
|
24
31
|
// Pre-deployment hooks
|
|
25
32
|
hooks: {
|
|
26
33
|
'pre-deployment': async context => {
|
|
@@ -43,18 +50,13 @@ export const securityModule = {
|
|
|
43
50
|
throw new Error('Deployment blocked due to critical security issues');
|
|
44
51
|
}
|
|
45
52
|
|
|
46
|
-
// Check deployment readiness
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
console.error('❌ Deployment not ready:');
|
|
50
|
-
readiness.issues.forEach(issue => console.error(` - ${issue}`));
|
|
51
|
-
throw new Error('Deployment blocked due to readiness issues');
|
|
52
|
-
}
|
|
53
|
+
// Check deployment readiness (DEPRECATED - commented out)
|
|
54
|
+
// Use MultiDomainOrchestrator's validation instead
|
|
55
|
+
console.log('⚠️ DeploymentManager readiness check skipped (deprecated)');
|
|
53
56
|
console.log(`✅ Security validation passed (${issues.length} total issues, ${criticalIssues.length} critical)`);
|
|
54
57
|
return {
|
|
55
58
|
valid: true,
|
|
56
|
-
issues
|
|
57
|
-
readiness
|
|
59
|
+
issues
|
|
58
60
|
};
|
|
59
61
|
},
|
|
60
62
|
'post-deployment': async context => {
|
|
@@ -64,14 +66,14 @@ export const securityModule = {
|
|
|
64
66
|
} = context;
|
|
65
67
|
console.log(`🔍 Post-deployment security checks for ${customer}/${environment}`);
|
|
66
68
|
|
|
67
|
-
// Perform post-deployment validation
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
69
|
+
// Perform post-deployment validation (DEPRECATED - commented out)
|
|
70
|
+
// DeploymentManager.performPostDeploymentChecks was simulated only
|
|
71
|
+
console.log('⚠️ Post-deployment checks skipped (DeploymentManager deprecated)');
|
|
72
|
+
console.log(`✅ Post-deployment phase complete`);
|
|
73
|
+
return {
|
|
74
|
+
success: true,
|
|
75
|
+
message: 'Post-deployment phase complete (DeploymentManager checks deprecated)'
|
|
76
|
+
};
|
|
75
77
|
}
|
|
76
78
|
},
|
|
77
79
|
// Utility methods
|
|
@@ -22,6 +22,38 @@ export class DeploymentCoordinator {
|
|
|
22
22
|
* @returns {Promise<Object>} Deployment result
|
|
23
23
|
*/
|
|
24
24
|
async deploySingleDomain(domain, domainState, handlers) {
|
|
25
|
+
const phaseResults = {
|
|
26
|
+
validation: {
|
|
27
|
+
success: false,
|
|
28
|
+
errors: [],
|
|
29
|
+
warnings: []
|
|
30
|
+
},
|
|
31
|
+
initialization: {
|
|
32
|
+
success: false,
|
|
33
|
+
errors: [],
|
|
34
|
+
warnings: []
|
|
35
|
+
},
|
|
36
|
+
database: {
|
|
37
|
+
success: false,
|
|
38
|
+
errors: [],
|
|
39
|
+
warnings: []
|
|
40
|
+
},
|
|
41
|
+
secrets: {
|
|
42
|
+
success: false,
|
|
43
|
+
errors: [],
|
|
44
|
+
warnings: []
|
|
45
|
+
},
|
|
46
|
+
deployment: {
|
|
47
|
+
success: false,
|
|
48
|
+
errors: [],
|
|
49
|
+
warnings: []
|
|
50
|
+
},
|
|
51
|
+
'post-validation': {
|
|
52
|
+
success: false,
|
|
53
|
+
errors: [],
|
|
54
|
+
warnings: []
|
|
55
|
+
}
|
|
56
|
+
};
|
|
25
57
|
try {
|
|
26
58
|
domainState.startTime = new Date();
|
|
27
59
|
domainState.status = 'deploying';
|
|
@@ -29,38 +61,105 @@ export class DeploymentCoordinator {
|
|
|
29
61
|
console.log(` Deployment ID: ${domainState.deploymentId}`);
|
|
30
62
|
console.log(` Environment: ${this.environment}`);
|
|
31
63
|
let deploymentUrl = null;
|
|
64
|
+
let hasCriticalErrors = false;
|
|
32
65
|
|
|
33
66
|
// Execute deployment phases
|
|
34
67
|
for (const phase of this.deploymentPhases) {
|
|
35
|
-
|
|
36
|
-
|
|
68
|
+
try {
|
|
69
|
+
const phaseResult = await this.executeDeploymentPhase(domain, phase, domainState, handlers);
|
|
70
|
+
domainState.phase = `${phase}-complete`;
|
|
71
|
+
|
|
72
|
+
// Mark phase as successful
|
|
73
|
+
phaseResults[phase].success = true;
|
|
74
|
+
|
|
75
|
+
// Capture deployment URL from deployment phase
|
|
76
|
+
if (phase === 'deployment' && phaseResult) {
|
|
77
|
+
if (phaseResult.url) {
|
|
78
|
+
deploymentUrl = phaseResult.url;
|
|
79
|
+
}
|
|
80
|
+
if (phaseResult.deployed === false) {
|
|
81
|
+
phaseResults[phase].warnings.push('Worker deployed in dry-run mode');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
37
84
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
85
|
+
// Capture database warnings
|
|
86
|
+
if (phase === 'database' && phaseResult) {
|
|
87
|
+
if (phaseResult.error) {
|
|
88
|
+
phaseResults[phase].warnings.push(phaseResult.error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} catch (phaseError) {
|
|
92
|
+
phaseResults[phase].success = false;
|
|
93
|
+
phaseResults[phase].errors.push(phaseError.message);
|
|
94
|
+
|
|
95
|
+
// Determine if error is critical (stops deployment)
|
|
96
|
+
const criticalPhases = ['validation', 'initialization', 'deployment'];
|
|
97
|
+
if (criticalPhases.includes(phase)) {
|
|
98
|
+
console.error(` ❌ Critical error in ${phase} phase: ${phaseError.message}`);
|
|
99
|
+
hasCriticalErrors = true;
|
|
100
|
+
throw phaseError; // Stop deployment on critical errors
|
|
101
|
+
} else {
|
|
102
|
+
// Non-critical errors (database migrations, health checks) - log but continue
|
|
103
|
+
console.warn(` ⚠️ ${phase} phase warning: ${phaseError.message}`);
|
|
104
|
+
console.warn(` 💡 Deployment will continue - this can be fixed manually`);
|
|
105
|
+
}
|
|
41
106
|
}
|
|
42
107
|
}
|
|
43
|
-
|
|
108
|
+
|
|
109
|
+
// Determine overall success based on phase results
|
|
110
|
+
const allPhasesSuccessful = Object.values(phaseResults).every(result => result.success);
|
|
111
|
+
const hasWarnings = Object.values(phaseResults).some(result => result.warnings.length > 0 || result.success === false && result.errors.length === 0);
|
|
112
|
+
domainState.status = hasCriticalErrors ? 'failed' : allPhasesSuccessful ? 'completed' : 'completed-with-warnings';
|
|
44
113
|
domainState.endTime = new Date();
|
|
45
|
-
|
|
114
|
+
domainState.phaseResults = phaseResults;
|
|
115
|
+
|
|
116
|
+
// Show appropriate completion message
|
|
117
|
+
if (allPhasesSuccessful) {
|
|
118
|
+
console.log(` ✅ ${domain} deployed successfully`);
|
|
119
|
+
} else if (!hasCriticalErrors) {
|
|
120
|
+
console.log(` ⚠️ ${domain} deployed with warnings`);
|
|
121
|
+
this.displayPhaseWarnings(phaseResults);
|
|
122
|
+
}
|
|
46
123
|
return {
|
|
47
124
|
domain,
|
|
48
|
-
success:
|
|
125
|
+
success: !hasCriticalErrors,
|
|
126
|
+
allPhasesSuccessful,
|
|
49
127
|
deploymentId: domainState.deploymentId,
|
|
50
128
|
duration: domainState.endTime - domainState.startTime,
|
|
51
129
|
phases: this.deploymentPhases.length,
|
|
52
130
|
url: deploymentUrl || domainState.deploymentUrl,
|
|
53
|
-
status:
|
|
131
|
+
status: domainState.status,
|
|
132
|
+
phaseResults
|
|
54
133
|
};
|
|
55
134
|
} catch (error) {
|
|
56
135
|
domainState.status = 'failed';
|
|
57
136
|
domainState.error = error.message;
|
|
58
137
|
domainState.endTime = new Date();
|
|
138
|
+
domainState.phaseResults = phaseResults;
|
|
59
139
|
console.error(` ❌ ${domain} deployment failed: ${error.message}`);
|
|
60
140
|
throw error;
|
|
61
141
|
}
|
|
62
142
|
}
|
|
63
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Display warnings for phases that had issues
|
|
146
|
+
* @param {Object} phaseResults - Phase results object
|
|
147
|
+
*/
|
|
148
|
+
displayPhaseWarnings(phaseResults) {
|
|
149
|
+
console.log(`\n 📊 Phase Status Summary:`);
|
|
150
|
+
for (const [phase, result] of Object.entries(phaseResults)) {
|
|
151
|
+
if (result.success && result.warnings.length === 0) {
|
|
152
|
+
console.log(` ✅ ${phase}: Success`);
|
|
153
|
+
} else if (result.success && result.warnings.length > 0) {
|
|
154
|
+
console.log(` ⚠️ ${phase}: Success with warnings`);
|
|
155
|
+
result.warnings.forEach(warn => console.log(` • ${warn}`));
|
|
156
|
+
} else {
|
|
157
|
+
console.log(` ❌ ${phase}: Failed`);
|
|
158
|
+
result.errors.forEach(err => console.log(` • ${err}`));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
64
163
|
/**
|
|
65
164
|
* Execute specific deployment phase
|
|
66
165
|
* @param {string} domain - Domain being deployed
|
|
@@ -12,7 +12,12 @@ import { DeploymentCoordinator } from './modules/DeploymentCoordinator.js';
|
|
|
12
12
|
import { StateManager } from './modules/StateManager.js';
|
|
13
13
|
import { DatabaseOrchestrator } from '../database/database-orchestrator.js';
|
|
14
14
|
import { EnhancedSecretManager } from '../utils/deployment/secret-generator.js';
|
|
15
|
+
import { WranglerConfigManager } from '../utils/deployment/wrangler-config-manager.js';
|
|
15
16
|
import { ConfigurationValidator } from '../security/ConfigurationValidator.js';
|
|
17
|
+
import { exec } from 'child_process';
|
|
18
|
+
import { promisify } from 'util';
|
|
19
|
+
import { join } from 'path';
|
|
20
|
+
const execAsync = promisify(exec);
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
23
|
* Multi-Domain Deployment Orchestrator
|
|
@@ -59,6 +64,11 @@ export class MultiDomainOrchestrator {
|
|
|
59
64
|
projectRoot: this.servicePath,
|
|
60
65
|
dryRun: this.dryRun
|
|
61
66
|
});
|
|
67
|
+
this.wranglerConfigManager = new WranglerConfigManager({
|
|
68
|
+
projectRoot: this.servicePath,
|
|
69
|
+
dryRun: this.dryRun,
|
|
70
|
+
verbose: options.verbose || false
|
|
71
|
+
});
|
|
62
72
|
|
|
63
73
|
// ConfigurationValidator is a static class - don't instantiate
|
|
64
74
|
// Access via ConfigurationValidator.validate() directly
|
|
@@ -270,6 +280,24 @@ export class MultiDomainOrchestrator {
|
|
|
270
280
|
domainState.databaseId = databaseId;
|
|
271
281
|
}
|
|
272
282
|
|
|
283
|
+
// CRITICAL: Update wrangler.toml BEFORE attempting migrations
|
|
284
|
+
console.log(` 📝 Configuring wrangler.toml for database...`);
|
|
285
|
+
try {
|
|
286
|
+
// Ensure environment section exists
|
|
287
|
+
await this.wranglerConfigManager.ensureEnvironment(this.environment);
|
|
288
|
+
|
|
289
|
+
// Add database binding (use snake_case for wrangler.toml compatibility)
|
|
290
|
+
await this.wranglerConfigManager.addDatabaseBinding(this.environment, {
|
|
291
|
+
binding: 'DB',
|
|
292
|
+
database_name: databaseName,
|
|
293
|
+
database_id: databaseId
|
|
294
|
+
});
|
|
295
|
+
console.log(` ✅ wrangler.toml updated with database configuration`);
|
|
296
|
+
} catch (configError) {
|
|
297
|
+
console.warn(` ⚠️ Failed to update wrangler.toml: ${configError.message}`);
|
|
298
|
+
console.warn(` 💡 You may need to manually add database configuration`);
|
|
299
|
+
}
|
|
300
|
+
|
|
273
301
|
// Apply migrations using DatabaseOrchestrator's enterprise capabilities
|
|
274
302
|
console.log(` 🔄 Applying database migrations...`);
|
|
275
303
|
try {
|
|
@@ -359,26 +387,109 @@ export class MultiDomainOrchestrator {
|
|
|
359
387
|
}
|
|
360
388
|
|
|
361
389
|
/**
|
|
362
|
-
* Deploy domain worker (
|
|
390
|
+
* Deploy domain worker (executes actual wrangler deploy)
|
|
363
391
|
*/
|
|
364
392
|
async deployDomainWorker(domain) {
|
|
365
|
-
// Placeholder: Add actual worker deployment logic here
|
|
366
393
|
console.log(` 🚀 Deploying worker for ${domain}`);
|
|
394
|
+
if (this.dryRun) {
|
|
395
|
+
console.log(` 🔍 DRY RUN: Would deploy worker for ${domain}`);
|
|
396
|
+
const subdomain = this.environment === 'production' ? 'api' : `${this.environment}-api`;
|
|
397
|
+
return {
|
|
398
|
+
url: `https://${subdomain}.${domain}`,
|
|
399
|
+
deployed: false,
|
|
400
|
+
dryRun: true
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
try {
|
|
404
|
+
// CRITICAL: Ensure environment section exists in wrangler.toml BEFORE deploying
|
|
405
|
+
console.log(` 📝 Verifying wrangler.toml configuration...`);
|
|
406
|
+
try {
|
|
407
|
+
await this.wranglerConfigManager.ensureEnvironment(this.environment);
|
|
408
|
+
} catch (configError) {
|
|
409
|
+
console.warn(` ⚠️ Could not verify wrangler.toml: ${configError.message}`);
|
|
410
|
+
// Continue anyway - wrangler will provide clearer error if config is wrong
|
|
411
|
+
}
|
|
367
412
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const subdomain = this.environment === 'production' ? 'api' : `${this.environment}-api`;
|
|
371
|
-
const workerUrl = `https://${subdomain}.${domain}`;
|
|
413
|
+
// Find wrangler.toml in service path
|
|
414
|
+
const wranglerConfigPath = join(this.servicePath, 'wrangler.toml');
|
|
372
415
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
416
|
+
// Build deploy command with environment
|
|
417
|
+
let deployCommand = `npx wrangler deploy`;
|
|
418
|
+
|
|
419
|
+
// Add environment flag for non-production
|
|
420
|
+
if (this.environment !== 'production') {
|
|
421
|
+
deployCommand += ` --env ${this.environment}`;
|
|
422
|
+
}
|
|
423
|
+
console.log(` � Executing: ${deployCommand}`);
|
|
424
|
+
console.log(` 📁 Working directory: ${this.servicePath}`);
|
|
425
|
+
|
|
426
|
+
// Execute deployment with timeout
|
|
427
|
+
const {
|
|
428
|
+
stdout,
|
|
429
|
+
stderr
|
|
430
|
+
} = await execAsync(deployCommand, {
|
|
431
|
+
cwd: this.servicePath,
|
|
432
|
+
timeout: 120000,
|
|
433
|
+
// 2 minute timeout
|
|
434
|
+
maxBuffer: 1024 * 1024 * 10 // 10MB buffer for large outputs
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// Log output for debugging
|
|
438
|
+
if (stdout) {
|
|
439
|
+
console.log(` 📄 Deployment output:`);
|
|
440
|
+
stdout.split('\n').filter(line => line.trim()).forEach(line => {
|
|
441
|
+
console.log(` ${line}`);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
if (stderr && !stderr.includes('deprecated')) {
|
|
445
|
+
console.warn(` ⚠️ Deployment warnings: ${stderr}`);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Parse worker URL from wrangler output
|
|
449
|
+
// Wrangler outputs: "Published service-name (version) to https://worker-url"
|
|
450
|
+
const urlMatch = stdout.match(/https:\/\/[^\s]+/);
|
|
451
|
+
const workerUrl = urlMatch ? urlMatch[0] : null;
|
|
452
|
+
|
|
453
|
+
// Also construct custom domain URL
|
|
454
|
+
const subdomain = this.environment === 'production' ? 'api' : `${this.environment}-api`;
|
|
455
|
+
const customUrl = `https://${subdomain}.${domain}`;
|
|
456
|
+
|
|
457
|
+
// Store URLs in domain state
|
|
458
|
+
const domainState = this.portfolioState.domainStates.get(domain);
|
|
459
|
+
if (domainState) {
|
|
460
|
+
domainState.workerUrl = workerUrl;
|
|
461
|
+
domainState.deploymentUrl = customUrl;
|
|
462
|
+
}
|
|
463
|
+
if (workerUrl) {
|
|
464
|
+
console.log(` ✅ Worker deployed successfully`);
|
|
465
|
+
console.log(` 🔗 Worker URL: ${workerUrl}`);
|
|
466
|
+
console.log(` 🔗 Custom URL: ${customUrl}`);
|
|
467
|
+
} else {
|
|
468
|
+
console.log(` ✅ Deployment completed (URL not detected in output)`);
|
|
469
|
+
console.log(` 🔗 Expected URL: ${customUrl}`);
|
|
470
|
+
}
|
|
471
|
+
return {
|
|
472
|
+
url: customUrl,
|
|
473
|
+
workerUrl: workerUrl,
|
|
474
|
+
deployed: true,
|
|
475
|
+
stdout,
|
|
476
|
+
stderr
|
|
477
|
+
};
|
|
478
|
+
} catch (error) {
|
|
479
|
+
console.error(` ❌ Worker deployment failed: ${error.message}`);
|
|
480
|
+
|
|
481
|
+
// Parse error for helpful diagnostics
|
|
482
|
+
if (error.message.includes('wrangler.toml')) {
|
|
483
|
+
console.error(` 💡 Ensure wrangler.toml exists in ${this.servicePath}`);
|
|
484
|
+
}
|
|
485
|
+
if (error.message.includes('No environment found')) {
|
|
486
|
+
console.error(` 💡 Add [env.${this.environment}] section to wrangler.toml`);
|
|
487
|
+
}
|
|
488
|
+
if (error.stderr) {
|
|
489
|
+
console.error(` 📄 Error details: ${error.stderr}`);
|
|
490
|
+
}
|
|
491
|
+
throw new Error(`Worker deployment failed for ${domain}: ${error.message}`);
|
|
377
492
|
}
|
|
378
|
-
return {
|
|
379
|
-
url: workerUrl,
|
|
380
|
-
deployed: true
|
|
381
|
-
};
|
|
382
493
|
}
|
|
383
494
|
|
|
384
495
|
/**
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
import { ConfigurationValidator } from '../security/ConfigurationValidator.js';
|
|
7
7
|
import { SecretGenerator } from '../security/SecretGenerator.js';
|
|
8
|
-
|
|
8
|
+
// DeploymentManager removed - was simulated deployment only
|
|
9
|
+
// Use MultiDomainOrchestrator for real deployments
|
|
10
|
+
|
|
9
11
|
export class SecurityCLI {
|
|
10
12
|
constructor() {
|
|
11
13
|
// Initialize with default settings
|
|
@@ -76,6 +78,7 @@ export class SecurityCLI {
|
|
|
76
78
|
|
|
77
79
|
/**
|
|
78
80
|
* Deploy with security validation
|
|
81
|
+
* @deprecated Use MultiDomainOrchestrator for real deployments
|
|
79
82
|
* @param {string} customer - Customer name
|
|
80
83
|
* @param {string} environment - Environment name
|
|
81
84
|
* @param {Object} options - Deployment options
|
|
@@ -83,89 +86,29 @@ export class SecurityCLI {
|
|
|
83
86
|
* @returns {Object} Deployment result
|
|
84
87
|
*/
|
|
85
88
|
async deployWithSecurity(customer, environment, options = {}) {
|
|
86
|
-
|
|
87
|
-
if (!customer || !environment) {
|
|
88
|
-
throw new Error('Customer and environment are required');
|
|
89
|
-
}
|
|
90
|
-
const result = await DeploymentManager.deployWithSecurity({
|
|
91
|
-
customer,
|
|
92
|
-
environment,
|
|
93
|
-
dryRun: options.dryRun || false
|
|
94
|
-
});
|
|
95
|
-
return {
|
|
96
|
-
success: true,
|
|
97
|
-
customer,
|
|
98
|
-
environment,
|
|
99
|
-
dryRun: options.dryRun,
|
|
100
|
-
deployed: !options.dryRun,
|
|
101
|
-
result
|
|
102
|
-
};
|
|
103
|
-
} catch (error) {
|
|
104
|
-
return {
|
|
105
|
-
success: false,
|
|
106
|
-
customer,
|
|
107
|
-
environment,
|
|
108
|
-
error: error.message
|
|
109
|
-
};
|
|
110
|
-
}
|
|
89
|
+
throw new Error('deployWithSecurity is deprecated. DeploymentManager was simulated deployment only. Use MultiDomainOrchestrator for real deployments.');
|
|
111
90
|
}
|
|
112
91
|
|
|
113
92
|
/**
|
|
114
93
|
* Generate secure configuration
|
|
94
|
+
* @deprecated Use UnifiedConfigManager for configuration management
|
|
115
95
|
* @param {string} customer - Customer name
|
|
116
96
|
* @param {string} environment - Environment name
|
|
117
97
|
* @returns {Object} Configuration generation result
|
|
118
98
|
*/
|
|
119
99
|
generateSecureConfig(customer, environment) {
|
|
120
|
-
|
|
121
|
-
if (!customer || !environment) {
|
|
122
|
-
throw new Error('Customer and environment are required');
|
|
123
|
-
}
|
|
124
|
-
const config = DeploymentManager.generateSecureConfig(customer, environment);
|
|
125
|
-
return {
|
|
126
|
-
success: true,
|
|
127
|
-
customer,
|
|
128
|
-
environment,
|
|
129
|
-
config
|
|
130
|
-
};
|
|
131
|
-
} catch (error) {
|
|
132
|
-
return {
|
|
133
|
-
success: false,
|
|
134
|
-
customer,
|
|
135
|
-
environment,
|
|
136
|
-
error: error.message
|
|
137
|
-
};
|
|
138
|
-
}
|
|
100
|
+
throw new Error('generateSecureConfig is deprecated. Use UnifiedConfigManager for configuration management.');
|
|
139
101
|
}
|
|
140
102
|
|
|
141
103
|
/**
|
|
142
104
|
* Check deployment readiness
|
|
105
|
+
* @deprecated Use MultiDomainOrchestrator's validation instead
|
|
143
106
|
* @param {string} customer - Customer name
|
|
144
107
|
* @param {string} environment - Environment name
|
|
145
108
|
* @returns {Object} Readiness check result
|
|
146
109
|
*/
|
|
147
110
|
checkDeploymentReadiness(customer, environment) {
|
|
148
|
-
|
|
149
|
-
if (!customer || !environment) {
|
|
150
|
-
throw new Error('Customer and environment are required');
|
|
151
|
-
}
|
|
152
|
-
const result = DeploymentManager.validateDeploymentReadiness(customer, environment);
|
|
153
|
-
return {
|
|
154
|
-
success: true,
|
|
155
|
-
customer,
|
|
156
|
-
environment,
|
|
157
|
-
ready: result.ready,
|
|
158
|
-
issues: result.issues || []
|
|
159
|
-
};
|
|
160
|
-
} catch (error) {
|
|
161
|
-
return {
|
|
162
|
-
success: false,
|
|
163
|
-
customer,
|
|
164
|
-
environment,
|
|
165
|
-
ready: false,
|
|
166
|
-
error: error.message
|
|
167
|
-
};
|
|
168
|
-
}
|
|
111
|
+
throw new Error('checkDeploymentReadiness is deprecated. Use MultiDomainOrchestrator validation instead.');
|
|
169
112
|
}
|
|
170
113
|
|
|
171
114
|
/**
|
package/dist/security/index.js
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { ConfigurationValidator } from './ConfigurationValidator.js';
|
|
7
|
-
|
|
7
|
+
// DeploymentManager removed - replaced by MultiDomainOrchestrator + WranglerConfigManager
|
|
8
8
|
import { SecretGenerator } from './SecretGenerator.js';
|
|
9
9
|
import { ErrorHandler } from '../utils/ErrorHandler.js';
|
|
10
|
-
|
|
10
|
+
// InteractiveDeploymentConfigurator removed - replaced by InputCollector
|
|
11
|
+
|
|
11
12
|
export { ConfigurationValidator } from './ConfigurationValidator.js';
|
|
12
|
-
export { DeploymentManager }
|
|
13
|
+
// export { DeploymentManager } - DEPRECATED: Use MultiDomainOrchestrator instead
|
|
13
14
|
export { SecretGenerator } from './SecretGenerator.js';
|
|
14
15
|
export { ErrorHandler } from '../utils/ErrorHandler.js';
|
|
15
|
-
export { InteractiveDeploymentConfigurator }
|
|
16
|
+
// export { InteractiveDeploymentConfigurator } - DEPRECATED: Use InputCollector instead
|
|
16
17
|
|
|
17
18
|
// Re-export patterns and rules for advanced usage
|
|
18
19
|
export { INSECURE_PATTERNS } from './patterns/insecure-patterns.js';
|
|
@@ -25,7 +26,7 @@ export function validateSecurity(config, environment = 'production') {
|
|
|
25
26
|
|
|
26
27
|
// Main secure deployment function
|
|
27
28
|
export async function deployWithSecurity(options) {
|
|
28
|
-
|
|
29
|
+
throw new Error('deployWithSecurity is deprecated. Use MultiDomainOrchestrator instead.');
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// Main key generation function
|
|
@@ -47,5 +48,5 @@ export function handleDeploymentError(error, context = {}) {
|
|
|
47
48
|
|
|
48
49
|
// Main configuration function
|
|
49
50
|
export async function generateConfiguration(defaults = {}) {
|
|
50
|
-
|
|
51
|
+
throw new Error('generateConfiguration is deprecated. Use InputCollector instead.');
|
|
51
52
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { InputHandler } from './handlers/InputHandler.js';
|
|
12
12
|
import { ConfirmationHandler } from './handlers/ConfirmationHandler.js';
|
|
13
13
|
import { GenerationHandler } from './handlers/GenerationHandler.js';
|
|
14
|
-
import {
|
|
14
|
+
import { WranglerConfigManager } from '../utils/deployment/wrangler-config-manager.js';
|
|
15
15
|
import { ValidationHandler } from './handlers/ValidationHandler.js';
|
|
16
16
|
|
|
17
17
|
// Legacy imports for backward compatibility
|
|
@@ -37,7 +37,7 @@ export class ServiceOrchestrator {
|
|
|
37
37
|
outputPath: this.outputPath,
|
|
38
38
|
templatePath: this.templatePath
|
|
39
39
|
});
|
|
40
|
-
this.
|
|
40
|
+
this.wranglerConfigManager = null; // Initialized when needed with specific config path
|
|
41
41
|
this.validationHandler = new ValidationHandler();
|
|
42
42
|
|
|
43
43
|
// Initialize legacy components for backward compatibility
|
|
@@ -398,35 +398,30 @@ export class ServiceOrchestrator {
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
/**
|
|
401
|
-
* Update domain configuration
|
|
401
|
+
* Update domain configuration
|
|
402
|
+
* @deprecated Use WranglerConfigManager directly for wrangler.toml updates
|
|
402
403
|
*/
|
|
403
404
|
async updateDomainConfig(servicePath, currentConfig, updates = null) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const newDomain = await this.confirmationHandler.promptHandler.prompt(`Current domain: ${currentConfig.domainName}\nNew domain name: `);
|
|
407
|
-
if (!newDomain || newDomain === currentConfig.domainName) {
|
|
408
|
-
console.log(chalk.yellow('Domain unchanged'));
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
updates = {
|
|
412
|
-
domainName: newDomain
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
return await this.configMutator.updateDomainConfig(servicePath, currentConfig, updates);
|
|
405
|
+
console.log(chalk.yellow('⚠️ updateDomainConfig is deprecated. Use WranglerConfigManager for wrangler.toml updates.'));
|
|
406
|
+
throw new Error('updateDomainConfig is deprecated. Please use WranglerConfigManager directly.');
|
|
416
407
|
}
|
|
417
408
|
|
|
418
409
|
/**
|
|
419
|
-
* Update Cloudflare configuration
|
|
410
|
+
* Update Cloudflare configuration
|
|
411
|
+
* @deprecated Use WranglerConfigManager directly for wrangler.toml updates
|
|
420
412
|
*/
|
|
421
413
|
async updateCloudflareConfig(servicePath, currentConfig, updates = null) {
|
|
422
|
-
|
|
414
|
+
console.log(chalk.yellow('⚠️ updateCloudflareConfig is deprecated. Use WranglerConfigManager for wrangler.toml updates.'));
|
|
415
|
+
throw new Error('updateCloudflareConfig is deprecated. Please use WranglerConfigManager directly.');
|
|
423
416
|
}
|
|
424
417
|
|
|
425
418
|
/**
|
|
426
|
-
* Update environment configuration
|
|
419
|
+
* Update environment configuration
|
|
420
|
+
* @deprecated Use WranglerConfigManager directly for wrangler.toml updates
|
|
427
421
|
*/
|
|
428
422
|
async updateEnvironmentConfig(servicePath, currentConfig, updates = null) {
|
|
429
|
-
|
|
423
|
+
console.log(chalk.yellow('⚠️ updateEnvironmentConfig is deprecated. Use WranglerConfigManager for wrangler.toml updates.'));
|
|
424
|
+
throw new Error('updateEnvironmentConfig is deprecated. Please use WranglerConfigManager directly.');
|
|
430
425
|
}
|
|
431
426
|
|
|
432
427
|
/**
|