From 627811f28d697564958386f9ac7f819c06098267 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Mon, 3 May 2021 09:18:24 -0400 Subject: [PATCH] Refactor Apollo Client handling --- helpers/apollo.ts | 88 +++++++++++++++++++++++++++++++++++++++++++ layouts/default.vue | 10 ----- nuxt.config.js | 10 +---- plugins/apollo.js | 12 ------ plugins/vue-apollo.ts | 15 ++++++++ 5 files changed, 104 insertions(+), 31 deletions(-) create mode 100644 helpers/apollo.ts delete mode 100644 plugins/apollo.js create mode 100644 plugins/vue-apollo.ts diff --git a/helpers/apollo.ts b/helpers/apollo.ts new file mode 100644 index 000000000..e1035fd7e --- /dev/null +++ b/helpers/apollo.ts @@ -0,0 +1,88 @@ +import { ApolloClient, HttpLink, InMemoryCache, split } from "@apollo/client/core"; +import { WebSocketLink } from "@apollo/client/link/ws"; +import { setContext } from '@apollo/client/link/context'; +import { fb } from "./fb"; +import { getMainDefinition } from "@apollo/client/utilities"; + +/** + * Stores the current authentication token + * + * The token stored here is the Firebase Auth token. + * If null, no token is passed (no user signed in) + */ +let authToken: string | null = null; + +/* + * Updates the token value on Firebase ID Token changes + */ +fb.idToken$.subscribe(newToken => { + authToken = newToken; +}); + +/** + * Injects auth token if available + */ +const authLink = setContext((_, { headers }) => { + if (authToken) { + return { + headers: { + ...headers, + authorization: `Bearer ${authToken}` + } + } + } else { + return { + headers + } + } +}) + + +const httpLink = new HttpLink({ + uri: process.env.CONTEXT === "production" + ? "https://api.hoppscotch.io/graphql" + : "https://api.hoppscotch.io/graphql", +}) + + +const wsLink = new WebSocketLink({ + uri: process.env.CONTEXT === "production" + ? "wss://api.hoppscotch.io/graphql" + : "wss://api.hoppscotch.io/graphql", + options: { + connectionParams: () => { + return { + headers: { + authorization: `Bearer ${authToken}` + } + } + } + } +}); + +const splitLink = split( + ({ query }) => { + const definition = getMainDefinition(query); + return ( + definition.kind === 'OperationDefinition' && + definition.operation === 'subscription' + ) + }, + wsLink, + httpLink +); + +export const apolloClient = new ApolloClient({ + link: authLink.concat(splitLink), + cache: new InMemoryCache(), + defaultOptions: { + query: { + fetchPolicy: 'network-only', + errorPolicy: 'ignore' + }, + watchQuery: { + fetchPolicy: 'network-only', + errorPolicy: 'ignore' + } + } +}); diff --git a/layouts/default.vue b/layouts/default.vue index f7159a38e..c15e3c70d 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -39,16 +39,6 @@ export default { "background-color:black;padding:4px 8px;border-radius:8px;font-size:16px;color:white;" ) - // Update GraphQL Token on firebase ID Token changes - fb.idToken$.subscribe((token) => { - if (token) { - console.log(token) - this.$apolloHelpers.onLogin(token) - } else { - this.$apolloHelpers.onLogout() - } - }) - const workbox = await window.$workbox if (workbox) { workbox.addEventListener("installed", (event) => { diff --git a/nuxt.config.js b/nuxt.config.js index e70579ed0..4b6a3f471 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -93,6 +93,7 @@ export default { "~/plugins/vuex-persist", "~/plugins/v-tooltip", "~/plugins/vue-rx", + "~/plugins/vue-apollo", { src: "~/plugins/web-worker", ssr: false }, ], @@ -129,16 +130,7 @@ export default { "@nuxtjs/robots", // https://github.com/nuxt-community/sitemap-module "@nuxtjs/sitemap", - // https://github.com/nuxt-community/apollo-module - "@nuxtjs/apollo", ], - - apollo: { - clientConfigs: { - default: "~/plugins/apollo.js", - }, - }, - // PWA module configuration (https://pwa.nuxtjs.org/setup) pwa: { meta: { diff --git a/plugins/apollo.js b/plugins/apollo.js deleted file mode 100644 index f28677922..000000000 --- a/plugins/apollo.js +++ /dev/null @@ -1,12 +0,0 @@ -export default () => { - return { - httpEndpoint: - process.env.CONTEXT === "production" - ? "https://api.hoppscotch.io/graphql" - : "https://api.hoppscotch.io/graphql", - wsEndpoint: - process.env.CONTEXT === "production" - ? "wss://api.hoppscotch.io/graphql" - : "wss://api.hoppscotch.io/graphql", - } -} diff --git a/plugins/vue-apollo.ts b/plugins/vue-apollo.ts new file mode 100644 index 000000000..bce33962a --- /dev/null +++ b/plugins/vue-apollo.ts @@ -0,0 +1,15 @@ +import Vue from "vue" +import VueApollo from "vue-apollo" +import { apolloClient } from "~/helpers/apollo"; + +const vueApolloProvider = new VueApollo({ + defaultClient: apolloClient as any +}); + +Vue.use(VueApollo); + +export default (ctx: any) => { + const { app } = ctx + + app.apolloProvider = vueApolloProvider +}