@ecomiq/storefront 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.js DELETED
@@ -1,1239 +0,0 @@
1
- import { z } from 'zod';
2
- import axios from 'axios';
3
- import { existsSync } from 'fs';
4
- import { createRequire } from 'module';
5
- import { join } from 'path';
6
- import '@opennextjs/cloudflare';
7
- import '@ecomiq/storefront/core';
8
-
9
- // src/core/constants/api-paths.ts
10
- var STOREFRONT_API_PATH_PREFIX = "v1";
11
-
12
- // src/core/constants/storefront-ecomiq-oauth-cookie.ts
13
- var STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME = "ecomiq_sf_oauth_at";
14
- var STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH = "/api/store";
15
-
16
- // src/core/constants/currency.ts
17
- var countryCurrency = {
18
- "PEN": "es-PE",
19
- "USD": "en-US",
20
- "COP": "es-CO",
21
- "MXN": "es-MX"
22
- };
23
-
24
- // src/core/utils/format-currency.ts
25
- function formatCurrency(amount, currency = "USD") {
26
- const locale = countryCurrency[currency] ?? "en-US";
27
- return new Intl.NumberFormat(locale, {
28
- style: "currency",
29
- currency
30
- }).format(amount);
31
- }
32
- var StorefrontCheckoutSettingsSchema = z.object({
33
- allowGuestCheckout: z.boolean().optional(),
34
- identityScope: z.enum(["store", "tenant", "global"]).optional(),
35
- signInMethods: z.array(z.string()).optional()
36
- });
37
- var looseRecord = z.record(z.string(), z.unknown());
38
- var StorefrontThemeConfigSchema = z.object({
39
- name: z.string().nullable().optional(),
40
- mode: z.string().nullable().optional(),
41
- colors: looseRecord.optional(),
42
- fonts: looseRecord.optional(),
43
- assets: looseRecord.optional()
44
- }).passthrough();
45
- var StorefrontFeaturesEnabledSchema = z.object({
46
- flags: looseRecord.optional()
47
- }).passthrough();
48
- var StorefrontCmsBrandingSchema = z.object({
49
- logoUrl: z.string().nullable().optional(),
50
- logoDarkUrl: z.string().nullable().optional(),
51
- faviconUrl: z.string().nullable().optional(),
52
- socialImageUrl: z.string().nullable().optional()
53
- });
54
- var StorefrontCmsSeoSchema = z.object({
55
- siteName: z.string().nullable().optional(),
56
- metaTitle: z.string().nullable().optional(),
57
- metaDescription: z.string().nullable().optional(),
58
- titleTemplate: z.string().nullable().optional(),
59
- robotsIndex: z.boolean().optional()
60
- });
61
- var StorefrontCmsSocialLinksSchema = z.object({
62
- instagram: z.string().nullable().optional(),
63
- facebook: z.string().nullable().optional(),
64
- tiktok: z.string().nullable().optional(),
65
- youtube: z.string().nullable().optional(),
66
- x: z.string().nullable().optional()
67
- });
68
- var StorefrontCmsContactSchema = z.object({
69
- supportEmail: z.string().nullable().optional(),
70
- phone: z.string().nullable().optional(),
71
- whatsapp: z.string().nullable().optional(),
72
- address: z.string().nullable().optional(),
73
- socialLinks: StorefrontCmsSocialLinksSchema.optional()
74
- });
75
- var StorefrontCmsTrackingSchema = z.object({
76
- googleAnalyticsMeasurementId: z.string().nullable().optional(),
77
- metaPixelId: z.string().nullable().optional(),
78
- googleTagManagerContainerId: z.string().nullable().optional()
79
- });
80
- var StorefrontCmsCustomScriptsSchema = z.object({
81
- enabled: z.boolean().optional(),
82
- head: z.string().nullable().optional(),
83
- bodyEnd: z.string().nullable().optional()
84
- });
85
- var StorefrontCmsSettingsSchema = z.object({
86
- themeKey: z.string().optional(),
87
- branding: StorefrontCmsBrandingSchema.optional(),
88
- seo: StorefrontCmsSeoSchema.optional(),
89
- contact: StorefrontCmsContactSchema.optional(),
90
- tracking: StorefrontCmsTrackingSchema.optional(),
91
- customScripts: StorefrontCmsCustomScriptsSchema.optional(),
92
- updatedOn: z.string().nullable().optional()
93
- });
94
- var StorefrontCmsPageSchema = z.object({
95
- id: z.string(),
96
- name: z.string(),
97
- slug: z.string(),
98
- layout: z.string().optional(),
99
- version: z.number().optional(),
100
- settings: z.record(z.string(), z.unknown()).optional().nullable(),
101
- sections: z.array(z.unknown()).optional(),
102
- status: z.string().optional(),
103
- hasPublishedVersion: z.boolean().optional(),
104
- publishedOn: z.string().nullable().optional(),
105
- publishedBy: z.string().nullable().optional(),
106
- createdOn: z.string().nullable().optional(),
107
- updatedOn: z.string().nullable().optional(),
108
- createdBy: z.string().nullable().optional(),
109
- updatedBy: z.string().nullable().optional(),
110
- lastModifiedBy: z.string().nullable().optional()
111
- }).passthrough();
112
- var StorefrontSettingsLegacyFlatSchema = z.object({
113
- id: z.coerce.string(),
114
- tenantId: z.string().nullable().optional(),
115
- name: z.string(),
116
- slug: z.coerce.string().optional(),
117
- description: z.string().nullable().optional(),
118
- visibility: z.string().nullable().optional(),
119
- logo: z.string().nullable().optional(),
120
- favicon: z.string().nullable().optional(),
121
- icon: z.string().nullable().optional(),
122
- currency: z.string().nullable().optional(),
123
- language: z.string().nullable().optional(),
124
- themeConfig: z.unknown().optional().nullable(),
125
- featuresEnabled: z.unknown().optional().nullable(),
126
- checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
127
- }).passthrough();
128
- function unwrapSettingsResponseBody(v) {
129
- if (!v || typeof v !== "object" || Array.isArray(v)) return v;
130
- const o = v;
131
- if ("data" in o && o.data != null && typeof o.data === "object" && !Array.isArray(o.data)) {
132
- return o.data;
133
- }
134
- return v;
135
- }
136
- function isLegacyFlatSettingsPayload(v) {
137
- if (!v || typeof v !== "object" || Array.isArray(v)) return false;
138
- const o = v;
139
- if ("store" in o || "schemaVersion" in o || "cms" in o) return false;
140
- return (typeof o.id === "string" || typeof o.id === "number") && typeof o.name === "string";
141
- }
142
- function normalizeStorefrontSettingsPayload(v) {
143
- const body = unwrapSettingsResponseBody(v);
144
- if (!isLegacyFlatSettingsPayload(body)) return body;
145
- const raw = body;
146
- const parsed = StorefrontSettingsLegacyFlatSchema.safeParse(raw);
147
- if (!parsed.success) return body;
148
- const l = parsed.data;
149
- const currency = l.currency?.trim() ? l.currency : "PEN";
150
- const language = l.language?.trim() ? l.language : "es";
151
- const slug = l.slug?.trim() ? l.slug : l.id;
152
- return {
153
- schemaVersion: 0,
154
- generatedAt: (/* @__PURE__ */ new Date(0)).toISOString(),
155
- store: {
156
- id: l.id,
157
- tenantId: l.tenantId ?? void 0,
158
- name: l.name,
159
- slug,
160
- description: l.description ?? null,
161
- logo: l.logo ?? null,
162
- icon: l.icon ?? null,
163
- visibility: l.visibility ?? void 0,
164
- currency,
165
- language,
166
- themeConfig: l.themeConfig ?? void 0,
167
- featuresEnabled: l.featuresEnabled ?? void 0,
168
- checkoutSettings: l.checkoutSettings ?? void 0
169
- },
170
- cms: {
171
- settings: {
172
- branding: {
173
- faviconUrl: l.favicon ?? null,
174
- logoUrl: l.logo ?? null,
175
- logoDarkUrl: null,
176
- socialImageUrl: null
177
- }
178
- },
179
- pages: []
180
- }
181
- };
182
- }
183
- var StorefrontStoreSchema = z.object({
184
- id: z.string(),
185
- tenantId: z.string().optional(),
186
- sellerId: z.string().optional(),
187
- plan: z.string().optional(),
188
- storageLimitBytes: z.number().optional(),
189
- monthlyTransferLimitBytes: z.number().optional(),
190
- maxUploadSizeBytes: z.number().optional(),
191
- maxStores: z.number().optional(),
192
- maxMembers: z.number().optional(),
193
- maxProducts: z.number().optional(),
194
- maxCategories: z.number().optional(),
195
- maxBrands: z.number().optional(),
196
- maxAttributes: z.number().optional(),
197
- maxCollections: z.number().optional(),
198
- enableApi: z.boolean().optional(),
199
- isActive: z.boolean().optional(),
200
- name: z.string(),
201
- description: z.string().nullable().optional(),
202
- avatarUrl: z.string().nullable().optional(),
203
- logo: z.string().nullable().optional(),
204
- icon: z.string().nullable().optional(),
205
- slug: z.string(),
206
- domain: z.string().nullable().optional(),
207
- domains: z.array(z.string()).optional(),
208
- timeZone: z.string().nullable().optional(),
209
- currency: z.string(),
210
- language: z.string(),
211
- visibility: z.string().optional(),
212
- privateAccessHash: z.string().nullable().optional(),
213
- privateAccessVersion: z.number().optional(),
214
- themeConfig: StorefrontThemeConfigSchema.optional(),
215
- featuresEnabled: StorefrontFeaturesEnabledSchema.optional(),
216
- checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
217
- }).passthrough();
218
- var StorefrontSettingsEnvelopeSchema = z.object({
219
- schemaVersion: z.number(),
220
- generatedAt: z.string(),
221
- store: StorefrontStoreSchema,
222
- cms: z.object({
223
- settings: StorefrontCmsSettingsSchema,
224
- pages: z.array(StorefrontCmsPageSchema)
225
- })
226
- }).passthrough();
227
- var StorefrontSettingsSchema = z.preprocess(
228
- normalizeStorefrontSettingsPayload,
229
- StorefrontSettingsEnvelopeSchema
230
- );
231
- function storefrontStoreRecord(settings) {
232
- return settings?.store ?? null;
233
- }
234
- function storefrontFaviconUrl(settings) {
235
- const b = settings?.cms?.settings?.branding;
236
- return b?.faviconUrl ?? settings?.store?.logo ?? settings?.store?.icon ?? null;
237
- }
238
- function storefrontOgImageUrl(settings) {
239
- const b = settings?.cms?.settings?.branding;
240
- return b?.socialImageUrl ?? settings?.store?.logo ?? null;
241
- }
242
-
243
- // src/core/lib/ecomiq-oauth-identity.ts
244
- function buildEcomiqOAuthIdentityHeaders(settings) {
245
- const record = storefrontStoreRecord(settings);
246
- if (!record?.id) {
247
- throw new Error("Tienda no disponible para iniciar sesi\xF3n");
248
- }
249
- const checkout = record.checkoutSettings;
250
- const identityScope = checkout?.identityScope === "tenant" ? "tenant" : "store";
251
- const headers = {
252
- "x-Identity-Scope": identityScope,
253
- "x-Store-Id": record.id
254
- };
255
- if (record.tenantId) headers["x-Tenant-Id"] = record.tenantId;
256
- return headers;
257
- }
258
-
259
- // src/core/lib/customer-order-labels.ts
260
- var ORDER_STATUS_LABELS = {
261
- New: "Pedido realizado",
262
- Confirmed: "Confirmado",
263
- Processing: "En preparaci\xF3n",
264
- InTransit: "En camino",
265
- Delivered: "Entregado",
266
- Cancelled: "Cancelado",
267
- Canceled: "Cancelado",
268
- Refunded: "Reembolsado",
269
- Pending: "Pendiente",
270
- Paid: "Pagado",
271
- Captured: "Pago confirmado"
272
- };
273
- function formatCustomerOrderStatus(status) {
274
- const trimmed = status.trim();
275
- if (!trimmed) return "Desconocido";
276
- return ORDER_STATUS_LABELS[trimmed] ?? trimmed.replace(/([A-Z])/g, " $1").trim();
277
- }
278
- function customerOrderStatusTone(status) {
279
- const s = status.toLowerCase();
280
- if (s.includes("cancel") || s.includes("refund")) return "danger";
281
- if (s.includes("deliver")) return "success";
282
- if (s.includes("transit") || s.includes("ship")) return "info";
283
- if (s.includes("confirm") || s.includes("paid") || s.includes("capture")) return "success";
284
- if (s.includes("pending") || s.includes("new") || s.includes("process")) return "warning";
285
- return "default";
286
- }
287
- function formatOrderDate(iso, locale = "es-PE") {
288
- const d = new Date(iso);
289
- if (Number.isNaN(d.getTime())) return iso;
290
- return new Intl.DateTimeFormat(locale, {
291
- day: "numeric",
292
- month: "long",
293
- year: "numeric"
294
- }).format(d);
295
- }
296
- function formatOrderDateTime(iso, locale = "es-PE") {
297
- const d = new Date(iso);
298
- if (Number.isNaN(d.getTime())) return iso;
299
- return new Intl.DateTimeFormat(locale, {
300
- day: "numeric",
301
- month: "short",
302
- year: "numeric",
303
- hour: "2-digit",
304
- minute: "2-digit"
305
- }).format(d);
306
- }
307
-
308
- // src/core/lib/storefront-geo-inei.ts
309
- function toGeoItems(data) {
310
- if (!Array.isArray(data)) return [];
311
- return data.map((raw) => {
312
- if (!raw || typeof raw !== "object") return null;
313
- const item = raw;
314
- return {
315
- code: String(item.code ?? ""),
316
- name: String(item.name ?? "")
317
- };
318
- }).filter((x) => !!x && !!x.code && !!x.name);
319
- }
320
- var departmentsCache = null;
321
- var departmentsRequest = null;
322
- function loadStorefrontGeoDepartments(headers) {
323
- if (departmentsCache) return Promise.resolve(departmentsCache);
324
- if (departmentsRequest) return departmentsRequest;
325
- departmentsRequest = fetch(
326
- `/api/store/geo/departments?countryCode=PE&source=inei&limit=200`,
327
- { cache: "no-store", headers }
328
- ).then((r) => r.json()).then((data) => {
329
- const items = toGeoItems(data);
330
- departmentsCache = items;
331
- return items;
332
- }).catch(() => {
333
- departmentsCache = [];
334
- return [];
335
- }).finally(() => {
336
- departmentsRequest = null;
337
- });
338
- return departmentsRequest;
339
- }
340
- async function fetchStorefrontGeoProvinces(headers, countryCode, departmentCode) {
341
- const res = await fetch(
342
- `/api/store/geo/provinces?countryCode=${encodeURIComponent(
343
- countryCode
344
- )}&departmentCode=${encodeURIComponent(departmentCode)}&source=inei&limit=200`,
345
- { headers }
346
- );
347
- const data = await res.json();
348
- return toGeoItems(data);
349
- }
350
- async function fetchStorefrontGeoDistricts(headers, countryCode, provinceCode) {
351
- const res = await fetch(
352
- `/api/store/geo/districts?countryCode=${encodeURIComponent(
353
- countryCode
354
- )}&provinceCode=${encodeURIComponent(provinceCode)}&source=inei`,
355
- { headers }
356
- );
357
- const data = await res.json();
358
- return toGeoItems(data);
359
- }
360
- async function resolveIneiCodesFromLabels(storeId, labels, countryCode = "PE") {
361
- const id = storeId.trim();
362
- if (!id) return null;
363
- const headers = { "X-Store-Id": id };
364
- const departments = await loadStorefrontGeoDepartments(headers);
365
- const dept = departments.find((d) => d.name.trim() === labels.department.trim());
366
- if (!dept) return null;
367
- const provinces = await fetchStorefrontGeoProvinces(headers, countryCode, dept.code);
368
- const prov = provinces.find((p) => p.name.trim() === labels.province.trim());
369
- if (!prov) {
370
- return { departmentCode: dept.code, provinceCode: "", districtCode: "" };
371
- }
372
- const districts = await fetchStorefrontGeoDistricts(headers, countryCode, prov.code);
373
- const dist = districts.find((d) => d.name.trim() === labels.district.trim());
374
- return {
375
- departmentCode: dept.code,
376
- provinceCode: prov.code,
377
- districtCode: dist?.code ?? ""
378
- };
379
- }
380
- var ApiClient = class {
381
- client;
382
- storeId;
383
- storeDomain;
384
- constructor(baseURL = "https://storefront.ecomiq.pe") {
385
- this.client = axios.create({
386
- baseURL,
387
- timeout: 1e4,
388
- headers: {
389
- "Content-Type": "application/json"
390
- }
391
- });
392
- this.client.interceptors.request.use(
393
- (config) => {
394
- if (config.headers) {
395
- if (this.storeId) config.headers["X-Store-Id"] = this.storeId;
396
- if (this.storeDomain) config.headers["X-Store-Domain"] = this.storeDomain;
397
- }
398
- return config;
399
- }
400
- );
401
- this.client.interceptors.response.use(
402
- (response) => response,
403
- (error) => {
404
- console.error("API Error:", error);
405
- return Promise.reject(error);
406
- }
407
- );
408
- }
409
- setStoreId(storeId) {
410
- this.storeId = storeId;
411
- }
412
- /** Subdominio para endpoints que usan X-Store-Domain (ej. GET /v1/storefront/settings) */
413
- setStoreDomain(domain) {
414
- this.storeDomain = domain;
415
- }
416
- get(url, config) {
417
- return this.client.get(url, config).then((response) => response.data);
418
- }
419
- post(url, data, config) {
420
- return this.client.post(url, data, config).then((response) => response.data);
421
- }
422
- put(url, data, config) {
423
- return this.client.put(url, data, config).then((response) => response.data);
424
- }
425
- patch(url, data, config) {
426
- return this.client.patch(url, data, config).then((response) => response.data);
427
- }
428
- delete(url, config) {
429
- return this.client.delete(url, config).then((response) => response.data);
430
- }
431
- };
432
- var apiClient = new ApiClient();
433
- var ProductVariantSchema = z.object({
434
- id: z.coerce.string(),
435
- name: z.string(),
436
- storeId: z.string(),
437
- productId: z.coerce.string(),
438
- basePrice: z.number().positive().optional().nullable(),
439
- comparePrice: z.number().positive().optional().nullable(),
440
- //TODO: remove this field
441
- originalPrice: z.number().positive().optional().nullable(),
442
- costPrice: z.number().positive().optional().nullable(),
443
- isDefault: z.boolean().optional().nullable(),
444
- reserveStock: z.number().nonnegative().optional().nullable(),
445
- weight: z.number().nonnegative().optional().nullable().default(0),
446
- width: z.number().nonnegative().optional().nullable(),
447
- height: z.number().nonnegative().optional().nullable(),
448
- unitOfMeasure: z.string().optional().nullable(),
449
- order: z.number().nonnegative().optional().nullable().default(0),
450
- sku: z.string().optional().nullable(),
451
- stock: z.number().nonnegative().optional().nullable(),
452
- leadTime: z.string().optional().nullable(),
453
- barCode: z.string().optional().nullable(),
454
- shippingWeight: z.number().nonnegative().optional().nullable(),
455
- images: z.array(z.string()).optional().nullable(),
456
- attributes: z.array(z.string()).optional().nullable(),
457
- variantStatus: z.string().optional().nullable(),
458
- status: z.string().optional().nullable(),
459
- createdOn: z.string().optional().nullable(),
460
- updatedOn: z.string().optional().nullable(),
461
- deletedOn: z.string().optional().nullable()
462
- });
463
- var ProductSchema = z.object({
464
- id: z.coerce.string(),
465
- name: z.string(),
466
- images: z.array(z.object({
467
- url: z.string().url(),
468
- name: z.string().optional(),
469
- isPrimary: z.boolean().optional()
470
- })),
471
- basePrice: z.number().positive().optional(),
472
- salePrice: z.number().positive().optional(),
473
- slug: z.string(),
474
- description: z.string().optional(),
475
- categories: z.array(z.object({
476
- id: z.coerce.string(),
477
- name: z.string(),
478
- slug: z.string(),
479
- logo: z.string().optional(),
480
- icon: z.string().optional()
481
- })).optional(),
482
- tags: z.array(z.string()).optional(),
483
- inStock: z.boolean().optional(),
484
- variants: z.array(ProductVariantSchema).optional()
485
- });
486
- var ProductsResponseSchema = z.object({
487
- items: z.array(ProductSchema),
488
- meta: z.object({
489
- total: z.number().int().positive(),
490
- page: z.number().int().positive(),
491
- pageSize: z.number().int().positive(),
492
- hasNextPage: z.boolean()
493
- })
494
- });
495
- var ProductsFiltersSchema = z.object({
496
- category: z.string().optional(),
497
- search: z.string().optional(),
498
- minPrice: z.number().positive().optional(),
499
- maxPrice: z.number().positive().optional(),
500
- inStock: z.boolean().optional(),
501
- sortBy: z.enum(["name", "price", "createdAt"]).optional(),
502
- sortOrder: z.enum(["asc", "desc"]).optional(),
503
- page: z.number().int().positive().optional(),
504
- limit: z.number().int().positive().optional()
505
- });
506
- var StorefrontProductSchema = z.object({
507
- id: z.coerce.string(),
508
- name: z.string(),
509
- slug: z.string(),
510
- productType: z.string().optional().nullable(),
511
- imageUrl: z.string().optional().nullable(),
512
- price: z.number().nonnegative(),
513
- compareAtPrice: z.number().nonnegative().optional().nullable(),
514
- variantCount: z.number().int().nonnegative().optional().default(0),
515
- isAvailable: z.boolean(),
516
- totalInventory: z.number().int().nonnegative(),
517
- bundleItemsCount: z.number().int().nonnegative().optional().default(0),
518
- brand: z.string().optional().nullable(),
519
- category: z.string().optional().nullable(),
520
- status: z.string().optional().nullable(),
521
- tags: z.array(z.string()).optional().nullable()
522
- });
523
- var StorefrontFacetSchema = z.object({
524
- value: z.string(),
525
- count: z.number().int().nonnegative()
526
- });
527
- var StorefrontProductsResponseSchema = z.object({
528
- pageIndex: z.number().int().positive(),
529
- pageSize: z.number().int().positive(),
530
- totalCount: z.number().int().nonnegative(),
531
- totalPages: z.number().int().nonnegative(),
532
- products: z.array(StorefrontProductSchema),
533
- categories: z.array(StorefrontFacetSchema).optional().default([]),
534
- brands: z.array(StorefrontFacetSchema).optional().default([]),
535
- minPrice: z.number().nonnegative().optional().nullable(),
536
- maxPrice: z.number().nonnegative().optional().nullable()
537
- });
538
- var StorefrontProductsParamsSchema = z.object({
539
- page: z.number().int().positive().optional().default(1),
540
- pageSize: z.number().int().positive().optional().default(20),
541
- sort: z.enum(["price_asc", "price_desc", "name_asc", "name_desc", "newest"]).optional().default("price_asc"),
542
- sellerId: z.string().optional(),
543
- search: z.string().optional(),
544
- collection: z.string().optional(),
545
- category: z.string().optional(),
546
- brand: z.string().optional(),
547
- productType: z.string().optional(),
548
- inStock: z.boolean().optional(),
549
- minPrice: z.number().nonnegative().optional(),
550
- maxPrice: z.number().nonnegative().optional()
551
- });
552
- var StorefrontVariantOptionSchema = z.object({
553
- key: z.string(),
554
- name: z.string(),
555
- value: z.string()
556
- });
557
- var StorefrontProductImageSchema = z.object({
558
- url: z.string(),
559
- name: z.string().optional().nullable(),
560
- order: z.number().int().nonnegative().optional()
561
- });
562
- var StorefrontVariantSchema = z.object({
563
- id: z.coerce.string().optional().default(""),
564
- sku: z.string(),
565
- status: z.string().optional().nullable(),
566
- price: z.number().nonnegative(),
567
- compareAtPrice: z.number().nonnegative().optional().nullable(),
568
- quantity: z.number().int().nonnegative(),
569
- options: z.array(StorefrontVariantOptionSchema).optional().default([]),
570
- images: z.array(StorefrontProductImageSchema).optional().default([])
571
- });
572
- var StorefrontPriceTierSchema = z.object({
573
- variantId: z.coerce.string(),
574
- minQuantity: z.number().int().positive(),
575
- maxQuantity: z.number().int().positive().optional().nullable(),
576
- unitPrice: z.number().nonnegative()
577
- });
578
- var StorefrontBundleItemSchema = z.object({
579
- productId: z.coerce.string(),
580
- variantId: z.coerce.string(),
581
- productName: z.string(),
582
- variantName: z.string().optional().nullable(),
583
- sku: z.string().optional().nullable(),
584
- brand: z.string().optional().nullable(),
585
- imageUrl: z.string().optional().nullable(),
586
- quantity: z.number().int(),
587
- availableStock: z.number().int().optional().default(0),
588
- allowBackorders: z.boolean().optional().default(false),
589
- requiresShipping: z.boolean().optional().default(true)
590
- });
591
- var StorefrontProductDetailSchema = z.object({
592
- id: z.coerce.string(),
593
- name: z.string(),
594
- slug: z.string(),
595
- description: z.string().optional().nullable(),
596
- productType: z.string().optional().nullable(),
597
- status: z.string().optional().nullable(),
598
- imageUrl: z.string().optional().nullable(),
599
- price: z.number().nonnegative(),
600
- compareAtPrice: z.number().nonnegative().optional().nullable(),
601
- isAvailable: z.boolean(),
602
- totalInventory: z.number().int().nonnegative(),
603
- brand: z.string().optional().nullable(),
604
- category: z.string().optional().nullable(),
605
- categoryId: z.coerce.string().optional().nullable(),
606
- tags: z.array(z.string()).optional().nullable(),
607
- specifications: z.array(z.record(z.string(), z.unknown())).optional().default([]),
608
- variants: z.array(StorefrontVariantSchema).optional().default([]),
609
- images: z.array(StorefrontProductImageSchema).optional().default([]),
610
- bundleItems: z.array(StorefrontBundleItemSchema).optional().default([]),
611
- priceTiers: z.array(StorefrontPriceTierSchema).optional().default([]),
612
- createdAt: z.string().optional().nullable(),
613
- updatedAt: z.string().optional().nullable()
614
- });
615
-
616
- // src/core/services/product.service.ts
617
- var ProductService = class _ProductService {
618
- static instance;
619
- constructor() {
620
- }
621
- static getInstance() {
622
- if (!_ProductService.instance) {
623
- _ProductService.instance = new _ProductService();
624
- }
625
- return _ProductService.instance;
626
- }
627
- /**
628
- * Obtiene todos los productos del store
629
- */
630
- async getProducts(filters) {
631
- if (filters) {
632
- ProductsFiltersSchema.parse(filters);
633
- }
634
- const params = new URLSearchParams();
635
- if (filters) {
636
- if (filters.category) params.append("category", filters.category);
637
- if (filters.search) params.append("search", filters.search);
638
- if (filters.minPrice) params.append("minPrice", filters.minPrice.toString());
639
- if (filters.maxPrice) params.append("maxPrice", filters.maxPrice.toString());
640
- if (filters.sortBy) params.append("sortBy", filters.sortBy);
641
- if (filters.sortOrder) params.append("sortOrder", filters.sortOrder);
642
- if (filters.page) params.append("page", filters.page.toString());
643
- if (filters.limit) params.append("limit", filters.limit.toString());
644
- }
645
- const queryString = params.toString();
646
- const url = `/${STOREFRONT_API_PATH_PREFIX}/products${queryString ? `?${queryString}` : ""}`;
647
- const response = await apiClient.get(url);
648
- return ProductsResponseSchema.parse(response);
649
- }
650
- /**
651
- * Obtiene un producto específico por ID
652
- */
653
- async getProduct(id) {
654
- const response = await apiClient.get(`/${STOREFRONT_API_PATH_PREFIX}/products/${id}`);
655
- return ProductSchema.parse(response);
656
- }
657
- /**
658
- * Obtiene un producto específico por slug
659
- */
660
- async getProductBySlug(slug) {
661
- const response = await apiClient.get(`/${STOREFRONT_API_PATH_PREFIX}/products/${encodeURIComponent(slug)}`);
662
- return ProductSchema.parse(response);
663
- }
664
- /**
665
- * Busca productos por término de búsqueda
666
- */
667
- async searchProducts(query, filters) {
668
- return this.getProducts({ ...filters, search: query });
669
- }
670
- /**
671
- * Obtiene productos por categoría
672
- */
673
- async getProductsByCategory(category, filters) {
674
- return this.getProducts({ ...filters, category });
675
- }
676
- /**
677
- * Obtiene productos en oferta (con descuento)
678
- */
679
- async getProductsOnSale(filters) {
680
- return this.getProducts({ ...filters, minPrice: 0 });
681
- }
682
- /**
683
- * Obtiene productos en stock
684
- */
685
- async getProductsInStock(filters) {
686
- return this.getProducts({ ...filters, inStock: true });
687
- }
688
- /**
689
- * Lista de productos del storefront (API v1/storefront/products).
690
- * Soporta paginación, orden y filtros por categoría, marca y precio.
691
- */
692
- async getStorefrontProducts(params) {
693
- const parsed = StorefrontProductsParamsSchema.parse(params ?? {});
694
- const searchParams = new URLSearchParams();
695
- searchParams.set("page", String(parsed.page));
696
- searchParams.set("pageSize", String(parsed.pageSize));
697
- if (parsed.sort) searchParams.set("sort", parsed.sort);
698
- if (parsed.sellerId) searchParams.set("sellerId", parsed.sellerId);
699
- if (parsed.collection) searchParams.set("collection", parsed.collection);
700
- if (parsed.category) searchParams.set("category", parsed.category);
701
- if (parsed.brand) searchParams.set("brand", parsed.brand);
702
- if (parsed.productType) searchParams.set("productType", parsed.productType);
703
- if (parsed.inStock != null) searchParams.set("inStock", String(parsed.inStock));
704
- if (parsed.minPrice != null) searchParams.set("minPrice", String(parsed.minPrice));
705
- if (parsed.maxPrice != null) searchParams.set("maxPrice", String(parsed.maxPrice));
706
- if (parsed.search) searchParams.set("search", parsed.search);
707
- const url = `/${STOREFRONT_API_PATH_PREFIX}/products?${searchParams.toString()}`;
708
- const response = await apiClient.get(url);
709
- return StorefrontProductsResponseSchema.parse(response);
710
- }
711
- /**
712
- * Obtiene un producto del storefront por slug (API v1/storefront/products/by-slug/:slug).
713
- */
714
- async getStorefrontProductBySlug(slug) {
715
- const response = await apiClient.get(`/${STOREFRONT_API_PATH_PREFIX}/products/by-slug/${encodeURIComponent(slug)}`);
716
- return StorefrontProductDetailSchema.parse(response);
717
- }
718
- };
719
- var productService = ProductService.getInstance();
720
- var StorefrontCollectionSchema = z.object({
721
- id: z.coerce.string(),
722
- slug: z.string(),
723
- name: z.string(),
724
- description: z.string().nullable().optional(),
725
- imageUrl: z.string().nullable().optional(),
726
- type: z.string(),
727
- productCount: z.number().int().nonnegative()
728
- });
729
- var StorefrontCollectionsResponseSchema = z.array(StorefrontCollectionSchema);
730
- var StorefrontCollectionDetailSchema = StorefrontCollectionSchema;
731
-
732
- // src/core/services/collection.service.ts
733
- var CollectionService = class _CollectionService {
734
- static instance;
735
- constructor() {
736
- }
737
- static getInstance() {
738
- if (!_CollectionService.instance) {
739
- _CollectionService.instance = new _CollectionService();
740
- }
741
- return _CollectionService.instance;
742
- }
743
- /**
744
- * Lista de colecciones del storefront (GET /v1/collections).
745
- */
746
- async getStorefrontCollections() {
747
- const response = await apiClient.get(
748
- `/${STOREFRONT_API_PATH_PREFIX}/collections`
749
- );
750
- return StorefrontCollectionsResponseSchema.parse(response);
751
- }
752
- /**
753
- * Obtiene una colección del storefront por slug (GET /v1/collections/by-slug/:slug).
754
- */
755
- async getStorefrontCollectionBySlug(slug) {
756
- const response = await apiClient.get(
757
- `/${STOREFRONT_API_PATH_PREFIX}/collections/by-slug/${encodeURIComponent(slug)}`
758
- );
759
- return StorefrontCollectionDetailSchema.parse(response);
760
- }
761
- };
762
- var collectionService = CollectionService.getInstance();
763
- var StorefrontPageListItemSchema = z.object({
764
- id: z.string(),
765
- name: z.string(),
766
- slug: z.string(),
767
- layout: z.string()
768
- });
769
- var StorefrontPageSeoSchema = z.object({
770
- title: z.string().optional(),
771
- description: z.string().optional()
772
- }).optional();
773
- var StorefrontPageSettingsSchema = z.object({
774
- seo: StorefrontPageSeoSchema,
775
- html: z.string().optional(),
776
- title: z.string().optional()
777
- }).catchall(z.unknown());
778
- var StorefrontPageBlockSchema = z.object({
779
- id: z.string(),
780
- type: z.string(),
781
- order: z.number(),
782
- settings: z.record(z.unknown()).optional()
783
- });
784
- var StorefrontPageSectionSchema = z.object({
785
- id: z.string(),
786
- type: z.string(),
787
- order: z.number(),
788
- settings: z.record(z.unknown()).optional(),
789
- blocks: z.array(StorefrontPageBlockSchema).optional().default([])
790
- });
791
- var StorefrontPageDetailSchema = z.object({
792
- id: z.string(),
793
- name: z.string(),
794
- slug: z.string(),
795
- layout: z.string(),
796
- settings: StorefrontPageSettingsSchema.optional(),
797
- sections: z.array(StorefrontPageSectionSchema).optional()
798
- });
799
-
800
- // src/core/services/page.service.ts
801
- var PageService = class _PageService {
802
- static instance;
803
- constructor() {
804
- }
805
- static getInstance() {
806
- if (!_PageService.instance) {
807
- _PageService.instance = new _PageService();
808
- }
809
- return _PageService.instance;
810
- }
811
- /**
812
- * Lista de páginas del storefront (GET /v1/pages).
813
- */
814
- async getPages() {
815
- const response = await apiClient.get(
816
- `/${STOREFRONT_API_PATH_PREFIX}/pages`
817
- );
818
- return z.array(StorefrontPageListItemSchema).parse(response);
819
- }
820
- /**
821
- * Obtiene una página por slug (GET /v1/pages/{slug}).
822
- * sections puede no venir en la respuesta.
823
- */
824
- async getPageBySlug(slug) {
825
- const response = await apiClient.get(
826
- `/${STOREFRONT_API_PATH_PREFIX}/pages/${encodeURIComponent(slug)}`
827
- );
828
- return StorefrontPageDetailSchema.parse(response);
829
- }
830
- };
831
- var pageService = PageService.getInstance();
832
-
833
- // src/core/services/store.service.ts
834
- var StoreService = class _StoreService {
835
- static instance;
836
- constructor() {
837
- }
838
- static getInstance() {
839
- if (!_StoreService.instance) {
840
- _StoreService.instance = new _StoreService();
841
- }
842
- return _StoreService.instance;
843
- }
844
- /**
845
- * Obtiene la configuración de la tienda por subdominio (GET /v1/settings).
846
- * Usa el header X-Store-Domain. Si se pasa domain, se configura antes de la petición.
847
- */
848
- async getStorefrontSettings(domain) {
849
- if (domain) {
850
- apiClient.setStoreDomain(domain);
851
- }
852
- const response = await apiClient.get(`/${STOREFRONT_API_PATH_PREFIX}/settings`);
853
- return StorefrontSettingsSchema.parse(response);
854
- }
855
- };
856
- var storeService = StoreService.getInstance();
857
- var CartBuyerRequestSchema = z.object({
858
- email: z.string().email(),
859
- firstName: z.string().min(1),
860
- lastName: z.string().min(1),
861
- phone: z.string().min(1)
862
- });
863
- var CartCreateRequestSchema = z.object({
864
- currencyCode: z.string(),
865
- salesChannelId: z.string(),
866
- email: z.string().email()
867
- });
868
- var CartAddressSchema = z.object({
869
- name: z.string().min(1),
870
- address1: z.string().min(1),
871
- city: z.string().min(1),
872
- countryCode: z.string().min(2),
873
- company: z.string().nullable().optional(),
874
- address2: z.string().nullable().optional(),
875
- province: z.string().nullable().optional(),
876
- postalCode: z.string().nullable().optional(),
877
- district: z.string().nullable().optional(),
878
- phone: z.string().nullable().optional(),
879
- latitude: z.number().nullable().optional(),
880
- longitude: z.number().nullable().optional(),
881
- geo: z.object({
882
- departmentCode: z.string().nullable().optional(),
883
- provinceCode: z.string().nullable().optional(),
884
- districtCode: z.string().nullable().optional()
885
- }).nullable().optional()
886
- });
887
- var CartAddressesRequestSchema = z.object({
888
- shippingAddress: CartAddressSchema,
889
- billingAddress: CartAddressSchema
890
- });
891
- var CartItemModifierRequestSchema = z.object({
892
- modifierGroupId: z.coerce.string().min(1),
893
- optionIds: z.array(z.coerce.string().min(1)).optional().default([])
894
- });
895
- var CartItemRequestSchema = z.object({
896
- variantId: z.coerce.string().min(1),
897
- quantity: z.number().int().positive(),
898
- modifiers: z.array(CartItemModifierRequestSchema).optional()
899
- });
900
- var CartCouponRequestSchema = z.object({
901
- code: z.string().min(1)
902
- });
903
- z.object({
904
- subtotal: z.number(),
905
- discount: z.number(),
906
- tax: z.number(),
907
- warranty: z.number().optional().default(0),
908
- total: z.number()
909
- });
910
- z.object({
911
- name: z.string().nullable().optional(),
912
- address1: z.string(),
913
- city: z.string(),
914
- countryCode: z.string(),
915
- company: z.string().nullable().optional(),
916
- address2: z.string().nullable().optional(),
917
- province: z.string().nullable().optional(),
918
- postalCode: z.string().nullable().optional(),
919
- district: z.string().nullable().optional(),
920
- phone: z.string().nullable().optional(),
921
- latitude: z.number().nullable().optional(),
922
- longitude: z.number().nullable().optional(),
923
- geo: z.object({
924
- departmentCode: z.string().nullable().optional(),
925
- provinceCode: z.string().nullable().optional(),
926
- districtCode: z.string().nullable().optional()
927
- }).nullable().optional()
928
- });
929
- var CartResponseBundleItemSchema = z.object({
930
- productId: z.coerce.string(),
931
- variantId: z.coerce.string(),
932
- productName: z.string(),
933
- variantName: z.string().nullable().optional(),
934
- sku: z.string().nullable().optional(),
935
- brand: z.string().nullable().optional(),
936
- imageUrl: z.string().nullable().optional(),
937
- quantity: z.number().int()
938
- });
939
- var CartResponseItemSchema = z.object({
940
- id: z.string(),
941
- title: z.string(),
942
- variantLabel: z.string().nullable().optional(),
943
- thumbnail: z.string().nullable().optional(),
944
- quantity: z.number().int(),
945
- variantId: z.coerce.string(),
946
- variantSku: z.string().nullable().optional(),
947
- unitPrice: z.number(),
948
- bundleItems: z.array(CartResponseBundleItemSchema).optional().default([])
949
- });
950
- z.object({
951
- id: z.string(),
952
- name: z.string(),
953
- description: z.string().nullable().optional(),
954
- total: z.number(),
955
- estimatedDays: z.number().int().nullable().optional(),
956
- pickupPointId: z.string().nullable().optional(),
957
- scheduledDate: z.string().nullable().optional(),
958
- scheduledTime: z.string().nullable().optional()
959
- });
960
- var CartResponseSchema = z.object({
961
- id: z.string(),
962
- regionId: z.string().nullable().optional(),
963
- salesChannelId: z.string().nullable().optional(),
964
- email: z.string().email().nullable().optional(),
965
- phone: z.string().nullable().optional(),
966
- firstName: z.string().nullable().optional(),
967
- lastName: z.string().nullable().optional(),
968
- currencyCode: z.string(),
969
- completedAt: z.string().nullable().optional(),
970
- shippingAddress: z.unknown().nullable().optional(),
971
- billingAddress: z.unknown().nullable().optional(),
972
- metadata: z.record(z.string(), z.unknown()).optional().default({}),
973
- promotionCodes: z.array(z.string()).optional().default([]),
974
- items: z.array(CartResponseItemSchema).optional().default([]),
975
- shippingMethods: z.array(z.unknown()).optional().default([]),
976
- totals: z.object({
977
- discountTotal: z.number(),
978
- shippingTotal: z.number(),
979
- subtotal: z.number(),
980
- taxTotal: z.number(),
981
- total: z.number(),
982
- warrantyTotal: z.number()
983
- })
984
- });
985
- var CartCheckoutRequestSchema = z.object({
986
- paymentMethodCode: z.string().min(1),
987
- externalRef: z.string().min(1),
988
- receiptUrl: z.string().min(1).optional()
989
- });
990
- var CartCheckoutPaymentActionSchema = z.object({
991
- publicConfiguration: z.object({
992
- publishableKey: z.string().nullable().optional(),
993
- checkoutMode: z.string().nullable().optional(),
994
- phoneNumber: z.string().nullable().optional(),
995
- accountHolder: z.string().nullable().optional(),
996
- qrImageUrl: z.string().nullable().optional()
997
- }).passthrough().nullable().optional(),
998
- url: z.string().nullable().optional(),
999
- html: z.string().nullable().optional(),
1000
- clientSecret: z.string().nullable().optional(),
1001
- qrCode: z.string().nullable().optional(),
1002
- expiresAt: z.string().nullable().optional()
1003
- }).passthrough();
1004
- var CartCheckoutPaymentSchema = z.object({
1005
- transactionId: z.string(),
1006
- paymentMethodCode: z.string(),
1007
- providerId: z.string().nullable().optional(),
1008
- status: z.string(),
1009
- amount: z.number(),
1010
- reference: z.string(),
1011
- actionType: z.string(),
1012
- receiptUrl: z.string().nullable().optional(),
1013
- action: CartCheckoutPaymentActionSchema.nullable().optional()
1014
- }).passthrough();
1015
- var CartCheckoutResponseSchema = z.object({
1016
- publicKey: z.string().optional(),
1017
- publishableKey: z.string().optional(),
1018
- stripePublicKey: z.string().optional(),
1019
- clientSecret: z.string().optional(),
1020
- intentClientSecret: z.string().optional(),
1021
- orderId: z.coerce.string().optional(),
1022
- orderGroup: z.string().optional(),
1023
- orderIds: z.array(z.coerce.string()).optional(),
1024
- /** Payload de pago (embedded, redirect, etc.) */
1025
- payment: CartCheckoutPaymentSchema.optional(),
1026
- cart: z.unknown().optional()
1027
- }).passthrough();
1028
- var CartPaymentReceiptResponseSchema = z.object({
1029
- id: z.string(),
1030
- url: z.string()
1031
- });
1032
- var CartPaymentMethodSchema = z.object({
1033
- code: z.string(),
1034
- name: z.string(),
1035
- description: z.string().nullable().optional(),
1036
- kind: z.string(),
1037
- isActive: z.boolean(),
1038
- isDefault: z.boolean(),
1039
- isManual: z.boolean(),
1040
- sortOrder: z.number(),
1041
- phoneNumber: z.string().nullable().optional(),
1042
- accountHolder: z.string().nullable().optional(),
1043
- qrImageUrl: z.string().nullable().optional()
1044
- });
1045
- var CartPaymentMethodsResponseSchema = z.object({
1046
- methods: z.array(CartPaymentMethodSchema)
1047
- });
1048
- var CartCheckoutReadResponseSchema = z.object({
1049
- cart: CartResponseSchema,
1050
- paymentMethods: CartPaymentMethodsResponseSchema
1051
- });
1052
- var ShippingRateSchema = z.object({
1053
- shippingMethodId: z.string(),
1054
- name: z.string(),
1055
- displayName: z.string().optional(),
1056
- type: z.string().optional(),
1057
- price: z.number(),
1058
- currency: z.string().optional(),
1059
- sortOrder: z.number().optional(),
1060
- rateId: z.string(),
1061
- description: z.string().nullable().optional(),
1062
- deliveryLocationId: z.string().nullable().optional(),
1063
- deliveryLocationName: z.string().nullable().optional(),
1064
- estimatedDeliveryDays: z.number().nullable().optional(),
1065
- serviceCode: z.string().nullable().optional(),
1066
- metadata: z.record(z.string(), z.unknown()).optional()
1067
- }).passthrough();
1068
- var ShippingOptionGroupSchema = z.object({
1069
- sellerId: z.string(),
1070
- shippingProfileId: z.string().nullable().optional(),
1071
- orderAmount: z.number().optional(),
1072
- totalWeight: z.number().optional(),
1073
- itemIds: z.array(z.string()).optional(),
1074
- rates: z.array(ShippingRateSchema)
1075
- }).passthrough();
1076
- var ShippingOptionsResponseSchema = z.object({
1077
- groups: z.array(ShippingOptionGroupSchema)
1078
- });
1079
- var CartShippingMethodPutRequestSchema = z.object({
1080
- rateId: z.string().min(1),
1081
- shippingMethodId: z.string().min(1),
1082
- serviceCode: z.string().nullable().optional(),
1083
- sellerId: z.string().nullable().optional(),
1084
- shippingProfileId: z.string().nullable().optional(),
1085
- locationId: z.string().nullable().optional(),
1086
- pickupPointId: z.string().nullable().optional(),
1087
- scheduledDate: z.string().nullable().optional(),
1088
- scheduledTime: z.string().nullable().optional()
1089
- });
1090
-
1091
- // src/core/services/cart.service.ts
1092
- var CartService = class _CartService {
1093
- static instance;
1094
- constructor() {
1095
- }
1096
- static getInstance() {
1097
- if (!_CartService.instance) {
1098
- _CartService.instance = new _CartService();
1099
- }
1100
- return _CartService.instance;
1101
- }
1102
- /**
1103
- * Obtiene el carrito actual (GET /v1/carts).
1104
- */
1105
- async getCart() {
1106
- const response = await apiClient.get(`/${STOREFRONT_API_PATH_PREFIX}/carts`);
1107
- return CartResponseSchema.parse(response);
1108
- }
1109
- /**
1110
- * Crea un carrito nuevo (POST /v1/carts).
1111
- */
1112
- async createCart(data) {
1113
- const payload = CartCreateRequestSchema.parse(data);
1114
- const response = await apiClient.post(`/${STOREFRONT_API_PATH_PREFIX}/carts`, payload);
1115
- return CartResponseSchema.parse(response);
1116
- }
1117
- /**
1118
- * Actualiza los datos del comprador del carrito actual (PATCH /v1/carts/buyer).
1119
- * El carrito se resuelve en backend vía contexto (token/guest), por eso no requiere cartId.
1120
- */
1121
- async updateBuyer(data) {
1122
- const payload = CartBuyerRequestSchema.parse(data);
1123
- const response = await apiClient.patch(`/${STOREFRONT_API_PATH_PREFIX}/carts/buyer`, payload);
1124
- return CartResponseSchema.parse(response);
1125
- }
1126
- /**
1127
- * Actualiza direcciones de envío y facturación del carrito (PATCH /v1/carts/addresses).
1128
- */
1129
- async updateAddresses(data) {
1130
- const payload = CartAddressesRequestSchema.parse(data);
1131
- const response = await apiClient.patch(`/${STOREFRONT_API_PATH_PREFIX}/carts/addresses`, payload);
1132
- return CartResponseSchema.parse(response);
1133
- }
1134
- /**
1135
- * Inicializa/obtiene detalles del método de pago para el checkout (POST /v1/carts/checkout).
1136
- * Usado para providers como Stripe (public key, client secret, etc).
1137
- */
1138
- async checkout(data) {
1139
- const payload = CartCheckoutRequestSchema.parse(data);
1140
- const response = await apiClient.post(`/${STOREFRONT_API_PATH_PREFIX}/carts/checkout`, payload);
1141
- return CartCheckoutResponseSchema.parse(response);
1142
- }
1143
- };
1144
- var cartService = CartService.getInstance();
1145
- var ECOMIQ_APP_APEX = "ecomiq.app";
1146
- var ECOMIQ_APP_SUFFIX = [`.${ECOMIQ_APP_APEX}`, `.localhost`];
1147
- function normalizeStoreHost(hostHeader) {
1148
- let h = hostHeader.trim().toLowerCase();
1149
- const colon = h.indexOf(":");
1150
- if (colon !== -1) h = h.slice(0, colon);
1151
- if (h.startsWith("www.")) h = h.slice(4);
1152
- return h;
1153
- }
1154
- function resolveStorefrontSettingsHost(hostHeader) {
1155
- const host = normalizeStoreHost(hostHeader);
1156
- if (!host) {
1157
- throw Object.assign(new Error("Host inv\xE1lido para tienda"), { status: 400 });
1158
- }
1159
- if (host === ECOMIQ_APP_APEX) {
1160
- throw Object.assign(new Error("Host apex ecomiq.app sin slug de tienda"), { status: 400 });
1161
- }
1162
- if (ECOMIQ_APP_SUFFIX.some((suffix) => host.endsWith(suffix))) {
1163
- const slug = host.slice(0, -(ECOMIQ_APP_SUFFIX.find((suffix) => host.endsWith(suffix))?.length ?? 0));
1164
- if (!slug) {
1165
- throw Object.assign(new Error("Host sin slug para ecomiq.app"), { status: 400 });
1166
- }
1167
- return slug;
1168
- }
1169
- return host;
1170
- }
1171
-
1172
- // src/core/config/ecomiq-config.ts
1173
- var CONFIG_FILENAMES = [
1174
- "ecomiq.config.js",
1175
- "ecomiq.config.cjs",
1176
- "ecomiq.config.mjs"
1177
- ];
1178
- var EcomiqConfigSchema = z.object({
1179
- /**
1180
- * Slug de tienda en Ecomiq (p. ej. `mi-tienda` para `mi-tienda.ecomiq.app`).
1181
- * Si está definido, tiene prioridad sobre el `Host` de la request (útil en `localhost`).
1182
- */
1183
- slugStore: z.string().min(1).optional()
1184
- });
1185
- var cachedConfig;
1186
- function parseExportedConfig(raw) {
1187
- const candidate = raw && typeof raw === "object" && "default" in raw ? raw.default : raw;
1188
- const parsed = EcomiqConfigSchema.safeParse(candidate);
1189
- if (!parsed.success) {
1190
- console.warn(
1191
- "[ecomiq] ecomiq.config.* inv\xE1lido:",
1192
- parsed.error.flatten().fieldErrors
1193
- );
1194
- return null;
1195
- }
1196
- const slugStore = parsed.data.slugStore?.trim();
1197
- return slugStore ? { slugStore } : {};
1198
- }
1199
- function loadEcomiqConfig(cwd = process.cwd()) {
1200
- if (cachedConfig !== void 0) return cachedConfig;
1201
- for (const filename of CONFIG_FILENAMES) {
1202
- const configPath = join(cwd, filename);
1203
- if (!existsSync(configPath)) continue;
1204
- try {
1205
- const requireFromApp = createRequire(join(cwd, "package.json"));
1206
- const loaded = requireFromApp(configPath);
1207
- const parsed = parseExportedConfig(loaded);
1208
- cachedConfig = parsed;
1209
- return cachedConfig;
1210
- } catch (error) {
1211
- console.warn(`[ecomiq] No se pudo cargar ${configPath}:`, error);
1212
- }
1213
- }
1214
- cachedConfig = null;
1215
- return null;
1216
- }
1217
- function clearEcomiqConfigCache() {
1218
- cachedConfig = void 0;
1219
- }
1220
- function resolvePublicStoreKey(hostHeader, cwd) {
1221
- const slugFromConfig = loadEcomiqConfig(cwd)?.slugStore?.trim();
1222
- if (slugFromConfig) return slugFromConfig;
1223
- if (!hostHeader?.trim()) {
1224
- throw Object.assign(
1225
- new Error(
1226
- "Host is required, o define slugStore en ecomiq.config.js en la ra\xEDz del proyecto"
1227
- ),
1228
- { status: 400 }
1229
- );
1230
- }
1231
- return resolveStorefrontSettingsHost(hostHeader);
1232
- }
1233
- function hasEcomiqSlugStoreConfig(cwd) {
1234
- return Boolean(loadEcomiqConfig(cwd)?.slugStore?.trim());
1235
- }
1236
-
1237
- export { CartAddressesRequestSchema, CartBuyerRequestSchema, CartCheckoutPaymentActionSchema, CartCheckoutPaymentSchema, CartCheckoutReadResponseSchema, CartCheckoutRequestSchema, CartCheckoutResponseSchema, CartCouponRequestSchema, CartCreateRequestSchema, CartItemModifierRequestSchema, CartItemRequestSchema, CartPaymentMethodSchema, CartPaymentMethodsResponseSchema, CartPaymentReceiptResponseSchema, CartResponseBundleItemSchema, CartResponseItemSchema, CartResponseSchema, CartShippingMethodPutRequestSchema, EcomiqConfigSchema, ProductSchema, ProductVariantSchema, ProductsFiltersSchema, ProductsResponseSchema, STOREFRONT_API_PATH_PREFIX, STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME, STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH, ShippingOptionGroupSchema, ShippingOptionsResponseSchema, ShippingRateSchema, StorefrontBundleItemSchema, StorefrontCheckoutSettingsSchema, StorefrontCollectionDetailSchema, StorefrontCollectionSchema, StorefrontCollectionsResponseSchema, StorefrontPageDetailSchema, StorefrontPageListItemSchema, StorefrontPriceTierSchema, StorefrontProductDetailSchema, StorefrontProductSchema, StorefrontProductsParamsSchema, StorefrontProductsResponseSchema, StorefrontSettingsLegacyFlatSchema, StorefrontSettingsSchema, StorefrontStoreSchema, apiClient, buildEcomiqOAuthIdentityHeaders, cartService, clearEcomiqConfigCache, collectionService, countryCurrency, customerOrderStatusTone, fetchStorefrontGeoDistricts, fetchStorefrontGeoProvinces, formatCurrency, formatCustomerOrderStatus, formatOrderDate, formatOrderDateTime, hasEcomiqSlugStoreConfig, loadEcomiqConfig, loadStorefrontGeoDepartments, normalizeStorefrontSettingsPayload, pageService, productService, resolveIneiCodesFromLabels, resolvePublicStoreKey, storeService, storefrontFaviconUrl, storefrontOgImageUrl, storefrontStoreRecord, toGeoItems };
1238
- //# sourceMappingURL=core.js.map
1239
- //# sourceMappingURL=core.js.map