@faststore/api 2.0.3-alpha.0 → 2.0.32-alpha.0

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
@@ -10,11 +10,9 @@ import { mapSchema, MapperKind, getDirective } from '@graphql-tools/utils';
10
10
 
11
11
  const fetchAPI = async (info, init) => {
12
12
  const response = await fetch(info, init);
13
-
14
13
  if (response.ok) {
15
14
  return response.status !== 204 ? response.json() : undefined;
16
15
  }
17
-
18
16
  console.error(info, init, response);
19
17
  const text = await response.text();
20
18
  throw new Error(text);
@@ -64,7 +62,8 @@ const VtexCommerce = ({
64
62
  const params = new URLSearchParams({
65
63
  sc: salesChannel
66
64
  });
67
- return fetchAPI(`${base}/api/checkout/pub/orderForms/simulation?${params.toString()}`, { ...BASE_INIT,
65
+ return fetchAPI(`${base}/api/checkout/pub/orderForms/simulation?${params.toString()}`, {
66
+ ...BASE_INIT,
68
67
  body: JSON.stringify(args)
69
68
  });
70
69
  },
@@ -72,7 +71,8 @@ const VtexCommerce = ({
72
71
  id,
73
72
  body
74
73
  }) => {
75
- return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/attachments/shippingData`, { ...BASE_INIT,
74
+ return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/attachments/shippingData`, {
75
+ ...BASE_INIT,
76
76
  body: JSON.stringify(body)
77
77
  });
78
78
  },
@@ -100,7 +100,8 @@ const VtexCommerce = ({
100
100
  allowOutdatedData,
101
101
  sc: salesChannel
102
102
  });
103
- return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/items?${params}`, { ...BASE_INIT,
103
+ return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/items?${params}`, {
104
+ ...BASE_INIT,
104
105
  body: JSON.stringify({
105
106
  orderItems
106
107
  }),
@@ -113,7 +114,8 @@ const VtexCommerce = ({
113
114
  key,
114
115
  value
115
116
  }) => {
116
- return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/customData/${appId}/${key}`, { ...BASE_INIT,
117
+ return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/customData/${appId}/${key}`, {
118
+ ...BASE_INIT,
117
119
  body: JSON.stringify({
118
120
  value
119
121
  }),
@@ -147,8 +149,10 @@ const VtexCommerce = ({
147
149
  });
148
150
  },
149
151
  subscribeToNewsletter: data => {
150
- return fetchAPI(`${base}/api/dataentities/NL/documents/`, { ...BASE_INIT,
151
- body: JSON.stringify({ ...data,
152
+ return fetchAPI(`${base}/api/dataentities/NL/documents/`, {
153
+ ...BASE_INIT,
154
+ body: JSON.stringify({
155
+ ...data,
152
156
  isNewsletterOptIn: true
153
157
  }),
154
158
  method: 'PATCH'
@@ -166,40 +170,32 @@ const IntelligentSearch = ({
166
170
  hideUnavailableItems
167
171
  }, ctx) => {
168
172
  const base = `https://${account}.${environment}.com.br/api/io`;
169
-
170
173
  const getPolicyFacet = () => {
171
174
  const {
172
175
  salesChannel
173
176
  } = ctx.storage.channel;
174
-
175
177
  if (!salesChannel) {
176
178
  return null;
177
179
  }
178
-
179
180
  return {
180
181
  key: POLICY_KEY,
181
182
  value: salesChannel
182
183
  };
183
184
  };
184
-
185
185
  const getRegionFacet = () => {
186
186
  const {
187
187
  regionId
188
188
  } = ctx.storage.channel;
189
-
190
189
  if (!regionId) {
191
190
  return null;
192
191
  }
193
-
194
192
  return {
195
193
  key: REGION_KEY,
196
194
  value: regionId
197
195
  };
198
196
  };
199
-
200
197
  const addDefaultFacets = facets => {
201
198
  var _facets$find, _facets$find2;
202
-
203
199
  const withDefaltFacets = facets.filter(({
204
200
  key
205
201
  }) => !CHANNEL_KEYS.has(key));
@@ -209,18 +205,14 @@ const IntelligentSearch = ({
209
205
  const regionFacet = (_facets$find2 = facets.find(({
210
206
  key
211
207
  }) => key === REGION_KEY)) != null ? _facets$find2 : getRegionFacet();
212
-
213
208
  if (policyFacet !== null) {
214
209
  withDefaltFacets.push(policyFacet);
215
210
  }
216
-
217
211
  if (regionFacet !== null) {
218
212
  withDefaltFacets.push(regionFacet);
219
213
  }
220
-
221
214
  return withDefaltFacets;
222
215
  };
223
-
224
216
  const search = ({
225
217
  query = '',
226
218
  page,
@@ -238,43 +230,37 @@ const IntelligentSearch = ({
238
230
  fuzzy,
239
231
  locale: ctx.storage.locale
240
232
  });
241
-
242
233
  if (hideUnavailableItems !== undefined) {
243
234
  params.append('hideUnavailableItems', hideUnavailableItems.toString());
244
235
  }
245
-
246
236
  const pathname = addDefaultFacets(selectedFacets).map(({
247
237
  key,
248
238
  value
249
239
  }) => `${key}/${value}`).join('/');
250
240
  return fetchAPI(`${base}/_v/api/intelligent-search/${type}/${pathname}?${params.toString()}`);
251
241
  };
252
-
253
- const products = args => search({ ...args,
242
+ const products = args => search({
243
+ ...args,
254
244
  type: 'product_search'
255
245
  });
256
-
257
246
  const suggestedTerms = args => {
258
247
  var _args$query$toString, _args$query;
259
-
260
248
  const params = new URLSearchParams({
261
249
  query: (_args$query$toString = (_args$query = args.query) == null ? void 0 : _args$query.toString()) != null ? _args$query$toString : '',
262
250
  locale: ctx.storage.locale
263
251
  });
264
252
  return fetchAPI(`${base}/_v/api/intelligent-search/search_suggestions?${params.toString()}`);
265
253
  };
266
-
267
254
  const topSearches = () => {
268
255
  const params = new URLSearchParams({
269
256
  locale: ctx.storage.locale
270
257
  });
271
258
  return fetchAPI(`${base}/_v/api/intelligent-search/top_searches?${params.toString()}`);
272
259
  };
273
-
274
- const facets = args => search({ ...args,
260
+ const facets = args => search({
261
+ ...args,
275
262
  type: 'facets'
276
263
  });
277
-
278
264
  return {
279
265
  facets,
280
266
  products,
@@ -289,11 +275,8 @@ const IntelligentSearch = ({
289
275
  */
290
276
  const THIRTY_MINUTES_S = 30 * 60;
291
277
  const ONE_YEAR_S = 365 * 24 * 3600;
292
-
293
278
  const randomUUID = () => (Math.random() * 1e6).toFixed(0);
294
-
295
279
  const timelapsed = past => (Date.now() - past) / 1e3;
296
-
297
280
  const createId = expiresSecond => {
298
281
  let payload = randomUUID();
299
282
  let createdAt = Date.now();
@@ -302,11 +285,9 @@ const createId = expiresSecond => {
302
285
  payload = randomUUID();
303
286
  createdAt = Date.now();
304
287
  }
305
-
306
288
  return payload;
307
289
  };
308
290
  };
309
-
310
291
  const user = {
311
292
  anonymous: /*#__PURE__*/createId(ONE_YEAR_S),
312
293
  session: /*#__PURE__*/createId(THIRTY_MINUTES_S)
@@ -315,11 +296,11 @@ const SP = ({
315
296
  account
316
297
  }, _) => {
317
298
  const base = `https://sp.vtex.com/event-api/v1/${account}/event`;
318
-
319
299
  const sendEvent = options => {
320
300
  return fetchAPI(base, {
321
301
  method: 'POST',
322
- body: JSON.stringify({ ...options,
302
+ body: JSON.stringify({
303
+ ...options,
323
304
  agent: '@faststore/api',
324
305
  anonymous: user.anonymous(),
325
306
  session: user.session()
@@ -329,7 +310,6 @@ const SP = ({
329
310
  }
330
311
  });
331
312
  };
332
-
333
313
  return {
334
314
  sendEvent
335
315
  };
@@ -348,14 +328,13 @@ const getClients = (options, ctx) => {
348
328
 
349
329
  const getSalesChannelLoader = (_, clients) => {
350
330
  const loader = async channels => Promise.all(channels.map(sc => clients.commerce.catalog.salesChannel(sc)));
351
-
352
331
  return new DataLoader(loader);
353
332
  };
354
333
 
334
+ // Limits concurrent requests to the API per request cycle
355
335
  const CONCURRENT_REQUESTS_MAX = 1;
356
336
  const getSimulationLoader = (_, clients) => {
357
337
  const limit = pLimit(CONCURRENT_REQUESTS_MAX);
358
-
359
338
  const loader = async simulationArgs => {
360
339
  const allItems = simulationArgs.reduce((acc, {
361
340
  items
@@ -367,32 +346,30 @@ const getSimulationLoader = (_, clients) => {
367
346
  country: simulationArgs[0].country,
368
347
  postalCode: simulationArgs[0].postalCode,
369
348
  items
370
- }); // Sort and filter simulation since Checkout API may return
349
+ });
350
+ // Sort and filter simulation since Checkout API may return
371
351
  // items that we didn't ask for
372
-
373
352
  const simulated = simulation.items.reduce((acc, item) => {
374
353
  const index = item.requestIndex;
375
-
376
354
  if (typeof index === 'number' && index < acc.length) {
377
355
  acc[index] = item;
378
356
  }
379
-
380
357
  return acc;
381
358
  }, Array(items.length).fill(null));
382
359
  const itemsIndices = allItems.reduce((acc, curr) => [...acc, curr.length + acc[acc.length - 1]], [0]);
383
- return allItems.map((__, index) => ({ ...simulation,
360
+ return allItems.map((__, index) => ({
361
+ ...simulation,
384
362
  items: simulated.slice(itemsIndices[index], itemsIndices[index + 1]).filter(item => Boolean(item))
385
363
  }));
386
364
  };
387
-
388
365
  const limited = async allItems => limit(loader, allItems);
389
-
390
366
  return new DataLoader(limited, {
391
367
  maxBatchSize: 50
392
368
  });
393
369
  };
394
370
 
395
- const enhanceSku = (item, product) => ({ ...item,
371
+ const enhanceSku = (item, product) => ({
372
+ ...item,
396
373
  isVariantOf: product
397
374
  });
398
375
 
@@ -402,9 +379,7 @@ class FastStoreError extends Error {
402
379
  this.extensions = extensions;
403
380
  this.name = 'FastStoreError';
404
381
  }
405
-
406
382
  }
407
-
408
383
  class BadRequestError extends FastStoreError {
409
384
  constructor(message) {
410
385
  super({
@@ -412,7 +387,6 @@ class BadRequestError extends FastStoreError {
412
387
  type: 'BadRequestError'
413
388
  }, message);
414
389
  }
415
-
416
390
  }
417
391
  class NotFoundError extends FastStoreError {
418
392
  constructor(message) {
@@ -421,17 +395,14 @@ class NotFoundError extends FastStoreError {
421
395
  type: 'NotFoundError'
422
396
  }, message);
423
397
  }
424
-
425
398
  }
426
399
  const isFastStoreError = error => (error == null ? void 0 : error.name) === 'FastStoreError';
427
400
  const isNotFoundError = error => {
428
401
  var _error$extensions;
429
-
430
402
  return (error == null ? void 0 : (_error$extensions = error.extensions) == null ? void 0 : _error$extensions.type) === 'NotFoundError';
431
403
  };
432
404
  const isBadRequestError = error => {
433
405
  var _error$extensions2;
434
-
435
406
  return (error == null ? void 0 : (_error$extensions2 = error.extensions) == null ? void 0 : _error$extensions2.type) === 'BadRequestError';
436
407
  };
437
408
 
@@ -448,42 +419,35 @@ const getSkuLoader = (_, clients) => {
448
419
  for (const sku of product.items) {
449
420
  acc[sku.itemId] = enhanceSku(sku, product);
450
421
  }
451
-
452
422
  return acc;
453
423
  }, {});
454
424
  const skus = skuIds.map(skuId => skuBySkuId[skuId]);
455
425
  const missingSkus = skuIds.filter(skuId => !skuBySkuId[skuId]);
456
-
457
426
  if (missingSkus.length > 0) {
458
427
  throw new NotFoundError(`Search API did not found the following skus: ${missingSkus.join(',')}`);
459
428
  }
460
-
461
429
  return skus;
462
430
  };
463
-
464
431
  return new DataLoader(loader, {
465
432
  maxBatchSize: 99
466
433
  });
467
434
  };
468
435
 
436
+ // Limits concurrent requests to 20 so that they don't timeout
469
437
  const CONCURRENT_REQUESTS_MAX$1 = 20;
470
438
  const collectionPageTypes = /*#__PURE__*/new Set(['brand', 'category', 'department', 'subcategory', 'collection', 'cluster']);
471
439
  const isCollectionPageType = x => typeof x.pageType === 'string' && collectionPageTypes.has(x.pageType.toLowerCase());
472
440
  const getCollectionLoader = (_, clients) => {
473
441
  const limit = pLimit(CONCURRENT_REQUESTS_MAX$1);
474
-
475
442
  const loader = async slugs => {
476
443
  return Promise.all(slugs.map(slug => limit(async () => {
477
444
  const page = await clients.commerce.catalog.portal.pagetype(slug);
478
-
479
445
  if (isCollectionPageType(page)) {
480
446
  return page;
481
447
  }
482
-
483
448
  throw new NotFoundError(`Catalog returned ${page.pageType} for slug: ${slug}. This usually happens when there is more than one category with the same name in the same category tree level.`);
484
449
  })));
485
450
  };
486
-
487
451
  return new DataLoader(loader, {
488
452
  // DataLoader is being used to cache requests, not to batch them
489
453
  batch: false
@@ -508,25 +472,21 @@ const getLoaders = (options, {
508
472
  const inStock = offer => offer.AvailableQuantity > 0;
509
473
  const price = offer => {
510
474
  var _offer$spotPrice;
511
-
512
475
  return (_offer$spotPrice = offer.spotPrice) != null ? _offer$spotPrice : 0;
513
476
  };
514
477
  const sellingPrice = offer => {
515
478
  var _offer$Price;
516
-
517
479
  return (_offer$Price = offer.Price) != null ? _offer$Price : 0;
518
480
  };
519
- const availability = available => available ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock'; // Smallest Available Spot Price First
520
-
481
+ const availability = available => available ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock';
482
+ // Smallest Available Spot Price First
521
483
  const bestOfferFirst = (a, b) => {
522
484
  if (inStock(a) && !inStock(b)) {
523
485
  return -1;
524
486
  }
525
-
526
487
  if (!inStock(a) && inStock(b)) {
527
488
  return 1;
528
489
  }
529
-
530
490
  return price(a) - price(b);
531
491
  };
532
492
  const inStockOrderFormItem = itemAvailability => itemAvailability === 'available';
@@ -544,7 +504,6 @@ const StoreAggregateOffer = {
544
504
  offerCount: offers => offers.length,
545
505
  priceCurrency: async (_, __, ctx) => {
546
506
  var _sc$CurrencyCode;
547
-
548
507
  const {
549
508
  loaders: {
550
509
  salesChannelLoader
@@ -565,8 +524,6 @@ const StoreAggregateRating = {
565
524
  reviewCount: () => 0
566
525
  };
567
526
 
568
- /* eslint-disable no-useless-escape */
569
-
570
527
  /**
571
528
  * VTEX catalog slugify function
572
529
  *
@@ -589,21 +546,16 @@ const StoreAggregateRating = {
589
546
  */
590
547
  const from = 'ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆÍÌÎÏŇÑÓÖÒÔÕØŘŔŠŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇíìîïňñóöòôõøðřŕšťúůüùûýÿžþÞĐđ߯a';
591
548
  const to = 'AAAAAACCCDEEEEEEEEIIIINNOOOOOORRSTUUUUUYYZaaaaaacccdeeeeeeeeiiiinnooooooorrstuuuuuyyzbBDdBAa';
592
-
593
549
  const removeDiacritics = str => {
594
550
  let newStr = str.slice(0);
595
-
596
551
  for (let i = 0; i < from.length; i++) {
597
552
  newStr = newStr.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
598
553
  }
599
-
600
554
  return newStr;
601
555
  };
602
-
603
556
  const slugifySpecialCharacters = str => {
604
557
  return str.replace(/[·/_,:]/, '-');
605
558
  };
606
-
607
559
  function slugify(str) {
608
560
  const noCommas = str.replace(/,/g, '');
609
561
  const replaced = noCommas.replace(/[*+~.()'"!:@&\[\]`/ %$#?{}|><=_^]/g, '-');
@@ -612,21 +564,16 @@ function slugify(str) {
612
564
  }
613
565
 
614
566
  const isBrand = x => x.type === 'brand' || isCollectionPageType(x) && x.pageType.toLowerCase() === 'brand';
615
-
616
567
  const isCollection = x => isCollectionPageType(x) && x.pageType.toLowerCase() === 'collection';
617
-
618
568
  const slugifyRoot = root => {
619
569
  if (isBrand(root) || isCollection(root)) {
620
570
  return slugify(root.name);
621
571
  }
622
-
623
572
  if (isCollectionPageType(root)) {
624
573
  return new URL(`https://${root.url}`).pathname.slice(1).toLowerCase();
625
574
  }
626
-
627
575
  return new URL(root.url).pathname.slice(1).toLowerCase();
628
576
  };
629
-
630
577
  const StoreCollection = {
631
578
  id: ({
632
579
  id
@@ -672,7 +619,6 @@ const StoreCollection = {
672
619
  * we need all metadata for both `/foo` and `/bar` and
673
620
  * thus we need to fetch pageType for `/foo` and `/bar`
674
621
  */
675
-
676
622
  const segments = slug.split('/').filter(segment => Boolean(segment));
677
623
  const slugs = segments.map((__, index) => segments.slice(0, index + 1).join('/'));
678
624
  const collections = await Promise.all(slugs.map(async s => {
@@ -697,7 +643,6 @@ class ChannelMarshal {
697
643
  static parse(channelString) {
698
644
  try {
699
645
  var _parsedChannel$region, _parsedChannel$salesC;
700
-
701
646
  const parsedChannel = JSON.parse(channelString);
702
647
  return {
703
648
  regionId: (_parsedChannel$region = parsedChannel.regionId) != null ? _parsedChannel$region : '',
@@ -708,11 +653,9 @@ class ChannelMarshal {
708
653
  throw new Error('Malformed channel string');
709
654
  }
710
655
  }
711
-
712
656
  static stringify(channel) {
713
657
  return JSON.stringify(channel);
714
658
  }
715
-
716
659
  }
717
660
 
718
661
  const FACET_CROSS_SELLING_MAP = {
@@ -727,7 +670,6 @@ const FACET_CROSS_SELLING_MAP = {
727
670
  * Transform facets from the store to VTEX platform facets.
728
671
  * For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm
729
672
  * */
730
-
731
673
  const transformSelectedFacet = ({
732
674
  key,
733
675
  value
@@ -740,17 +682,14 @@ const transformSelectedFacet = ({
740
682
  key: 'trade-policy',
741
683
  value: channel.salesChannel
742
684
  }];
743
-
744
685
  if (channel.regionId) {
745
686
  channelFacets.push({
746
687
  key: 'region-id',
747
688
  value: channel.regionId
748
689
  });
749
690
  }
750
-
751
691
  return channelFacets;
752
692
  }
753
-
754
693
  case 'locale':
755
694
  {
756
695
  return []; // remove this facet from search
@@ -763,7 +702,6 @@ const transformSelectedFacet = ({
763
702
  value: value.replace('-to-', ':')
764
703
  };
765
704
  }
766
-
767
705
  case "buy":
768
706
  case "view":
769
707
  case "similars":
@@ -783,43 +721,34 @@ const transformSelectedFacet = ({
783
721
  };
784
722
  const parseRange = range => {
785
723
  const splitted = range.split(':').map(Number);
786
-
787
724
  if (splitted.length !== 2 || Number.isNaN(splitted[0]) || Number.isNaN(splitted[1])) {
788
725
  return null;
789
726
  }
790
-
791
727
  return splitted;
792
728
  };
793
729
  const isCrossSelling = x => typeof FACET_CROSS_SELLING_MAP[x] === "string";
794
730
  const findCrossSelling = facets => {
795
731
  var _filtered$;
796
-
797
732
  const filtered = facets == null ? void 0 : facets.filter(x => isCrossSelling(x.key));
798
-
799
733
  if (Array.isArray(filtered) && filtered.length > 1) {
800
734
  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(',')}`);
801
735
  }
802
-
803
736
  return (_filtered$ = filtered == null ? void 0 : filtered[0]) != null ? _filtered$ : null;
804
737
  };
805
738
  const findSlug = facets => {
806
739
  var _facets$find$value, _facets$find;
807
-
808
740
  return (_facets$find$value = facets == null ? void 0 : (_facets$find = facets.find(x => x.key === 'slug')) == null ? void 0 : _facets$find.value) != null ? _facets$find$value : null;
809
741
  };
810
742
  const findSkuId = facets => {
811
743
  var _facets$find$value2, _facets$find2;
812
-
813
744
  return (_facets$find$value2 = facets == null ? void 0 : (_facets$find2 = facets.find(x => x.key === 'id')) == null ? void 0 : _facets$find2.value) != null ? _facets$find$value2 : null;
814
745
  };
815
746
  const findLocale = facets => {
816
747
  var _facets$find$value3, _facets$find3;
817
-
818
748
  return (_facets$find$value3 = facets == null ? void 0 : (_facets$find3 = facets.find(x => x.key === 'locale')) == null ? void 0 : _facets$find3.value) != null ? _facets$find$value3 : null;
819
749
  };
820
750
  const findChannel = facets => {
821
751
  var _facets$find$value4, _facets$find4;
822
-
823
752
  return (_facets$find$value4 = facets == null ? void 0 : (_facets$find4 = facets.find(facet => facet.key === 'channel')) == null ? void 0 : _facets$find4.value) != null ? _facets$find$value4 : null;
824
753
  };
825
754
 
@@ -829,13 +758,11 @@ const findChannel = facets => {
829
758
  // O(n) search to find the max of an array
830
759
  const min = (array, cmp) => {
831
760
  let best = 0;
832
-
833
761
  for (let curr = 1; curr < array.length; curr++) {
834
762
  if (cmp(array[best], array[curr]) > 0) {
835
763
  best = curr;
836
764
  }
837
765
  }
838
-
839
766
  return array[best];
840
767
  };
841
768
 
@@ -871,7 +798,6 @@ const StoreFacetRange = {
871
798
  }
872
799
  }) => {
873
800
  var _searchArgs$selectedF, _searchArgs$selectedF2, _searchArgs$selectedF3, _facet$range$from, _selectedRange$;
874
-
875
801
  /**
876
802
  * Fetch the selected range the user queried.
877
803
  *
@@ -895,7 +821,6 @@ const StoreFacetRange = {
895
821
  }
896
822
  }) => {
897
823
  var _searchArgs$selectedF4, _searchArgs$selectedF5, _searchArgs$selectedF6, _facet$range$to, _selectedRange$2;
898
-
899
824
  /**
900
825
  * Fetch the selected range the user queried.
901
826
  *
@@ -958,13 +883,10 @@ function getPropertyId(item) {
958
883
  }
959
884
 
960
885
  const isAttachment = value => value.valueReference === VALUE_REFERENCES.attachment;
961
-
962
886
  const getId = item => {
963
887
  var _item$itemOffered$add;
964
-
965
888
  return [item.itemOffered.sku, item.seller.identifier, item.price < 0.01 ? 'Gift' : undefined, (_item$itemOffered$add = item.itemOffered.additionalProperty) == null ? void 0 : _item$itemOffered$add.filter(isAttachment).map(getPropertyId).join('-')].filter(Boolean).join('::');
966
889
  };
967
-
968
890
  const orderFormItemToOffer = (item, index) => ({
969
891
  listPrice: item.listPrice / 100,
970
892
  price: item.sellingPrice / 100,
@@ -980,10 +902,8 @@ const orderFormItemToOffer = (item, index) => ({
980
902
  },
981
903
  index
982
904
  });
983
-
984
905
  const offerToOrderItemInput = offer => {
985
906
  var _offer$itemOffered$ad, _offer$itemOffered$ad2;
986
-
987
907
  return {
988
908
  quantity: offer.quantity,
989
909
  seller: offer.seller.identifier,
@@ -995,64 +915,58 @@ const offerToOrderItemInput = offer => {
995
915
  }))
996
916
  };
997
917
  };
998
-
999
918
  const groupById = offers => offers.reduce((acc, item) => {
1000
919
  var _acc$get;
1001
-
1002
920
  const id = getId(item);
1003
-
1004
921
  if (!acc.has(id)) {
1005
922
  acc.set(id, []);
1006
923
  }
1007
-
1008
924
  (_acc$get = acc.get(id)) == null ? void 0 : _acc$get.push(item);
1009
925
  return acc;
1010
926
  }, new Map());
1011
-
1012
927
  const equals = (storeOrder, orderForm) => {
1013
- const pick = (item, index) => ({ ...item,
928
+ const pick = (item, index) => ({
929
+ ...item,
1014
930
  itemOffered: {
1015
931
  sku: item.itemOffered.sku
1016
932
  },
1017
933
  index
1018
934
  });
1019
-
1020
935
  const orderFormItems = orderForm.items.map(orderFormItemToOffer).map(pick);
1021
936
  const storeOrderItems = storeOrder.acceptedOffer.map(pick);
1022
937
  const isSameOrder = storeOrder.orderNumber === orderForm.orderFormId;
1023
938
  const orderItemsAreSync = deepEquals(orderFormItems, storeOrderItems);
1024
939
  return isSameOrder && orderItemsAreSync;
1025
940
  };
1026
-
1027
941
  const joinItems = form => {
1028
942
  const itemsById = form.items.reduce((acc, item) => {
1029
943
  const id = getId(orderFormItemToOffer(item));
1030
-
1031
944
  if (!acc[id]) {
1032
945
  acc[id] = [];
1033
946
  }
1034
-
1035
947
  acc[id].push(item);
1036
948
  return acc;
1037
949
  }, {});
1038
- return { ...form,
950
+ return {
951
+ ...form,
1039
952
  items: Object.values(itemsById).map(items => {
1040
953
  const [item] = items;
1041
954
  const quantity = items.reduce((acc, i) => acc + i.quantity, 0);
1042
955
  const totalPrice = items.reduce((acc, i) => acc + i.quantity * i.sellingPrice, 0);
1043
- return { ...item,
956
+ return {
957
+ ...item,
1044
958
  quantity,
1045
959
  sellingPrice: totalPrice / quantity
1046
960
  };
1047
961
  })
1048
962
  };
1049
963
  };
1050
-
1051
964
  const orderFormToCart = async (form, skuLoader) => {
1052
965
  return {
1053
966
  order: {
1054
967
  orderNumber: form.orderFormId,
1055
- acceptedOffer: form.items.map(async item => ({ ...item,
968
+ acceptedOffer: form.items.map(async item => ({
969
+ ...item,
1056
970
  product: await skuLoader.load(item.id)
1057
971
  }))
1058
972
  },
@@ -1065,11 +979,9 @@ const orderFormToCart = async (form, skuLoader) => {
1065
979
  }))
1066
980
  };
1067
981
  };
1068
-
1069
982
  const getOrderFormEtag = ({
1070
983
  items
1071
984
  }) => md5(JSON.stringify(items));
1072
-
1073
985
  const setOrderFormEtag = async (form, commerce) => {
1074
986
  try {
1075
987
  const orderForm = await commerce.checkout.setCustomData({
@@ -1089,44 +1001,35 @@ const setOrderFormEtag = async (form, commerce) => {
1089
1001
  * @description If cartEtag is not up to date, this means that
1090
1002
  * another system changed the cart, like Checkout UI or Order Placed
1091
1003
  */
1092
-
1093
-
1094
1004
  const isOrderFormStale = form => {
1095
1005
  var _form$customData, _faststoreData$fields;
1096
-
1097
1006
  const faststoreData = (_form$customData = form.customData) == null ? void 0 : _form$customData.customApps.find(app => app.id === 'faststore');
1098
1007
  const oldEtag = faststoreData == null ? void 0 : (_faststoreData$fields = faststoreData.fields) == null ? void 0 : _faststoreData$fields.cartEtag;
1099
-
1100
1008
  if (oldEtag == null) {
1101
1009
  return true;
1102
1010
  }
1103
-
1104
1011
  const newEtag = getOrderFormEtag(form);
1105
1012
  return newEtag !== oldEtag;
1106
- }; // Returns the regionalized orderForm
1107
-
1108
-
1013
+ };
1014
+ // Returns the regionalized orderForm
1109
1015
  const getOrderForm = async (id, session, {
1110
1016
  clients: {
1111
1017
  commerce
1112
1018
  }
1113
1019
  }) => {
1114
1020
  var _orderForm$shippingDa, _orderForm$shippingDa2;
1115
-
1116
1021
  const orderForm = await commerce.checkout.orderForm({
1117
1022
  id
1118
- }); // Stores that are not yet providing the session while validating the cart
1023
+ });
1024
+ // Stores that are not yet providing the session while validating the cart
1119
1025
  // should not be able to update the shipping data
1120
1026
  //
1121
1027
  // This was causing errors while validating regionalizated carts
1122
1028
  // because the following code was trying to change the shippingData to an undefined address/session
1123
-
1124
1029
  if (!session) {
1125
1030
  return orderForm;
1126
1031
  }
1127
-
1128
1032
  const shouldUpdateShippingData = typeof session.postalCode === 'string' && ((_orderForm$shippingDa = orderForm.shippingData) == null ? void 0 : (_orderForm$shippingDa2 = _orderForm$shippingDa.address) == null ? void 0 : _orderForm$shippingDa2.postalCode) != session.postalCode;
1129
-
1130
1033
  if (shouldUpdateShippingData) {
1131
1034
  return commerce.checkout.shippingData({
1132
1035
  id: orderForm.orderFormId,
@@ -1135,7 +1038,6 @@ const getOrderForm = async (id, session, {
1135
1038
  }
1136
1039
  });
1137
1040
  }
1138
-
1139
1041
  return orderForm;
1140
1042
  };
1141
1043
  /**
@@ -1151,8 +1053,6 @@ const getOrderForm = async (id, session, {
1151
1053
  * 3. Update the orderForm in VTEX platform accordingly
1152
1054
  * 4. If any changes were made, send to the UI the new cart. Null otherwise
1153
1055
  */
1154
-
1155
-
1156
1056
  const validateCart = async (_, {
1157
1057
  cart: {
1158
1058
  order
@@ -1173,49 +1073,46 @@ const validateCart = async (_, {
1173
1073
  loaders: {
1174
1074
  skuLoader
1175
1075
  }
1176
- } = ctx; // Step1: Get OrderForm from VTEX Commerce
1177
-
1178
- const orderForm = await getOrderForm(orderNumber, session, ctx); // Step1.5: Check if another system changed the orderForm with this orderNumber
1076
+ } = ctx;
1077
+ // Step1: Get OrderForm from VTEX Commerce
1078
+ const orderForm = await getOrderForm(orderNumber, session, ctx);
1079
+ // Step1.5: Check if another system changed the orderForm with this orderNumber
1179
1080
  // If so, this means the user interacted with this cart elsewhere and expects
1180
1081
  // to see this new cart state instead of what's stored on the user's browser.
1181
-
1182
1082
  if (enableOrderFormSync === true) {
1183
1083
  const isStale = isOrderFormStale(orderForm);
1184
-
1185
1084
  if (isStale === true && orderNumber) {
1186
1085
  const newOrderForm = await setOrderFormEtag(orderForm, commerce).then(joinItems);
1187
1086
  return orderFormToCart(newOrderForm, skuLoader);
1188
1087
  }
1189
- } // Step2: Process items from both browser and checkout so they have the same shape
1190
-
1191
-
1088
+ }
1089
+ // Step2: Process items from both browser and checkout so they have the same shape
1192
1090
  const browserItemsById = groupById(acceptedOffer);
1193
1091
  const originItemsById = groupById(orderForm.items.map(orderFormItemToOffer));
1194
1092
  const originItems = Array.from(originItemsById.entries()); // items on the VTEX platform backend
1195
-
1196
1093
  const browserItems = Array.from(browserItemsById.entries()); // items on the user's browser
1197
1094
  // Step3: Compute delta changes
1198
-
1199
1095
  const {
1200
1096
  itemsToAdd,
1201
1097
  itemsToUpdate
1202
1098
  } = browserItems.reduce((acc, [id, items]) => {
1203
- const maybeOriginItem = originItemsById.get(id); // Adding new items to cart
1204
-
1099
+ const maybeOriginItem = originItemsById.get(id);
1100
+ // Adding new items to cart
1205
1101
  if (!maybeOriginItem) {
1206
1102
  items.forEach(item => acc.itemsToAdd.push(item));
1207
1103
  return acc;
1208
- } // Update existing items
1209
-
1210
-
1104
+ }
1105
+ // Update existing items
1211
1106
  const [head, ...tail] = maybeOriginItem;
1212
- const totalQuantity = items.reduce((acc, curr) => acc + curr.quantity, 0); // set total quantity to first item
1213
-
1214
- acc.itemsToUpdate.push({ ...head,
1107
+ const totalQuantity = items.reduce((acc, curr) => acc + curr.quantity, 0);
1108
+ // set total quantity to first item
1109
+ acc.itemsToUpdate.push({
1110
+ ...head,
1215
1111
  quantity: totalQuantity
1216
- }); // Remove all the rest
1217
-
1218
- tail.forEach(item => acc.itemsToUpdate.push({ ...item,
1112
+ });
1113
+ // Remove all the rest
1114
+ tail.forEach(item => acc.itemsToUpdate.push({
1115
+ ...item,
1219
1116
  quantity: 0
1220
1117
  }));
1221
1118
  return acc;
@@ -1223,28 +1120,28 @@ const validateCart = async (_, {
1223
1120
  itemsToAdd: [],
1224
1121
  itemsToUpdate: []
1225
1122
  });
1226
- const itemsToDelete = originItems.filter(([id]) => !browserItemsById.has(id)).flatMap(([, items]) => items.map(item => ({ ...item,
1123
+ const itemsToDelete = originItems.filter(([id]) => !browserItemsById.has(id)).flatMap(([, items]) => items.map(item => ({
1124
+ ...item,
1227
1125
  quantity: 0
1228
1126
  })));
1229
1127
  const changes = [...itemsToAdd, ...itemsToUpdate, ...itemsToDelete].map(offerToOrderItemInput);
1230
-
1231
1128
  if (changes.length === 0) {
1232
1129
  return null;
1233
- } // Step4: Apply delta changes to order form
1234
-
1235
-
1236
- const updatedOrderForm = await commerce.checkout // update orderForm items
1130
+ }
1131
+ // Step4: Apply delta changes to order form
1132
+ const updatedOrderForm = await commerce.checkout
1133
+ // update orderForm items
1237
1134
  .updateOrderFormItems({
1238
1135
  id: orderForm.orderFormId,
1239
1136
  orderItems: changes
1240
- }) // update orderForm etag so we know last time we touched this orderForm
1241
- .then(form => enableOrderFormSync ? setOrderFormEtag(form, commerce) : form).then(joinItems); // Step5: If no changes detected before/after updating orderForm, the order is validated
1242
-
1137
+ })
1138
+ // update orderForm etag so we know last time we touched this orderForm
1139
+ .then(form => enableOrderFormSync ? setOrderFormEtag(form, commerce) : form).then(joinItems);
1140
+ // Step5: If no changes detected before/after updating orderForm, the order is validated
1243
1141
  if (equals(order, updatedOrderForm)) {
1244
1142
  return null;
1245
- } // Step6: There were changes, convert orderForm to StoreCart
1246
-
1247
-
1143
+ }
1144
+ // Step6: There were changes, convert orderForm to StoreCart
1248
1145
  return orderFormToCart(updatedOrderForm, skuLoader);
1249
1146
  };
1250
1147
 
@@ -1255,7 +1152,6 @@ const validateSession = async (_, {
1255
1152
  clients
1256
1153
  }) => {
1257
1154
  var _oldSession$channel, _oldSession$postalCod, _oldSession$country, _params$get, _sessionData$namespac, _sessionData$namespac2, _store$currencyCode$v, _store$currencySymbol, _store$countryCode$va, _store$channel$value, _store$channel, _regionData$0$id, _regionData$, _profile$id$value, _profile$id, _profile$email$value, _profile$email, _profile$firstName$va, _profile$firstName, _profile$lastName$val, _profile$lastName;
1258
-
1259
1155
  const channel = ChannelMarshal.parse((_oldSession$channel = oldSession.channel) != null ? _oldSession$channel : '');
1260
1156
  const postalCode = String((_oldSession$postalCod = oldSession.postalCode) != null ? _oldSession$postalCod : '').replace(/\D/g, '');
1261
1157
  const country = (_oldSession$country = oldSession.country) != null ? _oldSession$country : '';
@@ -1269,7 +1165,8 @@ const validateSession = async (_, {
1269
1165
  }) : Promise.resolve(null), clients.commerce.session(params.toString()).catch(() => null)]);
1270
1166
  const profile = (_sessionData$namespac = sessionData == null ? void 0 : sessionData.namespaces.profile) != null ? _sessionData$namespac : null;
1271
1167
  const store = (_sessionData$namespac2 = sessionData == null ? void 0 : sessionData.namespaces.store) != null ? _sessionData$namespac2 : null;
1272
- const newSession = { ...oldSession,
1168
+ const newSession = {
1169
+ ...oldSession,
1273
1170
  currency: {
1274
1171
  code: (_store$currencyCode$v = store == null ? void 0 : store.currencyCode.value) != null ? _store$currencyCode$v : oldSession.currency.code,
1275
1172
  symbol: (_store$currencySymbol = store == null ? void 0 : store.currencySymbol.value) != null ? _store$currencySymbol : oldSession.currency.symbol
@@ -1286,11 +1183,9 @@ const validateSession = async (_, {
1286
1183
  familyName: (_profile$lastName$val = (_profile$lastName = profile.lastName) == null ? void 0 : _profile$lastName.value) != null ? _profile$lastName$val : ''
1287
1184
  } : null
1288
1185
  };
1289
-
1290
1186
  if (deepEquals(oldSession, newSession)) {
1291
1187
  return null;
1292
1188
  }
1293
-
1294
1189
  return newSession;
1295
1190
  };
1296
1191
 
@@ -1305,25 +1200,19 @@ const ObjectOrString = /*#__PURE__*/new GraphQLScalarType({
1305
1200
  description: 'A string or the string representation of an object (a stringified object).',
1306
1201
  parseValue: toObjectOrString,
1307
1202
  serialize: stringify,
1308
-
1309
1203
  parseLiteral(ast) {
1310
1204
  if (ast.kind === Kind.STRING) {
1311
1205
  return getValueAsObjectOrString(ast.value);
1312
1206
  }
1313
-
1314
1207
  return null;
1315
1208
  }
1316
-
1317
1209
  });
1318
-
1319
1210
  function toObjectOrString(value) {
1320
1211
  if (typeof value === 'string') {
1321
1212
  return getValueAsObjectOrString(value);
1322
1213
  }
1323
-
1324
1214
  return null;
1325
1215
  }
1326
-
1327
1216
  function getValueAsObjectOrString(value) {
1328
1217
  try {
1329
1218
  return JSON.parse(value);
@@ -1331,27 +1220,21 @@ function getValueAsObjectOrString(value) {
1331
1220
  return value;
1332
1221
  }
1333
1222
  }
1334
-
1335
1223
  function stringify(value) {
1336
1224
  if (typeof value === 'object') {
1337
1225
  return JSON.stringify(value);
1338
1226
  }
1339
-
1340
1227
  if (typeof value === 'string') {
1341
1228
  return value;
1342
1229
  }
1343
-
1344
1230
  return null;
1345
1231
  }
1346
1232
 
1347
1233
  const isSearchItem = item => 'Price' in item && 'seller' in item && 'product' in item;
1348
-
1349
1234
  const isOrderFormItem = item => 'skuName' in item;
1350
-
1351
1235
  const StoreOffer = {
1352
1236
  priceCurrency: async (_, __, ctx) => {
1353
1237
  var _sc$CurrencyCode;
1354
-
1355
1238
  const {
1356
1239
  loaders: {
1357
1240
  salesChannelLoader
@@ -1366,16 +1249,12 @@ const StoreOffer = {
1366
1249
  priceValidUntil: root => {
1367
1250
  if (isSearchItem(root)) {
1368
1251
  var _root$PriceValidUntil;
1369
-
1370
1252
  return (_root$PriceValidUntil = root.PriceValidUntil) != null ? _root$PriceValidUntil : '';
1371
1253
  }
1372
-
1373
1254
  if (isOrderFormItem(root)) {
1374
1255
  var _root$priceValidUntil;
1375
-
1376
1256
  return (_root$priceValidUntil = root.priceValidUntil) != null ? _root$priceValidUntil : '';
1377
1257
  }
1378
-
1379
1258
  return null;
1380
1259
  },
1381
1260
  itemCondition: () => 'https://schema.org/NewCondition',
@@ -1383,89 +1262,73 @@ const StoreOffer = {
1383
1262
  if (isSearchItem(root)) {
1384
1263
  return availability(inStock(root));
1385
1264
  }
1386
-
1387
1265
  if (isOrderFormItem(root)) {
1388
1266
  return availability(inStockOrderFormItem(root.availability));
1389
1267
  }
1390
-
1391
1268
  return null;
1392
1269
  },
1393
1270
  seller: root => {
1394
1271
  if (isSearchItem(root)) {
1395
1272
  var _root$seller$sellerId;
1396
-
1397
1273
  return {
1398
1274
  identifier: (_root$seller$sellerId = root.seller.sellerId) != null ? _root$seller$sellerId : ''
1399
1275
  };
1400
1276
  }
1401
-
1402
1277
  if (isOrderFormItem(root)) {
1403
1278
  return {
1404
1279
  identifier: root.seller
1405
1280
  };
1406
1281
  }
1407
-
1408
1282
  return null;
1409
1283
  },
1410
1284
  price: root => {
1411
1285
  if (isSearchItem(root)) {
1412
1286
  return price(root);
1413
1287
  }
1414
-
1415
1288
  if (isOrderFormItem(root)) {
1416
1289
  return root.sellingPrice / 1e2;
1417
1290
  }
1418
-
1419
1291
  return null;
1420
1292
  },
1421
1293
  sellingPrice: root => {
1422
1294
  if (isSearchItem(root)) {
1423
1295
  return sellingPrice(root);
1424
1296
  }
1425
-
1426
1297
  if (isOrderFormItem(root)) {
1427
1298
  return root.sellingPrice / 1e2;
1428
1299
  }
1429
-
1430
1300
  return null;
1431
1301
  },
1432
1302
  listPrice: root => {
1433
1303
  if (isSearchItem(root)) {
1434
1304
  var _root$ListPrice;
1435
-
1436
1305
  return (_root$ListPrice = root.ListPrice) != null ? _root$ListPrice : 0;
1437
1306
  }
1438
-
1439
1307
  if (isOrderFormItem(root)) {
1440
1308
  return root.listPrice / 1e2;
1441
1309
  }
1442
-
1443
1310
  return null;
1444
1311
  },
1445
1312
  itemOffered: root => {
1446
1313
  if (isSearchItem(root)) {
1447
1314
  return root.product;
1448
1315
  }
1449
-
1450
1316
  if (isOrderFormItem(root)) {
1451
- return { ...root.product,
1317
+ return {
1318
+ ...root.product,
1452
1319
  attachmentsValues: root.attachments
1453
1320
  };
1454
1321
  }
1455
-
1456
1322
  return null;
1457
1323
  },
1458
1324
  quantity: root => {
1459
1325
  if (isSearchItem(root)) {
1460
1326
  var _root$AvailableQuanti;
1461
-
1462
1327
  return (_root$AvailableQuanti = root.AvailableQuantity) != null ? _root$AvailableQuanti : 0;
1463
1328
  }
1464
-
1465
1329
  if (isOrderFormItem(root)) {
1466
1330
  return root.quantity;
1467
1331
  }
1468
-
1469
1332
  return null;
1470
1333
  }
1471
1334
  };
@@ -1478,7 +1341,8 @@ const enhanceCommercialOffer = ({
1478
1341
  offer,
1479
1342
  seller,
1480
1343
  product
1481
- }) => ({ ...offer,
1344
+ }) => ({
1345
+ ...offer,
1482
1346
  product,
1483
1347
  seller
1484
1348
  });
@@ -1487,13 +1351,9 @@ const DEFAULT_IMAGE = {
1487
1351
  imageText: 'image',
1488
1352
  imageUrl: 'https://storecomponents.vtexassets.com/assets/faststore/images/image___117a6d3e229a96ad0e0d0876352566e2.svg'
1489
1353
  };
1490
-
1491
1354
  const getSlug = (link, id) => `${link}-${id}`;
1492
-
1493
1355
  const getPath = (link, id) => `/${getSlug(link, id)}/p`;
1494
-
1495
1356
  const nonEmptyArray = array => Array.isArray(array) && array.length > 0 ? array : null;
1496
-
1497
1357
  const StoreProduct = {
1498
1358
  productID: ({
1499
1359
  itemId
@@ -1557,7 +1417,6 @@ const StoreProduct = {
1557
1417
  images
1558
1418
  }) => {
1559
1419
  var _nonEmptyArray;
1560
-
1561
1420
  return ((_nonEmptyArray = nonEmptyArray(images)) != null ? _nonEmptyArray : [DEFAULT_IMAGE]).map(({
1562
1421
  imageUrl,
1563
1422
  imageText
@@ -1573,7 +1432,6 @@ const StoreProduct = {
1573
1432
  referenceId
1574
1433
  }) => {
1575
1434
  var _referenceId$0$Value, _referenceId$;
1576
-
1577
1435
  return (_referenceId$0$Value = (_referenceId$ = referenceId[0]) == null ? void 0 : _referenceId$.Value) != null ? _referenceId$0$Value : '';
1578
1436
  },
1579
1437
  review: () => [],
@@ -1619,8 +1477,10 @@ const StoreProductGroup = {
1619
1477
  isVariantOf: {
1620
1478
  specificationGroups
1621
1479
  }
1622
- }) => specificationGroups // Filter sku specifications so we don't mix them with product specs.
1623
- .filter(specificationGroup => !BLOCKED_SPECIFICATIONS.has(specificationGroup.name)) // Transform specs back into product specs.
1480
+ }) => specificationGroups
1481
+ // Filter sku specifications so we don't mix them with product specs.
1482
+ .filter(specificationGroup => !BLOCKED_SPECIFICATIONS.has(specificationGroup.name))
1483
+ // Transform specs back into product specs.
1624
1484
  .flatMap(({
1625
1485
  specifications
1626
1486
  }) => specifications.flatMap(({
@@ -1669,7 +1529,6 @@ const SORT_MAP = {
1669
1529
  *
1670
1530
  * The best sku is the one with the best (cheapest available) offer
1671
1531
  * */
1672
-
1673
1532
  const pickBestSku = skus => {
1674
1533
  const offersBySku = skus.flatMap(sku => sku.sellers.map(seller => ({
1675
1534
  offer: seller.commertialOffer,
@@ -1693,15 +1552,12 @@ const Query = {
1693
1552
  const locale = findLocale(locator);
1694
1553
  const id = findSkuId(locator);
1695
1554
  const slug = findSlug(locator);
1696
-
1697
1555
  if (channel) {
1698
1556
  mutateChannelContext(ctx, channel);
1699
1557
  }
1700
-
1701
1558
  if (locale) {
1702
1559
  mutateLocaleContext(ctx, locale);
1703
1560
  }
1704
-
1705
1561
  const {
1706
1562
  loaders: {
1707
1563
  skuLoader
@@ -1711,16 +1567,12 @@ const Query = {
1711
1567
  search
1712
1568
  }
1713
1569
  } = ctx;
1714
-
1715
1570
  try {
1716
1571
  var _ref;
1717
-
1718
1572
  const skuId = (_ref = id != null ? id : slug == null ? void 0 : slug.split('-').pop()) != null ? _ref : '';
1719
-
1720
1573
  if (!isValidSkuId(skuId)) {
1721
1574
  throw new Error('Invalid SkuId');
1722
1575
  }
1723
-
1724
1576
  const sku = await skuLoader.load(skuId);
1725
1577
  /**
1726
1578
  * Here be dragons 🦄🦄🦄
@@ -1729,23 +1581,18 @@ const Query = {
1729
1581
  * product. This condition makes sure that the fetched sku
1730
1582
  * is the one we actually asked for
1731
1583
  * */
1732
-
1733
1584
  if (slug && sku.isVariantOf.linkText && !slug.startsWith(sku.isVariantOf.linkText)) {
1734
1585
  throw new Error(`Slug was set but the fetched sku does not satisfy the slug condition. slug: ${slug}, linkText: ${sku.isVariantOf.linkText}`);
1735
1586
  }
1736
-
1737
1587
  return sku;
1738
1588
  } catch (err) {
1739
1589
  if (slug == null) {
1740
1590
  throw new BadRequestError('Missing slug or id');
1741
1591
  }
1742
-
1743
1592
  const route = await commerce.catalog.portal.pagetype(`${slug}/p`);
1744
-
1745
1593
  if (route.pageType !== 'Product' || !route.id) {
1746
1594
  throw new NotFoundError(`No product found for slug ${slug}`);
1747
1595
  }
1748
-
1749
1596
  const {
1750
1597
  products: [product]
1751
1598
  } = await search.products({
@@ -1753,11 +1600,9 @@ const Query = {
1753
1600
  count: 1,
1754
1601
  query: `product:${route.id}`
1755
1602
  });
1756
-
1757
1603
  if (!product) {
1758
1604
  throw new NotFoundError(`No product found for id ${route.id}`);
1759
1605
  }
1760
-
1761
1606
  const sku = pickBestSku(product.items);
1762
1607
  return enhanceSku(sku, product);
1763
1608
  }
@@ -1780,20 +1625,16 @@ const Query = {
1780
1625
  selectedFacets
1781
1626
  }, ctx) => {
1782
1627
  var _selectedFacets$flatM;
1783
-
1784
1628
  // Insert channel in context for later usage
1785
1629
  const channel = findChannel(selectedFacets);
1786
1630
  const locale = findLocale(selectedFacets);
1787
1631
  const crossSelling = findCrossSelling(selectedFacets);
1788
-
1789
1632
  if (channel) {
1790
1633
  mutateChannelContext(ctx, channel);
1791
1634
  }
1792
-
1793
1635
  if (locale) {
1794
1636
  mutateLocaleContext(ctx, locale);
1795
1637
  }
1796
-
1797
1638
  let query = term;
1798
1639
  /**
1799
1640
  * In case we are using crossSelling, we need to modify the search
@@ -1804,7 +1645,6 @@ const Query = {
1804
1645
  * selling with Search features, like pagination, internationalization
1805
1646
  * etc
1806
1647
  */
1807
-
1808
1648
  if (crossSelling) {
1809
1649
  const products = await ctx.clients.commerce.catalog.products.crossselling({
1810
1650
  type: FACET_CROSS_SELLING_MAP[crossSelling.key],
@@ -1812,7 +1652,6 @@ const Query = {
1812
1652
  });
1813
1653
  query = `product:${products.map(x => x.productId).slice(0, first).join(";")}`;
1814
1654
  }
1815
-
1816
1655
  const after = maybeAfter ? Number(maybeAfter) : 0;
1817
1656
  const searchArgs = {
1818
1657
  page: Math.ceil(after / first),
@@ -1865,25 +1704,24 @@ const Query = {
1865
1704
  const after = maybeAfter ? Number(maybeAfter) : 0;
1866
1705
  const [brands, tree] = await Promise.all([commerce.catalog.brand.list(), commerce.catalog.category.tree()]);
1867
1706
  const categories = [];
1868
-
1869
1707
  const dfs = (node, level) => {
1870
- categories.push({ ...node,
1708
+ categories.push({
1709
+ ...node,
1871
1710
  level
1872
1711
  });
1873
-
1874
1712
  for (const child of node.children) {
1875
1713
  dfs(child, level + 1);
1876
1714
  }
1877
1715
  };
1878
-
1879
1716
  for (const node of tree) {
1880
1717
  dfs(node, 0);
1881
1718
  }
1882
-
1883
- const collections = [...brands.filter(brand => brand.isActive).map(x => ({ ...x,
1719
+ const collections = [...brands.filter(brand => brand.isActive).map(x => ({
1720
+ ...x,
1884
1721
  type: 'brand'
1885
1722
  })), ...categories];
1886
- const validCollections = collections // Nullable slugs may cause one route to override the other
1723
+ const validCollections = collections
1724
+ // Nullable slugs may cause one route to override the other
1887
1725
  .filter(node => Boolean(StoreCollection.slug(node, null, ctx, null)));
1888
1726
  return {
1889
1727
  pageInfo: {
@@ -1920,7 +1758,8 @@ const Query = {
1920
1758
  postalCode,
1921
1759
  country
1922
1760
  })]);
1923
- return { ...simulation,
1761
+ return {
1762
+ ...simulation,
1924
1763
  address
1925
1764
  };
1926
1765
  }
@@ -1937,15 +1776,14 @@ const StoreReview = {
1937
1776
  };
1938
1777
 
1939
1778
  const isRootFacet = facet => facet.key === 'category-1';
1940
-
1941
1779
  const StoreSearchResult = {
1942
1780
  suggestions: async (searchArgs, _, ctx) => {
1943
1781
  const {
1944
1782
  clients: {
1945
1783
  search
1946
1784
  }
1947
- } = ctx; // If there's no search query, suggest the most popular searches.
1948
-
1785
+ } = ctx;
1786
+ // If there's no search query, suggest the most popular searches.
1949
1787
  if (!searchArgs.query) {
1950
1788
  const topSearches = await search.topSearches();
1951
1789
  return {
@@ -1956,7 +1794,6 @@ const StoreSearchResult = {
1956
1794
  products: []
1957
1795
  };
1958
1796
  }
1959
-
1960
1797
  const terms = await search.suggestedTerms(searchArgs);
1961
1798
  const products = await search.products(searchArgs);
1962
1799
  const skus = products.products.map(product => {
@@ -1981,12 +1818,11 @@ const StoreSearchResult = {
1981
1818
  sp
1982
1819
  }
1983
1820
  } = ctx;
1984
- const products = await search.products(searchArgs); // Raise event on search's analytics API when performing
1821
+ const products = await search.products(searchArgs);
1822
+ // Raise event on search's analytics API when performing
1985
1823
  // a full text search.
1986
-
1987
1824
  if (searchArgs.query) {
1988
1825
  var _products$correction$, _products$correction;
1989
-
1990
1826
  sp.sendEvent({
1991
1827
  type: 'search.query',
1992
1828
  text: searchArgs.query,
@@ -1996,7 +1832,6 @@ const StoreSearchResult = {
1996
1832
  locale: ctx.storage.locale
1997
1833
  }).catch(console.error);
1998
1834
  }
1999
-
2000
1835
  const skus = products.products.map(product => {
2001
1836
  const [maybeSku] = product.items;
2002
1837
  return maybeSku && enhanceSku(maybeSku, product);
@@ -2026,7 +1861,8 @@ const StoreSearchResult = {
2026
1861
  facets = []
2027
1862
  } = await is.facets(searchArgs);
2028
1863
  const isCollectionPage = !searchArgs.query;
2029
- const filteredFacets = facets // Remove root facet on category pages
1864
+ const filteredFacets = facets
1865
+ // Remove root facet on category pages
2030
1866
  .filter(facet => !isCollectionPage || !isRootFacet(facet));
2031
1867
  return filteredFacets;
2032
1868
  }
@@ -2045,10 +1881,8 @@ const StoreSeo = {
2045
1881
  titleTemplate: () => ''
2046
1882
  };
2047
1883
 
2048
- const units = ['bd', 'd', 'h', 'm']; // eslint-disable-next-line @typescript-eslint/no-explicit-any
2049
-
1884
+ const units = ['bd', 'd', 'h', 'm'];
2050
1885
  const isUnit = x => units.includes(x);
2051
-
2052
1886
  const localizedEstimates = {
2053
1887
  bd: {
2054
1888
  0: 'Today',
@@ -2075,25 +1909,20 @@ const localizedEstimates = {
2075
1909
  * Transforms estimate (e.g 3bd) into friendly format (e.g Up to 3 business days)
2076
1910
  * based on https://github.com/vtex-apps/shipping-estimate-translator/blob/13e17055d6353dd3f3f4c31bae77ab049002809b/messages/en.json
2077
1911
  */
2078
-
2079
1912
  const getLocalizedEstimates = estimate => {
2080
1913
  var _localizedEstimates$u;
2081
-
2082
1914
  const [amount, unit] = [estimate.split(/\D+/)[0], estimate.split(/[0-9]+/)[1]];
2083
1915
  const isAmountNumber = amount !== '' && !Number.isNaN(Number(amount));
2084
1916
  const isUnitValid = isUnit(unit);
2085
-
2086
1917
  if (!isAmountNumber || !isUnitValid) {
2087
1918
  return '';
2088
1919
  }
2089
-
2090
1920
  const amountKey = Number(amount) < 2 ? Number(amount) : 'other';
2091
1921
  return (_localizedEstimates$u = localizedEstimates[unit][amountKey].replace('#', amount)) != null ? _localizedEstimates$u : '';
2092
1922
  };
2093
1923
  const ShippingSLA = {
2094
1924
  carrier: root => {
2095
1925
  var _ref, _root$friendlyName;
2096
-
2097
1926
  return (_ref = (_root$friendlyName = root == null ? void 0 : root.friendlyName) != null ? _root$friendlyName : root == null ? void 0 : root.name) != null ? _ref : '';
2098
1927
  },
2099
1928
  price: root => root != null && root.price ? root.price / 100 : root == null ? void 0 : root.price,
@@ -2102,10 +1931,8 @@ const ShippingSLA = {
2102
1931
 
2103
1932
  function findSkuVariantImage(availableImages) {
2104
1933
  var _availableImages$find;
2105
-
2106
1934
  return (_availableImages$find = availableImages.find(imageProperties => imageProperties.imageLabel === 'skuvariation')) != null ? _availableImages$find : availableImages[0];
2107
1935
  }
2108
-
2109
1936
  function createSlugsMap(variants, dominantVariantName, baseSlug) {
2110
1937
  /**
2111
1938
  * Maps property value combinations to their respective SKU's slug. Enables
@@ -2117,23 +1944,18 @@ function createSlugsMap(variants, dominantVariantName, baseSlug) {
2117
1944
  const slugsMap = {};
2118
1945
  variants.forEach(variant => {
2119
1946
  var _skuSpecificationProp, _skuSpecificationProp2;
2120
-
2121
1947
  const skuSpecificationProperties = variant.variations;
2122
-
2123
1948
  if (skuSpecificationProperties.length === 0) {
2124
1949
  return;
2125
- } // Make sure that the 'name-value' pair for the dominant variation
1950
+ }
1951
+ // Make sure that the 'name-value' pair for the dominant variation
2126
1952
  // is always the first one.
2127
-
2128
-
2129
1953
  const dominantNameValue = `${dominantVariantName}-${(_skuSpecificationProp = (_skuSpecificationProp2 = skuSpecificationProperties.find(variationDetails => variationDetails.name === dominantVariantName)) == null ? void 0 : _skuSpecificationProp2.values[0]) != null ? _skuSpecificationProp : ''}`;
2130
1954
  const skuVariantKey = skuSpecificationProperties.reduce((acc, property) => {
2131
1955
  const shouldIgnore = property.name === dominantVariantName;
2132
-
2133
1956
  if (shouldIgnore) {
2134
1957
  return acc;
2135
1958
  }
2136
-
2137
1959
  return acc + `-${property.name}-${property.values[0]}`;
2138
1960
  }, dominantNameValue);
2139
1961
  slugsMap[skuVariantKey] = `${baseSlug}-${variant.itemId}`;
@@ -2151,44 +1973,34 @@ function getVariantsByName(skuSpecifications) {
2151
1973
  const variants = {};
2152
1974
  skuSpecifications == null ? void 0 : skuSpecifications.forEach(specification => {
2153
1975
  var _specification$field$;
2154
-
2155
1976
  variants[(_specification$field$ = specification.field.originalName) != null ? _specification$field$ : specification.field.name] = specification.values.map(value => {
2156
1977
  var _value$originalName;
2157
-
2158
1978
  return (_value$originalName = value.originalName) != null ? _value$originalName : value.name;
2159
1979
  });
2160
1980
  });
2161
1981
  return variants;
2162
1982
  }
2163
-
2164
1983
  function compare(a, b) {
2165
1984
  // Values are always represented as Strings, so we need to handle numbers
2166
1985
  // in this special case.
2167
1986
  if (!Number.isNaN(Number(a) - Number(b))) {
2168
1987
  return Number(a) - Number(b);
2169
1988
  }
2170
-
2171
1989
  if (a < b) {
2172
1990
  return -1;
2173
1991
  }
2174
-
2175
1992
  if (a > b) {
2176
1993
  return 1;
2177
1994
  }
2178
-
2179
1995
  return 0;
2180
1996
  }
2181
-
2182
1997
  function sortVariants(variantsByName) {
2183
1998
  const sortedVariants = variantsByName;
2184
-
2185
1999
  for (const variantProperty in variantsByName) {
2186
2000
  variantsByName[variantProperty].sort((a, b) => compare(a.value, b.value));
2187
2001
  }
2188
-
2189
2002
  return sortedVariants;
2190
2003
  }
2191
-
2192
2004
  function getFormattedVariations(variants, dominantVariantName, dominantVariantValue) {
2193
2005
  /**
2194
2006
  * SKU options already formatted and indexed by their property name.
@@ -2207,20 +2019,15 @@ function getFormattedVariations(variants, dominantVariantName, dominantVariantVa
2207
2019
  if (variant.variations.length === 0) {
2208
2020
  return;
2209
2021
  }
2210
-
2211
2022
  const variantImageToUse = findSkuVariantImage(variant.images);
2212
2023
  const dominantVariantEntry = variant.variations.find(variation => variation.name === dominantVariantName);
2213
2024
  const matchesDominantVariant = (dominantVariantEntry == null ? void 0 : dominantVariantEntry.values[0]) === dominantVariantValue;
2214
-
2215
2025
  if (!matchesDominantVariant) {
2216
2026
  var _variantImageToUse$im;
2217
-
2218
2027
  const nameValueIdentifier = `${dominantVariantName}-${dominantVariantEntry == null ? void 0 : dominantVariantEntry.values[0]}`;
2219
-
2220
2028
  if (!dominantVariantEntry || previouslySeenPropertyValues.has(nameValueIdentifier)) {
2221
2029
  return;
2222
2030
  }
2223
-
2224
2031
  previouslySeenPropertyValues.add(nameValueIdentifier);
2225
2032
  const formattedVariant = {
2226
2033
  src: variantImageToUse.imageUrl,
@@ -2228,25 +2035,19 @@ function getFormattedVariations(variants, dominantVariantName, dominantVariantVa
2228
2035
  label: `${dominantVariantName}: ${dominantVariantEntry.values[0]}`,
2229
2036
  value: dominantVariantEntry.values[0]
2230
2037
  };
2231
-
2232
2038
  if (variantsByName[dominantVariantEntry.name]) {
2233
2039
  variantsByName[dominantVariantEntry.name].push(formattedVariant);
2234
2040
  } else {
2235
2041
  variantsByName[dominantVariantEntry.name] = [formattedVariant];
2236
2042
  }
2237
-
2238
2043
  return;
2239
2044
  }
2240
-
2241
2045
  variant.variations.forEach(variationProperty => {
2242
2046
  var _variantImageToUse$im2;
2243
-
2244
2047
  const nameValueIdentifier = `${variationProperty.name}-${variationProperty.values[0]}`;
2245
-
2246
2048
  if (previouslySeenPropertyValues.has(nameValueIdentifier)) {
2247
2049
  return;
2248
2050
  }
2249
-
2250
2051
  previouslySeenPropertyValues.add(nameValueIdentifier);
2251
2052
  const formattedVariant = {
2252
2053
  src: variantImageToUse.imageUrl,
@@ -2254,7 +2055,6 @@ function getFormattedVariations(variants, dominantVariantName, dominantVariantVa
2254
2055
  label: `${variationProperty.name}: ${variationProperty.values[0]}`,
2255
2056
  value: variationProperty.values[0]
2256
2057
  };
2257
-
2258
2058
  if (variantsByName[variationProperty.name]) {
2259
2059
  variantsByName[variationProperty.name].push(formattedVariant);
2260
2060
  } else {
@@ -2268,7 +2068,8 @@ function getFormattedVariations(variants, dominantVariantName, dominantVariantVa
2268
2068
  const SkuVariants = {
2269
2069
  activeVariations: root => getActiveSkuVariations(root.variations),
2270
2070
  allVariantsByName: root => getVariantsByName(root.isVariantOf.skuSpecifications),
2271
- slugsMap: (root, args) => createSlugsMap(root.isVariantOf.items, // Since `dominantVariantProperty` is a required argument, we can safely
2071
+ slugsMap: (root, args) => createSlugsMap(root.isVariantOf.items,
2072
+ // Since `dominantVariantProperty` is a required argument, we can safely
2272
2073
  // access it.
2273
2074
  args.dominantVariantName, root.isVariantOf.linkText),
2274
2075
  availableVariations: (root, args) => {
@@ -2305,7 +2106,6 @@ const Resolvers = {
2305
2106
  };
2306
2107
  const getContextFactory = options => ctx => {
2307
2108
  var _options$flags;
2308
-
2309
2109
  ctx.storage = {
2310
2110
  channel: ChannelMarshal.parse(options.channel),
2311
2111
  flags: (_options$flags = options.flags) != null ? _options$flags : {},
@@ -2409,35 +2209,27 @@ const stringify$1 = ({
2409
2209
  sMaxAge = 0,
2410
2210
  staleWhileRevalidate = 0
2411
2211
  }) => `${scope}, s-maxage=${sMaxAge}, stale-while-revalidate=${staleWhileRevalidate}`;
2412
-
2413
2212
  const min$1 = (a, b) => {
2414
2213
  if (typeof a === "number" && typeof b === "number") {
2415
2214
  return a > b ? b : a;
2416
2215
  }
2417
-
2418
2216
  if (typeof a === "number") {
2419
2217
  return a;
2420
2218
  }
2421
-
2422
2219
  return b;
2423
2220
  };
2424
-
2425
2221
  const minScope = (a, b) => {
2426
2222
  if (typeof a === "string" && typeof b === "string") {
2427
2223
  return a === "public" && b === "public" ? "public" : "private";
2428
2224
  }
2429
-
2430
2225
  return a || b;
2431
2226
  };
2432
-
2433
2227
  const directive = {
2434
2228
  typeDefs: `directive @cacheControl(sMaxAge: Int, staleWhileRevalidate: Int, scope: String) on FIELD_DEFINITION`,
2435
2229
  transformer: schema => mapSchema(schema, {
2436
2230
  [MapperKind.OBJECT_FIELD]: fieldConfig => {
2437
2231
  var _getDirective;
2438
-
2439
2232
  const cacheControl = (_getDirective = getDirective(schema, fieldConfig, NAME)) == null ? void 0 : _getDirective[0];
2440
-
2441
2233
  if (cacheControl) {
2442
2234
  const {
2443
2235
  sMaxAge,
@@ -2445,10 +2237,8 @@ const directive = {
2445
2237
  scope
2446
2238
  } = cacheControl;
2447
2239
  const resolver = fieldConfig.resolve;
2448
-
2449
2240
  fieldConfig.resolve = (obj, args, ctx, info) => {
2450
2241
  var _ctx$cacheControl, _ctx$cacheControl2, _ctx$cacheControl3;
2451
-
2452
2242
  ctx.cacheControl = {
2453
2243
  sMaxAge: min$1((_ctx$cacheControl = ctx.cacheControl) == null ? void 0 : _ctx$cacheControl.sMaxAge, sMaxAge),
2454
2244
  staleWhileRevalidate: min$1((_ctx$cacheControl2 = ctx.cacheControl) == null ? void 0 : _ctx$cacheControl2.staleWhileRevalidate, staleWhileRevalidate),
@@ -2457,7 +2247,6 @@ const directive = {
2457
2247
  return resolver == null ? void 0 : resolver(obj, args, ctx, info);
2458
2248
  };
2459
2249
  }
2460
-
2461
2250
  return fieldConfig;
2462
2251
  }
2463
2252
  })