request.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import {
  2. audit,
  3. combineLatest,
  4. distinctUntilChanged,
  5. EMPTY,
  6. from,
  7. map,
  8. Subscription,
  9. } from "rxjs"
  10. import { doc, getDoc, getFirestore, setDoc } from "firebase/firestore"
  11. import cloneDeep from "lodash/cloneDeep"
  12. import { HoppRESTRequest, translateToNewRequest } from "@hoppscotch/data"
  13. import { currentUser$, HoppUser } from "./auth"
  14. import { restRequest$ } from "~/newstore/RESTSession"
  15. /**
  16. * Writes a request to a user's firestore sync
  17. *
  18. * @param user The user to write to
  19. * @param request The request to write to the request sync
  20. */
  21. function writeCurrentRequest(user: HoppUser, request: HoppRESTRequest) {
  22. const req = cloneDeep(request)
  23. // Remove FormData entries because those can't be stored on Firestore
  24. if (req.body.contentType === "multipart/form-data") {
  25. req.body.body = req.body.body.map((formData) => {
  26. if (!formData.isFile) return formData
  27. return {
  28. active: formData.active,
  29. isFile: false,
  30. key: formData.key,
  31. value: "",
  32. }
  33. })
  34. }
  35. return setDoc(doc(getFirestore(), "users", user.uid, "requests", "rest"), req)
  36. }
  37. /**
  38. * Loads the synced request from the firestore sync
  39. *
  40. * @returns Fetched request object if exists else null
  41. */
  42. export async function loadRequestFromSync(): Promise<HoppRESTRequest | null> {
  43. const currentUser = currentUser$.value
  44. if (!currentUser)
  45. throw new Error("Cannot load request from sync without login")
  46. const fbDoc = await getDoc(
  47. doc(getFirestore(), "users", currentUser.uid, "requests", "rest")
  48. )
  49. const data = fbDoc.data()
  50. if (!data) return null
  51. else return translateToNewRequest(data)
  52. }
  53. /**
  54. * Performs sync of the REST Request session with Firestore.
  55. *
  56. * @returns A subscription to the sync observable stream.
  57. * Unsubscribe to stop syncing.
  58. */
  59. export function startRequestSync(): Subscription {
  60. const sub = combineLatest([
  61. currentUser$,
  62. restRequest$.pipe(distinctUntilChanged()),
  63. ])
  64. .pipe(
  65. map(([user, request]) =>
  66. user ? from(writeCurrentRequest(user, request)) : EMPTY
  67. ),
  68. audit((x) => x)
  69. )
  70. .subscribe(() => {
  71. // NOTE: This subscription should be kept
  72. })
  73. return sub
  74. }