Middleware: defineComposite

Bundles a series of middleware into a single middleware.

build receives the composite's config and returns the parts, outermost first — the same order pipeline takes. The composite's contributions are derived from the parts', so it publishes exactly the union of what they contribute. There is no argument for declaring a key, so a composite cannot over-declare — and internal may only name a key some part actually contributes. Prerequisites are derived the same way — a part's In that an earlier part contributes is discharged internally, and anything outstanding becomes the composite's own In.

At runtime the parts fold exactly as pipeline folds them, each merging its own single key. A part that short-circuits therefore does so from inside the fold, where an enclosing middleware's response seam observes its response.

Parameters

Examples

A composite with private plumbing

import { defineComposite } from '@supabase/middleware'

// `withGate` contributes the whole auth result at `ctx.auth`; the projections
// republish the individual keys the public contract promises. `auth` itself is
// an implementation detail, so it is marked internal.
export const withAuth = defineComposite({
  build: (config: { mode: 'user' | 'none' }) =>
    [withGate(config), withMode(), withClaims()] as const,
  internal: ['auth'],
})

// Nested, or flat — one declaration serves both.
export default {
  fetch: pipeline([withAuth({ mode: 'user' }), withPostgres()], async (req, ctx) => {
    ctx.authMode   // from withMode
    ctx.jwtClaims  // from withClaims
    ctx.postgres   // reads ctx.jwtClaims as its own `In`
    return Response.json({ ok: true })
  }),
}