@altazion/commerce-sdk-core 26.618.8362 → 26.619.8376
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/dist/index.cjs +21 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.iife.js +21 -22
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +21 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -765,38 +765,37 @@ class StoresModule {
|
|
|
765
765
|
this.cache = cache;
|
|
766
766
|
}
|
|
767
767
|
/** Recherche des magasins par coordonnées géographiques */
|
|
768
|
-
findByLocation(latitude, longitude,
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
),
|
|
775
|
-
"cache-first",
|
|
776
|
-
15 * 6e4
|
|
777
|
-
// 15 minutes
|
|
778
|
-
);
|
|
768
|
+
findByLocation(latitude, longitude, countryCode = "FRA", count = 10, feature) {
|
|
769
|
+
const country = countryCode.toUpperCase();
|
|
770
|
+
let url = `/commerce/api/stores/locator/by-proximity/${country}?latitude=${latitude}&longitude=${longitude}&count=${count}`;
|
|
771
|
+
if (feature) url += `&feature=${encodeURIComponent(feature)}`;
|
|
772
|
+
const key = `stores:geo:${country}:${latitude.toFixed(4)}:${longitude.toFixed(4)}:${count}:${feature ?? ""}`;
|
|
773
|
+
return this.cache.execute(key, () => this.http.get(url), "cache-first", 5 * 6e4);
|
|
779
774
|
}
|
|
780
775
|
/** Recherche des magasins par code postal */
|
|
781
|
-
findByPostalCode(postalCode, countryCode = "
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
),
|
|
788
|
-
"cache-first",
|
|
789
|
-
15 * 6e4
|
|
790
|
-
);
|
|
776
|
+
findByPostalCode(postalCode, countryCode = "FRA", count = 10, feature) {
|
|
777
|
+
const country = countryCode.toUpperCase();
|
|
778
|
+
let url = `/commerce/api/stores/locator/by-proximity/${country}/${encodeURIComponent(postalCode)}?count=${count}`;
|
|
779
|
+
if (feature) url += `&feature=${encodeURIComponent(feature)}`;
|
|
780
|
+
const key = `stores:postal:${country}:${postalCode}:${count}:${feature ?? ""}`;
|
|
781
|
+
return this.cache.execute(key, () => this.http.get(url), "cache-first", 15 * 6e4);
|
|
791
782
|
}
|
|
792
783
|
/** Récupère le détail d'un magasin par son GUID */
|
|
793
784
|
getStore(storeGuid) {
|
|
794
785
|
return this.cache.execute(
|
|
795
786
|
`stores:detail:${storeGuid}`,
|
|
796
|
-
() => this.http.get(`/commerce/api/stores/${storeGuid}`),
|
|
787
|
+
() => this.http.get(`/commerce/api/stores/locator/${storeGuid}`),
|
|
797
788
|
"stale-while-revalidate"
|
|
798
789
|
);
|
|
799
790
|
}
|
|
791
|
+
/** Récupère le magasin associé à la session en cours (null si aucun) */
|
|
792
|
+
async getSessionStore() {
|
|
793
|
+
try {
|
|
794
|
+
return await this.http.get("/commerce/api/stores/locator/from-session");
|
|
795
|
+
} catch {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
800
799
|
}
|
|
801
800
|
class DeviceNotification {
|
|
802
801
|
constructor() {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","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/CartSummaryStore.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/kiosk/DeviceManager.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 { WorkerBridge } from '../../workers/WorkerBridge.js'\nimport type { Cart, CartContent, CartLine, CartSummarySnapshot, CartSummaryContentSnapshot } from '../../types/index.js'\n\nconst CART_SUMMARY_KEY = 'cart:summary:current'\nconst DEFAULT_SUMMARY_STALE_TTL_MS = 90_000\nconst DEFAULT_STORAGE_TTL_MS = 24 * 60 * 60_000\n\nexport interface CartSummaryStoreOptions {\n staleTtlMs?: number\n storageTtlMs?: number\n}\n\nexport class CartSummaryStore {\n private summary: CartSummarySnapshot | null = null\n private readonly staleTtlMs: number\n private readonly storageTtlMs: number\n\n constructor(\n private readonly bridge: WorkerBridge,\n options?: CartSummaryStoreOptions\n ) {\n this.staleTtlMs = options?.staleTtlMs ?? DEFAULT_SUMMARY_STALE_TTL_MS\n this.storageTtlMs = options?.storageTtlMs ?? DEFAULT_STORAGE_TTL_MS\n }\n\n peek(): CartSummarySnapshot | null {\n return this.summary\n }\n\n async get(): Promise<CartSummarySnapshot | null> {\n if (this.summary !== null) {\n return this.summary\n }\n\n this.summary = await this.bridge.get<CartSummarySnapshot>(CART_SUMMARY_KEY)\n return this.summary\n }\n\n isStale(summary: CartSummarySnapshot | null): boolean {\n if (summary === null) {\n return true\n }\n\n return Date.now() >= Date.parse(summary.staleAt)\n }\n\n async setFromCart(cart: Cart): Promise<CartSummarySnapshot> {\n const now = Date.now()\n const summary = buildCartSummarySnapshot(cart, now, this.staleTtlMs)\n\n this.summary = summary\n await this.bridge.set(CART_SUMMARY_KEY, summary, this.storageTtlMs)\n return summary\n }\n\n async clear(): Promise<void> {\n this.summary = null\n await this.bridge.invalidate('^cart:summary:current$')\n }\n}\n\nfunction buildCartSummarySnapshot(cart: Cart, now: number, staleTtlMs: number): CartSummarySnapshot {\n const content = cart.content ?? []\n const topLevelLines = content.flatMap((entry) => getMainLines(entry))\n\n return {\n cartGuid: cart.guid,\n sourceCartLastModifiedDate: cart.lastModifiedDate,\n cachedAt: new Date(now).toISOString(),\n staleAt: new Date(now + staleTtlMs).toISOString(),\n totalAmountWithTax: cart.totalAmountWithTax,\n totalQuantity: cart.totalQuantity,\n mainReferencesCount: countDistinctReferences(topLevelLines),\n mainQuantity: sumQuantities(topLevelLines),\n contents: content.map((entry) => buildContentSummary(entry)),\n }\n}\n\nfunction buildContentSummary(content: CartContent): CartSummaryContentSnapshot {\n const mainLines = getMainLines(content)\n\n return {\n contentType: content.contentType,\n totalAmountWithTax: content.totalAmountWithTax,\n mainReferencesCount: countDistinctReferences(mainLines),\n mainLinesCount: mainLines.length,\n mainQuantity: sumQuantities(mainLines),\n }\n}\n\nfunction getMainLines(content: CartContent): CartLine[] {\n return (content.lines ?? []).filter((line) => !line.parentLineId)\n}\n\nfunction countDistinctReferences(lines: CartLine[]): number {\n const keys = new Set<string>()\n\n for (const line of lines) {\n const key = line.reference?.trim() || line.productGuid\n if (key) {\n keys.add(key)\n }\n }\n\n return keys.size\n}\n\nfunction sumQuantities(lines: CartLine[]): number {\n return lines.reduce((total, line) => total + line.quantity, 0)\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, CartLine, CartSummarySnapshot, CartValidationStatus } from '../../types/index.js'\nimport { CartSummaryStore } from './CartSummaryStore.js'\nimport type { WorkerBridge } from '../../workers/WorkerBridge.js'\n\nexport class CartModule {\n private readonly summaryStore: CartSummaryStore\n\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy,\n private readonly connectivity: ConnectivityManager,\n bridge: WorkerBridge\n ) {\n this.summaryStore = new CartSummaryStore(bridge)\n }\n\n /** Récupère le panier en cours */\n async getCart(): Promise<Cart> {\n const cart = await this.cache.execute(\n 'cart:current',\n () => this.http.get<Cart>('/commerce/api/process/cart'),\n 'network-first'\n )\n\n await this.summaryStore.setFromCart(cart)\n return cart\n }\n\n /** Retourne le dernier résumé panier disponible sans forcer un accès réseau */\n peekSummary(): CartSummarySnapshot | null {\n return this.summaryStore.peek()\n }\n\n /** Retourne le résumé panier local et lance une revalidation lazy si nécessaire */\n async getSummary(): Promise<CartSummarySnapshot | null> {\n const summary = await this.summaryStore.get()\n\n if (summary !== null) {\n if (this.summaryStore.isStale(summary) && !this.connectivity.isOffline) {\n void this.refreshSummary()\n }\n\n return summary\n }\n\n if (this.connectivity.isOffline) {\n return null\n }\n\n return this.refreshSummary()\n }\n\n /** Force le rechargement du panier puis du résumé local */\n async refreshSummary(): Promise<CartSummarySnapshot> {\n const cart = await this.getCart()\n return this.summaryStore.setFromCart(cart)\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 normalizedReference = reference.trim()\n if (normalizedReference.length === 0) {\n throw new Error('La reference produit est requise pour ajouter un article au panier')\n }\n\n const normalizedQuantity = Math.max(1, Math.floor(quantity))\n const previousQuantity = await this.getExistingQuantity(normalizedReference)\n let cart = await this.http.post<Cart>(this.buildAddItemUrl(normalizedReference, options))\n\n if (normalizedQuantity > 1 || previousQuantity > 0) {\n const line = this.findLineByReference(cart, normalizedReference)\n if (line) {\n cart = await this.http.post<Cart>(`/commerce/api/process/cart/${encodeURIComponent(line.id)}/quantity?qty=${previousQuantity + normalizedQuantity}`)\n }\n }\n\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\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 normalizedQuantity = Math.max(0, Math.floor(quantity))\n const cart = await this.http.post<Cart>(`/commerce/api/process/cart/${encodeURIComponent(lineId)}/quantity?qty=${normalizedQuantity}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\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/${encodeURIComponent(lineId)}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\n return cart\n }\n\n /** Applique un coupon */\n async applyCoupon(code: string): Promise<Cart> {\n this.ensureOnline()\n const normalizedCode = code.trim()\n if (normalizedCode.length === 0) {\n throw new Error('Le code coupon est requis')\n }\n\n const cart = await this.http.post<Cart>(`/commerce/api/process/cart/coupons/${encodeURIComponent(normalizedCode)}/add`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\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 await this.summaryStore.setFromCart(cart)\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 private async getExistingQuantity(reference: string): Promise<number> {\n try {\n const cart = await this.getCart()\n const line = this.findLineByReference(cart, reference)\n return line?.quantity ?? 0\n } catch {\n return 0\n }\n }\n\n private findLineByReference(cart: Cart | null | undefined, reference: string): CartLine | null {\n const normalizedReference = reference.trim().toUpperCase()\n if (normalizedReference.length === 0) {\n return null\n }\n\n for (const content of cart?.content ?? []) {\n for (const line of content.lines ?? []) {\n if ((line.reference ?? '').trim().toUpperCase() === normalizedReference) {\n return line\n }\n }\n }\n\n return null\n }\n\n private buildAddItemUrl(reference: string, options?: Record<string, unknown>): string {\n const query = new URLSearchParams()\n\n for (const [key, value] of Object.entries(options ?? {})) {\n if (value === undefined || value === null) {\n continue\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entry !== undefined && entry !== null) {\n query.append(key, String(entry))\n }\n }\n\n continue\n }\n\n query.append(key, String(value))\n }\n\n const queryString = query.toString()\n return `/commerce/api/process/cart/add/${encodeURIComponent(reference)}${queryString ? `?${queryString}` : ''}`\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","export class DeviceNotification {\n kind!: string\n associatedDevice?: string\n jsonData?: string\n rawData?: unknown\n\n getData<T = unknown>(): T | null {\n return decodeNotificationData<T>(this.rawData ?? this.jsonData)\n }\n\n getRecordData(): Record<string, unknown> | null {\n return asRecord(this.getData())\n }\n\n getNormalizedPayload(): DeviceNormalizedPayload | null {\n const raw = this.getRecordData()\n if (!raw) {\n return null\n }\n\n return normalizeDevicePayload(raw, this.associatedDevice)\n }\n}\n\nexport interface DeviceNormalizedPayload {\n associatedDevice?: string\n status?: string\n orderGuid?: string\n orderNumber?: string\n mrgGuid?: string\n amount?: number\n currency?: string\n reasonCode?: string\n reasonMessage?: string\n transactionId?: string\n barcode?: string\n symbology?: string\n raw: Record<string, unknown>\n}\n\nexport type DeviceNotificationListener = (notification: DeviceNotification) => void\nexport type DeviceOperationListener = (type: string, orderGuid: string, notification: DeviceNotification) => void\n\nexport class PeripheralBase {\n name = ''\n guid = ''\n type = ''\n state: string | null = null\n\n isAvailable(): boolean {\n if (this.state == null) {\n return true\n }\n\n switch (this.state.toLowerCase()) {\n case 'available':\n case 'active':\n return true\n default:\n return false\n }\n }\n\n IsAvailable(): boolean {\n return this.isAvailable()\n }\n}\n\nexport abstract class PeripheralBarCode extends PeripheralBase {\n protected globalListener?: DeviceNotificationListener\n protected successListener?: DeviceOperationListener\n protected failureListener?: DeviceOperationListener\n\n on(callback: DeviceNotificationListener): void {\n this.globalListener = callback\n }\n\n onSuccess(callback: DeviceOperationListener): void {\n this.successListener = callback\n }\n\n onError(callback: DeviceOperationListener): void {\n this.failureListener = callback\n }\n\n dispatchNotification(notification: DeviceNotification): void {\n this.globalListener?.(notification)\n }\n\n dispatchSuccess(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.successListener?.(type, orderGuid, notification)\n }\n\n dispatchFailure(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.failureListener?.(type, orderGuid, notification)\n }\n}\n\nexport abstract class PeripheralTpe extends PeripheralBase {\n protected globalListener?: DeviceNotificationListener\n protected successListener?: DeviceOperationListener\n protected failureListener?: DeviceOperationListener\n\n on(callback: DeviceNotificationListener): void {\n this.globalListener = callback\n }\n\n onSuccess(callback: DeviceOperationListener): void {\n this.successListener = callback\n }\n\n onFailure(callback: DeviceOperationListener): void {\n this.failureListener = callback\n }\n\n onError(callback: DeviceOperationListener): void {\n this.failureListener = callback\n }\n\n dispatchNotification(notification: DeviceNotification): void {\n this.globalListener?.(notification)\n }\n\n dispatchSuccess(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.successListener?.(type, orderGuid, notification)\n }\n\n dispatchFailure(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.failureListener?.(type, orderGuid, notification)\n }\n\n abstract makePayment(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void\n abstract makeRefund(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void\n abstract cancelPendingPayment(): void\n}\n\ninterface WebViewMessageEvent {\n data: unknown\n}\n\ninterface WebViewHost {\n postMessage(message: unknown): void\n addEventListener(type: 'message', listener: (event: WebViewMessageEvent) => void): void\n removeEventListener(type: 'message', listener: (event: WebViewMessageEvent) => void): void\n}\n\ninterface HostDeviceDescriptor {\n guid?: string\n name?: string\n type?: string\n state?: string\n status?: string\n deviceGuid?: string\n deviceName?: string\n label?: string\n kind?: string\n deviceKind?: string\n}\n\ninterface WindowWithWebView extends Window {\n chrome?: {\n webview?: WebViewHost\n }\n}\n\nexport class DeviceManager {\n private initialized = false\n private globalListener?: DeviceNotificationListener\n private peripherals: PeripheralBase[] = []\n private readonly host: WebViewHost | null\n private readonly hostListener = (event: WebViewMessageEvent): void => {\n const notification = this.normalizeNotification(event.data)\n if (notification) {\n this.notify(notification)\n }\n }\n\n constructor() {\n this.host = this.resolveHost()\n this.host?.addEventListener('message', this.hostListener)\n }\n\n get isHostAvailable(): boolean {\n return this.host !== null\n }\n\n registerGlobalCallback(callback: DeviceNotificationListener): void {\n if (!this.initialized) {\n this.initialize()\n }\n\n this.globalListener = callback\n }\n\n initialize(mockMode = false): void {\n if (!mockMode && !this.isHostAvailable) {\n return\n }\n\n this.initialized = true\n this.peripherals = []\n\n if (mockMode) {\n const mockTpe = new DeviceTpeMock((notification) => this.notify(notification))\n mockTpe.guid = '86602b7f-3d17-4715-9b5f-7109f4fe92f4'\n mockTpe.name = 'MockTPE'\n mockTpe.type = 'TPE'\n this.peripherals.push(mockTpe)\n return\n }\n\n this.host?.postMessage({\n kind: 'DeviceManager.Init',\n })\n }\n\n init(mockMode = false): void {\n this.initialize(mockMode)\n }\n\n dispose(): void {\n this.host?.removeEventListener('message', this.hostListener)\n }\n\n findPeripheral(guid: string): PeripheralBase | null {\n if (!this.initialized) {\n this.initialize()\n }\n\n for (const peripheral of this.peripherals) {\n if (peripheral.guid === guid) {\n return peripheral\n }\n }\n\n return null\n }\n\n findPeripheralByType(type: string): PeripheralBase[] {\n if (!this.initialized) {\n this.initialize()\n }\n\n return this.peripherals.filter((peripheral) => peripheral.type.toLowerCase() === type.toLowerCase())\n }\n\n findPeripheralsByType(type: string): PeripheralBase[] {\n return this.findPeripheralByType(type)\n }\n\n notify(notification: DeviceNotification): void {\n if (notification.kind.trim().length === 0) {\n return\n }\n\n const kind = notification.kind.toLowerCase()\n\n switch (kind) {\n case 'status_update': {\n const device = notification.associatedDevice ? this.findPeripheral(notification.associatedDevice) : null\n const status = this.readStatus(notification)\n if (device && status) {\n device.state = status\n }\n this.globalListener?.(notification)\n break\n }\n\n case 'init': {\n this.initialized = true\n this.peripherals = this.createPeripherals(resolveDeviceDescriptors(notification.getData()))\n this.globalListener?.(notification)\n return\n }\n\n default:\n this.globalListener?.(notification)\n break\n }\n\n if (kind.startsWith('tpe:') || kind.startsWith('barcode:')) {\n this.dispatchPeripheralNotification(notification, kind)\n }\n }\n\n changeShellState(newState: string): void {\n this.host?.postMessage({\n kind: 'shell.state-change',\n data: {\n desiredState: newState,\n },\n })\n }\n\n sendAppStatusUpdate(currentApp: string, currentStatus: string, value: string | null = null): void {\n this.host?.postMessage({\n kind: 'app.status-update',\n data: {\n app: currentApp,\n status: currentStatus,\n value,\n },\n })\n }\n\n private resolveHost(): WebViewHost | null {\n if (typeof window === 'undefined') {\n return null\n }\n\n return (window as WindowWithWebView).chrome?.webview ?? null\n }\n\n private normalizeNotification(data: unknown): DeviceNotification | null {\n if (data instanceof DeviceNotification) {\n if (data.rawData === undefined && data.jsonData !== undefined) {\n data.rawData = data.jsonData\n }\n return data\n }\n\n const candidate = resolveNotificationRecord(data)\n if (!candidate) {\n return null\n }\n\n const kind = normalizeNotificationKind(readStringValue(candidate, ['kind', 'Kind', 'eventKind', 'notificationKind', 'type', 'Type']))\n if (!kind) {\n return null\n }\n\n const notification = new DeviceNotification()\n const payload = resolveNotificationPayload(candidate)\n notification.kind = kind\n notification.associatedDevice = readStringValue(candidate, [\n 'associatedDevice',\n 'AssociatedDevice',\n 'associatedDeviceGuid',\n 'AssociatedDeviceGuid',\n 'deviceGuid',\n 'DeviceGuid',\n 'deviceId',\n 'DeviceId',\n 'peripheralGuid',\n 'PeripheralGuid',\n ]) ?? readAssociatedDeviceValue(payload) ?? undefined\n notification.rawData = payload\n notification.jsonData = encodeNotificationData(payload)\n return notification\n }\n\n private createPeripherals(devices: HostDeviceDescriptor[]): PeripheralBase[] {\n const peripherals: PeripheralBase[] = []\n\n for (const device of devices) {\n const peripheral = this.createPeripheral(device)\n if (peripheral) {\n peripherals.push(peripheral)\n }\n }\n\n return peripherals\n }\n\n private createPeripheral(device: HostDeviceDescriptor): PeripheralBase | null {\n const type = readStringValue(device, ['type', 'kind', 'deviceKind'])?.toLowerCase()\n let peripheral: PeripheralBase | null\n\n switch (type) {\n case 'tpe':\n peripheral = new DeviceTpeShell(\n (notification) => this.notify(notification),\n (message) => this.host?.postMessage(message),\n )\n break\n case 'barcodescanner':\n case 'barcode':\n peripheral = new DeviceBarCodeShell()\n break\n default:\n peripheral = new PeripheralBase()\n break\n }\n\n peripheral.guid = readStringValue(device, ['guid', 'deviceGuid', 'id']) ?? ''\n peripheral.name = readStringValue(device, ['name', 'deviceName', 'label']) ?? ''\n peripheral.type = readStringValue(device, ['type', 'kind', 'deviceKind']) ?? ''\n peripheral.state = readStringValue(device, ['state', 'status']) ?? null\n return peripheral\n }\n\n private readStatus(notification: DeviceNotification): string | null {\n return notification.getNormalizedPayload()?.status ?? null\n }\n\n private dispatchPeripheralNotification(notification: DeviceNotification, kind: string): void {\n if (!notification.associatedDevice) {\n return\n }\n\n const device = this.findPeripheral(notification.associatedDevice)\n if (!device) {\n return\n }\n\n const orderGuid = notification.getNormalizedPayload()?.orderGuid ?? ''\n\n if (device instanceof PeripheralTpe) {\n switch (kind) {\n case 'tpe:payment-success':\n device.dispatchSuccess('payment', orderGuid, notification)\n break\n case 'tpe:payment-failure':\n device.dispatchFailure('payment', orderGuid, notification)\n break\n case 'tpe:refund-success':\n device.dispatchSuccess('refund', orderGuid, notification)\n break\n case 'tpe:refund-failure':\n device.dispatchFailure('refund', orderGuid, notification)\n break\n default:\n break\n }\n\n device.dispatchNotification(notification)\n return\n }\n\n if (device instanceof PeripheralBarCode) {\n switch (kind) {\n case 'barcode:scan':\n device.dispatchSuccess('scan', orderGuid, notification)\n break\n case 'barcode:error':\n device.dispatchFailure('scan', orderGuid, notification)\n break\n default:\n break\n }\n\n device.dispatchNotification(notification)\n }\n }\n}\n\nfunction decodeNotificationData<T>(value: unknown): T | null {\n const decoded = unwrapSerializedData(value)\n return decoded == null ? null : decoded as T\n}\n\nfunction unwrapSerializedData(value: unknown): unknown {\n let current = value\n\n for (let index = 0; index < 3; index += 1) {\n if (current == null) {\n return null\n }\n\n if (typeof current !== 'string') {\n return current\n }\n\n const trimmed = current.trim()\n if (trimmed.length === 0) {\n return null\n }\n\n try {\n current = JSON.parse(trimmed)\n continue\n } catch {\n return current\n }\n }\n\n return current\n}\n\nfunction encodeNotificationData(value: unknown): string | undefined {\n if (value == null) {\n return undefined\n }\n\n if (typeof value === 'string') {\n return value\n }\n\n try {\n return JSON.stringify(value)\n } catch {\n return undefined\n }\n}\n\nfunction resolveNotificationRecord(data: unknown): Record<string, unknown> | null {\n let current = asRecord(data)\n\n for (let depth = 0; depth < 4 && current; depth += 1) {\n if (readStringValue(current, ['kind', 'Kind', 'eventKind', 'notificationKind', 'type', 'Type'])) {\n return current\n }\n\n const nested = firstRecord(current, ['message', 'notification', 'event', 'payload', 'data', 'Data'])\n if (!nested) {\n return null\n }\n\n current = nested\n }\n\n return null\n}\n\nfunction resolveNotificationPayload(notification: Record<string, unknown>): unknown {\n for (const key of ['jsonData', 'JsonData', 'payload', 'Payload', 'json', 'Json', 'data', 'Data']) {\n if (!(key in notification)) {\n continue\n }\n\n const value = notification[key]\n if (typeof value === 'string' || Array.isArray(value)) {\n return value\n }\n\n const nested = asRecord(value)\n if (nested && !readStringValue(nested, ['kind', 'Kind', 'eventKind', 'notificationKind', 'type', 'Type'])) {\n return value\n }\n }\n\n return undefined\n}\n\nfunction normalizeNotificationKind(value: string | null): string | null {\n if (!value) {\n return null\n }\n\n const normalized = value.trim().toLowerCase().replace(/\\s+/g, '')\n const unified = normalized.replace(/[.\\/]+/g, ':').replace(/_/g, '-')\n\n switch (unified) {\n case 'init':\n case 'devicemanager:init':\n case 'device-manager:init':\n return 'init'\n case 'status-update':\n case 'statusupdate':\n return 'status_update'\n default:\n if (unified.startsWith('tpe-')) {\n return `tpe:${unified.slice('tpe-'.length)}`\n }\n\n if (unified.startsWith('barcode-')) {\n return `barcode:${unified.slice('barcode-'.length)}`\n }\n\n return unified\n }\n}\n\nfunction firstRecord(source: Record<string, unknown>, keys: string[]): Record<string, unknown> | null {\n for (const key of keys) {\n const value = source[key]\n const record = asRecord(value)\n if (record) {\n return record\n }\n }\n\n return null\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n return value as Record<string, unknown>\n}\n\nfunction readStringValue(source: object, keys: string[]): string | null {\n const record = source as Record<string, unknown>\n\n for (const key of keys) {\n const value = record[key]\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (trimmed.length > 0) {\n return trimmed\n }\n }\n }\n\n return null\n}\n\nfunction resolveDeviceDescriptors(payload: unknown): HostDeviceDescriptor[] {\n if (Array.isArray(payload)) {\n return payload.filter((entry): entry is HostDeviceDescriptor => asRecord(entry) !== null)\n }\n\n const record = asRecord(payload)\n if (!record) {\n return []\n }\n\n for (const key of ['devices', 'Devices', 'peripherals', 'Peripherals', 'data', 'Data']) {\n const value = record[key]\n if (Array.isArray(value)) {\n return value.filter((entry): entry is HostDeviceDescriptor => asRecord(entry) !== null)\n }\n\n const nested = asRecord(value)\n if (nested) {\n const nestedDevices = resolveDeviceDescriptors(nested)\n if (nestedDevices.length > 0) {\n return nestedDevices\n }\n }\n }\n\n return []\n}\n\nfunction readAssociatedDeviceValue(payload: unknown): string | null {\n const record = asRecord(payload)\n if (!record) {\n return null\n }\n\n const direct = readStringValue(record, [\n 'associatedDevice',\n 'AssociatedDevice',\n 'associatedDeviceGuid',\n 'AssociatedDeviceGuid',\n 'deviceGuid',\n 'DeviceGuid',\n 'deviceId',\n 'DeviceId',\n 'peripheralGuid',\n 'PeripheralGuid',\n ])\n if (direct) {\n return direct\n }\n\n for (const key of ['data', 'Data', 'payload', 'Payload']) {\n const nested = asRecord(record[key])\n if (!nested) {\n continue\n }\n\n const nestedDevice = readAssociatedDeviceValue(nested)\n if (nestedDevice) {\n return nestedDevice\n }\n }\n\n return null\n}\n\nfunction normalizeDevicePayload(\n record: Record<string, unknown>,\n associatedDevice?: string,\n): DeviceNormalizedPayload {\n return {\n associatedDevice: associatedDevice ?? readAssociatedDeviceValue(record) ?? undefined,\n status: readStringValueDeep(record, ['status', 'Status', 'state', 'State']) ?? undefined,\n orderGuid: readStringValueDeep(record, ['orderGuid', 'OrderGuid', 'orderGUID', 'orderId', 'OrderId']) ?? undefined,\n orderNumber: readStringValueDeep(record, ['orderNumber', 'OrderNumber', 'reference', 'Reference']) ?? undefined,\n mrgGuid: readStringValueDeep(record, ['mrgGuid', 'MrgGuid', 'mrgId', 'MrgId']) ?? undefined,\n amount: readNumberValueDeep(record, ['amount', 'Amount', 'totalAmount', 'TotalAmount']) ?? undefined,\n currency: readStringValueDeep(record, ['currency', 'Currency', 'currencyCode', 'CurrencyCode']) ?? undefined,\n reasonCode: readStringValueDeep(record, ['reasonCode', 'ReasonCode', 'code', 'Code']) ?? undefined,\n reasonMessage: readStringValueDeep(record, ['reasonMessage', 'ReasonMessage', 'message', 'Message']) ?? undefined,\n transactionId: readStringValueDeep(record, ['transactionId', 'TransactionId', 'transactionNumber', 'TransactionNumber']) ?? undefined,\n barcode: readStringValueDeep(record, ['barcode', 'Barcode', 'value', 'Value', 'scanValue', 'ScanValue']) ?? undefined,\n symbology: readStringValueDeep(record, ['symbology', 'Symbology', 'barcodeType', 'BarcodeType']) ?? undefined,\n raw: record,\n }\n}\n\nfunction readStringValueDeep(source: Record<string, unknown>, keys: string[]): string | null {\n const direct = readStringValue(source, keys)\n if (direct) {\n return direct\n }\n\n for (const key of ['data', 'Data', 'payload', 'Payload', 'result', 'Result']) {\n const nested = asRecord(source[key])\n if (!nested) {\n continue\n }\n\n const nestedValue = readStringValueDeep(nested, keys)\n if (nestedValue) {\n return nestedValue\n }\n }\n\n return null\n}\n\nfunction readNumberValueDeep(source: Record<string, unknown>, keys: string[]): number | null {\n const direct = readNumberValue(source, keys)\n if (direct !== null) {\n return direct\n }\n\n for (const key of ['data', 'Data', 'payload', 'Payload', 'result', 'Result']) {\n const nested = asRecord(source[key])\n if (!nested) {\n continue\n }\n\n const nestedValue = readNumberValueDeep(nested, keys)\n if (nestedValue !== null) {\n return nestedValue\n }\n }\n\n return null\n}\n\nfunction readNumberValue(source: Record<string, unknown>, keys: string[]): number | null {\n for (const key of keys) {\n const value = source[key]\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value\n }\n\n if (typeof value === 'string') {\n const parsed = Number(value.trim())\n if (Number.isFinite(parsed)) {\n return parsed\n }\n }\n }\n\n return null\n}\n\nfunction readOrderGuid(payload: unknown): string {\n const record = asRecord(payload)\n if (!record) {\n return ''\n }\n\n return normalizeDevicePayload(record).orderGuid ?? ''\n}\n\nclass DeviceTpeMock extends PeripheralTpe {\n private cancelled = false\n\n constructor(private readonly emitNotification: (notification: DeviceNotification) => void) {\n super()\n }\n\n makePayment(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.cancelled = false\n\n this.schedule(200, () => this.createNotification('TPE:Progress', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'START',\n reasonMessage: 'Veuillez suivre les instructions sur le terminal de paiement',\n }))\n\n this.schedule(2500, () => this.createNotification('TPE:Progress', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'PINCODE',\n reasonMessage: 'Saisie du pin-code en attente',\n }))\n\n if (orderNumber.startsWith('F')) {\n this.schedule(7500, () => this.createNotification('TPE:Payment-Failure', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'FAKE',\n reasonMessage: \"Votre paiement n'a pas pu être traité\",\n }))\n return\n }\n\n this.schedule(7500, () => this.createNotification('TPE:Payment-Success', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n transactionId: 'FakeTransactionNumber',\n reasonCode: 'FAKE',\n reasonMessage: 'Paiement terminé',\n }))\n }\n\n makeRefund(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.cancelled = false\n this.schedule(2500, () => this.createNotification('TPE:Refund-Failure', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'FAKE',\n reasonMessage: \"Votre paiement n'a pas pu être remboursé : nous sommes en mode mock\",\n }))\n }\n\n cancelPendingPayment(): void {\n this.cancelled = true\n\n this.schedule(2500, () => this.createNotification('TPE:Payment-Failure', {\n reasonCode: 'CANCEL',\n reasonMessage: 'Paiement annulé',\n }))\n }\n\n private schedule(delay: number, factory: () => DeviceNotification): void {\n setTimeout(() => {\n if (!this.cancelled) {\n this.emitNotification(factory())\n }\n }, delay)\n }\n\n private createNotification(kind: string, payload: Record<string, unknown>): DeviceNotification {\n const notification = new DeviceNotification()\n notification.kind = kind\n notification.associatedDevice = this.guid\n notification.jsonData = JSON.stringify(payload)\n return notification\n }\n}\n\nclass DeviceTpeShell extends PeripheralTpe {\n constructor(\n private readonly emitNotification: (notification: DeviceNotification) => void,\n private readonly postMessage: (message: unknown) => void,\n ) {\n super()\n }\n\n setState(state: string): void {\n const notification = new DeviceNotification()\n notification.kind = 'STATUS_UPDATE'\n notification.associatedDevice = this.guid\n notification.jsonData = JSON.stringify({ status: state })\n this.emitNotification(notification)\n }\n\n makePayment(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.postMessage({\n deviceKind: 'TPE',\n deviceGuid: this.guid,\n kind: 'payment-request',\n data: {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n },\n })\n }\n\n makeRefund(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.postMessage({\n deviceKind: 'TPE',\n deviceGuid: this.guid,\n kind: 'refund-request',\n data: {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n },\n })\n }\n\n cancelPendingPayment(): void {\n this.postMessage({\n deviceKind: 'TPE',\n deviceGuid: this.guid,\n kind: 'payment-request-cancel',\n data: {},\n })\n }\n}\n\nclass DeviceBarCodeShell extends PeripheralBarCode {}","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 { DeviceManager } from '../kiosk/DeviceManager.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 readonly devices: DeviceManager\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 this.devices = new DeviceManager()\n\n // Modules API\n this.session = new SessionModule(this.http, this.cacheStrategy)\n this.cart = new CartModule(this.http, this.cacheStrategy, this.connectivity, this.workerBridge)\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 this.devices.dispose()\n }\n}\n"],"names":["data","_a","delay"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","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/CartSummaryStore.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/kiosk/DeviceManager.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 { WorkerBridge } from '../../workers/WorkerBridge.js'\nimport type { Cart, CartContent, CartLine, CartSummarySnapshot, CartSummaryContentSnapshot } from '../../types/index.js'\n\nconst CART_SUMMARY_KEY = 'cart:summary:current'\nconst DEFAULT_SUMMARY_STALE_TTL_MS = 90_000\nconst DEFAULT_STORAGE_TTL_MS = 24 * 60 * 60_000\n\nexport interface CartSummaryStoreOptions {\n staleTtlMs?: number\n storageTtlMs?: number\n}\n\nexport class CartSummaryStore {\n private summary: CartSummarySnapshot | null = null\n private readonly staleTtlMs: number\n private readonly storageTtlMs: number\n\n constructor(\n private readonly bridge: WorkerBridge,\n options?: CartSummaryStoreOptions\n ) {\n this.staleTtlMs = options?.staleTtlMs ?? DEFAULT_SUMMARY_STALE_TTL_MS\n this.storageTtlMs = options?.storageTtlMs ?? DEFAULT_STORAGE_TTL_MS\n }\n\n peek(): CartSummarySnapshot | null {\n return this.summary\n }\n\n async get(): Promise<CartSummarySnapshot | null> {\n if (this.summary !== null) {\n return this.summary\n }\n\n this.summary = await this.bridge.get<CartSummarySnapshot>(CART_SUMMARY_KEY)\n return this.summary\n }\n\n isStale(summary: CartSummarySnapshot | null): boolean {\n if (summary === null) {\n return true\n }\n\n return Date.now() >= Date.parse(summary.staleAt)\n }\n\n async setFromCart(cart: Cart): Promise<CartSummarySnapshot> {\n const now = Date.now()\n const summary = buildCartSummarySnapshot(cart, now, this.staleTtlMs)\n\n this.summary = summary\n await this.bridge.set(CART_SUMMARY_KEY, summary, this.storageTtlMs)\n return summary\n }\n\n async clear(): Promise<void> {\n this.summary = null\n await this.bridge.invalidate('^cart:summary:current$')\n }\n}\n\nfunction buildCartSummarySnapshot(cart: Cart, now: number, staleTtlMs: number): CartSummarySnapshot {\n const content = cart.content ?? []\n const topLevelLines = content.flatMap((entry) => getMainLines(entry))\n\n return {\n cartGuid: cart.guid,\n sourceCartLastModifiedDate: cart.lastModifiedDate,\n cachedAt: new Date(now).toISOString(),\n staleAt: new Date(now + staleTtlMs).toISOString(),\n totalAmountWithTax: cart.totalAmountWithTax,\n totalQuantity: cart.totalQuantity,\n mainReferencesCount: countDistinctReferences(topLevelLines),\n mainQuantity: sumQuantities(topLevelLines),\n contents: content.map((entry) => buildContentSummary(entry)),\n }\n}\n\nfunction buildContentSummary(content: CartContent): CartSummaryContentSnapshot {\n const mainLines = getMainLines(content)\n\n return {\n contentType: content.contentType,\n totalAmountWithTax: content.totalAmountWithTax,\n mainReferencesCount: countDistinctReferences(mainLines),\n mainLinesCount: mainLines.length,\n mainQuantity: sumQuantities(mainLines),\n }\n}\n\nfunction getMainLines(content: CartContent): CartLine[] {\n return (content.lines ?? []).filter((line) => !line.parentLineId)\n}\n\nfunction countDistinctReferences(lines: CartLine[]): number {\n const keys = new Set<string>()\n\n for (const line of lines) {\n const key = line.reference?.trim() || line.productGuid\n if (key) {\n keys.add(key)\n }\n }\n\n return keys.size\n}\n\nfunction sumQuantities(lines: CartLine[]): number {\n return lines.reduce((total, line) => total + line.quantity, 0)\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, CartLine, CartSummarySnapshot, CartValidationStatus } from '../../types/index.js'\nimport { CartSummaryStore } from './CartSummaryStore.js'\nimport type { WorkerBridge } from '../../workers/WorkerBridge.js'\n\nexport class CartModule {\n private readonly summaryStore: CartSummaryStore\n\n constructor(\n private readonly http: CommerceHttpAdapter,\n private readonly cache: CacheStrategy,\n private readonly connectivity: ConnectivityManager,\n bridge: WorkerBridge\n ) {\n this.summaryStore = new CartSummaryStore(bridge)\n }\n\n /** Récupère le panier en cours */\n async getCart(): Promise<Cart> {\n const cart = await this.cache.execute(\n 'cart:current',\n () => this.http.get<Cart>('/commerce/api/process/cart'),\n 'network-first'\n )\n\n await this.summaryStore.setFromCart(cart)\n return cart\n }\n\n /** Retourne le dernier résumé panier disponible sans forcer un accès réseau */\n peekSummary(): CartSummarySnapshot | null {\n return this.summaryStore.peek()\n }\n\n /** Retourne le résumé panier local et lance une revalidation lazy si nécessaire */\n async getSummary(): Promise<CartSummarySnapshot | null> {\n const summary = await this.summaryStore.get()\n\n if (summary !== null) {\n if (this.summaryStore.isStale(summary) && !this.connectivity.isOffline) {\n void this.refreshSummary()\n }\n\n return summary\n }\n\n if (this.connectivity.isOffline) {\n return null\n }\n\n return this.refreshSummary()\n }\n\n /** Force le rechargement du panier puis du résumé local */\n async refreshSummary(): Promise<CartSummarySnapshot> {\n const cart = await this.getCart()\n return this.summaryStore.setFromCart(cart)\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 normalizedReference = reference.trim()\n if (normalizedReference.length === 0) {\n throw new Error('La reference produit est requise pour ajouter un article au panier')\n }\n\n const normalizedQuantity = Math.max(1, Math.floor(quantity))\n const previousQuantity = await this.getExistingQuantity(normalizedReference)\n let cart = await this.http.post<Cart>(this.buildAddItemUrl(normalizedReference, options))\n\n if (normalizedQuantity > 1 || previousQuantity > 0) {\n const line = this.findLineByReference(cart, normalizedReference)\n if (line) {\n cart = await this.http.post<Cart>(`/commerce/api/process/cart/${encodeURIComponent(line.id)}/quantity?qty=${previousQuantity + normalizedQuantity}`)\n }\n }\n\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\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 normalizedQuantity = Math.max(0, Math.floor(quantity))\n const cart = await this.http.post<Cart>(`/commerce/api/process/cart/${encodeURIComponent(lineId)}/quantity?qty=${normalizedQuantity}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\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/${encodeURIComponent(lineId)}`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\n return cart\n }\n\n /** Applique un coupon */\n async applyCoupon(code: string): Promise<Cart> {\n this.ensureOnline()\n const normalizedCode = code.trim()\n if (normalizedCode.length === 0) {\n throw new Error('Le code coupon est requis')\n }\n\n const cart = await this.http.post<Cart>(`/commerce/api/process/cart/coupons/${encodeURIComponent(normalizedCode)}/add`)\n await this.cache.execute('cart:current', () => Promise.resolve(cart), 'network-first')\n await this.summaryStore.setFromCart(cart)\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 await this.summaryStore.setFromCart(cart)\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 private async getExistingQuantity(reference: string): Promise<number> {\n try {\n const cart = await this.getCart()\n const line = this.findLineByReference(cart, reference)\n return line?.quantity ?? 0\n } catch {\n return 0\n }\n }\n\n private findLineByReference(cart: Cart | null | undefined, reference: string): CartLine | null {\n const normalizedReference = reference.trim().toUpperCase()\n if (normalizedReference.length === 0) {\n return null\n }\n\n for (const content of cart?.content ?? []) {\n for (const line of content.lines ?? []) {\n if ((line.reference ?? '').trim().toUpperCase() === normalizedReference) {\n return line\n }\n }\n }\n\n return null\n }\n\n private buildAddItemUrl(reference: string, options?: Record<string, unknown>): string {\n const query = new URLSearchParams()\n\n for (const [key, value] of Object.entries(options ?? {})) {\n if (value === undefined || value === null) {\n continue\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entry !== undefined && entry !== null) {\n query.append(key, String(entry))\n }\n }\n\n continue\n }\n\n query.append(key, String(value))\n }\n\n const queryString = query.toString()\n return `/commerce/api/process/cart/add/${encodeURIComponent(reference)}${queryString ? `?${queryString}` : ''}`\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, countryCode = 'FRA', count = 10, feature?: string): Promise<StoreWithOpeningHours[]> {\n const country = countryCode.toUpperCase()\n let url = `/commerce/api/stores/locator/by-proximity/${country}?latitude=${latitude}&longitude=${longitude}&count=${count}`\n if (feature) url += `&feature=${encodeURIComponent(feature)}`\n const key = `stores:geo:${country}:${latitude.toFixed(4)}:${longitude.toFixed(4)}:${count}:${feature ?? ''}`\n return this.cache.execute(key, () => this.http.get<StoreWithOpeningHours[]>(url), 'cache-first', 5 * 60_000)\n }\n\n /** Recherche des magasins par code postal */\n findByPostalCode(postalCode: string, countryCode = 'FRA', count = 10, feature?: string): Promise<StoreWithOpeningHours[]> {\n const country = countryCode.toUpperCase()\n let url = `/commerce/api/stores/locator/by-proximity/${country}/${encodeURIComponent(postalCode)}?count=${count}`\n if (feature) url += `&feature=${encodeURIComponent(feature)}`\n const key = `stores:postal:${country}:${postalCode}:${count}:${feature ?? ''}`\n return this.cache.execute(key, () => this.http.get<StoreWithOpeningHours[]>(url), 'cache-first', 15 * 60_000)\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/locator/${storeGuid}`),\n 'stale-while-revalidate'\n )\n }\n\n /** Récupère le magasin associé à la session en cours (null si aucun) */\n async getSessionStore(): Promise<StoreWithOpeningHours | null> {\n try {\n return await this.http.get<StoreWithOpeningHours>('/commerce/api/stores/locator/from-session')\n } catch {\n return null\n }\n }\n}\n","export class DeviceNotification {\n kind!: string\n associatedDevice?: string\n jsonData?: string\n rawData?: unknown\n\n getData<T = unknown>(): T | null {\n return decodeNotificationData<T>(this.rawData ?? this.jsonData)\n }\n\n getRecordData(): Record<string, unknown> | null {\n return asRecord(this.getData())\n }\n\n getNormalizedPayload(): DeviceNormalizedPayload | null {\n const raw = this.getRecordData()\n if (!raw) {\n return null\n }\n\n return normalizeDevicePayload(raw, this.associatedDevice)\n }\n}\n\nexport interface DeviceNormalizedPayload {\n associatedDevice?: string\n status?: string\n orderGuid?: string\n orderNumber?: string\n mrgGuid?: string\n amount?: number\n currency?: string\n reasonCode?: string\n reasonMessage?: string\n transactionId?: string\n barcode?: string\n symbology?: string\n raw: Record<string, unknown>\n}\n\nexport type DeviceNotificationListener = (notification: DeviceNotification) => void\nexport type DeviceOperationListener = (type: string, orderGuid: string, notification: DeviceNotification) => void\n\nexport class PeripheralBase {\n name = ''\n guid = ''\n type = ''\n state: string | null = null\n\n isAvailable(): boolean {\n if (this.state == null) {\n return true\n }\n\n switch (this.state.toLowerCase()) {\n case 'available':\n case 'active':\n return true\n default:\n return false\n }\n }\n\n IsAvailable(): boolean {\n return this.isAvailable()\n }\n}\n\nexport abstract class PeripheralBarCode extends PeripheralBase {\n protected globalListener?: DeviceNotificationListener\n protected successListener?: DeviceOperationListener\n protected failureListener?: DeviceOperationListener\n\n on(callback: DeviceNotificationListener): void {\n this.globalListener = callback\n }\n\n onSuccess(callback: DeviceOperationListener): void {\n this.successListener = callback\n }\n\n onError(callback: DeviceOperationListener): void {\n this.failureListener = callback\n }\n\n dispatchNotification(notification: DeviceNotification): void {\n this.globalListener?.(notification)\n }\n\n dispatchSuccess(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.successListener?.(type, orderGuid, notification)\n }\n\n dispatchFailure(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.failureListener?.(type, orderGuid, notification)\n }\n}\n\nexport abstract class PeripheralTpe extends PeripheralBase {\n protected globalListener?: DeviceNotificationListener\n protected successListener?: DeviceOperationListener\n protected failureListener?: DeviceOperationListener\n\n on(callback: DeviceNotificationListener): void {\n this.globalListener = callback\n }\n\n onSuccess(callback: DeviceOperationListener): void {\n this.successListener = callback\n }\n\n onFailure(callback: DeviceOperationListener): void {\n this.failureListener = callback\n }\n\n onError(callback: DeviceOperationListener): void {\n this.failureListener = callback\n }\n\n dispatchNotification(notification: DeviceNotification): void {\n this.globalListener?.(notification)\n }\n\n dispatchSuccess(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.successListener?.(type, orderGuid, notification)\n }\n\n dispatchFailure(type: string, orderGuid: string, notification: DeviceNotification): void {\n this.failureListener?.(type, orderGuid, notification)\n }\n\n abstract makePayment(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void\n abstract makeRefund(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void\n abstract cancelPendingPayment(): void\n}\n\ninterface WebViewMessageEvent {\n data: unknown\n}\n\ninterface WebViewHost {\n postMessage(message: unknown): void\n addEventListener(type: 'message', listener: (event: WebViewMessageEvent) => void): void\n removeEventListener(type: 'message', listener: (event: WebViewMessageEvent) => void): void\n}\n\ninterface HostDeviceDescriptor {\n guid?: string\n name?: string\n type?: string\n state?: string\n status?: string\n deviceGuid?: string\n deviceName?: string\n label?: string\n kind?: string\n deviceKind?: string\n}\n\ninterface WindowWithWebView extends Window {\n chrome?: {\n webview?: WebViewHost\n }\n}\n\nexport class DeviceManager {\n private initialized = false\n private globalListener?: DeviceNotificationListener\n private peripherals: PeripheralBase[] = []\n private readonly host: WebViewHost | null\n private readonly hostListener = (event: WebViewMessageEvent): void => {\n const notification = this.normalizeNotification(event.data)\n if (notification) {\n this.notify(notification)\n }\n }\n\n constructor() {\n this.host = this.resolveHost()\n this.host?.addEventListener('message', this.hostListener)\n }\n\n get isHostAvailable(): boolean {\n return this.host !== null\n }\n\n registerGlobalCallback(callback: DeviceNotificationListener): void {\n if (!this.initialized) {\n this.initialize()\n }\n\n this.globalListener = callback\n }\n\n initialize(mockMode = false): void {\n if (!mockMode && !this.isHostAvailable) {\n return\n }\n\n this.initialized = true\n this.peripherals = []\n\n if (mockMode) {\n const mockTpe = new DeviceTpeMock((notification) => this.notify(notification))\n mockTpe.guid = '86602b7f-3d17-4715-9b5f-7109f4fe92f4'\n mockTpe.name = 'MockTPE'\n mockTpe.type = 'TPE'\n this.peripherals.push(mockTpe)\n return\n }\n\n this.host?.postMessage({\n kind: 'DeviceManager.Init',\n })\n }\n\n init(mockMode = false): void {\n this.initialize(mockMode)\n }\n\n dispose(): void {\n this.host?.removeEventListener('message', this.hostListener)\n }\n\n findPeripheral(guid: string): PeripheralBase | null {\n if (!this.initialized) {\n this.initialize()\n }\n\n for (const peripheral of this.peripherals) {\n if (peripheral.guid === guid) {\n return peripheral\n }\n }\n\n return null\n }\n\n findPeripheralByType(type: string): PeripheralBase[] {\n if (!this.initialized) {\n this.initialize()\n }\n\n return this.peripherals.filter((peripheral) => peripheral.type.toLowerCase() === type.toLowerCase())\n }\n\n findPeripheralsByType(type: string): PeripheralBase[] {\n return this.findPeripheralByType(type)\n }\n\n notify(notification: DeviceNotification): void {\n if (notification.kind.trim().length === 0) {\n return\n }\n\n const kind = notification.kind.toLowerCase()\n\n switch (kind) {\n case 'status_update': {\n const device = notification.associatedDevice ? this.findPeripheral(notification.associatedDevice) : null\n const status = this.readStatus(notification)\n if (device && status) {\n device.state = status\n }\n this.globalListener?.(notification)\n break\n }\n\n case 'init': {\n this.initialized = true\n this.peripherals = this.createPeripherals(resolveDeviceDescriptors(notification.getData()))\n this.globalListener?.(notification)\n return\n }\n\n default:\n this.globalListener?.(notification)\n break\n }\n\n if (kind.startsWith('tpe:') || kind.startsWith('barcode:')) {\n this.dispatchPeripheralNotification(notification, kind)\n }\n }\n\n changeShellState(newState: string): void {\n this.host?.postMessage({\n kind: 'shell.state-change',\n data: {\n desiredState: newState,\n },\n })\n }\n\n sendAppStatusUpdate(currentApp: string, currentStatus: string, value: string | null = null): void {\n this.host?.postMessage({\n kind: 'app.status-update',\n data: {\n app: currentApp,\n status: currentStatus,\n value,\n },\n })\n }\n\n private resolveHost(): WebViewHost | null {\n if (typeof window === 'undefined') {\n return null\n }\n\n return (window as WindowWithWebView).chrome?.webview ?? null\n }\n\n private normalizeNotification(data: unknown): DeviceNotification | null {\n if (data instanceof DeviceNotification) {\n if (data.rawData === undefined && data.jsonData !== undefined) {\n data.rawData = data.jsonData\n }\n return data\n }\n\n const candidate = resolveNotificationRecord(data)\n if (!candidate) {\n return null\n }\n\n const kind = normalizeNotificationKind(readStringValue(candidate, ['kind', 'Kind', 'eventKind', 'notificationKind', 'type', 'Type']))\n if (!kind) {\n return null\n }\n\n const notification = new DeviceNotification()\n const payload = resolveNotificationPayload(candidate)\n notification.kind = kind\n notification.associatedDevice = readStringValue(candidate, [\n 'associatedDevice',\n 'AssociatedDevice',\n 'associatedDeviceGuid',\n 'AssociatedDeviceGuid',\n 'deviceGuid',\n 'DeviceGuid',\n 'deviceId',\n 'DeviceId',\n 'peripheralGuid',\n 'PeripheralGuid',\n ]) ?? readAssociatedDeviceValue(payload) ?? undefined\n notification.rawData = payload\n notification.jsonData = encodeNotificationData(payload)\n return notification\n }\n\n private createPeripherals(devices: HostDeviceDescriptor[]): PeripheralBase[] {\n const peripherals: PeripheralBase[] = []\n\n for (const device of devices) {\n const peripheral = this.createPeripheral(device)\n if (peripheral) {\n peripherals.push(peripheral)\n }\n }\n\n return peripherals\n }\n\n private createPeripheral(device: HostDeviceDescriptor): PeripheralBase | null {\n const type = readStringValue(device, ['type', 'kind', 'deviceKind'])?.toLowerCase()\n let peripheral: PeripheralBase | null\n\n switch (type) {\n case 'tpe':\n peripheral = new DeviceTpeShell(\n (notification) => this.notify(notification),\n (message) => this.host?.postMessage(message),\n )\n break\n case 'barcodescanner':\n case 'barcode':\n peripheral = new DeviceBarCodeShell()\n break\n default:\n peripheral = new PeripheralBase()\n break\n }\n\n peripheral.guid = readStringValue(device, ['guid', 'deviceGuid', 'id']) ?? ''\n peripheral.name = readStringValue(device, ['name', 'deviceName', 'label']) ?? ''\n peripheral.type = readStringValue(device, ['type', 'kind', 'deviceKind']) ?? ''\n peripheral.state = readStringValue(device, ['state', 'status']) ?? null\n return peripheral\n }\n\n private readStatus(notification: DeviceNotification): string | null {\n return notification.getNormalizedPayload()?.status ?? null\n }\n\n private dispatchPeripheralNotification(notification: DeviceNotification, kind: string): void {\n if (!notification.associatedDevice) {\n return\n }\n\n const device = this.findPeripheral(notification.associatedDevice)\n if (!device) {\n return\n }\n\n const orderGuid = notification.getNormalizedPayload()?.orderGuid ?? ''\n\n if (device instanceof PeripheralTpe) {\n switch (kind) {\n case 'tpe:payment-success':\n device.dispatchSuccess('payment', orderGuid, notification)\n break\n case 'tpe:payment-failure':\n device.dispatchFailure('payment', orderGuid, notification)\n break\n case 'tpe:refund-success':\n device.dispatchSuccess('refund', orderGuid, notification)\n break\n case 'tpe:refund-failure':\n device.dispatchFailure('refund', orderGuid, notification)\n break\n default:\n break\n }\n\n device.dispatchNotification(notification)\n return\n }\n\n if (device instanceof PeripheralBarCode) {\n switch (kind) {\n case 'barcode:scan':\n device.dispatchSuccess('scan', orderGuid, notification)\n break\n case 'barcode:error':\n device.dispatchFailure('scan', orderGuid, notification)\n break\n default:\n break\n }\n\n device.dispatchNotification(notification)\n }\n }\n}\n\nfunction decodeNotificationData<T>(value: unknown): T | null {\n const decoded = unwrapSerializedData(value)\n return decoded == null ? null : decoded as T\n}\n\nfunction unwrapSerializedData(value: unknown): unknown {\n let current = value\n\n for (let index = 0; index < 3; index += 1) {\n if (current == null) {\n return null\n }\n\n if (typeof current !== 'string') {\n return current\n }\n\n const trimmed = current.trim()\n if (trimmed.length === 0) {\n return null\n }\n\n try {\n current = JSON.parse(trimmed)\n continue\n } catch {\n return current\n }\n }\n\n return current\n}\n\nfunction encodeNotificationData(value: unknown): string | undefined {\n if (value == null) {\n return undefined\n }\n\n if (typeof value === 'string') {\n return value\n }\n\n try {\n return JSON.stringify(value)\n } catch {\n return undefined\n }\n}\n\nfunction resolveNotificationRecord(data: unknown): Record<string, unknown> | null {\n let current = asRecord(data)\n\n for (let depth = 0; depth < 4 && current; depth += 1) {\n if (readStringValue(current, ['kind', 'Kind', 'eventKind', 'notificationKind', 'type', 'Type'])) {\n return current\n }\n\n const nested = firstRecord(current, ['message', 'notification', 'event', 'payload', 'data', 'Data'])\n if (!nested) {\n return null\n }\n\n current = nested\n }\n\n return null\n}\n\nfunction resolveNotificationPayload(notification: Record<string, unknown>): unknown {\n for (const key of ['jsonData', 'JsonData', 'payload', 'Payload', 'json', 'Json', 'data', 'Data']) {\n if (!(key in notification)) {\n continue\n }\n\n const value = notification[key]\n if (typeof value === 'string' || Array.isArray(value)) {\n return value\n }\n\n const nested = asRecord(value)\n if (nested && !readStringValue(nested, ['kind', 'Kind', 'eventKind', 'notificationKind', 'type', 'Type'])) {\n return value\n }\n }\n\n return undefined\n}\n\nfunction normalizeNotificationKind(value: string | null): string | null {\n if (!value) {\n return null\n }\n\n const normalized = value.trim().toLowerCase().replace(/\\s+/g, '')\n const unified = normalized.replace(/[.\\/]+/g, ':').replace(/_/g, '-')\n\n switch (unified) {\n case 'init':\n case 'devicemanager:init':\n case 'device-manager:init':\n return 'init'\n case 'status-update':\n case 'statusupdate':\n return 'status_update'\n default:\n if (unified.startsWith('tpe-')) {\n return `tpe:${unified.slice('tpe-'.length)}`\n }\n\n if (unified.startsWith('barcode-')) {\n return `barcode:${unified.slice('barcode-'.length)}`\n }\n\n return unified\n }\n}\n\nfunction firstRecord(source: Record<string, unknown>, keys: string[]): Record<string, unknown> | null {\n for (const key of keys) {\n const value = source[key]\n const record = asRecord(value)\n if (record) {\n return record\n }\n }\n\n return null\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n return value as Record<string, unknown>\n}\n\nfunction readStringValue(source: object, keys: string[]): string | null {\n const record = source as Record<string, unknown>\n\n for (const key of keys) {\n const value = record[key]\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (trimmed.length > 0) {\n return trimmed\n }\n }\n }\n\n return null\n}\n\nfunction resolveDeviceDescriptors(payload: unknown): HostDeviceDescriptor[] {\n if (Array.isArray(payload)) {\n return payload.filter((entry): entry is HostDeviceDescriptor => asRecord(entry) !== null)\n }\n\n const record = asRecord(payload)\n if (!record) {\n return []\n }\n\n for (const key of ['devices', 'Devices', 'peripherals', 'Peripherals', 'data', 'Data']) {\n const value = record[key]\n if (Array.isArray(value)) {\n return value.filter((entry): entry is HostDeviceDescriptor => asRecord(entry) !== null)\n }\n\n const nested = asRecord(value)\n if (nested) {\n const nestedDevices = resolveDeviceDescriptors(nested)\n if (nestedDevices.length > 0) {\n return nestedDevices\n }\n }\n }\n\n return []\n}\n\nfunction readAssociatedDeviceValue(payload: unknown): string | null {\n const record = asRecord(payload)\n if (!record) {\n return null\n }\n\n const direct = readStringValue(record, [\n 'associatedDevice',\n 'AssociatedDevice',\n 'associatedDeviceGuid',\n 'AssociatedDeviceGuid',\n 'deviceGuid',\n 'DeviceGuid',\n 'deviceId',\n 'DeviceId',\n 'peripheralGuid',\n 'PeripheralGuid',\n ])\n if (direct) {\n return direct\n }\n\n for (const key of ['data', 'Data', 'payload', 'Payload']) {\n const nested = asRecord(record[key])\n if (!nested) {\n continue\n }\n\n const nestedDevice = readAssociatedDeviceValue(nested)\n if (nestedDevice) {\n return nestedDevice\n }\n }\n\n return null\n}\n\nfunction normalizeDevicePayload(\n record: Record<string, unknown>,\n associatedDevice?: string,\n): DeviceNormalizedPayload {\n return {\n associatedDevice: associatedDevice ?? readAssociatedDeviceValue(record) ?? undefined,\n status: readStringValueDeep(record, ['status', 'Status', 'state', 'State']) ?? undefined,\n orderGuid: readStringValueDeep(record, ['orderGuid', 'OrderGuid', 'orderGUID', 'orderId', 'OrderId']) ?? undefined,\n orderNumber: readStringValueDeep(record, ['orderNumber', 'OrderNumber', 'reference', 'Reference']) ?? undefined,\n mrgGuid: readStringValueDeep(record, ['mrgGuid', 'MrgGuid', 'mrgId', 'MrgId']) ?? undefined,\n amount: readNumberValueDeep(record, ['amount', 'Amount', 'totalAmount', 'TotalAmount']) ?? undefined,\n currency: readStringValueDeep(record, ['currency', 'Currency', 'currencyCode', 'CurrencyCode']) ?? undefined,\n reasonCode: readStringValueDeep(record, ['reasonCode', 'ReasonCode', 'code', 'Code']) ?? undefined,\n reasonMessage: readStringValueDeep(record, ['reasonMessage', 'ReasonMessage', 'message', 'Message']) ?? undefined,\n transactionId: readStringValueDeep(record, ['transactionId', 'TransactionId', 'transactionNumber', 'TransactionNumber']) ?? undefined,\n barcode: readStringValueDeep(record, ['barcode', 'Barcode', 'value', 'Value', 'scanValue', 'ScanValue']) ?? undefined,\n symbology: readStringValueDeep(record, ['symbology', 'Symbology', 'barcodeType', 'BarcodeType']) ?? undefined,\n raw: record,\n }\n}\n\nfunction readStringValueDeep(source: Record<string, unknown>, keys: string[]): string | null {\n const direct = readStringValue(source, keys)\n if (direct) {\n return direct\n }\n\n for (const key of ['data', 'Data', 'payload', 'Payload', 'result', 'Result']) {\n const nested = asRecord(source[key])\n if (!nested) {\n continue\n }\n\n const nestedValue = readStringValueDeep(nested, keys)\n if (nestedValue) {\n return nestedValue\n }\n }\n\n return null\n}\n\nfunction readNumberValueDeep(source: Record<string, unknown>, keys: string[]): number | null {\n const direct = readNumberValue(source, keys)\n if (direct !== null) {\n return direct\n }\n\n for (const key of ['data', 'Data', 'payload', 'Payload', 'result', 'Result']) {\n const nested = asRecord(source[key])\n if (!nested) {\n continue\n }\n\n const nestedValue = readNumberValueDeep(nested, keys)\n if (nestedValue !== null) {\n return nestedValue\n }\n }\n\n return null\n}\n\nfunction readNumberValue(source: Record<string, unknown>, keys: string[]): number | null {\n for (const key of keys) {\n const value = source[key]\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value\n }\n\n if (typeof value === 'string') {\n const parsed = Number(value.trim())\n if (Number.isFinite(parsed)) {\n return parsed\n }\n }\n }\n\n return null\n}\n\nfunction readOrderGuid(payload: unknown): string {\n const record = asRecord(payload)\n if (!record) {\n return ''\n }\n\n return normalizeDevicePayload(record).orderGuid ?? ''\n}\n\nclass DeviceTpeMock extends PeripheralTpe {\n private cancelled = false\n\n constructor(private readonly emitNotification: (notification: DeviceNotification) => void) {\n super()\n }\n\n makePayment(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.cancelled = false\n\n this.schedule(200, () => this.createNotification('TPE:Progress', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'START',\n reasonMessage: 'Veuillez suivre les instructions sur le terminal de paiement',\n }))\n\n this.schedule(2500, () => this.createNotification('TPE:Progress', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'PINCODE',\n reasonMessage: 'Saisie du pin-code en attente',\n }))\n\n if (orderNumber.startsWith('F')) {\n this.schedule(7500, () => this.createNotification('TPE:Payment-Failure', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'FAKE',\n reasonMessage: \"Votre paiement n'a pas pu être traité\",\n }))\n return\n }\n\n this.schedule(7500, () => this.createNotification('TPE:Payment-Success', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n transactionId: 'FakeTransactionNumber',\n reasonCode: 'FAKE',\n reasonMessage: 'Paiement terminé',\n }))\n }\n\n makeRefund(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.cancelled = false\n this.schedule(2500, () => this.createNotification('TPE:Refund-Failure', {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n reasonCode: 'FAKE',\n reasonMessage: \"Votre paiement n'a pas pu être remboursé : nous sommes en mode mock\",\n }))\n }\n\n cancelPendingPayment(): void {\n this.cancelled = true\n\n this.schedule(2500, () => this.createNotification('TPE:Payment-Failure', {\n reasonCode: 'CANCEL',\n reasonMessage: 'Paiement annulé',\n }))\n }\n\n private schedule(delay: number, factory: () => DeviceNotification): void {\n setTimeout(() => {\n if (!this.cancelled) {\n this.emitNotification(factory())\n }\n }, delay)\n }\n\n private createNotification(kind: string, payload: Record<string, unknown>): DeviceNotification {\n const notification = new DeviceNotification()\n notification.kind = kind\n notification.associatedDevice = this.guid\n notification.jsonData = JSON.stringify(payload)\n return notification\n }\n}\n\nclass DeviceTpeShell extends PeripheralTpe {\n constructor(\n private readonly emitNotification: (notification: DeviceNotification) => void,\n private readonly postMessage: (message: unknown) => void,\n ) {\n super()\n }\n\n setState(state: string): void {\n const notification = new DeviceNotification()\n notification.kind = 'STATUS_UPDATE'\n notification.associatedDevice = this.guid\n notification.jsonData = JSON.stringify({ status: state })\n this.emitNotification(notification)\n }\n\n makePayment(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.postMessage({\n deviceKind: 'TPE',\n deviceGuid: this.guid,\n kind: 'payment-request',\n data: {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n },\n })\n }\n\n makeRefund(orderGuid: string, orderNumber: string, mrgGuid: string, amount: number, currency: string): void {\n this.postMessage({\n deviceKind: 'TPE',\n deviceGuid: this.guid,\n kind: 'refund-request',\n data: {\n orderGuid,\n orderNumber,\n mrgGuid,\n amount,\n currency,\n },\n })\n }\n\n cancelPendingPayment(): void {\n this.postMessage({\n deviceKind: 'TPE',\n deviceGuid: this.guid,\n kind: 'payment-request-cancel',\n data: {},\n })\n }\n}\n\nclass DeviceBarCodeShell extends PeripheralBarCode {}","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 { DeviceManager } from '../kiosk/DeviceManager.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 readonly devices: DeviceManager\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 this.devices = new DeviceManager()\n\n // Modules API\n this.session = new SessionModule(this.http, this.cacheStrategy)\n this.cart = new CartModule(this.http, this.cacheStrategy, this.connectivity, this.workerBridge)\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 this.devices.dispose()\n }\n}\n"],"names":["data","_a","delay"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -913,11 +913,13 @@ declare class StoresModule {
|
|
|
913
913
|
private readonly cache;
|
|
914
914
|
constructor(http: CommerceHttpAdapter, cache: CacheStrategy);
|
|
915
915
|
/** Recherche des magasins par coordonnées géographiques */
|
|
916
|
-
findByLocation(latitude: number, longitude: number,
|
|
916
|
+
findByLocation(latitude: number, longitude: number, countryCode?: string, count?: number, feature?: string): Promise<StoreWithOpeningHours[]>;
|
|
917
917
|
/** Recherche des magasins par code postal */
|
|
918
|
-
findByPostalCode(postalCode: string, countryCode?: string): Promise<StoreWithOpeningHours[]>;
|
|
918
|
+
findByPostalCode(postalCode: string, countryCode?: string, count?: number, feature?: string): Promise<StoreWithOpeningHours[]>;
|
|
919
919
|
/** Récupère le détail d'un magasin par son GUID */
|
|
920
920
|
getStore(storeGuid: string): Promise<StoreWithOpeningHours>;
|
|
921
|
+
/** Récupère le magasin associé à la session en cours (null si aucun) */
|
|
922
|
+
getSessionStore(): Promise<StoreWithOpeningHours | null>;
|
|
921
923
|
}
|
|
922
924
|
|
|
923
925
|
export declare interface StoreWithOpeningHours {
|