@apptus/esales-api
Version:
Library for making requests to Elevate 4 API v3
252 lines (234 loc) • 9.08 kB
text/typescript
import { assert, addUrlParams, createBaseUrl, facetsToParams, ResponseError, type Type, type UrlParams } from './util/mod.ts';
import type { FullOptions } from './config.ts';
import type { FacetParams } from './mod.ts';
import type * as m from './models/mod.ts';
export class Query {
constructor(private readonly __config: FullOptions) {}
/**
* Retrieve recommendations for a product that has just been added to the cart.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await api.query.addToCartPopup({ variantKey: 'variant-key-123' }, {
* recommendationLists: [{
* id: 'addons',
* algorithm: 'ADD_TO_CART_RECS'
* }]
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/add-to-cart-popup/
*/
addToCartPopup(params: m.AddToCartPopupParams, recommendationLists: m.AddToCartPopupBody) {
return this.__query<m.AddToCartPopup>('add-to-cart-popup', {
params: params as Type<m.AddToCartPopupParams>,
body: { recommendationLists }
});
}
/**
* Autocomplete based on provided query parameter, for search suggestions,
* product suggestions, and more.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await api.query.autocomplete({ q: 'shirt' });
* const sale = await api.query.autocomplete({ q: 'dress' }, {
* productFilter: { discount: 50 }
* p});
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/autocomplete/
*/
autocomplete(params: m.AutocompleteParams, body?: m.AutocompleteBody) {
return this.__query<m.Autocomplete>('autocomplete', { params: params as Type<m.AutocompleteParams>, body });
}
/**
* Retrieve the complete navigation tree, suitable for a top/mobile navigation of the site.
*
* @param params query parameter options to submit
*
* @example
* ```ts
* const tree = await api.query.navigationTree();
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/navigation-tree/
*/
navigationTree(params?: m.NavigationTreeParams) {
return this.__query<m.NavigationTree>('navigation-tree', { params: params as Type<m.NavigationTreeParams> });
}
/**
* Returns a product listing with facets based on provided query, optionally
* with related navigation included.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await api.query.searchPage({ q: 'shirt' });
* const sale = await api.query.searchPage({ q: 'dress' }, {
* primaryList: {
* productFilter: { discount: 50 }
* },
* navigation: { include: true }
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/search-page/
*/
searchPage(params: m.SearchPageParams, body?: m.SearchPageBody) {
const { facets, ...p } = params;
return this.__query<m.SearchPage>('search-page', { facets, params: { ...p }, body });
}
/**
* Retrieves product information and related info suitable to show on a Product page.
* Can be configured to show various recommendation lists based on body configuration settings.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await api.query.productPage({ productKey: 'p123' }, {
* recommendationLists: [{
* id: 'alts',
* algorithm: 'ALTERNATIVES'
* }]
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/product-page/
*/
productPage(params: m.ProductPageParams, body?: m.ProductPageBody) {
return this.__query<m.ProductPage>('product-page', { params: params as Type<m.ProductPageParams>, body });
}
/**
* Retrieve products - and possibly recommendation lists - suitable for display
* on a cart page.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await api.query.cartPage({ cart: ['p123', 'p456'] }, {
* recommendationLists: [{
* id: 'addons',
* algorithm: 'CART'
* }]
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/cart-page/
*/
cartPage(params: m.CartPageParams, body?: m.CartPageBody) {
return this.__query<m.CartPage>('cart-page', { params: params as Type<m.CartPageParams>, body });
}
/**
* Request for generic landing pages, or category pages. Can return product listing with facets,
* recommendation lists, or both. Suitable for the start/home page, intermediate category pages,
* brand pages, and more.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await api.query.landingPage();
* const sale = await api.query.landingPage({ limit: 30, skip: 0 }, {
* primaryList: {
* productFilter: { discount: 50 }
* },
* recommendationLists: [{
* id: 'personal',
* algorithm: 'PERSONAL'
* }]
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/landing-page/
*/
landingPage(params: m.LandingPageParams = {}, body?: m.LandingPageBody) {
const { facets, ...p } = params;
return this.__query<m.LandingPage>('landing-page', { facets, params: { ...p }, body });
}
/**
* Request for retrieving a list of sponsored products for a Page.
*
* @beta ⚠️ This request is currently limited to a private beta and will fail otherwise.
*
* @param params query parameter options to submit
*
* @example
* ```ts
* const res = await api.query.sponsoredPage({
* pageReference: '/women/tops'
* });
* ```
* @see https://docs.apptus.com/elevate/4/integration/api/specifications/storefront/v3/queries/sponsored-page/
*/
sponsoredPage(params: m.SponsoredPageParams) {
return this.__query<m.SponsoredPage>('sponsored-page', { params: params as Type<m.SponsoredPageParams> });
}
/**
* Mirrors the Product Page, but for Content instead of Products. Retrieves content
* information for the provided `contentKeys` (required).
*
* @param params query parameter options to submit
*
* @example
* ```ts
* const res = await api.query.contentInformation({
* contentKeys: ['ck_123456', 'ck_234567']
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/content-information/
*/
contentInformation(params: m.ContentInformationParams) {
return this.__query<m.ContentInformation>('content-information', { params: params as Type<m.ContentInformationParams> });
}
/**
* Mirrors the Search Page request, but for Content instead of Products. Returns content
* results matching the provided query. Suiteable for searching in e.g. FAQ or customer service,
* where no product results are required.
*
* @param params query parameter options to submit
* @param body configuration options to submit
*
* @example
* ```ts
* const res = await this.contentSearchPage({ q: 'returns' });
* ```
* @example
* ```ts
* const res = await this.contentSearchPage({ q: 'shipping', skip: 20 }, {
* primaryList: {
* contentFilter: {
* type: 'faq'
* }
* }
* });
* ```
* @see https://docs.elevate.voyado.cloud/elevate/4/integration/api/specifications/storefront/v3/queries/content-search-page/
*/
contentSearchPage(params: m.ContentSearchPageParams, body?: m.ContentSearchPageBody) {
return this.__query<m.ContentSearchPage>('content-search-page', { params: params as Type<m.ContentSearchPageParams>, body });
}
private async __query<T>(endpoint: string, options: { params?: UrlParams, facets?: FacetParams, body?: object }) {
const { params = {}, facets, body } = options;
assert(typeof params === 'object', 'If provided, params must be an object');
const url = await createBaseUrl(`queries/${endpoint}`, this.__config);
const { locale, touchpoint } = this.__config;
addUrlParams(url, { locale, touchpoint, ...params, ...facetsToParams(facets) });
const init: RequestInit = !body ?
{ method: 'GET' } :
{ method: 'POST', headers: { 'Content-Type': 'text/plain' }, body: JSON.stringify(body) };
const res = await fetch(url, init);
const content = await res.json();
// TODO: res.ok
if (res.status >= 200 && res.status < 400) {
return content as T;
}
throw new ResponseError(content);
}
}