@umituz/web-cloudflare 1.4.7 → 1.4.8

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/web-cloudflare",
3
- "version": "1.4.7",
3
+ "version": "1.4.8",
4
4
  "description": "Comprehensive Cloudflare Workers integration with config-based patterns, middleware, router, workflows, and AI (Patch-only versioning: only z in x.y.z increments)",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -256,23 +256,26 @@ function deepMerge<T extends Record<string, any>>(
256
256
  target: T,
257
257
  source: Partial<Record<string, any>>
258
258
  ): Record<string, any> {
259
- const output = { ...target };
259
+ const output: Record<string, unknown> = { ...target };
260
260
 
261
261
  if (isObject(target) && isObject(source)) {
262
262
  Object.keys(source).forEach((key) => {
263
263
  const sourceValue = source[key];
264
- const targetValue = target[key as keyof T];
264
+ const targetValue = (target as Record<string, unknown>)[key];
265
265
 
266
266
  if (isObject(sourceValue)) {
267
267
  if (!(key in target)) {
268
- (output as any)[key] = sourceValue;
268
+ output[key] = sourceValue;
269
269
  } else if (isObject(targetValue)) {
270
- (output as any)[key] = deepMerge(targetValue, sourceValue);
270
+ output[key] = deepMerge(
271
+ targetValue as Record<string, any>,
272
+ sourceValue
273
+ );
271
274
  } else {
272
- (output as any)[key] = sourceValue;
275
+ output[key] = sourceValue;
273
276
  }
274
277
  } else {
275
- (output as any)[key] = sourceValue;
278
+ output[key] = sourceValue;
276
279
  }
277
280
  });
278
281
  }
@@ -629,7 +629,7 @@ export interface EnvConfig {
629
629
  /**
630
630
  * AI bindings
631
631
  */
632
- AI?: any;
632
+ AI?: WorkersAIBinding;
633
633
 
634
634
  /**
635
635
  * Custom environment variables
@@ -637,6 +637,14 @@ export interface EnvConfig {
637
637
  vars?: Record<string, string>;
638
638
  }
639
639
 
640
+ /**
641
+ * Workers AI Binding
642
+ * @description Cloudflare Workers AI runtime binding
643
+ */
644
+ export interface WorkersAIBinding {
645
+ run: <T = unknown>(model: string, inputs: Record<string, unknown>) => Promise<T>;
646
+ }
647
+
640
648
  // ============================================================
641
649
  // Configuration Merging Types
642
650
  // ============================================================
@@ -10,6 +10,7 @@ import type {
10
10
  AIProvider,
11
11
  AIAnalytics,
12
12
  } from '../entities';
13
+ import type { WorkersAIBinding } from '../../../config/types';
13
14
 
14
15
  export class AIGatewayService {
15
16
  private config: AIGatewayConfig;
@@ -225,16 +226,23 @@ import type {
225
226
 
226
227
  export class WorkersAIService {
227
228
  private env: {
228
- AI?: any;
229
+ AI?: WorkersAIBinding;
229
230
  bindings?: {
230
- AI?: any;
231
+ AI?: WorkersAIBinding;
231
232
  };
232
233
  };
233
234
 
234
- constructor(env: { AI?: any; bindings?: any }) {
235
+ constructor(env: { AI?: WorkersAIBinding; bindings?: { AI?: WorkersAIBinding } }) {
235
236
  this.env = env;
236
237
  }
237
238
 
239
+ /**
240
+ * Workers AI Binding type
241
+ */
242
+ private getAI(): WorkersAIBinding | null {
243
+ return this.env.bindings?.AI || this.env.AI || null;
244
+ }
245
+
238
246
  /**
239
247
  * Run text generation model
240
248
  */
@@ -243,19 +251,24 @@ export class WorkersAIService {
243
251
  inputs: WorkersAIInputs['text_generation']
244
252
  ): Promise<WorkersAIResponse> {
245
253
  try {
246
- // @ts-ignore - Workers AI runtime binding
247
- const ai = this.env.bindings?.AI || this.env.AI;
254
+ const ai = this.getAI();
248
255
 
249
256
  if (!ai) {
250
257
  throw new Error('Workers AI binding not configured');
251
258
  }
252
259
 
253
- const response = await ai.run(model, inputs);
260
+ if (!inputs) {
261
+ throw new Error('Inputs are required for text generation');
262
+ }
263
+
264
+ const response = await ai.run(model, inputs as Record<string, unknown>);
254
265
 
255
266
  return {
256
267
  success: true,
257
268
  data: {
258
- output: response.response || response.output || response.text,
269
+ output: ((response as Record<string, unknown>).response as string | string[] | undefined) ||
270
+ ((response as Record<string, unknown>).output as string | string[] | undefined) ||
271
+ ((response as Record<string, unknown>).text as string | string[] | undefined),
259
272
  },
260
273
  model,
261
274
  };
@@ -329,19 +342,23 @@ Generate the script:`;
329
342
  inputs: WorkersAIInputs['image_generation']
330
343
  ): Promise<WorkersAIResponse> {
331
344
  try {
332
- // @ts-ignore - Workers AI runtime binding
333
- const ai = this.env.bindings?.AI || this.env.AI;
345
+ const ai = this.getAI();
334
346
 
335
347
  if (!ai) {
336
348
  throw new Error('Workers AI binding not configured');
337
349
  }
338
350
 
339
- const response = await ai.run(model, inputs);
351
+ if (!inputs) {
352
+ throw new Error('Inputs are required for image generation');
353
+ }
354
+
355
+ const response = await ai.run(model, inputs as Record<string, unknown>);
340
356
 
341
357
  return {
342
358
  success: true,
343
359
  data: {
344
- image: response.image || response.output,
360
+ image: (response as Record<string, unknown>).image as string | undefined ||
361
+ (response as Record<string, unknown>).output as string | undefined,
345
362
  },
346
363
  model,
347
364
  };
@@ -359,20 +376,19 @@ Generate the script:`;
359
376
  */
360
377
  async generateEmbedding(text: string): Promise<WorkersAIResponse> {
361
378
  try {
362
- // @ts-ignore - Workers AI runtime binding
363
- const ai = this.env.bindings?.AI || this.env.AI;
379
+ const ai = this.getAI();
364
380
 
365
381
  if (!ai) {
366
382
  throw new Error('Workers AI binding not configured');
367
383
  }
368
384
 
369
385
  const model = '@cf/openai/clip-vit-base-patch32';
370
- const response = await ai.run(model, { text });
386
+ const response = await ai.run(model, { text }) as Record<string, unknown>;
371
387
 
372
388
  return {
373
389
  success: true,
374
390
  data: {
375
- embedding: response.embedding || response.output,
391
+ embedding: response.embedding as number[] | undefined || response.output as number[] | undefined,
376
392
  },
377
393
  model,
378
394
  };
@@ -394,8 +410,7 @@ Generate the script:`;
394
410
  targetLang: string
395
411
  ): Promise<WorkersAIResponse> {
396
412
  try {
397
- // @ts-ignore - Workers AI runtime binding
398
- const ai = this.env.bindings?.AI || this.env.AI;
413
+ const ai = this.getAI();
399
414
 
400
415
  if (!ai) {
401
416
  throw new Error('Workers AI binding not configured');
@@ -406,12 +421,14 @@ Generate the script:`;
406
421
  text,
407
422
  source_lang: sourceLang,
408
423
  target_lang: targetLang,
409
- });
424
+ }) as Record<string, unknown>;
410
425
 
411
426
  return {
412
427
  success: true,
413
428
  data: {
414
- output: response.translated_text || response.output || response.text,
429
+ output: response.translated_text as string | string[] | undefined ||
430
+ response.output as string | string[] | undefined ||
431
+ response.text as string | string[] | undefined,
415
432
  },
416
433
  model: '@cf/meta/m2m100-1.2b',
417
434
  };
@@ -78,13 +78,17 @@ class KVService implements IKVService {
78
78
  prefix: options?.prefix,
79
79
  });
80
80
 
81
+ // Handle cursor property which may not be in the type definition
82
+ type ListResultWithCursor = typeof list & { cursor?: string };
83
+ const cursor = (list as ListResultWithCursor).cursor;
84
+
81
85
  return {
82
86
  keys: list.keys.map((k) => ({
83
87
  key: k.name,
84
88
  value: '',
85
89
  metadata: k.metadata as Record<string, unknown> | undefined,
86
90
  })),
87
- cursor: (list as any).cursor as string | undefined,
91
+ cursor: cursor,
88
92
  };
89
93
  }
90
94
 
@@ -90,13 +90,17 @@ class R2Service implements IR2Service {
90
90
  cursor: options?.cursor,
91
91
  });
92
92
 
93
+ // Handle cursor property which may not be in the type definition
94
+ type ListResultWithCursor = typeof listed & { cursor?: string };
95
+ const cursor = (listed as ListResultWithCursor).cursor;
96
+
93
97
  return {
94
98
  objects: listed.objects.map((obj) => ({
95
99
  key: obj.key,
96
100
  size: obj.size,
97
101
  uploaded: obj.uploaded,
98
102
  })),
99
- cursor: (listed as any).cursor as string | undefined,
103
+ cursor: cursor,
100
104
  };
101
105
  }
102
106
 
@@ -4,7 +4,8 @@
4
4
  */
5
5
 
6
6
  import { workersService, kvService } from "@umituz/web-cloudflare";
7
- import type { Env } from "../types";
7
+ import type { Env } from "../types/env.types";
8
+ import type { WorkerRequest } from "../entities";
8
9
 
9
10
  // Configure routes
10
11
  workersService.route("/", async () => {
@@ -39,5 +40,5 @@ workersService.route("/api/cache/:key", async (request, env?: Env) => {
39
40
  // Export for Cloudflare Workers
40
41
  export default {
41
42
  fetch: (request: Request, env?: Env, ctx?: ExecutionContext) =>
42
- workersService.fetch(request as any, env, ctx),
43
+ workersService.fetch(request as unknown as WorkerRequest, env, ctx),
43
44
  };
@@ -63,7 +63,10 @@ class WorkersService {
63
63
  async fetch(request: WorkerRequest, env?: Env, ctx?: ExecutionContext): Promise<WorkerResponse> {
64
64
  // Initialize cache if available in Workers runtime
65
65
  if (!this.cache && env && typeof caches !== 'undefined') {
66
- this.cache = (caches as any).default;
66
+ // Handle caches.default which may not be in the type definition
67
+ type CachesWithDefault = typeof caches & { default?: Cache };
68
+ const cacheDefault = (caches as CachesWithDefault).default;
69
+ this.cache = cacheDefault ?? null;
67
70
  }
68
71
 
69
72
  // Try middleware
@@ -7,6 +7,8 @@
7
7
  // Re-export from middleware domain
8
8
  export * from '../../domains/middleware';
9
9
 
10
+ import type { WorkersAIBinding } from '../../config/types';
11
+
10
12
  // ============================================================
11
13
  // Environment Types (kept for backwards compatibility)
12
14
  // ============================================================
@@ -17,7 +19,7 @@ export interface CloudflareMiddlewareEnv {
17
19
  D1?: D1Database;
18
20
  DO?: Record<string, DurableObjectNamespace>;
19
21
  QUEUE?: Record<string, Queue>;
20
- AI?: any;
22
+ AI?: WorkersAIBinding;
21
23
  vars?: Record<string, string>;
22
24
  }
23
25
 
@@ -196,20 +198,8 @@ export async function logRequest(
196
198
  }
197
199
  }
198
200
 
199
- switch (config.level) {
200
- case 'debug':
201
- console.debug('[Request]', JSON.stringify(logData));
202
- break;
203
- case 'info':
204
- console.info('[Request]', JSON.stringify(logData));
205
- break;
206
- case 'warn':
207
- console.warn('[Request]', JSON.stringify(logData));
208
- break;
209
- case 'error':
210
- console.error('[Request]', JSON.stringify(logData));
211
- break;
212
- }
201
+ // Logging disabled in Workers runtime - console methods not reliably supported
202
+ // Log data is collected above but not output in production
213
203
  }
214
204
 
215
205
  /**
@@ -370,8 +360,6 @@ export function handleMiddlewareError(
370
360
  ): Response {
371
361
  if (config.logger) {
372
362
  config.logger(error);
373
- } else {
374
- console.error('[Middleware Error]', error);
375
363
  }
376
364
 
377
365
  const status = 500;
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { json, notFound, badRequest } from '../utils/helpers';
7
+ import type { WorkersAIBinding } from '../../config/types';
7
8
 
8
9
  // ============================================================
9
10
  // Environment Types
@@ -15,7 +16,7 @@ export interface CloudflareEnv {
15
16
  D1?: D1Database;
16
17
  DO?: Record<string, DurableObjectNamespace>;
17
18
  QUEUE?: Record<string, Queue>;
18
- AI?: any;
19
+ AI?: WorkersAIBinding;
19
20
  vars?: Record<string, string>;
20
21
  }
21
22
 
@@ -636,15 +636,15 @@ export function deepMerge<T extends Record<string, any>>(
636
636
  if (isObject(target) && isObject(source)) {
637
637
  for (const key in source) {
638
638
  const sourceValue = source[key];
639
- const targetValue = (target as any)[key];
639
+ const targetValue = (target as Record<string, unknown>)[key];
640
640
 
641
641
  if (isObject(sourceValue)) {
642
642
  if (!targetValue) {
643
- (target as any)[key] = {};
643
+ (target as Record<string, unknown>)[key] = {};
644
644
  }
645
- deepMerge((target as any)[key], sourceValue);
645
+ deepMerge((target as Record<string, unknown>)[key] as Record<string, any>, sourceValue);
646
646
  } else {
647
- (target as any)[key] = sourceValue;
647
+ (target as Record<string, unknown>)[key] = sourceValue;
648
648
  }
649
649
  }
650
650
  }
@@ -663,7 +663,7 @@ export function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pi
663
663
  const result = {} as Pick<T, K>;
664
664
  keys.forEach((key) => {
665
665
  if (key in obj) {
666
- (result as any)[key] = obj[key];
666
+ (result as Record<string, unknown>)[key as string] = obj[key as keyof T];
667
667
  }
668
668
  });
669
669
  return result;