@cloudwerk/vite-plugin 0.6.8 → 0.7.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 (2) hide show
  1. package/dist/index.js +91 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -481,7 +481,7 @@ async function renderWithHydration(element, status = 200, routeId, pageProps, la
481
481
  let scripts = VITE_CLIENT
482
482
  ${rendererName === "react" ? `// React: embed serialized page data for full-tree hydration
483
483
  if (routeId) {
484
- const pageData = JSON.stringify({ routeId, pageProps: pageProps || {}, layoutData: layoutData || [] })
484
+ const pageData = JSON.stringify({ routeId, pageProps: pageProps || {}, layoutData: layoutData || [] }).replace(/</g, '\\\\u003c')
485
485
  scripts += '<script id="__CLOUDWERK_DATA__" type="application/json">' + pageData + '</script>'
486
486
  }` : ""}
487
487
  scripts += '<script type="module" src="${clientEntryPath}"></script>'
@@ -1319,7 +1319,7 @@ ${cssImportStatements}console.debug('[Cloudwerk] No route manifest available for
1319
1319
  layoutVars.push(importedLayouts.get(layoutPath));
1320
1320
  }
1321
1321
  routeMapEntries.push(
1322
- ` '${route.urlPattern}': { page: ${pageVar}.default, layouts: [${layoutVars.map((v) => `${v}.default`).join(", ")}] }`
1322
+ ` ${JSON.stringify(route.urlPattern)}: { page: ${pageVar}.default, layouts: [${layoutVars.map((v) => `${v}.default`).join(", ")}] }`
1323
1323
  );
1324
1324
  }
1325
1325
  return `/**
@@ -1594,6 +1594,87 @@ export default __WrappedComponent
1594
1594
  }
1595
1595
  }
1596
1596
 
1597
+ // src/strip-server-exports.ts
1598
+ import { parseSync as parseSync2 } from "@swc/core";
1599
+ var SERVER_ONLY_EXPORTS = /* @__PURE__ */ new Set(["loader", "config", "generateStaticParams"]);
1600
+ function stripServerExports(code) {
1601
+ const ast = parseSync2(code, {
1602
+ syntax: "typescript",
1603
+ tsx: true,
1604
+ comments: true
1605
+ });
1606
+ const stripped = [];
1607
+ const removals = [];
1608
+ for (const node of ast.body) {
1609
+ if (node.type === "ExportDeclaration") {
1610
+ const decl = node.declaration;
1611
+ if (decl.type === "FunctionDeclaration" && SERVER_ONLY_EXPORTS.has(decl.identifier.value)) {
1612
+ stripped.push(decl.identifier.value);
1613
+ removals.push({ start: node.span.start, end: node.span.end });
1614
+ continue;
1615
+ }
1616
+ if (decl.type === "VariableDeclaration") {
1617
+ const names = decl.declarations.map((d) => d.id.type === "Identifier" ? d.id.value : null).filter(Boolean);
1618
+ const allServerOnly = names.length > 0 && names.every((n) => SERVER_ONLY_EXPORTS.has(n));
1619
+ if (allServerOnly) {
1620
+ stripped.push(...names);
1621
+ removals.push({ start: node.span.start, end: node.span.end });
1622
+ }
1623
+ }
1624
+ }
1625
+ if (node.type === "ExportNamedDeclaration") {
1626
+ const specifiers = node.specifiers;
1627
+ if (specifiers.length === 0) continue;
1628
+ const serverSpecifiers = [];
1629
+ const keptSpecifiers = [];
1630
+ for (const spec of specifiers) {
1631
+ if (spec.type === "ExportSpecifier") {
1632
+ const exportedName = spec.exported?.type === "Identifier" ? spec.exported.value : null;
1633
+ const origName = spec.orig.type === "Identifier" ? spec.orig.value : null;
1634
+ const effectiveName = exportedName ?? origName;
1635
+ if (effectiveName && SERVER_ONLY_EXPORTS.has(effectiveName)) {
1636
+ serverSpecifiers.push(effectiveName);
1637
+ } else {
1638
+ if (origName) {
1639
+ if (exportedName && exportedName !== origName) {
1640
+ keptSpecifiers.push(`${origName} as ${exportedName}`);
1641
+ } else {
1642
+ keptSpecifiers.push(origName);
1643
+ }
1644
+ }
1645
+ }
1646
+ }
1647
+ }
1648
+ if (serverSpecifiers.length === 0) continue;
1649
+ stripped.push(...serverSpecifiers);
1650
+ if (keptSpecifiers.length === 0) {
1651
+ removals.push({ start: node.span.start, end: node.span.end });
1652
+ } else {
1653
+ const source = node.source ? ` from ${code.slice(node.source.span.start - ast.span.start, node.source.span.end - ast.span.start)}` : "";
1654
+ const replacement = `export { ${keptSpecifiers.join(", ")} }${source}`;
1655
+ removals.push({
1656
+ start: node.span.start,
1657
+ end: node.span.end,
1658
+ replacement
1659
+ });
1660
+ }
1661
+ }
1662
+ }
1663
+ if (removals.length === 0) {
1664
+ return { code, stripped: [] };
1665
+ }
1666
+ const offset = ast.span.start;
1667
+ let result = code;
1668
+ removals.sort((a, b) => b.start - a.start);
1669
+ for (const removal of removals) {
1670
+ const start = removal.start - offset;
1671
+ const end = removal.end - offset;
1672
+ const replacement = removal.replacement ?? "";
1673
+ result = result.slice(0, start) + replacement + result.slice(end);
1674
+ }
1675
+ return { code: result, stripped };
1676
+ }
1677
+
1597
1678
  // src/wrangler-watcher.ts
1598
1679
  import * as fs from "fs";
1599
1680
  import * as path2 from "path";
@@ -2529,7 +2610,7 @@ function cloudwerkPlugin(options = {}) {
2529
2610
  * Transform hook to detect and wrap client components,
2530
2611
  * and rewrite binding imports to use the bindings proxy.
2531
2612
  */
2532
- transform(code, id) {
2613
+ transform(code, id, options2) {
2533
2614
  if (!state) return null;
2534
2615
  if (id.includes("node_modules")) return null;
2535
2616
  if (!id.endsWith(".tsx") && !id.endsWith(".ts")) return null;
@@ -2613,6 +2694,13 @@ function cloudwerkPlugin(options = {}) {
2613
2694
  }
2614
2695
  }
2615
2696
  }
2697
+ if ((isLayout || isPage) && !options2?.ssr) {
2698
+ const stripResult = stripServerExports(transformedCode);
2699
+ if (stripResult.stripped.length > 0) {
2700
+ transformedCode = stripResult.code;
2701
+ wasTransformed = true;
2702
+ }
2703
+ }
2616
2704
  if (hasUseClientDirective(transformedCode)) {
2617
2705
  const componentId = generateComponentId(id, state.options.root);
2618
2706
  const bundlePath = `${state.options.hydrationEndpoint}/${componentId}.js`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudwerk/vite-plugin",
3
- "version": "0.6.8",
3
+ "version": "0.7.0",
4
4
  "description": "Vite plugin for Cloudwerk file-based routing with virtual entry generation",
5
5
  "repository": {
6
6
  "type": "git",