import { CreateCartMutationVariables, GetCartQueryVariables, GetLastCartQueryVariables, LineItemFieldCreate, LineItemFieldFragment, ModifyCartMutationVariables, OrderState, ProductFieldType } from "../graphql/types"; import { AbstractOp, GraphQLOpts, RequestResponseError } from "../request"; import { Store } from "effector"; export interface CartType { discount_code: string | null; id: string; line_items: Array<{ id: string; quantity: number; variant: Variant | null; variant_id: string | null; discount_preview: number; field_set: { id: string; } | null; fields: Array<{ field_index: number; choice_index: number; type: ProductFieldType; label: string; value: string; }>; subscription_plan_index: number; }>; state: OrderState; updated_at: string; uuid: string; currency: string; } export interface CartLineItem { quantity: number; variant: Variant | undefined; variantID: string; discountPreview: number; fieldSetID: string; fields?: LineItemFieldFragment[]; subscriptionPlanIndex?: number; } export interface CartOperationResult { orders: Array> | null; } export interface CartOperationResultSingular { order: CartType | null; } export interface CartAPIState { cart: CartType; lineItems: CartLineItem[]; } /** * Cart background activity state. * - **idle**: cart is doing nothing * - **sync**: cart is syncing line items with the server * - **init**: cart is initializing * - **discount**: applying/removing discount code * - **currency**: applying currency */ export declare type CartActivity = "idle" | "sync" | "init" | "discount" | "currency"; export interface CartConfig { /** * A set of GraphQL queries cart uses to manipulate cart's server-side state. One can provide custom ones as * long as they pass minimum requirements (this is ensured only by typescript type safety). Or one can use * default ones from "./config/defaultCartGraphQLConfig". */ readonly graphql: { readonly getCartQuery: AbstractOp, GetCartQueryVariables>; readonly getLastCartQuery: AbstractOp, GetLastCartQueryVariables>; readonly createCartMutation: AbstractOp, CreateCartMutationVariables>; readonly modifyCartMutation: AbstractOp, ModifyCartMutationVariables>; }; /** Your shop id. */ readonly shopID: string; /** These graphql options are applied to all "request" api calls cart does. */ readonly opts?: GraphQLOpts; /** Internal debug hook, interface is not specified, use at your own risk. */ readonly debug?: any; /** A store that represents current auth state. You should pass it in to keep auth state in-sync. */ readonly jwt: Store; /** Current locale. Module will react to its changes. */ readonly locale: Store; } /** * All variants for cart initialization. * * 1. **fetch_last**: Fetch last cart for a registered customer. This option assumes that config contains a * valid authToken. * 2. **fetch_by_id**: Fetch cart by id and uuid. This options works best for unregistered customers, who created a cart * and saved its id/uuid in localStorage. * 3. **new**: Create a new cart. New cart is created lazily when customer adds items to it. */ export declare type CartInit = { kind: "fetch_last"; } | { kind: "fetch_by_id"; id: string; uuid: string; } | { kind: "fetch_last_or_by_id"; id: string; uuid: string; } | { kind: "new"; }; /** * When applying discount code, it responds with one of these. * * - **ok**: Everything is okay, discount code was applied, its value will be reported via onChange() callback. * - **discarded**: Something failed on init/sync stage, ignore this error, the Cart API will call onSyncLock(true) * and you will have to lock the UI in another place. Feel free to avoid clearing discount code input field. Customer * might want to retry after "reload()". * - **not_found**: Discount code is not found or expired. * - **customer_id_required**: If promotion has max uses per customer restriction, it requires customer id to be * assigned to the cart/order. Ask your customer to enter it again at a later stage. * - **unexpected_error**: Unexpected error happened during API call. Most likely connectivity issue. */ export declare type ApplyDiscountCodeResult = { kind: "ok"; } | { kind: "discarded"; } | { kind: "not_found"; } | { kind: "customer_id_required"; } | { kind: "unexpected_error"; error: RequestResponseError; }; export interface Cart { /** * Once cart is created or fetched, this reflects the currency used by the cart. */ currency: Store; /** * Use this store for discount code input field. Its value will be used on {@link Cart#applyDiscountCode}. */ discountCodeInput: Store; /** * This store is used to report changes on background cart activity. Cart code might delay activity report * changes with intention to provide better UI experience. */ activity: Store; /** * This store is changed if there was a failure during cart line items synchronization. You cannot perform * any actions with the cart but "reload()" after this point. Make sure UI reflects this. Note that this store * is also changed when cart is restored after "reload()". */ locked: Store; /** * Current line items on the cart. Could be result of client-side prediction or up-to-date info from the server. */ lineItems: Store[]>; /** * The most recent cart data received from the server. It also contains line items augmented with data * from prediction model. For example if server fails to expand a variant on a line item, but this * line item was added prior to that using predicted data, the line item will keep using predicted data. */ cartData: Store | null>; /** * Represents current discount code received from the server. */ discountCode: Store; /** * Whether "apply discount code" operation is pending (disable "apply" button if so). */ discountCodePending: Store; /** * Outcome of the last "apply discount code" operation. * * @see {ApplyDiscountCodeResult} */ discountCodeResult: Store; /** * Make an attempt to unlock the cart by reloading it from the server. If cart ends up being locked (see: "locked" Store), * you should display an error UI which offers customer to reload the cart by clicking a button. All cart operations * will throw an exception if you try to invoke them in a locked state. */ reload(): void; /** * Set cart item. * * Second "variant" parameter is optional, however it's recommended to provide one, this variant info is used for * client-side prediction. The info you pass in will be reflected in "lineItems" Store instantly as a result * client-side prediction. Furthermore if server fails to provide variant info, the existing info will be used * instead. This may happen for example if shop was statically generated, but since then the target product * was unpublished. */ setItem(variantID: string, variant: Variant | undefined, quantity: number, fieldSetID?: string, fields?: LineItemFieldCreate[], subscriptionPlanIndex?: number): void; /** * Change cart item, use quantityDelta == +1 to increment item quantity (or add a new item), use quantityDelta == -1 * to decrement an item. You can of course use other quantities. * * Second "variant" parameter is optional, however it's recommended to provide one, this variant info is used for * client-side prediction. The info you pass in will be reflected in "lineItems" Store instantly as a result * client-side prediction. Furthermore if server fails to provide variant info, the existing info will be used * instead. This may happen for example if shop was statically generated, but since then the target product * was unpublished. */ changeItem(variantID: string, variant: Variant | undefined, quantityDelta: number, fieldSetID?: string, fields?: LineItemFieldCreate[], subscriptionPlanIndex?: number): void; /** * Remove item from the cart. */ removeItem(variantID: string): void; /** * Apply discount code to the cart. * * @see {Cart.discountCodeInput} */ applyDiscountCode(): void; /** * Remove discount code from the cart. */ removeDiscountCode(): void; /** * Use method to set value for {@link Cart#discountCodeInput} */ setDiscountCodeInput(value: string): void; /** * This callback is executed in cart's queue once everything is settled. It is meant to be used for checkout flow. */ checkout(callback: () => Promise): void; /** * Set cart's currency. When "soft" mode is used, the currency is only set if there is no cart yet. */ setCurrency(currency: string, mode?: "soft"): void; } /** * Create the Cart instance with a given config and init option. Note that if init option is not "new", cart * will start fetching its state from the server right away. */ export declare function createCart(config: CartConfig, init: CartInit): Cart;