@devlusoft/devix 0.1.0 → 0.2.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 (49) hide show
  1. package/README.md +6 -4
  2. package/dist/cli/build.js +145 -6
  3. package/dist/cli/build.js.map +4 -4
  4. package/dist/cli/dev.js +155 -4
  5. package/dist/cli/dev.js.map +4 -4
  6. package/dist/cli/generate.js +174 -12
  7. package/dist/cli/generate.js.map +4 -4
  8. package/dist/cli/index.js +200 -18
  9. package/dist/cli/index.js.map +4 -4
  10. package/dist/cli/start.js +12 -0
  11. package/dist/cli/start.js.map +3 -3
  12. package/dist/runtime/api-context.d.ts +3 -2
  13. package/dist/runtime/api-context.js.map +1 -1
  14. package/dist/runtime/fetch.d.ts +19 -0
  15. package/dist/runtime/fetch.js +35 -0
  16. package/dist/runtime/fetch.js.map +7 -0
  17. package/dist/runtime/index.d.ts +6 -1
  18. package/dist/runtime/index.js +68 -0
  19. package/dist/runtime/index.js.map +3 -3
  20. package/dist/server/api-router.d.ts +1 -0
  21. package/dist/server/api-router.js +1 -0
  22. package/dist/server/api-router.js.map +2 -2
  23. package/dist/server/api.js +1 -0
  24. package/dist/server/api.js.map +2 -2
  25. package/dist/server/index.js.map +2 -2
  26. package/dist/utils/cookies.d.ts +12 -0
  27. package/dist/utils/cookies.js +29 -0
  28. package/dist/utils/cookies.js.map +7 -0
  29. package/dist/utils/env.d.ts +1 -0
  30. package/dist/utils/env.js +14 -0
  31. package/dist/utils/env.js.map +7 -0
  32. package/dist/utils/response.d.ts +3 -0
  33. package/dist/utils/response.js +10 -0
  34. package/dist/utils/response.js.map +7 -0
  35. package/dist/vite/codegen/extract-methods.d.ts +4 -0
  36. package/dist/vite/codegen/extract-methods.js +16 -0
  37. package/dist/vite/codegen/extract-methods.js.map +7 -0
  38. package/dist/vite/codegen/routes-dts.d.ts +10 -0
  39. package/dist/vite/codegen/routes-dts.js +61 -0
  40. package/dist/vite/codegen/routes-dts.js.map +7 -0
  41. package/dist/vite/codegen/scan-api.d.ts +2 -0
  42. package/dist/vite/codegen/scan-api.js +78 -0
  43. package/dist/vite/codegen/scan-api.js.map +7 -0
  44. package/dist/vite/codegen/write-routes-dts.d.ts +1 -0
  45. package/dist/vite/codegen/write-routes-dts.js +17 -0
  46. package/dist/vite/codegen/write-routes-dts.js.map +7 -0
  47. package/dist/vite/index.js +143 -4
  48. package/dist/vite/index.js.map +4 -4
  49. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -167,6 +167,9 @@ var init_api = __esm({
167
167
  });
168
168
 
169
169
  // src/utils/patterns.ts
170
+ function routePattern(rel) {
171
+ return rel.replace(/\.(tsx|ts|jsx|js)$/, "").replace(/\(.*?\)\//g, "").replace(/^index$|\/index$/, "").replace(/\[([^\]]+)]/g, ":$1") || "/";
172
+ }
170
173
  var init_patterns = __esm({
171
174
  "src/utils/patterns.ts"() {
172
175
  "use strict";
@@ -187,6 +190,11 @@ var init_pages_router = __esm({
187
190
  });
188
191
 
189
192
  // src/server/api-router.ts
193
+ function keyToRoutePattern(key, apiDir) {
194
+ const rel = key.slice(apiDir.length + 1).replace(/\\/g, "/");
195
+ const pattern = routePattern(rel);
196
+ return pattern === "/" ? "/api" : `/api/${pattern}`.replace("/api//", "/api/");
197
+ }
190
198
  function invalidateApiCache() {
191
199
  cache2 = null;
192
200
  }
@@ -211,6 +219,136 @@ var init_context = __esm({
211
219
  }
212
220
  });
213
221
 
222
+ // src/vite/codegen/extract-methods.ts
223
+ function stripComments(content) {
224
+ return content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
225
+ }
226
+ function extractHttpMethods(content) {
227
+ const found = /* @__PURE__ */ new Set();
228
+ for (const match of stripComments(content).matchAll(METHOD_EXPORT_RE)) {
229
+ found.add(match[1]);
230
+ }
231
+ return [...found];
232
+ }
233
+ var METHOD_EXPORT_RE;
234
+ var init_extract_methods = __esm({
235
+ "src/vite/codegen/extract-methods.ts"() {
236
+ "use strict";
237
+ METHOD_EXPORT_RE = /export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g;
238
+ }
239
+ });
240
+
241
+ // src/vite/codegen/routes-dts.ts
242
+ function filePathToIdentifier(filePath, apiDir) {
243
+ return "_api_" + filePath.slice(`${apiDir}/`.length).replace(/\.(ts|tsx)$/, "").replace(/[^a-zA-Z0-9]/g, "_");
244
+ }
245
+ function buildRouteEntry(filePath, apiDir, methods) {
246
+ return {
247
+ filePath,
248
+ urlPattern: keyToRoutePattern(filePath, apiDir),
249
+ identifier: filePathToIdentifier(filePath, apiDir),
250
+ methods
251
+ };
252
+ }
253
+ function generateRoutesDts(entries, apiDir) {
254
+ if (entries.length === 0) {
255
+ return `// auto-generado por devix \u2014 no editar
256
+ declare module '@devlusoft/devix' {
257
+ interface ApiRoutes {}
258
+ }
259
+ `;
260
+ }
261
+ const imports = entries.map((e) => {
262
+ const importPath = "../" + e.filePath.replace(/\.(ts|tsx)$/, "");
263
+ return `import type * as ${e.identifier} from '${importPath}'`;
264
+ }).join("\n");
265
+ const routeLines = entries.flatMap(
266
+ (e) => e.methods.map(
267
+ (m) => ` '${m} ${e.urlPattern}': InferRoute<(typeof ${e.identifier})['${m}']>`
268
+ )
269
+ ).join("\n");
270
+ return `// auto-generado por devix \u2014 no editar
271
+ ${imports}
272
+
273
+ type InferRoute<T> = T extends (...args: any[]) => any
274
+ ? Exclude<Awaited<ReturnType<T>>, Response | null | void>
275
+ : never
276
+
277
+ declare module '@devlusoft/devix' {
278
+ interface ApiRoutes {
279
+ ${routeLines}
280
+ }
281
+ }
282
+ `;
283
+ }
284
+ var init_routes_dts = __esm({
285
+ "src/vite/codegen/routes-dts.ts"() {
286
+ "use strict";
287
+ init_api_router();
288
+ }
289
+ });
290
+
291
+ // src/vite/codegen/scan-api.ts
292
+ import { readFileSync, readdirSync, statSync } from "node:fs";
293
+ import { join, relative } from "node:path";
294
+ function walkDir(dir, root) {
295
+ const entries = [];
296
+ for (const name of readdirSync(dir)) {
297
+ const full = join(dir, name);
298
+ if (statSync(full).isDirectory()) {
299
+ entries.push(...walkDir(full, root));
300
+ } else if (/\.(ts|tsx)$/.test(name)) {
301
+ entries.push(relative(root, full).replace(/\\/g, "/"));
302
+ }
303
+ }
304
+ return entries;
305
+ }
306
+ function scanApiFiles(appDir, projectRoot) {
307
+ const apiDir = join(projectRoot, appDir, "api");
308
+ let files;
309
+ try {
310
+ files = walkDir(apiDir, projectRoot);
311
+ } catch {
312
+ return [];
313
+ }
314
+ return files.filter((f) => !f.endsWith("middleware.ts") && !f.endsWith("middleware.tsx")).flatMap((filePath) => {
315
+ try {
316
+ const content = readFileSync(join(projectRoot, filePath), "utf-8");
317
+ const methods = extractHttpMethods(content);
318
+ if (methods.length === 0) return [];
319
+ return [buildRouteEntry(filePath, `${appDir}/api`, methods)];
320
+ } catch {
321
+ return [];
322
+ }
323
+ });
324
+ }
325
+ var init_scan_api = __esm({
326
+ "src/vite/codegen/scan-api.ts"() {
327
+ "use strict";
328
+ init_extract_methods();
329
+ init_routes_dts();
330
+ }
331
+ });
332
+
333
+ // src/vite/codegen/write-routes-dts.ts
334
+ import { mkdirSync, readFileSync as readFileSync2, writeFileSync, existsSync } from "node:fs";
335
+ import { join as join2 } from "node:path";
336
+ function writeRoutesDts(content, projectRoot) {
337
+ const devixDir = join2(projectRoot, ".devix");
338
+ const outPath = join2(devixDir, "routes.d.ts");
339
+ mkdirSync(devixDir, { recursive: true });
340
+ if (existsSync(outPath) && readFileSync2(outPath, "utf-8") === content) {
341
+ return false;
342
+ }
343
+ writeFileSync(outPath, content, "utf-8");
344
+ return true;
345
+ }
346
+ var init_write_routes_dts = __esm({
347
+ "src/vite/codegen/write-routes-dts.ts"() {
348
+ "use strict";
349
+ }
350
+ });
351
+
214
352
  // src/vite/index.ts
215
353
  import { mergeConfig } from "vite";
216
354
  import react from "@vitejs/plugin-react";
@@ -245,14 +383,35 @@ function devix(config3) {
245
383
  if (id === `\0${VIRTUAL_CONTEXT}`)
246
384
  return generateContext();
247
385
  },
386
+ buildStart() {
387
+ const root = process.cwd();
388
+ const entries = scanApiFiles(appDir, root);
389
+ writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root);
390
+ },
248
391
  configureServer(server) {
392
+ const root = process.cwd();
393
+ const regenerateDts = () => {
394
+ const entries = scanApiFiles(appDir, root);
395
+ writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root);
396
+ };
249
397
  server.watcher.on("add", (file) => {
250
- if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache();
251
- if (file.includes(`${appDir}/api`)) invalidateApiCache();
398
+ if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache();
399
+ if (file.includes(`${appDir}/api`)) {
400
+ invalidateApiCache();
401
+ regenerateDts();
402
+ }
252
403
  });
253
404
  server.watcher.on("unlink", (file) => {
254
- if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache();
255
- if (file.includes(`${appDir}/api`)) invalidateApiCache();
405
+ if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache();
406
+ if (file.includes(`${appDir}/api`)) {
407
+ invalidateApiCache();
408
+ regenerateDts();
409
+ }
410
+ });
411
+ server.watcher.on("change", (file) => {
412
+ if (file.includes(`${appDir}/api`) && !file.endsWith("middleware.ts")) {
413
+ regenerateDts();
414
+ }
256
415
  });
257
416
  }
258
417
  };
@@ -274,6 +433,9 @@ var init_vite = __esm({
274
433
  init_pages_router();
275
434
  init_api_router();
276
435
  init_context();
436
+ init_scan_api();
437
+ init_routes_dts();
438
+ init_write_routes_dts();
277
439
  __dirname = dirname(fileURLToPath(import.meta.url));
278
440
  VIRTUAL_ENTRY_CLIENT = "virtual:devix/entry-client";
279
441
  VIRTUAL_CLIENT_ROUTES = "virtual:devix/client-routes";
@@ -403,6 +565,22 @@ var init_duration = __esm({
403
565
  }
404
566
  });
405
567
 
568
+ // src/utils/env.ts
569
+ import { loadEnv } from "vite";
570
+ function loadDotenv(mode) {
571
+ const env = loadEnv(mode, process.cwd(), "");
572
+ for (const [key, value] of Object.entries(env)) {
573
+ if (process.env[key] === void 0) {
574
+ process.env[key] = value;
575
+ }
576
+ }
577
+ }
578
+ var init_env = __esm({
579
+ "src/utils/env.ts"() {
580
+ "use strict";
581
+ }
582
+ });
583
+
406
584
  // src/cli/dev.ts
407
585
  var dev_exports = {};
408
586
  import { createServer } from "node:http";
@@ -418,6 +596,8 @@ var init_dev = __esm({
418
596
  init_banner();
419
597
  init_collect_css();
420
598
  init_duration();
599
+ init_env();
600
+ loadDotenv("development");
421
601
  VIRTUAL_RENDER2 = "virtual:devix/render";
422
602
  VIRTUAL_API2 = "virtual:devix/api";
423
603
  config = (await import(`${process.cwd()}/devix.config.ts`)).default;
@@ -469,7 +649,7 @@ var init_dev = __esm({
469
649
 
470
650
  // src/cli/build.ts
471
651
  var build_exports = {};
472
- import { writeFileSync } from "node:fs";
652
+ import { writeFileSync as writeFileSync2 } from "node:fs";
473
653
  import { resolve as resolve2 } from "node:path";
474
654
  import { build } from "vite";
475
655
  var config2, baseConfig, runtimeConfig;
@@ -511,7 +691,7 @@ var init_build = __esm({
511
691
  loaderTimeout: parseDuration(config2.loaderTimeout ?? 1e4),
512
692
  output: config2.output ?? "server"
513
693
  };
514
- writeFileSync(
694
+ writeFileSync2(
515
695
  resolve2(process.cwd(), "dist/devix.config.json"),
516
696
  JSON.stringify(runtimeConfig, null, 2),
517
697
  "utf-8"
@@ -521,8 +701,8 @@ var init_build = __esm({
521
701
 
522
702
  // src/cli/generate.ts
523
703
  var generate_exports = {};
524
- import { readFileSync, mkdirSync, writeFileSync as writeFileSync2 } from "node:fs";
525
- import { resolve as resolve3, join } from "node:path";
704
+ import { readFileSync as readFileSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
705
+ import { resolve as resolve3, join as join3 } from "node:path";
526
706
  var userConfig, t, renderModule2, manifest, urls;
527
707
  var init_generate = __esm({
528
708
  async "src/cli/generate.ts"() {
@@ -535,7 +715,7 @@ var init_generate = __esm({
535
715
  t = Date.now();
536
716
  renderModule2 = await import(resolve3(process.cwd(), "dist/server/render.js") + `?t=${t}`);
537
717
  manifest = JSON.parse(
538
- readFileSync(resolve3(process.cwd(), "dist/client/.vite/manifest.json"), "utf-8")
718
+ readFileSync3(resolve3(process.cwd(), "dist/client/.vite/manifest.json"), "utf-8")
539
719
  );
540
720
  urls = await renderModule2.getStaticRoutes();
541
721
  console.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? "" : "s"}...`);
@@ -546,9 +726,9 @@ var init_generate = __esm({
546
726
  console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`);
547
727
  continue;
548
728
  }
549
- const outPath = url === "/" ? join(process.cwd(), "dist/client/index.html") : join(process.cwd(), "dist/client", url, "index.html");
550
- mkdirSync(join(outPath, ".."), { recursive: true });
551
- writeFileSync2(outPath, `<!DOCTYPE html>${html}`, "utf-8");
729
+ const outPath = url === "/" ? join3(process.cwd(), "dist/client/index.html") : join3(process.cwd(), "dist/client", url, "index.html");
730
+ mkdirSync2(join3(outPath, ".."), { recursive: true });
731
+ writeFileSync3(outPath, `<!DOCTYPE html>${html}`, "utf-8");
552
732
  console.log(` \u2713 ${url}`);
553
733
  }
554
734
  console.log("[devix] Generation complete.");
@@ -557,7 +737,7 @@ var init_generate = __esm({
557
737
 
558
738
  // src/cli/start.ts
559
739
  var start_exports = {};
560
- import { readFileSync as readFileSync2 } from "node:fs";
740
+ import { readFileSync as readFileSync4 } from "node:fs";
561
741
  import { serve } from "@hono/node-server";
562
742
  import { serveStatic } from "@hono/node-server/serve-static";
563
743
  import { Hono as Hono2 } from "hono";
@@ -567,13 +747,15 @@ var init_start = __esm({
567
747
  async "src/cli/start.ts"() {
568
748
  "use strict";
569
749
  init_routes();
750
+ init_env();
751
+ loadDotenv("production");
570
752
  try {
571
- runtimeConfig2 = JSON.parse(readFileSync2(resolve4(process.cwd(), "dist/devix.config.json"), "utf-8"));
753
+ runtimeConfig2 = JSON.parse(readFileSync4(resolve4(process.cwd(), "dist/devix.config.json"), "utf-8"));
572
754
  if (runtimeConfig2.output !== "static") {
573
755
  renderModule3 = await import(resolve4(process.cwd(), "dist/server/render.js"));
574
756
  apiModule2 = await import(resolve4(process.cwd(), "dist/server/api.js"));
575
757
  }
576
- manifest2 = JSON.parse(readFileSync2(resolve4(process.cwd(), "dist/client/.vite/manifest.json"), "utf-8"));
758
+ manifest2 = JSON.parse(readFileSync4(resolve4(process.cwd(), "dist/client/.vite/manifest.json"), "utf-8"));
577
759
  } catch {
578
760
  console.error('[devix] Build not found. Run "devix build" first.');
579
761
  process.exit(1);
@@ -598,8 +780,8 @@ var init_start = __esm({
598
780
  });
599
781
 
600
782
  // src/cli/index.ts
601
- import { readFileSync as readFileSync3 } from "node:fs";
602
- import { join as join2, dirname as dirname2 } from "node:path";
783
+ import { readFileSync as readFileSync5 } from "node:fs";
784
+ import { join as join4, dirname as dirname2 } from "node:path";
603
785
  import { fileURLToPath as fileURLToPath2 } from "node:url";
604
786
  var command = process.argv[2];
605
787
  switch (command) {
@@ -617,7 +799,7 @@ switch (command) {
617
799
  break;
618
800
  case "--version":
619
801
  case "-v": {
620
- const pkg = JSON.parse(readFileSync3(join2(dirname2(fileURLToPath2(import.meta.url)), "../../package.json"), "utf-8"));
802
+ const pkg = JSON.parse(readFileSync5(join4(dirname2(fileURLToPath2(import.meta.url)), "../../package.json"), "utf-8"));
621
803
  console.log(pkg.version);
622
804
  break;
623
805
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/vite/codegen/entry-client.ts", "../../src/vite/codegen/client-routes.ts", "../../src/vite/codegen/render.ts", "../../src/vite/codegen/api.ts", "../../src/utils/patterns.ts", "../../src/server/pages-router.ts", "../../src/server/api-router.ts", "../../src/vite/codegen/context.ts", "../../src/vite/index.ts", "../../src/server/routes.ts", "../../src/utils/banner.ts", "../../src/server/collect-css.ts", "../../src/utils/duration.ts", "../../src/cli/dev.ts", "../../src/cli/build.ts", "../../src/cli/generate.ts", "../../src/cli/start.ts", "../../src/cli/index.ts"],
4
- "sourcesContent": ["interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({cssUrls}: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}", "interface ClientRoutesOptions {\n pagesDir: string\n matcherPath: string\n}\n\nexport function generateClientRoutes({pagesDir, matcherPath}: ClientRoutesOptions) {\n return `\nimport React from 'react'\nimport { createMatcher } from '${matcherPath}'\nconst pageFiles = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst layoutFiles = import.meta.glob('/${pagesDir}/**/layout.tsx')\nconst errorFiles = import.meta.glob('/${pagesDir}/**/error.tsx')\n\nexport const matchClientRoute = createMatcher(pageFiles, layoutFiles)\n\nexport async function loadErrorPage() {\n const key = Object.keys(errorFiles)[0]\n if (!key) return null\n const mod = await errorFiles[key]()\n return mod?.default ?? null\n}\n\nexport function getDefaultErrorPage() {\n return function DefaultError({ statusCode, message }) {\n return React.createElement('main', {\n style: { minHeight: '100dvh', display: 'flex', flexDirection: 'column', \n alignItems: 'center', justifyContent: 'center', gap: '8px',\n fontFamily: 'system-ui, sans-serif' }\n },\n React.createElement('h1', {style: {fontSize: '4rem', fontWeight: 700}}, statusCode),\n React.createElement('p', {style: {color: '#666'}}, message ?? 'An unexpected error occurred'),\n )\n }\n}\n`\n}", "interface RenderOptions {\n pagesDir: string\n renderPath: string\n}\n\nexport function generateRender({pagesDir, renderPath}: RenderOptions): string {\n return `\nimport { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${renderPath}'\n\nconst _pages = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst _layouts = import.meta.glob('/${pagesDir}/**/layout.tsx')\n\nconst _glob = {\n pages: _pages,\n layouts: _layouts,\n pagesDir: '/${pagesDir}',\n}\n\nexport function render(url, request, options) {\n return _render(url, request, _glob, options)\n}\n\nexport function runLoader(url, request, options) {\n return _runLoader(url, request, _glob, options)\n}\n\nexport function getStaticRoutes() {\n return _getStaticRoutes(_glob)\n}\n`\n}\n", "interface ApiOptions {\n apiPath: string\n appDir: string\n}\n\nexport function generateApi({apiPath, appDir}: ApiOptions): string {\n return `\nimport { handleApiRequest as _handleApiRequest } from '${apiPath}'\n\nconst _routes = import.meta.glob(['/${appDir}/api/**/*.ts', '!**/middleware.ts'])\nconst _middlewares = import.meta.glob('/${appDir}/api/**/middleware.ts')\n\nconst _glob = {\n routes: _routes,\n middlewares: _middlewares,\n apiDir: '/${appDir}/api',\n}\n\nexport function handleApiRequest(url, request) {\n return _handleApiRequest(url, request, _glob)\n}\n`\n}\n", "export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nfunction keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "import {UserConfig, Plugin, mergeConfig} from 'vite'\nimport type {DevixConfig} from '../config'\nimport react from '@vitejs/plugin-react'\nimport {fileURLToPath} from 'node:url'\nimport {dirname, resolve} from 'node:path'\nimport {generateEntryClient} from './codegen/entry-client'\nimport {generateClientRoutes} from './codegen/client-routes'\nimport {generateRender} from './codegen/render'\nimport {generateApi} from './codegen/api'\nimport {invalidatePagesCache} from \"../server/pages-router\";\nimport {invalidateApiCache} from \"../server/api-router\";\nimport {generateContext} from \"./codegen/context\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\nexport function devix(config: DevixConfig): UserConfig {\n const appDir = config.appDir ?? 'app'\n const pagesDir = `${appDir}/pages`\n const cssUrls = (config.css ?? []).map(u => u.startsWith('/') ? u : `/${u.replace(/^\\.\\//, '')}`)\n\n const renderPath = resolve(__dirname, '../server/render.js').replace(/\\\\/g, '/')\n const apiPath = resolve(__dirname, '../server/api.js').replace(/\\\\/g, '/')\n const matcherPath = resolve(__dirname, '../runtime/client-router.js').replace(/\\\\/g, '/')\n\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({cssUrls})\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({pagesDir, matcherPath})\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({pagesDir, renderPath})\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({apiPath, appDir})\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n configureServer(server) {\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) invalidateApiCache()\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(process.cwd(), pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) invalidateApiCache()\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n ssr: {noExternal: ['@devlusoft/devix']},\n ...(config.envPrefix ? {envPrefix: config.envPrefix} : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\n}", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import pc from 'picocolors'\nimport {networkInterfaces} from 'node:os'\nimport {createRequire} from 'node:module'\n\nfunction getNetworkUrl(port: number): string | null {\n const nets = networkInterfaces()\n for (const interfaces of Object.values(nets)) {\n for (const net of interfaces ?? []) {\n if (net.family === 'IPv4' && !net.internal) {\n return `http://${net.address}:${port}/`\n }\n }\n }\n return null\n}\n\nexport function printDevBanner(port: number) {\n const req = createRequire(import.meta.url)\n const version = req('../../package.json').version\n const networkUrl = getNetworkUrl(port)\n\n console.log()\n console.log(` ${pc.bold(pc.yellow('devix'))} ${pc.dim(`v${version}`)}`)\n console.log()\n console.log(` ${pc.green('\u279C')} ${pc.bold('Local:')} ${pc.cyan(`http://localhost:${port}/`)}`)\n if (networkUrl) {\n console.log(` ${pc.green('\u279C')} ${pc.bold('Network:')} ${pc.cyan(networkUrl)}`)\n } else {\n console.log(` ${pc.green('\u279C')} ${pc.bold('Network:')} ${pc.dim('use --host to expose')}`)\n }\n console.log()\n}", "import type {ViteDevServer} from 'vite'\n\nexport async function collectCss(vite: ViteDevServer): Promise<string[]> {\n const cssUrls = new Set<string>()\n\n for (const [, mod] of vite.moduleGraph.idToModuleMap) {\n if (!mod.id) continue\n if (mod.id.endsWith('.css') || mod.id.includes('.css?')) {\n cssUrls.add(mod.url)\n }\n }\n\n return [...cssUrls]\n}", "export function parseDuration(value: number | string): number {\n if (typeof value === 'number') return value\n const match = value.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h)?$/)\n if (!match) throw new Error(`[devix] Invalid duration: \"${value}\". Use a number (ms) or a string like \"5s\", \"2m\", \"500ms\".`)\n const n = parseFloat(match[1])\n switch (match[2]) {\n case 'h': return n * 3_600_000\n case 'm': return n * 60_000\n case 's': return n * 1_000\n case 'ms':\n default: return n\n }\n}\n", "import {createServer} from 'node:http'\nimport {createServer as createViteServer} from 'vite'\nimport {getRequestListener} from '@hono/node-server'\nimport {Hono} from 'hono'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {registerApiRoutes} from '../server/routes'\nimport {printDevBanner} from \"../utils/banner\";\nimport {collectCss} from \"../server/collect-css\";\nimport {parseDuration} from \"../utils/duration\";\n\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst port = Number(process.env.PORT) || config.port || 3000\nconst host = typeof config.host === 'string' ? config.host : config.host ? '0.0.0.0' : 'localhost'\n\nconst vite = await createViteServer({\n ...devix(config),\n configFile: false,\n appType: 'custom',\n server: {middlewareMode: true},\n})\n\nconst renderModule = {\n render: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_RENDER)).render(...args),\n runLoader: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_RENDER)).runLoader(...args),\n}\n\nconst apiModule = {\n handleApiRequest: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_API)).handleApiRequest(...args),\n}\n\nconst app = new Hono()\n\nregisterApiRoutes(app, {renderModule, apiModule})\n\napp.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000)})\n\n const cssUrls = await collectCss(vite)\n const cssLinks = cssUrls.map(url => `<link rel=\"stylesheet\" href=\"${url}\">`).join('\\n')\n\n const htmlWithCss = cssLinks ? html.replace('</head>', `${cssLinks}\\n</head>`) : html\n const transformed = await vite.transformIndexHtml(c.req.url, `<!DOCTYPE html>${htmlWithCss}`)\n\n const res = c.html(transformed, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n vite.ssrFixStacktrace(e as Error)\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n})\n\nconst honoHandler = getRequestListener(app.fetch)\n\ncreateServer(async (req, res) => {\n await new Promise<void>(resolve => vite.middlewares(req, res, resolve))\n if (!res.writableEnded) await honoHandler(req, res)\n}).listen(port, host, () => {\n printDevBanner(port)\n})\n\nexport {}", "import {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport type {DevixConfig} from '../config'\n\nconst userConfig: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(resolve(process.cwd(), 'dist/server/render.js') + `?t=${t}`)\n\nconst manifest: Manifest = JSON.parse(\n readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8')\n)\n\nconst urls: string[] = await renderModule.getStaticRoutes()\n\nconsole.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? '' : 's'}...`)\n\nfor (const url of urls) {\n const fullUrl = `http://localhost${url}`\n const {html, statusCode} = await renderModule.render(fullUrl, new Request(fullUrl), {manifest})\n\n if (statusCode !== 200) {\n console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`)\n continue\n }\n\n const outPath = url === '/'\n ? join(process.cwd(), 'dist/client/index.html')\n : join(process.cwd(), 'dist/client', url, 'index.html')\n\n mkdirSync(join(outPath, '..'), {recursive: true})\n writeFileSync(outPath, `<!DOCTYPE html>${html}`, 'utf-8')\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nexport {}\n", "import {readFileSync} from 'node:fs'\nimport {serve} from '@hono/node-server'\nimport {serveStatic} from '@hono/node-server/serve-static'\nimport {Hono} from 'hono'\nimport {resolve} from 'node:path'\nimport type {Manifest} from 'vite'\nimport {registerApiRoutes, registerSsrRoute} from '../server/routes'\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(resolve(process.cwd(), 'dist/server/render.js'))\n apiModule = await import(resolve(process.cwd(), 'dist/server/api.js'))\n }\n manifest = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\napp.use('/*', serveStatic({\n root: './dist/client',\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, {renderModule, apiModule, manifest})\n registerSsrRoute(app, {renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout})\n}\n\nserve({fetch: app.fetch, port, hostname: host}, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport {}", "#!/usr/bin/env node\nimport {readFileSync} from 'node:fs'\nimport {join, dirname} from 'node:path'\nimport {fileURLToPath} from 'node:url'\n\nconst command = process.argv[2]\n\nswitch (command) {\n case 'dev':\n await import(\"./dev.js\")\n break\n case \"build\":\n await import(\"./build.js\")\n break\n case \"generate\":\n await import(\"./generate.js\")\n break\n case \"start\":\n await import(\"./start.js\")\n break\n case '--version':\n case '-v': {\n const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../package.json'), 'utf-8'))\n console.log(pkg.version)\n break\n }\n case '--help':\n case '-h':\n console.log(`\ndevix \u2014 a lightweight SSR framework\n\nUsage:\n devix dev Start development server\n devix build Build for production\n devix generate Build and generate static HTML (SSG)\n devix start Start production server\n\nOptions:\n -v, --version Show version\n -h, --help Show this help\n\nOutput modes (set in devix.config.ts):\n output: \"server\" SSR mode \u2014 devix start handles requests dynamically (default)\n output: \"static\" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only\n `.trim())\n break\n default:\n console.error(`Unknown command: ${command}`)\n console.error('Usage: devix <dev|build|generate|start>')\n process.exit(1)\n}\n\nexport {}"],
5
- "mappings": "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",
6
- "names": ["cache", "config", "app", "apiModule", "renderModule", "manifest", "port", "vite", "VIRTUAL_RENDER", "VIRTUAL_API", "resolve", "resolve", "config", "writeFileSync", "resolve", "renderModule", "readFileSync", "Hono", "resolve", "renderModule", "apiModule", "manifest", "runtimeConfig", "port", "host", "app", "readFileSync", "join", "dirname", "fileURLToPath"]
3
+ "sources": ["../../src/vite/codegen/entry-client.ts", "../../src/vite/codegen/client-routes.ts", "../../src/vite/codegen/render.ts", "../../src/vite/codegen/api.ts", "../../src/utils/patterns.ts", "../../src/server/pages-router.ts", "../../src/server/api-router.ts", "../../src/vite/codegen/context.ts", "../../src/vite/codegen/extract-methods.ts", "../../src/vite/codegen/routes-dts.ts", "../../src/vite/codegen/scan-api.ts", "../../src/vite/codegen/write-routes-dts.ts", "../../src/vite/index.ts", "../../src/server/routes.ts", "../../src/utils/banner.ts", "../../src/server/collect-css.ts", "../../src/utils/duration.ts", "../../src/utils/env.ts", "../../src/cli/dev.ts", "../../src/cli/build.ts", "../../src/cli/generate.ts", "../../src/cli/start.ts", "../../src/cli/index.ts"],
4
+ "sourcesContent": ["interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({cssUrls}: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}", "interface ClientRoutesOptions {\n pagesDir: string\n matcherPath: string\n}\n\nexport function generateClientRoutes({pagesDir, matcherPath}: ClientRoutesOptions) {\n return `\nimport React from 'react'\nimport { createMatcher } from '${matcherPath}'\nconst pageFiles = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst layoutFiles = import.meta.glob('/${pagesDir}/**/layout.tsx')\nconst errorFiles = import.meta.glob('/${pagesDir}/**/error.tsx')\n\nexport const matchClientRoute = createMatcher(pageFiles, layoutFiles)\n\nexport async function loadErrorPage() {\n const key = Object.keys(errorFiles)[0]\n if (!key) return null\n const mod = await errorFiles[key]()\n return mod?.default ?? null\n}\n\nexport function getDefaultErrorPage() {\n return function DefaultError({ statusCode, message }) {\n return React.createElement('main', {\n style: { minHeight: '100dvh', display: 'flex', flexDirection: 'column', \n alignItems: 'center', justifyContent: 'center', gap: '8px',\n fontFamily: 'system-ui, sans-serif' }\n },\n React.createElement('h1', {style: {fontSize: '4rem', fontWeight: 700}}, statusCode),\n React.createElement('p', {style: {color: '#666'}}, message ?? 'An unexpected error occurred'),\n )\n }\n}\n`\n}", "interface RenderOptions {\n pagesDir: string\n renderPath: string\n}\n\nexport function generateRender({pagesDir, renderPath}: RenderOptions): string {\n return `\nimport { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${renderPath}'\n\nconst _pages = import.meta.glob(['/${pagesDir}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])\nconst _layouts = import.meta.glob('/${pagesDir}/**/layout.tsx')\n\nconst _glob = {\n pages: _pages,\n layouts: _layouts,\n pagesDir: '/${pagesDir}',\n}\n\nexport function render(url, request, options) {\n return _render(url, request, _glob, options)\n}\n\nexport function runLoader(url, request, options) {\n return _runLoader(url, request, _glob, options)\n}\n\nexport function getStaticRoutes() {\n return _getStaticRoutes(_glob)\n}\n`\n}\n", "interface ApiOptions {\n apiPath: string\n appDir: string\n}\n\nexport function generateApi({apiPath, appDir}: ApiOptions): string {\n return `\nimport { handleApiRequest as _handleApiRequest } from '${apiPath}'\n\nconst _routes = import.meta.glob(['/${appDir}/api/**/*.ts', '!**/middleware.ts'])\nconst _middlewares = import.meta.glob('/${appDir}/api/**/middleware.ts')\n\nconst _glob = {\n routes: _routes,\n middlewares: _middlewares,\n apiDir: '/${appDir}/api',\n}\n\nexport function handleApiRequest(url, request) {\n return _handleApiRequest(url, request, _glob)\n}\n`\n}\n", "export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nconst METHOD_EXPORT_RE = /export\\s+(?:const|async\\s+function|function)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/g\n\nfunction stripComments(content: string): string {\n return content\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n}\n\nexport function extractHttpMethods(content: string): HttpMethod[] {\n const found = new Set<HttpMethod>()\n for (const match of stripComments(content).matchAll(METHOD_EXPORT_RE)) {\n found.add(match[1] as HttpMethod)\n }\n return [...found]\n}\n", "import { keyToRoutePattern } from '../../server/api-router'\nimport type { HttpMethod } from './extract-methods'\n\nexport interface RouteEntry {\n filePath: string\n urlPattern: string\n identifier: string\n methods: HttpMethod[]\n}\n\nexport function filePathToIdentifier(filePath: string, apiDir: string): string {\n return '_api_' + filePath\n .slice(`${apiDir}/`.length)\n .replace(/\\.(ts|tsx)$/, '')\n .replace(/[^a-zA-Z0-9]/g, '_')\n}\n\nexport function buildRouteEntry(filePath: string, apiDir: string, methods: HttpMethod[]): RouteEntry {\n return {\n filePath,\n urlPattern: keyToRoutePattern(filePath, apiDir),\n identifier: filePathToIdentifier(filePath, apiDir),\n methods,\n }\n}\n\nexport function generateRoutesDts(entries: RouteEntry[], apiDir: string): string {\n if (entries.length === 0) {\n return `// auto-generado por devix \u2014 no editar\\ndeclare module '@devlusoft/devix' {\\n interface ApiRoutes {}\\n}\\n`\n }\n\n const imports = entries\n .map(e => {\n const importPath = '../' + e.filePath.replace(/\\.(ts|tsx)$/, '')\n return `import type * as ${e.identifier} from '${importPath}'`\n })\n .join('\\n')\n\n const routeLines = entries.flatMap(e =>\n e.methods.map(m =>\n ` '${m} ${e.urlPattern}': InferRoute<(typeof ${e.identifier})['${m}']>`\n )\n ).join('\\n')\n\n return `// auto-generado por devix \u2014 no editar\n${imports}\n\ntype InferRoute<T> = T extends (...args: any[]) => any\n ? Exclude<Awaited<ReturnType<T>>, Response | null | void>\n : never\n\ndeclare module '@devlusoft/devix' {\n interface ApiRoutes {\n${routeLines}\n }\n}\n`\n}\n", "import {readFileSync, readdirSync, statSync} from 'node:fs'\nimport {join, relative} from 'node:path'\nimport {extractHttpMethods} from './extract-methods'\nimport {buildRouteEntry} from './routes-dts'\nimport type {RouteEntry} from './routes-dts'\n\nfunction walkDir(dir: string, root: string): string[] {\n const entries: string[] = []\n for (const name of readdirSync(dir)) {\n const full = join(dir, name)\n if (statSync(full).isDirectory()) {\n entries.push(...walkDir(full, root))\n } else if (/\\.(ts|tsx)$/.test(name)) {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport function scanApiFiles(appDir: string, projectRoot: string): RouteEntry[] {\n const apiDir = join(projectRoot, appDir, 'api')\n\n let files: string[]\n try {\n files = walkDir(apiDir, projectRoot)\n } catch {\n return []\n }\n\n return files\n .filter(f => !f.endsWith('middleware.ts') && !f.endsWith('middleware.tsx'))\n .flatMap(filePath => {\n try {\n const content = readFileSync(join(projectRoot, filePath), 'utf-8')\n const methods = extractHttpMethods(content)\n if (methods.length === 0) return []\n return [buildRouteEntry(filePath, `${appDir}/api`, methods)]\n } catch {\n return []\n }\n })\n}\n", "import {mkdirSync, readFileSync, writeFileSync, existsSync} from 'node:fs'\nimport {join} from 'node:path'\n\nexport function writeRoutesDts(content: string, projectRoot: string): boolean {\n const devixDir = join(projectRoot, '.devix')\n const outPath = join(devixDir, 'routes.d.ts')\n\n mkdirSync(devixDir, {recursive: true})\n\n if (existsSync(outPath) && readFileSync(outPath, 'utf-8') === content) {\n return false\n }\n\n writeFileSync(outPath, content, 'utf-8')\n return true\n}\n", "import {UserConfig, Plugin, mergeConfig} from 'vite'\nimport type {DevixConfig} from '../config'\nimport react from '@vitejs/plugin-react'\nimport {fileURLToPath} from 'node:url'\nimport {dirname, resolve} from 'node:path'\nimport {generateEntryClient} from './codegen/entry-client'\nimport {generateClientRoutes} from './codegen/client-routes'\nimport {generateRender} from './codegen/render'\nimport {generateApi} from './codegen/api'\nimport {invalidatePagesCache} from \"../server/pages-router\";\nimport {invalidateApiCache} from \"../server/api-router\";\nimport {generateContext} from \"./codegen/context\";\nimport {scanApiFiles} from \"./codegen/scan-api\";\nimport {generateRoutesDts} from \"./codegen/routes-dts\";\nimport {writeRoutesDts} from \"./codegen/write-routes-dts\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\nexport function devix(config: DevixConfig): UserConfig {\n const appDir = config.appDir ?? 'app'\n const pagesDir = `${appDir}/pages`\n const cssUrls = (config.css ?? []).map(u => u.startsWith('/') ? u : `/${u.replace(/^\\.\\//, '')}`)\n\n const renderPath = resolve(__dirname, '../server/render.js').replace(/\\\\/g, '/')\n const apiPath = resolve(__dirname, '../server/api.js').replace(/\\\\/g, '/')\n const matcherPath = resolve(__dirname, '../runtime/client-router.js').replace(/\\\\/g, '/')\n\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({cssUrls})\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({pagesDir, matcherPath})\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({pagesDir, renderPath})\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({apiPath, appDir})\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n buildStart() {\n const root = process.cwd()\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n },\n\n configureServer(server) {\n const root = process.cwd()\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('change', (file) => {\n if (file.includes(`${appDir}/api`) && !file.endsWith('middleware.ts')) {\n regenerateDts()\n }\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n ssr: {noExternal: ['@devlusoft/devix']},\n ...(config.envPrefix ? {envPrefix: config.envPrefix} : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\n}", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import pc from 'picocolors'\nimport {networkInterfaces} from 'node:os'\nimport {createRequire} from 'node:module'\n\nfunction getNetworkUrl(port: number): string | null {\n const nets = networkInterfaces()\n for (const interfaces of Object.values(nets)) {\n for (const net of interfaces ?? []) {\n if (net.family === 'IPv4' && !net.internal) {\n return `http://${net.address}:${port}/`\n }\n }\n }\n return null\n}\n\nexport function printDevBanner(port: number) {\n const req = createRequire(import.meta.url)\n const version = req('../../package.json').version\n const networkUrl = getNetworkUrl(port)\n\n console.log()\n console.log(` ${pc.bold(pc.yellow('devix'))} ${pc.dim(`v${version}`)}`)\n console.log()\n console.log(` ${pc.green('\u279C')} ${pc.bold('Local:')} ${pc.cyan(`http://localhost:${port}/`)}`)\n if (networkUrl) {\n console.log(` ${pc.green('\u279C')} ${pc.bold('Network:')} ${pc.cyan(networkUrl)}`)\n } else {\n console.log(` ${pc.green('\u279C')} ${pc.bold('Network:')} ${pc.dim('use --host to expose')}`)\n }\n console.log()\n}", "import type {ViteDevServer} from 'vite'\n\nexport async function collectCss(vite: ViteDevServer): Promise<string[]> {\n const cssUrls = new Set<string>()\n\n for (const [, mod] of vite.moduleGraph.idToModuleMap) {\n if (!mod.id) continue\n if (mod.id.endsWith('.css') || mod.id.includes('.css?')) {\n cssUrls.add(mod.url)\n }\n }\n\n return [...cssUrls]\n}", "export function parseDuration(value: number | string): number {\n if (typeof value === 'number') return value\n const match = value.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h)?$/)\n if (!match) throw new Error(`[devix] Invalid duration: \"${value}\". Use a number (ms) or a string like \"5s\", \"2m\", \"500ms\".`)\n const n = parseFloat(match[1])\n switch (match[2]) {\n case 'h': return n * 3_600_000\n case 'm': return n * 60_000\n case 's': return n * 1_000\n case 'ms':\n default: return n\n }\n}\n", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n", "import {createServer} from 'node:http'\nimport {createServer as createViteServer} from 'vite'\nimport {getRequestListener} from '@hono/node-server'\nimport {Hono} from 'hono'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {registerApiRoutes} from '../server/routes'\nimport {printDevBanner} from \"../utils/banner\";\nimport {collectCss} from \"../server/collect-css\";\nimport {parseDuration} from \"../utils/duration\";\nimport {loadDotenv} from \"../utils/env\";\n\nloadDotenv('development')\n\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst port = Number(process.env.PORT) || config.port || 3000\nconst host = typeof config.host === 'string' ? config.host : config.host ? '0.0.0.0' : 'localhost'\n\nconst vite = await createViteServer({\n ...devix(config),\n configFile: false,\n appType: 'custom',\n server: {middlewareMode: true},\n})\n\nconst renderModule = {\n render: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_RENDER)).render(...args),\n runLoader: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_RENDER)).runLoader(...args),\n}\n\nconst apiModule = {\n handleApiRequest: async (...args: any[]) => (await vite.ssrLoadModule(VIRTUAL_API)).handleApiRequest(...args),\n}\n\nconst app = new Hono()\n\nregisterApiRoutes(app, {renderModule, apiModule})\n\napp.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000)})\n\n const cssUrls = await collectCss(vite)\n const cssLinks = cssUrls.map(url => `<link rel=\"stylesheet\" href=\"${url}\">`).join('\\n')\n\n const htmlWithCss = cssLinks ? html.replace('</head>', `${cssLinks}\\n</head>`) : html\n const transformed = await vite.transformIndexHtml(c.req.url, `<!DOCTYPE html>${htmlWithCss}`)\n\n const res = c.html(transformed, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n vite.ssrFixStacktrace(e as Error)\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n})\n\nconst honoHandler = getRequestListener(app.fetch)\n\ncreateServer(async (req, res) => {\n await new Promise<void>(resolve => vite.middlewares(req, res, resolve))\n if (!res.writableEnded) await honoHandler(req, res)\n}).listen(port, host, () => {\n printDevBanner(port)\n})\n\nexport {}", "import {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport type {DevixConfig} from '../config'\n\nconst userConfig: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(resolve(process.cwd(), 'dist/server/render.js') + `?t=${t}`)\n\nconst manifest: Manifest = JSON.parse(\n readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8')\n)\n\nconst urls: string[] = await renderModule.getStaticRoutes()\n\nconsole.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? '' : 's'}...`)\n\nfor (const url of urls) {\n const fullUrl = `http://localhost${url}`\n const {html, statusCode} = await renderModule.render(fullUrl, new Request(fullUrl), {manifest})\n\n if (statusCode !== 200) {\n console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`)\n continue\n }\n\n const outPath = url === '/'\n ? join(process.cwd(), 'dist/client/index.html')\n : join(process.cwd(), 'dist/client', url, 'index.html')\n\n mkdirSync(join(outPath, '..'), {recursive: true})\n writeFileSync(outPath, `<!DOCTYPE html>${html}`, 'utf-8')\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nexport {}\n", "import {readFileSync} from 'node:fs'\nimport {serve} from '@hono/node-server'\nimport {serveStatic} from '@hono/node-server/serve-static'\nimport {Hono} from 'hono'\nimport {resolve} from 'node:path'\nimport type {Manifest} from 'vite'\nimport {registerApiRoutes, registerSsrRoute} from '../server/routes'\nimport {loadDotenv} from '../utils/env'\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(resolve(process.cwd(), 'dist/server/render.js'))\n apiModule = await import(resolve(process.cwd(), 'dist/server/api.js'))\n }\n manifest = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\napp.use('/*', serveStatic({\n root: './dist/client',\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, {renderModule, apiModule, manifest})\n registerSsrRoute(app, {renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout})\n}\n\nserve({fetch: app.fetch, port, hostname: host}, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport {}", "#!/usr/bin/env node\nimport {readFileSync} from 'node:fs'\nimport {join, dirname} from 'node:path'\nimport {fileURLToPath} from 'node:url'\n\nconst command = process.argv[2]\n\nswitch (command) {\n case 'dev':\n await import(\"./dev.js\")\n break\n case \"build\":\n await import(\"./build.js\")\n break\n case \"generate\":\n await import(\"./generate.js\")\n break\n case \"start\":\n await import(\"./start.js\")\n break\n case '--version':\n case '-v': {\n const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../package.json'), 'utf-8'))\n console.log(pkg.version)\n break\n }\n case '--help':\n case '-h':\n console.log(`\ndevix \u2014 a lightweight SSR framework\n\nUsage:\n devix dev Start development server\n devix build Build for production\n devix generate Build and generate static HTML (SSG)\n devix start Start production server\n\nOptions:\n -v, --version Show version\n -h, --help Show this help\n\nOutput modes (set in devix.config.ts):\n output: \"server\" SSR mode \u2014 devix start handles requests dynamically (default)\n output: \"static\" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only\n `.trim())\n break\n default:\n console.error(`Unknown command: ${command}`)\n console.error('Usage: devix <dev|build|generate|start>')\n process.exit(1)\n}\n\nexport {}"],
5
+ "mappings": "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",
6
+ "names": ["cache", "readFileSync", "join", "config", "app", "apiModule", "renderModule", "manifest", "port", "vite", "VIRTUAL_RENDER", "VIRTUAL_API", "resolve", "writeFileSync", "resolve", "config", "readFileSync", "mkdirSync", "writeFileSync", "resolve", "join", "renderModule", "readFileSync", "Hono", "resolve", "renderModule", "apiModule", "manifest", "runtimeConfig", "port", "host", "app", "readFileSync", "join", "dirname", "fileURLToPath"]
7
7
  }
package/dist/cli/start.js CHANGED
@@ -43,7 +43,19 @@ function registerSsrRoute(app2, { renderModule: renderModule2, manifest: manifes
43
43
  });
44
44
  }
45
45
 
46
+ // src/utils/env.ts
47
+ import { loadEnv } from "vite";
48
+ function loadDotenv(mode) {
49
+ const env = loadEnv(mode, process.cwd(), "");
50
+ for (const [key, value] of Object.entries(env)) {
51
+ if (process.env[key] === void 0) {
52
+ process.env[key] = value;
53
+ }
54
+ }
55
+ }
56
+
46
57
  // src/cli/start.ts
58
+ loadDotenv("production");
47
59
  var renderModule;
48
60
  var apiModule;
49
61
  var manifest;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/cli/start.ts", "../../src/server/routes.ts"],
4
- "sourcesContent": ["import {readFileSync} from 'node:fs'\nimport {serve} from '@hono/node-server'\nimport {serveStatic} from '@hono/node-server/serve-static'\nimport {Hono} from 'hono'\nimport {resolve} from 'node:path'\nimport type {Manifest} from 'vite'\nimport {registerApiRoutes, registerSsrRoute} from '../server/routes'\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(resolve(process.cwd(), 'dist/server/render.js'))\n apiModule = await import(resolve(process.cwd(), 'dist/server/api.js'))\n }\n manifest = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\napp.use('/*', serveStatic({\n root: './dist/client',\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, {renderModule, apiModule, manifest})\n registerSsrRoute(app, {renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout})\n}\n\nserve({fetch: app.fetch, port, hostname: host}, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport {}", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}"],
5
- "mappings": "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",
3
+ "sources": ["../../src/cli/start.ts", "../../src/server/routes.ts", "../../src/utils/env.ts"],
4
+ "sourcesContent": ["import {readFileSync} from 'node:fs'\nimport {serve} from '@hono/node-server'\nimport {serveStatic} from '@hono/node-server/serve-static'\nimport {Hono} from 'hono'\nimport {resolve} from 'node:path'\nimport type {Manifest} from 'vite'\nimport {registerApiRoutes, registerSsrRoute} from '../server/routes'\nimport {loadDotenv} from '../utils/env'\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(resolve(process.cwd(), 'dist/server/render.js'))\n apiModule = await import(resolve(process.cwd(), 'dist/server/api.js'))\n }\n manifest = JSON.parse(readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\napp.use('/*', serveStatic({\n root: './dist/client',\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, {renderModule, apiModule, manifest})\n registerSsrRoute(app, {renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout})\n}\n\nserve({fetch: app.fetch, port, hostname: host}, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport {}", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["app", "apiModule", "renderModule", "manifest"]
7
7
  }