Update product mutations & queries

This commit is contained in:
cond0r 2021-04-29 19:22:22 +03:00
parent efed2c5e95
commit cdf8005c21
16 changed files with 170 additions and 98 deletions

View File

@ -1,6 +1,12 @@
import { ProductEdge } from '../../schema' import {
GetAllProductPathsQuery,
GetAllProductVendorsQuery,
ProductEdge,
} from '../../schema'
import { ShopifyConfig } from '..' import { ShopifyConfig } from '..'
type FetchAllProductsQuery = GetAllProductPathsQuery | GetAllProductVendorsQuery
const fetchAllProducts = async ({ const fetchAllProducts = async ({
config, config,
query, query,
@ -10,19 +16,18 @@ const fetchAllProducts = async ({
}: { }: {
config: ShopifyConfig config: ShopifyConfig
query: string query: string
acc?: ProductEdge[] acc?: any[]
variables?: any variables?: any
cursor?: string cursor?: string
}): Promise<ProductEdge[]> => { }): Promise<ProductEdge[]> => {
const { data } = await config.fetch(query, { const { data } = await config.fetch<FetchAllProductsQuery>(query, {
variables: { ...variables, cursor }, variables: { ...variables, cursor },
}) })
const edges: ProductEdge[] = data.products?.edges ?? [] const edges = data.products.edges
const hasNextPage = data.products?.pageInfo?.hasNextPage
acc = acc.concat(edges) acc = acc.concat(edges)
if (hasNextPage) { if (data.products.pageInfo.hasNextPage) {
const cursor = edges.pop()?.cursor const cursor = edges.pop()?.cursor
if (cursor) { if (cursor) {
return fetchAllProducts({ return fetchAllProducts({

View File

@ -1,7 +1,5 @@
import { Product } from '@commerce/types'
import { getConfig, ShopifyConfig } from '../api' import { getConfig, ShopifyConfig } from '../api'
import fetchAllProducts from '../api/utils/fetch-all-products' import fetchAllProducts from '../api/utils/fetch-all-products'
import { ProductEdge } from '../schema'
import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query' import getAllProductsPathsQuery from '../utils/queries/get-all-products-paths-query'
type ProductPath = { type ProductPath = {
@ -31,7 +29,7 @@ const getAllProductPaths = async (options?: {
}) })
return { return {
products: products?.map(({ node: { handle } }: ProductEdge) => ({ products: products?.map(({ node: { handle } }) => ({
node: { node: {
path: `/${handle}`, path: `/${handle}`,
}, },

View File

@ -1,6 +1,5 @@
import { GraphQLFetcherResult } from '@commerce/api'
import { getConfig, ShopifyConfig } from '../api' import { getConfig, ShopifyConfig } from '../api'
import { ProductEdge } from '../schema' import { GetAllProductsQuery, Product as ShopifyProduct } from '../schema'
import { getAllProductsQuery } from '../utils/queries' import { getAllProductsQuery } from '../utils/queries'
import { normalizeProduct } from '../utils/normalize' import { normalizeProduct } from '../utils/normalize'
import { Product } from '@commerce/types' import { Product } from '@commerce/types'
@ -10,30 +9,25 @@ type Variables = {
field?: string field?: string
} }
type ReturnType = {
products: Product[]
}
const getAllProducts = async (options: { const getAllProducts = async (options: {
variables?: Variables variables?: Variables
config?: ShopifyConfig config?: ShopifyConfig
preview?: boolean preview?: boolean
}): Promise<ReturnType> => { }): Promise<{
products: Product[]
}> => {
let { config, variables = { first: 250 } } = options ?? {} let { config, variables = { first: 250 } } = options ?? {}
config = getConfig(config) config = getConfig(config)
const { data }: GraphQLFetcherResult = await config.fetch( const { data } = await config.fetch<GetAllProductsQuery>(
getAllProductsQuery, getAllProductsQuery,
{ variables } { variables }
) )
const products =
data.products?.edges?.map(({ node: p }: ProductEdge) =>
normalizeProduct(p)
) ?? []
return { return {
products, products: data.products.edges.map(({ node }) =>
normalizeProduct(node as ShopifyProduct)
),
} }
} }

View File

@ -1,30 +1,32 @@
import { GraphQLFetcherResult } from '@commerce/api' import { GetProductBySlugQuery, Product as ShopifyProduct } from '../schema'
import { getConfig, ShopifyConfig } from '../api' import { getConfig, ShopifyConfig } from '../api'
import { normalizeProduct, getProductQuery } from '../utils' import { normalizeProduct, getProductQuery } from '../utils'
import { Product } from '@commerce/types'
type Variables = { type Variables = {
slug: string slug: string
} }
type ReturnType = {
product: any
}
const getProduct = async (options: { const getProduct = async (options: {
variables: Variables variables: Variables
config: ShopifyConfig config: ShopifyConfig
preview?: boolean preview?: boolean
}): Promise<ReturnType> => { }): Promise<{
product?: Product
}> => {
let { config, variables } = options ?? {} let { config, variables } = options ?? {}
config = getConfig(config) config = getConfig(config)
const { data }: GraphQLFetcherResult = await config.fetch(getProductQuery, { const {
data: { productByHandle },
} = await config.fetch<GetProductBySlugQuery>(getProductQuery, {
variables, variables,
}) })
const { productByHandle } = data
return { return {
product: productByHandle ? normalizeProduct(productByHandle) : null, ...(productByHandle && {
product: normalizeProduct(productByHandle as ShopifyProduct),
}),
} }
} }

View File

@ -1,7 +1,12 @@
import { SWRHook } from '@commerce/utils/types' import { SWRHook } from '@commerce/utils/types'
import useSearch, { UseSearch } from '@commerce/product/use-search' import useSearch, { UseSearch } from '@commerce/product/use-search'
import { ProductEdge } from '../schema' import {
CollectionEdge,
GetAllProductsQuery,
Product as ShopifyProduct,
ProductEdge,
} from '../schema'
import { import {
getAllProductsQuery, getAllProductsQuery,
getCollectionProductsQuery, getCollectionProductsQuery,
@ -35,30 +40,38 @@ export const handler: SWRHook<
}, },
async fetcher({ input, options, fetch }) { async fetcher({ input, options, fetch }) {
const { categoryId, brandId } = input const { categoryId, brandId } = input
const method = options?.method
const variables = getSearchVariables(input)
let products
const data = await fetch({ // change the query to getCollectionProductsQuery when categoryId is set
query: categoryId ? getCollectionProductsQuery : options.query,
method: options?.method,
variables: getSearchVariables(input),
})
let edges
if (categoryId) { if (categoryId) {
edges = data.node?.products?.edges ?? [] const data = await fetch<CollectionEdge>({
if (brandId) { query: getCollectionProductsQuery,
edges = edges.filter( method,
({ node: { vendor } }: ProductEdge) => variables,
vendor.replace(/\s+/g, '-').toLowerCase() === brandId })
) // filter on client when brandId & categoryId are set since is not available on collection product query
} products = brandId
? data.node.products.edges.filter(
({ node: { vendor } }: ProductEdge) =>
vendor.replace(/\s+/g, '-').toLowerCase() === brandId
)
: data.node.products.edges
} else { } else {
edges = data.products?.edges ?? [] const data = await fetch<GetAllProductsQuery>({
query: options.query,
method,
variables,
})
products = data.products.edges
} }
return { return {
products: edges.map(({ node }: ProductEdge) => normalizeProduct(node)), products: products?.map(({ node }) =>
found: !!edges.length, normalizeProduct(node as ShopifyProduct)
),
found: !!products?.length,
} }
}, },
useHook: ({ useData }) => (input = {}) => { useHook: ({ useData }) => (input = {}) => {

View File

@ -37,7 +37,7 @@ export type ApiVersion = {
displayName: Scalars['String'] displayName: Scalars['String']
/** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */ /** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */
handle: Scalars['String'] handle: Scalars['String']
/** Whether the version is supported by Shopify. */ /** Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/concepts/about-apis/versioning). */
supported: Scalars['Boolean'] supported: Scalars['Boolean']
} }
@ -393,6 +393,8 @@ export type Checkout = Node & {
taxExempt: Scalars['Boolean'] taxExempt: Scalars['Boolean']
/** Specifies if taxes are included in the line item and shipping line prices. */ /** Specifies if taxes are included in the line item and shipping line prices. */
taxesIncluded: Scalars['Boolean'] taxesIncluded: Scalars['Boolean']
/** The sum of all the duties applied to the line items in the checkout. */
totalDuties?: Maybe<MoneyV2>
/** /**
* The sum of all the prices of all the items in the checkout, taxes and discounts included. * The sum of all the prices of all the items in the checkout, taxes and discounts included.
* @deprecated Use `totalPriceV2` instead * @deprecated Use `totalPriceV2` instead
@ -1661,6 +1663,8 @@ export enum CountryCode {
Zm = 'ZM', Zm = 'ZM',
/** Zimbabwe. */ /** Zimbabwe. */
Zw = 'ZW', Zw = 'ZW',
/** Unknown Region. */
Zz = 'ZZ',
} }
/** Credit card information used for a payment. */ /** Credit card information used for a payment. */
@ -2561,6 +2565,8 @@ export type ExternalVideo = Node &
alt?: Maybe<Scalars['String']> alt?: Maybe<Scalars['String']>
/** The URL. */ /** The URL. */
embeddedUrl: Scalars['URL'] embeddedUrl: Scalars['URL']
/** The host of the external video. */
host: MediaHost
/** Globally unique identifier. */ /** Globally unique identifier. */
id: Scalars['ID'] id: Scalars['ID']
/** The media content type. */ /** The media content type. */
@ -2935,6 +2941,14 @@ export type MediaEdge = {
node: Media node: Media
} }
/** Host for a Media Resource. */
export enum MediaHost {
/** Host for YouTube embedded videos. */
Youtube = 'YOUTUBE',
/** Host for Vimeo embedded videos. */
Vimeo = 'VIMEO',
}
/** Represents a Shopify hosted image. */ /** Represents a Shopify hosted image. */
export type MediaImage = Node & export type MediaImage = Node &
Media & { Media & {
@ -3503,6 +3517,8 @@ export type Order = Node & {
currencyCode: CurrencyCode currencyCode: CurrencyCode
/** The subtotal of line items and their discounts, excluding line items that have been removed. Does not contain order-level discounts, duties, shipping costs, or shipping discounts. Taxes are not included unless the order is a taxes-included order. */ /** The subtotal of line items and their discounts, excluding line items that have been removed. Does not contain order-level discounts, duties, shipping costs, or shipping discounts. Taxes are not included unless the order is a taxes-included order. */
currentSubtotalPrice: MoneyV2 currentSubtotalPrice: MoneyV2
/** The total cost of duties for the order, including refunds. */
currentTotalDuties?: Maybe<MoneyV2>
/** The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. */ /** The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. */
currentTotalPrice: MoneyV2 currentTotalPrice: MoneyV2
/** The total of all taxes applied to the order, excluding taxes for returned line items. */ /** The total of all taxes applied to the order, excluding taxes for returned line items. */
@ -3532,6 +3548,8 @@ export type Order = Node & {
name: Scalars['String'] name: Scalars['String']
/** A unique numeric identifier for the order for use by shop owner and customer. */ /** A unique numeric identifier for the order for use by shop owner and customer. */
orderNumber: Scalars['Int'] orderNumber: Scalars['Int']
/** The total cost of duties charged at checkout. */
originalTotalDuties?: Maybe<MoneyV2>
/** The total price of the order before any applied edits. */ /** The total price of the order before any applied edits. */
originalTotalPrice: MoneyV2 originalTotalPrice: MoneyV2
/** The customer's phone number for receiving SMS notifications. */ /** The customer's phone number for receiving SMS notifications. */
@ -5013,9 +5031,11 @@ export type AssociateCustomerWithCheckoutMutation = {
> >
} }
export type Unnamed_1_MutationVariables = Exact<{ [key: string]: never }> export type CheckoutCreateMutationVariables = Exact<{
input?: Maybe<CheckoutCreateInput>
}>
export type Unnamed_1_Mutation = { __typename?: 'Mutation' } & { export type CheckoutCreateMutation = { __typename?: 'Mutation' } & {
checkoutCreate?: Maybe< checkoutCreate?: Maybe<
{ __typename?: 'CheckoutCreatePayload' } & { { __typename?: 'CheckoutCreatePayload' } & {
checkoutUserErrors: Array< checkoutUserErrors: Array<
@ -5029,12 +5049,12 @@ export type Unnamed_1_Mutation = { __typename?: 'Mutation' } & {
> >
} }
export type Unnamed_2_MutationVariables = Exact<{ export type CheckoutLineItemAddMutationVariables = Exact<{
checkoutId: Scalars['ID'] checkoutId: Scalars['ID']
lineItems: Array<CheckoutLineItemInput> | CheckoutLineItemInput lineItems: Array<CheckoutLineItemInput> | CheckoutLineItemInput
}> }>
export type Unnamed_2_Mutation = { __typename?: 'Mutation' } & { export type CheckoutLineItemAddMutation = { __typename?: 'Mutation' } & {
checkoutLineItemsAdd?: Maybe< checkoutLineItemsAdd?: Maybe<
{ __typename?: 'CheckoutLineItemsAddPayload' } & { { __typename?: 'CheckoutLineItemsAddPayload' } & {
checkoutUserErrors: Array< checkoutUserErrors: Array<
@ -5048,12 +5068,12 @@ export type Unnamed_2_Mutation = { __typename?: 'Mutation' } & {
> >
} }
export type Unnamed_3_MutationVariables = Exact<{ export type CheckoutLineItemRemoveMutationVariables = Exact<{
checkoutId: Scalars['ID'] checkoutId: Scalars['ID']
lineItemIds: Array<Scalars['ID']> | Scalars['ID'] lineItemIds: Array<Scalars['ID']> | Scalars['ID']
}> }>
export type Unnamed_3_Mutation = { __typename?: 'Mutation' } & { export type CheckoutLineItemRemoveMutation = { __typename?: 'Mutation' } & {
checkoutLineItemsRemove?: Maybe< checkoutLineItemsRemove?: Maybe<
{ __typename?: 'CheckoutLineItemsRemovePayload' } & { { __typename?: 'CheckoutLineItemsRemovePayload' } & {
checkoutUserErrors: Array< checkoutUserErrors: Array<
@ -5067,12 +5087,12 @@ export type Unnamed_3_Mutation = { __typename?: 'Mutation' } & {
> >
} }
export type Unnamed_4_MutationVariables = Exact<{ export type CheckoutLineItemUpdateMutationVariables = Exact<{
checkoutId: Scalars['ID'] checkoutId: Scalars['ID']
lineItems: Array<CheckoutLineItemUpdateInput> | CheckoutLineItemUpdateInput lineItems: Array<CheckoutLineItemUpdateInput> | CheckoutLineItemUpdateInput
}> }>
export type Unnamed_4_Mutation = { __typename?: 'Mutation' } & { export type CheckoutLineItemUpdateMutation = { __typename?: 'Mutation' } & {
checkoutLineItemsUpdate?: Maybe< checkoutLineItemsUpdate?: Maybe<
{ __typename?: 'CheckoutLineItemsUpdatePayload' } & { { __typename?: 'CheckoutLineItemsUpdatePayload' } & {
checkoutUserErrors: Array< checkoutUserErrors: Array<
@ -5370,11 +5390,11 @@ export type CheckoutDetailsFragment = { __typename?: 'Checkout' } & Pick<
} }
} }
export type Unnamed_5_QueryVariables = Exact<{ export type GetCheckoutQueryVariables = Exact<{
checkoutId: Scalars['ID'] checkoutId: Scalars['ID']
}> }>
export type Unnamed_5_Query = { __typename?: 'QueryRoot' } & { export type GetCheckoutQuery = { __typename?: 'QueryRoot' } & {
node?: Maybe< node?: Maybe<
| { __typename?: 'AppliedGiftCard' } | { __typename?: 'AppliedGiftCard' }
| { __typename?: 'Article' } | { __typename?: 'Article' }
@ -5464,11 +5484,11 @@ export type GetCustomerQuery = { __typename?: 'QueryRoot' } & {
> >
} }
export type Unnamed_6_QueryVariables = Exact<{ export type GetPageQueryVariables = Exact<{
id: Scalars['ID'] id: Scalars['ID']
}> }>
export type Unnamed_6_Query = { __typename?: 'QueryRoot' } & { export type GetPageQuery = { __typename?: 'QueryRoot' } & {
node?: Maybe< node?: Maybe<
| ({ __typename?: 'AppliedGiftCard' } & Pick<AppliedGiftCard, 'id'>) | ({ __typename?: 'AppliedGiftCard' } & Pick<AppliedGiftCard, 'id'>)
| ({ __typename?: 'Article' } & Pick<Article, 'id'>) | ({ __typename?: 'Article' } & Pick<Article, 'id'>)

View File

@ -28,7 +28,7 @@ type ApiVersion {
handle: String! handle: String!
""" """
Whether the version is supported by Shopify. Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/concepts/about-apis/versioning).
""" """
supported: Boolean! supported: Boolean!
} }
@ -769,6 +769,11 @@ type Checkout implements Node {
""" """
taxesIncluded: Boolean! taxesIncluded: Boolean!
"""
The sum of all the duties applied to the line items in the checkout.
"""
totalDuties: MoneyV2
""" """
The sum of all the prices of all the items in the checkout, taxes and discounts included. The sum of all the prices of all the items in the checkout, taxes and discounts included.
""" """
@ -3306,6 +3311,11 @@ enum CountryCode {
Zimbabwe. Zimbabwe.
""" """
ZW ZW
"""
Unknown Region.
"""
ZZ
} }
""" """
@ -5178,6 +5188,11 @@ type ExternalVideo implements Node & Media {
""" """
embeddedUrl: URL! embeddedUrl: URL!
"""
The host of the external video.
"""
host: MediaHost!
""" """
Globally unique identifier. Globally unique identifier.
""" """
@ -5803,6 +5818,21 @@ type MediaEdge {
node: Media! node: Media!
} }
"""
Host for a Media Resource.
"""
enum MediaHost {
"""
Host for YouTube embedded videos.
"""
YOUTUBE
"""
Host for Vimeo embedded videos.
"""
VIMEO
}
""" """
Represents a Shopify hosted image. Represents a Shopify hosted image.
""" """
@ -6745,6 +6775,11 @@ type Order implements Node {
""" """
currentSubtotalPrice: MoneyV2! currentSubtotalPrice: MoneyV2!
"""
The total cost of duties for the order, including refunds.
"""
currentTotalDuties: MoneyV2
""" """
The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed. The total amount of the order, including duties, taxes and discounts, minus amounts for line items that have been removed.
""" """
@ -6861,6 +6896,11 @@ type Order implements Node {
""" """
orderNumber: Int! orderNumber: Int!
"""
The total cost of duties charged at checkout.
"""
originalTotalDuties: MoneyV2
""" """
The total price of the order before any applied edits. The total price of the order before any applied edits.
""" """

View File

@ -9,7 +9,9 @@ export type ShopifyCheckout = {
export type Cart = Core.Cart & { export type Cart = Core.Cart & {
lineItems: LineItem[] lineItems: LineItem[]
url?: String
} }
export interface LineItem extends Core.LineItem { export interface LineItem extends Core.LineItem {
options?: any[] options?: any[]
} }

View File

@ -27,12 +27,6 @@ export type CheckoutPayload =
| CheckoutQuery | CheckoutQuery
const checkoutToCart = (checkoutPayload?: Maybe<CheckoutPayload>): Cart => { const checkoutToCart = (checkoutPayload?: Maybe<CheckoutPayload>): Cart => {
if (!checkoutPayload) {
throw new CommerceError({
message: 'Missing checkout payload from response',
})
}
const checkout = checkoutPayload?.checkout const checkout = checkoutPayload?.checkout
throwUserErrors(checkoutPayload?.checkoutUserErrors) throwUserErrors(checkoutPayload?.checkoutUserErrors)

View File

@ -1,8 +1,8 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query' import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutCreateMutation = /* GraphQL */ ` const checkoutCreateMutation = /* GraphQL */ `
mutation { mutation checkoutCreate($input: CheckoutCreateInput = {}) {
checkoutCreate(input: {}) { checkoutCreate(input: $input) {
checkoutUserErrors { checkoutUserErrors {
code code
field field

View File

@ -1,7 +1,10 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query' import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutLineItemAddMutation = /* GraphQL */ ` const checkoutLineItemAddMutation = /* GraphQL */ `
mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) { mutation checkoutLineItemAdd(
$checkoutId: ID!
$lineItems: [CheckoutLineItemInput!]!
) {
checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) { checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) {
checkoutUserErrors { checkoutUserErrors {
code code

View File

@ -1,7 +1,7 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query' import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutLineItemRemoveMutation = /* GraphQL */ ` const checkoutLineItemRemoveMutation = /* GraphQL */ `
mutation($checkoutId: ID!, $lineItemIds: [ID!]!) { mutation checkoutLineItemRemove($checkoutId: ID!, $lineItemIds: [ID!]!) {
checkoutLineItemsRemove( checkoutLineItemsRemove(
checkoutId: $checkoutId checkoutId: $checkoutId
lineItemIds: $lineItemIds lineItemIds: $lineItemIds

View File

@ -1,7 +1,10 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query' import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutLineItemUpdateMutation = /* GraphQL */ ` const checkoutLineItemUpdateMutation = /* GraphQL */ `
mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) { mutation checkoutLineItemUpdate(
$checkoutId: ID!
$lineItems: [CheckoutLineItemUpdateInput!]!
) {
checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) { checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) {
checkoutUserErrors { checkoutUserErrors {
code code

View File

@ -75,22 +75,21 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
) )
} }
export function normalizeProduct(productNode: ShopifyProduct): Product { export function normalizeProduct({
const { id,
id, title: name,
title: name, vendor,
vendor, images,
images, variants,
variants, description,
description, descriptionHtml,
descriptionHtml, handle,
handle, priceRange,
priceRange, options,
options, metafields,
...rest ...rest
} = productNode }: ShopifyProduct): Product {
return {
const product = {
id, id,
name, name,
vendor, vendor,
@ -108,13 +107,12 @@ export function normalizeProduct(productNode: ShopifyProduct): Product {
...(descriptionHtml && { descriptionHtml }), ...(descriptionHtml && { descriptionHtml }),
...rest, ...rest,
} }
return product
} }
export function normalizeCart(checkout: Checkout): Cart { export function normalizeCart(checkout: Checkout): Cart {
return { return {
id: checkout.id, id: checkout.id,
url: checkout.webUrl,
customerId: '', customerId: '',
email: '', email: '',
createdAt: checkout.createdAt, createdAt: checkout.createdAt,
@ -131,7 +129,7 @@ export function normalizeCart(checkout: Checkout): Cart {
} }
function normalizeLineItem({ function normalizeLineItem({
node: { id, title, variant, quantity, ...rest }, node: { id, title, variant, quantity },
}: CheckoutLineItemEdge): LineItem { }: CheckoutLineItemEdge): LineItem {
return { return {
id, id,
@ -144,7 +142,7 @@ function normalizeLineItem({
sku: variant?.sku ?? '', sku: variant?.sku ?? '',
name: variant?.title!, name: variant?.title!,
image: { image: {
url: variant?.image?.originalSrc ?? '/product-img-placeholder.svg', url: variant?.image?.originalSrc || '/product-img-placeholder.svg',
}, },
requiresShipping: variant?.requiresShipping ?? false, requiresShipping: variant?.requiresShipping ?? false,
price: variant?.priceV2?.amount, price: variant?.priceV2?.amount,

View File

@ -56,7 +56,7 @@ export const checkoutDetailsFragment = /* GraphQL */ `
` `
const getCheckoutQuery = /* GraphQL */ ` const getCheckoutQuery = /* GraphQL */ `
query($checkoutId: ID!) { query getCheckout($checkoutId: ID!) {
node(id: $checkoutId) { node(id: $checkoutId) {
...checkoutDetails ...checkoutDetails
} }

View File

@ -1,5 +1,5 @@
export const getPageQuery = /* GraphQL */ ` export const getPageQuery = /* GraphQL */ `
query($id: ID!) { query getPage($id: ID!) {
node(id: $id) { node(id: $id) {
id id
... on Page { ... on Page {