@@ -2,6 +2,7 @@ import 'es6-promise/auto';
2
2
import { apiInstance , RESPONSE_BAD_REQUEST , RESPONSE_SERVER_ERROR } from './api' ;
3
3
import { Settings } from './settings' ;
4
4
import { AxiosResponse } from 'axios' ;
5
+ import { isEmptyObject } from './util' ;
5
6
6
7
interface RecommendOptions {
7
8
type : 'RELATED_ITEMS' | 'FREQUENTLY_BOUGHT_TOGETHER' ;
@@ -121,6 +122,7 @@ const executeApiFetch: ExecuteApiFetch = function (
121
122
122
123
let keyword = '' ;
123
124
let queryParamsString = '' ;
125
+ let requestPayloadObject = { } ;
124
126
125
127
// API Path (eq. /search, /suggest, /autocomplete/document-field)
126
128
let apiEndpoint : string | null = null ;
@@ -155,6 +157,7 @@ const executeApiFetch: ExecuteApiFetch = function (
155
157
}
156
158
}
157
159
160
+ // GET Parameters
158
161
queryParamsString =
159
162
settingToQueryParam ( settings ?. lang , 'lang' ) +
160
163
settingToQueryParam ( fuzzy , 'fuzzy' ) +
@@ -176,8 +179,37 @@ const executeApiFetch: ExecuteApiFetch = function (
176
179
settingToQueryParam ( settings ?. searchOperator , 'defaultOperator' ) +
177
180
settingToQueryParam ( settings ?. analyticsTag , 'analyticsTag' ) ;
178
181
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
+
179
211
// Add sortBy and sortOrder
180
- if ( Array . isArray ( settings ?. paging . sortBy ) ) {
212
+ if ( Array . isArray ( settings ?. paging . sortBy ) && settings ?. paging . sortBy . length > 1 ) {
181
213
settings ?. paging . sortBy . forEach ( function ( value , index ) {
182
214
queryParamsString =
183
215
queryParamsString +
@@ -193,16 +225,34 @@ const executeApiFetch: ExecuteApiFetch = function (
193
225
194
226
// Add custom field filters
195
227
if ( settings ?. customFieldFilters ) {
228
+ const customFieldFiltersValues : any = { } ;
196
229
for ( let i = 0 ; i < settings ?. customFieldFilters . length ; i ++ ) {
197
230
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 ;
198
237
}
238
+
239
+ requestPayloadObject = {
240
+ ...requestPayloadObject ,
241
+ customField : isEmptyObject ( customFieldFiltersValues ) ? undefined : customFieldFiltersValues
242
+ } ;
199
243
}
200
244
201
245
// Add facet fields
202
246
if ( settings ?. facetFields ) {
247
+ const facetFieldsValues : string [ ] = [ ] ;
203
248
for ( let i = 0 ; i < settings ?. facetFields . length ; i ++ ) {
204
249
queryParamsString = queryParamsString + '&facet=' + settings ?. facetFields [ i ] ;
250
+ facetFieldsValues . push ( settings ?. facetFields [ i ] ) ;
205
251
}
252
+ requestPayloadObject = {
253
+ ...requestPayloadObject ,
254
+ facet : facetFieldsValues . length > 0 ? facetFieldsValues : undefined
255
+ } ;
206
256
}
207
257
208
258
// Range facets
@@ -211,6 +261,10 @@ const executeApiFetch: ExecuteApiFetch = function (
211
261
queryParamsString +
212
262
'&rangeFacets=' +
213
263
encodeURIComponent ( JSON . stringify ( settings ?. rangeFacets ) ) ;
264
+ requestPayloadObject = {
265
+ ...requestPayloadObject ,
266
+ rangeFacets : settings ?. rangeFacets
267
+ } ;
214
268
}
215
269
216
270
// Hierarchical facets
@@ -219,32 +273,56 @@ const executeApiFetch: ExecuteApiFetch = function (
219
273
queryParamsString +
220
274
'&hierarchicalFacets=' +
221
275
encodeURIComponent ( JSON . stringify ( settings ?. hierarchicalFacetSetting ) ) ;
276
+ requestPayloadObject = {
277
+ ...requestPayloadObject ,
278
+ hierarchicalFacets : settings ?. hierarchicalFacetSetting
279
+ } ;
222
280
}
223
281
224
282
// Stats fields
225
283
if ( settings ?. statsFields ) {
284
+ const statsFieldsValues : string [ ] = [ ] ;
226
285
for ( let i = 0 ; i < settings ?. statsFields . length ; i ++ ) {
227
286
queryParamsString = queryParamsString + '&fieldStat=' + settings ?. statsFields [ i ] ;
287
+ statsFieldsValues . push ( settings ?. statsFields [ i ] ) ;
228
288
}
289
+ requestPayloadObject = {
290
+ ...requestPayloadObject ,
291
+ statsFields : statsFieldsValues
292
+ } ;
229
293
}
230
294
231
295
// Personalization events
232
296
if ( settings ?. personalizationEvents && Array . isArray ( settings ?. personalizationEvents ) ) {
297
+ const personalizationEventsValues : any [ ] = [ ] ;
233
298
for ( let i = 0 ; i < settings ?. personalizationEvents . length ; i ++ ) {
234
299
const obj = settings ?. personalizationEvents [ i ] ;
235
300
const key = Object . keys ( obj ) [ 0 ] ;
236
301
queryParamsString =
237
302
queryParamsString + '&personalizationEvent=' + encodeURIComponent ( key + '=' + obj [ key ] ) ;
303
+ personalizationEventsValues . push ( obj ) ;
238
304
}
305
+ requestPayloadObject = {
306
+ ...requestPayloadObject ,
307
+ personalizationEvents : personalizationEventsValues
308
+ } ;
239
309
}
240
310
241
311
// Filter object
242
312
if ( customFilterObject ) {
243
313
queryParamsString =
244
314
queryParamsString + '&filter=' + encodeURIComponent ( JSON . stringify ( customFilterObject ) ) ;
315
+ requestPayloadObject = {
316
+ ...requestPayloadObject ,
317
+ filter : customFilterObject
318
+ } ;
245
319
} else if ( settings ?. filterObject ) {
246
320
queryParamsString =
247
321
queryParamsString + '&filter=' + encodeURIComponent ( JSON . stringify ( settings ?. filterObject ) ) ;
322
+ requestPayloadObject = {
323
+ ...requestPayloadObject ,
324
+ filter : isEmptyObject ( settings ?. filterObject ) ? undefined : settings ?. filterObject
325
+ } ;
248
326
}
249
327
250
328
apiEndpoint =
@@ -295,6 +373,12 @@ const executeApiFetch: ExecuteApiFetch = function (
295
373
queryParamsString =
296
374
settingToQueryParam ( settings ?. suggestionsSize , 'size' ) +
297
375
settingToQueryParam ( settings ?. lang , 'language' ) ;
376
+ requestPayloadObject = {
377
+ ...requestPayloadObject ,
378
+ size : settings ?. suggestionsSize ,
379
+ language : settings ?. lang
380
+ } ;
381
+
298
382
keyword = settings ?. suggestionsPrefix as string ;
299
383
apiEndpoint =
300
384
'https://' +
@@ -325,6 +409,12 @@ const executeApiFetch: ExecuteApiFetch = function (
325
409
'?term=' +
326
410
keyword +
327
411
queryParamsString ;
412
+
413
+ requestPayloadObject = {
414
+ ...requestPayloadObject ,
415
+ source : settings ?. autocomplete . field ,
416
+ size : settings ?. autocomplete . size
417
+ } ;
328
418
} else if ( type === 'recommend' ) {
329
419
if ( recommendOptions ?. type === 'RELATED_ITEMS' ) {
330
420
queryParamsString = settingToQueryParam ( recommendOptions . itemId , 'itemId' ) ;
@@ -335,6 +425,12 @@ const executeApiFetch: ExecuteApiFetch = function (
335
425
recommendOptions . blockId +
336
426
'?' +
337
427
queryParamsString ;
428
+
429
+ requestPayloadObject = {
430
+ ...requestPayloadObject ,
431
+ itemId : recommendOptions . itemId ?? undefined ,
432
+ blockId : recommendOptions . blockId
433
+ } ;
338
434
} else if ( recommendOptions ?. type === 'FREQUENTLY_BOUGHT_TOGETHER' ) {
339
435
queryParamsString = settingToQueryParam ( recommendOptions . itemId , 'itemId' ) ;
340
436
apiPath =
@@ -343,49 +439,70 @@ const executeApiFetch: ExecuteApiFetch = function (
343
439
'?configurationKey=' +
344
440
recommendOptions . configurationKey +
345
441
queryParamsString ;
442
+
443
+ requestPayloadObject = {
444
+ ...requestPayloadObject ,
445
+ itemId : recommendOptions . itemId ?? undefined ,
446
+ configurationKey : recommendOptions . configurationKey
447
+ } ;
346
448
}
347
449
apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath ;
348
450
}
349
451
452
+ // Handle API response for all types except ai-answers
350
453
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
+ ) ;
364
472
}
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
- }
374
473
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'
377
485
}
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
- } ) ;
388
486
} ) ;
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
+ }
389
506
}
390
507
} ;
391
508
0 commit comments