@decocms/start 2.4.2 → 2.6.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.
Files changed (48) hide show
  1. package/.agents/skills/deco-to-tanstack-migration/SKILL.md +1 -0
  2. package/.agents/skills/deco-to-tanstack-migration/references/post-migration-cleanup.md +163 -0
  3. package/.agents/skills/deco-to-tanstack-migration/references/vite-config/README.md +27 -2
  4. package/.agents/skills/deco-to-tanstack-migration/templates/vite-config.md +143 -68
  5. package/.cursor/skills/deco-to-tanstack-migration/SKILL.md +1 -0
  6. package/.cursor/skills/deco-to-tanstack-migration/references/post-migration-cleanup.md +163 -0
  7. package/.cursor/skills/deco-to-tanstack-migration/references/vite-config/README.md +27 -2
  8. package/.cursor/skills/deco-to-tanstack-migration/templates/vite-config.md +143 -68
  9. package/package.json +1 -1
  10. package/scripts/deco-migrate-cli.ts +1 -1
  11. package/scripts/migrate/analyzers/island-classifier.ts +2 -2
  12. package/scripts/migrate/analyzers/loader-inventory.ts +2 -2
  13. package/scripts/migrate/analyzers/section-metadata.ts +2 -2
  14. package/scripts/migrate/analyzers/theme-extractor.ts +2 -2
  15. package/scripts/migrate/phase-analyze.ts +6 -6
  16. package/scripts/migrate/phase-cleanup.test.ts +141 -0
  17. package/scripts/migrate/phase-cleanup.ts +134 -35
  18. package/scripts/migrate/phase-report.ts +2 -2
  19. package/scripts/migrate/phase-scaffold.ts +26 -22
  20. package/scripts/migrate/phase-transform.ts +9 -9
  21. package/scripts/migrate/phase-verify.ts +2 -2
  22. package/scripts/migrate/templates/app-css.ts +2 -2
  23. package/scripts/migrate/templates/cache-config.ts +1 -1
  24. package/scripts/migrate/templates/commerce-loaders.ts +1 -1
  25. package/scripts/migrate/templates/hooks.ts +1 -1
  26. package/scripts/migrate/templates/lib-utils.test.ts +91 -0
  27. package/scripts/migrate/templates/lib-utils.ts +51 -19
  28. package/scripts/migrate/templates/package-json.ts +1 -1
  29. package/scripts/migrate/templates/routes.ts +1 -1
  30. package/scripts/migrate/templates/sdk-gen.ts +1 -1
  31. package/scripts/migrate/templates/section-loaders.ts +1 -1
  32. package/scripts/migrate/templates/server-entry.ts +1 -1
  33. package/scripts/migrate/templates/setup.ts +1 -1
  34. package/scripts/migrate/templates/types-gen.ts +1 -1
  35. package/scripts/migrate/templates/ui-components.ts +1 -1
  36. package/scripts/migrate/templates/vite-config.ts +1 -1
  37. package/scripts/migrate/templates/wrangler.ts +1 -1
  38. package/scripts/migrate/transforms/dead-code.ts +1 -1
  39. package/scripts/migrate/transforms/deno-isms.ts +1 -1
  40. package/scripts/migrate/transforms/fresh-apis.ts +1 -1
  41. package/scripts/migrate/transforms/imports.ts +1 -1
  42. package/scripts/migrate/transforms/jsx.ts +1 -1
  43. package/scripts/migrate/transforms/section-conventions.ts +1 -1
  44. package/scripts/migrate/transforms/tailwind.ts +1 -1
  45. package/scripts/migrate.ts +8 -8
  46. package/src/cms/sectionLoaders.test.ts +4 -1
  47. package/src/vite/plugin.js +47 -10
  48. package/vitest.config.ts +11 -1
@@ -25,14 +25,14 @@
25
25
 
26
26
  import * as path from "node:path";
27
27
  import { execSync } from "node:child_process";
28
- import { createContext, logPhase } from "./migrate/types.ts";
29
- import { analyze } from "./migrate/phase-analyze.ts";
30
- import { scaffold } from "./migrate/phase-scaffold.ts";
31
- import { transform } from "./migrate/phase-transform.ts";
32
- import { cleanup } from "./migrate/phase-cleanup.ts";
33
- import { report } from "./migrate/phase-report.ts";
34
- import { verify } from "./migrate/phase-verify.ts";
35
- import { banner, stat, red, green, yellow } from "./migrate/colors.ts";
28
+ import { createContext, logPhase } from "./migrate/types";
29
+ import { analyze } from "./migrate/phase-analyze";
30
+ import { scaffold } from "./migrate/phase-scaffold";
31
+ import { transform } from "./migrate/phase-transform";
32
+ import { cleanup } from "./migrate/phase-cleanup";
33
+ import { report } from "./migrate/phase-report";
34
+ import { verify } from "./migrate/phase-verify";
35
+ import { banner, stat, red, green, yellow } from "./migrate/colors";
36
36
 
37
37
  function parseArgs(args: string[]): {
38
38
  source: string;
@@ -24,7 +24,10 @@ const makeSection = (component: string, props: Record<string, unknown> = {}): Re
24
24
 
25
25
  describe("runSingleSectionLoader — page context injection", () => {
26
26
  it("injects __pageUrl and __pagePath into loader props", async () => {
27
- const loader = vi.fn(async (props: Record<string, unknown>) => props);
27
+ // Two-arg signature so loader.mock.calls[0] types as [props, req].
28
+ const loader = vi.fn(
29
+ async (props: Record<string, unknown>, _req: Request) => props,
30
+ );
28
31
  registerSectionLoader("site/sections/SearchBanner.tsx", loader);
29
32
 
30
33
  const section = makeSection("site/sections/SearchBanner.tsx", { foo: "bar" });
@@ -13,6 +13,18 @@
13
13
  * file, and this plugin intercepts the .ts import to return JSON.parse(...)
14
14
  * — V8's JSON parser is 2-10x faster than the JS parser for large data.
15
15
  *
16
+ * meta.gen handling:
17
+ * The admin schema bundle (`server/admin/meta.gen.json`) is server-only;
18
+ * the client receives pre-resolved blocks via the SSR payload. Stubbing
19
+ * it on the client cuts a typically-large module out of the browser bundle.
20
+ * Match is done by substring on the import id, so any path style works.
21
+ *
22
+ * manualChunks:
23
+ * `@decocms/start` and `@decocms/apps` are intentionally NOT split into
24
+ * their own chunks. They have circular re-exports that produce a load-order
25
+ * crash when chunked separately. Rollup's default bundling (group with
26
+ * importer or vendor catch-all) avoids that.
27
+ *
16
28
  * Usage:
17
29
  * ```ts
18
30
  * import { decoVitePlugin } from "@decocms/start/vite";
@@ -62,6 +74,11 @@ const STUB_SOURCE = {
62
74
 
63
75
  "\0stub:tanstack-head-scripts":
64
76
  "export const injectedHeadScripts = undefined;",
77
+
78
+ // The admin schema bundle is server-only — the client receives pre-resolved
79
+ // blocks via the SSR payload. Stubbing it on the client cuts a large module
80
+ // (typically 0.5-5 MB) out of the browser bundle.
81
+ "\0stub:meta-gen": "export default {};",
65
82
  };
66
83
 
67
84
  /** @returns {import("vite").PluginOption} */
@@ -71,10 +88,23 @@ export function decoVitePlugin() {
71
88
  name: "deco-server-only-stubs",
72
89
  enforce: "pre",
73
90
 
74
- resolveId(id, _importer, options) {
91
+ resolveId(id, importer, options) {
75
92
  // Server builds keep the real modules.
76
93
  if (options?.ssr) return undefined;
77
- return CLIENT_STUBS[id];
94
+ // Bare-specifier exact-match stubs (react-dom/server, node:stream, etc.).
95
+ if (CLIENT_STUBS[id]) return CLIENT_STUBS[id];
96
+ // meta.gen.{json,ts} — the admin schema bundle. Server-only; client
97
+ // receives pre-resolved blocks. Matches both file extensions so the
98
+ // plugin works whether `setup.ts` imports the .json directly (current)
99
+ // or a future variant routes through a generated .ts wrapper.
100
+ // Requires `importer` so we don't accidentally stub the entry module.
101
+ if (
102
+ importer &&
103
+ (id.endsWith("meta.gen.json") || id.endsWith("meta.gen.ts"))
104
+ ) {
105
+ return "\0stub:meta-gen";
106
+ }
107
+ return undefined;
78
108
  },
79
109
 
80
110
  load(id, options) {
@@ -163,9 +193,14 @@ export function decoVitePlugin() {
163
193
  /** @type {import("vite").UserConfig} */
164
194
  const cfg = {};
165
195
 
166
- // Allow tunnel domains through Vite's host check
196
+ // Allow tunnel domains through Vite's host check.
197
+ // .deco.studio is the new admin frontend; both real-world Deco sites
198
+ // (casaevideo-storefront, baggagio-tanstack) duplicated this list to
199
+ // include it — bundling it here removes that boilerplate.
167
200
  if (process.env.DECO_SITE_NAME) {
168
- cfg.server = { allowedHosts: [".deco.host", ".decocdn.com"] };
201
+ cfg.server = {
202
+ allowedHosts: [".deco.host", ".decocdn.com", ".deco.studio"],
203
+ };
169
204
  }
170
205
 
171
206
  // Only split chunks for production builds — dev uses unbundled ESM.
@@ -219,12 +254,14 @@ export function decoVitePlugin() {
219
254
  if (id.includes("@tanstack/react-query")) {
220
255
  return "vendor-query";
221
256
  }
222
- if (id.includes("@decocms/start")) {
223
- return "vendor-deco";
224
- }
225
- if (id.includes("@decocms/apps")) {
226
- return "vendor-commerce";
227
- }
257
+ // Intentionally NOT splitting @decocms/start or @decocms/apps:
258
+ // they have circular re-exports (e.g. apps imports from
259
+ // start/sdk/cachedLoader, start admin imports from apps).
260
+ // Splitting them into separate chunks produces a Rollup
261
+ // chunk-load order that crashes at runtime ("undefined is not
262
+ // a function") — both real-world sites worked around this by
263
+ // overriding manualChunks. Letting Rollup bundle them together
264
+ // (or with the importing chunk) is correct.
228
265
  },
229
266
  },
230
267
  },
package/vitest.config.ts CHANGED
@@ -1,9 +1,19 @@
1
1
  import { defineConfig } from "vitest/config";
2
2
 
3
+ // Two test suites, one runner:
4
+ // - `src/**` runs in jsdom (React rendering, hooks, browser globals).
5
+ // - `scripts/**` runs in node (filesystem, migration script logic).
6
+ // vitest applies env-per-file via the `environmentMatchGlobs` map.
3
7
  export default defineConfig({
4
8
  test: {
5
9
  environment: "jsdom",
6
- include: ["src/**/*.test.{ts,tsx}"],
10
+ environmentMatchGlobs: [
11
+ ["scripts/**", "node"],
12
+ ],
13
+ include: [
14
+ "src/**/*.test.{ts,tsx}",
15
+ "scripts/**/*.test.ts",
16
+ ],
7
17
  globals: true,
8
18
  },
9
19
  });