@altazion/commerce-sdk-core 26.407.7565 → 26.415.7673
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/index.cjs +12 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -82
- package/dist/index.iife.js +12 -183
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +13 -184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/client/CommerceContext.ts","../src/client/errors.ts","../src/client/CommerceHttpAdapter.ts","../src/connectivity/ConnectivityManager.ts","../src/workers/WorkerBridge.ts","../src/workers/CacheStrategy.ts","../src/offline/OfflineQueue.ts","../src/session/BrowserSessionManager.ts","../src/session/KioskSessionManager.ts","../src/session/SessionManagerFactory.ts","../src/modules/session/index.ts","../src/modules/cart/index.ts","../src/modules/catalog/index.ts","../src/modules/shipping/index.ts","../src/modules/marketing/index.ts","../src/modules/stores/index.ts","../src/client/CommerceClient.ts"],"sourcesContent":["/**\n * Mode d'exécution du SDK.\n * - `browser` : navigateur classique — le SDK gère la création de session et le cookie.\n * - `kiosk` : borne avec \"Altazion Device Shell\" — le browser embarqué gère les cookies.\n */\nexport type CommerceMode = 'browser' | 'kiosk'\n\nexport interface CommerceContextOptions {\n /** URL de base de l'API (ex. : \"https://api.monsite.com\") */\n baseUrl: string\n /** Identifiant ou URL du site web pour la création de session (mode browser) */\n siteUrl?: string\n /**\n * Clé primaire du site (alternative à siteUrl).\n * Requiert aussi rjsId.\n */\n sitePk?: number\n /** Identifiant du tenant RJS (nécessaire avec sitePk) */\n rjsId?: number\n /** Locale par défaut (ex. : \"fr-FR\") */\n locale?: string\n /** Devise par défaut (ex. : \"EUR\") */\n currency?: string\n}\n\n/**\n * Contexte partagé du SDK, instancié une seule fois et transmis\n * à tous les sous-systèmes (HttpAdapter, SessionManager, modules…).\n */\nexport class CommerceContext {\n readonly baseUrl: string\n readonly siteUrl: string | undefined\n readonly sitePk: number | undefined\n readonly rjsId: number | undefined\n readonly locale: string\n readonly currency: string\n readonly mode: CommerceMode\n\n constructor(options: CommerceContextOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.siteUrl = options.siteUrl\n this.sitePk = options.sitePk\n this.rjsId = options.rjsId\n this.locale = options.locale ?? 'fr-FR'\n this.currency = options.currency ?? 'EUR'\n this.mode = CommerceContext.detectMode()\n }\n\n private static detectMode(): CommerceMode {\n if (typeof navigator !== 'undefined' && navigator.userAgent.includes('Altazion Device Shell')) {\n return 'kiosk'\n }\n return 'browser'\n }\n}\n","/**\n * Représentation d'une réponse d'erreur ProblemDetails (RFC 9457)\n * telle que renvoyée par GlobalExceptionFilter.cs\n */\nexport interface ProblemDetails {\n type?: string\n title?: string\n status?: number\n detail?: string\n instance?: string\n [key: string]: unknown\n}\n\n/**\n * Erreur générée par l'API Altazion Commerce (HTTP 4xx / 5xx).\n */\nexport class AltazionApiError extends Error {\n readonly status: number\n readonly problem: ProblemDetails\n\n constructor(status: number, problem: ProblemDetails) {\n super(problem.detail ?? problem.title ?? `HTTP ${status}`)\n this.name = 'AltazionApiError'\n this.status = status\n this.problem = problem\n }\n}\n\n/**\n * Erreur levée lorsque le SDK est hors-ligne et ne peut pas\n * satisfaire la requête depuis le cache.\n */\nexport class OfflineError extends Error {\n constructor(message = 'Le SDK est hors-ligne et aucun cache n\\'est disponible pour cette ressource') {\n super(message)\n this.name = 'OfflineError'\n }\n}\n\n/**\n * Erreur liée à une opération sur le cache (IndexedDB, SharedWorker).\n */\nexport class CacheError extends Error {\n readonly cause: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'CacheError'\n this.cause = cause\n }\n}\n\n/**\n * Erreur levée lors du rejeu de l'OfflineQueue (conflit serveur).\n */\nexport class QueueFlushError extends Error {\n readonly failedOperationId: string\n readonly apiError: AltazionApiError\n\n constructor(operationId: string, apiError: AltazionApiError) {\n super(`Échec du rejeu de l'opération ${operationId} : ${apiError.message}`)\n this.name = 'QueueFlushError'\n this.failedOperationId = operationId\n this.apiError = apiError\n }\n}\n","import { AltazionApiError, type ProblemDetails } from './errors.js'\nimport type { CommerceContext } from './CommerceContext.js'\n\nexport interface RequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n body?: unknown\n headers?: Record<string, string>\n /** Nombre maximum de tentatives réseau (uniquement sur erreurs réseau, jamais sur 4xx) */\n maxRetries?: number\n}\n\n/**\n * Adaptateur HTTP basé sur fetch natif.\n *\n * Responsabilités :\n * - Construction des URLs à partir du baseUrl du contexte\n * - Ajout des headers standard (Content-Type, Accept, locale)\n * - credentials: 'include' pour la transmission automatique des cookies (modes browser et kiosk)\n * - Parse des réponses ProblemDetails en AltazionApiError\n * - Retry limité sur les erreurs réseau (TypeError), jamais sur les 4xx/5xx\n */\nexport class CommerceHttpAdapter {\n private readonly context: CommerceContext\n\n constructor(context: CommerceContext) {\n this.context = context\n }\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { method = 'GET', body, headers = {}, maxRetries = 2 } = options\n const url = `${this.context.baseUrl}${path}`\n\n const requestHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'Accept-Language': this.context.locale,\n ...headers\n }\n\n if (body !== undefined) {\n requestHeaders['Content-Type'] = 'application/json'\n }\n\n const init: RequestInit = {\n method,\n headers: requestHeaders,\n credentials: 'include',\n body: body !== undefined ? JSON.stringify(body) : undefined\n }\n\n let lastNetworkError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, init)\n return await this.handleResponse<T>(response)\n } catch (err) {\n // AltazionApiError n'est jamais retenté\n if (err instanceof AltazionApiError) throw err\n lastNetworkError = err\n // Petite pause exponentielle avant de réessayer (uniquement sur erreurs réseau)\n if (attempt < maxRetries) {\n await delay(150 * Math.pow(2, attempt))\n }\n }\n }\n\n throw lastNetworkError\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n if (response.ok) {\n const contentType = response.headers.get('content-type') ?? ''\n if (response.status === 204 || !contentType.includes('application/json')) {\n return undefined as unknown as T\n }\n return response.json() as Promise<T>\n }\n\n // Tenter de parser un ProblemDetails\n let problem: ProblemDetails = { status: response.status }\n try {\n const contentType = response.headers.get('content-type') ?? ''\n if (contentType.includes('application/json') || contentType.includes('application/problem+json')) {\n problem = await response.json() as ProblemDetails\n problem.status ??= response.status\n }\n } catch {\n // JSON invalide — on garde le problem minimal\n }\n\n throw new AltazionApiError(response.status, problem)\n }\n\n /** Effectue un GET et retourne T */\n get<T>(path: string, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'GET', headers })\n }\n\n /** Effectue un POST avec un body JSON et retourne T */\n post<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'POST', body, headers })\n }\n\n /** Effectue un PUT avec un body JSON et retourne T */\n put<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'PUT', body, headers })\n }\n\n /** Effectue un PATCH avec un body JSON et retourne T */\n patch<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body, headers })\n }\n\n /** Effectue un DELETE et retourne T */\n delete<T>(path: string, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'DELETE', headers })\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","export type ConnectivityStatus = 'online' | 'offline'\n\nexport type ConnectivityListener = (status: ConnectivityStatus) => void\n\n/**\n * Surveille l'état de la connexion réseau.\n *\n * - Utilise navigator.onLine comme valeur initiale\n * - Écoute les événements window 'online' / 'offline'\n * - Permet d'abonner des listeners (pattern observable léger)\n */\nexport class ConnectivityManager {\n private status: ConnectivityStatus\n private readonly listeners = new Set<ConnectivityListener>()\n\n constructor() {\n this.status = this.readOnlineStatus()\n\n if (typeof window !== 'undefined') {\n window.addEventListener('online', this.handleOnline)\n window.addEventListener('offline', this.handleOffline)\n }\n }\n\n get isOnline(): boolean {\n return this.status === 'online'\n }\n\n get isOffline(): boolean {\n return this.status === 'offline'\n }\n\n /**\n * Abonne un listener aux changements de connectivité.\n * Retourne une fonction de désabonnement.\n */\n subscribe(listener: ConnectivityListener): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n /** Libère les event listeners sur window. */\n dispose(): void {\n if (typeof window !== 'undefined') {\n window.removeEventListener('online', this.handleOnline)\n window.removeEventListener('offline', this.handleOffline)\n }\n this.listeners.clear()\n }\n\n private readOnlineStatus(): ConnectivityStatus {\n if (typeof navigator === 'undefined' || navigator.onLine === undefined) {\n return 'online' // SSR / environnement sans navigator : on suppose online\n }\n return navigator.onLine ? 'online' : 'offline'\n }\n\n private readonly handleOnline = (): void => {\n this.status = 'online'\n this.emit('online')\n }\n\n private readonly handleOffline = (): void => {\n this.status = 'offline'\n this.emit('offline')\n }\n\n private emit(status: ConnectivityStatus): void {\n for (const listener of this.listeners) {\n try {\n listener(status)\n } catch {\n // Un listener ne doit pas faire planter les autres\n }\n }\n }\n}\n","import { CacheError } from '../client/errors.js'\n\ninterface PendingRequest {\n resolve: (value: unknown) => void\n reject: (reason: unknown) => void\n}\n\n/**\n * Abstraction du canal de communication avec le SharedWorker de cache.\n *\n * - Utilise un SharedWorker si le navigateur le supporte\n * - Fallback : Map in-memory (données non persistantes, perdues au reload)\n *\n * Chaque appel retourne une Promise, résolue/rejetée via la réponse du worker.\n */\nexport class WorkerBridge {\n private port: MessagePort | null = null\n private readonly pending = new Map<string, PendingRequest>()\n private requestCounter = 0\n private readonly fallback = new Map<string, { data: unknown; expiresAt: number }>()\n private readonly usingFallback: boolean\n\n constructor() {\n this.usingFallback = !this.tryStartWorker()\n }\n\n private tryStartWorker(): boolean {\n if (typeof SharedWorker === 'undefined') return false\n\n try {\n const worker = new SharedWorker(\n new URL('./cache.worker.ts', import.meta.url),\n { type: 'module', name: 'altazion-cache-worker' }\n )\n this.port = worker.port\n this.port.addEventListener('message', this.handleMessage)\n this.port.start()\n return true\n } catch {\n return false\n }\n }\n\n private readonly handleMessage = (event: MessageEvent<{ id: string; result?: unknown; error?: string }>): void => {\n const { id, result, error } = event.data\n const pending = this.pending.get(id)\n if (!pending) return\n this.pending.delete(id)\n\n if (error !== undefined) {\n pending.reject(new CacheError(error))\n } else {\n pending.resolve(result)\n }\n }\n\n private nextId(): string {\n return String(++this.requestCounter)\n }\n\n private send(message: Record<string, unknown>): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (!this.port) {\n reject(new CacheError('Worker non initialisé'))\n return\n }\n const id = this.nextId()\n this.pending.set(id, { resolve, reject })\n this.port.postMessage({ ...message, id })\n })\n }\n\n async get<T>(key: string): Promise<T | null> {\n if (this.usingFallback) {\n const entry = this.fallback.get(key)\n if (!entry || Date.now() > entry.expiresAt) return null\n return entry.data as T\n }\n return this.send({ type: 'GET', key }) as Promise<T | null>\n }\n\n async set(key: string, data: unknown, ttlMs: number): Promise<void> {\n if (this.usingFallback) {\n this.fallback.set(key, { data, expiresAt: Date.now() + ttlMs })\n return\n }\n await this.send({ type: 'SET', key, data, ttl: ttlMs })\n }\n\n async invalidate(pattern: string): Promise<void> {\n if (this.usingFallback) {\n const regex = new RegExp(pattern)\n for (const key of this.fallback.keys()) {\n if (regex.test(key)) this.fallback.delete(key)\n }\n return\n }\n await this.send({ type: 'INVALIDATE', pattern })\n }\n\n async clearAll(): Promise<void> {\n if (this.usingFallback) {\n this.fallback.clear()\n return\n }\n await this.send({ type: 'CLEAR_ALL' })\n }\n\n dispose(): void {\n this.port?.removeEventListener('message', this.handleMessage)\n this.pending.clear()\n }\n}\n","import type { WorkerBridge } from './WorkerBridge.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\n\n/**\n * Stratégies de cache disponibles pour les requêtes HTTP.\n */\nexport type CacheStrategyName =\n | 'network-only' // Jamais de cache (mutations)\n | 'network-first' // Réseau, fallback cache si erreur réseau\n | 'cache-first' // Cache, revalidation réseau en background si périmé\n | 'stale-while-revalidate' // Retourne le cache immédiatement + revalide en arrière-plan\n\n/** TTL par stratégie, en millisecondes */\nexport const DEFAULT_TTL: Record<Exclude<CacheStrategyName, 'network-only'>, number> = {\n 'network-first': 30_000, // 30 secondes (session, panier)\n 'cache-first': 5 * 60_000, // 5 minutes (recherche)\n 'stale-while-revalidate': 60 * 60_000 // 1 heure (catalogue)\n}\n\nexport class CacheStrategy {\n constructor(\n private readonly bridge: WorkerBridge,\n private readonly http: CommerceHttpAdapter\n ) {}\n\n /**\n * Exécute la requête selon la stratégie choisie.\n *\n * @param key Clé de cache (généralement le path + params)\n * @param fetcher Fonction qui effectue la requête HTTP\n * @param strategy Stratégie à appliquer\n * @param ttlMs TTL du cache (override la valeur par défaut)\n */\n async execute<T>(\n key: string,\n fetcher: () => Promise<T>,\n strategy: CacheStrategyName,\n ttlMs?: number\n ): Promise<T> {\n switch (strategy) {\n case 'network-only':\n return fetcher()\n\n case 'network-first':\n return this.networkFirst<T>(key, fetcher, ttlMs ?? DEFAULT_TTL['network-first'])\n\n case 'cache-first':\n return this.cacheFirst<T>(key, fetcher, ttlMs ?? DEFAULT_TTL['cache-first'])\n\n case 'stale-while-revalidate':\n return this.staleWhileRevalidate<T>(key, fetcher, ttlMs ?? DEFAULT_TTL['stale-while-revalidate'])\n }\n }\n\n private async networkFirst<T>(key: string, fetcher: () => Promise<T>, ttlMs: number): Promise<T> {\n try {\n const data = await fetcher()\n await this.bridge.set(key, data, ttlMs)\n return data\n } catch (err) {\n // Erreur réseau uniquement (TypeError) : on tente le cache\n if (err instanceof TypeError) {\n const cached = await this.bridge.get<T>(key)\n if (cached !== null) return cached\n }\n throw err\n }\n }\n\n private async cacheFirst<T>(key: string, fetcher: () => Promise<T>, ttlMs: number): Promise<T> {\n const cached = await this.bridge.get<T>(key)\n if (cached !== null) return cached\n\n const data = await fetcher()\n await this.bridge.set(key, data, ttlMs)\n return data\n }\n\n private async staleWhileRevalidate<T>(key: string, fetcher: () => Promise<T>, ttlMs: number): Promise<T> {\n const cached = await this.bridge.get<T>(key)\n\n // Revalidation en arrière-plan (ne bloque pas le résultat)\n const revalidate = fetcher()\n .then((data) => this.bridge.set(key, data, ttlMs))\n .catch(() => { /* Échec silencieux : on garde le cache */ })\n\n if (cached !== null) {\n // On lance la revalidation sans attendre\n void revalidate\n return cached\n }\n\n // Pas de cache : on attend le réseau\n const data = await fetcher()\n await this.bridge.set(key, data, ttlMs)\n return data\n }\n}\n","import type { QueuedOperation } from './QueuedOperation.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\nimport { AltazionApiError, QueueFlushError } from '../client/errors.js'\n\nconst DB_NAME = 'altazion-queue'\nconst DB_VERSION = 1\nconst STORE_NAME = 'operations'\n\nexport type QueueEventType = 'enqueued' | 'flushed' | 'conflict' | 'emptied'\n\nexport interface QueueEvent {\n type: QueueEventType\n operation?: QueuedOperation\n error?: QueueFlushError\n}\n\nexport type QueueEventListener = (event: QueueEvent) => void\n\n/**\n * File d'attente persistante (IndexedDB) pour les mutations effectuées hors-ligne.\n *\n * Flux :\n * 1. `enqueue(operation)` — stocke l'opération en IndexedDB\n * 2. Au retour en ligne, `flush()` rejoue les opérations dans l'ordre d'enfilage\n * 3. En cas d'erreur 4xx (conflit) : émet un événement `conflict` et ne retire PAS l'opération\n * 4. En cas de succès : retire l'opération de la file\n */\nexport class OfflineQueue {\n private db: IDBDatabase | null = null\n private readonly listeners = new Set<QueueEventListener>()\n private counter = 0\n\n /** Abonne un listener aux événements de file. Retourne une fonction de désabonnement. */\n subscribe(listener: QueueEventListener): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n get pendingCount(): Promise<number> {\n return this.openDb().then(\n (db) =>\n new Promise<number>((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly')\n const req = tx.objectStore(STORE_NAME).count()\n req.onsuccess = () => resolve(req.result)\n req.onerror = () => reject(req.error)\n })\n )\n }\n\n async enqueue(\n method: QueuedOperation['method'],\n path: string,\n body?: unknown,\n headers?: Record<string, string>\n ): Promise<QueuedOperation> {\n const operation: QueuedOperation = {\n id: `${Date.now()}-${++this.counter}`,\n enqueuedAt: Date.now(),\n method,\n path,\n body,\n headers,\n attempts: 0\n }\n\n const db = await this.openDb()\n await this.put(db, operation)\n this.emit({ type: 'enqueued', operation })\n return operation\n }\n\n /**\n * Rejoue toutes les opérations en attente dans l'ordre d'enfilage.\n * S'arrête sur un conflit (4xx) et émet un événement `conflict`.\n */\n async flush(http: CommerceHttpAdapter): Promise<void> {\n const operations = await this.getAll()\n if (operations.length === 0) return\n\n for (const op of operations) {\n try {\n op.attempts++\n await http.request(op.path, {\n method: op.method,\n body: op.body,\n headers: op.headers\n })\n await this.remove(op.id)\n } catch (err) {\n if (err instanceof AltazionApiError && err.status >= 400 && err.status < 500) {\n const flushError = new QueueFlushError(op.id, err)\n this.emit({ type: 'conflict', operation: op, error: flushError })\n // On arrête le flush pour éviter de rejouer des opérations dépendantes\n return\n }\n // Erreur réseau ou 5xx : on met à jour l'opération et on arrête (ce n'est pas le bon moment)\n await this.put(await this.openDb(), op)\n return\n }\n }\n\n this.emit({ type: 'flushed' })\n\n const remaining = await this.pendingCount\n if (remaining === 0) {\n this.emit({ type: 'emptied' })\n }\n }\n\n private emit(event: QueueEvent): void {\n for (const listener of this.listeners) {\n try { listener(event) } catch { /* isolation */ }\n }\n }\n\n private openDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n if (this.db) { resolve(this.db); return }\n\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n\n request.onupgradeneeded = (event) => {\n const database = (event.target as IDBOpenDBRequest).result\n if (!database.objectStoreNames.contains(STORE_NAME)) {\n database.createObjectStore(STORE_NAME, { keyPath: 'id' })\n }\n }\n\n request.onsuccess = (event) => {\n this.db = (event.target as IDBOpenDBRequest).result\n resolve(this.db)\n }\n\n request.onerror = () => reject(request.error)\n })\n }\n\n private put(db: IDBDatabase, operation: QueuedOperation): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite')\n const req = tx.objectStore(STORE_NAME).put(operation)\n req.onsuccess = () => resolve()\n req.onerror = () => reject(req.error)\n })\n }\n\n private remove(id: string): Promise<void> {\n return this.openDb().then(\n (db) =>\n new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readwrite')\n const req = tx.objectStore(STORE_NAME).delete(id)\n req.onsuccess = () => resolve()\n req.onerror = () => reject(req.error)\n })\n )\n }\n\n private getAll(): Promise<QueuedOperation[]> {\n return this.openDb().then(\n (db) =>\n new Promise<QueuedOperation[]>((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, 'readonly')\n const req = tx.objectStore(STORE_NAME).getAll()\n req.onsuccess = () => {\n const ops = (req.result as QueuedOperation[]).sort(\n (a, b) => a.enqueuedAt - b.enqueuedAt\n )\n resolve(ops)\n }\n req.onerror = () => reject(req.error)\n })\n )\n }\n}\n","import type { SessionManager } from './SessionManager.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\nimport type { CommerceContext } from '../client/CommerceContext.js'\nimport type { SessionInfo } from '../types/index.js'\nimport { AltazionApiError } from '../client/errors.js'\n\n/**\n * Gestionnaire de session pour le mode navigateur classique.\n *\n * Responsabilités :\n * - Appel à POST /commerce/api/sessions/create pour créer la session\n * - La session est identifiée côté serveur via le cookie `altz_session_id`\n * (créé automatiquement par l'API et transmis grâce à credentials:'include')\n */\nexport class BrowserSessionManager implements SessionManager {\n private readonly http: CommerceHttpAdapter\n private readonly context: CommerceContext\n\n constructor(http: CommerceHttpAdapter, context: CommerceContext) {\n this.http = http\n this.context = context\n }\n\n async initialize(): Promise<SessionInfo | null> {\n // Vérifier si une session existe déjà\n try {\n const existing = await this.http.get<SessionInfo>('/commerce/api/sessions/raw')\n return existing\n } catch (err) {\n // 404 = pas de session, on en crée une\n if (err instanceof AltazionApiError && err.status === 404) {\n return this.createSession()\n }\n throw err\n }\n }\n\n async onSessionExpired(): Promise<void> {\n await this.createSession()\n }\n\n private async createSession(): Promise<SessionInfo> {\n const body = this.buildCreationRequest()\n return this.http.post<SessionInfo>('/commerce/api/sessions/create', body)\n }\n\n private buildCreationRequest(): Record<string, unknown> {\n if (this.context.sitePk !== undefined && this.context.rjsId !== undefined) {\n return { sitePk: this.context.sitePk, rjsId: this.context.rjsId }\n }\n if (this.context.siteUrl !== undefined) {\n return { siteUrl: this.context.siteUrl }\n }\n // Fallback : envoyer l'URL courante du navigateur\n const currentUrl = typeof window !== 'undefined' ? window.location.href : undefined\n return { siteUrl: currentUrl }\n }\n}\n","import type { SessionManager } from './SessionManager.js'\nimport type { SessionInfo } from '../types/index.js'\n\n/**\n * Gestionnaire de session pour le mode borne (Altazion Device Shell).\n *\n * Le browser embarqué gère intégralement les cookies de session.\n * Le SDK n'a pas à intervenir : fetch avec credentials:'include' suffit\n * pour que les cookies soient transmis automatiquement.\n *\n * Cette implémentation est un no-op intentionnel.\n */\nexport class KioskSessionManager implements SessionManager {\n async initialize(): Promise<SessionInfo | null> {\n // Le browser embarqué est responsable de la session.\n // Aucune action requise côté SDK.\n return null\n }\n\n async onSessionExpired(): Promise<void> {\n // Le browser embarqué gère le renouvellement de session.\n // Aucune action requise côté SDK.\n }\n}\n","import type { SessionManager } from './SessionManager.js'\nimport { BrowserSessionManager } from './BrowserSessionManager.js'\nimport { KioskSessionManager } from './KioskSessionManager.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\nimport type { CommerceContext } from '../client/CommerceContext.js'\n\n/**\n * Instancie le SessionManager adapté au contexte d'exécution.\n *\n * Détection du mode kiosk : présence de \"Altazion Device Shell\" dans le User-Agent.\n * Dans ce cas, le browser embarqué gère entièrement les cookies de session.\n */\nexport class SessionManagerFactory {\n static create(http: CommerceHttpAdapter, context: CommerceContext): SessionManager {\n if (context.mode === 'kiosk') {\n return new KioskSessionManager()\n }\n return new BrowserSessionManager(http, context)\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { SessionInfo } from '../../types/index.js'\n\nexport class SessionModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère les informations de la session en cours */\n getSession(): Promise<SessionInfo> {\n return this.cache.execute(\n 'session:raw',\n () => this.http.get<SessionInfo>('/commerce/api/sessions/raw'),\n 'network-first'\n )\n }\n\n /** Associe un magasin à la session */\n async associateStore(storeGuid: string): Promise<SessionInfo> {\n const result = await this.http.post<SessionInfo>(\n `/commerce/api/sessions/associate/store/${storeGuid}`\n )\n await this.cache.execute('session:raw', () => Promise.resolve(result), 'network-first')\n return result\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { OfflineQueue } from '../../offline/OfflineQueue.js'\nimport type { ConnectivityManager } from '../../connectivity/ConnectivityManager.js'\nimport type { Cart, CartValidationStatus } from '../../types/index.js'\n\nexport class CartModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy,\n private readonly queue: OfflineQueue,\n private readonly connectivity: ConnectivityManager\n ) {}\n\n /** Récupère le panier en cours */\n getCart(): Promise<Cart> {\n return this.cache.execute(\n 'cart:current',\n () => this.http.get<Cart>('/commerce/api/process/cart'),\n 'network-first'\n )\n }\n\n /** Récupère le statut de validation du panier */\n getValidationStatus(): Promise<CartValidationStatus> {\n return this.http.get<CartValidationStatus>('/commerce/api/process/cart/status/check')\n }\n\n /** Ajoute un article au panier */\n async addItem(reference: string, quantity: number, options?: Record<string, unknown>): Promise<Cart> {\n const body = { reference, quantity, ...options }\n if (this.connectivity.isOffline) {\n await this.queue.enqueue('POST', '/commerce/api/process/cart/items', body)\n // Retourner le panier depuis le cache\n return this.cache.execute('cart:current', () => this.http.get<Cart>('/commerce/api/process/cart'), 'network-first')\n }\n const cart = await this.http.post<Cart>('/commerce/api/process/cart/items', body)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Met à jour la quantité d'une ligne */\n async updateItem(lineId: string, quantity: number): Promise<Cart> {\n const body = { quantity }\n if (this.connectivity.isOffline) {\n await this.queue.enqueue('PUT', `/commerce/api/process/cart/items/${lineId}`, body)\n return this.cache.execute('cart:current', () => this.http.get<Cart>('/commerce/api/process/cart'), 'network-first')\n }\n const cart = await this.http.put<Cart>(`/commerce/api/process/cart/items/${lineId}`, body)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Supprime une ligne du panier */\n async removeItem(lineId: string): Promise<Cart> {\n if (this.connectivity.isOffline) {\n await this.queue.enqueue('DELETE', `/commerce/api/process/cart/items/${lineId}`)\n return this.cache.execute('cart:current', () => this.http.get<Cart>('/commerce/api/process/cart'), 'network-first')\n }\n const cart = await this.http.delete<Cart>(`/commerce/api/process/cart/items/${lineId}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Applique un coupon */\n async applyCoupon(code: string): Promise<Cart> {\n const cart = await this.http.post<Cart>('/commerce/api/process/cart/coupons', { code })\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Retire un coupon */\n async removeCoupon(code: string): Promise<Cart> {\n const cart = await this.http.delete<Cart>(`/commerce/api/process/cart/coupons/${encodeURIComponent(code)}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { ProductDetails, WebProduct, SearchRequest, SearchResult } from '../../types/index.js'\n\nexport class CatalogModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère le détail d'un produit par sa référence */\n getProduct(reference: string): Promise<ProductDetails> {\n return this.cache.execute(\n `catalog:product:${reference}`,\n () => this.http.get<ProductDetails>(`/commerce/api/pim/products/${encodeURIComponent(reference)}`),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère une liste de produits par leurs références */\n getProducts(references: string[]): Promise<WebProduct[]> {\n const key = `catalog:products:${references.sort().join(',')}`\n return this.cache.execute(\n key,\n () => this.http.post<WebProduct[]>('/commerce/api/pim/products/batch', { references }),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère les produits d'une catégorie */\n getCategory(categoryCode: string, pageIndex = 0, pageSize = 20): Promise<SearchResult> {\n const key = `catalog:category:${categoryCode}:${pageIndex}:${pageSize}`\n return this.cache.execute(\n key,\n () => this.http.get<SearchResult>(\n `/commerce/api/pim/categories/${encodeURIComponent(categoryCode)}/products?pageIndex=${pageIndex}&pageSize=${pageSize}`\n ),\n 'stale-while-revalidate'\n )\n }\n\n /** Effectue une recherche full-text */\n search(request: SearchRequest): Promise<SearchResult> {\n const key = `catalog:search:${JSON.stringify(request)}`\n return this.cache.execute(\n key,\n () => this.http.post<SearchResult>('/commerce/api/pim/search', request),\n 'cache-first'\n )\n }\n\n /** Récupère les suggestions de recherche (autocomplete) */\n suggest(query: string): Promise<string[]> {\n return this.cache.execute(\n `catalog:suggest:${query}`,\n () => this.http.get<string[]>(`/commerce/api/pim/search/suggest?q=${encodeURIComponent(query)}`),\n 'cache-first',\n 2 * 60_000 // 2 minutes pour les suggestions\n )\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { ShippingChoiceGroup, ShippingAddress, PickupPoint } from '../../types/index.js'\n\nexport class ShippingModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère les groupes de modes de livraison disponibles pour le panier en cours */\n getAvailableModes(): Promise<ShippingChoiceGroup[]> {\n return this.cache.execute(\n 'shipping:modes',\n () => this.http.get<ShippingChoiceGroup[]>('/commerce/api/process/cart/shipping/modes'),\n 'network-first'\n )\n }\n\n /** Sélectionne un mode de livraison */\n selectMode(shippingModeGuid: string): Promise<void> {\n return this.http.post('/commerce/api/process/cart/shipping/mode', { shippingModeGuid })\n }\n\n /** Met à jour l'adresse de livraison */\n setAddress(address: ShippingAddress): Promise<void> {\n return this.http.put('/commerce/api/process/cart/address/shipping', address)\n }\n\n /** Recherche des points relais à proximité */\n getRelayPoints(postalCode: string, countryCode = 'FR', shippingModeGuid?: string): Promise<PickupPoint[]> {\n const params = new URLSearchParams({ postalCode, countryCode })\n if (shippingModeGuid) params.set('shippingModeGuid', shippingModeGuid)\n const key = `shipping:relays:${postalCode}:${countryCode}:${shippingModeGuid ?? ''}`\n return this.cache.execute(\n key,\n () => this.http.get<PickupPoint[]>(`/commerce/api/process/shipping/relays?${params.toString()}`),\n 'cache-first',\n 10 * 60_000 // 10 minutes\n )\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { MarketingItem } from '../../types/index.js'\n\nexport class MarketingModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère un item marketing par son code */\n getItem(code: string): Promise<MarketingItem> {\n return this.cache.execute(\n `marketing:item:${code}`,\n () => this.http.get<MarketingItem>(`/commerce/api/marketing/items/${encodeURIComponent(code)}`),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère plusieurs items marketing par leurs codes */\n getItems(codes: string[]): Promise<MarketingItem[]> {\n const key = `marketing:items:${codes.sort().join(',')}`\n return this.cache.execute(\n key,\n () => this.http.post<MarketingItem[]>('/commerce/api/marketing/items/batch', { codes }),\n 'stale-while-revalidate'\n )\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { StoreWithOpeningHours } from '../../types/index.js'\n\nexport class StoresModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Recherche des magasins par coordonnées géographiques */\n findByLocation(latitude: number, longitude: number, radiusKm = 50): Promise<StoreWithOpeningHours[]> {\n const key = `stores:geo:${latitude.toFixed(4)}:${longitude.toFixed(4)}:${radiusKm}`\n return this.cache.execute(\n key,\n () => this.http.get<StoreWithOpeningHours[]>(\n `/commerce/api/stores/locator?lat=${latitude}&lon=${longitude}&radius=${radiusKm}`\n ),\n 'cache-first',\n 15 * 60_000 // 15 minutes\n )\n }\n\n /** Recherche des magasins par code postal */\n findByPostalCode(postalCode: string, countryCode = 'FR'): Promise<StoreWithOpeningHours[]> {\n const key = `stores:postal:${postalCode}:${countryCode}`\n return this.cache.execute(\n key,\n () => this.http.get<StoreWithOpeningHours[]>(\n `/commerce/api/stores/locator?postalCode=${encodeURIComponent(postalCode)}&countryCode=${encodeURIComponent(countryCode)}`\n ),\n 'cache-first',\n 15 * 60_000\n )\n }\n\n /** Récupère le détail d'un magasin par son GUID */\n getStore(storeGuid: string): Promise<StoreWithOpeningHours> {\n return this.cache.execute(\n `stores:detail:${storeGuid}`,\n () => this.http.get<StoreWithOpeningHours>(`/commerce/api/stores/${storeGuid}`),\n 'stale-while-revalidate'\n )\n }\n}\n","import { CommerceContext, type CommerceContextOptions } from './CommerceContext.js'\nimport { CommerceHttpAdapter } from './CommerceHttpAdapter.js'\nimport { ConnectivityManager } from '../connectivity/ConnectivityManager.js'\nimport { WorkerBridge } from '../workers/WorkerBridge.js'\nimport { CacheStrategy } from '../workers/CacheStrategy.js'\nimport { OfflineQueue } from '../offline/OfflineQueue.js'\nimport { SessionManagerFactory } from '../session/SessionManagerFactory.js'\nimport { SessionModule } from '../modules/session/index.js'\nimport { CartModule } from '../modules/cart/index.js'\nimport { CatalogModule } from '../modules/catalog/index.js'\nimport { ShippingModule } from '../modules/shipping/index.js'\nimport { MarketingModule } from '../modules/marketing/index.js'\nimport { StoresModule } from '../modules/stores/index.js'\nimport type { SessionManager } from '../session/SessionManager.js'\nimport type { SessionInfo } from '../types/index.js'\n\nexport { CommerceContext, type CommerceContextOptions } from './CommerceContext.js'\n\n/**\n * Point d'entrée principal du SDK Altazion Commerce.\n *\n * Usage :\n * ```ts\n * const client = new CommerceClient({ baseUrl: 'https://api.monsite.com', siteUrl: window.location.href })\n * await client.initialize()\n *\n * const cart = await client.cart.getCart()\n * ```\n */\nexport class CommerceClient {\n readonly context: CommerceContext\n readonly connectivity: ConnectivityManager\n\n readonly session: SessionModule\n readonly cart: CartModule\n readonly catalog: CatalogModule\n readonly shipping: ShippingModule\n readonly marketing: MarketingModule\n readonly stores: StoresModule\n\n private readonly http: CommerceHttpAdapter\n private readonly workerBridge: WorkerBridge\n private readonly cacheStrategy: CacheStrategy\n private readonly offlineQueue: OfflineQueue\n private readonly sessionManager: SessionManager\n\n private unsubscribeOnline: (() => void) | null = null\n\n constructor(options: CommerceContextOptions) {\n this.context = new CommerceContext(options)\n this.http = new CommerceHttpAdapter(this.context)\n this.connectivity = new ConnectivityManager()\n this.workerBridge = new WorkerBridge()\n this.cacheStrategy = new CacheStrategy(this.workerBridge, this.http)\n this.offlineQueue = new OfflineQueue()\n this.sessionManager = SessionManagerFactory.create(this.http, this.context)\n\n // Modules API\n this.session = new SessionModule(this.http, this.cacheStrategy)\n this.cart = new CartModule(this.http, this.cacheStrategy, this.offlineQueue, this.connectivity)\n this.catalog = new CatalogModule(this.http, this.cacheStrategy)\n this.shipping = new ShippingModule(this.http, this.cacheStrategy)\n this.marketing = new MarketingModule(this.http, this.cacheStrategy)\n this.stores = new StoresModule(this.http, this.cacheStrategy)\n }\n\n /**\n * Initialise le SDK :\n * - Crée la session si nécessaire (mode browser uniquement)\n * - Abonne le flush automatique de la file hors-ligne au retour en ligne\n */\n async initialize(): Promise<SessionInfo | null> {\n // Flush automatique quand on revient en ligne\n this.unsubscribeOnline = this.connectivity.subscribe(async (status) => {\n if (status === 'online') {\n await this.offlineQueue.flush(this.http)\n }\n })\n\n return this.sessionManager.initialize()\n }\n\n /**\n * Retourne vrai si le SDK est hors-ligne.\n */\n get isOffline(): boolean {\n return this.connectivity.isOffline\n }\n\n /**\n * Retourne le nombre d'opérations en attente dans la file hors-ligne.\n */\n get pendingOperationsCount(): Promise<number> {\n return this.offlineQueue.pendingCount\n }\n\n /**\n * Abonne un listener aux événements de la file hors-ligne.\n * Retourne une fonction de désabonnement.\n */\n onQueueEvent(\n listener: Parameters<OfflineQueue['subscribe']>[0]\n ): () => void {\n return this.offlineQueue.subscribe(listener)\n }\n\n /**\n * Force le vidage du cache.\n */\n clearCache(): Promise<void> {\n return this.workerBridge.clearAll()\n }\n\n /**\n * Libère les ressources (listeners, worker).\n */\n dispose(): void {\n this.unsubscribeOnline?.()\n this.connectivity.dispose()\n this.workerBridge.dispose()\n }\n}\n"],"names":["data"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/client/CommerceContext.ts","../src/client/errors.ts","../src/client/CommerceHttpAdapter.ts","../src/connectivity/ConnectivityManager.ts","../src/workers/WorkerBridge.ts","../src/workers/CacheStrategy.ts","../src/session/BrowserSessionManager.ts","../src/session/KioskSessionManager.ts","../src/session/SessionManagerFactory.ts","../src/modules/session/index.ts","../src/modules/cart/index.ts","../src/modules/catalog/index.ts","../src/modules/shipping/index.ts","../src/modules/marketing/index.ts","../src/modules/stores/index.ts","../src/client/CommerceClient.ts"],"sourcesContent":["/**\n * Mode d'exécution du SDK.\n * - `browser` : navigateur classique — le SDK gère la création de session et le cookie.\n * - `kiosk` : borne avec \"Altazion Device Shell\" — le browser embarqué gère les cookies.\n */\nexport type CommerceMode = 'browser' | 'kiosk'\n\nexport interface CommerceContextOptions {\n /** URL de base de l'API (ex. : \"https://api.monsite.com\") */\n baseUrl: string\n /** Identifiant ou URL du site web pour la création de session (mode browser) */\n siteUrl?: string\n /**\n * Clé primaire du site (alternative à siteUrl).\n * Requiert aussi rjsId.\n */\n sitePk?: number\n /** Identifiant du tenant RJS (nécessaire avec sitePk) */\n rjsId?: number\n /** Locale par défaut (ex. : \"fr-FR\") */\n locale?: string\n /** Devise par défaut (ex. : \"EUR\") */\n currency?: string\n}\n\n/**\n * Contexte partagé du SDK, instancié une seule fois et transmis\n * à tous les sous-systèmes (HttpAdapter, SessionManager, modules…).\n */\nexport class CommerceContext {\n readonly baseUrl: string\n readonly siteUrl: string | undefined\n readonly sitePk: number | undefined\n readonly rjsId: number | undefined\n readonly locale: string\n readonly currency: string\n readonly mode: CommerceMode\n\n constructor(options: CommerceContextOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.siteUrl = options.siteUrl\n this.sitePk = options.sitePk\n this.rjsId = options.rjsId\n this.locale = options.locale ?? 'fr-FR'\n this.currency = options.currency ?? 'EUR'\n this.mode = CommerceContext.detectMode()\n }\n\n private static detectMode(): CommerceMode {\n if (typeof navigator !== 'undefined' && navigator.userAgent.includes('Altazion Device Shell')) {\n return 'kiosk'\n }\n return 'browser'\n }\n}\n","/**\n * Représentation d'une réponse d'erreur ProblemDetails (RFC 9457)\n * telle que renvoyée par GlobalExceptionFilter.cs\n */\nexport interface ProblemDetails {\n type?: string\n title?: string\n status?: number\n detail?: string\n instance?: string\n [key: string]: unknown\n}\n\n/**\n * Erreur générée par l'API Altazion Commerce (HTTP 4xx / 5xx).\n */\nexport class AltazionApiError extends Error {\n readonly status: number\n readonly problem: ProblemDetails\n\n constructor(status: number, problem: ProblemDetails) {\n super(problem.detail ?? problem.title ?? `HTTP ${status}`)\n this.name = 'AltazionApiError'\n this.status = status\n this.problem = problem\n }\n}\n\n/**\n * Erreur levée lorsque le SDK est hors-ligne et ne peut pas\n * satisfaire la requête depuis le cache.\n */\nexport class OfflineError extends Error {\n constructor(message = 'Le SDK est hors-ligne et aucun cache n\\'est disponible pour cette ressource') {\n super(message)\n this.name = 'OfflineError'\n }\n}\n\n/**\n * Erreur liée à une opération sur le cache (IndexedDB, SharedWorker).\n */\nexport class CacheError extends Error {\n readonly cause: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'CacheError'\n this.cause = cause\n }\n}\n","import { AltazionApiError, type ProblemDetails } from './errors.js'\nimport type { CommerceContext } from './CommerceContext.js'\n\nexport interface RequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n body?: unknown\n headers?: Record<string, string>\n /** Nombre maximum de tentatives réseau (uniquement sur erreurs réseau, jamais sur 4xx) */\n maxRetries?: number\n}\n\n/**\n * Adaptateur HTTP basé sur fetch natif.\n *\n * Responsabilités :\n * - Construction des URLs à partir du baseUrl du contexte\n * - Ajout des headers standard (Content-Type, Accept, locale)\n * - credentials: 'include' pour la transmission automatique des cookies (modes browser et kiosk)\n * - Parse des réponses ProblemDetails en AltazionApiError\n * - Retry limité sur les erreurs réseau (TypeError), jamais sur les 4xx/5xx\n */\nexport class CommerceHttpAdapter {\n private readonly context: CommerceContext\n\n constructor(context: CommerceContext) {\n this.context = context\n }\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { method = 'GET', body, headers = {}, maxRetries = 2 } = options\n const url = `${this.context.baseUrl}${path}`\n\n const requestHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'Accept-Language': this.context.locale,\n ...headers\n }\n\n if (body !== undefined) {\n requestHeaders['Content-Type'] = 'application/json'\n }\n\n const init: RequestInit = {\n method,\n headers: requestHeaders,\n credentials: 'include',\n body: body !== undefined ? JSON.stringify(body) : undefined\n }\n\n let lastNetworkError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, init)\n return await this.handleResponse<T>(response)\n } catch (err) {\n // AltazionApiError n'est jamais retenté\n if (err instanceof AltazionApiError) throw err\n lastNetworkError = err\n // Petite pause exponentielle avant de réessayer (uniquement sur erreurs réseau)\n if (attempt < maxRetries) {\n await delay(150 * Math.pow(2, attempt))\n }\n }\n }\n\n throw lastNetworkError\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n if (response.ok) {\n const contentType = response.headers.get('content-type') ?? ''\n if (response.status === 204 || !contentType.includes('application/json')) {\n return undefined as unknown as T\n }\n return response.json() as Promise<T>\n }\n\n // Tenter de parser un ProblemDetails\n let problem: ProblemDetails = { status: response.status }\n try {\n const contentType = response.headers.get('content-type') ?? ''\n if (contentType.includes('application/json') || contentType.includes('application/problem+json')) {\n problem = await response.json() as ProblemDetails\n problem.status ??= response.status\n }\n } catch {\n // JSON invalide — on garde le problem minimal\n }\n\n throw new AltazionApiError(response.status, problem)\n }\n\n /** Effectue un GET et retourne T */\n get<T>(path: string, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'GET', headers })\n }\n\n /** Effectue un POST avec un body JSON et retourne T */\n post<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'POST', body, headers })\n }\n\n /** Effectue un PUT avec un body JSON et retourne T */\n put<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'PUT', body, headers })\n }\n\n /** Effectue un PATCH avec un body JSON et retourne T */\n patch<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body, headers })\n }\n\n /** Effectue un DELETE et retourne T */\n delete<T>(path: string, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(path, { method: 'DELETE', headers })\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","export type ConnectivityStatus = 'online' | 'offline'\n\nexport type ConnectivityListener = (status: ConnectivityStatus) => void\n\n/**\n * Surveille l'état de la connexion réseau.\n *\n * - Utilise navigator.onLine comme valeur initiale\n * - Écoute les événements window 'online' / 'offline'\n * - Permet d'abonner des listeners (pattern observable léger)\n */\nexport class ConnectivityManager {\n private status: ConnectivityStatus\n private readonly listeners = new Set<ConnectivityListener>()\n\n constructor() {\n this.status = this.readOnlineStatus()\n\n if (typeof window !== 'undefined') {\n window.addEventListener('online', this.handleOnline)\n window.addEventListener('offline', this.handleOffline)\n }\n }\n\n get isOnline(): boolean {\n return this.status === 'online'\n }\n\n get isOffline(): boolean {\n return this.status === 'offline'\n }\n\n /**\n * Abonne un listener aux changements de connectivité.\n * Retourne une fonction de désabonnement.\n */\n subscribe(listener: ConnectivityListener): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n /** Libère les event listeners sur window. */\n dispose(): void {\n if (typeof window !== 'undefined') {\n window.removeEventListener('online', this.handleOnline)\n window.removeEventListener('offline', this.handleOffline)\n }\n this.listeners.clear()\n }\n\n private readOnlineStatus(): ConnectivityStatus {\n if (typeof navigator === 'undefined' || navigator.onLine === undefined) {\n return 'online' // SSR / environnement sans navigator : on suppose online\n }\n return navigator.onLine ? 'online' : 'offline'\n }\n\n private readonly handleOnline = (): void => {\n this.status = 'online'\n this.emit('online')\n }\n\n private readonly handleOffline = (): void => {\n this.status = 'offline'\n this.emit('offline')\n }\n\n private emit(status: ConnectivityStatus): void {\n for (const listener of this.listeners) {\n try {\n listener(status)\n } catch {\n // Un listener ne doit pas faire planter les autres\n }\n }\n }\n}\n","import { CacheError } from '../client/errors.js'\n\ninterface PendingRequest {\n resolve: (value: unknown) => void\n reject: (reason: unknown) => void\n}\n\n/**\n * Abstraction du canal de communication avec le SharedWorker de cache.\n *\n * - Utilise un SharedWorker si le navigateur le supporte\n * - Fallback : Map in-memory (données non persistantes, perdues au reload)\n *\n * Chaque appel retourne une Promise, résolue/rejetée via la réponse du worker.\n */\nexport class WorkerBridge {\n private port: MessagePort | null = null\n private readonly pending = new Map<string, PendingRequest>()\n private requestCounter = 0\n private readonly fallback = new Map<string, { data: unknown; expiresAt: number }>()\n private readonly usingFallback: boolean\n\n constructor() {\n this.usingFallback = !this.tryStartWorker()\n }\n\n private tryStartWorker(): boolean {\n if (typeof SharedWorker === 'undefined') return false\n\n try {\n const worker = new SharedWorker(\n new URL('./cache.worker.ts', import.meta.url),\n { type: 'module', name: 'altazion-cache-worker' }\n )\n this.port = worker.port\n this.port.addEventListener('message', this.handleMessage)\n this.port.start()\n return true\n } catch {\n return false\n }\n }\n\n private readonly handleMessage = (event: MessageEvent<{ id: string; result?: unknown; error?: string }>): void => {\n const { id, result, error } = event.data\n const pending = this.pending.get(id)\n if (!pending) return\n this.pending.delete(id)\n\n if (error !== undefined) {\n pending.reject(new CacheError(error))\n } else {\n pending.resolve(result)\n }\n }\n\n private nextId(): string {\n return String(++this.requestCounter)\n }\n\n private send(message: Record<string, unknown>): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (!this.port) {\n reject(new CacheError('Worker non initialisé'))\n return\n }\n const id = this.nextId()\n this.pending.set(id, { resolve, reject })\n this.port.postMessage({ ...message, id })\n })\n }\n\n async get<T>(key: string): Promise<T | null> {\n if (this.usingFallback) {\n const entry = this.fallback.get(key)\n if (!entry || Date.now() > entry.expiresAt) return null\n return entry.data as T\n }\n return this.send({ type: 'GET', key }) as Promise<T | null>\n }\n\n async set(key: string, data: unknown, ttlMs: number): Promise<void> {\n if (this.usingFallback) {\n this.fallback.set(key, { data, expiresAt: Date.now() + ttlMs })\n return\n }\n await this.send({ type: 'SET', key, data, ttl: ttlMs })\n }\n\n async invalidate(pattern: string): Promise<void> {\n if (this.usingFallback) {\n const regex = new RegExp(pattern)\n for (const key of this.fallback.keys()) {\n if (regex.test(key)) this.fallback.delete(key)\n }\n return\n }\n await this.send({ type: 'INVALIDATE', pattern })\n }\n\n async clearAll(): Promise<void> {\n if (this.usingFallback) {\n this.fallback.clear()\n return\n }\n await this.send({ type: 'CLEAR_ALL' })\n }\n\n dispose(): void {\n this.port?.removeEventListener('message', this.handleMessage)\n this.pending.clear()\n }\n}\n","import type { WorkerBridge } from './WorkerBridge.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\n\n/**\n * Stratégies de cache disponibles pour les requêtes HTTP.\n */\nexport type CacheStrategyName =\n | 'network-only' // Jamais de cache (mutations)\n | 'network-first' // Réseau, fallback cache si erreur réseau\n | 'cache-first' // Cache, revalidation réseau en background si périmé\n | 'stale-while-revalidate' // Retourne le cache immédiatement + revalide en arrière-plan\n\n/** TTL par stratégie, en millisecondes */\nexport const DEFAULT_TTL: Record<Exclude<CacheStrategyName, 'network-only'>, number> = {\n 'network-first': 30_000, // 30 secondes (session, panier)\n 'cache-first': 5 * 60_000, // 5 minutes (recherche)\n 'stale-while-revalidate': 60 * 60_000 // 1 heure (catalogue)\n}\n\nexport class CacheStrategy {\n constructor(\n private readonly bridge: WorkerBridge,\n private readonly http: CommerceHttpAdapter\n ) {}\n\n /**\n * Exécute la requête selon la stratégie choisie.\n *\n * @param key Clé de cache (généralement le path + params)\n * @param fetcher Fonction qui effectue la requête HTTP\n * @param strategy Stratégie à appliquer\n * @param ttlMs TTL du cache (override la valeur par défaut)\n */\n async execute<T>(\n key: string,\n fetcher: () => Promise<T>,\n strategy: CacheStrategyName,\n ttlMs?: number\n ): Promise<T> {\n switch (strategy) {\n case 'network-only':\n return fetcher()\n\n case 'network-first':\n return this.networkFirst<T>(key, fetcher, ttlMs ?? DEFAULT_TTL['network-first'])\n\n case 'cache-first':\n return this.cacheFirst<T>(key, fetcher, ttlMs ?? DEFAULT_TTL['cache-first'])\n\n case 'stale-while-revalidate':\n return this.staleWhileRevalidate<T>(key, fetcher, ttlMs ?? DEFAULT_TTL['stale-while-revalidate'])\n }\n }\n\n private async networkFirst<T>(key: string, fetcher: () => Promise<T>, ttlMs: number): Promise<T> {\n try {\n const data = await fetcher()\n await this.bridge.set(key, data, ttlMs)\n return data\n } catch (err) {\n // Erreur réseau uniquement (TypeError) : on tente le cache\n if (err instanceof TypeError) {\n const cached = await this.bridge.get<T>(key)\n if (cached !== null) return cached\n }\n throw err\n }\n }\n\n private async cacheFirst<T>(key: string, fetcher: () => Promise<T>, ttlMs: number): Promise<T> {\n const cached = await this.bridge.get<T>(key)\n if (cached !== null) return cached\n\n const data = await fetcher()\n await this.bridge.set(key, data, ttlMs)\n return data\n }\n\n private async staleWhileRevalidate<T>(key: string, fetcher: () => Promise<T>, ttlMs: number): Promise<T> {\n const cached = await this.bridge.get<T>(key)\n\n // Revalidation en arrière-plan (ne bloque pas le résultat)\n const revalidate = fetcher()\n .then((data) => this.bridge.set(key, data, ttlMs))\n .catch(() => { /* Échec silencieux : on garde le cache */ })\n\n if (cached !== null) {\n // On lance la revalidation sans attendre\n void revalidate\n return cached\n }\n\n // Pas de cache : on attend le réseau\n const data = await fetcher()\n await this.bridge.set(key, data, ttlMs)\n return data\n }\n}\n","import type { SessionManager } from './SessionManager.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\nimport type { CommerceContext } from '../client/CommerceContext.js'\nimport type { SessionInfo } from '../types/index.js'\nimport { AltazionApiError } from '../client/errors.js'\n\n/**\n * Gestionnaire de session pour le mode navigateur classique.\n *\n * Responsabilités :\n * - Appel à POST /commerce/api/sessions/create pour créer la session\n * - La session est identifiée côté serveur via le cookie `altz_session_id`\n * (créé automatiquement par l'API et transmis grâce à credentials:'include')\n */\nexport class BrowserSessionManager implements SessionManager {\n private readonly http: CommerceHttpAdapter\n private readonly context: CommerceContext\n\n constructor(http: CommerceHttpAdapter, context: CommerceContext) {\n this.http = http\n this.context = context\n }\n\n async initialize(): Promise<SessionInfo | null> {\n // Vérifier si une session existe déjà\n try {\n const existing = await this.http.get<SessionInfo>('/commerce/api/sessions/raw')\n return existing\n } catch (err) {\n // 404 = pas de session, on en crée une\n if (err instanceof AltazionApiError && err.status === 404) {\n return this.createSession()\n }\n throw err\n }\n }\n\n async onSessionExpired(): Promise<void> {\n await this.createSession()\n }\n\n private async createSession(): Promise<SessionInfo> {\n const body = this.buildCreationRequest()\n return this.http.post<SessionInfo>('/commerce/api/sessions/create', body)\n }\n\n private buildCreationRequest(): Record<string, unknown> {\n if (this.context.sitePk !== undefined && this.context.rjsId !== undefined) {\n return { sitePk: this.context.sitePk, rjsId: this.context.rjsId }\n }\n if (this.context.siteUrl !== undefined) {\n return { siteUrl: this.context.siteUrl }\n }\n // Fallback : envoyer l'URL courante du navigateur\n const currentUrl = typeof window !== 'undefined' ? window.location.href : undefined\n return { siteUrl: currentUrl }\n }\n}\n","import type { SessionManager } from './SessionManager.js'\nimport type { SessionInfo } from '../types/index.js'\n\n/**\n * Gestionnaire de session pour le mode borne (Altazion Device Shell).\n *\n * Le browser embarqué gère intégralement les cookies de session.\n * Le SDK n'a pas à intervenir : fetch avec credentials:'include' suffit\n * pour que les cookies soient transmis automatiquement.\n *\n * Cette implémentation est un no-op intentionnel.\n */\nexport class KioskSessionManager implements SessionManager {\n async initialize(): Promise<SessionInfo | null> {\n // Le browser embarqué est responsable de la session.\n // Aucune action requise côté SDK.\n return null\n }\n\n async onSessionExpired(): Promise<void> {\n // Le browser embarqué gère le renouvellement de session.\n // Aucune action requise côté SDK.\n }\n}\n","import type { SessionManager } from './SessionManager.js'\nimport { BrowserSessionManager } from './BrowserSessionManager.js'\nimport { KioskSessionManager } from './KioskSessionManager.js'\nimport type { CommerceHttpAdapter } from '../client/CommerceHttpAdapter.js'\nimport type { CommerceContext } from '../client/CommerceContext.js'\n\n/**\n * Instancie le SessionManager adapté au contexte d'exécution.\n *\n * Détection du mode kiosk : présence de \"Altazion Device Shell\" dans le User-Agent.\n * Dans ce cas, le browser embarqué gère entièrement les cookies de session.\n */\nexport class SessionManagerFactory {\n static create(http: CommerceHttpAdapter, context: CommerceContext): SessionManager {\n if (context.mode === 'kiosk') {\n return new KioskSessionManager()\n }\n return new BrowserSessionManager(http, context)\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { SessionInfo } from '../../types/index.js'\n\nexport class SessionModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère les informations de la session en cours */\n getSession(): Promise<SessionInfo> {\n return this.cache.execute(\n 'session:raw',\n () => this.http.get<SessionInfo>('/commerce/api/sessions/raw'),\n 'network-first'\n )\n }\n\n /** Associe un magasin à la session */\n async associateStore(storeGuid: string): Promise<SessionInfo> {\n const result = await this.http.post<SessionInfo>(\n `/commerce/api/sessions/associate/store/${storeGuid}`\n )\n await this.cache.execute('session:raw', () => Promise.resolve(result), 'network-first')\n return result\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport { OfflineError } from '../../client/errors.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { ConnectivityManager } from '../../connectivity/ConnectivityManager.js'\nimport type { Cart, CartValidationStatus } from '../../types/index.js'\n\nexport class CartModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy,\n private readonly connectivity: ConnectivityManager\n ) {}\n\n /** Récupère le panier en cours */\n getCart(): Promise<Cart> {\n return this.cache.execute(\n 'cart:current',\n () => this.http.get<Cart>('/commerce/api/process/cart'),\n 'network-first'\n )\n }\n\n /** Récupère le statut de validation du panier */\n getValidationStatus(): Promise<CartValidationStatus> {\n return this.http.get<CartValidationStatus>('/commerce/api/process/cart/status/check')\n }\n\n /** Ajoute un article au panier */\n async addItem(reference: string, quantity: number, options?: Record<string, unknown>): Promise<Cart> {\n this.ensureOnline()\n const body = { reference, quantity, ...options }\n const cart = await this.http.post<Cart>('/commerce/api/process/cart/items', body)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Met à jour la quantité d'une ligne */\n async updateItem(lineId: string, quantity: number): Promise<Cart> {\n this.ensureOnline()\n const body = { quantity }\n const cart = await this.http.put<Cart>(`/commerce/api/process/cart/items/${lineId}`, body)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Supprime une ligne du panier */\n async removeItem(lineId: string): Promise<Cart> {\n this.ensureOnline()\n const cart = await this.http.delete<Cart>(`/commerce/api/process/cart/items/${lineId}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Applique un coupon */\n async applyCoupon(code: string): Promise<Cart> {\n this.ensureOnline()\n const cart = await this.http.post<Cart>('/commerce/api/process/cart/coupons', { code })\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n /** Retire un coupon */\n async removeCoupon(code: string): Promise<Cart> {\n this.ensureOnline()\n const cart = await this.http.delete<Cart>(`/commerce/api/process/cart/coupons/${encodeURIComponent(code)}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n return cart\n }\n\n private ensureOnline(): void {\n if (this.connectivity.isOffline) {\n throw new OfflineError('Le terminal est hors ligne, les modifications du panier sont indisponibles')\n }\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { ProductDetails, WebProduct, SearchRequest, SearchResult } from '../../types/index.js'\n\nexport class CatalogModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère le détail d'un produit par sa référence */\n getProduct(reference: string): Promise<ProductDetails> {\n return this.cache.execute(\n `catalog:product:${reference}`,\n () => this.http.get<ProductDetails>(`/commerce/api/pim/products/${encodeURIComponent(reference)}`),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère une liste de produits par leurs références */\n getProducts(references: string[]): Promise<WebProduct[]> {\n const key = `catalog:products:${references.sort().join(',')}`\n return this.cache.execute(\n key,\n () => this.http.post<WebProduct[]>('/commerce/api/pim/products/batch', { references }),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère les produits d'une catégorie */\n getCategory(categoryCode: string, pageIndex = 0, pageSize = 20): Promise<SearchResult> {\n const key = `catalog:category:${categoryCode}:${pageIndex}:${pageSize}`\n return this.cache.execute(\n key,\n () => this.http.get<SearchResult>(\n `/commerce/api/pim/categories/${encodeURIComponent(categoryCode)}/products?pageIndex=${pageIndex}&pageSize=${pageSize}`\n ),\n 'stale-while-revalidate'\n )\n }\n\n /** Effectue une recherche full-text */\n search(request: SearchRequest): Promise<SearchResult> {\n const key = `catalog:search:${JSON.stringify(request)}`\n return this.cache.execute(\n key,\n () => this.http.post<SearchResult>('/commerce/api/pim/search', request),\n 'cache-first'\n )\n }\n\n /** Récupère les suggestions de recherche (autocomplete) */\n suggest(query: string): Promise<string[]> {\n return this.cache.execute(\n `catalog:suggest:${query}`,\n () => this.http.get<string[]>(`/commerce/api/pim/search/suggest?q=${encodeURIComponent(query)}`),\n 'cache-first',\n 2 * 60_000 // 2 minutes pour les suggestions\n )\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { ShippingChoiceGroup, ShippingAddress, PickupPoint } from '../../types/index.js'\n\nexport class ShippingModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère les groupes de modes de livraison disponibles pour le panier en cours */\n getAvailableModes(): Promise<ShippingChoiceGroup[]> {\n return this.cache.execute(\n 'shipping:modes',\n () => this.http.get<ShippingChoiceGroup[]>('/commerce/api/process/cart/shipping/modes'),\n 'network-first'\n )\n }\n\n /** Sélectionne un mode de livraison */\n selectMode(shippingModeGuid: string): Promise<void> {\n return this.http.post('/commerce/api/process/cart/shipping/mode', { shippingModeGuid })\n }\n\n /** Met à jour l'adresse de livraison */\n setAddress(address: ShippingAddress): Promise<void> {\n return this.http.put('/commerce/api/process/cart/address/shipping', address)\n }\n\n /** Recherche des points relais à proximité */\n getRelayPoints(postalCode: string, countryCode = 'FR', shippingModeGuid?: string): Promise<PickupPoint[]> {\n const params = new URLSearchParams({ postalCode, countryCode })\n if (shippingModeGuid) params.set('shippingModeGuid', shippingModeGuid)\n const key = `shipping:relays:${postalCode}:${countryCode}:${shippingModeGuid ?? ''}`\n return this.cache.execute(\n key,\n () => this.http.get<PickupPoint[]>(`/commerce/api/process/shipping/relays?${params.toString()}`),\n 'cache-first',\n 10 * 60_000 // 10 minutes\n )\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { MarketingItem } from '../../types/index.js'\n\nexport class MarketingModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Récupère un item marketing par son code */\n getItem(code: string): Promise<MarketingItem> {\n return this.cache.execute(\n `marketing:item:${code}`,\n () => this.http.get<MarketingItem>(`/commerce/api/marketing/items/${encodeURIComponent(code)}`),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère plusieurs items marketing par leurs codes */\n getItems(codes: string[]): Promise<MarketingItem[]> {\n const key = `marketing:items:${codes.sort().join(',')}`\n return this.cache.execute(\n key,\n () => this.http.post<MarketingItem[]>('/commerce/api/marketing/items/batch', { codes }),\n 'stale-while-revalidate'\n )\n }\n}\n","import type { CommerceHttpAdapter } from '../../client/CommerceHttpAdapter.js'\nimport type { CacheStrategy } from '../../workers/CacheStrategy.js'\nimport type { StoreWithOpeningHours } from '../../types/index.js'\n\nexport class StoresModule {\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy\n ) {}\n\n /** Recherche des magasins par coordonnées géographiques */\n findByLocation(latitude: number, longitude: number, radiusKm = 50): Promise<StoreWithOpeningHours[]> {\n const key = `stores:geo:${latitude.toFixed(4)}:${longitude.toFixed(4)}:${radiusKm}`\n return this.cache.execute(\n key,\n () => this.http.get<StoreWithOpeningHours[]>(\n `/commerce/api/stores/locator?lat=${latitude}&lon=${longitude}&radius=${radiusKm}`\n ),\n 'cache-first',\n 15 * 60_000 // 15 minutes\n )\n }\n\n /** Recherche des magasins par code postal */\n findByPostalCode(postalCode: string, countryCode = 'FR'): Promise<StoreWithOpeningHours[]> {\n const key = `stores:postal:${postalCode}:${countryCode}`\n return this.cache.execute(\n key,\n () => this.http.get<StoreWithOpeningHours[]>(\n `/commerce/api/stores/locator?postalCode=${encodeURIComponent(postalCode)}&countryCode=${encodeURIComponent(countryCode)}`\n ),\n 'cache-first',\n 15 * 60_000\n )\n }\n\n /** Récupère le détail d'un magasin par son GUID */\n getStore(storeGuid: string): Promise<StoreWithOpeningHours> {\n return this.cache.execute(\n `stores:detail:${storeGuid}`,\n () => this.http.get<StoreWithOpeningHours>(`/commerce/api/stores/${storeGuid}`),\n 'stale-while-revalidate'\n )\n }\n}\n","import { CommerceContext, type CommerceContextOptions } from './CommerceContext.js'\nimport { CommerceHttpAdapter } from './CommerceHttpAdapter.js'\nimport { ConnectivityManager } from '../connectivity/ConnectivityManager.js'\nimport { WorkerBridge } from '../workers/WorkerBridge.js'\nimport { CacheStrategy } from '../workers/CacheStrategy.js'\nimport { SessionManagerFactory } from '../session/SessionManagerFactory.js'\nimport { SessionModule } from '../modules/session/index.js'\nimport { CartModule } from '../modules/cart/index.js'\nimport { CatalogModule } from '../modules/catalog/index.js'\nimport { ShippingModule } from '../modules/shipping/index.js'\nimport { MarketingModule } from '../modules/marketing/index.js'\nimport { StoresModule } from '../modules/stores/index.js'\nimport type { SessionManager } from '../session/SessionManager.js'\nimport type { SessionInfo } from '../types/index.js'\n\nexport { CommerceContext, type CommerceContextOptions } from './CommerceContext.js'\n\n/**\n * Point d'entrée principal du SDK Altazion Commerce.\n *\n * Usage :\n * ```ts\n * const client = new CommerceClient({ baseUrl: 'https://api.monsite.com', siteUrl: window.location.href })\n * await client.initialize()\n *\n * const cart = await client.cart.getCart()\n * ```\n */\nexport class CommerceClient {\n readonly context: CommerceContext\n readonly connectivity: ConnectivityManager\n\n readonly session: SessionModule\n readonly cart: CartModule\n readonly catalog: CatalogModule\n readonly shipping: ShippingModule\n readonly marketing: MarketingModule\n readonly stores: StoresModule\n\n private readonly http: CommerceHttpAdapter\n private readonly workerBridge: WorkerBridge\n private readonly cacheStrategy: CacheStrategy\n private readonly sessionManager: SessionManager\n\n constructor(options: CommerceContextOptions) {\n this.context = new CommerceContext(options)\n this.http = new CommerceHttpAdapter(this.context)\n this.connectivity = new ConnectivityManager()\n this.workerBridge = new WorkerBridge()\n this.cacheStrategy = new CacheStrategy(this.workerBridge, this.http)\n this.sessionManager = SessionManagerFactory.create(this.http, this.context)\n\n // Modules API\n this.session = new SessionModule(this.http, this.cacheStrategy)\n this.cart = new CartModule(this.http, this.cacheStrategy, this.connectivity)\n this.catalog = new CatalogModule(this.http, this.cacheStrategy)\n this.shipping = new ShippingModule(this.http, this.cacheStrategy)\n this.marketing = new MarketingModule(this.http, this.cacheStrategy)\n this.stores = new StoresModule(this.http, this.cacheStrategy)\n }\n\n /**\n * Initialise le SDK :\n * - Crée la session si nécessaire (mode browser uniquement)\n */\n async initialize(): Promise<SessionInfo | null> {\n return this.sessionManager.initialize()\n }\n\n /**\n * Retourne vrai si le SDK est hors-ligne.\n */\n get isOffline(): boolean {\n return this.connectivity.isOffline\n }\n\n /**\n * Force le vidage du cache.\n */\n clearCache(): Promise<void> {\n return this.workerBridge.clearAll()\n }\n\n /**\n * Libère les ressources (listeners, worker).\n */\n dispose(): void {\n this.connectivity.dispose()\n this.workerBridge.dispose()\n }\n}\n"],"names":["data"],"mappings":";;;AA6BO,MAAM,gBAAgB;AAAA,EAS3B,YAAY,SAAiC;AARpC;AACA;AACA;AACA;AACA;AACA;AACA;AAGP,SAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAChD,SAAK,UAAU,QAAQ;AACvB,SAAK,SAAS,QAAQ;AACtB,SAAK,QAAQ,QAAQ;AACrB,SAAK,SAAS,QAAQ,UAAU;AAChC,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,OAAO,gBAAgB,WAAA;AAAA,EAC9B;AAAA,EAEA,OAAe,aAA2B;AACxC,QAAI,OAAO,cAAc,eAAe,UAAU,UAAU,SAAS,uBAAuB,GAAG;AAC7F,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;ACtCO,MAAM,yBAAyB,MAAM;AAAA,EAI1C,YAAY,QAAgB,SAAyB;AACnD,UAAM,QAAQ,UAAU,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAJlD;AACA;AAIP,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACjB;AACF;AAMO,MAAM,qBAAqB,MAAM;AAAA,EACtC,YAAY,UAAU,8EAA+E;AACnG,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,mBAAmB,MAAM;AAAA,EAGpC,YAAY,SAAiB,OAAiB;AAC5C,UAAM,OAAO;AAHN;AAIP,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AACF;AC7BO,MAAM,oBAAoB;AAAA,EAG/B,YAAY,SAA0B;AAFrB;AAGf,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,QAAW,MAAc,UAA0B,IAAgB;AACvE,UAAM,EAAE,SAAS,OAAO,MAAM,UAAU,IAAI,aAAa,EAAA,IAAM;AAC/D,UAAM,MAAM,GAAG,KAAK,QAAQ,OAAO,GAAG,IAAI;AAE1C,UAAM,iBAAyC;AAAA,MAC7C,QAAQ;AAAA,MACR,mBAAmB,KAAK,QAAQ;AAAA,MAChC,GAAG;AAAA,IAAA;AAGL,QAAI,SAAS,QAAW;AACtB,qBAAe,cAAc,IAAI;AAAA,IACnC;AAEA,UAAM,OAAoB;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,MACT,aAAa;AAAA,MACb,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IAAA;AAGpD,QAAI;AACJ,aAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,KAAK,IAAI;AACtC,eAAO,MAAM,KAAK,eAAkB,QAAQ;AAAA,MAC9C,SAAS,KAAK;AAEZ,YAAI,eAAe,iBAAkB,OAAM;AAC3C,2BAAmB;AAEnB,YAAI,UAAU,YAAY;AACxB,gBAAM,MAAM,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AAAA,EAEA,MAAc,eAAkB,UAAgC;AAC9D,QAAI,SAAS,IAAI;AACf,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,UAAI,SAAS,WAAW,OAAO,CAAC,YAAY,SAAS,kBAAkB,GAAG;AACxE,eAAO;AAAA,MACT;AACA,aAAO,SAAS,KAAA;AAAA,IAClB;AAGA,QAAI,UAA0B,EAAE,QAAQ,SAAS,OAAA;AACjD,QAAI;AACF,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,UAAI,YAAY,SAAS,kBAAkB,KAAK,YAAY,SAAS,0BAA0B,GAAG;AAChG,kBAAU,MAAM,SAAS,KAAA;AACzB,gBAAQ,WAAR,QAAQ,SAAW,SAAS;AAAA,MAC9B;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,UAAM,IAAI,iBAAiB,SAAS,QAAQ,OAAO;AAAA,EACrD;AAAA;AAAA,EAGA,IAAO,MAAc,SAA8C;AACjE,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,OAAO,SAAS;AAAA,EACzD;AAAA;AAAA,EAGA,KAAQ,MAAc,MAAgB,SAA8C;AAClF,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,QAAQ,MAAM,SAAS;AAAA,EAChE;AAAA;AAAA,EAGA,IAAO,MAAc,MAAgB,SAA8C;AACjF,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,OAAO,MAAM,SAAS;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAS,MAAc,MAAgB,SAA8C;AACnF,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,SAAS,MAAM,SAAS;AAAA,EACjE;AAAA;AAAA,EAGA,OAAU,MAAc,SAA8C;AACpE,WAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,UAAU,SAAS;AAAA,EAC5D;AACF;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AC7GO,MAAM,oBAAoB;AAAA,EAI/B,cAAc;AAHN;AACS,yDAAgB,IAAA;AA4ChB,wCAAe,MAAY;AAC1C,WAAK,SAAS;AACd,WAAK,KAAK,QAAQ;AAAA,IACpB;AAEiB,yCAAgB,MAAY;AAC3C,WAAK,SAAS;AACd,WAAK,KAAK,SAAS;AAAA,IACrB;AAjDE,SAAK,SAAS,KAAK,iBAAA;AAEnB,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO,iBAAiB,UAAU,KAAK,YAAY;AACnD,aAAO,iBAAiB,WAAW,KAAK,aAAa;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,UAA4C;AACpD,SAAK,UAAU,IAAI,QAAQ;AAC3B,WAAO,MAAM,KAAK,UAAU,OAAO,QAAQ;AAAA,EAC7C;AAAA;AAAA,EAGA,UAAgB;AACd,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO,oBAAoB,UAAU,KAAK,YAAY;AACtD,aAAO,oBAAoB,WAAW,KAAK,aAAa;AAAA,IAC1D;AACA,SAAK,UAAU,MAAA;AAAA,EACjB;AAAA,EAEQ,mBAAuC;AAC7C,QAAI,OAAO,cAAc,eAAe,UAAU,WAAW,QAAW;AACtE,aAAO;AAAA,IACT;AACA,WAAO,UAAU,SAAS,WAAW;AAAA,EACvC;AAAA,EAYQ,KAAK,QAAkC;AAC7C,eAAW,YAAY,KAAK,WAAW;AACrC,UAAI;AACF,iBAAS,MAAM;AAAA,MACjB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;AC7DO,MAAM,aAAa;AAAA,EAOxB,cAAc;AANN,gCAA2B;AAClB,uDAAc,IAAA;AACvB,0CAAiB;AACR,wDAAe,IAAA;AACf;AAuBA,yCAAgB,CAAC,UAAgF;AAChH,YAAM,EAAE,IAAI,QAAQ,MAAA,IAAU,MAAM;AACpC,YAAM,UAAU,KAAK,QAAQ,IAAI,EAAE;AACnC,UAAI,CAAC,QAAS;AACd,WAAK,QAAQ,OAAO,EAAE;AAEtB,UAAI,UAAU,QAAW;AACvB,gBAAQ,OAAO,IAAI,WAAW,KAAK,CAAC;AAAA,MACtC,OAAO;AACL,gBAAQ,QAAQ,MAAM;AAAA,MACxB;AAAA,IACF;AA/BE,SAAK,gBAAgB,CAAC,KAAK,eAAA;AAAA,EAC7B;AAAA,EAEQ,iBAA0B;AAChC,QAAI,OAAO,iBAAiB,YAAa,QAAO;AAEhD,QAAI;AACF,YAAM,SAAS,IAAI;AAAA,QACjB;;;;;QACA,EAAE,MAAM,UAAU,MAAM,wBAAA;AAAA,MAAwB;AAElD,WAAK,OAAO,OAAO;AACnB,WAAK,KAAK,iBAAiB,WAAW,KAAK,aAAa;AACxD,WAAK,KAAK,MAAA;AACV,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAeQ,SAAiB;AACvB,WAAO,OAAO,EAAE,KAAK,cAAc;AAAA,EACrC;AAAA,EAEQ,KAAK,SAAoD;AAC/D,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI,CAAC,KAAK,MAAM;AACd,eAAO,IAAI,WAAW,uBAAuB,CAAC;AAC9C;AAAA,MACF;AACA,YAAM,KAAK,KAAK,OAAA;AAChB,WAAK,QAAQ,IAAI,IAAI,EAAE,SAAS,QAAQ;AACxC,WAAK,KAAK,YAAY,EAAE,GAAG,SAAS,IAAI;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAO,KAAgC;AAC3C,QAAI,KAAK,eAAe;AACtB,YAAM,QAAQ,KAAK,SAAS,IAAI,GAAG;AACnC,UAAI,CAAC,SAAS,KAAK,QAAQ,MAAM,UAAW,QAAO;AACnD,aAAO,MAAM;AAAA,IACf;AACA,WAAO,KAAK,KAAK,EAAE,MAAM,OAAO,KAAK;AAAA,EACvC;AAAA,EAEA,MAAM,IAAI,KAAa,MAAe,OAA8B;AAClE,QAAI,KAAK,eAAe;AACtB,WAAK,SAAS,IAAI,KAAK,EAAE,MAAM,WAAW,KAAK,QAAQ,OAAO;AAC9D;AAAA,IACF;AACA,UAAM,KAAK,KAAK,EAAE,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO;AAAA,EACxD;AAAA,EAEA,MAAM,WAAW,SAAgC;AAC/C,QAAI,KAAK,eAAe;AACtB,YAAM,QAAQ,IAAI,OAAO,OAAO;AAChC,iBAAW,OAAO,KAAK,SAAS,KAAA,GAAQ;AACtC,YAAI,MAAM,KAAK,GAAG,EAAG,MAAK,SAAS,OAAO,GAAG;AAAA,MAC/C;AACA;AAAA,IACF;AACA,UAAM,KAAK,KAAK,EAAE,MAAM,cAAc,SAAS;AAAA,EACjD;AAAA,EAEA,MAAM,WAA0B;AAC9B,QAAI,KAAK,eAAe;AACtB,WAAK,SAAS,MAAA;AACd;AAAA,IACF;AACA,UAAM,KAAK,KAAK,EAAE,MAAM,aAAa;AAAA,EACvC;AAAA,EAEA,UAAgB;AJ/EX;AIgFH,eAAK,SAAL,mBAAW,oBAAoB,WAAW,KAAK;AAC/C,SAAK,QAAQ,MAAA;AAAA,EACf;AACF;ACnGO,MAAM,cAA0E;AAAA,EACrF,iBAAiB;AAAA;AAAA,EACjB,eAAe,IAAI;AAAA;AAAA,EACnB,0BAA0B,KAAK;AAAA;AACjC;AAEO,MAAM,cAAc;AAAA,EACzB,YACmB,QACA,MACjB;AAFiB,SAAA,SAAA;AACA,SAAA,OAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUH,MAAM,QACJ,KACA,SACA,UACA,OACY;AACZ,YAAQ,UAAA;AAAA,MACN,KAAK;AACH,eAAO,QAAA;AAAA,MAET,KAAK;AACH,eAAO,KAAK,aAAgB,KAAK,SAAS,SAAS,YAAY,eAAe,CAAC;AAAA,MAEjF,KAAK;AACH,eAAO,KAAK,WAAc,KAAK,SAAS,SAAS,YAAY,aAAa,CAAC;AAAA,MAE7E,KAAK;AACH,eAAO,KAAK,qBAAwB,KAAK,SAAS,SAAS,YAAY,wBAAwB,CAAC;AAAA,IAAA;AAAA,EAEtG;AAAA,EAEA,MAAc,aAAgB,KAAa,SAA2B,OAA2B;AAC/F,QAAI;AACF,YAAM,OAAO,MAAM,QAAA;AACnB,YAAM,KAAK,OAAO,IAAI,KAAK,MAAM,KAAK;AACtC,aAAO;AAAA,IACT,SAAS,KAAK;AAEZ,UAAI,eAAe,WAAW;AAC5B,cAAM,SAAS,MAAM,KAAK,OAAO,IAAO,GAAG;AAC3C,YAAI,WAAW,KAAM,QAAO;AAAA,MAC9B;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,WAAc,KAAa,SAA2B,OAA2B;AAC7F,UAAM,SAAS,MAAM,KAAK,OAAO,IAAO,GAAG;AAC3C,QAAI,WAAW,KAAM,QAAO;AAE5B,UAAM,OAAO,MAAM,QAAA;AACnB,UAAM,KAAK,OAAO,IAAI,KAAK,MAAM,KAAK;AACtC,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,qBAAwB,KAAa,SAA2B,OAA2B;AACvG,UAAM,SAAS,MAAM,KAAK,OAAO,IAAO,GAAG;AAGxB,YAAA,EAChB,KAAK,CAACA,UAAS,KAAK,OAAO,IAAI,KAAKA,OAAM,KAAK,CAAC,EAChD,MAAM,MAAM;AAAA,IAA6C,CAAC;AAE7D,QAAI,WAAW,MAAM;AAGnB,aAAO;AAAA,IACT;AAGA,UAAM,OAAO,MAAM,QAAA;AACnB,UAAM,KAAK,OAAO,IAAI,KAAK,MAAM,KAAK;AACtC,WAAO;AAAA,EACT;AACF;ACnFO,MAAM,sBAAgD;AAAA,EAI3D,YAAY,MAA2B,SAA0B;AAHhD;AACA;AAGf,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,aAA0C;AAE9C,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,IAAiB,4BAA4B;AAC9E,aAAO;AAAA,IACT,SAAS,KAAK;AAEZ,UAAI,eAAe,oBAAoB,IAAI,WAAW,KAAK;AACzD,eAAO,KAAK,cAAA;AAAA,MACd;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,mBAAkC;AACtC,UAAM,KAAK,cAAA;AAAA,EACb;AAAA,EAEA,MAAc,gBAAsC;AAClD,UAAM,OAAO,KAAK,qBAAA;AAClB,WAAO,KAAK,KAAK,KAAkB,iCAAiC,IAAI;AAAA,EAC1E;AAAA,EAEQ,uBAAgD;AACtD,QAAI,KAAK,QAAQ,WAAW,UAAa,KAAK,QAAQ,UAAU,QAAW;AACzE,aAAO,EAAE,QAAQ,KAAK,QAAQ,QAAQ,OAAO,KAAK,QAAQ,MAAA;AAAA,IAC5D;AACA,QAAI,KAAK,QAAQ,YAAY,QAAW;AACtC,aAAO,EAAE,SAAS,KAAK,QAAQ,QAAA;AAAA,IACjC;AAEA,UAAM,aAAa,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAC1E,WAAO,EAAE,SAAS,WAAA;AAAA,EACpB;AACF;AC7CO,MAAM,oBAA8C;AAAA,EACzD,MAAM,aAA0C;AAG9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,mBAAkC;AAAA,EAGxC;AACF;ACXO,MAAM,sBAAsB;AAAA,EACjC,OAAO,OAAO,MAA2B,SAA0C;AACjF,QAAI,QAAQ,SAAS,SAAS;AAC5B,aAAO,IAAI,oBAAA;AAAA,IACb;AACA,WAAO,IAAI,sBAAsB,MAAM,OAAO;AAAA,EAChD;AACF;ACfO,MAAM,cAAc;AAAA,EACzB,YACmB,MACA,OACjB;AAFiB,SAAA,OAAA;AACA,SAAA,QAAA;AAAA,EAChB;AAAA;AAAA,EAGH,aAAmC;AACjC,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,IAAiB,4BAA4B;AAAA,MAC7D;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,MAAM,eAAe,WAAyC;AAC5D,UAAM,SAAS,MAAM,KAAK,KAAK;AAAA,MAC7B,0CAA0C,SAAS;AAAA,IAAA;AAErD,UAAM,KAAK,MAAM,QAAQ,eAAe,MAAM,QAAQ,QAAQ,MAAM,GAAG,eAAe;AACtF,WAAO;AAAA,EACT;AACF;ACrBO,MAAM,WAAW;AAAA,EACtB,YACmB,MACA,OACA,cACjB;AAHiB,SAAA,OAAA;AACA,SAAA,QAAA;AACA,SAAA,eAAA;AAAA,EAChB;AAAA;AAAA,EAGH,UAAyB;AACvB,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,IAAU,4BAA4B;AAAA,MACtD;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,sBAAqD;AACnD,WAAO,KAAK,KAAK,IAA0B,yCAAyC;AAAA,EACtF;AAAA;AAAA,EAGA,MAAM,QAAQ,WAAmB,UAAkB,SAAkD;AACnG,SAAK,aAAA;AACL,UAAM,OAAO,EAAE,WAAW,UAAU,GAAG,QAAA;AACvC,UAAM,OAAO,MAAM,KAAK,KAAK,KAAW,oCAAoC,IAAI;AAChF,UAAM,KAAK,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,IAAI,GAAG,eAAe;AACrF,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,WAAW,QAAgB,UAAiC;AAChE,SAAK,aAAA;AACL,UAAM,OAAO,EAAE,SAAA;AACf,UAAM,OAAO,MAAM,KAAK,KAAK,IAAU,oCAAoC,MAAM,IAAI,IAAI;AACzF,UAAM,KAAK,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,IAAI,GAAG,eAAe;AACrF,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,WAAW,QAA+B;AAC9C,SAAK,aAAA;AACL,UAAM,OAAO,MAAM,KAAK,KAAK,OAAa,oCAAoC,MAAM,EAAE;AACtF,UAAM,KAAK,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,IAAI,GAAG,eAAe;AACrF,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,YAAY,MAA6B;AAC7C,SAAK,aAAA;AACL,UAAM,OAAO,MAAM,KAAK,KAAK,KAAW,sCAAsC,EAAE,MAAM;AACtF,UAAM,KAAK,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,IAAI,GAAG,eAAe;AACrF,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,aAAa,MAA6B;AAC9C,SAAK,aAAA;AACL,UAAM,OAAO,MAAM,KAAK,KAAK,OAAa,sCAAsC,mBAAmB,IAAI,CAAC,EAAE;AAC1G,UAAM,KAAK,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,IAAI,GAAG,eAAe;AACrF,WAAO;AAAA,EACT;AAAA,EAEQ,eAAqB;AAC3B,QAAI,KAAK,aAAa,WAAW;AAC/B,YAAM,IAAI,aAAa,4EAA4E;AAAA,IACrG;AAAA,EACF;AACF;ACtEO,MAAM,cAAc;AAAA,EACzB,YACmB,MACA,OACjB;AAFiB,SAAA,OAAA;AACA,SAAA,QAAA;AAAA,EAChB;AAAA;AAAA,EAGH,WAAW,WAA4C;AACrD,WAAO,KAAK,MAAM;AAAA,MAChB,mBAAmB,SAAS;AAAA,MAC5B,MAAM,KAAK,KAAK,IAAoB,8BAA8B,mBAAmB,SAAS,CAAC,EAAE;AAAA,MACjG;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,YAAY,YAA6C;AACvD,UAAM,MAAM,oBAAoB,WAAW,OAAO,KAAK,GAAG,CAAC;AAC3D,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,KAAmB,oCAAoC,EAAE,YAAY;AAAA,MACrF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,YAAY,cAAsB,YAAY,GAAG,WAAW,IAA2B;AACrF,UAAM,MAAM,oBAAoB,YAAY,IAAI,SAAS,IAAI,QAAQ;AACrE,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK;AAAA,QACd,gCAAgC,mBAAmB,YAAY,CAAC,uBAAuB,SAAS,aAAa,QAAQ;AAAA,MAAA;AAAA,MAEvH;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,OAAO,SAA+C;AACpD,UAAM,MAAM,kBAAkB,KAAK,UAAU,OAAO,CAAC;AACrD,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,KAAmB,4BAA4B,OAAO;AAAA,MACtE;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,QAAQ,OAAkC;AACxC,WAAO,KAAK,MAAM;AAAA,MAChB,mBAAmB,KAAK;AAAA,MACxB,MAAM,KAAK,KAAK,IAAc,sCAAsC,mBAAmB,KAAK,CAAC,EAAE;AAAA,MAC/F;AAAA,MACA,IAAI;AAAA;AAAA,IAAA;AAAA,EAER;AACF;ACxDO,MAAM,eAAe;AAAA,EAC1B,YACmB,MACA,OACjB;AAFiB,SAAA,OAAA;AACA,SAAA,QAAA;AAAA,EAChB;AAAA;AAAA,EAGH,oBAAoD;AAClD,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,IAA2B,2CAA2C;AAAA,MACtF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,WAAW,kBAAyC;AAClD,WAAO,KAAK,KAAK,KAAK,4CAA4C,EAAE,kBAAkB;AAAA,EACxF;AAAA;AAAA,EAGA,WAAW,SAAyC;AAClD,WAAO,KAAK,KAAK,IAAI,+CAA+C,OAAO;AAAA,EAC7E;AAAA;AAAA,EAGA,eAAe,YAAoB,cAAc,MAAM,kBAAmD;AACxG,UAAM,SAAS,IAAI,gBAAgB,EAAE,YAAY,aAAa;AAC9D,QAAI,iBAAkB,QAAO,IAAI,oBAAoB,gBAAgB;AACrE,UAAM,MAAM,mBAAmB,UAAU,IAAI,WAAW,IAAI,oBAAoB,EAAE;AAClF,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,IAAmB,yCAAyC,OAAO,SAAA,CAAU,EAAE;AAAA,MAC/F;AAAA,MACA,KAAK;AAAA;AAAA,IAAA;AAAA,EAET;AACF;ACrCO,MAAM,gBAAgB;AAAA,EAC3B,YACmB,MACA,OACjB;AAFiB,SAAA,OAAA;AACA,SAAA,QAAA;AAAA,EAChB;AAAA;AAAA,EAGH,QAAQ,MAAsC;AAC5C,WAAO,KAAK,MAAM;AAAA,MAChB,kBAAkB,IAAI;AAAA,MACtB,MAAM,KAAK,KAAK,IAAmB,iCAAiC,mBAAmB,IAAI,CAAC,EAAE;AAAA,MAC9F;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,SAAS,OAA2C;AAClD,UAAM,MAAM,mBAAmB,MAAM,OAAO,KAAK,GAAG,CAAC;AACrD,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK,KAAsB,uCAAuC,EAAE,OAAO;AAAA,MACtF;AAAA,IAAA;AAAA,EAEJ;AACF;ACxBO,MAAM,aAAa;AAAA,EACxB,YACmB,MACA,OACjB;AAFiB,SAAA,OAAA;AACA,SAAA,QAAA;AAAA,EAChB;AAAA;AAAA,EAGH,eAAe,UAAkB,WAAmB,WAAW,IAAsC;AACnG,UAAM,MAAM,cAAc,SAAS,QAAQ,CAAC,CAAC,IAAI,UAAU,QAAQ,CAAC,CAAC,IAAI,QAAQ;AACjF,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK;AAAA,QACd,oCAAoC,QAAQ,QAAQ,SAAS,WAAW,QAAQ;AAAA,MAAA;AAAA,MAElF;AAAA,MACA,KAAK;AAAA;AAAA,IAAA;AAAA,EAET;AAAA;AAAA,EAGA,iBAAiB,YAAoB,cAAc,MAAwC;AACzF,UAAM,MAAM,iBAAiB,UAAU,IAAI,WAAW;AACtD,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,KAAK;AAAA,QACd,2CAA2C,mBAAmB,UAAU,CAAC,gBAAgB,mBAAmB,WAAW,CAAC;AAAA,MAAA;AAAA,MAE1H;AAAA,MACA,KAAK;AAAA,IAAA;AAAA,EAET;AAAA;AAAA,EAGA,SAAS,WAAmD;AAC1D,WAAO,KAAK,MAAM;AAAA,MAChB,iBAAiB,SAAS;AAAA,MAC1B,MAAM,KAAK,KAAK,IAA2B,wBAAwB,SAAS,EAAE;AAAA,MAC9E;AAAA,IAAA;AAAA,EAEJ;AACF;AChBO,MAAM,eAAe;AAAA,EAgB1B,YAAY,SAAiC;AAfpC;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEQ;AACA;AACA;AACA;AAGf,SAAK,UAAU,IAAI,gBAAgB,OAAO;AAC1C,SAAK,OAAO,IAAI,oBAAoB,KAAK,OAAO;AAChD,SAAK,eAAe,IAAI,oBAAA;AACxB,SAAK,eAAe,IAAI,aAAA;AACxB,SAAK,gBAAgB,IAAI,cAAc,KAAK,cAAc,KAAK,IAAI;AACnE,SAAK,iBAAiB,sBAAsB,OAAO,KAAK,MAAM,KAAK,OAAO;AAG1E,SAAK,UAAU,IAAI,cAAc,KAAK,MAAM,KAAK,aAAa;AAC9D,SAAK,OAAO,IAAI,WAAW,KAAK,MAAM,KAAK,eAAe,KAAK,YAAY;AAC3E,SAAK,UAAU,IAAI,cAAc,KAAK,MAAM,KAAK,aAAa;AAC9D,SAAK,WAAW,IAAI,eAAe,KAAK,MAAM,KAAK,aAAa;AAChE,SAAK,YAAY,IAAI,gBAAgB,KAAK,MAAM,KAAK,aAAa;AAClE,SAAK,SAAS,IAAI,aAAa,KAAK,MAAM,KAAK,aAAa;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAA0C;AAC9C,WAAO,KAAK,eAAe,WAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAAqB;AACvB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,aAA4B;AAC1B,WAAO,KAAK,aAAa,SAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,SAAK,aAAa,QAAA;AAClB,SAAK,aAAa,QAAA;AAAA,EACpB;AACF;"}
|
package/package.json
CHANGED