@commercengine/pos 0.4.6 → 0.6.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../sdk-core/dist/index.mjs","../src/lib/utils/jwt.ts","../src/lib/utils/auth.ts","../src/lib/middleware/auth.ts","../src/lib/utils/url.ts","../src/lib/client.ts","../src/lib/pos.ts","../src/index.ts"],"sourcesContent":["import createClient from \"openapi-fetch\";\n\n//#region src/middleware/debug.ts\n/**\n* Response utilities for debugging and working with Response objects\n*/\nvar ResponseUtils = class {\n\t/**\n\t* Get response headers as a plain object\n\t*/\n\tstatic getHeaders(response) {\n\t\treturn Object.fromEntries(response.headers.entries());\n\t}\n\t/**\n\t* Get specific header value\n\t*/\n\tstatic getHeader(response, name) {\n\t\treturn response.headers.get(name);\n\t}\n\t/**\n\t* Check if response was successful\n\t*/\n\tstatic isSuccess(response) {\n\t\treturn response.ok;\n\t}\n\t/**\n\t* Get response metadata\n\t*/\n\tstatic getMetadata(response) {\n\t\treturn {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\tok: response.ok,\n\t\t\turl: response.url,\n\t\t\tredirected: response.redirected,\n\t\t\ttype: response.type,\n\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t};\n\t}\n\t/**\n\t* Clone and read response as text (useful for debugging)\n\t* Note: This can only be called once per response\n\t*/\n\tstatic async getText(response) {\n\t\treturn await response.clone().text();\n\t}\n\t/**\n\t* Clone and read response as JSON (useful for debugging)\n\t* Note: This can only be called once per response\n\t*/\n\tstatic async getJSON(response) {\n\t\treturn await response.clone().json();\n\t}\n\t/**\n\t* Format response information for debugging\n\t*/\n\tstatic format(response) {\n\t\tconst metadata = this.getMetadata(response);\n\t\treturn `${metadata.status} ${metadata.statusText} - ${metadata.url}`;\n\t}\n\t/**\n\t* Format response for logging purposes (enhanced version)\n\t*/\n\tstatic formatResponse(response) {\n\t\treturn {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\turl: response.url,\n\t\t\tok: response.ok\n\t\t};\n\t}\n};\n/**\n* Debug logging utilities\n*/\nvar DebugLogger = class {\n\tlogger;\n\tconstructor(logger) {\n\t\tthis.logger = logger || ((level, message, data) => {\n\t\t\tconsole.log(`[${level.toUpperCase()}]`, message);\n\t\t\tif (data) console.log(data);\n\t\t});\n\t}\n\t/**\n\t* Log debug information about API request\n\t*/\n\tlogRequest(request, requestBody) {\n\t\tthis.logger(\"info\", \"API Request Debug Info\", {\n\t\t\tmethod: request.method,\n\t\t\turl: request.url,\n\t\t\theaders: Object.fromEntries(request.headers.entries()),\n\t\t\tbody: requestBody,\n\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t});\n\t}\n\t/**\n\t* Log debug information about API response\n\t*/\n\tasync logResponse(response, responseBody) {\n\t\tthis.logger(\"info\", \"API Response Debug Info\", {\n\t\t\turl: response.url,\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\tok: response.ok,\n\t\t\theaders: Object.fromEntries(response.headers.entries()),\n\t\t\tredirected: response.redirected,\n\t\t\ttype: response.type,\n\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t});\n\t\tif (responseBody) this.logger(\"info\", \"API Response Data\", {\n\t\t\tdata: responseBody,\n\t\t\tcontentType: response.headers.get(\"content-type\"),\n\t\t\tcontentLength: response.headers.get(\"content-length\")\n\t\t});\n\t}\n\t/**\n\t* Log error information\n\t*/\n\tlogError(message, error) {\n\t\tthis.logger(\"error\", message, error);\n\t}\n\t/**\n\t* Compatibility shim retained for older internal callers.\n\t* Response bodies are no longer cached by the debug logger.\n\t*/\n\tgetCachedResponseText(_url) {\n\t\treturn null;\n\t}\n\t/**\n\t* Compatibility shim retained for older internal callers.\n\t* Response bodies are no longer cached by the debug logger.\n\t*/\n\tclearCache() {}\n\tinfo(message, data) {\n\t\tthis.logger(\"info\", message, data);\n\t}\n\twarn(message, data) {\n\t\tthis.logger(\"warn\", message, data);\n\t}\n\terror(message, data) {\n\t\tthis.logger(\"error\", message, data);\n\t}\n};\n/**\n* Extract request body for logging\n*/\nasync function extractRequestBody(request) {\n\tif (request.method === \"GET\" || request.method === \"HEAD\") return null;\n\ttry {\n\t\tconst clonedRequest = request.clone();\n\t\tconst contentType = request.headers.get(\"content-type\")?.toLowerCase();\n\t\tif (contentType?.startsWith(\"application/json\")) return await clonedRequest.json();\n\t\telse if (contentType?.startsWith(\"multipart/form-data\")) return \"[FormData - cannot display]\";\n\t\telse if (contentType?.startsWith(\"text/\")) return await clonedRequest.text();\n\t\treturn \"[Request body - unknown format]\";\n\t} catch (error) {\n\t\treturn \"[Request body unavailable]\";\n\t}\n}\n/**\n* Create debug middleware for openapi-fetch (internal use)\n* Enhanced version that combines original functionality with duration tracking\n*/\nfunction createDebugMiddleware(logger) {\n\tconst debugLogger = new DebugLogger(logger);\n\treturn {\n\t\tasync onRequest({ request }) {\n\t\t\trequest.__debugStartTime = Date.now();\n\t\t\tconst requestBody = await extractRequestBody(request);\n\t\t\tdebugLogger.logRequest(request, requestBody);\n\t\t\treturn request;\n\t\t},\n\t\tasync onResponse({ request, response }) {\n\t\t\tconst startTime = request.__debugStartTime;\n\t\t\tconst duration = startTime ? Date.now() - startTime : 0;\n\t\t\tconst cloned = response.clone();\n\t\t\tlet responseBody = null;\n\t\t\ttry {\n\t\t\t\tconst contentType = response.headers.get(\"content-type\")?.toLowerCase();\n\t\t\t\tif (contentType?.startsWith(\"application/json\")) responseBody = await cloned.json();\n\t\t\t\telse if (contentType?.startsWith(\"text/\")) responseBody = await cloned.text();\n\t\t\t} catch (error) {}\n\t\t\tawait debugLogger.logResponse(response, responseBody);\n\t\t\tif (duration > 0) debugLogger.info(`Request completed in ${duration}ms`, {\n\t\t\t\turl: request.url,\n\t\t\t\tmethod: request.method\n\t\t\t});\n\t\t\treturn response;\n\t\t},\n\t\tasync onError({ error, request }) {\n\t\t\tdebugLogger.logError(\"API Request Failed\", {\n\t\t\t\terror: {\n\t\t\t\t\tname: error instanceof Error ? error.name : \"Unknown\",\n\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : void 0\n\t\t\t\t},\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: request.method,\n\t\t\t\t\turl: request.url,\n\t\t\t\t\theaders: Object.fromEntries(request.headers.entries())\n\t\t\t\t},\n\t\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n//#endregion\n//#region src/middleware/timeout.ts\n/**\n* Timeout middleware for Commerce Engine SDKs\n*/\n/**\n* Create timeout middleware for openapi-fetch\n* Adds configurable request timeout functionality\n* \n* @param timeoutMs - Timeout duration in milliseconds\n* @returns Middleware object with onRequest handler\n*/\nfunction createTimeoutMiddleware(timeoutMs) {\n\tconst timeouts = /* @__PURE__ */ new WeakMap();\n\tconst clearRequestTimeout = (signal) => {\n\t\tconst timeoutId = timeouts.get(signal);\n\t\tif (timeoutId) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\ttimeouts.delete(signal);\n\t\t}\n\t};\n\treturn {\n\t\tonRequest: async ({ request }) => {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\tif (request.signal) request.signal.addEventListener(\"abort\", () => controller.abort(), { once: true });\n\t\t\tconst newRequest = new Request(request, { signal: controller.signal });\n\t\t\ttimeouts.set(newRequest.signal, timeoutId);\n\t\t\tcontroller.signal.addEventListener(\"abort\", () => clearRequestTimeout(newRequest.signal), { once: true });\n\t\t\treturn newRequest;\n\t\t},\n\t\tonResponse: async ({ request, response }) => {\n\t\t\tclearRequestTimeout(request.signal);\n\t\t\treturn response;\n\t\t},\n\t\tonError: async ({ request, error }) => {\n\t\t\tclearRequestTimeout(request.signal);\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n//#endregion\n//#region src/middleware/headers.ts\n/**\n* Header transformation and merging utilities for Commerce Engine SDKs\n*/\n/**\n* Merge two header objects\n* Method-level headers take precedence over default headers\n*\n* @param defaultHeaders - Default headers from SDK configuration\n* @param methodHeaders - Headers passed to the specific method call\n* @returns Merged headers object\n*/\nfunction mergeHeaders(defaultHeaders, methodHeaders) {\n\tconst merged = {};\n\tif (defaultHeaders) Object.assign(merged, defaultHeaders);\n\tif (methodHeaders) Object.assign(merged, methodHeaders);\n\tObject.keys(merged).forEach((key) => {\n\t\tif (merged[key] === void 0) delete merged[key];\n\t});\n\treturn merged;\n}\n/**\n* Transform headers using a transformation mapping\n* Headers not in the transformation map are passed through unchanged\n*\n* @param headers - Headers object with original names\n* @param transformations - Mapping of original names to transformed names\n* @returns Headers object with transformed names\n*/\nfunction transformHeaders(headers, transformations) {\n\tconst transformed = {};\n\tfor (const [key, value] of Object.entries(headers)) if (value !== void 0) {\n\t\tconst headerName = transformations[key] || key;\n\t\ttransformed[headerName] = value;\n\t}\n\treturn transformed;\n}\n/**\n* Merge headers with transformation support\n* Transforms default headers, then merges with method headers\n*\n* @param defaultHeaders - Default headers from SDK configuration\n* @param methodHeaders - Headers passed to the specific method call\n* @param transformations - Mapping for header name transformations\n* @returns Merged headers object with transformations applied\n*/\nfunction mergeAndTransformHeaders(defaultHeaders, methodHeaders, transformations) {\n\tconst merged = {};\n\tif (defaultHeaders && transformations) {\n\t\tconst transformedDefaults = transformHeaders(defaultHeaders, transformations);\n\t\tObject.assign(merged, transformedDefaults);\n\t} else if (defaultHeaders) Object.assign(merged, defaultHeaders);\n\tif (methodHeaders) Object.assign(merged, methodHeaders);\n\tObject.keys(merged).forEach((key) => {\n\t\tif (merged[key] === void 0) delete merged[key];\n\t});\n\treturn merged;\n}\n\n//#endregion\n//#region src/utils/response.ts\n/**\n* Execute a request and handle the response consistently\n* This provides unified error handling and response processing across all SDKs\n*\n* @param apiCall - Function that executes the API request\n* @returns Promise with the API response in standardized format\n*/\nasync function executeRequest(apiCall) {\n\ttry {\n\t\tconst { data, error, response } = await apiCall();\n\t\tif (error) return {\n\t\t\tdata: null,\n\t\t\terror,\n\t\t\tresponse\n\t\t};\n\t\tif (data && data.content !== void 0) return {\n\t\t\tdata: data.content,\n\t\t\terror: null,\n\t\t\tresponse\n\t\t};\n\t\treturn {\n\t\t\tdata,\n\t\t\terror: null,\n\t\t\tresponse\n\t\t};\n\t} catch (err) {\n\t\tconst mockResponse = new Response(null, {\n\t\t\tstatus: 503,\n\t\t\tstatusText: \"Service Unavailable\"\n\t\t});\n\t\treturn {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\tsuccess: false,\n\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\tmessage: \"Network error occurred\",\n\t\t\t\terror: err\n\t\t\t},\n\t\t\tresponse: mockResponse\n\t\t};\n\t}\n}\n\n//#endregion\n//#region src/base-client.ts\n/**\n* Base API client for Commerce Engine SDKs\n* Provides common functionality without token management\n*/\n/**\n* Generic base API client that all Commerce Engine SDKs can extend\n* Handles common functionality like middleware setup, request execution, and header management\n* Does NOT include token management - that's SDK-specific\n* \n* @template TPaths - OpenAPI paths type\n* @template THeaders - Supported default headers type\n*/\nvar BaseAPIClient = class {\n\tclient;\n\tconfig;\n\tbaseUrl;\n\theaderTransformations;\n\t/**\n\t* Create a new BaseAPIClient\n\t*\n\t* @param config - Configuration for the API client\n\t* @param baseUrl - The base URL for the API (must be provided by subclass)\n\t* @param headerTransformations - Header name transformations for this SDK\n\t*/\n\tconstructor(config, baseUrl, headerTransformations = {}) {\n\t\tthis.config = { ...config };\n\t\tthis.headerTransformations = headerTransformations;\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.client = createClient({ baseUrl: this.baseUrl });\n\t\tthis.setupMiddleware();\n\t}\n\t/**\n\t* Set up all middleware for the client\n\t*/\n\tsetupMiddleware() {\n\t\tif (this.config.timeout) {\n\t\t\tconst timeoutMiddleware = createTimeoutMiddleware(this.config.timeout);\n\t\t\tthis.client.use(timeoutMiddleware);\n\t\t}\n\t\tif (this.config.debug) {\n\t\t\tconst debugMiddleware = createDebugMiddleware(this.config.logger);\n\t\t\tthis.client.use(debugMiddleware);\n\t\t}\n\t}\n\t/**\n\t* Get the base URL of the API\n\t*\n\t* @returns The base URL of the API\n\t*/\n\tgetBaseUrl() {\n\t\treturn this.baseUrl;\n\t}\n\t/**\n\t* Execute a request and handle the response consistently\n\t* This provides unified error handling and response processing\n\t*\n\t* @param apiCall - Function that executes the API request\n\t* @returns Promise with the API response in standardized format\n\t*/\n\tasync executeRequest(apiCall) {\n\t\treturn executeRequest(apiCall);\n\t}\n\t/**\n\t* Merge default headers with method-level headers\n\t* Method-level headers take precedence over default headers\n\t* Automatically applies SDK-specific header transformations\n\t*\n\t* @param methodHeaders - Headers passed to the specific method call\n\t* @returns Merged headers object with proper HTTP header names\n\t*/\n\tmergeHeaders(methodHeaders) {\n\t\treturn mergeAndTransformHeaders(this.config.defaultHeaders, methodHeaders, this.headerTransformations);\n\t}\n\t/**\n\t* Set default headers for the client\n\t*\n\t* @param headers - Default headers to set\n\t*/\n\tsetDefaultHeaders(headers) {\n\t\tthis.config.defaultHeaders = headers;\n\t}\n\t/**\n\t* Get current default headers\n\t*\n\t* @returns Current default headers\n\t*/\n\tgetDefaultHeaders() {\n\t\treturn this.config.defaultHeaders;\n\t}\n};\n\n//#endregion\n//#region src/utils/url.ts\n/**\n* Generic URL utility functions for any SDK\n*/\n/**\n* Extract pathname from URL\n* Useful for middleware that needs to inspect request paths\n*/\nfunction getPathnameFromUrl(url) {\n\ttry {\n\t\treturn new URL(url).pathname;\n\t} catch {\n\t\treturn url.split(\"?\")[0] || url;\n\t}\n}\n\n//#endregion\nexport { BaseAPIClient, DebugLogger, ResponseUtils, createDebugMiddleware, createTimeoutMiddleware, executeRequest, extractRequestBody, getPathnameFromUrl, mergeAndTransformHeaders, mergeHeaders, transformHeaders };","/**\n * Decode a JWT token payload without signature verification.\n * This is a lightweight replacement for jose's decodeJwt.\n *\n * @param token - The JWT token to decode\n * @returns The decoded payload\n * @throws Error if the token is malformed\n */\nfunction decodeJwt<T = Record<string, unknown>>(token: string): T {\n if (typeof token !== \"string\") {\n throw new Error(\"Invalid token: must be a string\");\n }\n\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid token: must have 3 parts\");\n }\n\n const base64Url = parts[1];\n if (!base64Url) throw new Error(\"Invalid token: missing payload\");\n\n let base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = base64.length % 4;\n if (padding) base64 += \"=\".repeat(4 - padding);\n\n // UTF-8 safe decoding\n const binaryStr = atob(base64);\n const bytes = new Uint8Array(binaryStr.length);\n for (let i = 0; i < binaryStr.length; i++) {\n bytes[i] = binaryStr.charCodeAt(i);\n }\n\n const payload = JSON.parse(new TextDecoder().decode(bytes));\n if (typeof payload !== \"object\" || payload === null) {\n throw new Error(\"Invalid token: payload must be an object\");\n }\n\n return payload;\n}\n\n/**\n * JWT payload structure for POS tokens\n */\nexport interface JwtPayload {\n token_type: string;\n exp: number;\n iat: number;\n jti: string;\n ulid: string;\n username: string;\n email: string;\n phone: string;\n first_name: string;\n last_name: string;\n store_id: string;\n is_logged_in: boolean;\n roles: {\n role_id: string;\n role_name: string;\n location_id: string;\n location_name: string;\n }[];\n location: {\n id: string;\n name: string;\n };\n tenant_id: string;\n channel: {\n id: string;\n name: string;\n type: string;\n };\n sid: string;\n}\n\n/**\n * User information extracted from POS JWT token\n */\nexport interface UserInfo {\n id: string;\n username: string;\n email: string;\n phone: string;\n firstName: string;\n lastName: string;\n storeId: string;\n isLoggedIn: boolean;\n roles: {\n roleId: string;\n roleName: string;\n locationId: string;\n locationName: string;\n }[];\n location: {\n id: string;\n name: string;\n };\n tenantId: string;\n channel: {\n id: string;\n name: string;\n type: string;\n };\n sessionId: string;\n tokenExpiry: Date;\n tokenIssuedAt: Date;\n}\n\n/**\n * Decode and extract user information from a JWT token\n *\n * @param token - The JWT token to decode\n * @returns User information or null if token is invalid\n */\nexport function extractUserInfoFromToken(token: string): UserInfo | null {\n try {\n const payload = decodeJwt(token) as JwtPayload;\n\n return {\n id: payload.ulid,\n username: payload.username,\n email: payload.email,\n phone: payload.phone,\n firstName: payload.first_name,\n lastName: payload.last_name,\n storeId: payload.store_id,\n isLoggedIn: payload.is_logged_in,\n roles: payload.roles.map(role => ({\n roleId: role.role_id,\n roleName: role.role_name,\n locationId: role.location_id,\n locationName: role.location_name,\n })),\n location: {\n id: payload.location.id,\n name: payload.location.name,\n },\n tenantId: payload.tenant_id,\n channel: {\n id: payload.channel.id,\n name: payload.channel.name,\n type: payload.channel.type,\n },\n sessionId: payload.sid,\n tokenExpiry: new Date(payload.exp * 1000),\n tokenIssuedAt: new Date(payload.iat * 1000),\n };\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return null;\n }\n}\n\n/**\n * Check if a JWT token is expired\n *\n * @param token - The JWT token to check\n * @param bufferSeconds - Buffer time in seconds (default: 30)\n * @returns True if token is expired or will expire within buffer time\n */\nexport function isTokenExpired(\n token: string,\n bufferSeconds: number = 30\n): boolean {\n try {\n const payload = decodeJwt<{ exp?: number }>(token);\n if (!payload.exp) return true;\n\n const currentTime = Math.floor(Date.now() / 1000);\n const expiryTime = payload.exp;\n\n // Consider token expired if it expires within the buffer time\n return currentTime >= expiryTime - bufferSeconds;\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return true; // Treat invalid tokens as expired\n }\n}\n\n/**\n * Get the user ID from a JWT token\n *\n * @param token - The JWT token\n * @returns User ID (ulid) or null if token is invalid\n */\nexport function getUserIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.id || null;\n}\n\n/**\n * Check if user is logged in based on JWT token\n *\n * @param token - The JWT token\n * @returns True if user is logged in, false otherwise\n */\nexport function isUserLoggedIn(token: string): boolean {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.isLoggedIn || false;\n}\n\n/**\n * Check if user is authenticated (has valid POS token)\n * Checks the token for isLoggedIn status\n *\n * @param token - The JWT token\n * @returns True if user is authenticated with valid POS access\n */\nexport function isUserAuthenticated(token: string): boolean {\n const userInfo = extractUserInfoFromToken(token);\n return !!userInfo?.isLoggedIn;\n}\n\n\n/**\n * Get the location ID from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Location ID or null if token is invalid\n */\nexport function getLocationIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.location?.id || null;\n}\n\n/**\n * Get the role information from a POS JWT token for the current location\n *\n * @param token - The JWT token\n * @returns Role object for the current location, or null if token is invalid\n */\nexport function getRoleFromToken(token: string): {\n roleId: string;\n roleName: string;\n locationId: string;\n locationName: string;\n} | null {\n const userInfo = extractUserInfoFromToken(token);\n if (!userInfo?.roles || userInfo.roles.length === 0) return null;\n\n // Find role for current location, or return first role if location match not found\n const currentLocationRole = userInfo.roles.find(role => role.locationId === userInfo.location.id);\n return currentLocationRole || userInfo.roles[0] || null;\n}\n\n/**\n * Get the tenant ID from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Tenant ID or null if token is invalid\n */\nexport function getTenantIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.tenantId || null;\n}\n\n/**\n * Get the channel information from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Channel object with id, name, and type, or null if token is invalid\n */\nexport function getChannelFromToken(token: string): {\n id: string;\n name: string;\n type: string;\n} | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.channel || null;\n}\n\n/**\n * Get the session ID from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Session ID or null if token is invalid\n */\nexport function getSessionIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.sessionId || null;\n}\n","/**\n * Check if a URL path is a POS login endpoint that should use API key\n * Based on POS spec, only these 5 endpoints use X-Api-Key:\n * - /pos/auth/login/email\n * - /pos/auth/login/phone\n * - /pos/auth/login/whatsapp\n * - /pos/auth/pair-device\n * - /pos/auth/verify-otp\n */\nexport function isApiKeyEndpoint(pathname: string): boolean {\n const apiKeyEndpoints = [\n \"/pos/auth/login/email\",\n \"/pos/auth/login/phone\",\n \"/pos/auth/login/whatsapp\",\n \"/pos/auth/pair-device\",\n \"/pos/auth/verify-otp\",\n \"/pos/locations\",\n ];\n return apiKeyEndpoints.some((endpoint) => pathname.includes(endpoint));\n}\n\n/**\n * Check if a URL path is a POS endpoint that returns tokens\n * Based on POS spec, only these endpoints return tokens:\n * - /pos/auth/verify-otp (after OTP verification)\n * - /pos/auth/refresh-token\n */\nexport function isTokenReturningEndpoint(pathname: string): boolean {\n const tokenEndpoints = [\"/pos/auth/verify-otp\", \"/pos/auth/refresh-token\"];\n return tokenEndpoints.some((endpoint) => pathname.includes(endpoint));\n}\n\n/**\n * Check if a URL path is a POS logout endpoint\n */\nexport function isLogoutEndpoint(pathname: string): boolean {\n return (\n pathname.includes(\"/pos/auth/logout\") || pathname.includes(\"/pos/logout\")\n );\n}\n\n// Re-export JWT utilities from jwt.ts\nexport {\n isTokenExpired,\n extractUserInfoFromToken,\n getUserIdFromToken,\n isUserLoggedIn,\n isUserAuthenticated,\n getLocationIdFromToken,\n getRoleFromToken,\n getTenantIdFromToken,\n} from \"./jwt\";\nexport type { UserInfo, JwtPayload } from \"./jwt\";\n","import type { Middleware } from \"openapi-fetch\";\nimport { getPathnameFromUrl } from \"@commercengine/sdk-core\";\nimport {\n isApiKeyEndpoint,\n isTokenReturningEndpoint,\n isLogoutEndpoint,\n isTokenExpired,\n} from \"../utils/auth\";\n\n/**\n * Token storage interface for the POS auth middleware\n */\nexport interface TokenStorage {\n getAccessToken(): Promise<string | null>;\n setAccessToken(token: string): Promise<void>;\n getRefreshToken(): Promise<string | null>;\n setRefreshToken(token: string): Promise<void>;\n clearTokens(): Promise<void>;\n}\n\n/**\n * Simple in-memory token storage implementation\n */\nexport class MemoryTokenStorage implements TokenStorage {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n\n async getAccessToken(): Promise<string | null> {\n return this.accessToken;\n }\n\n async setAccessToken(token: string): Promise<void> {\n this.accessToken = token;\n }\n\n async getRefreshToken(): Promise<string | null> {\n return this.refreshToken;\n }\n\n async setRefreshToken(token: string): Promise<void> {\n this.refreshToken = token;\n }\n\n async clearTokens(): Promise<void> {\n this.accessToken = null;\n this.refreshToken = null;\n }\n}\n\n/**\n * Browser localStorage token storage implementation for POS\n */\nexport class BrowserTokenStorage implements TokenStorage {\n private accessTokenKey: string;\n private refreshTokenKey: string;\n\n constructor(prefix: string = \"pos_\") {\n this.accessTokenKey = `${prefix}access_token`;\n this.refreshTokenKey = `${prefix}refresh_token`;\n }\n\n async getAccessToken(): Promise<string | null> {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(this.accessTokenKey);\n }\n\n async setAccessToken(token: string): Promise<void> {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(this.accessTokenKey, token);\n }\n }\n\n async getRefreshToken(): Promise<string | null> {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(this.refreshTokenKey);\n }\n\n async setRefreshToken(token: string): Promise<void> {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(this.refreshTokenKey, token);\n }\n }\n\n async clearTokens(): Promise<void> {\n if (typeof localStorage !== \"undefined\") {\n localStorage.removeItem(this.accessTokenKey);\n localStorage.removeItem(this.refreshTokenKey);\n }\n }\n}\n\n/**\n * Configuration for the POS auth middleware\n */\nexport interface PosAuthMiddlewareConfig {\n /**\n * Token storage implementation\n */\n tokenStorage: TokenStorage;\n\n /**\n * API key for X-Api-Key endpoints (login, pair-device, verify-otp)\n * Required for POS authentication flows and fallback scenarios\n */\n apiKey: string;\n\n /**\n * Base URL for the API (used for refresh token endpoint)\n */\n baseUrl: string;\n\n /**\n * Function to refresh tokens\n * Should make a call to the POS refresh token endpoint\n */\n refreshTokenFn?: (refreshToken: string) => Promise<{\n access_token: string;\n refresh_token: string;\n }>;\n\n /**\n * Callback when tokens are updated (login/refresh)\n */\n onTokensUpdated?: (accessToken: string, refreshToken: string) => void;\n\n /**\n * Callback when tokens are cleared (logout/error)\n */\n onTokensCleared?: () => void;\n}\n\n/**\n * Create POS authentication middleware for openapi-fetch\n *\n * POS Authentication Rules:\n * 1. API Key endpoints (X-Api-Key): login/email, login/phone, login/whatsapp, pair-device, verify-otp\n * 2. Bearer token endpoints: All other endpoints\n * 3. Token returning endpoints: verify-otp, refresh-token\n */\nexport function createPosAuthMiddleware(\n config: PosAuthMiddlewareConfig\n): Middleware {\n let isRefreshing = false;\n let refreshPromise: Promise<void> | null = null;\n let hasAssessedTokens = false;\n\n const assessTokenStateOnce = async (): Promise<void> => {\n // Skip if already assessed (tokenStorage is guaranteed to exist when middleware is created)\n if (hasAssessedTokens) return;\n\n hasAssessedTokens = true;\n\n try {\n const accessToken = await config.tokenStorage.getAccessToken();\n const refreshToken = await config.tokenStorage.getRefreshToken();\n\n // Case 1: Valid access token - do nothing\n if (accessToken && !isTokenExpired(accessToken)) {\n return;\n }\n\n // Case 2: Orphaned refresh token (no access token but refresh token exists)\n if (!accessToken && refreshToken) {\n // Clean up orphaned refresh token to prevent confusion\n await config.tokenStorage.clearTokens();\n config.onTokensCleared?.();\n console.info(\"Cleaned up orphaned refresh token in POS\");\n return;\n }\n\n // Case 3: Expired access token with valid refresh token\n if (accessToken && refreshToken && !isTokenExpired(refreshToken)) {\n try {\n await refreshTokens();\n console.info(\"POS tokens refreshed proactively on startup\");\n } catch (error) {\n // Refresh failed - both tokens are likely invalid, clear them\n await config.tokenStorage.clearTokens();\n config.onTokensCleared?.();\n console.info(\"POS tokens cleared after failed refresh on startup\");\n }\n return;\n }\n\n // Case 4: Both tokens expired or invalid - clear stale tokens\n if (\n (accessToken && isTokenExpired(accessToken)) ||\n (refreshToken && isTokenExpired(refreshToken))\n ) {\n await config.tokenStorage.clearTokens();\n config.onTokensCleared?.();\n console.info(\n \"POS stale tokens cleared on startup - user needs to re-authenticate\"\n );\n return;\n }\n\n // Case 5: No tokens at all - valid unauthenticated state\n if (!accessToken && !refreshToken) {\n // This is normal - user hasn't logged in or has logged out\n // No action needed, POS will work with API key endpoints\n return;\n }\n\n // Note: Unlike storefront, POS doesn't have anonymous fallback\n // Users must explicitly authenticate through login endpoints\n } catch (error) {\n // Silent fail - don't break the request flow\n console.warn(\"POS token state assessment failed:\", error);\n }\n };\n\n const refreshTokens = async (): Promise<void> => {\n if (isRefreshing && refreshPromise) {\n return refreshPromise;\n }\n\n isRefreshing = true;\n refreshPromise = (async () => {\n try {\n const refreshToken = await config.tokenStorage.getRefreshToken();\n\n if (!refreshToken || isTokenExpired(refreshToken)) {\n throw new Error(\"No valid refresh token available\");\n }\n\n let newTokens: { access_token: string; refresh_token: string };\n\n if (config.refreshTokenFn) {\n // Use provided refresh function\n newTokens = await config.refreshTokenFn(refreshToken);\n } else {\n // Default refresh implementation for POS\n const response = await fetch(\n `${config.baseUrl}/pos/auth/refresh-token`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${await config.tokenStorage.getAccessToken()}`,\n },\n body: JSON.stringify({ refresh_token: refreshToken }),\n }\n );\n\n if (!response.ok) {\n throw new Error(`POS token refresh failed: ${response.status}`);\n }\n\n const data = await response.json();\n newTokens = data.content || data;\n }\n\n // Store new tokens\n await config.tokenStorage.setAccessToken(newTokens.access_token);\n await config.tokenStorage.setRefreshToken(newTokens.refresh_token);\n\n // Notify callback\n config.onTokensUpdated?.(\n newTokens.access_token,\n newTokens.refresh_token\n );\n } catch (error) {\n console.error(\"POS token refresh failed:\", error);\n // Clear tokens on refresh failure\n await config.tokenStorage.clearTokens();\n config.onTokensCleared?.();\n throw error;\n } finally {\n isRefreshing = false;\n refreshPromise = null;\n }\n })();\n\n return refreshPromise;\n };\n\n return {\n async onRequest({ request }) {\n const pathname = getPathnameFromUrl(request.url);\n\n // Assess token state once per middleware instance (POS session start)\n await assessTokenStateOnce();\n\n // Handle API Key endpoints (5 specific endpoints only)\n if (isApiKeyEndpoint(pathname)) {\n request.headers.set(\"X-Api-Key\", config.apiKey);\n return request;\n }\n\n // For all other endpoints, use Bearer token\n let accessToken = await config.tokenStorage.getAccessToken();\n\n // Check if token needs refresh\n if (accessToken && isTokenExpired(accessToken)) {\n try {\n await refreshTokens();\n accessToken = await config.tokenStorage.getAccessToken();\n } catch (error) {\n // If refresh fails, continue without token (will get 401)\n console.warn(\"Token refresh failed:\", error);\n accessToken = null;\n }\n }\n\n // Add Authorization header if we have a token\n if (accessToken) {\n request.headers.set(\"Authorization\", `Bearer ${accessToken}`);\n }\n\n return request;\n },\n\n async onResponse({ request, response }) {\n const pathname = getPathnameFromUrl(request.url);\n\n // Handle successful responses that return tokens (verify-otp, refresh-token)\n if (response.ok && isTokenReturningEndpoint(pathname)) {\n try {\n const data = await response.clone().json();\n const content = data.content || data;\n\n if (content?.access_token && content?.refresh_token) {\n await config.tokenStorage.setAccessToken(content.access_token);\n await config.tokenStorage.setRefreshToken(content.refresh_token);\n config.onTokensUpdated?.(\n content.access_token,\n content.refresh_token\n );\n }\n } catch (error) {\n console.warn(\"Failed to extract tokens from POS response:\", error);\n }\n } else if (response.ok && isLogoutEndpoint(pathname)) {\n // Clear tokens on successful logout\n await config.tokenStorage.clearTokens();\n config.onTokensCleared?.();\n }\n\n // Handle 401 responses - retry once if token was expired\n if (response.status === 401 && !isApiKeyEndpoint(pathname)) {\n const currentToken = await config.tokenStorage.getAccessToken();\n\n // Only attempt refresh if we have a token and it's expired\n if (currentToken && isTokenExpired(currentToken, 0)) {\n try {\n await refreshTokens();\n\n // Retry the original request with new token\n const newToken = await config.tokenStorage.getAccessToken();\n if (newToken) {\n const retryRequest = request.clone();\n retryRequest.headers.set(\"Authorization\", `Bearer ${newToken}`);\n return fetch(retryRequest);\n }\n } catch (error) {\n // If refresh fails, let the original 401 response through\n console.warn(\"POS token refresh failed on 401 response:\", error);\n }\n }\n }\n\n // Handle 403 responses - token is blacklisted/revoked, clear all tokens\n if (response.status === 403 && !isApiKeyEndpoint(pathname)) {\n await config.tokenStorage.clearTokens();\n config.onTokensCleared?.();\n console.info(\n \"POS tokens cleared due to 403 - session revoked. This can happen when a user has more than 5 active sessions. Please re-authenticate.\"\n );\n }\n\n return response;\n },\n };\n}\n\n/**\n * Helper function to create POS auth middleware with sensible defaults\n */\nexport function createDefaultPosAuthMiddleware(options: {\n apiKey: string;\n baseUrl: string;\n tokenStorage?: TokenStorage;\n onTokensUpdated?: (accessToken: string, refreshToken: string) => void;\n onTokensCleared?: () => void;\n}): Middleware {\n const tokenStorage =\n options.tokenStorage ||\n (typeof localStorage !== \"undefined\"\n ? new BrowserTokenStorage()\n : new MemoryTokenStorage());\n\n return createPosAuthMiddleware({\n tokenStorage,\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n onTokensUpdated: options.onTokensUpdated,\n onTokensCleared: options.onTokensCleared,\n });\n}\n","/**\n * Environment configuration for POS API\n */\nexport enum Environment {\n Development = \"dev\",\n Staging = \"staging\",\n Production = \"production\",\n}\n\n/**\n * Configuration for building POS API URLs\n */\nexport interface PosURLConfig {\n storeId: string;\n environment?: Environment;\n baseUrl?: string;\n}\n\n/**\n * Build the base URL for POS API requests\n *\n * @param config - URL configuration\n * @returns The base URL for POS API requests\n */\nexport function buildPosURL(config: PosURLConfig): string {\n // If custom baseUrl is provided, use it directly\n if (config.baseUrl) {\n return config.baseUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n }\n\n // Build URL based on environment and store ID\n const env = config.environment || Environment.Production;\n\n switch (env) {\n case Environment.Staging:\n return `https://staging.api.commercengine.io/api/v1/${config.storeId}/storefront`;\n case Environment.Production:\n default:\n return `https://prod.api.commercengine.io/api/v1/${config.storeId}/storefront`;\n }\n}\n","import type { paths } from \"../types/pos\";\nimport type { paths as AdminPaths } from \"../types/admin-pos\";\nimport { BaseAPIClient, getPathnameFromUrl } from \"@commercengine/sdk-core\";\nimport { createDefaultPosAuthMiddleware } from \"./middleware/auth\";\nimport { isApiKeyEndpoint } from \"./utils/auth\";\nimport { buildPosURL } from \"./utils/url\";\nimport type { PosSDKOptions, SupportedDefaultHeaders } from \"../index\";\n\ntype CombinedPaths = paths & AdminPaths;\n\n/**\n * POS API client that extends the generic BaseAPIClient\n * Adds Commerce Engine POS specific authentication and token management\n */\nexport class PosAPIClient extends BaseAPIClient<\n CombinedPaths,\n SupportedDefaultHeaders\n> {\n protected config: PosSDKOptions;\n private initializationPromise: Promise<void> | null = null;\n\n /**\n * Validate required configuration parameters\n * @param config - Configuration to validate\n * @throws Error with descriptive message if validation fails\n */\n private static validateConfig(config: PosSDKOptions): void {\n const errors: string[] = [];\n\n // Required fields validation\n if (!config.storeId?.trim()) {\n errors.push(\"storeId is required and cannot be empty\");\n }\n\n if (!config.apiKey?.trim()) {\n errors.push(\n \"apiKey is required for POS authentication (needed for login, device pairing, and token refresh fallbacks)\"\n );\n }\n\n // Token configuration validation\n if (config.accessToken && !config.tokenStorage && !config.refreshToken) {\n errors.push(\n \"When providing accessToken without tokenStorage, consider providing refreshToken for token refresh capability\"\n );\n }\n\n if (config.refreshToken && !config.accessToken) {\n errors.push(\n \"refreshToken cannot be provided without accessToken (orphaned refresh token)\"\n );\n }\n\n if (config.refreshToken && !config.tokenStorage) {\n errors.push(\n \"refreshToken requires tokenStorage for automatic token management\"\n );\n }\n\n // Callback validation\n if (\n (config.onTokensUpdated || config.onTokensCleared) &&\n !config.tokenStorage\n ) {\n errors.push(\n \"Token callbacks (onTokensUpdated/onTokensCleared) require tokenStorage for automatic token management\"\n );\n }\n\n // URL validation\n if (config.baseUrl && !PosAPIClient.isValidUrl(config.baseUrl)) {\n errors.push(\"baseUrl must be a valid HTTP/HTTPS URL\");\n }\n\n if (errors.length > 0) {\n throw new Error(\n `POS SDK configuration validation failed:\\n- ${errors.join(\"\\n- \")}`\n );\n }\n }\n\n /**\n * Check if a string is a valid URL\n * @param url - URL string to validate\n * @returns True if valid URL\n */\n private static isValidUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n }\n\n /**\n * Create a new PosAPIClient\n *\n * @param config - Configuration for the API client\n */\n constructor(config: PosSDKOptions) {\n // Validate required configuration first (before calling super)\n PosAPIClient.validateConfig(config);\n\n // Build base URL from Commerce Engine config\n const baseUrl = buildPosURL({\n storeId: config.storeId,\n environment: config.environment,\n baseUrl: config.baseUrl,\n });\n\n // Header transformations for POS API\n const headerTransformations = {\n customer_group_id: \"x-customer-group-id\",\n debug_mode: \"x-debug-mode\",\n // Add any other header transformations here\n } as Record<keyof SupportedDefaultHeaders, string>;\n\n // Call parent constructor with generic config\n super(\n {\n baseUrl: baseUrl,\n timeout: config.timeout,\n defaultHeaders: config.defaultHeaders,\n debug: config.debug,\n logger: config.logger,\n },\n baseUrl,\n headerTransformations\n );\n\n // Store full config for POS-specific features\n this.config = { ...config };\n\n // Set up POS-specific auth middleware\n this.setupPosAuth();\n }\n\n /**\n * Set up POS-specific authentication middleware\n */\n private setupPosAuth(): void {\n const config = this.config as PosSDKOptions;\n\n // Set up auth middleware if token storage is provided\n if (config.tokenStorage) {\n const authMiddleware = createDefaultPosAuthMiddleware({\n apiKey: config.apiKey,\n baseUrl: this.getBaseUrl(),\n tokenStorage: config.tokenStorage,\n onTokensUpdated: config.onTokensUpdated,\n onTokensCleared: config.onTokensCleared,\n });\n this.client.use(authMiddleware);\n\n // If initial tokens were provided, store them in tokenStorage\n if (config.accessToken) {\n this.initializationPromise = this.initializeTokens(\n config.accessToken,\n config.refreshToken\n );\n // Clear the manual tokens since we're using storage\n config.accessToken = undefined;\n config.refreshToken = undefined;\n }\n } else {\n // For manual token management, add simple header injection middleware\n this.client.use({\n onRequest: async ({ request }) => {\n const pathname = getPathnameFromUrl(request.url);\n\n // For login endpoints, use API key\n if (isApiKeyEndpoint(pathname)) {\n request.headers.set(\"X-Api-Key\", config.apiKey);\n return request;\n }\n\n // For all other endpoints, prefer access token, fallback to API key\n if (config.accessToken) {\n request.headers.set(\n \"Authorization\",\n `Bearer ${config.accessToken}`\n );\n } else if (config.apiKey) {\n request.headers.set(\"X-Api-Key\", config.apiKey);\n }\n\n return request;\n },\n });\n }\n }\n\n /**\n * Get the authorization header value\n * If using token storage, gets the current token from storage\n * Otherwise returns the manual token\n *\n * @returns The Authorization header value or empty string if no token is set\n */\n public async getAuthorizationHeader(): Promise<string> {\n // Wait for initialization to complete if using token storage\n if (this.config.tokenStorage && this.initializationPromise) {\n await this.initializationPromise;\n }\n\n if (this.config.tokenStorage) {\n const token = await this.config.tokenStorage.getAccessToken();\n return token ? `Bearer ${token}` : \"\";\n }\n return this.config.accessToken ? `Bearer ${this.config.accessToken}` : \"\";\n }\n\n /**\n * Set authentication tokens\n *\n * @param accessToken - The access token (required)\n * @param refreshToken - The refresh token (optional)\n *\n * Behavior:\n * - If tokenStorage is provided: Stores tokens for automatic management\n * - If tokenStorage is not provided: Only stores access token for manual management\n */\n public async setTokens(\n accessToken: string,\n refreshToken?: string\n ): Promise<void> {\n if (this.config.tokenStorage) {\n // Automatic token management\n await this.config.tokenStorage.setAccessToken(accessToken);\n if (refreshToken) {\n await this.config.tokenStorage.setRefreshToken(refreshToken);\n }\n } else {\n // Manual token management - only access token\n this.config.accessToken = accessToken;\n if (refreshToken) {\n console.warn(\n \"Refresh token provided but ignored in manual token management mode. Use tokenStorage for automatic management.\"\n );\n }\n }\n }\n\n /**\n * Clear all authentication tokens\n *\n * Behavior:\n * - If tokenStorage is provided: Clears both access and refresh tokens from storage\n * - If tokenStorage is not provided: Clears the manual access token\n */\n public async clearTokens(): Promise<void> {\n if (this.config.tokenStorage) {\n await this.config.tokenStorage.clearTokens();\n } else {\n this.config.accessToken = undefined;\n }\n }\n\n /**\n * Set the X-Api-Key header\n *\n * @param apiKey - The API key to set\n */\n public setApiKey(apiKey: string): void {\n this.config.apiKey = apiKey;\n }\n\n /**\n * Initialize tokens in storage (private helper method)\n */\n private async initializeTokens(\n accessToken: string,\n refreshToken?: string\n ): Promise<void> {\n try {\n if (this.config.tokenStorage) {\n await this.config.tokenStorage.setAccessToken(accessToken);\n if (refreshToken) {\n await this.config.tokenStorage.setRefreshToken(refreshToken);\n }\n }\n } catch (error) {\n console.warn(\"Failed to initialize tokens in storage:\", error);\n }\n }\n\n /**\n * Get client typed for storefront POS operations (paths schema)\n * This provides proper typing for storefront POS endpoints\n */\n public get storefrontClient() {\n return this.client as BaseAPIClient<\n paths,\n SupportedDefaultHeaders\n >[\"client\"];\n }\n\n /**\n * Get client typed for admin POS operations (AdminPaths schema)\n * This provides proper typing for admin POS endpoints\n */\n public get adminClient() {\n return this.client as BaseAPIClient<\n AdminPaths,\n SupportedDefaultHeaders\n >[\"client\"];\n }\n}\n","import { PosAPIClient } from \"./client\";\nimport type { ApiResult } from \"@commercengine/sdk-core\";\nimport type {\n // Auth types\n LoginPosDeviceWithEmailBody,\n LoginPosDeviceWithEmailContent,\n LoginPosDeviceWithPhoneBody,\n LoginPosDeviceWithPhoneContent,\n LoginPosDeviceWithWhatsappBody,\n LoginPosDeviceWithWhatsappContent,\n PairPosDeviceContent,\n RefreshPosAccessTokenBody,\n RefreshPosAccessTokenContent,\n VerifyPosLoginOtpBody,\n VerifyPosLoginOtpContent,\n LogoutFromPosDeviceResponse,\n\n // Devices\n PairPosDeviceBody,\n ListPosDevicesContent,\n ClaimPosDevicePathParams,\n UnclaimPosDevicePathParams,\n ClaimPosDeviceResponse,\n UnclaimPosDeviceResponse,\n\n // Cart types\n PosCreateCartBody,\n PosCreateCartContent,\n PosGetCartPathParams,\n PosGetCartContent,\n PosDeleteCartPathParams,\n PosDeleteCartResponse,\n PosUpdateCartPathParams,\n PosUpdateCartBody,\n PosUpdateCartContent,\n PosGetUserCartPathParams,\n PosGetUserCartContent,\n\n // Cart address\n PosCreateCartAddressPathParams,\n PosCreateCartAddressBody,\n PosCreateCartAddressContent,\n\n // Coupons\n PosListCouponsContent,\n PosListCouponsHeaderParams,\n PosApplyCouponPathParams,\n PosApplyCouponBody,\n PosApplyCouponContent,\n PosRemoveCouponPathParams,\n PosRemoveCouponContent,\n PosEvaluateCouponsPathParams,\n PosEvaluateCouponsContent,\n\n // Promotions\n PosListPromotionsContent,\n PosListPromotionsHeaderParams,\n PosEvaluatePromotionsPathParams,\n PosEvaluatePromotionsContent,\n\n // Credit balance\n PosRedeemCreditBalancePathParams,\n PosRedeemCreditBalanceBody,\n PosRedeemCreditBalanceContent,\n PosRemoveCreditBalancePathParams,\n PosRemoveCreditBalanceContent,\n\n // Loyalty points\n PosRedeemLoyaltyPointsPathParams,\n PosRedeemLoyaltyPointsBody,\n PosRedeemLoyaltyPointsContent,\n PosRemoveLoyaltyPointsPathParams,\n PosRemoveLoyaltyPointsContent,\n\n // Fulfillment\n PosUpdateFulfillmentPreferencePathParams,\n PosUpdateFulfillmentPreferenceBody,\n PosUpdateFulfillmentPreferenceResponse,\n GetPosFulfillmentOptionsBody,\n GetPosFulfillmentOptionsContent,\n\n // Customer\n UpdatePosCartCustomerPathParams,\n UpdatePosCartCustomerBody,\n UpdatePosCartCustomerContent,\n\n // Orders\n CreatePosOrderBody,\n CreatePosOrderContent,\n\n // Payment\n PosGetPaymentStatusContent,\n PosGetPaymentStatusPathParams,\n\n // Catalog types\n PosListCategoriesContent,\n PosListCategoriesQuery,\n PosListProductsContent,\n PosListProductsQuery,\n PosListProductsHeaderParams,\n PosListCrosssellProductsContent,\n PosListCrosssellProductsQuery,\n PosListCrosssellProductsHeaderParams,\n PosSearchProductsBody,\n PosSearchProductsContent,\n PosSearchProductsHeaderParams,\n PosListSimilarProductsContent,\n PosListSimilarProductsQuery,\n PosListSimilarProductsHeaderParams,\n PosListUpsellProductsContent,\n PosListUpsellProductsQuery,\n PosListUpsellProductsHeaderParams,\n PosGetProductDetailPathParams,\n PosGetProductDetailQuery,\n PosGetProductDetailContent,\n PosGetProductDetailHeaderParams,\n PosListProductReviewsPathParams,\n PosListProductReviewsContent,\n PosListProductReviewsQuery,\n PosListProductVariantsPathParams,\n PosListProductVariantsQuery,\n PosListProductVariantsContent,\n PosListProductVariantsHeaderParams,\n PosGetVariantDetailPathParams,\n PosGetVariantDetailQuery,\n PosGetVariantDetailContent,\n PosGetVariantDetailHeaderParams,\n PosListSkusContent,\n PosListSkusQuery,\n PosListSkusHeaderParams,\n ListPosLocationsContent,\n GetPosUserPathParams,\n GetPosUserContent,\n UnclaimPosDeviceContent,\n ClaimPosDeviceContent,\n LoginPosDeviceWithEmailHeaderParams,\n LoginPosDeviceWithPhoneHeaderParams,\n LoginPosDeviceWithWhatsappHeaderParams,\n PosUpdateFulfillmentPreferenceContent,\n} from \"../types/pos-api-types\";\nimport type {\n // Admin Inventory types\n PosListInventoryContent,\n PosListInventoryQuery,\n PosListInventoryActivityContent,\n PosListInventoryActivityQuery,\n PosListInventoryDetailContent,\n PosListInventoryDetailQuery,\n\n // Admin Customer types\n PosListCustomersContent,\n PosListCustomersQuery,\n PosGetCustomerDetailContent,\n PosGetCustomerDetailPathParams,\n\n // Admin Order types\n PosListOrdersContent,\n PosListOrdersQuery,\n PosGetOrderDetailContent,\n PosGetOrderDetailPathParams,\n PosListOrderActivityContent,\n PosListOrderActivityPathParams,\n PosGetOrderInvoiceContent,\n PosGetOrderInvoiceQuery,\n PosGetOrderInvoicePathParams,\n PosGetOrderReceiptContent,\n PosGetOrderReceiptQuery,\n PosGetOrderReceiptPathParams,\n PosListOrderShipmentsContent,\n PosListOrderShipmentsPathParams,\n\n // Admin Shipment types\n PosListShipmentsContent,\n PosListShipmentsQuery,\n PosCheckOrderInventoryContent,\n PosCheckOrderInventoryPathParams,\n PosRefundShortfallResponse,\n PosRefundShortfallPathParams,\n PosRefundShortfallBody,\n PosGetShipmentDetailContent,\n PosGetShipmentDetailPathParams,\n PosGetShipmentInvoiceContent,\n PosGetShipmentInvoiceQuery,\n PosGetShipmentInvoicePathParams,\n PosUpdateShipmentContent,\n PosUpdateShipmentPathParams,\n PosUpdateShipmentBody,\n} from \"../types/admin-pos-api-types\";\n\n/**\n * Client for interacting with POS endpoints\n * Single client that handles all POS operations including auth, cart, orders, etc.\n */\nexport class PosClient extends PosAPIClient {\n // ===============================\n // AUTHENTICATION ENDPOINTS\n // ===============================\n\n /**\n * Login with email address\n * @param body - Login credentials containing location ID and email\n * @returns Promise with OTP token and action\n * @example\n * ```typescript\n * const { data, error } = await pos.loginWithEmail({\n * location_id: \"pos-location-123\",\n * email: \"staff@example.com\"\n * });\n *\n * if (error) {\n * console.error(\"Login failed:\", error.message);\n * } else {\n * console.log(\"OTP sent:\", data.otp_token);\n * console.log(\"Action:\", data.otp_action);\n * // Use the otp_token to verify OTP\n * }\n * ```\n */\n public async loginWithEmail(\n body: LoginPosDeviceWithEmailBody,\n headers?: LoginPosDeviceWithEmailHeaderParams\n ): Promise<ApiResult<LoginPosDeviceWithEmailContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/login/email\", {\n body: body,\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Login with phone number\n * @param body - Login credentials containing location ID and phone\n * @returns Promise with OTP token and action\n * @example\n * ```typescript\n * const { data, error } = await pos.loginWithPhone({\n * location_id: \"pos-location-123\",\n * phone: \"234567890\",\n * country_code: \"+91\" // default is +91\n * });\n *\n * if (error) {\n * console.error(\"Login failed:\", error.message);\n * } else {\n * console.log(\"OTP sent:\", data.otp_token);\n * console.log(\"Action:\", data.otp_action);\n * // Use the otp_token to verify OTP\n * }\n * ```\n */\n public async loginWithPhone(\n body: LoginPosDeviceWithPhoneBody,\n headers?: LoginPosDeviceWithPhoneHeaderParams\n ): Promise<ApiResult<LoginPosDeviceWithPhoneContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/login/phone\", {\n body,\n params: { header: mergedHeaders },\n })\n );\n }\n\n /**\n * Login with WhatsApp\n * @param body - Login credentials containing location ID and phone\n * @returns Promise with OTP token and action\n * @example\n * ```typescript\n * const { data, error } = await pos.loginWithWhatsapp({\n * location_id: \"pos-location-123\",\n * phone: \"234567890\",\n * country_code: \"+91\" // default is +91\n * });\n *\n * if (error) {\n * console.error(\"WhatsApp login failed:\", error.message);\n * } else {\n * console.log(\"WhatsApp OTP sent:\", data.otp_token);\n * console.log(\"Action:\", data.otp_action);\n * // Use the otp_token to verify OTP\n * }\n * ```\n */\n public async loginWithWhatsapp(\n body: LoginPosDeviceWithWhatsappBody,\n headers?: LoginPosDeviceWithWhatsappHeaderParams\n ): Promise<ApiResult<LoginPosDeviceWithWhatsappContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/login/whatsapp\", {\n body,\n params: { header: mergedHeaders },\n })\n );\n }\n\n /**\n * Verify OTP\n * @param body - OTP verification data\n * @returns Promise with user info and tokens\n * @example\n * ```typescript\n * const { data, error } = await pos.verifyOtp({\n * otp_token: \"otp-token-from-login\",\n * otp: \"123456\",\n * otp_action: \"login\"\n * });\n *\n * if (error) {\n * console.error(\"OTP verification failed:\", error.message);\n * } else {\n * console.log(\"Login successful:\", data.user);\n * console.log(\"Access token:\", data.access_token);\n * console.log(\"Refresh token:\", data.refresh_token);\n * // Tokens are automatically stored by the SDK\n * }\n * ```\n */\n public async verifyOtp(\n body: VerifyPosLoginOtpBody\n ): Promise<ApiResult<VerifyPosLoginOtpContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/verify-otp\", { body })\n );\n }\n\n /**\n * Refresh POS access token\n * @param body - Refresh token data\n * @returns Promise with new tokens\n * @example\n * ```typescript\n * const { data, error } = await pos.refreshAccessToken({\n * refresh_token: \"refresh-token-here\"\n * });\n *\n * if (error) {\n * console.error(\"Token refresh failed:\", error.message);\n * } else {\n * console.log(\"New access token:\", data.access_token);\n * console.log(\"New refresh token:\", data.refresh_token);\n * // New tokens are automatically stored by the SDK\n * }\n * ```\n */\n public async refreshAccessToken(\n body: RefreshPosAccessTokenBody\n ): Promise<ApiResult<RefreshPosAccessTokenContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/refresh-token\", { body })\n );\n }\n\n /**\n * Get POS user details\n * @param pathParams - User ID\n * @returns Promise with user details\n * @example\n * ```typescript\n * const { data, error } = await pos.getUser({\n * id: \"01H9USER12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get user:\", error.message);\n * } else {\n * console.log(\"User:\", data.user);\n * }\n * ```\n */\n public async getUser(\n pathParams: GetPosUserPathParams\n ): Promise<ApiResult<GetPosUserContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/users/{id}\", { params: { path: pathParams } })\n );\n }\n\n /**\n * Logout\n * @returns Promise with logout confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.logout();\n *\n * if (error) {\n * console.error(\"Logout failed:\", error.message);\n * } else {\n * console.log(\"Logout message:\", data.message);\n * console.log(\"Success:\", data.success);\n * // Tokens are automatically cleared by the SDK\n * }\n * ```\n */\n public async logout(): Promise<ApiResult<LogoutFromPosDeviceResponse>> {\n return this.executeRequest(() => this.client.POST(\"/pos/auth/logout\"));\n }\n\n // ===============================\n // DEVICE ENDPOINTS\n // ===============================\n\n /**\n * List store locations\n * @returns Promise with list of locations\n * @example\n * ```typescript\n * const { data, error } = await pos.listLocations();\n * if (error) {\n * console.error(\"Failed to list locations:\", error.message);\n * } else {\n * console.log(\"Locations:\", data.locations);\n * }\n * ```\n */\n public async listLocations(): Promise<ApiResult<ListPosLocationsContent>> {\n return this.executeRequest(() => this.client.GET(\"/pos/locations\"));\n }\n\n /**\n * List devices\n * @returns Promise with list of devices\n * @example\n * ```typescript\n * const { data, error } = await pos.listDevices();\n * if (error) {\n * console.error(\"Failed to list devices:\", error.message);\n * } else {\n * console.log(\"Devices:\", data.devices);\n * }\n * ```\n */\n public async listDevices(): Promise<ApiResult<ListPosDevicesContent>> {\n return this.executeRequest(() => this.client.GET(\"/pos/devices\"));\n }\n\n /**\n * Pair POS device with pairing code\n * @param body - Pairing code received via phone/email\n * @returns Promise with device information\n * @example\n * ```typescript\n * const { data, error } = await pos.pairDevice({\n * pairing_code: \"ABC123\"\n * });\n *\n * if (error) {\n * console.error(\"Device pairing failed:\", error.message);\n * } else {\n * console.log(\"Device paired:\", data.device.id);\n * console.log(\"Device name:\", data.device.name);\n * // Store device_id for future use\n * }\n * ```\n */\n public async pairDevice(\n body: PairPosDeviceBody\n ): Promise<ApiResult<PairPosDeviceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/pair-device\", { body })\n );\n }\n\n /**\n * Unclaim POS device - Unlinks a device from the user session\n * @param pathParams - Device ID\n * @returns Promise with unclaim confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.unclaimDevice({\n * id: \"01H9DEVICE12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to unclaim device:\", error.message);\n * } else {\n * console.log(\"Device unclaimed:\", data.message);\n * }\n * ```\n */\n public async unclaimDevice(\n pathParams: UnclaimPosDevicePathParams\n ): Promise<ApiResult<UnclaimPosDeviceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/devices/{id}/unclaim\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Claim POS device - Links a device to the user session\n * @param pathParams - Device ID\n * @returns Promise with claim confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.claimDevice({\n * id: \"01H9DEVICE12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to claim device:\", error.message);\n * } else {\n * console.log(\"Device claimed:\", data.message);\n * }\n * ```\n */\n public async claimDevice(\n pathParams: ClaimPosDevicePathParams\n ): Promise<ApiResult<ClaimPosDeviceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/devices/{id}/claim\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // CART ENDPOINTS\n // ===============================\n\n /**\n * Create a new cart\n * @param body - Cart creation data with items\n * @returns Promise with created cart\n * @example\n * ```typescript\n * const { data, error } = await pos.createCart({\n * items: [\n * {\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: null,\n * quantity: 2\n * },\n * {\n * product_id: \"01H9ABC67890FGHIJ\",\n * variant_id: \"01H9XYZ67890KLMNO\",\n * quantity: 1\n * }\n * ],\n * metadata: {\n * \"source\": \"pos-terminal-1\",\n * \"staff_id\": \"staff-123\"\n * }\n * });\n *\n * if (error) {\n * console.error(\"Failed to create cart:\", error.message);\n * } else {\n * console.log(\"Cart created:\", data.cart.id);\n * console.log(\"Cart total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async createCart(\n body: PosCreateCartBody\n ): Promise<ApiResult<PosCreateCartContent>> {\n return this.executeRequest(() => this.client.POST(\"/pos/carts\", { body }));\n }\n\n /**\n * Get cart details\n * @param pathParams - Cart ID\n * @returns Promise with cart details\n * @example\n * ```typescript\n * const { data, error } = await pos.getCart({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get cart:\", error.message);\n * } else {\n * const cart = data.cart;\n * console.log(\"Cart total:\", cart.grand_total);\n * console.log(\"Items count:\", cart.cart_items.length);\n * }\n * ```\n */\n public async getCart(\n pathParams: PosGetCartPathParams\n ): Promise<ApiResult<PosGetCartContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/{id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get cart details by user ID\n * @param pathParams - User ID\n * @returns Promise with cart details\n * @example\n * ```typescript\n * const { data, error } = await pos.getUserCart({\n * user_id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get user cart:\", error.message);\n * } else {\n * console.log(\"User cart ID:\", data.cart.id);\n * console.log(\"Cart value:\", data.cart.subtotal_amount);\n * }\n * ```\n */\n public async getUserCart(\n pathParams: PosGetUserCartPathParams\n ): Promise<ApiResult<PosGetUserCartContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/users/{user_id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Delete cart (remove all items)\n * @param pathParams - Cart ID\n * @returns Promise with deletion confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.deleteCart({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to delete cart:\", error.message);\n * } else {\n * console.log(\"Cart deleted:\", data.message);\n * }\n * ```\n */\n public async deleteCart(\n pathParams: PosDeleteCartPathParams\n ): Promise<ApiResult<PosDeleteCartResponse>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Add/update cart item (set quantity to 0 to remove)\n * @param pathParams - Cart ID\n * @param body - Item update data\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * // Add item to cart\n * const { data, error } = await pos.updateCart(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: null,\n * quantity: 3\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update cart:\", error.message);\n * } else {\n * console.log(\"Cart updated:\", data.cart.cart_items.length);\n * }\n *\n * // Remove item from cart (set quantity to 0)\n * const { data: removeData, error: removeError } = await pos.updateCart(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: null,\n * quantity: 0\n * }\n * );\n * ```\n */\n public async updateCart(\n pathParams: PosUpdateCartPathParams,\n body: PosUpdateCartBody\n ): Promise<ApiResult<PosUpdateCartContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/items\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Update cart address (billing/shipping)\n * @param pathParams - Cart ID\n * @param body - Address data (registered user IDs or guest addresses)\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * // For registered users with saved addresses\n * const { data, error } = await pos.createCartAddress(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * billing_address_id: \"01H9ADDR12345BILL\",\n * shipping_address_id: \"01H9ADDR12345SHIP\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update cart address:\", error.message);\n * } else {\n * console.log(\"Addresses updated:\", data.message);\n * }\n *\n * // For guest checkout with new addresses\n * const { data: guestData, error: guestError } = await pos.createCartAddress(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * billing_address: {\n * first_name: \"John\",\n * last_name: \"Doe\",\n * email: \"john@example.com\",\n * phone: \"9876543210\",\n * country_code: \"+91\",\n * address_line1: \"123 Main Street\",\n * address_line2: \"Apt 4B\",\n * city: \"Mumbai\",\n * state: \"Maharashtra\",\n * pincode: \"400001\",\n * country: \"India\",\n * landmark: \"Near Station\",\n * tax_identification_number: null,\n * business_name: null\n * },\n * shipping_address: {\n * first_name: \"John\",\n * last_name: \"Doe\",\n * email: \"john@example.com\",\n * phone: \"9876543210\",\n * country_code: \"+91\",\n * address_line1: \"456 Oak Avenue\",\n * address_line2: null,\n * city: \"Pune\",\n * state: \"Maharashtra\",\n * pincode: \"411001\",\n * country: \"India\",\n * landmark: \"Near Mall\",\n * tax_identification_number: null,\n * business_name: null\n * }\n * }\n * );\n * ```\n */\n public async createCartAddress(\n pathParams: PosCreateCartAddressPathParams,\n body: PosCreateCartAddressBody\n ): Promise<ApiResult<PosCreateCartAddressContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/address\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n // ===============================\n // COUPON & PROMOTION ENDPOINTS\n // ===============================\n\n /**\n * List all available coupons\n * @param headers - Optional header parameters (customer_group_id, etc.)\n * @returns Promise with available coupons\n * @example\n * ```typescript\n * // Get all available coupons\n * const { data, error } = await pos.listCoupons();\n *\n * if (error) {\n * console.error(\"Failed to get available coupons:\", error.message);\n * } else {\n * const coupons = data.coupons || [];\n * console.log(\"Available coupons:\", coupons.length);\n * coupons.forEach(coupon => {\n * console.log(\"Coupon:\", coupon.code, \"Discount:\", coupon.discount_amount);\n * });\n * }\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listCoupons({\n * \"x-customer-group-id\": \"01H9GROUP12345ABC\" // Override default SDK config\n * });\n * ```\n */\n public async listCoupons(\n headers?: PosListCouponsHeaderParams\n ): Promise<ApiResult<PosListCouponsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/available-coupons\", {\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List all available promotions\n * @param headers - Optional header parameters (customer_group_id, etc.)\n * @returns Promise with available promotions\n * @example\n * ```typescript\n * // Get all available promotions\n * const { data, error } = await pos.listPromotions();\n *\n * if (error) {\n * console.error(\"Failed to get available promotions:\", error.message);\n * } else {\n * const promotions = data.promotions || [];\n * console.log(\"Available promotions:\", promotions.length);\n * promotions.forEach(promotion => {\n * console.log(\"Promotion:\", promotion.name, \"Type:\", promotion.promotion_type);\n * });\n * }\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listPromotions({\n * \"x-customer-group-id\": \"01H9GROUP12345ABC\" // Override default SDK config\n * });\n * ```\n */\n public async listPromotions(\n headers?: PosListPromotionsHeaderParams\n ): Promise<ApiResult<PosListPromotionsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/available-promotions\", {\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Apply coupon to cart\n * @param pathParams - Cart ID\n * @param body - Coupon code\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.applyCoupon(\n * { id: \"01H9CART12345ABCDE\" },\n * { coupon_code: \"FLAT100OFF\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to apply coupon:\", error.message);\n * } else {\n * console.log(\"Coupon applied, new total:\", data.cart.grand_total);\n * console.log(\"Discount amount:\", data.cart.coupon_discount_amount);\n * }\n * ```\n */\n public async applyCoupon(\n pathParams: PosApplyCouponPathParams,\n body: PosApplyCouponBody\n ): Promise<ApiResult<PosApplyCouponContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/coupon\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Remove coupon from cart\n * @param pathParams - Cart ID\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.removeCoupon({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to remove coupon:\", error.message);\n * } else {\n * console.log(\"Coupon removed, new total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async removeCoupon(\n pathParams: PosRemoveCouponPathParams\n ): Promise<ApiResult<PosRemoveCouponContent>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}/coupon\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Evaluate applicable/inapplicable coupons for cart\n * @param pathParams - Cart ID\n * @returns Promise with coupon evaluation results\n * @example\n * ```typescript\n * const { data, error } = await pos.evaluateCoupons({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to evaluate coupons:\", error.message);\n * } else {\n * const applicable = data.applicable_coupons || [];\n * const inapplicable = data.inapplicable_coupons || [];\n *\n * console.log(\"Applicable coupons:\", applicable.length);\n * applicable.forEach(coupon => {\n * console.log(`- ${coupon.code}: Save $${coupon.estimated_discount}`);\n * });\n *\n * console.log(\"Inapplicable coupons:\", inapplicable.length);\n * inapplicable.forEach(coupon => {\n * console.log(`- ${coupon.code}: ${coupon.reason}`);\n * });\n * }\n * ```\n */\n public async evaluateCoupons(\n pathParams: PosEvaluateCouponsPathParams\n ): Promise<ApiResult<PosEvaluateCouponsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/{id}/evaluate-coupons\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Evaluate applicable/inapplicable promotions for cart\n * @param pathParams - Cart ID\n * @returns Promise with promotion evaluation results\n * @example\n * ```typescript\n * const { data, error } = await pos.evaluatePromotions({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to evaluate promotions:\", error.message);\n * } else {\n * const applicable = data.applicable_promotions || [];\n * const inapplicable = data.inapplicable_promotions || [];\n *\n * console.log(\"Applicable promotions:\", applicable.length);\n * applicable.forEach(promo => {\n * console.log(`- ${promo.name}: ${promo.savings_message}`);\n * });\n *\n * console.log(\"Inapplicable promotions:\", inapplicable.length);\n * inapplicable.forEach(promo => {\n * console.log(`- ${promo.name}: ${promo.reason}`);\n * });\n * }\n * ```\n */\n public async evaluatePromotions(\n pathParams: PosEvaluatePromotionsPathParams\n ): Promise<ApiResult<PosEvaluatePromotionsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/{id}/evaluate-promotions\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // CREDIT BALANCE ENDPOINTS\n // ===============================\n\n /**\n * Apply credit balance to cart\n * @param pathParams - Cart ID\n * @param body - Credit balance amount to use\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.redeemCreditBalance(\n * { id: \"01H9CART12345ABCDE\" },\n * { credit_balance_used: 250.00 }\n * );\n *\n * if (error) {\n * console.error(\"Failed to redeem credit balance:\", error.message);\n * } else {\n * console.log(\"Credit applied, new total:\", data.cart.grand_total);\n * console.log(\"Credit used:\", data.cart.credit_balance_used);\n * }\n * ```\n */\n public async redeemCreditBalance(\n pathParams: PosRedeemCreditBalancePathParams,\n body: PosRedeemCreditBalanceBody\n ): Promise<ApiResult<PosRedeemCreditBalanceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/credit-balance\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Remove credit balance from cart\n * @param pathParams - Cart ID\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.removeCreditBalance({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to remove credit balance:\", error.message);\n * } else {\n * console.log(\"Credit balance removed, new total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async removeCreditBalance(\n pathParams: PosRemoveCreditBalancePathParams\n ): Promise<ApiResult<PosRemoveCreditBalanceContent>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}/credit-balance\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // LOYALTY POINTS ENDPOINTS\n // ===============================\n\n /**\n * Redeem loyalty points for cart\n * @param pathParams - Cart ID\n * @param body - Loyalty points to redeem\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.redeemLoyaltyPoints(\n * { id: \"01H9CART12345ABCDE\" },\n * { loyalty_point_redeemed: 500 }\n * );\n *\n * if (error) {\n * console.error(\"Failed to redeem loyalty points:\", error.message);\n * } else {\n * console.log(\"Points redeemed, new total:\", data.cart.grand_total);\n * console.log(\"Points redeemed:\", data.cart.loyalty_points_redeemed);\n * }\n * ```\n */\n public async redeemLoyaltyPoints(\n pathParams: PosRedeemLoyaltyPointsPathParams,\n body: PosRedeemLoyaltyPointsBody\n ): Promise<ApiResult<PosRedeemLoyaltyPointsContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/loyalty-points\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Remove loyalty points from cart\n * @param pathParams - Cart ID\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.removeLoyaltyPoints({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to remove loyalty points:\", error.message);\n * } else {\n * console.log(\"Loyalty points removed, new total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async removeLoyaltyPoints(\n pathParams: PosRemoveLoyaltyPointsPathParams\n ): Promise<ApiResult<PosRemoveLoyaltyPointsContent>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}/loyalty-points\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // FULFILLMENT ENDPOINTS\n // ===============================\n\n /**\n * Update cart fulfillment preference (delivery/pickup)\n * @param pathParams - Cart ID\n * @param body - Fulfillment preference data\n * @returns Promise with confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.updateFulfillmentPreference(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * fulfillment_type: \"delivery\",\n * delivery_address_id: \"01H9ADDR12345ABCDE\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update fulfillment preference:\", error.message);\n * } else {\n * console.log(\"Fulfillment preference updated:\", data.message);\n * console.log(\"Success:\", data.success);\n * }\n * ```\n */\n public async updateFulfillmentPreference(\n pathParams: PosUpdateFulfillmentPreferencePathParams,\n body: PosUpdateFulfillmentPreferenceBody\n ): Promise<ApiResult<PosUpdateFulfillmentPreferenceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/fulfillment-preference\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Get fulfillment options for cart\n * @param body - Cart data for fulfillment calculation\n * @returns Promise with fulfillment options\n * @example\n * ```typescript\n * const { data, error } = await pos.getFulfillmentOptions({\n * cart_id: \"01H9CART12345ABCDE\",\n * delivery_address: {\n * street: \"123 Main St\",\n * city: \"New York\",\n * state: \"NY\",\n * zip_code: \"10001\",\n * country: \"US\"\n * }\n * });\n *\n * if (error) {\n * console.error(\"Failed to get fulfillment options:\", error.message);\n * } else {\n * console.log(\"Available fulfillment options:\", data.options.length);\n * data.options.forEach(option => {\n * console.log(`${option.type}: ${option.name} - $${option.cost}`);\n * });\n * }\n * ```\n */\n public async getFulfillmentOptions(\n body: GetPosFulfillmentOptionsBody\n ): Promise<ApiResult<GetPosFulfillmentOptionsContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/fulfillment-options\", { body })\n );\n }\n\n // ===============================\n // CUSTOMER ENDPOINTS\n // ===============================\n\n /**\n * Update cart customer information\n * @param pathParams - Cart ID\n * @param body - Customer update data\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.updateCartCustomer(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * customer_id: \"01H9CUST12345ABCDE\",\n * customer_group_id: \"01H9GROUP12345ABCDE\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update cart customer:\", error.message);\n * } else {\n * console.log(\"Cart customer updated:\", data.cart.id);\n * console.log(\"Customer ID:\", data.cart.customer_id);\n * console.log(\"Customer group:\", data.cart.customer_group_id);\n * }\n * ```\n */\n public async updateCartCustomer(\n pathParams: UpdatePosCartCustomerPathParams,\n body: UpdatePosCartCustomerBody\n ): Promise<ApiResult<UpdatePosCartCustomerContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/update-customer\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n // ===============================\n // ORDER ENDPOINTS\n // ===============================\n\n /**\n * Create order from cart\n * @param body - Order creation data\n * @returns Promise with created order\n * @example\n * ```typescript\n * const { data, error } = await pos.createOrder({\n * cart_id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to create order:\", error.message);\n * } else {\n * console.log(\"Order created:\", data.order.id);\n * console.log(\"Payment required:\", data.payment_required);\n * }\n * ```\n */\n public async createOrder(\n body: CreatePosOrderBody\n ): Promise<ApiResult<CreatePosOrderContent>> {\n return this.executeRequest(() =>\n // USES storefrontClient to avoid path conflicts with admin. This is only required when same path exists for both storefront and admin.\n this.storefrontClient.POST(\"/pos/orders\", { body })\n );\n }\n\n // ===============================\n // PAYMENT ENDPOINTS\n // ===============================\n\n /**\n * Get payment status\n * @param pathParams - Order number\n * @returns Promise with payment status\n * @example\n * ```typescript\n * const { data, error } = await pos.getPaymentStatus({ order_number: \"1234567890\" });\n *\n * if (error) {\n * console.error(\"Failed to get payment status:\", error.message);\n * } else {\n * console.log(\"Payment status:\", data.status);\n * console.log(\"Amount paid:\", data.amount_paid);\n * console.log(\"Amount unpaid:\", data.amount_unpaid);\n * console.log(\"Retry available:\", data.is_retry_available);\n * }\n * ```\n */\n public async getPaymentStatus(\n pathParams: PosGetPaymentStatusPathParams\n ): Promise<ApiResult<PosGetPaymentStatusContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/payment-status\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // CATALOG ENDPOINTS\n // ===============================\n\n /**\n * List all categories\n * @param query - Optional query parameters for filtering categories\n * @returns Promise with list of categories\n * @example\n * ```typescript\n * // Basic category listing\n * const { data, error } = await pos.listCategories();\n *\n * if (error) {\n * console.error(\"Failed to list categories:\", error.message);\n * } else {\n * console.log(\"Categories found:\", data.categories?.length || 0);\n * data.categories?.forEach(category => {\n * console.log(`Category: ${category.name} - ${category.description}`);\n * });\n * }\n *\n * // With pagination\n * const { data: catData, error: catError } = await pos.listCategories({\n * page: 1,\n * limit: 10\n * });\n * ```\n */\n public async listCategories(\n query?: PosListCategoriesQuery\n ): Promise<ApiResult<PosListCategoriesContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/categories\", {\n params: { query },\n })\n );\n }\n\n /**\n * List all products\n * @param query - Optional query parameters for filtering products\n * @param headers - Optional header parameters\n * @returns Promise with list of products\n * @example\n * ```typescript\n * // Basic product listing\n * const { data, error } = await pos.listProducts();\n *\n * if (error) {\n * console.error(\"Failed to list products:\", error.message);\n * } else {\n * console.log(\"Products found:\", data.products?.length || 0);\n * console.log(\"Pagination:\", data.pagination);\n * data.products?.forEach(product => {\n * console.log(`Product: ${product.name} - $${product.price}`);\n * });\n * }\n *\n * // With filtering and pagination\n * const { data: filteredData, error: filteredError } = await pos.listProducts({\n * page: 1,\n * limit: 20,\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" }),\n * category_slug: [\"electronics\", \"smartphones\"]\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listProducts(\n * {\n * page: 1,\n * limit: 20,\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" }),\n * category_slug: [\"electronics\", \"smartphones\"]\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async listProducts(\n query?: PosListProductsQuery,\n headers?: PosListProductsHeaderParams\n ): Promise<ApiResult<PosListProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List cross-sell products\n * @param query - Query parameters with product IDs for cross-sell recommendations\n * @param headers - Optional header parameters\n * @returns Promise with cross-sell products\n * @example\n * ```typescript\n * // Basic usage - get cross-sell products for cart items\n * const { data, error } = await pos.listCrosssellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\", \"prod_01H9ABC67890FGHIJ\"]\n * });\n *\n * // Advanced usage with pagination and custom sorting\n * const { data, error } = await pos.listCrosssellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 10,\n * sort_by: '{\"price\":\"asc\"}'\n * });\n *\n * // Override customer group ID for this specific request\n * const { data, error } = await pos.listCrosssellProducts(\n * {\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 10\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get cross-sell products:\", error.message);\n * } else {\n * console.log(\"Cross-sell products found:\", data.products.length);\n * console.log(\"Pagination:\", data.pagination);\n * data.products.forEach(product => {\n * console.log(`Product: ${product.name} - ${product.price}`);\n * });\n * }\n * ```\n */\n public async listCrosssellProducts(\n query: PosListCrosssellProductsQuery,\n headers?: PosListCrosssellProductsHeaderParams\n ): Promise<ApiResult<PosListCrosssellProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/cross-sell\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Search products\n * @param body - Search criteria and parameters\n * @param headers - Optional header parameters\n * @returns Promise with search results including SKUs, facet distribution, facet stats, and pagination\n * @example\n * ```typescript\n * // Basic search\n * const { data, error } = await pos.searchProducts({\n * query: \"smartphone\",\n * page: 1,\n * limit: 20\n * });\n *\n * if (error) {\n * console.error(\"Failed to search products:\", error.message);\n * } else {\n * console.log(\"Search results:\", data.skus?.length || 0, \"products found\");\n * console.log(\"Facet distribution:\", data.facet_distribution);\n * console.log(\"Facet stats:\", data.facet_stats);\n * console.log(\"Pagination:\", data.pagination);\n *\n * data.skus?.forEach(sku => {\n * console.log(`Found: ${sku.product_name} - ${sku.pricing?.selling_price}`);\n * });\n * }\n *\n * // With filter (string expression — Meilisearch syntax)\n * const { data: filtered, error: filteredError } = await pos.searchProducts({\n * query: \"laptop\",\n * filter: \"pricing.selling_price 500 TO 2000 AND product_type = physical\",\n * sort: [\"pricing.selling_price:asc\"],\n * facets: [\"product_type\", \"categories.name\", \"tags\"],\n * page: 1,\n * limit: 10\n * });\n *\n * // With filter (array of conditions — combined with AND)\n * const { data: arrayFiltered, error: arrayError } = await pos.searchProducts({\n * query: \"shoes\",\n * filter: [\"product_type = physical\", \"rating >= 4\", \"stock_available > 0\"],\n * sort: [\"rating:desc\"],\n * facets: [\"*\"],\n * page: 1,\n * limit: 25\n * });\n *\n * // With filter (nested arrays — inner arrays use OR, outer uses AND)\n * const { data: nestedFiltered, error: nestedError } = await pos.searchProducts({\n * query: \"headphones\",\n * filter: [\n * \"pricing.selling_price 50 TO 300\",\n * [\"product_type = physical\", \"product_type = bundle\"]\n * ],\n * page: 1,\n * limit: 25\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.searchProducts(\n * {\n * query: \"laptop\",\n * filter: \"categories.name = computers\",\n * page: 1,\n * limit: 20\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async searchProducts(\n body: PosSearchProductsBody,\n headers?: PosSearchProductsHeaderParams\n ): Promise<ApiResult<PosSearchProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/catalog/products/search\", {\n body,\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List similar products\n * @param query - Query parameters with product ID for similarity recommendations\n * @param headers - Optional header parameters\n * @returns Promise with similar products\n * @example\n * ```typescript\n * // Basic usage - get similar products for a specific product\n * const { data, error } = await pos.listSimilarProducts({\n * product_id: \"prod_01H9XYZ12345ABCDE\"\n * });\n *\n * // Advanced usage with pagination and custom sorting\n * const { data, error } = await pos.listSimilarProducts({\n * product_id: \"prod_01H9XYZ12345ABCDE\",\n * page: 1,\n * limit: 20,\n * sort_by: '{\"relevance\":\"desc\"}'\n * });\n *\n * // Override customer group ID for this specific request\n * const { data, error } = await pos.listSimilarProducts(\n * {\n * product_id: \"prod_01H9XYZ12345ABCDE\",\n * page: 1,\n * limit: 20\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get similar products:\", error.message);\n * } else {\n * console.log(\"Similar products found:\", data.products.length);\n * console.log(\"Pagination:\", data.pagination);\n * data.products.forEach(product => {\n * console.log(`Similar: ${product.name} - ${product.price}`);\n * });\n * }\n * ```\n */\n public async listSimilarProducts(\n query: PosListSimilarProductsQuery,\n headers?: PosListSimilarProductsHeaderParams\n ): Promise<ApiResult<PosListSimilarProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/similar\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List up-sell products\n * @param query - Query parameters with product IDs for up-sell recommendations\n * @param headers - Optional header parameters\n * @returns Promise with up-sell products\n * @example\n * ```typescript\n * // Basic usage - get up-sell products for cart items\n * const { data, error } = await pos.listUpsellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"]\n * });\n *\n * // Advanced usage with pagination and custom sorting\n * const { data, error } = await pos.listUpsellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 15,\n * sort_by: '{\"relevance\":\"desc\"}'\n * });\n *\n * // Override customer group ID for this specific request\n * const { data, error } = await pos.listUpsellProducts(\n * {\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 15\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get up-sell products:\", error.message);\n * } else {\n * console.log(\"Up-sell products found:\", data.products.length);\n * console.log(\"Pagination:\", data.pagination);\n * data.products.forEach(product => {\n * console.log(`Up-sell: ${product.name} - ${product.price}`);\n * });\n * }\n * ```\n */\n public async listUpsellProducts(\n query: PosListUpsellProductsQuery,\n headers?: PosListUpsellProductsHeaderParams\n ): Promise<ApiResult<PosListUpsellProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/up-sell\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Get product details\n * @param pathParams - The path parameters. Accepts product ID or product slug.\n * @param headers - Optional header parameters\n * @returns Promise with product details\n * @example\n * ```typescript\n * // Get product by ID\n * const { data, error } = await pos.getProductDetail(\n * { product_id: \"prod_123\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get product details:\", error.message);\n * } else {\n * console.log(\"Product:\", data.product.name);\n * console.log(\"Price:\", data.product.pricing?.selling_price);\n * console.log(\"Description:\", data.product.short_description);\n * }\n *\n * // Get product by slug (also accepted in place of product_id)\n * const { data: slugData, error: slugError } = await pos.getProductDetail({\n * product_id: \"detox-candy\"\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.getProductDetail(\n * { product_id: \"detox-candy\" },\n * undefined,\n * {\n * \"x-customer-group-id\": \"premium_customers\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async getProductDetail(\n pathParams: PosGetProductDetailPathParams,\n query?: PosGetProductDetailQuery,\n headers?: PosGetProductDetailHeaderParams\n ): Promise<ApiResult<PosGetProductDetailContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/{product_id}\", {\n params: {\n path: pathParams,\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List product reviews\n * @param pathParams - Product ID\n * @param query - Optional query parameters for filtering reviews\n * @returns Promise with product reviews\n * @example\n * ```typescript\n * const { data, error } = await pos.listProductReviews(\n * { product_id: \"prod_123\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to list product reviews:\", error.message);\n * } else {\n * console.log(\"Reviews found:\", data.reviews?.length || 0);\n * data.reviews?.forEach(review => {\n * console.log(`Review by ${review.customer_name}: ${review.rating}/5`);\n * console.log(\"Comment:\", review.comment);\n * });\n * }\n *\n * // With pagination\n * const { data: reviewData, error: reviewError } = await pos.listProductReviews(\n * { product_id: \"prod_123\" },\n * {\n * page: 1,\n * limit: 5\n * }\n * );\n * ```\n */\n public async listProductReviews(\n pathParams: PosListProductReviewsPathParams,\n query?: PosListProductReviewsQuery\n ): Promise<ApiResult<PosListProductReviewsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/{product_id}/reviews\", {\n params: {\n path: pathParams,\n query,\n },\n })\n );\n }\n\n /**\n * List product variants\n * @param pathParams - The path parameters. Accepts product ID or product slug.\n * @param headers - Optional header parameters\n * @returns Promise with product variants\n * @example\n * ```typescript\n * // By product ID\n * const { data, error } = await pos.listProductVariants(\n * { product_id: \"prod_123\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to list product variants:\", error.message);\n * } else {\n * console.log(\"Variants found:\", data.variants?.length || 0);\n * data.variants?.forEach(variant => {\n * console.log(`Variant: ${variant.name} - SKU: ${variant.sku} - Price: ${variant.pricing?.selling_price}`);\n * });\n * }\n *\n * // By product slug (also accepted in place of product_id)\n * const { data: slugData, error: slugError } = await pos.listProductVariants(\n * { product_id: \"detox-candy\" }\n * );\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listProductVariants(\n * { product_id: \"prod_123\" },\n * undefined,\n * {\n * \"x-customer-group-id\": \"wholesale_customers\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async listProductVariants(\n pathParams: PosListProductVariantsPathParams,\n query?: PosListProductVariantsQuery,\n headers?: PosListProductVariantsHeaderParams\n ): Promise<ApiResult<PosListProductVariantsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/{product_id}/variants\", {\n params: {\n path: pathParams,\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Get variant details\n * @param pathParams - The path parameters. Accepts product ID or slug for product_id, and variant ID or slug for variant_id.\n * @param headers - Optional header parameters\n * @returns Promise with variant details\n * @example\n * ```typescript\n * // By product ID and variant ID\n * const { data, error } = await pos.getVariantDetail(\n * {\n * product_id: \"prod_123\",\n * variant_id: \"var_456\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get variant details:\", error.message);\n * } else {\n * console.log(\"Variant:\", data.variant.name);\n * console.log(\"SKU:\", data.variant.sku);\n * console.log(\"Price:\", data.variant.pricing?.selling_price);\n * console.log(\"Stock available:\", data.variant.stock_available);\n * }\n *\n * // By product slug and variant slug (also accepted in place of IDs)\n * const { data: slugData, error: slugError } = await pos.getVariantDetail(\n * {\n * product_id: \"detox-candy\",\n * variant_id: \"detox-candy-100g\"\n * }\n * );\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.getVariantDetail(\n * {\n * product_id: \"prod_123\",\n * variant_id: \"var_456\"\n * },\n * undefined,\n * {\n * \"x-customer-group-id\": \"wholesale_customers\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async getVariantDetail(\n pathParams: PosGetVariantDetailPathParams,\n query?: PosGetVariantDetailQuery,\n headers?: PosGetVariantDetailHeaderParams\n ): Promise<ApiResult<PosGetVariantDetailContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\n \"/pos/catalog/products/{product_id}/variants/{variant_id}\",\n {\n params: {\n path: pathParams,\n query,\n header: mergedHeaders,\n },\n }\n )\n );\n }\n\n /**\n * List all SKUs\n * @param query - Optional query parameters for filtering SKUs\n * @param headers - Optional header parameters\n * @returns Promise with list of SKUs\n * @example\n * ```typescript\n * // Basic SKU listing\n * const { data, error } = await pos.listSkus();\n *\n * if (error) {\n * console.error(\"Failed to list SKUs:\", error.message);\n * } else {\n * console.log(\"SKUs found:\", data.skus?.length || 0);\n * console.log(\"Pagination:\", data.pagination);\n * data.skus?.forEach(sku => {\n * console.log(`SKU: ${sku.sku} - Price: ${sku.price}`);\n * });\n * }\n *\n * // With pagination\n * const { data: skuData, error: skuError } = await pos.listSkus({\n * page: 1,\n * limit: 50\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listSkus(\n * {\n * page: 1,\n * limit: 50\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async listSkus(\n query?: PosListSkusQuery,\n headers?: PosListSkusHeaderParams\n ): Promise<ApiResult<PosListSkusContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/skus\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n // ===============================\n // ADMIN ENDPOINTS\n // ===============================\n\n // ADMIN INVENTORY ENDPOINTS\n\n /**\n * List all inventories (Admin)\n * @param query - Optional query parameters for filtering inventories\n * @returns Promise with list of inventories\n * @example\n * ```typescript\n * // Basic inventory listing\n * const { data, error } = await pos.listInventories();\n *\n * if (error) {\n * console.error(\"Failed to list inventories:\", error.message);\n * } else {\n * console.log(\"Inventories found:\", data.content?.inventories?.length || 0);\n * data.content?.inventories?.forEach(inventory => {\n * console.log(`Product: ${inventory.product_name} - Stock: ${inventory.stock_quantity}`);\n * });\n * }\n *\n * // With pagination and filters\n * const { data: filteredData, error: filteredError } = await pos.listInventories({\n * page: 1,\n * limit: 20,\n * sort_by: JSON.stringify({ \"stock_quantity\": \"desc\" }),\n * filters: JSON.stringify({ \"product_name\": \"smartphone\" })\n * });\n * ```\n */\n public async listInventories(\n query?: PosListInventoryQuery\n ): Promise<ApiResult<PosListInventoryContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/inventories\", {\n params: { query },\n })\n );\n }\n\n /**\n * List all inventory activities (Admin)\n * @param query - Optional query parameters for filtering inventory activities\n * @returns Promise with list of inventory activities\n * @example\n * ```typescript\n * // Basic inventory activities listing\n * const { data, error } = await pos.listInventoryActivities();\n *\n * if (error) {\n * console.error(\"Failed to list inventory activities:\", error.message);\n * } else {\n * console.log(\"Activities found:\", data.content?.activities?.length || 0);\n * data.content?.activities?.forEach(activity => {\n * console.log(`Activity: ${activity.activity_type} - Product: ${activity.product_name} - Quantity: ${activity.quantity}`);\n * });\n * }\n *\n * // With pagination and filters\n * const { data: filteredData, error: filteredError } = await pos.listInventoryActivities({\n * page: 1,\n * limit: 50,\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" }),\n * filters: JSON.stringify({ \"activity_type\": \"add\" })\n * });\n * ```\n */\n public async listInventoryActivities(\n query?: PosListInventoryActivityQuery\n ): Promise<ApiResult<PosListInventoryActivityContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/inventories/activites\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get inventory detail (Admin)\n * @param query - Query parameters with product/variant information\n * @returns Promise with inventory details\n * @example\n * ```typescript\n * // Get inventory detail for a product\n * const { data, error } = await pos.getInventoryDetail({\n * product_id: \"01H9XYZ12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get inventory detail:\", error.message);\n * } else {\n * const inventory = data.content?.inventory;\n * console.log(`Product: ${inventory?.product_name}`);\n * console.log(`Stock: ${inventory?.stock_quantity}`);\n * console.log(`Warehouse details:`, inventory?.details);\n * }\n *\n * // Get inventory detail for a product variant\n * const { data: variantData, error: variantError } = await pos.getInventoryDetail({\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: \"01H9ABC67890FGHIJ\"\n * });\n *\n * // Get inventory detail for a specific lot/batch\n * const { data: batchData, error: batchError } = await pos.getInventoryDetail({\n * product_id: \"01H9XYZ12345ABCDE\",\n * lot_batch: \"BATCH001\"\n * });\n * ```\n */\n public async getInventoryDetail(\n query: PosListInventoryDetailQuery\n ): Promise<ApiResult<PosListInventoryDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/inventories/detail\", {\n params: { query },\n })\n );\n }\n\n // ADMIN CUSTOMER ENDPOINTS\n\n /**\n * List all customers (Admin)\n * @param query - Optional query parameters for filtering customers\n * @returns Promise with list of customers\n * @example\n * ```typescript\n * // Basic customer listing\n * const { data, error } = await pos.getCustomers();\n *\n * if (error) {\n * console.error(\"Failed to list customers:\", error.message);\n * } else {\n * console.log(\"Customers found:\", data.content?.customers?.length || 0);\n * console.log(\"Pagination:\", data.content?.pagination);\n * data.content?.customers?.forEach(customer => {\n * console.log(`Customer: ${customer.full_name} - Email: ${customer.email}`);\n * });\n * }\n *\n * // With search and pagination\n * const { data: searchData, error: searchError } = await pos.getCustomers({\n * page: 1,\n * limit: 20,\n * search: \"john@example.com\",\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" })\n * });\n * ```\n */\n public async getCustomers(\n query?: PosListCustomersQuery\n ): Promise<ApiResult<PosListCustomersContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/customers\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get customer details (Admin)\n * @param pathParams - Customer ID\n * @returns Promise with customer details\n * @example\n * ```typescript\n * const { data, error } = await pos.getCustomer({\n * id: \"01H9CUST12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get customer:\", error.message);\n * } else {\n * const customer = data.content?.customer;\n * console.log(`Customer: ${customer?.full_name}`);\n * console.log(`Email: ${customer?.email}`);\n * console.log(`Phone: ${customer?.phone}`);\n * console.log(`Loyalty points: ${customer?.loyalty?.points_balance}`);\n * console.log(`Total spent: ${customer?.loyalty?.lifetime_spent}`);\n * }\n * ```\n */\n public async getCustomer(\n pathParams: PosGetCustomerDetailPathParams\n ): Promise<ApiResult<PosGetCustomerDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/customers/{id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ADMIN ORDER ENDPOINTS\n\n /**\n * List all orders (Admin)\n * @param query - Optional query parameters for filtering orders\n * @returns Promise with list of orders\n * @example\n * ```typescript\n * // Basic order listing\n * const { data, error } = await pos.listOrders();\n *\n * if (error) {\n * console.error(\"Failed to list orders:\", error.message);\n * } else {\n * console.log(\"Orders found:\", data.content?.orders?.length || 0);\n * console.log(\"Pagination:\", data.content?.pagination);\n * data.content?.orders?.forEach(order => {\n * console.log(`Order: ${order.order_number} - Status: ${order.status} - Total: ${order.grand_total}`);\n * });\n * }\n *\n * // With filters and pagination\n * const { data: filteredData, error: filteredError } = await pos.listOrders({\n * page: 1,\n * limit: 50,\n * search: \"ORD-2024\",\n * filters: JSON.stringify({ \"status\": \"delivered\", \"payment_status\": \"success\" }),\n * sort_by: JSON.stringify({ \"order_date\": \"desc\" })\n * });\n * ```\n */\n public async listOrders(\n query?: PosListOrdersQuery\n ): Promise<ApiResult<PosListOrdersContent>> {\n return this.executeRequest(() =>\n // USES adminClient to avoid path conflicts with storefront. This is only required when same path exists for both storefront and admin.\n this.adminClient.GET(\"/pos/orders\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get order details (Admin)\n * @param pathParams - Order number\n * @returns Promise with order details\n * @example\n * ```typescript\n * const { data, error } = await pos.getOrderDetail({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get order:\", error.message);\n * } else {\n * const order = data.content?.order;\n * console.log(`Order: ${order?.order_number}`);\n * console.log(`Status: ${order?.status}`);\n * console.log(`Payment Status: ${order?.payment_status}`);\n * console.log(`Total: ${order?.grand_total}`);\n * console.log(`Items:`, order?.order_items);\n * console.log(`Billing Address:`, order?.billing_address);\n * console.log(`Payments:`, order?.payments);\n * }\n * ```\n */\n public async getOrderDetail(\n pathParams: PosGetOrderDetailPathParams\n ): Promise<ApiResult<PosGetOrderDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * List order activity (Admin)\n * @param pathParams - Order number\n * @returns Promise with order activities\n * @example\n * ```typescript\n * const { data, error } = await pos.listOrderActivity({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get order activity:\", error.message);\n * } else {\n * console.log(\"Activities found:\", data.content?.activity?.length || 0);\n * data.content?.activity?.forEach(activity => {\n * console.log(`${activity.created_at}: ${activity.activity_type} - ${activity.comment}`);\n * console.log(`By: ${activity.user_name} (${activity.user_type})`);\n * });\n * }\n * ```\n */\n public async listOrderActivity(\n pathParams: PosListOrderActivityPathParams\n ): Promise<ApiResult<PosListOrderActivityContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/activity\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get order invoice (Admin)\n * @param pathParams - Order number\n * @param query - Optional format parameter\n * @returns Promise with order invoice\n * @example\n * ```typescript\n * // Get invoice as JSON\n * const { data, error } = await pos.getOrderInvoice(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"json\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get order invoice:\", error.message);\n * } else {\n * data.content?.invoices?.forEach(invoice => {\n * console.log(`Invoice: ${invoice.invoice_number}`);\n * console.log(`Date: ${invoice.invoice_date}`);\n * console.log(`Total: ${invoice.grand_total}`);\n * console.log(`Items:`, invoice.items);\n * });\n * }\n *\n * // Get invoice as PDF\n * const { data: pdfData, error: pdfError } = await pos.getOrderInvoice(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"pdf\" }\n * );\n * ```\n */\n public async getOrderInvoice(\n pathParams: PosGetOrderInvoicePathParams,\n query?: PosGetOrderInvoiceQuery\n ): Promise<ApiResult<PosGetOrderInvoiceContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/invoice\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n /**\n * Get order receipt (Admin)\n * @param pathParams - Order number\n * @param query - Optional format parameter\n * @returns Promise with order receipt\n * @example\n * ```typescript\n * // Get receipt as JSON\n * const { data, error } = await pos.getOrderReceipt(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"json\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get order receipt:\", error.message);\n * } else {\n * const receipt = data.content?.order_receipt;\n * console.log(`Order: ${receipt?.order_number}`);\n * console.log(`Date: ${receipt?.order_date}`);\n * console.log(`Total: ${receipt?.grand_total}`);\n * console.log(`Items:`, receipt?.order_items);\n * console.log(`Payments:`, receipt?.payments);\n * }\n *\n * // Get receipt as PDF\n * const { data: pdfData, error: pdfError } = await pos.getOrderReceipt(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"pdf\" }\n * );\n * ```\n */\n public async getOrderReceipt(\n pathParams: PosGetOrderReceiptPathParams,\n query?: PosGetOrderReceiptQuery\n ): Promise<ApiResult<PosGetOrderReceiptContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/receipt\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n /**\n * Get order shipments (Admin)\n * @param pathParams - Order number\n * @returns Promise with order shipments\n * @example\n * ```typescript\n * const { data, error } = await pos.getOrderShipments({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get order shipments:\", error.message);\n * } else {\n * const shipment = data.content?.shipment;\n * console.log(`Order: ${shipment?.order_number}`);\n * console.log(`Order Status: ${shipment?.order_status}`);\n * console.log(`Payment Status: ${shipment?.payment_status}`);\n * console.log(`Customer: ${shipment?.customer_name}`);\n * console.log(`Shipments:`, shipment?.shipments);\n * console.log(`Allowed Actions:`, shipment?.allowed_actions);\n * }\n * ```\n */\n public async getOrderShipments(\n pathParams: PosListOrderShipmentsPathParams\n ): Promise<ApiResult<PosListOrderShipmentsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/shipments\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ADMIN SHIPMENT ENDPOINTS\n\n /**\n * List all shipments (Admin)\n * @param query - Optional query parameters for filtering shipments\n * @returns Promise with list of shipments\n * @example\n * ```typescript\n * // Basic shipment listing\n * const { data, error } = await pos.listShipments();\n *\n * if (error) {\n * console.error(\"Failed to list shipments:\", error.message);\n * } else {\n * console.log(\"Shipments found:\", data.content?.shipments?.length || 0);\n * console.log(\"Pagination:\", data.content?.pagination);\n * data.content?.shipments?.forEach(shipment => {\n * console.log(`Shipment: ${shipment.shipment_number} - Status: ${shipment.status}`);\n * console.log(`Order: ${shipment.order_number} - AWB: ${shipment.awb_no}`);\n * });\n * }\n *\n * // With filters and search\n * const { data: filteredData, error: filteredError } = await pos.listShipments({\n * page: 1,\n * limit: 25,\n * search: \"SHIP-2024\",\n * filters: JSON.stringify({ \"status\": \"shipped\" }),\n * sort_by: JSON.stringify({ \"shipped_date\": \"desc\" })\n * });\n * ```\n */\n public async listShipments(\n query?: PosListShipmentsQuery\n ): Promise<ApiResult<PosListShipmentsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments\", {\n params: { query },\n })\n );\n }\n\n /**\n * Check inventory for order (Admin)\n * @param pathParams - Order number\n * @returns Promise with inventory check results\n * @example\n * ```typescript\n * const { data, error } = await pos.checkInventory({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to check inventory:\", error.message);\n * } else {\n * const inventory = data.content;\n * console.log(`Inventory Status: ${inventory?.inventory_status}`);\n * console.log(`Shipment Items:`, inventory?.shipment_items);\n * console.log(`Recommended Warehouses:`, inventory?.recommended_warehouses);\n * console.log(`Inventory Detail:`, inventory?.inventory_detail);\n * console.log(`Allowed Actions:`, inventory?.allowed_action);\n * }\n * ```\n */\n public async checkInventory(\n pathParams: PosCheckOrderInventoryPathParams\n ): Promise<ApiResult<PosCheckOrderInventoryContent>> {\n return this.executeRequest(() =>\n this.adminClient.GET(\n \"/pos/orders/{order_number}/check-inventory\",\n {\n params: { path: pathParams },\n }\n )\n );\n }\n\n /**\n * Refund shortfall for order (Admin)\n * @param pathParams - Order number\n * @param body - Refund details\n * @returns Promise with refund confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.refundShortfall(\n * { order_number: \"ORD-2024-001234\" },\n * {\n * items: [\n * {\n * sku: \"SKU-123\",\n * quantity: 2,\n * free_quantity: 0\n * }\n * ],\n * payment_method: \"original-payment-mode\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to process refund:\", error.message);\n * } else {\n * console.log(\"Refund processed:\", data.message);\n * console.log(\"Success:\", data.success);\n * }\n *\n * // Refund to bank transfer\n * const { data: bankData, error: bankError } = await pos.refundShortfall(\n * { order_number: \"ORD-2024-001234\" },\n * {\n * items: [{ sku: \"SKU-123\", quantity: 1 }],\n * payment_method: \"bank-transfer\",\n * bank_account_id: \"BANK_ACC_123\"\n * }\n * );\n * ```\n */\n public async refundShortfall(\n pathParams: PosRefundShortfallPathParams,\n body: PosRefundShortfallBody\n ): Promise<ApiResult<PosRefundShortfallResponse>> {\n return this.executeRequest(() =>\n this.client.POST(\n \"/pos/shipping/shipments/{order_number}/refund-shortfall\",\n {\n params: { path: pathParams },\n body,\n }\n )\n );\n }\n\n /**\n * Get shipment details (Admin)\n * @param pathParams - Shipment reference number\n * @returns Promise with shipment details\n * @example\n * ```typescript\n * const { data, error } = await pos.getShipment({\n * reference_number: \"SHIP-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get shipment:\", error.message);\n * } else {\n * const shipment = data.content?.shipment;\n * console.log(`Order: ${shipment?.order_number}`);\n * console.log(`Shipments:`, shipment?.shipments);\n * shipment?.shipments?.forEach(s => {\n * console.log(` Shipment: ${s.shipment_number} - Status: ${s.status}`);\n * console.log(` AWB: ${s.awb_no} - Courier: ${s.courier_company_name}`);\n * console.log(` Items:`, s.shipment_items);\n * });\n * }\n * ```\n */\n public async getShipment(\n pathParams: PosGetShipmentDetailPathParams\n ): Promise<ApiResult<PosGetShipmentDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments/{reference_number}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get shipment invoice (Admin)\n * @param pathParams - Shipment reference number\n * @param query - Optional format parameter\n * @returns Promise with shipment invoice\n * @example\n * ```typescript\n * // Get shipment invoice as JSON\n * const { data, error } = await pos.getShipmentInvoice(\n * { reference_number: \"SHIP-2024-001234\" },\n * { format: \"json\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get shipment invoice:\", error.message);\n * } else {\n * const invoice = data.content?.invoice;\n * console.log(`Invoice: ${invoice?.invoice_number}`);\n * console.log(`Date: ${invoice?.invoice_date}`);\n * console.log(`Total: ${invoice?.grand_total}`);\n * console.log(`Items:`, invoice?.items);\n * }\n *\n * // Get shipment invoice as PDF\n * const { data: pdfData, error: pdfError } = await pos.getShipmentInvoice(\n * { reference_number: \"SHIP-2024-001234\" },\n * { format: \"pdf\" }\n * );\n * ```\n */\n public async getShipmentInvoice(\n pathParams: PosGetShipmentInvoicePathParams,\n query?: PosGetShipmentInvoiceQuery\n ): Promise<ApiResult<PosGetShipmentInvoiceContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments/{reference_number}/invoice\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n /**\n * Update shipment details (Admin)\n * @param pathParams - Shipment reference number\n * @param body - Shipment update data\n * @returns Promise with updated shipment\n * @example\n * ```typescript\n * const { data, error } = await pos.updateShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * status: \"shipped\",\n * awb_no: \"AWB123456789\",\n * courier_company_name: \"BlueDart\",\n * shipping_label_url: \"https://example.com/label.pdf\",\n * tracking_url: \"https://tracking.example.com/AWB123456789\",\n * eta_delivery: \"2024-01-15T10:00:00Z\",\n * shipped_date: \"2024-01-10T14:30:00Z\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update shipment:\", error.message);\n * } else {\n * console.log(\"Shipment updated successfully:\", data.message);\n * const shipment = data.content?.shipment;\n * console.log(`Updated shipment status:`, shipment?.shipments?.[0]?.status);\n * }\n *\n * // Update delivery status\n * const { data: deliveryData, error: deliveryError } = await pos.updateShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * status: \"delivered\",\n * delivered_date: \"2024-01-15T16:45:00Z\"\n * }\n * );\n * ```\n */\n public async updateShipment(\n pathParams: PosUpdateShipmentPathParams,\n body: PosUpdateShipmentBody\n ): Promise<ApiResult<PosUpdateShipmentContent>> {\n return this.executeRequest(() =>\n this.client.PUT(\n \"/pos/shipping/shipments/{reference_number}/manual-update\",\n {\n params: { path: pathParams },\n body,\n }\n )\n );\n }\n}\n","import { PosAPIClient } from \"./lib/client\";\nimport { type BaseSDKOptions } from \"@commercengine/sdk-core\";\nimport { Environment } from \"./lib/utils/url\";\nimport { PosClient } from \"./lib/pos\";\nimport {\n type TokenStorage,\n MemoryTokenStorage,\n BrowserTokenStorage,\n} from \"./lib/middleware/auth\";\nimport {\n extractUserInfoFromToken,\n getUserIdFromToken,\n isUserLoggedIn,\n isUserAuthenticated,\n getLocationIdFromToken,\n getRoleFromToken,\n getTenantIdFromToken,\n type UserInfo,\n} from \"./lib/utils/jwt\";\nimport { ResponseUtils } from \"@commercengine/sdk-core\";\n\n/**\n * Supported default headers for POS API\n */\nexport interface SupportedDefaultHeaders {\n /**\n * Customer group ID used for pricing and promotions\n */\n customer_group_id?: string;\n /**\n * Debug mode header\n */\n debug_mode?: boolean;\n}\n\n/**\n * SDK initialization options for the POS API\n */\nexport interface PosSDKOptions extends BaseSDKOptions<SupportedDefaultHeaders> {\n /**\n * Store ID for the API requests\n */\n storeId: string;\n\n /**\n * Environment to use (defaults to Production)\n * Overrides baseUrl if provided\n */\n environment?: Environment;\n\n /**\n * Custom base URL (overrides environment if provided)\n * If not provided, will be built from storeId and environment\n */\n baseUrl?: string;\n\n /**\n * X-Api-Key for authentication endpoints that require API key\n * Required for login, pair-device, and verify-otp endpoints\n * Always required even when initializing with tokens (for refresh fallbacks)\n */\n apiKey: string;\n\n /**\n * Optional initial access token\n * - If tokenStorage is provided: Used as initial token value, then managed automatically\n * - If tokenStorage is not provided: Used for manual token management\n */\n accessToken?: string;\n\n /**\n * Optional initial refresh token\n * - Only used when tokenStorage is provided\n * - Allows initialization with both access and refresh tokens\n */\n refreshToken?: string;\n\n /**\n * Optional token storage for automatic token management\n * If provided, enables automatic token refresh and management\n */\n tokenStorage?: TokenStorage;\n\n /**\n * Callback when tokens are updated (login/refresh)\n */\n onTokensUpdated?: (accessToken: string, refreshToken: string) => void;\n\n /**\n * Callback when tokens are cleared (logout/error)\n */\n onTokensCleared?: () => void;\n}\n\n/**\n * Main SDK class for the POS API\n * Provides access to all POS endpoints through a single client\n */\nexport class PosSDK {\n /**\n * Client for all POS operations (auth, cart, orders, etc.)\n */\n public readonly pos: PosClient;\n\n /**\n * Create a new PosSDK instance\n *\n * @param options - Configuration options for the SDK\n */\n constructor(options: PosSDKOptions) {\n // Convert options to internal config format\n const config: PosSDKOptions = {\n storeId: options.storeId,\n environment: options.environment,\n baseUrl: options.baseUrl,\n accessToken: options.accessToken,\n refreshToken: options.refreshToken,\n apiKey: options.apiKey,\n timeout: options.timeout,\n tokenStorage: options.tokenStorage,\n onTokensUpdated: options.onTokensUpdated,\n onTokensCleared: options.onTokensCleared,\n defaultHeaders: options.defaultHeaders,\n debug: options.debug,\n logger: options.logger,\n };\n\n this.pos = new PosClient(config);\n }\n\n /**\n * Set authentication tokens for the client\n *\n * @param accessToken - The access token (required)\n * @param refreshToken - The refresh token (optional)\n *\n * Behavior:\n * - If tokenStorage is provided: Stores tokens for automatic management\n * - If tokenStorage is not provided: Only stores access token for manual management\n */\n public async setTokens(\n accessToken: string,\n refreshToken?: string\n ): Promise<void> {\n await this.pos.setTokens(accessToken, refreshToken);\n }\n\n /**\n * Clear all authentication tokens from the client\n *\n * Behavior:\n * - If tokenStorage is provided: Clears both access and refresh tokens from storage\n * - If tokenStorage is not provided: Clears the manual access token\n */\n public async clearTokens(): Promise<void> {\n await this.pos.clearTokens();\n }\n\n /**\n * Set the API key for the client\n *\n * @param apiKey - The API key to set\n */\n public setApiKey(apiKey: string): void {\n this.pos.setApiKey(apiKey);\n }\n\n /**\n * Get the current access token if available\n */\n public async getAccessToken(): Promise<string | null> {\n const header = await this.pos.getAuthorizationHeader();\n return header.startsWith(\"Bearer \") ? header.substring(7) : null;\n }\n\n /**\n * Set default headers for the client\n *\n * @param headers - Default headers to set\n */\n public setDefaultHeaders(headers: SupportedDefaultHeaders): void {\n this.pos.setDefaultHeaders(headers);\n }\n\n /**\n * Get current default headers\n */\n public getDefaultHeaders(): SupportedDefaultHeaders | undefined {\n return this.pos.getDefaultHeaders();\n }\n\n /**\n * Get user information from the current access token\n *\n * @returns User information extracted from JWT token, or null if no token or invalid token\n */\n public async getUserInfo(): Promise<UserInfo | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return extractUserInfoFromToken(token);\n }\n\n /**\n * Get the current user ID from the access token\n *\n * @returns User ID (ulid) or null if no token or invalid token\n */\n public async getUserId(): Promise<string | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getUserIdFromToken(token);\n }\n\n /**\n * Check if the current user is logged in\n *\n * @returns True if user is logged in, false otherwise\n */\n public async isLoggedIn(): Promise<boolean> {\n const token = await this.getAccessToken();\n if (!token) return false;\n return isUserLoggedIn(token);\n }\n\n /**\n * Check if the current user is authenticated with POS access\n * This verifies the user has valid device and role information\n *\n * @returns True if user is authenticated for POS operations\n */\n public async isAuthenticated(): Promise<boolean> {\n const token = await this.getAccessToken();\n if (!token) return false;\n return isUserAuthenticated(token);\n }\n\n /**\n * Get the location ID from the current access token\n * This is commonly needed for POS API requests\n *\n * @returns Location ID or null if no token or invalid token\n */\n public async getLocationId(): Promise<string | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getLocationIdFromToken(token);\n }\n\n /**\n * Get the role information from the current access token\n *\n * @returns Role object with roleId, roleName, locationId, and locationName, or null if no token or invalid token\n */\n public async getRole(): Promise<{\n roleId: string;\n roleName: string;\n locationId: string;\n locationName: string;\n } | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getRoleFromToken(token);\n }\n\n /**\n * Get the tenant ID from the current access token\n *\n * @returns Tenant ID or null if no token or invalid token\n */\n public async getTenantId(): Promise<string | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getTenantIdFromToken(token);\n }\n}\n\n// Export the main SDK class as default\nexport default PosSDK;\n\n// Export individual clients for advanced usage\nexport { PosAPIClient, PosClient, ResponseUtils };\n\n// Export environment enum\nexport { Environment } from \"./lib/utils/url\";\n\n// Export token storage types\nexport type { TokenStorage };\nexport { MemoryTokenStorage, BrowserTokenStorage };\n\n// Export ALL types from sdk-core\nexport type * from \"@commercengine/sdk-core\";\n\n// Export POS-specific JWT types\nexport type { UserInfo } from \"./lib/utils/jwt\";\n\n// Export API types for consumer usage\nexport type { components, operations, paths } from \"./types/pos\";\nexport type * from \"./types/pos-api-types\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["#sessionKey","#legacyAccessKey","#legacyRefreshKey","#legacyRevisionKey","#storage","#locks","#createRevision","#listeners","#onStorage","#leaseHeld","#ownedRevision","#pendingAccess","#notify","#leaseReady","#leaseWaitMs","#acquireContextLease","#refreshHandler","#releaseLease","#beginSessionOwner","#lastReadRefreshToken","#readSessionOrMigrate","#writeSession","#ownsSharedRevision","#readRequestOwner","#requireLease","#assertRequestRevision","#readPairOrThrow","#refreshOwnedPair","#readSessionOrThrow","#pairReplaced","#refreshInFlight","#runSdkRefresh","#clearOwnedPair","#assertRequestOwner","#commitPair","#storageOrThrow"],"sources":["../../sdk-core/dist/index.mjs","../src/lib/auth-token-storage.ts","../src/lib/utils/jwt.ts","../src/lib/utils/auth.ts","../src/lib/middleware/auth.ts","../src/lib/utils/url.ts","../src/lib/client.ts","../src/lib/pos.ts","../src/index.ts"],"sourcesContent":["import createClient from \"openapi-fetch\";\n\n//#region src/middleware/debug.ts\n/**\n* Response utilities for debugging and working with Response objects\n*/\nvar ResponseUtils = class {\n\t/**\n\t* Get response headers as a plain object\n\t*/\n\tstatic getHeaders(response) {\n\t\treturn Object.fromEntries(response.headers.entries());\n\t}\n\t/**\n\t* Get specific header value\n\t*/\n\tstatic getHeader(response, name) {\n\t\treturn response.headers.get(name);\n\t}\n\t/**\n\t* Check if response was successful\n\t*/\n\tstatic isSuccess(response) {\n\t\treturn response.ok;\n\t}\n\t/**\n\t* Get response metadata\n\t*/\n\tstatic getMetadata(response) {\n\t\treturn {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\tok: response.ok,\n\t\t\turl: response.url,\n\t\t\tredirected: response.redirected,\n\t\t\ttype: response.type,\n\t\t\theaders: Object.fromEntries(response.headers.entries())\n\t\t};\n\t}\n\t/**\n\t* Clone and read response as text (useful for debugging)\n\t* Note: This can only be called once per response\n\t*/\n\tstatic async getText(response) {\n\t\treturn await response.clone().text();\n\t}\n\t/**\n\t* Clone and read response as JSON (useful for debugging)\n\t* Note: This can only be called once per response\n\t*/\n\tstatic async getJSON(response) {\n\t\treturn await response.clone().json();\n\t}\n\t/**\n\t* Format response information for debugging\n\t*/\n\tstatic format(response) {\n\t\tconst metadata = this.getMetadata(response);\n\t\treturn `${metadata.status} ${metadata.statusText} - ${metadata.url}`;\n\t}\n\t/**\n\t* Format response for logging purposes (enhanced version)\n\t*/\n\tstatic formatResponse(response) {\n\t\treturn {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\turl: response.url,\n\t\t\tok: response.ok\n\t\t};\n\t}\n};\n/**\n* Debug logging utilities\n*/\nvar DebugLogger = class {\n\tlogger;\n\tconstructor(logger) {\n\t\tthis.logger = logger || ((level, message, data) => {\n\t\t\tconsole.log(`[${level.toUpperCase()}]`, message);\n\t\t\tif (data) console.log(data);\n\t\t});\n\t}\n\t/**\n\t* Log debug information about API request\n\t*/\n\tlogRequest(request, requestBody) {\n\t\tthis.logger(\"info\", \"API Request Debug Info\", {\n\t\t\tmethod: request.method,\n\t\t\turl: request.url,\n\t\t\theaders: Object.fromEntries(request.headers.entries()),\n\t\t\tbody: requestBody,\n\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t});\n\t}\n\t/**\n\t* Log debug information about API response\n\t*/\n\tasync logResponse(response, responseBody) {\n\t\tthis.logger(\"info\", \"API Response Debug Info\", {\n\t\t\turl: response.url,\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\tok: response.ok,\n\t\t\theaders: Object.fromEntries(response.headers.entries()),\n\t\t\tredirected: response.redirected,\n\t\t\ttype: response.type,\n\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t});\n\t\tif (responseBody) this.logger(\"info\", \"API Response Data\", {\n\t\t\tdata: responseBody,\n\t\t\tcontentType: response.headers.get(\"content-type\"),\n\t\t\tcontentLength: response.headers.get(\"content-length\")\n\t\t});\n\t}\n\t/**\n\t* Log error information\n\t*/\n\tlogError(message, error) {\n\t\tthis.logger(\"error\", message, error);\n\t}\n\t/**\n\t* Compatibility shim retained for older internal callers.\n\t* Response bodies are no longer cached by the debug logger.\n\t*/\n\tgetCachedResponseText(_url) {\n\t\treturn null;\n\t}\n\t/**\n\t* Compatibility shim retained for older internal callers.\n\t* Response bodies are no longer cached by the debug logger.\n\t*/\n\tclearCache() {}\n\tinfo(message, data) {\n\t\tthis.logger(\"info\", message, data);\n\t}\n\twarn(message, data) {\n\t\tthis.logger(\"warn\", message, data);\n\t}\n\terror(message, data) {\n\t\tthis.logger(\"error\", message, data);\n\t}\n};\n/**\n* Extract request body for logging\n*/\nasync function extractRequestBody(request) {\n\tif (request.method === \"GET\" || request.method === \"HEAD\") return null;\n\ttry {\n\t\tconst clonedRequest = request.clone();\n\t\tconst contentType = request.headers.get(\"content-type\")?.toLowerCase();\n\t\tif (contentType?.startsWith(\"application/json\")) return await clonedRequest.json();\n\t\telse if (contentType?.startsWith(\"multipart/form-data\")) return \"[FormData - cannot display]\";\n\t\telse if (contentType?.startsWith(\"text/\")) return await clonedRequest.text();\n\t\treturn \"[Request body - unknown format]\";\n\t} catch (error) {\n\t\treturn \"[Request body unavailable]\";\n\t}\n}\n/**\n* Create debug middleware for openapi-fetch (internal use)\n* Enhanced version that combines original functionality with duration tracking\n*/\nfunction createDebugMiddleware(logger) {\n\tconst debugLogger = new DebugLogger(logger);\n\treturn {\n\t\tasync onRequest({ request }) {\n\t\t\trequest.__debugStartTime = Date.now();\n\t\t\tconst requestBody = await extractRequestBody(request);\n\t\t\tdebugLogger.logRequest(request, requestBody);\n\t\t\treturn request;\n\t\t},\n\t\tasync onResponse({ request, response }) {\n\t\t\tconst startTime = request.__debugStartTime;\n\t\t\tconst duration = startTime ? Date.now() - startTime : 0;\n\t\t\tconst cloned = response.clone();\n\t\t\tlet responseBody = null;\n\t\t\ttry {\n\t\t\t\tconst contentType = response.headers.get(\"content-type\")?.toLowerCase();\n\t\t\t\tif (contentType?.startsWith(\"application/json\")) responseBody = await cloned.json();\n\t\t\t\telse if (contentType?.startsWith(\"text/\")) responseBody = await cloned.text();\n\t\t\t} catch (error) {}\n\t\t\tawait debugLogger.logResponse(response, responseBody);\n\t\t\tif (duration > 0) debugLogger.info(`Request completed in ${duration}ms`, {\n\t\t\t\turl: request.url,\n\t\t\t\tmethod: request.method\n\t\t\t});\n\t\t\treturn response;\n\t\t},\n\t\tasync onError({ error, request }) {\n\t\t\tdebugLogger.logError(\"API Request Failed\", {\n\t\t\t\terror: {\n\t\t\t\t\tname: error instanceof Error ? error.name : \"Unknown\",\n\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : void 0\n\t\t\t\t},\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: request.method,\n\t\t\t\t\turl: request.url,\n\t\t\t\t\theaders: Object.fromEntries(request.headers.entries())\n\t\t\t\t},\n\t\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n//#endregion\n//#region src/middleware/timeout.ts\n/**\n* Timeout middleware for Commerce Engine SDKs\n*/\n/**\n* Create timeout middleware for openapi-fetch\n* Adds configurable request timeout functionality\n* \n* @param timeoutMs - Timeout duration in milliseconds\n* @returns Middleware object with onRequest handler\n*/\nfunction createTimeoutMiddleware(timeoutMs) {\n\tconst timeouts = /* @__PURE__ */ new WeakMap();\n\tconst clearRequestTimeout = (signal) => {\n\t\tconst timeoutId = timeouts.get(signal);\n\t\tif (timeoutId) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\ttimeouts.delete(signal);\n\t\t}\n\t};\n\treturn {\n\t\tonRequest: async ({ request }) => {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\tif (request.signal) request.signal.addEventListener(\"abort\", () => controller.abort(), { once: true });\n\t\t\tconst newRequest = new Request(request, { signal: controller.signal });\n\t\t\ttimeouts.set(newRequest.signal, timeoutId);\n\t\t\tcontroller.signal.addEventListener(\"abort\", () => clearRequestTimeout(newRequest.signal), { once: true });\n\t\t\treturn newRequest;\n\t\t},\n\t\tonResponse: async ({ request, response }) => {\n\t\t\tclearRequestTimeout(request.signal);\n\t\t\treturn response;\n\t\t},\n\t\tonError: async ({ request, error }) => {\n\t\t\tclearRequestTimeout(request.signal);\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n//#endregion\n//#region src/middleware/headers.ts\n/**\n* Header transformation and merging utilities for Commerce Engine SDKs\n*/\n/**\n* Merge two header objects\n* Method-level headers take precedence over default headers\n*\n* @param defaultHeaders - Default headers from SDK configuration\n* @param methodHeaders - Headers passed to the specific method call\n* @returns Merged headers object\n*/\nfunction mergeHeaders(defaultHeaders, methodHeaders) {\n\tconst merged = {};\n\tif (defaultHeaders) Object.assign(merged, defaultHeaders);\n\tif (methodHeaders) Object.assign(merged, methodHeaders);\n\tObject.keys(merged).forEach((key) => {\n\t\tif (merged[key] === void 0) delete merged[key];\n\t});\n\treturn merged;\n}\n/**\n* Transform headers using a transformation mapping\n* Headers not in the transformation map are passed through unchanged\n*\n* @param headers - Headers object with original names\n* @param transformations - Mapping of original names to transformed names\n* @returns Headers object with transformed names\n*/\nfunction transformHeaders(headers, transformations) {\n\tconst transformed = {};\n\tfor (const [key, value] of Object.entries(headers)) if (value !== void 0) {\n\t\tconst headerName = transformations[key] || key;\n\t\ttransformed[headerName] = value;\n\t}\n\treturn transformed;\n}\n/**\n* Merge headers with transformation support\n* Transforms default headers, then merges with method headers\n*\n* @param defaultHeaders - Default headers from SDK configuration\n* @param methodHeaders - Headers passed to the specific method call\n* @param transformations - Mapping for header name transformations\n* @returns Merged headers object with transformations applied\n*/\nfunction mergeAndTransformHeaders(defaultHeaders, methodHeaders, transformations) {\n\tconst merged = {};\n\tif (defaultHeaders && transformations) {\n\t\tconst transformedDefaults = transformHeaders(defaultHeaders, transformations);\n\t\tObject.assign(merged, transformedDefaults);\n\t} else if (defaultHeaders) Object.assign(merged, defaultHeaders);\n\tif (methodHeaders) Object.assign(merged, methodHeaders);\n\tObject.keys(merged).forEach((key) => {\n\t\tif (merged[key] === void 0) delete merged[key];\n\t});\n\treturn merged;\n}\n\n//#endregion\n//#region src/utils/response.ts\n/**\n* Execute a request and handle the response consistently\n* This provides unified error handling and response processing across all SDKs\n*\n* @param apiCall - Function that executes the API request\n* @returns Promise with the API response in standardized format\n*/\nasync function executeRequest(apiCall) {\n\ttry {\n\t\tconst { data, error, response } = await apiCall();\n\t\tif (error) return {\n\t\t\tdata: null,\n\t\t\terror,\n\t\t\tresponse\n\t\t};\n\t\tif (data && data.content !== void 0) return {\n\t\t\tdata: data.content,\n\t\t\terror: null,\n\t\t\tresponse\n\t\t};\n\t\treturn {\n\t\t\tdata,\n\t\t\terror: null,\n\t\t\tresponse\n\t\t};\n\t} catch (err) {\n\t\tconst mockResponse = new Response(null, {\n\t\t\tstatus: 503,\n\t\t\tstatusText: \"Service Unavailable\"\n\t\t});\n\t\treturn {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\tsuccess: false,\n\t\t\t\tcode: \"NETWORK_ERROR\",\n\t\t\t\tmessage: \"Network error occurred\",\n\t\t\t\terror: err\n\t\t\t},\n\t\t\tresponse: mockResponse\n\t\t};\n\t}\n}\n\n//#endregion\n//#region src/base-client.ts\n/**\n* Base API client for Commerce Engine SDKs\n* Provides common functionality without token management\n*/\n/**\n* Generic base API client that all Commerce Engine SDKs can extend\n* Handles common functionality like middleware setup, request execution, and header management\n* Does NOT include token management - that's SDK-specific\n* \n* @template TPaths - OpenAPI paths type\n* @template THeaders - Supported default headers type\n*/\nvar BaseAPIClient = class {\n\tclient;\n\tconfig;\n\tbaseUrl;\n\theaderTransformations;\n\t/**\n\t* Create a new BaseAPIClient\n\t*\n\t* @param config - Configuration for the API client\n\t* @param baseUrl - The base URL for the API (must be provided by subclass)\n\t* @param headerTransformations - Header name transformations for this SDK\n\t*/\n\tconstructor(config, baseUrl, headerTransformations = {}) {\n\t\tthis.config = { ...config };\n\t\tthis.headerTransformations = headerTransformations;\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.client = createClient({ baseUrl: this.baseUrl });\n\t\tthis.setupMiddleware();\n\t}\n\t/**\n\t* Set up all middleware for the client\n\t*/\n\tsetupMiddleware() {\n\t\tif (this.config.timeout) {\n\t\t\tconst timeoutMiddleware = createTimeoutMiddleware(this.config.timeout);\n\t\t\tthis.client.use(timeoutMiddleware);\n\t\t}\n\t\tif (this.config.debug) {\n\t\t\tconst debugMiddleware = createDebugMiddleware(this.config.logger);\n\t\t\tthis.client.use(debugMiddleware);\n\t\t}\n\t}\n\t/**\n\t* Get the base URL of the API\n\t*\n\t* @returns The base URL of the API\n\t*/\n\tgetBaseUrl() {\n\t\treturn this.baseUrl;\n\t}\n\t/**\n\t* Execute a request and handle the response consistently\n\t* This provides unified error handling and response processing\n\t*\n\t* @param apiCall - Function that executes the API request\n\t* @returns Promise with the API response in standardized format\n\t*/\n\tasync executeRequest(apiCall) {\n\t\treturn executeRequest(apiCall);\n\t}\n\t/**\n\t* Merge default headers with method-level headers\n\t* Method-level headers take precedence over default headers\n\t* Automatically applies SDK-specific header transformations\n\t*\n\t* @param methodHeaders - Headers passed to the specific method call\n\t* @returns Merged headers object with proper HTTP header names\n\t*/\n\tmergeHeaders(methodHeaders) {\n\t\treturn mergeAndTransformHeaders(this.config.defaultHeaders, methodHeaders, this.headerTransformations);\n\t}\n\t/**\n\t* Set default headers for the client\n\t*\n\t* @param headers - Default headers to set\n\t*/\n\tsetDefaultHeaders(headers) {\n\t\tthis.config.defaultHeaders = headers;\n\t}\n\t/**\n\t* Get current default headers\n\t*\n\t* @returns Current default headers\n\t*/\n\tgetDefaultHeaders() {\n\t\treturn this.config.defaultHeaders;\n\t}\n};\n\n//#endregion\n//#region src/utils/url.ts\n/**\n* Generic URL utility functions for any SDK\n*/\n/**\n* Extract pathname from URL\n* Useful for middleware that needs to inspect request paths\n*/\nfunction getPathnameFromUrl(url) {\n\ttry {\n\t\treturn new URL(url).pathname;\n\t} catch {\n\t\treturn url.split(\"?\")[0] || url;\n\t}\n}\n\n//#endregion\nexport { BaseAPIClient, DebugLogger, ResponseUtils, createDebugMiddleware, createTimeoutMiddleware, executeRequest, extractRequestBody, getPathnameFromUrl, mergeAndTransformHeaders, mergeHeaders, transformHeaders };","import type { AuthTokenPair, RequestOwner, TokenStorage } from \"./middleware/auth\";\n\nconst DEFAULT_PREFIX = \"ce_pos_\";\nconst AUTH_SESSION_LOCK = \"ce-pos-auth-session\";\nconst AUTH_CONTEXT_LOCK = \"ce-pos-auth-context\";\nconst SESSION_VERSION = 1;\n\nexport interface AuthStorageLike {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n removeItem: (key: string) => void;\n}\n\ninterface AuthLockManager {\n request<T>(\n name: string,\n options: { mode: \"exclusive\"; ifAvailable?: boolean; signal?: AbortSignal },\n callback: (lock?: unknown | null) => Promise<T> | T\n ): Promise<T>;\n}\n\n/**\n * A refresh the server answered, and refused — or one that could not even be\n * asked, because the refresh token itself has expired.\n *\n * Only this ends a session. Everything else a refresh can run into — no\n * network, a gateway timeout, a 5xx, a response that would not parse — says\n * nothing about whether the session is still good, so the tokens are kept\n * and the next request tries again. A refresh handler an app installs\n * (`setRefreshHandler`) says \"refused\" by throwing this, or any error with\n * the same `name` and shape: the check is by shape, not by class, so an app\n * on an older package can speak the contract.\n */\nexport class RefreshRejectedError extends Error {\n readonly status: number | null;\n readonly reason: \"rejected\" | \"expired\";\n\n constructor(detail: { status?: number; reason?: \"rejected\" | \"expired\" }) {\n const reason = detail.reason ?? \"rejected\";\n super(\n reason === \"expired\"\n ? \"No valid refresh token available\"\n : `POS token refresh rejected: ${detail.status ?? \"unknown\"}`\n );\n this.name = \"RefreshRejectedError\";\n this.status = detail.status ?? null;\n this.reason = reason;\n }\n}\n\n/**\n * A refresh that could not complete — no network, a timeout, a 5xx, a body\n * that would not parse. Wrapped so a caller can tell it from a lost lease or\n * a failed store: those are not the refresh's fault, and a request that\n * would otherwise go out on the API key alone must stay closed for them.\n * The cause keeps its message, so callers reading the message see the\n * original failure.\n */\nexport class RefreshUnavailableError extends Error {\n readonly cause: unknown;\n\n constructor(cause: unknown) {\n super(cause instanceof Error ? cause.message : \"POS token refresh could not complete\");\n this.name = \"RefreshUnavailableError\";\n this.cause = cause;\n }\n}\n\n/** Whether a thrown error came out of the refresh itself, refused or not. */\nexport function isRefreshFailure(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const name = (error as { name?: unknown }).name;\n return name === \"RefreshRejectedError\" || name === \"RefreshUnavailableError\";\n}\n\nconst DEFINITIVE_REFRESH_STATUSES = new Set([400, 401, 403]);\n\n/** Whether a refresh failure means the session is over — see `RefreshRejectedError`. */\nexport function refreshEndsSession(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const shaped = error as { name?: unknown; status?: unknown; reason?: unknown };\n if (shaped.name !== \"RefreshRejectedError\") return false;\n if (shaped.reason === \"expired\") return true;\n return typeof shaped.status === \"number\" && DEFINITIVE_REFRESH_STATUSES.has(shaped.status);\n}\n\n/**\n * How long a new page waits for the context lock before concluding that\n * another page really holds it.\n *\n * A reload is the common case: the old document's lock is released when it is\n * destroyed, and that release and the new document's request race in the\n * browser process. Asking with `ifAvailable` lost that race on a slower\n * WebView every time, and a lost race read as \"another tab owns this till\" —\n * a login screen over a session that was still on the device. Queueing for\n * the lock is granted the moment the old document lets go, which is\n * milliseconds; only a page that is genuinely still open keeps it this long.\n */\nconst DEFAULT_LEASE_WAIT_MS = 4000;\n\ninterface StoredAuthSession {\n readonly version: typeof SESSION_VERSION;\n readonly revision: string;\n readonly tokens: AuthTokenPair | null;\n}\n\nexport type AuthTokenOwner = RequestOwner;\n\nexport type TokenAdoption = \"adopted\" | \"failed\" | \"stale\";\nexport type UnauthorizedRecovery = \"refreshed\" | \"failed\" | \"stale\";\ntype ClearOutcome = \"cleared\" | \"failed\" | \"stale\";\ntype OwnershipLost = (reason: \"stale\" | \"storage\") => void;\ntype RefreshHandler = (refreshToken: string, accessToken: string) => Promise<AuthTokenPair>;\n\nconst browserStorage = (): AuthStorageLike | null => {\n try {\n return typeof localStorage === \"undefined\" ? null : localStorage;\n } catch {\n return null;\n }\n};\n\nconst browserLocks = (): AuthLockManager | null => {\n try {\n return typeof navigator === \"undefined\" ? null : (navigator.locks ?? null);\n } catch {\n return null;\n }\n};\n\nconst newRevision = (): string => {\n try {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n } catch {\n // A unique fallback is sufficient; this value is an owner nonce, not a secret.\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n};\n\nconst tokenNeedsRefresh = (token: string): boolean => {\n try {\n const payloadPart = token.split(\".\")[1];\n if (!payloadPart) return true;\n let base64 = payloadPart.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = base64.length % 4;\n if (padding) base64 += \"=\".repeat(4 - padding);\n const payload = JSON.parse(atob(base64)) as { exp?: unknown };\n return typeof payload.exp !== \"number\" || Math.floor(Date.now() / 1000) >= payload.exp - 30;\n } catch {\n return true;\n }\n};\n\nconst isNonemptyString = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0;\n\nconst normalizeStoredTokenPair = (\n value: unknown\n): { readonly pair: AuthTokenPair; readonly wasLegacy: boolean } => {\n if (!value || typeof value !== \"object\") {\n throw new Error(\"Invalid POS auth token pair.\");\n }\n const tokens = value as Record<string, unknown>;\n const hasCanonicalShape = \"access_token\" in tokens || \"refresh_token\" in tokens;\n const hasLegacyShape = \"accessToken\" in tokens || \"refreshToken\" in tokens;\n if (hasCanonicalShape === hasLegacyShape) {\n throw new Error(\"Invalid POS auth token pair.\");\n }\n const accessToken = hasCanonicalShape ? tokens.access_token : tokens.accessToken;\n const refreshToken = hasCanonicalShape ? tokens.refresh_token : tokens.refreshToken;\n if (!isNonemptyString(accessToken) || !isNonemptyString(refreshToken)) {\n throw new Error(\"Invalid POS auth token pair.\");\n }\n return {\n pair: { access_token: accessToken, refresh_token: refreshToken },\n wasLegacy: hasLegacyShape,\n };\n};\n\nconst parseSession = (\n raw: string\n): { readonly session: StoredAuthSession; readonly wasLegacy: boolean } => {\n const parsed: unknown = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\") throw new Error(\"Invalid POS auth session record.\");\n const record = parsed as Record<string, unknown>;\n if (record.version !== SESSION_VERSION || !isNonemptyString(record.revision)) {\n throw new Error(\"Unsupported POS auth session record.\");\n }\n if (record.tokens === null) {\n return {\n session: { version: SESSION_VERSION, revision: record.revision, tokens: null },\n wasLegacy: false,\n };\n }\n const normalized = normalizeStoredTokenPair(record.tokens);\n return {\n session: {\n version: SESSION_VERSION,\n revision: record.revision,\n tokens: normalized.pair,\n },\n wasLegacy: normalized.wasLegacy,\n };\n};\n\n/**\n * Browser token storage with one same-origin session owner.\n *\n * Revision and both tokens live in one versioned localStorage value. A Web\n * Storage write is atomic, so process termination can expose either the old\n * complete session or the new complete session, never a mixed token pair or an\n * old pair relabelled with a new owner revision.\n */\nexport class CoordinatedBrowserTokenStorage implements TokenStorage {\n readonly #sessionKey: string;\n readonly #legacyAccessKey: string;\n readonly #legacyRefreshKey: string;\n readonly #legacyRevisionKey: string;\n readonly #storage: () => AuthStorageLike | null;\n readonly #locks: () => AuthLockManager | null;\n readonly #createRevision: () => string;\n readonly #listeners = new Set<OwnershipLost>();\n readonly #onStorage = (event: StorageEvent): void => {\n if (!this.#leaseHeld || event.key !== this.#sessionKey) return;\n try {\n const revision =\n event.newValue === null ? null : parseSession(event.newValue).session.revision;\n if (revision === this.#ownedRevision) return;\n } catch {\n // A corrupt replacement is an ownership loss, not an absent session.\n }\n this.#pendingAccess = null;\n this.#notify(\"stale\");\n };\n\n #ownedRevision: string | null = null;\n readonly #leaseReady: Promise<boolean>;\n readonly #leaseWaitMs: number;\n #leaseHeld = false;\n #releaseLease: (() => void) | null = null;\n #lastReadRefreshToken: string | null = null;\n #refreshHandler: RefreshHandler | null = null;\n #refreshInFlight: Promise<void> | null = null;\n #pendingAccess: {\n revision: string | null;\n expectedRefreshToken: string | null;\n token: string;\n } | null = null;\n\n constructor(\n prefix = DEFAULT_PREFIX,\n options: {\n storage?: () => AuthStorageLike | null;\n locks?: () => AuthLockManager | null;\n createRevision?: () => string;\n /** See `DEFAULT_LEASE_WAIT_MS`; tests shorten it. */\n leaseWaitMs?: number;\n } = {}\n ) {\n this.#leaseWaitMs = options.leaseWaitMs ?? DEFAULT_LEASE_WAIT_MS;\n this.#sessionKey = `${prefix}auth_session`;\n this.#legacyAccessKey = `${prefix}access_token`;\n this.#legacyRefreshKey = `${prefix}refresh_token`;\n this.#legacyRevisionKey = `${prefix}auth_revision`;\n this.#storage = options.storage ?? browserStorage;\n this.#locks = options.locks ?? browserLocks;\n this.#createRevision = options.createRevision ?? newRevision;\n this.#leaseReady = this.#acquireContextLease();\n\n try {\n if (typeof window !== \"undefined\") window.addEventListener(\"storage\", this.#onStorage);\n } catch {\n // Request-time ownership checks remain authoritative without events.\n }\n }\n\n onOwnershipLost(listener: OwnershipLost): () => void {\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n setRefreshHandler(handler: RefreshHandler): void {\n this.#refreshHandler = handler;\n }\n\n waitForContextLease(): Promise<boolean> {\n return this.#leaseReady;\n }\n\n /** Test/lifecycle hook; a destroyed page releases the Web Lock implicitly. */\n releaseContextLease(): void {\n this.#releaseLease?.();\n this.#releaseLease = null;\n }\n\n /** Claim credentials already written by an SDK/login test boundary. */\n adoptExistingSessionOwner(): string | null {\n if (!this.#leaseHeld) {\n this.#notify(\"storage\");\n return null;\n }\n return this.#beginSessionOwner(true);\n }\n\n /** Logout retains its exact bearer pair until the server request is sent. */\n beginLogoutSession(): string | null {\n if (!this.#leaseHeld) {\n this.#notify(\"storage\");\n return null;\n }\n return this.#beginSessionOwner(true);\n }\n\n /** Login atomically advances ownership and retires the previous pair. */\n async beginLoginSession(): Promise<boolean> {\n if (!this.#leaseHeld && !(await this.#leaseReady)) {\n this.#notify(\"storage\");\n return false;\n }\n if (!this.#leaseHeld) {\n this.#notify(\"storage\");\n return false;\n }\n return this.#beginSessionOwner(false) !== null;\n }\n\n #beginSessionOwner(preservePair: boolean): string | null {\n this.#pendingAccess = null;\n this.#lastReadRefreshToken = null;\n try {\n const current = this.#readSessionOrMigrate();\n const revision = this.#createRevision();\n const next: StoredAuthSession = {\n version: SESSION_VERSION,\n revision,\n tokens: preservePair ? (current?.tokens ?? null) : null,\n };\n this.#writeSession(next);\n this.#ownedRevision = revision;\n return revision;\n } catch {\n this.#notify(\"storage\");\n return null;\n }\n }\n\n captureOwner(): AuthTokenOwner {\n try {\n if (!this.#leaseHeld) throw new Error(\"This browser context does not own the POS session.\");\n const session = this.#readSessionOrMigrate();\n return {\n revision: this.#ownedRevision,\n accessToken: session?.tokens?.access_token ?? null,\n refreshToken: session?.tokens?.refresh_token ?? null,\n };\n } catch {\n this.#notify(\"storage\");\n return { revision: this.#ownedRevision, accessToken: null, refreshToken: null };\n }\n }\n\n owns(owner: AuthTokenOwner): boolean {\n return (\n this.#leaseHeld &&\n owner.revision === this.#ownedRevision &&\n this.#ownsSharedRevision(owner.revision)\n );\n }\n\n sharesRevision(owner: AuthTokenOwner): boolean {\n if (owner.revision === null) return false;\n try {\n return this.#readSessionOrMigrate()?.revision === owner.revision;\n } catch {\n this.#notify(\"storage\");\n return false;\n }\n }\n\n ownsCurrentSession(): boolean {\n return this.#ownsSharedRevision(this.#ownedRevision);\n }\n\n /** Pure ownership probe for transaction code that must not mutate auth. */\n isCurrentSessionOwner(): boolean {\n if (!this.#leaseHeld) return false;\n try {\n const sharedRevision = this.#readSessionOrMigrate()?.revision ?? null;\n return (\n sharedRevision === null ||\n (this.#ownedRevision !== null && sharedRevision === this.#ownedRevision)\n );\n } catch {\n return false;\n }\n }\n\n hasCurrentPair(accessToken: string, refreshToken: string): boolean {\n if (!this.#ownsSharedRevision(this.#ownedRevision)) return false;\n try {\n const pair = this.#readSessionOrMigrate()?.tokens;\n return pair?.access_token === accessToken && pair.refresh_token === refreshToken;\n } catch {\n this.#notify(\"storage\");\n return false;\n }\n }\n\n assertCurrentSession(): boolean {\n const current = this.ownsCurrentSession();\n if (!current) this.#notify(\"stale\");\n return current;\n }\n\n /** Used by the SDK callback after its request-owned clear attempt. */\n notifySdkTokensCleared(): void {\n this.#notify(\"stale\");\n }\n\n async getAccessToken(): Promise<string | null> {\n return (await this.getRequestOwner()).accessToken;\n }\n\n /**\n * Atomically capture the bearer and revision for one SDK request.\n *\n * Return the private operation's promise directly. That operation performs\n * any proactive refresh and captures both fields in its final synchronous\n * continuation, leaving no second await where a same-token revision change\n * could pair an old bearer with a new owner.\n */\n getRequestOwner(): Promise<AuthTokenOwner> {\n // Capture before entering the async operation. In particular, do not let a\n // login/logout that wins while the lease or refresh awaits are pending\n // rebind an already-started SDK request to the new operator.\n const initiatingRevision = this.#ownedRevision;\n return this.#readRequestOwner(initiatingRevision);\n }\n\n async #readRequestOwner(initiatingRevision: string | null): Promise<AuthTokenOwner> {\n await this.#requireLease();\n this.#assertRequestRevision(initiatingRevision);\n const pair = this.#readPairOrThrow();\n const accessToken = pair?.access_token ?? null;\n const refreshToken = pair?.refresh_token;\n if (accessToken && tokenNeedsRefresh(accessToken) && refreshToken && this.#refreshHandler) {\n await this.#refreshOwnedPair({\n revision: initiatingRevision,\n accessToken,\n refreshToken,\n });\n }\n\n this.#assertRequestRevision(initiatingRevision);\n const current = this.#readSessionOrThrow();\n return {\n accessToken: current.tokens?.access_token ?? null,\n refreshToken: current.tokens?.refresh_token ?? null,\n revision: current.revision,\n };\n }\n\n /**\n * Recover one request whose bearer the server rejected before its JWT expiry.\n *\n * The SDK's response middleware refreshes a 401 only after its own expiry\n * check has elapsed. A server-side expiry can lead that clock, so long-lived\n * pollers use this request-owned boundary to join the same storage\n * single-flight and retry once with the rotated pair.\n */\n async recoverAfterUnauthorized(owner: AuthTokenOwner): Promise<UnauthorizedRecovery> {\n try {\n await this.#requireLease();\n } catch {\n return \"failed\";\n }\n if (this.#pairReplaced(owner)) return \"refreshed\";\n if (!this.owns(owner) || !owner.accessToken || !owner.refreshToken || !this.#refreshHandler) {\n return \"stale\";\n }\n try {\n await this.#refreshOwnedPair(owner);\n } catch {\n return this.#pairReplaced(owner) ? \"refreshed\" : \"failed\";\n }\n if (this.#pairReplaced(owner)) return \"refreshed\";\n return this.owns(owner) ? \"failed\" : \"stale\";\n }\n\n async #refreshOwnedPair(owner: AuthTokenOwner): Promise<void> {\n const refreshHandler = this.#refreshHandler;\n const refreshToken = owner.refreshToken;\n if (!refreshHandler || !refreshToken) throw new Error(\"No POS refresh token is available.\");\n const refreshOperation =\n this.#refreshInFlight ??\n (async () => {\n try {\n // A refresh token past its own expiry cannot be traded for anything:\n // that is the session over, known here without asking the server —\n // and asked, the server could only answer with a refusal or, from a\n // browser origin with no network, with nothing at all.\n if (tokenNeedsRefresh(refreshToken)) {\n throw new RefreshRejectedError({ reason: \"expired\" });\n }\n await this.#runSdkRefresh(owner.revision, refreshToken, (ownedAccessToken) =>\n refreshHandler(refreshToken, ownedAccessToken)\n );\n } catch (error) {\n // Another coordinated refresh may have won while this operation was\n // waiting for the cross-document lock. Its complete pair is success,\n // not permission to clear the newer credentials.\n if (this.#pairReplaced(owner)) return;\n // A refresh that could not complete is not a refusal: the pair\n // stays, the caller hears the failure — as a refresh failure, so it\n // is not mistaken for a lost lease — and the next request tries\n // again. Only the server's \"no\" (or an expired refresh token) clears.\n if (!refreshEndsSession(error)) throw new RefreshUnavailableError(error);\n const outcome = await this.#clearOwnedPair(owner);\n if (outcome === \"cleared\") this.#notify(\"stale\");\n if (outcome === \"failed\") this.#notify(\"storage\");\n if (outcome !== \"stale\") throw error;\n }\n })();\n this.#refreshInFlight = refreshOperation;\n try {\n await refreshOperation;\n } finally {\n if (this.#refreshInFlight === refreshOperation) this.#refreshInFlight = null;\n }\n }\n\n #pairReplaced(owner: AuthTokenOwner): boolean {\n try {\n const current = this.#readSessionOrMigrate();\n return (\n current?.revision === owner.revision &&\n current.tokens !== null &&\n current.tokens.access_token !== owner.accessToken\n );\n } catch {\n this.#notify(\"storage\");\n return false;\n }\n }\n\n async getRefreshToken(): Promise<string | null> {\n await this.#requireLease();\n this.#assertRequestOwner();\n const token = this.#readPairOrThrow()?.refresh_token ?? null;\n this.#lastReadRefreshToken = token;\n return token;\n }\n\n /** Stage only; the pair becomes visible together from setRefreshToken. */\n async setAccessToken(token: string): Promise<void> {\n await this.#requireLease();\n if (!this.#ownsSharedRevision(this.#ownedRevision)) {\n this.#pendingAccess = null;\n this.#notify(\"stale\");\n return;\n }\n this.#pendingAccess = {\n revision: this.#ownedRevision,\n expectedRefreshToken: this.#lastReadRefreshToken,\n token,\n };\n }\n\n async setRefreshToken(token: string): Promise<void> {\n await this.#requireLease();\n const pending = this.#pendingAccess;\n this.#pendingAccess = null;\n if (!pending) {\n this.#notify(\"storage\");\n return;\n }\n await this.#commitPair(pending.revision, pending.expectedRefreshToken, pending.token, token);\n }\n\n /**\n * SDK compatibility boundary.\n *\n * The patched POS middleware supplies the bearer that produced a 403/logout\n * response. An older response is therefore inert after login or refresh. SDK\n * internal cleanup without a request bearer still captures the exact current\n * pair before entering the serialized clear.\n */\n async clearTokens(\n expectedAccessToken?: string | null,\n expectedRevision?: string | null\n ): Promise<boolean> {\n await this.#requireLease();\n this.#pendingAccess = null;\n const owner = this.captureOwner();\n const hasExpectedOwner = expectedAccessToken !== undefined || expectedRevision !== undefined;\n if (\n hasExpectedOwner &&\n (owner.accessToken !== (expectedAccessToken ?? null) ||\n owner.revision !== (expectedRevision ?? null))\n ) {\n return false;\n }\n const outcome = await this.#clearOwnedPair(owner);\n if (outcome === \"failed\") this.#notify(\"storage\");\n return outcome === \"cleared\";\n }\n\n /** Own the SDK's automatic refresh from token read through pair commit. */\n async runSdkRefresh(\n refreshToken: string,\n execute: (accessToken: string) => Promise<AuthTokenPair>\n ): Promise<AuthTokenPair> {\n const initiatingRevision = this.#ownedRevision;\n return this.#runSdkRefresh(initiatingRevision, refreshToken, execute);\n }\n\n async #runSdkRefresh(\n initiatingRevision: string | null,\n refreshToken: string,\n execute: (accessToken: string) => Promise<AuthTokenPair>\n ): Promise<AuthTokenPair> {\n await this.#requireLease();\n const locks = this.#locks();\n if (!locks) {\n this.#notify(\"storage\");\n throw new Error(\"Cross-context token coordination is unavailable.\");\n }\n\n return locks.request(AUTH_SESSION_LOCK, { mode: \"exclusive\" }, async () => {\n if (\n initiatingRevision !== this.#ownedRevision ||\n !this.#ownsSharedRevision(initiatingRevision)\n ) {\n throw new Error(\"The authenticated session changed before token refresh.\");\n }\n const current = this.#readSessionOrThrow();\n if (current.tokens?.refresh_token !== refreshToken || !current.tokens.access_token) {\n throw new Error(\"A newer token refresh already completed.\");\n }\n const originalPair = current.tokens;\n const pair = await execute(originalPair.access_token);\n if (!pair.access_token || !pair.refresh_token) {\n throw new Error(\"Token refresh returned an incomplete pair.\");\n }\n if (\n initiatingRevision !== this.#ownedRevision ||\n !this.#ownsSharedRevision(initiatingRevision)\n ) {\n throw new Error(\"The authenticated session changed during token refresh.\");\n }\n const latest = this.#readSessionOrThrow();\n if (latest.tokens?.refresh_token !== refreshToken) {\n throw new Error(\"A newer token refresh already completed.\");\n }\n this.#writeSession({\n version: SESSION_VERSION,\n revision: latest.revision,\n tokens: pair,\n });\n this.#lastReadRefreshToken = pair.refresh_token;\n return pair;\n });\n }\n\n /** Commit a side-effect-free direct refresh against its captured pair. */\n async adoptTokens(\n owner: AuthTokenOwner,\n accessToken: string,\n refreshToken: string\n ): Promise<TokenAdoption> {\n try {\n await this.#requireLease();\n } catch {\n return \"failed\";\n }\n if (!this.owns(owner)) return \"stale\";\n return this.#commitPair(owner.revision, owner.refreshToken, accessToken, refreshToken);\n }\n\n #notify(reason: \"stale\" | \"storage\"): void {\n const hadOwner = this.#ownedRevision !== null;\n this.#ownedRevision = null;\n this.#pendingAccess = null;\n this.#lastReadRefreshToken = null;\n if (reason === \"stale\" && !hadOwner) return;\n for (const listener of this.#listeners) listener(reason);\n }\n\n #acquireContextLease(): Promise<boolean> {\n const locks = this.#locks();\n if (!locks) return Promise.resolve(false);\n\n return new Promise<boolean>((resolve) => {\n let readySettled = false;\n const settleReady = (held: boolean): void => {\n if (readySettled) return;\n readySettled = true;\n resolve(held);\n };\n\n // Queue for the lock rather than ask whether it is free right now; give\n // up only after `leaseWaitMs`, by which time a reloading page's release\n // has long arrived and a lock still held belongs to a live page.\n const waiting = new AbortController();\n const deadline = setTimeout(() => waiting.abort(), this.#leaseWaitMs);\n\n void locks\n .request(AUTH_CONTEXT_LOCK, { mode: \"exclusive\", signal: waiting.signal }, async (lock) => {\n clearTimeout(deadline);\n if (!lock) {\n settleReady(false);\n return;\n }\n\n try {\n const session = this.#readSessionOrMigrate();\n this.#leaseHeld = true;\n this.#ownedRevision = session?.revision ?? null;\n } catch {\n this.#leaseHeld = false;\n this.#notify(\"storage\");\n settleReady(false);\n return;\n }\n settleReady(true);\n\n await new Promise<void>((release) => {\n this.#releaseLease = release;\n });\n this.#releaseLease = null;\n this.#leaseHeld = false;\n this.#ownedRevision = null;\n this.#pendingAccess = null;\n })\n .catch(() => {\n // Aborted at the deadline, or the lock manager refused: not held.\n clearTimeout(deadline);\n settleReady(false);\n });\n });\n }\n\n async #requireLease(): Promise<void> {\n if ((await this.#leaseReady) && this.#leaseHeld) return;\n this.#notify(\"storage\");\n throw new Error(\"Another browser tab owns this POS session.\");\n }\n\n #assertRequestOwner(): void {\n if (this.#ownsSharedRevision(this.#ownedRevision)) return;\n this.#notify(\"stale\");\n throw new Error(\"The authenticated session belongs to another browser context.\");\n }\n\n #assertRequestRevision(revision: string | null): void {\n if (revision === this.#ownedRevision && this.#ownsSharedRevision(revision)) return;\n // A newer login/logout in this same context legitimately owns the shared\n // record. Reject only the old call; do not invalidate the winner.\n if (this.#ownsSharedRevision(this.#ownedRevision)) {\n throw new Error(\"The authenticated session changed before the POS request was sent.\");\n }\n this.#notify(\"stale\");\n throw new Error(\"The authenticated session belongs to another browser context.\");\n }\n\n #ownsSharedRevision(revision: string | null): boolean {\n if (!this.#leaseHeld || revision === null) return false;\n try {\n return this.#readSessionOrMigrate()?.revision === revision;\n } catch {\n this.#notify(\"storage\");\n return false;\n }\n }\n\n #readPairOrThrow(): AuthTokenPair | null {\n return this.#readSessionOrThrow().tokens;\n }\n\n #readSessionOrThrow(): StoredAuthSession {\n const session = this.#readSessionOrMigrate();\n if (!session) throw new Error(\"No POS auth session exists.\");\n return session;\n }\n\n #readSessionOrMigrate(): StoredAuthSession | null {\n const storage = this.#storageOrThrow();\n const raw = storage.getItem(this.#sessionKey);\n if (raw !== null) {\n const parsed = parseSession(raw);\n if (parsed.wasLegacy) this.#writeSession(parsed.session);\n return parsed.session;\n }\n\n const accessToken = storage.getItem(this.#legacyAccessKey);\n const refreshToken = storage.getItem(this.#legacyRefreshKey);\n const legacyRevision = storage.getItem(this.#legacyRevisionKey);\n if (accessToken === null && refreshToken === null && legacyRevision === null) return null;\n if ((accessToken === null) !== (refreshToken === null)) {\n throw new Error(\"Incomplete legacy POS auth token pair.\");\n }\n if (accessToken !== null && (!accessToken || !refreshToken)) {\n throw new Error(\"Invalid legacy POS auth token pair.\");\n }\n if (legacyRevision !== null && !legacyRevision) {\n throw new Error(\"Invalid legacy POS auth revision.\");\n }\n\n const migrated: StoredAuthSession = {\n version: SESSION_VERSION,\n revision: legacyRevision ?? this.#createRevision(),\n tokens:\n accessToken === null\n ? null\n : { access_token: accessToken, refresh_token: refreshToken as string },\n };\n this.#writeSession(migrated);\n // The committed record is authoritative. Legacy cleanup is best-effort and\n // cannot make a complete atomic session unreadable.\n try {\n storage.removeItem(this.#legacyAccessKey);\n storage.removeItem(this.#legacyRefreshKey);\n storage.removeItem(this.#legacyRevisionKey);\n } catch {\n // Ignore: these keys are never consulted while the versioned record exists.\n }\n return migrated;\n }\n\n #writeSession(session: StoredAuthSession): void {\n this.#storageOrThrow().setItem(this.#sessionKey, JSON.stringify(session));\n }\n\n #storageOrThrow(): AuthStorageLike {\n const storage = this.#storage();\n if (!storage) throw new Error(\"Browser storage is unavailable.\");\n return storage;\n }\n\n async #clearOwnedPair(owner: AuthTokenOwner): Promise<ClearOutcome> {\n const locks = this.#locks();\n if (!locks) return \"failed\";\n try {\n return await locks.request(AUTH_SESSION_LOCK, { mode: \"exclusive\" }, () => {\n if (!this.owns(owner)) return \"stale\";\n const current = this.#readSessionOrThrow();\n if (\n current.tokens?.access_token !== owner.accessToken ||\n current.tokens?.refresh_token !== owner.refreshToken\n ) {\n return \"stale\";\n }\n try {\n this.#writeSession({ ...current, tokens: null });\n } catch {\n return \"failed\";\n }\n this.#lastReadRefreshToken = null;\n return \"cleared\";\n });\n } catch {\n return \"failed\";\n }\n }\n\n async #commitPair(\n revision: string | null,\n expectedRefreshToken: string | null,\n accessToken: string,\n refreshToken: string\n ): Promise<TokenAdoption> {\n const locks = this.#locks();\n if (!locks) {\n this.#notify(\"storage\");\n return \"failed\";\n }\n\n try {\n return await locks.request(AUTH_SESSION_LOCK, { mode: \"exclusive\" }, () => {\n if (revision !== this.#ownedRevision || !this.#ownsSharedRevision(revision)) {\n this.#notify(\"stale\");\n return \"stale\";\n }\n const current = this.#readSessionOrThrow();\n if ((current.tokens?.refresh_token ?? null) !== expectedRefreshToken) return \"stale\";\n try {\n this.#writeSession({\n version: SESSION_VERSION,\n revision: current.revision,\n tokens: { access_token: accessToken, refresh_token: refreshToken },\n });\n } catch {\n this.#notify(\"storage\");\n return \"failed\";\n }\n this.#lastReadRefreshToken = refreshToken;\n return \"adopted\";\n });\n } catch {\n this.#notify(\"storage\");\n return \"failed\";\n }\n }\n}\n\ninterface AuthTokenHotData {\n authTokenStorage?: CoordinatedBrowserTokenStorage;\n}\n\nconst hotData = (\n import.meta as ImportMeta & { hot?: { data: AuthTokenHotData } }\n).hot?.data;\nexport const authTokenStorage = hotData?.authTokenStorage ?? new CoordinatedBrowserTokenStorage();\nif (hotData) hotData.authTokenStorage = authTokenStorage;\n","/**\n * Decode a JWT token payload without signature verification.\n * This is a lightweight replacement for jose's decodeJwt.\n *\n * @param token - The JWT token to decode\n * @returns The decoded payload\n * @throws Error if the token is malformed\n */\nfunction decodeJwt<T = Record<string, unknown>>(token: string): T {\n if (typeof token !== \"string\") {\n throw new Error(\"Invalid token: must be a string\");\n }\n\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid token: must have 3 parts\");\n }\n\n const base64Url = parts[1];\n if (!base64Url) throw new Error(\"Invalid token: missing payload\");\n\n let base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = base64.length % 4;\n if (padding) base64 += \"=\".repeat(4 - padding);\n\n // UTF-8 safe decoding\n const binaryStr = atob(base64);\n const bytes = new Uint8Array(binaryStr.length);\n for (let i = 0; i < binaryStr.length; i++) {\n bytes[i] = binaryStr.charCodeAt(i);\n }\n\n const payload = JSON.parse(new TextDecoder().decode(bytes));\n if (typeof payload !== \"object\" || payload === null) {\n throw new Error(\"Invalid token: payload must be an object\");\n }\n\n return payload;\n}\n\n/**\n * JWT payload structure for POS tokens\n */\nexport interface JwtPayload {\n token_type: string;\n exp: number;\n iat: number;\n jti: string;\n ulid: string;\n username: string;\n email: string;\n phone: string;\n first_name: string;\n last_name: string;\n store_id: string;\n is_logged_in: boolean;\n roles: {\n role_id: string;\n role_name: string;\n location_id: string;\n location_name: string;\n }[];\n location: {\n id: string;\n name: string;\n };\n tenant_id: string;\n channel: {\n id: string;\n name: string;\n type: string;\n };\n sid: string;\n}\n\n/**\n * User information extracted from POS JWT token\n */\nexport interface UserInfo {\n id: string;\n username: string;\n email: string;\n phone: string;\n firstName: string;\n lastName: string;\n storeId: string;\n isLoggedIn: boolean;\n roles: {\n roleId: string;\n roleName: string;\n locationId: string;\n locationName: string;\n }[];\n location: {\n id: string;\n name: string;\n };\n tenantId: string;\n channel: {\n id: string;\n name: string;\n type: string;\n };\n sessionId: string;\n tokenExpiry: Date;\n tokenIssuedAt: Date;\n}\n\n/**\n * Decode and extract user information from a JWT token\n *\n * @param token - The JWT token to decode\n * @returns User information or null if token is invalid\n */\nexport function extractUserInfoFromToken(token: string): UserInfo | null {\n try {\n const payload = decodeJwt(token) as JwtPayload;\n\n return {\n id: payload.ulid,\n username: payload.username,\n email: payload.email,\n phone: payload.phone,\n firstName: payload.first_name,\n lastName: payload.last_name,\n storeId: payload.store_id,\n isLoggedIn: payload.is_logged_in,\n roles: payload.roles.map(role => ({\n roleId: role.role_id,\n roleName: role.role_name,\n locationId: role.location_id,\n locationName: role.location_name,\n })),\n location: {\n id: payload.location.id,\n name: payload.location.name,\n },\n tenantId: payload.tenant_id,\n channel: {\n id: payload.channel.id,\n name: payload.channel.name,\n type: payload.channel.type,\n },\n sessionId: payload.sid,\n tokenExpiry: new Date(payload.exp * 1000),\n tokenIssuedAt: new Date(payload.iat * 1000),\n };\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return null;\n }\n}\n\n/**\n * Check if a JWT token is expired\n *\n * @param token - The JWT token to check\n * @param bufferSeconds - Buffer time in seconds (default: 30)\n * @returns True if token is expired or will expire within buffer time\n */\nexport function isTokenExpired(\n token: string,\n bufferSeconds: number = 30\n): boolean {\n try {\n const payload = decodeJwt<{ exp?: number }>(token);\n if (!payload.exp) return true;\n\n const currentTime = Math.floor(Date.now() / 1000);\n const expiryTime = payload.exp;\n\n // Consider token expired if it expires within the buffer time\n return currentTime >= expiryTime - bufferSeconds;\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return true; // Treat invalid tokens as expired\n }\n}\n\n/**\n * Get the user ID from a JWT token\n *\n * @param token - The JWT token\n * @returns User ID (ulid) or null if token is invalid\n */\nexport function getUserIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.id || null;\n}\n\n/**\n * Check if user is logged in based on JWT token\n *\n * @param token - The JWT token\n * @returns True if user is logged in, false otherwise\n */\nexport function isUserLoggedIn(token: string): boolean {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.isLoggedIn || false;\n}\n\n/**\n * Check if user is authenticated (has valid POS token)\n * Checks the token for isLoggedIn status\n *\n * @param token - The JWT token\n * @returns True if user is authenticated with valid POS access\n */\nexport function isUserAuthenticated(token: string): boolean {\n const userInfo = extractUserInfoFromToken(token);\n return !!userInfo?.isLoggedIn;\n}\n\n\n/**\n * Get the location ID from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Location ID or null if token is invalid\n */\nexport function getLocationIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.location?.id || null;\n}\n\n/**\n * Get the role information from a POS JWT token for the current location\n *\n * @param token - The JWT token\n * @returns Role object for the current location, or null if token is invalid\n */\nexport function getRoleFromToken(token: string): {\n roleId: string;\n roleName: string;\n locationId: string;\n locationName: string;\n} | null {\n const userInfo = extractUserInfoFromToken(token);\n if (!userInfo?.roles || userInfo.roles.length === 0) return null;\n\n // Find role for current location, or return first role if location match not found\n const currentLocationRole = userInfo.roles.find(role => role.locationId === userInfo.location.id);\n return currentLocationRole || userInfo.roles[0] || null;\n}\n\n/**\n * Get the tenant ID from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Tenant ID or null if token is invalid\n */\nexport function getTenantIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.tenantId || null;\n}\n\n/**\n * Get the channel information from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Channel object with id, name, and type, or null if token is invalid\n */\nexport function getChannelFromToken(token: string): {\n id: string;\n name: string;\n type: string;\n} | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.channel || null;\n}\n\n/**\n * Get the session ID from a POS JWT token\n *\n * @param token - The JWT token\n * @returns Session ID or null if token is invalid\n */\nexport function getSessionIdFromToken(token: string): string | null {\n const userInfo = extractUserInfoFromToken(token);\n return userInfo?.sessionId || null;\n}\n","/**\n * Check if a URL path is a POS login endpoint that should use API key\n * Based on POS spec, only these 5 endpoints use X-Api-Key:\n * - /pos/auth/login/email\n * - /pos/auth/login/phone\n * - /pos/auth/login/whatsapp\n * - /pos/auth/pair-device\n * - /pos/auth/verify-otp\n */\nexport function isApiKeyEndpoint(pathname: string): boolean {\n const apiKeyEndpoints = [\n \"/pos/auth/login/email\",\n \"/pos/auth/login/phone\",\n \"/pos/auth/login/whatsapp\",\n \"/pos/auth/pair-device\",\n \"/pos/auth/verify-otp\",\n \"/pos/locations\",\n ];\n return apiKeyEndpoints.some((endpoint) => pathname.includes(endpoint));\n}\n\n/**\n * Check if a URL path is a POS endpoint that returns tokens\n * Based on POS spec, only these endpoints return tokens:\n * - /pos/auth/verify-otp (after OTP verification)\n * - /pos/auth/refresh-token\n */\nexport function isTokenReturningEndpoint(pathname: string): boolean {\n const tokenEndpoints = [\"/pos/auth/verify-otp\", \"/pos/auth/refresh-token\"];\n return tokenEndpoints.some((endpoint) => pathname.includes(endpoint));\n}\n\n/**\n * Check if a URL path is a POS logout endpoint\n */\nexport function isLogoutEndpoint(pathname: string): boolean {\n return (\n pathname.includes(\"/pos/auth/logout\") || pathname.includes(\"/pos/logout\")\n );\n}\n\n// Re-export JWT utilities from jwt.ts\nexport {\n isTokenExpired,\n extractUserInfoFromToken,\n getUserIdFromToken,\n isUserLoggedIn,\n isUserAuthenticated,\n getLocationIdFromToken,\n getRoleFromToken,\n getTenantIdFromToken,\n} from \"./jwt\";\nexport type { UserInfo, JwtPayload } from \"./jwt\";\n","import type { Middleware } from \"openapi-fetch\";\nimport { getPathnameFromUrl } from \"@commercengine/sdk-core\";\nimport { RefreshRejectedError, isRefreshFailure, refreshEndsSession } from \"../auth-token-storage\";\nimport {\n isApiKeyEndpoint,\n isTokenReturningEndpoint,\n isLogoutEndpoint,\n isTokenExpired,\n} from \"../utils/auth\";\n\n/**\n * An atomic snapshot of the authenticated session, used to bind requests and\n * destructive token operations to the session that initiated them.\n */\nexport interface RequestOwner {\n accessToken: string | null;\n refreshToken: string | null;\n /**\n * Opaque marker that changes whenever the stored session changes.\n * Two owners with the same revision belong to the same session.\n */\n revision: string | null;\n}\n\n/** Canonical token-pair shape used at every POS SDK auth boundary. */\nexport interface AuthTokenPair {\n access_token: string;\n refresh_token: string;\n}\n\n/**\n * Token storage interface for the POS auth middleware\n */\nexport interface TokenStorage {\n getAccessToken(): Promise<string | null>;\n setAccessToken(token: string): Promise<void>;\n getRefreshToken(): Promise<string | null>;\n setRefreshToken(token: string): Promise<void>;\n /**\n * Read the access token, refresh token, and session revision as one atomic\n * snapshot. Storages that implement this let the middleware detect a session\n * that changed mid-request (another tab logging in, a different user).\n */\n getRequestOwner?(): Promise<RequestOwner>;\n /**\n * Clear the stored tokens.\n *\n * When `expectedAccessToken` (and optionally `expectedRevision`) is given,\n * the storage must clear ONLY if the stored session still matches — a\n * compare-and-swap that stops one session's failure from logging out the\n * session that replaced it. Returns `false` when the guard refused to clear.\n */\n clearTokens(\n expectedAccessToken?: string | null,\n expectedRevision?: string | null\n ): Promise<void | boolean>;\n}\n\n/**\n * Simple in-memory token storage implementation\n */\nexport class MemoryTokenStorage implements TokenStorage {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n\n async getAccessToken(): Promise<string | null> {\n return this.accessToken;\n }\n\n async setAccessToken(token: string): Promise<void> {\n this.accessToken = token;\n }\n\n async getRefreshToken(): Promise<string | null> {\n return this.refreshToken;\n }\n\n async setRefreshToken(token: string): Promise<void> {\n this.refreshToken = token;\n }\n\n async clearTokens(\n expectedAccessToken?: string | null,\n _expectedRevision?: string | null\n ): Promise<boolean> {\n if (\n expectedAccessToken !== undefined &&\n this.accessToken !== expectedAccessToken\n ) {\n return false;\n }\n this.accessToken = null;\n this.refreshToken = null;\n return true;\n }\n}\n\n/**\n * Browser localStorage token storage implementation for POS\n */\nexport class BrowserTokenStorage implements TokenStorage {\n private accessTokenKey: string;\n private refreshTokenKey: string;\n\n constructor(prefix: string = \"pos_\") {\n this.accessTokenKey = `${prefix}access_token`;\n this.refreshTokenKey = `${prefix}refresh_token`;\n }\n\n async getAccessToken(): Promise<string | null> {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(this.accessTokenKey);\n }\n\n async setAccessToken(token: string): Promise<void> {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(this.accessTokenKey, token);\n }\n }\n\n async getRefreshToken(): Promise<string | null> {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(this.refreshTokenKey);\n }\n\n async setRefreshToken(token: string): Promise<void> {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(this.refreshTokenKey, token);\n }\n }\n\n async clearTokens(\n expectedAccessToken?: string | null,\n _expectedRevision?: string | null\n ): Promise<boolean> {\n if (typeof localStorage !== \"undefined\") {\n if (\n expectedAccessToken !== undefined &&\n localStorage.getItem(this.accessTokenKey) !== expectedAccessToken\n ) {\n return false;\n }\n localStorage.removeItem(this.accessTokenKey);\n localStorage.removeItem(this.refreshTokenKey);\n }\n return true;\n }\n}\n\n/**\n * Configuration for the POS auth middleware\n */\nexport interface PosAuthMiddlewareConfig {\n /**\n * Token storage implementation\n */\n tokenStorage: TokenStorage;\n\n /**\n * API key for X-Api-Key endpoints (login, pair-device, verify-otp)\n * Required for POS authentication flows and fallback scenarios\n */\n apiKey: string;\n\n /**\n * Base URL for the API (used for refresh token endpoint)\n */\n baseUrl: string;\n\n /**\n * Function to refresh tokens\n * Should make a call to the POS refresh token endpoint\n */\n refreshTokenFn?: (refreshToken: string) => Promise<AuthTokenPair>;\n\n /**\n * Callback when tokens are updated (login/refresh)\n */\n onTokensUpdated?: (accessToken: string, refreshToken: string) => void;\n\n /**\n * Callback when tokens are cleared (logout/error)\n */\n onTokensCleared?: () => void;\n\n /**\n * Persist token pairs returned by verify/refresh response middleware.\n * Defaults to true. Disable when the application adopts returned pairs only\n * after its own request-ownership checks.\n */\n storeTokenResponses?: boolean;\n}\n\n/**\n * Create POS authentication middleware for openapi-fetch\n *\n * POS Authentication Rules:\n * 1. API Key endpoints (X-Api-Key): login/email, login/phone, login/whatsapp, pair-device, verify-otp\n * 2. Bearer token endpoints: All other endpoints\n * 3. Token returning endpoints: verify-otp, refresh-token\n *\n * When the token storage implements `getRequestOwner()`, every destructive\n * operation (clear on failed refresh, logout, 403) is scoped to the session\n * that initiated it, and a request whose session changed between scheduling\n * and dispatch is refused instead of sent with another session's identity.\n */\nexport function createPosAuthMiddleware(\n config: PosAuthMiddlewareConfig\n): Middleware {\n let isRefreshing = false;\n let refreshPromise: Promise<void> | null = null;\n let hasAssessedTokens = false;\n\n /** The owner each in-flight request was signed for, keyed by Request. */\n const requestOwners = new WeakMap<\n Request,\n { accessToken: string; revision: string | null | undefined }\n >();\n\n /**\n * Clear tokens on behalf of `owner`. With an owner this is a\n * compare-and-swap — a session that replaced the failing one survives —\n * and `onTokensCleared` only fires when something was actually cleared.\n */\n const clearAssessedOwner = async (\n owner: RequestOwner | null | undefined\n ): Promise<boolean> => {\n const cleared = owner\n ? await config.tokenStorage.clearTokens(owner.accessToken, owner.revision)\n : await config.tokenStorage.clearTokens();\n if (cleared !== false) config.onTokensCleared?.();\n return cleared !== false;\n };\n\n const assessTokenStateOnce = async (\n initiatingOwner?: RequestOwner | null\n ): Promise<void> => {\n // Skip if already assessed (tokenStorage is guaranteed to exist when middleware is created)\n if (hasAssessedTokens) return;\n\n hasAssessedTokens = true;\n\n try {\n const owner =\n initiatingOwner ?? (await config.tokenStorage.getRequestOwner?.());\n const accessToken = owner\n ? owner.accessToken\n : await config.tokenStorage.getAccessToken();\n const refreshToken = owner\n ? owner.refreshToken\n : await config.tokenStorage.getRefreshToken();\n\n // Case 1: Valid access token - do nothing\n if (accessToken && !isTokenExpired(accessToken)) {\n return;\n }\n\n // Case 2: Orphaned refresh token (no access token but refresh token exists)\n if (!accessToken && refreshToken) {\n // Clean up orphaned refresh token to prevent confusion\n await clearAssessedOwner(owner);\n console.info(\"Cleaned up orphaned refresh token in POS\");\n return;\n }\n\n // Case 3: Expired access token with valid refresh token\n if (accessToken && refreshToken && !isTokenExpired(refreshToken)) {\n try {\n await refreshTokens(owner);\n console.info(\"POS tokens refreshed proactively on startup\");\n } catch (error) {\n // refreshTokens cleared the tokens if the answer was definitive;\n // otherwise they are kept and the next request tries again.\n console.info(\n refreshEndsSession(error)\n ? \"POS tokens cleared after a rejected refresh on startup\"\n : \"POS startup refresh could not complete; tokens kept\"\n );\n }\n return;\n }\n\n // Case 4: Both tokens expired or invalid - clear stale tokens\n if (\n (accessToken && isTokenExpired(accessToken)) ||\n (refreshToken && isTokenExpired(refreshToken))\n ) {\n await clearAssessedOwner(owner);\n console.info(\n \"POS stale tokens cleared on startup - user needs to re-authenticate\"\n );\n return;\n }\n\n // Case 5: No tokens at all - valid unauthenticated state\n if (!accessToken && !refreshToken) {\n // This is normal - user hasn't logged in or has logged out\n // No action needed, POS will work with API key endpoints\n return;\n }\n\n // Note: Unlike storefront, POS doesn't have anonymous fallback\n // Users must explicitly authenticate through login endpoints\n } catch (error) {\n // Silent fail - don't break the request flow\n console.warn(\"POS token state assessment failed:\", error);\n // A coordinated storage failing to answer is a real fault the caller\n // must see, not a degraded-but-working state.\n if (config.tokenStorage.getRequestOwner) throw error;\n }\n };\n\n const refreshTokens = async (\n initiatingOwner?: RequestOwner | null\n ): Promise<void> => {\n if (isRefreshing && refreshPromise) {\n return refreshPromise;\n }\n\n isRefreshing = true;\n refreshPromise = (async () => {\n try {\n const refreshToken = initiatingOwner\n ? initiatingOwner.refreshToken\n : await config.tokenStorage.getRefreshToken();\n\n if (!refreshToken || isTokenExpired(refreshToken)) {\n throw new RefreshRejectedError({ reason: \"expired\" });\n }\n\n let newTokens: AuthTokenPair;\n\n if (config.refreshTokenFn) {\n // Use provided refresh function\n newTokens = await config.refreshTokenFn(refreshToken);\n } else {\n // Default refresh implementation for POS\n const accessToken = initiatingOwner\n ? initiatingOwner.accessToken\n : await config.tokenStorage.getAccessToken();\n if (!accessToken) {\n throw new Error(\"No valid access token available for POS token refresh\");\n }\n const response = await fetch(\n `${config.baseUrl}/pos/auth/refresh-token`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({ refresh_token: refreshToken }),\n }\n );\n\n if (!response.ok) {\n throw new RefreshRejectedError({ status: response.status });\n }\n\n const data = await response.json();\n newTokens = data.content || data;\n }\n\n // Store new tokens\n await config.tokenStorage.setAccessToken(newTokens.access_token);\n await config.tokenStorage.setRefreshToken(newTokens.refresh_token);\n\n // Notify callback\n config.onTokensUpdated?.(\n newTokens.access_token,\n newTokens.refresh_token\n );\n } catch (error) {\n if (refreshEndsSession(error)) {\n console.error(\"POS token refresh rejected; tokens cleared:\", error);\n // Scoped to the session that was refused.\n await clearAssessedOwner(initiatingOwner);\n } else {\n console.warn(\"POS token refresh could not complete; tokens kept:\", error);\n }\n throw error;\n } finally {\n isRefreshing = false;\n refreshPromise = null;\n }\n })();\n\n return refreshPromise;\n };\n\n return {\n async onRequest({ request }) {\n const pathname = getPathnameFromUrl(request.url);\n\n // Assess token state once per middleware instance (POS session start)\n let initiatingOwner: RequestOwner | null | undefined;\n try {\n initiatingOwner = await config.tokenStorage.getRequestOwner?.();\n } catch (error) {\n // Reading the owner can mean refreshing an expired access token, and\n // that refresh can fail without saying anything about the session (no\n // network, a gateway timeout). A request that needs only the API key\n // — the login, the locations list — must not be the one that pays\n // for it: it goes out as itself, and the session's next own request\n // tries the refresh again. Only for a *refresh* failure, though: a\n // lease this page does not hold, or a store it cannot read, closes\n // every request, API-key ones included — that boundary is the\n // single-owner rule, and the refresh is not allowed to loosen it.\n if (!isApiKeyEndpoint(pathname) || !isRefreshFailure(error)) throw error;\n request.headers.set(\"X-Api-Key\", config.apiKey);\n return request;\n }\n await assessTokenStateOnce(initiatingOwner);\n\n // Handle API Key endpoints (5 specific endpoints only)\n if (isApiKeyEndpoint(pathname)) {\n request.headers.set(\"X-Api-Key\", config.apiKey);\n return request;\n }\n\n // For all other endpoints, use Bearer token\n let requestOwner = await config.tokenStorage.getRequestOwner?.();\n if (\n initiatingOwner &&\n requestOwner?.revision !== initiatingOwner.revision\n ) {\n throw new Error(\n \"The authenticated session changed before the POS request was sent.\"\n );\n }\n let accessToken = requestOwner\n ? requestOwner.accessToken\n : await config.tokenStorage.getAccessToken();\n\n // Check if token needs refresh\n if (accessToken && isTokenExpired(accessToken)) {\n try {\n await refreshTokens(requestOwner);\n requestOwner = await config.tokenStorage.getRequestOwner?.();\n if (\n initiatingOwner &&\n requestOwner?.revision !== initiatingOwner.revision\n ) {\n throw new Error(\n \"The authenticated session changed before the POS request was sent.\"\n );\n }\n accessToken = requestOwner\n ? requestOwner.accessToken\n : await config.tokenStorage.getAccessToken();\n } catch (error) {\n // If refresh fails, continue without token (will get 401)\n console.warn(\"Token refresh failed:\", error);\n accessToken = null;\n }\n }\n\n // Add Authorization header if we have a token\n if (accessToken) {\n request.headers.set(\"Authorization\", `Bearer ${accessToken}`);\n // Remember which session this request was signed for, so response\n // handling can scope destructive actions to it.\n requestOwners.set(request, {\n accessToken,\n revision: requestOwner?.revision,\n });\n }\n\n return request;\n },\n\n async onResponse({ request, response }) {\n const pathname = getPathnameFromUrl(request.url);\n\n // Handle successful responses that return tokens (verify-otp, refresh-token)\n if (\n config.storeTokenResponses !== false &&\n response.ok &&\n isTokenReturningEndpoint(pathname)\n ) {\n try {\n const data = await response.clone().json();\n const content = data.content || data;\n\n if (content?.access_token && content?.refresh_token) {\n await config.tokenStorage.setAccessToken(content.access_token);\n await config.tokenStorage.setRefreshToken(content.refresh_token);\n config.onTokensUpdated?.(\n content.access_token,\n content.refresh_token\n );\n }\n } catch (error) {\n console.warn(\"Failed to extract tokens from POS response:\", error);\n }\n } else if (response.ok && isLogoutEndpoint(pathname)) {\n // Clear tokens on successful logout - only the session that sent it\n const owner = requestOwners.get(request);\n if (owner?.accessToken) {\n const cleared = await config.tokenStorage.clearTokens(\n owner.accessToken,\n owner.revision\n );\n if (cleared !== false) config.onTokensCleared?.();\n }\n }\n\n // Handle 401 responses - retry once if token was expired\n if (response.status === 401 && !isApiKeyEndpoint(pathname)) {\n const currentToken = await config.tokenStorage.getAccessToken();\n\n // Only attempt refresh if we have a token and it's expired\n if (currentToken && isTokenExpired(currentToken, 0)) {\n try {\n await refreshTokens();\n\n // Retry the original request with new token\n const newToken = await config.tokenStorage.getAccessToken();\n if (newToken) {\n const retryRequest = request.clone();\n retryRequest.headers.set(\"Authorization\", `Bearer ${newToken}`);\n return fetch(retryRequest);\n }\n } catch (error) {\n // If refresh fails, let the original 401 response through\n console.warn(\"POS token refresh failed on 401 response:\", error);\n }\n }\n }\n\n // Handle 403 responses - token is blacklisted/revoked, clear all tokens\n if (response.status === 403 && !isApiKeyEndpoint(pathname)) {\n const owner = requestOwners.get(request);\n if (owner?.accessToken) {\n const cleared = await config.tokenStorage.clearTokens(\n owner.accessToken,\n owner.revision\n );\n if (cleared !== false) config.onTokensCleared?.();\n }\n console.info(\n \"POS tokens cleared due to 403 - session revoked. This can happen when a user has more than 5 active sessions. Please re-authenticate.\"\n );\n }\n\n return response;\n },\n };\n}\n\n/**\n * Helper function to create POS auth middleware with sensible defaults\n */\nexport function createDefaultPosAuthMiddleware(options: {\n apiKey: string;\n baseUrl: string;\n tokenStorage?: TokenStorage;\n onTokensUpdated?: (accessToken: string, refreshToken: string) => void;\n onTokensCleared?: () => void;\n storeTokenResponses?: boolean;\n}): Middleware {\n const tokenStorage =\n options.tokenStorage ||\n (typeof localStorage !== \"undefined\"\n ? new BrowserTokenStorage()\n : new MemoryTokenStorage());\n\n return createPosAuthMiddleware({\n tokenStorage,\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n onTokensUpdated: options.onTokensUpdated,\n onTokensCleared: options.onTokensCleared,\n storeTokenResponses: options.storeTokenResponses,\n });\n}\n","/**\n * Environment configuration for POS API\n */\nexport enum Environment {\n Development = \"dev\",\n Staging = \"staging\",\n Production = \"production\",\n}\n\n/**\n * Configuration for building POS API URLs\n */\nexport interface PosURLConfig {\n storeId: string;\n environment?: Environment;\n baseUrl?: string;\n}\n\n/**\n * Build the base URL for POS API requests\n *\n * @param config - URL configuration\n * @returns The base URL for POS API requests\n */\nexport function buildPosURL(config: PosURLConfig): string {\n // If custom baseUrl is provided, use it directly\n if (config.baseUrl) {\n return config.baseUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n }\n\n // Build URL based on environment and store ID\n const env = config.environment || Environment.Production;\n\n switch (env) {\n case Environment.Staging:\n return `https://staging.api.commercengine.io/api/v1/${config.storeId}/storefront`;\n case Environment.Production:\n default:\n return `https://prod.api.commercengine.io/api/v1/${config.storeId}/storefront`;\n }\n}\n","import type { paths } from \"../types/pos\";\nimport { BaseAPIClient, getPathnameFromUrl } from \"@commercengine/sdk-core\";\nimport { createDefaultPosAuthMiddleware } from \"./middleware/auth\";\nimport { isApiKeyEndpoint } from \"./utils/auth\";\nimport { buildPosURL } from \"./utils/url\";\nimport type { PosSDKOptions, SupportedDefaultHeaders } from \"../index\";\n\n/**\n * POS API client that extends the generic BaseAPIClient\n * Adds Commerce Engine POS specific authentication and token management\n */\nexport class PosAPIClient extends BaseAPIClient<\n paths,\n SupportedDefaultHeaders\n> {\n protected config: PosSDKOptions;\n private initializationPromise: Promise<void> | null = null;\n\n /**\n * Validate required configuration parameters\n * @param config - Configuration to validate\n * @throws Error with descriptive message if validation fails\n */\n private static validateConfig(config: PosSDKOptions): void {\n const errors: string[] = [];\n\n // Required fields validation\n if (!config.storeId?.trim()) {\n errors.push(\"storeId is required and cannot be empty\");\n }\n\n if (!config.apiKey?.trim()) {\n errors.push(\n \"apiKey is required for POS authentication (needed for login, device pairing, and token refresh fallbacks)\"\n );\n }\n\n // Token configuration validation\n if (config.accessToken && !config.tokenStorage && !config.refreshToken) {\n errors.push(\n \"When providing accessToken without tokenStorage, consider providing refreshToken for token refresh capability\"\n );\n }\n\n if (config.refreshToken && !config.accessToken) {\n errors.push(\n \"refreshToken cannot be provided without accessToken (orphaned refresh token)\"\n );\n }\n\n if (config.refreshToken && !config.tokenStorage) {\n errors.push(\n \"refreshToken requires tokenStorage for automatic token management\"\n );\n }\n\n // Callback validation\n if (\n (config.onTokensUpdated || config.onTokensCleared) &&\n !config.tokenStorage\n ) {\n errors.push(\n \"Token callbacks (onTokensUpdated/onTokensCleared) require tokenStorage for automatic token management\"\n );\n }\n\n // URL validation\n if (config.baseUrl && !PosAPIClient.isValidUrl(config.baseUrl)) {\n errors.push(\"baseUrl must be a valid HTTP/HTTPS URL\");\n }\n\n if (errors.length > 0) {\n throw new Error(\n `POS SDK configuration validation failed:\\n- ${errors.join(\"\\n- \")}`\n );\n }\n }\n\n /**\n * Check if a string is a valid URL\n * @param url - URL string to validate\n * @returns True if valid URL\n */\n private static isValidUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n }\n\n /**\n * Create a new PosAPIClient\n *\n * @param config - Configuration for the API client\n */\n constructor(config: PosSDKOptions) {\n // Validate required configuration first (before calling super)\n PosAPIClient.validateConfig(config);\n\n // Build base URL from Commerce Engine config\n const baseUrl = buildPosURL({\n storeId: config.storeId,\n environment: config.environment,\n baseUrl: config.baseUrl,\n });\n\n // Header transformations for POS API\n const headerTransformations = {\n customer_group_id: \"x-customer-group-id\",\n debug_mode: \"x-debug-mode\",\n // Add any other header transformations here\n } as Record<keyof SupportedDefaultHeaders, string>;\n\n // Call parent constructor with generic config\n super(\n {\n baseUrl: baseUrl,\n timeout: config.timeout,\n defaultHeaders: config.defaultHeaders,\n debug: config.debug,\n logger: config.logger,\n },\n baseUrl,\n headerTransformations\n );\n\n // Store full config for POS-specific features\n this.config = { ...config };\n\n // Set up POS-specific auth middleware\n this.setupPosAuth();\n }\n\n /**\n * Set up POS-specific authentication middleware\n */\n private setupPosAuth(): void {\n const config = this.config as PosSDKOptions;\n\n // Set up auth middleware if token storage is provided\n if (config.tokenStorage) {\n const authMiddleware = createDefaultPosAuthMiddleware({\n apiKey: config.apiKey,\n baseUrl: this.getBaseUrl(),\n tokenStorage: config.tokenStorage,\n onTokensUpdated: config.onTokensUpdated,\n onTokensCleared: config.onTokensCleared,\n storeTokenResponses: config.storeTokenResponses,\n });\n this.client.use(authMiddleware);\n\n // If initial tokens were provided, store them in tokenStorage\n if (config.accessToken) {\n this.initializationPromise = this.initializeTokens(\n config.accessToken,\n config.refreshToken\n );\n // Clear the manual tokens since we're using storage\n config.accessToken = undefined;\n config.refreshToken = undefined;\n }\n } else {\n // For manual token management, add simple header injection middleware\n this.client.use({\n onRequest: async ({ request }) => {\n const pathname = getPathnameFromUrl(request.url);\n\n // For login endpoints, use API key\n if (isApiKeyEndpoint(pathname)) {\n request.headers.set(\"X-Api-Key\", config.apiKey);\n return request;\n }\n\n // For all other endpoints, prefer access token, fallback to API key\n if (config.accessToken) {\n request.headers.set(\n \"Authorization\",\n `Bearer ${config.accessToken}`\n );\n } else if (config.apiKey) {\n request.headers.set(\"X-Api-Key\", config.apiKey);\n }\n\n return request;\n },\n });\n }\n }\n\n /**\n * Get the authorization header value\n * If using token storage, gets the current token from storage\n * Otherwise returns the manual token\n *\n * @returns The Authorization header value or empty string if no token is set\n */\n public async getAuthorizationHeader(): Promise<string> {\n // Wait for initialization to complete if using token storage\n if (this.config.tokenStorage && this.initializationPromise) {\n await this.initializationPromise;\n }\n\n if (this.config.tokenStorage) {\n const token = await this.config.tokenStorage.getAccessToken();\n return token ? `Bearer ${token}` : \"\";\n }\n return this.config.accessToken ? `Bearer ${this.config.accessToken}` : \"\";\n }\n\n /**\n * Set authentication tokens\n *\n * @param accessToken - The access token (required)\n * @param refreshToken - The refresh token (optional)\n *\n * Behavior:\n * - If tokenStorage is provided: Stores tokens for automatic management\n * - If tokenStorage is not provided: Only stores access token for manual management\n */\n public async setTokens(\n accessToken: string,\n refreshToken?: string\n ): Promise<void> {\n if (this.config.tokenStorage) {\n // Automatic token management\n await this.config.tokenStorage.setAccessToken(accessToken);\n if (refreshToken) {\n await this.config.tokenStorage.setRefreshToken(refreshToken);\n }\n } else {\n // Manual token management - only access token\n this.config.accessToken = accessToken;\n if (refreshToken) {\n console.warn(\n \"Refresh token provided but ignored in manual token management mode. Use tokenStorage for automatic management.\"\n );\n }\n }\n }\n\n /**\n * Clear all authentication tokens\n *\n * Behavior:\n * - If tokenStorage is provided: Clears both access and refresh tokens from storage\n * - If tokenStorage is not provided: Clears the manual access token\n */\n public async clearTokens(): Promise<void> {\n if (this.config.tokenStorage) {\n await this.config.tokenStorage.clearTokens();\n } else {\n this.config.accessToken = undefined;\n }\n }\n\n /**\n * Set the X-Api-Key header\n *\n * @param apiKey - The API key to set\n */\n public setApiKey(apiKey: string): void {\n this.config.apiKey = apiKey;\n }\n\n /**\n * Initialize tokens in storage (private helper method)\n */\n private async initializeTokens(\n accessToken: string,\n refreshToken?: string\n ): Promise<void> {\n try {\n if (this.config.tokenStorage) {\n await this.config.tokenStorage.setAccessToken(accessToken);\n if (refreshToken) {\n await this.config.tokenStorage.setRefreshToken(refreshToken);\n }\n }\n } catch (error) {\n console.warn(\"Failed to initialize tokens in storage:\", error);\n }\n }\n\n}\n","import { PosAPIClient } from \"./client\";\nimport type { ApiResult } from \"@commercengine/sdk-core\";\nimport type {\n // Auth types\n LoginPosDeviceWithEmailBody,\n LoginPosDeviceWithEmailContent,\n LoginPosDeviceWithPhoneBody,\n LoginPosDeviceWithPhoneContent,\n LoginPosDeviceWithWhatsappBody,\n LoginPosDeviceWithWhatsappContent,\n PairPosDeviceContent,\n RefreshPosAccessTokenBody,\n RefreshPosAccessTokenContent,\n VerifyPosLoginOtpBody,\n VerifyPosLoginOtpContent,\n LogoutFromPosDeviceResponse,\n\n // Devices\n PairPosDeviceBody,\n ListPosDevicesContent,\n ClaimPosDevicePathParams,\n UnclaimPosDevicePathParams,\n ClaimPosDeviceResponse,\n UnclaimPosDeviceResponse,\n\n // Cart types\n PosCreateCartBody,\n PosCreateCartContent,\n PosGetCartPathParams,\n PosGetCartContent,\n PosDeleteCartPathParams,\n PosDeleteCartResponse,\n PosUpdateCartPathParams,\n PosUpdateCartBody,\n PosUpdateCartContent,\n PosGetUserCartPathParams,\n PosGetUserCartContent,\n\n // Cart address\n PosCreateCartAddressPathParams,\n PosCreateCartAddressBody,\n PosCreateCartAddressContent,\n\n // Coupons\n PosListCouponsContent,\n PosListCouponsHeaderParams,\n PosApplyCouponPathParams,\n PosApplyCouponBody,\n PosApplyCouponContent,\n PosRemoveCouponPathParams,\n PosRemoveCouponContent,\n PosEvaluateCouponsPathParams,\n PosEvaluateCouponsContent,\n\n // Promotions\n PosListPromotionsContent,\n PosListPromotionsHeaderParams,\n PosEvaluatePromotionsPathParams,\n PosEvaluatePromotionsContent,\n\n // Credit balance\n PosRedeemCreditBalancePathParams,\n PosRedeemCreditBalanceBody,\n PosRedeemCreditBalanceContent,\n PosRemoveCreditBalancePathParams,\n PosRemoveCreditBalanceContent,\n\n // Loyalty points\n PosRedeemLoyaltyPointsPathParams,\n PosRedeemLoyaltyPointsBody,\n PosRedeemLoyaltyPointsContent,\n PosRemoveLoyaltyPointsPathParams,\n PosRemoveLoyaltyPointsContent,\n\n // Fulfillment\n PosUpdateFulfillmentPreferencePathParams,\n PosUpdateFulfillmentPreferenceBody,\n PosUpdateFulfillmentPreferenceResponse,\n PosGetFulfillmentOptionsBody,\n PosGetFulfillmentOptionsContent,\n\n // Customer\n UpdatePosCartCustomerPathParams,\n UpdatePosCartCustomerBody,\n UpdatePosCartCustomerContent,\n\n // Orders\n CreatePosOrderBody,\n CreatePosOrderContent,\n\n // Payment\n PosGetPaymentStatusContent,\n PosGetPaymentStatusPathParams,\n\n // Catalog types\n PosListCategoriesContent,\n PosListCategoriesQuery,\n PosListProductsContent,\n PosListProductsQuery,\n PosListProductsHeaderParams,\n PosListCrosssellProductsContent,\n PosListCrosssellProductsQuery,\n PosListCrosssellProductsHeaderParams,\n PosSearchProductsBody,\n PosSearchProductsContent,\n PosSearchProductsHeaderParams,\n PosListSimilarProductsContent,\n PosListSimilarProductsQuery,\n PosListSimilarProductsHeaderParams,\n PosListUpsellProductsContent,\n PosListUpsellProductsQuery,\n PosListUpsellProductsHeaderParams,\n PosGetProductDetailPathParams,\n PosGetProductDetailQuery,\n PosGetProductDetailContent,\n PosGetProductDetailHeaderParams,\n PosListProductVariantsPathParams,\n PosListProductVariantsQuery,\n PosListProductVariantsContent,\n PosListProductVariantsHeaderParams,\n PosGetVariantDetailPathParams,\n PosGetVariantDetailQuery,\n PosGetVariantDetailContent,\n PosGetVariantDetailHeaderParams,\n PosListSkusContent,\n PosListSkusQuery,\n PosListSkusHeaderParams,\n ListPosLocationsContent,\n GetPosUserPathParams,\n GetPosUserContent,\n UnclaimPosDeviceContent,\n ClaimPosDeviceContent,\n LoginPosDeviceWithEmailHeaderParams,\n LoginPosDeviceWithPhoneHeaderParams,\n LoginPosDeviceWithWhatsappHeaderParams,\n PosUpdateFulfillmentPreferenceContent,\n\n // Payments\n PosListPaymentMethodsQuery,\n PosListPaymentMethodsContent,\n PosVerifyVpaQuery,\n PosVerifyVpaContent,\n PosGetCardInfoQuery,\n PosGetCardInfoContent,\n PosAuthenticateDirectOtpBody,\n PosAuthenticateDirectOtpResponse,\n PosResendDirectOtpBody,\n PosResendDirectOtpContent,\n PosRetryOrderPaymentPathParams,\n PosRetryOrderPaymentBody,\n PosRetryOrderPaymentContent,\n PosCreateOrderPaymentRequestPathParams,\n PosCreateOrderPaymentRequestBody,\n PosCreateOrderPaymentRequestContent,\n\n // Customer addresses\n PosListAddressesPathParams,\n PosListAddressesContent,\n PosCreateAddressPathParams,\n PosCreateAddressBody,\n PosCreateAddressContent,\n PosUpdateAddressPathParams,\n PosUpdateAddressBody,\n PosUpdateAddressContent,\n PosDeleteAddressPathParams,\n PosDeleteAddressResponse,\n\n // Common\n PosListCountryStatesPathParams,\n PosListCountryStatesContent,\n PosListCountryPincodesPathParams,\n PosListCountryPincodesQuery,\n PosListCountryPincodesContent,\n\n // Admin Inventory types\n PosListInventoryContent,\n PosListInventoryQuery,\n PosListInventoryActivityContent,\n PosListInventoryActivityQuery,\n PosListInventoryDetailContent,\n PosListInventoryDetailQuery,\n\n // Admin Customer types\n PosListCustomersContent,\n PosListCustomersQuery,\n PosGetCustomerDetailContent,\n PosGetCustomerDetailPathParams,\n\n // Admin Order types\n PosListOrdersContent,\n PosListOrdersQuery,\n PosGetOrderDetailContent,\n PosGetOrderDetailPathParams,\n PosListOrderActivityContent,\n PosListOrderActivityPathParams,\n PosGetOrderInvoiceContent,\n PosGetOrderInvoiceQuery,\n PosGetOrderInvoicePathParams,\n PosGetOrderReceiptContent,\n PosGetOrderReceiptQuery,\n PosGetOrderReceiptPathParams,\n PosListOrderShipmentsContent,\n PosListOrderShipmentsPathParams,\n\n // Admin Shipment types\n PosListShipmentsContent,\n PosListShipmentsQuery,\n PosCheckOrderInventoryContent,\n PosCheckOrderInventoryQuery,\n PosCheckOrderInventoryPathParams,\n PosRefundShortfallResponse,\n PosRefundShortfallPathParams,\n PosRefundShortfallBody,\n PosGetShipmentDetailContent,\n PosGetShipmentDetailPathParams,\n PosGetShipmentActivitiesContent,\n PosGetShipmentActivitiesPathParams,\n PosGetShipmentInvoiceContent,\n PosGetShipmentInvoiceQuery,\n PosGetShipmentInvoicePathParams,\n PosUpdateShipmentContent,\n PosUpdateShipmentPathParams,\n PosUpdateShipmentBody,\n PosCreateReplacementShipmentResponse,\n PosCreateReplacementShipmentPathParams,\n PosCreateReplacementShipmentBody,\n} from \"../types/pos-api-types\";\n\n/**\n * Client for interacting with POS endpoints\n * Single client that handles all POS operations including auth, cart, orders, etc.\n */\nexport class PosClient extends PosAPIClient {\n // ===============================\n // AUTHENTICATION ENDPOINTS\n // ===============================\n\n /**\n * Login with email address\n * @param body - Login credentials containing location ID and email\n * @returns Promise with OTP token and action\n * @example\n * ```typescript\n * const { data, error } = await pos.loginWithEmail({\n * location_id: \"pos-location-123\",\n * email: \"staff@example.com\"\n * });\n *\n * if (error) {\n * console.error(\"Login failed:\", error.message);\n * } else {\n * console.log(\"OTP sent:\", data.otp_token);\n * console.log(\"Action:\", data.otp_action);\n * // Use the otp_token to verify OTP\n * }\n * ```\n */\n public async loginWithEmail(\n body: LoginPosDeviceWithEmailBody,\n headers?: LoginPosDeviceWithEmailHeaderParams\n ): Promise<ApiResult<LoginPosDeviceWithEmailContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/login/email\", {\n body: body,\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Login with phone number\n * @param body - Login credentials containing location ID and phone\n * @returns Promise with OTP token and action\n * @example\n * ```typescript\n * const { data, error } = await pos.loginWithPhone({\n * location_id: \"pos-location-123\",\n * phone: \"234567890\",\n * country_code: \"+91\" // default is +91\n * });\n *\n * if (error) {\n * console.error(\"Login failed:\", error.message);\n * } else {\n * console.log(\"OTP sent:\", data.otp_token);\n * console.log(\"Action:\", data.otp_action);\n * // Use the otp_token to verify OTP\n * }\n * ```\n */\n public async loginWithPhone(\n body: LoginPosDeviceWithPhoneBody,\n headers?: LoginPosDeviceWithPhoneHeaderParams\n ): Promise<ApiResult<LoginPosDeviceWithPhoneContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/login/phone\", {\n body,\n params: { header: mergedHeaders },\n })\n );\n }\n\n /**\n * Login with WhatsApp\n * @param body - Login credentials containing location ID and phone\n * @returns Promise with OTP token and action\n * @example\n * ```typescript\n * const { data, error } = await pos.loginWithWhatsapp({\n * location_id: \"pos-location-123\",\n * phone: \"234567890\",\n * country_code: \"+91\" // default is +91\n * });\n *\n * if (error) {\n * console.error(\"WhatsApp login failed:\", error.message);\n * } else {\n * console.log(\"WhatsApp OTP sent:\", data.otp_token);\n * console.log(\"Action:\", data.otp_action);\n * // Use the otp_token to verify OTP\n * }\n * ```\n */\n public async loginWithWhatsapp(\n body: LoginPosDeviceWithWhatsappBody,\n headers?: LoginPosDeviceWithWhatsappHeaderParams\n ): Promise<ApiResult<LoginPosDeviceWithWhatsappContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/login/whatsapp\", {\n body,\n params: { header: mergedHeaders },\n })\n );\n }\n\n /**\n * Verify OTP\n * @param body - OTP verification data\n * @returns Promise with user info and tokens\n * @example\n * ```typescript\n * const { data, error } = await pos.verifyOtp({\n * otp_token: \"otp-token-from-login\",\n * otp: \"123456\",\n * otp_action: \"login\"\n * });\n *\n * if (error) {\n * console.error(\"OTP verification failed:\", error.message);\n * } else {\n * console.log(\"Login successful:\", data.user);\n * console.log(\"Access token:\", data.access_token);\n * console.log(\"Refresh token:\", data.refresh_token);\n * // Tokens are automatically stored by the SDK\n * }\n * ```\n */\n public async verifyOtp(\n body: VerifyPosLoginOtpBody\n ): Promise<ApiResult<VerifyPosLoginOtpContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/verify-otp\", { body })\n );\n }\n\n /**\n * Refresh POS access token\n * @param body - Refresh token data\n * @returns Promise with new tokens\n * @example\n * ```typescript\n * const { data, error } = await pos.refreshAccessToken({\n * refresh_token: \"refresh-token-here\"\n * });\n *\n * if (error) {\n * console.error(\"Token refresh failed:\", error.message);\n * } else {\n * console.log(\"New access token:\", data.access_token);\n * console.log(\"New refresh token:\", data.refresh_token);\n * // New tokens are automatically stored by the SDK\n * }\n * ```\n */\n public async refreshAccessToken(\n body: RefreshPosAccessTokenBody\n ): Promise<ApiResult<RefreshPosAccessTokenContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/refresh-token\", { body })\n );\n }\n\n /**\n * Get POS user details\n * @param pathParams - User ID\n * @returns Promise with user details\n * @example\n * ```typescript\n * const { data, error } = await pos.getUser({\n * id: \"01H9USER12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get user:\", error.message);\n * } else {\n * console.log(\"User:\", data.user);\n * }\n * ```\n */\n public async getUser(\n pathParams: GetPosUserPathParams\n ): Promise<ApiResult<GetPosUserContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/users/{id}\", { params: { path: pathParams } })\n );\n }\n\n /**\n * Logout\n * @returns Promise with logout confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.logout();\n *\n * if (error) {\n * console.error(\"Logout failed:\", error.message);\n * } else {\n * console.log(\"Logout message:\", data.message);\n * console.log(\"Success:\", data.success);\n * // Tokens are automatically cleared by the SDK\n * }\n * ```\n */\n public async logout(): Promise<ApiResult<LogoutFromPosDeviceResponse>> {\n return this.executeRequest(() => this.client.POST(\"/pos/auth/logout\"));\n }\n\n // ===============================\n // DEVICE ENDPOINTS\n // ===============================\n\n /**\n * List store locations\n * @returns Promise with list of locations\n * @example\n * ```typescript\n * const { data, error } = await pos.listLocations();\n * if (error) {\n * console.error(\"Failed to list locations:\", error.message);\n * } else {\n * console.log(\"Locations:\", data.locations);\n * }\n * ```\n */\n public async listLocations(): Promise<ApiResult<ListPosLocationsContent>> {\n return this.executeRequest(() => this.client.GET(\"/pos/locations\"));\n }\n\n /**\n * List devices\n * @returns Promise with list of devices\n * @example\n * ```typescript\n * const { data, error } = await pos.listDevices();\n * if (error) {\n * console.error(\"Failed to list devices:\", error.message);\n * } else {\n * console.log(\"Devices:\", data.devices);\n * }\n * ```\n */\n public async listDevices(): Promise<ApiResult<ListPosDevicesContent>> {\n return this.executeRequest(() => this.client.GET(\"/pos/devices\"));\n }\n\n /**\n * Pair POS device with pairing code\n * @param body - Pairing code received via phone/email\n * @returns Promise with device information\n * @example\n * ```typescript\n * const { data, error } = await pos.pairDevice({\n * pairing_code: \"ABC123\"\n * });\n *\n * if (error) {\n * console.error(\"Device pairing failed:\", error.message);\n * } else {\n * console.log(\"Device paired:\", data.device.id);\n * console.log(\"Device name:\", data.device.name);\n * // Store device_id for future use\n * }\n * ```\n */\n public async pairDevice(\n body: PairPosDeviceBody\n ): Promise<ApiResult<PairPosDeviceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/auth/pair-device\", { body })\n );\n }\n\n /**\n * Unclaim POS device - Unlinks a device from the user session\n * @param pathParams - Device ID\n * @returns Promise with unclaim confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.unclaimDevice({\n * id: \"01H9DEVICE12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to unclaim device:\", error.message);\n * } else {\n * console.log(\"Device unclaimed:\", data.message);\n * }\n * ```\n */\n public async unclaimDevice(\n pathParams: UnclaimPosDevicePathParams\n ): Promise<ApiResult<UnclaimPosDeviceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/devices/{id}/unclaim\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Claim POS device - Links a device to the user session\n * @param pathParams - Device ID\n * @returns Promise with claim confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.claimDevice({\n * id: \"01H9DEVICE12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to claim device:\", error.message);\n * } else {\n * console.log(\"Device claimed:\", data.message);\n * }\n * ```\n */\n public async claimDevice(\n pathParams: ClaimPosDevicePathParams\n ): Promise<ApiResult<ClaimPosDeviceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/devices/{id}/claim\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // CART ENDPOINTS\n // ===============================\n\n /**\n * Create a new cart\n * @param body - Cart creation data with items\n * @returns Promise with created cart\n * @example\n * ```typescript\n * const { data, error } = await pos.createCart({\n * items: [\n * {\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: null,\n * quantity: 2\n * },\n * {\n * product_id: \"01H9ABC67890FGHIJ\",\n * variant_id: \"01H9XYZ67890KLMNO\",\n * quantity: 1\n * }\n * ],\n * metadata: {\n * \"source\": \"pos-terminal-1\",\n * \"staff_id\": \"staff-123\"\n * }\n * });\n *\n * if (error) {\n * console.error(\"Failed to create cart:\", error.message);\n * } else {\n * console.log(\"Cart created:\", data.cart.id);\n * console.log(\"Cart total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async createCart(\n body: PosCreateCartBody\n ): Promise<ApiResult<PosCreateCartContent>> {\n return this.executeRequest(() => this.client.POST(\"/pos/carts\", { body }));\n }\n\n /**\n * Get cart details\n * @param pathParams - Cart ID\n * @returns Promise with cart details\n * @example\n * ```typescript\n * const { data, error } = await pos.getCart({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get cart:\", error.message);\n * } else {\n * const cart = data.cart;\n * console.log(\"Cart total:\", cart.grand_total);\n * console.log(\"Items count:\", cart.cart_items.length);\n * }\n * ```\n */\n public async getCart(\n pathParams: PosGetCartPathParams\n ): Promise<ApiResult<PosGetCartContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/{id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get cart details by user ID\n * @param pathParams - User ID\n * @returns Promise with cart details\n * @example\n * ```typescript\n * const { data, error } = await pos.getUserCart({\n * user_id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get user cart:\", error.message);\n * } else {\n * console.log(\"User cart ID:\", data.cart.id);\n * console.log(\"Cart value:\", data.cart.subtotal_amount);\n * }\n * ```\n */\n public async getUserCart(\n pathParams: PosGetUserCartPathParams\n ): Promise<ApiResult<PosGetUserCartContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/users/{user_id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Delete cart (remove all items)\n * @param pathParams - Cart ID\n * @returns Promise with deletion confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.deleteCart({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to delete cart:\", error.message);\n * } else {\n * console.log(\"Cart deleted:\", data.message);\n * }\n * ```\n */\n public async deleteCart(\n pathParams: PosDeleteCartPathParams\n ): Promise<ApiResult<PosDeleteCartResponse>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Add/update cart item (set quantity to 0 to remove)\n * @param pathParams - Cart ID\n * @param body - Item update data\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * // Add item to cart\n * const { data, error } = await pos.updateCart(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: null,\n * quantity: 3\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update cart:\", error.message);\n * } else {\n * console.log(\"Cart updated:\", data.cart.cart_items.length);\n * }\n *\n * // Remove item from cart (set quantity to 0)\n * const { data: removeData, error: removeError } = await pos.updateCart(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: null,\n * quantity: 0\n * }\n * );\n * ```\n */\n public async updateCart(\n pathParams: PosUpdateCartPathParams,\n body: PosUpdateCartBody\n ): Promise<ApiResult<PosUpdateCartContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/items\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Update cart address (billing/shipping)\n * @param pathParams - Cart ID\n * @param body - Address data (registered user IDs or guest addresses)\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * // For registered users with saved addresses\n * const { data, error } = await pos.createCartAddress(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * billing_address_id: \"01H9ADDR12345BILL\",\n * shipping_address_id: \"01H9ADDR12345SHIP\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update cart address:\", error.message);\n * } else {\n * console.log(\"Addresses updated:\", data.message);\n * }\n *\n * // For guest checkout with new addresses\n * const { data: guestData, error: guestError } = await pos.createCartAddress(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * billing_address: {\n * first_name: \"John\",\n * last_name: \"Doe\",\n * email: \"john@example.com\",\n * phone: \"9876543210\",\n * country_code: \"+91\",\n * address_line1: \"123 Main Street\",\n * address_line2: \"Apt 4B\",\n * city: \"Mumbai\",\n * state: \"Maharashtra\",\n * pincode: \"400001\",\n * country: \"India\",\n * landmark: \"Near Station\",\n * tax_identification_number: null,\n * business_name: null\n * },\n * shipping_address: {\n * first_name: \"John\",\n * last_name: \"Doe\",\n * email: \"john@example.com\",\n * phone: \"9876543210\",\n * country_code: \"+91\",\n * address_line1: \"456 Oak Avenue\",\n * address_line2: null,\n * city: \"Pune\",\n * state: \"Maharashtra\",\n * pincode: \"411001\",\n * country: \"India\",\n * landmark: \"Near Mall\",\n * tax_identification_number: null,\n * business_name: null\n * }\n * }\n * );\n * ```\n */\n public async createCartAddress(\n pathParams: PosCreateCartAddressPathParams,\n body: PosCreateCartAddressBody\n ): Promise<ApiResult<PosCreateCartAddressContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/address\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n // ===============================\n // COUPON & PROMOTION ENDPOINTS\n // ===============================\n\n /**\n * List all available coupons\n * @param headers - Optional header parameters (customer_group_id, etc.)\n * @returns Promise with available coupons\n * @example\n * ```typescript\n * // Get all available coupons\n * const { data, error } = await pos.listCoupons();\n *\n * if (error) {\n * console.error(\"Failed to get available coupons:\", error.message);\n * } else {\n * const coupons = data.coupons || [];\n * console.log(\"Available coupons:\", coupons.length);\n * coupons.forEach(coupon => {\n * console.log(\"Coupon:\", coupon.code, \"Discount:\", coupon.discount_amount);\n * });\n * }\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listCoupons({\n * \"x-customer-group-id\": \"01H9GROUP12345ABC\" // Override default SDK config\n * });\n * ```\n */\n public async listCoupons(\n headers?: PosListCouponsHeaderParams\n ): Promise<ApiResult<PosListCouponsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/available-coupons\", {\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List all available promotions\n * @param headers - Optional header parameters (customer_group_id, etc.)\n * @returns Promise with available promotions\n * @example\n * ```typescript\n * // Get all available promotions\n * const { data, error } = await pos.listPromotions();\n *\n * if (error) {\n * console.error(\"Failed to get available promotions:\", error.message);\n * } else {\n * const promotions = data.promotions || [];\n * console.log(\"Available promotions:\", promotions.length);\n * promotions.forEach(promotion => {\n * console.log(\"Promotion:\", promotion.name, \"Type:\", promotion.promotion_type);\n * });\n * }\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listPromotions({\n * \"x-customer-group-id\": \"01H9GROUP12345ABC\" // Override default SDK config\n * });\n * ```\n */\n public async listPromotions(\n headers?: PosListPromotionsHeaderParams\n ): Promise<ApiResult<PosListPromotionsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/available-promotions\", {\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Apply coupon to cart\n * @param pathParams - Cart ID\n * @param body - Coupon code\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.applyCoupon(\n * { id: \"01H9CART12345ABCDE\" },\n * { coupon_code: \"FLAT100OFF\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to apply coupon:\", error.message);\n * } else {\n * console.log(\"Coupon applied, new total:\", data.cart.grand_total);\n * console.log(\"Discount amount:\", data.cart.coupon_discount_amount);\n * }\n * ```\n */\n public async applyCoupon(\n pathParams: PosApplyCouponPathParams,\n body: PosApplyCouponBody\n ): Promise<ApiResult<PosApplyCouponContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/coupon\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Remove coupon from cart\n * @param pathParams - Cart ID\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.removeCoupon({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to remove coupon:\", error.message);\n * } else {\n * console.log(\"Coupon removed, new total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async removeCoupon(\n pathParams: PosRemoveCouponPathParams\n ): Promise<ApiResult<PosRemoveCouponContent>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}/coupon\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Evaluate applicable/inapplicable coupons for cart\n * @param pathParams - Cart ID\n * @returns Promise with coupon evaluation results\n * @example\n * ```typescript\n * const { data, error } = await pos.evaluateCoupons({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to evaluate coupons:\", error.message);\n * } else {\n * const applicable = data.applicable_coupons || [];\n * const inapplicable = data.inapplicable_coupons || [];\n *\n * console.log(\"Applicable coupons:\", applicable.length);\n * applicable.forEach(coupon => {\n * console.log(`- ${coupon.code}: Save $${coupon.estimated_discount}`);\n * });\n *\n * console.log(\"Inapplicable coupons:\", inapplicable.length);\n * inapplicable.forEach(coupon => {\n * console.log(`- ${coupon.code}: ${coupon.reason}`);\n * });\n * }\n * ```\n */\n public async evaluateCoupons(\n pathParams: PosEvaluateCouponsPathParams\n ): Promise<ApiResult<PosEvaluateCouponsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/{id}/evaluate-coupons\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Evaluate applicable/inapplicable promotions for cart\n * @param pathParams - Cart ID\n * @returns Promise with promotion evaluation results\n * @example\n * ```typescript\n * const { data, error } = await pos.evaluatePromotions({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to evaluate promotions:\", error.message);\n * } else {\n * const applicable = data.applicable_promotions || [];\n * const inapplicable = data.inapplicable_promotions || [];\n *\n * console.log(\"Applicable promotions:\", applicable.length);\n * applicable.forEach(promo => {\n * console.log(`- ${promo.name}: ${promo.savings_message}`);\n * });\n *\n * console.log(\"Inapplicable promotions:\", inapplicable.length);\n * inapplicable.forEach(promo => {\n * console.log(`- ${promo.name}: ${promo.reason}`);\n * });\n * }\n * ```\n */\n public async evaluatePromotions(\n pathParams: PosEvaluatePromotionsPathParams\n ): Promise<ApiResult<PosEvaluatePromotionsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/carts/{id}/evaluate-promotions\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // CREDIT BALANCE ENDPOINTS\n // ===============================\n\n /**\n * Apply credit balance to cart\n * @param pathParams - Cart ID\n * @param body - Credit balance amount to use\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.redeemCreditBalance(\n * { id: \"01H9CART12345ABCDE\" },\n * { credit_balance_used: 250.00 }\n * );\n *\n * if (error) {\n * console.error(\"Failed to redeem credit balance:\", error.message);\n * } else {\n * console.log(\"Credit applied, new total:\", data.cart.grand_total);\n * console.log(\"Credit used:\", data.cart.credit_balance_used);\n * }\n * ```\n */\n public async redeemCreditBalance(\n pathParams: PosRedeemCreditBalancePathParams,\n body: PosRedeemCreditBalanceBody\n ): Promise<ApiResult<PosRedeemCreditBalanceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/credit-balance\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Remove credit balance from cart\n * @param pathParams - Cart ID\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.removeCreditBalance({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to remove credit balance:\", error.message);\n * } else {\n * console.log(\"Credit balance removed, new total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async removeCreditBalance(\n pathParams: PosRemoveCreditBalancePathParams\n ): Promise<ApiResult<PosRemoveCreditBalanceContent>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}/credit-balance\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // LOYALTY POINTS ENDPOINTS\n // ===============================\n\n /**\n * Redeem loyalty points for cart\n * @param pathParams - Cart ID\n * @param body - Loyalty points to redeem\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.redeemLoyaltyPoints(\n * { id: \"01H9CART12345ABCDE\" },\n * { loyalty_point_redeemed: 500 }\n * );\n *\n * if (error) {\n * console.error(\"Failed to redeem loyalty points:\", error.message);\n * } else {\n * console.log(\"Points redeemed, new total:\", data.cart.grand_total);\n * console.log(\"Points redeemed:\", data.cart.loyalty_points_redeemed);\n * }\n * ```\n */\n public async redeemLoyaltyPoints(\n pathParams: PosRedeemLoyaltyPointsPathParams,\n body: PosRedeemLoyaltyPointsBody\n ): Promise<ApiResult<PosRedeemLoyaltyPointsContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/loyalty-points\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Remove loyalty points from cart\n * @param pathParams - Cart ID\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.removeLoyaltyPoints({\n * id: \"01H9CART12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to remove loyalty points:\", error.message);\n * } else {\n * console.log(\"Loyalty points removed, new total:\", data.cart.grand_total);\n * }\n * ```\n */\n public async removeLoyaltyPoints(\n pathParams: PosRemoveLoyaltyPointsPathParams\n ): Promise<ApiResult<PosRemoveLoyaltyPointsContent>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/carts/{id}/loyalty-points\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // FULFILLMENT ENDPOINTS\n // ===============================\n\n /**\n * Update cart fulfillment preference (delivery/pickup)\n * @param pathParams - Cart ID\n * @param body - Fulfillment preference data\n * @returns Promise with confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.updateFulfillmentPreference(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * fulfillment_type: \"delivery\",\n * delivery_address_id: \"01H9ADDR12345ABCDE\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update fulfillment preference:\", error.message);\n * } else {\n * console.log(\"Fulfillment preference updated:\", data.message);\n * console.log(\"Success:\", data.success);\n * }\n * ```\n */\n public async updateFulfillmentPreference(\n pathParams: PosUpdateFulfillmentPreferencePathParams,\n body: PosUpdateFulfillmentPreferenceBody\n ): Promise<ApiResult<PosUpdateFulfillmentPreferenceContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/fulfillment-preference\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Get fulfillment options for cart\n * @param body - Cart data for fulfillment calculation\n * @returns Promise with fulfillment options\n * @example\n * ```typescript\n * const { data, error } = await pos.getFulfillmentOptions({\n * cart_id: \"01H9CART12345ABCDE\",\n * delivery_address: {\n * street: \"123 Main St\",\n * city: \"New York\",\n * state: \"NY\",\n * zip_code: \"10001\",\n * country: \"US\"\n * }\n * });\n *\n * if (error) {\n * console.error(\"Failed to get fulfillment options:\", error.message);\n * } else {\n * console.log(\"Available fulfillment options:\", data.options.length);\n * data.options.forEach(option => {\n * console.log(`${option.type}: ${option.name} - $${option.cost}`);\n * });\n * }\n * ```\n */\n public async getFulfillmentOptions(\n body: PosGetFulfillmentOptionsBody\n ): Promise<ApiResult<PosGetFulfillmentOptionsContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/fulfillment-options\", { body })\n );\n }\n\n // ===============================\n // CUSTOMER ENDPOINTS\n // ===============================\n\n /**\n * Update cart customer information\n * @param pathParams - Cart ID\n * @param body - Customer update data\n * @returns Promise with updated cart\n * @example\n * ```typescript\n * const { data, error } = await pos.updateCartCustomer(\n * { id: \"01H9CART12345ABCDE\" },\n * {\n * customer_id: \"01H9CUST12345ABCDE\",\n * customer_group_id: \"01H9GROUP12345ABCDE\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update cart customer:\", error.message);\n * } else {\n * console.log(\"Cart customer updated:\", data.cart.id);\n * console.log(\"Customer ID:\", data.cart.customer_id);\n * console.log(\"Customer group:\", data.cart.customer_group_id);\n * }\n * ```\n */\n public async updateCartCustomer(\n pathParams: UpdatePosCartCustomerPathParams,\n body: UpdatePosCartCustomerBody\n ): Promise<ApiResult<UpdatePosCartCustomerContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/carts/{id}/update-customer\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n // ===============================\n // ORDER ENDPOINTS\n // ===============================\n\n /**\n * Create order from cart\n * @param body - Cart ID, plus an optional payment method to create the\n * initial payment request in the same call\n * @returns Promise with the created order, `payment_required`, and gateway\n * initiation details (`payment_info`) when an auto payment method was used\n * @example\n * ```typescript\n * const { data, error } = await pos.createOrder({\n * cart_id: \"01H9CART12345ABCDE\",\n * payment_method: { payment_provider_slug: \"cash\" },\n * });\n *\n * if (error) {\n * console.error(\"Failed to create order:\", error.message);\n * } else {\n * console.log(\"Order created:\", data.order.order_number);\n * console.log(\"Payment required:\", data.payment_required);\n * }\n * ```\n */\n public async createOrder(\n body: CreatePosOrderBody\n ): Promise<ApiResult<CreatePosOrderContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/orders\", { body })\n );\n }\n\n // ===============================\n // PAYMENT ENDPOINTS\n // ===============================\n\n /**\n * Create a payment request for an order\n *\n * Use this when the order was created without a payment method, or to\n * collect the remaining `to_be_paid` amount with another method (split\n * tender). The total requested across payment requests cannot exceed the\n * order's `to_be_paid`.\n * @param pathParams - Order number\n * @param body - Amount to request and the payment method to use\n * @returns Promise with all payment records for the order, the remaining\n * `pending_amount`, and gateway initiation details (`payment_info`) when\n * an auto payment method was used\n * @example\n * ```typescript\n * const { data, error } = await pos.createOrderPaymentRequest(\n * { order_number: \"1234567890\" },\n * { amount: 500, payment_method: { payment_provider_slug: \"cash\" } }\n * );\n *\n * if (error) {\n * console.error(\"Failed to create payment request:\", error.message);\n * } else {\n * console.log(\"Pending amount:\", data.pending_amount);\n * console.log(\"Payments:\", data.payments.length);\n * }\n * ```\n */\n public async createOrderPaymentRequest(\n pathParams: PosCreateOrderPaymentRequestPathParams,\n body: PosCreateOrderPaymentRequestBody\n ): Promise<ApiResult<PosCreateOrderPaymentRequestContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/orders/{order_number}/payments\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Get payment status\n * @param pathParams - Order number\n * @returns Promise with payment status\n * @example\n * ```typescript\n * const { data, error } = await pos.getPaymentStatus({ order_number: \"1234567890\" });\n *\n * if (error) {\n * console.error(\"Failed to get payment status:\", error.message);\n * } else {\n * console.log(\"Payment status:\", data.status);\n * console.log(\"Amount paid:\", data.amount_paid);\n * console.log(\"Amount unpaid:\", data.amount_unpaid);\n * console.log(\"Retry available:\", data.is_retry_available);\n * }\n * ```\n */\n public async getPaymentStatus(\n pathParams: PosGetPaymentStatusPathParams\n ): Promise<ApiResult<PosGetPaymentStatusContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/payment-status\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * List available payment methods\n * @param query - Optional query parameters (e.g. amount for method filtering)\n * @returns Promise with the payment methods enabled for the store\n * @example\n * ```typescript\n * const { data, error } = await pos.listPaymentMethods();\n *\n * if (error) {\n * console.error(\"Failed to list payment methods:\", error.message);\n * } else {\n * data.payment_methods.forEach(method => {\n * console.log(`${method.name} (${method.code})`);\n * });\n * }\n * ```\n */\n public async listPaymentMethods(\n query?: PosListPaymentMethodsQuery\n ): Promise<ApiResult<PosListPaymentMethodsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/payments/payment-methods\", {\n params: { query },\n })\n );\n }\n\n /**\n * Verify a UPI VPA (virtual payment address)\n * @param query - The VPA to verify\n * @returns Promise with the verification result and account holder name\n * @example\n * ```typescript\n * const { data, error } = await pos.verifyVpa({ vpa: \"customer@upi\" });\n *\n * if (error) {\n * console.error(\"VPA verification failed:\", error.message);\n * } else if (data.is_valid) {\n * console.log(\"Paying to:\", data.customer_name);\n * }\n * ```\n */\n public async verifyVpa(\n query: PosVerifyVpaQuery\n ): Promise<ApiResult<PosVerifyVpaContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/payments/verify-vpa\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get card metadata for a card number prefix\n * @param query - Card number prefix (BIN) to look up\n * @returns Promise with card brand, type, and issuer details\n * @example\n * ```typescript\n * const { data, error } = await pos.getCardInfo({ card_number: \"411111\" });\n *\n * if (error) {\n * console.error(\"Card lookup failed:\", error.message);\n * } else {\n * console.log(`${data.card_brand} ${data.card_type}`);\n * }\n * ```\n */\n public async getCardInfo(\n query: PosGetCardInfoQuery\n ): Promise<ApiResult<PosGetCardInfoContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/payments/card-info\", {\n params: { query },\n })\n );\n }\n\n /**\n * Authenticate a direct (headless) card payment with an OTP\n * @param body - OTP authentication payload from the payment flow\n * @returns Promise with the authentication result\n * @example\n * ```typescript\n * const { data, error } = await pos.authenticateDirectOtp({\n * transaction_id: \"txn_123\",\n * otp: \"123456\"\n * });\n *\n * if (error) {\n * console.error(\"OTP authentication failed:\", error.message);\n * }\n * ```\n */\n public async authenticateDirectOtp(\n body: PosAuthenticateDirectOtpBody\n ): Promise<ApiResult<PosAuthenticateDirectOtpResponse>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/payments/authenticate-direct-otp\", { body })\n );\n }\n\n /**\n * Resend the OTP for a direct (headless) card payment\n * @param body - The transaction whose OTP should be resent\n * @returns Promise with the resend confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.resendDirectOtp({\n * transaction_id: \"txn_123\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to resend OTP:\", error.message);\n * }\n * ```\n */\n public async resendDirectOtp(\n body: PosResendDirectOtpBody\n ): Promise<ApiResult<PosResendDirectOtpContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/payments/resend-direct-otp\", { body })\n );\n }\n\n /**\n * Retry payment for an order whose previous payment failed or is unpaid\n * @param pathParams - Order number\n * @param body - Payment method details for the retry\n * @returns Promise with fresh payment info for the retried payment\n * @example\n * ```typescript\n * const { data, error } = await pos.retryOrderPayment(\n * { order_number: \"ORD-2024-001\" },\n * { payment_method: \"upi\" }\n * );\n *\n * if (error) {\n * console.error(\"Payment retry failed:\", error.message);\n * } else {\n * console.log(\"New payment initiated:\", data.payment_info);\n * }\n * ```\n */\n public async retryOrderPayment(\n pathParams: PosRetryOrderPaymentPathParams,\n body: PosRetryOrderPaymentBody\n ): Promise<ApiResult<PosRetryOrderPaymentContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/orders/{order_number}/retry-payment\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n // ===============================\n // CATALOG ENDPOINTS\n // ===============================\n\n /**\n * List all categories\n * @param query - Optional query parameters for filtering categories\n * @returns Promise with list of categories\n * @example\n * ```typescript\n * // Basic category listing\n * const { data, error } = await pos.listCategories();\n *\n * if (error) {\n * console.error(\"Failed to list categories:\", error.message);\n * } else {\n * console.log(\"Categories found:\", data.categories?.length || 0);\n * data.categories?.forEach(category => {\n * console.log(`Category: ${category.name} - ${category.description}`);\n * });\n * }\n *\n * // With pagination\n * const { data: catData, error: catError } = await pos.listCategories({\n * page: 1,\n * limit: 10\n * });\n * ```\n */\n public async listCategories(\n query?: PosListCategoriesQuery\n ): Promise<ApiResult<PosListCategoriesContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/categories\", {\n params: { query },\n })\n );\n }\n\n /**\n * List all products\n * @param query - Optional query parameters for filtering products\n * @param headers - Optional header parameters\n * @returns Promise with list of products\n * @example\n * ```typescript\n * // Basic product listing\n * const { data, error } = await pos.listProducts();\n *\n * if (error) {\n * console.error(\"Failed to list products:\", error.message);\n * } else {\n * console.log(\"Products found:\", data.products?.length || 0);\n * console.log(\"Pagination:\", data.pagination);\n * data.products?.forEach(product => {\n * console.log(`Product: ${product.name} - $${product.price}`);\n * });\n * }\n *\n * // With filtering and pagination\n * const { data: filteredData, error: filteredError } = await pos.listProducts({\n * page: 1,\n * limit: 20,\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" }),\n * category_slug: [\"electronics\", \"smartphones\"]\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listProducts(\n * {\n * page: 1,\n * limit: 20,\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" }),\n * category_slug: [\"electronics\", \"smartphones\"]\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async listProducts(\n query?: PosListProductsQuery,\n headers?: PosListProductsHeaderParams\n ): Promise<ApiResult<PosListProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List cross-sell products\n * @param query - Query parameters with product IDs for cross-sell recommendations\n * @param headers - Optional header parameters\n * @returns Promise with cross-sell products\n * @example\n * ```typescript\n * // Basic usage - get cross-sell products for cart items\n * const { data, error } = await pos.listCrosssellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\", \"prod_01H9ABC67890FGHIJ\"]\n * });\n *\n * // Advanced usage with pagination and custom sorting\n * const { data, error } = await pos.listCrosssellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 10,\n * sort_by: '{\"price\":\"asc\"}'\n * });\n *\n * // Override customer group ID for this specific request\n * const { data, error } = await pos.listCrosssellProducts(\n * {\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 10\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get cross-sell products:\", error.message);\n * } else {\n * console.log(\"Cross-sell products found:\", data.products.length);\n * console.log(\"Pagination:\", data.pagination);\n * data.products.forEach(product => {\n * console.log(`Product: ${product.name} - ${product.price}`);\n * });\n * }\n * ```\n */\n public async listCrosssellProducts(\n query: PosListCrosssellProductsQuery,\n headers?: PosListCrosssellProductsHeaderParams\n ): Promise<ApiResult<PosListCrosssellProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/cross-sell\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Search products\n * @param body - Search criteria and parameters\n * @param headers - Optional header parameters\n * @returns Promise with search results including SKUs, facet distribution, facet stats, and pagination\n * @example\n * ```typescript\n * // Basic search\n * const { data, error } = await pos.searchProducts({\n * query: \"smartphone\",\n * page: 1,\n * limit: 20\n * });\n *\n * if (error) {\n * console.error(\"Failed to search products:\", error.message);\n * } else {\n * console.log(\"Search results:\", data.skus?.length || 0, \"products found\");\n * console.log(\"Facet distribution:\", data.facet_distribution);\n * console.log(\"Facet stats:\", data.facet_stats);\n * console.log(\"Pagination:\", data.pagination);\n *\n * data.skus?.forEach(sku => {\n * console.log(`Found: ${sku.product_name} - ${sku.pricing?.selling_price}`);\n * });\n * }\n *\n * // With filter (string expression — Meilisearch syntax)\n * const { data: filtered, error: filteredError } = await pos.searchProducts({\n * query: \"laptop\",\n * filter: \"pricing.selling_price 500 TO 2000 AND product_type = physical\",\n * sort: [\"pricing.selling_price:asc\"],\n * facets: [\"product_type\", \"categories.name\", \"tags\"],\n * page: 1,\n * limit: 10\n * });\n *\n * // With filter (array of conditions — combined with AND)\n * const { data: arrayFiltered, error: arrayError } = await pos.searchProducts({\n * query: \"shoes\",\n * filter: [\"product_type = physical\", \"rating >= 4\", \"stock_available > 0\"],\n * sort: [\"rating:desc\"],\n * facets: [\"*\"],\n * page: 1,\n * limit: 25\n * });\n *\n * // With filter (nested arrays — inner arrays use OR, outer uses AND)\n * const { data: nestedFiltered, error: nestedError } = await pos.searchProducts({\n * query: \"headphones\",\n * filter: [\n * \"pricing.selling_price 50 TO 300\",\n * [\"product_type = physical\", \"product_type = bundle\"]\n * ],\n * page: 1,\n * limit: 25\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.searchProducts(\n * {\n * query: \"laptop\",\n * filter: \"categories.name = computers\",\n * page: 1,\n * limit: 20\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async searchProducts(\n body: PosSearchProductsBody,\n headers?: PosSearchProductsHeaderParams\n ): Promise<ApiResult<PosSearchProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.POST(\"/pos/catalog/products/search\", {\n body,\n params: {\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List similar products\n * @param query - Query parameters with product ID for similarity recommendations\n * @param headers - Optional header parameters\n * @returns Promise with similar products\n * @example\n * ```typescript\n * // Basic usage - get similar products for a specific product\n * const { data, error } = await pos.listSimilarProducts({\n * product_id: \"prod_01H9XYZ12345ABCDE\"\n * });\n *\n * // Advanced usage with pagination and custom sorting\n * const { data, error } = await pos.listSimilarProducts({\n * product_id: \"prod_01H9XYZ12345ABCDE\",\n * page: 1,\n * limit: 20,\n * sort_by: '{\"relevance\":\"desc\"}'\n * });\n *\n * // Override customer group ID for this specific request\n * const { data, error } = await pos.listSimilarProducts(\n * {\n * product_id: \"prod_01H9XYZ12345ABCDE\",\n * page: 1,\n * limit: 20\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get similar products:\", error.message);\n * } else {\n * console.log(\"Similar products found:\", data.products.length);\n * console.log(\"Pagination:\", data.pagination);\n * data.products.forEach(product => {\n * console.log(`Similar: ${product.name} - ${product.price}`);\n * });\n * }\n * ```\n */\n public async listSimilarProducts(\n query: PosListSimilarProductsQuery,\n headers?: PosListSimilarProductsHeaderParams\n ): Promise<ApiResult<PosListSimilarProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/similar\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List up-sell products\n * @param query - Query parameters with product IDs for up-sell recommendations\n * @param headers - Optional header parameters\n * @returns Promise with up-sell products\n * @example\n * ```typescript\n * // Basic usage - get up-sell products for cart items\n * const { data, error } = await pos.listUpsellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"]\n * });\n *\n * // Advanced usage with pagination and custom sorting\n * const { data, error } = await pos.listUpsellProducts({\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 15,\n * sort_by: '{\"relevance\":\"desc\"}'\n * });\n *\n * // Override customer group ID for this specific request\n * const { data, error } = await pos.listUpsellProducts(\n * {\n * product_ids: [\"prod_01H9XYZ12345ABCDE\"],\n * page: 1,\n * limit: 15\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get up-sell products:\", error.message);\n * } else {\n * console.log(\"Up-sell products found:\", data.products.length);\n * console.log(\"Pagination:\", data.pagination);\n * data.products.forEach(product => {\n * console.log(`Up-sell: ${product.name} - ${product.price}`);\n * });\n * }\n * ```\n */\n public async listUpsellProducts(\n query: PosListUpsellProductsQuery,\n headers?: PosListUpsellProductsHeaderParams\n ): Promise<ApiResult<PosListUpsellProductsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/up-sell\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Get product details\n * @param pathParams - The path parameters. Accepts product ID or product slug.\n * @param headers - Optional header parameters\n * @returns Promise with product details\n * @example\n * ```typescript\n * // Get product by ID\n * const { data, error } = await pos.getProductDetail(\n * { product_id: \"prod_123\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get product details:\", error.message);\n * } else {\n * console.log(\"Product:\", data.product.name);\n * console.log(\"Price:\", data.product.pricing?.selling_price);\n * console.log(\"Description:\", data.product.short_description);\n * }\n *\n * // Get product by slug (also accepted in place of product_id)\n * const { data: slugData, error: slugError } = await pos.getProductDetail({\n * product_id: \"detox-candy\"\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.getProductDetail(\n * { product_id: \"detox-candy\" },\n * undefined,\n * {\n * \"x-customer-group-id\": \"premium_customers\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async getProductDetail(\n pathParams: PosGetProductDetailPathParams,\n query?: PosGetProductDetailQuery,\n headers?: PosGetProductDetailHeaderParams\n ): Promise<ApiResult<PosGetProductDetailContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/{product_id}\", {\n params: {\n path: pathParams,\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * List product variants\n * @param pathParams - The path parameters. Accepts product ID or product slug.\n * @param headers - Optional header parameters\n * @returns Promise with product variants\n * @example\n * ```typescript\n * // By product ID\n * const { data, error } = await pos.listProductVariants(\n * { product_id: \"prod_123\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to list product variants:\", error.message);\n * } else {\n * console.log(\"Variants found:\", data.variants?.length || 0);\n * data.variants?.forEach(variant => {\n * console.log(`Variant: ${variant.name} - SKU: ${variant.sku} - Price: ${variant.pricing?.selling_price}`);\n * });\n * }\n *\n * // By product slug (also accepted in place of product_id)\n * const { data: slugData, error: slugError } = await pos.listProductVariants(\n * { product_id: \"detox-candy\" }\n * );\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listProductVariants(\n * { product_id: \"prod_123\" },\n * undefined,\n * {\n * \"x-customer-group-id\": \"wholesale_customers\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async listProductVariants(\n pathParams: PosListProductVariantsPathParams,\n query?: PosListProductVariantsQuery,\n headers?: PosListProductVariantsHeaderParams\n ): Promise<ApiResult<PosListProductVariantsContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/products/{product_id}/variants\", {\n params: {\n path: pathParams,\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n /**\n * Get variant details\n * @param pathParams - The path parameters. Accepts product ID or slug for product_id, and variant ID or slug for variant_id.\n * @param headers - Optional header parameters\n * @returns Promise with variant details\n * @example\n * ```typescript\n * // By product ID and variant ID\n * const { data, error } = await pos.getVariantDetail(\n * {\n * product_id: \"prod_123\",\n * variant_id: \"var_456\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get variant details:\", error.message);\n * } else {\n * console.log(\"Variant:\", data.variant.name);\n * console.log(\"SKU:\", data.variant.sku);\n * console.log(\"Price:\", data.variant.pricing?.selling_price);\n * console.log(\"Stock available:\", data.variant.stock_available);\n * }\n *\n * // By product slug and variant slug (also accepted in place of IDs)\n * const { data: slugData, error: slugError } = await pos.getVariantDetail(\n * {\n * product_id: \"detox-candy\",\n * variant_id: \"detox-candy-100g\"\n * }\n * );\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.getVariantDetail(\n * {\n * product_id: \"prod_123\",\n * variant_id: \"var_456\"\n * },\n * undefined,\n * {\n * \"x-customer-group-id\": \"wholesale_customers\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async getVariantDetail(\n pathParams: PosGetVariantDetailPathParams,\n query?: PosGetVariantDetailQuery,\n headers?: PosGetVariantDetailHeaderParams\n ): Promise<ApiResult<PosGetVariantDetailContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\n \"/pos/catalog/products/{product_id}/variants/{variant_id}\",\n {\n params: {\n path: pathParams,\n query,\n header: mergedHeaders,\n },\n }\n )\n );\n }\n\n /**\n * List all SKUs\n * @param query - Optional query parameters for filtering SKUs\n * @param headers - Optional header parameters\n * @returns Promise with list of SKUs\n * @example\n * ```typescript\n * // Basic SKU listing\n * const { data, error } = await pos.listSkus();\n *\n * if (error) {\n * console.error(\"Failed to list SKUs:\", error.message);\n * } else {\n * console.log(\"SKUs found:\", data.skus?.length || 0);\n * console.log(\"Pagination:\", data.pagination);\n * data.skus?.forEach(sku => {\n * console.log(`SKU: ${sku.sku} - Price: ${sku.price}`);\n * });\n * }\n *\n * // With pagination\n * const { data: skuData, error: skuError } = await pos.listSkus({\n * page: 1,\n * limit: 50\n * });\n *\n * // Override customer group ID for this specific request\n * const { data: overrideData, error: overrideError } = await pos.listSkus(\n * {\n * page: 1,\n * limit: 50\n * },\n * {\n * \"x-customer-group-id\": \"01H9XYZ12345USERID\" // Override default SDK config\n * }\n * );\n * ```\n */\n public async listSkus(\n query?: PosListSkusQuery,\n headers?: PosListSkusHeaderParams\n ): Promise<ApiResult<PosListSkusContent>> {\n const mergedHeaders = this.mergeHeaders(headers);\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/skus\", {\n params: {\n query,\n header: mergedHeaders,\n },\n })\n );\n }\n\n // ===============================\n // ADMIN ENDPOINTS\n // ===============================\n\n // ADMIN INVENTORY ENDPOINTS\n\n /**\n * List all inventories (Admin)\n * @param query - Optional query parameters for filtering inventories\n * @returns Promise with list of inventories\n * @example\n * ```typescript\n * // Basic inventory listing\n * const { data, error } = await pos.listInventories();\n *\n * if (error) {\n * console.error(\"Failed to list inventories:\", error.message);\n * } else {\n * console.log(\"Inventories found:\", data.content?.inventories?.length || 0);\n * data.content?.inventories?.forEach(inventory => {\n * console.log(`Product: ${inventory.product_name} - Stock: ${inventory.stock_quantity}`);\n * });\n * }\n *\n * // With pagination and filters\n * const { data: filteredData, error: filteredError } = await pos.listInventories({\n * page: 1,\n * limit: 20,\n * sort_by: JSON.stringify({ \"stock_quantity\": \"desc\" }),\n * filters: JSON.stringify({ \"product_name\": \"smartphone\" })\n * });\n * ```\n */\n public async listInventories(\n query?: PosListInventoryQuery\n ): Promise<ApiResult<PosListInventoryContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/inventories\", {\n params: { query },\n })\n );\n }\n\n /**\n * List all inventory activities (Admin)\n * @param query - Optional query parameters for filtering inventory activities\n * @returns Promise with list of inventory activities\n * @example\n * ```typescript\n * // Basic inventory activities listing\n * const { data, error } = await pos.listInventoryActivities();\n *\n * if (error) {\n * console.error(\"Failed to list inventory activities:\", error.message);\n * } else {\n * console.log(\"Activities found:\", data.content?.activities?.length || 0);\n * data.content?.activities?.forEach(activity => {\n * console.log(`Activity: ${activity.activity_type} - Product: ${activity.product_name} - Quantity: ${activity.quantity}`);\n * });\n * }\n *\n * // With pagination and filters\n * const { data: filteredData, error: filteredError } = await pos.listInventoryActivities({\n * page: 1,\n * limit: 50,\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" }),\n * filters: JSON.stringify({ \"activity_type\": \"add\" })\n * });\n * ```\n */\n public async listInventoryActivities(\n query?: PosListInventoryActivityQuery\n ): Promise<ApiResult<PosListInventoryActivityContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/inventories/activites\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get inventory detail (Admin)\n * @param query - Query parameters with product/variant information\n * @returns Promise with inventory details\n * @example\n * ```typescript\n * // Get inventory detail for a product\n * const { data, error } = await pos.getInventoryDetail({\n * product_id: \"01H9XYZ12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get inventory detail:\", error.message);\n * } else {\n * const inventory = data.content?.inventory;\n * console.log(`Product: ${inventory?.product_name}`);\n * console.log(`Stock: ${inventory?.stock_quantity}`);\n * console.log(`Warehouse details:`, inventory?.details);\n * }\n *\n * // Get inventory detail for a product variant\n * const { data: variantData, error: variantError } = await pos.getInventoryDetail({\n * product_id: \"01H9XYZ12345ABCDE\",\n * variant_id: \"01H9ABC67890FGHIJ\"\n * });\n *\n * // Get inventory detail for a specific lot/batch\n * const { data: batchData, error: batchError } = await pos.getInventoryDetail({\n * product_id: \"01H9XYZ12345ABCDE\",\n * lot_batch: \"BATCH001\"\n * });\n * ```\n */\n public async getInventoryDetail(\n query: PosListInventoryDetailQuery\n ): Promise<ApiResult<PosListInventoryDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/catalog/inventories/detail\", {\n params: { query },\n })\n );\n }\n\n // ADMIN CUSTOMER ENDPOINTS\n\n /**\n * List all customers (Admin)\n * @param query - Optional query parameters for filtering customers\n * @returns Promise with list of customers\n * @example\n * ```typescript\n * // Basic customer listing\n * const { data, error } = await pos.getCustomers();\n *\n * if (error) {\n * console.error(\"Failed to list customers:\", error.message);\n * } else {\n * console.log(\"Customers found:\", data.content?.customers?.length || 0);\n * console.log(\"Pagination:\", data.content?.pagination);\n * data.content?.customers?.forEach(customer => {\n * console.log(`Customer: ${customer.full_name} - Email: ${customer.email}`);\n * });\n * }\n *\n * // With search and pagination\n * const { data: searchData, error: searchError } = await pos.getCustomers({\n * page: 1,\n * limit: 20,\n * search: \"john@example.com\",\n * sort_by: JSON.stringify({ \"created_at\": \"desc\" })\n * });\n * ```\n */\n public async getCustomers(\n query?: PosListCustomersQuery\n ): Promise<ApiResult<PosListCustomersContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/customers\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get customer details (Admin)\n * @param pathParams - Customer ID\n * @returns Promise with customer details\n * @example\n * ```typescript\n * const { data, error } = await pos.getCustomer({\n * id: \"01H9CUST12345ABCDE\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get customer:\", error.message);\n * } else {\n * const customer = data.content?.customer;\n * console.log(`Customer: ${customer?.full_name}`);\n * console.log(`Email: ${customer?.email}`);\n * console.log(`Phone: ${customer?.phone}`);\n * console.log(`Loyalty points: ${customer?.loyalty?.points_balance}`);\n * console.log(`Total spent: ${customer?.loyalty?.lifetime_spent}`);\n * }\n * ```\n */\n public async getCustomer(\n pathParams: PosGetCustomerDetailPathParams\n ): Promise<ApiResult<PosGetCustomerDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/customers/{id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * List a customer's saved addresses (Admin)\n * @param pathParams - Customer ID\n * @returns Promise with the customer's addresses\n * @example\n * ```typescript\n * const { data, error } = await pos.listAddresses({ id: \"cust_123\" });\n *\n * if (error) {\n * console.error(\"Failed to list addresses:\", error.message);\n * } else {\n * data.addresses?.forEach(address => {\n * console.log(`${address.name}: ${address.city}, ${address.state}`);\n * });\n * }\n * ```\n */\n public async listAddresses(\n pathParams: PosListAddressesPathParams\n ): Promise<ApiResult<PosListAddressesContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/customers/{id}/addresses\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Create an address on a customer's profile (Admin)\n * @param pathParams - Customer ID\n * @param body - The address to save\n * @returns Promise with the created address\n * @example\n * ```typescript\n * const { data, error } = await pos.createAddress(\n * { id: \"cust_123\" },\n * {\n * name: \"Home\",\n * address_line_1: \"123 Main St\",\n * city: \"Mumbai\",\n * state: \"Maharashtra\",\n * country: \"India\",\n * pincode: \"400001\",\n * phone: \"9876543210\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to create address:\", error.message);\n * }\n * ```\n */\n public async createAddress(\n pathParams: PosCreateAddressPathParams,\n body: PosCreateAddressBody\n ): Promise<ApiResult<PosCreateAddressContent>> {\n return this.executeRequest(() =>\n this.client.POST(\"/pos/customers/{id}/addresses\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Update a customer's saved address (Admin)\n * @param pathParams - Customer ID and address ID\n * @param body - The address fields to update\n * @returns Promise with the updated address\n * @example\n * ```typescript\n * const { data, error } = await pos.updateAddress(\n * { id: \"cust_123\", address_id: \"addr_456\" },\n * { phone: \"9876543210\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update address:\", error.message);\n * }\n * ```\n */\n public async updateAddress(\n pathParams: PosUpdateAddressPathParams,\n body: PosUpdateAddressBody\n ): Promise<ApiResult<PosUpdateAddressContent>> {\n return this.executeRequest(() =>\n this.client.PUT(\"/pos/customers/{id}/addresses/{address_id}\", {\n params: { path: pathParams },\n body,\n })\n );\n }\n\n /**\n * Delete a customer's saved address (Admin)\n * @param pathParams - Customer ID and address ID\n * @returns Promise with the deletion confirmation\n * @example\n * ```typescript\n * const { error } = await pos.deleteAddress({\n * id: \"cust_123\",\n * address_id: \"addr_456\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to delete address:\", error.message);\n * }\n * ```\n */\n public async deleteAddress(\n pathParams: PosDeleteAddressPathParams\n ): Promise<ApiResult<PosDeleteAddressResponse>> {\n return this.executeRequest(() =>\n this.client.DELETE(\"/pos/customers/{id}/addresses/{address_id}\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ===============================\n // COMMON ENDPOINTS\n // ===============================\n\n /**\n * List states for a country\n * @param pathParams - ISO country code\n * @returns Promise with the country's states\n * @example\n * ```typescript\n * const { data, error } = await pos.listCountryStates({\n * country_iso_code: \"IN\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to list states:\", error.message);\n * } else {\n * data.states?.forEach(state => console.log(state.name));\n * }\n * ```\n */\n public async listCountryStates(\n pathParams: PosListCountryStatesPathParams\n ): Promise<ApiResult<PosListCountryStatesContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/common/countries/{country_iso_code}/states\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * List pincodes for a country\n * @param pathParams - ISO country code\n * @param query - Optional query parameters for search and pagination\n * @returns Promise with the country's serviceable pincodes\n * @example\n * ```typescript\n * const { data, error } = await pos.listCountryPincodes(\n * { country_iso_code: \"IN\" },\n * { search: \"4000\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to list pincodes:\", error.message);\n * }\n * ```\n */\n public async listCountryPincodes(\n pathParams: PosListCountryPincodesPathParams,\n query?: PosListCountryPincodesQuery\n ): Promise<ApiResult<PosListCountryPincodesContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/common/countries/{country_iso_code}/pincodes\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n // ADMIN ORDER ENDPOINTS\n\n /**\n * List all orders (Admin)\n * @param query - Optional query parameters for filtering orders\n * @returns Promise with list of orders\n * @example\n * ```typescript\n * // Basic order listing\n * const { data, error } = await pos.listOrders();\n *\n * if (error) {\n * console.error(\"Failed to list orders:\", error.message);\n * } else {\n * console.log(\"Orders found:\", data.content?.orders?.length || 0);\n * console.log(\"Pagination:\", data.content?.pagination);\n * data.content?.orders?.forEach(order => {\n * console.log(`Order: ${order.order_number} - Status: ${order.status} - Total: ${order.grand_total}`);\n * });\n * }\n *\n * // With filters and pagination\n * const { data: filteredData, error: filteredError } = await pos.listOrders({\n * page: 1,\n * limit: 50,\n * search: \"ORD-2024\",\n * filters: JSON.stringify({ \"status\": \"delivered\", \"payment_status\": \"success\" }),\n * sort_by: JSON.stringify({ \"order_date\": \"desc\" })\n * });\n * ```\n */\n public async listOrders(\n query?: PosListOrdersQuery\n ): Promise<ApiResult<PosListOrdersContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders\", {\n params: { query },\n })\n );\n }\n\n /**\n * Get order details (Admin)\n * @param pathParams - Order number\n * @returns Promise with order details\n * @example\n * ```typescript\n * const { data, error } = await pos.getOrderDetail({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get order:\", error.message);\n * } else {\n * const order = data.content?.order;\n * console.log(`Order: ${order?.order_number}`);\n * console.log(`Status: ${order?.status}`);\n * console.log(`Payment Status: ${order?.payment_status}`);\n * console.log(`Total: ${order?.grand_total}`);\n * console.log(`Items:`, order?.order_items);\n * console.log(`Billing Address:`, order?.billing_address);\n * console.log(`Payments:`, order?.payments);\n * }\n * ```\n */\n public async getOrderDetail(\n pathParams: PosGetOrderDetailPathParams\n ): Promise<ApiResult<PosGetOrderDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * List order activity (Admin)\n * @param pathParams - Order number\n * @returns Promise with order activities\n * @example\n * ```typescript\n * const { data, error } = await pos.listOrderActivity({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get order activity:\", error.message);\n * } else {\n * console.log(\"Activities found:\", data.content?.activity?.length || 0);\n * data.content?.activity?.forEach(activity => {\n * console.log(`${activity.created_at}: ${activity.activity_type} - ${activity.comment}`);\n * console.log(`By: ${activity.user_name} (${activity.user_type})`);\n * });\n * }\n * ```\n */\n public async listOrderActivity(\n pathParams: PosListOrderActivityPathParams\n ): Promise<ApiResult<PosListOrderActivityContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/activity\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get order invoice (Admin)\n * @param pathParams - Order number\n * @param query - Optional format parameter\n * @returns Promise with order invoice\n * @example\n * ```typescript\n * // Get invoice as JSON\n * const { data, error } = await pos.getOrderInvoice(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"json\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get order invoice:\", error.message);\n * } else {\n * data.content?.invoices?.forEach(invoice => {\n * console.log(`Invoice: ${invoice.invoice_number}`);\n * console.log(`Date: ${invoice.invoice_date}`);\n * console.log(`Total: ${invoice.grand_total}`);\n * console.log(`Items:`, invoice.items);\n * });\n * }\n *\n * // Get invoice as PDF\n * const { data: pdfData, error: pdfError } = await pos.getOrderInvoice(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"pdf\" }\n * );\n * ```\n */\n public async getOrderInvoice(\n pathParams: PosGetOrderInvoicePathParams,\n query?: PosGetOrderInvoiceQuery\n ): Promise<ApiResult<PosGetOrderInvoiceContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/invoice\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n /**\n * Get order receipt (Admin)\n * @param pathParams - Order number\n * @param query - Optional format parameter\n * @returns Promise with order receipt\n * @example\n * ```typescript\n * // Get receipt as JSON\n * const { data, error } = await pos.getOrderReceipt(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"json\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get order receipt:\", error.message);\n * } else {\n * const receipt = data.content?.order_receipt;\n * console.log(`Order: ${receipt?.order_number}`);\n * console.log(`Date: ${receipt?.order_date}`);\n * console.log(`Total: ${receipt?.grand_total}`);\n * console.log(`Items:`, receipt?.order_items);\n * console.log(`Payments:`, receipt?.payments);\n * }\n *\n * // Get receipt as PDF\n * const { data: pdfData, error: pdfError } = await pos.getOrderReceipt(\n * { order_number: \"ORD-2024-001234\" },\n * { format: \"pdf\" }\n * );\n * ```\n */\n public async getOrderReceipt(\n pathParams: PosGetOrderReceiptPathParams,\n query?: PosGetOrderReceiptQuery\n ): Promise<ApiResult<PosGetOrderReceiptContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/receipt\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n /**\n * Get order shipments (Admin)\n * @param pathParams - Order number\n * @returns Promise with order shipments\n * @example\n * ```typescript\n * const { data, error } = await pos.getOrderShipments({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get order shipments:\", error.message);\n * } else {\n * const shipment = data.content?.shipment;\n * console.log(`Order: ${shipment?.order_number}`);\n * console.log(`Order Status: ${shipment?.order_status}`);\n * console.log(`Payment Status: ${shipment?.payment_status}`);\n * console.log(`Customer: ${shipment?.customer_name}`);\n * console.log(`Shipments:`, shipment?.shipments);\n * console.log(`Allowed Actions:`, shipment?.allowed_actions);\n * }\n * ```\n */\n public async getOrderShipments(\n pathParams: PosListOrderShipmentsPathParams\n ): Promise<ApiResult<PosListOrderShipmentsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/orders/{order_number}/shipments\", {\n params: { path: pathParams },\n })\n );\n }\n\n // ADMIN SHIPMENT ENDPOINTS\n\n /**\n * List all shipments (Admin)\n * @param query - Optional query parameters for filtering shipments\n * @returns Promise with list of shipments\n * @example\n * ```typescript\n * // Basic shipment listing\n * const { data, error } = await pos.listShipments();\n *\n * if (error) {\n * console.error(\"Failed to list shipments:\", error.message);\n * } else {\n * console.log(\"Shipments found:\", data.content?.shipments?.length || 0);\n * console.log(\"Pagination:\", data.content?.pagination);\n * data.content?.shipments?.forEach(shipment => {\n * console.log(`Shipment: ${shipment.shipment_number} - Status: ${shipment.status}`);\n * console.log(`Order: ${shipment.order_number} - AWB: ${shipment.awb_no}`);\n * });\n * }\n *\n * // With filters and search\n * const { data: filteredData, error: filteredError } = await pos.listShipments({\n * page: 1,\n * limit: 25,\n * search: \"SHIP-2024\",\n * filters: JSON.stringify({ \"status\": \"shipped\" }),\n * sort_by: JSON.stringify({ \"shipped_date\": \"desc\" })\n * });\n * ```\n */\n public async listShipments(\n query?: PosListShipmentsQuery\n ): Promise<ApiResult<PosListShipmentsContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments\", {\n params: { query },\n })\n );\n }\n\n /**\n * Check inventory for order (Admin)\n * @param pathParams - Order number\n * @param query - Optional shipment number and fulfillment type to evaluate against.\n * Defaults to the order's `unscheduled` shipment and that shipment's own\n * `fulfillment_type` when omitted.\n * @returns Promise with inventory check results\n * @example\n * ```typescript\n * // Check the order's unscheduled shipment\n * const { data, error } = await pos.checkInventory({\n * order_number: \"ORD-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to check inventory:\", error.message);\n * } else {\n * const inventory = data.inventory;\n * console.log(`Inventory Status: ${inventory?.inventory_status}`);\n * console.log(`Shipment Items:`, inventory?.shipment_items);\n * console.log(`Recommended Warehouses:`, inventory?.recommended_warehouses);\n * console.log(`Inventory Detail:`, inventory?.inventory_detail);\n * console.log(`Allowed Actions:`, inventory?.allowed_actions);\n * }\n *\n * // Check a specific shipment, evaluated as an in-store collection\n * const { data: pickupData } = await pos.checkInventory(\n * { order_number: \"ORD-2024-001234\" },\n * {\n * shipment_number: \"SHIP-2024-001234\",\n * fulfillment_type: \"collect-in-store\"\n * }\n * );\n *\n * console.log(`Can fulfill from store:`, pickupData?.inventory?.inventory_status);\n * ```\n */\n public async checkInventory(\n pathParams: PosCheckOrderInventoryPathParams,\n query?: PosCheckOrderInventoryQuery\n ): Promise<ApiResult<PosCheckOrderInventoryContent>> {\n return this.executeRequest(() =>\n this.client.GET(\n \"/pos/orders/{order_number}/check-inventory\",\n {\n params: { path: pathParams, query },\n }\n )\n );\n }\n\n /**\n * Refund shortfall for order (Admin)\n * @param pathParams - Order number\n * @param body - Refund details\n * @returns Promise with refund confirmation\n * @example\n * ```typescript\n * const { data, error } = await pos.refundShortfall(\n * { order_number: \"ORD-2024-001234\" },\n * {\n * items: [\n * {\n * sku: \"SKU-123\",\n * quantity: 2,\n * free_quantity: 0\n * }\n * ],\n * payment_method: \"original-payment-mode\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to process refund:\", error.message);\n * } else {\n * console.log(\"Refund processed:\", data.message);\n * console.log(\"Success:\", data.success);\n * }\n *\n * // Refund to bank transfer\n * const { data: bankData, error: bankError } = await pos.refundShortfall(\n * { order_number: \"ORD-2024-001234\" },\n * {\n * items: [{ sku: \"SKU-123\", quantity: 1 }],\n * payment_method: \"bank-transfer\",\n * bank_account_id: \"BANK_ACC_123\"\n * }\n * );\n * ```\n */\n public async refundShortfall(\n pathParams: PosRefundShortfallPathParams,\n body: PosRefundShortfallBody\n ): Promise<ApiResult<PosRefundShortfallResponse>> {\n return this.executeRequest(() =>\n this.client.POST(\n \"/pos/shipping/shipments/{order_number}/refund-shortfall\",\n {\n params: { path: pathParams },\n body,\n }\n )\n );\n }\n\n /**\n * Get shipment details (Admin)\n * @param pathParams - Shipment reference number\n * @returns Promise with shipment details\n * @example\n * ```typescript\n * const { data, error } = await pos.getShipment({\n * reference_number: \"SHIP-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get shipment:\", error.message);\n * } else {\n * const shipment = data.content?.shipment;\n * console.log(`Order: ${shipment?.order_number}`);\n * console.log(`Shipments:`, shipment?.shipments);\n * shipment?.shipments?.forEach(s => {\n * console.log(` Shipment: ${s.shipment_number} - Status: ${s.status}`);\n * console.log(` AWB: ${s.awb_no} - Courier: ${s.courier_company_name}`);\n * console.log(` Items:`, s.shipment_items);\n * });\n * }\n * ```\n */\n public async getShipment(\n pathParams: PosGetShipmentDetailPathParams\n ): Promise<ApiResult<PosGetShipmentDetailContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments/{reference_number}\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get shipment activities (Admin)\n * @param pathParams - Shipment reference number\n * @returns Promise with the shipment's activity trail\n * @example\n * ```typescript\n * const { data, error } = await pos.getShipmentActivities({\n * reference_number: \"SHIP-2024-001234\"\n * });\n *\n * if (error) {\n * console.error(\"Failed to get shipment activities:\", error.message);\n * } else {\n * data.activities?.forEach(activity => {\n * console.log(`[${activity.created_at}] ${activity.activity_type} - ${activity.status}`);\n * console.log(` ${activity.comment} (by ${activity.user_name}, ${activity.user_type})`);\n * });\n * console.log(`Total activities: ${data.pagination?.total_records}`);\n * }\n * ```\n */\n public async getShipmentActivities(\n pathParams: PosGetShipmentActivitiesPathParams\n ): Promise<ApiResult<PosGetShipmentActivitiesContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments/{reference_number}/activities\", {\n params: { path: pathParams },\n })\n );\n }\n\n /**\n * Get shipment invoice (Admin)\n * @param pathParams - Shipment reference number\n * @param query - Optional format parameter\n * @returns Promise with shipment invoice\n * @example\n * ```typescript\n * // Get shipment invoice as JSON\n * const { data, error } = await pos.getShipmentInvoice(\n * { reference_number: \"SHIP-2024-001234\" },\n * { format: \"json\" }\n * );\n *\n * if (error) {\n * console.error(\"Failed to get shipment invoice:\", error.message);\n * } else {\n * const invoice = data.content?.invoice;\n * console.log(`Invoice: ${invoice?.invoice_number}`);\n * console.log(`Date: ${invoice?.invoice_date}`);\n * console.log(`Total: ${invoice?.grand_total}`);\n * console.log(`Items:`, invoice?.items);\n * }\n *\n * // Get shipment invoice as PDF\n * const { data: pdfData, error: pdfError } = await pos.getShipmentInvoice(\n * { reference_number: \"SHIP-2024-001234\" },\n * { format: \"pdf\" }\n * );\n * ```\n */\n public async getShipmentInvoice(\n pathParams: PosGetShipmentInvoicePathParams,\n query?: PosGetShipmentInvoiceQuery\n ): Promise<ApiResult<PosGetShipmentInvoiceContent>> {\n return this.executeRequest(() =>\n this.client.GET(\"/pos/shipping/shipments/{reference_number}/invoice\", {\n params: { path: pathParams, query },\n })\n );\n }\n\n /**\n * Update shipment details (Admin)\n * @param pathParams - Shipment reference number\n * @param body - Shipment update data\n * @returns Promise with updated shipment\n * @example\n * ```typescript\n * const { data, error } = await pos.updateShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * status: \"shipped\",\n * awb_no: \"AWB123456789\",\n * courier_company_name: \"BlueDart\",\n * shipping_label_url: \"https://example.com/label.pdf\",\n * tracking_url: \"https://tracking.example.com/AWB123456789\",\n * eta_delivery: \"2024-01-15T10:00:00Z\",\n * shipped_date: \"2024-01-10T14:30:00Z\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to update shipment:\", error.message);\n * } else {\n * console.log(\"Shipment updated successfully:\", data.message);\n * const shipment = data.content?.shipment;\n * console.log(`Updated shipment status:`, shipment?.shipments?.[0]?.status);\n * }\n *\n * // Update delivery status\n * const { data: deliveryData, error: deliveryError } = await pos.updateShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * status: \"delivered\",\n * delivered_date: \"2024-01-15T16:45:00Z\"\n * }\n * );\n * ```\n */\n public async updateShipment(\n pathParams: PosUpdateShipmentPathParams,\n body: PosUpdateShipmentBody\n ): Promise<ApiResult<PosUpdateShipmentContent>> {\n return this.executeRequest(() =>\n this.client.PUT(\n \"/pos/shipping/shipments/{reference_number}/manual-update\",\n {\n params: { path: pathParams },\n body,\n }\n )\n );\n }\n\n /**\n * Create a replacement shipment against an existing shipment (Admin)\n * @param pathParams - Reference number of the original shipment being replaced\n * @param body - Replacement payload. Use `shipping_option: \"manual\"` to dispatch\n * outside an integrated carrier, `shipping_option: \"auto\"` to fulfill through an\n * integrated carrier with system-managed rates, or `fulfillment_type:\n * \"collect-in-store\"` when the customer picks the items up in store.\n * @returns Promise with replacement confirmation\n * @example\n * ```typescript\n * // Replacement shipped through an integrated carrier, system-packed\n * const { data, error } = await pos.createReplacementShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * fulfillment_type: \"delivery\",\n * warehouse_id: \"WH-001\",\n * shipment_items: [\n * { product_id: \"PROD-123\", variant_id: \"VAR-456\", quantity: 1 }\n * ],\n * shipping_option: \"auto\",\n * shipping_provider_id: \"SP-001\",\n * packing_option: \"auto\",\n * total_weight: 1.5,\n * reason: \"Damaged on delivery\"\n * }\n * );\n *\n * if (error) {\n * console.error(\"Failed to create replacement:\", error.message);\n * } else {\n * console.log(\"Replacement created:\", data.message);\n * }\n *\n * // Replacement dispatched manually, with explicit box packing\n * const { data: manualData } = await pos.createReplacementShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * fulfillment_type: \"delivery\",\n * warehouse_id: \"WH-001\",\n * shipment_items: [\n * { product_id: \"PROD-123\", variant_id: null, quantity: 2 }\n * ],\n * shipping_option: \"manual\",\n * shipping_provider_id: \"SP-MANUAL-01\",\n * packing_option: \"manual\",\n * boxes: [\n * {\n * box_name: \"Medium\",\n * box_length: 30,\n * box_width: 20,\n * box_height: 15,\n * box_weight: 2,\n * items_count: 2,\n * box_count: 1\n * }\n * ],\n * total_weight: 2,\n * expected_delivery_date: \"2024-01-20\",\n * tracking_link: \"https://tracking.example.com/AWB123456789\",\n * manual_shipping_charges: 120,\n * reason: \"Wrong item shipped\"\n * }\n * );\n *\n * // Replacement collected by the customer in store\n * const { data: pickupData } = await pos.createReplacementShipment(\n * { reference_number: \"SHIP-2024-001234\" },\n * {\n * fulfillment_type: \"collect-in-store\",\n * warehouse_id: \"STORE-042\",\n * shipment_items: [\n * { product_id: \"PROD-123\", variant_id: \"VAR-456\", quantity: 1 }\n * ],\n * shipping_option: \"manual\",\n * shipping_provider_id: \"SP-MANUAL-01\",\n * packing_option: \"auto\",\n * reason: \"Size exchange\"\n * }\n * );\n * ```\n */\n public async createReplacementShipment(\n pathParams: PosCreateReplacementShipmentPathParams,\n body: PosCreateReplacementShipmentBody\n ): Promise<ApiResult<PosCreateReplacementShipmentResponse>> {\n return this.executeRequest(() =>\n this.client.POST(\n \"/pos/shipping/shipments/{reference_number}/replacement\",\n {\n params: { path: pathParams },\n body,\n }\n )\n );\n }\n}\n","import { PosAPIClient } from \"./lib/client\";\nimport { type BaseSDKOptions } from \"@commercengine/sdk-core\";\nimport { Environment } from \"./lib/utils/url\";\nimport { PosClient } from \"./lib/pos\";\nimport {\n type TokenStorage,\n type RequestOwner,\n type AuthTokenPair,\n MemoryTokenStorage,\n BrowserTokenStorage,\n} from \"./lib/middleware/auth\";\nimport {\n extractUserInfoFromToken,\n getUserIdFromToken,\n isUserLoggedIn,\n isUserAuthenticated,\n getLocationIdFromToken,\n getRoleFromToken,\n getTenantIdFromToken,\n type UserInfo,\n} from \"./lib/utils/jwt\";\nimport { ResponseUtils } from \"@commercengine/sdk-core\";\n\n/**\n * Supported default headers for POS API\n */\nexport interface SupportedDefaultHeaders {\n /**\n * Customer group ID used for pricing and promotions\n */\n customer_group_id?: string;\n /**\n * Debug mode header\n */\n debug_mode?: boolean;\n}\n\n/**\n * SDK initialization options for the POS API\n */\nexport interface PosSDKOptions extends BaseSDKOptions<SupportedDefaultHeaders> {\n /**\n * Store ID for the API requests\n */\n storeId: string;\n\n /**\n * Environment to use (defaults to Production)\n * Overrides baseUrl if provided\n */\n environment?: Environment;\n\n /**\n * Custom base URL (overrides environment if provided)\n * If not provided, will be built from storeId and environment\n */\n baseUrl?: string;\n\n /**\n * X-Api-Key for authentication endpoints that require API key\n * Required for login, pair-device, and verify-otp endpoints\n * Always required even when initializing with tokens (for refresh fallbacks)\n */\n apiKey: string;\n\n /**\n * Optional initial access token\n * - If tokenStorage is provided: Used as initial token value, then managed automatically\n * - If tokenStorage is not provided: Used for manual token management\n */\n accessToken?: string;\n\n /**\n * Optional initial refresh token\n * - Only used when tokenStorage is provided\n * - Allows initialization with both access and refresh tokens\n */\n refreshToken?: string;\n\n /**\n * Optional token storage for automatic token management\n * If provided, enables automatic token refresh and management\n */\n tokenStorage?: TokenStorage;\n\n /**\n * Callback when tokens are updated (login/refresh)\n */\n onTokensUpdated?: (accessToken: string, refreshToken: string) => void;\n\n /**\n * Callback when tokens are cleared (logout/error)\n */\n onTokensCleared?: () => void;\n\n /**\n * Persist token pairs returned by verify/refresh response middleware.\n * Defaults to true. Disable when the application adopts returned pairs only\n * after its own request-ownership checks.\n */\n storeTokenResponses?: boolean;\n}\n\n/**\n * Main SDK class for the POS API\n * Provides access to all POS endpoints through a single client\n */\nexport class PosSDK {\n /**\n * Client for all POS operations (auth, cart, orders, etc.)\n */\n public readonly pos: PosClient;\n\n /**\n * Create a new PosSDK instance\n *\n * @param options - Configuration options for the SDK\n */\n constructor(options: PosSDKOptions) {\n // Convert options to internal config format\n const config: PosSDKOptions = {\n storeId: options.storeId,\n environment: options.environment,\n baseUrl: options.baseUrl,\n accessToken: options.accessToken,\n refreshToken: options.refreshToken,\n apiKey: options.apiKey,\n timeout: options.timeout,\n tokenStorage: options.tokenStorage,\n onTokensUpdated: options.onTokensUpdated,\n onTokensCleared: options.onTokensCleared,\n storeTokenResponses: options.storeTokenResponses,\n defaultHeaders: options.defaultHeaders,\n debug: options.debug,\n logger: options.logger,\n };\n\n this.pos = new PosClient(config);\n }\n\n /**\n * Set authentication tokens for the client\n *\n * @param accessToken - The access token (required)\n * @param refreshToken - The refresh token (optional)\n *\n * Behavior:\n * - If tokenStorage is provided: Stores tokens for automatic management\n * - If tokenStorage is not provided: Only stores access token for manual management\n */\n public async setTokens(\n accessToken: string,\n refreshToken?: string\n ): Promise<void> {\n await this.pos.setTokens(accessToken, refreshToken);\n }\n\n /**\n * Clear all authentication tokens from the client\n *\n * Behavior:\n * - If tokenStorage is provided: Clears both access and refresh tokens from storage\n * - If tokenStorage is not provided: Clears the manual access token\n */\n public async clearTokens(): Promise<void> {\n await this.pos.clearTokens();\n }\n\n /**\n * Set the API key for the client\n *\n * @param apiKey - The API key to set\n */\n public setApiKey(apiKey: string): void {\n this.pos.setApiKey(apiKey);\n }\n\n /**\n * Get the current access token if available\n */\n public async getAccessToken(): Promise<string | null> {\n const header = await this.pos.getAuthorizationHeader();\n return header.startsWith(\"Bearer \") ? header.substring(7) : null;\n }\n\n /**\n * Set default headers for the client\n *\n * @param headers - Default headers to set\n */\n public setDefaultHeaders(headers: SupportedDefaultHeaders): void {\n this.pos.setDefaultHeaders(headers);\n }\n\n /**\n * Get current default headers\n */\n public getDefaultHeaders(): SupportedDefaultHeaders | undefined {\n return this.pos.getDefaultHeaders();\n }\n\n /**\n * Get user information from the current access token\n *\n * @returns User information extracted from JWT token, or null if no token or invalid token\n */\n public async getUserInfo(): Promise<UserInfo | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return extractUserInfoFromToken(token);\n }\n\n /**\n * Get the current user ID from the access token\n *\n * @returns User ID (ulid) or null if no token or invalid token\n */\n public async getUserId(): Promise<string | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getUserIdFromToken(token);\n }\n\n /**\n * Check if the current user is logged in\n *\n * @returns True if user is logged in, false otherwise\n */\n public async isLoggedIn(): Promise<boolean> {\n const token = await this.getAccessToken();\n if (!token) return false;\n return isUserLoggedIn(token);\n }\n\n /**\n * Check if the current user is authenticated with POS access\n * This verifies the user has valid device and role information\n *\n * @returns True if user is authenticated for POS operations\n */\n public async isAuthenticated(): Promise<boolean> {\n const token = await this.getAccessToken();\n if (!token) return false;\n return isUserAuthenticated(token);\n }\n\n /**\n * Get the location ID from the current access token\n * This is commonly needed for POS API requests\n *\n * @returns Location ID or null if no token or invalid token\n */\n public async getLocationId(): Promise<string | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getLocationIdFromToken(token);\n }\n\n /**\n * Get the role information from the current access token\n *\n * @returns Role object with roleId, roleName, locationId, and locationName, or null if no token or invalid token\n */\n public async getRole(): Promise<{\n roleId: string;\n roleName: string;\n locationId: string;\n locationName: string;\n } | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getRoleFromToken(token);\n }\n\n /**\n * Get the tenant ID from the current access token\n *\n * @returns Tenant ID or null if no token or invalid token\n */\n public async getTenantId(): Promise<string | null> {\n const token = await this.getAccessToken();\n if (!token) return null;\n return getTenantIdFromToken(token);\n }\n}\n\n// Export the main SDK class as default\nexport default PosSDK;\n\n// Export individual clients for advanced usage\nexport { PosAPIClient, PosClient, ResponseUtils };\n\n// Export environment enum\nexport { Environment } from \"./lib/utils/url\";\n\n// Export token storage types\nexport type { TokenStorage, RequestOwner, AuthTokenPair };\nexport { MemoryTokenStorage, BrowserTokenStorage };\nexport type {\n AuthStorageLike,\n AuthTokenOwner,\n TokenAdoption,\n UnauthorizedRecovery,\n} from \"./lib/auth-token-storage\";\nexport {\n CoordinatedBrowserTokenStorage,\n RefreshRejectedError,\n RefreshUnavailableError,\n authTokenStorage,\n isRefreshFailure,\n refreshEndsSession,\n} from \"./lib/auth-token-storage\";\n\n// Export ALL types from sdk-core\nexport type * from \"@commercengine/sdk-core\";\n\n// Export POS-specific JWT types\nexport type { UserInfo } from \"./lib/utils/jwt\";\n\n// Export API types for consumer usage\nexport type { components, operations, paths } from \"./types/pos\";\nexport type * from \"./types/pos-api-types\";\n"],"mappings":"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"}