@kotao/storefront 0.2.4 → 0.2.6
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 +50 -2
- package/dist/bridge-ZKbKqgFd.d.ts +239 -0
- package/dist/cart-documents-BLavRDiu.d.ts +89 -0
- package/dist/cart-documents.d.ts +1 -2
- package/dist/cart-documents.js +1 -1
- package/dist/{chunk-M7BPQ54D.js → chunk-2MRB6SMP.js} +4 -3
- package/dist/chunk-2MRB6SMP.js.map +1 -0
- package/dist/chunk-CKGI3Y7L.js +19 -0
- package/dist/chunk-CKGI3Y7L.js.map +1 -0
- package/dist/{chunk-4TEFGD42.js → chunk-EG34HLSX.js} +209 -162
- package/dist/chunk-EG34HLSX.js.map +1 -0
- package/dist/chunk-O6YZEY7X.js +1382 -0
- package/dist/chunk-O6YZEY7X.js.map +1 -0
- package/dist/{chunk-7MTCGXIG.js → chunk-R4N565GX.js} +8 -4
- package/dist/chunk-R4N565GX.js.map +1 -0
- package/dist/{chunk-XMTWFJCZ.js → chunk-RFM27BKZ.js} +31 -7
- package/dist/chunk-RFM27BKZ.js.map +1 -0
- package/dist/{chunk-MYDKIJRH.js → chunk-SVMYFYIA.js} +2 -2
- package/dist/{chunk-MYDKIJRH.js.map → chunk-SVMYFYIA.js.map} +1 -1
- package/dist/{chunk-H3D7BAOL.js → chunk-VOTBNOWH.js} +21 -3
- package/dist/chunk-VOTBNOWH.js.map +1 -0
- package/dist/{chunk-PXVDVUFX.js → chunk-W74FGUZH.js} +10 -3
- package/dist/chunk-W74FGUZH.js.map +1 -0
- package/dist/{chunk-2IWNUDSZ.js → chunk-WNXI3MPM.js} +2 -2
- package/dist/chunk-WNXI3MPM.js.map +1 -0
- package/dist/chunk-XXNCFWXT.js +2118 -0
- package/dist/chunk-XXNCFWXT.js.map +1 -0
- package/dist/{client-bsiNPHBi.d.ts → client-CwOPPpFF.d.ts} +11 -1
- package/dist/{createCartHandler-C4RrPwSG.d.ts → createCartHandler-7DdKB-GF.d.ts} +1 -1
- package/dist/custom-css-Bl7Ur3-H.d.ts +6 -0
- package/dist/editor.d.ts +57 -104
- package/dist/editor.js +270 -1
- package/dist/editor.js.map +1 -1
- package/dist/events-react.d.ts +1 -1
- package/dist/events-react.js +1 -1
- package/dist/events.d.ts +3 -3
- package/dist/events.js +1 -1
- package/dist/{fetch-M3Y-fQrW.d.ts → fetch-Bq_cc8_G.d.ts} +5 -0
- package/dist/hydrogen-Bu7k0kE4.d.ts +259 -0
- package/dist/index.d.ts +74 -51
- package/dist/index.js +19 -15
- package/dist/index.js.map +1 -1
- package/dist/react-router.d.ts +30 -9
- package/dist/react-router.js +16 -7
- package/dist/react-router.js.map +1 -1
- package/dist/react.d.ts +79 -11
- package/dist/react.js +279 -10
- package/dist/react.js.map +1 -1
- package/dist/{routing-sEonP93J.d.ts → routing-Bz3Cg0BW.d.ts} +36 -6
- package/dist/seo.d.ts +7 -4
- package/dist/seo.js +2 -2
- package/dist/settings.d.ts +14 -4
- package/dist/settings.js +2 -2
- package/dist/{shop-BJSvtmnV.d.ts → shop-CnrnSAJw.d.ts} +33 -6
- package/dist/{store-CtCWHI8H.d.ts → store-DO08fzJi.d.ts} +1 -1
- package/dist/storefront-api-types.d.ts +12 -0
- package/dist/{types-BDhHWZsP.d.ts → types-BkY0yET-.d.ts} +3 -3
- package/dist/{types-bcbQzx87.d.ts → types-DZX8ScsJ.d.ts} +2 -0
- package/package.json +4 -4
- package/dist/cart-documents-CwwRTvm8.d.ts +0 -21
- package/dist/chunk-2IWNUDSZ.js.map +0 -1
- package/dist/chunk-4TEFGD42.js.map +0 -1
- package/dist/chunk-7MTCGXIG.js.map +0 -1
- package/dist/chunk-H3D7BAOL.js.map +0 -1
- package/dist/chunk-M7BPQ54D.js.map +0 -1
- package/dist/chunk-PXVDVUFX.js.map +0 -1
- package/dist/chunk-PXZ737N3.js +0 -439
- package/dist/chunk-PXZ737N3.js.map +0 -1
- package/dist/chunk-XMTWFJCZ.js.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { CONSENT_BUCKETS, readConsentCookie, CART_FORM_ACTIONS } from './chunk-OGWYTYYS.js';
|
|
2
|
-
import { fetchThemeSettings } from './chunk-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { fetchThemeSettings } from './chunk-2MRB6SMP.js';
|
|
3
|
+
import { encodeUtf8Base64Url, toBase64Url, fromBase64Url, decodeBase64UrlUtf8 } from './chunk-CKGI3Y7L.js';
|
|
4
|
+
import { createEventsClient, normalizeStorefrontHeaders } from './chunk-R4N565GX.js';
|
|
5
|
+
import { HOSTED_SURFACE_DESIGN_INPUTS, MARKET_ID_HEADER, MARKET_DEFAULT_LOCALE_HEADER, MARKET_CANONICAL_URL_HEADER, MARKET_ROOT_URLS_HEADER, MARKET_PATH_PREFIX_HEADER, MARKET_THEME_ID_HEADER, MARKET_SETTINGS_ENVIRONMENT_HEADER, MARKET_ALTERNATE_LOCALES_HEADER, SHOP_HEADER, SHOP_SIGNATURE_HEADER, SHOP_ORIGIN_HEADER, autoRedirectEnabled, AUTO_REDIRECT_COUNTRY_HEADER, signShopContext } from '@kotao/storefront-contracts';
|
|
6
|
+
export { MARKET_ALTERNATE_LOCALES_HEADER, MARKET_CANONICAL_URL_HEADER, MARKET_DEFAULT_LOCALE_HEADER, MARKET_ID_HEADER, MARKET_PATH_PREFIX_HEADER, MARKET_ROOT_URLS_HEADER, MARKET_SETTINGS_ENVIRONMENT_HEADER, MARKET_THEME_ID_HEADER } from '@kotao/storefront-contracts';
|
|
5
7
|
|
|
6
8
|
// src/cache/cache.ts
|
|
7
9
|
var DEFAULT_STALE_IF_ERROR_SECONDS = 300;
|
|
@@ -115,6 +117,87 @@ function buildCartIdCookie(cartId) {
|
|
|
115
117
|
return `${CART_ID_COOKIE}=${encodeURIComponent(cartId)}; Path=/; Max-Age=${CART_MAX_AGE}; SameSite=Lax; Secure; HttpOnly`;
|
|
116
118
|
}
|
|
117
119
|
|
|
120
|
+
// src/customer-account/session.ts
|
|
121
|
+
var CUSTOMER_SESSION_COOKIE = "kotao_customer_session";
|
|
122
|
+
var DEFAULT_SESSION_MAX_AGE = 60 * 60 * 24 * 30;
|
|
123
|
+
var HOSTED_CUSTOMER_SESSION_COOKIE = "__Host-kotao_customer_session";
|
|
124
|
+
var HOSTED_CUSTOMER_CSRF_COOKIE = "__Host-kotao_customer_csrf";
|
|
125
|
+
var HOSTED_CUSTOMER_CSRF_HEADER = "x-kotao-csrf-token";
|
|
126
|
+
var MAX_HOSTED_SESSION_MAX_AGE = 60 * 60 * 24 * 365;
|
|
127
|
+
var DEFAULT_HOSTED_SESSION_MAX_AGE = MAX_HOSTED_SESSION_MAX_AGE;
|
|
128
|
+
var MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH = 4096;
|
|
129
|
+
var assertHostname = (hostname) => {
|
|
130
|
+
if (hostname === "" || hostname.startsWith(".") || hostname.endsWith(".")) {
|
|
131
|
+
throw new Error(`invalid shop hostname for the customer session cookie: '${hostname}'`);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
function shopHostname(request) {
|
|
135
|
+
return new URL(request.url).hostname;
|
|
136
|
+
}
|
|
137
|
+
function buildCustomerSessionCookie(token, attrs) {
|
|
138
|
+
assertHostname(attrs.hostname);
|
|
139
|
+
const maxAge = attrs.maxAgeSeconds ?? DEFAULT_SESSION_MAX_AGE;
|
|
140
|
+
return `${CUSTOMER_SESSION_COOKIE}=${encodeURIComponent(token)}; Domain=${attrs.hostname}; Path=/; Max-Age=${maxAge}; HttpOnly; Secure; SameSite=Lax`;
|
|
141
|
+
}
|
|
142
|
+
function clearCustomerSessionCookie(attrs) {
|
|
143
|
+
assertHostname(attrs.hostname);
|
|
144
|
+
return `${CUSTOMER_SESSION_COOKIE}=; Domain=${attrs.hostname}; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Lax`;
|
|
145
|
+
}
|
|
146
|
+
function readCustomerSessionToken(cookieHeader) {
|
|
147
|
+
if (cookieHeader === null || cookieHeader === void 0 || cookieHeader === "") return null;
|
|
148
|
+
const match = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${CUSTOMER_SESSION_COOKIE}=`));
|
|
149
|
+
if (match === void 0) return null;
|
|
150
|
+
const raw = match.slice(CUSTOMER_SESSION_COOKIE.length + 1);
|
|
151
|
+
if (raw === "") return null;
|
|
152
|
+
try {
|
|
153
|
+
return decodeURIComponent(raw);
|
|
154
|
+
} catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function buildHostedCustomerSessionCookie(token, attrs = {}) {
|
|
159
|
+
if (token === "") throw new Error("hosted customer session token must not be empty");
|
|
160
|
+
const maxAge = attrs.maxAgeSeconds ?? DEFAULT_HOSTED_SESSION_MAX_AGE;
|
|
161
|
+
if (!Number.isInteger(maxAge) || maxAge <= 0 || maxAge > MAX_HOSTED_SESSION_MAX_AGE) {
|
|
162
|
+
throw new Error("hosted customer session Max-Age must be between 1 second and 365 days");
|
|
163
|
+
}
|
|
164
|
+
return `${HOSTED_CUSTOMER_SESSION_COOKIE}=${encodeURIComponent(token)}; Path=/; Max-Age=${maxAge}; HttpOnly; Secure; SameSite=Lax`;
|
|
165
|
+
}
|
|
166
|
+
function clearHostedCustomerSessionCookie() {
|
|
167
|
+
return `${HOSTED_CUSTOMER_SESSION_COOKIE}=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Lax`;
|
|
168
|
+
}
|
|
169
|
+
function readHostedCustomerSessionToken(cookieHeader) {
|
|
170
|
+
return readBoundedCookie(cookieHeader, HOSTED_CUSTOMER_SESSION_COOKIE);
|
|
171
|
+
}
|
|
172
|
+
function readHostedCustomerCsrfToken(cookieHeader) {
|
|
173
|
+
const token = readBoundedCookie(cookieHeader, HOSTED_CUSTOMER_CSRF_COOKIE, 43);
|
|
174
|
+
return token !== null && /^[A-Za-z0-9_-]{43}$/.test(token) ? token : null;
|
|
175
|
+
}
|
|
176
|
+
function readLegacyCustomerSessionToken(cookieHeader, options) {
|
|
177
|
+
if (!options.allowLegacy) return null;
|
|
178
|
+
return readBoundedCookie(
|
|
179
|
+
cookieHeader,
|
|
180
|
+
CUSTOMER_SESSION_COOKIE,
|
|
181
|
+
MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
function clearLegacyCustomerSessionCookie(attrs) {
|
|
185
|
+
return clearCustomerSessionCookie(attrs);
|
|
186
|
+
}
|
|
187
|
+
function readBoundedCookie(cookieHeader, name, maxLength = MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH) {
|
|
188
|
+
if (cookieHeader === null || cookieHeader === void 0 || cookieHeader === "") return null;
|
|
189
|
+
const match = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${name}=`));
|
|
190
|
+
if (match === void 0) return null;
|
|
191
|
+
const raw = match.slice(name.length + 1);
|
|
192
|
+
if (raw === "" || raw.length > maxLength) return null;
|
|
193
|
+
try {
|
|
194
|
+
const decoded = decodeURIComponent(raw);
|
|
195
|
+
return decoded.length <= maxLength ? decoded : null;
|
|
196
|
+
} catch {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
118
201
|
// src/checkout/consent.ts
|
|
119
202
|
var PARAM_PREFIX = "consent_";
|
|
120
203
|
var VALID_PARAM_VALUES = /* @__PURE__ */ new Set(["0", "1"]);
|
|
@@ -214,51 +297,18 @@ function assertNoZoneIdentityLeak(url) {
|
|
|
214
297
|
}
|
|
215
298
|
}
|
|
216
299
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
defaultValue: ""
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
type: "color",
|
|
233
|
-
name: "checkoutColorAccent",
|
|
234
|
-
label: "Checkout accent color",
|
|
235
|
-
defaultValue: "#005bd3"
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
type: "color",
|
|
239
|
-
name: "checkoutColorBackground",
|
|
240
|
-
label: "Checkout background color",
|
|
241
|
-
defaultValue: "#ffffff"
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
type: "color",
|
|
245
|
-
name: "checkoutColorForeground",
|
|
246
|
-
label: "Checkout foreground color",
|
|
247
|
-
defaultValue: "#111827"
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
type: "font",
|
|
251
|
-
name: "checkoutFontBody",
|
|
252
|
-
label: "Checkout body font",
|
|
253
|
-
defaultValue: "Inter"
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
type: "font",
|
|
257
|
-
name: "checkoutFontHeading",
|
|
258
|
-
label: "Checkout heading font",
|
|
259
|
-
defaultValue: "Inter"
|
|
260
|
-
}
|
|
261
|
-
];
|
|
300
|
+
var CHECKOUT_TOKEN_DEFAULTS = {
|
|
301
|
+
checkoutLogoAlt: "",
|
|
302
|
+
checkoutColorAccent: "#005bd3",
|
|
303
|
+
checkoutColorBackground: "#ffffff",
|
|
304
|
+
checkoutColorForeground: "#111827",
|
|
305
|
+
checkoutFontBody: "Inter",
|
|
306
|
+
checkoutFontHeading: "Inter"
|
|
307
|
+
};
|
|
308
|
+
var CHECKOUT_DESIGN_TOKEN_INPUTS = HOSTED_SURFACE_DESIGN_INPUTS.map((input) => ({
|
|
309
|
+
...input,
|
|
310
|
+
...input.name in CHECKOUT_TOKEN_DEFAULTS ? { defaultValue: CHECKOUT_TOKEN_DEFAULTS[input.name] } : {}
|
|
311
|
+
}));
|
|
262
312
|
function extractCheckoutDesignTokens(snapshot) {
|
|
263
313
|
const global = snapshot.global;
|
|
264
314
|
const logoUrl = optionalString(global["checkoutLogoUrl"], "checkoutLogoUrl");
|
|
@@ -316,6 +366,7 @@ var CART_FRAGMENT = (
|
|
|
316
366
|
email
|
|
317
367
|
phone
|
|
318
368
|
countryCode
|
|
369
|
+
companyLocationId
|
|
319
370
|
}
|
|
320
371
|
note
|
|
321
372
|
attributes {
|
|
@@ -575,6 +626,8 @@ function createCartHandler(opts) {
|
|
|
575
626
|
cartId = void 0;
|
|
576
627
|
}
|
|
577
628
|
const consent = readConsentCookie(request?.headers.get("cookie"));
|
|
629
|
+
const cookieHeader = request?.headers.get("cookie");
|
|
630
|
+
const customerAccessToken = readHostedCustomerSessionToken(cookieHeader) ?? readCustomerSessionToken(cookieHeader);
|
|
578
631
|
const currentCartId = async () => {
|
|
579
632
|
if (cartId !== void 0) return cartId;
|
|
580
633
|
cartId = await getCartId() ?? null;
|
|
@@ -611,9 +664,16 @@ function createCartHandler(opts) {
|
|
|
611
664
|
return headers;
|
|
612
665
|
};
|
|
613
666
|
const create = async (input = {}) => {
|
|
667
|
+
const effectiveInput = customerAccessToken === null ? input : {
|
|
668
|
+
...input,
|
|
669
|
+
buyerIdentity: {
|
|
670
|
+
...input.buyerIdentity,
|
|
671
|
+
customerAccessToken: input.buyerIdentity?.customerAccessToken ?? customerAccessToken
|
|
672
|
+
}
|
|
673
|
+
};
|
|
614
674
|
const data = await opts.storefront.mutate(
|
|
615
675
|
CART_CREATE_MUTATION,
|
|
616
|
-
{ variables: { input } }
|
|
676
|
+
{ variables: { input: effectiveInput } }
|
|
617
677
|
);
|
|
618
678
|
return withCookie(data.cartCreate);
|
|
619
679
|
};
|
|
@@ -732,87 +792,6 @@ function appendSetCartIdHeaders(headers, value) {
|
|
|
732
792
|
}
|
|
733
793
|
}
|
|
734
794
|
|
|
735
|
-
// src/customer-account/session.ts
|
|
736
|
-
var CUSTOMER_SESSION_COOKIE = "kotao_customer_session";
|
|
737
|
-
var DEFAULT_SESSION_MAX_AGE = 60 * 60 * 24 * 30;
|
|
738
|
-
var HOSTED_CUSTOMER_SESSION_COOKIE = "__Host-kotao_customer_session";
|
|
739
|
-
var HOSTED_CUSTOMER_CSRF_COOKIE = "__Host-kotao_customer_csrf";
|
|
740
|
-
var HOSTED_CUSTOMER_CSRF_HEADER = "x-kotao-csrf-token";
|
|
741
|
-
var MAX_HOSTED_SESSION_MAX_AGE = 60 * 60 * 24 * 365;
|
|
742
|
-
var DEFAULT_HOSTED_SESSION_MAX_AGE = MAX_HOSTED_SESSION_MAX_AGE;
|
|
743
|
-
var MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH = 4096;
|
|
744
|
-
var assertHostname = (hostname) => {
|
|
745
|
-
if (hostname === "" || hostname.startsWith(".") || hostname.endsWith(".")) {
|
|
746
|
-
throw new Error(`invalid shop hostname for the customer session cookie: '${hostname}'`);
|
|
747
|
-
}
|
|
748
|
-
};
|
|
749
|
-
function shopHostname(request) {
|
|
750
|
-
return new URL(request.url).hostname;
|
|
751
|
-
}
|
|
752
|
-
function buildCustomerSessionCookie(token, attrs) {
|
|
753
|
-
assertHostname(attrs.hostname);
|
|
754
|
-
const maxAge = attrs.maxAgeSeconds ?? DEFAULT_SESSION_MAX_AGE;
|
|
755
|
-
return `${CUSTOMER_SESSION_COOKIE}=${encodeURIComponent(token)}; Domain=${attrs.hostname}; Path=/; Max-Age=${maxAge}; HttpOnly; Secure; SameSite=Lax`;
|
|
756
|
-
}
|
|
757
|
-
function clearCustomerSessionCookie(attrs) {
|
|
758
|
-
assertHostname(attrs.hostname);
|
|
759
|
-
return `${CUSTOMER_SESSION_COOKIE}=; Domain=${attrs.hostname}; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Lax`;
|
|
760
|
-
}
|
|
761
|
-
function readCustomerSessionToken(cookieHeader) {
|
|
762
|
-
if (cookieHeader === null || cookieHeader === void 0 || cookieHeader === "") return null;
|
|
763
|
-
const match = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${CUSTOMER_SESSION_COOKIE}=`));
|
|
764
|
-
if (match === void 0) return null;
|
|
765
|
-
const raw = match.slice(CUSTOMER_SESSION_COOKIE.length + 1);
|
|
766
|
-
if (raw === "") return null;
|
|
767
|
-
try {
|
|
768
|
-
return decodeURIComponent(raw);
|
|
769
|
-
} catch {
|
|
770
|
-
return null;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
function buildHostedCustomerSessionCookie(token, attrs = {}) {
|
|
774
|
-
if (token === "") throw new Error("hosted customer session token must not be empty");
|
|
775
|
-
const maxAge = attrs.maxAgeSeconds ?? DEFAULT_HOSTED_SESSION_MAX_AGE;
|
|
776
|
-
if (!Number.isInteger(maxAge) || maxAge <= 0 || maxAge > MAX_HOSTED_SESSION_MAX_AGE) {
|
|
777
|
-
throw new Error("hosted customer session Max-Age must be between 1 second and 365 days");
|
|
778
|
-
}
|
|
779
|
-
return `${HOSTED_CUSTOMER_SESSION_COOKIE}=${encodeURIComponent(token)}; Path=/; Max-Age=${maxAge}; HttpOnly; Secure; SameSite=Lax`;
|
|
780
|
-
}
|
|
781
|
-
function clearHostedCustomerSessionCookie() {
|
|
782
|
-
return `${HOSTED_CUSTOMER_SESSION_COOKIE}=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Lax`;
|
|
783
|
-
}
|
|
784
|
-
function readHostedCustomerSessionToken(cookieHeader) {
|
|
785
|
-
return readBoundedCookie(cookieHeader, HOSTED_CUSTOMER_SESSION_COOKIE);
|
|
786
|
-
}
|
|
787
|
-
function readHostedCustomerCsrfToken(cookieHeader) {
|
|
788
|
-
const token = readBoundedCookie(cookieHeader, HOSTED_CUSTOMER_CSRF_COOKIE, 43);
|
|
789
|
-
return token !== null && /^[A-Za-z0-9_-]{43}$/.test(token) ? token : null;
|
|
790
|
-
}
|
|
791
|
-
function readLegacyCustomerSessionToken(cookieHeader, options) {
|
|
792
|
-
if (!options.allowLegacy) return null;
|
|
793
|
-
return readBoundedCookie(
|
|
794
|
-
cookieHeader,
|
|
795
|
-
CUSTOMER_SESSION_COOKIE,
|
|
796
|
-
MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH
|
|
797
|
-
);
|
|
798
|
-
}
|
|
799
|
-
function clearLegacyCustomerSessionCookie(attrs) {
|
|
800
|
-
return clearCustomerSessionCookie(attrs);
|
|
801
|
-
}
|
|
802
|
-
function readBoundedCookie(cookieHeader, name, maxLength = MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH) {
|
|
803
|
-
if (cookieHeader === null || cookieHeader === void 0 || cookieHeader === "") return null;
|
|
804
|
-
const match = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${name}=`));
|
|
805
|
-
if (match === void 0) return null;
|
|
806
|
-
const raw = match.slice(name.length + 1);
|
|
807
|
-
if (raw === "" || raw.length > maxLength) return null;
|
|
808
|
-
try {
|
|
809
|
-
const decoded = decodeURIComponent(raw);
|
|
810
|
-
return decoded.length <= maxLength ? decoded : null;
|
|
811
|
-
} catch {
|
|
812
|
-
return null;
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
|
|
816
795
|
// src/customer-account/types.ts
|
|
817
796
|
var CustomerAccountError = class extends Error {
|
|
818
797
|
code;
|
|
@@ -1294,22 +1273,6 @@ function idTokenNonce(idToken) {
|
|
|
1294
1273
|
}
|
|
1295
1274
|
}
|
|
1296
1275
|
|
|
1297
|
-
// src/geo/base64url.ts
|
|
1298
|
-
var toBase64Url = (bytes) => {
|
|
1299
|
-
let bin = "";
|
|
1300
|
-
for (const b of bytes) bin += String.fromCharCode(b);
|
|
1301
|
-
return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1302
|
-
};
|
|
1303
|
-
var fromBase64Url = (s) => {
|
|
1304
|
-
const b64 = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
1305
|
-
const bin = atob(b64);
|
|
1306
|
-
const out = new Uint8Array(bin.length);
|
|
1307
|
-
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
1308
|
-
return out;
|
|
1309
|
-
};
|
|
1310
|
-
var encodeUtf8Base64Url = (text) => toBase64Url(new TextEncoder().encode(text));
|
|
1311
|
-
var decodeBase64UrlUtf8 = (s) => new TextDecoder().decode(fromBase64Url(s));
|
|
1312
|
-
|
|
1313
1276
|
// src/geo/geo.ts
|
|
1314
1277
|
var GEO_HEADER = "x-kotao-geo";
|
|
1315
1278
|
var GEO_SIGNATURE_HEADER = "x-kotao-geo-signature";
|
|
@@ -1384,7 +1347,10 @@ function splitFirstPathSegment(pathname) {
|
|
|
1384
1347
|
const withoutSlash = pathname.slice(1);
|
|
1385
1348
|
const slash = withoutSlash.indexOf("/");
|
|
1386
1349
|
if (slash === -1) return { segment: withoutSlash, rest: "" };
|
|
1387
|
-
return {
|
|
1350
|
+
return {
|
|
1351
|
+
segment: withoutSlash.slice(0, slash),
|
|
1352
|
+
rest: withoutSlash.slice(slash)
|
|
1353
|
+
};
|
|
1388
1354
|
}
|
|
1389
1355
|
function isLocalePathSegment(segment) {
|
|
1390
1356
|
return LOCALE_SEGMENT_RE.test(segment);
|
|
@@ -1475,12 +1441,16 @@ function localizePath(path, locale, options = {}) {
|
|
|
1475
1441
|
const targetLocale = normalizeLocale(locale);
|
|
1476
1442
|
const primaryLocale = normalizeLocale(options.primaryLocale);
|
|
1477
1443
|
const url = new URL(path.startsWith("/") ? path : "/", "https://storefront.local");
|
|
1478
|
-
const
|
|
1444
|
+
const marketPrefix = options.marketPathPrefix !== null && options.marketPathPrefix !== void 0 && options.marketPathPrefix.startsWith("/") ? options.marketPathPrefix.replace(/\/+$/u, "") : null;
|
|
1445
|
+
const withoutMarket = marketPrefix !== null && (url.pathname === marketPrefix || url.pathname.startsWith(`${marketPrefix}/`)) ? url.pathname.slice(marketPrefix.length) || "/" : url.pathname;
|
|
1446
|
+
const stripped = stripLocalePrefixFromPathname(withoutMarket).pathname;
|
|
1479
1447
|
const suffix = `${url.search}${url.hash}`;
|
|
1448
|
+
const marketBase = marketPrefix ?? "";
|
|
1480
1449
|
if (targetLocale === null || primaryLocale !== null && targetLocale === primaryLocale) {
|
|
1481
|
-
return `${stripped}${suffix}
|
|
1450
|
+
return `${marketBase}${stripped}${suffix}` || "/";
|
|
1482
1451
|
}
|
|
1483
|
-
|
|
1452
|
+
const localized = stripped === "/" ? `/${targetLocale}` : `/${targetLocale}${stripped}`;
|
|
1453
|
+
return `${marketBase}${localized}${suffix}`;
|
|
1484
1454
|
}
|
|
1485
1455
|
|
|
1486
1456
|
// src/storefront-client/client.ts
|
|
@@ -1802,6 +1772,40 @@ async function localSignedShopContextHeaders(key, siteId, hostname) {
|
|
|
1802
1772
|
);
|
|
1803
1773
|
return { [SHOP_HEADER]: payload, [SHOP_SIGNATURE_HEADER]: signature };
|
|
1804
1774
|
}
|
|
1775
|
+
function marketContextFromHeaders(headers) {
|
|
1776
|
+
const id = headers.get(MARKET_ID_HEADER)?.trim();
|
|
1777
|
+
const defaultLocale = headers.get(MARKET_DEFAULT_LOCALE_HEADER)?.trim();
|
|
1778
|
+
const canonicalUrl = headers.get(MARKET_CANONICAL_URL_HEADER)?.trim();
|
|
1779
|
+
const encodedRoots = headers.get(MARKET_ROOT_URLS_HEADER);
|
|
1780
|
+
if (!id || !defaultLocale || !canonicalUrl?.startsWith("https://") || encodedRoots === null || encodedRoots.length > 32768) {
|
|
1781
|
+
return null;
|
|
1782
|
+
}
|
|
1783
|
+
let rootUrls;
|
|
1784
|
+
try {
|
|
1785
|
+
const parsed = JSON.parse(encodedRoots);
|
|
1786
|
+
if (!Array.isArray(parsed) || parsed.length === 0 || !parsed.every(
|
|
1787
|
+
(root) => typeof root === "object" && root !== null && "locale" in root && typeof root.locale === "string" && "url" in root && typeof root.url === "string" && root.url.startsWith("https://")
|
|
1788
|
+
)) {
|
|
1789
|
+
return null;
|
|
1790
|
+
}
|
|
1791
|
+
rootUrls = parsed;
|
|
1792
|
+
} catch {
|
|
1793
|
+
return null;
|
|
1794
|
+
}
|
|
1795
|
+
const pathPrefix = headers.get(MARKET_PATH_PREFIX_HEADER)?.trim();
|
|
1796
|
+
const themeId = headers.get(MARKET_THEME_ID_HEADER)?.trim();
|
|
1797
|
+
const settingsEnvironmentHandle = headers.get(MARKET_SETTINGS_ENVIRONMENT_HEADER)?.trim();
|
|
1798
|
+
return {
|
|
1799
|
+
id,
|
|
1800
|
+
pathPrefix: pathPrefix ? pathPrefix : null,
|
|
1801
|
+
defaultLocale,
|
|
1802
|
+
alternateLocales: headers.get(MARKET_ALTERNATE_LOCALES_HEADER)?.split(",").map((locale) => locale.trim()).filter((locale) => locale.length > 0) ?? [],
|
|
1803
|
+
rootUrls,
|
|
1804
|
+
canonicalUrl,
|
|
1805
|
+
themeId: themeId ? themeId : null,
|
|
1806
|
+
settingsEnvironmentHandle: settingsEnvironmentHandle ? settingsEnvironmentHandle : null
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1805
1809
|
var CACHE_NAME = "kotao-storefront-v1";
|
|
1806
1810
|
var CACHE_VERSION_HEADER = "x-kotao-cache-version";
|
|
1807
1811
|
var REQUEST_ID_HEADER = "x-kotao-request-id";
|
|
@@ -1842,6 +1846,36 @@ function resolveStorefrontApiEndpoint(endpoint, requestUrl) {
|
|
|
1842
1846
|
return new URL("/api/storefront", requestUrl).toString();
|
|
1843
1847
|
return endpoint;
|
|
1844
1848
|
}
|
|
1849
|
+
var STOREFRONT_API_PROTECTED_HEADERS = [
|
|
1850
|
+
SHOP_HEADER,
|
|
1851
|
+
SHOP_ORIGIN_HEADER,
|
|
1852
|
+
SHOP_SIGNATURE_HEADER,
|
|
1853
|
+
"x-kotao-locale",
|
|
1854
|
+
"x-kotao-country",
|
|
1855
|
+
REQUEST_ID_HEADER,
|
|
1856
|
+
DEPLOYMENT_ID_HEADER
|
|
1857
|
+
];
|
|
1858
|
+
function createStorefrontApiFetch(endpoint, defaultHeaders) {
|
|
1859
|
+
const base = new URL(endpoint);
|
|
1860
|
+
const basePath = base.pathname.replace(/\/+$/, "") || "/";
|
|
1861
|
+
return async (input, init) => {
|
|
1862
|
+
const inputUrl = input instanceof Request ? input.url : String(input);
|
|
1863
|
+
const target = new URL(inputUrl, base);
|
|
1864
|
+
const withinBasePath = basePath === "/" || target.pathname === basePath || target.pathname.startsWith(`${basePath}/`);
|
|
1865
|
+
if (target.username !== "" || target.password !== "" || target.origin !== base.origin || !withinBasePath) {
|
|
1866
|
+
throw new TypeError("storefront API fetch target is outside the configured endpoint");
|
|
1867
|
+
}
|
|
1868
|
+
const request = new Request(input instanceof Request ? input : target, {
|
|
1869
|
+
...init,
|
|
1870
|
+
// Never forward signed shop headers across a redirect selected by untrusted theme code.
|
|
1871
|
+
redirect: "manual"
|
|
1872
|
+
});
|
|
1873
|
+
const headers = new Headers(request.headers);
|
|
1874
|
+
for (const name of STOREFRONT_API_PROTECTED_HEADERS) headers.delete(name);
|
|
1875
|
+
defaultHeaders.forEach((value, name) => headers.set(name, value));
|
|
1876
|
+
return fetch(new Request(request, { headers }));
|
|
1877
|
+
};
|
|
1878
|
+
}
|
|
1845
1879
|
async function createKotaoContext(request, env, executionCtx, deps) {
|
|
1846
1880
|
const waitUntil = (p) => {
|
|
1847
1881
|
executionCtx.waitUntil(p);
|
|
@@ -1863,22 +1897,28 @@ async function createKotaoContext(request, env, executionCtx, deps) {
|
|
|
1863
1897
|
const siteId = resolvedEnv.KOTAO_SITE_ID ?? resolvedEnv.KOTAO_SHOP_ID;
|
|
1864
1898
|
const inboundShop = request.headers.get(SHOP_HEADER);
|
|
1865
1899
|
const inboundShopSignature = request.headers.get(SHOP_SIGNATURE_HEADER);
|
|
1866
|
-
const signedShopContextHeaders = inboundShop !== null && inboundShopSignature !== null ? {
|
|
1900
|
+
const signedShopContextHeaders = inboundShop !== null && inboundShopSignature !== null ? {
|
|
1901
|
+
[SHOP_HEADER]: inboundShop,
|
|
1902
|
+
[SHOP_SIGNATURE_HEADER]: inboundShopSignature
|
|
1903
|
+
} : await localSignedShopContextHeaders(
|
|
1867
1904
|
resolvedEnv.STOREFRONT_SHOP_CONTEXT_KEY,
|
|
1868
1905
|
siteId,
|
|
1869
1906
|
new URL(request.url).hostname
|
|
1870
1907
|
);
|
|
1871
|
-
const
|
|
1908
|
+
const requestUrl = new URL(request.url);
|
|
1909
|
+
const editorMode = requestUrl.searchParams.get("kotao_editor") === "1";
|
|
1910
|
+
const requestedEditorLocale = editorMode ? requestUrl.searchParams.get("kotao_locale")?.trim() : void 0;
|
|
1911
|
+
const requestedEditorCountry = editorMode ? requestUrl.searchParams.get("kotao_country")?.trim().toUpperCase() : void 0;
|
|
1912
|
+
const editorLocale = requestedEditorLocale !== void 0 && API_LOCALE_RE.test(requestedEditorLocale) ? requestedEditorLocale : null;
|
|
1913
|
+
const editorCountry = requestedEditorCountry !== void 0 && API_COUNTRY_RE.test(requestedEditorCountry) ? requestedEditorCountry : null;
|
|
1914
|
+
const pathLocale = editorLocale ?? parseLocale(request);
|
|
1915
|
+
const market = marketContextFromHeaders(request.headers);
|
|
1872
1916
|
const localizationCookie = readLocalizationCookie(request.headers.get("cookie"));
|
|
1873
|
-
const cookieLocale = localizationCookie.locale;
|
|
1874
|
-
const autoLanguage = autoRedirectEnabled(request.headers, AUTO_REDIRECT_LANGUAGE_HEADER);
|
|
1875
1917
|
const autoCountry = autoRedirectEnabled(request.headers, AUTO_REDIRECT_COUNTRY_HEADER);
|
|
1876
|
-
const
|
|
1877
|
-
const selectedLocale = pathLocale ?? cookieLocale ?? browserLocale?.split("-")[0] ?? null;
|
|
1878
|
-
const apiLocale = selectedLocale !== null && API_LOCALE_RE.test(selectedLocale) ? selectedLocale : void 0;
|
|
1918
|
+
const apiLocale = pathLocale !== null && API_LOCALE_RE.test(pathLocale) ? pathLocale : void 0;
|
|
1879
1919
|
const cookieCountry = localizationCookie.country !== null && API_COUNTRY_RE.test(localizationCookie.country) ? localizationCookie.country : null;
|
|
1880
1920
|
const geoCountry = autoCountry ? geo?.country?.trim().toUpperCase() ?? null : null;
|
|
1881
|
-
const apiCountry = cookieCountry ?? (geoCountry !== null && API_COUNTRY_RE.test(geoCountry) ? geoCountry : null);
|
|
1921
|
+
const apiCountry = editorCountry ?? cookieCountry ?? (geoCountry !== null && API_COUNTRY_RE.test(geoCountry) ? geoCountry : null);
|
|
1882
1922
|
const extraHeaders = {};
|
|
1883
1923
|
const requestId = request.headers.get(REQUEST_ID_HEADER)?.trim();
|
|
1884
1924
|
if (requestId !== void 0 && requestId.length > 0) extraHeaders[REQUEST_ID_HEADER] = requestId;
|
|
@@ -1906,6 +1946,10 @@ async function createKotaoContext(request, env, executionCtx, deps) {
|
|
|
1906
1946
|
fetch,
|
|
1907
1947
|
defaultHeaders: eventHeaders
|
|
1908
1948
|
});
|
|
1949
|
+
const storefrontApiFetch = createStorefrontApiFetch(
|
|
1950
|
+
resolvedEnv.STOREFRONT_API_ENDPOINT,
|
|
1951
|
+
eventHeaders
|
|
1952
|
+
);
|
|
1909
1953
|
const cart = createCartHandler({ request, storefront });
|
|
1910
1954
|
const contextSession = withSessionPresenceHint(
|
|
1911
1955
|
deps?.session,
|
|
@@ -1921,12 +1965,14 @@ async function createKotaoContext(request, env, executionCtx, deps) {
|
|
|
1921
1965
|
const settingsEndpoint = `${resolvedEnv.STOREFRONT_API_ENDPOINT.replace(/\/+$/, "")}/settings`;
|
|
1922
1966
|
return {
|
|
1923
1967
|
storefront,
|
|
1968
|
+
fetch: storefrontApiFetch,
|
|
1924
1969
|
events,
|
|
1925
1970
|
cart,
|
|
1926
1971
|
customerAccount,
|
|
1927
1972
|
geo,
|
|
1928
1973
|
withCache: createWithCache(cache),
|
|
1929
1974
|
locale: pathLocale,
|
|
1975
|
+
market,
|
|
1930
1976
|
// Cookie-presence hint only — the theme cannot validate the HMAC; the authoritative check is the proxy.
|
|
1931
1977
|
session: contextSession,
|
|
1932
1978
|
env: resolvedEnv,
|
|
@@ -1935,7 +1981,8 @@ async function createKotaoContext(request, env, executionCtx, deps) {
|
|
|
1935
1981
|
endpoint: settingsEndpoint,
|
|
1936
1982
|
allowCrossOrigin: true,
|
|
1937
1983
|
...signedShopContextHeaders ? { shopContextHeaders: signedShopContextHeaders } : {},
|
|
1938
|
-
...opts?.fetch ? { fetch: opts.fetch } : {}
|
|
1984
|
+
...opts?.fetch ? { fetch: opts.fetch } : {},
|
|
1985
|
+
...opts?.templateHandle ? { templateHandle: opts.templateHandle } : {}
|
|
1939
1986
|
})
|
|
1940
1987
|
};
|
|
1941
1988
|
}
|
|
@@ -1988,6 +2035,6 @@ function createEphemeralSession(isLoggedIn) {
|
|
|
1988
2035
|
};
|
|
1989
2036
|
}
|
|
1990
2037
|
|
|
1991
|
-
export { CART_ID_COOKIE, CHECKOUT_CONSENT_CATEGORIES, CHECKOUT_CONSENT_PARAM_PREFIX, CHECKOUT_DESIGN_TOKEN_INPUTS, CUSTOMER_SESSION_COOKIE, CacheCustom, CacheLong, CacheNone, CacheShort, CustomerAccountError, DEFAULT_HOSTED_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE, GEO_HEADER, GEO_SIGNATURE_HEADER, HOSTED_CUSTOMER_CSRF_COOKIE, HOSTED_CUSTOMER_CSRF_HEADER, HOSTED_CUSTOMER_SESSION_COOKIE, LOCALIZATION_COOKIE, MAX_HOSTED_SESSION_MAX_AGE, MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH, ROUTING_LOCALE_HEADER, ROUTING_ORIGINAL_PATHNAME_HEADER, StorefrontDefaultCache, StorefrontQueryTimeoutError, StorefrontUpstreamError, buildCartIdCookie, buildCustomerSessionCookie, buildHostedCustomerSessionCookie, buildLocalizationCookie, cartGetIdDefault, cartSetIdDefault, clearCustomerSessionCookie, clearHostedCustomerSessionCookie, clearLegacyCustomerSessionCookie, createCache, createCartHandler, createCustomerAccountClient, createKotaoContext, createStorefrontClient, createWithCache, decodeCheckoutConsent, encodeCheckoutConsent, extractCheckoutDesignTokens, generateCacheControlHeader, isLocalePathSegment, localeFromAcceptLanguage, localeFromPathname, localeFromRequest, localizePath, originalPathnameFromRequest, readCartIdCookie, readCustomerSessionToken, readHostedCustomerCsrfToken, readHostedCustomerSessionToken, readLegacyCustomerSessionToken, readLocalizationCookie, resolveCheckoutUrl, shopHostname, signGeo, stripLocalePrefixFromPathname, stripLocalePrefixFromRequest, trustedShopOriginFromHeaders, verifyGeo };
|
|
1992
|
-
//# sourceMappingURL=chunk-
|
|
1993
|
-
//# sourceMappingURL=chunk-
|
|
2038
|
+
export { CART_ID_COOKIE, CHECKOUT_CONSENT_CATEGORIES, CHECKOUT_CONSENT_PARAM_PREFIX, CHECKOUT_DESIGN_TOKEN_INPUTS, CUSTOMER_SESSION_COOKIE, CacheCustom, CacheLong, CacheNone, CacheShort, CustomerAccountError, DEFAULT_HOSTED_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE, GEO_HEADER, GEO_SIGNATURE_HEADER, HOSTED_CUSTOMER_CSRF_COOKIE, HOSTED_CUSTOMER_CSRF_HEADER, HOSTED_CUSTOMER_SESSION_COOKIE, LOCALIZATION_COOKIE, MAX_HOSTED_SESSION_MAX_AGE, MAX_LEGACY_CUSTOMER_SESSION_TOKEN_LENGTH, ROUTING_LOCALE_HEADER, ROUTING_ORIGINAL_PATHNAME_HEADER, StorefrontDefaultCache, StorefrontQueryTimeoutError, StorefrontUpstreamError, buildCartIdCookie, buildCustomerSessionCookie, buildHostedCustomerSessionCookie, buildLocalizationCookie, cartGetIdDefault, cartSetIdDefault, clearCustomerSessionCookie, clearHostedCustomerSessionCookie, clearLegacyCustomerSessionCookie, createCache, createCartHandler, createCustomerAccountClient, createKotaoContext, createStorefrontClient, createWithCache, decodeCheckoutConsent, encodeCheckoutConsent, extractCheckoutDesignTokens, generateCacheControlHeader, isLocalePathSegment, localeFromAcceptLanguage, localeFromPathname, localeFromRequest, localizePath, marketContextFromHeaders, originalPathnameFromRequest, readCartIdCookie, readCustomerSessionToken, readHostedCustomerCsrfToken, readHostedCustomerSessionToken, readLegacyCustomerSessionToken, readLocalizationCookie, resolveCheckoutUrl, shopHostname, signGeo, stripLocalePrefixFromPathname, stripLocalePrefixFromRequest, trustedShopOriginFromHeaders, verifyGeo };
|
|
2039
|
+
//# sourceMappingURL=chunk-EG34HLSX.js.map
|
|
2040
|
+
//# sourceMappingURL=chunk-EG34HLSX.js.map
|