@zenky/storefront-vue 0.10.6 → 0.10.7
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 +10 -0
- package/dist/cart/index.js +2 -2
- package/dist/{chunk-E4DUFN2M.js → chunk-2SMSLZ6G.js} +3 -3
- package/dist/{chunk-E4DUFN2M.js.map → chunk-2SMSLZ6G.js.map} +1 -1
- package/dist/{chunk-RAJDWCJU.js → chunk-B3UU7HF5.js} +26 -3
- package/dist/chunk-B3UU7HF5.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/products/index.d.ts +9 -1
- package/dist/products/index.js +2 -1
- package/dist/seo/index.js +2 -1
- package/dist/seo/index.js.map +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-RAJDWCJU.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createDebounce } from './chunk-XUGXLJZB.js';
|
|
2
2
|
import { createRuntimeState } from './chunk-5QCUH3FF.js';
|
|
3
|
+
import { useCatalogStore } from './chunk-Z3IW4ODZ.js';
|
|
3
4
|
import { useRuntime, useStoreProfileStore, useAuthStore } from './chunk-VFMVQR6Y.js';
|
|
4
5
|
import { UnitType } from '@zenky/storefront-api';
|
|
5
6
|
import { computed, ref, watch } from 'vue';
|
|
@@ -560,6 +561,28 @@ function findProductInCatalog(catalog, shortId) {
|
|
|
560
561
|
return null;
|
|
561
562
|
}
|
|
562
563
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
564
|
+
// src/products/useProductDetail.ts
|
|
565
|
+
var PRODUCT_DETAIL_INCLUDES = "images,variants.prices,variants.options,categories,modifiers,modifiers.cover,modifiers_groups,modifiers_groups.cover,custom_fields";
|
|
566
|
+
function useProductDetail() {
|
|
567
|
+
const { sdk } = useRuntime();
|
|
568
|
+
const catalogStore = useCatalogStore();
|
|
569
|
+
const profileStore = useStoreProfileStore();
|
|
570
|
+
function findInCatalog(shortId) {
|
|
571
|
+
return findProductInCatalog(catalogStore.catalog, shortId);
|
|
572
|
+
}
|
|
573
|
+
async function fetchProduct(shortId) {
|
|
574
|
+
const storeId = profileStore.store?.id;
|
|
575
|
+
if (!storeId) return null;
|
|
576
|
+
try {
|
|
577
|
+
return await sdk.products.getProduct(storeId, shortId, { with: PRODUCT_DETAIL_INCLUDES });
|
|
578
|
+
} catch (e) {
|
|
579
|
+
console.error("[product-detail] getProduct failed", e);
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
return { findInCatalog, fetchProduct };
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
export { canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductDetail, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts };
|
|
587
|
+
//# sourceMappingURL=chunk-B3UU7HF5.js.map
|
|
588
|
+
//# sourceMappingURL=chunk-B3UU7HF5.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","../src/products/useProductDetail.ts"],"names":["computed","ref","watch"],"mappings":"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","file":"chunk-B3UU7HF5.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","import { useRuntime } from '../ports/runtime'\nimport { useCatalogStore } from '../stores/catalog'\nimport { useStoreProfileStore } from '../stores/store-profile'\nimport { findProductInCatalog, type CatalogProductMatch } from './findProductInCatalog'\n\nimport type { Product } from '@zenky/storefront-api'\n\n// images — обложка и OG; variants.options — иначе селектор вариантов схлопывается\n// на первый вариант; variants.prices — цена самого варианта, а не 0; custom_fields —\n// доп. атрибуты товара.\nconst PRODUCT_DETAIL_INCLUDES =\n 'images,variants.prices,variants.options,categories,modifiers,modifiers.cover,modifiers_groups,modifiers_groups.cover,custom_fields'\n\nexport interface UseProductDetailApi {\n /** Синхронный поиск по уже загруженному статичному каталогу. */\n findInCatalog: (shortId: string) => CatalogProductMatch | null\n /** API-фолбэк, когда товара нет в каталоге. */\n fetchProduct: (shortId: string) => Promise<Product | null>\n}\n\nexport function useProductDetail(): UseProductDetailApi {\n const { sdk } = useRuntime()\n const catalogStore = useCatalogStore()\n const profileStore = useStoreProfileStore()\n\n function findInCatalog(shortId: string): CatalogProductMatch | null {\n return findProductInCatalog(catalogStore.catalog, shortId)\n }\n\n async function fetchProduct(shortId: string): Promise<Product | null> {\n const storeId = profileStore.store?.id\n if (!storeId) return null\n\n try {\n return await sdk.products.getProduct(storeId, shortId, { with: PRODUCT_DETAIL_INCLUDES })\n } catch (e) {\n console.error('[product-detail] getProduct failed', e)\n return null\n }\n }\n\n return { findInCatalog, fetchProduct }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Plugin } from 'vue';
|
|
|
4
4
|
export { Major, Minor, asMajor, asMinor, formatPrice, majorToMinor, minorToMajor, minorToMajorString } from './money/index.js';
|
|
5
5
|
export { FontConfig, PrimaryShades, ThemeColorConfig, ThemeData, buildCssVariableMap, generatePrimaryShades, generateShades, useTheme } from './theme/index.js';
|
|
6
6
|
export { DayScheduleInfo, OperationChain, SocialLink, TodayScheduleInfo, buildQrCodeUrl, createDebounce, createOperationChain, formatAddressCityLast, formatDate, formatDateTime, formatPhoneNational, formatPhoneSpaced, formatScheduleStatus, getApiErrorMessage, getApiFieldErrors, getEmailLink, getPhoneTelLink, getSocialLinks, getTodayInfo, getWebsiteLink, getWeeklySchedule, pluralize, toDateInputValue, todayInTimezone } from './utils/index.js';
|
|
7
|
-
export { CatalogProductMatch, CategoryWithProducts, OrderCredentials, ProductVariantOptionListItem, ResolvedPrice, canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts } from './products/index.js';
|
|
7
|
+
export { CatalogProductMatch, CategoryWithProducts, OrderCredentials, ProductVariantOptionListItem, ResolvedPrice, UseProductDetailApi, canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductDetail, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts } from './products/index.js';
|
|
8
8
|
export { GroupedProducts, SubcategoryGroup, collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, getCity, getRemoteCatalog, getStock, groupProductsBySubcategory, useCollections } from './catalog/index.js';
|
|
9
9
|
export { AttachedCustomerCache, BonusesReconciliation, BonusesReconciliationDeps, CASH_DENOMINATIONS_MAJOR, CachedCustomerView, CartCredentials, CartDependencies, CartErrorScope, CartInitialization, CartItemRequest, CartLineKeyParams, CartMutationComposable, CartOperations, CartQuantities, CartRecalculation, CartRecalculationDeps, CartStockWatcher, CashChangePresetsOptions, CheckoutFlowFlags, CheckoutSubmitComposable, CustomerAttachComposable, DEFAULT_ROUND_STEPS_MAJOR, MainPaymentRequestParams, MutationKind, MutationOptions, ORDER_EVENTS, ORDER_WITH, OrderBonusesComposable, OrderBonusesDeps, OrderCredentialsLike, OrderDelivery, OrderDeliveryDeps, OrderPromocodeComposable, OrderPromocodeDeps, OrderSettingsComposable, OrderTotal, PaymentSelection, PaymentSelectionComposable, RecaptchaPayloadProvider, RestrictedAddToCart, RestrictionGate, RestrictionGateProduct, RetryOptions, 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 } from './cart/index.js';
|
|
10
10
|
export { RawSnippetItem, Snippet, SnippetGroup, SnippetLanguage, SnippetPosition, normalizeSnippets } from './snippets/index.js';
|
package/dist/index.js
CHANGED
|
@@ -3,17 +3,17 @@ export { useProductsStore, useStore, useStorefrontProfile } from './chunk-PTMSPB
|
|
|
3
3
|
export { buildCssVariableMap, generatePrimaryShades, generateShades, useTheme } from './chunk-4IFPVEO7.js';
|
|
4
4
|
export { buildQrCodeUrl, createOperationChain, formatAddressCityLast, formatDate, formatDateTime, formatPhoneNational, formatPhoneSpaced, formatScheduleStatus, getApiErrorMessage, getApiFieldErrors, getEmailLink, getPhoneTelLink, getSocialLinks, getTodayInfo, getWebsiteLink, getWeeklySchedule, pluralize, toDateInputValue, todayInTimezone } from './chunk-MZ66ARDL.js';
|
|
5
5
|
import './chunk-EMGQXBU3.js';
|
|
6
|
-
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-
|
|
6
|
+
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-2SMSLZ6G.js';
|
|
7
7
|
export { useCartCredentials } from './chunk-5YD4AIY2.js';
|
|
8
|
-
export { useCatalogStore } from './chunk-Z3IW4ODZ.js';
|
|
9
8
|
export { useCartStore, useOrderSettingsStore, usePromotionsStore } from './chunk-Z247QRDJ.js';
|
|
10
9
|
export { collectDescendantIds, findCategoryById, findCategoryByShortId, findRootAncestor, getCategoryPath, groupProductsBySubcategory, useCollections } from './chunk-NG7RUIWW.js';
|
|
11
10
|
export { getCity, getRemoteCatalog, getStock } from './chunk-E3G7NGCH.js';
|
|
12
11
|
export { asMajor, asMinor, formatPrice, majorToMinor, minorToMajor, minorToMajorString } from './chunk-RO25KNM5.js';
|
|
13
12
|
export { KEY_MESSAGE_FORMATTER, NOOP_ACTIVITY_REPORTER, NOOP_NOTIFIER, NOOP_RUM, createMemoryStorage, err, ok } from './chunk-MOG6UMFM.js';
|
|
14
|
-
export { canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts } from './chunk-
|
|
13
|
+
export { canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductDetail, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts } from './chunk-B3UU7HF5.js';
|
|
15
14
|
export { createDebounce } from './chunk-XUGXLJZB.js';
|
|
16
15
|
import './chunk-5QCUH3FF.js';
|
|
16
|
+
export { useCatalogStore } from './chunk-Z3IW4ODZ.js';
|
|
17
17
|
export { createStorefront, provideStorefront, useAuthStore, useRuntime, useStoreProfileStore } from './chunk-VFMVQR6Y.js';
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
package/dist/products/index.d.ts
CHANGED
|
@@ -102,4 +102,12 @@ interface CatalogProductMatch {
|
|
|
102
102
|
/** Поиск товара по short_id в статичном каталоге. null — если не найден. */
|
|
103
103
|
declare function findProductInCatalog(catalog: CatalogItem[], shortId: string): CatalogProductMatch | null;
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
interface UseProductDetailApi {
|
|
106
|
+
/** Синхронный поиск по уже загруженному статичному каталогу. */
|
|
107
|
+
findInCatalog: (shortId: string) => CatalogProductMatch | null;
|
|
108
|
+
/** API-фолбэк, когда товара нет в каталоге. */
|
|
109
|
+
fetchProduct: (shortId: string) => Promise<Product | null>;
|
|
110
|
+
}
|
|
111
|
+
declare function useProductDetail(): UseProductDetailApi;
|
|
112
|
+
|
|
113
|
+
export { type CatalogProductMatch, type CategoryWithProducts, type OrderCredentials, type ProductVariantOptionListItem, type ResolvedPrice, type UseProductDetailApi, canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductDetail, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts };
|
package/dist/products/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts } from '../chunk-
|
|
1
|
+
export { canAddDirectly, findProductInCatalog, formatWeight, getProductWeight, getVariantWeight, resolveVariantPrice, toGrams, usePriceRecalculation, useProductDetail, useProductPricing, useProductVariant, useProductVariantModifiers, useProductVariantSelector, useProductsByCategory, useRelatedProducts } from '../chunk-B3UU7HF5.js';
|
|
2
2
|
import '../chunk-XUGXLJZB.js';
|
|
3
3
|
import '../chunk-5QCUH3FF.js';
|
|
4
|
+
import '../chunk-Z3IW4ODZ.js';
|
|
4
5
|
import '../chunk-VFMVQR6Y.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/seo/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { getSocialLinks } from '../chunk-MZ66ARDL.js';
|
|
2
2
|
import { minorToMajorString } from '../chunk-RO25KNM5.js';
|
|
3
|
-
import { resolveVariantPrice } from '../chunk-
|
|
3
|
+
import { resolveVariantPrice } from '../chunk-B3UU7HF5.js';
|
|
4
4
|
import '../chunk-XUGXLJZB.js';
|
|
5
5
|
import '../chunk-5QCUH3FF.js';
|
|
6
|
+
import '../chunk-Z3IW4ODZ.js';
|
|
6
7
|
import '../chunk-VFMVQR6Y.js';
|
|
7
8
|
import { ContactType } from '@zenky/storefront-api';
|
|
8
9
|
|
package/dist/seo/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/seo/utils.ts","../../src/seo/siteOrigin.ts","../../src/seo/productSchema.ts","../../src/seo/categorySchema.ts","../../src/seo/articleSchema.ts","../../src/seo/organizationSchema.ts","../../src/seo/ogTags.ts","../../src/seo/entitySeo.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Media, Store } from '@zenky/storefront-api'\n\n/**\n * Resolves the best available URL from a Media object.\n */\nexport function resolveMediaUrl(media: Media): string | null {\n return (\n media.hd?.url ||\n media.xlarge?.url ||\n media.large?.url ||\n media.medium?.url ||\n media.placeholder?.url ||\n null\n )\n}\n\n/**\n * Resolves store logo URL, preferring square logo over rectangular.\n * Tries all available size variants so CDN assets with only hd/xlarge are found too.\n */\nexport function resolveStoreLogoUrl(store: Store | null | undefined): string | null {\n if (!store) return null\n if (store.square_logo) {\n const url = resolveMediaUrl(store.square_logo)\n if (url) return url\n }\n if (store.logo) {\n return resolveMediaUrl(store.logo)\n }\n return null\n}\n\n/**\n * Strips HTML tags from a string.\n */\nexport function stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim()\n}\n\n/**\n * Prepares a string for use as og:description or meta description:\n * strips HTML tags and truncates to maxLength (default 160).\n */\nexport function prepareOgDescription(\n text: string | null | undefined,\n maxLength = 160\n): string | null {\n if (!text) return null\n const plain = stripHtml(text)\n if (!plain) return null\n return plain.length > maxLength ? `${plain.slice(0, maxLength - 3)}...` : plain\n}\n","/**\n * Каноничный публичный origin сайта из `store.domain`. Fallback (хост запроса)\n * приносит потребитель — ядро не знает про useRequestURL.\n */\nexport function resolveSiteOrigin(\n storeDomain: string | null | undefined,\n fallbackOrigin: string\n): string {\n const domain = storeDomain?.trim()\n if (domain) {\n const host = domain.replace(/^https?:\\/\\//, '').replace(/\\/+$/, '')\n return `https://${host}`\n }\n return fallbackOrigin\n}\n","import type { Product, ProductVariant } from '@zenky/storefront-api'\n\nimport { minorToMajorString } from '../money'\nimport { resolveVariantPrice } from '../products'\nimport { resolveMediaUrl } from './utils'\n\nfunction isProductInStock(variants: ProductVariant[]): boolean {\n if (!variants.length) return false\n return variants.some((variant) => {\n const remainders = variant.remainders\n if (!remainders?.length) return true\n return remainders.some((remainder) => remainder.quantity > 0)\n })\n}\n\n/**\n * JSON-LD schema.org/Product. Google → Rich Results (цена/наличие/рейтинг в выдаче).\n * Возвращает массив (0 или 1 объект) — потребитель оборачивает в `<script ld+json>`.\n * Spec: https://schema.org/Product\n */\nexport function buildProductSchema(product: Product, currency: string): Record<string, unknown>[] {\n const variants = product.variants ?? []\n\n const firstVariant = variants[0]\n let offerBlock: Record<string, unknown> | undefined\n\n if (firstVariant) {\n const resolved = resolveVariantPrice(firstVariant)\n\n offerBlock = {\n '@type': 'Offer',\n price: minorToMajorString(resolved.price, currency),\n priceCurrency: currency,\n availability: isProductInStock(variants)\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n ...(firstVariant.sku ? { sku: firstVariant.sku } : {}),\n }\n }\n\n const images = (product.images ?? []).map(resolveMediaUrl).filter((url): url is string => !!url)\n\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name,\n }\n\n if (product.description) schema.description = product.description\n if (images.length) schema.image = images\n if (offerBlock) schema.offers = offerBlock\n\n return [schema]\n}\n","import type { NestedCategory, Product } from '@zenky/storefront-api'\n\nimport { resolveMediaUrl } from './utils'\nimport type { BreadcrumbItem } from './types'\n\n/**\n * JSON-LD для страницы категории: BreadcrumbList (хлебные крошки) + ItemList\n * (первые 10 товаров). Возвращает массив JSON-LD объектов (0–2).\n * Spec: https://schema.org/ItemList · https://schema.org/BreadcrumbList\n */\nexport function buildCategorySchemas(\n category: NestedCategory,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n const schemas: Record<string, unknown>[] = []\n\n if (breadcrumbs.length) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: breadcrumbs.map((crumb, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: crumb.label,\n ...(crumb.to ? { item: `${origin}${crumb.to}` } : {}),\n })),\n })\n }\n\n const items = products.slice(0, 10)\n if (items.length) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'ItemList',\n name: category.name,\n numberOfItems: items.length,\n itemListElement: items.map((product, index) => {\n const url = `${origin}/products/${product.short_id}/${product.slug || product.short_id}`\n const firstImage = product.images?.[0]\n const image = firstImage ? resolveMediaUrl(firstImage) : null\n\n const item: Record<string, unknown> = {\n '@type': 'ListItem',\n position: index + 1,\n url,\n name: product.name,\n }\n\n if (image) item.image = image\n\n return item\n }),\n })\n }\n\n return schemas\n}\n","import type { Article, Media, OfferArticle } from '@zenky/storefront-api'\n\nimport { prepareOgDescription, resolveMediaUrl } from './utils'\n\nfunction articleSchema(\n type: 'Article' | 'BlogPosting',\n opts: {\n title: string | null | undefined\n intro: string | null | undefined\n cover: Media | null | undefined\n storeName: string\n origin: string\n }\n): Record<string, unknown> {\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': type,\n headline: opts.title ?? '',\n author: {\n '@type': 'Organization',\n name: opts.storeName,\n url: opts.origin,\n },\n }\n\n const description = prepareOgDescription(opts.intro)\n if (description) schema.description = description\n\n const image = opts.cover ? resolveMediaUrl(opts.cover) : null\n if (image) schema.image = image\n\n return schema\n}\n\n/**\n * JSON-LD schema.org/Article для страницы акции (редакционный контент).\n * Spec: https://schema.org/Article\n */\nexport function buildOfferArticleSchema(\n article: OfferArticle,\n storeName: string,\n origin: string\n): Record<string, unknown>[] {\n if (!article.title) return []\n\n return [\n articleSchema('Article', {\n title: article.title,\n intro: article.intro,\n cover: article.cover,\n storeName,\n origin,\n }),\n ]\n}\n\n/**\n * JSON-LD schema.org/BlogPosting для статьи блога (Google Rich Results).\n * Spec: https://schema.org/BlogPosting\n */\nexport function buildBlogPostSchema(\n article: Article,\n storeName: string,\n origin: string\n): Record<string, unknown>[] {\n const schema = articleSchema('BlogPosting', {\n title: article.title,\n intro: article.intro,\n cover: article.cover,\n storeName,\n origin,\n })\n\n if (article.updated_at) {\n schema.dateModified = article.updated_at\n // Нет отдельного datePublished — используем updated_at.\n schema.datePublished = article.updated_at\n }\n\n return [schema]\n}\n","import { ContactType } from '@zenky/storefront-api'\n\nimport type { Schedule, Store } from '@zenky/storefront-api'\n\nimport { getSocialLinks } from '../utils'\n\n/** Ключ дня в Schedule.days → schema.org DayOfWeek. */\nconst SCHEMA_DAY: Record<string, string> = {\n monday: 'Monday',\n tuesday: 'Tuesday',\n wednesday: 'Wednesday',\n thursday: 'Thursday',\n friday: 'Friday',\n saturday: 'Saturday',\n sunday: 'Sunday',\n}\n\n/**\n * Schedule (по дням `hours` — «10:00–22:00») → массив schema.org/OpeningHoursSpecification.\n * Дни без распознаваемого интервала (выходной / круглосуточно / пусто) пропускаем.\n */\nfunction buildOpeningHours(schedule: Schedule | null | undefined): Record<string, unknown>[] {\n if (!schedule) return []\n\n const result: Record<string, unknown>[] = []\n for (const key of Object.keys(SCHEMA_DAY)) {\n const day = schedule.days[key as keyof typeof schedule.days]\n const match = day?.hours?.match(/(\\d{1,2}:\\d{2}).*?(\\d{1,2}:\\d{2})/)\n if (!match) continue\n\n result.push({\n '@type': 'OpeningHoursSpecification',\n dayOfWeek: SCHEMA_DAY[key],\n opens: match[1],\n closes: match[2],\n })\n }\n\n return result\n}\n\n/**\n * JSON-LD schema.org/Organization (или LocalBusiness при наличии физической точки)\n * для главной. Google → Knowledge Panel. Все данные из уже загруженного профиля.\n * Spec: https://schema.org/Organization · https://schema.org/LocalBusiness\n */\nexport function buildOrganizationSchema(store: Store, origin: string): Record<string, unknown>[] {\n const logoUrl =\n store.square_logo?.medium?.url ||\n store.square_logo?.large?.url ||\n store.logo?.medium?.url ||\n store.logo?.large?.url ||\n null\n\n const phones = (store.phones ?? []).map((p) => p.number).filter((n): n is string => !!n)\n const email = store.links?.find((c) => c.type === ContactType.Email)?.value ?? null\n const socialLinks = getSocialLinks(store.links ?? []).map((l) => l.url)\n\n const city = (store.cities ?? []).find((c) => c.is_default) ?? store.cities?.[0] ?? null\n const stock = city?.stocks?.find((st) => st.address) ?? city?.stocks?.[0] ?? null\n\n const streetAddress = stock?.address ?? null\n const geo = stock?.coordinates ?? city?.coordinates ?? null\n const openingHours = buildOpeningHours(stock?.schedule ?? city?.schedule)\n\n const isLocalBusiness = Boolean(streetAddress || geo || openingHours.length)\n\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': isLocalBusiness ? 'LocalBusiness' : 'Organization',\n name: store.name,\n url: origin,\n }\n\n if (logoUrl) {\n schema.logo = logoUrl\n schema.image = logoUrl\n }\n\n if (phones.length) schema.telephone = phones.length === 1 ? phones[0] : phones\n if (email) schema.email = email\n if (socialLinks.length) schema.sameAs = socialLinks\n\n if (streetAddress || city?.name) {\n schema.address = {\n '@type': 'PostalAddress',\n ...(streetAddress ? { streetAddress } : {}),\n ...(city?.name ? { addressLocality: city.name } : {}),\n addressCountry: 'RU',\n }\n }\n\n if (geo) {\n schema.geo = {\n '@type': 'GeoCoordinates',\n latitude: geo.latitude,\n longitude: geo.longitude,\n }\n }\n\n if (openingHours.length) schema.openingHoursSpecification = openingHours\n\n return [schema]\n}\n","/** Уже разрешённые (с учётом дефолтов потребителя) значения OG/Twitter-тегов. */\nexport interface OgTagsInput {\n title: string | null\n description?: string | null\n image?: string | null\n type?: string\n url?: string | null\n}\n\n/** Framework-neutral OG + Twitter meta records. The consumer controls head priority. */\nexport function buildOgTags(input: OgTagsInput): Record<string, string>[] {\n const tags: Record<string, string>[] = []\n\n if (input.title) {\n tags.push({ property: 'og:title', content: input.title })\n tags.push({ name: 'twitter:title', content: input.title })\n }\n\n if (input.description) {\n tags.push({ property: 'og:description', content: input.description })\n tags.push({ name: 'twitter:description', content: input.description })\n }\n\n if (input.image) {\n tags.push({ property: 'og:image', content: input.image })\n tags.push({ name: 'twitter:image', content: input.image })\n }\n\n tags.push({ property: 'og:type', content: input.type ?? 'website' })\n\n if (input.url) {\n tags.push({ property: 'og:url', content: input.url })\n }\n\n return tags\n}\n","import type { Seo, SeoMetaTag } from '@zenky/storefront-api'\n\n/** SDK `Seo.meta` tags mapped to framework-neutral head meta records. */\nexport function mapSeoMetaTags(tags: SeoMetaTag[]): Record<string, string>[] {\n return tags.map((tag) => {\n const attrs: Record<string, string> = {\n [tag.name.attribute]: tag.name.value,\n [tag.value.attribute]: tag.value.value,\n }\n\n for (const additional of tag.additional) {\n attrs[additional.attribute] = additional.value\n }\n\n return attrs\n })\n}\n\n/** meta-теги из `Seo`-сущности (description + маппинг `Seo.meta`). Title резолвит потребитель. */\nexport function buildEntitySeoMeta(seo: Seo | null | undefined): Record<string, string>[] {\n const tags: Record<string, string>[] = []\n\n if (seo?.description) {\n tags.push({ name: 'description', content: seo.description })\n }\n\n if (seo?.meta?.length) {\n tags.push(...mapSeoMetaTags(seo.meta))\n }\n\n return tags\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/seo/utils.ts","../../src/seo/siteOrigin.ts","../../src/seo/productSchema.ts","../../src/seo/categorySchema.ts","../../src/seo/articleSchema.ts","../../src/seo/organizationSchema.ts","../../src/seo/ogTags.ts","../../src/seo/entitySeo.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Media, Store } from '@zenky/storefront-api'\n\n/**\n * Resolves the best available URL from a Media object.\n */\nexport function resolveMediaUrl(media: Media): string | null {\n return (\n media.hd?.url ||\n media.xlarge?.url ||\n media.large?.url ||\n media.medium?.url ||\n media.placeholder?.url ||\n null\n )\n}\n\n/**\n * Resolves store logo URL, preferring square logo over rectangular.\n * Tries all available size variants so CDN assets with only hd/xlarge are found too.\n */\nexport function resolveStoreLogoUrl(store: Store | null | undefined): string | null {\n if (!store) return null\n if (store.square_logo) {\n const url = resolveMediaUrl(store.square_logo)\n if (url) return url\n }\n if (store.logo) {\n return resolveMediaUrl(store.logo)\n }\n return null\n}\n\n/**\n * Strips HTML tags from a string.\n */\nexport function stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim()\n}\n\n/**\n * Prepares a string for use as og:description or meta description:\n * strips HTML tags and truncates to maxLength (default 160).\n */\nexport function prepareOgDescription(\n text: string | null | undefined,\n maxLength = 160\n): string | null {\n if (!text) return null\n const plain = stripHtml(text)\n if (!plain) return null\n return plain.length > maxLength ? `${plain.slice(0, maxLength - 3)}...` : plain\n}\n","/**\n * Каноничный публичный origin сайта из `store.domain`. Fallback (хост запроса)\n * приносит потребитель — ядро не знает про useRequestURL.\n */\nexport function resolveSiteOrigin(\n storeDomain: string | null | undefined,\n fallbackOrigin: string\n): string {\n const domain = storeDomain?.trim()\n if (domain) {\n const host = domain.replace(/^https?:\\/\\//, '').replace(/\\/+$/, '')\n return `https://${host}`\n }\n return fallbackOrigin\n}\n","import type { Product, ProductVariant } from '@zenky/storefront-api'\n\nimport { minorToMajorString } from '../money'\nimport { resolveVariantPrice } from '../products'\nimport { resolveMediaUrl } from './utils'\n\nfunction isProductInStock(variants: ProductVariant[]): boolean {\n if (!variants.length) return false\n return variants.some((variant) => {\n const remainders = variant.remainders\n if (!remainders?.length) return true\n return remainders.some((remainder) => remainder.quantity > 0)\n })\n}\n\n/**\n * JSON-LD schema.org/Product. Google → Rich Results (цена/наличие/рейтинг в выдаче).\n * Возвращает массив (0 или 1 объект) — потребитель оборачивает в `<script ld+json>`.\n * Spec: https://schema.org/Product\n */\nexport function buildProductSchema(product: Product, currency: string): Record<string, unknown>[] {\n const variants = product.variants ?? []\n\n const firstVariant = variants[0]\n let offerBlock: Record<string, unknown> | undefined\n\n if (firstVariant) {\n const resolved = resolveVariantPrice(firstVariant)\n\n offerBlock = {\n '@type': 'Offer',\n price: minorToMajorString(resolved.price, currency),\n priceCurrency: currency,\n availability: isProductInStock(variants)\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n ...(firstVariant.sku ? { sku: firstVariant.sku } : {}),\n }\n }\n\n const images = (product.images ?? []).map(resolveMediaUrl).filter((url): url is string => !!url)\n\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name,\n }\n\n if (product.description) schema.description = product.description\n if (images.length) schema.image = images\n if (offerBlock) schema.offers = offerBlock\n\n return [schema]\n}\n","import type { NestedCategory, Product } from '@zenky/storefront-api'\n\nimport { resolveMediaUrl } from './utils'\nimport type { BreadcrumbItem } from './types'\n\n/**\n * JSON-LD для страницы категории: BreadcrumbList (хлебные крошки) + ItemList\n * (первые 10 товаров). Возвращает массив JSON-LD объектов (0–2).\n * Spec: https://schema.org/ItemList · https://schema.org/BreadcrumbList\n */\nexport function buildCategorySchemas(\n category: NestedCategory,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n const schemas: Record<string, unknown>[] = []\n\n if (breadcrumbs.length) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: breadcrumbs.map((crumb, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: crumb.label,\n ...(crumb.to ? { item: `${origin}${crumb.to}` } : {}),\n })),\n })\n }\n\n const items = products.slice(0, 10)\n if (items.length) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'ItemList',\n name: category.name,\n numberOfItems: items.length,\n itemListElement: items.map((product, index) => {\n const url = `${origin}/products/${product.short_id}/${product.slug || product.short_id}`\n const firstImage = product.images?.[0]\n const image = firstImage ? resolveMediaUrl(firstImage) : null\n\n const item: Record<string, unknown> = {\n '@type': 'ListItem',\n position: index + 1,\n url,\n name: product.name,\n }\n\n if (image) item.image = image\n\n return item\n }),\n })\n }\n\n return schemas\n}\n","import type { Article, Media, OfferArticle } from '@zenky/storefront-api'\n\nimport { prepareOgDescription, resolveMediaUrl } from './utils'\n\nfunction articleSchema(\n type: 'Article' | 'BlogPosting',\n opts: {\n title: string | null | undefined\n intro: string | null | undefined\n cover: Media | null | undefined\n storeName: string\n origin: string\n }\n): Record<string, unknown> {\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': type,\n headline: opts.title ?? '',\n author: {\n '@type': 'Organization',\n name: opts.storeName,\n url: opts.origin,\n },\n }\n\n const description = prepareOgDescription(opts.intro)\n if (description) schema.description = description\n\n const image = opts.cover ? resolveMediaUrl(opts.cover) : null\n if (image) schema.image = image\n\n return schema\n}\n\n/**\n * JSON-LD schema.org/Article для страницы акции (редакционный контент).\n * Spec: https://schema.org/Article\n */\nexport function buildOfferArticleSchema(\n article: OfferArticle,\n storeName: string,\n origin: string\n): Record<string, unknown>[] {\n if (!article.title) return []\n\n return [\n articleSchema('Article', {\n title: article.title,\n intro: article.intro,\n cover: article.cover,\n storeName,\n origin,\n }),\n ]\n}\n\n/**\n * JSON-LD schema.org/BlogPosting для статьи блога (Google Rich Results).\n * Spec: https://schema.org/BlogPosting\n */\nexport function buildBlogPostSchema(\n article: Article,\n storeName: string,\n origin: string\n): Record<string, unknown>[] {\n const schema = articleSchema('BlogPosting', {\n title: article.title,\n intro: article.intro,\n cover: article.cover,\n storeName,\n origin,\n })\n\n if (article.updated_at) {\n schema.dateModified = article.updated_at\n // Нет отдельного datePublished — используем updated_at.\n schema.datePublished = article.updated_at\n }\n\n return [schema]\n}\n","import { ContactType } from '@zenky/storefront-api'\n\nimport type { Schedule, Store } from '@zenky/storefront-api'\n\nimport { getSocialLinks } from '../utils'\n\n/** Ключ дня в Schedule.days → schema.org DayOfWeek. */\nconst SCHEMA_DAY: Record<string, string> = {\n monday: 'Monday',\n tuesday: 'Tuesday',\n wednesday: 'Wednesday',\n thursday: 'Thursday',\n friday: 'Friday',\n saturday: 'Saturday',\n sunday: 'Sunday',\n}\n\n/**\n * Schedule (по дням `hours` — «10:00–22:00») → массив schema.org/OpeningHoursSpecification.\n * Дни без распознаваемого интервала (выходной / круглосуточно / пусто) пропускаем.\n */\nfunction buildOpeningHours(schedule: Schedule | null | undefined): Record<string, unknown>[] {\n if (!schedule) return []\n\n const result: Record<string, unknown>[] = []\n for (const key of Object.keys(SCHEMA_DAY)) {\n const day = schedule.days[key as keyof typeof schedule.days]\n const match = day?.hours?.match(/(\\d{1,2}:\\d{2}).*?(\\d{1,2}:\\d{2})/)\n if (!match) continue\n\n result.push({\n '@type': 'OpeningHoursSpecification',\n dayOfWeek: SCHEMA_DAY[key],\n opens: match[1],\n closes: match[2],\n })\n }\n\n return result\n}\n\n/**\n * JSON-LD schema.org/Organization (или LocalBusiness при наличии физической точки)\n * для главной. Google → Knowledge Panel. Все данные из уже загруженного профиля.\n * Spec: https://schema.org/Organization · https://schema.org/LocalBusiness\n */\nexport function buildOrganizationSchema(store: Store, origin: string): Record<string, unknown>[] {\n const logoUrl =\n store.square_logo?.medium?.url ||\n store.square_logo?.large?.url ||\n store.logo?.medium?.url ||\n store.logo?.large?.url ||\n null\n\n const phones = (store.phones ?? []).map((p) => p.number).filter((n): n is string => !!n)\n const email = store.links?.find((c) => c.type === ContactType.Email)?.value ?? null\n const socialLinks = getSocialLinks(store.links ?? []).map((l) => l.url)\n\n const city = (store.cities ?? []).find((c) => c.is_default) ?? store.cities?.[0] ?? null\n const stock = city?.stocks?.find((st) => st.address) ?? city?.stocks?.[0] ?? null\n\n const streetAddress = stock?.address ?? null\n const geo = stock?.coordinates ?? city?.coordinates ?? null\n const openingHours = buildOpeningHours(stock?.schedule ?? city?.schedule)\n\n const isLocalBusiness = Boolean(streetAddress || geo || openingHours.length)\n\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': isLocalBusiness ? 'LocalBusiness' : 'Organization',\n name: store.name,\n url: origin,\n }\n\n if (logoUrl) {\n schema.logo = logoUrl\n schema.image = logoUrl\n }\n\n if (phones.length) schema.telephone = phones.length === 1 ? phones[0] : phones\n if (email) schema.email = email\n if (socialLinks.length) schema.sameAs = socialLinks\n\n if (streetAddress || city?.name) {\n schema.address = {\n '@type': 'PostalAddress',\n ...(streetAddress ? { streetAddress } : {}),\n ...(city?.name ? { addressLocality: city.name } : {}),\n addressCountry: 'RU',\n }\n }\n\n if (geo) {\n schema.geo = {\n '@type': 'GeoCoordinates',\n latitude: geo.latitude,\n longitude: geo.longitude,\n }\n }\n\n if (openingHours.length) schema.openingHoursSpecification = openingHours\n\n return [schema]\n}\n","/** Уже разрешённые (с учётом дефолтов потребителя) значения OG/Twitter-тегов. */\nexport interface OgTagsInput {\n title: string | null\n description?: string | null\n image?: string | null\n type?: string\n url?: string | null\n}\n\n/** Framework-neutral OG + Twitter meta records. The consumer controls head priority. */\nexport function buildOgTags(input: OgTagsInput): Record<string, string>[] {\n const tags: Record<string, string>[] = []\n\n if (input.title) {\n tags.push({ property: 'og:title', content: input.title })\n tags.push({ name: 'twitter:title', content: input.title })\n }\n\n if (input.description) {\n tags.push({ property: 'og:description', content: input.description })\n tags.push({ name: 'twitter:description', content: input.description })\n }\n\n if (input.image) {\n tags.push({ property: 'og:image', content: input.image })\n tags.push({ name: 'twitter:image', content: input.image })\n }\n\n tags.push({ property: 'og:type', content: input.type ?? 'website' })\n\n if (input.url) {\n tags.push({ property: 'og:url', content: input.url })\n }\n\n return tags\n}\n","import type { Seo, SeoMetaTag } from '@zenky/storefront-api'\n\n/** SDK `Seo.meta` tags mapped to framework-neutral head meta records. */\nexport function mapSeoMetaTags(tags: SeoMetaTag[]): Record<string, string>[] {\n return tags.map((tag) => {\n const attrs: Record<string, string> = {\n [tag.name.attribute]: tag.name.value,\n [tag.value.attribute]: tag.value.value,\n }\n\n for (const additional of tag.additional) {\n attrs[additional.attribute] = additional.value\n }\n\n return attrs\n })\n}\n\n/** meta-теги из `Seo`-сущности (description + маппинг `Seo.meta`). Title резолвит потребитель. */\nexport function buildEntitySeoMeta(seo: Seo | null | undefined): Record<string, string>[] {\n const tags: Record<string, string>[] = []\n\n if (seo?.description) {\n tags.push({ name: 'description', content: seo.description })\n }\n\n if (seo?.meta?.length) {\n tags.push(...mapSeoMetaTags(seo.meta))\n }\n\n return tags\n}\n"]}
|
package/dist/stores/index.d.ts
CHANGED
|
@@ -150,7 +150,7 @@ interface CartStore {
|
|
|
150
150
|
hasBonusesApplied: ComputedRef<boolean>;
|
|
151
151
|
productQuantities: ComputedRef<Record<string, number>>;
|
|
152
152
|
}
|
|
153
|
-
declare const useCartStore: pinia.StoreDefinition<"zenky-cart", Pick<CartStore, "order" | "credentials" | "loading" | "initializing" | "optimisticAdjustments" | "lineOptimistic" | "deliveryMethods" | "orderSettings" | "comment" | "personsCount" | "checkoutTotal" | "selectedPaymentMethod" | "selectedPaymentBill" | "selectedCardTokenId" | "selectedSaveCard" | "bonusesIntent" | "deliveryTimeIntent" | "minPriceViolation">, Pick<CartStore, "
|
|
153
|
+
declare const useCartStore: pinia.StoreDefinition<"zenky-cart", Pick<CartStore, "order" | "credentials" | "loading" | "initializing" | "optimisticAdjustments" | "lineOptimistic" | "deliveryMethods" | "orderSettings" | "comment" | "personsCount" | "checkoutTotal" | "selectedPaymentMethod" | "selectedPaymentBill" | "selectedCardTokenId" | "selectedSaveCard" | "bonusesIntent" | "deliveryTimeIntent" | "minPriceViolation">, Pick<CartStore, "variants" | "hasOrder" | "hasCredentials" | "totalPrice" | "itemCount" | "availableDeliveryMethodIds" | "paymentMethods" | "hasBonusesApplied" | "productQuantities">, Pick<CartStore, "setOrder" | "patchOrder" | "setCredentials" | "setLoading" | "setInitializing" | "adjustOptimistic" | "clearOptimistic" | "adjustLineOptimistic" | "setDeliveryMethods" | "setOrderSettings" | "setComment" | "setPersonsCount" | "setSelectedPaymentMethod" | "setSelectedPaymentBill" | "setSelectedCardTokenId" | "setSelectedSaveCard" | "setBonusesIntentEnabled" | "setDesiredBonusesAmount" | "setBonusesRequiresConfirmation" | "clearBonusesIntent" | "setDeliveryTimeIntent" | "restorePaymentSelection" | "validatePaymentSelection" | "setOrderPaymentsState" | "setCheckoutTotal" | "clearCart">>;
|
|
154
154
|
|
|
155
155
|
interface RewardSelectionContext {
|
|
156
156
|
type: string;
|
package/dist/stores/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { useProductsStore, useStore, useStorefrontProfile } from '../chunk-PTMSPB34.js';
|
|
2
|
-
export { useCatalogStore } from '../chunk-Z3IW4ODZ.js';
|
|
3
2
|
export { useCartStore, useOrderSettingsStore, usePromotionsStore } from '../chunk-Z247QRDJ.js';
|
|
3
|
+
export { useCatalogStore } from '../chunk-Z3IW4ODZ.js';
|
|
4
4
|
export { useAuthStore, useStoreProfileStore } from '../chunk-VFMVQR6Y.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
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-RAJDWCJU.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"]}
|