autotel-cloudflare 3.0.0 → 4.0.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 (73) hide show
  1. package/dist/agents.d.ts +626 -123
  2. package/dist/agents.d.ts.map +1 -1
  3. package/dist/agents.js +260 -171
  4. package/dist/agents.js.map +1 -1
  5. package/package.json +8 -4
  6. package/src/actors/alarms.ts +0 -225
  7. package/src/actors/index.ts +0 -36
  8. package/src/actors/instrument-actor.test.ts +0 -179
  9. package/src/actors/instrument-actor.ts +0 -574
  10. package/src/actors/sockets.ts +0 -217
  11. package/src/actors/storage.ts +0 -263
  12. package/src/actors/traced-handler.ts +0 -300
  13. package/src/actors/types.ts +0 -98
  14. package/src/actors.ts +0 -50
  15. package/src/agents/index.ts +0 -42
  16. package/src/agents/otel-observability.test.ts +0 -336
  17. package/src/agents/otel-observability.ts +0 -474
  18. package/src/agents/types.ts +0 -167
  19. package/src/agents.ts +0 -76
  20. package/src/bindings/ai.test.ts +0 -170
  21. package/src/bindings/ai.ts +0 -73
  22. package/src/bindings/analytics-engine.test.ts +0 -175
  23. package/src/bindings/analytics-engine.ts +0 -78
  24. package/src/bindings/bindings-cache.test.ts +0 -80
  25. package/src/bindings/bindings-detection.test.ts +0 -235
  26. package/src/bindings/bindings-this-binding.test.ts +0 -294
  27. package/src/bindings/bindings.ts +0 -720
  28. package/src/bindings/browser-rendering.test.ts +0 -160
  29. package/src/bindings/browser-rendering.ts +0 -70
  30. package/src/bindings/common.ts +0 -84
  31. package/src/bindings/hyperdrive.test.ts +0 -176
  32. package/src/bindings/hyperdrive.ts +0 -74
  33. package/src/bindings/images.test.ts +0 -262
  34. package/src/bindings/images.ts +0 -182
  35. package/src/bindings/index.ts +0 -20
  36. package/src/bindings/queue-producer.test.ts +0 -224
  37. package/src/bindings/queue-producer.ts +0 -105
  38. package/src/bindings/rate-limiter.test.ts +0 -140
  39. package/src/bindings/rate-limiter.ts +0 -69
  40. package/src/bindings/vectorize.test.ts +0 -362
  41. package/src/bindings/vectorize.ts +0 -86
  42. package/src/bindings.ts +0 -6
  43. package/src/events.ts +0 -6
  44. package/src/execution-logger.test.ts +0 -127
  45. package/src/execution-logger.ts +0 -112
  46. package/src/global/cache.test.ts +0 -292
  47. package/src/global/cache.ts +0 -164
  48. package/src/global/fetch.test.ts +0 -399
  49. package/src/global/fetch.ts +0 -136
  50. package/src/global/index.ts +0 -7
  51. package/src/handlers/durable-objects.test.ts +0 -524
  52. package/src/handlers/durable-objects.ts +0 -250
  53. package/src/handlers/index.ts +0 -6
  54. package/src/handlers/workflows.test.ts +0 -411
  55. package/src/handlers/workflows.ts +0 -345
  56. package/src/handlers.ts +0 -6
  57. package/src/index.ts +0 -91
  58. package/src/logger.ts +0 -15
  59. package/src/native/native-tracing.test.ts +0 -54
  60. package/src/native/native-tracing.ts +0 -83
  61. package/src/native.ts +0 -12
  62. package/src/parse-error.ts +0 -1
  63. package/src/sampling.ts +0 -6
  64. package/src/testing.ts +0 -6
  65. package/src/wrappers/cf-attributes.test.ts +0 -334
  66. package/src/wrappers/define-worker-fetch.test.ts +0 -102
  67. package/src/wrappers/define-worker-fetch.ts +0 -71
  68. package/src/wrappers/index.ts +0 -13
  69. package/src/wrappers/instrument.integration.test.ts +0 -578
  70. package/src/wrappers/instrument.ts +0 -806
  71. package/src/wrappers/native-instrument.test.ts +0 -153
  72. package/src/wrappers/wrap-do.ts +0 -34
  73. package/src/wrappers/wrap-module.ts +0 -37
@@ -1,235 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
- import { trace, SpanStatusCode, SpanKind } from '@opentelemetry/api';
3
- import { instrumentBindings } from './bindings';
4
- import { isWrapped, wrap } from './common';
5
-
6
- describe('instrumentBindings() detection logic', () => {
7
- let mockTracer: any;
8
- let mockSpan: any;
9
- let getTracerSpy: any;
10
-
11
- beforeEach(() => {
12
- mockSpan = {
13
- spanContext: () => ({
14
- traceId: 'test-trace-id',
15
- spanId: 'test-span-id',
16
- traceFlags: 1,
17
- }),
18
- setAttribute: vi.fn(),
19
- setAttributes: vi.fn(),
20
- setStatus: vi.fn(),
21
- recordException: vi.fn(),
22
- end: vi.fn(),
23
- isRecording: () => true,
24
- updateName: vi.fn(),
25
- addEvent: vi.fn(),
26
- };
27
-
28
- mockTracer = {
29
- startActiveSpan: vi.fn((name, options, fn) => {
30
- return fn(mockSpan);
31
- }),
32
- };
33
-
34
- getTracerSpy = vi.spyOn(trace, 'getTracer').mockReturnValue(mockTracer as any);
35
- });
36
-
37
- afterEach(() => {
38
- getTracerSpy.mockRestore();
39
- });
40
-
41
- it('should detect R2 (object with get, put, delete, list, head methods)', () => {
42
- const mockR2 = {
43
- get: vi.fn(),
44
- put: vi.fn(),
45
- delete: vi.fn(),
46
- list: vi.fn(),
47
- head: vi.fn(),
48
- };
49
-
50
- const result = instrumentBindings({ MY_R2: mockR2 });
51
-
52
- expect(result.MY_R2).not.toBe(mockR2);
53
- expect(isWrapped(result.MY_R2)).toBe(true);
54
- });
55
-
56
- it('should detect KV (object with get, put, delete, list but NOT head)', () => {
57
- const mockKV = {
58
- get: vi.fn(),
59
- put: vi.fn(),
60
- delete: vi.fn(),
61
- list: vi.fn(),
62
- };
63
-
64
- const result = instrumentBindings({ MY_KV: mockKV });
65
-
66
- expect(result.MY_KV).not.toBe(mockKV);
67
- expect(isWrapped(result.MY_KV)).toBe(true);
68
- });
69
-
70
- it('should detect D1 (object with prepare, exec methods)', () => {
71
- const mockD1 = {
72
- prepare: vi.fn(),
73
- exec: vi.fn(),
74
- };
75
-
76
- const result = instrumentBindings({ MY_DB: mockD1 });
77
-
78
- expect(result.MY_DB).not.toBe(mockD1);
79
- expect(isWrapped(result.MY_DB)).toBe(true);
80
- });
81
-
82
- it('should detect Vectorize (object with query, insert, upsert, describe methods)', () => {
83
- const mockVectorize = {
84
- query: vi.fn(),
85
- insert: vi.fn(),
86
- upsert: vi.fn(),
87
- describe: vi.fn(),
88
- };
89
-
90
- const result = instrumentBindings({ MY_INDEX: mockVectorize });
91
-
92
- expect(result.MY_INDEX).not.toBe(mockVectorize);
93
- expect(isWrapped(result.MY_INDEX)).toBe(true);
94
- });
95
-
96
- it('should detect AI (object with run method AND gateway property)', () => {
97
- const mockAI = {
98
- run: vi.fn(),
99
- gateway: {},
100
- };
101
-
102
- const result = instrumentBindings({ AI: mockAI });
103
-
104
- expect(result.AI).not.toBe(mockAI);
105
- expect(isWrapped(result.AI)).toBe(true);
106
- });
107
-
108
- it('should detect Hyperdrive (object with connect method AND connectionString, host properties)', () => {
109
- const mockHyperdrive = {
110
- connect: vi.fn(),
111
- connectionString: 'postgresql://user:pass@host:5432/db',
112
- host: 'db.example.com',
113
- port: 5432,
114
- user: 'user',
115
- password: 'pass',
116
- database: 'db',
117
- };
118
-
119
- const result = instrumentBindings({ HYPERDRIVE: mockHyperdrive });
120
-
121
- expect(result.HYPERDRIVE).not.toBe(mockHyperdrive);
122
- expect(isWrapped(result.HYPERDRIVE)).toBe(true);
123
- });
124
-
125
- it('should detect Queue Producer (object with send, sendBatch but NOT get)', () => {
126
- const mockQueue = {
127
- send: vi.fn(),
128
- sendBatch: vi.fn(),
129
- };
130
-
131
- const result = instrumentBindings({ MY_QUEUE: mockQueue });
132
-
133
- expect(result.MY_QUEUE).not.toBe(mockQueue);
134
- expect(isWrapped(result.MY_QUEUE)).toBe(true);
135
- });
136
-
137
- it('should detect Analytics Engine (object with writeDataPoint method)', () => {
138
- const mockAE = {
139
- writeDataPoint: vi.fn(),
140
- };
141
-
142
- const result = instrumentBindings({ ANALYTICS: mockAE });
143
-
144
- expect(result.ANALYTICS).not.toBe(mockAE);
145
- expect(isWrapped(result.ANALYTICS)).toBe(true);
146
- });
147
-
148
- it('should detect Images (object with info, input methods)', () => {
149
- const mockImages = {
150
- info: vi.fn(),
151
- input: vi.fn(),
152
- };
153
-
154
- const result = instrumentBindings({ IMAGES: mockImages });
155
-
156
- expect(result.IMAGES).not.toBe(mockImages);
157
- expect(isWrapped(result.IMAGES)).toBe(true);
158
- });
159
-
160
- it('should detect Service Binding (object with fetch method) - last', () => {
161
- const mockService = {
162
- fetch: vi.fn(),
163
- };
164
-
165
- const result = instrumentBindings({ MY_SERVICE: mockService });
166
-
167
- expect(result.MY_SERVICE).not.toBe(mockService);
168
- expect(isWrapped(result.MY_SERVICE)).toBe(true);
169
- });
170
-
171
- it('should detect R2 before KV (object with head gets R2, without head gets KV)', () => {
172
- const withHead = {
173
- get: vi.fn(),
174
- put: vi.fn(),
175
- delete: vi.fn(),
176
- list: vi.fn(),
177
- head: vi.fn(),
178
- };
179
- const withoutHead = {
180
- get: vi.fn(),
181
- put: vi.fn(),
182
- delete: vi.fn(),
183
- list: vi.fn(),
184
- };
185
-
186
- const result = instrumentBindings({
187
- R2_BUCKET: withHead,
188
- KV_STORE: withoutHead,
189
- });
190
-
191
- // Both should be wrapped but detected as different types
192
- expect(isWrapped(result.R2_BUCKET)).toBe(true);
193
- expect(isWrapped(result.KV_STORE)).toBe(true);
194
- expect(result.R2_BUCKET).not.toBe(withHead);
195
- expect(result.KV_STORE).not.toBe(withoutHead);
196
- });
197
-
198
- it('should skip already-wrapped bindings', () => {
199
- const mockKV = {
200
- get: vi.fn(),
201
- put: vi.fn(),
202
- delete: vi.fn(),
203
- list: vi.fn(),
204
- };
205
-
206
- // Pre-wrap the binding using the wrap helper
207
- const preWrapped = wrap(mockKV, {
208
- get(target, prop) {
209
- return Reflect.get(target, prop);
210
- },
211
- });
212
-
213
- const result = instrumentBindings({ MY_KV: preWrapped });
214
-
215
- // Should be the same already-wrapped object, not double-wrapped
216
- expect(result.MY_KV).toBe(preWrapped);
217
- expect(isWrapped(result.MY_KV)).toBe(true);
218
- });
219
-
220
- it('should pass through non-object values (strings, numbers)', () => {
221
- const result = instrumentBindings({
222
- API_KEY: 'my-secret-key',
223
- TIMEOUT: 5000,
224
- ENABLED: true,
225
- EMPTY: null,
226
- UNDEF: undefined,
227
- });
228
-
229
- expect(result.API_KEY).toBe('my-secret-key');
230
- expect(result.TIMEOUT).toBe(5000);
231
- expect(result.ENABLED).toBe(true);
232
- expect(result.EMPTY).toBe(null);
233
- expect(result.UNDEF).toBe(undefined);
234
- });
235
- });
@@ -1,294 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
- import { trace, SpanStatusCode, SpanKind } from '@opentelemetry/api';
3
- import { instrumentKV, instrumentR2, instrumentD1, instrumentServiceBinding } from './bindings';
4
-
5
- describe('Bindings this-binding tests', () => {
6
- let mockTracer: any;
7
- let mockSpan: any;
8
- let getTracerSpy: any;
9
-
10
- beforeEach(() => {
11
- mockSpan = {
12
- spanContext: () => ({
13
- traceId: 'test-trace-id',
14
- spanId: 'test-span-id',
15
- traceFlags: 1,
16
- }),
17
- setAttribute: vi.fn(),
18
- setAttributes: vi.fn(),
19
- setStatus: vi.fn(),
20
- recordException: vi.fn(),
21
- end: vi.fn(),
22
- isRecording: () => true,
23
- updateName: vi.fn(),
24
- addEvent: vi.fn(),
25
- };
26
-
27
- mockTracer = {
28
- startActiveSpan: vi.fn((name, options, fn) => {
29
- return fn(mockSpan);
30
- }),
31
- };
32
-
33
- getTracerSpy = vi.spyOn(trace, 'getTracer').mockReturnValue(mockTracer as any);
34
- });
35
-
36
- afterEach(() => {
37
- getTracerSpy.mockRestore();
38
- });
39
-
40
- describe('KV this-binding', () => {
41
- it('should invoke get() with original object as this, not the proxy', async () => {
42
- let receivedThis: any;
43
- const mockKV = {
44
- get: vi.fn(async function(this: any) {
45
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
46
- receivedThis = this;
47
- return 'value';
48
- }),
49
- put: vi.fn(async () => undefined),
50
- delete: vi.fn(async () => undefined),
51
- list: vi.fn(async () => ({ keys: [], list_complete: true, cacheStatus: null })),
52
- } as unknown as KVNamespace;
53
- const instrumented = instrumentKV(mockKV, 'test');
54
- await instrumented.get('key');
55
- expect(receivedThis).toBe(mockKV);
56
- });
57
-
58
- it('should invoke put() with original object as this, not the proxy', async () => {
59
- let receivedThis: any;
60
- const mockKV = {
61
- get: vi.fn(async () => null),
62
- put: vi.fn(async function(this: any) {
63
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
64
- receivedThis = this;
65
- }),
66
- delete: vi.fn(async () => undefined),
67
- list: vi.fn(async () => ({ keys: [], list_complete: true, cacheStatus: null })),
68
- } as unknown as KVNamespace;
69
- const instrumented = instrumentKV(mockKV, 'test');
70
- await instrumented.put('key', 'value');
71
- expect(receivedThis).toBe(mockKV);
72
- });
73
-
74
- it('should invoke delete() with original object as this, not the proxy', async () => {
75
- let receivedThis: any;
76
- const mockKV = {
77
- get: vi.fn(async () => null),
78
- put: vi.fn(async () => undefined),
79
- delete: vi.fn(async function(this: any) {
80
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
81
- receivedThis = this;
82
- }),
83
- list: vi.fn(async () => ({ keys: [], list_complete: true, cacheStatus: null })),
84
- } as unknown as KVNamespace;
85
- const instrumented = instrumentKV(mockKV, 'test');
86
- await instrumented.delete('key');
87
- expect(receivedThis).toBe(mockKV);
88
- });
89
-
90
- it('should invoke list() with original object as this, not the proxy', async () => {
91
- let receivedThis: any;
92
- const mockKV = {
93
- get: vi.fn(async () => null),
94
- put: vi.fn(async () => undefined),
95
- delete: vi.fn(async () => undefined),
96
- list: vi.fn(async function(this: any) {
97
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
98
- receivedThis = this;
99
- return { keys: [], list_complete: true, cacheStatus: null };
100
- }),
101
- } as unknown as KVNamespace;
102
- const instrumented = instrumentKV(mockKV, 'test');
103
- await instrumented.list();
104
- expect(receivedThis).toBe(mockKV);
105
- });
106
- });
107
-
108
- describe('R2 this-binding', () => {
109
- it('should invoke get() with original object as this, not the proxy', async () => {
110
- let receivedThis: any;
111
- const mockR2 = {
112
- get: vi.fn(async function(this: any) {
113
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
114
- receivedThis = this;
115
- return { size: 100, etag: 'abc', httpMetadata: {} };
116
- }),
117
- put: vi.fn(async () => ({ etag: 'abc', uploaded: new Date() })),
118
- delete: vi.fn(async () => undefined),
119
- list: vi.fn(async () => ({ objects: [], truncated: false })),
120
- head: vi.fn(async () => null),
121
- } as unknown as R2Bucket;
122
- const instrumented = instrumentR2(mockR2, 'test');
123
- await instrumented.get('key');
124
- expect(receivedThis).toBe(mockR2);
125
- });
126
-
127
- it('should invoke put() with original object as this, not the proxy', async () => {
128
- let receivedThis: any;
129
- const mockR2 = {
130
- get: vi.fn(async () => null),
131
- put: vi.fn(async function(this: any) {
132
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
133
- receivedThis = this;
134
- return { etag: 'abc', uploaded: new Date() };
135
- }),
136
- delete: vi.fn(async () => undefined),
137
- list: vi.fn(async () => ({ objects: [], truncated: false })),
138
- head: vi.fn(async () => null),
139
- } as unknown as R2Bucket;
140
- const instrumented = instrumentR2(mockR2, 'test');
141
- await instrumented.put('key', 'value');
142
- expect(receivedThis).toBe(mockR2);
143
- });
144
-
145
- it('should invoke delete() with original object as this, not the proxy', async () => {
146
- let receivedThis: any;
147
- const mockR2 = {
148
- get: vi.fn(async () => null),
149
- put: vi.fn(async () => ({ etag: 'abc', uploaded: new Date() })),
150
- delete: vi.fn(async function(this: any) {
151
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
152
- receivedThis = this;
153
- }),
154
- list: vi.fn(async () => ({ objects: [], truncated: false })),
155
- head: vi.fn(async () => null),
156
- } as unknown as R2Bucket;
157
- const instrumented = instrumentR2(mockR2, 'test');
158
- await instrumented.delete('key');
159
- expect(receivedThis).toBe(mockR2);
160
- });
161
-
162
- it('should invoke list() with original object as this, not the proxy', async () => {
163
- let receivedThis: any;
164
- const mockR2 = {
165
- get: vi.fn(async () => null),
166
- put: vi.fn(async () => ({ etag: 'abc', uploaded: new Date() })),
167
- delete: vi.fn(async () => undefined),
168
- list: vi.fn(async function(this: any) {
169
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
170
- receivedThis = this;
171
- return { objects: [], truncated: false };
172
- }),
173
- head: vi.fn(async () => null),
174
- } as unknown as R2Bucket;
175
- const instrumented = instrumentR2(mockR2, 'test');
176
- await instrumented.list();
177
- expect(receivedThis).toBe(mockR2);
178
- });
179
- });
180
-
181
- describe('D1 this-binding', () => {
182
- it('should invoke prepare() with original object as this, not the proxy', () => {
183
- let receivedThis: any;
184
- const mockPrepared = {
185
- first: vi.fn(async () => null),
186
- run: vi.fn(async () => ({})),
187
- all: vi.fn(async () => []),
188
- raw: vi.fn(async () => []),
189
- bind: vi.fn(function() { return mockPrepared; }),
190
- };
191
- const mockD1 = {
192
- prepare: vi.fn(function(this: any) {
193
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
194
- receivedThis = this;
195
- return mockPrepared;
196
- }),
197
- exec: vi.fn(async () => ({ count: 0 })),
198
- } as unknown as D1Database;
199
- const instrumented = instrumentD1(mockD1, 'test');
200
- instrumented.prepare('SELECT 1');
201
- expect(receivedThis).toBe(mockD1);
202
- });
203
-
204
- it('should invoke prepared statement methods with original prepared object as this, not the proxy', async () => {
205
- let receivedThis: any;
206
- const mockPrepared = {
207
- first: vi.fn(async function(this: any) {
208
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
209
- receivedThis = this;
210
- return { id: 1 };
211
- }),
212
- run: vi.fn(async () => ({})),
213
- all: vi.fn(async () => []),
214
- raw: vi.fn(async () => []),
215
- bind: vi.fn(function() { return mockPrepared; }),
216
- };
217
- const mockD1 = {
218
- prepare: vi.fn(() => mockPrepared),
219
- exec: vi.fn(async () => ({ count: 0 })),
220
- } as unknown as D1Database;
221
- const instrumented = instrumentD1(mockD1, 'test');
222
- const stmt = instrumented.prepare('SELECT * FROM users WHERE id = ?');
223
- await stmt.first();
224
- expect(receivedThis).toBe(mockPrepared);
225
- });
226
-
227
- it('should invoke exec() with original object as this, not the proxy', async () => {
228
- let receivedThis: any;
229
- const mockD1 = {
230
- prepare: vi.fn(() => ({ first: vi.fn(), run: vi.fn(), all: vi.fn(), raw: vi.fn() })),
231
- exec: vi.fn(async function(this: any) {
232
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
233
- receivedThis = this;
234
- return { count: 1 };
235
- }),
236
- } as unknown as D1Database;
237
- const instrumented = instrumentD1(mockD1, 'test');
238
- await instrumented.exec('CREATE TABLE test (id INTEGER PRIMARY KEY)');
239
- expect(receivedThis).toBe(mockD1);
240
- });
241
- });
242
-
243
- describe('Service Binding this-binding', () => {
244
- it('should invoke fetch() with original object as this, not the proxy', async () => {
245
- let receivedThis: any;
246
- const mockFetcher = {
247
- fetch: vi.fn(async function(this: any) {
248
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
249
- receivedThis = this;
250
- return new Response('ok', { status: 200 });
251
- }),
252
- } as unknown as Fetcher;
253
- const instrumented = instrumentServiceBinding(mockFetcher, 'test');
254
- await instrumented.fetch('https://example.com');
255
- expect(receivedThis).toBe(mockFetcher);
256
- });
257
-
258
- it('should not throw "Illegal invocation" for native-like bindings that check this', async () => {
259
- // Simulate a native Cloudflare Fetcher that throws when `this` is wrong.
260
- // Native bindings use C++ checks that reject proxied `this` references.
261
- class NativeFetcher {
262
- async fetch(input: RequestInfo | URL, _init?: RequestInit): Promise<Response> {
263
- // Native bindings validate `this` — throw if it's not the exact instance
264
- if (!(this instanceof NativeFetcher)) {
265
- throw new TypeError('Illegal invocation: function called with incorrect `this` reference');
266
- }
267
- return new Response('ok', { status: 200 });
268
- }
269
- }
270
-
271
- const nativeFetcher = new NativeFetcher() as unknown as Fetcher;
272
- const instrumented = instrumentServiceBinding(nativeFetcher, 'native-service');
273
-
274
- // This should NOT throw — the fix ensures fetch() is called on the
275
- // original target, preserving the native `this` binding
276
- await expect(instrumented.fetch('https://example.com')).resolves.toBeInstanceOf(Response);
277
- });
278
-
279
- it('should bind non-fetch methods to the original target', () => {
280
- let receivedThis: any;
281
- const mockFetcher = {
282
- fetch: vi.fn(async () => new Response('ok', { status: 200 })),
283
- connect: vi.fn(function(this: any) {
284
- // eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias
285
- receivedThis = this;
286
- return {};
287
- }),
288
- } as unknown as Fetcher;
289
- const instrumented = instrumentServiceBinding(mockFetcher, 'test');
290
- (instrumented as any).connect('https://example.com');
291
- expect(receivedThis).toBe(mockFetcher);
292
- });
293
- });
294
- });