@faststore/api 1.9.17 → 1.10.8

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/CHANGELOG.md CHANGED
@@ -3,6 +3,39 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.10.8](https://github.com/vtex/faststore/compare/v1.10.7...v1.10.8) (2022-07-07)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add priceCurrency to Offer ([#1399](https://github.com/vtex/faststore/issues/1399)) ([7ca846a](https://github.com/vtex/faststore/commit/7ca846af9b157707c71422b0d7e3e481edfbe5e6))
12
+
13
+
14
+
15
+
16
+
17
+ ## 1.10.6 (2022-07-05)
18
+
19
+
20
+ ### Features
21
+
22
+ * Support for cross selling API ([#1396](https://github.com/vtex/faststore/issues/1396)) ([98eb7e2](https://github.com/vtex/faststore/commit/98eb7e2cc6670bcb05d00418f901e26a2e9db8f0))
23
+
24
+
25
+
26
+
27
+
28
+ ## [1.10.4](https://github.com/vtex/faststore/compare/v1.10.3...v1.10.4) (2022-07-04)
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * @faststore/graphql-utils ([#1394](https://github.com/vtex/faststore/issues/1394)) ([ea4b483](https://github.com/vtex/faststore/commit/ea4b4832b25fe257d8c5c0c67bc09fb04dc693cf))
34
+
35
+
36
+
37
+
38
+
6
39
  ## [1.9.17](https://github.com/vtex/faststore/compare/v1.9.16...v1.9.17) (2022-06-28)
7
40
 
8
41
  **Note:** Version bump only for package @faststore/api
@@ -36,6 +36,7 @@ const VtexCommerce = ({
36
36
  const base = `https://${account}.${environment}.com.br`;
37
37
  return {
38
38
  catalog: {
39
+ salesChannel: sc => fetchAPI(`${base}/api/catalog_system/pub/saleschannel/${sc}`),
39
40
  brand: {
40
41
  list: () => fetchAPI(`${base}/api/catalog_system/pub/brand/list`)
41
42
  },
@@ -44,6 +45,19 @@ const VtexCommerce = ({
44
45
  },
45
46
  portal: {
46
47
  pagetype: slug => fetchAPI(`${base}/api/catalog_system/pub/portal/pagetype/${slug}`)
48
+ },
49
+ products: {
50
+ crossselling: ({
51
+ type,
52
+ productId,
53
+ groupByProduct = true
54
+ }) => {
55
+ const params = new URLSearchParams({
56
+ sc: ctx.storage.channel.salesChannel,
57
+ groupByProduct: groupByProduct.toString()
58
+ });
59
+ return fetchAPI(`${base}/api/catalog_system/pub/products/crossselling/${type}/${productId}?${params}`);
60
+ }
47
61
  }
48
62
  },
49
63
  checkout: {
@@ -313,6 +327,12 @@ const getClients = (options, ctx) => {
313
327
  };
314
328
  };
315
329
 
330
+ const getSalesChannelLoader = (_, clients) => {
331
+ const loader = async channels => Promise.all(channels.map(sc => clients.commerce.catalog.salesChannel(sc)));
332
+
333
+ return new DataLoader(loader);
334
+ };
335
+
316
336
  const CONCURRENT_REQUESTS_MAX = 1;
317
337
  const getSimulationLoader = (_, clients) => {
318
338
  const limit = pLimit(CONCURRENT_REQUESTS_MAX);
@@ -450,10 +470,12 @@ const getLoaders = (options, {
450
470
  const skuLoader = getSkuLoader(options, clients);
451
471
  const simulationLoader = getSimulationLoader(options, clients);
452
472
  const collectionLoader = getCollectionLoader(options, clients);
473
+ const salesChannelLoader = getSalesChannelLoader(options, clients);
453
474
  return {
454
475
  skuLoader,
455
476
  simulationLoader,
456
- collectionLoader
477
+ collectionLoader,
478
+ salesChannelLoader
457
479
  };
458
480
  };
459
481
 
@@ -494,7 +516,20 @@ const StoreAggregateOffer = {
494
516
  return lowOffer ? price(lowOffer) : 0;
495
517
  },
496
518
  offerCount: offers => offers.length,
497
- priceCurrency: () => '',
519
+ priceCurrency: async (_, __, ctx) => {
520
+ var _sc$CurrencyCode;
521
+
522
+ const {
523
+ loaders: {
524
+ salesChannelLoader
525
+ },
526
+ storage: {
527
+ channel
528
+ }
529
+ } = ctx;
530
+ const sc = await salesChannelLoader.load(channel.salesChannel);
531
+ return (_sc$CurrencyCode = sc.CurrencyCode) != null ? _sc$CurrencyCode : '';
532
+ },
498
533
  offers: offers => offers
499
534
  };
500
535
 
@@ -641,6 +676,14 @@ class ChannelMarshal {
641
676
 
642
677
  }
643
678
 
679
+ const FACET_CROSS_SELLING_MAP = {
680
+ buy: "whoboughtalsobought",
681
+ view: "whosawalsosaw",
682
+ similars: "similars",
683
+ viewAndBought: "whosawalsobought",
684
+ accessories: "accessories",
685
+ suggestions: "suggestions"
686
+ };
644
687
  /**
645
688
  * Transform facets from the store to VTEX platform facets.
646
689
  * For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm
@@ -682,6 +725,16 @@ const transformSelectedFacet = ({
682
725
  };
683
726
  }
684
727
 
728
+ case "buy":
729
+ case "view":
730
+ case "similars":
731
+ case "viewAndBought":
732
+ case "accessories":
733
+ case "suggestions":
734
+ {
735
+ return []; // remove this facet from search
736
+ }
737
+
685
738
  default:
686
739
  return {
687
740
  key,
@@ -698,6 +751,18 @@ const parseRange = range => {
698
751
 
699
752
  return splitted;
700
753
  };
754
+ const isCrossSelling = x => typeof FACET_CROSS_SELLING_MAP[x] === "string";
755
+ const findCrossSelling = facets => {
756
+ var _filtered$;
757
+
758
+ const filtered = facets == null ? void 0 : facets.filter(x => isCrossSelling(x.key));
759
+
760
+ if (Array.isArray(filtered) && filtered.length > 1) {
761
+ 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(',')}`);
762
+ }
763
+
764
+ return (_filtered$ = filtered == null ? void 0 : filtered[0]) != null ? _filtered$ : null;
765
+ };
701
766
  const findSlug = facets => {
702
767
  var _facets$find$value, _facets$find;
703
768
 
@@ -1159,7 +1224,20 @@ const isSearchItem = item => 'Price' in item && 'seller' in item && 'product' in
1159
1224
  const isOrderFormItem = item => 'skuName' in item;
1160
1225
 
1161
1226
  const StoreOffer = {
1162
- priceCurrency: () => '',
1227
+ priceCurrency: async (_, __, ctx) => {
1228
+ var _sc$CurrencyCode;
1229
+
1230
+ const {
1231
+ loaders: {
1232
+ salesChannelLoader
1233
+ },
1234
+ storage: {
1235
+ channel
1236
+ }
1237
+ } = ctx;
1238
+ const sc = await salesChannelLoader.load(channel.salesChannel);
1239
+ return (_sc$CurrencyCode = sc.CurrencyCode) != null ? _sc$CurrencyCode : '';
1240
+ },
1163
1241
  priceValidUntil: root => {
1164
1242
  if (isSearchItem(root)) {
1165
1243
  var _root$PriceValidUntil;
@@ -1565,6 +1643,7 @@ const Query = {
1565
1643
  // Insert channel in context for later usage
1566
1644
  const channel = findChannel(selectedFacets);
1567
1645
  const locale = findLocale(selectedFacets);
1646
+ const crossSelling = findCrossSelling(selectedFacets);
1568
1647
 
1569
1648
  if (channel) {
1570
1649
  mutateChannelContext(ctx, channel);
@@ -1574,11 +1653,30 @@ const Query = {
1574
1653
  mutateLocaleContext(ctx, locale);
1575
1654
  }
1576
1655
 
1656
+ let query = term;
1657
+ /**
1658
+ * In case we are using crossSelling, we need to modify the search
1659
+ * we will be performing on our search engine. The idea in here
1660
+ * is to use the cross selling API for fetching the productIds our
1661
+ * search will return for us.
1662
+ * Doing this two request workflow makes it possible to have cross
1663
+ * selling with Search features, like pagination, internationalization
1664
+ * etc
1665
+ */
1666
+
1667
+ if (crossSelling) {
1668
+ const products = await ctx.clients.commerce.catalog.products.crossselling({
1669
+ type: FACET_CROSS_SELLING_MAP[crossSelling.key],
1670
+ productId: crossSelling.value
1671
+ });
1672
+ query = `product:${products.map(x => x.productId).slice(0, first).join(";")}`;
1673
+ }
1674
+
1577
1675
  const after = maybeAfter ? Number(maybeAfter) : 0;
1578
1676
  const searchArgs = {
1579
1677
  page: Math.ceil(after / first),
1580
1678
  count: first,
1581
- query: term,
1679
+ query,
1582
1680
  sort: SORT_MAP[sort != null ? sort : 'score_desc'],
1583
1681
  selectedFacets: (_selectedFacets$flatM = selectedFacets == null ? void 0 : selectedFacets.flatMap(transformSelectedFacet)) != null ? _selectedFacets$flatM : []
1584
1682
  };