request.ts 2.2 KB

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