import { Product } from '@commerce/types' import { Customer } from '@commerce/types' import { Product as ShopifyProduct, Checkout, CheckoutLineItemEdge, SelectedOption, ImageConnection, ProductVariantConnection, MoneyV2, ProductOption, } from '../schema' import type { Cart, LineItem, SwellCustomer } from '../types' const money = ({ amount, currencyCode }: MoneyV2) => { return { value: +amount, currencyCode, } } const normalizeProductOption = ({ id, name: displayName, values, }: ProductOption) => { return { __typename: 'MultipleChoiceOption', id, displayName, values: values.map((value) => { let output: any = { label: value, } if (displayName === 'Color') { output = { ...output, hexColors: [value], } } return output }), } } const normalizeProductImages = ({ edges }: ImageConnection) => edges?.map(({ node: { originalSrc: url, ...rest } }) => ({ url, ...rest, })) const normalizeProductVariants = ({ edges }: ProductVariantConnection) => { return edges?.map( ({ node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 }, }) => ({ id, name: title, sku: sku ?? id, price: +priceV2.amount, listPrice: +compareAtPriceV2?.amount, requiresShipping: true, options: selectedOptions.map(({ name, value }: SelectedOption) => normalizeProductOption({ id, name, values: [value], }) ), }) ) } export function normalizeProduct(productNode: ShopifyProduct): Product { const { id, title: name, vendor, images, variants, description, handle, priceRange, options, ...rest } = productNode const product = { id, name, vendor, description, path: `/${handle}`, slug: handle?.replace(/^\/+|\/+$/g, ''), price: money(priceRange?.minVariantPrice), images: normalizeProductImages(images), variants: variants ? normalizeProductVariants(variants) : [], options: options ? options.map((o) => normalizeProductOption(o)) : [], ...rest, } return product } export function normalizeCart(checkout: Checkout): Cart { return { id: checkout.id, customerId: '', email: '', createdAt: checkout.createdAt, currency: { code: checkout.totalPriceV2?.currencyCode, }, taxesIncluded: checkout.taxesIncluded, lineItems: checkout.lineItems?.edges.map(normalizeLineItem), lineItemsSubtotalPrice: +checkout.subtotalPriceV2?.amount, subtotalPrice: +checkout.subtotalPriceV2?.amount, totalPrice: checkout.totalPriceV2?.amount, discounts: [], } } export function normalizeCustomer(customer: SwellCustomer): Customer { const { first_name: firstName, last_name: lastName } = customer return { ...customer, firstName, lastName, } } function normalizeLineItem({ node: { id, title, variant, quantity }, }: CheckoutLineItemEdge): LineItem { return { id, variantId: String(variant?.id), productId: String(variant?.id), name: `${title}`, quantity, variant: { id: String(variant?.id), sku: variant?.sku ?? '', name: variant?.title!, image: { url: variant?.image?.originalSrc, }, requiresShipping: variant?.requiresShipping ?? false, price: variant?.priceV2?.amount, listPrice: variant?.compareAtPriceV2?.amount, }, path: '', discounts: [], options: [ { value: variant?.title, }, ], } }