@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
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Worker Router
|
|
3
|
+
* @description Express-like router for Cloudflare Workers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { json, notFound, badRequest } from '../utils/helpers';
|
|
7
|
+
|
|
8
|
+
// ============================================================
|
|
9
|
+
// Route Handler Types
|
|
10
|
+
// ============================================================
|
|
11
|
+
|
|
12
|
+
export type RouteHandler = (
|
|
13
|
+
request: Request,
|
|
14
|
+
params?: Record<string, string>,
|
|
15
|
+
env?: Env,
|
|
16
|
+
ctx?: ExecutionContext
|
|
17
|
+
) => Promise<Response> | Response;
|
|
18
|
+
|
|
19
|
+
export type Middleware = (
|
|
20
|
+
request: Request,
|
|
21
|
+
env?: Env,
|
|
22
|
+
ctx?: ExecutionContext
|
|
23
|
+
) => Promise<Response | null> | Response | null;
|
|
24
|
+
|
|
25
|
+
export interface Route {
|
|
26
|
+
method: string;
|
|
27
|
+
pattern: URLPattern;
|
|
28
|
+
handler: RouteHandler;
|
|
29
|
+
middlewares?: Middleware[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ============================================================
|
|
33
|
+
// Router Class
|
|
34
|
+
// ============================================================
|
|
35
|
+
|
|
36
|
+
export class Router {
|
|
37
|
+
private routes: Route[] = [];
|
|
38
|
+
private globalMiddlewares: Middleware[] = [];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Add global middleware
|
|
42
|
+
*/
|
|
43
|
+
use(middleware: Middleware): Router {
|
|
44
|
+
this.globalMiddlewares.push(middleware);
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Add GET route
|
|
50
|
+
*/
|
|
51
|
+
get(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
52
|
+
return this.addRoute('GET', path, handler, middlewares);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Add POST route
|
|
57
|
+
*/
|
|
58
|
+
post(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
59
|
+
return this.addRoute('POST', path, handler, middlewares);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Add PUT route
|
|
64
|
+
*/
|
|
65
|
+
put(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
66
|
+
return this.addRoute('PUT', path, handler, middlewares);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Add PATCH route
|
|
71
|
+
*/
|
|
72
|
+
patch(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
73
|
+
return this.addRoute('PATCH', path, handler, middlewares);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Add DELETE route
|
|
78
|
+
*/
|
|
79
|
+
delete(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
80
|
+
return this.addRoute('DELETE', path, handler, middlewares);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Add HEAD route
|
|
85
|
+
*/
|
|
86
|
+
head(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
87
|
+
return this.addRoute('HEAD', path, handler, middlewares);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Add OPTIONS route
|
|
92
|
+
*/
|
|
93
|
+
options(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
94
|
+
return this.addRoute('OPTIONS', path, handler, middlewares);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Add route for any method
|
|
99
|
+
*/
|
|
100
|
+
all(path: string, handler: RouteHandler, middlewares?: Middleware[]): Router {
|
|
101
|
+
return this.addRoute('*', path, handler, middlewares);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Add route
|
|
106
|
+
*/
|
|
107
|
+
private addRoute(
|
|
108
|
+
method: string,
|
|
109
|
+
path: string,
|
|
110
|
+
handler: RouteHandler,
|
|
111
|
+
middlewares?: Middleware[]
|
|
112
|
+
): Router {
|
|
113
|
+
// Convert path pattern to URLPattern
|
|
114
|
+
const pattern = new URLPattern({ pathname: path });
|
|
115
|
+
|
|
116
|
+
this.routes.push({
|
|
117
|
+
method,
|
|
118
|
+
pattern,
|
|
119
|
+
handler,
|
|
120
|
+
middlewares,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Group routes with prefix
|
|
128
|
+
*/
|
|
129
|
+
group(prefix: string, callback: (router: Router) => void): Router {
|
|
130
|
+
const groupedRouter = new Router();
|
|
131
|
+
callback(groupedRouter);
|
|
132
|
+
|
|
133
|
+
// Add all routes from grouped router with prefix
|
|
134
|
+
groupedRouter.routes.forEach((route) => {
|
|
135
|
+
const prefixedPath = prefix + route.pattern.pathname;
|
|
136
|
+
this.routes.push({
|
|
137
|
+
...route,
|
|
138
|
+
pattern: new URLPattern({ pathname: prefixedPath }),
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Handle request
|
|
147
|
+
*/
|
|
148
|
+
async handle(
|
|
149
|
+
request: Request,
|
|
150
|
+
env?: Env,
|
|
151
|
+
ctx?: ExecutionContext
|
|
152
|
+
): Promise<Response> {
|
|
153
|
+
const url = new URL(request.url);
|
|
154
|
+
const method = request.method;
|
|
155
|
+
|
|
156
|
+
// Run global middlewares
|
|
157
|
+
for (const middleware of this.globalMiddlewares) {
|
|
158
|
+
const response = await middleware(request, env, ctx);
|
|
159
|
+
if (response) {
|
|
160
|
+
return response;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Find matching route
|
|
165
|
+
for (const route of this.routes) {
|
|
166
|
+
// Check method (wildcard matches all)
|
|
167
|
+
if (route.method !== '*' && route.method !== method) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Check path pattern
|
|
172
|
+
const match = route.pattern.exec(url);
|
|
173
|
+
if (!match) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Extract params
|
|
178
|
+
const params = this.extractParams(match);
|
|
179
|
+
|
|
180
|
+
// Run route middlewares
|
|
181
|
+
if (route.middlewares) {
|
|
182
|
+
for (const middleware of route.middlewares) {
|
|
183
|
+
const response = await middleware(request, env, ctx);
|
|
184
|
+
if (response) {
|
|
185
|
+
return response;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Run handler
|
|
191
|
+
try {
|
|
192
|
+
return await route.handler(request, params, env, ctx);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
return json(
|
|
195
|
+
{
|
|
196
|
+
error: error instanceof Error ? error.message : 'Internal Server Error',
|
|
197
|
+
},
|
|
198
|
+
500
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// No route matched
|
|
204
|
+
return notFound();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Extract params from URLPattern result
|
|
209
|
+
*/
|
|
210
|
+
private extractParams(
|
|
211
|
+
match: URLPatternResult | null
|
|
212
|
+
): Record<string, string> {
|
|
213
|
+
if (!match) {
|
|
214
|
+
return {};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const params: Record<string, string> = {};
|
|
218
|
+
|
|
219
|
+
// Extract pathname groups
|
|
220
|
+
if (match.pathname?.groups) {
|
|
221
|
+
Object.assign(params, match.pathname.groups);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return params;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Get all registered routes
|
|
229
|
+
*/
|
|
230
|
+
getRoutes(): Array<{ method: string; path: string }> {
|
|
231
|
+
return this.routes.map((route) => ({
|
|
232
|
+
method: route.method,
|
|
233
|
+
path: route.pattern.pathname,
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Clear all routes
|
|
239
|
+
*/
|
|
240
|
+
clear(): Router {
|
|
241
|
+
this.routes = [];
|
|
242
|
+
this.globalMiddlewares = [];
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ============================================================
|
|
248
|
+
// Route Builder (Fluent API)
|
|
249
|
+
// ============================================================
|
|
250
|
+
|
|
251
|
+
export class RouteBuilder {
|
|
252
|
+
private router: Router;
|
|
253
|
+
|
|
254
|
+
constructor() {
|
|
255
|
+
this.router = new Router();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Define route with fluent API
|
|
260
|
+
*/
|
|
261
|
+
route(method: string, path: string, handler: RouteHandler): RouteBuilder {
|
|
262
|
+
switch (method.toUpperCase()) {
|
|
263
|
+
case 'GET':
|
|
264
|
+
this.router.get(path, handler);
|
|
265
|
+
break;
|
|
266
|
+
case 'POST':
|
|
267
|
+
this.router.post(path, handler);
|
|
268
|
+
break;
|
|
269
|
+
case 'PUT':
|
|
270
|
+
this.router.put(path, handler);
|
|
271
|
+
break;
|
|
272
|
+
case 'PATCH':
|
|
273
|
+
this.router.patch(path, handler);
|
|
274
|
+
break;
|
|
275
|
+
case 'DELETE':
|
|
276
|
+
this.router.delete(path, handler);
|
|
277
|
+
break;
|
|
278
|
+
case 'HEAD':
|
|
279
|
+
this.router.head(path, handler);
|
|
280
|
+
break;
|
|
281
|
+
case 'OPTIONS':
|
|
282
|
+
this.router.options(path, handler);
|
|
283
|
+
break;
|
|
284
|
+
default:
|
|
285
|
+
this.router.all(path, handler);
|
|
286
|
+
}
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Add middleware
|
|
292
|
+
*/
|
|
293
|
+
use(middleware: Middleware): RouteBuilder {
|
|
294
|
+
this.router.use(middleware);
|
|
295
|
+
return this;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Get router instance
|
|
300
|
+
*/
|
|
301
|
+
build(): Router {
|
|
302
|
+
return this.router;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ============================================================
|
|
307
|
+
// Controller Helpers
|
|
308
|
+
// ============================================================
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Create resource routes (CRUD)
|
|
312
|
+
*/
|
|
313
|
+
export function resource(
|
|
314
|
+
router: Router,
|
|
315
|
+
path: string,
|
|
316
|
+
controller: {
|
|
317
|
+
index?: RouteHandler;
|
|
318
|
+
show?: RouteHandler;
|
|
319
|
+
create?: RouteHandler;
|
|
320
|
+
update?: RouteHandler;
|
|
321
|
+
delete?: RouteHandler;
|
|
322
|
+
}
|
|
323
|
+
): Router {
|
|
324
|
+
if (controller.index) {
|
|
325
|
+
router.get(path, controller.index);
|
|
326
|
+
}
|
|
327
|
+
if (controller.show) {
|
|
328
|
+
router.get(`${path}/:id`, controller.show);
|
|
329
|
+
}
|
|
330
|
+
if (controller.create) {
|
|
331
|
+
router.post(path, controller.create);
|
|
332
|
+
}
|
|
333
|
+
if (controller.update) {
|
|
334
|
+
router.put(`${path}/:id`, controller.update);
|
|
335
|
+
router.patch(`${path}/:id`, controller.update);
|
|
336
|
+
}
|
|
337
|
+
if (controller.delete) {
|
|
338
|
+
router.delete(`${path}/:id`, controller.delete);
|
|
339
|
+
}
|
|
340
|
+
return router;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Create API routes
|
|
345
|
+
*/
|
|
346
|
+
export function api(
|
|
347
|
+
router: Router,
|
|
348
|
+
path: string,
|
|
349
|
+
handlers: {
|
|
350
|
+
list?: RouteHandler;
|
|
351
|
+
get?: RouteHandler;
|
|
352
|
+
create?: RouteHandler;
|
|
353
|
+
update?: RouteHandler;
|
|
354
|
+
delete?: RouteHandler;
|
|
355
|
+
}
|
|
356
|
+
): Router {
|
|
357
|
+
const basePath = path.startsWith('/') ? path : `/${path}`;
|
|
358
|
+
|
|
359
|
+
if (handlers.list) {
|
|
360
|
+
router.get(`${basePath}`, handlers.list);
|
|
361
|
+
}
|
|
362
|
+
if (handlers.get) {
|
|
363
|
+
router.get(`${basePath}/:id`, handlers.get);
|
|
364
|
+
}
|
|
365
|
+
if (handlers.create) {
|
|
366
|
+
router.post(`${basePath}`, handlers.create);
|
|
367
|
+
}
|
|
368
|
+
if (handlers.update) {
|
|
369
|
+
router.put(`${basePath}/:id`, handlers.update);
|
|
370
|
+
router.patch(`${basePath}/:id`, handlers.update);
|
|
371
|
+
}
|
|
372
|
+
if (handlers.delete) {
|
|
373
|
+
router.delete(`${basePath}/:id`, handlers.delete);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return router;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// ============================================================
|
|
380
|
+
// Middleware Helpers
|
|
381
|
+
// ============================================================
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Combine multiple middlewares
|
|
385
|
+
*/
|
|
386
|
+
export function combineMiddlewares(...middlewares: Middleware[]): Middleware {
|
|
387
|
+
return async (request, env, ctx) => {
|
|
388
|
+
for (const middleware of middlewares) {
|
|
389
|
+
const response = await middleware(request, env, ctx);
|
|
390
|
+
if (response) {
|
|
391
|
+
return response;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return null;
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Create conditional middleware
|
|
400
|
+
*/
|
|
401
|
+
export function conditionalMiddleware(
|
|
402
|
+
condition: (request: Request) => boolean,
|
|
403
|
+
middleware: Middleware
|
|
404
|
+
): Middleware {
|
|
405
|
+
return async (request, env, ctx) => {
|
|
406
|
+
if (condition(request)) {
|
|
407
|
+
return middleware(request, env, ctx);
|
|
408
|
+
}
|
|
409
|
+
return null;
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Create path-specific middleware
|
|
415
|
+
*/
|
|
416
|
+
export function pathMiddleware(path: string, middleware: Middleware): Middleware {
|
|
417
|
+
return conditionalMiddleware(
|
|
418
|
+
(request) => {
|
|
419
|
+
const url = new URL(request.url);
|
|
420
|
+
return url.pathname.startsWith(path);
|
|
421
|
+
},
|
|
422
|
+
middleware
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Create method-specific middleware
|
|
428
|
+
*/
|
|
429
|
+
export function methodMiddleware(
|
|
430
|
+
methods: string[],
|
|
431
|
+
middleware: Middleware
|
|
432
|
+
): Middleware {
|
|
433
|
+
return conditionalMiddleware(
|
|
434
|
+
(request) => methods.includes(request.method),
|
|
435
|
+
middleware
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// ============================================================
|
|
440
|
+
// Response Helpers
|
|
441
|
+
// ============================================================
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Send JSON response
|
|
445
|
+
*/
|
|
446
|
+
export const send = json;
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Send success response
|
|
450
|
+
*/
|
|
451
|
+
export function success(data: unknown, message?: string): Response {
|
|
452
|
+
return json({
|
|
453
|
+
success: true,
|
|
454
|
+
...(message && { message }),
|
|
455
|
+
data,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Send error response
|
|
461
|
+
*/
|
|
462
|
+
export function fail(error: string, status: number = 400): Response {
|
|
463
|
+
return json(
|
|
464
|
+
{
|
|
465
|
+
success: false,
|
|
466
|
+
error,
|
|
467
|
+
},
|
|
468
|
+
status
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Send validation error
|
|
474
|
+
*/
|
|
475
|
+
export function validationError(errors: Record<string, string[]>): Response {
|
|
476
|
+
return json(
|
|
477
|
+
{
|
|
478
|
+
success: false,
|
|
479
|
+
error: 'Validation failed',
|
|
480
|
+
errors,
|
|
481
|
+
},
|
|
482
|
+
400
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// ============================================================
|
|
487
|
+
// Request Helpers
|
|
488
|
+
// ============================================================
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Get request body as JSON
|
|
492
|
+
*/
|
|
493
|
+
export async function body<T = unknown>(request: Request): Promise<T> {
|
|
494
|
+
return request.json() as Promise<T>;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Get query params
|
|
499
|
+
*/
|
|
500
|
+
export function query(request: Request): Record<string, string> {
|
|
501
|
+
const url = new URL(request.url);
|
|
502
|
+
return Object.fromEntries(url.searchParams.entries());
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Get path params
|
|
507
|
+
*/
|
|
508
|
+
export function params(request: Request): Record<string, string> {
|
|
509
|
+
// This should be called from within a route handler
|
|
510
|
+
// and relies on the router passing params
|
|
511
|
+
return {};
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Get headers
|
|
516
|
+
*/
|
|
517
|
+
export function headers(request: Request): Headers {
|
|
518
|
+
return request.headers;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Get header value
|
|
523
|
+
*/
|
|
524
|
+
export function header(request: Request, name: string): string | null {
|
|
525
|
+
return request.headers.get(name);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Get cookie value
|
|
530
|
+
*/
|
|
531
|
+
export function cookie(request: Request, name: string): string | null {
|
|
532
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
533
|
+
if (!cookieHeader) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const cookies = cookieHeader.split(';').map((c) => c.trim());
|
|
538
|
+
const target = cookies.find((c) => c.startsWith(`${name}=`));
|
|
539
|
+
|
|
540
|
+
return target ? target.substring(name.length + 1) : null;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// ============================================================
|
|
544
|
+
// Export shorthand
|
|
545
|
+
// ============================================================
|
|
546
|
+
|
|
547
|
+
export const createRouter = (): Router => new Router();
|
|
548
|
+
|
|
549
|
+
export const createBuilder = (): RouteBuilder => new RouteBuilder();
|