{"version":3,"sources":["../../../src/core/handlers/HttpHandler.ts"],"sourcesContent":["import { ResponseResolutionContext } from '../utils/executeHandlers'\nimport { devUtils } from '../utils/internal/devUtils'\nimport { isStringEqual } from '../utils/internal/isStringEqual'\nimport { getStatusCodeColor } from '../utils/logging/getStatusCodeColor'\nimport { getTimestamp } from '../utils/logging/getTimestamp'\nimport { serializeRequest } from '../utils/logging/serializeRequest'\nimport { serializeResponse } from '../utils/logging/serializeResponse'\nimport {\n  matchRequestUrl,\n  Match,\n  Path,\n  PathParams,\n} from '../utils/matching/matchRequestUrl'\nimport { toPublicUrl } from '../utils/request/toPublicUrl'\nimport { getAllRequestCookies } from '../utils/request/getRequestCookies'\nimport { cleanUrl } from '../utils/url/cleanUrl'\nimport {\n  RequestHandler,\n  RequestHandlerDefaultInfo,\n  RequestHandlerOptions,\n  ResponseResolver,\n} from './RequestHandler'\n\nexport type HttpHandlerMethod = string | RegExp\n\nexport interface HttpHandlerInfo extends RequestHandlerDefaultInfo {\n  method: HttpHandlerMethod\n  path: HttpRequestPredicate<PathParams>\n}\n\nexport enum HttpMethods {\n  HEAD = 'HEAD',\n  GET = 'GET',\n  POST = 'POST',\n  PUT = 'PUT',\n  PATCH = 'PATCH',\n  OPTIONS = 'OPTIONS',\n  DELETE = 'DELETE',\n}\n\nexport type RequestQuery = {\n  [queryName: string]: string\n}\n\nexport type HttpRequestParsedResult = {\n  match: Match\n  cookies: Record<string, string>\n}\n\nexport type HttpRequestResolverExtras<Params extends PathParams> = {\n  params: Params\n  cookies: Record<string, string>\n}\n\nexport type HttpCustomPredicate<Params extends PathParams> = (args: {\n  request: Request\n  cookies: Record<string, string>\n}) =>\n  | HttpCustomPredicateResult<Params>\n  | Promise<HttpCustomPredicateResult<Params>>\n\nexport type HttpCustomPredicateResult<Params extends PathParams> =\n  | boolean\n  | {\n      matches: boolean\n      params: Params\n    }\n\nexport type HttpRequestPredicate<Params extends PathParams> =\n  | Path\n  | HttpCustomPredicate<Params>\n\n/**\n * Request handler for HTTP requests.\n * Provides request matching based on method and URL.\n */\nexport class HttpHandler extends RequestHandler<\n  HttpHandlerInfo,\n  HttpRequestParsedResult,\n  HttpRequestResolverExtras<any>\n> {\n  constructor(\n    method: HttpHandlerMethod,\n    predicate: HttpRequestPredicate<PathParams>,\n    resolver: ResponseResolver<HttpRequestResolverExtras<any>, any, any>,\n    options?: RequestHandlerOptions,\n  ) {\n    const displayPath =\n      typeof predicate === 'function' ? '[custom predicate]' : predicate\n\n    super({\n      info: {\n        header: `${method}${displayPath ? ` ${displayPath}` : ''}`,\n        path: predicate,\n        method,\n      },\n      resolver,\n      options,\n    })\n\n    this.checkRedundantQueryParameters()\n  }\n\n  private checkRedundantQueryParameters() {\n    const { method, path } = this.info\n\n    if (!path || path instanceof RegExp || typeof path === 'function') {\n      return\n    }\n\n    const url = cleanUrl(path)\n\n    // Bypass request handler URLs that have no redundant characters.\n    if (url === path) {\n      return\n    }\n\n    devUtils.warn(\n      `Found a redundant usage of query parameters in the request handler URL for \"${method} ${path}\". Please match against a path instead and access query parameters using \"new URL(request.url).searchParams\" instead. Learn more: https://mswjs.io/docs/http/intercepting-requests#querysearch-parameters`,\n    )\n  }\n\n  async parse(args: {\n    request: Request\n    resolutionContext?: ResponseResolutionContext\n  }) {\n    const url = new URL(args.request.url)\n    const cookies = getAllRequestCookies(args.request)\n\n    /**\n     * Handle custom predicate functions.\n     * @note Invoke this during parsing so the user can parse the path parameters\n     * manually. Otherwise, `params` is always an empty object, which isn't nice.\n     */\n    if (typeof this.info.path === 'function') {\n      const customPredicateResult = await this.info.path({\n        request: args.request,\n        cookies,\n      })\n\n      const match =\n        typeof customPredicateResult === 'boolean'\n          ? {\n              matches: customPredicateResult,\n              params: {},\n            }\n          : customPredicateResult\n\n      return {\n        match,\n        cookies,\n      }\n    }\n\n    const match = this.info.path\n      ? matchRequestUrl(url, this.info.path, args.resolutionContext?.baseUrl)\n      : { matches: false, params: {} }\n\n    return {\n      match,\n      cookies,\n    }\n  }\n\n  async predicate(args: {\n    request: Request\n    parsedResult: HttpRequestParsedResult\n    resolutionContext?: ResponseResolutionContext\n  }) {\n    const hasMatchingMethod = this.matchMethod(args.request.method)\n    const hasMatchingUrl = args.parsedResult.match.matches\n    return hasMatchingMethod && hasMatchingUrl\n  }\n\n  private matchMethod(actualMethod: string): boolean {\n    return this.info.method instanceof RegExp\n      ? this.info.method.test(actualMethod)\n      : isStringEqual(this.info.method, actualMethod)\n  }\n\n  protected extendResolverArgs(args: {\n    request: Request\n    parsedResult: HttpRequestParsedResult\n  }) {\n    return {\n      params: args.parsedResult.match?.params || {},\n      cookies: args.parsedResult.cookies,\n    }\n  }\n\n  async log(args: { request: Request; response: Response }) {\n    const publicUrl = toPublicUrl(args.request.url)\n    const loggedRequest = await serializeRequest(args.request)\n    const loggedResponse = await serializeResponse(args.response)\n    const statusColor = getStatusCodeColor(loggedResponse.status)\n\n    console.groupCollapsed(\n      devUtils.formatMessage(\n        `${getTimestamp()} ${args.request.method} ${publicUrl} (%c${\n          loggedResponse.status\n        } ${loggedResponse.statusText}%c)`,\n      ),\n      `color:${statusColor}`,\n      'color:inherit',\n    )\n    // eslint-disable-next-line no-console\n    console.log('Request', loggedRequest)\n    // eslint-disable-next-line no-console\n    console.log('Handler:', this)\n    // eslint-disable-next-line no-console\n    console.log('Response', loggedResponse)\n    console.groupEnd()\n  }\n}\n"],"mappings":"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","names":["HttpMethods","match"]}