Merge pull request #2 from CristianCucunuba/fix-types

fix types for normalize products
This commit is contained in:
Loan Laux 2021-05-05 17:33:34 +04:00 committed by GitHub
commit b125f9f577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 114 additions and 107 deletions

View File

@ -5,7 +5,6 @@ export interface CommerceAPIConfig {
commerceUrl: string
apiToken: string
cartCookie: string
cartIdCookie: string
cartCookieMaxAge: number
customerCookie: string
fetch<Data = any, Variables = any>(

View File

@ -0,0 +1,2 @@
REACTION_STORE_DOMAIN=
REACTION_SHOP_ID=

View File

@ -18,7 +18,14 @@ if (!API_URL) {
import fetchGraphqlApi from './utils/fetch-graphql-api'
export interface ReactionCommerceConfig extends CommerceAPIConfig {}
export interface ReactionCommerceConfig
extends Omit<CommerceAPIConfig, 'apiToken'> {
shopId: string
cartIdCookie: string
dummyEmptyCartId?: string
anonymousCartTokenCookie?: string
anonymousCartTokenCookieMaxAge?: number
}
export class Config {
private config: ReactionCommerceConfig
@ -42,9 +49,11 @@ export class Config {
const config = new Config({
locale: 'en-US',
commerceUrl: API_URL,
anonymousCartTokenCookie: REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
cartCookie: REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
cartIdCookie: REACTION_CART_ID_COOKIE,
dummyEmptyCartId: REACTION_EMPTY_DUMMY_CART_ID,
cartCookieMaxAge: REACTION_COOKIE_EXPIRE,
anonymousCartTokenCookie: REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
anonymousCartTokenCookieMaxAge: REACTION_COOKIE_EXPIRE,
fetch: fetchGraphqlApi,
customerCookie: REACTION_CUSTOMER_TOKEN_COOKIE,

View File

@ -1,14 +1,16 @@
export const REACTION_ANONYMOUS_CART_TOKEN_COOKIE =
'reaction_anonymousCartToken'
export const REACTION_CUSTOMER_TOKEN_COOKIE = 'reaction_customerToken'
export const REACTION_CART_ID_COOKIE = 'reaction_cartId'
export const REACTION_EMPTY_DUMMY_CART_ID = 'DUMMY_EMPTY_CART_ID'
export const REACTION_CUSTOMER_TOKEN_COOKIE = 'reaction_customerToken'
export const STORE_DOMAIN = process.env.NEXT_PUBLIC_REACTION_STORE_DOMAIN
export const REACTION_COOKIE_EXPIRE = 30
export const API_URL = `http://127.0.0.1:3000/graphql`
export const API_URL = `http://${process.env.REACTION_STORE_DOMAIN}/graphql`
export const SHOP_ID = 'cmVhY3Rpb24vc2hvcDpIZGIycnRYTWVpbVRKbzZrcg=='
export const SHOP_ID = process.env.REACTION_SHOP_ID ?? ''

View File

@ -8,18 +8,28 @@ import {
} from '@commerce'
import { reactionCommerceProvider, ReactionCommerceProvider } from './provider'
import { REACTION_ANONYMOUS_CART_TOKEN_COOKIE, SHOP_ID } from './const'
import {
REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
SHOP_ID,
REACTION_CART_ID_COOKIE,
} from './const'
export { reactionCommerceProvider }
export type { ReactionCommerceProvider }
export const reactionCommerceConfig: CommerceConfig = {
type ReactionConfig = CommerceConfig & {
shopId: string
anonymousCartTokenCookie: string
}
export const reactionCommerceConfig: ReactionConfig = {
locale: 'en-us',
anonymousCartTokenCookie: REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
cartCookie: REACTION_CART_ID_COOKIE,
shopId: SHOP_ID,
}
export type ReactionCommerceConfig = Partial<CommerceConfig>
export type ReactionCommerceConfig = Partial<ReactionConfig>
export type ReactionCommerceProps = {
children?: ReactNode

View File

@ -1,6 +1,6 @@
import { GraphQLFetcherResult } from '@commerce/api'
import { getConfig, ReactionCommerceConfig } from '../api'
import { CatalogItemEdge } from '../schema'
import { CatalogItemEdge, CatalogItemProduct } from '../schema'
import { catalogItemsQuery, normalizeProduct } from '../utils'
import { Product } from '@commerce/types'
@ -10,7 +10,7 @@ type Variables = {
}
type ReturnType = {
products: CatalogItemConnection[]
products: Product[]
}
const getAllProducts = async (options: {
@ -29,8 +29,8 @@ const getAllProducts = async (options: {
})
const catalogItems =
data.catalogItems?.edges?.map(({ node: p }: CatalogItemEdge) =>
normalizeProduct(p)
data.catalogItems?.edges?.map(({ node: itemProduct }: CatalogItemEdge) =>
normalizeProduct(itemProduct as CatalogItemProduct)
) ?? []
return {

View File

@ -1,27 +1,39 @@
import { Customer } from '@commerce/types'
import { Product, Customer } from '@commerce/types'
import {
Account,
CatalogItem,
Cart as ReactionCart,
ProductPricingInfo,
CatalogProductVariant,
CartItemEdge,
CatalogItemProduct,
CatalogProduct,
ImageInfo,
Maybe,
} from '../schema'
import type { Cart, LineItem } from '../types'
type ProductOption = {
__typename?: string
id: string
displayName: string
values: any[]
}
const money = ({ displayPrice }: ProductPricingInfo) => {
return {
displayPrice,
}
}
const normalizeProductOption = ({
id,
name: displayName,
values,
}: ProductOption) => {
const normalizeProductImages = (images: Maybe<ImageInfo>[], name: string) =>
images.map((image) => ({
url: image?.URLs?.original || image?.URLs?.medium || '',
alt: name,
}))
const normalizeProductOption = ({ id, displayName, values }: ProductOption) => {
return {
__typename: 'MultipleChoiceOption',
id,
@ -30,7 +42,7 @@ const normalizeProductOption = ({
let output: any = {
label: value,
}
if (displayName === 'Color') {
if (displayName.toLowerCase() === 'color') {
output = {
...output,
hexColors: [value],
@ -41,59 +53,39 @@ const normalizeProductOption = ({
}
}
const normalizeProductVariants = (variants: [CatalogProductVariant]) => {
return variants?.map(
({
variantId,
attributeLabel,
optionTitle,
options,
sku,
title,
pricing,
}) => {
let variantPrice = pricing[0]?.price ?? pricing[0]?.minPrice
if (variantPrice === undefined) {
variantPrice = 0
}
const normalizeProductVariants = (variants: Maybe<CatalogProductVariant>[]) => {
return variants.map((variant) => {
const { _id, options, sku, title, pricing = [], variantId } = variant ?? {}
const variantPrice = pricing[0]?.price ?? pricing[0]?.minPrice ?? 0
return {
id: variantId,
id: _id ?? '',
name: title,
sku: sku ?? variantId,
price: variantPrice,
listPrice: pricing[0]?.compareAtPrice?.amount ?? variantPrice,
requiresShipping: true,
options:
options?.map(
({ _id, attributeLabel, optionTitle }: CatalogProductVariant) =>
normalizeProductOption({
id: _id,
name: attributeLabel,
values: [optionTitle],
options: options?.length
? options.map((option) => {
return normalizeProductOption({
id: option?._id ?? '',
displayName: option?.attributeLabel ?? '',
values: [option?.optionTitle],
})
) ?? [],
// options: [
// {
// __typename: 'MultipleChoiceOption',
// displayName: attributeLabel,
// values: [{ label: optionTitle }],
// },
// ],
})
: [],
}
}
)
})
}
export function groupProductOptionsByAttributeLabel(
options: [CatalogProductVariant]
options: Maybe<CatalogProductVariant>[]
) {
return options.reduce((groupedOptions, currentOption) => {
const attributeLabelIndex = groupedOptions.findIndex((option) => {
return (
option.displayName.toLowerCase() ===
currentOption.attributeLabel.toLowerCase()
currentOption?.attributeLabel.toLowerCase()
)
})
@ -101,68 +93,61 @@ export function groupProductOptionsByAttributeLabel(
groupedOptions[attributeLabelIndex].values = [
...groupedOptions[attributeLabelIndex].values,
{
label: currentOption.optionTitle,
hexColors: [currentOption.optionTitle],
label: currentOption?.optionTitle ?? '',
hexColors: [currentOption?.optionTitle] ?? '',
},
]
} else {
groupedOptions = [
...groupedOptions,
normalizeProductOption({
id: currentOption.variantId,
name: currentOption.attributeLabel,
values: [currentOption.optionTitle],
id: currentOption?.variantId ?? '',
displayName: currentOption?.attributeLabel ?? '',
values: [currentOption?.optionTitle ?? ''],
}),
]
}
return groupedOptions
}, [])
}, [] as ProductOption[])
}
export function normalizeProduct(productNode: CatalogItemEdge): CatalogItem {
export function normalizeProduct(productNode: CatalogItemProduct): Product {
const product = productNode.product as CatalogProduct
const {
_id,
product: {
productId,
title,
description,
title: name,
vendor,
pricing,
slug,
primaryImage,
variants,
},
...rest
} = productNode
const product = {
id: productId ?? _id,
name,
sku,
media,
pricing,
vendor,
description,
path: `/${slug}`,
slug: slug?.replace(/^\/+|\/+$/g, ''),
variants,
...rest
} = product
return {
id: productId ?? _id,
name: title ?? '',
description: description ?? '',
slug: slug?.replace(/^\/+|\/+$/g, '') ?? '',
path: slug ?? '',
sku: sku ?? '',
images: media?.length ? normalizeProductImages(media, title ?? '') : [],
vendor: product.vendor,
price: {
value: pricing[0].minPrice,
currencyCode: pricing[0].currency.code,
value: pricing[0]?.price ?? 0,
currencyCode: pricing[0]?.currency.code,
},
variants: variants ? normalizeProductVariants(variants) : [],
options: variants ? groupProductOptionsByAttributeLabel(variants) : [],
images: [],
variants: variants?.length ? normalizeProductVariants(variants) : [],
options: variants?.length
? groupProductOptionsByAttributeLabel(variants)
: [],
...rest,
}
if (productNode.product.primaryImage) {
product.images = [
{
url: primaryImage?.URLs?.original,
alt: name,
},
]
}
return product
}
export function normalizeCart(cart: ReactionCart): Cart {

View File

@ -29,7 +29,7 @@ edges {
minPrice
maxPrice
}
primaryImage {
media {
URLs {
thumbnail
small