@nuskin/ns-product-lib 2.6.1-cx24-3608.4 → 2.6.1-cx24-3607.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +3 -25
- package/package.json +1 -1
- package/src/equinox-helpers/childSkus.js +25 -0
- package/src/equinox-helpers/index.js +39 -4
- package/src/productData.js +130 -146
package/CHANGELOG.md
CHANGED
@@ -1,32 +1,10 @@
|
|
1
|
-
## [2.6.1-cx24-
|
1
|
+
## [2.6.1-cx24-3607.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.0...v2.6.1-cx24-3607.1) (2023-03-15)
|
2
2
|
|
3
3
|
|
4
4
|
### Fix
|
5
5
|
|
6
|
-
*
|
7
|
-
*
|
8
|
-
|
9
|
-
## [2.6.1-cx24-3608.3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-3608.2...v2.6.1-cx24-3608.3) (2023-03-15)
|
10
|
-
|
11
|
-
|
12
|
-
### Fix
|
13
|
-
|
14
|
-
* imageURL issue when product is kit ([0e4281d](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/0e4281de4435d1a5749ff9b6d52a7c4a45d75d6d))
|
15
|
-
|
16
|
-
## [2.6.1-cx24-3608.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-3608.1...v2.6.1-cx24-3608.2) (2023-03-15)
|
17
|
-
|
18
|
-
|
19
|
-
### Fix
|
20
|
-
|
21
|
-
* imageURL issue when product is kit ([3172244](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/3172244e53c328e90d663a0989c25c25eba967d3))
|
22
|
-
|
23
|
-
## [2.6.1-cx24-3608.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.0...v2.6.1-cx24-3608.1) (2023-03-15)
|
24
|
-
|
25
|
-
|
26
|
-
### Fix
|
27
|
-
|
28
|
-
* imageURL issue when product is kit ([2a68af6](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/2a68af668a2ca0835a4b0d0995117ea8ab019bed))
|
29
|
-
* imageURL issue when product is kit ([656505a](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/656505a32421ae4e5d8e29dd451b68b24e72f30d))
|
6
|
+
* (equinox-enabled) skip product mapping when an error occurs in PLP #CX24-3607 ([950c165](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/950c1650115f92badc5b898b5df722568b034afe)), closes [#CX24-3607](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3607)
|
7
|
+
* Cannot read properties of undefined (reading 'qty') in PLP #CX24-3607 ([8cde88f](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/8cde88f2f61279d20794a0e43696187c4326ca28)), closes [#CX24-3607](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3607)
|
30
8
|
|
31
9
|
# [2.6.0](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.5.2...v2.6.0) (2023-03-13)
|
32
10
|
|
package/package.json
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
/**
|
2
|
+
* childSkus creates an array of object that contains
|
3
|
+
* the list of SKUs of a kit.
|
4
|
+
*
|
5
|
+
* @param {import('./').KitSKUQuantity[]} kits
|
6
|
+
* @param {import('./').EquinoxProduct} product
|
7
|
+
*/
|
8
|
+
function childSkus(kits, product) {
|
9
|
+
const sku = product.sku[0];
|
10
|
+
const kit = kits.filter(k => k.sku === sku.identifier)[0];
|
11
|
+
|
12
|
+
return {
|
13
|
+
productId: product.identifier,
|
14
|
+
skuId: sku.identifier,
|
15
|
+
type: 'MANDATORY',
|
16
|
+
skuQuantity: kit.qty,
|
17
|
+
availableChannels: sku.properties.availableChannels,
|
18
|
+
inventory: {
|
19
|
+
atpQty: sku.inventoryProperties.atpQty,
|
20
|
+
backOrdered: sku.inventoryProperties.backOrdered
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
module.exports = childSkus;
|
@@ -1,10 +1,11 @@
|
|
1
1
|
/**
|
2
|
+
* @description This model represents the mapped values of a product
|
2
3
|
* @typedef Product
|
3
4
|
* @type {object}
|
4
|
-
* @property {
|
5
|
+
* @property {ProductChildSku[]} childSkus
|
5
6
|
* @property {Inventory} [inventoryProperties]
|
6
|
-
*
|
7
|
-
* @typedef
|
7
|
+
*
|
8
|
+
* @typedef ProductChildSku
|
8
9
|
* @type {object}
|
9
10
|
* @property {string} productId
|
10
11
|
* @property {string} skuId
|
@@ -12,14 +13,48 @@
|
|
12
13
|
* @property {number} skuQuantity
|
13
14
|
* @property {string} availableChannels
|
14
15
|
* @property {Inventory} [inventory]
|
16
|
+
*
|
17
|
+
* ---
|
18
|
+
*
|
19
|
+
* @description This model represents a product within an Equinox response.
|
20
|
+
* @typedef EquinoxProduct
|
21
|
+
* @type {object}
|
22
|
+
* @property {EquinoxProduct[]} sku
|
23
|
+
* @property {"kit"|"bundle"} [type]
|
24
|
+
*
|
25
|
+
* @typedef EquinoxProductSKU
|
26
|
+
* @type {object}
|
27
|
+
* @property {string} identifier
|
28
|
+
* @property {EquinoxProductProperties} properties
|
29
|
+
* @property {Inventory} inventoryProperties
|
30
|
+
*
|
31
|
+
* @typedef EquinoxProductProperties
|
32
|
+
* @type {object}
|
33
|
+
* @property {string} availableChannels
|
34
|
+
*
|
35
|
+
* ---
|
36
|
+
*
|
37
|
+
* Types common to Product model and Equinox Product model
|
15
38
|
*
|
16
39
|
* @typedef Inventory
|
17
40
|
* @type {object}
|
18
41
|
* @property {number} atpQty
|
19
42
|
* @property {boolean} backOrdered
|
43
|
+
*
|
44
|
+
* ---
|
45
|
+
*
|
46
|
+
* Standalone types. These are types not related to Product
|
47
|
+
* and Equinox Product models.
|
48
|
+
*
|
49
|
+
* @typedef KitSKUQuantity
|
50
|
+
* @type {object}
|
51
|
+
* @property {string} sku
|
52
|
+
* @property {number} number
|
20
53
|
*/
|
21
54
|
const availableQuantity = require('./availableQuantity');
|
55
|
+
const childSkus = require('./childSkus');
|
22
56
|
|
23
57
|
module.exports = {
|
24
|
-
mapAvailableQuantity: availableQuantity
|
58
|
+
mapAvailableQuantity: availableQuantity,
|
59
|
+
mapChildSkus: childSkus
|
25
60
|
};
|
package/src/productData.js
CHANGED
@@ -5,7 +5,7 @@ const contentstack = require('./contentstack/contentstack');
|
|
5
5
|
const Product = require("./product");
|
6
6
|
const CustomerTypes = require('./models/customerTypes');
|
7
7
|
const ProductStatus = require("./models/productStatus");
|
8
|
-
const { mapAvailableQuantity } = require('./equinox-helpers');
|
8
|
+
const { mapAvailableQuantity, mapChildSkus } = require('./equinox-helpers');
|
9
9
|
|
10
10
|
const productTypes = {
|
11
11
|
kit: 'kit'
|
@@ -129,16 +129,14 @@ const ProductData = {
|
|
129
129
|
*/
|
130
130
|
eqProductVariantMapper: function (eqVariant) {
|
131
131
|
|
132
|
-
let imageURL = eqVariant.properties.imageURL
|
132
|
+
let imageURL = eqVariant.properties.imageURL;
|
133
133
|
const regex = /\d+\.\d+/
|
134
134
|
let thumbnailImage = ''
|
135
135
|
|
136
|
-
if (imageURL
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
thumbnailImage = imageURL.replace(regex, '40.40')
|
141
|
-
}
|
136
|
+
if (imageURL.includes('contentstack')) {
|
137
|
+
thumbnailImage = imageURL + '?width=40'
|
138
|
+
} else {
|
139
|
+
thumbnailImage = imageURL.replace(regex, '40.40')
|
142
140
|
}
|
143
141
|
|
144
142
|
const { eventName, eventLabels, computedPrice, defaultProductPrice } = this.getEqProductPromotions(eqVariant);
|
@@ -346,139 +344,142 @@ const ProductData = {
|
|
346
344
|
},
|
347
345
|
|
348
346
|
eqProductMapper: async function (productDataResponse, skus) {
|
349
|
-
// console.log(productDataResponse, skus);
|
350
347
|
let count = 0;
|
351
348
|
let variants = {};
|
352
349
|
const products = [];
|
353
350
|
|
354
351
|
for (const productData of productDataResponse) {
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
352
|
+
try {
|
353
|
+
let product = (productData.type && productData.type === "kit") ? productData : productData.sku[count];
|
354
|
+
let imageURL = product.properties.imageURL;
|
355
|
+
const regex = /\d+\.\d+/
|
356
|
+
let thumbnailImage = ''
|
359
357
|
|
360
|
-
if (imageURL !== "") {
|
361
358
|
if (imageURL.includes('contentstack')) {
|
362
359
|
thumbnailImage = imageURL + '?width=40'
|
363
360
|
} else {
|
364
361
|
thumbnailImage = imageURL.replace(regex, '40.40')
|
365
362
|
}
|
366
|
-
}
|
367
|
-
|
368
|
-
if (productData.sku && productData.sku.length > 1) {
|
369
|
-
// exclude base product from variants
|
370
|
-
productData.sku.filter(v => v.identifier.substring(2, 4) !== "55").map(variant => {
|
371
|
-
variants[variant.identifier] = this.eqProductVariantMapper(variant);
|
372
|
-
return variant;
|
373
|
-
});
|
374
|
-
}
|
375
363
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
const discountedPrice = eventName ? computedPrice : product.priceFacets["Regular Price"];
|
384
|
-
|
385
|
-
product.childSkus = await this.fetchChildSkus(product);
|
386
|
-
product.availableQuantity = mapAvailableQuantity(product);
|
387
|
-
product = {
|
388
|
-
...product,
|
389
|
-
"sku": product.identifier,
|
390
|
-
"globalProductID": productData.identifier,
|
391
|
-
"title": productData.properties.name,
|
392
|
-
"country": product.properties.market,
|
393
|
-
"language": "en",
|
394
|
-
"shortDescr": productData.properties.description,
|
395
|
-
"longDescr": productData.properties.productDetailsDescription,
|
396
|
-
"fullImage": imageURL,
|
397
|
-
"imageAltText": productData.properties.name,
|
398
|
-
"productCarouselImages": [
|
399
|
-
{
|
400
|
-
"contentType": "img",
|
401
|
-
"src": "/content/products/24/00/35/24003529/jcr:content/fullImage.imgw.1280.1280.png",
|
402
|
-
"alt": ""
|
403
|
-
}
|
404
|
-
],
|
405
|
-
"thumbnail": thumbnailImage,
|
406
|
-
"ingredients": productData.properties.ingredients,
|
407
|
-
"benefits": productData.properties.benefits,
|
408
|
-
"usage": productData.properties.usage,
|
409
|
-
"resources": product.properties.resources,
|
410
|
-
"videos": "",
|
411
|
-
"movie": "",
|
412
|
-
"youtube": "",
|
413
|
-
"salesEventText": "",
|
414
|
-
"contentSection": [
|
415
|
-
{
|
416
|
-
"sectionContent": "<div class=\"contentSections\"></div>\n"
|
417
|
-
}
|
418
|
-
],
|
419
|
-
"scanQualified": productData.properties.scanQualifiedCount,
|
420
|
-
"maxQuantity": 999,
|
421
|
-
"points": "",
|
422
|
-
"cv": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
423
|
-
"pv": product.priceFacets.PV,
|
424
|
-
"priceType": "WRTL",
|
425
|
-
"price": discountedPrice,
|
426
|
-
"priceMap": {
|
427
|
-
"WRTL": productPrice,
|
428
|
-
"WADW-WRTL": product.priceFacets["Regular Price"],
|
429
|
-
"WADR": product.priceFacets["Regular Price"],
|
430
|
-
"RTL": product.priceFacets["Regular Price"],
|
431
|
-
"WADW": product.priceFacets["Wholesale Price"],
|
432
|
-
"WHL": product.priceFacets["Wholesale Price"],
|
433
|
-
"WWHL": product.priceFacets["Wholesale Price"]
|
434
|
-
},
|
435
|
-
"cvMap": {
|
436
|
-
"WWHL": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
437
|
-
"WADW": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
438
|
-
"WHL": (product.priceFacets.CV) ? product.priceFacets.CV : ''
|
439
|
-
},
|
440
|
-
"pvMap": {
|
441
|
-
"WWHL": product.priceFacets.PV,
|
442
|
-
"WADW": product.priceFacets.PV,
|
443
|
-
"WHL": product.priceFacets.PV
|
444
|
-
},
|
445
|
-
"orderTypes": this._setOrderType(product.properties),
|
446
|
-
"custTypes": this.switchCustType(product.properties.customerTypes),
|
447
|
-
"division": productData.properties.division,
|
448
|
-
"backOrderDate": null,
|
449
|
-
"locallyProduced": false,
|
450
|
-
"agelocme": null,
|
451
|
-
"count": "",
|
452
|
-
"flavor": "",
|
453
|
-
"size": product.properties.size,
|
454
|
-
"shade": "",
|
455
|
-
"status": this.switchStatusFromEquinox(product.properties.productStatus),
|
456
|
-
"variantType": "Other",
|
457
|
-
"variantDropdownLabel": product.properties.variantLabel || "",
|
458
|
-
"variantDropdownPlaceholder": "Select Type",
|
459
|
-
"variantsLabel": product.properties.variantLabel || "",
|
460
|
-
"groupOffer": false,
|
461
|
-
"personalOffer": false,
|
462
|
-
"savedEventName": eventName,
|
463
|
-
"salesLabel": eventLabels,
|
464
|
-
"eventName": eventName,
|
465
|
-
"sizeWeight": '',
|
466
|
-
"nettoWeight": "",
|
467
|
-
"variants": variants,
|
468
|
-
"searchScore": 0,
|
469
|
-
"isExclusive": product.properties.isExclusive || false,
|
470
|
-
"marketAttributes": {
|
471
|
-
"discount": true,
|
472
|
-
"redeem": true,
|
473
|
-
"earn": true
|
474
|
-
},
|
475
|
-
"restrictedMarkets": [],
|
476
|
-
"addOns": [],
|
477
|
-
"inventory": product.inventory || "", //inventory label
|
478
|
-
"equinoxProductId": productData.identifier
|
479
|
-
};
|
364
|
+
if (productData.sku && productData.sku.length > 1) {
|
365
|
+
// exclude base product from variants
|
366
|
+
productData.sku.filter(v => v.identifier.substring(2, 4) !== "55").map(variant => {
|
367
|
+
variants[variant.identifier] = this.eqProductVariantMapper(variant);
|
368
|
+
return variant;
|
369
|
+
});
|
370
|
+
}
|
480
371
|
|
481
|
-
|
372
|
+
const {
|
373
|
+
eventName,
|
374
|
+
eventLabels,
|
375
|
+
computedPrice,
|
376
|
+
defaultProductPrice
|
377
|
+
} = this.getEqProductPromotions(product);
|
378
|
+
const productPrice = eventName ? defaultProductPrice : product.priceFacets["Regular Price"];
|
379
|
+
const discountedPrice = eventName ? computedPrice : product.priceFacets["Regular Price"];
|
380
|
+
|
381
|
+
product.childSkus = await this.fetchChildSkus(product);
|
382
|
+
product.availableQuantity = mapAvailableQuantity(product);
|
383
|
+
product = {
|
384
|
+
...product,
|
385
|
+
"sku": product.identifier,
|
386
|
+
"globalProductID": productData.identifier,
|
387
|
+
"title": productData.properties.name,
|
388
|
+
"country": product.properties.market,
|
389
|
+
"language": "en",
|
390
|
+
"shortDescr": productData.properties.description,
|
391
|
+
"longDescr": productData.properties.productDetailsDescription,
|
392
|
+
"fullImage": imageURL,
|
393
|
+
"imageAltText": productData.properties.name,
|
394
|
+
"productCarouselImages": [
|
395
|
+
{
|
396
|
+
"contentType": "img",
|
397
|
+
"src": "/content/products/24/00/35/24003529/jcr:content/fullImage.imgw.1280.1280.png",
|
398
|
+
"alt": ""
|
399
|
+
}
|
400
|
+
],
|
401
|
+
"thumbnail": thumbnailImage,
|
402
|
+
"ingredients": productData.properties.ingredients,
|
403
|
+
"benefits": productData.properties.benefits,
|
404
|
+
"usage": productData.properties.usage,
|
405
|
+
"resources": product.properties.resources,
|
406
|
+
"videos": "",
|
407
|
+
"movie": "",
|
408
|
+
"youtube": "",
|
409
|
+
"salesEventText": "",
|
410
|
+
"contentSection": [
|
411
|
+
{
|
412
|
+
"sectionContent": "<div class=\"contentSections\"></div>\n"
|
413
|
+
}
|
414
|
+
],
|
415
|
+
"scanQualified": productData.properties.scanQualifiedCount,
|
416
|
+
"maxQuantity": 999,
|
417
|
+
"points": "",
|
418
|
+
"cv": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
419
|
+
"pv": product.priceFacets.PV,
|
420
|
+
"priceType": "WRTL",
|
421
|
+
"price": discountedPrice,
|
422
|
+
"priceMap": {
|
423
|
+
"WRTL": productPrice,
|
424
|
+
"WADW-WRTL": product.priceFacets["Regular Price"],
|
425
|
+
"WADR": product.priceFacets["Regular Price"],
|
426
|
+
"RTL": product.priceFacets["Regular Price"],
|
427
|
+
"WADW": product.priceFacets["Wholesale Price"],
|
428
|
+
"WHL": product.priceFacets["Wholesale Price"],
|
429
|
+
"WWHL": product.priceFacets["Wholesale Price"]
|
430
|
+
},
|
431
|
+
"cvMap": {
|
432
|
+
"WWHL": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
433
|
+
"WADW": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
434
|
+
"WHL": (product.priceFacets.CV) ? product.priceFacets.CV : ''
|
435
|
+
},
|
436
|
+
"pvMap": {
|
437
|
+
"WWHL": product.priceFacets.PV,
|
438
|
+
"WADW": product.priceFacets.PV,
|
439
|
+
"WHL": product.priceFacets.PV
|
440
|
+
},
|
441
|
+
"orderTypes": this._setOrderType(product.properties),
|
442
|
+
"custTypes": this.switchCustType(product.properties.customerTypes),
|
443
|
+
"division": productData.properties.division,
|
444
|
+
"backOrderDate": null,
|
445
|
+
"locallyProduced": false,
|
446
|
+
"agelocme": null,
|
447
|
+
"count": "",
|
448
|
+
"flavor": "",
|
449
|
+
"size": product.properties.size,
|
450
|
+
"shade": "",
|
451
|
+
"status": this.switchStatusFromEquinox(product.properties.productStatus),
|
452
|
+
"variantType": "Other",
|
453
|
+
"variantDropdownLabel": product.properties.variantLabel || "",
|
454
|
+
"variantDropdownPlaceholder": "Select Type",
|
455
|
+
"variantsLabel": product.properties.variantLabel || "",
|
456
|
+
"groupOffer": false,
|
457
|
+
"personalOffer": false,
|
458
|
+
"savedEventName": eventName,
|
459
|
+
"salesLabel": eventLabels,
|
460
|
+
"eventName": eventName,
|
461
|
+
"sizeWeight": '',
|
462
|
+
"nettoWeight": "",
|
463
|
+
"variants": variants,
|
464
|
+
"searchScore": 0,
|
465
|
+
"isExclusive": product.properties.isExclusive || false,
|
466
|
+
"marketAttributes": {
|
467
|
+
"discount": true,
|
468
|
+
"redeem": true,
|
469
|
+
"earn": true
|
470
|
+
},
|
471
|
+
"restrictedMarkets": [],
|
472
|
+
"addOns": [],
|
473
|
+
"inventory": product.inventory || "", //inventory label
|
474
|
+
"equinoxProductId": productData.identifier
|
475
|
+
};
|
476
|
+
|
477
|
+
products.push(new Product(product));
|
478
|
+
} catch (err) {
|
479
|
+
console.error('Unable to map the product', productData.identifier, ':', err);
|
480
|
+
console.error('Product info:', productDataResponse, skus);
|
481
|
+
continue;
|
482
|
+
}
|
482
483
|
}
|
483
484
|
|
484
485
|
let data = {
|
@@ -521,7 +522,7 @@ const ProductData = {
|
|
521
522
|
type: 'SKUKIT',
|
522
523
|
availableChannels: product.properties.availableChannels
|
523
524
|
},
|
524
|
-
...res.data.product.map(p =>
|
525
|
+
...res.data.product.map(p => mapChildSkus(kits, p))
|
525
526
|
];
|
526
527
|
|
527
528
|
return childSkus;
|
@@ -530,23 +531,6 @@ const ProductData = {
|
|
530
531
|
return [];
|
531
532
|
},
|
532
533
|
|
533
|
-
buildChildSkus: function (kits, product) {
|
534
|
-
const sku = product.sku[0];
|
535
|
-
const kit = kits.filter(k => k.sku === sku.identifier)[0];
|
536
|
-
|
537
|
-
return {
|
538
|
-
productId: product.identifier,
|
539
|
-
skuId: sku.identifier,
|
540
|
-
type: 'MANDATORY',
|
541
|
-
skuQuantity: kit.qty,
|
542
|
-
availableChannels: sku.properties.availableChannels,
|
543
|
-
inventory: {
|
544
|
-
atpQty: sku.inventoryProperties.atpQty,
|
545
|
-
backOrdered: sku.inventoryProperties.backOrdered
|
546
|
-
}
|
547
|
-
}
|
548
|
-
},
|
549
|
-
|
550
534
|
/**
|
551
535
|
*
|
552
536
|
* Map status from equinox to legacy
|