@shopify/hydrogen-react
Version:
React components, hooks, and utilities for creating custom Shopify storefronts
298 lines (297 loc) • 10.4 kB
TypeScript
import { Cart as CartType, CartInput, CartLine, CartLineInput, CartLineUpdateInput, MutationCartNoteUpdateArgs, CartBuyerIdentityInput, MutationCartAttributesUpdateArgs, ComponentizableCartLine } from './storefront-api-types.js';
import { StateMachine } from '@xstate/fsm';
import type { PartialDeep } from 'type-fest';
export type CartStatus = CartState['status'];
export interface CartBase {
/** The cart's ID if it has been created through the Storefront API. */
id?: string;
/** The cart lines. */
lines: Array<CartLine | ComponentizableCartLine>;
/** The checkout URL for the cart, if the cart has been created in the Storefront API. */
checkoutUrl?: string;
/** The cart's note. */
note?: string;
/** The cart's buyer identity. */
buyerIdentity?: CartType['buyerIdentity'];
/** The cart's attributes. */
attributes: CartType['attributes'];
/** The discount codes applied to the cart. */
discountCodes?: CartType['discountCodes'];
/** The cost for the cart, including the subtotal, total, taxes, and duties. */
cost?: CartType['cost'];
/** The total number of items in the cart, across all lines. If there are no lines, then the value is 0. */
totalQuantity?: number;
}
interface CartActions {
/** The status of the cart. This returns `uninitialized` when the cart is not yet created, `creating` when the cart is being created, `fetching` when an existing cart is being fetched, `updating` when the cart is updating, and `idle` when the cart isn't being created or updated. */
status: CartStatus;
/** If an error occurred on the previous cart action, then `error` will exist and `cart` will be put back into the last valid status it was in. */
error?: unknown;
/** A callback that creates a cart. Expects the same input you would provide to the Storefront API's `cartCreate` mutation. */
cartCreate: (cart: CartInput) => void;
/** A callback that adds lines to the cart. Expects the same `lines` input that you would provide to the Storefront API's `cartLinesAdd` mutation. If a cart doesn't already exist, then it will create the cart for you. */
linesAdd: (lines: CartLineInput[]) => void;
/** A callback that removes lines from the cart. Expects the same `lines` input that you would provide to the Storefront API's `cartLinesRemove` mutation. Only lines that are included in the `lines` parameter will be in the cart afterwards. */
linesRemove: (lines: string[]) => void;
/** A callback that updates lines in the cart. Expects the same `lines` input that you would provide to the Storefront API's `cartLinesUpdate` mutation. If a line item is not included in the `lines` parameter, it will still exist in the cart and will not be changed. */
linesUpdate: (lines: CartLineUpdateInput[]) => void;
/** A callback that updates the note in the cart. Expects the same `note` input that you would provide to the Storefront API's `cartNoteUpdate` mutation. */
noteUpdate: (note: MutationCartNoteUpdateArgs['note']) => void;
/** A callback that updates the buyer identity in the cart. Expects the same `buyerIdentity` input that you would provide to the Storefront API's `cartBuyerIdentityUpdate` mutation. */
buyerIdentityUpdate: (buyerIdenity: CartBuyerIdentityInput) => void;
/** A callback that updates the cart attributes. Expects the same `attributes` input that you would provide to the Storefront API's `cartAttributesUpdate` mutation. */
cartAttributesUpdate: (attributes: MutationCartAttributesUpdateArgs['attributes']) => void;
/** A callback that updates the cart's discount codes. Expects the same `codes` input that you would provide to the Storefront API's `cartDiscountCodesUpdate` mutation. */
discountCodesUpdate: (discountCodes: string[]) => void;
/** The total number of items in the cart, across all lines. If there are no lines, then the value is 0. */
totalQuantity?: number;
/** The fragment used to query the cart object for all queries and mutations. */
cartFragment: string;
/** A boolean indicating if the cart is ready to be interacted with. */
cartReady?: boolean;
}
export type Cart = PartialDeep<CartBase, {
recurseIntoArrays: true;
}>;
export interface CartWithActions extends Cart, CartActions {
}
export interface CartWithActionsDocs extends CartBase, CartActions {
}
export type CartState =
/** A cart has not been created yet, or an error occurred when a cart was attempting to be created or fetched. */
{
status: 'uninitialized';
error?: string;
}
/** An existing cart is being fetched from the Storefront API. */
| {
status: 'fetching';
}
/** A new cart is being created through the Storefront API. */
| {
status: 'creating';
}
/** The cart is in the process of being updated. */
| {
status: 'updating';
cart: Cart;
lastValidCart: Cart;
}
/** The cart has been created and no action is currently happening. */
| {
status: 'idle';
cart: Cart;
error?: string;
};
export type CartAction = {
type: 'cartFetch';
} | {
type: 'cartCreate';
} | {
type: 'addLineItem';
} | {
type: 'removeLineItem';
lines: string[];
} | {
type: 'updateLineItem';
lines: CartLineUpdateInput[];
} | {
type: 'noteUpdate';
} | {
type: 'buyerIdentityUpdate';
} | {
type: 'cartAttributesUpdate';
} | {
type: 'discountCodesUpdate';
} | {
type: 'resolve';
cart: Cart;
rawCartResult?: PartialDeep<CartType, {
recurseIntoArrays: true;
}>;
} | {
type: 'reject';
errors: unknown;
} | {
type: 'resetCart';
};
export type CartMachineContext = {
cart?: PartialDeep<Cart, {
recurseIntoArrays: true;
}>;
lastValidCart?: PartialDeep<Cart, {
recurseIntoArrays: true;
}>;
rawCartResult?: PartialDeep<CartType, {
recurseIntoArrays: true;
}>;
prevCart?: PartialDeep<Cart, {
recurseIntoArrays: true;
}>;
errors?: unknown;
};
export type CartFetchEvent = {
type: 'CART_FETCH';
payload: {
cartId: string;
};
};
export type CartCreateEvent = {
type: 'CART_CREATE';
payload: CartInput;
};
export type CartSetEvent = {
type: 'CART_SET';
payload: {
cart: CartType;
};
};
export type CartLineAddEvent = {
type: 'CARTLINE_ADD';
payload: {
lines: CartLineInput[];
};
};
export type CartLineRemoveEvent = {
type: 'CARTLINE_REMOVE';
payload: {
lines: string[];
};
};
export type CartLineUpdateEvent = {
type: 'CARTLINE_UPDATE';
payload: {
lines: CartLineUpdateInput[];
};
};
export type NoteUpdateEvent = {
type: 'NOTE_UPDATE';
payload: {
note: MutationCartNoteUpdateArgs['note'];
};
};
export type BuyerIdentityUpdateEvent = {
type: 'BUYER_IDENTITY_UPDATE';
payload: {
buyerIdentity: CartBuyerIdentityInput;
};
};
export type CartAttributesUpdateEvent = {
type: 'CART_ATTRIBUTES_UPDATE';
payload: {
attributes: MutationCartAttributesUpdateArgs['attributes'];
};
};
export type DiscountCodesUpdateEvent = {
type: 'DISCOUNT_CODES_UPDATE';
payload: {
discountCodes: string[];
};
};
export type CartMachineActionEvent = CartFetchEvent | CartCreateEvent | CartSetEvent | CartLineAddEvent | CartLineRemoveEvent | CartLineUpdateEvent | NoteUpdateEvent | BuyerIdentityUpdateEvent | CartAttributesUpdateEvent | DiscountCodesUpdateEvent;
export type CartMachineFetchResultEvent = {
type: 'CART_COMPLETED';
payload: {
cartActionEvent: CartMachineActionEvent;
};
} | {
type: 'RESOLVE';
payload: {
cartActionEvent: CartMachineActionEvent;
cart: Cart;
rawCartResult: PartialDeep<CartType, {
recurseIntoArrays: true;
}>;
};
} | {
type: 'ERROR';
payload: {
cartActionEvent: CartMachineActionEvent;
errors: unknown;
};
};
export type CartMachineEvent = CartMachineActionEvent | CartMachineFetchResultEvent;
export type CartMachineTypeState = {
value: 'uninitialized';
context: CartMachineContext & {
cart: undefined;
lastValidCart: undefined;
prevCart: undefined;
errors?: unknown;
};
} | {
value: 'initializationError';
context: CartMachineContext & {
cart: undefined;
lastValidCart: undefined;
prevCart: undefined;
errors: unknown;
};
} | {
value: 'cartCompleted';
context: CartMachineContext & {
cart: undefined;
prevCart?: Cart;
lastValidCart: undefined;
errors: unknown;
};
} | {
value: 'idle';
context: CartMachineContext & {
cart: Cart;
prevCart?: Cart;
lastValidCart?: Cart;
errors?: unknown;
};
} | {
value: 'error';
context: CartMachineContext & {
cart?: Cart;
prevCart?: Cart;
lastValidCart?: Cart;
errors: unknown;
};
} | {
value: 'cartFetching';
context: CartMachineContext;
} | {
value: 'cartCreating';
context: CartMachineContext;
} | {
value: 'cartLineRemoving';
context: CartMachineContext;
} | {
value: 'cartLineUpdating';
context: CartMachineContext;
} | {
value: 'cartLineAdding';
context: CartMachineContext;
} | {
value: 'noteUpdating';
context: CartMachineContext;
} | {
value: 'buyerIdentityUpdating';
context: CartMachineContext;
} | {
value: 'cartAttributesUpdating';
context: CartMachineContext;
} | {
value: 'discountCodesUpdating';
context: CartMachineContext;
};
export type CartMachineAction = StateMachine.ActionFunction<CartMachineContext, CartMachineEvent>;
export type CartMachineActions = {
cartFetchAction: CartMachineAction;
cartCreateAction: CartMachineAction;
cartLineRemoveAction: CartMachineAction;
cartLineUpdateAction: CartMachineAction;
cartLineAddAction: CartMachineAction;
noteUpdateAction: CartMachineAction;
buyerIdentityUpdateAction: CartMachineAction;
cartAttributesUpdateAction: CartMachineAction;
discountCodesUpdateAction: CartMachineAction;
onCartActionEntry?: CartMachineAction;
onCartActionOptimisticUI?: StateMachine.AssignActionObject<CartMachineContext, CartMachineEvent>;
onCartActionComplete?: CartMachineAction;
};
export {};