{"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, getSearchParams } from '../utils/url/cleanUrl'\nimport {\n  RequestHandler,\n  RequestHandlerDefaultInfo,\n  RequestHandlerOptions,\n  ResponseResolver,\n} from './RequestHandler'\n\ntype HttpHandlerMethod = string | RegExp\n\nexport interface HttpHandlerInfo extends RequestHandlerDefaultInfo {\n  method: HttpHandlerMethod\n  path: Path\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\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    path: Path,\n    resolver: ResponseResolver<HttpRequestResolverExtras<any>, any, any>,\n    options?: RequestHandlerOptions,\n  ) {\n    super({\n      info: {\n        header: `${method} ${path}`,\n        path,\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 instanceof RegExp) {\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    const searchParams = getSearchParams(path)\n    const queryParams: string[] = []\n\n    searchParams.forEach((_, paramName) => {\n      queryParams.push(paramName)\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/recipes/query-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 match = matchRequestUrl(\n      url,\n      this.info.path,\n      args.resolutionContext?.baseUrl,\n    )\n    const cookies = getAllRequestCookies(args.request)\n\n    return {\n      match,\n      cookies,\n    }\n  }\n\n  predicate(args: { request: Request; parsedResult: HttpRequestParsedResult }) {\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    // eslint-disable-next-line no-console\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    // eslint-disable-next-line no-console\n    console.groupEnd()\n  }\n}\n"],"mappings":"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","names":["HttpMethods"]}