@nuskin/ns-product-lib 2.2.0-cx24-2467.2 → 2.3.0-cx24-2186.1

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,16 +1,17 @@
1
- # [2.2.0-cx24-2467.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.2.0-cx24-2467.1...v2.2.0-cx24-2467.2) (2022-10-11)
1
+ # [2.3.0-cx24-2186.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.2.0...v2.3.0-cx24-2186.1) (2022-10-13)
2
2
 
3
3
 
4
- ### Update
4
+ ### New
5
5
 
6
- * map product variant based on Product (#CX24-2467) ([7de46cc](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/7de46cc1595244504d44d4e2049f07e8697b4f20)), closes [#CX24-2467](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-2467)
6
+ * added inventory label in the mapping (#CX24-2186) ([a24fc39](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/a24fc39915e3d7e525949a2de8be04727c5226fd)), closes [#CX24-2186](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-2186)
7
7
 
8
- # [2.2.0-cx24-2467.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.1.0...v2.2.0-cx24-2467.1) (2022-10-11)
8
+ # [2.2.0](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.1.0...v2.2.0) (2022-10-13)
9
9
 
10
10
 
11
- ### New
11
+ ### Update
12
12
 
13
- * add variants (#CX24-2467) ([04b0632](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/04b0632d3f10758852f815cf2d06dd1f04aa7188)), closes [#CX24-2467](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-2467)
13
+ * Get Kong URL from contentstack (CX24-2447) ([272b35a](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/272b35a63908267e3c004ef43cbc2ecf0452a907))
14
+ * redirect to equinox sign-in if the market is equinox-enabled (CX24-2092) ([ffff6e2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/ffff6e21c0c6e72e0e3e42583dd443d7a0227bea))
14
15
 
15
16
  # [2.1.0](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.0.1...v2.1.0) (2022-10-04)
16
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/ns-product-lib",
3
- "version": "2.2.0-cx24-2467.2",
3
+ "version": "2.3.0-cx24-2186.1",
4
4
  "description": "This project contains shared Product models and code between the backend and frontend.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -29,7 +29,7 @@
29
29
  "prettier": "1.19.1"
30
30
  },
31
31
  "dependencies": {
32
- "@nuskin/ns-common-lib": "1.3.0",
32
+ "@nuskin/ns-common-lib": "1.4.5",
33
33
  "@nuskin/ns-util": "3.107.0",
34
34
  "axios": "0.27.2",
35
35
  "qs": "6.11.0"
@@ -14,11 +14,12 @@ const headers = {
14
14
  const http = axios.create({ baseURL, headers });
15
15
 
16
16
  // in-memory caching
17
- const cacheKeys = { aemConfig: 'aemConfig', equinoxMarkets: 'equinoxMarkets' };
17
+ const cacheKeys = { aemConfig: 'aemConfig', equinoxMarkets: 'equinoxMarkets', kongUrl: 'kongUrl' };
18
18
  const cacheTTLInSeconds = 30 * 1000;
19
19
  const cache = {
20
20
  [cacheKeys.aemConfig]: { data: null, ttl: Date.now() + cacheTTLInSeconds },
21
- [cacheKeys.equinoxMarkets]: { data: null, ttl: Date.now() + cacheTTLInSeconds }
21
+ [cacheKeys.equinoxMarkets]: { data: null, ttl: Date.now() + cacheTTLInSeconds },
22
+ [cacheKeys.kongUrl]: { data: null, ttl: Date.now() + cacheTTLInSeconds}
22
23
  };
23
24
 
24
25
  /**
@@ -139,6 +140,36 @@ async function getEquinoxMarkets() {
139
140
  }
140
141
  }
141
142
 
143
+ /**getKongUrl gets the URL for Kong in contentstack
144
+ *
145
+ * @returns {string}
146
+ */
147
+ async function getKongUrl() {
148
+ try {
149
+ if (isCacheExpired(cacheKeys.kongUrl)) {
150
+ const variables = { uid: 'blt5633ff9e560f14ef' };
151
+ const query = `query KongUrlByUid($uid: String!) {
152
+ equinox_markets(uid: $uid) {
153
+ kong_urls {
154
+ ${env}
155
+ }
156
+ }
157
+ }`;
158
+
159
+ const { data } = await contentstackService({
160
+ data: { variables, query }
161
+ });
162
+
163
+ setCachedData(cacheKeys.kongUrl, data.equinox_markets.kong_urls[env]);
164
+ }
165
+
166
+ return getCachedData(cacheKeys.kongUrl);
167
+ } catch (error) {
168
+ console.error(error);
169
+ return [];
170
+ }
171
+ }
172
+
142
173
  /**
143
174
  * isMarketEnabled checks is the given market is in the list
144
175
  * of equinox-enabled markets.
@@ -177,5 +208,6 @@ async function contentstackService(config) {
177
208
  module.exports = {
178
209
  getAEMConfig,
179
210
  getEquinoxMarkets,
180
- isMarketEnabled
211
+ isMarketEnabled,
212
+ getKongUrl
181
213
  }
package/src/product.js CHANGED
@@ -72,6 +72,11 @@ const Product = function(productData) {
72
72
  // agelocme stuff
73
73
  this.agelocme = null; // object containing agelocme information (like code, label, name)
74
74
 
75
+ //equinox API inventory label
76
+ //@example "IN STOCK"
77
+ //@string inventoryLabel
78
+ this.inventoryLabel = "";
79
+
75
80
  this.setMarketAttributes = function(productStatus) {
76
81
  if (productStatus.marketAttributes) {
77
82
  this.marketAttributes = productStatus.marketAttributes;
@@ -626,6 +631,7 @@ const Product = function(productData) {
626
631
  this.marketAttributes = productData.marketAttributes;
627
632
  this.addOns = productData.addOns || [];
628
633
  this.restrictedMarkets = productData.restrictedMarkets || [];
634
+ this.inventoryLabel = productData.inventoryLabel || "";
629
635
 
630
636
  if (data.priceType) {
631
637
  this.addPricing(data.priceType, data.price);
@@ -28,7 +28,9 @@ const ProductData = {
28
28
  getProductFromEquinox: async function (skus, locale, storeID) {
29
29
  const filter = '{"filters":[{"field":"index_key_skuId","operation":"IN","value":"' + skus.toString() + '"}]}';
30
30
  axios.defaults.withCredentials = true;
31
- const url = `https://storefront.api.wde.nuskin.io/orchestrationservices/storefront/catalogs/search/`;
31
+
32
+ const url = await contentstack.getKongUrl() + `/orchestrationservices/storefront/catalogs/search/`;
33
+ console.log("Dynamic URL", url)
32
34
  const href = `${url}?filter=${encodeURI(filter)}`;
33
35
  const response = await axios.request({
34
36
  method: 'get',
@@ -88,132 +90,13 @@ const ProductData = {
88
90
  };
89
91
  },
90
92
 
91
- /**
92
- * Map product variant
93
- * @todo remove unnecessary fields
94
- * @param {*} eqVariant
95
- * @returns Array<Product>
96
- */
97
- eqProductVariantMapper : function (eqVariant) {
98
-
99
- let imageURL = eqVariant.properties.imageURL;
100
- const regex = /\d+.\d+/
101
- let thumbnailImage = ''
102
-
103
- if (imageURL.includes('contentstack')) {
104
- thumbnailImage = imageURL + '?width=40'
105
- } else {
106
- thumbnailImage = imageURL.replace(regex,'40.40')
107
- }
108
-
109
- return {
110
- "sku": eqVariant.identifier,
111
- "globalProductID": eqVariant.identifier,
112
- "title": eqVariant.properties.name,
113
- "country": eqVariant.properties.market,
114
- "language": "en",
115
- "shortDescr": eqVariant.properties.description,
116
- "longDescr": eqVariant.properties.productDetailsDescription,
117
- "fullImage": imageURL,
118
- "imageAltText": eqVariant.properties.name,
119
- "productCarouselImages": [
120
- {
121
- "contentType": "img",
122
- "src": "/content/products/24/00/35/24003529/jcr:content/fullImage.imgw.1280.1280.png",
123
- "alt": ""
124
- }
125
- ],
126
- "thumbnail": thumbnailImage,
127
- "ingredients": eqVariant.properties.ingredients,
128
- "benefits": eqVariant.properties.benefits,
129
- "usage": eqVariant.properties.usage,
130
- "resources": eqVariant.properties.resources,
131
- "videos": "",
132
- "movie": "",
133
- "youtube": "",
134
- "salesEventText": "",
135
- "contentSection": [
136
- {
137
- "sectionContent": "<div class=\"contentSections\"><div class=\"contentSection section\"><div>\n<h3>BENEFITS</h3>\n<div>\n<div class=\"sectionContent parsys\"><div class=\"text parbase section\">\n<p>Green tea has been used in China for thousands of years for its health-preserving and revitalizing power. Modern science has identified powerful antioxidants in green tea called polyphenols. One group of polyphenols called catechins is particularly potent and is highly effective at neutralizing free radicals at the cellular level. Catechins support healthy cell function while providing antioxidant protection to critical cell structures such as DNA. Clinical studies show catechins interfere with the production of certain enzymes involved in cell damage. Additionally, catechins have been demonstrated to cause a thermogenic effect that enhances the body s metabolic rate. Tegreen 97<sup>®</sup> from Pharmanex is a proprietary, highly concentrated extract of the catechins found in green tea. Tegreen 97<sup>®</sup> is one of the most potent antioxidant supplements on the market with a 97 percent polyphenol content, 65% catechins. Each Tegreen 97<sup>®</sup> capsule contains the catechin equivalent of approximately seven cups of green tea and is 99.5 percent caffeine free.</p>\r\n\n</div>\n\n</div>\n\n</div>\n</div>\n</div>\n<div class=\"contentSection section\"><div>\n<h3>USAGE</h3>\n<div>\n<div class=\"sectionContent parsys\"><div class=\"text parbase section\">\n<p>As a dietary supplement, take one (1) to four (4) capsules daily; preferably one (1) to two (2) each morning and evening with food. Store in a cool, dry place.</p>\r\n\n</div>\n\n</div>\n\n</div>\n</div>\n</div>\n<div class=\"contentSection section\"><div>\n<h3>INGREDIENTS</h3>\n<div>\n<div class=\"sectionContent parsys\"><div class=\"text parbase section\">\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"0\" width=\"360\"><tbody>\r\n<tr>\r\n<td><b>Nutritional Facts</b></td>\r\n<td><b>Amount</b></td>\r\n<td><b>% Daily Value</b></td>\r\n</tr>\r\n<tr>\r\n<td colspan=\"3\"><b>Serving Size: 1 Capsule<br>\r\nServings Per Container: 120</b></td>\r\n</tr>\r\n<tr>\r\n<td width=\"55%\">Green tea leaf (20:1) Extract (<i>Camellia sinensis</i></td>\r\n<td width=\"20%\">250 mg</td>\r\n<td width=\"25%\">&nbsp;</td>\r\n</tr>\r\n<tr>\r\n<td width=\"55%\" colspan=\"3\">* Daily Value not established</td>\r\n</tr>\r\n<tr>\r\n<td width=\"55%\" colspan=\"3\"><b>Other Ingredients: Gelatin, Silicon Dioxide, Microcrystalline Cellulose, Magnesium Stearate.</b></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n<p>&nbsp;</p>\r\n\n</div>\n\n</div>\n\n</div>\n</div>\n</div>\n</div>\n"
138
- }
139
- ],
140
- "scanQualified": eqVariant.properties.scanQualifiedCount,
141
- "availableQuantity": 999,
142
- "maxQuantity": 999,
143
- "points": "",
144
- "cv": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : '',
145
- "pv":eqVariant.priceFacets.PV,
146
- "priceType": "WRTL",
147
- "price": eqVariant.priceFacets["Regular Price"],
148
- "priceMap": {
149
- "WRTL": eqVariant.priceFacets["Regular Price"],
150
- "WADW-WRTL": eqVariant.priceFacets["Regular Price"],
151
- "WADR": 9999.01,
152
- "RTL": eqVariant.priceFacets["Regular Price"],
153
- "WWHL": 9998.01,
154
- "WADW": 9998.01,
155
- "WHL": 9998.01
156
- },
157
- "cvMap": {
158
- "WWHL": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : '',
159
- "WADW": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : '',
160
- "WHL": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : ''
161
- },
162
- "pvMap": {
163
- "WWHL": eqVariant.priceFacets.PV,
164
- "WADW": eqVariant.priceFacets.PV,
165
- "WHL": eqVariant.priceFacets.PV
166
- },
167
- "orderTypes": {
168
- "adr": true,
169
- "order": true,
170
- "zpfc": false,
171
- "zadp": true,
172
- "ars": true,
173
- "kiosk": true,
174
- "mobile": true,
175
- "preferred customer": true,
176
- "retail": true,
177
- "web": true,
178
- "web display": true
179
- },
180
- "division": eqVariant.properties.division,
181
- "backOrderDate": null,
182
- "locallyProduced": false,
183
- "agelocme": null,
184
- "count": "",
185
- "flavor": "",
186
- "size": eqVariant.properties.size,
187
- "shade": "",
188
- "status": this.switchStatusFromEquinox(eqVariant.properties.status),
189
- "variantType": "Other",
190
- "variantDropdownLabel": "Select Type",
191
- "variantDropdownPlaceholder": "Select Type",
192
- "variantsLabel": "Select Type",
193
- "groupOffer": false,
194
- "personalOffer": false,
195
- "savedEventName": null,
196
- "salesLabel": "",
197
- "eventName": null,
198
- "sizeWeight": '',
199
- "nettoWeight": "",
200
- "searchScore": 0,
201
- "isExclusive": false,
202
- "marketAttributes": {
203
- "discount": true,
204
- "redeem": true,
205
- "earn": true
206
- },
207
- "restrictedMarkets": [],
208
- "addOns": []
209
- };
210
- },
211
-
212
93
  eqProductMapper: function (productDataResponse) {
213
94
  let prod = [];
214
- let variants = [];
215
95
 
216
- let prodArr = productDataResponse.map((data, count) => {
96
+ //sku[0] is equal to base sku
97
+ let count = 0;
98
+
99
+ let prodArr = productDataResponse.map((data) => {
217
100
  let imageURL = data.sku[count].properties.imageURL;
218
101
  const regex = /\d+.\d+/
219
102
  let thumbnailImage = ''
@@ -223,14 +106,6 @@ const ProductData = {
223
106
  } else {
224
107
  thumbnailImage = imageURL.replace(regex,'40.40')
225
108
  }
226
-
227
- if (data.sku && data.sku.length > 1) {
228
- data.sku.map(variant => {
229
- variants[variant.identifier] = this.eqProductVariantMapper(variant);
230
- return variant;
231
- });
232
- }
233
-
234
109
  prod = {
235
110
  "sku": data.sku[count].identifier,
236
111
  "globalProductID": data.identifier,
@@ -324,25 +199,28 @@ const ProductData = {
324
199
  "eventName": null,
325
200
  "sizeWeight": '',
326
201
  "nettoWeight": "",
327
- "variants": variants,
202
+ "variants": {
203
+ },
328
204
  "searchScore": 0,
329
- "isExclusive": false,
205
+ "isExclusive": data.sku[count].properties.isExclusive,
330
206
  "marketAttributes": {
331
207
  "discount": true,
332
208
  "redeem": true,
333
209
  "earn": true
334
210
  },
335
211
  "restrictedMarkets": [],
336
- "addOns": []
212
+ "addOns": [],
213
+ inventoryLabel: data.sku[count].inventory || ""
337
214
  };
338
- let newProduct = new Product(prod);
339
- return newProduct
340
- })
215
+
216
+ return new Product(prod);
217
+ });
341
218
 
342
219
  let data = {
343
220
  products: prodArr,
344
221
  count: productDataResponse.length
345
222
  };
223
+
346
224
  return {
347
225
  data: {
348
226
  "status": 200,
@@ -371,7 +249,7 @@ const ProductData = {
371
249
  newStatus = 'NOT_RELEASED_FOR_SALE';
372
250
  break;
373
251
  default:
374
- newStatus = 'RELEASED_FOR_SALE'
252
+ newStatus = 'NOT_RELEASED_FOR_SALE'
375
253
  break;
376
254
  }
377
255
  return newStatus;