@altazion/commerce-sdk-htmx 26.618.8367 → 26.619.8377
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 +177 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.iife.js +177 -2
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +177 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/extensions/altazion-engine.ts","../src/extensions/modules/cart.ts","../src/extensions/modules/session.ts","../src/extensions/modules/marketing.ts","../src/extensions/modules/stores.ts","../src/extensions/altazion-auth.ts","../src/helpers/price.ts","../src/helpers/product.ts","../src/helpers/cart.ts","../src/rendering/declarative-renderer.ts","../src/templates/product-card.hbs?raw","../src/templates/cart-mini.hbs?raw","../src/templates/product-list.hbs?raw","../src/index.ts"],"sourcesContent":["import {\n AltazionApiError,\n OfflineError,\n type CommerceClient,\n type ProblemDetails,\n} from '@altazion/commerce-sdk-core'\n\ndeclare global {\n interface Window {\n htmx?: {\n on(eventName: string, listener: (event: Event) => void): void\n off(eventName: string, listener: (event: Event) => void): void\n ajax(\n method: string,\n path: string,\n context?: {\n source?: Element\n target?: Element | string\n swap?: string\n select?: string\n values?: Record<string, unknown>\n }\n ): Promise<unknown> | void\n }\n }\n}\n\nexport interface AltazionExtensionHandle {\n dispose(): void\n}\n\nexport interface AltazionActionEventDetail<\n TModule extends string = string,\n TAction extends string = string,\n TResult = unknown,\n> {\n module: TModule\n action: TAction\n element: Element\n payload: Record<string, unknown>\n result?: TResult\n error?: unknown\n errorDetail?: AltazionActionErrorDetail\n}\n\nexport interface AltazionActionErrorDetail {\n name: string\n message: string\n status?: number\n problem?: ProblemDetails\n isOffline: boolean\n isConflict: boolean\n}\n\nexport type AltazionSuccessEventKind = 'loaded' | 'updated' | 'changed' | 'none'\n\nexport interface AltazionModuleDefinition<\n TModule extends string = string,\n TAction extends string = string,\n TResult = unknown,\n> {\n moduleName: TModule\n actionAttribute: string\n payloadAttributes?: Record<string, string>\n jsonPayloadAttributes?: Record<string, string>\n payloadAliases?: Record<string, string>\n normalizePayload?(payload: Record<string, unknown>): void\n parseAction(actionValue: string): TAction\n execute(client: CommerceClient, action: TAction, payload: Record<string, unknown>): Promise<TResult>\n successEventKind?: AltazionSuccessEventKind | ((action: TAction, result: TResult, payload: Record<string, unknown>) => AltazionSuccessEventKind)\n getResultEventSuffixes?(action: TAction, result: TResult, payload: Record<string, unknown>): string[]\n}\n\ninterface HtmxConfigRequestEvent extends Event {\n detail: {\n headers: Record<string, string>\n elt: Element\n }\n}\n\ninterface MatchedAction<TModule extends string = string, TAction extends string = string, TResult = unknown> {\n definition: AltazionModuleDefinition<TModule, TAction, TResult>\n element: Element\n}\n\ninterface DisableableElement extends HTMLElement {\n disabled: boolean\n}\n\nconst EXTENSION_NAME = 'altazion'\nconst JSON_VALUES_ATTRIBUTE = 'hx-vals'\nconst REFRESH_ATTRIBUTE = 'hx-altazion-refresh'\nconst REFRESH_EVENT_NAME = 'altazion:refresh'\n\nconst REQUEST_ATTRIBUTES = [\n { attribute: 'hx-get', method: 'GET' },\n { attribute: 'hx-post', method: 'POST' },\n { attribute: 'hx-put', method: 'PUT' },\n { attribute: 'hx-patch', method: 'PATCH' },\n { attribute: 'hx-delete', method: 'DELETE' },\n] as const\n\nexport function createAltazionExtension(\n client: CommerceClient,\n modules: readonly AltazionModuleDefinition<any, any, any>[]\n): AltazionExtensionHandle {\n const requestHandler = (event: Event): void => {\n const e = event as HtmxConfigRequestEvent\n e.detail.headers['Accept-Language'] = client.context.locale\n e.detail.headers['X-Altazion-Currency'] = client.context.currency\n }\n\n if (typeof window !== 'undefined' && window.htmx) {\n window.htmx.on('htmx:configRequest', requestHandler)\n }\n\n if (typeof document === 'undefined') {\n return {\n dispose(): void {\n if (typeof window !== 'undefined' && window.htmx) {\n window.htmx.off('htmx:configRequest', requestHandler)\n }\n },\n }\n }\n\n const handleClick = (event: Event): void => {\n const mouseEvent = event as MouseEvent\n if (\n mouseEvent.defaultPrevented\n || mouseEvent.button !== 0\n || mouseEvent.metaKey\n || mouseEvent.ctrlKey\n || mouseEvent.shiftKey\n || mouseEvent.altKey\n ) {\n return\n }\n\n const target = event.target\n if (!(target instanceof Element)) {\n return\n }\n\n const matchedAction = findMatchedAction(target, modules)\n if (!matchedAction || matchedAction.element instanceof HTMLFormElement || !hasAltazionExtension(matchedAction.element)) {\n return\n }\n\n event.preventDefault()\n void runModuleAction(client, matchedAction)\n }\n\n const handleSubmit = (event: Event): void => {\n const target = event.target\n if (!(target instanceof HTMLFormElement)) {\n return\n }\n\n const matchedAction = findMatchedAction(target, modules)\n if (!matchedAction || matchedAction.element !== target || !hasAltazionExtension(target)) {\n return\n }\n\n event.preventDefault()\n void runModuleAction(client, matchedAction)\n }\n\n document.addEventListener('click', handleClick)\n document.addEventListener('submit', handleSubmit)\n\n return {\n dispose(): void {\n if (typeof window !== 'undefined' && window.htmx) {\n window.htmx.off('htmx:configRequest', requestHandler)\n }\n\n document.removeEventListener('click', handleClick)\n document.removeEventListener('submit', handleSubmit)\n },\n }\n}\n\nexport function requireString(value: unknown, fieldName: string): string {\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n\n throw new Error(`Missing payload field: ${fieldName}`)\n}\n\nexport function requireNumber(value: unknown, fieldName: string): number {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value\n }\n\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) {\n return parsed\n }\n }\n\n throw new Error(`Invalid payload field: ${fieldName}`)\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined\n }\n\n return value as Record<string, unknown>\n}\n\nasync function runModuleAction<TModule extends string, TAction extends string, TResult>(\n client: CommerceClient,\n matchedAction: MatchedAction<TModule, TAction, TResult>\n): Promise<void> {\n const { definition, element } = matchedAction\n const action = readActionName(element, definition)\n const payload = collectPayload(element, definition)\n const releasePending = markPending(element)\n\n dispatchModuleEvent<TModule, TAction, undefined>(element, buildModuleEventName(definition.moduleName, 'before'), {\n module: definition.moduleName,\n action,\n element,\n payload,\n })\n\n try {\n const result = await definition.execute(client, action, payload)\n\n dispatchModuleEvent<TModule, TAction, TResult>(element, buildModuleEventName(definition.moduleName, 'after'), {\n module: definition.moduleName,\n action,\n element,\n payload,\n result,\n })\n\n const successEventKind = resolveSuccessEventKind(definition, action, result, payload)\n const emittedSuffixes = new Set<string>()\n\n if (successEventKind !== 'none') {\n emittedSuffixes.add(successEventKind)\n dispatchModuleEvent<TModule, TAction, TResult>(element, buildModuleEventName(definition.moduleName, successEventKind), {\n module: definition.moduleName,\n action,\n element,\n payload,\n result,\n })\n }\n\n for (const suffix of definition.getResultEventSuffixes?.(action, result, payload) ?? []) {\n if (emittedSuffixes.has(suffix)) {\n continue\n }\n\n dispatchModuleEvent<TModule, TAction, TResult>(element, buildModuleEventName(definition.moduleName, suffix), {\n module: definition.moduleName,\n action,\n element,\n payload,\n result,\n })\n }\n\n await refreshTargets(element)\n } catch (error) {\n const errorDetail = normalizeError(error)\n\n dispatchModuleEvent<TModule, TAction, undefined>(element, buildModuleEventName(definition.moduleName, 'error'), {\n module: definition.moduleName,\n action,\n element,\n payload,\n error,\n errorDetail,\n })\n console.error(`[AltazionHtmx] ${definition.moduleName} action failed`, error)\n } finally {\n releasePending()\n }\n}\n\nfunction findMatchedAction(\n target: Element,\n modules: readonly AltazionModuleDefinition<any, any, any>[]\n): MatchedAction | null {\n let current: Element | null = target\n\n while (current) {\n for (const definition of modules) {\n if (current.hasAttribute(definition.actionAttribute)) {\n return { definition, element: current }\n }\n }\n\n current = current.parentElement\n }\n\n return null\n}\n\nfunction readActionName<TModule extends string, TAction extends string, TResult>(\n element: Element,\n definition: AltazionModuleDefinition<TModule, TAction, TResult>\n): TAction {\n const action = element.getAttribute(definition.actionAttribute)\n if (!action) {\n throw new Error(`Missing ${definition.actionAttribute} attribute`)\n }\n\n return definition.parseAction(action)\n}\n\nfunction collectPayload<TModule extends string, TAction extends string, TResult>(\n element: Element,\n definition: AltazionModuleDefinition<TModule, TAction, TResult>\n): Record<string, unknown> {\n const payload: Record<string, unknown> = {}\n const form = element instanceof HTMLFormElement ? element : element.closest('form')\n\n if (form) {\n Object.assign(payload, formDataToObject(new FormData(form)))\n mergeJsonValues(payload, form)\n applyAttributePayload(payload, form, definition.payloadAttributes)\n applyJsonAttributePayload(payload, form, definition.jsonPayloadAttributes)\n }\n\n mergeJsonValues(payload, element)\n applyAttributePayload(payload, element, definition.payloadAttributes)\n applyJsonAttributePayload(payload, element, definition.jsonPayloadAttributes)\n applyPayloadAliases(payload, definition.payloadAliases)\n definition.normalizePayload?.(payload)\n\n return payload\n}\n\nfunction mergeJsonValues(payload: Record<string, unknown>, element: Element): void {\n const values = readJsonValues(element, JSON_VALUES_ATTRIBUTE)\n if (values) {\n Object.assign(payload, values)\n }\n}\n\nfunction applyAttributePayload(\n payload: Record<string, unknown>,\n element: Element,\n attributes?: Record<string, string>\n): void {\n if (!attributes) {\n return\n }\n\n for (const [attributeName, payloadKey] of Object.entries(attributes)) {\n const value = element.getAttribute(attributeName)\n if (value !== null) {\n payload[payloadKey] = value\n }\n }\n}\n\nfunction applyJsonAttributePayload(\n payload: Record<string, unknown>,\n element: Element,\n attributes?: Record<string, string>\n): void {\n if (!attributes) {\n return\n }\n\n for (const [attributeName, payloadKey] of Object.entries(attributes)) {\n const value = readJsonValues(element, attributeName)\n if (value !== undefined) {\n payload[payloadKey] = value\n }\n }\n}\n\nfunction applyPayloadAliases(payload: Record<string, unknown>, aliases?: Record<string, string>): void {\n if (!aliases) {\n return\n }\n\n for (const [alias, canonicalKey] of Object.entries(aliases)) {\n if (payload[alias] !== undefined && payload[canonicalKey] === undefined) {\n payload[canonicalKey] = payload[alias]\n }\n }\n}\n\nfunction formDataToObject(formData: FormData): Record<string, unknown> {\n const payload: Record<string, unknown> = {}\n\n for (const [key, value] of formData.entries()) {\n const normalizedValue = typeof value === 'string' ? value : value.name\n const previous = payload[key]\n\n if (previous === undefined) {\n payload[key] = normalizedValue\n } else if (Array.isArray(previous)) {\n previous.push(normalizedValue)\n } else {\n payload[key] = [previous, normalizedValue]\n }\n }\n\n return payload\n}\n\nfunction dispatchModuleEvent<TModule extends string, TAction extends string, TResult>(\n element: Element,\n eventName: string,\n detail: AltazionActionEventDetail<TModule, TAction, TResult>\n): void {\n element.dispatchEvent(new CustomEvent<AltazionActionEventDetail<TModule, TAction, TResult>>(eventName, {\n bubbles: true,\n detail,\n }))\n}\n\nfunction buildModuleEventName(moduleName: string, suffix: string): string {\n return `altazion:${moduleName}:${suffix}`\n}\n\nfunction resolveSuccessEventKind<TModule extends string, TAction extends string, TResult>(\n definition: AltazionModuleDefinition<TModule, TAction, TResult>,\n action: TAction,\n result: TResult,\n payload: Record<string, unknown>\n): AltazionSuccessEventKind {\n const configuredKind = definition.successEventKind\n if (typeof configuredKind === 'function') {\n return configuredKind(action, result, payload)\n }\n\n if (configuredKind) {\n return configuredKind\n }\n\n return inferSuccessEventKind(action, result)\n}\n\nfunction inferSuccessEventKind<TAction extends string, TResult>(action: TAction, result: TResult): AltazionSuccessEventKind {\n if (result === undefined) {\n return 'changed'\n }\n\n const normalizedAction = action.toLowerCase()\n if (\n normalizedAction.startsWith('get')\n || normalizedAction.startsWith('find')\n || normalizedAction.startsWith('search')\n || normalizedAction.startsWith('suggest')\n || normalizedAction.startsWith('load')\n || normalizedAction.startsWith('list')\n ) {\n return 'loaded'\n }\n\n return 'updated'\n}\n\nfunction normalizeError(error: unknown): AltazionActionErrorDetail {\n if (error instanceof AltazionApiError) {\n return {\n name: error.name,\n message: error.message,\n status: error.status,\n problem: error.problem,\n isOffline: false,\n isConflict: error.status === 409,\n }\n }\n\n if (error instanceof OfflineError) {\n return {\n name: error.name,\n message: error.message,\n isOffline: true,\n isConflict: false,\n }\n }\n\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n isOffline: false,\n isConflict: false,\n }\n }\n\n return {\n name: 'UnknownError',\n message: 'Unknown error',\n isOffline: false,\n isConflict: false,\n }\n}\n\nasync function refreshTargets(element: Element): Promise<void> {\n const targets = resolveRefreshTargets(element)\n if (targets.length === 0) {\n return\n }\n\n await Promise.all(targets.map((target) => refreshTargetElement(element, target)))\n}\n\nfunction resolveRefreshTargets(element: Element): Element[] {\n if (typeof document === 'undefined') {\n return []\n }\n\n const selectors = collectRefreshSelectors(element)\n if (selectors.length === 0) {\n return []\n }\n\n const targets = new Set<Element>()\n\n for (const selector of selectors) {\n try {\n for (const target of document.querySelectorAll(selector)) {\n targets.add(target)\n }\n } catch (error) {\n console.error(`[AltazionHtmx] invalid refresh selector: ${selector}`, error)\n }\n }\n\n return [...targets]\n}\n\nfunction collectRefreshSelectors(element: Element): string[] {\n const values = new Set<string>()\n const form = element instanceof HTMLFormElement ? element : element.closest('form')\n\n addRefreshSelectors(values, form)\n addRefreshSelectors(values, element)\n\n return [...values]\n}\n\nfunction addRefreshSelectors(values: Set<string>, element: Element | null): void {\n const rawValue = element?.getAttribute(REFRESH_ATTRIBUTE)\n if (!rawValue) {\n return\n }\n\n for (const selector of rawValue.split(';')) {\n const trimmed = selector.trim()\n if (trimmed.length > 0) {\n values.add(trimmed)\n }\n }\n}\n\nasync function refreshTargetElement(sourceElement: Element, targetElement: Element): Promise<void> {\n const request = readRefreshRequest(targetElement)\n if (request && typeof window !== 'undefined' && window.htmx?.ajax) {\n const context: {\n source: Element\n target: Element\n swap?: string\n select?: string\n values?: Record<string, unknown>\n } = {\n source: sourceElement,\n target: targetElement,\n }\n\n const swap = targetElement.getAttribute('hx-swap')\n if (swap) {\n context.swap = swap\n }\n\n const select = targetElement.getAttribute('hx-select')\n if (select) {\n context.select = select\n }\n\n const values = readJsonValues(targetElement, JSON_VALUES_ATTRIBUTE)\n if (values) {\n context.values = values\n }\n\n await Promise.resolve(window.htmx.ajax(request.method, request.path, context))\n return\n }\n\n targetElement.dispatchEvent(new CustomEvent(REFRESH_EVENT_NAME, {\n bubbles: true,\n detail: {\n source: sourceElement,\n target: targetElement,\n },\n }))\n}\n\nfunction readRefreshRequest(element: Element): { method: string, path: string } | null {\n for (const requestAttribute of REQUEST_ATTRIBUTES) {\n const path = element.getAttribute(requestAttribute.attribute)\n if (path) {\n return {\n method: requestAttribute.method,\n path,\n }\n }\n }\n\n return null\n}\n\nfunction readJsonValues(element: Element, attributeName: string): Record<string, unknown> | undefined {\n const raw = element.getAttribute(attributeName)\n if (!raw) {\n return undefined\n }\n\n try {\n const parsed = JSON.parse(raw) as unknown\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>\n }\n } catch {\n throw new Error(`Invalid JSON in ${attributeName}`)\n }\n\n return undefined\n}\n\nfunction markPending(element: Element): () => void {\n const previousBusy = element.getAttribute('aria-busy')\n element.setAttribute('aria-busy', 'true')\n\n const disableable = isDisableableElement(element) ? element : null\n const previousDisabled = disableable?.disabled ?? false\n if (disableable) {\n disableable.disabled = true\n }\n\n return (): void => {\n if (previousBusy === null) {\n element.removeAttribute('aria-busy')\n } else {\n element.setAttribute('aria-busy', previousBusy)\n }\n\n if (disableable) {\n disableable.disabled = previousDisabled\n }\n }\n}\n\nfunction isDisableableElement(element: Element): element is DisableableElement {\n return 'disabled' in element\n}\n\nfunction hasAltazionExtension(element: Element): boolean {\n let current: Element | null = element\n while (current) {\n const extensions = current.getAttribute('hx-ext')\n if (extensions && parseExtensions(extensions).includes(EXTENSION_NAME)) {\n return true\n }\n\n current = current.parentElement\n }\n\n return false\n}\n\nfunction parseExtensions(value: string): string[] {\n return value\n .split(/[\\s,]+/)\n .map((extension) => extension.trim())\n .filter((extension) => extension.length > 0)\n}","import type { Cart, CartValidationStatus, CommerceClient } from '@altazion/commerce-sdk-core'\n\nimport {\n asRecord,\n requireNumber,\n requireString,\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionCartActionName =\n | 'getCart'\n | 'getValidationStatus'\n | 'addItem'\n | 'updateItem'\n | 'removeItem'\n | 'applyCoupon'\n | 'removeCoupon'\n\nexport type CartActionResult = Cart | CartValidationStatus\n\nexport const cartModuleDefinition: AltazionModuleDefinition<'cart', AltazionCartActionName, CartActionResult> = {\n moduleName: 'cart',\n actionAttribute: 'hx-altazion-cart-action',\n payloadAttributes: {\n 'hx-altazion-cart-reference': 'reference',\n 'hx-altazion-cart-quantity': 'quantity',\n 'hx-altazion-cart-line-id': 'lineId',\n 'hx-altazion-cart-code': 'code',\n },\n jsonPayloadAttributes: {\n 'hx-altazion-cart-options': 'options',\n },\n payloadAliases: {\n ref: 'reference',\n productReference: 'reference',\n qty: 'quantity',\n line: 'lineId',\n coupon: 'code',\n },\n parseAction(actionValue: string): AltazionCartActionName {\n switch (actionValue) {\n case 'getCart':\n case 'getValidationStatus':\n case 'addItem':\n case 'updateItem':\n case 'removeItem':\n case 'applyCoupon':\n case 'removeCoupon':\n return actionValue\n default:\n throw new Error(`Unsupported cart action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionCartActionName, payload: Record<string, unknown>): Promise<CartActionResult> {\n switch (action) {\n case 'getCart':\n return client.cart.getCart()\n case 'getValidationStatus':\n return client.cart.getValidationStatus()\n case 'addItem': {\n const reference = requireString(payload.reference, 'reference')\n const quantity = requireNumber(payload.quantity, 'quantity')\n const options = buildAddItemOptions(payload)\n return client.cart.addItem(reference, quantity, options)\n }\n case 'updateItem': {\n const lineId = requireString(payload.lineId, 'lineId')\n const quantity = requireNumber(payload.quantity, 'quantity')\n return client.cart.updateItem(lineId, quantity)\n }\n case 'removeItem':\n return client.cart.removeItem(requireString(payload.lineId, 'lineId'))\n case 'applyCoupon':\n return client.cart.applyCoupon(requireString(payload.code, 'code'))\n case 'removeCoupon':\n return client.cart.removeCoupon(requireString(payload.code, 'code'))\n }\n },\n successEventKind(action: AltazionCartActionName): AltazionSuccessEventKind {\n switch (action) {\n case 'getCart':\n return 'loaded'\n case 'getValidationStatus':\n return 'none'\n case 'addItem':\n case 'updateItem':\n case 'removeItem':\n case 'applyCoupon':\n case 'removeCoupon':\n return 'updated'\n }\n },\n getResultEventSuffixes(_action: AltazionCartActionName, result: CartActionResult): string[] {\n return isCart(result) ? ['updated'] : ['status']\n },\n}\n\nfunction buildAddItemOptions(payload: Record<string, unknown>): Record<string, unknown> | undefined {\n const options = asRecord(payload.options)\n const extraEntries = Object.entries(payload).filter(([key]) => ![\n 'reference',\n 'ref',\n 'productReference',\n 'quantity',\n 'qty',\n 'options',\n ].includes(key))\n\n if (extraEntries.length === 0 && !options) {\n return undefined\n }\n\n return {\n ...Object.fromEntries(extraEntries),\n ...options,\n }\n}\n\nfunction isCart(result: CartActionResult): result is Cart {\n return 'guid' in result\n}","import type { CommerceClient, SessionInfo } from '@altazion/commerce-sdk-core'\n\nimport {\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionSessionActionName = 'getSession'\n\nexport const sessionModuleDefinition: AltazionModuleDefinition<'session', AltazionSessionActionName, SessionInfo> = {\n moduleName: 'session',\n actionAttribute: 'hx-altazion-session-action',\n parseAction(actionValue: string): AltazionSessionActionName {\n switch (actionValue) {\n case 'getSession':\n return actionValue\n default:\n throw new Error(`Unsupported session action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionSessionActionName): Promise<SessionInfo> {\n switch (action) {\n case 'getSession':\n return client.session.getSession()\n }\n },\n successEventKind(): AltazionSuccessEventKind {\n return 'loaded'\n },\n}","import type { CommerceClient, MarketingItem } from '@altazion/commerce-sdk-core'\n\nimport {\n requireString,\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionMarketingActionName = 'getItem' | 'getItems'\n\nexport type MarketingActionResult = MarketingItem | MarketingItem[]\n\nexport const marketingModuleDefinition: AltazionModuleDefinition<'marketing', AltazionMarketingActionName, MarketingActionResult> = {\n moduleName: 'marketing',\n actionAttribute: 'hx-altazion-marketing-action',\n payloadAttributes: {\n 'hx-altazion-marketing-code': 'code',\n },\n jsonPayloadAttributes: {\n 'hx-altazion-marketing-codes': 'codes',\n },\n parseAction(actionValue: string): AltazionMarketingActionName {\n switch (actionValue) {\n case 'getItem':\n case 'getItems':\n return actionValue\n default:\n throw new Error(`Unsupported marketing action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionMarketingActionName, payload: Record<string, unknown>): Promise<MarketingActionResult> {\n switch (action) {\n case 'getItem':\n return client.marketing.getItem(requireString(payload.code, 'code'))\n case 'getItems':\n return client.marketing.getItems(readCodes(payload))\n }\n },\n successEventKind(): AltazionSuccessEventKind {\n return 'loaded'\n },\n getResultEventSuffixes(action: AltazionMarketingActionName): string[] {\n switch (action) {\n case 'getItem':\n return ['item-loaded']\n case 'getItems':\n return ['items-loaded']\n }\n },\n}\n\nfunction readCodes(payload: Record<string, unknown>): string[] {\n const value = payload.codes\n\n if (Array.isArray(value)) {\n const codes = value\n .filter((entry): entry is string => typeof entry === 'string')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n\n if (codes.length > 0) {\n return codes\n }\n }\n\n if (typeof value === 'string') {\n const codes = value\n .split(',')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n\n if (codes.length > 0) {\n return codes\n }\n }\n\n if (typeof payload.code === 'string' && payload.code.trim().length > 0) {\n return [payload.code.trim()]\n }\n\n throw new Error('Missing payload field: codes')\n}","import type { CommerceClient, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\n\nimport {\n requireNumber,\n requireString,\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionStoresActionName = 'findByLocation' | 'findByPostalCode' | 'getStore'\n\nexport type StoresActionResult = StoreWithOpeningHours | StoreWithOpeningHours[]\n\nexport const storesModuleDefinition: AltazionModuleDefinition<'stores', AltazionStoresActionName, StoresActionResult> = {\n moduleName: 'stores',\n actionAttribute: 'hx-altazion-stores-action',\n payloadAttributes: {\n 'hx-altazion-stores-store-guid': 'storeGuid',\n 'hx-altazion-stores-latitude': 'latitude',\n 'hx-altazion-stores-longitude': 'longitude',\n 'hx-altazion-stores-radius-km': 'radiusKm',\n 'hx-altazion-stores-postal-code': 'postalCode',\n 'hx-altazion-stores-country-code': 'countryCode',\n },\n payloadAliases: {\n lat: 'latitude',\n lon: 'longitude',\n lng: 'longitude',\n radius: 'radiusKm',\n storeId: 'storeGuid',\n id: 'storeGuid',\n postal: 'postalCode',\n country: 'countryCode',\n },\n parseAction(actionValue: string): AltazionStoresActionName {\n switch (actionValue) {\n case 'findByLocation':\n case 'findByPostalCode':\n case 'getStore':\n return actionValue\n default:\n throw new Error(`Unsupported stores action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionStoresActionName, payload: Record<string, unknown>): Promise<StoresActionResult> {\n switch (action) {\n case 'findByLocation': {\n const latitude = requireNumber(payload.latitude, 'latitude')\n const longitude = requireNumber(payload.longitude, 'longitude')\n const radiusKm = payload.radiusKm === undefined ? 50 : requireNumber(payload.radiusKm, 'radiusKm')\n return client.stores.findByLocation(latitude, longitude, radiusKm)\n }\n case 'findByPostalCode': {\n const postalCode = requireString(payload.postalCode, 'postalCode')\n const countryCode = payload.countryCode === undefined\n ? 'FR'\n : requireString(payload.countryCode, 'countryCode')\n return client.stores.findByPostalCode(postalCode, countryCode)\n }\n case 'getStore':\n return client.stores.getStore(requireString(payload.storeGuid, 'storeGuid'))\n }\n },\n successEventKind(): AltazionSuccessEventKind {\n return 'loaded'\n },\n getResultEventSuffixes(action: AltazionStoresActionName): string[] {\n switch (action) {\n case 'getStore':\n return ['store-loaded']\n case 'findByLocation':\n case 'findByPostalCode':\n return ['stores-loaded']\n }\n },\n}","import type { CommerceClient } from '@altazion/commerce-sdk-core'\n\nimport {\n createAltazionExtension,\n type AltazionActionEventDetail,\n type AltazionActionErrorDetail,\n type AltazionExtensionHandle,\n type AltazionSuccessEventKind,\n} from './altazion-engine'\nimport {\n cartModuleDefinition,\n type AltazionCartActionName,\n} from './modules/cart'\nimport {\n sessionModuleDefinition,\n type AltazionSessionActionName,\n} from './modules/session'\nimport {\n marketingModuleDefinition,\n type AltazionMarketingActionName,\n} from './modules/marketing'\nimport {\n storesModuleDefinition,\n type AltazionStoresActionName,\n} from './modules/stores'\n\nexport type { AltazionCartActionName }\nexport type { AltazionMarketingActionName }\nexport type { AltazionSessionActionName }\nexport type { AltazionStoresActionName }\nexport type {\n AltazionActionEventDetail,\n AltazionActionErrorDetail,\n AltazionExtensionHandle,\n AltazionSuccessEventKind,\n}\n\nexport type AltazionCartEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'cart',\n AltazionCartActionName,\n TResult\n>\n\nexport type AltazionSessionEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'session',\n AltazionSessionActionName,\n TResult\n>\n\nexport type AltazionMarketingEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'marketing',\n AltazionMarketingActionName,\n TResult\n>\n\nexport type AltazionStoresEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'stores',\n AltazionStoresActionName,\n TResult\n>\n\n/**\n * Extension HTMX Altazion.\n *\n * - Ajoute les headers de contexte Altazion sur les requêtes HTMX\n * - Interprète les attributs `hx-altazion-cart-action`, `hx-altazion-session-action`,\n * `hx-altazion-marketing-action` et `hx-altazion-stores-action`\n * pour appeler le SDK core\n * - Émet des événements DOM `altazion:cart:*`, `altazion:session:*`,\n * `altazion:marketing:*` et `altazion:stores:*`\n * exploitables par HTMX\n */\nexport function registerAltazionExtension(client: CommerceClient): AltazionExtensionHandle {\n return createAltazionExtension(client, [\n cartModuleDefinition,\n sessionModuleDefinition,\n marketingModuleDefinition,\n storesModuleDefinition,\n ])\n}\n\nexport const registerAltazionAuthExtension = registerAltazionExtension\n","import type Handlebars from 'handlebars'\n\ntype HandlebarsInstance = typeof Handlebars\n\n/**\n * Formate un montant selon la locale et la devise.\n * Usage : {{formatPrice 19.99 \"EUR\" \"fr-FR\"}}\n * Si locale/currency sont omis, utilise les valeurs passées au registre.\n */\nexport function registerPriceHelpers(\n hbs: HandlebarsInstance,\n defaults: { locale: string; currency: string }\n): void {\n hbs.registerHelper(\n 'formatPrice',\n function (\n value: unknown,\n currency?: unknown,\n locale?: unknown\n ): string {\n const amount = typeof value === 'number' ? value : parseFloat(String(value))\n if (isNaN(amount)) return ''\n\n const resolvedCurrency =\n typeof currency === 'string' ? currency : defaults.currency\n const resolvedLocale =\n typeof locale === 'string' ? locale : defaults.locale\n\n return new Intl.NumberFormat(resolvedLocale, {\n style: 'currency',\n currency: resolvedCurrency,\n }).format(amount)\n }\n )\n\n hbs.registerHelper(\n 'formatPriceCompact',\n function (value: unknown, currency?: unknown, locale?: unknown): string {\n const amount = typeof value === 'number' ? value : parseFloat(String(value))\n if (isNaN(amount)) return ''\n\n const resolvedCurrency =\n typeof currency === 'string' ? currency : defaults.currency\n const resolvedLocale =\n typeof locale === 'string' ? locale : defaults.locale\n\n return new Intl.NumberFormat(resolvedLocale, {\n style: 'currency',\n currency: resolvedCurrency,\n notation: 'compact',\n }).format(amount)\n }\n )\n\n hbs.registerHelper(\n 'discountPercent',\n function (original: unknown, discounted: unknown): string {\n const orig = typeof original === 'number' ? original : parseFloat(String(original))\n const disc = typeof discounted === 'number' ? discounted : parseFloat(String(discounted))\n if (isNaN(orig) || isNaN(disc) || orig === 0) return ''\n const pct = Math.round(((orig - disc) / orig) * 100)\n return `-${pct}%`\n }\n )\n}\n","import type Handlebars from 'handlebars'\n\ntype HandlebarsInstance = typeof Handlebars\n\n/**\n * Helpers Handlebars liés aux produits.\n *\n * Usage :\n * {{productUrl reference}}\n * {{thumbnailUrl imageUrl 400}}\n * {{#if (isAvailable availability)}} ... {{/if}}\n */\nexport function registerProductHelpers(hbs: HandlebarsInstance, siteUrl: string): void {\n // URL de la fiche produit côté site vitrine\n hbs.registerHelper('productUrl', function (reference: unknown): string {\n if (typeof reference !== 'string' && typeof reference !== 'number') return ''\n const base = siteUrl.replace(/\\/$/, '')\n return `${base}/product/${encodeURIComponent(String(reference))}`\n })\n\n // Transforme une URL d'image en URL redimensionnée si le serveur le supporte\n // Pattern attendu : /media/images/{id} → /media/images/{id}?w={size}\n hbs.registerHelper('thumbnailUrl', function (imageUrl: unknown, size?: unknown): string {\n if (typeof imageUrl !== 'string' || !imageUrl) return ''\n const resolvedSize = typeof size === 'number' ? size : 300\n const separator = imageUrl.includes('?') ? '&' : '?'\n return `${imageUrl}${separator}w=${resolvedSize}`\n })\n\n // Retourne true si le produit est disponible (availability > 0 ou pas de stock géré)\n hbs.registerHelper('isAvailable', function (availability: unknown): boolean {\n if (availability === null || availability === undefined) return true\n if (typeof availability === 'boolean') return availability\n if (typeof availability === 'number') return availability > 0\n if (typeof availability === 'string') {\n const lower = availability.toLowerCase()\n return lower === 'available' || lower === 'instock'\n }\n return false\n })\n\n // Helper ifCond simple pour les comparaisons dans les templates\n hbs.registerHelper(\n 'ifCond',\n function (\n this: unknown,\n v1: unknown,\n operator: string,\n v2: unknown,\n options: Handlebars.HelperOptions\n ): string {\n let result = false\n switch (operator) {\n case '==': result = v1 == v2; break\n case '===': result = v1 === v2; break\n case '!=': result = v1 != v2; break\n case '!==': result = v1 !== v2; break\n case '>': result = (v1 as number) > (v2 as number); break\n case '<': result = (v1 as number) < (v2 as number); break\n case '>=': result = (v1 as number) >= (v2 as number); break\n case '<=': result = (v1 as number) <= (v2 as number); break\n default: result = false\n }\n return result ? options.fn(this as object) : options.inverse(this as object)\n }\n )\n}\n","import type Handlebars from 'handlebars'\nimport type { Cart, CartContent } from '@altazion/commerce-sdk-core'\n\ntype HandlebarsInstance = typeof Handlebars\n\n/**\n * Helpers Handlebars liés au panier.\n *\n * Nécessite un getter réactif sur le panier actuel.\n * Usage :\n * Nombre d'articles : {{cartCount}}\n * Total : {{cartTotal}}\n * {{#if cartHasItems}} ... {{/if}}\n */\nexport function registerCartHelpers(\n hbs: HandlebarsInstance,\n getCart: () => Cart | null,\n defaults: { locale: string; currency: string }\n): void {\n hbs.registerHelper('cartCount', function (): number {\n const cart = getCart()\n if (!cart) return 0\n return cart.totalQuantity\n })\n\n hbs.registerHelper('cartTotal', function (): string {\n const cart = getCart()\n if (!cart) return ''\n return new Intl.NumberFormat(defaults.locale, {\n style: 'currency',\n currency: defaults.currency,\n }).format(cart.totalAmountWithTax)\n })\n\n hbs.registerHelper('cartTotalRaw', function (): number {\n const cart = getCart()\n return cart?.totalAmountWithTax ?? 0\n })\n\n hbs.registerHelper('cartHasItems', function (this: unknown, options: Handlebars.HelperOptions): string {\n const cart = getCart()\n const hasItems = cart ? cart.totalQuantity > 0 : false\n return hasItems ? options.fn(this as object) : options.inverse(this as object)\n })\n\n hbs.registerHelper('cartLineCount', function (): number {\n const cart = getCart()\n if (!cart?.content) return 0\n return cart.content.reduce((sum: number, group: CartContent) => sum + (group.lines?.length ?? 0), 0)\n })\n}\n","import type { Cart, MarketingItem, SessionInfo, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\nimport type Handlebars from 'handlebars'\n\nexport interface AltazionDeclarativeViewModel {\n cart: Cart | null\n session: SessionInfo | null\n store: StoreWithOpeningHours | null\n stores: StoreWithOpeningHours[]\n marketingItem: MarketingItem | null\n marketingItems: MarketingItem[]\n slots: Record<string, unknown>\n}\n\nexport interface AltazionDeclarativeRendererHandle {\n update<K extends keyof AltazionDeclarativeViewModel>(\n key: K,\n value: AltazionDeclarativeViewModel[K]\n ): void\n updateSlot(name: string, value: unknown): void\n render(): void\n dispose(): void\n}\n\ntype HandlebarsRuntime = typeof Handlebars\ntype ViewModelKey = keyof AltazionDeclarativeViewModel\ntype DataSourceReference =\n | { kind: 'state', key: ViewModelKey }\n | { kind: 'slot', key: string }\n\nconst DATA_SOURCE_ATTRIBUTE = 'hx-altazion-data-source'\nconst DATA_STATUS_ATTRIBUTE = 'hx-altazion-data-status'\nconst RENDER_TEMPLATE_ATTRIBUTE = 'hx-render-template'\n\nconst DATA_SOURCE_ALIASES: Record<string, ViewModelKey> = {\n cart: 'cart',\n session: 'session',\n store: 'store',\n stores: 'stores',\n 'marketing-item': 'marketingItem',\n 'marketing-items': 'marketingItems',\n}\n\nexport function createAltazionDeclarativeRenderer(\n handlebars?: HandlebarsRuntime\n): AltazionDeclarativeRendererHandle {\n const state: AltazionDeclarativeViewModel = {\n cart: null,\n session: null,\n store: null,\n stores: [],\n marketingItem: null,\n marketingItems: [],\n slots: {},\n }\n\n const templateCache = new Map<string, (context: AltazionDeclarativeViewModel) => string>()\n\n const render = (): void => {\n if (typeof document === 'undefined') {\n return\n }\n\n for (const element of document.querySelectorAll(`[${DATA_SOURCE_ATTRIBUTE}]`)) {\n const rawSource = element.getAttribute(DATA_SOURCE_ATTRIBUTE)\n const source = resolveDataSource(rawSource)\n if (!source) {\n continue\n }\n\n const rawStatus = element.getAttribute(DATA_STATUS_ATTRIBUTE)\n const sourceValue = resolveSourceValue(state, source)\n const isVisible = matchesStatus(rawStatus, sourceValue)\n applyVisibility(element, isVisible)\n renderElementTemplate(element, isVisible, state, sourceValue, handlebars, templateCache)\n }\n }\n\n return {\n update(key, value): void {\n state[key] = value\n render()\n },\n updateSlot(name, value): void {\n state.slots[name] = value\n render()\n },\n render,\n dispose(): void {\n templateCache.clear()\n },\n }\n}\n\nfunction matchesStatus(status: string | null, value: unknown): boolean {\n if (Array.isArray(value)) {\n switch (status) {\n case 'empty':\n return value.length === 0\n case 'not-empty':\n return value.length > 0\n default:\n return true\n }\n }\n\n switch (status) {\n case 'null':\n return value == null\n case 'not-null':\n return value != null\n default:\n return true\n }\n}\n\nfunction resolveDataSource(source: string | null): DataSourceReference | null {\n if (!source) {\n return null\n }\n\n if (source.startsWith('slot:')) {\n const slotKey = source.slice(5).trim()\n return slotKey.length > 0 ? { kind: 'slot', key: slotKey } : null\n }\n\n const resolvedKey = DATA_SOURCE_ALIASES[source]\n return resolvedKey ? { kind: 'state', key: resolvedKey } : null\n}\n\nfunction resolveSourceValue(\n state: AltazionDeclarativeViewModel,\n source: DataSourceReference\n): unknown {\n if (source.kind === 'slot') {\n return state.slots[source.key] ?? null\n }\n\n return state[source.key]\n}\n\nfunction applyVisibility(element: Element, isVisible: boolean): void {\n element.setAttribute('aria-hidden', isVisible ? 'false' : 'true')\n\n if (element instanceof HTMLElement) {\n element.hidden = !isVisible\n } else if (isVisible) {\n element.removeAttribute('hidden')\n } else {\n element.setAttribute('hidden', '')\n }\n}\n\nfunction renderElementTemplate(\n element: Element,\n isVisible: boolean,\n state: AltazionDeclarativeViewModel,\n sourceValue: unknown,\n handlebars: HandlebarsRuntime | undefined,\n templateCache: Map<string, (context: AltazionDeclarativeViewModel) => string>\n): void {\n if (!isVisible || !element.hasAttribute(RENDER_TEMPLATE_ATTRIBUTE) || !handlebars) {\n return\n }\n\n const templateId = element.getAttribute(RENDER_TEMPLATE_ATTRIBUTE)\n if (!templateId) {\n return\n }\n\n const template = resolveTemplate(templateId, handlebars, templateCache)\n if (!template) {\n return\n }\n\n element.innerHTML = template({\n ...state,\n slot: sourceValue,\n } as AltazionDeclarativeViewModel)\n}\n\nfunction resolveTemplate(\n templateId: string,\n handlebars: HandlebarsRuntime,\n templateCache: Map<string, (context: AltazionDeclarativeViewModel) => string>\n): ((context: AltazionDeclarativeViewModel) => string) | null {\n const cached = templateCache.get(templateId)\n if (cached) {\n return cached\n }\n\n if (typeof document === 'undefined') {\n return null\n }\n\n const templateElement = document.getElementById(templateId)\n if (!templateElement) {\n console.warn(`[AltazionHtmx] Template not found: ${templateId}`)\n return null\n }\n\n const compiled = handlebars.compile(templateElement.innerHTML)\n templateCache.set(templateId, compiled)\n return compiled\n}","export default \"<article class=\\\"altz-product-card{{#unless (isAvailable availability)}} altz-product-card--unavailable{{/unless}}\\\">\\n {{#if imageUrl}}\\n <a href=\\\"{{productUrl reference}}\\\" class=\\\"altz-product-card__image-link\\\" aria-label=\\\"{{name}}\\\">\\n <img\\n src=\\\"{{thumbnailUrl imageUrl 400}}\\\"\\n alt=\\\"{{name}}\\\"\\n class=\\\"altz-product-card__image\\\"\\n loading=\\\"lazy\\\"\\n width=\\\"400\\\"\\n />\\n </a>\\n {{/if}}\\n\\n <div class=\\\"altz-product-card__body\\\">\\n <a href=\\\"{{productUrl reference}}\\\" class=\\\"altz-product-card__title\\\">\\n {{name}}\\n </a>\\n\\n <div class=\\\"altz-product-card__pricing\\\">\\n {{#if discount}}\\n <span class=\\\"altz-product-card__price altz-product-card__price--discounted\\\">\\n {{formatPrice price}}\\n </span>\\n <span class=\\\"altz-product-card__price altz-product-card__price--original\\\">\\n {{formatPrice originalPrice}}\\n </span>\\n <span class=\\\"altz-product-card__discount-badge\\\">\\n {{discountPercent originalPrice price}}\\n </span>\\n {{else}}\\n <span class=\\\"altz-product-card__price\\\">\\n {{formatPrice price}}\\n </span>\\n {{/if}}\\n </div>\\n\\n {{#unless (isAvailable availability)}}\\n <p class=\\\"altz-product-card__unavailable\\\">{{unavailableLabel}}</p>\\n {{/unless}}\\n\\n {{#if (isAvailable availability)}}\\n <button\\n class=\\\"altz-product-card__add-to-cart\\\"\\n hx-ext=\\\"altazion\\\"\\n hx-altazion-cart-action=\\\"addItem\\\"\\n hx-altazion-cart-reference=\\\"{{reference}}\\\"\\n hx-altazion-cart-quantity=\\\"1\\\"\\n hx-altazion-refresh=\\\"#altz-cart-mini\\\"\\n hx-indicator=\\\".altz-spinner\\\"\\n >\\n {{addToCartLabel}}\\n </button>\\n {{/if}}\\n </div>\\n</article>\\n\"","export default \"<div id=\\\"altz-cart-mini\\\" class=\\\"altz-cart-mini\\\">\\n <div class=\\\"altz-cart-mini__header\\\">\\n <span class=\\\"altz-cart-mini__label\\\">{{cartLabel}}</span>\\n <span class=\\\"altz-cart-mini__count\\\">{{cartCount}}</span>\\n </div>\\n\\n {{#cartHasItems}}\\n <ul class=\\\"altz-cart-mini__lines\\\">\\n {{#each lines}}\\n <li class=\\\"altz-cart-mini__line\\\">\\n <span class=\\\"altz-cart-mini__line-name\\\">{{this.productName}}</span>\\n <span class=\\\"altz-cart-mini__line-qty\\\">× {{this.quantity}}</span>\\n <span class=\\\"altz-cart-mini__line-price\\\">{{formatPrice this.unitPriceWithTax}}</span>\\n </li>\\n {{/each}}\\n </ul>\\n\\n <div class=\\\"altz-cart-mini__total\\\">\\n <span>{{totalLabel}}</span>\\n <strong>{{cartTotal}}</strong>\\n </div>\\n\\n <a href=\\\"{{cartUrl}}\\\" class=\\\"altz-cart-mini__cta\\\">\\n {{viewCartLabel}}\\n </a>\\n {{/cartHasItems}}\\n\\n {{^cartHasItems}}\\n <p class=\\\"altz-cart-mini__empty\\\">{{emptyLabel}}</p>\\n {{/cartHasItems}}\\n</div>\\n\"","export default \"<section class=\\\"altz-product-list\\\">\\n {{#if title}}\\n <h2 class=\\\"altz-product-list__title\\\">{{title}}</h2>\\n {{/if}}\\n\\n {{#if products.length}}\\n <ul class=\\\"altz-product-list__grid\\\" role=\\\"list\\\">\\n {{#each products}}\\n <li class=\\\"altz-product-list__item\\\">\\n <article class=\\\"altz-product-card{{#unless (isAvailable this.availability)}} altz-product-card--unavailable{{/unless}}\\\">\\n {{#if this.imageUrl}}\\n <a href=\\\"{{productUrl this.reference}}\\\" class=\\\"altz-product-card__image-link\\\" aria-label=\\\"{{this.name}}\\\">\\n <img\\n src=\\\"{{thumbnailUrl this.imageUrl 300}}\\\"\\n alt=\\\"{{this.name}}\\\"\\n class=\\\"altz-product-card__image\\\"\\n loading=\\\"lazy\\\"\\n width=\\\"300\\\"\\n />\\n </a>\\n {{/if}}\\n\\n <div class=\\\"altz-product-card__body\\\">\\n <a href=\\\"{{productUrl this.reference}}\\\" class=\\\"altz-product-card__title\\\">\\n {{this.name}}\\n </a>\\n\\n <div class=\\\"altz-product-card__pricing\\\">\\n {{#if this.discount}}\\n <span class=\\\"altz-product-card__price altz-product-card__price--discounted\\\">\\n {{formatPrice this.price}}\\n </span>\\n <span class=\\\"altz-product-card__price altz-product-card__price--original\\\">\\n {{formatPrice this.originalPrice}}\\n </span>\\n <span class=\\\"altz-product-card__discount-badge\\\">\\n {{discountPercent this.originalPrice this.price}}\\n </span>\\n {{else}}\\n <span class=\\\"altz-product-card__price\\\">\\n {{formatPrice this.price}}\\n </span>\\n {{/if}}\\n </div>\\n\\n {{#if (isAvailable this.availability)}}\\n <button\\n class=\\\"altz-product-card__add-to-cart\\\"\\n hx-ext=\\\"altazion\\\"\\n hx-altazion-cart-action=\\\"addItem\\\"\\n hx-altazion-cart-reference=\\\"{{this.reference}}\\\"\\n hx-altazion-cart-quantity=\\\"1\\\"\\n hx-altazion-refresh=\\\"#altz-cart-mini\\\"\\n hx-indicator=\\\".altz-spinner\\\"\\n >\\n {{../addToCartLabel}}\\n </button>\\n {{/if}}\\n </div>\\n </article>\\n </li>\\n {{/each}}\\n </ul>\\n {{else}}\\n <p class=\\\"altz-product-list__empty\\\">{{emptyLabel}}</p>\\n {{/if}}\\n</section>\\n\"","import type { CommerceClient, Cart, ConnectivityStatus, SessionInfo, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\nimport type Handlebars from 'handlebars'\n\nimport {\n registerAltazionExtension,\n type AltazionActionEventDetail,\n type AltazionCartEventDetail,\n type AltazionExtensionHandle,\n type AltazionMarketingEventDetail,\n type AltazionSessionEventDetail,\n type AltazionStoresEventDetail,\n} from './extensions/altazion-auth'\nimport { registerPriceHelpers } from './helpers/price'\nimport { registerProductHelpers } from './helpers/product'\nimport { registerCartHelpers } from './helpers/cart'\nimport { createAltazionDeclarativeRenderer } from './rendering/declarative-renderer'\n\n// Templates pré-compilés importés en tant que chaînes brutes\nimport productCardTemplate from './templates/product-card.hbs?raw'\nimport cartMiniTemplate from './templates/cart-mini.hbs?raw'\nimport productListTemplate from './templates/product-list.hbs?raw'\n\nexport type { Cart }\n\ntype SelectorInput = string | string[]\n\nexport interface AltazionTerminalModeConfig {\n /** Zones interactives à masquer en mode hors ligne. */\n interactiveSelectors?: SelectorInput\n /** Zones passives à afficher en mode hors ligne. */\n offlineScreenSelectors?: SelectorInput\n}\n\nexport interface AltazionConnectivityEventDetail {\n status: ConnectivityStatus\n isOnline: boolean\n isOffline: boolean\n root: Element\n}\n\nexport interface AltazionHtmxConfig {\n /** Instance CommerceClient déjà initialisée */\n client: CommerceClient\n /**\n * Instance Handlebars (global ou importée).\n * Si omis, les helpers ne sont pas enregistrés.\n */\n handlebars?: typeof Handlebars\n /**\n * Sélecteur CSS de l'élément DOM à basculer avec la classe `altz-offline`\n * lorsque la connectivité est perdue/restaurée.\n * @default 'body'\n */\n offlineSelector?: string\n /** Configuration UI du mode hors ligne borne. */\n terminalMode?: AltazionTerminalModeConfig\n}\n\nexport interface AltazionHtmxInstance {\n /** Templates Handlebars compilés prêts à l'emploi */\n templates: {\n productCard: HandlebarsTemplateDelegate\n cartMini: HandlebarsTemplateDelegate\n productList: HandlebarsTemplateDelegate\n }\n /** Détruit les listeners et libère les ressources */\n dispose(): void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype HandlebarsTemplateDelegate = (context?: any) => string\n\n/**\n * Initialise le SDK HTMX Altazion.\n *\n * - Enregistre l'extension HTMX (headers contexte) si htmx est présent\n * - Enregistre les helpers Handlebars (prix, produits, panier) si hbs est fourni\n * - Active l'indicateur d'état offline sur le DOM\n * - Retourne les templates compilés\n *\n * @example\n * ```ts\n * import Handlebars from 'handlebars'\n * const sdk = init({ client, handlebars: Handlebars })\n * const html = sdk.templates.productCard(product)\n * document.getElementById('product')!.innerHTML = html\n * ```\n */\nexport function initAltazionHtmx(config: AltazionHtmxConfig): AltazionHtmxInstance {\n const {\n client,\n handlebars,\n offlineSelector = 'body',\n terminalMode,\n } = config\n\n // 1. Extension HTMX — headers de contexte + actions panier déclaratives\n const extensionHandle: AltazionExtensionHandle = registerAltazionExtension(client)\n\n // 2. HTMX config globale — transmettre les cookies sur les requêtes XHR HTMX\n if (typeof window !== 'undefined' && window.htmx) {\n // @ts-expect-error — htmx.config n'est pas dans les types window\n window.htmx.config = window.htmx.config ?? {}\n // @ts-expect-error\n window.htmx.config.withCredentials = true\n }\n\n // 3. Helpers Handlebars\n const defaults = {\n locale: client.context.locale,\n currency: client.context.currency,\n }\n\n const handlebarsRuntime = handlebars\n ?? (typeof window !== 'undefined'\n ? (window as Window & { Handlebars?: typeof Handlebars }).Handlebars\n : undefined)\n\n const declarativeRenderer = createAltazionDeclarativeRenderer(handlebarsRuntime)\n const syncSlotFromEvent = (detail: AltazionActionEventDetail): void => {\n const slotName = detail.element.getAttribute('hx-altazion-data-slot')?.trim()\n if (!slotName) {\n return\n }\n\n declarativeRenderer.updateSlot(slotName, detail.result ?? null)\n }\n\n // Getter réactif sur le panier actuel utilisé par les helpers Handlebars.\n let currentCart: Cart | null = null\n const getCart = (): Cart | null => currentCart\n\n const syncCartFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionCartEventDetail<Cart>>\n if (customEvent.detail.result) {\n currentCart = customEvent.detail.result\n declarativeRenderer.update('cart', currentCart)\n }\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncSessionFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionSessionEventDetail<SessionInfo>>\n declarativeRenderer.update('session', customEvent.detail.result ?? null)\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncStoreFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionStoresEventDetail<StoreWithOpeningHours>>\n declarativeRenderer.update('store', customEvent.detail.result ?? null)\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncStoresFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionStoresEventDetail<StoreWithOpeningHours[]>>\n declarativeRenderer.update('stores', Array.isArray(customEvent.detail.result) ? customEvent.detail.result : [])\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncMarketingItemFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionMarketingEventDetail>\n declarativeRenderer.update('marketingItem', Array.isArray(customEvent.detail.result) ? null : customEvent.detail.result ?? null)\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncMarketingItemsFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionMarketingEventDetail>\n declarativeRenderer.update('marketingItems', Array.isArray(customEvent.detail.result) ? customEvent.detail.result : [])\n syncSlotFromEvent(customEvent.detail)\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('altazion:cart:loaded', syncCartFromEvent)\n document.addEventListener('altazion:cart:updated', syncCartFromEvent)\n document.addEventListener('altazion:session:loaded', syncSessionFromEvent)\n document.addEventListener('altazion:stores:store-loaded', syncStoreFromEvent)\n document.addEventListener('altazion:stores:stores-loaded', syncStoresFromEvent)\n document.addEventListener('altazion:marketing:item-loaded', syncMarketingItemFromEvent)\n document.addEventListener('altazion:marketing:items-loaded', syncMarketingItemsFromEvent)\n }\n\n void client.cart.getCart()\n .then((cart: Cart) => {\n currentCart = cart\n declarativeRenderer.update('cart', cart)\n })\n .catch(() => { /* panier non disponible au chargement */ })\n\n if (handlebars) {\n registerPriceHelpers(handlebars, defaults)\n registerProductHelpers(handlebars, client.context.siteUrl ?? '')\n registerCartHelpers(handlebars, getCart, defaults)\n }\n\n declarativeRenderer.render()\n\n // 4. Indicateur offline DOM + mode borne\n const offlineEl = typeof document !== 'undefined'\n ? document.querySelector(offlineSelector) ?? document.body\n : null\n\n let lastConnectivityStatus: ConnectivityStatus | null = null\n\n const updateOfflineClass = (): void => {\n if (!offlineEl) {\n return\n }\n\n const status: ConnectivityStatus = client.isOffline ? 'offline' : 'online'\n const isOffline = status === 'offline'\n\n offlineEl.classList.toggle('altz-offline', isOffline)\n offlineEl.classList.toggle('altz-terminal-offline', isOffline)\n offlineEl.classList.toggle('altz-terminal-online', !isOffline)\n offlineEl.setAttribute('data-altazion-terminal-state', status)\n\n updateManagedVisibility(resolveManagedElements(terminalMode?.interactiveSelectors), isOffline, 'altz-terminal-interactive-hidden')\n updateManagedVisibility(resolveManagedElements(terminalMode?.offlineScreenSelectors), !isOffline, 'altz-terminal-offline-screen-hidden')\n\n if (lastConnectivityStatus === status) {\n return\n }\n\n lastConnectivityStatus = status\n dispatchConnectivityEvent(offlineEl, 'altazion:connectivity:changed', status)\n dispatchConnectivityEvent(offlineEl, isOffline ? 'altazion:offline' : 'altazion:online', status)\n }\n\n // Synchronisation initiale\n updateOfflineClass()\n\n // Abonnement ConnectivityManager — retourne la fonction de désabonnement\n const unsubscribeConnectivity = client.connectivity?.subscribe(() => updateOfflineClass())\n\n // 5. Templates compilés (retournés pour usage dans le code applicatif)\n const noHbs = (): HandlebarsTemplateDelegate =>\n () => '<!-- handlebars non initialisé dans @altazion/commerce-sdk-htmx -->'\n\n const templates = handlebars\n ? {\n productCard: handlebars.compile(productCardTemplate),\n cartMini: handlebars.compile(cartMiniTemplate),\n productList: handlebars.compile(productListTemplate),\n }\n : {\n productCard: noHbs(),\n cartMini: noHbs(),\n productList: noHbs(),\n }\n\n return {\n templates,\n dispose(): void {\n extensionHandle.dispose()\n if (typeof document !== 'undefined') {\n document.removeEventListener('altazion:cart:loaded', syncCartFromEvent)\n document.removeEventListener('altazion:cart:updated', syncCartFromEvent)\n document.removeEventListener('altazion:session:loaded', syncSessionFromEvent)\n document.removeEventListener('altazion:stores:store-loaded', syncStoreFromEvent)\n document.removeEventListener('altazion:stores:stores-loaded', syncStoresFromEvent)\n document.removeEventListener('altazion:marketing:item-loaded', syncMarketingItemFromEvent)\n document.removeEventListener('altazion:marketing:items-loaded', syncMarketingItemsFromEvent)\n }\n declarativeRenderer.dispose()\n unsubscribeConnectivity?.()\n },\n }\n}\n\nexport const init = initAltazionHtmx\n\nfunction resolveManagedElements(selectorInput?: SelectorInput): Element[] {\n if (typeof document === 'undefined' || !selectorInput) {\n return []\n }\n\n const selectors = Array.isArray(selectorInput) ? selectorInput : [selectorInput]\n const elements = new Set<Element>()\n\n for (const selector of selectors) {\n if (!selector.trim()) {\n continue\n }\n\n try {\n for (const element of document.querySelectorAll(selector)) {\n elements.add(element)\n }\n } catch {\n // Sélecteur invalide : on ignore silencieusement.\n }\n }\n\n return [...elements]\n}\n\nfunction updateManagedVisibility(elements: Element[], hidden: boolean, hiddenClassName: string): void {\n for (const element of elements) {\n element.classList.toggle(hiddenClassName, hidden)\n element.setAttribute('aria-hidden', hidden ? 'true' : 'false')\n\n if (element instanceof HTMLElement) {\n element.hidden = hidden\n } else if (hidden) {\n element.setAttribute('hidden', '')\n } else {\n element.removeAttribute('hidden')\n }\n }\n}\n\nfunction dispatchConnectivityEvent(\n root: Element,\n eventName: string,\n status: ConnectivityStatus\n): void {\n const detail: AltazionConnectivityEventDetail = {\n status,\n isOnline: status === 'online',\n isOffline: status === 'offline',\n root,\n }\n\n root.dispatchEvent(new CustomEvent<AltazionConnectivityEventDetail>(eventName, {\n bubbles: true,\n detail,\n }))\n}\n\n// Re-exports helpers pour usage à la carte\nexport { registerPriceHelpers } from './helpers/price'\nexport { registerProductHelpers } from './helpers/product'\nexport { registerCartHelpers } from './helpers/cart'\nexport {\n registerAltazionExtension,\n registerAltazionAuthExtension,\n} from './extensions/altazion-auth'\nexport type {\n AltazionActionEventDetail,\n AltazionActionErrorDetail,\n AltazionCartActionName,\n AltazionCartEventDetail,\n AltazionExtensionHandle,\n AltazionMarketingActionName,\n AltazionMarketingEventDetail,\n AltazionSessionActionName,\n AltazionSessionEventDetail,\n AltazionStoresActionName,\n AltazionStoresEventDetail,\n AltazionSuccessEventKind,\n} from './extensions/altazion-auth'\n"],"names":["AltazionApiError","OfflineError","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/extensions/altazion-engine.ts","../src/extensions/modules/cart.ts","../src/extensions/modules/session.ts","../src/extensions/modules/marketing.ts","../src/extensions/modules/stores.ts","../src/extensions/altazion-auth.ts","../src/helpers/price.ts","../src/helpers/product.ts","../src/helpers/cart.ts","../src/rendering/declarative-renderer.ts","../src/modules/store-picker.ts","../src/templates/product-card.hbs?raw","../src/templates/cart-mini.hbs?raw","../src/templates/product-list.hbs?raw","../src/index.ts"],"sourcesContent":["import {\n AltazionApiError,\n OfflineError,\n type CommerceClient,\n type ProblemDetails,\n} from '@altazion/commerce-sdk-core'\n\ndeclare global {\n interface Window {\n htmx?: {\n on(eventName: string, listener: (event: Event) => void): void\n off(eventName: string, listener: (event: Event) => void): void\n ajax(\n method: string,\n path: string,\n context?: {\n source?: Element\n target?: Element | string\n swap?: string\n select?: string\n values?: Record<string, unknown>\n }\n ): Promise<unknown> | void\n }\n }\n}\n\nexport interface AltazionExtensionHandle {\n dispose(): void\n}\n\nexport interface AltazionActionEventDetail<\n TModule extends string = string,\n TAction extends string = string,\n TResult = unknown,\n> {\n module: TModule\n action: TAction\n element: Element\n payload: Record<string, unknown>\n result?: TResult\n error?: unknown\n errorDetail?: AltazionActionErrorDetail\n}\n\nexport interface AltazionActionErrorDetail {\n name: string\n message: string\n status?: number\n problem?: ProblemDetails\n isOffline: boolean\n isConflict: boolean\n}\n\nexport type AltazionSuccessEventKind = 'loaded' | 'updated' | 'changed' | 'none'\n\nexport interface AltazionModuleDefinition<\n TModule extends string = string,\n TAction extends string = string,\n TResult = unknown,\n> {\n moduleName: TModule\n actionAttribute: string\n payloadAttributes?: Record<string, string>\n jsonPayloadAttributes?: Record<string, string>\n payloadAliases?: Record<string, string>\n normalizePayload?(payload: Record<string, unknown>): void\n parseAction(actionValue: string): TAction\n execute(client: CommerceClient, action: TAction, payload: Record<string, unknown>): Promise<TResult>\n successEventKind?: AltazionSuccessEventKind | ((action: TAction, result: TResult, payload: Record<string, unknown>) => AltazionSuccessEventKind)\n getResultEventSuffixes?(action: TAction, result: TResult, payload: Record<string, unknown>): string[]\n}\n\ninterface HtmxConfigRequestEvent extends Event {\n detail: {\n headers: Record<string, string>\n elt: Element\n }\n}\n\ninterface MatchedAction<TModule extends string = string, TAction extends string = string, TResult = unknown> {\n definition: AltazionModuleDefinition<TModule, TAction, TResult>\n element: Element\n}\n\ninterface DisableableElement extends HTMLElement {\n disabled: boolean\n}\n\nconst EXTENSION_NAME = 'altazion'\nconst JSON_VALUES_ATTRIBUTE = 'hx-vals'\nconst REFRESH_ATTRIBUTE = 'hx-altazion-refresh'\nconst REFRESH_EVENT_NAME = 'altazion:refresh'\n\nconst REQUEST_ATTRIBUTES = [\n { attribute: 'hx-get', method: 'GET' },\n { attribute: 'hx-post', method: 'POST' },\n { attribute: 'hx-put', method: 'PUT' },\n { attribute: 'hx-patch', method: 'PATCH' },\n { attribute: 'hx-delete', method: 'DELETE' },\n] as const\n\nexport function createAltazionExtension(\n client: CommerceClient,\n modules: readonly AltazionModuleDefinition<any, any, any>[]\n): AltazionExtensionHandle {\n const requestHandler = (event: Event): void => {\n const e = event as HtmxConfigRequestEvent\n e.detail.headers['Accept-Language'] = client.context.locale\n e.detail.headers['X-Altazion-Currency'] = client.context.currency\n }\n\n if (typeof window !== 'undefined' && window.htmx) {\n window.htmx.on('htmx:configRequest', requestHandler)\n }\n\n if (typeof document === 'undefined') {\n return {\n dispose(): void {\n if (typeof window !== 'undefined' && window.htmx) {\n window.htmx.off('htmx:configRequest', requestHandler)\n }\n },\n }\n }\n\n const handleClick = (event: Event): void => {\n const mouseEvent = event as MouseEvent\n if (\n mouseEvent.defaultPrevented\n || mouseEvent.button !== 0\n || mouseEvent.metaKey\n || mouseEvent.ctrlKey\n || mouseEvent.shiftKey\n || mouseEvent.altKey\n ) {\n return\n }\n\n const target = event.target\n if (!(target instanceof Element)) {\n return\n }\n\n const matchedAction = findMatchedAction(target, modules)\n if (!matchedAction || matchedAction.element instanceof HTMLFormElement || !hasAltazionExtension(matchedAction.element)) {\n return\n }\n\n event.preventDefault()\n void runModuleAction(client, matchedAction)\n }\n\n const handleSubmit = (event: Event): void => {\n const target = event.target\n if (!(target instanceof HTMLFormElement)) {\n return\n }\n\n const matchedAction = findMatchedAction(target, modules)\n if (!matchedAction || matchedAction.element !== target || !hasAltazionExtension(target)) {\n return\n }\n\n event.preventDefault()\n void runModuleAction(client, matchedAction)\n }\n\n document.addEventListener('click', handleClick)\n document.addEventListener('submit', handleSubmit)\n\n return {\n dispose(): void {\n if (typeof window !== 'undefined' && window.htmx) {\n window.htmx.off('htmx:configRequest', requestHandler)\n }\n\n document.removeEventListener('click', handleClick)\n document.removeEventListener('submit', handleSubmit)\n },\n }\n}\n\nexport function requireString(value: unknown, fieldName: string): string {\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n\n throw new Error(`Missing payload field: ${fieldName}`)\n}\n\nexport function requireNumber(value: unknown, fieldName: string): number {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value\n }\n\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) {\n return parsed\n }\n }\n\n throw new Error(`Invalid payload field: ${fieldName}`)\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined\n }\n\n return value as Record<string, unknown>\n}\n\nasync function runModuleAction<TModule extends string, TAction extends string, TResult>(\n client: CommerceClient,\n matchedAction: MatchedAction<TModule, TAction, TResult>\n): Promise<void> {\n const { definition, element } = matchedAction\n const action = readActionName(element, definition)\n const payload = collectPayload(element, definition)\n const releasePending = markPending(element)\n\n dispatchModuleEvent<TModule, TAction, undefined>(element, buildModuleEventName(definition.moduleName, 'before'), {\n module: definition.moduleName,\n action,\n element,\n payload,\n })\n\n try {\n const result = await definition.execute(client, action, payload)\n\n dispatchModuleEvent<TModule, TAction, TResult>(element, buildModuleEventName(definition.moduleName, 'after'), {\n module: definition.moduleName,\n action,\n element,\n payload,\n result,\n })\n\n const successEventKind = resolveSuccessEventKind(definition, action, result, payload)\n const emittedSuffixes = new Set<string>()\n\n if (successEventKind !== 'none') {\n emittedSuffixes.add(successEventKind)\n dispatchModuleEvent<TModule, TAction, TResult>(element, buildModuleEventName(definition.moduleName, successEventKind), {\n module: definition.moduleName,\n action,\n element,\n payload,\n result,\n })\n }\n\n for (const suffix of definition.getResultEventSuffixes?.(action, result, payload) ?? []) {\n if (emittedSuffixes.has(suffix)) {\n continue\n }\n\n dispatchModuleEvent<TModule, TAction, TResult>(element, buildModuleEventName(definition.moduleName, suffix), {\n module: definition.moduleName,\n action,\n element,\n payload,\n result,\n })\n }\n\n await refreshTargets(element)\n } catch (error) {\n const errorDetail = normalizeError(error)\n\n dispatchModuleEvent<TModule, TAction, undefined>(element, buildModuleEventName(definition.moduleName, 'error'), {\n module: definition.moduleName,\n action,\n element,\n payload,\n error,\n errorDetail,\n })\n console.error(`[AltazionHtmx] ${definition.moduleName} action failed`, error)\n } finally {\n releasePending()\n }\n}\n\nfunction findMatchedAction(\n target: Element,\n modules: readonly AltazionModuleDefinition<any, any, any>[]\n): MatchedAction | null {\n let current: Element | null = target\n\n while (current) {\n for (const definition of modules) {\n if (current.hasAttribute(definition.actionAttribute)) {\n return { definition, element: current }\n }\n }\n\n current = current.parentElement\n }\n\n return null\n}\n\nfunction readActionName<TModule extends string, TAction extends string, TResult>(\n element: Element,\n definition: AltazionModuleDefinition<TModule, TAction, TResult>\n): TAction {\n const action = element.getAttribute(definition.actionAttribute)\n if (!action) {\n throw new Error(`Missing ${definition.actionAttribute} attribute`)\n }\n\n return definition.parseAction(action)\n}\n\nfunction collectPayload<TModule extends string, TAction extends string, TResult>(\n element: Element,\n definition: AltazionModuleDefinition<TModule, TAction, TResult>\n): Record<string, unknown> {\n const payload: Record<string, unknown> = {}\n const form = element instanceof HTMLFormElement ? element : element.closest('form')\n\n if (form) {\n Object.assign(payload, formDataToObject(new FormData(form)))\n mergeJsonValues(payload, form)\n applyAttributePayload(payload, form, definition.payloadAttributes)\n applyJsonAttributePayload(payload, form, definition.jsonPayloadAttributes)\n }\n\n mergeJsonValues(payload, element)\n applyAttributePayload(payload, element, definition.payloadAttributes)\n applyJsonAttributePayload(payload, element, definition.jsonPayloadAttributes)\n applyPayloadAliases(payload, definition.payloadAliases)\n definition.normalizePayload?.(payload)\n\n return payload\n}\n\nfunction mergeJsonValues(payload: Record<string, unknown>, element: Element): void {\n const values = readJsonValues(element, JSON_VALUES_ATTRIBUTE)\n if (values) {\n Object.assign(payload, values)\n }\n}\n\nfunction applyAttributePayload(\n payload: Record<string, unknown>,\n element: Element,\n attributes?: Record<string, string>\n): void {\n if (!attributes) {\n return\n }\n\n for (const [attributeName, payloadKey] of Object.entries(attributes)) {\n const value = element.getAttribute(attributeName)\n if (value !== null) {\n payload[payloadKey] = value\n }\n }\n}\n\nfunction applyJsonAttributePayload(\n payload: Record<string, unknown>,\n element: Element,\n attributes?: Record<string, string>\n): void {\n if (!attributes) {\n return\n }\n\n for (const [attributeName, payloadKey] of Object.entries(attributes)) {\n const value = readJsonValues(element, attributeName)\n if (value !== undefined) {\n payload[payloadKey] = value\n }\n }\n}\n\nfunction applyPayloadAliases(payload: Record<string, unknown>, aliases?: Record<string, string>): void {\n if (!aliases) {\n return\n }\n\n for (const [alias, canonicalKey] of Object.entries(aliases)) {\n if (payload[alias] !== undefined && payload[canonicalKey] === undefined) {\n payload[canonicalKey] = payload[alias]\n }\n }\n}\n\nfunction formDataToObject(formData: FormData): Record<string, unknown> {\n const payload: Record<string, unknown> = {}\n\n for (const [key, value] of formData.entries()) {\n const normalizedValue = typeof value === 'string' ? value : value.name\n const previous = payload[key]\n\n if (previous === undefined) {\n payload[key] = normalizedValue\n } else if (Array.isArray(previous)) {\n previous.push(normalizedValue)\n } else {\n payload[key] = [previous, normalizedValue]\n }\n }\n\n return payload\n}\n\nfunction dispatchModuleEvent<TModule extends string, TAction extends string, TResult>(\n element: Element,\n eventName: string,\n detail: AltazionActionEventDetail<TModule, TAction, TResult>\n): void {\n element.dispatchEvent(new CustomEvent<AltazionActionEventDetail<TModule, TAction, TResult>>(eventName, {\n bubbles: true,\n detail,\n }))\n}\n\nfunction buildModuleEventName(moduleName: string, suffix: string): string {\n return `altazion:${moduleName}:${suffix}`\n}\n\nfunction resolveSuccessEventKind<TModule extends string, TAction extends string, TResult>(\n definition: AltazionModuleDefinition<TModule, TAction, TResult>,\n action: TAction,\n result: TResult,\n payload: Record<string, unknown>\n): AltazionSuccessEventKind {\n const configuredKind = definition.successEventKind\n if (typeof configuredKind === 'function') {\n return configuredKind(action, result, payload)\n }\n\n if (configuredKind) {\n return configuredKind\n }\n\n return inferSuccessEventKind(action, result)\n}\n\nfunction inferSuccessEventKind<TAction extends string, TResult>(action: TAction, result: TResult): AltazionSuccessEventKind {\n if (result === undefined) {\n return 'changed'\n }\n\n const normalizedAction = action.toLowerCase()\n if (\n normalizedAction.startsWith('get')\n || normalizedAction.startsWith('find')\n || normalizedAction.startsWith('search')\n || normalizedAction.startsWith('suggest')\n || normalizedAction.startsWith('load')\n || normalizedAction.startsWith('list')\n ) {\n return 'loaded'\n }\n\n return 'updated'\n}\n\nfunction normalizeError(error: unknown): AltazionActionErrorDetail {\n if (error instanceof AltazionApiError) {\n return {\n name: error.name,\n message: error.message,\n status: error.status,\n problem: error.problem,\n isOffline: false,\n isConflict: error.status === 409,\n }\n }\n\n if (error instanceof OfflineError) {\n return {\n name: error.name,\n message: error.message,\n isOffline: true,\n isConflict: false,\n }\n }\n\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n isOffline: false,\n isConflict: false,\n }\n }\n\n return {\n name: 'UnknownError',\n message: 'Unknown error',\n isOffline: false,\n isConflict: false,\n }\n}\n\nasync function refreshTargets(element: Element): Promise<void> {\n const targets = resolveRefreshTargets(element)\n if (targets.length === 0) {\n return\n }\n\n await Promise.all(targets.map((target) => refreshTargetElement(element, target)))\n}\n\nfunction resolveRefreshTargets(element: Element): Element[] {\n if (typeof document === 'undefined') {\n return []\n }\n\n const selectors = collectRefreshSelectors(element)\n if (selectors.length === 0) {\n return []\n }\n\n const targets = new Set<Element>()\n\n for (const selector of selectors) {\n try {\n for (const target of document.querySelectorAll(selector)) {\n targets.add(target)\n }\n } catch (error) {\n console.error(`[AltazionHtmx] invalid refresh selector: ${selector}`, error)\n }\n }\n\n return [...targets]\n}\n\nfunction collectRefreshSelectors(element: Element): string[] {\n const values = new Set<string>()\n const form = element instanceof HTMLFormElement ? element : element.closest('form')\n\n addRefreshSelectors(values, form)\n addRefreshSelectors(values, element)\n\n return [...values]\n}\n\nfunction addRefreshSelectors(values: Set<string>, element: Element | null): void {\n const rawValue = element?.getAttribute(REFRESH_ATTRIBUTE)\n if (!rawValue) {\n return\n }\n\n for (const selector of rawValue.split(';')) {\n const trimmed = selector.trim()\n if (trimmed.length > 0) {\n values.add(trimmed)\n }\n }\n}\n\nasync function refreshTargetElement(sourceElement: Element, targetElement: Element): Promise<void> {\n const request = readRefreshRequest(targetElement)\n if (request && typeof window !== 'undefined' && window.htmx?.ajax) {\n const context: {\n source: Element\n target: Element\n swap?: string\n select?: string\n values?: Record<string, unknown>\n } = {\n source: sourceElement,\n target: targetElement,\n }\n\n const swap = targetElement.getAttribute('hx-swap')\n if (swap) {\n context.swap = swap\n }\n\n const select = targetElement.getAttribute('hx-select')\n if (select) {\n context.select = select\n }\n\n const values = readJsonValues(targetElement, JSON_VALUES_ATTRIBUTE)\n if (values) {\n context.values = values\n }\n\n await Promise.resolve(window.htmx.ajax(request.method, request.path, context))\n return\n }\n\n targetElement.dispatchEvent(new CustomEvent(REFRESH_EVENT_NAME, {\n bubbles: true,\n detail: {\n source: sourceElement,\n target: targetElement,\n },\n }))\n}\n\nfunction readRefreshRequest(element: Element): { method: string, path: string } | null {\n for (const requestAttribute of REQUEST_ATTRIBUTES) {\n const path = element.getAttribute(requestAttribute.attribute)\n if (path) {\n return {\n method: requestAttribute.method,\n path,\n }\n }\n }\n\n return null\n}\n\nfunction readJsonValues(element: Element, attributeName: string): Record<string, unknown> | undefined {\n const raw = element.getAttribute(attributeName)\n if (!raw) {\n return undefined\n }\n\n try {\n const parsed = JSON.parse(raw) as unknown\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>\n }\n } catch {\n throw new Error(`Invalid JSON in ${attributeName}`)\n }\n\n return undefined\n}\n\nfunction markPending(element: Element): () => void {\n const previousBusy = element.getAttribute('aria-busy')\n element.setAttribute('aria-busy', 'true')\n\n const disableable = isDisableableElement(element) ? element : null\n const previousDisabled = disableable?.disabled ?? false\n if (disableable) {\n disableable.disabled = true\n }\n\n return (): void => {\n if (previousBusy === null) {\n element.removeAttribute('aria-busy')\n } else {\n element.setAttribute('aria-busy', previousBusy)\n }\n\n if (disableable) {\n disableable.disabled = previousDisabled\n }\n }\n}\n\nfunction isDisableableElement(element: Element): element is DisableableElement {\n return 'disabled' in element\n}\n\nfunction hasAltazionExtension(element: Element): boolean {\n let current: Element | null = element\n while (current) {\n const extensions = current.getAttribute('hx-ext')\n if (extensions && parseExtensions(extensions).includes(EXTENSION_NAME)) {\n return true\n }\n\n current = current.parentElement\n }\n\n return false\n}\n\nfunction parseExtensions(value: string): string[] {\n return value\n .split(/[\\s,]+/)\n .map((extension) => extension.trim())\n .filter((extension) => extension.length > 0)\n}","import type { Cart, CartValidationStatus, CommerceClient } from '@altazion/commerce-sdk-core'\n\nimport {\n asRecord,\n requireNumber,\n requireString,\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionCartActionName =\n | 'getCart'\n | 'getValidationStatus'\n | 'addItem'\n | 'updateItem'\n | 'removeItem'\n | 'applyCoupon'\n | 'removeCoupon'\n\nexport type CartActionResult = Cart | CartValidationStatus\n\nexport const cartModuleDefinition: AltazionModuleDefinition<'cart', AltazionCartActionName, CartActionResult> = {\n moduleName: 'cart',\n actionAttribute: 'hx-altazion-cart-action',\n payloadAttributes: {\n 'hx-altazion-cart-reference': 'reference',\n 'hx-altazion-cart-quantity': 'quantity',\n 'hx-altazion-cart-line-id': 'lineId',\n 'hx-altazion-cart-code': 'code',\n },\n jsonPayloadAttributes: {\n 'hx-altazion-cart-options': 'options',\n },\n payloadAliases: {\n ref: 'reference',\n productReference: 'reference',\n qty: 'quantity',\n line: 'lineId',\n coupon: 'code',\n },\n parseAction(actionValue: string): AltazionCartActionName {\n switch (actionValue) {\n case 'getCart':\n case 'getValidationStatus':\n case 'addItem':\n case 'updateItem':\n case 'removeItem':\n case 'applyCoupon':\n case 'removeCoupon':\n return actionValue\n default:\n throw new Error(`Unsupported cart action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionCartActionName, payload: Record<string, unknown>): Promise<CartActionResult> {\n switch (action) {\n case 'getCart':\n return client.cart.getCart()\n case 'getValidationStatus':\n return client.cart.getValidationStatus()\n case 'addItem': {\n const reference = requireString(payload.reference, 'reference')\n const quantity = requireNumber(payload.quantity, 'quantity')\n const options = buildAddItemOptions(payload)\n return client.cart.addItem(reference, quantity, options)\n }\n case 'updateItem': {\n const lineId = requireString(payload.lineId, 'lineId')\n const quantity = requireNumber(payload.quantity, 'quantity')\n return client.cart.updateItem(lineId, quantity)\n }\n case 'removeItem':\n return client.cart.removeItem(requireString(payload.lineId, 'lineId'))\n case 'applyCoupon':\n return client.cart.applyCoupon(requireString(payload.code, 'code'))\n case 'removeCoupon':\n return client.cart.removeCoupon(requireString(payload.code, 'code'))\n }\n },\n successEventKind(action: AltazionCartActionName): AltazionSuccessEventKind {\n switch (action) {\n case 'getCart':\n return 'loaded'\n case 'getValidationStatus':\n return 'none'\n case 'addItem':\n case 'updateItem':\n case 'removeItem':\n case 'applyCoupon':\n case 'removeCoupon':\n return 'updated'\n }\n },\n getResultEventSuffixes(_action: AltazionCartActionName, result: CartActionResult): string[] {\n return isCart(result) ? ['updated'] : ['status']\n },\n}\n\nfunction buildAddItemOptions(payload: Record<string, unknown>): Record<string, unknown> | undefined {\n const options = asRecord(payload.options)\n const extraEntries = Object.entries(payload).filter(([key]) => ![\n 'reference',\n 'ref',\n 'productReference',\n 'quantity',\n 'qty',\n 'options',\n ].includes(key))\n\n if (extraEntries.length === 0 && !options) {\n return undefined\n }\n\n return {\n ...Object.fromEntries(extraEntries),\n ...options,\n }\n}\n\nfunction isCart(result: CartActionResult): result is Cart {\n return 'guid' in result\n}","import type { CommerceClient, SessionInfo } from '@altazion/commerce-sdk-core'\n\nimport {\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionSessionActionName = 'getSession'\n\nexport const sessionModuleDefinition: AltazionModuleDefinition<'session', AltazionSessionActionName, SessionInfo> = {\n moduleName: 'session',\n actionAttribute: 'hx-altazion-session-action',\n parseAction(actionValue: string): AltazionSessionActionName {\n switch (actionValue) {\n case 'getSession':\n return actionValue\n default:\n throw new Error(`Unsupported session action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionSessionActionName): Promise<SessionInfo> {\n switch (action) {\n case 'getSession':\n return client.session.getSession()\n }\n },\n successEventKind(): AltazionSuccessEventKind {\n return 'loaded'\n },\n}","import type { CommerceClient, MarketingItem } from '@altazion/commerce-sdk-core'\n\nimport {\n requireString,\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionMarketingActionName = 'getItem' | 'getItems'\n\nexport type MarketingActionResult = MarketingItem | MarketingItem[]\n\nexport const marketingModuleDefinition: AltazionModuleDefinition<'marketing', AltazionMarketingActionName, MarketingActionResult> = {\n moduleName: 'marketing',\n actionAttribute: 'hx-altazion-marketing-action',\n payloadAttributes: {\n 'hx-altazion-marketing-code': 'code',\n },\n jsonPayloadAttributes: {\n 'hx-altazion-marketing-codes': 'codes',\n },\n parseAction(actionValue: string): AltazionMarketingActionName {\n switch (actionValue) {\n case 'getItem':\n case 'getItems':\n return actionValue\n default:\n throw new Error(`Unsupported marketing action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionMarketingActionName, payload: Record<string, unknown>): Promise<MarketingActionResult> {\n switch (action) {\n case 'getItem':\n return client.marketing.getItem(requireString(payload.code, 'code'))\n case 'getItems':\n return client.marketing.getItems(readCodes(payload))\n }\n },\n successEventKind(): AltazionSuccessEventKind {\n return 'loaded'\n },\n getResultEventSuffixes(action: AltazionMarketingActionName): string[] {\n switch (action) {\n case 'getItem':\n return ['item-loaded']\n case 'getItems':\n return ['items-loaded']\n }\n },\n}\n\nfunction readCodes(payload: Record<string, unknown>): string[] {\n const value = payload.codes\n\n if (Array.isArray(value)) {\n const codes = value\n .filter((entry): entry is string => typeof entry === 'string')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n\n if (codes.length > 0) {\n return codes\n }\n }\n\n if (typeof value === 'string') {\n const codes = value\n .split(',')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n\n if (codes.length > 0) {\n return codes\n }\n }\n\n if (typeof payload.code === 'string' && payload.code.trim().length > 0) {\n return [payload.code.trim()]\n }\n\n throw new Error('Missing payload field: codes')\n}","import type { CommerceClient, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\n\nimport {\n requireNumber,\n requireString,\n type AltazionModuleDefinition,\n type AltazionSuccessEventKind,\n} from '../altazion-engine'\n\nexport type AltazionStoresActionName = 'findByLocation' | 'findByPostalCode' | 'getStore'\n\nexport type StoresActionResult = StoreWithOpeningHours | StoreWithOpeningHours[]\n\nexport const storesModuleDefinition: AltazionModuleDefinition<'stores', AltazionStoresActionName, StoresActionResult> = {\n moduleName: 'stores',\n actionAttribute: 'hx-altazion-stores-action',\n payloadAttributes: {\n 'hx-altazion-stores-store-guid': 'storeGuid',\n 'hx-altazion-stores-latitude': 'latitude',\n 'hx-altazion-stores-longitude': 'longitude',\n 'hx-altazion-stores-radius-km': 'radiusKm',\n 'hx-altazion-stores-postal-code': 'postalCode',\n 'hx-altazion-stores-country-code': 'countryCode',\n },\n payloadAliases: {\n lat: 'latitude',\n lon: 'longitude',\n lng: 'longitude',\n radius: 'radiusKm',\n storeId: 'storeGuid',\n id: 'storeGuid',\n postal: 'postalCode',\n country: 'countryCode',\n },\n parseAction(actionValue: string): AltazionStoresActionName {\n switch (actionValue) {\n case 'findByLocation':\n case 'findByPostalCode':\n case 'getStore':\n return actionValue\n default:\n throw new Error(`Unsupported stores action: ${actionValue}`)\n }\n },\n execute(client: CommerceClient, action: AltazionStoresActionName, payload: Record<string, unknown>): Promise<StoresActionResult> {\n switch (action) {\n case 'findByLocation': {\n const latitude = requireNumber(payload.latitude, 'latitude')\n const longitude = requireNumber(payload.longitude, 'longitude')\n const countryCode = payload.countryCode === undefined\n ? 'FRA'\n : requireString(payload.countryCode, 'countryCode')\n return client.stores.findByLocation(latitude, longitude, countryCode)\n }\n case 'findByPostalCode': {\n const postalCode = requireString(payload.postalCode, 'postalCode')\n const countryCode = payload.countryCode === undefined\n ? 'FR'\n : requireString(payload.countryCode, 'countryCode')\n return client.stores.findByPostalCode(postalCode, countryCode)\n }\n case 'getStore':\n return client.stores.getStore(requireString(payload.storeGuid, 'storeGuid'))\n }\n },\n successEventKind(): AltazionSuccessEventKind {\n return 'loaded'\n },\n getResultEventSuffixes(action: AltazionStoresActionName): string[] {\n switch (action) {\n case 'getStore':\n return ['store-loaded']\n case 'findByLocation':\n case 'findByPostalCode':\n return ['stores-loaded']\n }\n },\n}","import type { CommerceClient } from '@altazion/commerce-sdk-core'\n\nimport {\n createAltazionExtension,\n type AltazionActionEventDetail,\n type AltazionActionErrorDetail,\n type AltazionExtensionHandle,\n type AltazionSuccessEventKind,\n} from './altazion-engine'\nimport {\n cartModuleDefinition,\n type AltazionCartActionName,\n} from './modules/cart'\nimport {\n sessionModuleDefinition,\n type AltazionSessionActionName,\n} from './modules/session'\nimport {\n marketingModuleDefinition,\n type AltazionMarketingActionName,\n} from './modules/marketing'\nimport {\n storesModuleDefinition,\n type AltazionStoresActionName,\n} from './modules/stores'\n\nexport type { AltazionCartActionName }\nexport type { AltazionMarketingActionName }\nexport type { AltazionSessionActionName }\nexport type { AltazionStoresActionName }\nexport type {\n AltazionActionEventDetail,\n AltazionActionErrorDetail,\n AltazionExtensionHandle,\n AltazionSuccessEventKind,\n}\n\nexport type AltazionCartEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'cart',\n AltazionCartActionName,\n TResult\n>\n\nexport type AltazionSessionEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'session',\n AltazionSessionActionName,\n TResult\n>\n\nexport type AltazionMarketingEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'marketing',\n AltazionMarketingActionName,\n TResult\n>\n\nexport type AltazionStoresEventDetail<TResult = unknown> = AltazionActionEventDetail<\n 'stores',\n AltazionStoresActionName,\n TResult\n>\n\n/**\n * Extension HTMX Altazion.\n *\n * - Ajoute les headers de contexte Altazion sur les requêtes HTMX\n * - Interprète les attributs `hx-altazion-cart-action`, `hx-altazion-session-action`,\n * `hx-altazion-marketing-action` et `hx-altazion-stores-action`\n * pour appeler le SDK core\n * - Émet des événements DOM `altazion:cart:*`, `altazion:session:*`,\n * `altazion:marketing:*` et `altazion:stores:*`\n * exploitables par HTMX\n */\nexport function registerAltazionExtension(client: CommerceClient): AltazionExtensionHandle {\n return createAltazionExtension(client, [\n cartModuleDefinition,\n sessionModuleDefinition,\n marketingModuleDefinition,\n storesModuleDefinition,\n ])\n}\n\nexport const registerAltazionAuthExtension = registerAltazionExtension\n","import type Handlebars from 'handlebars'\n\ntype HandlebarsInstance = typeof Handlebars\n\n/**\n * Formate un montant selon la locale et la devise.\n * Usage : {{formatPrice 19.99 \"EUR\" \"fr-FR\"}}\n * Si locale/currency sont omis, utilise les valeurs passées au registre.\n */\nexport function registerPriceHelpers(\n hbs: HandlebarsInstance,\n defaults: { locale: string; currency: string }\n): void {\n hbs.registerHelper(\n 'formatPrice',\n function (\n value: unknown,\n currency?: unknown,\n locale?: unknown\n ): string {\n const amount = typeof value === 'number' ? value : parseFloat(String(value))\n if (isNaN(amount)) return ''\n\n const resolvedCurrency =\n typeof currency === 'string' ? currency : defaults.currency\n const resolvedLocale =\n typeof locale === 'string' ? locale : defaults.locale\n\n return new Intl.NumberFormat(resolvedLocale, {\n style: 'currency',\n currency: resolvedCurrency,\n }).format(amount)\n }\n )\n\n hbs.registerHelper(\n 'formatPriceCompact',\n function (value: unknown, currency?: unknown, locale?: unknown): string {\n const amount = typeof value === 'number' ? value : parseFloat(String(value))\n if (isNaN(amount)) return ''\n\n const resolvedCurrency =\n typeof currency === 'string' ? currency : defaults.currency\n const resolvedLocale =\n typeof locale === 'string' ? locale : defaults.locale\n\n return new Intl.NumberFormat(resolvedLocale, {\n style: 'currency',\n currency: resolvedCurrency,\n notation: 'compact',\n }).format(amount)\n }\n )\n\n hbs.registerHelper(\n 'discountPercent',\n function (original: unknown, discounted: unknown): string {\n const orig = typeof original === 'number' ? original : parseFloat(String(original))\n const disc = typeof discounted === 'number' ? discounted : parseFloat(String(discounted))\n if (isNaN(orig) || isNaN(disc) || orig === 0) return ''\n const pct = Math.round(((orig - disc) / orig) * 100)\n return `-${pct}%`\n }\n )\n}\n","import type Handlebars from 'handlebars'\n\ntype HandlebarsInstance = typeof Handlebars\n\n/**\n * Helpers Handlebars liés aux produits.\n *\n * Usage :\n * {{productUrl reference}}\n * {{thumbnailUrl imageUrl 400}}\n * {{#if (isAvailable availability)}} ... {{/if}}\n */\nexport function registerProductHelpers(hbs: HandlebarsInstance, siteUrl: string): void {\n // URL de la fiche produit côté site vitrine\n hbs.registerHelper('productUrl', function (reference: unknown): string {\n if (typeof reference !== 'string' && typeof reference !== 'number') return ''\n const base = siteUrl.replace(/\\/$/, '')\n return `${base}/product/${encodeURIComponent(String(reference))}`\n })\n\n // Transforme une URL d'image en URL redimensionnée si le serveur le supporte\n // Pattern attendu : /media/images/{id} → /media/images/{id}?w={size}\n hbs.registerHelper('thumbnailUrl', function (imageUrl: unknown, size?: unknown): string {\n if (typeof imageUrl !== 'string' || !imageUrl) return ''\n const resolvedSize = typeof size === 'number' ? size : 300\n const separator = imageUrl.includes('?') ? '&' : '?'\n return `${imageUrl}${separator}w=${resolvedSize}`\n })\n\n // Retourne true si le produit est disponible (availability > 0 ou pas de stock géré)\n hbs.registerHelper('isAvailable', function (availability: unknown): boolean {\n if (availability === null || availability === undefined) return true\n if (typeof availability === 'boolean') return availability\n if (typeof availability === 'number') return availability > 0\n if (typeof availability === 'string') {\n const lower = availability.toLowerCase()\n return lower === 'available' || lower === 'instock'\n }\n return false\n })\n\n // Helper ifCond simple pour les comparaisons dans les templates\n hbs.registerHelper(\n 'ifCond',\n function (\n this: unknown,\n v1: unknown,\n operator: string,\n v2: unknown,\n options: Handlebars.HelperOptions\n ): string {\n let result = false\n switch (operator) {\n case '==': result = v1 == v2; break\n case '===': result = v1 === v2; break\n case '!=': result = v1 != v2; break\n case '!==': result = v1 !== v2; break\n case '>': result = (v1 as number) > (v2 as number); break\n case '<': result = (v1 as number) < (v2 as number); break\n case '>=': result = (v1 as number) >= (v2 as number); break\n case '<=': result = (v1 as number) <= (v2 as number); break\n default: result = false\n }\n return result ? options.fn(this as object) : options.inverse(this as object)\n }\n )\n}\n","import type Handlebars from 'handlebars'\nimport type { Cart, CartContent } from '@altazion/commerce-sdk-core'\n\ntype HandlebarsInstance = typeof Handlebars\n\n/**\n * Helpers Handlebars liés au panier.\n *\n * Nécessite un getter réactif sur le panier actuel.\n * Usage :\n * Nombre d'articles : {{cartCount}}\n * Total : {{cartTotal}}\n * {{#if cartHasItems}} ... {{/if}}\n */\nexport function registerCartHelpers(\n hbs: HandlebarsInstance,\n getCart: () => Cart | null,\n defaults: { locale: string; currency: string }\n): void {\n hbs.registerHelper('cartCount', function (): number {\n const cart = getCart()\n if (!cart) return 0\n return cart.totalQuantity\n })\n\n hbs.registerHelper('cartTotal', function (): string {\n const cart = getCart()\n if (!cart) return ''\n return new Intl.NumberFormat(defaults.locale, {\n style: 'currency',\n currency: defaults.currency,\n }).format(cart.totalAmountWithTax)\n })\n\n hbs.registerHelper('cartTotalRaw', function (): number {\n const cart = getCart()\n return cart?.totalAmountWithTax ?? 0\n })\n\n hbs.registerHelper('cartHasItems', function (this: unknown, options: Handlebars.HelperOptions): string {\n const cart = getCart()\n const hasItems = cart ? cart.totalQuantity > 0 : false\n return hasItems ? options.fn(this as object) : options.inverse(this as object)\n })\n\n hbs.registerHelper('cartLineCount', function (): number {\n const cart = getCart()\n if (!cart?.content) return 0\n return cart.content.reduce((sum: number, group: CartContent) => sum + (group.lines?.length ?? 0), 0)\n })\n}\n","import type { Cart, MarketingItem, SessionInfo, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\nimport type Handlebars from 'handlebars'\n\nexport interface AltazionDeclarativeViewModel {\n cart: Cart | null\n session: SessionInfo | null\n store: StoreWithOpeningHours | null\n stores: StoreWithOpeningHours[]\n marketingItem: MarketingItem | null\n marketingItems: MarketingItem[]\n slots: Record<string, unknown>\n}\n\nexport interface AltazionDeclarativeRendererHandle {\n update<K extends keyof AltazionDeclarativeViewModel>(\n key: K,\n value: AltazionDeclarativeViewModel[K]\n ): void\n updateSlot(name: string, value: unknown): void\n render(): void\n dispose(): void\n}\n\ntype HandlebarsRuntime = typeof Handlebars\ntype ViewModelKey = keyof AltazionDeclarativeViewModel\ntype DataSourceReference =\n | { kind: 'state', key: ViewModelKey }\n | { kind: 'slot', key: string }\n\nconst DATA_SOURCE_ATTRIBUTE = 'hx-altazion-data-source'\nconst DATA_STATUS_ATTRIBUTE = 'hx-altazion-data-status'\nconst RENDER_TEMPLATE_ATTRIBUTE = 'hx-render-template'\n\nconst DATA_SOURCE_ALIASES: Record<string, ViewModelKey> = {\n cart: 'cart',\n session: 'session',\n store: 'store',\n stores: 'stores',\n 'marketing-item': 'marketingItem',\n 'marketing-items': 'marketingItems',\n}\n\nexport function createAltazionDeclarativeRenderer(\n handlebars?: HandlebarsRuntime\n): AltazionDeclarativeRendererHandle {\n const state: AltazionDeclarativeViewModel = {\n cart: null,\n session: null,\n store: null,\n stores: [],\n marketingItem: null,\n marketingItems: [],\n slots: {},\n }\n\n const templateCache = new Map<string, (context: AltazionDeclarativeViewModel) => string>()\n\n const render = (): void => {\n if (typeof document === 'undefined') {\n return\n }\n\n for (const element of document.querySelectorAll(`[${DATA_SOURCE_ATTRIBUTE}]`)) {\n const rawSource = element.getAttribute(DATA_SOURCE_ATTRIBUTE)\n const source = resolveDataSource(rawSource)\n if (!source) {\n continue\n }\n\n const rawStatus = element.getAttribute(DATA_STATUS_ATTRIBUTE)\n const sourceValue = resolveSourceValue(state, source)\n const isVisible = matchesStatus(rawStatus, sourceValue)\n applyVisibility(element, isVisible)\n renderElementTemplate(element, isVisible, state, sourceValue, handlebars, templateCache)\n }\n }\n\n return {\n update(key, value): void {\n state[key] = value\n render()\n },\n updateSlot(name, value): void {\n state.slots[name] = value\n render()\n },\n render,\n dispose(): void {\n templateCache.clear()\n },\n }\n}\n\nfunction matchesStatus(status: string | null, value: unknown): boolean {\n if (Array.isArray(value)) {\n switch (status) {\n case 'empty':\n return value.length === 0\n case 'not-empty':\n return value.length > 0\n default:\n return true\n }\n }\n\n switch (status) {\n case 'null':\n return value == null\n case 'not-null':\n return value != null\n default:\n return true\n }\n}\n\nfunction resolveDataSource(source: string | null): DataSourceReference | null {\n if (!source) {\n return null\n }\n\n if (source.startsWith('slot:')) {\n const slotKey = source.slice(5).trim()\n return slotKey.length > 0 ? { kind: 'slot', key: slotKey } : null\n }\n\n const resolvedKey = DATA_SOURCE_ALIASES[source]\n return resolvedKey ? { kind: 'state', key: resolvedKey } : null\n}\n\nfunction resolveSourceValue(\n state: AltazionDeclarativeViewModel,\n source: DataSourceReference\n): unknown {\n if (source.kind === 'slot') {\n return state.slots[source.key] ?? null\n }\n\n return state[source.key]\n}\n\nfunction applyVisibility(element: Element, isVisible: boolean): void {\n element.setAttribute('aria-hidden', isVisible ? 'false' : 'true')\n\n if (element instanceof HTMLElement) {\n element.hidden = !isVisible\n } else if (isVisible) {\n element.removeAttribute('hidden')\n } else {\n element.setAttribute('hidden', '')\n }\n}\n\nfunction renderElementTemplate(\n element: Element,\n isVisible: boolean,\n state: AltazionDeclarativeViewModel,\n sourceValue: unknown,\n handlebars: HandlebarsRuntime | undefined,\n templateCache: Map<string, (context: AltazionDeclarativeViewModel) => string>\n): void {\n if (!isVisible || !element.hasAttribute(RENDER_TEMPLATE_ATTRIBUTE) || !handlebars) {\n return\n }\n\n const templateId = element.getAttribute(RENDER_TEMPLATE_ATTRIBUTE)\n if (!templateId) {\n return\n }\n\n const template = resolveTemplate(templateId, handlebars, templateCache)\n if (!template) {\n return\n }\n\n element.innerHTML = template({\n ...state,\n slot: sourceValue,\n } as AltazionDeclarativeViewModel)\n}\n\nfunction resolveTemplate(\n templateId: string,\n handlebars: HandlebarsRuntime,\n templateCache: Map<string, (context: AltazionDeclarativeViewModel) => string>\n): ((context: AltazionDeclarativeViewModel) => string) | null {\n const cached = templateCache.get(templateId)\n if (cached) {\n return cached\n }\n\n if (typeof document === 'undefined') {\n return null\n }\n\n const templateElement = document.getElementById(templateId)\n if (!templateElement) {\n console.warn(`[AltazionHtmx] Template not found: ${templateId}`)\n return null\n }\n\n const compiled = handlebars.compile(templateElement.innerHTML)\n templateCache.set(templateId, compiled)\n return compiled\n}","import type { CommerceClient, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\nimport type Handlebars from 'handlebars'\n\nconst DIALOG_SELECTOR = '[data-hz-store-picker]'\nconst TEMPLATE_ID = 'hz-store-picker-store-tmpl'\nconst RESULTS_SELECTOR = '[data-store-picker-results]'\nconst HINT_SELECTOR = '[data-store-picker-hint]'\nconst FORM_SELECTOR = '[data-store-picker-form]'\nconst INPUT_SELECTOR = '[data-store-picker-input]'\n\ntype HandlebarsRuntime = typeof Handlebars\n\n/**\n * Initialise le comportement du dialog de choix de magasin.\n *\n * Écoute les actions :\n * - `open-store-picker` — ouvre le dialog (showModal)\n * - `close-store-picker` — ferme le dialog\n * - `store-picker-geolocate` — géolocalisation + recherche\n * - `select-store` — associe le magasin à la session puis recharge la page\n *\n * La recherche par code postal est déclenchée par la soumission du formulaire\n * `[data-store-picker-form]`.\n *\n * Les résultats sont rendus via le template Handlebars contenu dans\n * `<template id=\"hz-store-picker-store-tmpl\">`. Si Handlebars n'est pas fourni\n * ou que le template est absent, les magasins sont rendus avec un fallback HTML minimal.\n *\n * @returns Fonction de nettoyage (dispose) à appeler pour retirer les listeners.\n */\nexport function initStorePicker(client: CommerceClient, handlebars?: HandlebarsRuntime): () => void {\n if (typeof document === 'undefined') return () => { /* noop SSR */ }\n\n // ── Compilation du template Handlebars ──────────────────────────────────\n let renderStore: ((store: StoreWithOpeningHours) => string) | null = null\n\n const templateEl = document.getElementById(TEMPLATE_ID) as HTMLTemplateElement | null\n if (templateEl && handlebars) {\n try {\n const tplSource = templateEl.innerHTML\n const compiled = handlebars.compile(tplSource)\n renderStore = (store) => compiled(store)\n } catch {\n /* template invalide — fallback */\n }\n }\n\n if (!renderStore) {\n renderStore = fallbackRender\n }\n\n // ── Helpers ─────────────────────────────────────────────────────────────\n function getDialog(): HTMLDialogElement | null {\n return document.querySelector<HTMLDialogElement>(DIALOG_SELECTOR)\n }\n\n function openDialog(): void {\n getDialog()?.showModal()\n }\n\n function closeDialog(): void {\n getDialog()?.close()\n }\n\n function getConfig(): { countryCode: string; feature: string } {\n const dialog = getDialog()\n return {\n countryCode: dialog?.dataset.storePickerCountry ?? 'FRA',\n feature: dialog?.dataset.storePickerFeature ?? 'InStoreOrder',\n }\n }\n\n function renderResults(stores: StoreWithOpeningHours[]): void {\n const dialog = getDialog()\n if (!dialog) return\n\n const list = dialog.querySelector<HTMLElement>(RESULTS_SELECTOR)\n const hint = dialog.querySelector<HTMLElement>(HINT_SELECTOR)\n\n if (!list) return\n\n if (stores.length === 0) {\n list.innerHTML = ''\n list.hidden = true\n if (hint) {\n hint.textContent = 'Aucun magasin trouvé dans ce secteur.'\n hint.hidden = false\n }\n return\n }\n\n list.innerHTML = stores.map(s => renderStore!(s)).join('')\n list.hidden = false\n if (hint) hint.hidden = true\n }\n\n function showSearching(): void {\n const dialog = getDialog()\n if (!dialog) return\n const hint = dialog.querySelector<HTMLElement>(HINT_SELECTOR)\n const list = dialog.querySelector<HTMLElement>(RESULTS_SELECTOR)\n if (hint) { hint.textContent = 'Recherche en cours…'; hint.hidden = false }\n if (list) list.hidden = true\n }\n\n function showError(message: string): void {\n const dialog = getDialog()\n if (!dialog) return\n const hint = dialog.querySelector<HTMLElement>(HINT_SELECTOR)\n if (hint) { hint.textContent = message; hint.hidden = false }\n }\n\n // ── Handlers ─────────────────────────────────────────────────────────────\n async function handlePostalCodeSearch(postalCode: string): Promise<void> {\n showSearching()\n const { countryCode, feature } = getConfig()\n try {\n const stores = await client.stores.findByPostalCode(postalCode, countryCode, 10, feature)\n renderResults(stores)\n } catch {\n showError('La recherche a échoué. Vérifiez votre code postal et réessayez.')\n }\n }\n\n async function handleGeolocate(): Promise<void> {\n if (!navigator.geolocation) {\n showError('La géolocalisation n\\'est pas disponible sur cet appareil.')\n return\n }\n showSearching()\n const { countryCode, feature } = getConfig()\n navigator.geolocation.getCurrentPosition(\n async (position) => {\n try {\n const stores = await client.stores.findByLocation(\n position.coords.latitude,\n position.coords.longitude,\n countryCode,\n 10,\n feature\n )\n renderResults(stores)\n } catch {\n showError('La recherche a échoué. Veuillez réessayer.')\n }\n },\n () => {\n showError('Impossible d\\'obtenir votre position. Vérifiez les autorisations de géolocalisation.')\n }\n )\n }\n\n async function handleSelectStore(storeGuid: string): Promise<void> {\n try {\n await client.session.associateStore(storeGuid)\n closeDialog()\n document.dispatchEvent(new CustomEvent('altazion:stores:store-associated', {\n bubbles: true,\n detail: { storeGuid },\n }))\n window.location.reload()\n } catch {\n showError('Impossible de sélectionner ce magasin. Veuillez réessayer.')\n }\n }\n\n // ── Listener global sur document ─────────────────────────────────────────\n function handleClick(event: Event): void {\n const target = (event.target as Element).closest('[data-action]') as HTMLElement | null\n if (!target) return\n\n const action = target.dataset.action\n switch (action) {\n case 'open-store-picker':\n openDialog()\n break\n case 'close-store-picker':\n closeDialog()\n break\n case 'store-picker-geolocate':\n void handleGeolocate()\n break\n case 'select-store': {\n const guid = target.dataset.storeGuid\n if (guid) void handleSelectStore(guid)\n break\n }\n }\n }\n\n function handleFormSubmit(event: Event): void {\n const form = (event.target as Element).closest(FORM_SELECTOR)\n if (!form) return\n event.preventDefault()\n const input = form.querySelector<HTMLInputElement>(INPUT_SELECTOR)\n const postalCode = input?.value.trim()\n if (postalCode) void handlePostalCodeSearch(postalCode)\n }\n\n document.addEventListener('click', handleClick)\n document.addEventListener('submit', handleFormSubmit)\n\n return () => {\n document.removeEventListener('click', handleClick)\n document.removeEventListener('submit', handleFormSubmit)\n }\n}\n\nfunction fallbackRender(store: StoreWithOpeningHours): string {\n const name = store.label ?? store.code ?? 'Magasin'\n const address = [store.streetAddress, store.postalCode, store.city].filter(Boolean).join(', ')\n return `<li class=\"hz-store-picker__item\">` +\n `<div class=\"hz-store-picker__item-info\">` +\n `<strong class=\"hz-store-picker__item-name\">${escHtml(name)}</strong>` +\n (address ? `<address class=\"hz-store-picker__item-address\">${escHtml(address)}</address>` : '') +\n `</div>` +\n `<button class=\"hz-store-picker__item-select\" type=\"button\" data-action=\"select-store\" data-store-guid=\"${escHtml(store.guid)}\">` +\n `Choisir ce magasin` +\n `</button>` +\n `</li>`\n}\n\nfunction escHtml(str: string): string {\n return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"')\n}\n","export default \"<article class=\\\"altz-product-card{{#unless (isAvailable availability)}} altz-product-card--unavailable{{/unless}}\\\">\\n {{#if imageUrl}}\\n <a href=\\\"{{productUrl reference}}\\\" class=\\\"altz-product-card__image-link\\\" aria-label=\\\"{{name}}\\\">\\n <img\\n src=\\\"{{thumbnailUrl imageUrl 400}}\\\"\\n alt=\\\"{{name}}\\\"\\n class=\\\"altz-product-card__image\\\"\\n loading=\\\"lazy\\\"\\n width=\\\"400\\\"\\n />\\n </a>\\n {{/if}}\\n\\n <div class=\\\"altz-product-card__body\\\">\\n <a href=\\\"{{productUrl reference}}\\\" class=\\\"altz-product-card__title\\\">\\n {{name}}\\n </a>\\n\\n <div class=\\\"altz-product-card__pricing\\\">\\n {{#if discount}}\\n <span class=\\\"altz-product-card__price altz-product-card__price--discounted\\\">\\n {{formatPrice price}}\\n </span>\\n <span class=\\\"altz-product-card__price altz-product-card__price--original\\\">\\n {{formatPrice originalPrice}}\\n </span>\\n <span class=\\\"altz-product-card__discount-badge\\\">\\n {{discountPercent originalPrice price}}\\n </span>\\n {{else}}\\n <span class=\\\"altz-product-card__price\\\">\\n {{formatPrice price}}\\n </span>\\n {{/if}}\\n </div>\\n\\n {{#unless (isAvailable availability)}}\\n <p class=\\\"altz-product-card__unavailable\\\">{{unavailableLabel}}</p>\\n {{/unless}}\\n\\n {{#if (isAvailable availability)}}\\n <button\\n class=\\\"altz-product-card__add-to-cart\\\"\\n hx-ext=\\\"altazion\\\"\\n hx-altazion-cart-action=\\\"addItem\\\"\\n hx-altazion-cart-reference=\\\"{{reference}}\\\"\\n hx-altazion-cart-quantity=\\\"1\\\"\\n hx-altazion-refresh=\\\"#altz-cart-mini\\\"\\n hx-indicator=\\\".altz-spinner\\\"\\n >\\n {{addToCartLabel}}\\n </button>\\n {{/if}}\\n </div>\\n</article>\\n\"","export default \"<div id=\\\"altz-cart-mini\\\" class=\\\"altz-cart-mini\\\">\\n <div class=\\\"altz-cart-mini__header\\\">\\n <span class=\\\"altz-cart-mini__label\\\">{{cartLabel}}</span>\\n <span class=\\\"altz-cart-mini__count\\\">{{cartCount}}</span>\\n </div>\\n\\n {{#cartHasItems}}\\n <ul class=\\\"altz-cart-mini__lines\\\">\\n {{#each lines}}\\n <li class=\\\"altz-cart-mini__line\\\">\\n <span class=\\\"altz-cart-mini__line-name\\\">{{this.productName}}</span>\\n <span class=\\\"altz-cart-mini__line-qty\\\">× {{this.quantity}}</span>\\n <span class=\\\"altz-cart-mini__line-price\\\">{{formatPrice this.unitPriceWithTax}}</span>\\n </li>\\n {{/each}}\\n </ul>\\n\\n <div class=\\\"altz-cart-mini__total\\\">\\n <span>{{totalLabel}}</span>\\n <strong>{{cartTotal}}</strong>\\n </div>\\n\\n <a href=\\\"{{cartUrl}}\\\" class=\\\"altz-cart-mini__cta\\\">\\n {{viewCartLabel}}\\n </a>\\n {{/cartHasItems}}\\n\\n {{^cartHasItems}}\\n <p class=\\\"altz-cart-mini__empty\\\">{{emptyLabel}}</p>\\n {{/cartHasItems}}\\n</div>\\n\"","export default \"<section class=\\\"altz-product-list\\\">\\n {{#if title}}\\n <h2 class=\\\"altz-product-list__title\\\">{{title}}</h2>\\n {{/if}}\\n\\n {{#if products.length}}\\n <ul class=\\\"altz-product-list__grid\\\" role=\\\"list\\\">\\n {{#each products}}\\n <li class=\\\"altz-product-list__item\\\">\\n <article class=\\\"altz-product-card{{#unless (isAvailable this.availability)}} altz-product-card--unavailable{{/unless}}\\\">\\n {{#if this.imageUrl}}\\n <a href=\\\"{{productUrl this.reference}}\\\" class=\\\"altz-product-card__image-link\\\" aria-label=\\\"{{this.name}}\\\">\\n <img\\n src=\\\"{{thumbnailUrl this.imageUrl 300}}\\\"\\n alt=\\\"{{this.name}}\\\"\\n class=\\\"altz-product-card__image\\\"\\n loading=\\\"lazy\\\"\\n width=\\\"300\\\"\\n />\\n </a>\\n {{/if}}\\n\\n <div class=\\\"altz-product-card__body\\\">\\n <a href=\\\"{{productUrl this.reference}}\\\" class=\\\"altz-product-card__title\\\">\\n {{this.name}}\\n </a>\\n\\n <div class=\\\"altz-product-card__pricing\\\">\\n {{#if this.discount}}\\n <span class=\\\"altz-product-card__price altz-product-card__price--discounted\\\">\\n {{formatPrice this.price}}\\n </span>\\n <span class=\\\"altz-product-card__price altz-product-card__price--original\\\">\\n {{formatPrice this.originalPrice}}\\n </span>\\n <span class=\\\"altz-product-card__discount-badge\\\">\\n {{discountPercent this.originalPrice this.price}}\\n </span>\\n {{else}}\\n <span class=\\\"altz-product-card__price\\\">\\n {{formatPrice this.price}}\\n </span>\\n {{/if}}\\n </div>\\n\\n {{#if (isAvailable this.availability)}}\\n <button\\n class=\\\"altz-product-card__add-to-cart\\\"\\n hx-ext=\\\"altazion\\\"\\n hx-altazion-cart-action=\\\"addItem\\\"\\n hx-altazion-cart-reference=\\\"{{this.reference}}\\\"\\n hx-altazion-cart-quantity=\\\"1\\\"\\n hx-altazion-refresh=\\\"#altz-cart-mini\\\"\\n hx-indicator=\\\".altz-spinner\\\"\\n >\\n {{../addToCartLabel}}\\n </button>\\n {{/if}}\\n </div>\\n </article>\\n </li>\\n {{/each}}\\n </ul>\\n {{else}}\\n <p class=\\\"altz-product-list__empty\\\">{{emptyLabel}}</p>\\n {{/if}}\\n</section>\\n\"","import type { CommerceClient, Cart, ConnectivityStatus, SessionInfo, StoreWithOpeningHours } from '@altazion/commerce-sdk-core'\nimport type Handlebars from 'handlebars'\n\nimport {\n registerAltazionExtension,\n type AltazionActionEventDetail,\n type AltazionCartEventDetail,\n type AltazionExtensionHandle,\n type AltazionMarketingEventDetail,\n type AltazionSessionEventDetail,\n type AltazionStoresEventDetail,\n} from './extensions/altazion-auth'\nimport { registerPriceHelpers } from './helpers/price'\nimport { registerProductHelpers } from './helpers/product'\nimport { registerCartHelpers } from './helpers/cart'\nimport { createAltazionDeclarativeRenderer } from './rendering/declarative-renderer'\nimport { initStorePicker } from './modules/store-picker'\n\n// Templates pré-compilés importés en tant que chaînes brutes\nimport productCardTemplate from './templates/product-card.hbs?raw'\nimport cartMiniTemplate from './templates/cart-mini.hbs?raw'\nimport productListTemplate from './templates/product-list.hbs?raw'\n\nexport type { Cart }\n\ntype SelectorInput = string | string[]\n\nexport interface AltazionTerminalModeConfig {\n /** Zones interactives à masquer en mode hors ligne. */\n interactiveSelectors?: SelectorInput\n /** Zones passives à afficher en mode hors ligne. */\n offlineScreenSelectors?: SelectorInput\n}\n\nexport interface AltazionConnectivityEventDetail {\n status: ConnectivityStatus\n isOnline: boolean\n isOffline: boolean\n root: Element\n}\n\nexport interface AltazionHtmxConfig {\n /** Instance CommerceClient déjà initialisée */\n client: CommerceClient\n /**\n * Instance Handlebars (global ou importée).\n * Si omis, les helpers ne sont pas enregistrés.\n */\n handlebars?: typeof Handlebars\n /**\n * Sélecteur CSS de l'élément DOM à basculer avec la classe `altz-offline`\n * lorsque la connectivité est perdue/restaurée.\n * @default 'body'\n */\n offlineSelector?: string\n /** Configuration UI du mode hors ligne borne. */\n terminalMode?: AltazionTerminalModeConfig\n}\n\nexport interface AltazionHtmxInstance {\n /** Templates Handlebars compilés prêts à l'emploi */\n templates: {\n productCard: HandlebarsTemplateDelegate\n cartMini: HandlebarsTemplateDelegate\n productList: HandlebarsTemplateDelegate\n }\n /** Détruit les listeners et libère les ressources */\n dispose(): void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype HandlebarsTemplateDelegate = (context?: any) => string\n\n/**\n * Initialise le SDK HTMX Altazion.\n *\n * - Enregistre l'extension HTMX (headers contexte) si htmx est présent\n * - Enregistre les helpers Handlebars (prix, produits, panier) si hbs est fourni\n * - Active l'indicateur d'état offline sur le DOM\n * - Retourne les templates compilés\n *\n * @example\n * ```ts\n * import Handlebars from 'handlebars'\n * const sdk = init({ client, handlebars: Handlebars })\n * const html = sdk.templates.productCard(product)\n * document.getElementById('product')!.innerHTML = html\n * ```\n */\nexport function initAltazionHtmx(config: AltazionHtmxConfig): AltazionHtmxInstance {\n const {\n client,\n handlebars,\n offlineSelector = 'body',\n terminalMode,\n } = config\n\n // 1. Extension HTMX — headers de contexte + actions panier déclaratives\n const extensionHandle: AltazionExtensionHandle = registerAltazionExtension(client)\n\n // 2. HTMX config globale — transmettre les cookies sur les requêtes XHR HTMX\n if (typeof window !== 'undefined' && window.htmx) {\n // @ts-expect-error — htmx.config n'est pas dans les types window\n window.htmx.config = window.htmx.config ?? {}\n // @ts-expect-error\n window.htmx.config.withCredentials = true\n }\n\n // 3. Helpers Handlebars\n const defaults = {\n locale: client.context.locale,\n currency: client.context.currency,\n }\n\n const handlebarsRuntime = handlebars\n ?? (typeof window !== 'undefined'\n ? (window as Window & { Handlebars?: typeof Handlebars }).Handlebars\n : undefined)\n\n const declarativeRenderer = createAltazionDeclarativeRenderer(handlebarsRuntime)\n const syncSlotFromEvent = (detail: AltazionActionEventDetail): void => {\n const slotName = detail.element.getAttribute('hx-altazion-data-slot')?.trim()\n if (!slotName) {\n return\n }\n\n declarativeRenderer.updateSlot(slotName, detail.result ?? null)\n }\n\n // Getter réactif sur le panier actuel utilisé par les helpers Handlebars.\n let currentCart: Cart | null = null\n const getCart = (): Cart | null => currentCart\n\n const syncCartFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionCartEventDetail<Cart>>\n if (customEvent.detail.result) {\n currentCart = customEvent.detail.result\n declarativeRenderer.update('cart', currentCart)\n }\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncSessionFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionSessionEventDetail<SessionInfo>>\n declarativeRenderer.update('session', customEvent.detail.result ?? null)\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncStoreFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionStoresEventDetail<StoreWithOpeningHours>>\n declarativeRenderer.update('store', customEvent.detail.result ?? null)\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncStoresFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionStoresEventDetail<StoreWithOpeningHours[]>>\n declarativeRenderer.update('stores', Array.isArray(customEvent.detail.result) ? customEvent.detail.result : [])\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncMarketingItemFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionMarketingEventDetail>\n declarativeRenderer.update('marketingItem', Array.isArray(customEvent.detail.result) ? null : customEvent.detail.result ?? null)\n syncSlotFromEvent(customEvent.detail)\n }\n\n const syncMarketingItemsFromEvent = (event: Event): void => {\n const customEvent = event as CustomEvent<AltazionMarketingEventDetail>\n declarativeRenderer.update('marketingItems', Array.isArray(customEvent.detail.result) ? customEvent.detail.result : [])\n syncSlotFromEvent(customEvent.detail)\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('altazion:cart:loaded', syncCartFromEvent)\n document.addEventListener('altazion:cart:updated', syncCartFromEvent)\n document.addEventListener('altazion:session:loaded', syncSessionFromEvent)\n document.addEventListener('altazion:stores:store-loaded', syncStoreFromEvent)\n document.addEventListener('altazion:stores:stores-loaded', syncStoresFromEvent)\n document.addEventListener('altazion:marketing:item-loaded', syncMarketingItemFromEvent)\n document.addEventListener('altazion:marketing:items-loaded', syncMarketingItemsFromEvent)\n }\n\n void client.cart.getCart()\n .then((cart: Cart) => {\n currentCart = cart\n declarativeRenderer.update('cart', cart)\n })\n .catch(() => { /* panier non disponible au chargement */ })\n\n if (handlebars) {\n registerPriceHelpers(handlebars, defaults)\n registerProductHelpers(handlebars, client.context.siteUrl ?? '')\n registerCartHelpers(handlebars, getCart, defaults)\n }\n\n declarativeRenderer.render()\n\n // 4. Store picker\n const disposeStorePicker = initStorePicker(client, handlebarsRuntime)\n\n // 5. Indicateur offline DOM + mode borne\n const offlineEl = typeof document !== 'undefined'\n ? document.querySelector(offlineSelector) ?? document.body\n : null\n\n let lastConnectivityStatus: ConnectivityStatus | null = null\n\n const updateOfflineClass = (): void => {\n if (!offlineEl) {\n return\n }\n\n const status: ConnectivityStatus = client.isOffline ? 'offline' : 'online'\n const isOffline = status === 'offline'\n\n offlineEl.classList.toggle('altz-offline', isOffline)\n offlineEl.classList.toggle('altz-terminal-offline', isOffline)\n offlineEl.classList.toggle('altz-terminal-online', !isOffline)\n offlineEl.setAttribute('data-altazion-terminal-state', status)\n\n updateManagedVisibility(resolveManagedElements(terminalMode?.interactiveSelectors), isOffline, 'altz-terminal-interactive-hidden')\n updateManagedVisibility(resolveManagedElements(terminalMode?.offlineScreenSelectors), !isOffline, 'altz-terminal-offline-screen-hidden')\n\n if (lastConnectivityStatus === status) {\n return\n }\n\n lastConnectivityStatus = status\n dispatchConnectivityEvent(offlineEl, 'altazion:connectivity:changed', status)\n dispatchConnectivityEvent(offlineEl, isOffline ? 'altazion:offline' : 'altazion:online', status)\n }\n\n // Synchronisation initiale\n updateOfflineClass()\n\n // Abonnement ConnectivityManager — retourne la fonction de désabonnement\n const unsubscribeConnectivity = client.connectivity?.subscribe(() => updateOfflineClass())\n\n // 5. Templates compilés (retournés pour usage dans le code applicatif)\n const noHbs = (): HandlebarsTemplateDelegate =>\n () => '<!-- handlebars non initialisé dans @altazion/commerce-sdk-htmx -->'\n\n const templates = handlebars\n ? {\n productCard: handlebars.compile(productCardTemplate),\n cartMini: handlebars.compile(cartMiniTemplate),\n productList: handlebars.compile(productListTemplate),\n }\n : {\n productCard: noHbs(),\n cartMini: noHbs(),\n productList: noHbs(),\n }\n\n return {\n templates,\n dispose(): void {\n extensionHandle.dispose()\n if (typeof document !== 'undefined') {\n document.removeEventListener('altazion:cart:loaded', syncCartFromEvent)\n document.removeEventListener('altazion:cart:updated', syncCartFromEvent)\n document.removeEventListener('altazion:session:loaded', syncSessionFromEvent)\n document.removeEventListener('altazion:stores:store-loaded', syncStoreFromEvent)\n document.removeEventListener('altazion:stores:stores-loaded', syncStoresFromEvent)\n document.removeEventListener('altazion:marketing:item-loaded', syncMarketingItemFromEvent)\n document.removeEventListener('altazion:marketing:items-loaded', syncMarketingItemsFromEvent)\n }\n declarativeRenderer.dispose()\n disposeStorePicker()\n unsubscribeConnectivity?.()\n },\n }\n}\n\nexport const init = initAltazionHtmx\n\nfunction resolveManagedElements(selectorInput?: SelectorInput): Element[] {\n if (typeof document === 'undefined' || !selectorInput) {\n return []\n }\n\n const selectors = Array.isArray(selectorInput) ? selectorInput : [selectorInput]\n const elements = new Set<Element>()\n\n for (const selector of selectors) {\n if (!selector.trim()) {\n continue\n }\n\n try {\n for (const element of document.querySelectorAll(selector)) {\n elements.add(element)\n }\n } catch {\n // Sélecteur invalide : on ignore silencieusement.\n }\n }\n\n return [...elements]\n}\n\nfunction updateManagedVisibility(elements: Element[], hidden: boolean, hiddenClassName: string): void {\n for (const element of elements) {\n element.classList.toggle(hiddenClassName, hidden)\n element.setAttribute('aria-hidden', hidden ? 'true' : 'false')\n\n if (element instanceof HTMLElement) {\n element.hidden = hidden\n } else if (hidden) {\n element.setAttribute('hidden', '')\n } else {\n element.removeAttribute('hidden')\n }\n }\n}\n\nfunction dispatchConnectivityEvent(\n root: Element,\n eventName: string,\n status: ConnectivityStatus\n): void {\n const detail: AltazionConnectivityEventDetail = {\n status,\n isOnline: status === 'online',\n isOffline: status === 'offline',\n root,\n }\n\n root.dispatchEvent(new CustomEvent<AltazionConnectivityEventDetail>(eventName, {\n bubbles: true,\n detail,\n }))\n}\n\n// Re-exports helpers pour usage à la carte\nexport { registerPriceHelpers } from './helpers/price'\nexport { registerProductHelpers } from './helpers/product'\nexport { registerCartHelpers } from './helpers/cart'\nexport {\n registerAltazionExtension,\n registerAltazionAuthExtension,\n} from './extensions/altazion-auth'\nexport type {\n AltazionActionEventDetail,\n AltazionActionErrorDetail,\n AltazionCartActionName,\n AltazionCartEventDetail,\n AltazionExtensionHandle,\n AltazionMarketingActionName,\n AltazionMarketingEventDetail,\n AltazionSessionActionName,\n AltazionSessionEventDetail,\n AltazionStoresActionName,\n AltazionStoresEventDetail,\n AltazionSuccessEventKind,\n} from './extensions/altazion-auth'\n"],"names":["AltazionApiError","OfflineError","_a"],"mappings":"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"}
|