diff --git a/.changeset/fix-undici-401-body-source.md b/.changeset/fix-undici-401-body-source.md new file mode 100644 index 0000000000..99d8a48237 --- /dev/null +++ b/.changeset/fix-undici-401-body-source.md @@ -0,0 +1,12 @@ +--- +"miniflare": patch +"wrangler": patch +--- + +fix: avoid "expected non-null body source" error on 401 responses with a request body + +`undici.fetch()` implements the Fetch spec's 401 credential-retry path, which throws `TypeError: fetch failed` with cause `"expected non-null body source"` whenever a request has a `ReadableStream` body and the server responds with HTTP 401. This affected `Miniflare#dispatchFetch()`, `unstable_startWorker().fetch()`, and the internal Cloudflare API client used by Wrangler. + +The fix replaces `undici.fetch()` with `undici.request()` at the affected call sites. `undici.request()` uses the Dispatcher API directly and does not implement the Fetch spec credential-retry path, so the crash cannot occur. The wrapper explicitly replicates the behaviours of `undici.fetch()` that callers rely on: `Accept`/`Accept-Encoding` default headers, transparent decompression of gzip/deflate/brotli responses, redirect following (honouring the `redirect` mode), and correct handling of multiple `set-cookie` headers. + +The workspace-level `pnpm` patch for `undici@7.24.4` that was previously used as a workaround has been removed. diff --git a/package.json b/package.json index d8ba71e347..32d9293625 100644 --- a/package.json +++ b/package.json @@ -85,8 +85,7 @@ "postal-mime": "patches/postal-mime.patch", "youch@4.1.0-beta.10": "patches/youch@4.1.0-beta.10.patch", "@netlify/build-info": "patches/@netlify__build-info.patch", - "buffer-equal-constant-time@1.0.1": "patches/buffer-equal-constant-time@1.0.1.patch", - "undici@7.24.4": "patches/undici@7.24.4.patch" + "buffer-equal-constant-time@1.0.1": "patches/buffer-equal-constant-time@1.0.1.patch" } } } diff --git a/packages/miniflare/src/http/fetch.ts b/packages/miniflare/src/http/fetch.ts index 18137305cc..98f59bfb2d 100644 --- a/packages/miniflare/src/http/fetch.ts +++ b/packages/miniflare/src/http/fetch.ts @@ -1,5 +1,6 @@ import assert from "node:assert"; import http from "node:http"; +import { Readable } from "node:stream"; import { IncomingRequestCfProperties } from "@cloudflare/workers-types/experimental"; import * as undici from "undici"; import { UndiciHeaders } from "undici/types/dispatcher"; @@ -16,7 +17,23 @@ export async function fetch( init?: RequestInit | Request ): Promise { const requestInit = init as RequestInit; - const request = new Request(input, requestInit); + // If input is already a Request-like object and there's no extra init to + // merge, use it directly rather than re-wrapping. Re-wrapping can fail in + // some environments (e.g. vitest forks with mixed ESM/CJS module graphs) + // because undici's internal `webidl.is.Request` brand-check uses class + // identity, and the test's ESM-resolved `Request` may be a different object + // from the CJS-required `Request` inside this bundle. Duck-typing on the + // public `RequestInfo` interface avoids that brittleness. + const isRequestLike = + requestInit === undefined && + typeof input === "object" && + input !== null && + typeof (input as Request).url === "string" && + typeof (input as Request).method === "string" && + typeof (input as Request).headers === "object"; + const request = isRequestLike + ? (input as Request) + : new Request(input, requestInit); // Handle WebSocket upgrades if ( @@ -80,10 +97,163 @@ export async function fetch( return responsePromise; } - const response = await undici.fetch(request, { - dispatcher: requestInit?.dispatcher, + // Wrap in a try/catch and re-throw as TypeError("fetch failed") to match + // the error shape that undici.fetch() produces for dispatcher-level errors + // (e.g. when the request contains an `upgrade` header that undici.request() + // rejects with InvalidArgumentError). + try { + return await fetchViaRequest(request, requestInit?.dispatcher); + } catch (e) { + if (e instanceof TypeError) throw e; + throw new TypeError("fetch failed", { cause: e }); + } +} + +/** + * Perform an HTTP request using `undici.request()` instead of `undici.fetch()`. + * + * `undici.fetch()` implements the Fetch spec's 401 credential-retry path, which + * crashes with "expected non-null body source" when the request body is a + * ReadableStream and the response status is 401. This is tracked upstream at + * https://github.com/nodejs/undici/issues/4910. + * + * `undici.request()` uses the Dispatcher API directly and has no such path. + * To maintain behavioural parity with `undici.fetch()` we explicitly handle: + * - Compression: send `Accept-Encoding: gzip, deflate` and decompress responses + * - Redirects: follow/manual/error modes as per the Fetch spec + * - `set-cookie`: preserve multiple values using `Headers.append()` + */ +async function fetchViaRequest( + request: Request, + dispatcher: undici.Dispatcher | undefined, + redirectsRemaining = 20 +): Promise { + const { + statusCode, + headers: rawHeaders, + body: rawBody, + } = await undici.request(request.url, { + method: request.method, + // Match undici.fetch() behaviour: add Accept-Encoding if the caller + // has not already specified one, so that the workerd entry worker + // applies the same content-encoding logic. + // Match undici.fetch() defaults: it sends `Accept: */*` and + // `Accept-Encoding: gzip, deflate` when the caller hasn't set them. + // These are placed before the spread so the caller's own headers + // take precedence. + headers: { + accept: "*/*", + "accept-encoding": "gzip, deflate", + ...Object.fromEntries(request.headers), + }, + // undici.request() accepts Node.js Readable streams but not web + // ReadableStreams. Convert if necessary. + body: + request.body !== null + ? Readable.fromWeb( + request.body as import("node:stream/web").ReadableStream + ) + : null, + dispatcher, }); - return new Response(response.body, response); + + // Build a proper Headers object. undici.request() returns headers as a plain + // object where `set-cookie` may be an array. Passing a plain object with an + // array value to `new Response()` merges the values incorrectly, losing the + // individual cookie boundaries. Using `Headers.append()` preserves them. + const headers = new undici.Headers(); + for (const [name, value] of Object.entries(rawHeaders)) { + if (Array.isArray(value)) { + for (const v of value) { + headers.append(name, v); + } + } else if (value !== undefined) { + headers.set(name, value); + } + } + + // Decompress response body to match undici.fetch() behaviour. undici.fetch() + // sends Accept-Encoding and transparently decompresses the response body while + // leaving the Content-Encoding header in place. We do the same here so that + // callers (e.g. index.ts dispatchFetch) can apply the same Content-Encoding + // stripping logic without receiving a still-compressed body. + // + // rawBody.body is the web ReadableStream exposed by undici's BodyReadable. + const webStream = rawBody.body as ReadableStream | null | undefined; + const contentEncoding = rawHeaders["content-encoding"]; + let responseBody: ReadableStream | null; + if ( + (contentEncoding === "gzip" || contentEncoding === "x-gzip") && + webStream != null + ) { + responseBody = webStream.pipeThrough(new DecompressionStream("gzip")); + } else if (contentEncoding === "deflate" && webStream != null) { + // Both zlib-wrapped deflate (the common HTTP interpretation) and raw deflate + // are handled by DecompressionStream("deflate") in Node 18+. + responseBody = webStream.pipeThrough(new DecompressionStream("deflate")); + } else if (contentEncoding === "br" && webStream != null) { + // "brotli" is not in the TypeScript CompressionFormat union yet, but + // Node 22+ supports it via DecompressionStream. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + responseBody = webStream.pipeThrough( + new DecompressionStream("brotli" as any) + ); + } else { + responseBody = webStream ?? null; + } + + // Handle redirect modes, matching undici.fetch() behaviour. + const redirectMode = request.redirect ?? "follow"; + const isRedirect = + statusCode >= 300 && + statusCode < 400 && + rawHeaders["location"] !== undefined; + + if (isRedirect) { + if (redirectMode === "error") { + await rawBody.dump(); + throw new TypeError("fetch failed"); + } + if (redirectMode === "manual") { + return new Response(responseBody as AsyncIterable | null, { + status: statusCode, + headers, + }); + } + // redirect === "follow" + if (redirectsRemaining === 0) { + await rawBody.dump(); + throw new TypeError("fetch failed"); + } + const location = new URL( + rawHeaders["location"] as string, + request.url + ).toString(); + await rawBody.dump(); + // For 303 See Other: switch to GET and drop the body + const redirectMethod = statusCode === 303 ? "GET" : request.method; + const redirectBody = statusCode === 303 ? null : request.body; + return fetchViaRequest( + new Request(location, { + method: redirectMethod, + headers: request.headers, + body: redirectBody, + redirect: request.redirect, + } as RequestInit), + dispatcher, + redirectsRemaining - 1 + ); + } + + // Responses with status 204/205 must have a null body (per spec). + // Pass null explicitly to avoid "Invalid response status code" errors. + const noBodyStatus = statusCode === 204 || statusCode === 205; + // undici's BodyInit type doesn't list ReadableStream, but it does accept + // AsyncIterable which ReadableStream satisfies at runtime. + return new Response( + noBodyStatus ? null : (responseBody as AsyncIterable | null), + { status: statusCode, headers } + ); } export type DispatchFetch = ( diff --git a/packages/miniflare/test/http/fetch.spec.ts b/packages/miniflare/test/http/fetch.spec.ts index c5c4df30e7..5ccc2ea2d2 100644 --- a/packages/miniflare/test/http/fetch.spec.ts +++ b/packages/miniflare/test/http/fetch.spec.ts @@ -20,6 +20,44 @@ test("fetch: performs regular http request", async ({ expect }) => { const res = await fetch(upstream); expect(await res.text()).toBe("upstream"); }); +test("fetch: returns 401 response for POST with ReadableStream body without throwing", async ({ + expect, +}) => { + // Regression test for https://github.com/cloudflare/workers-sdk/issues/12967 + // + // undici.fetch() implements the Fetch spec's 401 credential-retry path, which + // crashes with "expected non-null body source" when the request body is a + // ReadableStream (body.source === null) and the response is 401. The fix + // uses undici.request() which bypasses that code path entirely. + // + // This test passes a Request object as input to miniflare's fetch() wrapper + // (the exact pattern used by dispatchFetch / unstable_startWorker), which + // causes the body to flow through as a ReadableStream internally. + const upstream = ( + await useServer((req, res) => { + req.resume(); + res.writeHead(401, { "content-type": "text/plain" }); + res.end("Unauthorized"); + }) + ).http; + + const body = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("hello")); + controller.close(); + }, + }); + // Pass the Request object directly as input — this is the pattern that + // triggered the bug via dispatchFetch/unstable_startWorker. + const request = new Request(upstream, { + method: "POST", + body, + duplex: "half", + }); + const res = await fetch(request); + expect(res.status).toBe(401); + expect(await res.text()).toBe("Unauthorized"); +}); test("fetch: performs http request with form data", async ({ expect }) => { const echoUpstream = ( await useServer((req, res) => { diff --git a/packages/wrangler/src/api/dev.ts b/packages/wrangler/src/api/dev.ts index ed289e02bb..1131e94e57 100644 --- a/packages/wrangler/src/api/dev.ts +++ b/packages/wrangler/src/api/dev.ts @@ -1,6 +1,7 @@ import events from "node:events"; +import { Readable } from "node:stream"; import { getDockerPath } from "@cloudflare/workers-utils"; -import { fetch, Request } from "undici"; +import { request as undiciRequest, Response, Request } from "undici"; import { startDev } from "../dev/start-dev"; import { run } from "../experimental-flags"; import { logger } from "../logger"; @@ -8,7 +9,8 @@ import type { StartDevOptions } from "../dev"; import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli/types"; import type { CfModule, Environment, Rule } from "@cloudflare/workers-utils"; import type { Json } from "miniflare"; -import type { RequestInfo, RequestInit, Response } from "undici"; +import type { ReadableStream } from "node:stream/web"; +import type { RequestInfo, RequestInit } from "undici"; export interface Unstable_DevOptions { config?: string; // Path to .toml configuration file, relative to cwd @@ -245,9 +247,48 @@ export async function unstable_dev( devServer.unregisterHotKeys?.(); }, fetch: async (input?: RequestInfo, init?: RequestInit) => { - return await fetch( - ...parseRequestInput(address, port, input, init, options?.localProtocol) + const [url, forwardInit] = parseRequestInput( + address, + port, + input, + init, + options?.localProtocol ); + // forwardInit is a Request object cast as RequestInit. Using + // undici.fetch(url, requestObject) triggers "expected non-null body + // source" on 401 responses when the body is a ReadableStream, because + // undici.fetch() implements the Fetch spec's 401 credential-retry path + // which checks request.body.source. undici.request() uses the + // Dispatcher API directly and has no such path. + // See: https://github.com/cloudflare/workers-sdk/issues/12967 + const forward = forwardInit as Request; + const { + statusCode, + headers: rawHeaders, + body, + } = await undiciRequest(url.toString(), { + method: forward.method, + headers: Object.fromEntries(forward.headers), + body: + forward.body !== null + ? Readable.fromWeb(forward.body as ReadableStream) + : null, + }); + // Build a Headers object that preserves multiple set-cookie values. + const responseHeaders = new Headers(); + for (const [name, value] of Object.entries(rawHeaders)) { + if (Array.isArray(value)) { + for (const v of value) { + responseHeaders.append(name, v); + } + } else if (value !== undefined) { + responseHeaders.set(name, value); + } + } + return new Response(body.body, { + status: statusCode, + headers: responseHeaders, + }); }, waitUntilExit: async () => { await events.once(devServer.devEnv, "teardown"); diff --git a/packages/wrangler/src/cfetch/internal.ts b/packages/wrangler/src/cfetch/internal.ts index 777819c909..69a0764ec9 100644 --- a/packages/wrangler/src/cfetch/internal.ts +++ b/packages/wrangler/src/cfetch/internal.ts @@ -1,4 +1,5 @@ import assert from "node:assert"; +import { Readable } from "node:stream"; import { APIError, getCloudflareApiBaseUrl, @@ -7,12 +8,20 @@ import { UserError, } from "@cloudflare/workers-utils"; import Cloudflare from "cloudflare"; -import { fetch, FormData, Headers, Request, Response } from "undici"; +import { + fetch, + request as undiciRequest, + FormData, + Headers, + Request, + Response, +} from "undici"; import { version as wranglerVersion } from "../../package.json"; import { logger } from "../logger"; import { loginOrRefreshIfRequired, requireApiToken } from "../user"; import type { ApiCredentials } from "../user"; import type { ComplianceConfig, Message } from "@cloudflare/workers-utils"; +import type { ReadableStream } from "node:stream/web"; import type { URLSearchParams } from "node:url"; import type { HeadersInit, RequestInfo, RequestInit } from "undici"; @@ -73,7 +82,39 @@ export function createCloudflareClient(complianceConfig: ComplianceConfig) { await logRequest(request, init); - const response = await fetch(request.url, request); + // Using undici.fetch(url, requestObject) triggers "expected non-null + // body source" on 401 responses when the body is a ReadableStream, + // because undici.fetch() implements the Fetch spec's 401 + // credential-retry path which checks request.body.source. + // undici.request() uses the Dispatcher API directly and has no such + // path. See: https://github.com/cloudflare/workers-sdk/issues/12967 + const { + statusCode, + headers: rawHeaders, + body, + } = await undiciRequest(request.url, { + method: request.method, + headers: Object.fromEntries(request.headers), + body: + request.body !== null + ? Readable.fromWeb(request.body as ReadableStream) + : null, + }); + // Build a Headers object that preserves multiple set-cookie values. + const responseHeaders = new Headers(); + for (const [name, value] of Object.entries(rawHeaders)) { + if (Array.isArray(value)) { + for (const v of value) { + responseHeaders.append(name, v); + } + } else if (value !== undefined) { + responseHeaders.set(name, value); + } + } + const response = new Response(body.body, { + status: statusCode, + headers: responseHeaders, + }); await logResponse(response); return response; }, diff --git a/patches/undici@7.24.4.patch b/patches/undici@7.24.4.patch deleted file mode 100644 index 8f64ee9e99..0000000000 --- a/patches/undici@7.24.4.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/lib/web/fetch/util.js b/lib/web/fetch/util.js -index fe63cb3a9b07e57198f08d6237d2b7b39bfd057d..78c5be1d3e40278354943517bf3a74ba82e689e5 100644 ---- a/lib/web/fetch/util.js -+++ b/lib/web/fetch/util.js -@@ -1447,8 +1447,12 @@ function includesCredentials (url) { - * @param {object|string} navigable - */ - function isTraversableNavigable (navigable) { -- // TODO -- return true -+ // Node.js has no traversable navigable (no browser UI to prompt for credentials), -+ // so this should always return false. Returning true causes fetch() to enter a -+ // 401 credential-retry path that crashes when the request body's source is null. -+ // See: https://github.com/cloudflare/workers-sdk/issues/12967 -+ // See: https://github.com/nodejs/undici/issues/4910 -+ return false - } - - class EnvironmentSettingsObjectBase { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c77a06b34..f7359caf93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,9 +91,6 @@ patchedDependencies: toucan-js@4.0.0: hash: qxsfpdzvzbhq2ecirbu5xq4vlq path: patches/toucan-js@4.0.0.patch - undici@7.24.4: - hash: eoxacwyrfksebemwxidpujesci - path: patches/undici@7.24.4.patch youch@4.1.0-beta.10: hash: flgmw54jmjdxqmelxigtxg6kum path: patches/youch@4.1.0-beta.10.patch @@ -176,7 +173,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -239,7 +236,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -260,7 +257,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -299,7 +296,7 @@ importers: version: link:../../packages/workers-tsconfig undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -317,7 +314,7 @@ importers: version: 4.20260317.1 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -353,7 +350,7 @@ importers: version: 2.2.0 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -380,7 +377,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -425,7 +422,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -446,7 +443,7 @@ importers: version: link:../shared undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -529,7 +526,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -584,7 +581,7 @@ importers: version: 4.20260317.1 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -617,7 +614,7 @@ importers: version: 1.2.7 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -638,7 +635,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -659,7 +656,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -687,7 +684,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -708,7 +705,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -726,7 +723,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -747,7 +744,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -768,7 +765,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -789,7 +786,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -829,7 +826,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -850,7 +847,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -865,7 +862,7 @@ importers: version: link:../../packages/workers-tsconfig undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -886,7 +883,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -907,7 +904,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -925,7 +922,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -943,7 +940,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -961,7 +958,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -979,7 +976,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -997,7 +994,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1036,7 +1033,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1051,7 +1048,7 @@ importers: version: link:../../packages/workers-tsconfig undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1066,7 +1063,7 @@ importers: version: link:../../packages/workers-tsconfig undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.9.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1272,7 +1269,7 @@ importers: version: link:../shared undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 wrangler: specifier: workspace:* version: link:../../packages/wrangler @@ -1294,7 +1291,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1390,7 +1387,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1411,7 +1408,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1432,7 +1429,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1453,7 +1450,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1474,7 +1471,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1507,7 +1504,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1534,7 +1531,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1555,7 +1552,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1573,7 +1570,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -1754,7 +1751,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vite: specifier: catalog:default version: 8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1) @@ -2004,7 +2001,7 @@ importers: version: 0.34.5 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 workerd: specifier: 1.20260317.1 version: 1.20260317.1 @@ -2259,7 +2256,7 @@ importers: version: 4.0.0(patch_hash=qxsfpdzvzbhq2ecirbu5xq4vlq) undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 wrangler: specifier: workspace:* version: link:../wrangler @@ -3602,7 +3599,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vitest: specifier: catalog:default version: 4.1.0(@opentelemetry/api@1.7.0)(@types/node@22.15.17)(@vitest/ui@4.1.0)(msw@2.12.4(@types/node@22.15.17)(typescript@5.8.3))(vite@8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1)) @@ -3751,7 +3748,7 @@ importers: version: 4.13.0 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 vite: specifier: catalog:default version: 8.0.1(@types/node@22.15.17)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.1) @@ -4176,7 +4173,7 @@ importers: version: 5.8.3 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 update-check: specifier: ^1.5.4 version: 1.5.4 @@ -4230,7 +4227,7 @@ importers: version: 2.2.0 undici: specifier: catalog:default - version: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + version: 7.24.4 wrangler: specifier: workspace:* version: link:../packages/wrangler @@ -22711,7 +22708,7 @@ snapshots: dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.34.5 - undici: 7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci) + undici: 7.24.4 workerd: 1.20260317.1 ws: 8.18.0 youch: 4.1.0-beta.10(patch_hash=flgmw54jmjdxqmelxigtxg6kum) @@ -25407,7 +25404,7 @@ snapshots: dependencies: '@fastify/busboy': 2.1.1 - undici@7.24.4(patch_hash=eoxacwyrfksebemwxidpujesci): {} + undici@7.24.4: {} unenv@2.0.0-rc.24: dependencies: