@decocms/blocks-cli 7.64.3 → 7.65.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/blocks-cli",
3
- "version": "7.64.3",
3
+ "version": "7.65.0",
4
4
  "type": "module",
5
5
  "description": "Deco codegen (generate-blocks, generate-schema, generate-invoke) and Fresh-to-TanStack migration tooling",
6
6
  "repository": {
@@ -33,7 +33,7 @@
33
33
  "lint:unused": "knip"
34
34
  },
35
35
  "dependencies": {
36
- "@decocms/blocks": "7.64.3",
36
+ "@decocms/blocks": "7.65.0",
37
37
  "ts-morph": "^27.0.0",
38
38
  "tsx": "^4.22.5"
39
39
  },
@@ -123,15 +123,15 @@ function showHelp() {
123
123
  npx tsx scripts/deco-migrate-cli.ts https://github.com/org/my-site
124
124
 
125
125
  ${dim("# Migrate local dir, compare against golden reference:")}
126
- npx tsx scripts/deco-migrate-cli.ts ./casaevideo \\
127
- --ref ./casaevideo-storefront
126
+ npx tsx scripts/deco-migrate-cli.ts ./acme \\
127
+ --ref ./acme-storefront
128
128
 
129
129
  ${dim("# Quick re-run (wipe previous output first):")}
130
- npx tsx scripts/deco-migrate-cli.ts ./casaevideo \\
131
- -o ./casaevideo-migrated --clean
130
+ npx tsx scripts/deco-migrate-cli.ts ./acme \\
131
+ -o ./acme-migrated --clean
132
132
 
133
133
  ${dim("# Dry run to preview what would change:")}
134
- npx tsx scripts/deco-migrate-cli.ts ./casaevideo --dry-run -v
134
+ npx tsx scripts/deco-migrate-cli.ts ./acme --dry-run -v
135
135
  `);
136
136
  }
137
137
 
@@ -197,8 +197,8 @@ describe("generate-invoke.ts — default --apps-dir resolution", () => {
197
197
  // at node_modules/@decocms/apps-vtex/src/invoke.ts — NOT at the package
198
198
  // root. The old default only probed the root, never resolved on a site
199
199
  // with npm-installed packages, and forced sites to pass
200
- // `--apps-dir node_modules/@decocms/apps-vtex/src` by hand (granadobr's
201
- // migration workaround). The default must probe <pkg>/invoke.ts first,
200
+ // `--apps-dir node_modules/@decocms/apps-vtex/src` by hand (a production
201
+ // site's migration workaround). The default must probe <pkg>/invoke.ts first,
202
202
  // then <pkg>/src/invoke.ts.
203
203
 
204
204
  function makeSite(layout: "root" | "src"): { siteDir: string; cleanup: () => void } {
@@ -156,7 +156,7 @@ describe("typeToJsonSchema with intersection types", () => {
156
156
  useInMemoryFileSystem: true,
157
157
  compilerOptions: { skipLibCheck: true },
158
158
  });
159
- // Mirrors the granado header `SiteNavigationElement` recursive workaround:
159
+ // Mirrors a production header `SiteNavigationElement` recursive workaround:
160
160
  // nested children written as `Leaf & { children?: Array<…> }`. Before the
161
161
  // intersection branch these collapsed to `children: { items: { type: "string" } }`.
162
162
  const sf = project.createSourceFile(
@@ -217,7 +217,7 @@ describe("typeToJsonSchema Section-typed props", () => {
217
217
  });
218
218
  }, 30_000);
219
219
 
220
- // Regression (casaevideo footer): a component that declares its own local
220
+ // Regression (a production footer): a component that declares its own local
221
221
  // `type Section = { label; items }` used to collide with the magic name and
222
222
  // collapse into a non-editable __SECTION_REF__ picker — the footer columns
223
223
  // showed only a drag handle, no expand arrow, no form. A concretely-shaped
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * Verifies the operationally important behavior: a co-located test/spec/
11
11
  * stories/gen file sitting next to a real section must never be walked into
12
- * sectionMeta (the fila incident this generator's `walkDir` reproduced:
12
+ * sectionMeta (a production-site incident this generator's `walkDir` reproduced:
13
13
  * `sections.test.ts` became a bogus section in a site's generated output).
14
14
  */
15
15
  import * as cp from "node:child_process";
@@ -273,8 +273,8 @@ describe("generate-sections neverDefer convention", () => {
273
273
  // SectionMetaEntry interface the SAME file declares omitted the field —
274
274
  // so every generated file containing a neverDefer section failed the
275
275
  // site's typecheck (TS2353 excess property), and sites hand-patched the
276
- // interface only to have the next regeneration wipe the patch (miess's
277
- // .deco/sections.gen.ts carried exactly that TODO). The emitted interface
276
+ // interface only to have the next regeneration wipe the patch (a production
277
+ // site's .deco/sections.gen.ts carried exactly that TODO). The emitted interface
278
278
  // must match SectionMetaEntry in @decocms/blocks/cms.
279
279
  let tmpDir: string;
280
280
  let sectionsDir: string;
@@ -292,7 +292,7 @@ describe("generate-sections neverDefer convention", () => {
292
292
  });
293
293
 
294
294
  it("declares neverDefer on the emitted SectionMetaEntry interface and the generated file typechecks + imports", () => {
295
- // Mirrors miess's src/sections/Product/SearchResult.tsx.
295
+ // Mirrors a production site's src/sections/Product/SearchResult.tsx.
296
296
  fs.writeFileSync(
297
297
  path.join(sectionsDir, "SearchResult.tsx"),
298
298
  "export const neverDefer = true;\nexport default function SearchResult() { return null; }\n",
@@ -83,7 +83,7 @@ describe("pickWinner", () => {
83
83
  });
84
84
 
85
85
  it("prefers higher decode-pass count when path-status matches", () => {
86
- // The lebiscuit reproduction case: a stale single-encoded leftover with a
86
+ // A production reproduction case: a stale single-encoded leftover with a
87
87
  // newer mtime and larger size loses to the bot's double-encoded fresh file.
88
88
  const stale = cand({
89
89
  file: "pages-Home%20-%20LB-618509.json",
@@ -7,7 +7,7 @@
7
7
  * only the package dependency that needs to move.
8
8
  *
9
9
  * Mapping derived by hand against a real production site
10
- * (montecarlo-tanstack) — see the issue for the full worked table. Symbol
10
+ * (a production VTEX storefront) — see the issue for the full worked table. Symbol
11
11
  * renames and relocations mean a pure specifier-string rewrite is not
12
12
  * enough for every case; those are called out below.
13
13
  */
@@ -116,7 +116,7 @@ describe("classify (pure)", () => {
116
116
  });
117
117
 
118
118
  it("treats hx-on with a fetch attr as click-swap (the fetch wins)", () => {
119
- // Real example from als (EmailAndPassword button): hx-get +
119
+ // Real example from a production htmx storefront (EmailAndPassword button): hx-get +
120
120
  // hx-target + hx-trigger=click — engineer often piles
121
121
  // hx-on alongside, but the dominant migration path is the
122
122
  // click-swap recipe.
@@ -127,11 +127,11 @@ describe("classify (pure)", () => {
127
127
  });
128
128
 
129
129
  /* ------------------------------------------------------------------ */
130
- /* analyzeFile() — JSX walker tests using real als-shaped fixtures */
130
+ /* analyzeFile() — JSX walker tests using real htmx-shaped fixtures */
131
131
  /* ------------------------------------------------------------------ */
132
132
 
133
133
  describe("analyzeFile (real shapes)", () => {
134
- it("detects hx-on:click={useScript(...)} click handler (als AddToBagButton shape)", () => {
134
+ it("detects hx-on:click={useScript(...)} click handler (AddToBagButton shape)", () => {
135
135
  const file = `
136
136
  import { useScript } from "@deco/deco/hooks";
137
137
  export default function AddToBagButton() {
@@ -157,7 +157,7 @@ export default function AddToBagButton() {
157
157
  expect(out[0].attrs).toEqual(["hx-on:click"]);
158
158
  });
159
159
 
160
- it("detects hx-post + hx-target + hx-trigger=keyup on an input as auto-fetch (als SearchInput shape)", () => {
160
+ it("detects hx-post + hx-target + hx-trigger=keyup on an input as auto-fetch (SearchInput shape)", () => {
161
161
  const file = `
162
162
  <input
163
163
  id={searchInputId}
@@ -181,7 +181,7 @@ export default function AddToBagButton() {
181
181
  expect(out[0].attrs).toContain("hx-target");
182
182
  });
183
183
 
184
- it("detects hx-post + hx-target + hx-swap on a form as form-swap (als EmailAndPassword shape)", () => {
184
+ it("detects hx-post + hx-target + hx-swap on a form as form-swap (EmailAndPassword shape)", () => {
185
185
  const file = `
186
186
  <form
187
187
  class="flex flex-col w-full"
@@ -202,7 +202,7 @@ export default function AddToBagButton() {
202
202
  expect(out[0].attrs).toContain("hx-target");
203
203
  });
204
204
 
205
- it("detects hx-get on a button as click-swap (als ForgotPassword shape)", () => {
205
+ it("detects hx-get on a button as click-swap (ForgotPassword shape)", () => {
206
206
  const file = `
207
207
  <button
208
208
  type="button"
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Looks for `.deco-migrate.config.json` next to the source root. The file
5
5
  * is optional — without it the script falls back to a baked-in default set
6
- * of section-convention names that work for `casaevideo` and most other
6
+ * of section-convention names that work for `acme` and most other
7
7
  * Deco/VTEX sites that derived from the same template.
8
8
  *
9
9
  * The defaults are kept here (not in `transforms/section-conventions.ts`)
@@ -61,7 +61,7 @@ export interface SectionConventionSets {
61
61
  }
62
62
 
63
63
  /**
64
- * Built-in defaults. Originally extracted from `casaevideo` migration —
64
+ * Built-in defaults. Originally extracted from a production migration —
65
65
  * these names are common across Deco/VTEX storefronts that share the
66
66
  * lineage. Sites that don't have these sections are unaffected (the
67
67
  * matcher just never fires).
@@ -10,7 +10,7 @@ import { extractGoogleFonts, extractPlatform } from "./phase-analyze";
10
10
  // 3. apps/site.ts loose string match against platform name + "platform"
11
11
  // 4. .deco/blocks filenames hinting at platform
12
12
  // Strategy 3 is the false-positive trap that ate Magento sites before #211:
13
- // helsinki/granadobr's apps/site.ts imports `apps/vtex/mod.ts` for the color
13
+ // a production site's apps/site.ts imports `apps/vtex/mod.ts` for the color
14
14
  // palette, so the content matches `"vtex"` even though the real platform is
15
15
  // declared via `apps/magento.ts`. The fix adds "magento" to the platforms
16
16
  // list so Strategy 2 fires first and short-circuits before Strategy 3 can
@@ -90,7 +90,7 @@ describe("extractPlatform", () => {
90
90
  fs.rmSync(tmp, { recursive: true, force: true });
91
91
  });
92
92
 
93
- it("detects magento from apps/magento.ts (granadobr/helsinki shape)", () => {
93
+ it("detects magento from apps/magento.ts (a production site shape)", () => {
94
94
  fs.writeFileSync(path.join(tmp, "apps", "magento.ts"), "export default {};\n");
95
95
  // Also write a site.ts that imports vtex for color palettes — this is
96
96
  // what tripped Strategy 3 before #211.
@@ -113,7 +113,7 @@ describe("extractPlatform", () => {
113
113
  });
114
114
 
115
115
  it("prefers magento over vtex when both an apps/magento.ts AND a vtex string match exist", () => {
116
- // Reproduce the exact granadobr trap: apps/magento.ts is the real signal,
116
+ // Reproduce the exact production trap: apps/magento.ts is the real signal,
117
117
  // but apps/site.ts loosely contains "vtex" + "platform".
118
118
  fs.writeFileSync(path.join(tmp, "apps", "magento.ts"), "export default {};\n");
119
119
  fs.writeFileSync(
@@ -41,7 +41,7 @@ const PATTERN_DETECTORS: Array<[DetectedPattern, RegExp]> = [
41
41
  ["head-component", /<Head[\s>]/],
42
42
  ["define-app", /defineApp\(/],
43
43
  ["invoke-proxy", /proxy<Manifest/],
44
- // Bagaggio-style HTMX dynamic-section loader. Both the source file and
44
+ // legacy HTMX-style dynamic-section loader. Both the source file and
45
45
  // every call site need manual conversion to React state / createServerFn.
46
46
  ["sections-component-loader", /sections\/Component\.tsx?$/m],
47
47
  ["use-component", /import\s*\{[^}]*\buseComponent\b[^}]*\}\s*from\s*["'][^"']*sections\/Component(?:\.tsx?)?["']/],
@@ -270,7 +270,7 @@ function decideAction(
270
270
  };
271
271
  }
272
272
 
273
- // Bagaggio-style HTMX dynamic-section loader → delete and flag.
273
+ // legacy HTMX-style dynamic-section loader → delete and flag.
274
274
  // The file uses Deno-only APIs (`toFileUrl(Deno.cwd())`, `import.meta.resolve`)
275
275
  // and the `useComponent(component, props)` HTMX render-and-swap pattern, none
276
276
  // of which work on TanStack Start / Cloudflare Workers. The site author must
@@ -430,7 +430,7 @@ function extractVtexAccount(sourceDir: string): string | null {
430
430
  const fp = path.join(sourceDir, candidate);
431
431
  if (!fs.existsSync(fp)) continue;
432
432
  const content = fs.readFileSync(fp, "utf-8");
433
- // Match patterns like: casaevideo: "casaevideonewio"
433
+ // Match patterns like: acme: "acmenewio"
434
434
  const match = content.match(/vtexAn|VTEX_AN/i);
435
435
  if (match) {
436
436
  const dictMatch = content.match(/["'](\w+)["']\s*:\s*["'](\w+myvtex|\w+newio|\w+)["']/);
@@ -718,7 +718,7 @@ export function analyze(ctx: MigrationContext): void {
718
718
  f.path === "sections/Component.ts",
719
719
  );
720
720
  if (componentLoaderFile || useComponentSites.length > 0) {
721
- console.log("\n ⚠ HTMX dynamic-section loader detected (Bagaggio-style)");
721
+ console.log("\n ⚠ HTMX dynamic-section loader detected (legacy HTMX-style)");
722
722
  if (componentLoaderFile) {
723
723
  console.log(` • ${componentLoaderFile.path} (will be deleted)`);
724
724
  }
@@ -627,7 +627,7 @@ function guardUndeclaredVariables(src: string, onFix: (msg: string) => void): st
627
627
  /**
628
628
  * Migrate account.json → src/constants/account.ts and rewrite imports.
629
629
  *
630
- * Old stack: root-level `account.json` containing e.g. `"casaevideo"`
630
+ * Old stack: root-level `account.json` containing e.g. `"acme"`
631
631
  * New stack: `src/constants/account.ts` exporting `accountName`
632
632
  *
633
633
  * Also rewrites every file that imports from `account.json` (via
@@ -31,7 +31,7 @@ function getSectionMeta(ctx: MigrationContext, relPath: string): SectionMeta | u
31
31
 
32
32
  /**
33
33
  * Cached per-run section-conventions closure. Built once from the
34
- * resolved config sets (`ctx.config.sectionConventions`), so casaevideo
34
+ * resolved config sets (`ctx.config.sectionConventions`), so the built-in
35
35
  * defaults still apply when no config file exists.
36
36
  */
37
37
  let cachedSectionTransform:
@@ -227,7 +227,7 @@ export function transform(ctx: MigrationContext): void {
227
227
  "that ships HTML fragments and swaps them client-side. It does not work on TanStack Start. " +
228
228
  "Recipes: " +
229
229
  "(1) Self-contained UI toggles → keep state in React (`useState` + event handlers); " +
230
- "(2) Form submissions / mutations → `createServerFn` + `useMutation` (see casaevideo-storefront for canonical examples); " +
230
+ "(2) Form submissions / mutations → `createServerFn` + `useMutation` (see a production storefront for canonical examples); " +
231
231
  "(3) Ad-hoc data fetches → call the loader/action via `~/server/invoke` and store results in `useState`. " +
232
232
  "Remove the import after refactoring, then delete `src/sections/Component.tsx`.",
233
233
  severity: "error",
@@ -1090,8 +1090,8 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1090
1090
  sitePath: "src/sdk/useSuggestions.ts",
1091
1091
  canonicalImport: "@decocms/blocks/sdk/useSuggestions",
1092
1092
  // Fingerprint: hand-rolled hook with the module-level signal +
1093
- // serial-queue + latestQuery cancel pattern. Both casaevideo and
1094
- // baggagio independently invented this exact shape. Sites that
1093
+ // serial-queue + latestQuery cancel pattern. Multiple production sites
1094
+ // independently invented this exact shape. Sites that
1095
1095
  // already adopted `createUseSuggestions(…)` factory calls won't
1096
1096
  // match this signature.
1097
1097
  contentSignature: [
@@ -183,7 +183,7 @@ describe("classifyShimExports — type/interface declarations", () => {
183
183
  });
184
184
  });
185
185
 
186
- describe("classifyShimExports — real casaevideo-storefront fixtures", () => {
186
+ describe("classifyShimExports — real production storefront fixtures", () => {
187
187
  it("vtex-segment.ts (mixed: stub + functional)", () => {
188
188
  const code = `
189
189
  export function getSegmentFromBag(_req?: any): Record<string, unknown> | null {
@@ -26,11 +26,11 @@
26
26
  * would need real semantic analysis. False negatives are tolerable; the
27
27
  * rule still warns when *any* imported symbol from the shim is a clear
28
28
  * stub, which is enough to surface the real-world regressions we've
29
- * actually seen on production sites (casaevideo: `getSegmentFromBag`,
29
+ * actually seen on production sites (e.g. `getSegmentFromBag`,
30
30
  * `getISCookiesFromBag`, `toProduct`).
31
31
  *
32
32
  * Implementation note — string parsing, not a real TypeScript AST. The
33
- * shim files are tiny by design (the casaevideo ones are 1-39 lines).
33
+ * shim files are tiny by design (the real ones are 1-39 lines).
34
34
  * A balanced-brace body extractor + small set of stub patterns covers
35
35
  * every case observed on real sites. If this ever needs to handle
36
36
  * decorators, generics on consts, or weirder JSX forms, the right move
@@ -45,9 +45,9 @@ describe("generateCiFiles", () => {
45
45
  expect(f[".github/workflows/ci.yml"]).toContain('BUN_VERSION: "1.3.5"');
46
46
  });
47
47
 
48
- it("is de-projectized — no colombo migration-debt refs", () => {
48
+ it("is de-projectized — no site-specific migration-debt refs", () => {
49
49
  const blob = Object.values(files).join("\n");
50
- expect(blob).not.toMatch(/oficina/i);
50
+ expect(blob).not.toMatch(/sitea|siteb/i);
51
51
  expect(blob).not.toMatch(/#7[89]|#81/); // issues #78/#79/#81
52
52
  expect(blob).not.toMatch(/AGENTS\.md/);
53
53
  });
@@ -156,7 +156,7 @@ describe("generateSyncBlocksBotYml", () => {
156
156
  });
157
157
 
158
158
  it("is de-projectized — no real site/customer names", () => {
159
- expect(yml).not.toMatch(/oficina|miess|colombo/i);
159
+ expect(yml).not.toMatch(/sitea|acme|siteb/i);
160
160
  });
161
161
 
162
162
  it("runs the site's own installed CLI, or a pinned one when given", () => {
@@ -58,8 +58,8 @@ describe("generateMigrationPolicyPointerRule", () => {
58
58
  it("escapes nothing weird from siteName — siteName is used as a label only", () => {
59
59
  // We don't sanitise; we trust the migration script to pass a real
60
60
  // package name. But verify nothing surprising happens with hyphens
61
- // (a common shape, e.g. "casaevideo-storefront").
62
- const out = generateMigrationPolicyPointerRule("casaevideo-storefront");
63
- expect(out).toContain("`casaevideo-storefront`");
61
+ // (a common shape, e.g. "acme-storefront").
62
+ const out = generateMigrationPolicyPointerRule("acme-storefront");
63
+ expect(out).toContain("`acme-storefront`");
64
64
  });
65
65
  });
@@ -9,7 +9,7 @@
9
9
  * - Most sites end up importing zero of these (apps-start exports
10
10
  * direct equivalents for most VTEX utilities — see migrate#107).
11
11
  * - Eager generation creates dead `src/lib/*.ts` files that every site
12
- * then has to clean up by hand (see baggagio-tanstack#7, ~235 LOC).
12
+ * then has to clean up by hand (~235 LOC on one production migration).
13
13
  *
14
14
  * Registry shape: `"src/lib/<name>.ts"` → file contents.
15
15
  */
@@ -41,8 +41,8 @@ export function selectImportedLibTemplates(
41
41
  // Per the migration tooling policy (D3 — Throwing stubs):
42
42
  // generated stubs MUST throw at runtime so the first call surfaces the
43
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).
44
+ // a real production incident (PDP product data was being dropped on the
45
+ // floor for weeks before anyone noticed).
46
46
  //
47
47
  // Each thrown message points at the canonical replacement so the fix
48
48
  // is mechanical. `deco-post-cleanup --fix` automates the swap.
@@ -19,7 +19,7 @@
19
19
  */
20
20
 
21
21
  /**
22
- * @param workerName Cloudflare Worker name (= wrangler `name` field, e.g. "oficina-tanstack").
22
+ * @param workerName Cloudflare Worker name (= wrangler `name` field, e.g. "my-site-tanstack").
23
23
  * Used in the CF check-run name and the main preview base URL.
24
24
  */
25
25
  export function generatePerfFiles(workerName: string): Record<string, string> {
@@ -139,8 +139,8 @@ export function generateSectionLoaders(ctx: MigrationContext): string {
139
139
  // returned.
140
140
  //
141
141
  // The previous template chose mixins XOR own-loader and silently dropped
142
- // the section's loader when both were present — see als-tanstack
143
- // SearchContainerV2 SSR regression.
142
+ // the section's loader when both were present — see a production
143
+ // storefront's SearchContainer SSR regression.
144
144
  for (const meta of ctx.sectionMetas) {
145
145
  if (meta.isHeader || meta.isAccountSection || meta.isStatusOnly) continue;
146
146
  // Skip sections with no loader AND no device needs
@@ -418,7 +418,7 @@ export function generateSectionLoaders(ctx: MigrationContext): string {
418
418
  // ---------- Privacy cookie check ----------
419
419
  if (isVtex && hasPrivacyPolice) {
420
420
  entries.push(``);
421
- const vtexAccount = ctx.vtexAccount || "casaevideonewio";
421
+ const vtexAccount = ctx.vtexAccount || "acme";
422
422
  entries.push(` "site/sections/Account/PrivacyPolice.tsx": (props: any, req) => {`);
423
423
  entries.push(` const cookies = req.headers.get("cookie") ?? "";`);
424
424
  entries.push(` const logged = cookies.includes("VtexIdclientAutCookie_${vtexAccount}");`);
@@ -11,7 +11,7 @@ function discoverFonts(ctx: MigrationContext): string[] {
11
11
  const staticFonts = path.join(ctx.sourceDir, "static", "fonts");
12
12
  if (fs.existsSync(staticFonts)) return scanFontDir(staticFonts);
13
13
 
14
- // Check static-*/fonts/ (multi-brand sites like casaevideo)
14
+ // Check static-*/fonts/ (multi-brand sites)
15
15
  try {
16
16
  const entries = fs.readdirSync(ctx.sourceDir, { withFileTypes: true });
17
17
  for (const e of entries) {
@@ -11,7 +11,7 @@ import type { TransformResult } from "../types";
11
11
  * *non-optional* deep read like `ctx.salesforce.cartExtension[0]` still throws
12
12
  * — and `withSectionLoader`'s try/catch would swallow it, dropping the
13
13
  * section's props (blank render). The hand-fixed reference migration
14
- * (`granadobr-tanstack`) solves this by optional-chaining every `ctx` read.
14
+ * (a production storefront) solves this by optional-chaining every `ctx` read.
15
15
  *
16
16
  * This codemod reproduces that: every `ctx.` member-access chain becomes an
17
17
  * optional chain (`ctx?.a?.b?.[0]`). Optional chaining short-circuits to
@@ -224,7 +224,7 @@ describe("transformHtmxOnEvents — idempotency + edge cases", () => {
224
224
  });
225
225
  });
226
226
 
227
- describe("transformHtmxOnEvents — als-shaped fixtures", () => {
227
+ describe("transformHtmxOnEvents — htmx-shaped fixtures", () => {
228
228
  it("AddToBagButton: hx-on-click + Fresh useScript → onClick + TODO", () => {
229
229
  const src = `import { useScript } from "site/sdk/useScript.ts";
230
230
 
@@ -61,8 +61,8 @@ const STANDARD_EVENT_MAP: Record<string, string> = {
61
61
  * handler bodies reference Fresh-only globals (`useScript`,
62
62
  * `globalThis.window.STOREFRONT`, `STOREFRONT.*`). The comment is the
63
63
  * only file-level annotation the codemod emits — per-occurrence
64
- * comments would balloon the diff for a 88-rename file like
65
- * als-storefront's hot paths. It is detected by an idempotency check
64
+ * comments would balloon the diff for an 88-rename file like a
65
+ * production storefront's hot paths. It is detected by an idempotency check
66
66
  * so re-running the codemod does not double-inject.
67
67
  */
68
68
  const TODO_MARKER = "// MIGRATION TODO (codemod: htmx-on-event-rename):";
@@ -140,7 +140,7 @@ export interface MigrationContext {
140
140
  layout: import("./source-layout").SourceLayout;
141
141
  siteName: string;
142
142
  platform: Platform;
143
- /** VTEX account name (e.g. "casaevideonewio") — extracted from source code */
143
+ /** VTEX account name (e.g. "acme") — extracted from source code */
144
144
  vtexAccount: string | null;
145
145
  gtmId: string | null;
146
146
 
@@ -46,13 +46,13 @@ describe("migrate-to-cf-observability codemod", () => {
46
46
  fs.writeFileSync(
47
47
  wranglerPath,
48
48
  `{
49
- "name": "lebiscuit-tanstack",
49
+ "name": "acme-tanstack",
50
50
  "compatibility_date": "2026-02-14",
51
51
  "main": "./src/worker-entry.ts",
52
52
  "kv_namespaces": [{ "binding": "SITES_KV", "id": "abc" }],
53
53
  "version_metadata": { "binding": "CF_VERSION_METADATA" },
54
54
  "analytics_engine_datasets": [
55
- { "binding": "DECO_METRICS", "dataset": "deco_metrics_lebiscuit" }
55
+ { "binding": "DECO_METRICS", "dataset": "deco_metrics_acme" }
56
56
  ],
57
57
  "observability": {
58
58
  "logs": {
@@ -77,7 +77,7 @@ describe("migrate-to-cf-observability codemod", () => {
77
77
  // No destinations by default.
78
78
  expect(result).not.toContain('"destinations"');
79
79
  // Original keys preserved.
80
- expect(result).toContain('"name": "lebiscuit-tanstack"');
80
+ expect(result).toContain('"name": "acme-tanstack"');
81
81
  expect(result).toContain('"binding": "DECO_METRICS"');
82
82
  // Result must be valid JSONC.
83
83
  expect(() => JSON.parse(stripJsoncComments(result))).not.toThrow();
@@ -87,7 +87,7 @@ describe("migrate-to-cf-observability codemod", () => {
87
87
  fs.writeFileSync(
88
88
  wranglerPath,
89
89
  `{
90
- "name": "lebiscuit-tanstack",
90
+ "name": "acme-tanstack",
91
91
  "main": "./src/worker-entry.ts",
92
92
  "observability": {
93
93
  "enabled": true,
@@ -146,7 +146,7 @@ describe("migrate-to-cf-observability codemod", () => {
146
146
  fs.writeFileSync(
147
147
  wranglerPath,
148
148
  `{
149
- "name": "lebiscuit-tanstack",
149
+ "name": "acme-tanstack",
150
150
  "main": "./src/worker-entry.ts",
151
151
  "observability": {
152
152
  "logs": { "enabled": true }
@@ -21,7 +21,7 @@
21
21
  * Cloudflare captures nothing, regardless of the sub-block flags.
22
22
  * `persist: true` keeps the data queryable in the CF dashboard
23
23
  * (Workers Logs view + Traces view). Discovered the hard way during the
24
- * lebiscuit canary cutover.
24
+ * production canary cutover.
25
25
  *
26
26
  * Behavior:
27
27
  * - dry-run by default — prints a unified diff against the existing