/
create-link.js
141 lines (125 loc) · 3.9 KB
/
create-link.js
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
const { HttpLink } = require('apollo-link-http')
const { getMainDefinition } = require('apollo-utilities')
const { setContext } = require('apollo-link-context')
const fetch = require('node-fetch')
const { onError } = require('apollo-link-error')
const { ApolloLink, split } = require('apollo-link')
const ApolloClient = require('apollo-client').default
const { InMemoryCache } = require('apollo-cache-inmemory')
const { SubscriptionClient } = require('subscriptions-transport-ws/dist/client')
const WebSocket = require('ws')
const { inspect } = require('util')
function createWsLink(clientName) {
return new ApolloLink(function(operation, forward) {
const context = operation.getContext();
const { graphqlContext: { subscriptionClients } } = context;
return subscriptionClients
&& subscriptionClients[clientName]
&& subscriptionClients[clientName].request(operation);
})
}
function createWsAdminLink(clientName, graphqlContext) {
return new ApolloLink(function(operation, forward) {
const { subscriptionClients } = graphqlContext;
return subscriptionClients
&& subscriptionClients[clientName]
&& subscriptionClients[clientName].request(operation);
})
}
const errorLink = onError(function({ graphQLErrors, networkError }) {
if (graphQLErrors)
graphQLErrors.map(function({ message, locations, path }) {
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
}
);
if (networkError) {
console.log(`[Network error]: ${inspect(networkError)}`);
}
});
function makeHttpLink(clientName, {urlMap}) {
return new HttpLink({ uri: urlMap[clientName].uri, fetch, credentials: 'include' });
}
function makeContextLink(context) {
return setContext(function(_request, previousContext) {
const { connParams } = context || previousContext.graphqlContext
return connParams
});
}
function isSubscriptionOperation({ query }) {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription'
}
function createLink(clientName, context){
const httpLink = makeHttpLink(clientName, context)
const contextLink = makeContextLink()
const finalHttpLink = errorLink.concat(contextLink.concat(httpLink))
const wsLink = context.ws ? createWsLink(clientName) : null
const finallWsLink = wsLink ? errorLink.concat(contextLink.concat(wsLink)) : null
const finalLink = finallWsLink ? split(
isSubscriptionOperation,
finallWsLink,
finalHttpLink
) : finalHttpLink
return {
link: finalLink,
}
}
function createAdminLink(clientName, context){
const httpLink = makeHttpLink(clientName, context)
const contextLink = makeContextLink(context)
const finalHttpLink = errorLink.concat(contextLink.concat(httpLink))
const wsLink = createWsAdminLink(clientName, context)
const finallWsLink = errorLink.concat(wsLink)
const finalLink = split(
isSubscriptionOperation,
finallWsLink,
finalHttpLink
)
return {
link: finalLink,
}
}
function createWsClient(clientName, context) {
const { urlMap, connParams } = context
const subUrl = urlMap[clientName].subUri
return new SubscriptionClient(subUrl, {
connectionParams: connParams,
reconnect: true,
}, WebSocket)
}
function getApolloClient({link}) {
return new ApolloClient({
link,
cache: new InMemoryCache(),
})
}
function createAdminContext(clientName, context) {
const { urlMap } = context
const connParams = {
headers: urlMap[clientName].headers
}
return {
connParams,
urlMap,
admin: true,
}
}
function makeConnectionParams({token, role}) {
return {
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
"X-Hasura-Role": role,
}
}
}
module.exports = {
createLink,
getApolloClient,
makeConnectionParams,
createWsClient,
createAdminContext,
createAdminLink,
}