@faststore/api 1.7.31 → 1.7.34
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 +27 -0
- package/dist/api.cjs.development.js +313 -181
- package/dist/api.cjs.development.js.map +1 -1
- package/dist/api.cjs.production.min.js +1 -1
- package/dist/api.cjs.production.min.js.map +1 -1
- package/dist/api.esm.js +313 -181
- package/dist/api.esm.js.map +1 -1
- package/dist/index.d.ts +27 -13
- package/dist/platforms/vtex/clients/index.d.ts +4 -1
- package/dist/platforms/vtex/clients/search/index.d.ts +3 -3
- package/dist/platforms/vtex/clients/search/types/AttributeSearchResult.d.ts +25 -51
- package/dist/platforms/vtex/clients/search/types/FacetSearchResult.d.ts +31 -0
- package/dist/platforms/vtex/clients/search/types/ProductSearchResult.d.ts +146 -154
- package/dist/platforms/vtex/clients/sp/index.d.ts +13 -0
- package/dist/platforms/vtex/index.d.ts +28 -14
- package/dist/platforms/vtex/resolvers/aggregateOffer.d.ts +10 -6
- package/dist/platforms/vtex/resolvers/facet.d.ts +2 -2
- package/dist/platforms/vtex/resolvers/facetValue.d.ts +2 -2
- package/dist/platforms/vtex/resolvers/offer.d.ts +7 -6
- package/dist/platforms/vtex/resolvers/product.d.ts +11 -2
- package/dist/platforms/vtex/resolvers/productGroup.d.ts +5 -2
- package/dist/platforms/vtex/utils/enhanceSku.d.ts +3 -3
- package/dist/platforms/vtex/utils/price.d.ts +2 -0
- package/dist/platforms/vtex/utils/productStock.d.ts +5 -0
- package/dist/typings/index.d.ts +2 -0
- package/package.json +2 -2
- package/src/platforms/vtex/clients/fetch.ts +1 -1
- package/src/platforms/vtex/clients/index.ts +3 -0
- package/src/platforms/vtex/clients/search/index.ts +6 -6
- package/src/platforms/vtex/clients/search/types/AttributeSearchResult.ts +24 -53
- package/src/platforms/vtex/clients/search/types/FacetSearchResult.ts +33 -0
- package/src/platforms/vtex/clients/search/types/ProductSearchResult.ts +135 -164
- package/src/platforms/vtex/clients/sp/index.ts +67 -0
- package/src/platforms/vtex/index.ts +2 -2
- package/src/platforms/vtex/loaders/sku.ts +2 -2
- package/src/platforms/vtex/resolvers/aggregateOffer.ts +17 -35
- package/src/platforms/vtex/resolvers/facet.ts +5 -5
- package/src/platforms/vtex/resolvers/facetValue.ts +7 -6
- package/src/platforms/vtex/resolvers/offer.ts +107 -17
- package/src/platforms/vtex/resolvers/product.ts +55 -73
- package/src/platforms/vtex/resolvers/productGroup.ts +22 -13
- package/src/platforms/vtex/resolvers/query.ts +3 -3
- package/src/platforms/vtex/resolvers/searchResult.ts +24 -12
- package/src/platforms/vtex/utils/enhanceSku.ts +4 -4
- package/src/platforms/vtex/utils/facets.ts +8 -2
- package/src/platforms/vtex/utils/price.ts +10 -0
- package/src/platforms/vtex/utils/productStock.ts +25 -0
- package/src/typings/index.ts +4 -0
package/dist/api.esm.js
CHANGED
|
@@ -9,7 +9,7 @@ const fetchAPI = async (info, init) => {
|
|
|
9
9
|
const response = await fetch(info, init);
|
|
10
10
|
|
|
11
11
|
if (response.ok) {
|
|
12
|
-
return response.json();
|
|
12
|
+
return response.status !== 204 ? response.json() : undefined;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
console.error(info, init, response);
|
|
@@ -106,7 +106,7 @@ const IntelligentSearch = ({
|
|
|
106
106
|
environment,
|
|
107
107
|
hideUnavailableItems
|
|
108
108
|
}, ctx) => {
|
|
109
|
-
const base = `
|
|
109
|
+
const base = `https://${account}.${environment}.com.br/api/io`;
|
|
110
110
|
const policyFacet = {
|
|
111
111
|
key: 'trade-policy',
|
|
112
112
|
value: ctx.storage.channel.salesChannel
|
|
@@ -142,14 +142,14 @@ const IntelligentSearch = ({
|
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
if (hideUnavailableItems !== undefined) {
|
|
145
|
-
params.append('
|
|
145
|
+
params.append('hideUnavailableItems', hideUnavailableItems.toString());
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
const pathname = addDefaultFacets(selectedFacets).map(({
|
|
149
149
|
key,
|
|
150
150
|
value
|
|
151
151
|
}) => `${key}/${value}`).join('/');
|
|
152
|
-
return fetchAPI(`${base}/api/
|
|
152
|
+
return fetchAPI(`${base}/_v/api/intelligent-search/${type}/${pathname}?${params.toString()}`);
|
|
153
153
|
};
|
|
154
154
|
|
|
155
155
|
const products = args => search({ ...args,
|
|
@@ -157,7 +157,7 @@ const IntelligentSearch = ({
|
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
const facets = args => search({ ...args,
|
|
160
|
-
type: '
|
|
160
|
+
type: 'facets'
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
return {
|
|
@@ -166,12 +166,66 @@ const IntelligentSearch = ({
|
|
|
166
166
|
};
|
|
167
167
|
};
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Client for SP, Intelligent search's analytics event API
|
|
171
|
+
* More info at: https://www.notion.so/vtexhandbook/Event-API-Documentation-48eee26730cf4d7f80f8fd7262231f84
|
|
172
|
+
*/
|
|
173
|
+
const THIRTY_MINUTES_S = 30 * 60;
|
|
174
|
+
const ONE_YEAR_S = 365 * 24 * 3600;
|
|
175
|
+
|
|
176
|
+
const randomUUID = () => (Math.random() * 1e6).toFixed(0);
|
|
177
|
+
|
|
178
|
+
const timelapsed = past => (Date.now() - past) / 1e3;
|
|
179
|
+
|
|
180
|
+
const createId = expiresSecond => {
|
|
181
|
+
let payload = randomUUID();
|
|
182
|
+
let createdAt = Date.now();
|
|
183
|
+
return () => {
|
|
184
|
+
if (timelapsed(createdAt) > expiresSecond) {
|
|
185
|
+
payload = randomUUID();
|
|
186
|
+
createdAt = Date.now();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return payload;
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const user = {
|
|
194
|
+
anonymous: /*#__PURE__*/createId(ONE_YEAR_S),
|
|
195
|
+
session: /*#__PURE__*/createId(THIRTY_MINUTES_S)
|
|
196
|
+
};
|
|
197
|
+
const SP = ({
|
|
198
|
+
account
|
|
199
|
+
}, _) => {
|
|
200
|
+
const base = `https://sp.vtex.com/event-api/v1/${account}/event`;
|
|
201
|
+
|
|
202
|
+
const sendEvent = options => {
|
|
203
|
+
return fetchAPI(base, {
|
|
204
|
+
method: 'POST',
|
|
205
|
+
body: JSON.stringify({ ...options,
|
|
206
|
+
agent: '@faststore/api',
|
|
207
|
+
anonymous: user.anonymous(),
|
|
208
|
+
session: user.session()
|
|
209
|
+
}),
|
|
210
|
+
headers: {
|
|
211
|
+
'content-type': 'application/json'
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
sendEvent
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
|
|
169
221
|
const getClients = (options, ctx) => {
|
|
170
222
|
const search = IntelligentSearch(options, ctx);
|
|
171
223
|
const commerce = VtexCommerce(options, ctx);
|
|
224
|
+
const sp = SP(options);
|
|
172
225
|
return {
|
|
173
226
|
search,
|
|
174
|
-
commerce
|
|
227
|
+
commerce,
|
|
228
|
+
sp
|
|
175
229
|
};
|
|
176
230
|
};
|
|
177
231
|
|
|
@@ -223,7 +277,7 @@ class NotFoundError extends Error {
|
|
|
223
277
|
|
|
224
278
|
}
|
|
225
279
|
|
|
226
|
-
const enhanceSku = (
|
|
280
|
+
const enhanceSku = (item, product) => ({ ...item,
|
|
227
281
|
isVariantOf: product
|
|
228
282
|
});
|
|
229
283
|
|
|
@@ -248,8 +302,8 @@ const getSkuLoader = (_, clients) => {
|
|
|
248
302
|
count: skuIds.length
|
|
249
303
|
});
|
|
250
304
|
const skuBySkuId = products.reduce((acc, product) => {
|
|
251
|
-
for (const sku of product.
|
|
252
|
-
acc[sku.
|
|
305
|
+
for (const sku of product.items) {
|
|
306
|
+
acc[sku.itemId] = enhanceSku(sku, product);
|
|
253
307
|
}
|
|
254
308
|
|
|
255
309
|
return acc;
|
|
@@ -306,38 +360,18 @@ const getLoaders = (options, {
|
|
|
306
360
|
};
|
|
307
361
|
};
|
|
308
362
|
|
|
309
|
-
const inStock = item => item.availability === 'available'; // Smallest Available Selling Price First
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const sortOfferByPrice = items => items.sort((a, b) => {
|
|
313
|
-
if (inStock(a) && !inStock(b)) {
|
|
314
|
-
return -1;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
if (!inStock(a) && inStock(b)) {
|
|
318
|
-
return 1;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
return a.sellingPrice - b.sellingPrice;
|
|
322
|
-
});
|
|
323
363
|
const StoreAggregateOffer = {
|
|
324
364
|
highPrice: ({
|
|
325
|
-
|
|
365
|
+
product
|
|
326
366
|
}) => {
|
|
327
|
-
var
|
|
367
|
+
var _product$isVariantOf$;
|
|
328
368
|
|
|
329
|
-
|
|
330
|
-
const highPrice = (_availableItems$pop = availableItems.pop()) == null ? void 0 : _availableItems$pop.sellingPrice;
|
|
331
|
-
return (highPrice != null ? highPrice : 0) / 1e2;
|
|
369
|
+
return (_product$isVariantOf$ = product.isVariantOf.priceRange.sellingPrice.highPrice) != null ? _product$isVariantOf$ : 0;
|
|
332
370
|
},
|
|
333
|
-
lowPrice:
|
|
334
|
-
|
|
335
|
-
}) => {
|
|
336
|
-
var _availableItems$;
|
|
371
|
+
lowPrice: root => {
|
|
372
|
+
var _root$product$isVaria;
|
|
337
373
|
|
|
338
|
-
|
|
339
|
-
const lowPrice = (_availableItems$ = availableItems[0]) == null ? void 0 : _availableItems$.sellingPrice;
|
|
340
|
-
return (lowPrice != null ? lowPrice : 0) / 1e2;
|
|
374
|
+
return (_root$product$isVaria = root.product.isVariantOf.priceRange.sellingPrice.lowPrice) != null ? _root$product$isVaria : 0;
|
|
341
375
|
},
|
|
342
376
|
offerCount: ({
|
|
343
377
|
items
|
|
@@ -475,33 +509,36 @@ const StoreCollection = {
|
|
|
475
509
|
const StoreFacet = {
|
|
476
510
|
key: ({
|
|
477
511
|
key
|
|
478
|
-
}) => key,
|
|
512
|
+
}) => key != null ? key : '',
|
|
479
513
|
label: ({
|
|
480
|
-
|
|
481
|
-
}) =>
|
|
514
|
+
name
|
|
515
|
+
}) => name != null ? name : 'unknown',
|
|
482
516
|
values: ({
|
|
483
517
|
values
|
|
484
518
|
}) => values,
|
|
485
519
|
type: ({
|
|
486
520
|
type
|
|
487
|
-
}) => type === '
|
|
521
|
+
}) => type === 'TEXT' ? 'BOOLEAN' : 'RANGE'
|
|
488
522
|
};
|
|
489
523
|
|
|
490
524
|
const StoreFacetValue = {
|
|
491
525
|
value: ({
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
526
|
+
value,
|
|
527
|
+
range
|
|
528
|
+
}) => {
|
|
529
|
+
var _range$from, _range$to;
|
|
530
|
+
|
|
531
|
+
return value != null ? value : `${(_range$from = range == null ? void 0 : range.from) != null ? _range$from : ''}-to-${(_range$to = range == null ? void 0 : range.to) != null ? _range$to : ''}`;
|
|
532
|
+
},
|
|
496
533
|
label: ({
|
|
497
|
-
|
|
498
|
-
}) =>
|
|
534
|
+
name
|
|
535
|
+
}) => name || 'unknown',
|
|
499
536
|
selected: ({
|
|
500
|
-
|
|
501
|
-
}) =>
|
|
537
|
+
selected
|
|
538
|
+
}) => selected,
|
|
502
539
|
quantity: ({
|
|
503
|
-
|
|
504
|
-
}) =>
|
|
540
|
+
quantity
|
|
541
|
+
}) => quantity
|
|
505
542
|
};
|
|
506
543
|
|
|
507
544
|
const getId = item => [item.itemOffered.sku, item.seller.identifier, item.price].join('::');
|
|
@@ -704,40 +741,132 @@ const Mutation = {
|
|
|
704
741
|
updateSession
|
|
705
742
|
};
|
|
706
743
|
|
|
744
|
+
const getItemPriceByKey = (item, key) => {
|
|
745
|
+
var _getFirstSeller$comme, _getFirstSeller;
|
|
746
|
+
|
|
747
|
+
return (_getFirstSeller$comme = (_getFirstSeller = getFirstSeller(item.sellers)) == null ? void 0 : _getFirstSeller.commertialOffer[key]) != null ? _getFirstSeller$comme : 0;
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
const inStock = item => item.sellers.find(seller => seller.commertialOffer.AvailableQuantity > 0);
|
|
751
|
+
const getFirstSeller = sellers => sellers[0]; // Smallest Available Selling Price First
|
|
752
|
+
|
|
753
|
+
const sortOfferByPrice = items => items.sort((a, b) => {
|
|
754
|
+
if (inStock(a) && !inStock(b)) {
|
|
755
|
+
return -1;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
if (!inStock(a) && inStock(b)) {
|
|
759
|
+
return 1;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
return getItemPriceByKey(a, 'Price') - getItemPriceByKey(b, 'Price');
|
|
763
|
+
});
|
|
764
|
+
const inStockOrderFormItem = availability => availability === 'available';
|
|
765
|
+
|
|
766
|
+
const isSearchItem = item => 'sellers' in item;
|
|
767
|
+
|
|
768
|
+
const isOrderFormItem = item => 'skuName' in item;
|
|
769
|
+
|
|
770
|
+
const getAvailability = available => available ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock';
|
|
771
|
+
|
|
707
772
|
const StoreOffer = {
|
|
708
773
|
priceCurrency: () => '',
|
|
709
|
-
priceValidUntil:
|
|
710
|
-
|
|
711
|
-
|
|
774
|
+
priceValidUntil: item => {
|
|
775
|
+
if (isSearchItem(item)) {
|
|
776
|
+
var _getFirstSeller$comme, _getFirstSeller;
|
|
777
|
+
|
|
778
|
+
return (_getFirstSeller$comme = (_getFirstSeller = getFirstSeller(item.sellers)) == null ? void 0 : _getFirstSeller.commertialOffer.PriceValidUntil) != null ? _getFirstSeller$comme : '';
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
if (isOrderFormItem(item)) {
|
|
782
|
+
var _item$priceValidUntil;
|
|
783
|
+
|
|
784
|
+
return (_item$priceValidUntil = item.priceValidUntil) != null ? _item$priceValidUntil : '';
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
return null;
|
|
788
|
+
},
|
|
712
789
|
itemCondition: () => 'https://schema.org/NewCondition',
|
|
713
|
-
availability:
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
790
|
+
availability: async item => {
|
|
791
|
+
if (isSearchItem(item)) {
|
|
792
|
+
return getAvailability(!!inStock(item));
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (isOrderFormItem(item)) {
|
|
796
|
+
return getAvailability(inStockOrderFormItem(item.availability));
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
return null;
|
|
800
|
+
},
|
|
801
|
+
seller: item => {
|
|
802
|
+
if (isSearchItem(item)) {
|
|
803
|
+
var _getFirstSeller$selle, _getFirstSeller2;
|
|
804
|
+
|
|
805
|
+
return {
|
|
806
|
+
identifier: (_getFirstSeller$selle = (_getFirstSeller2 = getFirstSeller(item.sellers)) == null ? void 0 : _getFirstSeller2.sellerId) != null ? _getFirstSeller$selle : ''
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
if (isOrderFormItem(item)) {
|
|
811
|
+
return {
|
|
812
|
+
identifier: item.seller
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return null;
|
|
817
|
+
},
|
|
818
|
+
price: item => {
|
|
819
|
+
if (isSearchItem(item)) {
|
|
820
|
+
return getItemPriceByKey(item, 'spotPrice');
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
if (isOrderFormItem(item)) {
|
|
824
|
+
return item.price / 1e2;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
return null;
|
|
828
|
+
},
|
|
829
|
+
sellingPrice: item => {
|
|
830
|
+
if (isSearchItem(item)) {
|
|
831
|
+
return getItemPriceByKey(item, 'Price');
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if (isOrderFormItem(item)) {
|
|
835
|
+
return item.sellingPrice / 1e2;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
return null;
|
|
839
|
+
},
|
|
840
|
+
listPrice: item => {
|
|
841
|
+
if (isSearchItem(item)) {
|
|
842
|
+
return getItemPriceByKey(item, 'ListPrice');
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
if (isOrderFormItem(item)) {
|
|
846
|
+
return item.listPrice / 1e2;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
return null;
|
|
850
|
+
},
|
|
730
851
|
itemOffered: ({
|
|
731
852
|
product
|
|
732
853
|
}) => product,
|
|
733
|
-
quantity:
|
|
734
|
-
|
|
735
|
-
|
|
854
|
+
quantity: item => {
|
|
855
|
+
if (isSearchItem(item)) {
|
|
856
|
+
return item.sellers.reduce((quantity, seller) => quantity + seller.commertialOffer.AvailableQuantity, 0);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
if (isOrderFormItem(item)) {
|
|
860
|
+
return item.quantity;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
return null;
|
|
864
|
+
}
|
|
736
865
|
};
|
|
737
866
|
|
|
738
867
|
const DEFAULT_IMAGE = {
|
|
739
|
-
|
|
740
|
-
|
|
868
|
+
imageText: 'image',
|
|
869
|
+
imageUrl: 'https://storecomponents.vtexassets.com/assets/faststore/images/image___117a6d3e229a96ad0e0d0876352566e2.svg'
|
|
741
870
|
};
|
|
742
871
|
|
|
743
872
|
const getSlug = (link, id) => `${link}-${id}`;
|
|
@@ -748,18 +877,18 @@ const nonEmptyArray = array => Array.isArray(array) && array.length > 0 ? array
|
|
|
748
877
|
|
|
749
878
|
const StoreProduct = {
|
|
750
879
|
productID: ({
|
|
751
|
-
|
|
752
|
-
}) =>
|
|
880
|
+
itemId
|
|
881
|
+
}) => itemId,
|
|
753
882
|
name: ({
|
|
754
883
|
isVariantOf,
|
|
755
884
|
name
|
|
756
|
-
}) => name != null ? name : isVariantOf.
|
|
885
|
+
}) => name != null ? name : isVariantOf.productName,
|
|
757
886
|
slug: ({
|
|
758
887
|
isVariantOf: {
|
|
759
|
-
|
|
888
|
+
linkText
|
|
760
889
|
},
|
|
761
|
-
|
|
762
|
-
}) => getSlug(
|
|
890
|
+
itemId
|
|
891
|
+
}) => getSlug(linkText, itemId),
|
|
763
892
|
description: ({
|
|
764
893
|
isVariantOf: {
|
|
765
894
|
description
|
|
@@ -767,11 +896,11 @@ const StoreProduct = {
|
|
|
767
896
|
}) => description,
|
|
768
897
|
seo: ({
|
|
769
898
|
isVariantOf: {
|
|
770
|
-
|
|
771
|
-
|
|
899
|
+
description,
|
|
900
|
+
productName
|
|
772
901
|
}
|
|
773
902
|
}) => ({
|
|
774
|
-
title:
|
|
903
|
+
title: productName,
|
|
775
904
|
description
|
|
776
905
|
}),
|
|
777
906
|
brand: ({
|
|
@@ -783,86 +912,61 @@ const StoreProduct = {
|
|
|
783
912
|
}),
|
|
784
913
|
breadcrumbList: ({
|
|
785
914
|
isVariantOf: {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
915
|
+
categories,
|
|
916
|
+
productName,
|
|
917
|
+
linkText
|
|
789
918
|
},
|
|
790
|
-
|
|
791
|
-
}) =>
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
919
|
+
itemId
|
|
920
|
+
}) => {
|
|
921
|
+
return {
|
|
922
|
+
itemListElement: [...categories.reverse().map((categoryPath, index) => {
|
|
923
|
+
const categoryNames = categoryPath.split('/');
|
|
924
|
+
return {
|
|
925
|
+
name: categoryNames[categoryNames.length - 2],
|
|
926
|
+
item: categoryPath.toLowerCase(),
|
|
927
|
+
position: index + 1
|
|
928
|
+
};
|
|
929
|
+
}), {
|
|
930
|
+
name: productName,
|
|
931
|
+
item: getPath(linkText, itemId),
|
|
932
|
+
position: categories.length + 1
|
|
933
|
+
}],
|
|
934
|
+
numberOfItems: categories.length
|
|
935
|
+
};
|
|
936
|
+
},
|
|
805
937
|
image: ({
|
|
806
|
-
isVariantOf,
|
|
807
938
|
images
|
|
808
939
|
}) => {
|
|
809
|
-
var
|
|
940
|
+
var _nonEmptyArray;
|
|
810
941
|
|
|
811
|
-
return ((
|
|
812
|
-
|
|
813
|
-
|
|
942
|
+
return ((_nonEmptyArray = nonEmptyArray(images)) != null ? _nonEmptyArray : [DEFAULT_IMAGE]).map(({
|
|
943
|
+
imageUrl,
|
|
944
|
+
imageText
|
|
814
945
|
}) => ({
|
|
815
|
-
alternateName:
|
|
816
|
-
url:
|
|
946
|
+
alternateName: imageText != null ? imageText : '',
|
|
947
|
+
url: imageUrl.replace('vteximg.com.br', 'vtexassets.com')
|
|
817
948
|
}));
|
|
818
949
|
},
|
|
819
950
|
sku: ({
|
|
820
|
-
|
|
821
|
-
}) =>
|
|
951
|
+
itemId
|
|
952
|
+
}) => itemId,
|
|
822
953
|
gtin: ({
|
|
823
|
-
|
|
824
|
-
}) =>
|
|
954
|
+
referenceId
|
|
955
|
+
}) => {
|
|
956
|
+
var _referenceId$0$Value, _referenceId$;
|
|
957
|
+
|
|
958
|
+
return (_referenceId$0$Value = (_referenceId$ = referenceId[0]) == null ? void 0 : _referenceId$.Value) != null ? _referenceId$0$Value : '';
|
|
959
|
+
},
|
|
825
960
|
review: () => [],
|
|
826
961
|
aggregateRating: () => ({}),
|
|
827
|
-
offers:
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
const {
|
|
831
|
-
loaders: {
|
|
832
|
-
simulationLoader
|
|
833
|
-
},
|
|
834
|
-
storage: {
|
|
835
|
-
channel
|
|
836
|
-
}
|
|
837
|
-
} = ctx;
|
|
838
|
-
const {
|
|
839
|
-
id,
|
|
840
|
-
policies
|
|
841
|
-
} = product;
|
|
842
|
-
const sellers = (_policies$find = policies.find(policy => policy.id === channel.salesChannel)) == null ? void 0 : _policies$find.sellers;
|
|
843
|
-
|
|
844
|
-
if (sellers === null || sellers === undefined) {
|
|
845
|
-
// This error will likely happen when you forget to forward the channel somewhere in your code.
|
|
846
|
-
// Make sure all queries that lead to a product are forwarding the channel in context corectly
|
|
847
|
-
throw new Error(`Product with id ${id} has no sellers for sales channel ${channel.salesChannel}.`);
|
|
848
|
-
} // Unique seller ids
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const sellerIds = sellers.map(seller => seller.id);
|
|
852
|
-
const items = Array.from(new Set(sellerIds)).map(seller => ({
|
|
853
|
-
quantity: 1,
|
|
854
|
-
seller,
|
|
855
|
-
id
|
|
856
|
-
}));
|
|
857
|
-
const simulation = await simulationLoader.load(items);
|
|
858
|
-
return { ...simulation,
|
|
859
|
-
items: sortOfferByPrice(simulation.items),
|
|
962
|
+
offers: product => {
|
|
963
|
+
return {
|
|
964
|
+
items: sortOfferByPrice(product.isVariantOf.items),
|
|
860
965
|
product
|
|
861
966
|
};
|
|
862
967
|
},
|
|
863
|
-
isVariantOf:
|
|
864
|
-
|
|
865
|
-
}) => isVariantOf,
|
|
968
|
+
isVariantOf: root => root,
|
|
969
|
+
// TODO: get this value. Fix any type
|
|
866
970
|
additionalProperty: ({
|
|
867
971
|
attributes = []
|
|
868
972
|
}) => attributes.map(attribute => ({
|
|
@@ -871,24 +975,31 @@ const StoreProduct = {
|
|
|
871
975
|
}))
|
|
872
976
|
};
|
|
873
977
|
|
|
978
|
+
const BLOCKED_PROPERTIES = {
|
|
979
|
+
sellerId: true
|
|
980
|
+
};
|
|
874
981
|
const StoreProductGroup = {
|
|
875
|
-
hasVariant: root => root.
|
|
982
|
+
hasVariant: root => root.isVariantOf.items.map(item => enhanceSku(item, root.isVariantOf)),
|
|
876
983
|
productGroupID: ({
|
|
877
|
-
|
|
878
|
-
}) =>
|
|
984
|
+
isVariantOf
|
|
985
|
+
}) => isVariantOf.productId,
|
|
879
986
|
name: ({
|
|
880
|
-
|
|
881
|
-
}) =>
|
|
987
|
+
isVariantOf
|
|
988
|
+
}) => isVariantOf.productName,
|
|
882
989
|
additionalProperty: ({
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
990
|
+
isVariantOf: {
|
|
991
|
+
properties
|
|
992
|
+
}
|
|
993
|
+
}) => properties.flatMap(property => {
|
|
994
|
+
if (BLOCKED_PROPERTIES[property.name]) {
|
|
995
|
+
return [];
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
return property.values.map(propertyValue => ({
|
|
999
|
+
name: property.name,
|
|
1000
|
+
value: propertyValue
|
|
890
1001
|
}));
|
|
891
|
-
}
|
|
1002
|
+
})
|
|
892
1003
|
};
|
|
893
1004
|
|
|
894
1005
|
/**
|
|
@@ -903,12 +1014,20 @@ const transformSelectedFacet = ({
|
|
|
903
1014
|
switch (key) {
|
|
904
1015
|
case 'channel':
|
|
905
1016
|
{
|
|
906
|
-
const channel = ChannelMarshal.parse(value);
|
|
907
|
-
|
|
908
|
-
return [{
|
|
1017
|
+
const channel = ChannelMarshal.parse(value);
|
|
1018
|
+
const channelFacets = [{
|
|
909
1019
|
key: 'trade-policy',
|
|
910
1020
|
value: channel.salesChannel
|
|
911
1021
|
}];
|
|
1022
|
+
|
|
1023
|
+
if (channel.regionId) {
|
|
1024
|
+
channelFacets.push({
|
|
1025
|
+
key: 'region-id',
|
|
1026
|
+
value: channel.regionId
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
return channelFacets;
|
|
912
1031
|
}
|
|
913
1032
|
|
|
914
1033
|
default:
|
|
@@ -1000,14 +1119,14 @@ const Query = {
|
|
|
1000
1119
|
page: Math.ceil(after / first),
|
|
1001
1120
|
count: first
|
|
1002
1121
|
});
|
|
1003
|
-
const skus = products.products.map(product => product.
|
|
1122
|
+
const skus = products.products.map(product => product.items.map(sku => enhanceSku(sku, product))).flat().filter(sku => sku.sellers.length > 0);
|
|
1004
1123
|
return {
|
|
1005
1124
|
pageInfo: {
|
|
1006
1125
|
hasNextPage: products.pagination.after.length > 0,
|
|
1007
1126
|
hasPreviousPage: products.pagination.before.length > 0,
|
|
1008
1127
|
startCursor: '0',
|
|
1009
|
-
endCursor: products.
|
|
1010
|
-
totalCount: products.
|
|
1128
|
+
endCursor: products.recordsFiltered.toString(),
|
|
1129
|
+
totalCount: products.recordsFiltered
|
|
1011
1130
|
},
|
|
1012
1131
|
// after + index is bigger than after+first itself because of the array flat() above
|
|
1013
1132
|
edges: skus.map((sku, index) => ({
|
|
@@ -1094,17 +1213,30 @@ const StoreReview = {
|
|
|
1094
1213
|
})
|
|
1095
1214
|
};
|
|
1096
1215
|
|
|
1097
|
-
const REMOVED_FACETS_FROM_COLLECTION_PAGE = ['departamento'];
|
|
1216
|
+
const REMOVED_FACETS_FROM_COLLECTION_PAGE = ['departamento', 'Departamento'];
|
|
1098
1217
|
const StoreSearchResult = {
|
|
1099
1218
|
products: async (searchArgs, _, ctx) => {
|
|
1100
1219
|
const {
|
|
1101
1220
|
clients: {
|
|
1102
|
-
search
|
|
1221
|
+
search,
|
|
1222
|
+
sp
|
|
1103
1223
|
}
|
|
1104
1224
|
} = ctx;
|
|
1105
|
-
const products = await search.products(searchArgs);
|
|
1225
|
+
const products = await search.products(searchArgs); // Raise event on search's analytics API when performing
|
|
1226
|
+
// a full text search.
|
|
1227
|
+
|
|
1228
|
+
if (searchArgs.query) {
|
|
1229
|
+
sp.sendEvent({
|
|
1230
|
+
type: 'search.query',
|
|
1231
|
+
text: searchArgs.query,
|
|
1232
|
+
misspelled: products.correction.misspelled,
|
|
1233
|
+
match: products.recordsFiltered,
|
|
1234
|
+
operator: products.operator
|
|
1235
|
+
}).catch(console.error);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1106
1238
|
const skus = products.products.map(product => {
|
|
1107
|
-
const [maybeSku] = product.
|
|
1239
|
+
const [maybeSku] = product.items;
|
|
1108
1240
|
return maybeSku && enhanceSku(maybeSku, product);
|
|
1109
1241
|
}).filter(sku => !!sku);
|
|
1110
1242
|
return {
|
|
@@ -1112,8 +1244,8 @@ const StoreSearchResult = {
|
|
|
1112
1244
|
hasNextPage: products.pagination.after.length > 0,
|
|
1113
1245
|
hasPreviousPage: products.pagination.before.length > 0,
|
|
1114
1246
|
startCursor: '0',
|
|
1115
|
-
endCursor: products.
|
|
1116
|
-
totalCount: products.
|
|
1247
|
+
endCursor: products.recordsFiltered.toString(),
|
|
1248
|
+
totalCount: products.recordsFiltered
|
|
1117
1249
|
},
|
|
1118
1250
|
edges: skus.map((sku, index) => ({
|
|
1119
1251
|
node: sku,
|
|
@@ -1122,17 +1254,17 @@ const StoreSearchResult = {
|
|
|
1122
1254
|
};
|
|
1123
1255
|
},
|
|
1124
1256
|
facets: async (searchArgs, _, ctx) => {
|
|
1125
|
-
var _facets$attributes;
|
|
1126
|
-
|
|
1127
1257
|
const {
|
|
1128
1258
|
clients: {
|
|
1129
1259
|
search: is
|
|
1130
1260
|
}
|
|
1131
1261
|
} = ctx;
|
|
1132
|
-
const
|
|
1262
|
+
const {
|
|
1263
|
+
facets
|
|
1264
|
+
} = await is.facets(searchArgs);
|
|
1133
1265
|
const isCollectionPage = !searchArgs.query;
|
|
1134
|
-
const filteredFacets = facets == null ? void 0 :
|
|
1135
|
-
const shouldFilterFacet = REMOVED_FACETS_FROM_COLLECTION_PAGE.includes(currentFacet.
|
|
1266
|
+
const filteredFacets = facets == null ? void 0 : facets.reduce((acc, currentFacet) => {
|
|
1267
|
+
const shouldFilterFacet = REMOVED_FACETS_FROM_COLLECTION_PAGE.includes(currentFacet.name);
|
|
1136
1268
|
const shouldRemoveFacetFromCollectionPage = isCollectionPage && shouldFilterFacet;
|
|
1137
1269
|
|
|
1138
1270
|
if (shouldRemoveFacetFromCollectionPage) {
|
|
@@ -1140,10 +1272,10 @@ const StoreSearchResult = {
|
|
|
1140
1272
|
}
|
|
1141
1273
|
|
|
1142
1274
|
currentFacet.values.sort((a, b) => {
|
|
1143
|
-
var _a$
|
|
1275
|
+
var _a$name, _b$name;
|
|
1144
1276
|
|
|
1145
|
-
const firstItemLabel = (_a$
|
|
1146
|
-
const secondItemLabel = (_b$
|
|
1277
|
+
const firstItemLabel = (_a$name = a.name) != null ? _a$name : '';
|
|
1278
|
+
const secondItemLabel = (_b$name = b.name) != null ? _b$name : '';
|
|
1147
1279
|
return firstItemLabel.localeCompare(secondItemLabel);
|
|
1148
1280
|
});
|
|
1149
1281
|
acc.push(currentFacet);
|