-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraphqlAPI.ts
162 lines (135 loc) · 3.94 KB
/
graphqlAPI.ts
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import { MutationResult, QueryResult } from 'react-apollo'
import { DocumentNode } from 'graphql'
import { flow } from 'mobx'
import { CancellablePromise } from 'mobx/lib/api/flow'
import { STATE } from 'src/lib/constants/api'
import { mutations, queries } from 'src/lib/gql/generated/graphqlConfigs'
import { TMutations, TQueries } from 'src/lib/gql/generated/graphqlTypes'
import { TStorage } from './types'
export type TNotification = {
id: string
type: 'ERROR' | 'SUCCESS'
message?: string
}
type TGraphqlActionType = 'query' | 'mutation'
type TSetState = (state: STATE) => void
type TCallGraphqlActionParams<TData, TParams extends {}> = {
GQLVariables?: TParams
onSuccess?: (data: TData) => void
onError?: (erorr: any) => void
setState?: TSetState
}
type Required2<NullableT, T = NonNullable<NullableT>> = {
[P in keyof T]-?: NonNullable<T[P]>
}
export type TGraphqlAction<TData, TParams extends {}, TDataStrict = Required2<TData>> = (
params?: TCallGraphqlActionParams<TDataStrict, TParams>
) => CancellablePromise<TDataStrict>
type TCreateGraphqlActionParams = {
GQLDocument: DocumentNode
type: TGraphqlActionType
notifications?: {
[key in TNotification['type']]?: Omit<TNotification, 'id' | 'type'>
}
}
export type TGraphqlConfig = Pick<TCreateGraphqlActionParams, 'GQLDocument' | 'notifications'>
type TGraphqlConfigs = {
[key: string]: TGraphqlConfig
}
type TGraphqlRequests = {
[key in ['queries', 'mutations'][number]]: TGraphqlConfigs
}
export class GraphqlAPIService {
public mutations!: TMutations
public queries!: TQueries
private services!: TStorage
constructor(services: TStorage) {
this.services = services
this.addConfigs({ mutations, queries })
}
private get apolloClient() {
const apollo = this.services.APOLLO
return apollo.getClient()
}
private createGraphqlAction = <
TGraphqlResult extends MutationResult | QueryResult,
TParams extends {}
>({
GQLDocument,
type,
}: TCreateGraphqlActionParams): TGraphqlAction<any, any> => {
const self = this
// @ts-expect-error
return flow(function* ({
GQLVariables,
onSuccess,
onError,
setState,
}: TCallGraphqlActionParams<TGraphqlResult['data'], TParams>) {
if (setState) {
setState(STATE.LOADING)
}
try {
let result: TGraphqlResult
if (type === 'mutation') {
result = yield self.apolloClient.mutate({
mutation: GQLDocument,
variables: GQLVariables,
})
} else {
result = yield self.apolloClient.query({
query: GQLDocument,
variables: GQLVariables,
})
}
const { data } = result
if (data) {
if (setState) {
setState(STATE.SUCCESS)
}
if (onSuccess) {
onSuccess(data)
} else {
return data
}
} else {
throw new Error('Graphql answer doesn`t contents data')
}
} catch (error) {
if (setState) {
setState(STATE.FAILED)
}
if (onError) {
onError(error)
} else {
throw error
}
}
})
}
private createGraphqlActions = <T extends TGraphqlConfigs>(
configs: T,
type: TGraphqlActionType
): { [key in keyof T]: TGraphqlAction<any, any> } => {
const result = {} as { [key in keyof T]: TGraphqlAction<any, any> }
Object.keys(configs).map((keyString) => {
const key = keyString as keyof T
result[key] = this.createGraphqlAction({ type, ...configs[key] })
})
return result
}
private addConfigs = ({ mutations, queries }: TGraphqlRequests) => {
if (mutations) {
this.mutations = {
...this.mutations,
...this.createGraphqlActions(mutations, 'mutation'),
}
}
if (queries) {
this.queries = {
...this.queries,
...this.createGraphqlActions(queries, 'query'),
}
}
}
}