commerce/framework/swell/utils/normalize.ts
2021-04-18 19:33:23 -05:00

195 lines
4.0 KiB
TypeScript

import { Product } from '@commerce/types'
import { Customer } from '@commerce/types'
import { fileURLToPath } from 'node:url'
import {
Product as ShopifyProduct,
Checkout,
CheckoutLineItemEdge,
SelectedOption,
ImageConnection,
ProductVariantConnection,
MoneyV2,
ProductOption,
} from '../schema'
import type { Cart, LineItem, SwellCustomer, SwellProduct } from '../types'
const money = ({ amount, currencyCode }: MoneyV2) => {
return {
value: +amount,
currencyCode,
}
}
const normalizeProductOption = ({
id,
name: displayName,
values,
}: ProductOption) => {
let returnValues = values.map((value) => {
let output: any = {
displayName,
label: value.name,
}
if (displayName === 'Color') {
output = {
...output,
hexColors: [value.name],
}
}
return output
})
return {
__typename: 'MultipleChoiceOption',
id,
displayName,
values: returnValues,
}
}
type SwellImage = {
file: {
url: String
height: Number
width: Number
}
id: string
}
const normalizeProductImages = (images) => {
if (!images) {
return [{ url: '/' }]
}
return images?.map(({ file, ...rest }: SwellImage) => ({
url: file?.url,
height: file?.height,
width: file?.width,
...rest,
}))
}
const normalizeProductVariants = (variants) => {
return variants?.map(({ id, name, price, sku }) => {
const values = name
.split(',')
.map((i) => ({ name: i.trim(), label: i.trim() }))
const options = values.map((value) => {
return normalizeProductOption({
id,
name,
values: [value],
})
})
return {
id,
name,
sku: sku ?? id,
price: price ?? null,
listPrice: price ?? null,
// requiresShipping: true,
options,
}
})
}
export function normalizeProduct(swellProduct: SwellProduct): Product {
const {
id,
description,
images,
options,
slug,
variants,
price: value,
currency: currencyCode,
} = swellProduct
const productOptions = options
? options.map((o) => normalizeProductOption(o))
: []
const productVariants = variants ? normalizeProductVariants(variants) : []
// ProductView.tsx assumes the existence of at least one product variant
const emptyVariants = [{ options: [{ id: 123 }] }]
const productImages = normalizeProductImages(images)
const product = {
...swellProduct,
description,
id,
vendor: '',
path: `/${slug}`,
images: productImages,
variants:
productVariants && productVariants.length
? productVariants
: emptyVariants,
options: productOptions,
price: {
value,
currencyCode,
},
}
return product
}
export function normalizeCart(cart: Checkout): Cart {
return {
id: cart.id,
customerId: cart.account_id,
email: '',
createdAt: cart.date_created,
currency: cart.currency,
taxesIncluded: cart.tax_included_total,
lineItems: cart.items?.map(normalizeLineItem),
lineItemsSubtotalPrice: +cart.sub_total,
subtotalPrice: +cart.sub_total,
totalPrice: cart.grand_total,
discounts: cart.discounts,
}
}
export function normalizeCustomer(customer: SwellCustomer): Customer {
const { first_name: firstName, last_name: lastName } = customer
return {
...customer,
firstName,
lastName,
}
}
function normalizeLineItem({
id,
product,
price,
variant,
quantity,
}: CheckoutLineItemEdge): LineItem {
const item = {
id,
variantId: String(variant?.id),
productId: String(product?.id),
name: product?.name ?? '',
quantity,
variant: {
id: String(variant?.id),
sku: variant?.sku ?? '',
name: variant?.name!,
image: {
url: product && product.images ? product?.images[0].file.url : '',
},
requiresShipping: false,
price: price,
listPrice: price,
},
path: '',
discounts: [],
options: [
{
value: variant?.name,
},
],
}
return item
}