//GQL Imports import { ApolloClient, InMemoryCache, split, ApolloLink, HttpLink, from, } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; import { RetryLink } from "@apollo/client/link/retry"; import { WebSocketLink } from "@apollo/client/link/ws"; import { SubscriptionClient } from "subscriptions-transport-ws"; import { auth } from "../firebase/firebase.utils"; import { onError } from "@apollo/client/link/error"; import { getMainDefinition } from "@apollo/client/utilities"; const httpLink = new HttpLink({ uri: "https://bodyshop-dev-db.herokuapp.com/v1/graphql", }); const wsLink = new WebSocketLink({ uri: "wss://bodyshop-dev-db.herokuapp.com/v1/graphql", options: { lazy: true, reconnect: true, connectionParams: async () => { const token = auth.currentUser && (await auth.currentUser.getIdToken(true)); if (token) { return { headers: { authorization: token ? `Bearer ${token}` : "", }, }; } }, }, }); //https://stackoverflow.com/questions/57163454/refreshing-a-token-with-apollo-client-firebase-auth const errorLink = onError( ({ graphQLErrors, networkError, operation, forward }) => { console.error(graphQLErrors); if (graphQLErrors) graphQLErrors.forEach(({ message, locations, path }) => console.error( `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}` ) ); if (networkError) console.error(`[Network error]: ${JSON.stringify(networkError)}`); console.log(operation.getContext()); } ); const subscriptionMiddleware = { applyMiddleware: async (options, next) => { options.authToken = auth.currentUser && (await auth.currentUser.getIdToken(true)); next(); }, }; wsLink.subscriptionClient.use([subscriptionMiddleware]); const link = split( // split based on operation type ({ query }) => { const definition = getMainDefinition(query); // console.log( // "##Intercepted GQL Transaction : " + // definition.operation + // "|" + // definition.name.value + // "##", // query // ); return ( definition.kind === "OperationDefinition" && definition.operation === "subscription" ); }, wsLink, httpLink ); const authLink = setContext((_, { headers }) => { return ( auth.currentUser && auth.currentUser.getIdToken().then((token) => { if (token) { return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", }, }; } else { return { headers }; } }) ); }); const retryLink = new RetryLink({ delay: { initial: 500, max: 5, jitter: true, }, attempts: { max: 5, retryIf: (error, _operation) => !!error, }, }); // const middlewares = []; // if (process.env.NODE_ENV === "development") { // middlewares.push(apolloLogger); // } // middlewares.push(retryLink.concat(errorLink.concat(authLink.concat(link)))); const cache = new InMemoryCache({}); export const client = new ApolloClient({ //link: ApolloLink.from(middlewares), //link: from([apolloLogger, errorLink, authLink, link]), link: from([authLink, link]), cache, // connectToDevTools: process.env.NODE_ENV !== "production", // defaultOptions: { // watchQuery: { // fetchPolicy: "cache-and-network", // }, // }, });