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