@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
package/dist/worker/index.js
DELETED
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
import { COMMON_FEATURES, ConfigurationManager } from "../../dist/bin/shared/config/ConfigurationManager.js";
|
|
2
|
-
import { getDomainFromEnv, createEnvironmentConfig } from '../config/domains.js';
|
|
3
|
-
|
|
4
|
-
// Create a singleton instance of ConfigurationManager for use in integration
|
|
5
|
-
export const configManager = new ConfigurationManager({});
|
|
6
|
-
|
|
7
|
-
// Legacy featureManager compatibility interface using ConfigurationManager
|
|
8
|
-
const featureManager = {
|
|
9
|
-
setDomain: domainConfig => configManager.setDomain(domainConfig),
|
|
10
|
-
getEnabledFeatures: () => configManager.getEnabledFeatures(),
|
|
11
|
-
isEnabled: featureName => configManager.isFeatureEnabled(featureName)
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// Simple inline logger to avoid circular dependency with index.js
|
|
15
|
-
const logger = {
|
|
16
|
-
info: (message, ...args) => console.log(`[WorkerIntegration] ${message}`, ...args),
|
|
17
|
-
error: (message, ...args) => console.error(`[WorkerIntegration] ${message}`, ...args),
|
|
18
|
-
warn: (message, ...args) => console.warn(`[WorkerIntegration] ${message}`, ...args),
|
|
19
|
-
debug: (message, ...args) => console.debug(`[WorkerIntegration] ${message}`, ...args)
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Initializes a service with domain and feature context
|
|
24
|
-
* @param {Object} env - Cloudflare Worker environment
|
|
25
|
-
* @param {Object} domainConfigs - Available domain configurations
|
|
26
|
-
* @returns {Object} Service initialization context
|
|
27
|
-
*/
|
|
28
|
-
export const initializeService = (env, domainConfigs = {}) => {
|
|
29
|
-
try {
|
|
30
|
-
// Get domain configuration from environment
|
|
31
|
-
const domainConfig = getDomainFromEnv(env, domainConfigs);
|
|
32
|
-
if (!domainConfig) {
|
|
33
|
-
throw new Error('No domain configuration found for service initialization');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Set domain in feature manager
|
|
37
|
-
featureManager.setDomain(domainConfig);
|
|
38
|
-
|
|
39
|
-
// Create environment-specific config
|
|
40
|
-
const environment = env.ENVIRONMENT || env.NODE_ENV || 'development';
|
|
41
|
-
const envConfig = createEnvironmentConfig(domainConfig, environment);
|
|
42
|
-
|
|
43
|
-
// Initialize service context
|
|
44
|
-
const serviceContext = {
|
|
45
|
-
domain: domainConfig.name,
|
|
46
|
-
environment,
|
|
47
|
-
features: featureManager.getEnabledFeatures(),
|
|
48
|
-
config: envConfig,
|
|
49
|
-
env,
|
|
50
|
-
isProduction: environment === 'production',
|
|
51
|
-
isStaging: environment === 'staging',
|
|
52
|
-
isDevelopment: environment === 'development'
|
|
53
|
-
};
|
|
54
|
-
logger.info(`Service initialized: ${domainConfig.name} (${environment})`);
|
|
55
|
-
logger.debug(`Enabled features: ${serviceContext.features.join(', ')}`);
|
|
56
|
-
return serviceContext;
|
|
57
|
-
} catch (error) {
|
|
58
|
-
logger.error(`Service initialization failed: ${error.message}`);
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Creates a feature guard middleware for Cloudflare Workers
|
|
65
|
-
* @param {string} featureName - Name of the feature to guard
|
|
66
|
-
* @param {Object} options - Guard options
|
|
67
|
-
* @returns {Function} Feature guard middleware
|
|
68
|
-
*/
|
|
69
|
-
export const createFeatureGuard = (featureName, options = {}) => {
|
|
70
|
-
const {
|
|
71
|
-
fallbackResponse = null,
|
|
72
|
-
required = true,
|
|
73
|
-
logAccess = true
|
|
74
|
-
} = options;
|
|
75
|
-
return handler => {
|
|
76
|
-
return async (request, env, ctx) => {
|
|
77
|
-
const isEnabled = featureManager.isEnabled(featureName);
|
|
78
|
-
if (logAccess) {
|
|
79
|
-
logger.debug(`Feature access: ${featureName} = ${isEnabled}`);
|
|
80
|
-
}
|
|
81
|
-
if (required && !isEnabled) {
|
|
82
|
-
const response = fallbackResponse || new Response(JSON.stringify({
|
|
83
|
-
error: 'Feature not available',
|
|
84
|
-
feature: featureName,
|
|
85
|
-
message: `The ${featureName} feature is not enabled for this domain`
|
|
86
|
-
}), {
|
|
87
|
-
status: 404,
|
|
88
|
-
headers: {
|
|
89
|
-
'Content-Type': 'application/json'
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
logger.warn(`Feature guard blocked access to ${featureName}`);
|
|
93
|
-
return response;
|
|
94
|
-
}
|
|
95
|
-
if (!isEnabled) {
|
|
96
|
-
logger.info(`Feature ${featureName} disabled, skipping handler`);
|
|
97
|
-
return fallbackResponse || new Response('Not Found', {
|
|
98
|
-
status: 404
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Feature is enabled, proceed with handler
|
|
103
|
-
return handler(request, env, ctx);
|
|
104
|
-
};
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates a route-based feature guard
|
|
110
|
-
* @param {Object} routeConfig - Route configuration with feature requirements
|
|
111
|
-
* @returns {Function} Route guard middleware
|
|
112
|
-
*/
|
|
113
|
-
export const createRouteGuard = routeConfig => {
|
|
114
|
-
return handler => {
|
|
115
|
-
return async (request, env, ctx) => {
|
|
116
|
-
// Check route-specific feature requirements
|
|
117
|
-
for (const [feature, required] of Object.entries(routeConfig)) {
|
|
118
|
-
if (required && !featureManager.isEnabled(feature)) {
|
|
119
|
-
logger.warn(`Route blocked: missing required feature ${feature}`);
|
|
120
|
-
return new Response(JSON.stringify({
|
|
121
|
-
error: 'Feature required',
|
|
122
|
-
feature,
|
|
123
|
-
message: `This endpoint requires the ${feature} feature`
|
|
124
|
-
}), {
|
|
125
|
-
status: 403,
|
|
126
|
-
headers: {
|
|
127
|
-
'Content-Type': 'application/json'
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return handler(request, env, ctx);
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Creates an environment-based guard
|
|
139
|
-
* @param {string[]} allowedEnvironments - Array of allowed environments
|
|
140
|
-
* @returns {Function} Environment guard middleware
|
|
141
|
-
*/
|
|
142
|
-
export const createEnvironmentGuard = (allowedEnvironments = ['production', 'staging']) => {
|
|
143
|
-
return handler => {
|
|
144
|
-
return async (request, env, ctx) => {
|
|
145
|
-
const currentEnv = env.ENVIRONMENT || env.NODE_ENV || 'development';
|
|
146
|
-
if (!allowedEnvironments.includes(currentEnv)) {
|
|
147
|
-
logger.warn(`Environment guard blocked: ${currentEnv} not in ${allowedEnvironments.join(', ')}`);
|
|
148
|
-
return new Response('Not Found', {
|
|
149
|
-
status: 404
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
return handler(request, env, ctx);
|
|
153
|
-
};
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Creates a rate limiting guard (basic implementation)
|
|
159
|
-
* @param {Object} options - Rate limiting options
|
|
160
|
-
* @returns {Function} Rate limiting middleware
|
|
161
|
-
*/
|
|
162
|
-
export const createRateLimitGuard = (options = {}) => {
|
|
163
|
-
const {
|
|
164
|
-
windowMs = 60000,
|
|
165
|
-
// 1 minute
|
|
166
|
-
maxRequests = 100,
|
|
167
|
-
skipSuccessfulRequests = false,
|
|
168
|
-
skipFailedRequests = false
|
|
169
|
-
} = options;
|
|
170
|
-
const requests = new Map();
|
|
171
|
-
const cleanup = () => {
|
|
172
|
-
const now = Date.now();
|
|
173
|
-
for (const [key, data] of requests.entries()) {
|
|
174
|
-
if (now - data.resetTime > windowMs) {
|
|
175
|
-
requests.delete(key);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
return handler => {
|
|
180
|
-
return async (request, env, ctx) => {
|
|
181
|
-
// Skip rate limiting if feature is disabled
|
|
182
|
-
if (!featureManager.isEnabled(COMMON_FEATURES.RATE_LIMITING)) {
|
|
183
|
-
return handler(request, env, ctx);
|
|
184
|
-
}
|
|
185
|
-
const clientId = request.headers.get('CF-Connecting-IP') || 'anonymous';
|
|
186
|
-
const now = Date.now();
|
|
187
|
-
cleanup();
|
|
188
|
-
const clientData = requests.get(clientId) || {
|
|
189
|
-
count: 0,
|
|
190
|
-
resetTime: now + windowMs
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
// Reset counter if window has passed
|
|
194
|
-
if (now > clientData.resetTime) {
|
|
195
|
-
clientData.count = 0;
|
|
196
|
-
clientData.resetTime = now + windowMs;
|
|
197
|
-
}
|
|
198
|
-
clientData.count++;
|
|
199
|
-
requests.set(clientId, clientData);
|
|
200
|
-
|
|
201
|
-
// Check if limit exceeded
|
|
202
|
-
if (clientData.count > maxRequests) {
|
|
203
|
-
logger.warn(`Rate limit exceeded for ${clientId}`);
|
|
204
|
-
return new Response(JSON.stringify({
|
|
205
|
-
error: 'Too many requests',
|
|
206
|
-
retryAfter: Math.ceil((clientData.resetTime - now) / 1000)
|
|
207
|
-
}), {
|
|
208
|
-
status: 429,
|
|
209
|
-
headers: {
|
|
210
|
-
'Content-Type': 'application/json',
|
|
211
|
-
'Retry-After': Math.ceil((clientData.resetTime - now) / 1000).toString()
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
const response = await handler(request, env, ctx);
|
|
216
|
-
|
|
217
|
-
// Optionally skip successful/failed requests from count
|
|
218
|
-
if (skipSuccessfulRequests && response.ok || skipFailedRequests && !response.ok) {
|
|
219
|
-
clientData.count--;
|
|
220
|
-
requests.set(clientId, clientData);
|
|
221
|
-
}
|
|
222
|
-
return response;
|
|
223
|
-
};
|
|
224
|
-
};
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Creates CORS middleware
|
|
229
|
-
* @param {Object} options - CORS options
|
|
230
|
-
* @returns {Function} CORS middleware
|
|
231
|
-
*/
|
|
232
|
-
export const createCorsMiddleware = (options = {}) => {
|
|
233
|
-
const {
|
|
234
|
-
origins = ['*'],
|
|
235
|
-
methods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
236
|
-
headers = ['Content-Type', 'Authorization'],
|
|
237
|
-
credentials = false,
|
|
238
|
-
maxAge = 86400
|
|
239
|
-
} = options;
|
|
240
|
-
return handler => {
|
|
241
|
-
return async (request, env, ctx) => {
|
|
242
|
-
// Handle preflight requests
|
|
243
|
-
if (request.method === 'OPTIONS') {
|
|
244
|
-
const origin = request.headers.get('Origin');
|
|
245
|
-
|
|
246
|
-
// Check if origin is allowed
|
|
247
|
-
const isWildcard = origins.includes('*');
|
|
248
|
-
const isOriginAllowed = isWildcard || origin && origins.includes(origin);
|
|
249
|
-
if (!isOriginAllowed) {
|
|
250
|
-
return new Response('CORS policy violation: Origin not allowed', {
|
|
251
|
-
status: 403,
|
|
252
|
-
headers: {
|
|
253
|
-
'Content-Type': 'text/plain'
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
const allowedOrigin = isWildcard ? '*' : origin;
|
|
258
|
-
return new Response(null, {
|
|
259
|
-
status: 200,
|
|
260
|
-
headers: {
|
|
261
|
-
'Access-Control-Allow-Origin': allowedOrigin,
|
|
262
|
-
'Access-Control-Allow-Methods': methods.join(', '),
|
|
263
|
-
'Access-Control-Allow-Headers': headers.join(', '),
|
|
264
|
-
'Access-Control-Max-Age': maxAge.toString(),
|
|
265
|
-
...(credentials && {
|
|
266
|
-
'Access-Control-Allow-Credentials': 'true'
|
|
267
|
-
})
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Handle actual requests
|
|
273
|
-
const response = await handler(request, env, ctx);
|
|
274
|
-
const origin = request.headers.get('Origin');
|
|
275
|
-
|
|
276
|
-
// Add CORS headers to response only if origin is allowed
|
|
277
|
-
const isWildcard = origins.includes('*');
|
|
278
|
-
const isOriginAllowed = isWildcard || origin && origins.includes(origin);
|
|
279
|
-
if (isOriginAllowed) {
|
|
280
|
-
const allowedOrigin = isWildcard ? '*' : origin;
|
|
281
|
-
response.headers.set('Access-Control-Allow-Origin', allowedOrigin);
|
|
282
|
-
response.headers.set('Access-Control-Allow-Methods', methods.join(', '));
|
|
283
|
-
response.headers.set('Access-Control-Allow-Headers', headers.join(', '));
|
|
284
|
-
if (credentials) {
|
|
285
|
-
response.headers.set('Access-Control-Allow-Credentials', 'true');
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return response;
|
|
289
|
-
};
|
|
290
|
-
};
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Creates error handling middleware
|
|
295
|
-
* @param {Object} options - Error handling options
|
|
296
|
-
* @returns {Function} Error handling middleware
|
|
297
|
-
*/
|
|
298
|
-
export const createErrorHandler = (options = {}) => {
|
|
299
|
-
const {
|
|
300
|
-
includeStack = false,
|
|
301
|
-
logErrors = true,
|
|
302
|
-
transformError = null
|
|
303
|
-
} = options;
|
|
304
|
-
return handler => {
|
|
305
|
-
return async (request, env, ctx) => {
|
|
306
|
-
try {
|
|
307
|
-
return await handler(request, env, ctx);
|
|
308
|
-
} catch (error) {
|
|
309
|
-
if (logErrors) {
|
|
310
|
-
logger.error(`Request error: ${error.message}`, {
|
|
311
|
-
url: request.url,
|
|
312
|
-
method: request.method,
|
|
313
|
-
stack: includeStack ? error.stack : undefined
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Transform error if transformer provided
|
|
318
|
-
let errorResponse = {
|
|
319
|
-
error: 'Internal Server Error',
|
|
320
|
-
message: error.message,
|
|
321
|
-
...(includeStack && {
|
|
322
|
-
stack: error.stack
|
|
323
|
-
})
|
|
324
|
-
};
|
|
325
|
-
if (transformError) {
|
|
326
|
-
errorResponse = transformError(error, errorResponse);
|
|
327
|
-
}
|
|
328
|
-
return new Response(JSON.stringify(errorResponse), {
|
|
329
|
-
status: 500,
|
|
330
|
-
headers: {
|
|
331
|
-
'Content-Type': 'application/json'
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
};
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Composes multiple middleware functions
|
|
341
|
-
* @param {...Function} middlewares - Middleware functions to compose
|
|
342
|
-
* @returns {Function} Composed middleware
|
|
343
|
-
*/
|
|
344
|
-
export const composeMiddleware = (...middlewares) => {
|
|
345
|
-
if (middlewares.length === 0) {
|
|
346
|
-
return handler => handler;
|
|
347
|
-
}
|
|
348
|
-
return middlewares.reduceRight((composed, middleware) => {
|
|
349
|
-
return handler => middleware(composed(handler));
|
|
350
|
-
});
|
|
351
|
-
};
|