mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 15:36:58 +00:00
fix types for normalize products
This commit is contained in:
parent
49bd38fd82
commit
d614e817c6
@ -5,7 +5,6 @@ export interface CommerceAPIConfig {
|
||||
commerceUrl: string
|
||||
apiToken: string
|
||||
cartCookie: string
|
||||
cartIdCookie: string
|
||||
cartCookieMaxAge: number
|
||||
customerCookie: string
|
||||
fetch<Data = any, Variables = any>(
|
||||
|
@ -1,2 +1,2 @@
|
||||
SHOPIFY_STORE_DOMAIN=
|
||||
SHOPIFY_STOREFRONT_ACCESS_TOKEN=
|
||||
REACTION_STORE_DOMAIN=
|
||||
REACTION_SHOP_ID=
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
|
||||
REACTION_CART_ID_COOKIE,
|
||||
REACTION_EMPTY_DUMMY_CART_ID,
|
||||
SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||
SHOPIFY_COOKIE_EXPIRE,
|
||||
REACTION_CUSTOMER_TOKEN_COOKIE,
|
||||
REACTION_COOKIE_EXPIRE,
|
||||
SHOP_ID,
|
||||
} from '../const'
|
||||
|
||||
@ -18,7 +18,11 @@ if (!API_URL) {
|
||||
|
||||
import fetchGraphqlApi from './utils/fetch-graphql-api'
|
||||
|
||||
export interface ReactionCommerceConfig extends CommerceAPIConfig {}
|
||||
export interface ReactionCommerceConfig extends CommerceAPIConfig {
|
||||
shopId: string
|
||||
cartIdCookie: string
|
||||
dummyEmptyCartId: string
|
||||
}
|
||||
|
||||
export class Config {
|
||||
private config: ReactionCommerceConfig
|
||||
@ -42,12 +46,13 @@ export class Config {
|
||||
const config = new Config({
|
||||
locale: 'en-US',
|
||||
commerceUrl: API_URL,
|
||||
apiToken: '',
|
||||
cartCookie: REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
|
||||
cartIdCookie: REACTION_CART_ID_COOKIE,
|
||||
dummyEmptyCartId: REACTION_EMPTY_DUMMY_CART_ID,
|
||||
cartCookieMaxAge: SHOPIFY_COOKIE_EXPIRE,
|
||||
cartCookieMaxAge: REACTION_COOKIE_EXPIRE,
|
||||
fetch: fetchGraphqlApi,
|
||||
customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||
customerCookie: REACTION_CUSTOMER_TOKEN_COOKIE,
|
||||
shopId: SHOP_ID,
|
||||
})
|
||||
|
||||
|
@ -1,18 +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 SHOPIFY_CHECKOUT_URL_COOKIE = 'shopify_checkoutUrl'
|
||||
export const STORE_DOMAIN = process.env.NEXT_PUBLIC_REACTION_STORE_DOMAIN
|
||||
|
||||
export const SHOPIFY_CUSTOMER_TOKEN_COOKIE = 'shopify_customerToken'
|
||||
export const REACTION_COOKIE_EXPIRE = 30
|
||||
|
||||
export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN
|
||||
export const API_URL = `http://${process.env.REACTION_STORE_DOMAIN}/graphql`
|
||||
|
||||
export const SHOPIFY_COOKIE_EXPIRE = 30
|
||||
|
||||
export const API_URL = `http://127.0.0.1:3000/graphql`
|
||||
|
||||
export const SHOP_ID = 'cmVhY3Rpb24vc2hvcDplcnBESFlDdzc5cFRBV0FHUg=='
|
||||
export const SHOP_ID = process.env.REACTION_SHOP_ID ?? ''
|
||||
|
@ -13,13 +13,17 @@ import { REACTION_ANONYMOUS_CART_TOKEN_COOKIE, SHOP_ID } from './const'
|
||||
export { reactionCommerceProvider }
|
||||
export type { ReactionCommerceProvider }
|
||||
|
||||
export const reactionCommerceConfig: CommerceConfig = {
|
||||
type ReactionConfig = CommerceConfig & {
|
||||
shopId: string
|
||||
}
|
||||
|
||||
export const reactionCommerceConfig: ReactionConfig = {
|
||||
locale: 'en-us',
|
||||
cartCookie: REACTION_ANONYMOUS_CART_TOKEN_COOKIE,
|
||||
shopId: SHOP_ID,
|
||||
}
|
||||
|
||||
export type ReactionCommerceConfig = Partial<CommerceConfig>
|
||||
export type ReactionCommerceConfig = Partial<ReactionConfig>
|
||||
|
||||
export type ReactionCommerceProps = {
|
||||
children?: ReactNode
|
||||
|
@ -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 } from '../utils/queries'
|
||||
import { normalizeProduct } from '../utils/normalize'
|
||||
import { Product } from '@commerce/types'
|
||||
@ -30,8 +30,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 {
|
||||
|
@ -1,20 +1,24 @@
|
||||
import Cookies, { CookieAttributes } from 'js-cookie'
|
||||
import { SHOPIFY_COOKIE_EXPIRE, SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const'
|
||||
import {
|
||||
REACTION_COOKIE_EXPIRE,
|
||||
REACTION_CUSTOMER_TOKEN_COOKIE,
|
||||
} from '../const'
|
||||
|
||||
export const getCustomerToken = () => Cookies.get(SHOPIFY_CUSTOMER_TOKEN_COOKIE)
|
||||
export const getCustomerToken = () =>
|
||||
Cookies.get(REACTION_CUSTOMER_TOKEN_COOKIE)
|
||||
|
||||
export const setCustomerToken = (
|
||||
token: string | null,
|
||||
options?: CookieAttributes
|
||||
) => {
|
||||
if (!token) {
|
||||
Cookies.remove(SHOPIFY_CUSTOMER_TOKEN_COOKIE)
|
||||
Cookies.remove(REACTION_CUSTOMER_TOKEN_COOKIE)
|
||||
} else {
|
||||
Cookies.set(
|
||||
SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||
REACTION_CUSTOMER_TOKEN_COOKIE,
|
||||
token,
|
||||
options ?? {
|
||||
expires: SHOPIFY_COOKIE_EXPIRE,
|
||||
expires: REACTION_COOKIE_EXPIRE,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1,26 +1,38 @@
|
||||
import { Product } from '@commerce/types'
|
||||
|
||||
import {
|
||||
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,
|
||||
@ -29,7 +41,7 @@ const normalizeProductOption = ({
|
||||
let output: any = {
|
||||
label: value,
|
||||
}
|
||||
if (displayName === 'Color') {
|
||||
if (displayName.toLowerCase() === 'color') {
|
||||
output = {
|
||||
...output,
|
||||
hexColors: [value],
|
||||
@ -40,53 +52,39 @@ const normalizeProductOption = ({
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeProductVariants = (variants: [CatalogProductVariant]) => {
|
||||
return variants?.map(
|
||||
({
|
||||
variantId,
|
||||
attributeLabel,
|
||||
optionTitle,
|
||||
options,
|
||||
sku,
|
||||
title,
|
||||
pricing,
|
||||
}) => {
|
||||
const variantPrice = pricing[0]?.price ?? pricing[0]?.minPrice
|
||||
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,
|
||||
name: title,
|
||||
sku: sku ?? variantId,
|
||||
price: variantPrice,
|
||||
listPrice: pricing[0]?.compareAtPrice?.amount ?? variantPrice,
|
||||
requiresShipping: true,
|
||||
// options: options?.map(({ attributeLabel, optionTitle }: CatalogProductVariant) =>
|
||||
// normalizeProductOption({
|
||||
// id: _id,
|
||||
// name: attributeLabel,
|
||||
// values: [optionTitle],
|
||||
// })
|
||||
// ) ?? [],
|
||||
options: [
|
||||
{
|
||||
__typename: 'MultipleChoiceOption',
|
||||
displayName: attributeLabel,
|
||||
values: [{ label: optionTitle }],
|
||||
},
|
||||
],
|
||||
}
|
||||
return {
|
||||
id: _id ?? '',
|
||||
name: title,
|
||||
sku: sku ?? variantId,
|
||||
price: variantPrice,
|
||||
listPrice: pricing[0]?.compareAtPrice?.amount ?? variantPrice,
|
||||
requiresShipping: true,
|
||||
options: options?.length
|
||||
? options.map((option) => {
|
||||
return normalizeProductOption({
|
||||
id: option?._id ?? '',
|
||||
displayName: option?.attributeLabel ?? '',
|
||||
values: [option?.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()
|
||||
)
|
||||
})
|
||||
|
||||
@ -94,68 +92,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,
|
||||
description,
|
||||
title: name,
|
||||
vendor,
|
||||
pricing,
|
||||
slug,
|
||||
primaryImage,
|
||||
variants,
|
||||
},
|
||||
...rest
|
||||
} = productNode
|
||||
|
||||
const product = {
|
||||
id: productId ?? _id,
|
||||
name,
|
||||
vendor,
|
||||
productId,
|
||||
title,
|
||||
description,
|
||||
path: `/${slug}`,
|
||||
slug: slug?.replace(/^\/+|\/+$/g, ''),
|
||||
slug,
|
||||
sku,
|
||||
media,
|
||||
pricing,
|
||||
vendor,
|
||||
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 {
|
||||
|
@ -29,7 +29,7 @@ edges {
|
||||
minPrice
|
||||
maxPrice
|
||||
}
|
||||
primaryImage {
|
||||
media {
|
||||
URLs {
|
||||
thumbnail
|
||||
small
|
||||
|
Loading…
x
Reference in New Issue
Block a user