Cart SDK reference
Cart state, line-item views, cart mutations and cart editor attributes.
Import these public values from @upstorr/theme-sdk/v1. Do not import their internal source files.
addThemeCartItem
addThemeCartItem(input: { productId: string; variantId: string; quantity?: number; metadata?: ThemeCartLineMetadata | null; }): Promise<ThemeCart>
createThemeCartLinesView
createThemeCartLinesView<TItem extends ThemeCartViewItemInput>(cart: ThemeCartViewInput<TItem>, options?: { showCurrencyCode?: boolean; imageRatio?: unknown; }): Array<ThemeCartLineView<TItem>>
createThemeCartRuntimeView
createThemeCartRuntimeView(cart: ThemeCartViewInput | null, state: { isLoading: boolean; error: string | null; }): { status: "loading" | "error"; cart: null; itemCount: number; isEmpty: boolean; message: string; } | { status: "empty" | "ready"; cart: ThemeCartViewInput; itemCount: number; isEmpty: boolean; message: null; }
createThemeCartSummaryView
createThemeCartSummaryView(cart: ThemeCartViewInput, options?: { showCurrencyCode?: boolean; }): ThemeCartSummaryView
createThemeInertCartRuntime
createThemeInertCartRuntime(initialCart?: ThemeCart | null): { cart: ThemeCart | null; view: { status: "loading" | "error"; cart: null; itemCount: number; isEmpty: boolean; message: string; } | { status: "empty" | "ready"; cart: import("@upstorr/theme-sdk/v1").ThemeCartViewInput; itemCount: number; isEmpty: boolean; message: null; }; isLoading: boolean; isUpdating: boolean; error: null; refresh(): Promise<ThemeCart | null>; addItem: () => Promise<never>; updateItemQuantity: () => Promise<never>; updateBookingItemQuantity: () => Promise<never>; updateLineItemQuantity: () => Promise<never>; removeItem: () => Promise<never>; replaceWithSingleItem: () => Promise<never>; }
fetchThemeCart
fetchThemeCart(): Promise<ThemeCart>
getThemeCartItemCount
getThemeCartItemCount(cart: Pick<ThemeCartViewInput, "itemCount">): number
getThemeCartPresenceView
getThemeCartPresenceView(cart: Pick<ThemeCartViewInput, "itemCount">, options?: { forceEmpty?: boolean; }): { itemCount: number; isEmpty: boolean; }
isThemeBookingCartLine
isThemeBookingCartLine(item: Pick<ThemeCartViewItemInput, "metadata">): boolean
readThemeCartRouteData
readThemeCartRouteData(data: unknown): ThemeCart | null
removeThemeCartItem
removeThemeCartItem(cartItemId: string, options?: { trackAnalytics?: boolean; }): Promise<ThemeCart>
replaceThemeCartWithSingleItem
replaceThemeCartWithSingleItem(input: { productId: string; variantId: string; quantity?: number; metadata?: ThemeCartLineMetadata | null; }): Promise<ThemeCart>
resolveThemeCartLineImageAspectRatio
resolveThemeCartLineImageAspectRatio(value: unknown, item: ThemeCartViewItemInput): string
runThemeCartMutation
runThemeCartMutation<T>(operationKey: string, task: () => Promise<T>): Promise<T>
ThemeCartLineView
type ThemeCartLineView<TItem extends ThemeCartViewItemInput = ThemeCartViewItemInput> = Omit<
ThemeCartCanonicalLineView,
'formattedLineTotal' | 'formattedLineTotalWithCurrencyCode' | 'quantity'
> & {
item: TItem;
formattedLineTotal: string;
quantity: Omit<ThemeCartCanonicalLineView['quantity'], 'value'> & {
normalizeInput: (value: unknown) => number;
};
};
ThemeCartSummaryView
type ThemeCartSummaryView = {
rows: Array<{
id: 'subtotal' | 'security-deposit' | 'total';
label: string;
formattedValue: string;
emphasis: 'regular' | 'strong';
announcesTotal: boolean;
exposesSubtotal: boolean;
}>;
checkout: {
disabled: boolean;
disabledReason: string | null;
};
};
ThemeCartVariantInput
type ThemeCartVariantInput = {
id?: string | null;
name?: string | null;
title?: string | null;
featuredImage?: string | null;
featured_image?: string | null;
image?: string | null;
thumbnail?: string | null;
images?: string[] | null;
option1?: string | null;
option2?: string | null;
option3?: string | null;
options?: Record<string, string> | Array<{ name?: string; value?: string }>;
};
ThemeCartViewInput
type ThemeCartViewInput<TItem extends ThemeCartViewItemInput = ThemeCartViewItemInput> = {
items: TItem[];
itemCount: number;
subtotal: number;
securityDepositTotal: number;
amountPayable: number;
currency: string;
customerNote?: string | null;
ui?: {
checkout?: {
canCheckout?: boolean;
disabledReason?: { message?: string | null } | null;
} | null;
lines?: Array<{
lineId?: string;
quantity?: {
minimum?: number;
maximum?: number | null;
step?: number;
canIncrease?: boolean;
canDecrease?: boolean;
};
}>;
} | null;
};
ThemeCartViewItemInput
type ThemeCartViewItemInput = {
id: string;
lineId?: string;
quantity: number;
lineTotal: number;
metadata?: ThemeCartLineMetadata | null;
booking?: ThemeCartBooking | null;
product: {
id: string;
title?: string | null;
name?: string | null;
handle?: string | null;
slug?: string | null;
thumbnail?: string | null;
images?: string[] | null;
metadata?: Record<string, unknown> | null;
options?: Array<{ name?: string | null; values?: string[] | null }>;
variants?: ThemeCartVariantInput[];
productVariants?: ThemeCartVariantInput[];
};
variant?: ThemeCartVariantInput | null;
};
updateThemeCartItemQuantity
updateThemeCartItemQuantity(cartItemId: string, quantity: number): Promise<ThemeCart>
useThemeCart
useThemeCart(initialCart?: ThemeCart | null): { cart: ThemeCart | null; view: { status: "loading" | "error"; cart: null; itemCount: number; isEmpty: boolean; message: string; } | { status: "empty" | "ready"; cart: import("@upstorr/theme-sdk/v1").ThemeCartViewInput; itemCount: number; isEmpty: boolean; message: null; }; isLoading: boolean; isUpdating: boolean; error: string | null; refresh: () => Promise<ThemeCart>; addItem: (input: Parameters<typeof addThemeCartItem>[0]) => Promise<ThemeCart>; updateItemQuantity: (cartItemId: string, quantity: number) => Promise<ThemeCart>; updateBookingItemQuantity: (cartItemId: string, quantity: number) => Promise<ThemeCart>; updateLineItemQuantity: (item: ThemeCartViewItemInput, quantity: number) => Promise<ThemeCart>; removeItem: (cartItemId: string) => Promise<ThemeCart>; replaceWithSingleItem: (input: Parameters<typeof replaceThemeCartWithSingleItem>[0]) => Promise<ThemeCart>; }