@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/README.md +159 -53
- package/dist/index-C-xqLr1g.d.ts +6551 -0
- package/dist/nextjs/api.d.ts +10 -14
- package/dist/nextjs/api.js +74 -41
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs.d.ts +21 -3193
- package/dist/nextjs.js +1759 -588
- package/dist/nextjs.js.map +1 -1
- package/dist/store-proxy-handler-CNzKlTFA.d.ts +10 -0
- package/dist/tanstack/api.d.ts +41 -0
- package/dist/tanstack/api.js +196 -0
- package/dist/tanstack/api.js.map +1 -0
- package/dist/tanstack.d.ts +30 -0
- package/dist/{react.js → tanstack.js} +2466 -2172
- package/dist/tanstack.js.map +1 -0
- package/package.json +21 -13
- package/dist/collection-anMkdWa7.d.ts +0 -4333
- package/dist/core.d.ts +0 -3396
- package/dist/core.js +0 -1239
- package/dist/core.js.map +0 -1
- package/dist/find-storefront-cms-page-DNwLo1iV.d.ts +0 -178
- package/dist/react.d.ts +0 -964
- package/dist/react.js.map +0 -1
package/dist/nextjs.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { Modal } from '@ecomiq/ui/components/modal';
|
|
3
|
-
import { StorefrontPageDetailSchema as StorefrontPageDetailSchema$1, formatCurrency, useCart, useStore as useStore$1, useStorefrontAuthClient, useStorefrontSession, SignInForm, SignUpForm, signInWithEcomiqCredentials } from '@ecomiq/storefront/react';
|
|
3
|
+
import { StorefrontPageDetailSchema as StorefrontPageDetailSchema$1, formatCurrency, useCart, useStore as useStore$1, useStorefrontAuthClient as useStorefrontAuthClient$1, useStorefrontSession as useStorefrontSession$1, SignInForm, SignUpForm, signInWithEcomiqCredentials } from '@ecomiq/storefront/react';
|
|
4
4
|
import { toast, Toaster as Toaster$1 } from 'sonner';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
6
|
import { useTheme } from 'next-themes';
|
|
7
|
-
import { headers } from 'next/headers';
|
|
8
7
|
import { StorefrontSettingsSchema, StorefrontProductsParamsSchema, StorefrontProductsResponseSchema, StorefrontProductDetailSchema, StorefrontCollectionsResponseSchema, StorefrontCollectionDetailSchema, StorefrontPageListItemSchema, StorefrontPageDetailSchema, CartCreateRequestSchema, CartResponseSchema, CartBuyerRequestSchema, CartAddressesRequestSchema, CartCouponRequestSchema, CartCheckoutRequestSchema, CartCheckoutResponseSchema, CartPaymentReceiptResponseSchema, CartCheckoutReadResponseSchema, ShippingOptionsResponseSchema, CartShippingMethodPutRequestSchema, CartItemRequestSchema } from '@ecomiq/storefront/core';
|
|
9
8
|
import { getCloudflareContext } from '@opennextjs/cloudflare';
|
|
9
|
+
import { QueryClient, hydrate, QueryClientProvider, useMutation, useQuery, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
|
10
|
+
import React2, { createContext, useRef, useEffect, useContext, useState, useMemo, useCallback } from 'react';
|
|
11
|
+
import { create } from 'zustand';
|
|
12
|
+
import { persist } from 'zustand/middleware';
|
|
13
|
+
import { createAuthMiddleware, createAuthEndpoint, formCsrfMiddleware } from 'better-auth/api';
|
|
14
|
+
import { APIError } from 'better-auth';
|
|
15
|
+
import { setSessionCookie } from 'better-auth/cookies';
|
|
16
|
+
import { parseUserOutput } from 'better-auth/db';
|
|
17
|
+
import axios from 'axios';
|
|
10
18
|
import { existsSync } from 'fs';
|
|
11
19
|
import { createRequire } from 'module';
|
|
12
20
|
import { join } from 'path';
|
|
13
|
-
import
|
|
14
|
-
import { QueryClient, useMutation, useQuery, QueryClientProvider, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
|
15
|
-
import { create } from 'zustand';
|
|
21
|
+
import { headers } from 'next/headers';
|
|
16
22
|
|
|
17
23
|
var __defProp = Object.defineProperty;
|
|
18
24
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -312,8 +318,8 @@ var init_modals_factory = __esm({
|
|
|
312
318
|
ModalsFactory = () => {
|
|
313
319
|
const cart = useCart();
|
|
314
320
|
const store = useStore$1();
|
|
315
|
-
const authClient = useStorefrontAuthClient();
|
|
316
|
-
const { refetch } = useStorefrontSession();
|
|
321
|
+
const authClient = useStorefrontAuthClient$1();
|
|
322
|
+
const { refetch } = useStorefrontSession$1();
|
|
317
323
|
const handlerLogin = async (values) => {
|
|
318
324
|
try {
|
|
319
325
|
await signInWithEcomiqCredentials(authClient, store.data, values);
|
|
@@ -451,18 +457,19 @@ var init_ecomiq_shell_ui = __esm({
|
|
|
451
457
|
}
|
|
452
458
|
});
|
|
453
459
|
|
|
454
|
-
// src/
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
const
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
setServerRequestOrigin(`${secure ? "https" : "http"}://${hostname}`);
|
|
463
|
-
return hostname;
|
|
460
|
+
// src/core/client/store-api-errors.ts
|
|
461
|
+
function isCartNotActiveApiError(error) {
|
|
462
|
+
if (!error || typeof error !== "object") return false;
|
|
463
|
+
const e = error;
|
|
464
|
+
if (e.status !== 400) return false;
|
|
465
|
+
const body = e.body;
|
|
466
|
+
const keys = body?.errors ? Object.keys(body.errors) : [];
|
|
467
|
+
return keys.includes("Carts.NotActive");
|
|
464
468
|
}
|
|
465
469
|
|
|
470
|
+
// src/core/client/index.ts
|
|
471
|
+
init_store_api_client();
|
|
472
|
+
|
|
466
473
|
// src/core/client/store-api-store.service.ts
|
|
467
474
|
init_store_api_client();
|
|
468
475
|
async function getStorefrontSettings(subdomain, cacheKey) {
|
|
@@ -543,235 +550,6 @@ async function getStorefrontSettingsFromKv(hostHeader) {
|
|
|
543
550
|
resolveStorefrontSettingsHost(hostHeader)
|
|
544
551
|
);
|
|
545
552
|
}
|
|
546
|
-
var CONFIG_FILENAMES = [
|
|
547
|
-
"ecomiq.config.js",
|
|
548
|
-
"ecomiq.config.cjs",
|
|
549
|
-
"ecomiq.config.mjs"
|
|
550
|
-
];
|
|
551
|
-
var EcomiqConfigSchema = z.object({
|
|
552
|
-
/**
|
|
553
|
-
* Slug de tienda en Ecomiq (p. ej. `mi-tienda` para `mi-tienda.ecomiq.app`).
|
|
554
|
-
* Si está definido, tiene prioridad sobre el `Host` de la request (útil en `localhost`).
|
|
555
|
-
*/
|
|
556
|
-
slugStore: z.string().min(1).optional()
|
|
557
|
-
});
|
|
558
|
-
var cachedConfig;
|
|
559
|
-
function parseExportedConfig(raw) {
|
|
560
|
-
const candidate = raw && typeof raw === "object" && "default" in raw ? raw.default : raw;
|
|
561
|
-
const parsed = EcomiqConfigSchema.safeParse(candidate);
|
|
562
|
-
if (!parsed.success) {
|
|
563
|
-
console.warn(
|
|
564
|
-
"[ecomiq] ecomiq.config.* inv\xE1lido:",
|
|
565
|
-
parsed.error.flatten().fieldErrors
|
|
566
|
-
);
|
|
567
|
-
return null;
|
|
568
|
-
}
|
|
569
|
-
const slugStore = parsed.data.slugStore?.trim();
|
|
570
|
-
return slugStore ? { slugStore } : {};
|
|
571
|
-
}
|
|
572
|
-
function loadEcomiqConfig(cwd = process.cwd()) {
|
|
573
|
-
if (cachedConfig !== void 0) return cachedConfig;
|
|
574
|
-
for (const filename of CONFIG_FILENAMES) {
|
|
575
|
-
const configPath = join(cwd, filename);
|
|
576
|
-
if (!existsSync(configPath)) continue;
|
|
577
|
-
try {
|
|
578
|
-
const requireFromApp = createRequire(join(cwd, "package.json"));
|
|
579
|
-
const loaded = requireFromApp(configPath);
|
|
580
|
-
const parsed = parseExportedConfig(loaded);
|
|
581
|
-
cachedConfig = parsed;
|
|
582
|
-
return cachedConfig;
|
|
583
|
-
} catch (error) {
|
|
584
|
-
console.warn(`[ecomiq] No se pudo cargar ${configPath}:`, error);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
cachedConfig = null;
|
|
588
|
-
return null;
|
|
589
|
-
}
|
|
590
|
-
function resolvePublicStoreKey(hostHeader, cwd) {
|
|
591
|
-
const slugFromConfig = loadEcomiqConfig(cwd)?.slugStore?.trim();
|
|
592
|
-
if (slugFromConfig) return slugFromConfig;
|
|
593
|
-
if (!hostHeader?.trim()) {
|
|
594
|
-
throw Object.assign(
|
|
595
|
-
new Error(
|
|
596
|
-
"Host is required, o define slugStore en ecomiq.config.js en la ra\xEDz del proyecto"
|
|
597
|
-
),
|
|
598
|
-
{ status: 400 }
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
return resolveStorefrontSettingsHost(hostHeader);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// src/react/shell/lib/public-store-settings-source.ts
|
|
605
|
-
var ENV_PUBLIC_STORE_SETTINGS_SOURCE = "PUBLIC_STORE_SETTINGS_SOURCE";
|
|
606
|
-
function resolvePublicStoreSettingsSource(envValue = process.env[ENV_PUBLIC_STORE_SETTINGS_SOURCE]) {
|
|
607
|
-
const v = (envValue ?? "api").trim().toLowerCase();
|
|
608
|
-
return v === "kv" ? "kv" : "api";
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// src/react/nextjs/actions/getPublicStore.ts
|
|
612
|
-
init_store_api_client();
|
|
613
|
-
async function getPublicStore(options) {
|
|
614
|
-
const headerList = await headers();
|
|
615
|
-
const host = headerList.get("host");
|
|
616
|
-
let storeKey;
|
|
617
|
-
try {
|
|
618
|
-
storeKey = resolvePublicStoreKey(host);
|
|
619
|
-
} catch (error) {
|
|
620
|
-
const err = error;
|
|
621
|
-
return {
|
|
622
|
-
data: null,
|
|
623
|
-
error: {
|
|
624
|
-
message: err.message ?? "Host is required",
|
|
625
|
-
statusCode: err.status ?? 400,
|
|
626
|
-
isNotFound: true,
|
|
627
|
-
subdomain: void 0
|
|
628
|
-
}
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
if (host?.trim()) {
|
|
632
|
-
const proto = headerList.get("x-forwarded-proto") ?? headerList.get("x-forwarded-ssl") ?? "http";
|
|
633
|
-
const secure = proto === "https" || (headerList.get("x-forwarded-ssl") ?? "") === "on";
|
|
634
|
-
setServerRequestOrigin(`${secure ? "https" : "http"}://${host}`);
|
|
635
|
-
}
|
|
636
|
-
const source = options?.source ?? resolvePublicStoreSettingsSource();
|
|
637
|
-
try {
|
|
638
|
-
setServerStoreId(null);
|
|
639
|
-
const data = source === "kv" ? await getStorefrontSettingsFromKvByStoreKey(storeKey) : await getStorefrontSettings(
|
|
640
|
-
storeKey,
|
|
641
|
-
`storefront-settings-${storeKey}`
|
|
642
|
-
);
|
|
643
|
-
setServerStoreId(data.store.id);
|
|
644
|
-
return { data, error: null };
|
|
645
|
-
} catch (error) {
|
|
646
|
-
const err = error;
|
|
647
|
-
const statusCode = err.status ?? 500;
|
|
648
|
-
return {
|
|
649
|
-
data: null,
|
|
650
|
-
error: {
|
|
651
|
-
message: err.message ?? "Error fetching store settings",
|
|
652
|
-
statusCode,
|
|
653
|
-
isNotFound: statusCode === 404,
|
|
654
|
-
subdomain: storeKey
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
var StorefrontAuthContext = createContext(null);
|
|
660
|
-
function StorefrontAuthProvider({
|
|
661
|
-
authClient,
|
|
662
|
-
children
|
|
663
|
-
}) {
|
|
664
|
-
return /* @__PURE__ */ jsx(StorefrontAuthContext.Provider, { value: authClient, children });
|
|
665
|
-
}
|
|
666
|
-
var useStore = create()(
|
|
667
|
-
(set) => ({
|
|
668
|
-
data: null,
|
|
669
|
-
drawers: {
|
|
670
|
-
cart: false,
|
|
671
|
-
search: false,
|
|
672
|
-
menu: false,
|
|
673
|
-
filter: false
|
|
674
|
-
},
|
|
675
|
-
openDrawer: (drawer) => set((state) => ({
|
|
676
|
-
drawers: {
|
|
677
|
-
...state.drawers,
|
|
678
|
-
[drawer]: true
|
|
679
|
-
}
|
|
680
|
-
})),
|
|
681
|
-
closeDrawer: (drawer) => set((state) => ({
|
|
682
|
-
drawers: {
|
|
683
|
-
...state.drawers,
|
|
684
|
-
[drawer]: false
|
|
685
|
-
}
|
|
686
|
-
})),
|
|
687
|
-
toggleDrawer: (drawer) => set((state) => ({
|
|
688
|
-
drawers: {
|
|
689
|
-
...state.drawers,
|
|
690
|
-
[drawer]: !state.drawers[drawer]
|
|
691
|
-
}
|
|
692
|
-
})),
|
|
693
|
-
closeAllDrawers: () => set((state) => ({
|
|
694
|
-
drawers: Object.keys(state.drawers).reduce(
|
|
695
|
-
(acc, key) => ({ ...acc, [key]: false }),
|
|
696
|
-
{}
|
|
697
|
-
)
|
|
698
|
-
})),
|
|
699
|
-
modals: {
|
|
700
|
-
login: false,
|
|
701
|
-
signup: false
|
|
702
|
-
},
|
|
703
|
-
openModal: (modal) => set((state) => ({
|
|
704
|
-
modals: {
|
|
705
|
-
...state.modals,
|
|
706
|
-
login: false,
|
|
707
|
-
signup: false,
|
|
708
|
-
[modal]: true
|
|
709
|
-
}
|
|
710
|
-
})),
|
|
711
|
-
closeModal: (modal) => set((state) => ({
|
|
712
|
-
modals: {
|
|
713
|
-
...state.modals,
|
|
714
|
-
login: false,
|
|
715
|
-
signup: false,
|
|
716
|
-
[modal]: false
|
|
717
|
-
}
|
|
718
|
-
})),
|
|
719
|
-
toggleModal: (modal) => set((state) => ({
|
|
720
|
-
modals: {
|
|
721
|
-
...state.modals,
|
|
722
|
-
[modal]: !state.modals[modal]
|
|
723
|
-
}
|
|
724
|
-
})),
|
|
725
|
-
closeAllModals: () => set((state) => ({
|
|
726
|
-
modals: Object.keys(state.modals).reduce(
|
|
727
|
-
(acc, key) => ({ ...acc, [key]: false }),
|
|
728
|
-
{}
|
|
729
|
-
)
|
|
730
|
-
}))
|
|
731
|
-
})
|
|
732
|
-
);
|
|
733
|
-
|
|
734
|
-
// src/react/shell/providers/EcomiqProvider.tsx
|
|
735
|
-
init_store_api_client();
|
|
736
|
-
function EcomiqProvider({
|
|
737
|
-
store,
|
|
738
|
-
authClient,
|
|
739
|
-
children,
|
|
740
|
-
withShellUi = false
|
|
741
|
-
}) {
|
|
742
|
-
useStore.setState({ data: store ?? null });
|
|
743
|
-
useEffect(() => {
|
|
744
|
-
setClientStoreId(store?.store.id ?? null);
|
|
745
|
-
return () => setClientStoreId(null);
|
|
746
|
-
}, [store]);
|
|
747
|
-
const [queryClient] = useState(() => new QueryClient());
|
|
748
|
-
const tree = /* @__PURE__ */ jsxs(QueryClientProvider, { client: queryClient, children: [
|
|
749
|
-
children,
|
|
750
|
-
withShellUi ? /* @__PURE__ */ jsx(EcomiqShellUi2, {}) : null
|
|
751
|
-
] });
|
|
752
|
-
if (!authClient) return tree;
|
|
753
|
-
return /* @__PURE__ */ jsx(StorefrontAuthProvider, { authClient, children: tree });
|
|
754
|
-
}
|
|
755
|
-
function EcomiqShellUi2() {
|
|
756
|
-
const [ui, setUi] = useState(null);
|
|
757
|
-
useEffect(() => {
|
|
758
|
-
void Promise.resolve().then(() => (init_ecomiq_shell_ui(), ecomiq_shell_ui_exports)).then((mod) => setUi(() => mod.EcomiqShellUi));
|
|
759
|
-
}, []);
|
|
760
|
-
return ui ? React2.createElement(ui) : null;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// src/core/client/store-api-errors.ts
|
|
764
|
-
function isCartNotActiveApiError(error) {
|
|
765
|
-
if (!error || typeof error !== "object") return false;
|
|
766
|
-
const e = error;
|
|
767
|
-
if (e.status !== 400) return false;
|
|
768
|
-
const body = e.body;
|
|
769
|
-
const keys = body?.errors ? Object.keys(body.errors) : [];
|
|
770
|
-
return keys.includes("Carts.NotActive");
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
// src/core/client/index.ts
|
|
774
|
-
init_store_api_client();
|
|
775
553
|
|
|
776
554
|
// src/core/client/store-api-product.service.ts
|
|
777
555
|
init_store_api_client();
|
|
@@ -1213,239 +991,99 @@ async function getSharedOrderDraft(shareToken) {
|
|
|
1213
991
|
);
|
|
1214
992
|
return OrderDraftSchema.parse(response);
|
|
1215
993
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
var StorefrontCheckoutSettingsSchema = z.object({
|
|
1220
|
-
allowGuestCheckout: z.boolean().optional(),
|
|
1221
|
-
identityScope: z.enum(["store", "tenant", "global"]).optional(),
|
|
1222
|
-
signInMethods: z.array(z.string()).optional()
|
|
1223
|
-
});
|
|
1224
|
-
var looseRecord = z.record(z.string(), z.unknown());
|
|
1225
|
-
var StorefrontThemeConfigSchema = z.object({
|
|
1226
|
-
name: z.string().nullable().optional(),
|
|
1227
|
-
mode: z.string().nullable().optional(),
|
|
1228
|
-
colors: looseRecord.optional(),
|
|
1229
|
-
fonts: looseRecord.optional(),
|
|
1230
|
-
assets: looseRecord.optional()
|
|
1231
|
-
}).passthrough();
|
|
1232
|
-
var StorefrontFeaturesEnabledSchema = z.object({
|
|
1233
|
-
flags: looseRecord.optional()
|
|
1234
|
-
}).passthrough();
|
|
1235
|
-
var StorefrontCmsBrandingSchema = z.object({
|
|
1236
|
-
logoUrl: z.string().nullable().optional(),
|
|
1237
|
-
logoDarkUrl: z.string().nullable().optional(),
|
|
1238
|
-
faviconUrl: z.string().nullable().optional(),
|
|
1239
|
-
socialImageUrl: z.string().nullable().optional()
|
|
1240
|
-
});
|
|
1241
|
-
var StorefrontCmsSeoSchema = z.object({
|
|
1242
|
-
siteName: z.string().nullable().optional(),
|
|
1243
|
-
metaTitle: z.string().nullable().optional(),
|
|
1244
|
-
metaDescription: z.string().nullable().optional(),
|
|
1245
|
-
titleTemplate: z.string().nullable().optional(),
|
|
1246
|
-
robotsIndex: z.boolean().optional()
|
|
1247
|
-
});
|
|
1248
|
-
var StorefrontCmsSocialLinksSchema = z.object({
|
|
1249
|
-
instagram: z.string().nullable().optional(),
|
|
1250
|
-
facebook: z.string().nullable().optional(),
|
|
1251
|
-
tiktok: z.string().nullable().optional(),
|
|
1252
|
-
youtube: z.string().nullable().optional(),
|
|
1253
|
-
x: z.string().nullable().optional()
|
|
1254
|
-
});
|
|
1255
|
-
var StorefrontCmsContactSchema = z.object({
|
|
1256
|
-
supportEmail: z.string().nullable().optional(),
|
|
1257
|
-
phone: z.string().nullable().optional(),
|
|
1258
|
-
whatsapp: z.string().nullable().optional(),
|
|
1259
|
-
address: z.string().nullable().optional(),
|
|
1260
|
-
socialLinks: StorefrontCmsSocialLinksSchema.optional()
|
|
1261
|
-
});
|
|
1262
|
-
var StorefrontCmsTrackingSchema = z.object({
|
|
1263
|
-
googleAnalyticsMeasurementId: z.string().nullable().optional(),
|
|
1264
|
-
metaPixelId: z.string().nullable().optional(),
|
|
1265
|
-
googleTagManagerContainerId: z.string().nullable().optional()
|
|
1266
|
-
});
|
|
1267
|
-
var StorefrontCmsCustomScriptsSchema = z.object({
|
|
1268
|
-
enabled: z.boolean().optional(),
|
|
1269
|
-
head: z.string().nullable().optional(),
|
|
1270
|
-
bodyEnd: z.string().nullable().optional()
|
|
1271
|
-
});
|
|
1272
|
-
var StorefrontCmsSettingsSchema = z.object({
|
|
1273
|
-
themeKey: z.string().optional(),
|
|
1274
|
-
branding: StorefrontCmsBrandingSchema.optional(),
|
|
1275
|
-
seo: StorefrontCmsSeoSchema.optional(),
|
|
1276
|
-
contact: StorefrontCmsContactSchema.optional(),
|
|
1277
|
-
tracking: StorefrontCmsTrackingSchema.optional(),
|
|
1278
|
-
customScripts: StorefrontCmsCustomScriptsSchema.optional(),
|
|
1279
|
-
updatedOn: z.string().nullable().optional()
|
|
1280
|
-
});
|
|
1281
|
-
var StorefrontCmsPageSchema = z.object({
|
|
1282
|
-
id: z.string(),
|
|
1283
|
-
name: z.string(),
|
|
1284
|
-
slug: z.string(),
|
|
1285
|
-
layout: z.string().optional(),
|
|
1286
|
-
version: z.number().optional(),
|
|
1287
|
-
settings: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
1288
|
-
sections: z.array(z.unknown()).optional(),
|
|
1289
|
-
status: z.string().optional(),
|
|
1290
|
-
hasPublishedVersion: z.boolean().optional(),
|
|
1291
|
-
publishedOn: z.string().nullable().optional(),
|
|
1292
|
-
publishedBy: z.string().nullable().optional(),
|
|
1293
|
-
createdOn: z.string().nullable().optional(),
|
|
1294
|
-
updatedOn: z.string().nullable().optional(),
|
|
1295
|
-
createdBy: z.string().nullable().optional(),
|
|
1296
|
-
updatedBy: z.string().nullable().optional(),
|
|
1297
|
-
lastModifiedBy: z.string().nullable().optional()
|
|
1298
|
-
}).passthrough();
|
|
1299
|
-
var StorefrontSettingsLegacyFlatSchema = z.object({
|
|
1300
|
-
id: z.coerce.string(),
|
|
1301
|
-
tenantId: z.string().nullable().optional(),
|
|
1302
|
-
name: z.string(),
|
|
1303
|
-
slug: z.coerce.string().optional(),
|
|
1304
|
-
description: z.string().nullable().optional(),
|
|
1305
|
-
visibility: z.string().nullable().optional(),
|
|
1306
|
-
logo: z.string().nullable().optional(),
|
|
1307
|
-
favicon: z.string().nullable().optional(),
|
|
1308
|
-
icon: z.string().nullable().optional(),
|
|
1309
|
-
currency: z.string().nullable().optional(),
|
|
1310
|
-
language: z.string().nullable().optional(),
|
|
1311
|
-
themeConfig: z.unknown().optional().nullable(),
|
|
1312
|
-
featuresEnabled: z.unknown().optional().nullable(),
|
|
1313
|
-
checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
|
|
1314
|
-
}).passthrough();
|
|
1315
|
-
function unwrapSettingsResponseBody(v) {
|
|
1316
|
-
if (!v || typeof v !== "object" || Array.isArray(v)) return v;
|
|
1317
|
-
const o = v;
|
|
1318
|
-
if ("data" in o && o.data != null && typeof o.data === "object" && !Array.isArray(o.data)) {
|
|
1319
|
-
return o.data;
|
|
994
|
+
var defaultOptions = {
|
|
995
|
+
queries: {
|
|
996
|
+
staleTime: 60 * 1e3
|
|
1320
997
|
}
|
|
1321
|
-
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
const parsed = StorefrontSettingsLegacyFlatSchema.safeParse(raw);
|
|
1334
|
-
if (!parsed.success) return body;
|
|
1335
|
-
const l = parsed.data;
|
|
1336
|
-
const currency = l.currency?.trim() ? l.currency : "PEN";
|
|
1337
|
-
const language = l.language?.trim() ? l.language : "es";
|
|
1338
|
-
const slug = l.slug?.trim() ? l.slug : l.id;
|
|
1339
|
-
return {
|
|
1340
|
-
schemaVersion: 0,
|
|
1341
|
-
generatedAt: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
1342
|
-
store: {
|
|
1343
|
-
id: l.id,
|
|
1344
|
-
tenantId: l.tenantId ?? void 0,
|
|
1345
|
-
name: l.name,
|
|
1346
|
-
slug,
|
|
1347
|
-
description: l.description ?? null,
|
|
1348
|
-
logo: l.logo ?? null,
|
|
1349
|
-
icon: l.icon ?? null,
|
|
1350
|
-
visibility: l.visibility ?? void 0,
|
|
1351
|
-
currency,
|
|
1352
|
-
language,
|
|
1353
|
-
themeConfig: l.themeConfig ?? void 0,
|
|
1354
|
-
featuresEnabled: l.featuresEnabled ?? void 0,
|
|
1355
|
-
checkoutSettings: l.checkoutSettings ?? void 0
|
|
1356
|
-
},
|
|
1357
|
-
cms: {
|
|
1358
|
-
settings: {
|
|
1359
|
-
branding: {
|
|
1360
|
-
faviconUrl: l.favicon ?? null,
|
|
1361
|
-
logoUrl: l.logo ?? null,
|
|
1362
|
-
logoDarkUrl: null,
|
|
1363
|
-
socialImageUrl: null
|
|
1364
|
-
}
|
|
1365
|
-
},
|
|
1366
|
-
pages: []
|
|
998
|
+
};
|
|
999
|
+
function QueryProvider({ children, dehydratedState }) {
|
|
1000
|
+
const queryClientRef = useRef(null);
|
|
1001
|
+
const hydratedRef = useRef(false);
|
|
1002
|
+
if (queryClientRef.current === null) {
|
|
1003
|
+
queryClientRef.current = new QueryClient({ defaultOptions });
|
|
1004
|
+
}
|
|
1005
|
+
const queryClient = queryClientRef.current;
|
|
1006
|
+
useEffect(() => {
|
|
1007
|
+
if (dehydratedState && !hydratedRef.current) {
|
|
1008
|
+
hydrate(queryClient, dehydratedState);
|
|
1009
|
+
hydratedRef.current = true;
|
|
1367
1010
|
}
|
|
1368
|
-
};
|
|
1011
|
+
}, [queryClient, dehydratedState]);
|
|
1012
|
+
return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children });
|
|
1369
1013
|
}
|
|
1370
|
-
var
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
monthlyTransferLimitBytes: z.number().optional(),
|
|
1377
|
-
maxUploadSizeBytes: z.number().optional(),
|
|
1378
|
-
maxStores: z.number().optional(),
|
|
1379
|
-
maxMembers: z.number().optional(),
|
|
1380
|
-
maxProducts: z.number().optional(),
|
|
1381
|
-
maxCategories: z.number().optional(),
|
|
1382
|
-
maxBrands: z.number().optional(),
|
|
1383
|
-
maxAttributes: z.number().optional(),
|
|
1384
|
-
maxCollections: z.number().optional(),
|
|
1385
|
-
enableApi: z.boolean().optional(),
|
|
1386
|
-
isActive: z.boolean().optional(),
|
|
1387
|
-
name: z.string(),
|
|
1388
|
-
description: z.string().nullable().optional(),
|
|
1389
|
-
avatarUrl: z.string().nullable().optional(),
|
|
1390
|
-
logo: z.string().nullable().optional(),
|
|
1391
|
-
icon: z.string().nullable().optional(),
|
|
1392
|
-
slug: z.string(),
|
|
1393
|
-
domain: z.string().nullable().optional(),
|
|
1394
|
-
domains: z.array(z.string()).optional(),
|
|
1395
|
-
timeZone: z.string().nullable().optional(),
|
|
1396
|
-
currency: z.string(),
|
|
1397
|
-
language: z.string(),
|
|
1398
|
-
visibility: z.string().optional(),
|
|
1399
|
-
privateAccessHash: z.string().nullable().optional(),
|
|
1400
|
-
privateAccessVersion: z.number().optional(),
|
|
1401
|
-
themeConfig: StorefrontThemeConfigSchema.optional(),
|
|
1402
|
-
featuresEnabled: StorefrontFeaturesEnabledSchema.optional(),
|
|
1403
|
-
checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
|
|
1404
|
-
}).passthrough();
|
|
1405
|
-
var StorefrontSettingsEnvelopeSchema = z.object({
|
|
1406
|
-
schemaVersion: z.number(),
|
|
1407
|
-
generatedAt: z.string(),
|
|
1408
|
-
store: StorefrontStoreSchema,
|
|
1409
|
-
cms: z.object({
|
|
1410
|
-
settings: StorefrontCmsSettingsSchema,
|
|
1411
|
-
pages: z.array(StorefrontCmsPageSchema)
|
|
1412
|
-
})
|
|
1413
|
-
}).passthrough();
|
|
1414
|
-
z.preprocess(
|
|
1415
|
-
normalizeStorefrontSettingsPayload,
|
|
1416
|
-
StorefrontSettingsEnvelopeSchema
|
|
1417
|
-
);
|
|
1418
|
-
function storefrontStoreRecord(settings) {
|
|
1419
|
-
return settings?.store ?? null;
|
|
1014
|
+
var StorefrontAuthContext = createContext(null);
|
|
1015
|
+
function StorefrontAuthProvider({
|
|
1016
|
+
authClient,
|
|
1017
|
+
children
|
|
1018
|
+
}) {
|
|
1019
|
+
return /* @__PURE__ */ jsx(StorefrontAuthContext.Provider, { value: authClient, children });
|
|
1420
1020
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1021
|
+
function useStorefrontAuthClient() {
|
|
1022
|
+
const client = useContext(StorefrontAuthContext);
|
|
1023
|
+
if (!client) {
|
|
1024
|
+
throw new Error(
|
|
1025
|
+
"useStorefrontAuthClient debe usarse dentro de StorefrontAuthProvider (o EcomiqProvider con authClient)."
|
|
1026
|
+
);
|
|
1427
1027
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1028
|
+
return client;
|
|
1029
|
+
}
|
|
1030
|
+
function storefrontSessionEndsSoon(expiresAt, skewMs = 12e4) {
|
|
1031
|
+
if (!expiresAt) return false;
|
|
1032
|
+
return Date.now() + skewMs >= expiresAt.getTime();
|
|
1033
|
+
}
|
|
1034
|
+
var storefrontAccessTokenNeedsRefresh = storefrontSessionEndsSoon;
|
|
1035
|
+
function parseStorefrontSessionExpires(at) {
|
|
1036
|
+
if (!at) return void 0;
|
|
1037
|
+
if (at instanceof Date) return Number.isNaN(at.getTime()) ? void 0 : at;
|
|
1038
|
+
if (typeof at === "string") {
|
|
1039
|
+
const d = new Date(at);
|
|
1040
|
+
return Number.isNaN(d.getTime()) ? void 0 : d;
|
|
1041
|
+
}
|
|
1042
|
+
return void 0;
|
|
1043
|
+
}
|
|
1044
|
+
function mapSessionUser(raw) {
|
|
1045
|
+
if (!raw || typeof raw !== "object") return null;
|
|
1046
|
+
const u = raw;
|
|
1047
|
+
const explicitFirst = typeof u.firstName === "string" ? u.firstName : typeof u.given_name === "string" ? u.given_name : "";
|
|
1048
|
+
const explicitLast = typeof u.lastName === "string" ? u.lastName : typeof u.family_name === "string" ? u.family_name : "";
|
|
1049
|
+
if (explicitFirst || explicitLast) {
|
|
1050
|
+
return {
|
|
1051
|
+
id: String(u.id ?? ""),
|
|
1052
|
+
email: String(u.email ?? ""),
|
|
1053
|
+
firstName: explicitFirst,
|
|
1054
|
+
lastName: explicitLast,
|
|
1055
|
+
name: typeof u.name === "string" ? u.name : void 0,
|
|
1056
|
+
phone: typeof u.phone === "string" ? u.phone : void 0
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
const emailLocal = String(u.email ?? "").split("@")[0] ?? "";
|
|
1060
|
+
const full = typeof u.name === "string" ? u.name.trim() : emailLocal.trim();
|
|
1061
|
+
const parts = full ? full.split(/\s+/) : [];
|
|
1062
|
+
return {
|
|
1063
|
+
id: String(u.id ?? ""),
|
|
1064
|
+
email: String(u.email ?? ""),
|
|
1065
|
+
firstName: parts[0] ?? "",
|
|
1066
|
+
lastName: parts.slice(1).join(" "),
|
|
1067
|
+
name: typeof u.name === "string" ? u.name : void 0,
|
|
1068
|
+
phone: typeof u.phone === "string" ? u.phone : void 0
|
|
1433
1069
|
};
|
|
1434
|
-
if (record.tenantId) headers3["x-Tenant-Id"] = record.tenantId;
|
|
1435
|
-
return headers3;
|
|
1436
1070
|
}
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
const
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1071
|
+
function useStorefrontSession() {
|
|
1072
|
+
const authClient = useStorefrontAuthClient();
|
|
1073
|
+
const session = authClient.useSession();
|
|
1074
|
+
const user = mapSessionUser(session.data?.user);
|
|
1075
|
+
const storefrontSession = session.data?.session;
|
|
1076
|
+
const sessionExpiresAt = parseStorefrontSessionExpires(storefrontSession?.expiresAt);
|
|
1077
|
+
return {
|
|
1078
|
+
session,
|
|
1079
|
+
user,
|
|
1080
|
+
sessionExpiresAt,
|
|
1081
|
+
isAuthenticated: Boolean(session.data?.user),
|
|
1082
|
+
isPending: session.isPending,
|
|
1083
|
+
error: session.error,
|
|
1084
|
+
refetch: session.refetch,
|
|
1085
|
+
signOut: () => authClient.signOut()
|
|
1086
|
+
};
|
|
1449
1087
|
}
|
|
1450
1088
|
function useStoreProducts() {
|
|
1451
1089
|
const useStorefrontProductsList = (params) => {
|
|
@@ -1662,132 +1300,1665 @@ function useStoreCart() {
|
|
|
1662
1300
|
useRemoveCartCoupon
|
|
1663
1301
|
};
|
|
1664
1302
|
}
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1303
|
+
var useStore = create()(
|
|
1304
|
+
(set) => ({
|
|
1305
|
+
data: null,
|
|
1306
|
+
drawers: {
|
|
1307
|
+
cart: false,
|
|
1308
|
+
search: false,
|
|
1309
|
+
menu: false,
|
|
1310
|
+
filter: false
|
|
1311
|
+
},
|
|
1312
|
+
openDrawer: (drawer) => set((state) => ({
|
|
1313
|
+
drawers: {
|
|
1314
|
+
...state.drawers,
|
|
1315
|
+
[drawer]: true
|
|
1316
|
+
}
|
|
1317
|
+
})),
|
|
1318
|
+
closeDrawer: (drawer) => set((state) => ({
|
|
1319
|
+
drawers: {
|
|
1320
|
+
...state.drawers,
|
|
1321
|
+
[drawer]: false
|
|
1322
|
+
}
|
|
1323
|
+
})),
|
|
1324
|
+
toggleDrawer: (drawer) => set((state) => ({
|
|
1325
|
+
drawers: {
|
|
1326
|
+
...state.drawers,
|
|
1327
|
+
[drawer]: !state.drawers[drawer]
|
|
1328
|
+
}
|
|
1329
|
+
})),
|
|
1330
|
+
closeAllDrawers: () => set((state) => ({
|
|
1331
|
+
drawers: Object.keys(state.drawers).reduce(
|
|
1332
|
+
(acc, key) => ({ ...acc, [key]: false }),
|
|
1333
|
+
{}
|
|
1334
|
+
)
|
|
1335
|
+
})),
|
|
1336
|
+
modals: {
|
|
1337
|
+
login: false,
|
|
1338
|
+
signup: false
|
|
1339
|
+
},
|
|
1340
|
+
openModal: (modal) => set((state) => ({
|
|
1341
|
+
modals: {
|
|
1342
|
+
...state.modals,
|
|
1343
|
+
login: false,
|
|
1344
|
+
signup: false,
|
|
1345
|
+
[modal]: true
|
|
1346
|
+
}
|
|
1347
|
+
})),
|
|
1348
|
+
closeModal: (modal) => set((state) => ({
|
|
1349
|
+
modals: {
|
|
1350
|
+
...state.modals,
|
|
1351
|
+
login: false,
|
|
1352
|
+
signup: false,
|
|
1353
|
+
[modal]: false
|
|
1354
|
+
}
|
|
1355
|
+
})),
|
|
1356
|
+
toggleModal: (modal) => set((state) => ({
|
|
1357
|
+
modals: {
|
|
1358
|
+
...state.modals,
|
|
1359
|
+
[modal]: !state.modals[modal]
|
|
1360
|
+
}
|
|
1361
|
+
})),
|
|
1362
|
+
closeAllModals: () => set((state) => ({
|
|
1363
|
+
modals: Object.keys(state.modals).reduce(
|
|
1364
|
+
(acc, key) => ({ ...acc, [key]: false }),
|
|
1365
|
+
{}
|
|
1366
|
+
)
|
|
1367
|
+
}))
|
|
1368
|
+
})
|
|
1369
|
+
);
|
|
1370
|
+
var useCart2 = create()(
|
|
1371
|
+
persist(
|
|
1372
|
+
(set) => ({
|
|
1373
|
+
count: 0,
|
|
1374
|
+
cart: [],
|
|
1375
|
+
cartTokenId: null,
|
|
1376
|
+
setCartTokenId: (token) => set((state) => ({ ...state, cartTokenId: token })),
|
|
1377
|
+
checkoutStep: null,
|
|
1378
|
+
setCheckoutStep: (step) => set((state) => ({ ...state, checkoutStep: step })),
|
|
1379
|
+
checkoutCustomerLocal: null,
|
|
1380
|
+
setCheckoutCustomerLocal: (customer) => set((state) => {
|
|
1381
|
+
if (!state.cartTokenId) return state;
|
|
1382
|
+
return {
|
|
1383
|
+
checkoutCustomerLocal: {
|
|
1384
|
+
cartTokenId: state.cartTokenId,
|
|
1385
|
+
customer
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
}),
|
|
1389
|
+
clearCheckoutCustomerLocal: () => set(() => ({ checkoutCustomerLocal: null })),
|
|
1390
|
+
addCart: (item) => set((state) => {
|
|
1391
|
+
const existingItem = state.cart.find(
|
|
1392
|
+
(cartItem) => cartItem.id === item.id
|
|
1393
|
+
);
|
|
1394
|
+
if (existingItem) {
|
|
1395
|
+
const newQuantity = Math.max(0, existingItem.quantity) + 1;
|
|
1396
|
+
const cart2 = state.cart.map(
|
|
1397
|
+
(cartItem) => cartItem.id === item.id ? { ...cartItem, quantity: newQuantity } : cartItem
|
|
1398
|
+
);
|
|
1399
|
+
const count2 = cart2.reduce((sum, i) => sum + Math.max(0, i.quantity), 0);
|
|
1400
|
+
return { count: count2, cart: cart2 };
|
|
1401
|
+
}
|
|
1402
|
+
const newItem = {
|
|
1403
|
+
...item,
|
|
1404
|
+
quantity: Math.max(1, Math.max(0, item.quantity ?? 1))
|
|
1405
|
+
};
|
|
1406
|
+
const cart = [...state.cart, newItem];
|
|
1407
|
+
const count = cart.reduce((sum, i) => sum + Math.max(0, i.quantity), 0);
|
|
1408
|
+
return { count, cart };
|
|
1409
|
+
}),
|
|
1410
|
+
removeCart: (id) => set((state) => {
|
|
1411
|
+
const existingItem = state.cart.find((item) => item.id === id);
|
|
1412
|
+
if (!existingItem) return state;
|
|
1413
|
+
if (existingItem.quantity > 1) {
|
|
1414
|
+
const newQuantity = Math.max(0, existingItem.quantity - 1);
|
|
1415
|
+
const cart2 = state.cart.map(
|
|
1416
|
+
(cartItem) => cartItem.id === id ? { ...cartItem, quantity: newQuantity } : cartItem
|
|
1417
|
+
);
|
|
1418
|
+
const count2 = cart2.reduce((sum, i) => sum + Math.max(0, i.quantity), 0);
|
|
1419
|
+
return { count: count2, cart: cart2 };
|
|
1420
|
+
}
|
|
1421
|
+
const cart = state.cart.filter((item) => item.id !== id);
|
|
1422
|
+
const count = Math.max(0, cart.reduce((sum, i) => sum + Math.max(0, i.quantity), 0));
|
|
1423
|
+
return { count, cart };
|
|
1424
|
+
}),
|
|
1425
|
+
clearCartSession: () => set(() => ({
|
|
1426
|
+
count: 0,
|
|
1427
|
+
cart: [],
|
|
1428
|
+
cartTokenId: null,
|
|
1429
|
+
checkoutStep: null,
|
|
1430
|
+
checkoutCustomerLocal: null
|
|
1431
|
+
}))
|
|
1432
|
+
}),
|
|
1433
|
+
{ name: "cart-storage" }
|
|
1434
|
+
)
|
|
1435
|
+
);
|
|
1436
|
+
init_store_api_client();
|
|
1437
|
+
function EcomiqProvider({
|
|
1438
|
+
store,
|
|
1439
|
+
authClient,
|
|
1440
|
+
children,
|
|
1441
|
+
withShellUi = false
|
|
1442
|
+
}) {
|
|
1443
|
+
useStore.setState({ data: store ?? null });
|
|
1444
|
+
useEffect(() => {
|
|
1445
|
+
setClientStoreId(store?.store.id ?? null);
|
|
1446
|
+
return () => setClientStoreId(null);
|
|
1447
|
+
}, [store]);
|
|
1448
|
+
const [queryClient] = useState(() => new QueryClient());
|
|
1449
|
+
const tree = /* @__PURE__ */ jsxs(QueryClientProvider, { client: queryClient, children: [
|
|
1450
|
+
children,
|
|
1451
|
+
withShellUi ? /* @__PURE__ */ jsx(EcomiqShellUi2, {}) : null
|
|
1452
|
+
] });
|
|
1453
|
+
if (!authClient) return tree;
|
|
1454
|
+
return /* @__PURE__ */ jsx(StorefrontAuthProvider, { authClient, children: tree });
|
|
1455
|
+
}
|
|
1456
|
+
function EcomiqShellUi2() {
|
|
1457
|
+
const [ui, setUi] = useState(null);
|
|
1458
|
+
useEffect(() => {
|
|
1459
|
+
void Promise.resolve().then(() => (init_ecomiq_shell_ui(), ecomiq_shell_ui_exports)).then((mod) => setUi(() => mod.EcomiqShellUi));
|
|
1460
|
+
}, []);
|
|
1461
|
+
return ui ? React2.createElement(ui) : null;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
// src/core/constants/storefront-ecomiq-oauth-cookie.ts
|
|
1465
|
+
var STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME = "ecomiq_sf_oauth_at";
|
|
1466
|
+
var STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH = "/api/store";
|
|
1467
|
+
|
|
1468
|
+
// src/react/auth/ecomiq-oauth-password-constants.ts
|
|
1469
|
+
var PLUGIN_ID = "ecomiq-oauth-password";
|
|
1470
|
+
var ECOMIQ_OAUTH_TOKEN_URL = "https://auth.ecomiq.pe/connect/token";
|
|
1471
|
+
var ECOMIQ_OAUTH_USERINFO_URL = "https://auth.ecomiq.pe/connect/userinfo";
|
|
1472
|
+
var tokenResponseSchema = z.object({
|
|
1473
|
+
access_token: z.string().min(1),
|
|
1474
|
+
token_type: z.string().optional(),
|
|
1475
|
+
/** Segundos hasta expiración (Ecomiq envía ej. `86399`). Sincroniza la sesión Better Auth con el bearer. */
|
|
1476
|
+
expires_in: z.coerce.number().int().positive().optional()
|
|
1477
|
+
});
|
|
1478
|
+
var userInfoSchema = z.object({
|
|
1479
|
+
sub: z.string(),
|
|
1480
|
+
email: z.string().email().optional(),
|
|
1481
|
+
family_name: z.string().optional(),
|
|
1482
|
+
given_name: z.string().optional(),
|
|
1483
|
+
iss: z.string().optional(),
|
|
1484
|
+
aud: z.union([z.string(), z.array(z.string())]).optional()
|
|
1485
|
+
});
|
|
1486
|
+
var signInBody = z.object({
|
|
1487
|
+
email: z.string().email(),
|
|
1488
|
+
password: z.string().min(1),
|
|
1489
|
+
callbackURL: z.string().optional(),
|
|
1490
|
+
rememberMe: z.boolean().optional().default(true)
|
|
1491
|
+
});
|
|
1492
|
+
|
|
1493
|
+
// src/react/auth/ecomiq-oauth-password-plugin.ts
|
|
1494
|
+
function ecomiqOAuthPassword() {
|
|
1495
|
+
const secureCookie = true;
|
|
1496
|
+
const clearStorefrontOAuthCookieMiddleware = createAuthMiddleware(async (ctx) => {
|
|
1497
|
+
ctx.setCookie(STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME, "", {
|
|
1498
|
+
path: STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH,
|
|
1499
|
+
httpOnly: true,
|
|
1500
|
+
sameSite: "lax",
|
|
1501
|
+
secure: secureCookie,
|
|
1502
|
+
maxAge: 0
|
|
1503
|
+
});
|
|
1504
|
+
});
|
|
1505
|
+
return {
|
|
1506
|
+
id: PLUGIN_ID,
|
|
1507
|
+
schema: {
|
|
1508
|
+
user: {
|
|
1509
|
+
fields: {
|
|
1510
|
+
firstName: { type: "string", required: false },
|
|
1511
|
+
lastName: { type: "string", required: false },
|
|
1512
|
+
phone: { type: "string", required: false }
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
},
|
|
1516
|
+
hooks: {
|
|
1517
|
+
after: [
|
|
1518
|
+
{
|
|
1519
|
+
matcher: (hookCtx) => hookCtx.path === "/sign-out",
|
|
1520
|
+
handler: clearStorefrontOAuthCookieMiddleware
|
|
1521
|
+
}
|
|
1522
|
+
]
|
|
1523
|
+
},
|
|
1524
|
+
endpoints: {
|
|
1525
|
+
signIn: createAuthEndpoint(
|
|
1526
|
+
"/ecomiq-oauth/sign-in",
|
|
1527
|
+
{
|
|
1528
|
+
method: "POST",
|
|
1529
|
+
use: [formCsrfMiddleware],
|
|
1530
|
+
body: signInBody
|
|
1531
|
+
},
|
|
1532
|
+
async (ctx) => {
|
|
1533
|
+
const { email: loginEmail, password, callbackURL, rememberMe } = ctx.body;
|
|
1534
|
+
const tokens = await exchangePasswordGrant(loginEmail, password, {
|
|
1535
|
+
identityScope: ctx.getHeader("x-Identity-Scope"),
|
|
1536
|
+
tenantId: ctx.getHeader("x-Tenant-Id"),
|
|
1537
|
+
storeId: ctx.getHeader("x-Store-Id")
|
|
1538
|
+
});
|
|
1539
|
+
const profile = await fetchUserInfo(tokens.access_token);
|
|
1540
|
+
const profileEmail = profile.email?.toLowerCase().trim();
|
|
1541
|
+
const canonicalEmail = profileEmail ?? loginEmail.toLowerCase().trim();
|
|
1542
|
+
if (profileEmail && profileEmail !== loginEmail.toLowerCase().trim()) {
|
|
1543
|
+
throw APIError.from("UNAUTHORIZED", {
|
|
1544
|
+
code: "ECOMIQ_EMAIL_MISMATCH",
|
|
1545
|
+
message: "El correo del perfil OAuth no coincide con el inicio de sesi\xF3n"
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
const displayName = displayNameFromUserInfo(profile, canonicalEmail);
|
|
1549
|
+
const existing = await ctx.context.internalAdapter.findUserByEmail(canonicalEmail);
|
|
1550
|
+
let user = existing?.user;
|
|
1551
|
+
if (!user) {
|
|
1552
|
+
user = await ctx.context.internalAdapter.createUser({
|
|
1553
|
+
email: canonicalEmail,
|
|
1554
|
+
name: displayName,
|
|
1555
|
+
emailVerified: true
|
|
1556
|
+
});
|
|
1557
|
+
} else if (user.name !== displayName) {
|
|
1558
|
+
await ctx.context.internalAdapter.updateUser(user.id, { name: displayName });
|
|
1559
|
+
user = { ...user, name: displayName };
|
|
1560
|
+
}
|
|
1561
|
+
const oauthSessionExpires = tokens.expires_in !== void 0 && tokens.expires_in > 0 ? new Date(Date.now() + tokens.expires_in * 1e3) : void 0;
|
|
1562
|
+
const session = await ctx.context.internalAdapter.createSession(
|
|
1563
|
+
user.id,
|
|
1564
|
+
rememberMe === false,
|
|
1565
|
+
oauthSessionExpires ? { expiresAt: oauthSessionExpires } : {},
|
|
1566
|
+
Boolean(oauthSessionExpires)
|
|
1567
|
+
);
|
|
1568
|
+
if (!session) {
|
|
1569
|
+
throw APIError.from("INTERNAL_SERVER_ERROR", {
|
|
1570
|
+
code: "ECOMIQ_SESSION_FAILED",
|
|
1571
|
+
message: "No se pudo crear la sesi\xF3n"
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
await setSessionCookie(ctx, { session, user }, rememberMe === false);
|
|
1575
|
+
const oauthMaxAgeSec = oauthSessionExpires !== void 0 ? Math.max(60, Math.ceil((oauthSessionExpires.getTime() - Date.now()) / 1e3)) : tokens.expires_in !== void 0 && tokens.expires_in > 0 ? tokens.expires_in : 60 * 60 * 24;
|
|
1576
|
+
await ctx.setCookie(STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME, tokens.access_token, {
|
|
1577
|
+
path: STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH,
|
|
1578
|
+
httpOnly: true,
|
|
1579
|
+
sameSite: "lax",
|
|
1580
|
+
secure: secureCookie,
|
|
1581
|
+
maxAge: oauthMaxAgeSec
|
|
1582
|
+
});
|
|
1583
|
+
if (callbackURL) ctx.setHeader("Location", callbackURL);
|
|
1584
|
+
return ctx.json({
|
|
1585
|
+
redirect: !!callbackURL,
|
|
1586
|
+
token: session.token,
|
|
1587
|
+
url: callbackURL,
|
|
1588
|
+
user: parseUserOutput(ctx.context.options, user)
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
)
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
function displayNameFromUserInfo(profile, fallbackEmail) {
|
|
1596
|
+
const parts = [profile.given_name?.trim(), profile.family_name?.trim()].filter(Boolean);
|
|
1597
|
+
const joined = parts.join(" ").trim();
|
|
1598
|
+
if (joined) return joined;
|
|
1599
|
+
return fallbackEmail.split("@")[0] || "Cliente";
|
|
1600
|
+
}
|
|
1601
|
+
async function fetchUserInfo(accessToken) {
|
|
1602
|
+
const res = await fetch(ECOMIQ_OAUTH_USERINFO_URL, {
|
|
1603
|
+
method: "GET",
|
|
1604
|
+
headers: {
|
|
1605
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1606
|
+
accept: "application/json"
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
const text = await res.text();
|
|
1610
|
+
let json;
|
|
1611
|
+
try {
|
|
1612
|
+
json = text ? JSON.parse(text) : {};
|
|
1613
|
+
} catch {
|
|
1614
|
+
throw APIError.from("UNAUTHORIZED", {
|
|
1615
|
+
code: "ECOMIQ_USERINFO_INVALID_BODY",
|
|
1616
|
+
message: "Respuesta inv\xE1lida del endpoint userinfo"
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
if (!res.ok) {
|
|
1620
|
+
const err = json;
|
|
1621
|
+
throw APIError.from("UNAUTHORIZED", {
|
|
1622
|
+
code: "ECOMIQ_USERINFO_REJECTED",
|
|
1623
|
+
message: err.error_description ?? err.error ?? "No se pudo obtener el perfil del usuario"
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
const parsed = userInfoSchema.safeParse(json);
|
|
1627
|
+
if (!parsed.success) {
|
|
1628
|
+
throw APIError.from("UNAUTHORIZED", {
|
|
1629
|
+
code: "ECOMIQ_USERINFO_SHAPE",
|
|
1630
|
+
message: "Perfil OAuth con formato inv\xE1lido"
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1633
|
+
return parsed.data;
|
|
1634
|
+
}
|
|
1635
|
+
async function exchangePasswordGrant(username, password, context) {
|
|
1636
|
+
const clientId = process.env.ECOMIQ_AUTH_CLIENT_ID ?? "";
|
|
1637
|
+
const clientSecret = process.env.ECOMIQ_AUTH_CLIENT_SECRET ?? "";
|
|
1638
|
+
const scope = process.env.ECOMIQ_AUTH_SCOPE ?? "";
|
|
1639
|
+
if (!clientId || !clientSecret) {
|
|
1640
|
+
throw APIError.from("INTERNAL_SERVER_ERROR", {
|
|
1641
|
+
code: "ECOMIQ_AUTH_NOT_CONFIGURED",
|
|
1642
|
+
message: "OAuth Ecomiq no configurado: ECOMIQ_AUTH_CLIENT_ID y ECOMIQ_AUTH_CLIENT_SECRET."
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
const body = new URLSearchParams({
|
|
1646
|
+
grant_type: "password",
|
|
1647
|
+
username,
|
|
1648
|
+
password,
|
|
1649
|
+
scope,
|
|
1650
|
+
client_id: clientId,
|
|
1651
|
+
client_secret: clientSecret
|
|
1652
|
+
});
|
|
1653
|
+
const identityScope = context.identityScope;
|
|
1654
|
+
const tenantId = context.tenantId;
|
|
1655
|
+
const storeId = context.storeId;
|
|
1656
|
+
const headers3 = new Headers({
|
|
1657
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
1658
|
+
accept: "application/json"
|
|
1659
|
+
});
|
|
1660
|
+
if (identityScope?.trim()) {
|
|
1661
|
+
headers3.set("x-Identity-Scope", identityScope.trim());
|
|
1662
|
+
}
|
|
1663
|
+
if (tenantId?.trim()) {
|
|
1664
|
+
headers3.set("x-Tenant-Id", tenantId.trim());
|
|
1665
|
+
}
|
|
1666
|
+
if (storeId?.trim()) {
|
|
1667
|
+
headers3.set("x-Store-Id", storeId.trim());
|
|
1668
|
+
}
|
|
1669
|
+
let res;
|
|
1670
|
+
let text;
|
|
1671
|
+
try {
|
|
1672
|
+
res = await fetch(ECOMIQ_OAUTH_TOKEN_URL, {
|
|
1673
|
+
method: "POST",
|
|
1674
|
+
headers: headers3,
|
|
1675
|
+
body
|
|
1676
|
+
});
|
|
1677
|
+
text = await res.text();
|
|
1678
|
+
} catch (e) {
|
|
1679
|
+
throw mapTokenEndpointFetchFailure(e);
|
|
1680
|
+
}
|
|
1681
|
+
const json = safeParseJson(text);
|
|
1682
|
+
if (!res.ok) {
|
|
1683
|
+
throwBadRequestFromOAuth(json, res.statusText || text || `HTTP ${res.status}`);
|
|
1684
|
+
}
|
|
1685
|
+
const parsed = tokenResponseSchema.safeParse(json);
|
|
1686
|
+
if (!parsed.success) {
|
|
1687
|
+
throwBadRequestFromOAuth(json, "Token de acceso no recibido");
|
|
1688
|
+
}
|
|
1689
|
+
return parsed.data;
|
|
1690
|
+
}
|
|
1691
|
+
function safeParseJson(text) {
|
|
1692
|
+
try {
|
|
1693
|
+
return text ? JSON.parse(text) : {};
|
|
1694
|
+
} catch {
|
|
1695
|
+
return {};
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
function throwBadRequestFromOAuth(payload, fallbackMessage) {
|
|
1699
|
+
const err = payload;
|
|
1700
|
+
const errorCode = typeof err.error === "string" && err.error.trim() ? err.error.trim() : "invalid_grant";
|
|
1701
|
+
const errorMessage = typeof err.error_description === "string" && err.error_description.trim() ? err.error_description.trim() : typeof err.error === "string" && err.error.trim() ? err.error.trim() : fallbackMessage.trim() || "Credenciales invalidas.";
|
|
1702
|
+
throw APIError.from("BAD_REQUEST", {
|
|
1703
|
+
code: errorCode,
|
|
1704
|
+
message: errorMessage.slice(0, 500)
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
function mapTokenEndpointFetchFailure(e) {
|
|
1708
|
+
const codes = collectNetworkErrorCodes(e);
|
|
1709
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1710
|
+
const isDnsError = codes.some((c) => c === "ENOTFOUND" || c === "EAI_AGAIN");
|
|
1711
|
+
if (isDnsError) {
|
|
1712
|
+
throw APIError.from("BAD_GATEWAY", {
|
|
1713
|
+
code: "ECOMIQ_AUTH_DNS",
|
|
1714
|
+
message: "No se pudo resolver el servidor de autenticacion."
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
const isConnectionRefused = codes.includes("ECONNREFUSED");
|
|
1718
|
+
if (isConnectionRefused) {
|
|
1719
|
+
throw APIError.from("BAD_GATEWAY", {
|
|
1720
|
+
code: "ECOMIQ_AUTH_REFUSED",
|
|
1721
|
+
message: "Conexion rechazada al servidor de autenticacion."
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
const looksLikeAbortOrSocketClose = codes.some(
|
|
1725
|
+
(c) => ["UND_ERR_SOCKET", "ECONNRESET", "EPIPE", "ECONNABORTED"].includes(c)
|
|
1726
|
+
) || /terminated|abort|closed|FIN|socket/i.test(msg);
|
|
1727
|
+
if (looksLikeAbortOrSocketClose) {
|
|
1728
|
+
throwBadRequestFromOAuth({}, "Credenciales invalidas o conexion cerrada por el servidor.");
|
|
1729
|
+
}
|
|
1730
|
+
throw APIError.from("INTERNAL_SERVER_ERROR", {
|
|
1731
|
+
code: "ECOMIQ_AUTH_REQUEST_FAILED",
|
|
1732
|
+
message: msg.slice(0, 280) || "Error al contactar el servidor de autenticacion."
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
function collectNetworkErrorCodes(e) {
|
|
1736
|
+
const out = [];
|
|
1737
|
+
const visit = (x) => {
|
|
1738
|
+
if (!x || typeof x !== "object") return;
|
|
1739
|
+
const code = "code" in x && typeof x.code === "string" ? x.code : void 0;
|
|
1740
|
+
if (code) out.push(code);
|
|
1741
|
+
if ("cause" in x && x.cause) {
|
|
1742
|
+
visit(x.cause);
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
visit(e);
|
|
1746
|
+
return out;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
// src/react/auth/ecomiq-oauth-password-client.ts
|
|
1750
|
+
function ecomiqOAuthPasswordClient() {
|
|
1751
|
+
return {
|
|
1752
|
+
id: PLUGIN_ID,
|
|
1753
|
+
pathMethods: {
|
|
1754
|
+
"/ecomiq-oauth/sign-in": "POST"
|
|
1755
|
+
},
|
|
1756
|
+
atomListeners: [
|
|
1757
|
+
{
|
|
1758
|
+
matcher: (path) => path === "/ecomiq-oauth/sign-in",
|
|
1759
|
+
signal: "$sessionSignal"
|
|
1760
|
+
}
|
|
1761
|
+
]
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
var StorefrontCheckoutSettingsSchema = z.object({
|
|
1765
|
+
allowGuestCheckout: z.boolean().optional(),
|
|
1766
|
+
identityScope: z.enum(["store", "tenant", "global"]).optional(),
|
|
1767
|
+
signInMethods: z.array(z.string()).optional()
|
|
1768
|
+
});
|
|
1769
|
+
var looseRecord = z.record(z.string(), z.unknown());
|
|
1770
|
+
var StorefrontThemeConfigSchema = z.object({
|
|
1771
|
+
name: z.string().nullable().optional(),
|
|
1772
|
+
mode: z.string().nullable().optional(),
|
|
1773
|
+
colors: looseRecord.optional(),
|
|
1774
|
+
fonts: looseRecord.optional(),
|
|
1775
|
+
assets: looseRecord.optional()
|
|
1776
|
+
}).passthrough();
|
|
1777
|
+
var StorefrontFeaturesEnabledSchema = z.object({
|
|
1778
|
+
flags: looseRecord.optional()
|
|
1779
|
+
}).passthrough();
|
|
1780
|
+
var StorefrontCmsBrandingSchema = z.object({
|
|
1781
|
+
logoUrl: z.string().nullable().optional(),
|
|
1782
|
+
logoDarkUrl: z.string().nullable().optional(),
|
|
1783
|
+
faviconUrl: z.string().nullable().optional(),
|
|
1784
|
+
socialImageUrl: z.string().nullable().optional()
|
|
1785
|
+
});
|
|
1786
|
+
var StorefrontCmsSeoSchema = z.object({
|
|
1787
|
+
siteName: z.string().nullable().optional(),
|
|
1788
|
+
metaTitle: z.string().nullable().optional(),
|
|
1789
|
+
metaDescription: z.string().nullable().optional(),
|
|
1790
|
+
titleTemplate: z.string().nullable().optional(),
|
|
1791
|
+
robotsIndex: z.boolean().optional()
|
|
1792
|
+
});
|
|
1793
|
+
var StorefrontCmsSocialLinksSchema = z.object({
|
|
1794
|
+
instagram: z.string().nullable().optional(),
|
|
1795
|
+
facebook: z.string().nullable().optional(),
|
|
1796
|
+
tiktok: z.string().nullable().optional(),
|
|
1797
|
+
youtube: z.string().nullable().optional(),
|
|
1798
|
+
x: z.string().nullable().optional()
|
|
1799
|
+
});
|
|
1800
|
+
var StorefrontCmsContactSchema = z.object({
|
|
1801
|
+
supportEmail: z.string().nullable().optional(),
|
|
1802
|
+
phone: z.string().nullable().optional(),
|
|
1803
|
+
whatsapp: z.string().nullable().optional(),
|
|
1804
|
+
address: z.string().nullable().optional(),
|
|
1805
|
+
socialLinks: StorefrontCmsSocialLinksSchema.optional()
|
|
1806
|
+
});
|
|
1807
|
+
var StorefrontCmsTrackingSchema = z.object({
|
|
1808
|
+
googleAnalyticsMeasurementId: z.string().nullable().optional(),
|
|
1809
|
+
metaPixelId: z.string().nullable().optional(),
|
|
1810
|
+
googleTagManagerContainerId: z.string().nullable().optional()
|
|
1811
|
+
});
|
|
1812
|
+
var StorefrontCmsCustomScriptsSchema = z.object({
|
|
1813
|
+
enabled: z.boolean().optional(),
|
|
1814
|
+
head: z.string().nullable().optional(),
|
|
1815
|
+
bodyEnd: z.string().nullable().optional()
|
|
1816
|
+
});
|
|
1817
|
+
var StorefrontCmsSettingsSchema = z.object({
|
|
1818
|
+
themeKey: z.string().optional(),
|
|
1819
|
+
branding: StorefrontCmsBrandingSchema.optional(),
|
|
1820
|
+
seo: StorefrontCmsSeoSchema.optional(),
|
|
1821
|
+
contact: StorefrontCmsContactSchema.optional(),
|
|
1822
|
+
tracking: StorefrontCmsTrackingSchema.optional(),
|
|
1823
|
+
customScripts: StorefrontCmsCustomScriptsSchema.optional(),
|
|
1824
|
+
updatedOn: z.string().nullable().optional()
|
|
1825
|
+
});
|
|
1826
|
+
var StorefrontCmsPageSchema = z.object({
|
|
1827
|
+
id: z.string(),
|
|
1828
|
+
name: z.string(),
|
|
1829
|
+
slug: z.string(),
|
|
1830
|
+
layout: z.string().optional(),
|
|
1831
|
+
version: z.number().optional(),
|
|
1832
|
+
settings: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
1833
|
+
sections: z.array(z.unknown()).optional(),
|
|
1834
|
+
status: z.string().optional(),
|
|
1835
|
+
hasPublishedVersion: z.boolean().optional(),
|
|
1836
|
+
publishedOn: z.string().nullable().optional(),
|
|
1837
|
+
publishedBy: z.string().nullable().optional(),
|
|
1838
|
+
createdOn: z.string().nullable().optional(),
|
|
1839
|
+
updatedOn: z.string().nullable().optional(),
|
|
1840
|
+
createdBy: z.string().nullable().optional(),
|
|
1841
|
+
updatedBy: z.string().nullable().optional(),
|
|
1842
|
+
lastModifiedBy: z.string().nullable().optional()
|
|
1843
|
+
}).passthrough();
|
|
1844
|
+
var StorefrontSettingsLegacyFlatSchema = z.object({
|
|
1845
|
+
id: z.coerce.string(),
|
|
1846
|
+
tenantId: z.string().nullable().optional(),
|
|
1847
|
+
name: z.string(),
|
|
1848
|
+
slug: z.coerce.string().optional(),
|
|
1849
|
+
description: z.string().nullable().optional(),
|
|
1850
|
+
visibility: z.string().nullable().optional(),
|
|
1851
|
+
logo: z.string().nullable().optional(),
|
|
1852
|
+
favicon: z.string().nullable().optional(),
|
|
1853
|
+
icon: z.string().nullable().optional(),
|
|
1854
|
+
currency: z.string().nullable().optional(),
|
|
1855
|
+
language: z.string().nullable().optional(),
|
|
1856
|
+
themeConfig: z.unknown().optional().nullable(),
|
|
1857
|
+
featuresEnabled: z.unknown().optional().nullable(),
|
|
1858
|
+
checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
|
|
1859
|
+
}).passthrough();
|
|
1860
|
+
function unwrapSettingsResponseBody(v) {
|
|
1861
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return v;
|
|
1862
|
+
const o = v;
|
|
1863
|
+
if ("data" in o && o.data != null && typeof o.data === "object" && !Array.isArray(o.data)) {
|
|
1864
|
+
return o.data;
|
|
1865
|
+
}
|
|
1866
|
+
return v;
|
|
1867
|
+
}
|
|
1868
|
+
function isLegacyFlatSettingsPayload(v) {
|
|
1869
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return false;
|
|
1870
|
+
const o = v;
|
|
1871
|
+
if ("store" in o || "schemaVersion" in o || "cms" in o) return false;
|
|
1872
|
+
return (typeof o.id === "string" || typeof o.id === "number") && typeof o.name === "string";
|
|
1873
|
+
}
|
|
1874
|
+
function normalizeStorefrontSettingsPayload(v) {
|
|
1875
|
+
const body = unwrapSettingsResponseBody(v);
|
|
1876
|
+
if (!isLegacyFlatSettingsPayload(body)) return body;
|
|
1877
|
+
const raw = body;
|
|
1878
|
+
const parsed = StorefrontSettingsLegacyFlatSchema.safeParse(raw);
|
|
1879
|
+
if (!parsed.success) return body;
|
|
1880
|
+
const l = parsed.data;
|
|
1881
|
+
const currency = l.currency?.trim() ? l.currency : "PEN";
|
|
1882
|
+
const language = l.language?.trim() ? l.language : "es";
|
|
1883
|
+
const slug = l.slug?.trim() ? l.slug : l.id;
|
|
1884
|
+
return {
|
|
1885
|
+
schemaVersion: 0,
|
|
1886
|
+
generatedAt: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
1887
|
+
store: {
|
|
1888
|
+
id: l.id,
|
|
1889
|
+
tenantId: l.tenantId ?? void 0,
|
|
1890
|
+
name: l.name,
|
|
1891
|
+
slug,
|
|
1892
|
+
description: l.description ?? null,
|
|
1893
|
+
logo: l.logo ?? null,
|
|
1894
|
+
icon: l.icon ?? null,
|
|
1895
|
+
visibility: l.visibility ?? void 0,
|
|
1896
|
+
currency,
|
|
1897
|
+
language,
|
|
1898
|
+
themeConfig: l.themeConfig ?? void 0,
|
|
1899
|
+
featuresEnabled: l.featuresEnabled ?? void 0,
|
|
1900
|
+
checkoutSettings: l.checkoutSettings ?? void 0
|
|
1901
|
+
},
|
|
1902
|
+
cms: {
|
|
1903
|
+
settings: {
|
|
1904
|
+
branding: {
|
|
1905
|
+
faviconUrl: l.favicon ?? null,
|
|
1906
|
+
logoUrl: l.logo ?? null,
|
|
1907
|
+
logoDarkUrl: null,
|
|
1908
|
+
socialImageUrl: null
|
|
1909
|
+
}
|
|
1910
|
+
},
|
|
1911
|
+
pages: []
|
|
1912
|
+
}
|
|
1913
|
+
};
|
|
1914
|
+
}
|
|
1915
|
+
var StorefrontStoreSchema = z.object({
|
|
1916
|
+
id: z.string(),
|
|
1917
|
+
tenantId: z.string().optional(),
|
|
1918
|
+
sellerId: z.string().optional(),
|
|
1919
|
+
plan: z.string().optional(),
|
|
1920
|
+
storageLimitBytes: z.number().optional(),
|
|
1921
|
+
monthlyTransferLimitBytes: z.number().optional(),
|
|
1922
|
+
maxUploadSizeBytes: z.number().optional(),
|
|
1923
|
+
maxStores: z.number().optional(),
|
|
1924
|
+
maxMembers: z.number().optional(),
|
|
1925
|
+
maxProducts: z.number().optional(),
|
|
1926
|
+
maxCategories: z.number().optional(),
|
|
1927
|
+
maxBrands: z.number().optional(),
|
|
1928
|
+
maxAttributes: z.number().optional(),
|
|
1929
|
+
maxCollections: z.number().optional(),
|
|
1930
|
+
enableApi: z.boolean().optional(),
|
|
1931
|
+
isActive: z.boolean().optional(),
|
|
1932
|
+
name: z.string(),
|
|
1933
|
+
description: z.string().nullable().optional(),
|
|
1934
|
+
avatarUrl: z.string().nullable().optional(),
|
|
1935
|
+
logo: z.string().nullable().optional(),
|
|
1936
|
+
icon: z.string().nullable().optional(),
|
|
1937
|
+
slug: z.string(),
|
|
1938
|
+
domain: z.string().nullable().optional(),
|
|
1939
|
+
domains: z.array(z.string()).optional(),
|
|
1940
|
+
timeZone: z.string().nullable().optional(),
|
|
1941
|
+
currency: z.string(),
|
|
1942
|
+
language: z.string(),
|
|
1943
|
+
visibility: z.string().optional(),
|
|
1944
|
+
privateAccessHash: z.string().nullable().optional(),
|
|
1945
|
+
privateAccessVersion: z.number().optional(),
|
|
1946
|
+
themeConfig: StorefrontThemeConfigSchema.optional(),
|
|
1947
|
+
featuresEnabled: StorefrontFeaturesEnabledSchema.optional(),
|
|
1948
|
+
checkoutSettings: StorefrontCheckoutSettingsSchema.optional().nullable()
|
|
1949
|
+
}).passthrough();
|
|
1950
|
+
var StorefrontSettingsEnvelopeSchema = z.object({
|
|
1951
|
+
schemaVersion: z.number(),
|
|
1952
|
+
generatedAt: z.string(),
|
|
1953
|
+
store: StorefrontStoreSchema,
|
|
1954
|
+
cms: z.object({
|
|
1955
|
+
settings: StorefrontCmsSettingsSchema,
|
|
1956
|
+
pages: z.array(StorefrontCmsPageSchema)
|
|
1957
|
+
})
|
|
1958
|
+
}).passthrough();
|
|
1959
|
+
var StorefrontSettingsSchema3 = z.preprocess(
|
|
1960
|
+
normalizeStorefrontSettingsPayload,
|
|
1961
|
+
StorefrontSettingsEnvelopeSchema
|
|
1962
|
+
);
|
|
1963
|
+
function storefrontStoreRecord(settings) {
|
|
1964
|
+
return settings?.store ?? null;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
// src/core/lib/ecomiq-oauth-identity.ts
|
|
1968
|
+
function buildEcomiqOAuthIdentityHeaders(settings) {
|
|
1969
|
+
const record = storefrontStoreRecord(settings);
|
|
1970
|
+
if (!record?.id) {
|
|
1971
|
+
throw new Error("Tienda no disponible para iniciar sesi\xF3n");
|
|
1972
|
+
}
|
|
1973
|
+
const checkout = record.checkoutSettings;
|
|
1974
|
+
const identityScope = checkout?.identityScope === "tenant" ? "tenant" : "store";
|
|
1975
|
+
const headers3 = {
|
|
1976
|
+
"x-Identity-Scope": identityScope,
|
|
1977
|
+
"x-Store-Id": record.id
|
|
1978
|
+
};
|
|
1979
|
+
if (record.tenantId) headers3["x-Tenant-Id"] = record.tenantId;
|
|
1980
|
+
return headers3;
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
// src/react/auth/ecomiq-storefront-sign-in.ts
|
|
1984
|
+
async function signInWithEcomiqCredentials2(authClient, settings, credentials) {
|
|
1985
|
+
const response = await authClient.$fetch("/ecomiq-oauth/sign-in", {
|
|
1986
|
+
method: "POST",
|
|
1987
|
+
headers: buildEcomiqOAuthIdentityHeaders(settings),
|
|
1988
|
+
body: credentials
|
|
1989
|
+
});
|
|
1990
|
+
if (response.error) {
|
|
1991
|
+
throw new Error(response.error.message ?? "Error al iniciar sesi\xF3n");
|
|
1992
|
+
}
|
|
1993
|
+
return response;
|
|
1994
|
+
}
|
|
1995
|
+
function isRenderableCmsPage(p) {
|
|
1996
|
+
if (!p.status) return true;
|
|
1997
|
+
return p.status === "published";
|
|
1998
|
+
}
|
|
1999
|
+
function findStorefrontCmsPageBySlug(settings, slug) {
|
|
2000
|
+
const pages = settings?.cms?.pages;
|
|
2001
|
+
if (!pages?.length) return null;
|
|
2002
|
+
const raw = pages.find(
|
|
2003
|
+
(p) => p.slug === slug && isRenderableCmsPage(p)
|
|
2004
|
+
);
|
|
2005
|
+
if (!raw) return null;
|
|
2006
|
+
const parsed = StorefrontPageDetailSchema$1.safeParse(raw);
|
|
2007
|
+
return parsed.success ? parsed.data : null;
|
|
2008
|
+
}
|
|
2009
|
+
function buildOptionGroups(variants) {
|
|
2010
|
+
const map = /* @__PURE__ */ new Map();
|
|
2011
|
+
for (const v of variants) {
|
|
2012
|
+
for (const opt of v.options ?? []) {
|
|
2013
|
+
const key = opt.key;
|
|
2014
|
+
const name = opt.name ?? key;
|
|
2015
|
+
if (!map.has(key)) map.set(key, /* @__PURE__ */ new Map());
|
|
2016
|
+
map.get(key).set(opt.value, name);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
return Array.from(map.entries()).map(([key, valueMap]) => ({
|
|
2020
|
+
key,
|
|
2021
|
+
name: Array.from(valueMap.values())[0] ?? key,
|
|
2022
|
+
values: Array.from(valueMap.keys())
|
|
2023
|
+
}));
|
|
2024
|
+
}
|
|
2025
|
+
function findVariant(variants, selected, hasConfigurableOptions) {
|
|
2026
|
+
if (!hasConfigurableOptions && variants.length > 0) {
|
|
2027
|
+
return variants[0] ?? null;
|
|
2028
|
+
}
|
|
2029
|
+
if (Object.keys(selected).length === 0) return null;
|
|
2030
|
+
for (const v of variants) {
|
|
2031
|
+
const opts = v.options ?? [];
|
|
2032
|
+
const match = opts.length > 0 && opts.every((o) => selected[o.key] === o.value);
|
|
2033
|
+
if (match) return v;
|
|
2034
|
+
}
|
|
2035
|
+
return null;
|
|
2036
|
+
}
|
|
2037
|
+
function getInitialOptions(variants, optionGroups) {
|
|
2038
|
+
const first = variants[0];
|
|
2039
|
+
if (!first) return {};
|
|
2040
|
+
const opts = first.options ?? [];
|
|
2041
|
+
const selected = {};
|
|
2042
|
+
for (const g of optionGroups) {
|
|
2043
|
+
const o = opts.find((x) => x.key === g.key);
|
|
2044
|
+
if (o) selected[g.key] = o.value;
|
|
2045
|
+
}
|
|
2046
|
+
return selected;
|
|
2047
|
+
}
|
|
2048
|
+
function ProductVariantSelector({
|
|
2049
|
+
product,
|
|
2050
|
+
currency = "USD",
|
|
2051
|
+
features = [],
|
|
2052
|
+
onVariantChange,
|
|
2053
|
+
children
|
|
2054
|
+
}) {
|
|
2055
|
+
const variants = useMemo(() => product.variants ?? [], [product.variants]);
|
|
2056
|
+
const optionGroups = useMemo(() => buildOptionGroups(variants), [variants]);
|
|
2057
|
+
const hasConfigurableOptions = optionGroups.length > 0;
|
|
2058
|
+
const [selectedOptions, setSelectedOptions] = useState(
|
|
2059
|
+
() => getInitialOptions(variants, optionGroups)
|
|
2060
|
+
);
|
|
2061
|
+
const selectedVariant = useMemo(
|
|
2062
|
+
() => findVariant(variants, selectedOptions, hasConfigurableOptions),
|
|
2063
|
+
[variants, selectedOptions, hasConfigurableOptions]
|
|
2064
|
+
);
|
|
2065
|
+
const displayPrice = selectedVariant?.price ?? product.price ?? 0;
|
|
2066
|
+
const compareAtPrice = selectedVariant?.compareAtPrice ?? product.compareAtPrice;
|
|
2067
|
+
const isAvailable = (selectedVariant ? (selectedVariant.quantity ?? 0) > 0 : product.isAvailable) ?? true;
|
|
2068
|
+
useEffect(() => {
|
|
2069
|
+
onVariantChange?.(selectedVariant, displayPrice);
|
|
2070
|
+
}, [selectedVariant, displayPrice, onVariantChange]);
|
|
2071
|
+
const setOption = useCallback((key, value) => {
|
|
2072
|
+
setSelectedOptions((prev) => ({ ...prev, [key]: value }));
|
|
2073
|
+
}, []);
|
|
2074
|
+
const hasVariants = hasConfigurableOptions;
|
|
2075
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
2076
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2 flex-wrap", children: [
|
|
2077
|
+
/* @__PURE__ */ jsx(
|
|
2078
|
+
"span",
|
|
2079
|
+
{
|
|
2080
|
+
className: "inline-flex items-center rounded-md bg-primary/10 px-2.5 py-0.5 text-base font-semibold text-primary",
|
|
2081
|
+
"data-testid": "product-display-price",
|
|
2082
|
+
children: formatCurrency(displayPrice, currency)
|
|
2083
|
+
}
|
|
2084
|
+
),
|
|
2085
|
+
compareAtPrice != null && compareAtPrice > displayPrice && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground line-through", children: formatCurrency(compareAtPrice, currency) })
|
|
2086
|
+
] }),
|
|
2087
|
+
hasVariants && optionGroups.map((group) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2088
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: group.name }),
|
|
2089
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: group.values.map((value) => {
|
|
2090
|
+
const isSelected = selectedOptions[group.key] === value;
|
|
2091
|
+
const isColorLike = group.key.toLowerCase().includes("color") || group.key.toLowerCase().includes("colour");
|
|
2092
|
+
return /* @__PURE__ */ jsx(
|
|
2093
|
+
"button",
|
|
2094
|
+
{
|
|
2095
|
+
type: "button",
|
|
2096
|
+
onClick: () => setOption(group.key, value),
|
|
2097
|
+
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"}`,
|
|
2098
|
+
style: isColorLike && isSelected && value.toLowerCase() === "black" ? { backgroundColor: "#1a1a1a", borderColor: "#1a1a1a", color: "#fff" } : isColorLike && value.toLowerCase() === "white" ? { backgroundColor: "#fafafa", color: "#1a1a1a", borderColor: "#e5e5e5" } : void 0,
|
|
2099
|
+
"data-testid": `variant-option-${group.key}-${value}`,
|
|
2100
|
+
children: value
|
|
2101
|
+
},
|
|
2102
|
+
value
|
|
2103
|
+
);
|
|
2104
|
+
}) })
|
|
2105
|
+
] }, group.key)),
|
|
2106
|
+
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)) }),
|
|
2107
|
+
children?.({
|
|
2108
|
+
product,
|
|
2109
|
+
selectedVariant,
|
|
2110
|
+
displayPrice,
|
|
2111
|
+
compareAtPrice,
|
|
2112
|
+
isAvailable,
|
|
2113
|
+
selectedOptions
|
|
2114
|
+
})
|
|
2115
|
+
] });
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
// src/core/constants/api-paths.ts
|
|
2119
|
+
var STOREFRONT_API_PATH_PREFIX = "v1";
|
|
2120
|
+
|
|
2121
|
+
// src/core/constants/currency.ts
|
|
2122
|
+
var countryCurrency = {
|
|
2123
|
+
"PEN": "es-PE",
|
|
2124
|
+
"USD": "en-US",
|
|
2125
|
+
"COP": "es-CO",
|
|
2126
|
+
"MXN": "es-MX"
|
|
2127
|
+
};
|
|
2128
|
+
|
|
2129
|
+
// src/core/utils/format-currency.ts
|
|
2130
|
+
function formatCurrency2(amount, currency = "USD") {
|
|
2131
|
+
const locale = countryCurrency[currency] ?? "en-US";
|
|
2132
|
+
return new Intl.NumberFormat(locale, {
|
|
2133
|
+
style: "currency",
|
|
2134
|
+
currency
|
|
2135
|
+
}).format(amount);
|
|
2136
|
+
}
|
|
2137
|
+
var ApiClient = class {
|
|
2138
|
+
client;
|
|
2139
|
+
storeId;
|
|
2140
|
+
storeDomain;
|
|
2141
|
+
constructor(baseURL = "https://storefront.ecomiq.pe") {
|
|
2142
|
+
this.client = axios.create({
|
|
2143
|
+
baseURL,
|
|
2144
|
+
timeout: 1e4,
|
|
2145
|
+
headers: {
|
|
2146
|
+
"Content-Type": "application/json"
|
|
2147
|
+
}
|
|
2148
|
+
});
|
|
2149
|
+
this.client.interceptors.request.use(
|
|
2150
|
+
(config) => {
|
|
2151
|
+
if (config.headers) {
|
|
2152
|
+
if (this.storeId) config.headers["X-Store-Id"] = this.storeId;
|
|
2153
|
+
if (this.storeDomain) config.headers["X-Store-Domain"] = this.storeDomain;
|
|
2154
|
+
}
|
|
2155
|
+
return config;
|
|
2156
|
+
}
|
|
2157
|
+
);
|
|
2158
|
+
this.client.interceptors.response.use(
|
|
2159
|
+
(response) => response,
|
|
2160
|
+
(error) => {
|
|
2161
|
+
console.error("API Error:", error);
|
|
2162
|
+
return Promise.reject(error);
|
|
2163
|
+
}
|
|
2164
|
+
);
|
|
2165
|
+
}
|
|
2166
|
+
setStoreId(storeId) {
|
|
2167
|
+
this.storeId = storeId;
|
|
2168
|
+
}
|
|
2169
|
+
/** Subdominio para endpoints que usan X-Store-Domain (ej. GET /v1/storefront/settings) */
|
|
2170
|
+
setStoreDomain(domain) {
|
|
2171
|
+
this.storeDomain = domain;
|
|
2172
|
+
}
|
|
2173
|
+
get(url, config) {
|
|
2174
|
+
return this.client.get(url, config).then((response) => response.data);
|
|
2175
|
+
}
|
|
2176
|
+
post(url, data, config) {
|
|
2177
|
+
return this.client.post(url, data, config).then((response) => response.data);
|
|
2178
|
+
}
|
|
2179
|
+
put(url, data, config) {
|
|
2180
|
+
return this.client.put(url, data, config).then((response) => response.data);
|
|
2181
|
+
}
|
|
2182
|
+
patch(url, data, config) {
|
|
2183
|
+
return this.client.patch(url, data, config).then((response) => response.data);
|
|
2184
|
+
}
|
|
2185
|
+
delete(url, config) {
|
|
2186
|
+
return this.client.delete(url, config).then((response) => response.data);
|
|
2187
|
+
}
|
|
2188
|
+
};
|
|
2189
|
+
new ApiClient();
|
|
2190
|
+
var ProductVariantSchema = z.object({
|
|
2191
|
+
id: z.coerce.string(),
|
|
2192
|
+
name: z.string(),
|
|
2193
|
+
storeId: z.string(),
|
|
2194
|
+
productId: z.coerce.string(),
|
|
2195
|
+
basePrice: z.number().positive().optional().nullable(),
|
|
2196
|
+
comparePrice: z.number().positive().optional().nullable(),
|
|
2197
|
+
//TODO: remove this field
|
|
2198
|
+
originalPrice: z.number().positive().optional().nullable(),
|
|
2199
|
+
costPrice: z.number().positive().optional().nullable(),
|
|
2200
|
+
isDefault: z.boolean().optional().nullable(),
|
|
2201
|
+
reserveStock: z.number().nonnegative().optional().nullable(),
|
|
2202
|
+
weight: z.number().nonnegative().optional().nullable().default(0),
|
|
2203
|
+
width: z.number().nonnegative().optional().nullable(),
|
|
2204
|
+
height: z.number().nonnegative().optional().nullable(),
|
|
2205
|
+
unitOfMeasure: z.string().optional().nullable(),
|
|
2206
|
+
order: z.number().nonnegative().optional().nullable().default(0),
|
|
2207
|
+
sku: z.string().optional().nullable(),
|
|
2208
|
+
stock: z.number().nonnegative().optional().nullable(),
|
|
2209
|
+
leadTime: z.string().optional().nullable(),
|
|
2210
|
+
barCode: z.string().optional().nullable(),
|
|
2211
|
+
shippingWeight: z.number().nonnegative().optional().nullable(),
|
|
2212
|
+
images: z.array(z.string()).optional().nullable(),
|
|
2213
|
+
attributes: z.array(z.string()).optional().nullable(),
|
|
2214
|
+
variantStatus: z.string().optional().nullable(),
|
|
2215
|
+
status: z.string().optional().nullable(),
|
|
2216
|
+
createdOn: z.string().optional().nullable(),
|
|
2217
|
+
updatedOn: z.string().optional().nullable(),
|
|
2218
|
+
deletedOn: z.string().optional().nullable()
|
|
2219
|
+
});
|
|
2220
|
+
var ProductSchema = z.object({
|
|
2221
|
+
id: z.coerce.string(),
|
|
2222
|
+
name: z.string(),
|
|
2223
|
+
images: z.array(z.object({
|
|
2224
|
+
url: z.string().url(),
|
|
2225
|
+
name: z.string().optional(),
|
|
2226
|
+
isPrimary: z.boolean().optional()
|
|
2227
|
+
})),
|
|
2228
|
+
basePrice: z.number().positive().optional(),
|
|
2229
|
+
salePrice: z.number().positive().optional(),
|
|
2230
|
+
slug: z.string(),
|
|
2231
|
+
description: z.string().optional(),
|
|
2232
|
+
categories: z.array(z.object({
|
|
2233
|
+
id: z.coerce.string(),
|
|
2234
|
+
name: z.string(),
|
|
2235
|
+
slug: z.string(),
|
|
2236
|
+
logo: z.string().optional(),
|
|
2237
|
+
icon: z.string().optional()
|
|
2238
|
+
})).optional(),
|
|
2239
|
+
tags: z.array(z.string()).optional(),
|
|
2240
|
+
inStock: z.boolean().optional(),
|
|
2241
|
+
variants: z.array(ProductVariantSchema).optional()
|
|
2242
|
+
});
|
|
2243
|
+
z.object({
|
|
2244
|
+
items: z.array(ProductSchema),
|
|
2245
|
+
meta: z.object({
|
|
2246
|
+
total: z.number().int().positive(),
|
|
2247
|
+
page: z.number().int().positive(),
|
|
2248
|
+
pageSize: z.number().int().positive(),
|
|
2249
|
+
hasNextPage: z.boolean()
|
|
2250
|
+
})
|
|
2251
|
+
});
|
|
2252
|
+
z.object({
|
|
2253
|
+
category: z.string().optional(),
|
|
2254
|
+
search: z.string().optional(),
|
|
2255
|
+
minPrice: z.number().positive().optional(),
|
|
2256
|
+
maxPrice: z.number().positive().optional(),
|
|
2257
|
+
inStock: z.boolean().optional(),
|
|
2258
|
+
sortBy: z.enum(["name", "price", "createdAt"]).optional(),
|
|
2259
|
+
sortOrder: z.enum(["asc", "desc"]).optional(),
|
|
2260
|
+
page: z.number().int().positive().optional(),
|
|
2261
|
+
limit: z.number().int().positive().optional()
|
|
2262
|
+
});
|
|
2263
|
+
var StorefrontProductSchema = z.object({
|
|
2264
|
+
id: z.coerce.string(),
|
|
2265
|
+
name: z.string(),
|
|
2266
|
+
slug: z.string(),
|
|
2267
|
+
productType: z.string().optional().nullable(),
|
|
2268
|
+
imageUrl: z.string().optional().nullable(),
|
|
2269
|
+
price: z.number().nonnegative(),
|
|
2270
|
+
compareAtPrice: z.number().nonnegative().optional().nullable(),
|
|
2271
|
+
variantCount: z.number().int().nonnegative().optional().default(0),
|
|
2272
|
+
isAvailable: z.boolean(),
|
|
2273
|
+
totalInventory: z.number().int().nonnegative(),
|
|
2274
|
+
bundleItemsCount: z.number().int().nonnegative().optional().default(0),
|
|
2275
|
+
brand: z.string().optional().nullable(),
|
|
2276
|
+
category: z.string().optional().nullable(),
|
|
2277
|
+
status: z.string().optional().nullable(),
|
|
2278
|
+
tags: z.array(z.string()).optional().nullable()
|
|
2279
|
+
});
|
|
2280
|
+
var StorefrontFacetSchema = z.object({
|
|
2281
|
+
value: z.string(),
|
|
2282
|
+
count: z.number().int().nonnegative()
|
|
2283
|
+
});
|
|
2284
|
+
var StorefrontProductsResponseSchema2 = z.object({
|
|
2285
|
+
pageIndex: z.number().int().positive(),
|
|
2286
|
+
pageSize: z.number().int().positive(),
|
|
2287
|
+
totalCount: z.number().int().nonnegative(),
|
|
2288
|
+
totalPages: z.number().int().nonnegative(),
|
|
2289
|
+
products: z.array(StorefrontProductSchema),
|
|
2290
|
+
categories: z.array(StorefrontFacetSchema).optional().default([]),
|
|
2291
|
+
brands: z.array(StorefrontFacetSchema).optional().default([]),
|
|
2292
|
+
minPrice: z.number().nonnegative().optional().nullable(),
|
|
2293
|
+
maxPrice: z.number().nonnegative().optional().nullable()
|
|
2294
|
+
});
|
|
2295
|
+
z.object({
|
|
2296
|
+
page: z.number().int().positive().optional().default(1),
|
|
2297
|
+
pageSize: z.number().int().positive().optional().default(20),
|
|
2298
|
+
sort: z.enum(["price_asc", "price_desc", "name_asc", "name_desc", "newest"]).optional().default("price_asc"),
|
|
2299
|
+
sellerId: z.string().optional(),
|
|
2300
|
+
search: z.string().optional(),
|
|
2301
|
+
collection: z.string().optional(),
|
|
2302
|
+
category: z.string().optional(),
|
|
2303
|
+
brand: z.string().optional(),
|
|
2304
|
+
productType: z.string().optional(),
|
|
2305
|
+
inStock: z.boolean().optional(),
|
|
2306
|
+
minPrice: z.number().nonnegative().optional(),
|
|
2307
|
+
maxPrice: z.number().nonnegative().optional()
|
|
2308
|
+
});
|
|
2309
|
+
var StorefrontVariantOptionSchema = z.object({
|
|
2310
|
+
key: z.string(),
|
|
2311
|
+
name: z.string(),
|
|
2312
|
+
value: z.string()
|
|
2313
|
+
});
|
|
2314
|
+
var StorefrontProductImageSchema = z.object({
|
|
2315
|
+
url: z.string(),
|
|
2316
|
+
name: z.string().optional().nullable(),
|
|
2317
|
+
order: z.number().int().nonnegative().optional()
|
|
2318
|
+
});
|
|
2319
|
+
var StorefrontVariantSchema = z.object({
|
|
2320
|
+
id: z.coerce.string().optional().default(""),
|
|
2321
|
+
sku: z.string(),
|
|
2322
|
+
status: z.string().optional().nullable(),
|
|
2323
|
+
price: z.number().nonnegative(),
|
|
2324
|
+
compareAtPrice: z.number().nonnegative().optional().nullable(),
|
|
2325
|
+
quantity: z.number().int().nonnegative(),
|
|
2326
|
+
options: z.array(StorefrontVariantOptionSchema).optional().default([]),
|
|
2327
|
+
images: z.array(StorefrontProductImageSchema).optional().default([])
|
|
2328
|
+
});
|
|
2329
|
+
var StorefrontPriceTierSchema = z.object({
|
|
2330
|
+
variantId: z.coerce.string(),
|
|
2331
|
+
minQuantity: z.number().int().positive(),
|
|
2332
|
+
maxQuantity: z.number().int().positive().optional().nullable(),
|
|
2333
|
+
unitPrice: z.number().nonnegative()
|
|
2334
|
+
});
|
|
2335
|
+
var StorefrontBundleItemSchema = z.object({
|
|
2336
|
+
productId: z.coerce.string(),
|
|
2337
|
+
variantId: z.coerce.string(),
|
|
2338
|
+
productName: z.string(),
|
|
2339
|
+
variantName: z.string().optional().nullable(),
|
|
2340
|
+
sku: z.string().optional().nullable(),
|
|
2341
|
+
brand: z.string().optional().nullable(),
|
|
2342
|
+
imageUrl: z.string().optional().nullable(),
|
|
2343
|
+
quantity: z.number().int(),
|
|
2344
|
+
availableStock: z.number().int().optional().default(0),
|
|
2345
|
+
allowBackorders: z.boolean().optional().default(false),
|
|
2346
|
+
requiresShipping: z.boolean().optional().default(true)
|
|
2347
|
+
});
|
|
2348
|
+
z.object({
|
|
2349
|
+
id: z.coerce.string(),
|
|
2350
|
+
name: z.string(),
|
|
2351
|
+
slug: z.string(),
|
|
2352
|
+
description: z.string().optional().nullable(),
|
|
2353
|
+
productType: z.string().optional().nullable(),
|
|
2354
|
+
status: z.string().optional().nullable(),
|
|
2355
|
+
imageUrl: z.string().optional().nullable(),
|
|
2356
|
+
price: z.number().nonnegative(),
|
|
2357
|
+
compareAtPrice: z.number().nonnegative().optional().nullable(),
|
|
2358
|
+
isAvailable: z.boolean(),
|
|
2359
|
+
totalInventory: z.number().int().nonnegative(),
|
|
2360
|
+
brand: z.string().optional().nullable(),
|
|
2361
|
+
category: z.string().optional().nullable(),
|
|
2362
|
+
categoryId: z.coerce.string().optional().nullable(),
|
|
2363
|
+
tags: z.array(z.string()).optional().nullable(),
|
|
2364
|
+
specifications: z.array(z.record(z.string(), z.unknown())).optional().default([]),
|
|
2365
|
+
variants: z.array(StorefrontVariantSchema).optional().default([]),
|
|
2366
|
+
images: z.array(StorefrontProductImageSchema).optional().default([]),
|
|
2367
|
+
bundleItems: z.array(StorefrontBundleItemSchema).optional().default([]),
|
|
2368
|
+
priceTiers: z.array(StorefrontPriceTierSchema).optional().default([]),
|
|
2369
|
+
createdAt: z.string().optional().nullable(),
|
|
2370
|
+
updatedAt: z.string().optional().nullable()
|
|
2371
|
+
});
|
|
2372
|
+
var StorefrontCollectionSchema = z.object({
|
|
2373
|
+
id: z.coerce.string(),
|
|
2374
|
+
slug: z.string(),
|
|
2375
|
+
name: z.string(),
|
|
2376
|
+
description: z.string().nullable().optional(),
|
|
2377
|
+
imageUrl: z.string().nullable().optional(),
|
|
2378
|
+
type: z.string(),
|
|
2379
|
+
productCount: z.number().int().nonnegative()
|
|
2380
|
+
});
|
|
2381
|
+
z.array(StorefrontCollectionSchema);
|
|
2382
|
+
z.object({
|
|
2383
|
+
id: z.string(),
|
|
2384
|
+
name: z.string(),
|
|
2385
|
+
slug: z.string(),
|
|
2386
|
+
layout: z.string()
|
|
2387
|
+
});
|
|
2388
|
+
var StorefrontPageSeoSchema = z.object({
|
|
2389
|
+
title: z.string().optional(),
|
|
2390
|
+
description: z.string().optional()
|
|
2391
|
+
}).optional();
|
|
2392
|
+
var StorefrontPageSettingsSchema = z.object({
|
|
2393
|
+
seo: StorefrontPageSeoSchema,
|
|
2394
|
+
html: z.string().optional(),
|
|
2395
|
+
title: z.string().optional()
|
|
2396
|
+
}).catchall(z.unknown());
|
|
2397
|
+
var StorefrontPageBlockSchema = z.object({
|
|
2398
|
+
id: z.string(),
|
|
2399
|
+
type: z.string(),
|
|
2400
|
+
order: z.number(),
|
|
2401
|
+
settings: z.record(z.unknown()).optional()
|
|
2402
|
+
});
|
|
2403
|
+
var StorefrontPageSectionSchema = z.object({
|
|
2404
|
+
id: z.string(),
|
|
2405
|
+
type: z.string(),
|
|
2406
|
+
order: z.number(),
|
|
2407
|
+
settings: z.record(z.unknown()).optional(),
|
|
2408
|
+
blocks: z.array(StorefrontPageBlockSchema).optional().default([])
|
|
2409
|
+
});
|
|
2410
|
+
z.object({
|
|
2411
|
+
id: z.string(),
|
|
2412
|
+
name: z.string(),
|
|
2413
|
+
slug: z.string(),
|
|
2414
|
+
layout: z.string(),
|
|
2415
|
+
settings: StorefrontPageSettingsSchema.optional(),
|
|
2416
|
+
sections: z.array(StorefrontPageSectionSchema).optional()
|
|
2417
|
+
});
|
|
2418
|
+
z.object({
|
|
2419
|
+
email: z.string().email(),
|
|
2420
|
+
firstName: z.string().min(1),
|
|
2421
|
+
lastName: z.string().min(1),
|
|
2422
|
+
phone: z.string().min(1)
|
|
2423
|
+
});
|
|
2424
|
+
z.object({
|
|
2425
|
+
currencyCode: z.string(),
|
|
2426
|
+
salesChannelId: z.string(),
|
|
2427
|
+
email: z.string().email()
|
|
2428
|
+
});
|
|
2429
|
+
var CartAddressSchema = z.object({
|
|
2430
|
+
name: z.string().min(1),
|
|
2431
|
+
address1: z.string().min(1),
|
|
2432
|
+
city: z.string().min(1),
|
|
2433
|
+
countryCode: z.string().min(2),
|
|
2434
|
+
company: z.string().nullable().optional(),
|
|
2435
|
+
address2: z.string().nullable().optional(),
|
|
2436
|
+
province: z.string().nullable().optional(),
|
|
2437
|
+
postalCode: z.string().nullable().optional(),
|
|
2438
|
+
district: z.string().nullable().optional(),
|
|
2439
|
+
phone: z.string().nullable().optional(),
|
|
2440
|
+
latitude: z.number().nullable().optional(),
|
|
2441
|
+
longitude: z.number().nullable().optional(),
|
|
2442
|
+
geo: z.object({
|
|
2443
|
+
departmentCode: z.string().nullable().optional(),
|
|
2444
|
+
provinceCode: z.string().nullable().optional(),
|
|
2445
|
+
districtCode: z.string().nullable().optional()
|
|
2446
|
+
}).nullable().optional()
|
|
2447
|
+
});
|
|
2448
|
+
z.object({
|
|
2449
|
+
shippingAddress: CartAddressSchema,
|
|
2450
|
+
billingAddress: CartAddressSchema
|
|
2451
|
+
});
|
|
2452
|
+
var CartItemModifierRequestSchema = z.object({
|
|
2453
|
+
modifierGroupId: z.coerce.string().min(1),
|
|
2454
|
+
optionIds: z.array(z.coerce.string().min(1)).optional().default([])
|
|
2455
|
+
});
|
|
2456
|
+
z.object({
|
|
2457
|
+
variantId: z.coerce.string().min(1),
|
|
2458
|
+
quantity: z.number().int().positive(),
|
|
2459
|
+
modifiers: z.array(CartItemModifierRequestSchema).optional()
|
|
2460
|
+
});
|
|
2461
|
+
z.object({
|
|
2462
|
+
code: z.string().min(1)
|
|
2463
|
+
});
|
|
2464
|
+
z.object({
|
|
2465
|
+
subtotal: z.number(),
|
|
2466
|
+
discount: z.number(),
|
|
2467
|
+
tax: z.number(),
|
|
2468
|
+
warranty: z.number().optional().default(0),
|
|
2469
|
+
total: z.number()
|
|
2470
|
+
});
|
|
2471
|
+
z.object({
|
|
2472
|
+
name: z.string().nullable().optional(),
|
|
2473
|
+
address1: z.string(),
|
|
2474
|
+
city: z.string(),
|
|
2475
|
+
countryCode: z.string(),
|
|
2476
|
+
company: z.string().nullable().optional(),
|
|
2477
|
+
address2: z.string().nullable().optional(),
|
|
2478
|
+
province: z.string().nullable().optional(),
|
|
2479
|
+
postalCode: z.string().nullable().optional(),
|
|
2480
|
+
district: z.string().nullable().optional(),
|
|
2481
|
+
phone: z.string().nullable().optional(),
|
|
2482
|
+
latitude: z.number().nullable().optional(),
|
|
2483
|
+
longitude: z.number().nullable().optional(),
|
|
2484
|
+
geo: z.object({
|
|
2485
|
+
departmentCode: z.string().nullable().optional(),
|
|
2486
|
+
provinceCode: z.string().nullable().optional(),
|
|
2487
|
+
districtCode: z.string().nullable().optional()
|
|
2488
|
+
}).nullable().optional()
|
|
2489
|
+
});
|
|
2490
|
+
var CartResponseBundleItemSchema = z.object({
|
|
2491
|
+
productId: z.coerce.string(),
|
|
2492
|
+
variantId: z.coerce.string(),
|
|
2493
|
+
productName: z.string(),
|
|
2494
|
+
variantName: z.string().nullable().optional(),
|
|
2495
|
+
sku: z.string().nullable().optional(),
|
|
2496
|
+
brand: z.string().nullable().optional(),
|
|
2497
|
+
imageUrl: z.string().nullable().optional(),
|
|
2498
|
+
quantity: z.number().int()
|
|
2499
|
+
});
|
|
2500
|
+
var CartResponseItemSchema = z.object({
|
|
2501
|
+
id: z.string(),
|
|
2502
|
+
title: z.string(),
|
|
2503
|
+
variantLabel: z.string().nullable().optional(),
|
|
2504
|
+
thumbnail: z.string().nullable().optional(),
|
|
2505
|
+
quantity: z.number().int(),
|
|
2506
|
+
variantId: z.coerce.string(),
|
|
2507
|
+
variantSku: z.string().nullable().optional(),
|
|
2508
|
+
unitPrice: z.number(),
|
|
2509
|
+
bundleItems: z.array(CartResponseBundleItemSchema).optional().default([])
|
|
2510
|
+
});
|
|
2511
|
+
z.object({
|
|
2512
|
+
id: z.string(),
|
|
2513
|
+
name: z.string(),
|
|
2514
|
+
description: z.string().nullable().optional(),
|
|
2515
|
+
total: z.number(),
|
|
2516
|
+
estimatedDays: z.number().int().nullable().optional(),
|
|
2517
|
+
pickupPointId: z.string().nullable().optional(),
|
|
2518
|
+
scheduledDate: z.string().nullable().optional(),
|
|
2519
|
+
scheduledTime: z.string().nullable().optional()
|
|
2520
|
+
});
|
|
2521
|
+
var CartResponseSchema2 = z.object({
|
|
2522
|
+
id: z.string(),
|
|
2523
|
+
regionId: z.string().nullable().optional(),
|
|
2524
|
+
salesChannelId: z.string().nullable().optional(),
|
|
2525
|
+
email: z.string().email().nullable().optional(),
|
|
2526
|
+
phone: z.string().nullable().optional(),
|
|
2527
|
+
firstName: z.string().nullable().optional(),
|
|
2528
|
+
lastName: z.string().nullable().optional(),
|
|
2529
|
+
currencyCode: z.string(),
|
|
2530
|
+
completedAt: z.string().nullable().optional(),
|
|
2531
|
+
shippingAddress: z.unknown().nullable().optional(),
|
|
2532
|
+
billingAddress: z.unknown().nullable().optional(),
|
|
2533
|
+
metadata: z.record(z.string(), z.unknown()).optional().default({}),
|
|
2534
|
+
promotionCodes: z.array(z.string()).optional().default([]),
|
|
2535
|
+
items: z.array(CartResponseItemSchema).optional().default([]),
|
|
2536
|
+
shippingMethods: z.array(z.unknown()).optional().default([]),
|
|
2537
|
+
totals: z.object({
|
|
2538
|
+
discountTotal: z.number(),
|
|
2539
|
+
shippingTotal: z.number(),
|
|
2540
|
+
subtotal: z.number(),
|
|
2541
|
+
taxTotal: z.number(),
|
|
2542
|
+
total: z.number(),
|
|
2543
|
+
warrantyTotal: z.number()
|
|
2544
|
+
})
|
|
2545
|
+
});
|
|
2546
|
+
z.object({
|
|
2547
|
+
paymentMethodCode: z.string().min(1),
|
|
2548
|
+
externalRef: z.string().min(1),
|
|
2549
|
+
receiptUrl: z.string().min(1).optional()
|
|
2550
|
+
});
|
|
2551
|
+
var CartCheckoutPaymentActionSchema = z.object({
|
|
2552
|
+
publicConfiguration: z.object({
|
|
2553
|
+
publishableKey: z.string().nullable().optional(),
|
|
2554
|
+
checkoutMode: z.string().nullable().optional(),
|
|
2555
|
+
phoneNumber: z.string().nullable().optional(),
|
|
2556
|
+
accountHolder: z.string().nullable().optional(),
|
|
2557
|
+
qrImageUrl: z.string().nullable().optional()
|
|
2558
|
+
}).passthrough().nullable().optional(),
|
|
2559
|
+
url: z.string().nullable().optional(),
|
|
2560
|
+
html: z.string().nullable().optional(),
|
|
2561
|
+
clientSecret: z.string().nullable().optional(),
|
|
2562
|
+
qrCode: z.string().nullable().optional(),
|
|
2563
|
+
expiresAt: z.string().nullable().optional()
|
|
2564
|
+
}).passthrough();
|
|
2565
|
+
var CartCheckoutPaymentSchema = z.object({
|
|
2566
|
+
transactionId: z.string(),
|
|
2567
|
+
paymentMethodCode: z.string(),
|
|
2568
|
+
providerId: z.string().nullable().optional(),
|
|
2569
|
+
status: z.string(),
|
|
2570
|
+
amount: z.number(),
|
|
2571
|
+
reference: z.string(),
|
|
2572
|
+
actionType: z.string(),
|
|
2573
|
+
receiptUrl: z.string().nullable().optional(),
|
|
2574
|
+
action: CartCheckoutPaymentActionSchema.nullable().optional()
|
|
2575
|
+
}).passthrough();
|
|
2576
|
+
z.object({
|
|
2577
|
+
publicKey: z.string().optional(),
|
|
2578
|
+
publishableKey: z.string().optional(),
|
|
2579
|
+
stripePublicKey: z.string().optional(),
|
|
2580
|
+
clientSecret: z.string().optional(),
|
|
2581
|
+
intentClientSecret: z.string().optional(),
|
|
2582
|
+
orderId: z.coerce.string().optional(),
|
|
2583
|
+
orderGroup: z.string().optional(),
|
|
2584
|
+
orderIds: z.array(z.coerce.string()).optional(),
|
|
2585
|
+
/** Payload de pago (embedded, redirect, etc.) */
|
|
2586
|
+
payment: CartCheckoutPaymentSchema.optional(),
|
|
2587
|
+
cart: z.unknown().optional()
|
|
2588
|
+
}).passthrough();
|
|
2589
|
+
z.object({
|
|
2590
|
+
id: z.string(),
|
|
2591
|
+
url: z.string()
|
|
2592
|
+
});
|
|
2593
|
+
var CartPaymentMethodSchema = z.object({
|
|
2594
|
+
code: z.string(),
|
|
2595
|
+
name: z.string(),
|
|
2596
|
+
description: z.string().nullable().optional(),
|
|
2597
|
+
kind: z.string(),
|
|
2598
|
+
isActive: z.boolean(),
|
|
2599
|
+
isDefault: z.boolean(),
|
|
2600
|
+
isManual: z.boolean(),
|
|
2601
|
+
sortOrder: z.number(),
|
|
2602
|
+
phoneNumber: z.string().nullable().optional(),
|
|
2603
|
+
accountHolder: z.string().nullable().optional(),
|
|
2604
|
+
qrImageUrl: z.string().nullable().optional()
|
|
2605
|
+
});
|
|
2606
|
+
var CartPaymentMethodsResponseSchema = z.object({
|
|
2607
|
+
methods: z.array(CartPaymentMethodSchema)
|
|
2608
|
+
});
|
|
2609
|
+
z.object({
|
|
2610
|
+
cart: CartResponseSchema2,
|
|
2611
|
+
paymentMethods: CartPaymentMethodsResponseSchema
|
|
2612
|
+
});
|
|
2613
|
+
var ShippingRateSchema = z.object({
|
|
2614
|
+
shippingMethodId: z.string(),
|
|
2615
|
+
name: z.string(),
|
|
2616
|
+
displayName: z.string().optional(),
|
|
2617
|
+
type: z.string().optional(),
|
|
2618
|
+
price: z.number(),
|
|
2619
|
+
currency: z.string().optional(),
|
|
2620
|
+
sortOrder: z.number().optional(),
|
|
2621
|
+
rateId: z.string(),
|
|
2622
|
+
description: z.string().nullable().optional(),
|
|
2623
|
+
deliveryLocationId: z.string().nullable().optional(),
|
|
2624
|
+
deliveryLocationName: z.string().nullable().optional(),
|
|
2625
|
+
estimatedDeliveryDays: z.number().nullable().optional(),
|
|
2626
|
+
serviceCode: z.string().nullable().optional(),
|
|
2627
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
2628
|
+
}).passthrough();
|
|
2629
|
+
var ShippingOptionGroupSchema = z.object({
|
|
2630
|
+
sellerId: z.string(),
|
|
2631
|
+
shippingProfileId: z.string().nullable().optional(),
|
|
2632
|
+
orderAmount: z.number().optional(),
|
|
2633
|
+
totalWeight: z.number().optional(),
|
|
2634
|
+
itemIds: z.array(z.string()).optional(),
|
|
2635
|
+
rates: z.array(ShippingRateSchema)
|
|
2636
|
+
}).passthrough();
|
|
2637
|
+
z.object({
|
|
2638
|
+
groups: z.array(ShippingOptionGroupSchema)
|
|
2639
|
+
});
|
|
2640
|
+
z.object({
|
|
2641
|
+
rateId: z.string().min(1),
|
|
2642
|
+
shippingMethodId: z.string().min(1),
|
|
2643
|
+
serviceCode: z.string().nullable().optional(),
|
|
2644
|
+
sellerId: z.string().nullable().optional(),
|
|
2645
|
+
shippingProfileId: z.string().nullable().optional(),
|
|
2646
|
+
locationId: z.string().nullable().optional(),
|
|
2647
|
+
pickupPointId: z.string().nullable().optional(),
|
|
2648
|
+
scheduledDate: z.string().nullable().optional(),
|
|
2649
|
+
scheduledTime: z.string().nullable().optional()
|
|
2650
|
+
});
|
|
2651
|
+
var CONFIG_FILENAMES = [
|
|
2652
|
+
"ecomiq.config.js",
|
|
2653
|
+
"ecomiq.config.cjs",
|
|
2654
|
+
"ecomiq.config.mjs"
|
|
2655
|
+
];
|
|
2656
|
+
var EcomiqConfigSchema = z.object({
|
|
2657
|
+
/**
|
|
2658
|
+
* Slug de tienda en Ecomiq (p. ej. `mi-tienda` para `mi-tienda.ecomiq.app`).
|
|
2659
|
+
* Si está definido, tiene prioridad sobre el `Host` de la request (útil en `localhost`).
|
|
2660
|
+
*/
|
|
2661
|
+
slugStore: z.string().min(1).optional()
|
|
2662
|
+
});
|
|
2663
|
+
var cachedConfig;
|
|
2664
|
+
function parseExportedConfig(raw) {
|
|
2665
|
+
const candidate = raw && typeof raw === "object" && "default" in raw ? raw.default : raw;
|
|
2666
|
+
const parsed = EcomiqConfigSchema.safeParse(candidate);
|
|
2667
|
+
if (!parsed.success) {
|
|
2668
|
+
console.warn(
|
|
2669
|
+
"[ecomiq] ecomiq.config.* inv\xE1lido:",
|
|
2670
|
+
parsed.error.flatten().fieldErrors
|
|
2671
|
+
);
|
|
2672
|
+
return null;
|
|
1698
2673
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
2674
|
+
const slugStore = parsed.data.slugStore?.trim();
|
|
2675
|
+
return slugStore ? { slugStore } : {};
|
|
2676
|
+
}
|
|
2677
|
+
function loadEcomiqConfig(cwd = process.cwd()) {
|
|
2678
|
+
if (cachedConfig !== void 0) return cachedConfig;
|
|
2679
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
2680
|
+
const configPath = join(cwd, filename);
|
|
2681
|
+
if (!existsSync(configPath)) continue;
|
|
2682
|
+
try {
|
|
2683
|
+
const requireFromApp = createRequire(join(cwd, "package.json"));
|
|
2684
|
+
const loaded = requireFromApp(configPath);
|
|
2685
|
+
const parsed = parseExportedConfig(loaded);
|
|
2686
|
+
cachedConfig = parsed;
|
|
2687
|
+
return cachedConfig;
|
|
2688
|
+
} catch (error) {
|
|
2689
|
+
console.warn(`[ecomiq] No se pudo cargar ${configPath}:`, error);
|
|
2690
|
+
}
|
|
1704
2691
|
}
|
|
2692
|
+
cachedConfig = null;
|
|
1705
2693
|
return null;
|
|
1706
2694
|
}
|
|
1707
|
-
function
|
|
1708
|
-
const
|
|
1709
|
-
if (
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
2695
|
+
function resolvePublicStoreKey(hostHeader, cwd) {
|
|
2696
|
+
const slugFromConfig = loadEcomiqConfig(cwd)?.slugStore?.trim();
|
|
2697
|
+
if (slugFromConfig) return slugFromConfig;
|
|
2698
|
+
if (!hostHeader?.trim()) {
|
|
2699
|
+
throw Object.assign(
|
|
2700
|
+
new Error(
|
|
2701
|
+
"Host is required, o define slugStore en ecomiq.config.js en la ra\xEDz del proyecto"
|
|
2702
|
+
),
|
|
2703
|
+
{ status: 400 }
|
|
2704
|
+
);
|
|
1715
2705
|
}
|
|
1716
|
-
return
|
|
2706
|
+
return resolveStorefrontSettingsHost(hostHeader);
|
|
1717
2707
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
const
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
);
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
2708
|
+
|
|
2709
|
+
// src/core/server/request-origin.ts
|
|
2710
|
+
init_store_api_client();
|
|
2711
|
+
function applyServerRequestOriginFromHeaders(headerList) {
|
|
2712
|
+
const host = headerList.get("host")?.trim();
|
|
2713
|
+
if (!host) return;
|
|
2714
|
+
const proto = headerList.get("x-forwarded-proto") ?? headerList.get("x-forwarded-ssl") ?? "http";
|
|
2715
|
+
const secure = proto === "https" || (headerList.get("x-forwarded-ssl") ?? "") === "on";
|
|
2716
|
+
setServerRequestOrigin(`${secure ? "https" : "http"}://${host}`);
|
|
2717
|
+
}
|
|
2718
|
+
function normalizeRequestHostname(headerList) {
|
|
2719
|
+
const host = headerList.get("host");
|
|
2720
|
+
return host?.replace(/^www\./, "") ?? null;
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
// src/core/server/fetch-public-store.ts
|
|
2724
|
+
init_store_api_client();
|
|
2725
|
+
|
|
2726
|
+
// src/react/shell/lib/public-store-settings-source.ts
|
|
2727
|
+
var ENV_PUBLIC_STORE_SETTINGS_SOURCE = "PUBLIC_STORE_SETTINGS_SOURCE";
|
|
2728
|
+
function resolvePublicStoreSettingsSource(envValue = process.env[ENV_PUBLIC_STORE_SETTINGS_SOURCE]) {
|
|
2729
|
+
const v = (envValue ?? "api").trim().toLowerCase();
|
|
2730
|
+
return v === "kv" ? "kv" : "api";
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
// src/core/server/fetch-public-store.ts
|
|
2734
|
+
async function fetchPublicStoreSettings(options) {
|
|
2735
|
+
let storeKey;
|
|
2736
|
+
try {
|
|
2737
|
+
storeKey = resolvePublicStoreKey(options.host);
|
|
2738
|
+
} catch (error) {
|
|
2739
|
+
const err = error;
|
|
2740
|
+
return {
|
|
2741
|
+
data: null,
|
|
2742
|
+
error: {
|
|
2743
|
+
message: err.message ?? "Host is required",
|
|
2744
|
+
statusCode: err.status ?? 400,
|
|
2745
|
+
isNotFound: true,
|
|
2746
|
+
subdomain: void 0
|
|
2747
|
+
}
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2750
|
+
const source = options.source ?? resolvePublicStoreSettingsSource();
|
|
2751
|
+
try {
|
|
2752
|
+
setServerStoreId(null);
|
|
2753
|
+
const data = source === "kv" ? await getStorefrontSettingsFromKvByStoreKey(storeKey) : await getStorefrontSettings(
|
|
2754
|
+
storeKey,
|
|
2755
|
+
`storefront-settings-${storeKey}`
|
|
2756
|
+
);
|
|
2757
|
+
setServerStoreId(data.store.id);
|
|
2758
|
+
return { data, error: null };
|
|
2759
|
+
} catch (error) {
|
|
2760
|
+
const err = error;
|
|
2761
|
+
const statusCode = err.status ?? 500;
|
|
2762
|
+
return {
|
|
2763
|
+
data: null,
|
|
2764
|
+
error: {
|
|
2765
|
+
message: err.message ?? "Error fetching store settings",
|
|
2766
|
+
statusCode,
|
|
2767
|
+
isNotFound: statusCode === 404,
|
|
2768
|
+
subdomain: storeKey
|
|
2769
|
+
}
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
// src/core/server/store-proxy-handler.ts
|
|
2775
|
+
var DEFAULT_API_BASE_URL = "https://storefront.ecomiq.pe";
|
|
2776
|
+
function jsonError(status, message, error) {
|
|
2777
|
+
return Response.json({ error, message, status }, { status });
|
|
2778
|
+
}
|
|
2779
|
+
async function ensureStoreContext(request) {
|
|
2780
|
+
const xStoreId = request.headers.get("x-store-id")?.trim();
|
|
2781
|
+
const xStoreDomain = request.headers.get("x-store-domain")?.trim();
|
|
2782
|
+
if (xStoreDomain) {
|
|
2783
|
+
return {
|
|
2784
|
+
ok: true,
|
|
2785
|
+
storeId: xStoreId || "",
|
|
2786
|
+
storeDomain: xStoreDomain || null
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
if (!xStoreId) {
|
|
2790
|
+
return {
|
|
2791
|
+
ok: false,
|
|
2792
|
+
response: jsonError(
|
|
2793
|
+
400,
|
|
2794
|
+
"X-Store-Id is required",
|
|
2795
|
+
"Store context required"
|
|
2796
|
+
)
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2799
|
+
return {
|
|
2800
|
+
ok: true,
|
|
2801
|
+
storeId: xStoreId || "",
|
|
2802
|
+
storeDomain: xStoreDomain || null
|
|
2803
|
+
};
|
|
2804
|
+
}
|
|
2805
|
+
var SKIP_FORWARD_HEADERS = /* @__PURE__ */ new Set([
|
|
2806
|
+
"host",
|
|
2807
|
+
"connection",
|
|
2808
|
+
"content-length",
|
|
2809
|
+
"transfer-encoding",
|
|
2810
|
+
"x-store-id",
|
|
2811
|
+
"x-store-domain",
|
|
2812
|
+
"authorization",
|
|
2813
|
+
"cookie",
|
|
2814
|
+
"cookie2",
|
|
2815
|
+
"set-cookie",
|
|
2816
|
+
"x-forwarded-for",
|
|
2817
|
+
"x-forwarded-proto",
|
|
2818
|
+
"x-forwarded-host",
|
|
2819
|
+
"x-real-ip",
|
|
2820
|
+
"forwarded",
|
|
2821
|
+
"cf-connecting-ip",
|
|
2822
|
+
"cf-connecting-ipv6",
|
|
2823
|
+
"true-client-ip",
|
|
2824
|
+
"cf-ipcountry",
|
|
2825
|
+
"cf-ray",
|
|
2826
|
+
"cf-visitor"
|
|
2827
|
+
]);
|
|
2828
|
+
function getClientIp(request) {
|
|
2829
|
+
const candidates = [
|
|
2830
|
+
request.headers.get("cf-connecting-ip"),
|
|
2831
|
+
request.headers.get("true-client-ip"),
|
|
2832
|
+
request.headers.get("x-real-ip")
|
|
2833
|
+
];
|
|
2834
|
+
for (const value of candidates) {
|
|
2835
|
+
const trimmed = value?.trim();
|
|
2836
|
+
if (trimmed) return trimmed;
|
|
2837
|
+
}
|
|
2838
|
+
const xff = request.headers.get("x-forwarded-for");
|
|
2839
|
+
if (xff?.trim()) {
|
|
2840
|
+
const first = xff.split(",")[0]?.trim();
|
|
2841
|
+
if (first) return first;
|
|
2842
|
+
}
|
|
2843
|
+
return null;
|
|
2844
|
+
}
|
|
2845
|
+
function getCookieValue(request, name) {
|
|
2846
|
+
const cookieHeader = request.headers.get("cookie");
|
|
2847
|
+
if (!cookieHeader) return void 0;
|
|
2848
|
+
for (const part of cookieHeader.split(";")) {
|
|
2849
|
+
const [rawKey, ...rest] = part.trim().split("=");
|
|
2850
|
+
if (rawKey?.trim() === name) {
|
|
2851
|
+
return decodeURIComponent(rest.join("="));
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
return void 0;
|
|
2855
|
+
}
|
|
2856
|
+
function buildUpstreamRequest(request, pathSegments, config, storeId, storeDomain) {
|
|
2857
|
+
const requestUrl = new URL(request.url);
|
|
2858
|
+
const base = (config.apiBaseUrl ?? DEFAULT_API_BASE_URL).replace(/\/$/, "");
|
|
2859
|
+
const userPath = pathSegments.length ? pathSegments.join("/") : "";
|
|
2860
|
+
const path = userPath ? `${STOREFRONT_API_PATH_PREFIX}/${userPath}` : STOREFRONT_API_PATH_PREFIX;
|
|
2861
|
+
const search = requestUrl.searchParams.toString();
|
|
2862
|
+
const url = search ? `${base}/${path}?${search}` : `${base}/${path}`;
|
|
2863
|
+
const headers3 = new Headers();
|
|
2864
|
+
request.headers.forEach((value, key) => {
|
|
2865
|
+
const lower = key.toLowerCase();
|
|
2866
|
+
if (!SKIP_FORWARD_HEADERS.has(lower)) {
|
|
2867
|
+
headers3.set(key, value);
|
|
2868
|
+
}
|
|
2869
|
+
});
|
|
2870
|
+
headers3.set("X-Store-Id", storeId);
|
|
2871
|
+
if (storeDomain) {
|
|
2872
|
+
headers3.set("X-Store-domain", storeDomain);
|
|
2873
|
+
}
|
|
2874
|
+
const clientIp = getClientIp(request);
|
|
2875
|
+
if (clientIp) {
|
|
2876
|
+
headers3.set("X-Forwarded-For", clientIp);
|
|
2877
|
+
}
|
|
2878
|
+
const forwardedProto = request.headers.get("cf-visitor")?.match(/"scheme":"(https?)"/)?.[1] ?? requestUrl.protocol.replace(":", "") ?? "https";
|
|
2879
|
+
headers3.set("X-Forwarded-Proto", forwardedProto);
|
|
2880
|
+
const forwardedHost = request.headers.get("host") ?? requestUrl.host;
|
|
2881
|
+
if (forwardedHost) {
|
|
2882
|
+
headers3.set("X-Forwarded-Host", forwardedHost);
|
|
2883
|
+
}
|
|
2884
|
+
const incomingAuth = request.headers.get("authorization")?.trim();
|
|
2885
|
+
const storefrontOAuth = getCookieValue(request, STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME)?.trim();
|
|
2886
|
+
if (incomingAuth && /^Bearer\s+\S+/i.test(incomingAuth)) {
|
|
2887
|
+
headers3.set("Authorization", incomingAuth);
|
|
2888
|
+
} else if (storefrontOAuth) {
|
|
2889
|
+
headers3.set("Authorization", `Bearer ${storefrontOAuth}`);
|
|
2890
|
+
}
|
|
2891
|
+
headers3.set("Accept-Encoding", "identity");
|
|
2892
|
+
const init = {
|
|
2893
|
+
method: request.method,
|
|
2894
|
+
headers: headers3
|
|
2895
|
+
};
|
|
2896
|
+
const bodyMethods = ["POST", "PUT", "PATCH"];
|
|
2897
|
+
if (bodyMethods.includes(request.method) && request.body) {
|
|
2898
|
+
init.body = request.body;
|
|
2899
|
+
init.duplex = "half";
|
|
2900
|
+
}
|
|
2901
|
+
return { url, init };
|
|
2902
|
+
}
|
|
2903
|
+
function isResponseBodyForbidden(status) {
|
|
2904
|
+
return status === 204 || status === 205 || status === 304;
|
|
2905
|
+
}
|
|
2906
|
+
async function handleStoreProxyRequest(request, pathSegments, config = {}) {
|
|
2907
|
+
const storeContext = await ensureStoreContext(request);
|
|
2908
|
+
if (!storeContext.ok) {
|
|
2909
|
+
return storeContext.response;
|
|
2910
|
+
}
|
|
2911
|
+
const { storeId, storeDomain } = storeContext;
|
|
2912
|
+
const { url, init } = buildUpstreamRequest(
|
|
2913
|
+
request,
|
|
2914
|
+
pathSegments,
|
|
2915
|
+
config,
|
|
2916
|
+
storeId,
|
|
2917
|
+
storeDomain
|
|
1734
2918
|
);
|
|
1735
|
-
const
|
|
1736
|
-
const
|
|
1737
|
-
const
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
}
|
|
1754
|
-
),
|
|
1755
|
-
compareAtPrice != null && compareAtPrice > displayPrice && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground line-through", children: formatCurrency(compareAtPrice, currency) })
|
|
1756
|
-
] }),
|
|
1757
|
-
hasVariants && optionGroups.map((group) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1758
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: group.name }),
|
|
1759
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: group.values.map((value) => {
|
|
1760
|
-
const isSelected = selectedOptions[group.key] === value;
|
|
1761
|
-
const isColorLike = group.key.toLowerCase().includes("color") || group.key.toLowerCase().includes("colour");
|
|
1762
|
-
return /* @__PURE__ */ jsx(
|
|
1763
|
-
"button",
|
|
1764
|
-
{
|
|
1765
|
-
type: "button",
|
|
1766
|
-
onClick: () => setOption(group.key, value),
|
|
1767
|
-
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"}`,
|
|
1768
|
-
style: isColorLike && isSelected && value.toLowerCase() === "black" ? { backgroundColor: "#1a1a1a", borderColor: "#1a1a1a", color: "#fff" } : isColorLike && value.toLowerCase() === "white" ? { backgroundColor: "#fafafa", color: "#1a1a1a", borderColor: "#e5e5e5" } : void 0,
|
|
1769
|
-
"data-testid": `variant-option-${group.key}-${value}`,
|
|
1770
|
-
children: value
|
|
1771
|
-
},
|
|
1772
|
-
value
|
|
1773
|
-
);
|
|
1774
|
-
}) })
|
|
1775
|
-
] }, group.key)),
|
|
1776
|
-
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)) }),
|
|
1777
|
-
children?.({
|
|
1778
|
-
product,
|
|
1779
|
-
selectedVariant,
|
|
1780
|
-
displayPrice,
|
|
1781
|
-
compareAtPrice,
|
|
1782
|
-
isAvailable,
|
|
1783
|
-
selectedOptions
|
|
1784
|
-
})
|
|
1785
|
-
] });
|
|
2919
|
+
const upstream = await fetch(url, init);
|
|
2920
|
+
const responseHeaders = new Headers(upstream.headers);
|
|
2921
|
+
const status = upstream.status;
|
|
2922
|
+
if (isResponseBodyForbidden(status)) {
|
|
2923
|
+
responseHeaders.delete("content-length");
|
|
2924
|
+
responseHeaders.delete("content-type");
|
|
2925
|
+
return new Response(null, {
|
|
2926
|
+
status,
|
|
2927
|
+
statusText: upstream.statusText,
|
|
2928
|
+
headers: responseHeaders
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2931
|
+
const body = await upstream.text();
|
|
2932
|
+
return new Response(body, {
|
|
2933
|
+
status,
|
|
2934
|
+
statusText: upstream.statusText,
|
|
2935
|
+
headers: responseHeaders
|
|
2936
|
+
});
|
|
1786
2937
|
}
|
|
1787
2938
|
|
|
1788
|
-
// src/
|
|
2939
|
+
// src/react/frameworks/index.ts
|
|
1789
2940
|
var usePublicStore = () => useStore.getState().data;
|
|
2941
|
+
async function getHostname() {
|
|
2942
|
+
const headerList = await headers();
|
|
2943
|
+
applyServerRequestOriginFromHeaders(headerList);
|
|
2944
|
+
return normalizeRequestHostname(headerList);
|
|
2945
|
+
}
|
|
2946
|
+
async function getPublicStore(options) {
|
|
2947
|
+
const headerList = await headers();
|
|
2948
|
+
applyServerRequestOriginFromHeaders(headerList);
|
|
2949
|
+
return fetchPublicStoreSettings({
|
|
2950
|
+
host: headerList.get("host"),
|
|
2951
|
+
source: options?.source
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2954
|
+
async function getPublicStoreFromHeaders(headerList, options) {
|
|
2955
|
+
applyServerRequestOriginFromHeaders(headerList);
|
|
2956
|
+
return fetchPublicStoreSettings({
|
|
2957
|
+
host: headerList.get("host"),
|
|
2958
|
+
...options
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
1790
2961
|
|
|
1791
|
-
export { CustomerAddressSchema, CustomerAddressUpsertSchema, CustomerMeSchema, CustomerOrderDetailSchema, CustomerOrderListItemSchema, CustomerProfilePatchSchema, CustomerRegisterRequestSchema, ECOMIQ_CLIENTS_STORE_KV_BINDING, EcomiqProvider, ProductVariantSelector, StoreApiClient, addCartCoupon, buildStorefrontKvSnapshotKey, buildStorefrontKvSnapshotKeyFromStoreKey, checkoutCart, createCart, createCustomerAddress, createStoreApiClient, customerMeToProfilePatch, deleteCustomerAddress, findStorefrontCmsPageBySlug, getCart, getCartCheckout, getCartPaymentMethods, getCustomerAddresses, getCustomerMe, getCustomerOrder, getCustomerOrders, getHostname, getPublicStore, getSharedOrderDraft, getShippingOptions, getStoreApiBaseUrl, getStoreApiClient, getStorefrontCollectionBySlug, getStorefrontCollections, getStorefrontPageBySlug, getStorefrontPagePreview, getStorefrontPages, getStorefrontProductBySlug, getStorefrontProducts, getStorefrontSettings, getStorefrontSettingsFromKv, getStorefrontSettingsFromKvByStoreKey, isCartNotActiveApiError, normalizeStoreHost, patchCartAddresses, patchCartBuyer, patchCustomer, putCartShippingMethod, registerCustomer, removeCartCoupon, resolvePublicStoreSettingsSource, resolveStorefrontSettingsHost, setClientStoreId, setServerRequestOrigin, setServerStoreId, signInWithEcomiqCredentials2 as signInWithEcomiqCredentials, storeApiClient, updateCustomerAddress, uploadPaymentReceipt, usePublicStore, useStore, useStoreCart, useStoreCollections, useStorePages, useStoreProducts };
|
|
2962
|
+
export { CustomerAddressSchema, CustomerAddressUpsertSchema, CustomerMeSchema, CustomerOrderDetailSchema, CustomerOrderListItemSchema, CustomerProfilePatchSchema, CustomerRegisterRequestSchema, ECOMIQ_CLIENTS_STORE_KV_BINDING, EcomiqProvider, ProductVariantSelector, QueryProvider, StoreApiClient, StorefrontAuthProvider, StorefrontProductSchema, StorefrontProductsResponseSchema2 as StorefrontProductsResponseSchema, StorefrontSettingsSchema3 as StorefrontSettingsSchema, addCartCoupon, applyServerRequestOriginFromHeaders, buildStorefrontKvSnapshotKey, buildStorefrontKvSnapshotKeyFromStoreKey, checkoutCart, createCart, createCustomerAddress, createStoreApiClient, customerMeToProfilePatch, deleteCustomerAddress, ecomiqOAuthPassword, ecomiqOAuthPasswordClient, fetchPublicStoreSettings, findStorefrontCmsPageBySlug, formatCurrency2 as formatCurrency, getCart, getCartCheckout, getCartPaymentMethods, getCustomerAddresses, getCustomerMe, getCustomerOrder, getCustomerOrders, getHostname, getPublicStore, getPublicStoreFromHeaders, getSharedOrderDraft, getShippingOptions, getStoreApiBaseUrl, getStoreApiClient, getStorefrontCollectionBySlug, getStorefrontCollections, getStorefrontPageBySlug, getStorefrontPagePreview, getStorefrontPages, getStorefrontProductBySlug, getStorefrontProducts, getStorefrontSettings, getStorefrontSettingsFromKv, getStorefrontSettingsFromKvByStoreKey, handleStoreProxyRequest, isCartNotActiveApiError, normalizeStoreHost, patchCartAddresses, patchCartBuyer, patchCustomer, putCartShippingMethod, registerCustomer, removeCartCoupon, resolvePublicStoreSettingsSource, resolveStorefrontSettingsHost, setClientStoreId, setServerRequestOrigin, setServerStoreId, signInWithEcomiqCredentials2 as signInWithEcomiqCredentials, storeApiClient, storefrontAccessTokenNeedsRefresh, storefrontSessionEndsSoon, updateCustomerAddress, uploadPaymentReceipt, useCart2 as useCart, usePublicStore, useStore, useStoreCart, useStoreCollections, useStorePages, useStoreProducts, useStorefrontAuthClient, useStorefrontSession };
|
|
1792
2963
|
//# sourceMappingURL=nextjs.js.map
|
|
1793
2964
|
//# sourceMappingURL=nextjs.js.map
|