import ApolloClient from 'apollo-client'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { split } from 'apollo-link'; import { HttpLink } from 'apollo-link-http'; import { WebSocketLink } from 'apollo-link-ws'; import { getMainDefinition } from 'apollo-utilities'; import gql from 'graphql-tag'; export class UnauthorizedError extends Error { constructor(...args: any[]) { super(...args) Object.setPrototypeOf(this, UnauthorizedError.prototype); } } let client: DaddyClient export function getClient(graphQLEndpoint: string, subscriptionEndpoint: string): DaddyClient { if (!client) { client = new DaddyClient(graphQLEndpoint, subscriptionEndpoint); } return client; } export class DaddyClient { gql: ApolloClient constructor(graphQLEndpoint: string, subscriptionEndpoint: string) { const wsLink = new WebSocketLink({ uri: subscriptionEndpoint, options: { reconnect: true } }); const httpLink = new HttpLink({ uri: graphQLEndpoint, fetchOptions: { mode: 'cors', credentials: 'include', } }); const link = split( ({ query }) => { const definition = getMainDefinition(query); return ( definition.kind === 'OperationDefinition' && definition.operation === 'subscription' ); }, wsLink, httpLink, ); this.gql = new ApolloClient({ link: link, cache: new InMemoryCache(), }); } fetchProfile() { return this.gql.query({ query: gql` query { userProfile { email, createdAt, connectedAt } }` }) .then(this.assertAuthorization) } assertAuthorization({ status, data }: any) { if (status === 401) return Promise.reject(new UnauthorizedError()); return data; } }