@devlusoft/devix 0.4.4 → 0.5.1

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 (81) hide show
  1. package/README.md +64 -9
  2. package/dist/cli/build.js +27 -17
  3. package/dist/cli/build.js.map +3 -3
  4. package/dist/cli/dev-server.js +31 -21
  5. package/dist/cli/dev-server.js.map +4 -4
  6. package/dist/cli/generate.js +29 -19
  7. package/dist/cli/generate.js.map +3 -3
  8. package/dist/cli/index.js +30 -20
  9. package/dist/cli/index.js.map +4 -4
  10. package/dist/cli/start.js +1 -1
  11. package/dist/cli/start.js.map +4 -4
  12. package/dist/config.d.ts +61 -0
  13. package/dist/config.js +1 -1
  14. package/dist/config.js.map +3 -3
  15. package/dist/runtime/api-context.d.ts +9 -4
  16. package/dist/runtime/api-context.js +1 -1
  17. package/dist/runtime/api-context.js.map +3 -3
  18. package/dist/runtime/context.d.ts +1 -0
  19. package/dist/runtime/context.js.map +2 -2
  20. package/dist/runtime/create-handler.d.ts +52 -2
  21. package/dist/runtime/create-handler.js +1 -1
  22. package/dist/runtime/create-handler.js.map +3 -3
  23. package/dist/runtime/error-boundary.d.ts +7 -1
  24. package/dist/runtime/error-boundary.js +1 -1
  25. package/dist/runtime/error-boundary.js.map +3 -3
  26. package/dist/runtime/fetch.d.ts +1 -0
  27. package/dist/runtime/fetch.js +1 -1
  28. package/dist/runtime/fetch.js.map +3 -3
  29. package/dist/runtime/index.d.ts +6 -2
  30. package/dist/runtime/index.js +1 -1
  31. package/dist/runtime/index.js.map +4 -4
  32. package/dist/runtime/link.js.map +2 -2
  33. package/dist/runtime/router-provider.d.ts +24 -1
  34. package/dist/runtime/router-provider.js +1 -1
  35. package/dist/runtime/router-provider.js.map +3 -3
  36. package/dist/runtime/server-app.d.ts +2 -1
  37. package/dist/runtime/server-app.js +1 -1
  38. package/dist/runtime/server-app.js.map +3 -3
  39. package/dist/runtime/server-client.d.ts +66 -0
  40. package/dist/runtime/server-client.js +2 -0
  41. package/dist/runtime/server-client.js.map +7 -0
  42. package/dist/server/api.d.ts +2 -1
  43. package/dist/server/api.js +1 -1
  44. package/dist/server/api.js.map +4 -4
  45. package/dist/server/handler-store.d.ts +12 -0
  46. package/dist/server/handler-store.js.map +2 -2
  47. package/dist/server/public-index.js.map +2 -2
  48. package/dist/server/render.d.ts +8 -0
  49. package/dist/server/render.js +1 -1
  50. package/dist/server/render.js.map +4 -4
  51. package/dist/server/routes.d.ts +4 -2
  52. package/dist/server/routes.js +1 -1
  53. package/dist/server/routes.js.map +4 -4
  54. package/dist/server/server-bound.d.ts +11 -0
  55. package/dist/server/server-bound.js +2 -0
  56. package/dist/server/server-bound.js.map +7 -0
  57. package/dist/server/server-proxy.d.ts +15 -0
  58. package/dist/server/server-proxy.js +2 -0
  59. package/dist/server/server-proxy.js.map +7 -0
  60. package/dist/server/types.d.ts +1 -0
  61. package/dist/types.d.ts +22 -0
  62. package/dist/utils/banner.js +1 -1
  63. package/dist/utils/glob.d.ts +11 -0
  64. package/dist/utils/glob.js +2 -0
  65. package/dist/utils/glob.js.map +7 -0
  66. package/dist/utils/response.d.ts +33 -1
  67. package/dist/utils/response.js +1 -1
  68. package/dist/utils/response.js.map +3 -3
  69. package/dist/utils/standard-schema.d.ts +39 -0
  70. package/dist/utils/standard-schema.js +1 -0
  71. package/dist/utils/standard-schema.js.map +7 -0
  72. package/dist/vite/codegen/entry-client.js +5 -3
  73. package/dist/vite/codegen/entry-client.js.map +2 -2
  74. package/dist/vite/codegen/page-types.d.ts +11 -2
  75. package/dist/vite/codegen/page-types.js +3 -3
  76. package/dist/vite/codegen/page-types.js.map +3 -3
  77. package/dist/vite/codegen/server-entry.js +16 -8
  78. package/dist/vite/codegen/server-entry.js.map +2 -2
  79. package/dist/vite/index.js +26 -16
  80. package/dist/vite/index.js.map +3 -3
  81. package/package.json +5 -5
@@ -1,4 +1,4 @@
1
- var l=(e,t)=>()=>(e&&(t=e(e=0)),t);import{build as Ue}from"esbuild";import{join as G}from"node:path";import{unlinkSync as Ne,writeFileSync as He}from"node:fs";import{pathToFileURL as ke}from"node:url";async function T(e){let t=await Ue({entryPoints:[G(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=G(e,`.devix-config-${Date.now()}.mjs`);He(r,t.outputFiles[0].text);try{return(await import(ke(r).href)).default}finally{Ne(r)}}var A=l(()=>{"use strict"});function X({cssUrls:e}){return`
1
+ var l=(e,t)=>()=>(e&&(t=e(e=0)),t);import{build as Ue}from"esbuild";import{join as X}from"node:path";import{unlinkSync as Ne,writeFileSync as He}from"node:fs";import{pathToFileURL as ke}from"node:url";async function b(e){let t=await Ue({entryPoints:[X(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=X(e,`.devix-config-${Date.now()}.mjs`);He(r,t.outputFiles[0].text);try{return(await import(ke(r).href)).default}finally{Ne(r)}}var C=l(()=>{"use strict"});function Y({cssUrls:e}){return`
2
2
  ${e.map(r=>`import '${r}'`).join(`
3
3
  `)}
4
4
  import "@vitejs/plugin-react/preamble"
@@ -16,11 +16,12 @@ if (!window.__DEVIX__) {
16
16
  const {metadata, viewport, clientEntry} = window.__DEVIX__
17
17
  const loaderData = window.__LOADER_DATA__
18
18
  const layoutsData = window.__LAYOUTS_DATA__ ?? []
19
+ const guardData = window.__GUARD_DATA__ ?? null
19
20
 
20
21
  const matched = matchClientRoute(window.location.pathname)
21
22
 
22
23
  if (window.__LOADER_ERROR__) {
23
- const {statusCode, message, data} = window.__LOADER_ERROR__
24
+ const {statusCode, message, code, data} = window.__LOADER_ERROR__
24
25
  const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()
25
26
  createRoot(root).render(
26
27
  React.createElement(RouterProvider, {
@@ -28,7 +29,7 @@ if (!window.__DEVIX__) {
28
29
  initialData: null,
29
30
  initialParams: {},
30
31
  initialPage: () => null,
31
- initialError: {statusCode, message, data},
32
+ initialError: {statusCode, message, code, data},
32
33
  initialErrorPage: ErrorPage,
33
34
  })
34
35
  )
@@ -46,6 +47,7 @@ if (!window.__DEVIX__) {
46
47
  initialPage: pageMod.default,
47
48
  initialLayouts: layoutMods.map(m => m.default),
48
49
  initialLayoutsData: layoutsData,
50
+ initialGuardData: guardData,
49
51
  initialMeta: metadata,
50
52
  initialViewport: viewport,
51
53
  })
@@ -75,7 +77,7 @@ if (!window.__DEVIX__) {
75
77
  )
76
78
  }
77
79
  }
78
- `}var Y=l(()=>{"use strict"});function z({pagesDir:e,matcherPath:t}){return`
80
+ `}var z=l(()=>{"use strict"});function Z({pagesDir:e,matcherPath:t}){return`
79
81
  import React from 'react'
80
82
  import { createMatcher } from '${t}'
81
83
  const pageFiles = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
@@ -103,7 +105,7 @@ export function getDefaultErrorPage() {
103
105
  )
104
106
  }
105
107
  }
106
- `}var Z=l(()=>{"use strict"});function K({pagesDir:e,renderPath:t}){return`
108
+ `}var K=l(()=>{"use strict"});function Q({pagesDir:e,renderPath:t}){return`
107
109
  import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${t}'
108
110
 
109
111
  const _pages = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
@@ -126,7 +128,7 @@ export function runLoader(url, request, options) {
126
128
  export function getStaticRoutes() {
127
129
  return _getStaticRoutes(_glob)
128
130
  }
129
- `}var Q=l(()=>{"use strict"});function ee({apiPath:e,appDir:t}){return`
131
+ `}var ee=l(()=>{"use strict"});function te({apiPath:e,appDir:t}){return`
130
132
  import { handleApiRequest as _handleApiRequest } from '${e}'
131
133
 
132
134
  const _routes = import.meta.glob(['/${t}/api/**/*.ts', '!**/middleware.ts'])
@@ -141,15 +143,15 @@ const _glob = {
141
143
  export function handleApiRequest(url, request) {
142
144
  return _handleApiRequest(url, request, _glob)
143
145
  }
144
- `}var te=l(()=>{"use strict"});function re(){return`
146
+ `}var re=l(()=>{"use strict"});function oe(){return`
145
147
  export {RouterContext} from '@devlusoft/devix/runtime/context'
146
- `}var oe=l(()=>{"use strict"});function Ve(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function ne(e){let t=new Set;for(let r of Ve(e).matchAll(qe))t.add(r[1]);return[...t]}var qe,ie=l(()=>{"use strict";qe=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function se(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var ae=l(()=>{"use strict"});function ce(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),o=se(r);return o==="/"?"/api":`/api/${o}`.replace("/api//","/api/")}var le=l(()=>{"use strict";ae()});function We(e,t){return"_api_"+e.slice(`${t}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function ue(e,t,r){return{filePath:e,urlPattern:ce(e,t),identifier:We(e,t),methods:r}}function F(e,t){if(e.length===0)return`// auto-generado por devix \u2014 no editar
148
+ `}var ne=l(()=>{"use strict"});function qe(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function ie(e){let t=new Set;for(let r of qe(e).matchAll(We))t.add(r[1]);return[...t]}var We,se=l(()=>{"use strict";We=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function ae(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var ce=l(()=>{"use strict"});function le(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),i=ae(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}var ue=l(()=>{"use strict";ce()});function Ve(e,t){return"_api_"+e.slice(`${t}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function pe(e,t,r){return{filePath:e,urlPattern:le(e,t),identifier:Ve(e,t),methods:r}}function F(e,t){if(e.length===0)return`// auto-generado por devix \u2014 no editar
147
149
  export {}
148
150
  declare module '@devlusoft/devix' {
149
151
  interface ApiRoutes {}
150
152
  }
151
- `;let r=e.map(n=>{let a="../"+n.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${n.identifier} from '${a}'`}).join(`
152
- `),o=e.flatMap(n=>n.methods.map(a=>` '${a} ${n.urlPattern}': InferRoute<(typeof ${n.identifier})['${a}']>`)).join(`
153
+ `;let r=e.map(o=>{let a="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${a}'`}).join(`
154
+ `),i=e.flatMap(o=>o.methods.map(a=>` '${a} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${a}']>`)).join(`
153
155
  `);return`// auto-generado por devix \u2014 no editar
154
156
  ${r}
155
157
 
@@ -170,14 +172,14 @@ type InferRoute<T> =
170
172
 
171
173
  declare module '@devlusoft/devix' {
172
174
  interface ApiRoutes {
173
- ${o}
175
+ ${i}
174
176
  }
175
177
  }
176
- `}var O=l(()=>{"use strict";le()});import{readFileSync as Je,readdirSync as Be,statSync as Ge}from"node:fs";import{join as M,relative as Xe}from"node:path";function pe(e,t){let r=[];for(let o of Be(e)){let n=M(e,o);Ge(n).isDirectory()?r.push(...pe(n,t)):/\.(ts|tsx)$/.test(o)&&r.push(Xe(t,n).replace(/\\/g,"/"))}return r}function I(e,t){let r=M(t,e,"api"),o;try{o=pe(r,t)}catch{return[]}return o.filter(n=>!n.endsWith("middleware.ts")&&!n.endsWith("middleware.tsx")).flatMap(n=>{try{let a=Je(M(t,n),"utf-8"),d=ne(a);return d.length===0?[]:[ue(n,`${e}/api`,d)]}catch{return[]}})}var de=l(()=>{"use strict";ie();O()});import{mkdirSync as Ye,readFileSync as ze,writeFileSync as Ze,existsSync as Ke}from"node:fs";import{join as me}from"node:path";function j(e,t){let r=me(t,".devix"),o=me(r,"routes.d.ts");return Ye(r,{recursive:!0}),Ke(o)&&ze(o,"utf-8")===e?!1:(Ze(o,e,"utf-8"),!0)}var fe=l(()=>{"use strict"});function ge({routesPath:e,envPath:t,honoServerPath:r,honoServerStaticPath:o,honoPath:n}){return`
178
+ `}var M=l(()=>{"use strict";ue()});import{readFileSync as Je,readdirSync as Be,statSync as Ge}from"node:fs";import{join as I,relative as Xe}from"node:path";function de(e,t){let r=[];for(let i of Be(e)){let o=I(e,i);Ge(o).isDirectory()?r.push(...de(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(Xe(t,o).replace(/\\/g,"/"))}return r}function O(e,t){let r=I(t,e,"api"),i;try{i=de(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=Je(I(t,o),"utf-8"),c=ie(a);return c.length===0?[]:[pe(o,`${e}/api`,c)]}catch{return[]}})}var fe=l(()=>{"use strict";se();M()});import{mkdirSync as Ye,readFileSync as ze,writeFileSync as Ze,existsSync as Ke}from"node:fs";import{join as me}from"node:path";function L(e,t){let r=me(t,".devix"),i=me(r,"routes.d.ts");return Ye(r,{recursive:!0}),Ke(i)&&ze(i,"utf-8")===e?!1:(Ze(i,e,"utf-8"),!0)}var ge=l(()=>{"use strict"});function xe({routesPath:e,envPath:t,honoServerPath:r,honoServerStaticPath:i,honoPath:o}){return`
177
179
  import { readFileSync } from 'node:fs'
178
180
  import { serve } from '${r}'
179
- import { serveStatic } from '${o}'
180
- import { Hono } from '${n}'
181
+ import { serveStatic } from '${i}'
182
+ import { Hono } from '${o}'
181
183
  import { resolve, join, dirname } from 'node:path'
182
184
  import { pathToFileURL } from 'node:url'
183
185
  import { registerApiRoutes, registerSsrRoute } from '${e}'
@@ -234,9 +236,17 @@ import { readFileSync } from 'node:fs'
234
236
 
235
237
  if (runtimeConfig.output === 'static') {
236
238
  console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')
237
- } else {
238
- registerApiRoutes(app, { renderModule, apiModule, manifest })
239
- registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout })
239
+ } else {
240
+ let userServerConfig
241
+ try {
242
+ const userConfigMod = await import(pathToFileURL(resolve(process.cwd(), 'devix.config.ts')).href).catch(() =>
243
+ import(pathToFileURL(resolve(process.cwd(), 'devix.config.js')).href))
244
+ userServerConfig = userConfigMod?.default?.server
245
+ } catch {
246
+ /* config sin server \u2014 sigue normal */
247
+ }
248
+ registerApiRoutes(app, { renderModule, apiModule, manifest, server: userServerConfig })
249
+ registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout, server: userServerConfig })
240
250
  }
241
251
 
242
252
  const server = serve({ fetch: app.fetch, port, hostname: host }, (info) =>
@@ -244,7 +254,7 @@ import { readFileSync } from 'node:fs'
244
254
 
245
255
  process.on('SIGTERM', () => server.close())
246
256
  process.on('SIGINT', () => server.close())
247
- `}var he=l(()=>{"use strict"});import{existsSync as ye,mkdirSync as Qe,readdirSync as et,readFileSync as xe,rmSync as tt,statSync as rt,writeFileSync as ot}from"node:fs";import{join as g,relative as ve}from"node:path";import{parseSync as nt}from"oxc-parser";function Re(e,t){let r=[];for(let o of et(e)){let n=g(e,o);rt(n).isDirectory()?r.push(...Re(n,t)):/\.(ts|tsx)$/.test(o)&&o!=="layout.tsx"&&o!=="error.tsx"&&r.push(ve(t,n).replace(/\\/g,"/"))}return r}function it(e,t){let r=nt(t,e,{sourceType:"module"});for(let o of r.program.body){if(o.type!=="ExportNamedDeclaration")continue;let n=o.declaration;if(n?.type==="FunctionDeclaration"&&n.id?.name==="loader")return!0;if(n?.type==="VariableDeclaration"){for(let a of n.declarations)if(a.id.type==="Identifier"&&a.id.name==="loader")return!0}for(let a of o.specifiers??[])if(a.exported.type==="Identifier"&&a.exported.name==="loader")return!0}return!1}function st(e,t){return t?`// auto-generado por devix \u2014 no editar
257
+ `}var he=l(()=>{"use strict"});import{existsSync as ve,mkdirSync as Qe,readdirSync as et,readFileSync as ye,rmSync as tt,statSync as rt,writeFileSync as ot}from"node:fs";import{join as h,relative as Re}from"node:path";import{parseSync as nt}from"oxc-parser";function we(e,t){let r=[];for(let i of et(e)){let o=h(e,i);rt(o).isDirectory()?r.push(...we(o,t)):/\.(ts|tsx)$/.test(i)&&i!=="layout.tsx"&&i!=="error.tsx"&&r.push(Re(t,o).replace(/\\/g,"/"))}return r}function it(e,t){let r=nt(t,e,{sourceType:"module"});for(let i of r.program.body){if(i.type!=="ExportNamedDeclaration")continue;let o=i.declaration;if(o?.type==="FunctionDeclaration"&&o.id?.name==="loader")return{exists:!0,isAsync:o.async,isReExport:!1};if(o?.type==="VariableDeclaration"){for(let a of o.declarations)if(a.id.type==="Identifier"&&a.id.name==="loader"){let c=a.init;return{exists:!0,isAsync:c?.type==="ArrowFunctionExpression"&&c.async||c?.type==="FunctionExpression"&&c.async,isReExport:!1}}}for(let a of i.specifiers??[])if(a.exported.type==="Identifier"&&a.exported.name==="loader")return{exists:!0,isAsync:!1,isReExport:!0}}return{exists:!1,isAsync:!1,isReExport:!1}}function st(e,t){return t?`// auto-generado por devix \u2014 no editar
248
258
  import type { loader } from "${e}"
249
259
  import type { Redirect } from "@devlusoft/devix"
250
260
 
@@ -256,5 +266,5 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
256
266
  `:`// auto-generado por devix - no editar
257
267
  export type PageData = undefined
258
268
  export type PageParams = Record<string, string>
259
- `}function $(e,t){let r=g(t,e),o=xe(r,"utf-8"),n=it(o,r),a=g(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),d=g(a,"$types.d.ts"),D=r.replace(/\.(tsx?|jsx?)$/,""),b=ve(a,D).replace(/\\/g,"/"),h=st(b,n);ye(d)&&xe(d,"utf-8")===h||(Qe(a,{recursive:!0}),ot(d,h,"utf-8"))}function we(e,t){let r=g(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),o=g(r,"$types.d.ts");ye(o)&&tt(o)}function L(e,t){let r=g(t,e,"pages"),o;try{o=Re(r,t)}catch{return}for(let n of o)try{$(n,t)}catch{}}var _e=l(()=>{"use strict"});import{mergeConfig as at}from"vite";import ct from"@vitejs/plugin-react";import{fileURLToPath as lt}from"node:url";import{dirname as ut,relative as pt,resolve as p}from"node:path";import{createRequire as dt}from"node:module";import{parseSync as mt}from"oxc-parser";function Ee(e){let t=e.appDir??"app",r=`${t}/pages`,o=(e.css??[]).map(i=>i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`),n=p(w,"../server/render.js").replace(/\\/g,"/"),a=p(w,"../server/api.js").replace(/\\/g,"/"),d=p(w,"../runtime/client-router.js").replace(/\\/g,"/"),D=p(w,"../server/routes.js").replace(/\\/g,"/"),b=p(w,"../utils/env.js").replace(/\\/g,"/"),h=dt(import.meta.url),Oe=h.resolve("@hono/node-server").replace(/\\/g,"/"),Me=h.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),Ie=h.resolve("hono").replace(/\\/g,"/"),je={name:"devix",enforce:"pre",resolveId(i){if(i===U)return`\0${U}`;if(i===N)return`\0${N}`;if(i===_)return`\0${_}`;if(i===P)return`\0${P}`;if(i===H)return`\0${H}`;if(i===k)return`\0${k}`},load(i){if(i===`\0${U}`)return X({cssUrls:o});if(i===`\0${N}`)return z({pagesDir:r,matcherPath:d});if(i===`\0${_}`)return K({pagesDir:r,renderPath:n});if(i===`\0${P}`)return ee({apiPath:a,appDir:t});if(i===`\0${H}`)return re();if(i===`\0${k}`)return ge({routesPath:D,envPath:b,honoServerPath:Oe,honoServerStaticPath:Me,honoPath:Ie})},transform(i,c,y){if(y?.ssr)return;let v=p(process.cwd(),r);if(!c.startsWith(v))return;let R=mt(c,i,{sourceType:"module"}),m=[];for(let u of R.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let f=u.declaration;if(f.type==="FunctionDeclaration"&&f.id&&Pe.has(f.id.name)&&m.push({start:u.start,end:u.end,name:f.id.name}),f.type==="VariableDeclaration"){let S=new Set;for(let C of f.declarations)C.id.type==="Identifier"&&Pe.has(C.id.name)&&(S.has(u.start)||(S.add(u.start),m.push({start:u.start,end:u.end,name:C.id.name})))}}if(m.length===0)return;m.sort((u,f)=>f.start-u.start);let s=i;for(let{start:u,end:f,name:S}of m)s=s.slice(0,u)+`export const ${S} = undefined`+s.slice(f);return{code:s,map:null}},buildStart(){let i=process.cwd(),c=I(t,i);j(F(c,`${t}/api`),i),L(t,i)},configureServer(i){let c=process.cwd();L(t,c);let y=()=>{let s=I(t,c);j(F(s,`${t}/api`),c)},v=s=>s.startsWith(p(c,r))&&!s.endsWith("layout.tsx")&&!s.endsWith("error.tsx"),R=s=>pt(c,s).replace(/\\/g,"/"),m=s=>{let u=i.moduleGraph.getModuleById(`\0${s}`);u&&i.moduleGraph.invalidateModule(u)};i.watcher.add(p(c,"devix.config.ts")),i.watcher.on("change",s=>{s===p(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),i.watcher.on("add",s=>{s.startsWith(p(c,r))&&m(_),v(s)&&$(R(s),c),s.includes(`${t}/api`)&&(m(P),y())}),i.watcher.on("unlink",s=>{s.startsWith(p(c,r))&&m(_),v(s)&&we(R(s),c),s.includes(`${t}/api`)&&(m(P),y())}),i.watcher.on("change",s=>{v(s)&&$(R(s),c),s.includes(`${t}/api`)&&!s.endsWith("middleware.ts")&&y()})}},Le={plugins:[ct(),je],publicDir:p(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return at(Le,e.vite??{})}var w,U,N,_,P,H,k,Pe,Se=l(()=>{"use strict";Y();Z();Q();te();oe();de();O();fe();he();_e();w=ut(lt(import.meta.url)),U="virtual:devix/entry-client",N="virtual:devix/client-routes",_="virtual:devix/render",P="virtual:devix/api",H="virtual:devix/context",k="virtual:devix/server-entry",Pe=new Set(["loader","guard","generateStaticParams","headers"])});function Te(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var $e=l(()=>{"use strict"});var xt={};import{writeFileSync as ft}from"node:fs";import{resolve as gt}from"node:path";import{build as q}from"vite";var E,V,ht,De=l(async()=>{"use strict";Se();$e();A();E=await T(process.cwd()),V=Ee(E);await q({...V,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await q({...V,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await q({...V,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});ht={port:E.port??3e3,host:E.host??!1,loaderTimeout:Te(E.loaderTimeout??1e4),output:E.output??"server"};ft(gt(process.cwd(),"dist/devix.config.json"),JSON.stringify(ht,null,2),"utf-8")});A();import{readFileSync as yt,mkdirSync as be,writeFileSync as Ce,rmSync as vt}from"node:fs";import{resolve as B,join as x}from"node:path";import{pathToFileURL as Rt}from"node:url";var Fe=await T(process.cwd());Fe.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await De().then(()=>xt);var wt=Date.now(),W=await import(Rt(B(process.cwd(),"dist/server/render.js")).href+`?t=${wt}`),Ae=JSON.parse(yt(B(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),J=await W.getStaticRoutes();console.log(`[devix] Generating ${J.length} static page${J.length===1?"":"s"}...`);for(let e of J){let t=`http://localhost${e}`,{html:r,statusCode:o}=await W.render(t,new Request(t),{manifest:Ae});if(o!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${o}`);continue}let n=e==="/"?x(process.cwd(),"dist/client/index.html"):x(process.cwd(),"dist/client",e,"index.html");be(x(n,".."),{recursive:!0}),Ce(n,`<!DOCTYPE html>${r}`,"utf-8");let a=await W.runLoader(t,new Request(t),{manifest:Ae}),d=e==="/"?x(process.cwd(),"dist/client/_data/index.json"):x(process.cwd(),"dist/client/_data",`${e}.json`);be(x(d,".."),{recursive:!0}),Ce(d,JSON.stringify(a),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Fe.output==="static"&&(vt(B(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"));
269
+ `}function j(e,t){let r=h(t,e),i=ye(r,"utf-8"),o=it(i,r),a=[];o.exists&&!o.isAsync&&!o.isReExport&&a.push(`[devix] ${e}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let c=h(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),y=h(c,"$types.d.ts"),A=r.replace(/\.(tsx?|jsx?)$/,""),R=Re(c,A).replace(/\\/g,"/"),D=st(R,o.exists);return ve(y)&&ye(y,"utf-8")===D?{warnings:a}:(Qe(c,{recursive:!0}),ot(y,D,"utf-8"),{warnings:a})}function _e(e,t){let r=h(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),i=h(r,"$types.d.ts");ve(i)&&tt(i)}function U(e,t){let r=h(t,e,"pages"),i=[],o;try{o=we(r,t)}catch{return{warnings:i}}for(let a of o)try{let c=j(a,t);i.push(...c.warnings)}catch{}return{warnings:i}}var Ee=l(()=>{"use strict"});import{mergeConfig as at}from"vite";import ct from"@vitejs/plugin-react";import{fileURLToPath as lt}from"node:url";import{dirname as ut,relative as pt,resolve as d}from"node:path";import{createRequire as dt}from"node:module";import{parseSync as ft}from"oxc-parser";function Se(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(s=>s.startsWith("/")?s:`/${s.replace(/^\.\//,"")}`),o=d(P,"../server/render.js").replace(/\\/g,"/"),a=d(P,"../server/api.js").replace(/\\/g,"/"),c=d(P,"../runtime/client-router.js").replace(/\\/g,"/"),y=d(P,"../server/routes.js").replace(/\\/g,"/"),A=d(P,"../utils/env.js").replace(/\\/g,"/"),R=dt(import.meta.url),D=R.resolve("@hono/node-server").replace(/\\/g,"/"),Ie=R.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),Oe=R.resolve("hono").replace(/\\/g,"/"),Le={name:"devix",enforce:"pre",resolveId(s){if(s===N)return`\0${N}`;if(s===H)return`\0${H}`;if(s===S)return`\0${S}`;if(s===T)return`\0${T}`;if(s===k)return`\0${k}`;if(s===W)return`\0${W}`},load(s){if(s===`\0${N}`)return Y({cssUrls:i});if(s===`\0${H}`)return Z({pagesDir:r,matcherPath:c});if(s===`\0${S}`)return Q({pagesDir:r,renderPath:o});if(s===`\0${T}`)return te({apiPath:a,appDir:t});if(s===`\0${k}`)return oe();if(s===`\0${W}`)return xe({routesPath:y,envPath:A,honoServerPath:D,honoServerStaticPath:Ie,honoPath:Oe})},transform(s,u,w){if(w?.ssr)return;let x=d(process.cwd(),r);if(!u.startsWith(x))return;let _=ft(u,s,{sourceType:"module"}),g=[];for(let p of _.program.body){if(p.type!=="ExportNamedDeclaration"||!p.declaration)continue;let n=p.declaration;if(n.type==="FunctionDeclaration"&&n.id&&Pe.has(n.id.name)&&g.push({start:p.start,end:p.end,name:n.id.name}),n.type==="VariableDeclaration"){let m=new Set;for(let E of n.declarations)E.id.type==="Identifier"&&Pe.has(E.id.name)&&(m.has(p.start)||(m.add(p.start),g.push({start:p.start,end:p.end,name:E.id.name})))}}if(g.length===0)return;g.sort((p,n)=>n.start-p.start);let f=s;for(let{start:p,end:n,name:m}of g)f=f.slice(0,p)+`export const ${m} = undefined`+f.slice(n);return{code:f,map:null}},buildStart(){let s=process.cwd(),u=O(t,s);L(F(u,`${t}/api`),s);let{warnings:w}=U(t,s);for(let x of w)console.warn(x)},configureServer(s){let u=process.cwd(),w=U(t,u);for(let n of w.warnings)console.warn(n);let x=()=>{let n=O(t,u);L(F(n,`${t}/api`),u)},_=n=>n.startsWith(d(u,r))&&!n.endsWith("layout.tsx")&&!n.endsWith("error.tsx"),g=n=>pt(u,n).replace(/\\/g,"/"),f=n=>{let m=s.moduleGraph.getModuleById(`\0${n}`);m&&s.moduleGraph.invalidateModule(m)};s.watcher.add(d(u,"devix.config.ts")),s.watcher.on("change",n=>{n===d(u,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))});let p=n=>{try{let{warnings:m}=j(g(n),u);for(let E of m)console.warn(E)}catch{}};s.watcher.on("add",n=>{n.startsWith(d(u,r))&&f(S),_(n)&&p(n),n.includes(`${t}/api`)&&(f(T),x())}),s.watcher.on("unlink",n=>{n.startsWith(d(u,r))&&f(S),_(n)&&_e(g(n),u),n.includes(`${t}/api`)&&(f(T),x())}),s.watcher.on("change",n=>{_(n)&&p(n),n.includes(`${t}/api`)&&!n.endsWith("middleware.ts")&&x()})}},je={plugins:[ct(),Le],publicDir:d(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return at(je,e.vite??{})}var P,N,H,S,T,k,W,Pe,Te=l(()=>{"use strict";z();K();ee();re();ne();fe();M();ge();he();Ee();P=ut(lt(import.meta.url)),N="virtual:devix/entry-client",H="virtual:devix/client-routes",S="virtual:devix/render",T="virtual:devix/api",k="virtual:devix/context",W="virtual:devix/server-entry",Pe=new Set(["loader","guard","generateStaticParams","headers"])});function $e(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var De=l(()=>{"use strict"});var ht={};import{writeFileSync as mt}from"node:fs";import{resolve as gt}from"node:path";import{build as q}from"vite";var $,V,xt,be=l(async()=>{"use strict";Te();De();C();$=await b(process.cwd()),V=Se($);await q({...V,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await q({...V,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await q({...V,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});xt={port:$.port??3e3,host:$.host??!1,loaderTimeout:$e($.loaderTimeout??1e4),output:$.output??"server"};mt(gt(process.cwd(),"dist/devix.config.json"),JSON.stringify(xt,null,2),"utf-8")});C();import{readFileSync as yt,mkdirSync as Ae,writeFileSync as Ce,rmSync as vt}from"node:fs";import{resolve as G,join as v}from"node:path";import{pathToFileURL as Rt}from"node:url";var Me=await b(process.cwd());Me.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await be().then(()=>ht);var wt=Date.now(),J=await import(Rt(G(process.cwd(),"dist/server/render.js")).href+`?t=${wt}`),Fe=JSON.parse(yt(G(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),B=await J.getStaticRoutes();console.log(`[devix] Generating ${B.length} static page${B.length===1?"":"s"}...`);for(let e of B){let t=`http://localhost${e}`,{html:r,statusCode:i}=await J.render(t,new Request(t),{manifest:Fe});if(i!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${i}`);continue}let o=e==="/"?v(process.cwd(),"dist/client/index.html"):v(process.cwd(),"dist/client",e,"index.html");Ae(v(o,".."),{recursive:!0}),Ce(o,`<!DOCTYPE html>${r}`,"utf-8");let a=await J.runLoader(t,new Request(t),{manifest:Fe}),c=e==="/"?v(process.cwd(),"dist/client/_data/index.json"):v(process.cwd(),"dist/client/_data",`${e}.json`);Ae(v(c,".."),{recursive:!0}),Ce(c,JSON.stringify(a),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Me.output==="static"&&(vt(G(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"));
260
270
  //# sourceMappingURL=generate.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/load-config.ts", "../../src/vite/codegen/entry-client.ts", "../../src/vite/codegen/client-routes.ts", "../../src/vite/codegen/render.ts", "../../src/vite/codegen/api.ts", "../../src/vite/codegen/context.ts", "../../src/vite/codegen/extract-methods.ts", "../../src/utils/patterns.ts", "../../src/server/api-router.ts", "../../src/vite/codegen/routes-dts.ts", "../../src/vite/codegen/scan-api.ts", "../../src/vite/codegen/write-routes-dts.ts", "../../src/vite/codegen/server-entry.ts", "../../src/vite/codegen/page-types.ts", "../../src/vite/index.ts", "../../src/utils/duration.ts", "../../src/cli/build.ts", "../../src/cli/generate.ts"],
4
- "sourcesContent": ["import {build} from 'esbuild'\nimport type {DevixConfig} from \"../config\"\nimport {join} from \"node:path\"\nimport {unlinkSync, writeFileSync} from \"node:fs\";\nimport {pathToFileURL} from \"node:url\";\n\nexport async function loadConfig(cwd: string): Promise<DevixConfig> {\n const result = await build({\n entryPoints: [join(cwd, 'devix.config.ts')],\n bundle: true,\n write: false,\n format: 'esm',\n platform: 'node',\n packages: 'external',\n })\n\n const tmpFile = join(cwd, `.devix-config-${Date.now()}.mjs`)\n writeFileSync(tmpFile, result.outputFiles[0].text)\n\n try {\n const mod = await import(pathToFileURL(tmpFile).href)\n return mod.default\n } finally {\n unlinkSync(tmpFile)\n }\n}", "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 (window.__LOADER_ERROR__) {\n const {statusCode, message, data} = window.__LOADER_ERROR__\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 initialError: {statusCode, message, data},\n initialErrorPage: ErrorPage,\n })\n )\n } else 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\n if (window.location.hash) { \n const id = window.location.hash.slice(1) \n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior \n requestAnimationFrame(() => { \n document.getElementById(id)?.scrollIntoView({ behavior: scrollBehavior }) \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 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", "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 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\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\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 return {routes, middlewares}\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", "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\\nexport {}\\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 JsonResponse<T, S extends number = number> = Response & { readonly __body: T; readonly __status: S }\ntype Is2xx<S extends number> = [number] extends [S] ? boolean : S extends 200 | 201 | 202 | 203 | 204 | 205 | 206 ? true : false\ntype UnwrapSuccessJson<T> = T extends JsonResponse<infer U, infer S> ? Is2xx<S> extends false ? never : U : never\ntype UnwrapErrorJson<T> = T extends JsonResponse<infer U, infer S> ? Is2xx<S> extends true ? never : U : never\ntype InferFnSuccess<T> = T extends (...args: any[]) => any ? UnwrapSuccessJson<Awaited<ReturnType<T>>> : never\ntype InferFnErrors<T> = T extends (...args: any[]) => any ? UnwrapErrorJson<Awaited<ReturnType<T>>> : never\ntype InferRoute<T> =\n T extends { readonly __return?: infer TReturn; readonly __body?: infer TBody }\n ? {\n __body: [TBody] extends [undefined] ? never : Exclude<TBody, undefined>\n __response: InferFnSuccess<() => TReturn>\n __errors: InferFnErrors<() => TReturn>\n }\n : InferFnSuccess<T>\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", "interface ServerEntryOptions {\n routesPath: string\n envPath: string\n honoServerPath: string\n honoServerStaticPath: string\n honoPath: string\n}\n\nexport function generateServerEntry({ routesPath, envPath, honoServerPath, honoServerStaticPath, honoPath }: ServerEntryOptions): string {\n return `\nimport { readFileSync } from 'node:fs'\n import { serve } from '${honoServerPath}'\n import { serveStatic } from '${honoServerStaticPath}'\n import { Hono } from '${honoPath}'\n import { resolve, join, dirname } from 'node:path'\n import { pathToFileURL } from 'node:url'\n import { registerApiRoutes, registerSsrRoute } from '${routesPath}' \n import { loadDotenv } from '${envPath}'\n \n loadDotenv('production')\n \n const __dir = dirname(process.argv[1])\n\n let renderModule, apiModule, manifest, runtimeConfig \n \n try { \n runtimeConfig = JSON.parse(readFileSync(resolve(__dir, '../devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') { \n renderModule = await import(pathToFileURL(resolve(__dir, 'render.js')).href)\n apiModule = await import(pathToFileURL(resolve(__dir, 'api.js')).href) \n } \n manifest = JSON.parse(readFileSync(resolve(__dir, '../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 \n const port = Number(process.env.PORT) || runtimeConfig.port || 3000 \n const host = typeof runtimeConfig.host === 'string'\n ? runtimeConfig.host \n : runtimeConfig.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0') \n \n const clientRoot = resolve(__dir, '../client') \n const app = new Hono()\n \n if (runtimeConfig.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\\\/_data/, '') || '/' \n const filePath = pathname === '/' \n ? join(clientRoot, '_data/index.json') \n : join(clientRoot, '_data', pathname + '.json') \n try { \n return c.json(JSON.parse(readFileSync(filePath, 'utf-8')))\n } catch { \n return c.json({ error: 'not found' }, 404)\n } \n }) \n }\n\n app.use('/*', serveStatic({ \n root: clientRoot,\n onFound: (_path, c) => { \n c.header('Cache-Control', _path.includes('/assets/') \n ? 'public, immutable, max-age=31536000'\n : 'no-cache') \n } \n })) \n \n if (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 \n const server = serve({ fetch: app.fetch, port, hostname: host }, (info) => \n console.log(\\`http://\\${info.address}:\\${info.port}\\`))\n\nprocess.on('SIGTERM', () => server.close())\nprocess.on('SIGINT', () => server.close())\n`\n}", "import {existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync} from \"node:fs\";\nimport {join, relative} from \"node:path\";\nimport {parseSync} from \"oxc-parser\";\n\nfunction walkPages(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(...walkPages(full, root))\n } else if (/\\.(ts|tsx)$/.test(name) && name !== 'layout.tsx' && name !== 'error.tsx') {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport function hasLoaderExport(code: string, filePath: string): boolean {\n const ast = parseSync(filePath, code, {sourceType: 'module'})\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration') continue\n const decl = node.declaration\n if (decl?.type === 'FunctionDeclaration' && decl.id?.name === 'loader') return true\n if (decl?.type === 'VariableDeclaration') {\n for (const d of decl.declarations) {\n if (d.id.type === 'Identifier' && d.id.name === 'loader') return true\n }\n }\n for (const spec of (node.specifiers ?? [])) {\n if (spec.exported.type === 'Identifier' && spec.exported.name === 'loader') return true\n }\n }\n return false\n}\n\nexport function generatePageTypesDts(importPath: string, withLoader: boolean): string {\n if (!withLoader) {\n return '// auto-generado por devix - no editar\\nexport type PageData = undefined\\nexport type PageParams = Record<string, string>\\n'\n }\n return `// auto-generado por devix \u2014 no editar\\nimport type { loader } from \"${importPath}\"\\nimport type { Redirect } from \"@devlusoft/devix\"\\n\\nexport type PageData = Exclude<\\n Awaited<ReturnType<NonNullable<typeof loader>>>,\\n Redirect | void | undefined\\n>\\nexport type PageParams = NonNullable<Parameters<typeof loader>[0]>[\"params\"]\\n`\n}\n\nexport function writePageTypes(pageRelPath: string, root: string): void {\n const fullPath = join(root, pageRelPath)\n const code = readFileSync(fullPath, 'utf-8')\n const withLoader = hasLoaderExport(code, fullPath)\n\n const typesDir = join(root, '.devix', 'pages', pageRelPath.replace(/\\.(tsx?|jsx?)$/, ''))\n const outPath = join(typesDir, '$types.d.ts')\n\n const pageAbsNoExt = fullPath.replace(/\\.(tsx?|jsx?)$/, '')\n const importPath = relative(typesDir, pageAbsNoExt).replace(/\\\\/g, '/')\n\n const content = generatePageTypesDts(importPath, withLoader)\n\n if (existsSync(outPath) && readFileSync(outPath, 'utf-8') === content) return\n\n mkdirSync(typesDir, {recursive: true})\n writeFileSync(outPath, content, 'utf-8')\n}\n\nexport function deletePageTypes(pageRelPath: string, root: string): void {\n const typesDir = join(root, '.devix', 'pages', pageRelPath.replace(/\\.(tsx?|jsx?)$/, ''))\n const outPath = join(typesDir, '$types.d.ts')\n if (existsSync(outPath)) rmSync(outPath)\n}\n\nexport function scanAndWritePageTypes(appDir: string, root: string): void {\n const pagesDir = join(root, appDir, 'pages')\n let files: string[]\n try {\n files = walkPages(pagesDir, root)\n } catch {\n return\n }\n for (const file of files) {\n try {\n writePageTypes(file, root)\n } catch {\n /* ignorar archivos no procesables */\n }\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, relative, resolve} from 'node:path'\nimport {createRequire} from 'node:module'\nimport {generateEntryClient} from './codegen/entry-client'\nimport {generateClientRoutes} from './codegen/client-routes'\nimport {generateRender} from './codegen/render'\nimport {generateApi} from './codegen/api'\nimport {generateContext} from \"./codegen/context\";\nimport {scanApiFiles} from \"./codegen/scan-api\";\nimport {generateRoutesDts} from \"./codegen/routes-dts\";\nimport {writeRoutesDts} from \"./codegen/write-routes-dts\";\nimport {parseSync} from 'oxc-parser'\nimport {generateServerEntry} from \"./codegen/server-entry\";\nimport {deletePageTypes, scanAndWritePageTypes, writePageTypes} from \"./codegen/page-types\";\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'\nconst VIRTUAL_SERVER_ENTRY = 'virtual:devix/server-entry'\n\nconst SERVER_EXPORTS = new Set(['loader', 'guard', 'generateStaticParams', 'headers'])\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 const routesPath = resolve(__dirname, '../server/routes.js').replace(/\\\\/g, '/')\n const envPath = resolve(__dirname, '../utils/env.js').replace(/\\\\/g, '/')\n\n const _require = createRequire(import.meta.url)\n const honoServerPath = _require.resolve('@hono/node-server').replace(/\\\\/g, '/')\n const honoServerStaticPath = _require.resolve('@hono/node-server/serve-static').replace(/\\\\/g, '/')\n const honoPath = _require.resolve('hono').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 if (id === VIRTUAL_SERVER_ENTRY) return `\\0${VIRTUAL_SERVER_ENTRY}`\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 if (id === `\\0${VIRTUAL_SERVER_ENTRY}`)\n return generateServerEntry({routesPath, envPath, honoServerPath, honoServerStaticPath, honoPath})\n },\n\n\n transform(code, id, options) {\n if (options?.ssr) return\n\n const resolvedPagesDir = resolve(process.cwd(), pagesDir)\n if (!id.startsWith(resolvedPagesDir)) return\n\n const ast = parseSync(id, code, {sourceType: 'module'})\n\n const replacements: { start: number; end: number; name: string }[] = []\n\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration' || !node.declaration) continue\n\n const decl = node.declaration\n\n if (decl.type === 'FunctionDeclaration' && decl.id && SERVER_EXPORTS.has(decl.id.name)) {\n replacements.push({start: node.start, end: node.end, name: decl.id.name})\n }\n\n if (decl.type === 'VariableDeclaration') {\n const seen = new Set<number>()\n for (const declarator of decl.declarations) {\n if (declarator.id.type === 'Identifier' && SERVER_EXPORTS.has(declarator.id.name)) {\n if (!seen.has(node.start)) {\n seen.add(node.start)\n replacements.push({start: node.start, end: node.end, name: declarator.id.name})\n }\n }\n }\n }\n }\n\n if (replacements.length === 0) return\n\n replacements.sort((a, b) => b.start - a.start)\n\n let result = code\n for (const {start, end, name} of replacements) {\n result = result.slice(0, start) + `export const ${name} = undefined` + result.slice(end)\n }\n\n return {code: result, map: null}\n },\n\n buildStart() {\n const root = process.cwd()\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n scanAndWritePageTypes(appDir, root)\n },\n\n configureServer(server) {\n const root = process.cwd()\n\n scanAndWritePageTypes(appDir, root)\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n const isPageFile = (file: string) => file.startsWith(resolve(root, pagesDir)) && !file.endsWith('layout.tsx') && !file.endsWith('error.tsx')\n\n const pageRelPath = (file: string) => relative(root, file).replace(/\\\\/g, '/')\n\n const invalidateVirtualModule = (id: string) => {\n const mod = server.moduleGraph.getModuleById(`\\0${id}`)\n if (mod) server.moduleGraph.invalidateModule(mod)\n }\n\n server.watcher.add(resolve(root, 'devix.config.ts'))\n server.watcher.on('change', (file) => {\n if (file === resolve(root, 'devix.config.ts')) {\n console.log('[devix] Config changed, restarting...')\n process.exit(75)\n }\n })\n\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidateVirtualModule(VIRTUAL_RENDER)\n if (isPageFile(file)) writePageTypes(pageRelPath(file), root)\n if (file.includes(`${appDir}/api`)) {\n invalidateVirtualModule(VIRTUAL_API)\n regenerateDts()\n }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidateVirtualModule(VIRTUAL_RENDER)\n if (isPageFile(file)) deletePageTypes(pageRelPath(file), root)\n if (file.includes(`${appDir}/api`)) {\n invalidateVirtualModule(VIRTUAL_API)\n regenerateDts()\n }\n })\n server.watcher.on('change', (file) => {\n if (isPageFile(file)) writePageTypes(pageRelPath(file), root)\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 publicDir: resolve(process.cwd(), config.publicDir ?? 'public'),\n ssr: {noExternal: ['@devlusoft/devix']},\n ...(config.envPrefix ? {envPrefix: config.envPrefix} : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\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 {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\nimport {loadConfig} from \"../utils/load-config\";\n\nconst config = await loadConfig(process.cwd())\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 copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n emptyOutDir: false,\n copyPublicDir: false,\n rolldownOptions: {\n input: { index: 'virtual:devix/server-entry' },\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, rmSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport { pathToFileURL } from \"node:url\"\nimport {loadConfig} from \"../utils/load-config\";\n\nconst userConfig = await loadConfig(process.cwd())\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(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href + `?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\n const data = await renderModule.runLoader(fullUrl, new Request(fullUrl), {manifest})\n const dataPath = url === '/'\n ? join(process.cwd(), 'dist/client/_data/index.json')\n : join(process.cwd(), 'dist/client/_data', `${url}.json`)\n \n mkdirSync(join(dataPath, '..'), {recursive: true})\n writeFileSync(dataPath, JSON.stringify(data), 'utf-8')\n\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nif (userConfig.output === 'static') {\n rmSync(resolve(process.cwd(), 'dist/server'), { recursive: true, force: true })\n console.log('[devix] Removed dist/server (not needed in static mode)')\n}\n\nexport {}\n"],
5
- "mappings": "mCAAA,OAAQ,SAAAA,OAAY,UAEpB,OAAQ,QAAAC,MAAW,YACnB,OAAQ,cAAAC,GAAY,iBAAAC,OAAoB,UACxC,OAAQ,iBAAAC,OAAoB,WAE5B,eAAsBC,EAAWC,EAAmC,CAChE,IAAMC,EAAS,MAAMP,GAAM,CACvB,YAAa,CAACC,EAAKK,EAAK,iBAAiB,CAAC,EAC1C,OAAQ,GACR,MAAO,GACP,OAAQ,MACR,SAAU,OACV,SAAU,UACd,CAAC,EAEKE,EAAUP,EAAKK,EAAK,iBAAiB,KAAK,IAAI,CAAC,MAAM,EAC3DH,GAAcK,EAASD,EAAO,YAAY,CAAC,EAAE,IAAI,EAEjD,GAAI,CAEA,OADY,MAAM,OAAOH,GAAcI,CAAO,EAAE,OACrC,OACf,QAAE,CACEN,GAAWM,CAAO,CACtB,CACJ,CAzBA,IAAAC,EAAAC,EAAA,oBCIO,SAASC,EAAoB,CAAE,QAAAC,CAAQ,EAA+B,CAGzE,MAAO;AAAA,EAFYA,EAAQ,IAAIC,GAAK,WAAWA,CAAC,GAAG,EAAE,KAAK;AAAA,CAAI,CAGtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA4EZ,CApFA,IAAAC,EAAAC,EAAA,oBCKO,SAASC,EAAqB,CAAC,SAAAC,EAAU,YAAAC,CAAW,EAAwB,CAC/E,MAAO;AAAA;AAAA,iCAEsBA,CAAW;AAAA,wCACJD,CAAQ;AAAA,yCACPA,CAAQ;AAAA,wCACTA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAwBhD,CAnCA,IAAAE,EAAAC,EAAA,oBCKO,SAASC,EAAe,CAAC,SAAAC,EAAU,WAAAC,CAAU,EAA0B,CAC1E,MAAO;AAAA,mGACwFA,CAAU;AAAA;AAAA,qCAExED,CAAQ;AAAA,sCACPA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,kBAK5BA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAe1B,CA9BA,IAAAE,EAAAC,EAAA,oBCKO,SAASC,GAAY,CAAC,QAAAC,EAAS,OAAAC,CAAM,EAAuB,CAC/D,MAAO;AAAA,yDAC8CD,CAAO;AAAA;AAAA,sCAE1BC,CAAM;AAAA,0CACFA,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKhCA,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAOtB,CAtBA,IAAAC,GAAAC,EAAA,oBCAO,SAASC,IAA0B,CACtC,MAAO;AAAA;AAAA,CAGX,CAJA,IAAAC,GAAAC,EAAA,oBCKA,SAASC,GAAcC,EAAyB,CAC5C,OAAOA,EACF,QAAQ,oBAAqB,EAAE,EAC/B,QAAQ,YAAa,EAAE,CAChC,CAEO,SAASC,GAAmBD,EAA+B,CAC9D,IAAME,EAAQ,IAAI,IAClB,QAAWC,KAASJ,GAAcC,CAAO,EAAE,SAASI,EAAgB,EAChEF,EAAM,IAAIC,EAAM,CAAC,CAAe,EAEpC,MAAO,CAAC,GAAGD,CAAK,CACpB,CAjBA,IAGME,GAHNC,GAAAC,EAAA,kBAGMF,GAAmB,+FCHlB,SAASG,GAAaC,EAAqB,CAC9C,OAAOA,EACE,QAAQ,qBAAsB,EAAE,EAChC,QAAQ,aAAc,EAAE,EACxB,QAAQ,mBAAoB,EAAE,EAC9B,QAAQ,eAAgB,KAAK,GAC/B,GACX,CAPA,IAAAC,GAAAC,EAAA,oBCmBO,SAASC,GAAkBC,EAAaC,EAAwB,CACnE,IAAMC,EAAMF,EAAI,MAAMC,EAAO,OAAS,CAAC,EAAE,QAAQ,MAAO,GAAG,EACrDE,EAAUC,GAAaF,CAAG,EAChC,OAAOC,IAAY,IAAM,OAAS,QAAQA,CAAO,GAAG,QAAQ,SAAU,OAAO,CACjF,CAvBA,IAAAE,GAAAC,EAAA,kBAAAC,OCUO,SAASC,GAAqBC,EAAkBC,EAAwB,CAC3E,MAAO,QAAUD,EACZ,MAAM,GAAGC,CAAM,IAAI,MAAM,EACzB,QAAQ,cAAe,EAAE,EACzB,QAAQ,gBAAiB,GAAG,CACrC,CAEO,SAASC,GAAgBF,EAAkBC,EAAgBE,EAAmC,CACjG,MAAO,CACH,SAAAH,EACA,WAAYI,GAAkBJ,EAAUC,CAAM,EAC9C,WAAYF,GAAqBC,EAAUC,CAAM,EACjD,QAAAE,CACJ,CACJ,CAEO,SAASE,EAAkBC,EAAuBL,EAAwB,CAC7E,GAAIK,EAAQ,SAAW,EACnB,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAGX,IAAMC,EAAUD,EACX,IAAIE,GAAK,CACN,IAAMC,EAAa,MAAQD,EAAE,SAAS,QAAQ,cAAe,EAAE,EAC/D,MAAO,oBAAoBA,EAAE,UAAU,UAAUC,CAAU,GAC/D,CAAC,EACA,KAAK;AAAA,CAAI,EAERC,EAAaJ,EAAQ,QAAQE,GAC/BA,EAAE,QAAQ,IAAIG,GACV,QAAQA,CAAC,IAAIH,EAAE,UAAU,yBAAyBA,EAAE,UAAU,MAAMG,CAAC,KACzE,CACJ,EAAE,KAAK;AAAA,CAAI,EAEX,MAAO;AAAA,EACTJ,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBPG,CAAU;AAAA;AAAA;AAAA,CAIZ,CApEA,IAAAE,EAAAC,EAAA,kBAAAC,OCAA,OAAQ,gBAAAC,GAAc,eAAAC,GAAa,YAAAC,OAAe,UAClD,OAAQ,QAAAC,EAAM,YAAAC,OAAe,YAK7B,SAASC,GAAQC,EAAaC,EAAwB,CAClD,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQR,GAAYK,CAAG,EAAG,CACjC,IAAMI,EAAOP,EAAKG,EAAKG,CAAI,EACvBP,GAASQ,CAAI,EAAE,YAAY,EAC3BF,EAAQ,KAAK,GAAGH,GAAQK,EAAMH,CAAI,CAAC,EAC5B,cAAc,KAAKE,CAAI,GAC9BD,EAAQ,KAAKJ,GAASG,EAAMG,CAAI,EAAE,QAAQ,MAAO,GAAG,CAAC,CAE7D,CACA,OAAOF,CACX,CAEO,SAASG,EAAaC,EAAgBC,EAAmC,CAC5E,IAAMC,EAASX,EAAKU,EAAaD,EAAQ,KAAK,EAE1CG,EACJ,GAAI,CACAA,EAAQV,GAAQS,EAAQD,CAAW,CACvC,MAAQ,CACJ,MAAO,CAAC,CACZ,CAEA,OAAOE,EACF,OAAOC,GAAK,CAACA,EAAE,SAAS,eAAe,GAAK,CAACA,EAAE,SAAS,gBAAgB,CAAC,EACzE,QAAQC,GAAY,CACjB,GAAI,CACA,IAAMC,EAAUlB,GAAaG,EAAKU,EAAaI,CAAQ,EAAG,OAAO,EAC3DE,EAAUC,GAAmBF,CAAO,EAC1C,OAAIC,EAAQ,SAAW,EAAU,CAAC,EAC3B,CAACE,GAAgBJ,EAAU,GAAGL,CAAM,OAAQO,CAAO,CAAC,CAC/D,MAAQ,CACJ,MAAO,CAAC,CACZ,CACJ,CAAC,CACT,CAzCA,IAAAG,GAAAC,EAAA,kBAEAC,KACAC,MCHA,OAAQ,aAAAC,GAAW,gBAAAC,GAAc,iBAAAC,GAAe,cAAAC,OAAiB,UACjE,OAAQ,QAAAC,OAAW,YAEZ,SAASC,EAAeC,EAAiBC,EAA8B,CAC1E,IAAMC,EAAWJ,GAAKG,EAAa,QAAQ,EACrCE,EAAUL,GAAKI,EAAU,aAAa,EAI5C,OAFAR,GAAUQ,EAAU,CAAC,UAAW,EAAI,CAAC,EAEjCL,GAAWM,CAAO,GAAKR,GAAaQ,EAAS,OAAO,IAAMH,EACnD,IAGXJ,GAAcO,EAASH,EAAS,OAAO,EAChC,GACX,CAfA,IAAAI,GAAAC,EAAA,oBCQO,SAASC,GAAoB,CAAE,WAAAC,EAAY,QAAAC,EAAS,eAAAC,EAAgB,qBAAAC,EAAsB,SAAAC,CAAS,EAA+B,CACrI,MAAO;AAAA;AAAA,2BAEgBF,CAAc;AAAA,iCACRC,CAAoB;AAAA,0BAC3BC,CAAQ;AAAA;AAAA;AAAA,yDAGuBJ,CAAU;AAAA,gCACnCC,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAgEvC,CAjFA,IAAAI,GAAAC,EAAA,oBCAA,OAAQ,cAAAC,GAAY,aAAAC,GAAW,eAAAC,GAAa,gBAAAC,GAAc,UAAAC,GAAQ,YAAAC,GAAU,iBAAAC,OAAoB,UAChG,OAAQ,QAAAC,EAAM,YAAAC,OAAe,YAC7B,OAAQ,aAAAC,OAAgB,aAExB,SAASC,GAAUC,EAAaC,EAAwB,CACpD,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQZ,GAAYS,CAAG,EAAG,CACjC,IAAMI,EAAOR,EAAKI,EAAKG,CAAI,EACvBT,GAASU,CAAI,EAAE,YAAY,EAC3BF,EAAQ,KAAK,GAAGH,GAAUK,EAAMH,CAAI,CAAC,EAC9B,cAAc,KAAKE,CAAI,GAAKA,IAAS,cAAgBA,IAAS,aACrED,EAAQ,KAAKL,GAASI,EAAMG,CAAI,EAAE,QAAQ,MAAO,GAAG,CAAC,CAE7D,CACA,OAAOF,CACX,CAEO,SAASG,GAAgBC,EAAcC,EAA2B,CACrE,IAAMC,EAAMV,GAAUS,EAAUD,EAAM,CAAC,WAAY,QAAQ,CAAC,EAC5D,QAAWG,KAAQD,EAAI,QAAQ,KAAM,CACjC,GAAIC,EAAK,OAAS,yBAA0B,SAC5C,IAAMC,EAAOD,EAAK,YAClB,GAAIC,GAAM,OAAS,uBAAyBA,EAAK,IAAI,OAAS,SAAU,MAAO,GAC/E,GAAIA,GAAM,OAAS,uBACf,QAAWC,KAAKD,EAAK,aACjB,GAAIC,EAAE,GAAG,OAAS,cAAgBA,EAAE,GAAG,OAAS,SAAU,MAAO,GAGzE,QAAWC,KAASH,EAAK,YAAc,CAAC,EACpC,GAAIG,EAAK,SAAS,OAAS,cAAgBA,EAAK,SAAS,OAAS,SAAU,MAAO,EAE3F,CACA,MAAO,EACX,CAEO,SAASC,GAAqBC,EAAoBC,EAA6B,CAClF,OAAKA,EAGE;AAAA,+BAAwED,CAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAF9E;AAAA;AAAA;AAAA,CAGf,CAEO,SAASE,EAAeC,EAAqBhB,EAAoB,CACpE,IAAMiB,EAAWtB,EAAKK,EAAMgB,CAAW,EACjCX,EAAOd,GAAa0B,EAAU,OAAO,EACrCH,EAAaV,GAAgBC,EAAMY,CAAQ,EAE3CC,EAAWvB,EAAKK,EAAM,SAAU,QAASgB,EAAY,QAAQ,iBAAkB,EAAE,CAAC,EAClFG,EAAUxB,EAAKuB,EAAU,aAAa,EAEtCE,EAAeH,EAAS,QAAQ,iBAAkB,EAAE,EACpDJ,EAAajB,GAASsB,EAAUE,CAAY,EAAE,QAAQ,MAAO,GAAG,EAEhEC,EAAUT,GAAqBC,EAAYC,CAAU,EAEvD1B,GAAW+B,CAAO,GAAK5B,GAAa4B,EAAS,OAAO,IAAME,IAE9DhC,GAAU6B,EAAU,CAAC,UAAW,EAAI,CAAC,EACrCxB,GAAcyB,EAASE,EAAS,OAAO,EAC3C,CAEO,SAASC,GAAgBN,EAAqBhB,EAAoB,CACrE,IAAMkB,EAAWvB,EAAKK,EAAM,SAAU,QAASgB,EAAY,QAAQ,iBAAkB,EAAE,CAAC,EAClFG,EAAUxB,EAAKuB,EAAU,aAAa,EACxC9B,GAAW+B,CAAO,GAAG3B,GAAO2B,CAAO,CAC3C,CAEO,SAASI,EAAsBC,EAAgBxB,EAAoB,CACtE,IAAMyB,EAAW9B,EAAKK,EAAMwB,EAAQ,OAAO,EACvCE,EACJ,GAAI,CACAA,EAAQ5B,GAAU2B,EAAUzB,CAAI,CACpC,MAAQ,CACJ,MACJ,CACA,QAAW2B,KAAQD,EACf,GAAI,CACAX,EAAeY,EAAM3B,CAAI,CAC7B,MAAQ,CAER,CAER,CAlFA,IAAA4B,GAAAC,EAAA,oBCAA,OAA4B,eAAAC,OAAkB,OAE9C,OAAOC,OAAW,uBAClB,OAAQ,iBAAAC,OAAoB,WAC5B,OAAQ,WAAAC,GAAS,YAAAC,GAAU,WAAAC,MAAc,YACzC,OAAQ,iBAAAC,OAAoB,cAS5B,OAAQ,aAAAC,OAAgB,aAejB,SAASC,GAAMC,EAAiC,CACnD,IAAMC,EAASD,EAAO,QAAU,MAC1BE,EAAW,GAAGD,CAAM,SACpBE,GAAWH,EAAO,KAAO,CAAC,GAAG,IAAII,GAAKA,EAAE,WAAW,GAAG,EAAIA,EAAI,IAAIA,EAAE,QAAQ,QAAS,EAAE,CAAC,EAAE,EAE1FC,EAAaT,EAAQU,EAAW,qBAAqB,EAAE,QAAQ,MAAO,GAAG,EACzEC,EAAUX,EAAQU,EAAW,kBAAkB,EAAE,QAAQ,MAAO,GAAG,EACnEE,EAAcZ,EAAQU,EAAW,6BAA6B,EAAE,QAAQ,MAAO,GAAG,EAClFG,EAAab,EAAQU,EAAW,qBAAqB,EAAE,QAAQ,MAAO,GAAG,EACzEI,EAAUd,EAAQU,EAAW,iBAAiB,EAAE,QAAQ,MAAO,GAAG,EAElEK,EAAWd,GAAc,YAAY,GAAG,EACxCe,GAAiBD,EAAS,QAAQ,mBAAmB,EAAE,QAAQ,MAAO,GAAG,EACzEE,GAAuBF,EAAS,QAAQ,gCAAgC,EAAE,QAAQ,MAAO,GAAG,EAC5FG,GAAWH,EAAS,QAAQ,MAAM,EAAE,QAAQ,MAAO,GAAG,EAEtDI,GAAwB,CAC1B,KAAM,QACN,QAAS,MAET,UAAUC,EAAI,CACV,GAAIA,IAAOC,EAAsB,MAAO,KAAKA,CAAoB,GACjE,GAAID,IAAOE,EAAuB,MAAO,KAAKA,CAAqB,GACnE,GAAIF,IAAOG,EAAgB,MAAO,KAAKA,CAAc,GACrD,GAAIH,IAAOI,EAAa,MAAO,KAAKA,CAAW,GAC/C,GAAIJ,IAAOK,EAAiB,MAAO,KAAKA,CAAe,GACvD,GAAIL,IAAOM,EAAsB,MAAO,KAAKA,CAAoB,EACrE,EAEA,KAAKN,EAAI,CACL,GAAIA,IAAO,KAAKC,CAAoB,GAChC,OAAOM,EAAoB,CAAC,QAAApB,CAAO,CAAC,EACxC,GAAIa,IAAO,KAAKE,CAAqB,GACjC,OAAOM,EAAqB,CAAC,SAAAtB,EAAU,YAAAM,CAAW,CAAC,EACvD,GAAIQ,IAAO,KAAKG,CAAc,GAC1B,OAAOM,EAAe,CAAC,SAAAvB,EAAU,WAAAG,CAAU,CAAC,EAChD,GAAIW,IAAO,KAAKI,CAAW,GACvB,OAAOM,GAAY,CAAC,QAAAnB,EAAS,OAAAN,CAAM,CAAC,EACxC,GAAIe,IAAO,KAAKK,CAAe,GAC3B,OAAOM,GAAgB,EAC3B,GAAIX,IAAO,KAAKM,CAAoB,GAChC,OAAOM,GAAoB,CAAC,WAAAnB,EAAY,QAAAC,EAAS,eAAAE,GAAgB,qBAAAC,GAAsB,SAAAC,EAAQ,CAAC,CACxG,EAGA,UAAUe,EAAMb,EAAIc,EAAS,CACzB,GAAIA,GAAS,IAAK,OAElB,IAAMC,EAAmBnC,EAAQ,QAAQ,IAAI,EAAGM,CAAQ,EACxD,GAAI,CAACc,EAAG,WAAWe,CAAgB,EAAG,OAEtC,IAAMC,EAAMlC,GAAUkB,EAAIa,EAAM,CAAC,WAAY,QAAQ,CAAC,EAEhDI,EAA+D,CAAC,EAEtE,QAAWC,KAAQF,EAAI,QAAQ,KAAM,CACjC,GAAIE,EAAK,OAAS,0BAA4B,CAACA,EAAK,YAAa,SAEjE,IAAMC,EAAOD,EAAK,YAMlB,GAJIC,EAAK,OAAS,uBAAyBA,EAAK,IAAMC,GAAe,IAAID,EAAK,GAAG,IAAI,GACjFF,EAAa,KAAK,CAAC,MAAOC,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAMC,EAAK,GAAG,IAAI,CAAC,EAGxEA,EAAK,OAAS,sBAAuB,CACrC,IAAME,EAAO,IAAI,IACjB,QAAWC,KAAcH,EAAK,aACtBG,EAAW,GAAG,OAAS,cAAgBF,GAAe,IAAIE,EAAW,GAAG,IAAI,IACvED,EAAK,IAAIH,EAAK,KAAK,IACpBG,EAAK,IAAIH,EAAK,KAAK,EACnBD,EAAa,KAAK,CAAC,MAAOC,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAMI,EAAW,GAAG,IAAI,CAAC,GAI9F,CACJ,CAEA,GAAIL,EAAa,SAAW,EAAG,OAE/BA,EAAa,KAAK,CAACM,EAAGC,IAAMA,EAAE,MAAQD,EAAE,KAAK,EAE7C,IAAIE,EAASZ,EACb,OAAW,CAAC,MAAAa,EAAO,IAAAC,EAAK,KAAAC,CAAI,IAAKX,EAC7BQ,EAASA,EAAO,MAAM,EAAGC,CAAK,EAAI,gBAAgBE,CAAI,eAAiBH,EAAO,MAAME,CAAG,EAG3F,MAAO,CAAC,KAAMF,EAAQ,IAAK,IAAI,CACnC,EAEA,YAAa,CACT,IAAMI,EAAO,QAAQ,IAAI,EACnBC,EAAUC,EAAa9C,EAAQ4C,CAAI,EACzCG,EAAeC,EAAkBH,EAAS,GAAG7C,CAAM,MAAM,EAAG4C,CAAI,EAChEK,EAAsBjD,EAAQ4C,CAAI,CACtC,EAEA,gBAAgBM,EAAQ,CACpB,IAAMN,EAAO,QAAQ,IAAI,EAEzBK,EAAsBjD,EAAQ4C,CAAI,EAElC,IAAMO,EAAgB,IAAM,CACxB,IAAMN,EAAUC,EAAa9C,EAAQ4C,CAAI,EACzCG,EAAeC,EAAkBH,EAAS,GAAG7C,CAAM,MAAM,EAAG4C,CAAI,CACpE,EAEMQ,EAAcC,GAAiBA,EAAK,WAAW1D,EAAQiD,EAAM3C,CAAQ,CAAC,GAAK,CAACoD,EAAK,SAAS,YAAY,GAAK,CAACA,EAAK,SAAS,WAAW,EAErIC,EAAeD,GAAiB3D,GAASkD,EAAMS,CAAI,EAAE,QAAQ,MAAO,GAAG,EAEvEE,EAA2BxC,GAAe,CAC5C,IAAMyC,EAAMN,EAAO,YAAY,cAAc,KAAKnC,CAAE,EAAE,EAClDyC,GAAKN,EAAO,YAAY,iBAAiBM,CAAG,CACpD,EAEAN,EAAO,QAAQ,IAAIvD,EAAQiD,EAAM,iBAAiB,CAAC,EACnDM,EAAO,QAAQ,GAAG,SAAWG,GAAS,CAC9BA,IAAS1D,EAAQiD,EAAM,iBAAiB,IACxC,QAAQ,IAAI,uCAAuC,EACnD,QAAQ,KAAK,EAAE,EAEvB,CAAC,EAEDM,EAAO,QAAQ,GAAG,MAAQG,GAAS,CAC3BA,EAAK,WAAW1D,EAAQiD,EAAM3C,CAAQ,CAAC,GAAGsD,EAAwBrC,CAAc,EAChFkC,EAAWC,CAAI,GAAGI,EAAeH,EAAYD,CAAI,EAAGT,CAAI,EACxDS,EAAK,SAAS,GAAGrD,CAAM,MAAM,IAC7BuD,EAAwBpC,CAAW,EACnCgC,EAAc,EAEtB,CAAC,EACDD,EAAO,QAAQ,GAAG,SAAWG,GAAS,CAC9BA,EAAK,WAAW1D,EAAQiD,EAAM3C,CAAQ,CAAC,GAAGsD,EAAwBrC,CAAc,EAChFkC,EAAWC,CAAI,GAAGK,GAAgBJ,EAAYD,CAAI,EAAGT,CAAI,EACzDS,EAAK,SAAS,GAAGrD,CAAM,MAAM,IAC7BuD,EAAwBpC,CAAW,EACnCgC,EAAc,EAEtB,CAAC,EACDD,EAAO,QAAQ,GAAG,SAAWG,GAAS,CAC9BD,EAAWC,CAAI,GAAGI,EAAeH,EAAYD,CAAI,EAAGT,CAAI,EACxDS,EAAK,SAAS,GAAGrD,CAAM,MAAM,GAAK,CAACqD,EAAK,SAAS,eAAe,GAChEF,EAAc,CAEtB,CAAC,CACL,CACJ,EAEMQ,GAAmB,CACrB,QAAS,CAACpE,GAAM,EAAGuB,EAAa,EAChC,UAAWnB,EAAQ,QAAQ,IAAI,EAAGI,EAAO,WAAa,QAAQ,EAC9D,IAAK,CAAC,WAAY,CAAC,kBAAkB,CAAC,EACtC,GAAIA,EAAO,UAAY,CAAC,UAAWA,EAAO,SAAS,EAAI,CAAC,CAC5D,EAEA,OAAOT,GAAYqE,GAAM5D,EAAO,MAAQ,CAAC,CAAC,CAC9C,CAzLA,IAkBMM,EAEAW,EACAC,EACAC,EACAC,EACAC,EACAC,EAEAc,GA3BNyB,GAAAC,EAAA,kBAMAC,IACAC,IACAC,IACAC,KACAC,KACAC,KACAC,IACAC,KAEAC,KACAC,KAEMlE,EAAYZ,GAAQD,GAAc,YAAY,GAAG,CAAC,EAElDwB,EAAuB,6BACvBC,EAAwB,8BACxBC,EAAiB,uBACjBC,EAAc,oBACdC,EAAkB,wBAClBC,EAAuB,6BAEvBc,GAAiB,IAAI,IAAI,CAAC,SAAU,QAAS,uBAAwB,SAAS,CAAC,IC3B9E,SAASqC,GAAcC,EAAgC,CAC1D,GAAI,OAAOA,GAAU,SAAU,OAAOA,EACtC,IAAMC,EAAQD,EAAM,KAAK,EAAE,MAAM,iCAAiC,EAClE,GAAI,CAACC,EAAO,MAAM,IAAI,MAAM,8BAA8BD,CAAK,4DAA4D,EAC3H,IAAME,EAAI,WAAWD,EAAM,CAAC,CAAC,EAC7B,OAAQA,EAAM,CAAC,EAAG,CACd,IAAK,IAAM,OAAOC,EAAI,KACtB,IAAK,IAAM,OAAOA,EAAI,IACtB,IAAK,IAAM,OAAOA,EAAI,IAEtB,QAAW,OAAOA,CACtB,CACJ,CAZA,IAAAC,GAAAC,EAAA,oBCAA,IAAAC,GAAA,UAAQ,iBAAAC,OAAoB,UAC5B,OAAQ,WAAAC,OAAc,YACtB,OAAQ,SAAAC,MAAY,OAFpB,IAOMC,EACAC,EA4CAC,GApDNC,GAAAC,EAAA,uBAGAC,KACAC,KACAC,IAEMP,EAAS,MAAMQ,EAAW,QAAQ,IAAI,CAAC,EACvCP,EAAaQ,GAAMT,CAAM,EAE/B,MAAMD,EAAM,CACR,GAAGE,EACH,WAAY,GACZ,MAAO,CACH,OAAQ,cACR,SAAU,GACV,gBAAiB,CACb,MAAO,4BACX,CACJ,CACJ,CAAC,EAED,MAAMF,EAAM,CACR,GAAGE,EACH,WAAY,GACZ,MAAO,CACH,IAAK,GACL,OAAQ,cACR,cAAe,GACf,gBAAiB,CACb,MAAO,CACH,OAAQ,uBACR,IAAK,mBACT,CACJ,CACJ,CACJ,CAAC,EAED,MAAMF,EAAM,CACR,GAAGE,EACH,WAAY,GACZ,MAAO,CACH,IAAK,GACL,OAAQ,cACR,YAAa,GACb,cAAe,GACf,gBAAiB,CACb,MAAO,CAAE,MAAO,4BAA6B,CACjD,CACJ,CACJ,CAAC,EAEKC,GAAgB,CAClB,KAAMF,EAAO,MAAQ,IACrB,KAAMA,EAAO,MAAQ,GACrB,cAAeU,GAAcV,EAAO,eAAiB,GAAM,EAC3D,OAAQA,EAAO,QAAU,QAC7B,EAEAH,GACIC,GAAQ,QAAQ,IAAI,EAAG,wBAAwB,EAC/C,KAAK,UAAUI,GAAe,KAAM,CAAC,EACrC,OACJ,IC3DAS,IAJA,OAAQ,gBAAAC,GAAc,aAAAC,GAAW,iBAAAC,GAAe,UAAAC,OAAa,UAC7D,OAAQ,WAAAC,EAAS,QAAAC,MAAW,YAE5B,OAAS,iBAAAC,OAAqB,WAG9B,IAAMC,GAAa,MAAMC,EAAW,QAAQ,IAAI,CAAC,EAC7CD,GAAW,SAAW,UACtB,QAAQ,KAAK,yFAAyF,EAG1G,KAAM,mBAEN,IAAME,GAAI,KAAK,IAAI,EACbC,EAAe,MAAM,OAAOJ,GAAcF,EAAQ,QAAQ,IAAI,EAAG,uBAAuB,CAAC,EAAE,KAAO,MAAMK,EAAC,IAEzGE,GAAqB,KAAK,MAC5BX,GAAaI,EAAQ,QAAQ,IAAI,EAAG,iCAAiC,EAAG,OAAO,CACnF,EAEMQ,EAAiB,MAAMF,EAAa,gBAAgB,EAE1D,QAAQ,IAAI,sBAAsBE,EAAK,MAAM,eAAeA,EAAK,SAAW,EAAI,GAAK,GAAG,KAAK,EAE7F,QAAWC,KAAOD,EAAM,CACpB,IAAME,EAAU,mBAAmBD,CAAG,GAChC,CAAC,KAAAE,EAAM,WAAAC,CAAU,EAAI,MAAMN,EAAa,OAAOI,EAAS,IAAI,QAAQA,CAAO,EAAG,CAAC,SAAAH,EAAQ,CAAC,EAE9F,GAAIK,IAAe,IAAK,CACpB,QAAQ,KAAK,oBAAoBH,CAAG,kBAAaG,CAAU,EAAE,EAC7D,QACJ,CAEA,IAAMC,EAAUJ,IAAQ,IAClBR,EAAK,QAAQ,IAAI,EAAG,wBAAwB,EAC5CA,EAAK,QAAQ,IAAI,EAAG,cAAeQ,EAAK,YAAY,EAE1DZ,GAAUI,EAAKY,EAAS,IAAI,EAAG,CAAC,UAAW,EAAI,CAAC,EAChDf,GAAce,EAAS,kBAAkBF,CAAI,GAAI,OAAO,EAExD,IAAMG,EAAO,MAAMR,EAAa,UAAUI,EAAS,IAAI,QAAQA,CAAO,EAAG,CAAC,SAAAH,EAAQ,CAAC,EAC7EQ,EAAWN,IAAQ,IACnBR,EAAK,QAAQ,IAAI,EAAG,8BAA8B,EAClDA,EAAK,QAAQ,IAAI,EAAG,oBAAqB,GAAGQ,CAAG,OAAO,EAE5DZ,GAAUI,EAAKc,EAAU,IAAI,EAAG,CAAC,UAAW,EAAI,CAAC,EACjDjB,GAAciB,EAAU,KAAK,UAAUD,CAAI,EAAG,OAAO,EAErD,QAAQ,IAAI,YAAOL,CAAG,EAAE,CAC5B,CAEA,QAAQ,IAAI,8BAA8B,EAEtCN,GAAW,SAAW,WACtBJ,GAAOC,EAAQ,QAAQ,IAAI,EAAG,aAAa,EAAG,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAC9E,QAAQ,IAAI,yDAAyD",
6
- "names": ["build", "join", "unlinkSync", "writeFileSync", "pathToFileURL", "loadConfig", "cwd", "result", "tmpFile", "init_load_config", "__esmMin", "generateEntryClient", "cssUrls", "u", "init_entry_client", "__esmMin", "generateClientRoutes", "pagesDir", "matcherPath", "init_client_routes", "__esmMin", "generateRender", "pagesDir", "renderPath", "init_render", "__esmMin", "generateApi", "apiPath", "appDir", "init_api", "__esmMin", "generateContext", "init_context", "__esmMin", "stripComments", "content", "extractHttpMethods", "found", "match", "METHOD_EXPORT_RE", "init_extract_methods", "__esmMin", "routePattern", "rel", "init_patterns", "__esmMin", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "init_api_router", "__esmMin", "init_patterns", "filePathToIdentifier", "filePath", "apiDir", "buildRouteEntry", "methods", "keyToRoutePattern", "generateRoutesDts", "entries", "imports", "e", "importPath", "routeLines", "m", "init_routes_dts", "__esmMin", "init_api_router", "readFileSync", "readdirSync", "statSync", "join", "relative", "walkDir", "dir", "root", "entries", "name", "full", "scanApiFiles", "appDir", "projectRoot", "apiDir", "files", "f", "filePath", "content", "methods", "extractHttpMethods", "buildRouteEntry", "init_scan_api", "__esmMin", "init_extract_methods", "init_routes_dts", "mkdirSync", "readFileSync", "writeFileSync", "existsSync", "join", "writeRoutesDts", "content", "projectRoot", "devixDir", "outPath", "init_write_routes_dts", "__esmMin", "generateServerEntry", "routesPath", "envPath", "honoServerPath", "honoServerStaticPath", "honoPath", "init_server_entry", "__esmMin", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "rmSync", "statSync", "writeFileSync", "join", "relative", "parseSync", "walkPages", "dir", "root", "entries", "name", "full", "hasLoaderExport", "code", "filePath", "ast", "node", "decl", "d", "spec", "generatePageTypesDts", "importPath", "withLoader", "writePageTypes", "pageRelPath", "fullPath", "typesDir", "outPath", "pageAbsNoExt", "content", "deletePageTypes", "scanAndWritePageTypes", "appDir", "pagesDir", "files", "file", "init_page_types", "__esmMin", "mergeConfig", "react", "fileURLToPath", "dirname", "relative", "resolve", "createRequire", "parseSync", "devix", "config", "appDir", "pagesDir", "cssUrls", "u", "renderPath", "__dirname", "apiPath", "matcherPath", "routesPath", "envPath", "_require", "honoServerPath", "honoServerStaticPath", "honoPath", "virtualPlugin", "id", "VIRTUAL_ENTRY_CLIENT", "VIRTUAL_CLIENT_ROUTES", "VIRTUAL_RENDER", "VIRTUAL_API", "VIRTUAL_CONTEXT", "VIRTUAL_SERVER_ENTRY", "generateEntryClient", "generateClientRoutes", "generateRender", "generateApi", "generateContext", "generateServerEntry", "code", "options", "resolvedPagesDir", "ast", "replacements", "node", "decl", "SERVER_EXPORTS", "seen", "declarator", "a", "b", "result", "start", "end", "name", "root", "entries", "scanApiFiles", "writeRoutesDts", "generateRoutesDts", "scanAndWritePageTypes", "server", "regenerateDts", "isPageFile", "file", "pageRelPath", "invalidateVirtualModule", "mod", "writePageTypes", "deletePageTypes", "base", "init_vite", "__esmMin", "init_entry_client", "init_client_routes", "init_render", "init_api", "init_context", "init_scan_api", "init_routes_dts", "init_write_routes_dts", "init_server_entry", "init_page_types", "parseDuration", "value", "match", "n", "init_duration", "__esmMin", "build_exports", "writeFileSync", "resolve", "build", "config", "baseConfig", "runtimeConfig", "init_build", "__esmMin", "init_vite", "init_duration", "init_load_config", "loadConfig", "devix", "parseDuration", "init_load_config", "readFileSync", "mkdirSync", "writeFileSync", "rmSync", "resolve", "join", "pathToFileURL", "userConfig", "loadConfig", "t", "renderModule", "manifest", "urls", "url", "fullUrl", "html", "statusCode", "outPath", "data", "dataPath"]
4
+ "sourcesContent": ["import {build} from 'esbuild'\nimport type {DevixConfig} from \"../config\"\nimport {join} from \"node:path\"\nimport {unlinkSync, writeFileSync} from \"node:fs\";\nimport {pathToFileURL} from \"node:url\";\n\nexport async function loadConfig(cwd: string): Promise<DevixConfig> {\n const result = await build({\n entryPoints: [join(cwd, 'devix.config.ts')],\n bundle: true,\n write: false,\n format: 'esm',\n platform: 'node',\n packages: 'external',\n })\n\n const tmpFile = join(cwd, `.devix-config-${Date.now()}.mjs`)\n writeFileSync(tmpFile, result.outputFiles[0].text)\n\n try {\n const mod = await import(pathToFileURL(tmpFile).href)\n return mod.default\n } finally {\n unlinkSync(tmpFile)\n }\n}", "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 const guardData = window.__GUARD_DATA__ ?? null\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (window.__LOADER_ERROR__) {\n const {statusCode, message, code, data} = window.__LOADER_ERROR__\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 initialError: {statusCode, message, code, data},\n initialErrorPage: ErrorPage,\n })\n )\n } else 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 initialGuardData: guardData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n\n if (window.location.hash) { \n const id = window.location.hash.slice(1) \n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior \n requestAnimationFrame(() => { \n document.getElementById(id)?.scrollIntoView({ behavior: scrollBehavior }) \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 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", "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 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\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\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 return {routes, middlewares}\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", "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\\nexport {}\\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 JsonResponse<T, S extends number = number> = Response & { readonly __body: T; readonly __status: S }\ntype Is2xx<S extends number> = [number] extends [S] ? boolean : S extends 200 | 201 | 202 | 203 | 204 | 205 | 206 ? true : false\ntype UnwrapSuccessJson<T> = T extends JsonResponse<infer U, infer S> ? Is2xx<S> extends false ? never : U : never\ntype UnwrapErrorJson<T> = T extends JsonResponse<infer U, infer S> ? Is2xx<S> extends true ? never : U : never\ntype InferFnSuccess<T> = T extends (...args: any[]) => any ? UnwrapSuccessJson<Awaited<ReturnType<T>>> : never\ntype InferFnErrors<T> = T extends (...args: any[]) => any ? UnwrapErrorJson<Awaited<ReturnType<T>>> : never\ntype InferRoute<T> =\n T extends { readonly __return?: infer TReturn; readonly __body?: infer TBody }\n ? {\n __body: [TBody] extends [undefined] ? never : Exclude<TBody, undefined>\n __response: InferFnSuccess<() => TReturn>\n __errors: InferFnErrors<() => TReturn>\n }\n : InferFnSuccess<T>\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", "interface ServerEntryOptions {\n routesPath: string\n envPath: string\n honoServerPath: string\n honoServerStaticPath: string\n honoPath: string\n}\n\nexport function generateServerEntry({ routesPath, envPath, honoServerPath, honoServerStaticPath, honoPath }: ServerEntryOptions): string {\n return `\nimport { readFileSync } from 'node:fs'\n import { serve } from '${honoServerPath}'\n import { serveStatic } from '${honoServerStaticPath}'\n import { Hono } from '${honoPath}'\n import { resolve, join, dirname } from 'node:path'\n import { pathToFileURL } from 'node:url'\n import { registerApiRoutes, registerSsrRoute } from '${routesPath}' \n import { loadDotenv } from '${envPath}'\n \n loadDotenv('production')\n \n const __dir = dirname(process.argv[1])\n\n let renderModule, apiModule, manifest, runtimeConfig \n \n try { \n runtimeConfig = JSON.parse(readFileSync(resolve(__dir, '../devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') { \n renderModule = await import(pathToFileURL(resolve(__dir, 'render.js')).href)\n apiModule = await import(pathToFileURL(resolve(__dir, 'api.js')).href) \n } \n manifest = JSON.parse(readFileSync(resolve(__dir, '../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 \n const port = Number(process.env.PORT) || runtimeConfig.port || 3000 \n const host = typeof runtimeConfig.host === 'string'\n ? runtimeConfig.host \n : runtimeConfig.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0') \n \n const clientRoot = resolve(__dir, '../client') \n const app = new Hono()\n \n if (runtimeConfig.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\\\/_data/, '') || '/' \n const filePath = pathname === '/' \n ? join(clientRoot, '_data/index.json') \n : join(clientRoot, '_data', pathname + '.json') \n try { \n return c.json(JSON.parse(readFileSync(filePath, 'utf-8')))\n } catch { \n return c.json({ error: 'not found' }, 404)\n } \n }) \n }\n\n app.use('/*', serveStatic({ \n root: clientRoot,\n onFound: (_path, c) => { \n c.header('Cache-Control', _path.includes('/assets/') \n ? 'public, immutable, max-age=31536000'\n : 'no-cache') \n } \n })) \n \n if (runtimeConfig.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n } else {\n let userServerConfig\n try {\n const userConfigMod = await import(pathToFileURL(resolve(process.cwd(), 'devix.config.ts')).href).catch(() =>\n import(pathToFileURL(resolve(process.cwd(), 'devix.config.js')).href))\n userServerConfig = userConfigMod?.default?.server\n } catch {\n /* config sin server \u2014 sigue normal */\n }\n registerApiRoutes(app, { renderModule, apiModule, manifest, server: userServerConfig })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout, server: userServerConfig })\n } \n \n const server = serve({ fetch: app.fetch, port, hostname: host }, (info) => \n console.log(\\`http://\\${info.address}:\\${info.port}\\`))\n\nprocess.on('SIGTERM', () => server.close())\nprocess.on('SIGINT', () => server.close())\n`\n}", "import {existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync} from \"node:fs\";\nimport {join, relative} from \"node:path\";\nimport {parseSync} from \"oxc-parser\";\n\nfunction walkPages(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(...walkPages(full, root))\n } else if (/\\.(ts|tsx)$/.test(name) && name !== 'layout.tsx' && name !== 'error.tsx') {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport interface LoaderExportInfo {\n exists: boolean\n isAsync: boolean\n isReExport: boolean\n}\n\nexport function inspectLoaderExport(code: string, filePath: string): LoaderExportInfo {\n const ast = parseSync(filePath, code, {sourceType: 'module'})\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration') continue\n const decl = node.declaration\n if (decl?.type === 'FunctionDeclaration' && decl.id?.name === 'loader') {\n return {exists: true, isAsync: decl.async, isReExport: false}\n }\n if (decl?.type === 'VariableDeclaration') {\n for (const d of decl.declarations) {\n if (d.id.type === 'Identifier' && d.id.name === 'loader') {\n const init = d.init\n const isAsync =\n (init?.type === 'ArrowFunctionExpression' && init.async) ||\n (init?.type === 'FunctionExpression' && init.async)\n return {exists: true, isAsync, isReExport: false}\n }\n }\n }\n for (const spec of (node.specifiers ?? [])) {\n if (spec.exported.type === 'Identifier' && spec.exported.name === 'loader') {\n return {exists: true, isAsync: false, isReExport: true}\n }\n }\n }\n return {exists: false, isAsync: false, isReExport: false}\n}\n\nexport function hasLoaderExport(code: string, filePath: string): boolean {\n return inspectLoaderExport(code, filePath).exists\n}\n\nexport function generatePageTypesDts(importPath: string, withLoader: boolean): string {\n if (!withLoader) {\n return '// auto-generado por devix - no editar\\nexport type PageData = undefined\\nexport type PageParams = Record<string, string>\\n'\n }\n return `// auto-generado por devix \u2014 no editar\\nimport type { loader } from \"${importPath}\"\\nimport type { Redirect } from \"@devlusoft/devix\"\\n\\nexport type PageData = Exclude<\\n Awaited<ReturnType<NonNullable<typeof loader>>>,\\n Redirect | void | undefined\\n>\\nexport type PageParams = NonNullable<Parameters<typeof loader>[0]>[\"params\"]\\n`\n}\n\nexport interface WritePageTypesResult {\n warnings: string[]\n}\n\nexport function writePageTypes(pageRelPath: string, root: string): WritePageTypesResult {\n const fullPath = join(root, pageRelPath)\n const code = readFileSync(fullPath, 'utf-8')\n const loaderInfo = inspectLoaderExport(code, fullPath)\n const warnings: string[] = []\n\n if (loaderInfo.exists && !loaderInfo.isAsync && !loaderInfo.isReExport) {\n warnings.push(\n `[devix] ${pageRelPath}: 'loader' must be async. ` +\n `Use 'export async function loader' or 'export const loader = async (...) => ...'.`\n )\n }\n\n const typesDir = join(root, '.devix', 'pages', pageRelPath.replace(/\\.(tsx?|jsx?)$/, ''))\n const outPath = join(typesDir, '$types.d.ts')\n\n const pageAbsNoExt = fullPath.replace(/\\.(tsx?|jsx?)$/, '')\n const importPath = relative(typesDir, pageAbsNoExt).replace(/\\\\/g, '/')\n\n const content = generatePageTypesDts(importPath, loaderInfo.exists)\n\n if (existsSync(outPath) && readFileSync(outPath, 'utf-8') === content) return {warnings}\n\n mkdirSync(typesDir, {recursive: true})\n writeFileSync(outPath, content, 'utf-8')\n return {warnings}\n}\n\nexport function deletePageTypes(pageRelPath: string, root: string): void {\n const typesDir = join(root, '.devix', 'pages', pageRelPath.replace(/\\.(tsx?|jsx?)$/, ''))\n const outPath = join(typesDir, '$types.d.ts')\n if (existsSync(outPath)) rmSync(outPath)\n}\n\nexport function scanAndWritePageTypes(appDir: string, root: string): WritePageTypesResult {\n const pagesDir = join(root, appDir, 'pages')\n const warnings: string[] = []\n let files: string[]\n try {\n files = walkPages(pagesDir, root)\n } catch {\n return {warnings}\n }\n for (const file of files) {\n try {\n const result = writePageTypes(file, root)\n warnings.push(...result.warnings)\n } catch {\n /* ignorar archivos no procesables */\n }\n }\n return {warnings}\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, relative, resolve} from 'node:path'\nimport {createRequire} from 'node:module'\nimport {generateEntryClient} from './codegen/entry-client'\nimport {generateClientRoutes} from './codegen/client-routes'\nimport {generateRender} from './codegen/render'\nimport {generateApi} from './codegen/api'\nimport {generateContext} from \"./codegen/context\";\nimport {scanApiFiles} from \"./codegen/scan-api\";\nimport {generateRoutesDts} from \"./codegen/routes-dts\";\nimport {writeRoutesDts} from \"./codegen/write-routes-dts\";\nimport {parseSync} from 'oxc-parser'\nimport {generateServerEntry} from \"./codegen/server-entry\";\nimport {deletePageTypes, scanAndWritePageTypes, writePageTypes} from \"./codegen/page-types\";\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'\nconst VIRTUAL_SERVER_ENTRY = 'virtual:devix/server-entry'\n\nconst SERVER_EXPORTS = new Set(['loader', 'guard', 'generateStaticParams', 'headers'])\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 const routesPath = resolve(__dirname, '../server/routes.js').replace(/\\\\/g, '/')\n const envPath = resolve(__dirname, '../utils/env.js').replace(/\\\\/g, '/')\n\n const _require = createRequire(import.meta.url)\n const honoServerPath = _require.resolve('@hono/node-server').replace(/\\\\/g, '/')\n const honoServerStaticPath = _require.resolve('@hono/node-server/serve-static').replace(/\\\\/g, '/')\n const honoPath = _require.resolve('hono').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 if (id === VIRTUAL_SERVER_ENTRY) return `\\0${VIRTUAL_SERVER_ENTRY}`\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 if (id === `\\0${VIRTUAL_SERVER_ENTRY}`)\n return generateServerEntry({routesPath, envPath, honoServerPath, honoServerStaticPath, honoPath})\n },\n\n\n transform(code, id, options) {\n if (options?.ssr) return\n\n const resolvedPagesDir = resolve(process.cwd(), pagesDir)\n if (!id.startsWith(resolvedPagesDir)) return\n\n const ast = parseSync(id, code, {sourceType: 'module'})\n\n const replacements: { start: number; end: number; name: string }[] = []\n\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration' || !node.declaration) continue\n\n const decl = node.declaration\n\n if (decl.type === 'FunctionDeclaration' && decl.id && SERVER_EXPORTS.has(decl.id.name)) {\n replacements.push({start: node.start, end: node.end, name: decl.id.name})\n }\n\n if (decl.type === 'VariableDeclaration') {\n const seen = new Set<number>()\n for (const declarator of decl.declarations) {\n if (declarator.id.type === 'Identifier' && SERVER_EXPORTS.has(declarator.id.name)) {\n if (!seen.has(node.start)) {\n seen.add(node.start)\n replacements.push({start: node.start, end: node.end, name: declarator.id.name})\n }\n }\n }\n }\n }\n\n if (replacements.length === 0) return\n\n replacements.sort((a, b) => b.start - a.start)\n\n let result = code\n for (const {start, end, name} of replacements) {\n result = result.slice(0, start) + `export const ${name} = undefined` + result.slice(end)\n }\n\n return {code: result, map: null}\n },\n\n buildStart() {\n const root = process.cwd()\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n const {warnings} = scanAndWritePageTypes(appDir, root)\n for (const w of warnings) console.warn(w)\n },\n\n configureServer(server) {\n const root = process.cwd()\n\n const initial = scanAndWritePageTypes(appDir, root)\n for (const w of initial.warnings) console.warn(w)\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n const isPageFile = (file: string) => file.startsWith(resolve(root, pagesDir)) && !file.endsWith('layout.tsx') && !file.endsWith('error.tsx')\n\n const pageRelPath = (file: string) => relative(root, file).replace(/\\\\/g, '/')\n\n const invalidateVirtualModule = (id: string) => {\n const mod = server.moduleGraph.getModuleById(`\\0${id}`)\n if (mod) server.moduleGraph.invalidateModule(mod)\n }\n\n server.watcher.add(resolve(root, 'devix.config.ts'))\n server.watcher.on('change', (file) => {\n if (file === resolve(root, 'devix.config.ts')) {\n console.log('[devix] Config changed, restarting...')\n process.exit(75)\n }\n })\n\n const writePageTypesAndLog = (file: string) => {\n try {\n const {warnings} = writePageTypes(pageRelPath(file), root)\n for (const w of warnings) console.warn(w)\n } catch {\n /* ignorar archivos no procesables */\n }\n }\n\n server.watcher.on('add', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidateVirtualModule(VIRTUAL_RENDER)\n if (isPageFile(file)) writePageTypesAndLog(file)\n if (file.includes(`${appDir}/api`)) {\n invalidateVirtualModule(VIRTUAL_API)\n regenerateDts()\n }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidateVirtualModule(VIRTUAL_RENDER)\n if (isPageFile(file)) deletePageTypes(pageRelPath(file), root)\n if (file.includes(`${appDir}/api`)) {\n invalidateVirtualModule(VIRTUAL_API)\n regenerateDts()\n }\n })\n server.watcher.on('change', (file) => {\n if (isPageFile(file)) writePageTypesAndLog(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 publicDir: resolve(process.cwd(), config.publicDir ?? 'public'),\n ssr: {noExternal: ['@devlusoft/devix']},\n ...(config.envPrefix ? {envPrefix: config.envPrefix} : {}),\n }\n\n return mergeConfig(base, config.vite ?? {})\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 {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\nimport {loadConfig} from \"../utils/load-config\";\n\nconst config = await loadConfig(process.cwd())\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 copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n emptyOutDir: false,\n copyPublicDir: false,\n rolldownOptions: {\n input: { index: 'virtual:devix/server-entry' },\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, rmSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport { pathToFileURL } from \"node:url\"\nimport {loadConfig} from \"../utils/load-config\";\n\nconst userConfig = await loadConfig(process.cwd())\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(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href + `?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\n const data = await renderModule.runLoader(fullUrl, new Request(fullUrl), {manifest})\n const dataPath = url === '/'\n ? join(process.cwd(), 'dist/client/_data/index.json')\n : join(process.cwd(), 'dist/client/_data', `${url}.json`)\n \n mkdirSync(join(dataPath, '..'), {recursive: true})\n writeFileSync(dataPath, JSON.stringify(data), 'utf-8')\n\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nif (userConfig.output === 'static') {\n rmSync(resolve(process.cwd(), 'dist/server'), { recursive: true, force: true })\n console.log('[devix] Removed dist/server (not needed in static mode)')\n}\n\nexport {}\n"],
5
+ "mappings": "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",
6
+ "names": ["build", "join", "unlinkSync", "writeFileSync", "pathToFileURL", "loadConfig", "cwd", "result", "tmpFile", "init_load_config", "__esmMin", "generateEntryClient", "cssUrls", "u", "init_entry_client", "__esmMin", "generateClientRoutes", "pagesDir", "matcherPath", "init_client_routes", "__esmMin", "generateRender", "pagesDir", "renderPath", "init_render", "__esmMin", "generateApi", "apiPath", "appDir", "init_api", "__esmMin", "generateContext", "init_context", "__esmMin", "stripComments", "content", "extractHttpMethods", "found", "match", "METHOD_EXPORT_RE", "init_extract_methods", "__esmMin", "routePattern", "rel", "init_patterns", "__esmMin", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "init_api_router", "__esmMin", "init_patterns", "filePathToIdentifier", "filePath", "apiDir", "buildRouteEntry", "methods", "keyToRoutePattern", "generateRoutesDts", "entries", "imports", "e", "importPath", "routeLines", "m", "init_routes_dts", "__esmMin", "init_api_router", "readFileSync", "readdirSync", "statSync", "join", "relative", "walkDir", "dir", "root", "entries", "name", "full", "scanApiFiles", "appDir", "projectRoot", "apiDir", "files", "f", "filePath", "content", "methods", "extractHttpMethods", "buildRouteEntry", "init_scan_api", "__esmMin", "init_extract_methods", "init_routes_dts", "mkdirSync", "readFileSync", "writeFileSync", "existsSync", "join", "writeRoutesDts", "content", "projectRoot", "devixDir", "outPath", "init_write_routes_dts", "__esmMin", "generateServerEntry", "routesPath", "envPath", "honoServerPath", "honoServerStaticPath", "honoPath", "init_server_entry", "__esmMin", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "rmSync", "statSync", "writeFileSync", "join", "relative", "parseSync", "walkPages", "dir", "root", "entries", "name", "full", "inspectLoaderExport", "code", "filePath", "ast", "node", "decl", "d", "init", "spec", "generatePageTypesDts", "importPath", "withLoader", "writePageTypes", "pageRelPath", "fullPath", "loaderInfo", "warnings", "typesDir", "outPath", "pageAbsNoExt", "content", "deletePageTypes", "scanAndWritePageTypes", "appDir", "pagesDir", "files", "file", "result", "init_page_types", "__esmMin", "mergeConfig", "react", "fileURLToPath", "dirname", "relative", "resolve", "createRequire", "parseSync", "devix", "config", "appDir", "pagesDir", "cssUrls", "u", "renderPath", "__dirname", "apiPath", "matcherPath", "routesPath", "envPath", "_require", "honoServerPath", "honoServerStaticPath", "honoPath", "virtualPlugin", "id", "VIRTUAL_ENTRY_CLIENT", "VIRTUAL_CLIENT_ROUTES", "VIRTUAL_RENDER", "VIRTUAL_API", "VIRTUAL_CONTEXT", "VIRTUAL_SERVER_ENTRY", "generateEntryClient", "generateClientRoutes", "generateRender", "generateApi", "generateContext", "generateServerEntry", "code", "options", "resolvedPagesDir", "ast", "replacements", "node", "decl", "SERVER_EXPORTS", "seen", "declarator", "a", "b", "result", "start", "end", "name", "root", "entries", "scanApiFiles", "writeRoutesDts", "generateRoutesDts", "warnings", "scanAndWritePageTypes", "w", "server", "initial", "regenerateDts", "isPageFile", "file", "pageRelPath", "invalidateVirtualModule", "mod", "writePageTypesAndLog", "writePageTypes", "deletePageTypes", "base", "init_vite", "__esmMin", "init_entry_client", "init_client_routes", "init_render", "init_api", "init_context", "init_scan_api", "init_routes_dts", "init_write_routes_dts", "init_server_entry", "init_page_types", "parseDuration", "value", "match", "n", "init_duration", "__esmMin", "build_exports", "writeFileSync", "resolve", "build", "config", "baseConfig", "runtimeConfig", "init_build", "__esmMin", "init_vite", "init_duration", "init_load_config", "loadConfig", "devix", "parseDuration", "init_load_config", "readFileSync", "mkdirSync", "writeFileSync", "rmSync", "resolve", "join", "pathToFileURL", "userConfig", "loadConfig", "t", "renderModule", "manifest", "urls", "url", "fullUrl", "html", "statusCode", "outPath", "data", "dataPath"]
7
7
  }