fix: preserve proxied HTTP responses

This commit is contained in:
Peter Steinberger
2026-07-09 16:04:46 +01:00
parent ea486effba
commit be22623699
3 changed files with 13 additions and 9 deletions
+1
View File
@@ -10,6 +10,7 @@
### Fixes
- CLI: accept npm 12's package-keyed `npm pack --json` output when building ClawPacks while retaining compatibility with earlier npm array output.
- Web/API: preserve JSON, SSR, and OG responses through the Convex proxy after the H3 response-wrapper update.
## 0.23.1 - 2026-06-29
+2
View File
@@ -72,6 +72,8 @@ describe("Convex HTTP proxy", () => {
VITE_CONVEX_URL: "https://preview-branch-123.convex.cloud",
});
expect(response).toBeInstanceOf(Response);
await expect(response.json()).resolves.toEqual({ ok: true });
expect(fetchMock).toHaveBeenCalledWith(
"https://preview-branch-123.convex.site/api/v1/skills/demo?include=latest",
expect.objectContaining({ method: "GET" }),
+10 -9
View File
@@ -1,10 +1,4 @@
import {
defineEventHandler,
getRequestURL,
proxyRequest,
type H3Event,
type HTTPResponse,
} from "h3";
import { defineEventHandler, getRequestURL, proxyRequest, type H3Event } from "h3";
import { convexDeploymentName, resolveConvexSiteUrl } from "../src/lib/convexDeploymentUrl";
type ProxyEnv = {
@@ -59,7 +53,7 @@ export function buildConvexProxyTarget(pathAndQuery: string, env: ProxyEnv) {
export async function proxyConvexRequest(
event: H3Event,
env: ProxyEnv = resolveConvexProxyEnv(process.env),
): Promise<HTTPResponse | Response> {
): Promise<Response> {
if (!isConvexProxyMethodAllowed(event.req.method, env)) {
return new Response("Disposable previews are read-only.", {
status: 405,
@@ -73,7 +67,14 @@ export async function proxyConvexRequest(
const requestUrl = getRequestURL(event);
const target = buildConvexProxyTarget(`${requestUrl.pathname}${requestUrl.search}`, env);
const response = await proxyRequest(event, target);
const proxied = await proxyRequest(event, target);
// H3's HTTPResponse is not guaranteed to share Nitro's bundled class identity.
// Normalize it before crossing that boundary or Nitro can stringify the wrapper.
const response = new Response(proxied.body, {
status: proxied.status,
statusText: proxied.statusText,
headers: proxied.headers,
});
if (isPreviewFrontend(env)) {
const deployment = convexDeploymentName(target);
if (deployment) response.headers.set("X-ClawHub-Preview-Backend", deployment);