@umituz/web-cloudflare 1.4.5 → 1.4.7
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 +2 -2
- package/src/config/patterns.ts +2 -2
- package/src/domains/ai-gateway/services/index.ts +18 -8
- package/src/domains/analytics/services/analytics.service.ts +16 -92
- package/src/domains/analytics/types/service.interface.ts +1 -1
- package/src/domains/d1/services/d1.service.ts +19 -22
- package/src/domains/images/services/images.service.ts +58 -21
- package/src/domains/kv/services/kv.service.ts +10 -5
- package/src/domains/middleware/entities/index.ts +106 -0
- package/src/domains/middleware/index.ts +14 -0
- package/src/{infrastructure/middleware/auth.ts → domains/middleware/services/auth.service.ts} +7 -11
- package/src/{infrastructure/middleware/cache.ts → domains/middleware/services/cache.service.ts} +13 -11
- package/src/{infrastructure/middleware/cors.ts → domains/middleware/services/cors.service.ts} +9 -14
- package/src/domains/middleware/services/index.ts +9 -0
- package/src/{infrastructure/middleware/rate-limit.ts → domains/middleware/services/rate-limit.service.ts} +8 -16
- package/src/domains/middleware/types/index.ts +5 -0
- package/src/domains/middleware/types/service.interface.ts +128 -0
- package/src/domains/r2/services/r2.service.ts +21 -13
- package/src/domains/workers/entities/index.ts +17 -1
- package/src/domains/workers/examples/worker.example.ts +10 -8
- package/src/domains/workers/services/workers.service.ts +6 -4
- package/src/domains/workflows/entities/index.ts +14 -1
- package/src/domains/workflows/services/workflows.service.ts +43 -10
- package/src/domains/wrangler/services/wrangler.service.ts +150 -443
- package/src/index.ts +45 -13
- package/src/infrastructure/middleware/index.ts +23 -8
- package/src/infrastructure/utils/helpers.ts +29 -7
- package/src/presentation/hooks/cloudflare.hooks.ts +7 -309
- package/src/presentation/hooks/index.ts +4 -1
package/src/index.ts
CHANGED
|
@@ -25,20 +25,52 @@
|
|
|
25
25
|
* - ./types - TypeScript types
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
// Domains
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// Domains - selective exports to avoid conflicts
|
|
29
|
+
// NOTE: Wrangler service is Node.js-only and not exported for Workers runtime
|
|
30
|
+
// import { wranglerService, WranglerService } from "./domains/wrangler";
|
|
31
|
+
export { workersService, WorkersService } from "./domains/workers";
|
|
31
32
|
export * from "./domains/ai-gateway";
|
|
32
|
-
export
|
|
33
|
-
export
|
|
34
|
-
export
|
|
35
|
-
export
|
|
36
|
-
export
|
|
37
|
-
|
|
33
|
+
export { r2Service, R2Service } from "./domains/r2";
|
|
34
|
+
export { d1Service, D1Service } from "./domains/d1";
|
|
35
|
+
export { kvService, KVService } from "./domains/kv";
|
|
36
|
+
export { imagesService, ImagesService } from "./domains/images";
|
|
37
|
+
export { analyticsService, AnalyticsService } from "./domains/analytics";
|
|
38
|
+
// Workflows - selective exports to avoid conflicts
|
|
39
|
+
export type {
|
|
40
|
+
WorkflowStep,
|
|
41
|
+
WorkflowDefinition,
|
|
42
|
+
WorkflowExecution,
|
|
43
|
+
CloudflareWorkflowConfig,
|
|
44
|
+
} from "./domains/workflows";
|
|
45
|
+
export {
|
|
46
|
+
workflowService,
|
|
47
|
+
WorkflowService,
|
|
48
|
+
} from "./domains/workflows";
|
|
49
|
+
// Middleware - selective exports to avoid conflicts
|
|
50
|
+
export type {
|
|
51
|
+
MiddlewareCORSConfig,
|
|
52
|
+
MiddlewareCacheConfig,
|
|
53
|
+
MiddlewareRateLimitConfig,
|
|
54
|
+
MiddlewareAuthConfig,
|
|
55
|
+
SecurityHeadersConfig,
|
|
56
|
+
IPFilterConfig,
|
|
57
|
+
LogConfig,
|
|
58
|
+
HealthCheckConfig,
|
|
59
|
+
ErrorHandlerConfig,
|
|
60
|
+
} from "./domains/middleware";
|
|
61
|
+
export {
|
|
62
|
+
cors,
|
|
63
|
+
addCorsHeaders,
|
|
64
|
+
cache,
|
|
65
|
+
setCache,
|
|
66
|
+
invalidateCache,
|
|
67
|
+
checkRateLimit,
|
|
68
|
+
requireAuth,
|
|
69
|
+
addUserContext,
|
|
70
|
+
} from "./domains/middleware";
|
|
38
71
|
|
|
39
|
-
// Infrastructure - Router,
|
|
72
|
+
// Infrastructure - Router, Utils
|
|
40
73
|
export * from "./infrastructure/router";
|
|
41
|
-
export * from "./infrastructure/middleware";
|
|
42
74
|
export * from "./infrastructure/utils/helpers";
|
|
43
75
|
export * from "./infrastructure/constants";
|
|
44
76
|
|
|
@@ -46,5 +78,5 @@ export * from "./infrastructure/constants";
|
|
|
46
78
|
export * from "./config/patterns";
|
|
47
79
|
export * from "./config/types";
|
|
48
80
|
|
|
49
|
-
// Presentation hooks
|
|
50
|
-
|
|
81
|
+
// Note: Presentation hooks are React-specific and not included in Workers runtime
|
|
82
|
+
// Use them in a separate React client package instead
|
|
@@ -1,10 +1,14 @@
|
|
|
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
|
|
|
7
|
+
// Re-export from middleware domain
|
|
8
|
+
export * from '../../domains/middleware';
|
|
9
|
+
|
|
6
10
|
// ============================================================
|
|
7
|
-
// Environment Types
|
|
11
|
+
// Environment Types (kept for backwards compatibility)
|
|
8
12
|
// ============================================================
|
|
9
13
|
|
|
10
14
|
export interface CloudflareMiddlewareEnv {
|
|
@@ -20,12 +24,6 @@ export interface CloudflareMiddlewareEnv {
|
|
|
20
24
|
// Type alias for backwards compatibility
|
|
21
25
|
export type Env = CloudflareMiddlewareEnv;
|
|
22
26
|
|
|
23
|
-
// Re-export existing middleware
|
|
24
|
-
export { cors, addCorsHeaders } from './cors';
|
|
25
|
-
export { cache, setCache, invalidateCache } from './cache';
|
|
26
|
-
export { checkRateLimit } from './rate-limit';
|
|
27
|
-
export { requireAuth, addUserContext } from './auth';
|
|
28
|
-
|
|
29
27
|
// ============================================================
|
|
30
28
|
// New Middleware
|
|
31
29
|
// ============================================================
|
|
@@ -320,10 +318,27 @@ export async function healthCheck(
|
|
|
320
318
|
env: CloudflareMiddlewareEnv,
|
|
321
319
|
config?: HealthCheckConfig
|
|
322
320
|
): Promise<Response> {
|
|
321
|
+
// Get uptime if available (Node.js only)
|
|
322
|
+
let uptime = 0;
|
|
323
|
+
if (config?.uptime !== undefined) {
|
|
324
|
+
uptime = config.uptime;
|
|
325
|
+
} else {
|
|
326
|
+
// Try to get process uptime in Node.js environment
|
|
327
|
+
try {
|
|
328
|
+
// @ts-ignore - process is not available in Workers runtime
|
|
329
|
+
if (typeof process !== 'undefined' && process?.uptime) {
|
|
330
|
+
// @ts-ignore
|
|
331
|
+
uptime = process.uptime();
|
|
332
|
+
}
|
|
333
|
+
} catch {
|
|
334
|
+
uptime = 0;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
323
338
|
const checks: Record<string, boolean | string> = {
|
|
324
339
|
healthy: true,
|
|
325
340
|
timestamp: new Date().toISOString(),
|
|
326
|
-
uptime:
|
|
341
|
+
uptime: uptime.toString(),
|
|
327
342
|
};
|
|
328
343
|
|
|
329
344
|
if (config?.checks) {
|
|
@@ -626,17 +626,25 @@ export function deepClone<T>(obj: T): T {
|
|
|
626
626
|
/**
|
|
627
627
|
* Deep merge objects
|
|
628
628
|
*/
|
|
629
|
-
export function deepMerge<T extends Record<string, any>>(
|
|
629
|
+
export function deepMerge<T extends Record<string, any>>(
|
|
630
|
+
target: T,
|
|
631
|
+
...sources: Array<Partial<Record<string, any>>>
|
|
632
|
+
): T {
|
|
630
633
|
if (!sources.length) return target;
|
|
631
634
|
const source = sources.shift();
|
|
632
635
|
|
|
633
636
|
if (isObject(target) && isObject(source)) {
|
|
634
637
|
for (const key in source) {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
+
const sourceValue = source[key];
|
|
639
|
+
const targetValue = (target as any)[key];
|
|
640
|
+
|
|
641
|
+
if (isObject(sourceValue)) {
|
|
642
|
+
if (!targetValue) {
|
|
643
|
+
(target as any)[key] = {};
|
|
644
|
+
}
|
|
645
|
+
deepMerge((target as any)[key], sourceValue);
|
|
638
646
|
} else {
|
|
639
|
-
|
|
647
|
+
(target as any)[key] = sourceValue;
|
|
640
648
|
}
|
|
641
649
|
}
|
|
642
650
|
}
|
|
@@ -651,16 +659,23 @@ function isObject(item: unknown): item is Record<string, unknown> {
|
|
|
651
659
|
/**
|
|
652
660
|
* Pick properties from object
|
|
653
661
|
*/
|
|
654
|
-
export function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
|
|
662
|
+
export function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
|
|
655
663
|
const result = {} as Pick<T, K>;
|
|
656
664
|
keys.forEach((key) => {
|
|
657
665
|
if (key in obj) {
|
|
658
|
-
result[key] = obj[key];
|
|
666
|
+
(result as any)[key] = obj[key];
|
|
659
667
|
}
|
|
660
668
|
});
|
|
661
669
|
return result;
|
|
662
670
|
}
|
|
663
671
|
|
|
672
|
+
/**
|
|
673
|
+
* Merge multiple objects
|
|
674
|
+
*/
|
|
675
|
+
export function merge<T extends object>(target: T, ...sources: Array<Partial<T>>): T {
|
|
676
|
+
return Object.assign(target, ...sources);
|
|
677
|
+
}
|
|
678
|
+
|
|
664
679
|
/**
|
|
665
680
|
* Omit properties from object
|
|
666
681
|
*/
|
|
@@ -672,6 +687,13 @@ export function omit<T, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {
|
|
|
672
687
|
return result as Omit<T, K>;
|
|
673
688
|
}
|
|
674
689
|
|
|
690
|
+
/**
|
|
691
|
+
* Clone object
|
|
692
|
+
*/
|
|
693
|
+
export function clone<T>(obj: T): T {
|
|
694
|
+
return JSON.parse(JSON.stringify(obj));
|
|
695
|
+
}
|
|
696
|
+
|
|
675
697
|
// ============================================================
|
|
676
698
|
// Random Utilities
|
|
677
699
|
// ============================================================
|
|
@@ -1,314 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare React Hooks
|
|
3
3
|
* @description React hooks for Cloudflare services (client-side)
|
|
4
|
+
*
|
|
5
|
+
* DEPRECATED: This file is disabled because React hooks are not compatible
|
|
6
|
+
* with Cloudflare Workers runtime.
|
|
7
|
+
*
|
|
8
|
+
* React hooks require browser/React environment and cannot be used in Workers.
|
|
9
|
+
* If you need React integration, create a separate client-side package.
|
|
4
10
|
*/
|
|
5
11
|
|
|
6
|
-
|
|
7
|
-
import { kvService } from "../../infrastructure/services/kv";
|
|
8
|
-
import { r2Service } from "../../infrastructure/services/r2";
|
|
9
|
-
import { imagesService } from "../../infrastructure/services/images";
|
|
10
|
-
import { analyticsService } from "../../infrastructure/services/analytics";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Cloudflare Worker Hook
|
|
14
|
-
* @description Fetch data from Cloudflare Workers
|
|
15
|
-
*/
|
|
16
|
-
export interface UseCloudflareWorkerOptions {
|
|
17
|
-
readonly enabled?: boolean;
|
|
18
|
-
readonly refetchInterval?: number;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function useCloudflareWorker<T = unknown>(
|
|
22
|
-
url: string,
|
|
23
|
-
options?: UseCloudflareWorkerOptions
|
|
24
|
-
) {
|
|
25
|
-
const [data, setData] = useState<T | null>(null);
|
|
26
|
-
const [loading, setLoading] = useState(false);
|
|
27
|
-
const [error, setError] = useState<Error | null>(null);
|
|
28
|
-
|
|
29
|
-
const fetcher = useCallback(async () => {
|
|
30
|
-
if (!options?.enabled ?? true) {
|
|
31
|
-
setLoading(true);
|
|
32
|
-
setError(null);
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const response = await fetch(url);
|
|
36
|
-
if (!response.ok) {
|
|
37
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
38
|
-
}
|
|
39
|
-
const json = await response.json();
|
|
40
|
-
setData(json);
|
|
41
|
-
} catch (err) {
|
|
42
|
-
setError(err as Error);
|
|
43
|
-
} finally {
|
|
44
|
-
setLoading(false);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}, [url, options?.enabled]);
|
|
48
|
-
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
fetcher();
|
|
51
|
-
|
|
52
|
-
if (options?.refetchInterval) {
|
|
53
|
-
const interval = setInterval(fetcher, options.refetchInterval);
|
|
54
|
-
return () => clearInterval(interval);
|
|
55
|
-
}
|
|
56
|
-
}, [fetcher, options?.refetchInterval]);
|
|
57
|
-
|
|
58
|
-
return { data, loading, error, refetch: fetcher };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Cloudflare KV Hook
|
|
63
|
-
* @description Read from Cloudflare KV (client-side, via Worker API)
|
|
64
|
-
*/
|
|
65
|
-
export interface UseCloudflareKVOptions {
|
|
66
|
-
readonly apiURL: string;
|
|
67
|
-
readonly enabled?: boolean;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function useCloudflareKV<T = unknown>(
|
|
71
|
-
key: string,
|
|
72
|
-
options: UseCloudflareKVOptions
|
|
73
|
-
) {
|
|
74
|
-
const [data, setData] = useState<T | null>(null);
|
|
75
|
-
const [loading, setLoading] = useState(false);
|
|
76
|
-
const [error, setError] = useState<Error | null>(null);
|
|
77
|
-
|
|
78
|
-
useEffect(() => {
|
|
79
|
-
if (!options.enabled ?? true) {
|
|
80
|
-
setLoading(true);
|
|
81
|
-
setError(null);
|
|
82
|
-
|
|
83
|
-
fetch(`${options.apiURL}/kv/${key}`)
|
|
84
|
-
.then((res) => {
|
|
85
|
-
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
|
86
|
-
return res.json();
|
|
87
|
-
})
|
|
88
|
-
.then((json) => setData(json.value))
|
|
89
|
-
.catch((err) => setError(err))
|
|
90
|
-
.finally(() => setLoading(false));
|
|
91
|
-
}
|
|
92
|
-
}, [key, options.apiURL, options.enabled]);
|
|
93
|
-
|
|
94
|
-
return { data, loading, error };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Cloudflare R2 Hook
|
|
99
|
-
* @description Upload files to R2 (client-side, via Worker API)
|
|
100
|
-
*/
|
|
101
|
-
export interface UseCloudflareR2Options {
|
|
102
|
-
readonly uploadURL: string;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function useCloudflareR2(options: UseCloudflareR2Options) {
|
|
106
|
-
const [uploading, setUploading] = useState(false);
|
|
107
|
-
const [progress, setProgress] = useState(0);
|
|
108
|
-
const [error, setError] = useState<Error | null>(null);
|
|
109
|
-
|
|
110
|
-
const upload = useCallback(
|
|
111
|
-
async (file: File, key?: string) => {
|
|
112
|
-
setUploading(true);
|
|
113
|
-
setProgress(0);
|
|
114
|
-
setError(null);
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const formData = new FormData();
|
|
118
|
-
formData.append("file", file);
|
|
119
|
-
if (key) formData.append("key", key);
|
|
120
|
-
|
|
121
|
-
const xhr = new XMLHttpRequest();
|
|
122
|
-
|
|
123
|
-
xhr.upload.addEventListener("progress", (e) => {
|
|
124
|
-
if (e.lengthComputable) {
|
|
125
|
-
setProgress((e.loaded / e.total) * 100);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
const promise = new Promise<{ key: string; url: string }>((resolve, reject) => {
|
|
130
|
-
xhr.addEventListener("load", () => {
|
|
131
|
-
if (xhr.status === 200) {
|
|
132
|
-
const data = JSON.parse(xhr.responseText);
|
|
133
|
-
resolve(data);
|
|
134
|
-
} else {
|
|
135
|
-
reject(new Error(`Upload failed: ${xhr.statusText}`));
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
xhr.addEventListener("error", () => {
|
|
140
|
-
reject(new Error("Upload failed"));
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
xhr.open("POST", options.uploadURL);
|
|
144
|
-
xhr.send(formData);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
return await promise;
|
|
148
|
-
} catch (err) {
|
|
149
|
-
setError(err as Error);
|
|
150
|
-
throw err;
|
|
151
|
-
} finally {
|
|
152
|
-
setUploading(false);
|
|
153
|
-
setProgress(0);
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
[options.uploadURL]
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
return { upload, uploading, progress, error };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Cloudflare D1 Hook
|
|
164
|
-
* @description Query D1 database (client-side, via Worker API)
|
|
165
|
-
*/
|
|
166
|
-
export interface UseCloudflareD1Options {
|
|
167
|
-
readonly apiURL: string;
|
|
168
|
-
readonly enabled?: boolean;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export function useCloudflareD1<T = unknown>(
|
|
172
|
-
query: string,
|
|
173
|
-
params?: readonly unknown[],
|
|
174
|
-
options?: UseCloudflareD1Options
|
|
175
|
-
) {
|
|
176
|
-
const [data, setData] = useState<T[] | null>(null);
|
|
177
|
-
const [loading, setLoading] = useState(false);
|
|
178
|
-
const [error, setError] = useState<Error | null>(null);
|
|
179
|
-
|
|
180
|
-
useEffect(() => {
|
|
181
|
-
if (!options?.enabled ?? true) {
|
|
182
|
-
setLoading(true);
|
|
183
|
-
setError(null);
|
|
184
|
-
|
|
185
|
-
fetch(`${options?.apiURL}/d1/query`, {
|
|
186
|
-
method: "POST",
|
|
187
|
-
headers: { "Content-Type": "application/json" },
|
|
188
|
-
body: JSON.stringify({ query, params }),
|
|
189
|
-
})
|
|
190
|
-
.then((res) => {
|
|
191
|
-
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
|
192
|
-
return res.json();
|
|
193
|
-
})
|
|
194
|
-
.then((json) => setData(json.results))
|
|
195
|
-
.catch((err) => setError(err))
|
|
196
|
-
.finally(() => setLoading(false));
|
|
197
|
-
}
|
|
198
|
-
}, [query, params, options?.apiURL, options?.enabled]);
|
|
199
|
-
|
|
200
|
-
return { data, loading, error };
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Cloudflare Images Hook
|
|
205
|
-
* @description Upload and manage images
|
|
206
|
-
*/
|
|
207
|
-
export interface UseCloudflareImagesOptions {
|
|
208
|
-
readonly accountId?: string;
|
|
209
|
-
readonly apiToken?: string;
|
|
210
|
-
readonly uploadURL?: string;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function useCloudflareImages(options?: UseCloudflareImagesOptions) {
|
|
214
|
-
const [uploading, setUploading] = useState(false);
|
|
215
|
-
const [error, setError] = useState<Error | null>(null);
|
|
216
|
-
|
|
217
|
-
useEffect(() => {
|
|
218
|
-
if (options?.accountId && options?.apiToken) {
|
|
219
|
-
imagesService.initialize({
|
|
220
|
-
accountId: options.accountId,
|
|
221
|
-
apiToken: options.apiToken,
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
}, [options?.accountId, options?.apiToken]);
|
|
225
|
-
|
|
226
|
-
const upload = useCallback(
|
|
227
|
-
async (file: File, metadata?: Record<string, string>) => {
|
|
228
|
-
setUploading(true);
|
|
229
|
-
setError(null);
|
|
230
|
-
|
|
231
|
-
try {
|
|
232
|
-
if (options?.uploadURL) {
|
|
233
|
-
// Upload via Worker proxy
|
|
234
|
-
const formData = new FormData();
|
|
235
|
-
formData.append("file", file);
|
|
236
|
-
if (metadata) {
|
|
237
|
-
for (const [key, value] of Object.entries(metadata)) {
|
|
238
|
-
formData.append(`metadata[${key}]`, value);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const response = await fetch(options.uploadURL, {
|
|
243
|
-
method: "POST",
|
|
244
|
-
body: formData,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
if (!response.ok) {
|
|
248
|
-
throw new Error(`Upload failed: ${response.statusText}`);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return await response.json();
|
|
252
|
-
} else {
|
|
253
|
-
// Direct upload to Cloudflare Images
|
|
254
|
-
return await imagesService.upload(file, { metadata });
|
|
255
|
-
}
|
|
256
|
-
} catch (err) {
|
|
257
|
-
setError(err as Error);
|
|
258
|
-
throw err;
|
|
259
|
-
} finally {
|
|
260
|
-
setUploading(false);
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
|
-
[options?.uploadURL]
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
const getTransformedURL = useCallback(
|
|
267
|
-
(imageId: string, transform: {
|
|
268
|
-
width?: number;
|
|
269
|
-
height?: number;
|
|
270
|
-
fit?: string;
|
|
271
|
-
format?: string;
|
|
272
|
-
quality?: number;
|
|
273
|
-
}) => {
|
|
274
|
-
return imagesService.getTransformedURL(imageId, transform);
|
|
275
|
-
},
|
|
276
|
-
[]
|
|
277
|
-
);
|
|
278
|
-
|
|
279
|
-
return { upload, uploading, error, getTransformedURL };
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Cloudflare Analytics Hook
|
|
284
|
-
* @description Track analytics events
|
|
285
|
-
*/
|
|
286
|
-
export interface UseCloudflareAnalyticsOptions {
|
|
287
|
-
readonly siteId: string;
|
|
288
|
-
readonly scriptUrl?: string;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export function useCloudflareAnalytics(options: UseCloudflareAnalyticsOptions) {
|
|
292
|
-
useEffect(() => {
|
|
293
|
-
analyticsService.initialize({
|
|
294
|
-
siteId: options.siteId,
|
|
295
|
-
scriptUrl: options.scriptUrl,
|
|
296
|
-
});
|
|
297
|
-
}, [options.siteId, options.scriptUrl]);
|
|
298
|
-
|
|
299
|
-
const trackPageview = useCallback((title: string, referrer?: string) => {
|
|
300
|
-
if (typeof window !== "undefined") {
|
|
301
|
-
analyticsService.trackPageview(window.location.href, title, referrer);
|
|
302
|
-
}
|
|
303
|
-
}, []);
|
|
304
|
-
|
|
305
|
-
const trackEvent = useCallback((eventName: string, data?: Record<string, unknown>) => {
|
|
306
|
-
analyticsService.trackCustom(eventName, data);
|
|
307
|
-
}, []);
|
|
308
|
-
|
|
309
|
-
const getScriptTag = useCallback(() => {
|
|
310
|
-
return analyticsService.getScriptTag();
|
|
311
|
-
}, []);
|
|
312
|
-
|
|
313
|
-
return { trackPageview, trackEvent, getScriptTag };
|
|
314
|
-
}
|
|
12
|
+
// Empty file - all functionality removed to prevent Workers runtime errors
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare React Hooks
|
|
3
3
|
* Subpath: @umituz/web-cloudflare/presentation
|
|
4
|
+
*
|
|
5
|
+
* DEPRECATED: React hooks are not compatible with Workers runtime.
|
|
6
|
+
* All exports have been disabled.
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
// No exports - React hooks disabled for Workers runtime compatibility
|