@thorprovider/adapters 5.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +6 -0
- package/README.md +53 -631
- package/dist/index.d.mts +406 -194
- package/dist/index.d.ts +406 -194
- package/dist/index.js +3092 -604
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3081 -602
- package/dist/index.mjs.map +1 -1
- package/docs/RETRY_SOLUTION_SUMMARY.md +1 -1
- package/docs/authentication.md +0 -26
- package/docs/capabilities-system.md +66 -36
- package/docs/getting-started.md +1 -1
- package/docs/providers-overview.md +16 -13
- package/docs/update-documentation.md +10 -8
- package/package.json +6 -5
- package/quick-reference.md +0 -33
- package/src/backend/factory.ts +11 -1
- package/src/factory/index.ts +52 -74
- package/src/index.ts +17 -3
- package/src/providers/bigcommerce/bigcommerce.ts +6 -0
- package/src/providers/bigcommerce/index.ts +315 -0
- package/src/providers/bigcommerce/transforms.ts +227 -0
- package/src/providers/index.ts +16 -1
- package/src/providers/magento/index.ts +387 -0
- package/src/providers/magento/magento.ts +5 -0
- package/src/providers/magento/queries.ts +267 -0
- package/src/providers/magento/transforms.ts +249 -0
- package/src/providers/medusa/auth.test.ts +94 -92
- package/src/providers/medusa/auth.ts +72 -123
- package/src/providers/medusa/index.test.ts +392 -0
- package/src/providers/medusa/index.ts +1 -21
- package/src/providers/medusa/live-smoke.test.ts +412 -0
- package/src/providers/shopify/auth.ts +402 -0
- package/src/providers/shopify/index.ts +444 -0
- package/src/providers/shopify/mutations.ts +247 -0
- package/src/providers/shopify/queries.ts +324 -0
- package/src/providers/shopify/shopify.ts +7 -0
- package/src/providers/shopify/transforms.ts +275 -0
- package/src/providers/spree/index.ts +344 -0
- package/src/providers/spree/spree.ts +5 -0
- package/src/providers/spree/transforms.ts +254 -0
- package/src/providers/woocommerce/index.ts +310 -0
- package/src/providers/woocommerce/transforms.ts +254 -0
- package/src/providers/woocommerce/woocommerce.ts +5 -0
- package/src/types/capabilities.types.ts +250 -0
- package/vitest.live.config.ts +18 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types/capabilities.types.ts","../src/core/errors.ts","../src/core/logger.ts","../src/core/fetch-utils.ts","../src/resilience/circuit-breaker.ts","../src/lib/money-transform.ts","../src/utils/payment-utils.ts","../src/utils/city-coordinates.ts","../src/utils/geolocation.ts","../src/providers/medusa/fulfillment-planner.ts","../src/providers/medusa/transforms.ts","../src/admin/AdminAuthService.ts","../src/admin/AdminSessionService.ts","../src/admin/MetricsService.ts","../src/backend/factory.ts","../src/backend/medusa/MedusaMetadataAdapter.ts","../src/metadata/channel-scope.ts","../src/metadata/channel-scope-validation.ts","../src/providers/medusa/index.ts","../src/providers/medusa/auth.ts","../src/providers/medusa/payment.ts","../src/providers/medusa/admin.ts","../src/providers/stelorder/transforms.ts","../src/providers/stelorder/client.ts","../src/providers/stelorder/index.ts","../src/providers/mock/mock.ts","../src/providers/mock/index.ts","../src/factory/index.ts"],"sourcesContent":["/**\n * @thorprovider/adapters v2.0\n * Main package exports\n * \n * Unified commerce adapters for Thor Commerce ecosystem\n * Supports multiple e-commerce platforms through a common interface\n */\n\n// ============================================\n// Types\n// ============================================\nexport type * from './types';\n\n// ============================================\n// Commerce Provider Interface (from @thorprovider/types)\n// ============================================\n// Re-export for backward compatibility\nexport type {\n CommerceProvider,\n BackendCapabilities,\n ProviderConfig,\n StorefrontContext,\n StorefrontPlatformType,\n StorefrontConfig,\n StorefrontSeoDefaults,\n DesignerConfig,\n DesignerThemeConfig,\n DesignerThemePreset,\n DesignerNavItem,\n DesignerHistoryEntry,\n} from '@thorprovider/types';\n\nexport {\n StorefrontConfigError,\n} from '@thorprovider/types';\n\n// ============================================\n// Capabilities\n// ============================================\nexport {\n MOCK_CAPABILITIES,\n MEDUSA_CAPABILITIES,\n STELORDER_CAPABILITIES,\n isBackendCapabilities,\n getCapabilityDescription,\n} from './types/capabilities.types';\n\n// ============================================\n// Core Utilities\n// ============================================\nexport {\n CommerceError,\n ProviderNotFoundError,\n ConfigurationError,\n ResourceNotFoundError,\n ProviderAPIError,\n createLogger,\n fetchWithRetry,\n extractErrorMessage,\n type Logger,\n type LogLevel,\n type RetryConfig,\n} from './core';\n\n// ============================================\n// Resilience Patterns\n// ============================================\nexport {\n CircuitBreaker,\n backendCircuitBreaker,\n CircuitBreakerOpenError,\n type CircuitState,\n type CircuitBreakerConfig,\n type CircuitBreakerStats,\n} from './resilience';\n\n// ============================================\n// Transformation Utilities\n// ============================================\nexport {\n moneyToNumber,\n numberToMoney,\n moneyToNumberSafe,\n} from './lib/money-transform';\n\n// ============================================\n// Payment Utilities\n// ============================================\nexport {\n getBackendProviderId,\n validatePaymentId,\n type BackendMapping,\n} from './utils/payment-utils';\n\n// ============================================\n// Inventory & Fulfillment Utilities\n// ============================================\nexport {\n calculateDistance,\n geocodeAddress,\n type Coordinates,\n} from './utils/geolocation';\n\nexport {\n planFulfillment,\n type FulfillmentGroup,\n type FulfillmentPlan,\n type PlanFulfillmentShippingAddress,\n} from './providers/medusa/fulfillment-planner';\n\nexport {\n transformStockLocation,\n transformInventoryLevel,\n transformFulfillmentOption,\n transformStorefrontConfig,\n} from './providers/medusa/transforms';\n\n// ============================================\n// Admin Services\n// ============================================\nexport {\n AdminAuthService,\n AdminSessionService,\n MetricsService,\n} from './admin';\n\nexport type {\n AdminSession,\n MetricsOrderInput,\n MetricsProductInput,\n} from './admin';\n\n// ============================================\n// Backend Metadata Adapters\n// ============================================\nexport type {\n BackendMetadataAdapter,\n} from './backend/BackendMetadataAdapter';\n\nexport type {\n BackendMetadataAdapterConfig,\n} from './backend/factory';\n\nexport {\n createBackendMetadataAdapter,\n} from './backend/factory';\n\nexport {\n MedusaMetadataAdapter,\n} from './backend/medusa/MedusaMetadataAdapter';\n\n// ============================================\n// Channel Scope (Multi-Tenant Metadata Helpers)\n// ============================================\nexport {\n CHANNEL_SCOPE_KEY,\n CHANNEL_ASSIGNED_AT_KEY,\n CHANNEL_ASSIGNED_BY_KEY,\n buildChannelScopeMetadata,\n getChannelScope,\n isScopedToChannel,\n isGlobalEntity,\n filterByChannel,\n filterGlobalOnly,\n partitionByChannel,\n ChannelScopeValidationError,\n validateChannelId,\n validateEntityId,\n validateAssignedBy,\n validateChannelScopeAssignment,\n assertEntityBelongsToChannel,\n} from './metadata';\n\nexport type {\n ChannelScopeable,\n ChannelScopeMetadata,\n} from './metadata';\n\n// ============================================\n// Factory\n// ============================================\nexport {\n createProvider,\n registerProvider,\n getRegisteredProviders,\n isProviderType,\n type ProviderType,\n type ProviderFactoryConfig,\n} from './factory';\n\n// ============================================\n// Providers\n// ============================================\nexport {\n MedusaProvider,\n type MedusaProviderConfig,\n StelOrderProvider,\n type StelOrderProviderConfig,\n MockProvider,\n type MockProviderConfig,\n} from './providers';\n","/**\n * @thorprovider/adapters v2.0\n * Backend Capabilities System\n * \n * Defines what operations each backend platform supports.\n * This is a compile-time capability detection system, NOT runtime feature flags.\n * \n * NOTE: BackendCapabilities interface is defined in @thorprovider/types (L1: Foundation).\n * This file re-exports it and provides platform-specific implementations.\n * \n * @see packages/core/docs/BACKEND_CAPABILITIES_ANALYSIS.md\n * @see packages/core/docs/COMMERCE_PROVIDER_ARCHITECTURE.md\n */\n\nimport type { BackendCapabilities } from '@thorprovider/types';\n\nexport type { BackendCapabilities };\n\n/**\n * Mock backend capabilities\n *\n * Fixture-backed provider used when a storefront has not yet been connected\n * to a real backend. Supports the minimum commerce flows needed for layout,\n * preview, navigation, region switching, and cart prototyping.\n */\nexport const MOCK_CAPABILITIES: Readonly<BackendCapabilities> = {\n updateProfile: false,\n updateEmail: false,\n changePasswordDirect: false,\n changePasswordViaEmail: false,\n deleteAccount: false,\n uploadAvatar: false,\n avatarViaMetadata: false,\n customAttributes: false,\n fetchOrders: true,\n cancelOrder: true,\n manageAddresses: false,\n defaultAddress: false,\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: false,\n listPaymentProviders: true,\n regionSpecificPayments: true,\n wishlist: false,\n advancedSearch: false,\n facetedFilters: false,\n productReviews: false,\n loyaltyProgram: false,\n};\n\n/**\n * Medusa backend capabilities\n * \n * @see https://docs.medusajs.com/api/store\n */\nexport const MEDUSA_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: false, // Security restriction\n changePasswordDirect: false, // Email flow only\n changePasswordViaEmail: true,\n deleteAccount: true, // Implemented via ThorMedusaClient\n \n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: true,\n \n // Custom Attributes\n customAttributes: true,\n \n // Orders\n fetchOrders: true,\n cancelOrder: true,\n \n // Addresses\n manageAddresses: true,\n defaultAddress: true,\n \n // Cart/Checkout\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: false, // Depends on payment provider\n listPaymentProviders: true,\n regionSpecificPayments: true,\n \n // Wishlist\n wishlist: false, // Requires custom implementation\n \n // Search\n advancedSearch: true,\n facetedFilters: true,\n \n // Reviews\n productReviews: false, // Requires custom implementation\n \n // Loyalty\n loyaltyProgram: false, // Requires custom implementation\n};\n\n/**\n * Stel Order backend capabilities\n *\n * ERP/document API with catalog, CRM, inventory visibility, and sales documents,\n * but without cart, checkout, customer auth, or storefront-native payment flows.\n */\nexport const STELORDER_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: false,\n updateEmail: false,\n changePasswordDirect: false,\n changePasswordViaEmail: false,\n deleteAccount: false,\n\n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: false,\n\n // Custom Attributes\n customAttributes: false,\n\n // Orders\n fetchOrders: true,\n cancelOrder: false,\n\n // Addresses\n manageAddresses: true,\n defaultAddress: false,\n\n // Cart/Checkout\n applyDiscounts: false,\n shippingCalculation: false,\n guestCheckout: false,\n savedPaymentMethods: false,\n listPaymentProviders: true,\n regionSpecificPayments: false,\n\n // Wishlist\n wishlist: false,\n\n // Search\n advancedSearch: false,\n facetedFilters: false,\n\n // Reviews\n productReviews: false,\n\n // Loyalty\n loyaltyProgram: false,\n};\n\n/**\n * Type guard to check if an object is a valid BackendCapabilities\n */\nexport function isBackendCapabilities(obj: unknown): obj is BackendCapabilities {\n if (typeof obj !== 'object' || obj === null) return false;\n \n const capabilities = obj as Partial<BackendCapabilities>;\n \n // Check required profile management capabilities\n return (\n typeof capabilities.updateProfile === 'boolean' &&\n typeof capabilities.updateEmail === 'boolean' &&\n typeof capabilities.changePasswordDirect === 'boolean'\n );\n}\n\n/**\n * Get capability description for UI display\n */\nexport function getCapabilityDescription(capability: keyof BackendCapabilities): string {\n const descriptions: Record<keyof BackendCapabilities, string> = {\n updateProfile: 'Update profile information (name, phone)',\n updateEmail: 'Change email address',\n changePasswordDirect: 'Change password directly',\n changePasswordViaEmail: 'Request password reset via email',\n deleteAccount: 'Delete account (self-service)',\n uploadAvatar: 'Upload profile picture',\n avatarViaMetadata: 'Store avatar URL in metadata',\n customAttributes: 'Custom customer attributes',\n fetchOrders: 'View order history',\n cancelOrder: 'Cancel orders',\n manageAddresses: 'Add/update/delete addresses',\n defaultAddress: 'Set default address',\n applyDiscounts: 'Apply discount codes',\n shippingCalculation: 'Calculate shipping rates',\n guestCheckout: 'Checkout without account',\n savedPaymentMethods: 'Save payment methods',\n listPaymentProviders: 'List available payment providers',\n regionSpecificPayments: 'Region-specific payment methods',\n wishlist: 'Wishlist/favorites',\n advancedSearch: 'Advanced product search',\n facetedFilters: 'Filter by product attributes',\n productReviews: 'Product reviews and ratings',\n loyaltyProgram: 'Loyalty/rewards program',\n };\n \n return descriptions[capability] || capability;\n}\n","/**\n * @thorprovider/adapters v2.0\n * Core errors\n */\n\n/**\n * Base error class for commerce providers\n */\nexport class CommerceError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n public readonly status?: number\n ) {\n super(message);\n this.name = 'CommerceError';\n }\n}\n\n/**\n * Provider not found error\n */\nexport class ProviderNotFoundError extends CommerceError {\n constructor(providerName: string) {\n super(`Provider not found: ${providerName}`, 'PROVIDER_NOT_FOUND');\n this.name = 'ProviderNotFoundError';\n }\n}\n\n/**\n * Configuration error\n */\nexport class ConfigurationError extends CommerceError {\n constructor(message: string) {\n super(message, 'CONFIGURATION_ERROR');\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Resource not found error\n */\nexport class ResourceNotFoundError extends CommerceError {\n constructor(resource: string, identifier: string) {\n super(`${resource} not found: ${identifier}`, 'RESOURCE_NOT_FOUND', 404);\n this.name = 'ResourceNotFoundError';\n }\n}\n\n/**\n * API error from provider\n */\nexport class ProviderAPIError extends CommerceError {\n constructor(\n message: string,\n public readonly provider: string,\n status?: number\n ) {\n super(message, 'PROVIDER_API_ERROR', status);\n this.name = 'ProviderAPIError';\n }\n}\n\n/**\n * Extract error message from various error types\n * Handles standard Error objects, API responses, and unknown error types\n */\nexport function extractErrorMessage(error: unknown): string {\n // Standard Error object\n if (error instanceof Error && error.message) {\n // Don't return generic messages if there's more data\n if (error.message !== 'An unknown error occurred.') {\n return error.message;\n }\n }\n \n // Object with message property\n if (typeof error === 'object' && error !== null) {\n const err = error as any;\n \n // Check for response body (common in fetch errors)\n if (err.body) {\n if (typeof err.body === 'string') return err.body;\n if (err.body.message) return String(err.body.message);\n if (err.body.error?.message) return String(err.body.error.message);\n }\n \n // Check for response object\n if (err.response) {\n if (err.response.data?.message) return String(err.response.data.message);\n if (err.response.data?.error) return String(err.response.data.error);\n if (err.response.statusText) return `${err.response.status || ''} ${err.response.statusText}`.trim();\n }\n \n // Check for data property\n if (err.data?.message) return String(err.data.message);\n if (err.data?.error) return String(err.data.error);\n \n // Check for error property\n if (err.error?.message) return String(err.error.message);\n \n // Check for statusText with status code\n if (err.status && err.statusText) {\n return `HTTP ${err.status}: ${err.statusText}`;\n }\n \n if (err.status && !err.statusText) {\n return `HTTP ${err.status} Error`;\n }\n \n // Check for message property (not generic)\n if (err.message && err.message !== 'An unknown error occurred.') {\n return String(err.message);\n }\n \n // Try to stringify the error object\n try {\n const stringified = JSON.stringify(error);\n if (stringified !== '{}') return stringified;\n } catch {\n // Ignore JSON.stringify errors\n }\n }\n \n // String error\n if (typeof error === 'string') {\n return error;\n }\n \n // Fallback\n return 'An unknown error occurred';\n}\n","/**\n * @thorprovider/adapters v2.0\n * Core logger utility\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface Logger {\n debug(message: string, ...args: any[]): void;\n info(message: string, ...args: any[]): void;\n warn(message: string, ...args: any[]): void;\n error(message: string, ...args: any[]): void;\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(\n namespace: string,\n enabled: boolean = false\n): Logger {\n const log = (level: LogLevel, message: string, ...args: any[]) => {\n if (!enabled && level !== 'error') return;\n \n const timestamp = new Date().toISOString();\n const prefix = `[${timestamp}] [@thorprovider/adapters:${namespace}] ${level.toUpperCase()}:`;\n \n console[level](prefix, message, ...args);\n };\n \n return {\n debug: (message, ...args) => log('debug', message, ...args),\n info: (message, ...args) => log('info', message, ...args),\n warn: (message, ...args) => log('warn', message, ...args),\n error: (message, ...args) => log('error', message, ...args),\n };\n}\n","/**\n * @thorprovider/adapters v2.0\n * Fetch Utilities - Retry logic, timeouts, and error handling\n * \n * This module provides enhanced fetch capabilities with:\n * - Automatic retries with exponential backoff\n * - Configurable timeouts\n * - Better error handling for network failures\n */\n\nimport { createLogger } from './logger';\n\nconst logger = createLogger('FetchUtils');\n\n/**\n * Configuration for fetch retry behavior\n */\nexport interface RetryConfig {\n /**\n * Maximum number of retry attempts (default: 3)\n */\n maxRetries?: number;\n \n /**\n * Initial delay in milliseconds before first retry (default: 300ms)\n */\n initialDelayMs?: number;\n \n /**\n * Multiplier for exponential backoff (default: 2)\n */\n backoffMultiplier?: number;\n \n /**\n * Maximum delay between retries in milliseconds (default: 5000ms)\n */\n maxDelayMs?: number;\n \n /**\n * Timeout for each fetch attempt in milliseconds (default: 10000ms - 10 seconds)\n */\n timeoutMs?: number;\n \n /**\n * HTTP status codes that should trigger a retry (default: [408, 429, 500, 502, 503, 504])\n */\n retryableStatusCodes?: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelayMs: 300,\n backoffMultiplier: 2,\n maxDelayMs: 5000,\n timeoutMs: 10000, // 10 seconds\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\n/**\n * Sleep utility for delays between retries\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Calculate delay for exponential backoff\n */\nfunction calculateDelay(\n attempt: number,\n config: Required<RetryConfig>\n): number {\n const delay = config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt);\n return Math.min(delay, config.maxDelayMs);\n}\n\n/**\n * Check if error is retryable\n */\nfunction isRetryableError(error: any, config: Required<RetryConfig>): boolean {\n // Network errors (fetch failed, connection refused, etc.)\n if (error.name === 'TypeError' || error.message?.includes('fetch failed')) {\n return true;\n }\n \n // Timeout errors\n if (error.name === 'AbortError' || error.message?.includes('timeout')) {\n return true;\n }\n \n // HTTP status codes\n if (error.status && config.retryableStatusCodes.includes(error.status)) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Enhanced fetch with retry logic and timeout\n * \n * @example\n * ```typescript\n * import { fetchWithRetry } from '@thorprovider/adapters/core/fetch-utils';\n * \n * // Basic usage with defaults (3 retries, 10s timeout)\n * const response = await fetchWithRetry('https://api.example.com/products');\n * \n * // Custom configuration\n * const response = await fetchWithRetry(\n * 'https://api.example.com/products',\n * {\n * method: 'POST',\n * body: JSON.stringify({ name: 'Product' }),\n * },\n * {\n * maxRetries: 5,\n * timeoutMs: 15000, // 15 seconds\n * initialDelayMs: 500,\n * }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n init?: RequestInit,\n retryConfig?: RetryConfig\n): Promise<Response> {\n const config = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };\n let lastError: any;\n \n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n try {\n // Create AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), config.timeoutMs);\n \n const fetchOptions: RequestInit = {\n ...init,\n signal: controller.signal,\n };\n \n logger.debug('Fetch attempt', {\n url,\n attempt: attempt + 1,\n maxAttempts: config.maxRetries + 1,\n timeout: config.timeoutMs,\n });\n \n // Execute fetch\n const response = await fetch(url, fetchOptions);\n \n // Clear timeout\n clearTimeout(timeoutId);\n \n // Check if status code is retryable\n if (!response.ok && config.retryableStatusCodes.includes(response.status)) {\n const error = new Error(`HTTP ${response.status}: ${response.statusText}`);\n (error as any).status = response.status;\n throw error;\n }\n \n // Success!\n logger.debug('Fetch successful', { url, attempt: attempt + 1 });\n return response;\n \n } catch (error: any) {\n lastError = error;\n \n // Clear timeout if it exists\n if (error.name === 'AbortError') {\n lastError = new Error(`Request timeout after ${config.timeoutMs}ms`);\n lastError.name = 'TimeoutError';\n }\n \n // Check if we should retry\n const shouldRetry = attempt < config.maxRetries && isRetryableError(error, config);\n \n if (shouldRetry) {\n const delay = calculateDelay(attempt, config);\n logger.warn('Fetch failed, retrying...', {\n url,\n attempt: attempt + 1,\n maxAttempts: config.maxRetries + 1,\n nextRetryIn: `${delay}ms`,\n error: error.message,\n });\n \n await sleep(delay);\n } else {\n logger.error('Fetch failed after all retries', {\n url,\n totalAttempts: attempt + 1,\n error: error.message,\n });\n break;\n }\n }\n }\n \n // All retries exhausted, throw the last error\n throw lastError;\n}\n\n/**\n * Create a fetch function with custom retry configuration\n * Useful for creating a configured fetch instance\n * \n * @example\n * ```typescript\n * import { createFetchWithRetry } from '@thorprovider/adapters/core/fetch-utils';\n * \n * // Create configured fetch\n * const customFetch = createFetchWithRetry({\n * maxRetries: 5,\n * timeoutMs: 15000,\n * });\n * \n * // Use it like regular fetch\n * const response = await customFetch('https://api.example.com/products');\n * ```\n */\nexport function createFetchWithRetry(\n retryConfig?: RetryConfig\n): (url: string, init?: RequestInit) => Promise<Response> {\n return (url: string, init?: RequestInit) => fetchWithRetry(url, init, retryConfig);\n}\n","/**\n * Circuit Breaker Pattern Implementation\n * \n * Prevents cascading failures when the backend is unavailable.\n * Implements the Circuit Breaker pattern as described by Martin Fowler.\n * \n * States:\n * - CLOSED: Normal operation, requests pass through\n * - OPEN: Too many failures, requests fail fast\n * - HALF_OPEN: Testing if backend has recovered\n * \n * @see https://martinfowler.com/bliki/CircuitBreaker.html\n */\n\nexport type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit */\n failureThreshold: number;\n /** Time in ms to wait before attempting recovery */\n resetTimeout: number;\n /** Name for logging/monitoring */\n name?: string;\n}\n\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failureCount: number;\n lastFailureTime: number | null;\n totalRequests: number;\n totalFailures: number;\n totalSuccesses: number;\n}\n\n/**\n * Circuit Breaker Class\n * \n * Monitors backend calls and prevents cascading failures by\n * failing fast when the backend is unhealthy.\n * \n * @example\n * ```ts\n * const breaker = new CircuitBreaker({\n * failureThreshold: 3,\n * resetTimeout: 60000, // 1 minute\n * name: 'backend-api'\n * });\n * \n * const result = await breaker.execute(\n * () => fetch('/api/data'),\n * fallbackData\n * );\n * ```\n */\nexport class CircuitBreaker {\n private failureCount = 0;\n private lastFailureTime: number | null = null;\n private totalRequests = 0;\n private totalFailures = 0;\n private totalSuccesses = 0;\n \n constructor(private config: CircuitBreakerConfig) {\n this.config = {\n failureThreshold: config.failureThreshold || 5,\n resetTimeout: config.resetTimeout || 60000, // 1 minute default\n name: config.name || 'circuit-breaker',\n };\n }\n \n /**\n * Get current circuit state\n */\n get state(): CircuitState {\n if (this.failureCount >= this.config.failureThreshold) {\n // Circuit is open (failing fast)\n if (this.shouldAttemptReset()) {\n return 'HALF_OPEN'; // Try to recover\n }\n return 'OPEN';\n }\n return 'CLOSED'; // Normal operation\n }\n \n /**\n * Get circuit breaker statistics\n */\n get stats(): CircuitBreakerStats {\n return {\n state: this.state,\n failureCount: this.failureCount,\n lastFailureTime: this.lastFailureTime,\n totalRequests: this.totalRequests,\n totalFailures: this.totalFailures,\n totalSuccesses: this.totalSuccesses,\n };\n }\n \n /**\n * Execute a function with circuit breaker protection\n * \n * @param fn - Function to execute\n * @param fallback - Fallback value if circuit is open\n * @returns Result from fn or fallback\n */\n async execute<T>(\n fn: () => Promise<T>,\n fallback?: T\n ): Promise<T> {\n this.totalRequests++;\n \n const currentState = this.state;\n \n // If circuit is OPEN and we have a fallback, return it immediately\n if (currentState === 'OPEN') {\n this.log('Circuit is OPEN - failing fast');\n if (fallback !== undefined) {\n return fallback;\n }\n throw new CircuitBreakerOpenError(\n `Circuit breaker \"${this.config.name}\" is OPEN - backend may be unavailable`\n );\n }\n \n // Try to execute the function\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n this.onFailure();\n \n // If we have a fallback, use it\n if (fallback !== undefined) {\n this.log('Returning fallback due to error:', error);\n return fallback;\n }\n \n // Otherwise, re-throw the error\n throw error;\n }\n }\n \n /**\n * Check if circuit should attempt to reset\n */\n private shouldAttemptReset(): boolean {\n if (!this.lastFailureTime) return false;\n \n const timeSinceLastFailure = Date.now() - this.lastFailureTime;\n return timeSinceLastFailure >= this.config.resetTimeout;\n }\n \n /**\n * Record a successful call\n */\n private onSuccess(): void {\n this.totalSuccesses++;\n this.reset();\n this.log('Request succeeded - circuit reset');\n }\n \n /**\n * Record a failed call\n */\n private onFailure(): void {\n this.failureCount++;\n this.totalFailures++;\n this.lastFailureTime = Date.now();\n \n if (this.state === 'OPEN') {\n this.log(`Circuit OPENED after ${this.failureCount} failures`);\n } else {\n this.log(`Failure recorded (${this.failureCount}/${this.config.failureThreshold})`);\n }\n }\n \n /**\n * Reset circuit to CLOSED state\n */\n private reset(): void {\n this.failureCount = 0;\n this.lastFailureTime = null;\n }\n \n /**\n * Manually reset the circuit breaker\n */\n public manualReset(): void {\n this.reset();\n this.log('Circuit manually reset');\n }\n \n /**\n * Log messages (only in development)\n */\n private log(...args: unknown[]): void {\n if (process.env.NODE_ENV === 'development') {\n console.log(`[CircuitBreaker:${this.config.name}]`, ...args);\n }\n }\n}\n\n/**\n * Custom error for when circuit is open\n */\nexport class CircuitBreakerOpenError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CircuitBreakerOpenError';\n }\n}\n\n/**\n * Global circuit breaker instance for backend API calls\n * \n * Can be imported and used throughout the application\n */\nexport const backendCircuitBreaker = new CircuitBreaker({\n failureThreshold: 5, // Open after 5 failures\n resetTimeout: 60000, // Try to recover after 1 minute\n name: 'backend-api',\n});\n","/**\n * @thorprovider/adapters\n * Money transformation utilities\n * \n * Handles conversion between domain Money types (string decimals) and\n * UI-ready number representations (smallest currency unit, e.g., cents).\n */\n\nimport type { Money } from '@thorprovider/types';\n\n/**\n * Converts Money object to number in smallest currency unit\n * \n * Money.amount is a decimal string (e.g., \"45.99\").\n * This function converts it to smallest unit (e.g., 4599 cents).\n * \n * @param money - Money object with decimal string amount\n * @returns Amount in smallest currency unit (e.g., cents for USD)\n * \n * @example\n * ```typescript\n * moneyToNumber({ amount: \"45.99\", currencyCode: \"USD\" }) // => 4599\n * moneyToNumber({ amount: \"100.00\", currencyCode: \"EUR\" }) // => 10000\n * moneyToNumber({ amount: \"0.50\", currencyCode: \"USD\" }) // => 50\n * ```\n */\nexport function moneyToNumber(money: Money): number {\n // Parse decimal string and convert to cents (multiply by 100)\n const amountInMajorUnits = parseFloat(money.amount);\n const amountInMinorUnits = Math.round(amountInMajorUnits * 100);\n return amountInMinorUnits;\n}\n\n/**\n * Converts number (smallest unit) to Money object\n * \n * Takes an amount in smallest currency unit (e.g., cents) and\n * converts it to a Money object with decimal string amount.\n * \n * @param amount - Amount in smallest currency unit (e.g., cents)\n * @param currency - ISO 4217 currency code (e.g., 'USD', 'EUR')\n * @returns Money object with decimal string amount\n * \n * @example\n * ```typescript\n * numberToMoney(4599, 'USD') // => { amount: \"45.99\", currencyCode: \"USD\" }\n * numberToMoney(10000, 'EUR') // => { amount: \"100.00\", currencyCode: \"EUR\" }\n * numberToMoney(50, 'USD') // => { amount: \"0.50\", currencyCode: \"USD\" }\n * ```\n */\nexport function numberToMoney(amount: number, currency: string): Money {\n // Convert cents to dollars and format as decimal string\n const amountInMajorUnits = amount / 100;\n const formattedAmount = amountInMajorUnits.toFixed(2);\n \n return {\n amount: formattedAmount,\n currencyCode: currency,\n };\n}\n\n/**\n * Safely converts Money to number, returning 0 for null/undefined\n * \n * Useful for optional Money fields that might not always be present.\n * \n * @param money - Money object or null/undefined\n * @returns Amount in smallest unit, or 0 if money is null/undefined\n * \n * @example\n * ```typescript\n * moneyToNumberSafe({ amount: \"10.00\", currencyCode: \"USD\" }) // => 1000\n * moneyToNumberSafe(undefined) // => 0\n * moneyToNumberSafe(null) // => 0\n * ```\n */\nexport function moneyToNumberSafe(money: Money | null | undefined): number {\n if (!money) return 0;\n return moneyToNumber(money);\n}\n","/**\n * @thorprovider/adapters - Payment Utilities\n * \n * Backend-agnostic utilities for extracting backend provider IDs from\n * normalized PaymentMethod objects using metadata.\n * \n * This solves the problem of losing backend-specific provider IDs during\n * transformation to frontend-friendly formats.\n * \n * @module payment-utils\n * @since 2.0.0\n */\n\nimport type { PaymentMethod } from '@thorprovider/types';\n\n/**\n * Backend mapping metadata stored in PaymentMethod.metadata\n * \n * This metadata is added during payment method transformation\n * to preserve the original backend-specific identifier.\n * \n * @example\n * ```typescript\n * const metadata = {\n * _backendMapping: {\n * backend: 'medusa',\n * originalId: 'pp_stripe_stripe',\n * normalizedType: 'card'\n * }\n * };\n * ```\n */\nexport interface BackendMapping {\n /**\n * Backend type (e.g., 'medusa', 'shopify', 'woocommerce')\n */\n backend: string;\n \n /**\n * Original backend-specific provider ID\n * \n * Examples:\n * - Medusa: 'pp_stripe_stripe', 'pp_paypal_paypal', 'pp_system_default'\n * - Shopify: 'shopify_payments', 'paypal_express'\n * - WooCommerce: 'stripe', 'paypal', 'cod'\n */\n originalId: string;\n \n /**\n * Normalized payment method type\n * \n * The frontend-friendly type we inferred from the backend ID\n * (e.g., 'card', 'wallet', 'bank_transfer', 'cash_on_delivery')\n */\n normalizedType: string;\n}\n\n/**\n * Extract backend provider ID from PaymentMethod\n * \n * Uses the `_backendMapping` metadata to retrieve the original\n * backend-specific provider ID that should be sent to API calls.\n * \n * **Why this exists:**\n * During transformation, we normalize backend IDs to friendly types:\n * - Backend: 'pp_stripe_stripe' → Frontend: type 'card'\n * - Backend: 'pp_system_default' → Frontend: type 'cash_on_delivery'\n * \n * But when making API calls, we need the ORIGINAL backend ID, not the type.\n * This function extracts it from metadata.\n * \n * @param method - PaymentMethod with _backendMapping metadata\n * @returns Backend provider ID (e.g., 'pp_stripe_stripe', 'pp_system_default')\n * @throws {Error} If _backendMapping metadata is missing or invalid\n * \n * @example\n * ```typescript\n * // PaymentMethod from backend with metadata\n * const method = {\n * id: 'pp_system_default',\n * type: 'cash_on_delivery',\n * name: 'Cash on Delivery',\n * metadata: {\n * _backendMapping: {\n * backend: 'medusa',\n * originalId: 'pp_system_default',\n * normalizedType: 'cash_on_delivery'\n * }\n * }\n * };\n * \n * const providerId = getBackendProviderId(method);\n * // Returns: 'pp_system_default'\n * \n * // Now safe to use with backend API:\n * await commerce.initiatePaymentSession(cartId, providerId);\n * ```\n * \n * @example\n * ```typescript\n * // Handling missing metadata\n * try {\n * const providerId = getBackendProviderId(methodWithoutMetadata);\n * } catch (error) {\n * console.error('Payment method missing backend mapping:', error.message);\n * // Error: PaymentMethod 'stripe' is missing _backendMapping metadata.\n * // This is required to extract the backend provider ID.\n * }\n * ```\n */\nexport function getBackendProviderId(method: PaymentMethod): string {\n const mapping = method.metadata?._backendMapping as BackendMapping | undefined;\n \n if (!mapping) {\n throw new Error(\n `PaymentMethod '${method.id}' is missing _backendMapping metadata. ` +\n `This is required to extract the backend provider ID. ` +\n `Ensure the payment method was transformed with metadata preservation. ` +\n `Check transformPaymentMethod() implementation in your provider adapter.`\n );\n }\n \n if (!mapping.originalId) {\n throw new Error(\n `PaymentMethod '${method.id}' has invalid _backendMapping metadata: ` +\n `'originalId' field is missing or empty. ` +\n `Expected structure: { _backendMapping: { backend: 'medusa', originalId: 'pp_...', normalizedType: '...' } }`\n );\n }\n \n return mapping.originalId;\n}\n\n/**\n * Validate payment provider ID format\n * \n * Checks if the provider ID is a valid backend-specific identifier,\n * not a normalized type like 'card', 'wallet', etc.\n * \n * **Why this exists:**\n * Common bug: Accidentally sending normalized types to backend APIs:\n * ❌ `initiatePaymentSession(cartId, 'card')` → Backend error\n * ✅ `initiatePaymentSession(cartId, 'pp_stripe_stripe')` → Success\n * \n * This validation catches the bug at runtime with a helpful error message.\n * \n * @param id - Provider ID to validate\n * @throws {Error} If ID appears to be a normalized type instead of backend ID\n * \n * @example\n * ```typescript\n * // Valid backend IDs - pass validation:\n * validatePaymentId('pp_stripe_stripe'); // ✅ OK (Medusa)\n * validatePaymentId('pp_system_default'); // ✅ OK (Medusa)\n * validatePaymentId('shopify_payments'); // ✅ OK (Shopify)\n * validatePaymentId('stripe'); // ✅ OK (WooCommerce)\n * validatePaymentId('paypal_express'); // ✅ OK (generic)\n * \n * // Invalid (normalized types) - throw error:\n * validatePaymentId('card'); // ❌ Throws error\n * validatePaymentId('wallet'); // ❌ Throws error\n * validatePaymentId('cash_on_delivery'); // ❌ Throws error\n * ```\n * \n * @example\n * ```typescript\n * // Use before API calls:\n * async function initiatePayment(cartId: string, providerId: string) {\n * // Validate before sending to backend\n * validatePaymentId(providerId);\n * \n * return await sdk.payment.initiatePaymentSession(cart, {\n * provider_id: providerId\n * });\n * }\n * \n * // Catches bugs early:\n * await initiatePayment(cartId, 'card');\n * // ❌ Error: Invalid payment provider ID: 'card'.\n * // This appears to be a normalized payment type, not a backend provider ID.\n * // Use getBackendProviderId() to extract the correct backend ID from PaymentMethod.\n * ```\n */\nexport function validatePaymentId(id: string): void {\n const normalizedTypes = [\n 'card',\n 'wallet',\n 'bank_transfer',\n 'buy_now_pay_later',\n 'cash_on_delivery',\n 'crypto',\n 'other'\n ];\n \n if (normalizedTypes.includes(id)) {\n throw new Error(\n `Invalid payment provider ID: '${id}'. ` +\n `This appears to be a normalized payment type, not a backend provider ID. ` +\n `Use getBackendProviderId() to extract the correct backend ID from PaymentMethod. ` +\n `Expected format examples: 'pp_stripe_stripe', 'pp_system_default', 'shopify_payments', 'stripe'`\n );\n }\n}\n","/**\n * City coordinates lookup table\n *\n * Lightweight approximation for geocoding without external APIs.\n * Keep this small and extend as needed.\n */\n\nexport interface CityCoordinates {\n lat: number;\n lng: number;\n}\n\nconst CITY_COORDINATES: Record<string, Record<string, CityCoordinates>> = {\n US: {\n 'New York': { lat: 40.7128, lng: -74.0060 },\n 'Los Angeles': { lat: 34.0522, lng: -118.2437 },\n Chicago: { lat: 41.8781, lng: -87.6298 },\n Miami: { lat: 25.7617, lng: -80.1918 },\n },\n GB: {\n London: { lat: 51.5074, lng: -0.1278 },\n Manchester: { lat: 53.4808, lng: -2.2426 },\n },\n DE: {\n Berlin: { lat: 52.52, lng: 13.405 },\n Hamburg: { lat: 53.5511, lng: 9.9937 },\n },\n ES: {\n Madrid: { lat: 40.4168, lng: -3.7038 },\n Barcelona: { lat: 41.3851, lng: 2.1734 },\n },\n};\n\nexport function getCityCoordinates(city: string, countryCode: string): CityCoordinates | null {\n const country = CITY_COORDINATES[countryCode.toUpperCase()];\n if (!country) return null;\n\n const cityKey = Object.keys(country).find((key) => key.toLowerCase() === city.toLowerCase());\n return cityKey ? country[cityKey] : null;\n}\n","/**\n * Geolocation utilities\n *\n * Framework-agnostic helpers for proximity-based fulfillment.\n */\n\nimport { getCityCoordinates } from './city-coordinates';\n\nexport interface Coordinates {\n lat: number;\n lng: number;\n}\n\n/**\n * Calculate distance between two coordinates using the Haversine formula.\n * @returns Distance in kilometers\n */\nexport function calculateDistance(from: Coordinates, to: Coordinates): number {\n const R = 6371;\n const dLat = toRad(to.lat - from.lat);\n const dLng = toRad(to.lng - from.lng);\n\n const a =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.cos(toRad(from.lat)) *\n Math.cos(toRad(to.lat)) *\n Math.sin(dLng / 2) *\n Math.sin(dLng / 2);\n\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n return R * c;\n}\n\nfunction toRad(degrees: number): number {\n return degrees * (Math.PI / 180);\n}\n\n/**\n * Geocode an address to coordinates.\n *\n * This is intentionally a best-effort approximation (city + country lookup).\n * For production-grade accuracy, integrate a real geocoding provider.\n */\nexport async function geocodeAddress(address: {\n city?: string;\n countryCode?: string;\n postalCode?: string;\n}): Promise<Coordinates | null> {\n if (!address.city || !address.countryCode) return null;\n\n return getCityCoordinates(address.city, address.countryCode);\n}\n","/**\n * Fulfillment planner\n *\n * Plans an optimal fulfillment strategy for cart items given:\n * - available stock locations\n * - inventory levels per variant\n * - an optional shipping address (for proximity sorting)\n */\n\nimport type { CartItem, InventoryLevel, StockLocation, FulfillmentOption } from '@thorprovider/types';\nimport { calculateDistance, geocodeAddress, type Coordinates } from '../../utils/geolocation';\n\nexport interface FulfillmentGroup {\n locationId: string;\n locationName: string;\n items: Array<{\n variantId: string;\n quantity: number;\n productName: string;\n }>;\n shippingOptions: FulfillmentOption[];\n}\n\nexport interface FulfillmentPlan {\n canFulfill: boolean;\n groups: FulfillmentGroup[];\n shippingAddress?: Coordinates;\n}\n\nexport interface PlanFulfillmentShippingAddress {\n city?: string;\n countryCode?: string;\n postalCode?: string;\n}\n\ninterface InventoryMap {\n [variantId: string]: InventoryLevel[];\n}\n\nexport async function planFulfillment(\n cartItems: CartItem[],\n stockLocations: StockLocation[],\n inventoryLevels: InventoryMap,\n shippingAddress?: PlanFulfillmentShippingAddress,\n): Promise<FulfillmentPlan> {\n if (cartItems.length === 0) {\n return { canFulfill: true, groups: [] };\n }\n\n let addressCoords: Coordinates | null = null;\n if (shippingAddress) {\n addressCoords = await geocodeAddress(shippingAddress);\n }\n\n const itemLocationMap = new Map<string, string[]>();\n\n for (const item of cartItems) {\n const variantId = item.merchandise.id;\n const levels = inventoryLevels[variantId] ?? [];\n\n const availableLocations = levels\n .filter((level) => level.availableQuantity >= item.quantity)\n .map((level) => level.locationId);\n\n itemLocationMap.set(variantId, availableLocations);\n }\n\n const singleLocationPlan = findSingleLocationFulfillment(\n cartItems,\n stockLocations,\n itemLocationMap,\n addressCoords,\n );\n\n if (singleLocationPlan) {\n return {\n canFulfill: true,\n groups: [singleLocationPlan],\n shippingAddress: addressCoords ?? undefined,\n };\n }\n\n const splitPlan = findSplitFulfillment(cartItems, stockLocations, inventoryLevels, addressCoords);\n\n return {\n canFulfill: splitPlan.groups.length > 0,\n groups: splitPlan.groups,\n shippingAddress: addressCoords ?? undefined,\n };\n}\n\nfunction findSingleLocationFulfillment(\n items: CartItem[],\n locations: StockLocation[],\n itemLocationMap: Map<string, string[]>,\n shippingCoords: Coordinates | null,\n): FulfillmentGroup | null {\n const firstVariantId = items[0]?.merchandise?.id;\n if (!firstVariantId) return null;\n\n const firstItemLocations = itemLocationMap.get(firstVariantId);\n if (!firstItemLocations || firstItemLocations.length === 0) {\n return null;\n }\n\n const locationCandidates = new Set<string>(firstItemLocations);\n\n for (let i = 1; i < items.length; i++) {\n const variantId = items[i]?.merchandise?.id;\n if (!variantId) return null;\n\n const itemLocations = itemLocationMap.get(variantId) ?? [];\n const itemLocationsSet = new Set(itemLocations);\n\n for (const loc of locationCandidates) {\n if (!itemLocationsSet.has(loc)) {\n locationCandidates.delete(loc);\n }\n }\n\n if (locationCandidates.size === 0) return null;\n }\n\n let selectedLocationId = Array.from(locationCandidates)[0];\n\n if (shippingCoords) {\n let minDistance = Infinity;\n\n for (const locId of locationCandidates) {\n const location = locations.find((l) => l.id === locId);\n const lat = location?.metadata?.lat;\n const lng = location?.metadata?.lng;\n if (typeof lat !== 'number' || typeof lng !== 'number') continue;\n\n const distance = calculateDistance(shippingCoords, { lat, lng });\n if (distance < minDistance) {\n minDistance = distance;\n selectedLocationId = locId;\n }\n }\n }\n\n const selectedLocation = locations.find((l) => l.id === selectedLocationId);\n if (!selectedLocation) return null;\n\n return {\n locationId: selectedLocationId,\n locationName: selectedLocation.name,\n items: items.map((item) => ({\n variantId: item.merchandise.id,\n quantity: item.quantity,\n productName: item.merchandise.product.title,\n })),\n shippingOptions: [],\n };\n}\n\nfunction findSplitFulfillment(\n items: CartItem[],\n locations: StockLocation[],\n inventoryLevels: InventoryMap,\n shippingCoords: Coordinates | null,\n): { groups: FulfillmentGroup[] } {\n const groups: FulfillmentGroup[] = [];\n const assignedVariantIds = new Set<string>();\n\n const sortedLocations = sortLocationsByProximity(locations, shippingCoords);\n\n for (const location of sortedLocations) {\n const groupItems: FulfillmentGroup['items'] = [];\n\n for (const item of items) {\n const variantId = item.merchandise.id;\n if (assignedVariantIds.has(variantId)) continue;\n\n const levels = inventoryLevels[variantId] ?? [];\n const levelAtLocation = levels.find((l) => l.locationId === location.id);\n\n if (levelAtLocation && levelAtLocation.availableQuantity >= item.quantity) {\n groupItems.push({\n variantId,\n quantity: item.quantity,\n productName: item.merchandise.product.title,\n });\n assignedVariantIds.add(variantId);\n }\n }\n\n if (groupItems.length > 0) {\n groups.push({\n locationId: location.id,\n locationName: location.name,\n items: groupItems,\n shippingOptions: [],\n });\n }\n\n if (assignedVariantIds.size === items.length) {\n break;\n }\n }\n\n return { groups };\n}\n\nfunction sortLocationsByProximity(\n locations: StockLocation[],\n shippingCoords: Coordinates | null,\n): StockLocation[] {\n if (!shippingCoords) return [...locations];\n\n return [...locations].sort((a, b) => {\n const distA =\n typeof a.metadata?.lat === 'number' && typeof a.metadata?.lng === 'number'\n ? calculateDistance(shippingCoords, { lat: a.metadata.lat, lng: a.metadata.lng })\n : Infinity;\n\n const distB =\n typeof b.metadata?.lat === 'number' && typeof b.metadata?.lng === 'number'\n ? calculateDistance(shippingCoords, { lat: b.metadata.lat, lng: b.metadata.lng })\n : Infinity;\n\n return distA - distB;\n });\n}\n","/**\n * @thorprovider/adapters v2.0\n * Medusa Provider - Transform functions\n * \n * These functions convert Medusa-specific types to our unified types\n */\n\n// Note: We use 'any' for Medusa types because the SDK returns different types\n// than what's in @medusajs/types (StoreProduct vs ProductDTO)\n\nimport type {\n Product,\n ProductVariant,\n ProductOption,\n Cart,\n CartItem,\n Collection,\n ProductCategory,\n Money,\n Image,\n StockLocation,\n InventoryLevel,\n FulfillmentOption,\n Order,\n OrderItem,\n OrderStatus,\n PaymentStatus,\n FulfillmentStatus,\n Address,\n Customer,\n StorefrontConfig,\n} from '@thorprovider/types';\n\n/**\n * Transform Medusa Money to unified Money\n *\n * Medusa v2 stores and returns monetary amounts in MAJOR units (dollars, euros, etc.).\n * Reference: https://docs.medusajs.com/resources/commerce-modules/pricing/concepts\n * \"The Price data model has an `amount` property...It's stored as an integer in major units.\n * For example, $20.00 is stored as 20, and $20.5 is stored as 20.5.\"\n *\n * Money.amount in @thorprovider/types is a decimal string in major units (e.g., \"45.00\").\n * No division by 100 is needed — the value comes through as-is.\n */\nfunction transformMoney(amount: number | null | undefined, currencyCode: string = 'USD'): Money {\n return {\n amount: (amount ?? 0).toFixed(2), // Medusa v2 sends major units (dollars/euros), not cents\n currencyCode: currencyCode.toUpperCase(),\n };\n}\n\n/**\n * Transform Medusa image to unified Image\n */\nfunction transformImage(url: string, alt: string = ''): Image {\n return {\n url,\n altText: alt,\n width: 800,\n height: 800,\n };\n}\n\n// ============================================\n// Inventory & Fulfillment Transforms\n// ============================================\n\nexport function transformStockLocation(raw: any): StockLocation {\n return {\n id: raw.id,\n name: raw.name,\n address: raw.address\n ? {\n address1: raw.address.address_1,\n address2: raw.address.address_2,\n city: raw.address.city,\n countryCode: raw.address.country_code,\n postalCode: raw.address.postal_code,\n province: raw.address.province,\n }\n : undefined,\n metadata: raw.metadata,\n };\n}\n\nexport function transformInventoryLevel(raw: any, locationName: string): InventoryLevel {\n return {\n locationId: raw.location_id,\n locationName,\n availableQuantity: raw.available_quantity ?? 0,\n reservedQuantity: raw.reserved_quantity ?? 0,\n incomingQuantity: raw.incoming_quantity,\n stockedQuantity: raw.stocked_quantity ?? 0,\n };\n}\n\nexport function transformFulfillmentOption(\n shippingOption: any,\n location: StockLocation,\n currencyCode: string,\n): FulfillmentOption {\n return {\n id: shippingOption.id,\n providerId: shippingOption.provider_id,\n name: shippingOption.name,\n description: shippingOption.description,\n price: transformMoney(shippingOption.amount, currencyCode),\n estimatedDays: shippingOption.metadata?.estimated_days,\n stockLocation: location,\n };\n}\n\n/**\n * Transform Medusa ProductOption to unified ProductOption\n */\nexport function transformProductOption(option: any): ProductOption {\n return {\n id: option.id!,\n name: option.title ?? '',\n values: option.values?.map((v: any) => v.value ?? '') ?? [],\n };\n}\n\n/**\n * Transform Medusa ProductVariant to unified ProductVariant\n */\nexport function transformProductVariant(\n variant: any,\n currencyCode: string = 'USD'\n): ProductVariant {\n let priceAmount: number | null | undefined;\n let priceCurrency: string = currencyCode;\n \n // Priority 1: Use calculated_price if available (from region-based pricing)\n if (variant.calculated_price) {\n priceAmount = variant.calculated_price.calculated_amount;\n priceCurrency = variant.calculated_price.currency_code || currencyCode;\n } \n // Priority 2: Fallback to prices array\n else if (variant.prices && variant.prices.length > 0) {\n const price = variant.prices.find((p: any) => p.currency_code === currencyCode.toLowerCase());\n priceAmount = price?.amount;\n priceCurrency = price?.currency_code || currencyCode;\n }\n \n // Determine if variant is available for sale\n // Following Medusa docs: https://docs.medusajs.com/resources/storefront-development/products/inventory\n // A variant is in stock if:\n // 1. manage_inventory is false (inventory not tracked) - always in stock\n // 2. inventory_quantity > 0 (has stock)\n // 3. allow_backorder is true (can order even without stock)\n const isAvailable = variant.manage_inventory === false\n ? true\n : (variant.inventory_quantity ?? 0) > 0 || variant.allow_backorder === true;\n \n return {\n id: variant.id!,\n title: variant.title ?? 'Default',\n sku: variant.sku ?? undefined,\n availableForSale: isAvailable,\n selectedOptions: variant.options?.map((opt: any) => ({\n name: (opt as any).option?.title ?? '',\n value: opt.value ?? '',\n })) ?? [],\n price: transformMoney(priceAmount, priceCurrency),\n compareAtPrice: undefined, // Medusa doesn't have compare-at pricing\n quantityAvailable: variant.manage_inventory ? variant.inventory_quantity : undefined,\n image: variant.thumbnail\n ? transformImage(variant.thumbnail, variant.title ?? '')\n : undefined,\n };\n}\n\n/**\n * Transform Medusa Product to unified Product\n */\nexport function transformProduct(\n product: any,\n currencyCode: string = 'USD'\n): Product {\n const variants = product.variants?.map((v: any) => transformProductVariant(v, currencyCode)) ?? [];\n \n // Calculate price range\n const prices = variants.map((v: any) => parseFloat(v.price.amount));\n const minPrice = Math.min(...prices);\n const maxPrice = Math.max(...prices);\n \n return {\n id: product.id!,\n handle: product.handle ?? '',\n title: product.title ?? '',\n description: product.description ?? '',\n descriptionHtml: product.description ?? '',\n // Medusa v2 /store/products API doesn't return 'status' field (it's null)\n // Products returned by Store API are already published, so we check if any variant is available\n availableForSale: variants.length > 0 && variants.some((v: ProductVariant) => v.availableForSale),\n \n options: product.options?.map(transformProductOption) ?? [],\n variants,\n \n featuredImage: product.thumbnail\n ? transformImage(product.thumbnail, product.title ?? '')\n : undefined,\n \n images: product.images?.map((img: any) => transformImage(img.url ?? '', product.title ?? '')) ?? [],\n \n priceRange: {\n // Build Money directly from already-resolved major-unit prices.\n // Do NOT pass through transformMoney (which would call toFixed on already-correct values)\n // and do NOT multiply by 100 (that was a compensatory hack for the old /100 bug).\n minVariantPrice: { amount: (Number.isFinite(minPrice) ? minPrice : 0).toFixed(2), currencyCode: currencyCode.toUpperCase() },\n maxVariantPrice: { amount: (Number.isFinite(maxPrice) ? maxPrice : 0).toFixed(2), currencyCode: currencyCode.toUpperCase() },\n },\n \n collections: product.collection ? [{\n id: product.collection.id,\n title: product.collection.title ?? '',\n handle: product.collection.handle ?? '',\n }] : undefined,\n \n productType: product.type?.value ?? undefined,\n vendor: undefined, // Medusa doesn't have vendor field\n tags: product.tags?.map((t: any) => t.value ?? '') ?? [],\n \n seo: {\n title: product.title ?? '',\n description: product.description ?? '',\n },\n \n createdAt: typeof product.created_at === 'string' \n ? product.created_at \n : product.created_at?.toISOString() ?? new Date().toISOString(),\n updatedAt: typeof product.updated_at === 'string' \n ? product.updated_at \n : product.updated_at?.toISOString() ?? new Date().toISOString(),\n \n metadata: product.metadata ?? undefined,\n };\n}\n\n/**\n * Transform Medusa LineItem to unified CartItem\n */\nfunction resolveMedusaCartItemCurrencyCode(item: any, cartCurrencyCode?: string): string {\n return (\n item?.cart?.currency_code ??\n cartCurrencyCode ??\n 'usd'\n );\n}\n\n/**\n * Resolve the total amount for a Medusa cart item.\n * All amounts from Medusa v2 are in major units (dollars, euros).\n */\nfunction resolveMedusaCartItemTotal(item: any): number {\n const quantity = item?.quantity ?? 1;\n const safeQuantity = typeof quantity === 'number' && quantity > 0 ? quantity : 1;\n\n const totalCandidates = [\n item?.total,\n item?.item_total,\n item?.original_total,\n item?.subtotal,\n item?.item_subtotal,\n item?.original_subtotal,\n ];\n\n for (const candidate of totalCandidates) {\n if (typeof candidate === 'number' && Number.isFinite(candidate) && candidate > 0) {\n return candidate;\n }\n }\n\n const unitCandidates = [\n item?.unit_price,\n item?.original_unit_price,\n ];\n\n for (const candidate of unitCandidates) {\n if (typeof candidate === 'number' && Number.isFinite(candidate) && candidate > 0) {\n return candidate * safeQuantity;\n }\n }\n\n return 0;\n}\n\nexport function transformCartItem(item: any, cartCurrencyCode?: string): CartItem {\n const variant = item.variant;\n const product = variant?.product;\n const currencyCode = resolveMedusaCartItemCurrencyCode(item, cartCurrencyCode);\n const totalCents = resolveMedusaCartItemTotal(item);\n \n return {\n id: item.id,\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: transformMoney(totalCents, currencyCode),\n },\n merchandise: {\n id: variant?.id ?? '',\n title: variant?.title ?? '',\n selectedOptions: variant?.options?.map((opt: any) => ({\n name: (opt as any).option?.title ?? '',\n value: opt.value ?? '',\n })) ?? [],\n product: {\n id: product?.id ?? '',\n handle: product?.handle ?? '',\n title: product?.title ?? '',\n featuredImage: product?.thumbnail\n ? transformImage(product.thumbnail, product.title ?? '')\n : transformImage('', ''),\n },\n },\n };\n}\n\n/**\n * Transform Medusa Cart to unified Cart\n */\nexport function transformCart(cart: any): Cart {\n const currencyCode = cart.currency_code ?? 'usd';\n \n return {\n id: cart.id,\n checkoutUrl: `/checkout/${cart.id}`, // Medusa doesn't have a direct checkout URL\n cost: {\n subtotalAmount: transformMoney(cart.subtotal, currencyCode),\n totalAmount: transformMoney(cart.total, currencyCode),\n totalTaxAmount: transformMoney(cart.tax_total, currencyCode),\n },\n lines: cart.items?.map((item: any) => transformCartItem(item, currencyCode)) ?? [],\n totalQuantity: cart.items?.reduce((sum: any, item: any) => sum + (item.quantity ?? 0), 0) ?? 0,\n completedAt: cart.completed_at\n ? (typeof cart.completed_at === 'string'\n ? cart.completed_at\n : cart.completed_at?.toISOString())\n : undefined,\n };\n}\n\n/**\n * Transform Medusa Collection to unified Collection\n */\nexport function transformCollection(collection: any): Collection {\n return {\n id: collection.id!,\n handle: collection.handle!,\n title: collection.title ?? '',\n description: collection.metadata?.description as string ?? '',\n seo: {\n title: collection.title ?? '',\n description: collection.metadata?.description as string ?? '',\n },\n path: `/collections/${collection.handle}`,\n updatedAt: typeof collection.updated_at === 'string'\n ? collection.updated_at\n : collection.updated_at?.toISOString() ?? new Date().toISOString(),\n };\n}\n\n/**\n * Transform Medusa ProductCategory to unified ProductCategory\n */\nexport function transformCategory(category: any): ProductCategory {\n return {\n id: category.id,\n name: category.name ?? '',\n handle: category.handle ?? '',\n description: category.description ?? undefined,\n parentCategoryId: category.parent_category_id ?? undefined,\n productCount: category.product_count ?? undefined,\n image: category.metadata?.image as string ?? undefined,\n metadata: category.metadata ?? undefined,\n };\n}\n\n/**\n * Transform Medusa order status to unified OrderStatus\n */\nfunction transformOrderStatus(status: string): OrderStatus {\n // Medusa order statuses: pending, completed, archived, canceled, requires_action, draft\n switch (status) {\n case 'pending':\n case 'requires_action':\n case 'draft':\n return 'pending';\n case 'completed':\n return 'completed';\n case 'canceled':\n return 'cancelled';\n case 'archived':\n // Archived could be completed or refunded, default to completed\n return 'completed';\n default:\n return 'processing';\n }\n}\n\n/**\n * Transform Medusa payment status to unified PaymentStatus\n */\nfunction transformPaymentStatus(status: string | undefined): PaymentStatus {\n // Medusa payment statuses: not_paid, awaiting, captured, partially_refunded, refunded, canceled, requires_action\n if (!status || status === 'not_paid' || status === 'requires_action') {\n return 'pending';\n }\n \n if (status === 'awaiting') {\n return 'authorized';\n }\n \n if (status === 'captured') {\n return 'paid';\n }\n \n if (status === 'partially_refunded') {\n return 'partially_refunded';\n }\n \n if (status === 'refunded') {\n return 'refunded';\n }\n \n return 'pending';\n}\n\n/**\n * Transform Medusa fulfillment status to unified FulfillmentStatus\n */\nfunction transformFulfillmentStatus(status: string | undefined): FulfillmentStatus {\n // Medusa fulfillment statuses: not_fulfilled, partially_fulfilled, fulfilled, \n // partially_shipped, shipped, partially_returned, returned, canceled, requires_action\n if (!status || status === 'not_fulfilled' || status === 'canceled') {\n return 'unfulfilled';\n }\n \n if (status === 'partially_fulfilled' || status === 'partially_shipped') {\n return 'partially_fulfilled';\n }\n \n if (status === 'fulfilled' || status === 'shipped') {\n return 'fulfilled';\n }\n \n if (status === 'returned' || status === 'partially_returned') {\n return 'returned';\n }\n \n return 'unfulfilled';\n}\n\n/**\n * Transform Medusa LineItem to unified OrderItem\n */\nexport function transformOrderItem(item: any, currencyCode: string): OrderItem {\n // Defensive checks for null/undefined item or variant\n if (!item) {\n throw new Error('Invalid order item: item is null or undefined');\n }\n \n const variant = item.variant ?? null;\n const product = variant?.product;\n \n return {\n id: item.id,\n title: item.product_title ?? item.title ?? '',\n variantTitle: item.variant_title ?? variant?.title ?? undefined,\n quantity: item.quantity ?? 1,\n price: transformMoney(item.unit_price, currencyCode),\n total: transformMoney(item.total, currencyCode),\n sku: variant?.sku ?? undefined,\n image: product?.thumbnail || item.thumbnail\n ? transformImage(product?.thumbnail || item.thumbnail, item.product_title ?? '')\n : undefined,\n productId: item.product_id ?? product?.id ?? undefined,\n variantId: item.variant_id ?? variant?.id ?? undefined,\n };\n}\n\n/**\n * Transform Medusa Address (snake_case) to unified Address (camelCase)\n */\nexport function transformAddress(address: any): Address {\n return {\n id: address.id ?? undefined,\n firstName: address.first_name ?? '',\n lastName: address.last_name ?? '',\n company: address.company ?? undefined,\n address1: address.address_1 ?? '',\n address2: address.address_2 ?? undefined,\n city: address.city ?? '',\n province: address.province ?? '',\n postalCode: address.postal_code ?? '',\n countryCode: address.country_code ?? '',\n phone: address.phone ?? undefined,\n isDefault: address.is_default ?? address.is_default_shipping ?? undefined,\n };\n}\n\n/**\n * Transform Medusa Customer (snake_case) to unified Customer (camelCase)\n */\nexport function transformCustomer(customer: any, email?: string): Customer {\n return {\n id: customer.id,\n email: customer.email ?? email ?? '',\n firstName: customer.first_name ?? '',\n lastName: customer.last_name ?? '',\n phone: customer.phone ?? undefined,\n hasAccount: customer.has_account ?? false,\n createdAt: typeof customer.created_at === 'string'\n ? customer.created_at\n : customer.created_at?.toISOString() ?? undefined,\n updatedAt: typeof customer.updated_at === 'string'\n ? customer.updated_at\n : customer.updated_at?.toISOString() ?? undefined,\n metadata: customer.metadata ?? undefined,\n };\n}\n\n/**\n * Transform Medusa Order to unified Order\n */\nexport function transformOrder(order: any): Order {\n const currencyCode = order.currency_code ?? 'usd';\n \n return {\n id: order.id,\n orderNumber: order.display_id?.toString() ?? order.id,\n email: order.email ?? '',\n \n // Status (3 separate statuses)\n status: transformOrderStatus(order.status),\n paymentStatus: transformPaymentStatus(order.payment_status),\n fulfillmentStatus: transformFulfillmentStatus(order.fulfillment_status),\n \n // Customer\n customerId: order.customer_id ?? undefined,\n customer: order.customer\n ? transformCustomer(order.customer, order.email)\n : undefined,\n \n // Items\n items: (order.items ?? [])\n .filter((item: any) => item != null) // Filter out null/undefined items\n .map((item: any) => transformOrderItem(item, currencyCode)) ?? [],\n \n // Pricing\n subtotal: transformMoney(order.subtotal, currencyCode),\n total: transformMoney(order.total, currencyCode),\n tax: transformMoney(order.tax_total, currencyCode),\n shipping: transformMoney(order.shipping_total, currencyCode),\n discount: transformMoney(order.discount_total, currencyCode),\n \n // Addresses (transformed to camelCase)\n shippingAddress: order.shipping_address\n ? transformAddress(order.shipping_address)\n : undefined,\n billingAddress: order.billing_address\n ? transformAddress(order.billing_address)\n : undefined,\n \n // Dates\n createdAt: typeof order.created_at === 'string'\n ? order.created_at\n : order.created_at?.toISOString() ?? new Date().toISOString(),\n updatedAt: typeof order.updated_at === 'string'\n ? order.updated_at\n : order.updated_at?.toISOString() ?? new Date().toISOString(),\n completedAt: order.completed_at\n ? (typeof order.completed_at === 'string'\n ? order.completed_at\n : order.completed_at?.toISOString())\n : undefined,\n cancelledAt: order.canceled_at\n ? (typeof order.canceled_at === 'string'\n ? order.canceled_at\n : order.canceled_at?.toISOString())\n : undefined,\n \n // Platform-specific metadata\n metadata: order.metadata ?? undefined,\n };\n}\n\n// ============================================\n// Storefront Configuration Transforms\n// ============================================\n\n/**\n * Transform backend `storefront_config` (snake_case) to `StorefrontConfig` (camelCase).\n *\n * Backend response shape:\n * ```json\n * {\n * \"id\": \"sfc_01J...\",\n * \"sales_channel_id\": \"sc_01J...\",\n * \"theme_accent_color\": \"indigo\",\n * \"logo_url\": \"https://...\",\n * \"currency_code\": \"EUR\",\n * \"seo_defaults\": { \"title\": \"...\", \"description\": \"...\", \"ogImage\": \"...\" },\n * \"created_at\": \"...\",\n * \"updated_at\": \"...\"\n * }\n * ```\n */\nexport function transformStorefrontConfig(raw: any): StorefrontConfig {\n return {\n id: raw.id ?? '',\n salesChannelId: raw.sales_channel_id ?? '',\n themeAccentColor: raw.theme_accent_color ?? '',\n logoUrl: raw.logo_url ?? '',\n currencyCode: raw.currency_code ?? 'USD',\n seoDefaults: {\n title: raw.seo_defaults?.title ?? '',\n description: raw.seo_defaults?.description ?? '',\n ogImage: raw.seo_defaults?.ogImage ?? raw.seo_defaults?.og_image,\n },\n createdAt: raw.created_at ?? '',\n updatedAt: raw.updated_at ?? '',\n };\n}\n","/**\n * Admin Authentication Service\n * \n * Framework-agnostic authentication logic for admin dashboard.\n * Uses bcryptjs for password hashing and jose for JWT operations.\n * \n * @remarks\n * - L2: No Next.js imports, no env var access\n * - Edge-compatible JWT via jose library\n * - Password verification via bcryptjs\n * \n * @module admin/AdminAuthService\n */\n\nimport bcrypt from 'bcryptjs';\nimport { SignJWT, jwtVerify, type JWTPayload } from 'jose';\n\n/**\n * Admin Auth Service\n * \n * Provides password verification and JWT management for admin authentication.\n * All methods are framework-agnostic and can be used in any runtime.\n */\nexport class AdminAuthService {\n /**\n * Verify password against bcrypt hash\n * \n * @param password - Plain text password from login form\n * @param hash - Bcrypt hash stored in environment\n * @returns true if password matches hash\n */\n async verifyPassword(password: string, hash: string): Promise<boolean> {\n return bcrypt.compare(password, hash);\n }\n\n /**\n * Generate a bcrypt hash for a password\n * \n * @param password - Plain text password\n * @param rounds - Bcrypt cost factor (default: 10)\n * @returns Bcrypt hash string\n */\n async hashPassword(password: string, rounds: number = 10): Promise<string> {\n return bcrypt.hash(password, rounds);\n }\n\n /**\n * Generate JWT token (Edge-compatible via jose)\n * \n * @param payload - Token payload data\n * @param secret - JWT secret string (min 32 chars recommended)\n * @param expiresIn - Token expiration (default: '8h')\n * @returns Signed JWT token string\n */\n async generateJWT(\n payload: Record<string, unknown>,\n secret: string,\n expiresIn: string = '8h',\n ): Promise<string> {\n const secretKey = new TextEncoder().encode(secret);\n\n return new SignJWT(payload as JWTPayload)\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(expiresIn)\n .sign(secretKey);\n }\n\n /**\n * Verify JWT token (Edge-compatible via jose)\n * \n * @param token - JWT token string\n * @param secret - JWT secret string\n * @returns Decoded payload or null if invalid/expired\n */\n async verifyJWT(\n token: string,\n secret: string,\n ): Promise<Record<string, unknown> | null> {\n try {\n const secretKey = new TextEncoder().encode(secret);\n const { payload } = await jwtVerify(token, secretKey);\n return payload as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n}\n","/**\n * Admin Session Service\n * \n * Framework-agnostic session verification for admin routes.\n * Extracts and verifies JWT tokens from HTTP requests.\n * \n * @remarks\n * - L2: No Next.js imports, no env var access\n * - Uses standard Request API (works in Edge, Node.js, etc.)\n * - JWT secret injected via constructor (no env var reading)\n * \n * @module admin/AdminSessionService\n */\n\nimport { AdminAuthService } from './AdminAuthService';\n\n/**\n * Admin Session payload decoded from JWT\n */\nexport interface AdminSession {\n /** Admin user identifier */\n adminId: string;\n /** Token type (always 'admin') */\n type: 'admin';\n /** Issued at timestamp */\n iat: number;\n /** Expiration timestamp */\n exp: number;\n}\n\n/**\n * Admin Session Service\n * \n * Verifies admin sessions by extracting and validating JWT tokens\n * from HTTP request cookies or Authorization headers.\n */\nexport class AdminSessionService {\n private authService: AdminAuthService;\n\n /**\n * @param jwtSecret - JWT secret for token verification\n */\n constructor(private jwtSecret: string) {\n this.authService = new AdminAuthService();\n }\n\n /**\n * Verify admin session from HTTP request\n * \n * Checks for JWT token in:\n * 1. `admin_token` cookie\n * 2. `Authorization: Bearer <token>` header\n * \n * @param request - Standard HTTP Request object\n * @returns AdminSession if valid, null otherwise\n */\n async verifySession(request: Request): Promise<AdminSession | null> {\n const token = this.extractToken(request);\n if (!token) return null;\n\n const payload = await this.authService.verifyJWT(token, this.jwtSecret);\n if (!payload || payload.type !== 'admin') return null;\n\n return payload as unknown as AdminSession;\n }\n\n /**\n * Extract JWT token from request (cookie or Authorization header)\n */\n private extractToken(request: Request): string | null {\n // Try cookie first\n const cookieHeader = request.headers.get('cookie');\n if (cookieHeader) {\n const cookies = Object.fromEntries(\n cookieHeader.split(';').map((c) => {\n const [key, ...v] = c.trim().split('=');\n return [key, v.join('=')];\n }),\n );\n if (cookies.admin_token) return cookies.admin_token;\n }\n\n // Try Authorization header\n const authHeader = request.headers.get('authorization');\n if (authHeader?.startsWith('Bearer ')) {\n return authHeader.substring(7);\n }\n\n return null;\n }\n}\n","/**\n * Metrics Calculation Service\n * \n * Framework-agnostic business logic for calculating dashboard metrics\n * from raw order and product data.\n * \n * @remarks\n * - L2: Pure business logic, no framework dependencies\n * - Works with @thorprovider/types Order and Product interfaces\n * - Stateless static methods for easy testing\n * \n * @module admin/MetricsService\n */\n\nimport type { DashboardMetrics, ChartDataPoint } from '@thorprovider/types';\n\n/**\n * Raw order data for metrics calculation\n * \n * @remarks\n * Minimal interface to avoid coupling to specific Order type fields.\n * Accepts the common fields available across all commerce providers.\n */\nexport interface MetricsOrderInput {\n total?: number;\n status?: string;\n created_at?: string;\n createdAt?: string;\n}\n\n/**\n * Raw product data for metrics calculation\n */\nexport interface MetricsProductInput {\n id: string;\n variants?: Array<{\n quantityAvailable?: number;\n }>;\n}\n\n/**\n * Metrics Service\n * \n * Calculates dashboard analytics from raw commerce data.\n * All methods are static and pure (no side effects).\n */\nexport class MetricsService {\n /** Threshold for low stock alerts */\n static readonly LOW_STOCK_THRESHOLD = 10;\n\n /**\n * Calculate complete dashboard metrics from orders and products\n * \n * @param orders - Array of order data\n * @param products - Array of product data\n * @returns Calculated DashboardMetrics\n */\n static calculate(\n orders: MetricsOrderInput[],\n products: MetricsProductInput[],\n ): DashboardMetrics {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);\n const monthAgo = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);\n\n // Calculate sales\n const totalSales = orders.reduce((sum, o) => sum + (o.total || 0), 0);\n const todaySales = orders\n .filter((o) => new Date(o.created_at || o.createdAt || '') >= today)\n .reduce((sum, o) => sum + (o.total || 0), 0);\n const weekSales = orders\n .filter((o) => new Date(o.created_at || o.createdAt || '') >= weekAgo)\n .reduce((sum, o) => sum + (o.total || 0), 0);\n const monthSales = orders\n .filter((o) => new Date(o.created_at || o.createdAt || '') >= monthAgo)\n .reduce((sum, o) => sum + (o.total || 0), 0);\n\n // Calculate orders by status\n const ordersByStatus = {\n total: orders.length,\n pending: orders.filter((o) => o.status === 'pending').length,\n processing: orders.filter((o) => o.status === 'processing').length,\n completed: orders.filter((o) => o.status === 'completed').length,\n };\n\n // Calculate products\n const lowStockCount = products.filter((p) => {\n const totalQty = (p.variants || []).reduce(\n (sum, v) => sum + (v.quantityAvailable || 0),\n 0,\n );\n return totalQty < MetricsService.LOW_STOCK_THRESHOLD;\n }).length;\n\n const productsMetrics = {\n total: products.length,\n lowStock: lowStockCount,\n };\n\n // Generate chart data (last 7 days)\n const chartData = MetricsService.generateChartData(orders, today);\n\n return {\n sales: {\n total: totalSales,\n today: todaySales,\n week: weekSales,\n month: monthSales,\n },\n orders: ordersByStatus,\n products: productsMetrics,\n chartData,\n };\n }\n\n /**\n * Generate chart data for the last 7 days\n */\n private static generateChartData(\n orders: MetricsOrderInput[],\n today: Date,\n ): ChartDataPoint[] {\n const chartData: ChartDataPoint[] = [];\n\n for (let i = 6; i >= 0; i--) {\n const date = new Date(today.getTime() - i * 24 * 60 * 60 * 1000);\n const nextDate = new Date(date.getTime() + 24 * 60 * 60 * 1000);\n\n const daySales = orders\n .filter((o) => {\n const orderDate = new Date(o.created_at || o.createdAt || '');\n return orderDate >= date && orderDate < nextDate;\n })\n .reduce((sum, o) => sum + (o.total || 0), 0);\n\n chartData.push({\n date: date.toISOString().split('T')[0],\n sales: daySales,\n });\n }\n\n return chartData;\n }\n}\n","/**\n * Backend Metadata Adapter Factory\n *\n * Framework-agnostic factory to create backend metadata adapters for admin/dashboard.\n * Keeps vendor-specific code in L2, prevents lock-in in L5.\n *\n * @remarks\n * This factory is distinct from the main provider factory (createProvider).\n * It's used for admin operations that require metadata/catalog access.\n * Provider types are imported from @thorprovider/types (L1) to maintain sync.\n *\n * @module backend/factory\n */\n\nimport Medusa from '@medusajs/js-sdk';\nimport { MedusaMetadataAdapter } from './medusa/MedusaMetadataAdapter';\nimport type { BackendMetadataAdapter } from './BackendMetadataAdapter';\nimport type { ProviderTypeString } from '@thorprovider/types';\n\n/**\n * Configuration for creating a backend metadata adapter\n *\n * @remarks\n * Currently only 'medusa' is implemented. When adding Shopify/WooCommerce metadata adapters:\n * 1. Uncomment the provider type in packages/types/src/provider.ts\n * 2. Update this interface to accept the new provider type\n * 3. Implement ShopifyMetadataAdapter, WooCommerceMetadataAdapter\n * 4. Add cases to createBackendMetadataAdapter() switch\n */\nexport interface BackendMetadataAdapterConfig {\n /** Backend provider type (from @thorprovider/types L1) */\n provider: ProviderTypeString;\n \n /** Backend base URL */\n baseUrl: string;\n \n /** Publishable API key (for storefront access) */\n publishableKey?: string;\n \n /** Enable debug logging */\n debug?: boolean;\n\n /**\n * Secret admin API key (from COMMERCE_ADMIN_API_KEY).\n * When provided, the metadata adapter SDK instance will send\n * `x-medusa-access-token` header on all admin requests.\n * Required for getMetadata/setMetadata to work after removing email/password auth.\n */\n adminApiKey?: string;\n}\n\n/**\n * Create a backend metadata adapter (Factory Pattern)\n * \n * Keeps vendor-specific code in L2, prevents lock-in in L5.\n * L5 only provides configuration from env vars.\n * \n * @param config - Adapter configuration\n * @returns BackendMetadataAdapter instance\n * \n * @example\n * ```typescript\n * // In L5 (starters)\n * import { createBackendMetadataAdapter } from '@thorprovider/adapters';\n * \n * export const metadataAdapter = createBackendMetadataAdapter({\n * provider: process.env.NEXT_PUBLIC_COMMERCE_PROVIDER as any,\n * baseUrl: process.env.NEXT_PUBLIC_COMMERCE_API_URL!,\n * publishableKey: process.env.NEXT_PUBLIC_COMMERCE_API_KEY!,\n * });\n * ```\n * \n * @throws {Error} If provider is not supported\n */\nexport function createBackendMetadataAdapter(\n config: BackendMetadataAdapterConfig\n): BackendMetadataAdapter {\n const { provider, baseUrl, publishableKey, debug } = config;\n\n if (provider === 'medusa') {\n const { adminApiKey } = config;\n\n // Create Medusa SDK client instance\n const medusa = new Medusa({\n baseUrl,\n publishableKey,\n debug: debug ?? false,\n // When adminApiKey is provided: sends x-medusa-access-token on all requests.\n // When not provided: requests are unauthenticated — admin routes will 401.\n ...(adminApiKey && { apiKey: adminApiKey }),\n });\n\n return new MedusaMetadataAdapter(medusa);\n }\n\n throw new Error(`Unsupported provider for metadata adapter: ${provider}. Only 'medusa' is currently supported.`);\n}\n","/**\n * Medusa Metadata Adapter\n * \n * Implementation of BackendMetadataAdapter for Medusa.js v2.\n * Uses Medusa's native metadata fields on sales_channel, customer, and order resources.\n * \n * Supported resource types:\n * - `'sales_channel'` — site config, channel-level settings\n * - `'customer'` — multi-tenant scoping (`sales_channel_id` key)\n * - `'order'` — multi-tenant scoping (`sales_channel_id` key)\n * \n * All operations require admin-level JWT authentication.\n * \n * @module backend/medusa/MedusaMetadataAdapter\n */\n\nimport type Medusa from '@medusajs/js-sdk';\nimport type { BackendMetadataAdapter } from '../BackendMetadataAdapter';\n\n/**\n * Medusa Metadata Adapter\n * \n * @remarks\n * - Supports 'sales_channel' and 'store' resource types\n * - Uses Medusa admin API (requires admin token)\n * - Metadata is stored as JSON in the metadata field\n * \n * @example\n * ```typescript\n * const adapter = new MedusaMetadataAdapter(medusaClient);\n * \n * // Store site configuration\n * await adapter.setMetadata(\n * 'sales_channel',\n * 'sc_01HXXX',\n * 'site_config',\n * { version: '2026-03-25', config: {...} }\n * );\n * ```\n */\nexport class MedusaMetadataAdapter implements BackendMetadataAdapter {\n constructor(private sdk: Medusa) {}\n\n /**\n * Get metadata value from Medusa resource\n */\n async getMetadata(\n resourceType: string,\n resourceId: string,\n key: string\n ): Promise<any | null> {\n try {\n if (resourceType === 'sales_channel') {\n const { sales_channel } = await this.sdk.admin.salesChannel.retrieve(\n resourceId\n );\n return sales_channel.metadata?.[key] ?? null;\n }\n\n if (resourceType === 'customer') {\n const result = await (this.sdk as any).admin.customer.retrieve(resourceId);\n return result?.customer?.metadata?.[key] ?? null;\n }\n\n if (resourceType === 'order') {\n const result = await (this.sdk as any).admin.order.retrieve(resourceId);\n return result?.order?.metadata?.[key] ?? null;\n }\n\n // Note: Store API in Medusa v2 requires store ID\n // Store support can be added when we have a reliable way to get the store ID\n\n throw new Error(\n `Unsupported resource type: ${resourceType}. ` +\n `Supported: 'sales_channel', 'customer', 'order'.`\n );\n } catch (error: any) {\n // If resource not found or metadata key doesn't exist, return null\n if (error.response?.status === 404 || error.status === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Set metadata value on Medusa resource\n */\n async setMetadata(\n resourceType: string,\n resourceId: string,\n key: string,\n value: any\n ): Promise<void> {\n if (resourceType === 'sales_channel') {\n await this.sdk.admin.salesChannel.update(resourceId, {\n metadata: { [key]: value },\n });\n return;\n }\n\n if (resourceType === 'customer') {\n await (this.sdk as any).admin.customer.update(resourceId, {\n metadata: { [key]: value },\n });\n return;\n }\n\n if (resourceType === 'order') {\n await (this.sdk as any).admin.order.update(resourceId, {\n metadata: { [key]: value },\n });\n return;\n }\n\n // Note: Store API in Medusa v2 requires store ID\n // Store support can be added when we have a reliable way to get the store ID\n\n throw new Error(\n `Unsupported resource type: ${resourceType}. ` +\n `Supported: 'sales_channel', 'customer', 'order'.`\n );\n }\n\n /**\n * Delete metadata key from Medusa resource\n * \n * @remarks\n * Medusa deletes metadata keys by setting them to undefined or null\n */\n async deleteMetadata(\n resourceType: string,\n resourceId: string,\n key: string\n ): Promise<void> {\n // Set to null to delete the key\n await this.setMetadata(resourceType, resourceId, key, null);\n }\n}\n","/**\n * Channel Scope — Backend-Agnostic Multi-Tenant Helpers\n *\n * Provides utilities for tagging, reading and filtering entity metadata by\n * sales-channel (or any future tenant key). Works with any backend that\n * exposes a writable `metadata: Record<string, unknown>` field on its\n * entities (Medusa, Shopify metafields, WooCommerce meta, etc.).\n *\n * ## Design decisions\n *\n * | Decision | Rationale |\n * |----------|-----------|\n * | Flat key (`sales_channel_id`) | Simpler queries, no prefix parsing required |\n * | Metadata, not custom fields | Zero DB migrations; works across backends |\n * | Pure functions | No side effects → easily testable; usable in any layer |\n * | `assigned_at` timestamp | Audit trail for dropshipper / admin assignment |\n *\n * @module metadata/channel-scope\n */\n\n// ────────────────────────────────────────────────────────────────────\n// Constants\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Well-known metadata key used to store the owning sales-channel on any\n * entity that Medusa (or the backend) does not natively scope.\n *\n * Convention: every entity whose metadata contains this key is\n * considered \"owned\" by the referenced channel. Entities without it\n * are global / unscoped.\n */\nexport const CHANNEL_SCOPE_KEY = 'sales_channel_id' as const;\n\n/**\n * Optional audit key — ISO-8601 timestamp of when the channel was assigned.\n */\nexport const CHANNEL_ASSIGNED_AT_KEY = 'channel_assigned_at' as const;\n\n/**\n * Optional audit key — who assigned the entity to the channel.\n * Value is a free-form string (admin email, user id, \"system\", etc.).\n */\nexport const CHANNEL_ASSIGNED_BY_KEY = 'channel_assigned_by' as const;\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Minimal shape any entity must satisfy in order to participate in\n * channel-scope filtering. Compatible with @thorprovider/types Customer,\n * Order, ProductCategory, etc.\n */\nexport interface ChannelScopeable {\n id: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Payload produced by `buildChannelScopeMetadata()`.\n * Can be spread directly into an `updateCustomer` / `updateOrder` call.\n */\nexport interface ChannelScopeMetadata {\n [CHANNEL_SCOPE_KEY]: string;\n [CHANNEL_ASSIGNED_AT_KEY]: string;\n [CHANNEL_ASSIGNED_BY_KEY]?: string;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Builders\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Build channel-scope metadata payload.\n *\n * The returned object should be **merged** into the entity's existing\n * `metadata` field when calling `updateCustomer`, `updateOrder`, etc.\n *\n * @param channelId - Sales-channel ID (e.g. `\"sc_01HXXX\"`)\n * @param assignedBy - Optional identifier of who performed the assignment\n * @returns Metadata fragment ready to spread into an update payload\n *\n * @example\n * ```typescript\n * const scope = buildChannelScopeMetadata('sc_01HXXX', 'admin@store.com');\n * await commerce.updateCustomer(customerId, {\n * metadata: { ...existingMeta, ...scope },\n * });\n * ```\n */\nexport function buildChannelScopeMetadata(\n channelId: string,\n assignedBy?: string,\n): ChannelScopeMetadata {\n const payload: ChannelScopeMetadata = {\n [CHANNEL_SCOPE_KEY]: channelId,\n [CHANNEL_ASSIGNED_AT_KEY]: new Date().toISOString(),\n };\n\n if (assignedBy) {\n payload[CHANNEL_ASSIGNED_BY_KEY] = assignedBy;\n }\n\n return payload;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Readers\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Read the channel-scope value from an entity's metadata.\n *\n * @returns The channel ID string, or `null` if the entity has no scope set.\n */\nexport function getChannelScope(entity: ChannelScopeable): string | null {\n const value = entity.metadata?.[CHANNEL_SCOPE_KEY];\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\n/**\n * Check if an entity is scoped to a specific channel.\n *\n * @param entity - Any entity with optional `metadata`\n * @param channelId - Channel ID to match against\n * @returns `true` if entity's metadata contains a matching scope key\n */\nexport function isScopedToChannel(\n entity: ChannelScopeable,\n channelId: string,\n): boolean {\n return getChannelScope(entity) === channelId;\n}\n\n/**\n * Check if an entity has **no** channel scope (i.e. it is \"global\").\n */\nexport function isGlobalEntity(entity: ChannelScopeable): boolean {\n return getChannelScope(entity) === null;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Filters\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Filter an array of entities to only those belonging to a channel.\n *\n * If `channelId` is `undefined` or empty, returns the full array unfiltered.\n * This preserves backward compatibility for admin views that intentionally\n * list all entities regardless of tenant.\n *\n * @param entities - Array of channel-scopeable entities\n * @param channelId - Optional channel ID to filter by\n * @returns Filtered (or unfiltered) array\n *\n * @example\n * ```typescript\n * const allCustomers = await commerce.getCustomers();\n * const myCustomers = filterByChannel(allCustomers, salesChannelId);\n * ```\n */\nexport function filterByChannel<T extends ChannelScopeable>(\n entities: T[],\n channelId?: string,\n): T[] {\n if (!channelId) return entities;\n return entities.filter((e) => isScopedToChannel(e, channelId));\n}\n\n/**\n * Filter an array of entities to only those that are global (unscoped).\n *\n * Useful for admin views that want to list entities not yet assigned to\n * any channel.\n */\nexport function filterGlobalOnly<T extends ChannelScopeable>(\n entities: T[],\n): T[] {\n return entities.filter(isGlobalEntity);\n}\n\n/**\n * Partition entities into `{ scoped, global }` groups.\n *\n * @param entities - Array of channel-scopeable entities\n * @param channelId - Channel ID to partition against\n * @returns Object with `scoped` (matching channel) and `global` (no scope) arrays\n *\n * @example\n * ```typescript\n * const { scoped, global } = partitionByChannel(customers, 'sc_123');\n * // scoped → customers assigned to sc_123\n * // global → customers not assigned to any channel\n * ```\n */\nexport function partitionByChannel<T extends ChannelScopeable>(\n entities: T[],\n channelId: string,\n): { scoped: T[]; global: T[] } {\n const scoped: T[] = [];\n const global: T[] = [];\n\n for (const entity of entities) {\n if (isScopedToChannel(entity, channelId)) {\n scoped.push(entity);\n } else if (isGlobalEntity(entity)) {\n global.push(entity);\n }\n // Entities scoped to a *different* channel are silently excluded.\n }\n\n return { scoped, global };\n}\n","/**\n * Channel Scope Validation — Pure TypeScript (no external deps)\n *\n * Validates channel-scope metadata before it is written to the backend.\n * Keeps all validation logic in L2 so that L5 starters don't duplicate checks.\n *\n * @module metadata/channel-scope-validation\n */\n\nimport type { ChannelScopeMetadata, ChannelScopeable } from './channel-scope';\nimport { CHANNEL_SCOPE_KEY } from './channel-scope';\n\n// ────────────────────────────────────────────────────────────────────\n// Errors\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Thrown when channel-scope validation fails.\n *\n * Consumers can catch this specific type to provide user-friendly feedback\n * without leaking internal details.\n */\nexport class ChannelScopeValidationError extends Error {\n public readonly field: string;\n public readonly value: unknown;\n\n constructor(message: string, field: string, value?: unknown) {\n super(message);\n this.name = 'ChannelScopeValidationError';\n this.field = field;\n this.value = value;\n }\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Validation functions\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Validate that a channel ID is a non-empty string.\n *\n * Does **not** enforce a specific prefix (e.g. `\"sc_\"`) because different\n * backends use different conventions:\n * - Medusa: `\"sc_01HXXX\"`\n * - Shopify: `\"gid://shopify/Channel/789\"`\n * - WooCommerce: `\"1\"` (numeric string)\n *\n * @throws {ChannelScopeValidationError}\n */\nexport function validateChannelId(channelId: unknown): asserts channelId is string {\n if (typeof channelId !== 'string' || channelId.trim().length === 0) {\n throw new ChannelScopeValidationError(\n 'Channel ID must be a non-empty string',\n 'channelId',\n channelId,\n );\n }\n\n // Sanity upper-bound for ID length (guards against payload abuse)\n if (channelId.length > 256) {\n throw new ChannelScopeValidationError(\n 'Channel ID exceeds maximum length (256)',\n 'channelId',\n channelId,\n );\n }\n}\n\n/**\n * Validate that an entity ID is a non-empty string.\n *\n * @throws {ChannelScopeValidationError}\n */\nexport function validateEntityId(entityId: unknown, label = 'entityId'): asserts entityId is string {\n if (typeof entityId !== 'string' || entityId.trim().length === 0) {\n throw new ChannelScopeValidationError(\n `${label} must be a non-empty string`,\n label,\n entityId,\n );\n }\n}\n\n/**\n * Validate that the `assignedBy` value (if provided) is a reasonable string.\n *\n * @throws {ChannelScopeValidationError}\n */\nexport function validateAssignedBy(assignedBy: unknown): asserts assignedBy is string | undefined {\n if (assignedBy === undefined || assignedBy === null) return;\n if (typeof assignedBy !== 'string') {\n throw new ChannelScopeValidationError(\n 'assignedBy must be a string',\n 'assignedBy',\n assignedBy,\n );\n }\n if (assignedBy.length > 512) {\n throw new ChannelScopeValidationError(\n 'assignedBy exceeds maximum length (512)',\n 'assignedBy',\n assignedBy,\n );\n }\n}\n\n/**\n * Full validation for a channel-scope assignment operation.\n *\n * Call before writing channel scope metadata to any entity.\n *\n * @throws {ChannelScopeValidationError} with descriptive field + value\n *\n * @example\n * ```typescript\n * validateChannelScopeAssignment('cus_123', 'sc_01HXXX', 'admin@store.com');\n * // If no error, safe to proceed\n * ```\n */\nexport function validateChannelScopeAssignment(\n entityId: string,\n channelId: string,\n assignedBy?: string,\n): void {\n validateEntityId(entityId, 'entityId');\n validateChannelId(channelId);\n validateAssignedBy(assignedBy);\n}\n\n/**\n * Validate that an entity is currently scoped to the expected channel.\n *\n * Useful as a guard before performing operations that should only\n * affect entities within the caller's channel (e.g. a dropshipper editing\n * a customer that must belong to their channel).\n *\n * @throws {ChannelScopeValidationError} if entity does not belong to expectedChannelId\n */\nexport function assertEntityBelongsToChannel(\n entity: ChannelScopeable,\n expectedChannelId: string,\n): void {\n const actual = entity.metadata?.[CHANNEL_SCOPE_KEY];\n if (actual !== expectedChannelId) {\n throw new ChannelScopeValidationError(\n `Entity \"${entity.id}\" does not belong to channel \"${expectedChannelId}\" (actual: \"${actual ?? 'none'}\")`,\n CHANNEL_SCOPE_KEY,\n actual,\n );\n }\n}\n","/**\n * @thorprovider/adapters v2.0\n * Medusa Provider - Main implementation\n */\n\nimport Medusa from '@medusajs/js-sdk';\nimport type {\n Product,\n GetProductsOptions,\n AdvancedSearchProductsOptions,\n SearchResultMeta,\n FilterConfig,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n ProductCategory,\n GetCategoriesOptions,\n GetCollectionsOptions,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n AuthConfig,\n AuthProvider,\n PaymentMethod,\n PaymentMethodsOptions,\n Order,\n StorefrontContext,\n Customer,\n GetCustomersOptions,\n GetOrdersOptions,\n AdminProduct,\n Region,\n Address,\n BackendCapabilities,\n StorefrontConfig,\n DesignerConfig,\n DesignerHistoryEntry,\n} from '@thorprovider/types';\nimport { StorefrontConfigError } from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { MEDUSA_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { fetchWithRetry, type RetryConfig } from '../../core/fetch-utils';\nimport { ProviderAPIError, ResourceNotFoundError, extractErrorMessage } from '../../core/errors';\nimport { validatePaymentId } from '../../utils/payment-utils';\nimport { transformProduct, transformCart, transformCollection, transformCategory, transformOrder, transformCustomer, transformStockLocation, transformInventoryLevel, transformAddress, transformStorefrontConfig } from './transforms';\nimport { MedusaAuthProvider } from './auth';\nimport { getPaymentMethods } from './payment';\nimport { MedusaAdminClient } from './admin';\nimport {\n buildChannelScopeMetadata,\n filterByChannel,\n validateChannelScopeAssignment,\n} from '../../metadata';\n\nconst MEDUSA_CART_RETRIEVE_FIELDS =\n '+items,+items.variant,+items.variant.product,+items.variant.product.thumbnail,+items.variant.options,+items.variant.options.option';\n\n/**\n * Medusa provider configuration\n */\nexport interface MedusaProviderConfig extends ProviderConfig {\n /**\n * Medusa backend URL\n */\n baseUrl: string;\n\n /**\n * Publishable API key (for storefront access)\n */\n publishableKey: string;\n\n /**\n * Default currency code (default: USD)\n */\n /**\n * Default currency code (default: USD)\n */\n currencyCode?: string;\n\n /**\n * Region ID (optional, will use default region if not provided)\n */\n regionId?: string;\n\n /**\n * Authentication configuration (optional)\n * If not provided, auth methods will not be available\n */\n auth?: AuthConfig;\n\n /**\n * Retry configuration for fetch requests (optional)\n * Configure automatic retries, timeouts, and backoff strategy\n *\n * @example\n * ```typescript\n * {\n * maxRetries: 3, // Retry up to 3 times\n * timeoutMs: 10000, // 10 second timeout per request\n * initialDelayMs: 300, // Start with 300ms delay\n * }\n * ```\n */\n retry?: RetryConfig;\n\n /**\n * Admin API configuration (optional).\n * Required for inventory operations (stock locations, inventory levels).\n * When not provided, admin-only methods will throw with a descriptive error.\n */\n adminConfig?: {\n /**\n * Secret API key created in Medusa Admin → Settings → API Keys → Secret.\n * Sent as `x-medusa-access-token` on every request of the dedicated admin SDK instance.\n * Never use a Publishable key here.\n */\n apiKey: string;\n };\n}\n\n/**\n * Medusa commerce provider\n *\n * Implements CommerceProvider interface for Medusa.js v2\n */\nexport class MedusaProvider implements CommerceProvider {\n readonly name = 'medusa';\n readonly version = '2.0.0';\n\n /**\n * Medusa backend capabilities.\n * Starts with static defaults, replaced by dynamic values from\n * `GET /store/thor/capabilities` once the fetch completes.\n */\n private _dynamicCapabilities: BackendCapabilities | null = null;\n\n /** Promise that resolves when capabilities fetch completes (success or failure) */\n private _capabilitiesPromise: Promise<void> | null = null;\n\n /**\n * Getter returns dynamic capabilities if available, otherwise static fallback.\n */\n get capabilities(): BackendCapabilities {\n return this._dynamicCapabilities ?? MEDUSA_CAPABILITIES;\n }\n\n private sdk: Medusa;\n private logger: ReturnType<typeof createLogger>;\n private currencyCode: string;\n private retryConfig: Required<RetryConfig>;\n private baseUrl: string;\n private publishableKey: string;\n\n /** Secret API key for admin operations (if configured). */\n private adminApiKey?: string;\n /**\n * Dedicated SDK instance for admin calls.\n * Separate from `this.sdk` to prevent the admin API key from being overwritten\n * by customer JWT tokens set during storefront authentication.\n * Only created when adminConfig.apiKey is provided.\n */\n private sdkAdmin?: Medusa;\n\n /**\n * Admin client for Thor multi-tenant endpoints (`/admin/thor/`).\n * Available when `adminConfig.apiKey` is provided.\n *\n * @example\n * ```typescript\n * const { customers } = await commerce.admin.getChannelCustomers('sc_01JXXXXX');\n * const { api_keys } = await commerce.admin.getChannelApiKeys('sc_01JXXXXX');\n * await commerce.admin.updateStorefrontConfig('sc_01JXXXXX', { theme_accent_color: '#EF4444', ... });\n * ```\n */\n public readonly admin?: MedusaAdminClient;\n /** Cached distinct product status values — rarely changes, cached for process lifetime */\n private _cachedProductStatuses: string[] | null = null;\n\n /**\n * In-memory cache for region countries\n * Structure: Map<regionId, { countries: Country[], expiresAt: number }>\n */\n private regionCountriesCache = new Map<\n string,\n { countries: import('@thorprovider/types').Country[]; expiresAt: number }\n >();\n\n /**\n * Cache TTL for region countries (5 minutes)\n */\n private readonly REGION_COUNTRIES_CACHE_TTL = 5 * 60 * 1000;\n\n /**\n * In-memory cache for storefront context (60 second TTL)\n */\n private storefrontContextCache: {\n context: StorefrontContext;\n expiresAt: number;\n } | null = null;\n\n /**\n * Cache TTL for storefront context (60 seconds)\n */\n private readonly STOREFRONT_CONTEXT_CACHE_TTL = 60 * 1000;\n\n /**\n * Authentication provider (available if auth config is provided)\n */\n public readonly auth?: AuthProvider;\n\n private async retrieveCartWithLineDetails(cartId: string): Promise<any> {\n const { cart } = await this.sdk.store.cart.retrieve(cartId, {\n fields: MEDUSA_CART_RETRIEVE_FIELDS,\n } as any);\n return cart;\n }\n\n constructor(config: MedusaProviderConfig) {\n this.logger = createLogger('MedusaProvider', config.debug);\n this.currencyCode = config.currencyCode ?? 'USD';\n this.baseUrl = config.baseUrl;\n this.publishableKey = config.publishableKey;\n\n // Store retry configuration\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? 3,\n timeoutMs: config.retry?.timeoutMs ?? 10000,\n initialDelayMs: config.retry?.initialDelayMs ?? 300,\n backoffMultiplier: config.retry?.backoffMultiplier ?? 2,\n maxDelayMs: config.retry?.maxDelayMs ?? 5000,\n retryableStatusCodes: config.retry?.retryableStatusCodes ?? [408, 429, 500, 502, 503, 504],\n };\n\n this.logger.info('Initializing Medusa Provider', {\n baseUrl: config.baseUrl,\n currencyCode: this.currencyCode,\n hasAuth: !!config.auth,\n hasAdminConfig: !!config.adminConfig,\n retryConfig: this.retryConfig,\n });\n\n this.sdk = new Medusa({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n debug: config.debug ?? false,\n // Always use JWT mode for auth - SDK needs to send Bearer tokens\n // Configure storage method for JWT tokens (browser only)\n auth: config.auth\n ? {\n type: 'jwt',\n // Use localStorage in browser, memory storage on server\n jwtTokenStorageMethod: typeof window !== 'undefined' ? 'local' : 'memory',\n }\n : undefined,\n });\n\n // Create dedicated admin SDK instance with API key (synchronous — no network call)\n if (config.adminConfig?.apiKey) {\n this.adminApiKey = config.adminConfig.apiKey;\n this.sdkAdmin = new Medusa({\n baseUrl: config.baseUrl,\n apiKey: config.adminConfig.apiKey, // → x-medusa-access-token header on all requests\n debug: config.debug ?? false,\n // No publishableKey or auth config: this instance is admin-only, no JWT needed\n });\n // Admin client for Thor multi-tenant custom endpoints (/admin/thor/)\n (this as any).admin = new MedusaAdminClient({\n baseUrl: config.baseUrl,\n apiKey: config.adminConfig.apiKey,\n debug: config.debug,\n });\n this.logger.info('[Admin Auth] Dedicated admin SDK instance created with API key');\n }\n\n // Initialize auth provider if config is provided\n if (config.auth) {\n this.auth = new MedusaAuthProvider(this.sdk, config.auth, config.debug, config.baseUrl, config.publishableKey);\n this.logger.info('Auth provider initialized');\n }\n\n // Fetch dynamic capabilities from Thor Commerce plugin (non-blocking).\n // Falls back to MEDUSA_CAPABILITIES if plugin is not installed.\n this._capabilitiesPromise = this._fetchCapabilities();\n }\n\n // ============================================\n // Thor Plugin — Dynamic Capabilities\n // ============================================\n\n /**\n * Fetch capabilities dynamically from `GET /store/thor/capabilities`.\n * Non-blocking — called in constructor. On failure, static fallback is used.\n * Cache: process-lifetime (per provider instance).\n */\n private async _fetchCapabilities(): Promise<void> {\n try {\n const url = `${this.baseUrl}/store/thor/capabilities`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (!response.ok) {\n this.logger.warn('[Capabilities] Thor plugin endpoint returned non-OK status', {\n status: response.status,\n });\n return;\n }\n\n const data = await response.json();\n this._dynamicCapabilities = data as BackendCapabilities;\n this.logger.info('[Capabilities] Dynamic capabilities loaded from backend');\n } catch (error) {\n // Non-fatal — static MEDUSA_CAPABILITIES remains as fallback\n this.logger.warn('[Capabilities] Failed to fetch dynamic capabilities, using static defaults', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n /**\n * Wrapper for SDK calls with retry logic\n * Handles network failures and temporary backend issues\n */\n private async withRetry<T>(\n operation: () => Promise<T>,\n operationName: string,\n context?: Record<string, any>,\n ): Promise<T> {\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Request timeout after ${this.retryConfig.timeoutMs}ms`));\n }, this.retryConfig.timeoutMs);\n });\n\n // Race between operation and timeout\n const result = await Promise.race([operation(), timeoutPromise]);\n\n if (attempt > 0) {\n this.logger.info(`${operationName} succeeded after ${attempt} retries`, context);\n }\n\n return result;\n } catch (error: any) {\n lastError = error;\n\n // Check if we should retry\n const isRetryable =\n error.message?.includes('fetch failed') ||\n error.message?.includes('timeout') ||\n error.message?.includes('ECONNREFUSED') ||\n error.message?.includes('ETIMEDOUT') ||\n (error.status && this.retryConfig.retryableStatusCodes.includes(error.status));\n\n const shouldRetry = attempt < this.retryConfig.maxRetries && isRetryable;\n\n if (shouldRetry) {\n const delay =\n this.retryConfig.initialDelayMs * Math.pow(this.retryConfig.backoffMultiplier, attempt);\n const cappedDelay = Math.min(delay, this.retryConfig.maxDelayMs);\n\n this.logger.warn(`${operationName} failed, retrying...`, {\n ...context,\n attempt: attempt + 1,\n maxAttempts: this.retryConfig.maxRetries + 1,\n nextRetryIn: `${cappedDelay}ms`,\n error: error.message,\n });\n\n await new Promise((resolve) => setTimeout(resolve, cappedDelay));\n } else {\n this.logger.error(`${operationName} failed after all retries`, {\n ...context,\n totalAttempts: attempt + 1,\n error: error.message,\n });\n break;\n }\n }\n }\n\n // All retries exhausted\n throw lastError;\n }\n\n async getProduct(handle: string, options?: { regionId?: string }): Promise<Product | undefined> {\n this.logger.debug('getProduct', { handle, regionId: options?.regionId });\n\n try {\n return await this.withRetry(\n async () => {\n // calculated_price requires region_id in Medusa v2 — only request it when available\n const baseFields = '+variants,+variants.inventory_quantity,+options,+images,+tags';\n const pricingFields = ',+variants.calculated_price,+variants.prices';\n const fields = options?.regionId ? baseFields + pricingFields : baseFields;\n\n const queryParams: any = {\n handle,\n limit: 1,\n fields,\n };\n // Add region_id for region-based pricing\n if (options?.regionId) {\n queryParams.region_id = options.regionId;\n }\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n queryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(queryParams);\n\n if (!products || products.length === 0) {\n this.logger.debug('Product not found', { handle });\n return undefined;\n }\n\n const transformedProduct = transformProduct(products[0], this.currencyCode);\n\n return transformedProduct;\n },\n 'getProduct',\n { handle, regionId: options?.regionId },\n );\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to fetch product: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getProducts(options: GetProductsOptions & { regionId?: string } = {}): Promise<Product[]> {\n this.logger.debug('getProducts', options);\n\n try {\n return await this.withRetry(\n async () => {\n // calculated_price requires region_id in Medusa v2 — only request it when available\n const baseFields = '+variants,+variants.inventory_quantity,+options,+images,+tags';\n const pricingFields = ',+variants.calculated_price,+variants.prices';\n const fields = options.regionId ? baseFields + pricingFields : baseFields;\n\n // Map Thor SortOption values to Medusa /store/products `order` field names.\n // Native endpoint supports: title, -title, created_at, -created_at\n // Price sorting (price-asc, price-desc) is not supported — omitted so\n // products-client.tsx handles it client-side as before.\n const SORT_KEY_MAP: Record<string, string | null> = {\n featured: null, // server default order\n name: 'title', // A→Z by product title\n newest: '-created_at', // newest products first\n 'price-asc': null, // not supported by native endpoint → client-side\n 'price-desc': null, // not supported by native endpoint → client-side\n rating: null, // not supported → server default\n };\n\n const queryParams: any = {\n q: options.query,\n limit: options.first ?? 100,\n offset: options.after ? parseInt(String(options.after), 10) : undefined,\n fields,\n };\n\n if (options.sortKey) {\n const mappedOrder = SORT_KEY_MAP[options.sortKey] ?? null;\n if (mappedOrder !== null) {\n queryParams.order = mappedOrder;\n }\n // If null → omit order param entirely (server returns default order)\n }\n\n // Add region_id for region-based pricing\n if (options.regionId) {\n queryParams.region_id = options.regionId;\n }\n\n // Basic category/collection filtering\n // Medusa v2 /store/products supports category_id[] and collection_id[]\n if (options.categoryIds && options.categoryIds.length > 0) {\n queryParams.category_id = options.categoryIds;\n }\n if (options.collectionIds && options.collectionIds.length > 0) {\n queryParams.collection_id = options.collectionIds;\n }\n\n // Scope to storefront sales channel when configured.\n // The publishable API key already scopes most requests, but\n // explicit filtering ensures multi-tenant isolation.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n queryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(queryParams);\n\n return products.map((p) => transformProduct(p, this.currencyCode));\n },\n 'getProducts',\n options,\n );\n } catch (error: any) {\n // Enhanced error logging\n this.logger.error('getProducts error details', {\n message: error.message,\n status: error.status,\n type: error.type,\n code: error.code,\n stack: error.stack,\n fullError: JSON.stringify(error, null, 2),\n });\n\n throw new ProviderAPIError(\n `Failed to fetch products: ${error.message || 'Unknown error'}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getProductRecommendations(productId: string): Promise<Product[]> {\n this.logger.debug('getProductRecommendations', { productId });\n\n // Medusa doesn't have built-in recommendations yet\n // Return empty array for now - can be extended with custom logic\n this.logger.warn('Product recommendations not yet implemented for Medusa');\n return [];\n }\n\n // ============================================\n // Advanced Search Operations\n // ============================================\n\n /**\n * Advanced product search using /store/search endpoint\n * \n * Uses hybrid MeiliSearch + Qdrant search with advanced filtering:\n * - Price range filtering\n * - Stock availability\n * - Custom product attributes\n * \n * Falls back to getProducts() if advanced search fails\n */\n async searchProductsAdvanced(\n options?: AdvancedSearchProductsOptions\n ): Promise<{\n products: Product[];\n meta?: SearchResultMeta;\n }> {\n this.logger.debug('searchProductsAdvanced', options);\n\n // Check if advanced search is available\n if (!this.capabilities.advancedSearch) {\n this.logger.warn('Advanced search not available, falling back to getProducts()');\n const products = await this.getProducts(options);\n return {\n products,\n meta: {\n limit: options?.first ?? 20,\n offset: Number(options?.after ?? 0),\n hybridSearchUsed: false,\n },\n };\n }\n\n try {\n // Build query parameters for /store/search\n const queryParams: Record<string, any> = {};\n\n // Text search\n if (options?.query) {\n queryParams.q = options.query;\n }\n\n // Pagination\n queryParams.limit = options?.first ?? 20;\n queryParams.offset = options?.after ? parseInt(String(options.after), 10) : 0;\n\n // Sort — map SortOption values to Medusa's sortable field names.\n // Price sorting is NOT included: backend does not support it yet.\n const SORT_OPTION_TO_ORDER: Record<string, string | null> = {\n featured: null, // no order → server default relevance\n 'price-asc': null, // ❌ not supported by backend; client handles it\n 'price-desc': null, // ❌ not supported by backend; client handles it\n name: 'title', // ✅ THE FIX — was sending 'name', must be 'title'\n newest: '-created_at', // standard Medusa field\n rating: null, // not supported; use server default\n };\n\n if (options?.sortKey) {\n const mapped = SORT_OPTION_TO_ORDER[options.sortKey];\n if (mapped !== undefined && mapped !== null) {\n // If the mapped value already contains '-', respect it; otherwise apply reverse flag\n queryParams.order = options.reverse && !mapped.startsWith('-') ? `-${mapped}` : mapped;\n }\n // If mapped === null → omit order param (server default)\n }\n\n // Native MeiliSearch filters (fast)\n if (options?.categoryIds && options.categoryIds.length > 0) {\n queryParams.categories = options.categoryIds.join(',');\n }\n\n if (options?.collectionIds && options.collectionIds.length > 0) {\n queryParams.collections = options.collectionIds.join(',');\n }\n\n if (options?.tagIds && options.tagIds.length > 0) {\n queryParams.tags = options.tagIds.join(',');\n }\n\n // Hybrid filters (MeiliSearch + Database)\n if (options?.priceMin !== undefined) {\n queryParams.price_min = options.priceMin;\n }\n\n if (options?.priceMax !== undefined) {\n queryParams.price_max = options.priceMax;\n }\n\n // Only send isAvailable=true. Sending false causes the backend to return\n // inventory_quantity=0 for all variants, incorrectly marking them out of stock.\n if (options?.inStockOnly === true) {\n queryParams.isAvailable = true;\n }\n\n // Custom attributes filtering\n if (options?.attributes && options.attributes.length > 0) {\n queryParams.attributes = JSON.stringify(options.attributes);\n }\n\n // Price context\n if (options?.currencyCode) {\n queryParams.currency_code = options.currencyCode;\n }\n\n if (options?.regionId) {\n queryParams.region_id = options.regionId;\n }\n\n // Note: /store/search always returns variants with calculated prices and stock.\n // includeVariants and includeFacets are NOT supported by this endpoint.\n\n // Make request to /store/search\n const url = new URL(`${this.baseUrl}/store/search`);\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n\n this.logger.debug('Calling /store/search', { url: url.toString() });\n\n const response = await fetchWithRetry(\n url.toString(),\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig\n );\n\n if (!response.ok) {\n throw new Error(`Search API returned ${response.status}: ${response.statusText}`);\n }\n\n const data = await response.json();\n\n // Transform products\n const products = (data.hits || []).map((hit: any) => \n transformProduct(hit, options?.currencyCode || this.currencyCode)\n );\n\n // Build metadata\n const meta: SearchResultMeta = {\n total: data.estimatedTotalHits || data.count,\n limit: data.limit || queryParams.limit,\n offset: data.offset || queryParams.offset,\n processingTimeMs: data.processingTimeMs,\n hybridSearchUsed: data.hybrid_query_applied || false,\n appliedFilters: data.applied_filters,\n priceContext: data.price_context\n ? {\n currencyCode: data.price_context.currency_code,\n regionId: data.price_context.region_id,\n }\n : undefined,\n };\n\n this.logger.debug('Search completed', {\n productsFound: products.length,\n totalResults: meta.total,\n processingTime: meta.processingTimeMs,\n });\n\n return { products, meta };\n } catch (error: any) {\n this.logger.error('Advanced search failed, falling back to getProducts()', {\n error: error.message,\n stack: error.stack,\n });\n\n // Graceful fallback to basic getProducts()\n const products = await this.getProducts(options);\n return {\n products,\n meta: {\n limit: options?.first ?? 20,\n offset: Number(options?.after ?? 0),\n hybridSearchUsed: false,\n },\n };\n }\n }\n\n /**\n * Get available filter options for product filtering\n * \n * Aggregates filters from:\n * - Basic filters: categories, collections (always available)\n * - Advanced filters: price range, stock (if useAdvancedSearch=true)\n * - Custom attributes: category-specific attributes from backend\n * \n * Returns empty array if backend doesn't support dynamic filters\n */\n async getAvailableFilters(options: {\n categoryId?: string;\n useAdvancedSearch?: boolean;\n includeBasicFilters?: boolean;\n includeFacetCounts?: boolean;\n }): Promise<FilterConfig[]> {\n this.logger.debug('getAvailableFilters', options);\n\n const filters: FilterConfig[] = [];\n\n try {\n // 1. Basic filters (categories, collections)\n if (options.includeBasicFilters !== false) {\n // Categories filter\n const categories = await this.getCategories({ includeDescendants: false });\n if (categories.length > 0) {\n filters.push({\n id: 'categories',\n label: 'Categories',\n type: 'multi',\n options: categories.map(cat => ({\n value: cat.handle ?? cat.id, // URL slug: ?categories=electronics\n label: cat.name, // Display: \"Electronics\"\n id: cat.id, // Backend ID: pcat_01KMND...\n })),\n isActive: false,\n ranking: 10, // Lower = higher priority\n });\n }\n\n // Collections filter\n const collections = await this.getCollections({ limit: 100 });\n if (collections.length > 0) {\n filters.push({\n id: 'collections',\n label: 'Collections',\n type: 'multi',\n options: collections.map(col => ({\n value: col.handle ?? col.id, // URL slug: ?collections=summer-2024\n label: col.title, // Display: \"Summer 2024\"\n id: col.id, // Backend ID: pcol_01KMND...\n })),\n isActive: false,\n ranking: 20,\n });\n }\n }\n\n // 2. Advanced filters (price, stock)\n if (options.useAdvancedSearch && this.capabilities.advancedSearch) {\n // resolved on all requests. Currently omitted to avoid 400 errors from\n // getProducts fallback when regionId is missing.\n filters.push({\n id: 'price',\n label: 'Price',\n type: 'range',\n min: 0,\n max: 10000,\n isActive: false,\n ranking: 0,\n });\n\n // Stock availability filter\n // ID must match the URL param read by page.tsx (?isAvailable=true)\n filters.push({\n id: 'isAvailable',\n label: 'In Stock',\n type: 'boolean',\n isActive: false,\n ranking: 5,\n });\n }\n\n // 3. Custom attributes (category-specific)\n // Guard: skip API call entirely when the customAttributes capability is disabled.\n // This prevents a network request to /store/custom-attributes/category/:id and\n // avoids rendering attribute filters that the backend hasn't enabled as a capability.\n if (options.categoryId && this.capabilities.customAttributes) {\n try {\n const url = `${this.baseUrl}/store/custom-attributes/category/${options.categoryId}`;\n this.logger.debug('Fetching custom attributes', { url });\n\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig\n );\n\n if (response.ok) {\n const data = await response.json();\n const rawAttributes = data.attributes || [];\n\n // Transform backend attributes to FilterConfig\n // Backend response shape: { attributes: [{ attribute_id, attribute: { name, handle, ... } }] }\n // The actual attribute data is nested inside the \"attribute\" property.\n rawAttributes.forEach((item: any) => {\n // Unwrap nested structure: item may be { attribute_id, attribute: {...} }\n // or a flat object with properties directly on it\n const attr = item.attribute ?? item;\n\n if (!attr.is_filterable || !attr.is_active) {\n return; // Skip non-filterable or inactive attributes\n }\n\n const filterType = this.mapAttributeTypeToFilterType(attr.type);\n\n const filter: FilterConfig = {\n id: attr.handle,\n label: attr.name,\n type: filterType,\n isActive: false,\n ranking: attr.ranking || 50, // Custom attributes lower priority\n };\n\n // Add options for single/multi types\n if ((filterType === 'single' || filterType === 'multi') && attr.values) {\n filter.options = attr.values.map((val: any) => ({\n value: this.toSlug(val.value), // URL slug: ?ram=8gb\n label: val.value, // Display: \"8GB\"\n id: val.id, // Backend ID: 01KN03N67V13K5S2E6B6695KRN\n count: options.includeFacetCounts ? val.count : undefined,\n }));\n }\n\n // Add range values for numeric types\n if (filterType === 'range' && attr.metadata) {\n filter.min = attr.metadata.min || 0;\n filter.max = attr.metadata.max || 100;\n }\n\n filters.push(filter);\n });\n\n this.logger.debug('Custom attributes loaded', {\n categoryId: options.categoryId,\n attributesCount: rawAttributes.length,\n filterableCount: filters.length,\n });\n } else {\n this.logger.warn('Custom attributes endpoint not available', {\n status: response.status,\n categoryId: options.categoryId,\n });\n }\n } catch (attrError: any) {\n // Don't fail if custom attributes unavailable\n this.logger.warn('Failed to load custom attributes, continuing without them', {\n error: attrError.message,\n categoryId: options.categoryId,\n });\n }\n }\n\n // Sort by ranking (lower = higher priority)\n filters.sort((a, b) => (a.ranking ?? 0) - (b.ranking ?? 0));\n\n this.logger.debug('Filters aggregated', {\n totalFilters: filters.length,\n filterIds: filters.map(f => f.id),\n });\n\n return filters;\n } catch (error: any) {\n this.logger.error('Failed to get available filters', {\n error: error.message,\n stack: error.stack,\n });\n\n // Return empty array on error (don't block UI)\n return [];\n }\n }\n\n /**\n * Convert a human-readable string to a URL-safe slug.\n * Used to produce SEO-friendly filter values (option.value) that go into the URL.\n *\n * Examples:\n * \"8GB RAM\" → \"8gb-ram\"\n * \"Red Color\" → \"red-color\"\n * \"16 GB\" → \"16-gb\"\n */\n private toSlug(str: string): string {\n return str\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '');\n }\n\n /**\n * Map backend attribute type to filter type\n */\n private mapAttributeTypeToFilterType(\n backendType: string\n ): 'single' | 'multi' | 'boolean' | 'range' {\n switch (backendType) {\n case 'single-select':\n return 'single';\n case 'multi-select':\n return 'multi';\n case 'boolean':\n return 'boolean';\n case 'number':\n case 'range':\n return 'range';\n default:\n return 'multi'; // Default to multi-select\n }\n }\n\n // ============================================\n // Collection Operations\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n this.logger.debug('getCollection', { handle });\n\n try {\n const { collections } = (await this.sdk.store.collection.list({\n handle: [handle],\n limit: 1,\n })) as any;\n\n if (!collections || collections.length === 0) {\n this.logger.debug('Collection not found', { handle });\n return undefined;\n }\n\n return transformCollection(collections[0]);\n } catch (error: any) {\n this.logger.error('Failed to fetch collection', { handle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch collection: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n this.logger.debug('getCollections', { options });\n\n try {\n // Increase limit for client-side filtering to improve search results\n // If query is present, fetch more items (up to 1000) to increase likelihood of finding matches\n const limit = options?.query ? 1000 : (options?.limit || 100);\n \n const { collections } = (await this.sdk.store.collection.list({\n limit,\n })) as any;\n\n let result = collections.map(transformCollection);\n\n // Client-side search filtering (Medusa Store API lacks query param for collections)\n if (options?.query) {\n const q = options.query.toLowerCase();\n result = result.filter((c: Collection) => \n c.title.toLowerCase().includes(q) || \n c.handle.toLowerCase().includes(q)\n );\n }\n\n return result;\n } catch (error: any) {\n this.logger.error('Failed to fetch collections', { error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch collections: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getCollectionProducts(\n handle: string,\n options: CollectionProductsOptions = {},\n ): Promise<Product[]> {\n this.logger.debug('getCollectionProducts', { handle, options });\n\n try {\n // First get the collection to get its ID\n const collection = await this.getCollection(handle);\n if (!collection) {\n throw new ResourceNotFoundError('Collection', handle);\n }\n\n // Then get products for this collection\n const collectionQueryParams: any = {\n collection_id: [collection.handle], // Medusa uses handle in queries\n order: options.sortKey,\n limit: options.first ?? 100,\n offset: options.after ? parseInt(options.after, 10) : undefined,\n fields:\n '+variants,+variants.prices,+variants.calculated_prices,+variants.inventory_quantity,+options,+images,+tags',\n };\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n collectionQueryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(collectionQueryParams);\n\n return products.map((p) => transformProduct(p, this.currencyCode));\n } catch (error: any) {\n if (error instanceof ResourceNotFoundError) throw error;\n\n this.logger.error('Failed to fetch collection products', { handle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch collection products: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n // ============================================\n // Category Operations\n // ============================================\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n this.logger.debug('getCategory', { idOrHandle });\n\n try {\n const { product_categories } = (await this.sdk.store.category.list({\n handle: [idOrHandle],\n limit: 1,\n })) as any;\n\n if (!product_categories || product_categories.length === 0) {\n this.logger.debug('Category not found', { idOrHandle });\n return undefined;\n }\n\n return transformCategory(product_categories[0]);\n } catch (error: any) {\n this.logger.error('Failed to fetch category', { idOrHandle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch category: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Returns the set of product-category IDs that have at least one product\n * available in the given sales channel.\n *\n * Because Medusa's store/product-categories endpoint does not accept a\n * `sales_channel_id` filter, we derive the active category IDs by querying\n * store/products with the sales-channel scope and collecting the category\n * relations from the response. Pagination is handled internally so the\n * result is always complete regardless of catalog size.\n *\n * @deprecated Use `_getChannelCategories()` instead (backed by Thor Commerce plugin).\n * Kept as fallback for backends without the plugin installed.\n */\n private async _getActiveCategoryIds(salesChannelId: string): Promise<Set<string>> {\n this.logger.debug('_getActiveCategoryIds', { salesChannelId });\n const categoryIds = new Set<string>();\n const limit = 500;\n let offset = 0;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { products } = (await this.sdk.store.product.list({\n sales_channel_id: [salesChannelId],\n // Request only the category id relation to minimise payload size\n fields: '+categories.id',\n limit,\n offset,\n } as any)) as any;\n\n for (const product of products ?? []) {\n for (const cat of product.categories ?? []) {\n if (cat?.id) categoryIds.add(cat.id);\n }\n }\n\n if (!products || products.length < limit) break;\n offset += limit;\n }\n\n this.logger.debug('_getActiveCategoryIds result', { count: categoryIds.size });\n return categoryIds;\n }\n\n /**\n * Fetch channel-scoped categories from Thor Commerce plugin.\n * Uses `GET /store/thor/categories` — a single indexed query.\n * Falls back to `_getActiveCategoryIds()` if the plugin is not available.\n */\n private async _getChannelCategories(salesChannelId: string): Promise<Set<string>> {\n try {\n const url = `${this.baseUrl}/store/thor/categories`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (response.status === 404) {\n // Plugin not installed — fall back to legacy N+1 method\n this.logger.debug('Thor plugin categories endpoint not found, falling back to legacy method');\n return this._getActiveCategoryIds(salesChannelId);\n }\n\n if (!response.ok) {\n this.logger.warn('Thor plugin categories endpoint returned non-OK status', {\n status: response.status,\n });\n return this._getActiveCategoryIds(salesChannelId);\n }\n\n const data = await response.json();\n const categoryIds = new Set<string>();\n for (const cat of data.categories ?? []) {\n if (cat?.id) categoryIds.add(cat.id);\n }\n\n this.logger.debug('_getChannelCategories result (Thor plugin)', { count: categoryIds.size });\n return categoryIds;\n } catch (error) {\n this.logger.warn('Failed to fetch channel categories from Thor plugin, falling back to legacy method', {\n error: error instanceof Error ? error.message : String(error),\n });\n return this._getActiveCategoryIds(salesChannelId);\n }\n }\n\n async getCategories(options: GetCategoriesOptions = {}): Promise<ProductCategory[]> {\n this.logger.debug('getCategories', { options });\n\n const { customFetcher } = options;\n\n // If custom fetcher provided, use it instead of default SDK logic\n if (customFetcher) {\n this.logger.debug('Using custom fetcher for categories');\n return customFetcher(options);\n }\n\n try {\n // Increase limit for client-side filtering to improve search results\n // If query is present, fetch more items (up to 1000) to increase likelihood of finding matches\n const limit = options.query ? 1000 : (options.limit ?? 100);\n\n const queryParams: any = {\n limit,\n include_descendants_tree: options.includeDescendants ?? false,\n };\n\n if (options.parentCategoryId) {\n queryParams.parent_category_id = options.parentCategoryId;\n }\n\n const { product_categories } = (await this.sdk.store.category.list(queryParams)) as any;\n\n let result = product_categories.map(transformCategory);\n\n // --- Sales channel scoping ---\n // Prefer Thor Commerce plugin endpoint (single indexed query).\n // Falls back to legacy N+1 method if plugin is not installed.\n const salesChannelId =\n options.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n const activeCategoryIds = await this._getChannelCategories(salesChannelId);\n result = result.filter((c: ProductCategory) => activeCategoryIds.has(c.id));\n }\n\n // Client-side search filtering\n if (options.query) {\n const q = options.query.toLowerCase();\n result = result.filter(\n (c: ProductCategory) =>\n c.name.toLowerCase().includes(q) || c.handle.toLowerCase().includes(q),\n );\n }\n\n return result;\n } catch (error: any) {\n this.logger.error('Failed to fetch categories', { error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch categories: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getCategoryProducts(\n handle: string,\n options: CollectionProductsOptions = {},\n ): Promise<Product[]> {\n this.logger.debug('getCategoryProducts', { handle, options });\n\n try {\n // First get the category to get its ID\n const category = await this.getCategory(handle);\n if (!category) {\n throw new ResourceNotFoundError('Category', handle);\n }\n\n // Then get products for this category\n const categoryQueryParams: any = {\n category_id: [category.id],\n order: options.sortKey,\n limit: options.first ?? 100,\n offset: options.after ? parseInt(options.after, 10) : undefined,\n fields:\n '+variants,+variants.prices,+variants.calculated_prices,+variants.inventory_quantity,+options,+images,+tags',\n };\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n categoryQueryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(categoryQueryParams);\n\n return products.map((p) => transformProduct(p, this.currencyCode));\n } catch (error: any) {\n if (error instanceof ResourceNotFoundError) throw error;\n\n this.logger.error('Failed to fetch category products', { handle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch category products: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n // ============================================\n // Cart Operations\n // ============================================\n\n async createCart(options?: { regionId?: string }): Promise<Cart> {\n this.logger.debug('createCart', { regionId: options?.regionId });\n\n try {\n const createPayload: any = {};\n\n // If a regionId is provided, prefer letting Medusa resolve the currency\n // from the region. Do NOT set `currency_code` when `region_id` is present,\n // otherwise Medusa may use the provided currency and ignore the region.\n if (options?.regionId) {\n createPayload.region_id = options.regionId;\n } else {\n createPayload.currency_code = this.currencyCode.toLowerCase();\n }\n\n const { cart } = await this.sdk.store.cart.create(createPayload);\n\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create cart', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create cart: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n this.logger.debug('getCart', { cartId });\n\n try {\n const cart = await this.retrieveCartWithLineDetails(cartId);\n\n if (!cart) {\n this.logger.debug('Cart not found', { cartId });\n return undefined;\n }\n\n return transformCart(cart);\n } catch (error: unknown) {\n // Medusa returns 404 for non-existent carts\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) {\n this.logger.debug('Cart not found', { cartId });\n return undefined;\n }\n\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch cart', { cartId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch cart: ${errorMessage}`, 'medusa', status);\n }\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n this.logger.debug('addToCart', { cartId, lines });\n\n try {\n // Ensure cart exists and has a region_id before attempting to add line items.\n // If Medusa can't resolve pricing due to missing region/pricing rows, it will throw a 500.\n const retrieveCtx = { cartId };\n const retrieveResult = await this.withRetry(\n async () => this.sdk.store.cart.retrieve(cartId),\n 'retrieveCartBeforeAdd',\n retrieveCtx,\n );\n\n console.log('retrieveResult =', JSON.stringify(retrieveResult, null, 2))\n \n const backendCart = (retrieveResult as any)?.cart;\n if (!backendCart) {\n this.logger.warn('Cart not found before addToCart', { cartId });\n throw new ProviderAPIError('Cart not found. Please refresh and try again.', 'medusa', 404);\n }\n\n console.log('backendCart =', JSON.stringify(backendCart, null, 2))\n\n if (!backendCart.region_id) {\n this.logger.warn('Attempted to add item to cart with no region_id', { cartId });\n throw new ProviderAPIError(\n 'Cart does not have a region set. Please select a region or recreate your cart and try again.',\n 'medusa',\n 400,\n );\n }\n\n // Add items one by one (Medusa SDK doesn't support batch add)\n for (const line of lines) {\n this.logger.debug('createLineItem payload', {\n cartId,\n variant_id: line.merchandiseId,\n quantity: line.quantity,\n cartRegion: backendCart.region_id,\n });\n\n // Pre-check: ensure variant has pricing for the cart's region/currency to avoid server 500\n try {\n // The Medusa SDK may not expose a direct productVariant.retrieve endpoint in this version.\n // Use product.list filtered by region to locate the variant and request region-aware prices.\n const variantCheckParams: any = {\n limit: 200,\n fields: '+variants,+variants.calculated_price,+variants.prices,+variants.money_amounts',\n region_id: backendCart.region_id,\n };\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n variantCheckParams.sales_channel_id = [salesChannelId];\n }\n\n const plist = await this.sdk.store.product.list(variantCheckParams);\n const products = (plist as any)?.products || [];\n let foundVariant: any | undefined;\n for (const p of products) {\n if (Array.isArray(p.variants)) {\n const v = p.variants.find((vv: any) => vv.id === line.merchandiseId);\n if (v) {\n foundVariant = v;\n break;\n }\n }\n }\n\n if (!foundVariant) {\n this.logger.warn('Variant not found in product.list for pricing check', {\n variantId: line.merchandiseId,\n cartRegion: backendCart.region_id,\n });\n throw new ProviderAPIError(\n 'Product or variant not found. Please refresh and try again.',\n 'medusa',\n 404,\n );\n }\n\n console.log('Found Variant:', JSON.stringify(foundVariant, null, 2));\n\n const variant = foundVariant;\n // Prefer calculated_price when present\n let hasPriceForRegion = false;\n if (\n variant?.calculated_price &&\n (variant.calculated_price.calculated_amount ?? null) !== null\n ) {\n const calcCurrency = (variant.calculated_price.currency_code || '').toLowerCase();\n const cartCurrency = (\n backendCart.currency_code ||\n this.currencyCode ||\n ''\n ).toLowerCase();\n\n console.log('calcCurrency =', calcCurrency);\n console.log('cartCurrency =', cartCurrency);\n console.log('this.currencyCode =', this.currencyCode)\n\n if (\n !cartCurrency ||\n calcCurrency === cartCurrency ||\n calcCurrency === this.currencyCode.toLowerCase()\n ) {\n hasPriceForRegion = true;\n }\n }\n\n if (!hasPriceForRegion) {\n const prices = variant?.prices || variant?.money_amounts || [];\n hasPriceForRegion =\n Array.isArray(prices) &&\n prices.some((p: any) => {\n return (\n p.region_id === backendCart.region_id ||\n p.currency_code === backendCart.currency_code ||\n p.currency_code === this.currencyCode ||\n p.currency === this.currencyCode\n );\n });\n }\n\n if (!hasPriceForRegion) {\n const prices = variant?.prices || variant?.money_amounts || [];\n this.logger.warn('Variant missing price for cart region (product.list)', {\n variantId: line.merchandiseId,\n cartRegion: backendCart.region_id,\n prices,\n });\n throw new ProviderAPIError(\n 'This product does not have pricing configured for your selected region. Please try a different region or contact support.',\n 'medusa',\n 400,\n );\n }\n } catch (variantErr) {\n this.logger.error('Variant price check failed', {\n variantId: line.merchandiseId,\n error: extractErrorMessage(variantErr),\n });\n // Surface a clear error to avoid a 500 from backend when possible\n throw new ProviderAPIError(\n 'Unable to verify variant pricing before adding to cart. Please try again later.',\n 'medusa',\n 500,\n );\n }\n\n const result = await this.sdk.store.cart.createLineItem(cartId, {\n variant_id: line.merchandiseId,\n quantity: line.quantity,\n });\n void result;\n }\n\n const cart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n const errorDetails: any = { cartId, lines, message: errorMessage };\n\n if (typeof error === 'object' && error !== null) {\n const err = error as any;\n if (err.status) errorDetails.status = err.status;\n if (err.statusCode) errorDetails.statusCode = err.statusCode;\n if (err.code) errorDetails.code = err.code;\n // If SDK exposes response body, include it for diagnostics\n if (err.response) {\n errorDetails.backendResponse = err.response.data ?? err.response;\n }\n // Fallback: include entire error for logs\n try {\n errorDetails.fullError = JSON.stringify(err, Object.getOwnPropertyNames(err));\n } catch (e) {\n // ignore stringify errors\n }\n }\n\n this.logger.error('Failed to add to cart', errorDetails);\n\n const status = (error as any)?.status || (error as any)?.statusCode;\n let userMessage = errorMessage;\n\n if (status === 500) {\n userMessage =\n 'Unable to add product to cart. This product may not have pricing configured for your selected region. Please try selecting a different region or contact support.';\n } else if (status === 404) {\n userMessage = 'Product or cart not found. Please refresh the page and try again.';\n } else if (status === 400 || status === 422) {\n userMessage = 'Invalid product configuration. This product may be unavailable.';\n }\n\n throw new ProviderAPIError(userMessage, 'medusa', status);\n }\n }\n\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n this.logger.debug('removeFromCart', { cartId, lineIds });\n \n try {\n // Medusa removes line items one at a time\n for (const lineId of lineIds) {\n await this.sdk.store.cart.deleteLineItem(cartId, lineId);\n }\n\n const cart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to remove from cart', { cartId, lineIds, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to remove from cart: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n this.logger.debug('updateCart', { cartId, lines });\n\n try {\n // Medusa updates line items one at a time\n for (const line of lines) {\n await this.sdk.store.cart.updateLineItem(cartId, line.id, {\n quantity: line.quantity,\n });\n }\n\n const cart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to update cart', { cartId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to update cart: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n /**\n * Get available regions from Medusa\n * Returns region information including id, name, and currency\n */\n async getRegions(): Promise<\n Array<{\n id: string;\n name: string;\n currency_code: string;\n countries?: Array<{ id: string; iso_2: string; name: string; display_name?: string }>;\n }>\n > {\n this.logger.debug('getRegions');\n\n try {\n const { regions } = await this.sdk.store.region.list();\n\n return regions.map((region: any) => ({\n id: region.id,\n name: region.name,\n currency_code: region.currency_code,\n countries: region.countries,\n }));\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch regions', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to fetch regions: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n // ============================================\n // Payment Operations\n // ============================================\n\n // ============================================\n // Order Operations\n // ============================================\n\n /**\n * Get all orders for a customer (storefront).\n *\n * Note: This retrieves orders from the storefront API (store.order.list),\n * which returns orders only for the authenticated customer in the JWT.\n *\n * @param options - Order query options (supports callbacks for custom backends)\n * @returns Array of orders for the authenticated customer\n *\n * @example\n * ```typescript\n * const orders = await provider.getOrders();\n * console.log(`Found ${orders.length} orders`);\n * ```\n */\n async getOrders(options: GetOrdersOptions = {}): Promise<Order[]> {\n const { customFetcher, salesChannelId } = options;\n\n // If custom fetcher provided, use it instead of default SDK logic\n if (customFetcher) {\n this.logger.debug('Using custom fetcher for orders');\n return customFetcher(options);\n }\n\n this.logger.info('Getting orders for authenticated customer');\n\n try {\n const result = await this.withRetry(\n async () =>\n this.sdk.store.order.list({\n // Medusa v2 JS-SDK automatically includes authorization header if JWT is present\n fields: '+items,+items.variant,+items.variant.product,+shipping_address,+billing_address,+customer',\n }),\n 'getOrders',\n {},\n );\n\n const orders = result.orders ?? [];\n this.logger.debug(`Found ${orders.length} orders for customer`);\n\n const transformed: Order[] = orders.map((order: any) => transformOrder(order));\n\n // Multi-tenant: filter by sales channel if requested\n const channelId = salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (channelId) {\n const scoped = filterByChannel<Order>(transformed, channelId);\n this.logger.debug(\n `Channel scoping: ${scoped.length}/${transformed.length} orders match channel ${channelId}`,\n );\n return scoped;\n }\n\n return transformed;\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n\n this.logger.error('Error getting orders', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to fetch orders: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n /**\n * Get a single order by ID\n *\n * @param orderId - Order ID\n * @returns Order or undefined if not found\n *\n * @example\n * ```typescript\n * const order = await provider.getOrder('order_123');\n * if (order) {\n * console.log(`Order ${order.orderNumber} - ${order.status}`);\n * }\n * ```\n */\n async getOrder(orderId: string): Promise<Order | undefined> {\n this.logger.info('Getting order', orderId);\n\n if (!orderId) {\n throw new ProviderAPIError('Order ID is required', 'medusa');\n }\n\n try {\n const { order } = await this.withRetry(\n async () =>\n this.sdk.store.order.retrieve(orderId, {\n fields: '+items,+items.variant,+items.variant.product,+shipping_address,+billing_address,+customer',\n }),\n 'getOrder',\n { orderId },\n );\n\n if (!order) {\n this.logger.debug(`Order not found: ${orderId}`);\n return undefined;\n }\n\n this.logger.debug(`Retrieved order: ${order.display_id ?? orderId}`);\n\n return transformOrder(order);\n } catch (error: unknown) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) {\n this.logger.debug(`Order not found: ${orderId}`);\n return undefined;\n }\n\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch order', { orderId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch order: ${errorMessage}`, 'medusa', status);\n }\n }\n\n // ============================================\n // Customer Operations\n // ============================================\n\n /**\n * List customers with optional filtering and pagination.\n *\n * Uses the Medusa admin API — requires admin-level JWT.\n *\n * @param options - Query options (search, sort, pagination)\n * @returns Array of customers\n *\n * @example\n * ```typescript\n * const customers = await provider.getCustomers({ search: 'john', limit: 20, offset: 0 });\n * ```\n */\n async getCustomers(options: GetCustomersOptions = {}): Promise<Customer[]> {\n this.logger.info('Getting customers', options);\n\n const { search, limit = 20, offset = 0, sortBy = 'createdAt', salesChannelId, customFetcher } = options;\n\n // If custom fetcher provided, use it instead of default SDK logic\n if (customFetcher) {\n this.logger.debug('Using custom fetcher for customers');\n return customFetcher(options);\n }\n\n const orderMap: Record<string, string> = {\n createdAt: 'created_at',\n email: 'email',\n firstName: 'first_name',\n };\n\n try {\n // Build filters object for multi-tenant scoping\n const filters: Record<string, any> = {};\n if (salesChannelId) {\n filters.metadata = { sales_channel_id: salesChannelId };\n this.logger.debug(`Filtering customers by salesChannelId: ${salesChannelId}`);\n }\n\n const result = await this.makeAdminRequest(async () => {\n return (this.sdkAdmin as any).admin.customer.list({\n q: search || undefined,\n limit,\n offset,\n order: orderMap[sortBy] ?? 'created_at',\n ...(Object.keys(filters).length > 0 && { filters }),\n });\n });\n\n const customers = result?.customers ?? [];\n this.logger.debug(`Found ${customers.length} customers`);\n\n const transformed: Customer[] = customers.map((c: any) => transformCustomer(c));\n\n return transformed;\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Error getting customers', { error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch customers: ${errorMessage}`, 'medusa', status);\n }\n }\n\n /**\n * Get a single customer by ID.\n *\n * Uses the Medusa admin API.\n *\n * @param customerId - Customer ID\n * @returns Customer or undefined if not found\n */\n async getCustomer(customerId: string): Promise<Customer | undefined> {\n this.logger.info('Getting customer', customerId);\n\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa');\n }\n\n try {\n const result = await this.makeAdminRequest(async () => {\n return (this.sdkAdmin as any).admin.customer.retrieve(customerId);\n });\n\n if (!result?.customer) {\n return undefined;\n }\n\n return transformCustomer(result.customer);\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch customer', { customerId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch customer: ${errorMessage}`, 'medusa', status);\n }\n }\n\n /**\n * Update customer information.\n *\n * Uses the Medusa admin API.\n *\n * @param customerId - Customer ID\n * @param data - Fields to update\n * @returns Updated customer\n */\n async updateCustomer(\n customerId: string,\n data: Partial<Omit<Customer, 'id' | 'createdAt'>>,\n ): Promise<Customer> {\n this.logger.info('Updating customer', { customerId, fields: Object.keys(data) });\n\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa');\n }\n\n // Transform Thor camelCase → Medusa snake_case\n const payload: Record<string, unknown> = {};\n if (data.firstName !== undefined) payload.first_name = data.firstName;\n if (data.lastName !== undefined) payload.last_name = data.lastName;\n if (data.phone !== undefined) payload.phone = data.phone ?? null;\n if (data.email !== undefined) payload.email = data.email;\n if (data.metadata !== undefined) payload.metadata = data.metadata;\n\n try {\n const result = await this.makeAdminRequest(async () => {\n return (this.sdkAdmin as any).admin.customer.update(customerId, payload);\n });\n\n return transformCustomer(result.customer);\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to update customer', { customerId, error: errorMessage });\n throw new ProviderAPIError(`Failed to update customer: ${errorMessage}`, 'medusa', status);\n }\n }\n\n /**\n * Get orders placed by a specific customer (admin view).\n *\n * @param customerId - Customer ID\n * @param limit - Max number of orders (default: 10)\n * @returns Array of orders\n */\n async getCustomerOrders(customerId: string, limit = 10): Promise<Order[]> {\n this.logger.info('Getting orders for customer (admin)', { customerId, limit });\n\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa');\n }\n\n if (!this.isAdminConfigured) {\n this.logger.warn('getCustomerOrders: adminConfig not provided, returning empty result');\n return [];\n }\n\n try {\n // Use makeAdminRequest to ensure proper admin authentication.\n // withRetry() does NOT inject admin auth — it would send unauthenticated\n // requests to admin endpoints.\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.order.list({\n customer_id: customerId,\n limit,\n order: '-created_at',\n fields: '+items,+items.variant,+items.variant.product,+shipping_address',\n });\n\n const orders = result?.orders ?? [];\n this.logger.debug(`Found ${orders.length} orders for customer ${customerId}`);\n\n return orders.map((o: any) => transformOrder(o));\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch customer orders', { customerId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch customer orders: ${errorMessage}`, 'medusa', status);\n }\n }\n\n // ============================================\n // Admin Customer Operations\n // ============================================\n\n /**\n * List customers for admin dashboard.\n *\n * Uses makeAdminRequest() to ensure proper admin authentication.\n * Unlike getCustomers() (which currently lacks admin auth), this method\n * properly awaits admin initialization and authenticates via SDK admin session.\n *\n * Gracefully degrades to empty result when adminConfig is not provided.\n *\n * @param options - Query options (search, limit, offset, salesChannelId)\n * @returns Object with customers array and count\n */\n async getAdminCustomers(options?: {\n search?: string;\n limit?: number;\n offset?: number;\n salesChannelId?: string;\n }): Promise<{ customers: Customer[]; count: number }> {\n if (!this.isAdminConfigured) {\n this.logger.warn('getAdminCustomers: adminConfig not provided, returning empty result');\n return { customers: [], count: 0 };\n }\n\n const limit = Math.min(options?.limit ?? 20, 1000);\n const offset = options?.offset ?? 0;\n\n this.logger.info('Getting admin customers', {\n limit,\n offset,\n search: options?.search,\n salesChannelId: options?.salesChannelId,\n });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.customer.list({\n limit,\n offset,\n order: '-created_at',\n ...(options?.search && { q: options.search }),\n });\n\n const customers = result?.customers ?? [];\n const count = result?.count ?? customers.length;\n\n this.logger.debug(`Admin customers: fetched ${customers.length} (backend count: ${count})`);\n\n const transformed: Customer[] = customers.map((c: any) => transformCustomer(c));\n\n // NOTE: Medusa customers are global — they are not natively scoped to\n // a sales channel. filterByChannel checks metadata.sales_channel_id\n // which Medusa seeds never set → would filter out ALL customers.\n // For admin dashboard, show all customers.\n this.logger.debug(`Admin customers: ${transformed.length} returned (backend count: ${count})`);\n\n return { customers: transformed, count };\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin customers', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin customers: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Get a single customer by ID for admin dashboard.\n *\n * Uses makeAdminRequest() for proper admin authentication.\n * Returns undefined (not an error) when the customer is not found (404).\n *\n * @param customerId - Customer ID\n * @returns Customer or undefined if not found\n */\n async getAdminCustomer(customerId: string): Promise<Customer | undefined> {\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminCustomer requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin customer', { customerId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.customer.retrieve(customerId);\n if (!result?.customer) return undefined;\n return transformCustomer(result.customer);\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin customer', { customerId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin customer: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n // ============================================\n // Admin Customer Address Operations\n // ============================================\n\n /**\n * Get all addresses for a customer (admin operation).\n * Uses sdk.admin.customer.listAddresses() for proper admin authentication.\n *\n * @param customerId - The customer's ID\n * @returns Array of addresses\n */\n async getAdminCustomerAddresses(customerId: string): Promise<Address[]> {\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminCustomerAddresses requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin customer addresses', { customerId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.customer.listAddresses(customerId);\n const addresses = result?.addresses ?? [];\n return addresses.map((addr: any) => transformAddress(addr));\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return [];\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin customer addresses', { customerId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get customer addresses: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n // ============================================\n // Admin Order Operations\n // ============================================\n\n /**\n * Get all orders for admin dashboard listing.\n *\n * Unlike getCustomerOrders() (which filters by a specific customerId via\n * sdk.admin.order.list with storefront JWT), this method:\n * - Lists ALL orders across the store\n * - Uses fetchAdminAPI() with proper admin credentials\n * - Applies multi-tenant channel scoping via filterByChannel()\n * - Gracefully degrades to empty result when adminConfig is not provided\n *\n * IMPORTANT: Do NOT use sdk.admin.order.list() here — it uses storefront\n * JWT auth which is insufficient for Medusa Admin API.\n */\n async getAdminOrders(options?: {\n search?: string;\n status?: string | string[];\n limit?: number;\n offset?: number;\n /** Medusa field name for sorting, e.g. 'created_at', 'total' */\n order?: string;\n direction?: 'asc' | 'desc';\n /** Filter by sales channel — uses Medusa native `sales_channel_id` query. */\n salesChannelId?: string;\n /**\n * When true, also fetches draft orders from /admin/draft-orders and merges\n * them into the result sorted by created_at desc. Draft orders are stored\n * as a separate entity from regular orders in Medusa v2 and do NOT appear\n * in GET /admin/orders.\n */\n includeDrafts?: boolean;\n }): Promise<{ orders: Order[]; count: number }> {\n if (!this.isAdminConfigured) {\n this.logger.warn('getAdminOrders: adminConfig not provided, returning empty result');\n return { orders: [], count: 0 };\n }\n\n const limit = Math.min(options?.limit ?? 20, 100);\n const offset = options?.offset ?? 0;\n\n this.logger.info('Getting admin orders', {\n limit,\n offset,\n search: options?.search,\n status: options?.status,\n salesChannelId: options?.salesChannelId,\n includeDrafts: options?.includeDrafts,\n });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { orders, count } = await this.sdkAdmin!.admin.order.list({\n limit,\n offset,\n fields:\n 'id,display_id,email,created_at,status,total,currency_code,' +\n '+items,+items.variant,' +\n '+shipping_address,+billing_address,+customer',\n ...(options?.search && { q: options.search }),\n // Medusa v2 admin API supports native sales_channel_id filter.\n ...(options?.salesChannelId && { sales_channel_id: [options.salesChannelId] }),\n });\n\n const transformed: Order[] = (orders ?? []).map((o: any) => transformOrder(o));\n\n this.logger.debug(`Admin orders: ${transformed.length} returned (backend count: ${count})`);\n\n // In Medusa v2, draft orders are a SEPARATE entity from regular orders.\n // GET /admin/orders never returns them — you must query GET /admin/draft-orders.\n // When includeDrafts is requested, merge both lists sorted by created_at desc.\n if (!options?.includeDrafts) {\n return { orders: transformed, count };\n }\n\n let draftOrders: Order[] = [];\n let draftCount = 0;\n\n try {\n // Fetch all draft orders (typically small number, no pagination needed).\n // Use a generous limit so we don't miss recently-created ones.\n const draftResult = await (this.sdkAdmin as any).admin.draftOrder.list({\n limit: 100,\n offset: 0,\n fields:\n 'id,display_id,email,created_at,status,total,currency_code,' +\n '+items,+items.variant,' +\n '+shipping_address,+billing_address,+customer',\n ...(options?.salesChannelId && { sales_channel_id: [options.salesChannelId] }),\n });\n\n // Medusa returns { draft_orders: [...], count: N }\n const rawDrafts = draftResult?.draft_orders ?? [];\n draftCount = draftResult?.count ?? rawDrafts.length;\n draftOrders = rawDrafts.map((o: any) => ({\n ...transformOrder(o),\n isDraft: true, // ← Mark as draft order for UI differentiation\n }));\n\n this.logger.debug(`Draft orders: ${draftOrders.length} returned (backend count: ${draftCount})`);\n } catch (draftError) {\n // Draft orders endpoint may not be available (plugin not installed).\n // Log warning but don't fail the whole request.\n this.logger.warn('Failed to fetch draft orders — plugin may not be installed', {\n error: extractErrorMessage(draftError),\n });\n }\n\n // Merge and sort combined list by created_at descending.\n const combined = [...transformed, ...draftOrders].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),\n );\n\n return { orders: combined, count: count + draftCount };\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin orders', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin orders: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Cancel an order (admin operation).\n * Uses sdk.admin.order.cancel() for proper SDK integration.\n * Throws ProviderAPIError if adminConfig is not provided.\n */\n async cancelOrder(orderId: string): Promise<Order> {\n if (!orderId || typeof orderId !== 'string') {\n throw new ProviderAPIError('Invalid order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'cancelOrder requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Cancelling order', { orderId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { order } = await this.sdkAdmin!.admin.order.cancel(orderId);\n\n const transformed = transformOrder(order);\n this.logger.debug('Order cancelled', { orderId, status: transformed.status });\n return transformed;\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to cancel order', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to cancel order: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Create a fulfillment for an order (admin operation).\n * Uses sdk.admin.order.createFulfillment() for proper SDK integration.\n * Throws ProviderAPIError if adminConfig is not provided.\n *\n * @param items - Optional specific line-items + quantities.\n * When omitted, Medusa fulfills all unfulfilled items.\n */\n async createFulfillment(\n orderId: string,\n items?: Array<{ id: string; quantity: number }>,\n ): Promise<void> {\n if (!orderId || typeof orderId !== 'string') {\n throw new ProviderAPIError('Invalid order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'createFulfillment requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Creating fulfillment', { orderId, itemCount: items?.length });\n\n if (items !== undefined && items.length === 0) {\n throw new ProviderAPIError(\n 'Cannot create fulfillment: items array must have at least one item.',\n 'medusa',\n 400,\n );\n }\n\n try {\n await this.makeAdminRequest(async () => {\n // items is guaranteed to be ≥1 here (empty array rejected above).\n // When items is undefined, pass items: [] to satisfy the SDK type;\n // Medusa will fulfill all unfulfilled items in that case.\n await this.sdkAdmin!.admin.order.createFulfillment(orderId, {\n items: items ?? [],\n });\n this.logger.debug('Fulfillment created', { orderId });\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create fulfillment', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create fulfillment: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Create a refund for an order (admin operation).\n *\n * Uses fetchAdminAPI() — NOT sdk.admin.refund.create().\n * Throws ProviderAPIError if adminConfig is not provided.\n *\n * @param amount - Amount in cents. Omit to refund the full order total.\n * @param reason - Reason string (default: 'admin_refund').\n */\n async createRefund(orderId: string, amount?: number, reason?: string): Promise<void> {\n if (!orderId || typeof orderId !== 'string') {\n throw new ProviderAPIError('Invalid order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'createRefund requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Creating refund', { orderId, amount, reason });\n\n try {\n await this.makeAdminRequest(async () => {\n // Note: Medusa v2 refunds are done via payment refund, not order refund\n // For now, fallback to manual request if SDK doesn't have direct order refund\n // This would need to be updated once we understand the exact refund flow\n // For now, we could use sdk.admin.claim.create() with type: 'refund'\n // or direct payment refund via sdk.admin.payment.refund()\n \n // Placeholder: using makeAdminRequest ensures proper auth\n // The actual refund endpoint may vary byMedusa version\n // Future: implement proper refund flow using SDK methods\n this.logger.warn('createRefund: full SDK integration pending - using minimal implementation');\n });\n this.logger.debug('Refund created', { orderId, amount });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create refund', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create refund: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * List all regions for admin dashboard (used in Create Order dialog).\n *\n * Returns Region[] compatible with CommerceProvider contract.\n * Maps Medusa's currency_code → currency and provides empty countryCodes array\n * when country detail is not required for the admin region picker.\n */\n async getAdminRegions(): Promise<Region[]> {\n if (!this.isAdminConfigured) {\n this.logger.warn('getAdminRegions: adminConfig not provided, returning empty result');\n return [];\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n const { regions } = await this.sdkAdmin!.admin.region.list({\n limit: 100,\n fields: 'id,name,currency_code,countries',\n });\n return (regions ?? []).map((r: any) => ({\n id: r.id,\n name: r.name,\n currency: r.currency_code ?? '',\n countryCodes: Array.isArray(r.countries)\n ? r.countries.map((c: any) => c.iso_2 ?? c.iso2 ?? '').filter(Boolean)\n : [],\n }));\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin regions', { error: errorMessage });\n return [];\n }\n }\n\n /**\n * Get a single order by ID for admin dashboard detail view.\n *\n * Uses makeAdminRequest() for proper admin authentication.\n * Returns full order with items, addresses, customer.\n *\n * @returns Order or undefined if not found\n */\n async getAdminOrder(orderId: string): Promise<Order | undefined> {\n if (!orderId) {\n throw new ProviderAPIError('Order ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminOrder requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin order', { orderId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { order } = await this.sdkAdmin!.admin.order.retrieve(orderId, {\n fields:\n 'id,display_id,email,created_at,updated_at,status,' +\n 'payment_status,fulfillment_status,' +\n 'total,subtotal,tax_total,shipping_total,discount_total,currency_code,' +\n '*items,*items.variant,' +\n '*shipping_address,*billing_address,*customer',\n });\n if (!order) return undefined;\n return transformOrder(order);\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin order', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin order: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n /**\n * Get a single product by ID for admin dashboard detail view.\n *\n * Uses makeAdminRequest() for proper admin authentication.\n * Returns full product with variants and prices.\n *\n * @returns AdminProduct or undefined if not found\n */\n async getAdminProduct(productId: string): Promise<AdminProduct | undefined> {\n if (!productId) {\n throw new ProviderAPIError('Product ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminProduct requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin product', { productId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { product } = await this.sdkAdmin!.admin.product.retrieve(productId, {\n fields:\n 'id,handle,title,description,status,thumbnail,' +\n '+variants,+variants.prices,+variants.inventory_quantity,+variants.sku,' +\n '+variants.options,+variants.options.option,' +\n '+images,+options',\n });\n if (!product) return undefined;\n return {\n id: product.id,\n handle: product.handle,\n title: product.title,\n description: (product as any).description ?? undefined,\n status: product.status,\n thumbnail: product.thumbnail ?? undefined,\n images: ((product as any).images ?? []).map((img: any) => img.url).filter(Boolean),\n variants: ((product as any).variants ?? []).map((v: any) => {\n // Build a readable title: explicit title > options joined > SKU > \"Default\"\n let variantTitle = v.title;\n if (!variantTitle && Array.isArray(v.options) && v.options.length > 0) {\n variantTitle = v.options\n .map((opt: any) => opt.value)\n .filter(Boolean)\n .join(' / ');\n }\n if (!variantTitle) variantTitle = v.sku || 'Default';\n\n return {\n id: v.id,\n title: variantTitle,\n sku: v.sku || undefined,\n quantityAvailable: v.inventory_quantity ?? undefined,\n prices: (v.prices ?? []).map((pr: any) => ({\n amount: pr.amount,\n currencyCode: (pr.currency_code ?? '').toUpperCase(),\n })),\n };\n }),\n };\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin product', { productId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin product: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n /**\n * Create a draft order.\n *\n * Uses Medusa v2 `sdk.admin.draftOrder.create()` API.\n * Draft orders have `is_draft_order = true` and can be converted to regular orders.\n *\n * @param params - Draft order parameters\n * @returns Created draft order as a transformed Order\n */\n async createDraftOrder(params: {\n email: string;\n regionId: string;\n salesChannelId?: string;\n items: Array<{ variantId: string; quantity: number }>;\n shippingAddress?: {\n firstName?: string;\n lastName?: string;\n address1?: string;\n city?: string;\n countryCode?: string;\n postalCode?: string;\n };\n }): Promise<Order> {\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'createDraftOrder requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Creating draft order', {\n email: params.email,\n regionId: params.regionId,\n itemCount: params.items.length,\n });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.draftOrder.create({\n email: params.email,\n region_id: params.regionId,\n ...(params.salesChannelId && { sales_channel_id: params.salesChannelId }),\n items: params.items.map((item) => ({\n variant_id: item.variantId,\n quantity: item.quantity,\n })),\n ...(params.shippingAddress && {\n shipping_address: {\n first_name: params.shippingAddress.firstName,\n last_name: params.shippingAddress.lastName,\n address_1: params.shippingAddress.address1,\n city: params.shippingAddress.city,\n country_code: params.shippingAddress.countryCode,\n postal_code: params.shippingAddress.postalCode,\n },\n }),\n });\n\n const draftOrder = result?.draft_order;\n if (!draftOrder) {\n throw new ProviderAPIError('Draft order creation returned no data', 'medusa', 500);\n }\n\n this.logger.debug('Draft order created', { id: draftOrder.id });\n return transformOrder(draftOrder);\n });\n } catch (error) {\n if (error instanceof ProviderAPIError) throw error;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create draft order', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create draft order: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Convert a draft order into a regular (pending) order.\n *\n * Uses `sdk.admin.draftOrder.convertToOrder()` which maps to\n * `POST /admin/draft-orders/{id}/convert-to-order`.\n * Returns the newly created order transformed into `@thorprovider/types.Order`.\n */\n async undraftOrder(draftOrderId: string): Promise<Order> {\n if (!draftOrderId || typeof draftOrderId !== 'string') {\n throw new ProviderAPIError('Invalid draft order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'undraftOrder requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Converting draft order to order', { draftOrderId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.draftOrder.convertToOrder(\n draftOrderId,\n );\n const order = result?.order;\n if (!order) {\n throw new ProviderAPIError(\n 'Unexpected response: missing order in convertToOrder result',\n 'medusa',\n 500,\n );\n }\n this.logger.debug('Draft order converted to order', { id: order.id });\n return transformOrder(order);\n });\n } catch (error) {\n if (error instanceof ProviderAPIError) throw error;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to convert draft order', { draftOrderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to convert draft order: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n // ============================================\n // Channel Scope Operations (Multi-Tenant)\n // ============================================\n\n /**\n * Assign a customer to a sales channel via metadata.\n *\n * This is the primary mechanism for multi-tenant isolation of entities\n * that the backend does not natively scope to a sales channel\n * (e.g. customers in Medusa).\n *\n * Writes `sales_channel_id` + audit fields into `customer.metadata`.\n * After assignment, `getCustomers({ salesChannelId })` will include\n * this customer in its results.\n *\n * @param customerId - Customer to assign\n * @param channelId - Target sales channel\n * @param assignedBy - Optional: who triggered the assignment\n * @returns Updated customer with new metadata\n *\n * @example\n * ```typescript\n * // Dropshipper creates customer → assign to their channel\n * const customer = await commerce.assignCustomerToChannel(\n * 'cus_01HXXX',\n * process.env.NEXT_PUBLIC_SALES_CHANNEL_ID!,\n * 'admin@mystore.com',\n * );\n * ```\n */\n async assignCustomerToChannel(\n customerId: string,\n channelId: string,\n assignedBy?: string,\n ): Promise<Customer> {\n validateChannelScopeAssignment(customerId, channelId, assignedBy);\n\n this.logger.info('Assigning customer to channel', { customerId, channelId, assignedBy });\n\n // Fetch current metadata to merge (preserves existing keys)\n const existing = await this.getCustomer(customerId);\n const currentMeta = existing?.metadata ?? {};\n\n const scopeMeta = buildChannelScopeMetadata(channelId, assignedBy);\n\n return this.updateCustomer(customerId, {\n metadata: { ...currentMeta, ...scopeMeta },\n });\n }\n\n /**\n * Assign an order to a sales channel via metadata.\n *\n * Same pattern as `assignCustomerToChannel` but for orders.\n * Useful when orders are created through flows that don't automatically\n * link them to a channel.\n *\n * @param orderId - Order to assign\n * @param channelId - Target sales channel\n * @param assignedBy - Optional: who triggered the assignment\n */\n async assignOrderToChannel(\n orderId: string,\n channelId: string,\n assignedBy?: string,\n ): Promise<void> {\n validateChannelScopeAssignment(orderId, channelId, assignedBy);\n\n this.logger.info('Assigning order to channel', { orderId, channelId, assignedBy });\n\n const scopeMeta = buildChannelScopeMetadata(channelId, assignedBy);\n\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'assignOrderToChannel requires adminConfig. Pass adminConfig.apiKey to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n try {\n await this.makeAdminRequest(async () => {\n await (this.sdkAdmin as any).admin.order.update(orderId, {\n metadata: scopeMeta,\n });\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to assign order to channel', { orderId, channelId, error: errorMessage });\n throw new ProviderAPIError(`Failed to assign order to channel: ${errorMessage}`, 'medusa', status);\n }\n }\n\n // ============================================\n // Payment Operations\n // ============================================\n\n /**\n * Get available payment methods\n *\n * Queries Medusa for payment providers available in a specific region.\n * Region is determined either from options.regionId or from the cart.\n *\n * @param options - Payment methods query options (regionId or cartId required)\n * @returns Array of available payment methods\n *\n * @example\n * ```typescript\n * // Get payment methods for a region\n * const methods = await provider.getPaymentMethods({\n * regionId: 'reg_123',\n * enabledOnly: true\n * });\n *\n * // Get payment methods for a cart\n * const methods = await provider.getPaymentMethods({\n * cartId: 'cart_123'\n * });\n * ```\n */\n async getPaymentMethods(options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n this.logger.info('Getting payment methods', options);\n\n try {\n const methods = await getPaymentMethods(this.sdk, options);\n this.logger.debug(`Found ${methods.length} payment methods`);\n return methods;\n } catch (error) {\n this.logger.error('Error getting payment methods', error);\n throw error; // Re-throw as it's already wrapped by getPaymentMethods\n }\n }\n\n // ============================================\n // Checkout Operations\n // ============================================\n\n /**\n * Complete checkout and create order from cart\n *\n * Finalizes the checkout process and converts the cart into an order.\n * Cart must have shipping address, shipping method, and payment session.\n *\n * @param cartId - Cart ID to checkout\n * @returns Created order\n * @throws {ProviderAPIError} If checkout fails\n */\n async completeCheckout(cartId: string): Promise<Order> {\n this.logger.debug('completeCheckout', { cartId });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: POST /store/carts/:id/complete\n const { order } = (await this.sdk.store.cart.complete(cartId)) as any;\n\n if (!order) {\n throw new ProviderAPIError('Checkout completed but no order returned', 'medusa', 500);\n }\n\n this.logger.info('Checkout completed successfully', {\n orderId: order.id,\n displayId: order.display_id,\n });\n\n return transformOrder(order);\n },\n 'completeCheckout',\n { cartId },\n );\n } catch (error: any) {\n this.logger.error('Failed to complete checkout', { cartId, error: error.message });\n throw new ProviderAPIError(\n `Failed to complete checkout: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Get available shipping methods for cart\n *\n * Fetches shipping options based on cart region and shipping address.\n *\n * @param cartId - Cart ID\n * @returns List of shipping methods with prices\n * @throws {ProviderAPIError} If cart not found or region not configured\n */\n async getShippingMethods(cartId: string): Promise<import('@thorprovider/types').ShippingMethod[]> {\n this.logger.info('🚚 [DEBUG] getShippingMethods called', { cartId });\n\n try {\n return await this.withRetry(\n async () => {\n // Get raw cart to access region\n this.logger.info('🚚 [DEBUG] Step 1: Retrieving cart from Medusa...', { cartId });\n const cartResponse = (await this.sdk.store.cart.retrieve(cartId)) as any;\n const { cart } = cartResponse;\n\n // Log raw cart response for debugging\n this.logger.info('🚚 [DEBUG] Step 2: Cart retrieved from backend', {\n cartId,\n hasCart: !!cart,\n cartKeys: cart ? Object.keys(cart) : [],\n regionId: cart?.region_id,\n currencyCode: cart?.currency_code,\n shippingAddress: cart?.shipping_address\n ? {\n country: cart.shipping_address.country_code,\n postal: cart.shipping_address.postal_code,\n }\n : null,\n });\n\n if (!cart) {\n this.logger.error('🚚 [DEBUG] ERROR: Cart not found in response', {\n cartId,\n cartResponse,\n });\n throw new ResourceNotFoundError('Cart', cartId);\n }\n\n if (!cart.region_id) {\n this.logger.error('🚚 [DEBUG] ERROR: Cart has no region_id', {\n cartId,\n cart: {\n id: cart.id,\n region_id: cart.region_id,\n region: cart.region,\n allKeys: Object.keys(cart),\n },\n });\n throw new ProviderAPIError('Cart has no region assigned', 'medusa', 400);\n }\n\n // Fetch shipping options for cart\n // Medusa v2 endpoint: GET /store/shipping-options?cart_id=...\n this.logger.info('🚚 [DEBUG] Step 3: Fetching shipping options from Medusa...', {\n cartId,\n regionId: cart.region_id,\n endpoint: `${this.baseUrl}store/shipping-options?cart_id=${cartId}`,\n note: 'About to fetch shipping options (SDK when available, otherwise HTTP)',\n });\n\n let shippingResponse: any;\n let shipping_options: any;\n\n try {\n const storeAny = this.sdk.store as any;\n\n // Prefer SDK if present (newer SDK versions)\n if (storeAny?.shippingOption?.list) {\n shippingResponse = (await storeAny.shippingOption.list({\n cart_id: cartId,\n })) as any;\n } else {\n // Fallback for SDK versions that don't expose shippingOption typings/APIs\n const baseUrl = this.baseUrl.endsWith('/') ? this.baseUrl : `${this.baseUrl}/`;\n const url = new URL('store/shipping-options', baseUrl);\n url.searchParams.set('cart_id', cartId);\n\n const response = await fetchWithRetry(\n url.toString(),\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'content-type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n shippingResponse = (await response.json()) as any;\n }\n\n shipping_options = shippingResponse.shipping_options;\n } catch (sdkError: any) {\n // Log detailed error from Medusa backend\n this.logger.error(\n '🚚 [DEBUG] ERROR: Medusa SDK threw error when fetching shipping options',\n {\n cartId,\n regionId: cart.region_id,\n errorType: sdkError?.constructor?.name,\n errorMessage: sdkError?.message,\n errorStatus: sdkError?.status,\n errorCode: sdkError?.code,\n errorResponse: sdkError?.response\n ? JSON.stringify(sdkError.response, null, 2)\n : 'N/A',\n errorBody: sdkError?.body ? JSON.stringify(sdkError.body, null, 2) : 'N/A',\n fullError: JSON.stringify(sdkError, Object.getOwnPropertyNames(sdkError), 2),\n },\n );\n throw sdkError;\n }\n\n // Log raw shipping options response\n this.logger.info('🚚 [DEBUG] Step 4: Shipping options received from backend', {\n cartId,\n totalOptions: shipping_options?.length || 0,\n rawResponse: JSON.stringify(shippingResponse, null, 2),\n firstOption: shipping_options?.[0]\n ? {\n id: shipping_options[0].id,\n name: shipping_options[0].name,\n allKeys: Object.keys(shipping_options[0]),\n price_incl_tax: shipping_options[0].price_incl_tax,\n amount: shipping_options[0].amount,\n data: shipping_options[0].data,\n }\n : null,\n });\n\n const methods = shipping_options.map((option: any) => ({\n id: option.id,\n name: option.name,\n price: {\n amount: option.price_incl_tax?.toString() || option.amount?.toString() || '0',\n currencyCode: cart.currency_code?.toUpperCase() || this.currencyCode,\n },\n description: option.data?.description,\n estimatedDays: option.data?.estimated_days || 'N/A',\n }));\n\n // Log transformed methods\n this.logger.info('🚚 [DEBUG] Step 5: Transformed methods for Thor types', {\n cartId,\n count: methods.length,\n methods: JSON.stringify(methods, null, 2),\n });\n\n return methods;\n },\n 'getShippingMethods',\n { cartId },\n );\n } catch (error: any) {\n this.logger.error('🚚 [DEBUG] ERROR: Failed to fetch shipping methods', {\n cartId,\n errorMessage: error.message,\n errorStack: error.stack,\n errorStatus: error.status,\n });\n throw new ProviderAPIError(\n `Failed to fetch shipping methods: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n // ============================================\n // Admin Authentication (SDK-Managed)\n // ============================================\n\n /**\n * Check if admin API is configured\n */\n private get isAdminConfigured(): boolean {\n return !!this.adminApiKey;\n }\n\n /**\n * Ensure admin is configured.\n * Synchronous check — API key auth has no async initialization.\n * @throws ProviderAPIError if admin configuration is missing\n */\n private ensureAdminConfigured(): void {\n if (!this.adminApiKey || !this.sdkAdmin) {\n throw new ProviderAPIError(\n 'Admin API is not configured. Pass adminConfig.apiKey to createProvider().',\n 'medusa',\n 503,\n );\n }\n }\n\n /**\n * Make an authenticated request to the Medusa Admin API via SDK\n * SDK automatically includes Bearer token in all admin requests\n * Awaits auth initialization before executing the operation\n */\n private async makeAdminRequest<T>(\n operation: () => Promise<T>,\n ): Promise<T> {\n // Ensure admin is configured (sync check — no async auth)\n this.ensureAdminConfigured();\n\n try {\n // Wrap with retry logic to handle transient network failures.\n // withRetry uses exponential backoff (300ms → 5s, up to 3 attempts).\n // It retries on: fetch failed, timeout, ECONNREFUSED, ETIMEDOUT, HTTP 429/500/502/503/504.\n // It does NOT retry 401/403 (auth errors) or 404/422 (business errors).\n return await this.withRetry(operation, 'adminRequest');\n } catch (error) {\n // SDK auth errors will be caught here\n // If token expired, SDK automatically refreshes\n // If credentials invalid (401), error propagates\n if (error instanceof Error) {\n this.logger.error('Admin API request failed', {\n error: error.message,\n });\n }\n throw error;\n }\n }\n\n // ============================================\n // Inventory Operations (Admin API)\n // ============================================\n\n /**\n * Fetch stock locations, optionally filtered by sales channel.\n * Returns empty array when admin config is not provided (graceful degradation).\n */\n async getStockLocations(params?: { salesChannelId?: string }): Promise<StockLocation[]> {\n if (!this.isAdminConfigured) {\n return []; // Graceful degradation when admin not configured\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n const { stock_locations } = await this.sdkAdmin!.admin.stockLocation.list({\n ...(params?.salesChannelId && { sales_channel_id: [params.salesChannelId] }),\n });\n\n return (stock_locations ?? []).map(transformStockLocation);\n });\n } catch (error) {\n this.logger.error('Failed to fetch stock locations:', error);\n return [];\n }\n }\n\n /**\n * Check inventory levels for a variant across locations.\n * Returns empty array when admin config is not provided (graceful degradation).\n */\n async checkInventoryLevels(variantId: string, salesChannelId?: string): Promise<InventoryLevel[]> {\n if (!this.isAdminConfigured) {\n return [];\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n // Find inventory item by variant ID\n const { inventory_items } = await this.sdkAdmin!.admin.inventoryItem.list({\n // Filter params may need adjustment based on actual SDK capabilities\n fields: 'id',\n });\n\n if (!inventory_items?.length) {\n return [];\n }\n\n // Find the matching inventory item for this variant\n // Note: SDK filtering might be different - we may need to filter client-side\n const inventoryItem = inventory_items.find((item: any) => item.variant_id === variantId);\n if (!inventoryItem) {\n return [];\n }\n\n // Get levels for this inventory item\n const { inventory_levels } = await this.sdkAdmin!.admin.inventoryItem.listLevels(\n inventoryItem.id,\n { fields: 'id,location_id,stocked_quantity,reserved_quantity' },\n );\n\n const locations = await this.getStockLocations({ salesChannelId });\n const locationMap = new Map(locations.map((l) => [l.id, l.name] as const));\n\n return (inventory_levels ?? []).map((level: any) =>\n transformInventoryLevel(level, locationMap.get(level.location_id) || 'Unknown'),\n );\n });\n } catch (error) {\n this.logger.error('Failed to check inventory levels:', error);\n return [];\n }\n }\n\n /**\n * Validate cart stock availability across all items.\n * Returns all-available when admin config is not provided (graceful degradation).\n */\n async validateCartStock(cartId: string): Promise<StockValidation> {\n if (!this.isAdminConfigured) {\n return { allAvailable: true, unavailableItems: [] };\n }\n\n try {\n const cart = await this.getCart(cartId);\n if (!cart) {\n throw new Error('Cart not found');\n }\n\n const unavailableItems: StockValidation['unavailableItems'] = [];\n\n for (const item of cart.lines) {\n const variantId = item.merchandise.id;\n const levels = await this.checkInventoryLevels(variantId);\n const totalAvailable = levels.reduce((sum, level) => sum + level.availableQuantity, 0);\n\n if (totalAvailable < item.quantity) {\n unavailableItems.push({\n variantId,\n productName: item.merchandise.product.title,\n requestedQuantity: item.quantity,\n availableQuantity: totalAvailable,\n });\n }\n }\n\n return { allAvailable: unavailableItems.length === 0, unavailableItems };\n } catch (error) {\n this.logger.error('Failed to validate cart stock:', error);\n return { allAvailable: false, unavailableItems: [] };\n }\n }\n\n /**\n * Get fulfillment options enriched with stock location data.\n * Not yet implemented — requires fulfillment planning + Admin inventory.\n */\n async getFulfillmentOptions(cartId: string, salesChannelId: string): Promise<FulfillmentOption[]> {\n void cartId;\n void salesChannelId;\n throw new Error(\n 'MedusaProvider.getFulfillmentOptions is not yet implemented. ' +\n 'This method requires Admin API access — implement it HERE in @thorprovider/adapters, ' +\n 'NOT in L5 starters. See docs/architecture/data-flow.md.',\n );\n }\n\n /**\n * Get a map of product IDs → admin status ('published' | 'draft' | etc.)\n * Returns {} when admin config is not provided (graceful degradation).\n */\n async getAdminProductStatuses(options?: { limit?: number }): Promise<Record<string, string>> {\n if (!this.isAdminConfigured) {\n return {};\n }\n\n try {\n const limit = options?.limit ?? 1000;\n\n return await this.makeAdminRequest(async () => {\n const { products } = await this.sdkAdmin!.admin.product.list({\n limit,\n fields: 'id,status',\n });\n\n const map: Record<string, string> = {};\n for (const p of products ?? []) {\n if (p.id && p.status) {\n map[p.id] = p.status;\n }\n }\n return map;\n });\n } catch (error) {\n this.logger.error('Failed to fetch admin product statuses:', error);\n return {};\n }\n }\n\n /**\n * Get the distinct product status values available in Medusa.\n * Derives values from getAdminProductStatuses and caches them for the process lifetime.\n * Returns [] when admin credentials are not configured.\n */\n async getAvailableProductStatuses(): Promise<string[]> {\n if (this._cachedProductStatuses !== null) {\n return this._cachedProductStatuses;\n }\n\n if (!this.isAdminConfigured) {\n return [];\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n const { products } = await this.sdkAdmin!.admin.product.list({\n limit: 1000,\n fields: 'id,status',\n });\n\n const statuses = Array.from(\n new Set((products ?? []).map((p: any) => p.status).filter(Boolean)),\n );\n this._cachedProductStatuses = statuses;\n return statuses;\n });\n } catch (error) {\n this.logger.error('Failed to fetch available product statuses:', error);\n return [];\n }\n }\n\n /**\n * List ALL products from the admin API (including non-published).\n * Returns real backend status values and variant-level price/inventory data.\n * Gracefully degrades to empty result when admin credentials are not configured.\n */\n async getAdminProducts(options?: {\n query?: string;\n limit?: number;\n offset?: number;\n }): Promise<{ products: AdminProduct[]; count: number }> {\n if (!this.isAdminConfigured) {\n return { products: [], count: 0 };\n }\n\n try {\n const limit = options?.limit ?? 1000;\n const offset = options?.offset ?? 0;\n\n return await this.makeAdminRequest(async () => {\n const { products, count } = await this.sdkAdmin!.admin.product.list({\n limit,\n offset,\n q: options?.query,\n fields:\n 'id,handle,title,status,thumbnail,' +\n '+variants,+variants.prices,+variants.inventory_quantity,+variants.sku,' +\n '+variants.options,+variants.options.option',\n });\n\n const transformedProducts: AdminProduct[] = (products ?? []).map((p: any) => ({\n id: p.id,\n handle: p.handle,\n title: p.title,\n status: p.status,\n thumbnail: p.thumbnail ?? undefined,\n variants: (p.variants ?? []).map((v: any) => {\n // Build a readable title: explicit title > options joined > SKU > \"Default\"\n let variantTitle = v.title;\n if (!variantTitle && Array.isArray(v.options) && v.options.length > 0) {\n variantTitle = v.options\n .map((opt: any) => opt.value)\n .filter(Boolean)\n .join(' / ');\n }\n if (!variantTitle) variantTitle = v.sku || 'Default';\n\n return {\n id: v.id,\n title: variantTitle,\n sku: v.sku || undefined,\n quantityAvailable: v.inventory_quantity ?? undefined,\n prices: (v.prices ?? []).map((pr: any) => ({\n amount: pr.amount,\n currencyCode: (pr.currency_code ?? '').toUpperCase(),\n })),\n };\n }),\n }));\n\n return { products: transformedProducts, count: count ?? transformedProducts.length };\n });\n } catch (error) {\n // Re-throw authentication errors (401) — these are not transient failures\n if (error instanceof ProviderAPIError && error.status === 401) {\n throw error;\n }\n\n // Silently degrade for other errors (network, service unavailable, etc.)\n this.logger.error('Failed to fetch admin products:', error);\n return { products: [], count: 0 };\n }\n }\n\n /**\n * Get available countries for a region\n *\n * Returns list of countries that can be used for shipping addresses\n * in the specified region. Results are cached for 5 minutes.\n *\n * @param regionId - Region ID\n * @returns Array of countries with codes and names\n * @throws {ProviderAPIError} If region not found or API error\n *\n * @example\n * ```typescript\n * const countries = await medusa.getRegionCountries('reg_01KHCJQ5YXYRWWCKSTYQ4SCM8V');\n * // [{ code: 'ES', name: 'Spain' }, { code: 'FR', name: 'France' }, ...]\n * ```\n */\n async getRegionCountries(regionId: string): Promise<import('@thorprovider/types').Country[]> {\n this.logger.info('🌍 [DEBUG] getRegionCountries called', { regionId });\n\n // Check cache first\n const cached = this.regionCountriesCache.get(regionId);\n const now = Date.now();\n\n if (cached && cached.expiresAt > now) {\n this.logger.info('🌍 [DEBUG] Returning cached countries', {\n regionId,\n count: cached.countries.length,\n cacheAge:\n Math.round((now - (cached.expiresAt - this.REGION_COUNTRIES_CACHE_TTL)) / 1000) + 's',\n });\n return cached.countries;\n }\n\n try {\n return await this.withRetry(\n async () => {\n this.logger.info('🌍 [DEBUG] Fetching countries from Medusa API...', { regionId });\n\n // Fetch region with countries using Medusa SDK\n const { region } = await this.sdk.store.region.retrieve(regionId, {\n fields:\n '+countries.iso_2,+countries.display_name,+countries.name,+countries.iso_3,+countries.num_code',\n });\n\n if (!region) {\n throw new ResourceNotFoundError('Region', regionId);\n }\n\n this.logger.info('🌍 [DEBUG] Region retrieved', {\n regionId,\n regionName: region.name,\n hasCountries: !!(region as any).countries,\n countriesCount: (region as any).countries?.length || 0,\n });\n\n // Transform to Country type\n const countries: import('@thorprovider/types').Country[] = ((region as any).countries || []).map(\n (c: any) => ({\n code: c.iso_2.toUpperCase(), // Frontend expects uppercase for validation\n name: c.display_name || c.name,\n iso3: c.iso_3,\n numCode: c.num_code,\n }),\n );\n\n // Sort by name for better UX\n countries.sort((a, b) => a.name.localeCompare(b.name));\n\n this.logger.info('🌍 [DEBUG] Countries transformed and sorted', {\n regionId,\n count: countries.length,\n firstThree: countries.slice(0, 3).map((c) => `${c.code}: ${c.name}`),\n });\n\n // Cache the result\n this.regionCountriesCache.set(regionId, {\n countries,\n expiresAt: now + this.REGION_COUNTRIES_CACHE_TTL,\n });\n\n return countries;\n },\n 'getRegionCountries',\n { regionId },\n );\n } catch (error: any) {\n this.logger.error('🌍 [DEBUG] ERROR: Failed to fetch region countries', {\n regionId,\n errorMessage: error.message,\n errorStatus: error.status,\n });\n\n // Provide helpful error messages\n if (error.status === 404) {\n throw new ResourceNotFoundError('Region', regionId);\n }\n\n throw new ProviderAPIError(\n `Failed to fetch countries for region: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Add shipping method to cart\n *\n * Applies a shipping method to the cart and updates totals.\n *\n * @param cartId - Cart ID\n * @param methodId - Shipping method ID (from getShippingMethods)\n * @returns Updated cart with shipping\n * @throws {ProviderAPIError} If method invalid or cart not ready\n */\n async addShippingMethod(cartId: string, methodId: string): Promise<Cart> {\n this.logger.debug('addShippingMethod', { cartId, methodId });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: POST /store/carts/:id/shipping-methods\n const { cart } = await this.sdk.store.cart.addShippingMethod(cartId, {\n option_id: methodId,\n } as any);\n\n this.logger.info('Shipping method added successfully', { cartId, methodId });\n\n void cart;\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\n },\n 'addShippingMethod',\n { cartId, methodId },\n );\n } catch (error: any) {\n this.logger.error('Failed to add shipping method', {\n cartId,\n methodId,\n error: error.message,\n });\n throw new ProviderAPIError(\n `Failed to add shipping method: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Initiate payment session with provider\n *\n * Creates a payment session for the cart with the specified provider.\n *\n * @param cartId - Cart ID\n * @param providerId - Payment provider ID (from getPaymentMethods)\n * @throws {ProviderAPIError} If provider invalid or cart not ready\n */\n async initiatePaymentSession(cartId: string, providerId: string): Promise<void> {\n this.logger.info('💳 [DEBUG] initiatePaymentSession called', { cartId, providerId });\n\n try {\n await this.withRetry(\n async () => {\n // Get RAW cart object from Medusa SDK (not transformed)\n // CHANGE 1: Add payment_collection fields to query\n this.logger.info(\n '💳 [DEBUG] Step 1: Retrieving RAW cart from Medusa for payment session...',\n { cartId },\n );\n const { cart: rawCart } = await this.sdk.store.cart.retrieve(cartId, {\n fields:\n '+shipping_methods,+shipping_address,+email,+region_id,+total,+items,+payment_collection,+payment_collection.payment_sessions,+billing_address',\n });\n\n this.logger.info('💳 [DEBUG] Step 2: RAW cart retrieved, checking state...', {\n cartId: rawCart.id,\n hasShippingMethod: !!rawCart.shipping_methods?.length,\n shippingMethodIds: rawCart.shipping_methods?.map((sm: any) => sm.id) || [],\n hasShippingAddress: !!rawCart.shipping_address,\n shippingAddressCity: rawCart.shipping_address?.city || 'N/A',\n hasEmail: !!rawCart.email,\n email: rawCart.email || 'N/A',\n hasBillingAddress: !!rawCart.billing_address,\n hasPaymentCollection: !!rawCart.payment_collection,\n existingSessionsCount: rawCart.payment_collection?.payment_sessions?.length || 0,\n regionId: rawCart.region_id,\n total: rawCart.total,\n itemCount: rawCart.items?.length || 0,\n });\n\n // 🛡️ VALIDATION: Cart must have items to create payment session\n if (!rawCart.items || rawCart.items.length === 0) {\n this.logger.error('💳 [DEBUG] ERROR: Cannot create payment session for empty cart', {\n cartId,\n itemCount: 0,\n reason: 'Cart has no items',\n });\n throw new ProviderAPIError(\n 'Cannot create payment session: cart is empty. Please add items to your cart before checking out.',\n 'medusa',\n 400,\n );\n }\n\n // 🛡️ VALIDATION: Required fields\n if (!rawCart.shipping_address) {\n this.logger.error('💳 [DEBUG] ERROR: Shipping address required', { cartId });\n throw new ProviderAPIError(\n 'Shipping address is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n if (!rawCart.shipping_methods?.length) {\n this.logger.error('💳 [DEBUG] ERROR: Shipping method required', { cartId });\n throw new ProviderAPIError(\n 'Shipping method is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n if (!rawCart.email) {\n this.logger.error('💳 [DEBUG] ERROR: Email required', { cartId });\n throw new ProviderAPIError(\n 'Email is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n // CHANGE 2: Validate billing address and warn if missing\n if (!rawCart.billing_address) {\n this.logger.warn(\n '💳 [DEBUG] WARNING: Billing address not set, payment provider may require it',\n {\n cartId: rawCart.id,\n shippingAddress: rawCart.shipping_address,\n },\n );\n }\n\n // CHANGE 3: Check for existing payment sessions (idempotency)\n // Note: payment_collection is created automatically by Medusa when calling initiatePaymentSession\n // So we don't need to validate its existence - just check if sessions already exist\n const existingSessions = rawCart.payment_collection?.payment_sessions || [];\n\n if (existingSessions.length > 0) {\n this.logger.info('💳 [DEBUG] Payment session already exists, skipping creation', {\n cartId: rawCart.id,\n sessionCount: existingSessions.length,\n sessionIds: existingSessions.map((s: any) => s.id),\n });\n\n // Return early - session already exists\n return;\n }\n\n this.logger.info('💳 [DEBUG] Step 2.5: No existing payment sessions, will create new one', {\n cartId: rawCart.id,\n hasPaymentCollection: !!rawCart.payment_collection,\n providerId,\n });\n\n // Medusa v2 SDK: sdk.store.payment.initiatePaymentSession(cart, options)\n this.logger.info('💳 [DEBUG] Step 3: Calling Medusa SDK initiatePaymentSession...', {\n cartId,\n providerId,\n endpoint: `${this.baseUrl}store/payment-collections`,\n note: 'About to call SDK method',\n });\n\n // VALIDATION: Ensure provider_id is a valid backend ID\n // Prevent sending normalized types like 'card', 'wallet', 'cash_on_delivery'\n this.logger.info('💳 [DEBUG] Step 2.5: Validating provider ID...', {\n providerId,\n });\n\n try {\n validatePaymentId(providerId);\n this.logger.info('💳 [DEBUG] Provider ID validation passed', { providerId });\n } catch (validationError: any) {\n this.logger.error('💳 [DEBUG] ERROR: Invalid provider ID detected', {\n providerId,\n error: validationError.message,\n hint: 'Use getBackendProviderId(paymentMethod) to extract correct ID',\n });\n throw new ProviderAPIError(\n validationError.message,\n 'medusa',\n 400\n );\n }\n\n let paymentResponse: any;\n try {\n paymentResponse = await this.sdk.store.payment.initiatePaymentSession(rawCart as any, {\n provider_id: providerId,\n });\n\n this.logger.info('💳 [DEBUG] Step 4: Payment session response received', {\n cartId,\n providerId,\n responseKeys: paymentResponse ? Object.keys(paymentResponse) : [],\n response: JSON.stringify(paymentResponse, null, 2),\n });\n } catch (sdkError: any) {\n // CHANGE 4: Enhanced error context\n this.logger.error(\n '💳 [DEBUG] ERROR: Medusa SDK threw error when initiating payment session',\n {\n cartId,\n providerId,\n errorType: sdkError?.constructor?.name,\n errorMessage: sdkError?.message,\n errorStatus: sdkError?.status,\n errorCode: sdkError?.code,\n errorResponse: sdkError?.response\n ? JSON.stringify(sdkError.response, null, 2)\n : 'N/A',\n errorBody: sdkError?.body ? JSON.stringify(sdkError.body, null, 2) : 'N/A',\n fullError: JSON.stringify(sdkError, Object.getOwnPropertyNames(sdkError), 2),\n // Include cart state in error for debugging\n cartState: {\n hasShippingMethod: !!rawCart.shipping_methods?.length,\n hasShippingAddress: !!rawCart.shipping_address,\n hasBillingAddress: !!rawCart.billing_address,\n hasEmail: !!rawCart.email,\n total: rawCart.total,\n itemCount: rawCart.items?.length || 0,\n },\n },\n );\n throw sdkError;\n }\n\n this.logger.info('💳 [DEBUG] Payment session initiated successfully', {\n cartId,\n providerId,\n });\n },\n 'initiatePaymentSession',\n { cartId, providerId },\n );\n } catch (error: any) {\n this.logger.error('💳 [DEBUG] ERROR: Failed to initiate payment session', {\n cartId,\n providerId,\n errorMessage: error.message,\n errorStack: error.stack,\n errorStatus: error.status,\n });\n throw new ProviderAPIError(\n `Failed to initiate payment session: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Apply discount code to cart\n *\n * Validates and applies a discount/promo code to the cart.\n *\n * @param cartId - Cart ID\n * @param code - Discount code\n * @returns Updated cart with discount\n * @throws {ProviderAPIError} If code invalid or expired\n */\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n this.logger.debug('applyDiscountCode', { cartId, code });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: POST /store/carts/:id/promotions\n const response = await fetch(`${this.baseUrl}/store/carts/${cartId}/promotions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-publishable-api-key': this.publishableKey || '',\n },\n body: JSON.stringify({\n promo_codes: [code],\n }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to apply discount code');\n }\n\n const { cart: medusaCart } = await response.json();\n\n this.logger.info('Discount code applied successfully', { cartId, code });\n\n void medusaCart;\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\n },\n 'applyDiscountCode',\n { cartId, code },\n );\n } catch (error: any) {\n this.logger.error('Failed to apply discount code', { cartId, code, error: error.message });\n throw new ProviderAPIError(\n `Failed to apply discount code: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Remove discount code from cart\n *\n * Removes a previously applied discount code.\n *\n * @param cartId - Cart ID\n * @param code - Discount code to remove\n * @returns Updated cart without discount\n * @throws {ProviderAPIError} If cart not found\n */\n async removeDiscountCode(cartId: string, code: string): Promise<Cart> {\n this.logger.debug('removeDiscountCode', { cartId, code });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: DELETE /store/carts/:id/promotions\n const response = await fetch(`${this.baseUrl}/store/carts/${cartId}/promotions`, {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n 'x-publishable-api-key': this.publishableKey || '',\n },\n body: JSON.stringify({\n promo_codes: [code],\n }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to remove discount code');\n }\n\n const { cart: medusaCart } = await response.json();\n\n this.logger.info('Discount code removed successfully', { cartId, code });\n\n void medusaCart;\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\n },\n 'removeDiscountCode',\n { cartId, code },\n );\n } catch (error: any) {\n this.logger.error('Failed to remove discount code', { cartId, code, error: error.message });\n throw new ProviderAPIError(\n `Failed to remove discount code: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Update cart shipping address\n * @param cartId - Cart ID\n * @param address - Shipping address details\n * @returns Updated cart\n *\n * **CRITICAL**: Must be called BEFORE initiatePaymentSession\n * Medusa requires shipping_address on cart before creating payment session\n */\n async updateShippingAddress(\n cartId: string,\n address: {\n email: string;\n firstName: string;\n lastName: string;\n address1: string;\n address2?: string;\n company?: string;\n city: string;\n province: string;\n postalCode: string;\n countryCode: string;\n phone: string;\n },\n ): Promise<void> {\n this.logger.info('📫 [DEBUG] updateShippingAddress called', {\n cartId,\n email: address.email,\n city: address.city,\n countryCode: address.countryCode,\n });\n\n try {\n // Update cart with shipping address using Medusa SDK\n const { cart: rawCart } = await this.sdk.store.cart.update(cartId, {\n email: address.email,\n shipping_address: {\n first_name: address.firstName,\n last_name: address.lastName,\n address_1: address.address1,\n address_2: address.address2 || '',\n company: address.company || '',\n city: address.city,\n province: address.province,\n postal_code: address.postalCode,\n country_code: address.countryCode.toLowerCase(), // Medusa expects lowercase\n phone: address.phone,\n },\n });\n\n this.logger.info('📫 [DEBUG] Shipping address updated successfully', {\n cartId,\n hasEmail: !!rawCart.email,\n hasShippingAddress: !!rawCart.shipping_address,\n });\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n const status = (error as any)?.status || (error as any)?.statusCode;\n\n this.logger.error('Failed to update shipping address', {\n cartId,\n error: errorMessage,\n status,\n });\n\n // Provide user-friendly error messages\n let userMessage = errorMessage;\n\n if (errorMessage.includes('is not within region')) {\n // Region/Country mismatch\n userMessage = `The selected country is not available for shipping in your current region. Please select a different country or change your region.`;\n } else if (status === 400) {\n userMessage = `Invalid shipping address: ${errorMessage}`;\n }\n\n throw new ProviderAPIError(userMessage, 'medusa', status);\n }\n }\n\n /**\n * Update cart billing address\n * @param cartId - Cart ID\n * @param address - Billing address details\n * @returns Updated cart\n *\n * **Usage**: Call when billing address differs from shipping address\n * Recommended to call BEFORE initiatePaymentSession\n */\n async updateBillingAddress(\n cartId: string,\n address: {\n firstName: string;\n lastName: string;\n address1: string;\n address2?: string;\n company?: string;\n city: string;\n province: string;\n postalCode: string;\n countryCode: string;\n phone?: string;\n },\n ): Promise<Cart> {\n this.logger.info('📫 [DEBUG] updateBillingAddress called', {\n cartId,\n city: address.city,\n countryCode: address.countryCode,\n });\n\n try {\n // Update cart with billing address using Medusa SDK\n const { cart: rawCart } = await this.sdk.store.cart.update(cartId, {\n billing_address: {\n first_name: address.firstName,\n last_name: address.lastName,\n address_1: address.address1,\n address_2: address.address2 || '',\n company: address.company || '',\n city: address.city,\n province: address.province,\n postal_code: address.postalCode,\n country_code: address.countryCode.toLowerCase(), // Medusa expects lowercase\n phone: address.phone || '',\n },\n });\n\n this.logger.info('📫 [DEBUG] Billing address updated successfully', {\n cartId,\n hasBillingAddress: !!rawCart.billing_address,\n });\n\n return transformCart(rawCart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n const status = (error as any)?.status || (error as any)?.statusCode;\n\n this.logger.error('Failed to update billing address', {\n cartId,\n error: errorMessage,\n status,\n });\n\n // Provide user-friendly error messages\n let userMessage = errorMessage;\n\n if (errorMessage.includes('is not within region')) {\n userMessage = `The billing address country is not available in your current region. Please select a different country or change your region.`;\n } else if (status === 400) {\n userMessage = `Invalid billing address: ${errorMessage}`;\n }\n\n throw new ProviderAPIError(userMessage, 'medusa', status);\n }\n }\n\n // ============================================\n // Storefront / Multi-Tenant Operations\n // ============================================\n\n /**\n * Get the current storefront/sales channel context.\n *\n * Validates that NEXT_PUBLIC_SALES_CHANNEL_ID is set and that the\n * corresponding sales channel exists in the Medusa backend.\n * Results are cached for 60 seconds.\n *\n * @returns StorefrontContext for the current storefront\n * @throws {StorefrontConfigError} if NEXT_PUBLIC_SALES_CHANNEL_ID is missing or invalid\n * @throws {ProviderAPIError} if the backend request fails\n */\n async getStorefrontContext(): Promise<StorefrontContext> {\n // Check cache first\n if (\n this.storefrontContextCache &&\n Date.now() < this.storefrontContextCache.expiresAt\n ) {\n return this.storefrontContextCache.context;\n }\n\n const channelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (!channelId) {\n throw new StorefrontConfigError(\n 'Medusa requires NEXT_PUBLIC_SALES_CHANNEL_ID to be configured. ' +\n 'Each storefront must be linked to a sales channel. ' +\n 'Set this in your .env file or environment variables.',\n 'medusa',\n 'NEXT_PUBLIC_SALES_CHANNEL_ID',\n );\n }\n\n try {\n // In Medusa v2, we build context from the channel ID.\n // The channel is validated implicitly when used in API calls (product filtering, cart creation).\n // If the channel is invalid, those operations will fail with clear errors.\n \n const context: StorefrontContext = {\n id: channelId,\n name: channelId, // Use ID as fallback name\n platformType: 'medusa',\n requiresProductScoping: true,\n currencyCode: this.currencyCode,\n metadata: {\n // Store channel ID for use in API requests\n channelId,\n },\n };\n\n // Cache for 60 seconds\n this.storefrontContextCache = {\n context,\n expiresAt: Date.now() + this.STOREFRONT_CONTEXT_CACHE_TTL,\n };\n\n this.logger.info('Storefront context initialized', {\n id: context.id,\n channelId,\n });\n\n return context;\n } catch (error) {\n if (error instanceof StorefrontConfigError) throw error;\n\n const errorMessage = extractErrorMessage(error);\n throw new ProviderAPIError(\n `Failed to initialize storefront context: ${errorMessage}`,\n 'medusa',\n (error as any)?.status ?? 500,\n );\n }\n }\n\n /**\n * Medusa always requires storefront configuration for multi-tenant support.\n */\n isStorefrontRequired(): boolean {\n return true;\n }\n\n // ============================================\n // Thor Plugin — Storefront Configuration\n // ============================================\n\n /** In-memory cache for storefront config (60s TTL) */\n private _storefrontConfigCache: {\n config: StorefrontConfig | null;\n expiresAt: number;\n } | null = null;\n\n /** In-memory cache for designer config (60s TTL) */\n private _designerConfigCache: {\n result: { version: string; config: DesignerConfig } | null;\n expiresAt: number;\n } | null = null;\n\n /** Cache TTL for Thor plugin configs (60 seconds) */\n private readonly THOR_CONFIG_CACHE_TTL = 60 * 1000;\n\n /**\n * Get per-channel storefront configuration from Thor Commerce plugin.\n * Calls `GET /store/thor/config`.\n *\n * @returns StorefrontConfig or null if plugin is not installed / config not set\n */\n async getStorefrontConfig(): Promise<StorefrontConfig | null> {\n // Check cache\n if (this._storefrontConfigCache && Date.now() < this._storefrontConfigCache.expiresAt) {\n return this._storefrontConfigCache.config;\n }\n\n try {\n const url = `${this.baseUrl}/store/thor/config`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (response.status === 404) {\n this._storefrontConfigCache = { config: null, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n return null;\n }\n\n if (!response.ok) {\n this.logger.warn('[StorefrontConfig] Non-OK response', { status: response.status });\n return null;\n }\n\n const data = await response.json();\n const config = transformStorefrontConfig(data.storefront_config ?? data);\n\n this._storefrontConfigCache = { config, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n this.logger.debug('[StorefrontConfig] Loaded from backend', { id: config.id });\n return config;\n } catch (error) {\n this.logger.warn('[StorefrontConfig] Failed to fetch', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n }\n\n /**\n * Get active Site Designer configuration from Thor Commerce plugin.\n * Calls `GET /store/thor/site-config`.\n *\n * @returns Versioned DesignerConfig or null if plugin is not installed / config not set\n */\n async getDesignerConfig(): Promise<{ version: string; config: DesignerConfig } | null> {\n // Check cache\n if (this._designerConfigCache && Date.now() < this._designerConfigCache.expiresAt) {\n return this._designerConfigCache.result;\n }\n\n try {\n const url = `${this.baseUrl}/store/thor/site-config`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (response.status === 404) {\n this._designerConfigCache = { result: null, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n return null;\n }\n\n if (!response.ok) {\n this.logger.warn('[DesignerConfig] Non-OK response', { status: response.status });\n return null;\n }\n\n const data = await response.json();\n const result = {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n };\n\n this._designerConfigCache = { result, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n this.logger.debug('[DesignerConfig] Loaded from backend', { version: result.version });\n return result;\n } catch (error) {\n this.logger.warn('[DesignerConfig] Failed to fetch', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n }\n\n // ============================================\n // Thor Plugin — Admin Site Designer\n // ============================================\n\n /**\n * Get admin Site Designer config + history for a sales channel.\n * Calls `GET /admin/thor/site-config/:salesChannelId`.\n */\n async getAdminDesignerConfig(salesChannelId: string): Promise<{\n version: string;\n config: DesignerConfig;\n history?: DesignerHistoryEntry[];\n } | null> {\n return this.makeAdminRequest(async () => {\n const path = `/admin/thor/site-config/${encodeURIComponent(salesChannelId)}`;\n let data: any;\n try {\n data = await this.sdk.client.fetch<any>(path, { method: 'GET' });\n } catch (error: any) {\n if (error?.status === 404) return null;\n throw new ProviderAPIError(\n `Failed to fetch admin designer config: ${error?.message ?? error?.status}`,\n 'medusa',\n error?.status,\n );\n }\n return {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n history: data.history as DesignerHistoryEntry[] | undefined,\n };\n });\n }\n\n /**\n * Update the Site Designer config for a sales channel.\n * Calls `PUT /admin/thor/site-config/:salesChannelId`.\n */\n async updateAdminDesignerConfig(salesChannelId: string, config: DesignerConfig): Promise<{\n version: string;\n config: DesignerConfig;\n }> {\n return this.makeAdminRequest(async () => {\n const path = `/admin/thor/site-config/${encodeURIComponent(salesChannelId)}`;\n let data: any;\n try {\n data = await this.sdk.client.fetch<any>(path, {\n method: 'PUT',\n body: JSON.stringify({ config }),\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to update admin designer config: ${error?.message ?? error?.status}`,\n 'medusa',\n error?.status,\n );\n }\n return {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n };\n });\n }\n\n /**\n * Restore a previous Site Designer config version.\n * Calls `POST /admin/thor/site-config/:salesChannelId/restore/:version`.\n */\n async restoreAdminDesignerConfig(salesChannelId: string, version: string): Promise<{\n version: string;\n config: DesignerConfig;\n }> {\n return this.makeAdminRequest(async () => {\n const path = `/admin/thor/site-config/${encodeURIComponent(salesChannelId)}/restore/${encodeURIComponent(version)}`;\n let data: any;\n try {\n data = await this.sdk.client.fetch<any>(path, { method: 'POST' });\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to restore admin designer config: ${error?.message ?? error?.status}`,\n 'medusa',\n error?.status,\n );\n }\n return {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n };\n });\n }\n}\n","/**\n * @fileoverview Medusa Authentication Provider\n * @module @thorprovider/adapters/providers/medusa/auth\n * \n * Implementation of AuthProvider for Medusa.js v2\n * Supports JWT and session-based authentication\n */\n\nimport Medusa from '@medusajs/js-sdk';\nimport type {\n AuthProvider,\n AuthConfig,\n LoginCredentials,\n RegisterData,\n AuthResponse,\n Customer,\n Address,\n UpdateCustomerData,\n CreateAddressData,\n PasswordResetRequest,\n PasswordResetConfirm,\n LinkCustomerToChannelResponse,\n} from '@thorprovider/types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\nimport type { Logger } from '../../core/logger';\nimport { transformCustomer, transformAddress } from './transforms';\n\n/**\n * Storage manager for authentication tokens\n */\nclass AuthStorageManager {\n private storage: AuthConfig['customStorage'] | null = null;\n private storageType: AuthConfig['storage'];\n private tokenKey = 'thor_auth_token';\n \n constructor(config: AuthConfig) {\n this.storageType = config.storage;\n this.storage = config.customStorage ?? null;\n }\n \n async getToken(): Promise<string | null> {\n if (this.storage) {\n return this.storage.getItem(this.tokenKey);\n }\n \n if (typeof window === 'undefined') {\n // Server-side: no storage available\n return null;\n }\n \n switch (this.storageType) {\n case 'localStorage':\n return window.localStorage.getItem(this.tokenKey);\n case 'sessionStorage':\n return window.sessionStorage.getItem(this.tokenKey);\n case 'cookie':\n // Cookies are handled automatically by fetch, just return null\n return null;\n case 'memory':\n return null;\n default:\n return null;\n }\n }\n \n async setToken(token: string): Promise<void> {\n if (this.storage) {\n await this.storage.setItem(this.tokenKey, token);\n return;\n }\n \n if (typeof window === 'undefined') {\n return;\n }\n \n switch (this.storageType) {\n case 'localStorage':\n window.localStorage.setItem(this.tokenKey, token);\n break;\n case 'sessionStorage':\n window.sessionStorage.setItem(this.tokenKey, token);\n break;\n case 'cookie':\n case 'memory':\n // No action needed for cookie (handled by SDK) or memory\n break;\n }\n }\n \n async removeToken(): Promise<void> {\n if (this.storage) {\n await this.storage.removeItem(this.tokenKey);\n return;\n }\n \n if (typeof window === 'undefined') {\n return;\n }\n \n switch (this.storageType) {\n case 'localStorage':\n window.localStorage.removeItem(this.tokenKey);\n break;\n case 'sessionStorage':\n window.sessionStorage.removeItem(this.tokenKey);\n break;\n case 'cookie':\n case 'memory':\n // No action needed\n break;\n }\n }\n}\n\n/**\n * Medusa authentication provider implementation\n */\nexport class MedusaAuthProvider implements AuthProvider {\n private sdk: Medusa;\n private logger: ReturnType<typeof createLogger>;\n private authConfig: AuthConfig;\n private storageManager: AuthStorageManager;\n /** Medusa backend base URL — needed for raw fetch calls */\n private baseUrl: string;\n /** Publishable API key — sent as x-publishable-api-key on store calls */\n private publishableKey: string;\n \n constructor(sdk: Medusa, authConfig: AuthConfig, debug = false, baseUrl = '', publishableKey = '') {\n this.sdk = sdk;\n this.authConfig = authConfig;\n this.logger = createLogger('MedusaAuthProvider', debug);\n this.storageManager = new AuthStorageManager(authConfig);\n this.baseUrl = baseUrl;\n this.publishableKey = publishableKey;\n \n this.logger.info('Medusa Auth Provider initialized', {\n method: authConfig.method,\n storage: authConfig.storage,\n });\n }\n \n // ========================================\n // Authentication Methods\n // ========================================\n \n async login(credentials: LoginCredentials): Promise<AuthResponse> {\n this.logger.debug('login', { email: credentials.email });\n \n try {\n // Step 1: Authenticate with Medusa\n const token = await this.sdk.auth.login('customer', 'emailpass', {\n email: credentials.email,\n password: credentials.password,\n });\n \n // Check if token requires additional actions (OAuth flow)\n if (typeof token !== 'string') {\n this.logger.warn('Authentication requires additional actions', token);\n return {\n requiresAction: true,\n redirectUrl: token.location,\n };\n }\n \n // Step 2: Store token based on auth method\n if (this.authConfig.method === 'jwt') {\n await this.storageManager.setToken(token);\n }\n // Note: For session-based auth, the SDK automatically handles cookies\n // when auth.login() is called with auth.type='session' in SDK config\n \n // Step 3: Fetch customer data\n const customer = await this.getCurrentCustomer();\n \n this.logger.info('Login successful', { customerId: customer?.id });\n \n return {\n token: this.authConfig.method === 'jwt' ? token : undefined,\n customer: customer ?? undefined,\n };\n } catch (error: any) {\n this.logger.error('Login failed', error);\n throw new ProviderAPIError(\n `Authentication failed: ${error.message}`,\n 'LOGIN_FAILED',\n error\n );\n }\n }\n \n async register(data: RegisterData): Promise<AuthResponse> {\n this.logger.debug('register', { email: data.email });\n \n try {\n // Step 1: Register auth identity with Medusa\n const token = await this.sdk.auth.register('customer', 'emailpass', {\n email: data.email,\n password: data.password,\n });\n \n if (typeof token !== 'string') {\n throw new Error('Registration returned non-string token');\n }\n \n // Step 2: Create customer profile\n // Note: The SDK automatically includes the token in the header after auth.register()\n const { customer } = await this.sdk.store.customer.create({\n email: data.email,\n first_name: data.first_name,\n last_name: data.last_name,\n phone: data.phone,\n });\n \n // Step 3: Store token based on auth method\n if (this.authConfig.method === 'jwt') {\n await this.storageManager.setToken(token);\n }\n // Note: For session-based auth, the SDK automatically handles cookies\n // when auth.register() is called with auth.type='session' in SDK config\n \n this.logger.info('Registration successful', { customerId: customer.id });\n \n return {\n token: this.authConfig.method === 'jwt' ? token : undefined,\n customer: transformCustomer(customer, customer.email),\n };\n } catch (error: any) {\n this.logger.error('Registration failed', error);\n throw new ProviderAPIError(\n `Registration failed: ${error.message}`,\n 'REGISTRATION_FAILED',\n error\n );\n }\n }\n \n async logout(): Promise<void> {\n this.logger.debug('logout');\n \n try {\n await this.storageManager.removeToken();\n \n // For session auth, also call logout endpoint\n if (this.authConfig.method === 'session') {\n await this.sdk.auth.logout();\n }\n \n this.logger.info('Logout successful');\n } catch (error: any) {\n this.logger.error('Logout failed', error);\n // Don't throw error on logout failure, just log it\n }\n }\n \n // ========================================\n // Password Management\n // ========================================\n \n async requestPasswordReset(email: string): Promise<void> {\n this.logger.debug('requestPasswordReset', { email });\n \n try {\n await this.sdk.auth.resetPassword('customer', 'emailpass', {\n identifier: email,\n });\n \n this.logger.info('Password reset email sent', { email });\n } catch (error: any) {\n this.logger.error('Password reset request failed', error);\n throw new ProviderAPIError(\n `Password reset request failed: ${error.message}`,\n 'PASSWORD_RESET_FAILED',\n error\n );\n }\n }\n \n async resetPassword(\n token: string,\n password: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug('resetPassword', { hasMetadata: !!metadata });\n \n // Medusa requires email in the request body\n // Extract from metadata or decode from token\n const email = metadata?.email as string | undefined;\n \n if (!email) {\n throw new ProviderAPIError(\n 'Email is required in metadata for Medusa password reset',\n 'MEDUSA_AUTH_PROVIDER',\n 400\n );\n }\n \n try {\n // Medusa v2.6+ API: email + password in body, token as 3rd param\n await this.sdk.auth.updateProvider('customer', 'emailpass', {\n email,\n password,\n }, token);\n \n this.logger.info('Password reset successful');\n } catch (error: any) {\n this.logger.error('Password reset failed', error);\n throw new ProviderAPIError(\n `Password reset failed: ${error.message}`,\n 'PASSWORD_RESET_CONFIRM_FAILED',\n error\n );\n }\n }\n \n // ========================================\n // Session Management\n // ========================================\n \n async getCurrentCustomer(): Promise<Customer | null> {\n this.logger.debug('getCurrentCustomer');\n \n try {\n const { customer } = await this.sdk.store.customer.retrieve();\n \n if (!customer) {\n return null;\n }\n \n return transformCustomer(customer, customer.email);\n } catch (error: any) {\n this.logger.debug('No authenticated customer');\n return null;\n }\n }\n \n async updateCustomer(data: UpdateCustomerData): Promise<Customer> {\n this.logger.debug('updateCustomer');\n \n try {\n const updateData = { ...data };\n if (updateData.phone === null) {\n delete updateData.phone; // Medusa doesn't accept null, only undefined\n }\n const { customer } = await this.sdk.store.customer.update(updateData as any);\n \n return transformCustomer(customer, customer.email);\n } catch (error: any) {\n this.logger.error('Update customer failed', error);\n throw new ProviderAPIError(\n `Failed to update customer: ${error.message}`,\n 'UPDATE_CUSTOMER_FAILED',\n error\n );\n }\n }\n \n async isAuthenticated(): Promise<boolean> {\n const customer = await this.getCurrentCustomer();\n return customer !== null;\n }\n \n getAuthToken(): string | null {\n // For JWT auth, return stored token\n if (this.authConfig.method === 'jwt') {\n // This is sync, so we can't use async storage\n // Return null and rely on storage manager\n return null;\n }\n \n // For session auth, return null (cookies are handled automatically)\n return null;\n }\n \n // ========================================\n // Address Management\n // ========================================\n \n async getAddresses(): Promise<Address[]> {\n this.logger.debug('getAddresses');\n try {\n const { addresses } = await this.sdk.store.customer.listAddress();\n return addresses.map((address: any) => transformAddress(address));\n } catch (error: any) {\n this.logger.error('Get addresses failed', error);\n throw new ProviderAPIError(\n `Failed to get addresses: ${error.message}`,\n 'GET_ADDRESSES_FAILED',\n error\n );\n }\n }\n \n async createAddress(data: CreateAddressData): Promise<Address> {\n this.logger.debug('createAddress');\n \n try {\n // Transform camelCase to snake_case for Medusa API\n const medusaData = {\n first_name: data.firstName,\n last_name: data.lastName,\n company: data.company,\n address_1: data.address1,\n address_2: data.address2,\n city: data.city,\n province: data.province,\n postal_code: data.postalCode,\n country_code: data.countryCode,\n phone: data.phone,\n metadata: data.metadata,\n };\n \n const { customer } = await this.sdk.store.customer.createAddress(medusaData);\n \n // Get the most recent address (last one in array)\n const addresses = customer.addresses || [];\n const address = addresses[addresses.length - 1];\n \n if (!address) {\n throw new Error('No address returned from createAddress');\n }\n \n return transformAddress(address);\n } catch (error: any) {\n this.logger.error('Create address failed', error);\n throw new ProviderAPIError(\n `Failed to create address: ${error.message}`,\n 'CREATE_ADDRESS_FAILED',\n error\n );\n }\n }\n \n async updateAddress(\n addressId: string,\n data: Partial<CreateAddressData>\n ): Promise<Address> {\n this.logger.debug('updateAddress', { addressId });\n \n try {\n // Transform camelCase to snake_case for Medusa API (partial)\n const medusaData: any = {};\n if (data.firstName !== undefined) medusaData.first_name = data.firstName;\n if (data.lastName !== undefined) medusaData.last_name = data.lastName;\n if (data.company !== undefined) medusaData.company = data.company;\n if (data.address1 !== undefined) medusaData.address_1 = data.address1;\n if (data.address2 !== undefined) medusaData.address_2 = data.address2;\n if (data.city !== undefined) medusaData.city = data.city;\n if (data.province !== undefined) medusaData.province = data.province;\n if (data.postalCode !== undefined) medusaData.postal_code = data.postalCode;\n if (data.countryCode !== undefined) medusaData.country_code = data.countryCode;\n if (data.phone !== undefined) medusaData.phone = data.phone;\n if (data.metadata !== undefined) medusaData.metadata = data.metadata;\n \n const { customer } = await this.sdk.store.customer.updateAddress(addressId, medusaData);\n \n // Find the updated address by ID\n const addresses = customer.addresses || [];\n const address = addresses.find((addr: any) => addr.id === addressId);\n \n if (!address) {\n throw new Error(`Address ${addressId} not found after update`);\n }\n \n return transformAddress(address);\n } catch (error: any) {\n this.logger.error('Update address failed', error);\n throw new ProviderAPIError(\n `Failed to update address: ${error.message}`,\n 'UPDATE_ADDRESS_FAILED',\n error\n );\n }\n }\n \n async deleteAddress(addressId: string): Promise<void> {\n this.logger.debug('deleteAddress', { addressId });\n \n try {\n await this.sdk.store.customer.deleteAddress(addressId);\n this.logger.info('Address deleted', { addressId });\n } catch (error: any) {\n this.logger.error('Delete address failed', error);\n throw new ProviderAPIError(\n `Failed to delete address: ${error.message}`,\n 'DELETE_ADDRESS_FAILED',\n error\n );\n }\n }\n\n async deleteCustomerAccount(): Promise<void> {\n this.logger.debug('deleteCustomerAccount');\n \n // TODO: Implement when custom Medusa backend endpoint is ready\n // DELETE /store/customers/me\n throw new ProviderAPIError(\n 'Delete customer account is not yet implemented. Requires custom Medusa backend endpoint.',\n 'NOT_IMPLEMENTED',\n undefined\n );\n }\n\n // ========================================\n // Multi-Tenant — Channel Link\n // ========================================\n\n /**\n * Link the currently authenticated customer to the storefront's sales channel.\n *\n * Must be called immediately after a successful `login()` so the customer\n * appears in the admin panel of the correct storefront channel.\n *\n * Implements `POST /store/thor/customers/me/channels`.\n * Idempotent — returns `{ linked: false, reason: 'already_linked' }` when\n * the link already exists.\n *\n * @throws {ProviderAPIError} When not authenticated (401) or channel cannot\n * be resolved from the publishable key (400).\n */\n async linkCustomerToChannel(): Promise<LinkCustomerToChannelResponse> {\n this.logger.debug('linkCustomerToChannel');\n\n if (!this.baseUrl || !this.publishableKey) {\n throw new ProviderAPIError(\n 'linkCustomerToChannel requires baseUrl and publishableKey to be set on the auth provider.',\n 'CONFIGURATION_ERROR',\n undefined\n );\n }\n\n // Retrieve the JWT token for the Authorization header.\n // Falls back to the SDK-managed token (session or JWT storage).\n const token = await this.storageManager.getToken();\n\n const headers: Record<string, string> = {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n };\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n try {\n const url = `${this.baseUrl}/store/thor/customers/me/channels`;\n const response = await fetch(url, {\n method: 'POST',\n headers,\n });\n\n if (response.status === 401) {\n throw new ProviderAPIError(\n 'linkCustomerToChannel: not authenticated. Call login() first.',\n 'NOT_AUTHENTICATED',\n 401\n );\n }\n\n if (response.status === 400) {\n const body = await response.json().catch(() => ({}));\n throw new ProviderAPIError(\n `linkCustomerToChannel: could not resolve sales channel from publishable key. ${body?.message ?? ''}`.trim(),\n 'CHANNEL_RESOLUTION_FAILED',\n 400\n );\n }\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n throw new ProviderAPIError(\n `linkCustomerToChannel failed with status ${response.status}: ${body?.message ?? 'Unknown error'}`,\n 'LINK_CHANNEL_FAILED',\n response.status\n );\n }\n\n const data = await response.json() as LinkCustomerToChannelResponse;\n this.logger.info('Customer linked to channel', { linked: data.linked, reason: data.reason });\n return data;\n } catch (error: any) {\n if (error instanceof ProviderAPIError) throw error;\n this.logger.error('linkCustomerToChannel failed', error);\n throw new ProviderAPIError(\n `linkCustomerToChannel failed: ${error.message}`,\n 'LINK_CHANNEL_FAILED',\n error\n );\n }\n }\n}\n","/**\n * @thorprovider/adapters v2.0\n * Medusa Payment Provider Implementation\n * \n * Transforms Medusa payment providers to Thor's unified PaymentMethod format.\n * Handles region-specific payment provider queries.\n */\n\nimport type Medusa from '@medusajs/js-sdk';\nimport type { HttpTypes } from '@medusajs/types';\nimport type { \n PaymentMethod, \n PaymentMethodsOptions, \n PaymentMethodType \n} from '@thorprovider/types';\nimport { ProviderAPIError } from '../../core/errors';\n\n/**\n * Map of Medusa provider names to display names\n */\nconst PROVIDER_DISPLAY_NAMES: Record<string, string> = {\n stripe: 'Stripe',\n paypal: 'PayPal',\n system: 'Cash on Delivery',\n manual: 'Manual Payment',\n bancontact: 'Bancontact',\n blik: 'BLIK',\n giropay: 'giropay',\n ideal: 'iDEAL',\n przelewy24: 'Przelewy24',\n promptpay: 'PromptPay',\n oxxo: 'OXXO',\n};\n\n/**\n * Infer payment method type from Medusa provider ID\n * \n * Medusa format: pp_{provider}_{method}\n * Examples:\n * - pp_stripe_stripe → 'card'\n * - pp_paypal_paypal → 'wallet'\n * - pp_system_default → 'cash_on_delivery'\n * - pp_stripe_bancontact → 'bank_transfer'\n * \n * @param providerId - Medusa provider ID\n * @returns Normalized payment method type\n */\nfunction inferPaymentType(providerId: string): PaymentMethodType {\n const id = providerId.toLowerCase();\n \n // Card payments\n if (id.includes('stripe') || id.includes('card')) {\n return 'card';\n }\n \n // Digital wallets\n if (\n id.includes('paypal') || \n id.includes('wallet') ||\n id.includes('apple') ||\n id.includes('google')\n ) {\n return 'wallet';\n }\n \n // Bank transfers\n if (\n id.includes('bancontact') ||\n id.includes('ideal') ||\n id.includes('giropay') ||\n id.includes('sepa') ||\n id.includes('ach') ||\n id.includes('bank')\n ) {\n return 'bank_transfer';\n }\n \n // Buy now pay later\n if (\n id.includes('klarna') ||\n id.includes('affirm') ||\n id.includes('afterpay') ||\n id.includes('przelewy24')\n ) {\n return 'buy_now_pay_later';\n }\n \n // Cash on delivery / Manual\n if (\n id.includes('system') ||\n id.includes('manual') ||\n id.includes('cod') ||\n id.includes('default')\n ) {\n return 'cash_on_delivery';\n }\n \n // Crypto\n if (id.includes('crypto') || id.includes('bitcoin')) {\n return 'crypto';\n }\n \n return 'other';\n}\n\n/**\n * Parse Medusa provider ID to extract provider and method names\n * \n * @param providerId - Medusa provider ID (e.g., \"pp_stripe_stripe\")\n * @returns Object with provider and method names\n */\nfunction parseProviderId(providerId: string): { provider: string; method: string } {\n // Medusa format: pp_{provider}_{method}\n const match = providerId.match(/^pp_([^_]+)_(.+)$/);\n \n if (match) {\n return {\n provider: match[1],\n method: match[2],\n };\n }\n \n // Fallback for non-standard formats\n return {\n provider: 'unknown',\n method: providerId,\n };\n}\n\n/**\n * Get display name for a provider\n */\nfunction getDisplayName(providerName: string): string {\n return PROVIDER_DISPLAY_NAMES[providerName.toLowerCase()] || \n providerName.charAt(0).toUpperCase() + providerName.slice(1);\n}\n\n/**\n * Transform Medusa payment provider to Thor payment method\n * \n * @param medusaProvider - Medusa payment provider from API\n * @returns Normalized Thor PaymentMethod\n */\nexport function transformPaymentMethod(\n medusaProvider: HttpTypes.StorePaymentProvider\n): PaymentMethod {\n const providerId = medusaProvider.id;\n const { provider, method } = parseProviderId(providerId);\n const type = inferPaymentType(providerId);\n \n // Determine features based on provider type\n const isStripe = provider === 'stripe';\n const isSystemDefault = provider === 'system' || method === 'default';\n const isPayPal = provider === 'paypal';\n \n return {\n id: providerId,\n name: getDisplayName(provider),\n type,\n isEnabled: true, // Medusa returns only enabled providers by default\n requiresSetup: !isSystemDefault, // System/manual payment requires no setup\n metadata: {\n providerId: provider,\n methodId: method,\n originalData: medusaProvider,\n _backendMapping: {\n backend: 'medusa',\n originalId: providerId,\n normalizedType: type,\n },\n },\n features: {\n // Stripe supports saving payment methods\n saveForLater: isStripe,\n \n // Stripe requires 3DS for SCA compliance\n requires3DS: isStripe,\n \n // Most providers support refunds except COD/manual\n supportsRefunds: !isSystemDefault,\n \n // Stripe has minimum amounts (varies by currency)\n minAmount: isStripe ? 50 : undefined, // 50 cents minimum for Stripe\n \n // PayPal has maximum transaction limits\n maxAmount: isPayPal ? 1000000 : undefined, // $10,000 for PayPal\n },\n };\n}\n\n/**\n * Get payment methods for Medusa\n * \n * Queries Medusa API for available payment providers in a region.\n * Medusa requires either regionId or cartId to determine available providers.\n * \n * @param sdk - Medusa SDK instance\n * @param options - Payment methods query options\n * @returns Array of normalized payment methods\n * \n * @throws {Error} If neither regionId nor cartId is provided\n * @throws {ProviderAPIError} If API request fails\n */\nexport async function getPaymentMethods(\n sdk: Medusa,\n options: PaymentMethodsOptions\n): Promise<PaymentMethod[]> {\n // Medusa requires region_id to list payment providers\n let regionId = options.regionId;\n \n // If cart ID is provided but no region, fetch cart to get region\n if (options.cartId && !regionId) {\n try {\n const { cart } = await sdk.store.cart.retrieve(options.cartId);\n regionId = cart.region_id;\n } catch (error) {\n const err = error as any;\n throw new ProviderAPIError(\n 'Failed to fetch cart to determine region',\n 'medusa',\n err?.status\n );\n }\n }\n \n // Validate that we have a region ID\n if (!regionId) {\n throw new Error(\n 'Either regionId or cartId is required for Medusa payment methods. ' +\n 'Medusa requires a region to determine available payment providers.'\n );\n }\n \n try {\n // Query Medusa API for payment providers in this region\n const response = await sdk.store.payment.listPaymentProviders({\n region_id: regionId,\n });\n \n // Transform to Thor format\n let methods = response.payment_providers.map(transformPaymentMethod);\n \n // Apply filters\n if (options.enabledOnly !== false) { // Default to true\n methods = methods.filter(m => m.isEnabled);\n }\n \n // Filter by currency if provided\n if (options.currencyCode) {\n methods = methods.filter(m => {\n // If method specifies supported currencies, check them\n if (m.features?.supportedCurrencies) {\n return m.features.supportedCurrencies.includes(options.currencyCode!);\n }\n // Otherwise assume all currencies supported\n return true;\n });\n }\n \n return methods;\n } catch (error) {\n const err = error as any;\n throw new ProviderAPIError(\n 'Failed to fetch payment providers from Medusa',\n 'medusa',\n err?.status\n );\n }\n}\n","/**\n * @fileoverview Medusa Multi-Tenant Admin Client\n * @module @thorprovider/adapters/providers/medusa/admin\n *\n * Wrapper methods for all `/admin/thor/` endpoints defined in the Thor Commerce\n * multi-tenant API contract. Requires an admin API key (`adminConfig.apiKey`)\n * to be provided when creating the Medusa provider.\n *\n * Every method performs a raw `fetch` against the Medusa backend using the\n * admin API key (`x-medusa-access-token`) — the Medusa JS-SDK's admin client\n * does not expose these custom Thor plugin routes, so we use direct HTTP calls.\n *\n * Endpoint reference: `multitenant-api-contract.md`\n */\n\nimport type {\n GetChannelCustomersOptions,\n GetChannelCustomersResponse,\n GetChannelApiKeysResponse,\n GetChannelCategoriesOptions,\n GetChannelCategoriesResponse,\n GetCategorySalesChannelsResponse,\n AssignCategoriesToChannelsBody,\n AssignCategoriesToChannelsResponse,\n UnassignCategoriesFromChannelsBody,\n UnassignCategoriesFromChannelsResponse,\n GetCollectionSalesChannelsResponse,\n AssignCollectionsToChannelsBody,\n AssignCollectionsToChannelsResponse,\n UnassignCollectionsFromChannelsBody,\n UnassignCollectionsFromChannelsResponse,\n GetAdminStorefrontConfigResponse,\n UpdateStorefrontConfigBody,\n UpdateStorefrontConfigResponse,\n GetAdminSiteConfigResponse,\n UpdateSiteConfigBody,\n UpdateSiteConfigResponse,\n GetAdminSiteConfigHistoryOptions,\n GetAdminSiteConfigHistoryResponse,\n RestoreSiteConfigResponse,\n} from '@thorprovider/types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ntype FetchMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\n/**\n * Configuration required to instantiate the admin client.\n */\nexport interface MedusaAdminClientConfig {\n /** Medusa backend base URL */\n baseUrl: string;\n /** Secret admin API key (x-medusa-access-token) */\n apiKey: string;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// MedusaAdminClient\n// ---------------------------------------------------------------------------\n\n/**\n * HTTP client for Thor Commerce multi-tenant admin endpoints (`/admin/thor/`).\n *\n * All methods throw `ProviderAPIError` on non-2xx responses.\n *\n * @example\n * ```typescript\n * const admin = new MedusaAdminClient({\n * baseUrl: process.env.MEDUSA_BACKEND_URL!,\n * apiKey: process.env.MEDUSA_ADMIN_API_KEY!,\n * });\n *\n * const { customers } = await admin.getChannelCustomers('sc_01JXXXXX');\n * ```\n */\nexport class MedusaAdminClient {\n private baseUrl: string;\n private apiKey: string;\n private logger: ReturnType<typeof createLogger>;\n\n constructor(config: MedusaAdminClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n this.logger = createLogger('MedusaAdminClient', config.debug);\n }\n\n // -----------------------------------------------------------------------\n // Private — HTTP helper\n // -----------------------------------------------------------------------\n\n private async request<T>(\n method: FetchMethod,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n this.logger.debug(`[admin] ${method} ${path}`);\n\n const headers: Record<string, string> = {\n 'x-medusa-access-token': this.apiKey,\n 'Content-Type': 'application/json',\n };\n\n const init: RequestInit = {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n };\n\n let response: Response;\n try {\n response = await fetch(url, init);\n } catch (networkError: any) {\n throw new ProviderAPIError(\n `[admin] Network error on ${method} ${path}: ${networkError.message}`,\n 'NETWORK_ERROR',\n networkError,\n );\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status}`;\n try {\n const json = await response.json();\n message = json?.message ?? message;\n } catch {\n // ignore parse errors\n }\n throw new ProviderAPIError(\n `[admin] ${method} ${path} failed: ${message}`,\n `ADMIN_API_${response.status}`,\n response.status,\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n // -----------------------------------------------------------------------\n // 3.1 — Sales Channel: Customers\n // -----------------------------------------------------------------------\n\n /**\n * Paginated list of customers linked to a sales channel.\n *\n * `GET /admin/thor/sales-channels/:id/customers`\n */\n async getChannelCustomers(\n salesChannelId: string,\n options: GetChannelCustomersOptions = {},\n ): Promise<GetChannelCustomersResponse> {\n const { limit = 20, offset = 0 } = options;\n return this.request<GetChannelCustomersResponse>(\n 'GET',\n `/admin/thor/sales-channels/${salesChannelId}/customers?limit=${limit}&offset=${offset}`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.2 — Sales Channel: API Keys\n // -----------------------------------------------------------------------\n\n /**\n * Publishable API keys associated with a sales channel.\n *\n * `GET /admin/thor/sales-channels/:id/api-keys`\n */\n async getChannelApiKeys(salesChannelId: string): Promise<GetChannelApiKeysResponse> {\n return this.request<GetChannelApiKeysResponse>(\n 'GET',\n `/admin/thor/sales-channels/${salesChannelId}/api-keys`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.3 — Sales Channel: Categories\n // -----------------------------------------------------------------------\n\n /**\n * Product categories assigned to a sales channel.\n *\n * `GET /admin/thor/sales-channels/:id/categories`\n */\n async getChannelCategories(\n salesChannelId: string,\n options: GetChannelCategoriesOptions = {},\n ): Promise<GetChannelCategoriesResponse> {\n const { limit = 20, offset = 0, include_descendants = false } = options;\n const qs = new URLSearchParams({\n limit: String(limit),\n offset: String(offset),\n include_descendants: String(include_descendants),\n });\n return this.request<GetChannelCategoriesResponse>(\n 'GET',\n `/admin/thor/sales-channels/${salesChannelId}/categories?${qs}`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.4 — Category: Sales Channels\n // -----------------------------------------------------------------------\n\n /**\n * Sales channels to which a category is assigned.\n *\n * `GET /admin/thor/categories/:id/sales-channels`\n */\n async getCategorySalesChannels(\n categoryId: string,\n ): Promise<GetCategorySalesChannelsResponse> {\n return this.request<GetCategorySalesChannelsResponse>(\n 'GET',\n `/admin/thor/categories/${categoryId}/sales-channels`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.5 — Category: Assign to Sales Channels\n // -----------------------------------------------------------------------\n\n /**\n * Assign a category to one or more sales channels (idempotent).\n *\n * `POST /admin/thor/categories/:id/sales-channels`\n */\n async assignCategoryToChannels(\n categoryId: string,\n body: AssignCategoriesToChannelsBody,\n ): Promise<AssignCategoriesToChannelsResponse> {\n return this.request<AssignCategoriesToChannelsResponse>(\n 'POST',\n `/admin/thor/categories/${categoryId}/sales-channels`,\n body,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.6 — Category: Unassign from Sales Channels\n // -----------------------------------------------------------------------\n\n /**\n * Remove category assignment from one or more sales channels (idempotent).\n *\n * `DELETE /admin/thor/categories/:id/sales-channels`\n */\n async unassignCategoryFromChannels(\n categoryId: string,\n body: UnassignCategoriesFromChannelsBody,\n ): Promise<UnassignCategoriesFromChannelsResponse> {\n return this.request<UnassignCategoriesFromChannelsResponse>(\n 'DELETE',\n `/admin/thor/categories/${categoryId}/sales-channels`,\n body,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.7 — Collection: Sales Channels\n // -----------------------------------------------------------------------\n\n /**\n * Sales channels to which a collection is assigned.\n *\n * `GET /admin/thor/collections/:id/sales-channels`\n */\n async getCollectionSalesChannels(\n collectionId: string,\n ): Promise<GetCollectionSalesChannelsResponse> {\n return this.request<GetCollectionSalesChannelsResponse>(\n 'GET',\n `/admin/thor/collections/${collectionId}/sales-channels`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.8 — Collection: Assign to Sales Channels\n // -----------------------------------------------------------------------\n\n /**\n * Assign a collection to one or more sales channels (idempotent).\n *\n * `POST /admin/thor/collections/:id/sales-channels`\n */\n async assignCollectionToChannels(\n collectionId: string,\n body: AssignCollectionsToChannelsBody,\n ): Promise<AssignCollectionsToChannelsResponse> {\n return this.request<AssignCollectionsToChannelsResponse>(\n 'POST',\n `/admin/thor/collections/${collectionId}/sales-channels`,\n body,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.9 — Collection: Unassign from Sales Channels\n // -----------------------------------------------------------------------\n\n /**\n * Remove collection assignment from one or more sales channels (idempotent).\n *\n * `DELETE /admin/thor/collections/:id/sales-channels`\n */\n async unassignCollectionFromChannels(\n collectionId: string,\n body: UnassignCollectionsFromChannelsBody,\n ): Promise<UnassignCollectionsFromChannelsResponse> {\n return this.request<UnassignCollectionsFromChannelsResponse>(\n 'DELETE',\n `/admin/thor/collections/${collectionId}/sales-channels`,\n body,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.10 — Storefront Config: Read\n // -----------------------------------------------------------------------\n\n /**\n * Read the visual storefront configuration for a channel.\n * `:id` is the `sales_channel_id`.\n *\n * `GET /admin/thor/storefront-config/:id`\n */\n async getStorefrontConfig(\n salesChannelId: string,\n ): Promise<GetAdminStorefrontConfigResponse> {\n return this.request<GetAdminStorefrontConfigResponse>(\n 'GET',\n `/admin/thor/storefront-config/${salesChannelId}`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.11 — Storefront Config: Update\n // -----------------------------------------------------------------------\n\n /**\n * Update the visual storefront configuration for a channel.\n * Triggers the `storefront_config.updated` event → ISR webhook.\n *\n * `PUT /admin/thor/storefront-config/:id`\n */\n async updateStorefrontConfig(\n salesChannelId: string,\n body: UpdateStorefrontConfigBody,\n ): Promise<UpdateStorefrontConfigResponse> {\n return this.request<UpdateStorefrontConfigResponse>(\n 'PUT',\n `/admin/thor/storefront-config/${salesChannelId}`,\n body,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.12 — Site Designer Config: Read\n // -----------------------------------------------------------------------\n\n /**\n * Read the active Site Designer configuration for a channel, including the\n * last 10 history entries.\n *\n * `GET /admin/thor/site-config/:sales_channel_id`\n */\n async getSiteConfig(salesChannelId: string): Promise<GetAdminSiteConfigResponse> {\n return this.request<GetAdminSiteConfigResponse>(\n 'GET',\n `/admin/thor/site-config/${salesChannelId}`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.13 — Site Designer Config: Update\n // -----------------------------------------------------------------------\n\n /**\n * Update the Site Designer configuration for a channel.\n * Creates a new history entry on every PUT.\n *\n * `PUT /admin/thor/site-config/:sales_channel_id`\n */\n async updateSiteConfig(\n salesChannelId: string,\n body: UpdateSiteConfigBody,\n ): Promise<UpdateSiteConfigResponse> {\n return this.request<UpdateSiteConfigResponse>(\n 'PUT',\n `/admin/thor/site-config/${salesChannelId}`,\n body,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.14 — Site Designer Config: History\n // -----------------------------------------------------------------------\n\n /**\n * Full paginated history of Site Designer versions for a channel.\n * Entries are immutable — they are never deleted.\n *\n * `GET /admin/thor/site-config/:sales_channel_id/history`\n */\n async getSiteConfigHistory(\n salesChannelId: string,\n options: GetAdminSiteConfigHistoryOptions = {},\n ): Promise<GetAdminSiteConfigHistoryResponse> {\n const { limit = 20, offset = 0 } = options;\n return this.request<GetAdminSiteConfigHistoryResponse>(\n 'GET',\n `/admin/thor/site-config/${salesChannelId}/history?limit=${limit}&offset=${offset}`,\n );\n }\n\n // -----------------------------------------------------------------------\n // 3.15 — Site Designer Config: Restore\n // -----------------------------------------------------------------------\n\n /**\n * Restore a previous Site Designer version.\n * Internally runs the update workflow with the stored config of the target\n * version — this creates a **new** history entry and does NOT mutate past\n * entries.\n *\n * `POST /admin/thor/site-config/:sales_channel_id/restore/:version`\n */\n async restoreSiteConfig(\n salesChannelId: string,\n version: string,\n ): Promise<RestoreSiteConfigResponse> {\n return this.request<RestoreSiteConfigResponse>(\n 'POST',\n `/admin/thor/site-config/${salesChannelId}/restore/${encodeURIComponent(version)}`,\n );\n }\n}\n","import type {\n Collection,\n Customer,\n Address,\n FulfillmentStatus,\n Image,\n InventoryLevel,\n Money,\n Order,\n OrderItem,\n OrderStatus,\n PaymentMethod,\n PaymentMethodType,\n PaymentStatus,\n Product,\n ProductCategory,\n ProductVariant,\n ShippingMethod,\n StockLocation,\n} from '@thorprovider/types';\n\nexport interface StelResource {\n id?: number;\n path?: string;\n deleted?: boolean;\n 'utc-last-modification-date'?: string;\n}\n\nexport interface StelItemImage {\n 'item-image-path'?: string;\n order?: number;\n}\n\nexport interface StelItemRate {\n 'rate-id'?: number;\n 'rate-path'?: string;\n price?: number;\n}\n\nexport interface StelProductWarehouse {\n 'warehouse-id'?: number;\n 'warehouse-path'?: string;\n 'minimum-stock'?: number;\n 'real-stock'?: number;\n 'virtual-stock'?: number;\n location?: string;\n}\n\nexport interface StelProduct extends StelResource {\n name?: string;\n description?: string;\n reference?: string;\n 'full-reference'?: string;\n barcode?: string;\n 'sales-price'?: number;\n 'purchase-price'?: number;\n 'product-category-id'?: number;\n 'product-category-path'?: string;\n 'real-stock'?: number;\n 'virtual-stock'?: number;\n 'minimum-stock'?: number;\n 'stock-enabled'?: boolean;\n inactive?: boolean;\n promotional?: boolean;\n 'creation-date'?: string;\n 'item-images'?: StelItemImage[];\n 'item-rates'?: StelItemRate[];\n 'product-warehouses'?: StelProductWarehouse[];\n}\n\nexport interface StelProductCategory extends StelResource {\n name?: string;\n description?: string;\n slug?: string;\n 'parent-category-id'?: number;\n}\n\nexport interface StelClient extends StelResource {\n name?: string;\n 'business-name'?: string;\n email?: string;\n phone?: string;\n mobile?: string;\n 'rate-id'?: number;\n 'payment-option-id'?: number;\n 'payment-term-id'?: number;\n 'delivery-option-id'?: number;\n 'main-address'?: StelAddress;\n}\n\nexport interface StelAddress extends StelResource {\n name?: string;\n 'first-name'?: string;\n 'last-name'?: string;\n company?: string;\n 'address-data'?: string;\n 'postal-code'?: string;\n 'city-town'?: string;\n province?: string;\n 'country-code'?: string;\n phone?: string;\n email?: string;\n}\n\nexport interface StelDocumentLine {\n 'item-id'?: number;\n 'item-name'?: string;\n 'item-description'?: string;\n 'item-base-price'?: number;\n 'primary-tax-percentage'?: number;\n 'discount-percentage'?: number;\n units?: number;\n 'line-type'?: 'ITEM' | 'DOCUMENT' | 'SECTION' | 'COMPONENT';\n}\n\nexport interface StelSalesOrder extends StelResource {\n reference?: string;\n status?: string;\n email?: string;\n 'client-id'?: number;\n 'payment-option-id'?: number;\n 'payment-term-id'?: number;\n 'delivery-option-id'?: number;\n 'creation-date'?: string;\n 'total-base'?: number;\n 'total-tax'?: number;\n total?: number;\n 'document-lines'?: StelDocumentLine[];\n}\n\nexport interface StelPaymentOption extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport interface StelPaymentTerm extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport interface StelDeliveryOption extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport interface StelWarehouse extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport function normalizeStelCollection<T>(payload: T | T[] | null | undefined): T[] {\n if (!payload) {\n return [];\n }\n\n return Array.isArray(payload) ? payload : [payload];\n}\n\nexport function normalizeStelEntity<T>(payload: T | T[] | null | undefined): T | undefined {\n if (!payload) {\n return undefined;\n }\n\n return Array.isArray(payload) ? payload[0] : payload;\n}\n\nexport function transformStelMoney(\n amount: number | string | null | undefined,\n currencyCode: string = 'USD',\n): Money {\n const normalizedAmount = typeof amount === 'string' ? Number.parseFloat(amount) : amount ?? 0;\n\n return {\n amount: Number.isFinite(normalizedAmount) ? normalizedAmount.toFixed(2) : '0.00',\n currencyCode: currencyCode.toUpperCase(),\n };\n}\n\nexport function transformStelImage(url: string | null | undefined, altText: string = ''): Image | undefined {\n const normalizedUrl = url?.trim();\n\n if (!normalizedUrl) {\n return undefined;\n }\n\n return {\n url: normalizedUrl,\n altText,\n width: 800,\n height: 800,\n };\n}\n\nexport function normalizeStelDate(value: string | null | undefined): string {\n if (!value) {\n return new Date().toISOString();\n }\n\n const parsed = new Date(value);\n return Number.isNaN(parsed.getTime()) ? new Date().toISOString() : parsed.toISOString();\n}\n\nexport function extractStelIdFromPath(path: string | null | undefined): string | undefined {\n if (!path) {\n return undefined;\n }\n\n const match = path.match(/\\/([^/]+)$/);\n return match?.[1];\n}\n\nexport function toStelStringId(value: string | number | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n return String(value);\n}\n\nfunction slugify(value: string): string {\n return value\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nexport function buildStelHandle(...candidates: Array<string | number | null | undefined>): string {\n for (const candidate of candidates) {\n if (candidate === null || candidate === undefined) {\n continue;\n }\n\n const normalized = slugify(String(candidate).trim());\n if (normalized) {\n return normalized;\n }\n }\n\n return 'stel-item';\n}\n\n// ---------------------------------------------------------------------------\n// Product transforms\n// ---------------------------------------------------------------------------\n\nfunction transformStelProductImages(product: StelProduct): Image[] {\n const images: Image[] = [];\n\n if (!product['item-images']) {\n return images;\n }\n\n const sorted = [...product['item-images']].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n\n for (const img of sorted) {\n const transformed = transformStelImage(img['item-image-path'], product.name ?? '');\n if (transformed) {\n images.push(transformed);\n }\n }\n\n return images;\n}\n\nfunction deriveStelStockStatus(product: StelProduct): 'in_stock' | 'out_of_stock' | 'low_stock' {\n if (!product['stock-enabled']) {\n return 'in_stock';\n }\n\n const realStock = product['real-stock'] ?? 0;\n const minimumStock = product['minimum-stock'] ?? 0;\n\n if (realStock <= 0) {\n return 'out_of_stock';\n }\n\n if (realStock <= minimumStock) {\n return 'low_stock';\n }\n\n return 'in_stock';\n}\n\n/**\n * Build a single synthetic variant from a STEL product.\n * STEL products have no variant concept — every product is a single SKU.\n */\nfunction buildSyntheticVariant(product: StelProduct, currencyCode: string): ProductVariant {\n const price = transformStelMoney(product['sales-price'], currencyCode);\n const stockStatus = deriveStelStockStatus(product);\n const quantityAvailable = product['stock-enabled'] ? (product['real-stock'] ?? 0) : undefined;\n const image = product['item-images']?.[0]\n ? transformStelImage(product['item-images'][0]['item-image-path'], product.name ?? '')\n : undefined;\n\n return {\n id: toStelStringId(product.id),\n title: 'Default',\n sku: product.barcode ?? product['full-reference'] ?? undefined,\n availableForSale: stockStatus !== 'out_of_stock',\n selectedOptions: [],\n price,\n compareAtPrice: undefined,\n quantityAvailable,\n stockStatus,\n image,\n };\n}\n\nexport function transformStelProduct(raw: StelProduct, currencyCode: string): Product {\n const id = toStelStringId(raw.id);\n const handle = buildStelHandle(raw['full-reference'], raw.reference, raw.name, raw.id);\n const price = transformStelMoney(raw['sales-price'], currencyCode);\n const images = transformStelProductImages(raw);\n const variant = buildSyntheticVariant(raw, currencyCode);\n const now = new Date().toISOString();\n\n return {\n id,\n handle,\n title: raw.name ?? '',\n description: raw.description ?? '',\n availableForSale: variant.availableForSale,\n options: [],\n variants: [variant],\n featuredImage: images[0],\n images,\n priceRange: {\n minVariantPrice: price,\n maxVariantPrice: price,\n },\n productType: undefined,\n vendor: undefined,\n tags: raw.promotional ? ['promotional'] : [],\n createdAt: normalizeStelDate(raw['creation-date']),\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']) || now,\n metadata: {\n stelFullReference: raw['full-reference'],\n stelReference: raw.reference,\n stelBarcode: raw.barcode,\n stelCategoryId: raw['product-category-id'],\n stelInactive: raw.inactive,\n stelPromotional: raw.promotional,\n stelPurchasePrice: raw['purchase-price'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Category transforms\n// ---------------------------------------------------------------------------\n\nexport function transformStelCategory(raw: StelProductCategory): ProductCategory {\n const id = toStelStringId(raw.id);\n const handle = buildStelHandle(raw.slug, raw.name, raw.id);\n\n return {\n id,\n name: raw.name ?? '',\n handle,\n description: raw.description ?? undefined,\n parentCategoryId: raw['parent-category-id']\n ? toStelStringId(raw['parent-category-id'])\n : undefined,\n metadata: {\n stelSlug: raw.slug,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Collection transforms (alias categories as collections)\n// ---------------------------------------------------------------------------\n\nexport function transformStelCategoryToCollection(raw: StelProductCategory): Collection {\n const id = toStelStringId(raw.id);\n const handle = buildStelHandle(raw.slug, raw.name, raw.id);\n\n return {\n id,\n handle,\n title: raw.name ?? '',\n description: raw.description ?? '',\n path: `/collections/${handle}`,\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Inventory / warehouse transforms\n// ---------------------------------------------------------------------------\n\nexport function transformStelWarehouseToStockLocation(raw: StelWarehouse): StockLocation {\n return {\n id: toStelStringId(raw.id),\n name: raw.name ?? 'Warehouse',\n };\n}\n\nexport function transformStelProductWarehouseToInventoryLevel(\n pw: StelProductWarehouse,\n): InventoryLevel {\n return {\n locationId: toStelStringId(pw['warehouse-id']),\n locationName: pw['warehouse-path'] ?? `Warehouse ${pw['warehouse-id'] ?? 'unknown'}`,\n availableQuantity: pw['real-stock'] ?? 0,\n reservedQuantity: Math.max(0, (pw['virtual-stock'] ?? 0) - (pw['real-stock'] ?? 0)),\n stockedQuantity: pw['virtual-stock'] ?? pw['real-stock'] ?? 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Customer / Address transforms\n// ---------------------------------------------------------------------------\n\nfunction splitStelName(fullName: string | null | undefined): { firstName: string; lastName: string } {\n if (!fullName?.trim()) {\n return { firstName: '', lastName: '' };\n }\n\n const parts = fullName.trim().split(/\\s+/);\n const firstName = parts[0] ?? '';\n const lastName = parts.length > 1 ? parts.slice(1).join(' ') : '';\n return { firstName, lastName };\n}\n\nexport function transformStelAddress(raw: StelAddress): Address {\n const firstName = raw['first-name'] ?? '';\n const lastName = raw['last-name'] ?? '';\n\n // If first/last not present, attempt to split the 'name' field\n const nameParts = !firstName && !lastName ? splitStelName(raw.name) : { firstName, lastName };\n\n return {\n id: raw.id ? toStelStringId(raw.id) : undefined,\n firstName: nameParts.firstName,\n lastName: nameParts.lastName,\n company: raw.company ?? undefined,\n address1: raw['address-data'] ?? '',\n city: raw['city-town'] ?? '',\n province: raw.province ?? undefined,\n postalCode: raw['postal-code'] ?? '',\n countryCode: raw['country-code'] ?? '',\n phone: raw.phone ?? undefined,\n isDefault: true,\n metadata: {\n stelEmail: raw.email,\n },\n };\n}\n\nexport function transformStelClient(raw: StelClient): Customer {\n const { firstName, lastName } = splitStelName(raw.name ?? raw['business-name']);\n\n return {\n id: toStelStringId(raw.id),\n email: raw.email ?? '',\n firstName: firstName || null,\n lastName: lastName || null,\n phone: raw.phone ?? raw.mobile ?? null,\n hasAccount: true,\n createdAt: normalizeStelDate(raw['utc-last-modification-date']),\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']),\n metadata: {\n stelBusinessName: raw['business-name'],\n stelRateId: raw['rate-id'],\n stelPaymentOptionId: raw['payment-option-id'],\n stelPaymentTermId: raw['payment-term-id'],\n stelDeliveryOptionId: raw['delivery-option-id'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Order transforms\n// ---------------------------------------------------------------------------\n\nfunction deriveStelOrderStatus(raw: StelSalesOrder): OrderStatus {\n if (raw.deleted) {\n return 'cancelled';\n }\n\n const status = (raw.status ?? '').toLowerCase();\n\n if (status.includes('cancel') || status.includes('anulad')) {\n return 'cancelled';\n }\n if (status.includes('complet') || status.includes('cerrad') || status.includes('settled')) {\n return 'completed';\n }\n if (status.includes('process') || status.includes('confirm')) {\n return 'processing';\n }\n\n return 'pending';\n}\n\nfunction deriveStelPaymentStatus(raw: StelSalesOrder): PaymentStatus {\n const orderStatus = deriveStelOrderStatus(raw);\n\n if (orderStatus === 'completed') {\n return 'paid';\n }\n if (orderStatus === 'cancelled') {\n return 'pending';\n }\n\n return 'pending';\n}\n\nfunction deriveStelFulfillmentStatus(raw: StelSalesOrder): FulfillmentStatus {\n const orderStatus = deriveStelOrderStatus(raw);\n\n if (orderStatus === 'completed') {\n return 'fulfilled';\n }\n\n return 'unfulfilled';\n}\n\nfunction transformStelDocumentLine(\n line: StelDocumentLine,\n index: number,\n currencyCode: string,\n): OrderItem {\n const unitPrice = line['item-base-price'] ?? 0;\n const quantity = line.units ?? 1;\n const lineTotal = unitPrice * quantity;\n\n return {\n id: toStelStringId(line['item-id'] ?? index),\n title: line['item-name'] ?? '',\n variantTitle: undefined,\n quantity,\n price: transformStelMoney(unitPrice, currencyCode),\n total: transformStelMoney(lineTotal, currencyCode),\n sku: undefined,\n productId: line['item-id'] ? toStelStringId(line['item-id']) : undefined,\n };\n}\n\nexport function transformStelSalesOrder(raw: StelSalesOrder, currencyCode: string): Order {\n const id = toStelStringId(raw.id);\n const now = new Date().toISOString();\n const items = (raw['document-lines'] ?? [])\n .filter((line) => line['line-type'] === 'ITEM' || !line['line-type'])\n .map((line, i) => transformStelDocumentLine(line, i, currencyCode));\n\n const status = deriveStelOrderStatus(raw);\n\n return {\n id,\n orderNumber: raw.reference ?? id,\n email: raw.email ?? '',\n status,\n paymentStatus: deriveStelPaymentStatus(raw),\n fulfillmentStatus: deriveStelFulfillmentStatus(raw),\n customerId: raw['client-id'] ? toStelStringId(raw['client-id']) : undefined,\n items,\n subtotal: transformStelMoney(raw['total-base'], currencyCode),\n total: transformStelMoney(raw.total, currencyCode),\n tax: raw['total-tax'] != null ? transformStelMoney(raw['total-tax'], currencyCode) : undefined,\n createdAt: normalizeStelDate(raw['creation-date']),\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']) || now,\n cancelledAt: status === 'cancelled' ? normalizeStelDate(raw['utc-last-modification-date']) : undefined,\n completedAt: status === 'completed' ? normalizeStelDate(raw['utc-last-modification-date']) : undefined,\n metadata: {\n stelReference: raw.reference,\n stelStatus: raw.status,\n stelPaymentOptionId: raw['payment-option-id'],\n stelPaymentTermId: raw['payment-term-id'],\n stelDeliveryOptionId: raw['delivery-option-id'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Payment / delivery transforms\n// ---------------------------------------------------------------------------\n\nfunction inferPaymentMethodType(name: string | null | undefined): PaymentMethodType {\n if (!name) {\n return 'other';\n }\n\n const lower = name.toLowerCase();\n\n if (lower.includes('transfer') || lower.includes('bank') || lower.includes('sepa') || lower.includes('iban')) {\n return 'bank_transfer';\n }\n if (lower.includes('card') || lower.includes('tarjeta') || lower.includes('visa') || lower.includes('master')) {\n return 'card';\n }\n if (lower.includes('paypal') || lower.includes('wallet') || lower.includes('apple') || lower.includes('google')) {\n return 'wallet';\n }\n if (lower.includes('cash') || lower.includes('contrar') || lower.includes('efectivo') || lower.includes('cod')) {\n return 'cash_on_delivery';\n }\n if (lower.includes('crypto') || lower.includes('bitcoin')) {\n return 'crypto';\n }\n\n return 'other';\n}\n\nexport function transformStelPaymentOption(raw: StelPaymentOption): PaymentMethod {\n return {\n id: toStelStringId(raw.id),\n name: raw.name ?? 'Payment Option',\n type: inferPaymentMethodType(raw.name),\n isEnabled: !raw.deleted,\n requiresSetup: false,\n description: raw.description ?? undefined,\n metadata: {\n stelPath: raw.path,\n source: 'paymentOption',\n },\n };\n}\n\nexport function transformStelDeliveryOption(raw: StelDeliveryOption, currencyCode: string): ShippingMethod {\n return {\n id: toStelStringId(raw.id),\n name: raw.name ?? 'Delivery Option',\n price: transformStelMoney(0, currencyCode),\n description: raw.description ?? undefined,\n };\n}\n","import type { ProviderConfig } from '../../types/provider';\nimport { ConfigurationError, ProviderAPIError, extractErrorMessage } from '../../core/errors';\nimport { fetchWithRetry, type RetryConfig } from '../../core/fetch-utils';\nimport { createLogger, type Logger } from '../../core/logger';\nimport { normalizeStelCollection, normalizeStelEntity } from './transforms';\n\ntype FetchImplementation = (url: string, init?: RequestInit) => Promise<Response>;\ntype HttpMethod = 'DELETE' | 'GET' | 'POST' | 'PUT';\n\nexport type StelQueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean>;\n\nexport type StelQueryParams = Record<string, StelQueryValue>;\n\nexport interface StelOrderProviderConfig extends ProviderConfig {\n baseUrl: string;\n apiKey?: string;\n publishableKey?: string;\n currencyCode?: string;\n companyName?: string;\n storefrontId?: string;\n retry?: RetryConfig;\n}\n\ntype RequiredRetryConfig = Required<RetryConfig>;\n\nconst DEFAULT_RETRY_CONFIG: RequiredRetryConfig = {\n maxRetries: 2,\n initialDelayMs: 300,\n backoffMultiplier: 2,\n maxDelayMs: 5000,\n timeoutMs: 10000,\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction calculateDelay(attempt: number, retryConfig: RequiredRetryConfig): number {\n const delay = retryConfig.initialDelayMs * Math.pow(retryConfig.backoffMultiplier, attempt);\n return Math.min(delay, retryConfig.maxDelayMs);\n}\n\nfunction isRetryableError(error: unknown, retryConfig: RequiredRetryConfig): boolean {\n if (error instanceof ProviderAPIError) {\n return typeof error.status === 'number' && retryConfig.retryableStatusCodes.includes(error.status);\n }\n\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n message.includes('fetch failed') ||\n message.includes('timeout') ||\n message.includes('econnrefused') ||\n message.includes('etimedout')\n );\n}\n\nfunction createRetryingFetch(\n fetchImplementation: FetchImplementation,\n retryConfig: RequiredRetryConfig,\n logger: Logger,\n): FetchImplementation {\n return async (url: string, init?: RequestInit): Promise<Response> => {\n let lastError: unknown = new Error('Unknown STEL Order request error');\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt += 1) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), retryConfig.timeoutMs);\n\n try {\n const response = await fetchImplementation(url, {\n ...init,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok && retryConfig.retryableStatusCodes.includes(response.status)) {\n throw new ProviderAPIError(\n `STEL Order API error: ${response.status} ${response.statusText}`,\n 'stelorder',\n response.status,\n );\n }\n\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n lastError = error;\n\n if (attempt >= retryConfig.maxRetries || !isRetryableError(error, retryConfig)) {\n throw error;\n }\n\n const delay = calculateDelay(attempt, retryConfig);\n logger.warn('STEL request failed, retrying.', {\n url,\n attempt: attempt + 1,\n maxAttempts: retryConfig.maxRetries + 1,\n nextRetryIn: delay,\n error: extractErrorMessage(error),\n });\n\n await sleep(delay);\n }\n }\n\n throw lastError;\n };\n}\n\nasync function parseErrorResponse(response: Response): Promise<string> {\n const contentType = response.headers.get('content-type') ?? '';\n\n try {\n if (contentType.includes('application/json')) {\n const body = (await response.json()) as unknown;\n const message = extractErrorMessage(body);\n if (message && message !== 'An unknown error occurred') {\n return message;\n }\n }\n } catch {\n // Ignore body parsing issues and fall back to text/status.\n }\n\n try {\n const text = await response.text();\n if (text.trim()) {\n return text.trim();\n }\n } catch {\n // Ignore body parsing issues and fall back to status.\n }\n\n return `STEL Order API error: ${response.status} ${response.statusText}`;\n}\n\nexport function normalizeStelApiBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim();\n\n if (!trimmed) {\n throw new ConfigurationError('Stel Order baseUrl is required.');\n }\n\n const normalized = trimmed\n .replace(/\\/api\\/openapi\\.json$/i, '')\n .replace(/\\/+$/, '');\n\n return normalized.endsWith('/app') ? normalized : `${normalized}/app`;\n}\n\ninterface StelRequestOptions {\n method: HttpMethod;\n path: string;\n query?: StelQueryParams;\n body?: unknown;\n headers?: HeadersInit;\n}\n\nexport class StelOrderClient {\n readonly apiBaseUrl: string;\n\n private readonly apiKey: string;\n private readonly logger: Logger;\n private readonly retryConfig: RequiredRetryConfig;\n private readonly fetchImplementation?: FetchImplementation;\n\n constructor(config: StelOrderProviderConfig) {\n const apiKey = config.apiKey ?? config.publishableKey;\n\n if (!apiKey) {\n throw new ConfigurationError(\n 'Stel Order API key is required. Pass `apiKey` or `publishableKey` to createProvider().',\n );\n }\n\n this.apiBaseUrl = normalizeStelApiBaseUrl(config.baseUrl);\n this.apiKey = apiKey;\n this.logger = createLogger('StelOrderClient', config.debug);\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config.retry,\n };\n this.fetchImplementation = config.customFetch\n ? createRetryingFetch(config.customFetch, this.retryConfig, this.logger)\n : undefined;\n\n this.logger.info('Initializing Stel Order client', {\n apiBaseUrl: this.apiBaseUrl,\n retryConfig: this.retryConfig,\n });\n }\n\n async list<T>(resource: string, query?: StelQueryParams): Promise<T[]> {\n const payload = await this.request<T | T[]>({\n method: 'GET',\n path: resource,\n query,\n });\n\n return normalizeStelCollection(payload);\n }\n\n async getOne<T>(resource: string, id: string | number, query?: StelQueryParams): Promise<T | undefined> {\n const payload = await this.request<T | T[]>({\n method: 'GET',\n path: `${resource}/${id}`,\n query,\n });\n\n return normalizeStelEntity(payload);\n }\n\n async create<TResponse, TBody = unknown>(resource: string, body: TBody): Promise<TResponse> {\n return this.request<TResponse>({\n method: 'POST',\n path: resource,\n body,\n });\n }\n\n async update<TResponse, TBody = unknown>(resource: string, id: string | number, body: TBody): Promise<TResponse> {\n return this.request<TResponse>({\n method: 'PUT',\n path: `${resource}/${id}`,\n body,\n });\n }\n\n async remove(resource: string, id: string | number): Promise<void> {\n await this.request<void>({\n method: 'DELETE',\n path: `${resource}/${id}`,\n });\n }\n\n private buildUrl(path: string, query?: StelQueryParams): string {\n const normalizedPath = path.replace(/^\\/+/, '');\n const url = new URL(`${this.apiBaseUrl}/${normalizedPath}`);\n\n if (!query) {\n return url.toString();\n }\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null || value === '') {\n continue;\n }\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.map(String).join(','));\n continue;\n }\n\n url.searchParams.set(key, String(value));\n }\n\n return url.toString();\n }\n\n private buildHeaders(headers?: HeadersInit, hasBody: boolean = false): Headers {\n const normalizedHeaders = new Headers(headers);\n\n normalizedHeaders.set('Accept', 'application/json');\n normalizedHeaders.set('APIKEY', this.apiKey);\n\n if (hasBody && !normalizedHeaders.has('Content-Type')) {\n normalizedHeaders.set('Content-Type', 'application/json');\n }\n\n return normalizedHeaders;\n }\n\n private async executeFetch(url: string, init: RequestInit): Promise<Response> {\n if (this.fetchImplementation) {\n return this.fetchImplementation(url, init);\n }\n\n return fetchWithRetry(url, init, this.retryConfig);\n }\n\n private async request<TResponse>(options: StelRequestOptions): Promise<TResponse> {\n const url = this.buildUrl(options.path, options.query);\n const hasBody = options.body !== undefined;\n\n this.logger.debug('STEL request', {\n method: options.method,\n url,\n });\n\n const response = await this.executeFetch(url, {\n method: options.method,\n headers: this.buildHeaders(options.headers, hasBody),\n body: hasBody ? JSON.stringify(options.body) : undefined,\n });\n\n if (!response.ok) {\n const message = await parseErrorResponse(response);\n throw new ProviderAPIError(message, 'stelorder', response.status);\n }\n\n if (response.status === 204) {\n return undefined as TResponse;\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as TResponse;\n }\n\n return (await response.text()) as TResponse;\n }\n}\n","import type {\n BackendCapabilities,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n Country,\n Customer,\n FulfillmentOption,\n GetCategoriesOptions,\n GetCollectionsOptions,\n GetCustomersOptions,\n GetOrdersOptions,\n GetProductsOptions,\n InventoryLevel,\n Order,\n PaymentMethod,\n PaymentMethodsOptions,\n Product,\n ProductCategory,\n ShippingMethod,\n StockLocation,\n StockValidation,\n StorefrontContext,\n} from '@thorprovider/types';\nimport type { CommerceProvider } from '../../types/provider';\nimport { STELORDER_CAPABILITIES } from '../../types/capabilities.types';\nimport { ProviderAPIError } from '../../core/errors';\nimport { createLogger } from '../../core/logger';\nimport { StelOrderClient, type StelOrderProviderConfig } from './client';\nimport {\n buildStelHandle,\n transformStelCategory,\n transformStelCategoryToCollection,\n transformStelClient,\n transformStelDeliveryOption,\n transformStelPaymentOption,\n transformStelProduct,\n transformStelProductWarehouseToInventoryLevel,\n transformStelSalesOrder,\n transformStelWarehouseToStockLocation,\n type StelClient,\n type StelDeliveryOption,\n type StelPaymentOption,\n type StelProduct,\n type StelProductCategory,\n type StelSalesOrder,\n type StelWarehouse,\n} from './transforms';\n\nexport type { StelOrderProviderConfig } from './client';\nexport { StelOrderClient } from './client';\nexport * from './transforms';\n\nexport class StelOrderProvider implements CommerceProvider {\n readonly name = 'stelorder';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = STELORDER_CAPABILITIES;\n\n private readonly client: StelOrderClient;\n private readonly logger: ReturnType<typeof createLogger>;\n private readonly currencyCode: string;\n private readonly storefrontId: string;\n private readonly companyName: string;\n\n constructor(config: StelOrderProviderConfig) {\n this.client = new StelOrderClient(config);\n this.logger = createLogger('StelOrderProvider', config.debug);\n this.currencyCode = config.currencyCode ?? 'USD';\n this.storefrontId = config.storefrontId ?? 'stelorder-primary';\n this.companyName = config.companyName ?? 'Stel Order';\n\n this.logger.info('Initializing Stel Order provider', {\n storefrontId: this.storefrontId,\n companyName: this.companyName,\n currencyCode: this.currencyCode,\n });\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n async getProduct(handle: string, _options?: { regionId?: string }): Promise<Product | undefined> {\n this.logger.debug('getProduct', { handle });\n\n try {\n // Attempt direct ID lookup if handle looks numeric\n if (/^\\d+$/.test(handle)) {\n const raw = await this.client.getOne<StelProduct>('products', handle);\n return raw ? transformStelProduct(raw, this.currencyCode) : undefined;\n }\n\n // Otherwise scan products to match by handle (slugified full-reference)\n const rawProducts = await this.client.list<StelProduct>('products', { limit: 100 });\n\n for (const raw of rawProducts) {\n const productHandle = buildStelHandle(raw['full-reference'], raw.reference, raw.name, raw.id);\n if (productHandle === handle) {\n return transformStelProduct(raw, this.currencyCode);\n }\n }\n\n return undefined;\n } catch (error) {\n this.logger.error('getProduct failed', { handle, error });\n throw this.wrapError('getProduct', error);\n }\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n this.logger.debug('getProducts', { options });\n\n try {\n const query: Record<string, string | number | boolean> = {};\n\n if (options?.first) {\n query.limit = options.first;\n }\n if (options?.skip) {\n query.start = options.skip;\n }\n if (typeof options?.after === 'number') {\n query.start = options.after;\n }\n if (options?.sortKey) {\n query.sort = options.reverse ? `-${options.sortKey}` : options.sortKey;\n }\n if (options?.categoryIds?.length) {\n query['product-category-id'] = `in:${options.categoryIds.join(',')}`;\n }\n\n const rawProducts = await this.client.list<StelProduct>('products', query);\n\n let products = rawProducts\n .filter((p) => !p.deleted && !p.inactive)\n .map((p) => transformStelProduct(p, this.currencyCode));\n\n // Client-side text search (STEL has no fulltext search)\n if (options?.query) {\n const needle = options.query.toLowerCase();\n products = products.filter(\n (p) =>\n p.title.toLowerCase().includes(needle) ||\n p.description.toLowerCase().includes(needle) ||\n p.handle.includes(needle),\n );\n }\n\n return products;\n } catch (error) {\n this.logger.error('getProducts failed', { options, error });\n throw this.wrapError('getProducts', error);\n }\n }\n\n async getProductRecommendations(_productId: string): Promise<Product[]> {\n // STEL has no recommendation engine — return empty array\n return [];\n }\n\n // ============================================\n // Category Operations\n // ============================================\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n this.logger.debug('getCategory', { idOrHandle });\n\n try {\n // Direct ID lookup\n if (/^\\d+$/.test(idOrHandle)) {\n const raw = await this.client.getOne<StelProductCategory>('productCategories', idOrHandle);\n return raw ? transformStelCategory(raw) : undefined;\n }\n\n // Scan by handle\n const rawCategories = await this.client.list<StelProductCategory>('productCategories');\n\n for (const raw of rawCategories) {\n const catHandle = buildStelHandle(raw.slug, raw.name, raw.id);\n if (catHandle === idOrHandle) {\n return transformStelCategory(raw);\n }\n }\n\n return undefined;\n } catch (error) {\n this.logger.error('getCategory failed', { idOrHandle, error });\n throw this.wrapError('getCategory', error);\n }\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n this.logger.debug('getCategories', { options });\n\n try {\n if (options?.customFetcher) {\n return options.customFetcher(options);\n }\n\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.parentCategoryId) {\n query['parent-category-id'] = options.parentCategoryId;\n }\n\n const rawCategories = await this.client.list<StelProductCategory>('productCategories', query);\n let categories = rawCategories\n .filter((c) => !c.deleted)\n .map(transformStelCategory);\n\n if (options?.query) {\n const needle = options.query.toLowerCase();\n categories = categories.filter(\n (c) =>\n c.name.toLowerCase().includes(needle) ||\n c.handle.includes(needle),\n );\n }\n\n return categories;\n } catch (error) {\n this.logger.error('getCategories failed', { options, error });\n throw this.wrapError('getCategories', error);\n }\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n this.logger.debug('getCategoryProducts', { handle, options });\n\n try {\n const category = await this.getCategory(handle);\n\n if (!category) {\n return [];\n }\n\n return this.getProducts({\n categoryIds: [category.id],\n first: options?.first,\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n after: options?.after,\n });\n } catch (error) {\n this.logger.error('getCategoryProducts failed', { handle, error });\n throw this.wrapError('getCategoryProducts', error);\n }\n }\n\n // ============================================\n // Collection Operations (alias categories)\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n this.logger.debug('getCollection', { handle });\n\n try {\n if (/^\\d+$/.test(handle)) {\n const raw = await this.client.getOne<StelProductCategory>('productCategories', handle);\n return raw ? transformStelCategoryToCollection(raw) : undefined;\n }\n\n const rawCategories = await this.client.list<StelProductCategory>('productCategories');\n\n for (const raw of rawCategories) {\n const catHandle = buildStelHandle(raw.slug, raw.name, raw.id);\n if (catHandle === handle) {\n return transformStelCategoryToCollection(raw);\n }\n }\n\n return undefined;\n } catch (error) {\n this.logger.error('getCollection failed', { handle, error });\n throw this.wrapError('getCollection', error);\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n this.logger.debug('getCollections', { options });\n\n try {\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n\n const rawCategories = await this.client.list<StelProductCategory>('productCategories', query);\n let collections = rawCategories\n .filter((c) => !c.deleted)\n .map(transformStelCategoryToCollection);\n\n if (options?.query) {\n const needle = options.query.toLowerCase();\n collections = collections.filter(\n (c) =>\n c.title.toLowerCase().includes(needle) ||\n c.handle.includes(needle),\n );\n }\n\n return collections;\n } catch (error) {\n this.logger.error('getCollections failed', { options, error });\n throw this.wrapError('getCollections', error);\n }\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n return this.getCategoryProducts(handle, options);\n }\n\n // ============================================\n // Inventory Operations\n // ============================================\n\n async getStockLocations(_params?: { salesChannelId?: string }): Promise<StockLocation[]> {\n this.logger.debug('getStockLocations');\n\n try {\n const rawWarehouses = await this.client.list<StelWarehouse>('warehouses');\n return rawWarehouses\n .filter((w) => !w.deleted)\n .map(transformStelWarehouseToStockLocation);\n } catch (error) {\n this.logger.error('getStockLocations failed', { error });\n throw this.wrapError('getStockLocations', error);\n }\n }\n\n async checkInventoryLevels(variantId: string, _salesChannelId?: string): Promise<InventoryLevel[]> {\n this.logger.debug('checkInventoryLevels', { variantId });\n\n try {\n // variantId is the product ID (single synthetic variant per product)\n const raw = await this.client.getOne<StelProduct>('products', variantId);\n\n if (!raw?.['product-warehouses']?.length) {\n return [];\n }\n\n return raw['product-warehouses'].map(transformStelProductWarehouseToInventoryLevel);\n } catch (error) {\n this.logger.error('checkInventoryLevels failed', { variantId, error });\n throw this.wrapError('checkInventoryLevels', error);\n }\n }\n\n validateCartStock(_cartId: string): Promise<StockValidation> {\n return this.notSupported('validateCartStock');\n }\n\n getFulfillmentOptions(_cartId: string, _salesChannelId: string): Promise<FulfillmentOption[]> {\n return this.notSupported('getFulfillmentOptions');\n }\n\n // ============================================\n // Cart Operations (unsupported — STEL is ERP, not storefront)\n // ============================================\n\n createCart(_options?: { regionId?: string }): Promise<Cart> {\n return this.notSupported('createCart');\n }\n\n getCart(_cartId: string): Promise<Cart | undefined> {\n return this.notSupported('getCart');\n }\n\n addToCart(_cartId: string, _lines: CartLineInput[]): Promise<Cart> {\n return this.notSupported('addToCart');\n }\n\n removeFromCart(_cartId: string, _lineIds: string[]): Promise<Cart> {\n return this.notSupported('removeFromCart');\n }\n\n updateCart(_cartId: string, _lines: CartLineUpdate[]): Promise<Cart> {\n return this.notSupported('updateCart');\n }\n\n // ============================================\n // Checkout Operations (unsupported)\n // ============================================\n\n completeCheckout(_cartId: string): Promise<Order> {\n return this.notSupported('completeCheckout');\n }\n\n getRegionCountries(_regionId: string): Promise<Country[]> {\n return this.notSupported('getRegionCountries');\n }\n\n addShippingMethod(_cartId: string, _methodId: string): Promise<Cart> {\n return this.notSupported('addShippingMethod');\n }\n\n initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n return this.notSupported('initiatePaymentSession');\n }\n\n applyDiscountCode(_cartId: string, _code: string): Promise<Cart> {\n return this.notSupported('applyDiscountCode');\n }\n\n removeDiscountCode(_cartId: string, _code: string): Promise<Cart> {\n return this.notSupported('removeDiscountCode');\n }\n\n // ============================================\n // Payment Methods\n // ============================================\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n this.logger.debug('getPaymentMethods');\n\n try {\n const rawOptions = await this.client.list<StelPaymentOption>('paymentOptions');\n return rawOptions\n .filter((o) => !o.deleted)\n .map(transformStelPaymentOption);\n } catch (error) {\n this.logger.error('getPaymentMethods failed', { error });\n throw this.wrapError('getPaymentMethods', error);\n }\n }\n\n // ============================================\n // Shipping / Delivery Methods\n // ============================================\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n this.logger.debug('getShippingMethods (delivery options listing)');\n\n try {\n const rawOptions = await this.client.list<StelDeliveryOption>('deliveryOptions');\n return rawOptions\n .filter((o) => !o.deleted)\n .map((o) => transformStelDeliveryOption(o, this.currencyCode));\n } catch (error) {\n this.logger.error('getShippingMethods failed', { error });\n throw this.wrapError('getShippingMethods', error);\n }\n }\n\n // ============================================\n // Customer Operations (optional)\n // ============================================\n\n async getCustomer(customerId: string): Promise<Customer | undefined> {\n this.logger.debug('getCustomer', { customerId });\n\n try {\n const raw = await this.client.getOne<StelClient>('clients', customerId);\n return raw ? transformStelClient(raw) : undefined;\n } catch (error) {\n this.logger.error('getCustomer failed', { customerId, error });\n throw this.wrapError('getCustomer', error);\n }\n }\n\n async getCustomers(options?: GetCustomersOptions): Promise<Customer[]> {\n this.logger.debug('getCustomers', { options });\n\n try {\n if (options?.customFetcher) {\n return options.customFetcher(options);\n }\n\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.offset) {\n query.start = options.offset;\n }\n\n const rawClients = await this.client.list<StelClient>('clients', query);\n let customers = rawClients\n .filter((c) => !c.deleted)\n .map(transformStelClient);\n\n // Client-side search (STEL has no fulltext search for clients)\n if (options?.search) {\n const needle = options.search.toLowerCase();\n customers = customers.filter(\n (c) =>\n c.email.toLowerCase().includes(needle) ||\n (c.firstName ?? '').toLowerCase().includes(needle) ||\n (c.lastName ?? '').toLowerCase().includes(needle),\n );\n }\n\n return customers;\n } catch (error) {\n this.logger.error('getCustomers failed', { options, error });\n throw this.wrapError('getCustomers', error);\n }\n }\n\n async updateCustomer(\n customerId: string,\n data: Partial<Omit<Customer, 'id' | 'createdAt'>>,\n ): Promise<Customer> {\n this.logger.debug('updateCustomer', { customerId, data });\n\n try {\n const stelPayload: Record<string, unknown> = {};\n\n if (data.firstName || data.lastName) {\n stelPayload.name = [data.firstName, data.lastName].filter(Boolean).join(' ');\n }\n if (data.email) {\n stelPayload.email = data.email;\n }\n if (data.phone) {\n stelPayload.phone = data.phone;\n }\n\n const raw = await this.client.update<StelClient>('clients', customerId, stelPayload);\n return transformStelClient(raw);\n } catch (error) {\n this.logger.error('updateCustomer failed', { customerId, error });\n throw this.wrapError('updateCustomer', error);\n }\n }\n\n // ============================================\n // Order Operations (optional)\n // ============================================\n\n async getOrder(orderId: string): Promise<Order | undefined> {\n this.logger.debug('getOrder', { orderId });\n\n try {\n const raw = await this.client.getOne<StelSalesOrder>('salesOrders', orderId);\n return raw ? transformStelSalesOrder(raw, this.currencyCode) : undefined;\n } catch (error) {\n this.logger.error('getOrder failed', { orderId, error });\n throw this.wrapError('getOrder', error);\n }\n }\n\n async getOrders(options: GetOrdersOptions): Promise<Order[]> {\n this.logger.debug('getOrders', { options });\n\n try {\n if (options?.customFetcher) {\n return options.customFetcher(options);\n }\n\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.offset) {\n query.start = options.offset;\n }\n if (options?.customerId) {\n query['client-id'] = options.customerId;\n }\n\n const rawOrders = await this.client.list<StelSalesOrder>('salesOrders', query);\n return rawOrders\n .filter((o) => !o.deleted)\n .map((o) => transformStelSalesOrder(o, this.currencyCode));\n } catch (error) {\n this.logger.error('getOrders failed', { options, error });\n throw this.wrapError('getOrders', error);\n }\n }\n\n async getAdminOrders(options?: {\n search?: string;\n status?: string | string[];\n limit?: number;\n offset?: number;\n }): Promise<{ orders: Order[]; count: number }> {\n this.logger.debug('getAdminOrders', { options });\n\n try {\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.offset) {\n query.start = options.offset;\n }\n\n const rawOrders = await this.client.list<StelSalesOrder>('salesOrders', query);\n let orders = rawOrders\n .filter((o) => !o.deleted)\n .map((o) => transformStelSalesOrder(o, this.currencyCode));\n\n if (options?.search) {\n const needle = options.search.toLowerCase();\n orders = orders.filter(\n (o) =>\n o.orderNumber.toLowerCase().includes(needle) ||\n o.email.toLowerCase().includes(needle),\n );\n }\n\n if (options?.status) {\n const statuses = Array.isArray(options.status) ? options.status : [options.status];\n orders = orders.filter((o) => statuses.includes(o.status));\n }\n\n return { orders, count: orders.length };\n } catch (error) {\n this.logger.error('getAdminOrders failed', { options, error });\n throw this.wrapError('getAdminOrders', error);\n }\n }\n\n cancelOrder(_orderId: string): Promise<Order> {\n return this.notSupported('cancelOrder');\n }\n\n createFulfillment(_orderId: string, _items?: Array<{ id: string; quantity: number }>): Promise<void> {\n return this.notSupported('createFulfillment');\n }\n\n createRefund(_orderId: string, _amount?: number, _reason?: string): Promise<void> {\n return this.notSupported('createRefund');\n }\n\n // ============================================\n // Storefront Context\n // ============================================\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.storefrontId,\n name: this.companyName,\n platformType: 'stelorder',\n requiresProductScoping: false,\n currencyCode: this.currencyCode,\n metadata: {\n apiBaseUrl: this.client.apiBaseUrl,\n singleCompany: true,\n providerVersion: this.version,\n },\n };\n }\n\n isStorefrontRequired(): boolean {\n return false;\n }\n\n // ============================================\n // Internal helpers\n // ============================================\n\n private notSupported<T>(operation: string): Promise<T> {\n return Promise.reject(\n new ProviderAPIError(\n `Stel Order does not support \\`${operation}\\`. STEL is an ERP adapter without cart/checkout/auth capabilities.`,\n 'stelorder',\n 501,\n ),\n );\n }\n\n private wrapError(operation: string, error: unknown): Error {\n if (error instanceof ProviderAPIError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return new ProviderAPIError(\n `Stel Order \\`${operation}\\` failed: ${message}`,\n 'stelorder',\n 500,\n );\n }\n}\n","import type {\n Cart,\n CartItem,\n Collection,\n Country,\n FulfillmentOption,\n Image,\n InventoryLevel,\n Money,\n Order,\n PaymentMethod,\n Product,\n ProductCategory,\n Region,\n SelectedOption,\n ShippingMethod,\n StockLocation,\n StockStatus,\n StockValidation,\n} from '@thorprovider/types';\n\nconst FIXTURE_TIMESTAMP = '2026-01-01T00:00:00.000Z';\nconst DEFAULT_SITE_URL = 'https://mock.thorcommerce.local';\n\ninterface MockRegionFixture {\n id: string;\n name: string;\n currencyCode: string;\n locale?: string;\n taxRate?: number;\n countries: Country[];\n}\n\ninterface MockCollectionFixture {\n id: string;\n handle: string;\n title: string;\n description: string;\n}\n\ninterface MockCategoryFixture {\n id: string;\n handle: string;\n name: string;\n description: string;\n parentCategoryId?: string;\n}\n\ninterface MockVariantFixture {\n id: string;\n title: string;\n price: number;\n compareAtPrice?: number;\n quantityAvailable: number;\n selectedOptions: SelectedOption[];\n}\n\ninterface MockProductFixture {\n id: string;\n handle: string;\n title: string;\n description: string;\n imageLabel: string;\n imageHue: number;\n collectionHandles: string[];\n categoryHandle: string;\n productType: string;\n vendor: string;\n tags: string[];\n options: Array<{ id: string; name: string; values: string[] }>;\n variants: MockVariantFixture[];\n}\n\nexport interface MockCartState {\n id: string;\n regionId?: string;\n lines: Array<{\n id: string;\n merchandiseId: string;\n quantity: number;\n }>;\n shippingMethodId?: string;\n paymentProviderId?: string;\n discountCode?: string;\n completedAt?: string;\n}\n\nconst regionFixtures: MockRegionFixture[] = [\n {\n id: 'mock-region-us',\n name: 'United States',\n currencyCode: 'USD',\n locale: 'en-US',\n taxRate: 0.08,\n countries: [{ code: 'US', name: 'United States' }],\n },\n {\n id: 'mock-region-eu',\n name: 'Europe',\n currencyCode: 'EUR',\n locale: 'en-ES',\n taxRate: 0.21,\n countries: [\n { code: 'ES', name: 'Spain' },\n { code: 'FR', name: 'France' },\n { code: 'DE', name: 'Germany' },\n ],\n },\n];\n\nconst collectionFixtures: MockCollectionFixture[] = [\n {\n id: 'mock-collection-new-arrivals',\n handle: 'new-arrivals',\n title: 'New Arrivals',\n description: 'Fresh mock catalog items for layout and merchandising flows.',\n },\n {\n id: 'mock-collection-best-sellers',\n handle: 'best-sellers',\n title: 'Best Sellers',\n description: 'High-performing mock products used to design hero grids and featured sections.',\n },\n {\n id: 'mock-collection-studio-essentials',\n handle: 'studio-essentials',\n title: 'Studio Essentials',\n description: 'A balanced fixture set for mock storefront navigation and detail pages.',\n },\n];\n\nconst categoryFixtures: MockCategoryFixture[] = [\n {\n id: 'mock-category-jackets',\n handle: 'jackets',\n name: 'Jackets',\n description: 'Outerwear and layering pieces.',\n },\n {\n id: 'mock-category-dresses',\n handle: 'dresses',\n name: 'Dresses',\n description: 'Editorial silhouettes for seasonal collections.',\n },\n {\n id: 'mock-category-home',\n handle: 'home',\n name: 'Home',\n description: 'Decor and living objects for lifestyle layouts.',\n },\n {\n id: 'mock-category-accessories',\n handle: 'accessories',\n name: 'Accessories',\n description: 'Complementary products for cart and bundle flows.',\n },\n];\n\nconst productFixtures: MockProductFixture[] = [\n {\n id: 'mock-product-aurora-jacket',\n handle: 'aurora-jacket',\n title: 'Aurora Quilted Jacket',\n description: 'Lightweight quilted outerwear with tonal hardware and a soft structured collar.',\n imageLabel: 'Aurora Jacket',\n imageHue: 222,\n collectionHandles: ['new-arrivals', 'best-sellers'],\n categoryHandle: 'jackets',\n productType: 'outerwear',\n vendor: 'Thor Atelier',\n tags: ['outerwear', 'quilted', 'winter'],\n options: [\n { id: 'aurora-size', name: 'Size', values: ['S', 'M', 'L'] },\n { id: 'aurora-color', name: 'Color', values: ['Midnight'] },\n ],\n variants: [\n {\n id: 'mock-variant-aurora-s',\n title: 'S / Midnight',\n price: 129,\n compareAtPrice: 159,\n quantityAvailable: 8,\n selectedOptions: [\n { name: 'Size', value: 'S' },\n { name: 'Color', value: 'Midnight' },\n ],\n },\n {\n id: 'mock-variant-aurora-m',\n title: 'M / Midnight',\n price: 129,\n compareAtPrice: 159,\n quantityAvailable: 12,\n selectedOptions: [\n { name: 'Size', value: 'M' },\n { name: 'Color', value: 'Midnight' },\n ],\n },\n ],\n },\n {\n id: 'mock-product-solis-dress',\n handle: 'solis-dress',\n title: 'Solis Pleated Dress',\n description: 'A fluid pleated dress with a clean neckline designed for hero storytelling.',\n imageLabel: 'Solis Dress',\n imageHue: 18,\n collectionHandles: ['new-arrivals', 'studio-essentials'],\n categoryHandle: 'dresses',\n productType: 'dress',\n vendor: 'Thor Atelier',\n tags: ['dress', 'occasion', 'pleated'],\n options: [\n { id: 'solis-size', name: 'Size', values: ['XS', 'S', 'M'] },\n { id: 'solis-color', name: 'Color', values: ['Clay'] },\n ],\n variants: [\n {\n id: 'mock-variant-solis-xs',\n title: 'XS / Clay',\n price: 164,\n quantityAvailable: 4,\n selectedOptions: [\n { name: 'Size', value: 'XS' },\n { name: 'Color', value: 'Clay' },\n ],\n },\n {\n id: 'mock-variant-solis-s',\n title: 'S / Clay',\n price: 164,\n quantityAvailable: 9,\n selectedOptions: [\n { name: 'Size', value: 'S' },\n { name: 'Color', value: 'Clay' },\n ],\n },\n ],\n },\n {\n id: 'mock-product-helios-lamp',\n handle: 'helios-lamp',\n title: 'Helios Table Lamp',\n description: 'Warm ambient lamp with sculptural proportions for lifestyle and home grids.',\n imageLabel: 'Helios Lamp',\n imageHue: 45,\n collectionHandles: ['best-sellers', 'studio-essentials'],\n categoryHandle: 'home',\n productType: 'lighting',\n vendor: 'Thor Home',\n tags: ['home', 'lighting', 'decor'],\n options: [{ id: 'helios-finish', name: 'Finish', values: ['Brass'] }],\n variants: [\n {\n id: 'mock-variant-helios-brass',\n title: 'Brass',\n price: 96,\n quantityAvailable: 15,\n selectedOptions: [{ name: 'Finish', value: 'Brass' }],\n },\n ],\n },\n {\n id: 'mock-product-luna-bag',\n handle: 'luna-bag',\n title: 'Luna Crossbody Bag',\n description: 'Compact everyday bag for accessory rails, checkout add-ons, and bundle modules.',\n imageLabel: 'Luna Bag',\n imageHue: 306,\n collectionHandles: ['studio-essentials'],\n categoryHandle: 'accessories',\n productType: 'bag',\n vendor: 'Thor Atelier',\n tags: ['bag', 'accessory', 'everyday'],\n options: [{ id: 'luna-color', name: 'Color', values: ['Berry'] }],\n variants: [\n {\n id: 'mock-variant-luna-berry',\n title: 'Berry',\n price: 82,\n quantityAvailable: 18,\n selectedOptions: [{ name: 'Color', value: 'Berry' }],\n },\n ],\n },\n];\n\nconst stockLocationFixture: StockLocation = {\n id: 'mock-stock-primary',\n name: 'Mock Main Warehouse',\n address: {\n address1: '100 Mock Avenue',\n city: 'Design City',\n countryCode: 'US',\n postalCode: '10001',\n province: 'NY',\n },\n metadata: {\n timezone: 'America/New_York',\n },\n};\n\nconst cartStore = new Map<string, MockCartState>();\nconst orderStore = new Map<string, Order>();\n\nlet sequence = 0;\n\nfunction nextId(prefix: string): string {\n sequence += 1;\n return `${prefix}-${sequence}`;\n}\n\nfunction createMoney(amount: number, currencyCode: string): Money {\n return {\n amount: amount.toFixed(2),\n currencyCode,\n };\n}\n\nfunction createImage(label: string, hue: number): Image {\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1200 1200\" role=\"img\" aria-label=\"${label}\">\n <defs>\n <linearGradient id=\"g\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"hsl(${hue}, 72%, 72%)\" />\n <stop offset=\"100%\" stop-color=\"hsl(${(hue + 48) % 360}, 62%, 42%)\" />\n </linearGradient>\n </defs>\n <rect width=\"1200\" height=\"1200\" fill=\"url(#g)\" rx=\"48\" />\n <circle cx=\"910\" cy=\"280\" r=\"180\" fill=\"rgba(255,255,255,0.22)\" />\n <text x=\"90\" y=\"990\" fill=\"white\" font-family=\"Arial, sans-serif\" font-size=\"96\" font-weight=\"700\">${label}</text>\n </svg>\n `.trim();\n\n return {\n url: `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`,\n altText: label,\n width: 1200,\n height: 1200,\n };\n}\n\nfunction getRegionFixture(regionId?: string): MockRegionFixture {\n if (!regionId) {\n return regionFixtures[0];\n }\n\n return regionFixtures.find((region) => region.id === regionId) ?? regionFixtures[0];\n}\n\nfunction createProductImageSet(label: string, hue: number): { featuredImage: Image; images: Image[] } {\n const featuredImage = createImage(label, hue);\n\n return {\n featuredImage,\n images: [featuredImage, createImage(`${label} Detail`, (hue + 18) % 360)],\n };\n}\n\nfunction buildCollections(): Collection[] {\n return collectionFixtures.map((collection) => ({\n id: collection.id,\n handle: collection.handle,\n title: collection.title,\n description: collection.description,\n path: `/collections/${collection.handle}`,\n updatedAt: FIXTURE_TIMESTAMP,\n }));\n}\n\nfunction buildCategories(): ProductCategory[] {\n return categoryFixtures.map((category) => ({\n id: category.id,\n handle: category.handle,\n name: category.name,\n description: category.description,\n parentCategoryId: category.parentCategoryId,\n productCount: productFixtures.filter((product) => product.categoryHandle === category.handle).length,\n image: createImage(category.name, 180).url,\n }));\n}\n\nfunction buildProducts(currencyCode: string): Product[] {\n const collections = buildCollections();\n\n return productFixtures.map((product) => {\n const { featuredImage, images } = createProductImageSet(product.imageLabel, product.imageHue);\n const variants = product.variants.map((variant) => ({\n id: variant.id,\n title: variant.title,\n availableForSale: variant.quantityAvailable > 0,\n selectedOptions: variant.selectedOptions,\n price: createMoney(variant.price, currencyCode),\n compareAtPrice: variant.compareAtPrice\n ? createMoney(variant.compareAtPrice, currencyCode)\n : undefined,\n quantityAvailable: variant.quantityAvailable,\n image: featuredImage,\n }));\n\n const prices = product.variants.map((variant) => variant.price);\n\n return {\n id: product.id,\n handle: product.handle,\n title: product.title,\n description: product.description,\n availableForSale: variants.some((variant) => variant.availableForSale),\n options: product.options,\n variants,\n featuredImage,\n images,\n priceRange: {\n minVariantPrice: createMoney(Math.min(...prices), currencyCode),\n maxVariantPrice: createMoney(Math.max(...prices), currencyCode),\n },\n collections: product.collectionHandles\n .map((handle) => collections.find((collection) => collection.handle === handle))\n .filter((collection): collection is Collection => Boolean(collection))\n .map((collection) => ({\n id: collection.id,\n title: collection.title,\n handle: collection.handle,\n })),\n productType: product.productType,\n vendor: product.vendor,\n tags: product.tags,\n createdAt: FIXTURE_TIMESTAMP,\n updatedAt: FIXTURE_TIMESTAMP,\n metadata: {\n categoryHandle: product.categoryHandle,\n collectionHandles: product.collectionHandles,\n },\n };\n });\n}\n\nfunction filterProducts(products: Product[], options: {\n query?: string;\n categoryIds?: string[];\n collectionIds?: string[];\n}): Product[] {\n const query = options.query?.trim().toLowerCase();\n const categoryIds = new Set(options.categoryIds ?? []);\n const collectionIds = new Set(options.collectionIds ?? []);\n\n return products.filter((product) => {\n if (query) {\n const matchesQuery = [product.title, product.description, ...(product.tags ?? [])]\n .join(' ')\n .toLowerCase()\n .includes(query);\n\n if (!matchesQuery) {\n return false;\n }\n }\n\n if (categoryIds.size > 0) {\n const categoryHandle = String(product.metadata?.categoryHandle ?? '');\n const category = categoryFixtures.find((item) => item.handle === categoryHandle);\n const matchesCategory = category\n ? categoryIds.has(category.id) || categoryIds.has(category.handle)\n : false;\n\n if (!matchesCategory) {\n return false;\n }\n }\n\n if (collectionIds.size > 0) {\n const productCollections = (product.collections ?? []).map((collection) => collection.handle);\n const matchesCollection = (product.collections ?? []).some(\n (collection) => collectionIds.has(collection.id) || collectionIds.has(collection.handle)\n ) || productCollections.some((handle) => collectionIds.has(handle));\n\n if (!matchesCollection) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nfunction sortProducts(products: Product[], sortKey?: string, reverse?: boolean): Product[] {\n const sorted = [...products];\n\n switch (sortKey) {\n case 'price':\n case 'price-asc':\n case 'price-desc':\n sorted.sort(\n (left, right) =>\n Number(left.priceRange.minVariantPrice.amount) - Number(right.priceRange.minVariantPrice.amount)\n );\n break;\n case 'created_at':\n case 'createdAt':\n case 'newest':\n sorted.sort((left, right) => left.createdAt.localeCompare(right.createdAt));\n break;\n case 'title':\n case 'name':\n default:\n sorted.sort((left, right) => left.title.localeCompare(right.title));\n break;\n }\n\n const shouldReverse = reverse || sortKey === 'price-desc' || sortKey === 'newest';\n return shouldReverse ? sorted.reverse() : sorted;\n}\n\nfunction paginateProducts(products: Product[], skip?: number, first?: number): Product[] {\n const start = Math.max(0, skip ?? 0);\n const end = first ? start + first : undefined;\n return products.slice(start, end);\n}\n\nfunction resolveVariant(currencyCode: string, merchandiseId: string): {\n product: Product;\n variant: Product['variants'][number];\n} | undefined {\n const products = buildProducts(currencyCode);\n\n for (const product of products) {\n const variant = product.variants.find((item) => item.id === merchandiseId);\n if (variant) {\n return { product, variant };\n }\n }\n\n return undefined;\n}\n\nfunction getShippingPrice(methodId: string | undefined): number {\n switch (methodId) {\n case 'mock-shipping-express':\n return 18;\n case 'mock-shipping-standard':\n return 8;\n default:\n return 0;\n }\n}\n\nfunction buildExternalCart(state: MockCartState, currencyCode: string, siteUrl: string): Cart {\n const region = getRegionFixture(state.regionId);\n const regionCurrency = region.currencyCode || currencyCode;\n\n const lines: CartItem[] = state.lines.flatMap((line) => {\n const resolved = resolveVariant(regionCurrency, line.merchandiseId);\n if (!resolved || !resolved.product.featuredImage) {\n return [];\n }\n\n const lineTotal = Number(resolved.variant.price.amount) * line.quantity;\n const stockStatus: StockStatus = resolved.variant.quantityAvailable && resolved.variant.quantityAvailable > 0\n ? 'in_stock'\n : 'out_of_stock';\n\n return [{\n id: line.id,\n quantity: line.quantity,\n stockStatus,\n cost: {\n totalAmount: createMoney(lineTotal, regionCurrency),\n },\n merchandise: {\n id: resolved.variant.id,\n title: resolved.variant.title,\n selectedOptions: resolved.variant.selectedOptions,\n product: {\n id: resolved.product.id,\n handle: resolved.product.handle,\n title: resolved.product.title,\n featuredImage: resolved.product.featuredImage,\n },\n },\n }];\n });\n\n const subtotal = lines.reduce(\n (sum, line) => sum + Number(line.cost.totalAmount.amount),\n 0\n );\n const shipping = getShippingPrice(state.shippingMethodId);\n const discount = state.discountCode ? subtotal * 0.1 : 0;\n const taxableBase = Math.max(subtotal + shipping - discount, 0);\n const totalTax = region.taxRate ? taxableBase * region.taxRate : 0;\n const total = taxableBase + totalTax;\n\n return {\n id: state.id,\n checkoutUrl: `${siteUrl}/checkout?cart=${state.id}`,\n cost: {\n subtotalAmount: createMoney(subtotal, regionCurrency),\n totalAmount: createMoney(total, regionCurrency),\n totalTaxAmount: createMoney(totalTax, regionCurrency),\n },\n lines,\n totalQuantity: lines.reduce((sum, line) => sum + line.quantity, 0),\n completedAt: state.completedAt,\n };\n}\n\nfunction buildOrderFromCart(state: MockCartState, currencyCode: string, siteUrl: string): Order {\n const cart = buildExternalCart(state, currencyCode, siteUrl);\n\n return {\n id: `mock-order-${state.id}`,\n orderNumber: `${1000 + sequence}`,\n email: 'mock-customer@thorprovider.dev',\n status: 'completed',\n paymentStatus: state.paymentProviderId ? 'paid' : 'pending',\n fulfillmentStatus: state.shippingMethodId ? 'fulfilled' : 'unfulfilled',\n items: cart.lines.map((line) => ({\n id: line.id ?? nextId('mock-order-line'),\n title: line.merchandise.product.title,\n variantTitle: line.merchandise.title,\n quantity: line.quantity,\n price: line.merchandise.product.featuredImage\n ? createMoney(Number(line.cost.totalAmount.amount) / Math.max(line.quantity, 1), cart.cost.totalAmount.currencyCode)\n : createMoney(0, cart.cost.totalAmount.currencyCode),\n total: line.cost.totalAmount,\n productId: line.merchandise.product.id,\n variantId: line.merchandise.id,\n image: line.merchandise.product.featuredImage,\n })),\n subtotal: cart.cost.subtotalAmount,\n total: cart.cost.totalAmount,\n tax: cart.cost.totalTaxAmount,\n shipping: createMoney(getShippingPrice(state.shippingMethodId), cart.cost.totalAmount.currencyCode),\n discount: createMoney(state.discountCode ? Number(cart.cost.subtotalAmount.amount) * 0.1 : 0, cart.cost.totalAmount.currencyCode),\n createdAt: FIXTURE_TIMESTAMP,\n updatedAt: FIXTURE_TIMESTAMP,\n completedAt: state.completedAt,\n metadata: {\n provider: 'mock',\n checkoutUrl: cart.checkoutUrl,\n },\n };\n}\n\nexport function getMockCollections(): Collection[] {\n return buildCollections();\n}\n\nexport function getMockCategories(): ProductCategory[] {\n return buildCategories();\n}\n\nexport function getMockProducts(options?: {\n currencyCode?: string;\n query?: string;\n sortKey?: string;\n reverse?: boolean;\n first?: number;\n skip?: number;\n categoryIds?: string[];\n collectionIds?: string[];\n regionId?: string;\n}): Product[] {\n const region = getRegionFixture(options?.regionId);\n const currencyCode = options?.currencyCode ?? region.currencyCode;\n const products = buildProducts(currencyCode);\n const filtered = filterProducts(products, {\n query: options?.query,\n categoryIds: options?.categoryIds,\n collectionIds: options?.collectionIds,\n });\n const sorted = sortProducts(filtered, options?.sortKey, options?.reverse);\n\n return paginateProducts(sorted, options?.skip, options?.first);\n}\n\nexport function getMockProduct(handle: string, regionId?: string): Product | undefined {\n const region = getRegionFixture(regionId);\n return buildProducts(region.currencyCode).find(\n (product) => product.handle === handle || product.id === handle\n );\n}\n\nexport function getMockProductRecommendations(productId: string, regionId?: string): Product[] {\n const product = getMockProduct(productId, regionId)\n ?? buildProducts(getRegionFixture(regionId).currencyCode).find((item) => item.id === productId);\n\n if (!product) {\n return [];\n }\n\n const collectionHandles = new Set((product.collections ?? []).map((collection) => collection.handle));\n\n return buildProducts(getRegionFixture(regionId).currencyCode)\n .filter((candidate) => candidate.id !== product.id)\n .filter((candidate) =>\n (candidate.collections ?? []).some((collection) => collectionHandles.has(collection.handle))\n )\n .slice(0, 4);\n}\n\nexport function getMockCollection(handle: string): Collection | undefined {\n return buildCollections().find(\n (collection) => collection.handle === handle || collection.id === handle\n );\n}\n\nexport function getMockCategory(idOrHandle: string): ProductCategory | undefined {\n return buildCategories().find(\n (category) => category.handle === idOrHandle || category.id === idOrHandle\n );\n}\n\nexport function getMockRegions(): Array<{\n id: string;\n name: string;\n currency_code: string;\n countries: Array<{ id: string; iso_2: string; name: string; display_name?: string }>;\n}> {\n return regionFixtures.map((region) => ({\n id: region.id,\n name: region.name,\n currency_code: region.currencyCode,\n countries: region.countries.map((country) => ({\n id: `country-${country.code.toLowerCase()}`,\n iso_2: country.code.toLowerCase(),\n name: country.name,\n display_name: country.name,\n })),\n }));\n}\n\nexport function getMockAdminRegions(): Region[] {\n return regionFixtures.map((region) => ({\n id: region.id,\n name: region.name,\n countryCodes: region.countries.map((country) => country.code),\n currency: region.currencyCode,\n taxRate: region.taxRate,\n isEnabled: true,\n }));\n}\n\nexport function getMockRegionCountries(regionId: string): Country[] {\n const region = regionFixtures.find((item) => item.id === regionId);\n return region?.countries ?? [];\n}\n\nexport function createMockCart(regionId?: string): MockCartState {\n const cart: MockCartState = {\n id: nextId('mock-cart'),\n regionId: regionId ?? regionFixtures[0].id,\n lines: [],\n };\n\n cartStore.set(cart.id, cart);\n return cart;\n}\n\nexport function getMockCartState(cartId: string): MockCartState | undefined {\n return cartStore.get(cartId);\n}\n\nexport function saveMockCartState(cart: MockCartState): MockCartState {\n cartStore.set(cart.id, cart);\n return cart;\n}\n\nexport function buildMockCart(cart: MockCartState, currencyCode?: string, siteUrl?: string): Cart {\n return buildExternalCart(\n cart,\n currencyCode ?? getRegionFixture(cart.regionId).currencyCode,\n siteUrl ?? DEFAULT_SITE_URL\n );\n}\n\nexport function getMockShippingMethods(regionId?: string): ShippingMethod[] {\n const currencyCode = getRegionFixture(regionId).currencyCode;\n\n return [\n {\n id: 'mock-shipping-standard',\n name: 'Standard Shipping',\n description: 'Fixture shipping option for checkout and cart layouts.',\n price: createMoney(8, currencyCode),\n estimatedDays: '3-5 business days',\n },\n {\n id: 'mock-shipping-express',\n name: 'Express Shipping',\n description: 'Faster fixture shipping option for premium checkout flows.',\n price: createMoney(18, currencyCode),\n estimatedDays: '1-2 business days',\n },\n ];\n}\n\nexport function getMockPaymentMethods(currencyCode: string): PaymentMethod[] {\n return [\n {\n id: 'mock-card',\n name: 'Mock Card',\n type: 'card',\n isEnabled: true,\n requiresSetup: true,\n description: `Fixture card checkout for ${currencyCode}.`,\n },\n {\n id: 'mock-cash',\n name: 'Cash on Delivery',\n type: 'cash_on_delivery',\n isEnabled: true,\n requiresSetup: false,\n description: 'Mock cash payment option for checkout prototypes.',\n },\n ];\n}\n\nexport function getMockStockLocations(): StockLocation[] {\n return [stockLocationFixture];\n}\n\nexport function getMockInventoryLevels(variantId: string): InventoryLevel[] {\n for (const region of regionFixtures) {\n const resolved = resolveVariant(region.currencyCode, variantId);\n if (resolved) {\n return [{\n locationId: stockLocationFixture.id,\n locationName: stockLocationFixture.name,\n availableQuantity: resolved.variant.quantityAvailable ?? 0,\n reservedQuantity: 0,\n stockedQuantity: resolved.variant.quantityAvailable ?? 0,\n }];\n }\n }\n\n return [];\n}\n\nexport function validateMockCartStock(cart: MockCartState): StockValidation {\n const currencyCode = getRegionFixture(cart.regionId).currencyCode;\n const unavailableItems = cart.lines.flatMap((line) => {\n const resolved = resolveVariant(currencyCode, line.merchandiseId);\n if (!resolved) {\n return [];\n }\n\n const availableQuantity = resolved.variant.quantityAvailable ?? 0;\n\n if (line.quantity <= availableQuantity) {\n return [];\n }\n\n return [{\n variantId: resolved.variant.id,\n productName: resolved.product.title,\n requestedQuantity: line.quantity,\n availableQuantity,\n }];\n });\n\n return {\n allAvailable: unavailableItems.length === 0,\n unavailableItems,\n };\n}\n\nexport function getMockFulfillmentOptions(regionId?: string): FulfillmentOption[] {\n return getMockShippingMethods(regionId).map((method) => ({\n id: method.id,\n providerId: 'mock-fulfillment',\n name: method.name,\n description: method.description,\n price: method.price,\n estimatedDays: method.estimatedDays,\n stockLocation: stockLocationFixture,\n }));\n}\n\nexport function completeMockCheckout(cart: MockCartState, currencyCode?: string, siteUrl?: string): Order {\n const completedAt = new Date().toISOString();\n const nextCart = {\n ...cart,\n completedAt,\n };\n\n cartStore.set(nextCart.id, nextCart);\n\n const order = buildOrderFromCart(\n nextCart,\n currencyCode ?? getRegionFixture(nextCart.regionId).currencyCode,\n siteUrl ?? DEFAULT_SITE_URL\n );\n\n orderStore.set(order.id, order);\n return order;\n}\n\nexport function getMockAdminOrders(): { orders: Order[]; count: number } {\n const orders = Array.from(orderStore.values()).sort((left, right) =>\n right.createdAt.localeCompare(left.createdAt)\n );\n\n return {\n orders,\n count: orders.length,\n };\n}\n\nexport function getMockOrder(orderId: string): Order | undefined {\n return orderStore.get(orderId);\n}\n\nexport function saveMockOrder(order: Order): Order {\n orderStore.set(order.id, order);\n return order;\n}\n","import type {\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCategoriesOptions,\n GetCollectionsOptions,\n GetOrdersOptions,\n GetProductsOptions,\n InventoryLevel,\n Order,\n PaymentMethodsOptions,\n Product,\n ProductCategory,\n Region,\n ShippingMethod,\n StockLocation,\n StockValidation,\n StorefrontContext,\n FulfillmentOption,\n PaymentMethod,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { ProviderAPIError, ResourceNotFoundError } from '../../core/errors';\nimport { MOCK_CAPABILITIES } from '../../types/capabilities.types';\nimport {\n buildMockCart,\n completeMockCheckout,\n createMockCart,\n getMockAdminOrders,\n getMockAdminRegions,\n getMockCategories,\n getMockCategory,\n getMockCollection,\n getMockCollections,\n getMockCartState,\n getMockFulfillmentOptions,\n getMockInventoryLevels,\n getMockOrder,\n getMockPaymentMethods,\n getMockProduct,\n getMockProductRecommendations,\n getMockProducts,\n getMockRegionCountries,\n getMockRegions,\n getMockShippingMethods,\n getMockStockLocations,\n saveMockCartState,\n saveMockOrder,\n validateMockCartStock,\n} from './mock';\n\nexport interface MockProviderConfig extends ProviderConfig {\n currencyCode?: string;\n siteUrl?: string;\n}\n\nexport class MockProvider implements CommerceProvider {\n readonly name = 'mock';\n readonly version = '1.0.0';\n readonly capabilities = MOCK_CAPABILITIES;\n readonly isMock = true;\n\n private readonly currencyCode: string;\n private readonly siteUrl: string;\n\n constructor(config: MockProviderConfig = {}) {\n this.currencyCode = config.currencyCode ?? 'USD';\n this.siteUrl = config.siteUrl ?? 'https://mock.thorcommerce.local';\n }\n\n private hasVariant(merchandiseId: string, regionId?: string): boolean {\n return getMockProducts({\n currencyCode: this.currencyCode,\n regionId,\n }).some((product) =>\n product.variants.some((variant) => variant.id === merchandiseId)\n );\n }\n\n async getProduct(handle: string, options?: { regionId?: string }): Promise<Product | undefined> {\n return getMockProduct(handle, options?.regionId);\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n return getMockProducts({\n currencyCode: this.currencyCode,\n query: options?.query,\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n first: options?.first,\n skip: options?.skip,\n categoryIds: options?.categoryIds,\n collectionIds: options?.collectionIds,\n regionId: options?.regionId,\n });\n }\n\n async getProductRecommendations(productId: string): Promise<Product[]> {\n return getMockProductRecommendations(productId);\n }\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n return getMockCollection(handle);\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const collections = getMockCollections();\n const query = options?.query?.trim().toLowerCase();\n const filtered = query\n ? collections.filter((collection) =>\n [collection.title, collection.description, collection.handle]\n .join(' ')\n .toLowerCase()\n .includes(query)\n )\n : collections;\n\n return filtered.slice(0, options?.limit ?? filtered.length);\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const collection = getMockCollection(handle);\n if (!collection) {\n return [];\n }\n\n return getMockProducts({\n currencyCode: this.currencyCode,\n collectionIds: [collection.id],\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n first: options?.first,\n });\n }\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n return getMockCategory(idOrHandle);\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n const categories = getMockCategories();\n const query = options?.query?.trim().toLowerCase();\n\n let filtered = query\n ? categories.filter((category) =>\n [category.name, category.description ?? '', category.handle]\n .join(' ')\n .toLowerCase()\n .includes(query)\n )\n : categories;\n\n if (options?.parentCategoryId) {\n filtered = filtered.filter((category) => category.parentCategoryId === options.parentCategoryId);\n }\n\n return filtered.slice(0, options?.limit ?? filtered.length);\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const category = getMockCategory(handle);\n if (!category) {\n return [];\n }\n\n return getMockProducts({\n currencyCode: this.currencyCode,\n categoryIds: [category.id],\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n first: options?.first,\n });\n }\n\n async createCart(options?: { regionId?: string }): Promise<Cart> {\n const cart = createMockCart(options?.regionId);\n return buildMockCart(cart, this.currencyCode, this.siteUrl);\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n const cart = getMockCartState(cartId);\n return cart ? buildMockCart(cart, this.currencyCode, this.siteUrl) : undefined;\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n for (const line of lines) {\n if (!this.hasVariant(line.merchandiseId, cart.regionId)) {\n throw new ResourceNotFoundError('variant', line.merchandiseId);\n }\n }\n\n const nextLines = [...cart.lines];\n for (const line of lines) {\n const existing = nextLines.find((item) => item.merchandiseId === line.merchandiseId);\n if (existing) {\n existing.quantity += line.quantity;\n } else {\n nextLines.push({\n id: `mock-line-${line.merchandiseId}`,\n merchandiseId: line.merchandiseId,\n quantity: line.quantity,\n });\n }\n }\n\n const saved = saveMockCartState({ ...cart, lines: nextLines });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const saved = saveMockCartState({\n ...cart,\n lines: cart.lines.filter((line) => !lineIds.includes(line.id)),\n });\n\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n for (const line of lines) {\n if (!this.hasVariant(line.merchandiseId, cart.regionId)) {\n throw new ResourceNotFoundError('variant', line.merchandiseId);\n }\n }\n\n const updates = new Map(lines.map((line) => [line.id, line]));\n const nextLines = cart.lines\n .map((line) => {\n const update = updates.get(line.id);\n if (!update) {\n return line;\n }\n\n return {\n ...line,\n merchandiseId: update.merchandiseId,\n quantity: update.quantity,\n };\n })\n .filter((line) => line.quantity > 0);\n\n const saved = saveMockCartState({ ...cart, lines: nextLines });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async getRegions(): Promise<Array<{ id: string; name: string; currency_code: string; countries?: Array<{ id: string; iso_2: string; name: string; display_name?: string }> }>> {\n return getMockRegions();\n }\n\n async completeCheckout(cartId: string): Promise<Order> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const order = completeMockCheckout(cart, this.currencyCode, this.siteUrl);\n return order;\n }\n\n async getShippingMethods(cartId: string): Promise<ShippingMethod[]> {\n const cart = getMockCartState(cartId);\n return getMockShippingMethods(cart?.regionId);\n }\n\n async getRegionCountries(regionId: string) {\n return getMockRegionCountries(regionId);\n }\n\n async addShippingMethod(cartId: string, methodId: string): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const allowed = getMockShippingMethods(cart.regionId).some((method) => method.id === methodId);\n if (!allowed) {\n throw new ProviderAPIError(`Unknown mock shipping method: ${methodId}`, 'mock', 400);\n }\n\n const saved = saveMockCartState({ ...cart, shippingMethodId: methodId });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async initiatePaymentSession(cartId: string, providerId: string): Promise<void> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const allowed = getMockPaymentMethods(this.currencyCode).some((method) => method.id === providerId);\n if (!allowed) {\n throw new ProviderAPIError(`Unknown mock payment method: ${providerId}`, 'mock', 400);\n }\n\n saveMockCartState({ ...cart, paymentProviderId: providerId });\n }\n\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const normalized = code.trim();\n if (!normalized) {\n throw new ProviderAPIError('Discount code is required.', 'mock', 400);\n }\n\n const saved = saveMockCartState({ ...cart, discountCode: normalized });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async removeDiscountCode(cartId: string, _code: string): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const saved = saveMockCartState({ ...cart, discountCode: undefined });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async getOrders(_options: GetOrdersOptions): Promise<Order[]> {\n return getMockAdminOrders().orders;\n }\n\n async getPaymentMethods(options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n return getMockPaymentMethods(options.currencyCode ?? this.currencyCode);\n }\n\n async getStockLocations(): Promise<StockLocation[]> {\n return getMockStockLocations();\n }\n\n async checkInventoryLevels(variantId: string): Promise<InventoryLevel[]> {\n return getMockInventoryLevels(variantId);\n }\n\n async validateCartStock(cartId: string): Promise<StockValidation> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n return validateMockCartStock(cart);\n }\n\n async getFulfillmentOptions(cartId: string, _salesChannelId: string): Promise<FulfillmentOption[]> {\n const cart = getMockCartState(cartId);\n return getMockFulfillmentOptions(cart?.regionId);\n }\n\n async cancelOrder(orderId: string): Promise<Order> {\n const order = getMockOrder(orderId);\n if (!order) {\n throw new ResourceNotFoundError('order', orderId);\n }\n\n return saveMockOrder({\n ...order,\n status: 'cancelled',\n updatedAt: new Date().toISOString(),\n cancelledAt: new Date().toISOString(),\n });\n }\n\n async createFulfillment(_orderId: string, _items?: Array<{ id: string; quantity: number }>): Promise<void> {\n return;\n }\n\n async createRefund(orderId: string, _amount?: number, _reason?: string): Promise<void> {\n const order = getMockOrder(orderId);\n if (!order) {\n throw new ResourceNotFoundError('order', orderId);\n }\n\n saveMockOrder({\n ...order,\n status: 'refunded',\n paymentStatus: 'refunded',\n updatedAt: new Date().toISOString(),\n });\n }\n\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> {\n return getMockAdminOrders();\n }\n\n async getAdminRegions(): Promise<Region[]> {\n return getMockAdminRegions();\n }\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: 'mock-storefront',\n name: 'Mock Storefront',\n platformType: 'mock',\n requiresProductScoping: false,\n currencyCode: this.currencyCode,\n locale: 'en-US',\n metadata: {\n mode: 'design',\n },\n };\n }\n\n isStorefrontRequired(): boolean {\n return false;\n }\n}\n","/**\n * @thorprovider/adapters v5.0\n * Provider Factory - Dynamic registry pattern\n *\n * Providers register themselves at import time via `registerProvider()`.\n * The factory no longer statically imports every backend — only the ones\n * the consumer explicitly imports will be available.\n *\n * Built-in providers (medusa, stelorder, mock) are registered automatically.\n */\n\nimport type { CommerceProvider } from '../types';\nimport { MedusaProvider, type MedusaProviderConfig } from '../providers/medusa';\nimport { StelOrderProvider, type StelOrderProviderConfig } from '../providers/stelorder';\nimport { MockProvider, type MockProviderConfig } from '../providers/mock';\nimport { ProviderNotFoundError, ConfigurationError } from '../core/errors';\nimport type { ProviderTypeString } from '@thorprovider/types';\n\n// ============================================\n// Registry\n// ============================================\n\ntype ProviderFactory = (config: any) => CommerceProvider;\n\nconst registry = new Map<string, ProviderFactory>();\n\n/**\n * Register a provider factory for a given type string.\n * Call this to make a provider available to `createProvider()`.\n *\n * @example\n * ```ts\n * import { registerProvider } from '@thorprovider/adapters';\n * import { MyProvider } from './my-provider';\n *\n * registerProvider('my-provider', (config) => new MyProvider(config));\n * ```\n */\nexport function registerProvider(type: string, factory: ProviderFactory): void {\n registry.set(type, factory);\n}\n\n/**\n * Get all registered provider type strings.\n */\nexport function getRegisteredProviders(): string[] {\n return Array.from(registry.keys());\n}\n\n// ============================================\n// Built-in registrations\n// ============================================\n\nregisterProvider('mock', (config) => new MockProvider(config));\nregisterProvider('medusa', (config) => new MedusaProvider(config));\nregisterProvider('stelorder', (config) => new StelOrderProvider(config));\n\n// ============================================\n// Types\n// ============================================\n\n/**\n * Supported provider types\n */\nexport type ProviderType = ProviderTypeString | (string & {});\n\n/**\n * Provider configuration discriminated union (built-in providers)\n */\nexport type ProviderFactoryConfig =\n | { provider: 'mock'; config: MockProviderConfig }\n | { provider: 'medusa'; config: MedusaProviderConfig }\n | { provider: 'stelorder'; config: StelOrderProviderConfig }\n | { provider: string; config: Record<string, unknown> };\n\n/**\n * Runtime provider configuration (accepts any registered provider string)\n */\nexport type RuntimeProviderConfig = {\n provider: string;\n config: Record<string, unknown>;\n};\n\n// ============================================\n// Factory\n// ============================================\n\n/**\n * Create a commerce provider instance from the registry.\n *\n * @example\n * ```ts\n * const commerce = createProvider({\n * provider: 'medusa',\n * config: {\n * baseUrl: process.env.MEDUSA_BACKEND_URL,\n * publishableKey: process.env.MEDUSA_PUBLISHABLE_KEY,\n * }\n * });\n * ```\n */\nexport function createProvider(options: ProviderFactoryConfig | RuntimeProviderConfig): CommerceProvider {\n if (!options || !options.provider) {\n throw new ConfigurationError('Provider type is required');\n }\n\n if (!options.config) {\n throw new ConfigurationError('Provider configuration is required');\n }\n\n const factory = registry.get(options.provider);\n\n if (!factory) {\n const available = getRegisteredProviders().join(', ');\n throw new ProviderNotFoundError(\n `Provider \"${options.provider}\" is not registered. Available: ${available}. ` +\n `Did you forget to import the provider package?`\n );\n }\n\n return factory(options.config);\n}\n\n/**\n * Type guard to check if a provider is of a specific type\n */\nexport function isProviderType<T extends ProviderType>(\n provider: CommerceProvider,\n type: T\n): boolean {\n return provider.name === type;\n}\n"],"mappings":"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","names":["import_types","bcrypt","Medusa","import_js_sdk","Medusa","DEFAULT_RETRY_CONFIG","sleep","calculateDelay","isRetryableError","logger"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types/capabilities.types.ts","../src/core/errors.ts","../src/core/logger.ts","../src/core/fetch-utils.ts","../src/resilience/circuit-breaker.ts","../src/lib/money-transform.ts","../src/utils/payment-utils.ts","../src/utils/city-coordinates.ts","../src/utils/geolocation.ts","../src/providers/medusa/fulfillment-planner.ts","../src/providers/medusa/transforms.ts","../src/admin/AdminAuthService.ts","../src/admin/AdminSessionService.ts","../src/admin/MetricsService.ts","../src/backend/factory.ts","../src/backend/medusa/MedusaMetadataAdapter.ts","../src/metadata/channel-scope.ts","../src/metadata/channel-scope-validation.ts","../src/providers/medusa/index.ts","../src/providers/medusa/auth.ts","../src/providers/medusa/payment.ts","../src/providers/shopify/transforms.ts","../src/providers/shopify/queries.ts","../src/providers/shopify/mutations.ts","../src/providers/shopify/index.ts","../src/providers/bigcommerce/transforms.ts","../src/providers/bigcommerce/index.ts","../src/providers/woocommerce/transforms.ts","../src/providers/woocommerce/index.ts","../src/providers/spree/transforms.ts","../src/providers/spree/index.ts","../src/providers/magento/transforms.ts","../src/providers/magento/queries.ts","../src/providers/magento/index.ts","../src/providers/stelorder/transforms.ts","../src/providers/stelorder/client.ts","../src/providers/stelorder/index.ts","../src/providers/mock/mock.ts","../src/providers/mock/index.ts","../src/factory/index.ts"],"sourcesContent":["/**\n * @thorprovider/adapters v2.0\n * Main package exports\n * \n * Unified commerce adapters for Thor Commerce ecosystem\n * Supports multiple e-commerce platforms through a common interface\n */\n\n// ============================================\n// Types\n// ============================================\nexport type * from './types';\n\n// ============================================\n// Commerce Provider Interface (from @thorprovider/types)\n// ============================================\n// Re-export for backward compatibility\nexport type {\n CommerceProvider,\n BackendCapabilities,\n ProviderConfig,\n StorefrontContext,\n StorefrontPlatformType,\n StorefrontConfig,\n StorefrontSeoDefaults,\n DesignerConfig,\n DesignerThemeConfig,\n DesignerThemePreset,\n DesignerNavItem,\n DesignerHistoryEntry,\n} from '@thorprovider/types';\n\nexport {\n StorefrontConfigError,\n} from '@thorprovider/types';\n\n// ============================================\n// Capabilities\n// ============================================\nexport {\n MOCK_CAPABILITIES,\n MEDUSA_CAPABILITIES,\n STELORDER_CAPABILITIES,\n SHOPIFY_CAPABILITIES,\n BIGCOMMERCE_CAPABILITIES,\n WOOCOMMERCE_CAPABILITIES,\n SPREE_CAPABILITIES,\n MAGENTO_CAPABILITIES,\n isBackendCapabilities,\n getCapabilityDescription,\n} from './types/capabilities.types';\n\n// ============================================\n// Core Utilities\n// ============================================\nexport {\n CommerceError,\n ProviderNotFoundError,\n ConfigurationError,\n ResourceNotFoundError,\n ProviderAPIError,\n extractErrorMessage,\n createLogger,\n fetchWithRetry,\n createFetchWithRetry,\n type Logger,\n type LogLevel,\n type RetryConfig,\n} from './core';\n\n// ============================================\n// Resilience Patterns\n// ============================================\nexport {\n CircuitBreaker,\n backendCircuitBreaker,\n CircuitBreakerOpenError,\n type CircuitState,\n type CircuitBreakerConfig,\n type CircuitBreakerStats,\n} from './resilience';\n\n// ============================================\n// Transformation Utilities\n// ============================================\nexport {\n moneyToNumber,\n numberToMoney,\n moneyToNumberSafe,\n} from './lib/money-transform';\n\n// ============================================\n// Payment Utilities\n// ============================================\nexport {\n getBackendProviderId,\n validatePaymentId,\n type BackendMapping,\n} from './utils/payment-utils';\n\n// ============================================\n// Inventory & Fulfillment Utilities\n// ============================================\nexport {\n calculateDistance,\n geocodeAddress,\n type Coordinates,\n} from './utils/geolocation';\n\nexport {\n planFulfillment,\n type FulfillmentGroup,\n type FulfillmentPlan,\n type PlanFulfillmentShippingAddress,\n} from './providers/medusa/fulfillment-planner';\n\nexport {\n transformStockLocation,\n transformInventoryLevel,\n transformFulfillmentOption,\n transformStorefrontConfig,\n} from './providers/medusa/transforms';\n\n// ============================================\n// Admin Services\n// ============================================\nexport {\n AdminAuthService,\n AdminSessionService,\n MetricsService,\n} from './admin';\n\nexport type {\n AdminSession,\n MetricsOrderInput,\n MetricsProductInput,\n} from './admin';\n\n// ============================================\n// Backend Metadata Adapters\n// ============================================\nexport type {\n BackendMetadataAdapter,\n} from './backend/BackendMetadataAdapter';\n\nexport type {\n BackendMetadataAdapterConfig,\n} from './backend/factory';\n\nexport {\n createBackendMetadataAdapter,\n} from './backend/factory';\n\nexport {\n MedusaMetadataAdapter,\n} from './backend/medusa/MedusaMetadataAdapter';\n\n// ============================================\n// Channel Scope (Multi-Tenant Metadata Helpers)\n// ============================================\nexport {\n CHANNEL_SCOPE_KEY,\n CHANNEL_ASSIGNED_AT_KEY,\n CHANNEL_ASSIGNED_BY_KEY,\n buildChannelScopeMetadata,\n getChannelScope,\n isScopedToChannel,\n isGlobalEntity,\n filterByChannel,\n filterGlobalOnly,\n partitionByChannel,\n ChannelScopeValidationError,\n validateChannelId,\n validateEntityId,\n validateAssignedBy,\n validateChannelScopeAssignment,\n assertEntityBelongsToChannel,\n} from './metadata';\n\nexport type {\n ChannelScopeable,\n ChannelScopeMetadata,\n} from './metadata';\n\n// ============================================\n// Factory\n// ============================================\nexport {\n createProvider,\n isProviderType,\n type ProviderType,\n type ProviderFactoryConfig,\n} from './factory';\n\n// ============================================\n// Providers\n// ============================================\nexport {\n MedusaProvider,\n type MedusaProviderConfig,\n StelOrderProvider,\n type StelOrderProviderConfig,\n MockProvider,\n type MockProviderConfig,\n ShopifyProvider,\n type ShopifyProviderConfig,\n BigCommerceProvider,\n type BigCommerceProviderConfig,\n WooCommerceProvider,\n type WooCommerceProviderConfig,\n SpreeProvider,\n type SpreeProviderConfig,\n MagentoProvider,\n type MagentoProviderConfig,\n} from './providers';\n","/**\n * @thorprovider/adapters v2.0\n * Backend Capabilities System\n * \n * Defines what operations each backend platform supports.\n * This is a compile-time capability detection system, NOT runtime feature flags.\n * \n * NOTE: BackendCapabilities interface is defined in @thorprovider/types (L1: Foundation).\n * This file re-exports it and provides platform-specific implementations.\n * \n * @see packages/core/docs/BACKEND_CAPABILITIES_ANALYSIS.md\n * @see packages/core/docs/COMMERCE_PROVIDER_ARCHITECTURE.md\n */\n\nimport type { BackendCapabilities } from '@thorprovider/types';\n\nexport type { BackendCapabilities };\n\n/**\n * Mock backend capabilities\n *\n * Fixture-backed provider used when a storefront has not yet been connected\n * to a real backend. Supports the minimum commerce flows needed for layout,\n * preview, navigation, region switching, and cart prototyping.\n */\nexport const MOCK_CAPABILITIES: Readonly<BackendCapabilities> = {\n updateProfile: false,\n updateEmail: false,\n changePasswordDirect: false,\n changePasswordViaEmail: false,\n deleteAccount: false,\n uploadAvatar: false,\n avatarViaMetadata: false,\n customAttributes: false,\n fetchOrders: true,\n cancelOrder: true,\n manageAddresses: false,\n defaultAddress: false,\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: false,\n listPaymentProviders: true,\n regionSpecificPayments: true,\n wishlist: false,\n advancedSearch: false,\n facetedFilters: false,\n productReviews: false,\n loyaltyProgram: false,\n};\n\n/**\n * Medusa backend capabilities\n * \n * @see https://docs.medusajs.com/api/store\n */\nexport const MEDUSA_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: false, // Security restriction\n changePasswordDirect: false, // Email flow only\n changePasswordViaEmail: true,\n deleteAccount: true, // Implemented via ThorMedusaClient\n \n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: true,\n \n // Custom Attributes\n customAttributes: true,\n \n // Orders\n fetchOrders: true,\n cancelOrder: true,\n \n // Addresses\n manageAddresses: true,\n defaultAddress: true,\n \n // Cart/Checkout\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: false, // Depends on payment provider\n listPaymentProviders: true,\n regionSpecificPayments: true,\n \n // Wishlist\n wishlist: false, // Requires custom implementation\n \n // Search\n advancedSearch: true,\n facetedFilters: true,\n \n // Reviews\n productReviews: false, // Requires custom implementation\n \n // Loyalty\n loyaltyProgram: false, // Requires custom implementation\n};\n\n/**\n * Stel Order backend capabilities\n *\n * ERP/document API with catalog, CRM, inventory visibility, and sales documents,\n * but without cart, checkout, customer auth, or storefront-native payment flows.\n */\nexport const STELORDER_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: false,\n updateEmail: false,\n changePasswordDirect: false,\n changePasswordViaEmail: false,\n deleteAccount: false,\n\n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: false,\n\n // Custom Attributes\n customAttributes: false,\n\n // Orders\n fetchOrders: true,\n cancelOrder: false,\n\n // Addresses\n manageAddresses: true,\n defaultAddress: false,\n\n // Cart/Checkout\n applyDiscounts: false,\n shippingCalculation: false,\n guestCheckout: false,\n savedPaymentMethods: false,\n listPaymentProviders: true,\n regionSpecificPayments: false,\n\n // Wishlist\n wishlist: false,\n\n // Search\n advancedSearch: false,\n facetedFilters: false,\n\n // Reviews\n productReviews: false,\n\n // Loyalty\n loyaltyProgram: false,\n};\n\n/**\n * Shopify backend capabilities\n * \n * @see https://shopify.dev/docs/api/storefront\n */\nexport const SHOPIFY_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: true,\n changePasswordDirect: true,\n changePasswordViaEmail: true,\n deleteAccount: false, // Requires admin API\n \n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: true,\n \n // Custom Attributes\n customAttributes: true,\n \n // Orders\n fetchOrders: true,\n cancelOrder: true,\n \n // Addresses\n manageAddresses: true,\n defaultAddress: true,\n \n // Cart/Checkout\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: true,\n listPaymentProviders: true,\n regionSpecificPayments: false, // Global payment methods\n \n // Wishlist\n wishlist: false, // Requires app\n \n // Search\n advancedSearch: true,\n facetedFilters: true,\n \n // Reviews\n productReviews: false, // Requires app\n \n // Loyalty\n loyaltyProgram: false, // Requires app\n};\n\n/**\n * BigCommerce backend capabilities\n * \n * @see https://developer.bigcommerce.com/docs/rest-storefront\n */\nexport const BIGCOMMERCE_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: true,\n changePasswordDirect: true,\n changePasswordViaEmail: true,\n deleteAccount: false,\n\n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: false,\n\n // Custom Attributes\n customAttributes: true,\n\n // Orders\n fetchOrders: true,\n cancelOrder: false, // Admin API only\n\n // Addresses\n manageAddresses: true,\n defaultAddress: false,\n\n // Cart/Checkout\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: true,\n listPaymentProviders: true,\n regionSpecificPayments: false,\n\n // Wishlist\n wishlist: true, // Native support\n\n // Search\n advancedSearch: true,\n facetedFilters: true,\n\n // Reviews\n productReviews: true, // Native support\n\n // Loyalty\n loyaltyProgram: false,\n};\n\n/**\n * WooCommerce backend capabilities\n * \n * @see https://developer.woocommerce.com/docs/apis/store-api\n */\nexport const WOOCOMMERCE_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: true,\n changePasswordDirect: false, // WordPress handles auth\n changePasswordViaEmail: true,\n deleteAccount: false,\n\n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: false, // Gravatar-based\n\n // Custom Attributes\n customAttributes: true, // Via meta_data\n\n // Orders\n fetchOrders: true,\n cancelOrder: true,\n\n // Addresses\n manageAddresses: true,\n defaultAddress: false, // Billing/shipping only\n\n // Cart/Checkout\n applyDiscounts: true, // Coupon codes\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: false,\n listPaymentProviders: true,\n regionSpecificPayments: false,\n\n // Wishlist\n wishlist: false, // Requires plugin\n\n // Search\n advancedSearch: false, // Basic WP search\n facetedFilters: false, // Requires plugin\n\n // Reviews\n productReviews: true, // Native WP reviews\n\n // Loyalty\n loyaltyProgram: false,\n};\n\n/**\n * Spree Commerce backend capabilities\n * \n * @see https://docs.spreecommerce.org/api-reference\n */\nexport const SPREE_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: true,\n changePasswordDirect: true,\n changePasswordViaEmail: true,\n deleteAccount: false,\n\n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: false,\n\n // Custom Attributes\n customAttributes: false,\n\n // Orders\n fetchOrders: true,\n cancelOrder: true,\n\n // Addresses\n manageAddresses: true,\n defaultAddress: true,\n\n // Cart/Checkout\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: false,\n listPaymentProviders: true,\n regionSpecificPayments: false,\n\n // Wishlist\n wishlist: true, // Native support\n\n // Search\n advancedSearch: false,\n facetedFilters: true, // Taxon-based filtering\n\n // Reviews\n productReviews: false, // Requires extension\n\n // Loyalty\n loyaltyProgram: false,\n};\n\n/**\n * Adobe Commerce / Magento backend capabilities\n * \n * @see https://developer.adobe.com/commerce/webapi/graphql/\n */\nexport const MAGENTO_CAPABILITIES: Readonly<BackendCapabilities> = {\n // Profile Management\n updateProfile: true,\n updateEmail: true,\n changePasswordDirect: true,\n changePasswordViaEmail: true,\n deleteAccount: false, // Admin only\n\n // Avatar\n uploadAvatar: false,\n avatarViaMetadata: false,\n\n // Custom Attributes\n customAttributes: true, // EAV model\n\n // Orders\n fetchOrders: true,\n cancelOrder: true,\n\n // Addresses\n manageAddresses: true,\n defaultAddress: true,\n\n // Cart/Checkout\n applyDiscounts: true,\n shippingCalculation: true,\n guestCheckout: true,\n savedPaymentMethods: true,\n listPaymentProviders: true,\n regionSpecificPayments: true, // Store-view scoped\n\n // Wishlist\n wishlist: true, // Native support\n\n // Search\n advancedSearch: true, // Elasticsearch/OpenSearch\n facetedFilters: true, // Layered navigation\n\n // Reviews\n productReviews: true, // Native support\n\n // Loyalty\n loyaltyProgram: false, // Requires extension\n};\n\n/**\n * Type guard to check if an object is a valid BackendCapabilities\n */\nexport function isBackendCapabilities(obj: unknown): obj is BackendCapabilities {\n if (typeof obj !== 'object' || obj === null) return false;\n \n const capabilities = obj as Partial<BackendCapabilities>;\n \n // Check required profile management capabilities\n return (\n typeof capabilities.updateProfile === 'boolean' &&\n typeof capabilities.updateEmail === 'boolean' &&\n typeof capabilities.changePasswordDirect === 'boolean'\n );\n}\n\n/**\n * Get capability description for UI display\n */\nexport function getCapabilityDescription(capability: keyof BackendCapabilities): string {\n const descriptions: Record<keyof BackendCapabilities, string> = {\n updateProfile: 'Update profile information (name, phone)',\n updateEmail: 'Change email address',\n changePasswordDirect: 'Change password directly',\n changePasswordViaEmail: 'Request password reset via email',\n deleteAccount: 'Delete account (self-service)',\n uploadAvatar: 'Upload profile picture',\n avatarViaMetadata: 'Store avatar URL in metadata',\n customAttributes: 'Custom customer attributes',\n fetchOrders: 'View order history',\n cancelOrder: 'Cancel orders',\n manageAddresses: 'Add/update/delete addresses',\n defaultAddress: 'Set default address',\n applyDiscounts: 'Apply discount codes',\n shippingCalculation: 'Calculate shipping rates',\n guestCheckout: 'Checkout without account',\n savedPaymentMethods: 'Save payment methods',\n listPaymentProviders: 'List available payment providers',\n regionSpecificPayments: 'Region-specific payment methods',\n wishlist: 'Wishlist/favorites',\n advancedSearch: 'Advanced product search',\n facetedFilters: 'Filter by product attributes',\n productReviews: 'Product reviews and ratings',\n loyaltyProgram: 'Loyalty/rewards program',\n };\n \n return descriptions[capability] || capability;\n}\n","/**\n * @thorprovider/adapters v2.0\n * Core errors\n */\n\n/**\n * Base error class for commerce providers\n */\nexport class CommerceError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n public readonly status?: number\n ) {\n super(message);\n this.name = 'CommerceError';\n }\n}\n\n/**\n * Provider not found error\n */\nexport class ProviderNotFoundError extends CommerceError {\n constructor(providerName: string) {\n super(`Provider not found: ${providerName}`, 'PROVIDER_NOT_FOUND');\n this.name = 'ProviderNotFoundError';\n }\n}\n\n/**\n * Configuration error\n */\nexport class ConfigurationError extends CommerceError {\n constructor(message: string) {\n super(message, 'CONFIGURATION_ERROR');\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Resource not found error\n */\nexport class ResourceNotFoundError extends CommerceError {\n constructor(resource: string, identifier: string) {\n super(`${resource} not found: ${identifier}`, 'RESOURCE_NOT_FOUND', 404);\n this.name = 'ResourceNotFoundError';\n }\n}\n\n/**\n * API error from provider\n */\nexport class ProviderAPIError extends CommerceError {\n constructor(\n message: string,\n public readonly provider: string,\n status?: number\n ) {\n super(message, 'PROVIDER_API_ERROR', status);\n this.name = 'ProviderAPIError';\n }\n}\n\n/**\n * Extract error message from various error types\n * Handles standard Error objects, API responses, and unknown error types\n */\nexport function extractErrorMessage(error: unknown): string {\n // Standard Error object\n if (error instanceof Error && error.message) {\n // Don't return generic messages if there's more data\n if (error.message !== 'An unknown error occurred.') {\n return error.message;\n }\n }\n \n // Object with message property\n if (typeof error === 'object' && error !== null) {\n const err = error as any;\n \n // Check for response body (common in fetch errors)\n if (err.body) {\n if (typeof err.body === 'string') return err.body;\n if (err.body.message) return String(err.body.message);\n if (err.body.error?.message) return String(err.body.error.message);\n }\n \n // Check for response object\n if (err.response) {\n if (err.response.data?.message) return String(err.response.data.message);\n if (err.response.data?.error) return String(err.response.data.error);\n if (err.response.statusText) return `${err.response.status || ''} ${err.response.statusText}`.trim();\n }\n \n // Check for data property\n if (err.data?.message) return String(err.data.message);\n if (err.data?.error) return String(err.data.error);\n \n // Check for error property\n if (err.error?.message) return String(err.error.message);\n \n // Check for statusText with status code\n if (err.status && err.statusText) {\n return `HTTP ${err.status}: ${err.statusText}`;\n }\n \n if (err.status && !err.statusText) {\n return `HTTP ${err.status} Error`;\n }\n \n // Check for message property (not generic)\n if (err.message && err.message !== 'An unknown error occurred.') {\n return String(err.message);\n }\n \n // Try to stringify the error object\n try {\n const stringified = JSON.stringify(error);\n if (stringified !== '{}') return stringified;\n } catch {\n // Ignore JSON.stringify errors\n }\n }\n \n // String error\n if (typeof error === 'string') {\n return error;\n }\n \n // Fallback\n return 'An unknown error occurred';\n}\n","/**\n * @thorprovider/adapters v2.0\n * Core logger utility\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface Logger {\n debug(message: string, ...args: any[]): void;\n info(message: string, ...args: any[]): void;\n warn(message: string, ...args: any[]): void;\n error(message: string, ...args: any[]): void;\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(\n namespace: string,\n enabled: boolean = false\n): Logger {\n const log = (level: LogLevel, message: string, ...args: any[]) => {\n if (!enabled && level !== 'error') return;\n \n const timestamp = new Date().toISOString();\n const prefix = `[${timestamp}] [@thorprovider/adapters:${namespace}] ${level.toUpperCase()}:`;\n \n console[level](prefix, message, ...args);\n };\n \n return {\n debug: (message, ...args) => log('debug', message, ...args),\n info: (message, ...args) => log('info', message, ...args),\n warn: (message, ...args) => log('warn', message, ...args),\n error: (message, ...args) => log('error', message, ...args),\n };\n}\n","/**\n * @thorprovider/adapters v2.0\n * Fetch Utilities - Retry logic, timeouts, and error handling\n * \n * This module provides enhanced fetch capabilities with:\n * - Automatic retries with exponential backoff\n * - Configurable timeouts\n * - Better error handling for network failures\n */\n\nimport { createLogger } from './logger';\n\nconst logger = createLogger('FetchUtils');\n\n/**\n * Configuration for fetch retry behavior\n */\nexport interface RetryConfig {\n /**\n * Maximum number of retry attempts (default: 3)\n */\n maxRetries?: number;\n \n /**\n * Initial delay in milliseconds before first retry (default: 300ms)\n */\n initialDelayMs?: number;\n \n /**\n * Multiplier for exponential backoff (default: 2)\n */\n backoffMultiplier?: number;\n \n /**\n * Maximum delay between retries in milliseconds (default: 5000ms)\n */\n maxDelayMs?: number;\n \n /**\n * Timeout for each fetch attempt in milliseconds (default: 10000ms - 10 seconds)\n */\n timeoutMs?: number;\n \n /**\n * HTTP status codes that should trigger a retry (default: [408, 429, 500, 502, 503, 504])\n */\n retryableStatusCodes?: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelayMs: 300,\n backoffMultiplier: 2,\n maxDelayMs: 5000,\n timeoutMs: 10000, // 10 seconds\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\n/**\n * Sleep utility for delays between retries\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Calculate delay for exponential backoff\n */\nfunction calculateDelay(\n attempt: number,\n config: Required<RetryConfig>\n): number {\n const delay = config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt);\n return Math.min(delay, config.maxDelayMs);\n}\n\n/**\n * Check if error is retryable\n */\nfunction isRetryableError(error: any, config: Required<RetryConfig>): boolean {\n // Network errors (fetch failed, connection refused, etc.)\n if (error.name === 'TypeError' || error.message?.includes('fetch failed')) {\n return true;\n }\n \n // Timeout errors\n if (error.name === 'AbortError' || error.message?.includes('timeout')) {\n return true;\n }\n \n // HTTP status codes\n if (error.status && config.retryableStatusCodes.includes(error.status)) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Enhanced fetch with retry logic and timeout\n * \n * @example\n * ```typescript\n * import { fetchWithRetry } from '@thorprovider/adapters/core/fetch-utils';\n * \n * // Basic usage with defaults (3 retries, 10s timeout)\n * const response = await fetchWithRetry('https://api.example.com/products');\n * \n * // Custom configuration\n * const response = await fetchWithRetry(\n * 'https://api.example.com/products',\n * {\n * method: 'POST',\n * body: JSON.stringify({ name: 'Product' }),\n * },\n * {\n * maxRetries: 5,\n * timeoutMs: 15000, // 15 seconds\n * initialDelayMs: 500,\n * }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n init?: RequestInit,\n retryConfig?: RetryConfig\n): Promise<Response> {\n const config = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };\n let lastError: any;\n \n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n try {\n // Create AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), config.timeoutMs);\n \n const fetchOptions: RequestInit = {\n ...init,\n signal: controller.signal,\n };\n \n logger.debug('Fetch attempt', {\n url,\n attempt: attempt + 1,\n maxAttempts: config.maxRetries + 1,\n timeout: config.timeoutMs,\n });\n \n // Execute fetch\n const response = await fetch(url, fetchOptions);\n \n // Clear timeout\n clearTimeout(timeoutId);\n \n // Check if status code is retryable\n if (!response.ok && config.retryableStatusCodes.includes(response.status)) {\n const error = new Error(`HTTP ${response.status}: ${response.statusText}`);\n (error as any).status = response.status;\n throw error;\n }\n \n // Success!\n logger.debug('Fetch successful', { url, attempt: attempt + 1 });\n return response;\n \n } catch (error: any) {\n lastError = error;\n \n // Clear timeout if it exists\n if (error.name === 'AbortError') {\n lastError = new Error(`Request timeout after ${config.timeoutMs}ms`);\n lastError.name = 'TimeoutError';\n }\n \n // Check if we should retry\n const shouldRetry = attempt < config.maxRetries && isRetryableError(error, config);\n \n if (shouldRetry) {\n const delay = calculateDelay(attempt, config);\n logger.warn('Fetch failed, retrying...', {\n url,\n attempt: attempt + 1,\n maxAttempts: config.maxRetries + 1,\n nextRetryIn: `${delay}ms`,\n error: error.message,\n });\n \n await sleep(delay);\n } else {\n logger.error('Fetch failed after all retries', {\n url,\n totalAttempts: attempt + 1,\n error: error.message,\n });\n break;\n }\n }\n }\n \n // All retries exhausted, throw the last error\n throw lastError;\n}\n\n/**\n * Create a fetch function with custom retry configuration\n * Useful for creating a configured fetch instance\n * \n * @example\n * ```typescript\n * import { createFetchWithRetry } from '@thorprovider/adapters/core/fetch-utils';\n * \n * // Create configured fetch\n * const customFetch = createFetchWithRetry({\n * maxRetries: 5,\n * timeoutMs: 15000,\n * });\n * \n * // Use it like regular fetch\n * const response = await customFetch('https://api.example.com/products');\n * ```\n */\nexport function createFetchWithRetry(\n retryConfig?: RetryConfig\n): (url: string, init?: RequestInit) => Promise<Response> {\n return (url: string, init?: RequestInit) => fetchWithRetry(url, init, retryConfig);\n}\n","/**\n * Circuit Breaker Pattern Implementation\n * \n * Prevents cascading failures when the backend is unavailable.\n * Implements the Circuit Breaker pattern as described by Martin Fowler.\n * \n * States:\n * - CLOSED: Normal operation, requests pass through\n * - OPEN: Too many failures, requests fail fast\n * - HALF_OPEN: Testing if backend has recovered\n * \n * @see https://martinfowler.com/bliki/CircuitBreaker.html\n */\n\nexport type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit */\n failureThreshold: number;\n /** Time in ms to wait before attempting recovery */\n resetTimeout: number;\n /** Name for logging/monitoring */\n name?: string;\n}\n\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failureCount: number;\n lastFailureTime: number | null;\n totalRequests: number;\n totalFailures: number;\n totalSuccesses: number;\n}\n\n/**\n * Circuit Breaker Class\n * \n * Monitors backend calls and prevents cascading failures by\n * failing fast when the backend is unhealthy.\n * \n * @example\n * ```ts\n * const breaker = new CircuitBreaker({\n * failureThreshold: 3,\n * resetTimeout: 60000, // 1 minute\n * name: 'backend-api'\n * });\n * \n * const result = await breaker.execute(\n * () => fetch('/api/data'),\n * fallbackData\n * );\n * ```\n */\nexport class CircuitBreaker {\n private failureCount = 0;\n private lastFailureTime: number | null = null;\n private totalRequests = 0;\n private totalFailures = 0;\n private totalSuccesses = 0;\n \n constructor(private config: CircuitBreakerConfig) {\n this.config = {\n failureThreshold: config.failureThreshold || 5,\n resetTimeout: config.resetTimeout || 60000, // 1 minute default\n name: config.name || 'circuit-breaker',\n };\n }\n \n /**\n * Get current circuit state\n */\n get state(): CircuitState {\n if (this.failureCount >= this.config.failureThreshold) {\n // Circuit is open (failing fast)\n if (this.shouldAttemptReset()) {\n return 'HALF_OPEN'; // Try to recover\n }\n return 'OPEN';\n }\n return 'CLOSED'; // Normal operation\n }\n \n /**\n * Get circuit breaker statistics\n */\n get stats(): CircuitBreakerStats {\n return {\n state: this.state,\n failureCount: this.failureCount,\n lastFailureTime: this.lastFailureTime,\n totalRequests: this.totalRequests,\n totalFailures: this.totalFailures,\n totalSuccesses: this.totalSuccesses,\n };\n }\n \n /**\n * Execute a function with circuit breaker protection\n * \n * @param fn - Function to execute\n * @param fallback - Fallback value if circuit is open\n * @returns Result from fn or fallback\n */\n async execute<T>(\n fn: () => Promise<T>,\n fallback?: T\n ): Promise<T> {\n this.totalRequests++;\n \n const currentState = this.state;\n \n // If circuit is OPEN and we have a fallback, return it immediately\n if (currentState === 'OPEN') {\n this.log('Circuit is OPEN - failing fast');\n if (fallback !== undefined) {\n return fallback;\n }\n throw new CircuitBreakerOpenError(\n `Circuit breaker \"${this.config.name}\" is OPEN - backend may be unavailable`\n );\n }\n \n // Try to execute the function\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n this.onFailure();\n \n // If we have a fallback, use it\n if (fallback !== undefined) {\n this.log('Returning fallback due to error:', error);\n return fallback;\n }\n \n // Otherwise, re-throw the error\n throw error;\n }\n }\n \n /**\n * Check if circuit should attempt to reset\n */\n private shouldAttemptReset(): boolean {\n if (!this.lastFailureTime) return false;\n \n const timeSinceLastFailure = Date.now() - this.lastFailureTime;\n return timeSinceLastFailure >= this.config.resetTimeout;\n }\n \n /**\n * Record a successful call\n */\n private onSuccess(): void {\n this.totalSuccesses++;\n this.reset();\n this.log('Request succeeded - circuit reset');\n }\n \n /**\n * Record a failed call\n */\n private onFailure(): void {\n this.failureCount++;\n this.totalFailures++;\n this.lastFailureTime = Date.now();\n \n if (this.state === 'OPEN') {\n this.log(`Circuit OPENED after ${this.failureCount} failures`);\n } else {\n this.log(`Failure recorded (${this.failureCount}/${this.config.failureThreshold})`);\n }\n }\n \n /**\n * Reset circuit to CLOSED state\n */\n private reset(): void {\n this.failureCount = 0;\n this.lastFailureTime = null;\n }\n \n /**\n * Manually reset the circuit breaker\n */\n public manualReset(): void {\n this.reset();\n this.log('Circuit manually reset');\n }\n \n /**\n * Log messages (only in development)\n */\n private log(...args: unknown[]): void {\n if (process.env.NODE_ENV === 'development') {\n console.log(`[CircuitBreaker:${this.config.name}]`, ...args);\n }\n }\n}\n\n/**\n * Custom error for when circuit is open\n */\nexport class CircuitBreakerOpenError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CircuitBreakerOpenError';\n }\n}\n\n/**\n * Global circuit breaker instance for backend API calls\n * \n * Can be imported and used throughout the application\n */\nexport const backendCircuitBreaker = new CircuitBreaker({\n failureThreshold: 5, // Open after 5 failures\n resetTimeout: 60000, // Try to recover after 1 minute\n name: 'backend-api',\n});\n","/**\n * @thorprovider/adapters\n * Money transformation utilities\n * \n * Handles conversion between domain Money types (string decimals) and\n * UI-ready number representations (smallest currency unit, e.g., cents).\n */\n\nimport type { Money } from '@thorprovider/types';\n\n/**\n * Converts Money object to number in smallest currency unit\n * \n * Money.amount is a decimal string (e.g., \"45.99\").\n * This function converts it to smallest unit (e.g., 4599 cents).\n * \n * @param money - Money object with decimal string amount\n * @returns Amount in smallest currency unit (e.g., cents for USD)\n * \n * @example\n * ```typescript\n * moneyToNumber({ amount: \"45.99\", currencyCode: \"USD\" }) // => 4599\n * moneyToNumber({ amount: \"100.00\", currencyCode: \"EUR\" }) // => 10000\n * moneyToNumber({ amount: \"0.50\", currencyCode: \"USD\" }) // => 50\n * ```\n */\nexport function moneyToNumber(money: Money): number {\n // Parse decimal string and convert to cents (multiply by 100)\n const amountInMajorUnits = parseFloat(money.amount);\n const amountInMinorUnits = Math.round(amountInMajorUnits * 100);\n return amountInMinorUnits;\n}\n\n/**\n * Converts number (smallest unit) to Money object\n * \n * Takes an amount in smallest currency unit (e.g., cents) and\n * converts it to a Money object with decimal string amount.\n * \n * @param amount - Amount in smallest currency unit (e.g., cents)\n * @param currency - ISO 4217 currency code (e.g., 'USD', 'EUR')\n * @returns Money object with decimal string amount\n * \n * @example\n * ```typescript\n * numberToMoney(4599, 'USD') // => { amount: \"45.99\", currencyCode: \"USD\" }\n * numberToMoney(10000, 'EUR') // => { amount: \"100.00\", currencyCode: \"EUR\" }\n * numberToMoney(50, 'USD') // => { amount: \"0.50\", currencyCode: \"USD\" }\n * ```\n */\nexport function numberToMoney(amount: number, currency: string): Money {\n // Convert cents to dollars and format as decimal string\n const amountInMajorUnits = amount / 100;\n const formattedAmount = amountInMajorUnits.toFixed(2);\n \n return {\n amount: formattedAmount,\n currencyCode: currency,\n };\n}\n\n/**\n * Safely converts Money to number, returning 0 for null/undefined\n * \n * Useful for optional Money fields that might not always be present.\n * \n * @param money - Money object or null/undefined\n * @returns Amount in smallest unit, or 0 if money is null/undefined\n * \n * @example\n * ```typescript\n * moneyToNumberSafe({ amount: \"10.00\", currencyCode: \"USD\" }) // => 1000\n * moneyToNumberSafe(undefined) // => 0\n * moneyToNumberSafe(null) // => 0\n * ```\n */\nexport function moneyToNumberSafe(money: Money | null | undefined): number {\n if (!money) return 0;\n return moneyToNumber(money);\n}\n","/**\n * @thorprovider/adapters - Payment Utilities\n * \n * Backend-agnostic utilities for extracting backend provider IDs from\n * normalized PaymentMethod objects using metadata.\n * \n * This solves the problem of losing backend-specific provider IDs during\n * transformation to frontend-friendly formats.\n * \n * @module payment-utils\n * @since 2.0.0\n */\n\nimport type { PaymentMethod } from '@thorprovider/types';\n\n/**\n * Backend mapping metadata stored in PaymentMethod.metadata\n * \n * This metadata is added during payment method transformation\n * to preserve the original backend-specific identifier.\n * \n * @example\n * ```typescript\n * const metadata = {\n * _backendMapping: {\n * backend: 'medusa',\n * originalId: 'pp_stripe_stripe',\n * normalizedType: 'card'\n * }\n * };\n * ```\n */\nexport interface BackendMapping {\n /**\n * Backend type (e.g., 'medusa', 'shopify', 'woocommerce')\n */\n backend: string;\n \n /**\n * Original backend-specific provider ID\n * \n * Examples:\n * - Medusa: 'pp_stripe_stripe', 'pp_paypal_paypal', 'pp_system_default'\n * - Shopify: 'shopify_payments', 'paypal_express'\n * - WooCommerce: 'stripe', 'paypal', 'cod'\n */\n originalId: string;\n \n /**\n * Normalized payment method type\n * \n * The frontend-friendly type we inferred from the backend ID\n * (e.g., 'card', 'wallet', 'bank_transfer', 'cash_on_delivery')\n */\n normalizedType: string;\n}\n\n/**\n * Extract backend provider ID from PaymentMethod\n * \n * Uses the `_backendMapping` metadata to retrieve the original\n * backend-specific provider ID that should be sent to API calls.\n * \n * **Why this exists:**\n * During transformation, we normalize backend IDs to friendly types:\n * - Backend: 'pp_stripe_stripe' → Frontend: type 'card'\n * - Backend: 'pp_system_default' → Frontend: type 'cash_on_delivery'\n * \n * But when making API calls, we need the ORIGINAL backend ID, not the type.\n * This function extracts it from metadata.\n * \n * @param method - PaymentMethod with _backendMapping metadata\n * @returns Backend provider ID (e.g., 'pp_stripe_stripe', 'pp_system_default')\n * @throws {Error} If _backendMapping metadata is missing or invalid\n * \n * @example\n * ```typescript\n * // PaymentMethod from backend with metadata\n * const method = {\n * id: 'pp_system_default',\n * type: 'cash_on_delivery',\n * name: 'Cash on Delivery',\n * metadata: {\n * _backendMapping: {\n * backend: 'medusa',\n * originalId: 'pp_system_default',\n * normalizedType: 'cash_on_delivery'\n * }\n * }\n * };\n * \n * const providerId = getBackendProviderId(method);\n * // Returns: 'pp_system_default'\n * \n * // Now safe to use with backend API:\n * await commerce.initiatePaymentSession(cartId, providerId);\n * ```\n * \n * @example\n * ```typescript\n * // Handling missing metadata\n * try {\n * const providerId = getBackendProviderId(methodWithoutMetadata);\n * } catch (error) {\n * console.error('Payment method missing backend mapping:', error.message);\n * // Error: PaymentMethod 'stripe' is missing _backendMapping metadata.\n * // This is required to extract the backend provider ID.\n * }\n * ```\n */\nexport function getBackendProviderId(method: PaymentMethod): string {\n const mapping = method.metadata?._backendMapping as BackendMapping | undefined;\n \n if (!mapping) {\n throw new Error(\n `PaymentMethod '${method.id}' is missing _backendMapping metadata. ` +\n `This is required to extract the backend provider ID. ` +\n `Ensure the payment method was transformed with metadata preservation. ` +\n `Check transformPaymentMethod() implementation in your provider adapter.`\n );\n }\n \n if (!mapping.originalId) {\n throw new Error(\n `PaymentMethod '${method.id}' has invalid _backendMapping metadata: ` +\n `'originalId' field is missing or empty. ` +\n `Expected structure: { _backendMapping: { backend: 'medusa', originalId: 'pp_...', normalizedType: '...' } }`\n );\n }\n \n return mapping.originalId;\n}\n\n/**\n * Validate payment provider ID format\n * \n * Checks if the provider ID is a valid backend-specific identifier,\n * not a normalized type like 'card', 'wallet', etc.\n * \n * **Why this exists:**\n * Common bug: Accidentally sending normalized types to backend APIs:\n * ❌ `initiatePaymentSession(cartId, 'card')` → Backend error\n * ✅ `initiatePaymentSession(cartId, 'pp_stripe_stripe')` → Success\n * \n * This validation catches the bug at runtime with a helpful error message.\n * \n * @param id - Provider ID to validate\n * @throws {Error} If ID appears to be a normalized type instead of backend ID\n * \n * @example\n * ```typescript\n * // Valid backend IDs - pass validation:\n * validatePaymentId('pp_stripe_stripe'); // ✅ OK (Medusa)\n * validatePaymentId('pp_system_default'); // ✅ OK (Medusa)\n * validatePaymentId('shopify_payments'); // ✅ OK (Shopify)\n * validatePaymentId('stripe'); // ✅ OK (WooCommerce)\n * validatePaymentId('paypal_express'); // ✅ OK (generic)\n * \n * // Invalid (normalized types) - throw error:\n * validatePaymentId('card'); // ❌ Throws error\n * validatePaymentId('wallet'); // ❌ Throws error\n * validatePaymentId('cash_on_delivery'); // ❌ Throws error\n * ```\n * \n * @example\n * ```typescript\n * // Use before API calls:\n * async function initiatePayment(cartId: string, providerId: string) {\n * // Validate before sending to backend\n * validatePaymentId(providerId);\n * \n * return await sdk.payment.initiatePaymentSession(cart, {\n * provider_id: providerId\n * });\n * }\n * \n * // Catches bugs early:\n * await initiatePayment(cartId, 'card');\n * // ❌ Error: Invalid payment provider ID: 'card'.\n * // This appears to be a normalized payment type, not a backend provider ID.\n * // Use getBackendProviderId() to extract the correct backend ID from PaymentMethod.\n * ```\n */\nexport function validatePaymentId(id: string): void {\n const normalizedTypes = [\n 'card',\n 'wallet',\n 'bank_transfer',\n 'buy_now_pay_later',\n 'cash_on_delivery',\n 'crypto',\n 'other'\n ];\n \n if (normalizedTypes.includes(id)) {\n throw new Error(\n `Invalid payment provider ID: '${id}'. ` +\n `This appears to be a normalized payment type, not a backend provider ID. ` +\n `Use getBackendProviderId() to extract the correct backend ID from PaymentMethod. ` +\n `Expected format examples: 'pp_stripe_stripe', 'pp_system_default', 'shopify_payments', 'stripe'`\n );\n }\n}\n","/**\n * City coordinates lookup table\n *\n * Lightweight approximation for geocoding without external APIs.\n * Keep this small and extend as needed.\n */\n\nexport interface CityCoordinates {\n lat: number;\n lng: number;\n}\n\nconst CITY_COORDINATES: Record<string, Record<string, CityCoordinates>> = {\n US: {\n 'New York': { lat: 40.7128, lng: -74.0060 },\n 'Los Angeles': { lat: 34.0522, lng: -118.2437 },\n Chicago: { lat: 41.8781, lng: -87.6298 },\n Miami: { lat: 25.7617, lng: -80.1918 },\n },\n GB: {\n London: { lat: 51.5074, lng: -0.1278 },\n Manchester: { lat: 53.4808, lng: -2.2426 },\n },\n DE: {\n Berlin: { lat: 52.52, lng: 13.405 },\n Hamburg: { lat: 53.5511, lng: 9.9937 },\n },\n ES: {\n Madrid: { lat: 40.4168, lng: -3.7038 },\n Barcelona: { lat: 41.3851, lng: 2.1734 },\n },\n};\n\nexport function getCityCoordinates(city: string, countryCode: string): CityCoordinates | null {\n const country = CITY_COORDINATES[countryCode.toUpperCase()];\n if (!country) return null;\n\n const cityKey = Object.keys(country).find((key) => key.toLowerCase() === city.toLowerCase());\n return cityKey ? country[cityKey] : null;\n}\n","/**\n * Geolocation utilities\n *\n * Framework-agnostic helpers for proximity-based fulfillment.\n */\n\nimport { getCityCoordinates } from './city-coordinates';\n\nexport interface Coordinates {\n lat: number;\n lng: number;\n}\n\n/**\n * Calculate distance between two coordinates using the Haversine formula.\n * @returns Distance in kilometers\n */\nexport function calculateDistance(from: Coordinates, to: Coordinates): number {\n const R = 6371;\n const dLat = toRad(to.lat - from.lat);\n const dLng = toRad(to.lng - from.lng);\n\n const a =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.cos(toRad(from.lat)) *\n Math.cos(toRad(to.lat)) *\n Math.sin(dLng / 2) *\n Math.sin(dLng / 2);\n\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n return R * c;\n}\n\nfunction toRad(degrees: number): number {\n return degrees * (Math.PI / 180);\n}\n\n/**\n * Geocode an address to coordinates.\n *\n * This is intentionally a best-effort approximation (city + country lookup).\n * For production-grade accuracy, integrate a real geocoding provider.\n */\nexport async function geocodeAddress(address: {\n city?: string;\n countryCode?: string;\n postalCode?: string;\n}): Promise<Coordinates | null> {\n if (!address.city || !address.countryCode) return null;\n\n return getCityCoordinates(address.city, address.countryCode);\n}\n","/**\n * Fulfillment planner\n *\n * Plans an optimal fulfillment strategy for cart items given:\n * - available stock locations\n * - inventory levels per variant\n * - an optional shipping address (for proximity sorting)\n */\n\nimport type { CartItem, InventoryLevel, StockLocation, FulfillmentOption } from '@thorprovider/types';\nimport { calculateDistance, geocodeAddress, type Coordinates } from '../../utils/geolocation';\n\nexport interface FulfillmentGroup {\n locationId: string;\n locationName: string;\n items: Array<{\n variantId: string;\n quantity: number;\n productName: string;\n }>;\n shippingOptions: FulfillmentOption[];\n}\n\nexport interface FulfillmentPlan {\n canFulfill: boolean;\n groups: FulfillmentGroup[];\n shippingAddress?: Coordinates;\n}\n\nexport interface PlanFulfillmentShippingAddress {\n city?: string;\n countryCode?: string;\n postalCode?: string;\n}\n\ninterface InventoryMap {\n [variantId: string]: InventoryLevel[];\n}\n\nexport async function planFulfillment(\n cartItems: CartItem[],\n stockLocations: StockLocation[],\n inventoryLevels: InventoryMap,\n shippingAddress?: PlanFulfillmentShippingAddress,\n): Promise<FulfillmentPlan> {\n if (cartItems.length === 0) {\n return { canFulfill: true, groups: [] };\n }\n\n let addressCoords: Coordinates | null = null;\n if (shippingAddress) {\n addressCoords = await geocodeAddress(shippingAddress);\n }\n\n const itemLocationMap = new Map<string, string[]>();\n\n for (const item of cartItems) {\n const variantId = item.merchandise.id;\n const levels = inventoryLevels[variantId] ?? [];\n\n const availableLocations = levels\n .filter((level) => level.availableQuantity >= item.quantity)\n .map((level) => level.locationId);\n\n itemLocationMap.set(variantId, availableLocations);\n }\n\n const singleLocationPlan = findSingleLocationFulfillment(\n cartItems,\n stockLocations,\n itemLocationMap,\n addressCoords,\n );\n\n if (singleLocationPlan) {\n return {\n canFulfill: true,\n groups: [singleLocationPlan],\n shippingAddress: addressCoords ?? undefined,\n };\n }\n\n const splitPlan = findSplitFulfillment(cartItems, stockLocations, inventoryLevels, addressCoords);\n\n return {\n canFulfill: splitPlan.groups.length > 0,\n groups: splitPlan.groups,\n shippingAddress: addressCoords ?? undefined,\n };\n}\n\nfunction findSingleLocationFulfillment(\n items: CartItem[],\n locations: StockLocation[],\n itemLocationMap: Map<string, string[]>,\n shippingCoords: Coordinates | null,\n): FulfillmentGroup | null {\n const firstVariantId = items[0]?.merchandise?.id;\n if (!firstVariantId) return null;\n\n const firstItemLocations = itemLocationMap.get(firstVariantId);\n if (!firstItemLocations || firstItemLocations.length === 0) {\n return null;\n }\n\n const locationCandidates = new Set<string>(firstItemLocations);\n\n for (let i = 1; i < items.length; i++) {\n const variantId = items[i]?.merchandise?.id;\n if (!variantId) return null;\n\n const itemLocations = itemLocationMap.get(variantId) ?? [];\n const itemLocationsSet = new Set(itemLocations);\n\n for (const loc of locationCandidates) {\n if (!itemLocationsSet.has(loc)) {\n locationCandidates.delete(loc);\n }\n }\n\n if (locationCandidates.size === 0) return null;\n }\n\n let selectedLocationId = Array.from(locationCandidates)[0];\n\n if (shippingCoords) {\n let minDistance = Infinity;\n\n for (const locId of locationCandidates) {\n const location = locations.find((l) => l.id === locId);\n const lat = location?.metadata?.lat;\n const lng = location?.metadata?.lng;\n if (typeof lat !== 'number' || typeof lng !== 'number') continue;\n\n const distance = calculateDistance(shippingCoords, { lat, lng });\n if (distance < minDistance) {\n minDistance = distance;\n selectedLocationId = locId;\n }\n }\n }\n\n const selectedLocation = locations.find((l) => l.id === selectedLocationId);\n if (!selectedLocation) return null;\n\n return {\n locationId: selectedLocationId,\n locationName: selectedLocation.name,\n items: items.map((item) => ({\n variantId: item.merchandise.id,\n quantity: item.quantity,\n productName: item.merchandise.product.title,\n })),\n shippingOptions: [],\n };\n}\n\nfunction findSplitFulfillment(\n items: CartItem[],\n locations: StockLocation[],\n inventoryLevels: InventoryMap,\n shippingCoords: Coordinates | null,\n): { groups: FulfillmentGroup[] } {\n const groups: FulfillmentGroup[] = [];\n const assignedVariantIds = new Set<string>();\n\n const sortedLocations = sortLocationsByProximity(locations, shippingCoords);\n\n for (const location of sortedLocations) {\n const groupItems: FulfillmentGroup['items'] = [];\n\n for (const item of items) {\n const variantId = item.merchandise.id;\n if (assignedVariantIds.has(variantId)) continue;\n\n const levels = inventoryLevels[variantId] ?? [];\n const levelAtLocation = levels.find((l) => l.locationId === location.id);\n\n if (levelAtLocation && levelAtLocation.availableQuantity >= item.quantity) {\n groupItems.push({\n variantId,\n quantity: item.quantity,\n productName: item.merchandise.product.title,\n });\n assignedVariantIds.add(variantId);\n }\n }\n\n if (groupItems.length > 0) {\n groups.push({\n locationId: location.id,\n locationName: location.name,\n items: groupItems,\n shippingOptions: [],\n });\n }\n\n if (assignedVariantIds.size === items.length) {\n break;\n }\n }\n\n return { groups };\n}\n\nfunction sortLocationsByProximity(\n locations: StockLocation[],\n shippingCoords: Coordinates | null,\n): StockLocation[] {\n if (!shippingCoords) return [...locations];\n\n return [...locations].sort((a, b) => {\n const distA =\n typeof a.metadata?.lat === 'number' && typeof a.metadata?.lng === 'number'\n ? calculateDistance(shippingCoords, { lat: a.metadata.lat, lng: a.metadata.lng })\n : Infinity;\n\n const distB =\n typeof b.metadata?.lat === 'number' && typeof b.metadata?.lng === 'number'\n ? calculateDistance(shippingCoords, { lat: b.metadata.lat, lng: b.metadata.lng })\n : Infinity;\n\n return distA - distB;\n });\n}\n","/**\n * @thorprovider/adapters v2.0\n * Medusa Provider - Transform functions\n * \n * These functions convert Medusa-specific types to our unified types\n */\n\n// Note: We use 'any' for Medusa types because the SDK returns different types\n// than what's in @medusajs/types (StoreProduct vs ProductDTO)\n\nimport type {\n Product,\n ProductVariant,\n ProductOption,\n Cart,\n CartItem,\n Collection,\n ProductCategory,\n Money,\n Image,\n StockLocation,\n InventoryLevel,\n FulfillmentOption,\n Order,\n OrderItem,\n OrderStatus,\n PaymentStatus,\n FulfillmentStatus,\n Address,\n Customer,\n StorefrontConfig,\n} from '@thorprovider/types';\n\n/**\n * Transform Medusa Money to unified Money\n *\n * Medusa v2 stores and returns monetary amounts in MAJOR units (dollars, euros, etc.).\n * Reference: https://docs.medusajs.com/resources/commerce-modules/pricing/concepts\n * \"The Price data model has an `amount` property...It's stored as an integer in major units.\n * For example, $20.00 is stored as 20, and $20.5 is stored as 20.5.\"\n *\n * Money.amount in @thorprovider/types is a decimal string in major units (e.g., \"45.00\").\n * No division by 100 is needed — the value comes through as-is.\n */\nfunction transformMoney(amount: number | null | undefined, currencyCode: string = 'USD'): Money {\n return {\n amount: (amount ?? 0).toFixed(2), // Medusa v2 sends major units (dollars/euros), not cents\n currencyCode: currencyCode.toUpperCase(),\n };\n}\n\n/**\n * Transform Medusa image to unified Image\n */\nfunction transformImage(url: string, alt: string = ''): Image {\n return {\n url,\n altText: alt,\n width: 800,\n height: 800,\n };\n}\n\n// ============================================\n// Inventory & Fulfillment Transforms\n// ============================================\n\nexport function transformStockLocation(raw: any): StockLocation {\n return {\n id: raw.id,\n name: raw.name,\n address: raw.address\n ? {\n address1: raw.address.address_1,\n address2: raw.address.address_2,\n city: raw.address.city,\n countryCode: raw.address.country_code,\n postalCode: raw.address.postal_code,\n province: raw.address.province,\n }\n : undefined,\n metadata: raw.metadata,\n };\n}\n\nexport function transformInventoryLevel(raw: any, locationName: string): InventoryLevel {\n return {\n locationId: raw.location_id,\n locationName,\n availableQuantity: raw.available_quantity ?? 0,\n reservedQuantity: raw.reserved_quantity ?? 0,\n incomingQuantity: raw.incoming_quantity,\n stockedQuantity: raw.stocked_quantity ?? 0,\n };\n}\n\nexport function transformFulfillmentOption(\n shippingOption: any,\n location: StockLocation,\n currencyCode: string,\n): FulfillmentOption {\n return {\n id: shippingOption.id,\n providerId: shippingOption.provider_id,\n name: shippingOption.name,\n description: shippingOption.description,\n price: transformMoney(shippingOption.amount, currencyCode),\n estimatedDays: shippingOption.metadata?.estimated_days,\n stockLocation: location,\n };\n}\n\n/**\n * Transform Medusa ProductOption to unified ProductOption\n */\nexport function transformProductOption(option: any): ProductOption {\n return {\n id: option.id!,\n name: option.title ?? '',\n values: option.values?.map((v: any) => v.value ?? '') ?? [],\n };\n}\n\n/**\n * Transform Medusa ProductVariant to unified ProductVariant\n */\nexport function transformProductVariant(\n variant: any,\n currencyCode: string = 'USD'\n): ProductVariant {\n let priceAmount: number | null | undefined;\n let priceCurrency: string = currencyCode;\n \n // Priority 1: Use calculated_price if available (from region-based pricing)\n if (variant.calculated_price) {\n priceAmount = variant.calculated_price.calculated_amount;\n priceCurrency = variant.calculated_price.currency_code || currencyCode;\n } \n // Priority 2: Fallback to prices array\n else if (variant.prices && variant.prices.length > 0) {\n const price = variant.prices.find((p: any) => p.currency_code === currencyCode.toLowerCase());\n priceAmount = price?.amount;\n priceCurrency = price?.currency_code || currencyCode;\n }\n \n // Determine if variant is available for sale\n // Following Medusa docs: https://docs.medusajs.com/resources/storefront-development/products/inventory\n // A variant is in stock if:\n // 1. manage_inventory is false (inventory not tracked) - always in stock\n // 2. inventory_quantity > 0 (has stock)\n // 3. allow_backorder is true (can order even without stock)\n const isAvailable = variant.manage_inventory === false\n ? true\n : (variant.inventory_quantity ?? 0) > 0 || variant.allow_backorder === true;\n \n return {\n id: variant.id!,\n title: variant.title ?? 'Default',\n sku: variant.sku ?? undefined,\n availableForSale: isAvailable,\n selectedOptions: variant.options?.map((opt: any) => ({\n name: (opt as any).option?.title ?? '',\n value: opt.value ?? '',\n })) ?? [],\n price: transformMoney(priceAmount, priceCurrency),\n compareAtPrice: undefined, // Medusa doesn't have compare-at pricing\n quantityAvailable: variant.manage_inventory ? variant.inventory_quantity : undefined,\n image: variant.thumbnail\n ? transformImage(variant.thumbnail, variant.title ?? '')\n : undefined,\n };\n}\n\n/**\n * Transform Medusa Product to unified Product\n */\nexport function transformProduct(\n product: any,\n currencyCode: string = 'USD'\n): Product {\n const variants = product.variants?.map((v: any) => transformProductVariant(v, currencyCode)) ?? [];\n \n // Calculate price range\n const prices = variants.map((v: any) => parseFloat(v.price.amount));\n const minPrice = Math.min(...prices);\n const maxPrice = Math.max(...prices);\n \n return {\n id: product.id!,\n handle: product.handle ?? '',\n title: product.title ?? '',\n description: product.description ?? '',\n descriptionHtml: product.description ?? '',\n // Medusa v2 /store/products API doesn't return 'status' field (it's null)\n // Products returned by Store API are already published, so we check if any variant is available\n availableForSale: variants.length > 0 && variants.some((v: ProductVariant) => v.availableForSale),\n \n options: product.options?.map(transformProductOption) ?? [],\n variants,\n \n featuredImage: product.thumbnail\n ? transformImage(product.thumbnail, product.title ?? '')\n : undefined,\n \n images: product.images?.map((img: any) => transformImage(img.url ?? '', product.title ?? '')) ?? [],\n \n priceRange: {\n // Build Money directly from already-resolved major-unit prices.\n // Do NOT pass through transformMoney (which would call toFixed on already-correct values)\n // and do NOT multiply by 100 (that was a compensatory hack for the old /100 bug).\n minVariantPrice: { amount: (Number.isFinite(minPrice) ? minPrice : 0).toFixed(2), currencyCode: currencyCode.toUpperCase() },\n maxVariantPrice: { amount: (Number.isFinite(maxPrice) ? maxPrice : 0).toFixed(2), currencyCode: currencyCode.toUpperCase() },\n },\n \n collections: product.collection ? [{\n id: product.collection.id,\n title: product.collection.title ?? '',\n handle: product.collection.handle ?? '',\n }] : undefined,\n \n productType: product.type?.value ?? undefined,\n vendor: undefined, // Medusa doesn't have vendor field\n tags: product.tags?.map((t: any) => t.value ?? '') ?? [],\n \n seo: {\n title: product.title ?? '',\n description: product.description ?? '',\n },\n \n createdAt: typeof product.created_at === 'string' \n ? product.created_at \n : product.created_at?.toISOString() ?? new Date().toISOString(),\n updatedAt: typeof product.updated_at === 'string' \n ? product.updated_at \n : product.updated_at?.toISOString() ?? new Date().toISOString(),\n \n metadata: product.metadata ?? undefined,\n };\n}\n\n/**\n * Transform Medusa LineItem to unified CartItem\n */\nfunction resolveMedusaCartItemCurrencyCode(item: any, cartCurrencyCode?: string): string {\n return (\n item?.cart?.currency_code ??\n cartCurrencyCode ??\n 'usd'\n );\n}\n\n/**\n * Resolve the total amount for a Medusa cart item.\n * All amounts from Medusa v2 are in major units (dollars, euros).\n */\nfunction resolveMedusaCartItemTotal(item: any): number {\n const quantity = item?.quantity ?? 1;\n const safeQuantity = typeof quantity === 'number' && quantity > 0 ? quantity : 1;\n\n const totalCandidates = [\n item?.total,\n item?.item_total,\n item?.original_total,\n item?.subtotal,\n item?.item_subtotal,\n item?.original_subtotal,\n ];\n\n for (const candidate of totalCandidates) {\n if (typeof candidate === 'number' && Number.isFinite(candidate) && candidate > 0) {\n return candidate;\n }\n }\n\n const unitCandidates = [\n item?.unit_price,\n item?.original_unit_price,\n ];\n\n for (const candidate of unitCandidates) {\n if (typeof candidate === 'number' && Number.isFinite(candidate) && candidate > 0) {\n return candidate * safeQuantity;\n }\n }\n\n return 0;\n}\n\nexport function transformCartItem(item: any, cartCurrencyCode?: string): CartItem {\n const variant = item.variant;\n const product = variant?.product;\n const currencyCode = resolveMedusaCartItemCurrencyCode(item, cartCurrencyCode);\n const totalCents = resolveMedusaCartItemTotal(item);\n \n return {\n id: item.id,\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: transformMoney(totalCents, currencyCode),\n },\n merchandise: {\n id: variant?.id ?? '',\n title: variant?.title ?? '',\n selectedOptions: variant?.options?.map((opt: any) => ({\n name: (opt as any).option?.title ?? '',\n value: opt.value ?? '',\n })) ?? [],\n product: {\n id: product?.id ?? '',\n handle: product?.handle ?? '',\n title: product?.title ?? '',\n featuredImage: product?.thumbnail\n ? transformImage(product.thumbnail, product.title ?? '')\n : transformImage('', ''),\n },\n },\n };\n}\n\n/**\n * Transform Medusa Cart to unified Cart\n */\nexport function transformCart(cart: any): Cart {\n const currencyCode = cart.currency_code ?? 'usd';\n \n return {\n id: cart.id,\n checkoutUrl: `/checkout/${cart.id}`, // Medusa doesn't have a direct checkout URL\n cost: {\n subtotalAmount: transformMoney(cart.subtotal, currencyCode),\n totalAmount: transformMoney(cart.total, currencyCode),\n totalTaxAmount: transformMoney(cart.tax_total, currencyCode),\n },\n lines: cart.items?.map((item: any) => transformCartItem(item, currencyCode)) ?? [],\n totalQuantity: cart.items?.reduce((sum: any, item: any) => sum + (item.quantity ?? 0), 0) ?? 0,\n completedAt: cart.completed_at\n ? (typeof cart.completed_at === 'string'\n ? cart.completed_at\n : cart.completed_at?.toISOString())\n : undefined,\n };\n}\n\n/**\n * Transform Medusa Collection to unified Collection\n */\nexport function transformCollection(collection: any): Collection {\n return {\n id: collection.id!,\n handle: collection.handle!,\n title: collection.title ?? '',\n description: collection.metadata?.description as string ?? '',\n seo: {\n title: collection.title ?? '',\n description: collection.metadata?.description as string ?? '',\n },\n path: `/collections/${collection.handle}`,\n updatedAt: typeof collection.updated_at === 'string'\n ? collection.updated_at\n : collection.updated_at?.toISOString() ?? new Date().toISOString(),\n };\n}\n\n/**\n * Transform Medusa ProductCategory to unified ProductCategory\n */\nexport function transformCategory(category: any): ProductCategory {\n return {\n id: category.id,\n name: category.name ?? '',\n handle: category.handle ?? '',\n description: category.description ?? undefined,\n parentCategoryId: category.parent_category_id ?? undefined,\n productCount: category.product_count ?? undefined,\n image: category.metadata?.image as string ?? undefined,\n metadata: category.metadata ?? undefined,\n };\n}\n\n/**\n * Transform Medusa order status to unified OrderStatus\n */\nfunction transformOrderStatus(status: string): OrderStatus {\n // Medusa order statuses: pending, completed, archived, canceled, requires_action, draft\n switch (status) {\n case 'pending':\n case 'requires_action':\n case 'draft':\n return 'pending';\n case 'completed':\n return 'completed';\n case 'canceled':\n return 'cancelled';\n case 'archived':\n // Archived could be completed or refunded, default to completed\n return 'completed';\n default:\n return 'processing';\n }\n}\n\n/**\n * Transform Medusa payment status to unified PaymentStatus\n */\nfunction transformPaymentStatus(status: string | undefined): PaymentStatus {\n // Medusa payment statuses: not_paid, awaiting, captured, partially_refunded, refunded, canceled, requires_action\n if (!status || status === 'not_paid' || status === 'requires_action') {\n return 'pending';\n }\n \n if (status === 'awaiting') {\n return 'authorized';\n }\n \n if (status === 'captured') {\n return 'paid';\n }\n \n if (status === 'partially_refunded') {\n return 'partially_refunded';\n }\n \n if (status === 'refunded') {\n return 'refunded';\n }\n \n return 'pending';\n}\n\n/**\n * Transform Medusa fulfillment status to unified FulfillmentStatus\n */\nfunction transformFulfillmentStatus(status: string | undefined): FulfillmentStatus {\n // Medusa fulfillment statuses: not_fulfilled, partially_fulfilled, fulfilled, \n // partially_shipped, shipped, partially_returned, returned, canceled, requires_action\n if (!status || status === 'not_fulfilled' || status === 'canceled') {\n return 'unfulfilled';\n }\n \n if (status === 'partially_fulfilled' || status === 'partially_shipped') {\n return 'partially_fulfilled';\n }\n \n if (status === 'fulfilled' || status === 'shipped') {\n return 'fulfilled';\n }\n \n if (status === 'returned' || status === 'partially_returned') {\n return 'returned';\n }\n \n return 'unfulfilled';\n}\n\n/**\n * Transform Medusa LineItem to unified OrderItem\n */\nexport function transformOrderItem(item: any, currencyCode: string): OrderItem {\n // Defensive checks for null/undefined item or variant\n if (!item) {\n throw new Error('Invalid order item: item is null or undefined');\n }\n \n const variant = item.variant ?? null;\n const product = variant?.product;\n \n return {\n id: item.id,\n title: item.product_title ?? item.title ?? '',\n variantTitle: item.variant_title ?? variant?.title ?? undefined,\n quantity: item.quantity ?? 1,\n price: transformMoney(item.unit_price, currencyCode),\n total: transformMoney(item.total, currencyCode),\n sku: variant?.sku ?? undefined,\n image: product?.thumbnail || item.thumbnail\n ? transformImage(product?.thumbnail || item.thumbnail, item.product_title ?? '')\n : undefined,\n productId: item.product_id ?? product?.id ?? undefined,\n variantId: item.variant_id ?? variant?.id ?? undefined,\n };\n}\n\n/**\n * Transform Medusa Address (snake_case) to unified Address (camelCase)\n */\nexport function transformAddress(address: any): Address {\n return {\n id: address.id ?? undefined,\n firstName: address.first_name ?? '',\n lastName: address.last_name ?? '',\n company: address.company ?? undefined,\n address1: address.address_1 ?? '',\n address2: address.address_2 ?? undefined,\n city: address.city ?? '',\n province: address.province ?? '',\n postalCode: address.postal_code ?? '',\n countryCode: address.country_code ?? '',\n phone: address.phone ?? undefined,\n isDefault: address.is_default ?? address.is_default_shipping ?? undefined,\n };\n}\n\n/**\n * Transform Medusa Customer (snake_case) to unified Customer (camelCase)\n */\nexport function transformCustomer(customer: any, email?: string): Customer {\n return {\n id: customer.id,\n email: customer.email ?? email ?? '',\n firstName: customer.first_name ?? '',\n lastName: customer.last_name ?? '',\n phone: customer.phone ?? undefined,\n hasAccount: customer.has_account ?? false,\n createdAt: typeof customer.created_at === 'string'\n ? customer.created_at\n : customer.created_at?.toISOString() ?? undefined,\n updatedAt: typeof customer.updated_at === 'string'\n ? customer.updated_at\n : customer.updated_at?.toISOString() ?? undefined,\n metadata: customer.metadata ?? undefined,\n };\n}\n\n/**\n * Transform Medusa Order to unified Order\n */\nexport function transformOrder(order: any): Order {\n const currencyCode = order.currency_code ?? 'usd';\n \n return {\n id: order.id,\n orderNumber: order.display_id?.toString() ?? order.id,\n email: order.email ?? '',\n \n // Status (3 separate statuses)\n status: transformOrderStatus(order.status),\n paymentStatus: transformPaymentStatus(order.payment_status),\n fulfillmentStatus: transformFulfillmentStatus(order.fulfillment_status),\n \n // Customer\n customerId: order.customer_id ?? undefined,\n customer: order.customer\n ? transformCustomer(order.customer, order.email)\n : undefined,\n \n // Items\n items: (order.items ?? [])\n .filter((item: any) => item != null) // Filter out null/undefined items\n .map((item: any) => transformOrderItem(item, currencyCode)) ?? [],\n \n // Pricing\n subtotal: transformMoney(order.subtotal, currencyCode),\n total: transformMoney(order.total, currencyCode),\n tax: transformMoney(order.tax_total, currencyCode),\n shipping: transformMoney(order.shipping_total, currencyCode),\n discount: transformMoney(order.discount_total, currencyCode),\n \n // Addresses (transformed to camelCase)\n shippingAddress: order.shipping_address\n ? transformAddress(order.shipping_address)\n : undefined,\n billingAddress: order.billing_address\n ? transformAddress(order.billing_address)\n : undefined,\n \n // Dates\n createdAt: typeof order.created_at === 'string'\n ? order.created_at\n : order.created_at?.toISOString() ?? new Date().toISOString(),\n updatedAt: typeof order.updated_at === 'string'\n ? order.updated_at\n : order.updated_at?.toISOString() ?? new Date().toISOString(),\n completedAt: order.completed_at\n ? (typeof order.completed_at === 'string'\n ? order.completed_at\n : order.completed_at?.toISOString())\n : undefined,\n cancelledAt: order.canceled_at\n ? (typeof order.canceled_at === 'string'\n ? order.canceled_at\n : order.canceled_at?.toISOString())\n : undefined,\n \n // Platform-specific metadata\n metadata: order.metadata ?? undefined,\n };\n}\n\n// ============================================\n// Storefront Configuration Transforms\n// ============================================\n\n/**\n * Transform backend `storefront_config` (snake_case) to `StorefrontConfig` (camelCase).\n *\n * Backend response shape:\n * ```json\n * {\n * \"id\": \"sfc_01J...\",\n * \"sales_channel_id\": \"sc_01J...\",\n * \"theme_accent_color\": \"indigo\",\n * \"logo_url\": \"https://...\",\n * \"currency_code\": \"EUR\",\n * \"seo_defaults\": { \"title\": \"...\", \"description\": \"...\", \"ogImage\": \"...\" },\n * \"created_at\": \"...\",\n * \"updated_at\": \"...\"\n * }\n * ```\n */\nexport function transformStorefrontConfig(raw: any): StorefrontConfig {\n return {\n id: raw.id ?? '',\n salesChannelId: raw.sales_channel_id ?? '',\n themeAccentColor: raw.theme_accent_color ?? '',\n logoUrl: raw.logo_url ?? '',\n currencyCode: raw.currency_code ?? 'USD',\n seoDefaults: {\n title: raw.seo_defaults?.title ?? '',\n description: raw.seo_defaults?.description ?? '',\n ogImage: raw.seo_defaults?.ogImage ?? raw.seo_defaults?.og_image,\n },\n createdAt: raw.created_at ?? '',\n updatedAt: raw.updated_at ?? '',\n };\n}\n","/**\n * Admin Authentication Service\n * \n * Framework-agnostic authentication logic for admin dashboard.\n * Uses bcryptjs for password hashing and jose for JWT operations.\n * \n * @remarks\n * - L2: No Next.js imports, no env var access\n * - Edge-compatible JWT via jose library\n * - Password verification via bcryptjs\n * \n * @module admin/AdminAuthService\n */\n\nimport bcrypt from 'bcryptjs';\nimport { SignJWT, jwtVerify, type JWTPayload } from 'jose';\n\n/**\n * Admin Auth Service\n * \n * Provides password verification and JWT management for admin authentication.\n * All methods are framework-agnostic and can be used in any runtime.\n */\nexport class AdminAuthService {\n /**\n * Verify password against bcrypt hash\n * \n * @param password - Plain text password from login form\n * @param hash - Bcrypt hash stored in environment\n * @returns true if password matches hash\n */\n async verifyPassword(password: string, hash: string): Promise<boolean> {\n return bcrypt.compare(password, hash);\n }\n\n /**\n * Generate a bcrypt hash for a password\n * \n * @param password - Plain text password\n * @param rounds - Bcrypt cost factor (default: 10)\n * @returns Bcrypt hash string\n */\n async hashPassword(password: string, rounds: number = 10): Promise<string> {\n return bcrypt.hash(password, rounds);\n }\n\n /**\n * Generate JWT token (Edge-compatible via jose)\n * \n * @param payload - Token payload data\n * @param secret - JWT secret string (min 32 chars recommended)\n * @param expiresIn - Token expiration (default: '8h')\n * @returns Signed JWT token string\n */\n async generateJWT(\n payload: Record<string, unknown>,\n secret: string,\n expiresIn: string = '8h',\n ): Promise<string> {\n const secretKey = new TextEncoder().encode(secret);\n\n return new SignJWT(payload as JWTPayload)\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(expiresIn)\n .sign(secretKey);\n }\n\n /**\n * Verify JWT token (Edge-compatible via jose)\n * \n * @param token - JWT token string\n * @param secret - JWT secret string\n * @returns Decoded payload or null if invalid/expired\n */\n async verifyJWT(\n token: string,\n secret: string,\n ): Promise<Record<string, unknown> | null> {\n try {\n const secretKey = new TextEncoder().encode(secret);\n const { payload } = await jwtVerify(token, secretKey);\n return payload as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n}\n","/**\n * Admin Session Service\n * \n * Framework-agnostic session verification for admin routes.\n * Extracts and verifies JWT tokens from HTTP requests.\n * \n * @remarks\n * - L2: No Next.js imports, no env var access\n * - Uses standard Request API (works in Edge, Node.js, etc.)\n * - JWT secret injected via constructor (no env var reading)\n * \n * @module admin/AdminSessionService\n */\n\nimport { AdminAuthService } from './AdminAuthService';\n\n/**\n * Admin Session payload decoded from JWT\n */\nexport interface AdminSession {\n /** Admin user identifier */\n adminId: string;\n /** Token type (always 'admin') */\n type: 'admin';\n /** Issued at timestamp */\n iat: number;\n /** Expiration timestamp */\n exp: number;\n}\n\n/**\n * Admin Session Service\n * \n * Verifies admin sessions by extracting and validating JWT tokens\n * from HTTP request cookies or Authorization headers.\n */\nexport class AdminSessionService {\n private authService: AdminAuthService;\n\n /**\n * @param jwtSecret - JWT secret for token verification\n */\n constructor(private jwtSecret: string) {\n this.authService = new AdminAuthService();\n }\n\n /**\n * Verify admin session from HTTP request\n * \n * Checks for JWT token in:\n * 1. `admin_token` cookie\n * 2. `Authorization: Bearer <token>` header\n * \n * @param request - Standard HTTP Request object\n * @returns AdminSession if valid, null otherwise\n */\n async verifySession(request: Request): Promise<AdminSession | null> {\n const token = this.extractToken(request);\n if (!token) return null;\n\n const payload = await this.authService.verifyJWT(token, this.jwtSecret);\n if (!payload || payload.type !== 'admin') return null;\n\n return payload as unknown as AdminSession;\n }\n\n /**\n * Extract JWT token from request (cookie or Authorization header)\n */\n private extractToken(request: Request): string | null {\n // Try cookie first\n const cookieHeader = request.headers.get('cookie');\n if (cookieHeader) {\n const cookies = Object.fromEntries(\n cookieHeader.split(';').map((c) => {\n const [key, ...v] = c.trim().split('=');\n return [key, v.join('=')];\n }),\n );\n if (cookies.admin_token) return cookies.admin_token;\n }\n\n // Try Authorization header\n const authHeader = request.headers.get('authorization');\n if (authHeader?.startsWith('Bearer ')) {\n return authHeader.substring(7);\n }\n\n return null;\n }\n}\n","/**\n * Metrics Calculation Service\n * \n * Framework-agnostic business logic for calculating dashboard metrics\n * from raw order and product data.\n * \n * @remarks\n * - L2: Pure business logic, no framework dependencies\n * - Works with @thorprovider/types Order and Product interfaces\n * - Stateless static methods for easy testing\n * \n * @module admin/MetricsService\n */\n\nimport type { DashboardMetrics, ChartDataPoint } from '@thorprovider/types';\n\n/**\n * Raw order data for metrics calculation\n * \n * @remarks\n * Minimal interface to avoid coupling to specific Order type fields.\n * Accepts the common fields available across all commerce providers.\n */\nexport interface MetricsOrderInput {\n total?: number;\n status?: string;\n created_at?: string;\n createdAt?: string;\n}\n\n/**\n * Raw product data for metrics calculation\n */\nexport interface MetricsProductInput {\n id: string;\n variants?: Array<{\n quantityAvailable?: number;\n }>;\n}\n\n/**\n * Metrics Service\n * \n * Calculates dashboard analytics from raw commerce data.\n * All methods are static and pure (no side effects).\n */\nexport class MetricsService {\n /** Threshold for low stock alerts */\n static readonly LOW_STOCK_THRESHOLD = 10;\n\n /**\n * Calculate complete dashboard metrics from orders and products\n * \n * @param orders - Array of order data\n * @param products - Array of product data\n * @returns Calculated DashboardMetrics\n */\n static calculate(\n orders: MetricsOrderInput[],\n products: MetricsProductInput[],\n ): DashboardMetrics {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);\n const monthAgo = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);\n\n // Calculate sales\n const totalSales = orders.reduce((sum, o) => sum + (o.total || 0), 0);\n const todaySales = orders\n .filter((o) => new Date(o.created_at || o.createdAt || '') >= today)\n .reduce((sum, o) => sum + (o.total || 0), 0);\n const weekSales = orders\n .filter((o) => new Date(o.created_at || o.createdAt || '') >= weekAgo)\n .reduce((sum, o) => sum + (o.total || 0), 0);\n const monthSales = orders\n .filter((o) => new Date(o.created_at || o.createdAt || '') >= monthAgo)\n .reduce((sum, o) => sum + (o.total || 0), 0);\n\n // Calculate orders by status\n const ordersByStatus = {\n total: orders.length,\n pending: orders.filter((o) => o.status === 'pending').length,\n processing: orders.filter((o) => o.status === 'processing').length,\n completed: orders.filter((o) => o.status === 'completed').length,\n };\n\n // Calculate products\n const lowStockCount = products.filter((p) => {\n const totalQty = (p.variants || []).reduce(\n (sum, v) => sum + (v.quantityAvailable || 0),\n 0,\n );\n return totalQty < MetricsService.LOW_STOCK_THRESHOLD;\n }).length;\n\n const productsMetrics = {\n total: products.length,\n lowStock: lowStockCount,\n };\n\n // Generate chart data (last 7 days)\n const chartData = MetricsService.generateChartData(orders, today);\n\n return {\n sales: {\n total: totalSales,\n today: todaySales,\n week: weekSales,\n month: monthSales,\n },\n orders: ordersByStatus,\n products: productsMetrics,\n chartData,\n };\n }\n\n /**\n * Generate chart data for the last 7 days\n */\n private static generateChartData(\n orders: MetricsOrderInput[],\n today: Date,\n ): ChartDataPoint[] {\n const chartData: ChartDataPoint[] = [];\n\n for (let i = 6; i >= 0; i--) {\n const date = new Date(today.getTime() - i * 24 * 60 * 60 * 1000);\n const nextDate = new Date(date.getTime() + 24 * 60 * 60 * 1000);\n\n const daySales = orders\n .filter((o) => {\n const orderDate = new Date(o.created_at || o.createdAt || '');\n return orderDate >= date && orderDate < nextDate;\n })\n .reduce((sum, o) => sum + (o.total || 0), 0);\n\n chartData.push({\n date: date.toISOString().split('T')[0],\n sales: daySales,\n });\n }\n\n return chartData;\n }\n}\n","/**\n * Backend Metadata Adapter Factory\n *\n * Framework-agnostic factory to create backend metadata adapters for admin/dashboard.\n * Keeps vendor-specific code in L2, prevents lock-in in L5.\n *\n * @remarks\n * This factory is distinct from the main provider factory (createProvider).\n * It's used for admin operations that require metadata/catalog access.\n * Provider types are imported from @thorprovider/types (L1) to maintain sync.\n *\n * @module backend/factory\n */\n\nimport Medusa from '@medusajs/js-sdk';\nimport { MedusaMetadataAdapter } from './medusa/MedusaMetadataAdapter';\nimport type { BackendMetadataAdapter } from './BackendMetadataAdapter';\nimport type { ProviderTypeString } from '@thorprovider/types';\n\n/**\n * Configuration for creating a backend metadata adapter\n *\n * @remarks\n * Currently only 'medusa' is implemented. When adding Shopify/WooCommerce metadata adapters:\n * 1. Uncomment the provider type in packages/types/src/provider.ts\n * 2. Update this interface to accept the new provider type\n * 3. Implement ShopifyMetadataAdapter, WooCommerceMetadataAdapter\n * 4. Add cases to createBackendMetadataAdapter() switch\n */\nexport interface BackendMetadataAdapterConfig {\n /** Backend provider type (from @thorprovider/types L1) */\n provider: ProviderTypeString;\n \n /** Backend base URL */\n baseUrl: string;\n \n /** Publishable API key (for storefront access) */\n publishableKey?: string;\n \n /** Enable debug logging */\n debug?: boolean;\n\n /**\n * Secret admin API key (from COMMERCE_ADMIN_API_KEY).\n * When provided, the metadata adapter SDK instance will send\n * `x-medusa-access-token` header on all admin requests.\n * Required for getMetadata/setMetadata to work after removing email/password auth.\n */\n adminApiKey?: string;\n}\n\n/**\n * Create a backend metadata adapter (Factory Pattern)\n * \n * Keeps vendor-specific code in L2, prevents lock-in in L5.\n * L5 only provides configuration from env vars.\n * \n * @param config - Adapter configuration\n * @returns BackendMetadataAdapter instance\n * \n * @example\n * ```typescript\n * // In L5 (starters)\n * import { createBackendMetadataAdapter } from '@thorprovider/adapters';\n * \n * export const metadataAdapter = createBackendMetadataAdapter({\n * provider: process.env.NEXT_PUBLIC_COMMERCE_PROVIDER as any,\n * baseUrl: process.env.NEXT_PUBLIC_COMMERCE_API_URL!,\n * publishableKey: process.env.NEXT_PUBLIC_COMMERCE_API_KEY!,\n * });\n * ```\n * \n * @throws {Error} If provider is not supported\n */\nexport function createBackendMetadataAdapter(\n config: BackendMetadataAdapterConfig\n): BackendMetadataAdapter {\n const { provider, baseUrl, publishableKey, debug } = config;\n\n if (provider === 'medusa') {\n const { adminApiKey } = config;\n\n // Create Medusa SDK client instance\n const medusa = new Medusa({\n baseUrl,\n publishableKey,\n debug: debug ?? false,\n // When adminApiKey is provided: sends x-medusa-access-token on all requests.\n // When not provided: requests are unauthenticated — admin routes will 401.\n ...(adminApiKey && { apiKey: adminApiKey }),\n });\n\n return new MedusaMetadataAdapter(medusa);\n }\n\n if (provider === 'shopify') {\n // TODO: Implement Shopify metadata adapter\n throw new Error('Shopify metadata adapter not yet implemented');\n }\n\n if (provider === 'woocommerce') {\n // TODO: Implement WooCommerce metadata adapter\n throw new Error('WooCommerce metadata adapter not yet implemented');\n }\n\n throw new Error(`Unsupported provider: ${provider}`);\n}\n","/**\n * Medusa Metadata Adapter\n * \n * Implementation of BackendMetadataAdapter for Medusa.js v2.\n * Uses Medusa's native metadata fields on sales_channel, customer, and order resources.\n * \n * Supported resource types:\n * - `'sales_channel'` — site config, channel-level settings\n * - `'customer'` — multi-tenant scoping (`sales_channel_id` key)\n * - `'order'` — multi-tenant scoping (`sales_channel_id` key)\n * \n * All operations require admin-level JWT authentication.\n * \n * @module backend/medusa/MedusaMetadataAdapter\n */\n\nimport type Medusa from '@medusajs/js-sdk';\nimport type { BackendMetadataAdapter } from '../BackendMetadataAdapter';\n\n/**\n * Medusa Metadata Adapter\n * \n * @remarks\n * - Supports 'sales_channel' and 'store' resource types\n * - Uses Medusa admin API (requires admin token)\n * - Metadata is stored as JSON in the metadata field\n * \n * @example\n * ```typescript\n * const adapter = new MedusaMetadataAdapter(medusaClient);\n * \n * // Store site configuration\n * await adapter.setMetadata(\n * 'sales_channel',\n * 'sc_01HXXX',\n * 'site_config',\n * { version: '2026-03-25', config: {...} }\n * );\n * ```\n */\nexport class MedusaMetadataAdapter implements BackendMetadataAdapter {\n constructor(private sdk: Medusa) {}\n\n /**\n * Get metadata value from Medusa resource\n */\n async getMetadata(\n resourceType: string,\n resourceId: string,\n key: string\n ): Promise<any | null> {\n try {\n if (resourceType === 'sales_channel') {\n const { sales_channel } = await this.sdk.admin.salesChannel.retrieve(\n resourceId\n );\n return sales_channel.metadata?.[key] ?? null;\n }\n\n if (resourceType === 'customer') {\n const result = await (this.sdk as any).admin.customer.retrieve(resourceId);\n return result?.customer?.metadata?.[key] ?? null;\n }\n\n if (resourceType === 'order') {\n const result = await (this.sdk as any).admin.order.retrieve(resourceId);\n return result?.order?.metadata?.[key] ?? null;\n }\n\n // Note: Store API in Medusa v2 requires store ID\n // Store support can be added when we have a reliable way to get the store ID\n\n throw new Error(\n `Unsupported resource type: ${resourceType}. ` +\n `Supported: 'sales_channel', 'customer', 'order'.`\n );\n } catch (error: any) {\n // If resource not found or metadata key doesn't exist, return null\n if (error.response?.status === 404 || error.status === 404) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Set metadata value on Medusa resource\n */\n async setMetadata(\n resourceType: string,\n resourceId: string,\n key: string,\n value: any\n ): Promise<void> {\n if (resourceType === 'sales_channel') {\n await this.sdk.admin.salesChannel.update(resourceId, {\n metadata: { [key]: value },\n });\n return;\n }\n\n if (resourceType === 'customer') {\n await (this.sdk as any).admin.customer.update(resourceId, {\n metadata: { [key]: value },\n });\n return;\n }\n\n if (resourceType === 'order') {\n await (this.sdk as any).admin.order.update(resourceId, {\n metadata: { [key]: value },\n });\n return;\n }\n\n // Note: Store API in Medusa v2 requires store ID\n // Store support can be added when we have a reliable way to get the store ID\n\n throw new Error(\n `Unsupported resource type: ${resourceType}. ` +\n `Supported: 'sales_channel', 'customer', 'order'.`\n );\n }\n\n /**\n * Delete metadata key from Medusa resource\n * \n * @remarks\n * Medusa deletes metadata keys by setting them to undefined or null\n */\n async deleteMetadata(\n resourceType: string,\n resourceId: string,\n key: string\n ): Promise<void> {\n // Set to null to delete the key\n await this.setMetadata(resourceType, resourceId, key, null);\n }\n}\n","/**\n * Channel Scope — Backend-Agnostic Multi-Tenant Helpers\n *\n * Provides utilities for tagging, reading and filtering entity metadata by\n * sales-channel (or any future tenant key). Works with any backend that\n * exposes a writable `metadata: Record<string, unknown>` field on its\n * entities (Medusa, Shopify metafields, WooCommerce meta, etc.).\n *\n * ## Design decisions\n *\n * | Decision | Rationale |\n * |----------|-----------|\n * | Flat key (`sales_channel_id`) | Simpler queries, no prefix parsing required |\n * | Metadata, not custom fields | Zero DB migrations; works across backends |\n * | Pure functions | No side effects → easily testable; usable in any layer |\n * | `assigned_at` timestamp | Audit trail for dropshipper / admin assignment |\n *\n * @module metadata/channel-scope\n */\n\n// ────────────────────────────────────────────────────────────────────\n// Constants\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Well-known metadata key used to store the owning sales-channel on any\n * entity that Medusa (or the backend) does not natively scope.\n *\n * Convention: every entity whose metadata contains this key is\n * considered \"owned\" by the referenced channel. Entities without it\n * are global / unscoped.\n */\nexport const CHANNEL_SCOPE_KEY = 'sales_channel_id' as const;\n\n/**\n * Optional audit key — ISO-8601 timestamp of when the channel was assigned.\n */\nexport const CHANNEL_ASSIGNED_AT_KEY = 'channel_assigned_at' as const;\n\n/**\n * Optional audit key — who assigned the entity to the channel.\n * Value is a free-form string (admin email, user id, \"system\", etc.).\n */\nexport const CHANNEL_ASSIGNED_BY_KEY = 'channel_assigned_by' as const;\n\n// ────────────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Minimal shape any entity must satisfy in order to participate in\n * channel-scope filtering. Compatible with @thorprovider/types Customer,\n * Order, ProductCategory, etc.\n */\nexport interface ChannelScopeable {\n id: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Payload produced by `buildChannelScopeMetadata()`.\n * Can be spread directly into an `updateCustomer` / `updateOrder` call.\n */\nexport interface ChannelScopeMetadata {\n [CHANNEL_SCOPE_KEY]: string;\n [CHANNEL_ASSIGNED_AT_KEY]: string;\n [CHANNEL_ASSIGNED_BY_KEY]?: string;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Builders\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Build channel-scope metadata payload.\n *\n * The returned object should be **merged** into the entity's existing\n * `metadata` field when calling `updateCustomer`, `updateOrder`, etc.\n *\n * @param channelId - Sales-channel ID (e.g. `\"sc_01HXXX\"`)\n * @param assignedBy - Optional identifier of who performed the assignment\n * @returns Metadata fragment ready to spread into an update payload\n *\n * @example\n * ```typescript\n * const scope = buildChannelScopeMetadata('sc_01HXXX', 'admin@store.com');\n * await commerce.updateCustomer(customerId, {\n * metadata: { ...existingMeta, ...scope },\n * });\n * ```\n */\nexport function buildChannelScopeMetadata(\n channelId: string,\n assignedBy?: string,\n): ChannelScopeMetadata {\n const payload: ChannelScopeMetadata = {\n [CHANNEL_SCOPE_KEY]: channelId,\n [CHANNEL_ASSIGNED_AT_KEY]: new Date().toISOString(),\n };\n\n if (assignedBy) {\n payload[CHANNEL_ASSIGNED_BY_KEY] = assignedBy;\n }\n\n return payload;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Readers\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Read the channel-scope value from an entity's metadata.\n *\n * @returns The channel ID string, or `null` if the entity has no scope set.\n */\nexport function getChannelScope(entity: ChannelScopeable): string | null {\n const value = entity.metadata?.[CHANNEL_SCOPE_KEY];\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\n/**\n * Check if an entity is scoped to a specific channel.\n *\n * @param entity - Any entity with optional `metadata`\n * @param channelId - Channel ID to match against\n * @returns `true` if entity's metadata contains a matching scope key\n */\nexport function isScopedToChannel(\n entity: ChannelScopeable,\n channelId: string,\n): boolean {\n return getChannelScope(entity) === channelId;\n}\n\n/**\n * Check if an entity has **no** channel scope (i.e. it is \"global\").\n */\nexport function isGlobalEntity(entity: ChannelScopeable): boolean {\n return getChannelScope(entity) === null;\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Filters\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Filter an array of entities to only those belonging to a channel.\n *\n * If `channelId` is `undefined` or empty, returns the full array unfiltered.\n * This preserves backward compatibility for admin views that intentionally\n * list all entities regardless of tenant.\n *\n * @param entities - Array of channel-scopeable entities\n * @param channelId - Optional channel ID to filter by\n * @returns Filtered (or unfiltered) array\n *\n * @example\n * ```typescript\n * const allCustomers = await commerce.getCustomers();\n * const myCustomers = filterByChannel(allCustomers, salesChannelId);\n * ```\n */\nexport function filterByChannel<T extends ChannelScopeable>(\n entities: T[],\n channelId?: string,\n): T[] {\n if (!channelId) return entities;\n return entities.filter((e) => isScopedToChannel(e, channelId));\n}\n\n/**\n * Filter an array of entities to only those that are global (unscoped).\n *\n * Useful for admin views that want to list entities not yet assigned to\n * any channel.\n */\nexport function filterGlobalOnly<T extends ChannelScopeable>(\n entities: T[],\n): T[] {\n return entities.filter(isGlobalEntity);\n}\n\n/**\n * Partition entities into `{ scoped, global }` groups.\n *\n * @param entities - Array of channel-scopeable entities\n * @param channelId - Channel ID to partition against\n * @returns Object with `scoped` (matching channel) and `global` (no scope) arrays\n *\n * @example\n * ```typescript\n * const { scoped, global } = partitionByChannel(customers, 'sc_123');\n * // scoped → customers assigned to sc_123\n * // global → customers not assigned to any channel\n * ```\n */\nexport function partitionByChannel<T extends ChannelScopeable>(\n entities: T[],\n channelId: string,\n): { scoped: T[]; global: T[] } {\n const scoped: T[] = [];\n const global: T[] = [];\n\n for (const entity of entities) {\n if (isScopedToChannel(entity, channelId)) {\n scoped.push(entity);\n } else if (isGlobalEntity(entity)) {\n global.push(entity);\n }\n // Entities scoped to a *different* channel are silently excluded.\n }\n\n return { scoped, global };\n}\n","/**\n * Channel Scope Validation — Pure TypeScript (no external deps)\n *\n * Validates channel-scope metadata before it is written to the backend.\n * Keeps all validation logic in L2 so that L5 starters don't duplicate checks.\n *\n * @module metadata/channel-scope-validation\n */\n\nimport type { ChannelScopeMetadata, ChannelScopeable } from './channel-scope';\nimport { CHANNEL_SCOPE_KEY } from './channel-scope';\n\n// ────────────────────────────────────────────────────────────────────\n// Errors\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Thrown when channel-scope validation fails.\n *\n * Consumers can catch this specific type to provide user-friendly feedback\n * without leaking internal details.\n */\nexport class ChannelScopeValidationError extends Error {\n public readonly field: string;\n public readonly value: unknown;\n\n constructor(message: string, field: string, value?: unknown) {\n super(message);\n this.name = 'ChannelScopeValidationError';\n this.field = field;\n this.value = value;\n }\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Validation functions\n// ────────────────────────────────────────────────────────────────────\n\n/**\n * Validate that a channel ID is a non-empty string.\n *\n * Does **not** enforce a specific prefix (e.g. `\"sc_\"`) because different\n * backends use different conventions:\n * - Medusa: `\"sc_01HXXX\"`\n * - Shopify: `\"gid://shopify/Channel/789\"`\n * - WooCommerce: `\"1\"` (numeric string)\n *\n * @throws {ChannelScopeValidationError}\n */\nexport function validateChannelId(channelId: unknown): asserts channelId is string {\n if (typeof channelId !== 'string' || channelId.trim().length === 0) {\n throw new ChannelScopeValidationError(\n 'Channel ID must be a non-empty string',\n 'channelId',\n channelId,\n );\n }\n\n // Sanity upper-bound for ID length (guards against payload abuse)\n if (channelId.length > 256) {\n throw new ChannelScopeValidationError(\n 'Channel ID exceeds maximum length (256)',\n 'channelId',\n channelId,\n );\n }\n}\n\n/**\n * Validate that an entity ID is a non-empty string.\n *\n * @throws {ChannelScopeValidationError}\n */\nexport function validateEntityId(entityId: unknown, label = 'entityId'): asserts entityId is string {\n if (typeof entityId !== 'string' || entityId.trim().length === 0) {\n throw new ChannelScopeValidationError(\n `${label} must be a non-empty string`,\n label,\n entityId,\n );\n }\n}\n\n/**\n * Validate that the `assignedBy` value (if provided) is a reasonable string.\n *\n * @throws {ChannelScopeValidationError}\n */\nexport function validateAssignedBy(assignedBy: unknown): asserts assignedBy is string | undefined {\n if (assignedBy === undefined || assignedBy === null) return;\n if (typeof assignedBy !== 'string') {\n throw new ChannelScopeValidationError(\n 'assignedBy must be a string',\n 'assignedBy',\n assignedBy,\n );\n }\n if (assignedBy.length > 512) {\n throw new ChannelScopeValidationError(\n 'assignedBy exceeds maximum length (512)',\n 'assignedBy',\n assignedBy,\n );\n }\n}\n\n/**\n * Full validation for a channel-scope assignment operation.\n *\n * Call before writing channel scope metadata to any entity.\n *\n * @throws {ChannelScopeValidationError} with descriptive field + value\n *\n * @example\n * ```typescript\n * validateChannelScopeAssignment('cus_123', 'sc_01HXXX', 'admin@store.com');\n * // If no error, safe to proceed\n * ```\n */\nexport function validateChannelScopeAssignment(\n entityId: string,\n channelId: string,\n assignedBy?: string,\n): void {\n validateEntityId(entityId, 'entityId');\n validateChannelId(channelId);\n validateAssignedBy(assignedBy);\n}\n\n/**\n * Validate that an entity is currently scoped to the expected channel.\n *\n * Useful as a guard before performing operations that should only\n * affect entities within the caller's channel (e.g. a dropshipper editing\n * a customer that must belong to their channel).\n *\n * @throws {ChannelScopeValidationError} if entity does not belong to expectedChannelId\n */\nexport function assertEntityBelongsToChannel(\n entity: ChannelScopeable,\n expectedChannelId: string,\n): void {\n const actual = entity.metadata?.[CHANNEL_SCOPE_KEY];\n if (actual !== expectedChannelId) {\n throw new ChannelScopeValidationError(\n `Entity \"${entity.id}\" does not belong to channel \"${expectedChannelId}\" (actual: \"${actual ?? 'none'}\")`,\n CHANNEL_SCOPE_KEY,\n actual,\n );\n }\n}\n","/**\n * @thorprovider/adapters v2.0\n * Medusa Provider - Main implementation\n */\n\nimport Medusa from '@medusajs/js-sdk';\nimport type {\n Product,\n GetProductsOptions,\n AdvancedSearchProductsOptions,\n SearchResultMeta,\n FilterConfig,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n ProductCategory,\n GetCategoriesOptions,\n GetCollectionsOptions,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n AuthConfig,\n AuthProvider,\n PaymentMethod,\n PaymentMethodsOptions,\n Order,\n StorefrontContext,\n Customer,\n GetCustomersOptions,\n GetOrdersOptions,\n AdminProduct,\n Region,\n Address,\n BackendCapabilities,\n StorefrontConfig,\n DesignerConfig,\n DesignerHistoryEntry,\n} from '@thorprovider/types';\nimport { StorefrontConfigError } from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { MEDUSA_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { fetchWithRetry, type RetryConfig } from '../../core/fetch-utils';\nimport { ProviderAPIError, ResourceNotFoundError, extractErrorMessage } from '../../core/errors';\nimport { validatePaymentId } from '../../utils/payment-utils';\nimport { transformProduct, transformCart, transformCollection, transformCategory, transformOrder, transformCustomer, transformStockLocation, transformInventoryLevel, transformAddress, transformStorefrontConfig } from './transforms';\nimport { MedusaAuthProvider } from './auth';\nimport { getPaymentMethods } from './payment';\nimport {\n buildChannelScopeMetadata,\n filterByChannel,\n validateChannelScopeAssignment,\n} from '../../metadata';\n\nconst MEDUSA_CART_RETRIEVE_FIELDS =\n '+items,+items.variant,+items.variant.product,+items.variant.product.thumbnail,+items.variant.options,+items.variant.options.option';\n\n/**\n * Medusa provider configuration\n */\nexport interface MedusaProviderConfig extends ProviderConfig {\n /**\n * Medusa backend URL\n */\n baseUrl: string;\n\n /**\n * Publishable API key (for storefront access)\n */\n publishableKey: string;\n\n /**\n * Default currency code (default: USD)\n */\n /**\n * Default currency code (default: USD)\n */\n currencyCode?: string;\n\n /**\n * Region ID (optional, will use default region if not provided)\n */\n regionId?: string;\n\n /**\n * Authentication configuration (optional)\n * If not provided, auth methods will not be available\n */\n auth?: AuthConfig;\n\n /**\n * Retry configuration for fetch requests (optional)\n * Configure automatic retries, timeouts, and backoff strategy\n *\n * @example\n * ```typescript\n * {\n * maxRetries: 3, // Retry up to 3 times\n * timeoutMs: 10000, // 10 second timeout per request\n * initialDelayMs: 300, // Start with 300ms delay\n * }\n * ```\n */\n retry?: RetryConfig;\n\n /**\n * Admin API configuration (optional).\n * Required for inventory operations (stock locations, inventory levels).\n * When not provided, admin-only methods will throw with a descriptive error.\n */\n adminConfig?: {\n /**\n * Secret API key created in Medusa Admin → Settings → API Keys → Secret.\n * Sent as `x-medusa-access-token` on every request of the dedicated admin SDK instance.\n * Never use a Publishable key here.\n */\n apiKey: string;\n };\n}\n\n/**\n * Medusa commerce provider\n *\n * Implements CommerceProvider interface for Medusa.js v2\n */\nexport class MedusaProvider implements CommerceProvider {\n readonly name = 'medusa';\n readonly version = '2.0.0';\n\n /**\n * Medusa backend capabilities.\n * Starts with static defaults, replaced by dynamic values from\n * `GET /store/thor/capabilities` once the fetch completes.\n */\n private _dynamicCapabilities: BackendCapabilities | null = null;\n\n /** Promise that resolves when capabilities fetch completes (success or failure) */\n private _capabilitiesPromise: Promise<void> | null = null;\n\n /**\n * Getter returns dynamic capabilities if available, otherwise static fallback.\n */\n get capabilities(): BackendCapabilities {\n return this._dynamicCapabilities ?? MEDUSA_CAPABILITIES;\n }\n\n private sdk: Medusa;\n private logger: ReturnType<typeof createLogger>;\n private currencyCode: string;\n private retryConfig: Required<RetryConfig>;\n private baseUrl: string;\n private publishableKey: string;\n\n /** Secret API key for admin operations (if configured). */\n private adminApiKey?: string;\n /**\n * Dedicated SDK instance for admin calls.\n * Separate from `this.sdk` to prevent the admin API key from being overwritten\n * by customer JWT tokens set during storefront authentication.\n * Only created when adminConfig.apiKey is provided.\n */\n private sdkAdmin?: Medusa;\n /** Cached distinct product status values — rarely changes, cached for process lifetime */\n private _cachedProductStatuses: string[] | null = null;\n\n /**\n * In-memory cache for region countries\n * Structure: Map<regionId, { countries: Country[], expiresAt: number }>\n */\n private regionCountriesCache = new Map<\n string,\n { countries: import('@thorprovider/types').Country[]; expiresAt: number }\n >();\n\n /**\n * Cache TTL for region countries (5 minutes)\n */\n private readonly REGION_COUNTRIES_CACHE_TTL = 5 * 60 * 1000;\n\n /**\n * In-memory cache for storefront context (60 second TTL)\n */\n private storefrontContextCache: {\n context: StorefrontContext;\n expiresAt: number;\n } | null = null;\n\n /**\n * Cache TTL for storefront context (60 seconds)\n */\n private readonly STOREFRONT_CONTEXT_CACHE_TTL = 60 * 1000;\n\n /**\n * Authentication provider (available if auth config is provided)\n */\n public readonly auth?: AuthProvider;\n\n private async retrieveCartWithLineDetails(cartId: string): Promise<any> {\n const { cart } = await this.sdk.store.cart.retrieve(cartId, {\n fields: MEDUSA_CART_RETRIEVE_FIELDS,\n } as any);\n return cart;\n }\n\n constructor(config: MedusaProviderConfig) {\n this.logger = createLogger('MedusaProvider', config.debug);\n this.currencyCode = config.currencyCode ?? 'USD';\n this.baseUrl = config.baseUrl;\n this.publishableKey = config.publishableKey;\n\n // Store retry configuration\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? 3,\n timeoutMs: config.retry?.timeoutMs ?? 10000,\n initialDelayMs: config.retry?.initialDelayMs ?? 300,\n backoffMultiplier: config.retry?.backoffMultiplier ?? 2,\n maxDelayMs: config.retry?.maxDelayMs ?? 5000,\n retryableStatusCodes: config.retry?.retryableStatusCodes ?? [408, 429, 500, 502, 503, 504],\n };\n\n this.logger.info('Initializing Medusa Provider', {\n baseUrl: config.baseUrl,\n currencyCode: this.currencyCode,\n hasAuth: !!config.auth,\n hasAdminConfig: !!config.adminConfig,\n retryConfig: this.retryConfig,\n });\n\n this.sdk = new Medusa({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n debug: config.debug ?? false,\n // Always use JWT mode for auth - SDK needs to send Bearer tokens\n // Configure storage method for JWT tokens (browser only)\n auth: config.auth\n ? {\n type: 'jwt',\n // Use localStorage in browser, memory storage on server\n jwtTokenStorageMethod: typeof window !== 'undefined' ? 'local' : 'memory',\n }\n : undefined,\n });\n\n // Create dedicated admin SDK instance with API key (synchronous — no network call)\n if (config.adminConfig?.apiKey) {\n this.adminApiKey = config.adminConfig.apiKey;\n this.sdkAdmin = new Medusa({\n baseUrl: config.baseUrl,\n apiKey: config.adminConfig.apiKey, // → x-medusa-access-token header on all requests\n debug: config.debug ?? false,\n // No publishableKey or auth config: this instance is admin-only, no JWT needed\n });\n this.logger.info('[Admin Auth] Dedicated admin SDK instance created with API key');\n }\n\n // Initialize auth provider if config is provided\n if (config.auth) {\n this.auth = new MedusaAuthProvider(this.sdk, config.auth, config.debug);\n this.logger.info('Auth provider initialized');\n }\n\n // Fetch dynamic capabilities from Thor Commerce plugin (non-blocking).\n // Falls back to MEDUSA_CAPABILITIES if plugin is not installed.\n this._capabilitiesPromise = this._fetchCapabilities();\n }\n\n // ============================================\n // Thor Plugin — Dynamic Capabilities\n // ============================================\n\n /**\n * Fetch capabilities dynamically from `GET /store/thor/capabilities`.\n * Non-blocking — called in constructor. On failure, static fallback is used.\n * Cache: process-lifetime (per provider instance).\n */\n private async _fetchCapabilities(): Promise<void> {\n try {\n const url = `${this.baseUrl}/store/thor/capabilities`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (!response.ok) {\n this.logger.warn('[Capabilities] Thor plugin endpoint returned non-OK status', {\n status: response.status,\n });\n return;\n }\n\n const data = await response.json();\n this._dynamicCapabilities = data as BackendCapabilities;\n this.logger.info('[Capabilities] Dynamic capabilities loaded from backend');\n } catch (error) {\n // Non-fatal — static MEDUSA_CAPABILITIES remains as fallback\n this.logger.warn('[Capabilities] Failed to fetch dynamic capabilities, using static defaults', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n /**\n * Wrapper for SDK calls with retry logic\n * Handles network failures and temporary backend issues\n */\n private async withRetry<T>(\n operation: () => Promise<T>,\n operationName: string,\n context?: Record<string, any>,\n ): Promise<T> {\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Request timeout after ${this.retryConfig.timeoutMs}ms`));\n }, this.retryConfig.timeoutMs);\n });\n\n // Race between operation and timeout\n const result = await Promise.race([operation(), timeoutPromise]);\n\n if (attempt > 0) {\n this.logger.info(`${operationName} succeeded after ${attempt} retries`, context);\n }\n\n return result;\n } catch (error: any) {\n lastError = error;\n\n // Check if we should retry\n const isRetryable =\n error.message?.includes('fetch failed') ||\n error.message?.includes('timeout') ||\n error.message?.includes('ECONNREFUSED') ||\n error.message?.includes('ETIMEDOUT') ||\n (error.status && this.retryConfig.retryableStatusCodes.includes(error.status));\n\n const shouldRetry = attempt < this.retryConfig.maxRetries && isRetryable;\n\n if (shouldRetry) {\n const delay =\n this.retryConfig.initialDelayMs * Math.pow(this.retryConfig.backoffMultiplier, attempt);\n const cappedDelay = Math.min(delay, this.retryConfig.maxDelayMs);\n\n this.logger.warn(`${operationName} failed, retrying...`, {\n ...context,\n attempt: attempt + 1,\n maxAttempts: this.retryConfig.maxRetries + 1,\n nextRetryIn: `${cappedDelay}ms`,\n error: error.message,\n });\n\n await new Promise((resolve) => setTimeout(resolve, cappedDelay));\n } else {\n this.logger.error(`${operationName} failed after all retries`, {\n ...context,\n totalAttempts: attempt + 1,\n error: error.message,\n });\n break;\n }\n }\n }\n\n // All retries exhausted\n throw lastError;\n }\n\n async getProduct(handle: string, options?: { regionId?: string }): Promise<Product | undefined> {\n this.logger.debug('getProduct', { handle, regionId: options?.regionId });\n\n try {\n return await this.withRetry(\n async () => {\n // calculated_price requires region_id in Medusa v2 — only request it when available\n const baseFields = '+variants,+variants.inventory_quantity,+options,+images,+tags';\n const pricingFields = ',+variants.calculated_price,+variants.prices';\n const fields = options?.regionId ? baseFields + pricingFields : baseFields;\n\n const queryParams: any = {\n handle,\n limit: 1,\n fields,\n };\n // Add region_id for region-based pricing\n if (options?.regionId) {\n queryParams.region_id = options.regionId;\n }\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n queryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(queryParams);\n\n if (!products || products.length === 0) {\n this.logger.debug('Product not found', { handle });\n return undefined;\n }\n\n const transformedProduct = transformProduct(products[0], this.currencyCode);\n\n return transformedProduct;\n },\n 'getProduct',\n { handle, regionId: options?.regionId },\n );\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to fetch product: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getProducts(options: GetProductsOptions & { regionId?: string } = {}): Promise<Product[]> {\n this.logger.debug('getProducts', options);\n\n try {\n return await this.withRetry(\n async () => {\n // calculated_price requires region_id in Medusa v2 — only request it when available\n const baseFields = '+variants,+variants.inventory_quantity,+options,+images,+tags';\n const pricingFields = ',+variants.calculated_price,+variants.prices';\n const fields = options.regionId ? baseFields + pricingFields : baseFields;\n\n // Map Thor SortOption values to Medusa /store/products `order` field names.\n // Native endpoint supports: title, -title, created_at, -created_at\n // Price sorting (price-asc, price-desc) is not supported — omitted so\n // products-client.tsx handles it client-side as before.\n const SORT_KEY_MAP: Record<string, string | null> = {\n featured: null, // server default order\n name: 'title', // A→Z by product title\n newest: '-created_at', // newest products first\n 'price-asc': null, // not supported by native endpoint → client-side\n 'price-desc': null, // not supported by native endpoint → client-side\n rating: null, // not supported → server default\n };\n\n const queryParams: any = {\n q: options.query,\n limit: options.first ?? 100,\n offset: options.after ? parseInt(String(options.after), 10) : undefined,\n fields,\n };\n\n if (options.sortKey) {\n const mappedOrder = SORT_KEY_MAP[options.sortKey] ?? null;\n if (mappedOrder !== null) {\n queryParams.order = mappedOrder;\n }\n // If null → omit order param entirely (server returns default order)\n }\n\n // Add region_id for region-based pricing\n if (options.regionId) {\n queryParams.region_id = options.regionId;\n }\n\n // Basic category/collection filtering\n // Medusa v2 /store/products supports category_id[] and collection_id[]\n if (options.categoryIds && options.categoryIds.length > 0) {\n queryParams.category_id = options.categoryIds;\n }\n if (options.collectionIds && options.collectionIds.length > 0) {\n queryParams.collection_id = options.collectionIds;\n }\n\n // Scope to storefront sales channel when configured.\n // The publishable API key already scopes most requests, but\n // explicit filtering ensures multi-tenant isolation.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n queryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(queryParams);\n\n return products.map((p) => transformProduct(p, this.currencyCode));\n },\n 'getProducts',\n options,\n );\n } catch (error: any) {\n // Enhanced error logging\n this.logger.error('getProducts error details', {\n message: error.message,\n status: error.status,\n type: error.type,\n code: error.code,\n stack: error.stack,\n fullError: JSON.stringify(error, null, 2),\n });\n\n throw new ProviderAPIError(\n `Failed to fetch products: ${error.message || 'Unknown error'}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getProductRecommendations(productId: string): Promise<Product[]> {\n this.logger.debug('getProductRecommendations', { productId });\n\n // Medusa doesn't have built-in recommendations yet\n // Return empty array for now - can be extended with custom logic\n this.logger.warn('Product recommendations not yet implemented for Medusa');\n return [];\n }\n\n // ============================================\n // Advanced Search Operations\n // ============================================\n\n /**\n * Advanced product search using /store/search endpoint\n * \n * Uses hybrid MeiliSearch + Qdrant search with advanced filtering:\n * - Price range filtering\n * - Stock availability\n * - Custom product attributes\n * \n * Falls back to getProducts() if advanced search fails\n */\n async searchProductsAdvanced(\n options?: AdvancedSearchProductsOptions\n ): Promise<{\n products: Product[];\n meta?: SearchResultMeta;\n }> {\n this.logger.debug('searchProductsAdvanced', options);\n\n // Check if advanced search is available\n if (!this.capabilities.advancedSearch) {\n this.logger.warn('Advanced search not available, falling back to getProducts()');\n const products = await this.getProducts(options);\n return {\n products,\n meta: {\n limit: options?.first ?? 20,\n offset: Number(options?.after ?? 0),\n hybridSearchUsed: false,\n },\n };\n }\n\n try {\n // Build query parameters for /store/search\n const queryParams: Record<string, any> = {};\n\n // Text search\n if (options?.query) {\n queryParams.q = options.query;\n }\n\n // Pagination\n queryParams.limit = options?.first ?? 20;\n queryParams.offset = options?.after ? parseInt(String(options.after), 10) : 0;\n\n // Sort — map SortOption values to Medusa's sortable field names.\n // Price sorting is NOT included: backend does not support it yet.\n const SORT_OPTION_TO_ORDER: Record<string, string | null> = {\n featured: null, // no order → server default relevance\n 'price-asc': null, // ❌ not supported by backend; client handles it\n 'price-desc': null, // ❌ not supported by backend; client handles it\n name: 'title', // ✅ THE FIX — was sending 'name', must be 'title'\n newest: '-created_at', // standard Medusa field\n rating: null, // not supported; use server default\n };\n\n if (options?.sortKey) {\n const mapped = SORT_OPTION_TO_ORDER[options.sortKey];\n if (mapped !== undefined && mapped !== null) {\n // If the mapped value already contains '-', respect it; otherwise apply reverse flag\n queryParams.order = options.reverse && !mapped.startsWith('-') ? `-${mapped}` : mapped;\n }\n // If mapped === null → omit order param (server default)\n }\n\n // Native MeiliSearch filters (fast)\n if (options?.categoryIds && options.categoryIds.length > 0) {\n queryParams.categories = options.categoryIds.join(',');\n }\n\n if (options?.collectionIds && options.collectionIds.length > 0) {\n queryParams.collections = options.collectionIds.join(',');\n }\n\n if (options?.tagIds && options.tagIds.length > 0) {\n queryParams.tags = options.tagIds.join(',');\n }\n\n // Hybrid filters (MeiliSearch + Database)\n if (options?.priceMin !== undefined) {\n queryParams.price_min = options.priceMin;\n }\n\n if (options?.priceMax !== undefined) {\n queryParams.price_max = options.priceMax;\n }\n\n // Only send isAvailable=true. Sending false causes the backend to return\n // inventory_quantity=0 for all variants, incorrectly marking them out of stock.\n if (options?.inStockOnly === true) {\n queryParams.isAvailable = true;\n }\n\n // Custom attributes filtering\n if (options?.attributes && options.attributes.length > 0) {\n queryParams.attributes = JSON.stringify(options.attributes);\n }\n\n // Price context\n if (options?.currencyCode) {\n queryParams.currency_code = options.currencyCode;\n }\n\n if (options?.regionId) {\n queryParams.region_id = options.regionId;\n }\n\n // Note: /store/search always returns variants with calculated prices and stock.\n // includeVariants and includeFacets are NOT supported by this endpoint.\n\n // Make request to /store/search\n const url = new URL(`${this.baseUrl}/store/search`);\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n\n this.logger.debug('Calling /store/search', { url: url.toString() });\n\n const response = await fetchWithRetry(\n url.toString(),\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig\n );\n\n if (!response.ok) {\n throw new Error(`Search API returned ${response.status}: ${response.statusText}`);\n }\n\n const data = await response.json();\n\n // Transform products\n const products = (data.hits || []).map((hit: any) => \n transformProduct(hit, options?.currencyCode || this.currencyCode)\n );\n\n // Build metadata\n const meta: SearchResultMeta = {\n total: data.estimatedTotalHits || data.count,\n limit: data.limit || queryParams.limit,\n offset: data.offset || queryParams.offset,\n processingTimeMs: data.processingTimeMs,\n hybridSearchUsed: data.hybrid_query_applied || false,\n appliedFilters: data.applied_filters,\n priceContext: data.price_context\n ? {\n currencyCode: data.price_context.currency_code,\n regionId: data.price_context.region_id,\n }\n : undefined,\n };\n\n this.logger.debug('Search completed', {\n productsFound: products.length,\n totalResults: meta.total,\n processingTime: meta.processingTimeMs,\n });\n\n return { products, meta };\n } catch (error: any) {\n this.logger.error('Advanced search failed, falling back to getProducts()', {\n error: error.message,\n stack: error.stack,\n });\n\n // Graceful fallback to basic getProducts()\n const products = await this.getProducts(options);\n return {\n products,\n meta: {\n limit: options?.first ?? 20,\n offset: Number(options?.after ?? 0),\n hybridSearchUsed: false,\n },\n };\n }\n }\n\n /**\n * Get available filter options for product filtering\n * \n * Aggregates filters from:\n * - Basic filters: categories, collections (always available)\n * - Advanced filters: price range, stock (if useAdvancedSearch=true)\n * - Custom attributes: category-specific attributes from backend\n * \n * Returns empty array if backend doesn't support dynamic filters\n */\n async getAvailableFilters(options: {\n categoryId?: string;\n useAdvancedSearch?: boolean;\n includeBasicFilters?: boolean;\n includeFacetCounts?: boolean;\n }): Promise<FilterConfig[]> {\n this.logger.debug('getAvailableFilters', options);\n\n const filters: FilterConfig[] = [];\n\n try {\n // 1. Basic filters (categories, collections)\n if (options.includeBasicFilters !== false) {\n // Categories filter\n const categories = await this.getCategories({ includeDescendants: false });\n if (categories.length > 0) {\n filters.push({\n id: 'categories',\n label: 'Categories',\n type: 'multi',\n options: categories.map(cat => ({\n value: cat.handle ?? cat.id, // URL slug: ?categories=electronics\n label: cat.name, // Display: \"Electronics\"\n id: cat.id, // Backend ID: pcat_01KMND...\n })),\n isActive: false,\n ranking: 10, // Lower = higher priority\n });\n }\n\n // Collections filter\n const collections = await this.getCollections({ limit: 100 });\n if (collections.length > 0) {\n filters.push({\n id: 'collections',\n label: 'Collections',\n type: 'multi',\n options: collections.map(col => ({\n value: col.handle ?? col.id, // URL slug: ?collections=summer-2024\n label: col.title, // Display: \"Summer 2024\"\n id: col.id, // Backend ID: pcol_01KMND...\n })),\n isActive: false,\n ranking: 20,\n });\n }\n }\n\n // 2. Advanced filters (price, stock)\n if (options.useAdvancedSearch && this.capabilities.advancedSearch) {\n // resolved on all requests. Currently omitted to avoid 400 errors from\n // getProducts fallback when regionId is missing.\n filters.push({\n id: 'price',\n label: 'Price',\n type: 'range',\n min: 0,\n max: 10000,\n isActive: false,\n ranking: 0,\n });\n\n // Stock availability filter\n // ID must match the URL param read by page.tsx (?isAvailable=true)\n filters.push({\n id: 'isAvailable',\n label: 'In Stock',\n type: 'boolean',\n isActive: false,\n ranking: 5,\n });\n }\n\n // 3. Custom attributes (category-specific)\n // Guard: skip API call entirely when the customAttributes capability is disabled.\n // This prevents a network request to /store/custom-attributes/category/:id and\n // avoids rendering attribute filters that the backend hasn't enabled as a capability.\n if (options.categoryId && this.capabilities.customAttributes) {\n try {\n const url = `${this.baseUrl}/store/custom-attributes/category/${options.categoryId}`;\n this.logger.debug('Fetching custom attributes', { url });\n\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig\n );\n\n if (response.ok) {\n const data = await response.json();\n const rawAttributes = data.attributes || [];\n\n // Transform backend attributes to FilterConfig\n // Backend response shape: { attributes: [{ attribute_id, attribute: { name, handle, ... } }] }\n // The actual attribute data is nested inside the \"attribute\" property.\n rawAttributes.forEach((item: any) => {\n // Unwrap nested structure: item may be { attribute_id, attribute: {...} }\n // or a flat object with properties directly on it\n const attr = item.attribute ?? item;\n\n if (!attr.is_filterable || !attr.is_active) {\n return; // Skip non-filterable or inactive attributes\n }\n\n const filterType = this.mapAttributeTypeToFilterType(attr.type);\n\n const filter: FilterConfig = {\n id: attr.handle,\n label: attr.name,\n type: filterType,\n isActive: false,\n ranking: attr.ranking || 50, // Custom attributes lower priority\n };\n\n // Add options for single/multi types\n if ((filterType === 'single' || filterType === 'multi') && attr.values) {\n filter.options = attr.values.map((val: any) => ({\n value: this.toSlug(val.value), // URL slug: ?ram=8gb\n label: val.value, // Display: \"8GB\"\n id: val.id, // Backend ID: 01KN03N67V13K5S2E6B6695KRN\n count: options.includeFacetCounts ? val.count : undefined,\n }));\n }\n\n // Add range values for numeric types\n if (filterType === 'range' && attr.metadata) {\n filter.min = attr.metadata.min || 0;\n filter.max = attr.metadata.max || 100;\n }\n\n filters.push(filter);\n });\n\n this.logger.debug('Custom attributes loaded', {\n categoryId: options.categoryId,\n attributesCount: rawAttributes.length,\n filterableCount: filters.length,\n });\n } else {\n this.logger.warn('Custom attributes endpoint not available', {\n status: response.status,\n categoryId: options.categoryId,\n });\n }\n } catch (attrError: any) {\n // Don't fail if custom attributes unavailable\n this.logger.warn('Failed to load custom attributes, continuing without them', {\n error: attrError.message,\n categoryId: options.categoryId,\n });\n }\n }\n\n // Sort by ranking (lower = higher priority)\n filters.sort((a, b) => (a.ranking ?? 0) - (b.ranking ?? 0));\n\n this.logger.debug('Filters aggregated', {\n totalFilters: filters.length,\n filterIds: filters.map(f => f.id),\n });\n\n return filters;\n } catch (error: any) {\n this.logger.error('Failed to get available filters', {\n error: error.message,\n stack: error.stack,\n });\n\n // Return empty array on error (don't block UI)\n return [];\n }\n }\n\n /**\n * Convert a human-readable string to a URL-safe slug.\n * Used to produce SEO-friendly filter values (option.value) that go into the URL.\n *\n * Examples:\n * \"8GB RAM\" → \"8gb-ram\"\n * \"Red Color\" → \"red-color\"\n * \"16 GB\" → \"16-gb\"\n */\n private toSlug(str: string): string {\n return str\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '');\n }\n\n /**\n * Map backend attribute type to filter type\n */\n private mapAttributeTypeToFilterType(\n backendType: string\n ): 'single' | 'multi' | 'boolean' | 'range' {\n switch (backendType) {\n case 'single-select':\n return 'single';\n case 'multi-select':\n return 'multi';\n case 'boolean':\n return 'boolean';\n case 'number':\n case 'range':\n return 'range';\n default:\n return 'multi'; // Default to multi-select\n }\n }\n\n // ============================================\n // Collection Operations\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n this.logger.debug('getCollection', { handle });\n\n try {\n const { collections } = (await this.sdk.store.collection.list({\n handle: [handle],\n limit: 1,\n })) as any;\n\n if (!collections || collections.length === 0) {\n this.logger.debug('Collection not found', { handle });\n return undefined;\n }\n\n return transformCollection(collections[0]);\n } catch (error: any) {\n this.logger.error('Failed to fetch collection', { handle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch collection: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n this.logger.debug('getCollections', { options });\n\n try {\n // Increase limit for client-side filtering to improve search results\n // If query is present, fetch more items (up to 1000) to increase likelihood of finding matches\n const limit = options?.query ? 1000 : (options?.limit || 100);\n \n const { collections } = (await this.sdk.store.collection.list({\n limit,\n })) as any;\n\n let result = collections.map(transformCollection);\n\n // Client-side search filtering (Medusa Store API lacks query param for collections)\n if (options?.query) {\n const q = options.query.toLowerCase();\n result = result.filter((c: Collection) => \n c.title.toLowerCase().includes(q) || \n c.handle.toLowerCase().includes(q)\n );\n }\n\n return result;\n } catch (error: any) {\n this.logger.error('Failed to fetch collections', { error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch collections: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getCollectionProducts(\n handle: string,\n options: CollectionProductsOptions = {},\n ): Promise<Product[]> {\n this.logger.debug('getCollectionProducts', { handle, options });\n\n try {\n // First get the collection to get its ID\n const collection = await this.getCollection(handle);\n if (!collection) {\n throw new ResourceNotFoundError('Collection', handle);\n }\n\n // Then get products for this collection\n const collectionQueryParams: any = {\n collection_id: [collection.handle], // Medusa uses handle in queries\n order: options.sortKey,\n limit: options.first ?? 100,\n offset: options.after ? parseInt(options.after, 10) : undefined,\n fields:\n '+variants,+variants.prices,+variants.calculated_prices,+variants.inventory_quantity,+options,+images,+tags',\n };\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n collectionQueryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(collectionQueryParams);\n\n return products.map((p) => transformProduct(p, this.currencyCode));\n } catch (error: any) {\n if (error instanceof ResourceNotFoundError) throw error;\n\n this.logger.error('Failed to fetch collection products', { handle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch collection products: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n // ============================================\n // Category Operations\n // ============================================\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n this.logger.debug('getCategory', { idOrHandle });\n\n try {\n const { product_categories } = (await this.sdk.store.category.list({\n handle: [idOrHandle],\n limit: 1,\n })) as any;\n\n if (!product_categories || product_categories.length === 0) {\n this.logger.debug('Category not found', { idOrHandle });\n return undefined;\n }\n\n return transformCategory(product_categories[0]);\n } catch (error: any) {\n this.logger.error('Failed to fetch category', { idOrHandle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch category: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Returns the set of product-category IDs that have at least one product\n * available in the given sales channel.\n *\n * Because Medusa's store/product-categories endpoint does not accept a\n * `sales_channel_id` filter, we derive the active category IDs by querying\n * store/products with the sales-channel scope and collecting the category\n * relations from the response. Pagination is handled internally so the\n * result is always complete regardless of catalog size.\n *\n * @deprecated Use `_getChannelCategories()` instead (backed by Thor Commerce plugin).\n * Kept as fallback for backends without the plugin installed.\n */\n private async _getActiveCategoryIds(salesChannelId: string): Promise<Set<string>> {\n this.logger.debug('_getActiveCategoryIds', { salesChannelId });\n const categoryIds = new Set<string>();\n const limit = 500;\n let offset = 0;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { products } = (await this.sdk.store.product.list({\n sales_channel_id: [salesChannelId],\n // Request only the category id relation to minimise payload size\n fields: '+categories.id',\n limit,\n offset,\n } as any)) as any;\n\n for (const product of products ?? []) {\n for (const cat of product.categories ?? []) {\n if (cat?.id) categoryIds.add(cat.id);\n }\n }\n\n if (!products || products.length < limit) break;\n offset += limit;\n }\n\n this.logger.debug('_getActiveCategoryIds result', { count: categoryIds.size });\n return categoryIds;\n }\n\n /**\n * Fetch channel-scoped categories from Thor Commerce plugin.\n * Uses `GET /store/thor/categories` — a single indexed query.\n * Falls back to `_getActiveCategoryIds()` if the plugin is not available.\n */\n private async _getChannelCategories(salesChannelId: string): Promise<Set<string>> {\n try {\n const url = `${this.baseUrl}/store/thor/categories`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (response.status === 404) {\n // Plugin not installed — fall back to legacy N+1 method\n this.logger.debug('Thor plugin categories endpoint not found, falling back to legacy method');\n return this._getActiveCategoryIds(salesChannelId);\n }\n\n if (!response.ok) {\n this.logger.warn('Thor plugin categories endpoint returned non-OK status', {\n status: response.status,\n });\n return this._getActiveCategoryIds(salesChannelId);\n }\n\n const data = await response.json();\n const categoryIds = new Set<string>();\n for (const cat of data.categories ?? []) {\n if (cat?.id) categoryIds.add(cat.id);\n }\n\n this.logger.debug('_getChannelCategories result (Thor plugin)', { count: categoryIds.size });\n return categoryIds;\n } catch (error) {\n this.logger.warn('Failed to fetch channel categories from Thor plugin, falling back to legacy method', {\n error: error instanceof Error ? error.message : String(error),\n });\n return this._getActiveCategoryIds(salesChannelId);\n }\n }\n\n async getCategories(options: GetCategoriesOptions = {}): Promise<ProductCategory[]> {\n this.logger.debug('getCategories', { options });\n\n const { customFetcher } = options;\n\n // If custom fetcher provided, use it instead of default SDK logic\n if (customFetcher) {\n this.logger.debug('Using custom fetcher for categories');\n return customFetcher(options);\n }\n\n try {\n // Increase limit for client-side filtering to improve search results\n // If query is present, fetch more items (up to 1000) to increase likelihood of finding matches\n const limit = options.query ? 1000 : (options.limit ?? 100);\n\n const queryParams: any = {\n limit,\n include_descendants_tree: options.includeDescendants ?? false,\n };\n\n if (options.parentCategoryId) {\n queryParams.parent_category_id = options.parentCategoryId;\n }\n\n const { product_categories } = (await this.sdk.store.category.list(queryParams)) as any;\n\n let result = product_categories.map(transformCategory);\n\n // --- Sales channel scoping ---\n // Prefer Thor Commerce plugin endpoint (single indexed query).\n // Falls back to legacy N+1 method if plugin is not installed.\n const salesChannelId =\n options.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n const activeCategoryIds = await this._getChannelCategories(salesChannelId);\n result = result.filter((c: ProductCategory) => activeCategoryIds.has(c.id));\n }\n\n // Client-side search filtering\n if (options.query) {\n const q = options.query.toLowerCase();\n result = result.filter(\n (c: ProductCategory) =>\n c.name.toLowerCase().includes(q) || c.handle.toLowerCase().includes(q),\n );\n }\n\n return result;\n } catch (error: any) {\n this.logger.error('Failed to fetch categories', { error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch categories: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n async getCategoryProducts(\n handle: string,\n options: CollectionProductsOptions = {},\n ): Promise<Product[]> {\n this.logger.debug('getCategoryProducts', { handle, options });\n\n try {\n // First get the category to get its ID\n const category = await this.getCategory(handle);\n if (!category) {\n throw new ResourceNotFoundError('Category', handle);\n }\n\n // Then get products for this category\n const categoryQueryParams: any = {\n category_id: [category.id],\n order: options.sortKey,\n limit: options.first ?? 100,\n offset: options.after ? parseInt(options.after, 10) : undefined,\n fields:\n '+variants,+variants.prices,+variants.calculated_prices,+variants.inventory_quantity,+options,+images,+tags',\n };\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n categoryQueryParams.sales_channel_id = [salesChannelId];\n }\n\n const { products } = await this.sdk.store.product.list(categoryQueryParams);\n\n return products.map((p) => transformProduct(p, this.currencyCode));\n } catch (error: any) {\n if (error instanceof ResourceNotFoundError) throw error;\n\n this.logger.error('Failed to fetch category products', { handle, error: error.message });\n throw new ProviderAPIError(\n `Failed to fetch category products: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n // ============================================\n // Cart Operations\n // ============================================\n\n async createCart(options?: { regionId?: string }): Promise<Cart> {\n this.logger.debug('createCart', { regionId: options?.regionId });\n\n try {\n const createPayload: any = {};\n\n // If a regionId is provided, prefer letting Medusa resolve the currency\n // from the region. Do NOT set `currency_code` when `region_id` is present,\n // otherwise Medusa may use the provided currency and ignore the region.\n if (options?.regionId) {\n createPayload.region_id = options.regionId;\n } else {\n createPayload.currency_code = this.currencyCode.toLowerCase();\n }\n\n const { cart } = await this.sdk.store.cart.create(createPayload);\n\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create cart', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create cart: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n this.logger.debug('getCart', { cartId });\n\n try {\n const cart = await this.retrieveCartWithLineDetails(cartId);\n\n if (!cart) {\n this.logger.debug('Cart not found', { cartId });\n return undefined;\n }\n\n return transformCart(cart);\n } catch (error: unknown) {\n // Medusa returns 404 for non-existent carts\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) {\n this.logger.debug('Cart not found', { cartId });\n return undefined;\n }\n\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch cart', { cartId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch cart: ${errorMessage}`, 'medusa', status);\n }\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n this.logger.debug('addToCart', { cartId, lines });\n\n try {\n // Ensure cart exists and has a region_id before attempting to add line items.\n // If Medusa can't resolve pricing due to missing region/pricing rows, it will throw a 500.\n const retrieveCtx = { cartId };\n const retrieveResult = await this.withRetry(\n async () => this.sdk.store.cart.retrieve(cartId),\n 'retrieveCartBeforeAdd',\n retrieveCtx,\n );\n\n console.log('retrieveResult =', JSON.stringify(retrieveResult, null, 2))\n \n const backendCart = (retrieveResult as any)?.cart;\n if (!backendCart) {\n this.logger.warn('Cart not found before addToCart', { cartId });\n throw new ProviderAPIError('Cart not found. Please refresh and try again.', 'medusa', 404);\n }\n\n console.log('backendCart =', JSON.stringify(backendCart, null, 2))\n\n if (!backendCart.region_id) {\n this.logger.warn('Attempted to add item to cart with no region_id', { cartId });\n throw new ProviderAPIError(\n 'Cart does not have a region set. Please select a region or recreate your cart and try again.',\n 'medusa',\n 400,\n );\n }\n\n // Add items one by one (Medusa SDK doesn't support batch add)\n for (const line of lines) {\n this.logger.debug('createLineItem payload', {\n cartId,\n variant_id: line.merchandiseId,\n quantity: line.quantity,\n cartRegion: backendCart.region_id,\n });\n\n // Pre-check: ensure variant has pricing for the cart's region/currency to avoid server 500\n try {\n // The Medusa SDK may not expose a direct productVariant.retrieve endpoint in this version.\n // Use product.list filtered by region to locate the variant and request region-aware prices.\n const variantCheckParams: any = {\n limit: 200,\n fields: '+variants,+variants.calculated_price,+variants.prices,+variants.money_amounts',\n region_id: backendCart.region_id,\n };\n\n // Scope to storefront sales channel when configured.\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n variantCheckParams.sales_channel_id = [salesChannelId];\n }\n\n const plist = await this.sdk.store.product.list(variantCheckParams);\n const products = (plist as any)?.products || [];\n let foundVariant: any | undefined;\n for (const p of products) {\n if (Array.isArray(p.variants)) {\n const v = p.variants.find((vv: any) => vv.id === line.merchandiseId);\n if (v) {\n foundVariant = v;\n break;\n }\n }\n }\n\n if (!foundVariant) {\n this.logger.warn('Variant not found in product.list for pricing check', {\n variantId: line.merchandiseId,\n cartRegion: backendCart.region_id,\n });\n throw new ProviderAPIError(\n 'Product or variant not found. Please refresh and try again.',\n 'medusa',\n 404,\n );\n }\n\n console.log('Found Variant:', JSON.stringify(foundVariant, null, 2));\n\n const variant = foundVariant;\n // Prefer calculated_price when present\n let hasPriceForRegion = false;\n if (\n variant?.calculated_price &&\n (variant.calculated_price.calculated_amount ?? null) !== null\n ) {\n const calcCurrency = (variant.calculated_price.currency_code || '').toLowerCase();\n const cartCurrency = (\n backendCart.currency_code ||\n this.currencyCode ||\n ''\n ).toLowerCase();\n\n console.log('calcCurrency =', calcCurrency);\n console.log('cartCurrency =', cartCurrency);\n console.log('this.currencyCode =', this.currencyCode)\n\n if (\n !cartCurrency ||\n calcCurrency === cartCurrency ||\n calcCurrency === this.currencyCode.toLowerCase()\n ) {\n hasPriceForRegion = true;\n }\n }\n\n if (!hasPriceForRegion) {\n const prices = variant?.prices || variant?.money_amounts || [];\n hasPriceForRegion =\n Array.isArray(prices) &&\n prices.some((p: any) => {\n return (\n p.region_id === backendCart.region_id ||\n p.currency_code === backendCart.currency_code ||\n p.currency_code === this.currencyCode ||\n p.currency === this.currencyCode\n );\n });\n }\n\n if (!hasPriceForRegion) {\n const prices = variant?.prices || variant?.money_amounts || [];\n this.logger.warn('Variant missing price for cart region (product.list)', {\n variantId: line.merchandiseId,\n cartRegion: backendCart.region_id,\n prices,\n });\n throw new ProviderAPIError(\n 'This product does not have pricing configured for your selected region. Please try a different region or contact support.',\n 'medusa',\n 400,\n );\n }\n } catch (variantErr) {\n this.logger.error('Variant price check failed', {\n variantId: line.merchandiseId,\n error: extractErrorMessage(variantErr),\n });\n // Surface a clear error to avoid a 500 from backend when possible\n throw new ProviderAPIError(\n 'Unable to verify variant pricing before adding to cart. Please try again later.',\n 'medusa',\n 500,\n );\n }\n\n const result = await this.sdk.store.cart.createLineItem(cartId, {\n variant_id: line.merchandiseId,\n quantity: line.quantity,\n });\n void result;\n }\n\n const cart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n const errorDetails: any = { cartId, lines, message: errorMessage };\n\n if (typeof error === 'object' && error !== null) {\n const err = error as any;\n if (err.status) errorDetails.status = err.status;\n if (err.statusCode) errorDetails.statusCode = err.statusCode;\n if (err.code) errorDetails.code = err.code;\n // If SDK exposes response body, include it for diagnostics\n if (err.response) {\n errorDetails.backendResponse = err.response.data ?? err.response;\n }\n // Fallback: include entire error for logs\n try {\n errorDetails.fullError = JSON.stringify(err, Object.getOwnPropertyNames(err));\n } catch (e) {\n // ignore stringify errors\n }\n }\n\n this.logger.error('Failed to add to cart', errorDetails);\n\n const status = (error as any)?.status || (error as any)?.statusCode;\n let userMessage = errorMessage;\n\n if (status === 500) {\n userMessage =\n 'Unable to add product to cart. This product may not have pricing configured for your selected region. Please try selecting a different region or contact support.';\n } else if (status === 404) {\n userMessage = 'Product or cart not found. Please refresh the page and try again.';\n } else if (status === 400 || status === 422) {\n userMessage = 'Invalid product configuration. This product may be unavailable.';\n }\n\n throw new ProviderAPIError(userMessage, 'medusa', status);\n }\n }\n\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n this.logger.debug('removeFromCart', { cartId, lineIds });\n \n try {\n // Medusa removes line items one at a time\n for (const lineId of lineIds) {\n await this.sdk.store.cart.deleteLineItem(cartId, lineId);\n }\n\n const cart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to remove from cart', { cartId, lineIds, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to remove from cart: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n this.logger.debug('updateCart', { cartId, lines });\n\n try {\n // Medusa updates line items one at a time\n for (const line of lines) {\n await this.sdk.store.cart.updateLineItem(cartId, line.id, {\n quantity: line.quantity,\n });\n }\n\n const cart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(cart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to update cart', { cartId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to update cart: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n /**\n * Get available regions from Medusa\n * Returns region information including id, name, and currency\n */\n async getRegions(): Promise<\n Array<{\n id: string;\n name: string;\n currency_code: string;\n countries?: Array<{ id: string; iso_2: string; name: string; display_name?: string }>;\n }>\n > {\n this.logger.debug('getRegions');\n\n try {\n const { regions } = await this.sdk.store.region.list();\n\n return regions.map((region: any) => ({\n id: region.id,\n name: region.name,\n currency_code: region.currency_code,\n countries: region.countries,\n }));\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch regions', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to fetch regions: ${errorMessage}`,\n 'medusa',\n (error as any)?.status || (error as any)?.statusCode,\n );\n }\n }\n\n // ============================================\n // Payment Operations\n // ============================================\n\n // ============================================\n // Order Operations\n // ============================================\n\n /**\n * Get all orders for a customer (storefront).\n *\n * Note: This retrieves orders from the storefront API (store.order.list),\n * which returns orders only for the authenticated customer in the JWT.\n *\n * @param options - Order query options (supports callbacks for custom backends)\n * @returns Array of orders for the authenticated customer\n *\n * @example\n * ```typescript\n * const orders = await provider.getOrders();\n * console.log(`Found ${orders.length} orders`);\n * ```\n */\n async getOrders(options: GetOrdersOptions = {}): Promise<Order[]> {\n const { customFetcher, salesChannelId } = options;\n\n // If custom fetcher provided, use it instead of default SDK logic\n if (customFetcher) {\n this.logger.debug('Using custom fetcher for orders');\n return customFetcher(options);\n }\n\n this.logger.info('Getting orders for authenticated customer');\n\n try {\n const result = await this.withRetry(\n async () =>\n this.sdk.store.order.list({\n // Medusa v2 JS-SDK automatically includes authorization header if JWT is present\n fields: '+items,+items.variant,+items.variant.product,+shipping_address,+billing_address,+customer',\n }),\n 'getOrders',\n {},\n );\n\n const orders = result.orders ?? [];\n this.logger.debug(`Found ${orders.length} orders for customer`);\n\n const transformed: Order[] = orders.map((order: any) => transformOrder(order));\n\n // Multi-tenant: filter by sales channel if requested\n const channelId = salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (channelId) {\n const scoped = filterByChannel<Order>(transformed, channelId);\n this.logger.debug(\n `Channel scoping: ${scoped.length}/${transformed.length} orders match channel ${channelId}`,\n );\n return scoped;\n }\n\n return transformed;\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n\n this.logger.error('Error getting orders', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to fetch orders: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n /**\n * Get a single order by ID\n *\n * @param orderId - Order ID\n * @returns Order or undefined if not found\n *\n * @example\n * ```typescript\n * const order = await provider.getOrder('order_123');\n * if (order) {\n * console.log(`Order ${order.orderNumber} - ${order.status}`);\n * }\n * ```\n */\n async getOrder(orderId: string): Promise<Order | undefined> {\n this.logger.info('Getting order', orderId);\n\n if (!orderId) {\n throw new ProviderAPIError('Order ID is required', 'medusa');\n }\n\n try {\n const { order } = await this.withRetry(\n async () =>\n this.sdk.store.order.retrieve(orderId, {\n fields: '+items,+items.variant,+items.variant.product,+shipping_address,+billing_address,+customer',\n }),\n 'getOrder',\n { orderId },\n );\n\n if (!order) {\n this.logger.debug(`Order not found: ${orderId}`);\n return undefined;\n }\n\n this.logger.debug(`Retrieved order: ${order.display_id ?? orderId}`);\n\n return transformOrder(order);\n } catch (error: unknown) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) {\n this.logger.debug(`Order not found: ${orderId}`);\n return undefined;\n }\n\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch order', { orderId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch order: ${errorMessage}`, 'medusa', status);\n }\n }\n\n // ============================================\n // Customer Operations\n // ============================================\n\n /**\n * List customers with optional filtering and pagination.\n *\n * Uses the Medusa admin API — requires admin-level JWT.\n *\n * @param options - Query options (search, sort, pagination)\n * @returns Array of customers\n *\n * @example\n * ```typescript\n * const customers = await provider.getCustomers({ search: 'john', limit: 20, offset: 0 });\n * ```\n */\n async getCustomers(options: GetCustomersOptions = {}): Promise<Customer[]> {\n this.logger.info('Getting customers', options);\n\n const { search, limit = 20, offset = 0, sortBy = 'createdAt', salesChannelId, customFetcher } = options;\n\n // If custom fetcher provided, use it instead of default SDK logic\n if (customFetcher) {\n this.logger.debug('Using custom fetcher for customers');\n return customFetcher(options);\n }\n\n const orderMap: Record<string, string> = {\n createdAt: 'created_at',\n email: 'email',\n firstName: 'first_name',\n };\n\n try {\n // Build filters object for multi-tenant scoping\n const filters: Record<string, any> = {};\n if (salesChannelId) {\n filters.metadata = { sales_channel_id: salesChannelId };\n this.logger.debug(`Filtering customers by salesChannelId: ${salesChannelId}`);\n }\n\n const result = await this.makeAdminRequest(async () => {\n return (this.sdkAdmin as any).admin.customer.list({\n q: search || undefined,\n limit,\n offset,\n order: orderMap[sortBy] ?? 'created_at',\n ...(Object.keys(filters).length > 0 && { filters }),\n });\n });\n\n const customers = result?.customers ?? [];\n this.logger.debug(`Found ${customers.length} customers`);\n\n const transformed: Customer[] = customers.map((c: any) => transformCustomer(c));\n\n return transformed;\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Error getting customers', { error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch customers: ${errorMessage}`, 'medusa', status);\n }\n }\n\n /**\n * Get a single customer by ID.\n *\n * Uses the Medusa admin API.\n *\n * @param customerId - Customer ID\n * @returns Customer or undefined if not found\n */\n async getCustomer(customerId: string): Promise<Customer | undefined> {\n this.logger.info('Getting customer', customerId);\n\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa');\n }\n\n try {\n const result = await this.makeAdminRequest(async () => {\n return (this.sdkAdmin as any).admin.customer.retrieve(customerId);\n });\n\n if (!result?.customer) {\n return undefined;\n }\n\n return transformCustomer(result.customer);\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch customer', { customerId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch customer: ${errorMessage}`, 'medusa', status);\n }\n }\n\n /**\n * Update customer information.\n *\n * Uses the Medusa admin API.\n *\n * @param customerId - Customer ID\n * @param data - Fields to update\n * @returns Updated customer\n */\n async updateCustomer(\n customerId: string,\n data: Partial<Omit<Customer, 'id' | 'createdAt'>>,\n ): Promise<Customer> {\n this.logger.info('Updating customer', { customerId, fields: Object.keys(data) });\n\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa');\n }\n\n // Transform Thor camelCase → Medusa snake_case\n const payload: Record<string, unknown> = {};\n if (data.firstName !== undefined) payload.first_name = data.firstName;\n if (data.lastName !== undefined) payload.last_name = data.lastName;\n if (data.phone !== undefined) payload.phone = data.phone ?? null;\n if (data.email !== undefined) payload.email = data.email;\n if (data.metadata !== undefined) payload.metadata = data.metadata;\n\n try {\n const result = await this.makeAdminRequest(async () => {\n return (this.sdkAdmin as any).admin.customer.update(customerId, payload);\n });\n\n return transformCustomer(result.customer);\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to update customer', { customerId, error: errorMessage });\n throw new ProviderAPIError(`Failed to update customer: ${errorMessage}`, 'medusa', status);\n }\n }\n\n /**\n * Get orders placed by a specific customer (admin view).\n *\n * @param customerId - Customer ID\n * @param limit - Max number of orders (default: 10)\n * @returns Array of orders\n */\n async getCustomerOrders(customerId: string, limit = 10): Promise<Order[]> {\n this.logger.info('Getting orders for customer (admin)', { customerId, limit });\n\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa');\n }\n\n if (!this.isAdminConfigured) {\n this.logger.warn('getCustomerOrders: adminConfig not provided, returning empty result');\n return [];\n }\n\n try {\n // Use makeAdminRequest to ensure proper admin authentication.\n // withRetry() does NOT inject admin auth — it would send unauthenticated\n // requests to admin endpoints.\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.order.list({\n customer_id: customerId,\n limit,\n order: '-created_at',\n fields: '+items,+items.variant,+items.variant.product,+shipping_address',\n });\n\n const orders = result?.orders ?? [];\n this.logger.debug(`Found ${orders.length} orders for customer ${customerId}`);\n\n return orders.map((o: any) => transformOrder(o));\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to fetch customer orders', { customerId, error: errorMessage });\n throw new ProviderAPIError(`Failed to fetch customer orders: ${errorMessage}`, 'medusa', status);\n }\n }\n\n // ============================================\n // Admin Customer Operations\n // ============================================\n\n /**\n * List customers for admin dashboard.\n *\n * Uses makeAdminRequest() to ensure proper admin authentication.\n * Unlike getCustomers() (which currently lacks admin auth), this method\n * properly awaits admin initialization and authenticates via SDK admin session.\n *\n * Gracefully degrades to empty result when adminConfig is not provided.\n *\n * @param options - Query options (search, limit, offset, salesChannelId)\n * @returns Object with customers array and count\n */\n async getAdminCustomers(options?: {\n search?: string;\n limit?: number;\n offset?: number;\n salesChannelId?: string;\n }): Promise<{ customers: Customer[]; count: number }> {\n if (!this.isAdminConfigured) {\n this.logger.warn('getAdminCustomers: adminConfig not provided, returning empty result');\n return { customers: [], count: 0 };\n }\n\n const limit = Math.min(options?.limit ?? 20, 1000);\n const offset = options?.offset ?? 0;\n\n this.logger.info('Getting admin customers', {\n limit,\n offset,\n search: options?.search,\n salesChannelId: options?.salesChannelId,\n });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.customer.list({\n limit,\n offset,\n order: '-created_at',\n ...(options?.search && { q: options.search }),\n });\n\n const customers = result?.customers ?? [];\n const count = result?.count ?? customers.length;\n\n this.logger.debug(`Admin customers: fetched ${customers.length} (backend count: ${count})`);\n\n const transformed: Customer[] = customers.map((c: any) => transformCustomer(c));\n\n // NOTE: Medusa customers are global — they are not natively scoped to\n // a sales channel. filterByChannel checks metadata.sales_channel_id\n // which Medusa seeds never set → would filter out ALL customers.\n // For admin dashboard, show all customers.\n this.logger.debug(`Admin customers: ${transformed.length} returned (backend count: ${count})`);\n\n return { customers: transformed, count };\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin customers', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin customers: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Get a single customer by ID for admin dashboard.\n *\n * Uses makeAdminRequest() for proper admin authentication.\n * Returns undefined (not an error) when the customer is not found (404).\n *\n * @param customerId - Customer ID\n * @returns Customer or undefined if not found\n */\n async getAdminCustomer(customerId: string): Promise<Customer | undefined> {\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminCustomer requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin customer', { customerId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.customer.retrieve(customerId);\n if (!result?.customer) return undefined;\n return transformCustomer(result.customer);\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin customer', { customerId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin customer: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n // ============================================\n // Admin Customer Address Operations\n // ============================================\n\n /**\n * Get all addresses for a customer (admin operation).\n * Uses sdk.admin.customer.listAddresses() for proper admin authentication.\n *\n * @param customerId - The customer's ID\n * @returns Array of addresses\n */\n async getAdminCustomerAddresses(customerId: string): Promise<Address[]> {\n if (!customerId) {\n throw new ProviderAPIError('Customer ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminCustomerAddresses requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin customer addresses', { customerId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.customer.listAddresses(customerId);\n const addresses = result?.addresses ?? [];\n return addresses.map((addr: any) => transformAddress(addr));\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return [];\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin customer addresses', { customerId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get customer addresses: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n // ============================================\n // Admin Order Operations\n // ============================================\n\n /**\n * Get all orders for admin dashboard listing.\n *\n * Unlike getCustomerOrders() (which filters by a specific customerId via\n * sdk.admin.order.list with storefront JWT), this method:\n * - Lists ALL orders across the store\n * - Uses fetchAdminAPI() with proper admin credentials\n * - Applies multi-tenant channel scoping via filterByChannel()\n * - Gracefully degrades to empty result when adminConfig is not provided\n *\n * IMPORTANT: Do NOT use sdk.admin.order.list() here — it uses storefront\n * JWT auth which is insufficient for Medusa Admin API.\n */\n async getAdminOrders(options?: {\n search?: string;\n status?: string | string[];\n limit?: number;\n offset?: number;\n /** Medusa field name for sorting, e.g. 'created_at', 'total' */\n order?: string;\n direction?: 'asc' | 'desc';\n /** Filter by sales channel — uses Medusa native `sales_channel_id` query. */\n salesChannelId?: string;\n /**\n * When true, also fetches draft orders from /admin/draft-orders and merges\n * them into the result sorted by created_at desc. Draft orders are stored\n * as a separate entity from regular orders in Medusa v2 and do NOT appear\n * in GET /admin/orders.\n */\n includeDrafts?: boolean;\n }): Promise<{ orders: Order[]; count: number }> {\n if (!this.isAdminConfigured) {\n this.logger.warn('getAdminOrders: adminConfig not provided, returning empty result');\n return { orders: [], count: 0 };\n }\n\n const limit = Math.min(options?.limit ?? 20, 100);\n const offset = options?.offset ?? 0;\n\n this.logger.info('Getting admin orders', {\n limit,\n offset,\n search: options?.search,\n status: options?.status,\n salesChannelId: options?.salesChannelId,\n includeDrafts: options?.includeDrafts,\n });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { orders, count } = await this.sdkAdmin!.admin.order.list({\n limit,\n offset,\n fields:\n 'id,display_id,email,created_at,status,total,currency_code,' +\n '+items,+items.variant,' +\n '+shipping_address,+billing_address,+customer',\n ...(options?.search && { q: options.search }),\n // Medusa v2 admin API supports native sales_channel_id filter.\n ...(options?.salesChannelId && { sales_channel_id: [options.salesChannelId] }),\n });\n\n const transformed: Order[] = (orders ?? []).map((o: any) => transformOrder(o));\n\n this.logger.debug(`Admin orders: ${transformed.length} returned (backend count: ${count})`);\n\n // In Medusa v2, draft orders are a SEPARATE entity from regular orders.\n // GET /admin/orders never returns them — you must query GET /admin/draft-orders.\n // When includeDrafts is requested, merge both lists sorted by created_at desc.\n if (!options?.includeDrafts) {\n return { orders: transformed, count };\n }\n\n let draftOrders: Order[] = [];\n let draftCount = 0;\n\n try {\n // Fetch all draft orders (typically small number, no pagination needed).\n // Use a generous limit so we don't miss recently-created ones.\n const draftResult = await (this.sdkAdmin as any).admin.draftOrder.list({\n limit: 100,\n offset: 0,\n fields:\n 'id,display_id,email,created_at,status,total,currency_code,' +\n '+items,+items.variant,' +\n '+shipping_address,+billing_address,+customer',\n ...(options?.salesChannelId && { sales_channel_id: [options.salesChannelId] }),\n });\n\n // Medusa returns { draft_orders: [...], count: N }\n const rawDrafts = draftResult?.draft_orders ?? [];\n draftCount = draftResult?.count ?? rawDrafts.length;\n draftOrders = rawDrafts.map((o: any) => ({\n ...transformOrder(o),\n isDraft: true, // ← Mark as draft order for UI differentiation\n }));\n\n this.logger.debug(`Draft orders: ${draftOrders.length} returned (backend count: ${draftCount})`);\n } catch (draftError) {\n // Draft orders endpoint may not be available (plugin not installed).\n // Log warning but don't fail the whole request.\n this.logger.warn('Failed to fetch draft orders — plugin may not be installed', {\n error: extractErrorMessage(draftError),\n });\n }\n\n // Merge and sort combined list by created_at descending.\n const combined = [...transformed, ...draftOrders].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),\n );\n\n return { orders: combined, count: count + draftCount };\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin orders', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin orders: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Cancel an order (admin operation).\n * Uses sdk.admin.order.cancel() for proper SDK integration.\n * Throws ProviderAPIError if adminConfig is not provided.\n */\n async cancelOrder(orderId: string): Promise<Order> {\n if (!orderId || typeof orderId !== 'string') {\n throw new ProviderAPIError('Invalid order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'cancelOrder requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Cancelling order', { orderId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { order } = await this.sdkAdmin!.admin.order.cancel(orderId);\n\n const transformed = transformOrder(order);\n this.logger.debug('Order cancelled', { orderId, status: transformed.status });\n return transformed;\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to cancel order', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to cancel order: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Create a fulfillment for an order (admin operation).\n * Uses sdk.admin.order.createFulfillment() for proper SDK integration.\n * Throws ProviderAPIError if adminConfig is not provided.\n *\n * @param items - Optional specific line-items + quantities.\n * When omitted, Medusa fulfills all unfulfilled items.\n */\n async createFulfillment(\n orderId: string,\n items?: Array<{ id: string; quantity: number }>,\n ): Promise<void> {\n if (!orderId || typeof orderId !== 'string') {\n throw new ProviderAPIError('Invalid order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'createFulfillment requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Creating fulfillment', { orderId, itemCount: items?.length });\n\n if (items !== undefined && items.length === 0) {\n throw new ProviderAPIError(\n 'Cannot create fulfillment: items array must have at least one item.',\n 'medusa',\n 400,\n );\n }\n\n try {\n await this.makeAdminRequest(async () => {\n // items is guaranteed to be ≥1 here (empty array rejected above).\n // When items is undefined, pass items: [] to satisfy the SDK type;\n // Medusa will fulfill all unfulfilled items in that case.\n await this.sdkAdmin!.admin.order.createFulfillment(orderId, {\n items: items ?? [],\n });\n this.logger.debug('Fulfillment created', { orderId });\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create fulfillment', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create fulfillment: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Create a refund for an order (admin operation).\n *\n * Uses fetchAdminAPI() — NOT sdk.admin.refund.create().\n * Throws ProviderAPIError if adminConfig is not provided.\n *\n * @param amount - Amount in cents. Omit to refund the full order total.\n * @param reason - Reason string (default: 'admin_refund').\n */\n async createRefund(orderId: string, amount?: number, reason?: string): Promise<void> {\n if (!orderId || typeof orderId !== 'string') {\n throw new ProviderAPIError('Invalid order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'createRefund requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Creating refund', { orderId, amount, reason });\n\n try {\n await this.makeAdminRequest(async () => {\n // Note: Medusa v2 refunds are done via payment refund, not order refund\n // For now, fallback to manual request if SDK doesn't have direct order refund\n // This would need to be updated once we understand the exact refund flow\n // For now, we could use sdk.admin.claim.create() with type: 'refund'\n // or direct payment refund via sdk.admin.payment.refund()\n \n // Placeholder: using makeAdminRequest ensures proper auth\n // The actual refund endpoint may vary byMedusa version\n // Future: implement proper refund flow using SDK methods\n this.logger.warn('createRefund: full SDK integration pending - using minimal implementation');\n });\n this.logger.debug('Refund created', { orderId, amount });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create refund', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create refund: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * List all regions for admin dashboard (used in Create Order dialog).\n *\n * Returns Region[] compatible with CommerceProvider contract.\n * Maps Medusa's currency_code → currency and provides empty countryCodes array\n * when country detail is not required for the admin region picker.\n */\n async getAdminRegions(): Promise<Region[]> {\n if (!this.isAdminConfigured) {\n this.logger.warn('getAdminRegions: adminConfig not provided, returning empty result');\n return [];\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n const { regions } = await this.sdkAdmin!.admin.region.list({\n limit: 100,\n fields: 'id,name,currency_code,countries',\n });\n return (regions ?? []).map((r: any) => ({\n id: r.id,\n name: r.name,\n currency: r.currency_code ?? '',\n countryCodes: Array.isArray(r.countries)\n ? r.countries.map((c: any) => c.iso_2 ?? c.iso2 ?? '').filter(Boolean)\n : [],\n }));\n });\n } catch (error) {\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin regions', { error: errorMessage });\n return [];\n }\n }\n\n /**\n * Get a single order by ID for admin dashboard detail view.\n *\n * Uses makeAdminRequest() for proper admin authentication.\n * Returns full order with items, addresses, customer.\n *\n * @returns Order or undefined if not found\n */\n async getAdminOrder(orderId: string): Promise<Order | undefined> {\n if (!orderId) {\n throw new ProviderAPIError('Order ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminOrder requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin order', { orderId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { order } = await this.sdkAdmin!.admin.order.retrieve(orderId, {\n fields:\n 'id,display_id,email,created_at,updated_at,status,' +\n 'payment_status,fulfillment_status,' +\n 'total,subtotal,tax_total,shipping_total,discount_total,currency_code,' +\n '*items,*items.variant,' +\n '*shipping_address,*billing_address,*customer',\n });\n if (!order) return undefined;\n return transformOrder(order);\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin order', { orderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin order: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n /**\n * Get a single product by ID for admin dashboard detail view.\n *\n * Uses makeAdminRequest() for proper admin authentication.\n * Returns full product with variants and prices.\n *\n * @returns AdminProduct or undefined if not found\n */\n async getAdminProduct(productId: string): Promise<AdminProduct | undefined> {\n if (!productId) {\n throw new ProviderAPIError('Product ID is required', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'getAdminProduct requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Getting admin product', { productId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const { product } = await this.sdkAdmin!.admin.product.retrieve(productId, {\n fields:\n 'id,handle,title,description,status,thumbnail,' +\n '+variants,+variants.prices,+variants.inventory_quantity,+variants.sku,' +\n '+variants.options,+variants.options.option,' +\n '+images,+options',\n });\n if (!product) return undefined;\n return {\n id: product.id,\n handle: product.handle,\n title: product.title,\n description: (product as any).description ?? undefined,\n status: product.status,\n thumbnail: product.thumbnail ?? undefined,\n images: ((product as any).images ?? []).map((img: any) => img.url).filter(Boolean),\n variants: ((product as any).variants ?? []).map((v: any) => {\n // Build a readable title: explicit title > options joined > SKU > \"Default\"\n let variantTitle = v.title;\n if (!variantTitle && Array.isArray(v.options) && v.options.length > 0) {\n variantTitle = v.options\n .map((opt: any) => opt.value)\n .filter(Boolean)\n .join(' / ');\n }\n if (!variantTitle) variantTitle = v.sku || 'Default';\n\n return {\n id: v.id,\n title: variantTitle,\n sku: v.sku || undefined,\n quantityAvailable: v.inventory_quantity ?? undefined,\n prices: (v.prices ?? []).map((pr: any) => ({\n amount: pr.amount,\n currencyCode: (pr.currency_code ?? '').toUpperCase(),\n })),\n };\n }),\n };\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n if (status === 404) return undefined;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to get admin product', { productId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to get admin product: ${errorMessage}`,\n 'medusa',\n status,\n );\n }\n }\n\n /**\n * Create a draft order.\n *\n * Uses Medusa v2 `sdk.admin.draftOrder.create()` API.\n * Draft orders have `is_draft_order = true` and can be converted to regular orders.\n *\n * @param params - Draft order parameters\n * @returns Created draft order as a transformed Order\n */\n async createDraftOrder(params: {\n email: string;\n regionId: string;\n salesChannelId?: string;\n items: Array<{ variantId: string; quantity: number }>;\n shippingAddress?: {\n firstName?: string;\n lastName?: string;\n address1?: string;\n city?: string;\n countryCode?: string;\n postalCode?: string;\n };\n }): Promise<Order> {\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'createDraftOrder requires adminConfig.',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Creating draft order', {\n email: params.email,\n regionId: params.regionId,\n itemCount: params.items.length,\n });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.draftOrder.create({\n email: params.email,\n region_id: params.regionId,\n ...(params.salesChannelId && { sales_channel_id: params.salesChannelId }),\n items: params.items.map((item) => ({\n variant_id: item.variantId,\n quantity: item.quantity,\n })),\n ...(params.shippingAddress && {\n shipping_address: {\n first_name: params.shippingAddress.firstName,\n last_name: params.shippingAddress.lastName,\n address_1: params.shippingAddress.address1,\n city: params.shippingAddress.city,\n country_code: params.shippingAddress.countryCode,\n postal_code: params.shippingAddress.postalCode,\n },\n }),\n });\n\n const draftOrder = result?.draft_order;\n if (!draftOrder) {\n throw new ProviderAPIError('Draft order creation returned no data', 'medusa', 500);\n }\n\n this.logger.debug('Draft order created', { id: draftOrder.id });\n return transformOrder(draftOrder);\n });\n } catch (error) {\n if (error instanceof ProviderAPIError) throw error;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to create draft order', { error: errorMessage });\n throw new ProviderAPIError(\n `Failed to create draft order: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n /**\n * Convert a draft order into a regular (pending) order.\n *\n * Uses `sdk.admin.draftOrder.convertToOrder()` which maps to\n * `POST /admin/draft-orders/{id}/convert-to-order`.\n * Returns the newly created order transformed into `@thorprovider/types.Order`.\n */\n async undraftOrder(draftOrderId: string): Promise<Order> {\n if (!draftOrderId || typeof draftOrderId !== 'string') {\n throw new ProviderAPIError('Invalid draft order ID', 'medusa', 400);\n }\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'undraftOrder requires adminConfig. Pass adminConfig to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n this.logger.info('Converting draft order to order', { draftOrderId });\n\n try {\n return await this.makeAdminRequest(async () => {\n const result = await (this.sdkAdmin as any).admin.draftOrder.convertToOrder(\n draftOrderId,\n );\n const order = result?.order;\n if (!order) {\n throw new ProviderAPIError(\n 'Unexpected response: missing order in convertToOrder result',\n 'medusa',\n 500,\n );\n }\n this.logger.debug('Draft order converted to order', { id: order.id });\n return transformOrder(order);\n });\n } catch (error) {\n if (error instanceof ProviderAPIError) throw error;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to convert draft order', { draftOrderId, error: errorMessage });\n throw new ProviderAPIError(\n `Failed to convert draft order: ${errorMessage}`,\n 'medusa',\n (error as any)?.status,\n );\n }\n }\n\n // ============================================\n // Channel Scope Operations (Multi-Tenant)\n // ============================================\n\n /**\n * Assign a customer to a sales channel via metadata.\n *\n * This is the primary mechanism for multi-tenant isolation of entities\n * that the backend does not natively scope to a sales channel\n * (e.g. customers in Medusa).\n *\n * Writes `sales_channel_id` + audit fields into `customer.metadata`.\n * After assignment, `getCustomers({ salesChannelId })` will include\n * this customer in its results.\n *\n * @param customerId - Customer to assign\n * @param channelId - Target sales channel\n * @param assignedBy - Optional: who triggered the assignment\n * @returns Updated customer with new metadata\n *\n * @example\n * ```typescript\n * // Dropshipper creates customer → assign to their channel\n * const customer = await commerce.assignCustomerToChannel(\n * 'cus_01HXXX',\n * process.env.NEXT_PUBLIC_SALES_CHANNEL_ID!,\n * 'admin@mystore.com',\n * );\n * ```\n */\n async assignCustomerToChannel(\n customerId: string,\n channelId: string,\n assignedBy?: string,\n ): Promise<Customer> {\n validateChannelScopeAssignment(customerId, channelId, assignedBy);\n\n this.logger.info('Assigning customer to channel', { customerId, channelId, assignedBy });\n\n // Fetch current metadata to merge (preserves existing keys)\n const existing = await this.getCustomer(customerId);\n const currentMeta = existing?.metadata ?? {};\n\n const scopeMeta = buildChannelScopeMetadata(channelId, assignedBy);\n\n return this.updateCustomer(customerId, {\n metadata: { ...currentMeta, ...scopeMeta },\n });\n }\n\n /**\n * Assign an order to a sales channel via metadata.\n *\n * Same pattern as `assignCustomerToChannel` but for orders.\n * Useful when orders are created through flows that don't automatically\n * link them to a channel.\n *\n * @param orderId - Order to assign\n * @param channelId - Target sales channel\n * @param assignedBy - Optional: who triggered the assignment\n */\n async assignOrderToChannel(\n orderId: string,\n channelId: string,\n assignedBy?: string,\n ): Promise<void> {\n validateChannelScopeAssignment(orderId, channelId, assignedBy);\n\n this.logger.info('Assigning order to channel', { orderId, channelId, assignedBy });\n\n const scopeMeta = buildChannelScopeMetadata(channelId, assignedBy);\n\n if (!this.isAdminConfigured) {\n throw new ProviderAPIError(\n 'assignOrderToChannel requires adminConfig. Pass adminConfig.apiKey to createProvider().',\n 'medusa',\n 503,\n );\n }\n\n try {\n await this.makeAdminRequest(async () => {\n await (this.sdkAdmin as any).admin.order.update(orderId, {\n metadata: scopeMeta,\n });\n });\n } catch (error) {\n const status = (error as any)?.status || (error as any)?.statusCode;\n const errorMessage = extractErrorMessage(error);\n this.logger.error('Failed to assign order to channel', { orderId, channelId, error: errorMessage });\n throw new ProviderAPIError(`Failed to assign order to channel: ${errorMessage}`, 'medusa', status);\n }\n }\n\n // ============================================\n // Payment Operations\n // ============================================\n\n /**\n * Get available payment methods\n *\n * Queries Medusa for payment providers available in a specific region.\n * Region is determined either from options.regionId or from the cart.\n *\n * @param options - Payment methods query options (regionId or cartId required)\n * @returns Array of available payment methods\n *\n * @example\n * ```typescript\n * // Get payment methods for a region\n * const methods = await provider.getPaymentMethods({\n * regionId: 'reg_123',\n * enabledOnly: true\n * });\n *\n * // Get payment methods for a cart\n * const methods = await provider.getPaymentMethods({\n * cartId: 'cart_123'\n * });\n * ```\n */\n async getPaymentMethods(options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n this.logger.info('Getting payment methods', options);\n\n try {\n const methods = await getPaymentMethods(this.sdk, options);\n this.logger.debug(`Found ${methods.length} payment methods`);\n return methods;\n } catch (error) {\n this.logger.error('Error getting payment methods', error);\n throw error; // Re-throw as it's already wrapped by getPaymentMethods\n }\n }\n\n // ============================================\n // Checkout Operations\n // ============================================\n\n /**\n * Complete checkout and create order from cart\n *\n * Finalizes the checkout process and converts the cart into an order.\n * Cart must have shipping address, shipping method, and payment session.\n *\n * @param cartId - Cart ID to checkout\n * @returns Created order\n * @throws {ProviderAPIError} If checkout fails\n */\n async completeCheckout(cartId: string): Promise<Order> {\n this.logger.debug('completeCheckout', { cartId });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: POST /store/carts/:id/complete\n const { order } = (await this.sdk.store.cart.complete(cartId)) as any;\n\n if (!order) {\n throw new ProviderAPIError('Checkout completed but no order returned', 'medusa', 500);\n }\n\n this.logger.info('Checkout completed successfully', {\n orderId: order.id,\n displayId: order.display_id,\n });\n\n return transformOrder(order);\n },\n 'completeCheckout',\n { cartId },\n );\n } catch (error: any) {\n this.logger.error('Failed to complete checkout', { cartId, error: error.message });\n throw new ProviderAPIError(\n `Failed to complete checkout: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Get available shipping methods for cart\n *\n * Fetches shipping options based on cart region and shipping address.\n *\n * @param cartId - Cart ID\n * @returns List of shipping methods with prices\n * @throws {ProviderAPIError} If cart not found or region not configured\n */\n async getShippingMethods(cartId: string): Promise<import('@thorprovider/types').ShippingMethod[]> {\n this.logger.info('🚚 [DEBUG] getShippingMethods called', { cartId });\n\n try {\n return await this.withRetry(\n async () => {\n // Get raw cart to access region\n this.logger.info('🚚 [DEBUG] Step 1: Retrieving cart from Medusa...', { cartId });\n const cartResponse = (await this.sdk.store.cart.retrieve(cartId)) as any;\n const { cart } = cartResponse;\n\n // Log raw cart response for debugging\n this.logger.info('🚚 [DEBUG] Step 2: Cart retrieved from backend', {\n cartId,\n hasCart: !!cart,\n cartKeys: cart ? Object.keys(cart) : [],\n regionId: cart?.region_id,\n currencyCode: cart?.currency_code,\n shippingAddress: cart?.shipping_address\n ? {\n country: cart.shipping_address.country_code,\n postal: cart.shipping_address.postal_code,\n }\n : null,\n });\n\n if (!cart) {\n this.logger.error('🚚 [DEBUG] ERROR: Cart not found in response', {\n cartId,\n cartResponse,\n });\n throw new ResourceNotFoundError('Cart', cartId);\n }\n\n if (!cart.region_id) {\n this.logger.error('🚚 [DEBUG] ERROR: Cart has no region_id', {\n cartId,\n cart: {\n id: cart.id,\n region_id: cart.region_id,\n region: cart.region,\n allKeys: Object.keys(cart),\n },\n });\n throw new ProviderAPIError('Cart has no region assigned', 'medusa', 400);\n }\n\n // Fetch shipping options for cart\n // Medusa v2 endpoint: GET /store/shipping-options?cart_id=...\n this.logger.info('🚚 [DEBUG] Step 3: Fetching shipping options from Medusa...', {\n cartId,\n regionId: cart.region_id,\n endpoint: `${this.baseUrl}store/shipping-options?cart_id=${cartId}`,\n note: 'About to fetch shipping options (SDK when available, otherwise HTTP)',\n });\n\n let shippingResponse: any;\n let shipping_options: any;\n\n try {\n const storeAny = this.sdk.store as any;\n\n // Prefer SDK if present (newer SDK versions)\n if (storeAny?.shippingOption?.list) {\n shippingResponse = (await storeAny.shippingOption.list({\n cart_id: cartId,\n })) as any;\n } else {\n // Fallback for SDK versions that don't expose shippingOption typings/APIs\n const baseUrl = this.baseUrl.endsWith('/') ? this.baseUrl : `${this.baseUrl}/`;\n const url = new URL('store/shipping-options', baseUrl);\n url.searchParams.set('cart_id', cartId);\n\n const response = await fetchWithRetry(\n url.toString(),\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'content-type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n shippingResponse = (await response.json()) as any;\n }\n\n shipping_options = shippingResponse.shipping_options;\n } catch (sdkError: any) {\n // Log detailed error from Medusa backend\n this.logger.error(\n '🚚 [DEBUG] ERROR: Medusa SDK threw error when fetching shipping options',\n {\n cartId,\n regionId: cart.region_id,\n errorType: sdkError?.constructor?.name,\n errorMessage: sdkError?.message,\n errorStatus: sdkError?.status,\n errorCode: sdkError?.code,\n errorResponse: sdkError?.response\n ? JSON.stringify(sdkError.response, null, 2)\n : 'N/A',\n errorBody: sdkError?.body ? JSON.stringify(sdkError.body, null, 2) : 'N/A',\n fullError: JSON.stringify(sdkError, Object.getOwnPropertyNames(sdkError), 2),\n },\n );\n throw sdkError;\n }\n\n // Log raw shipping options response\n this.logger.info('🚚 [DEBUG] Step 4: Shipping options received from backend', {\n cartId,\n totalOptions: shipping_options?.length || 0,\n rawResponse: JSON.stringify(shippingResponse, null, 2),\n firstOption: shipping_options?.[0]\n ? {\n id: shipping_options[0].id,\n name: shipping_options[0].name,\n allKeys: Object.keys(shipping_options[0]),\n price_incl_tax: shipping_options[0].price_incl_tax,\n amount: shipping_options[0].amount,\n data: shipping_options[0].data,\n }\n : null,\n });\n\n const methods = shipping_options.map((option: any) => ({\n id: option.id,\n name: option.name,\n price: {\n amount: option.price_incl_tax?.toString() || option.amount?.toString() || '0',\n currencyCode: cart.currency_code?.toUpperCase() || this.currencyCode,\n },\n description: option.data?.description,\n estimatedDays: option.data?.estimated_days || 'N/A',\n }));\n\n // Log transformed methods\n this.logger.info('🚚 [DEBUG] Step 5: Transformed methods for Thor types', {\n cartId,\n count: methods.length,\n methods: JSON.stringify(methods, null, 2),\n });\n\n return methods;\n },\n 'getShippingMethods',\n { cartId },\n );\n } catch (error: any) {\n this.logger.error('🚚 [DEBUG] ERROR: Failed to fetch shipping methods', {\n cartId,\n errorMessage: error.message,\n errorStack: error.stack,\n errorStatus: error.status,\n });\n throw new ProviderAPIError(\n `Failed to fetch shipping methods: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n // ============================================\n // Admin Authentication (SDK-Managed)\n // ============================================\n\n /**\n * Check if admin API is configured\n */\n private get isAdminConfigured(): boolean {\n return !!this.adminApiKey;\n }\n\n /**\n * Ensure admin is configured.\n * Synchronous check — API key auth has no async initialization.\n * @throws ProviderAPIError if admin configuration is missing\n */\n private ensureAdminConfigured(): void {\n if (!this.adminApiKey || !this.sdkAdmin) {\n throw new ProviderAPIError(\n 'Admin API is not configured. Pass adminConfig.apiKey to createProvider().',\n 'medusa',\n 503,\n );\n }\n }\n\n /**\n * Make an authenticated request to the Medusa Admin API via SDK\n * SDK automatically includes Bearer token in all admin requests\n * Awaits auth initialization before executing the operation\n */\n private async makeAdminRequest<T>(\n operation: () => Promise<T>,\n ): Promise<T> {\n // Ensure admin is configured (sync check — no async auth)\n this.ensureAdminConfigured();\n\n try {\n // Wrap with retry logic to handle transient network failures.\n // withRetry uses exponential backoff (300ms → 5s, up to 3 attempts).\n // It retries on: fetch failed, timeout, ECONNREFUSED, ETIMEDOUT, HTTP 429/500/502/503/504.\n // It does NOT retry 401/403 (auth errors) or 404/422 (business errors).\n return await this.withRetry(operation, 'adminRequest');\n } catch (error) {\n // SDK auth errors will be caught here\n // If token expired, SDK automatically refreshes\n // If credentials invalid (401), error propagates\n if (error instanceof Error) {\n this.logger.error('Admin API request failed', {\n error: error.message,\n });\n }\n throw error;\n }\n }\n\n // ============================================\n // Inventory Operations (Admin API)\n // ============================================\n\n /**\n * Fetch stock locations, optionally filtered by sales channel.\n * Returns empty array when admin config is not provided (graceful degradation).\n */\n async getStockLocations(params?: { salesChannelId?: string }): Promise<StockLocation[]> {\n if (!this.isAdminConfigured) {\n return []; // Graceful degradation when admin not configured\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n const { stock_locations } = await this.sdkAdmin!.admin.stockLocation.list({\n ...(params?.salesChannelId && { sales_channel_id: [params.salesChannelId] }),\n });\n\n return (stock_locations ?? []).map(transformStockLocation);\n });\n } catch (error) {\n this.logger.error('Failed to fetch stock locations:', error);\n return [];\n }\n }\n\n /**\n * Check inventory levels for a variant across locations.\n * Returns empty array when admin config is not provided (graceful degradation).\n */\n async checkInventoryLevels(variantId: string, salesChannelId?: string): Promise<InventoryLevel[]> {\n if (!this.isAdminConfigured) {\n return [];\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n // Find inventory item by variant ID\n const { inventory_items } = await this.sdkAdmin!.admin.inventoryItem.list({\n // Filter params may need adjustment based on actual SDK capabilities\n fields: 'id',\n });\n\n if (!inventory_items?.length) {\n return [];\n }\n\n // Find the matching inventory item for this variant\n // Note: SDK filtering might be different - we may need to filter client-side\n const inventoryItem = inventory_items.find((item: any) => item.variant_id === variantId);\n if (!inventoryItem) {\n return [];\n }\n\n // Get levels for this inventory item\n const { inventory_levels } = await this.sdkAdmin!.admin.inventoryItem.listLevels(\n inventoryItem.id,\n { fields: 'id,location_id,stocked_quantity,reserved_quantity' },\n );\n\n const locations = await this.getStockLocations({ salesChannelId });\n const locationMap = new Map(locations.map((l) => [l.id, l.name] as const));\n\n return (inventory_levels ?? []).map((level: any) =>\n transformInventoryLevel(level, locationMap.get(level.location_id) || 'Unknown'),\n );\n });\n } catch (error) {\n this.logger.error('Failed to check inventory levels:', error);\n return [];\n }\n }\n\n /**\n * Validate cart stock availability across all items.\n * Returns all-available when admin config is not provided (graceful degradation).\n */\n async validateCartStock(cartId: string): Promise<StockValidation> {\n if (!this.isAdminConfigured) {\n return { allAvailable: true, unavailableItems: [] };\n }\n\n try {\n const cart = await this.getCart(cartId);\n if (!cart) {\n throw new Error('Cart not found');\n }\n\n const unavailableItems: StockValidation['unavailableItems'] = [];\n\n for (const item of cart.lines) {\n const variantId = item.merchandise.id;\n const levels = await this.checkInventoryLevels(variantId);\n const totalAvailable = levels.reduce((sum, level) => sum + level.availableQuantity, 0);\n\n if (totalAvailable < item.quantity) {\n unavailableItems.push({\n variantId,\n productName: item.merchandise.product.title,\n requestedQuantity: item.quantity,\n availableQuantity: totalAvailable,\n });\n }\n }\n\n return { allAvailable: unavailableItems.length === 0, unavailableItems };\n } catch (error) {\n this.logger.error('Failed to validate cart stock:', error);\n return { allAvailable: false, unavailableItems: [] };\n }\n }\n\n /**\n * Get fulfillment options enriched with stock location data.\n * Not yet implemented — requires fulfillment planning + Admin inventory.\n */\n async getFulfillmentOptions(cartId: string, salesChannelId: string): Promise<FulfillmentOption[]> {\n void cartId;\n void salesChannelId;\n throw new Error(\n 'MedusaProvider.getFulfillmentOptions is not yet implemented. ' +\n 'This method requires Admin API access — implement it HERE in @thorprovider/adapters, ' +\n 'NOT in L5 starters. See docs/architecture/data-flow.md.',\n );\n }\n\n /**\n * Get a map of product IDs → admin status ('published' | 'draft' | etc.)\n * Returns {} when admin config is not provided (graceful degradation).\n */\n async getAdminProductStatuses(options?: { limit?: number }): Promise<Record<string, string>> {\n if (!this.isAdminConfigured) {\n return {};\n }\n\n try {\n const limit = options?.limit ?? 1000;\n\n return await this.makeAdminRequest(async () => {\n const { products } = await this.sdkAdmin!.admin.product.list({\n limit,\n fields: 'id,status',\n });\n\n const map: Record<string, string> = {};\n for (const p of products ?? []) {\n if (p.id && p.status) {\n map[p.id] = p.status;\n }\n }\n return map;\n });\n } catch (error) {\n this.logger.error('Failed to fetch admin product statuses:', error);\n return {};\n }\n }\n\n /**\n * Get the distinct product status values available in Medusa.\n * Derives values from getAdminProductStatuses and caches them for the process lifetime.\n * Returns [] when admin credentials are not configured.\n */\n async getAvailableProductStatuses(): Promise<string[]> {\n if (this._cachedProductStatuses !== null) {\n return this._cachedProductStatuses;\n }\n\n if (!this.isAdminConfigured) {\n return [];\n }\n\n try {\n return await this.makeAdminRequest(async () => {\n const { products } = await this.sdkAdmin!.admin.product.list({\n limit: 1000,\n fields: 'id,status',\n });\n\n const statuses = Array.from(\n new Set((products ?? []).map((p: any) => p.status).filter(Boolean)),\n );\n this._cachedProductStatuses = statuses;\n return statuses;\n });\n } catch (error) {\n this.logger.error('Failed to fetch available product statuses:', error);\n return [];\n }\n }\n\n /**\n * List ALL products from the admin API (including non-published).\n * Returns real backend status values and variant-level price/inventory data.\n * Gracefully degrades to empty result when admin credentials are not configured.\n */\n async getAdminProducts(options?: {\n query?: string;\n limit?: number;\n offset?: number;\n }): Promise<{ products: AdminProduct[]; count: number }> {\n if (!this.isAdminConfigured) {\n return { products: [], count: 0 };\n }\n\n try {\n const limit = options?.limit ?? 1000;\n const offset = options?.offset ?? 0;\n\n return await this.makeAdminRequest(async () => {\n const { products, count } = await this.sdkAdmin!.admin.product.list({\n limit,\n offset,\n q: options?.query,\n fields:\n 'id,handle,title,status,thumbnail,' +\n '+variants,+variants.prices,+variants.inventory_quantity,+variants.sku,' +\n '+variants.options,+variants.options.option',\n });\n\n const transformedProducts: AdminProduct[] = (products ?? []).map((p: any) => ({\n id: p.id,\n handle: p.handle,\n title: p.title,\n status: p.status,\n thumbnail: p.thumbnail ?? undefined,\n variants: (p.variants ?? []).map((v: any) => {\n // Build a readable title: explicit title > options joined > SKU > \"Default\"\n let variantTitle = v.title;\n if (!variantTitle && Array.isArray(v.options) && v.options.length > 0) {\n variantTitle = v.options\n .map((opt: any) => opt.value)\n .filter(Boolean)\n .join(' / ');\n }\n if (!variantTitle) variantTitle = v.sku || 'Default';\n\n return {\n id: v.id,\n title: variantTitle,\n sku: v.sku || undefined,\n quantityAvailable: v.inventory_quantity ?? undefined,\n prices: (v.prices ?? []).map((pr: any) => ({\n amount: pr.amount,\n currencyCode: (pr.currency_code ?? '').toUpperCase(),\n })),\n };\n }),\n }));\n\n return { products: transformedProducts, count: count ?? transformedProducts.length };\n });\n } catch (error) {\n // Re-throw authentication errors (401) — these are not transient failures\n if (error instanceof ProviderAPIError && error.status === 401) {\n throw error;\n }\n\n // Silently degrade for other errors (network, service unavailable, etc.)\n this.logger.error('Failed to fetch admin products:', error);\n return { products: [], count: 0 };\n }\n }\n\n /**\n * Get available countries for a region\n *\n * Returns list of countries that can be used for shipping addresses\n * in the specified region. Results are cached for 5 minutes.\n *\n * @param regionId - Region ID\n * @returns Array of countries with codes and names\n * @throws {ProviderAPIError} If region not found or API error\n *\n * @example\n * ```typescript\n * const countries = await medusa.getRegionCountries('reg_01KHCJQ5YXYRWWCKSTYQ4SCM8V');\n * // [{ code: 'ES', name: 'Spain' }, { code: 'FR', name: 'France' }, ...]\n * ```\n */\n async getRegionCountries(regionId: string): Promise<import('@thorprovider/types').Country[]> {\n this.logger.info('🌍 [DEBUG] getRegionCountries called', { regionId });\n\n // Check cache first\n const cached = this.regionCountriesCache.get(regionId);\n const now = Date.now();\n\n if (cached && cached.expiresAt > now) {\n this.logger.info('🌍 [DEBUG] Returning cached countries', {\n regionId,\n count: cached.countries.length,\n cacheAge:\n Math.round((now - (cached.expiresAt - this.REGION_COUNTRIES_CACHE_TTL)) / 1000) + 's',\n });\n return cached.countries;\n }\n\n try {\n return await this.withRetry(\n async () => {\n this.logger.info('🌍 [DEBUG] Fetching countries from Medusa API...', { regionId });\n\n // Fetch region with countries using Medusa SDK\n const { region } = await this.sdk.store.region.retrieve(regionId, {\n fields:\n '+countries.iso_2,+countries.display_name,+countries.name,+countries.iso_3,+countries.num_code',\n });\n\n if (!region) {\n throw new ResourceNotFoundError('Region', regionId);\n }\n\n this.logger.info('🌍 [DEBUG] Region retrieved', {\n regionId,\n regionName: region.name,\n hasCountries: !!(region as any).countries,\n countriesCount: (region as any).countries?.length || 0,\n });\n\n // Transform to Country type\n const countries: import('@thorprovider/types').Country[] = ((region as any).countries || []).map(\n (c: any) => ({\n code: c.iso_2.toUpperCase(), // Frontend expects uppercase for validation\n name: c.display_name || c.name,\n iso3: c.iso_3,\n numCode: c.num_code,\n }),\n );\n\n // Sort by name for better UX\n countries.sort((a, b) => a.name.localeCompare(b.name));\n\n this.logger.info('🌍 [DEBUG] Countries transformed and sorted', {\n regionId,\n count: countries.length,\n firstThree: countries.slice(0, 3).map((c) => `${c.code}: ${c.name}`),\n });\n\n // Cache the result\n this.regionCountriesCache.set(regionId, {\n countries,\n expiresAt: now + this.REGION_COUNTRIES_CACHE_TTL,\n });\n\n return countries;\n },\n 'getRegionCountries',\n { regionId },\n );\n } catch (error: any) {\n this.logger.error('🌍 [DEBUG] ERROR: Failed to fetch region countries', {\n regionId,\n errorMessage: error.message,\n errorStatus: error.status,\n });\n\n // Provide helpful error messages\n if (error.status === 404) {\n throw new ResourceNotFoundError('Region', regionId);\n }\n\n throw new ProviderAPIError(\n `Failed to fetch countries for region: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Add shipping method to cart\n *\n * Applies a shipping method to the cart and updates totals.\n *\n * @param cartId - Cart ID\n * @param methodId - Shipping method ID (from getShippingMethods)\n * @returns Updated cart with shipping\n * @throws {ProviderAPIError} If method invalid or cart not ready\n */\n async addShippingMethod(cartId: string, methodId: string): Promise<Cart> {\n this.logger.debug('addShippingMethod', { cartId, methodId });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: POST /store/carts/:id/shipping-methods\n const { cart } = await this.sdk.store.cart.addShippingMethod(cartId, {\n option_id: methodId,\n } as any);\n\n this.logger.info('Shipping method added successfully', { cartId, methodId });\n\n void cart;\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\n },\n 'addShippingMethod',\n { cartId, methodId },\n );\n } catch (error: any) {\n this.logger.error('Failed to add shipping method', {\n cartId,\n methodId,\n error: error.message,\n });\n throw new ProviderAPIError(\n `Failed to add shipping method: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Initiate payment session with provider\n *\n * Creates a payment session for the cart with the specified provider.\n *\n * @param cartId - Cart ID\n * @param providerId - Payment provider ID (from getPaymentMethods)\n * @throws {ProviderAPIError} If provider invalid or cart not ready\n */\n async initiatePaymentSession(cartId: string, providerId: string): Promise<void> {\n this.logger.info('💳 [DEBUG] initiatePaymentSession called', { cartId, providerId });\n\n try {\n await this.withRetry(\n async () => {\n // Get RAW cart object from Medusa SDK (not transformed)\n // CHANGE 1: Add payment_collection fields to query\n this.logger.info(\n '💳 [DEBUG] Step 1: Retrieving RAW cart from Medusa for payment session...',\n { cartId },\n );\n const { cart: rawCart } = await this.sdk.store.cart.retrieve(cartId, {\n fields:\n '+shipping_methods,+shipping_address,+email,+region_id,+total,+items,+payment_collection,+payment_collection.payment_sessions,+billing_address',\n });\n\n this.logger.info('💳 [DEBUG] Step 2: RAW cart retrieved, checking state...', {\n cartId: rawCart.id,\n hasShippingMethod: !!rawCart.shipping_methods?.length,\n shippingMethodIds: rawCart.shipping_methods?.map((sm: any) => sm.id) || [],\n hasShippingAddress: !!rawCart.shipping_address,\n shippingAddressCity: rawCart.shipping_address?.city || 'N/A',\n hasEmail: !!rawCart.email,\n email: rawCart.email || 'N/A',\n hasBillingAddress: !!rawCart.billing_address,\n hasPaymentCollection: !!rawCart.payment_collection,\n existingSessionsCount: rawCart.payment_collection?.payment_sessions?.length || 0,\n regionId: rawCart.region_id,\n total: rawCart.total,\n itemCount: rawCart.items?.length || 0,\n });\n\n // 🛡️ VALIDATION: Cart must have items to create payment session\n if (!rawCart.items || rawCart.items.length === 0) {\n this.logger.error('💳 [DEBUG] ERROR: Cannot create payment session for empty cart', {\n cartId,\n itemCount: 0,\n reason: 'Cart has no items',\n });\n throw new ProviderAPIError(\n 'Cannot create payment session: cart is empty. Please add items to your cart before checking out.',\n 'medusa',\n 400,\n );\n }\n\n // 🛡️ VALIDATION: Required fields\n if (!rawCart.shipping_address) {\n this.logger.error('💳 [DEBUG] ERROR: Shipping address required', { cartId });\n throw new ProviderAPIError(\n 'Shipping address is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n if (!rawCart.shipping_methods?.length) {\n this.logger.error('💳 [DEBUG] ERROR: Shipping method required', { cartId });\n throw new ProviderAPIError(\n 'Shipping method is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n if (!rawCart.email) {\n this.logger.error('💳 [DEBUG] ERROR: Email required', { cartId });\n throw new ProviderAPIError(\n 'Email is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n // CHANGE 2: Validate billing address and warn if missing\n if (!rawCart.billing_address) {\n this.logger.warn(\n '💳 [DEBUG] WARNING: Billing address not set, payment provider may require it',\n {\n cartId: rawCart.id,\n shippingAddress: rawCart.shipping_address,\n },\n );\n }\n\n // CHANGE 3: Check for existing payment sessions (idempotency)\n // Note: payment_collection is created automatically by Medusa when calling initiatePaymentSession\n // So we don't need to validate its existence - just check if sessions already exist\n const existingSessions = rawCart.payment_collection?.payment_sessions || [];\n\n if (existingSessions.length > 0) {\n this.logger.info('💳 [DEBUG] Payment session already exists, skipping creation', {\n cartId: rawCart.id,\n sessionCount: existingSessions.length,\n sessionIds: existingSessions.map((s: any) => s.id),\n });\n\n // Return early - session already exists\n return;\n }\n\n this.logger.info('💳 [DEBUG] Step 2.5: No existing payment sessions, will create new one', {\n cartId: rawCart.id,\n hasPaymentCollection: !!rawCart.payment_collection,\n providerId,\n });\n\n // Medusa v2 SDK: sdk.store.payment.initiatePaymentSession(cart, options)\n this.logger.info('💳 [DEBUG] Step 3: Calling Medusa SDK initiatePaymentSession...', {\n cartId,\n providerId,\n endpoint: `${this.baseUrl}store/payment-collections`,\n note: 'About to call SDK method',\n });\n\n // VALIDATION: Ensure provider_id is a valid backend ID\n // Prevent sending normalized types like 'card', 'wallet', 'cash_on_delivery'\n this.logger.info('💳 [DEBUG] Step 2.5: Validating provider ID...', {\n providerId,\n });\n\n try {\n validatePaymentId(providerId);\n this.logger.info('💳 [DEBUG] Provider ID validation passed', { providerId });\n } catch (validationError: any) {\n this.logger.error('💳 [DEBUG] ERROR: Invalid provider ID detected', {\n providerId,\n error: validationError.message,\n hint: 'Use getBackendProviderId(paymentMethod) to extract correct ID',\n });\n throw new ProviderAPIError(\n validationError.message,\n 'medusa',\n 400\n );\n }\n\n let paymentResponse: any;\n try {\n paymentResponse = await this.sdk.store.payment.initiatePaymentSession(rawCart as any, {\n provider_id: providerId,\n });\n\n this.logger.info('💳 [DEBUG] Step 4: Payment session response received', {\n cartId,\n providerId,\n responseKeys: paymentResponse ? Object.keys(paymentResponse) : [],\n response: JSON.stringify(paymentResponse, null, 2),\n });\n } catch (sdkError: any) {\n // CHANGE 4: Enhanced error context\n this.logger.error(\n '💳 [DEBUG] ERROR: Medusa SDK threw error when initiating payment session',\n {\n cartId,\n providerId,\n errorType: sdkError?.constructor?.name,\n errorMessage: sdkError?.message,\n errorStatus: sdkError?.status,\n errorCode: sdkError?.code,\n errorResponse: sdkError?.response\n ? JSON.stringify(sdkError.response, null, 2)\n : 'N/A',\n errorBody: sdkError?.body ? JSON.stringify(sdkError.body, null, 2) : 'N/A',\n fullError: JSON.stringify(sdkError, Object.getOwnPropertyNames(sdkError), 2),\n // Include cart state in error for debugging\n cartState: {\n hasShippingMethod: !!rawCart.shipping_methods?.length,\n hasShippingAddress: !!rawCart.shipping_address,\n hasBillingAddress: !!rawCart.billing_address,\n hasEmail: !!rawCart.email,\n total: rawCart.total,\n itemCount: rawCart.items?.length || 0,\n },\n },\n );\n throw sdkError;\n }\n\n this.logger.info('💳 [DEBUG] Payment session initiated successfully', {\n cartId,\n providerId,\n });\n },\n 'initiatePaymentSession',\n { cartId, providerId },\n );\n } catch (error: any) {\n this.logger.error('💳 [DEBUG] ERROR: Failed to initiate payment session', {\n cartId,\n providerId,\n errorMessage: error.message,\n errorStack: error.stack,\n errorStatus: error.status,\n });\n throw new ProviderAPIError(\n `Failed to initiate payment session: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Apply discount code to cart\n *\n * Validates and applies a discount/promo code to the cart.\n *\n * @param cartId - Cart ID\n * @param code - Discount code\n * @returns Updated cart with discount\n * @throws {ProviderAPIError} If code invalid or expired\n */\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n this.logger.debug('applyDiscountCode', { cartId, code });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: POST /store/carts/:id/promotions\n const response = await fetch(`${this.baseUrl}/store/carts/${cartId}/promotions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-publishable-api-key': this.publishableKey || '',\n },\n body: JSON.stringify({\n promo_codes: [code],\n }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to apply discount code');\n }\n\n const { cart: medusaCart } = await response.json();\n\n this.logger.info('Discount code applied successfully', { cartId, code });\n\n void medusaCart;\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\n },\n 'applyDiscountCode',\n { cartId, code },\n );\n } catch (error: any) {\n this.logger.error('Failed to apply discount code', { cartId, code, error: error.message });\n throw new ProviderAPIError(\n `Failed to apply discount code: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Remove discount code from cart\n *\n * Removes a previously applied discount code.\n *\n * @param cartId - Cart ID\n * @param code - Discount code to remove\n * @returns Updated cart without discount\n * @throws {ProviderAPIError} If cart not found\n */\n async removeDiscountCode(cartId: string, code: string): Promise<Cart> {\n this.logger.debug('removeDiscountCode', { cartId, code });\n\n try {\n return await this.withRetry(\n async () => {\n // Medusa v2: DELETE /store/carts/:id/promotions\n const response = await fetch(`${this.baseUrl}/store/carts/${cartId}/promotions`, {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n 'x-publishable-api-key': this.publishableKey || '',\n },\n body: JSON.stringify({\n promo_codes: [code],\n }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to remove discount code');\n }\n\n const { cart: medusaCart } = await response.json();\n\n this.logger.info('Discount code removed successfully', { cartId, code });\n\n void medusaCart;\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\n },\n 'removeDiscountCode',\n { cartId, code },\n );\n } catch (error: any) {\n this.logger.error('Failed to remove discount code', { cartId, code, error: error.message });\n throw new ProviderAPIError(\n `Failed to remove discount code: ${error.message}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Update cart shipping address\n * @param cartId - Cart ID\n * @param address - Shipping address details\n * @returns Updated cart\n *\n * **CRITICAL**: Must be called BEFORE initiatePaymentSession\n * Medusa requires shipping_address on cart before creating payment session\n */\n async updateShippingAddress(\n cartId: string,\n address: {\n email: string;\n firstName: string;\n lastName: string;\n address1: string;\n address2?: string;\n company?: string;\n city: string;\n province: string;\n postalCode: string;\n countryCode: string;\n phone: string;\n },\n ): Promise<void> {\n this.logger.info('📫 [DEBUG] updateShippingAddress called', {\n cartId,\n email: address.email,\n city: address.city,\n countryCode: address.countryCode,\n });\n\n try {\n // Update cart with shipping address using Medusa SDK\n const { cart: rawCart } = await this.sdk.store.cart.update(cartId, {\n email: address.email,\n shipping_address: {\n first_name: address.firstName,\n last_name: address.lastName,\n address_1: address.address1,\n address_2: address.address2 || '',\n company: address.company || '',\n city: address.city,\n province: address.province,\n postal_code: address.postalCode,\n country_code: address.countryCode.toLowerCase(), // Medusa expects lowercase\n phone: address.phone,\n },\n });\n\n this.logger.info('📫 [DEBUG] Shipping address updated successfully', {\n cartId,\n hasEmail: !!rawCart.email,\n hasShippingAddress: !!rawCart.shipping_address,\n });\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n const status = (error as any)?.status || (error as any)?.statusCode;\n\n this.logger.error('Failed to update shipping address', {\n cartId,\n error: errorMessage,\n status,\n });\n\n // Provide user-friendly error messages\n let userMessage = errorMessage;\n\n if (errorMessage.includes('is not within region')) {\n // Region/Country mismatch\n userMessage = `The selected country is not available for shipping in your current region. Please select a different country or change your region.`;\n } else if (status === 400) {\n userMessage = `Invalid shipping address: ${errorMessage}`;\n }\n\n throw new ProviderAPIError(userMessage, 'medusa', status);\n }\n }\n\n /**\n * Update cart billing address\n * @param cartId - Cart ID\n * @param address - Billing address details\n * @returns Updated cart\n *\n * **Usage**: Call when billing address differs from shipping address\n * Recommended to call BEFORE initiatePaymentSession\n */\n async updateBillingAddress(\n cartId: string,\n address: {\n firstName: string;\n lastName: string;\n address1: string;\n address2?: string;\n company?: string;\n city: string;\n province: string;\n postalCode: string;\n countryCode: string;\n phone?: string;\n },\n ): Promise<Cart> {\n this.logger.info('📫 [DEBUG] updateBillingAddress called', {\n cartId,\n city: address.city,\n countryCode: address.countryCode,\n });\n\n try {\n // Update cart with billing address using Medusa SDK\n const { cart: rawCart } = await this.sdk.store.cart.update(cartId, {\n billing_address: {\n first_name: address.firstName,\n last_name: address.lastName,\n address_1: address.address1,\n address_2: address.address2 || '',\n company: address.company || '',\n city: address.city,\n province: address.province,\n postal_code: address.postalCode,\n country_code: address.countryCode.toLowerCase(), // Medusa expects lowercase\n phone: address.phone || '',\n },\n });\n\n this.logger.info('📫 [DEBUG] Billing address updated successfully', {\n cartId,\n hasBillingAddress: !!rawCart.billing_address,\n });\n\n return transformCart(rawCart);\n } catch (error: unknown) {\n const errorMessage = extractErrorMessage(error);\n const status = (error as any)?.status || (error as any)?.statusCode;\n\n this.logger.error('Failed to update billing address', {\n cartId,\n error: errorMessage,\n status,\n });\n\n // Provide user-friendly error messages\n let userMessage = errorMessage;\n\n if (errorMessage.includes('is not within region')) {\n userMessage = `The billing address country is not available in your current region. Please select a different country or change your region.`;\n } else if (status === 400) {\n userMessage = `Invalid billing address: ${errorMessage}`;\n }\n\n throw new ProviderAPIError(userMessage, 'medusa', status);\n }\n }\n\n // ============================================\n // Storefront / Multi-Tenant Operations\n // ============================================\n\n /**\n * Get the current storefront/sales channel context.\n *\n * Validates that NEXT_PUBLIC_SALES_CHANNEL_ID is set and that the\n * corresponding sales channel exists in the Medusa backend.\n * Results are cached for 60 seconds.\n *\n * @returns StorefrontContext for the current storefront\n * @throws {StorefrontConfigError} if NEXT_PUBLIC_SALES_CHANNEL_ID is missing or invalid\n * @throws {ProviderAPIError} if the backend request fails\n */\n async getStorefrontContext(): Promise<StorefrontContext> {\n // Check cache first\n if (\n this.storefrontContextCache &&\n Date.now() < this.storefrontContextCache.expiresAt\n ) {\n return this.storefrontContextCache.context;\n }\n\n const channelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (!channelId) {\n throw new StorefrontConfigError(\n 'Medusa requires NEXT_PUBLIC_SALES_CHANNEL_ID to be configured. ' +\n 'Each storefront must be linked to a sales channel. ' +\n 'Set this in your .env file or environment variables.',\n 'medusa',\n 'NEXT_PUBLIC_SALES_CHANNEL_ID',\n );\n }\n\n try {\n // In Medusa v2, we build context from the channel ID.\n // The channel is validated implicitly when used in API calls (product filtering, cart creation).\n // If the channel is invalid, those operations will fail with clear errors.\n \n const context: StorefrontContext = {\n id: channelId,\n name: channelId, // Use ID as fallback name\n platformType: 'medusa',\n requiresProductScoping: true,\n currencyCode: this.currencyCode,\n metadata: {\n // Store channel ID for use in API requests\n channelId,\n },\n };\n\n // Cache for 60 seconds\n this.storefrontContextCache = {\n context,\n expiresAt: Date.now() + this.STOREFRONT_CONTEXT_CACHE_TTL,\n };\n\n this.logger.info('Storefront context initialized', {\n id: context.id,\n channelId,\n });\n\n return context;\n } catch (error) {\n if (error instanceof StorefrontConfigError) throw error;\n\n const errorMessage = extractErrorMessage(error);\n throw new ProviderAPIError(\n `Failed to initialize storefront context: ${errorMessage}`,\n 'medusa',\n (error as any)?.status ?? 500,\n );\n }\n }\n\n /**\n * Medusa always requires storefront configuration for multi-tenant support.\n */\n isStorefrontRequired(): boolean {\n return true;\n }\n\n // ============================================\n // Thor Plugin — Storefront Configuration\n // ============================================\n\n /** In-memory cache for storefront config (60s TTL) */\n private _storefrontConfigCache: {\n config: StorefrontConfig | null;\n expiresAt: number;\n } | null = null;\n\n /** In-memory cache for designer config (60s TTL) */\n private _designerConfigCache: {\n result: { version: string; config: DesignerConfig } | null;\n expiresAt: number;\n } | null = null;\n\n /** Cache TTL for Thor plugin configs (60 seconds) */\n private readonly THOR_CONFIG_CACHE_TTL = 60 * 1000;\n\n /**\n * Get per-channel storefront configuration from Thor Commerce plugin.\n * Calls `GET /store/thor/config`.\n *\n * @returns StorefrontConfig or null if plugin is not installed / config not set\n */\n async getStorefrontConfig(): Promise<StorefrontConfig | null> {\n // Check cache\n if (this._storefrontConfigCache && Date.now() < this._storefrontConfigCache.expiresAt) {\n return this._storefrontConfigCache.config;\n }\n\n try {\n const url = `${this.baseUrl}/store/thor/config`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (response.status === 404) {\n this._storefrontConfigCache = { config: null, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n return null;\n }\n\n if (!response.ok) {\n this.logger.warn('[StorefrontConfig] Non-OK response', { status: response.status });\n return null;\n }\n\n const data = await response.json();\n const config = transformStorefrontConfig(data.storefront_config ?? data);\n\n this._storefrontConfigCache = { config, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n this.logger.debug('[StorefrontConfig] Loaded from backend', { id: config.id });\n return config;\n } catch (error) {\n this.logger.warn('[StorefrontConfig] Failed to fetch', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n }\n\n /**\n * Get active Site Designer configuration from Thor Commerce plugin.\n * Calls `GET /store/thor/site-config`.\n *\n * @returns Versioned DesignerConfig or null if plugin is not installed / config not set\n */\n async getDesignerConfig(): Promise<{ version: string; config: DesignerConfig } | null> {\n // Check cache\n if (this._designerConfigCache && Date.now() < this._designerConfigCache.expiresAt) {\n return this._designerConfigCache.result;\n }\n\n try {\n const url = `${this.baseUrl}/store/thor/site-config`;\n const response = await fetchWithRetry(\n url,\n {\n method: 'GET',\n headers: {\n 'x-publishable-api-key': this.publishableKey,\n 'Content-Type': 'application/json',\n },\n },\n this.retryConfig,\n );\n\n if (response.status === 404) {\n this._designerConfigCache = { result: null, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n return null;\n }\n\n if (!response.ok) {\n this.logger.warn('[DesignerConfig] Non-OK response', { status: response.status });\n return null;\n }\n\n const data = await response.json();\n const result = {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n };\n\n this._designerConfigCache = { result, expiresAt: Date.now() + this.THOR_CONFIG_CACHE_TTL };\n this.logger.debug('[DesignerConfig] Loaded from backend', { version: result.version });\n return result;\n } catch (error) {\n this.logger.warn('[DesignerConfig] Failed to fetch', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n }\n\n // ============================================\n // Thor Plugin — Admin Site Designer\n // ============================================\n\n /**\n * Get admin Site Designer config + history for a sales channel.\n * Calls `GET /admin/thor/site-config/:salesChannelId`.\n */\n async getAdminDesignerConfig(salesChannelId: string): Promise<{\n version: string;\n config: DesignerConfig;\n history?: DesignerHistoryEntry[];\n } | null> {\n return this.makeAdminRequest(async () => {\n const path = `/admin/thor/site-config/${encodeURIComponent(salesChannelId)}`;\n let data: any;\n try {\n data = await this.sdk.client.fetch<any>(path, { method: 'GET' });\n } catch (error: any) {\n if (error?.status === 404) return null;\n throw new ProviderAPIError(\n `Failed to fetch admin designer config: ${error?.message ?? error?.status}`,\n 'medusa',\n error?.status,\n );\n }\n return {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n history: data.history as DesignerHistoryEntry[] | undefined,\n };\n });\n }\n\n /**\n * Update the Site Designer config for a sales channel.\n * Calls `PUT /admin/thor/site-config/:salesChannelId`.\n */\n async updateAdminDesignerConfig(salesChannelId: string, config: DesignerConfig): Promise<{\n version: string;\n config: DesignerConfig;\n }> {\n return this.makeAdminRequest(async () => {\n const path = `/admin/thor/site-config/${encodeURIComponent(salesChannelId)}`;\n let data: any;\n try {\n data = await this.sdk.client.fetch<any>(path, {\n method: 'PUT',\n body: JSON.stringify({ config }),\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to update admin designer config: ${error?.message ?? error?.status}`,\n 'medusa',\n error?.status,\n );\n }\n return {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n };\n });\n }\n\n /**\n * Restore a previous Site Designer config version.\n * Calls `POST /admin/thor/site-config/:salesChannelId/restore/:version`.\n */\n async restoreAdminDesignerConfig(salesChannelId: string, version: string): Promise<{\n version: string;\n config: DesignerConfig;\n }> {\n return this.makeAdminRequest(async () => {\n const path = `/admin/thor/site-config/${encodeURIComponent(salesChannelId)}/restore/${encodeURIComponent(version)}`;\n let data: any;\n try {\n data = await this.sdk.client.fetch<any>(path, { method: 'POST' });\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to restore admin designer config: ${error?.message ?? error?.status}`,\n 'medusa',\n error?.status,\n );\n }\n return {\n version: data.version ?? '',\n config: data.config as DesignerConfig,\n };\n });\n }\n}\n","/**\n * @fileoverview Medusa Authentication Provider\n * @module @thorprovider/adapters/providers/medusa/auth\n * \n * Implementation of AuthProvider for Medusa.js v2\n * Supports JWT and session-based authentication\n */\n\nimport Medusa from '@medusajs/js-sdk';\nimport type {\n AuthProvider,\n AuthConfig,\n LoginCredentials,\n RegisterData,\n AuthResponse,\n Customer,\n Address,\n UpdateCustomerData,\n CreateAddressData,\n PasswordResetRequest,\n PasswordResetConfirm,\n} from '@thorprovider/types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\nimport type { Logger } from '../../core/logger';\nimport { transformCustomer, transformAddress } from './transforms';\n\n/**\n * Storage manager for authentication tokens\n */\nclass AuthStorageManager {\n private storage: AuthConfig['customStorage'] | null = null;\n private storageType: AuthConfig['storage'];\n private tokenKey = 'thor_auth_token';\n \n constructor(config: AuthConfig) {\n this.storageType = config.storage;\n this.storage = config.customStorage ?? null;\n }\n \n async getToken(): Promise<string | null> {\n if (this.storage) {\n return this.storage.getItem(this.tokenKey);\n }\n \n if (typeof window === 'undefined') {\n // Server-side: no storage available\n return null;\n }\n \n switch (this.storageType) {\n case 'localStorage':\n return window.localStorage.getItem(this.tokenKey);\n case 'sessionStorage':\n return window.sessionStorage.getItem(this.tokenKey);\n case 'cookie':\n // Cookies are handled automatically by fetch, just return null\n return null;\n case 'memory':\n return null;\n default:\n return null;\n }\n }\n \n async setToken(token: string): Promise<void> {\n if (this.storage) {\n await this.storage.setItem(this.tokenKey, token);\n return;\n }\n \n if (typeof window === 'undefined') {\n return;\n }\n \n switch (this.storageType) {\n case 'localStorage':\n window.localStorage.setItem(this.tokenKey, token);\n break;\n case 'sessionStorage':\n window.sessionStorage.setItem(this.tokenKey, token);\n break;\n case 'cookie':\n case 'memory':\n // No action needed for cookie (handled by SDK) or memory\n break;\n }\n }\n \n async removeToken(): Promise<void> {\n if (this.storage) {\n await this.storage.removeItem(this.tokenKey);\n return;\n }\n \n if (typeof window === 'undefined') {\n return;\n }\n \n switch (this.storageType) {\n case 'localStorage':\n window.localStorage.removeItem(this.tokenKey);\n break;\n case 'sessionStorage':\n window.sessionStorage.removeItem(this.tokenKey);\n break;\n case 'cookie':\n case 'memory':\n // No action needed\n break;\n }\n }\n}\n\n/**\n * Medusa authentication provider implementation\n */\nexport class MedusaAuthProvider implements AuthProvider {\n private sdk: Medusa;\n private logger: ReturnType<typeof createLogger>;\n private authConfig: AuthConfig;\n private storageManager: AuthStorageManager;\n \n constructor(sdk: Medusa, authConfig: AuthConfig, debug = false) {\n this.sdk = sdk;\n this.authConfig = authConfig;\n this.logger = createLogger('MedusaAuthProvider', debug);\n this.storageManager = new AuthStorageManager(authConfig);\n \n this.logger.info('Medusa Auth Provider initialized', {\n method: authConfig.method,\n storage: authConfig.storage,\n });\n }\n \n // ========================================\n // Authentication Methods\n // ========================================\n \n async login(credentials: LoginCredentials): Promise<AuthResponse> {\n this.logger.debug('login', { email: credentials.email });\n\n try {\n // Step 1: Authenticate with Medusa\n const loginResult = await this.sdk.auth.login('customer', 'emailpass', {\n email: credentials.email,\n password: credentials.password,\n });\n\n // Check if login requires additional actions (OAuth or email verification)\n if (typeof loginResult !== 'string') {\n // v2.16.0: email verification required\n if ('verification_required' in loginResult && loginResult.verification_required) {\n this.logger.warn('Authentication requires email verification', loginResult);\n return {\n requiresAction: true,\n token: loginResult.token,\n };\n }\n\n // OAuth redirect flow\n if ('location' in loginResult) {\n this.logger.warn('Authentication requires additional actions', loginResult);\n return {\n requiresAction: true,\n redirectUrl: loginResult.location,\n };\n }\n\n throw new Error('Unexpected login result type');\n }\n\n const token = loginResult;\n\n // Step 2: Store token based on auth method\n if (this.authConfig.method === 'jwt') {\n await this.storageManager.setToken(token);\n }\n // Note: For session-based auth, the SDK automatically handles cookies\n // when auth.login() is called with auth.type='session' in SDK config\n\n // Step 3: Fetch customer data\n const customer = await this.getCurrentCustomer();\n\n this.logger.info('Login successful', { customerId: customer?.id });\n\n return {\n token: this.authConfig.method === 'jwt' ? token : undefined,\n customer: customer ?? undefined,\n };\n } catch (error: any) {\n this.logger.error('Login failed', error);\n throw new ProviderAPIError(\n `Authentication failed: ${error.message}`,\n 'LOGIN_FAILED',\n error\n );\n }\n }\n \n async register(data: RegisterData): Promise<AuthResponse> {\n this.logger.debug('register', { email: data.email });\n\n try {\n // Step 1: Register auth identity with Medusa\n // v2.16.0: register no longer accepts returnVerification option.\n // The SDK auto-stores the registration JWT token for subsequent requests.\n await this.sdk.auth.register('customer', 'emailpass', {\n email: data.email,\n password: data.password,\n });\n\n // Step 2: Create customer profile\n // The registration token is automatically included in the header by the SDK.\n const { customer } = await this.sdk.store.customer.create({\n email: data.email,\n first_name: data.first_name,\n last_name: data.last_name,\n phone: data.phone,\n });\n\n // Step 3: Login to obtain the actual session/token\n // v2.16.0: verification status is now returned by login, not register.\n const loginResult = await this.sdk.auth.login('customer', 'emailpass', {\n email: data.email,\n password: data.password,\n });\n\n if (typeof loginResult !== 'string') {\n // v2.16.0: email verification required before full login\n if ('verification_required' in loginResult && loginResult.verification_required) {\n this.logger.warn('Registration requires email verification', loginResult);\n return {\n requiresAction: true,\n token: loginResult.token,\n };\n }\n\n // OAuth redirect flow\n if ('location' in loginResult) {\n this.logger.warn('Registration requires additional actions', loginResult);\n return {\n requiresAction: true,\n redirectUrl: loginResult.location,\n };\n }\n\n throw new Error('Unexpected login result after registration');\n }\n\n const token = loginResult;\n\n // Step 4: Store actual auth token based on auth method\n if (this.authConfig.method === 'jwt') {\n await this.storageManager.setToken(token);\n }\n // Note: For session-based auth, the SDK automatically handles cookies\n\n this.logger.info('Registration successful', { customerId: customer.id });\n\n return {\n token: this.authConfig.method === 'jwt' ? token : undefined,\n customer: transformCustomer(customer, customer.email),\n };\n } catch (error: any) {\n this.logger.error('Registration failed', error);\n throw new ProviderAPIError(\n `Registration failed: ${error.message}`,\n 'REGISTRATION_FAILED',\n error\n );\n }\n }\n \n async logout(): Promise<void> {\n this.logger.debug('logout');\n \n try {\n await this.storageManager.removeToken();\n \n // For session auth, also call logout endpoint\n if (this.authConfig.method === 'session') {\n await this.sdk.auth.logout();\n }\n \n this.logger.info('Logout successful');\n } catch (error: any) {\n this.logger.error('Logout failed', error);\n // Don't throw error on logout failure, just log it\n }\n }\n \n // ========================================\n // Password Management\n // ========================================\n \n async requestPasswordReset(email: string): Promise<void> {\n this.logger.debug('requestPasswordReset', { email });\n \n try {\n await this.sdk.auth.resetPassword('customer', 'emailpass', {\n identifier: email,\n });\n \n this.logger.info('Password reset email sent', { email });\n } catch (error: any) {\n this.logger.error('Password reset request failed', error);\n throw new ProviderAPIError(\n `Password reset request failed: ${error.message}`,\n 'PASSWORD_RESET_FAILED',\n error\n );\n }\n }\n \n async resetPassword(\n token: string,\n password: string,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n this.logger.debug('resetPassword', { hasMetadata: !!metadata });\n \n // Medusa requires email in the request body\n // Extract from metadata or decode from token\n const email = metadata?.email as string | undefined;\n \n if (!email) {\n throw new ProviderAPIError(\n 'Email is required in metadata for Medusa password reset',\n 'MEDUSA_AUTH_PROVIDER',\n 400\n );\n }\n \n try {\n // Medusa v2.6+ API: email + password in body, token as 3rd param\n await this.sdk.auth.updateProvider('customer', 'emailpass', {\n email,\n password,\n }, token);\n \n this.logger.info('Password reset successful');\n } catch (error: any) {\n this.logger.error('Password reset failed', error);\n throw new ProviderAPIError(\n `Password reset failed: ${error.message}`,\n 'PASSWORD_RESET_CONFIRM_FAILED',\n error\n );\n }\n }\n \n // ========================================\n // Session Management\n // ========================================\n \n async getCurrentCustomer(): Promise<Customer | null> {\n this.logger.debug('getCurrentCustomer');\n \n try {\n const { customer } = await this.sdk.store.customer.retrieve();\n \n if (!customer) {\n return null;\n }\n \n return transformCustomer(customer, customer.email);\n } catch (error: any) {\n this.logger.debug('No authenticated customer');\n return null;\n }\n }\n \n async updateCustomer(data: UpdateCustomerData): Promise<Customer> {\n this.logger.debug('updateCustomer');\n \n try {\n const updateData = { ...data };\n if (updateData.phone === null) {\n delete updateData.phone; // Medusa doesn't accept null, only undefined\n }\n const { customer } = await this.sdk.store.customer.update(updateData as any);\n \n return transformCustomer(customer, customer.email);\n } catch (error: any) {\n this.logger.error('Update customer failed', error);\n throw new ProviderAPIError(\n `Failed to update customer: ${error.message}`,\n 'UPDATE_CUSTOMER_FAILED',\n error\n );\n }\n }\n \n async isAuthenticated(): Promise<boolean> {\n const customer = await this.getCurrentCustomer();\n return customer !== null;\n }\n \n getAuthToken(): string | null {\n // For JWT auth, return stored token\n if (this.authConfig.method === 'jwt') {\n // This is sync, so we can't use async storage\n // Return null and rely on storage manager\n return null;\n }\n \n // For session auth, return null (cookies are handled automatically)\n return null;\n }\n \n // ========================================\n // Address Management\n // ========================================\n \n async getAddresses(): Promise<Address[]> {\n this.logger.debug('getAddresses');\n try {\n const { addresses } = await this.sdk.store.customer.listAddress();\n return addresses.map((address: any) => transformAddress(address));\n } catch (error: any) {\n this.logger.error('Get addresses failed', error);\n throw new ProviderAPIError(\n `Failed to get addresses: ${error.message}`,\n 'GET_ADDRESSES_FAILED',\n error\n );\n }\n }\n \n async createAddress(data: CreateAddressData): Promise<Address> {\n this.logger.debug('createAddress');\n \n try {\n // Transform camelCase to snake_case for Medusa API\n const medusaData = {\n first_name: data.firstName,\n last_name: data.lastName,\n company: data.company,\n address_1: data.address1,\n address_2: data.address2,\n city: data.city,\n province: data.province,\n postal_code: data.postalCode,\n country_code: data.countryCode,\n phone: data.phone,\n metadata: data.metadata,\n };\n \n const { customer } = await this.sdk.store.customer.createAddress(medusaData);\n \n // Get the most recent address (last one in array)\n const addresses = customer.addresses || [];\n const address = addresses[addresses.length - 1];\n \n if (!address) {\n throw new Error('No address returned from createAddress');\n }\n \n return transformAddress(address);\n } catch (error: any) {\n this.logger.error('Create address failed', error);\n throw new ProviderAPIError(\n `Failed to create address: ${error.message}`,\n 'CREATE_ADDRESS_FAILED',\n error\n );\n }\n }\n \n async updateAddress(\n addressId: string,\n data: Partial<CreateAddressData>\n ): Promise<Address> {\n this.logger.debug('updateAddress', { addressId });\n \n try {\n // Transform camelCase to snake_case for Medusa API (partial)\n const medusaData: any = {};\n if (data.firstName !== undefined) medusaData.first_name = data.firstName;\n if (data.lastName !== undefined) medusaData.last_name = data.lastName;\n if (data.company !== undefined) medusaData.company = data.company;\n if (data.address1 !== undefined) medusaData.address_1 = data.address1;\n if (data.address2 !== undefined) medusaData.address_2 = data.address2;\n if (data.city !== undefined) medusaData.city = data.city;\n if (data.province !== undefined) medusaData.province = data.province;\n if (data.postalCode !== undefined) medusaData.postal_code = data.postalCode;\n if (data.countryCode !== undefined) medusaData.country_code = data.countryCode;\n if (data.phone !== undefined) medusaData.phone = data.phone;\n if (data.metadata !== undefined) medusaData.metadata = data.metadata;\n \n const { customer } = await this.sdk.store.customer.updateAddress(addressId, medusaData);\n \n // Find the updated address by ID\n const addresses = customer.addresses || [];\n const address = addresses.find((addr: any) => addr.id === addressId);\n \n if (!address) {\n throw new Error(`Address ${addressId} not found after update`);\n }\n \n return transformAddress(address);\n } catch (error: any) {\n this.logger.error('Update address failed', error);\n throw new ProviderAPIError(\n `Failed to update address: ${error.message}`,\n 'UPDATE_ADDRESS_FAILED',\n error\n );\n }\n }\n \n async deleteAddress(addressId: string): Promise<void> {\n this.logger.debug('deleteAddress', { addressId });\n \n try {\n await this.sdk.store.customer.deleteAddress(addressId);\n this.logger.info('Address deleted', { addressId });\n } catch (error: any) {\n this.logger.error('Delete address failed', error);\n throw new ProviderAPIError(\n `Failed to delete address: ${error.message}`,\n 'DELETE_ADDRESS_FAILED',\n error\n );\n }\n }\n\n async deleteCustomerAccount(): Promise<void> {\n this.logger.debug('deleteCustomerAccount');\n \n // TODO: Implement when custom Medusa backend endpoint is ready\n // DELETE /store/customers/me\n throw new ProviderAPIError(\n 'Delete customer account is not yet implemented. Requires custom Medusa backend endpoint.',\n 'NOT_IMPLEMENTED',\n undefined\n );\n }\n}\n","/**\n * @thorprovider/adapters v2.0\n * Medusa Payment Provider Implementation\n * \n * Transforms Medusa payment providers to Thor's unified PaymentMethod format.\n * Handles region-specific payment provider queries.\n */\n\nimport type Medusa from '@medusajs/js-sdk';\nimport type { HttpTypes } from '@medusajs/types';\nimport type { \n PaymentMethod, \n PaymentMethodsOptions, \n PaymentMethodType \n} from '@thorprovider/types';\nimport { ProviderAPIError } from '../../core/errors';\n\n/**\n * Map of Medusa provider names to display names\n */\nconst PROVIDER_DISPLAY_NAMES: Record<string, string> = {\n stripe: 'Stripe',\n paypal: 'PayPal',\n system: 'Cash on Delivery',\n manual: 'Manual Payment',\n bancontact: 'Bancontact',\n blik: 'BLIK',\n giropay: 'giropay',\n ideal: 'iDEAL',\n przelewy24: 'Przelewy24',\n promptpay: 'PromptPay',\n oxxo: 'OXXO',\n};\n\n/**\n * Infer payment method type from Medusa provider ID\n * \n * Medusa format: pp_{provider}_{method}\n * Examples:\n * - pp_stripe_stripe → 'card'\n * - pp_paypal_paypal → 'wallet'\n * - pp_system_default → 'cash_on_delivery'\n * - pp_stripe_bancontact → 'bank_transfer'\n * \n * @param providerId - Medusa provider ID\n * @returns Normalized payment method type\n */\nfunction inferPaymentType(providerId: string): PaymentMethodType {\n const id = providerId.toLowerCase();\n \n // Card payments\n if (id.includes('stripe') || id.includes('card')) {\n return 'card';\n }\n \n // Digital wallets\n if (\n id.includes('paypal') || \n id.includes('wallet') ||\n id.includes('apple') ||\n id.includes('google')\n ) {\n return 'wallet';\n }\n \n // Bank transfers\n if (\n id.includes('bancontact') ||\n id.includes('ideal') ||\n id.includes('giropay') ||\n id.includes('sepa') ||\n id.includes('ach') ||\n id.includes('bank')\n ) {\n return 'bank_transfer';\n }\n \n // Buy now pay later\n if (\n id.includes('klarna') ||\n id.includes('affirm') ||\n id.includes('afterpay') ||\n id.includes('przelewy24')\n ) {\n return 'buy_now_pay_later';\n }\n \n // Cash on delivery / Manual\n if (\n id.includes('system') ||\n id.includes('manual') ||\n id.includes('cod') ||\n id.includes('default')\n ) {\n return 'cash_on_delivery';\n }\n \n // Crypto\n if (id.includes('crypto') || id.includes('bitcoin')) {\n return 'crypto';\n }\n \n return 'other';\n}\n\n/**\n * Parse Medusa provider ID to extract provider and method names\n * \n * @param providerId - Medusa provider ID (e.g., \"pp_stripe_stripe\")\n * @returns Object with provider and method names\n */\nfunction parseProviderId(providerId: string): { provider: string; method: string } {\n // Medusa format: pp_{provider}_{method}\n const match = providerId.match(/^pp_([^_]+)_(.+)$/);\n \n if (match) {\n return {\n provider: match[1],\n method: match[2],\n };\n }\n \n // Fallback for non-standard formats\n return {\n provider: 'unknown',\n method: providerId,\n };\n}\n\n/**\n * Get display name for a provider\n */\nfunction getDisplayName(providerName: string): string {\n return PROVIDER_DISPLAY_NAMES[providerName.toLowerCase()] || \n providerName.charAt(0).toUpperCase() + providerName.slice(1);\n}\n\n/**\n * Transform Medusa payment provider to Thor payment method\n * \n * @param medusaProvider - Medusa payment provider from API\n * @returns Normalized Thor PaymentMethod\n */\nexport function transformPaymentMethod(\n medusaProvider: HttpTypes.StorePaymentProvider\n): PaymentMethod {\n const providerId = medusaProvider.id;\n const { provider, method } = parseProviderId(providerId);\n const type = inferPaymentType(providerId);\n \n // Determine features based on provider type\n const isStripe = provider === 'stripe';\n const isSystemDefault = provider === 'system' || method === 'default';\n const isPayPal = provider === 'paypal';\n \n return {\n id: providerId,\n name: getDisplayName(provider),\n type,\n isEnabled: true, // Medusa returns only enabled providers by default\n requiresSetup: !isSystemDefault, // System/manual payment requires no setup\n metadata: {\n providerId: provider,\n methodId: method,\n originalData: medusaProvider,\n _backendMapping: {\n backend: 'medusa',\n originalId: providerId,\n normalizedType: type,\n },\n },\n features: {\n // Stripe supports saving payment methods\n saveForLater: isStripe,\n \n // Stripe requires 3DS for SCA compliance\n requires3DS: isStripe,\n \n // Most providers support refunds except COD/manual\n supportsRefunds: !isSystemDefault,\n \n // Stripe has minimum amounts (varies by currency)\n minAmount: isStripe ? 50 : undefined, // 50 cents minimum for Stripe\n \n // PayPal has maximum transaction limits\n maxAmount: isPayPal ? 1000000 : undefined, // $10,000 for PayPal\n },\n };\n}\n\n/**\n * Get payment methods for Medusa\n * \n * Queries Medusa API for available payment providers in a region.\n * Medusa requires either regionId or cartId to determine available providers.\n * \n * @param sdk - Medusa SDK instance\n * @param options - Payment methods query options\n * @returns Array of normalized payment methods\n * \n * @throws {Error} If neither regionId nor cartId is provided\n * @throws {ProviderAPIError} If API request fails\n */\nexport async function getPaymentMethods(\n sdk: Medusa,\n options: PaymentMethodsOptions\n): Promise<PaymentMethod[]> {\n // Medusa requires region_id to list payment providers\n let regionId = options.regionId;\n \n // If cart ID is provided but no region, fetch cart to get region\n if (options.cartId && !regionId) {\n try {\n const { cart } = await sdk.store.cart.retrieve(options.cartId);\n regionId = cart.region_id;\n } catch (error) {\n const err = error as any;\n throw new ProviderAPIError(\n 'Failed to fetch cart to determine region',\n 'medusa',\n err?.status\n );\n }\n }\n \n // Validate that we have a region ID\n if (!regionId) {\n throw new Error(\n 'Either regionId or cartId is required for Medusa payment methods. ' +\n 'Medusa requires a region to determine available payment providers.'\n );\n }\n \n try {\n // Query Medusa API for payment providers in this region\n const response = await sdk.store.payment.listPaymentProviders({\n region_id: regionId,\n });\n \n // Transform to Thor format\n let methods = response.payment_providers.map(transformPaymentMethod);\n \n // Apply filters\n if (options.enabledOnly !== false) { // Default to true\n methods = methods.filter(m => m.isEnabled);\n }\n \n // Filter by currency if provided\n if (options.currencyCode) {\n methods = methods.filter(m => {\n // If method specifies supported currencies, check them\n if (m.features?.supportedCurrencies) {\n return m.features.supportedCurrencies.includes(options.currencyCode!);\n }\n // Otherwise assume all currencies supported\n return true;\n });\n }\n \n return methods;\n } catch (error) {\n const err = error as any;\n throw new ProviderAPIError(\n 'Failed to fetch payment providers from Medusa',\n 'medusa',\n err?.status\n );\n }\n}\n","/**\n * @thorprovider/adapters — Shopify Provider\n * Transform functions: Shopify GraphQL responses → @thorprovider/types\n */\n\nimport type {\n Product,\n ProductVariant,\n ProductOption,\n Cart,\n CartItem,\n Collection,\n Money,\n Image,\n Order,\n OrderItem,\n OrderStatus,\n PaymentStatus,\n FulfillmentStatus,\n Customer,\n Address,\n} from '@thorprovider/types';\n\n// ============================================\n// Money & Image Transforms\n// ============================================\n\nfunction transformMoney(shopifyMoney: { amount: string; currencyCode: string } | null | undefined): Money {\n return {\n amount: shopifyMoney?.amount ?? '0.00',\n currencyCode: shopifyMoney?.currencyCode?.toUpperCase() ?? 'USD',\n };\n}\n\nfunction transformImage(shopifyImage: { url: string; altText?: string | null; width?: number; height?: number } | null | undefined): Image {\n return {\n url: shopifyImage?.url ?? '',\n altText: shopifyImage?.altText ?? '',\n width: shopifyImage?.width ?? 800,\n height: shopifyImage?.height ?? 800,\n };\n}\n\n// ============================================\n// Product Transforms\n// ============================================\n\nfunction transformVariant(raw: any): ProductVariant {\n return {\n id: raw.id,\n title: raw.title ?? '',\n availableForSale: raw.availableForSale ?? true,\n price: transformMoney(raw.price),\n compareAtPrice: raw.compareAtPrice ? transformMoney(raw.compareAtPrice) : undefined,\n selectedOptions: (raw.selectedOptions ?? []).map((opt: any) => ({\n name: opt.name,\n value: opt.value,\n })),\n image: raw.image ? transformImage(raw.image) : undefined,\n };\n}\n\nfunction transformOption(raw: any): ProductOption {\n return {\n id: raw.id,\n name: raw.name,\n values: raw.values ?? [],\n };\n}\n\nexport function transformProduct(raw: any): Product {\n const images = (raw.images?.edges ?? []).map((edge: any) => transformImage(edge.node));\n const variants = (raw.variants?.edges ?? []).map((edge: any) => transformVariant(edge.node));\n\n return {\n id: raw.id,\n handle: raw.handle,\n title: raw.title,\n description: raw.description ?? '',\n descriptionHtml: raw.descriptionHtml ?? '',\n availableForSale: raw.availableForSale ?? true,\n featuredImage: raw.featuredImage ? transformImage(raw.featuredImage) : (images[0] ?? { url: '', altText: '', width: 800, height: 800 }),\n images,\n options: (raw.options ?? []).map(transformOption),\n variants,\n priceRange: {\n minVariantPrice: transformMoney(raw.priceRange?.minVariantPrice),\n maxVariantPrice: transformMoney(raw.priceRange?.maxVariantPrice),\n },\n seo: {\n title: raw.seo?.title ?? raw.title ?? '',\n description: raw.seo?.description ?? raw.description ?? '',\n },\n tags: raw.tags ?? [],\n createdAt: raw.createdAt ?? new Date().toISOString(),\n updatedAt: raw.updatedAt ?? new Date().toISOString(),\n vendor: raw.vendor,\n productType: raw.productType,\n };\n}\n\n// ============================================\n// Collection Transforms\n// ============================================\n\nexport function transformCollection(raw: any): Collection {\n return {\n id: raw.id ?? '',\n handle: raw.handle,\n title: raw.title,\n description: raw.description ?? '',\n seo: {\n title: raw.seo?.title ?? raw.title ?? '',\n description: raw.seo?.description ?? raw.description ?? '',\n },\n updatedAt: raw.updatedAt ?? new Date().toISOString(),\n path: `/collections/${raw.handle}`,\n };\n}\n\n// ============================================\n// Cart Transforms\n// ============================================\n\nfunction transformCartItem(raw: any): CartItem {\n const merchandise = raw.merchandise ?? {};\n const product = merchandise.product ?? {};\n\n return {\n id: raw.id,\n quantity: raw.quantity ?? 1,\n cost: {\n totalAmount: transformMoney(raw.cost?.totalAmount),\n },\n merchandise: {\n id: merchandise.id ?? '',\n title: merchandise.title ?? '',\n selectedOptions: (merchandise.selectedOptions ?? []).map((opt: any) => ({\n name: opt.name,\n value: opt.value,\n })),\n product: {\n id: product.id ?? '',\n handle: product.handle ?? '',\n title: product.title ?? '',\n featuredImage: product.featuredImage\n ? transformImage(product.featuredImage)\n : { url: '', altText: '', width: 800, height: 800 },\n },\n },\n };\n}\n\nexport function transformCart(raw: any): Cart {\n const lines = (raw.lines?.edges ?? []).map((edge: any) => transformCartItem(edge.node));\n\n return {\n id: raw.id,\n checkoutUrl: raw.checkoutUrl ?? '',\n totalQuantity: raw.totalQuantity ?? 0,\n cost: {\n subtotalAmount: transformMoney(raw.cost?.subtotalAmount),\n totalAmount: transformMoney(raw.cost?.totalAmount),\n totalTaxAmount: raw.cost?.totalTaxAmount ? transformMoney(raw.cost.totalTaxAmount) : undefined,\n },\n lines,\n };\n}\n\n// ============================================\n// Customer Transforms\n// ============================================\n\nexport function transformAddress(raw: any): Address {\n return {\n id: raw.id ?? '',\n firstName: raw.firstName ?? '',\n lastName: raw.lastName ?? '',\n address1: raw.address1 ?? '',\n address2: raw.address2 ?? '',\n city: raw.city ?? '',\n province: raw.province ?? '',\n countryCode: raw.country ?? raw.countryCodeV2 ?? '',\n postalCode: raw.zip ?? '',\n phone: raw.phone ?? '',\n company: raw.company ?? '',\n };\n}\n\nexport function transformCustomer(raw: any): Customer {\n return {\n id: raw.id ?? '',\n email: raw.email ?? '',\n firstName: raw.firstName ?? '',\n lastName: raw.lastName ?? '',\n phone: raw.phone ?? '',\n hasAccount: true,\n };\n}\n\nexport function transformCustomerAddresses(raw: any): Address[] {\n const edges = raw.addresses?.edges ?? [];\n return edges.map((edge: any) => transformAddress(edge.node));\n}\n\n// ============================================\n// Order Transforms\n// ============================================\n\nfunction mapFinancialStatus(status: string | null | undefined): PaymentStatus {\n switch (status?.toUpperCase()) {\n case 'PAID': return 'paid';\n case 'PENDING': return 'pending';\n case 'AUTHORIZED': return 'authorized';\n case 'REFUNDED': return 'refunded';\n case 'PARTIALLY_REFUNDED': return 'partially_refunded';\n default: return 'pending';\n }\n}\n\nfunction mapFulfillmentStatus(status: string | null | undefined): FulfillmentStatus {\n switch (status?.toUpperCase()) {\n case 'FULFILLED': return 'fulfilled';\n case 'PARTIAL': return 'partially_fulfilled';\n case 'UNFULFILLED': return 'unfulfilled';\n default: return 'unfulfilled';\n }\n}\n\nfunction deriveOrderStatus(financial: string | null, fulfillment: string | null): OrderStatus {\n if (financial?.toUpperCase() === 'VOIDED') return 'cancelled';\n if (financial?.toUpperCase() === 'REFUNDED') return 'refunded';\n if (fulfillment?.toUpperCase() === 'FULFILLED') return 'completed';\n if (financial?.toUpperCase() === 'PAID') return 'processing';\n return 'pending';\n}\n\nfunction transformOrderItem(raw: any): OrderItem {\n const variant = raw.variant ?? {};\n const product = variant.product ?? {};\n\n return {\n id: variant.id ?? raw.title ?? '',\n title: raw.title ?? '',\n variantTitle: variant.title ?? '',\n quantity: raw.quantity ?? 1,\n price: transformMoney(variant.price),\n total: {\n amount: ((parseFloat(variant.price?.amount ?? '0')) * (raw.quantity ?? 1)).toFixed(2),\n currencyCode: variant.price?.currencyCode ?? 'USD',\n },\n productId: product.id,\n variantId: variant.id,\n };\n}\n\nexport function transformOrder(raw: any): Order {\n const items = (raw.lineItems?.edges ?? []).map((edge: any) => transformOrderItem(edge.node));\n\n return {\n id: raw.id ?? '',\n orderNumber: raw.orderNumber?.toString() ?? '',\n email: raw.email ?? '',\n status: deriveOrderStatus(raw.financialStatus, raw.fulfillmentStatus),\n paymentStatus: mapFinancialStatus(raw.financialStatus),\n fulfillmentStatus: mapFulfillmentStatus(raw.fulfillmentStatus),\n items,\n total: transformMoney(raw.totalPrice),\n subtotal: transformMoney(raw.subtotalPrice ?? raw.totalPrice),\n tax: { amount: '0.00', currencyCode: raw.totalPrice?.currencyCode ?? 'USD' },\n shipping: { amount: '0.00', currencyCode: raw.totalPrice?.currencyCode ?? 'USD' },\n createdAt: raw.processedAt ?? new Date().toISOString(),\n updatedAt: raw.processedAt ?? new Date().toISOString(),\n };\n}\n","/**\n * @thorprovider/adapters — Shopify Provider\n * GraphQL query definitions for Storefront API\n */\n\nexport const PRODUCT_FRAGMENT = `\n fragment ProductFields on Product {\n id\n title\n handle\n description\n descriptionHtml\n vendor\n productType\n tags\n availableForSale\n createdAt\n updatedAt\n seo {\n title\n description\n }\n featuredImage {\n url\n altText\n width\n height\n }\n images(first: 10) {\n edges {\n node {\n url\n altText\n width\n height\n }\n }\n }\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n maxVariantPrice {\n amount\n currencyCode\n }\n }\n options {\n id\n name\n values\n }\n variants(first: 100) {\n edges {\n node {\n id\n title\n availableForSale\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n selectedOptions {\n name\n value\n }\n image {\n url\n altText\n width\n height\n }\n }\n }\n }\n }\n`;\n\nexport const GET_PRODUCT_BY_HANDLE = `\n query GetProductByHandle($handle: String!) {\n product(handle: $handle) {\n ...ProductFields\n }\n }\n ${PRODUCT_FRAGMENT}\n`;\n\nexport const GET_PRODUCTS = `\n query GetProducts($first: Int!, $query: String, $sortKey: ProductSortKeys, $reverse: Boolean, $after: String) {\n products(first: $first, query: $query, sortKey: $sortKey, reverse: $reverse, after: $after) {\n edges {\n node {\n ...ProductFields\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n }\n }\n }\n ${PRODUCT_FRAGMENT}\n`;\n\nexport const GET_PRODUCT_RECOMMENDATIONS = `\n query GetProductRecommendations($productId: ID!) {\n productRecommendations(productId: $productId) {\n ...ProductFields\n }\n }\n ${PRODUCT_FRAGMENT}\n`;\n\nexport const COLLECTION_FRAGMENT = `\n fragment CollectionFields on Collection {\n id\n title\n handle\n description\n image {\n url\n altText\n width\n height\n }\n seo {\n title\n description\n }\n updatedAt\n }\n`;\n\nexport const GET_COLLECTION_BY_HANDLE = `\n query GetCollectionByHandle($handle: String!) {\n collection(handle: $handle) {\n ...CollectionFields\n }\n }\n ${COLLECTION_FRAGMENT}\n`;\n\nexport const GET_COLLECTIONS = `\n query GetCollections($first: Int!) {\n collections(first: $first) {\n edges {\n node {\n ...CollectionFields\n }\n }\n }\n }\n ${COLLECTION_FRAGMENT}\n`;\n\nexport const GET_COLLECTION_PRODUCTS = `\n query GetCollectionProducts($handle: String!, $first: Int!, $sortKey: ProductCollectionSortKeys, $reverse: Boolean, $after: String) {\n collection(handle: $handle) {\n products(first: $first, sortKey: $sortKey, reverse: $reverse, after: $after) {\n edges {\n node {\n ...ProductFields\n }\n cursor\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n ${PRODUCT_FRAGMENT}\n`;\n\nexport const CART_FRAGMENT = `\n fragment CartFields on Cart {\n id\n checkoutUrl\n totalQuantity\n cost {\n subtotalAmount {\n amount\n currencyCode\n }\n totalAmount {\n amount\n currencyCode\n }\n totalTaxAmount {\n amount\n currencyCode\n }\n }\n lines(first: 100) {\n edges {\n node {\n id\n quantity\n cost {\n totalAmount {\n amount\n currencyCode\n }\n }\n merchandise {\n ... on ProductVariant {\n id\n title\n selectedOptions {\n name\n value\n }\n product {\n id\n handle\n title\n featuredImage {\n url\n altText\n width\n height\n }\n }\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_CART = `\n query GetCart($cartId: ID!) {\n cart(id: $cartId) {\n ...CartFields\n }\n }\n ${CART_FRAGMENT}\n`;\n\nexport const GET_CUSTOMER = `\n query GetCustomer {\n customer {\n id\n firstName\n lastName\n email\n phone\n defaultAddress {\n id\n address1\n address2\n city\n province\n country\n zip\n phone\n firstName\n lastName\n }\n addresses(first: 20) {\n edges {\n node {\n id\n address1\n address2\n city\n province\n country\n zip\n phone\n firstName\n lastName\n }\n }\n }\n orders(first: 50) {\n edges {\n node {\n id\n orderNumber\n processedAt\n financialStatus\n fulfillmentStatus\n totalPrice {\n amount\n currencyCode\n }\n lineItems(first: 50) {\n edges {\n node {\n title\n quantity\n variant {\n id\n title\n price {\n amount\n currencyCode\n }\n image {\n url\n altText\n }\n product {\n id\n handle\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n`;\n","/**\n * @thorprovider/adapters — Shopify Provider\n * GraphQL mutation definitions for Storefront API\n */\n\nimport { CART_FRAGMENT } from './queries';\n\nexport const CART_CREATE = `\n mutation CartCreate($input: CartInput!) {\n cartCreate(input: $input) {\n cart {\n ...CartFields\n }\n userErrors {\n field\n message\n code\n }\n }\n }\n ${CART_FRAGMENT}\n`;\n\nexport const CART_LINES_ADD = `\n mutation CartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {\n cartLinesAdd(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFields\n }\n userErrors {\n field\n message\n code\n }\n }\n }\n ${CART_FRAGMENT}\n`;\n\nexport const CART_LINES_UPDATE = `\n mutation CartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) {\n cartLinesUpdate(cartId: $cartId, lines: $lines) {\n cart {\n ...CartFields\n }\n userErrors {\n field\n message\n code\n }\n }\n }\n ${CART_FRAGMENT}\n`;\n\nexport const CART_LINES_REMOVE = `\n mutation CartLinesRemove($cartId: ID!, $lineIds: [ID!]!) {\n cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {\n cart {\n ...CartFields\n }\n userErrors {\n field\n message\n code\n }\n }\n }\n ${CART_FRAGMENT}\n`;\n\nexport const CART_DISCOUNT_CODES_UPDATE = `\n mutation CartDiscountCodesUpdate($cartId: ID!, $discountCodes: [String!]!) {\n cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {\n cart {\n ...CartFields\n }\n userErrors {\n field\n message\n code\n }\n }\n }\n ${CART_FRAGMENT}\n`;\n\nexport const CUSTOMER_ACCESS_TOKEN_CREATE = `\n mutation CustomerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {\n customerAccessTokenCreate(input: $input) {\n customerAccessToken {\n accessToken\n expiresAt\n }\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_ACCESS_TOKEN_DELETE = `\n mutation CustomerAccessTokenDelete($customerAccessToken: String!) {\n customerAccessTokenDelete(customerAccessToken: $customerAccessToken) {\n deletedAccessToken\n deletedCustomerAccessTokenId\n userErrors {\n field\n message\n }\n }\n }\n`;\n\nexport const CUSTOMER_CREATE = `\n mutation CustomerCreate($input: CustomerCreateInput!) {\n customerCreate(input: $input) {\n customer {\n id\n email\n firstName\n lastName\n }\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_UPDATE = `\n mutation CustomerUpdate($customerAccessToken: String!, $customer: CustomerUpdateInput!) {\n customerUpdate(customerAccessToken: $customerAccessToken, customer: $customer) {\n customer {\n id\n email\n firstName\n lastName\n phone\n }\n customerAccessToken {\n accessToken\n expiresAt\n }\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_RECOVER = `\n mutation CustomerRecover($email: String!) {\n customerRecover(email: $email) {\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_RESET = `\n mutation CustomerReset($id: ID!, $input: CustomerResetInput!) {\n customerReset(id: $id, input: $input) {\n customerAccessToken {\n accessToken\n expiresAt\n }\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_ADDRESS_CREATE = `\n mutation CustomerAddressCreate($customerAccessToken: String!, $address: MailingAddressInput!) {\n customerAddressCreate(customerAccessToken: $customerAccessToken, address: $address) {\n customerAddress {\n id\n firstName\n lastName\n address1\n address2\n city\n province\n country\n zip\n phone\n company\n }\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_ADDRESS_UPDATE = `\n mutation CustomerAddressUpdate($customerAccessToken: String!, $id: ID!, $address: MailingAddressInput!) {\n customerAddressUpdate(customerAccessToken: $customerAccessToken, id: $id, address: $address) {\n customerAddress {\n id\n firstName\n lastName\n address1\n address2\n city\n province\n country\n zip\n phone\n company\n }\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n\nexport const CUSTOMER_ADDRESS_DELETE = `\n mutation CustomerAddressDelete($customerAccessToken: String!, $id: ID!) {\n customerAddressDelete(customerAccessToken: $customerAccessToken, id: $id) {\n deletedCustomerAddressId\n customerUserErrors {\n field\n message\n code\n }\n }\n }\n`;\n","/**\n * @thorprovider/adapters — Shopify Provider\n * Implements CommerceProvider for Shopify Storefront API (GraphQL)\n *\n * Uses @shopify/storefront-api-client for type-safe GraphQL operations.\n * Authentication via public/private access tokens (legacy Storefront tokens).\n */\n\nimport type {\n Product,\n GetProductsOptions,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCollectionsOptions,\n ProductCategory,\n GetCategoriesOptions,\n Order,\n GetOrdersOptions,\n Customer,\n Address,\n PaymentMethod,\n PaymentMethodsOptions,\n ShippingMethod,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n StorefrontContext,\n BackendCapabilities,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { SHOPIFY_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError, ResourceNotFoundError } from '../../core/errors';\nimport { transformProduct, transformCart, transformCollection, transformCustomer, transformOrder } from './transforms';\nimport {\n GET_PRODUCT_BY_HANDLE,\n GET_PRODUCTS,\n GET_PRODUCT_RECOMMENDATIONS,\n GET_COLLECTION_BY_HANDLE,\n GET_COLLECTIONS,\n GET_COLLECTION_PRODUCTS,\n GET_CART,\n GET_CUSTOMER,\n} from './queries';\nimport {\n CART_CREATE,\n CART_LINES_ADD,\n CART_LINES_UPDATE,\n CART_LINES_REMOVE,\n CART_DISCOUNT_CODES_UPDATE,\n} from './mutations';\n\n/**\n * Shopify provider configuration\n */\nexport interface ShopifyProviderConfig extends ProviderConfig {\n /** Store domain (e.g., 'your-store.myshopify.com') */\n storeDomain: string;\n /** Public Storefront API access token */\n publicAccessToken: string;\n /** Private Storefront API access token (server-side only) */\n privateAccessToken?: string;\n /** API version (default: '2026-04') */\n apiVersion?: string;\n}\n\n/**\n * Shopify commerce provider\n *\n * Implements CommerceProvider for Shopify Storefront API.\n * Uses raw fetch + GraphQL queries (no SDK dependency to stay L2-pure).\n */\nexport class ShopifyProvider implements CommerceProvider {\n readonly name = 'shopify';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = SHOPIFY_CAPABILITIES;\n\n private logger: ReturnType<typeof createLogger>;\n private storeDomain: string;\n private apiVersion: string;\n private endpoint: string;\n private headers: Record<string, string>;\n\n constructor(config: ShopifyProviderConfig) {\n this.logger = createLogger('ShopifyProvider', config.debug);\n this.storeDomain = config.storeDomain.replace(/^https?:\\/\\//, '').replace(/\\/$/, '');\n this.apiVersion = config.apiVersion ?? '2026-04';\n this.endpoint = `https://${this.storeDomain}/api/${this.apiVersion}/graphql.json`;\n\n this.headers = {\n 'Content-Type': 'application/json',\n ...(config.privateAccessToken\n ? { 'Shopify-Storefront-Private-Token': config.privateAccessToken }\n : { 'X-Shopify-Storefront-Access-Token': config.publicAccessToken }),\n };\n\n this.logger.info('Initializing Shopify Provider', {\n storeDomain: this.storeDomain,\n apiVersion: this.apiVersion,\n authType: config.privateAccessToken ? 'private' : 'public',\n });\n }\n\n // ============================================\n // GraphQL Client\n // ============================================\n\n private async query<T = any>(gql: string, variables?: Record<string, any>): Promise<T> {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ query: gql, variables }),\n });\n\n if (!response.ok) {\n throw new ProviderAPIError(\n `Shopify API error: ${response.status} ${response.statusText}`,\n 'SHOPIFY_API_ERROR',\n response.status,\n );\n }\n\n const json = await response.json() as { data?: T; errors?: Array<{ message: string }> };\n\n if (json.errors?.length) {\n const message = json.errors.map((e) => e.message).join('; ');\n throw new ProviderAPIError(`Shopify GraphQL error: ${message}`, 'SHOPIFY_GRAPHQL_ERROR');\n }\n\n return json.data as T;\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n async getProduct(handle: string): Promise<Product | undefined> {\n const data = await this.query<{ product: any }>(GET_PRODUCT_BY_HANDLE, { handle });\n return data.product ? transformProduct(data.product) : undefined;\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n const first = options?.first ?? 20;\n const sortKeyMap: Record<string, string> = {\n 'title-asc': 'TITLE',\n 'title-desc': 'TITLE',\n 'price-asc': 'PRICE',\n 'price-desc': 'PRICE',\n 'best-selling': 'BEST_SELLING',\n 'created-desc': 'CREATED_AT',\n 'relevance': 'RELEVANCE',\n };\n const sortKey = options?.sortKey ? (sortKeyMap[options.sortKey] ?? 'RELEVANCE') : 'RELEVANCE';\n const reverse = options?.sortKey?.endsWith('-desc') ?? false;\n\n const data = await this.query<{ products: { edges: Array<{ node: any }> } }>(GET_PRODUCTS, {\n first,\n query: options?.query,\n sortKey,\n reverse,\n });\n\n return data.products.edges.map((edge) => transformProduct(edge.node));\n }\n\n async getProductRecommendations(productId: string): Promise<Product[]> {\n const data = await this.query<{ productRecommendations: any[] }>(GET_PRODUCT_RECOMMENDATIONS, {\n productId,\n });\n return (data.productRecommendations ?? []).map(transformProduct);\n }\n\n // ============================================\n // Collection Operations\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n const data = await this.query<{ collection: any }>(GET_COLLECTION_BY_HANDLE, { handle });\n return data.collection ? transformCollection(data.collection) : undefined;\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const data = await this.query<{ collections: { edges: Array<{ node: any }> } }>(GET_COLLECTIONS, {\n first: options?.limit ?? 50,\n });\n return data.collections.edges.map((edge) => transformCollection(edge.node));\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const data = await this.query<{ collection: { products: { edges: Array<{ node: any }> } } }>(\n GET_COLLECTION_PRODUCTS,\n {\n handle,\n first: options?.first ?? 20,\n sortKey: options?.sortKey === 'price-asc' || options?.sortKey === 'price-desc' ? 'PRICE' : 'BEST_SELLING',\n reverse: options?.sortKey?.endsWith('-desc') ?? false,\n },\n );\n return (data.collection?.products?.edges ?? []).map((edge) => transformProduct(edge.node));\n }\n\n // ============================================\n // Category Operations (Shopify does not have native categories)\n // ============================================\n\n async getCategory(): Promise<ProductCategory | undefined> {\n this.logger.warn('Shopify does not support native categories. Use collections instead.');\n return undefined;\n }\n\n async getCategories(): Promise<ProductCategory[]> {\n return [];\n }\n\n async getCategoryProducts(): Promise<Product[]> {\n return [];\n }\n\n // ============================================\n // Cart Operations\n // ============================================\n\n async createCart(): Promise<Cart> {\n const data = await this.query<{ cartCreate: { cart: any; userErrors: any[] } }>(CART_CREATE, {\n input: {},\n });\n\n if (data.cartCreate.userErrors?.length) {\n throw new ProviderAPIError(\n `Cart creation failed: ${data.cartCreate.userErrors.map((e: any) => e.message).join('; ')}`,\n 'SHOPIFY_CART_ERROR',\n );\n }\n\n return transformCart(data.cartCreate.cart);\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n const data = await this.query<{ cart: any }>(GET_CART, { cartId });\n return data.cart ? transformCart(data.cart) : undefined;\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n const data = await this.query<{ cartLinesAdd: { cart: any; userErrors: any[] } }>(CART_LINES_ADD, {\n cartId,\n lines: lines.map((l) => ({ merchandiseId: l.merchandiseId, quantity: l.quantity })),\n });\n\n if (data.cartLinesAdd.userErrors?.length) {\n throw new ProviderAPIError(\n `Add to cart failed: ${data.cartLinesAdd.userErrors.map((e: any) => e.message).join('; ')}`,\n 'SHOPIFY_CART_ERROR',\n );\n }\n\n return transformCart(data.cartLinesAdd.cart);\n }\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n const data = await this.query<{ cartLinesRemove: { cart: any; userErrors: any[] } }>(CART_LINES_REMOVE, {\n cartId,\n lineIds,\n });\n\n if (data.cartLinesRemove.userErrors?.length) {\n throw new ProviderAPIError(\n `Remove from cart failed: ${data.cartLinesRemove.userErrors.map((e: any) => e.message).join('; ')}`,\n 'SHOPIFY_CART_ERROR',\n );\n }\n\n return transformCart(data.cartLinesRemove.cart);\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n const data = await this.query<{ cartLinesUpdate: { cart: any; userErrors: any[] } }>(CART_LINES_UPDATE, {\n cartId,\n lines: lines.map((l) => ({ id: l.id, quantity: l.quantity })),\n });\n\n if (data.cartLinesUpdate.userErrors?.length) {\n throw new ProviderAPIError(\n `Update cart failed: ${data.cartLinesUpdate.userErrors.map((e: any) => e.message).join('; ')}`,\n 'SHOPIFY_CART_ERROR',\n );\n }\n\n return transformCart(data.cartLinesUpdate.cart);\n }\n\n // ============================================\n // Checkout Operations\n // ============================================\n\n async completeCheckout(_cartId: string): Promise<Order> {\n // Shopify checkout is hosted — redirect to cart.checkoutUrl\n // This method cannot programmatically complete checkout\n throw new ProviderAPIError(\n 'Shopify uses hosted checkout. Redirect the buyer to cart.checkoutUrl instead of calling completeCheckout().',\n 'SHOPIFY_HOSTED_CHECKOUT',\n );\n }\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n // Shopify handles shipping selection in hosted checkout\n return [];\n }\n\n async getRegionCountries(): Promise<import('@thorprovider/types').Country[]> {\n return [];\n }\n\n async addShippingMethod(_cartId: string, _methodId: string): Promise<Cart> {\n throw new ProviderAPIError(\n 'Shopify handles shipping selection in hosted checkout.',\n 'SHOPIFY_HOSTED_CHECKOUT',\n );\n }\n\n async initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n throw new ProviderAPIError(\n 'Shopify handles payment in hosted checkout.',\n 'SHOPIFY_HOSTED_CHECKOUT',\n );\n }\n\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n const currentCart = await this.getCart(cartId);\n const existingCodes: string[] = []; // Shopify replaces all codes\n existingCodes.push(code);\n\n const data = await this.query<{ cartDiscountCodesUpdate: { cart: any; userErrors: any[] } }>(\n CART_DISCOUNT_CODES_UPDATE,\n { cartId, discountCodes: existingCodes },\n );\n\n if (data.cartDiscountCodesUpdate.userErrors?.length) {\n throw new ProviderAPIError(\n `Discount code failed: ${data.cartDiscountCodesUpdate.userErrors.map((e: any) => e.message).join('; ')}`,\n 'SHOPIFY_DISCOUNT_ERROR',\n );\n }\n\n return transformCart(data.cartDiscountCodesUpdate.cart);\n }\n\n async removeDiscountCode(cartId: string, _code: string): Promise<Cart> {\n const data = await this.query<{ cartDiscountCodesUpdate: { cart: any; userErrors: any[] } }>(\n CART_DISCOUNT_CODES_UPDATE,\n { cartId, discountCodes: [] },\n );\n\n return transformCart(data.cartDiscountCodesUpdate.cart);\n }\n\n // ============================================\n // Customer Operations\n // ============================================\n\n async getOrders(options: GetOrdersOptions): Promise<Order[]> {\n this.logger.warn('Shopify orders require Customer Account API (planned upgrade path).');\n return [];\n }\n\n // ============================================\n // Payment Operations\n // ============================================\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n // Shopify payment selection happens in hosted checkout\n return [];\n }\n\n // ============================================\n // Inventory Operations (not available via Storefront API)\n // ============================================\n\n async getStockLocations(): Promise<StockLocation[]> {\n return [];\n }\n\n async checkInventoryLevels(): Promise<InventoryLevel[]> {\n return [];\n }\n\n async validateCartStock(): Promise<StockValidation> {\n return { allAvailable: true, unavailableItems: [] };\n }\n\n async getFulfillmentOptions(): Promise<FulfillmentOption[]> {\n return [];\n }\n\n // ============================================\n // Admin Operations (not available via Storefront API)\n // ============================================\n\n async cancelOrder(_orderId: string): Promise<Order> {\n throw new ProviderAPIError(\n 'Order cancellation requires Shopify Admin API (not available in Storefront API).',\n 'SHOPIFY_ADMIN_REQUIRED',\n );\n }\n\n async createFulfillment(_orderId: string): Promise<void> {\n throw new ProviderAPIError(\n 'Fulfillment requires Shopify Admin API.',\n 'SHOPIFY_ADMIN_REQUIRED',\n );\n }\n\n async createRefund(_orderId: string): Promise<void> {\n throw new ProviderAPIError(\n 'Refunds require Shopify Admin API.',\n 'SHOPIFY_ADMIN_REQUIRED',\n );\n }\n\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> {\n return { orders: [], count: 0 };\n }\n\n // ============================================\n // Storefront / Multi-Tenant\n // ============================================\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.storeDomain,\n name: this.storeDomain,\n platformType: 'shopify',\n requiresProductScoping: false,\n currencyCode: 'USD',\n };\n }\n\n isStorefrontRequired(): boolean {\n return false;\n }\n}\n","/**\n * @thorprovider/adapters — BigCommerce Provider\n * Transform functions: BigCommerce REST API → @thorprovider/types\n */\n\nimport type {\n Product,\n ProductVariant,\n ProductOption,\n Cart,\n CartItem,\n Collection,\n Money,\n Image,\n Order,\n OrderItem,\n OrderStatus,\n PaymentStatus,\n FulfillmentStatus,\n Customer,\n Address,\n} from '@thorprovider/types';\n\n// ============================================\n// Money & Image Transforms\n// ============================================\n\nfunction transformMoney(amount: number | string | null | undefined, currencyCode: string = 'USD'): Money {\n const numAmount = typeof amount === 'string' ? parseFloat(amount) : (amount ?? 0);\n return {\n amount: numAmount.toFixed(2),\n currencyCode: currencyCode.toUpperCase(),\n };\n}\n\nfunction transformImage(url: string, alt: string = ''): Image {\n return { url, altText: alt, width: 800, height: 800 };\n}\n\n// ============================================\n// Product Transforms\n// ============================================\n\nexport function transformProduct(raw: any, currencyCode: string = 'USD'): Product {\n const images: Image[] = (raw.images ?? []).map((img: any) =>\n transformImage(img.url_standard ?? img.url_thumbnail ?? '', img.description ?? ''),\n );\n\n const variants: ProductVariant[] = (raw.variants ?? []).map((v: any) => ({\n id: String(v.id),\n title: v.option_display_name ?? `Variant ${v.id}`,\n availableForSale: (v.purchasing_disabled !== true),\n price: transformMoney(v.price ?? raw.price, currencyCode),\n compareAtPrice: v.sale_price ? transformMoney(v.sale_price, currencyCode) : undefined,\n selectedOptions: (v.option_values ?? []).map((ov: any) => ({\n name: ov.option_display_name ?? '',\n value: ov.label ?? '',\n })),\n }));\n\n const options: ProductOption[] = (raw.options ?? []).map((opt: any) => ({\n id: String(opt.id),\n name: opt.display_name ?? '',\n values: (opt.option_values ?? []).map((val: any) => val.label ?? ''),\n }));\n\n const price = raw.price ?? raw.calculated_price?.as_entered ?? 0;\n\n return {\n id: String(raw.id),\n handle: raw.custom_url?.url?.replace(/^\\//, '').replace(/\\/$/, '') ?? String(raw.id),\n title: raw.name ?? '',\n description: raw.plain_text_description ?? raw.description ?? '',\n descriptionHtml: raw.description ?? '',\n availableForSale: raw.availability === 'available' || raw.is_visible !== false,\n featuredImage: images[0] ?? { url: '', altText: '', width: 800, height: 800 },\n images,\n options,\n variants,\n priceRange: {\n minVariantPrice: transformMoney(price, currencyCode),\n maxVariantPrice: transformMoney(price, currencyCode),\n },\n seo: {\n title: raw.page_title ?? raw.name ?? '',\n description: raw.meta_description ?? '',\n },\n tags: [],\n createdAt: raw.date_created ?? new Date().toISOString(),\n updatedAt: raw.date_modified ?? new Date().toISOString(),\n };\n}\n\n// ============================================\n// Collection Transforms (BigCommerce \"Categories\" or \"Brands\")\n// ============================================\n\nexport function transformCollection(raw: any): Collection {\n return {\n id: String(raw.id ?? ''),\n handle: raw.custom_url?.url?.replace(/^\\//, '').replace(/\\/$/, '') ?? String(raw.id),\n title: raw.name ?? '',\n description: raw.description ?? '',\n seo: {\n title: raw.page_title ?? raw.name ?? '',\n description: raw.meta_description ?? '',\n },\n updatedAt: raw.date_modified ?? new Date().toISOString(),\n path: `/collections/${raw.custom_url?.url?.replace(/^\\//, '').replace(/\\/$/, '') ?? raw.id}`,\n };\n}\n\n// ============================================\n// Cart Transforms\n// ============================================\n\nexport function transformCart(raw: any, currencyCode: string = 'USD'): Cart {\n const lineItems = Object.values(raw.line_items ?? {}).flat() as any[];\n\n const lines: CartItem[] = lineItems.map((item: any) => ({\n id: item.id,\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: transformMoney(item.extended_sale_price ?? item.sale_price ?? 0, currencyCode),\n },\n merchandise: {\n id: String(item.variant_id ?? item.product_id),\n title: item.name ?? '',\n selectedOptions: (item.options ?? []).map((opt: any) => ({\n name: opt.name ?? '',\n value: opt.value ?? '',\n })),\n product: {\n id: String(item.product_id),\n handle: String(item.product_id),\n title: item.name ?? '',\n featuredImage: item.image_url\n ? transformImage(item.image_url)\n : { url: '', altText: '', width: 800, height: 800 },\n },\n },\n }));\n\n return {\n id: raw.id,\n checkoutUrl: raw.redirect_urls?.checkout_url ?? '',\n totalQuantity: lines.reduce((sum, l) => sum + l.quantity, 0),\n cost: {\n subtotalAmount: transformMoney(raw.base_amount ?? 0, currencyCode),\n totalAmount: transformMoney(raw.cart_amount ?? 0, currencyCode),\n },\n lines,\n };\n}\n\n// ============================================\n// Customer Transforms\n// ============================================\n\nexport function transformCustomer(raw: any): Customer {\n return {\n id: String(raw.id),\n email: raw.email ?? '',\n firstName: raw.first_name ?? '',\n lastName: raw.last_name ?? '',\n phone: raw.phone ?? '',\n hasAccount: true,\n };\n}\n\nexport function transformAddress(raw: any): Address {\n return {\n id: String(raw.id ?? ''),\n firstName: raw.first_name ?? '',\n lastName: raw.last_name ?? '',\n address1: raw.address1 ?? '',\n address2: raw.address2 ?? '',\n city: raw.city ?? '',\n province: raw.state_or_province ?? '',\n countryCode: raw.country_code ?? '',\n postalCode: raw.postal_code ?? '',\n phone: raw.phone ?? '',\n company: raw.company ?? '',\n };\n}\n\n// ============================================\n// Order Transforms\n// ============================================\n\nexport function transformOrder(raw: any, currencyCode: string = 'USD'): Order {\n const items: OrderItem[] = (raw.products ?? []).map((p: any) => ({\n id: String(p.id),\n title: p.name ?? '',\n variantTitle: p.sku ?? '',\n quantity: p.quantity ?? 1,\n price: transformMoney(p.base_price ?? 0, currencyCode),\n total: transformMoney(p.base_total ?? 0, currencyCode),\n productId: String(p.product_id),\n }));\n\n const statusMap: Record<string, OrderStatus> = {\n 'Incomplete': 'pending',\n 'Pending': 'pending',\n 'Shipped': 'completed',\n 'Partially Shipped': 'processing',\n 'Refunded': 'refunded',\n 'Cancelled': 'cancelled',\n 'Completed': 'completed',\n };\n\n return {\n id: String(raw.id),\n orderNumber: String(raw.id),\n email: raw.billing_address?.email ?? '',\n status: statusMap[raw.status] ?? 'pending',\n paymentStatus: raw.payment_status === 'paid' ? 'paid' : 'pending',\n fulfillmentStatus: raw.status === 'Shipped' ? 'fulfilled' : 'unfulfilled',\n items,\n total: transformMoney(raw.total_inc_tax ?? 0, currencyCode),\n subtotal: transformMoney(raw.subtotal_inc_tax ?? 0, currencyCode),\n tax: transformMoney(raw.total_tax ?? 0, currencyCode),\n shipping: transformMoney(raw.shipping_cost_inc_tax ?? 0, currencyCode),\n createdAt: raw.date_created ?? new Date().toISOString(),\n updatedAt: raw.date_modified ?? new Date().toISOString(),\n };\n}\n","/**\n * @thorprovider/adapters — BigCommerce Provider\n * Implements CommerceProvider for BigCommerce REST Storefront API\n *\n * Uses raw fetch against BigCommerce Storefront REST API.\n * The official `@bigcommerce/storefront-data-hooks` is deprecated (3 years unmaintained).\n */\n\nimport type {\n Product,\n GetProductsOptions,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCollectionsOptions,\n ProductCategory,\n GetCategoriesOptions,\n Order,\n GetOrdersOptions,\n Customer,\n Address,\n PaymentMethod,\n PaymentMethodsOptions,\n ShippingMethod,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n StorefrontContext,\n BackendCapabilities,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { BIGCOMMERCE_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\nimport {\n transformProduct,\n transformCart,\n transformCollection,\n transformCustomer,\n transformOrder,\n} from './transforms';\n\n/**\n * BigCommerce provider configuration\n */\nexport interface BigCommerceProviderConfig extends ProviderConfig {\n /** BigCommerce store hash */\n storeHash: string;\n /** Storefront API token (JWT) */\n storefrontApiToken: string;\n /** Storefront API URL (usually https://store-{hash}.mybigcommerce.com) */\n storefrontApiUrl: string;\n /** Channel ID */\n channelId: string;\n /** Default currency code (default: 'USD') */\n currencyCode?: string;\n}\n\nexport class BigCommerceProvider implements CommerceProvider {\n readonly name = 'bigcommerce';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = BIGCOMMERCE_CAPABILITIES;\n\n private logger: ReturnType<typeof createLogger>;\n private storefrontApiUrl: string;\n private storeHash: string;\n private channelId: string;\n private currencyCode: string;\n private headers: Record<string, string>;\n\n constructor(config: BigCommerceProviderConfig) {\n this.logger = createLogger('BigCommerceProvider', config.debug);\n this.storefrontApiUrl = config.storefrontApiUrl.replace(/\\/$/, '');\n this.storeHash = config.storeHash;\n this.channelId = config.channelId;\n this.currencyCode = config.currencyCode ?? 'USD';\n this.headers = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.storefrontApiToken}`,\n };\n this.logger.info('Initializing BigCommerce Provider', { storeHash: this.storeHash, channelId: this.channelId });\n }\n\n private async fetchApi<T = any>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.storefrontApiUrl}${path}`;\n const response = await fetch(url, {\n ...init,\n headers: { ...this.headers, ...init?.headers },\n });\n\n if (!response.ok) {\n throw new ProviderAPIError(\n `BigCommerce API error: ${response.status} ${response.statusText}`,\n 'BIGCOMMERCE_API_ERROR',\n response.status,\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n async getProduct(handle: string): Promise<Product | undefined> {\n try {\n const data = await this.fetchApi<{ data: any[] }>(`/api/storefront/products?include=variants,options,images&keyword=${encodeURIComponent(handle)}`);\n const product = data.data?.[0];\n return product ? transformProduct(product, this.currencyCode) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n const limit = options?.first ?? 20;\n let path = `/api/storefront/products?include=variants,options,images&limit=${limit}`;\n if (options?.query) path += `&keyword=${encodeURIComponent(options.query)}`;\n\n const data = await this.fetchApi<{ data: any[] }>(path);\n return (data.data ?? []).map((p) => transformProduct(p, this.currencyCode));\n }\n\n async getProductRecommendations(_productId: string): Promise<Product[]> {\n return []; // BigCommerce doesn't have a Storefront recommendation API\n }\n\n // ============================================\n // Collection Operations (BigCommerce Categories)\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n try {\n const data = await this.fetchApi<{ data: any[] }>(`/api/storefront/categories?url=/${handle}/`);\n const cat = data.data?.[0];\n return cat ? transformCollection(cat) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const limit = options?.limit ?? 50;\n const data = await this.fetchApi<{ data: any[] }>(`/api/storefront/categories?limit=${limit}`);\n return (data.data ?? []).map(transformCollection);\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const limit = options?.first ?? 20;\n const data = await this.fetchApi<{ data: any[] }>(\n `/api/storefront/products?include=variants,options,images&categories:in=${handle}&limit=${limit}`,\n );\n return (data.data ?? []).map((p) => transformProduct(p, this.currencyCode));\n }\n\n // ============================================\n // Category Operations\n // ============================================\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n return this.getCollection(idOrHandle) as any;\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n return this.getCollections(options) as any;\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n return this.getCollectionProducts(handle, options);\n }\n\n // ============================================\n // Cart Operations\n // ============================================\n\n async createCart(): Promise<Cart> {\n const data = await this.fetchApi<{ data: any }>('/api/storefront/carts', {\n method: 'POST',\n body: JSON.stringify({ line_items: [] }),\n });\n return transformCart(data.data ?? data, this.currencyCode);\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n try {\n const data = await this.fetchApi<{ data: any }>(`/api/storefront/carts/${cartId}?include=line_items.physical_items.options`);\n return transformCart(data.data ?? data, this.currencyCode);\n } catch {\n return undefined;\n }\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n const lineItems = lines.map((l) => ({\n product_id: parseInt(l.merchandiseId, 10),\n quantity: l.quantity,\n }));\n\n const data = await this.fetchApi<{ data: any }>(`/api/storefront/carts/${cartId}/items`, {\n method: 'POST',\n body: JSON.stringify({ line_items: lineItems }),\n });\n\n return transformCart(data.data ?? data, this.currencyCode);\n }\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n for (const lineId of lineIds) {\n await this.fetchApi(`/api/storefront/carts/${cartId}/items/${lineId}`, { method: 'DELETE' });\n }\n\n const cart = await this.getCart(cartId);\n if (!cart) throw new ProviderAPIError('Cart not found after removal', 'BIGCOMMERCE_CART_ERROR');\n return cart;\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n for (const line of lines) {\n await this.fetchApi(`/api/storefront/carts/${cartId}/items/${line.id}`, {\n method: 'PUT',\n body: JSON.stringify({ line_item: { quantity: line.quantity } }),\n });\n }\n\n const cart = await this.getCart(cartId);\n if (!cart) throw new ProviderAPIError('Cart not found after update', 'BIGCOMMERCE_CART_ERROR');\n return cart;\n }\n\n // ============================================\n // Checkout Operations (Hosted)\n // ============================================\n\n async completeCheckout(_cartId: string): Promise<Order> {\n throw new ProviderAPIError(\n 'BigCommerce uses Embedded Checkout. Redirect the buyer to cart.checkoutUrl.',\n 'BIGCOMMERCE_HOSTED_CHECKOUT',\n );\n }\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n return [];\n }\n\n async getRegionCountries(): Promise<import('@thorprovider/types').Country[]> {\n return [];\n }\n\n async addShippingMethod(_cartId: string, _methodId: string): Promise<Cart> {\n throw new ProviderAPIError('BigCommerce handles shipping in Embedded Checkout.', 'BIGCOMMERCE_HOSTED_CHECKOUT');\n }\n\n async initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n throw new ProviderAPIError('BigCommerce handles payment in Embedded Checkout.', 'BIGCOMMERCE_HOSTED_CHECKOUT');\n }\n\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n const data = await this.fetchApi<{ data: any }>(`/api/storefront/carts/${cartId}/coupons`, {\n method: 'POST',\n body: JSON.stringify({ coupon_code: code }),\n });\n return transformCart(data.data ?? data, this.currencyCode);\n }\n\n async removeDiscountCode(cartId: string, code: string): Promise<Cart> {\n await this.fetchApi(`/api/storefront/carts/${cartId}/coupons/${encodeURIComponent(code)}`, { method: 'DELETE' });\n const cart = await this.getCart(cartId);\n if (!cart) throw new ProviderAPIError('Cart not found after coupon removal', 'BIGCOMMERCE_CART_ERROR');\n return cart;\n }\n\n // ============================================\n // Customer, Order, Payment, Inventory, Admin\n // ============================================\n\n async getOrders(_options: GetOrdersOptions): Promise<Order[]> {\n return [];\n }\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n return [];\n }\n\n async getStockLocations(): Promise<StockLocation[]> { return []; }\n async checkInventoryLevels(): Promise<InventoryLevel[]> { return []; }\n async validateCartStock(): Promise<StockValidation> { return { allAvailable: true, unavailableItems: [] }; }\n async getFulfillmentOptions(): Promise<FulfillmentOption[]> { return []; }\n\n async cancelOrder(_orderId: string): Promise<Order> {\n throw new ProviderAPIError('Order cancellation requires BigCommerce Management API.', 'BIGCOMMERCE_ADMIN_REQUIRED');\n }\n async createFulfillment(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Fulfillment requires BigCommerce Management API.', 'BIGCOMMERCE_ADMIN_REQUIRED');\n }\n async createRefund(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Refunds require BigCommerce Management API.', 'BIGCOMMERCE_ADMIN_REQUIRED');\n }\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> { return { orders: [], count: 0 }; }\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.channelId,\n name: `BigCommerce Store ${this.storeHash}`,\n platformType: 'bigcommerce',\n requiresProductScoping: false,\n currencyCode: this.currencyCode,\n };\n }\n\n isStorefrontRequired(): boolean { return false; }\n}\n","/**\n * @thorprovider/adapters — WooCommerce Provider\n * Transform functions: WooCommerce Store API responses → @thorprovider/types\n */\n\nimport type {\n Product,\n ProductVariant,\n ProductOption,\n Cart,\n CartItem,\n Collection,\n Money,\n Image,\n Order,\n OrderItem,\n OrderStatus,\n PaymentStatus,\n FulfillmentStatus,\n Customer,\n Address,\n} from '@thorprovider/types';\n\n// ============================================\n// Money & Image Transforms\n// ============================================\n\nfunction transformMoney(amount: string | number | null | undefined, currencyCode: string = 'USD'): Money {\n const numAmount = typeof amount === 'string' ? parseFloat(amount) : (amount ?? 0);\n return {\n amount: isNaN(numAmount) ? '0.00' : numAmount.toFixed(2),\n currencyCode: currencyCode.toUpperCase(),\n };\n}\n\nfunction transformImage(url: string, alt: string = ''): Image {\n return { url, altText: alt, width: 800, height: 800 };\n}\n\n// ============================================\n// Product Transforms (Store API format)\n// ============================================\n\nexport function transformProduct(raw: any, currencyCode: string = 'USD'): Product {\n const images: Image[] = (raw.images ?? []).map((img: any) =>\n transformImage(img.src ?? '', img.alt ?? img.name ?? ''),\n );\n\n const variants: ProductVariant[] = (raw.variations ?? []).map((v: any) => ({\n id: String(v.id),\n title: v.name ?? '',\n availableForSale: v.in_stock !== false,\n price: transformMoney(v.prices?.price ?? v.price, currencyCode),\n compareAtPrice: v.prices?.regular_price\n ? transformMoney(v.prices.regular_price, currencyCode)\n : undefined,\n selectedOptions: (v.attributes ?? []).map((attr: any) => ({\n name: attr.name ?? '',\n value: attr.value ?? '',\n })),\n }));\n\n const options: ProductOption[] = (raw.attributes ?? [])\n .filter((attr: any) => attr.variation === true || attr.has_options === true)\n .map((attr: any) => ({\n id: String(attr.id),\n name: attr.name ?? '',\n values: (attr.terms ?? attr.options ?? []).map((t: any) =>\n typeof t === 'string' ? t : (t.name ?? t.value ?? ''),\n ),\n }));\n\n // WooCommerce Store API prices are in minor units (cents)\n const priceMinor = raw.prices?.price ?? '0';\n const priceDecimalPlaces = raw.prices?.currency_minor_unit ?? 2;\n const priceMajor = (parseInt(priceMinor, 10) / Math.pow(10, priceDecimalPlaces));\n\n return {\n id: String(raw.id),\n handle: raw.slug ?? String(raw.id),\n title: raw.name ?? '',\n description: raw.short_description ?? raw.description ?? '',\n descriptionHtml: raw.description ?? '',\n availableForSale: raw.is_purchasable !== false && raw.is_in_stock !== false,\n featuredImage: images[0] ?? { url: '', altText: '', width: 800, height: 800 },\n images,\n options,\n variants,\n priceRange: {\n minVariantPrice: transformMoney(priceMajor, currencyCode),\n maxVariantPrice: transformMoney(priceMajor, currencyCode),\n },\n seo: {\n title: raw.name ?? '',\n description: raw.short_description?.replace(/<[^>]*>/g, '') ?? '',\n },\n tags: [],\n createdAt: raw.date_created ?? new Date().toISOString(),\n updatedAt: raw.date_modified ?? new Date().toISOString(),\n };\n}\n\n// ============================================\n// Collection Transforms (WooCom categories)\n// ============================================\n\nexport function transformCollection(raw: any): Collection {\n return {\n id: String(raw.id ?? ''),\n handle: raw.slug ?? String(raw.id),\n title: raw.name ?? '',\n description: raw.description ?? '',\n seo: {\n title: raw.name ?? '',\n description: raw.description?.replace(/<[^>]*>/g, '') ?? '',\n },\n updatedAt: new Date().toISOString(),\n path: `/collections/${raw.slug ?? raw.id}`,\n };\n}\n\n// ============================================\n// Cart Transforms (Store API cart format)\n// ============================================\n\nexport function transformCart(raw: any, currencyCode: string = 'USD'): Cart {\n const lines: CartItem[] = (raw.items ?? []).map((item: any) => {\n const minorUnit = item.prices?.currency_minor_unit ?? 2;\n const divisor = Math.pow(10, minorUnit);\n const lineTotal = (parseInt(item.totals?.line_total ?? '0', 10)) / divisor;\n\n return {\n id: item.key ?? String(item.id),\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: transformMoney(lineTotal, currencyCode),\n },\n merchandise: {\n id: String(item.id),\n title: item.name ?? '',\n selectedOptions: (item.variation ?? []).map((v: any) => ({\n name: v.attribute ?? '',\n value: v.value ?? '',\n })),\n product: {\n id: String(item.id),\n handle: item.slug ?? String(item.id),\n title: item.name ?? '',\n featuredImage: item.images?.[0]\n ? transformImage(item.images[0].src, item.images[0].alt ?? '')\n : { url: '', altText: '', width: 800, height: 800 },\n },\n },\n };\n });\n\n const minorUnit = raw.totals?.currency_minor_unit ?? 2;\n const divisor = Math.pow(10, minorUnit);\n const subtotal = (parseInt(raw.totals?.total_items ?? '0', 10)) / divisor;\n const total = (parseInt(raw.totals?.total_price ?? '0', 10)) / divisor;\n\n return {\n id: raw.cart_key ?? undefined,\n checkoutUrl: '', // WooCommerce handles checkout via its own /checkout page\n totalQuantity: raw.items_count ?? lines.reduce((sum, l) => sum + l.quantity, 0),\n cost: {\n subtotalAmount: transformMoney(subtotal, currencyCode),\n totalAmount: transformMoney(total, currencyCode),\n },\n lines,\n };\n}\n\n// ============================================\n// Customer Transforms\n// ============================================\n\nexport function transformCustomer(raw: any): Customer {\n return {\n id: String(raw.id),\n email: raw.email ?? '',\n firstName: raw.first_name ?? '',\n lastName: raw.last_name ?? '',\n phone: raw.billing?.phone ?? '',\n hasAccount: true,\n };\n}\n\nfunction transformWooAddress(raw: any): Address {\n return {\n id: undefined,\n firstName: raw.first_name ?? '',\n lastName: raw.last_name ?? '',\n address1: raw.address_1 ?? '',\n address2: raw.address_2 ?? '',\n city: raw.city ?? '',\n province: raw.state ?? '',\n countryCode: raw.country ?? '',\n postalCode: raw.postcode ?? '',\n phone: raw.phone ?? '',\n company: raw.company ?? '',\n };\n}\n\n// ============================================\n// Order Transforms\n// ============================================\n\nexport function transformOrder(raw: any, currencyCode: string = 'USD'): Order {\n const items: OrderItem[] = (raw.line_items ?? []).map((item: any) => ({\n id: String(item.id),\n title: item.name ?? '',\n quantity: item.quantity ?? 1,\n price: transformMoney(item.price ?? 0, currencyCode),\n total: transformMoney(item.total ?? 0, currencyCode),\n productId: String(item.product_id),\n variantId: item.variation_id ? String(item.variation_id) : undefined,\n }));\n\n const statusMap: Record<string, OrderStatus> = {\n pending: 'pending',\n processing: 'processing',\n 'on-hold': 'pending',\n completed: 'completed',\n cancelled: 'cancelled',\n refunded: 'refunded',\n failed: 'cancelled',\n };\n\n const paymentMap: Record<string, PaymentStatus> = {\n pending: 'pending',\n processing: 'authorized',\n completed: 'paid',\n refunded: 'refunded',\n };\n\n return {\n id: String(raw.id),\n orderNumber: String(raw.number ?? raw.id),\n email: raw.billing?.email ?? '',\n status: statusMap[raw.status] ?? 'pending',\n paymentStatus: paymentMap[raw.status] ?? 'pending',\n fulfillmentStatus: raw.status === 'completed' ? 'fulfilled' : 'unfulfilled',\n items,\n total: transformMoney(raw.total ?? 0, currencyCode),\n subtotal: transformMoney(raw.subtotal ?? 0, currencyCode),\n tax: transformMoney(raw.total_tax ?? 0, currencyCode),\n shipping: transformMoney(raw.shipping_total ?? 0, currencyCode),\n shippingAddress: raw.shipping ? transformWooAddress(raw.shipping) : undefined,\n billingAddress: raw.billing ? transformWooAddress(raw.billing) : undefined,\n createdAt: raw.date_created ?? new Date().toISOString(),\n updatedAt: raw.date_modified ?? new Date().toISOString(),\n };\n}\n","/**\n * @thorprovider/adapters — WooCommerce Provider\n * Implements CommerceProvider for WooCommerce Store API + REST API v3\n *\n * Store API: Unauthenticated, cookie-based sessions — products, cart, checkout\n * REST API v3: Authenticated via Application Passwords — customers, orders\n */\n\nimport type {\n Product,\n GetProductsOptions,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCollectionsOptions,\n ProductCategory,\n GetCategoriesOptions,\n Order,\n GetOrdersOptions,\n Customer,\n Address,\n PaymentMethod,\n PaymentMethodsOptions,\n ShippingMethod,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n StorefrontContext,\n BackendCapabilities,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { WOOCOMMERCE_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\nimport { transformProduct, transformCart, transformCollection, transformOrder } from './transforms';\n\n/**\n * WooCommerce provider configuration\n */\nexport interface WooCommerceProviderConfig extends ProviderConfig {\n /** WordPress site URL (e.g., 'https://mystore.com') */\n url: string;\n /** WooCommerce REST API consumer key (for authenticated operations) */\n consumerKey?: string;\n /** WooCommerce REST API consumer secret (for authenticated operations) */\n consumerSecret?: string;\n /** Default currency code (default: 'USD') */\n currencyCode?: string;\n}\n\nexport class WooCommerceProvider implements CommerceProvider {\n readonly name = 'woocommerce';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = WOOCOMMERCE_CAPABILITIES;\n\n private logger: ReturnType<typeof createLogger>;\n private baseUrl: string;\n private storeApiBase: string;\n private restApiBase: string;\n private currencyCode: string;\n private authHeader?: string;\n\n constructor(config: WooCommerceProviderConfig) {\n this.logger = createLogger('WooCommerceProvider', config.debug);\n this.baseUrl = config.url.replace(/\\/$/, '');\n this.storeApiBase = `${this.baseUrl}/wp-json/wc/store/v1`;\n this.restApiBase = `${this.baseUrl}/wp-json/wc/v3`;\n this.currencyCode = config.currencyCode ?? 'USD';\n\n if (config.consumerKey && config.consumerSecret) {\n this.authHeader = 'Basic ' + btoa(`${config.consumerKey}:${config.consumerSecret}`);\n }\n\n this.logger.info('Initializing WooCommerce Provider', { baseUrl: this.baseUrl });\n }\n\n private async storeApiFetch<T = any>(path: string, init?: RequestInit): Promise<T> {\n const response = await fetch(`${this.storeApiBase}${path}`, {\n ...init,\n headers: { 'Content-Type': 'application/json', ...init?.headers },\n });\n if (!response.ok) {\n throw new ProviderAPIError(`WooCommerce Store API error: ${response.status}`, 'WOOCOMMERCE_API_ERROR', response.status);\n }\n return response.json() as Promise<T>;\n }\n\n private async restApiFetch<T = any>(path: string, init?: RequestInit): Promise<T> {\n if (!this.authHeader) {\n throw new ProviderAPIError('WooCommerce REST API requires consumer key/secret.', 'WOOCOMMERCE_AUTH_REQUIRED');\n }\n const response = await fetch(`${this.restApiBase}${path}`, {\n ...init,\n headers: { 'Content-Type': 'application/json', 'Authorization': this.authHeader, ...init?.headers },\n });\n if (!response.ok) {\n throw new ProviderAPIError(`WooCommerce REST API error: ${response.status}`, 'WOOCOMMERCE_API_ERROR', response.status);\n }\n return response.json() as Promise<T>;\n }\n\n // ============================================\n // Product Operations (Store API)\n // ============================================\n\n async getProduct(handle: string): Promise<Product | undefined> {\n try {\n const products = await this.storeApiFetch<any[]>(`/products?slug=${encodeURIComponent(handle)}`);\n return products[0] ? transformProduct(products[0], this.currencyCode) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n let path = `/products?per_page=${options?.first ?? 20}`;\n if (options?.query) path += `&search=${encodeURIComponent(options.query)}`;\n if (options?.sortKey) {\n const [orderby, order] = options.sortKey.includes('-desc')\n ? [options.sortKey.replace('-desc', ''), 'desc']\n : [options.sortKey.replace('-asc', ''), 'asc'];\n path += `&orderby=${orderby}&order=${order}`;\n }\n const products = await this.storeApiFetch<any[]>(path);\n return products.map((p) => transformProduct(p, this.currencyCode));\n }\n\n async getProductRecommendations(_productId: string): Promise<Product[]> {\n return [];\n }\n\n // ============================================\n // Collection/Category Operations (Store API)\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n try {\n const cats = await this.storeApiFetch<any[]>(`/products/categories?slug=${encodeURIComponent(handle)}`);\n return cats[0] ? transformCollection(cats[0]) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const cats = await this.storeApiFetch<any[]>(`/products/categories?per_page=${options?.limit ?? 50}`);\n return cats.map(transformCollection);\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const products = await this.storeApiFetch<any[]>(\n `/products?category=${encodeURIComponent(handle)}&per_page=${options?.first ?? 20}`,\n );\n return products.map((p) => transformProduct(p, this.currencyCode));\n }\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n return this.getCollection(idOrHandle) as any;\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n return this.getCollections(options) as any;\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n return this.getCollectionProducts(handle, options);\n }\n\n // ============================================\n // Cart Operations (Store API)\n // ============================================\n\n async createCart(): Promise<Cart> {\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n async getCart(_cartId: string): Promise<Cart | undefined> {\n try {\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n } catch {\n return undefined;\n }\n }\n\n async addToCart(_cartId: string, lines: CartLineInput[]): Promise<Cart> {\n for (const line of lines) {\n await this.storeApiFetch('/cart/add-item', {\n method: 'POST',\n body: JSON.stringify({ id: parseInt(line.merchandiseId, 10), quantity: line.quantity }),\n });\n }\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n async removeFromCart(_cartId: string, lineIds: string[]): Promise<Cart> {\n for (const key of lineIds) {\n await this.storeApiFetch('/cart/remove-item', {\n method: 'POST',\n body: JSON.stringify({ key }),\n });\n }\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n async updateCart(_cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n for (const line of lines) {\n await this.storeApiFetch('/cart/update-item', {\n method: 'POST',\n body: JSON.stringify({ key: line.id, quantity: line.quantity }),\n });\n }\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n // ============================================\n // Checkout Operations (Store API)\n // ============================================\n\n async completeCheckout(_cartId: string): Promise<Order> {\n const result = await this.storeApiFetch<any>('/checkout', { method: 'POST', body: JSON.stringify({}) });\n return transformOrder(result, this.currencyCode);\n }\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n return [];\n }\n\n async getRegionCountries(): Promise<import('@thorprovider/types').Country[]> {\n return [];\n }\n\n async addShippingMethod(_cartId: string, methodId: string): Promise<Cart> {\n await this.storeApiFetch('/cart/select-shipping-rate', {\n method: 'POST',\n body: JSON.stringify({ rate_id: methodId }),\n });\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n async initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n // WooCommerce handles payment during checkout POST\n }\n\n async applyDiscountCode(_cartId: string, code: string): Promise<Cart> {\n await this.storeApiFetch('/cart/apply-coupon', {\n method: 'POST',\n body: JSON.stringify({ code }),\n });\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n async removeDiscountCode(_cartId: string, code: string): Promise<Cart> {\n await this.storeApiFetch('/cart/remove-coupon', {\n method: 'POST',\n body: JSON.stringify({ code }),\n });\n const cart = await this.storeApiFetch<any>('/cart');\n return transformCart(cart, this.currencyCode);\n }\n\n // ============================================\n // Customer, Order, Payment, Inventory, Admin\n // ============================================\n\n async getOrders(_options: GetOrdersOptions): Promise<Order[]> {\n return [];\n }\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n return [];\n }\n\n async getStockLocations(): Promise<StockLocation[]> { return []; }\n async checkInventoryLevels(): Promise<InventoryLevel[]> { return []; }\n async validateCartStock(): Promise<StockValidation> { return { allAvailable: true, unavailableItems: [] }; }\n async getFulfillmentOptions(): Promise<FulfillmentOption[]> { return []; }\n\n async cancelOrder(_orderId: string): Promise<Order> {\n throw new ProviderAPIError('Order cancellation requires WooCommerce REST API v3.', 'WOOCOMMERCE_AUTH_REQUIRED');\n }\n async createFulfillment(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Fulfillment requires WooCommerce REST API v3.', 'WOOCOMMERCE_AUTH_REQUIRED');\n }\n async createRefund(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Refunds require WooCommerce REST API v3.', 'WOOCOMMERCE_AUTH_REQUIRED');\n }\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> { return { orders: [], count: 0 }; }\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.baseUrl,\n name: `WooCommerce ${this.baseUrl}`,\n platformType: 'woocommerce',\n requiresProductScoping: false,\n currencyCode: this.currencyCode,\n };\n }\n\n isStorefrontRequired(): boolean { return false; }\n}\n","/**\n * Spree Commerce Transform Functions\n * Converts Spree JSON:API responses to @thorprovider/types\n *\n * Spree uses JSON:API format with `data` arrays containing `id`, `type`, `attributes`, `relationships`.\n * Prices are stored as strings (e.g., \"19.99\").\n */\n\nimport type { Product, ProductVariant, ProductOption, Image, Collection, Cart, CartItem, Order, OrderItem, Customer, Address, Money } from '@thorprovider/types';\n\n// ============================================\n// Money / Price Helpers\n// ============================================\n\nfunction toMoney(amount: string | number, currencyCode: string): Money {\n const num = typeof amount === 'string' ? parseFloat(amount) || 0 : amount;\n return { amount: num.toFixed(2), currencyCode };\n}\n\n// ============================================\n// Product Transforms\n// ============================================\n\nexport function transformProduct(data: any, included: any[] = [], currencyCode: string = 'USD'): Product {\n const attrs = data.attributes ?? data;\n const id = String(data.id ?? '');\n\n // Resolve images from relationships or included\n const images: Image[] = [];\n const imageRels = data.relationships?.images?.data ?? [];\n for (const imgRef of imageRels) {\n const imgIncluded = included.find((i: any) => i.type === 'image' && String(i.id) === String(imgRef.id));\n if (imgIncluded) {\n images.push({\n url: imgIncluded.attributes?.original_url ?? imgIncluded.attributes?.styles?.[0]?.url ?? '',\n altText: imgIncluded.attributes?.alt ?? attrs.name ?? '',\n width: undefined,\n height: undefined,\n });\n }\n }\n\n // If no resolved images, try attributes.images directly\n if (images.length === 0 && Array.isArray(attrs.images)) {\n for (const img of attrs.images) {\n images.push({\n url: img.original_url ?? img.url ?? '',\n altText: img.alt ?? attrs.name ?? '',\n width: undefined,\n height: undefined,\n });\n }\n }\n\n // Resolve variants from relationships or included\n const variants: ProductVariant[] = [];\n const variantRels = data.relationships?.variants?.data ?? [];\n for (const varRef of variantRels) {\n const varIncluded = included.find((i: any) => i.type === 'variant' && String(i.id) === String(varRef.id));\n if (varIncluded) {\n const vAttrs = varIncluded.attributes ?? {};\n variants.push({\n id: String(varIncluded.id),\n title: vAttrs.name ?? vAttrs.sku ?? `Variant ${varIncluded.id}`,\n availableForSale: vAttrs.in_stock !== false && vAttrs.purchasable !== false,\n price: toMoney(vAttrs.price ?? vAttrs.display_price ?? '0', currencyCode),\n compareAtPrice: vAttrs.compare_at_price ? toMoney(vAttrs.compare_at_price, currencyCode) : undefined,\n selectedOptions: (vAttrs.option_values ?? []).map((ov: any) => ({\n name: ov.option_type_name ?? 'Option',\n value: ov.name ?? ov.presentation ?? '',\n })),\n });\n }\n }\n\n // Fallback to default variant if no relationships\n if (variants.length === 0) {\n variants.push({\n id: attrs.default_variant_id ? String(attrs.default_variant_id) : id,\n title: 'Default',\n availableForSale: attrs.in_stock !== false && attrs.purchasable !== false,\n price: toMoney(attrs.price ?? attrs.display_price ?? '0', currencyCode),\n compareAtPrice: attrs.compare_at_price ? toMoney(attrs.compare_at_price, currencyCode) : undefined,\n selectedOptions: [],\n });\n }\n\n // Options from option_types\n const options: ProductOption[] = (attrs.option_types ?? []).map((ot: any) => ({\n id: String(ot.id ?? ot.name ?? ''),\n name: ot.presentation ?? ot.name ?? '',\n values: (ot.option_values ?? []).map((ov: any) => ov.presentation ?? ov.name ?? ''),\n }));\n\n return {\n id,\n handle: attrs.slug ?? id,\n title: attrs.name ?? '',\n description: attrs.description ?? '',\n descriptionHtml: attrs.description ?? '',\n availableForSale: attrs.in_stock !== false && attrs.purchasable !== false,\n priceRange: {\n minVariantPrice: variants.reduce(\n (min, v) => (v.price.amount < min.amount ? v.price : min),\n variants[0]?.price ?? toMoney('0', currencyCode),\n ),\n maxVariantPrice: variants.reduce(\n (max, v) => (v.price.amount > max.amount ? v.price : max),\n variants[0]?.price ?? toMoney('0', currencyCode),\n ),\n },\n variants,\n options,\n images,\n featuredImage: images[0] ?? { url: '', altText: attrs.name ?? '' },\n tags: [],\n seo: {\n title: attrs.meta_title ?? attrs.name ?? '',\n description: attrs.meta_description ?? '',\n },\n updatedAt: attrs.updated_at ?? new Date().toISOString(),\n createdAt: attrs.created_at ?? new Date().toISOString(),\n };\n}\n\n// ============================================\n// Collection Transforms (Spree Taxonomies/Taxons)\n// ============================================\n\nexport function transformCollection(data: any): Collection {\n const attrs = data.attributes ?? data;\n return {\n id: String(data.id ?? ''),\n handle: attrs.permalink ?? attrs.slug ?? String(data.id ?? ''),\n title: attrs.name ?? '',\n description: attrs.description ?? '',\n seo: {\n title: attrs.meta_title ?? attrs.name ?? '',\n description: attrs.meta_description ?? '',\n },\n updatedAt: attrs.updated_at ?? new Date().toISOString(),\n path: `/collections/${attrs.permalink ?? attrs.slug ?? data.id}`,\n };\n}\n\n// ============================================\n// Cart Transforms\n// ============================================\n\nexport function transformCart(data: any, currencyCode: string = 'USD'): Cart {\n const attrs = data.attributes ?? data;\n const items: CartItem[] = (attrs.line_items ?? data.included?.filter((i: any) => i.type === 'line_item') ?? []).map(\n (item: any): CartItem => {\n const itemAttrs = item.attributes ?? item;\n return {\n id: String(item.id ?? itemAttrs.id ?? ''),\n quantity: itemAttrs.quantity ?? 1,\n cost: {\n totalAmount: toMoney(itemAttrs.total ?? itemAttrs.display_total ?? '0', currencyCode),\n },\n merchandise: {\n id: String(itemAttrs.variant_id ?? item.id ?? ''),\n title: itemAttrs.name ?? '',\n selectedOptions: [],\n product: {\n id: String(itemAttrs.product_id ?? ''),\n handle: itemAttrs.slug ?? '',\n title: itemAttrs.name ?? '',\n featuredImage: { url: itemAttrs.image_url ?? '', altText: itemAttrs.name ?? '' },\n },\n },\n };\n },\n );\n\n return {\n id: String(data.id ?? attrs.token ?? ''),\n checkoutUrl: '',\n totalQuantity: items.reduce((sum, i) => sum + i.quantity, 0),\n cost: {\n subtotalAmount: toMoney(attrs.item_total ?? attrs.display_item_total ?? '0', currencyCode),\n totalAmount: toMoney(attrs.total ?? attrs.display_total ?? '0', currencyCode),\n totalTaxAmount: toMoney(attrs.tax_total ?? attrs.display_tax_total ?? '0', currencyCode),\n },\n lines: items,\n };\n}\n\n// ============================================\n// Customer Transforms\n// ============================================\n\nexport function transformCustomer(data: any): Customer {\n const attrs = data.attributes ?? data;\n return {\n id: String(data.id ?? ''),\n email: attrs.email ?? '',\n firstName: attrs.first_name ?? '',\n lastName: attrs.last_name ?? '',\n phone: attrs.phone ?? '',\n hasAccount: true,\n };\n}\n\nfunction transformAddress(addr: any): Address {\n return {\n id: String(addr.id ?? ''),\n firstName: addr.first_name ?? addr.firstname ?? '',\n lastName: addr.last_name ?? addr.lastname ?? '',\n company: addr.company ?? '',\n address1: addr.address1 ?? '',\n address2: addr.address2 ?? '',\n city: addr.city ?? '',\n province: addr.state_name ?? addr.state ?? '',\n postalCode: addr.zipcode ?? addr.zip ?? '',\n countryCode: addr.country_iso ?? addr.country_code ?? '',\n phone: addr.phone ?? '',\n };\n}\n\n// ============================================\n// Order Transforms\n// ============================================\n\nexport function transformOrder(data: any, currencyCode: string = 'USD'): Order {\n const attrs = data.attributes ?? data;\n const items: OrderItem[] = (attrs.line_items ?? []).map((item: any) => ({\n id: String(item.id ?? ''),\n title: item.name ?? '',\n quantity: item.quantity ?? 1,\n price: toMoney(item.price ?? '0', currencyCode),\n total: toMoney(item.total ?? '0', currencyCode),\n productId: String(item.product_id ?? ''),\n variantId: String(item.variant_id ?? ''),\n }));\n\n return {\n id: String(data.id ?? attrs.number ?? ''),\n orderNumber: attrs.number ?? String(data.id ?? ''),\n email: attrs.email ?? '',\n status: (attrs.state === 'complete' ? 'completed' : attrs.state === 'canceled' ? 'cancelled' : 'pending') as any,\n paymentStatus: (attrs.payment_state === 'paid' ? 'paid' : attrs.payment_state === 'balance_due' ? 'pending' : 'pending') as any,\n fulfillmentStatus: (attrs.shipment_state === 'shipped' ? 'fulfilled' : attrs.shipment_state === 'partial' ? 'partially_fulfilled' : 'unfulfilled') as any,\n items,\n total: toMoney(attrs.total ?? '0', currencyCode),\n subtotal: toMoney(attrs.item_total ?? '0', currencyCode),\n tax: toMoney(attrs.tax_total ?? '0', currencyCode),\n shipping: toMoney(attrs.ship_total ?? '0', currencyCode),\n shippingAddress: attrs.ship_address ? transformAddress(attrs.ship_address) : undefined,\n billingAddress: attrs.bill_address ? transformAddress(attrs.bill_address) : undefined,\n createdAt: attrs.created_at ?? new Date().toISOString(),\n updatedAt: attrs.updated_at ?? new Date().toISOString(),\n };\n}\n","/**\n * @thorprovider/adapters — Spree Commerce Provider\n * Implements CommerceProvider for Spree Commerce Storefront API v2\n *\n * Spree uses JSON:API format. Supports guest token + bearer token auth.\n * API base: /api/v2/storefront/\n */\n\nimport type {\n Product,\n GetProductsOptions,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCollectionsOptions,\n ProductCategory,\n GetCategoriesOptions,\n Order,\n GetOrdersOptions,\n Customer,\n Address,\n PaymentMethod,\n PaymentMethodsOptions,\n ShippingMethod,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n StorefrontContext,\n BackendCapabilities,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { SPREE_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\nimport { transformProduct, transformCart, transformCollection, transformOrder } from './transforms';\n\n/**\n * Spree provider configuration\n */\nexport interface SpreeProviderConfig extends ProviderConfig {\n /** Spree store base URL (e.g., 'https://myspreestore.com') */\n baseUrl: string;\n /** Bearer token for authenticated operations (customer or OAuth) */\n bearerToken?: string;\n /** Default currency code (default: 'USD') */\n currencyCode?: string;\n}\n\nexport class SpreeProvider implements CommerceProvider {\n readonly name = 'spree';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = SPREE_CAPABILITIES;\n\n private logger: ReturnType<typeof createLogger>;\n private baseUrl: string;\n private apiBase: string;\n private currencyCode: string;\n private bearerToken?: string;\n private orderToken?: string; // guest cart token\n\n constructor(config: SpreeProviderConfig) {\n this.logger = createLogger('SpreeProvider', config.debug);\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.apiBase = `${this.baseUrl}/api/v2/storefront`;\n this.currencyCode = config.currencyCode ?? 'USD';\n this.bearerToken = config.bearerToken;\n\n this.logger.info('Initializing Spree Provider', { baseUrl: this.baseUrl });\n }\n\n private async apiFetch<T = any>(path: string, init?: RequestInit): Promise<{ data: T; included?: any[] }> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/vnd.api+json',\n 'Accept': 'application/vnd.api+json',\n ...((init?.headers as Record<string, string>) ?? {}),\n };\n\n if (this.bearerToken) {\n headers['Authorization'] = `Bearer ${this.bearerToken}`;\n }\n if (this.orderToken) {\n headers['X-Spree-Order-Token'] = this.orderToken;\n }\n\n const response = await fetch(`${this.apiBase}${path}`, {\n ...init,\n headers,\n });\n\n if (!response.ok) {\n throw new ProviderAPIError(\n `Spree API error: ${response.status}`,\n 'SPREE_API_ERROR',\n response.status,\n );\n }\n\n return response.json() as Promise<{ data: T; included?: any[] }>;\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n async getProduct(handle: string): Promise<Product | undefined> {\n try {\n const { data, included } = await this.apiFetch<any>(\n `/products/${encodeURIComponent(handle)}?include=images,variants,option_types`,\n );\n return transformProduct(data, included ?? [], this.currencyCode);\n } catch {\n return undefined;\n }\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n let path = `/products?include=images,variants&per_page=${options?.first ?? 20}`;\n if (options?.query) path += `&filter[name]=${encodeURIComponent(options.query)}`;\n if (options?.sortKey) {\n const sortMap: Record<string, string> = {\n 'price-asc': 'price',\n 'price-desc': '-price',\n 'title-asc': 'name',\n 'title-desc': '-name',\n 'created-desc': '-created_at',\n };\n if (sortMap[options.sortKey]) path += `&sort=${sortMap[options.sortKey]}`;\n }\n\n const { data, included } = await this.apiFetch<any[]>(path);\n return (Array.isArray(data) ? data : []).map((p) => transformProduct(p, included ?? [], this.currencyCode));\n }\n\n async getProductRecommendations(_productId: string): Promise<Product[]> {\n return [];\n }\n\n // ============================================\n // Collection/Taxon Operations\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n try {\n const { data } = await this.apiFetch<any>(`/taxons/${encodeURIComponent(handle)}`);\n return transformCollection(data);\n } catch {\n return undefined;\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const { data } = await this.apiFetch<any[]>(`/taxons?per_page=${options?.limit ?? 50}`);\n return (Array.isArray(data) ? data : []).map(transformCollection);\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const { data, included } = await this.apiFetch<any[]>(\n `/products?include=images,variants&filter[taxons]=${encodeURIComponent(handle)}&per_page=${options?.first ?? 20}`,\n );\n return (Array.isArray(data) ? data : []).map((p) => transformProduct(p, included ?? [], this.currencyCode));\n }\n\n async getCategory(handle: string): Promise<ProductCategory | undefined> {\n return this.getCollection(handle) as any;\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n return this.getCollections(options) as any;\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n return this.getCollectionProducts(handle, options);\n }\n\n // ============================================\n // Cart Operations\n // ============================================\n\n async createCart(): Promise<Cart> {\n const { data } = await this.apiFetch<any>('/cart', {\n method: 'POST',\n body: JSON.stringify({}),\n });\n\n // Store order token for guest operations\n if (data.attributes?.token) {\n this.orderToken = data.attributes.token;\n }\n\n return transformCart(data, this.currencyCode);\n }\n\n async getCart(_cartId: string): Promise<Cart | undefined> {\n try {\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n } catch {\n return undefined;\n }\n }\n\n async addToCart(_cartId: string, lines: CartLineInput[]): Promise<Cart> {\n for (const line of lines) {\n await this.apiFetch('/cart/add_item', {\n method: 'POST',\n body: JSON.stringify({ variant_id: line.merchandiseId, quantity: line.quantity }),\n });\n }\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n }\n\n async removeFromCart(_cartId: string, lineIds: string[]): Promise<Cart> {\n for (const id of lineIds) {\n await this.apiFetch(`/cart/remove_line_item/${id}`, { method: 'DELETE' });\n }\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n }\n\n async updateCart(_cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n for (const line of lines) {\n await this.apiFetch(`/cart/set_quantity`, {\n method: 'PATCH',\n body: JSON.stringify({ line_item_id: line.id, quantity: line.quantity }),\n });\n }\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n }\n\n // ============================================\n // Checkout Operations\n // ============================================\n\n async completeCheckout(_cartId: string): Promise<Order> {\n const { data } = await this.apiFetch<any>('/checkout/complete', { method: 'PATCH' });\n return transformOrder(data, this.currencyCode);\n }\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n try {\n const { data } = await this.apiFetch<any[]>('/checkout/shipping_rates');\n return (Array.isArray(data) ? data : []).map((rate: any) => ({\n id: String(rate.id),\n name: rate.attributes?.name ?? rate.name ?? '',\n price: { amount: String(parseFloat(rate.attributes?.final_price ?? rate.attributes?.cost ?? '0').toFixed(2)), currencyCode: this.currencyCode },\n }));\n } catch {\n return [];\n }\n }\n\n async getRegionCountries(): Promise<import('@thorprovider/types').Country[]> {\n return [];\n }\n\n async addShippingMethod(_cartId: string, methodId: string): Promise<Cart> {\n await this.apiFetch('/checkout', {\n method: 'PATCH',\n body: JSON.stringify({ order: { shipments_attributes: [{ selected_shipping_rate_id: methodId }] } }),\n });\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n }\n\n async initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n // Spree handles payments via checkout advance\n }\n\n async applyDiscountCode(_cartId: string, code: string): Promise<Cart> {\n await this.apiFetch('/cart/apply_coupon_code', {\n method: 'PATCH',\n body: JSON.stringify({ coupon_code: code }),\n });\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n }\n\n async removeDiscountCode(_cartId: string, code: string): Promise<Cart> {\n await this.apiFetch(`/cart/remove_coupon_code/${encodeURIComponent(code)}`, { method: 'DELETE' });\n const { data } = await this.apiFetch<any>('/cart?include=line_items');\n return transformCart(data, this.currencyCode);\n }\n\n // ============================================\n // Customer, Order, Payment, Inventory, Admin\n // ============================================\n\n async getOrders(_options: GetOrdersOptions): Promise<Order[]> {\n try {\n const { data } = await this.apiFetch<any[]>('/account/orders');\n return (Array.isArray(data) ? data : []).map((o) => transformOrder(o, this.currencyCode));\n } catch {\n return [];\n }\n }\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n try {\n const { data } = await this.apiFetch<any[]>('/checkout/payment_methods');\n return (Array.isArray(data) ? data : []).map((pm: any) => ({\n id: String(pm.id),\n name: pm.attributes?.name ?? '',\n type: 'other' as const,\n isEnabled: true,\n requiresSetup: false,\n }));\n } catch {\n return [];\n }\n }\n\n async getStockLocations(): Promise<StockLocation[]> { return []; }\n async checkInventoryLevels(): Promise<InventoryLevel[]> { return []; }\n async validateCartStock(): Promise<StockValidation> { return { allAvailable: true, unavailableItems: [] }; }\n async getFulfillmentOptions(): Promise<FulfillmentOption[]> { return []; }\n\n async cancelOrder(_orderId: string): Promise<Order> {\n throw new ProviderAPIError('Order cancellation requires Spree Admin API.', 'SPREE_ADMIN_REQUIRED');\n }\n async createFulfillment(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Fulfillment requires Spree Admin API.', 'SPREE_ADMIN_REQUIRED');\n }\n async createRefund(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Refunds require Spree Admin API.', 'SPREE_ADMIN_REQUIRED');\n }\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> { return { orders: [], count: 0 }; }\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.baseUrl,\n name: `Spree ${this.baseUrl}`,\n platformType: 'spree',\n requiresProductScoping: true,\n currencyCode: this.currencyCode,\n };\n }\n\n isStorefrontRequired(): boolean { return true; }\n}\n","/**\n * Adobe Commerce (Magento) Transform Functions\n * Converts Magento GraphQL / REST API responses to @thorprovider/types\n *\n * Magento returns price as { regularPrice: { amount: { value, currency } } }\n * Images have url + label directly.\n */\n\nimport type { Product, ProductVariant, ProductOption, Image, Collection, Cart, CartItem, Order, OrderItem, Customer, Address, Money } from '@thorprovider/types';\n\n// ============================================\n// Money / Price Helpers\n// ============================================\n\nfunction toMoney(value: number | undefined, currencyCode: string): Money {\n return { amount: (value ?? 0).toFixed(2), currencyCode };\n}\n\nfunction extractPrice(priceRange: any, currencyCode: string): { min: Money; max: Money } {\n const minPrice = priceRange?.minimum_price?.regular_price?.value ?? priceRange?.minimum_price?.final_price?.value ?? 0;\n const maxPrice = priceRange?.maximum_price?.regular_price?.value ?? priceRange?.maximum_price?.final_price?.value ?? minPrice;\n const currency = priceRange?.minimum_price?.regular_price?.currency ?? currencyCode;\n return {\n min: toMoney(minPrice, currency),\n max: toMoney(maxPrice, currency),\n };\n}\n\n// ============================================\n// Product Transforms\n// ============================================\n\nexport function transformProduct(data: any, currencyCode: string = 'USD'): Product {\n const id = String(data.id ?? data.uid ?? '');\n const { min, max } = extractPrice(data.price_range, currencyCode);\n\n // Images\n const images: Image[] = (data.media_gallery ?? data.media_gallery_entries ?? []).map((img: any) => ({\n url: img.url ?? (img.file ? `${img.file}` : ''),\n altText: img.label ?? data.name ?? '',\n width: undefined,\n height: undefined,\n }));\n\n // Small image fallback\n if (images.length === 0 && data.small_image?.url) {\n images.push({ url: data.small_image.url, altText: data.small_image.label ?? data.name ?? '' });\n }\n if (images.length === 0 && data.image?.url) {\n images.push({ url: data.image.url, altText: data.image.label ?? data.name ?? '' });\n }\n\n // Variants from configurable_options / variants\n const variants: ProductVariant[] = [];\n if (data.variants && Array.isArray(data.variants)) {\n for (const v of data.variants) {\n const product = v.product ?? {};\n const vPrice = product.price_range?.minimum_price?.final_price ?? {};\n variants.push({\n id: String(product.id ?? product.uid ?? product.sku ?? ''),\n title: product.name ?? product.sku ?? '',\n availableForSale: product.stock_status === 'IN_STOCK',\n price: toMoney(vPrice.value ?? min.amount, vPrice.currency ?? currencyCode),\n compareAtPrice: undefined,\n selectedOptions: (v.attributes ?? []).map((attr: any) => ({\n name: attr.label ?? '',\n value: attr.value_index != null ? String(attr.value_index) : '',\n })),\n });\n }\n }\n\n // Default variant if simple product\n if (variants.length === 0) {\n variants.push({\n id: data.sku ?? id,\n title: data.name ?? '',\n availableForSale: data.stock_status === 'IN_STOCK',\n price: min,\n compareAtPrice: undefined,\n selectedOptions: [],\n });\n }\n\n // Options\n const options: ProductOption[] = (data.configurable_options ?? []).map((opt: any) => ({\n id: String(opt.attribute_id ?? opt.attribute_code ?? ''),\n name: opt.label ?? opt.attribute_code ?? '',\n values: (opt.values ?? []).map((v: any) => v.label ?? v.store_label ?? String(v.value_index ?? '')),\n }));\n\n return {\n id,\n handle: data.url_key ?? data.sku ?? id,\n title: data.name ?? '',\n description: data.short_description?.html ?? data.description?.html ?? '',\n descriptionHtml: data.description?.html ?? '',\n availableForSale: data.stock_status === 'IN_STOCK',\n priceRange: { minVariantPrice: min, maxVariantPrice: max },\n variants,\n options,\n images,\n featuredImage: images[0] ?? { url: '', altText: data.name ?? '' },\n tags: [],\n seo: {\n title: data.meta_title ?? data.name ?? '',\n description: data.meta_description ?? '',\n },\n updatedAt: data.updated_at ?? new Date().toISOString(),\n createdAt: data.created_at ?? new Date().toISOString(),\n };\n}\n\n// ============================================\n// Collection Transforms (Magento Categories)\n// ============================================\n\nexport function transformCollection(data: any): Collection {\n return {\n id: String(data.id ?? data.uid ?? ''),\n handle: data.url_key ?? data.url_path ?? String(data.id ?? data.uid ?? ''),\n title: data.name ?? '',\n description: data.description ?? '',\n seo: {\n title: data.meta_title ?? data.name ?? '',\n description: data.meta_description ?? '',\n },\n updatedAt: data.updated_at ?? new Date().toISOString(),\n path: `/collections/${data.url_key ?? data.url_path ?? data.id}`,\n };\n}\n\n// ============================================\n// Cart Transforms (Magento Cart / Quote)\n// ============================================\n\nexport function transformCart(data: any, currencyCode: string = 'USD'): Cart {\n const items: CartItem[] = (data.items ?? []).map((item: any): CartItem => {\n const product = item.product ?? {};\n const priceVal = item.prices?.price?.value ?? product.price_range?.minimum_price?.final_price?.value ?? 0;\n const totalVal = item.prices?.row_total?.value ?? priceVal * (item.quantity ?? 1);\n\n return {\n id: String(item.id ?? item.uid ?? ''),\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: toMoney(totalVal, item.prices?.price?.currency ?? currencyCode),\n },\n merchandise: {\n id: String(product.sku ?? item.id ?? ''),\n title: product.name ?? item.product?.name ?? '',\n selectedOptions: (item.configurable_options ?? []).map((opt: any) => ({\n name: opt.option_label ?? '',\n value: opt.value_label ?? '',\n })),\n product: {\n id: String(product.id ?? product.uid ?? ''),\n handle: product.url_key ?? '',\n title: product.name ?? '',\n featuredImage: {\n url: product.small_image?.url ?? product.thumbnail?.url ?? '',\n altText: product.name ?? '',\n },\n },\n },\n };\n });\n\n const totalVal = data.prices?.grand_total?.value ?? 0;\n const subtotalVal = data.prices?.subtotal_excluding_tax?.value ?? data.prices?.subtotal_including_tax?.value ?? totalVal;\n const taxVal = (data.prices?.applied_taxes ?? []).reduce((sum: number, t: any) => sum + (t.amount?.value ?? 0), 0);\n\n return {\n id: String(data.id ?? ''),\n checkoutUrl: '',\n totalQuantity: items.reduce((sum, i) => sum + i.quantity, 0),\n cost: {\n subtotalAmount: toMoney(subtotalVal, data.prices?.grand_total?.currency ?? currencyCode),\n totalAmount: toMoney(totalVal, data.prices?.grand_total?.currency ?? currencyCode),\n totalTaxAmount: toMoney(taxVal, currencyCode),\n },\n lines: items,\n };\n}\n\n// ============================================\n// Customer Transforms\n// ============================================\n\nexport function transformCustomer(data: any): Customer {\n return {\n id: String(data.id ?? ''),\n email: data.email ?? '',\n firstName: data.firstname ?? data.first_name ?? '',\n lastName: data.lastname ?? data.last_name ?? '',\n phone: data.phone ?? '',\n hasAccount: true,\n };\n}\n\nfunction transformAddress(addr: any): Address {\n return {\n id: String(addr.id ?? ''),\n firstName: addr.firstname ?? '',\n lastName: addr.lastname ?? '',\n company: addr.company ?? '',\n address1: Array.isArray(addr.street) ? addr.street[0] ?? '' : addr.street ?? '',\n address2: Array.isArray(addr.street) ? addr.street[1] ?? '' : '',\n city: addr.city ?? '',\n province: addr.region?.region ?? '',\n postalCode: addr.postcode ?? '',\n countryCode: addr.country_code ?? addr.country_id ?? '',\n phone: addr.telephone ?? '',\n };\n}\n\n// ============================================\n// Order Transforms\n// ============================================\n\nexport function transformOrder(data: any, currencyCode: string = 'USD'): Order {\n const items: OrderItem[] = (data.items ?? []).map((item: any) => ({\n id: String(item.id ?? ''),\n title: item.product_name ?? '',\n quantity: item.quantity_ordered ?? item.quantity ?? 1,\n price: toMoney(item.product_sale_price?.value ?? item.price ?? 0, currencyCode),\n total: toMoney((item.product_sale_price?.value ?? item.price ?? 0) * (item.quantity_ordered ?? item.quantity ?? 1), currencyCode),\n sku: item.product_sku ?? item.sku,\n productId: String(item.product_id ?? ''),\n }));\n\n return {\n id: String(data.id ?? data.order_number ?? ''),\n orderNumber: data.order_number ?? data.number ?? String(data.id ?? ''),\n email: data.email ?? '',\n status: (data.status === 'complete' ? 'completed' : data.status === 'canceled' ? 'cancelled' : data.status === 'closed' ? 'refunded' : 'pending') as any,\n paymentStatus: (data.payment_status === 'paid' ? 'paid' : 'pending') as any,\n fulfillmentStatus: (data.shipment_status === 'shipped' ? 'fulfilled' : 'unfulfilled') as any,\n items,\n total: toMoney(data.total?.grand_total?.value ?? data.grand_total ?? 0, currencyCode),\n subtotal: toMoney(data.total?.subtotal?.value ?? data.subtotal ?? 0, currencyCode),\n tax: toMoney(data.total?.total_tax?.value ?? data.tax_amount ?? 0, currencyCode),\n shipping: toMoney(data.total?.total_shipping?.value ?? data.shipping_amount ?? 0, currencyCode),\n shippingAddress: data.shipping_address ? transformAddress(data.shipping_address) : undefined,\n billingAddress: data.billing_address ? transformAddress(data.billing_address) : undefined,\n createdAt: data.order_date ?? data.created_at ?? new Date().toISOString(),\n updatedAt: data.updated_at ?? data.order_date ?? new Date().toISOString(),\n };\n}\n","/**\n * Magento GraphQL Queries for Storefront\n * Used by MagentoProvider to query products, categories, cart, and customer data.\n */\n\nexport const PRODUCT_FIELDS = `\n id\n uid\n sku\n name\n url_key\n stock_status\n short_description { html }\n description { html }\n meta_title\n meta_description\n created_at\n updated_at\n price_range {\n minimum_price {\n regular_price { value currency }\n final_price { value currency }\n }\n maximum_price {\n regular_price { value currency }\n final_price { value currency }\n }\n }\n small_image { url label }\n image { url label }\n media_gallery {\n url\n label\n }\n ... on ConfigurableProduct {\n configurable_options {\n attribute_code\n attribute_id\n label\n values {\n label\n value_index\n }\n }\n variants {\n product {\n id uid sku name\n stock_status\n price_range {\n minimum_price {\n final_price { value currency }\n }\n }\n small_image { url label }\n }\n attributes {\n label\n value_index\n }\n }\n }\n`;\n\nexport const GET_PRODUCTS = `\n query GetProducts($search: String, $pageSize: Int, $currentPage: Int, $sort: ProductAttributeSortInput) {\n products(search: $search, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {\n items { ${PRODUCT_FIELDS} }\n total_count\n }\n }\n`;\n\nexport const GET_PRODUCT_BY_URL_KEY = `\n query GetProductByUrlKey($urlKey: String!) {\n products(filter: { url_key: { eq: $urlKey } }, pageSize: 1) {\n items { ${PRODUCT_FIELDS} }\n }\n }\n`;\n\nexport const GET_CATEGORIES = `\n query GetCategories($pageSize: Int) {\n categories(pageSize: $pageSize) {\n items {\n id uid name url_key url_path description meta_title meta_description\n }\n }\n }\n`;\n\nexport const GET_CATEGORY_BY_URL_KEY = `\n query GetCategoryByUrlKey($urlKey: String!) {\n categories(filters: { url_key: { eq: $urlKey } }, pageSize: 1) {\n items {\n id uid name url_key url_path description meta_title meta_description\n }\n }\n }\n`;\n\nexport const GET_CATEGORY_PRODUCTS = `\n query GetCategoryProducts($urlKey: String!, $pageSize: Int) {\n products(filter: { category_url_key: { eq: $urlKey } }, pageSize: $pageSize) {\n items { ${PRODUCT_FIELDS} }\n total_count\n }\n }\n`;\n\nexport const GET_CART = `\n query GetCart($cartId: String!) {\n cart(cart_id: $cartId) {\n id\n items {\n id uid quantity\n product {\n id uid sku name url_key\n small_image { url }\n thumbnail { url }\n price_range {\n minimum_price {\n final_price { value currency }\n }\n }\n }\n prices {\n price { value currency }\n row_total { value currency }\n }\n ... on ConfigurableCartItem {\n configurable_options {\n option_label\n value_label\n }\n }\n }\n prices {\n grand_total { value currency }\n subtotal_excluding_tax { value currency }\n subtotal_including_tax { value currency }\n applied_taxes {\n amount { value currency }\n label\n }\n }\n }\n }\n`;\n\nexport const CREATE_EMPTY_CART = `\n mutation CreateEmptyCart {\n createEmptyCart\n }\n`;\n\nexport const ADD_TO_CART = `\n mutation AddToCart($cartId: String!, $cartItems: [CartItemInput!]!) {\n addProductsToCart(cartId: $cartId, cartItems: $cartItems) {\n cart {\n id\n items { id uid quantity product { sku name } prices { price { value currency } row_total { value currency } } }\n prices { grand_total { value currency } subtotal_excluding_tax { value currency } }\n }\n user_errors { code message }\n }\n }\n`;\n\nexport const REMOVE_FROM_CART = `\n mutation RemoveFromCart($cartId: String!, $cartItemUid: ID!) {\n removeItemFromCart(input: { cart_id: $cartId, cart_item_uid: $cartItemUid }) {\n cart {\n id\n items { id uid quantity product { sku name } prices { price { value currency } row_total { value currency } } }\n prices { grand_total { value currency } subtotal_excluding_tax { value currency } }\n }\n }\n }\n`;\n\nexport const UPDATE_CART_ITEMS = `\n mutation UpdateCartItems($cartId: String!, $cartItems: [CartItemUpdateInput!]!) {\n updateCartItems(input: { cart_id: $cartId, cart_items: $cartItems }) {\n cart {\n id\n items { id uid quantity product { sku name } prices { price { value currency } row_total { value currency } } }\n prices { grand_total { value currency } subtotal_excluding_tax { value currency } }\n }\n }\n }\n`;\n\nexport const APPLY_COUPON = `\n mutation ApplyCoupon($cartId: String!, $couponCode: String!) {\n applyCouponToCart(input: { cart_id: $cartId, coupon_code: $couponCode }) {\n cart {\n id\n prices { grand_total { value currency } subtotal_excluding_tax { value currency } }\n }\n }\n }\n`;\n\nexport const REMOVE_COUPON = `\n mutation RemoveCoupon($cartId: String!) {\n removeCouponFromCart(input: { cart_id: $cartId }) {\n cart {\n id\n prices { grand_total { value currency } subtotal_excluding_tax { value currency } }\n }\n }\n }\n`;\n\nexport const GET_CUSTOMER = `\n query GetCustomer {\n customer {\n id\n email\n firstname\n lastname\n addresses {\n id\n firstname lastname company\n street city\n region { region region_code }\n postcode\n country_code\n telephone\n default_shipping\n default_billing\n }\n }\n }\n`;\n\nexport const GET_CUSTOMER_ORDERS = `\n query GetCustomerOrders($pageSize: Int, $currentPage: Int) {\n customer {\n orders(pageSize: $pageSize, currentPage: $currentPage) {\n items {\n id order_number order_date status\n total {\n grand_total { value currency }\n subtotal { value currency }\n total_tax { value currency }\n total_shipping { value currency }\n }\n items {\n id product_name product_sku\n quantity_ordered\n product_sale_price { value currency }\n }\n shipping_address {\n firstname lastname street city\n region postcode country_code telephone\n }\n billing_address {\n firstname lastname street city\n region postcode country_code telephone\n }\n }\n total_count\n }\n }\n }\n`;\n","/**\n * @thorprovider/adapters — Magento (Adobe Commerce) Provider\n * Implements CommerceProvider for Magento 2 GraphQL + REST APIs\n *\n * Uses GraphQL Storefront for read operations (products, categories, cart).\n * REST API for customer/order operations requiring auth tokens.\n * PaaS-first approach (not Adobe IMS/SaaS).\n */\n\nimport type {\n Product,\n GetProductsOptions,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCollectionsOptions,\n ProductCategory,\n GetCategoriesOptions,\n Order,\n GetOrdersOptions,\n Customer,\n Address,\n PaymentMethod,\n PaymentMethodsOptions,\n ShippingMethod,\n StockLocation,\n InventoryLevel,\n StockValidation,\n FulfillmentOption,\n StorefrontContext,\n BackendCapabilities,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { MAGENTO_CAPABILITIES } from '../../types/capabilities.types';\nimport { createLogger } from '../../core/logger';\nimport { ProviderAPIError } from '../../core/errors';\nimport { transformProduct, transformCart, transformCollection, transformOrder, transformCustomer } from './transforms';\nimport {\n GET_PRODUCTS,\n GET_PRODUCT_BY_URL_KEY,\n GET_CATEGORIES,\n GET_CATEGORY_BY_URL_KEY,\n GET_CATEGORY_PRODUCTS,\n GET_CART,\n CREATE_EMPTY_CART,\n ADD_TO_CART,\n REMOVE_FROM_CART,\n UPDATE_CART_ITEMS,\n APPLY_COUPON,\n REMOVE_COUPON,\n GET_CUSTOMER,\n GET_CUSTOMER_ORDERS,\n} from './queries';\n\n/**\n * Magento provider configuration\n */\nexport interface MagentoProviderConfig extends ProviderConfig {\n /** Magento base URL (e.g., 'https://mymagento.com') */\n baseUrl: string;\n /** Store code for multi-tenant (default: 'default') */\n storeCode?: string;\n /** Customer bearer token (for authenticated operations) */\n customerToken?: string;\n /** Integration access token (for admin-level operations) */\n accessToken?: string;\n /** Default currency code (default: 'USD') */\n currencyCode?: string;\n}\n\nexport class MagentoProvider implements CommerceProvider {\n readonly name = 'magento';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = MAGENTO_CAPABILITIES;\n\n private logger: ReturnType<typeof createLogger>;\n private baseUrl: string;\n private storeCode: string;\n private currencyCode: string;\n private graphqlEndpoint: string;\n private customerToken?: string;\n private accessToken?: string;\n\n constructor(config: MagentoProviderConfig) {\n this.logger = createLogger('MagentoProvider', config.debug);\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.storeCode = config.storeCode ?? 'default';\n this.currencyCode = config.currencyCode ?? 'USD';\n this.graphqlEndpoint = `${this.baseUrl}/graphql`;\n this.customerToken = config.customerToken;\n this.accessToken = config.accessToken;\n\n this.logger.info('Initializing Magento Provider', {\n baseUrl: this.baseUrl,\n storeCode: this.storeCode,\n });\n }\n\n private async graphql<T = any>(query: string, variables?: Record<string, any>): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Store': this.storeCode,\n };\n\n if (this.customerToken) {\n headers['Authorization'] = `Bearer ${this.customerToken}`;\n }\n\n const response = await fetch(this.graphqlEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ query, variables }),\n });\n\n if (!response.ok) {\n throw new ProviderAPIError(\n `Magento GraphQL error: ${response.status}`,\n 'MAGENTO_API_ERROR',\n response.status,\n );\n }\n\n const json = await response.json() as { data?: T; errors?: Array<{ message: string }> };\n\n if (json.errors?.length) {\n const message = json.errors.map((e) => e.message).join('; ');\n throw new ProviderAPIError(`Magento GraphQL error: ${message}`, 'MAGENTO_GRAPHQL_ERROR');\n }\n\n return json.data as T;\n }\n\n // ============================================\n // Product Operations (GraphQL)\n // ============================================\n\n async getProduct(handle: string): Promise<Product | undefined> {\n try {\n const data = await this.graphql<{ products: { items: any[] } }>(GET_PRODUCT_BY_URL_KEY, { urlKey: handle });\n return data.products.items[0] ? transformProduct(data.products.items[0], this.currencyCode) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n const variables: Record<string, any> = {\n pageSize: options?.first ?? 20,\n currentPage: 1,\n };\n\n if (options?.query) variables.search = options.query;\n if (options?.sortKey) {\n const sortMap: Record<string, Record<string, string>> = {\n 'price-asc': { price: 'ASC' },\n 'price-desc': { price: 'DESC' },\n 'title-asc': { name: 'ASC' },\n 'title-desc': { name: 'DESC' },\n 'created-desc': { created_at: 'DESC' },\n 'relevance': { relevance: 'DESC' },\n };\n variables.sort = sortMap[options.sortKey] ?? { relevance: 'DESC' };\n }\n\n const data = await this.graphql<{ products: { items: any[] } }>(GET_PRODUCTS, variables);\n return (data.products?.items ?? []).map((p) => transformProduct(p, this.currencyCode));\n }\n\n async getProductRecommendations(_productId: string): Promise<Product[]> {\n return [];\n }\n\n // ============================================\n // Collection/Category Operations (GraphQL)\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n try {\n const data = await this.graphql<{ categories: { items: any[] } }>(GET_CATEGORY_BY_URL_KEY, { urlKey: handle });\n return data.categories.items[0] ? transformCollection(data.categories.items[0]) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const data = await this.graphql<{ categories: { items: any[] } }>(GET_CATEGORIES, {\n pageSize: options?.limit ?? 50,\n });\n return (data.categories?.items ?? []).map(transformCollection);\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const data = await this.graphql<{ products: { items: any[] } }>(GET_CATEGORY_PRODUCTS, {\n urlKey: handle,\n pageSize: options?.first ?? 20,\n });\n return (data.products?.items ?? []).map((p) => transformProduct(p, this.currencyCode));\n }\n\n async getCategory(handle: string): Promise<ProductCategory | undefined> {\n return this.getCollection(handle) as any;\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n return this.getCollections(options) as any;\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n return this.getCollectionProducts(handle, options);\n }\n\n // ============================================\n // Cart Operations (GraphQL)\n // ============================================\n\n async createCart(): Promise<Cart> {\n const data = await this.graphql<{ createEmptyCart: string }>(CREATE_EMPTY_CART);\n const cartId = data.createEmptyCart;\n const cartData = await this.graphql<{ cart: any }>(GET_CART, { cartId });\n return transformCart(cartData.cart ?? { id: cartId, items: [], prices: {} }, this.currencyCode);\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n try {\n const data = await this.graphql<{ cart: any }>(GET_CART, { cartId });\n return data.cart ? transformCart(data.cart, this.currencyCode) : undefined;\n } catch {\n return undefined;\n }\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n const cartItems = lines.map((l) => ({\n sku: l.merchandiseId,\n quantity: l.quantity,\n }));\n\n const data = await this.graphql<{ addProductsToCart: { cart: any; user_errors: any[] } }>(ADD_TO_CART, {\n cartId,\n cartItems,\n });\n\n if (data.addProductsToCart.user_errors?.length) {\n throw new ProviderAPIError(\n `Add to cart failed: ${data.addProductsToCart.user_errors.map((e: any) => e.message).join('; ')}`,\n 'MAGENTO_CART_ERROR',\n );\n }\n\n return transformCart(data.addProductsToCart.cart, this.currencyCode);\n }\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n let cart: any;\n for (const itemUid of lineIds) {\n const data = await this.graphql<{ removeItemFromCart: { cart: any } }>(REMOVE_FROM_CART, {\n cartId,\n cartItemUid: itemUid,\n });\n cart = data.removeItemFromCart.cart;\n }\n return transformCart(cart ?? { id: cartId, items: [], prices: {} }, this.currencyCode);\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n const cartItems = lines.map((l) => ({\n cart_item_uid: l.id,\n quantity: l.quantity,\n }));\n\n const data = await this.graphql<{ updateCartItems: { cart: any } }>(UPDATE_CART_ITEMS, {\n cartId,\n cartItems,\n });\n\n return transformCart(data.updateCartItems.cart, this.currencyCode);\n }\n\n // ============================================\n // Checkout Operations\n // ============================================\n\n async completeCheckout(_cartId: string): Promise<Order> {\n throw new ProviderAPIError(\n 'Magento checkout requires multi-step process (set addresses, shipping, payment, place order). Use the Magento checkout flow.',\n 'MAGENTO_CHECKOUT_MULTI_STEP',\n );\n }\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n return [];\n }\n\n async getRegionCountries(): Promise<import('@thorprovider/types').Country[]> {\n return [];\n }\n\n async addShippingMethod(_cartId: string, _methodId: string): Promise<Cart> {\n throw new ProviderAPIError(\n 'Magento shipping selection requires set-shipping-methods mutation.',\n 'MAGENTO_CHECKOUT_MULTI_STEP',\n );\n }\n\n async initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n // Magento handles payment via set-payment-method mutation\n }\n\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n const data = await this.graphql<{ applyCouponToCart: { cart: any } }>(APPLY_COUPON, {\n cartId,\n couponCode: code,\n });\n return transformCart(data.applyCouponToCart.cart, this.currencyCode);\n }\n\n async removeDiscountCode(cartId: string, _code: string): Promise<Cart> {\n const data = await this.graphql<{ removeCouponFromCart: { cart: any } }>(REMOVE_COUPON, {\n cartId,\n });\n return transformCart(data.removeCouponFromCart.cart, this.currencyCode);\n }\n\n // ============================================\n // Customer & Orders (GraphQL — requires customerToken)\n // ============================================\n\n async getOrders(_options: GetOrdersOptions): Promise<Order[]> {\n if (!this.customerToken) return [];\n try {\n const data = await this.graphql<{ customer: { orders: { items: any[] } } }>(GET_CUSTOMER_ORDERS, {\n pageSize: 20,\n currentPage: 1,\n });\n return (data.customer?.orders?.items ?? []).map((o) => transformOrder(o, this.currencyCode));\n } catch {\n return [];\n }\n }\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n return [];\n }\n\n // ============================================\n // Inventory\n // ============================================\n\n async getStockLocations(): Promise<StockLocation[]> { return []; }\n async checkInventoryLevels(): Promise<InventoryLevel[]> { return []; }\n async validateCartStock(): Promise<StockValidation> { return { allAvailable: true, unavailableItems: [] }; }\n async getFulfillmentOptions(): Promise<FulfillmentOption[]> { return []; }\n\n // ============================================\n // Admin Operations\n // ============================================\n\n async cancelOrder(_orderId: string): Promise<Order> {\n throw new ProviderAPIError('Order cancellation requires Magento Admin API.', 'MAGENTO_ADMIN_REQUIRED');\n }\n async createFulfillment(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Fulfillment requires Magento Admin API.', 'MAGENTO_ADMIN_REQUIRED');\n }\n async createRefund(_orderId: string): Promise<void> {\n throw new ProviderAPIError('Refunds require Magento Admin API.', 'MAGENTO_ADMIN_REQUIRED');\n }\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> { return { orders: [], count: 0 }; }\n\n // ============================================\n // Storefront / Multi-Tenant\n // ============================================\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.storeCode,\n name: `Magento ${this.storeCode}`,\n platformType: 'magento',\n requiresProductScoping: true,\n currencyCode: this.currencyCode,\n };\n }\n\n isStorefrontRequired(): boolean { return true; }\n}\n","import type {\n Collection,\n Customer,\n Address,\n FulfillmentStatus,\n Image,\n InventoryLevel,\n Money,\n Order,\n OrderItem,\n OrderStatus,\n PaymentMethod,\n PaymentMethodType,\n PaymentStatus,\n Product,\n ProductCategory,\n ProductVariant,\n ShippingMethod,\n StockLocation,\n} from '@thorprovider/types';\n\nexport interface StelResource {\n id?: number;\n path?: string;\n deleted?: boolean;\n 'utc-last-modification-date'?: string;\n}\n\nexport interface StelItemImage {\n 'item-image-path'?: string;\n order?: number;\n}\n\nexport interface StelItemRate {\n 'rate-id'?: number;\n 'rate-path'?: string;\n price?: number;\n}\n\nexport interface StelProductWarehouse {\n 'warehouse-id'?: number;\n 'warehouse-path'?: string;\n 'minimum-stock'?: number;\n 'real-stock'?: number;\n 'virtual-stock'?: number;\n location?: string;\n}\n\nexport interface StelProduct extends StelResource {\n name?: string;\n description?: string;\n reference?: string;\n 'full-reference'?: string;\n barcode?: string;\n 'sales-price'?: number;\n 'purchase-price'?: number;\n 'product-category-id'?: number;\n 'product-category-path'?: string;\n 'real-stock'?: number;\n 'virtual-stock'?: number;\n 'minimum-stock'?: number;\n 'stock-enabled'?: boolean;\n inactive?: boolean;\n promotional?: boolean;\n 'creation-date'?: string;\n 'item-images'?: StelItemImage[];\n 'item-rates'?: StelItemRate[];\n 'product-warehouses'?: StelProductWarehouse[];\n}\n\nexport interface StelProductCategory extends StelResource {\n name?: string;\n description?: string;\n slug?: string;\n 'parent-category-id'?: number;\n}\n\nexport interface StelClient extends StelResource {\n name?: string;\n 'business-name'?: string;\n email?: string;\n phone?: string;\n mobile?: string;\n 'rate-id'?: number;\n 'payment-option-id'?: number;\n 'payment-term-id'?: number;\n 'delivery-option-id'?: number;\n 'main-address'?: StelAddress;\n}\n\nexport interface StelAddress extends StelResource {\n name?: string;\n 'first-name'?: string;\n 'last-name'?: string;\n company?: string;\n 'address-data'?: string;\n 'postal-code'?: string;\n 'city-town'?: string;\n province?: string;\n 'country-code'?: string;\n phone?: string;\n email?: string;\n}\n\nexport interface StelDocumentLine {\n 'item-id'?: number;\n 'item-name'?: string;\n 'item-description'?: string;\n 'item-base-price'?: number;\n 'primary-tax-percentage'?: number;\n 'discount-percentage'?: number;\n units?: number;\n 'line-type'?: 'ITEM' | 'DOCUMENT' | 'SECTION' | 'COMPONENT';\n}\n\nexport interface StelSalesOrder extends StelResource {\n reference?: string;\n status?: string;\n email?: string;\n 'client-id'?: number;\n 'payment-option-id'?: number;\n 'payment-term-id'?: number;\n 'delivery-option-id'?: number;\n 'creation-date'?: string;\n 'total-base'?: number;\n 'total-tax'?: number;\n total?: number;\n 'document-lines'?: StelDocumentLine[];\n}\n\nexport interface StelPaymentOption extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport interface StelPaymentTerm extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport interface StelDeliveryOption extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport interface StelWarehouse extends StelResource {\n name?: string;\n description?: string;\n}\n\nexport function normalizeStelCollection<T>(payload: T | T[] | null | undefined): T[] {\n if (!payload) {\n return [];\n }\n\n return Array.isArray(payload) ? payload : [payload];\n}\n\nexport function normalizeStelEntity<T>(payload: T | T[] | null | undefined): T | undefined {\n if (!payload) {\n return undefined;\n }\n\n return Array.isArray(payload) ? payload[0] : payload;\n}\n\nexport function transformStelMoney(\n amount: number | string | null | undefined,\n currencyCode: string = 'USD',\n): Money {\n const normalizedAmount = typeof amount === 'string' ? Number.parseFloat(amount) : amount ?? 0;\n\n return {\n amount: Number.isFinite(normalizedAmount) ? normalizedAmount.toFixed(2) : '0.00',\n currencyCode: currencyCode.toUpperCase(),\n };\n}\n\nexport function transformStelImage(url: string | null | undefined, altText: string = ''): Image | undefined {\n const normalizedUrl = url?.trim();\n\n if (!normalizedUrl) {\n return undefined;\n }\n\n return {\n url: normalizedUrl,\n altText,\n width: 800,\n height: 800,\n };\n}\n\nexport function normalizeStelDate(value: string | null | undefined): string {\n if (!value) {\n return new Date().toISOString();\n }\n\n const parsed = new Date(value);\n return Number.isNaN(parsed.getTime()) ? new Date().toISOString() : parsed.toISOString();\n}\n\nexport function extractStelIdFromPath(path: string | null | undefined): string | undefined {\n if (!path) {\n return undefined;\n }\n\n const match = path.match(/\\/([^/]+)$/);\n return match?.[1];\n}\n\nexport function toStelStringId(value: string | number | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n return String(value);\n}\n\nfunction slugify(value: string): string {\n return value\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nexport function buildStelHandle(...candidates: Array<string | number | null | undefined>): string {\n for (const candidate of candidates) {\n if (candidate === null || candidate === undefined) {\n continue;\n }\n\n const normalized = slugify(String(candidate).trim());\n if (normalized) {\n return normalized;\n }\n }\n\n return 'stel-item';\n}\n\n// ---------------------------------------------------------------------------\n// Product transforms\n// ---------------------------------------------------------------------------\n\nfunction transformStelProductImages(product: StelProduct): Image[] {\n const images: Image[] = [];\n\n if (!product['item-images']) {\n return images;\n }\n\n const sorted = [...product['item-images']].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n\n for (const img of sorted) {\n const transformed = transformStelImage(img['item-image-path'], product.name ?? '');\n if (transformed) {\n images.push(transformed);\n }\n }\n\n return images;\n}\n\nfunction deriveStelStockStatus(product: StelProduct): 'in_stock' | 'out_of_stock' | 'low_stock' {\n if (!product['stock-enabled']) {\n return 'in_stock';\n }\n\n const realStock = product['real-stock'] ?? 0;\n const minimumStock = product['minimum-stock'] ?? 0;\n\n if (realStock <= 0) {\n return 'out_of_stock';\n }\n\n if (realStock <= minimumStock) {\n return 'low_stock';\n }\n\n return 'in_stock';\n}\n\n/**\n * Build a single synthetic variant from a STEL product.\n * STEL products have no variant concept — every product is a single SKU.\n */\nfunction buildSyntheticVariant(product: StelProduct, currencyCode: string): ProductVariant {\n const price = transformStelMoney(product['sales-price'], currencyCode);\n const stockStatus = deriveStelStockStatus(product);\n const quantityAvailable = product['stock-enabled'] ? (product['real-stock'] ?? 0) : undefined;\n const image = product['item-images']?.[0]\n ? transformStelImage(product['item-images'][0]['item-image-path'], product.name ?? '')\n : undefined;\n\n return {\n id: toStelStringId(product.id),\n title: 'Default',\n sku: product.barcode ?? product['full-reference'] ?? undefined,\n availableForSale: stockStatus !== 'out_of_stock',\n selectedOptions: [],\n price,\n compareAtPrice: undefined,\n quantityAvailable,\n stockStatus,\n image,\n };\n}\n\nexport function transformStelProduct(raw: StelProduct, currencyCode: string): Product {\n const id = toStelStringId(raw.id);\n const handle = buildStelHandle(raw['full-reference'], raw.reference, raw.name, raw.id);\n const price = transformStelMoney(raw['sales-price'], currencyCode);\n const images = transformStelProductImages(raw);\n const variant = buildSyntheticVariant(raw, currencyCode);\n const now = new Date().toISOString();\n\n return {\n id,\n handle,\n title: raw.name ?? '',\n description: raw.description ?? '',\n availableForSale: variant.availableForSale,\n options: [],\n variants: [variant],\n featuredImage: images[0],\n images,\n priceRange: {\n minVariantPrice: price,\n maxVariantPrice: price,\n },\n productType: undefined,\n vendor: undefined,\n tags: raw.promotional ? ['promotional'] : [],\n createdAt: normalizeStelDate(raw['creation-date']),\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']) || now,\n metadata: {\n stelFullReference: raw['full-reference'],\n stelReference: raw.reference,\n stelBarcode: raw.barcode,\n stelCategoryId: raw['product-category-id'],\n stelInactive: raw.inactive,\n stelPromotional: raw.promotional,\n stelPurchasePrice: raw['purchase-price'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Category transforms\n// ---------------------------------------------------------------------------\n\nexport function transformStelCategory(raw: StelProductCategory): ProductCategory {\n const id = toStelStringId(raw.id);\n const handle = buildStelHandle(raw.slug, raw.name, raw.id);\n\n return {\n id,\n name: raw.name ?? '',\n handle,\n description: raw.description ?? undefined,\n parentCategoryId: raw['parent-category-id']\n ? toStelStringId(raw['parent-category-id'])\n : undefined,\n metadata: {\n stelSlug: raw.slug,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Collection transforms (alias categories as collections)\n// ---------------------------------------------------------------------------\n\nexport function transformStelCategoryToCollection(raw: StelProductCategory): Collection {\n const id = toStelStringId(raw.id);\n const handle = buildStelHandle(raw.slug, raw.name, raw.id);\n\n return {\n id,\n handle,\n title: raw.name ?? '',\n description: raw.description ?? '',\n path: `/collections/${handle}`,\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Inventory / warehouse transforms\n// ---------------------------------------------------------------------------\n\nexport function transformStelWarehouseToStockLocation(raw: StelWarehouse): StockLocation {\n return {\n id: toStelStringId(raw.id),\n name: raw.name ?? 'Warehouse',\n };\n}\n\nexport function transformStelProductWarehouseToInventoryLevel(\n pw: StelProductWarehouse,\n): InventoryLevel {\n return {\n locationId: toStelStringId(pw['warehouse-id']),\n locationName: pw['warehouse-path'] ?? `Warehouse ${pw['warehouse-id'] ?? 'unknown'}`,\n availableQuantity: pw['real-stock'] ?? 0,\n reservedQuantity: Math.max(0, (pw['virtual-stock'] ?? 0) - (pw['real-stock'] ?? 0)),\n stockedQuantity: pw['virtual-stock'] ?? pw['real-stock'] ?? 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Customer / Address transforms\n// ---------------------------------------------------------------------------\n\nfunction splitStelName(fullName: string | null | undefined): { firstName: string; lastName: string } {\n if (!fullName?.trim()) {\n return { firstName: '', lastName: '' };\n }\n\n const parts = fullName.trim().split(/\\s+/);\n const firstName = parts[0] ?? '';\n const lastName = parts.length > 1 ? parts.slice(1).join(' ') : '';\n return { firstName, lastName };\n}\n\nexport function transformStelAddress(raw: StelAddress): Address {\n const firstName = raw['first-name'] ?? '';\n const lastName = raw['last-name'] ?? '';\n\n // If first/last not present, attempt to split the 'name' field\n const nameParts = !firstName && !lastName ? splitStelName(raw.name) : { firstName, lastName };\n\n return {\n id: raw.id ? toStelStringId(raw.id) : undefined,\n firstName: nameParts.firstName,\n lastName: nameParts.lastName,\n company: raw.company ?? undefined,\n address1: raw['address-data'] ?? '',\n city: raw['city-town'] ?? '',\n province: raw.province ?? undefined,\n postalCode: raw['postal-code'] ?? '',\n countryCode: raw['country-code'] ?? '',\n phone: raw.phone ?? undefined,\n isDefault: true,\n metadata: {\n stelEmail: raw.email,\n },\n };\n}\n\nexport function transformStelClient(raw: StelClient): Customer {\n const { firstName, lastName } = splitStelName(raw.name ?? raw['business-name']);\n\n return {\n id: toStelStringId(raw.id),\n email: raw.email ?? '',\n firstName: firstName || null,\n lastName: lastName || null,\n phone: raw.phone ?? raw.mobile ?? null,\n hasAccount: true,\n createdAt: normalizeStelDate(raw['utc-last-modification-date']),\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']),\n metadata: {\n stelBusinessName: raw['business-name'],\n stelRateId: raw['rate-id'],\n stelPaymentOptionId: raw['payment-option-id'],\n stelPaymentTermId: raw['payment-term-id'],\n stelDeliveryOptionId: raw['delivery-option-id'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Order transforms\n// ---------------------------------------------------------------------------\n\nfunction deriveStelOrderStatus(raw: StelSalesOrder): OrderStatus {\n if (raw.deleted) {\n return 'cancelled';\n }\n\n const status = (raw.status ?? '').toLowerCase();\n\n if (status.includes('cancel') || status.includes('anulad')) {\n return 'cancelled';\n }\n if (status.includes('complet') || status.includes('cerrad') || status.includes('settled')) {\n return 'completed';\n }\n if (status.includes('process') || status.includes('confirm')) {\n return 'processing';\n }\n\n return 'pending';\n}\n\nfunction deriveStelPaymentStatus(raw: StelSalesOrder): PaymentStatus {\n const orderStatus = deriveStelOrderStatus(raw);\n\n if (orderStatus === 'completed') {\n return 'paid';\n }\n if (orderStatus === 'cancelled') {\n return 'pending';\n }\n\n return 'pending';\n}\n\nfunction deriveStelFulfillmentStatus(raw: StelSalesOrder): FulfillmentStatus {\n const orderStatus = deriveStelOrderStatus(raw);\n\n if (orderStatus === 'completed') {\n return 'fulfilled';\n }\n\n return 'unfulfilled';\n}\n\nfunction transformStelDocumentLine(\n line: StelDocumentLine,\n index: number,\n currencyCode: string,\n): OrderItem {\n const unitPrice = line['item-base-price'] ?? 0;\n const quantity = line.units ?? 1;\n const lineTotal = unitPrice * quantity;\n\n return {\n id: toStelStringId(line['item-id'] ?? index),\n title: line['item-name'] ?? '',\n variantTitle: undefined,\n quantity,\n price: transformStelMoney(unitPrice, currencyCode),\n total: transformStelMoney(lineTotal, currencyCode),\n sku: undefined,\n productId: line['item-id'] ? toStelStringId(line['item-id']) : undefined,\n };\n}\n\nexport function transformStelSalesOrder(raw: StelSalesOrder, currencyCode: string): Order {\n const id = toStelStringId(raw.id);\n const now = new Date().toISOString();\n const items = (raw['document-lines'] ?? [])\n .filter((line) => line['line-type'] === 'ITEM' || !line['line-type'])\n .map((line, i) => transformStelDocumentLine(line, i, currencyCode));\n\n const status = deriveStelOrderStatus(raw);\n\n return {\n id,\n orderNumber: raw.reference ?? id,\n email: raw.email ?? '',\n status,\n paymentStatus: deriveStelPaymentStatus(raw),\n fulfillmentStatus: deriveStelFulfillmentStatus(raw),\n customerId: raw['client-id'] ? toStelStringId(raw['client-id']) : undefined,\n items,\n subtotal: transformStelMoney(raw['total-base'], currencyCode),\n total: transformStelMoney(raw.total, currencyCode),\n tax: raw['total-tax'] != null ? transformStelMoney(raw['total-tax'], currencyCode) : undefined,\n createdAt: normalizeStelDate(raw['creation-date']),\n updatedAt: normalizeStelDate(raw['utc-last-modification-date']) || now,\n cancelledAt: status === 'cancelled' ? normalizeStelDate(raw['utc-last-modification-date']) : undefined,\n completedAt: status === 'completed' ? normalizeStelDate(raw['utc-last-modification-date']) : undefined,\n metadata: {\n stelReference: raw.reference,\n stelStatus: raw.status,\n stelPaymentOptionId: raw['payment-option-id'],\n stelPaymentTermId: raw['payment-term-id'],\n stelDeliveryOptionId: raw['delivery-option-id'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Payment / delivery transforms\n// ---------------------------------------------------------------------------\n\nfunction inferPaymentMethodType(name: string | null | undefined): PaymentMethodType {\n if (!name) {\n return 'other';\n }\n\n const lower = name.toLowerCase();\n\n if (lower.includes('transfer') || lower.includes('bank') || lower.includes('sepa') || lower.includes('iban')) {\n return 'bank_transfer';\n }\n if (lower.includes('card') || lower.includes('tarjeta') || lower.includes('visa') || lower.includes('master')) {\n return 'card';\n }\n if (lower.includes('paypal') || lower.includes('wallet') || lower.includes('apple') || lower.includes('google')) {\n return 'wallet';\n }\n if (lower.includes('cash') || lower.includes('contrar') || lower.includes('efectivo') || lower.includes('cod')) {\n return 'cash_on_delivery';\n }\n if (lower.includes('crypto') || lower.includes('bitcoin')) {\n return 'crypto';\n }\n\n return 'other';\n}\n\nexport function transformStelPaymentOption(raw: StelPaymentOption): PaymentMethod {\n return {\n id: toStelStringId(raw.id),\n name: raw.name ?? 'Payment Option',\n type: inferPaymentMethodType(raw.name),\n isEnabled: !raw.deleted,\n requiresSetup: false,\n description: raw.description ?? undefined,\n metadata: {\n stelPath: raw.path,\n source: 'paymentOption',\n },\n };\n}\n\nexport function transformStelDeliveryOption(raw: StelDeliveryOption, currencyCode: string): ShippingMethod {\n return {\n id: toStelStringId(raw.id),\n name: raw.name ?? 'Delivery Option',\n price: transformStelMoney(0, currencyCode),\n description: raw.description ?? undefined,\n };\n}\n","import type { ProviderConfig } from '../../types/provider';\nimport { ConfigurationError, ProviderAPIError, extractErrorMessage } from '../../core/errors';\nimport { fetchWithRetry, type RetryConfig } from '../../core/fetch-utils';\nimport { createLogger, type Logger } from '../../core/logger';\nimport { normalizeStelCollection, normalizeStelEntity } from './transforms';\n\ntype FetchImplementation = (url: string, init?: RequestInit) => Promise<Response>;\ntype HttpMethod = 'DELETE' | 'GET' | 'POST' | 'PUT';\n\nexport type StelQueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean>;\n\nexport type StelQueryParams = Record<string, StelQueryValue>;\n\nexport interface StelOrderProviderConfig extends ProviderConfig {\n baseUrl: string;\n apiKey?: string;\n publishableKey?: string;\n currencyCode?: string;\n companyName?: string;\n storefrontId?: string;\n retry?: RetryConfig;\n}\n\ntype RequiredRetryConfig = Required<RetryConfig>;\n\nconst DEFAULT_RETRY_CONFIG: RequiredRetryConfig = {\n maxRetries: 2,\n initialDelayMs: 300,\n backoffMultiplier: 2,\n maxDelayMs: 5000,\n timeoutMs: 10000,\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction calculateDelay(attempt: number, retryConfig: RequiredRetryConfig): number {\n const delay = retryConfig.initialDelayMs * Math.pow(retryConfig.backoffMultiplier, attempt);\n return Math.min(delay, retryConfig.maxDelayMs);\n}\n\nfunction isRetryableError(error: unknown, retryConfig: RequiredRetryConfig): boolean {\n if (error instanceof ProviderAPIError) {\n return typeof error.status === 'number' && retryConfig.retryableStatusCodes.includes(error.status);\n }\n\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n message.includes('fetch failed') ||\n message.includes('timeout') ||\n message.includes('econnrefused') ||\n message.includes('etimedout')\n );\n}\n\nfunction createRetryingFetch(\n fetchImplementation: FetchImplementation,\n retryConfig: RequiredRetryConfig,\n logger: Logger,\n): FetchImplementation {\n return async (url: string, init?: RequestInit): Promise<Response> => {\n let lastError: unknown = new Error('Unknown STEL Order request error');\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt += 1) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), retryConfig.timeoutMs);\n\n try {\n const response = await fetchImplementation(url, {\n ...init,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok && retryConfig.retryableStatusCodes.includes(response.status)) {\n throw new ProviderAPIError(\n `STEL Order API error: ${response.status} ${response.statusText}`,\n 'stelorder',\n response.status,\n );\n }\n\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n lastError = error;\n\n if (attempt >= retryConfig.maxRetries || !isRetryableError(error, retryConfig)) {\n throw error;\n }\n\n const delay = calculateDelay(attempt, retryConfig);\n logger.warn('STEL request failed, retrying.', {\n url,\n attempt: attempt + 1,\n maxAttempts: retryConfig.maxRetries + 1,\n nextRetryIn: delay,\n error: extractErrorMessage(error),\n });\n\n await sleep(delay);\n }\n }\n\n throw lastError;\n };\n}\n\nasync function parseErrorResponse(response: Response): Promise<string> {\n const contentType = response.headers.get('content-type') ?? '';\n\n try {\n if (contentType.includes('application/json')) {\n const body = (await response.json()) as unknown;\n const message = extractErrorMessage(body);\n if (message && message !== 'An unknown error occurred') {\n return message;\n }\n }\n } catch {\n // Ignore body parsing issues and fall back to text/status.\n }\n\n try {\n const text = await response.text();\n if (text.trim()) {\n return text.trim();\n }\n } catch {\n // Ignore body parsing issues and fall back to status.\n }\n\n return `STEL Order API error: ${response.status} ${response.statusText}`;\n}\n\nexport function normalizeStelApiBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim();\n\n if (!trimmed) {\n throw new ConfigurationError('Stel Order baseUrl is required.');\n }\n\n const normalized = trimmed\n .replace(/\\/api\\/openapi\\.json$/i, '')\n .replace(/\\/+$/, '');\n\n return normalized.endsWith('/app') ? normalized : `${normalized}/app`;\n}\n\ninterface StelRequestOptions {\n method: HttpMethod;\n path: string;\n query?: StelQueryParams;\n body?: unknown;\n headers?: HeadersInit;\n}\n\nexport class StelOrderClient {\n readonly apiBaseUrl: string;\n\n private readonly apiKey: string;\n private readonly logger: Logger;\n private readonly retryConfig: RequiredRetryConfig;\n private readonly fetchImplementation?: FetchImplementation;\n\n constructor(config: StelOrderProviderConfig) {\n const apiKey = config.apiKey ?? config.publishableKey;\n\n if (!apiKey) {\n throw new ConfigurationError(\n 'Stel Order API key is required. Pass `apiKey` or `publishableKey` to createProvider().',\n );\n }\n\n this.apiBaseUrl = normalizeStelApiBaseUrl(config.baseUrl);\n this.apiKey = apiKey;\n this.logger = createLogger('StelOrderClient', config.debug);\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config.retry,\n };\n this.fetchImplementation = config.customFetch\n ? createRetryingFetch(config.customFetch, this.retryConfig, this.logger)\n : undefined;\n\n this.logger.info('Initializing Stel Order client', {\n apiBaseUrl: this.apiBaseUrl,\n retryConfig: this.retryConfig,\n });\n }\n\n async list<T>(resource: string, query?: StelQueryParams): Promise<T[]> {\n const payload = await this.request<T | T[]>({\n method: 'GET',\n path: resource,\n query,\n });\n\n return normalizeStelCollection(payload);\n }\n\n async getOne<T>(resource: string, id: string | number, query?: StelQueryParams): Promise<T | undefined> {\n const payload = await this.request<T | T[]>({\n method: 'GET',\n path: `${resource}/${id}`,\n query,\n });\n\n return normalizeStelEntity(payload);\n }\n\n async create<TResponse, TBody = unknown>(resource: string, body: TBody): Promise<TResponse> {\n return this.request<TResponse>({\n method: 'POST',\n path: resource,\n body,\n });\n }\n\n async update<TResponse, TBody = unknown>(resource: string, id: string | number, body: TBody): Promise<TResponse> {\n return this.request<TResponse>({\n method: 'PUT',\n path: `${resource}/${id}`,\n body,\n });\n }\n\n async remove(resource: string, id: string | number): Promise<void> {\n await this.request<void>({\n method: 'DELETE',\n path: `${resource}/${id}`,\n });\n }\n\n private buildUrl(path: string, query?: StelQueryParams): string {\n const normalizedPath = path.replace(/^\\/+/, '');\n const url = new URL(`${this.apiBaseUrl}/${normalizedPath}`);\n\n if (!query) {\n return url.toString();\n }\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null || value === '') {\n continue;\n }\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.map(String).join(','));\n continue;\n }\n\n url.searchParams.set(key, String(value));\n }\n\n return url.toString();\n }\n\n private buildHeaders(headers?: HeadersInit, hasBody: boolean = false): Headers {\n const normalizedHeaders = new Headers(headers);\n\n normalizedHeaders.set('Accept', 'application/json');\n normalizedHeaders.set('APIKEY', this.apiKey);\n\n if (hasBody && !normalizedHeaders.has('Content-Type')) {\n normalizedHeaders.set('Content-Type', 'application/json');\n }\n\n return normalizedHeaders;\n }\n\n private async executeFetch(url: string, init: RequestInit): Promise<Response> {\n if (this.fetchImplementation) {\n return this.fetchImplementation(url, init);\n }\n\n return fetchWithRetry(url, init, this.retryConfig);\n }\n\n private async request<TResponse>(options: StelRequestOptions): Promise<TResponse> {\n const url = this.buildUrl(options.path, options.query);\n const hasBody = options.body !== undefined;\n\n this.logger.debug('STEL request', {\n method: options.method,\n url,\n });\n\n const response = await this.executeFetch(url, {\n method: options.method,\n headers: this.buildHeaders(options.headers, hasBody),\n body: hasBody ? JSON.stringify(options.body) : undefined,\n });\n\n if (!response.ok) {\n const message = await parseErrorResponse(response);\n throw new ProviderAPIError(message, 'stelorder', response.status);\n }\n\n if (response.status === 204) {\n return undefined as TResponse;\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as TResponse;\n }\n\n return (await response.text()) as TResponse;\n }\n}\n","import type {\n BackendCapabilities,\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n Country,\n Customer,\n FulfillmentOption,\n GetCategoriesOptions,\n GetCollectionsOptions,\n GetCustomersOptions,\n GetOrdersOptions,\n GetProductsOptions,\n InventoryLevel,\n Order,\n PaymentMethod,\n PaymentMethodsOptions,\n Product,\n ProductCategory,\n ShippingMethod,\n StockLocation,\n StockValidation,\n StorefrontContext,\n} from '@thorprovider/types';\nimport type { CommerceProvider } from '../../types/provider';\nimport { STELORDER_CAPABILITIES } from '../../types/capabilities.types';\nimport { ProviderAPIError } from '../../core/errors';\nimport { createLogger } from '../../core/logger';\nimport { StelOrderClient, type StelOrderProviderConfig } from './client';\nimport {\n buildStelHandle,\n transformStelCategory,\n transformStelCategoryToCollection,\n transformStelClient,\n transformStelDeliveryOption,\n transformStelPaymentOption,\n transformStelProduct,\n transformStelProductWarehouseToInventoryLevel,\n transformStelSalesOrder,\n transformStelWarehouseToStockLocation,\n type StelClient,\n type StelDeliveryOption,\n type StelPaymentOption,\n type StelProduct,\n type StelProductCategory,\n type StelSalesOrder,\n type StelWarehouse,\n} from './transforms';\n\nexport type { StelOrderProviderConfig } from './client';\nexport { StelOrderClient } from './client';\nexport * from './transforms';\n\nexport class StelOrderProvider implements CommerceProvider {\n readonly name = 'stelorder';\n readonly version = '1.0.0';\n readonly capabilities: BackendCapabilities = STELORDER_CAPABILITIES;\n\n private readonly client: StelOrderClient;\n private readonly logger: ReturnType<typeof createLogger>;\n private readonly currencyCode: string;\n private readonly storefrontId: string;\n private readonly companyName: string;\n\n constructor(config: StelOrderProviderConfig) {\n this.client = new StelOrderClient(config);\n this.logger = createLogger('StelOrderProvider', config.debug);\n this.currencyCode = config.currencyCode ?? 'USD';\n this.storefrontId = config.storefrontId ?? 'stelorder-primary';\n this.companyName = config.companyName ?? 'Stel Order';\n\n this.logger.info('Initializing Stel Order provider', {\n storefrontId: this.storefrontId,\n companyName: this.companyName,\n currencyCode: this.currencyCode,\n });\n }\n\n // ============================================\n // Product Operations\n // ============================================\n\n async getProduct(handle: string, _options?: { regionId?: string }): Promise<Product | undefined> {\n this.logger.debug('getProduct', { handle });\n\n try {\n // Attempt direct ID lookup if handle looks numeric\n if (/^\\d+$/.test(handle)) {\n const raw = await this.client.getOne<StelProduct>('products', handle);\n return raw ? transformStelProduct(raw, this.currencyCode) : undefined;\n }\n\n // Otherwise scan products to match by handle (slugified full-reference)\n const rawProducts = await this.client.list<StelProduct>('products', { limit: 100 });\n\n for (const raw of rawProducts) {\n const productHandle = buildStelHandle(raw['full-reference'], raw.reference, raw.name, raw.id);\n if (productHandle === handle) {\n return transformStelProduct(raw, this.currencyCode);\n }\n }\n\n return undefined;\n } catch (error) {\n this.logger.error('getProduct failed', { handle, error });\n throw this.wrapError('getProduct', error);\n }\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n this.logger.debug('getProducts', { options });\n\n try {\n const query: Record<string, string | number | boolean> = {};\n\n if (options?.first) {\n query.limit = options.first;\n }\n if (options?.skip) {\n query.start = options.skip;\n }\n if (typeof options?.after === 'number') {\n query.start = options.after;\n }\n if (options?.sortKey) {\n query.sort = options.reverse ? `-${options.sortKey}` : options.sortKey;\n }\n if (options?.categoryIds?.length) {\n query['product-category-id'] = `in:${options.categoryIds.join(',')}`;\n }\n\n const rawProducts = await this.client.list<StelProduct>('products', query);\n\n let products = rawProducts\n .filter((p) => !p.deleted && !p.inactive)\n .map((p) => transformStelProduct(p, this.currencyCode));\n\n // Client-side text search (STEL has no fulltext search)\n if (options?.query) {\n const needle = options.query.toLowerCase();\n products = products.filter(\n (p) =>\n p.title.toLowerCase().includes(needle) ||\n p.description.toLowerCase().includes(needle) ||\n p.handle.includes(needle),\n );\n }\n\n return products;\n } catch (error) {\n this.logger.error('getProducts failed', { options, error });\n throw this.wrapError('getProducts', error);\n }\n }\n\n async getProductRecommendations(_productId: string): Promise<Product[]> {\n // STEL has no recommendation engine — return empty array\n return [];\n }\n\n // ============================================\n // Category Operations\n // ============================================\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n this.logger.debug('getCategory', { idOrHandle });\n\n try {\n // Direct ID lookup\n if (/^\\d+$/.test(idOrHandle)) {\n const raw = await this.client.getOne<StelProductCategory>('productCategories', idOrHandle);\n return raw ? transformStelCategory(raw) : undefined;\n }\n\n // Scan by handle\n const rawCategories = await this.client.list<StelProductCategory>('productCategories');\n\n for (const raw of rawCategories) {\n const catHandle = buildStelHandle(raw.slug, raw.name, raw.id);\n if (catHandle === idOrHandle) {\n return transformStelCategory(raw);\n }\n }\n\n return undefined;\n } catch (error) {\n this.logger.error('getCategory failed', { idOrHandle, error });\n throw this.wrapError('getCategory', error);\n }\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n this.logger.debug('getCategories', { options });\n\n try {\n if (options?.customFetcher) {\n return options.customFetcher(options);\n }\n\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.parentCategoryId) {\n query['parent-category-id'] = options.parentCategoryId;\n }\n\n const rawCategories = await this.client.list<StelProductCategory>('productCategories', query);\n let categories = rawCategories\n .filter((c) => !c.deleted)\n .map(transformStelCategory);\n\n if (options?.query) {\n const needle = options.query.toLowerCase();\n categories = categories.filter(\n (c) =>\n c.name.toLowerCase().includes(needle) ||\n c.handle.includes(needle),\n );\n }\n\n return categories;\n } catch (error) {\n this.logger.error('getCategories failed', { options, error });\n throw this.wrapError('getCategories', error);\n }\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n this.logger.debug('getCategoryProducts', { handle, options });\n\n try {\n const category = await this.getCategory(handle);\n\n if (!category) {\n return [];\n }\n\n return this.getProducts({\n categoryIds: [category.id],\n first: options?.first,\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n after: options?.after,\n });\n } catch (error) {\n this.logger.error('getCategoryProducts failed', { handle, error });\n throw this.wrapError('getCategoryProducts', error);\n }\n }\n\n // ============================================\n // Collection Operations (alias categories)\n // ============================================\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n this.logger.debug('getCollection', { handle });\n\n try {\n if (/^\\d+$/.test(handle)) {\n const raw = await this.client.getOne<StelProductCategory>('productCategories', handle);\n return raw ? transformStelCategoryToCollection(raw) : undefined;\n }\n\n const rawCategories = await this.client.list<StelProductCategory>('productCategories');\n\n for (const raw of rawCategories) {\n const catHandle = buildStelHandle(raw.slug, raw.name, raw.id);\n if (catHandle === handle) {\n return transformStelCategoryToCollection(raw);\n }\n }\n\n return undefined;\n } catch (error) {\n this.logger.error('getCollection failed', { handle, error });\n throw this.wrapError('getCollection', error);\n }\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n this.logger.debug('getCollections', { options });\n\n try {\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n\n const rawCategories = await this.client.list<StelProductCategory>('productCategories', query);\n let collections = rawCategories\n .filter((c) => !c.deleted)\n .map(transformStelCategoryToCollection);\n\n if (options?.query) {\n const needle = options.query.toLowerCase();\n collections = collections.filter(\n (c) =>\n c.title.toLowerCase().includes(needle) ||\n c.handle.includes(needle),\n );\n }\n\n return collections;\n } catch (error) {\n this.logger.error('getCollections failed', { options, error });\n throw this.wrapError('getCollections', error);\n }\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n return this.getCategoryProducts(handle, options);\n }\n\n // ============================================\n // Inventory Operations\n // ============================================\n\n async getStockLocations(_params?: { salesChannelId?: string }): Promise<StockLocation[]> {\n this.logger.debug('getStockLocations');\n\n try {\n const rawWarehouses = await this.client.list<StelWarehouse>('warehouses');\n return rawWarehouses\n .filter((w) => !w.deleted)\n .map(transformStelWarehouseToStockLocation);\n } catch (error) {\n this.logger.error('getStockLocations failed', { error });\n throw this.wrapError('getStockLocations', error);\n }\n }\n\n async checkInventoryLevels(variantId: string, _salesChannelId?: string): Promise<InventoryLevel[]> {\n this.logger.debug('checkInventoryLevels', { variantId });\n\n try {\n // variantId is the product ID (single synthetic variant per product)\n const raw = await this.client.getOne<StelProduct>('products', variantId);\n\n if (!raw?.['product-warehouses']?.length) {\n return [];\n }\n\n return raw['product-warehouses'].map(transformStelProductWarehouseToInventoryLevel);\n } catch (error) {\n this.logger.error('checkInventoryLevels failed', { variantId, error });\n throw this.wrapError('checkInventoryLevels', error);\n }\n }\n\n validateCartStock(_cartId: string): Promise<StockValidation> {\n return this.notSupported('validateCartStock');\n }\n\n getFulfillmentOptions(_cartId: string, _salesChannelId: string): Promise<FulfillmentOption[]> {\n return this.notSupported('getFulfillmentOptions');\n }\n\n // ============================================\n // Cart Operations (unsupported — STEL is ERP, not storefront)\n // ============================================\n\n createCart(_options?: { regionId?: string }): Promise<Cart> {\n return this.notSupported('createCart');\n }\n\n getCart(_cartId: string): Promise<Cart | undefined> {\n return this.notSupported('getCart');\n }\n\n addToCart(_cartId: string, _lines: CartLineInput[]): Promise<Cart> {\n return this.notSupported('addToCart');\n }\n\n removeFromCart(_cartId: string, _lineIds: string[]): Promise<Cart> {\n return this.notSupported('removeFromCart');\n }\n\n updateCart(_cartId: string, _lines: CartLineUpdate[]): Promise<Cart> {\n return this.notSupported('updateCart');\n }\n\n // ============================================\n // Checkout Operations (unsupported)\n // ============================================\n\n completeCheckout(_cartId: string): Promise<Order> {\n return this.notSupported('completeCheckout');\n }\n\n getRegionCountries(_regionId: string): Promise<Country[]> {\n return this.notSupported('getRegionCountries');\n }\n\n addShippingMethod(_cartId: string, _methodId: string): Promise<Cart> {\n return this.notSupported('addShippingMethod');\n }\n\n initiatePaymentSession(_cartId: string, _providerId: string): Promise<void> {\n return this.notSupported('initiatePaymentSession');\n }\n\n applyDiscountCode(_cartId: string, _code: string): Promise<Cart> {\n return this.notSupported('applyDiscountCode');\n }\n\n removeDiscountCode(_cartId: string, _code: string): Promise<Cart> {\n return this.notSupported('removeDiscountCode');\n }\n\n // ============================================\n // Payment Methods\n // ============================================\n\n async getPaymentMethods(_options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n this.logger.debug('getPaymentMethods');\n\n try {\n const rawOptions = await this.client.list<StelPaymentOption>('paymentOptions');\n return rawOptions\n .filter((o) => !o.deleted)\n .map(transformStelPaymentOption);\n } catch (error) {\n this.logger.error('getPaymentMethods failed', { error });\n throw this.wrapError('getPaymentMethods', error);\n }\n }\n\n // ============================================\n // Shipping / Delivery Methods\n // ============================================\n\n async getShippingMethods(_cartId: string): Promise<ShippingMethod[]> {\n this.logger.debug('getShippingMethods (delivery options listing)');\n\n try {\n const rawOptions = await this.client.list<StelDeliveryOption>('deliveryOptions');\n return rawOptions\n .filter((o) => !o.deleted)\n .map((o) => transformStelDeliveryOption(o, this.currencyCode));\n } catch (error) {\n this.logger.error('getShippingMethods failed', { error });\n throw this.wrapError('getShippingMethods', error);\n }\n }\n\n // ============================================\n // Customer Operations (optional)\n // ============================================\n\n async getCustomer(customerId: string): Promise<Customer | undefined> {\n this.logger.debug('getCustomer', { customerId });\n\n try {\n const raw = await this.client.getOne<StelClient>('clients', customerId);\n return raw ? transformStelClient(raw) : undefined;\n } catch (error) {\n this.logger.error('getCustomer failed', { customerId, error });\n throw this.wrapError('getCustomer', error);\n }\n }\n\n async getCustomers(options?: GetCustomersOptions): Promise<Customer[]> {\n this.logger.debug('getCustomers', { options });\n\n try {\n if (options?.customFetcher) {\n return options.customFetcher(options);\n }\n\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.offset) {\n query.start = options.offset;\n }\n\n const rawClients = await this.client.list<StelClient>('clients', query);\n let customers = rawClients\n .filter((c) => !c.deleted)\n .map(transformStelClient);\n\n // Client-side search (STEL has no fulltext search for clients)\n if (options?.search) {\n const needle = options.search.toLowerCase();\n customers = customers.filter(\n (c) =>\n c.email.toLowerCase().includes(needle) ||\n (c.firstName ?? '').toLowerCase().includes(needle) ||\n (c.lastName ?? '').toLowerCase().includes(needle),\n );\n }\n\n return customers;\n } catch (error) {\n this.logger.error('getCustomers failed', { options, error });\n throw this.wrapError('getCustomers', error);\n }\n }\n\n async updateCustomer(\n customerId: string,\n data: Partial<Omit<Customer, 'id' | 'createdAt'>>,\n ): Promise<Customer> {\n this.logger.debug('updateCustomer', { customerId, data });\n\n try {\n const stelPayload: Record<string, unknown> = {};\n\n if (data.firstName || data.lastName) {\n stelPayload.name = [data.firstName, data.lastName].filter(Boolean).join(' ');\n }\n if (data.email) {\n stelPayload.email = data.email;\n }\n if (data.phone) {\n stelPayload.phone = data.phone;\n }\n\n const raw = await this.client.update<StelClient>('clients', customerId, stelPayload);\n return transformStelClient(raw);\n } catch (error) {\n this.logger.error('updateCustomer failed', { customerId, error });\n throw this.wrapError('updateCustomer', error);\n }\n }\n\n // ============================================\n // Order Operations (optional)\n // ============================================\n\n async getOrder(orderId: string): Promise<Order | undefined> {\n this.logger.debug('getOrder', { orderId });\n\n try {\n const raw = await this.client.getOne<StelSalesOrder>('salesOrders', orderId);\n return raw ? transformStelSalesOrder(raw, this.currencyCode) : undefined;\n } catch (error) {\n this.logger.error('getOrder failed', { orderId, error });\n throw this.wrapError('getOrder', error);\n }\n }\n\n async getOrders(options: GetOrdersOptions): Promise<Order[]> {\n this.logger.debug('getOrders', { options });\n\n try {\n if (options?.customFetcher) {\n return options.customFetcher(options);\n }\n\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.offset) {\n query.start = options.offset;\n }\n if (options?.customerId) {\n query['client-id'] = options.customerId;\n }\n\n const rawOrders = await this.client.list<StelSalesOrder>('salesOrders', query);\n return rawOrders\n .filter((o) => !o.deleted)\n .map((o) => transformStelSalesOrder(o, this.currencyCode));\n } catch (error) {\n this.logger.error('getOrders failed', { options, error });\n throw this.wrapError('getOrders', error);\n }\n }\n\n async getAdminOrders(options?: {\n search?: string;\n status?: string | string[];\n limit?: number;\n offset?: number;\n }): Promise<{ orders: Order[]; count: number }> {\n this.logger.debug('getAdminOrders', { options });\n\n try {\n const query: Record<string, string | number> = {};\n\n if (options?.limit) {\n query.limit = options.limit;\n }\n if (options?.offset) {\n query.start = options.offset;\n }\n\n const rawOrders = await this.client.list<StelSalesOrder>('salesOrders', query);\n let orders = rawOrders\n .filter((o) => !o.deleted)\n .map((o) => transformStelSalesOrder(o, this.currencyCode));\n\n if (options?.search) {\n const needle = options.search.toLowerCase();\n orders = orders.filter(\n (o) =>\n o.orderNumber.toLowerCase().includes(needle) ||\n o.email.toLowerCase().includes(needle),\n );\n }\n\n if (options?.status) {\n const statuses = Array.isArray(options.status) ? options.status : [options.status];\n orders = orders.filter((o) => statuses.includes(o.status));\n }\n\n return { orders, count: orders.length };\n } catch (error) {\n this.logger.error('getAdminOrders failed', { options, error });\n throw this.wrapError('getAdminOrders', error);\n }\n }\n\n cancelOrder(_orderId: string): Promise<Order> {\n return this.notSupported('cancelOrder');\n }\n\n createFulfillment(_orderId: string, _items?: Array<{ id: string; quantity: number }>): Promise<void> {\n return this.notSupported('createFulfillment');\n }\n\n createRefund(_orderId: string, _amount?: number, _reason?: string): Promise<void> {\n return this.notSupported('createRefund');\n }\n\n // ============================================\n // Storefront Context\n // ============================================\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: this.storefrontId,\n name: this.companyName,\n platformType: 'stelorder',\n requiresProductScoping: false,\n currencyCode: this.currencyCode,\n metadata: {\n apiBaseUrl: this.client.apiBaseUrl,\n singleCompany: true,\n providerVersion: this.version,\n },\n };\n }\n\n isStorefrontRequired(): boolean {\n return false;\n }\n\n // ============================================\n // Internal helpers\n // ============================================\n\n private notSupported<T>(operation: string): Promise<T> {\n return Promise.reject(\n new ProviderAPIError(\n `Stel Order does not support \\`${operation}\\`. STEL is an ERP adapter without cart/checkout/auth capabilities.`,\n 'stelorder',\n 501,\n ),\n );\n }\n\n private wrapError(operation: string, error: unknown): Error {\n if (error instanceof ProviderAPIError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return new ProviderAPIError(\n `Stel Order \\`${operation}\\` failed: ${message}`,\n 'stelorder',\n 500,\n );\n }\n}\n","import type {\n Cart,\n CartItem,\n Collection,\n Country,\n FulfillmentOption,\n Image,\n InventoryLevel,\n Money,\n Order,\n PaymentMethod,\n Product,\n ProductCategory,\n Region,\n SelectedOption,\n ShippingMethod,\n StockLocation,\n StockStatus,\n StockValidation,\n} from '@thorprovider/types';\n\nconst FIXTURE_TIMESTAMP = '2026-01-01T00:00:00.000Z';\nconst DEFAULT_SITE_URL = 'https://mock.thorcommerce.local';\n\ninterface MockRegionFixture {\n id: string;\n name: string;\n currencyCode: string;\n locale?: string;\n taxRate?: number;\n countries: Country[];\n}\n\ninterface MockCollectionFixture {\n id: string;\n handle: string;\n title: string;\n description: string;\n}\n\ninterface MockCategoryFixture {\n id: string;\n handle: string;\n name: string;\n description: string;\n parentCategoryId?: string;\n}\n\ninterface MockVariantFixture {\n id: string;\n title: string;\n price: number;\n compareAtPrice?: number;\n quantityAvailable: number;\n selectedOptions: SelectedOption[];\n}\n\ninterface MockProductFixture {\n id: string;\n handle: string;\n title: string;\n description: string;\n imageLabel: string;\n imageHue: number;\n collectionHandles: string[];\n categoryHandle: string;\n productType: string;\n vendor: string;\n tags: string[];\n options: Array<{ id: string; name: string; values: string[] }>;\n variants: MockVariantFixture[];\n}\n\nexport interface MockCartState {\n id: string;\n regionId?: string;\n lines: Array<{\n id: string;\n merchandiseId: string;\n quantity: number;\n }>;\n shippingMethodId?: string;\n paymentProviderId?: string;\n discountCode?: string;\n completedAt?: string;\n}\n\nconst regionFixtures: MockRegionFixture[] = [\n {\n id: 'mock-region-us',\n name: 'United States',\n currencyCode: 'USD',\n locale: 'en-US',\n taxRate: 0.08,\n countries: [{ code: 'US', name: 'United States' }],\n },\n {\n id: 'mock-region-eu',\n name: 'Europe',\n currencyCode: 'EUR',\n locale: 'en-ES',\n taxRate: 0.21,\n countries: [\n { code: 'ES', name: 'Spain' },\n { code: 'FR', name: 'France' },\n { code: 'DE', name: 'Germany' },\n ],\n },\n];\n\nconst collectionFixtures: MockCollectionFixture[] = [\n {\n id: 'mock-collection-new-arrivals',\n handle: 'new-arrivals',\n title: 'New Arrivals',\n description: 'Fresh mock catalog items for layout and merchandising flows.',\n },\n {\n id: 'mock-collection-best-sellers',\n handle: 'best-sellers',\n title: 'Best Sellers',\n description: 'High-performing mock products used to design hero grids and featured sections.',\n },\n {\n id: 'mock-collection-studio-essentials',\n handle: 'studio-essentials',\n title: 'Studio Essentials',\n description: 'A balanced fixture set for mock storefront navigation and detail pages.',\n },\n];\n\nconst categoryFixtures: MockCategoryFixture[] = [\n {\n id: 'mock-category-jackets',\n handle: 'jackets',\n name: 'Jackets',\n description: 'Outerwear and layering pieces.',\n },\n {\n id: 'mock-category-dresses',\n handle: 'dresses',\n name: 'Dresses',\n description: 'Editorial silhouettes for seasonal collections.',\n },\n {\n id: 'mock-category-home',\n handle: 'home',\n name: 'Home',\n description: 'Decor and living objects for lifestyle layouts.',\n },\n {\n id: 'mock-category-accessories',\n handle: 'accessories',\n name: 'Accessories',\n description: 'Complementary products for cart and bundle flows.',\n },\n];\n\nconst productFixtures: MockProductFixture[] = [\n {\n id: 'mock-product-aurora-jacket',\n handle: 'aurora-jacket',\n title: 'Aurora Quilted Jacket',\n description: 'Lightweight quilted outerwear with tonal hardware and a soft structured collar.',\n imageLabel: 'Aurora Jacket',\n imageHue: 222,\n collectionHandles: ['new-arrivals', 'best-sellers'],\n categoryHandle: 'jackets',\n productType: 'outerwear',\n vendor: 'Thor Atelier',\n tags: ['outerwear', 'quilted', 'winter'],\n options: [\n { id: 'aurora-size', name: 'Size', values: ['S', 'M', 'L'] },\n { id: 'aurora-color', name: 'Color', values: ['Midnight'] },\n ],\n variants: [\n {\n id: 'mock-variant-aurora-s',\n title: 'S / Midnight',\n price: 129,\n compareAtPrice: 159,\n quantityAvailable: 8,\n selectedOptions: [\n { name: 'Size', value: 'S' },\n { name: 'Color', value: 'Midnight' },\n ],\n },\n {\n id: 'mock-variant-aurora-m',\n title: 'M / Midnight',\n price: 129,\n compareAtPrice: 159,\n quantityAvailable: 12,\n selectedOptions: [\n { name: 'Size', value: 'M' },\n { name: 'Color', value: 'Midnight' },\n ],\n },\n ],\n },\n {\n id: 'mock-product-solis-dress',\n handle: 'solis-dress',\n title: 'Solis Pleated Dress',\n description: 'A fluid pleated dress with a clean neckline designed for hero storytelling.',\n imageLabel: 'Solis Dress',\n imageHue: 18,\n collectionHandles: ['new-arrivals', 'studio-essentials'],\n categoryHandle: 'dresses',\n productType: 'dress',\n vendor: 'Thor Atelier',\n tags: ['dress', 'occasion', 'pleated'],\n options: [\n { id: 'solis-size', name: 'Size', values: ['XS', 'S', 'M'] },\n { id: 'solis-color', name: 'Color', values: ['Clay'] },\n ],\n variants: [\n {\n id: 'mock-variant-solis-xs',\n title: 'XS / Clay',\n price: 164,\n quantityAvailable: 4,\n selectedOptions: [\n { name: 'Size', value: 'XS' },\n { name: 'Color', value: 'Clay' },\n ],\n },\n {\n id: 'mock-variant-solis-s',\n title: 'S / Clay',\n price: 164,\n quantityAvailable: 9,\n selectedOptions: [\n { name: 'Size', value: 'S' },\n { name: 'Color', value: 'Clay' },\n ],\n },\n ],\n },\n {\n id: 'mock-product-helios-lamp',\n handle: 'helios-lamp',\n title: 'Helios Table Lamp',\n description: 'Warm ambient lamp with sculptural proportions for lifestyle and home grids.',\n imageLabel: 'Helios Lamp',\n imageHue: 45,\n collectionHandles: ['best-sellers', 'studio-essentials'],\n categoryHandle: 'home',\n productType: 'lighting',\n vendor: 'Thor Home',\n tags: ['home', 'lighting', 'decor'],\n options: [{ id: 'helios-finish', name: 'Finish', values: ['Brass'] }],\n variants: [\n {\n id: 'mock-variant-helios-brass',\n title: 'Brass',\n price: 96,\n quantityAvailable: 15,\n selectedOptions: [{ name: 'Finish', value: 'Brass' }],\n },\n ],\n },\n {\n id: 'mock-product-luna-bag',\n handle: 'luna-bag',\n title: 'Luna Crossbody Bag',\n description: 'Compact everyday bag for accessory rails, checkout add-ons, and bundle modules.',\n imageLabel: 'Luna Bag',\n imageHue: 306,\n collectionHandles: ['studio-essentials'],\n categoryHandle: 'accessories',\n productType: 'bag',\n vendor: 'Thor Atelier',\n tags: ['bag', 'accessory', 'everyday'],\n options: [{ id: 'luna-color', name: 'Color', values: ['Berry'] }],\n variants: [\n {\n id: 'mock-variant-luna-berry',\n title: 'Berry',\n price: 82,\n quantityAvailable: 18,\n selectedOptions: [{ name: 'Color', value: 'Berry' }],\n },\n ],\n },\n];\n\nconst stockLocationFixture: StockLocation = {\n id: 'mock-stock-primary',\n name: 'Mock Main Warehouse',\n address: {\n address1: '100 Mock Avenue',\n city: 'Design City',\n countryCode: 'US',\n postalCode: '10001',\n province: 'NY',\n },\n metadata: {\n timezone: 'America/New_York',\n },\n};\n\nconst cartStore = new Map<string, MockCartState>();\nconst orderStore = new Map<string, Order>();\n\nlet sequence = 0;\n\nfunction nextId(prefix: string): string {\n sequence += 1;\n return `${prefix}-${sequence}`;\n}\n\nfunction createMoney(amount: number, currencyCode: string): Money {\n return {\n amount: amount.toFixed(2),\n currencyCode,\n };\n}\n\nfunction createImage(label: string, hue: number): Image {\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1200 1200\" role=\"img\" aria-label=\"${label}\">\n <defs>\n <linearGradient id=\"g\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"hsl(${hue}, 72%, 72%)\" />\n <stop offset=\"100%\" stop-color=\"hsl(${(hue + 48) % 360}, 62%, 42%)\" />\n </linearGradient>\n </defs>\n <rect width=\"1200\" height=\"1200\" fill=\"url(#g)\" rx=\"48\" />\n <circle cx=\"910\" cy=\"280\" r=\"180\" fill=\"rgba(255,255,255,0.22)\" />\n <text x=\"90\" y=\"990\" fill=\"white\" font-family=\"Arial, sans-serif\" font-size=\"96\" font-weight=\"700\">${label}</text>\n </svg>\n `.trim();\n\n return {\n url: `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`,\n altText: label,\n width: 1200,\n height: 1200,\n };\n}\n\nfunction getRegionFixture(regionId?: string): MockRegionFixture {\n if (!regionId) {\n return regionFixtures[0];\n }\n\n return regionFixtures.find((region) => region.id === regionId) ?? regionFixtures[0];\n}\n\nfunction createProductImageSet(label: string, hue: number): { featuredImage: Image; images: Image[] } {\n const featuredImage = createImage(label, hue);\n\n return {\n featuredImage,\n images: [featuredImage, createImage(`${label} Detail`, (hue + 18) % 360)],\n };\n}\n\nfunction buildCollections(): Collection[] {\n return collectionFixtures.map((collection) => ({\n id: collection.id,\n handle: collection.handle,\n title: collection.title,\n description: collection.description,\n path: `/collections/${collection.handle}`,\n updatedAt: FIXTURE_TIMESTAMP,\n }));\n}\n\nfunction buildCategories(): ProductCategory[] {\n return categoryFixtures.map((category) => ({\n id: category.id,\n handle: category.handle,\n name: category.name,\n description: category.description,\n parentCategoryId: category.parentCategoryId,\n productCount: productFixtures.filter((product) => product.categoryHandle === category.handle).length,\n image: createImage(category.name, 180).url,\n }));\n}\n\nfunction buildProducts(currencyCode: string): Product[] {\n const collections = buildCollections();\n\n return productFixtures.map((product) => {\n const { featuredImage, images } = createProductImageSet(product.imageLabel, product.imageHue);\n const variants = product.variants.map((variant) => ({\n id: variant.id,\n title: variant.title,\n availableForSale: variant.quantityAvailable > 0,\n selectedOptions: variant.selectedOptions,\n price: createMoney(variant.price, currencyCode),\n compareAtPrice: variant.compareAtPrice\n ? createMoney(variant.compareAtPrice, currencyCode)\n : undefined,\n quantityAvailable: variant.quantityAvailable,\n image: featuredImage,\n }));\n\n const prices = product.variants.map((variant) => variant.price);\n\n return {\n id: product.id,\n handle: product.handle,\n title: product.title,\n description: product.description,\n availableForSale: variants.some((variant) => variant.availableForSale),\n options: product.options,\n variants,\n featuredImage,\n images,\n priceRange: {\n minVariantPrice: createMoney(Math.min(...prices), currencyCode),\n maxVariantPrice: createMoney(Math.max(...prices), currencyCode),\n },\n collections: product.collectionHandles\n .map((handle) => collections.find((collection) => collection.handle === handle))\n .filter((collection): collection is Collection => Boolean(collection))\n .map((collection) => ({\n id: collection.id,\n title: collection.title,\n handle: collection.handle,\n })),\n productType: product.productType,\n vendor: product.vendor,\n tags: product.tags,\n createdAt: FIXTURE_TIMESTAMP,\n updatedAt: FIXTURE_TIMESTAMP,\n metadata: {\n categoryHandle: product.categoryHandle,\n collectionHandles: product.collectionHandles,\n },\n };\n });\n}\n\nfunction filterProducts(products: Product[], options: {\n query?: string;\n categoryIds?: string[];\n collectionIds?: string[];\n}): Product[] {\n const query = options.query?.trim().toLowerCase();\n const categoryIds = new Set(options.categoryIds ?? []);\n const collectionIds = new Set(options.collectionIds ?? []);\n\n return products.filter((product) => {\n if (query) {\n const matchesQuery = [product.title, product.description, ...(product.tags ?? [])]\n .join(' ')\n .toLowerCase()\n .includes(query);\n\n if (!matchesQuery) {\n return false;\n }\n }\n\n if (categoryIds.size > 0) {\n const categoryHandle = String(product.metadata?.categoryHandle ?? '');\n const category = categoryFixtures.find((item) => item.handle === categoryHandle);\n const matchesCategory = category\n ? categoryIds.has(category.id) || categoryIds.has(category.handle)\n : false;\n\n if (!matchesCategory) {\n return false;\n }\n }\n\n if (collectionIds.size > 0) {\n const productCollections = (product.collections ?? []).map((collection) => collection.handle);\n const matchesCollection = (product.collections ?? []).some(\n (collection) => collectionIds.has(collection.id) || collectionIds.has(collection.handle)\n ) || productCollections.some((handle) => collectionIds.has(handle));\n\n if (!matchesCollection) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nfunction sortProducts(products: Product[], sortKey?: string, reverse?: boolean): Product[] {\n const sorted = [...products];\n\n switch (sortKey) {\n case 'price':\n case 'price-asc':\n case 'price-desc':\n sorted.sort(\n (left, right) =>\n Number(left.priceRange.minVariantPrice.amount) - Number(right.priceRange.minVariantPrice.amount)\n );\n break;\n case 'created_at':\n case 'createdAt':\n case 'newest':\n sorted.sort((left, right) => left.createdAt.localeCompare(right.createdAt));\n break;\n case 'title':\n case 'name':\n default:\n sorted.sort((left, right) => left.title.localeCompare(right.title));\n break;\n }\n\n const shouldReverse = reverse || sortKey === 'price-desc' || sortKey === 'newest';\n return shouldReverse ? sorted.reverse() : sorted;\n}\n\nfunction paginateProducts(products: Product[], skip?: number, first?: number): Product[] {\n const start = Math.max(0, skip ?? 0);\n const end = first ? start + first : undefined;\n return products.slice(start, end);\n}\n\nfunction resolveVariant(currencyCode: string, merchandiseId: string): {\n product: Product;\n variant: Product['variants'][number];\n} | undefined {\n const products = buildProducts(currencyCode);\n\n for (const product of products) {\n const variant = product.variants.find((item) => item.id === merchandiseId);\n if (variant) {\n return { product, variant };\n }\n }\n\n return undefined;\n}\n\nfunction getShippingPrice(methodId: string | undefined): number {\n switch (methodId) {\n case 'mock-shipping-express':\n return 18;\n case 'mock-shipping-standard':\n return 8;\n default:\n return 0;\n }\n}\n\nfunction buildExternalCart(state: MockCartState, currencyCode: string, siteUrl: string): Cart {\n const region = getRegionFixture(state.regionId);\n const regionCurrency = region.currencyCode || currencyCode;\n\n const lines: CartItem[] = state.lines.flatMap((line) => {\n const resolved = resolveVariant(regionCurrency, line.merchandiseId);\n if (!resolved || !resolved.product.featuredImage) {\n return [];\n }\n\n const lineTotal = Number(resolved.variant.price.amount) * line.quantity;\n const stockStatus: StockStatus = resolved.variant.quantityAvailable && resolved.variant.quantityAvailable > 0\n ? 'in_stock'\n : 'out_of_stock';\n\n return [{\n id: line.id,\n quantity: line.quantity,\n stockStatus,\n cost: {\n totalAmount: createMoney(lineTotal, regionCurrency),\n },\n merchandise: {\n id: resolved.variant.id,\n title: resolved.variant.title,\n selectedOptions: resolved.variant.selectedOptions,\n product: {\n id: resolved.product.id,\n handle: resolved.product.handle,\n title: resolved.product.title,\n featuredImage: resolved.product.featuredImage,\n },\n },\n }];\n });\n\n const subtotal = lines.reduce(\n (sum, line) => sum + Number(line.cost.totalAmount.amount),\n 0\n );\n const shipping = getShippingPrice(state.shippingMethodId);\n const discount = state.discountCode ? subtotal * 0.1 : 0;\n const taxableBase = Math.max(subtotal + shipping - discount, 0);\n const totalTax = region.taxRate ? taxableBase * region.taxRate : 0;\n const total = taxableBase + totalTax;\n\n return {\n id: state.id,\n checkoutUrl: `${siteUrl}/checkout?cart=${state.id}`,\n cost: {\n subtotalAmount: createMoney(subtotal, regionCurrency),\n totalAmount: createMoney(total, regionCurrency),\n totalTaxAmount: createMoney(totalTax, regionCurrency),\n },\n lines,\n totalQuantity: lines.reduce((sum, line) => sum + line.quantity, 0),\n completedAt: state.completedAt,\n };\n}\n\nfunction buildOrderFromCart(state: MockCartState, currencyCode: string, siteUrl: string): Order {\n const cart = buildExternalCart(state, currencyCode, siteUrl);\n\n return {\n id: `mock-order-${state.id}`,\n orderNumber: `${1000 + sequence}`,\n email: 'mock-customer@thorprovider.dev',\n status: 'completed',\n paymentStatus: state.paymentProviderId ? 'paid' : 'pending',\n fulfillmentStatus: state.shippingMethodId ? 'fulfilled' : 'unfulfilled',\n items: cart.lines.map((line) => ({\n id: line.id ?? nextId('mock-order-line'),\n title: line.merchandise.product.title,\n variantTitle: line.merchandise.title,\n quantity: line.quantity,\n price: line.merchandise.product.featuredImage\n ? createMoney(Number(line.cost.totalAmount.amount) / Math.max(line.quantity, 1), cart.cost.totalAmount.currencyCode)\n : createMoney(0, cart.cost.totalAmount.currencyCode),\n total: line.cost.totalAmount,\n productId: line.merchandise.product.id,\n variantId: line.merchandise.id,\n image: line.merchandise.product.featuredImage,\n })),\n subtotal: cart.cost.subtotalAmount,\n total: cart.cost.totalAmount,\n tax: cart.cost.totalTaxAmount,\n shipping: createMoney(getShippingPrice(state.shippingMethodId), cart.cost.totalAmount.currencyCode),\n discount: createMoney(state.discountCode ? Number(cart.cost.subtotalAmount.amount) * 0.1 : 0, cart.cost.totalAmount.currencyCode),\n createdAt: FIXTURE_TIMESTAMP,\n updatedAt: FIXTURE_TIMESTAMP,\n completedAt: state.completedAt,\n metadata: {\n provider: 'mock',\n checkoutUrl: cart.checkoutUrl,\n },\n };\n}\n\nexport function getMockCollections(): Collection[] {\n return buildCollections();\n}\n\nexport function getMockCategories(): ProductCategory[] {\n return buildCategories();\n}\n\nexport function getMockProducts(options?: {\n currencyCode?: string;\n query?: string;\n sortKey?: string;\n reverse?: boolean;\n first?: number;\n skip?: number;\n categoryIds?: string[];\n collectionIds?: string[];\n regionId?: string;\n}): Product[] {\n const region = getRegionFixture(options?.regionId);\n const currencyCode = options?.currencyCode ?? region.currencyCode;\n const products = buildProducts(currencyCode);\n const filtered = filterProducts(products, {\n query: options?.query,\n categoryIds: options?.categoryIds,\n collectionIds: options?.collectionIds,\n });\n const sorted = sortProducts(filtered, options?.sortKey, options?.reverse);\n\n return paginateProducts(sorted, options?.skip, options?.first);\n}\n\nexport function getMockProduct(handle: string, regionId?: string): Product | undefined {\n const region = getRegionFixture(regionId);\n return buildProducts(region.currencyCode).find(\n (product) => product.handle === handle || product.id === handle\n );\n}\n\nexport function getMockProductRecommendations(productId: string, regionId?: string): Product[] {\n const product = getMockProduct(productId, regionId)\n ?? buildProducts(getRegionFixture(regionId).currencyCode).find((item) => item.id === productId);\n\n if (!product) {\n return [];\n }\n\n const collectionHandles = new Set((product.collections ?? []).map((collection) => collection.handle));\n\n return buildProducts(getRegionFixture(regionId).currencyCode)\n .filter((candidate) => candidate.id !== product.id)\n .filter((candidate) =>\n (candidate.collections ?? []).some((collection) => collectionHandles.has(collection.handle))\n )\n .slice(0, 4);\n}\n\nexport function getMockCollection(handle: string): Collection | undefined {\n return buildCollections().find(\n (collection) => collection.handle === handle || collection.id === handle\n );\n}\n\nexport function getMockCategory(idOrHandle: string): ProductCategory | undefined {\n return buildCategories().find(\n (category) => category.handle === idOrHandle || category.id === idOrHandle\n );\n}\n\nexport function getMockRegions(): Array<{\n id: string;\n name: string;\n currency_code: string;\n countries: Array<{ id: string; iso_2: string; name: string; display_name?: string }>;\n}> {\n return regionFixtures.map((region) => ({\n id: region.id,\n name: region.name,\n currency_code: region.currencyCode,\n countries: region.countries.map((country) => ({\n id: `country-${country.code.toLowerCase()}`,\n iso_2: country.code.toLowerCase(),\n name: country.name,\n display_name: country.name,\n })),\n }));\n}\n\nexport function getMockAdminRegions(): Region[] {\n return regionFixtures.map((region) => ({\n id: region.id,\n name: region.name,\n countryCodes: region.countries.map((country) => country.code),\n currency: region.currencyCode,\n taxRate: region.taxRate,\n isEnabled: true,\n }));\n}\n\nexport function getMockRegionCountries(regionId: string): Country[] {\n const region = regionFixtures.find((item) => item.id === regionId);\n return region?.countries ?? [];\n}\n\nexport function createMockCart(regionId?: string): MockCartState {\n const cart: MockCartState = {\n id: nextId('mock-cart'),\n regionId: regionId ?? regionFixtures[0].id,\n lines: [],\n };\n\n cartStore.set(cart.id, cart);\n return cart;\n}\n\nexport function getMockCartState(cartId: string): MockCartState | undefined {\n return cartStore.get(cartId);\n}\n\nexport function saveMockCartState(cart: MockCartState): MockCartState {\n cartStore.set(cart.id, cart);\n return cart;\n}\n\nexport function buildMockCart(cart: MockCartState, currencyCode?: string, siteUrl?: string): Cart {\n return buildExternalCart(\n cart,\n currencyCode ?? getRegionFixture(cart.regionId).currencyCode,\n siteUrl ?? DEFAULT_SITE_URL\n );\n}\n\nexport function getMockShippingMethods(regionId?: string): ShippingMethod[] {\n const currencyCode = getRegionFixture(regionId).currencyCode;\n\n return [\n {\n id: 'mock-shipping-standard',\n name: 'Standard Shipping',\n description: 'Fixture shipping option for checkout and cart layouts.',\n price: createMoney(8, currencyCode),\n estimatedDays: '3-5 business days',\n },\n {\n id: 'mock-shipping-express',\n name: 'Express Shipping',\n description: 'Faster fixture shipping option for premium checkout flows.',\n price: createMoney(18, currencyCode),\n estimatedDays: '1-2 business days',\n },\n ];\n}\n\nexport function getMockPaymentMethods(currencyCode: string): PaymentMethod[] {\n return [\n {\n id: 'mock-card',\n name: 'Mock Card',\n type: 'card',\n isEnabled: true,\n requiresSetup: true,\n description: `Fixture card checkout for ${currencyCode}.`,\n },\n {\n id: 'mock-cash',\n name: 'Cash on Delivery',\n type: 'cash_on_delivery',\n isEnabled: true,\n requiresSetup: false,\n description: 'Mock cash payment option for checkout prototypes.',\n },\n ];\n}\n\nexport function getMockStockLocations(): StockLocation[] {\n return [stockLocationFixture];\n}\n\nexport function getMockInventoryLevels(variantId: string): InventoryLevel[] {\n for (const region of regionFixtures) {\n const resolved = resolveVariant(region.currencyCode, variantId);\n if (resolved) {\n return [{\n locationId: stockLocationFixture.id,\n locationName: stockLocationFixture.name,\n availableQuantity: resolved.variant.quantityAvailable ?? 0,\n reservedQuantity: 0,\n stockedQuantity: resolved.variant.quantityAvailable ?? 0,\n }];\n }\n }\n\n return [];\n}\n\nexport function validateMockCartStock(cart: MockCartState): StockValidation {\n const currencyCode = getRegionFixture(cart.regionId).currencyCode;\n const unavailableItems = cart.lines.flatMap((line) => {\n const resolved = resolveVariant(currencyCode, line.merchandiseId);\n if (!resolved) {\n return [];\n }\n\n const availableQuantity = resolved.variant.quantityAvailable ?? 0;\n\n if (line.quantity <= availableQuantity) {\n return [];\n }\n\n return [{\n variantId: resolved.variant.id,\n productName: resolved.product.title,\n requestedQuantity: line.quantity,\n availableQuantity,\n }];\n });\n\n return {\n allAvailable: unavailableItems.length === 0,\n unavailableItems,\n };\n}\n\nexport function getMockFulfillmentOptions(regionId?: string): FulfillmentOption[] {\n return getMockShippingMethods(regionId).map((method) => ({\n id: method.id,\n providerId: 'mock-fulfillment',\n name: method.name,\n description: method.description,\n price: method.price,\n estimatedDays: method.estimatedDays,\n stockLocation: stockLocationFixture,\n }));\n}\n\nexport function completeMockCheckout(cart: MockCartState, currencyCode?: string, siteUrl?: string): Order {\n const completedAt = new Date().toISOString();\n const nextCart = {\n ...cart,\n completedAt,\n };\n\n cartStore.set(nextCart.id, nextCart);\n\n const order = buildOrderFromCart(\n nextCart,\n currencyCode ?? getRegionFixture(nextCart.regionId).currencyCode,\n siteUrl ?? DEFAULT_SITE_URL\n );\n\n orderStore.set(order.id, order);\n return order;\n}\n\nexport function getMockAdminOrders(): { orders: Order[]; count: number } {\n const orders = Array.from(orderStore.values()).sort((left, right) =>\n right.createdAt.localeCompare(left.createdAt)\n );\n\n return {\n orders,\n count: orders.length,\n };\n}\n\nexport function getMockOrder(orderId: string): Order | undefined {\n return orderStore.get(orderId);\n}\n\nexport function saveMockOrder(order: Order): Order {\n orderStore.set(order.id, order);\n return order;\n}\n","import type {\n Cart,\n CartLineInput,\n CartLineUpdate,\n Collection,\n CollectionProductsOptions,\n GetCategoriesOptions,\n GetCollectionsOptions,\n GetOrdersOptions,\n GetProductsOptions,\n InventoryLevel,\n Order,\n PaymentMethodsOptions,\n Product,\n ProductCategory,\n Region,\n ShippingMethod,\n StockLocation,\n StockValidation,\n StorefrontContext,\n FulfillmentOption,\n PaymentMethod,\n} from '@thorprovider/types';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport { ProviderAPIError, ResourceNotFoundError } from '../../core/errors';\nimport { MOCK_CAPABILITIES } from '../../types/capabilities.types';\nimport {\n buildMockCart,\n completeMockCheckout,\n createMockCart,\n getMockAdminOrders,\n getMockAdminRegions,\n getMockCategories,\n getMockCategory,\n getMockCollection,\n getMockCollections,\n getMockCartState,\n getMockFulfillmentOptions,\n getMockInventoryLevels,\n getMockOrder,\n getMockPaymentMethods,\n getMockProduct,\n getMockProductRecommendations,\n getMockProducts,\n getMockRegionCountries,\n getMockRegions,\n getMockShippingMethods,\n getMockStockLocations,\n saveMockCartState,\n saveMockOrder,\n validateMockCartStock,\n} from './mock';\n\nexport interface MockProviderConfig extends ProviderConfig {\n currencyCode?: string;\n siteUrl?: string;\n}\n\nexport class MockProvider implements CommerceProvider {\n readonly name = 'mock';\n readonly version = '1.0.0';\n readonly capabilities = MOCK_CAPABILITIES;\n readonly isMock = true;\n\n private readonly currencyCode: string;\n private readonly siteUrl: string;\n\n constructor(config: MockProviderConfig = {}) {\n this.currencyCode = config.currencyCode ?? 'USD';\n this.siteUrl = config.siteUrl ?? 'https://mock.thorcommerce.local';\n }\n\n private hasVariant(merchandiseId: string, regionId?: string): boolean {\n return getMockProducts({\n currencyCode: this.currencyCode,\n regionId,\n }).some((product) =>\n product.variants.some((variant) => variant.id === merchandiseId)\n );\n }\n\n async getProduct(handle: string, options?: { regionId?: string }): Promise<Product | undefined> {\n return getMockProduct(handle, options?.regionId);\n }\n\n async getProducts(options?: GetProductsOptions): Promise<Product[]> {\n return getMockProducts({\n currencyCode: this.currencyCode,\n query: options?.query,\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n first: options?.first,\n skip: options?.skip,\n categoryIds: options?.categoryIds,\n collectionIds: options?.collectionIds,\n regionId: options?.regionId,\n });\n }\n\n async getProductRecommendations(productId: string): Promise<Product[]> {\n return getMockProductRecommendations(productId);\n }\n\n async getCollection(handle: string): Promise<Collection | undefined> {\n return getMockCollection(handle);\n }\n\n async getCollections(options?: GetCollectionsOptions): Promise<Collection[]> {\n const collections = getMockCollections();\n const query = options?.query?.trim().toLowerCase();\n const filtered = query\n ? collections.filter((collection) =>\n [collection.title, collection.description, collection.handle]\n .join(' ')\n .toLowerCase()\n .includes(query)\n )\n : collections;\n\n return filtered.slice(0, options?.limit ?? filtered.length);\n }\n\n async getCollectionProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const collection = getMockCollection(handle);\n if (!collection) {\n return [];\n }\n\n return getMockProducts({\n currencyCode: this.currencyCode,\n collectionIds: [collection.id],\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n first: options?.first,\n });\n }\n\n async getCategory(idOrHandle: string): Promise<ProductCategory | undefined> {\n return getMockCategory(idOrHandle);\n }\n\n async getCategories(options?: GetCategoriesOptions): Promise<ProductCategory[]> {\n const categories = getMockCategories();\n const query = options?.query?.trim().toLowerCase();\n\n let filtered = query\n ? categories.filter((category) =>\n [category.name, category.description ?? '', category.handle]\n .join(' ')\n .toLowerCase()\n .includes(query)\n )\n : categories;\n\n if (options?.parentCategoryId) {\n filtered = filtered.filter((category) => category.parentCategoryId === options.parentCategoryId);\n }\n\n return filtered.slice(0, options?.limit ?? filtered.length);\n }\n\n async getCategoryProducts(handle: string, options?: CollectionProductsOptions): Promise<Product[]> {\n const category = getMockCategory(handle);\n if (!category) {\n return [];\n }\n\n return getMockProducts({\n currencyCode: this.currencyCode,\n categoryIds: [category.id],\n sortKey: options?.sortKey,\n reverse: options?.reverse,\n first: options?.first,\n });\n }\n\n async createCart(options?: { regionId?: string }): Promise<Cart> {\n const cart = createMockCart(options?.regionId);\n return buildMockCart(cart, this.currencyCode, this.siteUrl);\n }\n\n async getCart(cartId: string): Promise<Cart | undefined> {\n const cart = getMockCartState(cartId);\n return cart ? buildMockCart(cart, this.currencyCode, this.siteUrl) : undefined;\n }\n\n async addToCart(cartId: string, lines: CartLineInput[]): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n for (const line of lines) {\n if (!this.hasVariant(line.merchandiseId, cart.regionId)) {\n throw new ResourceNotFoundError('variant', line.merchandiseId);\n }\n }\n\n const nextLines = [...cart.lines];\n for (const line of lines) {\n const existing = nextLines.find((item) => item.merchandiseId === line.merchandiseId);\n if (existing) {\n existing.quantity += line.quantity;\n } else {\n nextLines.push({\n id: `mock-line-${line.merchandiseId}`,\n merchandiseId: line.merchandiseId,\n quantity: line.quantity,\n });\n }\n }\n\n const saved = saveMockCartState({ ...cart, lines: nextLines });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const saved = saveMockCartState({\n ...cart,\n lines: cart.lines.filter((line) => !lineIds.includes(line.id)),\n });\n\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async updateCart(cartId: string, lines: CartLineUpdate[]): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n for (const line of lines) {\n if (!this.hasVariant(line.merchandiseId, cart.regionId)) {\n throw new ResourceNotFoundError('variant', line.merchandiseId);\n }\n }\n\n const updates = new Map(lines.map((line) => [line.id, line]));\n const nextLines = cart.lines\n .map((line) => {\n const update = updates.get(line.id);\n if (!update) {\n return line;\n }\n\n return {\n ...line,\n merchandiseId: update.merchandiseId,\n quantity: update.quantity,\n };\n })\n .filter((line) => line.quantity > 0);\n\n const saved = saveMockCartState({ ...cart, lines: nextLines });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async getRegions(): Promise<Array<{ id: string; name: string; currency_code: string; countries?: Array<{ id: string; iso_2: string; name: string; display_name?: string }> }>> {\n return getMockRegions();\n }\n\n async completeCheckout(cartId: string): Promise<Order> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const order = completeMockCheckout(cart, this.currencyCode, this.siteUrl);\n return order;\n }\n\n async getShippingMethods(cartId: string): Promise<ShippingMethod[]> {\n const cart = getMockCartState(cartId);\n return getMockShippingMethods(cart?.regionId);\n }\n\n async getRegionCountries(regionId: string) {\n return getMockRegionCountries(regionId);\n }\n\n async addShippingMethod(cartId: string, methodId: string): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const allowed = getMockShippingMethods(cart.regionId).some((method) => method.id === methodId);\n if (!allowed) {\n throw new ProviderAPIError(`Unknown mock shipping method: ${methodId}`, 'mock', 400);\n }\n\n const saved = saveMockCartState({ ...cart, shippingMethodId: methodId });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async initiatePaymentSession(cartId: string, providerId: string): Promise<void> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const allowed = getMockPaymentMethods(this.currencyCode).some((method) => method.id === providerId);\n if (!allowed) {\n throw new ProviderAPIError(`Unknown mock payment method: ${providerId}`, 'mock', 400);\n }\n\n saveMockCartState({ ...cart, paymentProviderId: providerId });\n }\n\n async applyDiscountCode(cartId: string, code: string): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const normalized = code.trim();\n if (!normalized) {\n throw new ProviderAPIError('Discount code is required.', 'mock', 400);\n }\n\n const saved = saveMockCartState({ ...cart, discountCode: normalized });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async removeDiscountCode(cartId: string, _code: string): Promise<Cart> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n const saved = saveMockCartState({ ...cart, discountCode: undefined });\n return buildMockCart(saved, this.currencyCode, this.siteUrl);\n }\n\n async getOrders(_options: GetOrdersOptions): Promise<Order[]> {\n return getMockAdminOrders().orders;\n }\n\n async getPaymentMethods(options: PaymentMethodsOptions): Promise<PaymentMethod[]> {\n return getMockPaymentMethods(options.currencyCode ?? this.currencyCode);\n }\n\n async getStockLocations(): Promise<StockLocation[]> {\n return getMockStockLocations();\n }\n\n async checkInventoryLevels(variantId: string): Promise<InventoryLevel[]> {\n return getMockInventoryLevels(variantId);\n }\n\n async validateCartStock(cartId: string): Promise<StockValidation> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n throw new ResourceNotFoundError('cart', cartId);\n }\n\n return validateMockCartStock(cart);\n }\n\n async getFulfillmentOptions(cartId: string, _salesChannelId: string): Promise<FulfillmentOption[]> {\n const cart = getMockCartState(cartId);\n return getMockFulfillmentOptions(cart?.regionId);\n }\n\n async cancelOrder(orderId: string): Promise<Order> {\n const order = getMockOrder(orderId);\n if (!order) {\n throw new ResourceNotFoundError('order', orderId);\n }\n\n return saveMockOrder({\n ...order,\n status: 'cancelled',\n updatedAt: new Date().toISOString(),\n cancelledAt: new Date().toISOString(),\n });\n }\n\n async createFulfillment(_orderId: string, _items?: Array<{ id: string; quantity: number }>): Promise<void> {\n return;\n }\n\n async createRefund(orderId: string, _amount?: number, _reason?: string): Promise<void> {\n const order = getMockOrder(orderId);\n if (!order) {\n throw new ResourceNotFoundError('order', orderId);\n }\n\n saveMockOrder({\n ...order,\n status: 'refunded',\n paymentStatus: 'refunded',\n updatedAt: new Date().toISOString(),\n });\n }\n\n async getAdminOrders(): Promise<{ orders: Order[]; count: number }> {\n return getMockAdminOrders();\n }\n\n async getAdminRegions(): Promise<Region[]> {\n return getMockAdminRegions();\n }\n\n async getStorefrontContext(): Promise<StorefrontContext> {\n return {\n id: 'mock-storefront',\n name: 'Mock Storefront',\n platformType: 'mock',\n requiresProductScoping: false,\n currencyCode: this.currencyCode,\n locale: 'en-US',\n metadata: {\n mode: 'design',\n },\n };\n }\n\n isStorefrontRequired(): boolean {\n return false;\n }\n}\n","/**\n * @thorprovider/adapters v2.0\n * Provider Factory - Create commerce providers dynamically\n *\n * This factory is bound to SupportedProviderType from @thorprovider/types (L1).\n * When adding a new provider:\n * 1. Update SupportedProviderType enum in packages/types/src/provider.ts\n * 2. Add new discriminated union case here\n * 3. Create packages/adapters/src/providers/[platform]/\n * 4. Implement CommerceProvider interface\n */\n\nimport type { CommerceProvider } from '../types';\nimport { MedusaProvider, type MedusaProviderConfig } from '../providers/medusa';\nimport { ShopifyProvider, type ShopifyProviderConfig } from '../providers/shopify';\nimport { BigCommerceProvider, type BigCommerceProviderConfig } from '../providers/bigcommerce';\nimport { WooCommerceProvider, type WooCommerceProviderConfig } from '../providers/woocommerce';\nimport { SpreeProvider, type SpreeProviderConfig } from '../providers/spree';\nimport { MagentoProvider, type MagentoProviderConfig } from '../providers/magento';\nimport { StelOrderProvider, type StelOrderProviderConfig } from '../providers/stelorder';\nimport { MockProvider, type MockProviderConfig } from '../providers/mock';\nimport { ProviderNotFoundError, ConfigurationError } from '../core/errors';\nimport type { ProviderTypeString } from '@thorprovider/types';\n\n/**\n * Supported provider types (imported from @thorprovider/types L1)\n * Kept for backward compatibility; prefer ProviderTypeString from @thorprovider/types\n */\nexport type ProviderType = ProviderTypeString;\n\n/**\n * Provider configuration discriminated union\n */\nexport type ProviderFactoryConfig =\n | { provider: 'mock'; config: MockProviderConfig }\n | { provider: 'medusa'; config: MedusaProviderConfig }\n | { provider: 'stelorder'; config: StelOrderProviderConfig }\n | { provider: 'shopify'; config: ShopifyProviderConfig }\n | { provider: 'bigcommerce'; config: BigCommerceProviderConfig }\n | { provider: 'woocommerce'; config: WooCommerceProviderConfig }\n | { provider: 'spree'; config: SpreeProviderConfig }\n | { provider: 'magento'; config: MagentoProviderConfig };\n\n/**\n * Runtime provider configuration (accepts any ProviderTypeString from env vars)\n */\nexport type RuntimeProviderConfig = {\n provider: ProviderTypeString;\n config: Record<string, unknown>;\n};\n\n/**\n * Create a commerce provider instance\n * \n * @example\n * ```ts\n * const commerce = createProvider({\n * provider: 'medusa',\n * config: {\n * baseUrl: process.env.MEDUSA_BACKEND_URL,\n * publishableKey: process.env.MEDUSA_PUBLISHABLE_KEY,\n * }\n * });\n * \n * const products = await commerce.getProducts();\n * ```\n */\nexport function createProvider(options: ProviderFactoryConfig | RuntimeProviderConfig): CommerceProvider {\n if (!options || !options.provider) {\n throw new ConfigurationError('Provider type is required');\n }\n \n if (!options.config) {\n throw new ConfigurationError('Provider configuration is required');\n }\n \n const config = options.config as any;\n \n switch (options.provider) {\n case 'mock':\n return new MockProvider(config);\n case 'medusa':\n return new MedusaProvider(config);\n case 'stelorder':\n return new StelOrderProvider(config);\n case 'shopify':\n return new ShopifyProvider(config);\n case 'bigcommerce':\n return new BigCommerceProvider(config);\n case 'woocommerce':\n return new WooCommerceProvider(config);\n case 'spree':\n return new SpreeProvider(config);\n case 'magento':\n return new MagentoProvider(config);\n \n default:\n throw new ProviderNotFoundError(String((options as any).provider));\n }\n}\n\n/**\n * Type guard to check if a provider is of a specific type\n */\nexport function isProviderType<T extends ProviderType>(\n provider: CommerceProvider,\n type: T\n): boolean {\n return provider.name === type;\n}\n"],"mappings":"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","names":["import_types","bcrypt","Medusa","import_js_sdk","Medusa","transformMoney","transformImage","transformProduct","transformCollection","transformCartItem","transformCart","transformProduct","transformCollection","transformCart","transformMoney","transformImage","transformProduct","transformCollection","transformCart","transformProduct","transformCollection","transformCart","transformMoney","transformImage","transformProduct","transformCollection","transformCart","minorUnit","divisor","transformOrder","transformMoney","transformProduct","transformCollection","transformCart","transformOrder","transformProduct","transformCollection","transformCart","transformAddress","transformOrder","transformProduct","transformCollection","transformCart","transformOrder","toMoney","transformProduct","transformCollection","transformCart","totalVal","transformAddress","transformOrder","toMoney","GET_PRODUCTS","GET_CART","transformProduct","GET_PRODUCTS","transformCollection","GET_CART","transformCart","transformOrder","DEFAULT_RETRY_CONFIG","sleep","calculateDelay","isRetryableError","logger"]}
|