@devlusoft/devix 0.4.1-beta.5 → 0.4.1-beta.7

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.
@@ -1,4 +1,4 @@
1
- var s=(t,e)=>()=>(t&&(e=t(t=0)),e);function k({cssUrls:t}){return`
1
+ var s=(t,e)=>()=>(t&&(e=t(t=0)),e);function j({cssUrls:t}){return`
2
2
  ${t.map(r=>`import '${r}'`).join(`
3
3
  `)}
4
4
  import "@vitejs/plugin-react/preamble"
@@ -62,7 +62,7 @@ if (!window.__DEVIX__) {
62
62
  )
63
63
  }
64
64
  }
65
- `}var H=s(()=>{"use strict"});function j({pagesDir:t,matcherPath:e}){return`
65
+ `}var q=s(()=>{"use strict"});function N({pagesDir:t,matcherPath:e}){return`
66
66
  import React from 'react'
67
67
  import { createMatcher } from '${e}'
68
68
  const pageFiles = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
@@ -90,7 +90,7 @@ export function getDefaultErrorPage() {
90
90
  )
91
91
  }
92
92
  }
93
- `}var q=s(()=>{"use strict"});function N({pagesDir:t,renderPath:e}){return`
93
+ `}var V=s(()=>{"use strict"});function W({pagesDir:t,renderPath:e}){return`
94
94
  import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${e}'
95
95
 
96
96
  const _pages = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
@@ -113,7 +113,7 @@ export function runLoader(url, request, options) {
113
113
  export function getStaticRoutes() {
114
114
  return _getStaticRoutes(_glob)
115
115
  }
116
- `}var V=s(()=>{"use strict"});function W({apiPath:t,appDir:e}){return`
116
+ `}var B=s(()=>{"use strict"});function J({apiPath:t,appDir:e}){return`
117
117
  import { handleApiRequest as _handleApiRequest } from '${t}'
118
118
 
119
119
  const _routes = import.meta.glob(['/${e}/api/**/*.ts', '!**/middleware.ts'])
@@ -128,14 +128,14 @@ const _glob = {
128
128
  export function handleApiRequest(url, request) {
129
129
  return _handleApiRequest(url, request, _glob)
130
130
  }
131
- `}var B=s(()=>{"use strict"});function v(t){return t.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var w=s(()=>{"use strict"});function E(){ht=null}var ht,J=s(()=>{"use strict";w();ht=null});function X(t,e){let r=t.slice(e.length+1).replace(/\\/g,"/"),i=v(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}function P(){xt=null}var xt,_=s(()=>{"use strict";w();xt=null});function G(){return`
131
+ `}var X=s(()=>{"use strict"});function w(t){return t.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var E=s(()=>{"use strict"});function P(){wt=null}var wt,G=s(()=>{"use strict";E();wt=null});function Y(t,e){let r=t.slice(e.length+1).replace(/\\/g,"/"),i=w(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}function _(){Et=null}var Et,T=s(()=>{"use strict";E();Et=null});function z(){return`
132
132
  export {RouterContext} from '@devlusoft/devix/runtime/context'
133
- `}var Y=s(()=>{"use strict"});function Rt(t){return t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function z(t){let e=new Set;for(let r of Rt(t).matchAll(yt))e.add(r[1]);return[...e]}var yt,Z=s(()=>{"use strict";yt=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function vt(t,e){return"_api_"+t.slice(`${e}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function K(t,e,r){return{filePath:t,urlPattern:X(t,e),identifier:vt(t,e),methods:r}}function $(t,e){if(t.length===0)return`// auto-generado por devix \u2014 no editar
133
+ `}var Z=s(()=>{"use strict"});function _t(t){return t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function K(t){let e=new Set;for(let r of _t(t).matchAll(Pt))e.add(r[1]);return[...e]}var Pt,Q=s(()=>{"use strict";Pt=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function Tt(t,e){return"_api_"+t.slice(`${e}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function tt(t,e,r){return{filePath:t,urlPattern:Y(t,e),identifier:Tt(t,e),methods:r}}function $(t,e){if(t.length===0)return`// auto-generado por devix \u2014 no editar
134
134
  declare module '@devlusoft/devix' {
135
135
  interface ApiRoutes {}
136
136
  }
137
- `;let r=t.map(o=>{let d="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${d}'`}).join(`
138
- `),i=t.flatMap(o=>o.methods.map(d=>` '${d} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${d}']>`)).join(`
137
+ `;let r=t.map(o=>{let u="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${u}'`}).join(`
138
+ `),i=t.flatMap(o=>o.methods.map(u=>` '${u} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${u}']>`)).join(`
139
139
  `);return`// auto-generado por devix \u2014 no editar
140
140
  ${r}
141
141
 
@@ -157,5 +157,5 @@ declare module '@devlusoft/devix' {
157
157
  ${i}
158
158
  }
159
159
  }
160
- `}var T=s(()=>{"use strict";_()});import{readFileSync as wt,readdirSync as Et,statSync as Pt}from"node:fs";import{join as D,relative as _t}from"node:path";function Q(t,e){let r=[];for(let i of Et(t)){let o=D(t,i);Pt(o).isDirectory()?r.push(...Q(o,e)):/\.(ts|tsx)$/.test(i)&&r.push(_t(e,o).replace(/\\/g,"/"))}return r}function A(t,e){let r=D(e,t,"api"),i;try{i=Q(r,e)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let d=wt(D(e,o),"utf-8"),h=z(d);return h.length===0?[]:[K(o,`${t}/api`,h)]}catch{return[]}})}var tt=s(()=>{"use strict";Z();T()});import{mkdirSync as $t,readFileSync as Tt,writeFileSync as Dt,existsSync as At}from"node:fs";import{join as et}from"node:path";function C(t,e){let r=et(e,".devix"),i=et(r,"routes.d.ts");return $t(r,{recursive:!0}),At(i)&&Tt(i,"utf-8")===t?!1:(Dt(i,t,"utf-8"),!0)}var rt=s(()=>{"use strict"});import{mergeConfig as Ct}from"vite";import St from"@vitejs/plugin-react";import{fileURLToPath as bt}from"node:url";import{dirname as It,resolve as p}from"node:path";import{parseSync as Mt}from"oxc-parser";function ot(t){let e=t.appDir??"app",r=`${e}/pages`,i=(t.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=p(S,"../server/render.js").replace(/\\/g,"/"),d=p(S,"../server/api.js").replace(/\\/g,"/"),h=p(S,"../runtime/client-router.js").replace(/\\/g,"/"),mt={name:"devix",enforce:"pre",resolveId(n){if(n===b)return`\0${b}`;if(n===I)return`\0${I}`;if(n===M)return`\0${M}`;if(n===O)return`\0${O}`;if(n===L)return`\0${L}`},load(n){if(n===`\0${b}`)return k({cssUrls:i});if(n===`\0${I}`)return j({pagesDir:r,matcherPath:h});if(n===`\0${M}`)return N({pagesDir:r,renderPath:o});if(n===`\0${O}`)return W({apiPath:d,appDir:e});if(n===`\0${L}`)return G()},transform(n,l,m){if(m?.ssr)return;let a=p(process.cwd(),r);if(!l.startsWith(a))return;let gt=Mt(l,n,{sourceType:"module"}),f=[];for(let c of gt.program.body){if(c.type!=="ExportNamedDeclaration"||!c.declaration)continue;let u=c.declaration;if(u.type==="FunctionDeclaration"&&u.id&&nt.has(u.id.name)&&f.push({start:c.start,end:c.end,name:u.id.name}),u.type==="VariableDeclaration"){let y=new Set;for(let R of u.declarations)R.id.type==="Identifier"&&nt.has(R.id.name)&&(y.has(c.start)||(y.add(c.start),f.push({start:c.start,end:c.end,name:R.id.name})))}}if(f.length===0)return;f.sort((c,u)=>u.start-c.start);let x=n;for(let{start:c,end:u,name:y}of f)x=x.slice(0,c)+`export const ${y} = undefined`+x.slice(u);return{code:x,map:null}},buildStart(){let n=process.cwd(),l=A(e,n);C($(l,`${e}/api`),n)},configureServer(n){let l=process.cwd(),m=()=>{let a=A(e,l);C($(a,`${e}/api`),l)};n.watcher.add(p(l,"devix.config.ts")),n.watcher.on("change",a=>{a===p(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",a=>{a.startsWith(p(l,r))&&E(),a.includes(`${e}/api`)&&(P(),m())}),n.watcher.on("unlink",a=>{a.startsWith(p(l,r))&&E(),a.includes(`${e}/api`)&&(P(),m())}),n.watcher.on("change",a=>{a.includes(`${e}/api`)&&!a.endsWith("middleware.ts")&&m()})}},ft={plugins:[St(),mt],publicDir:p(process.cwd(),t.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...t.envPrefix?{envPrefix:t.envPrefix}:{}};return Ct(ft,t.vite??{})}var S,b,I,M,O,L,nt,it=s(()=>{"use strict";H();q();V();B();J();_();Y();tt();T();rt();S=It(bt(import.meta.url)),b="virtual:devix/entry-client",I="virtual:devix/client-routes",M="virtual:devix/render",O="virtual:devix/api",L="virtual:devix/context",nt=new Set(["loader","guard","generateStaticParams","headers"])});function st(t){if(typeof t=="number")return t;let e=t.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!e)throw new Error(`[devix] Invalid duration: "${t}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(e[1]);switch(e[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var at=s(()=>{"use strict"});var Ut={};import{writeFileSync as Ot}from"node:fs";import{resolve as Lt}from"node:path";import{build as ct}from"vite";var g,lt,Ft,ut=s(async()=>{"use strict";it();at();g=(await import(`${process.cwd()}/devix.config.ts`)).default,lt=ot(g);await ct({...lt,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await ct({...lt,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});Ft={port:g.port??3e3,host:g.host??!1,loaderTimeout:st(g.loaderTimeout??1e4),output:g.output??"server"};Ot(Lt(process.cwd(),"dist/devix.config.json"),JSON.stringify(Ft,null,2),"utf-8")});import{readFileSync as kt,mkdirSync as Ht,writeFileSync as jt}from"node:fs";import{resolve as pt,join as F}from"node:path";var qt=(await import(`${process.cwd()}/devix.config.ts`)).default;qt.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await ut().then(()=>Ut);var Nt=Date.now(),dt=await import(pt(process.cwd(),"dist/server/render.js")+`?t=${Nt}`),Vt=JSON.parse(kt(pt(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),U=await dt.getStaticRoutes();console.log(`[devix] Generating ${U.length} static page${U.length===1?"":"s"}...`);for(let t of U){let e=`http://localhost${t}`,{html:r,statusCode:i}=await dt.render(e,new Request(e),{manifest:Vt});if(i!==200){console.warn(`[devix] Skipping ${t} \u2014 status ${i}`);continue}let o=t==="/"?F(process.cwd(),"dist/client/index.html"):F(process.cwd(),"dist/client",t,"index.html");Ht(F(o,".."),{recursive:!0}),jt(o,`<!DOCTYPE html>${r}`,"utf-8"),console.log(` \u2713 ${t}`)}console.log("[devix] Generation complete.");
160
+ `}var D=s(()=>{"use strict";T()});import{readFileSync as $t,readdirSync as Dt,statSync as At}from"node:fs";import{join as A,relative as Ct}from"node:path";function et(t,e){let r=[];for(let i of Dt(t)){let o=A(t,i);At(o).isDirectory()?r.push(...et(o,e)):/\.(ts|tsx)$/.test(i)&&r.push(Ct(e,o).replace(/\\/g,"/"))}return r}function C(t,e){let r=A(e,t,"api"),i;try{i=et(r,e)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let u=$t(A(e,o),"utf-8"),m=K(u);return m.length===0?[]:[tt(o,`${t}/api`,m)]}catch{return[]}})}var rt=s(()=>{"use strict";Q();D()});import{mkdirSync as St,readFileSync as bt,writeFileSync as Ot,existsSync as It}from"node:fs";import{join as nt}from"node:path";function S(t,e){let r=nt(e,".devix"),i=nt(r,"routes.d.ts");return St(r,{recursive:!0}),It(i)&&bt(i,"utf-8")===t?!1:(Ot(i,t,"utf-8"),!0)}var ot=s(()=>{"use strict"});import{mergeConfig as Lt}from"vite";import Mt from"@vitejs/plugin-react";import{fileURLToPath as Ft}from"node:url";import{dirname as Ut,resolve as d}from"node:path";import{parseSync as kt}from"oxc-parser";function st(t){let e=t.appDir??"app",r=`${e}/pages`,i=(t.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=d(b,"../server/render.js").replace(/\\/g,"/"),u=d(b,"../server/api.js").replace(/\\/g,"/"),m=d(b,"../runtime/client-router.js").replace(/\\/g,"/"),yt={name:"devix",enforce:"pre",resolveId(n){if(n===O)return`\0${O}`;if(n===I)return`\0${I}`;if(n===L)return`\0${L}`;if(n===M)return`\0${M}`;if(n===F)return`\0${F}`},load(n){if(n===`\0${O}`)return j({cssUrls:i});if(n===`\0${I}`)return N({pagesDir:r,matcherPath:m});if(n===`\0${L}`)return W({pagesDir:r,renderPath:o});if(n===`\0${M}`)return J({apiPath:u,appDir:e});if(n===`\0${F}`)return z()},transform(n,l,g){if(g?.ssr)return;let a=d(process.cwd(),r);if(!l.startsWith(a))return;let vt=kt(l,n,{sourceType:"module"}),h=[];for(let c of vt.program.body){if(c.type!=="ExportNamedDeclaration"||!c.declaration)continue;let p=c.declaration;if(p.type==="FunctionDeclaration"&&p.id&&it.has(p.id.name)&&h.push({start:c.start,end:c.end,name:p.id.name}),p.type==="VariableDeclaration"){let R=new Set;for(let v of p.declarations)v.id.type==="Identifier"&&it.has(v.id.name)&&(R.has(c.start)||(R.add(c.start),h.push({start:c.start,end:c.end,name:v.id.name})))}}if(h.length===0)return;h.sort((c,p)=>p.start-c.start);let y=n;for(let{start:c,end:p,name:R}of h)y=y.slice(0,c)+`export const ${R} = undefined`+y.slice(p);return{code:y,map:null}},buildStart(){let n=process.cwd(),l=C(e,n);S($(l,`${e}/api`),n)},configureServer(n){let l=process.cwd(),g=()=>{let a=C(e,l);S($(a,`${e}/api`),l)};n.watcher.add(d(l,"devix.config.ts")),n.watcher.on("change",a=>{a===d(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",a=>{a.startsWith(d(l,r))&&P(),a.includes(`${e}/api`)&&(_(),g())}),n.watcher.on("unlink",a=>{a.startsWith(d(l,r))&&P(),a.includes(`${e}/api`)&&(_(),g())}),n.watcher.on("change",a=>{a.includes(`${e}/api`)&&!a.endsWith("middleware.ts")&&g()})}},Rt={plugins:[Mt(),yt],publicDir:d(process.cwd(),t.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...t.envPrefix?{envPrefix:t.envPrefix}:{}};return Lt(Rt,t.vite??{})}var b,O,I,L,M,F,it,at=s(()=>{"use strict";q();V();B();X();G();T();Z();rt();D();ot();b=Ut(Ft(import.meta.url)),O="virtual:devix/entry-client",I="virtual:devix/client-routes",L="virtual:devix/render",M="virtual:devix/api",F="virtual:devix/context",it=new Set(["loader","guard","generateStaticParams","headers"])});function ct(t){if(typeof t=="number")return t;let e=t.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!e)throw new Error(`[devix] Invalid duration: "${t}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(e[1]);switch(e[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var lt=s(()=>{"use strict"});var Wt={};import{writeFileSync as Ht}from"node:fs";import{resolve as jt}from"node:path";import{build as ut}from"vite";import{pathToFileURL as qt}from"node:url";import{join as Nt}from"node:path";var x,pt,Vt,dt=s(async()=>{"use strict";at();lt();x=(await import(qt(Nt(process.cwd(),"devix.config.ts")).href)).default,pt=st(x);await ut({...pt,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await ut({...pt,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});Vt={port:x.port??3e3,host:x.host??!1,loaderTimeout:ct(x.loaderTimeout??1e4),output:x.output??"server"};Ht(jt(process.cwd(),"dist/devix.config.json"),JSON.stringify(Vt,null,2),"utf-8")});import{readFileSync as Bt,mkdirSync as mt,writeFileSync as ft,rmSync as Jt}from"node:fs";import{resolve as H,join as f}from"node:path";import{pathToFileURL as ht}from"node:url";var xt=(await import(ht(f(process.cwd(),"devix.config.ts")).href)).default;xt.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await dt().then(()=>Wt);var Xt=Date.now(),U=await import(ht(H(process.cwd(),"dist/server/render.js")).href+`?t=${Xt}`),gt=JSON.parse(Bt(H(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),k=await U.getStaticRoutes();console.log(`[devix] Generating ${k.length} static page${k.length===1?"":"s"}...`);for(let t of k){let e=`http://localhost${t}`,{html:r,statusCode:i}=await U.render(e,new Request(e),{manifest:gt});if(i!==200){console.warn(`[devix] Skipping ${t} \u2014 status ${i}`);continue}let o=t==="/"?f(process.cwd(),"dist/client/index.html"):f(process.cwd(),"dist/client",t,"index.html");mt(f(o,".."),{recursive:!0}),ft(o,`<!DOCTYPE html>${r}`,"utf-8");let u=await U.runLoader(e,new Request(e),{manifest:gt}),m=t==="/"?f(process.cwd(),"dist/client/_data/index.json"):f(process.cwd(),"dist/client/_data",`${t}.json`);mt(f(m,".."),{recursive:!0}),ft(m,JSON.stringify(u),"utf-8"),console.log(` \u2713 ${t}`)}console.log("[devix] Generation complete.");xt.output==="static"&&(Jt(H(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"));
161
161
  //# sourceMappingURL=generate.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/vite/codegen/entry-client.ts", "../../src/vite/codegen/client-routes.ts", "../../src/vite/codegen/render.ts", "../../src/vite/codegen/api.ts", "../../src/utils/patterns.ts", "../../src/server/pages-router.ts", "../../src/server/api-router.ts", "../../src/vite/codegen/context.ts", "../../src/vite/codegen/extract-methods.ts", "../../src/vite/codegen/routes-dts.ts", "../../src/vite/codegen/scan-api.ts", "../../src/vite/codegen/write-routes-dts.ts", "../../src/vite/index.ts", "../../src/utils/duration.ts", "../../src/cli/build.ts", "../../src/cli/generate.ts"],
4
- "sourcesContent": ["interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({ cssUrls }: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n\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 routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nconst METHOD_EXPORT_RE = /export\\s+(?:const|async\\s+function|function)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/g\n\nfunction stripComments(content: string): string {\n return content\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n}\n\nexport function extractHttpMethods(content: string): HttpMethod[] {\n const found = new Set<HttpMethod>()\n for (const match of stripComments(content).matchAll(METHOD_EXPORT_RE)) {\n found.add(match[1] as HttpMethod)\n }\n return [...found]\n}\n", "import { keyToRoutePattern } from '../../server/api-router'\nimport type { HttpMethod } from './extract-methods'\n\nexport interface RouteEntry {\n filePath: string\n urlPattern: string\n identifier: string\n methods: HttpMethod[]\n}\n\nexport function filePathToIdentifier(filePath: string, apiDir: string): string {\n return '_api_' + filePath\n .slice(`${apiDir}/`.length)\n .replace(/\\.(ts|tsx)$/, '')\n .replace(/[^a-zA-Z0-9]/g, '_')\n}\n\nexport function buildRouteEntry(filePath: string, apiDir: string, methods: HttpMethod[]): RouteEntry {\n return {\n filePath,\n urlPattern: keyToRoutePattern(filePath, apiDir),\n identifier: filePathToIdentifier(filePath, apiDir),\n methods,\n }\n}\n\nexport function generateRoutesDts(entries: RouteEntry[], apiDir: string): string {\n if (entries.length === 0) {\n return `// auto-generado por devix \u2014 no editar\\ndeclare module '@devlusoft/devix' {\\n interface ApiRoutes {}\\n}\\n`\n }\n\n const imports = entries\n .map(e => {\n const importPath = '../' + e.filePath.replace(/\\.(ts|tsx)$/, '')\n return `import type * as ${e.identifier} from '${importPath}'`\n })\n .join('\\n')\n\n const routeLines = entries.flatMap(e =>\n e.methods.map(m =>\n ` '${m} ${e.urlPattern}': InferRoute<(typeof ${e.identifier})['${m}']>`\n )\n ).join('\\n')\n\n return `// auto-generado por devix \u2014 no editar\n${imports}\n\ntype JsonResponse<T> = Response & { readonly __body: T }\ntype UnwrapJson<T> = T extends JsonResponse<infer U> ? U : never\ntype InferFnReturn<T> = T extends (...args: any[]) => any\n ? UnwrapJson<Awaited<ReturnType<T>>> | Exclude<Awaited<ReturnType<T>>, JsonResponse<any> | null | void | undefined>\n : 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: InferFnReturn<() => TReturn>\n }\n : InferFnReturn<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", "import { UserConfig, Plugin, mergeConfig } from 'vite'\nimport type { DevixConfig } from '../config'\nimport react from '@vitejs/plugin-react'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { generateEntryClient } from './codegen/entry-client'\nimport { generateClientRoutes } from './codegen/client-routes'\nimport { generateRender } from './codegen/render'\nimport { generateApi } from './codegen/api'\nimport { invalidatePagesCache } from \"../server/pages-router\";\nimport { invalidateApiCache } from \"../server/api-router\";\nimport { generateContext } from \"./codegen/context\";\nimport { scanApiFiles } from \"./codegen/scan-api\";\nimport { generateRoutesDts } from \"./codegen/routes-dts\";\nimport { writeRoutesDts } from \"./codegen/write-routes-dts\";\nimport { parseSync } from 'oxc-parser'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\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\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({ cssUrls })\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({ pagesDir, matcherPath })\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({ pagesDir, renderPath })\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({ apiPath, appDir })\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n\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 },\n\n configureServer(server) {\n const root = process.cwd()\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n server.watcher.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))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('change', (file) => {\n if (file.includes(`${appDir}/api`) && !file.endsWith('middleware.ts')) {\n regenerateDts()\n }\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n 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 type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\n\nconst config: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport type {DevixConfig} from '../config'\n\nconst userConfig: DevixConfig = (await import(`${process.cwd()}/devix.config.ts`)).default\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(resolve(process.cwd(), 'dist/server/render.js') + `?t=${t}`)\n\nconst manifest: Manifest = JSON.parse(\n readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8')\n)\n\nconst urls: string[] = await renderModule.getStaticRoutes()\n\nconsole.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? '' : 's'}...`)\n\nfor (const url of urls) {\n const fullUrl = `http://localhost${url}`\n const {html, statusCode} = await renderModule.render(fullUrl, new Request(fullUrl), {manifest})\n\n if (statusCode !== 200) {\n console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`)\n continue\n }\n\n const outPath = url === '/'\n ? join(process.cwd(), 'dist/client/index.html')\n : join(process.cwd(), 'dist/client', url, 'index.html')\n\n mkdirSync(join(outPath, '..'), {recursive: true})\n writeFileSync(outPath, `<!DOCTYPE html>${html}`, 'utf-8')\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nexport {}\n"],
5
- "mappings": "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",
6
- "names": ["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", "routePattern", "rel", "init_patterns", "__esmMin", "invalidatePagesCache", "cache", "init_pages_router", "__esmMin", "init_patterns", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "invalidateApiCache", "cache", "init_api_router", "__esmMin", "init_patterns", "generateContext", "init_context", "__esmMin", "stripComments", "content", "extractHttpMethods", "found", "match", "METHOD_EXPORT_RE", "init_extract_methods", "__esmMin", "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", "mergeConfig", "react", "fileURLToPath", "dirname", "resolve", "parseSync", "devix", "config", "appDir", "pagesDir", "cssUrls", "u", "renderPath", "__dirname", "apiPath", "matcherPath", "virtualPlugin", "id", "VIRTUAL_ENTRY_CLIENT", "VIRTUAL_CLIENT_ROUTES", "VIRTUAL_RENDER", "VIRTUAL_API", "VIRTUAL_CONTEXT", "generateEntryClient", "generateClientRoutes", "generateRender", "generateApi", "generateContext", "code", "options", "resolvedPagesDir", "ast", "replacements", "node", "decl", "SERVER_EXPORTS", "seen", "declarator", "a", "b", "result", "start", "end", "name", "root", "entries", "scanApiFiles", "writeRoutesDts", "generateRoutesDts", "server", "regenerateDts", "file", "invalidatePagesCache", "invalidateApiCache", "base", "init_vite", "__esmMin", "init_entry_client", "init_client_routes", "init_render", "init_api", "init_pages_router", "init_api_router", "init_context", "init_scan_api", "init_routes_dts", "init_write_routes_dts", "parseDuration", "value", "match", "n", "init_duration", "__esmMin", "build_exports", "writeFileSync", "resolve", "build", "config", "baseConfig", "runtimeConfig", "init_build", "__esmMin", "init_vite", "init_duration", "devix", "parseDuration", "readFileSync", "mkdirSync", "writeFileSync", "resolve", "join", "userConfig", "t", "renderModule", "manifest", "urls", "url", "fullUrl", "html", "statusCode", "outPath"]
4
+ "sourcesContent": ["interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({ cssUrls }: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n\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 routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {routePattern} from \"../utils/patterns\";\n\nexport interface Page {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface Layout {\n dir: string\n key: string\n}\n\nexport interface PagesResult {\n pages: Page[]\n layouts: Layout[]\n}\n\nfunction keyToRoutePattern(key: string, pagesDir: string): string {\n const rel = key.slice(pagesDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === \"/\" ? \"/\" : `/${pattern}`\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: PagesResult | null = null\n\nexport function invalidatePagesCache() {\n cache = null\n}\n\nexport function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult {\n if (cache) return cache\n\n const pages: Page[] = []\n const layouts: Layout[] = []\n\n for (const key of layoutKeys) {\n layouts.push({dir: keyToDir(key), key})\n }\n\n for (const key of pageKeys) {\n const pattern = keyToRoutePattern(key, pagesDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n pages.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n\n pages.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {pages, layouts}\n return cache\n}\n\nexport function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[] {\n const pageDir = keyToDir(pageKey)\n\n return layouts\n .filter(layout => pageDir.startsWith(layout.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchPage(pathname: string, pages: Page[]): {\n page: Page\n params: Record<string, string>\n} | null {\n for (const page of pages) {\n const match = pathname.match(page.regex)\n if (match) {\n const params: Record<string, string> = {}\n page.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {page, params}\n }\n }\n return null\n}\n", "import {routePattern} from \"../utils/patterns\";\n\nexport interface ApiRoute {\n path: string\n key: string\n params: string[]\n regex: RegExp\n}\n\nexport interface ApiMiddleware {\n dir: string\n key: string\n}\n\nexport interface ApiResult {\n routes: ApiRoute[]\n middlewares: ApiMiddleware[]\n}\n\nexport function keyToRoutePattern(key: string, apiDir: string): string {\n const rel = key.slice(apiDir.length + 1).replace(/\\\\/g, '/')\n const pattern = routePattern(rel)\n return pattern === '/' ? '/api' : `/api/${pattern}`.replace('/api//', '/api/')\n}\n\nfunction keyToDir(key: string): string {\n return key.slice(0, key.lastIndexOf('/'))\n}\n\nlet cache: ApiResult | null = null\n\nexport function invalidateApiCache() {\n cache = null\n}\n\nexport function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult {\n if (cache) return cache\n\n const routes: ApiRoute[] = []\n const middlewares: ApiMiddleware[] = []\n\n for (const key of middlewareKeys) {\n middlewares.push({dir: keyToDir(key), key})\n }\n\n for (const key of routeKeys) {\n const pattern = keyToRoutePattern(key, apiDir)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n const regexStr = pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n routes.push({path: pattern, key, params, regex: new RegExp(`^${regexStr}$`)})\n }\n routes.sort((a, b) => {\n const aScore = (a.path.match(/:/g) || []).length\n const bScore = (b.path.match(/:/g) || []).length\n if (aScore !== bScore) return aScore - bScore\n return b.path.length - a.path.length\n })\n\n cache = {routes, middlewares}\n return cache\n}\n\nexport function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[] {\n const routeDir = keyToDir(routeKey)\n\n return middlewares\n .filter(mw => routeDir.startsWith(mw.dir))\n .sort((a, b) => a.dir.split('/').length - b.dir.split('/').length)\n}\n\nexport function matchRoute(\n pathname: string,\n routes: ApiRoute[]\n): {route: ApiRoute; params: Record<string, string>} | null {\n for (const route of routes) {\n const match = pathname.match(route.regex)\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return {route, params}\n }\n }\n return null\n}\n", "export function generateContext(): string {\n return `\nexport {RouterContext} from '@devlusoft/devix/runtime/context'\n`\n}", "const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nconst METHOD_EXPORT_RE = /export\\s+(?:const|async\\s+function|function)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/g\n\nfunction stripComments(content: string): string {\n return content\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n}\n\nexport function extractHttpMethods(content: string): HttpMethod[] {\n const found = new Set<HttpMethod>()\n for (const match of stripComments(content).matchAll(METHOD_EXPORT_RE)) {\n found.add(match[1] as HttpMethod)\n }\n return [...found]\n}\n", "import { keyToRoutePattern } from '../../server/api-router'\nimport type { HttpMethod } from './extract-methods'\n\nexport interface RouteEntry {\n filePath: string\n urlPattern: string\n identifier: string\n methods: HttpMethod[]\n}\n\nexport function filePathToIdentifier(filePath: string, apiDir: string): string {\n return '_api_' + filePath\n .slice(`${apiDir}/`.length)\n .replace(/\\.(ts|tsx)$/, '')\n .replace(/[^a-zA-Z0-9]/g, '_')\n}\n\nexport function buildRouteEntry(filePath: string, apiDir: string, methods: HttpMethod[]): RouteEntry {\n return {\n filePath,\n urlPattern: keyToRoutePattern(filePath, apiDir),\n identifier: filePathToIdentifier(filePath, apiDir),\n methods,\n }\n}\n\nexport function generateRoutesDts(entries: RouteEntry[], apiDir: string): string {\n if (entries.length === 0) {\n return `// auto-generado por devix \u2014 no editar\\ndeclare module '@devlusoft/devix' {\\n interface ApiRoutes {}\\n}\\n`\n }\n\n const imports = entries\n .map(e => {\n const importPath = '../' + e.filePath.replace(/\\.(ts|tsx)$/, '')\n return `import type * as ${e.identifier} from '${importPath}'`\n })\n .join('\\n')\n\n const routeLines = entries.flatMap(e =>\n e.methods.map(m =>\n ` '${m} ${e.urlPattern}': InferRoute<(typeof ${e.identifier})['${m}']>`\n )\n ).join('\\n')\n\n return `// auto-generado por devix \u2014 no editar\n${imports}\n\ntype JsonResponse<T> = Response & { readonly __body: T }\ntype UnwrapJson<T> = T extends JsonResponse<infer U> ? U : never\ntype InferFnReturn<T> = T extends (...args: any[]) => any\n ? UnwrapJson<Awaited<ReturnType<T>>> | Exclude<Awaited<ReturnType<T>>, JsonResponse<any> | null | void | undefined>\n : 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: InferFnReturn<() => TReturn>\n }\n : InferFnReturn<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", "import { UserConfig, Plugin, mergeConfig } from 'vite'\nimport type { DevixConfig } from '../config'\nimport react from '@vitejs/plugin-react'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { generateEntryClient } from './codegen/entry-client'\nimport { generateClientRoutes } from './codegen/client-routes'\nimport { generateRender } from './codegen/render'\nimport { generateApi } from './codegen/api'\nimport { invalidatePagesCache } from \"../server/pages-router\";\nimport { invalidateApiCache } from \"../server/api-router\";\nimport { generateContext } from \"./codegen/context\";\nimport { scanApiFiles } from \"./codegen/scan-api\";\nimport { generateRoutesDts } from \"./codegen/routes-dts\";\nimport { writeRoutesDts } from \"./codegen/write-routes-dts\";\nimport { parseSync } from 'oxc-parser'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst VIRTUAL_ENTRY_CLIENT = 'virtual:devix/entry-client'\nconst VIRTUAL_CLIENT_ROUTES = 'virtual:devix/client-routes'\nconst VIRTUAL_RENDER = 'virtual:devix/render'\nconst VIRTUAL_API = 'virtual:devix/api'\nconst VIRTUAL_CONTEXT = 'virtual:devix/context'\n\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\n const virtualPlugin: Plugin = {\n name: 'devix',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ENTRY_CLIENT) return `\\0${VIRTUAL_ENTRY_CLIENT}`\n if (id === VIRTUAL_CLIENT_ROUTES) return `\\0${VIRTUAL_CLIENT_ROUTES}`\n if (id === VIRTUAL_RENDER) return `\\0${VIRTUAL_RENDER}`\n if (id === VIRTUAL_API) return `\\0${VIRTUAL_API}`\n if (id === VIRTUAL_CONTEXT) return `\\0${VIRTUAL_CONTEXT}`\n },\n\n load(id) {\n if (id === `\\0${VIRTUAL_ENTRY_CLIENT}`)\n return generateEntryClient({ cssUrls })\n if (id === `\\0${VIRTUAL_CLIENT_ROUTES}`)\n return generateClientRoutes({ pagesDir, matcherPath })\n if (id === `\\0${VIRTUAL_RENDER}`)\n return generateRender({ pagesDir, renderPath })\n if (id === `\\0${VIRTUAL_API}`)\n return generateApi({ apiPath, appDir })\n if (id === `\\0${VIRTUAL_CONTEXT}`)\n return generateContext()\n },\n\n\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 },\n\n configureServer(server) {\n const root = process.cwd()\n\n const regenerateDts = () => {\n const entries = scanApiFiles(appDir, root)\n writeRoutesDts(generateRoutesDts(entries, `${appDir}/api`), root)\n }\n\n server.watcher.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))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('unlink', (file) => {\n if (file.startsWith(resolve(root, pagesDir))) invalidatePagesCache()\n if (file.includes(`${appDir}/api`)) { invalidateApiCache(); regenerateDts() }\n })\n server.watcher.on('change', (file) => {\n if (file.includes(`${appDir}/api`) && !file.endsWith('middleware.ts')) {\n regenerateDts()\n }\n })\n },\n }\n\n const base: UserConfig = {\n plugins: [react(), virtualPlugin],\n 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 type {DevixConfig} from '../config'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\nimport {pathToFileURL} from \"node:url\"\nimport {join} from \"node:path\"\n\nconst config: DevixConfig = (await import(pathToFileURL(join(process.cwd(), 'devix.config.ts')).href)).default\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync, rmSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport type {DevixConfig} from '../config'\nimport { pathToFileURL } from \"node:url\"\n\nconst userConfig: DevixConfig = (await import(pathToFileURL(join(process.cwd(), 'devix.config.ts')).href)).default\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(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": ["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", "routePattern", "rel", "init_patterns", "__esmMin", "invalidatePagesCache", "cache", "init_pages_router", "__esmMin", "init_patterns", "keyToRoutePattern", "key", "apiDir", "rel", "pattern", "routePattern", "invalidateApiCache", "cache", "init_api_router", "__esmMin", "init_patterns", "generateContext", "init_context", "__esmMin", "stripComments", "content", "extractHttpMethods", "found", "match", "METHOD_EXPORT_RE", "init_extract_methods", "__esmMin", "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", "mergeConfig", "react", "fileURLToPath", "dirname", "resolve", "parseSync", "devix", "config", "appDir", "pagesDir", "cssUrls", "u", "renderPath", "__dirname", "apiPath", "matcherPath", "virtualPlugin", "id", "VIRTUAL_ENTRY_CLIENT", "VIRTUAL_CLIENT_ROUTES", "VIRTUAL_RENDER", "VIRTUAL_API", "VIRTUAL_CONTEXT", "generateEntryClient", "generateClientRoutes", "generateRender", "generateApi", "generateContext", "code", "options", "resolvedPagesDir", "ast", "replacements", "node", "decl", "SERVER_EXPORTS", "seen", "declarator", "a", "b", "result", "start", "end", "name", "root", "entries", "scanApiFiles", "writeRoutesDts", "generateRoutesDts", "server", "regenerateDts", "file", "invalidatePagesCache", "invalidateApiCache", "base", "init_vite", "__esmMin", "init_entry_client", "init_client_routes", "init_render", "init_api", "init_pages_router", "init_api_router", "init_context", "init_scan_api", "init_routes_dts", "init_write_routes_dts", "parseDuration", "value", "match", "n", "init_duration", "__esmMin", "build_exports", "writeFileSync", "resolve", "build", "pathToFileURL", "join", "config", "baseConfig", "runtimeConfig", "init_build", "__esmMin", "init_vite", "init_duration", "devix", "parseDuration", "readFileSync", "mkdirSync", "writeFileSync", "rmSync", "resolve", "join", "pathToFileURL", "userConfig", "t", "renderModule", "manifest", "urls", "url", "fullUrl", "html", "statusCode", "outPath", "data", "dataPath"]
7
7
  }
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- var s=(e,t)=>()=>(e&&(t=e(e=0)),t);var je={};import{spawnSync as Me}from"node:child_process";import{fileURLToPath as Ie}from"node:url";import{dirname as ke,resolve as Le}from"node:path";var Ue,X=s(()=>{"use strict";Ue=ke(Ie(import.meta.url));for(;Me(process.execPath,[Le(Ue,"dev-server.js")],{stdio:"inherit",env:process.env}).status===75;);});function G({cssUrls:e}){return`
3
- ${e.map(r=>`import '${r}'`).join(`
2
+ var a=(t,e)=>()=>(t&&(e=t(t=0)),e);var Wt={};import{spawnSync as qt}from"node:child_process";import{fileURLToPath as Nt}from"node:url";import{dirname as Vt,resolve as Bt}from"node:path";var Jt,K=a(()=>{"use strict";Jt=Vt(Nt(import.meta.url));for(;qt(process.execPath,[Bt(Jt,"dev-server.js")],{stdio:"inherit",env:process.env}).status===75;);});function Q({cssUrls:t}){return`
3
+ ${t.map(r=>`import '${r}'`).join(`
4
4
  `)}
5
5
  import "@vitejs/plugin-react/preamble"
6
6
  import React from "react"
@@ -63,12 +63,12 @@ if (!window.__DEVIX__) {
63
63
  )
64
64
  }
65
65
  }
66
- `}var Y=s(()=>{"use strict"});function z({pagesDir:e,matcherPath:t}){return`
66
+ `}var tt=a(()=>{"use strict"});function et({pagesDir:t,matcherPath:e}){return`
67
67
  import React from 'react'
68
- import { createMatcher } from '${t}'
69
- const pageFiles = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
70
- const layoutFiles = import.meta.glob('/${e}/**/layout.tsx')
71
- const errorFiles = import.meta.glob('/${e}/**/error.tsx')
68
+ import { createMatcher } from '${e}'
69
+ const pageFiles = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
70
+ const layoutFiles = import.meta.glob('/${t}/**/layout.tsx')
71
+ const errorFiles = import.meta.glob('/${t}/**/error.tsx')
72
72
 
73
73
  export const matchClientRoute = createMatcher(pageFiles, layoutFiles)
74
74
 
@@ -91,16 +91,16 @@ export function getDefaultErrorPage() {
91
91
  )
92
92
  }
93
93
  }
94
- `}var Z=s(()=>{"use strict"});function K({pagesDir:e,renderPath:t}){return`
95
- import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${t}'
94
+ `}var rt=a(()=>{"use strict"});function ot({pagesDir:t,renderPath:e}){return`
95
+ import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${e}'
96
96
 
97
- const _pages = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
98
- const _layouts = import.meta.glob('/${e}/**/layout.tsx')
97
+ const _pages = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
98
+ const _layouts = import.meta.glob('/${t}/**/layout.tsx')
99
99
 
100
100
  const _glob = {
101
101
  pages: _pages,
102
102
  layouts: _layouts,
103
- pagesDir: '/${e}',
103
+ pagesDir: '/${t}',
104
104
  }
105
105
 
106
106
  export function render(url, request, options) {
@@ -114,29 +114,29 @@ export function runLoader(url, request, options) {
114
114
  export function getStaticRoutes() {
115
115
  return _getStaticRoutes(_glob)
116
116
  }
117
- `}var Q=s(()=>{"use strict"});function ee({apiPath:e,appDir:t}){return`
118
- import { handleApiRequest as _handleApiRequest } from '${e}'
117
+ `}var nt=a(()=>{"use strict"});function it({apiPath:t,appDir:e}){return`
118
+ import { handleApiRequest as _handleApiRequest } from '${t}'
119
119
 
120
- const _routes = import.meta.glob(['/${t}/api/**/*.ts', '!**/middleware.ts'])
121
- const _middlewares = import.meta.glob('/${t}/api/**/middleware.ts')
120
+ const _routes = import.meta.glob(['/${e}/api/**/*.ts', '!**/middleware.ts'])
121
+ const _middlewares = import.meta.glob('/${e}/api/**/middleware.ts')
122
122
 
123
123
  const _glob = {
124
124
  routes: _routes,
125
125
  middlewares: _middlewares,
126
- apiDir: '/${t}/api',
126
+ apiDir: '/${e}/api',
127
127
  }
128
128
 
129
129
  export function handleApiRequest(url, request) {
130
130
  return _handleApiRequest(url, request, _glob)
131
131
  }
132
- `}var te=s(()=>{"use strict"});function S(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var T=s(()=>{"use strict"});function $(){Fe=null}var Fe,re=s(()=>{"use strict";T();Fe=null});function oe(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),i=S(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}function b(){He=null}var He,D=s(()=>{"use strict";T();He=null});function ne(){return`
132
+ `}var st=a(()=>{"use strict"});function $(t){return t.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var b=a(()=>{"use strict"});function D(){Xt=null}var Xt,at=a(()=>{"use strict";b();Xt=null});function ct(t,e){let r=t.slice(e.length+1).replace(/\\/g,"/"),i=$(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}function C(){Gt=null}var Gt,A=a(()=>{"use strict";b();Gt=null});function lt(){return`
133
133
  export {RouterContext} from '@devlusoft/devix/runtime/context'
134
- `}var ie=s(()=>{"use strict"});function Ne(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function se(e){let t=new Set;for(let r of Ne(e).matchAll(qe))t.add(r[1]);return[...t]}var qe,ae=s(()=>{"use strict";qe=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function Ve(e,t){return"_api_"+e.slice(`${t}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function ce(e,t,r){return{filePath:e,urlPattern:oe(e,t),identifier:Ve(e,t),methods:r}}function C(e,t){if(e.length===0)return`// auto-generado por devix \u2014 no editar
134
+ `}var ut=a(()=>{"use strict"});function zt(t){return t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function pt(t){let e=new Set;for(let r of zt(t).matchAll(Yt))e.add(r[1]);return[...e]}var Yt,dt=a(()=>{"use strict";Yt=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function Zt(t,e){return"_api_"+t.slice(`${e}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function mt(t,e,r){return{filePath:t,urlPattern:ct(t,e),identifier:Zt(t,e),methods:r}}function O(t,e){if(t.length===0)return`// auto-generado por devix \u2014 no editar
135
135
  declare module '@devlusoft/devix' {
136
136
  interface ApiRoutes {}
137
137
  }
138
- `;let r=e.map(o=>{let a="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${a}'`}).join(`
139
- `),i=e.flatMap(o=>o.methods.map(a=>` '${a} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${a}']>`)).join(`
138
+ `;let r=t.map(o=>{let s="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${s}'`}).join(`
139
+ `),i=t.flatMap(o=>o.methods.map(s=>` '${s} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${s}']>`)).join(`
140
140
  `);return`// auto-generado por devix \u2014 no editar
141
141
  ${r}
142
142
 
@@ -158,7 +158,7 @@ declare module '@devlusoft/devix' {
158
158
  ${i}
159
159
  }
160
160
  }
161
- `}var A=s(()=>{"use strict";D()});import{readFileSync as Be,readdirSync as We,statSync as Je}from"node:fs";import{join as O,relative as Xe}from"node:path";function le(e,t){let r=[];for(let i of We(e)){let o=O(e,i);Je(o).isDirectory()?r.push(...le(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(Xe(t,o).replace(/\\/g,"/"))}return r}function M(e,t){let r=O(t,e,"api"),i;try{i=le(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=Be(O(t,o),"utf-8"),m=se(a);return m.length===0?[]:[ce(o,`${e}/api`,m)]}catch{return[]}})}var ue=s(()=>{"use strict";ae();A()});import{mkdirSync as Ge,readFileSync as Ye,writeFileSync as ze,existsSync as Ze}from"node:fs";import{join as pe}from"node:path";function I(e,t){let r=pe(t,".devix"),i=pe(r,"routes.d.ts");return Ge(r,{recursive:!0}),Ze(i)&&Ye(i,"utf-8")===e?!1:(ze(i,e,"utf-8"),!0)}var de=s(()=>{"use strict"});import{mergeConfig as Ke}from"vite";import Qe from"@vitejs/plugin-react";import{fileURLToPath as et}from"node:url";import{dirname as tt,resolve as d}from"node:path";import{parseSync as rt}from"oxc-parser";function fe(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=d(k,"../server/render.js").replace(/\\/g,"/"),a=d(k,"../server/api.js").replace(/\\/g,"/"),m=d(k,"../runtime/client-router.js").replace(/\\/g,"/"),h={name:"devix",enforce:"pre",resolveId(n){if(n===L)return`\0${L}`;if(n===U)return`\0${U}`;if(n===j)return`\0${j}`;if(n===F)return`\0${F}`;if(n===H)return`\0${H}`},load(n){if(n===`\0${L}`)return G({cssUrls:i});if(n===`\0${U}`)return z({pagesDir:r,matcherPath:m});if(n===`\0${j}`)return K({pagesDir:r,renderPath:o});if(n===`\0${F}`)return ee({apiPath:a,appDir:t});if(n===`\0${H}`)return ne()},transform(n,l,x){if(x?.ssr)return;let c=d(process.cwd(),r);if(!l.startsWith(c))return;let Oe=rt(l,n,{sourceType:"module"}),v=[];for(let u of Oe.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let p=u.declaration;if(p.type==="FunctionDeclaration"&&p.id&&me.has(p.id.name)&&v.push({start:u.start,end:u.end,name:p.id.name}),p.type==="VariableDeclaration"){let w=new Set;for(let P of p.declarations)P.id.type==="Identifier"&&me.has(P.id.name)&&(w.has(u.start)||(w.add(u.start),v.push({start:u.start,end:u.end,name:P.id.name})))}}if(v.length===0)return;v.sort((u,p)=>p.start-u.start);let R=n;for(let{start:u,end:p,name:w}of v)R=R.slice(0,u)+`export const ${w} = undefined`+R.slice(p);return{code:R,map:null}},buildStart(){let n=process.cwd(),l=M(t,n);I(C(l,`${t}/api`),n)},configureServer(n){let l=process.cwd(),x=()=>{let c=M(t,l);I(C(c,`${t}/api`),l)};n.watcher.add(d(l,"devix.config.ts")),n.watcher.on("change",c=>{c===d(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",c=>{c.startsWith(d(l,r))&&$(),c.includes(`${t}/api`)&&(b(),x())}),n.watcher.on("unlink",c=>{c.startsWith(d(l,r))&&$(),c.includes(`${t}/api`)&&(b(),x())}),n.watcher.on("change",c=>{c.includes(`${t}/api`)&&!c.endsWith("middleware.ts")&&x()})}},g={plugins:[Qe(),h],publicDir:d(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Ke(g,e.vite??{})}var k,L,U,j,F,H,me,ge=s(()=>{"use strict";Y();Z();Q();te();re();D();ie();ue();A();de();k=tt(et(import.meta.url)),L="virtual:devix/entry-client",U="virtual:devix/client-routes",j="virtual:devix/render",F="virtual:devix/api",H="virtual:devix/context",me=new Set(["loader","guard","generateStaticParams","headers"])});function he(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 xe=s(()=>{"use strict"});var Re={};import{writeFileSync as ot}from"node:fs";import{resolve as nt}from"node:path";import{build as ve}from"vite";var y,ye,it,q=s(async()=>{"use strict";ge();xe();y=(await import(`${process.cwd()}/devix.config.ts`)).default,ye=fe(y);await ve({...ye,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await ve({...ye,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});it={port:y.port??3e3,host:y.host??!1,loaderTimeout:he(y.loaderTimeout??1e4),output:y.output??"server"};ot(nt(process.cwd(),"dist/devix.config.json"),JSON.stringify(it,null,2),"utf-8")});var dt={};import{readFileSync as st,mkdirSync as at,writeFileSync as ct}from"node:fs";import{resolve as we,join as N}from"node:path";var lt,ut,_e,pt,V,Ee=s(async()=>{"use strict";lt=(await import(`${process.cwd()}/devix.config.ts`)).default;lt.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await q().then(()=>Re);ut=Date.now(),_e=await import(we(process.cwd(),"dist/server/render.js")+`?t=${ut}`),pt=JSON.parse(st(we(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),V=await _e.getStaticRoutes();console.log(`[devix] Generating ${V.length} static page${V.length===1?"":"s"}...`);for(let e of V){let t=`http://localhost${e}`,{html:r,statusCode:i}=await _e.render(t,new Request(t),{manifest:pt});if(i!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${i}`);continue}let o=e==="/"?N(process.cwd(),"dist/client/index.html"):N(process.cwd(),"dist/client",e,"index.html");at(N(o,".."),{recursive:!0}),ct(o,`<!DOCTYPE html>${r}`,"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.")});function Pe(e,{apiModule:t,renderModule:r,loaderTimeout:i}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:a,search:m}=new URL(o.req.url,"http://localhost"),h=a.replace(/^\/_data/,"")+m,g=await r.runLoader(h,o.req.raw,{loaderTimeout:i});return g.error?o.json({error:"internal error"},500):o.json(g)}catch(a){return console.error(a),o.json({error:"internal error"},500)}})}function Se(e,{renderModule:t,manifest:r,loaderTimeout:i}){e.get("*",async o=>{try{let{html:a,statusCode:m,headers:h}=await t.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:i}),g=o.html(`<!DOCTYPE html>${a}`,m);for(let[n,l]of Object.entries(h))g.headers.set(n,l);return g}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Te=s(()=>{"use strict"});import{loadEnv as mt}from"vite";function $e(e){let t=mt(e,process.cwd(),"");for(let[r,i]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=i)}var be=s(()=>{"use strict"});var wt={};import{readFileSync as De}from"node:fs";import{serve as ft}from"@hono/node-server";import{serveStatic as gt}from"@hono/node-server/serve-static";import{Hono as ht}from"hono";import{resolve as _,join as xt}from"node:path";var B,W,J,f,vt,yt,E,Rt,Ce=s(async()=>{"use strict";Te();be();$e("production");try{f=JSON.parse(De(_(process.cwd(),"dist/devix.config.json"),"utf-8")),f.output!=="static"&&(B=await import(_(process.cwd(),"dist/server/render.js")),W=await import(_(process.cwd(),"dist/server/api.js"))),J=JSON.parse(De(_(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}vt=Number(process.env.PORT)||f.port||3e3,yt=typeof f.host=="string"?f.host:f.host?"0.0.0.0":process.env.HOST||"0.0.0.0",E=new ht,Rt=xt(process.cwd(),"dist/client");E.use("/*",gt({root:Rt,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));f.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Pe(E,{renderModule:B,apiModule:W,manifest:J}),Se(E,{renderModule:B,apiModule:W,manifest:J,loaderTimeout:f.loaderTimeout}));ft({fetch:E.fetch,port:vt,hostname:yt},e=>console.log(`http://${e.address}:${e.port}`))});var Ae=process.argv[2];switch(Ae){case"dev":await Promise.resolve().then(()=>(X(),je));break;case"build":await q().then(()=>Re);break;case"generate":await Ee().then(()=>dt);break;case"start":await Ce().then(()=>wt);break;case"--version":case"-v":{console.log("0.4.1-beta.5");break}case"--help":case"-h":console.log(`
161
+ `}var M=a(()=>{"use strict";A()});import{readFileSync as Kt,readdirSync as Qt,statSync as te}from"node:fs";import{join as I,relative as ee}from"node:path";function ft(t,e){let r=[];for(let i of Qt(t)){let o=I(t,i);te(o).isDirectory()?r.push(...ft(o,e)):/\.(ts|tsx)$/.test(i)&&r.push(ee(e,o).replace(/\\/g,"/"))}return r}function L(t,e){let r=I(e,t,"api"),i;try{i=ft(r,e)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let s=Kt(I(e,o),"utf-8"),p=pt(s);return p.length===0?[]:[mt(o,`${t}/api`,p)]}catch{return[]}})}var gt=a(()=>{"use strict";dt();M()});import{mkdirSync as re,readFileSync as oe,writeFileSync as ne,existsSync as ie}from"node:fs";import{join as ht}from"node:path";function j(t,e){let r=ht(e,".devix"),i=ht(r,"routes.d.ts");return re(r,{recursive:!0}),ie(i)&&oe(i,"utf-8")===t?!1:(ne(i,t,"utf-8"),!0)}var xt=a(()=>{"use strict"});import{mergeConfig as se}from"vite";import ae from"@vitejs/plugin-react";import{fileURLToPath as ce}from"node:url";import{dirname as le,resolve as m}from"node:path";import{parseSync as ue}from"oxc-parser";function yt(t){let e=t.appDir??"app",r=`${e}/pages`,i=(t.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=m(k,"../server/render.js").replace(/\\/g,"/"),s=m(k,"../server/api.js").replace(/\\/g,"/"),p=m(k,"../runtime/client-router.js").replace(/\\/g,"/"),x={name:"devix",enforce:"pre",resolveId(n){if(n===U)return`\0${U}`;if(n===F)return`\0${F}`;if(n===H)return`\0${H}`;if(n===q)return`\0${q}`;if(n===N)return`\0${N}`},load(n){if(n===`\0${U}`)return Q({cssUrls:i});if(n===`\0${F}`)return et({pagesDir:r,matcherPath:p});if(n===`\0${H}`)return ot({pagesDir:r,renderPath:o});if(n===`\0${q}`)return it({apiPath:s,appDir:e});if(n===`\0${N}`)return lt()},transform(n,l,v){if(v?.ssr)return;let c=m(process.cwd(),r);if(!l.startsWith(c))return;let Ht=ue(l,n,{sourceType:"module"}),y=[];for(let u of Ht.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let d=u.declaration;if(d.type==="FunctionDeclaration"&&d.id&&vt.has(d.id.name)&&y.push({start:u.start,end:u.end,name:d.id.name}),d.type==="VariableDeclaration"){let P=new Set;for(let T of d.declarations)T.id.type==="Identifier"&&vt.has(T.id.name)&&(P.has(u.start)||(P.add(u.start),y.push({start:u.start,end:u.end,name:T.id.name})))}}if(y.length===0)return;y.sort((u,d)=>d.start-u.start);let E=n;for(let{start:u,end:d,name:P}of y)E=E.slice(0,u)+`export const ${P} = undefined`+E.slice(d);return{code:E,map:null}},buildStart(){let n=process.cwd(),l=L(e,n);j(O(l,`${e}/api`),n)},configureServer(n){let l=process.cwd(),v=()=>{let c=L(e,l);j(O(c,`${e}/api`),l)};n.watcher.add(m(l,"devix.config.ts")),n.watcher.on("change",c=>{c===m(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",c=>{c.startsWith(m(l,r))&&D(),c.includes(`${e}/api`)&&(C(),v())}),n.watcher.on("unlink",c=>{c.startsWith(m(l,r))&&D(),c.includes(`${e}/api`)&&(C(),v())}),n.watcher.on("change",c=>{c.includes(`${e}/api`)&&!c.endsWith("middleware.ts")&&v()})}},g={plugins:[ae(),x],publicDir:m(process.cwd(),t.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...t.envPrefix?{envPrefix:t.envPrefix}:{}};return se(g,t.vite??{})}var k,U,F,H,q,N,vt,Rt=a(()=>{"use strict";tt();rt();nt();st();at();A();ut();gt();M();xt();k=le(ce(import.meta.url)),U="virtual:devix/entry-client",F="virtual:devix/client-routes",H="virtual:devix/render",q="virtual:devix/api",N="virtual:devix/context",vt=new Set(["loader","guard","generateStaticParams","headers"])});function wt(t){if(typeof t=="number")return t;let e=t.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!e)throw new Error(`[devix] Invalid duration: "${t}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(e[1]);switch(e[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var _t=a(()=>{"use strict"});var St={};import{writeFileSync as pe}from"node:fs";import{resolve as de}from"node:path";import{build as Et}from"vite";import{pathToFileURL as me}from"node:url";import{join as fe}from"node:path";var R,Pt,ge,V=a(async()=>{"use strict";Rt();_t();R=(await import(me(fe(process.cwd(),"devix.config.ts")).href)).default,Pt=yt(R);await Et({...Pt,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await Et({...Pt,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});ge={port:R.port??3e3,host:R.host??!1,loaderTimeout:wt(R.loaderTimeout??1e4),output:R.output??"server"};pe(de(process.cwd(),"dist/devix.config.json"),JSON.stringify(ge,null,2),"utf-8")});var ye={};import{readFileSync as he,mkdirSync as Tt,writeFileSync as $t,rmSync as xe}from"node:fs";import{resolve as W,join as h}from"node:path";import{pathToFileURL as Dt}from"node:url";var Ct,ve,B,bt,J,At=a(async()=>{"use strict";Ct=(await import(Dt(h(process.cwd(),"devix.config.ts")).href)).default;Ct.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await V().then(()=>St);ve=Date.now(),B=await import(Dt(W(process.cwd(),"dist/server/render.js")).href+`?t=${ve}`),bt=JSON.parse(he(W(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),J=await B.getStaticRoutes();console.log(`[devix] Generating ${J.length} static page${J.length===1?"":"s"}...`);for(let t of J){let e=`http://localhost${t}`,{html:r,statusCode:i}=await B.render(e,new Request(e),{manifest:bt});if(i!==200){console.warn(`[devix] Skipping ${t} \u2014 status ${i}`);continue}let o=t==="/"?h(process.cwd(),"dist/client/index.html"):h(process.cwd(),"dist/client",t,"index.html");Tt(h(o,".."),{recursive:!0}),$t(o,`<!DOCTYPE html>${r}`,"utf-8");let s=await B.runLoader(e,new Request(e),{manifest:bt}),p=t==="/"?h(process.cwd(),"dist/client/_data/index.json"):h(process.cwd(),"dist/client/_data",`${t}.json`);Tt(h(p,".."),{recursive:!0}),$t(p,JSON.stringify(s),"utf-8"),console.log(` \u2713 ${t}`)}console.log("[devix] Generation complete.");Ct.output==="static"&&(xe(W(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function Ot(t,{apiModule:e,renderModule:r,loaderTimeout:i}){t.all("/api/*",async o=>{try{return await e.handleApiRequest(o.req.url,o.req.raw)}catch(s){return console.error(s),o.json({error:"internal error"},500)}}),t.get("/_data/*",async o=>{try{let{pathname:s,search:p}=new URL(o.req.url,"http://localhost"),x=s.replace(/^\/_data/,"")+p,g=await r.runLoader(x,o.req.raw,{loaderTimeout:i});return g.error?o.json({error:"internal error"},500):o.json(g)}catch(s){return console.error(s),o.json({error:"internal error"},500)}})}function Mt(t,{renderModule:e,manifest:r,loaderTimeout:i}){t.get("*",async o=>{try{let{html:s,statusCode:p,headers:x}=await e.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:i}),g=o.html(`<!DOCTYPE html>${s}`,p);for(let[n,l]of Object.entries(x))g.headers.set(n,l);return g}catch(s){return console.error(s),o.text("Internal Server Error",500)}})}var It=a(()=>{"use strict"});import{loadEnv as Re}from"vite";function Lt(t){let e=Re(t,process.cwd(),"");for(let[r,i]of Object.entries(e))process.env[r]===void 0&&(process.env[r]=i)}var jt=a(()=>{"use strict"});var Te={};import{readFileSync as X}from"node:fs";import{serve as we}from"@hono/node-server";import{serveStatic as _e}from"@hono/node-server/serve-static";import{Hono as Ee}from"hono";import{resolve as kt,join as w}from"node:path";import{pathToFileURL as S}from"node:url";var G,Y,z,f,Pe,Se,_,Z,Ut=a(async()=>{"use strict";It();jt();Lt("production");try{f=JSON.parse(X(S(w(process.cwd(),"dist/devix.config.jso")).href,"utf-8")),f.output!=="static"&&(G=await import(S(kt(process.cwd(),"dist/server/render.js")).href),Y=await import(S(kt(process.cwd(),"dist/server/api.js")).href)),z=JSON.parse(X(S(w(process.cwd(),"dist/client/.vite/manifest.json")),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}Pe=Number(process.env.PORT)||f.port||3e3,Se=typeof f.host=="string"?f.host:f.host?"0.0.0.0":process.env.HOST||"0.0.0.0",_=new Ee,Z=w(process.cwd(),"dist/client");f.output==="static"&&_.get("/_data/*",t=>{let e=t.req.path.replace(/^\/_data/,"")||"/",r=e==="/"?w(Z,"_data/index.json"):w(Z,"_data",`${e}.json`);try{let i=X(r,"utf-8");return t.json(JSON.parse(i))}catch{return t.json({error:"not found"},404)}});_.use("/*",_e({root:Z,onFound:(t,e)=>{e.header("Cache-Control",t.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));f.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Ot(_,{renderModule:G,apiModule:Y,manifest:z}),Mt(_,{renderModule:G,apiModule:Y,manifest:z,loaderTimeout:f.loaderTimeout}));we({fetch:_.fetch,port:Pe,hostname:Se},t=>console.log(`http://${t.address}:${t.port}`))});var Ft=process.argv[2];switch(Ft){case"dev":await Promise.resolve().then(()=>(K(),Wt));break;case"build":await V().then(()=>St);break;case"generate":await At().then(()=>ye);break;case"start":await Ut().then(()=>Te);break;case"--version":case"-v":{console.log("0.4.1-beta.7");break}case"--help":case"-h":console.log(`
162
162
  devix \u2014 a lightweight SSR framework
163
163
 
164
164
  Usage:
@@ -174,5 +174,5 @@ Options:
174
174
  Output modes (set in devix.config.ts):
175
175
  output: "server" SSR mode \u2014 devix start handles requests dynamically (default)
176
176
  output: "static" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only
177
- `.trim());break;default:console.error(`Unknown command: ${Ae}`),console.error("Usage: devix <dev|build|generate|start>"),process.exit(1)}
177
+ `.trim());break;default:console.error(`Unknown command: ${Ft}`),console.error("Usage: devix <dev|build|generate|start>"),process.exit(1)}
178
178
  //# sourceMappingURL=index.js.map