@neowhale/storefront 0.1.2 → 0.2.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.
@@ -0,0 +1,305 @@
1
+ interface PixelConfig {
2
+ provider: string;
3
+ pixel_id: string;
4
+ }
5
+ interface StorefrontConfig {
6
+ object: 'storefront_config';
7
+ pixels: PixelConfig[];
8
+ }
9
+
10
+ interface PricingTier {
11
+ id: string;
12
+ unit: string;
13
+ label: string;
14
+ quantity: number;
15
+ sort_order: number;
16
+ default_price: number;
17
+ }
18
+ interface ProductVariation {
19
+ id: string;
20
+ product_id: string;
21
+ name: string;
22
+ sku: string | null;
23
+ price: number;
24
+ stock_quantity: number;
25
+ attributes: Record<string, string>;
26
+ }
27
+ interface Product {
28
+ id: string;
29
+ name: string;
30
+ slug: string;
31
+ sku: string | null;
32
+ description: string | null;
33
+ status: string;
34
+ type: string;
35
+ primary_category_id: string;
36
+ featured_image: string | null;
37
+ image_gallery: string[];
38
+ pricing_data: PricingTier[] | {
39
+ mode?: string;
40
+ tiers?: PricingTier[];
41
+ } | null;
42
+ custom_fields: Record<string, string | null>;
43
+ stock_quantity?: number;
44
+ }
45
+ interface Category {
46
+ id: string;
47
+ name: string;
48
+ slug: string;
49
+ }
50
+ interface CartItem {
51
+ id: string;
52
+ product_id: string;
53
+ product_name: string;
54
+ image_url: string | null;
55
+ quantity: number;
56
+ unit_price: number;
57
+ tier_label: string | null;
58
+ line_total: number;
59
+ }
60
+ interface TaxBreakdown {
61
+ name: string;
62
+ rate: number;
63
+ type: string;
64
+ rate_decimal: number;
65
+ }
66
+ interface Cart {
67
+ id: string;
68
+ items: CartItem[];
69
+ item_count: number;
70
+ subtotal: number;
71
+ tax_rate: number;
72
+ tax_amount: number;
73
+ total: number;
74
+ tax_breakdown: TaxBreakdown[];
75
+ discount_amount: number;
76
+ customer_email: string | null;
77
+ }
78
+ interface Order {
79
+ id: string;
80
+ order_number: string;
81
+ status: string;
82
+ total_amount: number;
83
+ subtotal: number;
84
+ tax_amount: number;
85
+ discount_amount: number;
86
+ item_count?: number;
87
+ created_at: string;
88
+ payment_status?: string;
89
+ fulfillment_status?: string;
90
+ items?: OrderItem[];
91
+ }
92
+ interface OrderItem {
93
+ id: string;
94
+ product_name: string;
95
+ quantity: number;
96
+ unit_price?: number;
97
+ cost_per_unit?: number;
98
+ line_total: number;
99
+ }
100
+ interface Customer {
101
+ id: string;
102
+ first_name: string;
103
+ last_name: string;
104
+ email: string | null;
105
+ phone: string | null;
106
+ loyalty_points: number;
107
+ loyalty_tier: string;
108
+ total_spent: number;
109
+ total_orders: number;
110
+ lifetime_value?: number;
111
+ street_address?: string | null;
112
+ city?: string | null;
113
+ state?: string | null;
114
+ postal_code?: string | null;
115
+ date_of_birth?: string | null;
116
+ created_at?: string;
117
+ is_staff?: boolean;
118
+ email_consent?: boolean;
119
+ sms_consent?: boolean;
120
+ }
121
+ interface Address {
122
+ firstName: string;
123
+ lastName: string;
124
+ address: string;
125
+ city: string;
126
+ state: string;
127
+ zip: string;
128
+ country: string;
129
+ }
130
+ interface PaymentData {
131
+ payment_method: 'card' | 'cash';
132
+ opaque_data?: {
133
+ dataDescriptor: string;
134
+ dataValue: string;
135
+ };
136
+ billTo?: Address;
137
+ shipTo?: Address;
138
+ }
139
+ interface CustomerAnalytics {
140
+ customer_id: string;
141
+ customer_name: string;
142
+ total_orders: number;
143
+ lifetime_revenue: number;
144
+ avg_order_value: number;
145
+ ltv_tier: string;
146
+ rfm_segment: string;
147
+ churn_risk: string;
148
+ last_order_date: string;
149
+ recency_days: number;
150
+ }
151
+ interface Location {
152
+ id: string;
153
+ name: string;
154
+ address?: string;
155
+ city?: string;
156
+ state?: string;
157
+ zip?: string;
158
+ phone?: string;
159
+ is_active?: boolean;
160
+ }
161
+ interface SendCodeResponse {
162
+ sent: boolean;
163
+ }
164
+ interface VerifyCodeResponse {
165
+ object: string;
166
+ token_hash: string;
167
+ needs_profile: boolean;
168
+ customer: Customer | null;
169
+ }
170
+ interface StorefrontSession {
171
+ id: string;
172
+ store_id: string;
173
+ customer_id?: string;
174
+ started_at: string;
175
+ last_active_at: string;
176
+ }
177
+ interface ListResponse<T> {
178
+ object: 'list';
179
+ data: T[];
180
+ has_more: boolean;
181
+ cursors?: {
182
+ before?: string;
183
+ after?: string;
184
+ };
185
+ url?: string;
186
+ }
187
+ interface WhaleStorefrontConfig {
188
+ /** Store UUID */
189
+ storeId: string;
190
+ /** API key (wk_live_... or wk_test_...) */
191
+ apiKey: string;
192
+ /** Gateway base URL. Defaults to https://whale-gateway.fly.dev */
193
+ gatewayUrl?: string;
194
+ /** Client-side proxy path. Defaults to /api/gw */
195
+ proxyPath?: string;
196
+ /** Media signing secret for image/video proxy */
197
+ mediaSigningSecret?: string;
198
+ /** Supabase host for media URL detection */
199
+ supabaseHost?: string;
200
+ /** localStorage key prefix. Defaults to "whale" */
201
+ storagePrefix?: string;
202
+ /** Analytics session TTL in ms. Defaults to 30 minutes */
203
+ sessionTtl?: number;
204
+ /** Enable debug logging */
205
+ debug?: boolean;
206
+ /**
207
+ * Master toggle for all tracking (analytics, pixels, behavioral).
208
+ * When false every tracking call is a no-op.
209
+ * Defaults to true; can also be set via NEXT_PUBLIC_TRACKING_ENABLED env var.
210
+ */
211
+ trackingEnabled?: boolean;
212
+ /**
213
+ * Fraction of sessions that record full behavioral replays (0 – 1).
214
+ * 0 = never, 1 = every session. Defaults to 0.1 (10 %).
215
+ * Can also be set via NEXT_PUBLIC_RECORDING_RATE env var.
216
+ */
217
+ recordingRate?: number;
218
+ }
219
+ type EventType = 'page_view' | 'product_view' | 'add_to_cart' | 'remove_from_cart' | 'begin_checkout' | 'purchase' | 'category_view' | 'search';
220
+
221
+ /**
222
+ * Extended query methods and static utilities for WhaleClient.
223
+ * Extracted from client.ts to keep the core under 300 lines.
224
+ */
225
+
226
+ /**
227
+ * Base64url-encode a URL string (works in both Node and browser).
228
+ */
229
+ declare function encodeBase64Url(url: string): string;
230
+ /**
231
+ * Quad-FNV (128-bit) media signing — matches gateway's media-signature.ts.
232
+ */
233
+ declare function signMedia(signingSecret: string, encodedUrl: string, w: string, q: string, f: string): string;
234
+
235
+ declare class WhaleClient {
236
+ readonly storeId: string;
237
+ readonly apiKey: string;
238
+ readonly gatewayUrl: string;
239
+ readonly proxyPath: string;
240
+ private _sessionToken;
241
+ constructor(config: WhaleStorefrontConfig);
242
+ setSessionToken(token: string | null): void;
243
+ getSessionToken(): string | null;
244
+ private get baseUrl();
245
+ private request;
246
+ listProducts(params?: {
247
+ limit?: number;
248
+ starting_after?: string;
249
+ status?: string;
250
+ }): Promise<ListResponse<Product>>;
251
+ getProduct(id: string): Promise<Product>;
252
+ getAllProducts(options?: {
253
+ status?: string;
254
+ maxPages?: number;
255
+ revalidate?: number;
256
+ filter?: (product: Product) => boolean;
257
+ }): Promise<Product[]>;
258
+ createCart(customerEmail?: string): Promise<Cart>;
259
+ getCart(cartId: string): Promise<Cart>;
260
+ addToCart(cartId: string, productId: string, quantity: number, options?: {
261
+ tier?: string;
262
+ unitPrice?: number;
263
+ }): Promise<CartItem>;
264
+ updateCartItem(cartId: string, itemId: string, quantity: number): Promise<Cart>;
265
+ removeCartItem(cartId: string, itemId: string): Promise<void>;
266
+ checkout(cartId: string, customerEmail?: string, payment?: PaymentData): Promise<Order>;
267
+ findCustomer(query: string): Promise<Customer[]>;
268
+ getCustomer(id: string): Promise<Customer>;
269
+ createCustomer(data: {
270
+ first_name: string;
271
+ last_name: string;
272
+ email: string;
273
+ phone?: string;
274
+ }): Promise<Customer>;
275
+ listOrders(params?: {
276
+ customer_id?: string;
277
+ limit?: number;
278
+ starting_after?: string;
279
+ }): Promise<ListResponse<Order>>;
280
+ getOrder(id: string): Promise<Order>;
281
+ getCustomerOrders(customerId: string): Promise<Order[]>;
282
+ sendCode(email: string): Promise<SendCodeResponse>;
283
+ verifyCode(email: string, code: string): Promise<VerifyCodeResponse>;
284
+ getCustomerAnalytics(customerId: string, customerName?: string): Promise<CustomerAnalytics | null>;
285
+ listLocations(): Promise<ListResponse<Location>>;
286
+ getCOAEmbedUrl(productId: string): string;
287
+ fetchStorefrontConfig(): Promise<StorefrontConfig>;
288
+ createSession(params: {
289
+ user_agent?: string;
290
+ referrer?: string;
291
+ }): Promise<StorefrontSession>;
292
+ updateSession(sessionId: string, params: {
293
+ last_active_at?: string;
294
+ customer_id?: string;
295
+ }): Promise<StorefrontSession>;
296
+ trackEvent(params: {
297
+ session_id: string;
298
+ event_type: EventType;
299
+ event_data?: Record<string, unknown>;
300
+ }): Promise<void>;
301
+ static encodeBase64Url: typeof encodeBase64Url;
302
+ static signMedia: typeof signMedia;
303
+ }
304
+
305
+ export { type Address as A, type Cart as C, type EventType as E, type ListResponse as L, type Order as O, type PaymentData as P, type SendCodeResponse as S, type TaxBreakdown as T, type VerifyCodeResponse as V, WhaleClient as W, type CartItem as a, type Category as b, type Customer as c, type CustomerAnalytics as d, type Location as e, type OrderItem as f, type PixelConfig as g, type PricingTier as h, type Product as i, type ProductVariation as j, type StorefrontConfig as k, type StorefrontSession as l, type WhaleStorefrontConfig as m };
package/dist/index.cjs CHANGED
@@ -1,12 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var chunkXMLH3TLA_cjs = require('./chunk-XMLH3TLA.cjs');
3
+ var chunkDAM7NZCI_cjs = require('./chunk-DAM7NZCI.cjs');
4
+ var chunkOP4LOUCV_cjs = require('./chunk-OP4LOUCV.cjs');
4
5
 
5
6
 
6
7
 
8
+ Object.defineProperty(exports, "PixelManager", {
9
+ enumerable: true,
10
+ get: function () { return chunkDAM7NZCI_cjs.PixelManager; }
11
+ });
7
12
  Object.defineProperty(exports, "WhaleClient", {
8
13
  enumerable: true,
9
- get: function () { return chunkXMLH3TLA_cjs.WhaleClient; }
14
+ get: function () { return chunkOP4LOUCV_cjs.WhaleClient; }
15
+ });
16
+ Object.defineProperty(exports, "resilientSend", {
17
+ enumerable: true,
18
+ get: function () { return chunkOP4LOUCV_cjs.resilientSend; }
10
19
  });
11
20
  //# sourceMappingURL=index.cjs.map
12
21
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -1,269 +1,16 @@
1
- interface PricingTier {
2
- id: string;
3
- unit: string;
4
- label: string;
5
- quantity: number;
6
- sort_order: number;
7
- default_price: number;
8
- }
9
- interface ProductVariation {
10
- id: string;
11
- product_id: string;
12
- name: string;
13
- sku: string | null;
14
- price: number;
15
- stock_quantity: number;
16
- attributes: Record<string, string>;
17
- }
18
- interface Product {
19
- id: string;
20
- name: string;
21
- slug: string;
22
- sku: string | null;
23
- description: string | null;
24
- status: string;
25
- type: string;
26
- primary_category_id: string;
27
- featured_image: string | null;
28
- image_gallery: string[];
29
- pricing_data: PricingTier[] | {
30
- mode?: string;
31
- tiers?: PricingTier[];
32
- } | null;
33
- custom_fields: Record<string, string | null>;
34
- stock_quantity?: number;
35
- }
36
- interface Category {
37
- id: string;
38
- name: string;
39
- slug: string;
40
- }
41
- interface CartItem {
42
- id: string;
43
- product_id: string;
44
- product_name: string;
45
- image_url: string | null;
46
- quantity: number;
47
- unit_price: number;
48
- tier_label: string | null;
49
- line_total: number;
50
- }
51
- interface TaxBreakdown {
52
- name: string;
53
- rate: number;
54
- type: string;
55
- rate_decimal: number;
56
- }
57
- interface Cart {
58
- id: string;
59
- items: CartItem[];
60
- item_count: number;
61
- subtotal: number;
62
- tax_rate: number;
63
- tax_amount: number;
64
- total: number;
65
- tax_breakdown: TaxBreakdown[];
66
- discount_amount: number;
67
- customer_email: string | null;
68
- }
69
- interface Order {
70
- id: string;
71
- order_number: string;
72
- status: string;
73
- total_amount: number;
74
- subtotal: number;
75
- tax_amount: number;
76
- discount_amount: number;
77
- item_count?: number;
78
- created_at: string;
79
- payment_status?: string;
80
- fulfillment_status?: string;
81
- items?: OrderItem[];
82
- }
83
- interface OrderItem {
84
- id: string;
85
- product_name: string;
86
- quantity: number;
87
- unit_price?: number;
88
- cost_per_unit?: number;
89
- line_total: number;
90
- }
91
- interface Customer {
92
- id: string;
93
- first_name: string;
94
- last_name: string;
95
- email: string | null;
96
- phone: string | null;
97
- loyalty_points: number;
98
- loyalty_tier: string;
99
- total_spent: number;
100
- total_orders: number;
101
- lifetime_value?: number;
102
- street_address?: string | null;
103
- city?: string | null;
104
- state?: string | null;
105
- postal_code?: string | null;
106
- date_of_birth?: string | null;
107
- created_at?: string;
108
- is_staff?: boolean;
109
- email_consent?: boolean;
110
- sms_consent?: boolean;
111
- }
112
- interface Address {
113
- firstName: string;
114
- lastName: string;
115
- address: string;
116
- city: string;
117
- state: string;
118
- zip: string;
119
- country: string;
120
- }
121
- interface PaymentData {
122
- payment_method: 'card' | 'cash';
123
- opaque_data?: {
124
- dataDescriptor: string;
125
- dataValue: string;
126
- };
127
- billTo?: Address;
128
- shipTo?: Address;
129
- }
130
- interface CustomerAnalytics {
131
- customer_id: string;
132
- customer_name: string;
133
- total_orders: number;
134
- lifetime_revenue: number;
135
- avg_order_value: number;
136
- ltv_tier: string;
137
- rfm_segment: string;
138
- churn_risk: string;
139
- last_order_date: string;
140
- recency_days: number;
141
- }
142
- interface Location {
143
- id: string;
144
- name: string;
145
- address?: string;
146
- city?: string;
147
- state?: string;
148
- zip?: string;
149
- phone?: string;
150
- is_active?: boolean;
151
- }
152
- interface SendCodeResponse {
153
- sent: boolean;
154
- }
155
- interface VerifyCodeResponse {
156
- object: string;
157
- token_hash: string;
158
- needs_profile: boolean;
159
- customer: Customer | null;
160
- }
161
- interface StorefrontSession {
162
- id: string;
163
- store_id: string;
164
- customer_id?: string;
165
- started_at: string;
166
- last_active_at: string;
167
- }
168
- interface ListResponse<T> {
169
- object: 'list';
170
- data: T[];
171
- has_more: boolean;
172
- cursors?: {
173
- before?: string;
174
- after?: string;
175
- };
176
- url?: string;
177
- }
178
- interface WhaleStorefrontConfig {
179
- /** Store UUID */
180
- storeId: string;
181
- /** API key (wk_live_... or wk_test_...) */
182
- apiKey: string;
183
- /** Gateway base URL. Defaults to https://whale-gateway.fly.dev */
184
- gatewayUrl?: string;
185
- /** Client-side proxy path. Defaults to /api/gw */
186
- proxyPath?: string;
187
- /** Media signing secret for image/video proxy */
188
- mediaSigningSecret?: string;
189
- /** Supabase host for media URL detection */
190
- supabaseHost?: string;
191
- /** localStorage key prefix. Defaults to "whale" */
192
- storagePrefix?: string;
193
- /** Analytics session TTL in ms. Defaults to 30 minutes */
194
- sessionTtl?: number;
195
- /** Enable debug logging */
196
- debug?: boolean;
197
- }
198
- type EventType = 'page_view' | 'product_view' | 'add_to_cart' | 'remove_from_cart' | 'begin_checkout' | 'purchase' | 'category_view' | 'search';
1
+ export { A as Address, C as Cart, a as CartItem, b as Category, c as Customer, d as CustomerAnalytics, E as EventType, L as ListResponse, e as Location, O as Order, f as OrderItem, P as PaymentData, g as PixelConfig, h as PricingTier, i as Product, j as ProductVariation, S as SendCodeResponse, k as StorefrontConfig, l as StorefrontSession, T as TaxBreakdown, V as VerifyCodeResponse, W as WhaleClient, m as WhaleStorefrontConfig } from './client-y0V1x0px.cjs';
2
+ export { P as PixelManager } from './pixel-manager-Db6Czwr2.cjs';
199
3
 
200
- declare class WhaleClient {
201
- readonly storeId: string;
202
- readonly apiKey: string;
203
- readonly gatewayUrl: string;
204
- readonly proxyPath: string;
205
- private _sessionToken;
206
- constructor(config: WhaleStorefrontConfig);
207
- setSessionToken(token: string | null): void;
208
- getSessionToken(): string | null;
209
- private get baseUrl();
210
- private request;
211
- listProducts(params?: {
212
- limit?: number;
213
- starting_after?: string;
214
- status?: string;
215
- }): Promise<ListResponse<Product>>;
216
- getProduct(id: string): Promise<Product>;
217
- getAllProducts(options?: {
218
- status?: string;
219
- maxPages?: number;
220
- revalidate?: number;
221
- filter?: (product: Product) => boolean;
222
- }): Promise<Product[]>;
223
- createCart(customerEmail?: string): Promise<Cart>;
224
- getCart(cartId: string): Promise<Cart>;
225
- addToCart(cartId: string, productId: string, quantity: number, options?: {
226
- tier?: string;
227
- unitPrice?: number;
228
- }): Promise<CartItem>;
229
- updateCartItem(cartId: string, itemId: string, quantity: number): Promise<Cart>;
230
- removeCartItem(cartId: string, itemId: string): Promise<void>;
231
- checkout(cartId: string, customerEmail?: string, payment?: PaymentData): Promise<Order>;
232
- findCustomer(query: string): Promise<Customer[]>;
233
- getCustomer(id: string): Promise<Customer>;
234
- createCustomer(data: {
235
- first_name: string;
236
- last_name: string;
237
- email: string;
238
- phone?: string;
239
- }): Promise<Customer>;
240
- listOrders(params?: {
241
- customer_id?: string;
242
- limit?: number;
243
- starting_after?: string;
244
- }): Promise<ListResponse<Order>>;
245
- getOrder(id: string): Promise<Order>;
246
- getCustomerOrders(customerId: string): Promise<Order[]>;
247
- sendCode(email: string): Promise<SendCodeResponse>;
248
- verifyCode(email: string, code: string): Promise<VerifyCodeResponse>;
249
- getCustomerAnalytics(customerId: string, customerName?: string): Promise<CustomerAnalytics | null>;
250
- listLocations(): Promise<ListResponse<Location>>;
251
- getCOAEmbedUrl(productId: string): string;
252
- createSession(params: {
253
- user_agent?: string;
254
- referrer?: string;
255
- }): Promise<StorefrontSession>;
256
- updateSession(sessionId: string, params: {
257
- last_active_at?: string;
258
- customer_id?: string;
259
- }): Promise<StorefrontSession>;
260
- trackEvent(params: {
261
- session_id: string;
262
- event_type: EventType;
263
- event_data?: Record<string, unknown>;
264
- }): Promise<void>;
265
- static encodeBase64Url(url: string): string;
266
- static signMedia(signingSecret: string, encodedUrl: string, w: string, q: string, f: string): string;
267
- }
4
+ /**
5
+ * Resilient HTTP sender for analytics/event payloads.
6
+ *
7
+ * Retries transient (5xx / network) failures with linear back-off,
8
+ * then falls back to navigator.sendBeacon so the event still lands
9
+ * even when the tab is being unloaded.
10
+ *
11
+ * 4xx responses are NOT retried — they indicate a client error that
12
+ * won't resolve by resending.
13
+ */
14
+ declare function resilientSend(url: string, payload: object, headers: Record<string, string>): Promise<void>;
268
15
 
269
- export { type Address, type Cart, type CartItem, type Category, type Customer, type CustomerAnalytics, type EventType, type ListResponse, type Location, type Order, type OrderItem, type PaymentData, type PricingTier, type Product, type ProductVariation, type SendCodeResponse, type StorefrontSession, type TaxBreakdown, type VerifyCodeResponse, WhaleClient, type WhaleStorefrontConfig };
16
+ export { resilientSend };