autotel-cloudflare 2.12.0 → 2.14.0

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 (44) hide show
  1. package/dist/actors.js +1 -1
  2. package/dist/bindings.d.ts +113 -1
  3. package/dist/bindings.js +2 -2
  4. package/dist/chunk-4UG2QCPQ.js +1060 -0
  5. package/dist/chunk-4UG2QCPQ.js.map +1 -0
  6. package/dist/{chunk-5NL62W4L.js → chunk-O4IYKWPJ.js} +8 -3
  7. package/dist/chunk-O4IYKWPJ.js.map +1 -0
  8. package/dist/{chunk-ADWSZ5GY.js → chunk-WDNZVVRW.js} +8 -9
  9. package/dist/chunk-WDNZVVRW.js.map +1 -0
  10. package/dist/handlers.d.ts +5 -14
  11. package/dist/handlers.js +2 -2
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +34 -6
  14. package/dist/index.js.map +1 -1
  15. package/package.json +2 -2
  16. package/src/bindings/ai.test.ts +156 -0
  17. package/src/bindings/ai.ts +71 -0
  18. package/src/bindings/analytics-engine.test.ts +160 -0
  19. package/src/bindings/analytics-engine.ts +78 -0
  20. package/src/bindings/bindings-detection.test.ts +235 -0
  21. package/src/bindings/bindings.ts +98 -47
  22. package/src/bindings/browser-rendering.test.ts +144 -0
  23. package/src/bindings/browser-rendering.ts +70 -0
  24. package/src/bindings/common.ts +9 -0
  25. package/src/bindings/hyperdrive.test.ts +154 -0
  26. package/src/bindings/hyperdrive.ts +74 -0
  27. package/src/bindings/images.test.ts +229 -0
  28. package/src/bindings/images.ts +182 -0
  29. package/src/bindings/index.ts +8 -0
  30. package/src/bindings/queue-producer.test.ts +192 -0
  31. package/src/bindings/queue-producer.ts +105 -0
  32. package/src/bindings/rate-limiter.test.ts +124 -0
  33. package/src/bindings/rate-limiter.ts +69 -0
  34. package/src/bindings/vectorize.test.ts +340 -0
  35. package/src/bindings/vectorize.ts +86 -0
  36. package/src/handlers/workflows.test.ts +325 -0
  37. package/src/handlers/workflows.ts +51 -41
  38. package/src/index.ts +8 -0
  39. package/src/wrappers/cf-attributes.test.ts +275 -0
  40. package/src/wrappers/instrument.ts +38 -0
  41. package/dist/chunk-5NL62W4L.js.map +0 -1
  42. package/dist/chunk-ADWSZ5GY.js.map +0 -1
  43. package/dist/chunk-UPQE3J4I.js +0 -520
  44. package/dist/chunk-UPQE3J4I.js.map +0 -1
@@ -0,0 +1,1060 @@
1
+ import { wrap, isWrapped, setAttr } from './chunk-O4IYKWPJ.js';
2
+ import { trace, SpanKind, SpanStatusCode } from '@opentelemetry/api';
3
+
4
+ function instrumentAI(ai, bindingName) {
5
+ const name = bindingName || "ai";
6
+ const handler = {
7
+ get(target, prop) {
8
+ const value = Reflect.get(target, prop);
9
+ if (prop === "run" && typeof value === "function") {
10
+ return new Proxy(value, {
11
+ apply: (fnTarget, thisArg, args) => {
12
+ const [model] = args;
13
+ const tracer = trace.getTracer("autotel-edge");
14
+ return tracer.startActiveSpan(
15
+ `AI ${name}: run ${model}`,
16
+ {
17
+ kind: SpanKind.CLIENT,
18
+ attributes: {
19
+ "gen_ai.system": "cloudflare-workers-ai",
20
+ "gen_ai.operation.name": "run",
21
+ "gen_ai.request.model": model
22
+ }
23
+ },
24
+ async (span) => {
25
+ try {
26
+ const result = await Reflect.apply(fnTarget, thisArg, args);
27
+ if (result?.usage?.prompt_tokens !== void 0) {
28
+ setAttr(span, "gen_ai.usage.input_tokens", Number(result.usage.prompt_tokens));
29
+ }
30
+ if (result?.usage?.completion_tokens !== void 0) {
31
+ setAttr(span, "gen_ai.usage.output_tokens", Number(result.usage.completion_tokens));
32
+ }
33
+ span.setStatus({ code: SpanStatusCode.OK });
34
+ return result;
35
+ } catch (error) {
36
+ span.recordException(error);
37
+ span.setStatus({
38
+ code: SpanStatusCode.ERROR,
39
+ message: error instanceof Error ? error.message : String(error)
40
+ });
41
+ throw error;
42
+ } finally {
43
+ span.end();
44
+ }
45
+ }
46
+ );
47
+ }
48
+ });
49
+ }
50
+ return value;
51
+ }
52
+ };
53
+ return wrap(ai, handler);
54
+ }
55
+ var TRACED_METHODS = ["query", "insert", "upsert", "deleteByIds", "getByIds", "describe"];
56
+ function instrumentVectorize(vectorize, indexName) {
57
+ const name = indexName || "vectorize";
58
+ const handler = {
59
+ get(target, prop) {
60
+ const value = Reflect.get(target, prop);
61
+ if (typeof prop === "string" && TRACED_METHODS.includes(prop) && typeof value === "function") {
62
+ return new Proxy(value, {
63
+ apply: (fnTarget, thisArg, args) => {
64
+ const operation = prop;
65
+ const tracer = trace.getTracer("autotel-edge");
66
+ const attributes = {
67
+ "db.system": "cloudflare-vectorize",
68
+ "db.operation": operation,
69
+ "db.collection.name": name
70
+ };
71
+ if (operation === "query") {
72
+ const queryInput = args[0];
73
+ if (queryInput?.topK !== void 0) {
74
+ attributes["db.vectorize.top_k"] = queryInput.topK;
75
+ }
76
+ }
77
+ if ((operation === "insert" || operation === "upsert") && Array.isArray(args[0])) {
78
+ attributes["db.vectorize.vectors_count"] = args[0].length;
79
+ }
80
+ return tracer.startActiveSpan(
81
+ `Vectorize ${name}: ${operation}`,
82
+ {
83
+ kind: SpanKind.CLIENT,
84
+ attributes
85
+ },
86
+ async (span) => {
87
+ try {
88
+ const result = await Reflect.apply(fnTarget, thisArg, args);
89
+ if (operation === "query" && result?.matches) {
90
+ setAttr(span, "db.vectorize.matches_count", result.matches.length);
91
+ }
92
+ span.setStatus({ code: SpanStatusCode.OK });
93
+ return result;
94
+ } catch (error) {
95
+ span.recordException(error);
96
+ span.setStatus({
97
+ code: SpanStatusCode.ERROR,
98
+ message: error instanceof Error ? error.message : String(error)
99
+ });
100
+ throw error;
101
+ } finally {
102
+ span.end();
103
+ }
104
+ }
105
+ );
106
+ }
107
+ });
108
+ }
109
+ return value;
110
+ }
111
+ };
112
+ return wrap(vectorize, handler);
113
+ }
114
+ function instrumentHyperdrive(hyperdrive, bindingName) {
115
+ const name = bindingName || "hyperdrive";
116
+ const handler = {
117
+ get(target, prop) {
118
+ const value = Reflect.get(target, prop);
119
+ if (prop === "connect" && typeof value === "function") {
120
+ return new Proxy(value, {
121
+ apply: (fnTarget, thisArg, args) => {
122
+ const tracer = trace.getTracer("autotel-edge");
123
+ const attributes = {
124
+ "db.system": "cloudflare-hyperdrive",
125
+ "db.operation": "connect"
126
+ };
127
+ try {
128
+ setAttr({ setAttribute: (k, v) => {
129
+ if (v !== void 0 && v !== null) attributes[k] = v;
130
+ } }, "server.address", target.host);
131
+ setAttr({ setAttribute: (k, v) => {
132
+ if (v !== void 0 && v !== null) attributes[k] = v;
133
+ } }, "server.port", target.port);
134
+ setAttr({ setAttribute: (k, v) => {
135
+ if (v !== void 0 && v !== null) attributes[k] = v;
136
+ } }, "db.user", target.user);
137
+ } catch {
138
+ }
139
+ return tracer.startActiveSpan(
140
+ `Hyperdrive ${name}: connect`,
141
+ {
142
+ kind: SpanKind.CLIENT,
143
+ attributes
144
+ },
145
+ async (span) => {
146
+ try {
147
+ const result = await Reflect.apply(fnTarget, thisArg, args);
148
+ span.setStatus({ code: SpanStatusCode.OK });
149
+ return result;
150
+ } catch (error) {
151
+ span.recordException(error);
152
+ span.setStatus({
153
+ code: SpanStatusCode.ERROR,
154
+ message: error instanceof Error ? error.message : String(error)
155
+ });
156
+ throw error;
157
+ } finally {
158
+ span.end();
159
+ }
160
+ }
161
+ );
162
+ }
163
+ });
164
+ }
165
+ return value;
166
+ }
167
+ };
168
+ return wrap(hyperdrive, handler);
169
+ }
170
+ function instrumentQueueProducer(queue, queueName) {
171
+ const name = queueName || "queue";
172
+ const handler = {
173
+ get(target, prop) {
174
+ const value = Reflect.get(target, prop);
175
+ if (prop === "send" && typeof value === "function") {
176
+ return new Proxy(value, {
177
+ apply: (fnTarget, thisArg, args) => {
178
+ const tracer = trace.getTracer("autotel-edge");
179
+ return tracer.startActiveSpan(
180
+ `Queue ${name}: send`,
181
+ {
182
+ kind: SpanKind.PRODUCER,
183
+ attributes: {
184
+ "messaging.system": "cloudflare-queues",
185
+ "messaging.operation.type": "publish",
186
+ "messaging.operation": "send",
187
+ "messaging.destination.name": name
188
+ }
189
+ },
190
+ async (span) => {
191
+ try {
192
+ const result = await Reflect.apply(fnTarget, thisArg, args);
193
+ setAttr(span, "messaging.message.id", result?.messageId);
194
+ span.setStatus({ code: SpanStatusCode.OK });
195
+ return result;
196
+ } catch (error) {
197
+ span.recordException(error);
198
+ span.setStatus({
199
+ code: SpanStatusCode.ERROR,
200
+ message: error instanceof Error ? error.message : String(error)
201
+ });
202
+ throw error;
203
+ } finally {
204
+ span.end();
205
+ }
206
+ }
207
+ );
208
+ }
209
+ });
210
+ }
211
+ if (prop === "sendBatch" && typeof value === "function") {
212
+ return new Proxy(value, {
213
+ apply: (fnTarget, thisArg, args) => {
214
+ const [messages] = args;
215
+ const tracer = trace.getTracer("autotel-edge");
216
+ return tracer.startActiveSpan(
217
+ `Queue ${name}: sendBatch`,
218
+ {
219
+ kind: SpanKind.PRODUCER,
220
+ attributes: {
221
+ "messaging.system": "cloudflare-queues",
222
+ "messaging.operation.type": "publish",
223
+ "messaging.operation": "sendBatch",
224
+ "messaging.destination.name": name,
225
+ "messaging.batch.message_count": Array.isArray(messages) ? messages.length : 0
226
+ }
227
+ },
228
+ async (span) => {
229
+ try {
230
+ const result = await Reflect.apply(fnTarget, thisArg, args);
231
+ span.setStatus({ code: SpanStatusCode.OK });
232
+ return result;
233
+ } catch (error) {
234
+ span.recordException(error);
235
+ span.setStatus({
236
+ code: SpanStatusCode.ERROR,
237
+ message: error instanceof Error ? error.message : String(error)
238
+ });
239
+ throw error;
240
+ } finally {
241
+ span.end();
242
+ }
243
+ }
244
+ );
245
+ }
246
+ });
247
+ }
248
+ return value;
249
+ }
250
+ };
251
+ return wrap(queue, handler);
252
+ }
253
+ function instrumentAnalyticsEngine(ae, datasetName) {
254
+ const name = datasetName || "analytics-engine";
255
+ const handler = {
256
+ get(target, prop) {
257
+ const value = Reflect.get(target, prop);
258
+ if (prop === "writeDataPoint" && typeof value === "function") {
259
+ return new Proxy(value, {
260
+ apply: (fnTarget, thisArg, args) => {
261
+ const [dataPoint] = args;
262
+ const tracer = trace.getTracer("autotel-edge");
263
+ const attributes = {
264
+ "analytics.system": "cloudflare-analytics-engine",
265
+ "analytics.operation": "writeDataPoint"
266
+ };
267
+ if (dataPoint) {
268
+ if (dataPoint.indexes) {
269
+ attributes["analytics.indexes_count"] = Array.isArray(dataPoint.indexes) ? dataPoint.indexes.length : 1;
270
+ }
271
+ if (dataPoint.doubles) {
272
+ attributes["analytics.doubles_count"] = dataPoint.doubles.length;
273
+ }
274
+ if (dataPoint.blobs) {
275
+ attributes["analytics.blobs_count"] = dataPoint.blobs.length;
276
+ }
277
+ }
278
+ return tracer.startActiveSpan(
279
+ `AnalyticsEngine ${name}: writeDataPoint`,
280
+ {
281
+ kind: SpanKind.CLIENT,
282
+ attributes
283
+ },
284
+ (span) => {
285
+ try {
286
+ Reflect.apply(fnTarget, thisArg, args);
287
+ span.setStatus({ code: SpanStatusCode.OK });
288
+ } catch (error) {
289
+ span.recordException(error);
290
+ span.setStatus({
291
+ code: SpanStatusCode.ERROR,
292
+ message: error instanceof Error ? error.message : String(error)
293
+ });
294
+ throw error;
295
+ } finally {
296
+ span.end();
297
+ }
298
+ }
299
+ );
300
+ }
301
+ });
302
+ }
303
+ return value;
304
+ }
305
+ };
306
+ return wrap(ae, handler);
307
+ }
308
+ var pipelineMetaSymbol = /* @__PURE__ */ Symbol("images-pipeline-meta");
309
+ function proxyTransformer(transformer, meta, bindingName) {
310
+ const handler = {
311
+ get(target, prop) {
312
+ const value = Reflect.get(target, prop);
313
+ if ((prop === "transform" || prop === "draw") && typeof value === "function") {
314
+ return new Proxy(value, {
315
+ apply: (fnTarget, _thisArg, args) => {
316
+ meta.operationCount++;
317
+ const result = Reflect.apply(fnTarget, target, args);
318
+ if (result === target || result && typeof result === "object" && "output" in result) {
319
+ return proxyTransformer(result, meta, bindingName);
320
+ }
321
+ return result;
322
+ }
323
+ });
324
+ }
325
+ if (prop === "output" && typeof value === "function") {
326
+ return new Proxy(value, {
327
+ apply: (fnTarget, _thisArg, args) => {
328
+ const tracer = trace.getTracer("autotel-edge");
329
+ const [formatOrOptions] = args;
330
+ const attributes = {
331
+ "images.system": "cloudflare-images",
332
+ "images.pipeline.operation_count": meta.operationCount
333
+ };
334
+ if (typeof formatOrOptions === "string") {
335
+ attributes["images.output.format"] = formatOrOptions;
336
+ } else if (formatOrOptions && typeof formatOrOptions === "object") {
337
+ const fmt = formatOrOptions.format;
338
+ if (fmt) attributes["images.output.format"] = fmt;
339
+ }
340
+ return tracer.startActiveSpan(
341
+ `Images ${bindingName}: output`,
342
+ {
343
+ kind: SpanKind.CLIENT,
344
+ attributes
345
+ },
346
+ async (span) => {
347
+ try {
348
+ const result = await Reflect.apply(fnTarget, target, args);
349
+ span.setStatus({ code: SpanStatusCode.OK });
350
+ return result;
351
+ } catch (error) {
352
+ span.recordException(error);
353
+ span.setStatus({
354
+ code: SpanStatusCode.ERROR,
355
+ message: error instanceof Error ? error.message : String(error)
356
+ });
357
+ throw error;
358
+ } finally {
359
+ span.end();
360
+ }
361
+ }
362
+ );
363
+ }
364
+ });
365
+ }
366
+ return value;
367
+ }
368
+ };
369
+ const proxy = new Proxy(transformer, handler);
370
+ Object.defineProperty(proxy, pipelineMetaSymbol, {
371
+ value: meta,
372
+ writable: false,
373
+ enumerable: false,
374
+ configurable: false
375
+ });
376
+ return proxy;
377
+ }
378
+ function instrumentImages(images, bindingName) {
379
+ const name = bindingName || "images";
380
+ const handler = {
381
+ get(target, prop) {
382
+ const value = Reflect.get(target, prop);
383
+ if (prop === "info" && typeof value === "function") {
384
+ return new Proxy(value, {
385
+ apply: (fnTarget, thisArg, args) => {
386
+ const tracer = trace.getTracer("autotel-edge");
387
+ return tracer.startActiveSpan(
388
+ `Images ${name}: info`,
389
+ {
390
+ kind: SpanKind.CLIENT,
391
+ attributes: {
392
+ "images.system": "cloudflare-images",
393
+ "images.operation": "info"
394
+ }
395
+ },
396
+ async (span) => {
397
+ try {
398
+ const result = await Reflect.apply(fnTarget, thisArg, args);
399
+ setAttr(span, "images.width", result?.width);
400
+ setAttr(span, "images.height", result?.height);
401
+ setAttr(span, "images.format", result?.format);
402
+ span.setStatus({ code: SpanStatusCode.OK });
403
+ return result;
404
+ } catch (error) {
405
+ span.recordException(error);
406
+ span.setStatus({
407
+ code: SpanStatusCode.ERROR,
408
+ message: error instanceof Error ? error.message : String(error)
409
+ });
410
+ throw error;
411
+ } finally {
412
+ span.end();
413
+ }
414
+ }
415
+ );
416
+ }
417
+ });
418
+ }
419
+ if (prop === "input" && typeof value === "function") {
420
+ return new Proxy(value, {
421
+ apply: (fnTarget, thisArg, args) => {
422
+ const transformer = Reflect.apply(fnTarget, thisArg, args);
423
+ const meta = { operationCount: 0 };
424
+ return proxyTransformer(transformer, meta, name);
425
+ }
426
+ });
427
+ }
428
+ return value;
429
+ }
430
+ };
431
+ return wrap(images, handler);
432
+ }
433
+
434
+ // src/bindings/bindings.ts
435
+ function instrumentKV(kv, namespaceName) {
436
+ const name = namespaceName || "kv";
437
+ const kvHandler = {
438
+ get(target, prop) {
439
+ const value = Reflect.get(target, prop);
440
+ if (prop === "get" && typeof value === "function") {
441
+ return new Proxy(value, {
442
+ apply: (fnTarget, thisArg, args) => {
443
+ const [key, options] = args;
444
+ const tracer = trace.getTracer("autotel-edge");
445
+ return tracer.startActiveSpan(
446
+ `KV ${name}: get`,
447
+ {
448
+ kind: SpanKind.CLIENT,
449
+ attributes: {
450
+ "db.system": "cloudflare-kv",
451
+ "db.operation": "get",
452
+ "db.namespace": name,
453
+ "db.key": key,
454
+ "db.cache_hit": options?.cacheTtl !== void 0
455
+ }
456
+ },
457
+ async (span) => {
458
+ try {
459
+ const result = await Reflect.apply(fnTarget, thisArg, args);
460
+ span.setAttribute("db.result.type", result === null ? "null" : typeof result);
461
+ span.setStatus({ code: SpanStatusCode.OK });
462
+ return result;
463
+ } catch (error) {
464
+ span.recordException(error);
465
+ span.setStatus({
466
+ code: SpanStatusCode.ERROR,
467
+ message: error instanceof Error ? error.message : String(error)
468
+ });
469
+ throw error;
470
+ } finally {
471
+ span.end();
472
+ }
473
+ }
474
+ );
475
+ }
476
+ });
477
+ }
478
+ if (prop === "put" && typeof value === "function") {
479
+ return new Proxy(value, {
480
+ apply: (fnTarget, thisArg, args) => {
481
+ const [key] = args;
482
+ const tracer = trace.getTracer("autotel-edge");
483
+ return tracer.startActiveSpan(
484
+ `KV ${name}: put`,
485
+ {
486
+ kind: SpanKind.CLIENT,
487
+ attributes: {
488
+ "db.system": "cloudflare-kv",
489
+ "db.operation": "put",
490
+ "db.namespace": name,
491
+ "db.key": key
492
+ }
493
+ },
494
+ async (span) => {
495
+ try {
496
+ const result = await Reflect.apply(fnTarget, thisArg, args);
497
+ span.setStatus({ code: SpanStatusCode.OK });
498
+ return result;
499
+ } catch (error) {
500
+ span.recordException(error);
501
+ span.setStatus({
502
+ code: SpanStatusCode.ERROR,
503
+ message: error instanceof Error ? error.message : String(error)
504
+ });
505
+ throw error;
506
+ } finally {
507
+ span.end();
508
+ }
509
+ }
510
+ );
511
+ }
512
+ });
513
+ }
514
+ if (prop === "delete" && typeof value === "function") {
515
+ return new Proxy(value, {
516
+ apply: (fnTarget, thisArg, args) => {
517
+ const [key] = args;
518
+ const tracer = trace.getTracer("autotel-edge");
519
+ return tracer.startActiveSpan(
520
+ `KV ${name}: delete`,
521
+ {
522
+ kind: SpanKind.CLIENT,
523
+ attributes: {
524
+ "db.system": "cloudflare-kv",
525
+ "db.operation": "delete",
526
+ "db.namespace": name,
527
+ "db.key": key
528
+ }
529
+ },
530
+ async (span) => {
531
+ try {
532
+ const result = await Reflect.apply(fnTarget, thisArg, args);
533
+ span.setStatus({ code: SpanStatusCode.OK });
534
+ return result;
535
+ } catch (error) {
536
+ span.recordException(error);
537
+ span.setStatus({
538
+ code: SpanStatusCode.ERROR,
539
+ message: error instanceof Error ? error.message : String(error)
540
+ });
541
+ throw error;
542
+ } finally {
543
+ span.end();
544
+ }
545
+ }
546
+ );
547
+ }
548
+ });
549
+ }
550
+ if (prop === "list" && typeof value === "function") {
551
+ return new Proxy(value, {
552
+ apply: (fnTarget, thisArg, args) => {
553
+ const [options] = args;
554
+ const tracer = trace.getTracer("autotel-edge");
555
+ return tracer.startActiveSpan(
556
+ `KV ${name}: list`,
557
+ {
558
+ kind: SpanKind.CLIENT,
559
+ attributes: {
560
+ "db.system": "cloudflare-kv",
561
+ "db.operation": "list",
562
+ "db.namespace": name,
563
+ "db.prefix": options?.prefix || void 0,
564
+ "db.limit": options?.limit || void 0
565
+ }
566
+ },
567
+ async (span) => {
568
+ try {
569
+ const result = await Reflect.apply(fnTarget, thisArg, args);
570
+ span.setAttribute("db.result.keys_count", result.keys.length);
571
+ span.setStatus({ code: SpanStatusCode.OK });
572
+ return result;
573
+ } catch (error) {
574
+ span.recordException(error);
575
+ span.setStatus({
576
+ code: SpanStatusCode.ERROR,
577
+ message: error instanceof Error ? error.message : String(error)
578
+ });
579
+ throw error;
580
+ } finally {
581
+ span.end();
582
+ }
583
+ }
584
+ );
585
+ }
586
+ });
587
+ }
588
+ return value;
589
+ }
590
+ };
591
+ return wrap(kv, kvHandler);
592
+ }
593
+ function instrumentR2(r2, bucketName) {
594
+ const name = bucketName || "r2";
595
+ const r2Handler = {
596
+ get(target, prop) {
597
+ const value = Reflect.get(target, prop);
598
+ if (prop === "get" && typeof value === "function") {
599
+ return new Proxy(value, {
600
+ apply: (fnTarget, thisArg, args) => {
601
+ const [key] = args;
602
+ const tracer = trace.getTracer("autotel-edge");
603
+ return tracer.startActiveSpan(
604
+ `R2 ${name}: get`,
605
+ {
606
+ kind: SpanKind.CLIENT,
607
+ attributes: {
608
+ "db.system": "cloudflare-r2",
609
+ "db.operation": "get",
610
+ "db.bucket": name,
611
+ "db.key": key
612
+ }
613
+ },
614
+ async (span) => {
615
+ try {
616
+ const result = await Reflect.apply(fnTarget, thisArg, args);
617
+ if (result) {
618
+ span.setAttribute("db.result.size", result.size);
619
+ span.setAttribute("db.result.etag", result.etag);
620
+ span.setAttribute("db.result.content_type", result.httpMetadata?.contentType);
621
+ } else {
622
+ span.setAttribute("db.result.exists", false);
623
+ }
624
+ span.setStatus({ code: SpanStatusCode.OK });
625
+ return result;
626
+ } catch (error) {
627
+ span.recordException(error);
628
+ span.setStatus({
629
+ code: SpanStatusCode.ERROR,
630
+ message: error instanceof Error ? error.message : String(error)
631
+ });
632
+ throw error;
633
+ } finally {
634
+ span.end();
635
+ }
636
+ }
637
+ );
638
+ }
639
+ });
640
+ }
641
+ if (prop === "put" && typeof value === "function") {
642
+ return new Proxy(value, {
643
+ apply: (fnTarget, thisArg, args) => {
644
+ const [key] = args;
645
+ const tracer = trace.getTracer("autotel-edge");
646
+ return tracer.startActiveSpan(
647
+ `R2 ${name}: put`,
648
+ {
649
+ kind: SpanKind.CLIENT,
650
+ attributes: {
651
+ "db.system": "cloudflare-r2",
652
+ "db.operation": "put",
653
+ "db.bucket": name,
654
+ "db.key": key
655
+ }
656
+ },
657
+ async (span) => {
658
+ try {
659
+ const result = await Reflect.apply(fnTarget, thisArg, args);
660
+ span.setAttribute("db.result.etag", result.etag);
661
+ span.setAttribute("db.result.uploaded", result.uploaded);
662
+ span.setStatus({ code: SpanStatusCode.OK });
663
+ return result;
664
+ } catch (error) {
665
+ span.recordException(error);
666
+ span.setStatus({
667
+ code: SpanStatusCode.ERROR,
668
+ message: error instanceof Error ? error.message : String(error)
669
+ });
670
+ throw error;
671
+ } finally {
672
+ span.end();
673
+ }
674
+ }
675
+ );
676
+ }
677
+ });
678
+ }
679
+ if (prop === "delete" && typeof value === "function") {
680
+ return new Proxy(value, {
681
+ apply: (fnTarget, thisArg, args) => {
682
+ const keys = args;
683
+ const tracer = trace.getTracer("autotel-edge");
684
+ return tracer.startActiveSpan(
685
+ `R2 ${name}: delete`,
686
+ {
687
+ kind: SpanKind.CLIENT,
688
+ attributes: {
689
+ "db.system": "cloudflare-r2",
690
+ "db.operation": "delete",
691
+ "db.bucket": name,
692
+ "db.keys_count": keys.length
693
+ }
694
+ },
695
+ async (span) => {
696
+ try {
697
+ const result = await Reflect.apply(fnTarget, thisArg, args);
698
+ span.setStatus({ code: SpanStatusCode.OK });
699
+ return result;
700
+ } catch (error) {
701
+ span.recordException(error);
702
+ span.setStatus({
703
+ code: SpanStatusCode.ERROR,
704
+ message: error instanceof Error ? error.message : String(error)
705
+ });
706
+ throw error;
707
+ } finally {
708
+ span.end();
709
+ }
710
+ }
711
+ );
712
+ }
713
+ });
714
+ }
715
+ if (prop === "list" && typeof value === "function") {
716
+ return new Proxy(value, {
717
+ apply: (fnTarget, thisArg, args) => {
718
+ const [options] = args;
719
+ const tracer = trace.getTracer("autotel-edge");
720
+ return tracer.startActiveSpan(
721
+ `R2 ${name}: list`,
722
+ {
723
+ kind: SpanKind.CLIENT,
724
+ attributes: {
725
+ "db.system": "cloudflare-r2",
726
+ "db.operation": "list",
727
+ "db.bucket": name,
728
+ "db.prefix": options?.prefix || void 0,
729
+ "db.limit": options?.limit || void 0
730
+ }
731
+ },
732
+ async (span) => {
733
+ try {
734
+ const result = await Reflect.apply(fnTarget, thisArg, args);
735
+ span.setAttribute("db.result.objects_count", result.objects.length);
736
+ span.setAttribute("db.result.truncated", result.truncated);
737
+ span.setStatus({ code: SpanStatusCode.OK });
738
+ return result;
739
+ } catch (error) {
740
+ span.recordException(error);
741
+ span.setStatus({
742
+ code: SpanStatusCode.ERROR,
743
+ message: error instanceof Error ? error.message : String(error)
744
+ });
745
+ throw error;
746
+ } finally {
747
+ span.end();
748
+ }
749
+ }
750
+ );
751
+ }
752
+ });
753
+ }
754
+ return value;
755
+ }
756
+ };
757
+ return wrap(r2, r2Handler);
758
+ }
759
+ function instrumentD1(d1, databaseName) {
760
+ const name = databaseName || "d1";
761
+ const d1Handler = {
762
+ get(target, prop) {
763
+ const value = Reflect.get(target, prop);
764
+ if (prop === "prepare" && typeof value === "function") {
765
+ return new Proxy(value, {
766
+ apply: (fnTarget, thisArg, args) => {
767
+ const [query] = args;
768
+ const tracer = trace.getTracer("autotel-edge");
769
+ const prepared = Reflect.apply(fnTarget, thisArg, args);
770
+ const preparedHandler = {
771
+ get(target2, prop2) {
772
+ const value2 = Reflect.get(target2, prop2);
773
+ if (prop2 === "first" || prop2 === "run" || prop2 === "all" || prop2 === "raw") {
774
+ return new Proxy(value2, {
775
+ apply: (fnTarget2, thisArg2, args2) => {
776
+ return tracer.startActiveSpan(
777
+ `D1 ${name}: ${prop2}`,
778
+ {
779
+ kind: SpanKind.CLIENT,
780
+ attributes: {
781
+ "db.system": "cloudflare-d1",
782
+ "db.operation": prop2,
783
+ "db.name": name,
784
+ "db.statement": query
785
+ }
786
+ },
787
+ async (span) => {
788
+ try {
789
+ const result = await Reflect.apply(fnTarget2, thisArg2, args2);
790
+ if (prop2 === "all" && Array.isArray(result)) {
791
+ span.setAttribute("db.result.rows_count", result.length);
792
+ } else if (prop2 === "first" && result) {
793
+ span.setAttribute("db.result.exists", true);
794
+ }
795
+ span.setStatus({ code: SpanStatusCode.OK });
796
+ return result;
797
+ } catch (error) {
798
+ span.recordException(error);
799
+ span.setStatus({
800
+ code: SpanStatusCode.ERROR,
801
+ message: error instanceof Error ? error.message : String(error)
802
+ });
803
+ throw error;
804
+ } finally {
805
+ span.end();
806
+ }
807
+ }
808
+ );
809
+ }
810
+ });
811
+ }
812
+ return value2;
813
+ }
814
+ };
815
+ return wrap(prepared, preparedHandler);
816
+ }
817
+ });
818
+ }
819
+ if (prop === "exec" && typeof value === "function") {
820
+ return new Proxy(value, {
821
+ apply: (fnTarget, thisArg, args) => {
822
+ const [query] = args;
823
+ const tracer = trace.getTracer("autotel-edge");
824
+ return tracer.startActiveSpan(
825
+ `D1 ${name}: exec`,
826
+ {
827
+ kind: SpanKind.CLIENT,
828
+ attributes: {
829
+ "db.system": "cloudflare-d1",
830
+ "db.operation": "exec",
831
+ "db.name": name,
832
+ "db.statement": query
833
+ }
834
+ },
835
+ async (span) => {
836
+ try {
837
+ const result = await Reflect.apply(fnTarget, thisArg, args);
838
+ span.setAttribute("db.result.count", result.count);
839
+ span.setStatus({ code: SpanStatusCode.OK });
840
+ return result;
841
+ } catch (error) {
842
+ span.recordException(error);
843
+ span.setStatus({
844
+ code: SpanStatusCode.ERROR,
845
+ message: error instanceof Error ? error.message : String(error)
846
+ });
847
+ throw error;
848
+ } finally {
849
+ span.end();
850
+ }
851
+ }
852
+ );
853
+ }
854
+ });
855
+ }
856
+ return value;
857
+ }
858
+ };
859
+ return wrap(d1, d1Handler);
860
+ }
861
+ function instrumentServiceBinding(fetcher, serviceName) {
862
+ const name = serviceName || "service";
863
+ const fetcherHandler = {
864
+ get(target, prop) {
865
+ const value = Reflect.get(target, prop);
866
+ if (prop === "fetch" && typeof value === "function") {
867
+ return new Proxy(value, {
868
+ apply: (fnTarget, thisArg, args) => {
869
+ const [input, init] = args;
870
+ const request = new Request(input, init);
871
+ const tracer = trace.getTracer("autotel-edge");
872
+ return tracer.startActiveSpan(
873
+ `Service ${name}: ${request.method}`,
874
+ {
875
+ kind: SpanKind.CLIENT,
876
+ attributes: {
877
+ "rpc.system": "cloudflare-service-binding",
878
+ "rpc.service": name,
879
+ "http.request.method": request.method,
880
+ "url.full": request.url
881
+ }
882
+ },
883
+ async (span) => {
884
+ try {
885
+ const response = await Reflect.apply(fnTarget, thisArg, args);
886
+ span.setAttribute("http.response.status_code", response.status);
887
+ span.setStatus({ code: SpanStatusCode.OK });
888
+ return response;
889
+ } catch (error) {
890
+ span.recordException(error);
891
+ span.setStatus({
892
+ code: SpanStatusCode.ERROR,
893
+ message: error instanceof Error ? error.message : String(error)
894
+ });
895
+ throw error;
896
+ } finally {
897
+ span.end();
898
+ }
899
+ }
900
+ );
901
+ }
902
+ });
903
+ }
904
+ return value;
905
+ }
906
+ };
907
+ return wrap(fetcher, fetcherHandler);
908
+ }
909
+ var hasMethod = (obj, m) => typeof obj?.[m] === "function";
910
+ var hasExactMethods = (obj, methods) => methods.every((m) => hasMethod(obj, m));
911
+ function instrumentBindings(env) {
912
+ const instrumented = {};
913
+ for (const [key, value] of Object.entries(env)) {
914
+ if (!value || typeof value !== "object") {
915
+ instrumented[key] = value;
916
+ continue;
917
+ }
918
+ if (isWrapped(value)) {
919
+ instrumented[key] = value;
920
+ continue;
921
+ }
922
+ if (hasExactMethods(value, ["get", "put", "delete", "list", "head"])) {
923
+ instrumented[key] = instrumentR2(value, key);
924
+ continue;
925
+ }
926
+ if (hasExactMethods(value, ["get", "put", "delete", "list"]) && !("head" in value)) {
927
+ instrumented[key] = instrumentKV(value, key);
928
+ continue;
929
+ }
930
+ if (hasExactMethods(value, ["prepare", "exec"])) {
931
+ instrumented[key] = instrumentD1(value, key);
932
+ continue;
933
+ }
934
+ if (hasExactMethods(value, ["query", "insert", "upsert", "describe"])) {
935
+ instrumented[key] = instrumentVectorize(value, key);
936
+ continue;
937
+ }
938
+ if (hasMethod(value, "run") && ("gateway" in value || "models" in value)) {
939
+ instrumented[key] = instrumentAI(value, key);
940
+ continue;
941
+ }
942
+ if (hasMethod(value, "connect") && "connectionString" in value && "host" in value) {
943
+ instrumented[key] = instrumentHyperdrive(value, key);
944
+ continue;
945
+ }
946
+ if (hasExactMethods(value, ["send", "sendBatch"]) && !("get" in value)) {
947
+ instrumented[key] = instrumentQueueProducer(value, key);
948
+ continue;
949
+ }
950
+ if (hasMethod(value, "writeDataPoint")) {
951
+ instrumented[key] = instrumentAnalyticsEngine(value, key);
952
+ continue;
953
+ }
954
+ if (hasExactMethods(value, ["info", "input"])) {
955
+ instrumented[key] = instrumentImages(value, key);
956
+ continue;
957
+ }
958
+ if (hasMethod(value, "fetch")) {
959
+ instrumented[key] = instrumentServiceBinding(value, key);
960
+ continue;
961
+ }
962
+ instrumented[key] = value;
963
+ }
964
+ return instrumented;
965
+ }
966
+ function instrumentRateLimiter(limiter, bindingName) {
967
+ const name = bindingName || "rate-limiter";
968
+ const handler = {
969
+ get(target, prop) {
970
+ const value = Reflect.get(target, prop);
971
+ if (prop === "limit" && typeof value === "function") {
972
+ return new Proxy(value, {
973
+ apply: (fnTarget, thisArg, args) => {
974
+ const [options] = args;
975
+ const tracer = trace.getTracer("autotel-edge");
976
+ return tracer.startActiveSpan(
977
+ `RateLimiter ${name}: limit`,
978
+ {
979
+ kind: SpanKind.CLIENT,
980
+ attributes: {
981
+ "rate_limiter.system": "cloudflare-rate-limiter",
982
+ "rate_limiter.key": options?.key
983
+ }
984
+ },
985
+ async (span) => {
986
+ try {
987
+ const result = await Reflect.apply(fnTarget, thisArg, args);
988
+ setAttr(span, "rate_limiter.success", result?.success);
989
+ span.setStatus({ code: SpanStatusCode.OK });
990
+ return result;
991
+ } catch (error) {
992
+ span.recordException(error);
993
+ span.setStatus({
994
+ code: SpanStatusCode.ERROR,
995
+ message: error instanceof Error ? error.message : String(error)
996
+ });
997
+ throw error;
998
+ } finally {
999
+ span.end();
1000
+ }
1001
+ }
1002
+ );
1003
+ }
1004
+ });
1005
+ }
1006
+ return value;
1007
+ }
1008
+ };
1009
+ return wrap(limiter, handler);
1010
+ }
1011
+ function instrumentBrowserRendering(browser, bindingName) {
1012
+ const name = bindingName || "browser";
1013
+ const handler = {
1014
+ get(target, prop) {
1015
+ const value = Reflect.get(target, prop);
1016
+ if (prop === "fetch" && typeof value === "function") {
1017
+ return new Proxy(value, {
1018
+ apply: (fnTarget, thisArg, args) => {
1019
+ const [input] = args;
1020
+ const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
1021
+ const tracer = trace.getTracer("autotel-edge");
1022
+ return tracer.startActiveSpan(
1023
+ `BrowserRendering ${name}: fetch`,
1024
+ {
1025
+ kind: SpanKind.CLIENT,
1026
+ attributes: {
1027
+ "browser.system": "cloudflare-browser-rendering",
1028
+ "url.full": url
1029
+ }
1030
+ },
1031
+ async (span) => {
1032
+ try {
1033
+ const result = await Reflect.apply(fnTarget, thisArg, args);
1034
+ setAttr(span, "http.response.status_code", result?.status);
1035
+ span.setStatus({ code: SpanStatusCode.OK });
1036
+ return result;
1037
+ } catch (error) {
1038
+ span.recordException(error);
1039
+ span.setStatus({
1040
+ code: SpanStatusCode.ERROR,
1041
+ message: error instanceof Error ? error.message : String(error)
1042
+ });
1043
+ throw error;
1044
+ } finally {
1045
+ span.end();
1046
+ }
1047
+ }
1048
+ );
1049
+ }
1050
+ });
1051
+ }
1052
+ return value;
1053
+ }
1054
+ };
1055
+ return wrap(browser, handler);
1056
+ }
1057
+
1058
+ export { instrumentAI, instrumentAnalyticsEngine, instrumentBindings, instrumentBrowserRendering, instrumentD1, instrumentHyperdrive, instrumentImages, instrumentKV, instrumentQueueProducer, instrumentR2, instrumentRateLimiter, instrumentServiceBinding, instrumentVectorize };
1059
+ //# sourceMappingURL=chunk-4UG2QCPQ.js.map
1060
+ //# sourceMappingURL=chunk-4UG2QCPQ.js.map