@zenky/storefront-vue 0.10.3 → 0.10.4
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/CHANGELOG.md +60 -1
- package/README.md +15 -5
- package/dist/cart/index.js +5 -7
- package/dist/catalog/index.d.ts +1 -11
- package/dist/catalog/index.js +1 -1
- package/dist/chunk-2CI4RW7V.js +21 -0
- package/dist/chunk-2CI4RW7V.js.map +1 -0
- package/dist/{chunk-GW2QNTAD.js → chunk-4IFPVEO7.js} +3 -113
- package/dist/chunk-4IFPVEO7.js.map +1 -0
- package/dist/{chunk-JLFBAAFT.js → chunk-IVG4FQE5.js} +4 -5
- package/dist/chunk-IVG4FQE5.js.map +1 -0
- package/dist/{chunk-RYYY7MVP.js → chunk-NG7RUIWW.js} +3 -13
- package/dist/chunk-NG7RUIWW.js.map +1 -0
- package/dist/{chunk-FFBZKQRV.js → chunk-NIQFYJRP.js} +41 -4
- package/dist/chunk-NIQFYJRP.js.map +1 -0
- package/dist/{chunk-GLTOJTZO.js → chunk-OTSAR32A.js} +6 -3
- package/dist/chunk-OTSAR32A.js.map +1 -0
- package/dist/{chunk-57IOMDAM.js → chunk-SS7B2NLF.js} +3 -3
- package/dist/{chunk-57IOMDAM.js.map → chunk-SS7B2NLF.js.map} +1 -1
- package/dist/{chunk-TEG7EL4N.js → chunk-TB5TBJ4U.js} +43 -5
- package/dist/chunk-TB5TBJ4U.js.map +1 -0
- package/dist/{chunk-N3NOTJUC.js → chunk-YREGCQSB.js} +4 -6
- package/dist/chunk-YREGCQSB.js.map +1 -0
- package/dist/{chunk-G2X4SBCO.js → chunk-YS5DXYYV.js} +34 -27
- package/dist/chunk-YS5DXYYV.js.map +1 -0
- package/dist/index.d.ts +5 -7
- package/dist/index.js +13 -15
- package/dist/order/index.d.ts +2 -0
- package/dist/order/index.js +2 -5
- package/dist/order/index.js.map +1 -1
- package/dist/ports/index.d.ts +12 -1
- package/dist/ports/index.js +1 -1
- package/dist/products/index.js +3 -4
- package/dist/promotions/index.js +3 -5
- package/dist/seo/index.d.ts +5 -11
- package/dist/seo/index.js +14 -24
- package/dist/seo/index.js.map +1 -1
- package/dist/snippets/index.d.ts +21 -15
- package/dist/snippets/index.js +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +3 -5
- package/dist/theme/index.d.ts +1 -11
- package/dist/theme/index.js +1 -1
- package/dist/utils/index.d.ts +26 -3
- package/dist/website-settings/index.d.ts +1 -1
- package/docs/consumer-setup.md +6 -2
- package/docs/ports.md +4 -0
- package/docs/releasing.md +8 -1
- package/package.json +7 -10
- package/dist/chunk-7FRMMCR5.js +0 -93
- package/dist/chunk-7FRMMCR5.js.map +0 -1
- package/dist/chunk-BWUKMWHL.js +0 -45
- package/dist/chunk-BWUKMWHL.js.map +0 -1
- package/dist/chunk-FFBZKQRV.js.map +0 -1
- package/dist/chunk-G2X4SBCO.js.map +0 -1
- package/dist/chunk-GLTOJTZO.js.map +0 -1
- package/dist/chunk-GW2QNTAD.js.map +0 -1
- package/dist/chunk-JLFBAAFT.js.map +0 -1
- package/dist/chunk-N3NOTJUC.js.map +0 -1
- package/dist/chunk-RYYY7MVP.js.map +0 -1
- package/dist/chunk-TEG7EL4N.js.map +0 -1
- package/dist/chunk-V3VVDQIR.js +0 -27
- package/dist/chunk-V3VVDQIR.js.map +0 -1
- package/dist/layout/index.d.ts +0 -54
- package/dist/layout/index.js +0 -106
- package/dist/layout/index.js.map +0 -1
- package/dist/schedule-Dd3zwHEb.d.ts +0 -27
- package/dist/snippets-BC5bkSjm.d.ts +0 -23
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,66 @@ All notable changes to this project are documented in this file. The format foll
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 0.10.4 - 2026-07-29
|
|
8
|
+
|
|
9
|
+
> **Breaking.** This release changes the runtime port contract and removes public
|
|
10
|
+
> exports. The version stays in the `0.10.x` range because the package has no stable
|
|
11
|
+
> release yet and has a single, already-migrated consumer. Read the migration notes
|
|
12
|
+
> below before upgrading.
|
|
13
|
+
|
|
14
|
+
### Migration
|
|
15
|
+
|
|
16
|
+
1. **Provide the `messages` port.** `StorefrontRuntime` now requires a
|
|
17
|
+
`MessageFormatter`. `createStorefront()` and `provideStorefront()` throw on start
|
|
18
|
+
when any required port is missing, instead of failing later inside a `catch` block.
|
|
19
|
+
Tests and headless consumers can pass `KEY_MESSAGE_FORMATTER`, which returns the key
|
|
20
|
+
itself.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { KEY_MESSAGE_FORMATTER } from '@zenky/storefront-vue/ports'
|
|
24
|
+
|
|
25
|
+
app.use(createStorefront({ ...runtime, messages: KEY_MESSAGE_FORMATTER }))
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. **Move removed symbols into your app.** Gone from their subpath *and* from the root
|
|
29
|
+
entry: `catalogRoutes` (`./catalog`), `THEME_PRESETS` / `DARK_THEME_PRESETS` /
|
|
30
|
+
`ThemePreset` (`./theme`), `buildSnippetHead` / `SnippetHead` (`./snippets`). Gone
|
|
31
|
+
from their subpath only: `withSeoMetaPriority` (`./seo`) and the entire `./layout`
|
|
32
|
+
subpath (`useHeaderData`, `useFooterData`) — neither was re-exported from the root.
|
|
33
|
+
|
|
34
|
+
3. **Pass `formatDayLabel` if you rely on localized day tabs.** Without it,
|
|
35
|
+
`generateFreeTimeGroups` labels days as `DD.MM`. This affects only free-slot mode —
|
|
36
|
+
in interval mode the day names come from the API.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- `check:boundaries` gate that fails the build when Nuxt, Unhead, route policy, or
|
|
41
|
+
tenant presets reappear in `src/`.
|
|
42
|
+
- Pull-request quality checks restored in CI.
|
|
43
|
+
|
|
44
|
+
### Removed
|
|
45
|
+
|
|
46
|
+
- The `./layout` subpath (`useHeaderData`, `useFooterData`, and the `HeaderData`,
|
|
47
|
+
`HeaderDataOptions`, `FooterData`, `FooterDataOptions`, `FormattedPhone`, `LegalLink`
|
|
48
|
+
types) — header and footer composition reads consumer config and belongs to the
|
|
49
|
+
consumer.
|
|
50
|
+
- `catalogRoutes` — catalog route policy is owned by the consumer.
|
|
51
|
+
- `withSeoMetaPriority` — `tagPriority` is Unhead-specific.
|
|
52
|
+
- `THEME_PRESETS`, `DARK_THEME_PRESETS`, `ThemePreset` — tenant branding.
|
|
53
|
+
- `buildSnippetHead`, `SnippetHead` — the head payload shape is framework-specific.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- Storefront runtime now requires a consumer-owned message formatter. Cart notification
|
|
58
|
+
copy is emitted as stable message keys instead of Russian literals. Error text
|
|
59
|
+
forwarded from the API is passed through untouched and stays in the language the
|
|
60
|
+
backend sent. Formatting helpers — weight units, schedule status, contact labels,
|
|
61
|
+
address parsing, pluralization — remain Russian-only and are tracked as known debt.
|
|
62
|
+
- Delivery slot labels are consumer-configurable and default to locale-neutral dates.
|
|
63
|
+
- SEO builders now return framework-neutral meta records without Unhead-specific fields.
|
|
64
|
+
- `@zenky/storefront-api` peer range moved to `^1.0.1`.
|
|
65
|
+
|
|
66
|
+
## 0.10.3 - 2026-07-24
|
|
8
67
|
|
|
9
68
|
### Added
|
|
10
69
|
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Peer dependencies (the consumer already has these):
|
|
|
21
21
|
{
|
|
22
22
|
"vue": "^3.5.0",
|
|
23
23
|
"pinia": "^3.0.0",
|
|
24
|
-
"@zenky/storefront-api": "
|
|
24
|
+
"@zenky/storefront-api": "^1.0.1",
|
|
25
25
|
"@zenky/integrations-sdk": ">=0.1.3"
|
|
26
26
|
}
|
|
27
27
|
```
|
|
@@ -48,6 +48,9 @@ app.use(
|
|
|
48
48
|
warning: (m) => toast.warning(m),
|
|
49
49
|
message: (title, opts) => toast(title, opts),
|
|
50
50
|
},
|
|
51
|
+
messages: { // consumer-owned localization
|
|
52
|
+
format: (key, params) => i18n.t(key, params),
|
|
53
|
+
},
|
|
51
54
|
activity: { // busy indicators for long operations
|
|
52
55
|
begin: (kind) => busy.begin(kind),
|
|
53
56
|
end: (kind) => busy.end(kind),
|
|
@@ -72,7 +75,7 @@ cart.totalPrice.value
|
|
|
72
75
|
|
|
73
76
|
## Runtime Ports
|
|
74
77
|
|
|
75
|
-
`createStorefront(runtime)` takes one object.
|
|
78
|
+
`createStorefront(runtime)` takes one object. Six ports are required; the rest are optional — omit an optional port and the feature that needs it is simply skipped.
|
|
76
79
|
|
|
77
80
|
| Port | Required | What the consumer provides |
|
|
78
81
|
| --- | --- | --- |
|
|
@@ -80,6 +83,7 @@ cart.totalPrice.value
|
|
|
80
83
|
| `config` | yes | `{ baseUrl, baseAuthUrl, salesChannelId? }`. |
|
|
81
84
|
| `storage` | yes | Key/value persistence — cookies, `localStorage`, memory. |
|
|
82
85
|
| `notifier` | yes | Toasts: `error` / `success` / `warning` / `message`. |
|
|
86
|
+
| `messages` | yes | Maps stable domain message keys to localized consumer copy. |
|
|
83
87
|
| `activity` | yes | `begin(kind)` / `end(kind)` for busy state. |
|
|
84
88
|
| `events` | no | Lazy `{ get() }` provider for `ZenkyIntegrationsSDK`; resolve on every event. |
|
|
85
89
|
| `realtime` | no | Lazy `{ get() }` provider for the WebSocket adapter (`subscribe` / `unsubscribe` / `isReady`). |
|
|
@@ -93,6 +97,7 @@ Types for every port live in the `ports` subpath, alongside no-op defaults and a
|
|
|
93
97
|
import {
|
|
94
98
|
type StorefrontRuntime,
|
|
95
99
|
type StorageAdapter,
|
|
100
|
+
KEY_MESSAGE_FORMATTER,
|
|
96
101
|
NOOP_NOTIFIER,
|
|
97
102
|
NOOP_ACTIVITY_REPORTER,
|
|
98
103
|
createMemoryStorage,
|
|
@@ -109,16 +114,19 @@ Each public domain is its own entry point, so bundlers only pull in what you imp
|
|
|
109
114
|
|
|
110
115
|
```ts
|
|
111
116
|
import { minorToMajor } from '@zenky/storefront-vue/money'
|
|
112
|
-
import { buildCssVariableMap
|
|
117
|
+
import { buildCssVariableMap } from '@zenky/storefront-vue/theme'
|
|
113
118
|
import { getRemoteCatalog, findCategoryByShortId } from '@zenky/storefront-vue/catalog'
|
|
114
119
|
import { useStorefrontCart, useCheckoutSubmit } from '@zenky/storefront-vue/cart'
|
|
115
120
|
import { generateFreeTimeGroups } from '@zenky/storefront-vue/order'
|
|
116
121
|
import { buildProductSchema, buildOgTags } from '@zenky/storefront-vue/seo'
|
|
117
|
-
import { useHeaderData, useFooterData } from '@zenky/storefront-vue/layout'
|
|
118
122
|
import { usePaginatedList } from '@zenky/storefront-vue/pagination'
|
|
119
123
|
```
|
|
120
124
|
|
|
121
|
-
Available subpaths: `ports`, `money`, `utils`, `theme`, `stores`, `products`, `catalog`, `cart`, `order`, `promotions`, `seo`, `
|
|
125
|
+
Available subpaths: `ports`, `money`, `utils`, `theme`, `stores`, `products`, `catalog`, `cart`, `order`, `promotions`, `seo`, `pagination`, `snippets`, `website-settings`.
|
|
126
|
+
|
|
127
|
+
Routing, tenant theme presets, localized copy, header/footer composition, and conversion to
|
|
128
|
+
framework-specific head records belong to the consumer. Core SEO builders return plain
|
|
129
|
+
records; a Nuxt adapter may add Unhead-specific fields such as `tagPriority`.
|
|
122
130
|
|
|
123
131
|
## Runtime Compatibility
|
|
124
132
|
|
|
@@ -177,6 +185,7 @@ npm test # vitest
|
|
|
177
185
|
npm run test:coverage # vitest + V8 coverage report
|
|
178
186
|
npm run check # format + lint + types + tests + build + exports
|
|
179
187
|
npm run check:exports # publint + are-the-types-wrong (esm-only profile)
|
|
188
|
+
npm run check:boundaries # reject Nuxt/Unhead and consumer policy in src/
|
|
180
189
|
npm run check:runtime # import all entries in SSR + reject Node-only output
|
|
181
190
|
npm run check:size # enforce gzip bundle budgets
|
|
182
191
|
```
|
|
@@ -203,6 +212,7 @@ npm run build && npx yalc push
|
|
|
203
212
|
- `test` / `test:watch` — run the Vitest suite.
|
|
204
213
|
- `typecheck` — type-only compile.
|
|
205
214
|
- `check:exports` — validate the exports map and published types.
|
|
215
|
+
- `check:boundaries` — reject Nuxt/Unhead APIs, routes, and tenant presets in core source.
|
|
206
216
|
- `check:runtime` — verify Node SSR imports and browser/edge-safe ESM output.
|
|
207
217
|
- `check:size` — enforce root/domain/all-output gzip budgets.
|
|
208
218
|
- `check:ci` — quality gate with the V8 coverage ratchet.
|
package/dist/cart/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
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-
|
|
2
|
-
export { useCartCredentials } from '../chunk-
|
|
3
|
-
import '../chunk-5QCUH3FF.js';
|
|
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-YS5DXYYV.js';
|
|
2
|
+
export { useCartCredentials } from '../chunk-YREGCQSB.js';
|
|
4
3
|
import '../chunk-Z3IW4ODZ.js';
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-TEG7EL4N.js';
|
|
4
|
+
import '../chunk-NIQFYJRP.js';
|
|
7
5
|
import '../chunk-E3G7NGCH.js';
|
|
8
|
-
import '../chunk-FFBZKQRV.js';
|
|
9
|
-
import '../chunk-V3VVDQIR.js';
|
|
10
6
|
import '../chunk-RO25KNM5.js';
|
|
7
|
+
import '../chunk-5QCUH3FF.js';
|
|
8
|
+
import '../chunk-TB5TBJ4U.js';
|
|
11
9
|
//# sourceMappingURL=index.js.map
|
|
12
10
|
//# sourceMappingURL=index.js.map
|
package/dist/catalog/index.d.ts
CHANGED
|
@@ -60,14 +60,4 @@ declare function useCollections(sdk: ZenkyStorefront): {
|
|
|
60
60
|
loadCollections: (storeId: string, request?: CollectionsListRequest) => Promise<ProductsCollection[]>;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
declare const catalogRoutes: {
|
|
65
|
-
/** Корневая страница каталога: список категорий + коллекций */
|
|
66
|
-
readonly index: () => string;
|
|
67
|
-
/** Страница конкретной категории */
|
|
68
|
-
readonly category: (shortId: string, slug: string | null) => string;
|
|
69
|
-
/** Страница конкретной коллекции */
|
|
70
|
-
readonly collection: (id: string) => string;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export { type GroupedProducts, type SubcategoryGroup, catalogRoutes, collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, getCity, getRemoteCatalog, getStock, groupProductsBySubcategory, useCollections };
|
|
63
|
+
export { type GroupedProducts, type SubcategoryGroup, collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, getCity, getRemoteCatalog, getStock, groupProductsBySubcategory, useCollections };
|
package/dist/catalog/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, groupProductsBySubcategory, useCollections } from '../chunk-NG7RUIWW.js';
|
|
2
2
|
export { getCity, getRemoteCatalog, getStock } from '../chunk-E3G7NGCH.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/snippets/snippets.ts
|
|
2
|
+
function normalizeSnippets(groups) {
|
|
3
|
+
if (!Array.isArray(groups)) return [];
|
|
4
|
+
return groups.flatMap(
|
|
5
|
+
(group, groupIndex) => (group.snippets ?? []).filter((item) => !!item.content?.trim()).map((item, itemIndex) => {
|
|
6
|
+
const snippet = {
|
|
7
|
+
id: `${group.region}-${groupIndex}-${itemIndex}`,
|
|
8
|
+
position: group.region,
|
|
9
|
+
language: item.language,
|
|
10
|
+
code: item.content,
|
|
11
|
+
enabled: item.enabled ?? true
|
|
12
|
+
};
|
|
13
|
+
if (item.name !== void 0) snippet.name = item.name;
|
|
14
|
+
return snippet;
|
|
15
|
+
})
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { normalizeSnippets };
|
|
20
|
+
//# sourceMappingURL=chunk-2CI4RW7V.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-2CI4RW7V.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/snippets/snippets.ts"],"names":[],"mappings":";AAwBO,SAAS,kBAAkB,MAAA,EAAsD;AACpF,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAA,CAAO,OAAA;AAAA,IAAQ,CAAC,OAAO,UAAA,KAAA,CACzB,KAAA,CAAM,YAAY,EAAC,EACf,OAAO,CAAC,IAAA,KAAS,CAAC,CAAC,IAAA,CAAK,SAAS,IAAA,EAAM,EACvC,GAAA,CAAI,CAAC,MAAM,SAAA,KAAuB;AAC/B,MAAA,MAAM,OAAA,GAAmB;AAAA,QACrB,IAAI,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,CAAA,EAAI,UAAU,IAAI,SAAS,CAAA,CAAA;AAAA,QAC9C,UAAU,KAAA,CAAM,MAAA;AAAA,QAChB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,MAAM,IAAA,CAAK,OAAA;AAAA,QACX,OAAA,EAAS,KAAK,OAAA,IAAW;AAAA,OAC7B;AAEA,MAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,EAAW,OAAA,CAAQ,OAAO,IAAA,CAAK,IAAA;AACjD,MAAA,OAAO,OAAA;AAAA,IACX,CAAC;AAAA,GACT;AACJ","file":"chunk-2CI4RW7V.js","sourcesContent":["export type SnippetPosition = 'head_start' | 'head_end' | 'body_start' | 'body_end'\nexport type SnippetLanguage = 'html' | 'css' | 'javascript'\n\nexport interface Snippet {\n id: string\n name?: string\n position: SnippetPosition\n language: SnippetLanguage\n code: string\n enabled: boolean\n}\n\nexport interface RawSnippetItem {\n language: SnippetLanguage\n content: string\n enabled?: boolean\n name?: string\n}\n\nexport interface SnippetGroup {\n region: SnippetPosition\n snippets: RawSnippetItem[]\n}\n\nexport function normalizeSnippets(groups: SnippetGroup[] | null | undefined): Snippet[] {\n if (!Array.isArray(groups)) return []\n\n return groups.flatMap((group, groupIndex) =>\n (group.snippets ?? [])\n .filter((item) => !!item.content?.trim())\n .map((item, itemIndex): Snippet => {\n const snippet: Snippet = {\n id: `${group.region}-${groupIndex}-${itemIndex}`,\n position: group.region,\n language: item.language,\n code: item.content,\n enabled: item.enabled ?? true,\n }\n // exactOptionalPropertyTypes: name задаём только если оно есть\n if (item.name !== undefined) snippet.name = item.name\n return snippet\n })\n )\n}\n"]}
|
|
@@ -212,116 +212,6 @@ function useTheme(colorConfig, fontConfig) {
|
|
|
212
212
|
};
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
id: "yarollov",
|
|
219
|
-
label: "Yarollov",
|
|
220
|
-
description: "\u0424\u0438\u0440\u043C\u0435\u043D\u043D\u044B\u0439 \u0431\u0440\u0435\u043D\u0434 \u2014 \u043C\u0430\u043B\u0438\u043D\u043E\u0432\u044B\u0439 primary, \u0442\u0451\u043C\u043D\u043E-\u0441\u0438\u043D\u0438\u0439 accent",
|
|
221
|
-
colors: {
|
|
222
|
-
primary: "#D81C4B",
|
|
223
|
-
secondary: "#8272C1",
|
|
224
|
-
accent: "#1E1B4B",
|
|
225
|
-
background: "#FFFFFF",
|
|
226
|
-
text: "#1A1A1A"
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
id: "orange",
|
|
231
|
-
label: "Orange",
|
|
232
|
-
description: "\u0422\u0451\u043F\u043B\u044B\u0439 \u043E\u0440\u0430\u043D\u0436\u0435\u0432\u044B\u0439 \u0441 \u0441\u0438\u043D\u0438\u043C \u0430\u043A\u0446\u0435\u043D\u0442\u043E\u043C",
|
|
233
|
-
colors: {
|
|
234
|
-
primary: "#FE5000",
|
|
235
|
-
secondary: "#64748B",
|
|
236
|
-
accent: "#007AFF",
|
|
237
|
-
background: "#FFFFFF",
|
|
238
|
-
text: "#1A1A1A"
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
{
|
|
242
|
-
id: "sushi03",
|
|
243
|
-
label: "Sushi03",
|
|
244
|
-
description: "\u0422\u0451\u043C\u043D\u043E-\u0441\u0438\u043D\u0438\u0439 primary + \u0433\u043E\u0440\u0447\u0438\u0447\u043D\u044B\u0439 accent",
|
|
245
|
-
colors: {
|
|
246
|
-
primary: "#002F8C",
|
|
247
|
-
secondary: "#8B9DC3",
|
|
248
|
-
accent: "#FFDE69",
|
|
249
|
-
background: "#FFFFFF",
|
|
250
|
-
text: "#1A1A1A",
|
|
251
|
-
success: "#00A980",
|
|
252
|
-
danger: "#E61717"
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
id: "olive",
|
|
257
|
-
label: "Olive Whisper",
|
|
258
|
-
description: "\u041A\u0438\u0441\u043B\u043E\u0442\u043D\u043E-\u0437\u0435\u043B\u0451\u043D\u044B\u0439 \u043D\u0430 \u0442\u0451\u043C\u043D\u043E\u043C \u0444\u043E\u043D\u0435",
|
|
259
|
-
colors: {
|
|
260
|
-
primary: "#C0F53D",
|
|
261
|
-
secondary: "#0A0D04",
|
|
262
|
-
accent: "#C0F53D",
|
|
263
|
-
background: "#1A2209",
|
|
264
|
-
text: "#FAFFF3",
|
|
265
|
-
headerBg: "#1A2209",
|
|
266
|
-
footerBg: "#0A0D04",
|
|
267
|
-
footerText: "#FAFFF3",
|
|
268
|
-
footerTextMuted: "#6B7A4A"
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
];
|
|
272
|
-
var DARK_THEME_PRESETS = [
|
|
273
|
-
{
|
|
274
|
-
id: "yarollov-dark",
|
|
275
|
-
label: "Yarollov Dark",
|
|
276
|
-
description: "\u0424\u0438\u0440\u043C\u0435\u043D\u043D\u044B\u0439 \u0431\u0440\u0435\u043D\u0434 (\u0442\u0451\u043C\u043D\u0430\u044F)",
|
|
277
|
-
colors: {
|
|
278
|
-
primary: "#F472B6",
|
|
279
|
-
secondary: "#A78BFA",
|
|
280
|
-
accent: "#818CF8",
|
|
281
|
-
background: "#121212",
|
|
282
|
-
text: "#E5E5E5",
|
|
283
|
-
headerBg: "#1A1A1A",
|
|
284
|
-
footerBg: "#0F0F0F",
|
|
285
|
-
footerText: "#A3A3A3",
|
|
286
|
-
footerTextMuted: "#525252"
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
id: "orange-dark",
|
|
291
|
-
label: "Orange Dark",
|
|
292
|
-
description: "\u0422\u0451\u043F\u043B\u044B\u0439 \u043E\u0440\u0430\u043D\u0436\u0435\u0432\u044B\u0439 (\u0442\u0451\u043C\u043D\u0430\u044F)",
|
|
293
|
-
colors: {
|
|
294
|
-
primary: "#FE5000",
|
|
295
|
-
secondary: "#64748B",
|
|
296
|
-
accent: "#60A5FA",
|
|
297
|
-
background: "#121212",
|
|
298
|
-
text: "#E5E5E5",
|
|
299
|
-
headerBg: "#1A1A1A",
|
|
300
|
-
footerBg: "#0F0F0F",
|
|
301
|
-
footerText: "#A3A3A3",
|
|
302
|
-
footerTextMuted: "#525252"
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
id: "sushi03-dark",
|
|
307
|
-
label: "Sushi03 Dark",
|
|
308
|
-
description: "\u0422\u0451\u043C\u043D\u043E-\u0441\u0438\u043D\u0438\u0439 (\u0442\u0451\u043C\u043D\u0430\u044F)",
|
|
309
|
-
colors: {
|
|
310
|
-
primary: "#4D8DE8",
|
|
311
|
-
secondary: "#5A6D8A",
|
|
312
|
-
accent: "#FFDE69",
|
|
313
|
-
background: "#0F1419",
|
|
314
|
-
text: "#E5E5E5",
|
|
315
|
-
success: "#34D399",
|
|
316
|
-
danger: "#F87171",
|
|
317
|
-
headerBg: "#161C24",
|
|
318
|
-
footerBg: "#0A0F14",
|
|
319
|
-
footerText: "#94A3B8",
|
|
320
|
-
footerTextMuted: "#475569"
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
];
|
|
324
|
-
|
|
325
|
-
export { DARK_THEME_PRESETS, THEME_PRESETS, buildCssVariableMap, generatePrimaryShades, generateShades, useTheme };
|
|
326
|
-
//# sourceMappingURL=chunk-GW2QNTAD.js.map
|
|
327
|
-
//# sourceMappingURL=chunk-GW2QNTAD.js.map
|
|
215
|
+
export { buildCssVariableMap, generatePrimaryShades, generateShades, useTheme };
|
|
216
|
+
//# sourceMappingURL=chunk-4IFPVEO7.js.map
|
|
217
|
+
//# sourceMappingURL=chunk-4IFPVEO7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/theme/colors.ts","../src/theme/useTheme.ts"],"names":["p","q"],"mappings":"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","file":"chunk-4IFPVEO7.js","sourcesContent":["// Генерация цветовой шкалы и CSS-переменных из базовых цветов бренда.\n// Чистая математика в HSL/RGB — ноль зависимостей, ноль Nuxt. Портируется как есть.\n\nexport interface ThemeColorConfig {\n primary: string\n secondary: string\n accent: string\n background: string\n text: string\n success?: string\n danger?: string\n warning?: string\n info?: string\n /** Цвет текста поверх primary-фона. Если не задан — рассчитывается автоматически. */\n onPrimary?: string\n headerBg?: string\n footerBg?: string\n footerText?: string\n footerTextMuted?: string\n}\n\ninterface HslColor {\n h: number\n s: number\n l: number\n}\n\nfunction hexToHsl(hex: string): HslColor {\n const clean = hex.replace('#', '')\n const r = parseInt(clean.substring(0, 2), 16) / 255\n const g = parseInt(clean.substring(2, 4), 16) / 255\n const b = parseInt(clean.substring(4, 6), 16) / 255\n\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const l = (max + min) / 2\n\n if (max === min) {\n return { h: 0, s: 0, l }\n }\n\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\n\n let h = 0\n\n if (max === r) {\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n } else if (max === g) {\n h = ((b - r) / d + 2) / 6\n } else {\n h = ((r - g) / d + 4) / 6\n }\n\n return { h, s, l }\n}\n\nfunction hslToHex(hsl: HslColor): string {\n const { h, s, l } = hsl\n\n if (s === 0) {\n const v = Math.round(l * 255)\n return `#${v.toString(16).padStart(2, '0').repeat(3)}`\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n let tt = t\n\n if (tt < 0) tt += 1\n if (tt > 1) tt -= 1\n if (tt < 1 / 6) return p + (q - p) * 6 * tt\n if (tt < 1 / 2) return q\n if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6\n\n return p\n }\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n\n const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255)\n const g = Math.round(hue2rgb(p, q, h) * 255)\n const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255)\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`\n}\n\n// ---------------------------------------------------------------------------\n// Color utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Mix two hex colors in HSL space.\n * amount: 0 = pure hex1, 100 = pure hex2.\n */\nfunction mixColors(hex1: string, hex2: string, amount: number): string {\n const c1 = hexToHsl(hex1)\n const c2 = hexToHsl(hex2)\n const t = amount / 100\n\n // Handle achromatic mixing: if one color has no saturation,\n // inherit hue from the other\n let h: number\n if (c1.s === 0 && c2.s === 0) {\n h = 0\n } else if (c1.s === 0) {\n h = c2.h\n } else if (c2.s === 0) {\n h = c1.h\n } else {\n // Shortest path around the hue circle\n let dh = c2.h - c1.h\n if (dh > 0.5) dh -= 1\n if (dh < -0.5) dh += 1\n h = c1.h + dh * t\n if (h < 0) h += 1\n if (h > 1) h -= 1\n }\n\n return hslToHex({\n h,\n s: c1.s + (c2.s - c1.s) * t,\n l: c1.l + (c2.l - c1.l) * t,\n })\n}\n\n/**\n * Mix two hex colors in linear RGB space — matches CSS `linear-gradient` overlay behavior.\n * amount: 0 = pure hex1, 100 = pure hex2.\n */\nfunction mixColorsRgb(hex1: string, hex2: string, amount: number): string {\n const c1 = hex1.replace('#', '')\n const c2 = hex2.replace('#', '')\n const t = amount / 100\n\n const r1 = parseInt(c1.substring(0, 2), 16)\n const g1 = parseInt(c1.substring(2, 4), 16)\n const b1 = parseInt(c1.substring(4, 6), 16)\n const r2 = parseInt(c2.substring(0, 2), 16)\n const g2 = parseInt(c2.substring(2, 4), 16)\n const b2 = parseInt(c2.substring(4, 6), 16)\n\n const r = Math.round(r1 + (r2 - r1) * t)\n const g = Math.round(g1 + (g2 - g1) * t)\n const b = Math.round(b1 + (b2 - b1) * t)\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`\n}\n\n/**\n * Adjust lightness of a hex color by a relative percentage.\n * delta: -0.05 = 5% darker, +0.05 = 5% lighter.\n */\nfunction adjustLightness(hex: string, delta: number): string {\n const hsl = hexToHsl(hex)\n return hslToHex({\n h: hsl.h,\n s: hsl.s,\n l: Math.min(1, Math.max(0, hsl.l + delta)),\n })\n}\n\n/**\n * Returns a contrasting text color (white or dark) for a given background hex.\n * Uses relative luminance formula (WCAG).\n */\nfunction getContrastColor(hex: string): string {\n const clean = hex.replace('#', '')\n const r = parseInt(clean.substring(0, 2), 16) / 255\n const g = parseInt(clean.substring(2, 4), 16) / 255\n const b = parseInt(clean.substring(4, 6), 16) / 255\n\n // sRGB to linear\n const toLinear = (c: number): number =>\n c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4\n const luminance = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b)\n\n return luminance > 0.4 ? '#1a1a1a' : '#ffffff'\n}\n\n// ---------------------------------------------------------------------------\n// Primary shades\n// ---------------------------------------------------------------------------\n\nexport interface PrimaryShades {\n lightest: string\n lighter: string\n light: string\n base: string\n dark: string\n darker: string\n darkest: string\n tint: string\n tintHover: string\n tintPressed: string\n ink: string\n}\n\n/** Универсальный генератор 11-ступенчатой шкалы от одного hex. */\nexport function generateShades(\n hex: string,\n bg: string = '#ffffff',\n text: string = '#000000'\n): PrimaryShades {\n return generatePrimaryShades(hex, bg, text)\n}\n\nexport function generatePrimaryShades(\n hex: string,\n bg: string = '#ffffff',\n text: string = '#000000'\n): PrimaryShades {\n const hsl = hexToHsl(hex)\n\n const clamp = (v: number): number => Math.min(1, Math.max(0, v))\n\n // For very dark colors (l < 0.15), dark shades go UP (lighten)\n // because you can't darken black — multiplying 0 by anything stays 0\n const isVeryDark = hsl.l < 0.15\n const dark = isVeryDark ? clamp(hsl.l + 0.12) : clamp(hsl.l * 0.85)\n const darker = isVeryDark ? clamp(hsl.l + 0.08) : clamp(hsl.l * 0.65)\n const darkest = isVeryDark ? clamp(hsl.l + 0.05) : clamp(hsl.l * 0.45)\n\n return {\n lightest: hslToHex({ h: hsl.h, s: hsl.s * 0.3, l: clamp(0.92) }),\n lighter: hslToHex({ h: hsl.h, s: hsl.s * 0.5, l: clamp(0.8) }),\n light: hslToHex({ h: hsl.h, s: hsl.s * 0.7, l: clamp(hsl.l + (1 - hsl.l) * 0.4) }),\n base: hex,\n dark: hslToHex({ h: hsl.h, s: hsl.s, l: dark }),\n darker: hslToHex({ h: hsl.h, s: hsl.s, l: darker }),\n darkest: hslToHex({ h: hsl.h, s: hsl.s, l: darkest }),\n tint: mixColorsRgb(bg, hex, 14),\n tintHover: mixColorsRgb(mixColorsRgb(bg, hex, 14), bg, 34),\n tintPressed: mixColorsRgb(bg, hex, 5),\n ink: mixColorsRgb(text, hex, 44),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Build complete CSS variable map from core colors\n// ---------------------------------------------------------------------------\n\nexport function buildCssVariableMap(config: ThemeColorConfig): Record<string, string> {\n const bg = config.background\n const text = config.text\n const shades = generatePrimaryShades(config.primary, bg, text)\n const secondaryShades = generateShades(config.secondary, bg, text)\n\n const vars: Record<string, string> = {\n // Primary palette\n '--zenky-primary-lightest': shades.lightest,\n '--zenky-primary-lighter': shades.lighter,\n '--zenky-primary-light': shades.light,\n '--zenky-primary': shades.base,\n '--zenky-primary-dark': shades.dark,\n '--zenky-primary-darker': shades.darker,\n '--zenky-primary-darkest': shades.darkest,\n '--zenky-primary-tint': shades.tint,\n '--zenky-primary-tint-hover': shades.tintHover,\n '--zenky-primary-tint-pressed': shades.tintPressed,\n '--zenky-primary-ink': shades.ink,\n\n // Secondary palette\n '--zenky-secondary-lightest': secondaryShades.lightest,\n '--zenky-secondary-lighter': secondaryShades.lighter,\n '--zenky-secondary-light': secondaryShades.light,\n '--zenky-secondary': secondaryShades.base,\n '--zenky-secondary-dark': secondaryShades.dark,\n '--zenky-secondary-darker': secondaryShades.darker,\n '--zenky-secondary-darkest': secondaryShades.darkest,\n\n // Auto-contrast for secondary\n '--zenky-on-secondary': getContrastColor(config.secondary),\n\n // Accent\n '--zenky-accent': config.accent,\n '--zenky-accent-tint': mixColorsRgb(bg, config.accent, 14),\n '--zenky-accent-tint-hover': mixColorsRgb(mixColorsRgb(bg, config.accent, 14), bg, 34),\n '--zenky-accent-tint-pressed': mixColorsRgb(bg, config.accent, 5),\n '--zenky-accent-ink': mixColorsRgb(text, config.accent, 44),\n '--zenky-bg': bg,\n '--zenky-text': text,\n\n // Цвет текста поверх primary: ручная настройка или авто-контраст\n '--zenky-on-primary': config.onPrimary || getContrastColor(config.primary),\n '--zenky-on-accent': getContrastColor(config.accent),\n\n // Derived text shades\n '--zenky-text-muted': mixColors(bg, text, 50),\n '--zenky-text-light': mixColors(bg, text, 35),\n\n // Derived borders\n '--zenky-border-light': mixColors(bg, text, 6),\n '--zenky-border': mixColors(bg, text, 12),\n '--zenky-border-strong': mixColors(bg, text, 35),\n\n // Derived surfaces\n '--zenky-surface-secondary': mixColors(bg, text, 5),\n '--zenky-surface-secondary-hover': mixColors(bg, text, 10),\n '--zenky-surface-active': mixColors(bg, config.primary, 8),\n '--zenky-surface-dark':\n getContrastColor(bg) === '#ffffff'\n ? adjustLightness(bg, 0.08)\n : adjustLightness(text, -0.1),\n '--zenky-control-active': mixColors(bg, text, 80),\n '--zenky-surface-elevated': adjustLightness(bg, 0.06),\n\n // Status (defaults if not provided)\n '--zenky-success': config.success ?? '#22c55e',\n '--zenky-danger': config.danger ?? '#ef4444',\n '--zenky-warning': config.warning ?? '#f59e0b',\n '--zenky-info': config.info ?? '#3b82f6',\n\n // Component semantic (auto-derived with optional overrides)\n '--zenky-header-bg': config.headerBg ?? adjustLightness(bg, -0.02),\n '--zenky-nav-bg': config.headerBg ?? adjustLightness(bg, -0.02),\n '--zenky-footer-bg': config.footerBg ?? adjustLightness(bg, -0.03),\n '--zenky-footer-text': config.footerText ?? mixColors(bg, text, 70),\n '--zenky-footer-text-muted': config.footerTextMuted ?? mixColors(bg, text, 40),\n }\n\n return vars\n}\n","import { computed, type ComputedRef } from 'vue'\n\nimport { buildCssVariableMap, type ThemeColorConfig } from './colors'\n\nexport interface FontConfig {\n family: string\n url: string\n}\n\nexport interface ThemeData {\n cssVariables: ComputedRef<Record<string, string>>\n fontFamily: ComputedRef<string | null>\n fontUrl: ComputedRef<string | null>\n}\n\n/** CSS-переменные темы + шрифт из цвето-/шрифто-конфига (инъекция в head — на стороне app). */\nexport function useTheme(colorConfig: ThemeColorConfig, fontConfig: FontConfig): ThemeData {\n const cssVariables = computed<Record<string, string>>(() => {\n const vars = buildCssVariableMap(colorConfig)\n\n if (fontConfig.family) {\n const stack = `'${fontConfig.family}', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif`\n vars['--zenky-font-sans'] = stack\n }\n\n return vars\n })\n\n const fontFamily = computed<string | null>(() => fontConfig.family || null)\n const fontUrl = computed<string | null>(() => fontConfig.url || null)\n\n return {\n cssVariables,\n fontFamily,\n fontUrl,\n }\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { createRuntimeState } from './chunk-5QCUH3FF.js';
|
|
2
|
-
import { useStoreProfileStore, useAuthStore } from './chunk-TEG7EL4N.js';
|
|
3
1
|
import { createDebounce } from './chunk-XUGXLJZB.js';
|
|
4
|
-
import {
|
|
2
|
+
import { createRuntimeState } from './chunk-5QCUH3FF.js';
|
|
3
|
+
import { useRuntime, useStoreProfileStore, useAuthStore } from './chunk-TB5TBJ4U.js';
|
|
5
4
|
import { UnitType } from '@zenky/storefront-api';
|
|
6
5
|
import { computed, ref, watch } from 'vue';
|
|
7
6
|
|
|
@@ -562,5 +561,5 @@ function findProductInCatalog(catalog, shortId) {
|
|
|
562
561
|
}
|
|
563
562
|
|
|
564
563
|
export { canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts };
|
|
565
|
-
//# sourceMappingURL=chunk-
|
|
566
|
-
//# sourceMappingURL=chunk-
|
|
564
|
+
//# sourceMappingURL=chunk-IVG4FQE5.js.map
|
|
565
|
+
//# sourceMappingURL=chunk-IVG4FQE5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/products/formatWeight.ts","../src/products/useProductsByCategory.ts","../src/products/useProductVariantModifiers.ts","../src/products/useProductPricing.ts","../src/products/useProductVariant.ts","../src/products/usePriceRecalculation.ts","../src/products/useProductVariantSelector.ts","../src/products/useRelatedProducts.ts","../src/products/findProductInCatalog.ts"],"names":["computed","ref","watch"],"mappings":"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","file":"chunk-IVG4FQE5.js","sourcesContent":["import { UnitType } from '@zenky/storefront-api'\n\nimport type { Product, ProductVariant } from '@zenky/storefront-api'\n\nconst UNIT_LABELS: Record<UnitType, string> = {\n [UnitType.Gram]: 'г',\n [UnitType.Kilogram]: 'кг',\n [UnitType.Meter]: 'м',\n [UnitType.Piece]: 'г',\n} as const\n\nfunction getWeightFromDimensions(variants: ProductVariant[] | undefined): number | null {\n if (!variants?.length) return null\n\n const dimension = variants[0]?.dimensions?.find((d) => d.dimension === 'weight')\n\n return dimension?.value ?? null\n}\n\nexport function getVariantWeight(variant: ProductVariant | null | undefined): number | null {\n if (!variant) return null\n\n return variant.dimensions?.find((d) => d.dimension === 'weight')?.value ?? null\n}\n\nexport function getProductWeight(product: Product): number | null {\n return product.weight ?? getWeightFromDimensions(product.variants) ?? null\n}\n\nexport function toGrams(weight: number | null, unitType: UnitType): number | null {\n if (!weight) {\n return null\n }\n\n if (unitType === UnitType.Kilogram) {\n return weight * 1000\n }\n\n if (unitType === UnitType.Meter) {\n return null\n }\n\n return weight\n}\n\nexport function formatWeight(weight: number | null, unitType: UnitType): string | null {\n if (!weight) {\n return null\n }\n\n const label = UNIT_LABELS[unitType]\n\n return `${weight} ${label}`\n}\n","import { computed, type ComputedRef } from 'vue'\n\nimport type { NestedCategory, Product } from '@zenky/storefront-api'\n\nexport interface CategoryWithProducts {\n id: string\n shortId: string\n slug: string | null\n name: string | null\n products: Product[]\n}\n\nexport function useProductsByCategory(\n products: ComputedRef<Product[]>,\n categories: ComputedRef<NestedCategory[]>\n): {\n grouped: ComputedRef<CategoryWithProducts[]>\n} {\n const grouped = computed<CategoryWithProducts[]>(() => {\n if (!categories.value.length || !products.value.length) {\n return []\n }\n\n const productsByCategory = new Map<string, Product[]>()\n\n for (const product of products.value) {\n for (const category of product.categories) {\n const existing = productsByCategory.get(category.id) ?? []\n existing.push(product)\n productsByCategory.set(category.id, existing)\n }\n }\n\n return flattenCategories(categories.value)\n .filter((category) => productsByCategory.has(category.id))\n .map((category) => ({\n id: category.id,\n shortId: category.short_id,\n slug: category.slug,\n name: category.name,\n products: productsByCategory.get(category.id) ?? [],\n }))\n })\n\n return { grouped }\n}\n\nfunction flattenCategories(categories: NestedCategory[]): NestedCategory[] {\n const result: NestedCategory[] = []\n\n for (const category of categories) {\n result.push(category)\n\n if (category.children?.length) {\n result.push(...flattenCategories(category.children))\n }\n }\n\n return result\n}\n","import { computed, ref, watch, type ComputedRef, type Ref } from 'vue'\n\nimport type { ProductModifiersRequest, ProductVariant } from '@zenky/storefront-api'\n\nfunction getInitialModifiersModel(variant: ProductVariant | null): ProductModifiersRequest[] {\n if (!variant?.default_modifiers?.modifiers.length) {\n return []\n }\n\n return variant.default_modifiers.modifiers.map((modifier) => ({\n modifier_id: modifier.modifier_id,\n modifiers_group_id: modifier.modifiers_group_id,\n quantity: modifier.quantity,\n }))\n}\n\nexport function useProductVariantModifiers(variant: ComputedRef<ProductVariant | null>): {\n modifiersModel: Ref<ProductModifiersRequest[]>\n selectedModifiersHash: Ref<string | null>\n hasAnyModifier: ComputedRef<boolean>\n} {\n const modifiersModel: Ref<ProductModifiersRequest[]> = ref([\n ...getInitialModifiersModel(variant.value),\n ])\n const selectedModifiersHash: Ref<string | null> = ref(null)\n const hasAnyModifier = computed<boolean>(() => modifiersModel.value.length > 0)\n\n watch(variant, () => {\n const newDefaults = getInitialModifiersModel(variant.value)\n\n // Сохраняем standalone модификаторы (без группы) — они продуктовые, не зависят от варианта.\n // Групповые модификаторы сбрасываются до дефолтов нового варианта.\n const userStandalone = modifiersModel.value.filter((m) => !m.modifiers_group_id)\n const defaultStandaloneIds = new Set(\n newDefaults.filter((d) => !d.modifiers_group_id).map((d) => d.modifier_id)\n )\n const preservedStandalone = userStandalone.filter(\n (m) => !defaultStandaloneIds.has(m.modifier_id)\n )\n\n modifiersModel.value = [...preservedStandalone, ...newDefaults]\n })\n\n return { modifiersModel, selectedModifiersHash, hasAnyModifier }\n}\n","import { computed, type ComputedRef } from 'vue'\n\nimport type { Discount, Product, ProductVariant } from '@zenky/storefront-api'\n\nexport interface ResolvedPrice {\n price: number\n originalPrice: number | null\n discount: Discount | null\n}\n\n/**\n * Определяет цену варианта с учётом склада.\n * Приоритет: prices[stockId] → prices[null] → top-level price.\n */\nexport function resolveVariantPrice(\n variant: ProductVariant,\n stockId?: string | null\n): ResolvedPrice {\n if (variant.prices?.length) {\n // 1. Точное совпадение по складу\n if (stockId) {\n const stockEntry = variant.prices.find((p) => p.stock_id === stockId)\n\n if (stockEntry) {\n return {\n price: stockEntry.price,\n originalPrice: stockEntry.original_price,\n discount: stockEntry.discount,\n }\n }\n }\n\n // 2. Глобальная цена (stock_id = null)\n const globalEntry = variant.prices.find((p) => p.stock_id === null)\n\n if (globalEntry) {\n return {\n price: globalEntry.price,\n originalPrice: globalEntry.original_price,\n discount: globalEntry.discount,\n }\n }\n }\n\n // 3. Fallback — top-level поля варианта\n return {\n price: variant.price,\n originalPrice: variant.original_price ?? null,\n discount: variant.discount ?? null,\n }\n}\n\nexport function useProductPricing(\n product: ComputedRef<Product>,\n stockId?: ComputedRef<string | null | undefined>\n): {\n displayPrice: ComputedRef<number>\n originalDisplayPrice: ComputedRef<number | null>\n hasDifferentPrices: ComputedRef<boolean>\n needsSelection: ComputedRef<boolean>\n} {\n const variants = computed(() => product.value.variants ?? [])\n const currentStockId = computed(() => stockId?.value ?? null)\n\n // Цены всех вариантов с учётом склада\n const resolvedPrices = computed(() =>\n variants.value.map((v) => resolveVariantPrice(v, currentStockId.value))\n )\n\n // Минимальная обязательная стоимость модификаторов, которая всегда добавляется к цене:\n // 1. modEntry.is_required — модификатор всегда присылается в API (нельзя убрать)\n // 2. groupEntry.is_required — пользователь обязан выбрать хотя бы один из группы →\n // добавляем минимальную цену из группы (если группа не покрыта is_required-модификатором)\n const minRequiredModifiersCost = computed<number>(() => {\n let total = 0\n\n for (const groupEntry of product.value.modifiers_groups ?? []) {\n const group = groupEntry.group\n\n // Обязательные модификаторы внутри группы — всегда добавляются в заказ\n for (const modEntry of group.modifiers) {\n if (modEntry.is_required && modEntry.modifier.price) {\n total += modEntry.modifier.price * Math.max(modEntry.min_quantity ?? 0, 1)\n }\n }\n\n if (\n groupEntry.is_required &&\n group.modifiers.length &&\n !group.modifiers.some((m) => m.is_required)\n ) {\n const cheapest = group.modifiers.reduce((min, m) =>\n (m.modifier.price ?? 0) < (min.modifier.price ?? 0) ? m : min\n )\n total += (cheapest.modifier.price ?? 0) * Math.max(cheapest.min_quantity ?? 0, 1)\n }\n }\n\n return total\n })\n\n const displayPrice = computed<number>(() => {\n if (!resolvedPrices.value.length) {\n return 0\n }\n\n return (\n Math.min(...resolvedPrices.value.map((r) => r.price)) + minRequiredModifiersCost.value\n )\n })\n\n // Цена без скидки: original_price минимального по цене варианта + обязательные модификаторы.\n // null если скидки нет.\n // original_price может быть null даже при наличии скидки — тогда вычисляем через discount.difference.\n const originalDisplayPrice = computed<number | null>(() => {\n if (!resolvedPrices.value.length) return null\n\n // Находим вариант с минимальной ценой (тот же, что определяет displayPrice)\n const cheapest = resolvedPrices.value.reduce((min, r) => (r.price < min.price ? r : min))\n\n // Приоритет: original_price, затем вычисление через discount\n let originalVariantPrice: number | null = null\n\n if (cheapest.originalPrice && cheapest.originalPrice > cheapest.price) {\n originalVariantPrice = cheapest.originalPrice\n } else if (cheapest.discount && cheapest.discount.difference > 0) {\n originalVariantPrice = cheapest.price + cheapest.discount.difference\n }\n\n if (!originalVariantPrice) return null\n\n return originalVariantPrice + minRequiredModifiersCost.value\n })\n\n const hasDifferentPrices = computed<boolean>(() => {\n if (resolvedPrices.value.length <= 1) {\n return false\n }\n\n const prices = new Set(resolvedPrices.value.map((r) => r.price))\n\n return prices.size > 1\n })\n\n const needsSelection = computed<boolean>(() => {\n if (variants.value.length > 1) {\n return true\n }\n\n const mods = product.value.modifiers\n const groups = product.value.modifiers_groups\n\n return (\n (Array.isArray(mods) && mods.length > 0) || (Array.isArray(groups) && groups.length > 0)\n )\n })\n\n return { displayPrice, originalDisplayPrice, hasDifferentPrices, needsSelection }\n}\n","import { computed, ref, watch, type ComputedRef, type Ref } from 'vue'\n\nimport type {\n Product,\n ProductVariant,\n ProductVariantOption,\n ProductVariantOptionValue,\n} from '@zenky/storefront-api'\n\nexport interface ProductVariantOptionListItem {\n id: string\n name: string | null\n values: ProductVariantOptionValue[]\n}\n\nfunction getDefaultOptionsModel(product: Product): Record<string, string> {\n const model: Record<string, string> = {}\n\n if (!product.variants?.length) {\n return model\n }\n\n const firstVariantOptions = product.variants.find(\n (variant: ProductVariant) => variant.options?.length\n )?.options\n\n if (!firstVariantOptions) {\n return model\n }\n\n firstVariantOptions.forEach((option: ProductVariantOption) => {\n model[option.id] = option.value.id\n })\n\n return model\n}\n\nfunction getProductVariantOptionsList(product: Product): ProductVariantOptionListItem[] {\n const list: ProductVariantOptionListItem[] = []\n\n if (!product.variants?.length) {\n return list\n }\n\n product.variants.forEach((variant: ProductVariant) => {\n if (!variant.options?.length) {\n return\n }\n\n variant.options.forEach((option: ProductVariantOption) => {\n let index = list.findIndex(\n (item: ProductVariantOptionListItem) => item.id === option.id\n )\n\n if (index === -1) {\n index = list.push({\n id: option.id,\n name: option.name,\n values: [],\n })\n\n index--\n }\n\n const valueIndex = list[index]!.values.findIndex(\n (value: ProductVariantOptionValue) => value.id === option.value.id\n )\n\n if (valueIndex === -1) {\n list[index]!.values.push(option.value)\n }\n })\n })\n\n return list\n}\n\nfunction computeDisabledValues(\n variants: ProductVariant[],\n optionsList: ProductVariantOptionListItem[],\n optionsModel: Record<string, string>\n): Record<string, Set<string>> {\n if (!variants.length) return {}\n\n const result: Record<string, Set<string>> = {}\n\n for (const option of optionsList) {\n const disabled = new Set<string>()\n\n for (const value of option.values) {\n const hasMatch = variants.some((variant) => {\n if (!variant.options?.length) return false\n\n const variantMap: Record<string, string> = {}\n for (const opt of variant.options) {\n variantMap[opt.id] = opt.value.id\n }\n\n // Variant must have this specific value for this option\n if (variantMap[option.id] !== value.id) return false\n\n // Variant must match all OTHER currently-selected values\n for (const [otherId, selectedId] of Object.entries(optionsModel)) {\n if (otherId === option.id) continue\n if (variantMap[otherId] !== selectedId) return false\n }\n\n return true\n })\n\n if (!hasMatch) {\n disabled.add(value.id)\n }\n }\n\n result[option.id] = disabled\n }\n\n return result\n}\n\nexport function useProductVariant(product: ComputedRef<Product>): {\n optionsModel: Ref<Record<string, string>>\n optionsList: Ref<ProductVariantOptionListItem[]>\n selectedVariant: ComputedRef<ProductVariant | null>\n disabledValues: ComputedRef<Record<string, Set<string>>>\n} {\n const optionsModel = ref({ ...getDefaultOptionsModel(product.value) })\n const optionsList = ref([...getProductVariantOptionsList(product.value)])\n\n const selectedVariant = computed<ProductVariant | null>(() => {\n if (!product.value.variants?.length) {\n return null\n } else if (product.value.variants.length === 1 || !Object.keys(optionsModel.value).length) {\n return product.value.variants[0] ?? null\n }\n\n return (\n product.value.variants.find((variant: ProductVariant) => {\n if (!variant.options?.length) {\n return false\n }\n\n return variant.options.every(\n (option: ProductVariantOption) =>\n optionsModel.value[option.id] === option.value.id\n )\n }) ?? null\n )\n })\n\n const disabledValues = computed<Record<string, Set<string>>>(() =>\n computeDisabledValues(product.value.variants ?? [], optionsList.value, optionsModel.value)\n )\n\n watch(product, () => {\n optionsModel.value = { ...getDefaultOptionsModel(product.value) }\n optionsList.value = [...getProductVariantOptionsList(product.value)]\n })\n\n return { optionsModel, optionsList, selectedVariant, disabledValues }\n}\n","import { computed, ref, watch, type ComputedRef, type Ref } from 'vue'\n\nimport type { Product, ProductModifiersRequest, ProductVariant } from '@zenky/storefront-api'\n\nimport { useRuntime } from '../ports/runtime'\nimport { useStoreProfileStore } from '../stores/store-profile'\nimport { createDebounce } from '../utils/debounce'\nimport { resolveVariantPrice } from './useProductPricing'\n\ninterface PriceRecalculationOptions {\n product: ComputedRef<Product>\n selectedVariant: ComputedRef<ProductVariant | null>\n modifiersModel: Ref<ProductModifiersRequest[]>\n requiredModifiersGroupIsMissing: ComputedRef<boolean>\n selectedModifiersHash: Ref<string | null>\n}\n\nexport function usePriceRecalculation({\n product,\n selectedVariant,\n modifiersModel,\n requiredModifiersGroupIsMissing,\n selectedModifiersHash,\n}: PriceRecalculationOptions): {\n price: ComputedRef<number>\n originalPrice: ComputedRef<number | null>\n priceWasModified: ComputedRef<boolean>\n priceIsRecalculating: Ref<boolean>\n} {\n // SDK берём из рантайма (DI-порт), а не из Nuxt-специфичного useStorefrontApi().\n const sdk = useRuntime().sdk\n const profileStore = useStoreProfileStore()\n\n // -------------------------------------------------------------------------\n // Computed: stock-aware variant pricing\n // -------------------------------------------------------------------------\n\n const currentStockId = computed(() => profileStore.stock?.id ?? null)\n\n const resolvedVariant = computed(() => {\n if (!selectedVariant.value) return null\n\n return resolveVariantPrice(selectedVariant.value, currentStockId.value)\n })\n\n // -------------------------------------------------------------------------\n // Computed: modifier price helpers\n // -------------------------------------------------------------------------\n\n const modifierPriceMap = computed<Map<string, number>>(() => {\n const map = new Map<string, number>()\n\n for (const item of product.value.modifiers ?? []) {\n if (item.modifier.price) {\n map.set(item.modifier.id, item.modifier.price)\n }\n }\n\n for (const group of product.value.modifiers_groups ?? []) {\n for (const item of group.group.modifiers ?? []) {\n if (item.modifier.price) {\n map.set(item.modifier.id, item.modifier.price)\n }\n }\n }\n\n return map\n })\n\n // Сумма цен выбранных модификаторов (включая дефолтные — они в modifiersModel)\n const selectedModifierTotal = computed<number>(() =>\n modifiersModel.value.reduce(\n (sum, req) => sum + (modifierPriceMap.value.get(req.modifier_id) ?? 0) * req.quantity,\n 0\n )\n )\n\n // -------------------------------------------------------------------------\n // Computed: optimistic price (мгновенный, без API)\n // -------------------------------------------------------------------------\n\n // variant.price — базовая цена варианта (stock-specific или fallback),\n // НЕ включает модификаторы. selectedModifierTotal добавляет все выбранные\n // (дефолтные + обязательные + пользовательские).\n const optimisticPrice = computed<number>(() => {\n if (!resolvedVariant.value) return 0\n\n return resolvedVariant.value.price + selectedModifierTotal.value\n })\n\n const optimisticOriginalPrice = computed<number | null>(() => {\n if (!resolvedVariant.value) return null\n\n const r = resolvedVariant.value\n\n if (r.originalPrice && r.originalPrice > r.price) return r.originalPrice\n if (r.discount && r.discount.difference > 0) return r.price + r.discount.difference\n\n return null\n })\n\n // -------------------------------------------------------------------------\n // API-confirmed price (перезаписывает optimistic после ответа)\n // -------------------------------------------------------------------------\n\n const apiPrice = ref<number | null>(null)\n const apiOriginalPrice = ref<number | null>(null)\n const priceIsRecalculating = ref(false)\n let requestId = 0\n\n // -------------------------------------------------------------------------\n // Final displayed price: API > optimistic\n // -------------------------------------------------------------------------\n\n const price = computed<number>(() => apiPrice.value ?? optimisticPrice.value)\n const originalPrice = computed<number | null>(\n () => apiOriginalPrice.value ?? optimisticOriginalPrice.value\n )\n const priceWasModified = computed<boolean>(() => apiPrice.value !== null)\n\n // -------------------------------------------------------------------------\n // API recalculation (подтверждает / корректирует optimistic)\n // -------------------------------------------------------------------------\n\n async function recalculatePrice(): Promise<void> {\n if (requiredModifiersGroupIsMissing.value) return\n if (!modifiersModel.value.length || !selectedVariant.value) return\n\n const currentRequestId = ++requestId\n priceIsRecalculating.value = true\n\n try {\n const response = await sdk.products.getProductVariantPrice(\n profileStore.store!.id,\n product.value.id,\n selectedVariant.value.id,\n {\n modifiers: modifiersModel.value,\n // exactOptionalPropertyTypes: stock_id включаем только если есть\n ...(currentStockId.value ? { stock_id: currentStockId.value } : {}),\n }\n )\n\n if (currentRequestId !== requestId) return\n\n apiPrice.value = response.price\n apiOriginalPrice.value = response.original_price\n selectedModifiersHash.value = response.modifiers_hash\n } catch (e) {\n console.error('[usePriceRecalculation] price recalculation failed', e)\n } finally {\n if (currentRequestId === requestId) {\n priceIsRecalculating.value = false\n }\n }\n }\n\n const debouncedRecalculate = createDebounce(() => recalculatePrice(), 300)\n\n // -------------------------------------------------------------------------\n // Watcher: сброс API-цены + пересчёт при смене варианта/модификаторов\n // -------------------------------------------------------------------------\n\n watch(selectedVariant, () => {\n apiPrice.value = null\n apiOriginalPrice.value = null\n requestId++\n selectedModifiersHash.value = selectedVariant.value?.default_modifiers?.hash ?? null\n })\n\n watch(\n modifiersModel,\n () => {\n apiPrice.value = null\n apiOriginalPrice.value = null\n requestId++\n\n if (modifiersModel.value.length && selectedVariant.value) {\n debouncedRecalculate()\n } else {\n selectedModifiersHash.value = selectedVariant.value?.default_modifiers?.hash ?? null\n }\n },\n { deep: true }\n )\n\n return { price, originalPrice, priceWasModified, priceIsRecalculating }\n}\n","import { computed, watch, type ComputedRef, type Ref } from 'vue'\n\nimport type { Product, ProductModifiersRequest, ProductVariant } from '@zenky/storefront-api'\n\nimport { usePriceRecalculation } from './usePriceRecalculation'\nimport { useProductVariant, type ProductVariantOptionListItem } from './useProductVariant'\nimport { useProductVariantModifiers } from './useProductVariantModifiers'\n\n// SDK-поле min_quantity опционально (number | null); нормализуем в положительное количество.\nfunction resolveQuantity(minQuantity: number | null): number {\n return minQuantity && minQuantity > 0 ? minQuantity : 1\n}\n\nexport function useProductVariantSelector(product: ComputedRef<Product>): {\n optionsModel: Ref<Record<string, string>>\n optionsList: Ref<ProductVariantOptionListItem[]>\n disabledValues: ComputedRef<Record<string, Set<string>>>\n modifiersModel: Ref<ProductModifiersRequest[]>\n selectedVariant: ComputedRef<ProductVariant | null>\n price: ComputedRef<number>\n originalPrice: ComputedRef<number | null>\n priceWasModified: ComputedRef<boolean>\n priceIsRecalculating: Ref<boolean>\n selectedModifiersHash: Ref<string | null>\n requiredModifiersGroupIsMissing: ComputedRef<boolean>\n} {\n const { optionsModel, optionsList, selectedVariant, disabledValues } =\n useProductVariant(product)\n const { modifiersModel, selectedModifiersHash } = useProductVariantModifiers(selectedVariant)\n\n // Обязательные модификаторы — всегда должны быть в модели.\n // 1) modEntry.is_required — индивидуальный обязательный модификатор\n // 2) groupEntry.is_required — обязательная группа: если в ней нет is_required-модификаторов,\n // автоматически выбираем самый дешёвый (зеркалит minRequiredModifiersCost в useProductPricing)\n const requiredModifierEntries = computed<ProductModifiersRequest[]>(() => {\n const result: ProductModifiersRequest[] = []\n\n for (const groupEntry of product.value.modifiers_groups ?? []) {\n const group = groupEntry.group\n const hasIndividualRequired = group.modifiers.some((m) => m.is_required)\n\n // 1. Индивидуальные обязательные модификаторы\n for (const modEntry of group.modifiers) {\n if (modEntry.is_required) {\n result.push({\n modifier_id: modEntry.modifier.id,\n modifiers_group_id: group.id,\n quantity: resolveQuantity(modEntry.min_quantity),\n })\n }\n }\n\n // 2. Обязательная группа без is_required-модификаторов →\n // пользователь должен выбрать хотя бы один; берём самый дешёвый\n if (groupEntry.is_required && !hasIndividualRequired) {\n const sorted = [...group.modifiers].sort(\n (a, b) => (a.modifier.price ?? 0) - (b.modifier.price ?? 0)\n )\n const cheapest = sorted[0]\n\n if (cheapest) {\n result.push({\n modifier_id: cheapest.modifier.id,\n modifiers_group_id: group.id,\n quantity: resolveQuantity(cheapest.min_quantity),\n })\n }\n }\n }\n\n return result\n })\n\n // Добавляет обязательные модификаторы в модель (для UI и API).\n // Одна мутация — без лишних реактивных перерасчётов.\n function seedRequiredModifiers(): void {\n const missing = requiredModifierEntries.value.filter(\n (req) => !modifiersModel.value.some((m) => m.modifier_id === req.modifier_id)\n )\n\n if (missing.length) {\n modifiersModel.value = [...modifiersModel.value, ...missing]\n }\n }\n\n // Синхронная инициализация — до регистрации любых watchers в usePriceRecalculation,\n // чтобы первый рендер сразу видел корректную цену.\n seedRequiredModifiers()\n\n // При смене варианта: useProductVariantModifiers watcher сбрасывает модель до дефолтов,\n // затем мы добавляем обязательные обратно. Оба watcher'а flush: 'pre' — отрабатывают\n // в порядке регистрации до рендера.\n watch(selectedVariant, seedRequiredModifiers)\n\n const requiredModifiersGroupIsMissing = computed<boolean>(() => {\n const requiredGroups = (product.value.modifiers_groups ?? [])\n .filter((group) => group.is_required)\n .map((group) => group.group.id)\n\n if (!requiredGroups.length) return false\n\n return requiredGroups.some(\n (groupId) =>\n !modifiersModel.value.find(\n (m) => m.modifiers_group_id === groupId && m.quantity > 0\n )\n )\n })\n\n const { price, originalPrice, priceWasModified, priceIsRecalculating } = usePriceRecalculation({\n product,\n selectedVariant,\n modifiersModel,\n requiredModifiersGroupIsMissing,\n selectedModifiersHash,\n })\n\n return {\n optionsModel,\n optionsList,\n disabledValues,\n modifiersModel,\n selectedVariant,\n price,\n originalPrice,\n priceWasModified,\n priceIsRecalculating,\n selectedModifiersHash,\n requiredModifiersGroupIsMissing,\n }\n}\n","// Запросы рекомендованных товаров. SDK не предоставляет типизированных методов\n// related.products.list — идём через публичный sdk.client.request.\nimport type { Product } from '@zenky/storefront-api'\n\nimport { useRuntime } from '../ports/runtime'\nimport { createRuntimeState } from '../ports/runtimeState'\nimport { useAuthStore } from '../stores/auth'\nimport { useStoreProfileStore } from '../stores/store-profile'\n\nexport interface OrderCredentials {\n id: string\n token: string\n}\n\ninterface UseRelatedProductsApi {\n fetchForProduct: (\n productId: string,\n orderCredentials: OrderCredentials | null,\n signal?: AbortSignal\n ) => Promise<Product[]>\n fetchForOrder: (orderId: string, orderToken: string, signal?: AbortSignal) => Promise<Product[]>\n}\n\n/**\n * Один из вариантов товара и ни одного модификатора — такой товар можно класть\n * в корзину одним кликом по рекомендации, минуя открытие карточки.\n */\nexport function canAddDirectly(product: Product): boolean {\n const variantsCount = product.variants?.length ?? 0\n const hasModifiers = (product.modifiers?.length ?? 0) > 0\n const hasModifierGroups = (product.modifiers_groups?.length ?? 0) > 0\n return variantsCount === 1 && !hasModifiers && !hasModifierGroups\n}\n\n// Без `variants.prices` приходят 0₽ (цены живут на variants). Без modifiers/groups\n// сломается canAddDirectly — посчитает товар «прямым добавлением», хотя модификаторы есть.\nconst RELATED_PRODUCT_INCLUDES = 'variants.prices,modifiers,modifiers_groups'\n\ninterface RelatedProductsState {\n productInFlight: Map<string, Promise<Product[]>>\n}\n\nconst getRelatedProductsState = createRuntimeState<RelatedProductsState>(() => ({\n productInFlight: new Map<string, Promise<Product[]>>(),\n}))\n\nexport function useRelatedProducts(): UseRelatedProductsApi {\n const runtime = useRuntime()\n const { sdk } = runtime\n const { productInFlight } = getRelatedProductsState(runtime)\n const profileStore = useStoreProfileStore()\n const authStore = useAuthStore()\n\n function getStoreId(): string {\n const id = profileStore.store?.id\n if (!id) throw new Error('Store is not initialized')\n return id\n }\n\n async function fetchForProduct(\n productId: string,\n orderCredentials: OrderCredentials | null,\n signal?: AbortSignal\n ): Promise<Product[]> {\n if (signal?.aborted) return []\n\n const key = orderCredentials ? `${productId}:${orderCredentials.id}` : productId\n\n let promise = productInFlight.get(key)\n if (!promise) {\n promise = (async (): Promise<Product[]> => {\n try {\n const storeId = getStoreId()\n const query: Record<string, string> = { with: RELATED_PRODUCT_INCLUDES }\n if (orderCredentials) {\n query.order_id = orderCredentials.id\n query.order_token = orderCredentials.token\n }\n const url = sdk.client.getStoreUrl(\n storeId,\n `/products/${productId}/related/products`,\n query\n )\n const response = await sdk.client.request(\n 'GET',\n url,\n undefined,\n authStore.token\n )\n return (response?.data as Product[] | undefined) ?? []\n } catch (e: unknown) {\n // По ТЗ при ошибке/пустом ответе никаких сообщений покупателю —\n // блок просто не появляется. Лог нужен разработчику.\n console.warn('[recommendations:product] fetch failed', e)\n return []\n }\n })().finally(() => productInFlight.delete(key))\n productInFlight.set(key, promise)\n }\n\n const result = await promise\n return signal?.aborted ? [] : result\n }\n\n async function fetchForOrder(\n orderId: string,\n orderToken: string,\n signal?: AbortSignal\n ): Promise<Product[]> {\n if (signal?.aborted) return []\n\n try {\n const storeId = getStoreId()\n const url = sdk.client.getStoreUrl(storeId, `/orders/${orderId}/related/products`, {\n token: orderToken,\n with: RELATED_PRODUCT_INCLUDES,\n })\n const response = await sdk.client.request('GET', url, undefined, authStore.token)\n if (signal?.aborted) return []\n return (response?.data as Product[] | undefined) ?? []\n } catch (e: unknown) {\n console.warn('[recommendations:order] fetch failed', e)\n return []\n }\n }\n\n return { fetchForProduct, fetchForOrder }\n}\n","import type { CatalogItem, Product } from '@zenky/storefront-api'\n\nexport interface CatalogProductMatch {\n product: Product\n catalogItem: CatalogItem\n}\n\n/** Поиск товара по short_id в статичном каталоге. null — если не найден. */\nexport function findProductInCatalog(\n catalog: CatalogItem[],\n shortId: string\n): CatalogProductMatch | null {\n for (const item of catalog) {\n if (!item.products.length) continue\n\n const found = item.products.find((p) => p.short_id === shortId)\n if (found) return { product: found, catalogItem: item }\n }\n\n return null\n}\n"]}
|
|
@@ -87,16 +87,6 @@ function useCollections(sdk) {
|
|
|
87
87
|
return { loadCollections };
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
index: () => "/catalog",
|
|
94
|
-
/** Страница конкретной категории */
|
|
95
|
-
category: (shortId, slug) => `/catalog/${shortId}/${slug || shortId}`,
|
|
96
|
-
/** Страница конкретной коллекции */
|
|
97
|
-
collection: (id) => `/collections/${id}`
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export { catalogRoutes, collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, groupProductsBySubcategory, useCollections };
|
|
101
|
-
//# sourceMappingURL=chunk-RYYY7MVP.js.map
|
|
102
|
-
//# sourceMappingURL=chunk-RYYY7MVP.js.map
|
|
90
|
+
export { collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, groupProductsBySubcategory, useCollections };
|
|
91
|
+
//# sourceMappingURL=chunk-NG7RUIWW.js.map
|
|
92
|
+
//# sourceMappingURL=chunk-NG7RUIWW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/catalog/findCategory.ts","../src/catalog/groupBySubcategory.ts","../src/catalog/useCollections.ts"],"names":[],"mappings":"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","file":"chunk-NG7RUIWW.js","sourcesContent":["import type { NestedCategory } from '@zenky/storefront-api'\n\n/**\n * Рекурсивный поиск категории в дереве по `short_id`.\n *\n * `NestedCategory[]` — это дерево: корневые категории на верхнем уровне,\n * вложенные — внутри `children[]`. Простой `tree.find()` найдёт только\n * корневые. Для вложенных (например «Куртки» внутри «Мужская» внутри «Одежда»)\n * нужно рекурсивно обойти все ветки.\n *\n * Возвращает первое совпадение (DFS pre-order).\n */\nexport function findCategoryByShortId(\n tree: NestedCategory[],\n shortId: string\n): NestedCategory | null {\n for (const cat of tree) {\n if (cat.short_id === shortId) return cat\n if (cat.children && cat.children.length > 0) {\n const found = findCategoryByShortId(cat.children, shortId)\n if (found) return found\n }\n }\n return null\n}\n\n/**\n * Находит корневого предка категории по `parent_id`.\n *\n * Для вложенной «Куртки» (parent: «Мужская») вернёт «Одежда» (корень ветки).\n * Для корневой «Одежда» вернёт саму себя.\n *\n * Используется в `CategoryTabs`, чтобы подсветить корневой таб когда юзер\n * находится на вложенной категории.\n */\nexport function findRootAncestor(\n tree: NestedCategory[],\n category: NestedCategory\n): NestedCategory | null {\n if (!category.parent_id) {\n // Уже корневая — возвращаем её саму если она есть в tree на верхнем уровне\n return tree.find((c) => c.id === category.id) ?? category\n }\n\n // Ищем родителя\n const parent = findCategoryById(tree, category.parent_id)\n if (!parent) return null\n return findRootAncestor(tree, parent)\n}\n\n/** Рекурсивный поиск по `id` (не `short_id`). Используется в findRootAncestor. */\nexport function findCategoryById(tree: NestedCategory[], id: string): NestedCategory | null {\n for (const cat of tree) {\n if (cat.id === id) return cat\n if (cat.children && cat.children.length > 0) {\n const found = findCategoryById(cat.children, id)\n if (found) return found\n }\n }\n return null\n}\n\n/**\n * Возвращает путь от корневой категории до указанной (включительно).\n *\n * Пример для «Куртки» в ветке «Одежда → Мужская → Куртки»:\n * → [Одежда, Мужская, Куртки]\n *\n * Используется для построения хлебных крошек.\n */\nexport function getCategoryPath(tree: NestedCategory[], target: NestedCategory): NestedCategory[] {\n const path: NestedCategory[] = []\n let current: NestedCategory | null = target\n\n while (current) {\n path.unshift(current)\n if (!current.parent_id) break\n current = findCategoryById(tree, current.parent_id)\n }\n\n return path\n}\n","import type { NestedCategory, Product } from '@zenky/storefront-api'\n\nexport interface SubcategoryGroup {\n category: NestedCategory\n products: Product[]\n}\n\nexport interface GroupedProducts {\n rootDirect: Product[]\n groups: SubcategoryGroup[]\n}\n\nexport function collectDescendantIds(category: NestedCategory): string[] {\n const ids = [category.id]\n for (const child of category.children ?? []) ids.push(...collectDescendantIds(child))\n return ids\n}\n\nfunction productCategoryIds(product: Product): string[] {\n const categories = (product as unknown as { categories?: Array<{ id: string }> }).categories\n return categories?.map((c) => c.id) ?? []\n}\n\n/**\n * Товары поддерева в порядке дерева (DFS): сперва товары самой категории\n * (в порядке каталога), затем рекурсивно товары дочерних категорий.\n * Дубли (товар в нескольких категориях) отбрасываем, оставляя первое вхождение.\n */\nfunction collectSubtreeProducts(\n category: NestedCategory,\n products: Product[],\n order: Map<string, number>\n): Product[] {\n const seen = new Set<string>()\n const out: Product[] = []\n\n const pushUnique = (list: Product[]): void => {\n for (const p of list) {\n if (!seen.has(p.id)) {\n seen.add(p.id)\n out.push(p)\n }\n }\n }\n\n pushUnique(\n products\n .filter((p) => productCategoryIds(p).includes(category.id))\n .sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0))\n )\n for (const child of category.children ?? []) {\n pushUnique(collectSubtreeProducts(child, products, order))\n }\n\n return out\n}\n\nexport function groupProductsBySubcategory(\n rootCategory: NestedCategory,\n products: Product[]\n): GroupedProducts {\n const order = new Map(products.map((p, i) => [p.id, i]))\n\n const rootDirect = products.filter((p) => productCategoryIds(p).includes(rootCategory.id))\n\n const groups: SubcategoryGroup[] = []\n for (const child of rootCategory.children ?? []) {\n const groupProducts = collectSubtreeProducts(child, products, order)\n if (groupProducts.length > 0) groups.push({ category: child, products: groupProducts })\n }\n\n return { rootDirect, groups }\n}\n","import type {\n CollectionsListRequest,\n ProductsCollection,\n ZenkyStorefront,\n} from '@zenky/storefront-api'\n\n/**\n * Загрузка списка коллекций товаров магазина.\n * Pure composable — SDK передаётся параметром (DI), Nuxt не нужен.\n *\n * NOTE: одиночный `getCollection(id)` в storefront API не предусмотрен,\n * для получения товаров коллекции используется `GET /products?collection_id=...`.\n * Чтобы получить метаданные коллекции — ищем в списке через `loadCollections`.\n */\nexport function useCollections(sdk: ZenkyStorefront): {\n loadCollections: (\n storeId: string,\n request?: CollectionsListRequest\n ) => Promise<ProductsCollection[]>\n} {\n async function loadCollections(\n storeId: string,\n request?: CollectionsListRequest\n ): Promise<ProductsCollection[]> {\n const response = await sdk.collections.getCollections(storeId, request)\n return response.items\n }\n\n return { loadCollections }\n}\n"]}
|