// API + config types for the WooCommerce widget. // // Adapted from the Shopify widget. The big difference: quota/ledger enforcement // is handled SERVER-SIDE by the brain storefront gateway, which signals // exhaustion via HTTP 402 and visitor rate-limiting via HTTP 429. The widget no // longer talks to a separate billing API. /** * Response from the brain storefront try-on gateway: * POST {BRAIN_URL}/api/storefront/tryon */ export interface TryOnSyncResponse { image: string; // Base64-encoded PNG cached: boolean; } export interface AvatarData { imageData: string; // Base64 image createdAt: string; } export interface TryOnHistoryItem { id: string; resultImage: string; clothingImage: string; productTitle?: string; createdAt: string; } /** * window.AISTHETIX_CONFIG injected by the WordPress plugin. * Kept compatible with the existing global the portable widget reads. */ export interface WidgetConfig { /** Brain storefront try-on endpoint, e.g. https://api.aisthetix.app/api/storefront/tryon */ apiBaseUrl: string; /** Brain base URL, e.g. https://api.aisthetix.app (no trailing slash). */ brainUrl?: string; /** Brain client-event ingestion endpoint, e.g. {brainUrl}/api/events. */ eventsUrl?: string; /** Domain-restricted publishable key — safe for the browser. */ publishableKey: string; /** Garment image URL (mutated by the bootstrap on variation change). */ productImage: string; productTitle: string; productId: string; /** Product category slugs (provider routing). Empty for uncategorized products. */ productCategories?: string[]; siteUrl?: string; /** WooCommerce site locale, e.g. "it_IT". */ locale?: string; /** Logged-in customer id, or null for guests. */ customerId?: string | null; /** * Durable first-party visitor key (the plugin's aisthetix_vid cookie) — the * PRIMARY attribution key. Falls back to the localStorage visitor id when absent. */ visitorKey?: string | null; /** variationId -> image URL map for variable products. */ variationImages?: Record; } /** * The kind of hard-stop the gateway reported, used to choose the blocked view. */ export type BlockedReason = 'quota_exhausted' | 'visitor_rate_limited'; export type WidgetState = | 'idle' | 'avatar-upload' | 'processing' | 'completed' | 'error' | 'quota-exceeded' | 'visitor-rate-limited';