Last active
May 4, 2021 22:26
-
-
Save realStandal/ba9645489d4acee6286b4f5c14b1abd0 to your computer and use it in GitHub Desktop.
Updated `RedwoodApolloProvider` providing full custom-`useAuth` pass through.
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
import { | |
ApolloProvider, | |
ApolloClientOptions, | |
ApolloClient, | |
ApolloLink, | |
InMemoryCache, | |
useQuery, | |
useMutation, | |
createHttpLink, | |
} from '@apollo/client' | |
import { setContext } from '@apollo/client/link/context' | |
import { AuthContextInterface, useAuth as useRwAuth } from '@redwoodjs/auth' | |
import { | |
FetchConfigProvider, | |
useFetchConfig, | |
} from 'src/components/FetchConfigProvider' | |
import { GraphQLHooksProvider } from 'src/components/GraphQLHooksProvider' | |
export type GraphQLClientConfig = Omit<ApolloClientOptions<InMemoryCache>, 'cache'> | |
export type CustomUseAuthHook = () => AuthContextInterface | |
const ApolloProviderWithFetchConfig: React.FunctionComponent<{ | |
config?: GraphQLClientConfig, | |
useAuth?: CustomUseAuthHook | |
}> = ({ config = {}, children, useAuth = useRwAuth }) => { | |
const { uri, headers } = useFetchConfig() | |
const { getToken, type: authProviderType, isAuthenticated } = useAuth() | |
const withToken = setContext(async () => { | |
if (isAuthenticated && getToken) { | |
const token = await getToken() | |
return { token } | |
} | |
return { token: null } | |
}) | |
const authMiddleware = new ApolloLink((operation, forward) => { | |
const { token } = operation.getContext() | |
// Only add auth headers when token is present | |
// Token is null, when !isAuthenticated | |
const authHeaders = token | |
? { | |
'auth-provider': authProviderType, | |
authorization: `Bearer ${token}`, | |
} | |
: {} | |
operation.setContext(() => ({ | |
headers: { | |
...headers, | |
// Duped auth headers, because we may remove FetchContext at a later date | |
...authHeaders, | |
}, | |
})) | |
return forward(operation) | |
}) | |
const httpLink = createHttpLink({ uri }) | |
const client = new ApolloClient({ | |
cache: new InMemoryCache(), | |
...config, | |
link: ApolloLink.from([withToken, authMiddleware.concat(httpLink)]), | |
}) | |
return <ApolloProvider client={client}>{children}</ApolloProvider> | |
} | |
export const RedwoodApolloProvider: React.FunctionComponent<{ | |
graphQLClientConfig?: GraphQLClientConfig | |
useAuth?: CustomUseAuthHook | |
}> = ({ graphQLClientConfig, useAuth, children }) => { | |
return ( | |
<FetchConfigProvider useAuth={useAuth}> | |
<ApolloProviderWithFetchConfig config={graphQLClientConfig}> | |
<GraphQLHooksProvider useQuery={useQuery} useMutation={useMutation}> | |
{children} | |
</GraphQLHooksProvider> | |
</ApolloProviderWithFetchConfig> | |
</FetchConfigProvider> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment