forked from reactioncommerce/example-storefront
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Janus Reith <mail@janusreith.de>
- Loading branch information
Janus Reith
committed
May 19, 2020
1 parent
1adb34c
commit 6865d8d
Showing
4 changed files
with
122 additions
and
282 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { ApolloClient, ApolloLink, HttpLink, InMemoryCache } from "@apollo/client"; | ||
import { setContext } from "@apollo/link-context"; | ||
import { onError } from "@apollo/link-error"; | ||
import fetch from "isomorphic-unfetch"; | ||
import Router from "next/router"; | ||
import logger from "../logger"; | ||
import { omitTypenameLink } from "./omitVariableTypenameLink"; | ||
|
||
const REFRESH_PATH = "/refresh"; | ||
const STATUS_BAD_REQUEST = 400; | ||
const STATUS_UNAUTHORIZED = 401; | ||
|
||
let token; | ||
|
||
/** | ||
* @summary Set the access token that GraphQL requests will use in the Authorization header | ||
* @param {String} value New token value | ||
* @return {undefined} | ||
*/ | ||
export function setAccessToken(value) { | ||
token = value; | ||
} | ||
|
||
export default function createApolloClient() { | ||
// Config | ||
let graphqlUrl; | ||
|
||
/* eslint-disable prefer-destructuring */ | ||
if (process.browser) { | ||
graphqlUrl = process.env.EXTERNAL_GRAPHQL_URL; | ||
} else { | ||
graphqlUrl = process.env.INTERNAL_GRAPHQL_URL; | ||
} | ||
|
||
const httpLink = new HttpLink({ uri: graphqlUrl, credentials: "same-origin", fetch }); | ||
|
||
// error handling for Apollo Link | ||
const errorLink = onError((apolloError) => { | ||
const { graphQLErrors, networkError, operation } = apolloError; | ||
|
||
if (graphQLErrors) { | ||
graphQLErrors.forEach(({ message, locations, path }) => { | ||
logger.error(`[GraphQL error]: ${message}`, { | ||
locations, | ||
operationName: operation && operation.operationName, | ||
path | ||
}); | ||
}); | ||
} | ||
|
||
if (networkError) { | ||
const errorCode = networkError.response && networkError.response.status; | ||
if (errorCode === STATUS_UNAUTHORIZED) { | ||
// If a 401 Unauthorized error occurred, redirect to /signin. | ||
// This will re-authenticate the user without showing a login page and a new token is issued. | ||
if (process && process.browser) { | ||
Router.push(REFRESH_PATH); | ||
} | ||
return; | ||
} | ||
if (errorCode !== STATUS_BAD_REQUEST) { | ||
logger.error(`Unable to access the GraphQL API. Is it running and accessible at ${graphqlUrl} from the Storefront UI server?`); | ||
} | ||
} | ||
}); | ||
|
||
// Set auth context | ||
// https://github.com/apollographql/apollo-link/tree/master/packages/apollo-link-context | ||
const authLink = setContext((_, { headers }) => ({ | ||
headers: { | ||
...headers, | ||
...(token ? { Authorization: token } : {}) | ||
} | ||
})); | ||
|
||
// Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient | ||
return new ApolloClient({ | ||
ssrMode: false, | ||
link: ApolloLink.from([omitTypenameLink, authLink, errorLink, httpLink]), | ||
cache: new InMemoryCache({ | ||
typePolicies: { | ||
} | ||
}) | ||
}); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from "react"; | ||
import { ApolloProvider } from "@apollo/client"; | ||
import createApolloClient from "./apolloClient"; | ||
|
||
// On the client we store the apollo client in the following variable | ||
// this prevents the client from reinitializing between page transitions. | ||
let globalApolloClient = null; | ||
|
||
|
||
const initApolloClient = () => { | ||
// Reuse client on the client-side | ||
if (!globalApolloClient) { | ||
globalApolloClient = createApolloClient(); | ||
} | ||
|
||
return globalApolloClient; | ||
}; | ||
|
||
export const withApollo = () => (PageComponent) => { | ||
const WithApollo = ({ ...pageProps }) => { | ||
const client = initApolloClient(); | ||
|
||
return ( | ||
<ApolloProvider client={client}> | ||
<PageComponent {...pageProps} /> | ||
</ApolloProvider> | ||
); | ||
}; | ||
|
||
// Set the correct displayName in development | ||
if (process.env.NODE_ENV !== "production") { | ||
const displayName = PageComponent.displayName || PageComponent.name || "Component"; | ||
WithApollo.displayName = `withApollo(${displayName})`; | ||
} | ||
|
||
return WithApollo; | ||
}; |
Oops, something went wrong.