153 lines
4.8 KiB
JavaScript
153 lines
4.8 KiB
JavaScript
import {defaultDataIdFromObject, InMemoryCache} from 'apollo-cache-inmemory';
|
|
import {createHttpLink} from 'apollo-link-http';
|
|
import {onError} from 'apollo-link-error';
|
|
import {ApolloClient} from 'apollo-client';
|
|
import {ApolloLink, Observable} from 'apollo-link';
|
|
import fetch from 'unfetch';
|
|
import {typeDefs} from '@/graphql/typedefs';
|
|
import {resolvers} from '@/graphql/resolvers';
|
|
|
|
const writeLocalCache = cache => {
|
|
// we use the cache as our local state
|
|
cache.writeData({
|
|
data: {
|
|
scrollPosition: {
|
|
__typename: 'ScrollPosition',
|
|
scrollTo: '',
|
|
},
|
|
sidebar: {
|
|
__typename: 'Sidebar',
|
|
profile: false,
|
|
navigation: false,
|
|
},
|
|
helloEmail: {
|
|
__typename: 'HelloEmail',
|
|
email: '',
|
|
},
|
|
instrumentFilter: {
|
|
__typename: 'InstrumentFilter',
|
|
currentFilter: 'abc'
|
|
}
|
|
},
|
|
});
|
|
};
|
|
|
|
export default function (uri, networkErrorCallback) {
|
|
const httpLink = createHttpLink({
|
|
// uri: process.env.NODE_ENV !== 'production' ? 'http://localhost:8000/api/graphql/' : '/api/graphql/',
|
|
uri,
|
|
credentials: 'include',
|
|
fetch: fetch,
|
|
headers: {
|
|
'X-CSRFToken': document.cookie.replace(/(?:(?:^|.*;\s*)csrftoken\s*=\s*([^;]*).*$)|^.*$/, '$1'),
|
|
},
|
|
});
|
|
|
|
const consoleLink = new ApolloLink((operation, forward) => {
|
|
// console.log(`starting request for ${operation.operationName}`);
|
|
|
|
return forward(operation).map((data) => {
|
|
// console.log(`ending request for ${operation.operationName}`);
|
|
|
|
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(({response, operation, networkError, graphQLErrors}) => {
|
|
if (networkError && networkErrorCallback) {
|
|
networkErrorCallback(networkError.statusCode);
|
|
return Observable.of();
|
|
}
|
|
|
|
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
|
|
return Observable.of();
|
|
}
|
|
});
|
|
|
|
const composedLink = ApolloLink.from([createOmitTypenameLink, consoleLink, errorLink, httpLink]);
|
|
|
|
const cache = new InMemoryCache({
|
|
dataIdFromObject: obj => {
|
|
switch (obj.__typename) {
|
|
case 'InstrumentNode':
|
|
case 'ModuleNode':
|
|
case 'RoomEntryNode':
|
|
return `${obj.__typename}:${obj.slug}`;
|
|
default:
|
|
return defaultDataIdFromObject(obj);
|
|
}
|
|
},
|
|
cacheRedirects: {
|
|
Query: {
|
|
contentBlock: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ContentBlockNode', id: args.id}),
|
|
chapter: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ChapterNode', id: args.id}),
|
|
assignment: (_, args, {getCacheKey}) => getCacheKey({__typename: 'AssignmentNode', id: args.id}),
|
|
objective: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveNode', id: args.id}),
|
|
objectiveGroup: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveGroupNode', id: args.id}),
|
|
projectEntry: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ProjectEntryNode', id: args.id}),
|
|
project: (_, args, {getCacheKey}) => {
|
|
if (args.slug) {
|
|
return getCacheKey({__typename: 'ProjectNode', id: args.slug});
|
|
} else {
|
|
return getCacheKey({__typename: 'ProjectNode', id: args.id});
|
|
}
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
// TODO: Monkey-patching in a fix for an open issue suggesting that
|
|
// `readQuery` should return null or undefined if the query is not yet in the
|
|
// cache: https://github.com/apollographql/apollo-feature-requests/issues/1
|
|
cache.originalReadQuery = cache.readQuery;
|
|
cache.readQuery = (...args) => {
|
|
try {
|
|
return cache.originalReadQuery(...args);
|
|
} catch (err) {
|
|
console.error(err);
|
|
return undefined;
|
|
}
|
|
};
|
|
|
|
writeLocalCache(cache);
|
|
|
|
// Create the apollo client
|
|
const client = new ApolloClient({
|
|
link: composedLink,
|
|
// link: httpLink,
|
|
cache,
|
|
connectToDevTools: true,
|
|
typeDefs,
|
|
resolvers,
|
|
});
|
|
client.onResetStore(() => {
|
|
writeLocalCache(cache);
|
|
});
|
|
return client;
|
|
}
|