Skip to content

Commit 776d3d5

Browse files
fix: pass in request when requestMiddleware is used in combination wi… (#5390)
1 parent 8d3478c commit 776d3d5

File tree

9 files changed

+160
-15
lines changed

9 files changed

+160
-15
lines changed

e2e/react-start/server-functions/src/routeTree.gen.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { Route as FormdataRedirectIndexRouteImport } from './routes/formdata-red
2727
import { Route as FactoryIndexRouteImport } from './routes/factory/index'
2828
import { Route as CookiesIndexRouteImport } from './routes/cookies/index'
2929
import { Route as MiddlewareSendServerFnRouteImport } from './routes/middleware/send-serverFn'
30+
import { Route as MiddlewareRequestMiddlewareRouteImport } from './routes/middleware/request-middleware'
3031
import { Route as MiddlewareClientMiddlewareRouterRouteImport } from './routes/middleware/client-middleware-router'
3132
import { Route as CookiesSetRouteImport } from './routes/cookies/set'
3233
import { Route as FormdataRedirectTargetNameRouteImport } from './routes/formdata-redirect/target.$name'
@@ -121,6 +122,12 @@ const MiddlewareSendServerFnRoute = MiddlewareSendServerFnRouteImport.update({
121122
path: '/middleware/send-serverFn',
122123
getParentRoute: () => rootRouteImport,
123124
} as any)
125+
const MiddlewareRequestMiddlewareRoute =
126+
MiddlewareRequestMiddlewareRouteImport.update({
127+
id: '/middleware/request-middleware',
128+
path: '/middleware/request-middleware',
129+
getParentRoute: () => rootRouteImport,
130+
} as any)
124131
const MiddlewareClientMiddlewareRouterRoute =
125132
MiddlewareClientMiddlewareRouterRouteImport.update({
126133
id: '/middleware/client-middleware-router',
@@ -155,6 +162,7 @@ export interface FileRoutesByFullPath {
155162
'/submit-post-formdata': typeof SubmitPostFormdataRoute
156163
'/cookies/set': typeof CookiesSetRoute
157164
'/middleware/client-middleware-router': typeof MiddlewareClientMiddlewareRouterRoute
165+
'/middleware/request-middleware': typeof MiddlewareRequestMiddlewareRoute
158166
'/middleware/send-serverFn': typeof MiddlewareSendServerFnRoute
159167
'/cookies': typeof CookiesIndexRoute
160168
'/factory': typeof FactoryIndexRoute
@@ -178,6 +186,7 @@ export interface FileRoutesByTo {
178186
'/submit-post-formdata': typeof SubmitPostFormdataRoute
179187
'/cookies/set': typeof CookiesSetRoute
180188
'/middleware/client-middleware-router': typeof MiddlewareClientMiddlewareRouterRoute
189+
'/middleware/request-middleware': typeof MiddlewareRequestMiddlewareRoute
181190
'/middleware/send-serverFn': typeof MiddlewareSendServerFnRoute
182191
'/cookies': typeof CookiesIndexRoute
183192
'/factory': typeof FactoryIndexRoute
@@ -202,6 +211,7 @@ export interface FileRoutesById {
202211
'/submit-post-formdata': typeof SubmitPostFormdataRoute
203212
'/cookies/set': typeof CookiesSetRoute
204213
'/middleware/client-middleware-router': typeof MiddlewareClientMiddlewareRouterRoute
214+
'/middleware/request-middleware': typeof MiddlewareRequestMiddlewareRoute
205215
'/middleware/send-serverFn': typeof MiddlewareSendServerFnRoute
206216
'/cookies/': typeof CookiesIndexRoute
207217
'/factory/': typeof FactoryIndexRoute
@@ -227,6 +237,7 @@ export interface FileRouteTypes {
227237
| '/submit-post-formdata'
228238
| '/cookies/set'
229239
| '/middleware/client-middleware-router'
240+
| '/middleware/request-middleware'
230241
| '/middleware/send-serverFn'
231242
| '/cookies'
232243
| '/factory'
@@ -250,6 +261,7 @@ export interface FileRouteTypes {
250261
| '/submit-post-formdata'
251262
| '/cookies/set'
252263
| '/middleware/client-middleware-router'
264+
| '/middleware/request-middleware'
253265
| '/middleware/send-serverFn'
254266
| '/cookies'
255267
| '/factory'
@@ -273,6 +285,7 @@ export interface FileRouteTypes {
273285
| '/submit-post-formdata'
274286
| '/cookies/set'
275287
| '/middleware/client-middleware-router'
288+
| '/middleware/request-middleware'
276289
| '/middleware/send-serverFn'
277290
| '/cookies/'
278291
| '/factory/'
@@ -297,6 +310,7 @@ export interface RootRouteChildren {
297310
SubmitPostFormdataRoute: typeof SubmitPostFormdataRoute
298311
CookiesSetRoute: typeof CookiesSetRoute
299312
MiddlewareClientMiddlewareRouterRoute: typeof MiddlewareClientMiddlewareRouterRoute
313+
MiddlewareRequestMiddlewareRoute: typeof MiddlewareRequestMiddlewareRoute
300314
MiddlewareSendServerFnRoute: typeof MiddlewareSendServerFnRoute
301315
CookiesIndexRoute: typeof CookiesIndexRoute
302316
FactoryIndexRoute: typeof FactoryIndexRoute
@@ -433,6 +447,13 @@ declare module '@tanstack/react-router' {
433447
preLoaderRoute: typeof MiddlewareSendServerFnRouteImport
434448
parentRoute: typeof rootRouteImport
435449
}
450+
'/middleware/request-middleware': {
451+
id: '/middleware/request-middleware'
452+
path: '/middleware/request-middleware'
453+
fullPath: '/middleware/request-middleware'
454+
preLoaderRoute: typeof MiddlewareRequestMiddlewareRouteImport
455+
parentRoute: typeof rootRouteImport
456+
}
436457
'/middleware/client-middleware-router': {
437458
id: '/middleware/client-middleware-router'
438459
path: '/middleware/client-middleware-router'
@@ -473,6 +494,7 @@ const rootRouteChildren: RootRouteChildren = {
473494
SubmitPostFormdataRoute: SubmitPostFormdataRoute,
474495
CookiesSetRoute: CookiesSetRoute,
475496
MiddlewareClientMiddlewareRouterRoute: MiddlewareClientMiddlewareRouterRoute,
497+
MiddlewareRequestMiddlewareRoute: MiddlewareRequestMiddlewareRoute,
476498
MiddlewareSendServerFnRoute: MiddlewareSendServerFnRoute,
477499
CookiesIndexRoute: CookiesIndexRoute,
478500
FactoryIndexRoute: FactoryIndexRoute,

e2e/react-start/server-functions/src/routes/middleware/index.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ function RouteComponent() {
2424
Client Middleware can send server function reference in context
2525
</Route.Link>
2626
</li>
27+
<li>
28+
<Route.Link
29+
to="./request-middleware"
30+
data-testid="request-middleware-link"
31+
reloadDocument={true}
32+
>
33+
Request Middleware in combination with server function
34+
</Route.Link>
35+
</li>
2736
</ul>
2837
</div>
2938
)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
import { createMiddleware, createServerFn } from '@tanstack/react-start'
3+
import { getRequest } from '@tanstack/react-start/server'
4+
import React from 'react'
5+
6+
const requestMiddleware = createMiddleware({ type: 'request' }).server(
7+
async ({ next, request }) => {
8+
return next({
9+
context: {
10+
requestParam: request.url,
11+
requestFunc: getRequest().url,
12+
},
13+
})
14+
},
15+
)
16+
17+
const serverFn = createServerFn()
18+
.middleware([requestMiddleware])
19+
.handler(async ({ context: { requestParam, requestFunc } }) => {
20+
return { requestParam, requestFunc }
21+
})
22+
23+
export const Route = createFileRoute('/middleware/request-middleware')({
24+
loader: () => serverFn(),
25+
component: RouteComponent,
26+
})
27+
28+
function RouteComponent() {
29+
const loaderData = Route.useLoaderData()
30+
31+
const [clientData, setClientData] = React.useState<typeof loaderData | null>(
32+
null,
33+
)
34+
35+
return (
36+
<div>
37+
<h2>Request Middleware in combination with server function</h2>
38+
<br />
39+
<div>
40+
<div data-testid="loader-data">
41+
<h3>Loader Data</h3>Request Param:
42+
<div data-testid="loader-data-request-param">
43+
{loaderData.requestParam}
44+
</div>
45+
Request Func:
46+
<div data-testid="loader-data-request-func">
47+
{loaderData.requestFunc}
48+
</div>
49+
</div>
50+
<br />
51+
<div data-testid="client-call">
52+
<button
53+
data-testid="client-call-button"
54+
onClick={async () => {
55+
const data = await serverFn()
56+
setClientData(data)
57+
}}
58+
>
59+
Call server function from client
60+
</button>
61+
</div>
62+
<br />
63+
<div data-testid="client-data-container">
64+
<h3>Client Data</h3>
65+
{clientData ? (
66+
<div data-testid="client-data">
67+
Request Param:
68+
<div data-testid="client-data-request-param">
69+
{clientData.requestParam}
70+
</div>
71+
Request Func:
72+
<div data-testid="client-data-request-func">
73+
{clientData.requestFunc}
74+
</div>
75+
</div>
76+
) : (
77+
' Loading ...'
78+
)}
79+
</div>
80+
</div>
81+
</div>
82+
)
83+
}

e2e/react-start/server-functions/tests/server-functions.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,32 @@ test.describe('middleware', () => {
382382
await runTest(page)
383383
})
384384
})
385+
386+
test('server function in combination with request middleware', async ({
387+
page,
388+
}) => {
389+
await page.goto('/middleware/request-middleware')
390+
391+
await page.waitForLoadState('networkidle')
392+
393+
async function checkEqual(prefix: string) {
394+
const requestParam = await page
395+
.getByTestId(`${prefix}-data-request-param`)
396+
.textContent()
397+
expect(requestParam).not.toBe('')
398+
const requestFunc = await page
399+
.getByTestId(`${prefix}-data-request-func`)
400+
.textContent()
401+
expect(requestParam).toBe(requestFunc)
402+
}
403+
404+
await checkEqual('loader')
405+
406+
await page.getByTestId('client-call-button').click()
407+
await page.waitForLoadState('networkidle')
408+
409+
await checkEqual('client')
410+
})
385411
})
386412

387413
test('factory', async ({ page }) => {

packages/start-client-core/src/createServerFn.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { isNotFound, isRedirect } from '@tanstack/router-core'
22
import { mergeHeaders } from '@tanstack/router-core/ssr/client'
33

44
import { TSS_SERVER_FUNCTION_FACTORY } from './constants'
5-
import { getServerContextAfterGlobalMiddlewares } from './getServerContextAfterGlobalMiddlewares'
65
import { getStartOptions } from './getStartOptions'
6+
import { getStartContextServerOnly } from './getStartContextServerOnly'
77
import type { TSS_SERVER_FUNCTION } from './constants'
88
import type {
99
AnyValidator,
@@ -130,8 +130,9 @@ export const createServerFn: CreateServerFn<Register> = (options, __opts) => {
130130
// The extracted function on the server-side calls
131131
// this function
132132
__executeServer: async (opts: any, signal: AbortSignal) => {
133+
const startContext = getStartContextServerOnly()
133134
const serverContextAfterGlobalMiddlewares =
134-
getServerContextAfterGlobalMiddlewares()
135+
startContext.contextAfterGlobalMiddlewares
135136
const ctx = {
136137
...extractedFn,
137138
...opts,
@@ -140,6 +141,7 @@ export const createServerFn: CreateServerFn<Register> = (options, __opts) => {
140141
...opts.context,
141142
},
142143
signal,
144+
request: startContext.request,
143145
}
144146

145147
return executeMiddleware(resolvedMiddleware, 'server', ctx).then(
@@ -199,11 +201,16 @@ export async function executeMiddleware(
199201
)
200202
}
201203

202-
const middlewareFn = (
203-
env === 'client' && 'client' in nextMiddleware.options
204-
? nextMiddleware.options.client
205-
: nextMiddleware.options.server
206-
) as MiddlewareFn | undefined
204+
let middlewareFn: MiddlewareFn | undefined = undefined
205+
if (env === 'client') {
206+
if ('client' in nextMiddleware.options) {
207+
middlewareFn = nextMiddleware.options.client as MiddlewareFn | undefined
208+
}
209+
}
210+
// env === 'server'
211+
else if ('server' in nextMiddleware.options) {
212+
middlewareFn = nextMiddleware.options.server as MiddlewareFn | undefined
213+
}
207214

208215
if (middlewareFn) {
209216
// Execute the middleware

packages/start-client-core/src/getServerContextAfterGlobalMiddlewares.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { getStartContext } from '@tanstack/start-storage-context'
2+
import { createServerOnlyFn } from './envOnly'
3+
4+
export const getStartContextServerOnly = createServerOnlyFn(getStartContext)

packages/start-server-core/src/createStartHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ export function createStartHandler<TRegister = Register>(
170170
getRouter,
171171
startOptions,
172172
contextAfterGlobalMiddlewares: context,
173+
request,
173174
},
174175
async () => {
175176
try {

packages/start-storage-context/src/async-local-storage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { Awaitable, RegisteredRouter } from '@tanstack/router-core'
33

44
export interface StartStorageContext {
55
getRouter: () => Awaitable<RegisteredRouter>
6-
6+
request: Request
77
// TODO type this properly
88
startOptions: /* AnyStartInstanceOptions*/ any
99

0 commit comments

Comments
 (0)