Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/stupid-lamps-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@react-router/dev": patch
"react-router": patch
---

Add future.unstable_passThroughRequests flag
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See [./AGENTS.md]
3 changes: 3 additions & 0 deletions packages/react-router-dev/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type ValidateConfigFunction = (config: ReactRouterConfig) => string | void;

interface FutureConfig {
unstable_optimizeDeps: boolean;
unstable_passThroughRequests: boolean;
unstable_subResourceIntegrity: boolean;
unstable_trailingSlashAwareDataRequests: boolean;
/**
Expand Down Expand Up @@ -684,6 +685,8 @@ async function resolveConfig({
let future: FutureConfig = {
unstable_optimizeDeps:
userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
unstable_passThroughRequests:
userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
unstable_subResourceIntegrity:
userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
unstable_trailingSlashAwareDataRequests:
Expand Down
50 changes: 45 additions & 5 deletions packages/react-router/__tests__/router/fetchers-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,19 @@ describe("fetchers", () => {
await A.loaders.foo.resolve("A DATA");
expect(A.fetcher.state).toBe("idle");
expect(A.fetcher.data).toBe("A DATA");
expect(A.loaders.foo.stub).toHaveBeenCalledWith({
params: {},
request: new Request("http://localhost/foo", {
signal: A.loaders.foo.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: "/foo",
unstable_path: {
pathname: "/foo",
search: "",
hash: "",
},
context: {},
});
});

it("loader re-fetch", async () => {
Expand Down Expand Up @@ -212,11 +225,19 @@ describe("fetchers", () => {
expect(A.fetcher.formAction).toBe("/foo");
expect(A.fetcher.formData).toEqual(createFormData({ key: "value" }));
expect(A.fetcher.formEncType).toBe("application/x-www-form-urlencoded");
expect(
new URL(
A.loaders.foo.stub.mock.calls[0][0].request.url,
).searchParams.toString(),
).toBe("key=value");
expect(A.loaders.foo.stub).toHaveBeenCalledWith({
params: {},
request: new Request("http://localhost/foo?key=value", {
signal: A.loaders.foo.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: "/foo",
unstable_path: {
pathname: "/foo",
search: "?key=value",
hash: "",
},
context: {},
});

await A.loaders.foo.resolve("A DATA");
expect(A.fetcher.state).toBe("idle");
Expand Down Expand Up @@ -264,6 +285,17 @@ describe("fetchers", () => {
formData: createFormData({ key: "value" }),
});
expect(A.fetcher.state).toBe("submitting");
expect(A.actions.foo.stub).toHaveBeenCalledWith({
params: {},
request: expect.any(Request),
unstable_pattern: "/foo",
unstable_path: {
pathname: "/foo",
search: "",
hash: "",
},
context: {},
});

await A.actions.foo.resolve("A ACTION");
expect(A.fetcher.state).toBe("loading");
Expand Down Expand Up @@ -374,6 +406,7 @@ describe("fetchers", () => {
signal: A.loaders.root.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});
});
Expand Down Expand Up @@ -3375,6 +3408,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -3405,6 +3439,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -3433,6 +3468,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -3461,6 +3497,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -3490,6 +3527,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -3521,6 +3559,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -3551,6 +3590,7 @@ describe("fetchers", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down
17 changes: 16 additions & 1 deletion packages/react-router/__tests__/router/router-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1752,6 +1752,7 @@ describe("a router", () => {
signal: nav.loaders.tasks.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: "/tasks",
unstable_path: { pathname: "/tasks", search: "", hash: "" },
context: {},
});

Expand All @@ -1762,6 +1763,7 @@ describe("a router", () => {
signal: nav2.loaders.tasksId.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: "/tasks/:id",
unstable_path: { pathname: "/tasks/1", search: "", hash: "" },
context: {},
});

Expand All @@ -1772,6 +1774,11 @@ describe("a router", () => {
signal: nav3.loaders.tasks.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: "/tasks",
unstable_path: {
pathname: "/tasks",
search: "?foo=bar",
hash: "#hash",
},
context: {},
});

Expand All @@ -1784,6 +1791,11 @@ describe("a router", () => {
signal: nav4.loaders.tasks.stub.mock.calls[0][0].request.signal,
}),
unstable_pattern: "/tasks",
unstable_path: {
pathname: "/tasks",
search: "?foo=bar",
hash: "#hash",
},
context: {},
});

Expand Down Expand Up @@ -2210,6 +2222,7 @@ describe("a router", () => {
params: {},
request: expect.any(Request),
unstable_pattern: "/tasks",
unstable_path: { pathname: "/tasks", search: "", hash: "" },
context: {},
});

Expand Down Expand Up @@ -2254,7 +2267,8 @@ describe("a router", () => {
expect(nav.actions.tasks.stub).toHaveBeenCalledWith({
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_pattern: "/tasks",
unstable_path: { pathname: "/tasks", search: "?foo=bar", hash: "" },
context: {},
});
// Assert request internals, cannot do a deep comparison above since some
Expand Down Expand Up @@ -2289,6 +2303,7 @@ describe("a router", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down
50 changes: 46 additions & 4 deletions packages/react-router/__tests__/router/ssr-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -837,12 +837,29 @@ describe("ssr", () => {
]);
await query(createRequest("/child"));

expect(rootLoaderStub).toHaveBeenCalledTimes(1);
expect(rootLoaderStub).toHaveBeenCalledWith({
request: new Request("http://localhost/child"),
unstable_pattern: "/child",
unstable_path: { pathname: "/child", search: "", hash: "" },
params: {},
context: {},
});
// @ts-expect-error
let rootLoaderRequest = rootLoaderStub.mock.calls[0][0]?.request;
// @ts-expect-error
let childLoaderRequest = childLoaderStub.mock.calls[0][0]?.request;
expect(rootLoaderRequest.method).toBe("GET");
expect(rootLoaderRequest.url).toBe("http://localhost/child");

expect(childLoaderStub).toHaveBeenCalledTimes(1);
expect(childLoaderStub).toHaveBeenCalledWith({
request: new Request("http://localhost/child"),
unstable_pattern: "/child",
unstable_path: { pathname: "/child", search: "", hash: "" },
params: {},
context: {},
});
// @ts-expect-error
let childLoaderRequest = childLoaderStub.mock.calls[0][0]?.request;
expect(childLoaderRequest.method).toBe("GET");
expect(childLoaderRequest.url).toBe("http://localhost/child");
});
Expand Down Expand Up @@ -874,6 +891,14 @@ describe("ssr", () => {
}),
);

expect(actionStub).toHaveBeenCalledTimes(1);
expect(actionStub).toHaveBeenCalledWith({
request: expect.any(Request),
unstable_pattern: "/child",
unstable_path: { pathname: "/child", search: "", hash: "" },
params: {},
context: {},
});
// @ts-expect-error
let actionRequest = actionStub.mock.calls[0][0]?.request;
expect(actionRequest.method).toBe("POST");
Expand All @@ -883,14 +908,31 @@ describe("ssr", () => {
);
expect((await actionRequest.formData()).get("key")).toBe("value");

expect(rootLoaderStub).toHaveBeenCalledTimes(1);
expect(rootLoaderStub).toHaveBeenCalledWith({
request: expect.any(Request),
unstable_pattern: "/child",
unstable_path: { pathname: "/child", search: "", hash: "" },
params: {},
context: {},
});
// @ts-expect-error
let rootLoaderRequest = rootLoaderStub.mock.calls[0][0]?.request;
// @ts-expect-error
let childLoaderRequest = childLoaderStub.mock.calls[0][0]?.request;
expect(rootLoaderRequest.method).toBe("GET");
expect(rootLoaderRequest.url).toBe("http://localhost/child");
expect(rootLoaderRequest.headers.get("test")).toBe("value");
expect(await rootLoaderRequest.text()).toBe("");

expect(childLoaderStub).toHaveBeenCalledTimes(1);
expect(childLoaderStub).toHaveBeenCalledWith({
request: expect.any(Request),
unstable_pattern: "/child",
unstable_path: { pathname: "/child", search: "", hash: "" },
params: {},
context: {},
});
// @ts-expect-error
let childLoaderRequest = childLoaderStub.mock.calls[0][0]?.request;
expect(childLoaderRequest.method).toBe("GET");
expect(childLoaderRequest.url).toBe("http://localhost/child");
expect(childLoaderRequest.headers.get("test")).toBe("value");
Expand Down
6 changes: 6 additions & 0 deletions packages/react-router/__tests__/router/submission-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ describe("submissions", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -984,6 +985,7 @@ describe("submissions", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -1017,6 +1019,7 @@ describe("submissions", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -1122,6 +1125,7 @@ describe("submissions", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -1161,6 +1165,7 @@ describe("submissions", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down Expand Up @@ -1197,6 +1202,7 @@ describe("submissions", () => {
params: {},
request: expect.any(Request),
unstable_pattern: expect.any(String),
unstable_path: expect.any(Object),
context: {},
});

Expand Down
3 changes: 2 additions & 1 deletion packages/react-router/lib/dom-export/hydrated-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ function createHydratedRouter({
unstable_instrumentations,
mapRouteProperties,
future: {
middleware: ssrInfo.context.future.v8_middleware,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no client-side middleware future flag since it was an opt-in API, so this wasn't doing anything

unstable_passThroughRequests:
ssrInfo.context.future.unstable_passThroughRequests,
},
dataStrategy: getTurboStreamSingleFetchDataStrategy(
() => router,
Expand Down
1 change: 1 addition & 0 deletions packages/react-router/lib/dom/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ export function createStaticRouter(
get future() {
return {
v8_middleware: false,
unstable_passThroughRequests: false,
...opts?.future,
};
},
Expand Down
1 change: 1 addition & 0 deletions packages/react-router/lib/dom/ssr/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface EntryContext extends FrameworkContextObject {
}

export interface FutureConfig {
unstable_passThroughRequests: boolean;
unstable_subResourceIntegrity: boolean;
unstable_trailingSlashAwareDataRequests: boolean;
v8_middleware: boolean;
Expand Down
2 changes: 2 additions & 0 deletions packages/react-router/lib/dom/ssr/routes-test-stub.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ export function createRoutesStub(
if (routerRef.current == null) {
frameworkContextRef.current = {
future: {
unstable_passThroughRequests:
future?.unstable_passThroughRequests === true,
unstable_subResourceIntegrity:
future?.unstable_subResourceIntegrity === true,
v8_middleware: future?.v8_middleware === true,
Expand Down
Loading
Loading