@decocms/start 2.14.0 → 2.16.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/.agents/skills/deco-to-tanstack-migration/references/post-migration-cleanup.md +103 -3
- package/.cursor/rules/migration-tooling-policy.mdc +111 -0
- package/CLAUDE.md +4 -0
- package/MIGRATION_TOOLING_PLAN.md +891 -0
- package/package.json +1 -1
- package/scripts/migrate/post-cleanup/rules.ts +121 -3
- package/scripts/migrate/post-cleanup/runner.test.ts +102 -0
- package/scripts/migrate/templates/lib-utils.test.ts +48 -0
- package/scripts/migrate/templates/lib-utils.ts +51 -12
package/package.json
CHANGED
|
@@ -239,6 +239,123 @@ const ruleSiteLocalGlobals: Rule = {
|
|
|
239
239
|
/* Rule 5 — `~/lib/vtex-*` shim regression */
|
|
240
240
|
/* ------------------------------------------------------------------ */
|
|
241
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Per-symbol guidance for the canonical replacement of each known
|
|
244
|
+
* shim stub. Used by the `vtex-shim-regression` rule to compose
|
|
245
|
+
* actionable `fix:` messages instead of the generic "Repoint imports"
|
|
246
|
+
* fallback.
|
|
247
|
+
*
|
|
248
|
+
* Kept as data (not code) so the JSON output of the audit can carry
|
|
249
|
+
* structured fix metadata for downstream tooling (CI dashboards,
|
|
250
|
+
* follow-up auto-fix rules, etc.).
|
|
251
|
+
*
|
|
252
|
+
* Categories:
|
|
253
|
+
* - `swap`: 1:1 import swap is safe — caller imports the symbol from
|
|
254
|
+
* `canonical` instead of the local shim. Note may flag a signature
|
|
255
|
+
* gotcha that the caller has to address at the call site.
|
|
256
|
+
* - `refactor`: a call-site rewrite is required (typically because the
|
|
257
|
+
* stub's "bag-based" API has no analog on TanStack Start; the request
|
|
258
|
+
* headers are the new source of truth). The note explains the pattern.
|
|
259
|
+
*
|
|
260
|
+
* Symbols absent from this table fall back to the generic guidance.
|
|
261
|
+
* The rule still flags them — only the `fix:` prose changes.
|
|
262
|
+
*/
|
|
263
|
+
export type FixHint =
|
|
264
|
+
| { kind: "swap"; canonical: string; note?: string }
|
|
265
|
+
| { kind: "refactor"; note: string };
|
|
266
|
+
|
|
267
|
+
export const STUB_FIX_HINTS: Record<string, FixHint> = {
|
|
268
|
+
// src/lib/vtex-transform
|
|
269
|
+
toProduct: {
|
|
270
|
+
kind: "swap",
|
|
271
|
+
canonical: "@decocms/apps/vtex/utils/transform",
|
|
272
|
+
note:
|
|
273
|
+
"canonical signature is `toProduct(product, sku, level, options)`; " +
|
|
274
|
+
"1-arg call sites need to expand args first — see skill § 5",
|
|
275
|
+
},
|
|
276
|
+
// src/lib/vtex-segment
|
|
277
|
+
getSegmentFromBag: {
|
|
278
|
+
kind: "refactor",
|
|
279
|
+
note:
|
|
280
|
+
"read cookies via `request.headers.get('cookie')` then call " +
|
|
281
|
+
"`buildSegmentFromCookies()` from '@decocms/apps/vtex/utils/segment'. " +
|
|
282
|
+
"The bag-based lookup mechanism does not exist on TanStack Start.",
|
|
283
|
+
},
|
|
284
|
+
withSegmentCookie: {
|
|
285
|
+
kind: "swap",
|
|
286
|
+
canonical: "@decocms/apps/vtex/utils/segment",
|
|
287
|
+
note:
|
|
288
|
+
"canonical signature is `withSegmentCookie(segment, headers?)`; " +
|
|
289
|
+
"if you currently pass only headers, also pass a segment object",
|
|
290
|
+
},
|
|
291
|
+
// src/lib/vtex-intelligent-search
|
|
292
|
+
getISCookiesFromBag: {
|
|
293
|
+
kind: "refactor",
|
|
294
|
+
note:
|
|
295
|
+
"extract IS cookies from `request.headers.get('cookie')` directly. " +
|
|
296
|
+
"The bag-based lookup mechanism does not exist on TanStack Start.",
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Format a single symbol's fix guidance as a one-liner suitable for
|
|
302
|
+
* the audit's `fix:` field. Returns undefined when the symbol has no
|
|
303
|
+
* specific entry in `STUB_FIX_HINTS`.
|
|
304
|
+
*/
|
|
305
|
+
export function formatFixHint(symbol: string): string | undefined {
|
|
306
|
+
const hint = STUB_FIX_HINTS[symbol];
|
|
307
|
+
if (!hint) return undefined;
|
|
308
|
+
if (hint.kind === "swap") {
|
|
309
|
+
const head = `${symbol} → ${hint.canonical} (1:1 import swap)`;
|
|
310
|
+
return hint.note ? `${head} — ${hint.note}` : head;
|
|
311
|
+
}
|
|
312
|
+
return `${symbol} → call-site refactor: ${hint.note}`;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Compose the `fix:` message for a finding from the per-shim stub map.
|
|
317
|
+
* Splits symbols into "have specific guidance" vs "fall back to generic".
|
|
318
|
+
* Output joins each piece with ` | ` so the message stays one logical
|
|
319
|
+
* line even when there are several stubs.
|
|
320
|
+
*/
|
|
321
|
+
export function buildVtexShimFixMessage(stubsBySim: Map<string, string[]>): string {
|
|
322
|
+
const known: string[] = [];
|
|
323
|
+
const unknown: string[] = [];
|
|
324
|
+
for (const syms of stubsBySim.values()) {
|
|
325
|
+
for (const s of syms) {
|
|
326
|
+
const hint = formatFixHint(s);
|
|
327
|
+
if (hint) known.push(hint);
|
|
328
|
+
else unknown.push(s);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const parts: string[] = [...known];
|
|
332
|
+
if (unknown.length > 0) {
|
|
333
|
+
parts.push(
|
|
334
|
+
`${unknown.join(", ")} → repoint to '@decocms/apps/vtex/...' or 'apps/commerce/utils/...'`,
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
return parts.length > 0
|
|
338
|
+
? parts.join(" | ")
|
|
339
|
+
: "Repoint imports to '@decocms/apps/vtex/...' or 'apps/commerce/utils/...'";
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Build the structured `fixHints` payload for `meta` so JSON consumers
|
|
344
|
+
* (CI dashboards, follow-up tooling) can render their own UI. Each
|
|
345
|
+
* entry is keyed by symbol; symbols without specific guidance are
|
|
346
|
+
* omitted (the prose fallback covers them).
|
|
347
|
+
*/
|
|
348
|
+
function fixHintsToMeta(stubsBySim: Map<string, string[]>): Record<string, FixHint> {
|
|
349
|
+
const out: Record<string, FixHint> = {};
|
|
350
|
+
for (const syms of stubsBySim.values()) {
|
|
351
|
+
for (const s of syms) {
|
|
352
|
+
const hint = STUB_FIX_HINTS[s];
|
|
353
|
+
if (hint) out[s] = hint;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return out;
|
|
357
|
+
}
|
|
358
|
+
|
|
242
359
|
/**
|
|
243
360
|
* Parse one or more ES `import { a, b as c, type d } from "spec"` blocks
|
|
244
361
|
* targeting a specific source spec out of a file. Returns the list of
|
|
@@ -319,16 +436,17 @@ const ruleVtexShimRegression: Rule = {
|
|
|
319
436
|
const rel = abs.slice(siteDir.length + 1);
|
|
320
437
|
const detail = [...stubsBySim.entries()]
|
|
321
438
|
.map(([s, syms]) => `${s} (${syms.join(", ")})`)
|
|
322
|
-
.join("; ")
|
|
323
|
-
;
|
|
439
|
+
.join("; ");
|
|
440
|
+
const fixHintsMeta = fixHintsToMeta(stubsBySim);
|
|
324
441
|
findings.push({
|
|
325
442
|
rule: "vtex-shim-regression",
|
|
326
443
|
severity: "warning",
|
|
327
444
|
file: rel,
|
|
328
445
|
message: `Imports stub-only symbols from ${detail} — runtime is silently stubbed`,
|
|
329
|
-
fix:
|
|
446
|
+
fix: buildVtexShimFixMessage(stubsBySim),
|
|
330
447
|
meta: {
|
|
331
448
|
stubsBySim: Object.fromEntries(stubsBySim),
|
|
449
|
+
...(Object.keys(fixHintsMeta).length > 0 ? { fixHints: fixHintsMeta } : {}),
|
|
332
450
|
},
|
|
333
451
|
});
|
|
334
452
|
}
|
|
@@ -404,6 +404,108 @@ describe("rule: vtex-shim-regression", () => {
|
|
|
404
404
|
});
|
|
405
405
|
});
|
|
406
406
|
|
|
407
|
+
describe("rule: vtex-shim-regression — per-symbol fix hints", () => {
|
|
408
|
+
it("emits 1:1 swap hint for `toProduct`", () => {
|
|
409
|
+
const fs = makeFs({
|
|
410
|
+
"/site/src/lib/vtex-transform.ts":
|
|
411
|
+
"export function toProduct(p: any): unknown { return p as unknown; }\n",
|
|
412
|
+
"/site/src/loaders/x.ts":
|
|
413
|
+
'import { toProduct } from "~/lib/vtex-transform";\n',
|
|
414
|
+
});
|
|
415
|
+
const report = runAudit(SITE, fs);
|
|
416
|
+
const r = report.rules.find((r) => r.rule === "vtex-shim-regression")!;
|
|
417
|
+
expect(r.findings).toHaveLength(1);
|
|
418
|
+
const f = r.findings[0];
|
|
419
|
+
expect(f.fix).toContain("toProduct → @decocms/apps/vtex/utils/transform");
|
|
420
|
+
expect(f.fix).toContain("1:1 import swap");
|
|
421
|
+
expect(f.meta?.fixHints).toEqual({
|
|
422
|
+
toProduct: {
|
|
423
|
+
kind: "swap",
|
|
424
|
+
canonical: "@decocms/apps/vtex/utils/transform",
|
|
425
|
+
note: expect.stringContaining("canonical signature"),
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it("emits refactor hint for `getSegmentFromBag`", () => {
|
|
431
|
+
const fs = makeFs({
|
|
432
|
+
"/site/src/lib/vtex-segment.ts":
|
|
433
|
+
"export function getSegmentFromBag(): null { return null; }\n",
|
|
434
|
+
"/site/src/loaders/x.ts":
|
|
435
|
+
'import { getSegmentFromBag } from "~/lib/vtex-segment";\n',
|
|
436
|
+
});
|
|
437
|
+
const report = runAudit(SITE, fs);
|
|
438
|
+
const r = report.rules.find((r) => r.rule === "vtex-shim-regression")!;
|
|
439
|
+
const f = r.findings[0];
|
|
440
|
+
expect(f.fix).toContain("getSegmentFromBag → call-site refactor");
|
|
441
|
+
expect(f.fix).toContain("buildSegmentFromCookies");
|
|
442
|
+
expect(f.meta?.fixHints).toEqual({
|
|
443
|
+
getSegmentFromBag: {
|
|
444
|
+
kind: "refactor",
|
|
445
|
+
note: expect.stringContaining("buildSegmentFromCookies"),
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it("composes hints for files with multiple stubs", () => {
|
|
451
|
+
const fs = makeFs({
|
|
452
|
+
"/site/src/lib/vtex-segment.ts":
|
|
453
|
+
"export function getSegmentFromBag(): null { return null; }\n",
|
|
454
|
+
"/site/src/lib/vtex-transform.ts":
|
|
455
|
+
"export function toProduct(p: any): unknown { return p as unknown; }\n",
|
|
456
|
+
"/site/src/loaders/x.ts":
|
|
457
|
+
'import { getSegmentFromBag } from "~/lib/vtex-segment";\n' +
|
|
458
|
+
'import { toProduct } from "~/lib/vtex-transform";\n',
|
|
459
|
+
});
|
|
460
|
+
const report = runAudit(SITE, fs);
|
|
461
|
+
const r = report.rules.find((r) => r.rule === "vtex-shim-regression")!;
|
|
462
|
+
const f = r.findings[0];
|
|
463
|
+
expect(f.fix).toContain("getSegmentFromBag → call-site refactor");
|
|
464
|
+
expect(f.fix).toContain("toProduct → @decocms/apps/vtex/utils/transform");
|
|
465
|
+
// Joined with " | " for visual separation.
|
|
466
|
+
expect(f.fix).toContain(" | ");
|
|
467
|
+
expect(Object.keys(f.meta?.fixHints as object)).toEqual(
|
|
468
|
+
expect.arrayContaining(["toProduct", "getSegmentFromBag"]),
|
|
469
|
+
);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it("falls back to generic hint for symbols without entries", () => {
|
|
473
|
+
const fs = makeFs({
|
|
474
|
+
"/site/src/lib/vtex-mystery.ts":
|
|
475
|
+
"export function unknownStub(): null { return null; }\n",
|
|
476
|
+
"/site/src/loaders/x.ts":
|
|
477
|
+
'import { unknownStub } from "~/lib/vtex-mystery";\n',
|
|
478
|
+
});
|
|
479
|
+
const report = runAudit(SITE, fs);
|
|
480
|
+
const r = report.rules.find((r) => r.rule === "vtex-shim-regression")!;
|
|
481
|
+
const f = r.findings[0];
|
|
482
|
+
expect(f.fix).toContain("unknownStub → repoint to '@decocms/apps/vtex/...");
|
|
483
|
+
// No fixHints in meta when no symbols match the table.
|
|
484
|
+
expect(f.meta?.fixHints).toBeUndefined();
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it("mixes specific hints and generic fallback in one message", () => {
|
|
488
|
+
const fs = makeFs({
|
|
489
|
+
"/site/src/lib/vtex-transform.ts":
|
|
490
|
+
"export function toProduct(p: any): unknown { return p as unknown; }\n",
|
|
491
|
+
"/site/src/lib/vtex-mystery.ts":
|
|
492
|
+
"export function unknownStub(): null { return null; }\n",
|
|
493
|
+
"/site/src/loaders/x.ts":
|
|
494
|
+
'import { toProduct } from "~/lib/vtex-transform";\n' +
|
|
495
|
+
'import { unknownStub } from "~/lib/vtex-mystery";\n',
|
|
496
|
+
});
|
|
497
|
+
const report = runAudit(SITE, fs);
|
|
498
|
+
const r = report.rules.find((r) => r.rule === "vtex-shim-regression")!;
|
|
499
|
+
const f = r.findings[0];
|
|
500
|
+
expect(f.fix).toContain("toProduct → @decocms/apps/vtex/utils/transform");
|
|
501
|
+
expect(f.fix).toContain("unknownStub → repoint");
|
|
502
|
+
// Only the known symbol shows up in fixHints.
|
|
503
|
+
expect(f.meta?.fixHints).toEqual({
|
|
504
|
+
toProduct: expect.objectContaining({ kind: "swap" }),
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
|
|
407
509
|
describe("rule: local-widgets-types", () => {
|
|
408
510
|
it("flags presence of src/types/widgets.ts and counts imports", () => {
|
|
409
511
|
const fs = makeFs({
|
|
@@ -89,3 +89,51 @@ describe("selectImportedLibTemplates()", () => {
|
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
});
|
|
92
|
+
|
|
93
|
+
describe("D3 — generated stubs throw at runtime", () => {
|
|
94
|
+
// Each stub MUST throw an Error whose message identifies:
|
|
95
|
+
// - the stub path so the dev sees it in their stack trace
|
|
96
|
+
// - the canonical replacement (so the fix is mechanical)
|
|
97
|
+
//
|
|
98
|
+
// See migration-tooling-policy.mdc § Decision 3.
|
|
99
|
+
it("vtex-transform.toProduct throws and points at the canonical path", () => {
|
|
100
|
+
const src = LIB_TEMPLATES["src/lib/vtex-transform.ts"];
|
|
101
|
+
expect(src).toMatch(/throw new Error/);
|
|
102
|
+
expect(src).toMatch(/@decocms\/apps\/vtex\/utils\/transform/);
|
|
103
|
+
expect(src).toMatch(/\[deco-migrate\]/);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("vtex-intelligent-search.getISCookiesFromBag throws", () => {
|
|
107
|
+
const src = LIB_TEMPLATES["src/lib/vtex-intelligent-search.ts"];
|
|
108
|
+
expect(src).toMatch(/getISCookiesFromBag[\s\S]*?throw new Error/);
|
|
109
|
+
expect(src).toMatch(/\[deco-migrate\]/);
|
|
110
|
+
// The other helpers in this file (isFilterParam, toPath,
|
|
111
|
+
// withDefaultFacets, withDefaultParams) are real impls — must not
|
|
112
|
+
// throw.
|
|
113
|
+
expect(src).toMatch(/export function isFilterParam[\s\S]*?return key\.startsWith/);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("vtex-segment.getSegmentFromBag and withSegmentCookie both throw", () => {
|
|
117
|
+
const src = LIB_TEMPLATES["src/lib/vtex-segment.ts"];
|
|
118
|
+
expect(src).toMatch(/getSegmentFromBag[\s\S]*?throw new Error/);
|
|
119
|
+
expect(src).toMatch(/withSegmentCookie[\s\S]*?throw new Error/);
|
|
120
|
+
expect(src).toMatch(/@decocms\/apps\/vtex\/utils\/segment/);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("non-stub helpers stay implemented (negative check — no throw)", () => {
|
|
124
|
+
// These are real impls, not stubs. They must not throw.
|
|
125
|
+
const real = [
|
|
126
|
+
"src/lib/http-utils.ts",
|
|
127
|
+
"src/lib/vtex-id.ts",
|
|
128
|
+
"src/lib/graphql-utils.ts",
|
|
129
|
+
"src/lib/filter-navigate.ts",
|
|
130
|
+
"src/lib/fetch-utils.ts",
|
|
131
|
+
];
|
|
132
|
+
for (const key of real) {
|
|
133
|
+
const src = LIB_TEMPLATES[key];
|
|
134
|
+
expect(src, `${key} should not contain a generated stub throw`).not.toMatch(
|
|
135
|
+
/\[deco-migrate\][^"]*generated stub/,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -38,15 +38,41 @@ export function selectImportedLibTemplates(
|
|
|
38
38
|
return out;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// Per the migration tooling policy (D3 — Throwing stubs):
|
|
42
|
+
// generated stubs MUST throw at runtime so the first call surfaces the
|
|
43
|
+
// gap loudly. Silent identity-cast `toProduct` was the bug behind
|
|
44
|
+
// baggagio-tanstack#10 (PDP product data was being dropped on the floor
|
|
45
|
+
// for weeks before anyone noticed).
|
|
46
|
+
//
|
|
47
|
+
// Each thrown message points at the canonical replacement so the fix
|
|
48
|
+
// is mechanical. `deco-post-cleanup --fix` automates the swap.
|
|
41
49
|
const LIB_VTEX_TRANSFORM = `import type { Product } from "@decocms/apps/commerce/types";
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
const STUB =
|
|
52
|
+
"[deco-migrate] \`~/lib/vtex-transform.toProduct\` is a generated stub. " +
|
|
53
|
+
"Replace with: import { toProduct } from '@decocms/apps/vtex/utils/transform' " +
|
|
54
|
+
"(canonical signature: \`toProduct(product, sku, level, options)\`). " +
|
|
55
|
+
"Run \`deco-post-cleanup --fix\` or see the deco-to-tanstack-migration skill " +
|
|
56
|
+
"(post-migration-cleanup § 5).";
|
|
57
|
+
|
|
58
|
+
export function toProduct(_vtexProduct: any, ..._rest: any[]): Product {
|
|
59
|
+
throw new Error(STUB);
|
|
45
60
|
}
|
|
46
61
|
`;
|
|
47
62
|
|
|
48
|
-
const LIB_VTEX_INTELLIGENT_SEARCH =
|
|
49
|
-
|
|
63
|
+
const LIB_VTEX_INTELLIGENT_SEARCH = `// Per the migration tooling policy (D3): \`getISCookiesFromBag\` cannot
|
|
64
|
+
// be implemented on TanStack Start because the bag-based lookup
|
|
65
|
+
// mechanism does not exist. Sites must read cookies directly from the
|
|
66
|
+
// request — see the \`vtex-shim-regression\` audit rule for guidance.
|
|
67
|
+
const STUB_GET_IS_COOKIES =
|
|
68
|
+
"[deco-migrate] \`~/lib/vtex-intelligent-search.getISCookiesFromBag\` is a " +
|
|
69
|
+
"generated stub. Refactor: extract IS cookies from " +
|
|
70
|
+
"\`request.headers.get('cookie')\` directly. The bag-based lookup mechanism " +
|
|
71
|
+
"does not exist on TanStack Start. See the deco-to-tanstack-migration " +
|
|
72
|
+
"skill (post-migration-cleanup § 5).";
|
|
73
|
+
|
|
74
|
+
export function getISCookiesFromBag(_req?: any): Record<string, string> {
|
|
75
|
+
throw new Error(STUB_GET_IS_COOKIES);
|
|
50
76
|
}
|
|
51
77
|
|
|
52
78
|
export function isFilterParam(key: string): boolean {
|
|
@@ -85,17 +111,30 @@ export function withDefaultParams(
|
|
|
85
111
|
}
|
|
86
112
|
`;
|
|
87
113
|
|
|
88
|
-
const LIB_VTEX_SEGMENT =
|
|
89
|
-
|
|
114
|
+
const LIB_VTEX_SEGMENT = `// Per the migration tooling policy (D3): both these stubs throw at
|
|
115
|
+
// runtime to force the call site to be fixed. Silent fallbacks here
|
|
116
|
+
// mean the storefront silently fails to forward VTEX segment data
|
|
117
|
+
// (sales channel, regionId, currency, etc.) and pricing/inventory
|
|
118
|
+
// quietly diverge from what the user should see.
|
|
119
|
+
const STUB_GET_SEGMENT_FROM_BAG =
|
|
120
|
+
"[deco-migrate] \`~/lib/vtex-segment.getSegmentFromBag\` is a generated " +
|
|
121
|
+
"stub. Refactor: read cookies via \`request.headers.get('cookie')\` then " +
|
|
122
|
+
"call \`buildSegmentFromCookies()\` from '@decocms/apps/vtex/utils/segment'. " +
|
|
123
|
+
"The bag-based lookup mechanism does not exist on TanStack Start.";
|
|
124
|
+
|
|
125
|
+
const STUB_WITH_SEGMENT_COOKIE =
|
|
126
|
+
"[deco-migrate] \`~/lib/vtex-segment.withSegmentCookie\` is a generated " +
|
|
127
|
+
"stub. Replace with: import { withSegmentCookie } from " +
|
|
128
|
+
"'@decocms/apps/vtex/utils/segment' (canonical signature: " +
|
|
129
|
+
"\`withSegmentCookie(segment, headers?)\`). Run \`deco-post-cleanup --fix\` " +
|
|
130
|
+
"or see the deco-to-tanstack-migration skill.";
|
|
131
|
+
|
|
132
|
+
export function getSegmentFromBag(_req?: any): Record<string, unknown> | null {
|
|
133
|
+
throw new Error(STUB_GET_SEGMENT_FROM_BAG);
|
|
90
134
|
}
|
|
91
135
|
|
|
92
136
|
export function withSegmentCookie(..._args: any[]): any {
|
|
93
|
-
|
|
94
|
-
if (arg instanceof Headers) {
|
|
95
|
-
return arg;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return new Headers();
|
|
137
|
+
throw new Error(STUB_WITH_SEGMENT_COOKIE);
|
|
99
138
|
}
|
|
100
139
|
`;
|
|
101
140
|
|