@nuskin/ns-product-lib 1.5.0 → 2.0.0-cx24-2382.2

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 CHANGED
@@ -1,3 +1,28 @@
1
+ # [2.0.0-cx24-2382.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.0.0-cx24-2382.1...v2.0.0-cx24-2382.2) (2022-09-07)
2
+
3
+
4
+ ### Update
5
+
6
+ * change the parameters passed to getProductData (CX24-2382) ([ba22522](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/ba225229615599f6884a56fc4fd4c172a2e3d83e))
7
+
8
+ # [2.0.0-cx24-2382.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v1.6.0-cx24-2382.1...v2.0.0-cx24-2382.1) (2022-09-06)
9
+
10
+
11
+ ### Breaking
12
+
13
+ * replace runConfig and marketConfig parameters of getProductData with locale and market (CX24-2382) ([713bbb6](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/713bbb6b52e20727ce846d4df5c84d837fb931d5))
14
+
15
+ ### New
16
+
17
+ * add equinox-enabled market validation (CX24-2382) ([6633eb5](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/6633eb5824ec621a7316aff401d29876761ffc38))
18
+
19
+ # [1.6.0-cx24-2382.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v1.5.0...v1.6.0-cx24-2382.1) (2022-09-01)
20
+
21
+
22
+ ### New
23
+
24
+ * query equinox-enabled markets (CX24-2382) ([1fcd191](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/1fcd191d654b5ad39603140e80dddd06ab7d0056))
25
+
1
26
  # [1.5.0](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v1.4.5...v1.5.0) (2022-08-25)
2
27
 
3
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/ns-product-lib",
3
- "version": "1.5.0",
3
+ "version": "2.0.0-cx24-2382.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,121 @@
1
+ // This module can be bundled into a package for better reusability.
2
+ const axios = require('axios');
3
+ const { getEnvironmentFromUrl } = require('@nuskin/ns-common-lib');
4
+
5
+ /**
6
+ * getAEMConfig fetches the market config from contentstack.
7
+ *
8
+ * @typedef MarketConfig
9
+ * @property {string} aws_url
10
+ * @property {string} checkout_client_id
11
+ * @property {string} checkout_client_secret
12
+ *
13
+ * @export
14
+ * @return {Promise<null|MarketConfig>}
15
+ */
16
+ async function getAEMConfig() {
17
+ try {
18
+ const env = getEnvironmentFromUrl('test.nuskin.com');
19
+ const marketConfig = `market_config_${env}`;
20
+ const variables = { uid: 'blt52b0b83a89763791' };
21
+ const query = `query EquinoxMarketsByUid($uid: String!) {
22
+ aem_config(uid: $uid) {
23
+ title
24
+ ${marketConfig} {
25
+ checkout_client_secret
26
+ checkout_client_id
27
+ aws_url
28
+ }
29
+ }
30
+ }`;
31
+
32
+ const { data } = await contentstackService({
33
+ method: 'post',
34
+ data: { variables, query }
35
+ });
36
+
37
+ return data.aem_config[marketConfig];
38
+ } catch (error) {
39
+ console.error(error);
40
+ return null;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * getEquinoxMarkets will get the list of Equinox-enabled markets from contentstack
46
+ *
47
+ * @typedef EquinoxEnabledMarket
48
+ * @property {string} market_name
49
+ * @property {string} country_code
50
+ * @property {string} store_id
51
+ *
52
+ * @typedef EquinoxEnabledMarkets
53
+ * @property {EquinoxEnabledMarket[]} [dev_markets]
54
+ * @property {EquinoxEnabledMarket[]} [test_markets]
55
+ * @property {EquinoxEnabledMarket[]} [staging_markets]
56
+ * @property {EquinoxEnabledMarket[]} [prod_markets]
57
+ *
58
+ * @export
59
+ * @return {Promise<EquinoxEnabledMarkets>}
60
+ */
61
+ async function getEquinoxMarkets() {
62
+ try {
63
+ const env = getEnvironmentFromUrl('test.nuskin.com');
64
+ const marketConfig = `${env}_markets`;
65
+ const variables = { uid: 'blt5633ff9e560f14ef' };
66
+ const query = `query EquinoxMarketsByUid($uid: String!) {
67
+ equinox_markets(uid: $uid) {
68
+ ${marketConfig} {
69
+ market_name
70
+ country_code
71
+ store_id
72
+ }
73
+ }
74
+ }`;
75
+
76
+ const { data } = await contentstackService({
77
+ method: 'post',
78
+ data: { variables, query }
79
+ });
80
+
81
+ return data.equinox_markets[marketConfig];
82
+ } catch (error) {
83
+ console.error(error);
84
+ return [];
85
+ }
86
+ }
87
+
88
+
89
+
90
+ /**
91
+ * Contentstack HTTP - axios wrapper for contentstack request
92
+ *
93
+ * @param {Object} config - required param
94
+ * @return {Promise<import('axios').AxiosResponse>} Promise that resolves to market_list_eq object
95
+ */
96
+ async function contentstackService(config) {
97
+ const baseURL = 'https://graphql.contentstack.com';
98
+ const deliveryToken = 'cs74599c107573ea7f6c7a1413';
99
+ const apiKey = 'blt7d4c4f4a1bf5a819';
100
+ const env = 'public-dev';
101
+ const defaultUrl = `${baseURL}/stacks/${apiKey}?environment=${env}`;
102
+
103
+ config.method = config.method || 'get'
104
+ config.url = config.url || defaultUrl
105
+ config.headers = {
106
+ 'access_token': `${deliveryToken}`,
107
+ 'Content-Type': 'application/json'
108
+ }
109
+
110
+ try {
111
+ const response = await axios(config);
112
+ return response.data
113
+ } catch (error) {
114
+ console.error(error.response.data.errors);
115
+ }
116
+ }
117
+
118
+ module.exports = {
119
+ getAEMConfig,
120
+ getEquinoxMarkets
121
+ }
@@ -1,72 +1,104 @@
1
1
  "use strict";
2
- const axios = require("axios");
3
- const product = require("./product")
2
+ const axios = require("axios");
3
+ const contentstack = require('./contentstack/contentstack');
4
+ const product = require("./product");
5
+
4
6
  /** @type {*} */
5
7
  const ProductData = {
6
8
  /**
7
9
  * @param {*} skus
8
10
  * @param {*} runConfig
9
11
  * @param {*} marketConfig
10
- * @param {{ isEnabled: boolean, storeID: string }} equinoxOptions
12
+ * @param {boolean} isEquinoxEnabled
11
13
  */
12
- getProductData: async function (skus, runConfig, marketConfig, equinoxOptions) {
13
- const locale = `${runConfig.language}_${runConfig.country}`;
14
+ getProductData: async function (skus, locale, market, isEquinoxEnabled = false) {
15
+ const localeMarket = `${locale}_${market}`;
16
+ const enabledMarkets = await contentstack.getEquinoxMarkets();
17
+ const isMarketEnabled = enabledMarkets
18
+ .map(m => m.country_code.toLowerCase())
19
+ .includes(market.toLowerCase());
14
20
 
15
- if (equinoxOptions !== undefined && equinoxOptions.isEnabled === true) {
16
- return await this.getProductFromEquinox(skus, locale, marketConfig, equinoxOptions.storeID);
21
+ if (isEquinoxEnabled && isMarketEnabled) {
22
+ return await this.getProductFromEquinox(skus, localeMarket, 406);
17
23
  }
18
24
 
19
- return await this.getProductFromLegacy(skus, locale, marketConfig);
25
+ return await this.getProductFromLegacy(skus, localeMarket);
20
26
  },
21
27
 
22
- getProductFromEquinox: async function(skus, locale, marketConfig, storeID) {
23
- const filter = `{
24
- "filters": [{
25
- "field": "index_key_skuId",
26
- "operation": "IN",
27
- "value": "${skus.toString()}"
28
- }]
29
- }`;
28
+ getProductFromEquinox: async function (skus, locale, storeID) {
29
+ const filter = '{"filters":[{"field":"index_key_skuId","operation":"IN","value":"' + skus.toString() + '"}]}';
30
30
  axios.defaults.withCredentials = true;
31
- const productDataResponse = await axios.request({
31
+ const url = `https://storefront.api.wts.nuskin.io/orchestrationservices/storefront/catalogs/search/`;
32
+ const href = `${url}?filter=${encodeURI(filter)}`;
33
+ const response = await axios.request({
32
34
  method: 'get',
33
- url: `https://storefront.api.wts.nuskin.io/orchestrationservices/storefront/catalogs/search/`,
35
+ url: href,
34
36
  params: {
35
37
  locale,
36
- storeId: storeID,
37
- filter
38
+ storeId: storeID
38
39
  },
39
- headers: this.getProductDataRequestHeaders(marketConfig),
40
- responseType: "json"
40
+ headers: this.getEquinoxRequestHeaders(),
41
+ responseType: 'json'
41
42
  });
42
43
 
43
- return this.eqProductMapper(productDataResponse.data.product);
44
+ if (response.data.product) {
45
+ return this.eqProductMapper(response.data.product);
46
+ }
47
+
48
+ return {
49
+ status: 400,
50
+ messages: [response.data.message],
51
+ data: { count: 0, products: [] }
52
+ }
44
53
  },
45
54
 
46
- getProductFromLegacy: async function(skus, locale, marketConfig) {
47
- const lambdaUrl = `${marketConfig.awsUrl}/productData/v1`;
55
+ getEquinoxRequestHeaders() {
56
+ return {
57
+ authorization: `Bearer ${localStorage.getItem('equinox-okta-token')}`,
58
+ 'Content-Type': 'application/json',
59
+ 'x-sk-session-id': localStorage.getItem('x-sk-session-id')
60
+ };
61
+ },
62
+
63
+ getProductFromLegacy: async function (skus, locale) {
64
+ const marketConfig = await contentstack.getAEMConfig();
65
+
66
+ if (marketConfig === null) {
67
+ return null;
68
+ }
69
+
70
+ const lambdaUrl = `${marketConfig.aws_url}/productData/v1`;
48
71
  const payload = { locale, skus };
49
72
 
50
73
  return await axios.request({
51
- method: "post",
74
+ method: 'post',
52
75
  url: lambdaUrl,
53
76
  data: payload,
54
- headers: this.getProductDataRequestHeaders(marketConfig),
55
- responseType: "json"
77
+ headers: this.getLegacyRequestHeaders(marketConfig),
78
+ responseType: 'json'
56
79
  });
57
80
  },
58
-
59
- /* eqProductMapper: function(productDataResponse) {
60
- return productDataResponse;
61
- }, */
81
+
82
+ /**
83
+ * @param {contentstack.MarketConfig} marketConfig
84
+ */
85
+ getLegacyRequestHeaders: function(marketConfig) {
86
+ return {
87
+ 'Content-Type': 'application/json',
88
+ client_id: marketConfig.checkout_client_id,
89
+ client_secret: marketConfig.checkout_client_secret
90
+ };
91
+ },
62
92
 
63
93
  eqProductMapper: function (productDataResponse) {
64
94
  let prodArr = [];
65
95
  let prod = [];
66
96
  let count = 0;
97
+
98
+ // we can use Array.map for this one
67
99
  productDataResponse.forEach((data, index) => {
68
100
  count++
69
-
101
+
70
102
  prod = {
71
103
  "sku": data.sku[0].identifier,
72
104
  "globalProductID": data.identifier,
@@ -189,15 +221,6 @@ const ProductData = {
189
221
  "messages": [],
190
222
  "data": data
191
223
  }
192
- }
193
-
194
- },
195
-
196
- getProductDataRequestHeaders: function (marketConfig) {
197
- return {
198
- "Content-Type": "application/json",
199
- client_id: marketConfig.checkout.clientId,
200
- client_secret: marketConfig.checkout.clientSecret
201
224
  };
202
225
  }
203
226
  }