@@ -15,32 +15,26 @@ import {
15
15
ValidationError ,
16
16
} from "src/errors" ;
17
17
import { QueryParamData } from "src/services/search/searchfetcher/SearchFetcher" ;
18
- // TODO (#1682): replace search specific references (since this is a generic API file that any
19
- // future page or different namespace could use)
20
18
import { APIResponse } from "src/types/apiResponseTypes" ;
21
19
22
20
export type ApiMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT" ;
23
21
export interface JSONRequestBody {
24
22
[ key : string ] : unknown ;
25
23
}
26
24
27
- interface APIResponseError {
28
- field : string ;
29
- message : string ;
30
- type : string ;
31
- }
32
-
33
25
export interface HeadersDict {
34
26
[ header : string ] : string ;
35
27
}
36
28
37
29
export default abstract class BaseApi {
38
- // Root path of API resource without leading slash.
39
- abstract get basePath ( ) : string ;
30
+ // Root path of API resource without leading slash, can be overridden by implementing API classes as necessary
31
+ get basePath ( ) {
32
+ return environment . API_URL ;
33
+ }
40
34
41
- // API version
35
+ // API version, can be overridden by implementing API classes as necessary
42
36
get version ( ) {
43
- return "v0.1 " ;
37
+ return "v1 " ;
44
38
}
45
39
46
40
// Namespace representing the API resource
@@ -54,29 +48,28 @@ export default abstract class BaseApi {
54
48
if ( environment . API_AUTH_TOKEN ) {
55
49
headers [ "X-AUTH" ] = environment . API_AUTH_TOKEN ;
56
50
}
51
+ headers [ "Content-Type" ] = "application/json" ;
57
52
return headers ;
58
53
}
59
54
60
55
/**
61
56
* Send an API request.
62
57
*/
63
- async request (
58
+ async request < ResponseType extends APIResponse > (
64
59
method : ApiMethod ,
65
- basePath : string ,
66
- namespace : string ,
67
60
subPath : string ,
68
61
queryParamData ?: QueryParamData ,
69
62
body ?: JSONRequestBody ,
70
63
options : {
71
64
additionalHeaders ?: HeadersDict ;
72
65
} = { } ,
73
- ) {
66
+ ) : Promise < ResponseType > {
74
67
const { additionalHeaders = { } } = options ;
75
68
const url = createRequestUrl (
76
69
method ,
77
- basePath ,
70
+ this . basePath ,
78
71
this . version ,
79
- namespace ,
72
+ this . namespace ,
80
73
subPath ,
81
74
body ,
82
75
) ;
@@ -85,8 +78,7 @@ export default abstract class BaseApi {
85
78
...this . headers ,
86
79
} ;
87
80
88
- headers [ "Content-Type" ] = "application/json" ;
89
- const response = await this . sendRequest (
81
+ const response = await this . sendRequest < ResponseType > (
90
82
url ,
91
83
{
92
84
body : method === "GET" || ! body ? null : createRequestBody ( body ) ,
@@ -102,16 +94,16 @@ export default abstract class BaseApi {
102
94
/**
103
95
* Send a request and handle the response
104
96
*/
105
- private async sendRequest (
97
+ private async sendRequest < ResponseType extends APIResponse > (
106
98
url : string ,
107
99
fetchOptions : RequestInit ,
108
100
queryParamData ?: QueryParamData ,
109
- ) {
110
- let response : Response ;
111
- let responseBody : APIResponse ;
101
+ ) : Promise < ResponseType > {
102
+ let response ;
103
+ let responseBody ;
112
104
try {
113
105
response = await fetch ( url , fetchOptions ) ;
114
- responseBody = ( await response . json ( ) ) as APIResponse ;
106
+ responseBody = ( await response . json ( ) ) as ResponseType ;
115
107
} catch ( error ) {
116
108
// API most likely down, but also possibly an error setting up or sending a request
117
109
// or parsing the response.
@@ -121,16 +113,7 @@ export default abstract class BaseApi {
121
113
handleNotOkResponse ( responseBody , url , queryParamData ) ;
122
114
}
123
115
124
- const { data, message, pagination_info, status_code, warnings } =
125
- responseBody ;
126
-
127
- return {
128
- data,
129
- message,
130
- pagination_info,
131
- status_code,
132
- warnings,
133
- } ;
116
+ return responseBody ;
134
117
}
135
118
}
136
119
@@ -149,14 +132,14 @@ export function createRequestUrl(
149
132
let url = [ ...cleanedPaths ] . join ( "/" ) ;
150
133
if ( method === "GET" && body && ! ( body instanceof FormData ) ) {
151
134
// Append query string to URL
152
- const body : { [ key : string ] : string } = { } ;
135
+ const newBody : { [ key : string ] : string } = { } ;
153
136
Object . entries ( body ) . forEach ( ( [ key , value ] ) => {
154
137
const stringValue =
155
138
typeof value === "string" ? value : JSON . stringify ( value ) ;
156
- body [ key ] = stringValue ;
139
+ newBody [ key ] = stringValue ;
157
140
} ) ;
158
141
159
- const params = new URLSearchParams ( body ) . toString ( ) ;
142
+ const params = new URLSearchParams ( newBody ) . toString ( ) ;
160
143
url = `${ url } ?${ params } ` ;
161
144
}
162
145
return url ;
@@ -206,7 +189,7 @@ function handleNotOkResponse(
206
189
throwError ( response , url , searchInputs ) ;
207
190
} else {
208
191
if ( errors ) {
209
- const firstError = errors [ 0 ] as APIResponseError ;
192
+ const firstError = errors [ 0 ] ;
210
193
throwError ( response , url , searchInputs , firstError ) ;
211
194
}
212
195
}
@@ -216,9 +199,9 @@ const throwError = (
216
199
response : APIResponse ,
217
200
url : string ,
218
201
searchInputs ?: QueryParamData ,
219
- firstError ?: APIResponseError ,
202
+ firstError ?: unknown ,
220
203
) => {
221
- const { status_code, message } = response ;
204
+ const { status_code = 0 , message = "" } = response ;
222
205
console . error (
223
206
`API request error at ${ url } (${ status_code } ): ${ message } ` ,
224
207
searchInputs ,
0 commit comments