-
Notifications
You must be signed in to change notification settings - Fork 5
/
RedwoodRelayProvider.tsx
92 lines (79 loc) · 3.06 KB
/
RedwoodRelayProvider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import type { AuthContextInterface } from '@redwoodjs/auth'
import { useIsBrowser } from '@redwoodjs/prerender/browserUtils'
import { useAuth as useRWAuth } from '@redwoodjs/auth'
import { FetchConfigProvider, useFetchConfig } from '@redwoodjs/web'
import { Suspense } from 'react'
import { RelayEnvironmentProvider } from 'react-relay'
import { Environment, FetchFunction, Network, RecordSource, Store } from 'relay-runtime'
export type UseAuthProp = () => AuthContextInterface
const RelayProviderWithFetchConfig: React.FunctionComponent<{
environment: Environment
useAuth: UseAuthProp
}> = ({ environment, children, useAuth }) => {
const { uri, headers } = useFetchConfig()
const { getToken, type: authProviderType, isAuthenticated } = useAuth()
async function fetcher(operation, variables) {
// Gets the access token before every query, this IMO is wasteful
// but is what redwood does OOTB
let token: string | undefined = undefined
if (isAuthenticated && getToken) {
token = await getToken()
}
const authHeaders = token
? {
'auth-provider': authProviderType,
authorization: `Bearer ${token}`,
}
: {}
// Relay offers a lot of info in the original outgoing request
// { cacheID: "64f3434db5fcda977516dfe1b15852f7", id: null, metadata: {}, name: "UsersPageQuery", operationKind: "query", text: "...", variables: {} }
// We re-format it to fit the setup inside graphql-helix
const body = {
query: operation.text,
operationName: operation.name,
operationKind: operation.operationKind,
variables,
}
const response = await fetch(uri, {
method: 'POST',
headers: {
...headers,
...authHeaders,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
})
// Get the response as JSON
return await response.json()
}
const env = environment || createDefaultEnvironment(fetcher)
// const hooks = createHooks(env)
return (
<RelayEnvironmentProvider environment={env}>
{/* <GraphQLHooksProvider useQuery={hooks.useQuery} useMutation={hooks.useMutation}> */}
{children}
{/* </GraphQLHooksProvider> */}
</RelayEnvironmentProvider>
)
}
export const createDefaultEnvironment = (fetch: FetchFunction) => {
// // Export a singleton instance of Relay Environment configured with our network function:
return new Environment({
network: Network.create(fetch),
store: new Store(new RecordSource()),
})
}
export const RedwoodRelayProvider: React.FunctionComponent<{
environment?: Environment
useAuth?: UseAuthProp
}> = ({ environment, useAuth = useRWAuth, children }) => {
const browser = useIsBrowser()
const SsrCompatibleSuspense = browser ? Suspense : (props) => props.children
return (
<FetchConfigProvider useAuth={useAuth}>
<RelayProviderWithFetchConfig environment={environment} useAuth={useAuth}>
<SsrCompatibleSuspense fallback={<div>Site loader</div>}>{children}</SsrCompatibleSuspense>
</RelayProviderWithFetchConfig>
</FetchConfigProvider>
)
}