@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
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type StoreProxyHandlerConfig = {
|
|
2
|
+
/** Base URL del API de storefront. Default: `https://storefront.ecomiq.pe` */
|
|
3
|
+
apiBaseUrl?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Proxy BFF `/api/store/*` → upstream Ecomiq. Usa Web Fetch API (`Request` / `Response`).
|
|
7
|
+
*/
|
|
8
|
+
declare function handleStoreProxyRequest(request: Request, pathSegments: string[], config?: StoreProxyHandlerConfig): Promise<Response>;
|
|
9
|
+
|
|
10
|
+
export { type StoreProxyHandlerConfig as S, handleStoreProxyRequest as h };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { S as StoreProxyHandlerConfig } from '../store-proxy-handler-CNzKlTFA.js';
|
|
2
|
+
export { h as handleStoreProxyRequest } from '../store-proxy-handler-CNzKlTFA.js';
|
|
3
|
+
|
|
4
|
+
type TanStackStoreApiHandlerConfig = StoreProxyHandlerConfig;
|
|
5
|
+
type TanStackStoreRouteParams = {
|
|
6
|
+
/** Splat de ruta `routes/api/store/$.ts` → `/api/store/products` → `"products"` */
|
|
7
|
+
_splat?: string;
|
|
8
|
+
/** Alternativa si pasas segmentos como string unido */
|
|
9
|
+
path?: string;
|
|
10
|
+
};
|
|
11
|
+
/** Convierte params de TanStack Start a segmentos de path del proxy. */
|
|
12
|
+
declare function tanStackStorePathSegments(params: TanStackStoreRouteParams): string[];
|
|
13
|
+
type TanStackHandlerContext = {
|
|
14
|
+
request: Request;
|
|
15
|
+
params: TanStackStoreRouteParams;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Handlers para server routes de TanStack Start (`routes/api/store/$.ts`).
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { createFileRoute } from "@tanstack/react-router";
|
|
22
|
+
* import { createTanStackStoreApiHandler } from "@ecomiq/storefront/tanstack/api";
|
|
23
|
+
*
|
|
24
|
+
* const storeApi = createTanStackStoreApiHandler({
|
|
25
|
+
* apiBaseUrl: process.env.STOREFRONT_API_URL,
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* export const Route = createFileRoute("/api/store/$")({
|
|
29
|
+
* server: { handlers: storeApi },
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare function createTanStackStoreApiHandler(config?: TanStackStoreApiHandlerConfig): {
|
|
34
|
+
GET: ({ request, params }: TanStackHandlerContext) => Promise<Response>;
|
|
35
|
+
POST: ({ request, params }: TanStackHandlerContext) => Promise<Response>;
|
|
36
|
+
PUT: ({ request, params }: TanStackHandlerContext) => Promise<Response>;
|
|
37
|
+
PATCH: ({ request, params }: TanStackHandlerContext) => Promise<Response>;
|
|
38
|
+
DELETE: ({ request, params }: TanStackHandlerContext) => Promise<Response>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { type TanStackStoreApiHandlerConfig, type TanStackStoreRouteParams, createTanStackStoreApiHandler, tanStackStorePathSegments };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// src/core/constants/api-paths.ts
|
|
2
|
+
var STOREFRONT_API_PATH_PREFIX = "v1";
|
|
3
|
+
|
|
4
|
+
// src/core/constants/storefront-ecomiq-oauth-cookie.ts
|
|
5
|
+
var STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME = "ecomiq_sf_oauth_at";
|
|
6
|
+
|
|
7
|
+
// src/core/server/store-proxy-handler.ts
|
|
8
|
+
var DEFAULT_API_BASE_URL = "https://storefront.ecomiq.pe";
|
|
9
|
+
function jsonError(status, message, error) {
|
|
10
|
+
return Response.json({ error, message, status }, { status });
|
|
11
|
+
}
|
|
12
|
+
async function ensureStoreContext(request) {
|
|
13
|
+
const xStoreId = request.headers.get("x-store-id")?.trim();
|
|
14
|
+
const xStoreDomain = request.headers.get("x-store-domain")?.trim();
|
|
15
|
+
if (xStoreDomain) {
|
|
16
|
+
return {
|
|
17
|
+
ok: true,
|
|
18
|
+
storeId: xStoreId || "",
|
|
19
|
+
storeDomain: xStoreDomain || null
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (!xStoreId) {
|
|
23
|
+
return {
|
|
24
|
+
ok: false,
|
|
25
|
+
response: jsonError(
|
|
26
|
+
400,
|
|
27
|
+
"X-Store-Id is required",
|
|
28
|
+
"Store context required"
|
|
29
|
+
)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
ok: true,
|
|
34
|
+
storeId: xStoreId || "",
|
|
35
|
+
storeDomain: xStoreDomain || null
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
var SKIP_FORWARD_HEADERS = /* @__PURE__ */ new Set([
|
|
39
|
+
"host",
|
|
40
|
+
"connection",
|
|
41
|
+
"content-length",
|
|
42
|
+
"transfer-encoding",
|
|
43
|
+
"x-store-id",
|
|
44
|
+
"x-store-domain",
|
|
45
|
+
"authorization",
|
|
46
|
+
"cookie",
|
|
47
|
+
"cookie2",
|
|
48
|
+
"set-cookie",
|
|
49
|
+
"x-forwarded-for",
|
|
50
|
+
"x-forwarded-proto",
|
|
51
|
+
"x-forwarded-host",
|
|
52
|
+
"x-real-ip",
|
|
53
|
+
"forwarded",
|
|
54
|
+
"cf-connecting-ip",
|
|
55
|
+
"cf-connecting-ipv6",
|
|
56
|
+
"true-client-ip",
|
|
57
|
+
"cf-ipcountry",
|
|
58
|
+
"cf-ray",
|
|
59
|
+
"cf-visitor"
|
|
60
|
+
]);
|
|
61
|
+
function getClientIp(request) {
|
|
62
|
+
const candidates = [
|
|
63
|
+
request.headers.get("cf-connecting-ip"),
|
|
64
|
+
request.headers.get("true-client-ip"),
|
|
65
|
+
request.headers.get("x-real-ip")
|
|
66
|
+
];
|
|
67
|
+
for (const value of candidates) {
|
|
68
|
+
const trimmed = value?.trim();
|
|
69
|
+
if (trimmed) return trimmed;
|
|
70
|
+
}
|
|
71
|
+
const xff = request.headers.get("x-forwarded-for");
|
|
72
|
+
if (xff?.trim()) {
|
|
73
|
+
const first = xff.split(",")[0]?.trim();
|
|
74
|
+
if (first) return first;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
function getCookieValue(request, name) {
|
|
79
|
+
const cookieHeader = request.headers.get("cookie");
|
|
80
|
+
if (!cookieHeader) return void 0;
|
|
81
|
+
for (const part of cookieHeader.split(";")) {
|
|
82
|
+
const [rawKey, ...rest] = part.trim().split("=");
|
|
83
|
+
if (rawKey?.trim() === name) {
|
|
84
|
+
return decodeURIComponent(rest.join("="));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
function buildUpstreamRequest(request, pathSegments, config, storeId, storeDomain) {
|
|
90
|
+
const requestUrl = new URL(request.url);
|
|
91
|
+
const base = (config.apiBaseUrl ?? DEFAULT_API_BASE_URL).replace(/\/$/, "");
|
|
92
|
+
const userPath = pathSegments.length ? pathSegments.join("/") : "";
|
|
93
|
+
const path = userPath ? `${STOREFRONT_API_PATH_PREFIX}/${userPath}` : STOREFRONT_API_PATH_PREFIX;
|
|
94
|
+
const search = requestUrl.searchParams.toString();
|
|
95
|
+
const url = search ? `${base}/${path}?${search}` : `${base}/${path}`;
|
|
96
|
+
const headers = new Headers();
|
|
97
|
+
request.headers.forEach((value, key) => {
|
|
98
|
+
const lower = key.toLowerCase();
|
|
99
|
+
if (!SKIP_FORWARD_HEADERS.has(lower)) {
|
|
100
|
+
headers.set(key, value);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
headers.set("X-Store-Id", storeId);
|
|
104
|
+
if (storeDomain) {
|
|
105
|
+
headers.set("X-Store-domain", storeDomain);
|
|
106
|
+
}
|
|
107
|
+
const clientIp = getClientIp(request);
|
|
108
|
+
if (clientIp) {
|
|
109
|
+
headers.set("X-Forwarded-For", clientIp);
|
|
110
|
+
}
|
|
111
|
+
const forwardedProto = request.headers.get("cf-visitor")?.match(/"scheme":"(https?)"/)?.[1] ?? requestUrl.protocol.replace(":", "") ?? "https";
|
|
112
|
+
headers.set("X-Forwarded-Proto", forwardedProto);
|
|
113
|
+
const forwardedHost = request.headers.get("host") ?? requestUrl.host;
|
|
114
|
+
if (forwardedHost) {
|
|
115
|
+
headers.set("X-Forwarded-Host", forwardedHost);
|
|
116
|
+
}
|
|
117
|
+
const incomingAuth = request.headers.get("authorization")?.trim();
|
|
118
|
+
const storefrontOAuth = getCookieValue(request, STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME)?.trim();
|
|
119
|
+
if (incomingAuth && /^Bearer\s+\S+/i.test(incomingAuth)) {
|
|
120
|
+
headers.set("Authorization", incomingAuth);
|
|
121
|
+
} else if (storefrontOAuth) {
|
|
122
|
+
headers.set("Authorization", `Bearer ${storefrontOAuth}`);
|
|
123
|
+
}
|
|
124
|
+
headers.set("Accept-Encoding", "identity");
|
|
125
|
+
const init = {
|
|
126
|
+
method: request.method,
|
|
127
|
+
headers
|
|
128
|
+
};
|
|
129
|
+
const bodyMethods = ["POST", "PUT", "PATCH"];
|
|
130
|
+
if (bodyMethods.includes(request.method) && request.body) {
|
|
131
|
+
init.body = request.body;
|
|
132
|
+
init.duplex = "half";
|
|
133
|
+
}
|
|
134
|
+
return { url, init };
|
|
135
|
+
}
|
|
136
|
+
function isResponseBodyForbidden(status) {
|
|
137
|
+
return status === 204 || status === 205 || status === 304;
|
|
138
|
+
}
|
|
139
|
+
async function handleStoreProxyRequest(request, pathSegments, config = {}) {
|
|
140
|
+
const storeContext = await ensureStoreContext(request);
|
|
141
|
+
if (!storeContext.ok) {
|
|
142
|
+
return storeContext.response;
|
|
143
|
+
}
|
|
144
|
+
const { storeId, storeDomain } = storeContext;
|
|
145
|
+
const { url, init } = buildUpstreamRequest(
|
|
146
|
+
request,
|
|
147
|
+
pathSegments,
|
|
148
|
+
config,
|
|
149
|
+
storeId,
|
|
150
|
+
storeDomain
|
|
151
|
+
);
|
|
152
|
+
const upstream = await fetch(url, init);
|
|
153
|
+
const responseHeaders = new Headers(upstream.headers);
|
|
154
|
+
const status = upstream.status;
|
|
155
|
+
if (isResponseBodyForbidden(status)) {
|
|
156
|
+
responseHeaders.delete("content-length");
|
|
157
|
+
responseHeaders.delete("content-type");
|
|
158
|
+
return new Response(null, {
|
|
159
|
+
status,
|
|
160
|
+
statusText: upstream.statusText,
|
|
161
|
+
headers: responseHeaders
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const body = await upstream.text();
|
|
165
|
+
return new Response(body, {
|
|
166
|
+
status,
|
|
167
|
+
statusText: upstream.statusText,
|
|
168
|
+
headers: responseHeaders
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/react/frameworks/tanstack/api/store-handler.ts
|
|
173
|
+
function tanStackStorePathSegments(params) {
|
|
174
|
+
const raw = params._splat ?? params.path ?? "";
|
|
175
|
+
return raw.split("/").filter(Boolean);
|
|
176
|
+
}
|
|
177
|
+
function createTanStackStoreApiHandler(config = {}) {
|
|
178
|
+
const handler = async ({ request, params }) => {
|
|
179
|
+
return handleStoreProxyRequest(
|
|
180
|
+
request,
|
|
181
|
+
tanStackStorePathSegments(params),
|
|
182
|
+
config
|
|
183
|
+
);
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
GET: handler,
|
|
187
|
+
POST: handler,
|
|
188
|
+
PUT: handler,
|
|
189
|
+
PATCH: handler,
|
|
190
|
+
DELETE: handler
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export { createTanStackStoreApiHandler, handleStoreProxyRequest, tanStackStorePathSegments };
|
|
195
|
+
//# sourceMappingURL=api.js.map
|
|
196
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/constants/api-paths.ts","../../src/core/constants/storefront-ecomiq-oauth-cookie.ts","../../src/core/server/store-proxy-handler.ts","../../src/react/frameworks/tanstack/api/store-handler.ts"],"names":[],"mappings":"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","file":"api.js","sourcesContent":["/** Prefijo base de la API storefront (ej. v1/storefront). */\nexport const STOREFRONT_API_PATH_PREFIX = \"v1\";\n","/** Cookie HttpOnly con el bearer OAuth storefront; solo path `/api/store` (no navega a todo el sitio). */\nexport const STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME = \"ecomiq_sf_oauth_at\";\n\n/** Debe coincidir con el prefijo de la ruta proxy en Next (`app/api/store/...`). */\nexport const STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH = \"/api/store\";\n","import { STOREFRONT_API_PATH_PREFIX } from \"../constants/api-paths\";\nimport { STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME } from \"../constants/storefront-ecomiq-oauth-cookie\";\n\nconst DEFAULT_API_BASE_URL = \"https://storefront.ecomiq.pe\";\n\nexport type StoreProxyHandlerConfig = {\n /** Base URL del API de storefront. Default: `https://storefront.ecomiq.pe` */\n apiBaseUrl?: string;\n};\n\ntype StoreContextResult =\n | {\n ok: true;\n storeId: string;\n storeDomain: string | null;\n }\n | { ok: false; response: Response };\n\nfunction jsonError(status: number, message: string, error: string): Response {\n return Response.json({ error, message, status }, { status });\n}\n\nasync function ensureStoreContext(request: Request): Promise<StoreContextResult> {\n const xStoreId = request.headers.get(\"x-store-id\")?.trim();\n const xStoreDomain = request.headers.get(\"x-store-domain\")?.trim();\n if (xStoreDomain) {\n return {\n ok: true,\n storeId: xStoreId || \"\",\n storeDomain: xStoreDomain || null,\n };\n }\n if (!xStoreId) {\n return {\n ok: false,\n response: jsonError(\n 400,\n \"X-Store-Id is required\",\n \"Store context required\",\n ),\n };\n }\n\n return {\n ok: true,\n storeId: xStoreId || \"\",\n storeDomain: xStoreDomain || null,\n };\n}\n\nconst SKIP_FORWARD_HEADERS = new Set([\n \"host\",\n \"connection\",\n \"content-length\",\n \"transfer-encoding\",\n \"x-store-id\",\n \"x-store-domain\",\n \"authorization\",\n \"cookie\",\n \"cookie2\",\n \"set-cookie\",\n \"x-forwarded-for\",\n \"x-forwarded-proto\",\n \"x-forwarded-host\",\n \"x-real-ip\",\n \"forwarded\",\n \"cf-connecting-ip\",\n \"cf-connecting-ipv6\",\n \"true-client-ip\",\n \"cf-ipcountry\",\n \"cf-ray\",\n \"cf-visitor\",\n]);\n\nfunction getClientIp(request: Request): string | null {\n const candidates = [\n request.headers.get(\"cf-connecting-ip\"),\n request.headers.get(\"true-client-ip\"),\n request.headers.get(\"x-real-ip\"),\n ];\n for (const value of candidates) {\n const trimmed = value?.trim();\n if (trimmed) return trimmed;\n }\n const xff = request.headers.get(\"x-forwarded-for\");\n if (xff?.trim()) {\n const first = xff.split(\",\")[0]?.trim();\n if (first) return first;\n }\n return null;\n}\n\nfunction getCookieValue(request: Request, name: string): string | undefined {\n const cookieHeader = request.headers.get(\"cookie\");\n if (!cookieHeader) return undefined;\n for (const part of cookieHeader.split(\";\")) {\n const [rawKey, ...rest] = part.trim().split(\"=\");\n if (rawKey?.trim() === name) {\n return decodeURIComponent(rest.join(\"=\"));\n }\n }\n return undefined;\n}\n\nfunction buildUpstreamRequest(\n request: Request,\n pathSegments: string[],\n config: StoreProxyHandlerConfig,\n storeId: string,\n storeDomain: string | null,\n): { url: string; init: RequestInit & { duplex?: \"half\" } } {\n const requestUrl = new URL(request.url);\n const base = (config.apiBaseUrl ?? DEFAULT_API_BASE_URL).replace(/\\/$/, \"\");\n const userPath = pathSegments.length ? pathSegments.join(\"/\") : \"\";\n const path = userPath\n ? `${STOREFRONT_API_PATH_PREFIX}/${userPath}`\n : STOREFRONT_API_PATH_PREFIX;\n const search = requestUrl.searchParams.toString();\n const url = search ? `${base}/${path}?${search}` : `${base}/${path}`;\n\n const headers = new Headers();\n request.headers.forEach((value, key) => {\n const lower = key.toLowerCase();\n if (!SKIP_FORWARD_HEADERS.has(lower)) {\n headers.set(key, value);\n }\n });\n headers.set(\"X-Store-Id\", storeId);\n if (storeDomain) {\n headers.set(\"X-Store-domain\", storeDomain);\n }\n\n const clientIp = getClientIp(request);\n if (clientIp) {\n headers.set(\"X-Forwarded-For\", clientIp);\n }\n const forwardedProto =\n request.headers.get(\"cf-visitor\")?.match(/\"scheme\":\"(https?)\"/)?.[1] ??\n requestUrl.protocol.replace(\":\", \"\") ??\n \"https\";\n headers.set(\"X-Forwarded-Proto\", forwardedProto);\n const forwardedHost = request.headers.get(\"host\") ?? requestUrl.host;\n if (forwardedHost) {\n headers.set(\"X-Forwarded-Host\", forwardedHost);\n }\n\n const incomingAuth = request.headers.get(\"authorization\")?.trim();\n const storefrontOAuth = getCookieValue(request, STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME)?.trim();\n\n if (incomingAuth && /^Bearer\\s+\\S+/i.test(incomingAuth)) {\n headers.set(\"Authorization\", incomingAuth);\n } else if (storefrontOAuth) {\n headers.set(\"Authorization\", `Bearer ${storefrontOAuth}`);\n }\n headers.set(\"Accept-Encoding\", \"identity\");\n\n const init: RequestInit & { duplex?: \"half\" } = {\n method: request.method,\n headers,\n };\n\n const bodyMethods = [\"POST\", \"PUT\", \"PATCH\"];\n if (bodyMethods.includes(request.method) && request.body) {\n init.body = request.body;\n init.duplex = \"half\";\n }\n\n return { url, init };\n}\n\nfunction isResponseBodyForbidden(status: number): boolean {\n return status === 204 || status === 205 || status === 304;\n}\n\n/**\n * Proxy BFF `/api/store/*` → upstream Ecomiq. Usa Web Fetch API (`Request` / `Response`).\n */\nexport async function handleStoreProxyRequest(\n request: Request,\n pathSegments: string[],\n config: StoreProxyHandlerConfig = {},\n): Promise<Response> {\n const storeContext = await ensureStoreContext(request);\n if (!storeContext.ok) {\n return storeContext.response;\n }\n\n const { storeId, storeDomain } = storeContext;\n const { url, init } = buildUpstreamRequest(\n request,\n pathSegments,\n config,\n storeId,\n storeDomain,\n );\n\n const upstream = await fetch(url, init);\n const responseHeaders = new Headers(upstream.headers);\n const status = upstream.status;\n\n if (isResponseBodyForbidden(status)) {\n responseHeaders.delete(\"content-length\");\n responseHeaders.delete(\"content-type\");\n return new Response(null, {\n status,\n statusText: upstream.statusText,\n headers: responseHeaders,\n });\n }\n\n const body = await upstream.text();\n return new Response(body, {\n status,\n statusText: upstream.statusText,\n headers: responseHeaders,\n });\n}\n","import {\n handleStoreProxyRequest,\n type StoreProxyHandlerConfig,\n} from \"../../../../core/server/store-proxy-handler\";\n\nexport type TanStackStoreApiHandlerConfig = StoreProxyHandlerConfig;\n\nexport type TanStackStoreRouteParams = {\n /** Splat de ruta `routes/api/store/$.ts` → `/api/store/products` → `\"products\"` */\n _splat?: string;\n /** Alternativa si pasas segmentos como string unido */\n path?: string;\n};\n\n/** Convierte params de TanStack Start a segmentos de path del proxy. */\nexport function tanStackStorePathSegments(\n params: TanStackStoreRouteParams,\n): string[] {\n const raw = params._splat ?? params.path ?? \"\";\n return raw.split(\"/\").filter(Boolean);\n}\n\ntype TanStackHandlerContext = {\n request: Request;\n params: TanStackStoreRouteParams;\n};\n\n/**\n * Handlers para server routes de TanStack Start (`routes/api/store/$.ts`).\n *\n * ```ts\n * import { createFileRoute } from \"@tanstack/react-router\";\n * import { createTanStackStoreApiHandler } from \"@ecomiq/storefront/tanstack/api\";\n *\n * const storeApi = createTanStackStoreApiHandler({\n * apiBaseUrl: process.env.STOREFRONT_API_URL,\n * });\n *\n * export const Route = createFileRoute(\"/api/store/$\")({\n * server: { handlers: storeApi },\n * });\n * ```\n */\nexport function createTanStackStoreApiHandler(\n config: TanStackStoreApiHandlerConfig = {},\n) {\n const handler = async ({ request, params }: TanStackHandlerContext) => {\n return handleStoreProxyRequest(\n request,\n tanStackStorePathSegments(params),\n config,\n );\n };\n\n return {\n GET: handler,\n POST: handler,\n PUT: handler,\n PATCH: handler,\n DELETE: handler,\n };\n}\n\nexport { handleStoreProxyRequest } from \"../../../../core/server/store-proxy-handler\";\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { P as PublicStoreSettingsSource, a as PublicStoreResult, F as FetchPublicStoreSettingsOptions } from './index-C-xqLr1g.js';
|
|
2
|
+
export { aM as CartItem, aN as CheckoutCustomerLocal, aw as CustomerAddress, aq as CustomerAddressSchema, ax as CustomerAddressUpsert, ar as CustomerAddressUpsertSchema, ay as CustomerMe, as as CustomerMeSchema, aF as CustomerOrderDetail, aF as CustomerOrderDetailDto, aD as CustomerOrderDetailSchema, aE as CustomerOrderListItem, aE as CustomerOrderListItemDto, aC as CustomerOrderListItemSchema, az as CustomerProfilePatch, at as CustomerProfilePatchSchema, av as CustomerRegisterRequest, aj as CustomerRegisterRequestSchema, W as ECOMIQ_CLIENTS_STORE_KV_BINDING, E as EcomiqProvider, h as EcomiqProviderProps, l as EcomiqSignInCredentials, aQ as OptionGroup, aO as ProductVariantSelector, aP as ProductVariantSelectorProps, aS as ProductVariantSelectorRenderProps, Q as QueryProvider, aR as SelectedOptions, H as StoreApiClient, R as StoreApiGetOptions, f as StorefrontAuthClientInstance, S as StorefrontAuthProvider, t as StorefrontCollection, v as StorefrontPageDetail, o as StorefrontProduct, p as StorefrontProductDetail, z as StorefrontProductSchema, r as StorefrontProductsParamsInput, q as StorefrontProductsResponse, A as StorefrontProductsResponseSchema, g as StorefrontSessionUser, n as StorefrontSettings, y as StorefrontSettingsSchema, w as StorefrontVariant, ac as addCartCoupon, C as applyServerRequestOriginFromHeaders, X as buildStorefrontKvSnapshotKey, Y as buildStorefrontKvSnapshotKeyFromStoreKey, af as checkoutCart, ae as createCart, al as createCustomerAddress, O as createStoreApiClient, au as customerMeToProfilePatch, an as deleteCustomerAddress, i as ecomiqOAuthPassword, j as ecomiqOAuthPasswordClient, B as fetchPublicStoreSettings, m as findStorefrontCmsPageBySlug, x as formatCurrency, a8 as getCart, a9 as getCartCheckout, ah as getCartPaymentMethods, ak as getCustomerAddresses, ao as getCustomerMe, aB as getCustomerOrder, aA as getCustomerOrders, aG as getSharedOrderDraft, aa as getShippingOptions, M as getStoreApiBaseUrl, N as getStoreApiClient, a2 as getStorefrontCollectionBySlug, a1 as getStorefrontCollections, a4 as getStorefrontPageBySlug, a5 as getStorefrontPagePreview, a3 as getStorefrontPages, a0 as getStorefrontProductBySlug, $ as getStorefrontProducts, T as getStorefrontSettings, U as getStorefrontSettingsFromKv, V as getStorefrontSettingsFromKvByStoreKey, G as isCartNotActiveApiError, Z as normalizeStoreHost, a7 as patchCartAddresses, a6 as patchCartBuyer, ap as patchCustomer, ab as putCartShippingMethod, ai as registerCustomer, ad as removeCartCoupon, D as resolvePublicStoreSettingsSource, _ as resolveStorefrontSettingsHost, L as setClientStoreId, J as setServerRequestOrigin, K as setServerStoreId, k as signInWithEcomiqCredentials, I as storeApiClient, s as storefrontAccessTokenNeedsRefresh, c as storefrontSessionEndsSoon, am as updateCustomerAddress, ag as uploadPaymentReceipt, aL as useCart, b as usePublicStore, u as useStore, aK as useStoreCart, aI as useStoreCollections, aJ as useStorePages, aH as useStoreProducts, d as useStorefrontAuthClient, e as useStorefrontSession } from './index-C-xqLr1g.js';
|
|
3
|
+
export { S as StoreProxyHandlerConfig, h as handleStoreProxyRequest } from './store-proxy-handler-CNzKlTFA.js';
|
|
4
|
+
import '@ecomiq/storefront/core';
|
|
5
|
+
import 'zod';
|
|
6
|
+
import 'react';
|
|
7
|
+
import '@tanstack/react-query';
|
|
8
|
+
import '@ecomiq/storefront/react';
|
|
9
|
+
import 'zustand';
|
|
10
|
+
import 'zustand/middleware';
|
|
11
|
+
import 'better-auth';
|
|
12
|
+
import 'better-auth/client';
|
|
13
|
+
import 'better-auth/react';
|
|
14
|
+
|
|
15
|
+
declare function getHostname(): Promise<string | null>;
|
|
16
|
+
|
|
17
|
+
type GetPublicStoreOptions = {
|
|
18
|
+
source?: PublicStoreSettingsSource;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Obtiene la tienda pública en TanStack Start (server function, loader o server route).
|
|
23
|
+
* Usa `getRequestHeaders()` del contexto de request activo.
|
|
24
|
+
*/
|
|
25
|
+
declare function getPublicStore(options?: GetPublicStoreOptions): Promise<PublicStoreResult>;
|
|
26
|
+
declare function getPublicStoreFromHeaders(headerList: {
|
|
27
|
+
get(name: string): string | null;
|
|
28
|
+
}, options?: Omit<FetchPublicStoreSettingsOptions, "host">): Promise<PublicStoreResult>;
|
|
29
|
+
|
|
30
|
+
export { FetchPublicStoreSettingsOptions, PublicStoreResult, PublicStoreSettingsSource, getHostname, getPublicStore, getPublicStoreFromHeaders };
|