@opennextjs/cloudflare 0.0.0-9758666 → 0.0.0-9aff12e

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.
@@ -17,7 +17,7 @@ function existsSync(path: string) {
17
17
  return FILES.has(path);
18
18
  }
19
19
 
20
- async function readFile(path: string, options: unknown): Promise<any> {
20
+ async function readFile(path: string, options: unknown): Promise<unknown> {
21
21
  console.log(
22
22
  "readFile",
23
23
  { path, options }
@@ -1,55 +1,76 @@
1
- import Stream from "node:stream";
2
- import type { NextConfig } from "next";
3
- import { NodeNextRequest, NodeNextResponse } from "next/dist/server/base-http/node";
4
- import { MockedResponse } from "next/dist/server/lib/mock-request";
5
1
  import NextNodeServer, { NodeRequestHandler } from "next/dist/server/next-server";
2
+ import { NodeNextRequest, NodeNextResponse } from "next/dist/server/base-http/node";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
4
+ import { type CloudflareContext } from "../../api";
6
5
  import type { IncomingMessage } from "node:http";
6
+ import { MockedResponse } from "next/dist/server/lib/mock-request";
7
+ import type { NextConfig } from "next";
8
+ import Stream from "node:stream";
7
9
 
8
10
  const NON_BODY_RESPONSES = new Set([101, 204, 205, 304]);
9
11
 
12
+ const cloudflareContextALS = new AsyncLocalStorage<CloudflareContext>();
13
+
14
+ // Note: this symbol needs to be kept in sync with the one defined in `src/api/get-cloudflare-context.ts`
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ (globalThis as any)[Symbol.for("__cloudflare-context__")] = new Proxy(
17
+ {},
18
+ {
19
+ ownKeys: () => Reflect.ownKeys(cloudflareContextALS.getStore()!),
20
+ getOwnPropertyDescriptor: (_, ...args) =>
21
+ Reflect.getOwnPropertyDescriptor(cloudflareContextALS.getStore()!, ...args),
22
+ get: (_, property) => Reflect.get(cloudflareContextALS.getStore()!, property),
23
+ set: (_, property, value) => Reflect.set(cloudflareContextALS.getStore()!, property, value),
24
+ }
25
+ );
26
+
10
27
  // Injected at build time
11
28
  const nextConfig: NextConfig = JSON.parse(process.env.__NEXT_PRIVATE_STANDALONE_CONFIG ?? "{}");
12
29
 
13
30
  let requestHandler: NodeRequestHandler | null = null;
14
31
 
15
32
  export default {
16
- async fetch(request: Request, env: any, ctx: any) {
17
- if (requestHandler == null) {
18
- globalThis.process.env = { ...globalThis.process.env, ...env };
19
- requestHandler = new NextNodeServer({
20
- conf: { ...nextConfig, env },
21
- customServer: false,
22
- dev: false,
23
- dir: "",
24
- minimalMode: false,
25
- }).getRequestHandler();
26
- }
27
-
28
- const url = new URL(request.url);
29
-
30
- if (url.pathname === "/_next/image") {
31
- let imageUrl =
32
- url.searchParams.get("url") ?? "https://developers.cloudflare.com/_astro/logo.BU9hiExz.svg";
33
- if (imageUrl.startsWith("/")) {
34
- return env.ASSETS.fetch(new URL(imageUrl, request.url));
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ async fetch(request: Request & { cf: IncomingRequestCfProperties }, env: any, ctx: any) {
35
+ return cloudflareContextALS.run({ env, ctx, cf: request.cf }, async () => {
36
+ if (requestHandler == null) {
37
+ globalThis.process.env = { ...globalThis.process.env, ...env };
38
+ requestHandler = new NextNodeServer({
39
+ conf: { ...nextConfig, env },
40
+ customServer: false,
41
+ dev: false,
42
+ dir: "",
43
+ minimalMode: false,
44
+ }).getRequestHandler();
45
+ }
46
+
47
+ const url = new URL(request.url);
48
+
49
+ if (url.pathname === "/_next/image") {
50
+ const imageUrl =
51
+ url.searchParams.get("url") ?? "https://developers.cloudflare.com/_astro/logo.BU9hiExz.svg";
52
+ if (imageUrl.startsWith("/")) {
53
+ return env.ASSETS.fetch(new URL(imageUrl, request.url));
54
+ }
55
+ // @ts-ignore
56
+ return fetch(imageUrl, { cf: { cacheEverything: true } } as unknown);
35
57
  }
36
- return fetch(imageUrl, { cf: { cacheEverything: true } } as any);
37
- }
38
58
 
39
- const { req, res, webResponse } = getWrappedStreams(request, ctx);
59
+ const { req, res, webResponse } = getWrappedStreams(request, ctx);
40
60
 
41
- ctx.waitUntil(requestHandler(new NodeNextRequest(req), new NodeNextResponse(res)));
61
+ ctx.waitUntil(requestHandler(new NodeNextRequest(req), new NodeNextResponse(res)));
42
62
 
43
- return await webResponse();
63
+ return await webResponse();
64
+ });
44
65
  },
45
66
  };
46
67
 
47
- function getWrappedStreams(request: Request, ctx: any) {
68
+ function getWrappedStreams(request: Request, ctx: ExecutionContext) {
48
69
  const url = new URL(request.url);
49
70
 
50
- const req = (
51
- request.body ? Stream.Readable.fromWeb(request.body as any) : Stream.Readable.from([])
52
- ) as IncomingMessage;
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ const reqBody = request.body && Stream.Readable.fromWeb(request.body as any);
73
+ const req = (reqBody ?? Stream.Readable.from([])) as IncomingMessage;
53
74
  req.httpVersion = "1.0";
54
75
  req.httpVersionMajor = 1;
55
76
  req.httpVersionMinor = 0;
@@ -76,7 +97,7 @@ function getWrappedStreams(request: Request, ctx: any) {
76
97
 
77
98
  const res = new MockedResponse({
78
99
  resWriter: (chunk) => {
79
- resBodyWriter.write(typeof chunk === "string" ? Buffer.from(chunk) : chunk).catch((err: any) => {
100
+ resBodyWriter.write(typeof chunk === "string" ? Buffer.from(chunk) : chunk).catch((err) => {
80
101
  if (
81
102
  err.message.includes("WritableStream has been closed") ||
82
103
  err.message.includes("Network connection lost")
@@ -92,6 +113,7 @@ function getWrappedStreams(request: Request, ctx: any) {
92
113
  });
93
114
 
94
115
  // It's implemented as a no-op, but really it should mark the headers as done
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
117
  res.flushHeaders = () => (res as any).headPromiseResolve();
96
118
 
97
119
  // Only allow statusCode to be modified if not sent
@@ -109,6 +131,7 @@ function getWrappedStreams(request: Request, ctx: any) {
109
131
  });
110
132
 
111
133
  // Make sure the writer is eventually closed
134
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
135
  ctx.waitUntil((res as any).hasStreamed.finally(() => resBodyWriter.close().catch(() => {})));
113
136
 
114
137
  return {
@@ -120,6 +143,7 @@ function getWrappedStreams(request: Request, ctx: any) {
120
143
  res.setHeader("content-encoding", "identity");
121
144
  return new Response(NON_BODY_RESPONSES.has(res.statusCode) ? null : readable, {
122
145
  status: res.statusCode,
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
147
  headers: (res as any).headers,
124
148
  });
125
149
  },
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "@opennextjs/cloudflare",
3
3
  "description": "Cloudflare builder for next apps",
4
- "version": "0.0.0-9758666",
5
- "bin": "dist/index.mjs",
4
+ "version": "0.0.0-9aff12e",
5
+ "bin": "dist/cli/index.mjs",
6
+ "main": "./dist/api/index.mjs",
7
+ "types": "./dist/api/index.d.mts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/api/index.mjs",
11
+ "types": "./dist/api/index.d.mts"
12
+ }
13
+ },
6
14
  "files": [
7
15
  "README.md",
8
16
  "dist"
@@ -23,21 +31,32 @@
23
31
  },
24
32
  "homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
25
33
  "devDependencies": {
26
- "@cloudflare/workers-types": "^4.20240919.0",
34
+ "@cloudflare/workers-types": "^4.20240925.0",
35
+ "@eslint/js": "^9.11.1",
27
36
  "@types/node": "^22.2.0",
28
37
  "esbuild": "^0.23.0",
38
+ "eslint": "^9.11.1",
39
+ "eslint-plugin-unicorn": "^55.0.0",
29
40
  "glob": "^11.0.0",
41
+ "globals": "^15.9.0",
30
42
  "next": "14.2.11",
43
+ "package-manager-detector": "^0.2.0",
31
44
  "tsup": "^8.2.4",
32
45
  "typescript": "^5.5.4",
46
+ "typescript-eslint": "^8.7.0",
33
47
  "vitest": "^2.1.1"
34
48
  },
35
49
  "dependencies": {
36
50
  "ts-morph": "^23.0.0"
37
51
  },
52
+ "peerDependencies": {
53
+ "wrangler": "^3.78.10"
54
+ },
38
55
  "scripts": {
39
56
  "build": "tsup",
40
57
  "build:watch": "tsup --watch src",
58
+ "lint:check": "eslint",
59
+ "lint:fix": "eslint --fix",
41
60
  "test": "vitest --run",
42
61
  "test:watch": "vitest"
43
62
  }
File without changes