UNPKG

@vulppi/intrest

Version:
3 lines (2 loc) 15.3 kB
import{createReadStream as rt,existsSync as ot,lstatSync as ue,readFileSync as nt}from"fs";import{join as _}from"path";import{createDeflate as be,createGunzip as Ae,createGzip as xe,createInflate as Ce,deflate as Oe,gunzip as Ne,gzip as $e,inflate as _e}from"zlib";function q(e){if(typeof e!="string")return e;let[,o,r]=e.match(/^(\d+)([kmgt]b?)$/i)||[];if(!o||!r)return 0;let t=parseInt(o);if(isNaN(t))return 0;switch(r.toLowerCase()){case"tb":return t*1024*1024*1024*1024;case"gb":return t*1024*1024*1024;case"mb":return t*1024*1024;case"kb":return t*1024;default:return t}}function ee(e){switch(!0){case e==null:return;case/^(no|n|false|f|off)$/i.test(e):return!1;case/^(yes|y|true|t|on)$/i.test(e):return!0;case!isNaN(parseFloat(e)):return parseFloat(e);default:return e}}async function V(e,o=["identity"]){let r=e;for(let t of o)/^gzip$/i.test(t)?r=await new Promise((s,p)=>{Ne(r,(n,a)=>{if(n)return p(n);s(a)})}):/^deflate$/i.test(t)&&(r=await new Promise((s,p)=>{_e(r,(n,a)=>{if(n)return p(n);s(a)})}));return r}async function G(e,o=["identity"]){let r=e;for(let t of o)/^gzip$/i.test(t)?r=await new Promise((s,p)=>{$e(r,(n,a)=>{if(n)return p(n);s(a)})}):/^deflate$/i.test(t)&&(r=await new Promise((s,p)=>{Oe(r,(n,a)=>{if(n)return p(n);s(a)})}));return r}async function ve(e,o=["identity"]){let r=e;for(let t of o)/^gzip$/i.test(t)?r=r.pipe(Ae()):/^deflate$/i.test(t)&&(r=r.pipe(Ce()));return r}async function W(e,o=["identity"]){let r=e;for(let t of o)/^gzip$/i.test(t)?r=r.pipe(xe()):/^deflate$/i.test(t)&&(r=r.pipe(be()));return r}import{glob as J}from"glob";import{join as K,normalize as je}from"path";import{pathToFileURL as Fe}from"url";var v=()=>process.env.NODE_ENV==="development",P={env:[".env",".env{.local,.development,.production}"],entryFolder:["routes","src/routes"],assetsFolder:["assets","src/assets"],staticFolder:["static","src/static","public","src/public"],configFile:"intrest.config.{mjs,cjs,js}",envFile:".env{.local,.development,.production}",bootstrapEntry:"bootstrap.ts",bootstrapCompiled:"bootstrap.mjs",entryPoints:"**/{route,middleware,validation}.ts",identityPoints:"**/__identity.mjs",middlewarePoints:"**/middleware.mjs",routeFile:"route.{mjs,cjs,js,ts}",middlewareFile:"middleware.{mjs,cjs,js,ts}"},D={env:/^\.env(?:\.[a-z-_]*)?$/,config:/^intrest\.config\.[mc]?js$/,bootstrap:/^bootstrap\.ts$/,entry:/(?:^|\/)(?:route|middleware|validation)\.ts$/,observable:/(?:route)\.ts$/,reservedChars:/(?:[.*+?^=!:${}()|\[\]\/\\])/g,startSlashesOrNot:/^[\\\/]*/,endSlashesOrNot:/[\\\/]*$/,multiSlashes:/[\\\/]+/g,isBusboyContentType:/^(?:x-www-form-urlencoded|multipart\/form-data.*)$/i,isJSONContentType:/^application\/json$/i,isXMLContentType:/^application\/xml$/i,isAcceptableContentType:/^(?:x-www-form-urlencoded|multipart\/form-data.*|application\/(?:json|xml))$/i},x={compiledFolder:".intrest",compiledRoutes:"routes",workerMultiWorker:"multi.mjs",workerSingleWorker:"single.mjs",workerRouter:"router.mjs",routeIdentity:"__identity.mjs"};function m(e){return je(e).replace(/[\/\\]+/g,"/")}async function te(e){if(!e)return{};let o=Fe(e);o.searchParams.set("update",Date.now().toString());try{return await import(o.toString()).then(r=>r)||{}}catch{return{}}}async function L(...e){let o=await J(m(K(...e)),{ignore:["**/node_modules/**"],windowsPathsNoEscape:!0});return o[0]&&m(o[0])}async function z(...e){return(await J(m(K(...e)),{ignore:["**/node_modules/**"],windowsPathsNoEscape:!0})).map(m)}async function Ie(...e){let o=e.map(t=>m(K(...t)));return(await J(o.reverse(),{ignore:["**/node_modules/**"],windowsPathsNoEscape:!0})).map(m)}async function N(e,o){return(await Ie(...o.map(r=>[e,r])))[0]||o[1]}function H(e){return v()?`${e}?update=${Date.now()}`:e}import De from"busboy";import k from"chalk";import Le from"concat-stream";import Q from"cookie";import{randomUUID as ze}from"crypto";import{XMLParser as He,XMLValidator as ke}from"fast-xml-parser";import{createWriteStream as Me,rmSync as Be}from"fs";import{StatusCodes as b,getReasonPhrase as Ue}from"http-status-codes";import re from"lodash";import{join as oe}from"path";import{performance as se}from"perf_hooks";import ne from"ms";function j(e,o,r,t=200){console.debug("%s(%s - %s) - %s %s",k.yellow(o),k.green(t),Ue(t),k.bold(r),k.cyan(`${(se.now()-e).toPrecision(5)}ms`))}function ae(e){return async function(r,t){let s=process.cwd(),p=await L(s,P.configFile),n=(await te(p)).default||{},a=m(oe(s,n.paths?.uploadTemp||".tmp")),c=r.method?.toUpperCase()||"GET",[i,l]=(r.url||"/").split("?"),f=decodeURIComponent(i),w=l||"",A=r.headers["content-type"]||"application/json",R=r.headers.origin||r.headers.host||"",C=r.socket.remoteAddress,S=R.replace(/^[a-z]+:\/\//,""),T=/^[a-z]+:\/\//.test(R)?R:R.includes("localhost")||v()?`http://${R||"localhost"}`:R?`https://${R}`:"*";if(n.limits?.allowOrigin&&!v()){let h=(Array.isArray(n.limits.allowOrigin)?n.limits.allowOrigin:[n.limits.allowOrigin]).map(d=>d.replace(/^[a-z]+:\/\//,"")).find(d=>S.endsWith(d));h?t.setHeader("Access-Control-Allow-Origin",h):t.setHeader("Access-Control-Allow-Origin","*")}else t.setHeader("Access-Control-Allow-Origin",T);t.setHeader("Server","IntREST"),t.setHeader("Accept",["application/json","application/xml","x-www-form-urlencoded","multipart/form-data"]),t.setHeader("Accept-Encoding",["gzip","x-gzip","deflate","identity"]),t.setHeader("Access-Control-Allow-Methods",["GET","POST","PUT","PATCH","DELETE","OPTIONS"]),t.setHeader("Access-Control-Allow-Headers",["Content-Length","Content-Type","Authorization","Range","*",...n.limits?.allowHeaders||[]]),t.setHeader("Access-Control-Allow-Credentials","true"),t.setHeader("Access-Control-Max-Age","86400"),t.setHeader("Accept-Ranges","bytes"),t.setHeader("Connection","keep-alive"),t.setHeader("Keep-Alive",["timeout=5","max=30"]);let y=se.now();if(/^options$/i.test(c)){t.statusCode=b.NO_CONTENT,t.end();return}if(!D.isAcceptableContentType.test(A))return t.writeHead(b.UNSUPPORTED_MEDIA_TYPE,{"Content-Type":"application/json"}),j(y,c,f,b.UNSUPPORTED_MEDIA_TYPE),t.end(JSON.stringify({message:n.messages?.UNSUPPORTED_MEDIA_TYPE||"Unsupported media type"}));let O={},fe=r.headers["content-length"]&&parseInt(r.headers["content-length"])||0,ge=q(n.limits?.bodyMaxSize||"10mb");if(fe>ge)return t.writeHead(b.REQUEST_TOO_LONG,{"Content-Type":"application/json"}),j(y,c,f,b.REQUEST_TOO_LONG),t.end(JSON.stringify({message:n.messages?.REQUEST_TOO_LONG||"Request entity too large"}));let B=[];if(!/^get$/i.test(c))try{if(D.isBusboyContentType.test(A))await new Promise((g,h)=>{let d=De({headers:r.headers});d.on("file",(u,E,ye)=>{let{filename:he,encoding:Re,mimeType:Te}=ye,Ee=ze(),U=m(oe(a,Ee)),Pe={absolutePath:U,filename:he,encoding:Re,mimetype:Te};re.set(O,u,Pe),B.push(U);let Se=Me(U,{flags:"w"});E.pipe(Se,{end:!0})}),d.on("field",(u,E)=>{re.set(O,u,ee(E))}),d.on("close",g),d.on("error",h),r.pipe(d,{end:!0})});else{let g=await new Promise(u=>{let E=Le(u);r.pipe(E)}),h=r.headers["content-encoding"]||"identity",d=(await V(g,h.split(/, */))).toString()||"{}";if(D.isJSONContentType.test(A))O=JSON.parse(d);else{let u=new He({ignoreAttributes:!1,allowBooleanAttributes:!0,attributeNamePrefix:"",attributesGroupName:"$attributes",commentPropName:"$comment",cdataPropName:"$cdata",textNodeName:"$text",alwaysCreateTextNode:!0,parseTagValue:!0,unpairedTags:["meta","link","img","br","hr","input"]});if(!ke.validate(d))throw new Error("Invalid XML");O=u.parse(d)}}}catch(g){return t.writeHead(b.BAD_REQUEST,{"Content-Type":"application/json"}),j(y,c,f,b.BAD_REQUEST),t.end(JSON.stringify({message:"Invalid body",error:g.message||g.toString()}))}let we=Q.parse(r.headers.cookie||"");try{await e({basePath:s,config:n,data:{method:c,path:f,custom:{},headers:r.headers,cookies:we,body:O,query:w,origin:{url:T==="*"?void 0:new URL(T),ip:C}}},(g,h)=>{if(g==="cookie"){let{name:d,value:u,options:E}=h;E?.maxAge&&typeof E?.maxAge=="string"&&(E.maxAge=ne(E.maxAge)),t.appendHeader("Set-Cookie",Q.serialize(d,u,E))}else if(g==="clear-cookie"){let{name:d,options:u}=h;u?.maxAge&&typeof u?.maxAge=="string"&&(u.maxAge=ne(u.maxAge)),t.appendHeader("Set-Cookie",Q.serialize(d,"",u))}else if(g==="set"){let[d,u]=h;t.setHeader(d,u||"")}else if(g==="write"){let d=h;t.write(d)}else if(g==="status")t.statusCode=h;else if(g==="end"){if(B.length&&n.removeUploadFilesAfterResponse)for(let d of B)try{Be(d)}catch(u){console.error(`Error removing file ${d}`,u.message)}j(y,c,f,t.statusCode),t.end()}})}catch(g){return console.error(g),t.writeHead(b.INTERNAL_SERVER_ERROR,{"Content-Type":"application/json"}),j(y,c,f,b.INTERNAL_SERVER_ERROR),t.end(JSON.stringify({message:n.messages?.INTERNAL_SERVER_ERROR||"Internal server error"}))}}}import{createReadStream as Xe}from"fs";import{StatusCodes as F}from"http-status-codes";import le from"lodash";import{lookup as Ye}from"mime-types";import{join as I}from"path";import{unescape as Ze}from"querystring";import{pathToFileURL as Y}from"url";import{StatusCodes as X}from"http-status-codes";import ce from"lodash";import Ke from"range-parser";import{Readable as Qe}from"stream";import{isAnyArrayBuffer as Ve,isUint16Array as Ge,isUint32Array as We,isUint8Array as Je}from"util/types";function ie(e){return!!(Ve(e)||Je(e)||Ge(e)||We(e))}function M(e){return!!(e&&Array.isArray(e)&&e.length&&e.type==="bytes")}async function pe(e,o,r,t){let s=Object.keys(e.headers||{}).find(i=>/^content-length$/i.test(i)),p=Object.keys(e.headers||{}).find(i=>/^content-type$/i.test(i)),n=ce.get(e.headers||{},s||"Content-Length",1/0),a=ce.get(e.headers||{},p||"Content-Type"),c=o.range?Ke(+n,o.range,{combine:!0}):void 0;M(c)&&(e.status=!e.status||e.status===X.OK?X.PARTIAL_CONTENT:e.status,e.headers={...e.headers,"Content-Range":`bytes ${c[0].start}-${c[0].end}`+(n&&isFinite(+n)?`/${n}`:"")},delete e.headers[s||"Content-Length"]);for(let i of Object.entries(e.headers||{}))t({requestId:r,state:"set",data:i});for(let[i,l]of Object.entries(e.cookies||{}))if(Array.isArray(l))for(let f of l)t({requestId:r,state:"cookie",data:{name:i,value:f.value,options:f.options}});else t({requestId:r,state:"cookie",data:{name:i,value:l.value,options:l.options}});for(let[i,l]of Object.entries(e.clearCookies||{}))if(Array.isArray(l))for(let f of l)t({requestId:r,state:"clear-cookie",data:{name:i,options:f}});else t({requestId:r,state:"clear-cookie",data:{name:i,options:l}});if(t({requestId:r,state:"status",data:e.status||X.OK}),e.body)if(typeof e.body=="string"||ie(e.body)){a||t({requestId:r,state:"set",data:["Content-Type","text/plain"]});let i=Buffer.from(e.body);M(c)?t({requestId:r,state:"write",data:i.subarray(c[0].start,c[0].end+1)}):t({requestId:r,state:"write",data:i})}else if(e.body instanceof Qe){a||t({requestId:r,state:"set",data:["Content-Type","application/octet-stream"]});let i=e.body;if(M(c)){let l=c[0].start,f=c[0].end,w=0;await new Promise((A,R)=>{i.on("data",C=>{let S=Buffer.from(C);if(S.length+w<l){w+=S.length;return}if(w>f)return i.destroy(),A();let T=Math.max(l-w,0),y=Math.min(f+1-w,S.length);w+=y;let O=S.subarray(T,T+y);t({requestId:r,state:"write",data:O})}),i.on("end",()=>{A()}),i.on("error",C=>{R(C)})})}else await new Promise((l,f)=>{i.on("data",w=>{t({requestId:r,state:"write",data:w})}),i.on("end",()=>{l()}),i.on("error",w=>{f(w)})})}else{a||t({requestId:r,state:"set",data:["Content-Type","application/json"]});let i=JSON.stringify(e.body),l=Buffer.from(i);M(c)?t({requestId:r,state:"write",data:l.subarray(c[0].start,c[0].end+1)}):t({requestId:r,state:"write",data:l})}t({requestId:r,state:"end",data:void 0})}async function de({data:e,config:o,basePath:r},t){let s={...e,params:{},query:new URLSearchParams(e.query||"")},p=await N(r,P.staticFolder);if(p){let n=await L(p,s.path);if(n){let a=Ye(n);if(a)return await $({status:F.OK,body:Xe(n),headers:{"Content-Type":a}},s.headers,t)}}try{let n=await qe(s.path);if(!n.length)return await $({status:F.NOT_FOUND,body:{message:o.messages?.NOT_FOUND||"Not found"},headers:{"Content-Type":"application/json"}},s.headers,t);let a=s.method,c=m(I(x.compiledFolder,x.compiledRoutes)),l=(await Promise.all(n.map(async T=>{let y=await import(H(Y(m(I(c,T.pathname,"route.mjs"))).toString()));return{handler:y[a]||y.ALL||y.default,identity:T}}))).find(T=>typeof T.handler=="function");if(!l?.handler)return await $({status:F.METHOD_NOT_ALLOWED,body:{message:o.messages?.METHOD_NOT_ALLOWED||"Method not allowed"},headers:{"Content-Type":"application/json"}},s.headers,t);let f=l.identity.paramExtract,w=l.identity.pathname,A=l.identity.paramKeys,R=Array.from(e.path.match(f)||[]).slice(1);s.params=le.zipObject(A,R.map(Ze));let C=await et(w),S=await me({middlewares:C,context:s,config:o,requestHandler:l.handler});if(!S)throw new Error("Response not found");return await $(S,s.headers,t)}catch(n){if(console.error(n),n instanceof Error)return await $({status:F.INTERNAL_SERVER_ERROR,body:{message:n.message},headers:{"Content-Type":"application/json"}},s.headers,t);if(typeof n=="object"&&n!=null)return await $(n,s.headers,t);throw n}}async function $(e,o,r){return await pe(e,o,"void",t=>{let{state:s,data:p}=t;r(s,p)})}async function qe(e){let o=m(I(process.cwd(),x.compiledFolder,x.compiledRoutes)),r=await z(o,P.identityPoints);return(await Promise.all(r.map(s=>import(H(Y(s).toString())).then(p=>p)))).filter(s=>s.paramExtract.test(e)).sort((s,p)=>s.pathname>p.pathname?1:-1).sort(tt)}async function et(e){let o=m(I(process.cwd(),x.compiledFolder,x.compiledRoutes)),r=e.split("/").map((n,a,c)=>a>0?c.slice(0,a+1).join("/"):"/").map(n=>m(I(o,n,"middleware.mjs"))),s=(await z(o,P.middlewarePoints)).filter(n=>r.some(a=>n===a));return(await Promise.all(s.map(async n=>({handler:await import(H(Y(n).toString())).then(a=>a.middleware||a.default),pathname:n.replace(o,"")})))).filter(n=>typeof n.handler=="function")}function tt(e,o){let r=e.pathname.split("/"),t=o.pathname.split("/");for(let s=0;s<r.length;s++)if(!(r[s][0]==="["&&t[s]?.[0]==="[")){if(r[s][0]==="[")return 1;if(t[s]?.[0]==="[")return-1}return o.route.toLowerCase()>e.route.toLowerCase()?-1:o.route.toLowerCase()<e.route.toLowerCase()?1:0}async function me({middlewares:e,context:o,config:r,requestHandler:t}){if(!e.length)return await t(o)||{status:F.NOT_FOUND};let s=e[0],p=setTimeout(()=>{throw new Error(`Middleware handler timeout: ${s.pathname}`)},r.limits?.middleware?.timeout||5e3),n=await s.handler(o,async a=>(clearTimeout(p),o.custom=le.merge(o.custom,a),me({middlewares:e.slice(1),context:o,config:r,requestHandler:t})));return clearTimeout(p),n}export*from"http-status-codes";async function Z(e){if(!ot(e))throw new Error(`File not found: ${e}`);if(!(await ue(e)).isFile())throw new Error(`File not found: ${e}`)}async function ar(e,o){let r=await N(process.cwd(),P.assetsFolder);await Z(m(_(r,e)));let t=o?.compress?.split(/, */g)||[],s=rt(m(_(r,e)),{autoClose:!0});return W(s,t)}async function st(e,o){let r=await N(process.cwd(),P.assetsFolder);await Z(m(_(r,e)));let t=o?.split(/, */g)||[],s=nt(m(_(r,e)));return G(s,t)}async function ir(e){return(await st(e)).toString()}var cr=ae(de);async function pr(e){let o=await N(process.cwd(),P.assetsFolder);return await Z(m(_(o,e))),ue(m(_(o,e)))}export{ir as assetsContent,st as assetsRawContent,pr as assetsStats,ar as assetsStream,cr as globalRequestHandler,G as parseCompressBuffer,W as parseCompressStream,V as parseDecompressBuffer,ve as parseDecompressStream}; //# sourceMappingURL=index.mjs.map