@decocms/apps-vtex 8.0.0 → 8.1.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/package.json +7 -52
  2. package/src/index.ts +12 -15
  3. package/src/utils/constants.ts +2 -56
  4. package/src/utils/cookieSanitizer.ts +59 -59
  5. package/src/utils/operationRouter.ts +76 -72
  6. package/src/utils/types.ts +709 -1557
  7. package/src/vtexClient.ts +444 -0
  8. package/src/README.md +0 -6
  9. package/src/__tests__/client-segment-cookie.test.ts +0 -255
  10. package/src/__tests__/client-set-cookie-forward.test.ts +0 -257
  11. package/src/__tests__/schemas.test.ts +0 -71
  12. package/src/actions/address.ts +0 -250
  13. package/src/actions/analytics/sendEvent.ts +0 -86
  14. package/src/actions/auth.ts +0 -333
  15. package/src/actions/checkout.ts +0 -659
  16. package/src/actions/index.ts +0 -11
  17. package/src/actions/masterData.ts +0 -168
  18. package/src/actions/misc.ts +0 -188
  19. package/src/actions/newsletter.ts +0 -105
  20. package/src/actions/orders.ts +0 -34
  21. package/src/actions/profile.ts +0 -201
  22. package/src/actions/session.ts +0 -85
  23. package/src/actions/trigger.ts +0 -43
  24. package/src/actions/wishlist.ts +0 -114
  25. package/src/client.ts +0 -667
  26. package/src/commerceLoaders.ts +0 -267
  27. package/src/hooks/__tests__/createCart.render.test.ts +0 -114
  28. package/src/hooks/__tests__/createCart.test.ts +0 -92
  29. package/src/hooks/__tests__/createUseCart.test.ts +0 -184
  30. package/src/hooks/__tests__/createUseUser.test.ts +0 -48
  31. package/src/hooks/__tests__/createUseWishlist.test.ts +0 -87
  32. package/src/hooks/cartQuery.ts +0 -204
  33. package/src/hooks/createCart.ts +0 -427
  34. package/src/hooks/createUseCart.ts +0 -360
  35. package/src/hooks/createUseUser.ts +0 -153
  36. package/src/hooks/createUseWishlist.ts +0 -242
  37. package/src/hooks/index.ts +0 -25
  38. package/src/hooks/useAutocomplete.ts +0 -83
  39. package/src/hooks/useCart.ts +0 -243
  40. package/src/hooks/useUser.ts +0 -78
  41. package/src/hooks/useWishlist.ts +0 -119
  42. package/src/invoke.ts +0 -235
  43. package/src/loaders/ProductDetailsPage.ts +0 -1
  44. package/src/loaders/ProductList.ts +0 -1
  45. package/src/loaders/ProductListingPage.ts +0 -1
  46. package/src/loaders/address.ts +0 -115
  47. package/src/loaders/autocomplete.ts +0 -58
  48. package/src/loaders/brands.ts +0 -44
  49. package/src/loaders/cart/attachments.ts +0 -53
  50. package/src/loaders/cart/full.ts +0 -67
  51. package/src/loaders/cart/gifts.ts +0 -43
  52. package/src/loaders/cart/orderFormId.ts +0 -31
  53. package/src/loaders/cart/shipping.test.ts +0 -125
  54. package/src/loaders/cart/shipping.ts +0 -136
  55. package/src/loaders/cart/summary.ts +0 -36
  56. package/src/loaders/cart.ts +0 -52
  57. package/src/loaders/catalog.ts +0 -163
  58. package/src/loaders/collections.ts +0 -55
  59. package/src/loaders/index.ts +0 -20
  60. package/src/loaders/intelligentSearch/__tests__/productListingPage.test.ts +0 -51
  61. package/src/loaders/intelligentSearch/productDetailsPage.ts +0 -113
  62. package/src/loaders/intelligentSearch/productList.ts +0 -154
  63. package/src/loaders/intelligentSearch/productListingPage.ts +0 -526
  64. package/src/loaders/intelligentSearch/suggestions.ts +0 -46
  65. package/src/loaders/legacy/productDetailsPage.ts +0 -1
  66. package/src/loaders/legacy/productList.ts +0 -1
  67. package/src/loaders/legacy/relatedProductsLoader.ts +0 -81
  68. package/src/loaders/legacy.ts +0 -635
  69. package/src/loaders/logistics.ts +0 -111
  70. package/src/loaders/minicart.ts +0 -78
  71. package/src/loaders/navbar.ts +0 -26
  72. package/src/loaders/orders.ts +0 -92
  73. package/src/loaders/pageType.ts +0 -68
  74. package/src/loaders/paths/PDPDefaultPath.ts +0 -51
  75. package/src/loaders/payment.ts +0 -97
  76. package/src/loaders/productListFull.ts +0 -159
  77. package/src/loaders/profile.ts +0 -138
  78. package/src/loaders/promotion.ts +0 -30
  79. package/src/loaders/search.ts +0 -124
  80. package/src/loaders/session.ts +0 -83
  81. package/src/loaders/user.ts +0 -87
  82. package/src/loaders/wishlist.ts +0 -89
  83. package/src/loaders/wishlistProducts.ts +0 -69
  84. package/src/loaders/workflow/products.ts +0 -64
  85. package/src/loaders/workflow.ts +0 -316
  86. package/src/logo.png +0 -0
  87. package/src/manifest.gen.ts +0 -89
  88. package/src/middleware.ts +0 -240
  89. package/src/mod.ts +0 -157
  90. package/src/registry.ts +0 -9
  91. package/src/schemas.gen.ts +0 -3191
  92. package/src/schemas.ts +0 -30
  93. package/src/types.ts +0 -248
  94. package/src/utils/__tests__/cartProjection.test.ts +0 -118
  95. package/src/utils/__tests__/cookieSanitizer.test.ts +0 -162
  96. package/src/utils/__tests__/fetch.test.ts +0 -80
  97. package/src/utils/__tests__/fetchCache.test.ts +0 -155
  98. package/src/utils/__tests__/instrumentedFetch.test.ts +0 -158
  99. package/src/utils/__tests__/intelligentSearch.test.ts +0 -88
  100. package/src/utils/__tests__/minicart.test.ts +0 -184
  101. package/src/utils/__tests__/operationRouter.test.ts +0 -227
  102. package/src/utils/__tests__/resilience.test.ts +0 -205
  103. package/src/utils/__tests__/resourceRange.test.ts +0 -32
  104. package/src/utils/__tests__/simulationCache.test.ts +0 -40
  105. package/src/utils/__tests__/sitemap.test.ts +0 -185
  106. package/src/utils/__tests__/slugify.test.ts +0 -31
  107. package/src/utils/__tests__/transform.test.ts +0 -769
  108. package/src/utils/accountLoaders.ts +0 -203
  109. package/src/utils/authHelpers.ts +0 -85
  110. package/src/utils/batch.ts +0 -18
  111. package/src/utils/cartProjection.ts +0 -96
  112. package/src/utils/cookies.ts +0 -167
  113. package/src/utils/enrichment.ts +0 -560
  114. package/src/utils/fetch.ts +0 -107
  115. package/src/utils/fetchCache.ts +0 -199
  116. package/src/utils/index.ts +0 -19
  117. package/src/utils/instrumentedFetch.ts +0 -97
  118. package/src/utils/intelligentSearch.ts +0 -96
  119. package/src/utils/legacy.ts +0 -139
  120. package/src/utils/minicart.ts +0 -139
  121. package/src/utils/pickAndOmit.ts +0 -25
  122. package/src/utils/proxy.ts +0 -435
  123. package/src/utils/resilience.ts +0 -352
  124. package/src/utils/resourceRange.ts +0 -10
  125. package/src/utils/segment.ts +0 -152
  126. package/src/utils/similars.ts +0 -37
  127. package/src/utils/simulationCache.ts +0 -73
  128. package/src/utils/sitemap.ts +0 -282
  129. package/src/utils/slugCache.ts +0 -28
  130. package/src/utils/slugify.ts +0 -13
  131. package/src/utils/transform.ts +0 -1522
  132. package/src/utils/vtexId.ts +0 -138
  133. package/tsconfig.json +0 -7
@@ -1,25 +0,0 @@
1
- export function pick<T extends object, K extends keyof T = keyof T>(
2
- keys: K[],
3
- obj: T | null | undefined,
4
- ): Pick<T, K> | null {
5
- if (!keys.length || !obj) {
6
- return null;
7
- }
8
-
9
- const entries = keys.map((key) => [key, obj[key]]);
10
-
11
- return Object.fromEntries(entries);
12
- }
13
-
14
- export function omit<T extends object, K extends keyof T>(
15
- keys: K[],
16
- obj: T | null | undefined,
17
- ): Omit<T, K> | null {
18
- if (!keys.length || !obj) {
19
- return null;
20
- }
21
-
22
- const pickedKeys = (Object.keys(obj) as K[]).filter((key) => !keys.includes(key));
23
-
24
- return pick(pickedKeys, obj) as unknown as Omit<T, K>;
25
- }
@@ -1,435 +0,0 @@
1
- /**
2
- * VTEX Proxy Utility.
3
- *
4
- * Proxies storefront requests for /checkout, /account, /api, /files, /arquivos
5
- * to the VTEX origin. Essential for checkout and My Account pages to work.
6
- *
7
- * Two flavors:
8
- * - `proxyToVtex()` — simple single-origin proxy (vtexcommercestable)
9
- * - `createVtexCheckoutProxy()` — production-grade dual-origin proxy with
10
- * proper cookie attribute preservation, non-ASCII sanitization, and
11
- * configurable origin routing (checkout UI vs API paths)
12
- *
13
- * Designed to be used with TanStack Start API routes or Cloudflare Worker
14
- * fetch handlers.
15
- */
16
-
17
- import { getVtexConfig, getVtexFetch, type VtexConfig, vtexHost } from "../client";
18
- import { proxySetCookie } from "./cookies";
19
-
20
- export interface VtexProxyOptions {
21
- /**
22
- * VTEX environment suffix.
23
- * @default "vtexcommercestable"
24
- */
25
- environment?: "vtexcommercestable" | "vtexcommercebeta";
26
-
27
- /**
28
- * Additional path prefixes to proxy beyond the defaults.
29
- * Example: ["/custom-api/"]
30
- */
31
- extraPaths?: string[];
32
-
33
- /**
34
- * Paths that should NOT be proxied even if they match a prefix.
35
- */
36
- excludePaths?: string[];
37
-
38
- /**
39
- * Whether to rewrite Set-Cookie domains to the storefront's domain.
40
- * @default true
41
- */
42
- rewriteCookieDomain?: boolean;
43
-
44
- /**
45
- * Custom headers to inject into every proxied request.
46
- */
47
- extraHeaders?: Record<string, string>;
48
- }
49
-
50
- const DEFAULT_PROXY_PATHS = [
51
- "/checkout",
52
- "/checkout/",
53
- "/account",
54
- "/account/",
55
- "/api/",
56
- "/files/",
57
- "/arquivos/",
58
- "/checkout/changeToAnonymousUser/",
59
- "/_v/",
60
- "/no-cache/",
61
- "/graphql/",
62
- "/login",
63
- "/login/",
64
- "/logout",
65
- "/logout/",
66
- "/assets/vtex",
67
- "/_secure/account",
68
- "/XMLData/",
69
- ] as const;
70
-
71
- const HOP_BY_HOP_HEADERS = new Set([
72
- "connection",
73
- "keep-alive",
74
- "proxy-authenticate",
75
- "proxy-authorization",
76
- "te",
77
- "trailers",
78
- "transfer-encoding",
79
- "upgrade",
80
- ]);
81
-
82
- /**
83
- * Returns all path prefixes that should be proxied to VTEX.
84
- */
85
- export function getVtexProxyPaths(options?: VtexProxyOptions): string[] {
86
- return [...DEFAULT_PROXY_PATHS, ...(options?.extraPaths ?? [])];
87
- }
88
-
89
- /**
90
- * Check if a request path should be proxied to VTEX.
91
- */
92
- export function shouldProxyToVtex(pathname: string, options?: VtexProxyOptions): boolean {
93
- const paths = getVtexProxyPaths(options);
94
- const excluded = options?.excludePaths ?? [];
95
-
96
- if (excluded.some((ex) => pathname.startsWith(ex))) return false;
97
- return paths.some((prefix) => pathname.startsWith(prefix));
98
- }
99
-
100
- function buildOriginUrl(request: Request, config: VtexConfig, environment: string): URL {
101
- const url = new URL(request.url);
102
- const originHost = vtexHost(environment, config);
103
- return new URL(`https://${originHost}${url.pathname}${url.search}`);
104
- }
105
-
106
- /**
107
- * Copy headers excluding hop-by-hop and Set-Cookie.
108
- *
109
- * Set-Cookie is excluded intentionally: Headers.forEach / .set() joins
110
- * multiple Set-Cookie values with ", " which corrupts cookies containing
111
- * commas (e.g. Expires dates). proxySetCookie handles Set-Cookie
112
- * separately using Headers.getSetCookie() for correct multi-cookie support.
113
- */
114
- function filterHeaders(headers: Headers): Headers {
115
- const filtered = new Headers();
116
- headers.forEach((value, key) => {
117
- const lower = key.toLowerCase();
118
- if (lower === "set-cookie") return;
119
- if (!HOP_BY_HOP_HEADERS.has(lower)) {
120
- filtered.set(key, value);
121
- }
122
- });
123
- return filtered;
124
- }
125
-
126
- /**
127
- * Proxy a request to VTEX origin.
128
- *
129
- * Forwards the request with all cookies and headers, rewrites
130
- * Set-Cookie domains on the response, and strips hop-by-hop headers.
131
- *
132
- * @example
133
- * ```ts
134
- * // In a TanStack Start API route or catch-all handler
135
- * if (shouldProxyToVtex(url.pathname)) {
136
- * return proxyToVtex(request);
137
- * }
138
- * ```
139
- */
140
- export async function proxyToVtex(request: Request, options?: VtexProxyOptions): Promise<Response> {
141
- const config = getVtexConfig();
142
- const environment = options?.environment ?? "vtexcommercestable";
143
-
144
- const originUrl = buildOriginUrl(request, config, environment);
145
- const forwardHeaders = filterHeaders(new Headers(request.headers));
146
-
147
- const requestUrl = new URL(request.url);
148
- forwardHeaders.set("origin", request.headers.get("origin") ?? requestUrl.origin);
149
- forwardHeaders.set("Host", originUrl.hostname);
150
- forwardHeaders.set("X-Forwarded-Host", requestUrl.host);
151
- forwardHeaders.set("X-Forwarded-Proto", "https");
152
-
153
- if (options?.extraHeaders) {
154
- for (const [k, v] of Object.entries(options.extraHeaders)) {
155
- forwardHeaders.set(k, v);
156
- }
157
- }
158
-
159
- if (typeof config.appKey === "string" && typeof config.appToken === "string") {
160
- forwardHeaders.set("X-VTEX-API-AppKey", config.appKey);
161
- forwardHeaders.set("X-VTEX-API-AppToken", config.appToken);
162
- }
163
-
164
- const init: RequestInit = {
165
- method: request.method,
166
- headers: forwardHeaders,
167
- redirect: "manual",
168
- };
169
-
170
- if (request.method !== "GET" && request.method !== "HEAD") {
171
- init.body = request.body;
172
- // @ts-expect-error -- needed for streaming body in Workers
173
- init.duplex = "half";
174
- }
175
-
176
- // Route through the configured VTEX fetch so traces / metrics / logs
177
- // see the proxied origin call. The URL router classifies the call
178
- // into the right `vtex.<area>.<op>` bucket (e.g. `vtex.checkout.*`,
179
- // `vtex.vtexid.logout`, `vtex.io.segment`) — no per-callsite hint
180
- // needed because we're a generic forwarder.
181
- const originResponse = await getVtexFetch()(originUrl.toString(), init);
182
-
183
- const responseHeaders = filterHeaders(new Headers(originResponse.headers));
184
-
185
- proxySetCookie(
186
- originResponse.headers,
187
- responseHeaders,
188
- options?.rewriteCookieDomain !== false ? requestUrl.origin : undefined,
189
- );
190
-
191
- if (originResponse.status >= 300 && originResponse.status < 400) {
192
- const location = originResponse.headers.get("location");
193
- if (location) {
194
- const originVtexHost = vtexHost(environment, config);
195
- const storefrontOrigin = requestUrl.origin;
196
- const vtexOrigin = `https://${originVtexHost}`;
197
- const rewritten = location.replace(vtexOrigin, storefrontOrigin);
198
- responseHeaders.set("location", rewritten);
199
- }
200
- }
201
-
202
- return new Response(originResponse.body, {
203
- status: originResponse.status,
204
- statusText: originResponse.statusText,
205
- headers: responseHeaders,
206
- });
207
- }
208
-
209
- // ---------------------------------------------------------------------------
210
- // Production-grade checkout proxy factory
211
- // ---------------------------------------------------------------------------
212
-
213
- export interface VtexCheckoutProxyConfig {
214
- /** VTEX account name (e.g. "casaevideonewio"). */
215
- account: string;
216
-
217
- /**
218
- * Store's public checkout domain (e.g. "secure.casaevideo.com.br").
219
- * Checkout UI, /files/, and /_v/private/graphql are routed here.
220
- */
221
- checkoutOrigin: string;
222
-
223
- /**
224
- * VTEX commerce-stable origin for API calls.
225
- * @default `https://{account}.vtexcommercestable.com.br`
226
- */
227
- apiOrigin?: string;
228
-
229
- /**
230
- * myvtex origin — used for redirect rewriting.
231
- * @default `https://{account}.myvtex.com`
232
- */
233
- myvtexOrigin?: string;
234
-
235
- /**
236
- * VTEX TLD — most accounts use `.com.br`, but some use `.com`.
237
- * @default "com.br"
238
- */
239
- domain?: string;
240
-
241
- /**
242
- * Extra paths on which to force-expire cookies.
243
- * Useful for logout: VTEX sends Max-Age=0 for auth cookies, but the
244
- * checkout orderForm cookie sometimes survives. This appends explicit
245
- * Set-Cookie: name=; Max-Age=0 entries.
246
- */
247
- expireCookiesOnPaths?: Array<{
248
- pathPrefix: string;
249
- cookies: string[];
250
- }>;
251
-
252
- /**
253
- * Optional HTML transform for checkout pages.
254
- * Receives the full HTML string and should return the modified version.
255
- */
256
- htmlTransform?: (html: string) => string;
257
- }
258
-
259
- const CF_INTERNAL_HEADERS = new Set([
260
- "cf-connecting-ip",
261
- "cf-ipcountry",
262
- "cf-ray",
263
- "cf-visitor",
264
- "cf-ew-via",
265
- "cdn-loop",
266
- ]);
267
-
268
- const CHECKOUT_SKIP_HEADERS = new Set([
269
- ...HOP_BY_HOP_HEADERS,
270
- "set-cookie",
271
- ...CF_INTERNAL_HEADERS,
272
- ]);
273
-
274
- const toAscii = (v: string) => v.replace(/[^\x20-\x7E]/g, "");
275
-
276
- function filterHeadersStrict(headers: Headers): Headers {
277
- const filtered = new Headers();
278
- headers.forEach((value, key) => {
279
- if (CHECKOUT_SKIP_HEADERS.has(key.toLowerCase())) return;
280
- try {
281
- filtered.set(key, toAscii(value));
282
- } catch {
283
- // skip headers that still fail after sanitization
284
- }
285
- });
286
- return filtered;
287
- }
288
-
289
- /**
290
- * Rewrite Set-Cookie headers: only change the Domain attribute.
291
- * Unlike `proxySetCookie`, this preserves ALL attributes (Max-Age,
292
- * Expires, SameSite, etc.) which is critical for logout.
293
- */
294
- function rewriteSetCookieDomain(from: Headers, to: Headers, toHostname: string) {
295
- const raw: string[] =
296
- typeof from.getSetCookie === "function"
297
- ? from.getSetCookie()
298
- : (from.get("set-cookie") ?? "").split(/,(?=[^ ]+=)/).filter(Boolean);
299
-
300
- for (const cookie of raw) {
301
- const rewritten = cookie.replace(/Domain=[^;]*/i, `Domain=${toHostname}`);
302
- to.append("Set-Cookie", rewritten);
303
- }
304
- }
305
-
306
- /**
307
- * Creates a production-grade VTEX checkout proxy handler.
308
- *
309
- * Routes checkout UI pages to the store's public domain and API calls
310
- * to vtexcommercestable. Properly rewrites Set-Cookie domains (preserving
311
- * Max-Age/Expires), sanitizes non-ASCII headers, filters hop-by-hop and
312
- * CF-internal headers, and rewrites Location redirects.
313
- *
314
- * Returns a function compatible with `createDecoWorkerEntry`'s `proxyHandler`.
315
- *
316
- * @example
317
- * ```ts
318
- * const vtexProxy = createVtexCheckoutProxy({
319
- * account: "casaevideonewio",
320
- * checkoutOrigin: "secure.casaevideo.com.br",
321
- * expireCookiesOnPaths: [
322
- * { pathPrefix: "/api/vtexid/pub/logout", cookies: ["checkout.vtex.com"] },
323
- * ],
324
- * htmlTransform: (html) =>
325
- * html.replace("</head>", "<style>.body{min-height:100vh}</style></head>"),
326
- * });
327
- *
328
- * createDecoWorkerEntry(serverEntry, {
329
- * proxyHandler: async (request, url) => {
330
- * if (url.pathname === "/login") return null;
331
- * if (!shouldProxyToVtex(url.pathname)) return null;
332
- * return vtexProxy(request, url);
333
- * },
334
- * });
335
- * ```
336
- */
337
- export function createVtexCheckoutProxy(
338
- config: VtexCheckoutProxyConfig,
339
- ): (request: Request, url: URL) => Promise<Response> {
340
- const domain = config.domain ?? "com.br";
341
- const checkoutOrigin = config.checkoutOrigin.startsWith("https://")
342
- ? config.checkoutOrigin
343
- : `https://${config.checkoutOrigin}`;
344
- const apiOrigin = config.apiOrigin ?? `https://${config.account}.vtexcommercestable.${domain}`;
345
- const myvtexOrigin = config.myvtexOrigin ?? `https://${config.account}.myvtex.com`;
346
-
347
- function getOrigin(pathname: string, method: string): string {
348
- if (
349
- pathname.startsWith("/checkout") ||
350
- pathname.startsWith("/account") ||
351
- pathname.startsWith("/_secure/account") ||
352
- pathname.startsWith("/files/") ||
353
- pathname.startsWith("/_v/private/graphql")
354
- ) {
355
- return checkoutOrigin;
356
- }
357
- if (method !== "GET" && method !== "HEAD" && pathname.startsWith("/_v/")) {
358
- return checkoutOrigin;
359
- }
360
- return apiOrigin;
361
- }
362
-
363
- return async (request: Request, url: URL): Promise<Response> => {
364
- const origin = getOrigin(url.pathname, request.method);
365
- const originUrl = new URL(`${origin}${url.pathname}${url.search}`);
366
- const fwd = filterHeadersStrict(new Headers(request.headers));
367
-
368
- fwd.set("Host", originUrl.hostname);
369
- fwd.set("X-Forwarded-Host", url.host);
370
- fwd.set("X-Forwarded-Proto", "https");
371
- fwd.set("origin", request.headers.get("origin") ?? url.origin);
372
-
373
- const isCheckoutUI =
374
- url.pathname.startsWith("/checkout") || url.pathname.startsWith("/account");
375
- const isLogout = url.pathname.startsWith("/api/vtexid/pub/logout");
376
-
377
- const init: RequestInit = {
378
- method: request.method,
379
- headers: fwd,
380
- redirect: isCheckoutUI || isLogout ? "manual" : "follow",
381
- };
382
- if (request.method !== "GET" && request.method !== "HEAD") {
383
- init.body = request.body;
384
- // @ts-expect-error -- needed for streaming body in Workers
385
- init.duplex = "half";
386
- }
387
-
388
- const originRes = await getVtexFetch()(originUrl.toString(), init);
389
- const resHeaders = filterHeadersStrict(new Headers(originRes.headers));
390
- rewriteSetCookieDomain(originRes.headers, resHeaders, url.hostname);
391
-
392
- // Force-expire cookies on configured paths
393
- if (config.expireCookiesOnPaths) {
394
- for (const rule of config.expireCookiesOnPaths) {
395
- if (url.pathname.startsWith(rule.pathPrefix)) {
396
- for (const name of rule.cookies) {
397
- resHeaders.append("Set-Cookie", `${name}=; Path=/; Max-Age=0; Domain=${url.hostname}`);
398
- }
399
- }
400
- }
401
- }
402
-
403
- // Rewrite redirect Location headers from VTEX domains to storefront
404
- if (originRes.status >= 300 && originRes.status < 400) {
405
- const loc = originRes.headers.get("location");
406
- if (loc) {
407
- resHeaders.set(
408
- "location",
409
- loc
410
- .replace(checkoutOrigin, url.origin)
411
- .replace(apiOrigin, url.origin)
412
- .replace(myvtexOrigin, url.origin),
413
- );
414
- }
415
- }
416
-
417
- // HTML transform for checkout pages
418
- const ct = originRes.headers.get("content-type") ?? "";
419
- if (config.htmlTransform && ct.includes("text/html")) {
420
- const html = await originRes.text();
421
- const patched = config.htmlTransform(html);
422
- return new Response(patched, {
423
- status: originRes.status,
424
- statusText: originRes.statusText,
425
- headers: resHeaders,
426
- });
427
- }
428
-
429
- return new Response(originRes.body, {
430
- status: originRes.status,
431
- statusText: originRes.statusText,
432
- headers: resHeaders,
433
- });
434
- };
435
- }