@cartbase/storefront 0.17.0 → 0.18.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 (107) hide show
  1. package/LICENSE +21 -21
  2. package/package.json +258 -256
  3. package/src/api/auth.ts +108 -108
  4. package/src/api/carts.ts +523 -523
  5. package/src/api/categories.ts +184 -184
  6. package/src/api/checkout.ts +526 -526
  7. package/src/api/collections.ts +130 -130
  8. package/src/api/consent.ts +75 -75
  9. package/src/api/content.ts +125 -125
  10. package/src/api/customers.ts +303 -303
  11. package/src/api/gift-cards.ts +112 -112
  12. package/src/api/http.ts +180 -180
  13. package/src/api/index.ts +30 -30
  14. package/src/api/menus.ts +77 -77
  15. package/src/api/metaobjects.ts +136 -136
  16. package/src/api/orders.ts +290 -290
  17. package/src/api/products.ts +43 -1
  18. package/src/api/redirects.ts +37 -37
  19. package/src/api/regions.ts +200 -200
  20. package/src/api/reviews.ts +259 -259
  21. package/src/api/search.ts +163 -163
  22. package/src/api/store.ts +35 -35
  23. package/src/api/types.ts +91 -91
  24. package/src/cart-drawer/context.tsx +277 -164
  25. package/src/cart-drawer/cross-sell-carousel.tsx +211 -211
  26. package/src/cart-drawer/cross-sell-sidebar.tsx +158 -158
  27. package/src/cart-drawer/gift-wrap.tsx +82 -82
  28. package/src/cart-drawer/index.ts +71 -68
  29. package/src/cart-drawer/item/index.tsx +162 -162
  30. package/src/cart-drawer/item/quantity.tsx +8 -14
  31. package/src/cart-drawer/item/upsell.tsx +110 -110
  32. package/src/cart-drawer/labels.ts +123 -123
  33. package/src/cart-drawer/mutation-queue.ts +78 -0
  34. package/src/cart-drawer/notes.tsx +131 -131
  35. package/src/cart-drawer/sticky-footer.tsx +73 -73
  36. package/src/cart-drawer/summary-breakdown.tsx +197 -197
  37. package/src/checkout/address-error-copy.ts +117 -117
  38. package/src/checkout/boxnow-locker-selector.tsx +410 -410
  39. package/src/checkout/compare-addresses.ts +40 -40
  40. package/src/checkout/discount-section.tsx +218 -218
  41. package/src/checkout/error-copy-codes.ts +63 -63
  42. package/src/checkout/geocode.ts +154 -154
  43. package/src/checkout/gift-card-section.tsx +224 -224
  44. package/src/checkout/index.ts +72 -72
  45. package/src/checkout/labels.ts +495 -495
  46. package/src/checkout/payment-button.tsx +372 -372
  47. package/src/checkout/payment-error-copy.ts +154 -154
  48. package/src/checkout/promotion-error-copy.ts +91 -91
  49. package/src/checkout/use-checkout-orchestration.ts +1592 -1592
  50. package/src/common/country-flag.tsx +52 -52
  51. package/src/common/country-select.tsx +11 -11
  52. package/src/common/index.ts +20 -20
  53. package/src/common/market-select.tsx +57 -57
  54. package/src/index.ts +12 -12
  55. package/src/lib/country-name.ts +59 -59
  56. package/src/lib/get-product-price.ts +133 -133
  57. package/src/lib/media-image.tsx +39 -39
  58. package/src/lib/payment-constants.ts +53 -53
  59. package/src/lib/platform.ts +13 -13
  60. package/src/lib/price.tsx +39 -39
  61. package/src/lib/store-api-error.ts +36 -36
  62. package/src/lib/variant-caption.ts +32 -32
  63. package/src/locales/bg.ts +467 -467
  64. package/src/locales/context.ts +37 -37
  65. package/src/locales/en.ts +26 -26
  66. package/src/locales/es.ts +466 -466
  67. package/src/locales/index.ts +19 -19
  68. package/src/locales/provider.tsx +59 -59
  69. package/src/locales/types.ts +77 -77
  70. package/src/order/index.ts +62 -62
  71. package/src/order/labels.ts +79 -79
  72. package/src/order/order-totals.tsx +250 -250
  73. package/src/primitives/select-field.tsx +93 -93
  74. package/src/products/image-gallery.tsx +43 -43
  75. package/src/products/index.ts +68 -59
  76. package/src/products/option-select.tsx +67 -67
  77. package/src/products/product-actions-wrapper.tsx +63 -62
  78. package/src/products/product-actions.tsx +151 -150
  79. package/src/products/product-price.tsx +69 -69
  80. package/src/products/product-promises.tsx +61 -61
  81. package/src/products/product-specs.tsx +65 -65
  82. package/src/products/product-tabs.tsx +123 -123
  83. package/src/products/product-template.tsx +163 -162
  84. package/src/products/purchase-options.tsx +130 -130
  85. package/src/products/sets.ts +110 -0
  86. package/src/products/use-product-actions.ts +199 -164
  87. package/src/products/variant-matching.ts +71 -71
  88. package/src/products/variant-url.ts +74 -74
  89. package/src/reviews-ui/index.ts +73 -73
  90. package/src/store/category-template.tsx +136 -136
  91. package/src/store/index.ts +40 -40
  92. package/src/tracking/chatgpt-pixel.tsx +99 -99
  93. package/src/tracking/consent-init.tsx +62 -62
  94. package/src/tracking/events.ts +348 -348
  95. package/src/tracking/ga4.tsx +93 -93
  96. package/src/tracking/google-ads.ts +84 -84
  97. package/src/tracking/gtm.tsx +60 -60
  98. package/src/tracking/inline-script.ts +49 -49
  99. package/src/tracking/oaiq.ts +206 -206
  100. package/src/tracking/tiktok-pixel.tsx +91 -91
  101. package/src/tracking/track-init.tsx +56 -56
  102. package/src/tracking/track-order-purchase.tsx +122 -122
  103. package/src/tracking/ttq.ts +180 -180
  104. package/src/tracking/use-tracking-config.ts +54 -54
  105. package/theme/index.css +25 -25
  106. package/theme/theme.css +150 -150
  107. package/theme/tokens.css +106 -106
@@ -1,184 +1,184 @@
1
- /**
2
- * @cartbase/storefront/api/categories — product categories, tags, types.
3
- *
4
- * Taxonomy reads for navigation trees and filter UIs. Categories are
5
- * hierarchical (`parent_category_id`) with optional ancestor/descendant tree
6
- * embedding; tags and types are flat value lists. Only ACTIVE, non-internal
7
- * categories are storefront-visible (RLS-enforced — inactive/internal 404
8
- * even by id). Docs: docs/storefront/categories.md.
9
- */
10
- import type { StorefrontClient } from "./http"
11
- import type { IsoDateString, ListEnvelope, PaginationQuery } from "./types"
12
-
13
- export interface StoreProductCategory {
14
- id: string
15
- name: string
16
- handle: string
17
- description: string | null
18
- parent_category_id: string | null
19
- rank: number
20
- is_active: true
21
- is_internal: false
22
- /** Materialized path (internal ordering detail). */
23
- mpath: string | null
24
- /** SEO override; null = fall back to `name`. */
25
- seo_title: string | null
26
- /** SEO override; null = fall back to `description`. */
27
- seo_description: string | null
28
- metadata: Record<string, unknown> | null
29
- created_at: IsoDateString
30
- updated_at: IsoDateString
31
- /** Present only when `include_descendants_tree` was requested. */
32
- category_children?: StoreProductCategory[]
33
- /** Present only when `include_ancestors_tree` was requested. */
34
- parent_category?: StoreProductCategory | null
35
- }
36
-
37
- export interface StoreProductTag {
38
- id: string
39
- value: string
40
- metadata: Record<string, unknown> | null
41
- created_at: IsoDateString
42
- updated_at: IsoDateString
43
- }
44
-
45
- export interface StoreProductType {
46
- id: string
47
- value: string
48
- metadata: Record<string, unknown> | null
49
- created_at: IsoDateString
50
- updated_at: IsoDateString
51
- }
52
-
53
- export interface ListCategoriesQuery extends PaginationQuery {
54
- /** Case-insensitive substring match on name. */
55
- q?: string
56
- handle?: string
57
- /** List one level: children of this category. */
58
- parent_category_id?: string
59
- /** Embed `parent_category` chains on each row. */
60
- include_ancestors_tree?: boolean
61
- /** Embed `category_children` recursively on each row. */
62
- include_descendants_tree?: boolean
63
- }
64
-
65
- export interface CategoryListResponse extends ListEnvelope {
66
- product_categories: StoreProductCategory[]
67
- }
68
-
69
- export interface CategoryResponse {
70
- product_category: StoreProductCategory
71
- }
72
-
73
- export interface RetrieveCategoryQuery {
74
- include_ancestors_tree?: boolean
75
- include_descendants_tree?: boolean
76
- }
77
-
78
- export interface ListTagsQuery extends PaginationQuery {
79
- /** Case-insensitive substring match on value. */
80
- q?: string
81
- /** Exact value match. */
82
- value?: string
83
- }
84
-
85
- export interface TagListResponse extends ListEnvelope {
86
- product_tags: StoreProductTag[]
87
- }
88
-
89
- export interface TagResponse {
90
- product_tag: StoreProductTag
91
- }
92
-
93
- export type ListTypesQuery = ListTagsQuery
94
-
95
- export interface TypeListResponse extends ListEnvelope {
96
- product_types: StoreProductType[]
97
- }
98
-
99
- export interface TypeResponse {
100
- product_type: StoreProductType
101
- }
102
-
103
- /**
104
- * List active, non-internal categories ordered by `rank`. Tree flags embed
105
- * ancestors/descendants per row (visible categories only).
106
- *
107
- * Auth: anon (`x-client-id`). Errors: 400 `missing_client_id`,
108
- * 400 `validation_failed`. Settings: category `is_active`/`is_internal`
109
- * flags and rank ordering (Admin → Categories).
110
- */
111
- export async function listCategories(
112
- client: StorefrontClient,
113
- query?: ListCategoriesQuery
114
- ): Promise<CategoryListResponse> {
115
- return client.get("/api/store/product-categories", { query: { ...query } })
116
- }
117
-
118
- /**
119
- * Retrieve one category by id, optionally with its ancestor/descendant tree.
120
- *
121
- * Auth: anon (`x-client-id`). Errors: 404 `not_found` (unknown, deleted, or
122
- * inactive/internal — RLS hides them even by id).
123
- */
124
- export async function retrieveCategory(
125
- client: StorefrontClient,
126
- categoryId: string,
127
- query?: RetrieveCategoryQuery
128
- ): Promise<CategoryResponse> {
129
- return client.get(`/api/store/product-categories/${encodeURIComponent(categoryId)}`, {
130
- query: { ...query },
131
- })
132
- }
133
-
134
- /**
135
- * List product tags ordered by value (filter chips; tag ids feed
136
- * `tag_id` filters on product listings and search).
137
- *
138
- * Auth: anon (`x-client-id`). Errors: 400 `missing_client_id`,
139
- * 400 `validation_failed`.
140
- */
141
- export async function listProductTags(
142
- client: StorefrontClient,
143
- query?: ListTagsQuery
144
- ): Promise<TagListResponse> {
145
- return client.get("/api/store/product-tags", { query: { ...query } })
146
- }
147
-
148
- /**
149
- * Retrieve one product tag by id.
150
- *
151
- * Auth: anon (`x-client-id`). Errors: 404 `not_found`.
152
- */
153
- export async function retrieveProductTag(
154
- client: StorefrontClient,
155
- tagId: string
156
- ): Promise<TagResponse> {
157
- return client.get(`/api/store/product-tags/${encodeURIComponent(tagId)}`)
158
- }
159
-
160
- /**
161
- * List product types ordered by value (type ids feed `type_id` filters on
162
- * product listings and search).
163
- *
164
- * Auth: anon (`x-client-id`). Errors: 400 `missing_client_id`,
165
- * 400 `validation_failed`.
166
- */
167
- export async function listProductTypes(
168
- client: StorefrontClient,
169
- query?: ListTypesQuery
170
- ): Promise<TypeListResponse> {
171
- return client.get("/api/store/product-types", { query: { ...query } })
172
- }
173
-
174
- /**
175
- * Retrieve one product type by id.
176
- *
177
- * Auth: anon (`x-client-id`). Errors: 404 `not_found`.
178
- */
179
- export async function retrieveProductType(
180
- client: StorefrontClient,
181
- typeId: string
182
- ): Promise<TypeResponse> {
183
- return client.get(`/api/store/product-types/${encodeURIComponent(typeId)}`)
184
- }
1
+ /**
2
+ * @cartbase/storefront/api/categories — product categories, tags, types.
3
+ *
4
+ * Taxonomy reads for navigation trees and filter UIs. Categories are
5
+ * hierarchical (`parent_category_id`) with optional ancestor/descendant tree
6
+ * embedding; tags and types are flat value lists. Only ACTIVE, non-internal
7
+ * categories are storefront-visible (RLS-enforced — inactive/internal 404
8
+ * even by id). Docs: docs/storefront/categories.md.
9
+ */
10
+ import type { StorefrontClient } from "./http"
11
+ import type { IsoDateString, ListEnvelope, PaginationQuery } from "./types"
12
+
13
+ export interface StoreProductCategory {
14
+ id: string
15
+ name: string
16
+ handle: string
17
+ description: string | null
18
+ parent_category_id: string | null
19
+ rank: number
20
+ is_active: true
21
+ is_internal: false
22
+ /** Materialized path (internal ordering detail). */
23
+ mpath: string | null
24
+ /** SEO override; null = fall back to `name`. */
25
+ seo_title: string | null
26
+ /** SEO override; null = fall back to `description`. */
27
+ seo_description: string | null
28
+ metadata: Record<string, unknown> | null
29
+ created_at: IsoDateString
30
+ updated_at: IsoDateString
31
+ /** Present only when `include_descendants_tree` was requested. */
32
+ category_children?: StoreProductCategory[]
33
+ /** Present only when `include_ancestors_tree` was requested. */
34
+ parent_category?: StoreProductCategory | null
35
+ }
36
+
37
+ export interface StoreProductTag {
38
+ id: string
39
+ value: string
40
+ metadata: Record<string, unknown> | null
41
+ created_at: IsoDateString
42
+ updated_at: IsoDateString
43
+ }
44
+
45
+ export interface StoreProductType {
46
+ id: string
47
+ value: string
48
+ metadata: Record<string, unknown> | null
49
+ created_at: IsoDateString
50
+ updated_at: IsoDateString
51
+ }
52
+
53
+ export interface ListCategoriesQuery extends PaginationQuery {
54
+ /** Case-insensitive substring match on name. */
55
+ q?: string
56
+ handle?: string
57
+ /** List one level: children of this category. */
58
+ parent_category_id?: string
59
+ /** Embed `parent_category` chains on each row. */
60
+ include_ancestors_tree?: boolean
61
+ /** Embed `category_children` recursively on each row. */
62
+ include_descendants_tree?: boolean
63
+ }
64
+
65
+ export interface CategoryListResponse extends ListEnvelope {
66
+ product_categories: StoreProductCategory[]
67
+ }
68
+
69
+ export interface CategoryResponse {
70
+ product_category: StoreProductCategory
71
+ }
72
+
73
+ export interface RetrieveCategoryQuery {
74
+ include_ancestors_tree?: boolean
75
+ include_descendants_tree?: boolean
76
+ }
77
+
78
+ export interface ListTagsQuery extends PaginationQuery {
79
+ /** Case-insensitive substring match on value. */
80
+ q?: string
81
+ /** Exact value match. */
82
+ value?: string
83
+ }
84
+
85
+ export interface TagListResponse extends ListEnvelope {
86
+ product_tags: StoreProductTag[]
87
+ }
88
+
89
+ export interface TagResponse {
90
+ product_tag: StoreProductTag
91
+ }
92
+
93
+ export type ListTypesQuery = ListTagsQuery
94
+
95
+ export interface TypeListResponse extends ListEnvelope {
96
+ product_types: StoreProductType[]
97
+ }
98
+
99
+ export interface TypeResponse {
100
+ product_type: StoreProductType
101
+ }
102
+
103
+ /**
104
+ * List active, non-internal categories ordered by `rank`. Tree flags embed
105
+ * ancestors/descendants per row (visible categories only).
106
+ *
107
+ * Auth: anon (`x-client-id`). Errors: 400 `missing_client_id`,
108
+ * 400 `validation_failed`. Settings: category `is_active`/`is_internal`
109
+ * flags and rank ordering (Admin → Categories).
110
+ */
111
+ export async function listCategories(
112
+ client: StorefrontClient,
113
+ query?: ListCategoriesQuery
114
+ ): Promise<CategoryListResponse> {
115
+ return client.get("/api/store/product-categories", { query: { ...query } })
116
+ }
117
+
118
+ /**
119
+ * Retrieve one category by id, optionally with its ancestor/descendant tree.
120
+ *
121
+ * Auth: anon (`x-client-id`). Errors: 404 `not_found` (unknown, deleted, or
122
+ * inactive/internal — RLS hides them even by id).
123
+ */
124
+ export async function retrieveCategory(
125
+ client: StorefrontClient,
126
+ categoryId: string,
127
+ query?: RetrieveCategoryQuery
128
+ ): Promise<CategoryResponse> {
129
+ return client.get(`/api/store/product-categories/${encodeURIComponent(categoryId)}`, {
130
+ query: { ...query },
131
+ })
132
+ }
133
+
134
+ /**
135
+ * List product tags ordered by value (filter chips; tag ids feed
136
+ * `tag_id` filters on product listings and search).
137
+ *
138
+ * Auth: anon (`x-client-id`). Errors: 400 `missing_client_id`,
139
+ * 400 `validation_failed`.
140
+ */
141
+ export async function listProductTags(
142
+ client: StorefrontClient,
143
+ query?: ListTagsQuery
144
+ ): Promise<TagListResponse> {
145
+ return client.get("/api/store/product-tags", { query: { ...query } })
146
+ }
147
+
148
+ /**
149
+ * Retrieve one product tag by id.
150
+ *
151
+ * Auth: anon (`x-client-id`). Errors: 404 `not_found`.
152
+ */
153
+ export async function retrieveProductTag(
154
+ client: StorefrontClient,
155
+ tagId: string
156
+ ): Promise<TagResponse> {
157
+ return client.get(`/api/store/product-tags/${encodeURIComponent(tagId)}`)
158
+ }
159
+
160
+ /**
161
+ * List product types ordered by value (type ids feed `type_id` filters on
162
+ * product listings and search).
163
+ *
164
+ * Auth: anon (`x-client-id`). Errors: 400 `missing_client_id`,
165
+ * 400 `validation_failed`.
166
+ */
167
+ export async function listProductTypes(
168
+ client: StorefrontClient,
169
+ query?: ListTypesQuery
170
+ ): Promise<TypeListResponse> {
171
+ return client.get("/api/store/product-types", { query: { ...query } })
172
+ }
173
+
174
+ /**
175
+ * Retrieve one product type by id.
176
+ *
177
+ * Auth: anon (`x-client-id`). Errors: 404 `not_found`.
178
+ */
179
+ export async function retrieveProductType(
180
+ client: StorefrontClient,
181
+ typeId: string
182
+ ): Promise<TypeResponse> {
183
+ return client.get(`/api/store/product-types/${encodeURIComponent(typeId)}`)
184
+ }