@devlusoft/devix 0.4.1-beta.7 → 0.4.1-beta.9
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.
- package/dist/cli/build.js +4 -4
- package/dist/cli/build.js.map +4 -4
- package/dist/cli/dev-server.js +8 -8
- package/dist/cli/dev-server.js.map +4 -4
- package/dist/cli/generate.js +7 -7
- package/dist/cli/generate.js.map +4 -4
- package/dist/cli/index.js +10 -10
- package/dist/cli/index.js.map +4 -4
- package/dist/cli/start.js +1 -1
- package/dist/cli/start.js.map +2 -2
- package/dist/utils/banner.js +1 -1
- package/dist/utils/load-config.d.ts +2 -0
- package/dist/utils/load-config.js +2 -0
- package/dist/utils/load-config.js.map +7 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
2
|
+
var s=(t,e)=>()=>(t&&(e=t(t=0)),e);var Gt={};import{spawnSync as Vt}from"node:child_process";import{fileURLToPath as Bt}from"node:url";import{dirname as Jt,resolve as Wt}from"node:path";var Xt,Q=s(()=>{"use strict";Xt=Jt(Bt(import.meta.url));for(;Vt(process.execPath,[Wt(Xt,"dev-server.js")],{stdio:"inherit",env:process.env}).status===75;);});function tt({cssUrls:t}){return`
|
|
3
3
|
${t.map(r=>`import '${r}'`).join(`
|
|
4
4
|
`)}
|
|
5
5
|
import "@vitejs/plugin-react/preamble"
|
|
@@ -63,7 +63,7 @@ if (!window.__DEVIX__) {
|
|
|
63
63
|
)
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
`}var
|
|
66
|
+
`}var et=s(()=>{"use strict"});function rt({pagesDir:t,matcherPath:e}){return`
|
|
67
67
|
import React from 'react'
|
|
68
68
|
import { createMatcher } from '${e}'
|
|
69
69
|
const pageFiles = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
@@ -91,7 +91,7 @@ export function getDefaultErrorPage() {
|
|
|
91
91
|
)
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
`}var
|
|
94
|
+
`}var ot=s(()=>{"use strict"});function nt({pagesDir:t,renderPath:e}){return`
|
|
95
95
|
import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${e}'
|
|
96
96
|
|
|
97
97
|
const _pages = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
@@ -114,7 +114,7 @@ export function runLoader(url, request, options) {
|
|
|
114
114
|
export function getStaticRoutes() {
|
|
115
115
|
return _getStaticRoutes(_glob)
|
|
116
116
|
}
|
|
117
|
-
`}var
|
|
117
|
+
`}var it=s(()=>{"use strict"});function st({apiPath:t,appDir:e}){return`
|
|
118
118
|
import { handleApiRequest as _handleApiRequest } from '${t}'
|
|
119
119
|
|
|
120
120
|
const _routes = import.meta.glob(['/${e}/api/**/*.ts', '!**/middleware.ts'])
|
|
@@ -129,14 +129,14 @@ const _glob = {
|
|
|
129
129
|
export function handleApiRequest(url, request) {
|
|
130
130
|
return _handleApiRequest(url, request, _glob)
|
|
131
131
|
}
|
|
132
|
-
`}var
|
|
132
|
+
`}var at=s(()=>{"use strict"});function $(t){return t.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var b=s(()=>{"use strict"});function D(){Yt=null}var Yt,ct=s(()=>{"use strict";b();Yt=null});function lt(t,e){let r=t.slice(e.length+1).replace(/\\/g,"/"),i=$(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}function C(){zt=null}var zt,A=s(()=>{"use strict";b();zt=null});function ut(){return`
|
|
133
133
|
export {RouterContext} from '@devlusoft/devix/runtime/context'
|
|
134
|
-
`}var
|
|
134
|
+
`}var pt=s(()=>{"use strict"});function Kt(t){return t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function dt(t){let e=new Set;for(let r of Kt(t).matchAll(Zt))e.add(r[1]);return[...e]}var Zt,mt=s(()=>{"use strict";Zt=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function Qt(t,e){return"_api_"+t.slice(`${e}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function ft(t,e,r){return{filePath:t,urlPattern:lt(t,e),identifier:Qt(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=t.map(o=>{let
|
|
139
|
-
`),i=t.flatMap(o=>o.methods.map(
|
|
138
|
+
`;let r=t.map(o=>{let a="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${a}'`}).join(`
|
|
139
|
+
`),i=t.flatMap(o=>o.methods.map(a=>` '${a} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${a}']>`)).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 M=
|
|
161
|
+
`}var M=s(()=>{"use strict";A()});import{readFileSync as te,readdirSync as ee,statSync as re}from"node:fs";import{join as I,relative as oe}from"node:path";function gt(t,e){let r=[];for(let i of ee(t)){let o=I(t,i);re(o).isDirectory()?r.push(...gt(o,e)):/\.(ts|tsx)$/.test(i)&&r.push(oe(e,o).replace(/\\/g,"/"))}return r}function L(t,e){let r=I(e,t,"api"),i;try{i=gt(r,e)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=te(I(e,o),"utf-8"),p=dt(a);return p.length===0?[]:[ft(o,`${t}/api`,p)]}catch{return[]}})}var ht=s(()=>{"use strict";mt();M()});import{mkdirSync as ne,readFileSync as ie,writeFileSync as se,existsSync as ae}from"node:fs";import{join as xt}from"node:path";function j(t,e){let r=xt(e,".devix"),i=xt(r,"routes.d.ts");return ne(r,{recursive:!0}),ae(i)&&ie(i,"utf-8")===t?!1:(se(i,t,"utf-8"),!0)}var yt=s(()=>{"use strict"});import{mergeConfig as ce}from"vite";import le from"@vitejs/plugin-react";import{fileURLToPath as ue}from"node:url";import{dirname as pe,resolve as m}from"node:path";import{parseSync as de}from"oxc-parser";function Rt(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,"/"),a=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===F)return`\0${F}`;if(n===U)return`\0${U}`;if(n===H)return`\0${H}`;if(n===q)return`\0${q}`;if(n===N)return`\0${N}`},load(n){if(n===`\0${F}`)return tt({cssUrls:i});if(n===`\0${U}`)return rt({pagesDir:r,matcherPath:p});if(n===`\0${H}`)return nt({pagesDir:r,renderPath:o});if(n===`\0${q}`)return st({apiPath:a,appDir:e});if(n===`\0${N}`)return ut()},transform(n,l,y){if(y?.ssr)return;let c=m(process.cwd(),r);if(!l.startsWith(c))return;let Nt=de(l,n,{sourceType:"module"}),v=[];for(let u of Nt.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let d=u.declaration;if(d.type==="FunctionDeclaration"&&d.id&&vt.has(d.id.name)&&v.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),v.push({start:u.start,end:u.end,name:T.id.name})))}}if(v.length===0)return;v.sort((u,d)=>d.start-u.start);let E=n;for(let{start:u,end:d,name:P}of v)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(),y=()=>{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(),y())}),n.watcher.on("unlink",c=>{c.startsWith(m(l,r))&&D(),c.includes(`${e}/api`)&&(C(),y())}),n.watcher.on("change",c=>{c.includes(`${e}/api`)&&!c.endsWith("middleware.ts")&&y()})}},g={plugins:[le(),x],publicDir:m(process.cwd(),t.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...t.envPrefix?{envPrefix:t.envPrefix}:{}};return ce(g,t.vite??{})}var k,F,U,H,q,N,vt,wt=s(()=>{"use strict";et();ot();it();at();ct();A();pt();ht();M();yt();k=pe(ue(import.meta.url)),F="virtual:devix/entry-client",U="virtual:devix/client-routes",H="virtual:devix/render",q="virtual:devix/api",N="virtual:devix/context",vt=new Set(["loader","guard","generateStaticParams","headers"])});function _t(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 Et=s(()=>{"use strict"});import{build as me}from"esbuild";import{join as Pt}from"node:path";import{unlinkSync as fe,writeFileSync as ge}from"node:fs";import{pathToFileURL as he}from"node:url";async function S(t){let e=await me({entryPoints:[Pt(t,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=Pt(t,`.devix-config-${Date.now()}.mjs`);ge(r,e.outputFiles[0].text);try{return(await import(he(r).href)).default}finally{fe(r)}}var V=s(()=>{"use strict"});var $t={};import{writeFileSync as xe}from"node:fs";import{resolve as ye}from"node:path";import{build as St}from"vite";var R,Tt,ve,B=s(async()=>{"use strict";wt();Et();V();R=await S(process.cwd()),Tt=Rt(R);await St({...Tt,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await St({...Tt,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});ve={port:R.port??3e3,host:R.host??!1,loaderTimeout:_t(R.loaderTimeout??1e4),output:R.output??"server"};xe(ye(process.cwd(),"dist/devix.config.json"),JSON.stringify(ve,null,2),"utf-8")});var Pe={};import{readFileSync as Re,mkdirSync as bt,writeFileSync as Dt,rmSync as we}from"node:fs";import{resolve as X,join as h}from"node:path";import{pathToFileURL as _e}from"node:url";var At,Ee,J,Ct,W,Ot=s(async()=>{"use strict";V();At=await S(process.cwd());At.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await B().then(()=>$t);Ee=Date.now(),J=await import(_e(X(process.cwd(),"dist/server/render.js")).href+`?t=${Ee}`),Ct=JSON.parse(Re(X(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),W=await J.getStaticRoutes();console.log(`[devix] Generating ${W.length} static page${W.length===1?"":"s"}...`);for(let t of W){let e=`http://localhost${t}`,{html:r,statusCode:i}=await J.render(e,new Request(e),{manifest:Ct});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");bt(h(o,".."),{recursive:!0}),Dt(o,`<!DOCTYPE html>${r}`,"utf-8");let a=await J.runLoader(e,new Request(e),{manifest:Ct}),p=t==="/"?h(process.cwd(),"dist/client/_data/index.json"):h(process.cwd(),"dist/client/_data",`${t}.json`);bt(h(p,".."),{recursive:!0}),Dt(p,JSON.stringify(a),"utf-8"),console.log(` \u2713 ${t}`)}console.log("[devix] Generation complete.");At.output==="static"&&(we(X(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function Mt(t,{apiModule:e,renderModule:r,loaderTimeout:i}){t.all("/api/*",async o=>{try{return await e.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),t.get("/_data/*",async o=>{try{let{pathname:a,search:p}=new URL(o.req.url,"http://localhost"),x=a.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(a){return console.error(a),o.json({error:"internal error"},500)}})}function It(t,{renderModule:e,manifest:r,loaderTimeout:i}){t.get("*",async o=>{try{let{html:a,statusCode:p,headers:x}=await e.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:i}),g=o.html(`<!DOCTYPE html>${a}`,p);for(let[n,l]of Object.entries(x))g.headers.set(n,l);return g}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Lt=s(()=>{"use strict"});import{loadEnv as Se}from"vite";function jt(t){let e=Se(t,process.cwd(),"");for(let[r,i]of Object.entries(e))process.env[r]===void 0&&(process.env[r]=i)}var kt=s(()=>{"use strict"});var Ae={};import{readFileSync as G}from"node:fs";import{serve as Te}from"@hono/node-server";import{serveStatic as $e}from"@hono/node-server/serve-static";import{Hono as be}from"hono";import{resolve as Ft,join as w}from"node:path";import{pathToFileURL as Ut}from"node:url";var Y,z,Z,f,De,Ce,_,K,Ht=s(async()=>{"use strict";Lt();kt();jt("production");try{f=JSON.parse(G(w(process.cwd(),"dist/devix.config.json"),"utf-8")),f.output!=="static"&&(Y=await import(Ut(Ft(process.cwd(),"dist/server/render.js")).href),z=await import(Ut(Ft(process.cwd(),"dist/server/api.js")).href)),Z=JSON.parse(G(w(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}De=Number(process.env.PORT)||f.port||3e3,Ce=typeof f.host=="string"?f.host:f.host?"0.0.0.0":process.env.HOST||"0.0.0.0",_=new be,K=w(process.cwd(),"dist/client");f.output==="static"&&_.get("/_data/*",t=>{let e=t.req.path.replace(/^\/_data/,"")||"/",r=e==="/"?w(K,"_data/index.json"):w(K,"_data",`${e}.json`);try{let i=G(r,"utf-8");return t.json(JSON.parse(i))}catch{return t.json({error:"not found"},404)}});_.use("/*",$e({root:K,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"):(Mt(_,{renderModule:Y,apiModule:z,manifest:Z}),It(_,{renderModule:Y,apiModule:z,manifest:Z,loaderTimeout:f.loaderTimeout}));Te({fetch:_.fetch,port:De,hostname:Ce},t=>console.log(`http://${t.address}:${t.port}`))});var qt=process.argv[2];switch(qt){case"dev":await Promise.resolve().then(()=>(Q(),Gt));break;case"build":await B().then(()=>$t);break;case"generate":await Ot().then(()=>Pe);break;case"start":await Ht().then(()=>Ae);break;case"--version":case"-v":{console.log("0.4.1-beta.9");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: ${
|
|
177
|
+
`.trim());break;default:console.error(`Unknown command: ${qt}`),console.error("Usage: devix <dev|build|generate|start>"),process.exit(1)}
|
|
178
178
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/cli/dev.ts", "../../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", "../../src/server/routes.ts", "../../src/utils/env.ts", "../../src/cli/start.ts", "../../src/cli/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { spawnSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nwhile (true) {\n const result = spawnSync(process.execPath, [resolve(__dirname, 'dev-server.js')], {\n stdio: 'inherit',\n env: process.env,\n })\n if (result.status !== 75) break\n}\n\nexport { }", "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", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n", "import { readFileSync } from 'node:fs'\nimport { serve } from '@hono/node-server'\nimport { serveStatic } from '@hono/node-server/serve-static'\nimport { Hono } from 'hono'\nimport { resolve, join } from 'node:path'\nimport type { Manifest } from 'vite'\nimport { registerApiRoutes, registerSsrRoute } from '../server/routes'\nimport { loadDotenv } from '../utils/env'\nimport {pathToFileURL} from \"node:url\"\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(pathToFileURL(join(process.cwd(), 'dist/devix.config.jso')).href, 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href)\n apiModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/api.js')).href)\n }\n manifest = JSON.parse(readFileSync(pathToFileURL(join(process.cwd(), 'dist/client/.vite/manifest.json')), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\nif (runtimeConfig!.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\/_data/, '') || '/'\n const filePath = pathname === '/'\n ? join(clientRoot, '_data/index.json')\n : join(clientRoot, '_data', `${pathname}.json`)\n\n try {\n const data = readFileSync(filePath, 'utf-8')\n return c.json(JSON.parse(data))\n } catch {\n return c.json({ error: 'not found' }, 404)\n }\n })\n}\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, { renderModule, apiModule, manifest })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout })\n}\n\nserve({ fetch: app.fetch, port, hostname: host }, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport { }", "#!/usr/bin/env node\ndeclare const __DEVIX_VERSION__: string\n\nconst command = process.argv[2]\n\nswitch (command) {\n case 'dev':\n await import(\"./dev.js\")\n break\n case \"build\":\n await import(\"./build.js\")\n break\n case \"generate\":\n await import(\"./generate.js\")\n break\n case \"start\":\n await import(\"./start.js\")\n break\n case '--version':\n case '-v': {\n console.log(__DEVIX_VERSION__)\n break\n }\n case '--help':\n case '-h':\n console.log(`\ndevix \u2014 a lightweight SSR framework\n\nUsage:\n devix dev Start development server\n devix build Build for production\n devix generate Build and generate static HTML (SSG)\n devix start Start production server\n\nOptions:\n -v, --version Show version\n -h, --help Show this help\n\nOutput modes (set in devix.config.ts):\n output: \"server\" SSR mode \u2014 devix start handles requests dynamically (default)\n output: \"static\" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only\n `.trim())\n break\n default:\n console.error(`Unknown command: ${command}`)\n console.error('Usage: devix <dev|build|generate|start>')\n process.exit(1)\n}\n\nexport {}"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["dev_exports", "spawnSync", "fileURLToPath", "dirname", "resolve", "__dirname", "init_dev", "__esmMin", "generateEntryClient", "cssUrls", "u", "init_entry_client", "__esmMin", "generateClientRoutes", "pagesDir", "matcherPath", "init_client_routes", "__esmMin", "generateRender", "pagesDir", "renderPath", "init_render", "__esmMin", "generateApi", "apiPath", "appDir", "init_api", "__esmMin", "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", "
|
|
3
|
+
"sources": ["../../src/cli/dev.ts", "../../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/utils/load-config.ts", "../../src/cli/build.ts", "../../src/cli/generate.ts", "../../src/server/routes.ts", "../../src/utils/env.ts", "../../src/cli/start.ts", "../../src/cli/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { spawnSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nwhile (true) {\n const result = spawnSync(process.execPath, [resolve(__dirname, 'dev-server.js')], {\n stdio: 'inherit',\n env: process.env,\n })\n if (result.status !== 75) break\n}\n\nexport { }", "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 {build} from 'esbuild'\nimport type {DevixConfig} from \"../config\"\nimport {join} from \"node:path\"\nimport {unlinkSync, writeFileSync} from \"node:fs\";\nimport {pathToFileURL} from \"node:url\";\n\nexport async function loadConfig(cwd: string): Promise<DevixConfig> {\n const result = await build({\n entryPoints: [join(cwd, 'devix.config.ts')],\n bundle: true,\n write: false,\n format: 'esm',\n platform: 'node',\n packages: 'external',\n })\n\n const tmpFile = join(cwd, `.devix-config-${Date.now()}.mjs`)\n writeFileSync(tmpFile, result.outputFiles[0].text)\n\n try {\n const mod = await import(pathToFileURL(tmpFile).href)\n return mod.default\n } finally {\n unlinkSync(tmpFile)\n }\n}", "import {writeFileSync} from 'node:fs'\nimport {resolve} from 'node:path'\nimport {build} from 'vite'\nimport {devix} from '../vite'\nimport {parseDuration} from '../utils/duration'\nimport {loadConfig} from \"../utils/load-config\";\n\nconst config = await loadConfig(process.cwd())\nconst baseConfig = devix(config)\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n outDir: 'dist/client',\n manifest: true,\n rolldownOptions: {\n input: 'virtual:devix/entry-client',\n },\n },\n})\n\nawait build({\n ...baseConfig,\n configFile: false,\n build: {\n ssr: true,\n outDir: 'dist/server',\n copyPublicDir: false,\n rolldownOptions: {\n input: {\n render: 'virtual:devix/render',\n api: 'virtual:devix/api',\n },\n },\n },\n})\n\nconst runtimeConfig = {\n port: config.port ?? 3000,\n host: config.host ?? false,\n loaderTimeout: parseDuration(config.loaderTimeout ?? 10_000),\n output: config.output ?? 'server',\n}\n\nwriteFileSync(\n resolve(process.cwd(), 'dist/devix.config.json'),\n JSON.stringify(runtimeConfig, null, 2),\n 'utf-8'\n)\n\n\nexport {}", "import {readFileSync, mkdirSync, writeFileSync, rmSync} from 'node:fs'\nimport {resolve, join} from 'node:path'\nimport type {Manifest} from 'vite'\nimport { pathToFileURL } from \"node:url\"\nimport {loadConfig} from \"../utils/load-config\";\n\nconst userConfig = await loadConfig(process.cwd())\nif (userConfig.output !== 'static') {\n console.warn('[devix] Tip: set output: \"static\" in devix.config.ts to skip the SSR server at runtime.')\n}\n\nawait import('./build.js')\n\nconst t = Date.now()\nconst renderModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href + `?t=${t}`)\n\nconst manifest: Manifest = JSON.parse(\n readFileSync(resolve(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8')\n)\n\nconst urls: string[] = await renderModule.getStaticRoutes()\n\nconsole.log(`[devix] Generating ${urls.length} static page${urls.length === 1 ? '' : 's'}...`)\n\nfor (const url of urls) {\n const fullUrl = `http://localhost${url}`\n const {html, statusCode} = await renderModule.render(fullUrl, new Request(fullUrl), {manifest})\n\n if (statusCode !== 200) {\n console.warn(`[devix] Skipping ${url} \u2014 status ${statusCode}`)\n continue\n }\n\n const outPath = url === '/'\n ? join(process.cwd(), 'dist/client/index.html')\n : join(process.cwd(), 'dist/client', url, 'index.html')\n\n mkdirSync(join(outPath, '..'), {recursive: true})\n writeFileSync(outPath, `<!DOCTYPE html>${html}`, 'utf-8')\n\n const data = await renderModule.runLoader(fullUrl, new Request(fullUrl), {manifest})\n const dataPath = url === '/'\n ? join(process.cwd(), 'dist/client/_data/index.json')\n : join(process.cwd(), 'dist/client/_data', `${url}.json`)\n \n mkdirSync(join(dataPath, '..'), {recursive: true})\n writeFileSync(dataPath, JSON.stringify(data), 'utf-8')\n\n console.log(` \u2713 ${url}`)\n}\n\nconsole.log('[devix] Generation complete.')\n\nif (userConfig.output === 'static') {\n rmSync(resolve(process.cwd(), 'dist/server'), { recursive: true, force: true })\n console.log('[devix] Removed dist/server (not needed in static mode)')\n}\n\nexport {}\n", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n", "import { readFileSync } from 'node:fs'\nimport { serve } from '@hono/node-server'\nimport { serveStatic } from '@hono/node-server/serve-static'\nimport { Hono } from 'hono'\nimport { resolve, join } from 'node:path'\nimport type { Manifest } from 'vite'\nimport { registerApiRoutes, registerSsrRoute } from '../server/routes'\nimport { loadDotenv } from '../utils/env'\nimport {pathToFileURL} from \"node:url\"\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(join(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href)\n apiModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/api.js')).href)\n }\n manifest = JSON.parse(readFileSync(join(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\nif (runtimeConfig!.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\/_data/, '') || '/'\n const filePath = pathname === '/'\n ? join(clientRoot, '_data/index.json')\n : join(clientRoot, '_data', `${pathname}.json`)\n\n try {\n const data = readFileSync(filePath, 'utf-8')\n return c.json(JSON.parse(data))\n } catch {\n return c.json({ error: 'not found' }, 404)\n }\n })\n}\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, { renderModule, apiModule, manifest })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout })\n}\n\nserve({ fetch: app.fetch, port, hostname: host }, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport { }", "#!/usr/bin/env node\ndeclare const __DEVIX_VERSION__: string\n\nconst command = process.argv[2]\n\nswitch (command) {\n case 'dev':\n await import(\"./dev.js\")\n break\n case \"build\":\n await import(\"./build.js\")\n break\n case \"generate\":\n await import(\"./generate.js\")\n break\n case \"start\":\n await import(\"./start.js\")\n break\n case '--version':\n case '-v': {\n console.log(__DEVIX_VERSION__)\n break\n }\n case '--help':\n case '-h':\n console.log(`\ndevix \u2014 a lightweight SSR framework\n\nUsage:\n devix dev Start development server\n devix build Build for production\n devix generate Build and generate static HTML (SSG)\n devix start Start production server\n\nOptions:\n -v, --version Show version\n -h, --help Show this help\n\nOutput modes (set in devix.config.ts):\n output: \"server\" SSR mode \u2014 devix start handles requests dynamically (default)\n output: \"static\" SSG mode \u2014 devix generate pre-renders all pages; devix start serves static files only\n `.trim())\n break\n default:\n console.error(`Unknown command: ${command}`)\n console.error('Usage: devix <dev|build|generate|start>')\n process.exit(1)\n}\n\nexport {}"],
|
|
5
|
+
"mappings": ";mCAAA,IAAAA,GAAA,UAAS,aAAAC,OAAiB,qBAC1B,OAAS,iBAAAC,OAAqB,WAC9B,OAAS,WAAAC,GAAS,WAAAC,OAAe,YAFjC,IAIMC,GAJNC,EAAAC,EAAA,kBAIMF,GAAYF,GAAQD,GAAc,YAAY,GAAG,CAAC,EAExD,KACmBD,GAAU,QAAQ,SAAU,CAACG,GAAQC,GAAW,eAAe,CAAC,EAAG,CAC9E,MAAO,UACP,IAAK,QAAQ,GACjB,CAAC,EACU,SAAW,IAAtB,ICPG,SAASG,GAAoB,CAAE,QAAAC,CAAQ,EAA+B,CAGzE,MAAO;AAAA,EAFYA,EAAQ,IAAIC,GAAK,WAAWA,CAAC,GAAG,EAAE,KAAK;AAAA,CAAI,CAGtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA+DZ,CAvEA,IAAAC,GAAAC,EAAA,oBCKO,SAASC,GAAqB,CAAC,SAAAC,EAAU,YAAAC,CAAW,EAAwB,CAC/E,MAAO;AAAA;AAAA,iCAEsBA,CAAW;AAAA,wCACJD,CAAQ;AAAA,yCACPA,CAAQ;AAAA,wCACTA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAwBhD,CAnCA,IAAAE,GAAAC,EAAA,oBCKO,SAASC,GAAe,CAAC,SAAAC,EAAU,WAAAC,CAAU,EAA0B,CAC1E,MAAO;AAAA,mGACwFA,CAAU;AAAA;AAAA,qCAExED,CAAQ;AAAA,sCACPA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,kBAK5BA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAe1B,CA9BA,IAAAE,GAAAC,EAAA,oBCKO,SAASC,GAAY,CAAC,QAAAC,EAAS,OAAAC,CAAM,EAAuB,CAC/D,MAAO;AAAA,yDAC8CD,CAAO;AAAA;AAAA,sCAE1BC,CAAM;AAAA,0CACFA,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKhCA,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAOtB,CAtBA,IAAAC,GAAAC,EAAA,oBCAO,SAASC,EAAaC,EAAqB,CAC9C,OAAOA,EACE,QAAQ,qBAAsB,EAAE,EAChC,QAAQ,aAAc,EAAE,EACxB,QAAQ,mBAAoB,EAAE,EAC9B,QAAQ,eAAgB,KAAK,GAC/B,GACX,CAPA,IAAAC,EAAAC,EAAA,oBC+BO,SAASC,GAAuB,CACnCC,GAAQ,IACZ,CAjCA,IA6BIA,GA7BJC,GAAAC,EAAA,kBAAAC,IA6BIH,GAA4B,OCVzB,SAASI,GAAkBC,EAAaC,EAAwB,CACnE,IAAMC,EAAMF,EAAI,MAAMC,EAAO,OAAS,CAAC,EAAE,QAAQ,MAAO,GAAG,EACrDE,EAAUC,EAAaF,CAAG,EAChC,OAAOC,IAAY,IAAM,OAAS,QAAQA,CAAO,GAAG,QAAQ,SAAU,OAAO,CACjF,CAQO,SAASE,GAAqB,CACjCC,GAAQ,IACZ,CAjCA,IA6BIA,GA7BJC,EAAAC,EAAA,kBAAAC,IA6BIH,GAA0B,OC7BvB,SAASI,IAA0B,CACtC,MAAO;AAAA;AAAA,CAGX,CAJA,IAAAC,GAAAC,EAAA,oBCKA,SAASC,GAAcC,EAAyB,CAC5C,OAAOA,EACF,QAAQ,oBAAqB,EAAE,EAC/B,QAAQ,YAAa,EAAE,CAChC,CAEO,SAASC,GAAmBD,EAA+B,CAC9D,IAAME,EAAQ,IAAI,IAClB,QAAWC,KAASJ,GAAcC,CAAO,EAAE,SAASI,EAAgB,EAChEF,EAAM,IAAIC,EAAM,CAAC,CAAe,EAEpC,MAAO,CAAC,GAAGD,CAAK,CACpB,CAjBA,IAGME,GAHNC,GAAAC,EAAA,kBAGMF,GAAmB,+FCOlB,SAASG,GAAqBC,EAAkBC,EAAwB,CAC3E,MAAO,QAAUD,EACZ,MAAM,GAAGC,CAAM,IAAI,MAAM,EACzB,QAAQ,cAAe,EAAE,EACzB,QAAQ,gBAAiB,GAAG,CACrC,CAEO,SAASC,GAAgBF,EAAkBC,EAAgBE,EAAmC,CACjG,MAAO,CACH,SAAAH,EACA,WAAYI,GAAkBJ,EAAUC,CAAM,EAC9C,WAAYF,GAAqBC,EAAUC,CAAM,EACjD,QAAAE,CACJ,CACJ,CAEO,SAASE,EAAkBC,EAAuBL,EAAwB,CAC7E,GAAIK,EAAQ,SAAW,EACnB,MAAO;AAAA;AAAA;AAAA;AAAA,EAGX,IAAMC,EAAUD,EACX,IAAIE,GAAK,CACN,IAAMC,EAAa,MAAQD,EAAE,SAAS,QAAQ,cAAe,EAAE,EAC/D,MAAO,oBAAoBA,EAAE,UAAU,UAAUC,CAAU,GAC/D,CAAC,EACA,KAAK;AAAA,CAAI,EAERC,EAAaJ,EAAQ,QAAQE,GAC/BA,EAAE,QAAQ,IAAIG,GACV,QAAQA,CAAC,IAAIH,EAAE,UAAU,yBAAyBA,EAAE,UAAU,MAAMG,CAAC,KACzE,CACJ,EAAE,KAAK;AAAA,CAAI,EAEX,MAAO;AAAA,EACTJ,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBPG,CAAU;AAAA;AAAA;AAAA,CAIZ,CAlEA,IAAAE,EAAAC,EAAA,kBAAAC,MCAA,OAAQ,gBAAAC,GAAc,eAAAC,GAAa,YAAAC,OAAe,UAClD,OAAQ,QAAAC,EAAM,YAAAC,OAAe,YAK7B,SAASC,GAAQC,EAAaC,EAAwB,CAClD,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQR,GAAYK,CAAG,EAAG,CACjC,IAAMI,EAAOP,EAAKG,EAAKG,CAAI,EACvBP,GAASQ,CAAI,EAAE,YAAY,EAC3BF,EAAQ,KAAK,GAAGH,GAAQK,EAAMH,CAAI,CAAC,EAC5B,cAAc,KAAKE,CAAI,GAC9BD,EAAQ,KAAKJ,GAASG,EAAMG,CAAI,EAAE,QAAQ,MAAO,GAAG,CAAC,CAE7D,CACA,OAAOF,CACX,CAEO,SAASG,EAAaC,EAAgBC,EAAmC,CAC5E,IAAMC,EAASX,EAAKU,EAAaD,EAAQ,KAAK,EAE1CG,EACJ,GAAI,CACAA,EAAQV,GAAQS,EAAQD,CAAW,CACvC,MAAQ,CACJ,MAAO,CAAC,CACZ,CAEA,OAAOE,EACF,OAAOC,GAAK,CAACA,EAAE,SAAS,eAAe,GAAK,CAACA,EAAE,SAAS,gBAAgB,CAAC,EACzE,QAAQC,GAAY,CACjB,GAAI,CACA,IAAMC,EAAUlB,GAAaG,EAAKU,EAAaI,CAAQ,EAAG,OAAO,EAC3DE,EAAUC,GAAmBF,CAAO,EAC1C,OAAIC,EAAQ,SAAW,EAAU,CAAC,EAC3B,CAACE,GAAgBJ,EAAU,GAAGL,CAAM,OAAQO,CAAO,CAAC,CAC/D,MAAQ,CACJ,MAAO,CAAC,CACZ,CACJ,CAAC,CACT,CAzCA,IAAAG,GAAAC,EAAA,kBAEAC,KACAC,MCHA,OAAQ,aAAAC,GAAW,gBAAAC,GAAc,iBAAAC,GAAe,cAAAC,OAAiB,UACjE,OAAQ,QAAAC,OAAW,YAEZ,SAASC,EAAeC,EAAiBC,EAA8B,CAC1E,IAAMC,EAAWJ,GAAKG,EAAa,QAAQ,EACrCE,EAAUL,GAAKI,EAAU,aAAa,EAI5C,OAFAR,GAAUQ,EAAU,CAAC,UAAW,EAAI,CAAC,EAEjCL,GAAWM,CAAO,GAAKR,GAAaQ,EAAS,OAAO,IAAMH,EACnD,IAGXJ,GAAcO,EAASH,EAAS,OAAO,EAChC,GACX,CAfA,IAAAI,GAAAC,EAAA,oBCAA,OAA6B,eAAAC,OAAmB,OAEhD,OAAOC,OAAW,uBAClB,OAAS,iBAAAC,OAAqB,WAC9B,OAAS,WAAAC,GAAS,WAAAC,MAAe,YAWjC,OAAS,aAAAC,OAAiB,aAYnB,SAASC,GAAMC,EAAiC,CACnD,IAAMC,EAASD,EAAO,QAAU,MAC1BE,EAAW,GAAGD,CAAM,SACpBE,GAAWH,EAAO,KAAO,CAAC,GAAG,IAAII,GAAKA,EAAE,WAAW,GAAG,EAAIA,EAAI,IAAIA,EAAE,QAAQ,QAAS,EAAE,CAAC,EAAE,EAE1FC,EAAaR,EAAQS,EAAW,qBAAqB,EAAE,QAAQ,MAAO,GAAG,EACzEC,EAAUV,EAAQS,EAAW,kBAAkB,EAAE,QAAQ,MAAO,GAAG,EACnEE,EAAcX,EAAQS,EAAW,6BAA6B,EAAE,QAAQ,MAAO,GAAG,EAElFG,EAAwB,CAC1B,KAAM,QACN,QAAS,MAET,UAAUC,EAAI,CACV,GAAIA,IAAOC,EAAsB,MAAO,KAAKA,CAAoB,GACjE,GAAID,IAAOE,EAAuB,MAAO,KAAKA,CAAqB,GACnE,GAAIF,IAAOG,EAAgB,MAAO,KAAKA,CAAc,GACrD,GAAIH,IAAOI,EAAa,MAAO,KAAKA,CAAW,GAC/C,GAAIJ,IAAOK,EAAiB,MAAO,KAAKA,CAAe,EAC3D,EAEA,KAAKL,EAAI,CACL,GAAIA,IAAO,KAAKC,CAAoB,GAChC,OAAOK,GAAoB,CAAE,QAAAb,CAAQ,CAAC,EAC1C,GAAIO,IAAO,KAAKE,CAAqB,GACjC,OAAOK,GAAqB,CAAE,SAAAf,EAAU,YAAAM,CAAY,CAAC,EACzD,GAAIE,IAAO,KAAKG,CAAc,GAC1B,OAAOK,GAAe,CAAE,SAAAhB,EAAU,WAAAG,CAAW,CAAC,EAClD,GAAIK,IAAO,KAAKI,CAAW,GACvB,OAAOK,GAAY,CAAE,QAAAZ,EAAS,OAAAN,CAAO,CAAC,EAC1C,GAAIS,IAAO,KAAKK,CAAe,GAC3B,OAAOK,GAAgB,CAC/B,EAGA,UAAUC,EAAMX,EAAIY,EAAS,CACzB,GAAIA,GAAS,IAAK,OAElB,IAAMC,EAAmB1B,EAAQ,QAAQ,IAAI,EAAGK,CAAQ,EACxD,GAAI,CAACQ,EAAG,WAAWa,CAAgB,EAAG,OAEtC,IAAMC,GAAM1B,GAAUY,EAAIW,EAAM,CAAE,WAAY,QAAS,CAAC,EAElDI,EAA+D,CAAC,EAEtE,QAAWC,KAAQF,GAAI,QAAQ,KAAM,CACjC,GAAIE,EAAK,OAAS,0BAA4B,CAACA,EAAK,YAAa,SAEjE,IAAMC,EAAOD,EAAK,YAMlB,GAJIC,EAAK,OAAS,uBAAyBA,EAAK,IAAMC,GAAe,IAAID,EAAK,GAAG,IAAI,GACjFF,EAAa,KAAK,CAAE,MAAOC,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAMC,EAAK,GAAG,IAAK,CAAC,EAG1EA,EAAK,OAAS,sBAAuB,CACrC,IAAME,EAAO,IAAI,IACjB,QAAWC,KAAcH,EAAK,aACtBG,EAAW,GAAG,OAAS,cAAgBF,GAAe,IAAIE,EAAW,GAAG,IAAI,IACvED,EAAK,IAAIH,EAAK,KAAK,IACpBG,EAAK,IAAIH,EAAK,KAAK,EACnBD,EAAa,KAAK,CAAE,MAAOC,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAMI,EAAW,GAAG,IAAK,CAAC,GAIhG,CACJ,CAEA,GAAIL,EAAa,SAAW,EAAG,OAE/BA,EAAa,KAAK,CAACM,EAAGC,IAAMA,EAAE,MAAQD,EAAE,KAAK,EAE7C,IAAIE,EAASZ,EACb,OAAW,CAAE,MAAAa,EAAO,IAAAC,EAAK,KAAAC,CAAK,IAAKX,EAC/BQ,EAASA,EAAO,MAAM,EAAGC,CAAK,EAAI,gBAAgBE,CAAI,eAAiBH,EAAO,MAAME,CAAG,EAG3F,MAAO,CAAE,KAAMF,EAAQ,IAAK,IAAK,CACrC,EAEA,YAAa,CACT,IAAMI,EAAO,QAAQ,IAAI,EACnBC,EAAUC,EAAatC,EAAQoC,CAAI,EACzCG,EAAeC,EAAkBH,EAAS,GAAGrC,CAAM,MAAM,EAAGoC,CAAI,CACpE,EAEA,gBAAgBK,EAAQ,CACpB,IAAML,EAAO,QAAQ,IAAI,EAEnBM,EAAgB,IAAM,CACxB,IAAML,EAAUC,EAAatC,EAAQoC,CAAI,EACzCG,EAAeC,EAAkBH,EAAS,GAAGrC,CAAM,MAAM,EAAGoC,CAAI,CACpE,EAEAK,EAAO,QAAQ,IAAI7C,EAAQwC,EAAM,iBAAiB,CAAC,EACnDK,EAAO,QAAQ,GAAG,SAAWE,GAAS,CAC9BA,IAAS/C,EAAQwC,EAAM,iBAAiB,IACxC,QAAQ,IAAI,uCAAuC,EACnD,QAAQ,KAAK,EAAE,EAEvB,CAAC,EAEDK,EAAO,QAAQ,GAAG,MAAQE,GAAS,CAC3BA,EAAK,WAAW/C,EAAQwC,EAAMnC,CAAQ,CAAC,GAAG2C,EAAqB,EAC/DD,EAAK,SAAS,GAAG3C,CAAM,MAAM,IAAK6C,EAAmB,EAAGH,EAAc,EAC9E,CAAC,EACDD,EAAO,QAAQ,GAAG,SAAWE,GAAS,CAC9BA,EAAK,WAAW/C,EAAQwC,EAAMnC,CAAQ,CAAC,GAAG2C,EAAqB,EAC/DD,EAAK,SAAS,GAAG3C,CAAM,MAAM,IAAK6C,EAAmB,EAAGH,EAAc,EAC9E,CAAC,EACDD,EAAO,QAAQ,GAAG,SAAWE,GAAS,CAC9BA,EAAK,SAAS,GAAG3C,CAAM,MAAM,GAAK,CAAC2C,EAAK,SAAS,eAAe,GAChED,EAAc,CAEtB,CAAC,CACL,CACJ,EAEMI,EAAmB,CACrB,QAAS,CAACrD,GAAM,EAAGe,CAAa,EAChC,UAAWZ,EAAQ,QAAQ,IAAI,EAAGG,EAAO,WAAa,QAAQ,EAC9D,IAAK,CAAE,WAAY,CAAC,kBAAkB,CAAE,EACxC,GAAIA,EAAO,UAAY,CAAE,UAAWA,EAAO,SAAU,EAAI,CAAC,CAC9D,EAEA,OAAOP,GAAYsD,EAAM/C,EAAO,MAAQ,CAAC,CAAC,CAC9C,CAxJA,IAiBMM,EAEAK,EACAC,EACAC,EACAC,EACAC,EAEAa,GAzBNoB,GAAAC,EAAA,kBAKAC,KACAC,KACAC,KACAC,KACAC,KACAC,IACAC,KACAC,KACAC,IACAC,KAGMrD,EAAYV,GAAQD,GAAc,YAAY,GAAG,CAAC,EAElDgB,EAAuB,6BACvBC,EAAwB,8BACxBC,EAAiB,uBACjBC,EAAc,oBACdC,EAAkB,wBAElBa,GAAiB,IAAI,IAAI,CAAC,SAAU,QAAS,uBAAwB,SAAS,CAAC,ICzB9E,SAASgC,GAAcC,EAAgC,CAC1D,GAAI,OAAOA,GAAU,SAAU,OAAOA,EACtC,IAAMC,EAAQD,EAAM,KAAK,EAAE,MAAM,iCAAiC,EAClE,GAAI,CAACC,EAAO,MAAM,IAAI,MAAM,8BAA8BD,CAAK,4DAA4D,EAC3H,IAAME,EAAI,WAAWD,EAAM,CAAC,CAAC,EAC7B,OAAQA,EAAM,CAAC,EAAG,CACd,IAAK,IAAM,OAAOC,EAAI,KACtB,IAAK,IAAM,OAAOA,EAAI,IACtB,IAAK,IAAM,OAAOA,EAAI,IAEtB,QAAW,OAAOA,CACtB,CACJ,CAZA,IAAAC,GAAAC,EAAA,oBCAA,OAAQ,SAAAC,OAAY,UAEpB,OAAQ,QAAAC,OAAW,YACnB,OAAQ,cAAAC,GAAY,iBAAAC,OAAoB,UACxC,OAAQ,iBAAAC,OAAoB,WAE5B,eAAsBC,EAAWC,EAAmC,CAChE,IAAMC,EAAS,MAAMP,GAAM,CACvB,YAAa,CAACC,GAAKK,EAAK,iBAAiB,CAAC,EAC1C,OAAQ,GACR,MAAO,GACP,OAAQ,MACR,SAAU,OACV,SAAU,UACd,CAAC,EAEKE,EAAUP,GAAKK,EAAK,iBAAiB,KAAK,IAAI,CAAC,MAAM,EAC3DH,GAAcK,EAASD,EAAO,YAAY,CAAC,EAAE,IAAI,EAEjD,GAAI,CAEA,OADY,MAAM,OAAOH,GAAcI,CAAO,EAAE,OACrC,OACf,QAAE,CACEN,GAAWM,CAAO,CACtB,CACJ,CAzBA,IAAAC,EAAAC,EAAA,oBCAA,IAAAC,GAAA,UAAQ,iBAAAC,OAAoB,UAC5B,OAAQ,WAAAC,OAAc,YACtB,OAAQ,SAAAC,OAAY,OAFpB,IAOMC,EACAC,GA8BAC,GAtCNC,EAAAC,EAAA,uBAGAC,KACAC,KACAC,IAEMP,EAAS,MAAMQ,EAAW,QAAQ,IAAI,CAAC,EACvCP,GAAaQ,GAAMT,CAAM,EAE/B,MAAMD,GAAM,CACR,GAAGE,GACH,WAAY,GACZ,MAAO,CACH,OAAQ,cACR,SAAU,GACV,gBAAiB,CACb,MAAO,4BACX,CACJ,CACJ,CAAC,EAED,MAAMF,GAAM,CACR,GAAGE,GACH,WAAY,GACZ,MAAO,CACH,IAAK,GACL,OAAQ,cACR,cAAe,GACf,gBAAiB,CACb,MAAO,CACH,OAAQ,uBACR,IAAK,mBACT,CACJ,CACJ,CACJ,CAAC,EAEKC,GAAgB,CAClB,KAAMF,EAAO,MAAQ,IACrB,KAAMA,EAAO,MAAQ,GACrB,cAAeU,GAAcV,EAAO,eAAiB,GAAM,EAC3D,OAAQA,EAAO,QAAU,QAC7B,EAEAH,GACIC,GAAQ,QAAQ,IAAI,EAAG,wBAAwB,EAC/C,KAAK,UAAUI,GAAe,KAAM,CAAC,EACrC,OACJ,ICjDA,IAAAS,GAAA,UAAQ,gBAAAC,GAAc,aAAAC,GAAW,iBAAAC,GAAe,UAAAC,OAAa,UAC7D,OAAQ,WAAAC,EAAS,QAAAC,MAAW,YAE5B,OAAS,iBAAAC,OAAqB,WAH9B,IAMMC,GAOAC,GACAC,EAEAC,GAIAC,EApBNC,GAAAC,EAAA,uBAIAC,IAEMP,GAAa,MAAMQ,EAAW,QAAQ,IAAI,CAAC,EAC7CR,GAAW,SAAW,UACtB,QAAQ,KAAK,yFAAyF,EAG1G,KAAM,kBAEAC,GAAI,KAAK,IAAI,EACbC,EAAe,MAAM,OAAOH,GAAcF,EAAQ,QAAQ,IAAI,EAAG,uBAAuB,CAAC,EAAE,KAAO,MAAMI,EAAC,IAEzGE,GAAqB,KAAK,MAC5BV,GAAaI,EAAQ,QAAQ,IAAI,EAAG,iCAAiC,EAAG,OAAO,CACnF,EAEMO,EAAiB,MAAMF,EAAa,gBAAgB,EAE1D,QAAQ,IAAI,sBAAsBE,EAAK,MAAM,eAAeA,EAAK,SAAW,EAAI,GAAK,GAAG,KAAK,EAE7F,QAAWK,KAAOL,EAAM,CACpB,IAAMM,EAAU,mBAAmBD,CAAG,GAChC,CAAC,KAAAE,EAAM,WAAAC,CAAU,EAAI,MAAMV,EAAa,OAAOQ,EAAS,IAAI,QAAQA,CAAO,EAAG,CAAC,SAAAP,EAAQ,CAAC,EAE9F,GAAIS,IAAe,IAAK,CACpB,QAAQ,KAAK,oBAAoBH,CAAG,kBAAaG,CAAU,EAAE,EAC7D,QACJ,CAEA,IAAMC,EAAUJ,IAAQ,IAClBX,EAAK,QAAQ,IAAI,EAAG,wBAAwB,EAC5CA,EAAK,QAAQ,IAAI,EAAG,cAAeW,EAAK,YAAY,EAE1Df,GAAUI,EAAKe,EAAS,IAAI,EAAG,CAAC,UAAW,EAAI,CAAC,EAChDlB,GAAckB,EAAS,kBAAkBF,CAAI,GAAI,OAAO,EAExD,IAAMG,EAAO,MAAMZ,EAAa,UAAUQ,EAAS,IAAI,QAAQA,CAAO,EAAG,CAAC,SAAAP,EAAQ,CAAC,EAC7EY,EAAWN,IAAQ,IACnBX,EAAK,QAAQ,IAAI,EAAG,8BAA8B,EAClDA,EAAK,QAAQ,IAAI,EAAG,oBAAqB,GAAGW,CAAG,OAAO,EAE5Df,GAAUI,EAAKiB,EAAU,IAAI,EAAG,CAAC,UAAW,EAAI,CAAC,EACjDpB,GAAcoB,EAAU,KAAK,UAAUD,CAAI,EAAG,OAAO,EAErD,QAAQ,IAAI,YAAOL,CAAG,EAAE,CAC5B,CAEA,QAAQ,IAAI,8BAA8B,EAEtCT,GAAW,SAAW,WACtBJ,GAAOC,EAAQ,QAAQ,IAAI,EAAG,aAAa,EAAG,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAC9E,QAAQ,IAAI,yDAAyD,KC7ClE,SAASmB,GAAkBC,EAAW,CAAC,UAAAC,EAAW,aAAAC,EAAc,cAAAC,CAAa,EAAkB,CAClGH,EAAI,IAAI,SAAU,MAAOI,GAAM,CAC3B,GAAI,CACA,OAAO,MAAMH,EAAU,iBAAiBG,EAAE,IAAI,IAAKA,EAAE,IAAI,GAAG,CAChE,OAASC,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,EAEDJ,EAAI,IAAI,WAAY,MAAOI,GAAM,CAC7B,GAAI,CACA,GAAM,CAAC,SAAAE,EAAU,OAAAC,CAAM,EAAI,IAAI,IAAIH,EAAE,IAAI,IAAK,kBAAkB,EAC1DI,EAAMF,EAAS,QAAQ,WAAY,EAAE,EAAIC,EAEzCE,EAAO,MAAMP,EAAa,UAAUM,EAAKJ,EAAE,IAAI,IAAK,CAAC,cAAAD,CAAa,CAAC,EACzE,OAAIM,EAAK,MAAcL,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,EACrDA,EAAE,KAAKK,CAAI,CACtB,OAASJ,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,CACL,CAEO,SAASM,GAAiBV,EAAW,CAAC,aAAAE,EAAc,SAAAS,EAAU,cAAAR,CAAa,EAAkB,CAChGH,EAAI,IAAI,IAAK,MAAOI,GAAM,CACtB,GAAI,CACA,GAAM,CAAC,KAAAQ,EAAM,WAAAC,EAAY,QAAAC,CAAO,EAAI,MAAMZ,EAAa,OAAOE,EAAE,IAAI,IAAKA,EAAE,IAAI,IAAK,CAAC,SAAAO,EAAU,cAAAR,CAAa,CAAC,EACvGY,EAAMX,EAAE,KAAK,kBAAkBQ,CAAI,GAAIC,CAAU,EACvD,OAAW,CAACG,EAAKC,CAAK,IAAK,OAAO,QAAQH,CAAiC,EACvEC,EAAI,QAAQ,IAAIC,EAAKC,CAAK,EAE9B,OAAOF,CACX,OAASV,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,wBAAyB,GAAG,CAC9C,CACJ,CAAC,CACL,CAjDA,IAAAc,GAAAC,EAAA,oBCAA,OAAQ,WAAAC,OAAc,OAEf,SAASC,GAAWC,EAAc,CACrC,IAAMC,EAAMH,GAAQE,EAAM,QAAQ,IAAI,EAAG,EAAE,EAC3C,OAAW,CAACE,EAAKC,CAAK,IAAK,OAAO,QAAQF,CAAG,EACrC,QAAQ,IAAIC,CAAG,IAAM,SACrB,QAAQ,IAAIA,CAAG,EAAIC,EAG/B,CATA,IAAAC,GAAAC,EAAA,oBCAA,IAAAC,GAAA,UAAS,gBAAAC,MAAoB,UAC7B,OAAS,SAAAC,OAAa,oBACtB,OAAS,eAAAC,OAAmB,iCAC5B,OAAS,QAAAC,OAAY,OACrB,OAAS,WAAAC,GAAS,QAAAC,MAAY,YAI9B,OAAQ,iBAAAC,OAAoB,WAR5B,IAYIC,EACAC,EACAC,EACAC,EAcEC,GACAC,GAIAC,EAEAC,EApCNC,GAAAC,EAAA,uBAMAC,KACAC,KAGAC,GAAW,YAAY,EAOvB,GAAI,CACAT,EAAgB,KAAK,MAAMV,EAAaK,EAAK,QAAQ,IAAI,EAAG,wBAAwB,EAAG,OAAO,CAAC,EAC3FK,EAAc,SAAW,WACzBH,EAAe,MAAM,OAAOD,GAAcF,GAAQ,QAAQ,IAAI,EAAG,uBAAuB,CAAC,EAAE,MAC3FI,EAAY,MAAM,OAAOF,GAAcF,GAAQ,QAAQ,IAAI,EAAG,oBAAoB,CAAC,EAAE,OAEzFK,EAAW,KAAK,MAAMT,EAAaK,EAAK,QAAQ,IAAI,EAAG,iCAAiC,EAAG,OAAO,CAAC,CACvG,MAAQ,CACJ,QAAQ,MAAM,mDAAmD,EACjE,QAAQ,KAAK,CAAC,CAClB,CAEMM,GAAO,OAAO,QAAQ,IAAI,IAAI,GAAKD,EAAe,MAAQ,IAC1DE,GAAO,OAAOF,EAAe,MAAS,SACtCA,EAAe,KACfA,EAAe,KAAO,UAAa,QAAQ,IAAI,MAAQ,UAEvDG,EAAM,IAAIV,GAEVW,EAAaT,EAAK,QAAQ,IAAI,EAAG,aAAa,EAEhDK,EAAe,SAAW,UAC1BG,EAAI,IAAI,WAAaO,GAAM,CACvB,IAAMC,EAAWD,EAAE,IAAI,KAAK,QAAQ,WAAY,EAAE,GAAK,IACjDE,EAAWD,IAAa,IACxBhB,EAAKS,EAAY,kBAAkB,EACnCT,EAAKS,EAAY,QAAS,GAAGO,CAAQ,OAAO,EAElD,GAAI,CACA,IAAME,EAAOvB,EAAasB,EAAU,OAAO,EAC3C,OAAOF,EAAE,KAAK,KAAK,MAAMG,CAAI,CAAC,CAClC,MAAQ,CACJ,OAAOH,EAAE,KAAK,CAAE,MAAO,WAAY,EAAG,GAAG,CAC7C,CACJ,CAAC,EAGLP,EAAI,IAAI,KAAMX,GAAY,CACtB,KAAMY,EACN,QAAS,CAACU,EAAOJ,IAAM,CACnBA,EAAE,OAAO,gBAAiBI,EAAM,SAAS,UAAU,EAC7C,sCACA,UAAU,CACpB,CACJ,CAAC,CAAC,EAEEd,EAAe,SAAW,SAC1B,QAAQ,IAAI,yEAAoE,GAEhFe,GAAkBZ,EAAK,CAAE,aAAAN,EAAc,UAAAC,EAAW,SAAAC,CAAS,CAAC,EAC5DiB,GAAiBb,EAAK,CAAE,aAAAN,EAAc,UAAAC,EAAW,SAAAC,EAAU,cAAeC,EAAe,aAAc,CAAC,GAG5GT,GAAM,CAAE,MAAOY,EAAI,MAAO,KAAAF,GAAM,SAAUC,EAAK,EAAIe,GAAS,QAAQ,IAAI,UAAUA,EAAK,OAAO,IAAIA,EAAK,IAAI,EAAE,CAAC,ICnE9G,IAAMC,GAAU,QAAQ,KAAK,CAAC,EAE9B,OAAQA,GAAS,CACb,IAAK,MACD,KAAM,sCACN,MACJ,IAAK,QACD,KAAM,kBACN,MACJ,IAAK,WACD,KAAM,mBACN,MACJ,IAAK,QACD,KAAM,mBACN,MACJ,IAAK,YACL,IAAK,KAAM,CACP,QAAQ,IAAI,cAAiB,EAC7B,KACJ,CACA,IAAK,SACL,IAAK,KACD,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAgBV,KAAK,CAAC,EACR,MACJ,QACI,QAAQ,MAAM,oBAAoBA,EAAO,EAAE,EAC3C,QAAQ,MAAM,yCAAyC,EACvD,QAAQ,KAAK,CAAC,CACtB",
|
|
6
|
+
"names": ["dev_exports", "spawnSync", "fileURLToPath", "dirname", "resolve", "__dirname", "init_dev", "__esmMin", "generateEntryClient", "cssUrls", "u", "init_entry_client", "__esmMin", "generateClientRoutes", "pagesDir", "matcherPath", "init_client_routes", "__esmMin", "generateRender", "pagesDir", "renderPath", "init_render", "__esmMin", "generateApi", "apiPath", "appDir", "init_api", "__esmMin", "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", "join", "unlinkSync", "writeFileSync", "pathToFileURL", "loadConfig", "cwd", "result", "tmpFile", "init_load_config", "__esmMin", "build_exports", "writeFileSync", "resolve", "build", "config", "baseConfig", "runtimeConfig", "init_build", "__esmMin", "init_vite", "init_duration", "init_load_config", "loadConfig", "devix", "parseDuration", "generate_exports", "readFileSync", "mkdirSync", "writeFileSync", "rmSync", "resolve", "join", "pathToFileURL", "userConfig", "t", "renderModule", "manifest", "urls", "init_generate", "__esmMin", "init_load_config", "loadConfig", "url", "fullUrl", "html", "statusCode", "outPath", "data", "dataPath", "registerApiRoutes", "app", "apiModule", "renderModule", "loaderTimeout", "c", "e", "pathname", "search", "url", "data", "registerSsrRoute", "manifest", "html", "statusCode", "headers", "res", "key", "value", "init_routes", "__esmMin", "loadEnv", "loadDotenv", "mode", "env", "key", "value", "init_env", "__esmMin", "start_exports", "readFileSync", "serve", "serveStatic", "Hono", "resolve", "join", "pathToFileURL", "renderModule", "apiModule", "manifest", "runtimeConfig", "port", "host", "app", "clientRoot", "init_start", "__esmMin", "init_routes", "init_env", "loadDotenv", "c", "pathname", "filePath", "data", "_path", "registerApiRoutes", "registerSsrRoute", "info", "command"]
|
|
7
7
|
}
|
package/dist/cli/start.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readFileSync as
|
|
1
|
+
import{readFileSync as l}from"node:fs";import{serve as b}from"@hono/node-server";import{serveStatic as q}from"@hono/node-server/serve-static";import{Hono as M}from"hono";import{resolve as j,join as c}from"node:path";function g(e,{apiModule:t,renderModule:s,loaderTimeout:a}){e.all("/api/*",async r=>{try{return await t.handleApiRequest(r.req.url,r.req.raw)}catch(o){return console.error(o),r.json({error:"internal error"},500)}}),e.get("/_data/*",async r=>{try{let{pathname:o,search:d}=new URL(r.req.url,"http://localhost"),u=o.replace(/^\/_data/,"")+d,i=await s.runLoader(u,r.req.raw,{loaderTimeout:a});return i.error?r.json({error:"internal error"},500):r.json(i)}catch(o){return console.error(o),r.json({error:"internal error"},500)}})}function y(e,{renderModule:t,manifest:s,loaderTimeout:a}){e.get("*",async r=>{try{let{html:o,statusCode:d,headers:u}=await t.render(r.req.url,r.req.raw,{manifest:s,loaderTimeout:a}),i=r.html(`<!DOCTYPE html>${o}`,d);for(let[x,O]of Object.entries(u))i.headers.set(x,O);return i}catch(o){return console.error(o),r.text("Internal Server Error",500)}})}import{loadEnv as R}from"vite";function w(e){let t=R(e,process.cwd(),"");for(let[s,a]of Object.entries(t))process.env[s]===void 0&&(process.env[s]=a)}import{pathToFileURL as S}from"node:url";w("production");var m,f,h,n;try{n=JSON.parse(l(c(process.cwd(),"dist/devix.config.json"),"utf-8")),n.output!=="static"&&(m=await import(S(j(process.cwd(),"dist/server/render.js")).href),f=await import(S(j(process.cwd(),"dist/server/api.js")).href)),h=JSON.parse(l(c(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}var T=Number(process.env.PORT)||n.port||3e3,_=typeof n.host=="string"?n.host:n.host?"0.0.0.0":process.env.HOST||"0.0.0.0",p=new M,v=c(process.cwd(),"dist/client");n.output==="static"&&p.get("/_data/*",e=>{let t=e.req.path.replace(/^\/_data/,"")||"/",s=t==="/"?c(v,"_data/index.json"):c(v,"_data",`${t}.json`);try{let a=l(s,"utf-8");return e.json(JSON.parse(a))}catch{return e.json({error:"not found"},404)}});p.use("/*",q({root:v,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));n.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(g(p,{renderModule:m,apiModule:f,manifest:h}),y(p,{renderModule:m,apiModule:f,manifest:h,loaderTimeout:n.loaderTimeout}));b({fetch:p.fetch,port:T,hostname:_},e=>console.log(`http://${e.address}:${e.port}`));
|
|
2
2
|
//# sourceMappingURL=start.js.map
|
package/dist/cli/start.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli/start.ts", "../../src/server/routes.ts", "../../src/utils/env.ts"],
|
|
4
|
-
"sourcesContent": ["import { readFileSync } from 'node:fs'\nimport { serve } from '@hono/node-server'\nimport { serveStatic } from '@hono/node-server/serve-static'\nimport { Hono } from 'hono'\nimport { resolve, join } from 'node:path'\nimport type { Manifest } from 'vite'\nimport { registerApiRoutes, registerSsrRoute } from '../server/routes'\nimport { loadDotenv } from '../utils/env'\nimport {pathToFileURL} from \"node:url\"\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(
|
|
5
|
-
"mappings": "AAAA,OAAS,gBAAAA,MAAoB,UAC7B,OAAS,SAAAC,MAAa,oBACtB,OAAS,eAAAC,MAAmB,iCAC5B,OAAS,QAAAC,MAAY,OACrB,OAAS,WAAAC,EAAS,QAAAC,MAAY,YCMvB,SAASC,EAAkBC,EAAW,CAAC,UAAAC,EAAW,aAAAC,EAAc,cAAAC,CAAa,EAAkB,CAClGH,EAAI,IAAI,SAAU,MAAOI,GAAM,CAC3B,GAAI,CACA,OAAO,MAAMH,EAAU,iBAAiBG,EAAE,IAAI,IAAKA,EAAE,IAAI,GAAG,CAChE,OAASC,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,EAEDJ,EAAI,IAAI,WAAY,MAAOI,GAAM,CAC7B,GAAI,CACA,GAAM,CAAC,SAAAE,EAAU,OAAAC,CAAM,EAAI,IAAI,IAAIH,EAAE,IAAI,IAAK,kBAAkB,EAC1DI,EAAMF,EAAS,QAAQ,WAAY,EAAE,EAAIC,EAEzCE,EAAO,MAAMP,EAAa,UAAUM,EAAKJ,EAAE,IAAI,IAAK,CAAC,cAAAD,CAAa,CAAC,EACzE,OAAIM,EAAK,MAAcL,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,EACrDA,EAAE,KAAKK,CAAI,CACtB,OAASJ,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,CACL,CAEO,SAASM,EAAiBV,EAAW,CAAC,aAAAE,EAAc,SAAAS,EAAU,cAAAR,CAAa,EAAkB,CAChGH,EAAI,IAAI,IAAK,MAAOI,GAAM,CACtB,GAAI,CACA,GAAM,CAAC,KAAAQ,EAAM,WAAAC,EAAY,QAAAC,CAAO,EAAI,MAAMZ,EAAa,OAAOE,EAAE,IAAI,IAAKA,EAAE,IAAI,IAAK,CAAC,SAAAO,EAAU,cAAAR,CAAa,CAAC,EACvGY,EAAMX,EAAE,KAAK,kBAAkBQ,CAAI,GAAIC,CAAU,EACvD,OAAW,CAACG,EAAKC,CAAK,IAAK,OAAO,QAAQH,CAAiC,EACvEC,EAAI,QAAQ,IAAIC,EAAKC,CAAK,EAE9B,OAAOF,CACX,OAASV,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,wBAAyB,GAAG,CAC9C,CACJ,CAAC,CACL,CCjDA,OAAQ,WAAAc,MAAc,OAEf,SAASC,EAAWC,EAAc,CACrC,IAAMC,EAAMH,EAAQE,EAAM,QAAQ,IAAI,EAAG,EAAE,EAC3C,OAAW,CAACE,EAAKC,CAAK,IAAK,OAAO,QAAQF,CAAG,EACrC,QAAQ,IAAIC,CAAG,IAAM,SACrB,QAAQ,IAAIA,CAAG,EAAIC,EAG/B,CFDA,OAAQ,iBAAAC,MAAoB,WAE5BC,EAAW,YAAY,EAEvB,IAAIC,EACAC,EACAC,EACAC,EAEJ,GAAI,CACAA,EAAgB,KAAK,MAAMC,
|
|
4
|
+
"sourcesContent": ["import { readFileSync } from 'node:fs'\nimport { serve } from '@hono/node-server'\nimport { serveStatic } from '@hono/node-server/serve-static'\nimport { Hono } from 'hono'\nimport { resolve, join } from 'node:path'\nimport type { Manifest } from 'vite'\nimport { registerApiRoutes, registerSsrRoute } from '../server/routes'\nimport { loadDotenv } from '../utils/env'\nimport {pathToFileURL} from \"node:url\"\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(join(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href)\n apiModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/api.js')).href)\n }\n manifest = JSON.parse(readFileSync(join(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\nif (runtimeConfig!.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\/_data/, '') || '/'\n const filePath = pathname === '/'\n ? join(clientRoot, '_data/index.json')\n : join(clientRoot, '_data', `${pathname}.json`)\n\n try {\n const data = readFileSync(filePath, 'utf-8')\n return c.json(JSON.parse(data))\n } catch {\n return c.json({ error: 'not found' }, 404)\n }\n })\n}\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, { renderModule, apiModule, manifest })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout })\n}\n\nserve({ fetch: app.fetch, port, hostname: host }, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport { }", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["readFileSync", "serve", "serveStatic", "Hono", "resolve", "join", "registerApiRoutes", "app", "apiModule", "renderModule", "loaderTimeout", "c", "e", "pathname", "search", "url", "data", "registerSsrRoute", "manifest", "html", "statusCode", "headers", "res", "key", "value", "loadEnv", "loadDotenv", "mode", "env", "key", "value", "pathToFileURL", "loadDotenv", "renderModule", "apiModule", "manifest", "runtimeConfig", "readFileSync", "join", "resolve", "port", "host", "app", "Hono", "clientRoot", "c", "pathname", "filePath", "data", "serveStatic", "_path", "registerApiRoutes", "registerSsrRoute", "serve", "info"]
|
|
7
7
|
}
|
package/dist/utils/banner.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.
|
|
1
|
+
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.9",n=s(e);console.log(),console.log(` ${o.bold(o.yellow("devix"))} ${o.dim(`v${l}`)}`),console.log(),console.log(` ${o.green("\u279C")} ${o.bold("Local:")} ${o.cyan(`http://localhost:${e}/`)}`),console.log(n?` ${o.green("\u279C")} ${o.bold("Network:")} ${o.cyan(n)}`:` ${o.green("\u279C")} ${o.bold("Network:")} ${o.dim("use --host to expose")}`),console.log()}export{$ as printDevBanner};
|
|
2
2
|
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{build as n}from"esbuild";import{join as i}from"node:path";import{unlinkSync as r,writeFileSync as m}from"node:fs";import{pathToFileURL as f}from"node:url";async function u(o){let e=await n({entryPoints:[i(o,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),t=i(o,`.devix-config-${Date.now()}.mjs`);m(t,e.outputFiles[0].text);try{return(await import(f(t).href)).default}finally{r(t)}}export{u as loadConfig};
|
|
2
|
+
//# sourceMappingURL=load-config.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/load-config.ts"],
|
|
4
|
+
"sourcesContent": ["import {build} from 'esbuild'\nimport type {DevixConfig} from \"../config\"\nimport {join} from \"node:path\"\nimport {unlinkSync, writeFileSync} from \"node:fs\";\nimport {pathToFileURL} from \"node:url\";\n\nexport async function loadConfig(cwd: string): Promise<DevixConfig> {\n const result = await build({\n entryPoints: [join(cwd, 'devix.config.ts')],\n bundle: true,\n write: false,\n format: 'esm',\n platform: 'node',\n packages: 'external',\n })\n\n const tmpFile = join(cwd, `.devix-config-${Date.now()}.mjs`)\n writeFileSync(tmpFile, result.outputFiles[0].text)\n\n try {\n const mod = await import(pathToFileURL(tmpFile).href)\n return mod.default\n } finally {\n unlinkSync(tmpFile)\n }\n}"],
|
|
5
|
+
"mappings": "AAAA,OAAQ,SAAAA,MAAY,UAEpB,OAAQ,QAAAC,MAAW,YACnB,OAAQ,cAAAC,EAAY,iBAAAC,MAAoB,UACxC,OAAQ,iBAAAC,MAAoB,WAE5B,eAAsBC,EAAWC,EAAmC,CAChE,IAAMC,EAAS,MAAMP,EAAM,CACvB,YAAa,CAACC,EAAKK,EAAK,iBAAiB,CAAC,EAC1C,OAAQ,GACR,MAAO,GACP,OAAQ,MACR,SAAU,OACV,SAAU,UACd,CAAC,EAEKE,EAAUP,EAAKK,EAAK,iBAAiB,KAAK,IAAI,CAAC,MAAM,EAC3DH,EAAcK,EAASD,EAAO,YAAY,CAAC,EAAE,IAAI,EAEjD,GAAI,CAEA,OADY,MAAM,OAAOH,EAAcI,CAAO,EAAE,OACrC,OACf,QAAE,CACEN,EAAWM,CAAO,CACtB,CACJ",
|
|
6
|
+
"names": ["build", "join", "unlinkSync", "writeFileSync", "pathToFileURL", "loadConfig", "cwd", "result", "tmpFile"]
|
|
7
|
+
}
|