primdy 0.1.2 → 0.1.3

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.
@@ -33,6 +33,6 @@ Expecting one of '${n.join("', '")}'`);let r=`${e}Help`;return this.on(r,(i)=>{l
33
33
  `;await Rt(ke(n,"routes.d.ts"),i)}async function Me(e,t){let n=await B(O(e,t)),r=await L(O(e,t)),i=await U(O(e,t)),o=await q(O(e,t)),s=O(e,".primdy");await kt(s,{recursive:!0,force:!0}),await Pt(s,{recursive:!0});let a=O(s,"routes"),c=[];for(let[f,p]of n.entries())c.push({...p,file:await Be(p.file,O(a,String(f)))});let l=await oe(r,O(s,"middleware")),u=await oe(i,O(s,"not-found")),h=await oe(o,O(s,"error"));return await Pe(e,c,l,u,h),await Fe(e,n),{routes:c,middleware:l,notFound:u,error:h}}async function oe(e,t){let n=[];for(let[r,i]of e.entries())n.push({...i,file:await Be(i.file,O(t,String(r)))});return n}async function Be(e,t){if((await Bt({entryPoints:[e],outdir:t,bundle:!0,platform:"node",format:"esm",sourcemap:"external",logLevel:"silent"})).errors.length)throw Error(`Failed to build ${e}`);let r=O(t,Mt(e).replace(/\.(ts|js)$/,".js"));return await Ht(`${r}.map`),r}async function Ht(e){let t=await Nt(e,"utf8");await Ft(e,JSON.stringify(JSON.parse(t)))}import{access as It}from"fs/promises";import{join as Vt}from"path";async function jt(e){for(let t of["primdy.config.ts","primdy.config.js","primdy.config.mjs"]){let n=Vt(e,t);try{return await It(n),n}catch{continue}}return null}async function se(e,t={}){let n=await jt(e),i=(n?await import(n).catch(()=>({default:{}})):{default:{}}).default??{};for(let[o,s]of Object.entries(t))if(s!==void 0)i[o]=s;return i}var y={success:(e)=>console.log(`${_.bold.green("\u2713")} ${e}`),info:(e)=>console.log(`${_.bold.cyan("\u2139")} ${e}`),warn:(e)=>console.log(`${_.bold.yellow("\u26A0")} ${e}`),err:(e)=>console.log(`${_.bold.red("\u2717")} ${e}`)},ae=(e)=>{y.success(`Ready in ${Math.round(performance.now()-e)}ms`)};import{createServer as Wt}from"http";import{Readable as qe}from"stream";function Ie(e,t){let n=t.split("/").filter(Boolean);for(let r of e){let i={},o=0,s=!0;for(let a of r.segments){if(a.type==="static"){if(n[o]!==a.value){s=!1;break}o++;continue}if(a.type==="dynamic"){let l=Ve(n[o]);if(l===null){s=!1;break}i[a.name]=l,o++;continue}if(a.type==="catchAll"){if(o>=n.length){s=!1;break}let l=He(n.slice(o));if(l===null){s=!1;break}i[a.name]=l,o=n.length;continue}let c=He(n.slice(o));if(c===null){s=!1;break}i[a.name]=c,o=n.length}if(s&&o===n.length)return{route:r,params:i}}return null}function Ve(e){try{return decodeURIComponent(e)}catch{return null}}function He(e){let t=[];for(let n of e){let r=Ve(n);if(r===null)return null;t.push(r)}return t}function je(e,t){return e.filter((n)=>n.dir===""||t.dir===n.dir||t.dir.startsWith(`${n.dir}/`))}function le(e,t){let n=null;for(let r of e){if(!(r.dir===""||r.dir===t||t.startsWith(`${r.dir}/`)))continue;if(!n||r.dir.length>n.dir.length)n=r}return n}var De=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];async function Ge(e,t,n=[],r=[],i=[]){let o=new URL(e.url),s=Ie(t,o.pathname);if(!s)return Dt(e,r,o.pathname);try{for(let u of je(n,s.route)){let h=await import(u.file),f=h.default??h.middleware??h.proxy;if(typeof f!=="function")continue;let p=await f(e,{params:s.params});if(p)return p}let a=e.method;if(!De.includes(a))return new Response("Method Not Allowed",{status:405,headers:{Allow:s.route.methods.join(", ")}});let c=await import(s.route.file),l=c[a];if(typeof l!=="function"){let u=De.filter((h)=>typeof c[h]==="function");if(!u.length)return new Response("Method Not Allowed",{status:405});return new Response("Method Not Allowed",{status:405,headers:{Allow:u.join(", ")}})}return await l(e,{params:s.params})}catch(a){return Gt(e,a,i,s.route.dir)}}async function Dt(e,t,n){let r=le(t,n.replace(/^\/+/,""));if(r)try{let i=await import(r.file),o=i.default??i.notFound;if(typeof o==="function"){let s=await o(e,{params:{}});if(s)return s}}catch(i){console.error(i)}return new Response("Not Found",{status:404})}async function Gt(e,t,n,r){console.error(t);let i=le(n,r);if(i)try{let o=await import(i.file),s=o.default??o.error;if(typeof s==="function"){let a=await s(e,t);if(a)return a}}catch(o){console.error(o)}return new Response("Internal Server Error",{status:500})}function ue(e,t,n,r){let i=performance.now()-r,o=_.dim(e.method),s=_.white(t),a=n>=500?_.red(n):n>=400?_.yellow(n):n>=300?_.cyan(n):_.green(n),c=i<1?_.dim(`${i.toFixed(2)}ms`):i>=100?_.yellow(`${Math.round(i)}ms`):_.dim(`${Math.round(i)}ms`);console.log(`${o} ${s} ${a} took ${c}`)}var Lt=typeof Bun<"u";function Ut(e,t){let n=new Headers;for(let i in e.headers){let o=e.headers[i];if(o===void 0)continue;n.set(i,Array.isArray(o)?o.join(", "):o)}let r=e.method!=="GET"&&e.method!=="HEAD";return new Request(`http://${e.headers.host??t}${e.url??"/"}`,{method:e.method,headers:n,body:r?qe.toWeb(e):void 0,duplex:r?"half":void 0})}function We(e){return e?.code==="EADDRINUSE"}function Le(e,t){let n=e?.code;if(n==="EADDRINUSE")return`Port ${t.port} is already in use`;if(n==="EACCES")return`Permission denied to listen on port ${t.port}`;return e instanceof Error?e.message:String(e)}function Ue(e){let t=!1,n=()=>{if(t)return;t=!0;try{e()}finally{process.exit(0)}};process.on("SIGINT",n),process.on("SIGTERM",n)}function ce(e,t,n=[],r=[],i=[]){let o=Lt&&!t.forceNode;async function s(h){let f=performance.now(),p=new URL(h.url);try{let C=await Ge(h,e,n,r,i);return ue(h,p.pathname,C.status,f),C}catch(C){console.error(C);let R=new Response("Internal Server Error",{status:500});return ue(h,p.pathname,R.status,f),R}}if(o){let h=t.port;for(let f=0;f<=5;f++)try{let p=Bun.serve({hostname:t.hostname,port:h,fetch:s});return console.log(`${_.bold.cyanBright("\u25C6 Primdy Server")}
34
34
  - Local: ${p.url}`),Ue(()=>p.stop(!0)),p}catch(p){if(!We(p)||f===5)y.err(Le(p,{...t,port:h})),process.exit(1);let C=h+1;y.warn(`Port ${h} is in use, using ${C} instead`),h=C}}let a=Wt(async(h,f)=>{let p=await s(Ut(h,t.hostname));f.statusCode=p.status;for(let[R,Xe]of p.headers)if(R.toLowerCase()!=="set-cookie")f.setHeader(R,Xe);let C=p.headers.getSetCookie?.();if(C?.length)f.setHeader("set-cookie",C);if(p.body)qe.fromWeb(p.body).pipe(f);else f.end()}),c=t.port,l=0,u=()=>{a.once("error",(h)=>{if(We(h)&&l<5){l++;let f=c+1;y.warn(`Port ${c} is in use, using ${f} instead`),c=f,u();return}y.err(Le(h,{...t,port:c})),process.exit(1)}),a.listen(c,t.hostname,()=>{console.log(`${_.bold.yellowBright("\u25C6 Primdy Server")}
35
35
  - Local: http://${t.hostname}:${c}/`),y.warn(`Primdy is optimized for Bun, and Node.js compatibility is slower
36
- Consider migrating your application: https://bun.sh/`)})};return u(),Ue(()=>{a.closeAllConnections?.(),a.close()}),a}import{stat as qt}from"fs/promises";function Yt(e){if(e<1024)return`${e} B`;return`${(e/1024).toFixed(1)} KB`}async function zt(e){return(await qt(e).catch(()=>({size:0}))).size}async function Ye(e){let t=e.filter((i)=>i.entries.length>0);if(!t.length)return;let n=await Promise.all(t.map((i)=>Promise.all(i.entries.slice().sort((o,s)=>o.label.localeCompare(s.label)).map(async(o)=>({label:o.label,size:await zt(o.file)}))))),r=Math.max(...n.flat().map((i)=>i.label.length));t.forEach((i,o)=>{let s=n[o];console.log(_.bold(i.title)),s.forEach((a,c)=>{let l=c===s.length-1?"\u2514\u2500":"\u251C\u2500",u=_.dim(Yt(a.size).padStart(8));console.log(`${l} ${a.label.padEnd(r+2)}${u}`)})})}var ze={name:"primdy",version:"0.1.2",description:"Blazingly fast, file-system routed API framework",license:"MIT",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"}},bin:{primdy:"dist/server/index.js"},files:["dist"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun run build",link:"bun run build && bun link && bun link primdy",test:"bun test"},dependencies:{chalk:"^6.0.0",commander:"^15.0.0",esbuild:"^0.28.2"},devDependencies:{"@types/bun":"^1.4.1",typescript:"^7.0.2"},engines:{bun:">=1.4.0"}};import{spawn as en}from"child_process";import{fileURLToPath as tn}from"url";async function Je(e,t=!1){if(process.title=e,!t||process.platform!=="linux")return;try{let{dlopen:n,FFIType:r,ptr:i}=await import("bun:ffi"),{symbols:o}=n("libc.so.6",{prctl:{args:[r.i32,r.ptr,r.u64,r.u64,r.u64],returns:r.i32}}),s=15;o.prctl(15,i(Buffer.from(`${e}\x00`)),0n,0n,0n)}catch{}}var Ke=typeof process<"u"&&!!process.versions?.bun;await Je("primdy-server",Ke);function nn(){return new Promise((e)=>{let t=tn(import.meta.url),n;try{n=en("bun",[t,...process.argv.slice(2)],{stdio:"inherit",env:process.env})}catch{e(null);return}let r=(o)=>{n.kill(o)};process.on("SIGINT",r),process.on("SIGTERM",r);let i=!1;n.once("error",()=>{i=!0,e(null)}),n.once("exit",(o,s)=>{if(process.off("SIGINT",r),process.off("SIGTERM",r),i)return;e(o??(s?1:0))})})}if(!Ke){if(!(process.argv.includes("--node")||process.argv.includes("-N")||await se(process.cwd()).then((n)=>n.node===!0).catch(()=>!1))){let n=await nn();if(n!==null)process.exit(n)}}process.on("uncaughtException",(e)=>{y.err(e instanceof Error?e.message:String(e)),process.exit(1)});process.on("unhandledRejection",(e)=>{y.err(e instanceof Error?e.message:String(e)),process.exit(1)});var S=new T;S.name("primdy").description("Blazingly fast, file-system routed API framework").version(ze.version).helpOption("-h, --help","Display help").helpCommand("help","Displays this message.");async function Y(e,t={}){let n=Zt(process.cwd(),e),r=await se(n,{port:Number(process.env.PORT)||void 0,hostname:process.env.HOSTNAME,...t}),i=r.src??"src",o=Xt(n,i),s=r.port??3000,a=r.hostname??"localhost";return{cwd:n,config:r,src:i,appPath:o,port:s,hostname:a}}function Qe(e){let t={};if(e.port!==void 0)t.port=Number(e.port);if(e.hostname!==void 0)t.hostname=e.hostname;if(e.node!==void 0)t.node=e.node;return t}async function rn(e){try{await Kt(e)}catch{return!1}return(await Qt(e,{recursive:!0,withFileTypes:!0}).catch(()=>[])).some((n)=>n.isFile()&&(n.name==="route.ts"||n.name==="route.js"))}async function he(e){if(await rn(e))return!0;return y.err(`No application found
36
+ Consider migrating your application: https://bun.sh/`)})};return u(),Ue(()=>{a.closeAllConnections?.(),a.close()}),a}import{stat as qt}from"fs/promises";function Yt(e){if(e<1024)return`${e} B`;return`${(e/1024).toFixed(1)} KB`}async function zt(e){return(await qt(e).catch(()=>({size:0}))).size}async function Ye(e){let t=e.filter((i)=>i.entries.length>0);if(!t.length)return;let n=await Promise.all(t.map((i)=>Promise.all(i.entries.slice().sort((o,s)=>o.label.localeCompare(s.label)).map(async(o)=>({label:o.label,size:await zt(o.file)}))))),r=Math.max(...n.flat().map((i)=>i.label.length));t.forEach((i,o)=>{let s=n[o];console.log(_.bold(i.title)),s.forEach((a,c)=>{let l=c===s.length-1?"\u2514\u2500":"\u251C\u2500",u=_.dim(Yt(a.size).padStart(8));console.log(`${l} ${a.label.padEnd(r+2)}${u}`)})})}var ze={name:"primdy",version:"0.1.3",description:"Blazingly fast, file-system routed API framework",license:"MIT",repository:{type:"git",url:"git+https://github.com/primdy/primdy.git"},bugs:{url:"https://github.com/primdy/primdy/issues"},homepage:"https://github.com/primdy/primdy",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"}},bin:{primdy:"dist/server/index.js"},files:["dist"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun run build",link:"bun run build && bun link && bun link primdy",test:"bun test"},dependencies:{esbuild:"^0.28.2"},devDependencies:{"@types/bun":"^1.4.1",chalk:"^6.0.0",commander:"^15.0.0",typescript:"^7.0.2"},engines:{bun:">=1.4.0"}};import{spawn as en}from"child_process";import{fileURLToPath as tn}from"url";async function Je(e,t=!1){if(process.title=e,!t||process.platform!=="linux")return;try{let{dlopen:n,FFIType:r,ptr:i}=await import("bun:ffi"),{symbols:o}=n("libc.so.6",{prctl:{args:[r.i32,r.ptr,r.u64,r.u64,r.u64],returns:r.i32}}),s=15;o.prctl(15,i(Buffer.from(`${e}\x00`)),0n,0n,0n)}catch{}}var Ke=typeof process<"u"&&!!process.versions?.bun;await Je("primdy-server",Ke);function nn(){return new Promise((e)=>{let t=tn(import.meta.url),n;try{n=en("bun",[t,...process.argv.slice(2)],{stdio:"inherit",env:process.env})}catch{e(null);return}let r=(o)=>{n.kill(o)};process.on("SIGINT",r),process.on("SIGTERM",r);let i=!1;n.once("error",()=>{i=!0,e(null)}),n.once("exit",(o,s)=>{if(process.off("SIGINT",r),process.off("SIGTERM",r),i)return;e(o??(s?1:0))})})}if(!Ke){if(!(process.argv.includes("--node")||process.argv.includes("-N")||await se(process.cwd()).then((n)=>n.node===!0).catch(()=>!1))){let n=await nn();if(n!==null)process.exit(n)}}process.on("uncaughtException",(e)=>{y.err(e instanceof Error?e.message:String(e)),process.exit(1)});process.on("unhandledRejection",(e)=>{y.err(e instanceof Error?e.message:String(e)),process.exit(1)});var S=new T;S.name("primdy").description("Blazingly fast, file-system routed API framework").version(ze.version).helpOption("-h, --help","Display help").helpCommand("help","Displays this message.");async function Y(e,t={}){let n=Zt(process.cwd(),e),r=await se(n,{port:Number(process.env.PORT)||void 0,hostname:process.env.HOSTNAME,...t}),i=r.src??"src",o=Xt(n,i),s=r.port??3000,a=r.hostname??"localhost";return{cwd:n,config:r,src:i,appPath:o,port:s,hostname:a}}function Qe(e){let t={};if(e.port!==void 0)t.port=Number(e.port);if(e.hostname!==void 0)t.hostname=e.hostname;if(e.node!==void 0)t.node=e.node;return t}async function rn(e){try{await Kt(e)}catch{return!1}return(await Qt(e,{recursive:!0,withFileTypes:!0}).catch(()=>[])).some((n)=>n.isFile()&&(n.name==="route.ts"||n.name==="route.js"))}async function he(e){if(await rn(e))return!0;return y.err(`No application found
37
37
  Cannot find ${e}`),!1}S.command("dev").argument("[directory]","Application directory",".").description("Starts the development server.").option("-p, --port <port>","Port to listen on").option("-H, --hostname <hostname>","Hostname to listen on").option("-N, --node","Force the Node.js runtime").action(async(e,t)=>{let n=performance.now(),r=await Y(e,Qe(t));if(!await he(r.appPath))process.exit(1);let i=await B(r.appPath),o=await L(r.appPath),s=await U(r.appPath),a=await q(r.appPath);ce(i,{port:r.port,hostname:r.hostname,forceNode:r.config.node},o,s,a),ae(n)});S.command("build").argument("[directory]","Application directory",".").description("Creates a production build of your application.").action(async(e)=>{let t=performance.now(),n=await Y(e);if(!await he(n.appPath))process.exit(1);try{let{routes:r,middleware:i,notFound:o,error:s}=await Me(n.cwd,n.src);await Ye([{title:"Routes",entries:r.map((l)=>({label:l.pathname,file:l.file}))},{title:"Middleware",entries:i.map((l)=>({label:l.dir?`/${l.dir}`:"/",file:l.file}))},{title:"Boundaries",entries:[...o,...s].map((l)=>({label:l.dir?`/${l.dir}`:"/",file:l.file}))}]);let a=performance.now()-t,c=a>=1000?`${(a/1000).toFixed(1)}s`:`${Math.round(a)}ms`;y.success(`Built ${r.length} routes in ${c}`)}catch(r){y.err(r instanceof Error?r.message:String(r)),process.exit(1)}});S.command("start").argument("[directory]","Application directory",".").description("Starts the production server.").option("-p, --port <port>","Port to listen on").option("-H, --hostname <hostname>","Hostname to listen on").option("-N, --node","Force the Node.js runtime").action(async(e,t)=>{let n=performance.now(),r=await Y(e,Qe(t));try{let i=await Ne(r.cwd);ce(i.routes,{port:r.port,hostname:r.hostname,forceNode:r.config.node},i.middleware,i.notFound,i.error),ae(n)}catch{y.err(`No production build found
38
38
  Run ${_.bold("primdy build")} to build your application`),process.exit(1)}});S.command("analyze").argument("[directory]","Application directory",".").description("Analyzes application routes.").action(async(e)=>{let t=await Y(e);if(!await he(t.appPath))process.exit(1);let n=await B(t.appPath);for(let r of n)console.log(`${r.pathname} ${r.file}`)});await S.parseAsync();
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "primdy",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Blazingly fast, file-system routed API framework",
5
5
  "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/primdy/primdy.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/primdy/primdy/issues"
12
+ },
13
+ "homepage": "https://github.com/primdy/primdy",
6
14
  "type": "module",
7
15
  "main": "./dist/index.js",
8
16
  "types": "./dist/index.d.ts",
@@ -25,12 +33,12 @@
25
33
  "test": "bun test"
26
34
  },
27
35
  "dependencies": {
28
- "chalk": "^6.0.0",
29
- "commander": "^15.0.0",
30
36
  "esbuild": "^0.28.2"
31
37
  },
32
38
  "devDependencies": {
33
39
  "@types/bun": "^1.4.1",
40
+ "chalk": "^6.0.0",
41
+ "commander": "^15.0.0",
34
42
  "typescript": "^7.0.2"
35
43
  },
36
44
  "engines": {