100 lines
3.2 KiB
JavaScript
100 lines
3.2 KiB
JavaScript
import { onError } from '@apollo/client/link/error';
|
|
import { ApolloClient, ApolloLink, createHttpLink } from '@apollo/client/core';
|
|
import { typeDefs } from '@/graphql/typedefs';
|
|
import { resolvers } from '@/graphql/resolvers';
|
|
import cache from './cache';
|
|
import log from 'loglevel';
|
|
import * as Sentry from '@sentry/vue';
|
|
|
|
import { router } from '@/router';
|
|
|
|
export default function(uri, networkErrorCallback) {
|
|
const httpLink = createHttpLink({
|
|
// uri: process.env.NODE_ENV !== 'production' ? 'http://localhost:8000/api/graphql/' : '/api/graphql/',
|
|
uri,
|
|
credentials: 'include',
|
|
headers: {
|
|
'X-CSRFToken': document.cookie.replace(/(?:(?:^|.*;\s*)csrftoken\s*=\s*([^;]*).*$)|^.*$/, '$1'),
|
|
},
|
|
});
|
|
|
|
const consoleLink = new ApolloLink((operation, forward) => {
|
|
// log.debug('operation', operation.operationName);
|
|
|
|
return forward(operation).map((data) => {
|
|
// log.debug(`returned from server for ${operation.operationName}`, data);
|
|
return data;
|
|
});
|
|
});
|
|
|
|
// from https://github.com/apollographql/apollo-client/issues/1564#issuecomment-357492659
|
|
const omitTypename = (key, value) => {
|
|
return key === '__typename' ? undefined : value;
|
|
};
|
|
|
|
const createOmitTypenameLink = new ApolloLink((operation, forward) => {
|
|
if (operation.variables) {
|
|
operation.variables = JSON.parse(JSON.stringify(operation.variables), omitTypename);
|
|
}
|
|
|
|
return forward(operation);
|
|
});
|
|
|
|
const errorLink = onError(({ networkError, graphQLErrors }) => {
|
|
if (networkError && networkErrorCallback) {
|
|
networkErrorCallback(networkError.statusCode);
|
|
if (networkError.statusCode == 402) {
|
|
// not authenticated, we don't need to continue here
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (graphQLErrors) {
|
|
graphQLErrors.forEach(({ message, locations, path }) => {
|
|
const err = `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`;
|
|
log.warn(err);
|
|
Sentry.captureMessage(err);
|
|
});
|
|
}
|
|
|
|
/*
|
|
The server redirects to the HTML login page, but apollo expects a JSON response. This is fine, we'll just ignore it
|
|
*/
|
|
if (networkError && networkError.name === 'ServerParseError') {
|
|
// workaround found here: https://github.com/apollographql/apollo-link/issues/855#issuecomment-485764697
|
|
}
|
|
});
|
|
|
|
const notFoundLink = new ApolloLink((operation, forward) => {
|
|
return forward(operation).map((response) => {
|
|
const { data } = response;
|
|
if (data) {
|
|
if (data.topic && data.topic.__typename === 'NotFound') {
|
|
// redirect to general 404 page.
|
|
// todo: specific topic not found page, with navigation?
|
|
router.push({
|
|
name: 'not-found',
|
|
});
|
|
}
|
|
}
|
|
return response;
|
|
});
|
|
});
|
|
|
|
let composedLink;
|
|
if (import.meta.env.MODE === 'production') {
|
|
composedLink = ApolloLink.from([createOmitTypenameLink, errorLink, notFoundLink, httpLink]);
|
|
} else {
|
|
composedLink = ApolloLink.from([consoleLink, createOmitTypenameLink, errorLink, notFoundLink, httpLink]);
|
|
}
|
|
|
|
// Create the apollo client
|
|
return new ApolloClient({
|
|
link: composedLink,
|
|
cache,
|
|
connectToDevTools: true,
|
|
typeDefs,
|
|
resolvers,
|
|
});
|
|
}
|