@shopgate/pwa-common-commerce
Version:
Commerce library for the Shopgate Connect PWA.
46 lines • 9.41 kB
JavaScript
var _excluded=["offset","limit"];function _objectWithoutProperties(source,excluded){if(source==null)return{};var target=_objectWithoutPropertiesLoose(source,excluded);var key,i;if(Object.getOwnPropertySymbols){var sourceSymbolKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceSymbolKeys.length;i++){key=sourceSymbolKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key];}}return target;}function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}return target;}function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import difference from'lodash/difference';import PipelineRequest from'@shopgate/pwa-core/classes/PipelineRequest';import{generateResultHash,shouldFetchData}from'@shopgate/pwa-common/helpers/redux';import{isNumber}from'@shopgate/pwa-common/helpers/validation';import configuration from'@shopgate/pwa-common/collections/Configuration';import{DEFAULT_PRODUCTS_FETCH_PARAMS}from'@shopgate/pwa-common/constants/Configuration';import{SORT_SCOPE_CATEGORY}from'@shopgate/engage/filter/constants';import{makeGetDefaultSortOrder}from'@shopgate/engage/filter/selectors';import{getFulfillmentParams}from'@shopgate/pwa-common-commerce/product/selectors/product';import{SHOPGATE_CATALOG_GET_PRODUCTS,SHOPGATE_CATALOG_GET_HIGHLIGHT_PRODUCTS,SHOPGATE_CATALOG_GET_LIVESHOPPING_PRODUCTS}from"../constants/Pipelines";import buildRequestFilters from"../../filter/actions/helpers/buildRequestFilters";import requestProducts from"../action-creators/requestProducts";import receiveProducts from"../action-creators/receiveProducts";import errorProducts from"../action-creators/errorProducts";import deleteProductsByIds from"../action-creators/deleteProductsByIds";import receiveProductsCached from"../action-creators/receiveProductsCached";import{makeGetProductResultByCustomHash}from"../selectors/product";/**
* Process the pipeline params to be compatible.
* Currently the categoryId field cannot be used in combination with the filter field. In order to
* use them together the categoryId field has to be extracted into the filter field.
* Then the pipeline is happy.
* @param {Object} params The request params.
* @param {Object} activeFilters The current active filters.
* @param {boolean} includeSort Tells if the sort parameters shall be included to the request.
* @param {boolean} includeFilters Tells if the filter parameters shall be included to the request.
* @returns {Object} A set of compatible params.
*/var processParams=function processParams(params,activeFilters){var includeSort=arguments.length>2&&arguments[2]!==undefined?arguments[2]:true;var includeFilters=arguments.length>3&&arguments[3]!==undefined?arguments[3]:true;var filters=buildRequestFilters(activeFilters);var newParams=_extends({},params,{},includeFilters&&filters&&Object.keys(filters).length&&{filters:filters});/**
* Check if the sort parameter should be included in the request parameters,
* and remove it if necessary.
*/if(includeSort===false&¶ms&¶ms.sort){delete newParams.sort;}return newParams;};var getDefaultSortOrder=makeGetDefaultSortOrder();/**
* Retrieves a product from the Redux store.
* @param {Object} options The options for the getProducts request.
* @param {Object} options.params The params for the getProduct pipeline.
* @param {string} [options.pipeline='getProducts'] The pipeline to call.
* @param {Object} [options.filters = null] Filters object for the request
* @param {boolean} [options.cached=true] If the result will be cached.
* @param {?number} [options.cachedTime=null] Cache TTL in ms.
* @param {?string} [options.id=null] A unique id for the component that is using this action.
* @param {boolean} [options.includeSort=true] Tells if the sort parameters shall be included
* into the product hash and the request.
* @param {boolean} [options.includeFilters=true] Tells if the filter parameters shall be included
* into the product hash and the request.
* @param {Function} [options.onBeforeDispatch=() => {}] A callback which is fired, before new data
* will be returned.
* @param {boolean} [options.resolveCachedProducts=false] Whether to resolve with products even
* when no actual request was done due to cached data.
* @return {Function} A Redux Thunk
*/function fetchProducts(options){var _options$params=options.params,params=_options$params===void 0?{}:_options$params,_options$filters=options.filters,filters=_options$filters===void 0?null:_options$filters,_options$pipeline=options.pipeline,pipeline=_options$pipeline===void 0?SHOPGATE_CATALOG_GET_PRODUCTS:_options$pipeline,_options$cached=options.cached,cached=_options$cached===void 0?true:_options$cached,_options$cachedTime=options.cachedTime,cachedTime=_options$cachedTime===void 0?null:_options$cachedTime,_options$id=options.id,id=_options$id===void 0?null:_options$id,_options$includeSort=options.includeSort,includeSort=_options$includeSort===void 0?true:_options$includeSort,_options$includeFilte=options.includeFilters,includeFilters=_options$includeFilte===void 0?true:_options$includeFilte,_options$includeFulfi=options.includeFulfillment,includeFulfillment=_options$includeFulfi===void 0?true:_options$includeFulfi,_options$onBeforeDisp=options.onBeforeDispatch,onBeforeDispatch=_options$onBeforeDisp===void 0?function(){}:_options$onBeforeDisp,_options$resolveCache=options.resolveCachedProducts,resolveCachedProducts=_options$resolveCache===void 0?false:_options$resolveCache;return function(dispatch,getState){var state=getState();var offset=params.offset,limit=params.limit,hashParams=_objectWithoutProperties(params,_excluded);var defaultSort=getDefaultSortOrder(state,{scope:SORT_SCOPE_CATEGORY});var _hashParams$sort=hashParams.sort,sort=_hashParams$sort===void 0?defaultSort:_hashParams$sort;var getProductsRequestParams;if(pipeline===SHOPGATE_CATALOG_GET_PRODUCTS){getProductsRequestParams=configuration.get(DEFAULT_PRODUCTS_FETCH_PARAMS);}// Append additional global fulfillment parameters.
var fulfillmentParams={};if(includeFulfillment&&pipeline===SHOPGATE_CATALOG_GET_PRODUCTS){fulfillmentParams=getFulfillmentParams(state);}// We need to process the params to handle edge cases in the pipeline params.
var requestParams=_extends({},fulfillmentParams,{},getProductsRequestParams,{},processParams(params,filters,includeSort,includeFilters));var hash=generateResultHash(_extends({pipeline:pipeline,sort:sort},fulfillmentParams,{},hashParams,{},filters&&Object.keys(filters).length&&{filters:filters},{},id&&{id:id}),includeSort,includeFilters);var result=state.product.resultsByHash[hash];var requiredProductCount=null;// Only set a required number of products if both offset and limit are valid.
if(isNumber(offset)&&isNumber(limit)){requiredProductCount=offset+limit;}// Stop if we don't need to get any data.
if(!shouldFetchData(result,'products',requiredProductCount)){var products=result.products;if(Array.isArray(products)){/**
* Fire the onBeforeDispatch callback to inform
* a caller that fetchProducts will return data.
*/onBeforeDispatch();dispatch(receiveProductsCached({hash:hash,requestParams:requestParams,products:products}));return Promise.resolve(resolveCachedProducts?makeGetProductResultByCustomHash(hash)(state):result);}return null;}// Fire the onBeforeDispatch callback to inform a caller that fetchProducts will return data.
onBeforeDispatch();dispatch(requestProducts({hash:hash,cached:cached,cachedTime:cachedTime,requestParams:requestParams}));var request=new PipelineRequest(pipeline).setInput(requestParams).dispatch();request.then(function(response){var totalResultCount=response.totalProductCount;/**
* When the next check was written, getHighlightProducts and getLiveshoppingProducts
* didn't deliver a totalProductCount within their responses - they simply returned all
* available products.
* So we set the products count of the response as totalProductCount to decrease the
* amount of logic, which is necessary to deal with product related pipeline.
*/if(typeof totalResultCount==='undefined'&&(pipeline===SHOPGATE_CATALOG_GET_HIGHLIGHT_PRODUCTS||pipeline===SHOPGATE_CATALOG_GET_LIVESHOPPING_PRODUCTS)){totalResultCount=response.products.length;}dispatch(receiveProducts({hash:hash,requestParams:requestParams,products:response.products,totalResultCount:totalResultCount,cached:cached,cachedTime:cachedTime}));if(Array.isArray(params===null||params===void 0?void 0:params.productIds)){var requestIds=params===null||params===void 0?void 0:params.productIds;var responseIds=response.products.map(function(product){return product.id;});var missingResponseIds=difference(requestIds,responseIds);if(missingResponseIds.length>0){dispatch(deleteProductsByIds(missingResponseIds));}}})["catch"](function(error){dispatch(errorProducts({errorCode:error.code,hash:hash,requestParams:requestParams}));});return request;};}export default fetchProducts;