@zenky/storefront-vue 0.10.18 → 0.12.0
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 +107 -0
- package/dist/cart/index.js +6 -6
- package/dist/chunk-6HOKVW4M.js +134 -0
- package/dist/chunk-6HOKVW4M.js.map +1 -0
- package/dist/{chunk-LABBB43Q.js → chunk-CQDOEP6T.js} +163 -128
- package/dist/chunk-CQDOEP6T.js.map +1 -0
- package/dist/{chunk-6BXHWR5E.js → chunk-IEHN2WNU.js} +46 -13
- package/dist/chunk-IEHN2WNU.js.map +1 -0
- package/dist/chunk-JY3UJRMF.js +59 -0
- package/dist/chunk-JY3UJRMF.js.map +1 -0
- package/dist/{chunk-YTYCSTHP.js → chunk-PBBVWWMI.js} +3 -3
- package/dist/{chunk-YTYCSTHP.js.map → chunk-PBBVWWMI.js.map} +1 -1
- package/dist/{chunk-2DUKIVKC.js → chunk-QFKA2R6D.js} +3 -3
- package/dist/{chunk-2DUKIVKC.js.map → chunk-QFKA2R6D.js.map} +1 -1
- package/dist/{chunk-T52G6JN7.js → chunk-TXR76IDL.js} +16 -3
- package/dist/chunk-TXR76IDL.js.map +1 -0
- package/dist/{chunk-RURXGVWW.js → chunk-UJKWKD3W.js} +4 -56
- package/dist/chunk-UJKWKD3W.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -11
- package/dist/products/index.d.ts +42 -2
- package/dist/products/index.js +3 -2
- package/dist/promotions/index.js +2 -2
- package/dist/seo/index.d.ts +44 -16
- package/dist/seo/index.js +338 -104
- package/dist/seo/index.js.map +1 -1
- package/dist/stores/index.d.ts +3 -2
- package/dist/stores/index.js +3 -3
- package/dist/utils/index.js +2 -1
- package/docs/architecture.md +5 -3
- package/docs/consumer-setup.md +1 -1
- package/package.json +3 -3
- package/dist/chunk-6BXHWR5E.js.map +0 -1
- package/dist/chunk-LABBB43Q.js.map +0 -1
- package/dist/chunk-RURXGVWW.js.map +0 -1
- package/dist/chunk-T52G6JN7.js.map +0 -1
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/listingSchema.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 * Canonical public origin of the site, from `store.domain`. The fallback (request host)\n * is supplied by the consumer — the core doesn't know about `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 uses it for Rich Results (price, availability,\n * rating in search listings).\n * Returns an array of 0 or 1 objects — the consumer wraps it in a `<script ld+json>` tag.\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, ProductsCollection } from '@zenky/storefront-api'\n\nimport { resolveMediaUrl } from './utils'\nimport type { BreadcrumbItem } from './types'\n\n/**\n * JSON-LD for a product listing page: BreadcrumbList + ItemList (first 10 products).\n * Returns an array of 0-2 JSON-LD objects. Category and collection pages differ only\n * in the list name, so both go through here.\n * Spec: https://schema.org/ItemList · https://schema.org/BreadcrumbList\n */\nfunction buildListingSchemas(\n name: string | null,\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,\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\n/** JSON-LD for a category page. */\nexport function buildCategorySchemas(\n category: NestedCategory,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n return buildListingSchemas(category.name, products, breadcrumbs, origin)\n}\n\n/** JSON-LD for a products collection page. */\nexport function buildCollectionSchemas(\n collection: ProductsCollection,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n return buildListingSchemas(collection.name, products, breadcrumbs, origin)\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 for the offer page's editorial copy.\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 for a blog article — enables 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 // No separate datePublished field is available — reuse 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 key → 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 (per-day `hours` string like \"10:00-22:00\") → array of schema.org/OpeningHoursSpecification.\n * Days without a recognizable interval (day off / 24 hours / empty) are skipped.\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 (or LocalBusiness if there's a physical location)\n * for the homepage. Feeds Google's Knowledge Panel. All data comes from the\n * already-loaded profile.\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","/** Already-resolved OG/Twitter tag values (with the consumer's defaults applied). */\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 tags from a `Seo` entity (description + `Seo.meta` mapping). The consumer resolves the 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/ids.ts","../../src/seo/businessType.ts","../../src/seo/productSchema.ts","../../src/seo/breadcrumbSchema.ts","../../src/seo/listingSchema.ts","../../src/seo/articleSchema.ts","../../src/seo/openingHours.ts","../../src/seo/locationSchema.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\nconst INVISIBLE_CHARACTERS = /[\\u00ad\\u200b-\\u200d\\u2060\\ufeff]/g\nconst BLOCK_TAG =\n /<\\/?(?:p|div|br|li|ul|ol|h[1-6]|tr|td|th|table|blockquote|section|article|header|footer)\\b[^>]*>/gi\nconst ANY_TAG = /<[^>]*>/g\nconst HTML_ENTITY = /&(#x[0-9a-f]+|#\\d+|[a-z]+);/gi\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n nbsp: ' ',\n laquo: '«',\n raquo: '»',\n ndash: '–',\n mdash: '—',\n hellip: '…',\n}\n\nfunction decodeEntity(entity: string, body: string): string {\n const lower = body.toLowerCase()\n if (lower.startsWith('#')) {\n const code = lower.startsWith('#x')\n ? Number.parseInt(lower.slice(2), 16)\n : Number.parseInt(lower.slice(1), 10)\n return Number.isInteger(code) && code > 0 && code <= 0x10ffff\n ? String.fromCodePoint(code)\n : entity\n }\n return NAMED_ENTITIES[lower] ?? entity\n}\n\nexport function normalizeSchemaText(value: string | null | undefined): string {\n if (!value) return ''\n return value.replace(INVISIBLE_CHARACTERS, '').replace(/\\s+/g, ' ').trim()\n}\n\nexport function htmlToPlainText(html: string | null | undefined): string {\n if (!html) return ''\n const text = html\n .replace(BLOCK_TAG, ' ')\n .replace(ANY_TAG, '')\n .replace(HTML_ENTITY, (entity, body: string) => decodeEntity(entity, body))\n return normalizeSchemaText(text)\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 * Canonical public origin of the site, from `store.domain`. The fallback (request host)\n * is supplied by the consumer — the core doesn't know about `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","export function organizationSchemaId(origin: string): string {\n return `${origin}/#organization`\n}\n\nexport function webSiteSchemaId(origin: string): string {\n return `${origin}/#website`\n}\n\nexport function locationAnchorId(stockId: string): string {\n return `location-${stockId}`\n}\n\nexport function locationSchemaId(origin: string, stockId: string): string {\n return `${origin}/#${locationAnchorId(stockId)}`\n}\n\nexport function productSchemaId(productUrl: string): string {\n return `${productUrl}#product`\n}\n","import type { Stock } from '@zenky/storefront-api'\n\nimport { normalizeSchemaText } from './utils'\n\nexport const BUSINESS_TYPES = [\n 'Restaurant',\n 'CafeOrCoffeeShop',\n 'FastFoodRestaurant',\n 'Bakery',\n 'BarOrPub',\n 'GroceryStore',\n 'ConvenienceStore',\n 'Florist',\n 'Pharmacy',\n 'PetStore',\n 'ClothingStore',\n 'Store',\n 'LocalBusiness',\n] as const\n\nexport type BusinessType = (typeof BUSINESS_TYPES)[number]\n\nconst FOOD_VENUE =\n /(?:^|[^\\p{L}])(?:ресторан\\p{L}*|кафе|кофейн\\p{L}*|бистро|пиццери\\p{L}*|бар(?:а|у|ом|е|ы|ов)?|паб(?:а|у|ом|е|ы|ов)?|restaurants?|caf[eé]s?|coffee|bistro|pizzeria|bars?|pubs?)(?!\\p{L})/iu\nconst PICKUP_POINT = /самовывоз|выдач|pick-?up/iu\n\nexport function isBusinessType(value: unknown): value is BusinessType {\n return typeof value === 'string' && (BUSINESS_TYPES as readonly string[]).includes(value)\n}\n\nexport function resolveLocationType(\n stock: Pick<Stock, 'name'>,\n businessType?: BusinessType | null\n): BusinessType {\n const name = normalizeSchemaText(stock.name)\n const isFoodVenue = FOOD_VENUE.test(name)\n\n if (!businessType) return isFoodVenue ? 'Restaurant' : 'LocalBusiness'\n if (!isFoodVenue && PICKUP_POINT.test(name)) return 'LocalBusiness'\n\n return businessType\n}\n","import { UnitType } from '@zenky/storefront-api'\n\nimport type { Product } from '@zenky/storefront-api'\n\nimport { minorToMajorString } from '../money'\nimport { getProductWeight } from '../products/formatWeight'\nimport { getRequiredModifiersMinCost, resolveVariantPrice } from '../products/useProductPricing'\nimport { productSchemaId } from './ids'\nimport { htmlToPlainText, normalizeSchemaText, resolveMediaUrl } from './utils'\n\nexport interface ProductSchemaOptions {\n url?: string | null\n stockId?: string | null\n seller?: Record<string, unknown> | null\n}\n\nexport interface ProductOffer {\n '@type': 'Offer' | 'AggregateOffer'\n price?: string\n lowPrice?: string\n highPrice?: string\n offerCount?: number\n priceCurrency: string\n availability: string\n sku?: string\n}\n\nconst IN_STOCK = 'https://schema.org/InStock'\n\nconst WEIGHT_UNIT_CODES: Partial<Record<UnitType, string>> = {\n [UnitType.Piece]: 'GRM',\n [UnitType.Gram]: 'GRM',\n [UnitType.Kilogram]: 'KGM',\n}\n\nfunction buildWeight(product: Product): Record<string, unknown> | null {\n const weight = getProductWeight(product)\n const unitCode = WEIGHT_UNIT_CODES[product.unit_type]\n if (!weight || weight < 0 || !unitCode) return null\n\n return { '@type': 'QuantitativeValue', value: weight, unitCode }\n}\n\nexport function buildProductOffer(\n product: Product,\n currency: string,\n stockId?: string | null\n): ProductOffer | null {\n const requiredModifiersCost = getRequiredModifiersMinCost(product)\n const priced = (product.variants ?? [])\n .map((variant) => ({\n variant,\n price: resolveVariantPrice(variant, stockId).price + requiredModifiersCost,\n }))\n .filter(({ price }) => price > 0)\n\n const [first] = priced\n if (!first) return null\n\n if (priced.length > 1) {\n const prices = priced.map(({ price }) => price)\n return {\n '@type': 'AggregateOffer',\n lowPrice: minorToMajorString(Math.min(...prices), currency),\n highPrice: minorToMajorString(Math.max(...prices), currency),\n offerCount: priced.length,\n priceCurrency: currency,\n availability: IN_STOCK,\n }\n }\n\n const sku = first.variant.sku\n return {\n '@type': 'Offer',\n price: minorToMajorString(first.price, currency),\n priceCurrency: currency,\n availability: IN_STOCK,\n ...(sku ? { sku } : {}),\n }\n}\n\nexport function buildProductSchema(\n product: Product,\n currency: string,\n options: ProductSchemaOptions = {}\n): Record<string, unknown>[] {\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Product',\n }\n\n if (options.url) {\n schema['@id'] = productSchemaId(options.url)\n schema.url = options.url\n }\n\n schema.name = normalizeSchemaText(product.name)\n\n const description = htmlToPlainText(product.description)\n if (description) schema.description = description\n\n const images = (product.images ?? []).map(resolveMediaUrl).filter((url): url is string => !!url)\n if (images.length) schema.image = images\n\n const variants = product.variants ?? []\n const sku = variants.length === 1 ? variants[0]?.sku : null\n if (sku) schema.sku = sku\n\n const category = normalizeSchemaText(product.categories?.[0]?.name)\n if (category) schema.category = category\n\n const weight = buildWeight(product)\n if (weight) schema.weight = weight\n\n const offer = buildProductOffer(product, currency, options.stockId)\n if (offer) {\n schema.offers = {\n ...offer,\n ...(options.url ? { url: options.url } : {}),\n ...(options.seller ? { seller: options.seller } : {}),\n }\n }\n\n return [schema]\n}\n","import type { BreadcrumbItem } from './types'\nimport { normalizeSchemaText } from './utils'\n\nfunction toAbsoluteUrl(path: string, origin: string): string {\n return /^https?:\\/\\//i.test(path) ? path : `${origin}${path}`\n}\n\nexport function buildBreadcrumbListSchema(\n items: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n const crumbs = items\n .map((item) => ({ name: normalizeSchemaText(item.label), to: item.to }))\n .filter((crumb) => crumb.name)\n\n if (!crumbs.length) return []\n\n return [\n {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: crumbs.map((crumb, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: crumb.name,\n ...(crumb.to ? { item: toAbsoluteUrl(crumb.to, origin) } : {}),\n })),\n },\n ]\n}\n","import type { NestedCategory, Product, ProductsCollection } from '@zenky/storefront-api'\n\nimport { buildBreadcrumbListSchema } from './breadcrumbSchema'\nimport type { BreadcrumbItem } from './types'\nimport { normalizeSchemaText, resolveMediaUrl } from './utils'\n\n/**\n * JSON-LD for a product listing page: BreadcrumbList + ItemList (first 10 products).\n * Returns an array of 0-2 JSON-LD objects. Category and collection pages differ only\n * in the list name, so both go through here.\n * Spec: https://schema.org/ItemList · https://schema.org/BreadcrumbList\n */\nfunction buildListingSchemas(\n name: string | null,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n const schemas = buildBreadcrumbListSchema(breadcrumbs, origin)\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,\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: normalizeSchemaText(product.name),\n }\n\n if (image) item.image = image\n\n return item\n }),\n })\n }\n\n return schemas\n}\n\n/** JSON-LD for a category page. */\nexport function buildCategorySchemas(\n category: NestedCategory,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n return buildListingSchemas(category.name, products, breadcrumbs, origin)\n}\n\n/** JSON-LD for a products collection page. */\nexport function buildCollectionSchemas(\n collection: ProductsCollection,\n products: Product[],\n breadcrumbs: BreadcrumbItem[],\n origin: string\n): Record<string, unknown>[] {\n return buildListingSchemas(collection.name, products, breadcrumbs, origin)\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 for the offer page's editorial copy.\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 for a blog article — enables 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 // No separate datePublished field is available — reuse updated_at.\n schema.datePublished = article.updated_at\n }\n\n return [schema]\n}\n","import type { Schedule } from '@zenky/storefront-api'\n\nconst SCHEMA_DAYS = [\n ['monday', 'Monday'],\n ['tuesday', 'Tuesday'],\n ['wednesday', 'Wednesday'],\n ['thursday', 'Thursday'],\n ['friday', 'Friday'],\n ['saturday', 'Saturday'],\n ['sunday', 'Sunday'],\n] as const\n\nconst ROUND_THE_CLOCK = /^\\s*0?0:00\\s*[-–—]\\s*0?0:00\\s*$|круглосуточно|24\\s*\\/\\s*7|24\\s*час/iu\nconst SHIFT = /(\\d{1,2}):(\\d{2})\\D+?(\\d{1,2}):(\\d{2})/g\n\ninterface OpeningHoursGroup {\n opens: string\n closes: string\n days: string[]\n}\n\nfunction formatTime(hours: string, minutes: string): string | null {\n const hour = Number(hours)\n const minute = Number(minutes)\n if (hour > 24 || minute > 59 || (hour === 24 && minute > 0)) return null\n if (hour === 24) return '23:59'\n return `${String(hour).padStart(2, '0')}:${minutes}`\n}\n\nfunction parseShifts(hours: string): [string, string][] {\n if (ROUND_THE_CLOCK.test(hours)) return [['00:00', '23:59']]\n\n const shifts: [string, string][] = []\n for (const [, openHour, openMinute, closeHour, closeMinute] of hours.matchAll(SHIFT)) {\n const opens = formatTime(openHour ?? '', openMinute ?? '')\n const closes = formatTime(closeHour ?? '', closeMinute ?? '')\n if (opens && closes) shifts.push([opens, closes])\n }\n return shifts\n}\n\nexport function buildOpeningHoursSpecification(\n schedule: Schedule | null | undefined\n): Record<string, unknown>[] {\n if (!schedule?.days) return []\n\n const groups: OpeningHoursGroup[] = []\n for (const [key, dayOfWeek] of SCHEMA_DAYS) {\n const hours = schedule.days[key]?.hours\n if (!hours) continue\n\n for (const [opens, closes] of parseShifts(hours)) {\n const group = groups.find((item) => item.opens === opens && item.closes === closes)\n if (group) group.days.push(dayOfWeek)\n else groups.push({ opens, closes, days: [dayOfWeek] })\n }\n }\n\n return groups.map(({ opens, closes, days }) => ({\n '@type': 'OpeningHoursSpecification',\n dayOfWeek: days,\n opens,\n closes,\n }))\n}\n","import type { City, GeoLocation, Stock, Store } from '@zenky/storefront-api'\n\nimport { type BusinessType, resolveLocationType } from './businessType'\nimport { locationSchemaId, organizationSchemaId } from './ids'\nimport { buildOpeningHoursSpecification } from './openingHours'\nimport { htmlToPlainText, normalizeSchemaText, resolveStoreLogoUrl } from './utils'\n\nexport interface LocationSchemaOptions {\n businessType?: BusinessType | null\n locationUrl?: ((stock: Stock) => string | null | undefined) | null\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction normalizeStreetAddress(address: string | null | undefined, cityName: string): string {\n const street = normalizeSchemaText(address)\n if (!street || !cityName) return street\n\n const city = `(?:г\\\\.?|город)?\\\\s*${escapeRegExp(cityName)}`\n const cityPrefix = new RegExp(`^${city}\\\\s*,\\\\s*`, 'iu')\n const citySuffix = new RegExp(`\\\\s*,\\\\s*${city}$`, 'iu')\n return street.replace(cityPrefix, '').replace(citySuffix, '') || street\n}\n\nfunction hasCoordinates(coordinates: GeoLocation | null | undefined): coordinates is GeoLocation {\n if (!coordinates) return false\n\n const { latitude, longitude } = coordinates\n if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) return false\n\n return latitude !== 0 || longitude !== 0\n}\n\nfunction buildLocationNode(\n stock: Stock,\n city: City,\n store: Store,\n origin: string,\n options: LocationSchemaOptions\n): Record<string, unknown> | null {\n const cityName = normalizeSchemaText(city.name)\n const streetAddress = normalizeStreetAddress(stock.address, cityName)\n if (!streetAddress) return null\n\n const node: Record<string, unknown> = {\n '@type': resolveLocationType(stock, options.businessType),\n '@id': locationSchemaId(origin, stock.id),\n name: normalizeSchemaText(stock.name) || normalizeSchemaText(store.name),\n }\n\n const description = htmlToPlainText(stock.description)\n if (description) node.description = description\n\n const url = options.locationUrl?.(stock)\n if (url) node.url = url\n\n const image = resolveStoreLogoUrl(store)\n if (image) node.image = image\n\n const telephone =\n stock.phones?.[0]?.number || city.phones?.[0]?.number || store.phones?.[0]?.number\n if (telephone) node.telephone = telephone\n\n node.address = {\n '@type': 'PostalAddress',\n streetAddress,\n ...(cityName ? { addressLocality: cityName } : {}),\n addressCountry: store.settings?.country || 'RU',\n }\n\n if (hasCoordinates(stock.coordinates)) {\n const { latitude, longitude } = stock.coordinates\n node.geo = { '@type': 'GeoCoordinates', latitude, longitude }\n node.hasMap = `https://yandex.ru/maps/?pt=${longitude},${latitude}&z=17&l=map`\n }\n\n const openingHours = buildOpeningHoursSpecification(stock.schedule)\n if (openingHours.length) node.openingHoursSpecification = openingHours\n\n node.parentOrganization = { '@id': organizationSchemaId(origin) }\n\n return node\n}\n\nexport function buildLocationNodes(\n store: Store,\n origin: string,\n options: LocationSchemaOptions = {}\n): Record<string, unknown>[] {\n const seen = new Set<string>()\n const nodes: Record<string, unknown>[] = []\n\n for (const city of store.cities ?? []) {\n for (const stock of city.stocks ?? []) {\n if (seen.has(stock.id)) continue\n\n const node = buildLocationNode(stock, city, store, origin, options)\n if (!node) continue\n\n seen.add(stock.id)\n nodes.push(node)\n }\n }\n\n return nodes\n}\n","import type { Store } from '@zenky/storefront-api'\n\nimport { getEmailLink, getSocialLinks } from '../utils/contacts'\nimport { organizationSchemaId, webSiteSchemaId } from './ids'\nimport { buildLocationNodes, type LocationSchemaOptions } from './locationSchema'\nimport { normalizeSchemaText, resolveStoreLogoUrl } from './utils'\n\nexport interface OrganizationSchemaOptions extends LocationSchemaOptions {\n inLanguage?: string | null\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values.filter(Boolean))]\n}\n\nexport function buildOrganizationReference(store: Store, origin: string): Record<string, unknown> {\n return {\n '@type': 'Organization',\n '@id': organizationSchemaId(origin),\n name: normalizeSchemaText(store.name),\n url: `${origin}/`,\n }\n}\n\nfunction buildOrganizationNode(store: Store, origin: string): Record<string, unknown> {\n const node = buildOrganizationReference(store, origin)\n\n const logo = resolveStoreLogoUrl(store)\n if (logo) node.logo = logo\n\n const phones = unique((store.phones ?? []).map((phone) => phone.number))\n if (phones.length) node.telephone = phones.length === 1 ? phones[0] : phones\n\n const email = getEmailLink(store.links ?? [])\n if (email) node.email = email\n\n const sameAs = unique(getSocialLinks(store.links ?? []).map((link) => link.url))\n if (sameAs.length) node.sameAs = sameAs\n\n const cities = store.cities ?? []\n const cityName = cities.length === 1 ? normalizeSchemaText(cities[0]?.name) : ''\n if (cityName) {\n node.address = {\n '@type': 'PostalAddress',\n addressLocality: cityName,\n addressCountry: store.settings?.country || 'RU',\n }\n }\n\n return node\n}\n\nfunction buildWebSiteNode(\n store: Store,\n origin: string,\n inLanguage: string | null | undefined\n): Record<string, unknown> {\n return {\n '@type': 'WebSite',\n '@id': webSiteSchemaId(origin),\n url: `${origin}/`,\n name: normalizeSchemaText(store.name),\n ...(inLanguage ? { inLanguage } : {}),\n publisher: { '@id': organizationSchemaId(origin) },\n }\n}\n\nexport function buildOrganizationSchema(\n store: Store,\n origin: string,\n options: OrganizationSchemaOptions = {}\n): Record<string, unknown>[] {\n return [\n {\n '@context': 'https://schema.org',\n '@graph': [\n buildOrganizationNode(store, origin),\n buildWebSiteNode(store, origin, options.inLanguage),\n ...buildLocationNodes(store, origin, options),\n ],\n },\n ]\n}\n\nexport function buildLocationsSchema(\n store: Store,\n origin: string,\n options: LocationSchemaOptions = {}\n): Record<string, unknown>[] {\n const locations = buildLocationNodes(store, origin, options)\n if (!locations.length) return []\n\n return [\n {\n '@context': 'https://schema.org',\n '@graph': [buildOrganizationNode(store, origin), ...locations],\n },\n ]\n}\n","/** Already-resolved OG/Twitter tag values (with the consumer's defaults applied). */\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 tags from a `Seo` entity (description + `Seo.meta` mapping). The consumer resolves the 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
|
@@ -3,7 +3,7 @@ import * as vue from 'vue';
|
|
|
3
3
|
import { Ref, ComputedRef } from 'vue';
|
|
4
4
|
import { S as StaticCatalogItem } from '../catalogEntity-C2UxCFng.js';
|
|
5
5
|
import * as _zenky_storefront_api from '@zenky/storefront-api';
|
|
6
|
-
import { Product, Store, City, Stock, NestedCategory, DeliveryMethod, Order, OrderDeliveryMethod, OrderSettings, OrderCheckoutTotal, PaymentMethod, OrderPaymentTransaction, OrderProductVariant, OrderPaymentMethod } from '@zenky/storefront-api';
|
|
6
|
+
import { Product, Store, City, Stock, NestedCategory, DeliveryMethod, Order, OrderDeliveryMethod, OrderSettings, OrderCheckoutTotal, PaymentMethod, OrderPackage, OrderPaymentTransaction, OrderProductVariant, OrderPaymentMethod } from '@zenky/storefront-api';
|
|
7
7
|
import { Website } from '../website-settings/index.js';
|
|
8
8
|
import { a as AuthStep, f as CodeContext, g as ConfirmationChannel, e as ChannelIntent, S as SelectableConfirmationChannel } from '../types-CXm2F6Hz.js';
|
|
9
9
|
import { R as RecaptchaPayloadProvider } from '../useCheckoutSubmit-C934F26-.js';
|
|
@@ -174,6 +174,7 @@ interface CartStore {
|
|
|
174
174
|
minPriceViolation: Ref<MinPriceViolation | null>;
|
|
175
175
|
setOrder: (order: Order) => void;
|
|
176
176
|
patchOrder: (partial: Order) => void;
|
|
177
|
+
setOrderPackages: (packages: OrderPackage[], packagingPrice: number | null) => void;
|
|
177
178
|
setCredentials: (credentials: CartCredentials) => void;
|
|
178
179
|
setLoading: (value: boolean) => void;
|
|
179
180
|
setInitializing: (value: boolean) => void;
|
|
@@ -210,7 +211,7 @@ interface CartStore {
|
|
|
210
211
|
hasBonusesApplied: ComputedRef<boolean>;
|
|
211
212
|
productQuantities: ComputedRef<Record<string, number>>;
|
|
212
213
|
}
|
|
213
|
-
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" | "clearOrderSettings" | "setComment" | "setPersonsCount" | "setSelectedPaymentMethod" | "setSelectedPaymentBill" | "setSelectedCardTokenId" | "setSelectedSaveCard" | "setBonusesIntentEnabled" | "setDesiredBonusesAmount" | "setBonusesRequiresConfirmation" | "clearBonusesIntent" | "setDeliveryTimeIntent" | "restorePaymentSelection" | "validatePaymentSelection" | "setOrderPaymentsState" | "setCheckoutTotal" | "clearCheckoutTotal" | "clearCart">>;
|
|
214
|
+
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" | "setOrderPackages" | "setCredentials" | "setLoading" | "setInitializing" | "adjustOptimistic" | "clearOptimistic" | "adjustLineOptimistic" | "setDeliveryMethods" | "setOrderSettings" | "clearOrderSettings" | "setComment" | "setPersonsCount" | "setSelectedPaymentMethod" | "setSelectedPaymentBill" | "setSelectedCardTokenId" | "setSelectedSaveCard" | "setBonusesIntentEnabled" | "setDesiredBonusesAmount" | "setBonusesRequiresConfirmation" | "clearBonusesIntent" | "setDeliveryTimeIntent" | "restorePaymentSelection" | "validatePaymentSelection" | "setOrderPaymentsState" | "setCheckoutTotal" | "clearCheckoutTotal" | "clearCart">>;
|
|
214
215
|
|
|
215
216
|
interface RewardSelectionContext {
|
|
216
217
|
type: string;
|
package/dist/stores/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { RESEND_TIMER_SECONDS, useAuthFlowStore, useProductsStore, useStore, useStorefrontProfile } from '../chunk-
|
|
1
|
+
export { RESEND_TIMER_SECONDS, useAuthFlowStore, useProductsStore, useStore, useStorefrontProfile } from '../chunk-PBBVWWMI.js';
|
|
2
2
|
import '../chunk-5B2P5W3E.js';
|
|
3
3
|
import '../chunk-TE42OCFK.js';
|
|
4
4
|
export { usePromotionsStore } from '../chunk-544USTPB.js';
|
|
5
|
-
export { useCatalogStore } from '../chunk-4JCJHAL3.js';
|
|
6
|
-
export { useAuthStore, useCartStore, useOrderSettingsStore } from '../chunk-T52G6JN7.js';
|
|
7
5
|
import '../chunk-TIQ7AJLY.js';
|
|
6
|
+
export { useCatalogStore } from '../chunk-4JCJHAL3.js';
|
|
7
|
+
export { useAuthStore, useCartStore, useOrderSettingsStore } from '../chunk-TXR76IDL.js';
|
|
8
8
|
export { useStoreProfileStore } from '../chunk-IOYYCA75.js';
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { buildQrCodeUrl, createOperationChain, formatAddressCityLast, formatDate, formatDateTime, formatPhoneNational, formatPhoneSpaced, formatScheduleStatus, getApiErrorMessage, getApiFieldErrors,
|
|
1
|
+
export { buildQrCodeUrl, createOperationChain, formatAddressCityLast, formatDate, formatDateTime, formatPhoneNational, formatPhoneSpaced, formatScheduleStatus, getApiErrorMessage, getApiFieldErrors, getPhoneTelLink, getTodayInfo, getWeeklySchedule, groupScheduleDays, pluralize, toDateInputValue, todayInTimezone } from '../chunk-UJKWKD3W.js';
|
|
2
|
+
export { getEmailLink, getSocialLinks, getWebsiteLink } from '../chunk-JY3UJRMF.js';
|
|
2
3
|
export { createDebounce } from '../chunk-XUGXLJZB.js';
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/docs/architecture.md
CHANGED
|
@@ -34,9 +34,11 @@ section). This list says what each one owns.
|
|
|
34
34
|
(`useProductDetail`, `useProductList`), and related-product recommendations.
|
|
35
35
|
- **`promotions/`** — checking whether the cart still qualifies for a promotion reward
|
|
36
36
|
after it changes.
|
|
37
|
-
- **`seo/`** — JSON-LD builders (
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
- **`seo/`** — JSON-LD builders (the store graph: `Organization` + `WebSite` + one node per
|
|
38
|
+
location with stable `@id`s; `Product` with a stock-aware `Offer`; `BreadcrumbList` +
|
|
39
|
+
`ItemList`; `BlogPosting`/`Article`) and OG-tag records. These return plain data;
|
|
40
|
+
turning that data into `<head>` tags is the consumer's job (see the README's note on
|
|
41
|
+
`useHead`).
|
|
40
42
|
- **`snippets/`** — normalizing the snippet records a website carries (tracking scripts,
|
|
41
43
|
custom CSS) into a consistent shape.
|
|
42
44
|
- **`stores/`** — the eight Pinia stores: `auth`, `authFlow`, `cart`, `catalog`,
|
package/docs/consumer-setup.md
CHANGED
|
@@ -11,7 +11,7 @@ Use an exact version while integrating or testing a prerelease. Upgrade delibera
|
|
|
11
11
|
after the consumer quality gate is green.
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install --save-exact @zenky/storefront-vue@0.
|
|
14
|
+
npm install --save-exact @zenky/storefront-vue@0.12.0
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
The consumer must also provide compatible peer dependencies:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenky/storefront-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Zenky Storefront SDK for Vue 3.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"zenky",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
},
|
|
120
120
|
"peerDependencies": {
|
|
121
121
|
"@zenky/integrations-sdk": ">=0.1.3",
|
|
122
|
-
"@zenky/storefront-api": "^1.
|
|
122
|
+
"@zenky/storefront-api": "^1.7.0",
|
|
123
123
|
"pinia": "^3.0.0",
|
|
124
124
|
"vue": "^3.5.0"
|
|
125
125
|
},
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"@types/node": "^22.10.0",
|
|
130
130
|
"@vitest/coverage-v8": "^4.1.10",
|
|
131
131
|
"@zenky/integrations-sdk": "^0.1.3",
|
|
132
|
-
"@zenky/storefront-api": "^1.
|
|
132
|
+
"@zenky/storefront-api": "^1.7.0",
|
|
133
133
|
"pinia": "^3.0.4",
|
|
134
134
|
"publint": "^0.3.21",
|
|
135
135
|
"tsup": "^8.3.5",
|