44 InMemoryCache ,
55 NormalizedCacheObject ,
66 createHttpLink ,
7+ InMemoryCacheConfig ,
78} from "@apollo/client" ;
89import { onError } from "@apollo/link-error" ;
910import merge from "deepmerge" ;
@@ -22,93 +23,98 @@ let apolloClient: CustomApolloClient | undefined;
2223
2324const { publicRuntimeConfig } = getConfig ( ) ;
2425
26+ const CACHE_CONFIG : InMemoryCacheConfig = {
27+ // possibleTypes must be provided to cache correctly unions and interfaces
28+ // https://www.apollographql.com/docs/react/data/fragments/#using-fragments-with-unions-and-interfaces
29+ possibleTypes : {
30+ AccessmodAnalysis : [
31+ "AccessmodGeographicCoverageAnalysis" ,
32+ "AccessmodAccessibilityAnalysis" ,
33+ "AccessmodZonalStatistics" ,
34+ ] ,
35+ } ,
36+ typePolicies : {
37+ Team : {
38+ merge : true ,
39+ fields : {
40+ permissions : {
41+ merge : true ,
42+ } ,
43+ } ,
44+ } ,
45+ AccessmodProject : {
46+ merge : true ,
47+ } ,
48+ AccessmodProjectPermission : {
49+ merge : true ,
50+ } ,
51+ User : {
52+ merge : true ,
53+ } ,
54+ AccessmodFileset : {
55+ merge : true ,
56+ // We need to tell to Apollo how to handle the metadata scalar
57+ fields : {
58+ metadata : {
59+ merge : true ,
60+ } ,
61+ } ,
62+ } ,
63+ Country : {
64+ // Country code are unique (at least it should). Let's use that for the cache key
65+ keyFields : false ,
66+ } ,
67+ } ,
68+ } ;
69+
2570const createApolloClient = ( headers : IncomingHttpHeaders | null = null ) => {
26- const enhancedFetch = ( url : RequestInfo , init : RequestInit ) => {
27- if ( process . env . NODE_ENV === "development" ) {
28- const body = JSON . parse ( init . body as string ) ;
29- console . log ( `Fetch ${ url } ${ body . operationName } ` ) ;
30- }
31- return fetch ( url , {
71+ const enhancedFetch = ( url : RequestInfo , init : RequestInit ) =>
72+ fetch ( url , {
3273 ...init ,
3374 headers : {
3475 ...init . headers ,
3576 cookie : headers ?. cookie ?? "" ,
3677 } ,
37- } ) . then ( ( resp ) => resp ) ;
38- } ;
39- return new ApolloClient ( {
40- ssrMode : typeof window === "undefined" ,
41- ssrForceFetchDelay : 100 , // in milliseconds
42- link : ApolloLink . from ( [
43- onError ( ( { graphQLErrors, networkError } ) => {
44- if ( graphQLErrors ) {
45- graphQLErrors . forEach ( ( { message, locations, path } ) =>
46- console . error (
47- `[GraphQL error]: Message: ${ message } , Location: ${ JSON . stringify (
48- locations
49- ) } , Path: ${ path } `
50- )
51- ) ;
52- }
53- if ( networkError ) {
78+ } ) ;
79+
80+ const link = ApolloLink . from ( [
81+ onError ( ( { graphQLErrors, networkError } ) => {
82+ if ( graphQLErrors ) {
83+ graphQLErrors . forEach ( ( { message, locations, path } ) =>
5484 console . error (
55- `[Network error]: ${ networkError } . Backend is unreachable. Is it running?`
56- ) ;
57- }
58- } ) ,
59-
60- createHttpLink ( {
61- uri : publicRuntimeConfig . GRAPHQL_ENDPOINT ,
62- fetch : enhancedFetch ,
63- credentials : "include" ,
64- fetchOptions : {
65- mode : "cors" ,
66- } ,
67- } ) ,
68- ] ) ,
69- cache : new InMemoryCache ( {
70- // possibleTypes must be provided to cache correctly unions and interfaces
71- // https://www.apollographql.com/docs/react/data/fragments/#using-fragments-with-unions-and-interfaces
72- possibleTypes : {
73- AccessmodAnalysis : [
74- "AccessmodGeographicCoverageAnalysis" ,
75- "AccessmodAccessibilityAnalysis" ,
76- "AccessmodZonalStatistics" ,
77- ] ,
78- } ,
79- typePolicies : {
80- Team : {
81- merge : true ,
82- fields : {
83- permissions : {
84- merge : true ,
85- } ,
86- } ,
87- } ,
88- AccessmodProject : {
89- merge : true ,
90- } ,
91- AccessmodProjectPermission : {
92- merge : true ,
93- } ,
94- User : {
95- merge : true ,
96- } ,
97- AccessmodFileset : {
98- merge : true ,
99- // We need to tell to Apollo how to handle the metadata scalar
100- fields : {
101- metadata : {
102- merge : true ,
103- } ,
104- } ,
105- } ,
106- Country : {
107- // Country code are unique (at least it should). Let's use that for the cache key
108- keyFields : false ,
109- } ,
85+ `[GraphQL error]: Message: ${ message } , Location: ${ JSON . stringify (
86+ locations
87+ ) } , Path: ${ path } `
88+ )
89+ ) ;
90+ }
91+ if ( networkError ) {
92+ console . error (
93+ `[Network error]: ${ networkError } . Backend is unreachable. Is it running?`
94+ ) ;
95+ }
96+ } ) ,
97+
98+ createHttpLink ( {
99+ uri : ( operation ) =>
100+ operation . operationName
101+ ? `${ publicRuntimeConfig . GRAPHQL_ENDPOINT } ${ operation . operationName } /`
102+ : publicRuntimeConfig . GRAPHQL_ENDPOINT ,
103+ fetch : enhancedFetch ,
104+ credentials : "include" ,
105+ fetchOptions : {
106+ mode : "cors" ,
110107 } ,
111108 } ) ,
109+ ] ) ;
110+
111+ const cache = new InMemoryCache ( CACHE_CONFIG ) ;
112+
113+ return new ApolloClient ( {
114+ ssrMode : typeof window === "undefined" ,
115+ ssrForceFetchDelay : 100 , // in milliseconds
116+ link,
117+ cache,
112118 } ) ;
113119} ;
114120
@@ -156,6 +162,7 @@ export const getApolloClient = (
156162
157163 return client ;
158164} ;
165+
159166export const addApolloState = ( client : ApolloClient < NormalizedCacheObject > ) => {
160167 return { props : { [ APOLLO_STATE_PROP_NAME ] : client . cache . extract ( ) } } ;
161168} ;
0 commit comments