@nuskin/ns-product-lib 2.12.0 → 2.13.0-cx24-5107.2

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ # [2.13.0-cx24-5107.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.13.0-cx24-5107.1...v2.13.0-cx24-5107.2) (2023-09-28)
2
+
3
+
4
+ ### Fix
5
+
6
+ * empty productById ([e4e455c](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/e4e455c34bae3558a429e4cce7c3226517ed6631))
7
+
8
+ # [2.13.0-cx24-5107.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.12.0...v2.13.0-cx24-5107.1) (2023-09-28)
9
+
10
+
11
+ ### Fix
12
+
13
+ * directory issue on jest ([41f8afa](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/41f8afa725923b472e33da741874e7ae9feeea73))
14
+ * file directory issue ([568d935](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/568d935f7575dfe18a33cd430d01e17ed3020080))
15
+ * kit and bundle ([5a4f13d](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/5a4f13d10ab87fa5ebfbe549ecb3df0c803f2296))
16
+ * linter ([1bf15af](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/1bf15afee64c0db411e794c5c3181ecbcbf64893))
17
+ * linter error (#CX24-5107) ([03f5abc](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/03f5abcd4940a91c2c04665b24e460813894eeba)), closes [#CX24-5107](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-5107)
18
+ * multi variants ([33ccfdd](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/33ccfdd979e4c229e82814e8b3a0aa93c7a1e14a))
19
+ * odd space in require ([f242b4d](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/f242b4dc696de968607b3c14340c60c3e7baa898))
20
+ * remove old code ([461e70e](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/461e70e1a4d5b1507c940a32bd6c645d5e3f8fef))
21
+ * sonar qube issue ([461a4b9](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/461a4b9007390608ba99b182ef698cc0cd1922cc))
22
+ * unit testing ([cda18ce](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/cda18ce61a0e411df889a2d2939898c54aba6c36))
23
+ * unitest issue in pipeline ([48b99f3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/48b99f375d1f357f6c5e906a00a09f3ad31042e4))
24
+
25
+ ### Update
26
+
27
+ * use graphql for product data (#CX24-5092) ([9e13973](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/9e139736e08eea59707164dec78ee4dc9542d4ec)), closes [#CX24-5092](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-5092)
28
+
1
29
  # [2.12.0](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.11.0...v2.12.0) (2023-09-22)
2
30
 
3
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/ns-product-lib",
3
- "version": "2.12.0",
3
+ "version": "2.13.0-cx24-5107.2",
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": {
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ const CustomerTypes = {
4
+ BrandAffiliate: "BrandAffiliate",
5
+ Preferred: "Preferred",
6
+ PreferredCustomer: "Preferred Customer",
7
+ Retail: "Retail",
8
+ properties: {
9
+ BRAND_AFFILIATE: { stringKey: "DIST", code: 10 },
10
+ RETAIL: { stringKey: "CUST", code: 20 },
11
+ PREFERRED: { stringKey: "preferred", code: 30 },
12
+ PREFERRED_CUSTOMER: { stringKey: "PREF", code: 30 }
13
+ }
14
+ };
15
+
16
+ module.exports = CustomerTypes;
@@ -0,0 +1,32 @@
1
+ const { getEnvironmentFromUrl } = require('@nuskin/ns-common-lib');
2
+
3
+ const config = {
4
+ dev: {
5
+ url: 'https://test.nuskin.com/product-api/graphql',
6
+ env: 'dev'
7
+ },
8
+ test: {
9
+ url: 'https://test.nuskin.com/product-api/graphql',
10
+ env: 'test'
11
+ },
12
+ prod: {
13
+ url: 'https://nuskin.com/product-api/graphql',
14
+ env: 'public'
15
+ }
16
+ };
17
+
18
+ /**
19
+ * Get product-api graphQL base URL based on web URL
20
+ * @returns {string} baseUrl (default: prod env url )
21
+ */
22
+ function graphQlUrl () {
23
+ const env = getEnvironmentFromUrl(window.location.host);
24
+
25
+ if (!config[env]) {
26
+ return config['prod'].url;
27
+ }
28
+
29
+ return config[env].url;
30
+ }
31
+
32
+ module.exports = graphQlUrl;
@@ -0,0 +1,7 @@
1
+ const getProduct = require('./product');
2
+ const graphQlUrl = require('./graphQlUrl');
3
+
4
+ module.exports = {
5
+ getProduct,
6
+ getGraphQlUrl: graphQlUrl
7
+ }
@@ -0,0 +1,418 @@
1
+ const axios = require('axios');
2
+ const { getProductByIdQuery } = require('./query');
3
+ const getGraphQlUrl = require('./graphQlUrl')
4
+ const ProductStatus = require("../models/productStatus");
5
+ const CustomerTypes = require('./customerTypes');
6
+ const Product = require("../product");
7
+
8
+ const defaultPayload = {
9
+ operationName: "getProduct",
10
+ useContentSource: "CS"
11
+ };
12
+
13
+ /**
14
+ * graphQl Http request
15
+ * @param {obj} payload
16
+ * @returns {Promise}
17
+ */
18
+ const graphQlHttpRequest = (payload) => {
19
+ const url = getGraphQlUrl();
20
+ return axios.request({
21
+ method: 'post',
22
+ url: url,
23
+ data: payload,
24
+ responseType: 'json'
25
+ });
26
+
27
+ }
28
+
29
+ /**
30
+ * Get product by ID
31
+ * @todo map promotions coming from promotions API
32
+ * @param {string} id
33
+ * @param {string} market
34
+ * @param {string} locale
35
+ * @param {obj} config
36
+ */
37
+ async function getProduct(id, market, locale, config) {
38
+
39
+ const productData = {
40
+ products: [],
41
+ count: 0
42
+ };
43
+
44
+ const payload = {
45
+ ...defaultPayload,
46
+ query: getProductByIdQuery,
47
+ variables: { id, market, locale }
48
+ }
49
+
50
+ try {
51
+ const { data } = await graphQlHttpRequest(payload);
52
+ if (data.productById) {
53
+ const product = mapProduct(data.productById, market, locale, config);
54
+ productData.products.push(new Product(product));
55
+ }
56
+ } catch (e) {
57
+ console.log(e);
58
+ }
59
+
60
+ return {
61
+ data: {
62
+ "status": 200,
63
+ "messages": [],
64
+ "data": productData
65
+ }
66
+ };
67
+ }
68
+
69
+ /**
70
+ *
71
+ * Map product data to be product card consumable structure *
72
+ * @param {object} product
73
+ * @param {string} market
74
+ * @param {string} locale
75
+ * @param {object} config
76
+ * @returns {object} Product
77
+ */
78
+ function mapProduct(product, market, locale, config) {
79
+ const kitBundleProducts = product.bundle;
80
+ let variants = product.variants || [];
81
+
82
+ const promotions = getPromotions(config);
83
+
84
+ if (kitBundleProducts) {
85
+
86
+ //merge kitBundleProducts and bundle attribute level
87
+ //since bundle level has totalPrice,availableChannels, etc
88
+ variants.push({
89
+ ...product,
90
+ ...kitBundleProducts,
91
+ productDetails: {
92
+ description: product.description
93
+ }
94
+ });
95
+ }
96
+
97
+ //serves as parent
98
+ const defaultVariant = variants[0];
99
+ const productDetail = {
100
+ "sku": defaultVariant.sku || product.id,
101
+ "globalProductID":product.id,
102
+ "title": defaultVariant.title,
103
+ "country": market,
104
+ "language": locale,
105
+ "shortDescr": defaultVariant.description,
106
+ "longDescr": defaultVariant.productDetails.description,
107
+ "fullImage": defaultVariant.productImages[0].url,
108
+ "imageAltText": defaultVariant.productImages[0].alt,
109
+ "thumbnail": defaultVariant.productImages[0].thumbnail,
110
+ "ingredients": defaultVariant.ingredients,
111
+ "benefits": defaultVariant.benefits,
112
+ "usage": defaultVariant.usage,
113
+ "resources": defaultVariant.resoruces,
114
+ "availableQuantity": defaultVariant.availableQuantity,
115
+ "maxQuantity": defaultVariant.maxQuantity,
116
+ "points": "",
117
+ "cv": (defaultVariant.points) ? defaultVariant.points.wholesale.cv : 0,
118
+ "pv": (defaultVariant.points) ? defaultVariant.points.wholesale.pv : 0,
119
+ "priceType": "WRTL",
120
+ "price": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.retail : defaultVariant.price.retail,
121
+ "priceMap": {
122
+ "WRTL": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.retail : defaultVariant.price.retail,
123
+ "WADW-WRTL": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.retailSubscription : defaultVariant.price.retail,
124
+ "WADR": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.retailSubscription : defaultVariant.price.retailSubscription, //retail ADR (subscription) price
125
+ "RTL": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.retail : defaultVariant.price.retail,
126
+ "WWHL": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.wholesale : defaultVariant.price.wholesale,
127
+ "WADW": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.wholesaleSubscription : defaultVariant.price.wholesaleSubscription,//wholesale ADR (subscription price)
128
+ "WHL": (defaultVariant.totalPrice) ? defaultVariant.totalPrice.wholesale : defaultVariant.price.wholesale
129
+ },
130
+ "cvMap": {
131
+ "WWHL": (defaultVariant.points) ? defaultVariant.points.wholesale.cv : 0,
132
+ "WADW": (defaultVariant.points) ? defaultVariant.points.subscription.cv : 0,
133
+ "WHL": (defaultVariant.points) ? defaultVariant.points.wholesale.cv : 0
134
+ },
135
+ "pvMap": {
136
+ "WWHL": (defaultVariant.points) ? defaultVariant.points.wholesale.pv : 0,
137
+ "WADW": (defaultVariant.points) ? defaultVariant.points.subscription.pv : 0,
138
+ "WHL": (defaultVariant.points) ? defaultVariant.points.wholesale.pv : 0
139
+ },
140
+ "orderTypes": mapOrderTypes(defaultVariant.availableChannels, defaultVariant.purchaseTypes),
141
+ "custTypes": mapCustomerTypes(defaultVariant.customerTypes),
142
+ "backOrderDate": defaultVariant.status.backorderedAvailableDate,
143
+ "size": defaultVariant.size,
144
+ "status": mapProductStatus(defaultVariant.status.status),
145
+ "variantType": "Other",
146
+ "variantDropdownLabel": product.variantSelectLabel || '',
147
+ "variantDropdownPlaceholder": "Select Type",
148
+ "variantsLabel": defaultVariant.variantLabel || '',
149
+ "groupOffer": false,
150
+ "personalOffer": false,
151
+ "savedEventName": '',
152
+ "salesLabel": '',
153
+ "eventName": promotions,
154
+ "sizeWeight": '',
155
+ "nettoWeight": "",
156
+ "searchScore": 0,
157
+ "isExclusive": defaultVariant.isExclusive || false,
158
+ "equinoxProductId": product.id,
159
+ "properties": {}
160
+
161
+ }
162
+
163
+ if (variants) {
164
+ productDetail.variants = mapVariants(product);
165
+ }
166
+
167
+ if (kitBundleProducts) {
168
+
169
+ //assemble childSku
170
+ //1st elememt should be parent product
171
+ productDetail.childSkus = [
172
+ {
173
+ availableChannels: kitBundleProducts.availableChannels,
174
+ productId: product.id,
175
+ skuId: product.id,
176
+ type: kitBundleProducts.type
177
+ },
178
+ ...mapChildSKU(kitBundleProducts)
179
+ ];
180
+ }
181
+
182
+ return productDetail;
183
+ }
184
+
185
+ /**
186
+ * Map product variants
187
+ * @param {*} product
188
+ * @returns {Array<object>} productVariants
189
+ */
190
+ function mapVariants(product) {
191
+
192
+ //return if it is not multi variant
193
+ if (!product.variants || (product.variants && product.variants.length === 1)) {
194
+ return [];
195
+ }
196
+
197
+ const variants = [];
198
+
199
+ product.variants.forEach(variant => {
200
+ const sku = variant.sku || variant.id;
201
+ variants[sku] = {
202
+ "sku": sku,
203
+ "globalProductID": product.id || variant.globalId,
204
+ "title": variant.title,
205
+ "shortDescr": variant.description,
206
+ "longDescr": variant.productDetails.description,
207
+ "fullImage": variant.productImages[0].url,
208
+ "imageAltText": variant.productImages[0].alt,
209
+ "thumbnail": variant.productImages[0].thumbnail,
210
+ "ingredients": variant.ingredients,
211
+ "benefits": variant.benefits,
212
+ "usage": variant.usage,
213
+ "resources": variant.resoruces,
214
+ "availableQuantity": variant.availableQuantity,
215
+ "maxQuantity": variant.maxQuantity,
216
+ "points": "",
217
+ "cv": (variant.points) ? variant.points.wholesale.cv : 0,
218
+ "pv": (variant.points) ? variant.points.wholesale.pv : 0,
219
+ "priceType": "WRTL",
220
+ "price": (variant.totalPrice) ? variant.totalPrice.retail : variant.price.retail,
221
+ "priceMap": {
222
+ "WRTL": (variant.totalPrice) ? variant.totalPrice.retail : variant.price.retail,
223
+ "WADW-WRTL": (variant.totalPrice) ? variant.totalPrice.retailSubscription : variant.price.retail,
224
+ "WADR": (variant.totalPrice) ? variant.totalPrice.retailSubscription : variant.price.retailSubscription, //retail ADR (subscription) price
225
+ "RTL": (variant.totalPrice) ? variant.totalPrice.retail : variant.price.retail,
226
+ "WWHL": (variant.totalPrice) ? variant.totalPrice.wholesale : variant.price.wholesale,
227
+ "WADW": (variant.totalPrice) ? variant.totalPrice.wholesaleSubscription : variant.price.wholesaleSubscription,//wholesale ADR (subscription price)
228
+ "WHL": (variant.totalPrice) ? variant.totalPrice.wholesale : variant.price.wholesale
229
+ },
230
+ "cvMap": {
231
+ "WWHL": (variant.points) ? variant.points.wholesale.cv : 0,
232
+ "WADW": (variant.points) ? variant.points.subscription.cv : 0,
233
+ "WHL": (variant.points) ? variant.points.wholesale.cv : 0
234
+ },
235
+ "pvMap": {
236
+ "WWHL": (variant.points) ? variant.points.wholesale.pv : 0,
237
+ "WADW": (variant.points) ? variant.points.subscription.pv : 0,
238
+ "WHL": (variant.points) ? variant.points.wholesale.pv : 0
239
+ },
240
+ "orderTypes": mapOrderTypes(variant.availableChannels, variant.purchaseTypes),
241
+ "custTypes": mapCustomerTypes(variant.customerTypes),
242
+ "backOrderDate": variant.status.backorderedAvailableDate,
243
+ "size": variant.size,
244
+ "status": mapProductStatus(variant.status.status),
245
+ "variantType": "Other",
246
+ "variantDropdownLabel": product.variantSelectLabel || '',
247
+ "variantDropdownPlaceholder": "Select Type",
248
+ "variantsLabel": variant.variantLabel || '',
249
+ "variants": [],
250
+ "groupOffer": false,
251
+ "personalOffer": false,
252
+ "savedEventName": '',
253
+ "salesLabel": '',
254
+ "eventName": '',
255
+ "sizeWeight": '',
256
+ "nettoWeight": "",
257
+ "searchScore": 0,
258
+ "isExclusive": variant.isExclusive || false,
259
+ "equinoxProductId": product.id,
260
+ "properties": {}
261
+ }
262
+ });
263
+
264
+ return variants;
265
+ }
266
+
267
+ /**
268
+ * Get promotions
269
+ * @todo use promotions API
270
+ * @param {*} config
271
+ * @returns {object} promotion
272
+ */
273
+ function getPromotions(config) {
274
+ console.log(`config `, config);
275
+ return 'event-name';
276
+ }
277
+
278
+ /**
279
+ * map product kit bundle child SKUs
280
+ * @param {*} kitBundleProducts
281
+ * @returns {array} kitBundleProducts
282
+ */
283
+ function mapChildSKU(kitBundleProducts) {
284
+ if (!kitBundleProducts || !kitBundleProducts.kitProducts) {
285
+ return [];
286
+ }
287
+
288
+ return kitBundleProducts.kitProducts.map((kitProduct) => {
289
+ const { product } = kitProduct;
290
+ const defaultVariant = product.variants[0];
291
+ return {
292
+ productId: product.id,
293
+ skuId: defaultVariant.sku,
294
+ type: 'MANDATORY',
295
+ skuQuantity: kitProduct.quantity,
296
+ availableChannels: kitBundleProducts.availableChannels,
297
+ inventory: {
298
+ atpQty: defaultVariant.availableQuantity,
299
+ backOrdered: defaultVariant.status.isBackordered,
300
+ backOrderedQty: defaultVariant.availableQuantity
301
+ }
302
+ }
303
+ });
304
+ }
305
+
306
+ /**
307
+ * map EQ customer types to supported product card customer types
308
+ * @param {Array<string>} eqCustomerTypes
309
+ * @returns{string} customer types
310
+ */
311
+ function mapCustomerTypes(eqCustomerTypes) {
312
+ if (!eqCustomerTypes) {
313
+ return "";
314
+ }
315
+
316
+ const custTypes = eqCustomerTypes;
317
+
318
+ let newCustType = [];
319
+ if (custTypes.includes(CustomerTypes.BrandAffiliate)) {
320
+ newCustType.push(CustomerTypes.properties.BRAND_AFFILIATE.code);
321
+ }
322
+
323
+ if (custTypes.includes(CustomerTypes.Retail)) {
324
+ newCustType.push(CustomerTypes.properties.RETAIL.code);
325
+ }
326
+
327
+ if (custTypes.includes(CustomerTypes.Preferred) || custTypes.includes(CustomerTypes.PreferredCustomer)) {
328
+ newCustType.push(CustomerTypes.properties.PREFERRED.code);
329
+ }
330
+
331
+ return newCustType.toString()
332
+ }
333
+
334
+ /**
335
+ * Map Order Types
336
+ * @param {Array<string>} availableChannels
337
+ * @param {object} purchaseTypes
338
+ * @returns {object} orderTypes
339
+ */
340
+ function mapOrderTypes(availableChannels, purchaseTypes) {
341
+
342
+ let orderTypes = {
343
+ "adr": false,
344
+ "order": false,
345
+ "zpfc": false,
346
+ "zadp": false,
347
+ "ars": false,
348
+ "kiosk": false,
349
+ "mobile": false,
350
+ "preferred customer": false,
351
+ "retail": false,
352
+ "web": false,
353
+ "web display": false
354
+ };
355
+
356
+ if (availableChannels) {
357
+ let availableChannelsArr = Array.isArray(availableChannels) ? availableChannels : availableChannels.split(',');
358
+
359
+ availableChannelsArr.forEach(channel => {
360
+ if (channel == 'arsPhone')
361
+ orderTypes.ars = true
362
+ if (channel == 'web') {
363
+ orderTypes.order = true
364
+ orderTypes.web = true
365
+ }
366
+ if (channel == 'kiosk')
367
+ orderTypes.kiosk = true
368
+ if (channel == 'mobile')
369
+ orderTypes.mobile = true
370
+ if (channel == 'subscription')
371
+ orderTypes.adr = true
372
+ });
373
+ }
374
+
375
+ if (purchaseTypes && purchaseTypes.buyOnce) {
376
+ orderTypes.web = true
377
+ orderTypes.order = true
378
+ }
379
+ if (purchaseTypes && purchaseTypes.subscription) {
380
+ orderTypes.adr = true
381
+ }
382
+
383
+ return orderTypes;
384
+ }
385
+
386
+ /**
387
+ * Map product status from Equinox format to Product card format
388
+ * @param {string} status
389
+ * @returns {string} status
390
+ */
391
+ function mapProductStatus (status) {
392
+ const { equinoxStatus } = ProductStatus;
393
+ let newStatus = '';
394
+ switch (status.toLowerCase()) {
395
+ case equinoxStatus.SELLABLE:
396
+ newStatus = ProductStatus.ReleasedForSale;
397
+ break;
398
+ case equinoxStatus.PREVIEW_PRODUCT:
399
+ newStatus = ProductStatus.NotReleasedForSale;
400
+ break;
401
+ case equinoxStatus.DISCONTINUED:
402
+ newStatus = ProductStatus.Discontinued;
403
+ break;
404
+ case equinoxStatus.STOPPED:
405
+ newStatus = ProductStatus.Discontinued;
406
+ break;
407
+ case equinoxStatus.REPLACEMENT:
408
+ newStatus = ProductStatus.NotReleasedForSale;
409
+ break;
410
+ default:
411
+ newStatus = ProductStatus.NotReleasedForSale;
412
+ break;
413
+ }
414
+
415
+ return newStatus;
416
+ }
417
+
418
+ module.exports = getProduct;
@@ -0,0 +1,535 @@
1
+ "use strict";
2
+
3
+ // eslint-disable-next-line max-len
4
+ const getProductByIdQuery = `query getProduct($id: String!, $market: String, $language: String, $useContentSource: String, $okta: String) {
5
+ productById(
6
+ id: $id
7
+ market: $market
8
+ language: $language
9
+ useContentSource: $useContentSource
10
+ okta: $okta
11
+ ) {
12
+ ...Product
13
+ bundle {
14
+ ...Kit
15
+ __typename
16
+ }
17
+ __typename
18
+ }
19
+ }
20
+
21
+ fragment Product on Product {
22
+ id
23
+ slug
24
+ title
25
+ secondaryTitle
26
+ productImages {
27
+ url
28
+ alt
29
+ thumbnail
30
+ __typename
31
+ }
32
+ salesLabel
33
+ salesText
34
+ description
35
+ salesDisclaimer
36
+ variantSelectLabel
37
+ variants {
38
+ ...Variant
39
+ __typename
40
+ }
41
+ features {
42
+ image {
43
+ url
44
+ alt
45
+ thumbnail
46
+ __typename
47
+ }
48
+ subtitle
49
+ features
50
+ backgroundColor
51
+ textColor
52
+ __typename
53
+ }
54
+ productDetails {
55
+ description
56
+ includedItems
57
+ highlights {
58
+ iconUrl
59
+ label
60
+ __typename
61
+ }
62
+ originCountry
63
+ importer
64
+ warnings
65
+ __typename
66
+ }
67
+ benefits {
68
+ benefits
69
+ image {
70
+ url
71
+ alt
72
+ thumbnail
73
+ __typename
74
+ }
75
+ youTubeVideoId
76
+ __typename
77
+ }
78
+ results {
79
+ summary
80
+ results {
81
+ percentage
82
+ text
83
+ __typename
84
+ }
85
+ report {
86
+ url
87
+ text
88
+ __typename
89
+ }
90
+ image {
91
+ url
92
+ alt
93
+ thumbnail
94
+ __typename
95
+ }
96
+ youTubeVideoId
97
+ __typename
98
+ }
99
+ sustainability {
100
+ youTubeVideoId
101
+ image {
102
+ url
103
+ __typename
104
+ }
105
+ description
106
+ highlights {
107
+ image {
108
+ url
109
+ __typename
110
+ }
111
+ description
112
+ __typename
113
+ }
114
+ __typename
115
+ }
116
+ usage {
117
+ steps
118
+ recommendations
119
+ warnings
120
+ additionalText
121
+ image {
122
+ url
123
+ alt
124
+ thumbnail
125
+ __typename
126
+ }
127
+ youTubeVideoId
128
+ markdown
129
+ __typename
130
+ }
131
+ resources {
132
+ title
133
+ url
134
+ image {
135
+ url
136
+ alt
137
+ thumbnail
138
+ __typename
139
+ }
140
+ __typename
141
+ }
142
+ warranty
143
+ faqs {
144
+ question
145
+ answers
146
+ __typename
147
+ }
148
+ ingredients {
149
+ productName
150
+ allIngredients
151
+ otherIngredients
152
+ activeIngredients
153
+ inactiveIngredients
154
+ ingredientDisclaimers
155
+ markdown
156
+ keyIngredients {
157
+ image {
158
+ url
159
+ alt
160
+ thumbnail
161
+ __typename
162
+ }
163
+ name
164
+ description
165
+ __typename
166
+ }
167
+ nutritionInformationImage {
168
+ url
169
+ alt
170
+ __typename
171
+ }
172
+ __typename
173
+ }
174
+ disclaimers
175
+ disclaimerWarnings {
176
+ icon {
177
+ url
178
+ alt
179
+ __typename
180
+ }
181
+ markdown
182
+ __typename
183
+ }
184
+ seoInformation {
185
+ metaDescription
186
+ metaTitle
187
+ canonicalURL
188
+ ogImage {
189
+ url
190
+ alt
191
+ __typename
192
+ }
193
+ __typename
194
+ }
195
+ thirdPartyScripts
196
+ productDataSource {
197
+ source
198
+ webBaseUrl
199
+ apiBaseUrl
200
+ storeId
201
+ __typename
202
+ }
203
+ error {
204
+ name
205
+ errors
206
+ lines
207
+ message
208
+ status
209
+ __typename
210
+ }
211
+ upSellProductIds
212
+ crossProductIds
213
+ __typename
214
+ }
215
+
216
+ fragment Variant on Variant {
217
+ sku
218
+ globalId
219
+ slug
220
+ variantLabel
221
+ variantColor
222
+ availableChannels
223
+ availableQuantity
224
+ customerTypes
225
+ maxQuantity
226
+ title
227
+ size
228
+ productImages {
229
+ url
230
+ alt
231
+ thumbnail
232
+ __typename
233
+ }
234
+ salesLabel
235
+ salesText
236
+ description
237
+ salesDisclaimer
238
+ nettoWeight
239
+ features {
240
+ image {
241
+ url
242
+ alt
243
+ thumbnail
244
+ __typename
245
+ }
246
+ subtitle
247
+ features
248
+ backgroundColor
249
+ textColor
250
+ __typename
251
+ }
252
+ productDetails {
253
+ description
254
+ includedItems
255
+ highlights {
256
+ iconUrl
257
+ label
258
+ __typename
259
+ }
260
+ originCountry
261
+ importer
262
+ warnings
263
+ __typename
264
+ }
265
+ benefits {
266
+ benefits
267
+ image {
268
+ url
269
+ alt
270
+ thumbnail
271
+ __typename
272
+ }
273
+ youTubeVideoId
274
+ __typename
275
+ }
276
+ results {
277
+ summary
278
+ results {
279
+ percentage
280
+ text
281
+ __typename
282
+ }
283
+ report {
284
+ url
285
+ text
286
+ __typename
287
+ }
288
+ image {
289
+ url
290
+ alt
291
+ thumbnail
292
+ __typename
293
+ }
294
+ youTubeVideoId
295
+ __typename
296
+ }
297
+ usage {
298
+ steps
299
+ recommendations
300
+ warnings
301
+ additionalText
302
+ image {
303
+ url
304
+ alt
305
+ thumbnail
306
+ __typename
307
+ }
308
+ youTubeVideoId
309
+ markdown
310
+ __typename
311
+ }
312
+ resources {
313
+ title
314
+ url
315
+ image {
316
+ url
317
+ alt
318
+ thumbnail
319
+ __typename
320
+ }
321
+ __typename
322
+ }
323
+ faqs {
324
+ question
325
+ answers
326
+ __typename
327
+ }
328
+ ingredients {
329
+ productName
330
+ allIngredients
331
+ otherIngredients
332
+ activeIngredients
333
+ inactiveIngredients
334
+ ingredientDisclaimers
335
+ markdown
336
+ keyIngredients {
337
+ image {
338
+ url
339
+ alt
340
+ thumbnail
341
+ __typename
342
+ }
343
+ name
344
+ description
345
+ __typename
346
+ }
347
+ nutritionInformationImage {
348
+ url
349
+ alt
350
+ __typename
351
+ }
352
+ __typename
353
+ }
354
+ isExclusive
355
+ price {
356
+ retail
357
+ wholesale
358
+ retailSales
359
+ wholesaleSales
360
+ retailSubscription
361
+ wholesaleSubscription
362
+ currencyCode
363
+ __typename
364
+ }
365
+ totalPrice {
366
+ retail
367
+ wholesale
368
+ retailSales
369
+ wholesaleSales
370
+ retailSubscription
371
+ wholesaleSubscription
372
+ currencyCode
373
+ __typename
374
+ }
375
+ points {
376
+ wholesale {
377
+ cv
378
+ pv
379
+ __typename
380
+ }
381
+ subscription {
382
+ cv
383
+ pv
384
+ __typename
385
+ }
386
+ __typename
387
+ }
388
+ totalPoints {
389
+ wholesale {
390
+ cv
391
+ pv
392
+ __typename
393
+ }
394
+ subscription {
395
+ cv
396
+ pv
397
+ __typename
398
+ }
399
+ __typename
400
+ }
401
+ pricingJson
402
+ availableQuantity
403
+ maxQuantity
404
+ status {
405
+ isBackordered
406
+ backorderedAvailableDate
407
+ status
408
+ __typename
409
+ }
410
+ purchaseTypes {
411
+ buyOnce
412
+ subscription
413
+ __typename
414
+ }
415
+ marketAttributes {
416
+ redeem
417
+ earn
418
+ __typename
419
+ }
420
+ disclaimers
421
+ disclaimerWarnings {
422
+ icon {
423
+ url
424
+ alt
425
+ __typename
426
+ }
427
+ markdown
428
+ __typename
429
+ }
430
+ restrictedMarkets
431
+ matchingVariant
432
+ shadeable
433
+ productType
434
+ primaryBrand
435
+ brandFamily
436
+ __typename
437
+ }
438
+
439
+ fragment Kit on Kit {
440
+ id
441
+ type
442
+ price {
443
+ currencyCode
444
+ retail
445
+ wholesale
446
+ retailSales
447
+ wholesaleSales
448
+ retailSubscription
449
+ wholesaleSubscription
450
+ __typename
451
+ }
452
+ totalPrice {
453
+ currencyCode
454
+ retail
455
+ wholesale
456
+ retailSales
457
+ wholesaleSales
458
+ retailSubscription
459
+ wholesaleSubscription
460
+ __typename
461
+ }
462
+ points {
463
+ wholesale {
464
+ cv
465
+ pv
466
+ __typename
467
+ }
468
+ subscription {
469
+ cv
470
+ pv
471
+ __typename
472
+ }
473
+ __typename
474
+ }
475
+ totalPoints {
476
+ wholesale {
477
+ cv
478
+ pv
479
+ __typename
480
+ }
481
+ subscription {
482
+ cv
483
+ pv
484
+ __typename
485
+ }
486
+ __typename
487
+ }
488
+ retailDiscount
489
+ wholesaleDiscount
490
+ pvDiscount
491
+ cvDiscount
492
+ sbDiscount
493
+ grpDiscount
494
+ availableChannels
495
+ customerTypes
496
+ purchaseTypes {
497
+ buyOnce
498
+ subscription
499
+ __typename
500
+ }
501
+ status {
502
+ status
503
+ isBackordered
504
+ backorderedAvailableDate
505
+ __typename
506
+ }
507
+ availableQuantity
508
+ chargeShipping
509
+ dangerousGoods
510
+ excludeFromSearch
511
+ isExclusive
512
+ marketAttributes {
513
+ discount
514
+ redeem
515
+ earn
516
+ __typename
517
+ }
518
+ restrictedMarkets
519
+ scanQualifiedCount
520
+ kitProducts {
521
+ quantity
522
+ isMandatory
523
+ product {
524
+ ...Product
525
+ __typename
526
+ }
527
+ __typename
528
+ }
529
+ __typename
530
+ }`
531
+
532
+
533
+ module.exports = {
534
+ getProductByIdQuery
535
+ };
@@ -7,7 +7,7 @@ const CustomerTypes = require('./models/customerTypes');
7
7
  const ProductStatus = require("./models/productStatus");
8
8
  const { mapBackOrderDate, mapAvailableQuantity, mapChildSKU, mapChildSKUBundle } = require('./equinox-helpers');
9
9
  const { productNotFoundInterceptor } = require('./equinox-helpers/interceptors');
10
-
10
+ const { getProduct } = require('./graph-ql');
11
11
  const productTypes = {
12
12
  kit: 'kit',
13
13
  bundle: 'bundle'
@@ -19,19 +19,16 @@ const ProductData = {
19
19
  * @param {string[]} skus
20
20
  * @param {string} locale
21
21
  * @param {string} market
22
- * @param {boolean} isEquinoxEnabled
23
22
  */
24
- getProductData: async function (skus, locale, market, isEquinoxEnabled = false) {
23
+ getProductData: async function (skus, locale, market) {
25
24
  const localeMarket = `${locale}_${market}`;
26
25
 
27
- if (isEquinoxEnabled) {
28
- const config = (await getConfiguration(['Equinox_Markets'])).Equinox_Markets;
29
-
30
- if (config.country_code === market && config.active) {
31
- return await this.getProductFromEquinox(skus, localeMarket, config);
32
- }
26
+ const config = (await getConfiguration(['Equinox_Markets'])).Equinox_Markets;
27
+ if (config.active) {
28
+ return await getProduct(skus[0], market, locale, config);
29
+ } else {
30
+ return await this.getProductFromLegacy(skus, localeMarket);
33
31
  }
34
- return await this.getProductFromLegacy(skus, localeMarket);
35
32
  },
36
33
 
37
34
  getProductFromEquinox: async function (skus, locale, config) {
@@ -60,7 +57,8 @@ const ProductData = {
60
57
 
61
58
  const shoppingContext = window && window.aem && window.aem.ShoppingContext && window.aem.ShoppingContext.getShoppingContext();
62
59
 
63
- if ((shoppingContext && shoppingContext.context === 'storefront') || window.location.hostname.includes(".mynuskin.com")) {
60
+ if ((shoppingContext && shoppingContext.context === 'storefront')
61
+ || window.location.hostname.includes(".mynuskin.com")) {
64
62
  config.API_Base_URLs = config.MySite_API_Base_URLs
65
63
  }
66
64