@cartbase/storefront 0.1.2 → 0.3.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.
Files changed (106) hide show
  1. package/README.md +3 -3
  2. package/package.json +231 -226
  3. package/src/api/auth.ts +1 -1
  4. package/src/api/carts.ts +5 -3
  5. package/src/api/checkout.ts +91 -40
  6. package/src/api/consent.ts +2 -2
  7. package/src/api/integrations.ts +4 -17
  8. package/src/api/regions.ts +1 -1
  9. package/src/cart-drawer/context.tsx +4 -4
  10. package/src/cart-drawer/cross-sell-carousel.tsx +1 -1
  11. package/src/cart-drawer/cross-sell-sidebar.tsx +1 -1
  12. package/src/cart-drawer/header.tsx +1 -1
  13. package/src/cart-drawer/item/index.tsx +2 -2
  14. package/src/cart-drawer/item/quantity.tsx +2 -2
  15. package/src/cart-drawer/item/upsell.tsx +3 -3
  16. package/src/cart-drawer/item/variant.tsx +2 -2
  17. package/src/cart-drawer/labels-bg.ts +2 -2
  18. package/src/cart-drawer/labels.ts +119 -119
  19. package/src/cart-drawer/summary-breakdown.tsx +197 -196
  20. package/src/cart-drawer/template.tsx +2 -2
  21. package/src/cart-drawer/tiered-progress.tsx +1 -1
  22. package/src/checkout/address-error-copy.ts +3 -3
  23. package/src/checkout/address-form.tsx +2 -2
  24. package/src/checkout/address-select.tsx +1 -1
  25. package/src/checkout/boxnow-locker-selector.tsx +3 -3
  26. package/src/checkout/checkout-client.tsx +15 -12
  27. package/src/checkout/company-details.tsx +1 -1
  28. package/src/checkout/compare-addresses.ts +1 -1
  29. package/src/checkout/discount-section.tsx +5 -5
  30. package/src/checkout/econt-office-selector.tsx +2 -2
  31. package/src/checkout/gift-card-section.tsx +2 -2
  32. package/src/checkout/index.ts +0 -1
  33. package/src/checkout/labels-bg.ts +2 -2
  34. package/src/checkout/labels.ts +263 -263
  35. package/src/checkout/line-item-card.tsx +2 -2
  36. package/src/checkout/order-summary.tsx +48 -48
  37. package/src/checkout/payment-button.tsx +4 -4
  38. package/src/checkout/payment-error-copy.ts +6 -6
  39. package/src/checkout/payment-method-list.tsx +93 -33
  40. package/src/checkout/payment-wrapper.tsx +8 -11
  41. package/src/checkout/promotion-error-copy.ts +2 -2
  42. package/src/checkout/shipping-method-list.tsx +2 -2
  43. package/src/checkout/stripe-wrapper.tsx +1 -1
  44. package/src/checkout/use-checkout-orchestration.ts +108 -98
  45. package/src/common/cart-button-client.tsx +1 -1
  46. package/src/common/cart-button.tsx +1 -1
  47. package/src/common/country-select.tsx +2 -2
  48. package/src/common/delete-button.tsx +1 -1
  49. package/src/common/index.ts +1 -1
  50. package/src/common/language-select.tsx +2 -2
  51. package/src/common/localized-link.tsx +1 -1
  52. package/src/lib/cart-helpers.ts +2 -2
  53. package/src/lib/cookie-names.ts +41 -0
  54. package/src/lib/get-product-price.ts +3 -3
  55. package/src/lib/payment-constants.ts +53 -66
  56. package/src/lib/store-api-error.ts +1 -1
  57. package/src/order/index.ts +1 -1
  58. package/src/order/labels-bg.ts +39 -39
  59. package/src/order/labels.ts +79 -79
  60. package/src/order/order-address-card.tsx +1 -1
  61. package/src/order/order-completed-template.tsx +20 -12
  62. package/src/order/order-confirmation-header.tsx +1 -1
  63. package/src/order/order-delivery-card.tsx +3 -3
  64. package/src/order/order-item.tsx +2 -2
  65. package/src/order/order-items-list.tsx +3 -3
  66. package/src/order/order-payment-card.tsx +27 -36
  67. package/src/order/order-timeline.tsx +2 -2
  68. package/src/order/order-totals.tsx +250 -245
  69. package/src/platform/identity.ts +18 -0
  70. package/src/platform/index.ts +8 -0
  71. package/src/platform/metadata.ts +26 -0
  72. package/src/platform/platform-init.tsx +46 -0
  73. package/src/products/image-gallery.tsx +1 -1
  74. package/src/products/mobile-actions.tsx +1 -1
  75. package/src/products/option-select.tsx +1 -1
  76. package/src/products/preview-price.tsx +1 -1
  77. package/src/products/product-actions.tsx +6 -6
  78. package/src/products/product-info.tsx +1 -1
  79. package/src/products/product-preview.tsx +1 -1
  80. package/src/products/product-price.tsx +2 -2
  81. package/src/products/product-tabs.tsx +1 -1
  82. package/src/products/purchase-options.tsx +1 -1
  83. package/src/products/related-products.tsx +3 -3
  84. package/src/products/variant-matching.ts +4 -4
  85. package/src/reviews-ui/labels.ts +1 -1
  86. package/src/reviews-ui/photo-upload.tsx +1 -1
  87. package/src/reviews-ui/review-list.tsx +1 -1
  88. package/src/reviews-ui/review-widget.tsx +1 -1
  89. package/src/reviews-ui/review-wizard.tsx +1 -1
  90. package/src/reviews-ui/wizard-state.ts +1 -1
  91. package/src/store/category-template.tsx +2 -2
  92. package/src/store/collection-template.tsx +2 -2
  93. package/src/store/labels.ts +2 -2
  94. package/src/store/paginated-products.tsx +1 -1
  95. package/src/store/search-params.ts +1 -1
  96. package/src/store/search-template.tsx +1 -1
  97. package/src/tracking/consent-banner.tsx +1 -1
  98. package/src/tracking/consent-init.tsx +1 -1
  99. package/src/tracking/consent.ts +6 -6
  100. package/src/tracking/fbq.ts +2 -2
  101. package/src/tracking/get-tracking-attribution.ts +1 -1
  102. package/src/tracking/get-tracking-config.ts +2 -2
  103. package/src/tracking/index.ts +2 -2
  104. package/src/tracking/meta-pixel.tsx +1 -1
  105. package/src/tracking/rybbit.tsx +1 -1
  106. package/src/tracking/types.ts +6 -6
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @cartbase/storefront/platform — platform-fingerprint emitters
3
+ * (docs/cards/platform-fingerprints.md). Same barrel discipline as every
4
+ * other feature folder (tracking, checkout, cart-drawer, ...).
5
+ */
6
+ export { PLATFORM_NAME, PLATFORM_VERSION } from "./identity"
7
+ export { createStorefrontMetadata } from "./metadata"
8
+ export { PlatformInit, type PlatformInitProps, type CartbaseWindowGlobal } from "./platform-init"
@@ -0,0 +1,26 @@
1
+ import type { Metadata } from "next"
2
+ import { PLATFORM_NAME } from "./identity"
3
+
4
+ /**
5
+ * createStorefrontMetadata — root-layout metadata helper
6
+ * (platform-fingerprints card, fingerprint #1). Every storefront built on
7
+ * `@cartbase/storefront` calls this instead of hand-writing
8
+ * `export const metadata`, so `<meta name="generator" content="Cartbase" />`
9
+ * ships by construction on every storefront-rendered page.
10
+ *
11
+ * Usage:
12
+ *
13
+ * export const metadata: Metadata = createStorefrontMetadata({
14
+ * title: "My Store",
15
+ * description: "...",
16
+ * })
17
+ *
18
+ * `generator` always resolves to the platform name — it is not
19
+ * overridable from `overrides` (a stray key there is simply shadowed).
20
+ */
21
+ export function createStorefrontMetadata(overrides: Metadata = {}): Metadata {
22
+ return {
23
+ ...overrides,
24
+ generator: PLATFORM_NAME,
25
+ }
26
+ }
@@ -0,0 +1,46 @@
1
+ import { PLATFORM_VERSION } from "./identity"
2
+
3
+ /**
4
+ * The shape of `window.Cartbase` — the strongest platform-detection signal
5
+ * (same mechanism as `window.Shopify`). No PII: store id + platform
6
+ * version only.
7
+ */
8
+ export interface CartbaseWindowGlobal {
9
+ version: string
10
+ storeId: string
11
+ }
12
+
13
+ declare global {
14
+ interface Window {
15
+ Cartbase?: CartbaseWindowGlobal
16
+ }
17
+ }
18
+
19
+ export interface PlatformInitProps {
20
+ /** The store's client id — the ONLY identifying value exposed. */
21
+ storeId: string
22
+ }
23
+
24
+ /**
25
+ * PlatformInit — mounts `window.Cartbase = { version, storeId }`
26
+ * (platform-fingerprints card, fingerprint #3). Same shape as
27
+ * `<ConsentInit />` (`../tracking/consent-init.tsx`): a server component
28
+ * rendering one synchronous inline `<script>`, mounted once near the top
29
+ * of `<body>` — no hydration wait, no client bundle cost.
30
+ *
31
+ * Storefront-surface only. Never mount this in an admin bundle — admin is
32
+ * not a storefront (category discipline: Cartbase exists ONLY as
33
+ * Ecommerce, and `window.Cartbase` must only ever appear where commerce
34
+ * actually happens).
35
+ */
36
+ export function PlatformInit({ storeId }: PlatformInitProps) {
37
+ const payload: CartbaseWindowGlobal = { version: PLATFORM_VERSION, storeId }
38
+ return (
39
+ <script
40
+ id="cartbase-platform-init"
41
+ dangerouslySetInnerHTML={{
42
+ __html: `window.Cartbase=${JSON.stringify(payload)};`,
43
+ }}
44
+ />
45
+ )
46
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * PDP image gallery — ported from
3
3
  * `@1click/ui/src/products/image-gallery.tsx` (v2.3.1). Data seam:
4
- * `HttpTypes.StoreProductImage[]` → barter `StoreProductImage[]`
4
+ * `HttpTypes.StoreProductImage[]` → Cartbase `StoreProductImage[]`
5
5
  * (`@cartbase/storefront/api/products`; images arrive rank-ordered from the
6
6
  * API). Server-safe.
7
7
  */
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * Mobile sticky add-to-cart bar + options bottom sheet — ported from
5
5
  * `@1click/ui/src/products/mobile-actions.tsx` (v2.3.1). Data seam:
6
- * `HttpTypes.*` → barter SDK DTOs; everything else (layout, z-index
6
+ * `HttpTypes.*` → Cartbase SDK DTOs; everything else (layout, z-index
7
7
  * layering above the cart drawer, morphing show/hide transition) unchanged.
8
8
  * Pure-props component — the add flow lives in `ProductActions`.
9
9
  */
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * Option selector — ported from
5
5
  * `@1click/ui/src/products/option-select.tsx` (v2.3.1). Data seam:
6
- * `HttpTypes.StoreProductOption` → barter `StoreProductOption`
6
+ * `HttpTypes.StoreProductOption` → Cartbase `StoreProductOption`
7
7
  * (`@cartbase/storefront/api/products`; `values` is present on
8
8
  * `product.options[]`, which is what this component receives).
9
9
  */
@@ -2,7 +2,7 @@
2
2
  * Preview (card) price — ported from
3
3
  * `@1click/ui/src/products/preview-price.tsx` (v2.3.1) unchanged. Renders a
4
4
  * pre-computed `VariantPrice` (from `lib/get-product-price`, which reads the
5
- * server-computed `variant.calculated_price` — barter's flat
5
+ * server-computed `variant.calculated_price` — Cartbase's flat
6
6
  * `price_list_type` wire shape); this component never computes money.
7
7
  */
8
8
  import { cn } from "../lib/utils"
@@ -5,16 +5,16 @@
5
5
  * `@1click/ui/src/products/product-actions.tsx` (v2.3.1).
6
6
  *
7
7
  * Data-seam adaptations (batch-10 port):
8
- * - `HttpTypes.*` → barter SDK DTOs (`@cartbase/storefront/api/products`).
8
+ * - `HttpTypes.*` → Cartbase SDK DTOs (`@cartbase/storefront/api/products`).
9
9
  * - The `addToCart` server action (Medusa js-sdk, cart-cookie owner) is now
10
10
  * an injected prop: the host app wires it to its own cart orchestration
11
11
  * (typically `api/carts` `addLineItem` + its cart-id cookie). Same for the
12
12
  * cart drawer: `openCart` replaces the `useCartDrawer()` context import so
13
13
  * the products family has no hard dependency on the cart-drawer family.
14
- * - `countryCode` (Medusa region routing) is dropped — barter pricing
14
+ * - `countryCode` (Medusa region routing) is dropped — Cartbase pricing
15
15
  * context travels with the product fetch, and the host's `addToCart`
16
16
  * closes over whatever routing it needs.
17
- * - Stock: barter's store surface does NOT expose `inventory_quantity`
17
+ * - Stock: Cartbase's store surface does NOT expose `inventory_quantity`
18
18
  * (availability is a search facet; the server enforces stock at add with
19
19
  * 400 `insufficient_inventory`). Managed-inventory variants without an
20
20
  * exposed quantity are treated as in stock optimistically; a thrown
@@ -23,7 +23,7 @@
23
23
  * quantity check.
24
24
  *
25
25
  * Variant matching is the extracted pure module `./variant-matching`
26
- * (handles barter's option-value link shape).
26
+ * (handles Cartbase's option-value link shape).
27
27
  */
28
28
  import { usePathname, useRouter, useSearchParams } from "next/navigation"
29
29
  import { useEffect, useMemo, useRef, useState } from "react"
@@ -74,7 +74,7 @@ export function ProductActions({
74
74
  const [options, setOptions] = useState<Record<string, string | undefined>>({})
75
75
  const [isAdding, setIsAdding] = useState(false)
76
76
  // Set when the server rejected an add with `insufficient_inventory`
77
- // (barter exposes no inventory_quantity on the store surface — the server
77
+ // (Cartbase exposes no inventory_quantity on the store surface — the server
78
78
  // is the stock truth). Cleared when the selection changes.
79
79
  const [stockExhausted, setStockExhausted] = useState(false)
80
80
 
@@ -123,7 +123,7 @@ export function ProductActions({
123
123
  if (!selectedVariant) return false
124
124
  if (!selectedVariant.manage_inventory) return true
125
125
  if (selectedVariant.allow_backorder) return true
126
- // barter wire shape carries no inventory_quantity — optimistic; the
126
+ // Cartbase wire shape carries no inventory_quantity — optimistic; the
127
127
  // server enforces stock on add. Richer DTOs keep the original check.
128
128
  const qty = (selectedVariant as { inventory_quantity?: number })
129
129
  .inventory_quantity
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * PDP title/collection/description block — ported from
3
3
  * `@1click/ui/src/products/product-info.tsx` (v2.3.1). Data seam:
4
- * `HttpTypes.StoreProduct` → barter `StoreProduct` (the collection embed is
4
+ * `HttpTypes.StoreProduct` → Cartbase `StoreProduct` (the collection embed is
5
5
  * `{id, title, handle}` — exactly what the link needs). Server-safe.
6
6
  */
7
7
  import Link from "next/link"
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Product card — ported from `@1click/ui/src/products/product-preview.tsx`
3
- * (v2.3.1). Data seam: `HttpTypes.StoreProduct` → barter `StoreProduct`.
3
+ * (v2.3.1). Data seam: `HttpTypes.StoreProduct` → Cartbase `StoreProduct`.
4
4
  * The ONE card renderer per the SDK doctrine: search results, collection
5
5
  * membership pages, and related products all serve the same canonical
6
6
  * product object — reuse this card (or pass a custom one via the templates'
@@ -4,9 +4,9 @@
4
4
  * PDP price display — ported from
5
5
  * `@1click/ui/src/products/product-price.tsx` (v2.3.1). Data seam:
6
6
  * `@medusajs/types` `HttpTypes.StoreProduct/StoreProductVariant` are
7
- * replaced by the barter SDK DTOs (`@cartbase/storefront/api/products`).
7
+ * replaced by the Cartbase SDK DTOs (`@cartbase/storefront/api/products`).
8
8
  * Pricing stays SERVER truth — `lib/get-product-price` only selects and
9
- * formats `variant.calculated_price` (barter's flat `price_list_type`).
9
+ * formats `variant.calculated_price` (Cartbase's flat `price_list_type`).
10
10
  */
11
11
  import type { StoreProduct, StoreProductVariant } from "../api/products"
12
12
  import { cn } from "../lib/utils"
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * PDP info/shipping accordion — ported from
5
5
  * `@1click/ui/src/products/product-tabs.tsx` (v2.3.1). Data seam:
6
- * `HttpTypes.StoreProduct` → barter `StoreProduct` (same physical fields:
6
+ * `HttpTypes.StoreProduct` → Cartbase `StoreProduct` (same physical fields:
7
7
  * material, origin_country, type.value, weight, length/width/height).
8
8
  * Layout, morphing +/− trigger, and label wiring unchanged.
9
9
  */
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * PDP purchase options — one-time vs subscription plans (subscriptions-core
5
- * card, step 4; barter-native, no @1click/ui ancestor). Presentational and
5
+ * card, step 4; Cartbase-native, no @1click/ui ancestor). Presentational and
6
6
  * controlled: the host owns the selection and passes the chosen plan id
7
7
  * into its add-to-cart seam (`carts.addLineItem` `selling_plan_id`). The
8
8
  * SERVER prices the line — the preview here is display-only and computed
@@ -1,16 +1,16 @@
1
1
  /**
2
2
  * Related-products strip — ported from
3
3
  * `@1click/ui/src/products/related-products.tsx` (v2.3.1), REWIRED to the
4
- * barter related-products endpoint (docs/storefront/search.md).
4
+ * Cartbase related-products endpoint (docs/storefront/search.md).
5
5
  *
6
6
  * The original hand-rolled relatedness client-side (same collection + shared
7
- * tags via a products listing). barter owns that server-side:
7
+ * tags via a products listing). Cartbase owns that server-side:
8
8
  * `api/search` `listRelatedProducts` returns manual admin picks first
9
9
  * (Admin → Product → Related, position order), then a deterministic fallback
10
10
  * fills to `limit` — same primary collection (newest first), then
11
11
  * most-shared-tags (`auto_filled: true` when any fallback item is present).
12
12
  * The anchor product is never in the results, so the source's self-filter is
13
- * gone. Region resolution via `countryCode` is replaced by the barter
13
+ * gone. Region resolution via `countryCode` is replaced by the Cartbase
14
14
  * pricing context (`currency_code`/`region_id`).
15
15
  *
16
16
  * Async server component — render inside `<Suspense>`.
@@ -5,14 +5,14 @@
5
5
  * (tests/unit/storefront-catalog.test.ts).
6
6
  *
7
7
  * Data-seam translation: Medusa served `variant.options[]` as flat
8
- * `{option_id, value}` rows; barter serves option-value LINKS
8
+ * `{option_id, value}` rows; Cartbase serves option-value LINKS
9
9
  * (`{value: {option_id, value, option}}` — see
10
10
  * `@cartbase/storefront/api/products` `StoreVariantOptionValueLink`).
11
- * `optionsAsKeymap` reads the barter link shape (null-safe) and falls back
11
+ * `optionsAsKeymap` reads the Cartbase link shape (null-safe) and falls back
12
12
  * to the flat Medusa row shape so both wire formats resolve identically.
13
13
  */
14
14
 
15
- /** Either barter's option-value link or Medusa's flat option-value row. */
15
+ /** Either Cartbase's option-value link or Medusa's flat option-value row. */
16
16
  export type VariantOptionLike =
17
17
  | {
18
18
  option_id?: string
@@ -34,7 +34,7 @@ export function optionsAsKeymap(
34
34
  if (!varopt) return acc
35
35
  const v = varopt.value
36
36
  if (v && typeof v === "object") {
37
- // barter link shape: { value: { option_id, value } }
37
+ // Cartbase link shape: { value: { option_id, value } }
38
38
  if (v.option_id) acc[v.option_id] = v.value
39
39
  } else if (varopt.option_id && typeof v === "string") {
40
40
  // Medusa flat row shape: { option_id, value }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Reviews UI label pack. The Alenika production storefront shipped this
3
3
  * copy hardcoded in Bulgarian (src/components/product/reviews-list.tsx +
4
- * src/app/(main)/review/[token]/review-form.tsx); the barter port lifts
4
+ * src/app/(main)/review/[token]/review-form.tsx); the Cartbase port lifts
5
5
  * every string into the family's labels/labels-bg discipline. English
6
6
  * defaults here; the exact production Bulgarian copy in `labels-bg.ts`.
7
7
  *
@@ -18,7 +18,7 @@ import {
18
18
  /**
19
19
  * Review media uploader — drag-drop zone + preview grid + the signed-PUT
20
20
  * pipeline. Ported from the Alenika review-form's media handling
21
- * (src/app/(main)/review/[token]/review-form.tsx) with the barter seam:
21
+ * (src/app/(main)/review/[token]/review-form.tsx) with the Cartbase seam:
22
22
  * the signed URL comes from `api/reviews.createUploadUrl(client, {token,
23
23
  * name, type, size})` (docs/storefront/reviews.md) instead of the Medusa
24
24
  * `/store/files/upload-url` helper; the raw-file PUT to R2 is unchanged.
@@ -15,7 +15,7 @@ import { StarRow } from "./star-badge"
15
15
  * media is filtered out server-side — the client just renders what it
16
16
  * gets).
17
17
  *
18
- * Verified-purchaser badge is unconditional — every barter review comes
18
+ * Verified-purchaser badge is unconditional — every Cartbase review comes
19
19
  * from a tokenized post-purchase email, so the badge is a tautology of
20
20
  * the system, not an opt-in flag.
21
21
  *
@@ -17,7 +17,7 @@ import { ReviewList } from "./review-list"
17
17
  /**
18
18
  * PDP reviews widget: aggregate header (score + distribution + sort) +
19
19
  * masonry card list + load-more. Ported from the Alenika PDP section
20
- * (src/components/product/reviews-list.tsx) with the barter data seam:
20
+ * (src/components/product/reviews-list.tsx) with the Cartbase data seam:
21
21
  *
22
22
  * - Bootstrap is ONE call — `api/reviews.getWidget(client, productId)`
23
23
  * (aggregate + first page sized/sorted per the store's Settings →
@@ -29,7 +29,7 @@ import {
29
29
  * The review token wizard — everything behind `<review_link_base>/<token>`.
30
30
  * Ported from the Alenika production storefront: the /review/[token]
31
31
  * server page's branching (page.tsx) AND the two-step client form
32
- * (review-form.tsx), merged into one component over the barter SDK:
32
+ * (review-form.tsx), merged into one component over the Cartbase SDK:
33
33
  *
34
34
  * entry: `resolveWizardEntry(validation)` — invalid/expired panels,
35
35
  * the terminal "already submitted" panel, or the form at the
@@ -25,7 +25,7 @@ export type WizardEntry =
25
25
  }
26
26
 
27
27
  /**
28
- * THE resume rule (production behavior, verified against barter's token
28
+ * THE resume rule (production behavior, verified against Cartbase's token
29
29
  * endpoint in batch 9): a consumed token does NOT mean "done".
30
30
  *
31
31
  * - `valid: false` → invalid panel
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Category page — ported from
3
3
  * `@1click/ui/src/store/category-template.tsx` (v2.3.1). Data seam:
4
- * `HttpTypes.StoreProductCategory` → barter `StoreProductCategory`
4
+ * `HttpTypes.StoreProductCategory` → Cartbase `StoreProductCategory`
5
5
  * (`@cartbase/storefront/api/categories`); products come from the plain
6
6
  * listing filtered by `category_id` (membership), via `PaginatedProducts`.
7
7
  *
@@ -9,7 +9,7 @@
9
9
  * `category_children` — fetch the category with `include_ancestors_tree` +
10
10
  * `include_descendants_tree` (`retrieveCategory` query flags), otherwise
11
11
  * those sections simply don't render. Skeleton count is the fixed default
12
- * (barter categories don't embed a products array).
12
+ * (Cartbase categories don't embed a products array).
13
13
  */
14
14
  import { Suspense } from "react"
15
15
  import { notFound } from "next/navigation"
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Collection page — ported from
3
3
  * `@1click/ui/src/store/collection-template.tsx` (v2.3.1), REWIRED to the
4
- * barter collection MEMBERSHIP listing (docs/storefront/collections.md).
4
+ * Cartbase collection MEMBERSHIP listing (docs/storefront/collections.md).
5
5
  *
6
6
  * The original filtered the plain products listing by `collection_id`
7
- * (Medusa primary collection). barter collections are curated groupings
7
+ * (Medusa primary collection). Cartbase collections are curated groupings
8
8
  * (manual or smart) with an admin-set `default_sort` — the membership
9
9
  * endpoint `api/collections` `listCollectionProducts` honors it SERVER-side
10
10
  * (manual position, title, EUR price asc/desc, newest/oldest, best_selling).
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Store-family label map — ported from `@1click/ui/src/store/labels.ts`
3
3
  * (v2.3.1), EXTENDED with the search-template keys (search-template is new
4
- * in barter — no @1click source). i18n discipline: components merge
4
+ * in Cartbase — no @1click source). i18n discipline: components merge
5
5
  * `labels` props over these defaults; `labels-bg.ts` must cover every key
6
6
  * (typed against the full shape — completeness is unit-tested).
7
7
  */
@@ -13,7 +13,7 @@ export type StoreLabels = {
13
13
  latestArrivals: string
14
14
  priceLowToHigh: string
15
15
  priceHighToLow: string
16
- // search-template (barter addition)
16
+ // search-template (Cartbase addition)
17
17
  searchTitle: string
18
18
  searchPlaceholder: string
19
19
  searchAction: string
@@ -2,7 +2,7 @@
2
2
  * Paginated product grid — ported from
3
3
  * `@1click/ui/src/store/paginated-products.tsx` (v2.3.1). Data seam: the
4
4
  * Medusa `listProductsWithSort` server action (region-resolved via
5
- * `countryCode`) becomes `api/products` `listProducts` with the barter
5
+ * `countryCode`) becomes `api/products` `listProducts` with the Cartbase
6
6
  * pricing context (`currency_code`/`region_id`).
7
7
  *
8
8
  * Sorting (server truth first):
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Search-template URL-state helpers — NEW in barter (no @1click source;
2
+ * Search-template URL-state helpers — NEW in Cartbase (no @1click source;
3
3
  * pure module so the round-trip is unit-testable —
4
4
  * tests/unit/storefront-catalog.test.ts).
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Search results page — NEW in barter (no @1click source; the Medusa stores
2
+ * Search results page — NEW in Cartbase (no @1click source; the Medusa stores
3
3
  * had no search endpoint). Built in the store-template idiom: filter
4
4
  * sidebar, heading, product grid, pagination — over `api/search`
5
5
  * `searchProducts` (docs/storefront/search.md).
@@ -16,7 +16,7 @@ import {
16
16
  /**
17
17
  * ConsentBanner — the built-in Consent Mode v2 UI.
18
18
  *
19
- * Ported from the barter reference implementation
19
+ * Ported from the Cartbase reference implementation
20
20
  * `src/components/storefront/consent/consent-banner.tsx` (itself from
21
21
  * `@1click/ui/src/tracking/consent-banner.tsx` v2.3.1, shipped on Alenika
22
22
  * d3d3d39), parameterized per docs/cards/consent-management.md: copy +
@@ -3,7 +3,7 @@ import { CONSENT_INIT_SNIPPET } from "./consent"
3
3
  /**
4
4
  * ConsentInit — the synchronous Consent Mode v2 "default" snippet.
5
5
  *
6
- * Ported from the barter reference implementation
6
+ * Ported from the Cartbase reference implementation
7
7
  * `src/components/storefront/consent/consent-init.tsx` (itself from
8
8
  * `@1click/ui/src/tracking/consent-init.tsx` v2.3.1); the snippet lives in
9
9
  * ./consent.ts (CONSENT_INIT_SNIPPET, character-identical) so its ordering
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Consent Mode v2 — shared state + appliers.
3
3
  *
4
- * Ported from the barter reference implementation
4
+ * Ported from the Cartbase reference implementation
5
5
  * `src/components/storefront/consent/consent.ts` (itself a verbatim port of
6
6
  * `@1click/ui/src/tracking/consent.ts` v2.3.1, shipped on Alenika d3d3d39).
7
7
  * THE COOKIE SEAM IS THE CONTRACT: the `_1c_consent` cookie name, JSON
8
8
  * shape `{analytics, ads, ts}` and 12-month lifetime must stay IDENTICAL
9
9
  * across the reference impl, this package, and any external CMP — every
10
- * barter-side gate reads it.
10
+ * Cartbase-side gate reads it.
11
11
  *
12
12
  * One first-party cookie (`_1c_consent`) is the single source of truth
13
13
  * for the visitor's choice. Three consumers read it:
@@ -27,9 +27,9 @@
27
27
  * - fbq queues events client-side and sends nothing until 'grant'
28
28
  *
29
29
  * External-CMP escape hatch (consent-management card §4): in
30
- * `mode: "external"` barter renders no banner — the merchant's CMP must
30
+ * `mode: "external"` Cartbase renders no banner — the merchant's CMP must
31
31
  * write the SAME consent state, either by setting the cookie itself or by
32
- * calling `setConsent()` below. That one seam keeps every barter-side
32
+ * calling `setConsent()` below. That one seam keeps every Cartbase-side
33
33
  * gate working with any outside app.
34
34
  *
35
35
  * Per-store configuration comes from `GET /api/store/consent`
@@ -123,7 +123,7 @@ export function applyConsent(choices: ConsentChoices): void {
123
123
  * The documented external-CMP entry point: write the shared consent state
124
124
  * (cookie) AND apply the live vendor update in one call. An outside CMP
125
125
  * that calls this — or writes the cookie in the same shape — drives every
126
- * barter-side gate exactly like the built-in banner does.
126
+ * Cartbase-side gate exactly like the built-in banner does.
127
127
  */
128
128
  export function setConsent(choices: Omit<ConsentChoices, "ts"> & { ts?: number }): void {
129
129
  const full: ConsentChoices = {
@@ -221,7 +221,7 @@ export type ConsentSettings = {
221
221
 
222
222
  /**
223
223
  * Mount `<ConsentBanner>` only when this is true. `external` mode renders
224
- * NO barter banner — the outside CMP owns the UI while `<ConsentInit>` +
224
+ * NO Cartbase banner — the outside CMP owns the UI while `<ConsentInit>` +
225
225
  * cookie gating keep working (the escape-hatch seam). Mirrors
226
226
  * `shouldRenderBanner` in `src/lib/consent/model.ts`.
227
227
  */
@@ -13,7 +13,7 @@ import type {
13
13
  *
14
14
  * Ported from `@1click/ui/src/tracking/fbq.ts` (v2.3.1) with ONE deliberate
15
15
  * seam change: the browser-side `fireCapiEvent` dual-fire is REMOVED —
16
- * in barter, server-side Conversions API sending is backend-owned (the
16
+ * in Cartbase, server-side Conversions API sending is backend-owned (the
17
17
  * `order.placed` forwarder, `src/lib/tracking/forward.ts` + admin-api.md
18
18
  * §34). This package fires CLIENT Pixel events only; the ad-blocked /
19
19
  * iOS-ATT recovery the dual-fire provided is covered by the backend CAPI
@@ -124,7 +124,7 @@ export function trackInitiateCheckout(data: InitiateCheckoutData): void {
124
124
 
125
125
  /**
126
126
  * Purchase event — eventID MUST equal `purchase_${order.display_id}`
127
- * to dedupe with the barter backend's order.placed CAPI Purchase.
127
+ * to dedupe with the Cartbase backend's order.placed CAPI Purchase.
128
128
  * Caller passes `order.display_id`; this helper builds the id so the
129
129
  * format can never drift between the two sides.
130
130
  */
@@ -10,7 +10,7 @@ import type { TrackingAttribution, TrackingClientHints } from "./types"
10
10
  * completion (consent-gated — only capture when the visitor's `_1c_consent`
11
11
  * choice allows it; see store-api.md "Tracking block" wiring contract).
12
12
  * Cart completion copies the keys onto `order.metadata`
13
- * (`src/lib/carts/complete/_order.ts`) and the barter `order.placed`
13
+ * (`src/lib/carts/complete/_order.ts`) and the Cartbase `order.placed`
14
14
  * forwarder reads exactly these keys to build the CAPI Purchase event's
15
15
  * `user_data` and the GA4 Measurement Protocol Purchase's `client_id` /
16
16
  * `session_id`.
@@ -8,7 +8,7 @@ import type { TrackingConfig, TrackingConfigResponse } from "./types"
8
8
  * block-builder registry in `src/lib/integrations/store-config.ts`).
9
9
  *
10
10
  * CRITICAL ADAPTATION vs `@1click/ui`: the original read
11
- * `{MEDUSA_BACKEND_URL}/store/integrations` from env vars; the barter
11
+ * `{MEDUSA_BACKEND_URL}/store/integrations` from env vars; the Cartbase
12
12
  * version goes through the `StorefrontClient` (x-client-id + optional
13
13
  * publishable key + locale handled by the ONE http seam). Only ENABLED
14
14
  * integrations contribute keys, and only non-sensitive IDs appear
@@ -18,7 +18,7 @@ import type { TrackingConfig, TrackingConfigResponse } from "./types"
18
18
  *
19
19
  * The @1click predecessor once called `/store/integrations/tracking`,
20
20
  * which 404'd and silently returned `{}` — pixel never loaded. The path
21
- * here is the registered barter route (`src/app/api/store/integrations/
21
+ * here is the registered Cartbase route (`src/app/api/store/integrations/
22
22
  * route.ts`); the contract tests execute this exact call.
23
23
  *
24
24
  * Response is cached for 5 minutes when running inside Next.js
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * @cartbase/storefront/tracking — Meta Pixel + GA4 + Rybbit + Consent Mode v2.
3
3
  *
4
- * Ported from `@1click/ui/src/tracking` (v2.3.1) with the barter seams:
4
+ * Ported from `@1click/ui/src/tracking` (v2.3.1) with the Cartbase seams:
5
5
  * - config comes from `GET /api/store/integrations` → `tracking` block
6
6
  * via `getTrackingConfig(client)` (never env vars)
7
- * - server-side CAPI / GA4-MP sending is barter-backend-owned (the
7
+ * - server-side CAPI / GA4-MP sending is Cartbase-backend-owned (the
8
8
  * `order.placed` forwarder) — this package fires CLIENT events only
9
9
  * and writes attribution for the server to inherit
10
10
  * - Purchase dedupe: Pixel `eventID = "purchase_" + order.display_id`
@@ -101,7 +101,7 @@ declare global {
101
101
  * of dedup compare the same digest).
102
102
  *
103
103
  * Also persists raw values via rememberKnownVisitor() so any future
104
- * consumer of getKnownVisitor() sees them. In barter the server-side
104
+ * consumer of getKnownVisitor() sees them. In Cartbase the server-side
105
105
  * CAPI enrichment is backend-owned (the order.placed forwarder reads
106
106
  * hashed PII from the order itself), so this call's job is the
107
107
  * browser-side Pixel Advanced Matching.
@@ -12,7 +12,7 @@ import Script from "next/script"
12
12
  *
13
13
  * `siteId` and `baseUrl` are platform-managed — Rybbit is the platform's
14
14
  * self-hosted, cookieless analytics, provisioned per store from platform
15
- * env, and is deliberately ABSENT from the barter store-config `tracking`
15
+ * env, and is deliberately ABSENT from the Cartbase store-config `tracking`
16
16
  * block (`src/lib/tracking/store-config-block.ts`). The host app passes
17
17
  * the values as props directly (e.g. from its own env). The merchant
18
18
  * never sees or configures them. Rybbit needs no consent gate.
@@ -2,20 +2,20 @@
2
2
  * Shared tracking types — Meta Pixel + Google Analytics 4 + consent.
3
3
  *
4
4
  * Ported from `@1click/ui/src/tracking/types.ts` (v2.3.1) and re-seated on
5
- * the barter contract:
5
+ * the Cartbase contract:
6
6
  *
7
- * - `TrackingConfig` mirrors the barter store-config `tracking` block
7
+ * - `TrackingConfig` mirrors the Cartbase store-config `tracking` block
8
8
  * served by `GET /api/store/integrations` (code truth:
9
9
  * `src/lib/tracking/constants.ts` `StoreTrackingBlock` +
10
10
  * `src/lib/tracking/store-block.ts`; contract: store-api.md "Tracking
11
- * block"). Differences vs the @1click shape: `googleAds` is a barter
11
+ * block"). Differences vs the @1click shape: `googleAds` is a Cartbase
12
12
  * extension, `consent_required` is new (consent-management card), and
13
13
  * `rybbit` is deliberately ABSENT — Rybbit is platform analytics,
14
14
  * provisioned from platform env, never a tenant integration; the
15
15
  * `<Rybbit>` component takes its props directly from the host app.
16
16
  *
17
17
  * - Server-side CAPI + GA4 Measurement Protocol sending is
18
- * barter-backend-owned (the `order.placed` forwarder,
18
+ * Cartbase-backend-owned (the `order.placed` forwarder,
19
19
  * `src/lib/tracking/forward.ts`) — this package fires CLIENT events
20
20
  * only and writes attribution for the server to inherit.
21
21
  *
@@ -37,7 +37,7 @@ export type TrackingConfig = {
37
37
  gtm?: { containerId: string }
38
38
  ga4?: { measurementId: string }
39
39
  klaviyo?: { publicKey: string }
40
- /** Barter extension over the @1click TrackingConfig — explicit Google
40
+ /** Cartbase extension over the @1click TrackingConfig — explicit Google
41
41
  * Ads tag config (the @1click engine wired Ads through GTM). */
42
42
  googleAds?: { conversionId: string; conversionLabel?: string }
43
43
  /** True when the store's consent CMP is enabled — client tags must
@@ -111,7 +111,7 @@ export type LeadData = {
111
111
  /**
112
112
  * Attribution payload written to `cart.metadata` before completion
113
113
  * (consent-gated — see store-api.md "Tracking block" wiring contract).
114
- * Cart completion copies these keys onto `order.metadata` and the barter
114
+ * Cart completion copies these keys onto `order.metadata` and the Cartbase
115
115
  * `order.placed` forwarder reads exactly them to build the CAPI Purchase
116
116
  * `user_data` and the GA4 MP Purchase `client_id` / `session_id`
117
117
  * (code truth: `src/lib/tracking/constants.ts` TrackingAttributionMeta).