export type CatalogStatus = "draft" | "active" | "archived"; export type ProductStatus = "draft" | "active" | "archived"; export type ListingStatus = "draft" | "active" | "hidden" | "archived"; export type InventoryPolicy = "deny" | "continue" | "external"; export type ProductMediaKind = "image" | "model" | "video" | "mockup"; export type ProductMediaView = "front" | "back" | "left" | "right" | "detail" | "model" | "other"; export type BrandColor = { name: string; hex: string; pantone?: string; }; export type BrandAsset = { id: string; name: string; type: "logo" | "icon" | "pattern" | "other"; url: string; variant?: "primary" | "secondary" | "light" | "dark" | "other"; }; /** Store/company identity plus reusable customer-approved design assets. */ export type BrandKit = { name?: string; assets: BrandAsset[]; colors: BrandColor[]; fonts: { name: string; family?: string; url?: string; }[]; guidelinesUrl?: string; notes?: string; }; export declare const emptyBrandKit: () => BrandKit; export type Catalog = { id: string; /** Host-controlled tenant/company identifier. */ ownerKey?: string | null; slug: string; name: string; status: CatalogStatus; currency: string; locale: string; brandKit: BrandKit; settings: Record; }; export type CatalogSource = { id: string; ownerKey?: string | null; provider: string; name: string; status: "active" | "paused" | "syncing" | "error"; /** Non-secret adapter configuration. Store credentials in the host secret store. */ settings: Record; cursor?: string | null; lastSyncedAt?: string | null; lastError?: string | null; productsSynced?: number; variantsSynced?: number; }; export type CatalogTaxon = { /** Provider-stable category, collection, or product-type identity. */ externalId: string; name: string; slug: string; kind: "category" | "subcategory" | "product_type" | "other"; parentExternalId?: string | null; metadata: Record; }; export type ProductMedia = { id?: string; kind: ProductMediaKind; url: string; alt?: string; view?: ProductMediaView; /** Supplier color code/name this asset depicts; absent means universal. */ color?: string; position?: number; }; export type DecorationArea = { id: string; name: string; methods: string[]; widthIn?: number; heightIn?: number; metadata?: Record; }; export type CatalogProduct = { id: string; sourceId?: string | null; externalId?: string | null; brand: string; styleCode: string; slug: string; title: string; description: string; category: string; productType: string; status: ProductStatus; tags: string[]; /** Ordered option names, e.g. ["Color", "Size"]. */ optionNames: string[]; attributes: Record; media: ProductMedia[]; decorationAreas: DecorationArea[]; metadata: Record; }; export type ProductVariant = { id: string; productId: string; externalId?: string | null; sku: string; supplierSku?: string | null; barcode?: string | null; /** Generic option map supports apparel and non-apparel catalogs alike. */ options: Record; priceCents?: number | null; compareAtCents?: number | null; costCents?: number | null; currency: string; inventoryPolicy: InventoryPolicy; inventoryQuantity?: number | null; available: boolean; media: ProductMedia[]; metadata: Record; }; export type CatalogListing = { id: string; catalogId: string; productId: string; slug: string; status: ListingStatus; position: number; /** Store-specific merchandising overrides. */ title?: string | null; description?: string | null; basePriceCents?: number | null; compareAtCents?: number | null; tags: string[]; /** approved | customizable | both | none */ customizationMode: "approved" | "customizable" | "both" | "none"; /** Approved art/placements, decoration constraints, buyer fields, etc. */ customization: CatalogCustomizationPolicy; metadata: Record; }; export type CatalogApprovedArtwork = { id: string; name: string; url: string; placements?: string[]; metadata?: Record; }; export type CatalogBuyerField = { id: string; label: string; required: boolean; type: "text" | "textarea" | "select"; options?: string[]; }; /** Store-owned policy; supplier decoration capabilities remain on CatalogProduct. */ export type CatalogCustomizationPolicy = { allowedPlacements?: string[]; approvedArtwork?: CatalogApprovedArtwork[]; buyerFields?: CatalogBuyerField[]; metadata?: Record; }; export type ResolvedCatalogListing = { listing: CatalogListing; product: CatalogProduct; variants: ProductVariant[]; }; export type CatalogCollection = { id: string; catalogId: string; slug: string; title: string; description?: string | null; imageUrl?: string | null; status: CatalogStatus; position: number; }; export type CatalogPage = { items: T[]; nextCursor?: string | null; }; export type InventoryLevel = { sku: string; available: boolean; quantity?: number | null; updatedAt?: string; }; /** Implemented by supplier adapters such as SanMar or S&S Activewear. */ export interface CatalogSourceProvider { readonly id: string; listTaxonomy?(): Promise; listProducts(input?: { cursor?: string; limit?: number; /** Provider-neutral free-text search across product and variant identity. */ search?: string; updatedAfter?: string; }): Promise>; getProduct?(externalId: string): Promise<{ product: CatalogProduct; variants: ProductVariant[]; } | null>; getInventory?(skus: string[]): Promise; } /** A variant may be sold when its feed says available and policy permits stock. */ export declare const variantIsAvailable: (variant: ProductVariant) => boolean; /** Resolve an exact SKU from arbitrary product options (case-insensitive). */ export declare const findVariantByOptions: (variants: ProductVariant[], selected: Record) => ProductVariant | null; /** Ordered, deduplicated option values for storefront selectors. */ export declare const optionValues: (variants: ProductVariant[], optionName: string, availableOnly?: boolean) => string[]; /** Listing price wins; otherwise use the exact variant's supplier/base price. */ export declare const listingPriceCents: (listing: CatalogListing, variant?: ProductVariant | null) => number | null; /** Prefer exact-color imagery, then neutral/unscoped supplier imagery. */ export declare const mediaForColor: (media: ProductMedia[], color?: string) => ProductMedia[];