@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.
Files changed (29) hide show
  1. package/package.json +2 -2
  2. package/src/config/patterns.ts +2 -2
  3. package/src/domains/ai-gateway/services/index.ts +18 -8
  4. package/src/domains/analytics/services/analytics.service.ts +16 -92
  5. package/src/domains/analytics/types/service.interface.ts +1 -1
  6. package/src/domains/d1/services/d1.service.ts +19 -22
  7. package/src/domains/images/services/images.service.ts +58 -21
  8. package/src/domains/kv/services/kv.service.ts +10 -5
  9. package/src/domains/middleware/entities/index.ts +106 -0
  10. package/src/domains/middleware/index.ts +14 -0
  11. package/src/{infrastructure/middleware/auth.ts → domains/middleware/services/auth.service.ts} +7 -11
  12. package/src/{infrastructure/middleware/cache.ts → domains/middleware/services/cache.service.ts} +13 -11
  13. package/src/{infrastructure/middleware/cors.ts → domains/middleware/services/cors.service.ts} +9 -14
  14. package/src/domains/middleware/services/index.ts +9 -0
  15. package/src/{infrastructure/middleware/rate-limit.ts → domains/middleware/services/rate-limit.service.ts} +8 -16
  16. package/src/domains/middleware/types/index.ts +5 -0
  17. package/src/domains/middleware/types/service.interface.ts +128 -0
  18. package/src/domains/r2/services/r2.service.ts +21 -13
  19. package/src/domains/workers/entities/index.ts +17 -1
  20. package/src/domains/workers/examples/worker.example.ts +10 -8
  21. package/src/domains/workers/services/workers.service.ts +6 -4
  22. package/src/domains/workflows/entities/index.ts +14 -1
  23. package/src/domains/workflows/services/workflows.service.ts +43 -10
  24. package/src/domains/wrangler/services/wrangler.service.ts +150 -443
  25. package/src/index.ts +45 -13
  26. package/src/infrastructure/middleware/index.ts +23 -8
  27. package/src/infrastructure/utils/helpers.ts +29 -7
  28. package/src/presentation/hooks/cloudflare.hooks.ts +7 -309
  29. package/src/presentation/hooks/index.ts +4 -1
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Wrangler Service Implementation
3
3
  * Wraps Wrangler CLI commands with TypeScript
4
+ *
5
+ * ⚠️ NODE.JS ONLY: This service requires Node.js runtime and is NOT compatible
6
+ * with Cloudflare Workers runtime. Use this service only in build/development
7
+ * scripts running in Node.js environment.
4
8
  */
5
9
 
6
- import { exec, spawn } from 'child_process';
7
- import { promisify } from 'util';
8
10
  import type {
9
11
  WranglerResult,
10
12
  WranglerCommandOptions,
@@ -17,8 +19,10 @@ import type {
17
19
  } from '../entities';
18
20
  import type { IWranglerService } from '../types/service.interface';
19
21
 
20
- const execAsync = promisify(exec);
21
-
22
+ /**
23
+ * Stub implementation for type checking only
24
+ * Real implementation requires Node.js runtime
25
+ */
22
26
  export class WranglerService implements IWranglerService {
23
27
  private readonly wranglerCommand: string;
24
28
 
@@ -26,444 +30,147 @@ export class WranglerService implements IWranglerService {
26
30
  this.wranglerCommand = options?.wranglerPath || 'npx wrangler';
27
31
  }
28
32
 
29
- /**
30
- * Execute a wrangler command
31
- */
32
- private async execute(
33
- args: string[],
34
- options: WranglerCommandOptions = {}
35
- ): Promise<WranglerResult<string>> {
36
- const { cwd = process.cwd(), env = {}, timeout = 30000, silent = false } = options;
37
-
38
- const command = `${this.wranglerCommand} ${args.join(' ')}`;
39
-
40
- try {
41
- if (!silent) {
42
- console.log(`🔧 Executing: ${command}`);
43
- }
44
-
45
- const { stdout, stderr } = await execAsync(command, {
46
- cwd,
47
- env: { ...process.env, ...env },
48
- timeout,
49
- });
50
-
51
- return {
52
- success: true,
53
- data: stdout.trim(),
54
- stdout: stdout.trim(),
55
- stderr: stderr.trim(),
56
- };
57
- } catch (error: unknown) {
58
- const err = error as { stdout?: string; stderr?: string; code?: number };
59
- return {
60
- success: false,
61
- error: err.stderr || err.stdout || String(error),
62
- exitCode: err.code,
63
- };
64
- }
65
- }
66
-
67
- /**
68
- * Execute a wrangler command with streaming (for dev, tail, etc.)
69
- */
70
- private executeStreaming(
71
- args: string[],
72
- options: WranglerCommandOptions = {}
73
- ): Promise<WranglerResult<void>> {
74
- return new Promise((resolve, reject) => {
75
- const { cwd = process.cwd(), env = {} } = options;
76
- const argsWithCommand = this.wranglerCommand.split(' ').concat(args);
77
-
78
- const child = spawn(argsWithCommand[0], argsWithCommand.slice(1), {
79
- cwd,
80
- env: { ...process.env, ...env },
81
- stdio: 'inherit',
82
- });
83
-
84
- child.on('close', (code) => {
85
- if (code === 0) {
86
- resolve({ success: true });
87
- } else {
88
- resolve({
89
- success: false,
90
- error: `Command exited with code ${code}`,
91
- exitCode: code,
92
- });
93
- }
94
- });
95
-
96
- child.on('error', (error) => {
97
- resolve({
98
- success: false,
99
- error: error.message,
100
- });
101
- });
102
- });
103
- }
104
-
105
- /**
106
- * Parse JSON from stdout
107
- */
108
- private parseJSON<T>(stdout: string): T | null {
109
- try {
110
- // Find JSON in output (wrangler sometimes outputs text before JSON)
111
- const jsonMatch = stdout.match(/\{[\s\S]*\}/);
112
- if (jsonMatch) {
113
- return JSON.parse(jsonMatch[0]) as T;
114
- }
115
- return JSON.parse(stdout) as T;
116
- } catch {
117
- return null;
118
- }
119
- }
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
-
129
- // ==================== Authentication ====================
130
-
131
- async login(options?: WranglerCommandOptions): Promise<WranglerResult<AuthInfo>> {
132
- const result = await this.execute(['login'], options);
133
- if (result.success) {
134
- return {
135
- ...result,
136
- data: { email: 'authenticated' },
137
- };
138
- }
139
- return result;
140
- }
141
-
142
- async logout(options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
143
- return this.asVoidResult(await this.execute(['logout'], options));
144
- }
145
-
146
- async whoami(options?: WranglerCommandOptions): Promise<WranglerResult<AuthInfo>> {
147
- const result = await this.execute(['whoami', '--json'], options);
148
- if (result.success && result.data) {
149
- const data = this.parseJSON<AuthInfo>(result.data);
150
- return {
151
- ...result,
152
- data: data || { email: 'authenticated' },
153
- };
154
- }
155
- return result;
156
- }
157
-
158
- // ==================== Project Management ====================
159
-
160
- async init(
161
- projectName: string,
162
- template?: string,
163
- options?: WranglerCommandOptions
164
- ): Promise<WranglerResult<void>> {
165
- const args = ['init', projectName];
166
- if (template) {
167
- args.push('--template', template);
168
- }
169
- return this.asVoidResult(await this.execute(args, options));
170
- }
171
-
172
- async dev(
173
- options?: WranglerCommandOptions & { port?: number; local?: boolean }
174
- ): Promise<WranglerResult<void>> {
175
- const args = ['dev'];
176
- if (options?.port) {
177
- args.push('--port', options.port.toString());
178
- }
179
- if (options?.local) {
180
- args.push('--local');
181
- }
182
- return this.executeStreaming(args, options);
183
- }
184
-
185
- async deploy(
186
- options?: WranglerCommandOptions & { env?: string }
187
- ): Promise<WranglerResult<{ url?: string }>> {
188
- const args = ['deploy'];
189
- if (options?.env) {
190
- args.push('--env', options.env);
191
- }
192
- const result = await this.execute(args, options);
193
-
194
- if (result.success && result.data) {
195
- // Extract URL from output
196
- const urlMatch = result.data.match(/https?:\/\/[^\s]+/);
197
- return {
198
- ...result,
199
- data: { url: urlMatch?.[0] },
200
- };
201
- }
202
-
203
- return result;
204
- }
205
-
206
- async deleteWorker(
207
- workerName: string,
208
- options?: WranglerCommandOptions
209
- ): Promise<WranglerResult<void>> {
210
- return this.execute(['delete', workerName], options);
211
- }
212
-
213
- // ==================== KV Operations ====================
214
-
215
- async kvNamespaceCreate(
216
- title: string,
217
- options?: WranglerCommandOptions
218
- ): Promise<WranglerResult<KVNamespaceInfo>> {
219
- const result = await this.execute(['kv:namespace', 'create', title], options);
220
- if (result.success && result.data) {
221
- const data = this.parseJSON<KVNamespaceInfo>(result.data);
222
- if (data) {
223
- return { ...result, data };
224
- }
225
- }
226
- return result;
227
- }
228
-
229
- async kvNamespaceList(
230
- options?: WranglerCommandOptions
231
- ): Promise<WranglerResult<KVNamespaceInfo[]>> {
232
- const result = await this.execute(['kv:namespace', 'list'], options);
233
- if (result.success && result.data) {
234
- const data = this.parseJSON<KVNamespaceInfo[]>(result.data);
235
- if (data) {
236
- return { ...result, data };
237
- }
238
- }
239
- return result;
240
- }
241
-
242
- async kvKeyPut(
243
- namespaceId: string,
244
- key: string,
245
- value: string,
246
- options?: WranglerCommandOptions
247
- ): Promise<WranglerResult<void>> {
248
- return this.asVoidResult(await this.execute(['kv:key', 'put', '--namespace-id', namespaceId, key, value], options));
249
- }
250
-
251
- async kvKeyGet(
252
- namespaceId: string,
253
- key: string,
254
- options?: WranglerCommandOptions
255
- ): Promise<WranglerResult<string>> {
256
- return this.execute(['kv:key', 'get', '--namespace-id', namespaceId, key], options);
257
- }
258
-
259
- async kvKeyDelete(
260
- namespaceId: string,
261
- key: string,
262
- options?: WranglerCommandOptions
263
- ): Promise<WranglerResult<void>> {
264
- return this.asVoidResult(await this.execute(['kv:key', 'delete', '--namespace-id', namespaceId, key], options));
265
- }
266
-
267
- // ==================== R2 Operations ====================
268
-
269
- async r2BucketCreate(
270
- bucketName: string,
271
- options?: WranglerCommandOptions
272
- ): Promise<WranglerResult<R2BucketInfo>> {
273
- const result = await this.execute(['r2', 'bucket', 'create', bucketName], options);
274
- if (result.success) {
275
- return {
276
- ...result,
277
- data: { name: bucketName },
278
- };
279
- }
280
- return result;
281
- }
282
-
283
- async r2BucketList(
284
- options?: WranglerCommandOptions
285
- ): Promise<WranglerResult<R2BucketInfo[]>> {
286
- const result = await this.execute(['r2', 'bucket', 'list'], options);
287
- if (result.success && result.data) {
288
- const data = this.parseJSON<R2BucketInfo[]>(result.data);
289
- if (data) {
290
- return { ...result, data };
291
- }
292
- }
293
- return result;
294
- }
295
-
296
- async r2BucketDelete(
297
- bucketName: string,
298
- options?: WranglerCommandOptions
299
- ): Promise<WranglerResult<void>> {
300
- return this.asVoidResult(await this.execute(['r2', 'bucket', 'delete', bucketName], options));
301
- }
302
-
303
- async r2ObjectPut(
304
- bucketName: string,
305
- key: string,
306
- file: string,
307
- options?: WranglerCommandOptions
308
- ): Promise<WranglerResult<void>> {
309
- return this.asVoidResult(await this.execute(['r2', 'object', 'put', bucketName, key, '--file', file], options));
310
- }
311
-
312
- // ==================== D1 Operations ====================
313
-
314
- async d1Create(
315
- databaseName: string,
316
- options?: WranglerCommandOptions
317
- ): Promise<WranglerResult<D1DatabaseInfo>> {
318
- const result = await this.execute(['d1', 'create', databaseName], options);
319
- if (result.success && result.data) {
320
- const data = this.parseJSON<D1DatabaseInfo>(result.data);
321
- if (data) {
322
- return { ...result, data };
323
- }
324
- }
325
- return result;
326
- }
327
-
328
- async d1List(options?: WranglerCommandOptions): Promise<WranglerResult<D1DatabaseInfo[]>> {
329
- const result = await this.execute(['d1', 'list'], options);
330
- if (result.success && result.data) {
331
- const data = this.parseJSON<D1DatabaseInfo[]>(result.data);
332
- if (data) {
333
- return { ...result, data };
334
- }
335
- }
336
- return result;
337
- }
338
-
339
- async d1Execute(
340
- databaseName: string,
341
- command: string,
342
- file?: string,
343
- options?: WranglerCommandOptions
344
- ): Promise<WranglerResult<unknown[]>> {
345
- const args = ['d1', 'execute', databaseName];
346
- if (file) {
347
- args.push('--file', file);
348
- } else {
349
- args.push('--command', command);
350
- }
351
- const result = await this.execute(args, options);
352
- if (result.success && result.data) {
353
- const data = this.parseJSON<unknown[]>(result.data);
354
- if (data) {
355
- return { ...result, data };
356
- }
357
- }
358
- return result;
359
- }
360
-
361
- // ==================== Secrets ====================
362
-
363
- async secretPut(
364
- secretName: string,
365
- value: string,
366
- options?: WranglerCommandOptions
367
- ): Promise<WranglerResult<void>> {
368
- // For secrets, we need to use stdin
369
- return new Promise((resolve) => {
370
- const args = ['secret', 'put', secretName];
371
- const argsWithCommand = this.wranglerCommand.split(' ').concat(args);
372
-
373
- const child = spawn(argsWithCommand[0], argsWithCommand.slice(1), {
374
- cwd: options?.cwd || process.cwd(),
375
- env: { ...process.env, ...options?.env },
376
- stdio: ['pipe', 'pipe', 'pipe'],
377
- });
378
-
379
- let stdout = '';
380
- let stderr = '';
381
-
382
- child.stdout?.on('data', (data) => {
383
- stdout += data.toString();
384
- });
385
-
386
- child.stderr?.on('data', (data) => {
387
- stderr += data.toString();
388
- });
389
-
390
- child.on('close', (code) => {
391
- if (code === 0) {
392
- resolve({ success: true, stdout: stdout.trim() });
393
- } else {
394
- resolve({
395
- success: false,
396
- error: stderr || 'Failed to put secret',
397
- exitCode: code,
398
- });
399
- }
400
- });
401
-
402
- // Write the secret value to stdin
403
- child.stdin?.write(value);
404
- child.stdin?.end();
405
- });
406
- }
407
-
408
- async secretList(options?: WranglerCommandOptions): Promise<WranglerResult<SecretInfo[]>> {
409
- const result = await this.execute(['secret', 'list'], options);
410
- if (result.success && result.data) {
411
- const data = this.parseJSON<SecretInfo[]>(result.data);
412
- if (data) {
413
- return { ...result, data };
414
- }
415
- }
416
- return result;
417
- }
418
-
419
- async secretDelete(
420
- secretName: string,
421
- options?: WranglerCommandOptions
422
- ): Promise<WranglerResult<void>> {
423
- return this.asVoidResult(await this.execute(['secret', 'delete', secretName], options));
424
- }
425
-
426
- // ==================== Monitoring ====================
427
-
428
- async tail(
429
- options?: WranglerCommandOptions & { format?: 'pretty' | 'json' }
430
- ): Promise<WranglerResult<void>> {
431
- const args = ['tail'];
432
- if (options?.format) {
433
- args.push('--format', options.format);
434
- }
435
- return this.executeStreaming(args, options);
436
- }
437
-
438
- // ==================== Versions ====================
439
-
440
- async versionsList(
441
- options?: WranglerCommandOptions
442
- ): Promise<WranglerResult<WorkerVersionInfo[]>> {
443
- const result = await this.execute(['versions', 'list'], options);
444
- if (result.success && result.data) {
445
- const data = this.parseJSON<WorkerVersionInfo[]>(result.data);
446
- if (data) {
447
- return { ...result, data };
448
- }
449
- }
450
- return result;
451
- }
452
-
453
- async versionsRollback(
454
- versionId: string,
455
- options?: WranglerCommandOptions
456
- ): Promise<WranglerResult<void>> {
457
- return this.asVoidResult(await this.execute(['versions', 'rollback', '--version-id', versionId], options));
458
- }
459
-
460
- // ==================== Generic Command Execution ====================
461
-
462
- async executeCommand(
463
- command: string,
464
- args: string[],
465
- options?: WranglerCommandOptions
466
- ): Promise<WranglerResult<string>> {
467
- return this.execute([command, ...args], options);
33
+ // Authentication
34
+ async login(_options?: WranglerCommandOptions): Promise<WranglerResult<AuthInfo>> {
35
+ return this.nodeNotAvailable<AuthInfo>();
36
+ }
37
+
38
+ async logout(_options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
39
+ return this.nodeNotAvailable<void>();
40
+ }
41
+
42
+ async whoami(_options?: WranglerCommandOptions): Promise<WranglerResult<AuthInfo>> {
43
+ return this.nodeNotAvailable<AuthInfo>();
44
+ }
45
+
46
+ // Project management
47
+ async init(_projectName: string, _template?: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
48
+ return this.nodeNotAvailable<void>();
49
+ }
50
+
51
+ async dev(_options?: WranglerCommandOptions & { port?: number; local?: boolean }): Promise<WranglerResult<void>> {
52
+ return this.nodeNotAvailable<void>();
53
+ }
54
+
55
+ async deploy(_options?: WranglerCommandOptions & { env?: string }): Promise<WranglerResult<{ url?: string }>> {
56
+ return this.nodeNotAvailable<{ url?: string }>();
57
+ }
58
+
59
+ async deleteWorker(_workerName: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
60
+ return this.nodeNotAvailable<void>();
61
+ }
62
+
63
+ // KV operations
64
+ async kvNamespaceCreate(_title: string, _options?: WranglerCommandOptions): Promise<WranglerResult<KVNamespaceInfo>> {
65
+ return this.nodeNotAvailable<KVNamespaceInfo>();
66
+ }
67
+
68
+ async kvNamespaceList(_options?: WranglerCommandOptions): Promise<WranglerResult<KVNamespaceInfo[]>> {
69
+ return this.nodeNotAvailable<KVNamespaceInfo[]>();
70
+ }
71
+
72
+ async kvKeyPut(_namespaceId: string, _key: string, _value: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
73
+ return this.nodeNotAvailable<void>();
74
+ }
75
+
76
+ async kvKeyList(_namespaceId: string, _options?: WranglerCommandOptions): Promise<WranglerResult<string[]>> {
77
+ return this.nodeNotAvailable<string[]>();
78
+ }
79
+
80
+ async kvKeyGet(_namespaceId: string, _key: string, _options?: WranglerCommandOptions): Promise<WranglerResult<string>> {
81
+ return this.nodeNotAvailable<string>();
82
+ }
83
+
84
+ async kvKeyDelete(_namespaceId: string, _key: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
85
+ return this.nodeNotAvailable<void>();
86
+ }
87
+
88
+ // R2 operations
89
+ async r2BucketCreate(_bucketName: string, _options?: WranglerCommandOptions): Promise<WranglerResult<R2BucketInfo>> {
90
+ return this.nodeNotAvailable<R2BucketInfo>();
91
+ }
92
+
93
+ async r2BucketList(_options?: WranglerCommandOptions): Promise<WranglerResult<R2BucketInfo[]>> {
94
+ return this.nodeNotAvailable<R2BucketInfo[]>();
95
+ }
96
+
97
+ async r2BucketDelete(_bucketName: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
98
+ return this.nodeNotAvailable<void>();
99
+ }
100
+
101
+ async r2ObjectPut(_bucketName: string, _key: string, _file: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
102
+ return this.nodeNotAvailable<void>();
103
+ }
104
+
105
+ async r2ObjectGet(_bucketName: string, _key: string, _file: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
106
+ return this.nodeNotAvailable<void>();
107
+ }
108
+
109
+ async r2ObjectDelete(_bucketName: string, _key: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
110
+ return this.nodeNotAvailable<void>();
111
+ }
112
+
113
+ // D1 operations
114
+ async d1DatabaseCreate(_databaseName: string, _options?: WranglerCommandOptions): Promise<WranglerResult<D1DatabaseInfo>> {
115
+ return this.nodeNotAvailable<D1DatabaseInfo>();
116
+ }
117
+
118
+ async d1DatabaseList(_options?: WranglerCommandOptions): Promise<WranglerResult<D1DatabaseInfo[]>> {
119
+ return this.nodeNotAvailable<D1DatabaseInfo[]>();
120
+ }
121
+
122
+ async d1Create(_databaseName: string, _options?: WranglerCommandOptions): Promise<WranglerResult<D1DatabaseInfo>> {
123
+ return this.nodeNotAvailable<D1DatabaseInfo>();
124
+ }
125
+
126
+ async d1List(_options?: WranglerCommandOptions): Promise<WranglerResult<D1DatabaseInfo[]>> {
127
+ return this.nodeNotAvailable<D1DatabaseInfo[]>();
128
+ }
129
+
130
+ async d1Execute(_databaseName: string, _command: string, _file?: string, _options?: WranglerCommandOptions): Promise<WranglerResult<unknown[]>> {
131
+ return this.nodeNotAvailable<unknown[]>();
132
+ }
133
+
134
+ // Secret management
135
+ async secretPut(_secretName: string, _value: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
136
+ return this.nodeNotAvailable<void>();
137
+ }
138
+
139
+ async secretList(_options?: WranglerCommandOptions): Promise<WranglerResult<SecretInfo[]>> {
140
+ return this.nodeNotAvailable<SecretInfo[]>();
141
+ }
142
+
143
+ async secretDelete(_secretName: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
144
+ return this.nodeNotAvailable<void>();
145
+ }
146
+
147
+ // Tail logs
148
+ async tail(_options?: WranglerCommandOptions & { format?: "json" | "pretty" }): Promise<WranglerResult<void>> {
149
+ return this.nodeNotAvailable<void>();
150
+ }
151
+
152
+ // Versions
153
+ async versionsList(_options?: WranglerCommandOptions): Promise<WranglerResult<WorkerVersionInfo[]>> {
154
+ return this.nodeNotAvailable<WorkerVersionInfo[]>();
155
+ }
156
+
157
+ async versionsRollback(_versionId: string, _options?: WranglerCommandOptions): Promise<WranglerResult<void>> {
158
+ return this.nodeNotAvailable<void>();
159
+ }
160
+
161
+ // Generic command execution
162
+ async executeCommand(_command: string, _args: string[], _options?: WranglerCommandOptions): Promise<WranglerResult<string>> {
163
+ return this.nodeNotAvailable<string>();
164
+ }
165
+
166
+ private nodeNotAvailable<T>(): never {
167
+ throw new Error(
168
+ 'WranglerService requires Node.js runtime. ' +
169
+ 'This service only works in Node.js environment, not in Cloudflare Workers. ' +
170
+ 'Use this service in build scripts or development tools only.'
171
+ );
468
172
  }
469
173
  }
174
+
175
+ // Export singleton instance
176
+ export const wranglerService = new WranglerService();