@zenky/storefront-vue 0.10.10 → 0.10.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +1 -1
  3. package/dist/auth/index.d.ts +14 -0
  4. package/dist/auth/index.js +4 -0
  5. package/dist/auth/index.js.map +1 -0
  6. package/dist/cart/index.d.ts +3 -28
  7. package/dist/cart/index.js +8 -6
  8. package/dist/{chunk-4UMDIBW5.js → chunk-5CNL24PI.js} +10 -107
  9. package/dist/chunk-5CNL24PI.js.map +1 -0
  10. package/dist/{chunk-32SLDGE5.js → chunk-6FVXAF7L.js} +4 -3
  11. package/dist/chunk-6FVXAF7L.js.map +1 -0
  12. package/dist/chunk-AK4276ND.js +67 -0
  13. package/dist/chunk-AK4276ND.js.map +1 -0
  14. package/dist/chunk-IOYYCA75.js +52 -0
  15. package/dist/chunk-IOYYCA75.js.map +1 -0
  16. package/dist/chunk-KX7KXN3W.js +529 -0
  17. package/dist/chunk-KX7KXN3W.js.map +1 -0
  18. package/dist/{chunk-GXDTRTUT.js → chunk-RURXGVWW.js} +35 -6
  19. package/dist/chunk-RURXGVWW.js.map +1 -0
  20. package/dist/{chunk-XULHV6SS.js → chunk-TE2QPH74.js} +3 -3
  21. package/dist/{chunk-XULHV6SS.js.map → chunk-TE2QPH74.js.map} +1 -1
  22. package/dist/chunk-TE42OCFK.js +102 -0
  23. package/dist/chunk-TE42OCFK.js.map +1 -0
  24. package/dist/{chunk-GILJFP55.js → chunk-VTZYJ6OZ.js} +2 -2
  25. package/dist/chunk-VTZYJ6OZ.js.map +1 -0
  26. package/dist/{chunk-46FNHMWC.js → chunk-W43D7JYV.js} +5 -4
  27. package/dist/chunk-W43D7JYV.js.map +1 -0
  28. package/dist/{chunk-QZ3S3NN3.js → chunk-WTZXTBF6.js} +3 -47
  29. package/dist/chunk-WTZXTBF6.js.map +1 -0
  30. package/dist/index.d.ts +5 -3
  31. package/dist/index.js +14 -11
  32. package/dist/ports/index.d.ts +1 -1
  33. package/dist/ports/index.js +1 -1
  34. package/dist/products/index.js +3 -2
  35. package/dist/promotions/index.js +4 -3
  36. package/dist/seo/index.js +5 -4
  37. package/dist/seo/index.js.map +1 -1
  38. package/dist/stores/index.d.ts +56 -1
  39. package/dist/stores/index.js +6 -3
  40. package/dist/types-CXm2F6Hz.d.ts +55 -0
  41. package/dist/useCheckoutSubmit-Be-lQd60.d.ts +30 -0
  42. package/dist/utils/index.d.ts +6 -1
  43. package/dist/utils/index.js +1 -1
  44. package/docs/architecture.md +79 -3
  45. package/package.json +7 -3
  46. package/dist/chunk-32SLDGE5.js.map +0 -1
  47. package/dist/chunk-46FNHMWC.js.map +0 -1
  48. package/dist/chunk-4UMDIBW5.js.map +0 -1
  49. package/dist/chunk-FXKG5TFQ.js +0 -38
  50. package/dist/chunk-FXKG5TFQ.js.map +0 -1
  51. package/dist/chunk-GILJFP55.js.map +0 -1
  52. package/dist/chunk-GXDTRTUT.js.map +0 -1
  53. package/dist/chunk-QZ3S3NN3.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -8,6 +8,14 @@ All notable changes to this project are documented in this file. The format foll
8
8
 
9
9
  ### Added
10
10
 
11
+ - `groupScheduleDays` (`/utils`) — collapses consecutive days that share the same hours
12
+ into one row, so a location prints "пн — пт: 10:00-19:00" instead of five identical
13
+ lines; a page listing a chain's pickup points would otherwise print seven day-rows per
14
+ location. Day abbreviations come from `Intl`, not from slicing the long name — Russian
15
+ "понедельник" abbreviates to "пн", not "по" — and are returned in the locale's own
16
+ casing, since capitalizing them here corrupts scripts such as Georgian. Intl formatters
17
+ are memoized: constructing one is the expensive part, and a seven-location page built
18
+ roughly a hundred of them.
11
19
  - `catalogItemEntity` / `isRenderableCatalogItem` (`/catalog`) — resolve a static catalog
12
20
  item to a discriminated `category | collection` entity, with `id` and `name` lifted out
13
21
  so a consumer can key, title, and scroll-spy a section without branching. Manual
@@ -26,6 +34,67 @@ All notable changes to this project are documented in this file. The format foll
26
34
  in the consuming app built this fetch by hand and had drifted apart; one of them was
27
35
  missing `variants.prices` and silently showed every product's store-wide price instead
28
36
  of the price of the stock the customer was actually browsing.
37
+ - `authFlow` store (`zenky-auth-flow`, new `/auth` subpath) — the registration/login/
38
+ password-reset step machine (`checkPhone`/`login`/`register`/`confirmRegistration`/
39
+ `resendCode`/`dispatchReset`/`resetPassword`), moved out of the consuming app, with
40
+ confirmation-channel selection added on top (SMS/Telegram/WhatsApp). `register`/
41
+ `resendCode`/`dispatchReset` gate on a channel picker when the store has 2+ channels
42
+ enabled (`store.settings.authentication`), retry on `auth.otp_request.failed` by
43
+ falling back to another enabled channel — the failed channel is exposed as
44
+ `lastFailedChannel` so the UI can hide/disable it on the retry. `SelectableConfirmationChannel`
45
+ (`ConfirmationChannel` minus the response-only `call`) types everything the user can
46
+ actually pick — `availableChannels`, `selectChannel`, `lastFailedChannel`. Requires
47
+ `@zenky/storefront-api@^1.1.0` for `ConfirmationMethod.Telegram/WhatsApp` and
48
+ `RequestedConfirmationMethod`. Recaptcha is a parameter on every action that dispatches
49
+ an OTP, including `checkPhone`/`login`'s internal auto-resend
50
+ (`RecaptchaPayloadProvider`, reused from `cart/useCheckoutSubmit` — not a new port,
51
+ same pattern as checkout submission). All user-facing error copy goes through the
52
+ `messages` port instead of hardcoded Russian strings — 8 new `StorefrontMessageKey`
53
+ entries (`auth.checkPhoneFailed`, `auth.invalidPassword`, `auth.registerFailed`,
54
+ `auth.invalidCode`, `auth.resendCodeFailed`, `auth.dispatchResetFailed`,
55
+ `auth.resetPasswordFailed`, `auth.otpUnavailable`). `handleAuthError` now takes a
56
+ `StorefrontMessageKey` fallback instead of a ready-made string, so the core makes no
57
+ assumption about locale — text and translation stay entirely on the consumer's side.
58
+ Every action is guarded against out-of-order responses with an operation-revision
59
+ counter: each top-level call (`checkPhone`, `login`, `register`, `confirmRegistration`,
60
+ `resendCode`, `dispatchReset`, `resetPassword`, `selectChannel`) opens a new revision
61
+ that a later call — a fresh attempt, `reset()`, any `goTo*` navigation including
62
+ `Back`, or `changeChannel()` — invalidates; after every `await` (recaptcha included)
63
+ the store checks its revision is still current before touching
64
+ `currentStep`/`error`/`loading`/etc., so a slow response from an abandoned attempt can
65
+ no longer land on top of a newer one. A nested call that's a continuation of the same
66
+ user attempt (`checkPhone`/`login`'s auto-resend, `register`'s 0-channel `login`
67
+ fallback, `selectChannel`'s dispatch) receives the parent's revision instead of
68
+ opening its own, so it isn't invalidated by its own caller. Invalidation isn't limited
69
+ to explicit actions: `phone`/`countryCode` invalidate on direct assignment too (a
70
+ `customRef`, transparent to `v-model`), since both are typically bound straight to an
71
+ input — a user can edit the field without re-submitting while a request for the old
72
+ value is still in flight. Every value read after an `await` (`phone`, `country`,
73
+ recaptcha action, the channel a failed OTP dispatch is attributed to) is a snapshot
74
+ taken before the first `await`, not a live read, so a value the user changes while a
75
+ request is in flight can't leak into how its response is handled. Both invalidating
76
+ helpers — `beginOperation()` for a fresh top-level attempt, `cancelPendingOperation()`
77
+ where nothing new replaces what's cancelled (`Back`, `reset()`, `changeChannel()`) —
78
+ clear `loading` themselves rather than assuming "the next line" will: for most actions
79
+ the next line isn't `loading.value = true` but a channel gate or a `storeId` check
80
+ that can `return` first, and the request's own `finally` has just lost the right to
81
+ clear `loading` by the same guard. An action that does reach its request sets
82
+ `loading` back to `true` a few lines later, in the same synchronous stretch, so this
83
+ reads as one transition, not a flicker.
84
+
85
+ Covered by 14 dedicated tests: a stale response losing to a newer one; a stale
86
+ `finally` not clearing a newer call's `loading`; the same class of bug in two more
87
+ shapes — every `goTo*`/`changeChannel()` invalidating the revision without clearing
88
+ `loading`, and a fresh action doing the same on its own early return, both leaving
89
+ `loading` stuck since the cancelled request's `finally` had already lost the right to
90
+ touch it; a stale recaptcha not overriding a channel picked after it; `Back` during a
91
+ dispatch neither landing the user back on `Code` nor leaving `loading` stuck; editing
92
+ `phone` without resubmitting neither applying a stale response nor letting a nested
93
+ auto-resend fire against the new number; a directly-assigned `confirmationMethod` (no
94
+ `customRef` on it — the legitimate paths already invalidate) not corrupting
95
+ `lastFailedChannel` on an OTP failure; and firing every remaining top-level action
96
+ twice to confirm the `loading` guard holds everywhere, not just where it was first
97
+ found broken.
29
98
 
30
99
  ### Changed
31
100
 
@@ -37,6 +106,76 @@ All notable changes to this project are documented in this file. The format foll
37
106
  widen that annotation.
38
107
  - `getRemoteCatalog` returns `StaticRemoteCatalog`, so `catalog_id` is typed.
39
108
 
109
+ ### Fixed
110
+
111
+ - `authFlow.goToReset()` no longer confuses the resend timer between phone numbers.
112
+ `resendTimerEndsAt`/`codeContext` are shared, request-scoped refs, and were only
113
+ cleared by a full `reset()` — checking a second phone number after abandoning a
114
+ password-reset flow for a first one could land the second number straight on the
115
+ confirmation-code step for a code that was never actually sent to it. `checkPhone()`
116
+ now clears both at the start of every phone check, and `goToReset()` only trusts the
117
+ timer when `codeContext` is already `Reset`.
118
+ - `authFlow` error messages for non-`ZenkyError` failures (network drop, CORS, an
119
+ ad-blocker) no longer leak the raw `Error.message` to the user — they fall through to
120
+ the localized `fallback` string, same as `cart`'s error handling already did.
121
+ - `authFlow.selectChannel()` no longer clears `channelIntent` before the dispatch it
122
+ triggers actually succeeds. Any failure other than `auth.otp_request.failed`
123
+ (validation, network) left `currentStep` on `Channel` with `channelIntent` already
124
+ `null` — picking a channel again silently did nothing, and `goToChannelBack()` sent
125
+ the user to `Phone` instead of back to `Register`/`Code`/`Reset`. `channelIntent` is
126
+ now cleared by `register`/`resendCode`/`dispatchReset` themselves, only on real
127
+ success.
128
+ - `authFlow.resendCode()` now transitions to `AUTH_STEP.Code` itself when the dispatch it
129
+ just ran was reached via the channel picker — previously it never advanced past
130
+ `Channel` on that path (only `checkPhone`/`login`'s direct calls advanced the step),
131
+ so picking a channel for a resend silently left the user stuck on the picker after a
132
+ successful send.
133
+ - `authFlow.checkPhone()`/`login()`'s internal auto-resend (registered-but-unconfirmed,
134
+ and the `ConfirmationRequired` branch of `login`) no longer dispatches the OTP with a
135
+ no-op recaptcha provider. Both now take `getRecaptchaPayload` and forward it — for
136
+ stores with 2+ channels this was invisible (the real provider arrives later via
137
+ `selectChannel`), but for a single-channel store the request went out with no
138
+ recaptcha token at all.
139
+ - `authFlow.checkPhone()` now clears the full phone-scoped state (`confirmationMethod`,
140
+ `pendingPassword`, `channelIntent`, `resetCode`, `registerCode` — previously only
141
+ `codeContext`/`resendTimerEndsAt`) at the start of every check. Backing out of a flow
142
+ for one phone number and checking a different one could otherwise carry over the
143
+ first number's selected channel or pending password.
144
+ - `authFlow.channelIntent` is now part of the store's public `$state` (returned from
145
+ `defineStore`'s setup, per the dts rule) instead of a closure-local ref. Pinia setup
146
+ stores only serialize/hydrate what's returned — if the server happened to render with
147
+ `currentStep === 'channel'`, the client would hydrate that step with `channelIntent`
148
+ reset to `null`, making the picker a no-op and `goToChannelBack()` misroute.
149
+ - `handleOtpDispatchError()` no longer force-casts `confirmationMethod.value` into
150
+ `lastFailedChannel`. The cast assumed the value was always the channel *just
151
+ requested*, which holds right after an explicit `selectChannel()` pick but not when
152
+ `confirmationMethod` was inherited from an *earlier* successful dispatch whose
153
+ response (`AuthConfirmationStatus.method`, the SDK's full `ConfirmationMethod`, not
154
+ the request-only `RequestedConfirmationMethod`) came back as the legacy `Call` value —
155
+ a real backend fallback (dial in, code is the caller ID's last 4 digits), not a
156
+ hypothetical. A later failed attempt would then have silently stored `'call'` into a
157
+ field typed to exclude it, making the "hide the channel that just failed" UX a no-op
158
+ for that case. Now a runtime check keeps `Call` out instead of asserting it away.
159
+ - `authFlow.changeChannel()` now invalidates the pending operation revision. Without it,
160
+ a dispatch still in flight when the user resets their channel choice could resolve
161
+ afterward and resurrect the very channel they just backed out of (its success handler
162
+ writes `confirmationMethod` from the response, unconditionally).
163
+
164
+ ### Security
165
+
166
+ - `authFlow.pendingPassword` is cleared immediately after a successful `register`
167
+ (0-channel edge case) or `confirmRegistration`, instead of lingering until the next
168
+ full `reset()`. It's a raw, publicly-exposed `Ref<string>` on the store — leaving a
169
+ plaintext password in reactive state after auth succeeds was an unnecessary window,
170
+ particularly for an SSR consumer where Pinia state can end up in the hydration
171
+ payload.
172
+ - `authFlow.register()`'s 0-channel edge case (`confirmation_required: false`) no longer
173
+ reports success while writing an empty string as the auth token.
174
+ `AuthConfirmationStatus` (register's response) never carries a token — `authStore`
175
+ treats an empty token as unauthenticated — so a caller that closed the auth UI on
176
+ `register()` returning `true` left the user believing they were signed in when they
177
+ weren't. This path now performs a real `login()` with the same password instead.
178
+
40
179
  ## 0.10.7 - 2026-08-02
41
180
 
42
181
  ### Added
package/README.md CHANGED
@@ -181,7 +181,7 @@ import { buildProductSchema, buildOgTags } from '@zenky/storefront-vue/seo'
181
181
  import { usePaginatedList } from '@zenky/storefront-vue/pagination'
182
182
  ```
183
183
 
184
- Available subpaths: `ports`, `money`, `utils`, `theme`, `stores`, `products`, `catalog`, `cart`, `order`, `promotions`, `seo`, `pagination`, `snippets`, `website-settings`.
184
+ Available subpaths: `ports`, `money`, `utils`, `theme`, `stores`, `products`, `catalog`, `cart`, `order`, `promotions`, `seo`, `pagination`, `snippets`, `website-settings`, `auth`.
185
185
 
186
186
  Routing, tenant theme presets, localized copy, header/footer composition, and conversion to
187
187
  framework-specific head records belong to the consumer. Core SEO builders return plain
@@ -0,0 +1,14 @@
1
+ import { S as SelectableConfirmationChannel } from '../types-CXm2F6Hz.js';
2
+ export { A as AUTH_STEP, a as AuthStep, C as CHANNEL_INTENT, b as CODE_CONTEXT, c as CONFIRMATION_CHANNEL, d as CONFIRMATION_CHANNEL_ORDER, e as ChannelIntent, f as CodeContext, g as ConfirmationChannel, t as toConfirmationChannel, h as toRequestedMethod } from '../types-CXm2F6Hz.js';
3
+ import { ComputedRef } from 'vue';
4
+ import '@zenky/storefront-api';
5
+
6
+ /**
7
+ * Доступные каналы подтверждения для текущего магазина, в порядке показа
8
+ * (Telegram, WhatsApp, SMS). Источник — `store.settings.authentication`.
9
+ * Логика "≥2 → показать выбор, 1 → использовать сразу, 0 → method не передаём" —
10
+ * в вызывающем коде, эта функция отдаёт только список.
11
+ */
12
+ declare function useAvailableConfirmationChannels(): ComputedRef<SelectableConfirmationChannel[]>;
13
+
14
+ export { SelectableConfirmationChannel, useAvailableConfirmationChannels };
@@ -0,0 +1,4 @@
1
+ export { AUTH_STEP, CHANNEL_INTENT, CODE_CONTEXT, CONFIRMATION_CHANNEL, CONFIRMATION_CHANNEL_ORDER, toConfirmationChannel, toRequestedMethod, useAvailableConfirmationChannels } from '../chunk-AK4276ND.js';
2
+ import '../chunk-IOYYCA75.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,6 +1,7 @@
1
- import { ProductModifiersRequest, OrderProductVariant, PaymentMethod, OrderPaymentMethodRequest, OrderAuthenticationMethod, OrderCredentials, Order, OrderCheckoutTotal, OrderSettings, OrderPaymentMethod, OrderDeliveryMethod, InclusionRequest, ZenkyStorefront, SetOrderCustomerRequest, SetOrderDeliveryRequest, OrderPromocode, RecommendationsBlock, OrderCheckoutResult, RecaptchaAction, EvaluatedRestriction, Media, Product } from '@zenky/storefront-api';
1
+ import { ProductModifiersRequest, OrderProductVariant, PaymentMethod, OrderPaymentMethodRequest, OrderAuthenticationMethod, OrderCredentials, Order, OrderCheckoutTotal, OrderSettings, OrderPaymentMethod, OrderDeliveryMethod, InclusionRequest, ZenkyStorefront, SetOrderCustomerRequest, SetOrderDeliveryRequest, OrderPromocode, RecommendationsBlock, EvaluatedRestriction, Media, Product } from '@zenky/storefront-api';
2
2
  import { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
3
3
  import { ActivityReporter, Notifier, Result } from '../ports/index.js';
4
+ export { C as CheckoutSubmitComposable, R as RecaptchaPayloadProvider, u as useCheckoutSubmit } from '../useCheckoutSubmit-Be-lQd60.js';
4
5
  import '@zenky/integrations-sdk';
5
6
 
6
7
  /** WebSocket events for the order channel */
@@ -513,32 +514,6 @@ interface CartOperations {
513
514
  }
514
515
  declare function useCartOperations(credentials: CartCredentials, initialization: CartInitialization, sdk: ZenkyStorefront, deps: CartDependencies): CartOperations;
515
516
 
516
- /** reCAPTCHA payload provider (implemented by the consumer app — Google reCAPTCHA v3). */
517
- type RecaptchaPayloadProvider = (action: RecaptchaAction) => Promise<{
518
- token: string;
519
- } | undefined>;
520
- interface CheckoutSubmitComposable {
521
- /** Last `checkoutOrder` result — needed by the UI (ConfirmationModal / online redirect) */
522
- result: Ref<OrderCheckoutResult | null>;
523
- submitting: Ref<boolean>;
524
- /**
525
- * Collects `OrderCheckoutRequest` from `cartStore` (notes + persons_count).
526
- * Returns `OrderCheckoutResult` with confirmation/online_payment flags.
527
- */
528
- submit: () => Promise<OrderCheckoutResult | null>;
529
- /** Confirm the SMS code (after checkoutOrder returned confirmation.required) */
530
- confirm: (code: string) => Promise<boolean>;
531
- /** Resend the code (with backoff — the UI is responsible for that) */
532
- resendCode: () => Promise<boolean>;
533
- cancel: () => Promise<boolean>;
534
- }
535
- /**
536
- * Final order submit + SMS confirmation.
537
- *
538
- * @param getRecaptchaPayload reCAPTCHA token provider (app-specific, injected).
539
- */
540
- declare function useCheckoutSubmit(getRecaptchaPayload: RecaptchaPayloadProvider): CheckoutSubmitComposable;
541
-
542
517
  declare function useOrderChannel(): void;
543
518
 
544
519
  interface StorefrontCart {
@@ -592,4 +567,4 @@ declare function useRestrictedAddToCart(): RestrictedAddToCart;
592
567
  */
593
568
  declare function useVisibleCartVariants(): ComputedRef<OrderProductVariant[]>;
594
569
 
595
- export { type AttachedCustomerCache, type BonusesReconciliation, type BonusesReconciliationDeps, CASH_DENOMINATIONS_MAJOR, type CachedCustomerView, type CartCredentials, type CartDependencies, type CartErrorScope, type CartInitialization, type CartItemRequest, type CartLineKeyParams, type CartMutationComposable, type CartOperations, type CartQuantities, type CartRecalculation, type CartRecalculationDeps, type CartStockWatcher, type CashChangePresetsOptions, type CheckoutFlowFlags, type CheckoutSubmitComposable, type CustomerAttachComposable, DEFAULT_ROUND_STEPS_MAJOR, type MainPaymentRequestParams, type MutationKind, type MutationOptions, ORDER_EVENTS, ORDER_WITH, type OrderBonusesComposable, type OrderBonusesDeps, type OrderCredentialsLike, type OrderDelivery, type OrderDeliveryDeps, type OrderPromocodeComposable, type OrderPromocodeDeps, type OrderSettingsComposable, type OrderTotal, type PaymentSelection, type PaymentSelectionComposable, type RecaptchaPayloadProvider, type RestrictedAddToCart, type RestrictionGate, type RestrictionGateProduct, type RetryOptions, type StorefrontCart, buildCartLineKey, buildCashChangePresets, buildMainPaymentRequest, getCartErrorCode, getCartErrorHttpCode, getCartErrorMessage, getCashDenominationsMinor, getDefaultRoundStepsMinor, getValidationErrors, logCartError, normalizeAddress, useBonusesReconciliation, useCartAddressSync, useCartCredentials, useCartCustomerAttachment, useCartDeliveryAttachment, useCartInitialization, useCartMutation, useCartOperations, useCartQuantities, useCartRecalculation, useCartStockWatcher, useCheckoutFlow, useCheckoutSubmit, useCustomerAttach, useOnlinePaymentRetry, useOrderBonuses, useOrderChannel, useOrderDelivery, useOrderPromocode, useOrderSettings, useOrderTotal, usePaymentSelection, useRestrictedAddToCart, useRestrictionGate, useStorefrontCart, useVisibleCartVariants, variantLineKey };
570
+ export { type AttachedCustomerCache, type BonusesReconciliation, type BonusesReconciliationDeps, CASH_DENOMINATIONS_MAJOR, type CachedCustomerView, type CartCredentials, type CartDependencies, type CartErrorScope, type CartInitialization, type CartItemRequest, type CartLineKeyParams, type CartMutationComposable, type CartOperations, type CartQuantities, type CartRecalculation, type CartRecalculationDeps, type CartStockWatcher, type CashChangePresetsOptions, type CheckoutFlowFlags, type CustomerAttachComposable, DEFAULT_ROUND_STEPS_MAJOR, type MainPaymentRequestParams, type MutationKind, type MutationOptions, ORDER_EVENTS, ORDER_WITH, type OrderBonusesComposable, type OrderBonusesDeps, type OrderCredentialsLike, type OrderDelivery, type OrderDeliveryDeps, type OrderPromocodeComposable, type OrderPromocodeDeps, type OrderSettingsComposable, type OrderTotal, type PaymentSelection, type PaymentSelectionComposable, type RestrictedAddToCart, type RestrictionGate, type RestrictionGateProduct, type RetryOptions, type StorefrontCart, buildCartLineKey, buildCashChangePresets, buildMainPaymentRequest, getCartErrorCode, getCartErrorHttpCode, getCartErrorMessage, getCashDenominationsMinor, getDefaultRoundStepsMinor, getValidationErrors, logCartError, normalizeAddress, useBonusesReconciliation, useCartAddressSync, useCartCredentials, useCartCustomerAttachment, useCartDeliveryAttachment, useCartInitialization, useCartMutation, useCartOperations, useCartQuantities, useCartRecalculation, useCartStockWatcher, useCheckoutFlow, useCustomerAttach, useOnlinePaymentRetry, useOrderBonuses, useOrderChannel, useOrderDelivery, useOrderPromocode, useOrderSettings, useOrderTotal, usePaymentSelection, useRestrictedAddToCart, useRestrictionGate, useStorefrontCart, useVisibleCartVariants, variantLineKey };
@@ -1,10 +1,12 @@
1
- export { CASH_DENOMINATIONS_MAJOR, DEFAULT_ROUND_STEPS_MAJOR, ORDER_EVENTS, ORDER_WITH, buildCartLineKey, buildCashChangePresets, buildMainPaymentRequest, getCartErrorCode, getCartErrorHttpCode, getCartErrorMessage, getCashDenominationsMinor, getDefaultRoundStepsMinor, getValidationErrors, logCartError, normalizeAddress, useBonusesReconciliation, useCartAddressSync, useCartCustomerAttachment, useCartDeliveryAttachment, useCartInitialization, useCartMutation, useCartOperations, useCartQuantities, useCartRecalculation, useCartStockWatcher, useCheckoutFlow, useCheckoutSubmit, useCustomerAttach, useOnlinePaymentRetry, useOrderBonuses, useOrderChannel, useOrderDelivery, useOrderPromocode, useOrderSettings, useOrderTotal, usePaymentSelection, useRestrictedAddToCart, useRestrictionGate, useStorefrontCart, useVisibleCartVariants, variantLineKey } from '../chunk-4UMDIBW5.js';
2
- export { useCartCredentials } from '../chunk-46FNHMWC.js';
3
- import '../chunk-XULHV6SS.js';
4
- import '../chunk-FS2UNPTY.js';
5
- import '../chunk-2Y6QTHXI.js';
1
+ export { CASH_DENOMINATIONS_MAJOR, DEFAULT_ROUND_STEPS_MAJOR, ORDER_EVENTS, ORDER_WITH, buildCartLineKey, buildCashChangePresets, buildMainPaymentRequest, getCashDenominationsMinor, getDefaultRoundStepsMinor, normalizeAddress, useBonusesReconciliation, useCartAddressSync, useCartCustomerAttachment, useCartDeliveryAttachment, useCartInitialization, useCartMutation, useCartOperations, useCartQuantities, useCartRecalculation, useCartStockWatcher, useCheckoutFlow, useCheckoutSubmit, useCustomerAttach, useOnlinePaymentRetry, useOrderBonuses, useOrderChannel, useOrderDelivery, useOrderPromocode, useOrderSettings, useOrderTotal, usePaymentSelection, useRestrictedAddToCart, useRestrictionGate, useStorefrontCart, useVisibleCartVariants, variantLineKey } from '../chunk-5CNL24PI.js';
2
+ export { useCartCredentials } from '../chunk-W43D7JYV.js';
6
3
  import '../chunk-5QCUH3FF.js';
4
+ export { getCartErrorCode, getCartErrorHttpCode, getCartErrorMessage, getValidationErrors, logCartError } from '../chunk-TE42OCFK.js';
5
+ import '../chunk-TE2QPH74.js';
7
6
  import '../chunk-NSOIL7PW.js';
8
- import '../chunk-QZ3S3NN3.js';
7
+ import '../chunk-WTZXTBF6.js';
8
+ import '../chunk-IOYYCA75.js';
9
+ import '../chunk-FS2UNPTY.js';
10
+ import '../chunk-2Y6QTHXI.js';
9
11
  //# sourceMappingURL=index.js.map
10
12
  //# sourceMappingURL=index.js.map
@@ -1,10 +1,12 @@
1
- import { useCartCredentials, usePromotionsChecker } from './chunk-46FNHMWC.js';
2
- import { useCartStore, useOrderSettingsStore, usePromotionsStore } from './chunk-XULHV6SS.js';
3
- import { getRemoteCatalog } from './chunk-FS2UNPTY.js';
4
- import { minorToMajor, majorToMinor } from './chunk-2Y6QTHXI.js';
1
+ import { useCartCredentials, usePromotionsChecker } from './chunk-W43D7JYV.js';
5
2
  import { createRuntimeState } from './chunk-5QCUH3FF.js';
3
+ import { logCartError, getCartErrorCode, getCartErrorMessage } from './chunk-TE42OCFK.js';
4
+ import { useCartStore, useOrderSettingsStore, usePromotionsStore } from './chunk-TE2QPH74.js';
6
5
  import { useCatalogStore } from './chunk-NSOIL7PW.js';
7
- import { useRuntime, useStoreProfileStore, useAuthStore } from './chunk-QZ3S3NN3.js';
6
+ import { useRuntime, useAuthStore } from './chunk-WTZXTBF6.js';
7
+ import { useStoreProfileStore } from './chunk-IOYYCA75.js';
8
+ import { getRemoteCatalog } from './chunk-FS2UNPTY.js';
9
+ import { minorToMajor, majorToMinor } from './chunk-2Y6QTHXI.js';
8
10
  import { PaymentMethod, OrderAuthenticationMethod, DeliveryMethod, OrderCartCheckerResultAction, RecaptchaAction } from '@zenky/storefront-api';
9
11
  import { ref, computed, watch, watchEffect, getCurrentScope, onScopeDispose, toValue } from 'vue';
10
12
  import { storeToRefs } from 'pinia';
@@ -92,105 +94,6 @@ function buildCashChangePresets({
92
94
  return [...candidates].sort((a, b) => a - b);
93
95
  }
94
96
 
95
- // src/cart/logCartError.ts
96
- var REDACTED = "[REDACTED]";
97
- var MAX_LOG_DEPTH = 6;
98
- var MAX_ARRAY_ITEMS = 25;
99
- var MAX_OBJECT_KEYS = 50;
100
- var SENSITIVE_KEY_PARTS = [
101
- "address",
102
- "authorization",
103
- "checkouturl",
104
- "cookie",
105
- "credential",
106
- "email",
107
- "password",
108
- "paymentlink",
109
- "paymentpageurl",
110
- "phone",
111
- "recaptcha",
112
- "redirecturl",
113
- "secret",
114
- "token"
115
- ];
116
- var SENSITIVE_EXACT_KEYS = /* @__PURE__ */ new Set(["cvc", "cvv", "otp", "pan", "pin"]);
117
- var SENSITIVE_ASSIGNMENT = /((?:address|authorization|cookie|email|password|phone|recaptcha|secret|(?:checkout|redirect)[_-]?url|payment(?:[_-]?page)?[_-]?(?:link|url)|(?:api|access|auth|card|order|refresh)[_-]?token|token)\s*[=:]\s*["']?)([^\s,"';&}\]]+)/gi;
118
- var SENSITIVE_QUERY_PARAM = /([?&#](?:address|authorization|email|password|phone|recaptcha|secret|(?:checkout|redirect)[_-]?url|payment(?:[_-]?page)?[_-]?(?:link|url)|(?:api|access|auth|card|order|refresh)[_-]?token|token)=)([^&#\s]+)/gi;
119
- var BEARER_TOKEN = /(bearer\s+)[a-z0-9._~+/=-]+/gi;
120
- function isSensitiveKey(key) {
121
- const normalized = key.replace(/[^a-z0-9]/gi, "").toLowerCase();
122
- return SENSITIVE_EXACT_KEYS.has(normalized) || normalized.includes("confirmationcode") || normalized.includes("verificationcode") || SENSITIVE_KEY_PARTS.some((part) => normalized.includes(part));
123
- }
124
- function sanitizeString(value) {
125
- return value.replace(BEARER_TOKEN, `$1${REDACTED}`).replace(SENSITIVE_QUERY_PARAM, `$1${REDACTED}`).replace(SENSITIVE_ASSIGNMENT, `$1${REDACTED}`);
126
- }
127
- function sanitizeLogValue(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
128
- if (typeof value === "string") return sanitizeString(value);
129
- if (value === null || typeof value !== "object") return value;
130
- if (depth >= MAX_LOG_DEPTH) return "[TRUNCATED]";
131
- if (seen.has(value)) return "[CIRCULAR]";
132
- seen.add(value);
133
- if (Array.isArray(value)) {
134
- const sanitized = value.slice(0, MAX_ARRAY_ITEMS).map((item) => sanitizeLogValue(item, depth + 1, seen));
135
- if (value.length > MAX_ARRAY_ITEMS) sanitized.push("[TRUNCATED]");
136
- return sanitized;
137
- }
138
- const result = {};
139
- if (value instanceof Error) {
140
- result.name = sanitizeString(value.name);
141
- result.message = sanitizeString(value.message);
142
- }
143
- let allEntries;
144
- try {
145
- allEntries = Object.entries(value);
146
- } catch {
147
- return "[UNSERIALIZABLE]";
148
- }
149
- const entries = allEntries.slice(0, MAX_OBJECT_KEYS);
150
- for (const [key, nestedValue] of entries) {
151
- if (key === "name" || key === "message") continue;
152
- result[key] = isSensitiveKey(key) ? REDACTED : sanitizeLogValue(nestedValue, depth + 1, seen);
153
- }
154
- if (allEntries.length > MAX_OBJECT_KEYS) result.__truncated__ = true;
155
- return result;
156
- }
157
- function logCartError({ scope, context }, e) {
158
- const err = e?.err;
159
- const safeContext = sanitizeLogValue(context);
160
- console.error(`[${scope}] failed`, {
161
- ...safeContext ?? {},
162
- httpCode: err?.http_code,
163
- errorCode: err?.error_code,
164
- message: sanitizeLogValue(err?.message),
165
- meta: sanitizeLogValue(err?.meta),
166
- error: sanitizeLogValue(e)
167
- });
168
- }
169
- function getCartErrorCode(e) {
170
- return e?.err?.error_code;
171
- }
172
- function getCartErrorHttpCode(e) {
173
- return e?.err?.http_code;
174
- }
175
- function getValidationErrors(e) {
176
- const err = e?.err;
177
- if (err?.error_code !== "validation") return {};
178
- const meta = err.meta;
179
- return meta?.errors ?? {};
180
- }
181
- function getCartErrorMessage(e, fallback) {
182
- const err = e?.err;
183
- if (!err) return fallback;
184
- if (err.error_code === "validation") {
185
- const errors = err.meta?.errors;
186
- if (errors) {
187
- const messages = Object.values(errors).flat().filter(Boolean);
188
- if (messages.length > 0) return messages.join(" ");
189
- }
190
- }
191
- return err.message ?? fallback;
192
- }
193
-
194
97
  // src/cart/useCartMutation.ts
195
98
  var getMutationState = createRuntimeState(() => ({
196
99
  versions: /* @__PURE__ */ new Map()
@@ -2010,6 +1913,6 @@ function useVisibleCartVariants() {
2010
1913
  );
2011
1914
  }
2012
1915
 
2013
- export { CASH_DENOMINATIONS_MAJOR, DEFAULT_ROUND_STEPS_MAJOR, ORDER_EVENTS, ORDER_WITH, buildCartLineKey, buildCashChangePresets, buildMainPaymentRequest, getCartErrorCode, getCartErrorHttpCode, getCartErrorMessage, getCashDenominationsMinor, getDefaultRoundStepsMinor, getValidationErrors, logCartError, normalizeAddress, useBonusesReconciliation, useCartAddressSync, useCartCustomerAttachment, useCartDeliveryAttachment, useCartInitialization, useCartMutation, useCartOperations, useCartQuantities, useCartRecalculation, useCartStockWatcher, useCheckoutFlow, useCheckoutSubmit, useCustomerAttach, useOnlinePaymentRetry, useOrderBonuses, useOrderChannel, useOrderDelivery, useOrderPromocode, useOrderSettings, useOrderTotal, usePaymentSelection, useRestrictedAddToCart, useRestrictionGate, useStorefrontCart, useVisibleCartVariants, variantLineKey };
2014
- //# sourceMappingURL=chunk-4UMDIBW5.js.map
2015
- //# sourceMappingURL=chunk-4UMDIBW5.js.map
1916
+ export { CASH_DENOMINATIONS_MAJOR, DEFAULT_ROUND_STEPS_MAJOR, ORDER_EVENTS, ORDER_WITH, buildCartLineKey, buildCashChangePresets, buildMainPaymentRequest, getCashDenominationsMinor, getDefaultRoundStepsMinor, normalizeAddress, useBonusesReconciliation, useCartAddressSync, useCartCustomerAttachment, useCartDeliveryAttachment, useCartInitialization, useCartMutation, useCartOperations, useCartQuantities, useCartRecalculation, useCartStockWatcher, useCheckoutFlow, useCheckoutSubmit, useCustomerAttach, useOnlinePaymentRetry, useOrderBonuses, useOrderChannel, useOrderDelivery, useOrderPromocode, useOrderSettings, useOrderTotal, usePaymentSelection, useRestrictedAddToCart, useRestrictionGate, useStorefrontCart, useVisibleCartVariants, variantLineKey };
1917
+ //# sourceMappingURL=chunk-5CNL24PI.js.map
1918
+ //# sourceMappingURL=chunk-5CNL24PI.js.map