@opennextjs/cloudflare 0.0.0-88fe982 → 0.0.0-953d0b1
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.
- package/README.md +60 -13
- package/dist/api/chunk-VTBEIZPQ.mjs +32 -0
- package/dist/api/get-cloudflare-context.d.mts +26 -0
- package/dist/api/get-cloudflare-context.mjs +6 -0
- package/dist/api/index.d.mts +1 -0
- package/dist/api/index.mjs +6 -0
- package/dist/cli/cache-handler.mjs +48 -0
- package/dist/cli/chunk-UJCSKKID.mjs +30 -0
- package/dist/{index.mjs → cli/index.mjs} +353 -330
- package/dist/{templates → cli/templates}/shims/node-fs.ts +1 -1
- package/dist/{templates → cli/templates}/worker.ts +57 -34
- package/package.json +26 -6
- /package/dist/{templates → cli/templates}/shims/empty.ts +0 -0
- /package/dist/{templates → cli/templates}/shims/env.ts +0 -0
- /package/dist/{templates → cli/templates}/shims/throw.ts +0 -0
|
@@ -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<
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
requestHandler
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
59
|
+
const { req, res, webResponse } = getWrappedStreams(request, ctx);
|
|
40
60
|
|
|
41
|
-
|
|
61
|
+
ctx.waitUntil(requestHandler(new NodeNextRequest(req), new NodeNextResponse(res)));
|
|
42
62
|
|
|
43
|
-
|
|
63
|
+
return await webResponse();
|
|
64
|
+
});
|
|
44
65
|
},
|
|
45
66
|
};
|
|
46
67
|
|
|
47
|
-
function getWrappedStreams(request: Request, ctx:
|
|
68
|
+
function getWrappedStreams(request: Request, ctx: ExecutionContext) {
|
|
48
69
|
const url = new URL(request.url);
|
|
49
70
|
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
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
|
|
@@ -102,7 +124,6 @@ function getWrappedStreams(request: Request, ctx: any) {
|
|
|
102
124
|
},
|
|
103
125
|
set: function (val) {
|
|
104
126
|
if (this.finished || this.headersSent) {
|
|
105
|
-
console.error("headers already sent");
|
|
106
127
|
return;
|
|
107
128
|
}
|
|
108
129
|
statusCode = val;
|
|
@@ -110,6 +131,7 @@ function getWrappedStreams(request: Request, ctx: any) {
|
|
|
110
131
|
});
|
|
111
132
|
|
|
112
133
|
// Make sure the writer is eventually closed
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
135
|
ctx.waitUntil((res as any).hasStreamed.finally(() => resBodyWriter.close().catch(() => {})));
|
|
114
136
|
|
|
115
137
|
return {
|
|
@@ -121,6 +143,7 @@ function getWrappedStreams(request: Request, ctx: any) {
|
|
|
121
143
|
res.setHeader("content-encoding", "identity");
|
|
122
144
|
return new Response(NON_BODY_RESPONSES.has(res.statusCode) ? null : readable, {
|
|
123
145
|
status: res.statusCode,
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
147
|
headers: (res as any).headers,
|
|
125
148
|
});
|
|
126
149
|
},
|
package/package.json
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennextjs/cloudflare",
|
|
3
3
|
"description": "Cloudflare builder for next apps",
|
|
4
|
-
"version": "0.0.0-
|
|
5
|
-
"bin": "dist/index.mjs",
|
|
4
|
+
"version": "0.0.0-953d0b1",
|
|
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"
|
|
9
17
|
],
|
|
10
18
|
"repository": {
|
|
11
19
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/
|
|
13
|
-
"directory": "
|
|
20
|
+
"url": "https://github.com/opennextjs/opennextjs-cloudflare.git",
|
|
21
|
+
"directory": "packages/cloudflare"
|
|
14
22
|
},
|
|
15
23
|
"keywords": [
|
|
16
24
|
"cloudflare",
|
|
@@ -19,23 +27,35 @@
|
|
|
19
27
|
],
|
|
20
28
|
"license": "MIT",
|
|
21
29
|
"bugs": {
|
|
22
|
-
"url": "https://github.com/
|
|
30
|
+
"url": "https://github.com/opennextjs/opennextjs-cloudflare/issues"
|
|
23
31
|
},
|
|
24
|
-
"homepage": "https://github.com/
|
|
32
|
+
"homepage": "https://github.com/opennextjs/opennextjs-cloudflare",
|
|
25
33
|
"devDependencies": {
|
|
34
|
+
"@cloudflare/workers-types": "^4.20240925.0",
|
|
35
|
+
"@eslint/js": "^9.11.1",
|
|
26
36
|
"@types/node": "^22.2.0",
|
|
27
37
|
"esbuild": "^0.23.0",
|
|
38
|
+
"eslint": "^9.11.1",
|
|
39
|
+
"eslint-plugin-unicorn": "^55.0.0",
|
|
28
40
|
"glob": "^11.0.0",
|
|
41
|
+
"globals": "^15.9.0",
|
|
42
|
+
"next": "14.2.11",
|
|
29
43
|
"tsup": "^8.2.4",
|
|
30
44
|
"typescript": "^5.5.4",
|
|
45
|
+
"typescript-eslint": "^8.7.0",
|
|
31
46
|
"vitest": "^2.1.1"
|
|
32
47
|
},
|
|
33
48
|
"dependencies": {
|
|
34
49
|
"ts-morph": "^23.0.0"
|
|
35
50
|
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"wrangler": "^3.78.10"
|
|
53
|
+
},
|
|
36
54
|
"scripts": {
|
|
37
55
|
"build": "tsup",
|
|
38
56
|
"build:watch": "tsup --watch src",
|
|
57
|
+
"lint:check": "eslint",
|
|
58
|
+
"lint:fix": "eslint --fix",
|
|
39
59
|
"test": "vitest --run",
|
|
40
60
|
"test:watch": "vitest"
|
|
41
61
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|