@cloudwerk/cli 0.2.0 → 0.3.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 +587 -98
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  import { program } from "commander";
5
5
 
6
6
  // src/commands/dev.ts
7
- import * as path6 from "path";
8
- import * as fs5 from "fs";
7
+ import * as path9 from "path";
8
+ import * as fs8 from "fs";
9
9
  import * as os from "os";
10
10
  import { serve } from "@hono/node-server";
11
11
  import {
@@ -112,11 +112,11 @@ function printError(message, suggestion) {
112
112
  }
113
113
  console.log();
114
114
  }
115
- function logRequest(method, path7, status, duration) {
115
+ function logRequest(method, path10, status, duration) {
116
116
  const methodColor = getMethodColor(method);
117
117
  const statusColor = status >= 400 ? pc.red : status >= 300 ? pc.yellow : pc.green;
118
118
  console.log(
119
- pc.dim("[") + methodColor(method.padEnd(6)) + pc.dim("]") + " " + path7 + " " + statusColor(String(status)) + " " + pc.dim(`${duration}ms`)
119
+ pc.dim("[") + methodColor(method.padEnd(6)) + pc.dim("]") + " " + path10 + " " + statusColor(String(status)) + " " + pc.dim(`${duration}ms`)
120
120
  );
121
121
  }
122
122
 
@@ -237,26 +237,26 @@ var handleParsingNestedValues = (form, key, value) => {
237
237
  };
238
238
 
239
239
  // ../../node_modules/.pnpm/hono@4.11.5/node_modules/hono/dist/utils/url.js
240
- var splitPath = (path7) => {
241
- const paths = path7.split("/");
240
+ var splitPath = (path10) => {
241
+ const paths = path10.split("/");
242
242
  if (paths[0] === "") {
243
243
  paths.shift();
244
244
  }
245
245
  return paths;
246
246
  };
247
247
  var splitRoutingPath = (routePath) => {
248
- const { groups, path: path7 } = extractGroupsFromPath(routePath);
249
- const paths = splitPath(path7);
248
+ const { groups, path: path10 } = extractGroupsFromPath(routePath);
249
+ const paths = splitPath(path10);
250
250
  return replaceGroupMarks(paths, groups);
251
251
  };
252
- var extractGroupsFromPath = (path7) => {
252
+ var extractGroupsFromPath = (path10) => {
253
253
  const groups = [];
254
- path7 = path7.replace(/\{[^}]+\}/g, (match2, index) => {
254
+ path10 = path10.replace(/\{[^}]+\}/g, (match2, index) => {
255
255
  const mark = `@${index}`;
256
256
  groups.push([mark, match2]);
257
257
  return mark;
258
258
  });
259
- return { groups, path: path7 };
259
+ return { groups, path: path10 };
260
260
  };
261
261
  var replaceGroupMarks = (paths, groups) => {
262
262
  for (let i = groups.length - 1; i >= 0; i--) {
@@ -311,8 +311,8 @@ var getPath = (request) => {
311
311
  const charCode = url.charCodeAt(i);
312
312
  if (charCode === 37) {
313
313
  const queryIndex = url.indexOf("?", i);
314
- const path7 = url.slice(start, queryIndex === -1 ? void 0 : queryIndex);
315
- return tryDecodeURI(path7.includes("%25") ? path7.replace(/%25/g, "%2525") : path7);
314
+ const path10 = url.slice(start, queryIndex === -1 ? void 0 : queryIndex);
315
+ return tryDecodeURI(path10.includes("%25") ? path10.replace(/%25/g, "%2525") : path10);
316
316
  } else if (charCode === 63) {
317
317
  break;
318
318
  }
@@ -329,11 +329,11 @@ var mergePath = (base, sub, ...rest) => {
329
329
  }
330
330
  return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
331
331
  };
332
- var checkOptionalParameter = (path7) => {
333
- if (path7.charCodeAt(path7.length - 1) !== 63 || !path7.includes(":")) {
332
+ var checkOptionalParameter = (path10) => {
333
+ if (path10.charCodeAt(path10.length - 1) !== 63 || !path10.includes(":")) {
334
334
  return null;
335
335
  }
336
- const segments = path7.split("/");
336
+ const segments = path10.split("/");
337
337
  const results = [];
338
338
  let basePath = "";
339
339
  segments.forEach((segment) => {
@@ -474,9 +474,9 @@ var HonoRequest = class {
474
474
  */
475
475
  path;
476
476
  bodyCache = {};
477
- constructor(request, path7 = "/", matchResult = [[]]) {
477
+ constructor(request, path10 = "/", matchResult = [[]]) {
478
478
  this.raw = request;
479
- this.path = path7;
479
+ this.path = path10;
480
480
  this.#matchResult = matchResult;
481
481
  this.#validatedData = {};
482
482
  }
@@ -1212,8 +1212,8 @@ var Hono = class _Hono {
1212
1212
  return this;
1213
1213
  };
1214
1214
  });
1215
- this.on = (method, path7, ...handlers) => {
1216
- for (const p of [path7].flat()) {
1215
+ this.on = (method, path10, ...handlers) => {
1216
+ for (const p of [path10].flat()) {
1217
1217
  this.#path = p;
1218
1218
  for (const m of [method].flat()) {
1219
1219
  handlers.map((handler) => {
@@ -1270,8 +1270,8 @@ var Hono = class _Hono {
1270
1270
  * app.route("/api", app2) // GET /api/user
1271
1271
  * ```
1272
1272
  */
1273
- route(path7, app) {
1274
- const subApp = this.basePath(path7);
1273
+ route(path10, app) {
1274
+ const subApp = this.basePath(path10);
1275
1275
  app.routes.map((r) => {
1276
1276
  let handler;
1277
1277
  if (app.errorHandler === errorHandler) {
@@ -1297,9 +1297,9 @@ var Hono = class _Hono {
1297
1297
  * const api = new Hono().basePath('/api')
1298
1298
  * ```
1299
1299
  */
1300
- basePath(path7) {
1300
+ basePath(path10) {
1301
1301
  const subApp = this.#clone();
1302
- subApp._basePath = mergePath(this._basePath, path7);
1302
+ subApp._basePath = mergePath(this._basePath, path10);
1303
1303
  return subApp;
1304
1304
  }
1305
1305
  /**
@@ -1373,7 +1373,7 @@ var Hono = class _Hono {
1373
1373
  * })
1374
1374
  * ```
1375
1375
  */
1376
- mount(path7, applicationHandler, options) {
1376
+ mount(path10, applicationHandler, options) {
1377
1377
  let replaceRequest;
1378
1378
  let optionHandler;
1379
1379
  if (options) {
@@ -1400,7 +1400,7 @@ var Hono = class _Hono {
1400
1400
  return [c.env, executionContext];
1401
1401
  };
1402
1402
  replaceRequest ||= (() => {
1403
- const mergedPath = mergePath(this._basePath, path7);
1403
+ const mergedPath = mergePath(this._basePath, path10);
1404
1404
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
1405
1405
  return (request) => {
1406
1406
  const url = new URL(request.url);
@@ -1415,14 +1415,14 @@ var Hono = class _Hono {
1415
1415
  }
1416
1416
  await next();
1417
1417
  };
1418
- this.#addRoute(METHOD_NAME_ALL, mergePath(path7, "*"), handler);
1418
+ this.#addRoute(METHOD_NAME_ALL, mergePath(path10, "*"), handler);
1419
1419
  return this;
1420
1420
  }
1421
- #addRoute(method, path7, handler) {
1421
+ #addRoute(method, path10, handler) {
1422
1422
  method = method.toUpperCase();
1423
- path7 = mergePath(this._basePath, path7);
1424
- const r = { basePath: this._basePath, path: path7, method, handler };
1425
- this.router.add(method, path7, [handler, r]);
1423
+ path10 = mergePath(this._basePath, path10);
1424
+ const r = { basePath: this._basePath, path: path10, method, handler };
1425
+ this.router.add(method, path10, [handler, r]);
1426
1426
  this.routes.push(r);
1427
1427
  }
1428
1428
  #handleError(err, c) {
@@ -1435,10 +1435,10 @@ var Hono = class _Hono {
1435
1435
  if (method === "HEAD") {
1436
1436
  return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
1437
1437
  }
1438
- const path7 = this.getPath(request, { env });
1439
- const matchResult = this.router.match(method, path7);
1438
+ const path10 = this.getPath(request, { env });
1439
+ const matchResult = this.router.match(method, path10);
1440
1440
  const c = new Context(request, {
1441
- path: path7,
1441
+ path: path10,
1442
1442
  matchResult,
1443
1443
  env,
1444
1444
  executionCtx,
@@ -1538,7 +1538,7 @@ var Hono = class _Hono {
1538
1538
 
1539
1539
  // ../../node_modules/.pnpm/hono@4.11.5/node_modules/hono/dist/router/reg-exp-router/matcher.js
1540
1540
  var emptyParam = [];
1541
- function match(method, path7) {
1541
+ function match(method, path10) {
1542
1542
  const matchers = this.buildAllMatchers();
1543
1543
  const match2 = ((method2, path22) => {
1544
1544
  const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
@@ -1554,7 +1554,7 @@ function match(method, path7) {
1554
1554
  return [matcher[1][index], match3];
1555
1555
  });
1556
1556
  this.match = match2;
1557
- return match2(method, path7);
1557
+ return match2(method, path10);
1558
1558
  }
1559
1559
 
1560
1560
  // ../../node_modules/.pnpm/hono@4.11.5/node_modules/hono/dist/router/reg-exp-router/node.js
@@ -1669,12 +1669,12 @@ var Node = class _Node {
1669
1669
  var Trie = class {
1670
1670
  #context = { varIndex: 0 };
1671
1671
  #root = new Node();
1672
- insert(path7, index, pathErrorCheckOnly) {
1672
+ insert(path10, index, pathErrorCheckOnly) {
1673
1673
  const paramAssoc = [];
1674
1674
  const groups = [];
1675
1675
  for (let i = 0; ; ) {
1676
1676
  let replaced = false;
1677
- path7 = path7.replace(/\{[^}]+\}/g, (m) => {
1677
+ path10 = path10.replace(/\{[^}]+\}/g, (m) => {
1678
1678
  const mark = `@\\${i}`;
1679
1679
  groups[i] = [mark, m];
1680
1680
  i++;
@@ -1685,7 +1685,7 @@ var Trie = class {
1685
1685
  break;
1686
1686
  }
1687
1687
  }
1688
- const tokens = path7.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
1688
+ const tokens = path10.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
1689
1689
  for (let i = groups.length - 1; i >= 0; i--) {
1690
1690
  const [mark] = groups[i];
1691
1691
  for (let j = tokens.length - 1; j >= 0; j--) {
@@ -1724,9 +1724,9 @@ var Trie = class {
1724
1724
  // ../../node_modules/.pnpm/hono@4.11.5/node_modules/hono/dist/router/reg-exp-router/router.js
1725
1725
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
1726
1726
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
1727
- function buildWildcardRegExp(path7) {
1728
- return wildcardRegExpCache[path7] ??= new RegExp(
1729
- path7 === "*" ? "" : `^${path7.replace(
1727
+ function buildWildcardRegExp(path10) {
1728
+ return wildcardRegExpCache[path10] ??= new RegExp(
1729
+ path10 === "*" ? "" : `^${path10.replace(
1730
1730
  /\/\*$|([.\\+*[^\]$()])/g,
1731
1731
  (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
1732
1732
  )}$`
@@ -1748,17 +1748,17 @@ function buildMatcherFromPreprocessedRoutes(routes) {
1748
1748
  );
1749
1749
  const staticMap = /* @__PURE__ */ Object.create(null);
1750
1750
  for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
1751
- const [pathErrorCheckOnly, path7, handlers] = routesWithStaticPathFlag[i];
1751
+ const [pathErrorCheckOnly, path10, handlers] = routesWithStaticPathFlag[i];
1752
1752
  if (pathErrorCheckOnly) {
1753
- staticMap[path7] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
1753
+ staticMap[path10] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
1754
1754
  } else {
1755
1755
  j++;
1756
1756
  }
1757
1757
  let paramAssoc;
1758
1758
  try {
1759
- paramAssoc = trie.insert(path7, j, pathErrorCheckOnly);
1759
+ paramAssoc = trie.insert(path10, j, pathErrorCheckOnly);
1760
1760
  } catch (e) {
1761
- throw e === PATH_ERROR ? new UnsupportedPathError(path7) : e;
1761
+ throw e === PATH_ERROR ? new UnsupportedPathError(path10) : e;
1762
1762
  }
1763
1763
  if (pathErrorCheckOnly) {
1764
1764
  continue;
@@ -1792,12 +1792,12 @@ function buildMatcherFromPreprocessedRoutes(routes) {
1792
1792
  }
1793
1793
  return [regexp, handlerMap, staticMap];
1794
1794
  }
1795
- function findMiddleware(middleware, path7) {
1795
+ function findMiddleware(middleware, path10) {
1796
1796
  if (!middleware) {
1797
1797
  return void 0;
1798
1798
  }
1799
1799
  for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
1800
- if (buildWildcardRegExp(k).test(path7)) {
1800
+ if (buildWildcardRegExp(k).test(path10)) {
1801
1801
  return [...middleware[k]];
1802
1802
  }
1803
1803
  }
@@ -1811,7 +1811,7 @@ var RegExpRouter = class {
1811
1811
  this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
1812
1812
  this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
1813
1813
  }
1814
- add(method, path7, handler) {
1814
+ add(method, path10, handler) {
1815
1815
  const middleware = this.#middleware;
1816
1816
  const routes = this.#routes;
1817
1817
  if (!middleware || !routes) {
@@ -1826,18 +1826,18 @@ var RegExpRouter = class {
1826
1826
  });
1827
1827
  });
1828
1828
  }
1829
- if (path7 === "/*") {
1830
- path7 = "*";
1829
+ if (path10 === "/*") {
1830
+ path10 = "*";
1831
1831
  }
1832
- const paramCount = (path7.match(/\/:/g) || []).length;
1833
- if (/\*$/.test(path7)) {
1834
- const re = buildWildcardRegExp(path7);
1832
+ const paramCount = (path10.match(/\/:/g) || []).length;
1833
+ if (/\*$/.test(path10)) {
1834
+ const re = buildWildcardRegExp(path10);
1835
1835
  if (method === METHOD_NAME_ALL) {
1836
1836
  Object.keys(middleware).forEach((m) => {
1837
- middleware[m][path7] ||= findMiddleware(middleware[m], path7) || findMiddleware(middleware[METHOD_NAME_ALL], path7) || [];
1837
+ middleware[m][path10] ||= findMiddleware(middleware[m], path10) || findMiddleware(middleware[METHOD_NAME_ALL], path10) || [];
1838
1838
  });
1839
1839
  } else {
1840
- middleware[method][path7] ||= findMiddleware(middleware[method], path7) || findMiddleware(middleware[METHOD_NAME_ALL], path7) || [];
1840
+ middleware[method][path10] ||= findMiddleware(middleware[method], path10) || findMiddleware(middleware[METHOD_NAME_ALL], path10) || [];
1841
1841
  }
1842
1842
  Object.keys(middleware).forEach((m) => {
1843
1843
  if (method === METHOD_NAME_ALL || method === m) {
@@ -1855,7 +1855,7 @@ var RegExpRouter = class {
1855
1855
  });
1856
1856
  return;
1857
1857
  }
1858
- const paths = checkOptionalParameter(path7) || [path7];
1858
+ const paths = checkOptionalParameter(path10) || [path10];
1859
1859
  for (let i = 0, len = paths.length; i < len; i++) {
1860
1860
  const path22 = paths[i];
1861
1861
  Object.keys(routes).forEach((m) => {
@@ -1882,13 +1882,13 @@ var RegExpRouter = class {
1882
1882
  const routes = [];
1883
1883
  let hasOwnRoute = method === METHOD_NAME_ALL;
1884
1884
  [this.#middleware, this.#routes].forEach((r) => {
1885
- const ownRoute = r[method] ? Object.keys(r[method]).map((path7) => [path7, r[method][path7]]) : [];
1885
+ const ownRoute = r[method] ? Object.keys(r[method]).map((path10) => [path10, r[method][path10]]) : [];
1886
1886
  if (ownRoute.length !== 0) {
1887
1887
  hasOwnRoute ||= true;
1888
1888
  routes.push(...ownRoute);
1889
1889
  } else if (method !== METHOD_NAME_ALL) {
1890
1890
  routes.push(
1891
- ...Object.keys(r[METHOD_NAME_ALL]).map((path7) => [path7, r[METHOD_NAME_ALL][path7]])
1891
+ ...Object.keys(r[METHOD_NAME_ALL]).map((path10) => [path10, r[METHOD_NAME_ALL][path10]])
1892
1892
  );
1893
1893
  }
1894
1894
  });
@@ -1908,13 +1908,13 @@ var SmartRouter = class {
1908
1908
  constructor(init) {
1909
1909
  this.#routers = init.routers;
1910
1910
  }
1911
- add(method, path7, handler) {
1911
+ add(method, path10, handler) {
1912
1912
  if (!this.#routes) {
1913
1913
  throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
1914
1914
  }
1915
- this.#routes.push([method, path7, handler]);
1915
+ this.#routes.push([method, path10, handler]);
1916
1916
  }
1917
- match(method, path7) {
1917
+ match(method, path10) {
1918
1918
  if (!this.#routes) {
1919
1919
  throw new Error("Fatal error");
1920
1920
  }
@@ -1929,7 +1929,7 @@ var SmartRouter = class {
1929
1929
  for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
1930
1930
  router.add(...routes[i2]);
1931
1931
  }
1932
- res = router.match(method, path7);
1932
+ res = router.match(method, path10);
1933
1933
  } catch (e) {
1934
1934
  if (e instanceof UnsupportedPathError) {
1935
1935
  continue;
@@ -1973,10 +1973,10 @@ var Node2 = class _Node2 {
1973
1973
  }
1974
1974
  this.#patterns = [];
1975
1975
  }
1976
- insert(method, path7, handler) {
1976
+ insert(method, path10, handler) {
1977
1977
  this.#order = ++this.#order;
1978
1978
  let curNode = this;
1979
- const parts = splitRoutingPath(path7);
1979
+ const parts = splitRoutingPath(path10);
1980
1980
  const possibleKeys = [];
1981
1981
  for (let i = 0, len = parts.length; i < len; i++) {
1982
1982
  const p = parts[i];
@@ -2027,12 +2027,12 @@ var Node2 = class _Node2 {
2027
2027
  }
2028
2028
  return handlerSets;
2029
2029
  }
2030
- search(method, path7) {
2030
+ search(method, path10) {
2031
2031
  const handlerSets = [];
2032
2032
  this.#params = emptyParams;
2033
2033
  const curNode = this;
2034
2034
  let curNodes = [curNode];
2035
- const parts = splitPath(path7);
2035
+ const parts = splitPath(path10);
2036
2036
  const curNodesQueue = [];
2037
2037
  for (let i = 0, len = parts.length; i < len; i++) {
2038
2038
  const part = parts[i];
@@ -2120,18 +2120,18 @@ var TrieRouter = class {
2120
2120
  constructor() {
2121
2121
  this.#node = new Node2();
2122
2122
  }
2123
- add(method, path7, handler) {
2124
- const results = checkOptionalParameter(path7);
2123
+ add(method, path10, handler) {
2124
+ const results = checkOptionalParameter(path10);
2125
2125
  if (results) {
2126
2126
  for (let i = 0, len = results.length; i < len; i++) {
2127
2127
  this.#node.insert(method, results[i], handler);
2128
2128
  }
2129
2129
  return;
2130
2130
  }
2131
- this.#node.insert(method, path7, handler);
2131
+ this.#node.insert(method, path10, handler);
2132
2132
  }
2133
- match(method, path7) {
2134
- return this.#node.search(method, path7);
2133
+ match(method, path10) {
2134
+ return this.#node.search(method, path10);
2135
2135
  }
2136
2136
  };
2137
2137
 
@@ -2155,9 +2155,17 @@ import { contextMiddleware } from "@cloudwerk/core";
2155
2155
  import { setActiveRenderer, getAvailableRenderers } from "@cloudwerk/ui";
2156
2156
 
2157
2157
  // src/server/registerRoutes.ts
2158
- import * as path5 from "path";
2159
- import { createHandlerAdapter, setRouteConfig, NotFoundError, RedirectError } from "@cloudwerk/core";
2160
- import { render } from "@cloudwerk/ui";
2158
+ import * as path8 from "path";
2159
+ import {
2160
+ createHandlerAdapter,
2161
+ setRouteConfig,
2162
+ NotFoundError,
2163
+ RedirectError,
2164
+ resolveErrorBoundary,
2165
+ resolveNotFoundBoundary,
2166
+ resolveLoadingBoundary
2167
+ } from "@cloudwerk/core";
2168
+ import { render, renderStream } from "@cloudwerk/ui";
2161
2169
 
2162
2170
  // src/server/loadHandler.ts
2163
2171
  import * as fs from "fs";
@@ -2558,6 +2566,300 @@ function findSafeTempDir4(filePath) {
2558
2566
  return dir;
2559
2567
  }
2560
2568
 
2569
+ // src/server/loadErrorBoundary.ts
2570
+ import * as fs5 from "fs";
2571
+ import * as path5 from "path";
2572
+ import { builtinModules as builtinModules5 } from "module";
2573
+ import { build as build5 } from "esbuild";
2574
+ import { pathToFileURL as pathToFileURL5 } from "url";
2575
+ var errorBoundaryModuleCache = /* @__PURE__ */ new Map();
2576
+ async function loadErrorBoundaryModule(absolutePath, verbose = false) {
2577
+ try {
2578
+ const stat = fs5.statSync(absolutePath);
2579
+ const mtime = stat.mtimeMs;
2580
+ const cached = errorBoundaryModuleCache.get(absolutePath);
2581
+ if (cached && cached.mtime === mtime) {
2582
+ return cached.module;
2583
+ }
2584
+ const nodeVersion = process.versions.node.split(".")[0];
2585
+ const target = `node${nodeVersion}`;
2586
+ const result = await build5({
2587
+ entryPoints: [absolutePath],
2588
+ bundle: true,
2589
+ write: false,
2590
+ format: "esm",
2591
+ platform: "node",
2592
+ target,
2593
+ jsx: "automatic",
2594
+ jsxImportSource: "hono/jsx",
2595
+ external: [
2596
+ "@cloudwerk/core",
2597
+ "@cloudwerk/ui",
2598
+ "hono",
2599
+ "hono/jsx",
2600
+ "hono/jsx/dom",
2601
+ "hono/jsx/streaming",
2602
+ "hono/html",
2603
+ // Use builtinModules for comprehensive Node.js built-in coverage
2604
+ ...builtinModules5,
2605
+ ...builtinModules5.map((m) => `node:${m}`)
2606
+ ],
2607
+ logLevel: verbose ? "warning" : "silent",
2608
+ sourcemap: "inline"
2609
+ });
2610
+ if (!result.outputFiles || result.outputFiles.length === 0) {
2611
+ throw new Error("No output from esbuild");
2612
+ }
2613
+ const code = result.outputFiles[0].text;
2614
+ const cacheKey = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
2615
+ const tempDir = findSafeTempDir5(absolutePath);
2616
+ const tempFile = path5.join(tempDir, `.cloudwerk-error-${cacheKey}.mjs`);
2617
+ fs5.writeFileSync(tempFile, code);
2618
+ try {
2619
+ const rawModule = await import(pathToFileURL5(tempFile).href);
2620
+ if (!rawModule.default) {
2621
+ throw new Error("Error boundary must have a default export");
2622
+ }
2623
+ if (typeof rawModule.default !== "function") {
2624
+ throw new Error(
2625
+ `Error boundary default export must be a function (component), got ${typeof rawModule.default}`
2626
+ );
2627
+ }
2628
+ let validatedLoader = void 0;
2629
+ if ("loader" in rawModule && rawModule.loader !== void 0) {
2630
+ if (typeof rawModule.loader !== "function") {
2631
+ throw new Error(
2632
+ `Error boundary loader export must be a function, got ${typeof rawModule.loader}`
2633
+ );
2634
+ }
2635
+ validatedLoader = rawModule.loader;
2636
+ }
2637
+ const module = {
2638
+ default: rawModule.default,
2639
+ loader: validatedLoader
2640
+ };
2641
+ errorBoundaryModuleCache.set(absolutePath, { module, mtime });
2642
+ return module;
2643
+ } finally {
2644
+ try {
2645
+ fs5.unlinkSync(tempFile);
2646
+ } catch {
2647
+ }
2648
+ }
2649
+ } catch (error) {
2650
+ const message = error instanceof Error ? error.message : String(error);
2651
+ throw new Error(`Failed to compile error boundary at ${absolutePath}: ${message}`);
2652
+ }
2653
+ }
2654
+ function findSafeTempDir5(filePath) {
2655
+ let dir = path5.dirname(filePath);
2656
+ const hasSpecialChars = (p) => /\[|\]|\(|\)/.test(path5.basename(p));
2657
+ while (hasSpecialChars(dir)) {
2658
+ const parent = path5.dirname(dir);
2659
+ if (parent === dir) {
2660
+ break;
2661
+ }
2662
+ dir = parent;
2663
+ }
2664
+ return dir;
2665
+ }
2666
+
2667
+ // src/server/loadNotFound.ts
2668
+ import * as fs6 from "fs";
2669
+ import * as path6 from "path";
2670
+ import { builtinModules as builtinModules6 } from "module";
2671
+ import { build as build6 } from "esbuild";
2672
+ import { pathToFileURL as pathToFileURL6 } from "url";
2673
+ var notFoundModuleCache = /* @__PURE__ */ new Map();
2674
+ async function loadNotFoundModule(absolutePath, verbose = false) {
2675
+ try {
2676
+ const stat = fs6.statSync(absolutePath);
2677
+ const mtime = stat.mtimeMs;
2678
+ const cached = notFoundModuleCache.get(absolutePath);
2679
+ if (cached && cached.mtime === mtime) {
2680
+ return cached.module;
2681
+ }
2682
+ const nodeVersion = process.versions.node.split(".")[0];
2683
+ const target = `node${nodeVersion}`;
2684
+ const result = await build6({
2685
+ entryPoints: [absolutePath],
2686
+ bundle: true,
2687
+ write: false,
2688
+ format: "esm",
2689
+ platform: "node",
2690
+ target,
2691
+ jsx: "automatic",
2692
+ jsxImportSource: "hono/jsx",
2693
+ external: [
2694
+ "@cloudwerk/core",
2695
+ "@cloudwerk/ui",
2696
+ "hono",
2697
+ "hono/jsx",
2698
+ "hono/jsx/dom",
2699
+ "hono/jsx/streaming",
2700
+ "hono/html",
2701
+ // Use builtinModules for comprehensive Node.js built-in coverage
2702
+ ...builtinModules6,
2703
+ ...builtinModules6.map((m) => `node:${m}`)
2704
+ ],
2705
+ logLevel: verbose ? "warning" : "silent",
2706
+ sourcemap: "inline"
2707
+ });
2708
+ if (!result.outputFiles || result.outputFiles.length === 0) {
2709
+ throw new Error("No output from esbuild");
2710
+ }
2711
+ const code = result.outputFiles[0].text;
2712
+ const cacheKey = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
2713
+ const tempDir = findSafeTempDir6(absolutePath);
2714
+ const tempFile = path6.join(tempDir, `.cloudwerk-not-found-${cacheKey}.mjs`);
2715
+ fs6.writeFileSync(tempFile, code);
2716
+ try {
2717
+ const rawModule = await import(pathToFileURL6(tempFile).href);
2718
+ if (!rawModule.default) {
2719
+ throw new Error("Not-found boundary must have a default export");
2720
+ }
2721
+ if (typeof rawModule.default !== "function") {
2722
+ throw new Error(
2723
+ `Not-found boundary default export must be a function (component), got ${typeof rawModule.default}`
2724
+ );
2725
+ }
2726
+ let validatedLoader = void 0;
2727
+ if ("loader" in rawModule && rawModule.loader !== void 0) {
2728
+ if (typeof rawModule.loader !== "function") {
2729
+ throw new Error(
2730
+ `Not-found boundary loader export must be a function, got ${typeof rawModule.loader}`
2731
+ );
2732
+ }
2733
+ validatedLoader = rawModule.loader;
2734
+ }
2735
+ const module = {
2736
+ default: rawModule.default,
2737
+ loader: validatedLoader
2738
+ };
2739
+ notFoundModuleCache.set(absolutePath, { module, mtime });
2740
+ return module;
2741
+ } finally {
2742
+ try {
2743
+ fs6.unlinkSync(tempFile);
2744
+ } catch {
2745
+ }
2746
+ }
2747
+ } catch (error) {
2748
+ const message = error instanceof Error ? error.message : String(error);
2749
+ throw new Error(`Failed to compile not-found boundary at ${absolutePath}: ${message}`);
2750
+ }
2751
+ }
2752
+ function findSafeTempDir6(filePath) {
2753
+ let dir = path6.dirname(filePath);
2754
+ const hasSpecialChars = (p) => /\[|\]|\(|\)/.test(path6.basename(p));
2755
+ while (hasSpecialChars(dir)) {
2756
+ const parent = path6.dirname(dir);
2757
+ if (parent === dir) {
2758
+ break;
2759
+ }
2760
+ dir = parent;
2761
+ }
2762
+ return dir;
2763
+ }
2764
+
2765
+ // src/server/loadLoading.ts
2766
+ import * as fs7 from "fs";
2767
+ import * as path7 from "path";
2768
+ import { builtinModules as builtinModules7 } from "module";
2769
+ import { build as build7 } from "esbuild";
2770
+ import { pathToFileURL as pathToFileURL7 } from "url";
2771
+ var loadingModuleCache = /* @__PURE__ */ new Map();
2772
+ async function loadLoadingModule(absolutePath, verbose = false) {
2773
+ try {
2774
+ const stat = fs7.statSync(absolutePath);
2775
+ const mtime = stat.mtimeMs;
2776
+ const cached = loadingModuleCache.get(absolutePath);
2777
+ if (cached && cached.mtime === mtime) {
2778
+ return cached.module;
2779
+ }
2780
+ const nodeVersion = process.versions.node.split(".")[0];
2781
+ const target = `node${nodeVersion}`;
2782
+ const result = await build7({
2783
+ entryPoints: [absolutePath],
2784
+ bundle: true,
2785
+ write: false,
2786
+ format: "esm",
2787
+ platform: "node",
2788
+ target,
2789
+ jsx: "automatic",
2790
+ jsxImportSource: "hono/jsx",
2791
+ external: [
2792
+ "@cloudwerk/core",
2793
+ "@cloudwerk/ui",
2794
+ "hono",
2795
+ "hono/jsx",
2796
+ "hono/jsx/dom",
2797
+ "hono/jsx/streaming",
2798
+ "hono/html",
2799
+ // Use builtinModules for comprehensive Node.js built-in coverage
2800
+ ...builtinModules7,
2801
+ ...builtinModules7.map((m) => `node:${m}`)
2802
+ ],
2803
+ logLevel: verbose ? "warning" : "silent",
2804
+ sourcemap: "inline"
2805
+ });
2806
+ if (!result.outputFiles || result.outputFiles.length === 0) {
2807
+ throw new Error("No output from esbuild");
2808
+ }
2809
+ const code = result.outputFiles[0].text;
2810
+ const cacheKey = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
2811
+ const tempDir = findSafeTempDir7(absolutePath);
2812
+ const tempFile = path7.join(tempDir, `.cloudwerk-loading-${cacheKey}.mjs`);
2813
+ fs7.writeFileSync(tempFile, code);
2814
+ try {
2815
+ const rawModule = await import(pathToFileURL7(tempFile).href);
2816
+ if (!rawModule.default) {
2817
+ throw new Error("Loading boundary must have a default export");
2818
+ }
2819
+ if (typeof rawModule.default !== "function") {
2820
+ throw new Error(
2821
+ `Loading boundary default export must be a function (component), got ${typeof rawModule.default}`
2822
+ );
2823
+ }
2824
+ let validatedConfig = void 0;
2825
+ if ("config" in rawModule && rawModule.config !== void 0) {
2826
+ if (typeof rawModule.config !== "object" || rawModule.config === null) {
2827
+ throw new Error(
2828
+ `Loading boundary config export must be an object, got ${typeof rawModule.config}`
2829
+ );
2830
+ }
2831
+ validatedConfig = rawModule.config;
2832
+ }
2833
+ const module = {
2834
+ default: rawModule.default,
2835
+ config: validatedConfig
2836
+ };
2837
+ loadingModuleCache.set(absolutePath, { module, mtime });
2838
+ return module;
2839
+ } finally {
2840
+ try {
2841
+ fs7.unlinkSync(tempFile);
2842
+ } catch {
2843
+ }
2844
+ }
2845
+ } catch (error) {
2846
+ const message = error instanceof Error ? error.message : String(error);
2847
+ throw new Error(`Failed to compile loading boundary at ${absolutePath}: ${message}`);
2848
+ }
2849
+ }
2850
+ function findSafeTempDir7(filePath) {
2851
+ let dir = path7.dirname(filePath);
2852
+ const hasSpecialChars = (p) => /\[|\]|\(|\)/.test(path7.basename(p));
2853
+ while (hasSpecialChars(dir)) {
2854
+ const parent = path7.dirname(dir);
2855
+ if (parent === dir) {
2856
+ break;
2857
+ }
2858
+ dir = parent;
2859
+ }
2860
+ return dir;
2861
+ }
2862
+
2561
2863
  // src/server/parseSearchParams.ts
2562
2864
  function parseSearchParams(c) {
2563
2865
  const result = {};
@@ -2597,9 +2899,6 @@ async function executeLoader(loader, args, c) {
2597
2899
  const data = await Promise.resolve(loader(args));
2598
2900
  return { data: data ?? {} };
2599
2901
  } catch (error) {
2600
- if (error instanceof NotFoundError) {
2601
- return { response: await Promise.resolve(c.notFound()) };
2602
- }
2603
2902
  if (error instanceof RedirectError) {
2604
2903
  return { response: c.redirect(error.url, error.status) };
2605
2904
  }
@@ -2614,16 +2913,13 @@ async function executeAction(action, args, c) {
2614
2913
  }
2615
2914
  return { data: result ?? {} };
2616
2915
  } catch (error) {
2617
- if (error instanceof NotFoundError) {
2618
- return { response: await Promise.resolve(c.notFound()) };
2619
- }
2620
2916
  if (error instanceof RedirectError) {
2621
2917
  return { response: c.redirect(error.url, error.status) };
2622
2918
  }
2623
2919
  throw error;
2624
2920
  }
2625
2921
  }
2626
- async function registerRoutes(app, manifest, logger, verbose = false) {
2922
+ async function registerRoutes(app, manifest, scanResult, logger, verbose = false) {
2627
2923
  const registeredRoutes = [];
2628
2924
  for (const route of manifest.routes) {
2629
2925
  if (route.fileType === "page") {
@@ -2635,13 +2931,26 @@ async function registerRoutes(app, manifest, logger, verbose = false) {
2635
2931
  route.layouts.map((layoutPath) => loadLayoutModule(layoutPath, verbose))
2636
2932
  );
2637
2933
  const layouts = layoutModules.map((m) => m.default);
2934
+ const loadingPath = resolveLoadingBoundary(route.filePath, scanResult.loading);
2935
+ let loadingModule = null;
2936
+ if (loadingPath) {
2937
+ try {
2938
+ loadingModule = await loadLoadingModule(loadingPath, verbose);
2939
+ if (verbose) {
2940
+ logger.info(`Loaded loading boundary: ${loadingPath} -> ${route.urlPattern}`);
2941
+ }
2942
+ } catch (loadingError) {
2943
+ const loadingMessage = loadingError instanceof Error ? loadingError.message : String(loadingError);
2944
+ logger.error(`Failed to load loading boundary: ${loadingMessage}`);
2945
+ }
2946
+ }
2638
2947
  for (const middlewarePath of route.middleware) {
2639
2948
  const middlewareHandler = await loadMiddlewareModule(middlewarePath, verbose);
2640
2949
  if (middlewareHandler) {
2641
2950
  app.use(route.urlPattern, middlewareHandler);
2642
2951
  if (verbose) {
2643
2952
  logger.info(
2644
- `Applied middleware: ${path5.basename(middlewarePath)} -> ${route.urlPattern}`
2953
+ `Applied middleware: ${path8.basename(middlewarePath)} -> ${route.urlPattern}`
2645
2954
  );
2646
2955
  }
2647
2956
  }
@@ -2653,12 +2962,70 @@ async function registerRoutes(app, manifest, logger, verbose = false) {
2653
2962
  }
2654
2963
  }
2655
2964
  app.get(route.urlPattern, async (c) => {
2965
+ const params = c.req.param();
2966
+ const searchParams = parseSearchParams(c);
2967
+ const request = c.req.raw;
2968
+ const pathname = new URL(request.url).pathname;
2969
+ const layoutLoaderData = [];
2970
+ const streamingDisabled = pageModule.config?.streaming === false;
2971
+ const useStreaming = loadingModule && !streamingDisabled;
2972
+ if (useStreaming) {
2973
+ try {
2974
+ const LoadingComponent = loadingModule.default;
2975
+ const loadingProps = { params, searchParams, pathname };
2976
+ let loadingElement = await Promise.resolve(LoadingComponent(loadingProps));
2977
+ for (let i = layouts.length - 1; i >= 0; i--) {
2978
+ const Layout = layouts[i];
2979
+ const layoutProps = {
2980
+ children: loadingElement,
2981
+ params
2982
+ // Pass empty objects for layout loader data since loaders haven't run
2983
+ };
2984
+ loadingElement = await Promise.resolve(Layout(layoutProps));
2985
+ }
2986
+ const contentPromise = (async () => {
2987
+ const loaderArgs = { params, request, context: c };
2988
+ for (let index = 0; index < layoutModules.length; index++) {
2989
+ const layoutModule = layoutModules[index];
2990
+ if (layoutModule.loader) {
2991
+ const result = await executeLoader(layoutModule.loader, loaderArgs, c);
2992
+ if (result.response) {
2993
+ throw new Error("Redirect during streaming not supported");
2994
+ }
2995
+ layoutLoaderData[index] = result.data;
2996
+ } else {
2997
+ layoutLoaderData[index] = {};
2998
+ }
2999
+ }
3000
+ let pageLoaderData = {};
3001
+ if (pageModule.loader) {
3002
+ const result = await executeLoader(pageModule.loader, loaderArgs, c);
3003
+ if (result.response) {
3004
+ throw new Error("Redirect during streaming not supported");
3005
+ }
3006
+ pageLoaderData = result.data;
3007
+ }
3008
+ const pageProps = { params, searchParams, ...pageLoaderData };
3009
+ let element = await Promise.resolve(PageComponent(pageProps));
3010
+ for (let i = layouts.length - 1; i >= 0; i--) {
3011
+ const Layout = layouts[i];
3012
+ const layoutProps = {
3013
+ children: element,
3014
+ params,
3015
+ ...layoutLoaderData[i]
3016
+ };
3017
+ element = await Promise.resolve(Layout(layoutProps));
3018
+ }
3019
+ return element;
3020
+ })();
3021
+ return renderStream(loadingElement, contentPromise);
3022
+ } catch (error) {
3023
+ const message = error instanceof Error ? error.message : String(error);
3024
+ logger.error(`Streaming error in ${route.filePath}: ${message}`);
3025
+ }
3026
+ }
2656
3027
  try {
2657
- const params = c.req.param();
2658
- const searchParams = parseSearchParams(c);
2659
- const request = c.req.raw;
2660
3028
  const loaderArgs = { params, request, context: c };
2661
- const layoutLoaderData = [];
2662
3029
  for (let index = 0; index < layoutModules.length; index++) {
2663
3030
  const layoutModule = layoutModules[index];
2664
3031
  if (layoutModule.loader) {
@@ -2692,6 +3059,67 @@ async function registerRoutes(app, manifest, logger, verbose = false) {
2692
3059
  }
2693
3060
  return render(element);
2694
3061
  } catch (error) {
3062
+ if (error instanceof NotFoundError) {
3063
+ const notFoundPath = resolveNotFoundBoundary(route.filePath, scanResult.notFound);
3064
+ if (notFoundPath) {
3065
+ try {
3066
+ const notFoundModule = await loadNotFoundModule(notFoundPath, verbose);
3067
+ const NotFoundComponent = notFoundModule.default;
3068
+ const notFoundProps = { params, searchParams };
3069
+ let notFoundElement = await Promise.resolve(NotFoundComponent(notFoundProps));
3070
+ for (let i = layouts.length - 1; i >= 0; i--) {
3071
+ const Layout = layouts[i];
3072
+ const layoutProps = {
3073
+ children: notFoundElement,
3074
+ params,
3075
+ ...layoutLoaderData[i]
3076
+ };
3077
+ notFoundElement = await Promise.resolve(Layout(layoutProps));
3078
+ }
3079
+ return render(notFoundElement, { status: 404 });
3080
+ } catch (boundaryError) {
3081
+ const boundaryMessage = boundaryError instanceof Error ? boundaryError.message : String(boundaryError);
3082
+ logger.error(`Not-found boundary failed: ${boundaryMessage}`);
3083
+ }
3084
+ }
3085
+ return c.notFound();
3086
+ }
3087
+ const errorPath = resolveErrorBoundary(route.filePath, scanResult.errors);
3088
+ if (errorPath) {
3089
+ try {
3090
+ const errorModule = await loadErrorBoundaryModule(errorPath, verbose);
3091
+ const ErrorComponent = errorModule.default;
3092
+ const digest = crypto.randomUUID().slice(0, 8);
3093
+ const originalMessage = error instanceof Error ? error.message : String(error);
3094
+ logger.error(`Error [${digest}] in ${route.filePath}: ${originalMessage}`);
3095
+ const sanitizedError = process.env.NODE_ENV === "production" ? Object.assign(new Error("An error occurred"), { digest }) : Object.assign(
3096
+ error instanceof Error ? error : new Error(String(error)),
3097
+ { digest }
3098
+ );
3099
+ const errorProps = {
3100
+ error: sanitizedError,
3101
+ errorType: "loader",
3102
+ reset: () => {
3103
+ },
3104
+ params,
3105
+ searchParams
3106
+ };
3107
+ let errorElement = await Promise.resolve(ErrorComponent(errorProps));
3108
+ for (let i = layouts.length - 1; i >= 0; i--) {
3109
+ const Layout = layouts[i];
3110
+ const layoutProps = {
3111
+ children: errorElement,
3112
+ params,
3113
+ ...layoutLoaderData[i]
3114
+ };
3115
+ errorElement = await Promise.resolve(Layout(layoutProps));
3116
+ }
3117
+ return render(errorElement, { status: 500 });
3118
+ } catch (boundaryError) {
3119
+ const boundaryMessage = boundaryError instanceof Error ? boundaryError.message : String(boundaryError);
3120
+ logger.error(`Error boundary failed: ${boundaryMessage}`);
3121
+ }
3122
+ }
2695
3123
  const message = error instanceof Error ? error.message : String(error);
2696
3124
  logger.error(`Error rendering page ${route.filePath}: ${message}`);
2697
3125
  return c.html(
@@ -2712,17 +3140,17 @@ async function registerRoutes(app, manifest, logger, verbose = false) {
2712
3140
  if (action && typeof action === "function") {
2713
3141
  const actionFn = action;
2714
3142
  registerMethod(app, method, route.urlPattern, async (c) => {
3143
+ const params = c.req.param();
3144
+ const searchParams = parseSearchParams(c);
3145
+ const request = c.req.raw;
3146
+ const layoutLoaderData = [];
2715
3147
  try {
2716
- const params = c.req.param();
2717
- const searchParams = parseSearchParams(c);
2718
- const request = c.req.raw;
2719
3148
  const actionArgs = { params, request, context: c };
2720
3149
  const actionResult = await executeAction(actionFn, actionArgs, c);
2721
3150
  if (actionResult.response) {
2722
3151
  return actionResult.response;
2723
3152
  }
2724
3153
  const loaderArgs = { params, request, context: c };
2725
- const layoutLoaderData = [];
2726
3154
  for (let index = 0; index < layoutModules.length; index++) {
2727
3155
  const layoutModule = layoutModules[index];
2728
3156
  if (layoutModule.loader) {
@@ -2761,6 +3189,67 @@ async function registerRoutes(app, manifest, logger, verbose = false) {
2761
3189
  }
2762
3190
  return render(element);
2763
3191
  } catch (error) {
3192
+ if (error instanceof NotFoundError) {
3193
+ const notFoundPath = resolveNotFoundBoundary(route.filePath, scanResult.notFound);
3194
+ if (notFoundPath) {
3195
+ try {
3196
+ const notFoundModule = await loadNotFoundModule(notFoundPath, verbose);
3197
+ const NotFoundComponent = notFoundModule.default;
3198
+ const notFoundProps = { params, searchParams };
3199
+ let notFoundElement = await Promise.resolve(NotFoundComponent(notFoundProps));
3200
+ for (let i = layouts.length - 1; i >= 0; i--) {
3201
+ const Layout = layouts[i];
3202
+ const layoutProps = {
3203
+ children: notFoundElement,
3204
+ params,
3205
+ ...layoutLoaderData[i]
3206
+ };
3207
+ notFoundElement = await Promise.resolve(Layout(layoutProps));
3208
+ }
3209
+ return render(notFoundElement, { status: 404 });
3210
+ } catch (boundaryError) {
3211
+ const boundaryMessage = boundaryError instanceof Error ? boundaryError.message : String(boundaryError);
3212
+ logger.error(`Not-found boundary failed: ${boundaryMessage}`);
3213
+ }
3214
+ }
3215
+ return c.notFound();
3216
+ }
3217
+ const errorPath = resolveErrorBoundary(route.filePath, scanResult.errors);
3218
+ if (errorPath) {
3219
+ try {
3220
+ const errorModule = await loadErrorBoundaryModule(errorPath, verbose);
3221
+ const ErrorComponent = errorModule.default;
3222
+ const digest = crypto.randomUUID().slice(0, 8);
3223
+ const originalMessage = error instanceof Error ? error.message : String(error);
3224
+ logger.error(`Error [${digest}] in ${route.filePath} action: ${originalMessage}`);
3225
+ const sanitizedError = process.env.NODE_ENV === "production" ? Object.assign(new Error("An error occurred"), { digest }) : Object.assign(
3226
+ error instanceof Error ? error : new Error(String(error)),
3227
+ { digest }
3228
+ );
3229
+ const errorProps = {
3230
+ error: sanitizedError,
3231
+ errorType: "action",
3232
+ reset: () => {
3233
+ },
3234
+ params,
3235
+ searchParams
3236
+ };
3237
+ let errorElement = await Promise.resolve(ErrorComponent(errorProps));
3238
+ for (let i = layouts.length - 1; i >= 0; i--) {
3239
+ const Layout = layouts[i];
3240
+ const layoutProps = {
3241
+ children: errorElement,
3242
+ params,
3243
+ ...layoutLoaderData[i]
3244
+ };
3245
+ errorElement = await Promise.resolve(Layout(layoutProps));
3246
+ }
3247
+ return render(errorElement, { status: 500 });
3248
+ } catch (boundaryError) {
3249
+ const boundaryMessage = boundaryError instanceof Error ? boundaryError.message : String(boundaryError);
3250
+ logger.error(`Error boundary failed: ${boundaryMessage}`);
3251
+ }
3252
+ }
2764
3253
  const message = error instanceof Error ? error.message : String(error);
2765
3254
  logger.error(`Error executing action ${route.filePath}: ${message}`);
2766
3255
  return c.html(
@@ -2793,7 +3282,7 @@ async function registerRoutes(app, manifest, logger, verbose = false) {
2793
3282
  if (middlewareHandler) {
2794
3283
  app.use(route.urlPattern, middlewareHandler);
2795
3284
  if (verbose) {
2796
- logger.info(`Applied middleware: ${path5.basename(middlewarePath)} -> ${route.urlPattern}`);
3285
+ logger.info(`Applied middleware: ${path8.basename(middlewarePath)} -> ${route.urlPattern}`);
2797
3286
  }
2798
3287
  }
2799
3288
  }
@@ -2861,7 +3350,7 @@ var HTTP_STATUS = {
2861
3350
  };
2862
3351
 
2863
3352
  // src/server/createApp.ts
2864
- async function createApp(manifest, config, logger, verbose = false) {
3353
+ async function createApp(manifest, scanResult, config, logger, verbose = false) {
2865
3354
  const rendererName = config.ui?.renderer ?? "hono-jsx";
2866
3355
  try {
2867
3356
  setActiveRenderer(rendererName);
@@ -2892,7 +3381,7 @@ async function createApp(manifest, config, logger, verbose = false) {
2892
3381
  app.use("*", middleware);
2893
3382
  }
2894
3383
  }
2895
- const routes = await registerRoutes(app, manifest, logger, verbose);
3384
+ const routes = await registerRoutes(app, manifest, scanResult, logger, verbose);
2896
3385
  app.notFound((c) => {
2897
3386
  return c.json(
2898
3387
  {
@@ -2929,8 +3418,8 @@ async function dev(pathArg, options) {
2929
3418
  const verbose = options.verbose ?? false;
2930
3419
  const logger = createLogger(verbose);
2931
3420
  try {
2932
- const cwd = pathArg ? path6.resolve(process.cwd(), pathArg) : process.cwd();
2933
- if (!fs5.existsSync(cwd)) {
3421
+ const cwd = pathArg ? path9.resolve(process.cwd(), pathArg) : process.cwd();
3422
+ if (!fs8.existsSync(cwd)) {
2934
3423
  throw new CliError(
2935
3424
  `Directory does not exist: ${cwd}`,
2936
3425
  "ENOENT",
@@ -2943,7 +3432,7 @@ async function dev(pathArg, options) {
2943
3432
  logger.debug(`Config loaded: routesDir=${config.routesDir}, extensions=${config.extensions.join(", ")}`);
2944
3433
  const routesDir = resolveRoutesDir(config, cwd);
2945
3434
  logger.debug(`Routes directory: ${routesDir}`);
2946
- if (!fs5.existsSync(routesDir)) {
3435
+ if (!fs8.existsSync(routesDir)) {
2947
3436
  throw new CliError(
2948
3437
  `Routes directory does not exist: ${routesDir}`,
2949
3438
  "ENOENT",
@@ -2978,7 +3467,7 @@ async function dev(pathArg, options) {
2978
3467
  logger.warn(`Create a route.ts file to get started.`);
2979
3468
  }
2980
3469
  logger.debug(`Creating Hono app...`);
2981
- const { app, routes } = await createApp(manifest, config, logger, verbose);
3470
+ const { app, routes } = await createApp(manifest, scanResult, config, logger, verbose);
2982
3471
  const port = parseInt(options.port, 10);
2983
3472
  if (isNaN(port) || port < 1 || port > 65535) {
2984
3473
  throw new CliError(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudwerk/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Dev server, build, deploy commands for Cloudwerk",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,8 +25,8 @@
25
25
  "commander": "^12.1.0",
26
26
  "esbuild": "^0.25.0",
27
27
  "picocolors": "^1.1.0",
28
- "@cloudwerk/core": "^0.2.0",
29
- "@cloudwerk/ui": "^0.1.1"
28
+ "@cloudwerk/core": "^0.3.0",
29
+ "@cloudwerk/ui": "^0.3.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^20.0.0",