@faststore/api 1.10.4 → 1.10.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.esm.js CHANGED
@@ -32,6 +32,7 @@ const VtexCommerce = ({
32
32
  const base = `https://${account}.${environment}.com.br`;
33
33
  return {
34
34
  catalog: {
35
+ salesChannel: sc => fetchAPI(`${base}/api/catalog_system/pub/saleschannel/${sc}`),
35
36
  brand: {
36
37
  list: () => fetchAPI(`${base}/api/catalog_system/pub/brand/list`)
37
38
  },
@@ -40,6 +41,19 @@ const VtexCommerce = ({
40
41
  },
41
42
  portal: {
42
43
  pagetype: slug => fetchAPI(`${base}/api/catalog_system/pub/portal/pagetype/${slug}`)
44
+ },
45
+ products: {
46
+ crossselling: ({
47
+ type,
48
+ productId,
49
+ groupByProduct = true
50
+ }) => {
51
+ const params = new URLSearchParams({
52
+ sc: ctx.storage.channel.salesChannel,
53
+ groupByProduct: groupByProduct.toString()
54
+ });
55
+ return fetchAPI(`${base}/api/catalog_system/pub/products/crossselling/${type}/${productId}?${params}`);
56
+ }
43
57
  }
44
58
  },
45
59
  checkout: {
@@ -309,6 +323,12 @@ const getClients = (options, ctx) => {
309
323
  };
310
324
  };
311
325
 
326
+ const getSalesChannelLoader = (_, clients) => {
327
+ const loader = async channels => Promise.all(channels.map(sc => clients.commerce.catalog.salesChannel(sc)));
328
+
329
+ return new DataLoader(loader);
330
+ };
331
+
312
332
  const CONCURRENT_REQUESTS_MAX = 1;
313
333
  const getSimulationLoader = (_, clients) => {
314
334
  const limit = pLimit(CONCURRENT_REQUESTS_MAX);
@@ -446,10 +466,12 @@ const getLoaders = (options, {
446
466
  const skuLoader = getSkuLoader(options, clients);
447
467
  const simulationLoader = getSimulationLoader(options, clients);
448
468
  const collectionLoader = getCollectionLoader(options, clients);
469
+ const salesChannelLoader = getSalesChannelLoader(options, clients);
449
470
  return {
450
471
  skuLoader,
451
472
  simulationLoader,
452
- collectionLoader
473
+ collectionLoader,
474
+ salesChannelLoader
453
475
  };
454
476
  };
455
477
 
@@ -490,7 +512,20 @@ const StoreAggregateOffer = {
490
512
  return lowOffer ? price(lowOffer) : 0;
491
513
  },
492
514
  offerCount: offers => offers.length,
493
- priceCurrency: () => '',
515
+ priceCurrency: async (_, __, ctx) => {
516
+ var _sc$CurrencyCode;
517
+
518
+ const {
519
+ loaders: {
520
+ salesChannelLoader
521
+ },
522
+ storage: {
523
+ channel
524
+ }
525
+ } = ctx;
526
+ const sc = await salesChannelLoader.load(channel.salesChannel);
527
+ return (_sc$CurrencyCode = sc.CurrencyCode) != null ? _sc$CurrencyCode : '';
528
+ },
494
529
  offers: offers => offers
495
530
  };
496
531
 
@@ -637,6 +672,14 @@ class ChannelMarshal {
637
672
 
638
673
  }
639
674
 
675
+ const FACET_CROSS_SELLING_MAP = {
676
+ buy: "whoboughtalsobought",
677
+ view: "whosawalsosaw",
678
+ similars: "similars",
679
+ viewAndBought: "whosawalsobought",
680
+ accessories: "accessories",
681
+ suggestions: "suggestions"
682
+ };
640
683
  /**
641
684
  * Transform facets from the store to VTEX platform facets.
642
685
  * For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm
@@ -678,6 +721,16 @@ const transformSelectedFacet = ({
678
721
  };
679
722
  }
680
723
 
724
+ case "buy":
725
+ case "view":
726
+ case "similars":
727
+ case "viewAndBought":
728
+ case "accessories":
729
+ case "suggestions":
730
+ {
731
+ return []; // remove this facet from search
732
+ }
733
+
681
734
  default:
682
735
  return {
683
736
  key,
@@ -694,6 +747,18 @@ const parseRange = range => {
694
747
 
695
748
  return splitted;
696
749
  };
750
+ const isCrossSelling = x => typeof FACET_CROSS_SELLING_MAP[x] === "string";
751
+ const findCrossSelling = facets => {
752
+ var _filtered$;
753
+
754
+ const filtered = facets == null ? void 0 : facets.filter(x => isCrossSelling(x.key));
755
+
756
+ if (Array.isArray(filtered) && filtered.length > 1) {
757
+ throw new BadRequestError(`You passed ${filtered.length} cross selling facets but only one is allowed. Please leave one of the following facet: ${filtered.map(x => x.key).join(',')}`);
758
+ }
759
+
760
+ return (_filtered$ = filtered == null ? void 0 : filtered[0]) != null ? _filtered$ : null;
761
+ };
697
762
  const findSlug = facets => {
698
763
  var _facets$find$value, _facets$find;
699
764
 
@@ -1155,7 +1220,20 @@ const isSearchItem = item => 'Price' in item && 'seller' in item && 'product' in
1155
1220
  const isOrderFormItem = item => 'skuName' in item;
1156
1221
 
1157
1222
  const StoreOffer = {
1158
- priceCurrency: () => '',
1223
+ priceCurrency: async (_, __, ctx) => {
1224
+ var _sc$CurrencyCode;
1225
+
1226
+ const {
1227
+ loaders: {
1228
+ salesChannelLoader
1229
+ },
1230
+ storage: {
1231
+ channel
1232
+ }
1233
+ } = ctx;
1234
+ const sc = await salesChannelLoader.load(channel.salesChannel);
1235
+ return (_sc$CurrencyCode = sc.CurrencyCode) != null ? _sc$CurrencyCode : '';
1236
+ },
1159
1237
  priceValidUntil: root => {
1160
1238
  if (isSearchItem(root)) {
1161
1239
  var _root$PriceValidUntil;
@@ -1561,6 +1639,7 @@ const Query = {
1561
1639
  // Insert channel in context for later usage
1562
1640
  const channel = findChannel(selectedFacets);
1563
1641
  const locale = findLocale(selectedFacets);
1642
+ const crossSelling = findCrossSelling(selectedFacets);
1564
1643
 
1565
1644
  if (channel) {
1566
1645
  mutateChannelContext(ctx, channel);
@@ -1570,11 +1649,30 @@ const Query = {
1570
1649
  mutateLocaleContext(ctx, locale);
1571
1650
  }
1572
1651
 
1652
+ let query = term;
1653
+ /**
1654
+ * In case we are using crossSelling, we need to modify the search
1655
+ * we will be performing on our search engine. The idea in here
1656
+ * is to use the cross selling API for fetching the productIds our
1657
+ * search will return for us.
1658
+ * Doing this two request workflow makes it possible to have cross
1659
+ * selling with Search features, like pagination, internationalization
1660
+ * etc
1661
+ */
1662
+
1663
+ if (crossSelling) {
1664
+ const products = await ctx.clients.commerce.catalog.products.crossselling({
1665
+ type: FACET_CROSS_SELLING_MAP[crossSelling.key],
1666
+ productId: crossSelling.value
1667
+ });
1668
+ query = `product:${products.map(x => x.productId).slice(0, first).join(";")}`;
1669
+ }
1670
+
1573
1671
  const after = maybeAfter ? Number(maybeAfter) : 0;
1574
1672
  const searchArgs = {
1575
1673
  page: Math.ceil(after / first),
1576
1674
  count: first,
1577
- query: term,
1675
+ query,
1578
1676
  sort: SORT_MAP[sort != null ? sort : 'score_desc'],
1579
1677
  selectedFacets: (_selectedFacets$flatM = selectedFacets == null ? void 0 : selectedFacets.flatMap(transformSelectedFacet)) != null ? _selectedFacets$flatM : []
1580
1678
  };