@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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 umituz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
# @umituz/web-cloudflare
|
|
2
|
+
|
|
3
|
+
Comprehensive Cloudflare Workers integration with config-based patterns, middleware, router, workflows, and AI.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Config-Based Patterns** - Pre-built configurations for different app types
|
|
8
|
+
- ✅ **Express-like Router** - Simple, intuitive routing with middleware support
|
|
9
|
+
- ✅ **Comprehensive Middleware** - CORS, caching, rate limiting, security, compression
|
|
10
|
+
- ✅ **Workers AI Integration** - AI content generation with emotion control
|
|
11
|
+
- ✅ **Workflows** - Idempotent, retryable long-running operations
|
|
12
|
+
- ✅ **AI Gateway** - Multi-provider AI routing with caching and fallback
|
|
13
|
+
- ✅ **Utility Functions** - 100+ helper functions for common tasks
|
|
14
|
+
- ✅ **Type-Safe** - Full TypeScript support
|
|
15
|
+
- ✅ **Tree-Shakeable** - Subpath exports for optimal bundle size
|
|
16
|
+
|
|
17
|
+
## 📦 Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @umituz/web-cloudflare
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 🎯 Quick Start
|
|
24
|
+
|
|
25
|
+
### Using Pre-built Configs
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { socialMediaConfig, ConfigBuilder, WorkerService } from '@umituz/web-cloudflare/config';
|
|
29
|
+
import { createRouter } from '@umituz/web-cloudflare/router';
|
|
30
|
+
import { cors, addCorsHeaders } from '@umituz/web-cloudflare/middleware';
|
|
31
|
+
|
|
32
|
+
// Use pre-built config
|
|
33
|
+
const worker = new WorkerService({
|
|
34
|
+
...socialMediaConfig,
|
|
35
|
+
env: {
|
|
36
|
+
KV: env.KV,
|
|
37
|
+
R2: env.R2,
|
|
38
|
+
D1: env.D1,
|
|
39
|
+
AI: env.AI,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Or build your own
|
|
44
|
+
const customConfig = ConfigBuilder
|
|
45
|
+
.create()
|
|
46
|
+
.withCache({ enabled: true, defaultTTL: 300 })
|
|
47
|
+
.withRateLimit({ enabled: true, maxRequests: 100, window: 60 })
|
|
48
|
+
.withAI({ enabled: true })
|
|
49
|
+
.build();
|
|
50
|
+
|
|
51
|
+
export default {
|
|
52
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
|
|
53
|
+
return worker.handle(request);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Using Router
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { createRouter, json, success, fail } from '@umituz/web-cloudflare/router';
|
|
62
|
+
import { cors } from '@umituz/web-cloudflare/middleware';
|
|
63
|
+
|
|
64
|
+
const router = createRouter()
|
|
65
|
+
.use(cors) // Add CORS middleware
|
|
66
|
+
.get('/api/health', () => json({ status: 'healthy' }))
|
|
67
|
+
.get('/api/users', async () => {
|
|
68
|
+
const users = await fetchUsers();
|
|
69
|
+
return success(users);
|
|
70
|
+
})
|
|
71
|
+
.post('/api/users', async (request) => {
|
|
72
|
+
const body = await request.json();
|
|
73
|
+
const user = await createUser(body);
|
|
74
|
+
return success(user, 'User created');
|
|
75
|
+
})
|
|
76
|
+
.get('/api/users/:id', async (request, params) => {
|
|
77
|
+
const user = await getUser(params.id);
|
|
78
|
+
if (!user) {
|
|
79
|
+
return fail('User not found', 404);
|
|
80
|
+
}
|
|
81
|
+
return success(user);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
fetch: (req, env, ctx) => router.handle(req, env, ctx),
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Using Workflows
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { WorkflowService, WORKFLOW_TEMPLATES } from '@umituz/web-cloudflare/workflows';
|
|
93
|
+
|
|
94
|
+
const workflowService = new WorkflowService({
|
|
95
|
+
KV: env.KV,
|
|
96
|
+
D1: env.D1,
|
|
97
|
+
maxExecutionTime: 600,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Start workflow
|
|
101
|
+
const execution = await workflowService.startExecution('media-processing', {
|
|
102
|
+
mediaUrl: 'https://example.com/video.mp4',
|
|
103
|
+
operations: ['transcode', 'optimize', 'thumbnail'],
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Check status
|
|
107
|
+
const status = await workflowService.getExecution(execution.id);
|
|
108
|
+
|
|
109
|
+
// Resume from any step (idempotent)
|
|
110
|
+
await workflowService.resumeExecution(execution.id, 'transcode');
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Using Workers AI
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { WorkersAIService } from '@umituz/web-cloudflare/workers-ai';
|
|
117
|
+
|
|
118
|
+
const aiService = new WorkersAIService({ bindings: { AI: env.AI } });
|
|
119
|
+
|
|
120
|
+
// Generate content with emotion control
|
|
121
|
+
const content = await aiService.generateSocialContent({
|
|
122
|
+
topic: 'AI in social media',
|
|
123
|
+
platform: 'linkedin',
|
|
124
|
+
tone: 'professional',
|
|
125
|
+
hashtags: true,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Sentiment analysis
|
|
129
|
+
const analysis = await aiService.analyzeSentiment(content);
|
|
130
|
+
// { sentiment: 'positive', confidence: 0.89, emotions: ['excited'] }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 📚 Subpath Exports
|
|
134
|
+
|
|
135
|
+
### Services
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// Workers service
|
|
139
|
+
import { WorkerService } from '@umituz/web-cloudflare/workers';
|
|
140
|
+
|
|
141
|
+
// KV cache
|
|
142
|
+
import { KVService } from '@umituz/web-cloudflare/kv';
|
|
143
|
+
|
|
144
|
+
// R2 storage
|
|
145
|
+
import { R2Service } from '@umituz/web-cloudflare/r2';
|
|
146
|
+
|
|
147
|
+
// D1 database
|
|
148
|
+
import { D1Service } from '@umituz/web-cloudflare/d1';
|
|
149
|
+
|
|
150
|
+
// Images optimization
|
|
151
|
+
import { ImagesService } from '@umituz/web-cloudflare/images';
|
|
152
|
+
|
|
153
|
+
// Analytics
|
|
154
|
+
import { AnalyticsService } from '@umituz/web-cloudflare/analytics';
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Workflows & AI
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Workflows orchestration
|
|
161
|
+
import { WorkflowService, WORKFLOW_TEMPLATES } from '@umituz/web-cloudflare/workflows';
|
|
162
|
+
|
|
163
|
+
// AI Gateway
|
|
164
|
+
import { AIGatewayService } from '@umituz/web-cloudflare/ai-gateway';
|
|
165
|
+
|
|
166
|
+
// Workers AI
|
|
167
|
+
import { WorkersAIService } from '@umituz/web-cloudflare/workers-ai';
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Router & Middleware
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// Router
|
|
174
|
+
import {
|
|
175
|
+
createRouter,
|
|
176
|
+
resource,
|
|
177
|
+
api,
|
|
178
|
+
success,
|
|
179
|
+
fail,
|
|
180
|
+
validationError
|
|
181
|
+
} from '@umituz/web-cloudflare/router';
|
|
182
|
+
|
|
183
|
+
// Middleware
|
|
184
|
+
import {
|
|
185
|
+
cors,
|
|
186
|
+
cache,
|
|
187
|
+
checkRateLimit,
|
|
188
|
+
addSecurityHeaders,
|
|
189
|
+
detectBot,
|
|
190
|
+
logRequest,
|
|
191
|
+
trackResponseTime
|
|
192
|
+
} from '@umituz/web-cloudflare/middleware';
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Config & Types
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// Config patterns
|
|
199
|
+
import {
|
|
200
|
+
socialMediaConfig,
|
|
201
|
+
ecommerceConfig,
|
|
202
|
+
saasConfig,
|
|
203
|
+
apiGatewayConfig,
|
|
204
|
+
cdnConfig,
|
|
205
|
+
aiFirstConfig,
|
|
206
|
+
minimalConfig,
|
|
207
|
+
ConfigBuilder,
|
|
208
|
+
mergeConfigs,
|
|
209
|
+
validateConfig,
|
|
210
|
+
loadConfigFromEnv
|
|
211
|
+
} from '@umituz/web-cloudflare/config';
|
|
212
|
+
|
|
213
|
+
// TypeScript types
|
|
214
|
+
import type {
|
|
215
|
+
WorkerConfig,
|
|
216
|
+
CacheConfig,
|
|
217
|
+
RateLimitConfig,
|
|
218
|
+
AIConfig,
|
|
219
|
+
WorkflowConfig
|
|
220
|
+
} from '@umituz/web-cloudflare/types';
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Utils
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
// Helper functions
|
|
227
|
+
import {
|
|
228
|
+
// Request helpers
|
|
229
|
+
parseBody,
|
|
230
|
+
getClientIP,
|
|
231
|
+
getUserAgent,
|
|
232
|
+
// Response helpers
|
|
233
|
+
json,
|
|
234
|
+
error,
|
|
235
|
+
redirect,
|
|
236
|
+
file,
|
|
237
|
+
stream,
|
|
238
|
+
// Validation
|
|
239
|
+
isValidEmail,
|
|
240
|
+
isValidURL,
|
|
241
|
+
isValidUUID,
|
|
242
|
+
// Cache helpers
|
|
243
|
+
generateCacheKey,
|
|
244
|
+
hash,
|
|
245
|
+
// Time helpers
|
|
246
|
+
parseDuration,
|
|
247
|
+
formatDuration,
|
|
248
|
+
sleep,
|
|
249
|
+
retry,
|
|
250
|
+
// URL helpers
|
|
251
|
+
buildURL,
|
|
252
|
+
parseQueryParams,
|
|
253
|
+
joinPath,
|
|
254
|
+
// Encoding
|
|
255
|
+
base64Encode,
|
|
256
|
+
base64Decode,
|
|
257
|
+
// Random
|
|
258
|
+
randomString,
|
|
259
|
+
randomID,
|
|
260
|
+
// Type guards
|
|
261
|
+
isDefined,
|
|
262
|
+
isEmpty,
|
|
263
|
+
// And 100+ more...
|
|
264
|
+
} from '@umituz/web-cloudflare/utils';
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 🔧 Config Patterns
|
|
268
|
+
|
|
269
|
+
### Pre-built Configs
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
// Social media app
|
|
273
|
+
import { socialMediaConfig } from '@umituz/web-cloudflare/config';
|
|
274
|
+
|
|
275
|
+
// E-commerce app
|
|
276
|
+
import { ecommerceConfig } from '@umituz/web-cloudflare/config';
|
|
277
|
+
|
|
278
|
+
// SaaS app
|
|
279
|
+
import { saasConfig } from '@umituz/web-cloudflare/config';
|
|
280
|
+
|
|
281
|
+
// API gateway
|
|
282
|
+
import { apiGatewayConfig } from '@umituz/web-cloudflare/config';
|
|
283
|
+
|
|
284
|
+
// CDN
|
|
285
|
+
import { cdnConfig } from '@umituz/web-cloudflare/config';
|
|
286
|
+
|
|
287
|
+
// AI-first app
|
|
288
|
+
import { aiFirstConfig } from '@umituz/web-cloudflare/config';
|
|
289
|
+
|
|
290
|
+
// Minimal (development)
|
|
291
|
+
import { minimalConfig } from '@umituz/web-cloudflare/config';
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Custom Config (Builder Pattern)
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import { ConfigBuilder } from '@umituz/web-cloudflare/config';
|
|
298
|
+
|
|
299
|
+
const config = ConfigBuilder
|
|
300
|
+
.create()
|
|
301
|
+
.withCache({
|
|
302
|
+
enabled: true,
|
|
303
|
+
defaultTTL: 300,
|
|
304
|
+
paths: {
|
|
305
|
+
'/api/posts': 3600,
|
|
306
|
+
'/api/users': 0,
|
|
307
|
+
},
|
|
308
|
+
})
|
|
309
|
+
.withRateLimit({
|
|
310
|
+
enabled: true,
|
|
311
|
+
maxRequests: 100,
|
|
312
|
+
window: 60,
|
|
313
|
+
})
|
|
314
|
+
.withAI({
|
|
315
|
+
enabled: true,
|
|
316
|
+
gateway: {
|
|
317
|
+
providers: [
|
|
318
|
+
{
|
|
319
|
+
id: 'workers-ai',
|
|
320
|
+
type: 'workers-ai',
|
|
321
|
+
models: ['@cf/meta/llama-3.1-8b-instruct'],
|
|
322
|
+
weight: 2,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
cacheEnabled: true,
|
|
326
|
+
cacheTTL: 3600,
|
|
327
|
+
},
|
|
328
|
+
})
|
|
329
|
+
.withWorkflows({
|
|
330
|
+
enabled: true,
|
|
331
|
+
maxExecutionTime: 600,
|
|
332
|
+
defaultRetries: 3,
|
|
333
|
+
})
|
|
334
|
+
.withCORS({
|
|
335
|
+
enabled: true,
|
|
336
|
+
allowedOrigins: ['https://example.com'],
|
|
337
|
+
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
338
|
+
})
|
|
339
|
+
.build();
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Environment-based Config
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { loadConfigFromEnv, getEnvironmentConfig } from '@umituz/web-cloudflare/config';
|
|
346
|
+
|
|
347
|
+
// Load from environment variables
|
|
348
|
+
const config = loadConfigFromEnv({
|
|
349
|
+
CF_CACHE_ENABLED: 'true',
|
|
350
|
+
CF_CACHE_DEFAULT_TTL: '300',
|
|
351
|
+
CF_RATE_LIMIT_ENABLED: 'true',
|
|
352
|
+
CF_RATE_LIMIT_MAX: '100',
|
|
353
|
+
CF_AI_ENABLED: 'true',
|
|
354
|
+
CF_WORKFLOWS_ENABLED: 'true',
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// Or use environment presets
|
|
358
|
+
const stagingConfig = getEnvironmentConfig('staging');
|
|
359
|
+
const prodConfig = getEnvironmentConfig('production');
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## 🛣️ Router Examples
|
|
363
|
+
|
|
364
|
+
### Basic Routing
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
import { createRouter } from '@umituz/web-cloudflare/router';
|
|
368
|
+
|
|
369
|
+
const router = createRouter()
|
|
370
|
+
.get('/', () => json({ message: 'Hello World' }))
|
|
371
|
+
.get('/users', () => json({ users: [] }))
|
|
372
|
+
.post('/users', async (req) => {
|
|
373
|
+
const body = await req.json();
|
|
374
|
+
return json({ created: true, id: '123' });
|
|
375
|
+
})
|
|
376
|
+
.delete('/users/:id', (req, params) => {
|
|
377
|
+
return json({ deleted: params.id });
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Resource Routes (CRUD)
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
import { resource } from '@umituz/web-cloudflare/router';
|
|
385
|
+
|
|
386
|
+
const router = createRouter();
|
|
387
|
+
|
|
388
|
+
resource(router, '/api/users', {
|
|
389
|
+
index: async () => json({ users: [] }),
|
|
390
|
+
show: async (req, params) => json({ user: params.id }),
|
|
391
|
+
create: async (req) => {
|
|
392
|
+
const body = await req.json();
|
|
393
|
+
return json({ created: true, ...body }, 201);
|
|
394
|
+
},
|
|
395
|
+
update: async (req, params) => {
|
|
396
|
+
const body = await req.json();
|
|
397
|
+
return json({ updated: params.id, ...body });
|
|
398
|
+
},
|
|
399
|
+
delete: async (req, params) => json({ deleted: params.id }),
|
|
400
|
+
});
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Middleware Chain
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
import { createRouter } from '@umituz/web-cloudflare/router';
|
|
407
|
+
import { cors, checkRateLimit, requireAuth } from '@umituz/web-cloudflare/middleware';
|
|
408
|
+
|
|
409
|
+
const router = createRouter()
|
|
410
|
+
.use(cors)
|
|
411
|
+
.use(checkRateLimit)
|
|
412
|
+
.get('/public', () => json({ message: 'Public' }))
|
|
413
|
+
.get('/protected', requireAuth, () => json({ message: 'Protected' }));
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Route Groups
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
const router = createRouter();
|
|
420
|
+
|
|
421
|
+
router.group('/api/v1', (api) => {
|
|
422
|
+
api.get('/users', () => json({ users: [] }));
|
|
423
|
+
api.post('/users', async (req) => {
|
|
424
|
+
const body = await req.json();
|
|
425
|
+
return json({ created: true });
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// Creates: /api/v1/users
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## 🎭 Middleware Examples
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
import {
|
|
436
|
+
cors,
|
|
437
|
+
cache,
|
|
438
|
+
checkRateLimit,
|
|
439
|
+
addSecurityHeaders,
|
|
440
|
+
detectBot,
|
|
441
|
+
logRequest,
|
|
442
|
+
trackResponseTime
|
|
443
|
+
} from '@umituz/web-cloudflare/middleware';
|
|
444
|
+
|
|
445
|
+
// Apply globally
|
|
446
|
+
const router = createRouter()
|
|
447
|
+
.use(cors)
|
|
448
|
+
.use(checkRateLimit)
|
|
449
|
+
.use(addSecurityHeaders)
|
|
450
|
+
.use(detectBot)
|
|
451
|
+
.use(logRequest)
|
|
452
|
+
.get('/', () => json({ hello: 'world' }));
|
|
453
|
+
|
|
454
|
+
// Or conditionally
|
|
455
|
+
router.use(
|
|
456
|
+
conditionalMiddleware(
|
|
457
|
+
(req) => req.method === 'POST',
|
|
458
|
+
cache
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## 🤖 Workers AI Examples
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import { WorkersAIService } from '@umituz/web-cloudflare/workers-ai';
|
|
467
|
+
|
|
468
|
+
const ai = new WorkersAIService({ bindings: { AI: env.AI } });
|
|
469
|
+
|
|
470
|
+
// Generate social media content
|
|
471
|
+
const content = await ai.generateSocialContent({
|
|
472
|
+
topic: 'Product launch',
|
|
473
|
+
platform: 'twitter',
|
|
474
|
+
tone: 'enthusiastic',
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Generate hashtags
|
|
478
|
+
const tags = await ai.generateHashtags(content, 10);
|
|
479
|
+
|
|
480
|
+
// Analyze sentiment
|
|
481
|
+
const sentiment = await ai.analyzeSentiment(content);
|
|
482
|
+
|
|
483
|
+
// Generate content calendar
|
|
484
|
+
const calendar = await ai.generateContentCalendar('tech startup', 7);
|
|
485
|
+
|
|
486
|
+
// Optimize for SEO
|
|
487
|
+
const optimized = await ai.optimizeSEO(content, ['AI', 'ML']);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## 🔄 Workflow Examples
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
import { WorkflowService } from '@umituz/web-cloudflare/workflows';
|
|
494
|
+
|
|
495
|
+
const workflows = new WorkflowService({
|
|
496
|
+
KV: env.KV,
|
|
497
|
+
D1: env.D1,
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
// Custom workflow
|
|
501
|
+
await workflows.createWorkflow({
|
|
502
|
+
id: 'social-publish',
|
|
503
|
+
name: 'Social Media Publish',
|
|
504
|
+
steps: [
|
|
505
|
+
{
|
|
506
|
+
id: 'validate',
|
|
507
|
+
name: 'Validate Content',
|
|
508
|
+
handler: 'validate-content',
|
|
509
|
+
retryPolicy: {
|
|
510
|
+
maxAttempts: 3,
|
|
511
|
+
backoffMultiplier: 2,
|
|
512
|
+
initialDelay: 1000,
|
|
513
|
+
maxDelay: 10000,
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
id: 'generate-content',
|
|
518
|
+
name: 'Generate AI Content',
|
|
519
|
+
handler: 'ai-generate',
|
|
520
|
+
dependencies: ['validate'],
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
id: 'publish',
|
|
524
|
+
name: 'Publish to Platforms',
|
|
525
|
+
handler: 'social-publish',
|
|
526
|
+
dependencies: ['generate-content'],
|
|
527
|
+
},
|
|
528
|
+
],
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// Execute workflow
|
|
532
|
+
const execution = await workflows.startExecution('social-publish', {
|
|
533
|
+
topic: 'New feature',
|
|
534
|
+
platforms: ['twitter', 'linkedin'],
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
// Check status
|
|
538
|
+
const status = await workflows.getExecution(execution.id);
|
|
539
|
+
|
|
540
|
+
// Resume from any step
|
|
541
|
+
await workflows.resumeExecution(execution.id, 'publish');
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## 💡 Utility Examples
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
import {
|
|
548
|
+
json,
|
|
549
|
+
error,
|
|
550
|
+
redirect,
|
|
551
|
+
getClientIP,
|
|
552
|
+
parseBody,
|
|
553
|
+
isValidEmail,
|
|
554
|
+
generateCacheKey,
|
|
555
|
+
retry,
|
|
556
|
+
sleep
|
|
557
|
+
} from '@umituz/web-cloudflare/utils';
|
|
558
|
+
|
|
559
|
+
// Response helpers
|
|
560
|
+
return json({ success: true }, 201);
|
|
561
|
+
return error('Not found', 404);
|
|
562
|
+
return redirect('/login');
|
|
563
|
+
|
|
564
|
+
// Request helpers
|
|
565
|
+
const ip = getClientIP(request);
|
|
566
|
+
const body = await parseBody<User>(request);
|
|
567
|
+
|
|
568
|
+
// Validation
|
|
569
|
+
if (!isValidEmail(email)) {
|
|
570
|
+
return error('Invalid email', 400);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Cache
|
|
574
|
+
const key = await generateCacheKey(request);
|
|
575
|
+
const hashKey = await hash(key);
|
|
576
|
+
|
|
577
|
+
// Retry with backoff
|
|
578
|
+
const result = await retry(
|
|
579
|
+
() => fetch(url),
|
|
580
|
+
{ maxAttempts: 3, initialDelay: 1000 }
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
// Sleep
|
|
584
|
+
await sleep(1000); // 1 second
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
## 📝 License
|
|
588
|
+
|
|
589
|
+
MIT
|
|
590
|
+
|
|
591
|
+
## 🤝 Contributing
|
|
592
|
+
|
|
593
|
+
Contributions are welcome!
|
|
594
|
+
|
|
595
|
+
## 📦 Package Structure
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
@umituz/web-cloudflare/
|
|
599
|
+
├── src/
|
|
600
|
+
│ ├── config/ # Config patterns and types
|
|
601
|
+
│ ├── domain/ # Domain entities
|
|
602
|
+
│ ├── infrastructure/
|
|
603
|
+
│ │ ├── services/ # Services (workers, kv, r2, d1, etc.)
|
|
604
|
+
│ │ ├── router/ # Express-like router
|
|
605
|
+
│ │ ├── middleware/ # Middleware collection
|
|
606
|
+
│ │ └── utils/ # Helper functions
|
|
607
|
+
│ └── presentation/
|
|
608
|
+
│ └── hooks/ # React hooks
|
|
609
|
+
└── package.json
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
## 🎯 Use Cases
|
|
613
|
+
|
|
614
|
+
- **Social Media Apps** - Content generation, multi-platform publishing
|
|
615
|
+
- **E-commerce** - Product APIs, cart management, payment processing
|
|
616
|
+
- **SaaS** - Subscription management, feature flags
|
|
617
|
+
- **API Gateway** - Rate limiting, caching, routing
|
|
618
|
+
- **CDN** - Static file serving, image optimization
|
|
619
|
+
- **AI-First Apps** - Content generation, sentiment analysis
|
|
620
|
+
|
|
621
|
+
Made with ❤️ by umituz
|