@devlusoft/devix 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -9
- package/dist/cli/build.js +27 -17
- package/dist/cli/build.js.map +3 -3
- package/dist/cli/dev-server.js +31 -21
- package/dist/cli/dev-server.js.map +4 -4
- package/dist/cli/generate.js +29 -19
- package/dist/cli/generate.js.map +3 -3
- package/dist/cli/index.js +30 -20
- package/dist/cli/index.js.map +4 -4
- package/dist/cli/start.js +1 -1
- package/dist/cli/start.js.map +4 -4
- package/dist/config.d.ts +61 -0
- package/dist/config.js +1 -1
- package/dist/config.js.map +3 -3
- package/dist/runtime/api-context.d.ts +9 -4
- package/dist/runtime/api-context.js +1 -1
- package/dist/runtime/api-context.js.map +3 -3
- package/dist/runtime/context.d.ts +1 -0
- package/dist/runtime/context.js.map +2 -2
- package/dist/runtime/create-handler.d.ts +52 -2
- package/dist/runtime/create-handler.js +1 -1
- package/dist/runtime/create-handler.js.map +3 -3
- package/dist/runtime/error-boundary.d.ts +7 -1
- package/dist/runtime/error-boundary.js +1 -1
- package/dist/runtime/error-boundary.js.map +3 -3
- package/dist/runtime/fetch.d.ts +1 -0
- package/dist/runtime/fetch.js +1 -1
- package/dist/runtime/fetch.js.map +3 -3
- package/dist/runtime/index.d.ts +6 -2
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +4 -4
- package/dist/runtime/link.js +1 -1
- package/dist/runtime/link.js.map +4 -4
- package/dist/runtime/router-provider.d.ts +24 -1
- package/dist/runtime/router-provider.js +1 -1
- package/dist/runtime/router-provider.js.map +4 -4
- package/dist/runtime/server-app.d.ts +2 -1
- package/dist/runtime/server-app.js +1 -1
- package/dist/runtime/server-app.js.map +3 -3
- package/dist/runtime/server-client.d.ts +66 -0
- package/dist/runtime/server-client.js +2 -0
- package/dist/runtime/server-client.js.map +7 -0
- package/dist/runtime/url.d.ts +9 -0
- package/dist/runtime/url.js +2 -0
- package/dist/runtime/url.js.map +7 -0
- package/dist/server/api.d.ts +2 -1
- package/dist/server/api.js +1 -1
- package/dist/server/api.js.map +4 -4
- package/dist/server/handler-store.d.ts +12 -0
- package/dist/server/handler-store.js.map +2 -2
- package/dist/server/public-index.js.map +2 -2
- package/dist/server/render.d.ts +8 -0
- package/dist/server/render.js +1 -1
- package/dist/server/render.js.map +4 -4
- package/dist/server/routes.d.ts +4 -2
- package/dist/server/routes.js +1 -1
- package/dist/server/routes.js.map +4 -4
- package/dist/server/server-bound.d.ts +11 -0
- package/dist/server/server-bound.js +2 -0
- package/dist/server/server-bound.js.map +7 -0
- package/dist/server/server-proxy.d.ts +15 -0
- package/dist/server/server-proxy.js +2 -0
- package/dist/server/server-proxy.js.map +7 -0
- package/dist/server/types.d.ts +1 -0
- package/dist/types.d.ts +22 -0
- package/dist/utils/banner.js +1 -1
- package/dist/utils/glob.d.ts +11 -0
- package/dist/utils/glob.js +2 -0
- package/dist/utils/glob.js.map +7 -0
- package/dist/utils/response.d.ts +33 -1
- package/dist/utils/response.js +1 -1
- package/dist/utils/response.js.map +3 -3
- package/dist/utils/standard-schema.d.ts +39 -0
- package/dist/utils/standard-schema.js +1 -0
- package/dist/utils/standard-schema.js.map +7 -0
- package/dist/vite/codegen/entry-client.js +5 -3
- package/dist/vite/codegen/entry-client.js.map +2 -2
- package/dist/vite/codegen/page-types.d.ts +11 -2
- package/dist/vite/codegen/page-types.js +3 -3
- package/dist/vite/codegen/page-types.js.map +3 -3
- package/dist/vite/codegen/server-entry.js +16 -8
- package/dist/vite/codegen/server-entry.js.map +2 -2
- package/dist/vite/index.js +26 -16
- package/dist/vite/index.js.map +3 -3
- package/package.json +5 -5
package/dist/utils/response.d.ts
CHANGED
|
@@ -23,8 +23,40 @@ export interface RouteError {
|
|
|
23
23
|
readonly [ERROR_BRAND]: true;
|
|
24
24
|
readonly statusCode: number;
|
|
25
25
|
readonly message: string;
|
|
26
|
+
readonly code?: string;
|
|
26
27
|
readonly data?: unknown;
|
|
27
28
|
}
|
|
28
|
-
export
|
|
29
|
+
export interface ErrorOptions {
|
|
30
|
+
code?: string;
|
|
31
|
+
data?: unknown;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Crea un error tipado que funciona en loaders, guards y handlers API.
|
|
35
|
+
*
|
|
36
|
+
* En loaders/guards: retórnalo (no lo lances) y el sistema renderiza `error.tsx`.
|
|
37
|
+
* En handlers API: retórnalo y el sistema serializa el shape `ErrorBody` como JSON
|
|
38
|
+
* con el statusCode correcto.
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* return error(404, 'Post no encontrado', { code: 'POST_NOT_FOUND' })
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function error(statusCode: number, message: string, options?: ErrorOptions): RouteError;
|
|
29
45
|
export declare function isLoaderError(value: unknown): value is RouteError;
|
|
46
|
+
/**
|
|
47
|
+
* Shape público del body de un error API. Todos los errores emitidos por `error()`
|
|
48
|
+
* o `DevixError` se serializan a este shape. `FetchError.body` del cliente lo recibe.
|
|
49
|
+
*/
|
|
50
|
+
export interface ErrorBody {
|
|
51
|
+
statusCode: number;
|
|
52
|
+
message: string;
|
|
53
|
+
code?: string;
|
|
54
|
+
data?: unknown;
|
|
55
|
+
}
|
|
56
|
+
export declare function errorToBody(err: {
|
|
57
|
+
statusCode: number;
|
|
58
|
+
message: string;
|
|
59
|
+
code?: string;
|
|
60
|
+
data?: unknown;
|
|
61
|
+
}): ErrorBody;
|
|
30
62
|
export {};
|
package/dist/utils/response.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function a(e,n=200){return new Response(JSON.stringify(e),{status:n,headers:{"Content-Type":"application/json"}})}var
|
|
1
|
+
function a(e,n=200){return new Response(JSON.stringify(e),{status:n,headers:{"Content-Type":"application/json"}})}var d=(e,n=200)=>new Response(e,{status:n,headers:{"Content-Type":"text/plain; charset=utf-8"}}),r=Symbol.for("devix.redirect");function u(e,n){let o=typeof n=="number"?n:n?.status??302,s=typeof n=="object"?n?.replace??!1:!1;return{[r]:!0,url:e,status:o,replace:s}}function c(e){return typeof e=="object"&&e!==null&&r in e}var t=Symbol.for("devix.loaderError");function i(e,n,o){return{[t]:!0,statusCode:e,message:n,code:o?.code,data:o?.data}}function p(e){return typeof e=="object"&&e!==null&&t in e}function R(e){let n={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(n.code=e.code),e.data!==void 0&&(n.data=e.data),n}export{i as error,R as errorToBody,p as isLoaderError,c as isRedirect,a as json,u as redirect,d as text};
|
|
2
2
|
//# sourceMappingURL=response.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/response.ts"],
|
|
4
|
-
"sourcesContent": ["export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol.for('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol.for('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly data?: unknown\n}\n\nexport function error(statusCode: number, message: string,
|
|
5
|
-
"mappings": "AAOO,SAASA,EAAcC,EAASC,EAAiB,IAA2B,CAC/E,OAAO,IAAI,SAAS,KAAK,UAAUD,CAAI,EAAG,CACtC,OAAAC,EACA,QAAS,CAAC,eAAgB,kBAAkB,CAChD,CAAC,CACL,CAEO,IAAMC,EAAO,CAACC,EAAcF,EAAS,MACxC,IAAI,SAASE,EAAM,CAAC,OAAAF,EAAQ,QAAS,CAAC,eAAgB,2BAA2B,CAAC,CAAC,EAEjFG,EAAiB,OAAO,IAAI,gBAAgB,EAc3C,SAASC,EAASC,EAAaC,EAAsD,CACxF,IAAMN,EAAS,OAAOM,GAAoB,SAAWA,EAAmBA,GAAiB,QAAU,IAC7FC,EAAU,OAAOD,GAAoB,SAAYA,GAAiB,SAAW,GAAS,GAC5F,MAAO,CAAC,CAACH,CAAc,EAAG,GAAM,IAAAE,EAAK,OAAAL,EAAQ,QAAAO,CAAO,CACxD,CAEO,SAASC,EAAWC,EAAmC,CAC1D,OAAO,OAAOA,GAAU,UAAYA,IAAU,MAAQN,KAAkBM,CAC5E,CAEA,IAAMC,EAAc,OAAO,IAAI,mBAAmB,
|
|
6
|
-
"names": ["json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "isRedirect", "value", "ERROR_BRAND", "error", "statusCode", "message", "isLoaderError"]
|
|
4
|
+
"sourcesContent": ["export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol.for('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol.for('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly code?: string\n readonly data?: unknown\n}\n\nexport interface ErrorOptions {\n code?: string\n data?: unknown\n}\n\n/**\n * Crea un error tipado que funciona en loaders, guards y handlers API.\n *\n * En loaders/guards: ret\u00F3rnalo (no lo lances) y el sistema renderiza `error.tsx`.\n * En handlers API: ret\u00F3rnalo y el sistema serializa el shape `ErrorBody` como JSON\n * con el statusCode correcto.\n *\n * ```ts\n * return error(404, 'Post no encontrado', { code: 'POST_NOT_FOUND' })\n * ```\n */\nexport function error(statusCode: number, message: string, options?: ErrorOptions): RouteError {\n return {\n [ERROR_BRAND]: true,\n statusCode,\n message,\n code: options?.code,\n data: options?.data,\n } as RouteError\n}\n\nexport function isLoaderError(value: unknown): value is RouteError {\n return typeof value === 'object' && value !== null && ERROR_BRAND in value\n}\n\n/**\n * Shape p\u00FAblico del body de un error API. Todos los errores emitidos por `error()`\n * o `DevixError` se serializan a este shape. `FetchError.body` del cliente lo recibe.\n */\nexport interface ErrorBody {\n statusCode: number\n message: string\n code?: string\n data?: unknown\n}\n\nexport function errorToBody(err: { statusCode: number; message: string; code?: string; data?: unknown }): ErrorBody {\n const body: ErrorBody = { statusCode: err.statusCode, message: err.message }\n if (err.code !== undefined) body.code = err.code\n if (err.data !== undefined) body.data = err.data\n return body\n}\n"],
|
|
5
|
+
"mappings": "AAOO,SAASA,EAAcC,EAASC,EAAiB,IAA2B,CAC/E,OAAO,IAAI,SAAS,KAAK,UAAUD,CAAI,EAAG,CACtC,OAAAC,EACA,QAAS,CAAC,eAAgB,kBAAkB,CAChD,CAAC,CACL,CAEO,IAAMC,EAAO,CAACC,EAAcF,EAAS,MACxC,IAAI,SAASE,EAAM,CAAC,OAAAF,EAAQ,QAAS,CAAC,eAAgB,2BAA2B,CAAC,CAAC,EAEjFG,EAAiB,OAAO,IAAI,gBAAgB,EAc3C,SAASC,EAASC,EAAaC,EAAsD,CACxF,IAAMN,EAAS,OAAOM,GAAoB,SAAWA,EAAmBA,GAAiB,QAAU,IAC7FC,EAAU,OAAOD,GAAoB,SAAYA,GAAiB,SAAW,GAAS,GAC5F,MAAO,CAAC,CAACH,CAAc,EAAG,GAAM,IAAAE,EAAK,OAAAL,EAAQ,QAAAO,CAAO,CACxD,CAEO,SAASC,EAAWC,EAAmC,CAC1D,OAAO,OAAOA,GAAU,UAAYA,IAAU,MAAQN,KAAkBM,CAC5E,CAEA,IAAMC,EAAc,OAAO,IAAI,mBAAmB,EA0B3C,SAASC,EAAMC,EAAoBC,EAAiBC,EAAoC,CAC3F,MAAO,CACH,CAACJ,CAAW,EAAG,GACf,WAAAE,EACA,QAAAC,EACA,KAAMC,GAAS,KACf,KAAMA,GAAS,IACnB,CACJ,CAEO,SAASC,EAAcN,EAAqC,CAC/D,OAAO,OAAOA,GAAU,UAAYA,IAAU,MAAQC,KAAeD,CACzE,CAaO,SAASO,EAAYC,EAAwF,CAChH,IAAMf,EAAkB,CAAE,WAAYe,EAAI,WAAY,QAASA,EAAI,OAAQ,EAC3E,OAAIA,EAAI,OAAS,SAAWf,EAAK,KAAOe,EAAI,MACxCA,EAAI,OAAS,SAAWf,EAAK,KAAOe,EAAI,MACrCf,CACX",
|
|
6
|
+
"names": ["json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "isRedirect", "value", "ERROR_BRAND", "error", "statusCode", "message", "options", "isLoaderError", "errorToBody", "err"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipos del contrato Standard Schema v1 — https://standardschema.dev
|
|
3
|
+
*
|
|
4
|
+
* Implementado por Zod 3.24+, Valibot, ArkType, Effect Schema y otros.
|
|
5
|
+
* devix usa este contrato para validar bodies de handlers de forma agnóstica
|
|
6
|
+
* al validador.
|
|
7
|
+
*/
|
|
8
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
9
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
10
|
+
}
|
|
11
|
+
export declare namespace StandardSchemaV1 {
|
|
12
|
+
interface Props<Input = unknown, Output = Input> {
|
|
13
|
+
readonly version: 1;
|
|
14
|
+
readonly vendor: string;
|
|
15
|
+
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
16
|
+
readonly types?: Types<Input, Output>;
|
|
17
|
+
}
|
|
18
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
19
|
+
interface SuccessResult<Output> {
|
|
20
|
+
readonly value: Output;
|
|
21
|
+
readonly issues?: undefined;
|
|
22
|
+
}
|
|
23
|
+
interface FailureResult {
|
|
24
|
+
readonly issues: readonly Issue[];
|
|
25
|
+
}
|
|
26
|
+
interface Issue {
|
|
27
|
+
readonly message: string;
|
|
28
|
+
readonly path?: readonly (PropertyKey | PathSegment)[] | undefined;
|
|
29
|
+
}
|
|
30
|
+
interface PathSegment {
|
|
31
|
+
readonly key: PropertyKey;
|
|
32
|
+
}
|
|
33
|
+
interface Types<Input = unknown, Output = Input> {
|
|
34
|
+
readonly input: Input;
|
|
35
|
+
readonly output: Output;
|
|
36
|
+
}
|
|
37
|
+
type InferInput<S> = S extends StandardSchemaV1<infer I, any> ? I : never;
|
|
38
|
+
type InferOutput<S> = S extends StandardSchemaV1<any, infer O> ? O : never;
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=standard-schema.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function o({cssUrls:t}){return`
|
|
2
|
-
${t.map(
|
|
2
|
+
${t.map(a=>`import '${a}'`).join(`
|
|
3
3
|
`)}
|
|
4
4
|
import "@vitejs/plugin-react/preamble"
|
|
5
5
|
import React from "react"
|
|
@@ -16,11 +16,12 @@ if (!window.__DEVIX__) {
|
|
|
16
16
|
const {metadata, viewport, clientEntry} = window.__DEVIX__
|
|
17
17
|
const loaderData = window.__LOADER_DATA__
|
|
18
18
|
const layoutsData = window.__LAYOUTS_DATA__ ?? []
|
|
19
|
+
const guardData = window.__GUARD_DATA__ ?? null
|
|
19
20
|
|
|
20
21
|
const matched = matchClientRoute(window.location.pathname)
|
|
21
22
|
|
|
22
23
|
if (window.__LOADER_ERROR__) {
|
|
23
|
-
const {statusCode, message, data} = window.__LOADER_ERROR__
|
|
24
|
+
const {statusCode, message, code, data} = window.__LOADER_ERROR__
|
|
24
25
|
const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()
|
|
25
26
|
createRoot(root).render(
|
|
26
27
|
React.createElement(RouterProvider, {
|
|
@@ -28,7 +29,7 @@ if (!window.__DEVIX__) {
|
|
|
28
29
|
initialData: null,
|
|
29
30
|
initialParams: {},
|
|
30
31
|
initialPage: () => null,
|
|
31
|
-
initialError: {statusCode, message, data},
|
|
32
|
+
initialError: {statusCode, message, code, data},
|
|
32
33
|
initialErrorPage: ErrorPage,
|
|
33
34
|
})
|
|
34
35
|
)
|
|
@@ -46,6 +47,7 @@ if (!window.__DEVIX__) {
|
|
|
46
47
|
initialPage: pageMod.default,
|
|
47
48
|
initialLayouts: layoutMods.map(m => m.default),
|
|
48
49
|
initialLayoutsData: layoutsData,
|
|
50
|
+
initialGuardData: guardData,
|
|
49
51
|
initialMeta: metadata,
|
|
50
52
|
initialViewport: viewport,
|
|
51
53
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/vite/codegen/entry-client.ts"],
|
|
4
|
-
"sourcesContent": ["interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({ cssUrls }: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (window.__LOADER_ERROR__) {\n const {statusCode, message, data} = window.__LOADER_ERROR__\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialError: {statusCode, message, data},\n initialErrorPage: ErrorPage,\n })\n )\n } else if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n\n if (window.location.hash) { \n const id = window.location.hash.slice(1) \n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior \n requestAnimationFrame(() => { \n document.getElementById(id)?.scrollIntoView({ behavior: scrollBehavior }) \n }) \n } \n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}"],
|
|
5
|
-
"mappings": "AAIO,SAASA,EAAoB,CAAE,QAAAC,CAAQ,EAA+B,CAGzE,MAAO;AAAA,EAFYA,EAAQ,IAAIC,GAAK,WAAWA,CAAC,GAAG,EAAE,KAAK;AAAA,CAAI,CAGtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["interface EntryClientOptions {\n cssUrls: string[]\n}\n\nexport function generateEntryClient({ cssUrls }: EntryClientOptions): string {\n const cssImports = cssUrls.map(u => `import '${u}'`).join('\\n')\n\n return `\n${cssImports}\nimport \"@vitejs/plugin-react/preamble\"\nimport React from \"react\"\nimport {hydrateRoot, createRoot} from 'react-dom/client'\nimport {matchClientRoute, loadErrorPage, getDefaultErrorPage} from 'virtual:devix/client-routes'\nimport {RouterProvider} from '@devlusoft/devix'\n\nconst root = document.getElementById('devix-root')\n\nif (!window.__DEVIX__) {\n const ErrorPage = getDefaultErrorPage()\n createRoot(root).render(React.createElement(ErrorPage, {statusCode: 500, message: 'Server error'}))\n} else {\n const {metadata, viewport, clientEntry} = window.__DEVIX__\n const loaderData = window.__LOADER_DATA__\n const layoutsData = window.__LAYOUTS_DATA__ ?? []\n const guardData = window.__GUARD_DATA__ ?? null\n\n const matched = matchClientRoute(window.location.pathname)\n\n if (window.__LOADER_ERROR__) {\n const {statusCode, message, code, data} = window.__LOADER_ERROR__\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialError: {statusCode, message, code, data},\n initialErrorPage: ErrorPage,\n })\n )\n } else if (matched) {\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n hydrateRoot(\n root,\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: loaderData,\n initialParams: matched.params,\n initialPage: pageMod.default,\n initialLayouts: layoutMods.map(m => m.default),\n initialLayoutsData: layoutsData,\n initialGuardData: guardData,\n initialMeta: metadata,\n initialViewport: viewport,\n })\n )\n\n if (window.location.hash) { \n const id = window.location.hash.slice(1) \n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior \n requestAnimationFrame(() => { \n document.getElementById(id)?.scrollIntoView({ behavior: scrollBehavior }) \n }) \n } \n } else {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n createRoot(root).render(\n React.createElement(RouterProvider, {\n clientEntry,\n initialData: null,\n initialParams: {},\n initialPage: () => null,\n initialLayouts: [],\n initialLayoutsData: [],\n initialMeta: null,\n initialError: {statusCode: 404, message: 'Not found'},\n initialErrorPage: ErrorPage,\n })\n )\n }\n}\n`\n}"],
|
|
5
|
+
"mappings": "AAIO,SAASA,EAAoB,CAAE,QAAAC,CAAQ,EAA+B,CAGzE,MAAO;AAAA,EAFYA,EAAQ,IAAIC,GAAK,WAAWA,CAAC,GAAG,EAAE,KAAK;AAAA,CAAI,CAGtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA8EZ",
|
|
6
6
|
"names": ["generateEntryClient", "cssUrls", "u"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
export interface LoaderExportInfo {
|
|
2
|
+
exists: boolean;
|
|
3
|
+
isAsync: boolean;
|
|
4
|
+
isReExport: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function inspectLoaderExport(code: string, filePath: string): LoaderExportInfo;
|
|
1
7
|
export declare function hasLoaderExport(code: string, filePath: string): boolean;
|
|
2
8
|
export declare function generatePageTypesDts(importPath: string, withLoader: boolean): string;
|
|
3
|
-
export
|
|
9
|
+
export interface WritePageTypesResult {
|
|
10
|
+
warnings: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function writePageTypes(pageRelPath: string, root: string): WritePageTypesResult;
|
|
4
13
|
export declare function deletePageTypes(pageRelPath: string, root: string): void;
|
|
5
|
-
export declare function scanAndWritePageTypes(appDir: string, root: string):
|
|
14
|
+
export declare function scanAndWritePageTypes(appDir: string, root: string): WritePageTypesResult;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{existsSync as d,mkdirSync as
|
|
2
|
-
import type { loader } from "${
|
|
1
|
+
import{existsSync as d,mkdirSync as m,readdirSync as P,readFileSync as f,rmSync as E,statSync as b,writeFileSync as v}from"node:fs";import{join as a,relative as l}from"node:path";import{parseSync as A}from"oxc-parser";function u(n,e){let s=[];for(let t of P(n)){let r=a(n,t);b(r).isDirectory()?s.push(...u(r,e)):/\.(ts|tsx)$/.test(t)&&t!=="layout.tsx"&&t!=="error.tsx"&&s.push(l(e,r).replace(/\\/g,"/"))}return s}function x(n,e){let s=A(e,n,{sourceType:"module"});for(let t of s.program.body){if(t.type!=="ExportNamedDeclaration")continue;let r=t.declaration;if(r?.type==="FunctionDeclaration"&&r.id?.name==="loader")return{exists:!0,isAsync:r.async,isReExport:!1};if(r?.type==="VariableDeclaration"){for(let o of r.declarations)if(o.id.type==="Identifier"&&o.id.name==="loader"){let i=o.init;return{exists:!0,isAsync:i?.type==="ArrowFunctionExpression"&&i.async||i?.type==="FunctionExpression"&&i.async,isReExport:!1}}}for(let o of t.specifiers??[])if(o.exported.type==="Identifier"&&o.exported.name==="loader")return{exists:!0,isAsync:!1,isReExport:!0}}return{exists:!1,isAsync:!1,isReExport:!1}}function S(n,e){return x(n,e).exists}function R(n,e){return e?`// auto-generado por devix \u2014 no editar
|
|
2
|
+
import type { loader } from "${n}"
|
|
3
3
|
import type { Redirect } from "@devlusoft/devix"
|
|
4
4
|
|
|
5
5
|
export type PageData = Exclude<
|
|
@@ -10,5 +10,5 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
|
10
10
|
`:`// auto-generado por devix - no editar
|
|
11
11
|
export type PageData = undefined
|
|
12
12
|
export type PageParams = Record<string, string>
|
|
13
|
-
`}function
|
|
13
|
+
`}function D(n,e){let s=a(e,n),t=f(s,"utf-8"),r=x(t,s),o=[];r.exists&&!r.isAsync&&!r.isReExport&&o.push(`[devix] ${n}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let i=a(e,".devix","pages",n.replace(/\.(tsx?|jsx?)$/,"")),c=a(i,"$types.d.ts"),y=s.replace(/\.(tsx?|jsx?)$/,""),g=l(i,y).replace(/\\/g,"/"),p=R(g,r.exists);return d(c)&&f(c,"utf-8")===p?{warnings:o}:(m(i,{recursive:!0}),v(c,p,"utf-8"),{warnings:o})}function $(n,e){let s=a(e,".devix","pages",n.replace(/\.(tsx?|jsx?)$/,"")),t=a(s,"$types.d.ts");d(t)&&E(t)}function N(n,e){let s=a(e,n,"pages"),t=[],r;try{r=u(s,e)}catch{return{warnings:t}}for(let o of r)try{let i=D(o,e);t.push(...i.warnings)}catch{}return{warnings:t}}export{$ as deletePageTypes,R as generatePageTypesDts,S as hasLoaderExport,x as inspectLoaderExport,N as scanAndWritePageTypes,D as writePageTypes};
|
|
14
14
|
//# sourceMappingURL=page-types.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/vite/codegen/page-types.ts"],
|
|
4
|
-
"sourcesContent": ["import {existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync} from \"node:fs\";\nimport {join, relative} from \"node:path\";\nimport {parseSync} from \"oxc-parser\";\n\nfunction walkPages(dir: string, root: string): string[] {\n const entries: string[] = []\n for (const name of readdirSync(dir)) {\n const full = join(dir, name)\n if (statSync(full).isDirectory()) {\n entries.push(...walkPages(full, root))\n } else if (/\\.(ts|tsx)$/.test(name) && name !== 'layout.tsx' && name !== 'error.tsx') {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport function
|
|
5
|
-
"mappings": "AAAA,OAAQ,cAAAA,EAAY,aAAAC,EAAW,eAAAC,EAAa,gBAAAC,EAAc,UAAAC,EAAQ,YAAAC,EAAU,iBAAAC,MAAoB,UAChG,OAAQ,QAAAC,EAAM,YAAAC,MAAe,YAC7B,OAAQ,aAAAC,MAAgB,aAExB,SAASC,EAAUC,EAAaC,EAAwB,CACpD,IAAMC,EAAoB,CAAC,EAC3B,QAAWC,KAAQZ,EAAYS,CAAG,EAAG,CACjC,IAAMI,EAAOR,EAAKI,EAAKG,CAAI,EACvBT,EAASU,CAAI,EAAE,YAAY,EAC3BF,EAAQ,KAAK,GAAGH,EAAUK,EAAMH,CAAI,CAAC,EAC9B,cAAc,KAAKE,CAAI,GAAKA,IAAS,cAAgBA,IAAS,aACrED,EAAQ,KAAKL,EAASI,EAAMG,CAAI,EAAE,QAAQ,MAAO,GAAG,CAAC,CAE7D,CACA,OAAOF,CACX,
|
|
6
|
-
"names": ["existsSync", "mkdirSync", "readdirSync", "readFileSync", "rmSync", "statSync", "writeFileSync", "join", "relative", "parseSync", "walkPages", "dir", "root", "entries", "name", "full", "
|
|
4
|
+
"sourcesContent": ["import {existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync} from \"node:fs\";\nimport {join, relative} from \"node:path\";\nimport {parseSync} from \"oxc-parser\";\n\nfunction walkPages(dir: string, root: string): string[] {\n const entries: string[] = []\n for (const name of readdirSync(dir)) {\n const full = join(dir, name)\n if (statSync(full).isDirectory()) {\n entries.push(...walkPages(full, root))\n } else if (/\\.(ts|tsx)$/.test(name) && name !== 'layout.tsx' && name !== 'error.tsx') {\n entries.push(relative(root, full).replace(/\\\\/g, '/'))\n }\n }\n return entries\n}\n\nexport interface LoaderExportInfo {\n exists: boolean\n isAsync: boolean\n isReExport: boolean\n}\n\nexport function inspectLoaderExport(code: string, filePath: string): LoaderExportInfo {\n const ast = parseSync(filePath, code, {sourceType: 'module'})\n for (const node of ast.program.body) {\n if (node.type !== 'ExportNamedDeclaration') continue\n const decl = node.declaration\n if (decl?.type === 'FunctionDeclaration' && decl.id?.name === 'loader') {\n return {exists: true, isAsync: decl.async, isReExport: false}\n }\n if (decl?.type === 'VariableDeclaration') {\n for (const d of decl.declarations) {\n if (d.id.type === 'Identifier' && d.id.name === 'loader') {\n const init = d.init\n const isAsync =\n (init?.type === 'ArrowFunctionExpression' && init.async) ||\n (init?.type === 'FunctionExpression' && init.async)\n return {exists: true, isAsync, isReExport: false}\n }\n }\n }\n for (const spec of (node.specifiers ?? [])) {\n if (spec.exported.type === 'Identifier' && spec.exported.name === 'loader') {\n return {exists: true, isAsync: false, isReExport: true}\n }\n }\n }\n return {exists: false, isAsync: false, isReExport: false}\n}\n\nexport function hasLoaderExport(code: string, filePath: string): boolean {\n return inspectLoaderExport(code, filePath).exists\n}\n\nexport function generatePageTypesDts(importPath: string, withLoader: boolean): string {\n if (!withLoader) {\n return '// auto-generado por devix - no editar\\nexport type PageData = undefined\\nexport type PageParams = Record<string, string>\\n'\n }\n return `// auto-generado por devix \u2014 no editar\\nimport type { loader } from \"${importPath}\"\\nimport type { Redirect } from \"@devlusoft/devix\"\\n\\nexport type PageData = Exclude<\\n Awaited<ReturnType<NonNullable<typeof loader>>>,\\n Redirect | void | undefined\\n>\\nexport type PageParams = NonNullable<Parameters<typeof loader>[0]>[\"params\"]\\n`\n}\n\nexport interface WritePageTypesResult {\n warnings: string[]\n}\n\nexport function writePageTypes(pageRelPath: string, root: string): WritePageTypesResult {\n const fullPath = join(root, pageRelPath)\n const code = readFileSync(fullPath, 'utf-8')\n const loaderInfo = inspectLoaderExport(code, fullPath)\n const warnings: string[] = []\n\n if (loaderInfo.exists && !loaderInfo.isAsync && !loaderInfo.isReExport) {\n warnings.push(\n `[devix] ${pageRelPath}: 'loader' must be async. ` +\n `Use 'export async function loader' or 'export const loader = async (...) => ...'.`\n )\n }\n\n const typesDir = join(root, '.devix', 'pages', pageRelPath.replace(/\\.(tsx?|jsx?)$/, ''))\n const outPath = join(typesDir, '$types.d.ts')\n\n const pageAbsNoExt = fullPath.replace(/\\.(tsx?|jsx?)$/, '')\n const importPath = relative(typesDir, pageAbsNoExt).replace(/\\\\/g, '/')\n\n const content = generatePageTypesDts(importPath, loaderInfo.exists)\n\n if (existsSync(outPath) && readFileSync(outPath, 'utf-8') === content) return {warnings}\n\n mkdirSync(typesDir, {recursive: true})\n writeFileSync(outPath, content, 'utf-8')\n return {warnings}\n}\n\nexport function deletePageTypes(pageRelPath: string, root: string): void {\n const typesDir = join(root, '.devix', 'pages', pageRelPath.replace(/\\.(tsx?|jsx?)$/, ''))\n const outPath = join(typesDir, '$types.d.ts')\n if (existsSync(outPath)) rmSync(outPath)\n}\n\nexport function scanAndWritePageTypes(appDir: string, root: string): WritePageTypesResult {\n const pagesDir = join(root, appDir, 'pages')\n const warnings: string[] = []\n let files: string[]\n try {\n files = walkPages(pagesDir, root)\n } catch {\n return {warnings}\n }\n for (const file of files) {\n try {\n const result = writePageTypes(file, root)\n warnings.push(...result.warnings)\n } catch {\n /* ignorar archivos no procesables */\n }\n }\n return {warnings}\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["existsSync", "mkdirSync", "readdirSync", "readFileSync", "rmSync", "statSync", "writeFileSync", "join", "relative", "parseSync", "walkPages", "dir", "root", "entries", "name", "full", "inspectLoaderExport", "code", "filePath", "ast", "node", "decl", "d", "init", "spec", "hasLoaderExport", "generatePageTypesDts", "importPath", "withLoader", "writePageTypes", "pageRelPath", "fullPath", "loaderInfo", "warnings", "typesDir", "outPath", "pageAbsNoExt", "content", "deletePageTypes", "scanAndWritePageTypes", "appDir", "pagesDir", "files", "file", "result"]
|
|
7
7
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
function
|
|
1
|
+
function n({routesPath:e,envPath:r,honoServerPath:o,honoServerStaticPath:t,honoPath:i}){return`
|
|
2
2
|
import { readFileSync } from 'node:fs'
|
|
3
3
|
import { serve } from '${o}'
|
|
4
|
-
import { serveStatic } from '${
|
|
5
|
-
import { Hono } from '${
|
|
4
|
+
import { serveStatic } from '${t}'
|
|
5
|
+
import { Hono } from '${i}'
|
|
6
6
|
import { resolve, join, dirname } from 'node:path'
|
|
7
7
|
import { pathToFileURL } from 'node:url'
|
|
8
8
|
import { registerApiRoutes, registerSsrRoute } from '${e}'
|
|
9
|
-
import { loadDotenv } from '${
|
|
9
|
+
import { loadDotenv } from '${r}'
|
|
10
10
|
|
|
11
11
|
loadDotenv('production')
|
|
12
12
|
|
|
@@ -59,9 +59,17 @@ import { readFileSync } from 'node:fs'
|
|
|
59
59
|
|
|
60
60
|
if (runtimeConfig.output === 'static') {
|
|
61
61
|
console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')
|
|
62
|
-
} else {
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
} else {
|
|
63
|
+
let userServerConfig
|
|
64
|
+
try {
|
|
65
|
+
const userConfigMod = await import(pathToFileURL(resolve(process.cwd(), 'devix.config.ts')).href).catch(() =>
|
|
66
|
+
import(pathToFileURL(resolve(process.cwd(), 'devix.config.js')).href))
|
|
67
|
+
userServerConfig = userConfigMod?.default?.server
|
|
68
|
+
} catch {
|
|
69
|
+
/* config sin server \u2014 sigue normal */
|
|
70
|
+
}
|
|
71
|
+
registerApiRoutes(app, { renderModule, apiModule, manifest, server: userServerConfig })
|
|
72
|
+
registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout, server: userServerConfig })
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
const server = serve({ fetch: app.fetch, port, hostname: host }, (info) =>
|
|
@@ -69,5 +77,5 @@ import { readFileSync } from 'node:fs'
|
|
|
69
77
|
|
|
70
78
|
process.on('SIGTERM', () => server.close())
|
|
71
79
|
process.on('SIGINT', () => server.close())
|
|
72
|
-
`}export{
|
|
80
|
+
`}export{n as generateServerEntry};
|
|
73
81
|
//# sourceMappingURL=server-entry.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/vite/codegen/server-entry.ts"],
|
|
4
|
-
"sourcesContent": ["interface ServerEntryOptions {\n routesPath: string\n envPath: string\n honoServerPath: string\n honoServerStaticPath: string\n honoPath: string\n}\n\nexport function generateServerEntry({ routesPath, envPath, honoServerPath, honoServerStaticPath, honoPath }: ServerEntryOptions): string {\n return `\nimport { readFileSync } from 'node:fs'\n import { serve } from '${honoServerPath}'\n import { serveStatic } from '${honoServerStaticPath}'\n import { Hono } from '${honoPath}'\n import { resolve, join, dirname } from 'node:path'\n import { pathToFileURL } from 'node:url'\n import { registerApiRoutes, registerSsrRoute } from '${routesPath}' \n import { loadDotenv } from '${envPath}'\n \n loadDotenv('production')\n \n const __dir = dirname(process.argv[1])\n\n let renderModule, apiModule, manifest, runtimeConfig \n \n try { \n runtimeConfig = JSON.parse(readFileSync(resolve(__dir, '../devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') { \n renderModule = await import(pathToFileURL(resolve(__dir, 'render.js')).href)\n apiModule = await import(pathToFileURL(resolve(__dir, 'api.js')).href) \n } \n manifest = JSON.parse(readFileSync(resolve(__dir, '../client/.vite/manifest.json'), 'utf-8')) \n } catch { \n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1) \n } \n \n const port = Number(process.env.PORT) || runtimeConfig.port || 3000 \n const host = typeof runtimeConfig.host === 'string'\n ? runtimeConfig.host \n : runtimeConfig.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0') \n \n const clientRoot = resolve(__dir, '../client') \n const app = new Hono()\n \n if (runtimeConfig.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\\\/_data/, '') || '/' \n const filePath = pathname === '/' \n ? join(clientRoot, '_data/index.json') \n : join(clientRoot, '_data', pathname + '.json') \n try { \n return c.json(JSON.parse(readFileSync(filePath, 'utf-8')))\n } catch { \n return c.json({ error: 'not found' }, 404)\n } \n }) \n }\n\n app.use('/*', serveStatic({ \n root: clientRoot,\n onFound: (_path, c) => { \n c.header('Cache-Control', _path.includes('/assets/') \n ? 'public, immutable, max-age=31536000'\n : 'no-cache') \n } \n })) \n \n if (runtimeConfig.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n } else {
|
|
5
|
-
"mappings": "AAQO,SAASA,EAAoB,CAAE,WAAAC,EAAY,QAAAC,EAAS,eAAAC,EAAgB,qBAAAC,EAAsB,SAAAC,CAAS,EAA+B,CACrI,MAAO;AAAA;AAAA,2BAEgBF,CAAc;AAAA,iCACRC,CAAoB;AAAA,0BAC3BC,CAAQ;AAAA;AAAA;AAAA,yDAGuBJ,CAAU;AAAA,gCACnCC,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["interface ServerEntryOptions {\n routesPath: string\n envPath: string\n honoServerPath: string\n honoServerStaticPath: string\n honoPath: string\n}\n\nexport function generateServerEntry({ routesPath, envPath, honoServerPath, honoServerStaticPath, honoPath }: ServerEntryOptions): string {\n return `\nimport { readFileSync } from 'node:fs'\n import { serve } from '${honoServerPath}'\n import { serveStatic } from '${honoServerStaticPath}'\n import { Hono } from '${honoPath}'\n import { resolve, join, dirname } from 'node:path'\n import { pathToFileURL } from 'node:url'\n import { registerApiRoutes, registerSsrRoute } from '${routesPath}' \n import { loadDotenv } from '${envPath}'\n \n loadDotenv('production')\n \n const __dir = dirname(process.argv[1])\n\n let renderModule, apiModule, manifest, runtimeConfig \n \n try { \n runtimeConfig = JSON.parse(readFileSync(resolve(__dir, '../devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') { \n renderModule = await import(pathToFileURL(resolve(__dir, 'render.js')).href)\n apiModule = await import(pathToFileURL(resolve(__dir, 'api.js')).href) \n } \n manifest = JSON.parse(readFileSync(resolve(__dir, '../client/.vite/manifest.json'), 'utf-8')) \n } catch { \n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1) \n } \n \n const port = Number(process.env.PORT) || runtimeConfig.port || 3000 \n const host = typeof runtimeConfig.host === 'string'\n ? runtimeConfig.host \n : runtimeConfig.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0') \n \n const clientRoot = resolve(__dir, '../client') \n const app = new Hono()\n \n if (runtimeConfig.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\\\/_data/, '') || '/' \n const filePath = pathname === '/' \n ? join(clientRoot, '_data/index.json') \n : join(clientRoot, '_data', pathname + '.json') \n try { \n return c.json(JSON.parse(readFileSync(filePath, 'utf-8')))\n } catch { \n return c.json({ error: 'not found' }, 404)\n } \n }) \n }\n\n app.use('/*', serveStatic({ \n root: clientRoot,\n onFound: (_path, c) => { \n c.header('Cache-Control', _path.includes('/assets/') \n ? 'public, immutable, max-age=31536000'\n : 'no-cache') \n } \n })) \n \n if (runtimeConfig.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n } else {\n let userServerConfig\n try {\n const userConfigMod = await import(pathToFileURL(resolve(process.cwd(), 'devix.config.ts')).href).catch(() =>\n import(pathToFileURL(resolve(process.cwd(), 'devix.config.js')).href))\n userServerConfig = userConfigMod?.default?.server\n } catch {\n /* config sin server \u2014 sigue normal */\n }\n registerApiRoutes(app, { renderModule, apiModule, manifest, server: userServerConfig })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout, server: userServerConfig })\n } \n \n const server = serve({ fetch: app.fetch, port, hostname: host }, (info) => \n console.log(\\`http://\\${info.address}:\\${info.port}\\`))\n\nprocess.on('SIGTERM', () => server.close())\nprocess.on('SIGINT', () => server.close())\n`\n}"],
|
|
5
|
+
"mappings": "AAQO,SAASA,EAAoB,CAAE,WAAAC,EAAY,QAAAC,EAAS,eAAAC,EAAgB,qBAAAC,EAAsB,SAAAC,CAAS,EAA+B,CACrI,MAAO;AAAA;AAAA,2BAEgBF,CAAc;AAAA,iCACRC,CAAoB;AAAA,0BAC3BC,CAAQ;AAAA;AAAA;AAAA,yDAGuBJ,CAAU;AAAA,gCACnCC,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAwEvC",
|
|
6
6
|
"names": ["generateServerEntry", "routesPath", "envPath", "honoServerPath", "honoServerStaticPath", "honoPath"]
|
|
7
7
|
}
|
package/dist/vite/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{mergeConfig as
|
|
1
|
+
import{mergeConfig as we}from"vite";import Te from"@vitejs/plugin-react";import{fileURLToPath as Se}from"node:url";import{dirname as $e,relative as Ae,resolve as u}from"node:path";import{createRequire as De}from"node:module";function U({cssUrls:e}){return`
|
|
2
2
|
${e.map(r=>`import '${r}'`).join(`
|
|
3
3
|
`)}
|
|
4
4
|
import "@vitejs/plugin-react/preamble"
|
|
@@ -16,11 +16,12 @@ if (!window.__DEVIX__) {
|
|
|
16
16
|
const {metadata, viewport, clientEntry} = window.__DEVIX__
|
|
17
17
|
const loaderData = window.__LOADER_DATA__
|
|
18
18
|
const layoutsData = window.__LAYOUTS_DATA__ ?? []
|
|
19
|
+
const guardData = window.__GUARD_DATA__ ?? null
|
|
19
20
|
|
|
20
21
|
const matched = matchClientRoute(window.location.pathname)
|
|
21
22
|
|
|
22
23
|
if (window.__LOADER_ERROR__) {
|
|
23
|
-
const {statusCode, message, data} = window.__LOADER_ERROR__
|
|
24
|
+
const {statusCode, message, code, data} = window.__LOADER_ERROR__
|
|
24
25
|
const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()
|
|
25
26
|
createRoot(root).render(
|
|
26
27
|
React.createElement(RouterProvider, {
|
|
@@ -28,7 +29,7 @@ if (!window.__DEVIX__) {
|
|
|
28
29
|
initialData: null,
|
|
29
30
|
initialParams: {},
|
|
30
31
|
initialPage: () => null,
|
|
31
|
-
initialError: {statusCode, message, data},
|
|
32
|
+
initialError: {statusCode, message, code, data},
|
|
32
33
|
initialErrorPage: ErrorPage,
|
|
33
34
|
})
|
|
34
35
|
)
|
|
@@ -46,6 +47,7 @@ if (!window.__DEVIX__) {
|
|
|
46
47
|
initialPage: pageMod.default,
|
|
47
48
|
initialLayouts: layoutMods.map(m => m.default),
|
|
48
49
|
initialLayoutsData: layoutsData,
|
|
50
|
+
initialGuardData: guardData,
|
|
49
51
|
initialMeta: metadata,
|
|
50
52
|
initialViewport: viewport,
|
|
51
53
|
})
|
|
@@ -103,7 +105,7 @@ export function getDefaultErrorPage() {
|
|
|
103
105
|
)
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
|
-
`}function
|
|
108
|
+
`}function H({pagesDir:e,renderPath:t}){return`
|
|
107
109
|
import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${t}'
|
|
108
110
|
|
|
109
111
|
const _pages = import.meta.glob(['/${e}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
@@ -126,7 +128,7 @@ export function runLoader(url, request, options) {
|
|
|
126
128
|
export function getStaticRoutes() {
|
|
127
129
|
return _getStaticRoutes(_glob)
|
|
128
130
|
}
|
|
129
|
-
`}function
|
|
131
|
+
`}function N({apiPath:e,appDir:t}){return`
|
|
130
132
|
import { handleApiRequest as _handleApiRequest } from '${e}'
|
|
131
133
|
|
|
132
134
|
const _routes = import.meta.glob(['/${t}/api/**/*.ts', '!**/middleware.ts'])
|
|
@@ -141,15 +143,15 @@ const _glob = {
|
|
|
141
143
|
export function handleApiRequest(url, request) {
|
|
142
144
|
return _handleApiRequest(url, request, _glob)
|
|
143
145
|
}
|
|
144
|
-
`}function
|
|
146
|
+
`}function W(){return`
|
|
145
147
|
export {RouterContext} from '@devlusoft/devix/runtime/context'
|
|
146
|
-
`}import{readFileSync as ce,readdirSync as le,statSync as
|
|
148
|
+
`}import{readFileSync as ce,readdirSync as le,statSync as pe}from"node:fs";import{join as A,relative as ue}from"node:path";var ie=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g;function se(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function k(e){let t=new Set;for(let r of se(e).matchAll(ie))t.add(r[1]);return[...t]}function V(e){return e.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}function q(e,t){let r=e.slice(t.length+1).replace(/\\/g,"/"),i=V(r);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}function ae(e,t){return"_api_"+e.slice(`${t}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function B(e,t,r){return{filePath:e,urlPattern:q(e,t),identifier:ae(e,t),methods:r}}function $(e,t){if(e.length===0)return`// auto-generado por devix \u2014 no editar
|
|
147
149
|
export {}
|
|
148
150
|
declare module '@devlusoft/devix' {
|
|
149
151
|
interface ApiRoutes {}
|
|
150
152
|
}
|
|
151
153
|
`;let r=e.map(o=>{let a="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${a}'`}).join(`
|
|
152
|
-
`),
|
|
154
|
+
`),i=e.flatMap(o=>o.methods.map(a=>` '${a} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${a}']>`)).join(`
|
|
153
155
|
`);return`// auto-generado por devix \u2014 no editar
|
|
154
156
|
${r}
|
|
155
157
|
|
|
@@ -170,13 +172,13 @@ type InferRoute<T> =
|
|
|
170
172
|
|
|
171
173
|
declare module '@devlusoft/devix' {
|
|
172
174
|
interface ApiRoutes {
|
|
173
|
-
${
|
|
175
|
+
${i}
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
|
-
`}function
|
|
178
|
+
`}function J(e,t){let r=[];for(let i of le(e)){let o=A(e,i);pe(o).isDirectory()?r.push(...J(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(ue(t,o).replace(/\\/g,"/"))}return r}function D(e,t){let r=A(t,e,"api"),i;try{i=J(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=ce(A(t,o),"utf-8"),p=k(a);return p.length===0?[]:[B(o,`${e}/api`,p)]}catch{return[]}})}import{mkdirSync as de,readFileSync as fe,writeFileSync as ge,existsSync as me}from"node:fs";import{join as G}from"node:path";function b(e,t){let r=G(t,".devix"),i=G(r,"routes.d.ts");return de(r,{recursive:!0}),me(i)&&fe(i,"utf-8")===e?!1:(ge(i,e,"utf-8"),!0)}import{parseSync as be}from"oxc-parser";function X({routesPath:e,envPath:t,honoServerPath:r,honoServerStaticPath:i,honoPath:o}){return`
|
|
177
179
|
import { readFileSync } from 'node:fs'
|
|
178
180
|
import { serve } from '${r}'
|
|
179
|
-
import { serveStatic } from '${
|
|
181
|
+
import { serveStatic } from '${i}'
|
|
180
182
|
import { Hono } from '${o}'
|
|
181
183
|
import { resolve, join, dirname } from 'node:path'
|
|
182
184
|
import { pathToFileURL } from 'node:url'
|
|
@@ -234,9 +236,17 @@ import { readFileSync } from 'node:fs'
|
|
|
234
236
|
|
|
235
237
|
if (runtimeConfig.output === 'static') {
|
|
236
238
|
console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')
|
|
237
|
-
} else {
|
|
238
|
-
|
|
239
|
-
|
|
239
|
+
} else {
|
|
240
|
+
let userServerConfig
|
|
241
|
+
try {
|
|
242
|
+
const userConfigMod = await import(pathToFileURL(resolve(process.cwd(), 'devix.config.ts')).href).catch(() =>
|
|
243
|
+
import(pathToFileURL(resolve(process.cwd(), 'devix.config.js')).href))
|
|
244
|
+
userServerConfig = userConfigMod?.default?.server
|
|
245
|
+
} catch {
|
|
246
|
+
/* config sin server \u2014 sigue normal */
|
|
247
|
+
}
|
|
248
|
+
registerApiRoutes(app, { renderModule, apiModule, manifest, server: userServerConfig })
|
|
249
|
+
registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig.loaderTimeout, server: userServerConfig })
|
|
240
250
|
}
|
|
241
251
|
|
|
242
252
|
const server = serve({ fetch: app.fetch, port, hostname: host }, (info) =>
|
|
@@ -244,7 +254,7 @@ import { readFileSync } from 'node:fs'
|
|
|
244
254
|
|
|
245
255
|
process.on('SIGTERM', () => server.close())
|
|
246
256
|
process.on('SIGINT', () => server.close())
|
|
247
|
-
`}import{existsSync as
|
|
257
|
+
`}import{existsSync as z,mkdirSync as xe,readdirSync as ye,readFileSync as Y,rmSync as he,statSync as Re,writeFileSync as ve}from"node:fs";import{join as x,relative as Z}from"node:path";import{parseSync as Ee}from"oxc-parser";function K(e,t){let r=[];for(let i of ye(e)){let o=x(e,i);Re(o).isDirectory()?r.push(...K(o,t)):/\.(ts|tsx)$/.test(i)&&i!=="layout.tsx"&&i!=="error.tsx"&&r.push(Z(t,o).replace(/\\/g,"/"))}return r}function _e(e,t){let r=Ee(t,e,{sourceType:"module"});for(let i of r.program.body){if(i.type!=="ExportNamedDeclaration")continue;let o=i.declaration;if(o?.type==="FunctionDeclaration"&&o.id?.name==="loader")return{exists:!0,isAsync:o.async,isReExport:!1};if(o?.type==="VariableDeclaration"){for(let a of o.declarations)if(a.id.type==="Identifier"&&a.id.name==="loader"){let p=a.init;return{exists:!0,isAsync:p?.type==="ArrowFunctionExpression"&&p.async||p?.type==="FunctionExpression"&&p.async,isReExport:!1}}}for(let a of i.specifiers??[])if(a.exported.type==="Identifier"&&a.exported.name==="loader")return{exists:!0,isAsync:!1,isReExport:!0}}return{exists:!1,isAsync:!1,isReExport:!1}}function Pe(e,t){return t?`// auto-generado por devix \u2014 no editar
|
|
248
258
|
import type { loader } from "${e}"
|
|
249
259
|
import type { Redirect } from "@devlusoft/devix"
|
|
250
260
|
|
|
@@ -256,5 +266,5 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
|
256
266
|
`:`// auto-generado por devix - no editar
|
|
257
267
|
export type PageData = undefined
|
|
258
268
|
export type PageParams = Record<string, string>
|
|
259
|
-
`}function
|
|
269
|
+
`}function C(e,t){let r=x(t,e),i=Y(r,"utf-8"),o=_e(i,r),a=[];o.exists&&!o.isAsync&&!o.isReExport&&a.push(`[devix] ${e}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let p=x(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),y=x(p,"$types.d.ts"),S=r.replace(/\.(tsx?|jsx?)$/,""),h=Z(p,S).replace(/\\/g,"/"),T=Pe(h,o.exists);return z(y)&&Y(y,"utf-8")===T?{warnings:a}:(xe(p,{recursive:!0}),ve(y,T,"utf-8"),{warnings:a})}function Q(e,t){let r=x(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),i=x(r,"$types.d.ts");z(i)&&he(i)}function I(e,t){let r=x(t,e,"pages"),i=[],o;try{o=K(r,t)}catch{return{warnings:i}}for(let a of o)try{let p=C(a,t);i.push(...p.warnings)}catch{}return{warnings:i}}var _=$e(Se(import.meta.url)),M="virtual:devix/entry-client",F="virtual:devix/client-routes",P="virtual:devix/render",w="virtual:devix/api",O="virtual:devix/context",L="virtual:devix/server-entry",ee=new Set(["loader","guard","generateStaticParams","headers"]);function Rt(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(s=>s.startsWith("/")?s:`/${s.replace(/^\.\//,"")}`),o=u(_,"../server/render.js").replace(/\\/g,"/"),a=u(_,"../server/api.js").replace(/\\/g,"/"),p=u(_,"../runtime/client-router.js").replace(/\\/g,"/"),y=u(_,"../server/routes.js").replace(/\\/g,"/"),S=u(_,"../utils/env.js").replace(/\\/g,"/"),h=De(import.meta.url),T=h.resolve("@hono/node-server").replace(/\\/g,"/"),te=h.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),re=h.resolve("hono").replace(/\\/g,"/"),ne={name:"devix",enforce:"pre",resolveId(s){if(s===M)return`\0${M}`;if(s===F)return`\0${F}`;if(s===P)return`\0${P}`;if(s===w)return`\0${w}`;if(s===O)return`\0${O}`;if(s===L)return`\0${L}`},load(s){if(s===`\0${M}`)return U({cssUrls:i});if(s===`\0${F}`)return j({pagesDir:r,matcherPath:p});if(s===`\0${P}`)return H({pagesDir:r,renderPath:o});if(s===`\0${w}`)return N({apiPath:a,appDir:t});if(s===`\0${O}`)return W();if(s===`\0${L}`)return X({routesPath:y,envPath:S,honoServerPath:T,honoServerStaticPath:te,honoPath:re})},transform(s,c,R){if(R?.ssr)return;let m=u(process.cwd(),r);if(!c.startsWith(m))return;let v=be(c,s,{sourceType:"module"}),g=[];for(let l of v.program.body){if(l.type!=="ExportNamedDeclaration"||!l.declaration)continue;let n=l.declaration;if(n.type==="FunctionDeclaration"&&n.id&&ee.has(n.id.name)&&g.push({start:l.start,end:l.end,name:n.id.name}),n.type==="VariableDeclaration"){let f=new Set;for(let E of n.declarations)E.id.type==="Identifier"&&ee.has(E.id.name)&&(f.has(l.start)||(f.add(l.start),g.push({start:l.start,end:l.end,name:E.id.name})))}}if(g.length===0)return;g.sort((l,n)=>n.start-l.start);let d=s;for(let{start:l,end:n,name:f}of g)d=d.slice(0,l)+`export const ${f} = undefined`+d.slice(n);return{code:d,map:null}},buildStart(){let s=process.cwd(),c=D(t,s);b($(c,`${t}/api`),s);let{warnings:R}=I(t,s);for(let m of R)console.warn(m)},configureServer(s){let c=process.cwd(),R=I(t,c);for(let n of R.warnings)console.warn(n);let m=()=>{let n=D(t,c);b($(n,`${t}/api`),c)},v=n=>n.startsWith(u(c,r))&&!n.endsWith("layout.tsx")&&!n.endsWith("error.tsx"),g=n=>Ae(c,n).replace(/\\/g,"/"),d=n=>{let f=s.moduleGraph.getModuleById(`\0${n}`);f&&s.moduleGraph.invalidateModule(f)};s.watcher.add(u(c,"devix.config.ts")),s.watcher.on("change",n=>{n===u(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))});let l=n=>{try{let{warnings:f}=C(g(n),c);for(let E of f)console.warn(E)}catch{}};s.watcher.on("add",n=>{n.startsWith(u(c,r))&&d(P),v(n)&&l(n),n.includes(`${t}/api`)&&(d(w),m())}),s.watcher.on("unlink",n=>{n.startsWith(u(c,r))&&d(P),v(n)&&Q(g(n),c),n.includes(`${t}/api`)&&(d(w),m())}),s.watcher.on("change",n=>{v(n)&&l(n),n.includes(`${t}/api`)&&!n.endsWith("middleware.ts")&&m()})}},oe={plugins:[Te(),ne],publicDir:u(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return we(oe,e.vite??{})}export{Rt as devix};
|
|
260
270
|
//# sourceMappingURL=index.js.map
|