@devlusoft/devix 0.4.1-beta.4 → 0.4.1-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/build.d.ts +1 -0
- package/dist/cli/dev-server.d.ts +1 -0
- package/dist/cli/dev-server.js +1 -1
- package/dist/cli/dev.d.ts +1 -0
- package/dist/cli/generate.d.ts +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/start.d.ts +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/runtime/api-context.d.ts +24 -0
- package/dist/runtime/client-router.d.ts +13 -0
- package/dist/runtime/context.d.ts +32 -0
- package/dist/runtime/create-handler.d.ts +10 -0
- package/dist/runtime/error-boundary.d.ts +19 -0
- package/dist/runtime/fetch.d.ts +39 -0
- package/dist/runtime/head.d.ts +7 -0
- package/dist/runtime/index.d.ts +14 -0
- package/dist/runtime/link.d.ts +8 -0
- package/dist/runtime/metadata.d.ts +10 -0
- package/dist/runtime/router-provider.d.ts +25 -0
- package/dist/runtime/server-app.d.ts +15 -0
- package/dist/server/api-router.d.ts +22 -0
- package/dist/server/api.d.ts +2 -0
- package/dist/server/collect-css.d.ts +2 -0
- package/dist/server/handler-store.d.ts +10 -0
- package/dist/server/index.d.ts +6 -0
- package/dist/server/pages-router.d.ts +21 -0
- package/dist/server/public-index.d.ts +1 -0
- package/dist/server/render.d.ts +62 -0
- package/dist/server/routes.d.ts +11 -0
- package/dist/server/types.d.ts +52 -0
- package/dist/types.d.ts +42 -0
- package/dist/utils/async.d.ts +1 -0
- package/dist/utils/banner.d.ts +1 -0
- package/dist/utils/banner.js +1 -1
- package/dist/utils/cookies.d.ts +12 -0
- package/dist/utils/duration.d.ts +1 -0
- package/dist/utils/env.d.ts +1 -0
- package/dist/utils/html.d.ts +2 -0
- package/dist/utils/patterns.d.ts +1 -0
- package/dist/utils/response.d.ts +19 -0
- package/dist/vite/codegen/api.d.ts +6 -0
- package/dist/vite/codegen/client-routes.d.ts +6 -0
- package/dist/vite/codegen/context.d.ts +1 -0
- package/dist/vite/codegen/entry-client.d.ts +5 -0
- package/dist/vite/codegen/extract-methods.d.ts +4 -0
- package/dist/vite/codegen/render.d.ts +6 -0
- package/dist/vite/codegen/routes-dts.d.ts +10 -0
- package/dist/vite/codegen/scan-api.d.ts +2 -0
- package/dist/vite/codegen/write-routes-dts.d.ts +1 -0
- package/dist/vite/index.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli/dev-server.js
CHANGED
|
@@ -157,7 +157,7 @@ declare module '@devlusoft/devix' {
|
|
|
157
157
|
${i}
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
-
`}function B(e,t){let r=[];for(let i of ue(e)){let o=D(e,i);pe(o).isDirectory()?r.push(...B(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(de(t,o).replace(/\\/g,"/"))}return r}function A(e,t){let r=D(t,e,"api"),i;try{i=B(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let s=le(D(t,o),"utf-8"),m=N(s);return m.length===0?[]:[W(o,`${e}/api`,m)]}catch{return[]}})}import{mkdirSync as me,readFileSync as fe,writeFileSync as ge,existsSync as he}from"node:fs";import{join as X}from"node:path";function b(e,t){let r=X(t,".devix"),i=X(r,"routes.d.ts");return me(r,{recursive:!0}),he(i)&&fe(i,"utf-8")===e?!1:(ge(i,e,"utf-8"),!0)}import{parseSync as we}from"oxc-parser";var S=ve(Re(import.meta.url)),C="virtual:devix/entry-client",I="virtual:devix/client-routes",L="virtual:devix/render",M="virtual:devix/api",O="virtual:devix/context",J=new Set(["loader","guard","generateStaticParams","headers"]);function Y(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=d(S,"../server/render.js").replace(/\\/g,"/"),s=d(S,"../server/api.js").replace(/\\/g,"/"),m=d(S,"../runtime/client-router.js").replace(/\\/g,"/"),y={name:"devix",enforce:"pre",resolveId(n){if(n===C)return`\0${C}`;if(n===I)return`\0${I}`;if(n===L)return`\0${L}`;if(n===M)return`\0${M}`;if(n===O)return`\0${O}`},load(n){if(n===`\0${C}`)return U({cssUrls:i});if(n===`\0${I}`)return H({pagesDir:r,matcherPath:m});if(n===`\0${L}`)return q({pagesDir:r,renderPath:o});if(n===`\0${M}`)return F({apiPath:s,appDir:t});if(n===`\0${O}`)return V()},transform(n,c,x){if(x?.ssr)return;let a=d(process.cwd(),r);if(!c.startsWith(a))return;let ne=we(c,n,{sourceType:"module"}),R=[];for(let l of ne.program.body){if(l.type!=="ExportNamedDeclaration"||!l.declaration)continue;let p=l.declaration;if(p.type==="FunctionDeclaration"&&p.id&&J.has(p.id.name)&&R.push({start:l.start,end:l.end,name:p.id.name}),p.type==="VariableDeclaration"){let w=new Set;for(let E of p.declarations)E.id.type==="Identifier"&&J.has(E.id.name)&&(w.has(l.start)||(w.add(l.start),R.push({start:l.start,end:l.end,name:E.id.name})))}}if(R.length===0)return;R.sort((l,p)=>p.start-l.start);let v=n;for(let{start:l,end:p,name:w}of R)v=v.slice(0,l)+`export const ${w} = undefined`+v.slice(p);return{code:v,map:null}},buildStart(){let n=process.cwd(),c=A(t,n);b(T(c,`${t}/api`),n)},configureServer(n){let c=process.cwd(),x=()=>{let a=A(t,c);b(T(a,`${t}/api`),c)};n.watcher.add(d(c,"devix.config.ts")),n.watcher.on("change",a=>{a===d(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",a=>{a.startsWith(d(c,r))&&P(),a.includes(`${t}/api`)&&($(),x())}),n.watcher.on("unlink",a=>{a.startsWith(d(c,r))&&P(),a.includes(`${t}/api`)&&($(),x())}),n.watcher.on("change",a=>{a.includes(`${t}/api`)&&!a.endsWith("middleware.ts")&&x()})}},f={plugins:[xe(),y],publicDir:d(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return ye(f,e.vite??{})}function G(e,{apiModule:t,renderModule:r,loaderTimeout:i}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(s){return console.error(s),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:s,search:m}=new URL(o.req.url,"http://localhost"),y=s.replace(/^\/_data/,"")+m,f=await r.runLoader(y,o.req.raw,{loaderTimeout:i});return f.error?o.json({error:"internal error"},500):o.json(f)}catch(s){return console.error(s),o.json({error:"internal error"},500)}})}import u from"picocolors";import{networkInterfaces as Ee}from"node:os";function _e(e){let t=Ee();for(let r of Object.values(t))for(let i of r??[])if(i.family==="IPv4"&&!i.internal)return`http://${i.address}:${e}/`;return null}function z(e){let t="0.4.1-beta.
|
|
160
|
+
`}function B(e,t){let r=[];for(let i of ue(e)){let o=D(e,i);pe(o).isDirectory()?r.push(...B(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(de(t,o).replace(/\\/g,"/"))}return r}function A(e,t){let r=D(t,e,"api"),i;try{i=B(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let s=le(D(t,o),"utf-8"),m=N(s);return m.length===0?[]:[W(o,`${e}/api`,m)]}catch{return[]}})}import{mkdirSync as me,readFileSync as fe,writeFileSync as ge,existsSync as he}from"node:fs";import{join as X}from"node:path";function b(e,t){let r=X(t,".devix"),i=X(r,"routes.d.ts");return me(r,{recursive:!0}),he(i)&&fe(i,"utf-8")===e?!1:(ge(i,e,"utf-8"),!0)}import{parseSync as we}from"oxc-parser";var S=ve(Re(import.meta.url)),C="virtual:devix/entry-client",I="virtual:devix/client-routes",L="virtual:devix/render",M="virtual:devix/api",O="virtual:devix/context",J=new Set(["loader","guard","generateStaticParams","headers"]);function Y(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=d(S,"../server/render.js").replace(/\\/g,"/"),s=d(S,"../server/api.js").replace(/\\/g,"/"),m=d(S,"../runtime/client-router.js").replace(/\\/g,"/"),y={name:"devix",enforce:"pre",resolveId(n){if(n===C)return`\0${C}`;if(n===I)return`\0${I}`;if(n===L)return`\0${L}`;if(n===M)return`\0${M}`;if(n===O)return`\0${O}`},load(n){if(n===`\0${C}`)return U({cssUrls:i});if(n===`\0${I}`)return H({pagesDir:r,matcherPath:m});if(n===`\0${L}`)return q({pagesDir:r,renderPath:o});if(n===`\0${M}`)return F({apiPath:s,appDir:t});if(n===`\0${O}`)return V()},transform(n,c,x){if(x?.ssr)return;let a=d(process.cwd(),r);if(!c.startsWith(a))return;let ne=we(c,n,{sourceType:"module"}),R=[];for(let l of ne.program.body){if(l.type!=="ExportNamedDeclaration"||!l.declaration)continue;let p=l.declaration;if(p.type==="FunctionDeclaration"&&p.id&&J.has(p.id.name)&&R.push({start:l.start,end:l.end,name:p.id.name}),p.type==="VariableDeclaration"){let w=new Set;for(let E of p.declarations)E.id.type==="Identifier"&&J.has(E.id.name)&&(w.has(l.start)||(w.add(l.start),R.push({start:l.start,end:l.end,name:E.id.name})))}}if(R.length===0)return;R.sort((l,p)=>p.start-l.start);let v=n;for(let{start:l,end:p,name:w}of R)v=v.slice(0,l)+`export const ${w} = undefined`+v.slice(p);return{code:v,map:null}},buildStart(){let n=process.cwd(),c=A(t,n);b(T(c,`${t}/api`),n)},configureServer(n){let c=process.cwd(),x=()=>{let a=A(t,c);b(T(a,`${t}/api`),c)};n.watcher.add(d(c,"devix.config.ts")),n.watcher.on("change",a=>{a===d(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",a=>{a.startsWith(d(c,r))&&P(),a.includes(`${t}/api`)&&($(),x())}),n.watcher.on("unlink",a=>{a.startsWith(d(c,r))&&P(),a.includes(`${t}/api`)&&($(),x())}),n.watcher.on("change",a=>{a.includes(`${t}/api`)&&!a.endsWith("middleware.ts")&&x()})}},f={plugins:[xe(),y],publicDir:d(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return ye(f,e.vite??{})}function G(e,{apiModule:t,renderModule:r,loaderTimeout:i}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(s){return console.error(s),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:s,search:m}=new URL(o.req.url,"http://localhost"),y=s.replace(/^\/_data/,"")+m,f=await r.runLoader(y,o.req.raw,{loaderTimeout:i});return f.error?o.json({error:"internal error"},500):o.json(f)}catch(s){return console.error(s),o.json({error:"internal error"},500)}})}import u from"picocolors";import{networkInterfaces as Ee}from"node:os";function _e(e){let t=Ee();for(let r of Object.values(t))for(let i of r??[])if(i.family==="IPv4"&&!i.internal)return`http://${i.address}:${e}/`;return null}function z(e){let t="0.4.1-beta.5",r=_e(e);console.log(),console.log(` ${u.bold(u.yellow("devix"))} ${u.dim(`v${t}`)}`),console.log(),console.log(` ${u.green("\u279C")} ${u.bold("Local:")} ${u.cyan(`http://localhost:${e}/`)}`),console.log(r?` ${u.green("\u279C")} ${u.bold("Network:")} ${u.cyan(r)}`:` ${u.green("\u279C")} ${u.bold("Network:")} ${u.dim("use --host to expose")}`),console.log()}async function Z(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 K(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 Pe}from"vite";function Q(e){let t=Pe(e,process.cwd(),"");for(let[r,i]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=i)}Q("development");var ee="virtual:devix/render",be="virtual:devix/api",h=(await import(`${process.cwd()}/devix.config.ts`)).default,te=Number(process.env.PORT)||h.port||3e3,Se=typeof h.host=="string"?h.host:h.host?"0.0.0.0":"localhost",g=await Te({...Y(h),configFile:!1,appType:"custom",server:{middlewareMode:!0}}),re={render:async(...e)=>(await g.ssrLoadModule(ee)).render(...e),runLoader:async(...e)=>(await g.ssrLoadModule(ee)).runLoader(...e)},Ce={handleApiRequest:async(...e)=>(await g.ssrLoadModule(be)).handleApiRequest(...e)},k=new Ae;G(k,{renderModule:re,apiModule:Ce});k.get("*",async e=>{try{let{html:t,statusCode:r,headers:i}=await re.render(e.req.url,e.req.raw,{loaderTimeout:K(h.loaderTimeout??1e4)}),s=(await Z(g)).map(n=>`<link rel="stylesheet" href="${n}">`).join(`
|
|
161
161
|
`),m=s?t.replace("</head>",`${s}
|
|
162
162
|
</head>`):t,y=await g.transformIndexHtml(e.req.url,`<!DOCTYPE html>${m}`),f=e.html(y,r);for(let[n,c]of Object.entries(i))f.headers.set(n,c);return f}catch(t){return g.ssrFixStacktrace(t),console.error(t),e.text("Internal Server Error",500)}});var Ie=De(k.fetch);$e(async(e,t)=>{await new Promise(r=>g.middlewares(e,t,r)),t.writableEnded||await Ie(e,t)}).listen(te,Se,()=>{z(te)});
|
|
163
163
|
//# sourceMappingURL=dev-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli/index.js
CHANGED
|
@@ -158,7 +158,7 @@ declare module '@devlusoft/devix' {
|
|
|
158
158
|
${i}
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
`}var A=s(()=>{"use strict";D()});import{readFileSync as Be,readdirSync as We,statSync as Je}from"node:fs";import{join as O,relative as Xe}from"node:path";function le(e,t){let r=[];for(let i of We(e)){let o=O(e,i);Je(o).isDirectory()?r.push(...le(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(Xe(t,o).replace(/\\/g,"/"))}return r}function M(e,t){let r=O(t,e,"api"),i;try{i=le(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=Be(O(t,o),"utf-8"),m=se(a);return m.length===0?[]:[ce(o,`${e}/api`,m)]}catch{return[]}})}var ue=s(()=>{"use strict";ae();A()});import{mkdirSync as Ge,readFileSync as Ye,writeFileSync as ze,existsSync as Ze}from"node:fs";import{join as pe}from"node:path";function I(e,t){let r=pe(t,".devix"),i=pe(r,"routes.d.ts");return Ge(r,{recursive:!0}),Ze(i)&&Ye(i,"utf-8")===e?!1:(ze(i,e,"utf-8"),!0)}var de=s(()=>{"use strict"});import{mergeConfig as Ke}from"vite";import Qe from"@vitejs/plugin-react";import{fileURLToPath as et}from"node:url";import{dirname as tt,resolve as d}from"node:path";import{parseSync as rt}from"oxc-parser";function fe(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=d(k,"../server/render.js").replace(/\\/g,"/"),a=d(k,"../server/api.js").replace(/\\/g,"/"),m=d(k,"../runtime/client-router.js").replace(/\\/g,"/"),h={name:"devix",enforce:"pre",resolveId(n){if(n===L)return`\0${L}`;if(n===U)return`\0${U}`;if(n===j)return`\0${j}`;if(n===F)return`\0${F}`;if(n===H)return`\0${H}`},load(n){if(n===`\0${L}`)return G({cssUrls:i});if(n===`\0${U}`)return z({pagesDir:r,matcherPath:m});if(n===`\0${j}`)return K({pagesDir:r,renderPath:o});if(n===`\0${F}`)return ee({apiPath:a,appDir:t});if(n===`\0${H}`)return ne()},transform(n,l,x){if(x?.ssr)return;let c=d(process.cwd(),r);if(!l.startsWith(c))return;let Oe=rt(l,n,{sourceType:"module"}),v=[];for(let u of Oe.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let p=u.declaration;if(p.type==="FunctionDeclaration"&&p.id&&me.has(p.id.name)&&v.push({start:u.start,end:u.end,name:p.id.name}),p.type==="VariableDeclaration"){let w=new Set;for(let P of p.declarations)P.id.type==="Identifier"&&me.has(P.id.name)&&(w.has(u.start)||(w.add(u.start),v.push({start:u.start,end:u.end,name:P.id.name})))}}if(v.length===0)return;v.sort((u,p)=>p.start-u.start);let R=n;for(let{start:u,end:p,name:w}of v)R=R.slice(0,u)+`export const ${w} = undefined`+R.slice(p);return{code:R,map:null}},buildStart(){let n=process.cwd(),l=M(t,n);I(C(l,`${t}/api`),n)},configureServer(n){let l=process.cwd(),x=()=>{let c=M(t,l);I(C(c,`${t}/api`),l)};n.watcher.add(d(l,"devix.config.ts")),n.watcher.on("change",c=>{c===d(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",c=>{c.startsWith(d(l,r))&&$(),c.includes(`${t}/api`)&&(b(),x())}),n.watcher.on("unlink",c=>{c.startsWith(d(l,r))&&$(),c.includes(`${t}/api`)&&(b(),x())}),n.watcher.on("change",c=>{c.includes(`${t}/api`)&&!c.endsWith("middleware.ts")&&x()})}},g={plugins:[Qe(),h],publicDir:d(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Ke(g,e.vite??{})}var k,L,U,j,F,H,me,ge=s(()=>{"use strict";Y();Z();Q();te();re();D();ie();ue();A();de();k=tt(et(import.meta.url)),L="virtual:devix/entry-client",U="virtual:devix/client-routes",j="virtual:devix/render",F="virtual:devix/api",H="virtual:devix/context",me=new Set(["loader","guard","generateStaticParams","headers"])});function he(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var xe=s(()=>{"use strict"});var Re={};import{writeFileSync as ot}from"node:fs";import{resolve as nt}from"node:path";import{build as ve}from"vite";var y,ye,it,q=s(async()=>{"use strict";ge();xe();y=(await import(`${process.cwd()}/devix.config.ts`)).default,ye=fe(y);await ve({...ye,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await ve({...ye,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});it={port:y.port??3e3,host:y.host??!1,loaderTimeout:he(y.loaderTimeout??1e4),output:y.output??"server"};ot(nt(process.cwd(),"dist/devix.config.json"),JSON.stringify(it,null,2),"utf-8")});var dt={};import{readFileSync as st,mkdirSync as at,writeFileSync as ct}from"node:fs";import{resolve as we,join as N}from"node:path";var lt,ut,_e,pt,V,Ee=s(async()=>{"use strict";lt=(await import(`${process.cwd()}/devix.config.ts`)).default;lt.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await q().then(()=>Re);ut=Date.now(),_e=await import(we(process.cwd(),"dist/server/render.js")+`?t=${ut}`),pt=JSON.parse(st(we(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),V=await _e.getStaticRoutes();console.log(`[devix] Generating ${V.length} static page${V.length===1?"":"s"}...`);for(let e of V){let t=`http://localhost${e}`,{html:r,statusCode:i}=await _e.render(t,new Request(t),{manifest:pt});if(i!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${i}`);continue}let o=e==="/"?N(process.cwd(),"dist/client/index.html"):N(process.cwd(),"dist/client",e,"index.html");at(N(o,".."),{recursive:!0}),ct(o,`<!DOCTYPE html>${r}`,"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.")});function Pe(e,{apiModule:t,renderModule:r,loaderTimeout:i}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:a,search:m}=new URL(o.req.url,"http://localhost"),h=a.replace(/^\/_data/,"")+m,g=await r.runLoader(h,o.req.raw,{loaderTimeout:i});return g.error?o.json({error:"internal error"},500):o.json(g)}catch(a){return console.error(a),o.json({error:"internal error"},500)}})}function Se(e,{renderModule:t,manifest:r,loaderTimeout:i}){e.get("*",async o=>{try{let{html:a,statusCode:m,headers:h}=await t.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:i}),g=o.html(`<!DOCTYPE html>${a}`,m);for(let[n,l]of Object.entries(h))g.headers.set(n,l);return g}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Te=s(()=>{"use strict"});import{loadEnv as mt}from"vite";function $e(e){let t=mt(e,process.cwd(),"");for(let[r,i]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=i)}var be=s(()=>{"use strict"});var wt={};import{readFileSync as De}from"node:fs";import{serve as ft}from"@hono/node-server";import{serveStatic as gt}from"@hono/node-server/serve-static";import{Hono as ht}from"hono";import{resolve as _,join as xt}from"node:path";var B,W,J,f,vt,yt,E,Rt,Ce=s(async()=>{"use strict";Te();be();$e("production");try{f=JSON.parse(De(_(process.cwd(),"dist/devix.config.json"),"utf-8")),f.output!=="static"&&(B=await import(_(process.cwd(),"dist/server/render.js")),W=await import(_(process.cwd(),"dist/server/api.js"))),J=JSON.parse(De(_(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}vt=Number(process.env.PORT)||f.port||3e3,yt=typeof f.host=="string"?f.host:f.host?"0.0.0.0":process.env.HOST||"0.0.0.0",E=new ht,Rt=xt(process.cwd(),"dist/client");E.use("/*",gt({root:Rt,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));f.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Pe(E,{renderModule:B,apiModule:W,manifest:J}),Se(E,{renderModule:B,apiModule:W,manifest:J,loaderTimeout:f.loaderTimeout}));ft({fetch:E.fetch,port:vt,hostname:yt},e=>console.log(`http://${e.address}:${e.port}`))});var Ae=process.argv[2];switch(Ae){case"dev":await Promise.resolve().then(()=>(X(),je));break;case"build":await q().then(()=>Re);break;case"generate":await Ee().then(()=>dt);break;case"start":await Ce().then(()=>wt);break;case"--version":case"-v":{console.log("0.4.1-beta.
|
|
161
|
+
`}var A=s(()=>{"use strict";D()});import{readFileSync as Be,readdirSync as We,statSync as Je}from"node:fs";import{join as O,relative as Xe}from"node:path";function le(e,t){let r=[];for(let i of We(e)){let o=O(e,i);Je(o).isDirectory()?r.push(...le(o,t)):/\.(ts|tsx)$/.test(i)&&r.push(Xe(t,o).replace(/\\/g,"/"))}return r}function M(e,t){let r=O(t,e,"api"),i;try{i=le(r,t)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let a=Be(O(t,o),"utf-8"),m=se(a);return m.length===0?[]:[ce(o,`${e}/api`,m)]}catch{return[]}})}var ue=s(()=>{"use strict";ae();A()});import{mkdirSync as Ge,readFileSync as Ye,writeFileSync as ze,existsSync as Ze}from"node:fs";import{join as pe}from"node:path";function I(e,t){let r=pe(t,".devix"),i=pe(r,"routes.d.ts");return Ge(r,{recursive:!0}),Ze(i)&&Ye(i,"utf-8")===e?!1:(ze(i,e,"utf-8"),!0)}var de=s(()=>{"use strict"});import{mergeConfig as Ke}from"vite";import Qe from"@vitejs/plugin-react";import{fileURLToPath as et}from"node:url";import{dirname as tt,resolve as d}from"node:path";import{parseSync as rt}from"oxc-parser";function fe(e){let t=e.appDir??"app",r=`${t}/pages`,i=(e.css??[]).map(n=>n.startsWith("/")?n:`/${n.replace(/^\.\//,"")}`),o=d(k,"../server/render.js").replace(/\\/g,"/"),a=d(k,"../server/api.js").replace(/\\/g,"/"),m=d(k,"../runtime/client-router.js").replace(/\\/g,"/"),h={name:"devix",enforce:"pre",resolveId(n){if(n===L)return`\0${L}`;if(n===U)return`\0${U}`;if(n===j)return`\0${j}`;if(n===F)return`\0${F}`;if(n===H)return`\0${H}`},load(n){if(n===`\0${L}`)return G({cssUrls:i});if(n===`\0${U}`)return z({pagesDir:r,matcherPath:m});if(n===`\0${j}`)return K({pagesDir:r,renderPath:o});if(n===`\0${F}`)return ee({apiPath:a,appDir:t});if(n===`\0${H}`)return ne()},transform(n,l,x){if(x?.ssr)return;let c=d(process.cwd(),r);if(!l.startsWith(c))return;let Oe=rt(l,n,{sourceType:"module"}),v=[];for(let u of Oe.program.body){if(u.type!=="ExportNamedDeclaration"||!u.declaration)continue;let p=u.declaration;if(p.type==="FunctionDeclaration"&&p.id&&me.has(p.id.name)&&v.push({start:u.start,end:u.end,name:p.id.name}),p.type==="VariableDeclaration"){let w=new Set;for(let P of p.declarations)P.id.type==="Identifier"&&me.has(P.id.name)&&(w.has(u.start)||(w.add(u.start),v.push({start:u.start,end:u.end,name:P.id.name})))}}if(v.length===0)return;v.sort((u,p)=>p.start-u.start);let R=n;for(let{start:u,end:p,name:w}of v)R=R.slice(0,u)+`export const ${w} = undefined`+R.slice(p);return{code:R,map:null}},buildStart(){let n=process.cwd(),l=M(t,n);I(C(l,`${t}/api`),n)},configureServer(n){let l=process.cwd(),x=()=>{let c=M(t,l);I(C(c,`${t}/api`),l)};n.watcher.add(d(l,"devix.config.ts")),n.watcher.on("change",c=>{c===d(l,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),n.watcher.on("add",c=>{c.startsWith(d(l,r))&&$(),c.includes(`${t}/api`)&&(b(),x())}),n.watcher.on("unlink",c=>{c.startsWith(d(l,r))&&$(),c.includes(`${t}/api`)&&(b(),x())}),n.watcher.on("change",c=>{c.includes(`${t}/api`)&&!c.endsWith("middleware.ts")&&x()})}},g={plugins:[Qe(),h],publicDir:d(process.cwd(),e.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...e.envPrefix?{envPrefix:e.envPrefix}:{}};return Ke(g,e.vite??{})}var k,L,U,j,F,H,me,ge=s(()=>{"use strict";Y();Z();Q();te();re();D();ie();ue();A();de();k=tt(et(import.meta.url)),L="virtual:devix/entry-client",U="virtual:devix/client-routes",j="virtual:devix/render",F="virtual:devix/api",H="virtual:devix/context",me=new Set(["loader","guard","generateStaticParams","headers"])});function he(e){if(typeof e=="number")return e;let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!t)throw new Error(`[devix] Invalid duration: "${e}". Use a number (ms) or a string like "5s", "2m", "500ms".`);let r=parseFloat(t[1]);switch(t[2]){case"h":return r*36e5;case"m":return r*6e4;case"s":return r*1e3;default:return r}}var xe=s(()=>{"use strict"});var Re={};import{writeFileSync as ot}from"node:fs";import{resolve as nt}from"node:path";import{build as ve}from"vite";var y,ye,it,q=s(async()=>{"use strict";ge();xe();y=(await import(`${process.cwd()}/devix.config.ts`)).default,ye=fe(y);await ve({...ye,configFile:!1,build:{outDir:"dist/client",manifest:!0,rolldownOptions:{input:"virtual:devix/entry-client"}}});await ve({...ye,configFile:!1,build:{ssr:!0,outDir:"dist/server",copyPublicDir:!1,rolldownOptions:{input:{render:"virtual:devix/render",api:"virtual:devix/api"}}}});it={port:y.port??3e3,host:y.host??!1,loaderTimeout:he(y.loaderTimeout??1e4),output:y.output??"server"};ot(nt(process.cwd(),"dist/devix.config.json"),JSON.stringify(it,null,2),"utf-8")});var dt={};import{readFileSync as st,mkdirSync as at,writeFileSync as ct}from"node:fs";import{resolve as we,join as N}from"node:path";var lt,ut,_e,pt,V,Ee=s(async()=>{"use strict";lt=(await import(`${process.cwd()}/devix.config.ts`)).default;lt.output!=="static"&&console.warn('[devix] Tip: set output: "static" in devix.config.ts to skip the SSR server at runtime.');await q().then(()=>Re);ut=Date.now(),_e=await import(we(process.cwd(),"dist/server/render.js")+`?t=${ut}`),pt=JSON.parse(st(we(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8")),V=await _e.getStaticRoutes();console.log(`[devix] Generating ${V.length} static page${V.length===1?"":"s"}...`);for(let e of V){let t=`http://localhost${e}`,{html:r,statusCode:i}=await _e.render(t,new Request(t),{manifest:pt});if(i!==200){console.warn(`[devix] Skipping ${e} \u2014 status ${i}`);continue}let o=e==="/"?N(process.cwd(),"dist/client/index.html"):N(process.cwd(),"dist/client",e,"index.html");at(N(o,".."),{recursive:!0}),ct(o,`<!DOCTYPE html>${r}`,"utf-8"),console.log(` \u2713 ${e}`)}console.log("[devix] Generation complete.")});function Pe(e,{apiModule:t,renderModule:r,loaderTimeout:i}){e.all("/api/*",async o=>{try{return await t.handleApiRequest(o.req.url,o.req.raw)}catch(a){return console.error(a),o.json({error:"internal error"},500)}}),e.get("/_data/*",async o=>{try{let{pathname:a,search:m}=new URL(o.req.url,"http://localhost"),h=a.replace(/^\/_data/,"")+m,g=await r.runLoader(h,o.req.raw,{loaderTimeout:i});return g.error?o.json({error:"internal error"},500):o.json(g)}catch(a){return console.error(a),o.json({error:"internal error"},500)}})}function Se(e,{renderModule:t,manifest:r,loaderTimeout:i}){e.get("*",async o=>{try{let{html:a,statusCode:m,headers:h}=await t.render(o.req.url,o.req.raw,{manifest:r,loaderTimeout:i}),g=o.html(`<!DOCTYPE html>${a}`,m);for(let[n,l]of Object.entries(h))g.headers.set(n,l);return g}catch(a){return console.error(a),o.text("Internal Server Error",500)}})}var Te=s(()=>{"use strict"});import{loadEnv as mt}from"vite";function $e(e){let t=mt(e,process.cwd(),"");for(let[r,i]of Object.entries(t))process.env[r]===void 0&&(process.env[r]=i)}var be=s(()=>{"use strict"});var wt={};import{readFileSync as De}from"node:fs";import{serve as ft}from"@hono/node-server";import{serveStatic as gt}from"@hono/node-server/serve-static";import{Hono as ht}from"hono";import{resolve as _,join as xt}from"node:path";var B,W,J,f,vt,yt,E,Rt,Ce=s(async()=>{"use strict";Te();be();$e("production");try{f=JSON.parse(De(_(process.cwd(),"dist/devix.config.json"),"utf-8")),f.output!=="static"&&(B=await import(_(process.cwd(),"dist/server/render.js")),W=await import(_(process.cwd(),"dist/server/api.js"))),J=JSON.parse(De(_(process.cwd(),"dist/client/.vite/manifest.json"),"utf-8"))}catch{console.error('[devix] Build not found. Run "devix build" first.'),process.exit(1)}vt=Number(process.env.PORT)||f.port||3e3,yt=typeof f.host=="string"?f.host:f.host?"0.0.0.0":process.env.HOST||"0.0.0.0",E=new ht,Rt=xt(process.cwd(),"dist/client");E.use("/*",gt({root:Rt,onFound:(e,t)=>{t.header("Cache-Control",e.includes("/assets/")?"public, immutable, max-age=31536000":"no-cache")}}));f.output==="static"?console.log("[devix] Static mode \u2014 serving pre-generated files from dist/client"):(Pe(E,{renderModule:B,apiModule:W,manifest:J}),Se(E,{renderModule:B,apiModule:W,manifest:J,loaderTimeout:f.loaderTimeout}));ft({fetch:E.fetch,port:vt,hostname:yt},e=>console.log(`http://${e.address}:${e.port}`))});var Ae=process.argv[2];switch(Ae){case"dev":await Promise.resolve().then(()=>(X(),je));break;case"build":await q().then(()=>Re);break;case"generate":await Ee().then(()=>dt);break;case"start":await Ce().then(()=>wt);break;case"--version":case"-v":{console.log("0.4.1-beta.5");break}case"--help":case"-h":console.log(`
|
|
162
162
|
devix \u2014 a lightweight SSR framework
|
|
163
163
|
|
|
164
164
|
Usage:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { UserConfig } from "vite";
|
|
2
|
+
export interface DevixConfig {
|
|
3
|
+
port?: number;
|
|
4
|
+
host?: string | boolean;
|
|
5
|
+
css?: string[];
|
|
6
|
+
appDir?: string;
|
|
7
|
+
publicDir?: string;
|
|
8
|
+
envPrefix?: string | string[];
|
|
9
|
+
html?: {
|
|
10
|
+
lang?: string;
|
|
11
|
+
};
|
|
12
|
+
vite?: UserConfig;
|
|
13
|
+
loaderTimeout?: number | string;
|
|
14
|
+
output?: 'server' | 'static';
|
|
15
|
+
}
|
|
16
|
+
export interface ResolvedDirs {
|
|
17
|
+
appDir: string;
|
|
18
|
+
pagesDir: string;
|
|
19
|
+
apiDir: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function defineConfig(config: DevixConfig): DevixConfig;
|
|
22
|
+
export declare function resolveDirs(config: DevixConfig): ResolvedDirs;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DevixHandler } from './create-handler';
|
|
2
|
+
export declare class RouteContext {
|
|
3
|
+
readonly params: Record<string, string>;
|
|
4
|
+
private _state;
|
|
5
|
+
constructor(params?: Record<string, string>);
|
|
6
|
+
set<T>(key: string, value: T): void;
|
|
7
|
+
get<T>(key: string): T | undefined;
|
|
8
|
+
}
|
|
9
|
+
export type RouteResult = Response | Record<string, unknown> | unknown[] | null | void;
|
|
10
|
+
export type RouteHandler = (ctx: RouteContext, req: Request) => Promise<RouteResult> | RouteResult;
|
|
11
|
+
export interface MiddlewareModule {
|
|
12
|
+
middleware: (ctx: RouteContext, req: Request) => Promise<Response | null> | Response | null;
|
|
13
|
+
}
|
|
14
|
+
type AnyHandler = RouteHandler | DevixHandler<any, any>;
|
|
15
|
+
export interface RouteModule {
|
|
16
|
+
GET?: AnyHandler;
|
|
17
|
+
POST?: AnyHandler;
|
|
18
|
+
PUT?: AnyHandler;
|
|
19
|
+
PATCH?: AnyHandler;
|
|
20
|
+
DELETE?: AnyHandler;
|
|
21
|
+
HEAD?: AnyHandler;
|
|
22
|
+
OPTIONS?: AnyHandler;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ComponentType } from "react";
|
|
2
|
+
export interface ClientMatch {
|
|
3
|
+
load: () => Promise<{
|
|
4
|
+
default: ComponentType<any>;
|
|
5
|
+
}>;
|
|
6
|
+
loadLayouts: Array<() => Promise<{
|
|
7
|
+
default: ComponentType<any>;
|
|
8
|
+
}>>;
|
|
9
|
+
params: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
type GlobMap = Record<string, () => Promise<any>>;
|
|
12
|
+
export declare function createMatcher(pageFiles: GlobMap, layoutFiles: GlobMap): (pathname: string) => ClientMatch | null;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Context, ComponentType } from "react";
|
|
2
|
+
import { Metadata, Viewport } from "../types";
|
|
3
|
+
import { LayoutProps, PageProps } from "../server/types";
|
|
4
|
+
export interface NavigateOptions {
|
|
5
|
+
replace?: boolean;
|
|
6
|
+
viewTransition?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface RouterContextValue {
|
|
9
|
+
pathname: string;
|
|
10
|
+
params: Record<string, string>;
|
|
11
|
+
loaderData: unknown;
|
|
12
|
+
layoutsData: unknown[];
|
|
13
|
+
Page: ComponentType<PageProps>;
|
|
14
|
+
layouts: ComponentType<LayoutProps>[];
|
|
15
|
+
metadata: Metadata | null;
|
|
16
|
+
viewport?: Viewport;
|
|
17
|
+
navigate: (to: string, options?: NavigateOptions) => Promise<void>;
|
|
18
|
+
revalidate: () => Promise<void>;
|
|
19
|
+
isNavigating: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface PageMetaContextValue {
|
|
22
|
+
metadata: Metadata | null;
|
|
23
|
+
viewport?: Viewport;
|
|
24
|
+
clientEntry?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface RouteDataContextValue {
|
|
27
|
+
loaderData: unknown;
|
|
28
|
+
params: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export declare const RouterContext: Context<RouterContextValue | null>;
|
|
31
|
+
export declare const PageMetaContext: Context<PageMetaContextValue | null>;
|
|
32
|
+
export declare const RouteDataContext: Context<RouteDataContextValue | null>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const HANDLER_BRAND: "__devix_handler__";
|
|
2
|
+
export interface DevixHandler<TBody = undefined, TReturn = unknown> {
|
|
3
|
+
readonly [HANDLER_BRAND]: true;
|
|
4
|
+
readonly fn: (...args: any[]) => any;
|
|
5
|
+
readonly __body: TBody;
|
|
6
|
+
readonly __return: TReturn;
|
|
7
|
+
}
|
|
8
|
+
type ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined;
|
|
9
|
+
export declare function createHandler<TFn extends (...args: any[]) => any>(fn: TFn): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Component, ComponentType, ReactNode } from "react";
|
|
2
|
+
import { ErrorProps } from "../server/types";
|
|
3
|
+
interface Props {
|
|
4
|
+
ErrorPage?: ComponentType<ErrorProps>;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
interface State {
|
|
8
|
+
error: ErrorProps | null;
|
|
9
|
+
}
|
|
10
|
+
export declare class DevixErrorBoundary extends Component<Props, State> {
|
|
11
|
+
state: State;
|
|
12
|
+
static getDerivedStateFromError(err: unknown): State;
|
|
13
|
+
render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
14
|
+
}
|
|
15
|
+
export declare class DevixError extends Error {
|
|
16
|
+
statusCode: number;
|
|
17
|
+
constructor(statusCode: number, message: string);
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface ApiRoutes {
|
|
2
|
+
}
|
|
3
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
4
|
+
type ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`;
|
|
5
|
+
type RouteData<M extends HttpMethod, P extends string> = ApiKey<M, P> extends keyof ApiRoutes ? ApiRoutes[ApiKey<M, P>] : unknown;
|
|
6
|
+
type AllApiPaths = {
|
|
7
|
+
[K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never;
|
|
8
|
+
}[keyof ApiRoutes];
|
|
9
|
+
type ApiPath = [AllApiPaths] extends [never] ? string : AllApiPaths | (string & {});
|
|
10
|
+
type ExtractBody<D> = D extends {
|
|
11
|
+
__body: infer B;
|
|
12
|
+
} ? B : never;
|
|
13
|
+
type UnwrapReturn<R> = R extends {
|
|
14
|
+
__body: infer B;
|
|
15
|
+
} ? B : R extends void | undefined ? never : R;
|
|
16
|
+
type ExtractResponse<D> = D extends {
|
|
17
|
+
__return: infer R;
|
|
18
|
+
} ? UnwrapReturn<R> : D extends {
|
|
19
|
+
__response: infer R;
|
|
20
|
+
} ? R : D;
|
|
21
|
+
type InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>;
|
|
22
|
+
type InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>;
|
|
23
|
+
type BodyOption<M extends HttpMethod, P extends string> = [
|
|
24
|
+
InferBody<M, P>
|
|
25
|
+
] extends [never] ? unknown : InferBody<M, P>;
|
|
26
|
+
export interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {
|
|
27
|
+
method?: M;
|
|
28
|
+
body?: BodyOption<M, P>;
|
|
29
|
+
headers?: HeadersInit;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
export declare class FetchError extends Error {
|
|
33
|
+
readonly status: number;
|
|
34
|
+
readonly statusText: string;
|
|
35
|
+
readonly response: Response;
|
|
36
|
+
constructor(status: number, statusText: string, response: Response);
|
|
37
|
+
}
|
|
38
|
+
export declare function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(path: P, options?: FetchOptions<M, P>): Promise<InferResult<M, P>>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Metadata, Viewport } from "../types";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
export declare function HeadSlot({ metadata, viewport }: {
|
|
4
|
+
metadata: Metadata | null;
|
|
5
|
+
viewport?: Viewport;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
export declare function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { useRouter, useNavigate, useRevalidate, useParams, useLoaderData, RouterProvider } from "./router-provider";
|
|
2
|
+
export { Link } from "./link";
|
|
3
|
+
export type { Metadata, Viewport, LoaderContext, LoaderContextWithGuard, LoaderFunction, GuardFunction } from '../types';
|
|
4
|
+
export type { NavigateOptions } from './context';
|
|
5
|
+
export type { PageProps, LayoutProps, PageModule, LayoutModule, ErrorProps } from '../server/types';
|
|
6
|
+
export type { RouteHandler, RouteResult } from './api-context';
|
|
7
|
+
export { getCookie, setCookie, deleteCookie } from '../utils/cookies';
|
|
8
|
+
export type { CookieOptions } from '../utils/cookies';
|
|
9
|
+
export { json, text, redirect } from '../utils/response';
|
|
10
|
+
export type { JsonResponse, Redirect, RedirectOptions } from '../utils/response';
|
|
11
|
+
export { $fetch, FetchError } from './fetch';
|
|
12
|
+
export type { ApiRoutes, FetchOptions } from './fetch';
|
|
13
|
+
export { createHandler } from './create-handler';
|
|
14
|
+
export type { DevixHandler } from './create-handler';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnchorHTMLAttributes } from "react";
|
|
2
|
+
interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
3
|
+
href: string;
|
|
4
|
+
prefetch?: boolean;
|
|
5
|
+
viewTransition?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function Link({ href, prefetch, viewTransition, children, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LayoutModule, PageModule } from "../server";
|
|
2
|
+
import { LoaderContext, Metadata, Viewport } from "../types";
|
|
3
|
+
export interface ResolvedMeta {
|
|
4
|
+
metadata: Metadata;
|
|
5
|
+
viewport?: Viewport;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveMetadata(module: PageModule | LayoutModule, ctx: LoaderContext & {
|
|
8
|
+
loaderData: unknown;
|
|
9
|
+
}): Promise<ResolvedMeta>;
|
|
10
|
+
export declare function mergeMetadata(...sources: (Metadata | null | undefined)[]): Metadata;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ComponentType } from "react";
|
|
2
|
+
import { ErrorProps, LayoutProps, PageProps } from "../server/types";
|
|
3
|
+
import { Metadata, Viewport } from "../types";
|
|
4
|
+
import { NavigateOptions } from "./context";
|
|
5
|
+
import type { Redirect } from "../utils/response";
|
|
6
|
+
export declare function useRouter(): import("virtual:devix/context").RouterContextValue | null;
|
|
7
|
+
export declare function useNavigate(): (to: string, options?: NavigateOptions) => Promise<void>;
|
|
8
|
+
export declare function useRevalidate(): () => Promise<void>;
|
|
9
|
+
export declare function useParams<T extends Record<string, string>>(): T;
|
|
10
|
+
type LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R> ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined> : T extends (...args: any[]) => infer R ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined> : T;
|
|
11
|
+
export declare function useLoaderData<T>(): LoaderReturnType<T>;
|
|
12
|
+
interface RouterProviderProps {
|
|
13
|
+
initialData: unknown;
|
|
14
|
+
initialParams: Record<string, string>;
|
|
15
|
+
initialPage: ComponentType<PageProps>;
|
|
16
|
+
initialLayouts?: ComponentType<LayoutProps>[];
|
|
17
|
+
initialLayoutsData?: unknown[];
|
|
18
|
+
initialMeta?: Metadata | null;
|
|
19
|
+
initialViewport?: Viewport;
|
|
20
|
+
initialError?: ErrorProps;
|
|
21
|
+
initialErrorPage?: ComponentType<ErrorProps>;
|
|
22
|
+
clientEntry: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function RouterProvider({ initialData, initialParams, initialPage, initialLayouts, initialLayoutsData, initialMeta, initialViewport, initialError, initialErrorPage, clientEntry, }: RouterProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { LayoutProps, PageProps } from '../server/types';
|
|
3
|
+
import { Metadata, Viewport } from '../types';
|
|
4
|
+
export interface ServerAppProps {
|
|
5
|
+
pathname: string;
|
|
6
|
+
params: Record<string, string>;
|
|
7
|
+
loaderData: unknown;
|
|
8
|
+
layoutsData: unknown[];
|
|
9
|
+
Page: ComponentType<PageProps>;
|
|
10
|
+
layouts: ComponentType<LayoutProps>[];
|
|
11
|
+
metadata: Metadata | null;
|
|
12
|
+
viewport?: Viewport;
|
|
13
|
+
clientEntry: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function ServerApp({ pathname, params, loaderData, layoutsData, Page, layouts, metadata, viewport, clientEntry, }: ServerAppProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ApiRoute {
|
|
2
|
+
path: string;
|
|
3
|
+
key: string;
|
|
4
|
+
params: string[];
|
|
5
|
+
regex: RegExp;
|
|
6
|
+
}
|
|
7
|
+
export interface ApiMiddleware {
|
|
8
|
+
dir: string;
|
|
9
|
+
key: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ApiResult {
|
|
12
|
+
routes: ApiRoute[];
|
|
13
|
+
middlewares: ApiMiddleware[];
|
|
14
|
+
}
|
|
15
|
+
export declare function keyToRoutePattern(key: string, apiDir: string): string;
|
|
16
|
+
export declare function invalidateApiCache(): void;
|
|
17
|
+
export declare function buildRoutes(routeKeys: string[], middlewareKeys: string[], apiDir: string): ApiResult;
|
|
18
|
+
export declare function collectMiddlewareChain(routeKey: string, middlewares: ApiMiddleware[]): ApiMiddleware[];
|
|
19
|
+
export declare function matchRoute(pathname: string, routes: ApiRoute[]): {
|
|
20
|
+
route: ApiRoute;
|
|
21
|
+
params: Record<string, string>;
|
|
22
|
+
} | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RouteContext } from '../runtime/api-context';
|
|
2
|
+
interface HandlerStore {
|
|
3
|
+
request: Request;
|
|
4
|
+
ctx: RouteContext;
|
|
5
|
+
}
|
|
6
|
+
export declare function withHandlerStore<T>(store: HandlerStore, fn: () => T): T;
|
|
7
|
+
export declare function useRequest(): Request;
|
|
8
|
+
export declare function useCtx(): RouteContext;
|
|
9
|
+
export declare function useParams(): Record<string, string>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { buildPages, collectLayoutChain, matchPage } from './pages-router';
|
|
2
|
+
export { buildRoutes, collectMiddlewareChain, matchRoute } from './api-router';
|
|
3
|
+
export { resolveMetadata, mergeMetadata } from '../runtime/metadata';
|
|
4
|
+
export type { Page, Layout, PagesResult } from './pages-router';
|
|
5
|
+
export type { ApiRoute, ApiMiddleware, ApiResult } from './api-router';
|
|
6
|
+
export type { PageModule, LayoutModule } from './types';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface Page {
|
|
2
|
+
path: string;
|
|
3
|
+
key: string;
|
|
4
|
+
params: string[];
|
|
5
|
+
regex: RegExp;
|
|
6
|
+
}
|
|
7
|
+
export interface Layout {
|
|
8
|
+
dir: string;
|
|
9
|
+
key: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PagesResult {
|
|
12
|
+
pages: Page[];
|
|
13
|
+
layouts: Layout[];
|
|
14
|
+
}
|
|
15
|
+
export declare function invalidatePagesCache(): void;
|
|
16
|
+
export declare function buildPages(pageKeys: string[], layoutKeys: string[], pagesDir: string): PagesResult;
|
|
17
|
+
export declare function collectLayoutChain(pageKey: string, layouts: Layout[]): Layout[];
|
|
18
|
+
export declare function matchPage(pathname: string, pages: Page[]): {
|
|
19
|
+
page: Page;
|
|
20
|
+
params: Record<string, string>;
|
|
21
|
+
} | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useRequest, useCtx, useParams } from './handler-store';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { PageGlob } from './types';
|
|
2
|
+
import type { Manifest } from "vite";
|
|
3
|
+
export declare function runLoader(url: string, request: Request, glob: PageGlob, options?: {
|
|
4
|
+
loaderTimeout?: number;
|
|
5
|
+
}): Promise<{
|
|
6
|
+
error: true;
|
|
7
|
+
loaderData: null;
|
|
8
|
+
params: {};
|
|
9
|
+
layouts: never[];
|
|
10
|
+
metadata: null;
|
|
11
|
+
viewport: undefined;
|
|
12
|
+
redirect?: undefined;
|
|
13
|
+
redirectStatus?: undefined;
|
|
14
|
+
redirectReplace?: undefined;
|
|
15
|
+
} | {
|
|
16
|
+
loaderData: null;
|
|
17
|
+
params: {};
|
|
18
|
+
layouts: never[];
|
|
19
|
+
metadata: null;
|
|
20
|
+
viewport: undefined;
|
|
21
|
+
error?: undefined;
|
|
22
|
+
redirect?: undefined;
|
|
23
|
+
redirectStatus?: undefined;
|
|
24
|
+
redirectReplace?: undefined;
|
|
25
|
+
} | {
|
|
26
|
+
redirect: string | undefined;
|
|
27
|
+
redirectStatus: number | undefined;
|
|
28
|
+
redirectReplace: boolean | undefined;
|
|
29
|
+
error?: undefined;
|
|
30
|
+
loaderData?: undefined;
|
|
31
|
+
params?: undefined;
|
|
32
|
+
layouts?: undefined;
|
|
33
|
+
metadata?: undefined;
|
|
34
|
+
viewport?: undefined;
|
|
35
|
+
} | {
|
|
36
|
+
loaderData: unknown;
|
|
37
|
+
params: Record<string, string>;
|
|
38
|
+
layouts: {
|
|
39
|
+
loaderData: unknown;
|
|
40
|
+
}[];
|
|
41
|
+
metadata: import("../types").Metadata;
|
|
42
|
+
viewport: import("../types").Viewport | undefined;
|
|
43
|
+
error?: undefined;
|
|
44
|
+
redirect?: undefined;
|
|
45
|
+
redirectStatus?: undefined;
|
|
46
|
+
redirectReplace?: undefined;
|
|
47
|
+
}>;
|
|
48
|
+
export declare function render(url: string, request: Request, glob: PageGlob, options?: {
|
|
49
|
+
manifest?: Manifest;
|
|
50
|
+
loaderTimeout?: number;
|
|
51
|
+
}): Promise<{
|
|
52
|
+
html: string;
|
|
53
|
+
statusCode: number | undefined;
|
|
54
|
+
headers: {
|
|
55
|
+
Location: string | undefined;
|
|
56
|
+
};
|
|
57
|
+
} | {
|
|
58
|
+
html: string;
|
|
59
|
+
statusCode: number;
|
|
60
|
+
headers: Record<string, string>;
|
|
61
|
+
}>;
|
|
62
|
+
export declare function getStaticRoutes(glob: PageGlob): Promise<string[]>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Hono } from 'hono';
|
|
2
|
+
import type { Manifest } from 'vite';
|
|
3
|
+
interface ServerOptions {
|
|
4
|
+
renderModule: any;
|
|
5
|
+
apiModule: any;
|
|
6
|
+
manifest?: Manifest;
|
|
7
|
+
loaderTimeout?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function registerApiRoutes(app: Hono, { apiModule, renderModule, loaderTimeout }: ServerOptions): void;
|
|
10
|
+
export declare function registerSsrRoute(app: Hono, { renderModule, manifest, loaderTimeout }: ServerOptions): void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { LoaderContext, Metadata, Viewport } from "../types";
|
|
3
|
+
import type { Redirect } from "../utils/response";
|
|
4
|
+
type InferLoaderData<T> = T extends (...args: any[]) => infer R ? [Awaited<R>] extends [void | undefined | Redirect] ? undefined : Exclude<Awaited<R>, Redirect> : T;
|
|
5
|
+
type IsParams<T> = [T] extends [Record<string, string>] ? true : false;
|
|
6
|
+
export interface PageProps<TDataOrParams = unknown, TParams = Record<string, string>> {
|
|
7
|
+
data: IsParams<TDataOrParams> extends true ? unknown : InferLoaderData<TDataOrParams>;
|
|
8
|
+
params: IsParams<TDataOrParams> extends true ? TDataOrParams extends Record<string, string> ? TDataOrParams : Record<string, string> : TParams;
|
|
9
|
+
url: string;
|
|
10
|
+
}
|
|
11
|
+
export interface LayoutProps<TDataOrParams = unknown, TParams = Record<string, string>> {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
data: IsParams<TDataOrParams> extends true ? unknown : InferLoaderData<TDataOrParams>;
|
|
14
|
+
params: IsParams<TDataOrParams> extends true ? TDataOrParams extends Record<string, string> ? TDataOrParams : Record<string, string> : TParams;
|
|
15
|
+
}
|
|
16
|
+
export interface ErrorProps {
|
|
17
|
+
statusCode: number;
|
|
18
|
+
message?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface PageGlob {
|
|
21
|
+
pages: Record<string, () => Promise<unknown>>;
|
|
22
|
+
layouts: Record<string, () => Promise<unknown>>;
|
|
23
|
+
pagesDir: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ApiGlob {
|
|
26
|
+
routes: Record<string, () => Promise<unknown>>;
|
|
27
|
+
middlewares: Record<string, () => Promise<unknown>>;
|
|
28
|
+
apiDir: string;
|
|
29
|
+
}
|
|
30
|
+
interface BaseModule<TData, TParams> {
|
|
31
|
+
loader?: (ctx: LoaderContext<TParams>) => Promise<TData | Redirect | void> | TData | Redirect | void;
|
|
32
|
+
guard?: (ctx: LoaderContext<TParams>) => Promise<string | Redirect | Record<string, unknown> | null> | string | Redirect | Record<string, unknown> | null;
|
|
33
|
+
metadata?: Metadata;
|
|
34
|
+
generateMetadata?: (ctx: LoaderContext<TParams> & {
|
|
35
|
+
loaderData: TData;
|
|
36
|
+
}) => Promise<Metadata> | Metadata;
|
|
37
|
+
viewport?: Viewport;
|
|
38
|
+
generateViewport?: (ctx: LoaderContext<TParams>) => Promise<Viewport> | Viewport;
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
export interface PageModule<TData = unknown, TParams = Record<string, string>> extends BaseModule<TData, TParams> {
|
|
42
|
+
default: React.ComponentType<PageProps<TData, TParams>>;
|
|
43
|
+
generateStaticParams?: () => Promise<Record<string, string>[]> | Record<string, string>[];
|
|
44
|
+
}
|
|
45
|
+
export interface LayoutModule<TData = unknown, TParams = Record<string, string>> extends BaseModule<TData, TParams> {
|
|
46
|
+
default: React.ComponentType<LayoutProps<TData, TParams>>;
|
|
47
|
+
lang?: string;
|
|
48
|
+
generateLang?: (ctx: LoaderContext<TParams> & {
|
|
49
|
+
loaderData: TData;
|
|
50
|
+
}) => Promise<string> | string;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface Metadata {
|
|
2
|
+
title?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
keywords?: string[];
|
|
5
|
+
og?: {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
image?: string;
|
|
9
|
+
type?: 'website' | 'article' | 'product';
|
|
10
|
+
url?: string;
|
|
11
|
+
};
|
|
12
|
+
twitter?: {
|
|
13
|
+
card?: 'summary' | 'summary_large_image';
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
image?: string;
|
|
17
|
+
creator?: string;
|
|
18
|
+
};
|
|
19
|
+
canonical?: string;
|
|
20
|
+
robots?: string;
|
|
21
|
+
alternates?: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
export interface Viewport {
|
|
24
|
+
width?: string | number;
|
|
25
|
+
initialScale?: number;
|
|
26
|
+
maximumScale?: number;
|
|
27
|
+
userScalable?: boolean;
|
|
28
|
+
themeColor?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface LoaderContext<TParams = Record<string, string>> {
|
|
31
|
+
params: TParams;
|
|
32
|
+
request: Request;
|
|
33
|
+
guardData: unknown;
|
|
34
|
+
}
|
|
35
|
+
import type { Redirect } from './utils/response';
|
|
36
|
+
export type LoaderFunction<TData = unknown, TParams = Record<string, string>> = (ctx: LoaderContext<TParams>) => Promise<TData | Redirect | void> | TData | Redirect | void;
|
|
37
|
+
export type GuardFunction<TParams = Record<string, string>> = (ctx: LoaderContext<TParams>) => Promise<string | Redirect | Record<string, unknown> | null> | string | Redirect | Record<string, unknown> | null;
|
|
38
|
+
type GuardData<TGuard> = TGuard extends (...args: any[]) => infer R ? Exclude<Awaited<R>, string | Redirect | null | undefined> : unknown;
|
|
39
|
+
export type LoaderContextWithGuard<TGuard extends GuardFunction | undefined = undefined, TParams = Record<string, string>> = LoaderContext<TParams> & {
|
|
40
|
+
guardData: GuardData<TGuard>;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function printDevBanner(port: number): void;
|
package/dist/utils/banner.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.
|
|
1
|
+
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.5",n=s(e);console.log(),console.log(` ${o.bold(o.yellow("devix"))} ${o.dim(`v${l}`)}`),console.log(),console.log(` ${o.green("\u279C")} ${o.bold("Local:")} ${o.cyan(`http://localhost:${e}/`)}`),console.log(n?` ${o.green("\u279C")} ${o.bold("Network:")} ${o.cyan(n)}`:` ${o.green("\u279C")} ${o.bold("Network:")} ${o.dim("use --host to expose")}`),console.log()}export{$ as printDevBanner};
|
|
2
2
|
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CookieOptions {
|
|
2
|
+
httpOnly?: boolean;
|
|
3
|
+
secure?: boolean;
|
|
4
|
+
sameSite?: 'Strict' | 'Lax' | 'None';
|
|
5
|
+
maxAge?: number;
|
|
6
|
+
expires?: Date;
|
|
7
|
+
path?: string;
|
|
8
|
+
domain?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getCookie(req: Request, name: string): string | undefined;
|
|
11
|
+
export declare function setCookie(headers: Headers, name: string, value: string, options?: CookieOptions): void;
|
|
12
|
+
export declare function deleteCookie(headers: Headers, name: string, options?: Pick<CookieOptions, 'path' | 'domain'>): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseDuration(value: number | string): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function loadDotenv(mode: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function routePattern(rel: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type JsonResponse<T = unknown> = Response & {
|
|
2
|
+
readonly __body: T;
|
|
3
|
+
};
|
|
4
|
+
export declare const json: <const T>(data: T, status?: number) => JsonResponse<T>;
|
|
5
|
+
export declare const text: (body: string, status?: number) => Response;
|
|
6
|
+
declare const REDIRECT_BRAND: unique symbol;
|
|
7
|
+
export interface RedirectOptions {
|
|
8
|
+
status?: number;
|
|
9
|
+
replace?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface Redirect {
|
|
12
|
+
readonly [REDIRECT_BRAND]: true;
|
|
13
|
+
readonly url: string;
|
|
14
|
+
readonly status: number;
|
|
15
|
+
readonly replace: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect;
|
|
18
|
+
export declare function isRedirect(value: unknown): value is Redirect;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateContext(): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HttpMethod } from './extract-methods';
|
|
2
|
+
export interface RouteEntry {
|
|
3
|
+
filePath: string;
|
|
4
|
+
urlPattern: string;
|
|
5
|
+
identifier: string;
|
|
6
|
+
methods: HttpMethod[];
|
|
7
|
+
}
|
|
8
|
+
export declare function filePathToIdentifier(filePath: string, apiDir: string): string;
|
|
9
|
+
export declare function buildRouteEntry(filePath: string, apiDir: string, methods: HttpMethod[]): RouteEntry;
|
|
10
|
+
export declare function generateRoutesDts(entries: RouteEntry[], apiDir: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function writeRoutesDts(content: string, projectRoot: string): boolean;
|