Files
dancefinder-app/app/plugins/apollo.ts
T
argoyle 7e14688ee0 fix(apollo): enable devtools configuration option
Update the Apollo Client configuration to use the new devtools 
option instead of the deprecated connectToDevTools. This change 
ensures proper integration with development tools and maintains 
compatibility with future Apollo updates.
2025-11-04 11:32:55 +01:00

110 lines
3.0 KiB
TypeScript

import { ApolloClient, ApolloLink, createHttpLink, from, InMemoryCache, split } from '@apollo/client/core'
import { setContext } from '@apollo/client/link/context'
import { WebSocketLink } from '@apollo/client/link/ws'
import { getMainDefinition } from '@apollo/client/utilities'
import type { GetTokenSilentlyOptions } from '@auth0/auth0-spa-js'
import type { Auth0VueClient } from '@auth0/auth0-vue'
import { SpanKind, TraceFlags } from '@opentelemetry/api'
import { DefaultApolloClient, provideApolloClient } from '@vue/apollo-composable'
import { defineNuxtPlugin, useNuxtApp } from '#app'
import { envConfig } from '~/utils/environment'
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(() => {
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 createSpanLink = new ApolloLink((operation, forward) => {
const nuxtApp = useNuxtApp()
if (nuxtApp.$faro) {
const { trace } = nuxtApp.$faro.api.getOTEL()
const span = trace.getTracer('default').startSpan(`gql.${operation.operationName}`, {
kind: SpanKind.INTERNAL, // 0: Internal, 1: Server, 2: Client, 3: Producer, 4: Consumer
})
const spanContext = span.spanContext()
const traceParent = '00' + '-' + spanContext.traceId + '-' + spanContext.spanId + '-0' + Number(spanContext.traceFlags || TraceFlags.NONE).toString(16)
operation.setContext({ span, headers: { ...operation.getContext().headers, 'traceparent': traceParent } })
return forward(operation).map((data) => {
span.end()
return data
})
}
return forward(operation)
})
const link =
from([
createSpanLink,
split(
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
authLink.concat(wsLink),
authLink.concat(httpLink),
),
])
const instance = new ApolloClient({
devtools: {
enabled: 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)
})