* Make an authenticated API request.
(url: string, request?: Partial<Options>)
| 277 | * Make an authenticated API request. |
| 278 | */ |
| 279 | async apiRequest(url: string, request?: Partial<Options>) { |
| 280 | await this.ensureAuthenticated(); |
| 281 | request = { |
| 282 | ...request, |
| 283 | headers: { |
| 284 | authorization: `Bearer ${this.accessToken}`, |
| 285 | "content-type": "application/json", |
| 286 | ...(request || {}).headers, |
| 287 | }, |
| 288 | }; |
| 289 | return retry<Record<string, any> | null>( |
| 290 | // Automatically retry network errors |
| 291 | async () => { |
| 292 | const response = await this.request.fetch(url, request); |
| 293 | |
| 294 | if (!response.ok()) { |
| 295 | const responsePayload = await response.text(); |
| 296 | throw new Error( |
| 297 | `API Error ${response.status()} ${url}, req: ${ |
| 298 | JSON.stringify(request.data) ?? "No request body" |
| 299 | }, res: ${JSON.stringify(responsePayload) ?? "No response body"}`, |
| 300 | ); |
| 301 | } |
| 302 | return response; |
| 303 | }, |
| 304 | // No exponential backoff |
| 305 | { retries: 2, minTimeout: 1000, factor: 1 }, |
| 306 | ); |
| 307 | } |
| 308 | |
| 309 | /** Block or unblock an organization **/ |
| 310 | async setFronteggTenantBlockedStatus(blocked: boolean) { |