mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
Updated Saleor Provider (#356)
* Initial work, copied from the Shopify provider * Added basis setup and type generation for the products queries * refactor: adjust the types * task: relax the Node.js constraint * fix: page/product properties * disable unknown fields * mention Saleor in the README * setup debugging for Next.js * Check nextjs-commerce bug if no images are added for a product * fix: client/server pecularities for env visibility Must prefix with `NEXT_PUBLIC_` so that the API URL is visible on the client * re: make search work with Saleor API (WIP) * task: update deps * task: move to Webpack 5.x * saleor: initial cart integration * update deps * saleor: shall the cart appear! * task: remove deprecated packages * saleor: adding/removing from the cart * saleor: preliminary signup process * saleor: fix the prices in the cart * update deps * update deps * Added the options for a variant to the product page * Mapped options to variants * Mapped options to variants * saleor: refine the auth process * saleor: remove unused code * saleor: handle customer find via refresh temporary solution * saleor: update deps * saleor: fix the session handling * saleor: fix the variants * saleor: simplify the naming for GraphQL statements * saleor: fix the type for collection * saleor: arrange the error codes * saleor: integrate collections * saleor: fix product sorting * saleor: set cookie location * saleor: update the schema * saleor: attach checkout to customer * saleor: fix the checkout flow * saleor: unify GraphQL naming approach * task: update deps * Add the env variables for saleor to the template * task: prettier * saleor: stub API for build/typescript compilation thanks @cond0r * task: temporarily disable for the `build` * saleor: refactor GraphQL queries * saleor: adjust the config * task: update dependencies * revert: Next.js to `10.0.9` * saleor: fix the checkout fetch query * task: update dependencies * saleor: adapt for displaying featured products * saleor: update the provider structure * saleor: make the home page representable * feature/cart: display the variant name (cond) Co-authored-by: Patryk Zawadzki <patrys@room-303.com> Co-authored-by: royderks <10717410+royderks@users.noreply.github.com>
This commit is contained in:
133
framework/saleor/utils/normalize.ts
Normal file
133
framework/saleor/utils/normalize.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
import { Product } from '@commerce/types/product'
|
||||
|
||||
import { Product as SaleorProduct, Checkout, CheckoutLine, Money, ProductVariant } from '../schema'
|
||||
|
||||
import type { Cart, LineItem } from '../types'
|
||||
|
||||
// TODO: Check nextjs-commerce bug if no images are added for a product
|
||||
const placeholderImg = '/product-img-placeholder.svg'
|
||||
|
||||
const money = ({ amount, currency }: Money) => {
|
||||
return {
|
||||
value: +amount,
|
||||
currencyCode: currency || 'USD',
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeProductOptions = (options: ProductVariant[]) => {
|
||||
return options
|
||||
?.map((option) => option?.attributes)
|
||||
.flat(1)
|
||||
.reduce<any>((acc, x) => {
|
||||
if (acc.find(({ displayName }: any) => displayName === x.attribute.name)) {
|
||||
return acc.map((opt: any) => {
|
||||
return opt.displayName === x.attribute.name
|
||||
? {
|
||||
...opt,
|
||||
values: [
|
||||
...opt.values,
|
||||
...x.values.map((value: any) => ({
|
||||
label: value?.name,
|
||||
})),
|
||||
],
|
||||
}
|
||||
: opt
|
||||
})
|
||||
}
|
||||
|
||||
return acc.concat({
|
||||
__typename: 'MultipleChoiceOption',
|
||||
displayName: x.attribute.name,
|
||||
variant: 'size',
|
||||
values: x.values.map((value: any) => ({
|
||||
label: value?.name,
|
||||
})),
|
||||
})
|
||||
}, [])
|
||||
}
|
||||
|
||||
const normalizeProductVariants = (variants: ProductVariant[]) => {
|
||||
return variants?.map((variant) => {
|
||||
const { id, sku, name, pricing } = variant
|
||||
const price = pricing?.price?.net && money(pricing.price.net)?.value
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
sku: sku ?? id,
|
||||
price,
|
||||
listPrice: price,
|
||||
requiresShipping: true,
|
||||
options: normalizeProductOptions([variant]),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function normalizeProduct(productNode: SaleorProduct): Product {
|
||||
const { id, name, media = [], variants, description, slug, pricing, ...rest } = productNode
|
||||
|
||||
const product = {
|
||||
id,
|
||||
name,
|
||||
vendor: '',
|
||||
description: description ? JSON.parse(description)?.blocks[0]?.data.text : '',
|
||||
path: `/${slug}`,
|
||||
slug: slug?.replace(/^\/+|\/+$/g, ''),
|
||||
price: (pricing?.priceRange?.start?.net && money(pricing.priceRange.start.net)) || {
|
||||
value: 0,
|
||||
currencyCode: 'USD',
|
||||
},
|
||||
// TODO: Check nextjs-commerce bug if no images are added for a product
|
||||
images: media?.length ? media : [{ url: placeholderImg }],
|
||||
variants: variants && variants.length > 0 ? normalizeProductVariants(variants as ProductVariant[]) : [],
|
||||
options: variants && variants.length > 0 ? normalizeProductOptions(variants as ProductVariant[]) : [],
|
||||
...rest,
|
||||
}
|
||||
|
||||
return product as Product
|
||||
}
|
||||
|
||||
export function normalizeCart(checkout: Checkout): Cart {
|
||||
const lines = checkout.lines as CheckoutLine[]
|
||||
const lineItems: LineItem[] = lines.length > 0 ? lines?.map<LineItem>(normalizeLineItem) : []
|
||||
|
||||
return {
|
||||
id: checkout.id,
|
||||
customerId: '',
|
||||
email: '',
|
||||
createdAt: checkout.created,
|
||||
currency: {
|
||||
code: checkout.totalPrice?.currency!,
|
||||
},
|
||||
taxesIncluded: false,
|
||||
lineItems,
|
||||
lineItemsSubtotalPrice: checkout.subtotalPrice?.gross?.amount!,
|
||||
subtotalPrice: checkout.subtotalPrice?.gross?.amount!,
|
||||
totalPrice: checkout.totalPrice?.gross.amount!,
|
||||
discounts: [],
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeLineItem({ id, variant, quantity }: CheckoutLine): LineItem {
|
||||
return {
|
||||
id,
|
||||
variantId: String(variant?.id),
|
||||
productId: String(variant?.id),
|
||||
name: `${variant.product.name}`,
|
||||
quantity,
|
||||
variant: {
|
||||
id: String(variant?.id),
|
||||
sku: variant?.sku ?? '',
|
||||
name: variant?.name!,
|
||||
image: {
|
||||
url: variant?.media![0] ? variant?.media![0].url : placeholderImg,
|
||||
},
|
||||
requiresShipping: false,
|
||||
price: variant?.pricing?.price?.gross.amount!,
|
||||
listPrice: 0,
|
||||
},
|
||||
path: String(variant?.product?.slug),
|
||||
discounts: [],
|
||||
options: [],
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user