@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
JavaScript
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