@umituz/web-cloudflare 1.4.4 → 1.4.6
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/package.json +3 -2
- package/src/config/patterns.ts +43 -24
- package/src/domain/entities/analytics.entity.ts +30 -0
- package/src/domain/entities/d1.entity.ts +27 -0
- package/src/domain/entities/image.entity.ts +48 -0
- package/src/domain/entities/kv.entity.ts +37 -0
- package/src/domain/entities/r2.entity.ts +49 -0
- package/src/domain/entities/worker.entity.ts +35 -0
- package/src/domains/analytics/entities/index.ts +2 -2
- package/src/domains/middleware/entities/index.ts +106 -0
- package/src/domains/middleware/index.ts +14 -0
- package/src/domains/middleware/services/auth.service.ts +110 -0
- package/src/domains/middleware/services/cache.service.ts +93 -0
- package/src/domains/middleware/services/cors.service.ts +87 -0
- package/src/domains/middleware/services/index.ts +9 -0
- package/src/domains/middleware/services/rate-limit.service.ts +93 -0
- package/src/domains/middleware/types/index.ts +5 -0
- package/src/domains/middleware/types/service.interface.ts +122 -0
- package/src/domains/workers/entities/index.ts +1 -1
- package/src/domains/workflows/entities/index.ts +60 -0
- package/src/domains/wrangler/entities/index.ts +2 -2
- package/src/domains/wrangler/services/wrangler.service.ts +16 -8
- package/src/domains/wrangler/types/service.interface.ts +2 -2
- package/src/index.ts +2 -2
- package/src/infrastructure/middleware/index.ts +23 -8
- package/src/infrastructure/router/index.ts +26 -4
- package/src/infrastructure/utils/helpers.ts +25 -11
- package/src/infrastructure/utils/utils.util.ts +3 -2
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Service
|
|
3
|
+
* @description Caching middleware for Cloudflare Workers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { CacheConfig } from '../entities';
|
|
7
|
+
|
|
8
|
+
interface CacheEntry {
|
|
9
|
+
response: Response;
|
|
10
|
+
expires: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const cacheStore = new Map<string, CacheEntry>();
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Cache middleware
|
|
17
|
+
*/
|
|
18
|
+
export async function cache(
|
|
19
|
+
request: Request,
|
|
20
|
+
config: CacheConfig
|
|
21
|
+
): Promise<Response | null> {
|
|
22
|
+
if (!config.enabled) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const url = new URL(request.url);
|
|
27
|
+
const cacheKey = `${config.prefix || 'cache'}:${url.pathname}${url.search}`;
|
|
28
|
+
|
|
29
|
+
// Check if path should bypass cache
|
|
30
|
+
if (config.bypassPaths?.some((path) => url.pathname.startsWith(path))) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Check cache
|
|
35
|
+
const cached = cacheStore.get(cacheKey);
|
|
36
|
+
if (cached && cached.expires > Date.now()) {
|
|
37
|
+
return cached.response;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Set cache
|
|
45
|
+
*/
|
|
46
|
+
export function setCache(
|
|
47
|
+
request: Request,
|
|
48
|
+
response: Response,
|
|
49
|
+
config: CacheConfig
|
|
50
|
+
): void {
|
|
51
|
+
if (!config.enabled) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const url = new URL(request.url);
|
|
56
|
+
const cacheKey = `${config.prefix || 'cache'}:${url.pathname}${url.search}`;
|
|
57
|
+
|
|
58
|
+
// Determine TTL
|
|
59
|
+
let ttl = config.defaultTTL;
|
|
60
|
+
for (const [path, pathTTL] of Object.entries(config.paths || {})) {
|
|
61
|
+
if (url.pathname.startsWith(path)) {
|
|
62
|
+
ttl = pathTTL;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Don't cache if TTL is 0
|
|
68
|
+
if (ttl === 0) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Cache the response
|
|
73
|
+
cacheStore.set(cacheKey, {
|
|
74
|
+
response: response.clone(),
|
|
75
|
+
expires: Date.now() + ttl * 1000,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Invalidate cache
|
|
81
|
+
*/
|
|
82
|
+
export function invalidateCache(pattern?: string): void {
|
|
83
|
+
if (!pattern) {
|
|
84
|
+
cacheStore.clear();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const key of cacheStore.keys()) {
|
|
89
|
+
if (key.includes(pattern)) {
|
|
90
|
+
cacheStore.delete(key);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS Service
|
|
3
|
+
* @description Cross-Origin Resource Sharing middleware for Cloudflare Workers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { CORSConfig } from '../entities';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Add CORS headers to response
|
|
10
|
+
*/
|
|
11
|
+
export function addCorsHeaders(
|
|
12
|
+
request: Request,
|
|
13
|
+
response: Response,
|
|
14
|
+
config: CORSConfig
|
|
15
|
+
): Response {
|
|
16
|
+
if (!config.enabled) {
|
|
17
|
+
return response;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const headers = new Headers(response.headers);
|
|
21
|
+
const origin = request.headers.get('Origin');
|
|
22
|
+
|
|
23
|
+
// Check if origin is allowed
|
|
24
|
+
const allowedOrigin = config.allowedOrigins.includes('*')
|
|
25
|
+
? '*'
|
|
26
|
+
: config.allowedOrigins.includes(origin || '')
|
|
27
|
+
? origin
|
|
28
|
+
: config.allowedOrigins[0];
|
|
29
|
+
|
|
30
|
+
headers.set('Access-Control-Allow-Origin', allowedOrigin);
|
|
31
|
+
headers.set('Access-Control-Allow-Methods', config.allowedMethods.join(', '));
|
|
32
|
+
headers.set('Access-Control-Allow-Headers', config.allowedHeaders.join(', '));
|
|
33
|
+
|
|
34
|
+
if (config.exposedHeaders) {
|
|
35
|
+
headers.set('Access-Control-Expose-Headers', config.exposedHeaders.join(', '));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (config.allowCredentials) {
|
|
39
|
+
headers.set('Access-Control-Allow-Credentials', 'true');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (config.maxAge) {
|
|
43
|
+
headers.set('Access-Control-Max-Age', config.maxAge.toString());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return new Response(response.body, {
|
|
47
|
+
status: response.status,
|
|
48
|
+
statusText: response.statusText,
|
|
49
|
+
headers,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* CORS middleware
|
|
55
|
+
*/
|
|
56
|
+
export async function cors(
|
|
57
|
+
request: Request,
|
|
58
|
+
config: CORSConfig
|
|
59
|
+
): Promise<Response | null> {
|
|
60
|
+
if (!config.enabled) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Handle preflight request
|
|
65
|
+
if (request.method === 'OPTIONS') {
|
|
66
|
+
const headers = new Headers();
|
|
67
|
+
const origin = request.headers.get('Origin');
|
|
68
|
+
|
|
69
|
+
const allowedOrigin = config.allowedOrigins.includes('*')
|
|
70
|
+
? '*'
|
|
71
|
+
: config.allowedOrigins.includes(origin || '')
|
|
72
|
+
? origin
|
|
73
|
+
: config.allowedOrigins[0];
|
|
74
|
+
|
|
75
|
+
headers.set('Access-Control-Allow-Origin', allowedOrigin);
|
|
76
|
+
headers.set('Access-Control-Allow-Methods', config.allowedMethods.join(', '));
|
|
77
|
+
headers.set('Access-Control-Allow-Headers', config.allowedHeaders.join(', '));
|
|
78
|
+
|
|
79
|
+
if (config.maxAge) {
|
|
80
|
+
headers.set('Access-Control-Max-Age', config.maxAge.toString());
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return new Response(null, { headers });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Services
|
|
3
|
+
* @description Middleware service implementations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { cors, addCorsHeaders } from './cors.service';
|
|
7
|
+
export { cache, setCache, invalidateCache } from './cache.service';
|
|
8
|
+
export { checkRateLimit } from './rate-limit.service';
|
|
9
|
+
export { requireAuth, addUserContext } from './auth.service';
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limit Service
|
|
3
|
+
* @description Rate limiting middleware for Cloudflare Workers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { RateLimitConfig } from '../entities';
|
|
7
|
+
|
|
8
|
+
interface RateLimitEntry {
|
|
9
|
+
count: number;
|
|
10
|
+
resetTime: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const rateLimitStore = new Map<string, RateLimitEntry>();
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get rate limit key
|
|
17
|
+
*/
|
|
18
|
+
function getRateLimitKey(request: Request, config: RateLimitConfig): string {
|
|
19
|
+
const parts: string[] = [];
|
|
20
|
+
|
|
21
|
+
if (config.by === 'ip' || config.by === 'both') {
|
|
22
|
+
parts.push(request.headers.get('CF-Connecting-IP') || 'unknown');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (config.by === 'user' || config.by === 'both') {
|
|
26
|
+
const auth = request.headers.get('Authorization');
|
|
27
|
+
if (auth) {
|
|
28
|
+
parts.push(auth.substring(0, 20));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (config.customKeys) {
|
|
33
|
+
for (const key of config.customKeys) {
|
|
34
|
+
parts.push(request.headers.get(key) || '');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return parts.join(':') || 'default';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Check rate limit
|
|
43
|
+
*/
|
|
44
|
+
export async function checkRateLimit(
|
|
45
|
+
request: Request,
|
|
46
|
+
config: RateLimitConfig
|
|
47
|
+
): Promise<Response | null> {
|
|
48
|
+
if (!config.enabled) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const key = getRateLimitKey(request, config);
|
|
53
|
+
|
|
54
|
+
// Check whitelist
|
|
55
|
+
if (config.whitelist?.includes(key)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const now = Date.now();
|
|
60
|
+
const entry = rateLimitStore.get(key);
|
|
61
|
+
|
|
62
|
+
// Reset if window expired
|
|
63
|
+
if (!entry || now > entry.resetTime) {
|
|
64
|
+
rateLimitStore.set(key, {
|
|
65
|
+
count: 1,
|
|
66
|
+
resetTime: now + config.window * 1000,
|
|
67
|
+
});
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Increment count
|
|
72
|
+
entry.count++;
|
|
73
|
+
|
|
74
|
+
// Check if exceeded
|
|
75
|
+
if (entry.count > config.maxRequests) {
|
|
76
|
+
const retryAfter = Math.ceil((entry.resetTime - now) / 1000);
|
|
77
|
+
return new Response(
|
|
78
|
+
JSON.stringify({
|
|
79
|
+
error: config.response?.message || 'Rate limit exceeded',
|
|
80
|
+
retryAfter,
|
|
81
|
+
}),
|
|
82
|
+
{
|
|
83
|
+
status: config.response?.status || 429,
|
|
84
|
+
headers: {
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'Retry-After': retryAfter.toString(),
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Service Interface
|
|
3
|
+
* @description Defines the contract for middleware operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
CORSConfig,
|
|
8
|
+
CacheConfig,
|
|
9
|
+
RateLimitConfig,
|
|
10
|
+
AuthConfig,
|
|
11
|
+
SecurityHeadersConfig,
|
|
12
|
+
IPFilterConfig,
|
|
13
|
+
LogConfig,
|
|
14
|
+
HealthCheckConfig,
|
|
15
|
+
ErrorHandlerConfig,
|
|
16
|
+
} from '../entities';
|
|
17
|
+
|
|
18
|
+
export interface IMiddlewareService {
|
|
19
|
+
/**
|
|
20
|
+
* CORS middleware
|
|
21
|
+
*/
|
|
22
|
+
cors(request: Request, config: CORSConfig): Promise<Response | null>;
|
|
23
|
+
addCorsHeaders(request: Request, response: Response, config: CORSConfig): Response;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Cache middleware
|
|
27
|
+
*/
|
|
28
|
+
cache(request: Request, config: CacheConfig): Promise<Response | null>;
|
|
29
|
+
setCache(request: Request, response: Response, config: CacheConfig): void;
|
|
30
|
+
invalidateCache(pattern?: string): void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Rate limit middleware
|
|
34
|
+
*/
|
|
35
|
+
checkRateLimit(request: Request, config: RateLimitConfig): Promise<Response | null>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Authentication middleware
|
|
39
|
+
*/
|
|
40
|
+
requireAuth(request: Request, config: AuthConfig): Promise<Response | null>;
|
|
41
|
+
addUserContext(request: Request, user: {
|
|
42
|
+
id: string;
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}): Request;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Security headers
|
|
48
|
+
*/
|
|
49
|
+
addSecurityHeaders(response: Response, config: SecurityHeadersConfig): Response;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Bot detection
|
|
53
|
+
*/
|
|
54
|
+
detectBot(request: Request): Promise<{
|
|
55
|
+
isBot: boolean;
|
|
56
|
+
botType?: string;
|
|
57
|
+
}>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Request logging
|
|
61
|
+
*/
|
|
62
|
+
logRequest(request: Request, config: LogConfig): Promise<void>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Response time tracking
|
|
66
|
+
*/
|
|
67
|
+
trackResponseTime(handler: () => Promise<Response>): Promise<{
|
|
68
|
+
response: Response;
|
|
69
|
+
duration: number;
|
|
70
|
+
}>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* IP filter
|
|
74
|
+
*/
|
|
75
|
+
checkIPFilter(request: Request, config: IPFilterConfig): Response | null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Method override
|
|
79
|
+
*/
|
|
80
|
+
methodOverride(request: Request): Request;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Request ID
|
|
84
|
+
*/
|
|
85
|
+
addRequestID(request: Request): string;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Health check
|
|
89
|
+
*/
|
|
90
|
+
healthCheck(
|
|
91
|
+
env: import('../../router').CloudflareEnv,
|
|
92
|
+
config?: HealthCheckConfig
|
|
93
|
+
): Promise<Response>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Error handling
|
|
97
|
+
*/
|
|
98
|
+
handleMiddlewareError(error: Error, config: ErrorHandlerConfig): Response;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Conditional middleware
|
|
102
|
+
*/
|
|
103
|
+
conditionalChainMiddleware(
|
|
104
|
+
condition: (request: Request) => boolean,
|
|
105
|
+
middleware: (request: Request) => Response | null
|
|
106
|
+
): (request: Request) => Response | null;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Chain middleware
|
|
110
|
+
*/
|
|
111
|
+
chainMiddleware(
|
|
112
|
+
...middlewares: Array<(request: Request) => Response | null>
|
|
113
|
+
): (request: Request) => Response | null;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Chain async middleware
|
|
117
|
+
*/
|
|
118
|
+
chainAsyncMiddleware(
|
|
119
|
+
request: Request,
|
|
120
|
+
...middlewares: Array<(request: Request) => Promise<Response | null>>
|
|
121
|
+
): Promise<Response | null>;
|
|
122
|
+
}
|
|
@@ -11,7 +11,7 @@ export interface WorkerResponse extends Response {
|
|
|
11
11
|
waitUntil?: (promise: Promise<unknown>) => void;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export interface
|
|
14
|
+
export interface CloudflareWorkerConfig {
|
|
15
15
|
readonly name: string;
|
|
16
16
|
readonly routes?: string[];
|
|
17
17
|
readonly schedule?: string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflows Domain Entities
|
|
3
|
+
* @description Workflow orchestration entities for Cloudflare Workers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Workflow step definition
|
|
8
|
+
*/
|
|
9
|
+
export interface WorkflowStep {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
handler: string;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
retryPolicy?: {
|
|
15
|
+
maxAttempts: number;
|
|
16
|
+
backoffMultiplier: number;
|
|
17
|
+
initialDelay: number;
|
|
18
|
+
maxDelay: number;
|
|
19
|
+
};
|
|
20
|
+
dependencies?: string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Workflow definition
|
|
25
|
+
*/
|
|
26
|
+
export interface WorkflowDefinition {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
steps: WorkflowStep[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Workflow execution state
|
|
35
|
+
*/
|
|
36
|
+
export interface WorkflowExecution {
|
|
37
|
+
id: string;
|
|
38
|
+
workflowId: string;
|
|
39
|
+
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
40
|
+
currentStep?: string;
|
|
41
|
+
startedAt: number;
|
|
42
|
+
completedAt?: number;
|
|
43
|
+
input: unknown;
|
|
44
|
+
output?: unknown;
|
|
45
|
+
error?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Workflow config
|
|
50
|
+
*/
|
|
51
|
+
export interface CloudflareWorkflowConfig {
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
maxExecutionTime: number;
|
|
54
|
+
defaultRetries: number;
|
|
55
|
+
workflows?: Record<string, WorkflowDefinition>;
|
|
56
|
+
storage?: 'kv' | 'd1';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Type alias for compatibility
|
|
60
|
+
export type WorkflowConfig = CloudflareWorkflowConfig;
|
|
@@ -132,9 +132,9 @@ export interface WorkerVersionInfo {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
/**
|
|
135
|
-
*
|
|
135
|
+
* Wrangler analytics data
|
|
136
136
|
*/
|
|
137
|
-
export interface
|
|
137
|
+
export interface WranglerAnalyticsData {
|
|
138
138
|
requests?: number;
|
|
139
139
|
errors?: number;
|
|
140
140
|
statusCodes?: Record<string, number>;
|
|
@@ -118,6 +118,14 @@ export class WranglerService implements IWranglerService {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Convert string result to void result
|
|
123
|
+
*/
|
|
124
|
+
private asVoidResult(result: WranglerResult<string>): WranglerResult<void> {
|
|
125
|
+
const { data, ...rest } = result;
|
|
126
|
+
return rest;
|
|
127
|
+
}
|
|
128
|
+
|
|
121
129
|
// ==================== Authentication ====================
|
|
122
130
|
|
|
123
131
|
async login(options?: WranglerCommandOptions): Promise<WranglerResult<AuthInfo>> {
|
|
@@ -132,7 +140,7 @@ export class WranglerService implements IWranglerService {
|
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
async logout(options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
|
|
135
|
-
return this.execute(['logout'], options);
|
|
143
|
+
return this.asVoidResult(await this.execute(['logout'], options));
|
|
136
144
|
}
|
|
137
145
|
|
|
138
146
|
async whoami(options?: WranglerCommandOptions): Promise<WranglerResult<AuthInfo>> {
|
|
@@ -158,7 +166,7 @@ export class WranglerService implements IWranglerService {
|
|
|
158
166
|
if (template) {
|
|
159
167
|
args.push('--template', template);
|
|
160
168
|
}
|
|
161
|
-
return this.execute(args, options);
|
|
169
|
+
return this.asVoidResult(await this.execute(args, options));
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
async dev(
|
|
@@ -237,7 +245,7 @@ export class WranglerService implements IWranglerService {
|
|
|
237
245
|
value: string,
|
|
238
246
|
options?: WranglerCommandOptions
|
|
239
247
|
): Promise<WranglerResult<void>> {
|
|
240
|
-
return this.execute(['kv:key', 'put', '--namespace-id', namespaceId, key, value], options);
|
|
248
|
+
return this.asVoidResult(await this.execute(['kv:key', 'put', '--namespace-id', namespaceId, key, value], options));
|
|
241
249
|
}
|
|
242
250
|
|
|
243
251
|
async kvKeyGet(
|
|
@@ -253,7 +261,7 @@ export class WranglerService implements IWranglerService {
|
|
|
253
261
|
key: string,
|
|
254
262
|
options?: WranglerCommandOptions
|
|
255
263
|
): Promise<WranglerResult<void>> {
|
|
256
|
-
return this.execute(['kv:key', 'delete', '--namespace-id', namespaceId, key], options);
|
|
264
|
+
return this.asVoidResult(await this.execute(['kv:key', 'delete', '--namespace-id', namespaceId, key], options));
|
|
257
265
|
}
|
|
258
266
|
|
|
259
267
|
// ==================== R2 Operations ====================
|
|
@@ -289,7 +297,7 @@ export class WranglerService implements IWranglerService {
|
|
|
289
297
|
bucketName: string,
|
|
290
298
|
options?: WranglerCommandOptions
|
|
291
299
|
): Promise<WranglerResult<void>> {
|
|
292
|
-
return this.execute(['r2', 'bucket', 'delete', bucketName], options);
|
|
300
|
+
return this.asVoidResult(await this.execute(['r2', 'bucket', 'delete', bucketName], options));
|
|
293
301
|
}
|
|
294
302
|
|
|
295
303
|
async r2ObjectPut(
|
|
@@ -298,7 +306,7 @@ export class WranglerService implements IWranglerService {
|
|
|
298
306
|
file: string,
|
|
299
307
|
options?: WranglerCommandOptions
|
|
300
308
|
): Promise<WranglerResult<void>> {
|
|
301
|
-
return this.execute(['r2', 'object', 'put', bucketName, key, '--file', file], options);
|
|
309
|
+
return this.asVoidResult(await this.execute(['r2', 'object', 'put', bucketName, key, '--file', file], options));
|
|
302
310
|
}
|
|
303
311
|
|
|
304
312
|
// ==================== D1 Operations ====================
|
|
@@ -412,7 +420,7 @@ export class WranglerService implements IWranglerService {
|
|
|
412
420
|
secretName: string,
|
|
413
421
|
options?: WranglerCommandOptions
|
|
414
422
|
): Promise<WranglerResult<void>> {
|
|
415
|
-
return this.execute(['secret', 'delete', secretName], options);
|
|
423
|
+
return this.asVoidResult(await this.execute(['secret', 'delete', secretName], options));
|
|
416
424
|
}
|
|
417
425
|
|
|
418
426
|
// ==================== Monitoring ====================
|
|
@@ -446,7 +454,7 @@ export class WranglerService implements IWranglerService {
|
|
|
446
454
|
versionId: string,
|
|
447
455
|
options?: WranglerCommandOptions
|
|
448
456
|
): Promise<WranglerResult<void>> {
|
|
449
|
-
return this.execute(['versions', 'rollback', '--version-id', versionId], options);
|
|
457
|
+
return this.asVoidResult(await this.execute(['versions', 'rollback', '--version-id', versionId], options));
|
|
450
458
|
}
|
|
451
459
|
|
|
452
460
|
// ==================== Generic Command Execution ====================
|
package/src/index.ts
CHANGED
|
@@ -35,10 +35,10 @@ export * from "./domains/kv";
|
|
|
35
35
|
export * from "./domains/images";
|
|
36
36
|
export * from "./domains/analytics";
|
|
37
37
|
export * from "./domains/workflows";
|
|
38
|
+
export * from "./domains/middleware";
|
|
38
39
|
|
|
39
|
-
// Infrastructure - Router,
|
|
40
|
+
// Infrastructure - Router, Utils
|
|
40
41
|
export * from "./infrastructure/router";
|
|
41
|
-
export * from "./infrastructure/middleware";
|
|
42
42
|
export * from "./infrastructure/utils/helpers";
|
|
43
43
|
export * from "./infrastructure/constants";
|
|
44
44
|
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare Middleware Collection
|
|
3
3
|
* @description Comprehensive middleware for Cloudflare Workers
|
|
4
|
+
* @deprecated Import from '@umituz/web-cloudflare/middleware' instead
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
|
-
// Re-export
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
// Re-export from middleware domain
|
|
8
|
+
export * from '../../domains/middleware';
|
|
9
|
+
|
|
10
|
+
// ============================================================
|
|
11
|
+
// Environment Types (kept for backwards compatibility)
|
|
12
|
+
// ============================================================
|
|
13
|
+
|
|
14
|
+
export interface CloudflareMiddlewareEnv {
|
|
15
|
+
KV?: KVNamespace;
|
|
16
|
+
R2?: R2Bucket;
|
|
17
|
+
D1?: D1Database;
|
|
18
|
+
DO?: Record<string, DurableObjectNamespace>;
|
|
19
|
+
QUEUE?: Record<string, Queue>;
|
|
20
|
+
AI?: any;
|
|
21
|
+
vars?: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Type alias for backwards compatibility
|
|
25
|
+
export type Env = CloudflareMiddlewareEnv;
|
|
11
26
|
|
|
12
27
|
// ============================================================
|
|
13
28
|
// New Middleware
|
|
@@ -300,7 +315,7 @@ export interface HealthCheckConfig {
|
|
|
300
315
|
}
|
|
301
316
|
|
|
302
317
|
export async function healthCheck(
|
|
303
|
-
env:
|
|
318
|
+
env: CloudflareMiddlewareEnv,
|
|
304
319
|
config?: HealthCheckConfig
|
|
305
320
|
): Promise<Response> {
|
|
306
321
|
const checks: Record<string, boolean | string> = {
|
|
@@ -357,9 +372,9 @@ export function handleMiddlewareError(
|
|
|
357
372
|
}
|
|
358
373
|
|
|
359
374
|
/**
|
|
360
|
-
* Conditional Middleware
|
|
375
|
+
* Conditional Middleware (Chain)
|
|
361
376
|
*/
|
|
362
|
-
export function
|
|
377
|
+
export function conditionalChainMiddleware(
|
|
363
378
|
condition: (request: Request) => boolean,
|
|
364
379
|
middleware: (request: Request) => Response | null
|
|
365
380
|
): (request: Request) => Response | null {
|