apollo.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import {
  2. ApolloClient,
  3. HttpLink,
  4. InMemoryCache,
  5. QueryOptions,
  6. OperationVariables,
  7. split,
  8. ApolloError,
  9. isApolloError as _isApolloError,
  10. } from "@apollo/client/core"
  11. import { WebSocketLink } from "@apollo/client/link/ws"
  12. import { setContext } from "@apollo/client/link/context"
  13. import { getMainDefinition } from "@apollo/client/utilities"
  14. import { ref, onMounted, onBeforeUnmount, Ref } from "@nuxtjs/composition-api"
  15. import { authIdToken$ } from "./fb/auth"
  16. let authToken: String | null = null
  17. export function registerApolloAuthUpdate() {
  18. authIdToken$.subscribe((token) => {
  19. authToken = token
  20. })
  21. }
  22. /**
  23. * Injects auth token if available
  24. */
  25. const authLink = setContext((_, { headers }) => {
  26. if (authToken) {
  27. return {
  28. headers: {
  29. ...headers,
  30. authorization: `Bearer ${authToken}`,
  31. },
  32. }
  33. } else {
  34. return {
  35. headers,
  36. }
  37. }
  38. })
  39. const httpLink = new HttpLink({
  40. uri:
  41. process.env.CONTEXT === "production"
  42. ? "https://api.hoppscotch.io/graphql"
  43. : "https://api.hoppscotch.io/graphql",
  44. })
  45. const wsLink = new WebSocketLink({
  46. uri:
  47. process.env.CONTEXT === "production"
  48. ? "wss://api.hoppscotch.io/graphql"
  49. : "wss://api.hoppscotch.io/graphql",
  50. options: {
  51. reconnect: true,
  52. lazy: true,
  53. connectionParams: () => {
  54. return {
  55. authorization: `Bearer ${authToken}`,
  56. }
  57. },
  58. },
  59. })
  60. const splitLink = split(
  61. ({ query }) => {
  62. const definition = getMainDefinition(query)
  63. return (
  64. definition.kind === "OperationDefinition" &&
  65. definition.operation === "subscription"
  66. )
  67. },
  68. wsLink,
  69. httpLink
  70. )
  71. export const apolloClient = new ApolloClient({
  72. link: authLink.concat(splitLink),
  73. cache: new InMemoryCache(),
  74. defaultOptions: {
  75. query: {
  76. fetchPolicy: "network-only",
  77. errorPolicy: "ignore",
  78. },
  79. watchQuery: {
  80. fetchPolicy: "network-only",
  81. errorPolicy: "ignore",
  82. },
  83. },
  84. })
  85. export function isApolloError(x: any): x is ApolloError {
  86. return _isApolloError(x)
  87. }
  88. export function useGQLQuery<T = any, TVariables = OperationVariables>(
  89. options: QueryOptions<TVariables, T>
  90. ): { loading: Ref<boolean>; data: Ref<T | ApolloError | undefined> } {
  91. const loading = ref(true)
  92. const data = ref<T | ApolloError | undefined>()
  93. let subscription: ZenObservable.Subscription | null = null
  94. onMounted(() => {
  95. subscription = apolloClient.watchQuery(options).subscribe((result) => {
  96. if (result.error) {
  97. data.value = result.error
  98. } else {
  99. data.value = result.data
  100. }
  101. loading.value = false
  102. })
  103. })
  104. onBeforeUnmount(() => {
  105. if (subscription) {
  106. subscription.unsubscribe()
  107. }
  108. })
  109. return {
  110. loading,
  111. data,
  112. }
  113. }