npm-tanstack--react-start

Description
Modern full-stack React framework with SSR, streaming, server functions, and API routes powered by TanStack Router and Vite.
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-tanstack--react-start@1.132.0

middleware.md docs/

1
# Middleware
2
3
The middleware system provides composable functions for server functions to handle validation, authentication, logging, and other cross-cutting concerns. Middleware can be chained together and applied to server functions for enhanced functionality.
4
5
## Capabilities
6
7
### Create Middleware
8
9
Creates middleware that can be applied to server functions for request/response processing.
10
11
```typescript { .api }
12
/**
13
* Creates middleware with optional configuration
14
* @param options - Configuration options including middleware type
15
* @returns CreateMiddlewareResult for chaining additional configuration
16
*/
17
function createMiddleware<TType extends MiddlewareType>(
18
options?: { type?: TType }
19
): CreateMiddlewareResult<{}, TType>;
20
21
interface CreateMiddlewareResult<TRegister, TType> {
22
/** Add middleware function to the chain */
23
middleware<T>(middleware: T): CreateMiddlewareResult<TRegister & T, TType>;
24
25
/** Add input validation to the middleware */
26
inputValidator<T>(validator: T): CreateMiddlewareResult<TRegister & T, TType>;
27
28
/** Add client-side processing */
29
client<T>(client: T): CreateMiddlewareResult<TRegister & T, TType>;
30
31
/** Add server-side processing */
32
server<T>(server: T): CreateMiddlewareResult<TRegister & T, TType>;
33
}
34
35
type MiddlewareType = 'request' | 'function';
36
```
37
38
**Usage Examples:**
39
40
```typescript
41
import { createMiddleware, createServerFn } from "@tanstack/react-start";
42
43
// Authentication middleware
44
const authMiddleware = createMiddleware()
45
.server(async (input, { request }) => {
46
const token = request.headers.get('Authorization');
47
if (!token) throw new Error('Unauthorized');
48
49
const user = await verifyToken(token);
50
return { ...input, user };
51
});
52
53
// Validation middleware
54
const validateUserInput = createMiddleware()
55
.inputValidator((data: unknown) => {
56
if (!data || typeof data !== 'object') {
57
throw new Error('Invalid input');
58
}
59
return data as { name: string; email: string };
60
});
61
62
// Apply middleware to server function
63
const createUser = createServerFn({ method: 'POST' })
64
.middleware(authMiddleware)
65
.middleware(validateUserInput)
66
.handler(async ({ name, email, user }) => {
67
// Handler receives validated input + auth context
68
return await db.user.create({
69
data: { name, email, createdBy: user.id }
70
});
71
});
72
```
73
74
### Function Middleware
75
76
Middleware specifically designed for server functions with type-safe parameter passing.
77
78
```typescript { .api }
79
interface FunctionMiddleware<TInput, TOutput, TContext = {}> {
80
(input: TInput, context: FunctionMiddlewareContext<TContext>):
81
Promise<TOutput> | TOutput;
82
}
83
84
interface FunctionMiddlewareContext<T = {}> {
85
/** Current request object */
86
request: Request;
87
/** Response headers */
88
headers: Headers;
89
/** Additional context data */
90
context: T;
91
/** Continue to next middleware */
92
next: () => Promise<any>;
93
}
94
95
interface FunctionMiddlewareOptions<
96
TRegister,
97
TResponse,
98
TMiddlewares,
99
TInputValidator,
100
THandler
101
> {
102
middleware?: TMiddlewares;
103
inputValidator?: TInputValidator;
104
handler?: THandler;
105
}
106
```
107
108
**Usage Examples:**
109
110
```typescript
111
import { createMiddleware } from "@tanstack/react-start";
112
113
// Logging middleware
114
const logMiddleware = createMiddleware()
115
.server(async (input, { request, next }) => {
116
console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`);
117
const start = Date.now();
118
119
const result = await next();
120
121
console.log(`Request completed in ${Date.now() - start}ms`);
122
return result;
123
});
124
125
// Rate limiting middleware
126
const rateLimitMiddleware = createMiddleware()
127
.server(async (input, { request, next }) => {
128
const ip = request.headers.get('x-forwarded-for') || 'unknown';
129
const key = `rate-limit:${ip}`;
130
131
const requests = await redis.incr(key);
132
if (requests === 1) {
133
await redis.expire(key, 60); // 1 minute window
134
}
135
136
if (requests > 100) {
137
throw new Error('Rate limit exceeded');
138
}
139
140
return await next();
141
});
142
```
143
144
### Request Middleware
145
146
Middleware that operates at the request level before server functions are invoked.
147
148
```typescript { .api }
149
interface RequestMiddleware<TContext = {}> {
150
(request: Request, context: RequestMiddlewareContext<TContext>):
151
Promise<Response | void> | Response | void;
152
}
153
154
interface RequestMiddlewareContext<T = {}> {
155
/** Additional context data */
156
context: T;
157
/** Continue to next middleware */
158
next: () => Promise<Response>;
159
}
160
161
interface RequestMiddlewareOptions<
162
TRegister,
163
TMiddlewares,
164
TServer
165
> {
166
type: 'request';
167
middleware?: TMiddlewares;
168
server?: TServer;
169
}
170
```
171
172
### Middleware Utilities
173
174
Helper functions for working with middleware chains and validation.
175
176
```typescript { .api }
177
/**
178
* Flattens nested middleware arrays into a single array
179
* @param middlewares - Array of middleware to flatten
180
* @returns Flattened middleware array
181
*/
182
function flattenMiddlewares(
183
middlewares: AnyFunctionMiddleware[]
184
): AnyFunctionMiddleware[];
185
186
/**
187
* Executes a middleware chain
188
* @param middlewares - The middleware chain to execute
189
* @param context - The execution context
190
* @returns Result of middleware execution
191
*/
192
function executeMiddleware<T>(
193
middlewares: AnyFunctionMiddleware[],
194
context: T
195
): Promise<T>;
196
197
/**
198
* Apply middleware to a function
199
* @param middleware - The middleware to apply
200
* @param fn - The function to wrap with middleware
201
* @returns Enhanced function with middleware
202
*/
203
function applyMiddleware<T>(
204
middleware: AnyFunctionMiddleware[],
205
fn: T
206
): T;
207
208
/**
209
* Execute validation logic
210
* @param validator - The validator to execute
211
* @param input - The input to validate
212
* @returns Validated output
213
*/
214
function execValidator<T, U>(
215
validator: Validator<T, U>,
216
input: T
217
): U;
218
```
219
220
### Middleware Composition
221
222
```typescript { .api }
223
interface IntersectAllValidatorInputs<T extends ReadonlyArray<any>> {
224
// Type helper for combining validator inputs
225
}
226
227
interface IntersectAllValidatorOutputs<T extends ReadonlyArray<any>> {
228
// Type helper for combining validator outputs
229
}
230
231
interface AssignAllMiddleware<T extends ReadonlyArray<any>> {
232
// Type helper for combining middleware types
233
}
234
```
235
236
## Advanced Patterns
237
238
### Conditional Middleware
239
240
```typescript
241
import { createMiddleware } from "@tanstack/react-start";
242
243
const conditionalAuth = createMiddleware()
244
.server(async (input, { request, next }) => {
245
const publicPaths = ['/health', '/api/public'];
246
const path = new URL(request.url).pathname;
247
248
if (publicPaths.includes(path)) {
249
return await next();
250
}
251
252
// Apply authentication for protected paths
253
const token = request.headers.get('Authorization');
254
if (!token) throw new Error('Authentication required');
255
256
const user = await verifyToken(token);
257
return { ...input, user };
258
});
259
```
260
261
### Error Handling Middleware
262
263
```typescript
264
import { createMiddleware } from "@tanstack/react-start";
265
266
const errorHandlerMiddleware = createMiddleware()
267
.server(async (input, { next }) => {
268
try {
269
return await next();
270
} catch (error) {
271
console.error('Server function error:', error);
272
273
if (error.message === 'Unauthorized') {
274
throw new Response('Unauthorized', { status: 401 });
275
}
276
277
throw new Response('Internal Server Error', { status: 500 });
278
}
279
});
280
```
281
282
## Types
283
284
```typescript { .api }
285
// Middleware type definitions
286
type MiddlewareType = 'request' | 'function';
287
288
interface AnyFunctionMiddleware {
289
type: 'function';
290
middleware: (...args: any[]) => any;
291
}
292
293
interface AnyRequestMiddleware {
294
type: 'request';
295
middleware: (request: Request, context: any) => any;
296
}
297
298
// Function middleware types
299
interface FunctionMiddlewareWithTypes<
300
TRegister,
301
TResponse,
302
TMiddlewares,
303
TInputValidator,
304
THandler
305
> {
306
middleware?: TMiddlewares;
307
inputValidator?: TInputValidator;
308
handler?: THandler;
309
}
310
311
interface FunctionMiddlewareValidator<T, U> {
312
(input: T): U;
313
}
314
315
interface FunctionMiddlewareServer<TInput, TOutput> {
316
(input: TInput, context: ServerFnCtx): Promise<TOutput> | TOutput;
317
}
318
319
interface FunctionMiddlewareClient<TInput, TOutput> {
320
(input: TInput): Promise<TOutput> | TOutput;
321
}
322
323
// Request middleware types
324
interface RequestMiddlewareWithTypes<
325
TRegister,
326
TMiddlewares,
327
TServer
328
> {
329
type: 'request';
330
middleware?: TMiddlewares;
331
server?: TServer;
332
}
333
334
interface RequestServerFn<T> {
335
(request: Request, context: T): Promise<Response | void> | Response | void;
336
}
337
338
// Middleware context types
339
interface FunctionMiddlewareAfterMiddleware<T> {
340
context: T;
341
next: () => Promise<any>;
342
}
343
344
interface RequestMiddlewareAfterMiddleware<T> {
345
context: T;
346
next: () => Promise<Response>;
347
}
348
349
// Validator types
350
interface Validator<TInput, TOutput> {
351
(input: TInput): TOutput;
352
}
353
354
// Context assignment helpers
355
interface AssignAllClientContextBeforeNext<T extends ReadonlyArray<any>> {
356
// Type helper for client context assignment
357
}
358
359
interface FunctionClientResultWithContext<T, U> {
360
result: T;
361
context: U;
362
}
363
364
interface FunctionServerResultWithContext<T, U> {
365
result: T;
366
context: U;
367
}
368
```