Files
dancefinder-app/plugins/apollo.ts
T

103 lines
2.6 KiB
TypeScript

import {
ApolloClient,
createHttpLink,
from,
InMemoryCache,
split,
} from '@apollo/client/core'
import { WebSocketLink } from '@apollo/client/link/ws'
import { setContext } from '@apollo/client/link/context'
import { getMainDefinition } from '@apollo/client/utilities'
import { SentryLink } from 'apollo-link-sentry'
import * as Sentry from '@sentry/browser'
import { type GetTokenSilentlyOptions } from '@auth0/auth0-spa-js'
import { DefaultApolloClient, provideApolloClient } from '@vue/apollo-composable'
import type { Auth0VueClient } from '@auth0/auth0-vue'
import { defineNuxtPlugin, useNuxtApp } from '#app'
import { envConfig } from '~/utils/environment'
// The side effect of patching fetch() has to occur before configuring Apollo Client
// https://github.com/getsentry/sentry-javascript/issues/2860#issuecomment-684514367
import './sentry'
const apiUrl = envConfig(window.location.hostname).apiUrl
const wsUrl = apiUrl.replace(/^http/, 'ws')
const cache = new InMemoryCache({
typePolicies: {
},
})
const getToken = async (options: GetTokenSilentlyOptions) => {
const nuxtApp = useNuxtApp()
const auth0: Auth0VueClient = nuxtApp.$auth0 as Auth0VueClient
return await auth0.getAccessTokenSilently(options).catch((err) => {
Sentry.captureException(err, {
extra: {
function: 'getTokenSilently',
},
})
return undefined
})
}
const httpLink = createHttpLink({
uri: apiUrl,
})
const wsLink = new WebSocketLink({
uri: wsUrl,
options: {
reconnect: true,
lazy: true,
connectionParams: () => {
return getToken({}).then((token) => ({
authToken: token,
}))
},
},
})
const authLink = setContext(async (_, { headers }) => {
return await getToken({}).then((token) => ({
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
}))
})
const link =
from([
new SentryLink({}),
split(
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
authLink.concat(wsLink),
authLink.concat(httpLink),
),
])
const instance = new ApolloClient({
connectToDevTools: true,
link,
cache,
defaultOptions: {
query: {
fetchPolicy: 'cache-first',
},
watchQuery: {
fetchPolicy: 'cache-and-network',
},
},
})
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.provide(DefaultApolloClient[Symbol.toStringTag], instance)
provideApolloClient(instance)
})