@thorprovider/adapters 5.0.9 → 5.0.11
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/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-test.log +897 -0
- package/.turbo/turbo-type-check.log +0 -0
- package/AGENTS.md +1 -1
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.d.mts +348 -11
- package/dist/index.d.ts +348 -11
- package/dist/index.js +1393 -496
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1386 -498
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/publish.log +93 -0
- package/src/core/errors.ts +31 -0
- package/src/factory/index.ts +16 -6
- package/src/factory/provider-types.test.ts +32 -0
- package/src/factory/provider-types.ts +176 -0
- package/src/index.ts +6 -4
- package/src/providers/index.ts +1 -1
- package/src/providers/medusa/available-filters.test.ts +280 -0
- package/src/providers/medusa/catalog-facet-support.test.ts +715 -0
- package/src/providers/medusa/catalog-query.test.ts +422 -0
- package/src/providers/medusa/catalog-sort.test.ts +175 -0
- package/src/providers/medusa/index.test.ts +480 -0
- package/src/providers/medusa/index.ts +1490 -518
- package/src/providers/medusa/live-smoke.test.ts +68 -0
- package/src/providers/medusa/transforms.test.ts +177 -0
- package/src/providers/medusa/transforms.ts +145 -66
- package/src/providers/mock/catalog-query.test.ts +355 -0
- package/src/providers/mock/index.test.ts +47 -0
- package/src/providers/mock/index.ts +43 -1
- package/src/providers/mock/mock.ts +324 -2
- package/src/types/completion.ts +57 -0
- package/src/types/index.ts +7 -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/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 public readonly details?: Record<string, unknown>\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 // Medusa v2 store cart items return flat fields (product_title, variant_title,\n // product_handle, thumbnail) instead of a nested variant.product object.\n const merchandiseId = variant?.id ?? item.variant_id ?? '';\n const merchandiseTitle = variant?.title ?? item.variant_title ?? '';\n const productId = product?.id ?? item.product_id ?? '';\n const productHandle = product?.handle ?? item.product_handle ?? '';\n const productTitle = product?.title ?? item.product_title ?? '';\n const thumbnail = product?.thumbnail ?? item.thumbnail ?? '';\n\n return {\n id: item.id,\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: transformMoney(totalCents, currencyCode),\n },\n merchandise: {\n id: merchandiseId,\n title: merchandiseTitle,\n selectedOptions:\n variant?.options?.map((opt: any) => ({\n name: (opt as any).option?.title ?? '',\n value: opt.value ?? '',\n })) ?? [],\n product: {\n id: productId,\n handle: productHandle,\n title: productTitle,\n featuredImage: thumbnail ? transformImage(thumbnail, productTitle) : 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 private regionId?: 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 this.regionId = config.regionId;\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 const regionId = options?.regionId ?? this.regionId;\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 = 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 (regionId) {\n queryParams.region_id = 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 const regionId = options.regionId ?? this.regionId;\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 = 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 (regionId) {\n queryParams.region_id = 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 // --- Sales channel scoping ---\n // Applied unconditionally: the Thor Commerce plugin endpoint resolves the\n // sales channel from the publishable key itself. An explicit channel id\n // (options.salesChannelId ?? env) is only needed for the legacy N+1\n // fallback on backends without the plugin.\n const salesChannelId =\n options?.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n const activeCollectionIds = await this._getChannelCollections(salesChannelId);\n if (activeCollectionIds) {\n result = result.filter((c: Collection) => activeCollectionIds.has(c.id));\n }\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 /**\n * Returns the set of product-collection IDs that have at least one product\n * available in the given sales channel (legacy fallback).\n *\n * @deprecated Use `_getChannelCollections()` instead (backed by Thor Commerce plugin).\n */\n private async _getActiveCollectionIds(salesChannelId: string): Promise<Set<string>> {\n this.logger.debug('_getActiveCollectionIds', { salesChannelId });\n const collectionIds = 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 fields: '+collections.id',\n limit,\n offset,\n } as any)) as any;\n\n for (const product of products ?? []) {\n for (const col of product.collections ?? []) {\n if (col?.id) collectionIds.add(col.id);\n }\n }\n\n if (!products || products.length < limit) break;\n offset += limit;\n }\n\n this.logger.debug('_getActiveCollectionIds result', { count: collectionIds.size });\n return collectionIds;\n }\n\n /**\n * Fetch channel-scoped collections from Thor Commerce plugin.\n * Uses `GET /store/thor/collections` — the endpoint resolves the sales\n * channel from the publishable key header itself.\n *\n * Falls back to `_getActiveCollectionIds()` (legacy N+1) when the plugin is\n * not available; the legacy fallback needs an explicit `salesChannelId`.\n * Returns `null` when no scoping could be performed.\n */\n private async _getChannelCollections(salesChannelId?: string): Promise<Set<string> | null> {\n try {\n const url = `${this.baseUrl}/store/thor/collections`;\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 || !response.ok) {\n this.logger.debug('Thor plugin collections endpoint unavailable, falling back to legacy method');\n return this._legacyChannelCollections(salesChannelId);\n }\n\n const data = await response.json();\n const collectionIds = new Set<string>();\n for (const col of data.collections ?? []) {\n if (col?.id) collectionIds.add(col.id);\n }\n\n this.logger.debug('_getChannelCollections result (Thor plugin)', { count: collectionIds.size });\n return collectionIds;\n } catch (error) {\n this.logger.warn('Failed to fetch channel collections from Thor plugin, falling back to legacy method', {\n error: error instanceof Error ? error.message : String(error),\n });\n return this._legacyChannelCollections(salesChannelId);\n }\n }\n\n /**\n * Legacy fallback for `_getChannelCollections()` when the Thor plugin is not\n * installed. Requires an explicit `salesChannelId`; returns `null` otherwise.\n */\n private async _legacyChannelCollections(salesChannelId?: string): Promise<Set<string> | null> {\n if (!salesChannelId) {\n this.logger.warn(\n 'Cannot scope collections: Thor plugin unavailable and no sales channel id provided; returning unscoped collections',\n );\n return null;\n }\n return this._getActiveCollectionIds(salesChannelId);\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. The endpoint\n * resolves the sales channel from the publishable key header itself, so no\n * explicit channel id is required when the plugin is installed.\n *\n * Falls back to `_getActiveCategoryIds()` (legacy N+1) when the plugin is\n * not available. The legacy fallback needs an explicit `salesChannelId`;\n * when none is provided and the plugin is unavailable, returns `null` to\n * signal that scoping is not possible and the caller should skip filtering.\n *\n * @param salesChannelId - Only used by the legacy fallback (plugin absent).\n * @returns Set of category IDs active in the channel, or `null` when no\n * scoping could be performed.\n */\n private async _getChannelCategories(salesChannelId?: string): Promise<Set<string> | null> {\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 || !response.ok) {\n // Plugin not installed — fall back to legacy N+1 method\n this.logger.debug('Thor plugin categories endpoint unavailable, falling back to legacy method');\n return this._legacyChannelCategories(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._legacyChannelCategories(salesChannelId);\n }\n }\n\n /**\n * Legacy fallback for `_getChannelCategories()` when the Thor plugin is not\n * installed. Requires an explicit `salesChannelId`; returns `null` otherwise.\n */\n private async _legacyChannelCategories(salesChannelId?: string): Promise<Set<string> | null> {\n if (!salesChannelId) {\n this.logger.warn(\n 'Cannot scope categories: Thor plugin unavailable and no sales channel id provided; returning unscoped categories',\n );\n return null;\n }\n return this._getActiveCategoryIds(salesChannelId);\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 // Applied unconditionally: the Thor Commerce plugin endpoint resolves the\n // sales channel from the publishable key itself. An explicit channel id\n // (options.salesChannelId ?? env) is only needed for the legacy N+1\n // fallback on backends without the plugin.\n const salesChannelId =\n options.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n const activeCategoryIds = await this._getChannelCategories(salesChannelId);\n if (activeCategoryIds) {\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 // Region-based pricing (calculated_price requires region_id in Medusa v2)\n if (this.regionId) {\n categoryQueryParams.region_id = this.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 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; salesChannelId?: string }): Promise<Cart> {\n this.logger.debug('createCart', {\n regionId: options?.regionId,\n salesChannelId: options?.salesChannelId,\n });\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 // Explicit sales channel scope. Normally Medusa auto-injects the channel\n // from the publishable key when it maps to exactly one channel, but\n // passing it explicitly is required when the key maps to multiple\n // channels (otherwise cart creation errors).\n const salesChannelId =\n options?.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n createPayload.sales_channel_id = salesChannelId;\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 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 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 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 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"]}
|
|
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/provider-types.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\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 StorefrontConfigError,\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 SupportedProviderType,\n PROVIDER_METADATA,\n isSupportedProviderType,\n getProviderMetadata,\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 MOCK_SALES_CHANNEL_ID,\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 * Storefront validation error.\n * Thrown when storefront configuration is invalid or missing.\n *\n * Moved here from `@thorprovider/types` so that package stays type-only.\n *\n * @example\n * ```typescript\n * throw new StorefrontConfigError(\n * 'Medusa requires NEXT_PUBLIC_SALES_CHANNEL_ID',\n * 'medusa',\n * 'NEXT_PUBLIC_SALES_CHANNEL_ID',\n * );\n * ```\n */\nexport class StorefrontConfigError extends Error {\n public readonly platformType: string;\n public readonly requiredEnvVar?: string;\n\n constructor(\n message: string,\n platformType: string,\n requiredEnvVar?: string,\n ) {\n super(message);\n this.name = 'StorefrontConfigError';\n this.platformType = platformType;\n this.requiredEnvVar = requiredEnvVar;\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 public readonly details?: Record<string, unknown>\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 * Backend-authoritative money (change B, decision 9).\n *\n * A finite backend amount is carried through unchanged, including a legitimate\n * zero; a missing or non-finite amount becomes an empty `amount` string instead\n * of an invented zero, so the runtime boundary can surface the backend gap\n * rather than fabricate a total. The currency comes from the backend and is\n * never defaulted to a hardcoded `USD`.\n */\nfunction transformAmount(\n amount: number | null | undefined,\n currencyCode?: string | null,\n): Money {\n const currencyCodeUpper = (currencyCode ?? '').toUpperCase();\n if (typeof amount !== 'number' || !Number.isFinite(amount)) {\n return { amount: '', currencyCode: currencyCodeUpper };\n }\n return { amount: amount.toFixed(2), currencyCode: currencyCodeUpper };\n}\n\n/**\n * Product price projection (change B, decision 6).\n *\n * Unlike cart/order money, a product variant price is NOT fabricated: an\n * absent or non-finite backend amount is carried as an empty `amount` string\n * so the runtime boundary (`parseMoney`) can reject it and mark the variant\n * unavailable instead of showing a fake zero. A backend-resolved valid zero is\n * preserved as `\"0.00\"`. The currency comes from the backend or the configured\n * context — never a hardcoded `USD` (an unresolved currency stays empty and is\n * likewise rejected downstream).\n */\nexport function transformProductPrice(\n amount: number | null | undefined,\n currencyCode?: string | null,\n): Money {\n return transformAmount(amount, currencyCode);\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\n): ProductVariant {\n let priceAmount: number | null | undefined;\n let priceCurrency: string | undefined = 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 (match the context currency, else the first)\n else if (variant.prices && variant.prices.length > 0) {\n const target = currencyCode?.toLowerCase();\n const price =\n (target\n ? variant.prices.find((p: any) => p.currency_code === target)\n : undefined) ?? variant.prices[0];\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 // NOTE: this is stock availability only. Price availability is a separate\n // concern resolved by the runtime boundary; an unpriced variant keeps its\n // stock-derived availability and carries an empty amount.\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 is optional descriptive data only — never API/purchase identity.\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: transformProductPrice(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\n): Product {\n const variants = product.variants?.map((v: any) => transformProductVariant(v, currencyCode)) ?? [];\n\n // Price range from resolvable variant prices only. An unresolved price is\n // carried as an empty amount (never fabricated as zero); if no variant is\n // priced, the range is unresolved too and the runtime marks it unavailable.\n const validPrices = variants\n .map((v: ProductVariant) => v.price)\n .filter((money: Money) => money.amount !== '' && Number.isFinite(Number(money.amount)))\n .map((money: Money) => Number(money.amount));\n const rangeCurrency =\n variants.find((v: ProductVariant) => v.price.currencyCode)?.price.currencyCode ??\n (currencyCode ?? '').toUpperCase();\n const minPrice = validPrices.length > 0 ? Math.min(...validPrices) : undefined;\n const maxPrice = validPrices.length > 0 ? Math.max(...validPrices) : undefined;\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 multiply by 100 (that was a compensatory hack for the old /100\n // bug) and do NOT fabricate a zero for an unresolved price.\n minVariantPrice: {\n amount: minPrice !== undefined ? minPrice.toFixed(2) : '',\n currencyCode: rangeCurrency,\n },\n maxVariantPrice: {\n amount: maxPrice !== undefined ? maxPrice.toFixed(2) : '',\n currencyCode: rangeCurrency,\n },\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 authoritative line total a Medusa cart line reports.\n *\n * Only backend-supplied totals are used (`total` after discounts, then\n * `item_total`, then `subtotal`); the adapter never multiplies a unit price by\n * a quantity to invent a line total. A legitimate `0` is preserved and an\n * absent total is returned as `undefined` so the money transform carries an\n * empty amount instead of fabricating a value.\n */\nfunction resolveAuthoritativeLineTotal(item: any): number | undefined {\n const candidates = [item?.total, item?.item_total, item?.subtotal];\n\n for (const candidate of candidates) {\n if (typeof candidate === 'number' && Number.isFinite(candidate)) {\n return candidate;\n }\n }\n\n return undefined;\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\n // Medusa v2 store cart items return flat fields (product_title, variant_title,\n // product_handle, thumbnail) instead of a nested variant.product object.\n const merchandiseId = variant?.id ?? item.variant_id ?? '';\n const merchandiseTitle = variant?.title ?? item.variant_title ?? '';\n const productId = product?.id ?? item.product_id ?? '';\n const productHandle = product?.handle ?? item.product_handle ?? '';\n const productTitle = product?.title ?? item.product_title ?? '';\n const thumbnail = product?.thumbnail ?? item.thumbnail ?? '';\n\n return {\n id: item.id,\n quantity: item.quantity ?? 1,\n cost: {\n totalAmount: transformAmount(resolveAuthoritativeLineTotal(item), currencyCode),\n // Backend unit price, carried so the display never derives it locally.\n unitPrice: transformAmount(item?.unit_price, currencyCode),\n },\n merchandise: {\n id: merchandiseId,\n title: merchandiseTitle,\n selectedOptions:\n variant?.options?.map((opt: any) => ({\n name: (opt as any).option?.title ?? '',\n value: opt.value ?? '',\n })) ?? [],\n product: {\n id: productId,\n handle: productHandle,\n title: productTitle,\n featuredImage: thumbnail ? transformImage(thumbnail, productTitle) : transformImage('', ''),\n },\n },\n };\n}\n\n/**\n * Transform Medusa Cart to unified Cart.\n *\n * Totals are backend-authoritative (change B, decision 9): subtotal, discount,\n * tax, shipping and total are carried straight from the cart response, a\n * legitimate zero is preserved, and no amount is derived locally.\n *\n * `subtotalAmount` prefers the backend's `item_subtotal` (the sum of the line\n * items, excluding shipping and tax). Medusa's native `subtotal` also folds in\n * `shipping_subtotal`; presenting that as the commercial subtotal would\n * double-count shipping. When `item_subtotal` is absent the native `subtotal`\n * is used unchanged, preserving backward compatibility.\n *\n * The cart's sales channel, region and currency are carried so the runtime can\n * enforce the validated single-store context, and `completed_at` is carried so\n * a completed cart can be reconciled.\n */\nexport function transformCart(cart: any): Cart {\n const currencyCode = cart.currency_code;\n\n return {\n id: cart.id,\n checkoutUrl: `/checkout/${cart.id}`, // Medusa doesn't have a direct checkout URL\n cost: {\n subtotalAmount: transformAmount(\n typeof cart.item_subtotal === 'number' ? cart.item_subtotal : cart.subtotal,\n currencyCode,\n ),\n discountAmount: transformAmount(cart.discount_total, currencyCode),\n totalTaxAmount: transformAmount(cart.tax_total, currencyCode),\n shippingAmount: transformAmount(cart.shipping_total, currencyCode),\n totalAmount: transformAmount(cart.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 salesChannelId: cart.sales_channel_id ?? undefined,\n regionId: cart.region_id ?? undefined,\n currencyCode:\n typeof currencyCode === 'string' ? currencyCode.toUpperCase() : undefined,\n selectedShippingMethodId: cart.shipping_methods?.[0]?.id ?? undefined,\n selectedShippingOptionId:\n cart.shipping_methods?.[0]?.shipping_option_id ?? undefined,\n completedAt: cart.completed_at\n ? (typeof cart.completed_at === 'string'\n ? cart.completed_at\n : cart.completed_at?.toISOString())\n : undefined,\n metadata: cart.metadata ?? 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: transformAmount(item.unit_price, currencyCode),\n total: transformAmount(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 — backend-authoritative; a legitimate zero is preserved and no\n // amount is derived locally. `subtotal` prefers the backend's\n // `item_subtotal` (lines only, excluding shipping/tax); Medusa's native\n // `subtotal` folds in `shipping_subtotal`, so falling back to it is only\n // for installs that do not supply `item_subtotal`.\n subtotal: transformAmount(\n typeof order.item_subtotal === 'number' ? order.item_subtotal : order.subtotal,\n currencyCode,\n ),\n total: transformAmount(order.total, currencyCode),\n tax: transformAmount(order.tax_total, currencyCode),\n shipping: transformAmount(order.shipping_total, currencyCode),\n discount: transformAmount(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 CatalogQuery,\n CatalogAppliedFilters,\n CatalogQueryOutcome,\n CatalogFacetId,\n CatalogFacetDemonstrationSource,\n FacetSupport,\n} from '@thorprovider/types';\nimport { StorefrontConfigError } from '../../core/errors';\nimport type { CommerceProvider, ProviderConfig } from '../../types/provider';\nimport type {\n CartCompletionCapable,\n CartCompletionError,\n CartCompletionResult,\n} from '../../types/completion';\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,+items.total,+items.unit_price,+items.item_subtotal,+items.item_total,+shipping_methods,+shipping_methods.id,+shipping_methods.shipping_option_id';\n\n/**\n * Fields requested when completing a cart into an order.\n *\n * The native `complete` default projection is minimal, so the returned order's\n * `items` are empty. `*items` selects all fields of the `items` relation\n * (Medusa field syntax: `*` retrieves all fields of a relation), which yields\n * each line's `id`, `title`, `product_title`, `variant_title`, `quantity`,\n * `unit_price` and `total` (all major units, backend-authoritative). The same\n * query is applied when completion returns a cart-with-error, and `*items` is\n * valid for both entities.\n */\nconst MEDUSA_ORDER_COMPLETION_FIELDS = '*items';\n\n/**\n * Per-request catalog listing bound (change B, decision 5).\n *\n * Listing is paginated with a configured per-request bound instead of an\n * unbounded scan. Live probes against the acceptance backend accepted\n * `limit` 1/50/100/200/1000, so 50 is a deliberately conservative *configured*\n * bound — NOT a claimed backend maximum. Override with\n * `MEDUSA_CATALOG_PAGE_SIZE` or `MedusaProviderConfig.catalogPageSize`.\n */\nconst DEFAULT_CATALOG_PAGE_SIZE = 50;\n\nfunction resolveCatalogPageSize(configured?: number): number {\n const fromEnv =\n process.env.MEDUSA_CATALOG_PAGE_SIZE !== undefined\n ? Number(process.env.MEDUSA_CATALOG_PAGE_SIZE)\n : undefined;\n const raw = configured ?? fromEnv;\n if (raw === undefined || !Number.isFinite(raw) || raw < 1) {\n return DEFAULT_CATALOG_PAGE_SIZE;\n }\n return Math.floor(raw);\n}\n\n/**\n * Resolve the configured sales channel for cart scoping.\n *\n * Prefers the server-only `MEDUSA_SALES_CHANNEL_ID`, then the legacy public\n * `NEXT_PUBLIC_SALES_CHANNEL_ID`. Returns `undefined` when neither is set, so\n * the caller can fall back to the backend's publishable-key channel.\n */\nfunction resolveConfiguredSalesChannelId(): string | undefined {\n return (\n process.env.MEDUSA_SALES_CHANNEL_ID ??\n process.env.NEXT_PUBLIC_SALES_CHANNEL_ID\n );\n}\n\n/**\n * Canonical Thor sort keys → Medusa Store `/store/products` `order` field names.\n *\n * Medusa's Store API only accepts fields on the route's allowed list (for\n * products: `title`, `created_at`, …) and fails a request with a 400 when the\n * field is not allowed (Store API pagination/sort contract). Thor's canonical\n * keys therefore cannot be passed through raw:\n *\n * - `featured` → no `order` (server default ordering)\n * - `name` → `title`\n * - `newest` → `-created_at`\n *\n * Legacy `SortOption` keys (`price-asc`, `price-desc`, `rating`) are not\n * supported at the query level and map to `null` (server default), preserving\n * the existing client-side behavior instead of sending an invalid order field.\n * `null` means \"omit `order` entirely\".\n */\nconst MEDUSA_SORT_KEY_MAP: Record<string, string | null> = {\n featured: null,\n name: 'title',\n newest: '-created_at',\n 'price-asc': null,\n 'price-desc': null,\n rating: null,\n};\n\n/**\n * Effective category scope for a canonical query (E2 task 2.2).\n *\n * The route category scope (`categoryScope`) is always retained; the\n * `categories` filter narrows within it. Returns `undefined` when no category\n * filter is requested, `[]` for an explicit empty intersection (a valid\n * zero-result query), or the handles to resolve to backend IDs.\n */\nfunction resolveEffectiveCategoryHandles(\n query: CatalogQuery,\n): string[] | undefined {\n const { categoryScope, categories } = query;\n if (categoryScope === undefined) return categories;\n if (categories === undefined) return [categoryScope];\n return categories.filter((handle) => handle === categoryScope);\n}\n\n/**\n * Filters a successful (or explicitly-empty) canonical result reports as\n * applied. Every requested filter that the adapter actually applied appears\n * here; unappliable filters never reach this path (they return a typed error).\n *\n * `includeAdvanced` is set only on a path that genuinely applied the requested\n * price/stock/attribute filters (the advanced endpoint execution, or a\n * zero-result scope short-circuit where the requested filters are moot because\n * the scope already matches nothing). The basic `/store/products` path never\n * includes them — it does not accept those parameters.\n */\nfunction buildAppliedCatalogFilters(\n query: CatalogQuery,\n effectiveCategoryHandles: string[] | undefined,\n includeAdvanced = false,\n): CatalogAppliedFilters {\n return {\n ...(query.text ? { text: query.text } : {}),\n ...(effectiveCategoryHandles !== undefined\n ? { categories: effectiveCategoryHandles }\n : {}),\n ...(query.collections !== undefined\n ? { collections: query.collections }\n : {}),\n ...(includeAdvanced && query.priceMin !== undefined\n ? { priceMin: query.priceMin }\n : {}),\n ...(includeAdvanced && query.priceMax !== undefined\n ? { priceMax: query.priceMax }\n : {}),\n ...(includeAdvanced && query.inStock !== undefined\n ? { inStock: query.inStock }\n : {}),\n ...(includeAdvanced && query.attributes !== undefined\n ? { attributes: query.attributes }\n : {}),\n };\n}\n\n/**\n * Basic fields the canonical `/store/products` endpoint actually accepts. A\n * basic demonstration's `appliedQuery` is limited to these; price/stock/\n * attribute filters are never recorded as applied by the basic endpoint because\n * it does not accept them.\n */\nfunction buildBasicDemonstratedQuery(query: CatalogQuery): CatalogQuery {\n return {\n ...(query.text !== undefined ? { text: query.text } : {}),\n ...(query.categoryScope !== undefined\n ? { categoryScope: query.categoryScope }\n : {}),\n ...(query.categories !== undefined ? { categories: query.categories } : {}),\n ...(query.collections !== undefined\n ? { collections: query.collections }\n : {}),\n };\n}\n\n/**\n * The optional advanced listing endpoint. Medusa's Store `/store/products`\n * endpoint (the equivalent basic endpoint) applies category/collection/text/\n * sort/pagination only; price, stock, and attribute filters require this\n * separate search plugin (E2 Decision 5). Its presence is proven by a real\n * request, never by a capability boolean or returned facet metadata.\n */\nconst ADVANCED_SEARCH_ENDPOINT = '/store/search';\n\n/** The canonical basic listing endpoint that serves a basic-only request. */\nconst BASIC_LISTING_ENDPOINT = '/store/products';\n\n/**\n * Canonical query fields that require the optional advanced endpoint. Empty\n * means the request is basic-only and can be served by `/store/products`.\n */\nfunction collectRequestedAdvancedFields(query: CatalogQuery): string[] {\n const fields: string[] = [];\n if (query.priceMin !== undefined) fields.push('priceMin');\n if (query.priceMax !== undefined) fields.push('priceMax');\n if (query.inStock !== undefined) fields.push('inStock');\n for (const name of Object.keys(query.attributes ?? {})) {\n fields.push(`attr.${name}`);\n }\n return fields;\n}\n\n/** Map a requested advanced field name to the canonical facet id it needs. */\nfunction advancedFieldToFacet(field: string): CatalogFacetId {\n if (field === 'priceMin' || field === 'priceMax') return 'price';\n return field as CatalogFacetId;\n}\n\n/**\n * Advanced fields requested through the legacy `searchProductsAdvanced` options.\n * Empty means the caller asked for a basic-only search that `getProducts` can\n * faithfully serve as a fallback.\n */\nfunction collectAdvancedSearchRequestFields(\n options?: AdvancedSearchProductsOptions,\n): string[] {\n const fields: string[] = [];\n if (options?.priceMin !== undefined) fields.push('priceMin');\n if (options?.priceMax !== undefined) fields.push('priceMax');\n if (options?.inStockOnly === true) fields.push('inStock');\n if (options?.attributes && options.attributes.length > 0) {\n fields.push('attributes');\n }\n return fields;\n}\n\n/**\n * Parse a value the backend may serialize as a number or a numeric string into\n * a finite number, or `undefined`. Shared by the applied-filter readers so a\n * non-finite or missing bound is never treated as an applied filter.\n */\nfunction toFiniteNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n\n/**\n * Read the real backend's `applied_filters.price_range` object (`{ min, max }`,\n * or `null` when no price filter was applied) into finite bounds. A missing,\n * non-object, or non-finite bound yields `undefined` so the price facet is never\n * fabricated (E2 Decision 2: price requires a finite, ordered range).\n */\nfunction readAppliedPriceRange(\n applied: Record<string, unknown>,\n): { min?: number; max?: number } {\n const range = applied.price_range;\n if (!range || typeof range !== 'object' || Array.isArray(range)) return {};\n const record = range as Record<string, unknown>;\n return { min: toFiniteNumber(record.min), max: toFiniteNumber(record.max) };\n}\n\n/**\n * Read the filters a real advanced-endpoint response echoes as applied. Only\n * explicit `applied_filters`/`appliedFilters` keys count as proof; a response\n * that omits them demonstrates nothing and the facet stays held (E2 Decision 5:\n * returned facet metadata is not proof).\n *\n * The real backend emits `price_range` (object) and `is_available` (boolean);\n * the documented legacy aliases (`price`/`price_min`/`price_max`,\n * `inStock`/`isAvailable`/`available`) stay recognized (E2 Decision 1).\n */\nfunction mapAppliedFiltersToFacets(\n applied: Record<string, unknown>,\n): Set<CatalogFacetId> {\n const facets = new Set<CatalogFacetId>();\n const priceRange = readAppliedPriceRange(applied);\n const hasAppliedPriceRange =\n priceRange.min !== undefined && priceRange.max !== undefined;\n if (\n hasAppliedPriceRange ||\n 'price' in applied ||\n 'price_min' in applied ||\n 'price_max' in applied\n ) {\n facets.add('price');\n }\n if (\n typeof applied.is_available === 'boolean' ||\n 'inStock' in applied ||\n 'isAvailable' in applied ||\n 'available' in applied\n ) {\n facets.add('inStock');\n }\n const attributes = applied.attributes;\n if (attributes && typeof attributes === 'object' && !Array.isArray(attributes)) {\n for (const name of Object.keys(attributes)) {\n facets.add(`attr.${name}` as CatalogFacetId);\n }\n }\n return facets;\n}\n\n/**\n * Requested advanced fields the actual advanced-endpoint response did not\n * confirm as applied. A probe echo alone cannot guarantee the listing request\n * applied the filter, so the executed response is re-validated against every\n * requested field (value equality where the backend echoes a scalar) before a\n * result is reported as success (E2 task 2.4).\n */\nfunction collectUnappliedAdvancedFields(\n applied: Record<string, unknown>,\n query: CatalogQuery,\n): string[] {\n const unapplied: string[] = [];\n\n const priceRange = readAppliedPriceRange(applied);\n\n if (query.priceMin !== undefined) {\n const echoed = toFiniteNumber(\n priceRange.min ?? applied.price_min ?? applied.priceMin,\n );\n if (echoed !== query.priceMin) unapplied.push('priceMin');\n }\n if (query.priceMax !== undefined) {\n const echoed = toFiniteNumber(\n priceRange.max ?? applied.price_max ?? applied.priceMax,\n );\n if (echoed !== query.priceMax) unapplied.push('priceMax');\n }\n if (query.inStock === true) {\n const echoed =\n applied.is_available ??\n applied.isAvailable ??\n applied.inStock ??\n applied.available;\n if (echoed !== true && echoed !== 'true') unapplied.push('inStock');\n }\n\n const requestedAttributes = query.attributes ?? {};\n const appliedAttributes = applied.attributes;\n for (const name of Object.keys(requestedAttributes)) {\n const hasName =\n !!appliedAttributes &&\n typeof appliedAttributes === 'object' &&\n !Array.isArray(appliedAttributes) &&\n name in (appliedAttributes as Record<string, unknown>);\n if (!hasName) unapplied.push(`attr.${name}`);\n }\n\n return unapplied;\n}\n\n/**\n * Read a backend-supplied numeric facet value (range bound or option count).\n *\n * Returns `undefined` when the backend did not supply a finite number, so\n * callers can omit the value entirely instead of inventing a default. This is\n * the guard that keeps `getAvailableFilters` from fabricating ranges or counts\n * (E2 Decision 4; spec \"Facet counts and ranges are never fabricated\").\n */\nfunction readFiniteFacetNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\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 * Per-request catalog listing bound. Listing is paginated with this bound\n * instead of an unbounded scan; it is a configured safety bound, not a\n * backend maximum. Defaults to `MEDUSA_CATALOG_PAGE_SIZE` or 50.\n */\n catalogPageSize?: number;\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, CartCompletionCapable {\n readonly name = 'medusa';\n readonly version = '2.0.0';\n\n /**\n * Canonical catalog sort keys this provider applies at the query level.\n *\n * Advertises only the backend-verified orderings (E2 Decision 6). `price-asc`,\n * `price-desc`, and `rating` are intentionally absent: they are not applied at\n * the query level, so the listing never offers them as global sorts.\n *\n * The literal tuple is assignable to `CommerceProvider['supportedCatalogSortKeys']`\n * (`readonly CatalogSortKey[]`); it is written structurally here so the adapter\n * compiles against the published `@thorprovider/types` declaration.\n */\n readonly supportedCatalogSortKeys = ['featured', 'name', 'newest'] as const;\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 private regionId?: string;\n /** Configured per-request catalog listing bound (never an unbounded scan). */\n private catalogPageSize: number;\n\n /**\n * Per-scope cache of the truthful facet-support descriptor. The optional\n * advanced endpoint is probed once per demonstrated scope/query rather than on\n * every listing request (E2 task 2.4).\n */\n private facetSupportCache = new Map<string, Promise<FacetSupport>>();\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 this.regionId = config.regionId;\n this.catalogPageSize = resolveCatalogPageSize(config.catalogPageSize);\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 ? config.auth.customStorage\n ? {\n type: 'jwt',\n // Request-scoped custom storage: the caller supplies a per-request\n // token holder (for example a server request's customer JWT). The\n // SDK reads the token on every request and writes the login /\n // registration token back into the same holder, so a fresh\n // provider per request is authenticated without shared state.\n jwtTokenStorageMethod: 'custom',\n storage: config.auth.customStorage,\n }\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 /** Fields needed to price a product variant for the current region. */\n private buildProductFields(regionId?: string): string {\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 return regionId ? baseFields + pricingFields : baseFields;\n }\n\n /** Scope a store query to the configured storefront sales channel, if any. */\n private applySalesChannelScope(queryParams: Record<string, unknown>): void {\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n queryParams.sales_channel_id = [salesChannelId];\n }\n }\n\n /**\n * Directed single-product lookup by a supported native filter (`handle` or\n * `id`). This is independent of catalog listing pagination, so a known\n * product beyond the first listing page still resolves without scanning.\n *\n * Medusa's store API supports `handle` and `id` on `/store/products`; it\n * does not expose a variant filter there, so a variant is resolved from the\n * product once the product is known (see `getProductDetailByHandle` in the\n * runtime). No `limit` beyond 1 is issued.\n */\n private async fetchSingleProduct(\n filter: { handle?: string; id?: string },\n options?: { regionId?: string },\n ): Promise<Product | undefined> {\n const regionId = options?.regionId ?? this.regionId;\n\n const queryParams: Record<string, unknown> = {\n ...filter,\n limit: 1,\n fields: this.buildProductFields(regionId),\n };\n // Add region_id for region-based pricing\n if (regionId) {\n queryParams.region_id = regionId;\n }\n this.applySalesChannelScope(queryParams);\n\n const { products } = await this.sdk.store.product.list(queryParams as any);\n\n if (!products || products.length === 0) {\n this.logger.debug('Product not found', filter);\n return undefined;\n }\n\n return transformProduct(products[0], this.currencyCode);\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 () => this.fetchSingleProduct({ handle }, options),\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 /**\n * Directed product lookup by backend product ID. Independent of the first\n * listing page, mirroring `getProduct` for handle-based resolution.\n */\n async getProductById(\n id: string,\n options?: { regionId?: string },\n ): Promise<Product | undefined> {\n this.logger.debug('getProductById', { id, regionId: options?.regionId });\n\n try {\n return await this.withRetry(\n () => this.fetchSingleProduct({ id }, options),\n 'getProductById',\n { id, regionId: options?.regionId },\n );\n } catch (error: any) {\n throw new ProviderAPIError(\n `Failed to fetch product by id: ${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 const regionId = options.regionId ?? this.regionId;\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 = regionId ? baseFields + pricingFields : baseFields;\n\n // Map Thor sort keys to Medusa /store/products `order` field names.\n // Native endpoint supports: title, -title, created_at, -created_at.\n // Price/rating sorting is not supported — omitted so products-client\n // handles it client-side as before (see MEDUSA_SORT_KEY_MAP).\n\n // Bounded, paginated listing (change B, decision 5): the per-request\n // limit is the configured catalog bound, never an unbounded scan.\n const queryParams: any = {\n q: options.query,\n limit: options.first ?? this.catalogPageSize,\n offset:\n options.after !== undefined\n ? parseInt(String(options.after), 10)\n : options.skip,\n fields,\n };\n\n if (options.sortKey) {\n const mappedOrder = MEDUSA_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 (regionId) {\n queryParams.region_id = 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 /**\n * Canonical catalog query path (E2 task 2.2).\n *\n * Accepts a validated `CatalogQuery`, translates it into Medusa Store\n * `/store/products` parameters, and returns a truthful `CatalogQueryOutcome`.\n * The route category scope is always retained and intersected with the\n * `categories` filter; `categories`/`collections` handles are resolved to\n * backend IDs through the existing directed lookups (`getCategory`/\n * `getCollection`). Any requested filter this provider cannot apply\n * (price/`inStock`/attributes) is rejected as a typed `unsupported-query`\n * outcome naming the fields — never a partial success and never a silent\n * drop. Pagination is `offset = (page - 1) * pageSize`, defaulting to the\n * canonical page size.\n *\n * Legacy `getProducts`/`getCategoryProducts` are unchanged; this additive\n * method is the typed seam the runtime query bridge (E2 task 3.1) consumes.\n */\n async getCatalogProducts(query: CatalogQuery): Promise<CatalogQueryOutcome> {\n this.logger.debug('getCatalogProducts', query);\n\n // Sort support is advertised explicitly by the adapter; an unadvertised\n // sort is rejected before any provider call.\n if (\n query.sort !== undefined &&\n !this.supportedCatalogSortKeys.includes(query.sort)\n ) {\n return this.unsupportedCatalogOutcome(['sort']);\n }\n\n const effectiveCategoryHandles = resolveEffectiveCategoryHandles(query);\n\n try {\n const categoryIds =\n effectiveCategoryHandles !== undefined\n ? await this.resolveCategoryIds(effectiveCategoryHandles)\n : undefined;\n const collectionIds = query.collections\n ? await this.resolveCollectionIds(query.collections)\n : undefined;\n\n // The truthful support descriptor for this scope, proven against the real\n // optional endpoint. It is attached to every successful result.\n const facetSupport = await this.getCatalogFacetSupport({\n query,\n categoryIds,\n collectionIds,\n scope: query.categoryScope,\n });\n\n // Reject every requested advanced field that was not demonstrated BEFORE\n // any early zero-result return, so an unsupported filter is never hidden\n // behind an empty category intersection or an unresolved handle.\n const requestedAdvanced = collectRequestedAdvancedFields(query);\n const heldAdvanced = requestedAdvanced.filter(\n (field) => !facetSupport.offered.includes(advancedFieldToFacet(field)),\n );\n if (heldAdvanced.length > 0) {\n return this.unsupportedCatalogOutcome(heldAdvanced);\n }\n\n // A scope that matches nothing (explicit empty route-scope ∩ categories\n // intersection, or a requested category/collection that resolves to no\n // backend ID) is a valid zero-result query — never an unfiltered request.\n // Requested+offered advanced filters are included as applied because the\n // scope already excludes every product; they are not silently dropped.\n const emptyIntersection =\n effectiveCategoryHandles !== undefined &&\n effectiveCategoryHandles.length === 0;\n const categoryFilterEmpty =\n effectiveCategoryHandles !== undefined &&\n (categoryIds?.length ?? 0) === 0;\n const collectionFilterEmpty =\n query.collections !== undefined && (collectionIds?.length ?? 0) === 0;\n if (emptyIntersection || categoryFilterEmpty || collectionFilterEmpty) {\n return {\n ok: true,\n results: {\n products: [],\n appliedFilters: buildAppliedCatalogFilters(\n query,\n effectiveCategoryHandles,\n requestedAdvanced.length > 0,\n ),\n facetSupport,\n },\n };\n }\n\n // When advanced filters were requested and demonstrated, the request is\n // executed against the real advanced endpoint and re-validated there;\n // it is never served by the basic endpoint with the filters dropped.\n if (requestedAdvanced.length > 0) {\n return this.queryAdvancedCatalog(\n query,\n categoryIds,\n collectionIds,\n facetSupport,\n );\n }\n\n return await this.queryBasicCatalog(\n query,\n effectiveCategoryHandles,\n categoryIds,\n collectionIds,\n facetSupport,\n );\n } catch (error: any) {\n this.logger.error('getCatalogProducts error details', {\n message: error.message,\n status: error.status,\n });\n throw new ProviderAPIError(\n `Failed to run catalog query: ${error.message || 'Unknown error'}`,\n 'medusa',\n error.status,\n );\n }\n }\n\n /**\n * Execute a basic-only canonical query against the equivalent basic endpoint\n * `/store/products`, reporting the filters it actually applied.\n */\n private async queryBasicCatalog(\n query: CatalogQuery,\n effectiveCategoryHandles: string[] | undefined,\n categoryIds: string[] | undefined,\n collectionIds: string[] | undefined,\n facetSupport: FacetSupport,\n ): Promise<CatalogQueryOutcome> {\n const pageSize = query.pageSize ?? this.catalogPageSize;\n const page = query.page ?? 1;\n const regionId = this.regionId;\n const baseFields =\n '+variants,+variants.inventory_quantity,+options,+images,+thumbnail,+tags';\n const pricingFields = ',+variants.calculated_price,+variants.prices';\n\n const queryParams: any = {\n limit: pageSize,\n offset: (page - 1) * pageSize,\n fields: regionId ? baseFields + pricingFields : baseFields,\n };\n\n if (query.text) {\n queryParams.q = query.text;\n }\n if (categoryIds && categoryIds.length > 0) {\n queryParams.category_id = categoryIds;\n }\n if (collectionIds && collectionIds.length > 0) {\n queryParams.collection_id = collectionIds;\n }\n\n // Canonical sort → Medusa `order`; `null` omits the parameter entirely.\n if (query.sort) {\n const mappedOrder = MEDUSA_SORT_KEY_MAP[query.sort] ?? null;\n if (mappedOrder !== null) {\n queryParams.order = mappedOrder;\n }\n }\n\n if (regionId) {\n queryParams.region_id = regionId;\n }\n\n const salesChannelId = process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n if (salesChannelId) {\n queryParams.sales_channel_id = [salesChannelId];\n }\n\n const response = (await this.sdk.store.product.list(queryParams)) as any;\n const products = (response.products ?? []).map((p: any) =>\n transformProduct(p, this.currencyCode),\n );\n const count = response.count;\n\n return {\n ok: true,\n results: {\n products,\n // Total is only the backend's actual count; never manufactured.\n ...(typeof count === 'number' ? { total: count } : {}),\n appliedFilters: buildAppliedCatalogFilters(\n query,\n effectiveCategoryHandles,\n ),\n facetSupport,\n },\n };\n }\n\n /**\n * Execute an advanced canonical query against the real optional endpoint\n * `/store/search`, then re-validate that the response applied every requested\n * filter. A response that does not confirm a requested field, or an endpoint\n * failure, yields a typed `unsupported-query` error — never a partial result\n * labelled success and never a silent fallback to the basic endpoint.\n */\n private async queryAdvancedCatalog(\n query: CatalogQuery,\n categoryIds: string[] | undefined,\n collectionIds: string[] | undefined,\n facetSupport: FacetSupport,\n ): Promise<CatalogQueryOutcome> {\n const pageSize = query.pageSize ?? this.catalogPageSize;\n const page = query.page ?? 1;\n const advancedQuery = this.buildAdvancedSearchQuery(\n query,\n categoryIds ?? [],\n collectionIds ?? [],\n );\n advancedQuery.limit = pageSize;\n advancedQuery.offset = (page - 1) * pageSize;\n\n let data: any;\n try {\n // Custom route: use the SDK client so the publishable API key and headers\n // are applied automatically (building-storefronts `sdk-client-fetch`).\n data = await this.sdk.client.fetch(ADVANCED_SEARCH_ENDPOINT, {\n query: advancedQuery,\n });\n } catch (error: any) {\n this.logger.error('Advanced catalog listing failed', {\n message: error?.message,\n status: error?.status,\n });\n // Do not fall back to the basic endpoint: that would silently drop the\n // requested advanced filters.\n return this.unsupportedCatalogOutcome(\n collectRequestedAdvancedFields(query),\n );\n }\n\n const appliedRaw = data?.applied_filters ?? data?.appliedFilters;\n if (!appliedRaw || typeof appliedRaw !== 'object') {\n this.logger.warn('Advanced endpoint did not echo applied filters', {\n endpoint: ADVANCED_SEARCH_ENDPOINT,\n });\n return this.unsupportedCatalogOutcome(\n collectRequestedAdvancedFields(query),\n );\n }\n\n const unapplied = collectUnappliedAdvancedFields(\n appliedRaw as Record<string, unknown>,\n query,\n );\n if (unapplied.length > 0) {\n this.logger.warn('Advanced endpoint did not apply requested filters', {\n endpoint: ADVANCED_SEARCH_ENDPOINT,\n fields: unapplied,\n });\n return this.unsupportedCatalogOutcome(unapplied);\n }\n\n const products = (data.hits ?? []).map((hit: any) =>\n transformProduct(hit, this.currencyCode),\n );\n const total =\n typeof data.estimatedTotalHits === 'number'\n ? data.estimatedTotalHits\n : typeof data.count === 'number'\n ? data.count\n : undefined;\n\n return {\n ok: true,\n results: {\n products,\n ...(total !== undefined ? { total } : {}),\n appliedFilters: buildAppliedCatalogFilters(\n query,\n resolveEffectiveCategoryHandles(query),\n true,\n ),\n facetSupport,\n },\n };\n }\n\n /** Resolve category handles to Medusa category IDs via directed lookups. */\n private async resolveCategoryIds(handles: string[]): Promise<string[]> {\n const ids: string[] = [];\n for (const handle of handles) {\n const category = await this.getCategory(handle);\n if (category) ids.push(category.id);\n }\n return ids;\n }\n\n /** Resolve collection handles to Medusa collection IDs via directed lookups. */\n private async resolveCollectionIds(handles: string[]): Promise<string[]> {\n const ids: string[] = [];\n for (const handle of handles) {\n const collection = await this.getCollection(handle);\n if (collection) ids.push(collection.id);\n }\n return ids;\n }\n\n /**\n * Truthful facet-support descriptor for a scope (E2 task 2.4).\n *\n * Basic facets (`categories`, `collections`) are always offered: they are\n * applied by the canonical basic endpoint `/store/products`, and the\n * descriptor records that endpoint with the applied query and scope as their\n * demonstration source.\n *\n * Optional advanced facets (`price`, `inStock`, and advertised `attr.<name>`)\n * are offered only when the real optional `/store/search` endpoint has been\n * demonstrated with the applied query for the current scope AND the response\n * echoes the filter as applied. Otherwise they are held with the real probe\n * status/reason — a capability boolean or returned facet metadata is never\n * accepted as proof (E2 Decisions 4–5; spec \"Backend support is proven against\n * the real endpoint, not assumed\").\n *\n * The descriptor carries no counts or ranges and no invented timestamp; every\n * offered facet has an actual `{ endpoint, appliedQuery, scope }` source.\n */\n async getCatalogFacetSupport(\n options: {\n query?: CatalogQuery;\n categoryIds?: string[];\n collectionIds?: string[];\n scope?: string;\n } = {},\n ): Promise<FacetSupport> {\n const query = options.query ?? {};\n const scope = options.scope ?? query.categoryScope;\n const key = JSON.stringify({\n scope: scope ?? null,\n categoryIds: options.categoryIds ?? null,\n collectionIds: options.collectionIds ?? null,\n categories: query.categories ?? null,\n text: query.text ?? null,\n collections: query.collections ?? null,\n priceMin: query.priceMin ?? null,\n priceMax: query.priceMax ?? null,\n inStock: query.inStock ?? null,\n attributes: query.attributes ?? null,\n });\n const cached = this.facetSupportCache.get(key);\n if (cached) return cached;\n const pending = this.resolveCatalogFacetSupport(\n query,\n options.categoryIds,\n options.collectionIds,\n scope,\n );\n this.facetSupportCache.set(key, pending);\n return pending;\n }\n\n private async resolveCatalogFacetSupport(\n query: CatalogQuery,\n providedCategoryIds: string[] | undefined,\n providedCollectionIds: string[] | undefined,\n scope: string | undefined,\n ): Promise<FacetSupport> {\n // The advanced demonstration records the full applied filter query; the\n // basic demonstration records only the fields `/store/products` actually\n // accepts (text/scope/categories/collections). Price/stock/attributes are\n // never recorded as applied by an endpoint that does not accept them.\n const advancedDemonstratedQuery: CatalogQuery = {\n ...(query.text !== undefined ? { text: query.text } : {}),\n ...(query.categoryScope !== undefined\n ? { categoryScope: query.categoryScope }\n : {}),\n ...(query.categories !== undefined ? { categories: query.categories } : {}),\n ...(query.collections !== undefined\n ? { collections: query.collections }\n : {}),\n ...(query.priceMin !== undefined ? { priceMin: query.priceMin } : {}),\n ...(query.priceMax !== undefined ? { priceMax: query.priceMax } : {}),\n ...(query.inStock !== undefined ? { inStock: query.inStock } : {}),\n ...(query.attributes !== undefined\n ? { attributes: query.attributes }\n : {}),\n };\n const basicDemonstratedQuery = buildBasicDemonstratedQuery(query);\n const scopeField = scope !== undefined ? { scope } : {};\n\n const offered: CatalogFacetId[] = ['categories', 'collections'];\n const demonstrations: Record<string, CatalogFacetDemonstrationSource> = {\n categories: {\n endpoint: BASIC_LISTING_ENDPOINT,\n appliedQuery: basicDemonstratedQuery,\n ...scopeField,\n },\n collections: {\n endpoint: BASIC_LISTING_ENDPOINT,\n appliedQuery: basicDemonstratedQuery,\n ...scopeField,\n },\n };\n const held: CatalogFacetId[] = [];\n const heldReasons: Record<string, string> = {};\n\n const categoryIds =\n providedCategoryIds ?? (await this.resolveScopeCategoryIds(query));\n const collectionIds =\n providedCollectionIds ??\n (query.collections\n ? await this.resolveCollectionIds(query.collections)\n : []);\n const candidates: CatalogFacetId[] = ['price', 'inStock'];\n for (const handle of await this.resolveFilterableAttributeHandles(\n categoryIds,\n )) {\n const facet = `attr.${handle}` as CatalogFacetId;\n if (!candidates.includes(facet)) candidates.push(facet);\n }\n\n const probe = await this.probeAdvancedSearchSupport(\n query,\n categoryIds,\n collectionIds,\n );\n if (probe.available) {\n for (const facet of candidates) {\n if (probe.applied.has(facet)) {\n offered.push(facet);\n demonstrations[facet] = {\n endpoint: ADVANCED_SEARCH_ENDPOINT,\n appliedQuery: advancedDemonstratedQuery,\n ...scopeField,\n };\n } else {\n held.push(facet);\n heldReasons[facet] =\n `not echoed as applied by ${ADVANCED_SEARCH_ENDPOINT}`;\n }\n }\n } else {\n for (const facet of candidates) {\n held.push(facet);\n heldReasons[facet] = probe.reason;\n }\n }\n\n return {\n offered,\n held,\n demonstrations,\n ...(Object.keys(heldReasons).length > 0 ? { heldReasons } : {}),\n };\n }\n\n /**\n * Demonstrate the optional advanced endpoint with the applied query for the\n * current scope. A non-2xx response (including the HTTP 404/500 an absent\n * plugin returns), an unparseable body, or a response that does not echo the\n * applied filters all mean the facet is not demonstrated — never a silent\n * assumption of support. Uses a single SDK request (no retry): a support probe\n * must not amplify a broken optional endpoint into repeated requests.\n */\n private async probeAdvancedSearchSupport(\n query: CatalogQuery,\n categoryIds: string[],\n collectionIds: string[],\n ): Promise<{\n available: boolean;\n applied: Set<CatalogFacetId>;\n reason: string;\n status?: number;\n }> {\n const advancedQuery = this.buildAdvancedSearchQuery(\n query,\n categoryIds,\n collectionIds,\n );\n advancedQuery.limit = 1;\n try {\n // Custom route: use the SDK client so the publishable API key and headers\n // are applied automatically (building-storefronts `sdk-client-fetch`).\n const data: any = await this.sdk.client.fetch(ADVANCED_SEARCH_ENDPOINT, {\n query: advancedQuery,\n });\n const appliedRaw = data?.applied_filters ?? data?.appliedFilters;\n if (!appliedRaw || typeof appliedRaw !== 'object') {\n return {\n available: false,\n applied: new Set(),\n reason: `${ADVANCED_SEARCH_ENDPOINT} did not echo applied filters; support unverified`,\n };\n }\n return {\n available: true,\n applied: mapAppliedFiltersToFacets(\n appliedRaw as Record<string, unknown>,\n ),\n reason: `${ADVANCED_SEARCH_ENDPOINT} demonstrated with the applied query`,\n };\n } catch (error: any) {\n const status =\n typeof error?.status === 'number' ? error.status : undefined;\n // Surface the absence/log it; never swallow it silently.\n this.logger.warn('Optional advanced search endpoint not demonstrated', {\n endpoint: ADVANCED_SEARCH_ENDPOINT,\n status,\n message: error?.message,\n });\n return {\n available: false,\n applied: new Set(),\n reason:\n status !== undefined\n ? `${ADVANCED_SEARCH_ENDPOINT} returned ${status}; optional advanced endpoint not demonstrated`\n : `${ADVANCED_SEARCH_ENDPOINT} unavailable: ${extractErrorMessage(error)}`,\n ...(status !== undefined ? { status } : {}),\n };\n }\n }\n\n /**\n * Build the advanced-endpoint query parameters from the canonical query. The\n * SDK serializes the plain object, so no manual stringification is needed.\n */\n private buildAdvancedSearchQuery(\n query: CatalogQuery,\n categoryIds: string[],\n collectionIds: string[],\n ): Record<string, unknown> {\n const advancedQuery: Record<string, unknown> = {};\n if (query.text) advancedQuery.q = query.text;\n if (categoryIds.length > 0) advancedQuery.categories = categoryIds.join(',');\n if (collectionIds.length > 0) {\n advancedQuery.collections = collectionIds.join(',');\n }\n if (query.priceMin !== undefined) advancedQuery.price_min = query.priceMin;\n if (query.priceMax !== undefined) advancedQuery.price_max = query.priceMax;\n if (query.inStock === true) advancedQuery.isAvailable = true;\n if (query.attributes) {\n // The backend route declares `attributes: z.string()` and JSON-parses an\n // ARRAY of `{ id, values }`. The canonical query carries a\n // `Record<string, string[]>`, so map it before serializing.\n const attributes = Object.entries(query.attributes).map(([id, values]) => ({\n id,\n values,\n }));\n advancedQuery.attributes = JSON.stringify(attributes);\n }\n if (query.sort) {\n const mappedOrder = MEDUSA_SORT_KEY_MAP[query.sort] ?? null;\n if (mappedOrder !== null) advancedQuery.order = mappedOrder;\n }\n if (this.regionId) advancedQuery.region_id = this.regionId;\n if (this.currencyCode) {\n advancedQuery.currency_code = this.currencyCode.toLowerCase();\n }\n return advancedQuery;\n }\n\n /** Resolve the effective category scope of a query to backend IDs. */\n private async resolveScopeCategoryIds(query: CatalogQuery): Promise<string[]> {\n const handles = resolveEffectiveCategoryHandles(query);\n if (handles === undefined || handles.length === 0) return [];\n return this.resolveCategoryIds(handles);\n }\n\n /**\n * Advertised filterable attribute handles for the scope. The custom-attributes\n * endpoint is facet *metadata* (which attributes exist), not proof that a\n * filter can be applied; these handles are candidates only, and each still\n * requires the advanced endpoint to echo it as applied before it is offered.\n */\n private async resolveFilterableAttributeHandles(\n categoryIds: string[],\n ): Promise<string[]> {\n const handles: string[] = [];\n for (const categoryId of categoryIds) {\n try {\n // Custom route: use the SDK client so the publishable API key and\n // headers are applied automatically (building-storefronts\n // `sdk-client-fetch`).\n const data: any = await this.sdk.client.fetch(\n `/store/custom-attributes/category/${categoryId}`,\n );\n for (const item of data?.attributes ?? []) {\n const attr = item.attribute ?? item;\n if (\n attr?.is_filterable &&\n attr?.is_active &&\n typeof attr.handle === 'string' &&\n attr.handle.length > 0\n ) {\n handles.push(attr.handle);\n }\n }\n } catch {\n // The optional custom-attributes endpoint may be absent; its absence\n // simply means no advertised attribute facets for the scope.\n }\n }\n return handles;\n }\n\n /** Build a typed `unsupported-query` outcome naming the offending fields. */\n private unsupportedCatalogOutcome(fields: string[]): CatalogQueryOutcome {\n return {\n ok: false,\n error: {\n code: 'unsupported-query',\n fields,\n message: `Unsupported catalog query: ${fields.join(', ')}`,\n repair: { remove: fields },\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. A capability boolean is not proof,\n // but when it is false the optional endpoint is definitely not wired; a\n // basic-only caller still gets the faithful `getProducts` fallback while a\n // caller that requested an advanced filter is rejected instead of silently\n // receiving unfiltered products (E2 task 2.4).\n if (!this.capabilities.advancedSearch) {\n this.logger.warn('Advanced search capability disabled, using faithful fallback');\n return this.fallbackAdvancedSearch(options);\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, using faithful fallback', {\n error: error.message,\n stack: error.stack,\n });\n\n // Do not silently drop advanced filters: a caller that requested price,\n // stock, or attributes gets a typed failure; a basic-only caller keeps the\n // faithful `getProducts` fallback.\n return this.fallbackAdvancedSearch(options);\n }\n }\n\n /**\n * Faithful fallback for `searchProductsAdvanced`. A basic-only request is\n * served by `getProducts`; a request that depends on the optional advanced\n * endpoint is rejected as a typed `ProviderAPIError` naming the unappliable\n * fields, so a failed advanced search never returns an unfiltered result\n * labelled success (E2 task 2.4).\n */\n private async fallbackAdvancedSearch(\n options?: AdvancedSearchProductsOptions,\n ): Promise<{\n products: Product[];\n meta?: SearchResultMeta;\n }> {\n const requested = collectAdvancedSearchRequestFields(options);\n if (requested.length > 0) {\n throw new ProviderAPIError(\n `Advanced search unavailable for requested fields: ${requested.join(', ')}`,\n 'medusa',\n undefined,\n { fields: requested, repair: { remove: requested } },\n );\n }\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 * 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 (stock)\n //\n // A price range is emitted ONLY when the backend supplies real range\n // metadata for the current query. Medusa's Store `/store/products`\n // returns the matching products and a total count, not the filterable\n // values or their numeric ranges (Store API contract; facets require a\n // separate search plugin), so there is no price range to read here and\n // the control is omitted instead of defaulted to a fabricated\n // `0..10000` (E2 Decision 4; spec \"Facet counts and ranges are never\n // fabricated\").\n //\n // The stock toggle is offered ONLY when the real optional endpoint has\n // demonstrated `inStock` for the scope. A capability boolean is not proof\n // (E2 task 2.4): the backend advertises `advancedSearch: true` while the\n // optional `/store/search` endpoint is absent, so the toggle is held\n // rather than shown.\n if (options.useAdvancedSearch) {\n const support = await this.getCatalogFacetSupport({\n categoryIds: options.categoryId ? [options.categoryId] : [],\n scope: options.categoryId,\n });\n if (support.offered.includes('inStock')) {\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\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. A per-option count is\n // attached only when the caller asked for counts AND the backend\n // supplied a real finite number; no zero or fabricated count is\n // invented (E2 Decision 4; spec \"Facet counts and ranges are\n // never fabricated\").\n if ((filterType === 'single' || filterType === 'multi') && attr.values) {\n filter.options = attr.values.map((val: any) => {\n const count = options.includeFacetCounts\n ? readFiniteFacetNumber(val.count)\n : undefined;\n return {\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 !== undefined ? { count } : {}),\n };\n });\n }\n\n // A numeric range is emitted only when the backend supplies BOTH\n // real bounds. A missing bound is never replaced by a fabricated\n // `0`/`100` default; without a real range the control is omitted\n // rather than shown with invented values (E2 Decision 4).\n if (filterType === 'range') {\n const min = readFiniteFacetNumber(attr.metadata?.min);\n const max = readFiniteFacetNumber(attr.metadata?.max);\n if (min === undefined || max === undefined) {\n return; // no real range → omit this range filter\n }\n filter.min = min;\n filter.max = max;\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 // --- Sales channel scoping ---\n // Applied unconditionally: the Thor Commerce plugin endpoint resolves the\n // sales channel from the publishable key itself. An explicit channel id\n // (options.salesChannelId ?? env) is only needed for the legacy N+1\n // fallback on backends without the plugin.\n const salesChannelId =\n options?.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n const activeCollectionIds = await this._getChannelCollections(salesChannelId);\n if (activeCollectionIds) {\n result = result.filter((c: Collection) => activeCollectionIds.has(c.id));\n }\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 /**\n * Returns the set of product-collection IDs that have at least one product\n * available in the given sales channel (legacy fallback).\n *\n * @deprecated Use `_getChannelCollections()` instead (backed by Thor Commerce plugin).\n */\n private async _getActiveCollectionIds(salesChannelId: string): Promise<Set<string>> {\n this.logger.debug('_getActiveCollectionIds', { salesChannelId });\n const collectionIds = 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 fields: '+collections.id',\n limit,\n offset,\n } as any)) as any;\n\n for (const product of products ?? []) {\n for (const col of product.collections ?? []) {\n if (col?.id) collectionIds.add(col.id);\n }\n }\n\n if (!products || products.length < limit) break;\n offset += limit;\n }\n\n this.logger.debug('_getActiveCollectionIds result', { count: collectionIds.size });\n return collectionIds;\n }\n\n /**\n * Fetch channel-scoped collections from Thor Commerce plugin.\n * Uses `GET /store/thor/collections` — the endpoint resolves the sales\n * channel from the publishable key header itself.\n *\n * Falls back to `_getActiveCollectionIds()` (legacy N+1) when the plugin is\n * not available; the legacy fallback needs an explicit `salesChannelId`.\n * Returns `null` when no scoping could be performed.\n */\n private async _getChannelCollections(salesChannelId?: string): Promise<Set<string> | null> {\n try {\n const url = `${this.baseUrl}/store/thor/collections`;\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 || !response.ok) {\n this.logger.debug('Thor plugin collections endpoint unavailable, falling back to legacy method');\n return this._legacyChannelCollections(salesChannelId);\n }\n\n const data = await response.json();\n const collectionIds = new Set<string>();\n for (const col of data.collections ?? []) {\n if (col?.id) collectionIds.add(col.id);\n }\n\n this.logger.debug('_getChannelCollections result (Thor plugin)', { count: collectionIds.size });\n return collectionIds;\n } catch (error) {\n this.logger.warn('Failed to fetch channel collections from Thor plugin, falling back to legacy method', {\n error: error instanceof Error ? error.message : String(error),\n });\n return this._legacyChannelCollections(salesChannelId);\n }\n }\n\n /**\n * Legacy fallback for `_getChannelCollections()` when the Thor plugin is not\n * installed. Requires an explicit `salesChannelId`; returns `null` otherwise.\n */\n private async _legacyChannelCollections(salesChannelId?: string): Promise<Set<string> | null> {\n if (!salesChannelId) {\n this.logger.warn(\n 'Cannot scope collections: Thor plugin unavailable and no sales channel id provided; returning unscoped collections',\n );\n return null;\n }\n return this._getActiveCollectionIds(salesChannelId);\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. The endpoint\n * resolves the sales channel from the publishable key header itself, so no\n * explicit channel id is required when the plugin is installed.\n *\n * Falls back to `_getActiveCategoryIds()` (legacy N+1) when the plugin is\n * not available. The legacy fallback needs an explicit `salesChannelId`;\n * when none is provided and the plugin is unavailable, returns `null` to\n * signal that scoping is not possible and the caller should skip filtering.\n *\n * @param salesChannelId - Only used by the legacy fallback (plugin absent).\n * @returns Set of category IDs active in the channel, or `null` when no\n * scoping could be performed.\n */\n private async _getChannelCategories(salesChannelId?: string): Promise<Set<string> | null> {\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 || !response.ok) {\n // Plugin not installed — fall back to legacy N+1 method\n this.logger.debug('Thor plugin categories endpoint unavailable, falling back to legacy method');\n return this._legacyChannelCategories(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._legacyChannelCategories(salesChannelId);\n }\n }\n\n /**\n * Legacy fallback for `_getChannelCategories()` when the Thor plugin is not\n * installed. Requires an explicit `salesChannelId`; returns `null` otherwise.\n */\n private async _legacyChannelCategories(salesChannelId?: string): Promise<Set<string> | null> {\n if (!salesChannelId) {\n this.logger.warn(\n 'Cannot scope categories: Thor plugin unavailable and no sales channel id provided; returning unscoped categories',\n );\n return null;\n }\n return this._getActiveCategoryIds(salesChannelId);\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 // Bounded per-request limit (change B, decision 5): no unbounded scan.\n // Client-side search filtering still runs over the bounded page.\n const limit = options.limit ?? this.catalogPageSize;\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 // Applied unconditionally: the Thor Commerce plugin endpoint resolves the\n // sales channel from the publishable key itself. An explicit channel id\n // (options.salesChannelId ?? env) is only needed for the legacy N+1\n // fallback on backends without the plugin.\n const salesChannelId =\n options.salesChannelId ?? process.env.NEXT_PUBLIC_SALES_CHANNEL_ID;\n const activeCategoryIds = await this._getChannelCategories(salesChannelId);\n if (activeCategoryIds) {\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 // Bounded, paginated listing (change B, decision 5).\n limit: options.first ?? this.catalogPageSize,\n offset: options.after ? parseInt(options.after, 10) : undefined,\n fields:\n '+variants,+variants.prices,+variants.calculated_price,+variants.inventory_quantity,+options,+images,+tags',\n };\n\n // Translate the Thor sort key through the same mapping `getProducts` uses.\n // A raw canonical key (`name`/`newest`/`featured`) is not a valid Medusa\n // `order` field and would be rejected by the Store API; `null` omits\n // `order` so the backend returns its default ordering.\n const mappedOrder = options.sortKey\n ? MEDUSA_SORT_KEY_MAP[options.sortKey] ?? null\n : null;\n if (mappedOrder !== null) {\n categoryQueryParams.order = mappedOrder;\n }\n\n // Region-based pricing (calculated_price requires region_id in Medusa v2)\n if (this.regionId) {\n categoryQueryParams.region_id = this.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 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; salesChannelId?: string }): Promise<Cart> {\n this.logger.debug('createCart', {\n regionId: options?.regionId,\n salesChannelId: options?.salesChannelId,\n });\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 // Explicit sales channel scope. Normally Medusa auto-injects the channel\n // from the publishable key when it maps to exactly one channel, but\n // passing it explicitly is required when the key maps to multiple\n // channels (otherwise cart creation errors).\n const salesChannelId =\n options?.salesChannelId ?? resolveConfiguredSalesChannelId();\n if (salesChannelId) {\n createPayload.sales_channel_id = salesChannelId;\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 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 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 = resolveConfiguredSalesChannelId();\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 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 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 const result = await this.completeCart(cartId);\n\n if (result.type === 'order') {\n return result.order;\n }\n\n if (result.type === 'cart') {\n throw new ProviderAPIError(\n `Failed to complete checkout: ${result.error.message}`,\n 'medusa',\n result.error.status,\n );\n }\n\n throw new ProviderAPIError(\n `Checkout outcome is unresolved: ${result.error.message}`,\n 'medusa',\n result.error.status,\n );\n }\n\n /**\n * Complete a cart exactly once and preserve the native discriminator\n * (change B, decision 11).\n *\n * Medusa's `POST /store/carts/:id/complete` returns HTTP 200 whose body is\n * either `{ type: 'order', order }` or `{ type: 'cart', cart, error }`. This\n * method never retries: a thrown transport/timeout/5xx failure becomes an\n * `unresolved` result so the caller reconciles the committed cart before any\n * further attempt. The Medusa JS SDK performs no implicit retry of its own,\n * so there is no blind retry beneath this call either.\n */\n async completeCart(cartId: string): Promise<CartCompletionResult> {\n this.logger.debug('completeCart', { cartId });\n\n try {\n const response = (await this.sdk.store.cart.complete(cartId, {\n fields: MEDUSA_ORDER_COMPLETION_FIELDS,\n } as any)) as any;\n\n if (response?.type === 'cart' || (response?.cart && response?.error)) {\n const error = this.toCompletionError(response.error);\n this.logger.warn('Cart completion returned a cart with an error', {\n cartId,\n code: error.code,\n message: error.message,\n });\n return { type: 'cart', cart: transformCart(response.cart), error };\n }\n\n const order = response?.order;\n if (!order) {\n return {\n type: 'unresolved',\n error: { message: 'Checkout returned neither an order nor a cart error' },\n };\n }\n\n this.logger.info('Checkout completed successfully', {\n orderId: order.id,\n displayId: order.display_id,\n });\n return { type: 'order', order: transformOrder(order) };\n } catch (error: unknown) {\n const completionError = this.toCompletionError(error);\n this.logger.error('Cart completion failed (unresolved, not retried)', {\n cartId,\n status: completionError.status,\n message: completionError.message,\n });\n return { type: 'unresolved', error: completionError };\n }\n }\n\n /** Normalize any thrown/returned completion failure into a structured error. */\n private toCompletionError(error: unknown): CartCompletionError {\n if (error && typeof error === 'object') {\n const err = error as any;\n const message =\n typeof err.message === 'string' && err.message.length > 0\n ? err.message\n : extractErrorMessage(error);\n return {\n message,\n code: typeof err.code === 'string' ? err.code : undefined,\n status: err.status ?? err.statusCode,\n raw: err,\n };\n }\n return { message: extractErrorMessage(error), raw: error };\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.debug('getShippingMethods', { cartId });\n\n try {\n return await this.withRetry(\n async () => {\n // The cart supplies the region and currency the options are priced in.\n const cartResponse = (await this.sdk.store.cart.retrieve(cartId)) as any;\n const { cart } = cartResponse;\n\n if (!cart) {\n throw new ResourceNotFoundError('Cart', cartId);\n }\n\n if (!cart.region_id) {\n throw new ProviderAPIError('Cart has no region assigned', 'medusa', 400);\n }\n\n // Medusa v2: list the shipping options eligible for this cart. The\n // JS SDK exposes `store.fulfillment.listCartOptions`; fall back to the\n // equivalent HTTP route for SDK builds that do not.\n let shippingOptions: any[] = [];\n const storeAny = this.sdk.store as any;\n\n if (storeAny?.fulfillment?.listCartOptions) {\n const response = (await storeAny.fulfillment.listCartOptions({\n cart_id: cartId,\n })) as any;\n shippingOptions = response?.shipping_options ?? [];\n } else {\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 shippingOptions = ((await response.json()) as any)?.shipping_options ?? [];\n }\n\n const currencyCode = cart.currency_code?.toUpperCase() ?? '';\n\n // Truthful projection (change B, decision 17): the amount is the\n // backend's option amount (or its tax-inclusive amount) and is never\n // replaced with a fabricated `'0'`; an absent description/ETA is\n // omitted rather than filled with a placeholder like `'N/A'`.\n return shippingOptions.map((option: any) => {\n const amount = option?.amount ?? option?.price_incl_tax;\n const estimatedDays =\n option?.data?.estimated_days != null\n ? String(option.data.estimated_days)\n : undefined;\n\n return {\n id: option.id,\n name: option.name,\n price: {\n amount:\n typeof amount === 'number' && Number.isFinite(amount)\n ? amount.toFixed(2)\n : '',\n currencyCode,\n },\n description: option?.data?.description,\n estimatedDays,\n fulfillmentSetType: option?.service_zone?.fulfillment_set?.type ?? null,\n };\n });\n },\n 'getShippingMethods',\n { cartId },\n );\n } catch (error: any) {\n this.logger.error('Failed to fetch shipping methods', {\n cartId,\n errorMessage: error.message,\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 // Medusa v2: POST /store/carts/:id/shipping-methods.\n // This is a non-idempotent mutation, so it is sent exactly once and is\n // NOT wrapped in a retry (change B, decision 11).\n 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 // Re-read the authoritative cart so the recalculated totals come from\n // the backend rather than the mutation response.\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\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.debug('initiatePaymentSession', { cartId, providerId });\n\n try {\n // Read the raw cart: the canonical transform does not carry the payment\n // collection, and the session compatibility check needs the backend's own\n // session shape (provider, amount, status).\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 if (!rawCart.items || rawCart.items.length === 0) {\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 if (!rawCart.shipping_address) {\n throw new ProviderAPIError(\n 'Shipping address is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n // Payment is applied only after shipping totals are final (decision 10).\n if (!rawCart.shipping_methods?.length) {\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 throw new ProviderAPIError(\n 'Email is required before initiating payment session',\n 'medusa',\n 400,\n );\n }\n\n validatePaymentId(providerId);\n\n // Reuse an existing session ONLY when its provider, state and amount are\n // compatible with the current cart; otherwise create/replace it.\n const existingSessions: any[] = rawCart.payment_collection?.payment_sessions ?? [];\n const compatible = existingSessions.find((session: any) => {\n const statusOk = ['pending', 'requires_more', 'authorized'].includes(session?.status);\n return (\n session?.provider_id === providerId &&\n session?.amount === rawCart.total &&\n statusOk\n );\n });\n\n if (compatible) {\n this.logger.info('Reusing compatible payment session', {\n cartId,\n providerId,\n sessionId: compatible.id,\n amount: compatible.amount,\n });\n return;\n }\n\n if (existingSessions.length > 0) {\n this.logger.info('Existing payment session incompatible; replacing it', {\n cartId,\n providerId,\n existing: existingSessions.map((session: any) => ({\n id: session.id,\n providerId: session.provider_id,\n amount: session.amount,\n status: session.status,\n })),\n });\n }\n\n // Non-idempotent mutation: sent exactly once, never retried.\n await this.sdk.store.payment.initiatePaymentSession(rawCart as any, {\n provider_id: providerId,\n });\n\n this.logger.info('Payment session initiated', { cartId, providerId });\n } catch (error: any) {\n this.logger.error('Failed to initiate payment session', {\n cartId,\n providerId,\n errorMessage: error.message,\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 // Medusa v2: POST /store/carts/:id/promotions.\n // Non-idempotent mutation: sent exactly once, never retried.\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 this.logger.info('Discount code applied successfully', { cartId, code });\n\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\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 // Medusa v2: DELETE /store/carts/:id/promotions.\n // Non-idempotent mutation: sent exactly once, never retried.\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 this.logger.info('Discount code removed successfully', { cartId, code });\n\n const updatedCart = await this.retrieveCartWithLineDetails(cartId);\n return transformCart(updatedCart);\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';\nimport type {\n CatalogAppliedFilters,\n CatalogFacetId,\n CatalogQuery,\n CatalogQueryOutcome,\n CatalogSortKey,\n FacetSupport,\n} from '@thorprovider/types';\n\nconst FIXTURE_TIMESTAMP = '2026-01-01T00:00:00.000Z';\nconst DEFAULT_SITE_URL = 'https://mock.thorcommerce.local';\n\n/**\n * Stable sales channel the fixture cart is scoped to. Exported so a host can\n * build a matching `StoreContext` for the mock data source; the runtime\n * context check compares against it like a real backend channel.\n */\nexport const MOCK_SALES_CHANNEL_ID = 'mock-sales-channel';\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 * Fixture-supplied creation timestamp (ISO-8601).\n *\n * Declared explicitly per product rather than derived from the id, so the\n * canonical `newest` ordering is truthful and deterministic. Products keep\n * distinct values so global ordering before pagination is observable.\n */\n createdAt: string;\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 createdAt: '2026-01-05T00:00:00.000Z',\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 createdAt: '2026-01-03T00:00:00.000Z',\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 createdAt: '2026-01-04T00:00:00.000Z',\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 createdAt: '2026-01-02T00:00:00.000Z',\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: product.createdAt,\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\n/**\n * Canonical sort keys the mock catalog can truthfully apply (E2 task 2.5).\n *\n * Mirrors the Medusa advertisement: `featured` (stable fixture order, the\n * canonical default), `name` (title ascending), and `newest` (fixture-supplied\n * `createdAt` descending). No global price or rating ordering is advertised.\n */\nexport const MOCK_CATALOG_SORT_KEYS: readonly CatalogSortKey[] = [\n 'featured',\n 'name',\n 'newest',\n];\n\n/**\n * The mock catalog's demonstration endpoint identity.\n *\n * Explicitly mock-scoped so a support descriptor can never be mistaken for a\n * live Medusa endpoint. The mock is the basic fixture listing; advanced facets\n * are held.\n */\nconst MOCK_CATALOG_ENDPOINT = 'mock://catalog/products';\n\n/** Canonical default page size, matching the Medusa configured bound. */\nconst MOCK_CATALOG_PAGE_SIZE = 50;\n\n/**\n * Effective category scope for a canonical query.\n *\n * Mirrors the Medusa contract: the route `categoryScope` is always retained and\n * the `categories` filter narrows within it. Returns `undefined` when no\n * category filter is requested, `[]` for an explicit empty intersection (a valid\n * zero-result query), or the handles to resolve against the fixtures.\n */\nfunction resolveEffectiveCategoryHandles(\n query: CatalogQuery\n): string[] | undefined {\n const { categoryScope, categories } = query;\n if (categoryScope === undefined) return categories;\n if (categories === undefined) return [categoryScope];\n return categories.filter((handle) => handle === categoryScope);\n}\n\n/** Canonical query fields that require advanced filtering the mock does not implement. */\nfunction collectRequestedAdvancedFields(query: CatalogQuery): string[] {\n const fields: string[] = [];\n if (query.priceMin !== undefined) fields.push('priceMin');\n if (query.priceMax !== undefined) fields.push('priceMax');\n if (query.inStock !== undefined) fields.push('inStock');\n for (const name of Object.keys(query.attributes ?? {})) {\n fields.push(`attr.${name}`);\n }\n return fields;\n}\n\n/** Map a requested advanced field name to the canonical facet id it needs. */\nfunction advancedFieldToFacet(field: string): CatalogFacetId {\n if (field === 'priceMin' || field === 'priceMax') return 'price';\n return field as CatalogFacetId;\n}\n\n/**\n * Filters a successful (or explicitly-empty) canonical result reports as\n * applied. The mock implements only the basic filters (text/categories/\n * collections); requested advanced filters never reach a success path.\n */\nfunction buildAppliedCatalogFilters(\n query: CatalogQuery,\n effectiveCategoryHandles: string[] | undefined\n): CatalogAppliedFilters {\n return {\n ...(query.text ? { text: query.text } : {}),\n ...(effectiveCategoryHandles !== undefined\n ? { categories: effectiveCategoryHandles }\n : {}),\n ...(query.collections !== undefined\n ? { collections: query.collections }\n : {}),\n };\n}\n\n/** Basic fields the mock listing actually accepts, recorded on the demonstration. */\nfunction buildBasicDemonstratedQuery(query: CatalogQuery): CatalogQuery {\n return {\n ...(query.text !== undefined ? { text: query.text } : {}),\n ...(query.categoryScope !== undefined\n ? { categoryScope: query.categoryScope }\n : {}),\n ...(query.categories !== undefined ? { categories: query.categories } : {}),\n ...(query.collections !== undefined\n ? { collections: query.collections }\n : {}),\n };\n}\n\n/**\n * Truthful facet-support descriptor for the mock.\n *\n * `categories`/`collections` are offered with the mock listing as their\n * demonstration source; `price`/`inStock` are held with a real reason because\n * the mock does not implement advanced filtering. No count or range is\n * synthesized and the endpoint is explicitly mock-scoped.\n */\nfunction buildMockFacetSupport(query: CatalogQuery): FacetSupport {\n const appliedQuery = buildBasicDemonstratedQuery(query);\n const scopeField =\n query.categoryScope !== undefined ? { scope: query.categoryScope } : {};\n\n return {\n offered: ['categories', 'collections'],\n held: ['price', 'inStock'],\n demonstrations: {\n categories: {\n endpoint: MOCK_CATALOG_ENDPOINT,\n appliedQuery,\n ...scopeField,\n },\n collections: {\n endpoint: MOCK_CATALOG_ENDPOINT,\n appliedQuery,\n ...scopeField,\n },\n },\n heldReasons: {\n price: `${MOCK_CATALOG_ENDPOINT} is the mock basic listing; price filtering is not implemented in mock mode`,\n inStock: `${MOCK_CATALOG_ENDPOINT} is the mock basic listing; stock filtering is not implemented in mock mode`,\n },\n };\n}\n\n/** Build a typed `unsupported-query` outcome naming the offending fields. */\nfunction unsupportedMockCatalogOutcome(fields: string[]): CatalogQueryOutcome {\n return {\n ok: false,\n error: {\n code: 'unsupported-query',\n fields,\n message: `Unsupported catalog query in mock mode: ${fields.join(', ')}`,\n repair: { remove: fields },\n },\n };\n}\n\n/**\n * Apply the canonical ordering globally, before pagination.\n *\n * `featured` preserves the stable fixture order; `name` sorts by title\n * ascending; `newest` sorts by the fixture-supplied `createdAt` descending.\n */\nfunction sortMockCatalogProducts(\n products: Product[],\n sortKey?: CatalogSortKey\n): Product[] {\n const sorted = [...products];\n if (sortKey === 'name') {\n sorted.sort((left, right) => left.title.localeCompare(right.title));\n } else if (sortKey === 'newest') {\n sorted.sort((left, right) => right.createdAt.localeCompare(left.createdAt));\n }\n return sorted;\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 discountAmount: createMoney(discount, regionCurrency),\n totalTaxAmount: createMoney(totalTax, regionCurrency),\n shippingAmount: createMoney(shipping, regionCurrency),\n totalAmount: createMoney(total, regionCurrency),\n },\n lines,\n totalQuantity: lines.reduce((sum, line) => sum + line.quantity, 0),\n salesChannelId: MOCK_SALES_CHANNEL_ID,\n regionId: state.regionId,\n currencyCode: regionCurrency.toUpperCase(),\n selectedShippingMethodId: state.shippingMethodId,\n // The mock method id IS the shipping option id (the value returned by\n // `getMockShippingMethods` and accepted by `addShippingMethod`), so the\n // canonical option identity mirrors the real adapter's `so_` field and the\n // checkout UI can highlight the selected option.\n selectedShippingOptionId: state.shippingMethodId,\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\n/**\n * Canonical catalog query for the mock provider — E2 `storefront-catalog-search-filters`\n * task 2.5.\n *\n * A faithful stand-in for the Medusa canonical contract so mock mode exercises\n * the same behavior:\n *\n * - The route `categoryScope` is always retained and intersected with the\n * `categories` filter; an explicit empty intersection (or a requested\n * category/collection handle that matches no fixture) is a valid zero-result\n * query, never an unfiltered request.\n * - Requested category/collection handles resolve against the fixtures by id or\n * handle; text matching is case-insensitive over title, description, and tags.\n * - Ordering is global, before pagination: `featured` preserves the stable\n * fixture order, `name` sorts by title ascending, and `newest` sorts by the\n * fixture-supplied `createdAt` descending. Only the advertised\n * `MOCK_CATALOG_SORT_KEYS` are accepted; any other sort is a typed\n * `unsupported-query`.\n * - `total` is the full matching fixture count (never the page length) and is\n * present whenever a listing is returned.\n * - Advanced filters (price/stock/attributes) are held and rejected as a typed\n * `unsupported-query` **before** any zero-result short-circuit, so a requested\n * filter is never silently dropped and a partial result is never labelled\n * success. The attached `facetSupport` marks its demonstration endpoint as\n * mock-scoped and never claims Medusa support.\n */\nexport function getMockCatalogProducts(\n query: CatalogQuery,\n options: { currencyCode?: string; regionId?: string } = {}\n): CatalogQueryOutcome {\n if (\n query.sort !== undefined &&\n !MOCK_CATALOG_SORT_KEYS.includes(query.sort)\n ) {\n return unsupportedMockCatalogOutcome(['sort']);\n }\n\n const region = getRegionFixture(options.regionId);\n const currencyCode = options.currencyCode ?? region.currencyCode;\n const allProducts = buildProducts(currencyCode);\n const facetSupport = buildMockFacetSupport(query);\n\n // Reject every requested advanced field before the zero-result short-circuit,\n // so an unsupported filter is never hidden behind an empty intersection.\n const requestedAdvanced = collectRequestedAdvancedFields(query);\n const heldAdvanced = requestedAdvanced.filter(\n (field) => !facetSupport.offered.includes(advancedFieldToFacet(field))\n );\n if (heldAdvanced.length > 0) {\n return unsupportedMockCatalogOutcome(heldAdvanced);\n }\n\n const effectiveCategoryHandles = resolveEffectiveCategoryHandles(query);\n const emptyIntersection =\n effectiveCategoryHandles !== undefined &&\n effectiveCategoryHandles.length === 0;\n const categoryFilterEmpty =\n effectiveCategoryHandles !== undefined &&\n !effectiveCategoryHandles.some((handle) =>\n categoryFixtures.some(\n (category) => category.handle === handle || category.id === handle\n )\n );\n const collectionFilterEmpty =\n query.collections !== undefined &&\n !query.collections.some((handle) =>\n collectionFixtures.some(\n (collection) =>\n collection.handle === handle || collection.id === handle\n )\n );\n\n if (emptyIntersection || categoryFilterEmpty || collectionFilterEmpty) {\n return {\n ok: true,\n results: {\n products: [],\n appliedFilters: buildAppliedCatalogFilters(\n query,\n effectiveCategoryHandles\n ),\n facetSupport,\n },\n };\n }\n\n const filtered = filterProducts(allProducts, {\n query: query.text,\n categoryIds: effectiveCategoryHandles,\n collectionIds: query.collections,\n });\n const sorted = sortMockCatalogProducts(filtered, query.sort);\n\n const pageSize = query.pageSize ?? MOCK_CATALOG_PAGE_SIZE;\n const page = query.page ?? 1;\n const offset = (page - 1) * pageSize;\n\n return {\n ok: true,\n results: {\n products: sorted.slice(offset, offset + pageSize),\n // The full matching fixture count, never the page length.\n total: filtered.length,\n appliedFilters: buildAppliedCatalogFilters(\n query,\n effectiveCategoryHandles\n ),\n facetSupport,\n },\n };\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 // The single approved manual TEST provider used by the real Medusa\n // backend, mirrored in mock mode so the guest TEST purchase path is\n // exercisable without a backend.\n id: 'pp_system_default',\n name: 'Manual TEST payment',\n type: 'cash_on_delivery',\n isEnabled: true,\n requiresSetup: false,\n description: 'Manual system TEST provider (bookkeeping only; not external funds).',\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 CatalogQuery,\n CatalogQueryOutcome,\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 type { CartCompletionCapable, CartCompletionResult } from '../../types/completion';\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 getMockCatalogProducts,\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 MOCK_CATALOG_SORT_KEYS,\n saveMockCartState,\n saveMockOrder,\n validateMockCartStock,\n} from './mock';\n\nexport interface MockProviderConfig extends ProviderConfig {\n currencyCode?: string;\n siteUrl?: string;\n}\n\nexport { MOCK_SALES_CHANNEL_ID } from './mock';\n\nexport class MockProvider implements CommerceProvider, CartCompletionCapable {\n readonly name = 'mock';\n readonly version = '1.0.0';\n readonly capabilities = MOCK_CAPABILITIES;\n readonly isMock = true;\n readonly supportedCatalogSortKeys = MOCK_CATALOG_SORT_KEYS;\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 /**\n * Canonical catalog query path (E2 task 2.5).\n *\n * Delegates to the fixture-backed canonical implementation so mock mode is a\n * faithful stand-in for the same contract the Medusa adapter honors: scope ∩\n * categories, collection resolution, global ordering before pagination, the\n * real full match count, and a typed `unsupported-query` for advanced filters\n * the mock does not implement.\n */\n async getCatalogProducts(query: CatalogQuery): Promise<CatalogQueryOutcome> {\n return getMockCatalogProducts(query, { currencyCode: this.currencyCode });\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 /**\n * Discriminated completion for the fixture provider.\n *\n * Completion is idempotent by construction (the fixture order id derives from\n * the cart id), so completing an already-completed cart returns the same\n * persisted order — mirroring the native reconcile path without a second\n * order.\n */\n async completeCart(cartId: string): Promise<CartCompletionResult> {\n const cart = getMockCartState(cartId);\n if (!cart) {\n return {\n type: 'unresolved',\n error: { message: `Cart not found: ${cartId}`, code: 'CART_NOT_FOUND', status: 404 },\n };\n }\n\n const order = completeMockCheckout(cart, this.currencyCode, this.siteUrl);\n return { type: 'order', 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 — Provider registry (runtime)\n *\n * Runtime owner of the provider registry: the `SupportedProviderType` enum,\n * its metadata, and the guards. The provider-type union contract\n * (`ProviderTypeString`) stays type-only in `@thorprovider/types`.\n *\n * When adding a new provider:\n * 1. Add the string to `ProviderTypeString` in packages/types/src/provider.ts.\n * 2. Add the enum member + metadata entry here.\n * 3. Create packages/adapters/src/providers/[platform]/.\n */\nimport type { ProviderTypeString } from '@thorprovider/types';\n\n/**\n * All supported commerce platform providers.\n * `mock` is the backend-optional runtime provider used for layout/design mode.\n * `medusa` is fully implemented for real backend usage; others are placeholders for future expansion.\n *\n * @remarks Implementation status:\n * - ✅ mock: Fixture-backed provider for backend-optional storefronts\n * - ✅ medusa: Fully implemented\n * - 🟡 stelorder: In progress (ERP adapter v1)\n * - 🟡 shopify: Planned (Phase 2)\n * - 🟡 bigcommerce: Planned (Phase 2)\n * - 🟡 woocommerce: Planned (Phase 3)\n * - 🟡 spree: Planned (Phase 3)\n * - 🟡 magento: Planned (Phase 3)\n */\nexport enum SupportedProviderType {\n Mock = 'mock',\n Medusa = 'medusa',\n StelOrder = 'stelorder',\n Shopify = 'shopify',\n BigCommerce = 'bigcommerce',\n WooCommerce = 'woocommerce',\n Spree = 'spree',\n Magento = 'magento',\n}\n\n/**\n * Metadata about each provider.\n * Useful for UI, error messages, validation, and documentation.\n */\nexport const PROVIDER_METADATA: Record<\n ProviderTypeString,\n {\n name: string;\n description: string;\n requiresStorefront: boolean;\n requiredEnvVars: string[];\n maxRetries: number;\n }\n> = {\n mock: {\n name: 'Mock',\n description: 'Fixture-backed runtime provider for layout/design mode without a real backend',\n requiresStorefront: false,\n requiredEnvVars: [],\n maxRetries: 0,\n },\n medusa: {\n name: 'Medusa JS',\n description: 'Medusa v2 commerce engine',\n requiresStorefront: true,\n requiredEnvVars: [\n 'NEXT_PUBLIC_COMMERCE_API_URL',\n 'NEXT_PUBLIC_COMMERCE_API_KEY',\n 'NEXT_PUBLIC_SALES_CHANNEL_ID',\n ],\n maxRetries: 3,\n },\n stelorder: {\n name: 'Stel Order',\n description: 'Stel Order ERP and sales document API',\n requiresStorefront: false,\n requiredEnvVars: [\n 'NEXT_PUBLIC_COMMERCE_API_URL',\n 'NEXT_PUBLIC_COMMERCE_API_KEY',\n ],\n maxRetries: 2,\n },\n shopify: {\n name: 'Shopify',\n description: 'Shopify Storefront API (GraphQL)',\n requiresStorefront: false,\n requiredEnvVars: [\n 'NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN',\n 'NEXT_PUBLIC_SHOPIFY_STOREFRONT_TOKEN',\n ],\n maxRetries: 3,\n },\n bigcommerce: {\n name: 'BigCommerce',\n description: 'BigCommerce REST Storefront API',\n requiresStorefront: false,\n requiredEnvVars: [\n 'BIGCOMMERCE_STORE_HASH',\n 'BIGCOMMERCE_STOREFRONT_API_TOKEN',\n 'BIGCOMMERCE_CHANNEL_ID',\n ],\n maxRetries: 3,\n },\n woocommerce: {\n name: 'WooCommerce',\n description: 'WooCommerce Store API + REST API v3',\n requiresStorefront: false,\n requiredEnvVars: [\n 'WOOCOMMERCE_URL',\n 'WOOCOMMERCE_CONSUMER_KEY',\n 'WOOCOMMERCE_CONSUMER_SECRET',\n ],\n maxRetries: 3,\n },\n spree: {\n name: 'Spree Commerce',\n description: 'Spree API v2 Storefront (JSON:API)',\n requiresStorefront: false,\n requiredEnvVars: [\n 'SPREE_API_URL',\n ],\n maxRetries: 3,\n },\n magento: {\n name: 'Adobe Commerce (Magento)',\n description: 'Adobe Commerce GraphQL + REST API',\n requiresStorefront: true,\n requiredEnvVars: [\n 'MAGENTO_URL',\n 'MAGENTO_STORE_CODE',\n ],\n maxRetries: 3,\n },\n};\n\n/**\n * Check if a string is a valid provider type.\n *\n * @example\n * ```typescript\n * if (isSupportedProviderType(process.env.COMMERCE_PROVIDER)) {\n * // type is narrowed to ProviderTypeString\n * }\n * ```\n */\nexport function isSupportedProviderType(\n value: unknown\n): value is ProviderTypeString {\n return (\n typeof value === 'string' &&\n (Object.values(SupportedProviderType) as string[]).includes(value)\n );\n}\n\n/**\n * Get metadata for a provider type.\n * Useful for validation, error messages, and logging.\n *\n * @example\n * ```typescript\n * const meta = getProviderMetadata('medusa');\n * console.log(`Using ${meta.name} with max ${meta.maxRetries} retries`);\n * ```\n */\nexport function getProviderMetadata(\n type: ProviderTypeString\n): (typeof PROVIDER_METADATA)[ProviderTypeString] {\n if (!isSupportedProviderType(type)) {\n throw new Error(\n `Unsupported provider: ${type}. Supported: ${Object.values(\n SupportedProviderType\n ).join(', ')}`\n );\n }\n return PROVIDER_METADATA[type];\n}\n","/**\n * @thorprovider/adapters v2.0\n * Provider Factory - Create commerce providers dynamically\n *\n * This factory owns the runtime provider registry (SupportedProviderType +\n * metadata + guards) and is bound to the type-only ProviderTypeString union\n * from @thorprovider/types (L1).\n * When adding a new provider:\n * 1. Update ProviderTypeString in packages/types/src/provider.ts\n * 2. Add the enum member + metadata in ./provider-types.ts\n * 3. Add new discriminated union case here\n * 4. Create packages/adapters/src/providers/[platform]/\n * 5. 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\nexport {\n SupportedProviderType,\n PROVIDER_METADATA,\n isSupportedProviderType,\n getProviderMetadata,\n} from './provider-types';\n\n/**\n * Supported provider types (type-only union owned by @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":["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","resolveEffectiveCategoryHandles","collectRequestedAdvancedFields","advancedFieldToFacet","buildAppliedCatalogFilters","buildBasicDemonstratedQuery","SupportedProviderType"]}
|