mirror of
https://github.com/vercel/commerce.git
synced 2025-07-08 05:41:22 +00:00
GetProduct Initial Commit
This commit is contained in:
parent
327cc2f055
commit
1daed6e9f7
@ -7,9 +7,8 @@ const getLoggedInCustomer: CustomerEndpoint['handlers']['getLoggedInCustomer'] =
|
|||||||
config,
|
config,
|
||||||
}) => {
|
}) => {
|
||||||
const token = req.cookies[config.customerCookie]
|
const token = req.cookies[config.customerCookie]
|
||||||
|
const accessToken = token ? JSON.parse(token).accessToken : null;
|
||||||
const { accessToken } = JSON.parse(token);
|
|
||||||
|
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
const { data } = await config.fetch(
|
const { data } = await config.fetch(
|
||||||
getCustomerAccountQuery,
|
getCustomerAccountQuery,
|
||||||
|
98
framework/kibocommerce/api/fragments/product.ts
Normal file
98
framework/kibocommerce/api/fragments/product.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
export const productPrices = /* GraphQL */`
|
||||||
|
fragment productPrices on Product {
|
||||||
|
price {
|
||||||
|
price
|
||||||
|
salePrice
|
||||||
|
}
|
||||||
|
priceRange {
|
||||||
|
lower { price, salePrice}
|
||||||
|
upper { price, salePrice }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const productAttributes = /* GraphQL */`
|
||||||
|
fragment productAttributes on Product {
|
||||||
|
properties {
|
||||||
|
attributeFQN
|
||||||
|
attributeDetail {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
isHidden
|
||||||
|
values {
|
||||||
|
value
|
||||||
|
stringValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const productContent = /* GraphQL */`
|
||||||
|
fragment productContent on Product {
|
||||||
|
content {
|
||||||
|
productFullDescription
|
||||||
|
productShortDescription
|
||||||
|
seoFriendlyUrl
|
||||||
|
productName
|
||||||
|
productImages {
|
||||||
|
imageUrl
|
||||||
|
imageLabel
|
||||||
|
mediaType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const productOptions = /* GraphQL */`
|
||||||
|
fragment productOptions on Product {
|
||||||
|
options {
|
||||||
|
attributeFQN
|
||||||
|
attributeDetail {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
isProductImageGroupSelector
|
||||||
|
isRequired
|
||||||
|
isMultiValue
|
||||||
|
values {
|
||||||
|
value
|
||||||
|
isSelected
|
||||||
|
deltaPrice
|
||||||
|
stringValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const productInfo = /* GraphQL */`
|
||||||
|
fragment productInfo on Product {
|
||||||
|
productCode
|
||||||
|
productUsage
|
||||||
|
|
||||||
|
purchasableState {
|
||||||
|
isPurchasable
|
||||||
|
}
|
||||||
|
|
||||||
|
variations {
|
||||||
|
productCode,
|
||||||
|
options {
|
||||||
|
__typename
|
||||||
|
attributeFQN
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
categories {
|
||||||
|
categoryCode
|
||||||
|
categoryId
|
||||||
|
content {
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
...productPrices
|
||||||
|
...productAttributes
|
||||||
|
...productContent
|
||||||
|
...productOptions
|
||||||
|
}
|
||||||
|
${productPrices}
|
||||||
|
${productAttributes}
|
||||||
|
${productContent}
|
||||||
|
${productOptions}
|
||||||
|
`;
|
@ -2,13 +2,14 @@ import { Product } from '@commerce/types/product'
|
|||||||
import { GetAllProductsOperation } from '@commerce/types/product'
|
import { GetAllProductsOperation } from '@commerce/types/product'
|
||||||
import type { OperationContext } from '@commerce/api/operations'
|
import type { OperationContext } from '@commerce/api/operations'
|
||||||
import type { KiboCommerceConfig } from '../index'
|
import type { KiboCommerceConfig } from '../index'
|
||||||
import data from '../../data.json'
|
import { getAllProductsQuery } from '../queries/get-all-products-query';
|
||||||
|
import { normalizeProduct } from '../../lib/normalize'
|
||||||
|
|
||||||
export default function getAllProductsOperation({
|
export default function getAllProductsOperation({
|
||||||
commerce,
|
commerce,
|
||||||
}: OperationContext<any>) {
|
}: OperationContext<any>) {
|
||||||
async function getAllProducts<T extends GetAllProductsOperation>({
|
async function getAllProducts<T extends GetAllProductsOperation>({
|
||||||
query = '',
|
query = getAllProductsQuery,
|
||||||
variables,
|
variables,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
@ -17,8 +18,14 @@ export default function getAllProductsOperation({
|
|||||||
config?: Partial<KiboCommerceConfig>
|
config?: Partial<KiboCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
} = {}): Promise<{ products: Product[] | any[] }> {
|
} = {}): Promise<{ products: Product[] | any[] }> {
|
||||||
|
|
||||||
|
const cfg = commerce.getConfig(config)
|
||||||
|
const { data } = await cfg.fetch(query);
|
||||||
|
|
||||||
|
let normalizedProducts = data.products.items ? data.products.items.map(normalizeProduct) : [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
products: data.products,
|
products: normalizedProducts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getAllProducts
|
return getAllProducts
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import type { KiboCommerceConfig } from '../index'
|
import type { KiboCommerceConfig } from '../index'
|
||||||
import { Product } from '@commerce/types/product'
|
import { Product } from '@commerce/types/product'
|
||||||
import { GetProductOperation } from '@commerce/types/product'
|
import { GetProductOperation } from '@commerce/types/product'
|
||||||
import data from '../../data.json'
|
|
||||||
import type { OperationContext } from '@commerce/api/operations'
|
import type { OperationContext } from '@commerce/api/operations'
|
||||||
|
import { getProductQuery } from '../queries/get-product-query'
|
||||||
|
import { normalizeProduct } from '../../lib/normalize'
|
||||||
|
|
||||||
export default function getProductOperation({
|
export default function getProductOperation({
|
||||||
commerce,
|
commerce,
|
||||||
}: OperationContext<any>) {
|
}: OperationContext<any>) {
|
||||||
|
|
||||||
async function getProduct<T extends GetProductOperation>({
|
async function getProduct<T extends GetProductOperation>({
|
||||||
query = '',
|
query = getProductQuery,
|
||||||
variables,
|
variables,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
@ -17,8 +19,18 @@ export default function getProductOperation({
|
|||||||
config?: Partial<KiboCommerceConfig>
|
config?: Partial<KiboCommerceConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
} = {}): Promise<Product | {} | any> {
|
} = {}): Promise<Product | {} | any> {
|
||||||
|
const { products } = await commerce.getAllProducts();
|
||||||
|
const product = products?.find((product: any)=> product.slug === variables?.slug );
|
||||||
|
|
||||||
|
const productVariables = { productCode: product.id}
|
||||||
|
|
||||||
|
const cfg = commerce.getConfig(config)
|
||||||
|
const { data } = await cfg.fetch(query, { variables: productVariables });
|
||||||
|
|
||||||
|
const normalizedProduct = normalizeProduct(data.product)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
product: data.products.find(({ slug }) => slug === variables!.slug),
|
product: normalizedProduct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
framework/kibocommerce/api/queries/get-all-products-query.ts
Normal file
19
framework/kibocommerce/api/queries/get-all-products-query.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { productInfo } from '../fragments/product';
|
||||||
|
|
||||||
|
export const getAllProductsQuery = /* GraphQL */`
|
||||||
|
${productInfo}
|
||||||
|
|
||||||
|
query products(
|
||||||
|
$filter: String
|
||||||
|
$pageSize: Int
|
||||||
|
) {
|
||||||
|
products(
|
||||||
|
filter: $filter
|
||||||
|
pageSize: $pageSize
|
||||||
|
) {
|
||||||
|
items {
|
||||||
|
...productInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
15
framework/kibocommerce/api/queries/get-product-query.ts
Normal file
15
framework/kibocommerce/api/queries/get-product-query.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { productInfo } from '../fragments/product';
|
||||||
|
|
||||||
|
export const getProductQuery = /* GraphQL */`
|
||||||
|
${productInfo}
|
||||||
|
|
||||||
|
query product(
|
||||||
|
$productCode: String!
|
||||||
|
) {
|
||||||
|
product(
|
||||||
|
productCode: $productCode
|
||||||
|
) {
|
||||||
|
...productInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
@ -24,54 +24,42 @@ function normalizeProductOption(productOption: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeProduct(productNode: any): any {
|
export function normalizeProduct(productNode: any): any {
|
||||||
const {
|
const product = {
|
||||||
entityId: id,
|
id: productNode.productCode,
|
||||||
productOptions,
|
name: productNode.content.productName,
|
||||||
prices,
|
vendor: "",
|
||||||
path,
|
path: `/${productNode.productCode}/${productNode.content.seoFriendlyUrl}`,
|
||||||
id: _,
|
// slug: `${productNode.productCode}/${productNode.content.seoFriendlyUrl}`,
|
||||||
options: _0,
|
slug: productNode.content.seoFriendlyUrl,
|
||||||
} = productNode
|
price: { value: productNode.price.price, "currencyCode": "USD" },
|
||||||
|
descriptionHtml: productNode.content.productShortDescription,
|
||||||
|
|
||||||
return update(productNode, {
|
images: productNode.content.productImages.map((p: any)=> ({
|
||||||
id: { $set: String(id) },
|
url: `http:${p.imageUrl}`,
|
||||||
images: {
|
altText: p.imageLabel,
|
||||||
$apply: ({ edges }: any) =>
|
})),
|
||||||
edges?.map(({ node: { urlOriginal, altText, ...rest } }: any) => ({
|
|
||||||
url: urlOriginal,
|
variants: productNode.variations?.map((v:any) => ({
|
||||||
alt: altText,
|
id: v.productCode,
|
||||||
...rest,
|
options: v.options.map((o:any) => ({
|
||||||
})),
|
["__typename"]: o["__typename"],
|
||||||
},
|
id: o.attributeFQN,
|
||||||
variants: {
|
displayName: o.attributeFQN.split('~')[1].toUpperCase(),
|
||||||
$apply: ({ edges }: any) =>
|
values: [{label: o.value}]
|
||||||
edges?.map(({ node: { entityId, productOptions, ...rest } }: any) => ({
|
}))
|
||||||
id: entityId,
|
})) || [],
|
||||||
options: productOptions?.edges
|
|
||||||
? productOptions.edges.map(normalizeProductOption)
|
options:productNode.options?.map((o:any)=> ({
|
||||||
: [],
|
id: o.attributeFQN,
|
||||||
...rest,
|
displayName: o.attributeDetail.name,
|
||||||
})),
|
values: o.values.map( (v:any)=> ({
|
||||||
},
|
label: v.value,
|
||||||
options: {
|
hexColors: ""
|
||||||
$set: productOptions.edges
|
}))
|
||||||
? productOptions?.edges.map(normalizeProductOption)
|
})) || []
|
||||||
: [],
|
}
|
||||||
},
|
|
||||||
brand: {
|
return product;
|
||||||
$apply: (brand: any) => (brand?.entityId ? brand?.entityId : null),
|
|
||||||
},
|
|
||||||
slug: {
|
|
||||||
$set: path?.replace(/^\/+|\/+$/g, ''),
|
|
||||||
},
|
|
||||||
price: {
|
|
||||||
$set: {
|
|
||||||
value: prices?.price.value,
|
|
||||||
currencyCode: prices?.price.currencyCode,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
$unset: ['entityId'],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizePage(page: any): any {
|
export function normalizePage(page: any): any {
|
||||||
|
@ -3,6 +3,6 @@ const commerce = require('./commerce.config.json')
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
commerce,
|
commerce,
|
||||||
images: {
|
images: {
|
||||||
domains: ['localhost'],
|
domains: ['d1slj7rdbjyb5l.cloudfront.net'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user