Skip to content

Commit 7562e24

Browse files
committed
Merge branch 'main' into vicb/r2-remote-binding
2 parents d2439fa + bf33735 commit 7562e24

54 files changed

Lines changed: 2916 additions & 1444 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

create-cloudflare/next/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"cf-typegen": "wrangler types --env-interface CloudflareEnv ./cloudflare-env.d.ts"
1414
},
1515
"dependencies": {
16-
"@opennextjs/cloudflare": "^1.15.1",
16+
"@opennextjs/cloudflare": "^1.17.1",
1717
"next": "16.1.5",
1818
"react": "19.1.5",
1919
"react-dom": "19.1.5"
@@ -28,6 +28,6 @@
2828
"eslint-config-next": "15.4.6",
2929
"tailwindcss": "^4",
3030
"typescript": "^5.7.4",
31-
"wrangler": "^4.59.3"
31+
"wrangler": "^4.65.0"
3232
}
3333
}

create-cloudflare/next/wrangler.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"$schema": "node_modules/wrangler/config-schema.json",
77
"name": "<WORKER_NAME>",
88
"main": ".open-next/worker.js",
9-
"compatibility_date": "2025-12-01",
9+
"compatibility_date": "<COMPATIBILITY_DATE>",
1010
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
1111
"assets": {
1212
"binding": "ASSETS",

packages/cloudflare/CHANGELOG.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,54 @@
11
# @opennextjs/cloudflare
22

3+
## 1.17.1
4+
5+
### Patch Changes
6+
7+
- [#1147](https://github.com/opennextjs/opennextjs-cloudflare/pull/1147) [`f5bd138`](https://github.com/opennextjs/opennextjs-cloudflare/commit/f5bd138fd3c77e02f2aa4b9c76d55681e59e98b4) Thanks [@vicb](https://github.com/vicb)! - make dev /cdn-cgi/image behaves like prod for consistency
8+
9+
## 1.17.0
10+
11+
### Minor Changes
12+
13+
- [#1133](https://github.com/opennextjs/opennextjs-cloudflare/pull/1133) [`25d5835`](https://github.com/opennextjs/opennextjs-cloudflare/commit/25d5835b1c006d6400141f3a5aa93332b26b04e3) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Update the `migrate` command to attempt to create an R2 bucket for caching, if that is not possible an application without caching enabled will be generated instead.
14+
15+
## 1.16.6
16+
17+
### Patch Changes
18+
19+
- [#1138](https://github.com/opennextjs/opennextjs-cloudflare/pull/1138) [`4487f1f`](https://github.com/opennextjs/opennextjs-cloudflare/commit/4487f1f64fbf14175a13d6e54928bc1a35d39fdf) Thanks [@james-elicx](https://github.com/james-elicx)! - Fix the CLI potentially setting a future compatibility date in the wrangler config when workerd has published a version matching a future date, by capping to the current date.
20+
21+
## 1.16.5
22+
23+
### Patch Changes
24+
25+
- [#1127](https://github.com/opennextjs/opennextjs-cloudflare/pull/1127) [`2b437f1`](https://github.com/opennextjs/opennextjs-cloudflare/commit/2b437f17cc696a65d8bb5b8fb5a230707267dd84) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - In the `migrate` command, add an initial step to create a Next.js config file (required by open-next) if it doesn't exist
26+
27+
- [#1126](https://github.com/opennextjs/opennextjs-cloudflare/pull/1126) [`8c3a36e`](https://github.com/opennextjs/opennextjs-cloudflare/commit/8c3a36e35a0c01745054ccf71169ff2859fa18ad) Thanks [@alex-all3dp](https://github.com/alex-all3dp)! - fix: prevent Worker hang on HEAD requests to static assets
28+
29+
## 1.16.4
30+
31+
### Patch Changes
32+
33+
- [#1122](https://github.com/opennextjs/opennextjs-cloudflare/pull/1122) [`6c94a4a`](https://github.com/opennextjs/opennextjs-cloudflare/commit/6c94a4aae9563942fea853b4bb4297dff62a5331) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - In `migrate` command, avoid adding unnecessary newlines when creating files
34+
35+
- [#1122](https://github.com/opennextjs/opennextjs-cloudflare/pull/1122) [`6c94a4a`](https://github.com/opennextjs/opennextjs-cloudflare/commit/6c94a4aae9563942fea853b4bb4297dff62a5331) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - fix `migrate` command incorrectly erroring if the target application doesn't have a `public` directory
36+
37+
- [#1122](https://github.com/opennextjs/opennextjs-cloudflare/pull/1122) [`6c94a4a`](https://github.com/opennextjs/opennextjs-cloudflare/commit/6c94a4aae9563942fea853b4bb4297dff62a5331) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Bump `@opennextjs/aws` to 3.9.16
38+
39+
- Fix `migrate` command not updating Next.js config files
40+
- Fixes [#1062](https://github.com/opennextjs/opennextjs-cloudflare/issues/1062), [#1115](https://github.com/opennextjs/opennextjs-cloudflare/issues/1115)
41+
42+
See details at <https://github.com/opennextjs/opennextjs-aws/releases/tag/v3.9.16>
43+
44+
- [#1097](https://github.com/opennextjs/opennextjs-cloudflare/pull/1097) [`fea645f`](https://github.com/opennextjs/opennextjs-cloudflare/commit/fea645f01e95b58e728ae6f429601c3fa06dd8bc) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Add `--help` and `--version` to the `opennextjs-cloudflare` CLI
45+
46+
Improve the `opennextjs-cloudflare` CLI by:
47+
48+
- ensuring that unknown commands (e.g., `opennextjs-cloudflare foo`) display a clear and helpful error message
49+
- adding a `-h`|`--help` flag to display the CLI's help message
50+
- adding a `-v`|`--version` flag to display the package's version
51+
352
## 1.16.3
453

554
### Patch Changes
@@ -67,8 +116,8 @@
67116

68117
- [#1071](https://github.com/opennextjs/opennextjs-cloudflare/pull/1071) [`886c742`](https://github.com/opennextjs/opennextjs-cloudflare/commit/886c742f8e735843196a4a1c758a9e5b1cb5464e) Thanks [@vicb](https://github.com/vicb)! - fix: patch Next config for missing fields.
69118

70-
There was a regression in Next 16.1.0 (https://github.com/vercel/next.js/pull/86830) and some fields were missing in the config.
71-
The Next team fixed that in 16.1.4 (https://github.com/vercel/next.js/pull/88733).
119+
There was a regression in Next 16.1.0 (<https://github.com/vercel/next.js/pull/86830>) and some fields were missing in the config.
120+
The Next team fixed that in 16.1.4 (<https://github.com/vercel/next.js/pull/88733>).
72121

73122
This PR introduce a patch for 16.1.0-16.1.3
74123

@@ -258,7 +307,7 @@
258307

259308
**Note:**
260309

261-
You can follow documentation https://developers.cloudflare.com/r2/api/tokens/ for creating API tokens with appropriate permissions for R2 access.
310+
You can follow documentation <https://developers.cloudflare.com/r2/api/tokens/> for creating API tokens with appropriate permissions for R2 access.
262311

263312
### Patch Changes
264313

@@ -637,7 +686,7 @@
637686

638687
- [#674](https://github.com/opennextjs/opennextjs-cloudflare/pull/674) [`ec9ea58`](https://github.com/opennextjs/opennextjs-cloudflare/commit/ec9ea58764fa344b6a47df33b4ae05063d9a1c07) Thanks [@conico974](https://github.com/conico974)! - fix blockConcurrencyWhile on DO queue
639688

640-
- [#672](https://github.com/opennextjs/opennextjs-cloudflare/pull/672) [`9188e67`](https://github.com/opennextjs/opennextjs-cloudflare/commit/9188e679cc70d14bc2dedfa2428926b51c1a1ba9) Thanks [@conico974](https://github.com/conico974)! - bump aws to 3.6.2. More details about the fixes can be found here: https://github.com/opennextjs/opennextjs-aws/blob/main/packages/open-next/CHANGELOG.md#362
689+
- [#672](https://github.com/opennextjs/opennextjs-cloudflare/pull/672) [`9188e67`](https://github.com/opennextjs/opennextjs-cloudflare/commit/9188e679cc70d14bc2dedfa2428926b51c1a1ba9) Thanks [@conico974](https://github.com/conico974)! - bump aws to 3.6.2. More details about the fixes can be found here: <https://github.com/opennextjs/opennextjs-aws/blob/main/packages/open-next/CHANGELOG.md#362>
641690

642691
## 1.0.3
643692

packages/cloudflare/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@opennextjs/cloudflare",
33
"description": "Cloudflare builder for next apps",
4-
"version": "1.16.3",
4+
"version": "1.17.1",
55
"type": "module",
66
"scripts": {
77
"clean": "rimraf dist",
@@ -54,10 +54,11 @@
5454
"dependencies": {
5555
"@ast-grep/napi": "^0.40.5",
5656
"@dotenvx/dotenvx": "catalog:",
57-
"@opennextjs/aws": "3.9.15",
57+
"@opennextjs/aws": "3.9.16",
5858
"cloudflare": "^4.4.1",
5959
"enquirer": "^2.4.1",
6060
"glob": "catalog:",
61+
"comment-json": "^4.5.1",
6162
"ts-tqdm": "^0.8.6",
6263
"yargs": "catalog:"
6364
},

packages/cloudflare/src/api/overrides/asset-resolver/index.spec.ts

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,80 @@
1-
import { describe, expect, test } from "vitest";
1+
import { beforeEach, describe, expect, test, vi } from "vitest";
22

33
import { isUserWorkerFirst } from "./index.js";
44

5+
const mockAssetsFetch = vi.fn();
6+
7+
vi.mock("../../cloudflare-context.js", () => ({
8+
getCloudflareContext: () => ({
9+
env: {
10+
ASSETS: { fetch: mockAssetsFetch },
11+
},
12+
}),
13+
}));
14+
15+
describe("maybeGetAssetResult", () => {
16+
let resolver: typeof import("./index.js").default;
17+
18+
beforeEach(async () => {
19+
vi.resetModules();
20+
mockAssetsFetch.mockReset();
21+
globalThis.__ASSETS_RUN_WORKER_FIRST__ = true;
22+
resolver = (await import("./index.js")).default;
23+
});
24+
25+
const makeEvent = (method: string, rawPath: string) =>
26+
({
27+
method,
28+
rawPath,
29+
headers: { accept: "*/*" },
30+
}) as Parameters<typeof resolver.maybeGetAssetResult>[0];
31+
32+
test("GET request returns response body", async () => {
33+
const body = new ReadableStream();
34+
mockAssetsFetch.mockResolvedValue(new Response(body, { status: 200 }));
35+
36+
const result = await resolver.maybeGetAssetResult(makeEvent("GET", "/style.css"));
37+
38+
expect(result).toBeDefined();
39+
expect(result!.statusCode).toBe(200);
40+
expect(result!.body).not.toBeNull();
41+
});
42+
43+
test("HEAD request returns null body", async () => {
44+
mockAssetsFetch.mockResolvedValue(new Response(null, { status: 200 }));
45+
46+
const result = await resolver.maybeGetAssetResult(makeEvent("HEAD", "/style.css"));
47+
48+
expect(result).toBeDefined();
49+
expect(result!.statusCode).toBe(200);
50+
expect(result!.body).toBeNull();
51+
});
52+
53+
test("returns undefined for 404 responses", async () => {
54+
mockAssetsFetch.mockResolvedValue(new Response(null, { status: 404 }));
55+
56+
const result = await resolver.maybeGetAssetResult(makeEvent("GET", "/missing.css"));
57+
58+
expect(result).toBeUndefined();
59+
});
60+
61+
test("returns undefined for POST requests", async () => {
62+
const result = await resolver.maybeGetAssetResult(makeEvent("POST", "/style.css"));
63+
64+
expect(result).toBeUndefined();
65+
expect(mockAssetsFetch).not.toHaveBeenCalled();
66+
});
67+
68+
test("returns undefined when run_worker_first is false", async () => {
69+
globalThis.__ASSETS_RUN_WORKER_FIRST__ = false;
70+
71+
const result = await resolver.maybeGetAssetResult(makeEvent("GET", "/style.css"));
72+
73+
expect(result).toBeUndefined();
74+
expect(mockAssetsFetch).not.toHaveBeenCalled();
75+
});
76+
});
77+
578
describe("isUserWorkerFirst", () => {
679
test("run_worker_first = false", () => {
780
expect(isUserWorkerFirst(false, "/test")).toBe(false);

packages/cloudflare/src/api/overrides/asset-resolver/index.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,33 @@ const resolver: AssetResolver = {
4444
type: "core",
4545
statusCode: response.status,
4646
headers: Object.fromEntries(response.headers.entries()),
47-
// Workers and Node types differ.
4847
// eslint-disable-next-line @typescript-eslint/no-explicit-any
49-
body: response.body || (new ReadableStream() as any),
48+
body: getResponseBody(method, response) as any,
5049
isBase64Encoded: false,
5150
} satisfies InternalResult;
5251
},
5352
};
5453

54+
/**
55+
* Returns the response body for an asset result.
56+
*
57+
* HEAD responses must return `null` because `response.body` is `null` per the HTTP spec
58+
* and the `new ReadableStream()` fallback would create a stream that never closes, hanging the Worker.
59+
*
60+
* @param method - The HTTP method of the request.
61+
* @param response - The response from the ASSETS binding.
62+
* @returns The body to use in the internal result.
63+
*/
64+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
65+
function getResponseBody(method: string, response: Response): ReadableStream<any> | null {
66+
if (method === "HEAD") {
67+
return null;
68+
}
69+
// Workers and Node ReadableStream types differ.
70+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
71+
return response.body || (new ReadableStream() as any);
72+
}
73+
5574
/**
5675
* @param runWorkerFirst `run_worker_first` config
5776
* @param pathname pathname of the request

packages/cloudflare/src/cli/build/build.ts

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { Unstable_Config } from "wrangler";
1010

1111
import { OpenNextConfig } from "../../api/config.js";
1212
import type { ProjectOptions } from "../project-options.js";
13+
import { ensureNextjsVersionSupported } from "../utils/nextjs-support.js";
1314
import { bundleServer } from "./bundle-server.js";
1415
import { compileCacheAssetsManifestSqlFile } from "./open-next/compile-cache-assets-manifest.js";
1516
import { compileEnvFiles } from "./open-next/compile-env-files.js";
@@ -104,25 +105,3 @@ export async function build(
104105

105106
logger.info("OpenNext build complete.");
106107
}
107-
108-
async function ensureNextjsVersionSupported({ nextVersion }: buildHelper.BuildOptions) {
109-
if (buildHelper.compareSemver(nextVersion, "<", "14.2.0")) {
110-
logger.error("Next.js version unsupported, please upgrade to version 14.2 or greater.");
111-
process.exit(1);
112-
}
113-
114-
const {
115-
default: { version: wranglerVersion },
116-
} = await import("wrangler/package.json", { with: { type: "json" } });
117-
118-
// We need a version of workerd that has a fix for setImmediate for Next.js 16.1+
119-
// See:
120-
// - https://github.com/cloudflare/workerd/pull/5869
121-
// - https://github.com/opennextjs/opennextjs-cloudflare/issues/1049
122-
if (
123-
buildHelper.compareSemver(nextVersion, ">=", "16.1.0") &&
124-
buildHelper.compareSemver(wranglerVersion, "<", "4.59.2")
125-
) {
126-
logger.warn(`Next.js 16.1+ requires wrangler 4.59.2 or greater (${wranglerVersion} detected).`);
127-
}
128-
}

packages/cloudflare/src/cli/build/bundle-server.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { build, type Plugin } from "esbuild";
1010

1111
import { getOpenNextConfig } from "../../api/config.js";
1212
import type { ProjectOptions } from "../project-options.js";
13+
import { normalizePath } from "../utils/normalize-path.js";
1314
import { patchVercelOgLibrary } from "./patches/ast/patch-vercel-og-library.js";
1415
import { patchWebpackRuntime } from "./patches/ast/webpack-runtime.js";
1516
import { inlineDynamicRequires } from "./patches/plugins/dynamic-requires.js";
@@ -26,7 +27,8 @@ import { shimRequireHook } from "./patches/plugins/require-hook.js";
2627
import { patchRouteModules } from "./patches/plugins/route-module.js";
2728
import { shimReact } from "./patches/plugins/shim-react.js";
2829
import { setWranglerExternal } from "./patches/plugins/wrangler-external.js";
29-
import { copyPackageCliFiles, needsExperimentalReact, normalizePath } from "./utils/index.js";
30+
import { copyPackageCliFiles } from "./utils/copy-package-cli-files.js";
31+
import { needsExperimentalReact } from "./utils/needs-experimental-react.js";
3032

3133
/** The dist directory of the Cloudflare adapter package */
3234
const packageDistDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "../..");

packages/cloudflare/src/cli/build/open-next/compile-env-files.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from "node:path";
33

44
import { BuildOptions } from "@opennextjs/aws/build/helper.js";
55

6-
import { extractProjectEnvVars } from "../utils/index.js";
6+
import { extractProjectEnvVars } from "../../utils/extract-project-env-vars.js";
77

88
/**
99
* Compiles the values extracted from the project's env files to the output directory for use in the worker.

packages/cloudflare/src/cli/build/open-next/createServerBundle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
2626
import type { Plugin } from "esbuild";
2727

2828
import { getOpenNextConfig } from "../../../api/config.js";
29+
import { normalizePath } from "../../utils/normalize-path.js";
2930
import { patchResRevalidate } from "../patches/plugins/res-revalidate.js";
3031
import { patchTurbopackRuntime } from "../patches/plugins/turbopack.js";
3132
import { patchUseCacheIO } from "../patches/plugins/use-cache.js";
32-
import { normalizePath } from "../utils/index.js";
3333
import { copyWorkerdPackages } from "../utils/workerd.js";
3434

3535
interface CodeCustomization {

0 commit comments

Comments
 (0)