UNPKG

@coveo/platform-client

Version:

The main goal of this package is to provide an easy to configure and straightforward way of querying Coveo Cloud APIs using JavaScript.

129 lines 5.13 kB
import { backOff } from 'exponential-backoff'; import getEndpoint, { Environment, Region } from './Endpoints.js'; import handleResponse from './handlers/response/ResponseHandlers.js'; import { createFetcher } from './utils/createFetcher.js'; import retrieve from './utils/Retriever.js'; import { handleRequest } from './handlers/request/RequestHandlers.js'; const HEADERS_JSON_CONTENT_TYPE = Object.freeze({ 'Content-Type': 'application/json' }); /** * Check whether the response status is `429 Too Many Requests`. * @param response */ const isTooManyRequests = (response) => response.status === 429; /** * Check whether the method is 'GET' (case insensitive). * @param value */ const isGet = (value) => (value ? /^GET$/i.test(value) : false); /** * "Logical OR" two optional abort signals. * @param signal1 * @param signal2 */ const abortOnEither = (signal1, signal2) => { if (signal1 && signal2) { const joined = new AbortController(); /** * */ function forwardAbort() { joined.abort(this.reason); } signal1.addEventListener('abort', forwardAbort); signal2.addEventListener('abort', forwardAbort); return joined.signal; } return signal1 ?? signal2; }; const withBody = (body, userArgs) => userArgs?.body ? undefined : { headers: HEADERS_JSON_CONTENT_TYPE, body: JSON.stringify(body) }; export default class API { config; isServerlessHost; static orgPlaceholder = '{organizationName}'; getRequestsController; tokenInfo; constructor(config, isServerlessHost) { this.config = config; this.isServerlessHost = isServerlessHost; this.getRequestsController = new AbortController(); } get organizationId() { if (this.config.organizationId === undefined) { throw new Error('No organization ID found in the config.'); } return retrieve(this.config.organizationId); } async get(url, args) { return await this.request(url, this.buildRequestInit('GET', args), args?.responseBodyFormat); } async post(url, body = {}, args) { return await this.request(url, this.buildRequestInit('POST', args, withBody(body, args)), args?.responseBodyFormat); } async postForm(url, body, args) { return await this.request(url, this.buildRequestInit('POST', args, { body }), args?.responseBodyFormat); } async put(url, body = {}, args) { return await this.request(url, this.buildRequestInit('PUT', args, withBody(body, args)), args?.responseBodyFormat); } async patch(url, body = {}, args) { return await this.request(url, this.buildRequestInit('PATCH', args, withBody(body, args)), args?.responseBodyFormat); } async delete(url, args) { return await this.request(url, this.buildRequestInit('DELETE', args), args?.responseBodyFormat); } abortGetRequests() { this.getRequestsController.abort(); this.getRequestsController = new AbortController(); } async checkToken() { const formData = new FormData(); formData.append('token', this.accessToken); this.tokenInfo = await this.postForm('/oauth/check_token', formData); } get currentUser() { return this.tokenInfo?.authentication; } get environment() { return this.config.environment || Environment.prod; } get region() { return this.config.region || Region.US; } get endpoint() { return (retrieve(this.isServerlessHost ? this.config.serverlessHost : this.config.host) || getEndpoint(this.environment, this.region, this.isServerlessHost)); } get accessToken() { return retrieve(this.config.accessToken); } getUrlFromRoute(route) { return `${this.endpoint}${route}`.replace(API.orgPlaceholder, this.organizationId); } buildRequestInit(method, args, prefilled) { const { responseBodyFormat: _, ...requestArgs } = args ?? {}; const globalRequestSettings = this.config.globalRequestSettings; const init = { ...prefilled, ...globalRequestSettings, ...requestArgs, method, headers: { Authorization: `Bearer ${this.accessToken}`, ...prefilled?.headers, ...globalRequestSettings?.headers, ...requestArgs?.headers, }, }; if (isGet(init.method)) { init.signal = abortOnEither(this.getRequestsController.signal, init.signal); } return init; } async request(route, init, responseBodyFormat) { const { url: enrichedRoute, ...enrichedRequestInit } = handleRequest(route, init, this.config.requestHandlers); const fetcher = createFetcher(this.getUrlFromRoute(enrichedRoute), enrichedRequestInit, isTooManyRequests); const response = await backOff(fetcher, { retry: isTooManyRequests }); return handleResponse(response, this.config.responseHandlers, responseBodyFormat); } } //# sourceMappingURL=APICore.js.map