import { type ReadonlySignal } from "@preact/signals-core"; import type { ResponseErrors } from "@shopify/graphql-client"; import { MetafieldOptions, StorefrontContext } from "../options/types"; import type { SwishApp } from "../swish"; import { LoadCollectionProductsArgs } from "./load-collection-products"; import { LoadProductArgs } from "./load-product"; import { LoadProductsArgs } from "./load-products"; import { ResolvedProductEntry } from "./load-products-by-ids"; import { LoadProductIdArgs } from "./load-product-id"; import { LoadProductImagesArgs } from "./load-product-images"; import { LoadResolvedProductArgs } from "./load-resolved-product"; import { LoadProductRecommendationsArgs } from "./load-product-recommendations"; import { LoadProductHandleArgs } from "./load-product-handle"; export * from "./load-collection-products"; export * from "./load-products"; export * from "./load-products-by-ids"; export * from "./load-product"; export * from "./load-product-recommendations"; export * from "./load-resolved-product"; export * from "./types/storefront.generated"; export type { SelectedOptionInput } from "./types/storefront.types"; export interface StorefrontApiResponse { data: TData; errors: ResponseErrors; } export declare const API_VERSION = "2026-04"; export interface StorefrontApiOptions { storeDomain: string; accessToken: string; } export declare const STOREFRONT_PRODUCT_STALE_TIME: number; export declare class StorefrontApiClient { private readonly client; private readonly shortCache; private readonly longCache; private readonly options; private readonly context; private metafields; private readonly baseProductMetafields; private readonly productDataVersionSignal; private swishApp; private readonly productLoader; constructor(options: StorefrontApiOptions, context: StorefrontContext, metafields?: MetafieldOptions); fetch(input: string | URL | Request, init?: RequestInit): Promise; query: >(query: string, variables: TVariables) => Promise<{ data: (TData extends undefined ? any : TData) | undefined; errors: ResponseErrors | null; }>; loadProduct: (args: ArgsWithoutDefaults) => Promise<{ data: { product: import("../types").Product | null; variant: import("../types").ProductVariant | null; }; errors: ResponseErrors | null; }>; loadProductImages: (args: ArgsWithoutDefaults) => Promise<{ data: (Pick | undefined)[]; errors: null; } | { data: null; errors: Error; }>; loadProductRecommendations: (args: ArgsWithoutDefaults) => Promise<{ data: { productRecommendations: { id: string; }[] | null; }; errors: ResponseErrors | null; }>; loadProductId: (args: LoadProductIdArgs) => Promise<{ data: import("./storefront-api-client").GetProductIdByHandleQuery | undefined; errors: ResponseErrors | null; }>; loadProductHandle: (args: LoadProductHandleArgs) => Promise<{ data: import("./storefront-api-client").GetProductHandleByIdQuery | undefined; errors: ResponseErrors | null; }>; loadCollectionProducts: (args: ArgsWithoutDefaults) => Promise<{ data: import("./storefront-api-client").GetCollectionProductsQuery | undefined; errors: ResponseErrors | null; }>; /** * Internal — do not document. Customiser preview seeding only. * * Loads a page of products straight from the store's root `products` field — * works on any store without requiring a collection handle (unlike * `loadCollectionProducts`, whose `handle: "all"` returns null on stores that * have no real collection with that handle). * * Primary use case: loading representative products for the customiser's * drawer preview seeding (see `preview-seeding.ts` in the customiser). * * @example * const result = await swish.storefront.loadProducts({ first: 20 }); * const ids = result.data?.products?.nodes?.map((n) => n.id) ?? []; */ loadProducts: (args: ArgsWithoutDefaults) => Promise<{ data: import("./storefront-api-client").GetProductsQuery | undefined; errors: ResponseErrors | null; }>; /** * Resolves a single product into a render-ready shape, transparently handling * combined listings. This is the primitive the built-in UI uses; it is * exposed here so custom (headless / vanilla-JS) wishlist pages can render * items without reimplementing combined-listing logic. */ loadResolvedProduct: (args: LoadResolvedProductArgs) => Promise; /** * Raw batched product fetch used exclusively by the products DataLoader. * Injects the store's metafields/localization; takes node GIDs directly. */ loadProductsByIdsRaw: (ids: string[]) => Promise<{ data: ResolvedProductEntry[]; errors: ResponseErrors | null; }>; /** * Loads the base product/variant for a single reference, cached per product * in the TanStack QueryClient and coalesced into batched `nodes(ids:)` * requests via the products DataLoader. * * Handle-only and active option-selection loads can't be batched by id (they * need `variantBySelectedOptions`), so they fall back to a direct * `loadProduct`. */ loadProductBatched: (args: LoadResolvedProductArgs) => Promise; /** * Wires the running SwishApp instance into the client. Called once during SDK * construction so the resolved-product loaders can reach `options.transforms` * and the AJAX client. */ setSwishApp(swish: SwishApp): void; private requireSwishApp; /** * Internal — do not document. Customiser preview only. * * Ticks each time `setPreviewProductMetafields` changes the metafields * products load with. Product hooks reload on a tick. It never ticks on a * live storefront. */ get productDataVersion(): ReadonlySignal; /** * Internal — do not document. Customiser preview only. * * Sets the product metafields the preview loads: the ones this client was * built with, plus `names`. On a live storefront the list is fixed once, by * createSwishOptions. The preview must follow badge rules the merchant is * still editing (SWI-3067), or a rule for a new metafield never finds a value. * `names` replaces the previous preview set rather than adding to it, so each * partial name typed during an edit does not stay in the query. * * When the list changes, cached product rows are marked stale and * `productDataVersion` ticks, so mounted cards load again. The changed query * body also misses the fetch cache. Returns whether the list changed. */ setPreviewProductMetafields(names: readonly string[]): boolean; clearCache(): Promise; } type ArgsWithoutDefaults = Omit;