@devlusoft/devix 0.5.1 → 0.5.2
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 +5 -3
- package/dist/cli/dev-server.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/runtime/api-context.d.ts +2 -2
- package/dist/runtime/api-context.js.map +2 -2
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +3 -3
- package/dist/runtime/server-client.d.ts +21 -48
- package/dist/runtime/server-client.js +1 -1
- package/dist/runtime/server-client.js.map +3 -3
- package/dist/server/api.js +1 -1
- package/dist/server/api.js.map +2 -2
- package/dist/server/render.js.map +2 -2
- package/dist/server/server-bound.d.ts +1 -1
- package/dist/server/server-bound.js.map +2 -2
- package/dist/types.d.ts +1 -1
- package/dist/utils/banner.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Construye aplicaciones React full-stack con enrutamiento basado en archivos, ren
|
|
|
13
13
|
- **SSG** — genera HTML estático con `generateStaticParams`
|
|
14
14
|
- **Rutas API** — basadas en archivos, con `createHandler` para tipado de extremo a extremo
|
|
15
15
|
- **$fetch** — cliente HTTP con body y respuesta tipados, con autocompletado de rutas
|
|
16
|
-
- **$server** — proxy
|
|
16
|
+
- **$server** — proxy a backends remotos con auth pass-through y allowlist (multi-backend, tipo via generic en el call site)
|
|
17
17
|
- **Validación de body** — soporte de [Standard Schema](https://standardschema.dev) (Zod, Valibot, ArkType) en `createHandler` con error shape automático
|
|
18
18
|
- **Error shape unificado** — `error()` y `DevixError` producen el mismo `{ statusCode, code, message }` en loaders, guards y handlers
|
|
19
19
|
- **Carga de datos** — funciones `loader` con hidratación automática en el cliente
|
|
@@ -250,14 +250,16 @@ export default defineConfig({
|
|
|
250
250
|
```ts
|
|
251
251
|
// Loader/handler — $server bound al request del usuario
|
|
252
252
|
export async function loader({ $server, params }: LoaderContext) {
|
|
253
|
-
return await $server.api.get(`/v1/posts/${params.id}`)
|
|
253
|
+
return await $server.api.get<Post>(`/v1/posts/${params.id}`)
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
// Cliente — pasa por el proxy interno con el mismo prepare
|
|
257
257
|
import { $server } from '@devlusoft/devix'
|
|
258
|
-
const me = await $server.api.get('/v1/me')
|
|
258
|
+
const me = await $server.api.get<User>('/v1/me')
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
+
El tipo de respuesta se declara con un generic en el call site (`<User>`). El backend remoto vive fuera del repo — devix no puede inferir tipos automáticamente.
|
|
262
|
+
|
|
261
263
|
> ⚠️ `$server` reenvía credenciales del usuario al backend (el backend valida). **No lo uses para APIs de terceros con keys del server (Stripe, etc.)** — eso expone esa key. Para terceros, escribe un handler explícito con autorización propia. Ver [Server primitive](./docs/server-primitive.md).
|
|
262
264
|
|
|
263
265
|
### Generación estática (SSG)
|
package/dist/cli/dev-server.js
CHANGED
|
@@ -266,7 +266,7 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
|
266
266
|
`:`// auto-generado por devix - no editar
|
|
267
267
|
export type PageData = undefined
|
|
268
268
|
export type PageParams = Record<string, string>
|
|
269
|
-
`}function j(e,t){let r=w(t,e),n=re(r,"utf-8"),o=Be(n,r),s=[];o.exists&&!o.isAsync&&!o.isReExport&&s.push(`[devix] ${e}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let a=w(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),f=w(a,"$types.d.ts"),m=r.replace(/\.(tsx?|jsx?)$/,""),l=oe(a,m).replace(/\\/g,"/"),p=Ve(l,o.exists);return ne(f)&&re(f,"utf-8")===p?{warnings:s}:(je(a,{recursive:!0}),ke(f,p,"utf-8"),{warnings:s})}function ie(e,t){let r=w(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),n=w(r,"$types.d.ts");ne(n)&&Fe(n)}function U(e,t){let r=w(t,e,"pages"),n=[],o;try{o=se(r,t)}catch{return{warnings:n}}for(let s of o)try{let a=j(s,t);n.push(...a.warnings)}catch{}return{warnings:n}}var C=Ge(Je(import.meta.url)),F="virtual:devix/entry-client",N="virtual:devix/client-routes",$="virtual:devix/render",D="virtual:devix/api",k="virtual:devix/context",H="virtual:devix/server-entry",ae=new Set(["loader","guard","generateStaticParams","headers"]);function ce(e){let t=e.appDir??"app",r=`${t}/pages`,n=(e.css??[]).map(c=>c.startsWith("/")?c:`/${c.replace(/^\.\//,"")}`),o=g(C,"../server/render.js").replace(/\\/g,"/"),s=g(C,"../server/api.js").replace(/\\/g,"/"),a=g(C,"../runtime/client-router.js").replace(/\\/g,"/"),f=g(C,"../server/routes.js").replace(/\\/g,"/"),m=g(C,"../utils/env.js").replace(/\\/g,"/"),l=Ye(import.meta.url),p=l.resolve("@hono/node-server").replace(/\\/g,"/"),Ee=l.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),we=l.resolve("hono").replace(/\\/g,"/"),_e={name:"devix",enforce:"pre",resolveId(c){if(c===F)return`\0${F}`;if(c===N)return`\0${N}`;if(c===$)return`\0${$}`;if(c===D)return`\0${D}`;if(c===k)return`\0${k}`;if(c===H)return`\0${H}`},load(c){if(c===`\0${F}`)return q({cssUrls:n});if(c===`\0${N}`)return W({pagesDir:r,matcherPath:a});if(c===`\0${$}`)return J({pagesDir:r,renderPath:o});if(c===`\0${D}`)return G({apiPath:s,appDir:t});if(c===`\0${k}`)return X();if(c===`\0${H}`)return te({routesPath:f,envPath:m,honoServerPath:p,honoServerStaticPath:Ee,honoPath:we})},transform(c,u,T){if(T?.ssr)return;let E=g(process.cwd(),r);if(!u.startsWith(E))return;let S=ze(u,c,{sourceType:"module"}),R=[];for(let d of S.program.body){if(d.type!=="ExportNamedDeclaration"||!d.declaration)continue;let i=d.declaration;if(i.type==="FunctionDeclaration"&&i.id&&ae.has(i.id.name)&&R.push({start:d.start,end:d.end,name:i.id.name}),i.type==="VariableDeclaration"){let x=new Set;for(let b of i.declarations)b.id.type==="Identifier"&&ae.has(b.id.name)&&(x.has(d.start)||(x.add(d.start),R.push({start:d.start,end:d.end,name:b.id.name})))}}if(R.length===0)return;R.sort((d,i)=>i.start-d.start);let h=c;for(let{start:d,end:i,name:x}of R)h=h.slice(0,d)+`export const ${x} = undefined`+h.slice(i);return{code:h,map:null}},buildStart(){let c=process.cwd(),u=L(t,c);M(I(u,`${t}/api`),c);let{warnings:T}=U(t,c);for(let E of T)console.warn(E)},configureServer(c){let u=process.cwd(),T=U(t,u);for(let i of T.warnings)console.warn(i);let E=()=>{let i=L(t,u);M(I(i,`${t}/api`),u)},S=i=>i.startsWith(g(u,r))&&!i.endsWith("layout.tsx")&&!i.endsWith("error.tsx"),R=i=>Xe(u,i).replace(/\\/g,"/"),h=i=>{let x=c.moduleGraph.getModuleById(`\0${i}`);x&&c.moduleGraph.invalidateModule(x)};c.watcher.add(g(u,"devix.config.ts")),c.watcher.on("change",i=>{i===g(u,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))});let d=i=>{try{let{warnings:x}=j(R(i),u);for(let b of x)console.warn(b)}catch{}};c.watcher.on("add",i=>{i.startsWith(g(u,r))&&h($),S(i)&&d(i),i.includes(`${t}/api`)&&(h(D),E())}),c.watcher.on("unlink",i=>{i.startsWith(g(u,r))&&h($),S(i)&&ie(R(i),u),i.includes(`${t}/api`)&&(h(D),E())}),c.watcher.on("change",i=>{S(i)&&d(i),i.includes(`${t}/api`)&&!i.endsWith("middleware.ts")&&E()})}},Pe={plugins:[We(),_e],publicDir:g(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return qe(Pe,e.vite??{})}function A(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}function Ke(e,t){return Ze(t).test(e)}function B(e,t){if(!t||t.length===0)return!1;for(let r of t)if(Ke(e,r))return!0;return!1}function Ze(e){let t="",r=0;for(;r<e.length;){let n=e[r];if(n==="*"&&e[r+1]==="*")t+=".*",r+=2;else if(n==="*")t+="[^/]*",r+=1;else if(n===":"){for(r+=1;r<e.length&&/[a-zA-Z0-9_]/.test(e[r]);)r+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(n)?(t+="\\"+n,r+=1):(t+=n,r+=1)}return new RegExp(`^${t}$`)}var le="/_devix/server";function P(e,t,r){let n=A({statusCode:e,message:t,code:r});return new Response(JSON.stringify(n),{status:e,headers:{"Content-Type":"application/json"}})}function Qe(e){if(!e.startsWith(le+"/"))return null;let t=e.slice(le.length+1),r=t.indexOf("/");return r===-1?{namespace:t,path:"/"}:{namespace:t.slice(0,r),path:t.slice(r)}}async function ue(e,t){let r=new URL(e.url),n=Qe(r.pathname);if(!n)return P(404,"Not found","PROXY_NOT_FOUND");let o=t?.[n.namespace];if(!o)return P(404,`Backend "${n.namespace}" not configured`,"BACKEND_NOT_FOUND");if(!B(n.path,o.allowedPaths))return P(403,"Path not allowed","PATH_NOT_ALLOWED");if(B(n.path,o.deniedPaths))return P(403,"Path denied","PATH_DENIED");let s=new URL(n.path+r.search,o.url),a=new Headers;if(o.prepare){let l={request:e,headers:a,url:s};try{let p=await o.prepare(l);if(p instanceof Response)return p}catch(p){return console.error(`[devix] server.${n.namespace}.prepare error:`,p),P(500,"Proxy prepare failed","PREPARE_ERROR")}}if(!a.has("Accept")){let l=e.headers.get("Accept");l&&a.set("Accept",l)}let f=e.headers.get("Content-Type");f&&!a.has("Content-Type")&&a.set("Content-Type",f);let m=null;e.method!=="GET"&&e.method!=="HEAD"&&(m=await e.arrayBuffer(),m.byteLength===0&&(m=null));try{let l=await fetch(s,{method:e.method,headers:a,body:m,redirect:"manual"});return new Response(l.body,{status:l.status,statusText:l.statusText,headers:tt(l.headers)})}catch(l){return console.error(`[devix] server.${n.namespace} fetch error:`,l),P(502,"Bad Gateway","BACKEND_UNREACHABLE")}}var et=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailers","transfer-encoding","upgrade"]);function tt(e){let t=new Headers;return e.forEach((r,n)=>{et.has(n.toLowerCase())||t.set(n,r)}),t}function de(e,{apiModule:t,renderModule:r,loaderTimeout:n,server:o}){o&&e.all("/_devix/server/*",async s=>{try{return await ue(s.req.raw,o)}catch(a){return console.error("[devix] proxy fatal error:",a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.all("/api/*",async s=>{try{return await t.handleApiRequest(s.req.url,s.req.raw,o)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.get("/_data/*",async s=>{try{let{pathname:a,search:f}=new URL(s.req.url,"http://localhost"),m=a.replace(/^\/_data/,"")+f,l=await r.runLoader(m,s.req.raw,{loaderTimeout:n,server:o});if(l.error)return s.json({statusCode:500,message:"Internal Server Error"},500);if("loaderError"in l){let p=A(l.loaderError);return s.json(p,p.statusCode)}return s.json(l)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}})}import y from"picocolors";import{networkInterfaces as rt}from"node:os";function nt(e){let t=rt();for(let r of Object.values(t))for(let n of r??[])if(n.family==="IPv4"&&!n.internal)return`http://${n.address}:${e}/`;return null}function pe(e){let t="0.5.
|
|
269
|
+
`}function j(e,t){let r=w(t,e),n=re(r,"utf-8"),o=Be(n,r),s=[];o.exists&&!o.isAsync&&!o.isReExport&&s.push(`[devix] ${e}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let a=w(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),f=w(a,"$types.d.ts"),m=r.replace(/\.(tsx?|jsx?)$/,""),l=oe(a,m).replace(/\\/g,"/"),p=Ve(l,o.exists);return ne(f)&&re(f,"utf-8")===p?{warnings:s}:(je(a,{recursive:!0}),ke(f,p,"utf-8"),{warnings:s})}function ie(e,t){let r=w(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),n=w(r,"$types.d.ts");ne(n)&&Fe(n)}function U(e,t){let r=w(t,e,"pages"),n=[],o;try{o=se(r,t)}catch{return{warnings:n}}for(let s of o)try{let a=j(s,t);n.push(...a.warnings)}catch{}return{warnings:n}}var C=Ge(Je(import.meta.url)),F="virtual:devix/entry-client",N="virtual:devix/client-routes",$="virtual:devix/render",D="virtual:devix/api",k="virtual:devix/context",H="virtual:devix/server-entry",ae=new Set(["loader","guard","generateStaticParams","headers"]);function ce(e){let t=e.appDir??"app",r=`${t}/pages`,n=(e.css??[]).map(c=>c.startsWith("/")?c:`/${c.replace(/^\.\//,"")}`),o=g(C,"../server/render.js").replace(/\\/g,"/"),s=g(C,"../server/api.js").replace(/\\/g,"/"),a=g(C,"../runtime/client-router.js").replace(/\\/g,"/"),f=g(C,"../server/routes.js").replace(/\\/g,"/"),m=g(C,"../utils/env.js").replace(/\\/g,"/"),l=Ye(import.meta.url),p=l.resolve("@hono/node-server").replace(/\\/g,"/"),Ee=l.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),we=l.resolve("hono").replace(/\\/g,"/"),_e={name:"devix",enforce:"pre",resolveId(c){if(c===F)return`\0${F}`;if(c===N)return`\0${N}`;if(c===$)return`\0${$}`;if(c===D)return`\0${D}`;if(c===k)return`\0${k}`;if(c===H)return`\0${H}`},load(c){if(c===`\0${F}`)return q({cssUrls:n});if(c===`\0${N}`)return W({pagesDir:r,matcherPath:a});if(c===`\0${$}`)return J({pagesDir:r,renderPath:o});if(c===`\0${D}`)return G({apiPath:s,appDir:t});if(c===`\0${k}`)return X();if(c===`\0${H}`)return te({routesPath:f,envPath:m,honoServerPath:p,honoServerStaticPath:Ee,honoPath:we})},transform(c,u,T){if(T?.ssr)return;let E=g(process.cwd(),r);if(!u.startsWith(E))return;let S=ze(u,c,{sourceType:"module"}),R=[];for(let d of S.program.body){if(d.type!=="ExportNamedDeclaration"||!d.declaration)continue;let i=d.declaration;if(i.type==="FunctionDeclaration"&&i.id&&ae.has(i.id.name)&&R.push({start:d.start,end:d.end,name:i.id.name}),i.type==="VariableDeclaration"){let x=new Set;for(let b of i.declarations)b.id.type==="Identifier"&&ae.has(b.id.name)&&(x.has(d.start)||(x.add(d.start),R.push({start:d.start,end:d.end,name:b.id.name})))}}if(R.length===0)return;R.sort((d,i)=>i.start-d.start);let h=c;for(let{start:d,end:i,name:x}of R)h=h.slice(0,d)+`export const ${x} = undefined`+h.slice(i);return{code:h,map:null}},buildStart(){let c=process.cwd(),u=L(t,c);M(I(u,`${t}/api`),c);let{warnings:T}=U(t,c);for(let E of T)console.warn(E)},configureServer(c){let u=process.cwd(),T=U(t,u);for(let i of T.warnings)console.warn(i);let E=()=>{let i=L(t,u);M(I(i,`${t}/api`),u)},S=i=>i.startsWith(g(u,r))&&!i.endsWith("layout.tsx")&&!i.endsWith("error.tsx"),R=i=>Xe(u,i).replace(/\\/g,"/"),h=i=>{let x=c.moduleGraph.getModuleById(`\0${i}`);x&&c.moduleGraph.invalidateModule(x)};c.watcher.add(g(u,"devix.config.ts")),c.watcher.on("change",i=>{i===g(u,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))});let d=i=>{try{let{warnings:x}=j(R(i),u);for(let b of x)console.warn(b)}catch{}};c.watcher.on("add",i=>{i.startsWith(g(u,r))&&h($),S(i)&&d(i),i.includes(`${t}/api`)&&(h(D),E())}),c.watcher.on("unlink",i=>{i.startsWith(g(u,r))&&h($),S(i)&&ie(R(i),u),i.includes(`${t}/api`)&&(h(D),E())}),c.watcher.on("change",i=>{S(i)&&d(i),i.includes(`${t}/api`)&&!i.endsWith("middleware.ts")&&E()})}},Pe={plugins:[We(),_e],publicDir:g(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return qe(Pe,e.vite??{})}function A(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}function Ke(e,t){return Ze(t).test(e)}function B(e,t){if(!t||t.length===0)return!1;for(let r of t)if(Ke(e,r))return!0;return!1}function Ze(e){let t="",r=0;for(;r<e.length;){let n=e[r];if(n==="*"&&e[r+1]==="*")t+=".*",r+=2;else if(n==="*")t+="[^/]*",r+=1;else if(n===":"){for(r+=1;r<e.length&&/[a-zA-Z0-9_]/.test(e[r]);)r+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(n)?(t+="\\"+n,r+=1):(t+=n,r+=1)}return new RegExp(`^${t}$`)}var le="/_devix/server";function P(e,t,r){let n=A({statusCode:e,message:t,code:r});return new Response(JSON.stringify(n),{status:e,headers:{"Content-Type":"application/json"}})}function Qe(e){if(!e.startsWith(le+"/"))return null;let t=e.slice(le.length+1),r=t.indexOf("/");return r===-1?{namespace:t,path:"/"}:{namespace:t.slice(0,r),path:t.slice(r)}}async function ue(e,t){let r=new URL(e.url),n=Qe(r.pathname);if(!n)return P(404,"Not found","PROXY_NOT_FOUND");let o=t?.[n.namespace];if(!o)return P(404,`Backend "${n.namespace}" not configured`,"BACKEND_NOT_FOUND");if(!B(n.path,o.allowedPaths))return P(403,"Path not allowed","PATH_NOT_ALLOWED");if(B(n.path,o.deniedPaths))return P(403,"Path denied","PATH_DENIED");let s=new URL(n.path+r.search,o.url),a=new Headers;if(o.prepare){let l={request:e,headers:a,url:s};try{let p=await o.prepare(l);if(p instanceof Response)return p}catch(p){return console.error(`[devix] server.${n.namespace}.prepare error:`,p),P(500,"Proxy prepare failed","PREPARE_ERROR")}}if(!a.has("Accept")){let l=e.headers.get("Accept");l&&a.set("Accept",l)}let f=e.headers.get("Content-Type");f&&!a.has("Content-Type")&&a.set("Content-Type",f);let m=null;e.method!=="GET"&&e.method!=="HEAD"&&(m=await e.arrayBuffer(),m.byteLength===0&&(m=null));try{let l=await fetch(s,{method:e.method,headers:a,body:m,redirect:"manual"});return new Response(l.body,{status:l.status,statusText:l.statusText,headers:tt(l.headers)})}catch(l){return console.error(`[devix] server.${n.namespace} fetch error:`,l),P(502,"Bad Gateway","BACKEND_UNREACHABLE")}}var et=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailers","transfer-encoding","upgrade"]);function tt(e){let t=new Headers;return e.forEach((r,n)=>{et.has(n.toLowerCase())||t.set(n,r)}),t}function de(e,{apiModule:t,renderModule:r,loaderTimeout:n,server:o}){o&&e.all("/_devix/server/*",async s=>{try{return await ue(s.req.raw,o)}catch(a){return console.error("[devix] proxy fatal error:",a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.all("/api/*",async s=>{try{return await t.handleApiRequest(s.req.url,s.req.raw,o)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.get("/_data/*",async s=>{try{let{pathname:a,search:f}=new URL(s.req.url,"http://localhost"),m=a.replace(/^\/_data/,"")+f,l=await r.runLoader(m,s.req.raw,{loaderTimeout:n,server:o});if(l.error)return s.json({statusCode:500,message:"Internal Server Error"},500);if("loaderError"in l){let p=A(l.loaderError);return s.json(p,p.statusCode)}return s.json(l)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}})}import y from"picocolors";import{networkInterfaces as rt}from"node:os";function nt(e){let t=rt();for(let r of Object.values(t))for(let n of r??[])if(n.family==="IPv4"&&!n.internal)return`http://${n.address}:${e}/`;return null}function pe(e){let t="0.5.2",r=nt(e);console.log(),console.log(` ${y.bold(y.yellow("devix"))} ${y.dim(`v${t}`)}`),console.log(),console.log(` ${y.green("\u279C")} ${y.bold("Local:")} ${y.cyan(`http://localhost:${e}/`)}`),console.log(r?` ${y.green("\u279C")} ${y.bold("Network:")} ${y.cyan(r)}`:` ${y.green("\u279C")} ${y.bold("Network:")} ${y.dim("use --host to expose")}`),console.log()}async function fe(e){let t=new Set;for(let[,r]of e.moduleGraph.idToModuleMap)r.id&&(r.id.endsWith(".css")||r.id.includes(".css?"))&&r.url.startsWith("/")&&t.add(r.url);return[...t]}function me(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}}import{loadEnv as ot}from"vite";function ge(e){let t=ot(e,process.cwd(),"");for(let[r,n]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=n)}import{build as st}from"esbuild";import{join as ye}from"node:path";import{unlinkSync as it,writeFileSync as at}from"node:fs";import{pathToFileURL as ct}from"node:url";async function he(e){let t=await st({entryPoints:[ye(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=ye(e,`.devix-config-${Date.now()}.mjs`);at(r,t.outputFiles[0].text);try{return(await import(ct(r).href)).default}finally{it(r)}}ge("development");var xe="virtual:devix/render",ft="virtual:devix/api",v=await he(process.cwd()),Re=Number(process.env.PORT)||v.port||3e3,mt=typeof v.host=="string"?v.host:v.host?"0.0.0.0":"localhost",_=await ut({...ce(v),configFile:!1,appType:"custom",server:{middlewareMode:!0}}),ve={render:async(...e)=>(await _.ssrLoadModule(xe)).render(...e),runLoader:async(...e)=>(await _.ssrLoadModule(xe)).runLoader(...e)},gt={handleApiRequest:async(...e)=>(await _.ssrLoadModule(ft)).handleApiRequest(...e)},V=new pt;de(V,{renderModule:ve,apiModule:gt,server:v.server});V.get("*",async e=>{try{let{html:t,statusCode:r,headers:n}=await ve.render(e.req.url,e.req.raw,{loaderTimeout:me(v.loaderTimeout??1e4),server:v.server}),s=(await fe(_)).map(l=>`<link rel="stylesheet" href="${l}">`).join(`
|
|
270
270
|
`),a=s?t.replace("</head>",`${s}
|
|
271
271
|
</head>`):t,f=await _.transformIndexHtml(e.req.url,`<!DOCTYPE html>${a}`),m=e.html(f,r);for(let[l,p]of Object.entries(n))m.headers.set(l,p);return m}catch(t){return _.ssrFixStacktrace(t),console.error(t),e.text("Internal Server Error",500)}});var yt=dt(V.fetch);lt(async(e,t)=>{await new Promise(r=>_.middlewares(e,t,r)),t.writableEnded||await yt(e,t)}).listen(Re,mt,()=>{pe(Re)});
|
|
272
272
|
//# sourceMappingURL=dev-server.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -267,7 +267,7 @@ export type PageParams = NonNullable<Parameters<typeof loader>[0]>["params"]
|
|
|
267
267
|
`:`// auto-generado por devix - no editar
|
|
268
268
|
export type PageData = undefined
|
|
269
269
|
export type PageParams = Record<string, string>
|
|
270
|
-
`}function J(e,t){let r=E(t,e),o=Oe(r,"utf-8"),n=Ft(o,r),s=[];n.exists&&!n.isAsync&&!n.isReExport&&s.push(`[devix] ${e}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let a=E(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),m=E(a,"$types.d.ts"),g=r.replace(/\.(tsx?|jsx?)$/,""),l=Ie(a,g).replace(/\\/g,"/"),f=Mt(l,n.exists);return je(m)&&Oe(m,"utf-8")===f?{warnings:s}:(Dt(a,{recursive:!0}),jt(m,f,"utf-8"),{warnings:s})}function Me(e,t){let r=E(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),o=E(r,"$types.d.ts");je(o)&&At(o)}function q(e,t){let r=E(t,e,"pages"),o=[],n;try{n=Fe(r,t)}catch{return{warnings:o}}for(let s of n)try{let a=J(s,t);o.push(...a.warnings)}catch{}return{warnings:o}}var Le=d(()=>{"use strict"});import{mergeConfig as Lt}from"vite";import Ut from"@vitejs/plugin-react";import{fileURLToPath as kt}from"node:url";import{dirname as Nt,relative as Ht,resolve as h}from"node:path";import{createRequire as Bt}from"node:module";import{parseSync as Jt}from"oxc-parser";function ke(e){let t=e.appDir??"app",r=`${t}/pages`,o=(e.css??[]).map(c=>c.startsWith("/")?c:`/${c.replace(/^\.\//,"")}`),n=h(D,"../server/render.js").replace(/\\/g,"/"),s=h(D,"../server/api.js").replace(/\\/g,"/"),a=h(D,"../runtime/client-router.js").replace(/\\/g,"/"),m=h(D,"../server/routes.js").replace(/\\/g,"/"),g=h(D,"../utils/env.js").replace(/\\/g,"/"),l=Bt(import.meta.url),f=l.resolve("@hono/node-server").replace(/\\/g,"/"),L=l.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),lt=l.resolve("hono").replace(/\\/g,"/"),dt={name:"devix",enforce:"pre",resolveId(c){if(c===V)return`\0${V}`;if(c===W)return`\0${W}`;if(c===$)return`\0${$}`;if(c===A)return`\0${A}`;if(c===G)return`\0${G}`;if(c===X)return`\0${X}`},load(c){if(c===`\0${V}`)return le({cssUrls:o});if(c===`\0${W}`)return ue({pagesDir:r,matcherPath:a});if(c===`\0${$}`)return fe({pagesDir:r,renderPath:n});if(c===`\0${A}`)return ge({apiPath:s,appDir:t});if(c===`\0${G}`)return xe();if(c===`\0${X}`)return $e({routesPath:m,envPath:g,honoServerPath:f,honoServerStaticPath:L,honoPath:lt})},transform(c,u,P){if(P?.ssr)return;let w=h(process.cwd(),r);if(!u.startsWith(w))return;let b=Jt(u,c,{sourceType:"module"}),R=[];for(let p of b.program.body){if(p.type!=="ExportNamedDeclaration"||!p.declaration)continue;let i=p.declaration;if(i.type==="FunctionDeclaration"&&i.id&&Ue.has(i.id.name)&&R.push({start:p.start,end:p.end,name:i.id.name}),i.type==="VariableDeclaration"){let y=new Set;for(let C of i.declarations)C.id.type==="Identifier"&&Ue.has(C.id.name)&&(y.has(p.start)||(y.add(p.start),R.push({start:p.start,end:p.end,name:C.id.name})))}}if(R.length===0)return;R.sort((p,i)=>i.start-p.start);let x=c;for(let{start:p,end:i,name:y}of R)x=x.slice(0,p)+`export const ${y} = undefined`+x.slice(i);return{code:x,map:null}},buildStart(){let c=process.cwd(),u=H(t,c);B(U(u,`${t}/api`),c);let{warnings:P}=q(t,c);for(let w of P)console.warn(w)},configureServer(c){let u=process.cwd(),P=q(t,u);for(let i of P.warnings)console.warn(i);let w=()=>{let i=H(t,u);B(U(i,`${t}/api`),u)},b=i=>i.startsWith(h(u,r))&&!i.endsWith("layout.tsx")&&!i.endsWith("error.tsx"),R=i=>Ht(u,i).replace(/\\/g,"/"),x=i=>{let y=c.moduleGraph.getModuleById(`\0${i}`);y&&c.moduleGraph.invalidateModule(y)};c.watcher.add(h(u,"devix.config.ts")),c.watcher.on("change",i=>{i===h(u,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))});let p=i=>{try{let{warnings:y}=J(R(i),u);for(let C of y)console.warn(C)}catch{}};c.watcher.on("add",i=>{i.startsWith(h(u,r))&&x($),b(i)&&p(i),i.includes(`${t}/api`)&&(x(A),w())}),c.watcher.on("unlink",i=>{i.startsWith(h(u,r))&&x($),b(i)&&Me(R(i),u),i.includes(`${t}/api`)&&(x(A),w())}),c.watcher.on("change",i=>{b(i)&&p(i),i.includes(`${t}/api`)&&!i.endsWith("middleware.ts")&&w()})}},ut={plugins:[Ut(),dt],publicDir:h(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Lt(ut,e.vite??{})}var D,V,W,$,A,G,X,Ue,Ne=d(()=>{"use strict";de();pe();me();he();ye();be();k();De();Ae();Le();D=Nt(kt(import.meta.url)),V="virtual:devix/entry-client",W="virtual:devix/client-routes",$="virtual:devix/render",A="virtual:devix/api",G="virtual:devix/context",X="virtual:devix/server-entry",Ue=new Set(["loader","guard","generateStaticParams","headers"])});function He(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var Be=d(()=>{"use strict"});import{build as qt}from"esbuild";import{join as Je}from"node:path";import{unlinkSync as Vt,writeFileSync as Wt}from"node:fs";import{pathToFileURL as Gt}from"node:url";async function _(e){let t=await qt({entryPoints:[Je(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=Je(e,`.devix-config-${Date.now()}.mjs`);Wt(r,t.outputFiles[0].text);try{return(await import(Gt(r).href)).default}finally{Vt(r)}}var F=d(()=>{"use strict"});var qe={};import{writeFileSync as Xt}from"node:fs";import{resolve as Yt}from"node:path";import{build as Y}from"vite";var O,z,zt,K=d(async()=>{"use strict";Ne();Be();F();O=await _(process.cwd()),z=ke(O);await Y({...z,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await Y({...z,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await Y({...z,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});zt={port:O.port??3e3,host:O.host??!1,loaderTimeout:He(O.loaderTimeout??1e4),output:O.output??"server"};Xt(Yt(process.cwd(),"dist/devix.config.json"),JSON.stringify(zt,null,2),"utf-8")});var tr={};import{readFileSync as Kt,mkdirSync as Ve,writeFileSync as We,rmSync as Zt}from"node:fs";import{resolve as ee,join as S}from"node:path";import{pathToFileURL as Qt}from"node:url";var Xe,er,Z,Ge,Q,Ye=d(async()=>{"use strict";F();Xe=await _(process.cwd());Xe.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await K().then(()=>qe);er=Date.now(),Z=await import(Qt(ee(process.cwd(),"dist/server/render.js")).href+`?t=${er}`),Ge=JSON.parse(Kt(ee(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),Q=await Z.getStaticRoutes();console.log(`[devix] Generating ${Q.length} static page${Q.length===1?"":"s"}...`);for(let e of Q){let t=`http://localhost${e}`,{html:r,statusCode:o}=await Z.render(t,new Request(t),{manifest:Ge});if(o!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${o}`);continue}let n=e==="/"?S(process.cwd(),"dist/client/index.html"):S(process.cwd(),"dist/client",e,"index.html");Ve(S(n,".."),{recursive:!0}),We(n,`<!DOCTYPE html>${r}`,"utf-8");let s=await Z.runLoader(t,new Request(t),{manifest:Ge}),a=e==="/"?S(process.cwd(),"dist/client/_data/index.json"):S(process.cwd(),"dist/client/_data",`${e}.json`);Ve(S(a,".."),{recursive:!0}),We(a,JSON.stringify(s),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Xe.output==="static"&&(Zt(ee(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function M(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}var te=d(()=>{"use strict"});function rr(e,t){return or(t).test(e)}function re(e,t){if(!t||t.length===0)return!1;for(let r of t)if(rr(e,r))return!0;return!1}function or(e){let t="",r=0;for(;r<e.length;){let o=e[r];if(o==="*"&&e[r+1]==="*")t+=".*",r+=2;else if(o==="*")t+="[^/]*",r+=1;else if(o===":"){for(r+=1;r<e.length&&/[a-zA-Z0-9_]/.test(e[r]);)r+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(o)?(t+="\\"+o,r+=1):(t+=o,r+=1)}return new RegExp(`^${t}$`)}var ze=d(()=>{"use strict"});function T(e,t,r){let o=M({statusCode:e,message:t,code:r});return new Response(JSON.stringify(o),{status:e,headers:{"Content-Type":"application/json"}})}function nr(e){if(!e.startsWith(Ke+"/"))return null;let t=e.slice(Ke.length+1),r=t.indexOf("/");return r===-1?{namespace:t,path:"/"}:{namespace:t.slice(0,r),path:t.slice(r)}}async function Ze(e,t){let r=new URL(e.url),o=nr(r.pathname);if(!o)return T(404,"Not found","PROXY_NOT_FOUND");let n=t?.[o.namespace];if(!n)return T(404,`Backend "${o.namespace}" not configured`,"BACKEND_NOT_FOUND");if(!re(o.path,n.allowedPaths))return T(403,"Path not allowed","PATH_NOT_ALLOWED");if(re(o.path,n.deniedPaths))return T(403,"Path denied","PATH_DENIED");let s=new URL(o.path+r.search,n.url),a=new Headers;if(n.prepare){let l={request:e,headers:a,url:s};try{let f=await n.prepare(l);if(f instanceof Response)return f}catch(f){return console.error(`[devix] server.${o.namespace}.prepare error:`,f),T(500,"Proxy prepare failed","PREPARE_ERROR")}}if(!a.has("Accept")){let l=e.headers.get("Accept");l&&a.set("Accept",l)}let m=e.headers.get("Content-Type");m&&!a.has("Content-Type")&&a.set("Content-Type",m);let g=null;e.method!=="GET"&&e.method!=="HEAD"&&(g=await e.arrayBuffer(),g.byteLength===0&&(g=null));try{let l=await fetch(s,{method:e.method,headers:a,body:g,redirect:"manual"});return new Response(l.body,{status:l.status,statusText:l.statusText,headers:ir(l.headers)})}catch(l){return console.error(`[devix] server.${o.namespace} fetch error:`,l),T(502,"Bad Gateway","BACKEND_UNREACHABLE")}}function ir(e){let t=new Headers;return e.forEach((r,o)=>{sr.has(o.toLowerCase())||t.set(o,r)}),t}var Ke,sr,Qe=d(()=>{"use strict";ze();te();Ke="/_devix/server";sr=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailers","transfer-encoding","upgrade"])});function et(e,{apiModule:t,renderModule:r,loaderTimeout:o,server:n}){n&&e.all("/_devix/server/*",async s=>{try{return await Ze(s.req.raw,n)}catch(a){return console.error("[devix] proxy fatal error:",a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.all("/api/*",async s=>{try{return await t.handleApiRequest(s.req.url,s.req.raw,n)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.get("/_data/*",async s=>{try{let{pathname:a,search:m}=new URL(s.req.url,"http://localhost"),g=a.replace(/^\/_data/,"")+m,l=await r.runLoader(g,s.req.raw,{loaderTimeout:o,server:n});if(l.error)return s.json({statusCode:500,message:"Internal Server Error"},500);if("loaderError"in l){let f=M(l.loaderError);return s.json(f,f.statusCode)}return s.json(l)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}})}function tt(e,{renderModule:t,manifest:r,loaderTimeout:o,server:n}){e.get("*",async s=>{try{let{html:a,statusCode:m,headers:g}=await t.render(s.req.url,s.req.raw,{manifest:r,loaderTimeout:o,server:n}),l=s.html(`<!DOCTYPE html>${a}`,m);for(let[f,L]of Object.entries(g))l.headers.set(f,L);return l}catch(a){return console.error(a),s.text("Internal Server Error",500)}})}var rt=d(()=>{"use strict";te();Qe()});import{loadEnv as ar}from"vite";function ot(e){let t=ar(e,process.cwd(),"");for(let[r,o]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=o)}var nt=d(()=>{"use strict"});var fr={};import{readFileSync as oe}from"node:fs";import{serve as cr}from"@hono/node-server";import{serveStatic as lr}from"@hono/node-server/serve-static";import{Hono as dr}from"hono";import{resolve as st,join as j}from"node:path";import{pathToFileURL as it}from"node:url";var ne,se,ie,v,ur,pr,I,ae,at=d(async()=>{"use strict";rt();nt();F();ot("production");try{v=JSON.parse(oe(j(process.cwd(),"dist/devix.config.json"),"utf-8")),v.output!=="static"&&(ne=await import(it(st(process.cwd(),"dist/server/render.js")).href),se=await import(it(st(process.cwd(),"dist/server/api.js")).href)),ie=JSON.parse(oe(j(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}ur=Number(process.env.PORT)||v.port||3e3,pr=typeof v.host=="string"?v.host:v.host?"0.0.0.0":process.env.HOST||"0.0.0.0",I=new dr,ae=j(process.cwd(),"dist/client");v.output==="static"&&I.get("/_data/*",e=>{let t=e.req.path.replace(/^\/_data/,"")||"/",r=t==="/"?j(ae,"_data/index.json"):j(ae,"_data",`${t}.json`);try{let o=oe(r,"utf-8");return e.json(JSON.parse(o))}catch{return e.json({error:"not found"},404)}});I.use("/*",lr({root:ae,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));if(v.output==="static")console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client");else{let e=await _(process.cwd()).catch(()=>null);et(I,{renderModule:ne,apiModule:se,manifest:ie,server:e?.server}),tt(I,{renderModule:ne,apiModule:se,manifest:ie,loaderTimeout:v.loaderTimeout})}cr({fetch:I.fetch,port:ur,hostname:pr},e=>console.log(`http://${e.address}:${e.port}`))});var ct=process.argv[2];switch(ct){case"dev":await Promise.resolve().then(()=>(ce(),xt));break;case"build":await K().then(()=>qe);break;case"generate":await Ye().then(()=>tr);break;case"start":await at().then(()=>fr);break;case"--version":case"-v":{console.log("0.5.1");break}case"--help":case"-h":console.log(`
|
|
270
|
+
`}function J(e,t){let r=E(t,e),o=Oe(r,"utf-8"),n=Ft(o,r),s=[];n.exists&&!n.isAsync&&!n.isReExport&&s.push(`[devix] ${e}: 'loader' must be async. Use 'export async function loader' or 'export const loader = async (...) => ...'.`);let a=E(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),m=E(a,"$types.d.ts"),g=r.replace(/\.(tsx?|jsx?)$/,""),l=Ie(a,g).replace(/\\/g,"/"),f=Mt(l,n.exists);return je(m)&&Oe(m,"utf-8")===f?{warnings:s}:(Dt(a,{recursive:!0}),jt(m,f,"utf-8"),{warnings:s})}function Me(e,t){let r=E(t,".devix","pages",e.replace(/\.(tsx?|jsx?)$/,"")),o=E(r,"$types.d.ts");je(o)&&At(o)}function q(e,t){let r=E(t,e,"pages"),o=[],n;try{n=Fe(r,t)}catch{return{warnings:o}}for(let s of n)try{let a=J(s,t);o.push(...a.warnings)}catch{}return{warnings:o}}var Le=d(()=>{"use strict"});import{mergeConfig as Lt}from"vite";import Ut from"@vitejs/plugin-react";import{fileURLToPath as kt}from"node:url";import{dirname as Nt,relative as Ht,resolve as h}from"node:path";import{createRequire as Bt}from"node:module";import{parseSync as Jt}from"oxc-parser";function ke(e){let t=e.appDir??"app",r=`${t}/pages`,o=(e.css??[]).map(c=>c.startsWith("/")?c:`/${c.replace(/^\.\//,"")}`),n=h(D,"../server/render.js").replace(/\\/g,"/"),s=h(D,"../server/api.js").replace(/\\/g,"/"),a=h(D,"../runtime/client-router.js").replace(/\\/g,"/"),m=h(D,"../server/routes.js").replace(/\\/g,"/"),g=h(D,"../utils/env.js").replace(/\\/g,"/"),l=Bt(import.meta.url),f=l.resolve("@hono/node-server").replace(/\\/g,"/"),L=l.resolve("@hono/node-server/serve-static").replace(/\\/g,"/"),lt=l.resolve("hono").replace(/\\/g,"/"),dt={name:"devix",enforce:"pre",resolveId(c){if(c===V)return`\0${V}`;if(c===W)return`\0${W}`;if(c===$)return`\0${$}`;if(c===A)return`\0${A}`;if(c===G)return`\0${G}`;if(c===X)return`\0${X}`},load(c){if(c===`\0${V}`)return le({cssUrls:o});if(c===`\0${W}`)return ue({pagesDir:r,matcherPath:a});if(c===`\0${$}`)return fe({pagesDir:r,renderPath:n});if(c===`\0${A}`)return ge({apiPath:s,appDir:t});if(c===`\0${G}`)return xe();if(c===`\0${X}`)return $e({routesPath:m,envPath:g,honoServerPath:f,honoServerStaticPath:L,honoPath:lt})},transform(c,u,P){if(P?.ssr)return;let w=h(process.cwd(),r);if(!u.startsWith(w))return;let b=Jt(u,c,{sourceType:"module"}),R=[];for(let p of b.program.body){if(p.type!=="ExportNamedDeclaration"||!p.declaration)continue;let i=p.declaration;if(i.type==="FunctionDeclaration"&&i.id&&Ue.has(i.id.name)&&R.push({start:p.start,end:p.end,name:i.id.name}),i.type==="VariableDeclaration"){let y=new Set;for(let C of i.declarations)C.id.type==="Identifier"&&Ue.has(C.id.name)&&(y.has(p.start)||(y.add(p.start),R.push({start:p.start,end:p.end,name:C.id.name})))}}if(R.length===0)return;R.sort((p,i)=>i.start-p.start);let x=c;for(let{start:p,end:i,name:y}of R)x=x.slice(0,p)+`export const ${y} = undefined`+x.slice(i);return{code:x,map:null}},buildStart(){let c=process.cwd(),u=H(t,c);B(U(u,`${t}/api`),c);let{warnings:P}=q(t,c);for(let w of P)console.warn(w)},configureServer(c){let u=process.cwd(),P=q(t,u);for(let i of P.warnings)console.warn(i);let w=()=>{let i=H(t,u);B(U(i,`${t}/api`),u)},b=i=>i.startsWith(h(u,r))&&!i.endsWith("layout.tsx")&&!i.endsWith("error.tsx"),R=i=>Ht(u,i).replace(/\\/g,"/"),x=i=>{let y=c.moduleGraph.getModuleById(`\0${i}`);y&&c.moduleGraph.invalidateModule(y)};c.watcher.add(h(u,"devix.config.ts")),c.watcher.on("change",i=>{i===h(u,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))});let p=i=>{try{let{warnings:y}=J(R(i),u);for(let C of y)console.warn(C)}catch{}};c.watcher.on("add",i=>{i.startsWith(h(u,r))&&x($),b(i)&&p(i),i.includes(`${t}/api`)&&(x(A),w())}),c.watcher.on("unlink",i=>{i.startsWith(h(u,r))&&x($),b(i)&&Me(R(i),u),i.includes(`${t}/api`)&&(x(A),w())}),c.watcher.on("change",i=>{b(i)&&p(i),i.includes(`${t}/api`)&&!i.endsWith("middleware.ts")&&w()})}},ut={plugins:[Ut(),dt],publicDir:h(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Lt(ut,e.vite??{})}var D,V,W,$,A,G,X,Ue,Ne=d(()=>{"use strict";de();pe();me();he();ye();be();k();De();Ae();Le();D=Nt(kt(import.meta.url)),V="virtual:devix/entry-client",W="virtual:devix/client-routes",$="virtual:devix/render",A="virtual:devix/api",G="virtual:devix/context",X="virtual:devix/server-entry",Ue=new Set(["loader","guard","generateStaticParams","headers"])});function He(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var Be=d(()=>{"use strict"});import{build as qt}from"esbuild";import{join as Je}from"node:path";import{unlinkSync as Vt,writeFileSync as Wt}from"node:fs";import{pathToFileURL as Gt}from"node:url";async function _(e){let t=await qt({entryPoints:[Je(e,"devix.config.ts")],bundle:!0,write:!1,format:"esm",platform:"node",packages:"external"}),r=Je(e,`.devix-config-${Date.now()}.mjs`);Wt(r,t.outputFiles[0].text);try{return(await import(Gt(r).href)).default}finally{Vt(r)}}var F=d(()=>{"use strict"});var qe={};import{writeFileSync as Xt}from"node:fs";import{resolve as Yt}from"node:path";import{build as Y}from"vite";var O,z,zt,K=d(async()=>{"use strict";Ne();Be();F();O=await _(process.cwd()),z=ke(O);await Y({...z,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await Y({...z,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});await Y({...z,configFile:!1,build:{ssr:!0,outDir:"dist/server",emptyOutDir:!1,copyPublicDir:!1,rolldownOptions:{input:{index:"virtual:devix/server-entry"}}}});zt={port:O.port??3e3,host:O.host??!1,loaderTimeout:He(O.loaderTimeout??1e4),output:O.output??"server"};Xt(Yt(process.cwd(),"dist/devix.config.json"),JSON.stringify(zt,null,2),"utf-8")});var tr={};import{readFileSync as Kt,mkdirSync as Ve,writeFileSync as We,rmSync as Zt}from"node:fs";import{resolve as ee,join as S}from"node:path";import{pathToFileURL as Qt}from"node:url";var Xe,er,Z,Ge,Q,Ye=d(async()=>{"use strict";F();Xe=await _(process.cwd());Xe.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await K().then(()=>qe);er=Date.now(),Z=await import(Qt(ee(process.cwd(),"dist/server/render.js")).href+`?t=${er}`),Ge=JSON.parse(Kt(ee(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),Q=await Z.getStaticRoutes();console.log(`[devix] Generating ${Q.length} static page${Q.length===1?"":"s"}...`);for(let e of Q){let t=`http://localhost${e}`,{html:r,statusCode:o}=await Z.render(t,new Request(t),{manifest:Ge});if(o!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${o}`);continue}let n=e==="/"?S(process.cwd(),"dist/client/index.html"):S(process.cwd(),"dist/client",e,"index.html");Ve(S(n,".."),{recursive:!0}),We(n,`<!DOCTYPE html>${r}`,"utf-8");let s=await Z.runLoader(t,new Request(t),{manifest:Ge}),a=e==="/"?S(process.cwd(),"dist/client/_data/index.json"):S(process.cwd(),"dist/client/_data",`${e}.json`);Ve(S(a,".."),{recursive:!0}),We(a,JSON.stringify(s),"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.");Xe.output==="static"&&(Zt(ee(process.cwd(),"dist/server"),{recursive:!0,force:!0}),console.log("[devix] Removed dist/server (not needed in static mode)"))});function M(e){let t={statusCode:e.statusCode,message:e.message};return e.code!==void 0&&(t.code=e.code),e.data!==void 0&&(t.data=e.data),t}var te=d(()=>{"use strict"});function rr(e,t){return or(t).test(e)}function re(e,t){if(!t||t.length===0)return!1;for(let r of t)if(rr(e,r))return!0;return!1}function or(e){let t="",r=0;for(;r<e.length;){let o=e[r];if(o==="*"&&e[r+1]==="*")t+=".*",r+=2;else if(o==="*")t+="[^/]*",r+=1;else if(o===":"){for(r+=1;r<e.length&&/[a-zA-Z0-9_]/.test(e[r]);)r+=1;t+="[^/]+"}else".+?^$()|[]{}\\".includes(o)?(t+="\\"+o,r+=1):(t+=o,r+=1)}return new RegExp(`^${t}$`)}var ze=d(()=>{"use strict"});function T(e,t,r){let o=M({statusCode:e,message:t,code:r});return new Response(JSON.stringify(o),{status:e,headers:{"Content-Type":"application/json"}})}function nr(e){if(!e.startsWith(Ke+"/"))return null;let t=e.slice(Ke.length+1),r=t.indexOf("/");return r===-1?{namespace:t,path:"/"}:{namespace:t.slice(0,r),path:t.slice(r)}}async function Ze(e,t){let r=new URL(e.url),o=nr(r.pathname);if(!o)return T(404,"Not found","PROXY_NOT_FOUND");let n=t?.[o.namespace];if(!n)return T(404,`Backend "${o.namespace}" not configured`,"BACKEND_NOT_FOUND");if(!re(o.path,n.allowedPaths))return T(403,"Path not allowed","PATH_NOT_ALLOWED");if(re(o.path,n.deniedPaths))return T(403,"Path denied","PATH_DENIED");let s=new URL(o.path+r.search,n.url),a=new Headers;if(n.prepare){let l={request:e,headers:a,url:s};try{let f=await n.prepare(l);if(f instanceof Response)return f}catch(f){return console.error(`[devix] server.${o.namespace}.prepare error:`,f),T(500,"Proxy prepare failed","PREPARE_ERROR")}}if(!a.has("Accept")){let l=e.headers.get("Accept");l&&a.set("Accept",l)}let m=e.headers.get("Content-Type");m&&!a.has("Content-Type")&&a.set("Content-Type",m);let g=null;e.method!=="GET"&&e.method!=="HEAD"&&(g=await e.arrayBuffer(),g.byteLength===0&&(g=null));try{let l=await fetch(s,{method:e.method,headers:a,body:g,redirect:"manual"});return new Response(l.body,{status:l.status,statusText:l.statusText,headers:ir(l.headers)})}catch(l){return console.error(`[devix] server.${o.namespace} fetch error:`,l),T(502,"Bad Gateway","BACKEND_UNREACHABLE")}}function ir(e){let t=new Headers;return e.forEach((r,o)=>{sr.has(o.toLowerCase())||t.set(o,r)}),t}var Ke,sr,Qe=d(()=>{"use strict";ze();te();Ke="/_devix/server";sr=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailers","transfer-encoding","upgrade"])});function et(e,{apiModule:t,renderModule:r,loaderTimeout:o,server:n}){n&&e.all("/_devix/server/*",async s=>{try{return await Ze(s.req.raw,n)}catch(a){return console.error("[devix] proxy fatal error:",a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.all("/api/*",async s=>{try{return await t.handleApiRequest(s.req.url,s.req.raw,n)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}}),e.get("/_data/*",async s=>{try{let{pathname:a,search:m}=new URL(s.req.url,"http://localhost"),g=a.replace(/^\/_data/,"")+m,l=await r.runLoader(g,s.req.raw,{loaderTimeout:o,server:n});if(l.error)return s.json({statusCode:500,message:"Internal Server Error"},500);if("loaderError"in l){let f=M(l.loaderError);return s.json(f,f.statusCode)}return s.json(l)}catch(a){return console.error(a),s.json({statusCode:500,message:"Internal Server Error"},500)}})}function tt(e,{renderModule:t,manifest:r,loaderTimeout:o,server:n}){e.get("*",async s=>{try{let{html:a,statusCode:m,headers:g}=await t.render(s.req.url,s.req.raw,{manifest:r,loaderTimeout:o,server:n}),l=s.html(`<!DOCTYPE html>${a}`,m);for(let[f,L]of Object.entries(g))l.headers.set(f,L);return l}catch(a){return console.error(a),s.text("Internal Server Error",500)}})}var rt=d(()=>{"use strict";te();Qe()});import{loadEnv as ar}from"vite";function ot(e){let t=ar(e,process.cwd(),"");for(let[r,o]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=o)}var nt=d(()=>{"use strict"});var fr={};import{readFileSync as oe}from"node:fs";import{serve as cr}from"@hono/node-server";import{serveStatic as lr}from"@hono/node-server/serve-static";import{Hono as dr}from"hono";import{resolve as st,join as j}from"node:path";import{pathToFileURL as it}from"node:url";var ne,se,ie,v,ur,pr,I,ae,at=d(async()=>{"use strict";rt();nt();F();ot("production");try{v=JSON.parse(oe(j(process.cwd(),"dist/devix.config.json"),"utf-8")),v.output!=="static"&&(ne=await import(it(st(process.cwd(),"dist/server/render.js")).href),se=await import(it(st(process.cwd(),"dist/server/api.js")).href)),ie=JSON.parse(oe(j(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}ur=Number(process.env.PORT)||v.port||3e3,pr=typeof v.host=="string"?v.host:v.host?"0.0.0.0":process.env.HOST||"0.0.0.0",I=new dr,ae=j(process.cwd(),"dist/client");v.output==="static"&&I.get("/_data/*",e=>{let t=e.req.path.replace(/^\/_data/,"")||"/",r=t==="/"?j(ae,"_data/index.json"):j(ae,"_data",`${t}.json`);try{let o=oe(r,"utf-8");return e.json(JSON.parse(o))}catch{return e.json({error:"not found"},404)}});I.use("/*",lr({root:ae,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));if(v.output==="static")console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client");else{let e=await _(process.cwd()).catch(()=>null);et(I,{renderModule:ne,apiModule:se,manifest:ie,server:e?.server}),tt(I,{renderModule:ne,apiModule:se,manifest:ie,loaderTimeout:v.loaderTimeout})}cr({fetch:I.fetch,port:ur,hostname:pr},e=>console.log(`http://${e.address}:${e.port}`))});var ct=process.argv[2];switch(ct){case"dev":await Promise.resolve().then(()=>(ce(),xt));break;case"build":await K().then(()=>qe);break;case"generate":await Ye().then(()=>tr);break;case"start":await at().then(()=>fr);break;case"--version":case"-v":{console.log("0.5.2");break}case"--help":case"-h":console.log(`
|
|
271
271
|
devix \u2014 a lightweight SSR framework
|
|
272
272
|
|
|
273
273
|
Usage:
|
|
@@ -5,9 +5,9 @@ export declare class RouteContext {
|
|
|
5
5
|
readonly params: Record<string, string>;
|
|
6
6
|
readonly request: Request;
|
|
7
7
|
readonly url: URL;
|
|
8
|
-
readonly $server: Record<string, BackendClient
|
|
8
|
+
readonly $server: Record<string, BackendClient>;
|
|
9
9
|
private _state;
|
|
10
|
-
constructor(params: Record<string, string>, request: Request, url: URL, $server?: Record<string, BackendClient
|
|
10
|
+
constructor(params: Record<string, string>, request: Request, url: URL, $server?: Record<string, BackendClient>);
|
|
11
11
|
set<T>(key: string, value: T): void;
|
|
12
12
|
get<T>(key: string): T | undefined;
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/api-context.ts"],
|
|
4
|
-
"sourcesContent": ["import type {DevixHandler} from './create-handler'\nimport type {RouteError} from '../utils/response'\nimport type {BackendClient} from './server-client'\n\nexport class RouteContext {\n readonly params: Record<string, string>\n readonly request: Request\n readonly url: URL\n readonly $server: Record<string, BackendClient
|
|
5
|
-
"mappings": "AAIO,IAAMA,EAAN,KAAmB,CACb,OACA,QACA,IACA,QACD,OAAS,IAAI,IAErB,YACIC,EACAC,EACAC,EACAC,
|
|
4
|
+
"sourcesContent": ["import type {DevixHandler} from './create-handler'\nimport type {RouteError} from '../utils/response'\nimport type {BackendClient} from './server-client'\n\nexport class RouteContext {\n readonly params: Record<string, string>\n readonly request: Request\n readonly url: URL\n readonly $server: Record<string, BackendClient>\n private _state = new Map<string, unknown>()\n\n constructor(\n params: Record<string, string>,\n request: Request,\n url: URL,\n $server: Record<string, BackendClient> = {},\n ) {\n this.params = params\n this.request = request\n this.url = url\n this.$server = $server\n }\n\n set<T>(key: string, value: T): void {\n this._state.set(key, value)\n }\n\n get<T>(key: string): T | undefined {\n return this._state.get(key) as T\n }\n}\n\nexport type RouteResult = Response | RouteError | Record<string, unknown> | unknown[] | null | void\n\nexport type RouteHandler = (ctx: RouteContext) => Promise<RouteResult> | RouteResult\n\nexport interface MiddlewareModule {\n middleware: (ctx: RouteContext) => Promise<Response | null> | Response | null\n}\n\ntype AnyHandler = RouteHandler | DevixHandler<any, any>\n\nexport interface RouteModule {\n GET?: AnyHandler\n POST?: AnyHandler\n PUT?: AnyHandler\n PATCH?: AnyHandler\n DELETE?: AnyHandler\n HEAD?: AnyHandler\n OPTIONS?: AnyHandler\n}\n"],
|
|
5
|
+
"mappings": "AAIO,IAAMA,EAAN,KAAmB,CACb,OACA,QACA,IACA,QACD,OAAS,IAAI,IAErB,YACIC,EACAC,EACAC,EACAC,EAAyC,CAAC,EAC5C,CACE,KAAK,OAASH,EACd,KAAK,QAAUC,EACf,KAAK,IAAMC,EACX,KAAK,QAAUC,CACnB,CAEA,IAAOC,EAAaC,EAAgB,CAChC,KAAK,OAAO,IAAID,EAAKC,CAAK,CAC9B,CAEA,IAAOD,EAA4B,CAC/B,OAAO,KAAK,OAAO,IAAIA,CAAG,CAC9B,CACJ",
|
|
6
6
|
"names": ["RouteContext", "params", "request", "url", "$server", "key", "value"]
|
|
7
7
|
}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type { DevixHandler } from './create-handler';
|
|
|
13
13
|
export type { StandardSchemaV1 } from '../utils/standard-schema';
|
|
14
14
|
export { FetchError } from './fetch';
|
|
15
15
|
export { $server } from './server-client';
|
|
16
|
-
export type {
|
|
16
|
+
export type { BackendClient, ServerFetchOptions } from './server-client';
|
|
17
17
|
export { DevixError } from './error-boundary';
|
|
18
18
|
export type { DevixErrorOptions } from './error-boundary';
|
|
19
19
|
export type { HttpMethod } from './fetch';
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as U,useContext as v,useEffect as xe,useRef as Y,useState as ae}from"react";import{RouterContext as L}from"virtual:devix/context";import{getDefaultErrorPage as se,loadErrorPage as ie,matchClientRoute as de}from"virtual:devix/client-routes";import{Fragment as te,jsx as _}from"react/jsx-runtime";function ge(e,t){let n=[];e.title&&n.push({tag:"title",children:e.title}),e.description&&n.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&n.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let r=e.og?.title??e.title;r&&n.push({tag:"meta",property:"og:title",content:r});let a=e.og?.description??e.description;a&&n.push({tag:"meta",property:"og:description",content:a}),e.og?.image&&n.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&n.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&n.push({tag:"meta",property:"og:url",content:e.og.url});let i=e.twitter?.title??e.title;i&&n.push({tag:"meta",name:"twitter:title",content:i});let g=e.twitter?.description??e.description;if(g&&n.push({tag:"meta",name:"twitter:description",content:g}),e.twitter?.card&&n.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&n.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&n.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&n.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&n.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[o,f]of Object.entries(e.alternates))n.push({tag:"link",rel:"alternate",href:f,hrefLang:o});if(e.icons){let o=Array.isArray(e.icons)?e.icons:[e.icons];for(let f of o){let y=typeof f=="string"?{href:f}:f;n.push({tag:"link",rel:y.rel??"icon",href:y.href,...y.type&&{type:y.type},...y.sizes&&{sizes:y.sizes}})}}if(t){let o=[];t.width!==void 0&&o.push(`width=${t.width}`),t.initialScale!==void 0&&o.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&o.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&o.push(`user-scalable=${t.userScalable?"yes":"no"}`),o.length&&n.push({tag:"meta",name:"viewport",content:o.join(", ")}),t.themeColor&&n.push({tag:"meta",name:"theme-color",content:t.themeColor})}return n}function ee({metadata:e,viewport:t}){return typeof window>"u"||!e?null:_(te,{children:he(e,t)})}function he(e,t){let n=ge(e,t);return _(te,{children:n.map((r,a)=>r.tag==="title"?_("title",{children:r.children},a):r.tag==="link"?_("link",{rel:r.rel,href:r.href,hrefLang:r.hrefLang,type:r.type,sizes:r.sizes},a):_("meta",{name:r.name,property:r.property,content:r.content},a))})}import{createContext as X}from"react";var C=globalThis;C.__devix_RouterContext__??=X(null);var ne=C.__devix_RouterContext__;C.__devix_PageMetaContext__??=X(null);C.__devix_RouteDataContext__??=X(null);var re=C.__devix_PageMetaContext__,H=C.__devix_RouteDataContext__;import{Component as me}from"react";import{jsx as oe}from"react/jsx-runtime";var G=class extends me{state={error:null};static getDerivedStateFromError(t){return t instanceof K?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?oe(this.props.ErrorPage,{...this.state.error}):this.state.error?oe("h1",{children:this.state.error.statusCode}):this.props.children}},K=class extends Error{statusCode;code;data;constructor(t,n,r){super(n),this.name="DevixError",this.statusCode=t,this.code=r?.code,this.data=r?.data}};function O(e){let t=new URL(window.location.href);t.pathname.endsWith("/")||(t.pathname+="/");let n=new URL(e,t);if(n.origin!==window.location.origin)return{kind:"external",url:n};let r=n.pathname.length>1?n.pathname.replace(/\/$/,""):n.pathname;return{kind:"internal",pathname:r,href:r+n.search+n.hash}}import{jsx as x,jsxs as be}from"react/jsx-runtime";var Pe={width:"device-width",initialScale:1};function Re(){return v(L)}var we=()=>Promise.resolve(),ke=()=>Promise.resolve();function Te(){return v(L)?.navigate??we}function Ee(){return v(L)?.revalidate??ke}function Se(){let e=v(H);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function Ce(){let e=v(H);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function ve(){let e=v(L);if(!e)throw new Error("useGuardData must be used within a route or layout");return e.guardData}function Me({initialData:e,initialParams:t,initialPage:n,initialLayouts:r=[],initialLayoutsData:a=[],initialGuardData:i=null,initialMeta:g,initialViewport:o,initialError:f,initialErrorPage:y,clientEntry:M}){let[s,E]=ae({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:a,guardData:i,Page:n,layouts:r,metadata:g??null,viewport:o,pendingError:f,ErrorPage:y}),b=Y(null),[w,$]=ae(!1),B=Y(new Map),le=U(u=>{let c=O(u);if(c.kind==="external")return;let l=c.href;if(B.current.has(l))return;let d=de(c.pathname);if(!d)return;let p=new AbortController,m=Promise.all([Promise.all([d.load(),...d.loadLayouts.map(P=>P())]),fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:p.signal})]).then(async([[P,...h],A])=>{if(!A.ok||!P.default)return null;let F=await A.json();return{pageMod:P,layoutMods:h,data:F}}).catch(()=>null),N=setTimeout(()=>{p.abort(),B.current.delete(l)},3e3);m.finally(()=>clearTimeout(N)),B.current.set(l,{promise:m,controller:p})},[]),D=U(async(u,c)=>{let l=u.split("?")[0].split("#")[0],d=de(l);if(!d){let R=await ie()??se();E(W=>({...W,pathname:l,pendingError:{statusCode:404,message:"Not found"},ErrorPage:R??void 0}));return}let p=B.current.get(u);p&&B.current.delete(u);let m=p?await p.promise:null;if(c.signal.aborted)return;let N,P,h;if(m)({pageMod:N,layoutMods:P,data:h}=m);else{let[[R,...W],k]=await Promise.all([Promise.all([d.load(),...d.loadLayouts.map(j=>j())]),fetch(`/_data${u}`,{headers:{Accept:"application/json"},signal:c.signal})]);if(c.signal.aborted||!R.default)return;if(!k.ok){let j=k.headers.get("Content-Type")??"",S=null;try{j.includes("application/json")?S=await k.json():j.includes("text/plain")&&(S={message:await k.text()})}catch{}let Z={};k.headers.forEach((q,ye)=>{Z[ye]=q});let fe=await ie()??se();E(q=>({...q,pathname:l,pendingError:{statusCode:S?.statusCode??k.status,message:S?.message??"Server error",code:S?.code,data:S?.data,headers:Z},ErrorPage:fe??void 0}));return}N=R,P=W,h=await k.json()}if(h.redirect){h.redirectReplace?window.history.replaceState(null,"",h.redirect):window.history.pushState(null,"",h.redirect),await D(h.redirect,c);return}E({pathname:l,params:h.params??{},loaderData:h.loaderData,layoutsData:(h.layouts??[]).map(R=>R.loaderData),guardData:h.guardData??null,Page:N.default,layouts:P.map(R=>R.default),metadata:h.metadata??null,viewport:h.viewport??Pe});let A=u.includes("#")?u.split("#")[1]:null,F=getComputedStyle(document.documentElement).scrollBehavior;A?requestAnimationFrame(()=>{document.getElementById(A)?.scrollIntoView({behavior:F})}):window.scrollTo({top:0,behavior:F})},[]),J=U(async(u,c)=>{let l=O(u);if(l.kind==="external"){window.location.href=l.url.href;return}let d=l.href;b.current?.abort();let p=new AbortController;b.current=p,$(!0);let m=async()=>{window.history[c?.replace?"replaceState":"pushState"](null,"",d),await D(d,p)};try{c?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(m).finished:await m()}finally{p.signal.aborted||$(!1)}},[D]),Q=Y(null),pe=U(async()=>{Q.current?.abort();let u=new AbortController;Q.current=u;let c=window.location.pathname+window.location.search,l;try{l=await fetch(`/_data${c}`,{headers:{Accept:"application/json"},signal:u.signal})}catch(p){if(p.name==="AbortError")return;throw p}if(u.signal.aborted||!l.ok)return;let d=await l.json();if(!u.signal.aborted){if(d.redirect){await J(d.redirect,{replace:d.redirectReplace});return}E(p=>({...p,loaderData:d.loaderData,layoutsData:(d.layouts??[]).map(m=>m.loaderData),guardData:d.guardData??null,params:d.params??p.params,metadata:d.metadata??p.metadata,viewport:d.viewport??p.viewport}))}},[J]);xe(()=>{let u=()=>{b.current?.abort();let c=new AbortController;b.current=c;let l=window.location.pathname+window.location.search;D(l,c).catch(d=>{d.name!=="AbortError"&&console.error("[router] popstate error:",d)})};return window.addEventListener("popstate",u),()=>window.removeEventListener("popstate",u)},[D]);let z;if(s.pendingError)z=s.ErrorPage?x(s.ErrorPage,{...s.pendingError}):x("h1",{children:s.pendingError.statusCode});else{let u=x(H,{value:{loaderData:s.loaderData,params:s.params},children:x(s.Page,{data:s.loaderData,params:s.params,url:s.pathname})});for(let c=s.layouts.length-1;c>=0;c--){let l=s.layouts[c],d=s.layoutsData[c];u=x(H,{value:{loaderData:d,params:s.params},children:x(l,{data:d,params:s.params,children:u})})}z=x(G,{ErrorPage:s.ErrorPage,children:u},s.pathname)}return be(re,{value:{metadata:s.metadata,viewport:s.viewport,clientEntry:M},children:[x(ee,{metadata:s.metadata,viewport:s.viewport}),x(L,{value:{...s,isNavigating:w,navigate:J,revalidate:pe,prefetchRoute:le},children:z})]})}import{useCallback as I,useContext as Be,useRef as De}from"react";import{jsx as Ae}from"react/jsx-runtime";function Ne({href:e,prefetch:t="hover",replace:n=!1,viewTransition:r=!1,children:a,...i}){let g=Be(ne),o=De(null),f=I(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null)},[]),y=I(()=>{!g||t==="none"||g.prefetchRoute(e)},[e,t,g]),M=I(()=>{t!=="none"&&(o.current=setTimeout(y,50))},[t,y]),s=I(()=>{f()},[f]),E=I(()=>{f(),y()},[f,y]);return Ae("a",{href:e,onClick:w=>{if(f(),!g||w.ctrlKey||w.metaKey||w.shiftKey||w.button!==0||O(e).kind==="external")return;w.preventDefault();let $={replace:n,viewTransition:r};g.navigate(e,$)},onMouseEnter:M,onMouseLeave:s,onTouchStart:E,...i,children:a})}function _e(e,t){let n=e.headers.get("cookie");if(n)for(let r of n.split(";")){let[a,...i]=r.trim().split("=");if(a.trim()===t)return decodeURIComponent(i.join("="))}}function ue(e,t,n,r={}){let a=`${t}=${encodeURIComponent(n)}; Path=${r.path??"/"}`;r.domain&&(a+=`; Domain=${r.domain}`),r.maxAge!==void 0&&(a+=`; Max-Age=${r.maxAge}`),r.expires&&(a+=`; Expires=${r.expires.toUTCString()}`),r.httpOnly&&(a+="; HttpOnly"),r.secure&&(a+="; Secure"),r.sameSite&&(a+=`; SameSite=${r.sameSite}`),e.append("Set-Cookie",a)}function He(e,t,n={}){ue(e,t,"",{...n,maxAge:0,expires:new Date(0)})}function Oe(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var Le=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Ie=Symbol.for("devix.redirect");function Ve(e,t){let n=typeof t=="number"?t:t?.status??302,r=typeof t=="object"?t?.replace??!1:!1;return{[Ie]:!0,url:e,status:n,replace:r}}var $e=Symbol.for("devix.loaderError");function Fe(e,t,n){return{[$e]:!0,statusCode:e,message:t,code:n?.code,data:n?.data}}var ce="__devix_handler__";function je(e,t){return t?{[ce]:!0,fn:t,schema:e}:{[ce]:!0,fn:e}}function Ge(e){if(e&&typeof e=="object"&&"message"in e){let t=e.message;if(typeof t=="string"&&t.length>0)return t}return null}var T=class extends Error{constructor(n,r,a,i){super(Ge(i)??`HTTP ${n}: ${r}`);this.status=n;this.statusText=r;this.response=a;this.body=i;this.name="FetchError"}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let n=this.body.code;return typeof n=="string"?n:void 0}}};var Ke="/_devix/server";async function V(e,t,n,r){let a=new Headers(r?.headers),i;r?.body!==void 0&&(r.body instanceof FormData||r.body instanceof Blob||r.body instanceof ArrayBuffer?i=r.body:(i=JSON.stringify(r.body),a.has("Content-Type")||a.set("Content-Type","application/json")));let g=`${Ke}/${e}${n}`,o=await fetch(g,{method:t,headers:a,body:i,signal:r?.signal}),f=o.status===204||o.headers.get("Content-Length")==="0";if(!o.ok){let M=o.headers.get("Content-Type")??"",s;if(!f&&M.includes("application/json"))try{s=await o.json()}catch{}throw new T(o.status,o.statusText,o,s)}return f?null:(o.headers.get("Content-Type")??"").includes("application/json")?o.json():o.text()}function Ue(e){return{get:(t,n)=>V(e,"GET",t,n),post:(t,n,r)=>V(e,"POST",t,{...r,body:n}),put:(t,n,r)=>V(e,"PUT",t,{...r,body:n}),patch:(t,n,r)=>V(e,"PATCH",t,{...r,body:n}),delete:(t,n)=>V(e,"DELETE",t,n)}}var Je=new Proxy({},{get(e,t){if(typeof t=="string")return e[t]||(e[t]=Ue(t)),e[t]}});async function Nt(e,t){let n=t?.method??"GET",r=new Headers(t?.headers),a;t?.body!==void 0&&(t.body instanceof FormData||t.body instanceof Blob||t.body instanceof ArrayBuffer?a=t.body:(a=JSON.stringify(t.body),r.has("Content-Type")||r.set("Content-Type","application/json")));let i=await fetch(e,{method:n,headers:r,body:a,signal:t?.signal}),g=i.status===204||i.headers.get("Content-Length")==="0";if(!i.ok){let f=i.headers.get("Content-Type")??"",y;if(!g&&f.includes("application/json"))try{y=await i.json()}catch{}throw new T(i.status,i.statusText,i,y)}return g?null:(i.headers.get("Content-Type")??"").includes("application/json")?i.json():i.text()}export{Nt as $fetch,Je as $server,K as DevixError,T as FetchError,Ne as Link,Me as RouterProvider,je as createHandler,He as deleteCookie,Fe as error,_e as getCookie,Oe as json,Ve as redirect,ue as setCookie,Le as text,ve as useGuardData,Ce as useLoaderData,Te as useNavigate,Se as useParams,Ee as useRevalidate,Re as useRouter};
|
|
1
|
+
import{useCallback as U,useContext as b,useEffect as xe,useRef as Y,useState as ae}from"react";import{RouterContext as O}from"virtual:devix/context";import{getDefaultErrorPage as se,loadErrorPage as ie,matchClientRoute as de}from"virtual:devix/client-routes";import{Fragment as te,jsx as H}from"react/jsx-runtime";function ye(e,t){let n=[];e.title&&n.push({tag:"title",children:e.title}),e.description&&n.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&n.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let r=e.og?.title??e.title;r&&n.push({tag:"meta",property:"og:title",content:r});let o=e.og?.description??e.description;o&&n.push({tag:"meta",property:"og:description",content:o}),e.og?.image&&n.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&n.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&n.push({tag:"meta",property:"og:url",content:e.og.url});let i=e.twitter?.title??e.title;i&&n.push({tag:"meta",name:"twitter:title",content:i});let y=e.twitter?.description??e.description;if(y&&n.push({tag:"meta",name:"twitter:description",content:y}),e.twitter?.card&&n.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&n.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&n.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&n.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&n.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[p,a]of Object.entries(e.alternates))n.push({tag:"link",rel:"alternate",href:a,hrefLang:p});if(e.icons){let p=Array.isArray(e.icons)?e.icons:[e.icons];for(let a of p){let f=typeof a=="string"?{href:a}:a;n.push({tag:"link",rel:f.rel??"icon",href:f.href,...f.type&&{type:f.type},...f.sizes&&{sizes:f.sizes}})}}if(t){let p=[];t.width!==void 0&&p.push(`width=${t.width}`),t.initialScale!==void 0&&p.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&p.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&p.push(`user-scalable=${t.userScalable?"yes":"no"}`),p.length&&n.push({tag:"meta",name:"viewport",content:p.join(", ")}),t.themeColor&&n.push({tag:"meta",name:"theme-color",content:t.themeColor})}return n}function ee({metadata:e,viewport:t}){return typeof window>"u"||!e?null:H(te,{children:me(e,t)})}function me(e,t){let n=ye(e,t);return H(te,{children:n.map((r,o)=>r.tag==="title"?H("title",{children:r.children},o):r.tag==="link"?H("link",{rel:r.rel,href:r.href,hrefLang:r.hrefLang,type:r.type,sizes:r.sizes},o):H("meta",{name:r.name,property:r.property,content:r.content},o))})}import{createContext as X}from"react";var k=globalThis;k.__devix_RouterContext__??=X(null);var ne=k.__devix_RouterContext__;k.__devix_PageMetaContext__??=X(null);k.__devix_RouteDataContext__??=X(null);var re=k.__devix_PageMetaContext__,B=k.__devix_RouteDataContext__;import{Component as he}from"react";import{jsx as oe}from"react/jsx-runtime";var G=class extends he{state={error:null};static getDerivedStateFromError(t){return t instanceof K?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?oe(this.props.ErrorPage,{...this.state.error}):this.state.error?oe("h1",{children:this.state.error.statusCode}):this.props.children}},K=class extends Error{statusCode;code;data;constructor(t,n,r){super(n),this.name="DevixError",this.statusCode=t,this.code=r?.code,this.data=r?.data}};function L(e){let t=new URL(window.location.href);t.pathname.endsWith("/")||(t.pathname+="/");let n=new URL(e,t);if(n.origin!==window.location.origin)return{kind:"external",url:n};let r=n.pathname.length>1?n.pathname.replace(/\/$/,""):n.pathname;return{kind:"internal",pathname:r,href:r+n.search+n.hash}}import{jsx as R,jsxs as Me}from"react/jsx-runtime";var Re={width:"device-width",initialScale:1};function we(){return b(O)}var Te=()=>Promise.resolve(),Pe=()=>Promise.resolve();function Ce(){return b(O)?.navigate??Te}function Ee(){return b(O)?.revalidate??Pe}function ve(){let e=b(B);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function ke(){let e=b(B);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function be(){let e=b(O);if(!e)throw new Error("useGuardData must be used within a route or layout");return e.guardData}function De({initialData:e,initialParams:t,initialPage:n,initialLayouts:r=[],initialLayoutsData:o=[],initialGuardData:i=null,initialMeta:y,initialViewport:p,initialError:a,initialErrorPage:f,clientEntry:F}){let[s,x]=ae({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:o,guardData:i,Page:n,layouts:r,metadata:y??null,viewport:p,pendingError:a,ErrorPage:f}),D=Y(null),[P,j]=ae(!1),M=Y(new Map),ce=U(u=>{let l=L(u);if(l.kind==="external")return;let c=l.href;if(M.current.has(c))return;let d=de(l.pathname);if(!d)return;let g=new AbortController,h=Promise.all([Promise.all([d.load(),...d.loadLayouts.map(w=>w())]),fetch(`/_data${c}`,{headers:{Accept:"application/json"},signal:g.signal})]).then(async([[w,...m],_])=>{if(!_.ok||!w.default)return null;let I=await _.json();return{pageMod:w,layoutMods:m,data:I}}).catch(()=>null),A=setTimeout(()=>{g.abort(),M.current.delete(c)},3e3);h.finally(()=>clearTimeout(A)),M.current.set(c,{promise:h,controller:g})},[]),S=U(async(u,l)=>{let c=u.split("?")[0].split("#")[0],d=de(c);if(!d){let T=await ie()??se();x(W=>({...W,pathname:c,pendingError:{statusCode:404,message:"Not found"},ErrorPage:T??void 0}));return}let g=M.current.get(u);g&&M.current.delete(u);let h=g?await g.promise:null;if(l.signal.aborted)return;let A,w,m;if(h)({pageMod:A,layoutMods:w,data:m}=h);else{let[[T,...W],C]=await Promise.all([Promise.all([d.load(),...d.loadLayouts.map($=>$())]),fetch(`/_data${u}`,{headers:{Accept:"application/json"},signal:l.signal})]);if(l.signal.aborted||!T.default)return;if(!C.ok){let $=C.headers.get("Content-Type")??"",v=null;try{$.includes("application/json")?v=await C.json():$.includes("text/plain")&&(v={message:await C.text()})}catch{}let Z={};C.headers.forEach((q,ge)=>{Z[ge]=q});let fe=await ie()??se();x(q=>({...q,pathname:c,pendingError:{statusCode:v?.statusCode??C.status,message:v?.message??"Server error",code:v?.code,data:v?.data,headers:Z},ErrorPage:fe??void 0}));return}A=T,w=W,m=await C.json()}if(m.redirect){m.redirectReplace?window.history.replaceState(null,"",m.redirect):window.history.pushState(null,"",m.redirect),await S(m.redirect,l);return}x({pathname:c,params:m.params??{},loaderData:m.loaderData,layoutsData:(m.layouts??[]).map(T=>T.loaderData),guardData:m.guardData??null,Page:A.default,layouts:w.map(T=>T.default),metadata:m.metadata??null,viewport:m.viewport??Re});let _=u.includes("#")?u.split("#")[1]:null,I=getComputedStyle(document.documentElement).scrollBehavior;_?requestAnimationFrame(()=>{document.getElementById(_)?.scrollIntoView({behavior:I})}):window.scrollTo({top:0,behavior:I})},[]),J=U(async(u,l)=>{let c=L(u);if(c.kind==="external"){window.location.href=c.url.href;return}let d=c.href;D.current?.abort();let g=new AbortController;D.current=g,j(!0);let h=async()=>{window.history[l?.replace?"replaceState":"pushState"](null,"",d),await S(d,g)};try{l?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(h).finished:await h()}finally{g.signal.aborted||j(!1)}},[S]),Q=Y(null),pe=U(async()=>{Q.current?.abort();let u=new AbortController;Q.current=u;let l=window.location.pathname+window.location.search,c;try{c=await fetch(`/_data${l}`,{headers:{Accept:"application/json"},signal:u.signal})}catch(g){if(g.name==="AbortError")return;throw g}if(u.signal.aborted||!c.ok)return;let d=await c.json();if(!u.signal.aborted){if(d.redirect){await J(d.redirect,{replace:d.redirectReplace});return}x(g=>({...g,loaderData:d.loaderData,layoutsData:(d.layouts??[]).map(h=>h.loaderData),guardData:d.guardData??null,params:d.params??g.params,metadata:d.metadata??g.metadata,viewport:d.viewport??g.viewport}))}},[J]);xe(()=>{let u=()=>{D.current?.abort();let l=new AbortController;D.current=l;let c=window.location.pathname+window.location.search;S(c,l).catch(d=>{d.name!=="AbortError"&&console.error("[router] popstate error:",d)})};return window.addEventListener("popstate",u),()=>window.removeEventListener("popstate",u)},[S]);let z;if(s.pendingError)z=s.ErrorPage?R(s.ErrorPage,{...s.pendingError}):R("h1",{children:s.pendingError.statusCode});else{let u=R(B,{value:{loaderData:s.loaderData,params:s.params},children:R(s.Page,{data:s.loaderData,params:s.params,url:s.pathname})});for(let l=s.layouts.length-1;l>=0;l--){let c=s.layouts[l],d=s.layoutsData[l];u=R(B,{value:{loaderData:d,params:s.params},children:R(c,{data:d,params:s.params,children:u})})}z=R(G,{ErrorPage:s.ErrorPage,children:u},s.pathname)}return Me(re,{value:{metadata:s.metadata,viewport:s.viewport,clientEntry:F},children:[R(ee,{metadata:s.metadata,viewport:s.viewport}),R(O,{value:{...s,isNavigating:P,navigate:J,revalidate:pe,prefetchRoute:ce},children:z})]})}import{useCallback as N,useContext as Se,useRef as Ae}from"react";import{jsx as He}from"react/jsx-runtime";function _e({href:e,prefetch:t="hover",replace:n=!1,viewTransition:r=!1,children:o,...i}){let y=Se(ne),p=Ae(null),a=N(()=>{p.current!==null&&(clearTimeout(p.current),p.current=null)},[]),f=N(()=>{!y||t==="none"||y.prefetchRoute(e)},[e,t,y]),F=N(()=>{t!=="none"&&(p.current=setTimeout(f,50))},[t,f]),s=N(()=>{a()},[a]),x=N(()=>{a(),f()},[a,f]);return He("a",{href:e,onClick:P=>{if(a(),!y||P.ctrlKey||P.metaKey||P.shiftKey||P.button!==0||L(e).kind==="external")return;P.preventDefault();let j={replace:n,viewTransition:r};y.navigate(e,j)},onMouseEnter:F,onMouseLeave:s,onTouchStart:x,...i,children:o})}function Be(e,t){let n=e.headers.get("cookie");if(n)for(let r of n.split(";")){let[o,...i]=r.trim().split("=");if(o.trim()===t)return decodeURIComponent(i.join("="))}}function ue(e,t,n,r={}){let o=`${t}=${encodeURIComponent(n)}; Path=${r.path??"/"}`;r.domain&&(o+=`; Domain=${r.domain}`),r.maxAge!==void 0&&(o+=`; Max-Age=${r.maxAge}`),r.expires&&(o+=`; Expires=${r.expires.toUTCString()}`),r.httpOnly&&(o+="; HttpOnly"),r.secure&&(o+="; Secure"),r.sameSite&&(o+=`; SameSite=${r.sameSite}`),e.append("Set-Cookie",o)}function Le(e,t,n={}){ue(e,t,"",{...n,maxAge:0,expires:new Date(0)})}function Oe(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var Ne=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Ve=Symbol.for("devix.redirect");function Fe(e,t){let n=typeof t=="number"?t:t?.status??302,r=typeof t=="object"?t?.replace??!1:!1;return{[Ve]:!0,url:e,status:n,replace:r}}var je=Symbol.for("devix.loaderError");function Ie(e,t,n){return{[je]:!0,statusCode:e,message:t,code:n?.code,data:n?.data}}var le="__devix_handler__";function $e(e,t){return t?{[le]:!0,fn:t,schema:e}:{[le]:!0,fn:e}}function Ge(e){if(e&&typeof e=="object"&&"message"in e){let t=e.message;if(typeof t=="string"&&t.length>0)return t}return null}var E=class extends Error{constructor(n,r,o,i){super(Ge(i)??`HTTP ${n}: ${r}`);this.status=n;this.statusText=r;this.response=o;this.body=i;this.name="FetchError"}get code(){if(this.body&&typeof this.body=="object"&&"code"in this.body){let n=this.body.code;return typeof n=="string"?n:void 0}}};var Ke="/_devix/server";async function V(e,t,n,r,o){let i=new Headers(o?.headers),y;r!=null&&(r instanceof FormData||r instanceof Blob||r instanceof ArrayBuffer?y=r:(y=JSON.stringify(r),i.has("Content-Type")||i.set("Content-Type","application/json")));let p=`${Ke}/${e}${n}`,a=await fetch(p,{method:t,headers:i,body:y,signal:o?.signal}),f=a.status===204||a.headers.get("Content-Length")==="0";if(!a.ok){let s=a.headers.get("Content-Type")??"",x;if(!f&&s.includes("application/json"))try{x=await a.json()}catch{}throw new E(a.status,a.statusText,a,x)}return f?null:(a.headers.get("Content-Type")??"").includes("application/json")?await a.json():await a.text()}function Ue(e){return{get:(t,n)=>V(e,"GET",t,void 0,n),post:(t,n,r)=>V(e,"POST",t,n,r),put:(t,n,r)=>V(e,"PUT",t,n,r),patch:(t,n,r)=>V(e,"PATCH",t,n,r),delete:(t,n)=>V(e,"DELETE",t,void 0,n)}}var Je=new Proxy({},{get(e,t){if(typeof t=="string")return e[t]||(e[t]=Ue(t)),e[t]}});async function _t(e,t){let n=t?.method??"GET",r=new Headers(t?.headers),o;t?.body!==void 0&&(t.body instanceof FormData||t.body instanceof Blob||t.body instanceof ArrayBuffer?o=t.body:(o=JSON.stringify(t.body),r.has("Content-Type")||r.set("Content-Type","application/json")));let i=await fetch(e,{method:n,headers:r,body:o,signal:t?.signal}),y=i.status===204||i.headers.get("Content-Length")==="0";if(!i.ok){let a=i.headers.get("Content-Type")??"",f;if(!y&&a.includes("application/json"))try{f=await i.json()}catch{}throw new E(i.status,i.statusText,i,f)}return y?null:(i.headers.get("Content-Type")??"").includes("application/json")?i.json():i.text()}export{_t as $fetch,Je as $server,K as DevixError,E as FetchError,_e as Link,De as RouterProvider,$e as createHandler,Le as deleteCookie,Ie as error,Be as getCookie,Oe as json,Fe as redirect,ue as setCookie,Ne as text,be as useGuardData,ke as useLoaderData,Ce as useNavigate,ve as useParams,Ee as useRevalidate,we as useRouter};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|