UNPKG

@commercetools/api-request-builder

Version:

Helper functions to construct API requests URI for the commercetools platform in a declarative way.

1,236 lines (1,161 loc) 41.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /** * NOTE: * These are so called implicit features * which work on endpoints automatically as they only * differ in the http method and request body * and do not need any further processing. * We specify these on endpoints for documentation purposes * only. */ var create = 'create'; var update = 'update'; // `delete` is a reserved word in JavaScript var del = 'delete'; /** * NOTE: * These are so called explicit features * which only work on a subset of endpoints and perform * additional manipulation on the request. */ var query$1 = 'query'; var queryOne = 'queryOne'; var queryExpand$1 = 'queryExpand'; var queryLocation$1 = 'queryLocation'; var search = 'search'; var projection = 'projection'; var suggest = 'suggest'; var features = /*#__PURE__*/Object.freeze({ __proto__: null, create: create, update: update, del: del, query: query$1, queryOne: queryOne, queryExpand: queryExpand$1, queryLocation: queryLocation$1, search: search, projection: projection, suggest: suggest }); var services = { login: { type: 'login', endpoint: '/login', features: [create] }, cartDiscounts: { type: 'cart-discounts', endpoint: '/cart-discounts', features: [create, update, del, query$1, queryOne, queryExpand$1] }, carts: { type: 'carts', endpoint: '/carts', features: [create, update, del, query$1, queryOne, queryExpand$1] }, categories: { type: 'categories', endpoint: '/categories', features: [create, update, del, query$1, queryOne, queryExpand$1] }, channels: { type: 'channels', endpoint: '/channels', features: [create, update, del, query$1, queryOne, queryExpand$1] }, customerGroups: { type: 'customer-groups', endpoint: '/customer-groups', features: [create, update, del, query$1, queryOne, queryExpand$1] }, customers: { type: 'customers', endpoint: '/customers', features: [create, update, del, query$1, queryOne, queryExpand$1] }, customersPassword: { type: 'customers-password', endpoint: '/customers/password', features: [create] }, customersPasswordToken: { type: 'customers-password-token', endpoint: '/customers/password-token', features: [create, queryOne] }, customersPasswordReset: { type: 'customers-password-reset', endpoint: '/customers/password/reset', features: [create] }, customersEmailVerificationToken: { type: 'customers-email-verification-token', endpoint: '/customers/email-token', features: [create, queryOne] }, customersEmailVerification: { type: 'customers-email-verification', endpoint: '/customers/email/confirm', features: [create] }, customObjects: { type: 'custom-objects', endpoint: '/custom-objects', features: [create, update, del, query$1, queryOne, queryExpand$1] }, discountCodes: { type: 'discount-codes', endpoint: '/discount-codes', features: [create, update, del, query$1, queryOne, queryExpand$1] }, extensions: { type: 'extensions', endpoint: '/extensions', features: [create, update, del, query$1, queryOne, queryExpand$1] }, inventory: { type: 'inventory', endpoint: '/inventory', features: [create, update, del, query$1, queryOne, queryExpand$1] }, messages: { type: 'messages', endpoint: '/messages', features: [query$1, queryOne, queryExpand$1] }, myActiveCart: { type: 'my-carts', endpoint: '/me/active-cart', features: [queryOne] }, myCarts: { type: 'my-carts', endpoint: '/me/carts', features: [create, update, del, query$1, queryOne, queryExpand$1] }, myOrders: { type: 'my-orders', endpoint: '/me/orders', features: [create, update, del, query$1, queryOne, queryExpand$1] }, orders: { type: 'orders', endpoint: '/orders', features: [create, update, del, query$1, queryOne, queryExpand$1] }, orderEdits: { type: 'orders-edits', endpoint: '/orders/edits', features: [create, update, del, query$1, queryOne, queryExpand$1] }, orderImport: { type: 'orderImport', endpoint: '/orders/import', features: [create, query$1] }, payments: { type: 'payments', endpoint: '/payments', features: [create, update, del, query$1, queryOne, queryExpand$1] }, productDiscounts: { type: 'product-discounts', endpoint: '/product-discounts', features: [create, update, del, query$1, queryOne, queryExpand$1] }, productProjections: { type: 'product-projections', endpoint: '/product-projections', features: [query$1, queryOne, queryExpand$1, projection] }, productProjectionsSearch: { type: 'product-projections-search', endpoint: '/product-projections/search', features: [search, queryOne, queryExpand$1, projection] }, productProjectionsSuggest: { type: 'product-projections-suggest', endpoint: '/product-projections/suggest', features: [search, suggest, queryOne, projection] }, products: { type: 'products', endpoint: '/products', features: [create, update, del, query$1, queryOne, queryExpand$1] }, productTypes: { type: 'product-types', endpoint: '/product-types', features: [create, update, del, query$1, queryOne, queryExpand$1] }, project: { type: 'project', endpoint: '/', features: [update, query$1] }, reviews: { type: 'reviews', endpoint: '/reviews', features: [create, update, del, query$1, queryOne, queryExpand$1] }, shippingMethods: { type: 'shipping-methods', endpoint: '/shipping-methods', features: [create, update, del, query$1, queryOne, queryExpand$1, queryLocation$1] }, shoppingLists: { type: 'shopping-lists', endpoint: '/shopping-lists', features: [create, update, del, query$1, queryOne, queryExpand$1] }, states: { type: 'states', endpoint: '/states', features: [create, update, del, query$1, queryOne, queryExpand$1] }, stores: { type: 'stores', endpoint: '/stores', features: [create, update, del, query$1, queryOne, queryExpand$1] }, subscriptions: { type: 'subscriptions', endpoint: '/subscriptions', features: [create, update, del, query$1, queryOne, queryExpand$1] }, taxCategories: { type: 'tax-categories', endpoint: '/tax-categories', features: [create, update, del, query$1, queryOne, queryExpand$1] }, types: { type: 'types', endpoint: '/types', features: [create, update, del, query$1, queryOne, queryExpand$1] }, zones: { type: 'zones', endpoint: '/zones', features: [create, update, del, query$1, queryOne, queryExpand$1] } }; /** * Return the default parameters for building a query string. * * @return {Object} */ function getDefaultQueryParams() { return { id: null, expand: [], pagination: { page: null, perPage: null, sort: [], withTotal: null }, location: { currency: '', country: '', state: '' }, query: { operator: 'and', where: [] }, searchKeywords: [] }; } /** * Return the default parameters for building a query search string. * * @return {Object} */ function getDefaultSearchParams() { return { expand: [], searchKeywords: [], pagination: { page: null, perPage: null, sort: [], withTotal: null }, search: { facet: [], filter: [], filterByQuery: [], filterByFacets: [], fuzzy: false, fuzzyLevel: 0, markMatchingVariants: false, text: null } }; } /** * Set the default parameters given the current service object. * * @return {void} */ function setDefaultParams() { this.params.expand = getDefaultQueryParams().expand; this.params.key = null; if (this.features.includes(queryOne)) this.params.id = getDefaultQueryParams().id; if (this.features.includes(query$1)) { this.params.pagination = getDefaultQueryParams().pagination; this.params.query = getDefaultQueryParams().query; } if (this.features.includes(search)) { this.params.pagination = getDefaultSearchParams().pagination; this.params.search = getDefaultSearchParams().search; } if (this.features.includes(queryLocation$1)) this.params.location = getDefaultQueryParams().location; if (this.features.includes(suggest)) this.params.searchKeywords = []; } var hasKey = function hasKey(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); }; /** * Set the supplied parameters given the current service object. * * @return {void} */ function setParams(params) { var _this = this; // verify params var knownKeys = ['expand', 'id', 'key', 'customerId', 'cartId', 'sort', 'page', 'perPage', 'staged', 'priceCurrency', 'priceCountry', 'priceCustomerGroup', 'priceChannel', 'text', 'fuzzy', 'fuzzyLevel', 'markMatchingVariants', 'facet', 'filter', 'filterByQuery', 'filterByFacets', 'searchKeywords', 'where', 'whereOperator', 'version', 'country', 'currency', 'state', 'dataErasure', 'withTotal', 'applyOrderEditTo', 'container', 'orderNumber']; Object.keys(params).forEach(function (key) { if (!knownKeys.includes(key)) throw new Error("Unknown key \"".concat(key, "\"")); }); // query-expand if (params.expand) params.expand.forEach(function (expansion) { _this.expand(expansion); }); // query-id if (hasKey(params, 'id')) this.byId(params.id); if (hasKey(params, 'key') && !hasKey(params, 'container')) this.byKey(params.key); if (hasKey(params, 'customerId')) this.byCustomerId(params.customerId); if (hasKey(params, 'cartId')) this.byCartId(params.cartId); // query-location if (hasKey(params, 'country')) this.byCountry(params.country); if (hasKey(params, 'currency')) this.byCurrency(params.currency); if (hasKey(params, 'state')) this.byState(params.state); // query-page if (params.sort) params.sort.forEach(function (sortDesc) { _this.sort(sortDesc.by, sortDesc.direction === 'asc'); }); if (hasKey(params, 'page')) this.page(params.page); if (hasKey(params, 'perPage')) this.perPage(params.perPage); // query-projection if (hasKey(params, 'staged')) this.staged(params.staged); if (hasKey(params, 'priceCurrency')) this.priceCurrency(params.priceCurrency); if (hasKey(params, 'priceCountry')) this.priceCountry(params.priceCountry); if (hasKey(params, 'priceCustomerGroup')) this.priceCustomerGroup(params.priceCustomerGroup); if (hasKey(params, 'priceChannel')) this.priceChannel(params.priceChannel); if (hasKey(params, 'orderNumber')) this.byOrderNumber(params.orderNumber); // query-search if (params.text) this.text(params.text.value, params.text.language); if (params.fuzzy) this.fuzzy(); // boolean switch if (hasKey(params, 'fuzzyLevel')) this.fuzzyLevel(params.fuzzyLevel); if (params.markMatchingVariants) this.markMatchingVariants(); // boolean switch if (params.facet) params.facet.forEach(function (facet) { _this.facet(facet); }); if (params.filter) params.filter.forEach(function (filter) { _this.filter(filter); }); if (params.filterByQuery) params.filterByQuery.forEach(function (query) { _this.filterByQuery(query); }); if (params.filterByFacets) params.filterByFacets.forEach(function (facet) { _this.filterByFacets(facet); }); // query-suggest if (params.searchKeywords) params.searchKeywords.forEach(function (searchKeyword) { _this.searchKeywords(searchKeyword.value, searchKeyword.language); }); // query if (params.where) params.where.forEach(function (predicate) { _this.where(predicate); }); if (hasKey(params, 'whereOperator')) this.whereOperator(params.whereOperator); // version if (hasKey(params, 'version')) this.withVersion(params.version); // dataErasure if (hasKey(params, 'dataErasure')) this.withFullDataErasure(); // withTotal if (hasKey(params, 'withTotal')) this.withTotal(params.withTotal); // withTotal if (hasKey(params, 'applyOrderEditTo')) this.applyOrderEditTo(params.applyOrderEditTo); // container and key if (hasKey(params, 'container') && hasKey(params, 'key')) this.byContainerAndKey(params.container, params.key); } /** * Given an object, return a clone with non-function properties defined as * non-enumerable, unwritable, and unconfigurable. * * @param {Object} * @return {Object} */ function classify(object) { var forceEnumerable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var clone = {}; Object.keys(object).forEach(function (key) { Object.defineProperty(clone, key, { value: object[key], enumerable: forceEnumerable ? true : typeof object[key] === 'function' }); }); return clone; } /** * Build the query string with the given parameters. * * @param {Object} params - An object with query / search parameters. * @throws If argument is missing. * @return {string} The fully encoded query string. */ function buildQueryString(params) { if (!params) throw new Error('Missing options object to build query string.'); var query = params.query, pagination = params.pagination, search = params.search, expand = params.expand, staged = params.staged, priceCurrency = params.priceCurrency, priceCountry = params.priceCountry, priceCustomerGroup = params.priceCustomerGroup, priceChannel = params.priceChannel, searchKeywords = params.searchKeywords, version = params.version, customerId = params.customerId, cartId = params.cartId, location = params.location, dataErasure = params.dataErasure, applyOrderEditTo = params.applyOrderEditTo; var queryString = []; if (customerId) queryString.push("customerId=".concat(customerId)); if (cartId) queryString.push("cartId=".concat(cartId)); if (typeof staged === 'boolean') queryString.push("staged=".concat(staged.toString())); if (priceCurrency) queryString.push("priceCurrency=".concat(priceCurrency)); if (priceCountry) queryString.push("priceCountry=".concat(priceCountry)); if (priceCustomerGroup) queryString.push("priceCustomerGroup=".concat(priceCustomerGroup)); if (priceChannel) queryString.push("priceChannel=".concat(priceChannel)); if (expand && expand.length) queryString = queryString.concat(expand.map(function (e) { return "expand=".concat(e); })); if (query) { var operator = query.operator, where = query.where; var whereParams = where.join(encodeURIComponent(" ".concat(operator, " "))); if (whereParams) queryString.push("where=".concat(whereParams)); } if (location) { var country = location.country, currency = location.currency, state = location.state; if (country) queryString.push("country=".concat(country)); if (currency) queryString.push("currency=".concat(currency)); if (state) queryString.push("state=".concat(state)); } if (pagination) { var page = pagination.page, perPage = pagination.perPage, sort = pagination.sort, withTotal = pagination.withTotal; if (typeof perPage === 'number') queryString.push("limit=".concat(perPage)); if (page) { var limitParam = perPage || 20; var offsetParam = limitParam * (page - 1); queryString.push("offset=".concat(offsetParam)); } if (sort && sort.length) queryString = queryString.concat(sort.map(function (s) { return "sort=".concat(s); })); if (typeof withTotal === 'boolean') queryString.push("withTotal=".concat(String(withTotal))); } if (search) { var text = search.text, fuzzy = search.fuzzy, fuzzyLevel = search.fuzzyLevel, markMatchingVariants = search.markMatchingVariants, facet = search.facet, filter = search.filter, filterByQuery = search.filterByQuery, filterByFacets = search.filterByFacets; if (text) queryString.push("text.".concat(text.lang, "=").concat(text.value)); if (fuzzy) queryString.push('fuzzy=true'); if (fuzzyLevel) queryString.push("fuzzyLevel=".concat(fuzzyLevel)); queryString.push("markMatchingVariants=".concat(markMatchingVariants.toString())); facet.forEach(function (f) { return queryString.push("facet=".concat(f)); }); filter.forEach(function (f) { return queryString.push("filter=".concat(f)); }); filterByQuery.forEach(function (f) { return queryString.push("filter.query=".concat(f)); }); filterByFacets.forEach(function (f) { return queryString.push("filter.facets=".concat(f)); }); } if (searchKeywords) searchKeywords.forEach(function (f) { return queryString.push("searchKeywords.".concat(f.lang, "=").concat(f.value)); }); if (version) queryString.push("version=".concat(version)); if (dataErasure) queryString.push(dataErasure); if (applyOrderEditTo) queryString.push("/".concat(applyOrderEditTo, "/apply")); return queryString.join('&'); } /** * Set the `version` number to the internal state of the service instance * in order to generate a uri with the resource version (for example; to * perform a `DELETE` request) * * @param {number} version - The version of the resource * @throws if `version` is missing or not a number. * @return {Object} The instance of the service, can be chained. */ function withVersion(version) { if (typeof version !== 'number') throw new Error('A resource version is missing or invalid'); this.params.version = version; return this; } /** * Set the `dataErasure` option to the internal state of the service instance * in order to generate a DELETE uri that guarantees that all personal data related to * the particular object, including invisible data, is erased, in compliance with the GDPR. * * Users are, however, responsible for identifying and deleting all objects that belong to a customer, and deleting them. * * More info here: https://docs.commercetools.com/release-notes#releases-2018-05-24-data-erasure * * @return {Object} The instance of the service, can be chained. */ function withFullDataErasure() { this.params.dataErasure = 'dataErasure=true'; return this; } /** * `Apply an OrderEdit` to an `order` by providing a correct Order Edit ID * * More info here: https://docs.commercetools.com/http-api-projects-order-edits#apply-an-orderedit * * @param {string} orderEditId - The ID of the Order Edit. * * @return {Object} The instance of the service, can be chained. */ function applyOrderEditTo(orderEditId) { if (typeof orderEditId !== 'string') throw new Error('A resource orderEditId is missing or invalid'); this.params.applyOrderEditTo = orderEditId; return this; } /** * Set the given `predicate` to the internal state of the service instance. * * @param {string} predicate - A non-URI encoded string representing a * [Predicate]{@link http://dev.sphere.io/http-api.html#predicates} * @throws If `predicate` is missing. * @return {Object} The instance of the service, can be chained. */ function where(predicate) { if (!predicate) throw new Error('Required argument for `where` is missing'); var encodedPredicate = encodeURIComponent(predicate); this.params.query.where.push(encodedPredicate); return this; } /** * Set the logical operator to combine multiple query predicates * {@link module:commons/query.where} * * @param {string} operator - A logical operator `and`, `or` * @throws If `operator` is missing or has a wrong value. * @return {Object} The instance of the service, can be chained. */ function whereOperator(operator) { if (!operator) throw new Error('Required argument for `whereOperator` is missing'); if (!(operator === 'and' || operator === 'or')) throw new Error('Required argument for `whereOperator` is invalid, ' + 'allowed values are (`and`, `or`)'); this.params.query.operator = operator; return this; } var query = /*#__PURE__*/Object.freeze({ __proto__: null, where: where, whereOperator: whereOperator }); /** * Set the given `id` to the internal state of the service instance. * * @param {string} id - A resource `UUID` * @throws If `id` is missing. * @return {Object} The instance of the service, can be chained. */ function byId(id) { if (!id) throw new Error('Required argument for `byId` is missing'); if (this.params.key) throw new Error('A key for this resource has already been set. ' + 'You cannot use both `byKey` and `byId`.'); if (this.params.customerId) throw new Error('A customerId for this resource has already been set. ' + 'You cannot use both `byId` and `byCustomerId`.'); if (this.params.cartId) throw new Error('A cartId for this resource has already been set. ' + 'You cannot use both `byId` and `byCartId`.'); this.params.id = id; return this; } /** * Set the given `key` to the internal state of the service instance. * * @param {string} key - A resource `key` * @throws If `key` is missing. * @return {Object} The instance of the service, can be chained. */ function byKey(key) { if (!key) throw new Error('Required argument for `byKey` is missing'); if (this.params.id) throw new Error('An ID for this resource has already been set. ' + 'You cannot use both `byId` and `byKey`.'); this.params.key = key; return this; } /** * Set the given `id` to the `customerId`internal state of the service instance. * For querying customer carts * * @param {string} id - A resource `UUID` * @throws If `id` is missing. * @return {Object} The instance of the service, can be chained. */ function byCustomerId(custId) { if (!custId) throw new Error('Required argument for `byCustomerId` is missing'); if (this.params.id) throw new Error('An ID for this resource has already been set. ' + 'You cannot use both `byId` and `byCustomerId`.'); this.params.customerId = custId; return this; } /** * Set the given `orderNumber` to the `orderNumber` internal state of the service instance. * For querying orders * * @param {string} orderNumber - An order number * @throws If `orderNumber` is missing or invalid * @return {Object} The instance of the service, can be chained. */ function byOrderNumber(orderNumber) { if (typeof orderNumber !== 'string') throw new Error('Required argument for `byOrderNumber` is missing or invalid'); this.params.orderNumber = orderNumber; return this; } /** * Set the given `id` to the `cartId` internal state of the service instance. * For querying shipping methods by cart id * * @param {string} id - A resource `UUID` * @throws If `id` is missing. * @return {Object} The instance of the service, can be chained. */ function byCartId(cartId) { if (!cartId) throw new Error('Required argument for `byCartId` is missing'); if (this.params.id) throw new Error('An ID for this resource has already been set. ' + 'You cannot use both `byId` and `byCartId`.'); this.params.cartId = cartId; return this; } /** * Set the given `container` and `key` to the internal state of the service instance. * * @param {string} container - A resource `container` * @param {string} key - A resource `key` * @throws If `container` or `key` is missing. * @return {Object} The instance of the service, can be chained. */ function byContainerAndKey(container, key) { if (typeof container !== 'string' || typeof key !== 'string') throw new Error('Required `container` or `key` argument for `byContainerAndKey` needs to be a string'); this.params.container = container; this.params.key = key; return this; } var queryId = /*#__PURE__*/Object.freeze({ __proto__: null, byId: byId, byKey: byKey, byCustomerId: byCustomerId, byOrderNumber: byOrderNumber, byCartId: byCartId, byContainerAndKey: byContainerAndKey }); /** * Set the given `country` param used for selection by country * * @param {string} value - A two-digit country code as per ISO 3166-1 alpha-2 * @return {Object} The instance of the service, can be chained. */ function byCountry(value) { if (!value) throw new Error('Required argument for `byCountry` is missing'); this.params.location.country = value; return this; } /** * Set the given `currency` param used for selection by currency. * * @param {string} value - The currency code compliant to ISO 4217 * Can only be used with country parameter * @return {Object} The instance of the service, can be chained. */ function byCurrency(value) { if (!value) throw new Error('Required argument for `byCurrency` is missing'); // logic to verify country has been set if (!this.params.location.country) throw new Error('A `country` for this resource has not been set. ' + 'You must set the country in order to use the `byCurrency` method.'); this.params.location.currency = value; return this; } /** * Set the given `state` param used for selection by state. * * @param {string} value - A string representing State name * Can only be used with country parameter * @return {Object} The instance of the service, can be chained. */ function byState(value) { if (!value) throw new Error('Required argument for `byState` is missing'); // logic to verify country has been set if (!this.params.location.country) throw new Error('A `country` for this resource has not been set. ' + 'You must set the country in order to use the `byState` method.'); this.params.location.state = value; return this; } var queryLocation = /*#__PURE__*/Object.freeze({ __proto__: null, byCountry: byCountry, byCurrency: byCurrency, byState: byState }); /** * Set the * [ExpansionPath](http://dev.sphere.io/http-api.html#reference-expansion) * used for expanding a * [Reference](http://dev.sphere.io/http-api-types.html#reference) * of a resource. * * @param {string} value - The expand path expression. * @throws If `value` is missing. * @return {Object} The instance of the service, can be chained. */ // eslint-disable-next-line import/prefer-default-export function expand(value) { if (!value) throw new Error('Required argument for `expand` is missing'); var encodedPath = encodeURIComponent(value); // Note: this goes to base `params`, not `params.query` // to be compatible with search. this.params.expand.push(encodedPath); return this; } var queryExpand = /*#__PURE__*/Object.freeze({ __proto__: null, expand: expand }); /** * Set the sort expression for the query, if the related endpoint supports it. * It is possible to specify several `sort` parameters. * In this case they are combined into a composed `sort` where the results * are first sorted by the first expression, followed by equal values being * sorted according to the second expression, and so on. * * @param {string} sortPath - The sort path expression. * @param {boolean} [ascending] - Whether the direction should be * ascending or not (default: `true`). * @throws If `sortPath` is missing. * @return {Object} The instance of the service, can be chained. */ function sort(sortPath) { var ascending = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (!sortPath) throw new Error('Required argument for `sort` is missing'); var direction = ascending ? 'asc' : 'desc'; var encodedSort = encodeURIComponent("".concat(sortPath, " ").concat(direction)); this.params.pagination.sort.push(encodedSort); return this; } /** * Set the page number to be requested from the complete query result * (used for pagination as `offset`) * * @param {string} value - The page number, greater then zero. * @throws If `value` is missing or is a number lesser then one. * @return {Object} The instance of the service, can be chained. */ function page(value) { if (typeof value !== 'number' && !value) throw new Error('Required argument for `page` is missing or invalid'); if (typeof value !== 'number' || value < 1) throw new Error('Required argument for `page` must be a number >= 1'); this.params.pagination.page = value; return this; } /** * Set the number of results to be returned from a query result * (used for pagination as `limit`) * * @param {string} value - How many results in a page, * greater or equals then zero. * @throws If `value` is missing or is a number lesser then zero. * @return {Object} The instance of the service, can be chained. */ function perPage(value) { if (typeof value !== 'number' && !value) throw new Error('Required argument for `perPage` is missing or invalid'); if (typeof value !== 'number' || value < 0) throw new Error('Required argument for `perPage` must be a number >= 0'); this.params.pagination.perPage = value; return this; } /** * Set whether or not the total should be calculated (and included) in the result * of a paginated query result. * * @param {boolean} value - indicating if the total should be included or not */ function withTotal() { var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; if (typeof value !== 'boolean') throw new Error('Required argument for `withTotal` is missing or invalid'); this.params.pagination.withTotal = value; return this; } var queryPage = /*#__PURE__*/Object.freeze({ __proto__: null, sort: sort, page: page, perPage: perPage, withTotal: withTotal }); /** * Define whether to get the staged or current projection * * @param {boolean} staged - Either `true` (default) or `false` * (for current / published) * @return {Object} The instance of the service, can be chained. */ function staged() { var shouldFetchStaged = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; this.params.staged = shouldFetchStaged; return this; } /** * Define whether to set price Selection or not * Set the given `priceCurrency` param used for price selection. * * @param {string} value - The currency code compliant to ISO 4217 * @return {Object} The instance of the service, can be chained. */ function priceCurrency(value) { this.params.priceCurrency = value; return this; } /** * Define whether to set price Selection or not * Set the given `priceCountry` param used for price selection. * * @param {string} value - A two-digit country code as per ISO 3166-1 alpha-2 * Can only be used with priceCurrency parameter * @return {Object} The instance of the service, can be chained. */ function priceCountry(value) { this.params.priceCountry = value; return this; } /** * Define whether to set price Selection or not * Set the given `priceCustomerGroup` param used for price selection. * * @param {string} value - price customer group UUID * Can only be used with priceCurrency parameter * @return {Object} The instance of the service, can be chained. */ function priceCustomerGroup(value) { this.params.priceCustomerGroup = value; return this; } /** * Define whether to set price Selection or not * Set the given `priceChannel` param used for price selection. * * @param {string} value - price channel UUID * Can only be used with priceCurrency parameter * @return {Object} The instance of the service, can be chained. */ function priceChannel(value) { this.params.priceChannel = value; return this; } var queryProjection = /*#__PURE__*/Object.freeze({ __proto__: null, staged: staged, priceCurrency: priceCurrency, priceCountry: priceCountry, priceCustomerGroup: priceCustomerGroup, priceChannel: priceChannel }); /** * Define a Suggestion used for matching tokens for product projections, * via a suggest tokenizer. * * The suggestions can be used to implement a basic auto-complete functionality. * The source of data for suggestions is the searchKeyword field in a product. * * @param {string} value - A non-URI encoded string representing a * text to search for. * @param {string} lang - An ISO language tag, used for search * the given text in localized content. * @throws If `value` or `lang` is missing. * @return {Object} The instance of the service, can be chained. */ // eslint-disable-next-line import/prefer-default-export function searchKeywords(value, lang) { if (!value || !lang) throw new Error('Required arguments for `searchKeywords` are missing'); this.params.searchKeywords.push({ lang: lang, value: encodeURIComponent(value) }); return this; } var querySuggest = /*#__PURE__*/Object.freeze({ __proto__: null, searchKeywords: searchKeywords }); /** * Set the given `text` param used for full-text search. * * @param {string} value - A non-URI encoded string representing a * text to search for. * @param {string} lang - An ISO language tag, used for search * the given text in localized content. * @throws If `value` or `lang` is missing. * @return {Object} The instance of the service, can be chained. */ function text(value, lang) { if (!value || !lang) throw new Error('Required arguments for `text` are missing'); this.params.search.text = { lang: lang, value: encodeURIComponent(value) }; return this; } /** * Define whether to enable the fuzzy search. * * @return {Object} The instance of the service, can be chained. */ function fuzzy() { this.params.search.fuzzy = true; return this; } /** * Define the level of the fuzzy search * * @param {number} value - An integer representing the fuzzy level * @throws If `value` is missing. * @return {Object} The instance of the service, can be chained. */ function fuzzyLevel(value) { if (value === undefined || value === null) throw new Error('Required argument for `fuzzyLevel` is missing'); this.params.search.fuzzyLevel = value; return this; } /** * Define whether to enable markMatchingVariants * * @return {Object} The instance of the service, can be chained. */ function markMatchingVariants() { this.params.search.markMatchingVariants = true; return this; } /** * Set the given `facet` filter used for calculating statistical counts. * * @param {string} value - A non-URI encoded string representing a * facet expression. * @throws If `value` is missing. * @return {Object} The instance of the service, can be chained. */ function facet(value) { if (!value) throw new Error('Required argument for `facet` is missing'); var encodedFacet = encodeURIComponent(value); this.params.search.facet.push(encodedFacet); return this; } /** * Set the given `filter` param used for filtering search results. * * @param {string} value - A non-URI encoded string representing a * filter expression. * @throws If `value` is missing. * @return {Object} The instance of the service, can be chained. */ function filter(value) { if (!value) throw new Error('Required argument for `filter` is missing'); var encodedFilter = encodeURIComponent(value); this.params.search.filter.push(encodedFilter); return this; } /** * Set the given `filter.query` param used for filtering search results. * * @param {string} value - A non-URI encoded string representing a * filter by query expression. * @throws If `value` is missing. * @return {Object} The instance of the service, can be chained. */ function filterByQuery(value) { if (!value) throw new Error('Required argument for `filterByQuery` is missing'); var encodedFilter = encodeURIComponent(value); this.params.search.filterByQuery.push(encodedFilter); return this; } /** * Set the given `filter.facets` param used for filtering search results. * * @param {string} value - A non-URI encoded string representing a * filter by query expression. * @throws If `value` is missing. * @return {Object} The instance of the service, can be chained. */ function filterByFacets(value) { if (!value) throw new Error('Required argument for `filterByFacets` is missing'); var encodedFilter = encodeURIComponent(value); this.params.search.filterByFacets.push(encodedFilter); return this; } var querySearch = /*#__PURE__*/Object.freeze({ __proto__: null, text: text, fuzzy: fuzzy, fuzzyLevel: fuzzyLevel, markMatchingVariants: markMatchingVariants, facet: facet, filter: filter, filterByQuery: filterByQuery, filterByFacets: filterByFacets }); var requiredDefinitionProps = ['type', 'endpoint', 'features']; function getIdOrKey(params) { if (params.id) return "/".concat(params.id); if (params.orderNumber) return "/order-number=".concat(params.orderNumber); if (params.key && !params.container) return "/key=".concat(params.key); if (params.key && params.container) return "/".concat(params.container, "/").concat(params.key); return ''; } function createService(definition) { var projectKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; if (!definition) throw new Error('Cannot create a service without its definition.'); requiredDefinitionProps.forEach(function (key) { if (!definition[key]) throw new Error("Definition is missing required parameter ".concat(key, ".")); }); if (!Array.isArray(definition.features) || !definition.features.length) throw new Error('Definition requires `features` to be a non empty array.'); if (!projectKey) throw new Error('No project defined. Please enter a project key'); var type = definition.type, endpoint = definition.endpoint, features$1 = definition.features; return classify(_objectSpread2(_objectSpread2({ type: type, features: features$1, params: getDefaultQueryParams(), withVersion: withVersion, withFullDataErasure: withFullDataErasure, applyOrderEditTo: applyOrderEditTo }, features$1.reduce(function (acc, feature) { if (feature === query$1) return _objectSpread2(_objectSpread2(_objectSpread2({}, acc), query), queryPage); if (feature === queryOne) return _objectSpread2(_objectSpread2({}, acc), queryId); if (feature === queryLocation$1) return _objectSpread2(_objectSpread2({}, acc), queryLocation); if (feature === queryExpand$1) return _objectSpread2(_objectSpread2({}, acc), queryExpand); if (feature === search) return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, acc), querySearch), queryPage), {}, { params: getDefaultSearchParams() }); if (feature === suggest) return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, acc), querySearch), queryPage), querySuggest); if (feature === projection) return _objectSpread2(_objectSpread2({}, acc), queryProjection); return acc; }, {})), {}, { // Call this method to get the built request URI // Pass some options to further configure the URI: // - `withProjectKey: false`: will omit the projectKey from the URI build: function build() { var uriOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { withProjectKey: true, applyOrderEdit: false }; var withProjectKey = uriOptions.withProjectKey, applyOrderEdit = uriOptions.applyOrderEdit; var queryParams = buildQueryString(this.params); var uri = (withProjectKey ? "/".concat(projectKey) : '') + endpoint + // TODO this can lead to invalid URIs as getIdOrKey can return // "/?customerId", so there can be multiple question marks, // same for when `queryParams` and `version` are present getIdOrKey(this.params) + (queryParams && !applyOrderEdit ? "?".concat(queryParams) : queryParams); setDefaultParams.call(this); return uri; }, // Call this method to parse an object as params parse: function parse(params) { setParams.call(this, params); return this; } })); } // pass an options argument of type object containing // the `projectkey` (string) and `customServices` (object) // The projectKey property is required // A sample options object would be: // // options: { // projectKey: 'myProject', // customServices: { // foo: { // type: 'foo', // endpoint: '/foo', // features: [ // features.query, // ], // } // } // } function createRequestBuilder() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var allServices = _objectSpread2(_objectSpread2({}, services), options.customServices); return Object.keys(allServices).reduce(function (acc, key) { return _objectSpread2(_objectSpread2({}, acc), {}, _defineProperty({}, key, createService(allServices[key], options.projectKey))); }, {}); } exports.createRequestBuilder = createRequestBuilder; exports.features = features;