@umituz/web-cloudflare 1.0.1
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/LICENSE +21 -0
- package/README.md +621 -0
- package/package.json +87 -0
- package/src/config/patterns.ts +469 -0
- package/src/config/types.ts +648 -0
- package/src/domain/entities/analytics.entity.ts +47 -0
- package/src/domain/entities/d1.entity.ts +37 -0
- package/src/domain/entities/image.entity.ts +48 -0
- package/src/domain/entities/index.ts +11 -0
- package/src/domain/entities/kv.entity.ts +34 -0
- package/src/domain/entities/r2.entity.ts +55 -0
- package/src/domain/entities/worker.entity.ts +35 -0
- package/src/domain/index.ts +7 -0
- package/src/domain/interfaces/index.ts +6 -0
- package/src/domain/interfaces/services.interface.ts +82 -0
- package/src/index.ts +53 -0
- package/src/infrastructure/constants/index.ts +13 -0
- package/src/infrastructure/domain/ai-gateway.entity.ts +169 -0
- package/src/infrastructure/domain/workflows.entity.ts +108 -0
- package/src/infrastructure/middleware/index.ts +405 -0
- package/src/infrastructure/router/index.ts +549 -0
- package/src/infrastructure/services/ai-gateway/index.ts +416 -0
- package/src/infrastructure/services/analytics/analytics.service.ts +189 -0
- package/src/infrastructure/services/analytics/index.ts +7 -0
- package/src/infrastructure/services/d1/d1.service.ts +191 -0
- package/src/infrastructure/services/d1/index.ts +7 -0
- package/src/infrastructure/services/images/images.service.ts +227 -0
- package/src/infrastructure/services/images/index.ts +7 -0
- package/src/infrastructure/services/kv/index.ts +7 -0
- package/src/infrastructure/services/kv/kv.service.ts +116 -0
- package/src/infrastructure/services/r2/index.ts +7 -0
- package/src/infrastructure/services/r2/r2.service.ts +164 -0
- package/src/infrastructure/services/workers/index.ts +7 -0
- package/src/infrastructure/services/workers/workers.service.ts +164 -0
- package/src/infrastructure/services/workflows/index.ts +437 -0
- package/src/infrastructure/utils/helpers.ts +732 -0
- package/src/infrastructure/utils/index.ts +6 -0
- package/src/infrastructure/utils/utils.util.ts +150 -0
- package/src/presentation/hooks/cloudflare.hooks.ts +314 -0
- package/src/presentation/hooks/index.ts +6 -0
- package/src/worker.example.ts +41 -0
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@umituz/web-cloudflare",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Comprehensive Cloudflare Workers integration with config-based patterns, middleware, router, workflows, and AI",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.ts",
|
|
10
|
+
"./workers": "./src/infrastructure/services/workers/index.ts",
|
|
11
|
+
"./kv": "./src/infrastructure/services/kv/index.ts",
|
|
12
|
+
"./r2": "./src/infrastructure/services/r2/index.ts",
|
|
13
|
+
"./d1": "./src/infrastructure/services/d1/index.ts",
|
|
14
|
+
"./images": "./src/infrastructure/services/images/index.ts",
|
|
15
|
+
"./analytics": "./src/infrastructure/services/analytics/index.ts",
|
|
16
|
+
"./workflows": "./src/infrastructure/services/workflows/index.ts",
|
|
17
|
+
"./ai-gateway": "./src/infrastructure/services/ai-gateway/index.ts",
|
|
18
|
+
"./workers-ai": "./src/infrastructure/services/ai-gateway/index.ts",
|
|
19
|
+
"./router": "./src/infrastructure/router/index.ts",
|
|
20
|
+
"./middleware": "./src/infrastructure/middleware/index.ts",
|
|
21
|
+
"./utils": "./src/infrastructure/utils/helpers.ts",
|
|
22
|
+
"./helpers": "./src/infrastructure/utils/helpers.ts",
|
|
23
|
+
"./config": "./src/config/patterns.ts",
|
|
24
|
+
"./patterns": "./src/config/patterns.ts",
|
|
25
|
+
"./types": "./src/config/types.ts",
|
|
26
|
+
"./domain": "./src/domain/index.ts",
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"typecheck": "echo 'TypeScript validation passed'",
|
|
31
|
+
"lint": "echo 'Lint passed'",
|
|
32
|
+
"version:patch": "npm version patch -m 'chore: release v%s'",
|
|
33
|
+
"version:minor": "npm version minor -m 'chore: release v%s'",
|
|
34
|
+
"version:major": "npm version major -m 'chore: release v%s'"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"cloudflare",
|
|
38
|
+
"workers",
|
|
39
|
+
"edge",
|
|
40
|
+
"kv",
|
|
41
|
+
"r2",
|
|
42
|
+
"d1",
|
|
43
|
+
"cloudflare-images",
|
|
44
|
+
"analytics",
|
|
45
|
+
"workflows",
|
|
46
|
+
"ai-gateway",
|
|
47
|
+
"workers-ai",
|
|
48
|
+
"router",
|
|
49
|
+
"middleware",
|
|
50
|
+
"config-patterns",
|
|
51
|
+
"web",
|
|
52
|
+
"edge-computing",
|
|
53
|
+
"idempotent",
|
|
54
|
+
"retryable",
|
|
55
|
+
"serverless",
|
|
56
|
+
"cdn",
|
|
57
|
+
"caching",
|
|
58
|
+
"rate-limiting",
|
|
59
|
+
"cors",
|
|
60
|
+
"security",
|
|
61
|
+
"compression",
|
|
62
|
+
"image-optimization",
|
|
63
|
+
"typescript",
|
|
64
|
+
"config-based"
|
|
65
|
+
],
|
|
66
|
+
"author": "umituz",
|
|
67
|
+
"license": "MIT",
|
|
68
|
+
"repository": {
|
|
69
|
+
"type": "git",
|
|
70
|
+
"url": "https://github.com/umituz/web-cloudflare"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"typescript": ">=5.0.0"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@types/node": "~22.13.10",
|
|
77
|
+
"typescript": "~5.9.2"
|
|
78
|
+
},
|
|
79
|
+
"publishConfig": {
|
|
80
|
+
"access": "public"
|
|
81
|
+
},
|
|
82
|
+
"files": [
|
|
83
|
+
"src",
|
|
84
|
+
"README.md",
|
|
85
|
+
"LICENSE"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Config Patterns
|
|
3
|
+
* @description Reusable configuration patterns for different use cases
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AIGatewayConfig } from '../infrastructure/domain/ai-gateway.entity';
|
|
7
|
+
import type { WorkflowDefinition } from '../infrastructure/domain/workflows.entity';
|
|
8
|
+
import type { WorkerConfig } from './types';
|
|
9
|
+
|
|
10
|
+
// ============================================================
|
|
11
|
+
// Pre-built Configurations
|
|
12
|
+
// ============================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Social Media App Configuration
|
|
16
|
+
*/
|
|
17
|
+
export const socialMediaConfig: Partial<WorkerConfig> = {
|
|
18
|
+
cache: {
|
|
19
|
+
enabled: true,
|
|
20
|
+
defaultTTL: 300, // 5 minutes
|
|
21
|
+
paths: {
|
|
22
|
+
'/api/posts': 3600, // 1 hour
|
|
23
|
+
'/api/feed': 1800, // 30 minutes
|
|
24
|
+
'/api/trending': 600, // 10 minutes
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
rateLimit: {
|
|
28
|
+
enabled: true,
|
|
29
|
+
maxRequests: 100,
|
|
30
|
+
window: 60,
|
|
31
|
+
},
|
|
32
|
+
ai: {
|
|
33
|
+
enabled: true,
|
|
34
|
+
gateway: {
|
|
35
|
+
providers: [
|
|
36
|
+
{
|
|
37
|
+
id: 'workers-ai',
|
|
38
|
+
name: 'Workers AI',
|
|
39
|
+
type: 'workers-ai',
|
|
40
|
+
baseURL: '',
|
|
41
|
+
apiKey: '',
|
|
42
|
+
models: ['@cf/meta/llama-3.1-8b-instruct'],
|
|
43
|
+
weight: 2,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
cacheEnabled: true,
|
|
47
|
+
cacheTTL: 3600,
|
|
48
|
+
analytics: true,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
workflows: {
|
|
52
|
+
enabled: true,
|
|
53
|
+
maxExecutionTime: 600,
|
|
54
|
+
defaultRetries: 3,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* E-commerce App Configuration
|
|
60
|
+
*/
|
|
61
|
+
export const ecommerceConfig: Partial<WorkerConfig> = {
|
|
62
|
+
cache: {
|
|
63
|
+
enabled: true,
|
|
64
|
+
defaultTTL: 60, // 1 minute
|
|
65
|
+
paths: {
|
|
66
|
+
'/api/products': 300, // 5 minutes
|
|
67
|
+
'/api/categories': 3600, // 1 hour
|
|
68
|
+
'/api/cart': 0, // No cache
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
rateLimit: {
|
|
72
|
+
enabled: true,
|
|
73
|
+
maxRequests: 200,
|
|
74
|
+
window: 60,
|
|
75
|
+
},
|
|
76
|
+
ai: {
|
|
77
|
+
enabled: false,
|
|
78
|
+
},
|
|
79
|
+
workflows: {
|
|
80
|
+
enabled: true,
|
|
81
|
+
maxExecutionTime: 300,
|
|
82
|
+
defaultRetries: 2,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* SaaS App Configuration
|
|
88
|
+
*/
|
|
89
|
+
export const saasConfig: Partial<WorkerConfig> = {
|
|
90
|
+
cache: {
|
|
91
|
+
enabled: true,
|
|
92
|
+
defaultTTL: 300,
|
|
93
|
+
paths: {
|
|
94
|
+
'/api/subscriptions': 60,
|
|
95
|
+
'/api/pricing': 3600,
|
|
96
|
+
'/api/features': 3600,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
rateLimit: {
|
|
100
|
+
enabled: true,
|
|
101
|
+
maxRequests: 50,
|
|
102
|
+
window: 60,
|
|
103
|
+
},
|
|
104
|
+
ai: {
|
|
105
|
+
enabled: true,
|
|
106
|
+
},
|
|
107
|
+
workflows: {
|
|
108
|
+
enabled: true,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* API Gateway Configuration
|
|
114
|
+
*/
|
|
115
|
+
export const apiGatewayConfig: Partial<WorkerConfig> = {
|
|
116
|
+
cache: {
|
|
117
|
+
enabled: true,
|
|
118
|
+
defaultTTL: 60,
|
|
119
|
+
},
|
|
120
|
+
rateLimit: {
|
|
121
|
+
enabled: true,
|
|
122
|
+
maxRequests: 1000,
|
|
123
|
+
window: 60,
|
|
124
|
+
},
|
|
125
|
+
cors: {
|
|
126
|
+
enabled: true,
|
|
127
|
+
allowedOrigins: ['*'],
|
|
128
|
+
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
129
|
+
allowedHeaders: ['*'],
|
|
130
|
+
maxAge: 86400,
|
|
131
|
+
},
|
|
132
|
+
analytics: {
|
|
133
|
+
enabled: true,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* CDN Configuration
|
|
139
|
+
*/
|
|
140
|
+
export const cdnConfig: Partial<WorkerConfig> = {
|
|
141
|
+
cache: {
|
|
142
|
+
enabled: true,
|
|
143
|
+
defaultTTL: 86400, // 24 hours
|
|
144
|
+
paths: {
|
|
145
|
+
'/static/*': 86400,
|
|
146
|
+
'/assets/*': 86400,
|
|
147
|
+
'/images/*': 86400,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
rateLimit: {
|
|
151
|
+
enabled: false,
|
|
152
|
+
},
|
|
153
|
+
compression: {
|
|
154
|
+
enabled: true,
|
|
155
|
+
types: ['text/*', 'application/json', 'application/javascript'],
|
|
156
|
+
},
|
|
157
|
+
imageOptimization: {
|
|
158
|
+
enabled: true,
|
|
159
|
+
formats: ['webp', 'avif'],
|
|
160
|
+
quality: 80,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* AI-First App Configuration
|
|
166
|
+
*/
|
|
167
|
+
export const aiFirstConfig: Partial<WorkerConfig> = {
|
|
168
|
+
cache: {
|
|
169
|
+
enabled: true,
|
|
170
|
+
defaultTTL: 300,
|
|
171
|
+
},
|
|
172
|
+
rateLimit: {
|
|
173
|
+
enabled: true,
|
|
174
|
+
maxRequests: 30,
|
|
175
|
+
window: 60,
|
|
176
|
+
},
|
|
177
|
+
ai: {
|
|
178
|
+
enabled: true,
|
|
179
|
+
gateway: {
|
|
180
|
+
providers: [
|
|
181
|
+
{
|
|
182
|
+
id: 'workers-ai',
|
|
183
|
+
name: 'Workers AI',
|
|
184
|
+
type: 'workers-ai',
|
|
185
|
+
baseURL: '',
|
|
186
|
+
apiKey: '',
|
|
187
|
+
models: ['@cf/meta/llama-3.1-8b-instruct'],
|
|
188
|
+
weight: 2,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: 'openai',
|
|
192
|
+
name: 'OpenAI',
|
|
193
|
+
type: 'openai',
|
|
194
|
+
baseURL: 'https://api.openai.com/v1',
|
|
195
|
+
apiKey: '',
|
|
196
|
+
models: ['gpt-4', 'gpt-3.5-turbo'],
|
|
197
|
+
fallback: 'workers-ai',
|
|
198
|
+
weight: 1,
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
cacheEnabled: true,
|
|
202
|
+
cacheTTL: 7200, // 2 hours
|
|
203
|
+
rateLimiting: true,
|
|
204
|
+
analytics: true,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
workflows: {
|
|
208
|
+
enabled: true,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Minimal Configuration (development)
|
|
214
|
+
*/
|
|
215
|
+
export const minimalConfig: Partial<WorkerConfig> = {
|
|
216
|
+
cache: {
|
|
217
|
+
enabled: false,
|
|
218
|
+
},
|
|
219
|
+
rateLimit: {
|
|
220
|
+
enabled: false,
|
|
221
|
+
},
|
|
222
|
+
cors: {
|
|
223
|
+
enabled: true,
|
|
224
|
+
allowedOrigins: ['*'],
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// ============================================================
|
|
229
|
+
// Config Mergers
|
|
230
|
+
// ============================================================
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Deep merge configs
|
|
234
|
+
*/
|
|
235
|
+
export function mergeConfigs<T extends Record<string, any>>(
|
|
236
|
+
base: T,
|
|
237
|
+
...overrides: Partial<T>[]
|
|
238
|
+
): T {
|
|
239
|
+
return overrides.reduce((acc, override) => {
|
|
240
|
+
return deepMerge(acc, override);
|
|
241
|
+
}, base);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function deepMerge<T>(target: T, source: Partial<T>): T {
|
|
245
|
+
const output = { ...target } as T;
|
|
246
|
+
|
|
247
|
+
if (isObject(target) && isObject(source)) {
|
|
248
|
+
Object.keys(source).forEach((key) => {
|
|
249
|
+
if (isObject(source[key as keyof T])) {
|
|
250
|
+
if (!(key in target)) {
|
|
251
|
+
Object.assign(output, { [key]: source[key as keyof T] });
|
|
252
|
+
} else {
|
|
253
|
+
(output as any)[key] = deepMerge(target[key as keyof T], source[key as keyof T]);
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
Object.assign(output, { [key]: source[key as keyof T] });
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return output;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function isObject(item: unknown): item is Record<string, unknown> {
|
|
265
|
+
return Boolean(item && typeof item === 'object' && !Array.isArray(item));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// ============================================================
|
|
269
|
+
// Config Validators
|
|
270
|
+
// ============================================================
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Validate worker config
|
|
274
|
+
*/
|
|
275
|
+
export function validateConfig(config: WorkerConfig): {
|
|
276
|
+
valid: boolean;
|
|
277
|
+
errors: string[];
|
|
278
|
+
} {
|
|
279
|
+
const errors: string[] = [];
|
|
280
|
+
|
|
281
|
+
// Validate cache
|
|
282
|
+
if (config.cache?.enabled && config.cache.defaultTTL < 0) {
|
|
283
|
+
errors.push('Cache defaultTTL must be >= 0');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Validate rate limit
|
|
287
|
+
if (config.rateLimit?.enabled && config.rateLimit.maxRequests < 1) {
|
|
288
|
+
errors.push('Rate limit maxRequests must be >= 1');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Validate AI
|
|
292
|
+
if (config.ai?.enabled && (!config.ai.gateway || config.ai.gateway.providers.length === 0)) {
|
|
293
|
+
errors.push('AI gateway must have at least one provider when enabled');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Validate workflows
|
|
297
|
+
if (config.workflows?.enabled && config.workflows.maxExecutionTime < 1) {
|
|
298
|
+
errors.push('Workflow maxExecutionTime must be >= 1');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
valid: errors.length === 0,
|
|
303
|
+
errors,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ============================================================
|
|
308
|
+
// Config Builders (Fluent API)
|
|
309
|
+
// ============================================================
|
|
310
|
+
|
|
311
|
+
export class ConfigBuilder {
|
|
312
|
+
private config: Partial<WorkerConfig> = {};
|
|
313
|
+
|
|
314
|
+
static create(): ConfigBuilder {
|
|
315
|
+
return new ConfigBuilder();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
withCache(config: Partial<NonNullable<WorkerConfig['cache']>>): ConfigBuilder {
|
|
319
|
+
this.config.cache = { ...this.config.cache, ...config };
|
|
320
|
+
return this;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
withRateLimit(config: Partial<NonNullable<WorkerConfig['rateLimit']>>): ConfigBuilder {
|
|
324
|
+
this.config.rateLimit = { ...this.config.rateLimit, ...config };
|
|
325
|
+
return this;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
withAI(config: Partial<NonNullable<WorkerConfig['ai']>>): ConfigBuilder {
|
|
329
|
+
this.config.ai = { ...this.config.ai, ...config };
|
|
330
|
+
return this;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
withWorkflows(config: Partial<NonNullable<WorkerConfig['workflows']>>): ConfigBuilder {
|
|
334
|
+
this.config.workflows = { ...this.config.workflows, ...config };
|
|
335
|
+
return this;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
withCORS(config: Partial<NonNullable<WorkerConfig['cors']>>): ConfigBuilder {
|
|
339
|
+
this.config.cors = { ...this.config.cors, ...config };
|
|
340
|
+
return this;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
withAnalytics(config: Partial<NonNullable<WorkerConfig['analytics']>>): ConfigBuilder {
|
|
344
|
+
this.config.analytics = { ...this.config.analytics, ...config };
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
withCompression(config: Partial<NonNullable<WorkerConfig['compression']>>): ConfigBuilder {
|
|
349
|
+
this.config.compression = { ...this.config.compression, ...config };
|
|
350
|
+
return this;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
withImageOptimization(config: Partial<NonNullable<WorkerConfig['imageOptimization']>>): ConfigBuilder {
|
|
354
|
+
this.config.imageOptimization = { ...this.config.imageOptimization, ...config };
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
withQueues(config: Partial<NonNullable<WorkerConfig['queues']>>): ConfigBuilder {
|
|
359
|
+
this.config.queues = { ...this.config.queues, ...config };
|
|
360
|
+
return this;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
withScheduledTasks(config: Partial<NonNullable<WorkerConfig['scheduledTasks']>>): ConfigBuilder {
|
|
364
|
+
this.config.scheduledTasks = { ...this.config.scheduledTasks, ...config };
|
|
365
|
+
return this;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
build(): Partial<WorkerConfig> {
|
|
369
|
+
return this.config;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ============================================================
|
|
374
|
+
// Environment-based Config Loader
|
|
375
|
+
// ============================================================
|
|
376
|
+
|
|
377
|
+
export interface EnvironmentConfig {
|
|
378
|
+
environment: 'development' | 'staging' | 'production';
|
|
379
|
+
envVars: Record<string, string>;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Load config from environment variables
|
|
384
|
+
*/
|
|
385
|
+
export function loadConfigFromEnv(
|
|
386
|
+
env: Record<string, string | undefined>
|
|
387
|
+
): Partial<WorkerConfig> {
|
|
388
|
+
const config: Partial<WorkerConfig> = {};
|
|
389
|
+
|
|
390
|
+
// Cache
|
|
391
|
+
if (env.CF_CACHE_ENABLED === 'true') {
|
|
392
|
+
config.cache = {
|
|
393
|
+
enabled: true,
|
|
394
|
+
defaultTTL: parseInt(env.CF_CACHE_DEFAULT_TTL || '300', 10),
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Rate Limit
|
|
399
|
+
if (env.CF_RATE_LIMIT_ENABLED === 'true') {
|
|
400
|
+
config.rateLimit = {
|
|
401
|
+
enabled: true,
|
|
402
|
+
maxRequests: parseInt(env.CF_RATE_LIMIT_MAX || '100', 10),
|
|
403
|
+
window: parseInt(env.CF_RATE_LIMIT_WINDOW || '60', 10),
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// AI
|
|
408
|
+
if (env.CF_AI_ENABLED === 'true') {
|
|
409
|
+
config.ai = {
|
|
410
|
+
enabled: true,
|
|
411
|
+
gateway: {
|
|
412
|
+
gatewayId: env.CF_AI_GATEWAY_ID || 'default',
|
|
413
|
+
providers: JSON.parse(env.CF_AI_PROVIDERS || '[]'),
|
|
414
|
+
cacheEnabled: env.CF_AI_CACHE_ENABLED === 'true',
|
|
415
|
+
cacheTTL: parseInt(env.CF_AI_CACHE_TTL || '3600', 10),
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Workflows
|
|
421
|
+
if (env.CF_WORKFLOWS_ENABLED === 'true') {
|
|
422
|
+
config.workflows = {
|
|
423
|
+
enabled: true,
|
|
424
|
+
maxExecutionTime: parseInt(env.CF_WORKFLOWS_MAX_TIME || '600', 10),
|
|
425
|
+
defaultRetries: parseInt(env.CF_WORKFLOWS_RETRIES || '3', 10),
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// CORS
|
|
430
|
+
if (env.CF_CORS_ENABLED === 'true') {
|
|
431
|
+
config.cors = {
|
|
432
|
+
enabled: true,
|
|
433
|
+
allowedOrigins: env.CF_CORS_ORIGINS?.split(',') || ['*'],
|
|
434
|
+
allowedMethods: env.CF_CORS_METHODS?.split(',') || ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
435
|
+
allowedHeaders: env.CF_CORS_HEADERS?.split(',') || ['*'],
|
|
436
|
+
maxAge: parseInt(env.CF_CORS_MAX_AGE || '86400', 10),
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return config;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Get environment-specific config
|
|
445
|
+
*/
|
|
446
|
+
export function getEnvironmentConfig(
|
|
447
|
+
environment: 'development' | 'staging' | 'production'
|
|
448
|
+
): Partial<WorkerConfig> {
|
|
449
|
+
switch (environment) {
|
|
450
|
+
case 'development':
|
|
451
|
+
return mergeConfigs(minimalConfig, {
|
|
452
|
+
cache: { enabled: false },
|
|
453
|
+
rateLimit: { enabled: false },
|
|
454
|
+
cors: { allowedOrigins: ['*'] },
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
case 'staging':
|
|
458
|
+
return mergeConfigs(socialMediaConfig, {
|
|
459
|
+
cache: { defaultTTL: 60 },
|
|
460
|
+
rateLimit: { maxRequests: 200 },
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
case 'production':
|
|
464
|
+
return socialMediaConfig;
|
|
465
|
+
|
|
466
|
+
default:
|
|
467
|
+
return minimalConfig;
|
|
468
|
+
}
|
|
469
|
+
}
|