UNPKG

@nacelle/compatibility-connector

Version:

Connect @nacelle/client-js-sdk to Nacelle's v2 back end with minimal code changes

115 lines (108 loc) 4.39 kB
import { transformMedia } from './transformMedia'; import { transformSourceEntryId } from './transformSourceEntryId'; import type { NacelleProduct, ProductVariant, Media } from '@nacelle/types'; import type { Product } from 'storefrontSdkV1'; export function transformProducts( products: Product[], locale: string ): NacelleProduct[] { return products.map((product: Product) => { const formatPrice = (price: number): string => { if (Number.isInteger(price)) return price.toFixed(1); return price.toString(); }; const hasVariant = Array.isArray(product.variants) && product.variants.length; const variantPrices = hasVariant && product.variants ?.map((variant) => parseFloat(variant.price)) // We provide a sort function here because by default, // "all non-undefined array elements are sorted by // converting them to strings and comparing strings // in UTF-16 code units order." For more details, see: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description .sort((a, b) => a - b) .map((price) => formatPrice(price)); const priceCurrency = hasVariant ? product.variants[0]?.priceCurrency : null; return { availableForSale: product.availableForSale as boolean, createdAt: product.createdAt as number, description: product.content?.description || null, featuredMedia: transformMedia(product.content?.featuredMedia), globalHandle: product.content?.handle ? `${product.content?.handle}::${locale}` : '', handle: product.content?.handle || '', id: product.nacelleEntryId, indexedAt: product.indexedAt as number, locale, media: product.content?.media?.map( (media) => transformMedia(media) as Media ) || null, metafields: product.metafields, pimSyncSource: '', pimSyncSourceDomain: '', pimSyncSourceProductId: transformSourceEntryId(product.sourceEntryId), priceRange: Array.isArray(variantPrices) ? { min: variantPrices[0], max: variantPrices[variantPrices.length - 1], currencyCode: priceCurrency } : null, productType: product.productType, tags: product.tags, title: product.content?.title || null, updatedAt: product.updatedAt, vendor: product.vendor, variants: product.variants?.map((variant): ProductVariant => { const transformedVariant: ProductVariant = { availableForSale: variant.availableForSale, compareAtPrice: variant.compareAtPrice && formatPrice(Number(variant.compareAtPrice)), compareAtPriceCurrency: variant.compareAtPrice && formatPrice(Number(variant.compareAtPrice)), featuredMedia: transformMedia(variant.content?.featuredMedia), id: transformSourceEntryId(variant.sourceEntryId), metafields: variant.metafields, price: formatPrice(Number(variant.price)), priceCurrency: variant.priceCurrency, priceRules: Array.isArray(variant.priceRules) && variant.priceRules.length ? variant.priceRules?.map((priceRule) => ({ ...priceRule, comparedAtPrice: priceRule.comparedAtPrice ? formatPrice(Number(priceRule.comparedAtPrice)) : null, price: formatPrice(Number(priceRule.price)), priceBreaks: priceRule.priceBreaks && priceRule.priceBreaks.map((priceBreak) => ({ ...priceBreak, price: formatPrice(Number(priceBreak.price)) })) })) : [], quantityAvailable: variant.quantityAvailable, selectedOptions: variant.content?.selectedOptions?.map(({ name, value }) => ({ name, value })) || null, sku: variant.sku, swatchSrc: variant.content?.swatchSrc || null, title: variant.content?.title || null, weight: variant.weight, weightUnit: variant.weightUnit }; return transformedVariant; }) }; }); }