index.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { Global } from "../global"
  2. import { Installation } from "../installation"
  3. import path from "path"
  4. export namespace Trace {
  5. export function init() {
  6. if (!Installation.isDev()) return
  7. const writer = Bun.file(path.join(Global.Path.data, "log", "fetch.log")).writer()
  8. const originalFetch = globalThis.fetch
  9. // @ts-expect-error
  10. globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
  11. const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url
  12. const method = init?.method || "GET"
  13. const urlObj = new URL(url)
  14. writer.write(`\n${method} ${urlObj.pathname}${urlObj.search} HTTP/1.1\n`)
  15. writer.write(`Host: ${urlObj.host}\n`)
  16. if (init?.headers) {
  17. if (init.headers instanceof Headers) {
  18. init.headers.forEach((value, key) => {
  19. writer.write(`${key}: ${value}\n`)
  20. })
  21. } else {
  22. for (const [key, value] of Object.entries(init.headers)) {
  23. writer.write(`${key}: ${value}\n`)
  24. }
  25. }
  26. }
  27. if (init?.body) {
  28. writer.write(`\n${init.body}`)
  29. }
  30. writer.flush()
  31. const response = await originalFetch(input, init)
  32. const clonedResponse = response.clone()
  33. writer.write(`\nHTTP/1.1 ${response.status} ${response.statusText}\n`)
  34. response.headers.forEach((value, key) => {
  35. writer.write(`${key}: ${value}\n`)
  36. })
  37. if (clonedResponse.body) {
  38. clonedResponse.text().then(async (x) => {
  39. writer.write(`\n${x}\n`)
  40. })
  41. }
  42. writer.flush()
  43. return response
  44. }
  45. }
  46. }