{"version":3,"file":"HttpMigrateRouteFetcher.mjs","sources":["../../src/http/HttpMigrateRouteFetcher.ts"],"sourcesContent":["import type { HttpMigration } from \"../HttpMigration\";\nimport { IHttpConnection } from \"../structures/IHttpConnection\";\nimport { IHttpResponse } from \"../structures/IHttpResponse\";\nimport { HttpError } from \"./HttpError\";\n\nexport namespace HttpMigrateRouteFetcher {\n  export const execute = async (\n    props: HttpMigration.IFetchProps,\n  ): Promise<unknown> => {\n    const result: IHttpResponse = await _Propagate(\"request\", props);\n    props.route.success?.media;\n    if (result.status !== 200 && result.status !== 201)\n      throw new HttpError(\n        props.route.method.toUpperCase() as \"GET\",\n        props.route.path,\n        result.status,\n        result.headers,\n        result.body as string,\n      );\n    return result.body;\n  };\n\n  export const propagate = (\n    props: HttpMigration.IFetchProps,\n  ): Promise<IHttpResponse> => _Propagate(\"propagate\", props);\n}\n\nconst _Propagate = async (\n  from: string,\n  props: HttpMigration.IFetchProps,\n): Promise<IHttpResponse> => {\n  // VALIDATE PARAMETERS\n  const error = (message: string) =>\n    new Error(`Error on MigrateRouteFetcher.${from}(): ${message}`);\n  if (Array.isArray(props.parameters)) {\n    if (props.route.parameters.length !== props.parameters.length)\n      throw error(`number of parameters is not matched.`);\n  } else if (\n    props.route.parameters.every(\n      (p) => (props.parameters as Record<string, any>)[p.key] !== undefined,\n    ) === false\n  )\n    throw error(`number of parameters is not matched.`);\n\n  // VALIDATE QUERY\n  if (!!props.route.query !== !!props.query)\n    throw error(`query is not matched.`);\n  else if (!!props.route.body !== (props.body !== undefined))\n    throw error(`body is not matched.`);\n\n  // INIT REQUEST DATA\n  const headers: Record<string, IHttpConnection.HeaderValue | undefined> = {\n    ...(props.connection.headers ?? {}),\n    ...(props.route.body?.type &&\n    props.route.body.type !== \"multipart/form-data\"\n      ? { \"Content-Type\": props.route.body.type }\n      : {}),\n  };\n  const init: RequestInit = {\n    ...(props.connection.options ?? {}),\n    method: props.route.method.toUpperCase(),\n    headers: (() => {\n      const output: [string, string][] = [];\n      for (const [key, value] of Object.entries(headers))\n        if (value === undefined) continue;\n        else if (Array.isArray(value))\n          for (const v of value) output.push([key, String(v)]);\n        else output.push([key, String(value)]);\n      return output;\n    })(),\n  };\n  if (props.body !== undefined)\n    init.body = (\n      props.route.body?.type === \"application/x-www-form-urlencoded\"\n        ? requestQueryBody(props.body)\n        : props.route.body?.type === \"multipart/form-data\"\n          ? requestFormDataBody(props.body)\n          : props.route.body?.type === \"application/json\"\n            ? JSON.stringify(props.body)\n            : props.body\n    ) as any;\n\n  // DO REQUEST\n  const resolvedPath: string =\n    props.connection.host.endsWith(\"/\") === false &&\n    props.route.emendedPath.startsWith(\"/\") === false\n      ? `/${getPath(props)}`\n      : getPath(props);\n  const url: URL = new URL(`${props.connection.host}${resolvedPath}`);\n\n  const response: Response = await (props.connection.fetch ?? fetch)(url, init);\n  const status: number = response.status;\n  const out = (body: unknown): IHttpResponse => ({\n    status,\n    headers: responseHeaders(response.headers),\n    body,\n  });\n\n  if (status === 200 || status === 201) {\n    // SUCCESS CASE\n    if (props.route.method.toUpperCase() === \"HEAD\") return out(undefined);\n    else if (\n      props.route.success === null ||\n      props.route.success.type === \"text/plain\"\n    )\n      return out(await response.text());\n    else if (props.route.success.type === \"application/json\") {\n      const text: string = await response.text();\n      return out(text.length ? JSON.parse(text) : undefined);\n    } else if (props.route.success.type === \"application/x-www-form-urlencoded\")\n      return out(new URLSearchParams(await response.text()));\n    else if (props.route.success.type === \"multipart/form-data\")\n      return out(await response.formData());\n    throw error(\"Unsupported response body type.\");\n  } else {\n    // FAILURE CASE\n    const type: string = (\n      response.headers.get(\"content-type\") ??\n      response.headers.get(\"Content-Type\") ??\n      \"\"\n    )\n      .split(\";\")[0]\n      .trim();\n    if (type === \"\" || type.startsWith(\"text/\"))\n      return out(await response.text());\n    else if (type === \"application/json\") return out(await response.json());\n    else if (type === \"application/x-www-form-urlencoded\")\n      return out(new URLSearchParams(await response.text()));\n    else if (type === \"multipart/form-data\")\n      return out(await response.formData());\n    else if (type === \"application/octet-stream\")\n      return out(await response.blob());\n    return out(await response.text());\n  }\n};\n\nconst getPath = (\n  props: Pick<HttpMigration.IFetchProps, \"route\" | \"parameters\" | \"query\">,\n): string => {\n  let path: string = props.route.emendedPath;\n  props.route.parameters.forEach((p, i) => {\n    path = path.replace(\n      `:${p.key}`,\n      encodeURIComponent(\n        String(\n          (Array.isArray(props.parameters)\n            ? props.parameters[i]\n            : props.parameters[p.key]) ?? \"null\",\n        ),\n      ),\n    );\n  });\n  if (props.route.query) path += getQueryPath(props.query ?? {});\n  return path;\n};\n\nconst getQueryPath = (query: Record<string, any>): string => {\n  const variables = new URLSearchParams();\n  for (const [key, value] of Object.entries(query))\n    if (undefined === value) continue;\n    else if (Array.isArray(value))\n      value.forEach((elem: any) => variables.append(key, String(elem)));\n    else variables.set(key, String(value));\n  return 0 === variables.size ? \"\" : `?${variables.toString()}`;\n};\n\nconst requestQueryBody = (input: any): URLSearchParams => {\n  const q: URLSearchParams = new URLSearchParams();\n  for (const [key, value] of Object.entries(input))\n    if (value === undefined) continue;\n    else if (Array.isArray(value))\n      value.forEach((elem) => q.append(key, String(elem)));\n    else q.set(key, String(value));\n  return q;\n};\nconst requestFormDataBody = (input: Record<string, any>): FormData => {\n  const encoded: FormData = new FormData();\n  const append = (key: string) => (value: any) => {\n    if (value === undefined) return;\n    else if (typeof File === \"function\" && value instanceof File)\n      encoded.append(key, value, value.name);\n    else encoded.append(key, value);\n  };\n  for (const [key, value] of Object.entries(input))\n    if (Array.isArray(value)) value.map(append(key));\n    else append(key)(value);\n  return encoded;\n};\n\nconst responseHeaders = (\n  headers: Headers,\n): Record<string, string | string[]> => {\n  const output: Record<string, string | string[]> = {};\n  headers.forEach((value, key) => {\n    if (key === \"set-cookie\") {\n      output[key] ??= [];\n      (output[key] as string[]).push(\n        ...value.split(\";\").map((str) => str.trim()),\n      );\n    } else output[key] = value;\n  });\n  return output;\n};\n"],"names":["HttpMigrateRouteFetcher","execute","async","props","result","_Propagate","route","success","media","status","HttpError","method","toUpperCase","path","headers","body","propagate","from","error","message","Error","Array","isArray","parameters","length","every","p","key","undefined","query","connection","type","init","options","output","value","Object","entries","v","push","String","requestQueryBody","requestFormDataBody","JSON","stringify","resolvedPath","host","endsWith","emendedPath","startsWith","getPath","url","URL","response","fetch","out","responseHeaders","text","parse","URLSearchParams","formData","get","split","trim","json","blob","forEach","i","replace","encodeURIComponent","getQueryPath","variables","elem","append","set","size","toString","input","q","encoded","FormData","File","name","map","str"],"mappings":"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"}