Add options and variants

This commit is contained in:
goncy 2021-08-12 15:29:58 -03:00
parent 4151865fa2
commit 0c2855a323
3 changed files with 79 additions and 28 deletions

View File

@ -1,7 +1,7 @@
import type { OperationContext } from '@commerce/api/operations' import type { OperationContext } from '@commerce/api/operations'
import type { GetProductOperation } from '@commerce/types/product' import type { GetProductOperation } from '@commerce/types/product'
import type { RawProduct } from '../../types/product' import type { RawProduct, RawSpec, RawVariant } from '../../types/product'
import type { OrdercloudConfig, Provider } from '../index' import type { OrdercloudConfig, Provider } from '../index'
import { normalize as normalizeProduct } from '../../utils/product' import { normalize as normalizeProduct } from '../../utils/product'
@ -22,14 +22,37 @@ export default function getProductOperation({
const { fetch } = commerce.getConfig(config) const { fetch } = commerce.getConfig(config)
// Get a single product // Get a single product
const rawProduct: RawProduct = await fetch<RawProduct>( const productPromise = fetch<RawProduct>(
'GET', 'GET',
`/me/products/${variables?.slug}` `/me/products/${variables?.slug}`
) )
// Get product specs
const specsPromise = fetch<{ Items: RawSpec[] }>(
'GET',
`/me/products/${variables?.slug}/specs`
).then((res) => res.Items)
// Get product variants
const variantsPromise = fetch<{ Items: RawVariant[] }>(
'GET',
`/me/products/${variables?.slug}/variants`
).then((res) => res.Items)
// Execute all promises in parallel
const [product, specs, variants] = await Promise.all([
productPromise,
specsPromise,
variantsPromise,
])
// Hydrate product
product.xp.Specs = specs
product.xp.Variants = variants
return { return {
// Normalize product to commerce schema // Normalize product to commerce schema
product: normalizeProduct(rawProduct), product: normalizeProduct(product),
} }
} }

View File

@ -1,3 +1,27 @@
interface RawVariantSpec {
SpecID: string
Name: string
OptionID: string
Value: string
}
export interface RawSpec {
ID: string
Name: string
Options: {
ID: string
Value: string
xp: {
hexColor?: string
}
}[]
}
export interface RawVariant {
ID: string
Specs: RawVariantSpec[]
}
export interface RawProduct { export interface RawProduct {
OwnerID: string OwnerID: string
DefaultPriceScheduleID: string | null DefaultPriceScheduleID: string | null
@ -23,6 +47,7 @@ export interface RawProduct {
Images: { Images: {
url: string url: string
}[] }[]
Facets: Record<string, string[]> Variants?: RawVariant[]
Specs?: RawSpec[]
} }
} }

View File

@ -13,30 +13,33 @@ export function normalize(product: RawProduct): Product {
value: product.xp.Price, value: product.xp.Price,
currencyCode: product.xp.PriceCurrency, currencyCode: product.xp.PriceCurrency,
}, },
// Variants are not always present, in case they are not, return a single unique variant variants: product.xp.Variants?.length
variants: ? product.xp.Variants.map((variant) => ({
product.VariantCount === 0 id: variant.ID,
? [ options: variant.Specs.map((spec) => ({
{ id: spec.SpecID,
id: 'unique', __typename: 'MultipleChoiceOption',
options: [ displayName: spec.Name,
{ values: [
id: 'unique', {
displayName: 'Unique', label: spec.Value,
values: [{ label: 'Unique' }], },
}, ],
], })),
}, }))
] : [
: [], {
// Facets are not always present, just iterate them if they are id: product.ID,
options: product.xp.Facets options: [],
? Object.entries(product.xp.Facets).map(([key, values]) => ({ },
id: key, ],
displayName: key, options: product.xp.Specs?.length
__typename: 'MultipleChoiceOption', ? product.xp.Specs.map((spec) => ({
values: values.map((value) => ({ id: spec.ID,
label: value, displayName: spec.Name,
values: spec.Options.map((option) => ({
label: option.Value,
...(option.xp?.hexColor && { hexColors: [option.xp.hexColor] }),
})), })),
})) }))
: [], : [],