@tamyla/clodo-framework 3.1.21 → 3.1.22
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 +9 -0
- package/README.md +53 -0
- package/dist/bin/clodo-service.js +47 -15
- package/dist/bin/commands/deploy.js +115 -83
- package/dist/bin/commands/helpers/deployment-ui.js +138 -0
- package/dist/bin/commands/helpers/deployment-verification.js +251 -0
- package/dist/bin/commands/helpers/error-recovery.js +80 -0
- package/dist/bin/commands/helpers/resource-detection.js +113 -0
- package/dist/bin/commands/validate.js +1 -1
- package/dist/bin/security/security-cli.js +1 -1
- package/dist/bin/shared/cache/configuration-cache.js +82 -0
- package/dist/bin/shared/cloudflare/domain-manager.js +1 -1
- package/dist/bin/shared/cloudflare/index.js +1 -1
- package/dist/bin/shared/cloudflare/ops.js +6 -4
- package/dist/bin/shared/config/ConfigurationManager.js +23 -1
- package/dist/bin/shared/config/command-config-manager.js +19 -3
- package/dist/bin/shared/config/index.js +1 -1
- package/dist/bin/shared/deployment/credential-collector.js +30 -7
- package/dist/bin/shared/deployment/index.js +2 -2
- package/dist/bin/shared/deployment/rollback-manager.js +4 -520
- package/dist/bin/shared/deployment/utilities/d1-error-recovery.js +177 -0
- package/dist/bin/shared/deployment/validator.js +40 -10
- package/dist/bin/shared/deployment/workflows/deployment-summary.js +214 -0
- package/dist/bin/shared/deployment/workflows/interactive-confirmation.js +188 -0
- package/dist/bin/shared/deployment/workflows/interactive-database-workflow.js +234 -0
- package/dist/bin/shared/deployment/workflows/interactive-domain-info-gatherer.js +240 -0
- package/dist/bin/shared/deployment/workflows/interactive-secret-workflow.js +228 -0
- package/dist/bin/shared/deployment/workflows/interactive-testing-workflow.js +235 -0
- package/dist/bin/shared/deployment/workflows/interactive-validation.js +218 -0
- package/dist/bin/shared/error-handling/error-classifier.js +46 -0
- package/dist/bin/shared/monitoring/health-checker.js +129 -1
- package/dist/bin/shared/monitoring/memory-manager.js +17 -6
- package/dist/bin/shared/routing/domain-router.js +1 -1
- package/dist/bin/shared/utils/deployment-validator.js +97 -0
- package/dist/bin/shared/utils/formatters.js +10 -0
- package/dist/bin/shared/utils/index.js +13 -1
- package/dist/bin/shared/utils/interactive-prompts.js +34 -18
- package/dist/bin/shared/utils/progress-manager.js +2 -2
- package/dist/bin/shared/utils/progress-spinner.js +53 -0
- package/dist/bin/shared/utils/sensitive-redactor.js +91 -0
- package/dist/bin/shared/validation/ValidationRegistry.js +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/patterns/insecure-patterns.js +1 -1
- package/dist/utils/constants.js +102 -0
- package/dist/utils/deployment/wrangler-config-manager.js +215 -48
- package/dist/utils/framework-config.js +2 -2
- package/dist/utils/interactive-prompts.js +10 -59
- package/package.json +16 -8
- 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/commands/create.js +0 -77
- package/dist/bin/commands/diagnose.js +0 -83
- package/dist/bin/commands/helpers.js +0 -138
- package/dist/bin/commands/update.js +0 -75
- package/dist/bin/database/deployment-db-manager.js +0 -423
- package/dist/bin/database/enterprise-db-manager.js +0 -457
- package/dist/bin/database/wrangler-d1-manager.js +0 -685
- 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/modules/DeploymentConfiguration.js +0 -395
- package/dist/bin/deployment/modules/DeploymentOrchestrator.js +0 -492
- package/dist/bin/deployment/modules/EnvironmentManager.js +0 -517
- package/dist/bin/deployment/modules/MonitoringIntegration.js +0 -560
- package/dist/bin/deployment/modules/ValidationManager.js +0 -342
- package/dist/bin/deployment/orchestration/BaseDeploymentOrchestrator.js +0 -426
- package/dist/bin/deployment/orchestration/EnterpriseOrchestrator.js +0 -401
- package/dist/bin/deployment/orchestration/PortfolioOrchestrator.js +0 -273
- package/dist/bin/deployment/orchestration/SingleServiceOrchestrator.js +0 -231
- package/dist/bin/deployment/orchestration/UnifiedDeploymentOrchestrator.js +0 -662
- package/dist/bin/deployment/test-interactive-utils.js +0 -66
- package/dist/bin/portfolio/portfolio-manager.js +0 -487
- package/dist/bin/service-management/create-service.js +0 -122
- package/dist/bin/service-management/init-service.js +0 -79
- package/dist/config/customers.js +0 -623
- package/dist/config/domains.js +0 -186
- package/dist/config/index.js +0 -6
- package/dist/database/database-orchestrator.js +0 -795
- package/dist/database/index.js +0 -4
- package/dist/deployment/index.js +0 -11
- package/dist/deployment/orchestration/BaseDeploymentOrchestrator.js +0 -426
- package/dist/deployment/orchestration/EnterpriseOrchestrator.js +0 -401
- package/dist/deployment/orchestration/PortfolioOrchestrator.js +0 -273
- package/dist/deployment/orchestration/SingleServiceOrchestrator.js +0 -231
- package/dist/deployment/orchestration/UnifiedDeploymentOrchestrator.js +0 -662
- package/dist/deployment/orchestration/index.js +0 -17
- package/dist/deployment/rollback-manager.js +0 -36
- package/dist/deployment/wrangler-deployer.js +0 -640
- package/dist/handlers/GenericRouteHandler.js +0 -532
- package/dist/migration/MigrationAdapters.js +0 -562
- package/dist/modules/ModuleManager.js +0 -668
- package/dist/modules/security.js +0 -96
- package/dist/orchestration/cross-domain-coordinator.js +0 -1083
- package/dist/orchestration/index.js +0 -5
- package/dist/orchestration/modules/DeploymentCoordinator.js +0 -368
- package/dist/orchestration/modules/DomainResolver.js +0 -198
- package/dist/orchestration/modules/StateManager.js +0 -332
- package/dist/orchestration/multi-domain-orchestrator.js +0 -724
- package/dist/routing/EnhancedRouter.js +0 -158
- package/dist/schema/SchemaManager.js +0 -778
- package/dist/service-management/ConfirmationEngine.js +0 -412
- package/dist/service-management/ErrorTracker.js +0 -299
- package/dist/service-management/GenerationEngine.js +0 -447
- package/dist/service-management/InputCollector.js +0 -619
- package/dist/service-management/ServiceCreator.js +0 -265
- package/dist/service-management/ServiceInitializer.js +0 -453
- package/dist/service-management/ServiceOrchestrator.js +0 -633
- package/dist/service-management/generators/BaseGenerator.js +0 -233
- package/dist/service-management/generators/GeneratorRegistry.js +0 -254
- package/dist/service-management/generators/cicd/CiWorkflowGenerator.js +0 -87
- package/dist/service-management/generators/cicd/DeployWorkflowGenerator.js +0 -106
- package/dist/service-management/generators/code/ServiceHandlersGenerator.js +0 -235
- package/dist/service-management/generators/code/ServiceMiddlewareGenerator.js +0 -116
- package/dist/service-management/generators/code/ServiceUtilsGenerator.js +0 -246
- package/dist/service-management/generators/code/WorkerIndexGenerator.js +0 -143
- package/dist/service-management/generators/config/DevelopmentEnvGenerator.js +0 -101
- package/dist/service-management/generators/config/DomainsConfigGenerator.js +0 -175
- package/dist/service-management/generators/config/EnvExampleGenerator.js +0 -178
- package/dist/service-management/generators/config/ProductionEnvGenerator.js +0 -97
- package/dist/service-management/generators/config/StagingEnvGenerator.js +0 -97
- package/dist/service-management/generators/config/WranglerTomlGenerator.js +0 -238
- package/dist/service-management/generators/core/PackageJsonGenerator.js +0 -243
- package/dist/service-management/generators/core/SiteConfigGenerator.js +0 -115
- package/dist/service-management/generators/documentation/ApiDocsGenerator.js +0 -331
- package/dist/service-management/generators/documentation/ConfigurationDocsGenerator.js +0 -294
- package/dist/service-management/generators/documentation/DeploymentDocsGenerator.js +0 -244
- package/dist/service-management/generators/documentation/ReadmeGenerator.js +0 -196
- package/dist/service-management/generators/schemas/ServiceSchemaGenerator.js +0 -190
- package/dist/service-management/generators/scripts/DeployScriptGenerator.js +0 -123
- package/dist/service-management/generators/scripts/HealthCheckScriptGenerator.js +0 -101
- package/dist/service-management/generators/scripts/SetupScriptGenerator.js +0 -88
- package/dist/service-management/generators/service-types/StaticSiteGenerator.js +0 -342
- package/dist/service-management/generators/testing/EslintConfigGenerator.js +0 -85
- package/dist/service-management/generators/testing/IntegrationTestsGenerator.js +0 -237
- package/dist/service-management/generators/testing/JestConfigGenerator.js +0 -72
- package/dist/service-management/generators/testing/UnitTestsGenerator.js +0 -277
- package/dist/service-management/generators/tooling/DockerComposeGenerator.js +0 -71
- package/dist/service-management/generators/tooling/GitignoreGenerator.js +0 -143
- package/dist/service-management/generators/utils/FileWriter.js +0 -179
- package/dist/service-management/generators/utils/PathResolver.js +0 -157
- package/dist/service-management/generators/utils/ServiceManifestGenerator.js +0 -111
- package/dist/service-management/generators/utils/TemplateEngine.js +0 -185
- package/dist/service-management/generators/utils/index.js +0 -18
- package/dist/service-management/handlers/ConfirmationHandler.js +0 -71
- package/dist/service-management/handlers/GenerationHandler.js +0 -80
- package/dist/service-management/handlers/InputHandler.js +0 -59
- package/dist/service-management/handlers/ValidationHandler.js +0 -203
- package/dist/service-management/index.js +0 -14
- package/dist/service-management/routing/DomainRouteMapper.js +0 -311
- package/dist/service-management/routing/RouteGenerator.js +0 -266
- package/dist/service-management/routing/WranglerRoutesBuilder.js +0 -273
- package/dist/service-management/routing/index.js +0 -14
- package/dist/service-management/services/DirectoryStructureService.js +0 -56
- package/dist/service-management/services/GenerationCoordinator.js +0 -208
- package/dist/service-management/services/GeneratorRegistry.js +0 -174
- package/dist/services/GenericDataService.js +0 -501
- package/dist/ui-structures/concepts/second-order-acquisition-strategy.md +0 -286
- package/dist/ui-structures/concepts/service-lifecycle-management.md +0 -150
- package/dist/ui-structures/concepts/service-manifest-guide.md +0 -309
- package/dist/ui-structures/concepts/three-tier-categorization-strategy.md +0 -231
- package/dist/ui-structures/creation/automated-generation-ui.json +0 -246
- package/dist/ui-structures/creation/core-inputs-ui.json +0 -217
- package/dist/ui-structures/creation/smart-confirmable-ui.json +0 -451
- package/dist/ui-structures/reference/absolutely-required-inputs.json +0 -315
- package/dist/ui-structures/reference/service-manifest-template.json +0 -342
- package/dist/version/VersionDetector.js +0 -723
- package/dist/worker/index.js +0 -4
- package/dist/worker/integration.js +0 -351
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DomainRouteMapper - Maps domain configurations to route patterns
|
|
3
|
-
*
|
|
4
|
-
* Handles the business logic of converting domain metadata into
|
|
5
|
-
* Cloudflare Workers route patterns with proper specificity ordering.
|
|
6
|
-
*
|
|
7
|
-
* @module service-management/routing/DomainRouteMapper
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { frameworkConfig } from '../../utils/framework-config.js';
|
|
11
|
-
export class DomainRouteMapper {
|
|
12
|
-
constructor(options = {}) {
|
|
13
|
-
// Load environment-specific routing config
|
|
14
|
-
this.frameworkConfig = frameworkConfig;
|
|
15
|
-
this.options = options;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Map domain configuration to route patterns
|
|
20
|
-
*
|
|
21
|
-
* @param {Object} domainConfig - Domain configuration object
|
|
22
|
-
* @param {Object} domainConfig.domains - Domain URLs by environment
|
|
23
|
-
* @param {string} domainConfig.zoneId - Cloudflare zone ID
|
|
24
|
-
* @param {string} domainConfig.apiBasePath - API base path (optional)
|
|
25
|
-
* @param {string} environment - Target environment (production|staging|development)
|
|
26
|
-
*
|
|
27
|
-
* @returns {Object} Route mapping with patterns and zone_id
|
|
28
|
-
* @returns {Array<string>} returns.patterns - Route patterns (ordered by specificity)
|
|
29
|
-
* @returns {string} returns.zoneId - Cloudflare zone ID
|
|
30
|
-
* @returns {string} returns.environment - Environment name
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* const mapper = new DomainRouteMapper();
|
|
34
|
-
* const routes = mapper.mapDomainToRoutes(
|
|
35
|
-
* {
|
|
36
|
-
* domains: { production: 'api.example.com' },
|
|
37
|
-
* zoneId: 'xyz789...',
|
|
38
|
-
* apiBasePath: '/api'
|
|
39
|
-
* },
|
|
40
|
-
* 'production'
|
|
41
|
-
* );
|
|
42
|
-
* // Returns:
|
|
43
|
-
* // {
|
|
44
|
-
* // patterns: ['api.example.com/*', 'example.com/api/*'],
|
|
45
|
-
* // zoneId: 'xyz789...',
|
|
46
|
-
* // environment: 'production'
|
|
47
|
-
* // }
|
|
48
|
-
*/
|
|
49
|
-
mapDomainToRoutes(domainConfig, environment) {
|
|
50
|
-
const domainUrl = domainConfig.domains[environment];
|
|
51
|
-
if (!domainUrl) {
|
|
52
|
-
return {
|
|
53
|
-
patterns: [],
|
|
54
|
-
zoneId: domainConfig.zoneId,
|
|
55
|
-
environment
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Skip workers.dev subdomains (no routes needed)
|
|
60
|
-
const routingConfig = this.frameworkConfig.getRoutingConfig();
|
|
61
|
-
const workersDomain = routingConfig.domains.workersDomain;
|
|
62
|
-
if (domainUrl.includes(workersDomain)) {
|
|
63
|
-
return {
|
|
64
|
-
patterns: [],
|
|
65
|
-
zoneId: domainConfig.zoneId,
|
|
66
|
-
environment
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Generate route patterns based on environment
|
|
71
|
-
let patterns;
|
|
72
|
-
switch (environment) {
|
|
73
|
-
case 'production':
|
|
74
|
-
patterns = this.generateProductionRoutes(domainUrl, domainConfig);
|
|
75
|
-
break;
|
|
76
|
-
case 'staging':
|
|
77
|
-
patterns = this.generateStagingRoutes(domainUrl, domainConfig);
|
|
78
|
-
break;
|
|
79
|
-
case 'development':
|
|
80
|
-
patterns = this.generateDevelopmentRoutes(domainUrl, domainConfig);
|
|
81
|
-
break;
|
|
82
|
-
default:
|
|
83
|
-
patterns = this._generateGenericRoutes(domainUrl, domainConfig);
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
patterns,
|
|
87
|
-
zoneId: domainConfig.zoneId,
|
|
88
|
-
environment
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Generate production environment routes
|
|
94
|
-
*
|
|
95
|
-
* Creates subdomain pattern and root domain fallback
|
|
96
|
-
*
|
|
97
|
-
* @param {string} domain - Domain URL (e.g., api.example.com)
|
|
98
|
-
* @param {Object} config - Domain configuration
|
|
99
|
-
* @returns {Array<string>} Route patterns (ordered by specificity)
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* mapper.generateProductionRoutes('api.example.com', { apiBasePath: '/api' })
|
|
103
|
-
* // Returns: ['api.example.com/*', 'example.com/api/*']
|
|
104
|
-
*/
|
|
105
|
-
generateProductionRoutes(domain, config = {}) {
|
|
106
|
-
const patterns = [];
|
|
107
|
-
|
|
108
|
-
// Check if it's a subdomain
|
|
109
|
-
const isSubdomain = this._isSubdomain(domain);
|
|
110
|
-
if (isSubdomain) {
|
|
111
|
-
// 1. Subdomain wildcard (most specific)
|
|
112
|
-
patterns.push(`${domain}/*`);
|
|
113
|
-
|
|
114
|
-
// 2. Root domain with path fallback
|
|
115
|
-
const rootDomain = this._getRootDomain(domain);
|
|
116
|
-
const pathPrefix = config.apiBasePath || this._getSubdomainPrefix(domain);
|
|
117
|
-
patterns.push(`${rootDomain}${pathPrefix}/*`);
|
|
118
|
-
} else {
|
|
119
|
-
// Root domain only
|
|
120
|
-
const envRouting = this.frameworkConfig.getEnvironmentRoutingConfig('production');
|
|
121
|
-
const pathPrefix = config.apiBasePath || envRouting.defaultPathPrefix;
|
|
122
|
-
patterns.push(`${domain}${pathPrefix}/*`);
|
|
123
|
-
}
|
|
124
|
-
return patterns;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Generate staging environment routes
|
|
129
|
-
*
|
|
130
|
-
* Similar to production but with staging-specific patterns
|
|
131
|
-
*
|
|
132
|
-
* @param {string} domain - Domain URL (e.g., staging-api.example.com)
|
|
133
|
-
* @param {Object} config - Domain configuration
|
|
134
|
-
* @returns {Array<string>} Route patterns (ordered by specificity)
|
|
135
|
-
*/
|
|
136
|
-
generateStagingRoutes(domain, config = {}) {
|
|
137
|
-
const patterns = [];
|
|
138
|
-
|
|
139
|
-
// Check if it's a subdomain
|
|
140
|
-
const isSubdomain = this._isSubdomain(domain);
|
|
141
|
-
if (isSubdomain) {
|
|
142
|
-
// 1. Staging subdomain wildcard
|
|
143
|
-
patterns.push(`${domain}/*`);
|
|
144
|
-
|
|
145
|
-
// 2. Root domain with staging path fallback
|
|
146
|
-
const rootDomain = this._getRootDomain(domain);
|
|
147
|
-
const pathPrefix = config.apiBasePath || this._getSubdomainPrefix(domain);
|
|
148
|
-
patterns.push(`${rootDomain}${pathPrefix}/*`);
|
|
149
|
-
} else {
|
|
150
|
-
// Root domain only
|
|
151
|
-
const envRouting = this.frameworkConfig.getEnvironmentRoutingConfig('staging');
|
|
152
|
-
const pathPrefix = config.apiBasePath || envRouting.defaultPathPrefix;
|
|
153
|
-
patterns.push(`${domain}${pathPrefix}/*`);
|
|
154
|
-
}
|
|
155
|
-
return patterns;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Generate development environment routes
|
|
160
|
-
*
|
|
161
|
-
* Development typically uses workers.dev subdomain (no routes needed)
|
|
162
|
-
* Only generate routes if custom domain explicitly specified
|
|
163
|
-
*
|
|
164
|
-
* @param {string} domain - Domain URL
|
|
165
|
-
* @param {Object} config - Domain configuration
|
|
166
|
-
* @returns {Array<string>} Route patterns (usually empty)
|
|
167
|
-
*/
|
|
168
|
-
generateDevelopmentRoutes(domain, config = {}) {
|
|
169
|
-
// Development typically uses *.workers.dev (no routes needed)
|
|
170
|
-
const routingConfig = this.frameworkConfig.getRoutingConfig();
|
|
171
|
-
const workersDomain = routingConfig.domains.workersDomain;
|
|
172
|
-
if (!domain || domain.includes(workersDomain)) {
|
|
173
|
-
return [];
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// If custom domain specified for development, generate routes
|
|
177
|
-
const patterns = [];
|
|
178
|
-
const isSubdomain = this._isSubdomain(domain);
|
|
179
|
-
if (isSubdomain) {
|
|
180
|
-
patterns.push(`${domain}/*`);
|
|
181
|
-
const rootDomain = this._getRootDomain(domain);
|
|
182
|
-
const pathPrefix = config.apiBasePath || this._getSubdomainPrefix(domain);
|
|
183
|
-
patterns.push(`${rootDomain}${pathPrefix}/*`);
|
|
184
|
-
} else {
|
|
185
|
-
const envRouting = this.frameworkConfig.getEnvironmentRoutingConfig('development');
|
|
186
|
-
const pathPrefix = config.apiBasePath || envRouting.defaultPathPrefix;
|
|
187
|
-
patterns.push(`${domain}${pathPrefix}/*`);
|
|
188
|
-
}
|
|
189
|
-
return patterns;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Generate generic routes (for any environment)
|
|
194
|
-
* @private
|
|
195
|
-
*/
|
|
196
|
-
_generateGenericRoutes(domain, config = {}) {
|
|
197
|
-
const patterns = [];
|
|
198
|
-
const isSubdomain = this._isSubdomain(domain);
|
|
199
|
-
if (isSubdomain) {
|
|
200
|
-
patterns.push(`${domain}/*`);
|
|
201
|
-
const rootDomain = this._getRootDomain(domain);
|
|
202
|
-
const pathPrefix = config.apiBasePath || this._getSubdomainPrefix(domain);
|
|
203
|
-
patterns.push(`${rootDomain}${pathPrefix}/*`);
|
|
204
|
-
} else {
|
|
205
|
-
const envRouting = this.frameworkConfig.getEnvironmentRoutingConfig('production');
|
|
206
|
-
const pathPrefix = config.apiBasePath || envRouting.defaultPathPrefix;
|
|
207
|
-
patterns.push(`${domain}${pathPrefix}/*`);
|
|
208
|
-
}
|
|
209
|
-
return patterns;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Check if domain is a subdomain
|
|
214
|
-
* @private
|
|
215
|
-
*
|
|
216
|
-
* @param {string} domain - Domain name
|
|
217
|
-
* @returns {boolean} True if subdomain, false if root domain
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* _isSubdomain('api.example.com') // true
|
|
221
|
-
* _isSubdomain('example.com') // false
|
|
222
|
-
* _isSubdomain('www.example.com') // true
|
|
223
|
-
*/
|
|
224
|
-
_isSubdomain(domain) {
|
|
225
|
-
if (!domain) return false;
|
|
226
|
-
const parts = domain.split('.');
|
|
227
|
-
|
|
228
|
-
// At least 3 parts = subdomain (e.g., api.example.com)
|
|
229
|
-
// 2 parts = root domain (e.g., example.com)
|
|
230
|
-
// Account for TLDs like .co.uk (4+ parts)
|
|
231
|
-
return parts.length >= 3;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Extract root domain from subdomain
|
|
236
|
-
* @private
|
|
237
|
-
*
|
|
238
|
-
* @param {string} domain - Full domain (e.g., api.example.com)
|
|
239
|
-
* @returns {string} Root domain (e.g., example.com)
|
|
240
|
-
*
|
|
241
|
-
* @example
|
|
242
|
-
* _getRootDomain('api.example.com') // 'example.com'
|
|
243
|
-
* _getRootDomain('staging-api.example.com') // 'example.com'
|
|
244
|
-
* _getRootDomain('example.com') // 'example.com'
|
|
245
|
-
*/
|
|
246
|
-
_getRootDomain(domain) {
|
|
247
|
-
if (!domain) return '';
|
|
248
|
-
const parts = domain.split('.');
|
|
249
|
-
|
|
250
|
-
// Handle different TLD formats
|
|
251
|
-
if (parts.length <= 2) {
|
|
252
|
-
// Already root domain
|
|
253
|
-
return domain;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Extract last 2 parts (handles .com, .org, etc.)
|
|
257
|
-
// TODO: Handle complex TLDs like .co.uk (requires TLD database)
|
|
258
|
-
return parts.slice(-2).join('.');
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Extract subdomain prefix and convert to path
|
|
263
|
-
* @private
|
|
264
|
-
*
|
|
265
|
-
* @param {string} domain - Full domain (e.g., api.example.com)
|
|
266
|
-
* @returns {string} Path prefix (e.g., /api)
|
|
267
|
-
*
|
|
268
|
-
* @example
|
|
269
|
-
* _getSubdomainPrefix('api.example.com') // '/api'
|
|
270
|
-
* _getSubdomainPrefix('staging-api.example.com') // '/staging-api'
|
|
271
|
-
* _getSubdomainPrefix('www.example.com') // '/www'
|
|
272
|
-
*/
|
|
273
|
-
_getSubdomainPrefix(domain) {
|
|
274
|
-
if (!domain) return '';
|
|
275
|
-
const parts = domain.split('.');
|
|
276
|
-
if (parts.length < 3) {
|
|
277
|
-
// Not a subdomain
|
|
278
|
-
return '';
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Get first part (subdomain)
|
|
282
|
-
const subdomain = parts[0];
|
|
283
|
-
|
|
284
|
-
// Convert to path (add leading slash)
|
|
285
|
-
return `/${subdomain}`;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Get zone ID for domain
|
|
290
|
-
*
|
|
291
|
-
* Extracts zone_id from coreInputs with validation
|
|
292
|
-
*
|
|
293
|
-
* @param {string} domain - Domain name
|
|
294
|
-
* @param {Object} coreInputs - Core service inputs
|
|
295
|
-
* @returns {string} Cloudflare zone ID
|
|
296
|
-
* @throws {Error} If zone_id missing or invalid format
|
|
297
|
-
*/
|
|
298
|
-
getZoneIdForDomain(domain, coreInputs) {
|
|
299
|
-
if (!coreInputs || !coreInputs.cloudflareZoneId) {
|
|
300
|
-
throw new Error(`cloudflareZoneId is required for domain "${domain}" route generation`);
|
|
301
|
-
}
|
|
302
|
-
const zoneId = coreInputs.cloudflareZoneId;
|
|
303
|
-
|
|
304
|
-
// Validate zone_id format (32 hex characters)
|
|
305
|
-
const zoneIdPattern = /^[a-f0-9]{32}$/;
|
|
306
|
-
if (!zoneIdPattern.test(zoneId)) {
|
|
307
|
-
throw new Error(`Invalid zone_id format for domain "${domain}". ` + `Expected 32 hex characters, received: "${zoneId}"`);
|
|
308
|
-
}
|
|
309
|
-
return zoneId;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RouteGenerator - Main orchestrator for route generation
|
|
3
|
-
*
|
|
4
|
-
* Generates Cloudflare Workers [[routes]] configuration from domain metadata.
|
|
5
|
-
* This is a CORE IDENTITY feature that completes multi-domain orchestration.
|
|
6
|
-
*
|
|
7
|
-
* @module service-management/routing/RouteGenerator
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { DomainRouteMapper } from './DomainRouteMapper.js';
|
|
11
|
-
import { WranglerRoutesBuilder } from './WranglerRoutesBuilder.js';
|
|
12
|
-
import { frameworkConfig } from '../../utils/framework-config.js';
|
|
13
|
-
export class RouteGenerator {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
this.mapper = new DomainRouteMapper(options);
|
|
16
|
-
this.builder = new WranglerRoutesBuilder(options);
|
|
17
|
-
|
|
18
|
-
// Load routing configuration from validation-config.json
|
|
19
|
-
const routingConfig = frameworkConfig.getRoutingConfig();
|
|
20
|
-
const templateDefaults = frameworkConfig.config.templates?.defaults || {};
|
|
21
|
-
this.options = {
|
|
22
|
-
// Routing defaults from config
|
|
23
|
-
includeComments: routingConfig.defaults.includeComments,
|
|
24
|
-
includeZoneId: routingConfig.defaults.includeZoneId,
|
|
25
|
-
environment: routingConfig.defaults.targetEnvironment,
|
|
26
|
-
// Map targetEnvironment -> environment
|
|
27
|
-
orderStrategy: routingConfig.defaults.orderStrategy,
|
|
28
|
-
// Domain configuration
|
|
29
|
-
workersDomain: templateDefaults.WORKERS_DEV_DOMAIN || 'workers.dev',
|
|
30
|
-
skipPatterns: routingConfig.domains.skipPatterns,
|
|
31
|
-
// Allow runtime overrides
|
|
32
|
-
...options
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Generate routes configuration for wrangler.toml
|
|
38
|
-
*
|
|
39
|
-
* @param {Object} coreInputs - Core service inputs (6 values)
|
|
40
|
-
* @param {string} coreInputs.serviceName - Service name
|
|
41
|
-
* @param {string} coreInputs.serviceType - Service type
|
|
42
|
-
* @param {string} coreInputs.domainName - Domain name
|
|
43
|
-
* @param {string} coreInputs.cloudflareAccountId - Cloudflare account ID
|
|
44
|
-
* @param {string} coreInputs.cloudflareZoneId - Cloudflare zone ID (32 hex chars)
|
|
45
|
-
* @param {string} coreInputs.environment - Environment (production|staging|development)
|
|
46
|
-
*
|
|
47
|
-
* @param {Object} confirmedValues - Confirmed configuration values (15 values)
|
|
48
|
-
* @param {string} confirmedValues.productionUrl - Production URL (e.g., api.example.com)
|
|
49
|
-
* @param {string} confirmedValues.stagingUrl - Staging URL (e.g., staging-api.example.com)
|
|
50
|
-
* @param {string} confirmedValues.developmentUrl - Development URL (optional, defaults to workers.dev)
|
|
51
|
-
* @param {string} confirmedValues.apiBasePath - API base path (e.g., /api)
|
|
52
|
-
* @param {string} confirmedValues.workerName - Worker name
|
|
53
|
-
*
|
|
54
|
-
* @param {Object} options - Generation options
|
|
55
|
-
* @param {boolean} options.includeComments - Include explanatory comments (default: true)
|
|
56
|
-
* @param {boolean} options.includeZoneId - Include zone_id in routes (default: true)
|
|
57
|
-
* @param {string} options.environment - Target environment filter (default: 'all')
|
|
58
|
-
*
|
|
59
|
-
* @returns {string} TOML-formatted routes configuration
|
|
60
|
-
*
|
|
61
|
-
* @throws {Error} If domain configuration is invalid or incomplete
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* const routeGenerator = new RouteGenerator();
|
|
65
|
-
* const routesConfig = routeGenerator.generateRoutes(
|
|
66
|
-
* {
|
|
67
|
-
* serviceName: 'my-api',
|
|
68
|
-
* domainName: 'example.com',
|
|
69
|
-
* cloudflareZoneId: 'abc123...',
|
|
70
|
-
* // ... other core inputs
|
|
71
|
-
* },
|
|
72
|
-
* {
|
|
73
|
-
* productionUrl: 'api.example.com',
|
|
74
|
-
* stagingUrl: 'staging-api.example.com',
|
|
75
|
-
* apiBasePath: '/api',
|
|
76
|
-
* // ... other confirmed values
|
|
77
|
-
* }
|
|
78
|
-
* );
|
|
79
|
-
*/
|
|
80
|
-
generateRoutes(coreInputs, confirmedValues, options = {}) {
|
|
81
|
-
// Merge options
|
|
82
|
-
const opts = {
|
|
83
|
-
...this.options,
|
|
84
|
-
...options
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// Validate inputs
|
|
88
|
-
this.validateDomainConfig(coreInputs, confirmedValues);
|
|
89
|
-
|
|
90
|
-
// Build domain configuration
|
|
91
|
-
const domainConfig = {
|
|
92
|
-
domains: {
|
|
93
|
-
production: confirmedValues.productionUrl,
|
|
94
|
-
staging: confirmedValues.stagingUrl,
|
|
95
|
-
development: confirmedValues.developmentUrl
|
|
96
|
-
},
|
|
97
|
-
zoneId: coreInputs.cloudflareZoneId,
|
|
98
|
-
apiBasePath: confirmedValues.apiBasePath,
|
|
99
|
-
serviceName: coreInputs.serviceName,
|
|
100
|
-
workerName: confirmedValues.workerName
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Generate routes for each environment
|
|
104
|
-
const productionRoutes = this._generateEnvironmentRoutes(domainConfig, 'production', opts);
|
|
105
|
-
const stagingRoutes = this._generateEnvironmentRoutes(domainConfig, 'staging', opts);
|
|
106
|
-
const developmentRoutes = this._generateEnvironmentRoutes(domainConfig, 'development', opts);
|
|
107
|
-
|
|
108
|
-
// Build complete routes section
|
|
109
|
-
let routesSection = '';
|
|
110
|
-
|
|
111
|
-
// Add header comment
|
|
112
|
-
if (opts.includeComments) {
|
|
113
|
-
routesSection += `# Routes configuration for ${domainConfig.serviceName}\n`;
|
|
114
|
-
routesSection += `# Generated by Clodo Framework RouteGenerator\n`;
|
|
115
|
-
routesSection += `# Generated: ${new Date().toISOString()}\n\n`;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Add production routes (top-level)
|
|
119
|
-
if (productionRoutes && (opts.environment === 'all' || opts.environment === 'production')) {
|
|
120
|
-
routesSection += productionRoutes;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Add staging routes
|
|
124
|
-
if (stagingRoutes && (opts.environment === 'all' || opts.environment === 'staging')) {
|
|
125
|
-
if (routesSection && !routesSection.endsWith('\n\n')) {
|
|
126
|
-
routesSection += '\n';
|
|
127
|
-
}
|
|
128
|
-
routesSection += stagingRoutes;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Add development routes (usually none - workers.dev)
|
|
132
|
-
if (developmentRoutes && (opts.environment === 'all' || opts.environment === 'development')) {
|
|
133
|
-
if (routesSection && !routesSection.endsWith('\n\n')) {
|
|
134
|
-
routesSection += '\n';
|
|
135
|
-
}
|
|
136
|
-
routesSection += developmentRoutes;
|
|
137
|
-
}
|
|
138
|
-
return routesSection.trim() + '\n';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Generate routes for a specific environment
|
|
143
|
-
* @private
|
|
144
|
-
*/
|
|
145
|
-
_generateEnvironmentRoutes(domainConfig, environment, options) {
|
|
146
|
-
const domainUrl = domainConfig.domains[environment];
|
|
147
|
-
|
|
148
|
-
// Skip if no domain configured or matches skip patterns
|
|
149
|
-
if (!domainUrl || this._shouldSkipDomain(domainUrl)) {
|
|
150
|
-
// workers.dev subdomain - no routes needed
|
|
151
|
-
if (environment === 'development' && options.includeComments) {
|
|
152
|
-
return this.builder.generateDevComment(domainConfig.workerName);
|
|
153
|
-
}
|
|
154
|
-
return '';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Map domain to route patterns
|
|
158
|
-
const routeMapping = this.mapper.mapDomainToRoutes(domainConfig, environment);
|
|
159
|
-
|
|
160
|
-
// Build TOML routes section
|
|
161
|
-
return this.builder.buildRoutesSection(routeMapping.patterns, environment, {
|
|
162
|
-
zoneId: options.includeZoneId ? routeMapping.zoneId : null,
|
|
163
|
-
includeComments: options.includeComments,
|
|
164
|
-
domain: domainUrl,
|
|
165
|
-
serviceName: domainConfig.serviceName
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Validate domain configuration completeness
|
|
171
|
-
*
|
|
172
|
-
* @param {Object} coreInputs - Core service inputs
|
|
173
|
-
* @param {Object} confirmedValues - Confirmed configuration values
|
|
174
|
-
* @throws {Error} If validation fails
|
|
175
|
-
*/
|
|
176
|
-
validateDomainConfig(coreInputs, confirmedValues) {
|
|
177
|
-
// Check required coreInputs
|
|
178
|
-
if (!coreInputs) {
|
|
179
|
-
throw new Error('coreInputs is required for route generation');
|
|
180
|
-
}
|
|
181
|
-
if (!coreInputs.serviceName) {
|
|
182
|
-
throw new Error('coreInputs.serviceName is required for route generation');
|
|
183
|
-
}
|
|
184
|
-
if (!coreInputs.cloudflareZoneId) {
|
|
185
|
-
throw new Error('coreInputs.cloudflareZoneId is required for route generation');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Validate zone_id format (32 hex characters)
|
|
189
|
-
const zoneIdPattern = /^[a-f0-9]{32}$/;
|
|
190
|
-
if (!zoneIdPattern.test(coreInputs.cloudflareZoneId)) {
|
|
191
|
-
throw new Error('coreInputs.cloudflareZoneId must be a valid Cloudflare zone ID (32 hex characters). ' + `Received: "${coreInputs.cloudflareZoneId}"`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Check required confirmedValues
|
|
195
|
-
if (!confirmedValues) {
|
|
196
|
-
throw new Error('confirmedValues is required for route generation');
|
|
197
|
-
}
|
|
198
|
-
if (!confirmedValues.productionUrl) {
|
|
199
|
-
throw new Error('confirmedValues.productionUrl is required for route generation');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Validate production URL format
|
|
203
|
-
if (!this._isValidDomain(confirmedValues.productionUrl)) {
|
|
204
|
-
throw new Error('confirmedValues.productionUrl must be a valid domain name. ' + `Received: "${confirmedValues.productionUrl}"`);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Check if a string is a valid domain name
|
|
210
|
-
* @private
|
|
211
|
-
*/
|
|
212
|
-
_isValidDomain(domain) {
|
|
213
|
-
if (!domain || typeof domain !== 'string') {
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Basic domain validation
|
|
218
|
-
const domainPattern = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
219
|
-
return domainPattern.test(domain);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Get route patterns for a specific domain and environment
|
|
224
|
-
*
|
|
225
|
-
* @param {string} domain - Domain name (e.g., api.example.com)
|
|
226
|
-
* @param {string} environment - Environment (production|staging|development)
|
|
227
|
-
* @param {Object} options - Additional options
|
|
228
|
-
* @returns {Array<string>} Array of route patterns
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* const patterns = routeGenerator.getRoutePatterns('api.example.com', 'production');
|
|
232
|
-
* // Returns: ['api.example.com/*', 'example.com/api/*']
|
|
233
|
-
*/
|
|
234
|
-
getRoutePatterns(domain, environment, options = {}) {
|
|
235
|
-
const domainConfig = {
|
|
236
|
-
domains: {
|
|
237
|
-
[environment]: domain
|
|
238
|
-
},
|
|
239
|
-
zoneId: options.zoneId || 'placeholder',
|
|
240
|
-
apiBasePath: options.apiBasePath,
|
|
241
|
-
serviceName: options.serviceName || 'service'
|
|
242
|
-
};
|
|
243
|
-
const routeMapping = this.mapper.mapDomainToRoutes(domainConfig, environment);
|
|
244
|
-
return routeMapping.patterns;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Check if a domain should be skipped for route generation
|
|
249
|
-
* @private
|
|
250
|
-
*
|
|
251
|
-
* @param {string} domain - Domain to check
|
|
252
|
-
* @returns {boolean} True if domain should be skipped
|
|
253
|
-
*/
|
|
254
|
-
_shouldSkipDomain(domain) {
|
|
255
|
-
if (!domain) return true;
|
|
256
|
-
|
|
257
|
-
// Check workers.dev domain
|
|
258
|
-
if (domain.includes(this.options.workersDomain)) {
|
|
259
|
-
return true;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Check configured skip patterns
|
|
263
|
-
const skipPatterns = this.options.skipPatterns || [];
|
|
264
|
-
return skipPatterns.some(pattern => domain.includes(pattern));
|
|
265
|
-
}
|
|
266
|
-
}
|