All files after.ts

100% Statements 66/66
84.61% Branches 11/13
100% Functions 9/9
100% Lines 66/66

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 57 58 59 60 61 62 63 64 65 661x 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 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x
import { Rowan, Next } from "./rowan.js";
 
/**
 * A middleware container that executes its child middleware after the next middleware
 * in the chain has completed. This is useful for post-processing, cleanup, logging,
 * or any operations that should happen after the main processing logic.
 * 
 * The After middleware ensures that its child middleware runs only after next() has
 * completed successfully. This creates a "post-processing" pattern where you can
 * add middleware that responds to or modifies the results of upstream processing.
 * 
 * @template Ctx - The type of the context object
 * 
 * @example
 * ```typescript
 * const after = new After([
 *   async (ctx) => console.log('Response:', ctx.response),
 *   async (ctx) => ctx.logged = true,
 *   async (ctx) => {
 *     // Send analytics after request is complete
 *     await analytics.track(ctx.userId, 'request_completed');
 *   }
 * ]);
 * 
 * await after.process(context, async () => {
 *   // Main request processing
 *   context.response = await processRequest(context.request);
 * });
 * ```
 */
export class After<Ctx = any> extends Rowan<Ctx>{
  /**
   * Processes the context by first calling next(), then executing all child middleware.
   * Child middleware is executed in sequence after the next middleware chain completes.
   * 
   * @param ctx - The context object to process
   * @param next - Function to call the next middleware in the chain
   * @returns A Promise that resolves when both next() and all child middleware have completed
   * 
   * @example
   * ```typescript
   * await after.process(ctx, async () => {
   *   // This runs first
   *   ctx.processed = true;
   * });
   * // Child middleware runs after the above completes
   * ```
   */
  process(ctx: Ctx, next: Next) {
    const self = this;
    return next().then(function(_) { 
      return self.processInternal(ctx, function () { return Promise.resolve(); }); 
    });
  }
 
  /**
   * Internal method to process child middleware without calling the main next function.
   * 
   * @param ctx - The context object to process
   * @param next - No-op next function for child middleware
   * @returns A Promise that resolves when child middleware processing is complete
   */
  private processInternal(ctx: Ctx, next: Next): Promise<void> {
    return super.process(ctx, next);
  }
}