@cartbase/storefront 0.20.0 → 0.20.1

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 (99) hide show
  1. package/LICENSE +21 -21
  2. package/package.json +258 -258
  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/redirects.ts +37 -37
  18. package/src/api/regions.ts +200 -200
  19. package/src/api/search.ts +163 -163
  20. package/src/api/store.ts +35 -35
  21. package/src/api/types.ts +91 -91
  22. package/src/cart-drawer/context.tsx +778 -778
  23. package/src/cart-drawer/cross-sell-carousel.tsx +211 -211
  24. package/src/cart-drawer/cross-sell-sidebar.tsx +158 -158
  25. package/src/cart-drawer/gift-wrap.tsx +82 -82
  26. package/src/cart-drawer/item/index.tsx +162 -162
  27. package/src/cart-drawer/item/upsell.tsx +110 -110
  28. package/src/cart-drawer/labels.ts +123 -123
  29. package/src/cart-drawer/mutation-queue.ts +78 -78
  30. package/src/cart-drawer/notes.tsx +131 -131
  31. package/src/cart-drawer/sticky-footer.tsx +73 -73
  32. package/src/cart-drawer/summary-breakdown.tsx +197 -197
  33. package/src/checkout/address-error-copy.ts +117 -117
  34. package/src/checkout/boxnow-locker-selector.tsx +410 -410
  35. package/src/checkout/compare-addresses.ts +40 -40
  36. package/src/checkout/discount-section.tsx +218 -218
  37. package/src/checkout/error-copy-codes.ts +63 -63
  38. package/src/checkout/geocode.ts +154 -154
  39. package/src/checkout/gift-card-section.tsx +224 -224
  40. package/src/checkout/index.ts +72 -72
  41. package/src/checkout/labels.ts +495 -495
  42. package/src/checkout/payment-button.tsx +372 -372
  43. package/src/checkout/payment-error-copy.ts +154 -154
  44. package/src/checkout/promotion-error-copy.ts +91 -91
  45. package/src/common/country-flag.tsx +52 -52
  46. package/src/common/country-select.tsx +11 -11
  47. package/src/common/index.ts +20 -20
  48. package/src/common/market-select.tsx +57 -57
  49. package/src/index.ts +12 -12
  50. package/src/lib/country-name.ts +59 -59
  51. package/src/lib/get-product-price.ts +133 -133
  52. package/src/lib/media-image.tsx +39 -39
  53. package/src/lib/payment-constants.ts +53 -53
  54. package/src/lib/platform.ts +13 -13
  55. package/src/lib/price.tsx +39 -39
  56. package/src/lib/store-api-error.ts +36 -36
  57. package/src/lib/variant-caption.ts +32 -32
  58. package/src/locales/context.ts +37 -37
  59. package/src/locales/en.ts +26 -26
  60. package/src/locales/index.ts +19 -19
  61. package/src/locales/provider.tsx +59 -59
  62. package/src/locales/types.ts +77 -77
  63. package/src/order/index.ts +62 -62
  64. package/src/order/labels.ts +79 -79
  65. package/src/order/order-totals.tsx +250 -250
  66. package/src/primitives/select-field.tsx +93 -93
  67. package/src/products/image-gallery.tsx +43 -43
  68. package/src/products/option-select.tsx +67 -67
  69. package/src/products/product-info.tsx +5 -5
  70. package/src/products/product-price.tsx +69 -69
  71. package/src/products/product-promises.tsx +61 -61
  72. package/src/products/product-specs.tsx +65 -65
  73. package/src/products/product-tabs.tsx +123 -123
  74. package/src/products/purchase-options.tsx +130 -130
  75. package/src/products/sets.ts +110 -110
  76. package/src/products/variant-matching.ts +71 -71
  77. package/src/products/variant-url.ts +74 -74
  78. package/src/reviews-ui/lightbox-state.ts +46 -46
  79. package/src/reviews-ui/review-header.tsx +166 -166
  80. package/src/reviews-ui/review-lightbox.tsx +271 -271
  81. package/src/reviews-ui/review-list.tsx +193 -193
  82. package/src/reviews-ui/review-widget.tsx +219 -218
  83. package/src/reviews-ui/widget-options.ts +55 -55
  84. package/src/store/category-template.tsx +136 -136
  85. package/src/store/index.ts +40 -40
  86. package/src/tracking/chatgpt-pixel.tsx +99 -99
  87. package/src/tracking/consent-init.tsx +62 -62
  88. package/src/tracking/events.ts +348 -348
  89. package/src/tracking/ga4.tsx +93 -93
  90. package/src/tracking/google-ads.ts +84 -84
  91. package/src/tracking/gtm.tsx +60 -60
  92. package/src/tracking/inline-script.ts +49 -49
  93. package/src/tracking/oaiq.ts +206 -206
  94. package/src/tracking/tiktok-pixel.tsx +91 -91
  95. package/src/tracking/track-init.tsx +56 -56
  96. package/src/tracking/track-order-purchase.tsx +122 -122
  97. package/src/tracking/ttq.ts +180 -180
  98. package/src/tracking/use-tracking-config.ts +54 -54
  99. package/theme/index.css +25 -25
@@ -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
+ }