@@ -29,25 +29,55 @@ const cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
29
29
/**
30
30
* Utility to get the current Cloudflare context
31
31
*
32
- * Throws an error if the context could not be retrieved
33
- *
34
32
* @returns the cloudflare context
35
33
*/
36
34
export async function getCloudflareContext <
37
35
CfProperties extends Record < string , unknown > = IncomingRequestCfProperties ,
38
36
Context = ExecutionContext ,
39
37
> ( ) : Promise < CloudflareContext < CfProperties , Context > > {
40
- const cloudflareContext = (
41
- globalThis as unknown as {
42
- [ cloudflareContextSymbol ] : CloudflareContext < CfProperties , Context > | undefined ;
43
- }
44
- ) [ cloudflareContextSymbol ] ;
38
+ const global = globalThis as unknown as {
39
+ [ cloudflareContextSymbol ] : CloudflareContext < CfProperties , Context > | undefined ;
40
+ } ;
41
+
42
+ const cloudflareContext = global [ cloudflareContextSymbol ] ;
45
43
46
44
if ( ! cloudflareContext ) {
47
- // TODO: cloudflareContext should always be present in production/preview, if not it means that this
48
- // is running under `next dev`, in this case use `getPlatformProxy` to return local proxies
49
- throw new Error ( "Cloudflare context is not defined!" ) ;
45
+ // the cloudflare context is initialized by the worker and is always present in production/preview,
46
+ // so, it not being present means that the application is running under `next dev`
47
+ return getCloudflareContextInNextDev ( ) ;
50
48
}
51
49
52
50
return cloudflareContext ;
53
51
}
52
+
53
+ const cloudflareContextInNextDevSymbol = Symbol . for ( "__next-dev/cloudflare-context__" ) ;
54
+
55
+ /**
56
+ * Gets a local proxy version of the cloudflare context (created using `getPlatformProxy`) when
57
+ * running in the standard next dev server (via `next dev`)
58
+ *
59
+ * @returns the local proxy version of the cloudflare context
60
+ */
61
+ async function getCloudflareContextInNextDev <
62
+ CfProperties extends Record < string , unknown > = IncomingRequestCfProperties ,
63
+ Context = ExecutionContext ,
64
+ > ( ) : Promise < CloudflareContext < CfProperties , Context > > {
65
+ const global = globalThis as unknown as {
66
+ [ cloudflareContextInNextDevSymbol ] : CloudflareContext < CfProperties , Context > | undefined ;
67
+ } ;
68
+
69
+ if ( ! global [ cloudflareContextInNextDevSymbol ] ) {
70
+ // Note: we never want wrangler to be bundled in the Next.js app, that's why the import below looks like it does
71
+ const { getPlatformProxy } = await import (
72
+ /* webpackIgnore: true */ `${ "__wrangler" . replaceAll ( "_" , "" ) } `
73
+ ) ;
74
+ const { env, cf, ctx } = await getPlatformProxy ( ) ;
75
+ global [ cloudflareContextInNextDevSymbol ] = {
76
+ env,
77
+ cf : cf as unknown as CfProperties ,
78
+ ctx : ctx as Context ,
79
+ } ;
80
+ }
81
+
82
+ return global [ cloudflareContextInNextDevSymbol ] ! ;
83
+ }
0 commit comments