All files / src/lib/api/middleware compose.ts

80.35% Statements 45/56
100% Branches 0/0
0% Functions 0/2
80.35% Lines 45/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 571x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x        
/**
 * Middleware Composition
 *
 * Utilities for composing multiple middleware functions.
 */
 
import type { RouteHandler, Middleware } from './types';
 
/**
 * Compose multiple middleware functions into one
 *
 * Middleware is applied right-to-left (innermost first).
 * This means the first middleware in the array is the outermost wrapper.
 *
 * @example
 * ```ts
 * // Apply withErrorHandling first (outermost), then withLogging, then withAuth
 * const handler = compose(
 *   withErrorHandling,
 *   withLogging,
 *   withAuth
 * )(async (request, context, session) => {
 *   return successResponse({ userId: session.user.id });
 * });
 * ```
 */
export function compose(...middlewares: Middleware[]): Middleware {
  return <T>(handler: RouteHandler<T>): RouteHandler<T> => {
    return middlewares.reduceRight(
      (acc, middleware) => middleware(acc),
      handler
    );
  };
}
 
/**
 * Pipe middleware functions (left-to-right composition)
 *
 * This is the opposite of compose - middleware is applied left-to-right.
 * The first middleware in the array wraps the second, which wraps the third, etc.
 *
 * @example
 * ```ts
 * // Apply withAuth first (innermost), then withLogging, then withErrorHandling
 * const handler = pipe(
 *   withAuth,
 *   withLogging,
 *   withErrorHandling
 * )(async (request, context, session) => {
 *   return successResponse({ userId: session.user.id });
 * });
 * ```
 */
export function pipe(...middlewares: Middleware[]): Middleware {
  return compose(...middlewares.reverse());
}