4
0
forked from crowetic/commerce
Jakub Neander 3b2bf654fe
Updated Saleor Provider ()
* 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>
2021-06-10 01:46:28 -05:00

134 lines
3.8 KiB
TypeScript

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: [],
}
}