CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tanstack--react-start

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

Pending
Overview
Eval results
Files

middleware.mddocs/

Middleware

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.

Capabilities

Create Middleware

Creates middleware that can be applied to server functions for request/response processing.

/**
 * Creates middleware with optional configuration
 * @param options - Configuration options including middleware type
 * @returns CreateMiddlewareResult for chaining additional configuration
 */
function createMiddleware<TType extends MiddlewareType>(
  options?: { type?: TType }
): CreateMiddlewareResult<{}, TType>;

interface CreateMiddlewareResult<TRegister, TType> {
  /** Add middleware function to the chain */
  middleware<T>(middleware: T): CreateMiddlewareResult<TRegister & T, TType>;

  /** Add input validation to the middleware */
  inputValidator<T>(validator: T): CreateMiddlewareResult<TRegister & T, TType>;

  /** Add client-side processing */
  client<T>(client: T): CreateMiddlewareResult<TRegister & T, TType>;

  /** Add server-side processing */
  server<T>(server: T): CreateMiddlewareResult<TRegister & T, TType>;
}

type MiddlewareType = 'request' | 'function';

Usage Examples:

import { createMiddleware, createServerFn } from "@tanstack/react-start";

// Authentication middleware
const authMiddleware = createMiddleware()
  .server(async (input, { request }) => {
    const token = request.headers.get('Authorization');
    if (!token) throw new Error('Unauthorized');

    const user = await verifyToken(token);
    return { ...input, user };
  });

// Validation middleware
const validateUserInput = createMiddleware()
  .inputValidator((data: unknown) => {
    if (!data || typeof data !== 'object') {
      throw new Error('Invalid input');
    }
    return data as { name: string; email: string };
  });

// Apply middleware to server function
const createUser = createServerFn({ method: 'POST' })
  .middleware(authMiddleware)
  .middleware(validateUserInput)
  .handler(async ({ name, email, user }) => {
    // Handler receives validated input + auth context
    return await db.user.create({
      data: { name, email, createdBy: user.id }
    });
  });

Function Middleware

Middleware specifically designed for server functions with type-safe parameter passing.

interface FunctionMiddleware<TInput, TOutput, TContext = {}> {
  (input: TInput, context: FunctionMiddlewareContext<TContext>):
    Promise<TOutput> | TOutput;
}

interface FunctionMiddlewareContext<T = {}> {
  /** Current request object */
  request: Request;
  /** Response headers */
  headers: Headers;
  /** Additional context data */
  context: T;
  /** Continue to next middleware */
  next: () => Promise<any>;
}

interface FunctionMiddlewareOptions<
  TRegister,
  TResponse,
  TMiddlewares,
  TInputValidator,
  THandler
> {
  middleware?: TMiddlewares;
  inputValidator?: TInputValidator;
  handler?: THandler;
}

Usage Examples:

import { createMiddleware } from "@tanstack/react-start";

// Logging middleware
const logMiddleware = createMiddleware()
  .server(async (input, { request, next }) => {
    console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`);
    const start = Date.now();

    const result = await next();

    console.log(`Request completed in ${Date.now() - start}ms`);
    return result;
  });

// Rate limiting middleware
const rateLimitMiddleware = createMiddleware()
  .server(async (input, { request, next }) => {
    const ip = request.headers.get('x-forwarded-for') || 'unknown';
    const key = `rate-limit:${ip}`;

    const requests = await redis.incr(key);
    if (requests === 1) {
      await redis.expire(key, 60); // 1 minute window
    }

    if (requests > 100) {
      throw new Error('Rate limit exceeded');
    }

    return await next();
  });

Request Middleware

Middleware that operates at the request level before server functions are invoked.

interface RequestMiddleware<TContext = {}> {
  (request: Request, context: RequestMiddlewareContext<TContext>):
    Promise<Response | void> | Response | void;
}

interface RequestMiddlewareContext<T = {}> {
  /** Additional context data */
  context: T;
  /** Continue to next middleware */
  next: () => Promise<Response>;
}

interface RequestMiddlewareOptions<
  TRegister,
  TMiddlewares,
  TServer
> {
  type: 'request';
  middleware?: TMiddlewares;
  server?: TServer;
}

Middleware Utilities

Helper functions for working with middleware chains and validation.

/**
 * Flattens nested middleware arrays into a single array
 * @param middlewares - Array of middleware to flatten
 * @returns Flattened middleware array
 */
function flattenMiddlewares(
  middlewares: AnyFunctionMiddleware[]
): AnyFunctionMiddleware[];

/**
 * Executes a middleware chain
 * @param middlewares - The middleware chain to execute
 * @param context - The execution context
 * @returns Result of middleware execution
 */
function executeMiddleware<T>(
  middlewares: AnyFunctionMiddleware[],
  context: T
): Promise<T>;

/**
 * Apply middleware to a function
 * @param middleware - The middleware to apply
 * @param fn - The function to wrap with middleware
 * @returns Enhanced function with middleware
 */
function applyMiddleware<T>(
  middleware: AnyFunctionMiddleware[],
  fn: T
): T;

/**
 * Execute validation logic
 * @param validator - The validator to execute
 * @param input - The input to validate
 * @returns Validated output
 */
function execValidator<T, U>(
  validator: Validator<T, U>,
  input: T
): U;

Middleware Composition

interface IntersectAllValidatorInputs<T extends ReadonlyArray<any>> {
  // Type helper for combining validator inputs
}

interface IntersectAllValidatorOutputs<T extends ReadonlyArray<any>> {
  // Type helper for combining validator outputs
}

interface AssignAllMiddleware<T extends ReadonlyArray<any>> {
  // Type helper for combining middleware types
}

Advanced Patterns

Conditional Middleware

import { createMiddleware } from "@tanstack/react-start";

const conditionalAuth = createMiddleware()
  .server(async (input, { request, next }) => {
    const publicPaths = ['/health', '/api/public'];
    const path = new URL(request.url).pathname;

    if (publicPaths.includes(path)) {
      return await next();
    }

    // Apply authentication for protected paths
    const token = request.headers.get('Authorization');
    if (!token) throw new Error('Authentication required');

    const user = await verifyToken(token);
    return { ...input, user };
  });

Error Handling Middleware

import { createMiddleware } from "@tanstack/react-start";

const errorHandlerMiddleware = createMiddleware()
  .server(async (input, { next }) => {
    try {
      return await next();
    } catch (error) {
      console.error('Server function error:', error);

      if (error.message === 'Unauthorized') {
        throw new Response('Unauthorized', { status: 401 });
      }

      throw new Response('Internal Server Error', { status: 500 });
    }
  });

Types

// Middleware type definitions
type MiddlewareType = 'request' | 'function';

interface AnyFunctionMiddleware {
  type: 'function';
  middleware: (...args: any[]) => any;
}

interface AnyRequestMiddleware {
  type: 'request';
  middleware: (request: Request, context: any) => any;
}

// Function middleware types
interface FunctionMiddlewareWithTypes<
  TRegister,
  TResponse,
  TMiddlewares,
  TInputValidator,
  THandler
> {
  middleware?: TMiddlewares;
  inputValidator?: TInputValidator;
  handler?: THandler;
}

interface FunctionMiddlewareValidator<T, U> {
  (input: T): U;
}

interface FunctionMiddlewareServer<TInput, TOutput> {
  (input: TInput, context: ServerFnCtx): Promise<TOutput> | TOutput;
}

interface FunctionMiddlewareClient<TInput, TOutput> {
  (input: TInput): Promise<TOutput> | TOutput;
}

// Request middleware types
interface RequestMiddlewareWithTypes<
  TRegister,
  TMiddlewares,
  TServer
> {
  type: 'request';
  middleware?: TMiddlewares;
  server?: TServer;
}

interface RequestServerFn<T> {
  (request: Request, context: T): Promise<Response | void> | Response | void;
}

// Middleware context types
interface FunctionMiddlewareAfterMiddleware<T> {
  context: T;
  next: () => Promise<any>;
}

interface RequestMiddlewareAfterMiddleware<T> {
  context: T;
  next: () => Promise<Response>;
}

// Validator types
interface Validator<TInput, TOutput> {
  (input: TInput): TOutput;
}

// Context assignment helpers
interface AssignAllClientContextBeforeNext<T extends ReadonlyArray<any>> {
  // Type helper for client context assignment
}

interface FunctionClientResultWithContext<T, U> {
  result: T;
  context: U;
}

interface FunctionServerResultWithContext<T, U> {
  result: T;
  context: U;
}

Install with Tessl CLI

npx tessl i tessl/npm-tanstack--react-start

docs

index.md

isomorphic-functions.md

middleware.md

request-response.md

rpc-system.md

server-functions.md

server-utilities.md

ssr-components.md

vite-plugin.md

tile.json