@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/CHANGELOG.md +32 -0
- package/dist/api.cjs.development.js +99 -310
- package/dist/api.cjs.development.js.map +1 -1
- package/dist/api.cjs.production.min.js.map +1 -1
- package/dist/api.esm.js +99 -310
- package/dist/api.esm.js.map +1 -1
- package/package.json +5 -3
- package/src/platforms/vtex/resolvers/shippingSLA.ts +0 -1
- package/src/platforms/vtex/utils/slugify.ts +0 -1
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()}`, {
|
|
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`, {
|
|
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}`, {
|
|
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}`, {
|
|
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/`, {
|
|
151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
-
});
|
|
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) => ({
|
|
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) => ({
|
|
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';
|
|
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) => ({
|
|
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 {
|
|
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 {
|
|
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 => ({
|
|
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
|
-
};
|
|
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
|
-
});
|
|
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;
|
|
1177
|
-
|
|
1178
|
-
const orderForm = await getOrderForm(orderNumber, session, ctx);
|
|
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
|
-
}
|
|
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);
|
|
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
|
-
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1104
|
+
}
|
|
1105
|
+
// Update existing items
|
|
1211
1106
|
const [head, ...tail] = maybeOriginItem;
|
|
1212
|
-
const totalQuantity = items.reduce((acc, curr) => acc + curr.quantity, 0);
|
|
1213
|
-
|
|
1214
|
-
acc.itemsToUpdate.push({
|
|
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
|
-
});
|
|
1217
|
-
|
|
1218
|
-
tail.forEach(item => acc.itemsToUpdate.push({
|
|
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 => ({
|
|
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
|
-
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
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
|
-
})
|
|
1241
|
-
|
|
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
|
-
}
|
|
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 = {
|
|
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 {
|
|
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
|
-
}) => ({
|
|
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
|
|
1623
|
-
|
|
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({
|
|
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
|
-
|
|
1719
|
+
const collections = [...brands.filter(brand => brand.isActive).map(x => ({
|
|
1720
|
+
...x,
|
|
1884
1721
|
type: 'brand'
|
|
1885
1722
|
})), ...categories];
|
|
1886
|
-
const validCollections = collections
|
|
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 {
|
|
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;
|
|
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);
|
|
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
|
|
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'];
|
|
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
|
-
}
|
|
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,
|
|
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
|
})
|