@nuskin/cs-product-lib 1.0.5 → 1.0.6-cx12-6632.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/package.json +2 -1
- package/src/csProduct.js +49 -5
- package/src/formatKit.js +169 -0
- package/src/formatProduct.js +76 -70
- package/src/helpers.js +3 -3
- package/src/transformBundle.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuskin/cs-product-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6-cx12-6632.2",
|
|
4
4
|
"description": "Library for pulling and parsing product content (and applying business logic) retrieved from Contentstack",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"config": "^3.3.6",
|
|
44
44
|
"entities": "4.4.0",
|
|
45
45
|
"lodash": "4.17.21",
|
|
46
|
+
"moment": "^2.29.4",
|
|
46
47
|
"turndown": "7.1.1"
|
|
47
48
|
}
|
|
48
49
|
}
|
package/src/csProduct.js
CHANGED
|
@@ -53,11 +53,14 @@ const csProduct = (props) => {
|
|
|
53
53
|
const REQUIRED = 'required_products.product.'
|
|
54
54
|
const OPTIONAL = 'optional_products.product.'
|
|
55
55
|
const BUNDLE_TYPE = 'bundle'
|
|
56
|
+
const PRODUCT_BUNDLE = 'product_bundle'
|
|
56
57
|
|
|
57
58
|
// eslint-disable-next-line max-len
|
|
58
|
-
const productIncludes = `&include[]=${VARIANTS}&include[]=${PRODUCT_FAQS}&include[]=${KEY_INGREDIENTS}&include[]=${PRODUCT_HIGHLIGHTS}&include[]=${PRODUCT_RESOURCES}&include[]=${VARIANT_KEY_INGREDIENTS}&include[]=${VARIANT_HIGHLIGHTS}&include[]=${VARIANT_FAQS}&include[]=${VARIANT_RESOURCES}&include[]=${PRODUCT_CATEGORY}&include[]=${PRODUCT_SUBCATEGORIES}&include[]=${PRODUCT_BRAND_STYLE}`
|
|
59
|
+
const productIncludes = `&include[]=${VARIANTS}&include[]=${PRODUCT_FAQS}&include[]=${KEY_INGREDIENTS}&include[]=${PRODUCT_HIGHLIGHTS}&include[]=${PRODUCT_RESOURCES}&include[]=${VARIANT_KEY_INGREDIENTS}&include[]=${VARIANT_HIGHLIGHTS}&include[]=${VARIANT_FAQS}&include[]=${VARIANT_RESOURCES}&include[]=${PRODUCT_CATEGORY}&include[]=${PRODUCT_SUBCATEGORIES}&include[]=${PRODUCT_BRAND_STYLE}&include[]=${PRODUCT_BUNDLE}`
|
|
59
60
|
const requiredIncludes = `&include[]=${REQUIRED}${VARIANTS}&include[]=${REQUIRED}${PRODUCT_FAQS}&include[]=${REQUIRED}${KEY_INGREDIENTS}&include[]=${REQUIRED}${PRODUCT_HIGHLIGHTS}&include[]=${REQUIRED}${PRODUCT_RESOURCES}&include[]=${REQUIRED}${VARIANT_KEY_INGREDIENTS}&include[]=${REQUIRED}${VARIANT_HIGHLIGHTS}&include[]=${REQUIRED}${VARIANT_FAQS}&include[]=${REQUIRED}${VARIANT_RESOURCES}&include[]=${REQUIRED}${PRODUCT_CATEGORY}&include[]=${REQUIRED}${PRODUCT_SUBCATEGORIES}`
|
|
60
61
|
const optionalIncludes = `&include[]=${OPTIONAL}${VARIANTS}&include[]=${OPTIONAL}${PRODUCT_FAQS}&include[]=${OPTIONAL}${KEY_INGREDIENTS}&include[]=${OPTIONAL}${PRODUCT_HIGHLIGHTS}&include[]=${OPTIONAL}${PRODUCT_RESOURCES}&include[]=${OPTIONAL}${VARIANT_KEY_INGREDIENTS}&include[]=${OPTIONAL}${VARIANT_HIGHLIGHTS}&include[]=${OPTIONAL}${VARIANT_FAQS}&include[]=${OPTIONAL}${VARIANT_RESOURCES}&include[]=${OPTIONAL}${PRODUCT_CATEGORY}&include[]=${OPTIONAL}${PRODUCT_SUBCATEGORIES}`
|
|
62
|
+
const bundleRequiredIncludes = `&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${VARIANTS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${PRODUCT_FAQS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${KEY_INGREDIENTS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${PRODUCT_HIGHLIGHTS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${PRODUCT_RESOURCES}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${VARIANT_KEY_INGREDIENTS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${VARIANT_HIGHLIGHTS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${VARIANT_FAQS}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${VARIANT_RESOURCES}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${PRODUCT_CATEGORY}&include[]=${PRODUCT_BUNDLE}.${REQUIRED}${PRODUCT_SUBCATEGORIES}`
|
|
63
|
+
const bundlOptionalIncludes = `&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${VARIANTS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${PRODUCT_FAQS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${KEY_INGREDIENTS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${PRODUCT_HIGHLIGHTS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${PRODUCT_RESOURCES}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${VARIANT_KEY_INGREDIENTS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${VARIANT_HIGHLIGHTS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${VARIANT_FAQS}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${VARIANT_RESOURCES}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${PRODUCT_CATEGORY}&include[]=${PRODUCT_BUNDLE}.${OPTIONAL}${PRODUCT_SUBCATEGORIES}`
|
|
61
64
|
|
|
62
65
|
validateConfig(props)
|
|
63
66
|
const { apiKey, environment, deliveryToken, homeUrl, awsBase, clientId } = props
|
|
@@ -183,6 +186,45 @@ const csProduct = (props) => {
|
|
|
183
186
|
})
|
|
184
187
|
}
|
|
185
188
|
|
|
189
|
+
const formatBundleKit = async (products, locale, translations) => {
|
|
190
|
+
for (let p = 0; p < products.length; p++) {
|
|
191
|
+
for (let b = 0; b < products[p]?.product_bundle?.length || 0; b++) {
|
|
192
|
+
|
|
193
|
+
for (
|
|
194
|
+
let i = 0;
|
|
195
|
+
i < (products[p].product_bundle[b].required_products || []).length;
|
|
196
|
+
i++
|
|
197
|
+
) {
|
|
198
|
+
await removeInvalidVariants(
|
|
199
|
+
products[p].product_bundle[b].required_products[i].product,
|
|
200
|
+
locale,
|
|
201
|
+
translations
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
for (
|
|
205
|
+
let i = 0;
|
|
206
|
+
i < (products[p].product_bundle[b].optional_products || []).length;
|
|
207
|
+
i++
|
|
208
|
+
) {
|
|
209
|
+
await removeInvalidVariants(
|
|
210
|
+
products[p].product_bundle[b].optional_products[i].product,
|
|
211
|
+
locale,
|
|
212
|
+
translations
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
products[p].product_bundle[b].type = "bundle"
|
|
216
|
+
}
|
|
217
|
+
products[p].bundle = formatBundleWithSchema(products[p].product_bundle)
|
|
218
|
+
if(products[p].product_bundle?.length > 0){
|
|
219
|
+
products[p].variants = []
|
|
220
|
+
}
|
|
221
|
+
products[p].type = (products[p].product_bundle?.length || 0) > 0 ? "bundle" : null
|
|
222
|
+
delete products[p].product_bundle
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
186
228
|
// includes is an array of all the referenced types in the contentType you are requesting that should be resolved
|
|
187
229
|
// and returned (Example: ['common_strings'])
|
|
188
230
|
const getEntriesByQuery = async ({
|
|
@@ -198,6 +240,8 @@ const csProduct = (props) => {
|
|
|
198
240
|
let url = `content_types/${contentType}/entries?environment=${environment}&locale=${locale}&include_count=true&limit=${limit}&query=${query}`
|
|
199
241
|
if (contentType === PRODUCT_TYPE) {
|
|
200
242
|
url += productIncludes
|
|
243
|
+
url += bundleRequiredIncludes
|
|
244
|
+
url += bundlOptionalIncludes
|
|
201
245
|
}
|
|
202
246
|
if (contentType === BUNDLE_TYPE) {
|
|
203
247
|
url += requiredIncludes
|
|
@@ -312,7 +356,7 @@ const csProduct = (props) => {
|
|
|
312
356
|
|
|
313
357
|
let products = await queryProducts(query, locale)
|
|
314
358
|
const translations = await getTranslations(locale)
|
|
315
|
-
|
|
359
|
+
await formatBundleKit(products, locale, translations)
|
|
316
360
|
await removeInvalidVariants(products, locale, translations)
|
|
317
361
|
for (const product of products) {
|
|
318
362
|
product.skus = skus
|
|
@@ -331,7 +375,7 @@ const csProduct = (props) => {
|
|
|
331
375
|
|
|
332
376
|
let products = await queryProducts(query, locale)
|
|
333
377
|
const translations = await getTranslations(locale)
|
|
334
|
-
|
|
378
|
+
await formatBundleKit(products, locale, translations)
|
|
335
379
|
await removeInvalidVariants(products, locale, translations)
|
|
336
380
|
return formatProductWithSchema(products)
|
|
337
381
|
}
|
|
@@ -346,7 +390,7 @@ const csProduct = (props) => {
|
|
|
346
390
|
|
|
347
391
|
const products = await queryProducts(query, locale)
|
|
348
392
|
const translations = await getTranslations(locale)
|
|
349
|
-
|
|
393
|
+
await formatBundleKit(products, locale, translations)
|
|
350
394
|
await removeInvalidVariants(products, locale, translations)
|
|
351
395
|
return formatProductWithSchema(products)
|
|
352
396
|
}
|
|
@@ -358,7 +402,7 @@ const csProduct = (props) => {
|
|
|
358
402
|
const query = `{"uid": {"$in": ${helpers?.arrayString(ids)}}}`
|
|
359
403
|
let products = await queryProducts(query, locale)
|
|
360
404
|
const translations = await getTranslations(locale)
|
|
361
|
-
|
|
405
|
+
await formatBundleKit(products, locale, translations)
|
|
362
406
|
await removeInvalidVariants(products, locale, translations)
|
|
363
407
|
return formatProductWithSchema(products)
|
|
364
408
|
}
|
package/src/formatKit.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
const moment = require('moment')
|
|
2
|
+
|
|
3
|
+
const parseStatus = (variant) => {
|
|
4
|
+
const dateFormat = 'YYYY-MM-DD'
|
|
5
|
+
const properties = variant.properties || {}
|
|
6
|
+
if (
|
|
7
|
+
variant.inventoryProperties &&
|
|
8
|
+
variant.inventoryProperties.backOrdered &&
|
|
9
|
+
variant.inventoryProperties.expectedBackOrderAvailabilityDate) {
|
|
10
|
+
return {
|
|
11
|
+
|
|
12
|
+
// changed
|
|
13
|
+
status: 'inactive',
|
|
14
|
+
isBackordered: variant.inventoryProperties.backOrdered,
|
|
15
|
+
backorderedAvailableDate: moment(variant.inventoryProperties.expectedBackOrderAvailabilityDate).format(dateFormat)
|
|
16
|
+
}
|
|
17
|
+
} else if(properties.productStatus) {
|
|
18
|
+
let isBackordered = false
|
|
19
|
+
let backorderedAvailableDate = null
|
|
20
|
+
if (variant.skuKit) {
|
|
21
|
+
try {
|
|
22
|
+
const latestBODate = Math.min(...variant.skuKit.flatMap(a=>a.sku.map(s=>s.inventoryProperties.expectedBackOrderAvailabilityDate))) || 0
|
|
23
|
+
if (latestBODate) {
|
|
24
|
+
isBackordered = true
|
|
25
|
+
backorderedAvailableDate = moment(Date(latestBODate)).format(dateFormat)
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
backorderedAvailableDate = null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} else if (variant.bundle) {
|
|
32
|
+
try {
|
|
33
|
+
const latestBODate = Math.min(...variant.bundleMandatoryProducts.flatMap(a=>a.sku.map(s=>s.inventoryProperties.expectedBackOrderAvailabilityDate))) || 0
|
|
34
|
+
if (latestBODate) {
|
|
35
|
+
isBackordered = true
|
|
36
|
+
backorderedAvailableDate = moment(Date(latestBODate)).format(dateFormat)
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
backorderedAvailableDate = null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
// changed
|
|
44
|
+
status: 'active',
|
|
45
|
+
isBackordered,
|
|
46
|
+
backorderedAvailableDate
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
// changed
|
|
51
|
+
status: 'active',
|
|
52
|
+
isBackordered: false,
|
|
53
|
+
backorderedAvailableDate: null
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const parsePrice = (variant) => {
|
|
58
|
+
const price = {}
|
|
59
|
+
const points = {}
|
|
60
|
+
price.currencyCode = (variant.prices || [])?.[0]?.currencyCode || (variant?.prices || [])?.[0]?.currencySymbol
|
|
61
|
+
const priceFacets = variant?.priceFacets || {}
|
|
62
|
+
price.retail = priceFacets['Regular Price'] || ((variant?.prices || [])[0] || {}).price
|
|
63
|
+
price.wholesale = priceFacets['Wholesale Price'] || ((variant?.prices || [])[0] || {}).price
|
|
64
|
+
price.retailSubscription = priceFacets['Regular Price'] || ((variant?.prices || [])[0] || {}).price
|
|
65
|
+
price.wholesaleSubscription = priceFacets['Wholesale Price'] || ((variant?.prices || [])[0] || {}).price
|
|
66
|
+
points.wholesale = {cv: priceFacets.CV, pv: priceFacets.PV, sb: priceFacets.SB}
|
|
67
|
+
// Where do we pull subscription price/points from?
|
|
68
|
+
points.subscription = {cv: priceFacets.CV, pv: priceFacets.PV, sb: priceFacets.SB}
|
|
69
|
+
return {price, points}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const parseKitAvailableQuantity = (skuKit) => {
|
|
73
|
+
try {
|
|
74
|
+
return Math.min(...skuKit.flatMap(a=>a.sku.map(s=>s.inventoryProperties.atpQty))) || 0
|
|
75
|
+
} catch {
|
|
76
|
+
return 0
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const parseBundleAvailableQuantity = (product) => {
|
|
81
|
+
try {
|
|
82
|
+
const {requiredProducts = []} = product|| {}
|
|
83
|
+
const quantities = requiredProducts?.map(p => p?.quantity || 0)
|
|
84
|
+
return Math.min(...quantities) || 0
|
|
85
|
+
} catch {
|
|
86
|
+
console.log("some error in availableQuantity")
|
|
87
|
+
return 0
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const parseKit = (product, market) => {
|
|
92
|
+
const kits = {}
|
|
93
|
+
const [properties] = product || []
|
|
94
|
+
kits.description = properties?.description
|
|
95
|
+
kits.availableChannels = properties.availableChannels
|
|
96
|
+
kits.chargeShipping = properties.chargeShipping === 'true'
|
|
97
|
+
kits.customerTypes = properties.customerTypes
|
|
98
|
+
kits.dangerousGoods = properties.dangerousGoods === 'true'
|
|
99
|
+
// missing
|
|
100
|
+
kits.excludeFromSearch = properties.excludeFromSearch === 'true'
|
|
101
|
+
kits.isExclusive = properties.isExclusive === 'true'
|
|
102
|
+
kits.marketAttributes = properties?.marketAttributes
|
|
103
|
+
kits.maxQuantity = (product.inventoryProperties || {}).atpQty
|
|
104
|
+
const priceData = parsePrice(product)
|
|
105
|
+
kits.points = priceData?.points
|
|
106
|
+
kits.price = priceData?.price
|
|
107
|
+
kits.purchaseTypes = {
|
|
108
|
+
buyOnce: kits?.availableChannels?.includes('web'),
|
|
109
|
+
subscription: kits?.availableChannels?.includes('subscription')
|
|
110
|
+
}
|
|
111
|
+
kits.retailDiscount= properties?.retailDiscount
|
|
112
|
+
kits.wholesaleDiscount = properties?.wholesaleDiscount
|
|
113
|
+
kits.pvDiscount = properties?.pvDiscount
|
|
114
|
+
kits.cvDiscount = properties?.cvDiscount
|
|
115
|
+
kits.sbDiscount = properties?.sbDiscount
|
|
116
|
+
kits.grpDiscount = properties?.grpDiscount
|
|
117
|
+
kits.scanQualifiedCount = properties?.scanQualifiedCount
|
|
118
|
+
// newVariant.slug = undefined
|
|
119
|
+
kits.status = parseStatus(product)
|
|
120
|
+
if ((kits.status || {}).status === 'active') kits.status.status = 'sellable'
|
|
121
|
+
const kitProducts = []
|
|
122
|
+
if (properties.type === 'kit') {
|
|
123
|
+
kits.type = 'skuKit'
|
|
124
|
+
kits.availableQuantity = parseKitAvailableQuantity(product.skuKit)
|
|
125
|
+
for (const kit of product.skuKit) {
|
|
126
|
+
const kitProduct = formatKit(kit, market)
|
|
127
|
+
kitProduct.id = kit.identifier
|
|
128
|
+
kitProducts.push({product: kitProduct, quantity: (kit.properties || {}).quantity || 0, isMandatory:true})
|
|
129
|
+
}
|
|
130
|
+
} else if (properties.type === 'bundle') {
|
|
131
|
+
kits.type = 'bundle'
|
|
132
|
+
kits.availableQuantity = parseBundleAvailableQuantity(properties)
|
|
133
|
+
for (const kit of properties?.requiredProducts || []) {
|
|
134
|
+
const kitProduct = formatKit(kit?.product, market)
|
|
135
|
+
kitProduct.id = kit.product.id
|
|
136
|
+
kitProducts.push({product: kitProduct, quantity: kit?.quantity || 0, isMandatory:true})
|
|
137
|
+
}
|
|
138
|
+
for (const kit of properties?.optionalProducts || []) {
|
|
139
|
+
const kitProduct = formatKit(kit?.product, market)
|
|
140
|
+
kitProduct.id = kit.product.id
|
|
141
|
+
kitProducts.push({product: kitProduct, quantity: kit?.quantity || 0, isMandatory:false})
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
kits.kitProducts = kitProducts
|
|
145
|
+
return kits
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const formatKit = (product, market) => {
|
|
149
|
+
|
|
150
|
+
if (!product) {
|
|
151
|
+
return {}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let kit = null
|
|
155
|
+
if(['kit', 'bundle'].includes(product.type)) {
|
|
156
|
+
kit = parseKit(product.bundle, market)
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
...product,
|
|
160
|
+
bundle: kit
|
|
161
|
+
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
module.exports = {
|
|
167
|
+
formatKit
|
|
168
|
+
}
|
|
169
|
+
|
package/src/formatProduct.js
CHANGED
|
@@ -1,77 +1,83 @@
|
|
|
1
1
|
const helpers = require('./helpers')
|
|
2
2
|
const entities = require('entities')
|
|
3
|
+
const { formatKit } = require('./formatKit')
|
|
3
4
|
|
|
4
5
|
/* istanbul ignore next */
|
|
5
|
-
const formatProduct = (parent, homeUrl) =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
displayName:
|
|
36
|
-
id:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
parent.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
?.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
6
|
+
const formatProduct = (parent, homeUrl) => {
|
|
7
|
+
const formatedProduct = {
|
|
8
|
+
// Each value is a function with a parameter 'parent' that is the current instance of a Product
|
|
9
|
+
// ContentStack references need to be queried separately (ie: variants)
|
|
10
|
+
id: parent.uid,
|
|
11
|
+
slug: parent?.seo_information?.slug,
|
|
12
|
+
variantSelectLabel: parent.variant_select_label,
|
|
13
|
+
secondaryTitle: parent.secondary_title,
|
|
14
|
+
title: parent.name,
|
|
15
|
+
productImages: helpers?.getProductImages(parent),
|
|
16
|
+
salesLabel: parent.sales_label,
|
|
17
|
+
salesText: parent.sales_text,
|
|
18
|
+
description: entities.decodeHTML(parent.short_description || ''),
|
|
19
|
+
salesDisclaimer: helpers?.mapSalesDisclaimer(parent.sales_disclaimer),
|
|
20
|
+
features: helpers?.mapFeatures(parent),
|
|
21
|
+
productDetails: helpers?.mapProductDetails(parent),
|
|
22
|
+
benefitsMedia: {
|
|
23
|
+
image: helpers?.mapImage(parent.benefits_media?.image),
|
|
24
|
+
youTubeVideoId: parent.benefits_media?.youtube_video_id
|
|
25
|
+
},
|
|
26
|
+
benefits: helpers?.mapBenefits(parent),
|
|
27
|
+
benefitsAndFeatures: helpers?.mapBenefitsAndFeatures(parent),
|
|
28
|
+
bundle: parent?.bundle,
|
|
29
|
+
type: parent?.type,
|
|
30
|
+
results: helpers?.mapResults(parent),
|
|
31
|
+
sustainability: helpers?.mapSustainability(parent),
|
|
32
|
+
usage: helpers?.mapUsage(parent, parent.legacy_usage),
|
|
33
|
+
resources: helpers?.mapResources(parent),
|
|
34
|
+
faqs: helpers?.mapFaqs(parent),
|
|
35
|
+
categories: parent.categories?.map((category) => ({
|
|
36
|
+
displayName: category.display_name,
|
|
37
|
+
id: category.category_id,
|
|
38
|
+
subcategories: category.subcategories?.map((subcategory) => ({
|
|
39
|
+
displayName: subcategory.display_name,
|
|
40
|
+
id: subcategory.category_id
|
|
41
|
+
}))
|
|
42
|
+
})),
|
|
43
|
+
ingredients: helpers?.mapIngredients(
|
|
44
|
+
parent.ingredients,
|
|
45
|
+
parent.legacy_ingredients
|
|
46
|
+
),
|
|
47
|
+
legacyBenefits: parent.legacy_benefits,
|
|
48
|
+
legacyLongDescription: parent.legacy_long_description,
|
|
49
|
+
legacyResources: parent.legacy_resources,
|
|
50
|
+
legacyUsage: parent.legacy_usage,
|
|
51
|
+
legacyIngredients: parent.legacy_ingredients,
|
|
52
|
+
legacyImages: parent.legacy_images || [],
|
|
53
|
+
legacyYouTube: parent.legacy_youtube_video,
|
|
54
|
+
disclaimers: parent.disclaimers || [],
|
|
55
|
+
disclaimerWarnings: helpers?.mapDisclaimerWarnings(
|
|
56
|
+
parent.disclaimer_warnings
|
|
57
|
+
),
|
|
58
|
+
seoInformation: helpers?.mapSeoInformation(parent, homeUrl),
|
|
59
|
+
variants: helpers?.mapVariants(parent),
|
|
60
|
+
refund: helpers?.mapRefund(parent),
|
|
61
|
+
shipping: helpers?.mapShipping(parent),
|
|
62
|
+
generalDisclaimer: parent.translations?.general_disclaimer_text,
|
|
63
|
+
thirdPartyScripts: parent.third_party_scripts
|
|
64
|
+
?.filter((tps) => tps.enabled && !!tps.script)
|
|
65
|
+
?.map((tps) => tps.script),
|
|
66
|
+
csAtts: {
|
|
67
|
+
version: parent._version || 0,
|
|
68
|
+
updatedAt: parent.updated_at || '',
|
|
69
|
+
updatedBy: parent.updated_by || '',
|
|
70
|
+
createdAt: parent.created_at || '',
|
|
71
|
+
createdBy: parent.created_by || '',
|
|
72
|
+
locale: parent.locale || ''
|
|
73
|
+
},
|
|
74
|
+
relevancyRank: parent.relevancy_rank || null,
|
|
75
|
+
warranty: helpers?.mapWarranty(parent),
|
|
76
|
+
upSellProductIds: helpers?.mapUpSellProductIds(parent),
|
|
77
|
+
crossProductIds: helpers?.mapCrossProductIds(parent)
|
|
78
|
+
}
|
|
79
|
+
return formatKit(formatedProduct)
|
|
80
|
+
}
|
|
75
81
|
|
|
76
82
|
module.exports = {
|
|
77
83
|
formatProduct
|
package/src/helpers.js
CHANGED
|
@@ -21,7 +21,7 @@ function mapBrandStyle(feature, type) {
|
|
|
21
21
|
const isBrandStyle = feature.brand_style && Array.isArray(feature.brand_style) && feature.brand_style.length > 0;
|
|
22
22
|
// eslint-disable-next-line no-nested-ternary
|
|
23
23
|
const backgroundColor = isBrandStyle ? feature.brand_style[0].background_color : feature.background_color.length > 1 ? feature.background_color : '#4f4d4d';
|
|
24
|
-
const textColor = isBrandStyle && feature.brand_style[0].background_color
|
|
24
|
+
const textColor = isBrandStyle && feature.brand_style[0].background_color?.length > 0 ? '#000000' : '#ffffff';
|
|
25
25
|
|
|
26
26
|
switch (type) {
|
|
27
27
|
case TEXT_COLOR:
|
|
@@ -30,7 +30,7 @@ function mapBrandStyle(feature, type) {
|
|
|
30
30
|
}
|
|
31
31
|
return textColor;
|
|
32
32
|
case BACKGROUND_COLOR:
|
|
33
|
-
if (!backgroundColor
|
|
33
|
+
if (!backgroundColor?.includes('#')) {
|
|
34
34
|
return `#${backgroundColor}`
|
|
35
35
|
}
|
|
36
36
|
return backgroundColor;
|
|
@@ -313,7 +313,7 @@ function mapVariants(parent) {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
function mapSeoInformation(parent, homeUrl) {
|
|
316
|
-
const { ogImage } = parent
|
|
316
|
+
const { ogImage } = parent?.seo_information || {}
|
|
317
317
|
const seoData = {
|
|
318
318
|
metaTitle: parent?.seo_information?.meta_title || parent.name,
|
|
319
319
|
metaDescription:
|
package/src/transformBundle.js
CHANGED