From 9f93b54de2847ca3e3aeb5f45fa89fb8b7e89ed3 Mon Sep 17 00:00:00 2001 From: James Opstad <13586373+jamesopstad@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:41:36 +0000 Subject: [PATCH 1/5] Strip query strings from module names when writing to disk (#12824) --- .changeset/fix-wasm-query-string-windows.md | 9 ++++ .../src/__tests__/deploy/formats.test.ts | 41 +++++++++++++++++++ .../deployment-bundle/module-collection.ts | 30 ++++++++++---- 3 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 .changeset/fix-wasm-query-string-windows.md diff --git a/.changeset/fix-wasm-query-string-windows.md b/.changeset/fix-wasm-query-string-windows.md new file mode 100644 index 000000000000..d89b85815cbb --- /dev/null +++ b/.changeset/fix-wasm-query-string-windows.md @@ -0,0 +1,9 @@ +--- +"wrangler": patch +--- + +Strip query strings from module names before writing to disk + +When bundling modules with query string suffixes (e.g. `.wasm?module`), the `?` character was included in the output filename. Since `?` is not a valid filename character on Windows, this caused an ENOENT error during `wrangler dev`. This was particularly visible when using Prisma Client with the D1 adapter, which imports `.wasm?module` files. + +The fix strips query strings from module names before writing them to disk, while preserving correct module resolution. diff --git a/packages/wrangler/src/__tests__/deploy/formats.test.ts b/packages/wrangler/src/__tests__/deploy/formats.test.ts index d8303399a429..fbff50d9c7d7 100644 --- a/packages/wrangler/src/__tests__/deploy/formats.test.ts +++ b/packages/wrangler/src/__tests__/deploy/formats.test.ts @@ -344,6 +344,47 @@ describe("deploy", () => { expect(std.warn).toMatchInlineSnapshot(`""`); }); + it("should strip query string suffixes from module names (esm)", async () => { + writeWranglerConfig(); + fs.writeFileSync( + "./index.js", + `import hello from './hello.wasm?module'; export default {};` + ); + fs.writeFileSync("./hello.wasm", "SOME WASM CONTENT"); + mockSubDomainRequest(); + mockUploadWorkerRequest({ + expectedType: "esm", + expectedBindings: [], + expectedModules: { + "./94b240d0d692281e6467aa42043986e5c7eea034-hello.wasm": + "SOME WASM CONTENT", + }, + }); + await runWrangler("deploy index.js"); + expect(std.err).toMatchInlineSnapshot(`""`); + }); + + it("should strip query string suffixes from module names with preserve_file_names (esm)", async () => { + writeWranglerConfig({ + preserve_file_names: true, + }); + fs.writeFileSync( + "./index.js", + `import hello from './hello.wasm?module'; export default {};` + ); + fs.writeFileSync("./hello.wasm", "SOME WASM CONTENT"); + mockSubDomainRequest(); + mockUploadWorkerRequest({ + expectedType: "esm", + expectedBindings: [], + expectedModules: { + "./hello.wasm": "SOME WASM CONTENT", + }, + }); + await runWrangler("deploy index.js"); + expect(std.err).toMatchInlineSnapshot(`""`); + }); + describe("inject process.env.NODE_ENV", () => { beforeEach(() => { vi.stubEnv("NODE_ENV", "some-node-env"); diff --git a/packages/wrangler/src/deployment-bundle/module-collection.ts b/packages/wrangler/src/deployment-bundle/module-collection.ts index e44bca26c4ac..5f9c101d8fcf 100644 --- a/packages/wrangler/src/deployment-bundle/module-collection.ts +++ b/packages/wrangler/src/deployment-bundle/module-collection.ts @@ -44,6 +44,13 @@ export const RuleTypeToModuleType: Record = export const ModuleTypeToRuleType = flipObject(RuleTypeToModuleType); +// Strip query string suffixes (e.g. `?module`) from module paths so that +// file paths and module names don't contain characters invalid on Windows. +function stripQueryString(modulePath: string): string { + const queryIndex = modulePath.indexOf("?"); + return queryIndex !== -1 ? modulePath.slice(0, queryIndex) : modulePath; +} + // This is a combination of an esbuild plugin and a mutable array // that we use to collect module references from source code. // There will be modules that _shouldn't_ be inlined directly into @@ -202,10 +209,11 @@ export function createModuleCollector(props: { // take the file and massage it to a // transportable/manageable format + const cleanedPath = stripQueryString(args.path); const filePath = path.join( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion props.wrangler1xLegacyModuleReferences!.rootDirectory, - args.path + cleanedPath ); const fileContent = (await readFile( filePath @@ -215,8 +223,8 @@ export function createModuleCollector(props: { .update(fileContent) .digest("hex"); const fileName = props.preserveFileNames - ? args.path - : `./${fileHash}-${path.basename(args.path)}`; + ? cleanedPath + : `./${fileHash}-${path.basename(cleanedPath)}`; const { rule } = rulesMatchers.find(({ regex }) => regex.test(fileName)) || {}; @@ -257,13 +265,17 @@ export function createModuleCollector(props: { // take the file and massage it to a // transportable/manageable format - let filePath = path.join(args.resolveDir, args.path); + // Strip query string suffixes (e.g. `?module`) from the import + // path. The `?` character is not valid in filenames on Windows + // and would cause ENOENT errors when writing modules to disk. + const cleanedPath = stripQueryString(args.path); + let filePath = path.join(args.resolveDir, cleanedPath); // If this was a found additional module, mark it as external. // Note, there's no need to watch the file here as we already // watch all `foundModulePaths` with `wrangler:modules-watch`. if (foundModulePaths.includes(filePath)) { - return { path: args.path, external: true }; + return { path: cleanedPath, external: true }; } // For JavaScript module rules, we only register this onResolve // callback if `findAdditionalModules` is true. If we didn't @@ -277,7 +289,7 @@ export function createModuleCollector(props: { // and if so, validate the import against the package.json exports // and resolve the file path to the correct file. try { - const resolved = await build.resolve(args.path, { + const resolved = await build.resolve(cleanedPath, { kind: args.kind, importer: args.importer, resolveDir: args.resolveDir, @@ -295,7 +307,7 @@ export function createModuleCollector(props: { // Next try to resolve using the node module resolution algorithm try { - const resolved = resolveSync(args.path, { + const resolved = resolveSync(cleanedPath, { basedir: args.resolveDir, }); filePath = resolved; @@ -314,8 +326,8 @@ export function createModuleCollector(props: { .update(fileContent) .digest("hex"); const fileName = props.preserveFileNames - ? args.path - : `./${fileHash}-${path.basename(args.path)}`; + ? cleanedPath + : `./${fileHash}-${path.basename(cleanedPath)}`; // add the module to the array modules.push({ From 2f57027c8403dcb48e8dbca3ea4c2e1aaae06d5e Mon Sep 17 00:00:00 2001 From: James Opstad <13586373+jamesopstad@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:51:59 +0000 Subject: [PATCH 2/5] Add workers-utils back into changesets (#12817) --- packages/workers-utils/package.json | 1 + tools/deployments/__tests__/validate-changesets.test.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/workers-utils/package.json b/packages/workers-utils/package.json index 96da86f21c51..d0a0ef3b91a8 100644 --- a/packages/workers-utils/package.json +++ b/packages/workers-utils/package.json @@ -32,6 +32,7 @@ "build": "tsup", "check:lint": "eslint . --max-warnings=0 --cache", "check:type": "tsc -p ./tsconfig.json", + "deploy": "echo 'no deploy'", "dev": "concurrently -c black,blue --kill-others-on-fail false \"pnpm tsup --watch src\" \"pnpm run check:type --watch --preserveWatchOutput\"", "test": "vitest", "test:ci": "vitest run", diff --git a/tools/deployments/__tests__/validate-changesets.test.ts b/tools/deployments/__tests__/validate-changesets.test.ts index 7d18322eebd5..3f1eadbaad6b 100644 --- a/tools/deployments/__tests__/validate-changesets.test.ts +++ b/tools/deployments/__tests__/validate-changesets.test.ts @@ -39,6 +39,7 @@ describe("findPackageNames()", () => { "@cloudflare/workers-editor-shared", "@cloudflare/workers-playground", "@cloudflare/workers-shared", + "@cloudflare/workers-utils", "@cloudflare/workflows-shared", "create-cloudflare", "miniflare", From cb148200336ed57c56cb89028453ddd5fdef2e7b Mon Sep 17 00:00:00 2001 From: James Opstad <13586373+jamesopstad@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:52:12 +0000 Subject: [PATCH 3/5] Update `@hey-api/openapi-ts` and move to pnpm catalog (#12828) --- .changeset/late-humans-win.md | 6 + packages/local-explorer-ui/package.json | 2 +- packages/miniflare/package.json | 2 +- pnpm-lock.yaml | 145 ++++++++---------------- pnpm-workspace.yaml | 1 + 5 files changed, 56 insertions(+), 100 deletions(-) create mode 100644 .changeset/late-humans-win.md diff --git a/.changeset/late-humans-win.md b/.changeset/late-humans-win.md new file mode 100644 index 000000000000..3128dcdfeeb7 --- /dev/null +++ b/.changeset/late-humans-win.md @@ -0,0 +1,6 @@ +--- +"@cloudflare/local-explorer-ui": patch +"miniflare": patch +--- + +Update `@hey-api/openapi-ts` to ^0.94.0 diff --git a/packages/local-explorer-ui/package.json b/packages/local-explorer-ui/package.json index e58525be6678..3699715fa9f9 100644 --- a/packages/local-explorer-ui/package.json +++ b/packages/local-explorer-ui/package.json @@ -44,7 +44,7 @@ "devDependencies": { "@cloudflare/eslint-config-shared": "workspace:*", "@cloudflare/workers-tsconfig": "workspace:*", - "@hey-api/openapi-ts": "^0.91.1", + "@hey-api/openapi-ts": "catalog:default", "@tanstack/react-router-devtools": "^1.158.0", "@tanstack/router-plugin": "^1.158.0", "@types/react": "^19.2.0", diff --git a/packages/miniflare/package.json b/packages/miniflare/package.json index a20fbce63faf..cd779aaa184a 100644 --- a/packages/miniflare/package.json +++ b/packages/miniflare/package.json @@ -64,7 +64,7 @@ "@cloudflare/workers-types": "catalog:default", "@cloudflare/workers-utils": "workspace:*", "@cloudflare/workflows-shared": "workspace:*", - "@hey-api/openapi-ts": "^0.90.0", + "@hey-api/openapi-ts": "catalog:default", "@microsoft/api-extractor": "^7.52.8", "@puppeteer/browsers": "^2.10.6", "@types/debug": "^4.1.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de0a48ac576b..2f41655ee2e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,9 @@ catalogs: '@cloudflare/workers-types': specifier: ^4.20260310.1 version: 4.20260310.1 + '@hey-api/openapi-ts': + specifier: ^0.94.0 + version: 0.94.0 '@typescript-eslint/eslint-plugin': specifier: ^8.35.1 version: 8.46.3 @@ -2185,8 +2188,8 @@ importers: specifier: workspace:* version: link:../workers-tsconfig '@hey-api/openapi-ts': - specifier: ^0.91.1 - version: 0.91.1(typescript@5.8.3) + specifier: catalog:default + version: 0.94.0(typescript@5.8.3) '@tanstack/react-router-devtools': specifier: ^1.158.0 version: 1.159.5(@tanstack/react-router@1.159.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.159.4)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -2267,8 +2270,8 @@ importers: specifier: workspace:* version: link:../workflows-shared '@hey-api/openapi-ts': - specifier: ^0.90.0 - version: 0.90.10(typescript@5.8.3) + specifier: catalog:default + version: 0.94.0(typescript@5.8.3) '@microsoft/api-extractor': specifier: ^7.52.8 version: 7.52.8(@types/node@20.19.9) @@ -5197,7 +5200,7 @@ packages: react: ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0 '@cloudflare/intl-types@1.5.7': - resolution: {integrity: sha512-5p+NqAoM3rOMsZsAS6RMWvClhuxWA3YqRkfIxkTcc6uYNsays90GuyzdXmN/v+T7UiSkmzRa7Atu75tD/245MQ==} + resolution: {integrity: sha512-5p+NqAoM3rOMsZsAS6RMWvClhuxWA3YqRkfIxkTcc6uYNsays90GuyzdXmN/v+T7UiSkmzRa7Atu75tD/245MQ==, tarball: https://registry.npmjs.org/@cloudflare/intl-types/-/intl-types-1.5.7.tgz} peerDependencies: react: ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0 @@ -5233,7 +5236,7 @@ packages: react: ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0 '@cloudflare/style-const@6.1.3': - resolution: {integrity: sha512-kwKNttljHfLMY9iVY4r4P00L9TrIc3xWvFoFte/ImLIOq13MH1sDXkQbA8nLC1qcFq7Liv/gbGrtgouPW2lO5Q==} + resolution: {integrity: sha512-kwKNttljHfLMY9iVY4r4P00L9TrIc3xWvFoFte/ImLIOq13MH1sDXkQbA8nLC1qcFq7Liv/gbGrtgouPW2lO5Q==, tarball: https://registry.npmjs.org/@cloudflare/style-const/-/style-const-6.1.3.tgz} peerDependencies: react: ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0 @@ -5261,7 +5264,7 @@ packages: react: ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0 '@cloudflare/types@6.29.1': - resolution: {integrity: sha512-3AfpWx3G47NWgrkTMMIxcDxl/JpS8K4a5w28+4afK8Eyzd2Mnh7+JRB3C59A6mUjo6e+KTJ/cEvyVIHYO6FQDA==} + resolution: {integrity: sha512-3AfpWx3G47NWgrkTMMIxcDxl/JpS8K4a5w28+4afK8Eyzd2Mnh7+JRB3C59A6mUjo6e+KTJ/cEvyVIHYO6FQDA==, tarball: https://registry.npmjs.org/@cloudflare/types/-/types-6.29.1.tgz} peerDependencies: react: ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0 @@ -5278,7 +5281,7 @@ packages: resolution: {integrity: sha512-qdCFf90hoZzT4o4xEmxOKUf9+bEJNGh4ANnRYApo6BMyVnHoHEHAQ3nWmGSHBmo+W9hOk2Ik7r1oHLbI0O/RRg==} '@cloudflare/util-en-garde@8.0.13': - resolution: {integrity: sha512-TJc3D+aA7bU/exJJbKgc07SLpYn1cpDMiYaz8NIxI4MJ8ZbAbZIWt6WYJKrh0m7sUu6+F2eIJPIV5/CFXOWmMw==} + resolution: {integrity: sha512-TJc3D+aA7bU/exJJbKgc07SLpYn1cpDMiYaz8NIxI4MJ8ZbAbZIWt6WYJKrh0m7sUu6+F2eIJPIV5/CFXOWmMw==, tarball: https://registry.npmjs.org/@cloudflare/util-en-garde/-/util-en-garde-8.0.13.tgz} '@cloudflare/util-hooks@1.3.1': resolution: {integrity: sha512-gIsPlzgUbMswIE1h8vGK6LZr/Io5yocUl01WCLy5fxEajhCQ0mNLixkD2Uqne+WPTfqzu4jgC5NxYXgl+Hf6yQ==} @@ -5296,91 +5299,91 @@ packages: vitest: 2.0.x - 3.2.x '@cloudflare/workerd-darwin-64@1.20251210.0': - resolution: {integrity: sha512-Nn9X1moUDERA9xtFdCQ2XpQXgAS9pOjiCxvOT8sVx9UJLAiBLkfSCGbpsYdarODGybXCpjRlc77Yppuolvt7oQ==} + resolution: {integrity: sha512-Nn9X1moUDERA9xtFdCQ2XpQXgAS9pOjiCxvOT8sVx9UJLAiBLkfSCGbpsYdarODGybXCpjRlc77Yppuolvt7oQ==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251210.0.tgz} engines: {node: '>=16'} cpu: [x64] os: [darwin] '@cloudflare/workerd-darwin-64@1.20260301.1': - resolution: {integrity: sha512-+kJvwociLrvy1JV9BAvoSVsMEIYD982CpFmo/yMEvBwxDIjltYsLTE8DLi0mCkGsQ8Ygidv2fD9wavzXeiY7OQ==} + resolution: {integrity: sha512-+kJvwociLrvy1JV9BAvoSVsMEIYD982CpFmo/yMEvBwxDIjltYsLTE8DLi0mCkGsQ8Ygidv2fD9wavzXeiY7OQ==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260301.1.tgz} engines: {node: '>=16'} cpu: [x64] os: [darwin] '@cloudflare/workerd-darwin-64@1.20260310.1': - resolution: {integrity: sha512-hF2VpoWaMb1fiGCQJqCY6M8I+2QQqjkyY4LiDYdTL5D/w6C1l5v1zhc0/jrjdD1DXfpJtpcSMSmEPjHse4p9Ig==} + resolution: {integrity: sha512-hF2VpoWaMb1fiGCQJqCY6M8I+2QQqjkyY4LiDYdTL5D/w6C1l5v1zhc0/jrjdD1DXfpJtpcSMSmEPjHse4p9Ig==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260310.1.tgz} engines: {node: '>=16'} cpu: [x64] os: [darwin] '@cloudflare/workerd-darwin-arm64@1.20251210.0': - resolution: {integrity: sha512-Mg8iYIZQFnbevq/ls9eW/eneWTk/EE13Pej1MwfkY5et0jVpdHnvOLywy/o+QtMJFef1AjsqXGULwAneYyBfHw==} + resolution: {integrity: sha512-Mg8iYIZQFnbevq/ls9eW/eneWTk/EE13Pej1MwfkY5et0jVpdHnvOLywy/o+QtMJFef1AjsqXGULwAneYyBfHw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251210.0.tgz} engines: {node: '>=16'} cpu: [arm64] os: [darwin] '@cloudflare/workerd-darwin-arm64@1.20260301.1': - resolution: {integrity: sha512-PPIetY3e67YBr9O4UhILK8nbm5TqUDl14qx4rwFNrRSBOvlzuczzbd4BqgpAtbGVFxKp1PWpjAnBvGU/OI/tLQ==} + resolution: {integrity: sha512-PPIetY3e67YBr9O4UhILK8nbm5TqUDl14qx4rwFNrRSBOvlzuczzbd4BqgpAtbGVFxKp1PWpjAnBvGU/OI/tLQ==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260301.1.tgz} engines: {node: '>=16'} cpu: [arm64] os: [darwin] '@cloudflare/workerd-darwin-arm64@1.20260310.1': - resolution: {integrity: sha512-h/Vl3XrYYPI6yFDE27XO1QPq/1G1lKIM8tzZGIWYpntK3IN5XtH3Ee/sLaegpJ49aIJoqhF2mVAZ6Yw+Vk2gJw==} + resolution: {integrity: sha512-h/Vl3XrYYPI6yFDE27XO1QPq/1G1lKIM8tzZGIWYpntK3IN5XtH3Ee/sLaegpJ49aIJoqhF2mVAZ6Yw+Vk2gJw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260310.1.tgz} engines: {node: '>=16'} cpu: [arm64] os: [darwin] '@cloudflare/workerd-linux-64@1.20251210.0': - resolution: {integrity: sha512-kjC2fCZhZ2Gkm1biwk2qByAYpGguK5Gf5ic8owzSCUw0FOUfQxTZUT9Lp3gApxsfTLbbnLBrX/xzWjywH9QR4g==} + resolution: {integrity: sha512-kjC2fCZhZ2Gkm1biwk2qByAYpGguK5Gf5ic8owzSCUw0FOUfQxTZUT9Lp3gApxsfTLbbnLBrX/xzWjywH9QR4g==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251210.0.tgz} engines: {node: '>=16'} cpu: [x64] os: [linux] '@cloudflare/workerd-linux-64@1.20260301.1': - resolution: {integrity: sha512-Gu5vaVTZuYl3cHa+u5CDzSVDBvSkfNyuAHi6Mdfut7TTUdcb3V5CIcR/mXRSyMXzEy9YxEWIfdKMxOMBjupvYQ==} + resolution: {integrity: sha512-Gu5vaVTZuYl3cHa+u5CDzSVDBvSkfNyuAHi6Mdfut7TTUdcb3V5CIcR/mXRSyMXzEy9YxEWIfdKMxOMBjupvYQ==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260301.1.tgz} engines: {node: '>=16'} cpu: [x64] os: [linux] '@cloudflare/workerd-linux-64@1.20260310.1': - resolution: {integrity: sha512-XzQ0GZ8G5P4d74bQYOIP2Su4CLdNPpYidrInaSOuSxMw+HamsHaFrjVsrV2mPy/yk2hi6SY2yMbgKFK9YjA7vw==} + resolution: {integrity: sha512-XzQ0GZ8G5P4d74bQYOIP2Su4CLdNPpYidrInaSOuSxMw+HamsHaFrjVsrV2mPy/yk2hi6SY2yMbgKFK9YjA7vw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260310.1.tgz} engines: {node: '>=16'} cpu: [x64] os: [linux] '@cloudflare/workerd-linux-arm64@1.20251210.0': - resolution: {integrity: sha512-2IB37nXi7PZVQLa1OCuO7/6pNxqisRSO8DmCQ5x/3sezI5op1vwOxAcb1osAnuVsVN9bbvpw70HJvhKruFJTuA==} + resolution: {integrity: sha512-2IB37nXi7PZVQLa1OCuO7/6pNxqisRSO8DmCQ5x/3sezI5op1vwOxAcb1osAnuVsVN9bbvpw70HJvhKruFJTuA==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251210.0.tgz} engines: {node: '>=16'} cpu: [arm64] os: [linux] '@cloudflare/workerd-linux-arm64@1.20260301.1': - resolution: {integrity: sha512-igL1pkyCXW6GiGpjdOAvqMi87UW0LMc/+yIQe/CSzuZJm5GzXoAMrwVTkCFnikk6JVGELrM5x0tGYlxa0sk5Iw==} + resolution: {integrity: sha512-igL1pkyCXW6GiGpjdOAvqMi87UW0LMc/+yIQe/CSzuZJm5GzXoAMrwVTkCFnikk6JVGELrM5x0tGYlxa0sk5Iw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260301.1.tgz} engines: {node: '>=16'} cpu: [arm64] os: [linux] '@cloudflare/workerd-linux-arm64@1.20260310.1': - resolution: {integrity: sha512-sxv4CxnN4ZR0uQGTFVGa0V4KTqwdej/czpIc5tYS86G8FQQoGIBiAIs2VvU7b8EROPcandxYHDBPTb+D9HIMPw==} + resolution: {integrity: sha512-sxv4CxnN4ZR0uQGTFVGa0V4KTqwdej/czpIc5tYS86G8FQQoGIBiAIs2VvU7b8EROPcandxYHDBPTb+D9HIMPw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260310.1.tgz} engines: {node: '>=16'} cpu: [arm64] os: [linux] '@cloudflare/workerd-windows-64@1.20251210.0': - resolution: {integrity: sha512-Uaz6/9XE+D6E7pCY4OvkCuJHu7HcSDzeGcCGY1HLhojXhHd7yL52c3yfiyJdS8hPatiAa0nn5qSI/42+aTdDSw==} + resolution: {integrity: sha512-Uaz6/9XE+D6E7pCY4OvkCuJHu7HcSDzeGcCGY1HLhojXhHd7yL52c3yfiyJdS8hPatiAa0nn5qSI/42+aTdDSw==, tarball: https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251210.0.tgz} engines: {node: '>=16'} cpu: [x64] os: [win32] '@cloudflare/workerd-windows-64@1.20260301.1': - resolution: {integrity: sha512-Q0wMJ4kcujXILwQKQFc1jaYamVsNvjuECzvRrTI8OxGFMx2yq9aOsswViE4X1gaS2YQQ5u0JGwuGi5WdT1Lt7A==} + resolution: {integrity: sha512-Q0wMJ4kcujXILwQKQFc1jaYamVsNvjuECzvRrTI8OxGFMx2yq9aOsswViE4X1gaS2YQQ5u0JGwuGi5WdT1Lt7A==, tarball: https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260301.1.tgz} engines: {node: '>=16'} cpu: [x64] os: [win32] '@cloudflare/workerd-windows-64@1.20260310.1': - resolution: {integrity: sha512-+1ZTViWKJypLfgH/luAHCqkent0DEBjAjvO40iAhOMHRLYP/SPphLvr4Jpi6lb+sIocS8Q1QZL4uM5Etg1Wskg==} + resolution: {integrity: sha512-+1ZTViWKJypLfgH/luAHCqkent0DEBjAjvO40iAhOMHRLYP/SPphLvr4Jpi6lb+sIocS8Q1QZL4uM5Etg1Wskg==, tarball: https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260310.1.tgz} engines: {node: '>=16'} cpu: [x64] os: [win32] @@ -6575,49 +6578,29 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@hey-api/codegen-core@0.5.5': - resolution: {integrity: sha512-f2ZHucnA2wBGAY8ipB4wn/mrEYW+WUxU2huJmUvfDO6AE2vfILSHeF3wCO39Pz4wUYPoAWZByaauftLrOfC12Q==} - engines: {node: '>=20.19.0'} - peerDependencies: - typescript: '>=5.5.3' - - '@hey-api/codegen-core@0.6.1': - resolution: {integrity: sha512-khTIpxhKEAqmRmeLUnAFJQs4Sbg9RPokovJk9rRcC8B5MWH1j3/BRSqfpAIiJUBDU1+nbVg2RVCV+eQ174cdvw==} + '@hey-api/codegen-core@0.7.1': + resolution: {integrity: sha512-X5qG+rr/BJvr+pEGcoW6l2azoZGrVuxsviEIhuf+3VwL9bk0atfubT65Xwo+4jDxXvjbhZvlwS0Ty3I7mLE2fg==} engines: {node: '>=20.19.0'} peerDependencies: typescript: '>=5.5.3' - '@hey-api/json-schema-ref-parser@1.2.2': - resolution: {integrity: sha512-oS+5yAdwnK20lSeFO1d53Ku+yaGCsY8PcrmSq2GtSs3bsBfRnHAbpPKSVzQcaxAOrzj5NB+f34WhZglVrNayBA==} - engines: {node: '>= 16'} - - '@hey-api/json-schema-ref-parser@1.2.3': - resolution: {integrity: sha512-gRbyyTjzpFVNmbD+Upn3w4dWV+bCXGJbff3A7leDO/tfNxSz1xIb6Ad/5UKtvEW9kDt/2Uyc3XkFZ6rpafvbfQ==} - engines: {node: '>= 16'} - - '@hey-api/openapi-ts@0.90.10': - resolution: {integrity: sha512-o0wlFxuLt1bcyIV/ZH8DQ1wrgODTnUYj/VfCHOOYgXUQlLp9Dm2PjihOz+WYrZLowhqUhSKeJRArOGzvLuOTsg==} + '@hey-api/json-schema-ref-parser@1.3.1': + resolution: {integrity: sha512-7atnpUkT8TyUPHYPLk91j/GyaqMuwTEHanLOe50Dlx0EEvNuQqFD52Yjg8x4KU0UFL1mWlyhE+sUE/wAtQ1N2A==} engines: {node: '>=20.19.0'} - hasBin: true - peerDependencies: - typescript: '>=5.5.3' - '@hey-api/openapi-ts@0.91.1': - resolution: {integrity: sha512-d16WR35UtthK/ihAIwJaKxrj/zvb5LbYwtVJCyZFFMin2qzDU8Y3Lpk78ensAykrLoaDLzpd0iIyt9JCP5Qmww==} + '@hey-api/openapi-ts@0.94.0': + resolution: {integrity: sha512-dbg3GG+v7sg9/Ahb7yFzwzQIJwm151JAtsnh9KtFyqiN0rGkMGA3/VqogEUq1kJB9XWrlMQwigwzhiEQ33VCSg==} engines: {node: '>=20.19.0'} hasBin: true peerDependencies: typescript: '>=5.5.3' - '@hey-api/shared@0.1.1': - resolution: {integrity: sha512-/irgNGXw9TL5aKB3S7jCLgh07vgDFkYjSjz7vEWO9xEe6MUhx76zSFzkPspk2UrLghYayvmaKPf1ky4XjNI9ZQ==} + '@hey-api/shared@0.2.2': + resolution: {integrity: sha512-vMqCS+j7F9xpWoXC7TBbqZkaelwrdeuSB+s/3elu54V5iq++S59xhkSq5rOgDIpI1trpE59zZQa6dpyUxItOgw==} engines: {node: '>=20.19.0'} peerDependencies: typescript: '>=5.5.3' - '@hey-api/types@0.1.2': - resolution: {integrity: sha512-uNNtiVAWL7XNrV/tFXx7GLY9lwaaDazx1173cGW3+UEaw4RUPsHEmiB4DSpcjNxMIcrctfz2sGKLnVx5PBG2RA==} - '@hey-api/types@0.1.3': resolution: {integrity: sha512-mZaiPOWH761yD4GjDQvtjS2ZYLu5o5pI1TVSvV/u7cmbybv51/FVtinFBeaE1kFQCKZ8OQpn2ezjLBJrKsGATw==} peerDependencies: @@ -9993,8 +9976,8 @@ packages: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} - commander@14.0.2: - resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} commander@4.1.1: @@ -17612,17 +17595,7 @@ snapshots: '@floating-ui/utils@0.2.10': {} - '@hey-api/codegen-core@0.5.5(typescript@5.8.3)': - dependencies: - '@hey-api/types': 0.1.2 - ansi-colors: 4.1.3 - c12: 3.3.3 - color-support: 1.1.3 - typescript: 5.8.3 - transitivePeerDependencies: - - magicast - - '@hey-api/codegen-core@0.6.1(typescript@5.8.3)': + '@hey-api/codegen-core@0.7.1(typescript@5.8.3)': dependencies: '@hey-api/types': 0.1.3(typescript@5.8.3) ansi-colors: 4.1.3 @@ -17632,51 +17605,29 @@ snapshots: transitivePeerDependencies: - magicast - '@hey-api/json-schema-ref-parser@1.2.2': - dependencies: - '@jsdevtools/ono': 7.1.3 - '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 - lodash: 4.17.23 - - '@hey-api/json-schema-ref-parser@1.2.3': + '@hey-api/json-schema-ref-parser@1.3.1': dependencies: '@jsdevtools/ono': 7.1.3 '@types/json-schema': 7.0.15 js-yaml: 4.1.1 - lodash: 4.17.23 - '@hey-api/openapi-ts@0.90.10(typescript@5.8.3)': + '@hey-api/openapi-ts@0.94.0(typescript@5.8.3)': dependencies: - '@hey-api/codegen-core': 0.5.5(typescript@5.8.3) - '@hey-api/json-schema-ref-parser': 1.2.2 - '@hey-api/types': 0.1.2 - ansi-colors: 4.1.3 - color-support: 1.1.3 - commander: 14.0.2 - open: 11.0.0 - semver: 7.7.3 - typescript: 5.8.3 - transitivePeerDependencies: - - magicast - - '@hey-api/openapi-ts@0.91.1(typescript@5.8.3)': - dependencies: - '@hey-api/codegen-core': 0.6.1(typescript@5.8.3) - '@hey-api/json-schema-ref-parser': 1.2.3 - '@hey-api/shared': 0.1.1(typescript@5.8.3) + '@hey-api/codegen-core': 0.7.1(typescript@5.8.3) + '@hey-api/json-schema-ref-parser': 1.3.1 + '@hey-api/shared': 0.2.2(typescript@5.8.3) '@hey-api/types': 0.1.3(typescript@5.8.3) ansi-colors: 4.1.3 color-support: 1.1.3 - commander: 14.0.2 + commander: 14.0.3 typescript: 5.8.3 transitivePeerDependencies: - magicast - '@hey-api/shared@0.1.1(typescript@5.8.3)': + '@hey-api/shared@0.2.2(typescript@5.8.3)': dependencies: - '@hey-api/codegen-core': 0.6.1(typescript@5.8.3) - '@hey-api/json-schema-ref-parser': 1.2.3 + '@hey-api/codegen-core': 0.7.1(typescript@5.8.3) + '@hey-api/json-schema-ref-parser': 1.3.1 '@hey-api/types': 0.1.3(typescript@5.8.3) ansi-colors: 4.1.3 cross-spawn: 7.0.6 @@ -17686,8 +17637,6 @@ snapshots: transitivePeerDependencies: - magicast - '@hey-api/types@0.1.2': {} - '@hey-api/types@0.1.3(typescript@5.8.3)': dependencies: typescript: 5.8.3 @@ -21361,7 +21310,7 @@ snapshots: commander@11.1.0: {} - commander@14.0.2: {} + commander@14.0.3: {} commander@4.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index fa5a75089b3e..2ecf7f2dbfdb 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -16,6 +16,7 @@ packages: # Quick Editor update | Every quarter | Update VSCode dependency and patches catalog: + "@hey-api/openapi-ts": "^0.94.0" "@types/node": "^20.19.9" "@typescript-eslint/eslint-plugin": "^8.35.1" "@typescript-eslint/parser": "^8.35.1" From cd16fdb293ad081cf0d7619e5f9cc4978360ccf1 Mon Sep 17 00:00:00 2001 From: Edmund Hung Date: Tue, 10 Mar 2026 12:30:43 +0000 Subject: [PATCH 4/5] chore: quarantine astro c3 e2e tests (#12829) --- packages/create-cloudflare/e2e/tests/frameworks/test-config.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/create-cloudflare/e2e/tests/frameworks/test-config.ts b/packages/create-cloudflare/e2e/tests/frameworks/test-config.ts index 68aabb9fa51d..251cc94b1bd5 100644 --- a/packages/create-cloudflare/e2e/tests/frameworks/test-config.ts +++ b/packages/create-cloudflare/e2e/tests/frameworks/test-config.ts @@ -48,6 +48,7 @@ function getFrameworkTestConfig(pm: string): NamedFrameworkTestConfig[] { { name: "astro:pages", argv: ["--platform", "pages"], + quarantine: true, testCommitMessage: true, unsupportedOSs: ["win32"], verifyDeploy: { @@ -65,6 +66,7 @@ function getFrameworkTestConfig(pm: string): NamedFrameworkTestConfig[] { { name: "astro:workers", argv: ["--platform", "workers"], + quarantine: true, testCommitMessage: true, unsupportedOSs: ["win32"], verifyDeploy: { @@ -720,6 +722,7 @@ function getExperimentalFrameworkTestConfig( { name: "astro:workers", argv: ["--platform", "workers"], + quarantine: true, testCommitMessage: true, unsupportedOSs: ["win32"], verifyDeploy: { From de65c58cbcf1c330a84c37fb351716780f2fd880 Mon Sep 17 00:00:00 2001 From: Gabi Date: Tue, 10 Mar 2026 09:20:14 -0500 Subject: [PATCH 5/5] containers: Remove experimental flag from enabling egress interception for containers (#12826) Co-authored-by: emily-shen --- .changeset/funny-mails-hammer.md | 9 +++++++++ packages/containers-shared/src/images.ts | 12 +++++------- packages/miniflare/src/plugins/core/index.ts | 17 ++++------------- .../vite-plugin-cloudflare/src/plugins/dev.ts | 3 --- .../src/plugins/preview.ts | 3 --- packages/wrangler/e2e/containers.dev.test.ts | 2 +- .../startDevWorker/LocalRuntimeController.ts | 1 - .../MultiworkerRuntimeController.ts | 1 - 8 files changed, 19 insertions(+), 29 deletions(-) create mode 100644 .changeset/funny-mails-hammer.md diff --git a/.changeset/funny-mails-hammer.md b/.changeset/funny-mails-hammer.md new file mode 100644 index 000000000000..fd10c5cdf5d6 --- /dev/null +++ b/.changeset/funny-mails-hammer.md @@ -0,0 +1,9 @@ +--- +"wrangler": minor +"miniflare": minor +"@cloudflare/vite-plugin": minor +--- + +Enable container egress interception in local dev without the `experimental` compatibility flag + +Container local development now always prepares the egress interceptor sidecar image needed for `interceptOutboundHttp()`. This makes container-to-Worker interception available by default in Wrangler, Miniflare, and the Cloudflare Vite plugin. diff --git a/packages/containers-shared/src/images.ts b/packages/containers-shared/src/images.ts index 0d6d1c10b08c..9d41ecb20918 100644 --- a/packages/containers-shared/src/images.ts +++ b/packages/containers-shared/src/images.ts @@ -17,8 +17,8 @@ import type { WranglerLogger, } from "./types"; -const DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE = - "cloudflare/proxy-everything:4dc6c7f@sha256:9621ef445ef120409e5d95bbd845ab2fa0f613636b59a01d998f5704f4096ae2"; +export const DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE = + "cloudflare/proxy-everything:3f5e832@sha256:816255f5b6ebdc2cdcddb578d803121e7ee9cfe178442da07725d75a66cdcf37"; export function getEgressInterceptorImage(): string { return ( @@ -114,7 +114,6 @@ export async function prepareContainerImagesForDev(args: { }) => void; logger: WranglerLogger | ViteLogger; isVite: boolean; - compatibilityFlags?: string[]; }): Promise { const { dockerPath, @@ -171,10 +170,9 @@ export async function prepareContainerImagesForDev(args: { } } - // Pull the egress interceptor image if experimental flag is enabled. - // This image is used to intercept outbound HTTP from containers and - // route it back to workerd (e.g. for interceptOutboundHttp). - if (!aborted && args.compatibilityFlags?.includes("experimental")) { + // Pull the egress interceptor image used to intercept outbound HTTP from + // containers and route it back to workerd (e.g. for interceptOutboundHttp). + if (!aborted) { await pullEgressInterceptorImage(dockerPath); } } diff --git a/packages/miniflare/src/plugins/core/index.ts b/packages/miniflare/src/plugins/core/index.ts index 2b3db8446c78..211258b09bf4 100644 --- a/packages/miniflare/src/plugins/core/index.ts +++ b/packages/miniflare/src/plugins/core/index.ts @@ -5,6 +5,7 @@ import path from "node:path"; import { Readable } from "node:stream"; import tls from "node:tls"; import { TextEncoder } from "node:util"; +import { DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE } from "@cloudflare/containers-shared"; import { bold } from "kleur/colors"; import { MockAgent } from "undici"; import SCRIPT_ENTRY from "worker:core/entry"; @@ -908,10 +909,7 @@ export const CORE_PLUGIN: Plugin< ); } ), - containerEngine: getContainerEngine( - options.containerEngine, - options.compatibilityFlags - ), + containerEngine: getContainerEngine(options.containerEngine), }, }); } @@ -1214,9 +1212,6 @@ function getWorkerScript( } } -const DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE = - "cloudflare/proxy-everything:4dc6c7f@sha256:9621ef445ef120409e5d95bbd845ab2fa0f613636b59a01d998f5704f4096ae2"; - /** * Returns the default containerEgressInterceptorImage. It's used for * container network interception for local dev. @@ -1234,8 +1229,7 @@ function getContainerEgressInterceptorImage(): string { * @returns The container engine, defaulting to the default docker socket located on linux/macOS at `unix:///var/run/docker.sock` */ function getContainerEngine( - engineOrSocketPath: Worker_ContainerEngine | string | undefined, - compatibilityFlags?: string[] + engineOrSocketPath: Worker_ContainerEngine | string | undefined ): Worker_ContainerEngine { if (!engineOrSocketPath) { // TODO: workerd does not support win named pipes @@ -1245,13 +1239,10 @@ function getContainerEngine( : "unix:///var/run/docker.sock"; } - // TODO: Once the feature becomes GA, we should remove the experimental requirement. // Egress interceptor is to support direct connectivity between the Container and Workers, // it spawns a container in the same network namespace as the local dev container and // intercepts traffic to redirect to Workerd. - const egressImage = compatibilityFlags?.includes("experimental") - ? getContainerEgressInterceptorImage() - : undefined; + const egressImage = getContainerEgressInterceptorImage(); if (typeof engineOrSocketPath === "string") { return { diff --git a/packages/vite-plugin-cloudflare/src/plugins/dev.ts b/packages/vite-plugin-cloudflare/src/plugins/dev.ts index 62982f334cbb..9554d10f0db7 100644 --- a/packages/vite-plugin-cloudflare/src/plugins/dev.ts +++ b/packages/vite-plugin-cloudflare/src/plugins/dev.ts @@ -208,9 +208,6 @@ export const devPlugin = createPlugin("dev", (ctx) => { onContainerImagePreparationEnd: () => {}, logger: viteDevServer.config.logger, isVite: true, - compatibilityFlags: ctx.allWorkerConfigs.flatMap( - (c) => c.compatibility_flags - ), }); containerImageTags = new Set(containerTagToOptionsMap.keys()); diff --git a/packages/vite-plugin-cloudflare/src/plugins/preview.ts b/packages/vite-plugin-cloudflare/src/plugins/preview.ts index ece7b7edec32..de4ddbb40a36 100644 --- a/packages/vite-plugin-cloudflare/src/plugins/preview.ts +++ b/packages/vite-plugin-cloudflare/src/plugins/preview.ts @@ -49,9 +49,6 @@ export const previewPlugin = createPlugin("preview", (ctx) => { onContainerImagePreparationEnd: () => {}, logger: vitePreviewServer.config.logger, isVite: true, - compatibilityFlags: ctx.allWorkerConfigs.flatMap( - (c) => c.compatibility_flags - ), }); const containerImageTags = new Set(containerTagToOptionsMap.keys()); diff --git a/packages/wrangler/e2e/containers.dev.test.ts b/packages/wrangler/e2e/containers.dev.test.ts index 4fcf1e736eb7..eb99415e5fee 100644 --- a/packages/wrangler/e2e/containers.dev.test.ts +++ b/packages/wrangler/e2e/containers.dev.test.ts @@ -47,7 +47,7 @@ for (const source of imageSource) { name: `${workerName}`, main: "src/index.ts", compatibility_date: "2025-04-03", - compatibility_flags: ["experimental", "enable_ctx_exports"], + compatibility_flags: ["enable_ctx_exports"], containers: [ { image: "./Dockerfile", diff --git a/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts b/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts index 23805b5ea615..33d60ca8f5dc 100644 --- a/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts +++ b/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts @@ -270,7 +270,6 @@ export class LocalRuntimeController extends RuntimeController { }, logger: logger, isVite: false, - compatibilityFlags: data.config.compatibilityFlags, }); if (this.containerBeingBuilt) { this.containerBeingBuilt.abortRequested = false; diff --git a/packages/wrangler/src/api/startDevWorker/MultiworkerRuntimeController.ts b/packages/wrangler/src/api/startDevWorker/MultiworkerRuntimeController.ts index 722e957c4f9d..a3fa386f2eb0 100644 --- a/packages/wrangler/src/api/startDevWorker/MultiworkerRuntimeController.ts +++ b/packages/wrangler/src/api/startDevWorker/MultiworkerRuntimeController.ts @@ -168,7 +168,6 @@ export class MultiworkerRuntimeController extends LocalRuntimeController { }, logger: logger, isVite: false, - compatibilityFlags: data.config.compatibilityFlags, }); if (this.containerBeingBuilt) { this.containerBeingBuilt.abortRequested = false;