-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathinstrumentFetch.ts
More file actions
68 lines (59 loc) · 2.26 KB
/
instrumentFetch.ts
File metadata and controls
68 lines (59 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import type { ExportedHandler } from '@cloudflare/workers-types';
import type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';
import type { CloudflareOptions } from '../../client';
import { ensureInstrumented } from '../../instrument';
import { getFinalOptions } from '../../options';
import { wrapRequestHandler } from '../../request';
import { instrumentContext } from '../../utils/instrumentContext';
import { instrumentEnv } from './instrumentEnv';
/**
* Instruments a fetch handler for ExportedHandler (env/ctx come from args).
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function instrumentExportedHandlerFetch<T extends ExportedHandler<any, any, any>>(
handler: T,
optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,
): void {
if (!('fetch' in handler) || typeof handler.fetch !== 'function') {
return;
}
handler.fetch = ensureInstrumented(
handler.fetch,
original =>
new Proxy(original, {
apply(target, thisArg, args: Parameters<NonNullable<T['fetch']>>) {
const [request, env, ctx] = args;
if (request.method === 'OPTIONS' || request.method === 'HEAD') {
return target.apply(thisArg, args);
}
const context = instrumentContext(ctx);
const options = getFinalOptions(optionsCallback(env), env);
args[1] = instrumentEnv(env, options);
args[2] = context;
return wrapRequestHandler({ options, request, context }, () => target.apply(thisArg, args));
},
}),
);
}
/**
* Instruments a fetch method for WorkerEntrypoint (options/context already available).
*/
export function instrumentWorkerEntrypointFetch<T extends WorkerEntrypoint>(
instance: T,
options: CloudflareOptions,
context: ExecutionContext,
): void {
if (!instance.fetch) {
return;
}
const original = instance.fetch.bind(instance);
instance.fetch = new Proxy(original, {
apply(target, thisArg, args: [Request]) {
const [request] = args;
if (request.method === 'OPTIONS' || request.method === 'HEAD') {
return Reflect.apply(target, thisArg, args);
}
return wrapRequestHandler({ options, request, context }, () => Reflect.apply(target, thisArg, args));
},
});
}