import { ApiResponse, Item, ItemControllerFindData, ItemCount, ItemDetail, ListControllerFindData, ListDetail, MarkAsRead, NotificationsControllerFindData, Order, OrderDetail, OrdersControllerFindData, PaginatedApiResponse, Profile, SmartListsControllerFindItemsData, SmartListsControllerRemoveItemData, Subscription, SubscriptionsControllerFindData, SwishClientConfig, UpdateProfile } from "@swishapp/api-client/2026-07"; import { EventBus } from "../events/event-bus"; import { StorefrontContext } from "../options/types"; export interface SwishApiConfig extends SwishClientConfig { requestInterceptor?: (request: Request) => Promise | Request; responseInterceptor?: (response: Response, request: Request) => Promise | void; } export declare class SwishApi { private readonly cache; private readonly apiClient; private readonly config; private readonly itemsLoader; private readonly auth; private readonly storefrontContext; constructor(config: SwishApiConfig, context: StorefrontContext, eventBus: EventBus, cacheKeyPrefix: string, tokenUrl: string); private fetchFunction; private requestInterceptor; private responseInterceptor; /** * Whether a successful mutation can give the session a Swish profile, so a * renewed token would carry `has_profile: true` (SWI-3190). * * Two storefront mutations never do: a Save for later from the cart * (`POST /items` with `source: "cart"`) and removing a smart-list item (the * cart save's undo). swish-api leaves `has_profile` false after both, so * renewing only repeated a `/profiles/token` request, and a `token-update` * refetch, after every cart save. Everything else keeps renewing. If the * body can't be read, renew as before. */ private mayCreateProfile; setAuthToken(token: string): void; getAuthToken(): string | undefined; initAuth(): Promise; /** * Whether the current token carries a customer profile (`has_profile`). * * `false` until the first write mints a profile: the responseInterceptor * renews the token after the first successful mutation that can create one, * and the renewed token carries `has_profile = true`. A Save for later from * the cart creates no profile, so it leaves this `false` (SWI-3190). Exposed publicly (the `auth` instance is * private) so the customiser can gate one-time preview seeding on it — * seeding runs only when there's no profile yet, and the post-first-write * renewal makes later launches/reloads skip re-seeding for free. */ hasProfile(): boolean; /** * Profile gate — for the saved-items family (items, lists). * * These live on the Swish profile, which anonymous visitors get on their * first write. Until one exists there is nothing to read, so skip the request * and return the empty fallback. * * Smart lists are NOT gated — see `smartLists` below (SWI-2958). */ private withFallback; /** * Signed-in + profile gate — for notifications. * * Notifications are only ever raised against a profile (back-in-stock, price * drops on saved items) and are only surfaced to a signed-in customer, so * both conditions must hold before it's worth a request. */ private withSignedInCustomerFallback; /** * Signed-in gate — for the Shopify-account family (orders, profile). * * This data belongs to the Shopify customer, not the Swish profile, so a * signed-in customer with no Swish profile yet must still reach the API. * Don't add a `hasProfile()` check here. */ private withSignedInCustomer; get items(): { count: () => Promise>; list: (query?: ItemControllerFindData["query"], options?: { batch?: boolean; shared?: boolean; }) => Promise>; findById: (itemId: string) => Promise>; create: (items: import("@swishapp/api-client").CreateItem) => Promise>; delete: (itemIds: import("@swishapp/api-client").DeleteItems["itemIds"]) => Promise>; updateById: (itemId: string, body: import("@swishapp/api-client").UpdateItem) => Promise>; deleteById: (itemId: string) => Promise>; setListsById: (itemId: string, listIds: import("@swishapp/api-client").SetItemLists["listIds"]) => Promise>; }; get lists(): { list: (query?: ListControllerFindData["query"]) => Promise>; findById: (listId: string, options?: { shared?: boolean; }) => Promise>; create: (list: import("@swishapp/api-client").CreateList) => Promise>; updateById: (listId: string, body: import("@swishapp/api-client").UpdateList) => Promise>; deleteById: (listId: string) => Promise>; orderItems: (listId: string, itemIds: import("@swishapp/api-client").SetListItemsOrder["itemIds"]) => Promise>; addItemsToList: (listId: string, itemIds: import("@swishapp/api-client").AddItemsToList["itemIds"]) => Promise>; removeItemFromList: (listId: string, itemId: string) => Promise>; }; get orders(): { list: (query?: OrdersControllerFindData["query"]) => Promise>; findById: (orderId: string | number) => Promise>; }; get notifications(): { list: (query?: NotificationsControllerFindData["query"]) => Promise>; getUnreadCount: () => Promise>; markAsRead: (notificationIds: MarkAsRead["notificationIds"]) => Promise>; markAllAsRead: () => Promise>; deleteById: (id: string) => Promise>; }; /** * Smart lists ("recently-viewed", "saved-from-cart") are read straight * through, with no `hasProfile()` gate (SWI-2958). * * They belong to the session, not the Swish profile: a Save for later from * the cart creates a "saved-from-cart" item but leaves the token's * `has_profile` false (only a wishlist save sets it). Gating these reads * hid a shopper's first cart save until they also saved to the wishlist. * For a visitor with nothing saved, the API answers 200 with empty data. */ get smartLists(): { list: () => Promise>; findById: (smartListId: string) => Promise>; findItems: (smartListId: string, query?: SmartListsControllerFindItemsData["query"]) => Promise>; removeItem: (smartListId: SmartListsControllerRemoveItemData["path"]["smartListId"], itemId: string) => Promise>; }; get profiles(): { getProfile: () => Promise>; updateProfile: (body: UpdateProfile) => Promise>; createToken: (body?: import("@swishapp/api-client").CreateProfileToken) => Promise>; identify: (body: import("@swishapp/api-client").IdentifyProfile) => Promise>; }; /** * Back-in-stock subscriptions (SWI-1896). * * `create` passes straight through: a signed-out shopper can subscribe, and * the request interceptor awaits `initAuth()` before every call, so the * session token that mints the profile is already in place. The reads are * profile-gated like every other read here — a subscription only exists * against a profile, so without one there is nothing to fetch and an expired * token would 401 rather than return an empty list. */ get subscriptions(): { list: (query?: SubscriptionsControllerFindData["query"]) => Promise>; findById: (id: string) => Promise>; create: (body: import("@swishapp/api-client").CreateSubscription) => Promise>; updateById: (id: string, body: import("@swishapp/api-client").UpdateSubscription) => Promise>; deleteById: (id: string) => Promise>; }; clearCache(): Promise; }