2025-06-13 15:21:27 +02:00
|
|
|
import { ApolloClient, ApolloLink, createHttpLink, from, InMemoryCache, split } from '@apollo/client/core'
|
2024-02-05 16:48:02 +01:00
|
|
|
import { setContext } from '@apollo/client/link/context'
|
2025-06-13 15:21:27 +02:00
|
|
|
import { WebSocketLink } from '@apollo/client/link/ws'
|
2024-02-05 16:48:02 +01:00
|
|
|
import { getMainDefinition } from '@apollo/client/utilities'
|
2024-08-06 13:59:08 +00:00
|
|
|
import type { GetTokenSilentlyOptions } from '@auth0/auth0-spa-js'
|
2024-02-05 16:48:02 +01:00
|
|
|
import type { Auth0VueClient } from '@auth0/auth0-vue'
|
2025-06-13 15:21:27 +02:00
|
|
|
import { SpanKind, TraceFlags } from '@opentelemetry/api'
|
|
|
|
|
import { DefaultApolloClient, provideApolloClient } from '@vue/apollo-composable'
|
|
|
|
|
|
2024-02-05 16:48:02 +01:00
|
|
|
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
|
2025-06-13 15:21:27 +02:00
|
|
|
return await auth0.getAccessTokenSilently(options).catch(() => {
|
2024-02-05 16:48:02 +01:00
|
|
|
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}` : '',
|
|
|
|
|
},
|
|
|
|
|
}))
|
|
|
|
|
})
|
|
|
|
|
|
2025-06-13 15:21:27 +02:00
|
|
|
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)
|
|
|
|
|
})
|
|
|
|
|
|
2024-05-21 13:58:45 +00:00
|
|
|
const link =
|
2024-02-05 16:48:02 +01:00
|
|
|
from([
|
2025-06-13 15:21:27 +02:00
|
|
|
createSpanLink,
|
2024-02-05 16:48:02 +01:00
|
|
|
split(
|
|
|
|
|
({ query }) => {
|
|
|
|
|
const definition = getMainDefinition(query)
|
|
|
|
|
return (
|
|
|
|
|
definition.kind === 'OperationDefinition' &&
|
|
|
|
|
definition.operation === 'subscription'
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
authLink.concat(wsLink),
|
|
|
|
|
authLink.concat(httpLink),
|
|
|
|
|
),
|
2024-05-21 13:58:45 +00:00
|
|
|
])
|
2024-02-05 16:48:02 +01:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
})
|