@ecomiq/storefront 1.0.0 → 1.0.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 (45) hide show
  1. package/README.md +63 -17
  2. package/dist/chunk-PCTSWSTB.js +346 -0
  3. package/dist/chunk-PCTSWSTB.js.map +1 -0
  4. package/dist/chunk-PDK2VYWD.js +1598 -0
  5. package/dist/chunk-PDK2VYWD.js.map +1 -0
  6. package/dist/chunk-Q762YXCQ.js +175 -0
  7. package/dist/chunk-Q762YXCQ.js.map +1 -0
  8. package/dist/{index-C-xqLr1g.d.ts → chunks/client.d.ts} +6577 -4565
  9. package/dist/chunks/client.js +2046 -0
  10. package/dist/chunks/client.js.map +1 -0
  11. package/dist/chunks/config.js +3 -0
  12. package/dist/chunks/config.js.map +1 -0
  13. package/dist/chunks/server-nextjs.d.ts +33 -0
  14. package/dist/chunks/server-nextjs.js +30 -0
  15. package/dist/chunks/server-nextjs.js.map +1 -0
  16. package/dist/chunks/server-tanstack.d.ts +22 -0
  17. package/dist/chunks/server-tanstack.js +30 -0
  18. package/dist/chunks/server-tanstack.js.map +1 -0
  19. package/dist/ecomiq-shell-ui-SWIFLQVM.js +8 -0
  20. package/dist/ecomiq-shell-ui-SWIFLQVM.js.map +1 -0
  21. package/dist/format-currency-oJD9jGYW.d.ts +6751 -0
  22. package/dist/index.d.ts +20 -30
  23. package/dist/index.js +11 -103
  24. package/dist/index.js.map +1 -1
  25. package/dist/index.server.d.ts +8 -0
  26. package/dist/index.server.js +7 -0
  27. package/dist/index.server.js.map +1 -0
  28. package/dist/nextjs/api.js +1 -174
  29. package/dist/nextjs/api.js.map +1 -1
  30. package/dist/nextjs.d.ts +13 -41
  31. package/dist/nextjs.js +11 -2964
  32. package/dist/nextjs.js.map +1 -1
  33. package/dist/nextjs.server.d.ts +1 -0
  34. package/dist/nextjs.server.js +1 -0
  35. package/dist/nextjs.server.js.map +1 -0
  36. package/dist/tanstack/api.js +3 -171
  37. package/dist/tanstack/api.js.map +1 -1
  38. package/dist/tanstack.d.ts +13 -30
  39. package/dist/tanstack.js +11 -2964
  40. package/dist/tanstack.js.map +1 -1
  41. package/dist/tanstack.server.d.ts +1 -0
  42. package/dist/tanstack.server.js +1 -0
  43. package/dist/tanstack.server.js.map +1 -0
  44. package/package.json +13 -1
  45. /package/dist/{..d.ts → chunks/config.d.ts} +0 -0
@@ -0,0 +1,2046 @@
1
+ "use client";
2
+ import { z } from 'zod';
3
+ import { QueryClient, hydrate, QueryClientProvider, useMutation, useQuery, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
4
+ import React2, { createContext, useRef, useEffect, useContext, useState, useMemo, useCallback } from 'react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+ import { toast } from 'sonner';
7
+ import { create } from 'zustand';
8
+ import { persist } from 'zustand/middleware';
9
+
10
+ // src/core/client/store-api-errors.ts
11
+ function isCartNotActiveApiError(error) {
12
+ if (!error || typeof error !== "object") return false;
13
+ const e = error;
14
+ if (e.status !== 400) return false;
15
+ const body = e.body;
16
+ const keys = body?.errors ? Object.keys(body.errors) : [];
17
+ return keys.includes("Carts.NotActive");
18
+ }
19
+
20
+ // src/core/client/store-api-client.ts
21
+ var STORE_API_PATH = "/api/store";
22
+ var serverRequestOriginGetter = null;
23
+ var serverStoreIdGetter = null;
24
+ var clientStoreIdGetter = null;
25
+ function setServerRequestOrigin(getter) {
26
+ serverRequestOriginGetter = getter;
27
+ }
28
+ function setServerStoreId(storeId) {
29
+ serverStoreIdGetter = storeId?.trim() || null;
30
+ }
31
+ function setClientStoreId(storeId) {
32
+ if (typeof window === "undefined") return;
33
+ clientStoreIdGetter = storeId?.trim() || null;
34
+ }
35
+ async function getStoreApiBaseUrl() {
36
+ if (typeof window !== "undefined") {
37
+ return STORE_API_PATH;
38
+ }
39
+ if (serverRequestOriginGetter) {
40
+ return `${serverRequestOriginGetter.replace(/\/$/, "")}/${STORE_API_PATH.replace(/^\//, "")}`;
41
+ }
42
+ return STORE_API_PATH;
43
+ }
44
+ function createStoreApiClient(baseUrl) {
45
+ return new StoreApiClient(baseUrl);
46
+ }
47
+ async function getStoreApiClient() {
48
+ const baseUrl = await getStoreApiBaseUrl();
49
+ return new StoreApiClient(baseUrl);
50
+ }
51
+ var StoreApiClient = class {
52
+ baseUrl;
53
+ constructor(baseUrl = STORE_API_PATH) {
54
+ this.baseUrl = baseUrl.replace(/\/$/, "");
55
+ }
56
+ async request(path, init, options) {
57
+ const pathNorm = path.replace(/^\/+/, "");
58
+ const url = path.startsWith("http") ? path : `${this.baseUrl}/${pathNorm}`;
59
+ const headers = new Headers(init.headers ?? {});
60
+ headers.set("Content-Type", "application/json");
61
+ headers.set("Accept-Encoding", "identity");
62
+ const explicitStoreId = options?.xStoreId?.trim();
63
+ const runtimeStoreId = explicitStoreId || (typeof window === "undefined" ? serverStoreIdGetter : clientStoreIdGetter);
64
+ if (runtimeStoreId && !headers.has("x-store-id")) {
65
+ headers.set("X-Store-Id", runtimeStoreId);
66
+ }
67
+ if (options?.xStoreDomain) {
68
+ headers.set("X-Store-Domain", options.xStoreDomain);
69
+ }
70
+ if (options?.xCartId) {
71
+ headers.set("X-Cart-Token", options.xCartId);
72
+ }
73
+ const bearer = typeof options?.bearerToken === "string" && options.bearerToken.trim().length > 0 ? options.bearerToken.trim() : void 0;
74
+ if (bearer) {
75
+ headers.set(
76
+ "Authorization",
77
+ bearer.toLowerCase().startsWith("bearer ") ? bearer : `Bearer ${bearer}`
78
+ );
79
+ }
80
+ const isServer = typeof window === "undefined";
81
+ const res = await fetch(url, {
82
+ ...init,
83
+ headers,
84
+ credentials: isServer ? "same-origin" : "include",
85
+ ...options?.noStore ? { cache: "no-store" } : {},
86
+ ...options?.cacheKey && isServer && !options?.noStore ? {
87
+ next: {
88
+ revalidate: 60,
89
+ tags: [options.cacheKey]
90
+ }
91
+ } : {}
92
+ });
93
+ if (!res.ok) {
94
+ let body;
95
+ try {
96
+ const errorText = await res.text();
97
+ body = errorText ? JSON.parse(errorText) : void 0;
98
+ } catch {
99
+ body = void 0;
100
+ }
101
+ const msg = typeof body === "object" && body !== null && "title" in body && typeof body.title === "string" ? body.title : res.statusText || "Store API error";
102
+ const err = new Error(msg);
103
+ err.status = res.status;
104
+ err.body = body;
105
+ throw err;
106
+ }
107
+ const text = await res.text();
108
+ if (!text) return void 0;
109
+ return JSON.parse(text);
110
+ }
111
+ get(path, options) {
112
+ return this.request(path, { method: "GET" }, options);
113
+ }
114
+ post(path, data, options) {
115
+ return this.request(
116
+ path,
117
+ {
118
+ method: "POST",
119
+ body: data != null ? JSON.stringify(data) : void 0
120
+ },
121
+ options
122
+ );
123
+ }
124
+ patch(path, data, options) {
125
+ return this.request(path, {
126
+ method: "PATCH",
127
+ body: data != null ? JSON.stringify(data) : void 0
128
+ }, options);
129
+ }
130
+ put(path, data, options) {
131
+ return this.request(
132
+ path,
133
+ {
134
+ method: "PUT",
135
+ body: data != null ? JSON.stringify(data) : void 0
136
+ },
137
+ options
138
+ );
139
+ }
140
+ delete(path, options) {
141
+ return this.request(path, { method: "DELETE" }, options);
142
+ }
143
+ };
144
+ var storeApiClient = new StoreApiClient(STORE_API_PATH);
145
+ var ProductVariantSchema = z.object({
146
+ id: z.coerce.string(),
147
+ name: z.string(),
148
+ storeId: z.string(),
149
+ productId: z.coerce.string(),
150
+ basePrice: z.number().positive().optional().nullable(),
151
+ comparePrice: z.number().positive().optional().nullable(),
152
+ //TODO: remove this field
153
+ originalPrice: z.number().positive().optional().nullable(),
154
+ costPrice: z.number().positive().optional().nullable(),
155
+ isDefault: z.boolean().optional().nullable(),
156
+ reserveStock: z.number().nonnegative().optional().nullable(),
157
+ weight: z.number().nonnegative().optional().nullable().default(0),
158
+ width: z.number().nonnegative().optional().nullable(),
159
+ height: z.number().nonnegative().optional().nullable(),
160
+ unitOfMeasure: z.string().optional().nullable(),
161
+ order: z.number().nonnegative().optional().nullable().default(0),
162
+ sku: z.string().optional().nullable(),
163
+ stock: z.number().nonnegative().optional().nullable(),
164
+ leadTime: z.string().optional().nullable(),
165
+ barCode: z.string().optional().nullable(),
166
+ shippingWeight: z.number().nonnegative().optional().nullable(),
167
+ images: z.array(z.string()).optional().nullable(),
168
+ attributes: z.array(z.string()).optional().nullable(),
169
+ variantStatus: z.string().optional().nullable(),
170
+ status: z.string().optional().nullable(),
171
+ createdOn: z.string().optional().nullable(),
172
+ updatedOn: z.string().optional().nullable(),
173
+ deletedOn: z.string().optional().nullable()
174
+ });
175
+ var ProductSchema = z.object({
176
+ id: z.coerce.string(),
177
+ name: z.string(),
178
+ images: z.array(z.object({
179
+ url: z.string().url(),
180
+ name: z.string().optional(),
181
+ isPrimary: z.boolean().optional()
182
+ })),
183
+ basePrice: z.number().positive().optional(),
184
+ salePrice: z.number().positive().optional(),
185
+ slug: z.string(),
186
+ description: z.string().optional(),
187
+ categories: z.array(z.object({
188
+ id: z.coerce.string(),
189
+ name: z.string(),
190
+ slug: z.string(),
191
+ logo: z.string().optional(),
192
+ icon: z.string().optional()
193
+ })).optional(),
194
+ tags: z.array(z.string()).optional(),
195
+ inStock: z.boolean().optional(),
196
+ variants: z.array(ProductVariantSchema).optional()
197
+ });
198
+ z.object({
199
+ items: z.array(ProductSchema),
200
+ meta: z.object({
201
+ total: z.number().int().positive(),
202
+ page: z.number().int().positive(),
203
+ pageSize: z.number().int().positive(),
204
+ hasNextPage: z.boolean()
205
+ })
206
+ });
207
+ z.object({
208
+ category: z.string().optional(),
209
+ search: z.string().optional(),
210
+ minPrice: z.number().positive().optional(),
211
+ maxPrice: z.number().positive().optional(),
212
+ inStock: z.boolean().optional(),
213
+ sortBy: z.enum(["name", "price", "createdAt"]).optional(),
214
+ sortOrder: z.enum(["asc", "desc"]).optional(),
215
+ page: z.number().int().positive().optional(),
216
+ limit: z.number().int().positive().optional()
217
+ });
218
+ var StorefrontProductSchema = z.object({
219
+ id: z.coerce.string(),
220
+ name: z.string(),
221
+ slug: z.string(),
222
+ productType: z.string().optional().nullable(),
223
+ imageUrl: z.string().optional().nullable(),
224
+ price: z.number().nonnegative(),
225
+ compareAtPrice: z.number().nonnegative().optional().nullable(),
226
+ variantCount: z.number().int().nonnegative().optional().default(0),
227
+ isAvailable: z.boolean(),
228
+ totalInventory: z.number().int().nonnegative(),
229
+ bundleItemsCount: z.number().int().nonnegative().optional().default(0),
230
+ brand: z.string().optional().nullable(),
231
+ category: z.string().optional().nullable(),
232
+ status: z.string().optional().nullable(),
233
+ tags: z.array(z.string()).optional().nullable()
234
+ });
235
+ var StorefrontFacetSchema = z.object({
236
+ value: z.string(),
237
+ count: z.number().int().nonnegative()
238
+ });
239
+ var StorefrontProductsResponseSchema = z.object({
240
+ pageIndex: z.number().int().positive(),
241
+ pageSize: z.number().int().positive(),
242
+ totalCount: z.number().int().nonnegative(),
243
+ totalPages: z.number().int().nonnegative(),
244
+ products: z.array(StorefrontProductSchema),
245
+ categories: z.array(StorefrontFacetSchema).optional().default([]),
246
+ brands: z.array(StorefrontFacetSchema).optional().default([]),
247
+ minPrice: z.number().nonnegative().optional().nullable(),
248
+ maxPrice: z.number().nonnegative().optional().nullable()
249
+ });
250
+ var StorefrontProductsParamsSchema = z.object({
251
+ page: z.number().int().positive().optional().default(1),
252
+ pageSize: z.number().int().positive().optional().default(20),
253
+ sort: z.enum(["price_asc", "price_desc", "name_asc", "name_desc", "newest"]).optional().default("price_asc"),
254
+ sellerId: z.string().optional(),
255
+ search: z.string().optional(),
256
+ collection: z.string().optional(),
257
+ category: z.string().optional(),
258
+ brand: z.string().optional(),
259
+ productType: z.string().optional(),
260
+ inStock: z.boolean().optional(),
261
+ minPrice: z.number().nonnegative().optional(),
262
+ maxPrice: z.number().nonnegative().optional()
263
+ });
264
+ var StorefrontVariantOptionSchema = z.object({
265
+ key: z.string(),
266
+ name: z.string(),
267
+ value: z.string()
268
+ });
269
+ var StorefrontProductImageSchema = z.object({
270
+ url: z.string(),
271
+ name: z.string().optional().nullable(),
272
+ order: z.number().int().nonnegative().optional()
273
+ });
274
+ var StorefrontVariantSchema = z.object({
275
+ id: z.coerce.string().optional().default(""),
276
+ sku: z.string(),
277
+ status: z.string().optional().nullable(),
278
+ price: z.number().nonnegative(),
279
+ compareAtPrice: z.number().nonnegative().optional().nullable(),
280
+ quantity: z.number().int().nonnegative(),
281
+ options: z.array(StorefrontVariantOptionSchema).optional().default([]),
282
+ images: z.array(StorefrontProductImageSchema).optional().default([])
283
+ });
284
+ var StorefrontPriceTierSchema = z.object({
285
+ variantId: z.coerce.string(),
286
+ minQuantity: z.number().int().positive(),
287
+ maxQuantity: z.number().int().positive().optional().nullable(),
288
+ unitPrice: z.number().nonnegative()
289
+ });
290
+ var StorefrontBundleItemSchema = z.object({
291
+ productId: z.coerce.string(),
292
+ variantId: z.coerce.string(),
293
+ productName: z.string(),
294
+ variantName: z.string().optional().nullable(),
295
+ sku: z.string().optional().nullable(),
296
+ brand: z.string().optional().nullable(),
297
+ imageUrl: z.string().optional().nullable(),
298
+ quantity: z.number().int(),
299
+ availableStock: z.number().int().optional().default(0),
300
+ allowBackorders: z.boolean().optional().default(false),
301
+ requiresShipping: z.boolean().optional().default(true)
302
+ });
303
+ var StorefrontProductDetailSchema = z.object({
304
+ id: z.coerce.string(),
305
+ name: z.string(),
306
+ slug: z.string(),
307
+ description: z.string().optional().nullable(),
308
+ productType: z.string().optional().nullable(),
309
+ status: z.string().optional().nullable(),
310
+ imageUrl: z.string().optional().nullable(),
311
+ price: z.number().nonnegative(),
312
+ compareAtPrice: z.number().nonnegative().optional().nullable(),
313
+ isAvailable: z.boolean(),
314
+ totalInventory: z.number().int().nonnegative(),
315
+ brand: z.string().optional().nullable(),
316
+ category: z.string().optional().nullable(),
317
+ categoryId: z.coerce.string().optional().nullable(),
318
+ tags: z.array(z.string()).optional().nullable(),
319
+ specifications: z.array(z.record(z.string(), z.unknown())).optional().default([]),
320
+ variants: z.array(StorefrontVariantSchema).optional().default([]),
321
+ images: z.array(StorefrontProductImageSchema).optional().default([]),
322
+ bundleItems: z.array(StorefrontBundleItemSchema).optional().default([]),
323
+ priceTiers: z.array(StorefrontPriceTierSchema).optional().default([]),
324
+ createdAt: z.string().optional().nullable(),
325
+ updatedAt: z.string().optional().nullable()
326
+ });
327
+
328
+ // src/core/client/store-api-product.service.ts
329
+ async function getStorefrontProducts(params, cacheKey) {
330
+ const parsed = StorefrontProductsParamsSchema.parse(params ?? {});
331
+ const searchParams = new URLSearchParams();
332
+ searchParams.set("page", String(parsed.page));
333
+ searchParams.set("pageSize", String(parsed.pageSize));
334
+ if (parsed.sort) searchParams.set("sort", parsed.sort);
335
+ if (parsed.sellerId) searchParams.set("sellerId", parsed.sellerId);
336
+ if (parsed.search) searchParams.set("search", parsed.search);
337
+ if (parsed.collection) searchParams.set("collection", parsed.collection);
338
+ if (parsed.category) searchParams.set("category", parsed.category);
339
+ if (parsed.brand) searchParams.set("brand", parsed.brand);
340
+ if (parsed.productType) searchParams.set("productType", parsed.productType);
341
+ if (parsed.inStock != null) searchParams.set("inStock", String(parsed.inStock));
342
+ if (parsed.minPrice != null) searchParams.set("minPrice", String(parsed.minPrice));
343
+ if (parsed.maxPrice != null) searchParams.set("maxPrice", String(parsed.maxPrice));
344
+ const path = `products?${searchParams.toString()}`;
345
+ const client = await getStoreApiClient();
346
+ const response = await client.get(path, {
347
+ cacheKey
348
+ });
349
+ return StorefrontProductsResponseSchema.parse(response);
350
+ }
351
+ async function getStorefrontProductBySlug(slug) {
352
+ const path = `products/${encodeURIComponent(slug)}`;
353
+ const client = await getStoreApiClient();
354
+ const response = await client.get(path);
355
+ return StorefrontProductDetailSchema.parse(response);
356
+ }
357
+ var StorefrontCollectionSchema = z.object({
358
+ id: z.coerce.string(),
359
+ slug: z.string(),
360
+ name: z.string(),
361
+ description: z.string().nullable().optional(),
362
+ imageUrl: z.string().nullable().optional(),
363
+ type: z.string(),
364
+ productCount: z.number().int().nonnegative()
365
+ });
366
+ var StorefrontCollectionsResponseSchema = z.array(StorefrontCollectionSchema);
367
+ var StorefrontCollectionDetailSchema = StorefrontCollectionSchema;
368
+
369
+ // src/core/client/store-api-collection.service.ts
370
+ async function getStorefrontCollections() {
371
+ const client = await getStoreApiClient();
372
+ const response = await client.get("collections");
373
+ return StorefrontCollectionsResponseSchema.parse(response);
374
+ }
375
+ async function getStorefrontCollectionBySlug(slug) {
376
+ const client = await getStoreApiClient();
377
+ const response = await client.get(
378
+ `collections/by-slug/${encodeURIComponent(slug)}`
379
+ );
380
+ return StorefrontCollectionDetailSchema.parse(response);
381
+ }
382
+ var StorefrontPageListItemSchema = z.object({
383
+ id: z.string(),
384
+ name: z.string(),
385
+ slug: z.string(),
386
+ layout: z.string()
387
+ });
388
+ var StorefrontPageSeoSchema = z.object({
389
+ title: z.string().optional(),
390
+ description: z.string().optional()
391
+ }).optional();
392
+ var StorefrontPageSettingsSchema = z.object({
393
+ seo: StorefrontPageSeoSchema,
394
+ html: z.string().optional(),
395
+ title: z.string().optional()
396
+ }).catchall(z.unknown());
397
+ var StorefrontPageBlockSchema = z.object({
398
+ id: z.string(),
399
+ type: z.string(),
400
+ order: z.number(),
401
+ settings: z.record(z.unknown()).optional()
402
+ });
403
+ var StorefrontPageSectionSchema = z.object({
404
+ id: z.string(),
405
+ type: z.string(),
406
+ order: z.number(),
407
+ settings: z.record(z.unknown()).optional(),
408
+ blocks: z.array(StorefrontPageBlockSchema).optional().default([])
409
+ });
410
+ var StorefrontPageDetailSchema = z.object({
411
+ id: z.string(),
412
+ name: z.string(),
413
+ slug: z.string(),
414
+ layout: z.string(),
415
+ settings: StorefrontPageSettingsSchema.optional(),
416
+ sections: z.array(StorefrontPageSectionSchema).optional()
417
+ });
418
+ async function getStorefrontPages() {
419
+ const client = await getStoreApiClient();
420
+ const response = await client.get("pages");
421
+ return z.array(StorefrontPageListItemSchema).parse(response);
422
+ }
423
+ async function getStorefrontPageBySlug(slug) {
424
+ const path = `pages/${encodeURIComponent(slug)}`;
425
+ const client = await getStoreApiClient();
426
+ const response = await client.get(path);
427
+ return StorefrontPageDetailSchema.parse(response);
428
+ }
429
+ async function getStorefrontPagePreview(slug, token) {
430
+ const path = `pages/${encodeURIComponent(slug)}/preview?token=${encodeURIComponent(token)}`;
431
+ const client = await getStoreApiClient();
432
+ const response = await client.get(path);
433
+ return StorefrontPageDetailSchema.parse(response);
434
+ }
435
+ var CartBuyerRequestSchema = z.object({
436
+ email: z.string().email(),
437
+ firstName: z.string().min(1),
438
+ lastName: z.string().min(1),
439
+ phone: z.string().min(1)
440
+ });
441
+ var CartCreateRequestSchema = z.object({
442
+ currencyCode: z.string(),
443
+ salesChannelId: z.string(),
444
+ email: z.string().email()
445
+ });
446
+ var CartAddressSchema = z.object({
447
+ name: z.string().min(1),
448
+ address1: z.string().min(1),
449
+ city: z.string().min(1),
450
+ countryCode: z.string().min(2),
451
+ company: z.string().nullable().optional(),
452
+ address2: z.string().nullable().optional(),
453
+ province: z.string().nullable().optional(),
454
+ postalCode: z.string().nullable().optional(),
455
+ district: z.string().nullable().optional(),
456
+ phone: z.string().nullable().optional(),
457
+ latitude: z.number().nullable().optional(),
458
+ longitude: z.number().nullable().optional(),
459
+ geo: z.object({
460
+ departmentCode: z.string().nullable().optional(),
461
+ provinceCode: z.string().nullable().optional(),
462
+ districtCode: z.string().nullable().optional()
463
+ }).nullable().optional()
464
+ });
465
+ var CartAddressesRequestSchema = z.object({
466
+ shippingAddress: CartAddressSchema,
467
+ billingAddress: CartAddressSchema
468
+ });
469
+ var CartItemModifierRequestSchema = z.object({
470
+ modifierGroupId: z.coerce.string().min(1),
471
+ optionIds: z.array(z.coerce.string().min(1)).optional().default([])
472
+ });
473
+ var CartItemRequestSchema = z.object({
474
+ variantId: z.coerce.string().min(1),
475
+ quantity: z.number().int().positive(),
476
+ modifiers: z.array(CartItemModifierRequestSchema).optional()
477
+ });
478
+ var CartCouponRequestSchema = z.object({
479
+ code: z.string().min(1)
480
+ });
481
+ z.object({
482
+ subtotal: z.number(),
483
+ discount: z.number(),
484
+ tax: z.number(),
485
+ warranty: z.number().optional().default(0),
486
+ total: z.number()
487
+ });
488
+ z.object({
489
+ name: z.string().nullable().optional(),
490
+ address1: z.string(),
491
+ city: z.string(),
492
+ countryCode: z.string(),
493
+ company: z.string().nullable().optional(),
494
+ address2: z.string().nullable().optional(),
495
+ province: z.string().nullable().optional(),
496
+ postalCode: z.string().nullable().optional(),
497
+ district: z.string().nullable().optional(),
498
+ phone: z.string().nullable().optional(),
499
+ latitude: z.number().nullable().optional(),
500
+ longitude: z.number().nullable().optional(),
501
+ geo: z.object({
502
+ departmentCode: z.string().nullable().optional(),
503
+ provinceCode: z.string().nullable().optional(),
504
+ districtCode: z.string().nullable().optional()
505
+ }).nullable().optional()
506
+ });
507
+ var CartResponseBundleItemSchema = z.object({
508
+ productId: z.coerce.string(),
509
+ variantId: z.coerce.string(),
510
+ productName: z.string(),
511
+ variantName: z.string().nullable().optional(),
512
+ sku: z.string().nullable().optional(),
513
+ brand: z.string().nullable().optional(),
514
+ imageUrl: z.string().nullable().optional(),
515
+ quantity: z.number().int()
516
+ });
517
+ var CartResponseItemSchema = z.object({
518
+ id: z.string(),
519
+ title: z.string(),
520
+ variantLabel: z.string().nullable().optional(),
521
+ thumbnail: z.string().nullable().optional(),
522
+ quantity: z.number().int(),
523
+ variantId: z.coerce.string(),
524
+ variantSku: z.string().nullable().optional(),
525
+ unitPrice: z.number(),
526
+ bundleItems: z.array(CartResponseBundleItemSchema).optional().default([])
527
+ });
528
+ z.object({
529
+ id: z.string(),
530
+ name: z.string(),
531
+ description: z.string().nullable().optional(),
532
+ total: z.number(),
533
+ estimatedDays: z.number().int().nullable().optional(),
534
+ pickupPointId: z.string().nullable().optional(),
535
+ scheduledDate: z.string().nullable().optional(),
536
+ scheduledTime: z.string().nullable().optional()
537
+ });
538
+ var CartResponseSchema = z.object({
539
+ id: z.string(),
540
+ regionId: z.string().nullable().optional(),
541
+ salesChannelId: z.string().nullable().optional(),
542
+ email: z.string().email().nullable().optional(),
543
+ phone: z.string().nullable().optional(),
544
+ firstName: z.string().nullable().optional(),
545
+ lastName: z.string().nullable().optional(),
546
+ currencyCode: z.string(),
547
+ completedAt: z.string().nullable().optional(),
548
+ shippingAddress: z.unknown().nullable().optional(),
549
+ billingAddress: z.unknown().nullable().optional(),
550
+ metadata: z.record(z.string(), z.unknown()).optional().default({}),
551
+ promotionCodes: z.array(z.string()).optional().default([]),
552
+ items: z.array(CartResponseItemSchema).optional().default([]),
553
+ shippingMethods: z.array(z.unknown()).optional().default([]),
554
+ totals: z.object({
555
+ discountTotal: z.number(),
556
+ shippingTotal: z.number(),
557
+ subtotal: z.number(),
558
+ taxTotal: z.number(),
559
+ total: z.number(),
560
+ warrantyTotal: z.number()
561
+ })
562
+ });
563
+ var CartCheckoutRequestSchema = z.object({
564
+ paymentMethodCode: z.string().min(1),
565
+ externalRef: z.string().min(1),
566
+ receiptUrl: z.string().min(1).optional()
567
+ });
568
+ var CartCheckoutPaymentActionSchema = z.object({
569
+ publicConfiguration: z.object({
570
+ publishableKey: z.string().nullable().optional(),
571
+ checkoutMode: z.string().nullable().optional(),
572
+ phoneNumber: z.string().nullable().optional(),
573
+ accountHolder: z.string().nullable().optional(),
574
+ qrImageUrl: z.string().nullable().optional()
575
+ }).passthrough().nullable().optional(),
576
+ url: z.string().nullable().optional(),
577
+ html: z.string().nullable().optional(),
578
+ clientSecret: z.string().nullable().optional(),
579
+ qrCode: z.string().nullable().optional(),
580
+ expiresAt: z.string().nullable().optional()
581
+ }).passthrough();
582
+ var CartCheckoutPaymentSchema = z.object({
583
+ transactionId: z.string(),
584
+ paymentMethodCode: z.string(),
585
+ providerId: z.string().nullable().optional(),
586
+ status: z.string(),
587
+ amount: z.number(),
588
+ reference: z.string(),
589
+ actionType: z.string(),
590
+ receiptUrl: z.string().nullable().optional(),
591
+ action: CartCheckoutPaymentActionSchema.nullable().optional()
592
+ }).passthrough();
593
+ var CartCheckoutResponseSchema = z.object({
594
+ publicKey: z.string().optional(),
595
+ publishableKey: z.string().optional(),
596
+ stripePublicKey: z.string().optional(),
597
+ clientSecret: z.string().optional(),
598
+ intentClientSecret: z.string().optional(),
599
+ orderId: z.coerce.string().optional(),
600
+ orderGroup: z.string().optional(),
601
+ orderIds: z.array(z.coerce.string()).optional(),
602
+ /** Payload de pago (embedded, redirect, etc.) */
603
+ payment: CartCheckoutPaymentSchema.optional(),
604
+ cart: z.unknown().optional()
605
+ }).passthrough();
606
+ var CartPaymentReceiptResponseSchema = z.object({
607
+ id: z.string(),
608
+ url: z.string()
609
+ });
610
+ var CartPaymentMethodSchema = z.object({
611
+ code: z.string(),
612
+ name: z.string(),
613
+ description: z.string().nullable().optional(),
614
+ kind: z.string(),
615
+ isActive: z.boolean(),
616
+ isDefault: z.boolean(),
617
+ isManual: z.boolean(),
618
+ sortOrder: z.number(),
619
+ phoneNumber: z.string().nullable().optional(),
620
+ accountHolder: z.string().nullable().optional(),
621
+ qrImageUrl: z.string().nullable().optional()
622
+ });
623
+ var CartPaymentMethodsResponseSchema = z.object({
624
+ methods: z.array(CartPaymentMethodSchema)
625
+ });
626
+ var CartCheckoutReadResponseSchema = z.object({
627
+ cart: CartResponseSchema,
628
+ paymentMethods: CartPaymentMethodsResponseSchema
629
+ });
630
+ var ShippingRateSchema = z.object({
631
+ shippingMethodId: z.string(),
632
+ name: z.string(),
633
+ displayName: z.string().optional(),
634
+ type: z.string().optional(),
635
+ price: z.number(),
636
+ currency: z.string().optional(),
637
+ sortOrder: z.number().optional(),
638
+ rateId: z.string(),
639
+ description: z.string().nullable().optional(),
640
+ deliveryLocationId: z.string().nullable().optional(),
641
+ deliveryLocationName: z.string().nullable().optional(),
642
+ estimatedDeliveryDays: z.number().nullable().optional(),
643
+ serviceCode: z.string().nullable().optional(),
644
+ metadata: z.record(z.string(), z.unknown()).optional()
645
+ }).passthrough();
646
+ var ShippingOptionGroupSchema = z.object({
647
+ sellerId: z.string(),
648
+ shippingProfileId: z.string().nullable().optional(),
649
+ orderAmount: z.number().optional(),
650
+ totalWeight: z.number().optional(),
651
+ itemIds: z.array(z.string()).optional(),
652
+ rates: z.array(ShippingRateSchema)
653
+ }).passthrough();
654
+ var ShippingOptionsResponseSchema = z.object({
655
+ groups: z.array(ShippingOptionGroupSchema)
656
+ });
657
+ var CartShippingMethodPutRequestSchema = z.object({
658
+ rateId: z.string().min(1),
659
+ shippingMethodId: z.string().min(1),
660
+ serviceCode: z.string().nullable().optional(),
661
+ sellerId: z.string().nullable().optional(),
662
+ shippingProfileId: z.string().nullable().optional(),
663
+ locationId: z.string().nullable().optional(),
664
+ pickupPointId: z.string().nullable().optional(),
665
+ scheduledDate: z.string().nullable().optional(),
666
+ scheduledTime: z.string().nullable().optional()
667
+ });
668
+
669
+ // src/core/client/store-api-cart.service.ts
670
+ async function createCart(data) {
671
+ const payload = CartCreateRequestSchema.parse(data);
672
+ const client = await getStoreApiClient();
673
+ const response = await client.post("carts", payload);
674
+ return CartResponseSchema.parse(response);
675
+ }
676
+ async function getCart(cartId) {
677
+ if (!cartId) throw new Error("cartId is required");
678
+ const client = await getStoreApiClient();
679
+ const response = await client.get(`carts/${cartId}`);
680
+ return CartResponseSchema.parse(response);
681
+ }
682
+ async function addCartItem(data, cartId) {
683
+ if (!cartId) throw new Error("cartId is required");
684
+ const payload = CartItemRequestSchema.parse(data);
685
+ const variantId = Number(payload.variantId);
686
+ if (!Number.isSafeInteger(variantId) || variantId <= 0) {
687
+ throw new Error("variantId must be a valid public id");
688
+ }
689
+ const modifiers = payload.modifiers?.map((modifier) => {
690
+ const modifierGroupId = Number(modifier.modifierGroupId);
691
+ const optionIds = modifier.optionIds.map((optionId) => Number(optionId));
692
+ if (!Number.isSafeInteger(modifierGroupId) || modifierGroupId <= 0 || optionIds.some((optionId) => !Number.isSafeInteger(optionId) || optionId <= 0)) {
693
+ throw new Error("modifiers must use valid public ids");
694
+ }
695
+ return { modifierGroupId, optionIds };
696
+ });
697
+ const client = await getStoreApiClient();
698
+ const response = await client.post(`carts/${cartId}/items`, {
699
+ ...payload,
700
+ variantId,
701
+ ...modifiers ? { modifiers } : {}
702
+ });
703
+ return CartResponseSchema.parse(response);
704
+ }
705
+ async function patchCartBuyer(data, cartId) {
706
+ if (!cartId) throw new Error("cartId is required");
707
+ const payload = CartBuyerRequestSchema.parse(data);
708
+ const client = await getStoreApiClient();
709
+ const response = await client.patch(
710
+ `carts/${cartId}/buyer`,
711
+ payload
712
+ );
713
+ return CartResponseSchema.parse(response);
714
+ }
715
+ async function patchCartAddresses(data, cartId) {
716
+ if (!cartId) throw new Error("cartId is required");
717
+ const payload = CartAddressesRequestSchema.parse(data);
718
+ const client = await getStoreApiClient();
719
+ const response = await client.patch(
720
+ `carts/${cartId}/addresses`,
721
+ payload
722
+ );
723
+ return CartResponseSchema.parse(response);
724
+ }
725
+ async function addCartCoupon(cartId, data) {
726
+ if (!cartId) throw new Error("cartId is required");
727
+ const payload = CartCouponRequestSchema.parse(data);
728
+ const client = await getStoreApiClient();
729
+ const response = await client.post(
730
+ `carts/${cartId}/promotion-codes`,
731
+ payload
732
+ );
733
+ return CartResponseSchema.parse(response);
734
+ }
735
+ async function removeCartCoupon(cartId, code) {
736
+ if (!cartId) throw new Error("cartId is required");
737
+ if (!code.trim()) throw new Error("code is required");
738
+ const client = await getStoreApiClient();
739
+ const response = await client.delete(
740
+ `carts/${cartId}/promotion-codes/${encodeURIComponent(code.trim())}`
741
+ );
742
+ return CartResponseSchema.parse(response);
743
+ }
744
+ async function checkoutCart(data, cartId) {
745
+ if (!cartId) throw new Error("cartId is required");
746
+ const payload = CartCheckoutRequestSchema.parse(data);
747
+ const client = await getStoreApiClient();
748
+ const response = await client.post(
749
+ `carts/${cartId}/checkout`,
750
+ payload
751
+ );
752
+ return CartCheckoutResponseSchema.parse(response);
753
+ }
754
+ async function uploadPaymentReceipt(cartId, file) {
755
+ if (!cartId) throw new Error("cartId is required");
756
+ const baseUrl = await getStoreApiBaseUrl();
757
+ const form = new FormData();
758
+ form.set("file", file);
759
+ const response = await fetch(
760
+ `${baseUrl.replace(/\/$/, "")}/carts/${encodeURIComponent(cartId)}/payment-receipt`,
761
+ {
762
+ method: "POST",
763
+ body: form,
764
+ ...typeof window === "undefined" && { cache: "no-store" }
765
+ }
766
+ );
767
+ if (!response.ok) {
768
+ let body;
769
+ try {
770
+ const errorText = await response.text();
771
+ body = errorText ? JSON.parse(errorText) : void 0;
772
+ } catch {
773
+ body = void 0;
774
+ }
775
+ const message = typeof body === "object" && body !== null && "title" in body && typeof body.title === "string" ? body.title : response.statusText || "Store API error";
776
+ const error = new Error(message);
777
+ error.status = response.status;
778
+ error.body = body;
779
+ throw error;
780
+ }
781
+ return CartPaymentReceiptResponseSchema.parse(await response.json());
782
+ }
783
+ async function getCartCheckout(cartId) {
784
+ if (!cartId) throw new Error("cartId is required");
785
+ const client = await getStoreApiClient();
786
+ const response = await client.get(`carts/${cartId}/checkout`);
787
+ return CartCheckoutReadResponseSchema.parse(response);
788
+ }
789
+ async function getShippingOptions(cartId, postalCode) {
790
+ if (!cartId) throw new Error("cartId is required");
791
+ if (!postalCode?.trim()) throw new Error("postalCode is required");
792
+ const client = await getStoreApiClient();
793
+ const q = new URLSearchParams({ postalCode: postalCode.trim() });
794
+ const response = await client.get(
795
+ `carts/${cartId}/shipping-options?${q.toString()}`
796
+ );
797
+ return ShippingOptionsResponseSchema.parse(response);
798
+ }
799
+ async function putCartShippingMethod(cartId, data) {
800
+ if (!cartId) throw new Error("cartId is required");
801
+ const payload = CartShippingMethodPutRequestSchema.parse(data);
802
+ const client = await getStoreApiClient();
803
+ const response = await client.put(
804
+ `carts/${cartId}/shipping-method`,
805
+ payload
806
+ );
807
+ return CartResponseSchema.parse(response);
808
+ }
809
+ async function getCartPaymentMethods(cartId) {
810
+ if (!cartId) throw new Error("cartId is required");
811
+ const { paymentMethods } = await getCartCheckout(cartId);
812
+ return paymentMethods;
813
+ }
814
+ var CustomerRegisterRequestSchema = z.object({
815
+ email: z.string().email(),
816
+ firstName: z.string().trim().min(1),
817
+ lastName: z.string().trim().min(1),
818
+ countryIsoCode: z.string().trim().length(2),
819
+ password: z.string(),
820
+ phone: z.string().trim().optional()
821
+ });
822
+ var CustomerAddressSchema = z.object({
823
+ /** Presente en listados cuando el upstream expone el id para PUT/DELETE. */
824
+ id: z.string().optional(),
825
+ addressKey: z.string(),
826
+ countryIsoCode: z.string(),
827
+ addressLine: z.string(),
828
+ addressNumber: z.string(),
829
+ department: z.string(),
830
+ province: z.string(),
831
+ district: z.string(),
832
+ phone: z.string(),
833
+ cellPhone: z.string(),
834
+ postalCode: z.string(),
835
+ reference: z.string(),
836
+ latitude: z.number().nullable(),
837
+ longitude: z.number().nullable(),
838
+ isDefault: z.boolean()
839
+ });
840
+ var CustomerAddressUpsertSchema = CustomerAddressSchema.omit({ id: true });
841
+ var CustomerMeSchema = z.object({
842
+ id: z.string(),
843
+ storeId: z.string(),
844
+ email: z.string().email(),
845
+ firstName: z.string(),
846
+ lastName: z.string(),
847
+ phone: z.string(),
848
+ identificationNumber: z.string().nullable(),
849
+ identificationType: z.string().nullable(),
850
+ entityName: z.string().nullable(),
851
+ dateOfBirth: z.string().nullable(),
852
+ gender: z.string().nullable(),
853
+ countryIsoCode: z.string(),
854
+ role: z.string().nullable(),
855
+ companyName: z.string().nullable(),
856
+ consent: z.boolean(),
857
+ userId: z.string(),
858
+ customerType: z.string(),
859
+ status: z.string(),
860
+ entityIdentificationNumber: z.string().nullable(),
861
+ defaultAddressId: z.string().nullable(),
862
+ metadata: z.unknown().nullable(),
863
+ totalOrders: z.number(),
864
+ avgOrders: z.number(),
865
+ lastOrderId: z.string().nullable(),
866
+ lastOrderDate: z.string().nullable(),
867
+ loyaltyPoints: z.number(),
868
+ addresses: z.array(CustomerAddressSchema),
869
+ createdOn: z.string(),
870
+ updatedOn: z.string().nullable()
871
+ });
872
+ var CustomerProfilePatchSchema = z.object({
873
+ firstName: z.string().trim().min(1),
874
+ lastName: z.string().trim().min(1),
875
+ phone: z.string().trim(),
876
+ identificationNumber: z.string().nullable(),
877
+ identificationType: z.string().nullable(),
878
+ entityName: z.string().nullable(),
879
+ entityIdentificationNumber: z.string().nullable(),
880
+ gender: z.string().nullable(),
881
+ role: z.string().nullable(),
882
+ companyName: z.string().nullable(),
883
+ dateOfBirth: z.string().nullable(),
884
+ consent: z.boolean(),
885
+ countryIsoCode: z.string().trim().length(2)
886
+ });
887
+ function customerMeToProfilePatch(me) {
888
+ return {
889
+ firstName: me.firstName,
890
+ lastName: me.lastName,
891
+ phone: me.phone ?? "",
892
+ identificationNumber: me.identificationNumber,
893
+ identificationType: me.identificationType,
894
+ entityName: me.entityName,
895
+ entityIdentificationNumber: me.entityIdentificationNumber,
896
+ gender: me.gender,
897
+ role: me.role,
898
+ companyName: me.companyName,
899
+ dateOfBirth: me.dateOfBirth,
900
+ consent: me.consent,
901
+ countryIsoCode: me.countryIsoCode || "PE"
902
+ };
903
+ }
904
+ function customerAuthOptions(accessToken) {
905
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
906
+ return token ? { bearerToken: token } : {};
907
+ }
908
+ async function registerCustomer(data) {
909
+ const payload = CustomerRegisterRequestSchema.parse(data);
910
+ const client = await getStoreApiClient();
911
+ return client.post("customer/register", payload);
912
+ }
913
+ async function getCustomerAddresses(accessToken) {
914
+ const client = await getStoreApiClient();
915
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
916
+ const response = await client.get("customer/addresses", {
917
+ ...token ? { bearerToken: token } : {}
918
+ });
919
+ return z.array(CustomerAddressSchema).parse(response);
920
+ }
921
+ async function createCustomerAddress(data, accessToken) {
922
+ const client = await getStoreApiClient();
923
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
924
+ const payload = CustomerAddressUpsertSchema.parse(data);
925
+ return client.post("customer/addresses", payload, {
926
+ ...token ? { bearerToken: token } : {}
927
+ });
928
+ }
929
+ async function updateCustomerAddress(addressId, data, accessToken) {
930
+ const client = await getStoreApiClient();
931
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
932
+ const payload = CustomerAddressUpsertSchema.parse(data);
933
+ const id = addressId.trim();
934
+ if (!id) throw new Error("addressId requerido");
935
+ return client.put(`customer/addresses/${encodeURIComponent(id)}`, payload, {
936
+ ...token ? { bearerToken: token } : {}
937
+ });
938
+ }
939
+ async function deleteCustomerAddress(addressId, accessToken) {
940
+ const client = await getStoreApiClient();
941
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
942
+ const id = addressId.trim();
943
+ if (!id) throw new Error("addressId requerido");
944
+ return client.delete(`customer/addresses/${encodeURIComponent(id)}`, {
945
+ ...token ? { bearerToken: token } : {}
946
+ });
947
+ }
948
+ async function getCustomerMe(accessToken) {
949
+ const client = await getStoreApiClient();
950
+ const response = await client.get("customer", customerAuthOptions(accessToken));
951
+ return CustomerMeSchema.parse(response);
952
+ }
953
+ async function patchCustomer(data, accessToken) {
954
+ const client = await getStoreApiClient();
955
+ const payload = CustomerProfilePatchSchema.parse(data);
956
+ await client.patch("customer", payload, customerAuthOptions(accessToken));
957
+ }
958
+ var CustomerOrderShippingAddressSchema = z.object({
959
+ name: z.string().nullable().optional(),
960
+ company: z.string().nullable().optional(),
961
+ address1: z.string(),
962
+ address2: z.string().nullable().optional(),
963
+ city: z.string().nullable().optional(),
964
+ countryCode: z.string(),
965
+ province: z.string().nullable().optional(),
966
+ postalCode: z.string().nullable().optional(),
967
+ district: z.string().nullable().optional(),
968
+ phone: z.string().nullable().optional(),
969
+ latitude: z.number().nullable().optional(),
970
+ longitude: z.number().nullable().optional(),
971
+ metadata: z.record(z.unknown()).nullable().optional()
972
+ }).passthrough();
973
+ var CustomerOrderLineItemSchema = z.object({
974
+ id: z.string(),
975
+ orderId: z.coerce.string(),
976
+ productId: z.coerce.string().nullable(),
977
+ variantId: z.coerce.string().nullable(),
978
+ title: z.string(),
979
+ subtitle: z.string().nullable().optional(),
980
+ thumbnail: z.string().nullable().optional(),
981
+ variantTitle: z.string().nullable().optional(),
982
+ productHandle: z.string().nullable().optional(),
983
+ quantity: z.number(),
984
+ unitPrice: z.number(),
985
+ total: z.number(),
986
+ status: z.string()
987
+ });
988
+ var CustomerOrderListItemSchema = z.object({
989
+ orderId: z.coerce.string(),
990
+ orderNumber: z.string(),
991
+ orderGroup: z.string(),
992
+ orderIds: z.array(z.coerce.string()),
993
+ status: z.string(),
994
+ total: z.number(),
995
+ totalPaid: z.number(),
996
+ currencyCode: z.string(),
997
+ orderDate: z.string(),
998
+ createdOn: z.string(),
999
+ updatedOn: z.string().nullable().optional(),
1000
+ paymentAt: z.string().nullable().optional(),
1001
+ shippingAddress: CustomerOrderShippingAddressSchema.nullable().optional(),
1002
+ shippingAddressSummary: z.string().nullable().optional(),
1003
+ items: z.array(CustomerOrderLineItemSchema)
1004
+ });
1005
+ var CustomerOrderPaymentSchema = z.object({
1006
+ id: z.string(),
1007
+ paymentMethod: z.string(),
1008
+ paymentCode: z.string(),
1009
+ amount: z.number(),
1010
+ paymentStatus: z.string(),
1011
+ receiptUrl: z.string().nullable().optional(),
1012
+ createdOn: z.string()
1013
+ });
1014
+ var CustomerOrderStatusTimelineSchema = z.object({
1015
+ key: z.string(),
1016
+ label: z.string(),
1017
+ occurredAt: z.string(),
1018
+ description: z.string().nullable().optional(),
1019
+ status: z.string(),
1020
+ source: z.string()
1021
+ });
1022
+ var CustomerOrderDetailSchema = z.object({
1023
+ id: z.coerce.string(),
1024
+ orderNumber: z.string(),
1025
+ orderGroup: z.string(),
1026
+ status: z.string(),
1027
+ total: z.number(),
1028
+ totalPaid: z.number(),
1029
+ currencyCode: z.string(),
1030
+ orderDate: z.string(),
1031
+ createdOn: z.string(),
1032
+ updatedOn: z.string().nullable().optional(),
1033
+ paymentAt: z.string().nullable().optional(),
1034
+ subTotal: z.number(),
1035
+ discount: z.number(),
1036
+ shipping: z.number(),
1037
+ tax: z.number(),
1038
+ email: z.string(),
1039
+ phone: z.string(),
1040
+ firstName: z.string(),
1041
+ lastName: z.string(),
1042
+ shippingAddress: CustomerOrderShippingAddressSchema.nullable().optional(),
1043
+ shippingAddressSummary: z.string().nullable().optional(),
1044
+ billingAddress: CustomerOrderShippingAddressSchema.nullable().optional(),
1045
+ items: z.array(CustomerOrderLineItemSchema),
1046
+ payments: z.array(CustomerOrderPaymentSchema),
1047
+ statusTimeline: z.array(CustomerOrderStatusTimelineSchema)
1048
+ });
1049
+ function authOptions(accessToken) {
1050
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
1051
+ return token ? { bearerToken: token } : {};
1052
+ }
1053
+ async function getCustomerOrders(accessToken) {
1054
+ const client = await getStoreApiClient();
1055
+ const response = await client.get("customer/orders", authOptions(accessToken));
1056
+ return z.array(CustomerOrderListItemSchema).parse(response);
1057
+ }
1058
+ async function getCustomerOrder(orderId, accessToken) {
1059
+ const client = await getStoreApiClient();
1060
+ const id = orderId.trim();
1061
+ if (!id) throw new Error("orderId requerido");
1062
+ const response = await client.get(
1063
+ `customer/orders/${encodeURIComponent(id)}`,
1064
+ authOptions(accessToken)
1065
+ );
1066
+ return CustomerOrderDetailSchema.parse(response);
1067
+ }
1068
+ var StorefrontOrderAddressSchema = z.object({
1069
+ address1: z.string().optional(),
1070
+ address2: z.string().optional(),
1071
+ city: z.string().optional(),
1072
+ province: z.string().optional(),
1073
+ country: z.string().optional(),
1074
+ zip: z.string().optional(),
1075
+ phone: z.string().optional(),
1076
+ firstName: z.string().optional(),
1077
+ lastName: z.string().optional()
1078
+ }).passthrough();
1079
+ var OrderDraftItemSchema = z.object({
1080
+ id: z.string(),
1081
+ productId: z.coerce.string().nullable().optional(),
1082
+ sellerId: z.string().nullable().optional(),
1083
+ shippingProfileId: z.string().nullable().optional(),
1084
+ variantId: z.coerce.string().nullable().optional(),
1085
+ title: z.string(),
1086
+ subtitle: z.string().nullable().optional(),
1087
+ thumbnail: z.string().nullable().optional(),
1088
+ quantity: z.number().optional().default(1),
1089
+ unitPrice: z.number().optional().default(0),
1090
+ subTotal: z.number().optional().default(0),
1091
+ discount: z.number().optional().default(0),
1092
+ shipping: z.number().optional().default(0),
1093
+ tax: z.number().optional().default(0),
1094
+ warranty: z.number().optional().default(0),
1095
+ total: z.number().optional().default(0),
1096
+ requiresShipping: z.boolean().optional().default(true),
1097
+ isTaxInclusive: z.boolean().optional().default(true),
1098
+ metadata: z.record(z.unknown()).optional().default({})
1099
+ });
1100
+ var OrderDraftShippingMethodSchema = z.object({
1101
+ id: z.string(),
1102
+ name: z.string().optional().default(""),
1103
+ description: z.string().nullable().optional(),
1104
+ subtotal: z.number().optional().default(0),
1105
+ discountTotal: z.number().optional().default(0),
1106
+ taxTotal: z.number().optional().default(0),
1107
+ total: z.number().optional().default(0),
1108
+ isTaxInclusive: z.boolean().optional().default(true),
1109
+ sellerId: z.string().nullable().optional(),
1110
+ shippingProfileId: z.string().nullable().optional(),
1111
+ shippingMethodId: z.string().nullable().optional(),
1112
+ connectionId: z.string().nullable().optional(),
1113
+ providerName: z.string().nullable().optional(),
1114
+ trackingCode: z.string().nullable().optional(),
1115
+ estimatedDays: z.number().nullable().optional(),
1116
+ zoneCode: z.string().nullable().optional(),
1117
+ locationId: z.string().nullable().optional(),
1118
+ pickupPointId: z.string().nullable().optional(),
1119
+ scheduledDate: z.string().nullable().optional(),
1120
+ scheduledTime: z.string().nullable().optional(),
1121
+ data: z.record(z.unknown()).optional().default({})
1122
+ });
1123
+ var OrderDraftSchema = z.object({
1124
+ id: z.string(),
1125
+ storeId: z.string().optional(),
1126
+ customerId: z.coerce.string().nullable().optional(),
1127
+ cartId: z.string().nullable().optional(),
1128
+ draftNumber: z.string(),
1129
+ currencyCode: z.string().optional().default("PEN"),
1130
+ source: z.string().nullable().optional(),
1131
+ notes: z.string().nullable().optional(),
1132
+ email: z.string().nullable().optional(),
1133
+ phone: z.string().nullable().optional(),
1134
+ firstName: z.string().nullable().optional(),
1135
+ lastName: z.string().nullable().optional(),
1136
+ identificationType: z.string().nullable().optional(),
1137
+ identificationNumber: z.string().nullable().optional(),
1138
+ entityTaxId: z.string().nullable().optional(),
1139
+ entityName: z.string().nullable().optional(),
1140
+ status: z.string(),
1141
+ draftDate: z.string().nullable().optional(),
1142
+ sentAt: z.string().nullable().optional(),
1143
+ viewedAt: z.string().nullable().optional(),
1144
+ acceptedAt: z.string().nullable().optional(),
1145
+ rejectedAt: z.string().nullable().optional(),
1146
+ expiredAt: z.string().nullable().optional(),
1147
+ cancelledAt: z.string().nullable().optional(),
1148
+ convertedAt: z.string().nullable().optional(),
1149
+ shareToken: z.string().nullable().optional(),
1150
+ shareExpiresAt: z.string().nullable().optional(),
1151
+ allowAnonymousShareAccess: z.boolean().optional().default(false),
1152
+ sharedAt: z.string().nullable().optional(),
1153
+ billingAddress: StorefrontOrderAddressSchema.optional().nullable(),
1154
+ shippingAddress: StorefrontOrderAddressSchema.optional().nullable(),
1155
+ metadata: z.record(z.unknown()).optional().default({}),
1156
+ subTotal: z.number().optional().default(0),
1157
+ discount: z.number().optional().default(0),
1158
+ shipping: z.number().optional().default(0),
1159
+ tax: z.number().optional().default(0),
1160
+ warranty: z.number().optional().default(0),
1161
+ total: z.number().optional().default(0),
1162
+ paymentMethod: z.string().optional().default(""),
1163
+ paymentCode: z.string().optional().default(""),
1164
+ items: z.array(OrderDraftItemSchema).optional().default([]),
1165
+ shippingMethods: z.array(OrderDraftShippingMethodSchema).optional().default([]),
1166
+ createdOn: z.string().optional(),
1167
+ updatedOn: z.string().nullable().optional()
1168
+ });
1169
+
1170
+ // src/core/client/store-api-order-draft.service.ts
1171
+ async function getSharedOrderDraft(shareToken) {
1172
+ const client = await getStoreApiClient();
1173
+ const response = await client.get(
1174
+ `order-drafts/share/${encodeURIComponent(shareToken)}`,
1175
+ { noStore: true }
1176
+ );
1177
+ return OrderDraftSchema.parse(response);
1178
+ }
1179
+ var defaultOptions = {
1180
+ queries: {
1181
+ staleTime: 60 * 1e3
1182
+ }
1183
+ };
1184
+ function QueryProvider({ children, dehydratedState }) {
1185
+ const queryClientRef = useRef(null);
1186
+ const hydratedRef = useRef(false);
1187
+ if (queryClientRef.current === null) {
1188
+ queryClientRef.current = new QueryClient({ defaultOptions });
1189
+ }
1190
+ const queryClient = queryClientRef.current;
1191
+ useEffect(() => {
1192
+ if (dehydratedState && !hydratedRef.current) {
1193
+ hydrate(queryClient, dehydratedState);
1194
+ hydratedRef.current = true;
1195
+ }
1196
+ }, [queryClient, dehydratedState]);
1197
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children });
1198
+ }
1199
+ var StorefrontAuthContext = createContext(null);
1200
+ function StorefrontAuthProvider({
1201
+ authClient,
1202
+ children
1203
+ }) {
1204
+ return /* @__PURE__ */ jsx(StorefrontAuthContext.Provider, { value: authClient, children });
1205
+ }
1206
+ function useStorefrontAuthClient() {
1207
+ const client = useContext(StorefrontAuthContext);
1208
+ if (!client) {
1209
+ throw new Error(
1210
+ "useStorefrontAuthClient debe usarse dentro de StorefrontAuthProvider (o EcomiqProvider con authClient)."
1211
+ );
1212
+ }
1213
+ return client;
1214
+ }
1215
+ function storefrontSessionEndsSoon(expiresAt, skewMs = 12e4) {
1216
+ if (!expiresAt) return false;
1217
+ return Date.now() + skewMs >= expiresAt.getTime();
1218
+ }
1219
+ var storefrontAccessTokenNeedsRefresh = storefrontSessionEndsSoon;
1220
+ function parseStorefrontSessionExpires(at) {
1221
+ if (!at) return void 0;
1222
+ if (at instanceof Date) return Number.isNaN(at.getTime()) ? void 0 : at;
1223
+ if (typeof at === "string") {
1224
+ const d = new Date(at);
1225
+ return Number.isNaN(d.getTime()) ? void 0 : d;
1226
+ }
1227
+ return void 0;
1228
+ }
1229
+ function mapSessionUser(raw) {
1230
+ if (!raw || typeof raw !== "object") return null;
1231
+ const u = raw;
1232
+ const explicitFirst = typeof u.firstName === "string" ? u.firstName : typeof u.given_name === "string" ? u.given_name : "";
1233
+ const explicitLast = typeof u.lastName === "string" ? u.lastName : typeof u.family_name === "string" ? u.family_name : "";
1234
+ if (explicitFirst || explicitLast) {
1235
+ return {
1236
+ id: String(u.id ?? ""),
1237
+ email: String(u.email ?? ""),
1238
+ firstName: explicitFirst,
1239
+ lastName: explicitLast,
1240
+ name: typeof u.name === "string" ? u.name : void 0,
1241
+ phone: typeof u.phone === "string" ? u.phone : void 0
1242
+ };
1243
+ }
1244
+ const emailLocal = String(u.email ?? "").split("@")[0] ?? "";
1245
+ const full = typeof u.name === "string" ? u.name.trim() : emailLocal.trim();
1246
+ const parts = full ? full.split(/\s+/) : [];
1247
+ return {
1248
+ id: String(u.id ?? ""),
1249
+ email: String(u.email ?? ""),
1250
+ firstName: parts[0] ?? "",
1251
+ lastName: parts.slice(1).join(" "),
1252
+ name: typeof u.name === "string" ? u.name : void 0,
1253
+ phone: typeof u.phone === "string" ? u.phone : void 0
1254
+ };
1255
+ }
1256
+ function useStorefrontSession() {
1257
+ const authClient = useStorefrontAuthClient();
1258
+ const session = authClient.useSession();
1259
+ const user = mapSessionUser(session.data?.user);
1260
+ const storefrontSession = session.data?.session;
1261
+ const sessionExpiresAt = parseStorefrontSessionExpires(storefrontSession?.expiresAt);
1262
+ return {
1263
+ session,
1264
+ user,
1265
+ sessionExpiresAt,
1266
+ isAuthenticated: Boolean(session.data?.user),
1267
+ isPending: session.isPending,
1268
+ error: session.error,
1269
+ refetch: session.refetch,
1270
+ signOut: () => authClient.signOut()
1271
+ };
1272
+ }
1273
+ function useStoreProducts() {
1274
+ const useStorefrontProductsList = (params) => {
1275
+ return useQuery({
1276
+ queryKey: ["storefront", "products", params],
1277
+ queryFn: () => getStorefrontProducts(params)
1278
+ });
1279
+ };
1280
+ const useStorefrontInfiniteProducts = (params) => {
1281
+ return useInfiniteQuery({
1282
+ queryKey: ["storefront", "products", "infinite", params],
1283
+ queryFn: ({ pageParam = 1 }) => getStorefrontProducts({ ...params, page: pageParam }),
1284
+ getNextPageParam: (lastPage) => lastPage.pageIndex < lastPage.totalPages ? lastPage.pageIndex + 1 : void 0,
1285
+ initialPageParam: 1
1286
+ });
1287
+ };
1288
+ const useProductBySlug = (slug) => {
1289
+ return useQuery({
1290
+ queryKey: ["storefront", "product", "slug", slug],
1291
+ queryFn: () => getStorefrontProductBySlug(slug),
1292
+ enabled: !!slug
1293
+ });
1294
+ };
1295
+ const useRefreshStorefrontProducts = () => {
1296
+ const queryClient = useQueryClient();
1297
+ return useMutation({
1298
+ mutationFn: (params) => getStorefrontProducts(params),
1299
+ onSuccess: () => {
1300
+ queryClient.invalidateQueries({ queryKey: ["storefront", "products"] });
1301
+ }
1302
+ });
1303
+ };
1304
+ return {
1305
+ useStorefrontProductsList,
1306
+ useStorefrontInfiniteProducts,
1307
+ useProductBySlug,
1308
+ useRefreshStorefrontProducts
1309
+ };
1310
+ }
1311
+ function useStoreCollections() {
1312
+ const useStorefrontCollectionsList = () => {
1313
+ return useQuery({
1314
+ queryKey: ["storefront", "collections"],
1315
+ queryFn: () => getStorefrontCollections()
1316
+ });
1317
+ };
1318
+ const useCollectionBySlug = (slug) => {
1319
+ return useQuery({
1320
+ queryKey: ["storefront", "collection", "slug", slug],
1321
+ queryFn: () => getStorefrontCollectionBySlug(slug),
1322
+ enabled: !!slug
1323
+ });
1324
+ };
1325
+ const useRefreshStorefrontCollections = () => {
1326
+ const queryClient = useQueryClient();
1327
+ return useMutation({
1328
+ mutationFn: () => getStorefrontCollections(),
1329
+ onSuccess: () => {
1330
+ queryClient.invalidateQueries({ queryKey: ["storefront", "collections"] });
1331
+ }
1332
+ });
1333
+ };
1334
+ return {
1335
+ useStorefrontCollectionsList,
1336
+ useCollectionBySlug,
1337
+ useRefreshStorefrontCollections
1338
+ };
1339
+ }
1340
+ function useStorePages() {
1341
+ const useStorefrontPagesList = () => {
1342
+ return useQuery({
1343
+ queryKey: ["storefront", "pages"],
1344
+ queryFn: () => getStorefrontPages()
1345
+ });
1346
+ };
1347
+ const usePageBySlug = (slug) => {
1348
+ return useQuery({
1349
+ queryKey: ["storefront", "page", "slug", slug],
1350
+ queryFn: () => getStorefrontPageBySlug(slug),
1351
+ enabled: !!slug
1352
+ });
1353
+ };
1354
+ const useRefreshStorefrontPages = () => {
1355
+ const queryClient = useQueryClient();
1356
+ return useMutation({
1357
+ mutationFn: () => getStorefrontPages(),
1358
+ onSuccess: () => {
1359
+ queryClient.invalidateQueries({ queryKey: ["storefront", "pages"] });
1360
+ }
1361
+ });
1362
+ };
1363
+ return {
1364
+ useStorefrontPagesList,
1365
+ usePageBySlug,
1366
+ useRefreshStorefrontPages
1367
+ };
1368
+ }
1369
+ var useCart = create()(
1370
+ persist(
1371
+ (set) => ({
1372
+ count: 0,
1373
+ cart: [],
1374
+ cartTokenId: null,
1375
+ setCartTokenId: (token) => set((state) => ({ ...state, cartTokenId: token })),
1376
+ checkoutStep: null,
1377
+ setCheckoutStep: (step) => set((state) => ({ ...state, checkoutStep: step })),
1378
+ checkoutCustomerLocal: null,
1379
+ setCheckoutCustomerLocal: (customer) => set((state) => {
1380
+ if (!state.cartTokenId) return state;
1381
+ return {
1382
+ checkoutCustomerLocal: {
1383
+ cartTokenId: state.cartTokenId,
1384
+ customer
1385
+ }
1386
+ };
1387
+ }),
1388
+ clearCheckoutCustomerLocal: () => set(() => ({ checkoutCustomerLocal: null })),
1389
+ addCart: (item) => set((state) => {
1390
+ const existingItem = state.cart.find(
1391
+ (cartItem) => cartItem.id === item.id
1392
+ );
1393
+ if (existingItem) {
1394
+ const newQuantity = Math.max(0, existingItem.quantity) + 1;
1395
+ const cart2 = state.cart.map(
1396
+ (cartItem) => cartItem.id === item.id ? { ...cartItem, quantity: newQuantity } : cartItem
1397
+ );
1398
+ const count2 = cart2.reduce((sum, i) => sum + Math.max(0, i.quantity), 0);
1399
+ return { count: count2, cart: cart2 };
1400
+ }
1401
+ const newItem = {
1402
+ ...item,
1403
+ quantity: Math.max(1, Math.max(0, item.quantity ?? 1))
1404
+ };
1405
+ const cart = [...state.cart, newItem];
1406
+ const count = cart.reduce((sum, i) => sum + Math.max(0, i.quantity), 0);
1407
+ return { count, cart };
1408
+ }),
1409
+ removeCart: (id) => set((state) => {
1410
+ const existingItem = state.cart.find((item) => item.id === id);
1411
+ if (!existingItem) return state;
1412
+ if (existingItem.quantity > 1) {
1413
+ const newQuantity = Math.max(0, existingItem.quantity - 1);
1414
+ const cart2 = state.cart.map(
1415
+ (cartItem) => cartItem.id === id ? { ...cartItem, quantity: newQuantity } : cartItem
1416
+ );
1417
+ const count2 = cart2.reduce((sum, i) => sum + Math.max(0, i.quantity), 0);
1418
+ return { count: count2, cart: cart2 };
1419
+ }
1420
+ const cart = state.cart.filter((item) => item.id !== id);
1421
+ const count = Math.max(0, cart.reduce((sum, i) => sum + Math.max(0, i.quantity), 0));
1422
+ return { count, cart };
1423
+ }),
1424
+ clearCartSession: () => set(() => ({
1425
+ count: 0,
1426
+ cart: [],
1427
+ cartTokenId: null,
1428
+ checkoutStep: null,
1429
+ checkoutCustomerLocal: null
1430
+ }))
1431
+ }),
1432
+ { name: "cart-storage" }
1433
+ )
1434
+ );
1435
+
1436
+ // src/react/shell/hooks/use-store-cart.ts
1437
+ function useStoreCart() {
1438
+ const useGetCart = (cartId) => useQuery({
1439
+ queryKey: ["storefront", "cart", cartId ?? null],
1440
+ queryFn: () => getCart(cartId ?? void 0),
1441
+ // Si devuelve 404 no reintentar; para otros errores solo un intento adicional como máximo.
1442
+ retry: (failureCount, error) => {
1443
+ const status = error.status;
1444
+ if (status === 404) return false;
1445
+ return failureCount < 1;
1446
+ },
1447
+ // Evitar refetch automático al enfocar la ventana; el carrito se carga una sola vez aquí.
1448
+ refetchOnWindowFocus: false,
1449
+ enabled: !!cartId
1450
+ });
1451
+ const useCreateCart = () => useMutation({
1452
+ mutationFn: (data) => createCart(data)
1453
+ });
1454
+ const useUpdateCartBuyer = () => useMutation({
1455
+ mutationFn: ({ data, cartId }) => patchCartBuyer(data, cartId)
1456
+ });
1457
+ const useUpdateCartAddresses = () => useMutation({
1458
+ mutationFn: ({ data, cartId }) => patchCartAddresses(data, cartId)
1459
+ });
1460
+ const useAddCartItem = () => useMutation({
1461
+ mutationFn: ({ cartId, ...data }) => addCartItem(data, cartId)
1462
+ });
1463
+ const useCheckoutCart = () => useMutation({
1464
+ mutationFn: ({ data, cartId }) => checkoutCart(data, cartId)
1465
+ });
1466
+ const useUploadPaymentReceipt = () => useMutation({
1467
+ mutationFn: ({ cartId, file }) => uploadPaymentReceipt(cartId, file)
1468
+ });
1469
+ const useGetCartCheckout = (cartId) => {
1470
+ const inactiveHandledRef = useRef(null);
1471
+ const query = useQuery({
1472
+ queryKey: ["storefront", "cart", cartId ?? null, "checkout"],
1473
+ queryFn: () => getCartCheckout(cartId),
1474
+ retry: (failureCount, error) => {
1475
+ const status = error.status;
1476
+ if (status === 404) return false;
1477
+ if (status === 400 && isCartNotActiveApiError(error)) return false;
1478
+ return failureCount < 1;
1479
+ },
1480
+ /** Evita GET repetidos al cambiar de paso / re-render; `refetch()` sigue forzando actualización tras mutaciones. */
1481
+ staleTime: 6e4,
1482
+ refetchOnMount: false,
1483
+ refetchOnReconnect: false,
1484
+ refetchOnWindowFocus: false,
1485
+ enabled: !!cartId
1486
+ });
1487
+ useEffect(() => {
1488
+ inactiveHandledRef.current = null;
1489
+ }, [cartId]);
1490
+ useEffect(() => {
1491
+ if (!cartId) return;
1492
+ if (!query.isError || !query.error) return;
1493
+ if (!isCartNotActiveApiError(query.error)) return;
1494
+ if (inactiveHandledRef.current === cartId) return;
1495
+ inactiveHandledRef.current = cartId;
1496
+ toast.error(
1497
+ "Este carrito ya no est\xE1 disponible. Se ha vaciado tu bolsa para que puedas empezar de nuevo."
1498
+ );
1499
+ useCart.getState().clearCartSession();
1500
+ }, [cartId, query.isError, query.error]);
1501
+ return query;
1502
+ };
1503
+ const useGetCartPaymentMethods = (cartId) => useQuery({
1504
+ queryKey: ["storefront", "cart", cartId ?? null, "payment-methods"],
1505
+ queryFn: () => getCartPaymentMethods(cartId ?? void 0),
1506
+ retry: (failureCount, error) => {
1507
+ const status = error.status;
1508
+ if (status === 404) return false;
1509
+ return failureCount < 1;
1510
+ },
1511
+ refetchOnWindowFocus: false,
1512
+ enabled: !!cartId
1513
+ });
1514
+ const useGetShippingOptions = (cartId, postalCode, enabled) => useQuery({
1515
+ queryKey: [
1516
+ "storefront",
1517
+ "cart",
1518
+ cartId ?? null,
1519
+ "shipping-options",
1520
+ postalCode ?? ""
1521
+ ],
1522
+ queryFn: () => getShippingOptions(cartId, postalCode),
1523
+ retry: (failureCount, error) => {
1524
+ const status = error.status;
1525
+ if (status === 404) return false;
1526
+ return failureCount < 1;
1527
+ },
1528
+ refetchOnWindowFocus: false,
1529
+ enabled: !!cartId && !!postalCode?.trim() && enabled
1530
+ });
1531
+ const usePutCartShippingMethod = () => useMutation({
1532
+ mutationFn: ({ cartId, data }) => putCartShippingMethod(cartId, data)
1533
+ });
1534
+ const useAddCartCoupon = () => useMutation({
1535
+ mutationFn: ({ cartId, data }) => addCartCoupon(cartId, data)
1536
+ });
1537
+ const useRemoveCartCoupon = () => useMutation({
1538
+ mutationFn: ({ cartId, code }) => removeCartCoupon(cartId, code)
1539
+ });
1540
+ return {
1541
+ useCreateCart,
1542
+ useGetCart,
1543
+ useGetCartCheckout,
1544
+ useUpdateCartBuyer,
1545
+ useUpdateCartAddresses,
1546
+ useAddCartItem,
1547
+ useCheckoutCart,
1548
+ useUploadPaymentReceipt,
1549
+ useGetCartPaymentMethods,
1550
+ useGetShippingOptions,
1551
+ usePutCartShippingMethod,
1552
+ useAddCartCoupon,
1553
+ useRemoveCartCoupon
1554
+ };
1555
+ }
1556
+ var useStore = create()(
1557
+ (set) => ({
1558
+ data: null,
1559
+ drawers: {
1560
+ cart: false,
1561
+ search: false,
1562
+ menu: false,
1563
+ filter: false
1564
+ },
1565
+ openDrawer: (drawer) => set((state) => ({
1566
+ drawers: {
1567
+ ...state.drawers,
1568
+ [drawer]: true
1569
+ }
1570
+ })),
1571
+ closeDrawer: (drawer) => set((state) => ({
1572
+ drawers: {
1573
+ ...state.drawers,
1574
+ [drawer]: false
1575
+ }
1576
+ })),
1577
+ toggleDrawer: (drawer) => set((state) => ({
1578
+ drawers: {
1579
+ ...state.drawers,
1580
+ [drawer]: !state.drawers[drawer]
1581
+ }
1582
+ })),
1583
+ closeAllDrawers: () => set((state) => ({
1584
+ drawers: Object.keys(state.drawers).reduce(
1585
+ (acc, key) => ({ ...acc, [key]: false }),
1586
+ {}
1587
+ )
1588
+ })),
1589
+ modals: {
1590
+ login: false,
1591
+ signup: false
1592
+ },
1593
+ openModal: (modal) => set((state) => ({
1594
+ modals: {
1595
+ ...state.modals,
1596
+ login: false,
1597
+ signup: false,
1598
+ [modal]: true
1599
+ }
1600
+ })),
1601
+ closeModal: (modal) => set((state) => ({
1602
+ modals: {
1603
+ ...state.modals,
1604
+ login: false,
1605
+ signup: false,
1606
+ [modal]: false
1607
+ }
1608
+ })),
1609
+ toggleModal: (modal) => set((state) => ({
1610
+ modals: {
1611
+ ...state.modals,
1612
+ [modal]: !state.modals[modal]
1613
+ }
1614
+ })),
1615
+ closeAllModals: () => set((state) => ({
1616
+ modals: Object.keys(state.modals).reduce(
1617
+ (acc, key) => ({ ...acc, [key]: false }),
1618
+ {}
1619
+ )
1620
+ }))
1621
+ })
1622
+ );
1623
+ function EcomiqProvider({
1624
+ store,
1625
+ authClient,
1626
+ children,
1627
+ withShellUi = false
1628
+ }) {
1629
+ useStore.setState({ data: store ?? null });
1630
+ useEffect(() => {
1631
+ setClientStoreId(store?.store.id ?? null);
1632
+ return () => setClientStoreId(null);
1633
+ }, [store]);
1634
+ const [queryClient] = useState(() => new QueryClient());
1635
+ const tree = /* @__PURE__ */ jsxs(QueryClientProvider, { client: queryClient, children: [
1636
+ children,
1637
+ withShellUi ? /* @__PURE__ */ jsx(EcomiqShellUi, {}) : null
1638
+ ] });
1639
+ if (!authClient) return tree;
1640
+ return /* @__PURE__ */ jsx(StorefrontAuthProvider, { authClient, children: tree });
1641
+ }
1642
+ function EcomiqShellUi() {
1643
+ const [ui, setUi] = useState(null);
1644
+ useEffect(() => {
1645
+ void import('../ecomiq-shell-ui-SWIFLQVM.js').then((mod) => setUi(() => mod.EcomiqShellUi));
1646
+ }, []);
1647
+ return ui ? React2.createElement(ui) : null;
1648
+ }
1649
+
1650
+ // src/react/auth/ecomiq-oauth-password-constants.ts
1651
+ var PLUGIN_ID = "ecomiq-oauth-password";
1652
+
1653
+ // src/react/auth/ecomiq-oauth-password-client.ts
1654
+ function ecomiqOAuthPasswordClient() {
1655
+ return {
1656
+ id: PLUGIN_ID,
1657
+ pathMethods: {
1658
+ "/ecomiq-oauth/sign-in": "POST"
1659
+ },
1660
+ atomListeners: [
1661
+ {
1662
+ matcher: (path) => path === "/ecomiq-oauth/sign-in",
1663
+ signal: "$sessionSignal"
1664
+ }
1665
+ ]
1666
+ };
1667
+ }
1668
+ var StorefrontCheckoutSettingsSchema = z.object({
1669
+ allowGuestCheckout: z.boolean().optional(),
1670
+ identityScope: z.enum(["store", "tenant", "global"]).optional(),
1671
+ signInMethods: z.array(z.string()).optional()
1672
+ });
1673
+ var looseRecord = z.record(z.string(), z.unknown());
1674
+ var StorefrontThemeConfigSchema = z.object({
1675
+ name: z.string().nullable().optional(),
1676
+ mode: z.string().nullable().optional(),
1677
+ colors: looseRecord.optional(),
1678
+ fonts: looseRecord.optional(),
1679
+ assets: looseRecord.optional()
1680
+ }).passthrough();
1681
+ var StorefrontFeaturesEnabledSchema = z.object({
1682
+ flags: looseRecord.optional()
1683
+ }).passthrough();
1684
+ var StorefrontCmsBrandingSchema = z.object({
1685
+ logoUrl: z.string().nullable().optional(),
1686
+ logoDarkUrl: z.string().nullable().optional(),
1687
+ faviconUrl: z.string().nullable().optional(),
1688
+ socialImageUrl: z.string().nullable().optional()
1689
+ });
1690
+ var StorefrontCmsSeoSchema = z.object({
1691
+ siteName: z.string().nullable().optional(),
1692
+ metaTitle: z.string().nullable().optional(),
1693
+ metaDescription: z.string().nullable().optional(),
1694
+ titleTemplate: z.string().nullable().optional(),
1695
+ robotsIndex: z.boolean().optional()
1696
+ });
1697
+ var StorefrontCmsSocialLinksSchema = z.object({
1698
+ instagram: z.string().nullable().optional(),
1699
+ facebook: z.string().nullable().optional(),
1700
+ tiktok: z.string().nullable().optional(),
1701
+ youtube: z.string().nullable().optional(),
1702
+ x: z.string().nullable().optional()
1703
+ });
1704
+ var StorefrontCmsContactSchema = z.object({
1705
+ supportEmail: z.string().nullable().optional(),
1706
+ phone: z.string().nullable().optional(),
1707
+ whatsapp: z.string().nullable().optional(),
1708
+ address: z.string().nullable().optional(),
1709
+ socialLinks: StorefrontCmsSocialLinksSchema.optional()
1710
+ });
1711
+ var StorefrontCmsTrackingSchema = z.object({
1712
+ googleAnalyticsMeasurementId: z.string().nullable().optional(),
1713
+ metaPixelId: z.string().nullable().optional(),
1714
+ googleTagManagerContainerId: z.string().nullable().optional()
1715
+ });
1716
+ var StorefrontCmsCustomScriptsSchema = z.object({
1717
+ enabled: z.boolean().optional(),
1718
+ head: z.string().nullable().optional(),
1719
+ bodyEnd: z.string().nullable().optional()
1720
+ });
1721
+ var StorefrontCmsSettingsSchema = z.object({
1722
+ themeKey: z.string().optional(),
1723
+ branding: StorefrontCmsBrandingSchema.optional(),
1724
+ seo: StorefrontCmsSeoSchema.optional(),
1725
+ contact: StorefrontCmsContactSchema.optional(),
1726
+ tracking: StorefrontCmsTrackingSchema.optional(),
1727
+ customScripts: StorefrontCmsCustomScriptsSchema.optional(),
1728
+ updatedOn: z.string().nullable().optional()
1729
+ });
1730
+ var StorefrontCmsPageSchema = z.object({
1731
+ id: z.string(),
1732
+ name: z.string(),
1733
+ slug: z.string(),
1734
+ layout: z.string().optional(),
1735
+ version: z.number().optional(),
1736
+ settings: z.record(z.string(), z.unknown()).optional().nullable(),
1737
+ sections: z.array(z.unknown()).optional(),
1738
+ status: z.string().optional(),
1739
+ hasPublishedVersion: z.boolean().optional(),
1740
+ publishedOn: z.string().nullable().optional(),
1741
+ publishedBy: z.string().nullable().optional(),
1742
+ createdOn: z.string().nullable().optional(),
1743
+ updatedOn: z.string().nullable().optional(),
1744
+ createdBy: z.string().nullable().optional(),
1745
+ updatedBy: z.string().nullable().optional(),
1746
+ lastModifiedBy: z.string().nullable().optional()
1747
+ }).passthrough();
1748
+ var StorefrontSettingsLegacyFlatSchema = z.object({
1749
+ id: z.coerce.string(),
1750
+ tenantId: z.string().nullable().optional(),
1751
+ name: z.string(),
1752
+ slug: z.coerce.string().optional(),
1753
+ description: z.string().nullable().optional(),
1754
+ visibility: z.string().nullable().optional(),
1755
+ logo: z.string().nullable().optional(),
1756
+ favicon: z.string().nullable().optional(),
1757
+ icon: z.string().nullable().optional(),
1758
+ currency: z.string().nullable().optional(),
1759
+ language: z.string().nullable().optional(),
1760
+ themeConfig: z.unknown().optional().nullable(),
1761
+ featuresEnabled: z.unknown().optional().nullable(),
1762
+ checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
1763
+ }).passthrough();
1764
+ function unwrapSettingsResponseBody(v) {
1765
+ if (!v || typeof v !== "object" || Array.isArray(v)) return v;
1766
+ const o = v;
1767
+ if ("data" in o && o.data != null && typeof o.data === "object" && !Array.isArray(o.data)) {
1768
+ return o.data;
1769
+ }
1770
+ return v;
1771
+ }
1772
+ function isLegacyFlatSettingsPayload(v) {
1773
+ if (!v || typeof v !== "object" || Array.isArray(v)) return false;
1774
+ const o = v;
1775
+ if ("store" in o || "schemaVersion" in o || "cms" in o) return false;
1776
+ return (typeof o.id === "string" || typeof o.id === "number") && typeof o.name === "string";
1777
+ }
1778
+ function normalizeStorefrontSettingsPayload(v) {
1779
+ const body = unwrapSettingsResponseBody(v);
1780
+ if (!isLegacyFlatSettingsPayload(body)) return body;
1781
+ const raw = body;
1782
+ const parsed = StorefrontSettingsLegacyFlatSchema.safeParse(raw);
1783
+ if (!parsed.success) return body;
1784
+ const l = parsed.data;
1785
+ const currency = l.currency?.trim() ? l.currency : "PEN";
1786
+ const language = l.language?.trim() ? l.language : "es";
1787
+ const slug = l.slug?.trim() ? l.slug : l.id;
1788
+ return {
1789
+ schemaVersion: 0,
1790
+ generatedAt: (/* @__PURE__ */ new Date(0)).toISOString(),
1791
+ store: {
1792
+ id: l.id,
1793
+ tenantId: l.tenantId ?? void 0,
1794
+ name: l.name,
1795
+ slug,
1796
+ description: l.description ?? null,
1797
+ logo: l.logo ?? null,
1798
+ icon: l.icon ?? null,
1799
+ visibility: l.visibility ?? void 0,
1800
+ currency,
1801
+ language,
1802
+ themeConfig: l.themeConfig ?? void 0,
1803
+ featuresEnabled: l.featuresEnabled ?? void 0,
1804
+ checkoutSettings: l.checkoutSettings ?? void 0
1805
+ },
1806
+ cms: {
1807
+ settings: {
1808
+ branding: {
1809
+ faviconUrl: l.favicon ?? null,
1810
+ logoUrl: l.logo ?? null,
1811
+ logoDarkUrl: null,
1812
+ socialImageUrl: null
1813
+ }
1814
+ },
1815
+ pages: []
1816
+ }
1817
+ };
1818
+ }
1819
+ var StorefrontStoreSchema = z.object({
1820
+ id: z.string(),
1821
+ tenantId: z.string().optional(),
1822
+ sellerId: z.string().optional(),
1823
+ plan: z.string().optional(),
1824
+ storageLimitBytes: z.number().optional(),
1825
+ monthlyTransferLimitBytes: z.number().optional(),
1826
+ maxUploadSizeBytes: z.number().optional(),
1827
+ maxStores: z.number().optional(),
1828
+ maxMembers: z.number().optional(),
1829
+ maxProducts: z.number().optional(),
1830
+ maxCategories: z.number().optional(),
1831
+ maxBrands: z.number().optional(),
1832
+ maxAttributes: z.number().optional(),
1833
+ maxCollections: z.number().optional(),
1834
+ enableApi: z.boolean().optional(),
1835
+ isActive: z.boolean().optional(),
1836
+ name: z.string(),
1837
+ description: z.string().nullable().optional(),
1838
+ avatarUrl: z.string().nullable().optional(),
1839
+ logo: z.string().nullable().optional(),
1840
+ icon: z.string().nullable().optional(),
1841
+ slug: z.string(),
1842
+ domain: z.string().nullable().optional(),
1843
+ domains: z.array(z.string()).optional(),
1844
+ timeZone: z.string().nullable().optional(),
1845
+ currency: z.string(),
1846
+ language: z.string(),
1847
+ visibility: z.string().optional(),
1848
+ privateAccessHash: z.string().nullable().optional(),
1849
+ privateAccessVersion: z.number().optional(),
1850
+ themeConfig: StorefrontThemeConfigSchema.optional(),
1851
+ featuresEnabled: StorefrontFeaturesEnabledSchema.optional(),
1852
+ checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
1853
+ }).passthrough();
1854
+ var StorefrontSettingsEnvelopeSchema = z.object({
1855
+ schemaVersion: z.number(),
1856
+ generatedAt: z.string(),
1857
+ store: StorefrontStoreSchema,
1858
+ cms: z.object({
1859
+ settings: StorefrontCmsSettingsSchema,
1860
+ pages: z.array(StorefrontCmsPageSchema)
1861
+ })
1862
+ }).passthrough();
1863
+ var StorefrontSettingsSchema = z.preprocess(
1864
+ normalizeStorefrontSettingsPayload,
1865
+ StorefrontSettingsEnvelopeSchema
1866
+ );
1867
+ function storefrontStoreRecord(settings) {
1868
+ return settings?.store ?? null;
1869
+ }
1870
+
1871
+ // src/core/lib/ecomiq-oauth-identity.ts
1872
+ function buildEcomiqOAuthIdentityHeaders(settings) {
1873
+ const record = storefrontStoreRecord(settings);
1874
+ if (!record?.id) {
1875
+ throw new Error("Tienda no disponible para iniciar sesi\xF3n");
1876
+ }
1877
+ const checkout = record.checkoutSettings;
1878
+ const identityScope = checkout?.identityScope === "tenant" ? "tenant" : "store";
1879
+ const headers = {
1880
+ "x-Identity-Scope": identityScope,
1881
+ "x-Store-Id": record.id
1882
+ };
1883
+ if (record.tenantId) headers["x-Tenant-Id"] = record.tenantId;
1884
+ return headers;
1885
+ }
1886
+
1887
+ // src/react/auth/ecomiq-storefront-sign-in.ts
1888
+ async function signInWithEcomiqCredentials(authClient, settings, credentials) {
1889
+ const response = await authClient.$fetch("/ecomiq-oauth/sign-in", {
1890
+ method: "POST",
1891
+ headers: buildEcomiqOAuthIdentityHeaders(settings),
1892
+ body: credentials
1893
+ });
1894
+ if (response.error) {
1895
+ throw new Error(response.error.message ?? "Error al iniciar sesi\xF3n");
1896
+ }
1897
+ return response;
1898
+ }
1899
+
1900
+ // src/react/shell/lib/find-storefront-cms-page.ts
1901
+ function isRenderableCmsPage(p) {
1902
+ if (!p.status) return true;
1903
+ return p.status === "published";
1904
+ }
1905
+ function findStorefrontCmsPageBySlug(settings, slug) {
1906
+ const pages = settings?.cms?.pages;
1907
+ if (!pages?.length) return null;
1908
+ const raw = pages.find(
1909
+ (p) => p.slug === slug && isRenderableCmsPage(p)
1910
+ );
1911
+ if (!raw) return null;
1912
+ const parsed = StorefrontPageDetailSchema.safeParse(raw);
1913
+ return parsed.success ? parsed.data : null;
1914
+ }
1915
+
1916
+ // src/core/constants/currency.ts
1917
+ var countryCurrency = {
1918
+ "PEN": "es-PE",
1919
+ "USD": "en-US",
1920
+ "COP": "es-CO",
1921
+ "MXN": "es-MX"
1922
+ };
1923
+
1924
+ // src/core/utils/format-currency.ts
1925
+ function formatCurrency(amount, currency = "USD") {
1926
+ const locale = countryCurrency[currency] ?? "en-US";
1927
+ return new Intl.NumberFormat(locale, {
1928
+ style: "currency",
1929
+ currency
1930
+ }).format(amount);
1931
+ }
1932
+ function buildOptionGroups(variants) {
1933
+ const map = /* @__PURE__ */ new Map();
1934
+ for (const v of variants) {
1935
+ for (const opt of v.options ?? []) {
1936
+ const key = opt.key;
1937
+ const name = opt.name ?? key;
1938
+ if (!map.has(key)) map.set(key, /* @__PURE__ */ new Map());
1939
+ map.get(key).set(opt.value, name);
1940
+ }
1941
+ }
1942
+ return Array.from(map.entries()).map(([key, valueMap]) => ({
1943
+ key,
1944
+ name: Array.from(valueMap.values())[0] ?? key,
1945
+ values: Array.from(valueMap.keys())
1946
+ }));
1947
+ }
1948
+ function findVariant(variants, selected, hasConfigurableOptions) {
1949
+ if (!hasConfigurableOptions && variants.length > 0) {
1950
+ return variants[0] ?? null;
1951
+ }
1952
+ if (Object.keys(selected).length === 0) return null;
1953
+ for (const v of variants) {
1954
+ const opts = v.options ?? [];
1955
+ const match = opts.length > 0 && opts.every((o) => selected[o.key] === o.value);
1956
+ if (match) return v;
1957
+ }
1958
+ return null;
1959
+ }
1960
+ function getInitialOptions(variants, optionGroups) {
1961
+ const first = variants[0];
1962
+ if (!first) return {};
1963
+ const opts = first.options ?? [];
1964
+ const selected = {};
1965
+ for (const g of optionGroups) {
1966
+ const o = opts.find((x) => x.key === g.key);
1967
+ if (o) selected[g.key] = o.value;
1968
+ }
1969
+ return selected;
1970
+ }
1971
+ function ProductVariantSelector({
1972
+ product,
1973
+ currency = "USD",
1974
+ features = [],
1975
+ onVariantChange,
1976
+ children
1977
+ }) {
1978
+ const variants = useMemo(() => product.variants ?? [], [product.variants]);
1979
+ const optionGroups = useMemo(() => buildOptionGroups(variants), [variants]);
1980
+ const hasConfigurableOptions = optionGroups.length > 0;
1981
+ const [selectedOptions, setSelectedOptions] = useState(
1982
+ () => getInitialOptions(variants, optionGroups)
1983
+ );
1984
+ const selectedVariant = useMemo(
1985
+ () => findVariant(variants, selectedOptions, hasConfigurableOptions),
1986
+ [variants, selectedOptions, hasConfigurableOptions]
1987
+ );
1988
+ const displayPrice = selectedVariant?.price ?? product.price ?? 0;
1989
+ const compareAtPrice = selectedVariant?.compareAtPrice ?? product.compareAtPrice;
1990
+ const isAvailable = (selectedVariant ? (selectedVariant.quantity ?? 0) > 0 : product.isAvailable) ?? true;
1991
+ useEffect(() => {
1992
+ onVariantChange?.(selectedVariant, displayPrice);
1993
+ }, [selectedVariant, displayPrice, onVariantChange]);
1994
+ const setOption = useCallback((key, value) => {
1995
+ setSelectedOptions((prev) => ({ ...prev, [key]: value }));
1996
+ }, []);
1997
+ const hasVariants = hasConfigurableOptions;
1998
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
1999
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
2000
+ /* @__PURE__ */ jsx(
2001
+ "span",
2002
+ {
2003
+ className: "inline-flex items-center rounded-md bg-primary/10 px-2.5 py-0.5 text-base font-semibold text-primary",
2004
+ "data-testid": "product-display-price",
2005
+ children: formatCurrency(displayPrice, currency)
2006
+ }
2007
+ ),
2008
+ compareAtPrice != null && compareAtPrice > displayPrice && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground line-through", children: formatCurrency(compareAtPrice, currency) })
2009
+ ] }),
2010
+ hasVariants && optionGroups.map((group) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2011
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: group.name }),
2012
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: group.values.map((value) => {
2013
+ const isSelected = selectedOptions[group.key] === value;
2014
+ const isColorLike = group.key.toLowerCase().includes("color") || group.key.toLowerCase().includes("colour");
2015
+ return /* @__PURE__ */ jsx(
2016
+ "button",
2017
+ {
2018
+ type: "button",
2019
+ onClick: () => setOption(group.key, value),
2020
+ className: isColorLike ? `min-w-[72px] rounded-md border-2 px-3 py-2 text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 ${isSelected ? "border-primary bg-primary text-foreground" : "border-border bg-muted/30 text-foreground hover:border-muted-foreground/50"}` : `rounded-md border px-3 py-2 text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 ${isSelected ? "border-primary bg-muted ring-1 ring-primary" : "border-border bg-transparent text-muted-foreground hover:border-muted-foreground/50 hover:text-foreground"}`,
2021
+ style: isColorLike && isSelected && value.toLowerCase() === "black" ? { backgroundColor: "#1a1a1a", borderColor: "#1a1a1a", color: "#fff" } : isColorLike && value.toLowerCase() === "white" ? { backgroundColor: "#fafafa", color: "#1a1a1a", borderColor: "#e5e5e5" } : void 0,
2022
+ "data-testid": `variant-option-${group.key}-${value}`,
2023
+ children: value
2024
+ },
2025
+ value
2026
+ );
2027
+ }) })
2028
+ ] }, group.key)),
2029
+ features.length > 0 && /* @__PURE__ */ jsx("ul", { className: "list-disc list-inside space-y-1 text-sm text-muted-foreground", children: features.map((f, i) => /* @__PURE__ */ jsx("li", { children: f }, i)) }),
2030
+ children?.({
2031
+ product,
2032
+ selectedVariant,
2033
+ displayPrice,
2034
+ compareAtPrice,
2035
+ isAvailable,
2036
+ selectedOptions
2037
+ })
2038
+ ] });
2039
+ }
2040
+
2041
+ // src/npm/framework-react-client.ts
2042
+ var usePublicStore = () => useStore.getState().data;
2043
+
2044
+ export { CustomerAddressSchema, CustomerAddressUpsertSchema, CustomerMeSchema, CustomerOrderDetailSchema, CustomerOrderListItemSchema, CustomerProfilePatchSchema, CustomerRegisterRequestSchema, EcomiqProvider, ProductVariantSelector, QueryProvider, StoreApiClient, StorefrontAuthProvider, StorefrontProductSchema, StorefrontProductsResponseSchema, StorefrontSettingsSchema, addCartCoupon, checkoutCart, createCart, createCustomerAddress, createStoreApiClient, customerMeToProfilePatch, deleteCustomerAddress, ecomiqOAuthPasswordClient, findStorefrontCmsPageBySlug, formatCurrency, getCart, getCartCheckout, getCartPaymentMethods, getCustomerAddresses, getCustomerMe, getCustomerOrder, getCustomerOrders, getSharedOrderDraft, getShippingOptions, getStoreApiBaseUrl, getStoreApiClient, getStorefrontCollectionBySlug, getStorefrontCollections, getStorefrontPageBySlug, getStorefrontPagePreview, getStorefrontPages, getStorefrontProductBySlug, getStorefrontProducts, isCartNotActiveApiError, patchCartAddresses, patchCartBuyer, patchCustomer, putCartShippingMethod, registerCustomer, removeCartCoupon, setClientStoreId, setServerRequestOrigin, setServerStoreId, signInWithEcomiqCredentials, storeApiClient, storefrontAccessTokenNeedsRefresh, storefrontSessionEndsSoon, updateCustomerAddress, uploadPaymentReceipt, useCart, usePublicStore, useStore, useStoreCart, useStoreCollections, useStorePages, useStoreProducts, useStorefrontAuthClient, useStorefrontSession };
2045
+ //# sourceMappingURL=client.js.map
2046
+ //# sourceMappingURL=client.js.map