import type { OperationContext, OperationOptions, } from '@commerce/api/operations' import type { GetProductOperation } from '../../types/product' import type { GetProductQuery, GetProductQueryVariables } from '../../schema' import setProductLocaleMeta from '../utils/set-product-locale-meta' import { productInfoFragment } from '../fragments/product' import { BigcommerceConfig, Provider } from '..' import { normalizeProduct } from '../../lib/normalize' export const getProductQuery = /* GraphQL */ ` query getProduct( $hasLocale: Boolean = false $locale: String = "null" $path: String! ) { site { route(path: $path) { node { __typename ... on Product { ...productInfo variants { edges { node { entityId defaultImage { urlOriginal altText isDefault } prices { ...productPrices } inventory { aggregated { availableToSell warningLevel } isInStock } productOptions { edges { node { __typename entityId displayName ...multipleChoiceOption } } } } } } } } } } } ${productInfoFragment} ` // TODO: See if this type is useful for defining the Product type // export type ProductNode = Extract< // GetProductQuery['site']['route']['node'], // { __typename: 'Product' } // > export default function getAllProductPathsOperation({ commerce, }: OperationContext) { async function getProduct(opts: { variables: T['variables'] config?: Partial preview?: boolean }): Promise async function getProduct( opts: { variables: T['variables'] config?: Partial preview?: boolean } & OperationOptions ): Promise async function getProduct({ query = getProductQuery, variables: { slug, ...vars }, config: cfg, }: { query?: string variables: T['variables'] config?: Partial preview?: boolean }): Promise { const config = commerce.getConfig(cfg) const { locale } = config const variables: GetProductQueryVariables = { locale, hasLocale: !!locale, path: slug ? `/${slug}/` : vars.path!, } const { data } = await config.fetch(query, { variables }) const product = data.site?.route?.node if (product?.__typename === 'Product') { if (locale && config.applyLocale) { setProductLocaleMeta(product) } return { product: normalizeProduct(product as any) } } return {} } return getProduct }