@cloudwerk/vite-plugin 0.8.0 → 0.8.2

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 +119 -1
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -557,6 +557,13 @@ app.use('*', async (c, next) => {
557
557
  return
558
558
  }
559
559
 
560
+ // Skip static asset serving during SSG \u2014 the ASSETS binding from getPlatformProxy
561
+ // is not a real Workers Static Assets binding and does not support fetch(Request)
562
+ if (c.env?.HONO_SSG_CONTEXT) {
563
+ await next()
564
+ return
565
+ }
566
+
560
567
  // Only serve static assets for GET/HEAD requests
561
568
  // Other methods (POST, PUT, etc.) should go directly to route handlers
562
569
  // to avoid consuming the request body
@@ -567,7 +574,15 @@ app.use('*', async (c, next) => {
567
574
  }
568
575
 
569
576
  // Try to serve the request as a static asset
570
- const response = await c.env.ASSETS.fetch(c.req.raw)
577
+ let response
578
+ try {
579
+ response = await c.env.ASSETS.fetch(c.req.raw)
580
+ } catch {
581
+ // ASSETS.fetch can fail during SSG or when the binding is a proxy
582
+ // that doesn't support fetch(Request) \u2014 fall through to routes
583
+ await next()
584
+ return
585
+ }
571
586
 
572
587
  // If asset found (not 404), return it with cache headers
573
588
  if (response.status !== 404) {
@@ -1767,8 +1782,111 @@ function stripServerExports(code) {
1767
1782
  const replacement = removal.replacement ?? "";
1768
1783
  result = result.slice(0, start) + replacement + result.slice(end);
1769
1784
  }
1785
+ result = removeUnusedImports(result);
1770
1786
  return { code: result, stripped };
1771
1787
  }
1788
+ function removeUnusedImports(code) {
1789
+ const ast = parseSync2(code, {
1790
+ syntax: "typescript",
1791
+ tsx: true,
1792
+ comments: true
1793
+ });
1794
+ const offset = ast.span.start;
1795
+ const imports = [];
1796
+ for (const node of ast.body) {
1797
+ if (node.type !== "ImportDeclaration") continue;
1798
+ if (node.specifiers.length === 0) continue;
1799
+ const specifiers = [];
1800
+ for (const spec of node.specifiers) {
1801
+ if (spec.type === "ImportSpecifier") {
1802
+ specifiers.push({ localName: spec.local.value });
1803
+ } else if (spec.type === "ImportDefaultSpecifier") {
1804
+ specifiers.push({ localName: spec.local.value });
1805
+ } else if (spec.type === "ImportNamespaceSpecifier") {
1806
+ specifiers.push({ localName: spec.local.value });
1807
+ }
1808
+ }
1809
+ if (specifiers.length > 0) {
1810
+ imports.push({
1811
+ node,
1812
+ start: node.span.start,
1813
+ end: node.span.end,
1814
+ specifiers
1815
+ });
1816
+ }
1817
+ }
1818
+ if (imports.length === 0) return code;
1819
+ const importRanges = imports.map((i) => ({ start: i.start - offset, end: i.end - offset }));
1820
+ let remaining = "";
1821
+ let pos = 0;
1822
+ for (const range of importRanges.sort((a, b) => a.start - b.start)) {
1823
+ remaining += code.slice(pos, range.start);
1824
+ pos = range.end;
1825
+ }
1826
+ remaining += code.slice(pos);
1827
+ const removals = [];
1828
+ for (const imp of imports) {
1829
+ const unusedSpecs = [];
1830
+ const usedSpecs = [];
1831
+ for (const spec of imp.specifiers) {
1832
+ const regex = new RegExp(`\\b${escapeRegExp(spec.localName)}\\b`);
1833
+ if (regex.test(remaining)) {
1834
+ usedSpecs.push(spec);
1835
+ } else {
1836
+ unusedSpecs.push(spec.localName);
1837
+ }
1838
+ }
1839
+ if (unusedSpecs.length === 0) continue;
1840
+ if (usedSpecs.length === 0) {
1841
+ removals.push({ start: imp.start, end: imp.end });
1842
+ } else {
1843
+ const importNode = imp.node;
1844
+ const source = code.slice(
1845
+ importNode.source.span.start - offset,
1846
+ importNode.source.span.end - offset
1847
+ );
1848
+ const typeOnly = importNode.typeOnly ? "type " : "";
1849
+ const keptNamed = [];
1850
+ let keptDefault = null;
1851
+ let keptNamespace = null;
1852
+ for (const spec of importNode.specifiers) {
1853
+ const localName = spec.local.value;
1854
+ if (!usedSpecs.some((u) => u.localName === localName)) continue;
1855
+ if (spec.type === "ImportDefaultSpecifier") {
1856
+ keptDefault = localName;
1857
+ } else if (spec.type === "ImportNamespaceSpecifier") {
1858
+ keptNamespace = localName;
1859
+ } else if (spec.type === "ImportSpecifier") {
1860
+ const imported = spec.imported;
1861
+ if (imported && imported.type === "Identifier" && imported.value !== localName) {
1862
+ keptNamed.push(`${imported.value} as ${localName}`);
1863
+ } else {
1864
+ keptNamed.push(localName);
1865
+ }
1866
+ }
1867
+ }
1868
+ const parts = [];
1869
+ if (keptDefault) parts.push(keptDefault);
1870
+ if (keptNamespace) parts.push(`* as ${keptNamespace}`);
1871
+ if (keptNamed.length > 0) parts.push(`{ ${keptNamed.join(", ")} }`);
1872
+ const replacement = `import ${typeOnly}${parts.join(", ")} from ${source}`;
1873
+ removals.push({ start: imp.start, end: imp.end, replacement });
1874
+ }
1875
+ }
1876
+ if (removals.length === 0) return code;
1877
+ let result = code;
1878
+ removals.sort((a, b) => b.start - a.start);
1879
+ for (const removal of removals) {
1880
+ const start = removal.start - offset;
1881
+ const end = removal.end - offset;
1882
+ const replacement = removal.replacement ?? "";
1883
+ result = result.slice(0, start) + replacement + result.slice(end);
1884
+ }
1885
+ return result;
1886
+ }
1887
+ function escapeRegExp(s) {
1888
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1889
+ }
1772
1890
 
1773
1891
  // src/wrangler-watcher.ts
1774
1892
  import * as fs from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudwerk/vite-plugin",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Vite plugin for Cloudwerk file-based routing with virtual entry generation",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  "@cloudwerk/ui": "^0.15.6"
24
24
  },
25
25
  "peerDependencies": {
26
- "vite": "^5.0.0 || ^6.0.0",
26
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
27
27
  "@hono/vite-dev-server": ">=0.18.0",
28
28
  "hono": "^4.0.0"
29
29
  },