@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,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment Coordinator Module
|
|
3
|
+
* Handles deployment orchestration, batching, and parallel execution
|
|
4
|
+
* Extracted from MultiDomainOrchestrator for focused responsibility
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class DeploymentCoordinator {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.parallelDeployments = options.parallelDeployments || 3;
|
|
10
|
+
this.skipTests = options.skipTests || false;
|
|
11
|
+
this.dryRun = options.dryRun || false;
|
|
12
|
+
this.environment = options.environment || 'production';
|
|
13
|
+
this.batchPauseMs = options.batchPauseMs || 2000;
|
|
14
|
+
this.deploymentPhases = options.phases || ['validation', 'initialization', 'database', 'secrets', 'deployment', 'post-validation'];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Deploy to single domain with comprehensive phase management
|
|
19
|
+
* @param {string} domain - Domain to deploy
|
|
20
|
+
* @param {Object} domainState - Domain state object
|
|
21
|
+
* @param {Object} handlers - Handler functions for each phase
|
|
22
|
+
* @returns {Promise<Object>} Deployment result
|
|
23
|
+
*/
|
|
24
|
+
async deploySingleDomain(domain, domainState, handlers) {
|
|
25
|
+
try {
|
|
26
|
+
domainState.startTime = new Date();
|
|
27
|
+
domainState.status = 'deploying';
|
|
28
|
+
console.log(`\n🚀 Deploying ${domain}`);
|
|
29
|
+
console.log(` Deployment ID: ${domainState.deploymentId}`);
|
|
30
|
+
console.log(` Environment: ${this.environment}`);
|
|
31
|
+
|
|
32
|
+
// Execute deployment phases
|
|
33
|
+
for (const phase of this.deploymentPhases) {
|
|
34
|
+
await this.executeDeploymentPhase(domain, phase, domainState, handlers);
|
|
35
|
+
domainState.phase = `${phase}-complete`;
|
|
36
|
+
}
|
|
37
|
+
domainState.status = 'completed';
|
|
38
|
+
domainState.endTime = new Date();
|
|
39
|
+
console.log(` ✅ ${domain} deployed successfully`);
|
|
40
|
+
return {
|
|
41
|
+
domain,
|
|
42
|
+
success: true,
|
|
43
|
+
deploymentId: domainState.deploymentId,
|
|
44
|
+
duration: domainState.endTime - domainState.startTime,
|
|
45
|
+
phases: this.deploymentPhases.length
|
|
46
|
+
};
|
|
47
|
+
} catch (error) {
|
|
48
|
+
domainState.status = 'failed';
|
|
49
|
+
domainState.error = error.message;
|
|
50
|
+
domainState.endTime = new Date();
|
|
51
|
+
console.error(` ❌ ${domain} deployment failed: ${error.message}`);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Execute specific deployment phase
|
|
58
|
+
* @param {string} domain - Domain being deployed
|
|
59
|
+
* @param {string} phase - Phase name
|
|
60
|
+
* @param {Object} domainState - Domain state object
|
|
61
|
+
* @param {Object} handlers - Phase handler functions
|
|
62
|
+
*/
|
|
63
|
+
async executeDeploymentPhase(domain, phase, domainState, handlers) {
|
|
64
|
+
const phaseHandler = handlers[phase];
|
|
65
|
+
if (!phaseHandler) {
|
|
66
|
+
console.warn(` ⚠️ No handler for phase: ${phase}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
console.log(` 📋 Phase: ${phase}`);
|
|
70
|
+
if (this.dryRun) {
|
|
71
|
+
console.log(` 🔍 DRY RUN: Would execute ${phase} for ${domain}`);
|
|
72
|
+
await new Promise(resolve => setTimeout(resolve, 100)); // Simulate work
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Skip post-validation if tests are disabled
|
|
77
|
+
if (phase === 'post-validation' && this.skipTests) {
|
|
78
|
+
console.log(` ⏭️ Skipping ${phase} (tests disabled)`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
await phaseHandler(domain, domainState);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Deploy to multiple domains with orchestrated coordination
|
|
86
|
+
* @param {Array} domains - Domains to deploy
|
|
87
|
+
* @param {Map} domainStates - Map of domain states
|
|
88
|
+
* @param {Object} handlers - Phase handler functions
|
|
89
|
+
* @returns {Promise<Object>} Portfolio deployment results
|
|
90
|
+
*/
|
|
91
|
+
async deployPortfolio(domains, domainStates, handlers) {
|
|
92
|
+
const startTime = Date.now();
|
|
93
|
+
const results = {
|
|
94
|
+
successful: [],
|
|
95
|
+
failed: [],
|
|
96
|
+
totalDuration: 0,
|
|
97
|
+
summary: {},
|
|
98
|
+
batches: []
|
|
99
|
+
};
|
|
100
|
+
try {
|
|
101
|
+
console.log('🌐 Starting Portfolio Deployment');
|
|
102
|
+
console.log(`📊 Total Domains: ${domains.length}`);
|
|
103
|
+
console.log(`⚡ Parallel Limit: ${this.parallelDeployments}`);
|
|
104
|
+
console.log('');
|
|
105
|
+
|
|
106
|
+
// Deploy domains in batches based on parallel limit
|
|
107
|
+
const batches = this.createDeploymentBatches(domains);
|
|
108
|
+
for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {
|
|
109
|
+
const batch = batches[batchIndex];
|
|
110
|
+
console.log(`📦 Batch ${batchIndex + 1}/${batches.length}: ${batch.join(', ')}`);
|
|
111
|
+
const batchResult = await this.deployBatch(batch, domainStates, handlers);
|
|
112
|
+
results.batches.push(batchResult);
|
|
113
|
+
|
|
114
|
+
// Merge batch results
|
|
115
|
+
results.successful.push(...batchResult.successful);
|
|
116
|
+
results.failed.push(...batchResult.failed);
|
|
117
|
+
|
|
118
|
+
// Brief pause between batches
|
|
119
|
+
if (batchIndex < batches.length - 1) {
|
|
120
|
+
console.log(' ⏳ Pausing between batches...\n');
|
|
121
|
+
await new Promise(resolve => setTimeout(resolve, this.batchPauseMs));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
results.totalDuration = Date.now() - startTime;
|
|
125
|
+
results.summary = this.generateDeploymentSummary(domains.length, results);
|
|
126
|
+
this.logDeploymentComplete(results);
|
|
127
|
+
return results;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('❌ Portfolio deployment failed:', error.message);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Deploy a single batch of domains in parallel
|
|
136
|
+
* @param {Array} batch - Domains in this batch
|
|
137
|
+
* @param {Map} domainStates - Domain states map
|
|
138
|
+
* @param {Object} handlers - Phase handlers
|
|
139
|
+
* @returns {Promise<Object>} Batch results
|
|
140
|
+
*/
|
|
141
|
+
async deployBatch(batch, domainStates, handlers) {
|
|
142
|
+
const batchResults = await Promise.allSettled(batch.map(domain => {
|
|
143
|
+
const domainState = domainStates.get(domain);
|
|
144
|
+
return this.deploySingleDomain(domain, domainState, handlers);
|
|
145
|
+
}));
|
|
146
|
+
const successful = [];
|
|
147
|
+
const failed = [];
|
|
148
|
+
batchResults.forEach((result, index) => {
|
|
149
|
+
const domain = batch[index];
|
|
150
|
+
if (result.status === 'fulfilled') {
|
|
151
|
+
successful.push({
|
|
152
|
+
domain,
|
|
153
|
+
...result.value
|
|
154
|
+
});
|
|
155
|
+
} else {
|
|
156
|
+
failed.push({
|
|
157
|
+
domain,
|
|
158
|
+
error: result.reason.message
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
successful,
|
|
164
|
+
failed,
|
|
165
|
+
batchSize: batch.length
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Create deployment batches based on parallel limit
|
|
171
|
+
* @param {Array} domains - Domains to batch
|
|
172
|
+
* @returns {Array<Array<string>>} Batches of domains
|
|
173
|
+
*/
|
|
174
|
+
createDeploymentBatches(domains) {
|
|
175
|
+
const batches = [];
|
|
176
|
+
for (let i = 0; i < domains.length; i += this.parallelDeployments) {
|
|
177
|
+
batches.push(domains.slice(i, i + this.parallelDeployments));
|
|
178
|
+
}
|
|
179
|
+
return batches;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Generate deployment summary statistics
|
|
184
|
+
* @param {number} totalDomains - Total domain count
|
|
185
|
+
* @param {Object} results - Deployment results
|
|
186
|
+
* @returns {Object} Summary statistics
|
|
187
|
+
*/
|
|
188
|
+
generateDeploymentSummary(totalDomains, results) {
|
|
189
|
+
return {
|
|
190
|
+
total: totalDomains,
|
|
191
|
+
successful: results.successful.length,
|
|
192
|
+
failed: results.failed.length,
|
|
193
|
+
successRate: (results.successful.length / totalDomains * 100).toFixed(1),
|
|
194
|
+
averageDuration: results.successful.length > 0 ? (results.successful.reduce((sum, r) => sum + r.duration, 0) / results.successful.length / 1000).toFixed(1) : 0,
|
|
195
|
+
totalBatches: results.batches.length
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Log deployment completion with formatted output
|
|
201
|
+
* @param {Object} results - Deployment results
|
|
202
|
+
*/
|
|
203
|
+
logDeploymentComplete(results) {
|
|
204
|
+
console.log('\n🎉 PORTFOLIO DEPLOYMENT COMPLETE');
|
|
205
|
+
console.log('================================');
|
|
206
|
+
console.log(`✅ Successful: ${results.summary.successful}/${results.summary.total}`);
|
|
207
|
+
console.log(`❌ Failed: ${results.summary.failed}/${results.summary.total}`);
|
|
208
|
+
console.log(`📊 Success Rate: ${results.summary.successRate}%`);
|
|
209
|
+
console.log(`⏱️ Total Duration: ${(results.totalDuration / 1000).toFixed(1)}s`);
|
|
210
|
+
console.log(`📦 Batches Processed: ${results.summary.totalBatches}`);
|
|
211
|
+
if (results.summary.averageDuration > 0) {
|
|
212
|
+
console.log(`⏱️ Average Duration: ${results.summary.averageDuration}s per domain`);
|
|
213
|
+
}
|
|
214
|
+
if (results.failed.length > 0) {
|
|
215
|
+
console.log('\n❌ Failed Domains:');
|
|
216
|
+
results.failed.forEach(failure => {
|
|
217
|
+
console.log(` - ${failure.domain}: ${failure.error}`);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Validate deployment coordination configuration
|
|
224
|
+
* @returns {Object} Validation result
|
|
225
|
+
*/
|
|
226
|
+
validateConfiguration() {
|
|
227
|
+
const issues = [];
|
|
228
|
+
if (this.parallelDeployments < 1) {
|
|
229
|
+
issues.push('parallelDeployments must be at least 1');
|
|
230
|
+
}
|
|
231
|
+
if (this.parallelDeployments > 10) {
|
|
232
|
+
issues.push('parallelDeployments exceeds recommended maximum of 10');
|
|
233
|
+
}
|
|
234
|
+
if (this.batchPauseMs < 0) {
|
|
235
|
+
issues.push('batchPauseMs cannot be negative');
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
valid: issues.length === 0,
|
|
239
|
+
issues,
|
|
240
|
+
warnings: this.parallelDeployments > 5 ? ['High parallelism may cause rate limiting'] : []
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get coordination statistics
|
|
246
|
+
* @returns {Object} Coordinator statistics
|
|
247
|
+
*/
|
|
248
|
+
getStats() {
|
|
249
|
+
return {
|
|
250
|
+
parallelDeployments: this.parallelDeployments,
|
|
251
|
+
batchPauseMs: this.batchPauseMs,
|
|
252
|
+
phasesCount: this.deploymentPhases.length,
|
|
253
|
+
dryRun: this.dryRun,
|
|
254
|
+
skipTests: this.skipTests,
|
|
255
|
+
environment: this.environment
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain Resolver Module
|
|
3
|
+
* Handles domain discovery, validation, and configuration generation
|
|
4
|
+
* Extracted from MultiDomainOrchestrator for focused responsibility
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class DomainResolver {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.environment = options.environment || 'production';
|
|
10
|
+
this.validationLevel = options.validationLevel || 'basic';
|
|
11
|
+
this.cacheEnabled = options.cacheEnabled !== false;
|
|
12
|
+
this.domainCache = new Map();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Generate standardized domain configuration
|
|
17
|
+
* @param {string} domain - Domain name
|
|
18
|
+
* @returns {Object} Domain configuration object
|
|
19
|
+
*/
|
|
20
|
+
generateDomainConfig(domain) {
|
|
21
|
+
if (this.cacheEnabled && this.domainCache.has(domain)) {
|
|
22
|
+
return this.domainCache.get(domain);
|
|
23
|
+
}
|
|
24
|
+
const cleanDomain = domain.replace(/\./g, '-').replace(/[^a-zA-Z0-9-]/g, '');
|
|
25
|
+
const config = {
|
|
26
|
+
name: domain,
|
|
27
|
+
cleanName: cleanDomain,
|
|
28
|
+
productionName: `${cleanDomain}-data-service`,
|
|
29
|
+
database: {
|
|
30
|
+
name: `${cleanDomain}-auth-db`,
|
|
31
|
+
id: null // Will be discovered/created
|
|
32
|
+
},
|
|
33
|
+
worker: {
|
|
34
|
+
name: `${cleanDomain}-data-service`
|
|
35
|
+
},
|
|
36
|
+
environments: {
|
|
37
|
+
production: domain,
|
|
38
|
+
staging: `staging.${domain}`,
|
|
39
|
+
development: `dev.${domain}`
|
|
40
|
+
},
|
|
41
|
+
metadata: {
|
|
42
|
+
generated: new Date().toISOString(),
|
|
43
|
+
environment: this.environment
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
if (this.cacheEnabled) {
|
|
47
|
+
this.domainCache.set(domain, config);
|
|
48
|
+
}
|
|
49
|
+
return config;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Validate domain prerequisites
|
|
54
|
+
* @param {string} domain - Domain to validate
|
|
55
|
+
* @returns {Promise<Object>} Validation result
|
|
56
|
+
*/
|
|
57
|
+
async validateDomainPrerequisites(domain) {
|
|
58
|
+
console.log(` 🔍 Validating ${domain} prerequisites...`);
|
|
59
|
+
const validation = {
|
|
60
|
+
domain,
|
|
61
|
+
valid: true,
|
|
62
|
+
issues: [],
|
|
63
|
+
warnings: []
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
// Validate required environment variables
|
|
67
|
+
const requiredEnvVars = ['CLOUDFLARE_API_TOKEN', 'CLOUDFLARE_ACCOUNT_ID'];
|
|
68
|
+
const missing = requiredEnvVars.filter(envVar => !process.env[envVar]);
|
|
69
|
+
if (missing.length > 0) {
|
|
70
|
+
validation.valid = false;
|
|
71
|
+
validation.issues.push(`Missing required environment variables: ${missing.join(', ')}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Validate domain format
|
|
75
|
+
if (!this.isValidDomainFormat(domain)) {
|
|
76
|
+
validation.valid = false;
|
|
77
|
+
validation.issues.push(`Invalid domain format: ${domain}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Additional validation based on level
|
|
81
|
+
if (this.validationLevel === 'comprehensive') {
|
|
82
|
+
await this.performComprehensiveValidation(domain, validation);
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
validation.valid = false;
|
|
86
|
+
validation.issues.push(`Validation error: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
return validation;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Resolve multiple domains with their configurations
|
|
93
|
+
* @param {Array} domains - Array of domain names
|
|
94
|
+
* @returns {Promise<Array>} Array of resolved domain configurations
|
|
95
|
+
*/
|
|
96
|
+
async resolveMultipleDomains(domains) {
|
|
97
|
+
const resolved = [];
|
|
98
|
+
for (const domain of domains) {
|
|
99
|
+
const config = this.generateDomainConfig(domain);
|
|
100
|
+
const validation = await this.validateDomainPrerequisites(domain);
|
|
101
|
+
resolved.push({
|
|
102
|
+
...config,
|
|
103
|
+
validation,
|
|
104
|
+
isValid: validation.valid
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return resolved;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Discover domains from configuration files or runtime
|
|
112
|
+
* @param {Object} options - Discovery options
|
|
113
|
+
* @returns {Promise<Array>} Discovered domains
|
|
114
|
+
*/
|
|
115
|
+
async discoverDomains(options = {}) {
|
|
116
|
+
const discovered = [];
|
|
117
|
+
if (options.sources?.includes('config')) {
|
|
118
|
+
const configDomains = await this.discoverFromConfig();
|
|
119
|
+
discovered.push(...configDomains);
|
|
120
|
+
}
|
|
121
|
+
if (options.sources?.includes('runtime')) {
|
|
122
|
+
const runtimeDomains = await this.discoverFromRuntime();
|
|
123
|
+
discovered.push(...runtimeDomains);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Remove duplicates and validate
|
|
127
|
+
const uniqueDomains = [...new Set(discovered)];
|
|
128
|
+
return await this.resolveMultipleDomains(uniqueDomains);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Check if domain format is valid
|
|
133
|
+
* @param {string} domain - Domain to check
|
|
134
|
+
* @returns {boolean} Valid status
|
|
135
|
+
*/
|
|
136
|
+
isValidDomainFormat(domain) {
|
|
137
|
+
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.[a-zA-Z]{2,}$/;
|
|
138
|
+
return domainRegex.test(domain);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Perform comprehensive domain validation
|
|
143
|
+
* @param {string} domain - Domain to validate
|
|
144
|
+
* @param {Object} validation - Validation object to update
|
|
145
|
+
*/
|
|
146
|
+
async performComprehensiveValidation(domain, validation) {
|
|
147
|
+
// Check domain accessibility (basic DNS check)
|
|
148
|
+
try {
|
|
149
|
+
// Note: In a real implementation, this would do DNS lookups
|
|
150
|
+
// For now, just simulate validation
|
|
151
|
+
if (domain.includes('localhost') || domain.includes('127.0.0.1')) {
|
|
152
|
+
validation.warnings.push('Using local domain - may not be accessible externally');
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
validation.warnings.push(`DNS validation failed: ${error.message}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Discover domains from configuration files
|
|
161
|
+
* @returns {Promise<Array>} Configuration-based domains
|
|
162
|
+
*/
|
|
163
|
+
async discoverFromConfig() {
|
|
164
|
+
// Placeholder - would read from actual config files
|
|
165
|
+
console.log(' 📂 Discovering domains from configuration...');
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Discover domains from runtime (e.g., Cloudflare API)
|
|
171
|
+
* @returns {Promise<Array>} Runtime-discovered domains
|
|
172
|
+
*/
|
|
173
|
+
async discoverFromRuntime() {
|
|
174
|
+
// Placeholder - would query Cloudflare API or other runtime sources
|
|
175
|
+
console.log(' 🌐 Discovering domains from runtime...');
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Clear domain configuration cache
|
|
181
|
+
*/
|
|
182
|
+
clearCache() {
|
|
183
|
+
this.domainCache.clear();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get cache statistics
|
|
188
|
+
* @returns {Object} Cache statistics
|
|
189
|
+
*/
|
|
190
|
+
getCacheStats() {
|
|
191
|
+
return {
|
|
192
|
+
size: this.domainCache.size,
|
|
193
|
+
enabled: this.cacheEnabled
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|