skillbox/client/src/graphql/client.js

109 lines
3.0 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 {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) => {
console.log('operation', operation.operationName);
return forward(operation).map(data => {
console.log(`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 (graphQLErrors) {
graphQLErrors.forEach(({message, locations, path}) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
}
/*
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 (process.env.NODE_ENV === '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,
});
}