@decocms/apps 1.15.0-next.2 → 1.15.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.
- package/package.json +3 -3
- package/vtex/client.ts +51 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decocms/apps",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Deco commerce apps for TanStack Start - Shopify, VTEX, commerce types, analytics utils",
|
|
6
6
|
"exports": {
|
|
@@ -109,14 +109,14 @@
|
|
|
109
109
|
"access": "public"
|
|
110
110
|
},
|
|
111
111
|
"peerDependencies": {
|
|
112
|
-
"@decocms/start": ">=5.3.0
|
|
112
|
+
"@decocms/start": ">=5.3.0",
|
|
113
113
|
"@tanstack/react-query": ">=5",
|
|
114
114
|
"react": ">=18",
|
|
115
115
|
"react-dom": ">=18"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
118
118
|
"@biomejs/biome": "^2.4.7",
|
|
119
|
-
"@decocms/start": "5.3.0
|
|
119
|
+
"@decocms/start": "5.3.0",
|
|
120
120
|
"@semantic-release/exec": "^7.1.0",
|
|
121
121
|
"@tanstack/react-query": "^5.90.21",
|
|
122
122
|
"@types/react": "^19.0.0",
|
package/vtex/client.ts
CHANGED
|
@@ -241,11 +241,7 @@ export async function vtexFetchResponse(
|
|
|
241
241
|
|
|
242
242
|
const response = await _fetch(url, {
|
|
243
243
|
...init,
|
|
244
|
-
headers:
|
|
245
|
-
...authHeaders(),
|
|
246
|
-
...(segmentCookie ? { cookie: segmentCookie } : {}),
|
|
247
|
-
...init?.headers,
|
|
248
|
-
},
|
|
244
|
+
headers: mergeHeaders(authHeaders(), segmentCookie, init?.headers),
|
|
249
245
|
});
|
|
250
246
|
if (!response.ok) {
|
|
251
247
|
throw new Error(`VTEX API error: ${response.status} ${response.statusText} - ${url}`);
|
|
@@ -253,6 +249,37 @@ export async function vtexFetchResponse(
|
|
|
253
249
|
return response;
|
|
254
250
|
}
|
|
255
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Combine framework headers + optional segment cookie + caller headers,
|
|
254
|
+
* preserving the precedence "caller wins" regardless of whether the
|
|
255
|
+
* caller passed `Headers`, `string[][]`, or `Record<string, string>`.
|
|
256
|
+
*
|
|
257
|
+
* Why a helper: the naive `{ ...authHeaders, ...init?.headers }` spread
|
|
258
|
+
* silently collapses a `Headers` instance to `{}` (Headers has no own
|
|
259
|
+
* enumerable entries), which means any cookies the caller put on a
|
|
260
|
+
* Headers object are lost on the wire. The `createVtexCheckoutProxy`
|
|
261
|
+
* factory passes init with Headers, which makes this the failure mode
|
|
262
|
+
* for every forwarder that relies on browser-supplied cookies reaching
|
|
263
|
+
* VTEX. Funneling all merges through the `Headers` constructor (which
|
|
264
|
+
* correctly absorbs every HeadersInit shape) keeps the bug from
|
|
265
|
+
* sneaking back in.
|
|
266
|
+
*/
|
|
267
|
+
function mergeHeaders(
|
|
268
|
+
auth: Record<string, string>,
|
|
269
|
+
segmentCookie: string | null,
|
|
270
|
+
callerHeaders: HeadersInit | undefined,
|
|
271
|
+
): Headers {
|
|
272
|
+
const merged = new Headers(auth);
|
|
273
|
+
if (segmentCookie) merged.set("cookie", segmentCookie);
|
|
274
|
+
if (callerHeaders) {
|
|
275
|
+
const incoming = new Headers(callerHeaders);
|
|
276
|
+
incoming.forEach((value, key) => {
|
|
277
|
+
merged.set(key, value);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return merged;
|
|
281
|
+
}
|
|
282
|
+
|
|
256
283
|
export async function vtexFetch<T>(path: string, init?: InstrumentedFetchInit): Promise<T> {
|
|
257
284
|
const response = await vtexFetchResponse(path, init);
|
|
258
285
|
return response.json();
|
|
@@ -282,12 +309,22 @@ export async function vtexCachedFetch<T>(
|
|
|
282
309
|
? { ttl: cacheOpts.cacheTTL }
|
|
283
310
|
: undefined;
|
|
284
311
|
|
|
312
|
+
// Mirrors vtexFetchResponse: Legacy Catalog and several other GET
|
|
313
|
+
// endpoints gate regional seller availability on the `vtex_segment`
|
|
314
|
+
// cookie. Cached GETs (PDP / shelf product lookups) must see the same
|
|
315
|
+
// regionalization the rest of the stack does — otherwise sites have
|
|
316
|
+
// to wrap _fetch themselves to forward the cookie, which is easy to
|
|
317
|
+
// get subtly wrong (especially around HeadersInit shapes). Inline
|
|
318
|
+
// here keeps the surface small; if a third callsite appears we
|
|
319
|
+
// extract a shared helper.
|
|
320
|
+
const segmentCookie = !hasCookieHeader(init?.headers) ? getSegmentCookieHeader() : null;
|
|
321
|
+
|
|
285
322
|
return fetchWithCache<T>(
|
|
286
323
|
url,
|
|
287
324
|
() =>
|
|
288
325
|
_fetch(url, {
|
|
289
326
|
...init,
|
|
290
|
-
headers:
|
|
327
|
+
headers: mergeHeaders(authHeaders(), segmentCookie, init?.headers),
|
|
291
328
|
}),
|
|
292
329
|
opts,
|
|
293
330
|
);
|
|
@@ -383,6 +420,14 @@ export async function intelligentSearch<T>(
|
|
|
383
420
|
const headers: Record<string, string> = { ...authHeaders() };
|
|
384
421
|
if (opts?.cookieHeader) {
|
|
385
422
|
headers.cookie = opts.cookieHeader;
|
|
423
|
+
} else {
|
|
424
|
+
// IS already gets regionId on the query string above, but some
|
|
425
|
+
// internal IS flows (and downstream services it consults) still
|
|
426
|
+
// honor the `vtex_segment` cookie — forward it when the caller
|
|
427
|
+
// didn't pass an explicit one. See vtexCachedFetch for the same
|
|
428
|
+
// rationale.
|
|
429
|
+
const segmentCookie = getSegmentCookieHeader();
|
|
430
|
+
if (segmentCookie) headers.cookie = segmentCookie;
|
|
386
431
|
}
|
|
387
432
|
|
|
388
433
|
const fullUrl = url.toString();
|