diff --git a/framework/kibocommerce/api/endpoints/customer/customer.ts b/framework/kibocommerce/api/endpoints/customer/customer.ts index 2ae29d2bf..b7bf0e25e 100644 --- a/framework/kibocommerce/api/endpoints/customer/customer.ts +++ b/framework/kibocommerce/api/endpoints/customer/customer.ts @@ -7,9 +7,8 @@ const getLoggedInCustomer: CustomerEndpoint['handlers']['getLoggedInCustomer'] = config, }) => { const token = req.cookies[config.customerCookie] - - const { accessToken } = JSON.parse(token); - + const accessToken = token ? JSON.parse(token).accessToken : null; + if (accessToken) { const { data } = await config.fetch( getCustomerAccountQuery, diff --git a/framework/kibocommerce/api/fragments/product.ts b/framework/kibocommerce/api/fragments/product.ts new file mode 100644 index 000000000..d5e7aa543 --- /dev/null +++ b/framework/kibocommerce/api/fragments/product.ts @@ -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} +`; diff --git a/framework/kibocommerce/api/operations/get-all-products.ts b/framework/kibocommerce/api/operations/get-all-products.ts index 31d2cebd0..48abb0799 100644 --- a/framework/kibocommerce/api/operations/get-all-products.ts +++ b/framework/kibocommerce/api/operations/get-all-products.ts @@ -2,13 +2,14 @@ import { Product } from '@commerce/types/product' import { GetAllProductsOperation } from '@commerce/types/product' import type { OperationContext } from '@commerce/api/operations' 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({ commerce, }: OperationContext) { async function getAllProducts({ - query = '', + query = getAllProductsQuery, variables, config, }: { @@ -17,8 +18,14 @@ export default function getAllProductsOperation({ config?: Partial preview?: boolean } = {}): 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 { - products: data.products, + products: normalizedProducts, } } return getAllProducts diff --git a/framework/kibocommerce/api/operations/get-product.ts b/framework/kibocommerce/api/operations/get-product.ts index d59a7b818..2dcda0c65 100644 --- a/framework/kibocommerce/api/operations/get-product.ts +++ b/framework/kibocommerce/api/operations/get-product.ts @@ -1,14 +1,16 @@ import type { KiboCommerceConfig } from '../index' import { Product } from '@commerce/types/product' import { GetProductOperation } from '@commerce/types/product' -import data from '../../data.json' import type { OperationContext } from '@commerce/api/operations' +import { getProductQuery } from '../queries/get-product-query' +import { normalizeProduct } from '../../lib/normalize' export default function getProductOperation({ commerce, }: OperationContext) { + async function getProduct({ - query = '', + query = getProductQuery, variables, config, }: { @@ -17,8 +19,18 @@ export default function getProductOperation({ config?: Partial preview?: boolean } = {}): Promise { + 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 { - product: data.products.find(({ slug }) => slug === variables!.slug), + product: normalizedProduct } } diff --git a/framework/kibocommerce/api/queries/get-all-products-query.ts b/framework/kibocommerce/api/queries/get-all-products-query.ts new file mode 100644 index 000000000..1131fecfc --- /dev/null +++ b/framework/kibocommerce/api/queries/get-all-products-query.ts @@ -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 + } + } +} +` \ No newline at end of file diff --git a/framework/kibocommerce/api/queries/get-product-query.ts b/framework/kibocommerce/api/queries/get-product-query.ts new file mode 100644 index 000000000..47db311e4 --- /dev/null +++ b/framework/kibocommerce/api/queries/get-product-query.ts @@ -0,0 +1,15 @@ +import { productInfo } from '../fragments/product'; + +export const getProductQuery = /* GraphQL */` +${productInfo} + + query product( + $productCode: String! + ) { + product( + productCode: $productCode + ) { + ...productInfo + } + } +` \ No newline at end of file diff --git a/framework/kibocommerce/lib/normalize.ts b/framework/kibocommerce/lib/normalize.ts index 07c3b67ac..f15e8d586 100644 --- a/framework/kibocommerce/lib/normalize.ts +++ b/framework/kibocommerce/lib/normalize.ts @@ -24,54 +24,42 @@ function normalizeProductOption(productOption: any) { } export function normalizeProduct(productNode: any): any { - const { - entityId: id, - productOptions, - prices, - path, - id: _, - options: _0, - } = productNode + const product = { + id: productNode.productCode, + name: productNode.content.productName, + vendor: "", + path: `/${productNode.productCode}/${productNode.content.seoFriendlyUrl}`, + // slug: `${productNode.productCode}/${productNode.content.seoFriendlyUrl}`, + slug: productNode.content.seoFriendlyUrl, + price: { value: productNode.price.price, "currencyCode": "USD" }, + descriptionHtml: productNode.content.productShortDescription, - return update(productNode, { - id: { $set: String(id) }, - images: { - $apply: ({ edges }: any) => - edges?.map(({ node: { urlOriginal, altText, ...rest } }: any) => ({ - url: urlOriginal, - alt: altText, - ...rest, - })), - }, - variants: { - $apply: ({ edges }: any) => - edges?.map(({ node: { entityId, productOptions, ...rest } }: any) => ({ - id: entityId, - options: productOptions?.edges - ? productOptions.edges.map(normalizeProductOption) - : [], - ...rest, - })), - }, - options: { - $set: productOptions.edges - ? productOptions?.edges.map(normalizeProductOption) - : [], - }, - brand: { - $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'], - }) + images: productNode.content.productImages.map((p: any)=> ({ + url: `http:${p.imageUrl}`, + altText: p.imageLabel, + })), + + variants: productNode.variations?.map((v:any) => ({ + id: v.productCode, + options: v.options.map((o:any) => ({ + ["__typename"]: o["__typename"], + id: o.attributeFQN, + displayName: o.attributeFQN.split('~')[1].toUpperCase(), + values: [{label: o.value}] + })) + })) || [], + + options:productNode.options?.map((o:any)=> ({ + id: o.attributeFQN, + displayName: o.attributeDetail.name, + values: o.values.map( (v:any)=> ({ + label: v.value, + hexColors: "" + })) + })) || [] +} + +return product; } export function normalizePage(page: any): any { diff --git a/framework/kibocommerce/next.config.js b/framework/kibocommerce/next.config.js index ce46b706f..bbcca64d9 100644 --- a/framework/kibocommerce/next.config.js +++ b/framework/kibocommerce/next.config.js @@ -3,6 +3,6 @@ const commerce = require('./commerce.config.json') module.exports = { commerce, images: { - domains: ['localhost'], + domains: ['d1slj7rdbjyb5l.cloudfront.net'], }, }