middleware.d.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import { OAuthClientProvider } from './auth.js';
  2. import { FetchLike } from '../shared/transport.js';
  3. /**
  4. * Middleware function that wraps and enhances fetch functionality.
  5. * Takes a fetch handler and returns an enhanced fetch handler.
  6. */
  7. export type Middleware = (next: FetchLike) => FetchLike;
  8. /**
  9. * Creates a fetch wrapper that handles OAuth authentication automatically.
  10. *
  11. * This wrapper will:
  12. * - Add Authorization headers with access tokens
  13. * - Handle 401 responses by attempting re-authentication
  14. * - Retry the original request after successful auth
  15. * - Handle OAuth errors appropriately (InvalidClientError, etc.)
  16. *
  17. * The baseUrl parameter is optional and defaults to using the domain from the request URL.
  18. * However, you should explicitly provide baseUrl when:
  19. * - Making requests to multiple subdomains (e.g., api.example.com, cdn.example.com)
  20. * - Using API paths that differ from OAuth discovery paths (e.g., requesting /api/v1/data but OAuth is at /)
  21. * - The OAuth server is on a different domain than your API requests
  22. * - You want to ensure consistent OAuth behavior regardless of request URLs
  23. *
  24. * For MCP transports, set baseUrl to the same URL you pass to the transport constructor.
  25. *
  26. * Note: This wrapper is designed for general-purpose fetch operations.
  27. * MCP transports (SSE and StreamableHTTP) already have built-in OAuth handling
  28. * and should not need this wrapper.
  29. *
  30. * @param provider - OAuth client provider for authentication
  31. * @param baseUrl - Base URL for OAuth server discovery (defaults to request URL domain)
  32. * @returns A fetch middleware function
  33. */
  34. export declare const withOAuth: (provider: OAuthClientProvider, baseUrl?: string | URL) => Middleware;
  35. /**
  36. * Logger function type for HTTP requests
  37. */
  38. export type RequestLogger = (input: {
  39. method: string;
  40. url: string | URL;
  41. status: number;
  42. statusText: string;
  43. duration: number;
  44. requestHeaders?: Headers;
  45. responseHeaders?: Headers;
  46. error?: Error;
  47. }) => void;
  48. /**
  49. * Configuration options for the logging middleware
  50. */
  51. export type LoggingOptions = {
  52. /**
  53. * Custom logger function, defaults to console logging
  54. */
  55. logger?: RequestLogger;
  56. /**
  57. * Whether to include request headers in logs
  58. * @default false
  59. */
  60. includeRequestHeaders?: boolean;
  61. /**
  62. * Whether to include response headers in logs
  63. * @default false
  64. */
  65. includeResponseHeaders?: boolean;
  66. /**
  67. * Status level filter - only log requests with status >= this value
  68. * Set to 0 to log all requests, 400 to log only errors
  69. * @default 0
  70. */
  71. statusLevel?: number;
  72. };
  73. /**
  74. * Creates a fetch middleware that logs HTTP requests and responses.
  75. *
  76. * When called without arguments `withLogging()`, it uses the default logger that:
  77. * - Logs successful requests (2xx) to `console.log`
  78. * - Logs error responses (4xx/5xx) and network errors to `console.error`
  79. * - Logs all requests regardless of status (statusLevel: 0)
  80. * - Does not include request or response headers in logs
  81. * - Measures and displays request duration in milliseconds
  82. *
  83. * Important: the default logger uses both `console.log` and `console.error` so it should not be used with
  84. * `stdio` transports and applications.
  85. *
  86. * @param options - Logging configuration options
  87. * @returns A fetch middleware function
  88. */
  89. export declare const withLogging: (options?: LoggingOptions) => Middleware;
  90. /**
  91. * Composes multiple fetch middleware functions into a single middleware pipeline.
  92. * Middleware are applied in the order they appear, creating a chain of handlers.
  93. *
  94. * @example
  95. * ```typescript
  96. * // Create a middleware pipeline that handles both OAuth and logging
  97. * const enhancedFetch = applyMiddlewares(
  98. * withOAuth(oauthProvider, 'https://api.example.com'),
  99. * withLogging({ statusLevel: 400 })
  100. * )(fetch);
  101. *
  102. * // Use the enhanced fetch - it will handle auth and log errors
  103. * const response = await enhancedFetch('https://api.example.com/data');
  104. * ```
  105. *
  106. * @param middleware - Array of fetch middleware to compose into a pipeline
  107. * @returns A single composed middleware function
  108. */
  109. export declare const applyMiddlewares: (...middleware: Middleware[]) => Middleware;
  110. /**
  111. * Helper function to create custom fetch middleware with cleaner syntax.
  112. * Provides the next handler and request details as separate parameters for easier access.
  113. *
  114. * @example
  115. * ```typescript
  116. * // Create custom authentication middleware
  117. * const customAuthMiddleware = createMiddleware(async (next, input, init) => {
  118. * const headers = new Headers(init?.headers);
  119. * headers.set('X-Custom-Auth', 'my-token');
  120. *
  121. * const response = await next(input, { ...init, headers });
  122. *
  123. * if (response.status === 401) {
  124. * console.log('Authentication failed');
  125. * }
  126. *
  127. * return response;
  128. * });
  129. *
  130. * // Create conditional middleware
  131. * const conditionalMiddleware = createMiddleware(async (next, input, init) => {
  132. * const url = typeof input === 'string' ? input : input.toString();
  133. *
  134. * // Only add headers for API routes
  135. * if (url.includes('/api/')) {
  136. * const headers = new Headers(init?.headers);
  137. * headers.set('X-API-Version', 'v2');
  138. * return next(input, { ...init, headers });
  139. * }
  140. *
  141. * // Pass through for non-API routes
  142. * return next(input, init);
  143. * });
  144. *
  145. * // Create caching middleware
  146. * const cacheMiddleware = createMiddleware(async (next, input, init) => {
  147. * const cacheKey = typeof input === 'string' ? input : input.toString();
  148. *
  149. * // Check cache first
  150. * const cached = await getFromCache(cacheKey);
  151. * if (cached) {
  152. * return new Response(cached, { status: 200 });
  153. * }
  154. *
  155. * // Make request and cache result
  156. * const response = await next(input, init);
  157. * if (response.ok) {
  158. * await saveToCache(cacheKey, await response.clone().text());
  159. * }
  160. *
  161. * return response;
  162. * });
  163. * ```
  164. *
  165. * @param handler - Function that receives the next handler and request parameters
  166. * @returns A fetch middleware function
  167. */
  168. export declare const createMiddleware: (handler: (next: FetchLike, input: string | URL, init?: RequestInit) => Promise<Response>) => Middleware;
  169. //# sourceMappingURL=middleware.d.ts.map