@devlusoft/devix 0.4.1-beta.8 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/build.js +130 -31
- package/dist/cli/build.js.map +4 -4
- package/dist/cli/dev-server.js +132 -33
- package/dist/cli/dev-server.js.map +4 -4
- package/dist/cli/generate.js +130 -31
- package/dist/cli/generate.js.map +4 -4
- package/dist/cli/index.js +131 -32
- package/dist/cli/index.js.map +4 -4
- package/dist/cli/start.js +1 -1
- package/dist/cli/start.js.map +3 -3
- package/dist/runtime/client-router.js +1 -1
- package/dist/runtime/client-router.js.map +3 -3
- package/dist/runtime/context.d.ts +1 -0
- package/dist/runtime/context.js.map +2 -2
- package/dist/runtime/fetch.d.ts +4 -35
- package/dist/runtime/fetch.js +1 -1
- package/dist/runtime/fetch.js.map +3 -3
- package/dist/runtime/index.d.ts +32 -4
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +4 -4
- package/dist/runtime/link.d.ts +3 -2
- package/dist/runtime/link.js +1 -1
- package/dist/runtime/link.js.map +4 -4
- package/dist/runtime/router-provider.js +1 -1
- package/dist/runtime/router-provider.js.map +3 -3
- package/dist/runtime/server-app.js +1 -1
- package/dist/runtime/server-app.js.map +3 -3
- package/dist/server/api-router.d.ts +0 -1
- package/dist/server/api-router.js +1 -1
- package/dist/server/api-router.js.map +3 -3
- package/dist/server/api.js +1 -1
- package/dist/server/api.js.map +3 -3
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +3 -3
- package/dist/server/pages-router.d.ts +0 -1
- package/dist/server/pages-router.js +1 -1
- package/dist/server/pages-router.js.map +3 -3
- package/dist/server/render.d.ts +15 -0
- package/dist/server/render.js +1 -1
- package/dist/server/render.js.map +3 -3
- package/dist/server/routes.js +1 -1
- package/dist/server/routes.js.map +3 -3
- package/dist/server/types.d.ts +4 -2
- package/dist/utils/banner.js +1 -1
- package/dist/utils/banner.js.map +1 -1
- package/dist/utils/load-config.js +1 -1
- package/dist/utils/load-config.js.map +3 -3
- package/dist/utils/response.d.ts +13 -2
- package/dist/utils/response.js +1 -1
- package/dist/utils/response.js.map +3 -3
- package/dist/vite/codegen/entry-client.js +14 -1
- package/dist/vite/codegen/entry-client.js.map +2 -2
- package/dist/vite/codegen/page-types.d.ts +5 -0
- package/dist/vite/codegen/page-types.js +14 -0
- package/dist/vite/codegen/page-types.js.map +7 -0
- package/dist/vite/codegen/routes-dts.js +13 -10
- package/dist/vite/codegen/routes-dts.js.map +2 -2
- package/dist/vite/codegen/scan-api.js +1 -1
- package/dist/vite/codegen/scan-api.js.map +1 -1
- package/dist/vite/codegen/server-entry.d.ts +9 -0
- package/dist/vite/codegen/server-entry.js +73 -0
- package/dist/vite/codegen/server-entry.js.map +7 -0
- package/dist/vite/index.js +131 -32
- package/dist/vite/index.js.map +4 -4
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
${
|
|
2
|
+
var c=(e,t)=>()=>(e&&(t=e(e=0)),t);var lt={};import{spawnSync as nt}from"node:child_process";import{fileURLToPath as it}from"node:url";import{dirname as st,resolve as at}from"node:path";var ct,ne=c(()=>{"use strict";ct=st(it(import.meta.url));for(;nt(process.execPath,[at(ct,"dev-server.js")],{stdio:"inherit",env:process.env}).status===75;);});function ie({cssUrls:e}){return`
|
|
3
|
+
${e.map(r=>`import '${r}'`).join(`
|
|
4
4
|
`)}
|
|
5
5
|
import "@vitejs/plugin-react/preamble"
|
|
6
6
|
import React from "react"
|
|
@@ -20,7 +20,20 @@ if (!window.__DEVIX__) {
|
|
|
20
20
|
|
|
21
21
|
const matched = matchClientRoute(window.location.pathname)
|
|
22
22
|
|
|
23
|
-
if (
|
|
23
|
+
if (window.__LOADER_ERROR__) {
|
|
24
|
+
const {statusCode, message, data} = window.__LOADER_ERROR__
|
|
25
|
+
const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()
|
|
26
|
+
createRoot(root).render(
|
|
27
|
+
React.createElement(RouterProvider, {
|
|
28
|
+
clientEntry,
|
|
29
|
+
initialData: null,
|
|
30
|
+
initialParams: {},
|
|
31
|
+
initialPage: () => null,
|
|
32
|
+
initialError: {statusCode, message, data},
|
|
33
|
+
initialErrorPage: ErrorPage,
|
|
34
|
+
})
|
|
35
|
+
)
|
|
36
|
+
} else if (matched) {
|
|
24
37
|
const [pageMod, ...layoutMods] = await Promise.all([
|
|
25
38
|
matched.load(),
|
|
26
39
|
...matched.loadLayouts.map(l => l()),
|
|
@@ -63,12 +76,12 @@ if (!window.__DEVIX__) {
|
|
|
63
76
|
)
|
|
64
77
|
}
|
|
65
78
|
}
|
|
66
|
-
`}var
|
|
79
|
+
`}var se=c(()=>{"use strict"});function ae({pagesDir:e,matcherPath:t}){return`
|
|
67
80
|
import React from 'react'
|
|
68
|
-
import { createMatcher } from '${
|
|
69
|
-
const pageFiles = import.meta.glob(['/${
|
|
70
|
-
const layoutFiles = import.meta.glob('/${
|
|
71
|
-
const errorFiles = import.meta.glob('/${
|
|
81
|
+
import { createMatcher } from '${t}'
|
|
82
|
+
const pageFiles = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
83
|
+
const layoutFiles = import.meta.glob('/${e}/**/layout.tsx')
|
|
84
|
+
const errorFiles = import.meta.glob('/${e}/**/error.tsx')
|
|
72
85
|
|
|
73
86
|
export const matchClientRoute = createMatcher(pageFiles, layoutFiles)
|
|
74
87
|
|
|
@@ -91,16 +104,16 @@ export function getDefaultErrorPage() {
|
|
|
91
104
|
)
|
|
92
105
|
}
|
|
93
106
|
}
|
|
94
|
-
`}var
|
|
95
|
-
import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${
|
|
107
|
+
`}var ce=c(()=>{"use strict"});function le({pagesDir:e,renderPath:t}){return`
|
|
108
|
+
import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${t}'
|
|
96
109
|
|
|
97
|
-
const _pages = import.meta.glob(['/${
|
|
98
|
-
const _layouts = import.meta.glob('/${
|
|
110
|
+
const _pages = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
111
|
+
const _layouts = import.meta.glob('/${e}/**/layout.tsx')
|
|
99
112
|
|
|
100
113
|
const _glob = {
|
|
101
114
|
pages: _pages,
|
|
102
115
|
layouts: _layouts,
|
|
103
|
-
pagesDir: '/${
|
|
116
|
+
pagesDir: '/${e}',
|
|
104
117
|
}
|
|
105
118
|
|
|
106
119
|
export function render(url, request, options) {
|
|
@@ -114,51 +127,137 @@ export function runLoader(url, request, options) {
|
|
|
114
127
|
export function getStaticRoutes() {
|
|
115
128
|
return _getStaticRoutes(_glob)
|
|
116
129
|
}
|
|
117
|
-
`}var
|
|
118
|
-
import { handleApiRequest as _handleApiRequest } from '${
|
|
130
|
+
`}var ue=c(()=>{"use strict"});function de({apiPath:e,appDir:t}){return`
|
|
131
|
+
import { handleApiRequest as _handleApiRequest } from '${e}'
|
|
119
132
|
|
|
120
|
-
const _routes = import.meta.glob(['/${
|
|
121
|
-
const _middlewares = import.meta.glob('/${
|
|
133
|
+
const _routes = import.meta.glob(['/${t}/api/**/*.ts', '!**/middleware.ts'])
|
|
134
|
+
const _middlewares = import.meta.glob('/${t}/api/**/middleware.ts')
|
|
122
135
|
|
|
123
136
|
const _glob = {
|
|
124
137
|
routes: _routes,
|
|
125
138
|
middlewares: _middlewares,
|
|
126
|
-
apiDir: '/${
|
|
139
|
+
apiDir: '/${t}/api',
|
|
127
140
|
}
|
|
128
141
|
|
|
129
142
|
export function handleApiRequest(url, request) {
|
|
130
143
|
return _handleApiRequest(url, request, _glob)
|
|
131
144
|
}
|
|
132
|
-
`}var
|
|
145
|
+
`}var pe=c(()=>{"use strict"});function me(){return`
|
|
133
146
|
export {RouterContext} from '@devlusoft/devix/runtime/context'
|
|
134
|
-
`}var
|
|
147
|
+
`}var fe=c(()=>{"use strict"});function dt(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function ge(e){let t=new Set;for(let r of dt(e).matchAll(ut))t.add(r[1]);return[...t]}var ut,he=c(()=>{"use strict";ut=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g});function ve(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var xe=c(()=>{"use strict"});function ye(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),n=ve(r);return n==="/"?"/api":`/api/${n}`.replace("/api//","/api/")}var Re=c(()=>{"use strict";xe()});function pt(e,t){return"_api_"+e.slice(`${t}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function we(e,t,r){return{filePath:e,urlPattern:ye(e,t),identifier:pt(e,t),methods:r}}function I(e,t){if(e.length===0)return`// auto-generado por devix \u2014 no editar
|
|
148
|
+
export {}
|
|
135
149
|
declare module '@devlusoft/devix' {
|
|
136
150
|
interface ApiRoutes {}
|
|
137
151
|
}
|
|
138
|
-
`;let r=
|
|
139
|
-
`),
|
|
152
|
+
`;let r=e.map(o=>{let a="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${a}'`}).join(`
|
|
153
|
+
`),n=e.flatMap(o=>o.methods.map(a=>` '${a} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${a}']>`)).join(`
|
|
140
154
|
`);return`// auto-generado por devix \u2014 no editar
|
|
141
155
|
${r}
|
|
142
156
|
|
|
143
|
-
type JsonResponse<T> = Response & { readonly __body: T }
|
|
144
|
-
type
|
|
145
|
-
type
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
type JsonResponse<T, S extends number = number> = Response & { readonly __body: T; readonly __status: S }
|
|
158
|
+
type Is2xx<S extends number> = [number] extends [S] ? boolean : S extends 200 | 201 | 202 | 203 | 204 | 205 | 206 ? true : false
|
|
159
|
+
type UnwrapSuccessJson<T> = T extends JsonResponse<infer U, infer S> ? Is2xx<S> extends false ? never : U : never
|
|
160
|
+
type UnwrapErrorJson<T> = T extends JsonResponse<infer U, infer S> ? Is2xx<S> extends true ? never : U : never
|
|
161
|
+
type InferFnSuccess<T> = T extends (...args: any[]) => any ? UnwrapSuccessJson<Awaited<ReturnType<T>>> : never
|
|
162
|
+
type InferFnErrors<T> = T extends (...args: any[]) => any ? UnwrapErrorJson<Awaited<ReturnType<T>>> : never
|
|
148
163
|
type InferRoute<T> =
|
|
149
164
|
T extends { readonly __return?: infer TReturn; readonly __body?: infer TBody }
|
|
150
165
|
? {
|
|
151
166
|
__body: [TBody] extends [undefined] ? never : Exclude<TBody, undefined>
|
|
152
|
-
__response:
|
|
167
|
+
__response: InferFnSuccess<() => TReturn>
|
|
168
|
+
__errors: InferFnErrors<() => TReturn>
|
|
153
169
|
}
|
|
154
|
-
:
|
|
170
|
+
: InferFnSuccess<T>
|
|
155
171
|
|
|
156
172
|
declare module '@devlusoft/devix' {
|
|
157
173
|
interface ApiRoutes {
|
|
158
|
-
${
|
|
174
|
+
${n}
|
|
159
175
|
}
|
|
160
176
|
}
|
|
161
|
-
`}var
|
|
177
|
+
`}var L=c(()=>{"use strict";Re()});import{readFileSync as mt,readdirSync as ft,statSync as gt}from"node:fs";import{join as U,relative as ht}from"node:path";function _e(e,t){let r=[];for(let n of ft(e)){let o=U(e,n);gt(o).isDirectory()?r.push(..._e(o,t)):/\.(ts|tsx)$/.test(n)&&r.push(ht(t,o).replace(/\\/g,"/"))}return r}function k(e,t){let r=U(t,e,"api"),n;try{n=_e(r,t)}catch{return[]}return n.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=mt(U(t,o),"utf-8"),d=ge(a);return d.length===0?[]:[we(o,`${e}/api`,d)]}catch{return[]}})}var Se=c(()=>{"use strict";he();L()});import{mkdirSync as vt,readFileSync as xt,writeFileSync as yt,existsSync as Rt}from"node:fs";import{join as Ee}from"node:path";function N(e,t){let r=Ee(t,".devix"),n=Ee(r,"routes.d.ts");return vt(r,{recursive:!0}),Rt(n)&&xt(n,"utf-8")===e?!1:(yt(n,e,"utf-8"),!0)}var Pe=c(()=>{"use strict"});function Te({routesPath:e,envPath:t,honoServerPath:r,honoServerStaticPath:n,honoPath:o}){return`
|
|
178
|
+
import { readFileSync } from 'node:fs'
|
|
179
|
+
import { serve } from '${r}'
|
|
180
|
+
import { serveStatic } from '${n}'
|
|
181
|
+
import { Hono } from '${o}'
|
|
182
|
+
import { resolve, join, dirname } from 'node:path'
|
|
183
|
+
import { pathToFileURL } from 'node:url'
|
|
184
|
+
import { registerApiRoutes, registerSsrRoute } from '${e}'
|
|
185
|
+
import { loadDotenv } from '${t}'
|
|
186
|
+
|
|
187
|
+
loadDotenv('production')
|
|
188
|
+
|
|
189
|
+
const __dir = dirname(process.argv[1])
|
|
190
|
+
|
|
191
|
+
let renderModule, apiModule, manifest, runtimeConfig
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
runtimeConfig = JSON.parse(readFileSync(resolve(__dir, '../devix.config.json'), 'utf-8'))
|
|
195
|
+
if (runtimeConfig.output !== 'static') {
|
|
196
|
+
renderModule = await import(pathToFileURL(resolve(__dir, 'render.js')).href)
|
|
197
|
+
apiModule = await import(pathToFileURL(resolve(__dir, 'api.js')).href)
|
|
198
|
+
}
|
|
199
|
+
manifest = JSON.parse(readFileSync(resolve(__dir, '../client/.vite/manifest.json'), 'utf-8'))
|
|
200
|
+
} catch {
|
|
201
|
+
console.error('[devix] Build not found. Run "devix build" first.')
|
|
202
|
+
process.exit(1)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const port = Number(process.env.PORT) || runtimeConfig.port || 3000
|
|
206
|
+
const host = typeof runtimeConfig.host === 'string'
|
|
207
|
+
? runtimeConfig.host
|
|
208
|
+
: runtimeConfig.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')
|
|
209
|
+
|
|
210
|
+
const clientRoot = resolve(__dir, '../client')
|
|
211
|
+
const app = new Hono()
|
|
212
|
+
|
|
213
|
+
if (runtimeConfig.output === 'static') {
|
|
214
|
+
app.get('/_data/*', (c) => {
|
|
215
|
+
const pathname = c.req.path.replace(/^\\/_data/, '') || '/'
|
|
216
|
+
const filePath = pathname === '/'
|
|
217
|
+
? join(clientRoot, '_data/index.json')
|
|
218
|
+
: join(clientRoot, '_data', pathname + '.json')
|
|
219
|
+
try {
|
|
220
|
+
return c.json(JSON.parse(readFileSync(filePath, 'utf-8')))
|
|
221
|
+
} catch {
|
|
222
|
+
return c.json({ error: 'not found' }, 404)
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
app.use('/*', serveStatic({
|
|
228
|
+
root: clientRoot,
|
|
229
|
+
onFound: (_path, c) => {
|
|
230
|
+
c.header('Cache-Control', _path.includes('/assets/')
|
|
231
|
+
? 'public, immutable, max-age=31536000'
|
|
232
|
+
: 'no-cache')
|
|
233
|
+
}
|
|
234
|
+
}))
|
|
235
|
+
|
|
236
|
+
if (runtimeConfig.output === 'static') {
|
|
237
|
+
console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')
|
|
238
|
+
} else {
|
|
239
|
+
registerApiRoutes(app, { renderModule, apiModule, manifest })
|
|
240
|
+
registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout })
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const server = serve({ fetch: app.fetch, port, hostname: host }, (info) =>
|
|
244
|
+
console.log(\`http://\${info.address}:\${info.port}\`))
|
|
245
|
+
|
|
246
|
+
process.on('SIGTERM', () => server.close())
|
|
247
|
+
process.on('SIGINT', () => server.close())
|
|
248
|
+
`}var $e=c(()=>{"use strict"});import{existsSync as De,mkdirSync as wt,readdirSync as _t,readFileSync as be,rmSync as St,statSync as Et,writeFileSync as Pt}from"node:fs";import{join as y,relative as Ce}from"node:path";import{parseSync as Tt}from"oxc-parser";function Ae(e,t){let r=[];for(let n of _t(e)){let o=y(e,n);Et(o).isDirectory()?r.push(...Ae(o,t)):/\.(ts|tsx)$/.test(n)&&n!=="layout.tsx"&&n!=="error.tsx"&&r.push(Ce(t,o).replace(/\\/g,"/"))}return r}function $t(e,t){let r=Tt(t,e,{sourceType:"module"});for(let n of r.program.body){if(n.type!=="ExportNamedDeclaration")continue;let o=n.declaration;if(o?.type==="FunctionDeclaration"&&o.id?.name==="loader")return!0;if(o?.type==="VariableDeclaration"){for(let a of o.declarations)if(a.id.type==="Identifier"&&a.id.name==="loader")return!0}for(let a of n.specifiers??[])if(a.exported.type==="Identifier"&&a.exported.name==="loader")return!0}return!1}function bt(e,t){return t?`// auto-generado por devix \u2014 no editar
|
|
249
|
+
import type { loader } from "${e}"
|
|
250
|
+
import type { Redirect } from "@devlusoft/devix"
|
|
251
|
+
|
|
252
|
+
export type PageData = Exclude<
|
|
253
|
+
Awaited<ReturnType<NonNullable<typeof loader>>>,
|
|
254
|
+
Redirect | void | undefined
|
|
255
|
+
>
|
|
256
|
+
export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
257
|
+
`:`// auto-generado por devix - no editar
|
|
258
|
+
export type PageData = undefined
|
|
259
|
+
export type PageParams = Record<string, string>
|
|
260
|
+
`}function O(e,t){let r=y(t,e),n=be(r,"utf-8"),o=$t(n,r),a=y(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),d=y(a,"$types.d.ts"),x=r.replace(/\.(tsx?|jsx?)$/,""),m=Ce(a,x).replace(/\\/g,"/"),f=bt(m,o);De(d)&&be(d,"utf-8")===f||(wt(a,{recursive:!0}),Pt(d,f,"utf-8"))}function Oe(e,t){let r=y(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),n=y(r,"$types.d.ts");De(n)&&St(n)}function H(e,t){let r=y(t,e,"pages"),n;try{n=Ae(r,t)}catch{return}for(let o of n)try{O(o,t)}catch{}}var je=c(()=>{"use strict"});import{mergeConfig as Dt}from"vite";import Ct from"@vitejs/plugin-react";import{fileURLToPath as At}from"node:url";import{dirname as Ot,relative as jt,resolve as p}from"node:path";import{createRequire as Mt}from"node:module";import{parseSync as Ft}from"oxc-parser";function Fe(e){let t=e.appDir??"app",r=`${t}/pages`,n=(e.css??[]).map(i=>i.startsWith("/")?i:`/${i.replace(/^\.\//,"")}`),o=p(P,"../server/render.js").replace(/\\/g,"/"),a=p(P,"../server/api.js").replace(/\\/g,"/"),d=p(P,"../runtime/client-router.js").replace(/\\/g,"/"),x=p(P,"../server/routes.js").replace(/\\/g,"/"),m=p(P,"../utils/env.js").replace(/\\/g,"/"),f=Mt(import.meta.url),w=f.resolve("@hono/node-server").replace(/\\/g,"/"),M=f.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),tt=f.resolve("hono").replace(/\\/g,"/"),rt={name:"devix",enforce:"pre",resolveId(i){if(i===q)return`\0${q}`;if(i===V)return`\0${V}`;if(i===T)return`\0${T}`;if(i===$)return`\0${$}`;if(i===J)return`\0${J}`;if(i===W)return`\0${W}`},load(i){if(i===`\0${q}`)return ie({cssUrls:n});if(i===`\0${V}`)return ae({pagesDir:r,matcherPath:d});if(i===`\0${T}`)return le({pagesDir:r,renderPath:o});if(i===`\0${$}`)return de({apiPath:a,appDir:t});if(i===`\0${J}`)return me();if(i===`\0${W}`)return Te({routesPath:x,envPath:m,honoServerPath:w,honoServerStaticPath:M,honoPath:tt})},transform(i,l,_){if(_?.ssr)return;let S=p(process.cwd(),r);if(!l.startsWith(S))return;let E=Ft(l,i,{sourceType:"module"}),g=[];for(let u of E.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let h=u.declaration;if(h.type==="FunctionDeclaration"&&h.id&&Me.has(h.id.name)&&g.push({start:u.start,end:u.end,name:h.id.name}),h.type==="VariableDeclaration"){let A=new Set;for(let F of h.declarations)F.id.type==="Identifier"&&Me.has(F.id.name)&&(A.has(u.start)||(A.add(u.start),g.push({start:u.start,end:u.end,name:F.id.name})))}}if(g.length===0)return;g.sort((u,h)=>h.start-u.start);let s=i;for(let{start:u,end:h,name:A}of g)s=s.slice(0,u)+`export const ${A} = undefined`+s.slice(h);return{code:s,map:null}},buildStart(){let i=process.cwd(),l=k(t,i);N(I(l,`${t}/api`),i),H(t,i)},configureServer(i){let l=process.cwd();H(t,l);let _=()=>{let s=k(t,l);N(I(s,`${t}/api`),l)},S=s=>s.startsWith(p(l,r))&&!s.endsWith("layout.tsx")&&!s.endsWith("error.tsx"),E=s=>jt(l,s).replace(/\\/g,"/"),g=s=>{let u=i.moduleGraph.getModuleById(`\0${s}`);u&&i.moduleGraph.invalidateModule(u)};i.watcher.add(p(l,"devix.config.ts")),i.watcher.on("change",s=>{s===p(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),i.watcher.on("add",s=>{s.startsWith(p(l,r))&&g(T),S(s)&&O(E(s),l),s.includes(`${t}/api`)&&(g($),_())}),i.watcher.on("unlink",s=>{s.startsWith(p(l,r))&&g(T),S(s)&&Oe(E(s),l),s.includes(`${t}/api`)&&(g($),_())}),i.watcher.on("change",s=>{S(s)&&O(E(s),l),s.includes(`${t}/api`)&&!s.endsWith("middleware.ts")&&_()})}},ot={plugins:[Ct(),rt],publicDir:p(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Dt(ot,e.vite??{})}var P,q,V,T,$,J,W,Me,Ie=c(()=>{"use strict";se();ce();ue();pe();fe();Se();L();Pe();$e();je();P=Ot(At(import.meta.url)),q="virtual:devix/entry-client",V="virtual:devix/client-routes",T="virtual:devix/render",$="virtual:devix/api",J="virtual:devix/context",W="virtual:devix/server-entry",Me=new Set(["loader","guard","generateStaticParams","headers"])});function Le(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var Ue=c(()=>{"use strict"});import{build as It}from"esbuild";import{join as ke}from"node:path";import{unlinkSync as Lt,writeFileSync as Ut}from"node:fs";import{pathToFileURL as kt}from"node:url";async function j(e){let t=await It({entryPoints:[ke(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=ke(e,`.devix-config-${Date.now()}.mjs`);Ut(r,t.outputFiles[0].text);try{return(await import(kt(r).href)).default}finally{Lt(r)}}var B=c(()=>{"use strict"});var Ne={};import{writeFileSync as Nt}from"node:fs";import{resolve as Ht}from"node:path";import{build as G}from"vite";var b,X,qt,Y=c(async()=>{"use strict";Ie();Ue();B();b=await j(process.cwd()),X=Fe(b);await G({...X,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await G({...X,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await G({...X,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});qt={port:b.port??3e3,host:b.host??!1,loaderTimeout:Le(b.loaderTimeout??1e4),output:b.output??"server"};Nt(Ht(process.cwd(),"dist/devix.config.json"),JSON.stringify(qt,null,2),"utf-8")});var Gt={};import{readFileSync as Vt,mkdirSync as He,writeFileSync as qe,rmSync as Jt}from"node:fs";import{resolve as K,join as R}from"node:path";import{pathToFileURL as Wt}from"node:url";var Je,Bt,z,Ve,Z,We=c(async()=>{"use strict";B();Je=await j(process.cwd());Je.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await Y().then(()=>Ne);Bt=Date.now(),z=await import(Wt(K(process.cwd(),"dist/server/render.js")).href+`?t=${Bt}`),Ve=JSON.parse(Vt(K(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),Z=await z.getStaticRoutes();console.log(`[devix] Generating ${Z.length} static page${Z.length===1?"":"s"}...`);for(let e of Z){let t=`http://localhost${e}`,{html:r,statusCode:n}=await z.render(t,new Request(t),{manifest:Ve});if(n!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${n}`);continue}let o=e==="/"?R(process.cwd(),"dist/client/index.html"):R(process.cwd(),"dist/client",e,"index.html");He(R(o,".."),{recursive:!0}),qe(o,`<!DOCTYPE html>${r}`,"utf-8");let a=await z.runLoader(t,new Request(t),{manifest:Ve}),d=e==="/"?R(process.cwd(),"dist/client/_data/index.json"):R(process.cwd(),"dist/client/_data",`${e}.json`);He(R(d,".."),{recursive:!0}),qe(d,JSON.stringify(a),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Je.output==="static"&&(Jt(K(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function Be(e,{apiModule:t,renderModule:r,loaderTimeout:n}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:a,search:d}=new URL(o.req.url,"http://localhost"),x=a.replace(/^\/_data/,"")+d,m=await r.runLoader(x,o.req.raw,{loaderTimeout:n});if(m.error)return o.json({error:"internal error"},500);if("loaderError"in m){let{statusCode:f,message:w,data:M}=m.loaderError;return o.json({statusCode:f,message:w,data:M},f)}return o.json(m)}catch(a){return console.error(a),o.json({error:"internal error"},500)}})}function Ge(e,{renderModule:t,manifest:r,loaderTimeout:n}){e.get("*",async o=>{try{let{html:a,statusCode:d,headers:x}=await t.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:n}),m=o.html(`<!DOCTYPE html>${a}`,d);for(let[f,w]of Object.entries(x))m.headers.set(f,w);return m}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Xe=c(()=>{"use strict"});import{loadEnv as Xt}from"vite";function Ye(e){let t=Xt(e,process.cwd(),"");for(let[r,n]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=n)}var ze=c(()=>{"use strict"});var er={};import{readFileSync as Q}from"node:fs";import{serve as Yt}from"@hono/node-server";import{serveStatic as zt}from"@hono/node-server/serve-static";import{Hono as Zt}from"hono";import{resolve as Ze,join as D}from"node:path";import{pathToFileURL as Ke}from"node:url";var ee,te,re,v,Kt,Qt,C,oe,Qe=c(async()=>{"use strict";Xe();ze();Ye("production");try{v=JSON.parse(Q(D(process.cwd(),"dist/devix.config.json"),"utf-8")),v.output!=="static"&&(ee=await import(Ke(Ze(process.cwd(),"dist/server/render.js")).href),te=await import(Ke(Ze(process.cwd(),"dist/server/api.js")).href)),re=JSON.parse(Q(D(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}Kt=Number(process.env.PORT)||v.port||3e3,Qt=typeof v.host=="string"?v.host:v.host?"0.0.0.0":process.env.HOST||"0.0.0.0",C=new Zt,oe=D(process.cwd(),"dist/client");v.output==="static"&&C.get("/_data/*",e=>{let t=e.req.path.replace(/^\/_data/,"")||"/",r=t==="/"?D(oe,"_data/index.json"):D(oe,"_data",`${t}.json`);try{let n=Q(r,"utf-8");return e.json(JSON.parse(n))}catch{return e.json({error:"not found"},404)}});C.use("/*",zt({root:oe,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));v.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Be(C,{renderModule:ee,apiModule:te,manifest:re}),Ge(C,{renderModule:ee,apiModule:te,manifest:re,loaderTimeout:v.loaderTimeout}));Yt({fetch:C.fetch,port:Kt,hostname:Qt},e=>console.log(`http://${e.address}:${e.port}`))});var et=process.argv[2];switch(et){case"dev":await Promise.resolve().then(()=>(ne(),lt));break;case"build":await Y().then(()=>Ne);break;case"generate":await We().then(()=>Gt);break;case"start":await Qe().then(()=>er);break;case"--version":case"-v":{console.log("0.4.1");break}case"--help":case"-h":console.log(`
|
|
162
261
|
devix \u2014 a lightweight SSR framework
|
|
163
262
|
|
|
164
263
|
Usage:
|
|
@@ -174,5 +273,5 @@ Options:
|
|
|
174
273
|
Output modes (set in devix.config.ts):
|
|
175
274
|
output: "server" SSR mode \u2014 devix start handles requests dynamically (default)
|
|
176
275
|
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: ${
|
|
276
|
+
`.trim());break;default:console.error(`Unknown command: ${et}`),console.error("Usage: devix <dev|build|generate|start>"),process.exit(1)}
|
|
178
277
|
//# sourceMappingURL=index.js.map
|