@@ -2,6 +2,7 @@ import 'es6-promise/auto';
22import { apiInstance , RESPONSE_BAD_REQUEST , RESPONSE_SERVER_ERROR } from './api' ;
33import { Settings } from './settings' ;
44import { AxiosResponse } from 'axios' ;
5+ import { isEmptyObject } from './util' ;
56
67interface RecommendOptions {
78 type : 'RELATED_ITEMS' | 'FREQUENTLY_BOUGHT_TOGETHER' ;
@@ -121,6 +122,7 @@ const executeApiFetch: ExecuteApiFetch = function (
121122
122123 let keyword = '' ;
123124 let queryParamsString = '' ;
125+ let requestPayloadObject = { } ;
124126
125127 // API Path (eq. /search, /suggest, /autocomplete/document-field)
126128 let apiEndpoint : string | null = null ;
@@ -155,6 +157,7 @@ const executeApiFetch: ExecuteApiFetch = function (
155157 }
156158 }
157159
160+ // GET Parameters
158161 queryParamsString =
159162 settingToQueryParam ( settings ?. lang , 'lang' ) +
160163 settingToQueryParam ( fuzzy , 'fuzzy' ) +
@@ -176,8 +179,37 @@ const executeApiFetch: ExecuteApiFetch = function (
176179 settingToQueryParam ( settings ?. searchOperator , 'defaultOperator' ) +
177180 settingToQueryParam ( settings ?. analyticsTag , 'analyticsTag' ) ;
178181
182+ // POST Parameters
183+
184+ requestPayloadObject = {
185+ ...requestPayloadObject ,
186+ language : settings ?. lang ,
187+ fuzzy : fuzzy !== true && fuzzy !== false ? fuzzy : JSON . stringify ( fuzzy ) ,
188+ collectAnalytics : settings ?. collectAnalytics ,
189+ postfixWildcard : settings ?. postfixWildcard ,
190+ categories : settings ?. categories ? settings ?. categories . split ( ',' ) : undefined ,
191+ priceFromCents : settings ?. priceFromCents ? parseInt ( settings ?. priceFromCents , 10 ) : undefined ,
192+ priceToCents : settings ?. priceToCents ? parseInt ( settings ?. priceToCents , 10 ) : undefined ,
193+ dateFrom : settings ?. dateFrom ,
194+ dateTo : settings ?. dateTo ,
195+ paging : {
196+ page : settings ?. paging . page ?? 1 ,
197+ pageSize : settings ?. paging . pageSize ?? 10 ,
198+ shuffleAndLimitTo : settings ?. shuffleAndLimitTo ?? undefined ,
199+ sortByField : settings ?. paging . sortBy ,
200+ sortOrder : settings ?. paging . sortOrder
201+ } ,
202+ jwt : settings ?. jwt ,
203+ resultType : settings ?. resultType ,
204+ userToken : settings ?. userToken ?? undefined ,
205+ numFacets : settings ?. numFacets ,
206+ cacheResponseWithTtlSeconds : settings ?. cacheResponseTime ?? undefined ,
207+ defaultOperator : settings ?. searchOperator ?? undefined ,
208+ analyticsTag : settings ?. analyticsTag
209+ } ;
210+
179211 // Add sortBy and sortOrder
180- if ( Array . isArray ( settings ?. paging . sortBy ) ) {
212+ if ( Array . isArray ( settings ?. paging . sortBy ) && settings ?. paging . sortBy . length > 1 ) {
181213 settings ?. paging . sortBy . forEach ( function ( value , index ) {
182214 queryParamsString =
183215 queryParamsString +
@@ -193,16 +225,34 @@ const executeApiFetch: ExecuteApiFetch = function (
193225
194226 // Add custom field filters
195227 if ( settings ?. customFieldFilters ) {
228+ const customFieldFiltersValues : any = { } ;
196229 for ( let i = 0 ; i < settings ?. customFieldFilters . length ; i ++ ) {
197230 queryParamsString = queryParamsString + '&customField=' + settings ?. customFieldFilters [ i ] ;
231+
232+ const decodedCustomFieldFilter = decodeURIComponent ( settings ?. customFieldFilters [ i ] ) ;
233+ const customFieldFilterPair = decodedCustomFieldFilter . split ( '=' ) ;
234+ const customFieldName = customFieldFilterPair [ 0 ] ;
235+ const customFieldValue = customFieldFilterPair [ 1 ] ;
236+ customFieldFiltersValues [ customFieldName ] = customFieldValue ;
198237 }
238+
239+ requestPayloadObject = {
240+ ...requestPayloadObject ,
241+ customField : isEmptyObject ( customFieldFiltersValues ) ? undefined : customFieldFiltersValues
242+ } ;
199243 }
200244
201245 // Add facet fields
202246 if ( settings ?. facetFields ) {
247+ const facetFieldsValues : string [ ] = [ ] ;
203248 for ( let i = 0 ; i < settings ?. facetFields . length ; i ++ ) {
204249 queryParamsString = queryParamsString + '&facet=' + settings ?. facetFields [ i ] ;
250+ facetFieldsValues . push ( settings ?. facetFields [ i ] ) ;
205251 }
252+ requestPayloadObject = {
253+ ...requestPayloadObject ,
254+ facet : facetFieldsValues . length > 0 ? facetFieldsValues : undefined
255+ } ;
206256 }
207257
208258 // Range facets
@@ -211,6 +261,10 @@ const executeApiFetch: ExecuteApiFetch = function (
211261 queryParamsString +
212262 '&rangeFacets=' +
213263 encodeURIComponent ( JSON . stringify ( settings ?. rangeFacets ) ) ;
264+ requestPayloadObject = {
265+ ...requestPayloadObject ,
266+ rangeFacets : settings ?. rangeFacets
267+ } ;
214268 }
215269
216270 // Hierarchical facets
@@ -219,32 +273,56 @@ const executeApiFetch: ExecuteApiFetch = function (
219273 queryParamsString +
220274 '&hierarchicalFacets=' +
221275 encodeURIComponent ( JSON . stringify ( settings ?. hierarchicalFacetSetting ) ) ;
276+ requestPayloadObject = {
277+ ...requestPayloadObject ,
278+ hierarchicalFacets : settings ?. hierarchicalFacetSetting
279+ } ;
222280 }
223281
224282 // Stats fields
225283 if ( settings ?. statsFields ) {
284+ const statsFieldsValues : string [ ] = [ ] ;
226285 for ( let i = 0 ; i < settings ?. statsFields . length ; i ++ ) {
227286 queryParamsString = queryParamsString + '&fieldStat=' + settings ?. statsFields [ i ] ;
287+ statsFieldsValues . push ( settings ?. statsFields [ i ] ) ;
228288 }
289+ requestPayloadObject = {
290+ ...requestPayloadObject ,
291+ statsFields : statsFieldsValues
292+ } ;
229293 }
230294
231295 // Personalization events
232296 if ( settings ?. personalizationEvents && Array . isArray ( settings ?. personalizationEvents ) ) {
297+ const personalizationEventsValues : any [ ] = [ ] ;
233298 for ( let i = 0 ; i < settings ?. personalizationEvents . length ; i ++ ) {
234299 const obj = settings ?. personalizationEvents [ i ] ;
235300 const key = Object . keys ( obj ) [ 0 ] ;
236301 queryParamsString =
237302 queryParamsString + '&personalizationEvent=' + encodeURIComponent ( key + '=' + obj [ key ] ) ;
303+ personalizationEventsValues . push ( obj ) ;
238304 }
305+ requestPayloadObject = {
306+ ...requestPayloadObject ,
307+ personalizationEvents : personalizationEventsValues
308+ } ;
239309 }
240310
241311 // Filter object
242312 if ( customFilterObject ) {
243313 queryParamsString =
244314 queryParamsString + '&filter=' + encodeURIComponent ( JSON . stringify ( customFilterObject ) ) ;
315+ requestPayloadObject = {
316+ ...requestPayloadObject ,
317+ filter : customFilterObject
318+ } ;
245319 } else if ( settings ?. filterObject ) {
246320 queryParamsString =
247321 queryParamsString + '&filter=' + encodeURIComponent ( JSON . stringify ( settings ?. filterObject ) ) ;
322+ requestPayloadObject = {
323+ ...requestPayloadObject ,
324+ filter : isEmptyObject ( settings ?. filterObject ) ? undefined : settings ?. filterObject
325+ } ;
248326 }
249327
250328 apiEndpoint =
@@ -295,6 +373,12 @@ const executeApiFetch: ExecuteApiFetch = function (
295373 queryParamsString =
296374 settingToQueryParam ( settings ?. suggestionsSize , 'size' ) +
297375 settingToQueryParam ( settings ?. lang , 'language' ) ;
376+ requestPayloadObject = {
377+ ...requestPayloadObject ,
378+ size : settings ?. suggestionsSize ,
379+ language : settings ?. lang
380+ } ;
381+
298382 keyword = settings ?. suggestionsPrefix as string ;
299383 apiEndpoint =
300384 'https://' +
@@ -325,6 +409,12 @@ const executeApiFetch: ExecuteApiFetch = function (
325409 '?term=' +
326410 keyword +
327411 queryParamsString ;
412+
413+ requestPayloadObject = {
414+ ...requestPayloadObject ,
415+ source : settings ?. autocomplete . field ,
416+ size : settings ?. autocomplete . size
417+ } ;
328418 } else if ( type === 'recommend' ) {
329419 if ( recommendOptions ?. type === 'RELATED_ITEMS' ) {
330420 queryParamsString = settingToQueryParam ( recommendOptions . itemId , 'itemId' ) ;
@@ -335,6 +425,12 @@ const executeApiFetch: ExecuteApiFetch = function (
335425 recommendOptions . blockId +
336426 '?' +
337427 queryParamsString ;
428+
429+ requestPayloadObject = {
430+ ...requestPayloadObject ,
431+ itemId : recommendOptions . itemId ?? undefined ,
432+ blockId : recommendOptions . blockId
433+ } ;
338434 } else if ( recommendOptions ?. type === 'FREQUENTLY_BOUGHT_TOGETHER' ) {
339435 queryParamsString = settingToQueryParam ( recommendOptions . itemId , 'itemId' ) ;
340436 apiPath =
@@ -343,49 +439,70 @@ const executeApiFetch: ExecuteApiFetch = function (
343439 '?configurationKey=' +
344440 recommendOptions . configurationKey +
345441 queryParamsString ;
442+
443+ requestPayloadObject = {
444+ ...requestPayloadObject ,
445+ itemId : recommendOptions . itemId ?? undefined ,
446+ configurationKey : recommendOptions . configurationKey
447+ } ;
346448 }
347449 apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath ;
348450 }
349451
452+ // Handle API response for all types except ai-answers
350453 if ( type !== 'ai-answers' ) {
351- apiInstance
352- . get ( apiEndpoint as string )
353- . then ( function ( response : AxiosResponse < GenericApiResponse > ) {
354- const json = response . data ;
355-
356- // Search again with fuzzy=true if no hits
357- if (
358- type === 'search' &&
359- settings ?. fuzzy === 'retry' &&
360- json . total_hits === 0 &&
361- fuzzyRetry !== true
362- ) {
363- executeApiFetch ( apiHostname , sitekey , type , settings , cb , true ) ;
454+ const handleApiResponse = function ( response : AxiosResponse < GenericApiResponse > ) {
455+ const json = response . data ;
456+
457+ // Search again with fuzzy=true if no hits
458+ if (
459+ type === 'search' &&
460+ settings ?. fuzzy === 'retry' &&
461+ json . total_hits === 0 &&
462+ fuzzyRetry !== true
463+ ) {
464+ executeApiFetch ( apiHostname , sitekey , type , settings , cb , true ) ;
465+ } else {
466+ // Cap fuzzy results to one page as quality decreases quickly
467+ if ( fuzzyRetry === true ) {
468+ json . total_hits = Math . min (
469+ json . total_hits ?? Infinity ,
470+ settings ?. paging ?. pageSize ?? Infinity
471+ ) ;
364472 }
365- // Fuzzy not "retry" OR fuzzyRetry already returning
366- else {
367- // Cap fuzzy results to one page as quality decreases quickly
368- if ( fuzzyRetry === true ) {
369- json . total_hits = Math . min (
370- json . total_hits ?? Infinity ,
371- settings ?. paging ?. pageSize ?? Infinity
372- ) ;
373- }
374473
375- // Callback
376- cb ( json ) ;
474+ // Callback
475+ cb ( json ) ;
476+ }
477+ } ;
478+
479+ const handleApiError = function ( error : any ) {
480+ console . error ( error ) ;
481+ cb ( {
482+ error : {
483+ response : RESPONSE_SERVER_ERROR ,
484+ message : 'invalid server response'
377485 }
378- } )
379- . catch ( function ( error ) {
380- console . error ( error ) ;
381-
382- cb ( {
383- error : {
384- response : RESPONSE_SERVER_ERROR ,
385- message : 'invalid server response'
386- }
387- } ) ;
388486 } ) ;
487+ } ;
488+
489+ if ( settings ?. apiMethod === 'POST' && [ 'search' , 'suggest' , 'autocomplete' ] . includes ( type ) ) {
490+ apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey ;
491+ const term = type === 'search' ? decodeURIComponent ( keyword ) : keyword ;
492+ requestPayloadObject = {
493+ term,
494+ ...requestPayloadObject
495+ } ;
496+ apiInstance
497+ . post ( apiEndpoint , requestPayloadObject )
498+ . then ( handleApiResponse )
499+ . catch ( handleApiError ) ;
500+ } else {
501+ apiInstance
502+ . get ( apiEndpoint as string )
503+ . then ( handleApiResponse )
504+ . catch ( handleApiError ) ;
505+ }
389506 }
390507} ;
391508
0 commit comments