molnos 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/storage.mjs CHANGED
@@ -1,2 +1,11 @@
1
1
  // MolnOS Core - See LICENSE file for copyright and license details.
2
- var st=(t,e,s)=>(r,o)=>{let n=-1;return a(0);async function a(i){if(i<=n)throw new Error("next() called multiple times");n=i;let u,c=!1,l;if(t[i]?(l=t[i][0][0],r.req.routeIndex=i):l=i===t.length&&o||void 0,l)try{u=await l(r,()=>a(i+1))}catch(h){if(h instanceof Error&&e)r.error=h,u=await e(h,r),c=!0;else throw h}else r.finalized===!1&&s&&(u=await s(r));return u&&(r.finalized===!1||c)&&(r.res=u),r}};var xt=Symbol();var Et=async(t,e=Object.create(null))=>{let{all:s=!1,dot:r=!1}=e,n=(t instanceof G?t.raw.headers:t.headers).get("Content-Type");return n?.startsWith("multipart/form-data")||n?.startsWith("application/x-www-form-urlencoded")?je(t,{all:s,dot:r}):{}};async function je(t,e){let s=await t.formData();return s?Pe(s,e):{}}function Pe(t,e){let s=Object.create(null);return t.forEach((r,o)=>{e.all||o.endsWith("[]")?Re(s,o,r):s[o]=r}),e.dot&&Object.entries(s).forEach(([r,o])=>{r.includes(".")&&(ke(s,r,o),delete s[r])}),s}var Re=(t,e,s)=>{t[e]!==void 0?Array.isArray(t[e])?t[e].push(s):t[e]=[t[e],s]:e.endsWith("[]")?t[e]=[s]:t[e]=s},ke=(t,e,s)=>{let r=t,o=e.split(".");o.forEach((n,a)=>{a===o.length-1?r[n]=s:((!r[n]||typeof r[n]!="object"||Array.isArray(r[n])||r[n]instanceof File)&&(r[n]=Object.create(null)),r=r[n])})};var nt=t=>{let e=t.split("/");return e[0]===""&&e.shift(),e},jt=t=>{let{groups:e,path:s}=Ce(t),r=nt(s);return Se(r,e)},Ce=t=>{let e=[];return t=t.replace(/\{[^}]+\}/g,(s,r)=>{let o=`@${r}`;return e.push([o,s]),o}),{groups:e,path:t}},Se=(t,e)=>{for(let s=e.length-1;s>=0;s--){let[r]=e[s];for(let o=t.length-1;o>=0;o--)if(t[o].includes(r)){t[o]=t[o].replace(r,e[s][1]);break}}return t},V={},Pt=(t,e)=>{if(t==="*")return"*";let s=t.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(s){let r=`${t}#${e}`;return V[r]||(s[2]?V[r]=e&&e[0]!==":"&&e[0]!=="*"?[r,s[1],new RegExp(`^${s[2]}(?=/${e})`)]:[t,s[1],new RegExp(`^${s[2]}$`)]:V[r]=[t,s[1],!0]),V[r]}return null},W=(t,e)=>{try{return e(t)}catch{return t.replace(/(?:%[0-9A-Fa-f]{2})+/g,s=>{try{return e(s)}catch{return s}})}},Oe=t=>W(t,decodeURI),at=t=>{let e=t.url,s=e.indexOf("/",e.indexOf(":")+4),r=s;for(;r<e.length;r++){let o=e.charCodeAt(r);if(o===37){let n=e.indexOf("?",r),a=e.slice(s,n===-1?void 0:n);return Oe(a.includes("%25")?a.replace(/%25/g,"%2525"):a)}else if(o===63)break}return e.slice(s,r)};var Rt=t=>{let e=at(t);return e.length>1&&e.at(-1)==="/"?e.slice(0,-1):e},C=(t,e,...s)=>(s.length&&(e=C(e,...s)),`${t?.[0]==="/"?"":"/"}${t}${e==="/"?"":`${t?.at(-1)==="/"?"":"/"}${e?.[0]==="/"?e.slice(1):e}`}`),K=t=>{if(t.charCodeAt(t.length-1)!==63||!t.includes(":"))return null;let e=t.split("/"),s=[],r="";return e.forEach(o=>{if(o!==""&&!/\:/.test(o))r+="/"+o;else if(/\:/.test(o))if(/\?/.test(o)){s.length===0&&r===""?s.push("/"):s.push(r);let n=o.replace("?","");r+="/"+n,s.push(r)}else r+="/"+o}),s.filter((o,n,a)=>a.indexOf(o)===n)},ot=t=>/[%+]/.test(t)?(t.indexOf("+")!==-1&&(t=t.replace(/\+/g," ")),t.indexOf("%")!==-1?W(t,it):t):t,kt=(t,e,s)=>{let r;if(!s&&e&&!/[%+]/.test(e)){let a=t.indexOf("?",8);if(a===-1)return;for(t.startsWith(e,a+1)||(a=t.indexOf(`&${e}`,a+1));a!==-1;){let i=t.charCodeAt(a+e.length+1);if(i===61){let u=a+e.length+2,c=t.indexOf("&",u);return ot(t.slice(u,c===-1?void 0:c))}else if(i==38||isNaN(i))return"";a=t.indexOf(`&${e}`,a+1)}if(r=/[%+]/.test(t),!r)return}let o={};r??=/[%+]/.test(t);let n=t.indexOf("?",8);for(;n!==-1;){let a=t.indexOf("&",n+1),i=t.indexOf("=",n);i>a&&a!==-1&&(i=-1);let u=t.slice(n+1,i===-1?a===-1?void 0:a:i);if(r&&(u=ot(u)),n=a,u==="")continue;let c;i===-1?c="":(c=t.slice(i+1,a===-1?void 0:a),r&&(c=ot(c))),s?(o[u]&&Array.isArray(o[u])||(o[u]=[]),o[u].push(c)):o[u]??=c}return e?o[e]:o},Ct=kt,St=(t,e)=>kt(t,e,!0),it=decodeURIComponent;var Ot=t=>W(t,it),G=class{raw;#e;#t;routeIndex=0;path;bodyCache={};constructor(t,e="/",s=[[]]){this.raw=t,this.path=e,this.#t=s,this.#e={}}param(t){return t?this.#r(t):this.#n()}#r(t){let e=this.#t[0][this.routeIndex][1][t],s=this.#o(e);return s&&/\%/.test(s)?Ot(s):s}#n(){let t={},e=Object.keys(this.#t[0][this.routeIndex][1]);for(let s of e){let r=this.#o(this.#t[0][this.routeIndex][1][s]);r!==void 0&&(t[s]=/\%/.test(r)?Ot(r):r)}return t}#o(t){return this.#t[1]?this.#t[1][t]:t}query(t){return Ct(this.url,t)}queries(t){return St(this.url,t)}header(t){if(t)return this.raw.headers.get(t)??void 0;let e={};return this.raw.headers.forEach((s,r)=>{e[r]=s}),e}async parseBody(t){return this.bodyCache.parsedBody??=await Et(this,t)}#s=t=>{let{bodyCache:e,raw:s}=this,r=e[t];if(r)return r;let o=Object.keys(e)[0];return o?e[o].then(n=>(o==="json"&&(n=JSON.stringify(n)),new Response(n)[t]())):e[t]=s[t]()};json(){return this.#s("text").then(t=>JSON.parse(t))}text(){return this.#s("text")}arrayBuffer(){return this.#s("arrayBuffer")}blob(){return this.#s("blob")}formData(){return this.#s("formData")}addValidatedData(t,e){this.#e[t]=e}valid(t){return this.#e[t]}get url(){return this.raw.url}get method(){return this.raw.method}get[xt](){return this.#t}get matchedRoutes(){return this.#t[0].map(([[,t]])=>t)}get routePath(){return this.#t[0].map(([[,t]])=>t)[this.routeIndex].path}};var At={Stringify:1,BeforeStream:2,Stream:3},Ae=(t,e)=>{let s=new String(t);return s.isEscaped=!0,s.callbacks=e,s};var ct=async(t,e,s,r,o)=>{typeof t=="object"&&!(t instanceof String)&&(t instanceof Promise||(t=t.toString()),t instanceof Promise&&(t=await t));let n=t.callbacks;if(!n?.length)return Promise.resolve(t);o?o[0]+=t:o=[t];let a=Promise.all(n.map(i=>i({phase:e,buffer:o,context:r}))).then(i=>Promise.all(i.filter(Boolean).map(u=>ct(u,e,!1,r,o))).then(()=>o[0]));return s?Ae(await a,n):a};var Me="text/plain; charset=UTF-8",ut=(t,e)=>({"Content-Type":t,...e}),Mt=class{#e;#t;env={};#r;finalized=!1;error;#n;#o;#s;#l;#c;#u;#i;#h;#d;constructor(t,e){this.#e=t,e&&(this.#o=e.executionCtx,this.env=e.env,this.#u=e.notFoundHandler,this.#d=e.path,this.#h=e.matchResult)}get req(){return this.#t??=new G(this.#e,this.#d,this.#h),this.#t}get event(){if(this.#o&&"respondWith"in this.#o)return this.#o;throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#o)return this.#o;throw Error("This context has no ExecutionContext")}get res(){return this.#s||=new Response(null,{headers:this.#i??=new Headers})}set res(t){if(this.#s&&t){t=new Response(t.body,t);for(let[e,s]of this.#s.headers.entries())if(e!=="content-type")if(e==="set-cookie"){let r=this.#s.headers.getSetCookie();t.headers.delete("set-cookie");for(let o of r)t.headers.append("set-cookie",o)}else t.headers.set(e,s)}this.#s=t,this.finalized=!0}render=(...t)=>(this.#c??=e=>this.html(e),this.#c(...t));setLayout=t=>this.#l=t;getLayout=()=>this.#l;setRenderer=t=>{this.#c=t};header=(t,e,s)=>{this.finalized&&(this.#s=new Response(this.#s.body,this.#s));let r=this.#s?this.#s.headers:this.#i??=new Headers;e===void 0?r.delete(t):s?.append?r.append(t,e):r.set(t,e)};status=t=>{this.#n=t};set=(t,e)=>{this.#r??=new Map,this.#r.set(t,e)};get=t=>this.#r?this.#r.get(t):void 0;get var(){return this.#r?Object.fromEntries(this.#r):{}}#a(t,e,s){let r=this.#s?new Headers(this.#s.headers):this.#i??new Headers;if(typeof e=="object"&&"headers"in e){let n=e.headers instanceof Headers?e.headers:new Headers(e.headers);for(let[a,i]of n)a.toLowerCase()==="set-cookie"?r.append(a,i):r.set(a,i)}if(s)for(let[n,a]of Object.entries(s))if(typeof a=="string")r.set(n,a);else{r.delete(n);for(let i of a)r.append(n,i)}let o=typeof e=="number"?e:e?.status??this.#n;return new Response(t,{status:o,headers:r})}newResponse=(...t)=>this.#a(...t);body=(t,e,s)=>this.#a(t,e,s);text=(t,e,s)=>!this.#i&&!this.#n&&!e&&!s&&!this.finalized?new Response(t):this.#a(t,e,ut(Me,s));json=(t,e,s)=>this.#a(JSON.stringify(t),e,ut("application/json",s));html=(t,e,s)=>{let r=o=>this.#a(o,e,ut("text/html; charset=UTF-8",s));return typeof t=="object"?ct(t,At.Stringify,!1,{}).then(r):r(t)};redirect=(t,e)=>{let s=String(t);return this.header("Location",/[^\x00-\xFF]/.test(s)?encodeURI(s):s),this.newResponse(null,e??302)};notFound=()=>(this.#u??=()=>new Response,this.#u(this))};var p="ALL",Bt="all",qt=["get","post","put","delete","options","patch"],J="Can not add a route since the matcher is already built.",Q=class extends Error{};var Tt="__COMPOSED_HANDLER";var Be=t=>t.text("404 Not Found",404),Ht=(t,e)=>{if("getResponse"in t){let s=t.getResponse();return e.newResponse(s.body,s)}return console.error(t),e.text("Internal Server Error",500)},It=class Dt{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#e="/";routes=[];constructor(e={}){[...qt,Bt].forEach(n=>{this[n]=(a,...i)=>(typeof a=="string"?this.#e=a:this.#n(n,this.#e,a),i.forEach(u=>{this.#n(n,this.#e,u)}),this)}),this.on=(n,a,...i)=>{for(let u of[a].flat()){this.#e=u;for(let c of[n].flat())i.map(l=>{this.#n(c.toUpperCase(),this.#e,l)})}return this},this.use=(n,...a)=>(typeof n=="string"?this.#e=n:(this.#e="*",a.unshift(n)),a.forEach(i=>{this.#n(p,this.#e,i)}),this);let{strict:r,...o}=e;Object.assign(this,o),this.getPath=r??!0?e.getPath??at:Rt}#t(){let e=new Dt({router:this.router,getPath:this.getPath});return e.errorHandler=this.errorHandler,e.#r=this.#r,e.routes=this.routes,e}#r=Be;errorHandler=Ht;route(e,s){let r=this.basePath(e);return s.routes.map(o=>{let n;s.errorHandler===Ht?n=o.handler:(n=async(a,i)=>(await st([],s.errorHandler)(a,()=>o.handler(a,i))).res,n[Tt]=o.handler),r.#n(o.method,o.path,n)}),this}basePath(e){let s=this.#t();return s._basePath=C(this._basePath,e),s}onError=e=>(this.errorHandler=e,this);notFound=e=>(this.#r=e,this);mount(e,s,r){let o,n;r&&(typeof r=="function"?n=r:(n=r.optionHandler,r.replaceRequest===!1?o=u=>u:o=r.replaceRequest));let a=n?u=>{let c=n(u);return Array.isArray(c)?c:[c]}:u=>{let c;try{c=u.executionCtx}catch{}return[u.env,c]};o||=(()=>{let u=C(this._basePath,e),c=u==="/"?0:u.length;return l=>{let h=new URL(l.url);return h.pathname=h.pathname.slice(c)||"/",new Request(h,l)}})();let i=async(u,c)=>{let l=await s(o(u.req.raw),...a(u));if(l)return l;await c()};return this.#n(p,C(e,"*"),i),this}#n(e,s,r){e=e.toUpperCase(),s=C(this._basePath,s);let o={basePath:this._basePath,path:s,method:e,handler:r};this.router.add(e,s,[r,o]),this.routes.push(o)}#o(e,s){if(e instanceof Error)return this.errorHandler(e,s);throw e}#s(e,s,r,o){if(o==="HEAD")return(async()=>new Response(null,await this.#s(e,s,r,"GET")))();let n=this.getPath(e,{env:r}),a=this.router.match(o,n),i=new Mt(e,{path:n,matchResult:a,env:r,executionCtx:s,notFoundHandler:this.#r});if(a[0].length===1){let c;try{c=a[0][0][0][0](i,async()=>{i.res=await this.#r(i)})}catch(l){return this.#o(l,i)}return c instanceof Promise?c.then(l=>l||(i.finalized?i.res:this.#r(i))).catch(l=>this.#o(l,i)):c??this.#r(i)}let u=st(a[0],this.errorHandler,this.#r);return(async()=>{try{let c=await u(i);if(!c.finalized)throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return c.res}catch(c){return this.#o(c,i)}})()}fetch=(e,...s)=>this.#s(e,s[1],s[0],e.method);request=(e,s,r,o)=>e instanceof Request?this.fetch(s?new Request(e,s):e,r,o):(e=e.toString(),this.fetch(new Request(/^https?:\/\//.test(e)?e:`http://localhost${C("/",e)}`,s),r,o));fire=()=>{addEventListener("fetch",e=>{e.respondWith(this.#s(e.request,e,void 0,e.request.method))})}};var X=[];function lt(t,e){let s=this.buildAllMatchers(),r=((o,n)=>{let a=s[o]||s[p],i=a[2][n];if(i)return i;let u=n.match(a[0]);if(!u)return[[],X];let c=u.indexOf("",1);return[a[1][c],u]});return this.match=r,r(t,e)}var Y="[^/]+",L=".*",$="(?:|/.*)",S=Symbol(),qe=new Set(".\\+*[^]$()");function Te(t,e){return t.length===1?e.length===1?t<e?-1:1:-1:e.length===1||t===L||t===$?1:e===L||e===$?-1:t===Y?1:e===Y?-1:t.length===e.length?t<e?-1:1:e.length-t.length}var Lt=class ht{#e;#t;#r=Object.create(null);insert(e,s,r,o,n){if(e.length===0){if(this.#e!==void 0)throw S;if(n)return;this.#e=s;return}let[a,...i]=e,u=a==="*"?i.length===0?["","",L]:["","",Y]:a==="/*"?["","",$]:a.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),c;if(u){let l=u[1],h=u[2]||Y;if(l&&u[2]&&(h===".*"||(h=h.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(h))))throw S;if(c=this.#r[h],!c){if(Object.keys(this.#r).some(d=>d!==L&&d!==$))throw S;if(n)return;c=this.#r[h]=new ht,l!==""&&(c.#t=o.varIndex++)}!n&&l!==""&&r.push([l,c.#t])}else if(c=this.#r[a],!c){if(Object.keys(this.#r).some(l=>l.length>1&&l!==L&&l!==$))throw S;if(n)return;c=this.#r[a]=new ht}c.insert(i,s,r,o,n)}buildRegExpStr(){let s=Object.keys(this.#r).sort(Te).map(r=>{let o=this.#r[r];return(typeof o.#t=="number"?`(${r})@${o.#t}`:qe.has(r)?`\\${r}`:r)+o.buildRegExpStr()});return typeof this.#e=="number"&&s.unshift(`#${this.#e}`),s.length===0?"":s.length===1?s[0]:"(?:"+s.join("|")+")"}};var $t=class{#e={varIndex:0};#t=new Lt;insert(t,e,s){let r=[],o=[];for(let a=0;;){let i=!1;if(t=t.replace(/\{[^}]+\}/g,u=>{let c=`@\\${a}`;return o[a]=[c,u],a++,i=!0,c}),!i)break}let n=t.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let a=o.length-1;a>=0;a--){let[i]=o[a];for(let u=n.length-1;u>=0;u--)if(n[u].indexOf(i)!==-1){n[u]=n[u].replace(i,o[a][1]);break}}return this.#t.insert(n,e,r,this.#e,s),r}buildRegExp(){let t=this.#t.buildRegExpStr();if(t==="")return[/^$/,[],[]];let e=0,s=[],r=[];return t=t.replace(/#(\d+)|@(\d+)|\.\*\$/g,(o,n,a)=>n!==void 0?(s[++e]=Number(n),"$()"):(a!==void 0&&(r[Number(a)]=++e),"")),[new RegExp(`^${t}`),s,r]}};var He=[/^$/,[],Object.create(null)],Nt=Object.create(null);function _t(t){return Nt[t]??=new RegExp(t==="*"?"":`^${t.replace(/\/\*$|([.\\+*[^\]$()])/g,(e,s)=>s?`\\${s}`:"(?:|/.*)")}$`)}function Ie(){Nt=Object.create(null)}function De(t){let e=new $t,s=[];if(t.length===0)return He;let r=t.map(c=>[!/\*|\/:/.test(c[0]),...c]).sort(([c,l],[h,d])=>c?1:h?-1:l.length-d.length),o=Object.create(null);for(let c=0,l=-1,h=r.length;c<h;c++){let[d,m,x]=r[c];d?o[m]=[x.map(([w])=>[w,Object.create(null)]),X]:l++;let f;try{f=e.insert(m,l,d)}catch(w){throw w===S?new Q(m):w}d||(s[l]=x.map(([w,R])=>{let U=Object.create(null);for(R-=1;R>=0;R--){let[z,j]=f[R];U[z]=j}return[w,U]}))}let[n,a,i]=e.buildRegExp();for(let c=0,l=s.length;c<l;c++)for(let h=0,d=s[c].length;h<d;h++){let m=s[c][h]?.[1];if(!m)continue;let x=Object.keys(m);for(let f=0,w=x.length;f<w;f++)m[x[f]]=i[m[x[f]]]}let u=[];for(let c in a)u[c]=s[a[c]];return[n,u,o]}function B(t,e){if(t){for(let s of Object.keys(t).sort((r,o)=>o.length-r.length))if(_t(s).test(e))return[...t[s]]}}var Z=class{name="RegExpRouter";#e;#t;constructor(){this.#e={[p]:Object.create(null)},this.#t={[p]:Object.create(null)}}add(t,e,s){let r=this.#e,o=this.#t;if(!r||!o)throw new Error(J);r[t]||[r,o].forEach(i=>{i[t]=Object.create(null),Object.keys(i[p]).forEach(u=>{i[t][u]=[...i[p][u]]})}),e==="/*"&&(e="*");let n=(e.match(/\/:/g)||[]).length;if(/\*$/.test(e)){let i=_t(e);t===p?Object.keys(r).forEach(u=>{r[u][e]||=B(r[u],e)||B(r[p],e)||[]}):r[t][e]||=B(r[t],e)||B(r[p],e)||[],Object.keys(r).forEach(u=>{(t===p||t===u)&&Object.keys(r[u]).forEach(c=>{i.test(c)&&r[u][c].push([s,n])})}),Object.keys(o).forEach(u=>{(t===p||t===u)&&Object.keys(o[u]).forEach(c=>i.test(c)&&o[u][c].push([s,n]))});return}let a=K(e)||[e];for(let i=0,u=a.length;i<u;i++){let c=a[i];Object.keys(o).forEach(l=>{(t===p||t===l)&&(o[l][c]||=[...B(r[l],c)||B(r[p],c)||[]],o[l][c].push([s,n-u+i+1]))})}}match=lt;buildAllMatchers(){let t=Object.create(null);return Object.keys(this.#t).concat(Object.keys(this.#e)).forEach(e=>{t[e]||=this.#r(e)}),this.#e=this.#t=void 0,Ie(),t}#r(t){let e=[],s=t===p;return[this.#e,this.#t].forEach(r=>{let o=r[t]?Object.keys(r[t]).map(n=>[n,r[t][n]]):[];o.length!==0?(s||=!0,e.push(...o)):t!==p&&e.push(...Object.keys(r[p]).map(n=>[n,r[p][n]]))}),s?De(e):null}};var dt=class{name="SmartRouter";#e=[];#t=[];constructor(t){this.#e=t.routers}add(t,e,s){if(!this.#t)throw new Error(J);this.#t.push([t,e,s])}match(t,e){if(!this.#t)throw new Error("Fatal error");let s=this.#e,r=this.#t,o=s.length,n=0,a;for(;n<o;n++){let i=s[n];try{for(let u=0,c=r.length;u<c;u++)i.add(...r[u]);a=i.match(t,e)}catch(u){if(u instanceof Q)continue;throw u}this.match=i.match.bind(i),this.#e=[i],this.#t=void 0;break}if(n===o)throw new Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,a}get activeRouter(){if(this.#t||this.#e.length!==1)throw new Error("No active router has been determined yet.");return this.#e[0]}};var N=Object.create(null),Ft=class Ut{#e;#t;#r;#n=0;#o=N;constructor(e,s,r){if(this.#t=r||Object.create(null),this.#e=[],e&&s){let o=Object.create(null);o[e]={handler:s,possibleKeys:[],score:0},this.#e=[o]}this.#r=[]}insert(e,s,r){this.#n=++this.#n;let o=this,n=jt(s),a=[];for(let i=0,u=n.length;i<u;i++){let c=n[i],l=n[i+1],h=Pt(c,l),d=Array.isArray(h)?h[0]:c;if(d in o.#t){o=o.#t[d],h&&a.push(h[1]);continue}o.#t[d]=new Ut,h&&(o.#r.push(h),a.push(h[1])),o=o.#t[d]}return o.#e.push({[e]:{handler:r,possibleKeys:a.filter((i,u,c)=>c.indexOf(i)===u),score:this.#n}}),o}#s(e,s,r,o){let n=[];for(let a=0,i=e.#e.length;a<i;a++){let u=e.#e[a],c=u[s]||u[p],l={};if(c!==void 0&&(c.params=Object.create(null),n.push(c),r!==N||o&&o!==N))for(let h=0,d=c.possibleKeys.length;h<d;h++){let m=c.possibleKeys[h],x=l[c.score];c.params[m]=o?.[m]&&!x?o[m]:r[m]??o?.[m],l[c.score]=!0}}return n}search(e,s){let r=[];this.#o=N;let n=[this],a=nt(s),i=[];for(let u=0,c=a.length;u<c;u++){let l=a[u],h=u===c-1,d=[];for(let m=0,x=n.length;m<x;m++){let f=n[m],w=f.#t[l];w&&(w.#o=f.#o,h?(w.#t["*"]&&r.push(...this.#s(w.#t["*"],e,f.#o)),r.push(...this.#s(w,e,f.#o))):d.push(w));for(let R=0,U=f.#r.length;R<U;R++){let z=f.#r[R],j=f.#o===N?{}:{...f.#o};if(z==="*"){let k=f.#t["*"];k&&(r.push(...this.#s(k,e,f.#o)),k.#o=j,d.push(k));continue}let[ve,vt,D]=z;if(!l&&!(D instanceof RegExp))continue;let P=f.#t[ve],xe=a.slice(u).join("/");if(D instanceof RegExp){let k=D.exec(xe);if(k){if(j[vt]=k[0],r.push(...this.#s(P,e,f.#o,j)),Object.keys(P.#t).length){P.#o=j;let Ee=k[0].match(/\//)?.length??0;(i[Ee]||=[]).push(P)}continue}}(D===!0||D.test(l))&&(j[vt]=l,h?(r.push(...this.#s(P,e,j,f.#o)),P.#t["*"]&&r.push(...this.#s(P.#t["*"],e,j,f.#o))):(P.#o=j,d.push(P)))}}n=d.concat(i.shift()??[])}return r.length>1&&r.sort((u,c)=>u.score-c.score),[r.map(({handler:u,params:c})=>[u,c])]}};var ft=class{name="TrieRouter";#e;constructor(){this.#e=new Ft}add(t,e,s){let r=K(e);if(r){for(let o=0,n=r.length;o<n;o++)this.#e.insert(t,r[o],s);return}this.#e.insert(t,e,s)}match(t,e){return this.#e.search(t,e)}};var pt=class extends It{constructor(t={}){super(t),this.router=t.router??new dt({routers:[new Z,new ft]})}};import{join as v,dirname as gr}from"node:path";import{promises as b}from"node:fs";import{createServer as Le}from"http";import{Http2ServerRequest as $e}from"http2";import{Http2ServerRequest as mt}from"http2";import{Readable as zt}from"stream";import Xe from"crypto";var O=class extends Error{constructor(t,e){super(t,e),this.name="RequestError"}},Ne=t=>t instanceof O?t:new O(t.message,{cause:t}),_e=global.Request,_=class extends _e{constructor(t,e){typeof t=="object"&&H in t&&(t=t[H]()),typeof e?.body?.getReader<"u"&&(e.duplex??="half"),super(t,e)}},Fe=t=>{let e=[],s=t.rawHeaders;for(let r=0;r<s.length;r+=2){let{[r]:o,[r+1]:n}=s;o.charCodeAt(0)!==58&&e.push([o,n])}return new Headers(e)},Vt=Symbol("wrapBodyStream"),Ue=(t,e,s,r,o)=>{let n={method:t,headers:s,signal:o.signal};if(t==="TRACE"){n.method="GET";let a=new _(e,n);return Object.defineProperty(a,"method",{get(){return"TRACE"}}),a}if(!(t==="GET"||t==="HEAD"))if("rawBody"in r&&r.rawBody instanceof Buffer)n.body=new ReadableStream({start(a){a.enqueue(r.rawBody),a.close()}});else if(r[Vt]){let a;n.body=new ReadableStream({async pull(i){try{a||=zt.toWeb(r).getReader();let{done:u,value:c}=await a.read();u?i.close():i.enqueue(c)}catch(u){i.error(u)}}})}else n.body=zt.toWeb(r);return new _(e,n)},H=Symbol("getRequestCache"),ze=Symbol("requestCache"),tt=Symbol("incomingKey"),et=Symbol("urlKey"),Ge=Symbol("headersKey"),T=Symbol("abortControllerKey"),Ve=Symbol("getAbortController"),rt={get method(){return this[tt].method||"GET"},get url(){return this[et]},get headers(){return this[Ge]||=Fe(this[tt])},[Ve](){return this[H](),this[T]},[H](){return this[T]||=new AbortController,this[ze]||=Ue(this.method,this[et],this.headers,this[tt],this[T])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach(t=>{Object.defineProperty(rt,t,{get(){return this[H]()[t]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach(t=>{Object.defineProperty(rt,t,{value:function(){return this[H]()[t]()}})});Object.setPrototypeOf(rt,_.prototype);var We=(t,e)=>{let s=Object.create(rt);s[tt]=t;let r=t.url||"";if(r[0]!=="/"&&(r.startsWith("http://")||r.startsWith("https://"))){if(t instanceof mt)throw new O("Absolute URL for :path is not allowed in HTTP/2");try{let i=new URL(r);s[et]=i.href}catch(i){throw new O("Invalid absolute URL",{cause:i})}return s}let o=(t instanceof mt?t.authority:t.headers.host)||e;if(!o)throw new O("Missing host header");let n;if(t instanceof mt){if(n=t.scheme,!(n==="http"||n==="https"))throw new O("Unsupported scheme")}else n=t.socket&&t.socket.encrypted?"https":"http";let a=new URL(`${n}://${o}${r}`);if(a.hostname.length!==o.length&&a.hostname!==o.replace(/:\d+$/,""))throw new O("Invalid host header");return s[et]=a.href,s},Gt=Symbol("responseCache"),q=Symbol("getResponseCache"),A=Symbol("cache"),gt=global.Response,F=class Wt{#e;#t;[q](){return delete this[A],this[Gt]||=new gt(this.#e,this.#t)}constructor(e,s){let r;if(this.#e=e,s instanceof Wt){let o=s[Gt];if(o){this.#t=o,this[q]();return}else this.#t=s.#t,r=new Headers(s.#t.headers)}else this.#t=s;(typeof e=="string"||typeof e?.getReader<"u"||e instanceof Blob||e instanceof Uint8Array)&&(r||=s?.headers||{"content-type":"text/plain; charset=UTF-8"},this[A]=[s?.status||200,e,r])}get headers(){let e=this[A];return e?(e[2]instanceof Headers||(e[2]=new Headers(e[2])),e[2]):this[q]().headers}get status(){return this[A]?.[0]??this[q]().status}get ok(){let e=this.status;return e>=200&&e<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach(t=>{Object.defineProperty(F.prototype,t,{get(){return this[q]()[t]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach(t=>{Object.defineProperty(F.prototype,t,{value:function(){return this[q]()[t]()}})});Object.setPrototypeOf(F,gt);Object.setPrototypeOf(F.prototype,gt.prototype);async function Ke(t){return Promise.race([t,Promise.resolve().then(()=>Promise.resolve(void 0))])}function Kt(t,e,s){let r=i=>{t.cancel(i).catch(()=>{})};return e.on("close",r),e.on("error",r),(s??t.read()).then(a,o),t.closed.finally(()=>{e.off("close",r),e.off("error",r)});function o(i){i&&e.destroy(i)}function n(){t.read().then(a,o)}function a({done:i,value:u}){try{if(i)e.end();else if(!e.write(u))e.once("drain",n);else return t.read().then(a,o)}catch(c){o(c)}}}function Je(t,e){if(t.locked)throw new TypeError("ReadableStream is locked.");return e.destroyed?void 0:Kt(t.getReader(),e)}var Jt=t=>{let e={};t instanceof Headers||(t=new Headers(t??void 0));let s=[];for(let[r,o]of t)r==="set-cookie"?s.push(o):e[r]=o;return s.length>0&&(e["set-cookie"]=s),e["content-type"]??="text/plain; charset=UTF-8",e},Qe="x-hono-already-sent",Ye=global.fetch;typeof global.crypto>"u"&&(global.crypto=Xe);global.fetch=(t,e)=>(e={compress:!1,...e},Ye(t,e));var bt=Symbol("outgoingEnded"),Ze=()=>new Response(null,{status:400}),Qt=t=>new Response(null,{status:t instanceof Error&&(t.name==="TimeoutError"||t.constructor.name==="TimeoutError")?504:500}),yt=(t,e)=>{let s=t instanceof Error?t:new Error("unknown error",{cause:t});s.code==="ERR_STREAM_PREMATURE_CLOSE"?console.info("The user aborted a request."):(console.error(t),e.headersSent||e.writeHead(500,{"Content-Type":"text/plain"}),e.end(`Error: ${s.message}`),e.destroy(s))},Xt=t=>{"flushHeaders"in t&&t.writable&&t.flushHeaders()},Yt=async(t,e)=>{let[s,r,o]=t[A];o instanceof Headers&&(o=Jt(o)),typeof r=="string"?o["Content-Length"]=Buffer.byteLength(r):r instanceof Uint8Array?o["Content-Length"]=r.byteLength:r instanceof Blob&&(o["Content-Length"]=r.size),e.writeHead(s,o),typeof r=="string"||r instanceof Uint8Array?e.end(r):r instanceof Blob?e.end(new Uint8Array(await r.arrayBuffer())):(Xt(e),await Je(r,e)?.catch(n=>yt(n,e))),e[bt]?.()},tr=t=>typeof t.then=="function",er=async(t,e,s={})=>{if(tr(t))if(s.errorHandler)try{t=await t}catch(o){let n=await s.errorHandler(o);if(!n)return;t=n}else t=await t.catch(Qt);if(A in t)return Yt(t,e);let r=Jt(t.headers);if(t.body){let o=t.body.getReader(),n=[],a=!1,i;if(r["transfer-encoding"]!=="chunked"){let u=2;for(let c=0;c<u;c++){i||=o.read();let l=await Ke(i).catch(h=>{console.error(h),a=!0});if(!l){if(c===1){await new Promise(h=>setTimeout(h)),u=3;continue}break}if(i=void 0,l.value&&n.push(l.value),l.done){a=!0;break}}a&&!("content-length"in r)&&(r["content-length"]=n.reduce((c,l)=>c+l.length,0))}e.writeHead(t.status,r),n.forEach(u=>{e.write(u)}),a?e.end():(n.length===0&&Xt(e),await Kt(o,e,i))}else r[Qe]||(e.writeHead(t.status,r),e.end());e[bt]?.()},rr=(t,e={})=>{let s=e.autoCleanupIncoming??!0;return e.overrideGlobalObjects!==!1&&global.Request!==_&&(Object.defineProperty(global,"Request",{value:_}),Object.defineProperty(global,"Response",{value:F})),async(r,o)=>{let n,a;try{a=We(r,e.hostname);let i=!s||r.method==="GET"||r.method==="HEAD";if(i||(r[Vt]=!0,r.on("end",()=>{i=!0}),r instanceof $e&&(o[bt]=()=>{i||setTimeout(()=>{i||setTimeout(()=>{r.destroy(),o.destroy()})})})),o.on("close",()=>{a[T]&&(r.errored?a[T].abort(r.errored.toString()):o.writableFinished||a[T].abort("Client connection prematurely closed.")),i||setTimeout(()=>{i||setTimeout(()=>{r.destroy()})})}),n=t(a,{incoming:r,outgoing:o}),A in n)return Yt(n,o)}catch(i){if(n)return yt(i,o);if(e.errorHandler){if(n=await e.errorHandler(a?i:Ne(i)),!n)return}else a?n=Qt(i):n=Ze()}try{return await er(n,o,e)}catch(i){return yt(i,o)}}},sr=t=>{let e=t.fetch,s=rr(e,{hostname:t.hostname,overrideGlobalObjects:t.overrideGlobalObjects,autoCleanupIncoming:t.autoCleanupIncoming});return(t.createServer||Le)(t.serverOptions||{},s)},Zt=(t,e)=>{let s=sr(t);return s.listen(t?.port??3e3,t.hostname,()=>{let r=s.address();e&&e(r)}),s};import{readFileSync as or,existsSync as nr}from"node:fs";function te(){let t=process.env.MOLNOS_RUNTIME_CONFIG;if(!t||!nr(t))return{molnos:{dataPath:"data"},server:{host:"localhost",port:3e3}};try{let e=or(t,"utf-8");return JSON.parse(e)}catch(e){return console.error("[loadRuntimeConfig] Failed to load runtime config:",e),{molnos:{dataPath:"data"},server:{host:"localhost",port:3e3}}}}var M=class extends Error{constructor(e){super(),this.name="NotFoundError",this.message=e||"Resource not found",this.cause={statusCode:404}}};function y(t,e="An error occurred"){let s=t?.message||t||e,r=t?.cause?.statusCode||t?.statusCode||400;return{message:s,status:r}}function ee(t,e,s={}){let r=Array.isArray(e)?e:[e];if(!t||!t.roles||!Array.isArray(t.roles)){let a=new Error("Unauthorized: User or roles missing");throw a.cause={statusCode:403},a}let o=t.roles.flatMap(a=>a?.policies?.flatMap(i=>(i?.permissions||[]).flatMap(c=>typeof c=="string"?c:c&&typeof c=="object"&&c.actions?c.actions:[]))||[]);if(!r.every(a=>o.includes(a)||o.includes("*")?!0:o.some(i=>{if(i.endsWith(".*")){let u=i.slice(0,-2);return a.startsWith(`${u}.`)}return!1}))){let a=new Error("Unauthorized");throw a.cause={statusCode:403},a}return!0}function re(t,e,s,r,o){let n=t.find(u=>u.service===e);if(!n){let u=new Error(`Function bindings do not include access to service: ${e}`);throw u.cause={statusCode:403},u}if(!n.permissions||n.permissions.length===0)return;for(let u of n.permissions)if(!(u.resource&&u.resource!==s)){if(!u.resource||!u.actions||u.actions.length===0)return;if(u.actions.includes(r)){if(u.targets&&u.targets.length>0){if(!o)return;if(!u.targets.includes(o))continue}return}}let a=o?`:${o}`:"",i=new Error(`Function bindings do not allow: ${e}.${s}.${r}${a}`);throw i.cause={statusCode:403},i}async function g(t,e,s,r,o,n,a){if(!e)return null;let i=t.get("user");if(!i){let c=t.req.header("authorization");if(!c){let h=new Error("Unauthorized: No authentication provided");throw h.cause={statusCode:401},h}let l=c.replace(/^Bearer\s+/i,"");if(i=await e.getUserFromToken(l),!i){let h=new Error("Unauthorized: Invalid token");throw h.cause={statusCode:401},h}}ee(i,s,{});let u=t.req.header("x-function-bindings");if(u)try{let c=JSON.parse(u);re(c,r,o,n,a)}catch(c){if(c.cause?.statusCode===403)throw c;let l=new Error("Invalid function bindings header");throw l.cause={statusCode:400},l}return i}async function se(t,e,s){try{await g(t,s,"storage.bucket.list","storage","bucket","list");let r=await e.listBuckets();return t.json({buckets:r},200)}catch(r){let{message:o,status:n}=y(r,"Error listing buckets");return t.json({error:o},n)}}var E=class{isSilent;propertyPath="";constructor(t=!1){this.isSilent=t}test(t,e){if(!e)throw new Error("Missing input!");this.updatePropertyPath();let{results:s,errors:r}=this.validate(t.properties,e),o=this.compileErrors(s,r),n=this.isSuccessful(s,o);return{errors:o,success:n}}compileErrors(t,e){let s=t.filter(r=>r.success===!1);return[...e,...s].flatMap(r=>r)}isSuccessful(t,e){return t.every(s=>s.success===!0)&&e.length===0}validate(t,e,s=[],r=[]){let o=t?.additionalProperties??!0,n=t?.required||[];r=this.checkForRequiredKeysErrors(n,e,r),r=this.checkForDisallowedProperties(Object.keys(e),Object.keys(t),r,o);for(let a in t){let i=n.includes(a)&&a!=="required",u=t[a],c=e[a],l=u.additionalProperties??!0;i&&(r=this.checkForRequiredKeysErrors(u.required||[],c,r)),this.isDefined(c)&&(this.handleValidation(a,c,u,s),r=this.checkForDisallowedProperties(Object.keys(c),Object.keys(u),r,l),this.handleNestedObject(c,u,s,r))}return{results:s,errors:r}}updatePropertyPath(t,e=""){if(!t){this.propertyPath="";return}e&&(this.propertyPath=e),this.propertyPath=`${this.propertyPath}.${t}`,this.propertyPath.startsWith(".")&&(this.propertyPath=this.propertyPath.substring(1,this.propertyPath.length))}isDefined(t){return!!(typeof t=="number"&&t===0||t||t===""||typeof t=="boolean")}checkForRequiredKeysErrors(t,e,s){if(!this.areRequiredKeysPresent(t,e)){let r=e?Object.keys(e):[],o=this.findNonOverlappingElements(t,r),n=o.length>0?`Missing the required key: '${o.join(", ")}'!`:`Missing values for required keys: '${r.filter(a=>!e[a]).join(", ")}'!`;s.push({key:"",value:e,success:!1,error:n})}return s}checkForDisallowedProperties(t,e,s,r){if(!r){let o=this.findNonOverlappingElements(t,e);o.length>0&&s.push({key:`${e}`,value:t,success:!1,error:`Has additional (disallowed) properties: '${o.join(", ")}'!`})}return s}handleValidation(t,e,s,r){this.updatePropertyPath(t);let o=this.validateProperty(this.propertyPath,s,e);r.push(...o);let n=(i,u)=>{i.forEach(c=>{let l=this.validateProperty(this.propertyPath,u.items,c);r.push(...l)}),this.updatePropertyPath()},a=i=>{let u=Object.keys(i),c=this.propertyPath;u.forEach(l=>{if(this.updatePropertyPath(l,c),this.isArray(i[l])&&s[l]?.items!=null)n(i[l],s[l]);else{let h=this.validateProperty(this.propertyPath,s[l],i[l]);r.push(...h)}})};this.isArray(e)&&s.items!=null?n(e,s):this.isObject(e)?a(e):this.updatePropertyPath()}handleNestedObject(t,e,s,r){if(this.isObject(t)){let o=this.getNestedObjects(t);for(let n of o){let a=e[n],i=t[n];a&&typeof i=="object"&&this.validate(a,i,s,r)}}}getNestedObjects(t){return Object.keys(t).filter(e=>{if(this.isObject(t))return e})}findNonOverlappingElements(t,e){return t.filter(s=>!e.includes(s))}areRequiredKeysPresent(t,e=[]){return t.every(s=>Object.keys(e).includes(s)?this.isDefined(e[s]):!1)}validateProperty(t,e,s){return this.validateInput(e,s).map(o=>{let{success:n,error:a}=o;return{key:t,value:s,success:n,error:a??""}})}validateInput(t,e){if(t){let s=[{condition:()=>t.type,validator:()=>this.isCorrectType(t.type,e),error:"Invalid type"},{condition:()=>t.format,validator:()=>this.isCorrectFormat(t.format,e),error:"Invalid format"},{condition:()=>t.minLength,validator:()=>this.isMinimumLength(t.minLength,e),error:"Length too short"},{condition:()=>t.maxLength,validator:()=>this.isMaximumLength(t.maxLength,e),error:"Length too long"},{condition:()=>t.minValue,validator:()=>this.isMinimumValue(t.minValue,e),error:"Value too small"},{condition:()=>t.maxValue,validator:()=>this.isMaximumValue(t.maxValue,e),error:"Value too large"},{condition:()=>t.matchesPattern,validator:()=>this.matchesPattern(t.matchesPattern,e),error:"Pattern does not match"}],r=[];for(let o of s)o.condition()&&!o.validator()&&r.push({success:!1,error:o.error});return r}else this.isSilent||console.warn(`Missing property '${t}' for match '${e}'. Skipping...`);return[{success:!0}]}isCorrectType(t,e){return Array.isArray(t)||(t=[t]),t.some(s=>{switch(s){case"string":return typeof e=="string";case"number":return typeof e=="number"&&!isNaN(e);case"boolean":return typeof e=="boolean";case"object":return this.isObject(e);case"array":return this.isArray(e)}})}isObject(t){return t!==null&&!this.isArray(t)&&typeof t=="object"&&t instanceof Object&&Object.prototype.toString.call(t)==="[object Object]"}isArray(t){return Array.isArray(t)}isCorrectFormat(t,e){switch(t){case"alphanumeric":return new RegExp(/^[a-zA-Z0-9]+$/).test(e);case"numeric":return new RegExp(/^-?\d+(\.\d+)?$/).test(e);case"email":return new RegExp(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/).test(e);case"date":return new RegExp(/^\d{4}-\d{2}-\d{2}$/).test(e);case"url":return new RegExp(/^(https?):\/\/[^\s$.?#].[^\s]*$/).test(e);case"hexColor":return new RegExp(/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i).test(e)}}isMinimumLength(t,e){return Array.isArray(e)?e.length>=t:e?.toString().length>=t}isMaximumLength(t,e){return Array.isArray(e)?e.length<=t:e.toString().length<=t}isMinimumValue(t,e){return e>=t}isMaximumValue(t,e){return e<=t}matchesPattern(t,e){return new RegExp(t).test(e)}schemaFrom(t){let e={properties:{additionalProperties:!1,required:[]}};for(let s in t){let r=t[s];e.properties.required.push(s),Array.isArray(r)?e.properties[s]=this.generateArraySchema(r):typeof r=="object"&&r!==null?e.properties[s]=this.generateNestedObjectSchema(r):e.properties[s]=this.generatePropertySchema(r)}return e}generateArraySchema(t){let e={type:"array"},s=t.filter(r=>r);if(s.length>0){let r=s[0];s.every(n=>typeof n==typeof r)?typeof r=="object"&&!Array.isArray(r)?e.items=this.generateNestedObjectSchema(r):e.items=this.generatePropertySchema(r):console.warn("All elements in array are not of the same type. Unable to generate a schema for these elements.")}return e}generateNestedObjectSchema(t){let e={type:"object",additionalProperties:!1,required:[]};for(let s in t){let r=t[s];e.required.push(s),typeof r=="object"&&!Array.isArray(r)&&r!==null?e[s]=this.generateNestedObjectSchema(r):e[s]=this.generatePropertySchema(r)}return e}generatePropertySchema(t){let e=typeof t,s={type:e};return e==="string"&&(s.minLength=1),s}};async function I(t){try{return await t.req.json()}catch{return{}}}var oe={properties:{public:{type:"boolean"}},additionalProperties:!1};var ir=new E;async function ne(t,e,s){try{let{bucket:r}=t.req.param();if(!r)return t.json({error:"bucket parameter is required"},400);let o=await I(t),n=ir.test(oe,o||{});if(!n.success)return t.json({error:"Invalid input",details:n.errors},400);await g(t,s,"storage.bucket.create","storage","bucket","create");let{public:a}=o||{};return await e.createBucket(r,a),t.json({success:!0,bucket:r,public:a||!1},200)}catch(r){let{message:o,status:n}=y(r,"Error creating bucket");return t.json({error:o},n)}}async function ae(t,e,s){try{let{bucket:r}=t.req.param();if(!r)return t.json({error:"bucket parameter is required"},400);await g(t,s,"storage.bucket.read","storage","bucket","read",r);let o=await e.getBucketStats(r),n=await e.isBucketPublic(r);return t.json({bucket:r,...o,public:n},200)}catch(r){let{message:o,status:n}=y(r,"Error getting bucket stats");return t.json({error:o},n)}}var ie={properties:{public:{type:"boolean"}},required:["public"],additionalProperties:!1};var ur=new E;async function ce(t,e,s){try{let{bucket:r}=t.req.param();if(!r)return t.json({error:"bucket parameter is required"},400);let o;try{o=await t.req.json()}catch{return t.json({error:"Invalid JSON body"},400)}let{public:n}=o;if(n===void 0)return t.json({error:"No valid configuration provided"},400);let a=ur.test(ie,o);if(!a.success)return t.json({error:"Invalid input",details:a.errors},400);if(await g(t,s,"storage.bucket.update","storage","bucket","update",r),!await e.bucketExists(r))return t.json({error:"Bucket not found"},404);await e.updateBucket(r,{public:n});let u=await e.isBucketPublic(r);return t.json({success:!0,bucket:r,public:u},200)}catch(r){let{message:o,status:n}=y(r,"Error updating bucket");return t.json({error:o},n)}}async function ue(t,e,s){try{let{bucket:r}=t.req.param();return r?(await g(t,s,"storage.bucket.delete","storage","bucket","delete",r),await e.bucketExists(r)?(await e.deleteBucket(r),t.json({success:!0,bucket:r},200)):t.json({error:"Bucket not found"},404)):t.json({error:"bucket parameter is required"},400)}catch(r){let{message:o,status:n}=y(r,"Error deleting bucket");return t.json({error:o},n)}}async function le(t,e,s){try{let{bucket:r}=t.req.param();if(!r)return t.json({error:"bucket parameter is required"},400);let o=t.req.query("prefix")||"";await g(t,s,"storage.object.list","storage","object","list");let n=await e.listObjects(r,o);return t.json({objects:n,prefix:o},200)}catch(r){let{message:o,status:n}=y(r,"Error listing objects");return t.json({error:o},n)}}var he={properties:{key:{type:"string",minLength:1},content:{type:"string"}},required:["key"],additionalProperties:!1};var hr=new E;async function de(t,e,s){try{let{bucket:r}=t.req.param(),o=t.req.header("content-type")||"";if(!r)return t.json({error:"bucket parameter is required"},400);if(await g(t,s,"storage.object.write","storage","object","write"),o.includes("multipart/form-data")){let c=await t.req.formData(),l=c.get("file"),h=c.get("key");if(!h)return t.json({error:"key is required"},400);if(!l)return t.json({error:"file is required"},400);let d=await l.arrayBuffer(),m=Buffer.from(d);return await e.putObject(r,h,m),t.json({success:!0,bucket:r,key:h},200)}if(o.includes("application/octet-stream")||o.includes("video/")||o.includes("image/")){let c=t.req.query("key");if(!c)return t.json({error:"key query parameter is required for binary uploads"},400);let l=await t.req.arrayBuffer(),h=Buffer.from(l);return await e.putObject(r,c,h),t.json({success:!0,bucket:r,key:c},200)}let n=await t.req.json(),a=hr.test(he,n);if(!a.success)return t.json({error:"Invalid input",details:a.errors},400);let{key:i,content:u}=n;return i?u?(await e.putObject(r,i,u),t.json({success:!0,bucket:r,key:i},200)):t.json({error:"content is required"},400):t.json({error:"key is required"},400)}catch(r){let{message:o,status:n}=y(r,"Error storing object");return t.json({error:o},n)}}var fe={properties:{key:{type:"string",minLength:1}},required:["key"],additionalProperties:!1};var fr=new E;async function pe(t,e,s){try{let{bucket:r}=t.req.param();if(!r)return t.json({error:"bucket parameter is required"},400);let o=await I(t),n=fr.test(fe,o);if(!n.success)return t.json({error:"Invalid input",details:n.errors},400);await g(t,s,"storage.object.read","storage","object","read");let{key:a}=o;if(!await e.objectExists(r,a))return t.json({error:"Object not found"},404);let u=await e.getObject(r,a);return t.json({bucket:r,key:a,content:u.toString()},200)}catch(r){let{message:o,status:n}=y(r,"Error getting object");return t.json({error:o},n)}}var me={properties:{key:{type:"string",minLength:1}},required:["key"],additionalProperties:!1};var mr=new E;async function ye(t,e,s){try{let{bucket:r}=t.req.param();if(!r)return t.json({error:"bucket parameter is required"},400);let o=await I(t),n=mr.test(me,o);if(!n.success)return t.json({error:"Invalid input",details:n.errors},400);await g(t,s,"storage.object.delete","storage","object","delete");let{key:a}=o;return await e.objectExists(r,a)?(await e.deleteObject(r,a),t.json({success:!0,bucket:r,key:a},200)):t.json({error:"Object not found"},404)}catch(r){let{message:o,status:n}=y(r,"Error deleting object");return t.json({error:o},n)}}function yr(t){let e=t.split(".").pop()?.toLowerCase();return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",pdf:"application/pdf",json:"application/json",txt:"text/plain",html:"text/html",css:"text/css",js:"application/javascript",mp4:"video/mp4",webm:"video/webm",mp3:"audio/mpeg",wav:"audio/wav"}[e||""]||"application/octet-stream"}async function ge(t,e,s){try{let{bucket:r}=t.req.param(),n=t.req.path.match(/^\/buckets\/[^/]+\/objects\/(.+)$/);if(!n)return t.json({error:"Invalid object path"},400);let a=decodeURIComponent(n[1]);if(!r)return t.json({error:"bucket parameter is required"},400);if(await g(t,s,"storage.object.read","storage","object","read"),!await e.objectExists(r,a))return t.json({error:"Object not found"},404);let u=await e.getObject(r,a),c=yr(a),l=new Uint8Array(u);return new Response(l,{status:200,headers:{"Content-Type":c,"Content-Length":u.length.toString()}})}catch(r){let{message:o,status:n}=y(r,"Error retrieving object");return t.json({error:o},n)}}var wt=class{rootPath;metadataPath;constructor(e){this.rootPath=e.path||"storage-data",this.metadataPath=v(this.rootPath,".metadata")}async start(){await b.mkdir(this.rootPath,{recursive:!0}),await b.mkdir(this.metadataPath,{recursive:!0})}getBucketMetadataPath(e){return v(this.metadataPath,`${e}.json`)}async readBucketMetadata(e){let s=this.getBucketMetadataPath(e);try{let r=await b.readFile(s,"utf-8");return JSON.parse(r)}catch{return{public:!1}}}async writeBucketMetadata(e,s){let r=this.getBucketMetadataPath(e);await b.writeFile(r,JSON.stringify(s,null,2))}async deleteBucketMetadata(e){let s=this.getBucketMetadataPath(e);try{await b.unlink(s)}catch{}}async putObject(e,s,r){let o=v(this.rootPath,e,s);await b.mkdir(gr(o),{recursive:!0}),await b.writeFile(o,r)}async getObject(e,s){let r=v(this.rootPath,e,s);return await b.readFile(r)}async deleteObject(e,s){let r=v(this.rootPath,e,s);await b.unlink(r)}async objectExists(e,s){let r=v(this.rootPath,e,s);try{return await b.access(r),!0}catch{return!1}}async createBucket(e,s=!1){let r=v(this.rootPath,e);await b.mkdir(r,{recursive:!0}),await this.writeBucketMetadata(e,{public:s})}async deleteBucket(e){let s=v(this.rootPath,e);await b.rm(s,{recursive:!0,force:!0}),await this.deleteBucketMetadata(e)}async bucketExists(e){let s=v(this.rootPath,e);try{return(await b.stat(s)).isDirectory()}catch{return!1}}async isBucketPublic(e){return(await this.readBucketMetadata(e)).public}async updateBucket(e,s){if(!await this.bucketExists(e))throw new Error("Bucket not found");let n={...await this.readBucketMetadata(e),...s.public!==void 0&&{public:s.public}};await this.writeBucketMetadata(e,n)}async listBuckets(){try{return(await b.readdir(this.rootPath,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name)}catch{return[]}}async getBucketStats(e){let s=v(this.rootPath,e);try{if(!(await b.stat(s)).isDirectory())throw new M("Bucket not found")}catch(a){throw a.code==="ENOENT"?new M("Bucket not found"):a}let r=0,o=0,n=async a=>{let i=await b.readdir(a,{withFileTypes:!0});for(let u of i){let c=v(a,u.name);if(u.isDirectory())await n(c);else if(u.isFile()){r++;let l=await b.stat(c);o+=l.size}}};try{await n(s)}catch{return{objectCount:0,totalSize:0}}return{objectCount:r,totalSize:o}}async listObjects(e,s=""){let r=v(this.rootPath,e);try{if(!(await b.stat(r)).isDirectory())throw new M("Bucket not found")}catch(c){throw c.code==="ENOENT"?new M("Bucket not found"):c}let o=[],n=async(c,l="")=>{let h=await b.readdir(c,{withFileTypes:!0});for(let d of h){let m=v(c,d.name),x=l?`${l}/${d.name}`:d.name;if(d.isDirectory())await n(m,x);else if(d.isFile()){let f=await b.stat(m);o.push({key:x,size:f.size,lastModified:f.mtime,type:"file"})}}};try{await n(r)}catch{return[]}let a=s?o.filter(c=>c.key.startsWith(s)):o,i=[],u=new Set;for(let c of a){let l=s?c.key.substring(s.length):c.key,h=l.indexOf("/");if(h===-1)i.push({key:l,size:c.size,lastModified:c.lastModified,type:"file"});else{let d=l.substring(0,h);u.has(d)||(u.add(d),i.push({key:`${d}/`,size:0,lastModified:c.lastModified,type:"folder"}))}}return i.sort((c,l)=>c.type!==l.type?c.type==="folder"?-1:1:c.key.localeCompare(l.key))}};async function br(t){let e=t.dataPath||"data",s=v(e,"storage"),r=new wt({path:t.storage?.path||s});await r.start();let o=t.identityService||null,n=new pt;return n.get("/buckets",async a=>se(a,r,o)),n.post("/buckets/:bucket",async a=>ne(a,r,o)),n.get("/buckets/:bucket",async a=>ae(a,r,o)),n.patch("/buckets/:bucket",async a=>ce(a,r,o)),n.delete("/buckets/:bucket",async a=>ue(a,r,o)),n.get("/buckets/:bucket/objects",async a=>le(a,r,o)),n.put("/buckets/:bucket/objects",async a=>de(a,r,o)),n.post("/buckets/:bucket/objects",async a=>pe(a,r,o)),n.delete("/buckets/:bucket/objects",async a=>ye(a,r,o)),n.get("/buckets/:bucket/objects/*",async a=>ge(a,r,o)),Zt({fetch:n.fetch,port:t.server.port||3001,hostname:t.server.host||"localhost"}),console.log(`Storage server started on ${t.server.host||"localhost"}:${t.server.port||3001}`),n}var wr=process.argv.slice(2),be=wr.find(t=>t.startsWith("--port=")),vr=be?parseInt(be.split("=")[1],10):3001,we=te(),xr={molnos:{dataPath:we.molnos.dataPath},storage:{},server:{port:vr,host:we.server.host}};br(xr);export{br as startServer};
2
+ var $=class{requests=new Map;limit;windowMs;constructor(t=100,e=60){this.limit=t,this.windowMs=e*1e3,setInterval(()=>this.cleanup(),this.windowMs)}getLimit(){return this.limit}isAllowed(t){let e=Date.now(),s=t||"unknown",r=this.requests.get(s);return(!r||r.resetTime<e)&&(r={count:0,resetTime:e+this.windowMs},this.requests.set(s,r)),r.count++,r.count<=this.limit}getRemainingRequests(t){let e=Date.now(),s=t||"unknown",r=this.requests.get(s);return!r||r.resetTime<e?this.limit:Math.max(0,this.limit-r.count)}getResetTime(t){let e=Date.now(),s=t||"unknown",r=this.requests.get(s);return!r||r.resetTime<e?Math.floor((e+this.windowMs)/1e3):Math.floor(r.resetTime/1e3)}cleanup(){let t=Date.now();for(let[e,s]of this.requests.entries())s.resetTime<t&&this.requests.delete(e)}};import{URL as dt}from"url";var H=class{routes=[];globalMiddlewares=[];pathPatterns=new Map;use(t){return this.globalMiddlewares.push(t),this}get(t,...e){let s=e.pop();return this.register("GET",t,s,e)}post(t,...e){let s=e.pop();return this.register("POST",t,s,e)}put(t,...e){let s=e.pop();return this.register("PUT",t,s,e)}delete(t,...e){let s=e.pop();return this.register("DELETE",t,s,e)}patch(t,...e){let s=e.pop();return this.register("PATCH",t,s,e)}any(t,...e){let s=e.pop(),r=e;return this.register("GET",t,s,r),this.register("POST",t,s,r),this.register("PUT",t,s,r),this.register("DELETE",t,s,r),this.register("PATCH",t,s,r),this.register("OPTIONS",t,s,r),this}options(t,...e){let s=e.pop();return this.register("OPTIONS",t,s,e)}match(t,e){for(let s of this.routes){if(s.method!==t)continue;let r=this.pathPatterns.get(s.path);if(!r)continue;let o=r.pattern.exec(e);if(!o)continue;let n={};return r.paramNames.forEach((i,c)=>{n[i]=o[c+1]||""}),{route:s,params:n}}return null}async handle(t,e){let s=t.method||"GET",r=new dt(t.url||"/",`http://${t.headers.host}`),o=r.pathname,n=this.match(s,o);if(!n)return null;let{route:i,params:c}=n,a={};r.searchParams.forEach((u,d)=>{a[d]=u});let l={req:t,res:e,params:c,query:a,body:t.body||{},headers:t.headers,path:o,state:{},raw:()=>e,binary:(u,d="application/octet-stream",h=200)=>({statusCode:h,body:u,headers:{"Content-Type":d,"Content-Length":u.length.toString()},isRaw:!0}),text:(u,d=200)=>({statusCode:d,body:u,headers:{"Content-Type":"text/plain"}}),form:(u,d=200)=>({statusCode:d,body:u,headers:{"Content-Type":"application/x-www-form-urlencoded"}}),json:(u,d=200)=>({statusCode:d,body:u,headers:{"Content-Type":"application/json"}}),html:(u,d=200)=>({statusCode:d,body:u,headers:{"Content-Type":"text/html"}}),redirect:(u,d=302)=>({statusCode:d,body:null,headers:{Location:u}}),status:function(u){return{raw:()=>e,binary:(d,h="application/octet-stream")=>({statusCode:u,body:d,headers:{"Content-Type":h,"Content-Length":d.length.toString()},isRaw:!0}),text:d=>({statusCode:u,body:d,headers:{"Content-Type":"text/plain"}}),json:d=>({statusCode:u,body:d,headers:{"Content-Type":"application/json"}}),html:d=>({statusCode:u,body:d,headers:{"Content-Type":"text/html"}}),form:d=>({statusCode:u,body:d,headers:{"Content-Type":"application/x-www-form-urlencoded"}}),redirect:(d,h=302)=>({statusCode:h,body:null,headers:{Location:d}}),status:d=>this.status(d)}}},f=[...this.globalMiddlewares,...i.middlewares];return this.executeMiddlewareChain(l,f,i.handler)}register(t,e,s,r=[]){return this.routes.push({method:t,path:e,handler:s,middlewares:r}),this.pathPatterns.set(e,this.createPathPattern(e)),this}createPathPattern(t){let e=[],s=t.replace(/\/:[^/]+/g,r=>{let o=r.slice(2);return e.push(o),"/([^/]+)"});return s.endsWith("/*")?(s=`${s.slice(0,-2)}(?:/(.*))?`,e.push("wildcard")):s=s.replace(/\/$/,"/?"),{pattern:new RegExp(`^${s}$`),paramNames:e}}async executeMiddlewareChain(t,e,s){let r=0,o=async()=>{if(r<e.length){let n=e[r++];return n(t,o)}return s(t)};return o()}};var E=()=>({port:Number(process.env.PORT)||3e3,host:process.env.HOST||"0.0.0.0",useHttps:!1,useHttp2:!1,sslCert:"",sslKey:"",sslCa:"",debug:ft(process.env.DEBUG)||!1,maxBodySize:1048576,requestTimeout:3e4,rateLimit:{enabled:!0,requestsPerMinute:100},allowedDomains:["*"]});function ft(t){return t==="true"||t===!0}var O=class extends Error{constructor(t){super(t),this.name="ValidationError",this.message=t||"Validation did not pass",this.cause={statusCode:400}}};import{existsSync as pt,readFileSync as mt}from"node:fs";var I=class{config={};options=[];validators=[];autoValidate=!0;constructor(t){let e=t?.configFilePath,s=t?.args||[],r=t?.config||{};this.options=t?.options||[],this.validators=t?.validators||[],t?.autoValidate!==void 0&&(this.autoValidate=t.autoValidate),this.config=this.createConfig(e,s,r)}deepMerge(t,e){let s={...t};for(let r in e)e[r]!==void 0&&(e[r]!==null&&typeof e[r]=="object"&&!Array.isArray(e[r])&&r in t&&t[r]!==null&&typeof t[r]=="object"&&!Array.isArray(t[r])?s[r]=this.deepMerge(t[r],e[r]):e[r]!==void 0&&(s[r]=e[r]));return s}setValueAtPath(t,e,s){let r=e.split("."),o=t;for(let i=0;i<r.length-1;i++){let c=r[i];!(c in o)||o[c]===null?o[c]={}:typeof o[c]!="object"&&(o[c]={}),o=o[c]}let n=r[r.length-1];o[n]=s}getValueAtPath(t,e){let s=e.split("."),r=t;for(let o of s){if(r==null)return;r=r[o]}return r}createConfig(t,e=[],s={}){let r={};for(let c of this.options)c.defaultValue!==void 0&&this.setValueAtPath(r,c.path,c.defaultValue);let o={};if(t&&pt(t))try{let c=mt(t,"utf8");o=JSON.parse(c),console.log(`Loaded configuration from ${t}`)}catch(c){console.error(`Error reading config file: ${c instanceof Error?c.message:String(c)}`)}let n=this.parseCliArgs(e),i=this.deepMerge({},r);return i=this.deepMerge(i,o),i=this.deepMerge(i,s),i=this.deepMerge(i,n),i}parseCliArgs(t){let e={},s=t[0]?.endsWith("node")||t[0]?.endsWith("node.exe")?2:0;for(;s<t.length;){let r=t[s++],o=this.options.find(n=>n.flag===r);if(o)if(o.isFlag)this.setValueAtPath(e,o.path,!0);else if(s<t.length&&!t[s].startsWith("-")){let n=t[s++];if(o.parser)try{n=o.parser(n)}catch(i){console.error(`Error parsing value for ${o.flag}: ${i instanceof Error?i.message:String(i)}`);continue}if(o.validator){let i=o.validator(n);if(i!==!0&&typeof i=="string"){console.error(`Invalid value for ${o.flag}: ${i}`);continue}if(i===!1){console.error(`Invalid value for ${o.flag}`);continue}}this.setValueAtPath(e,o.path,n)}else console.error(`Missing value for option ${r}`)}return e}validate(){for(let t of this.validators){let e=this.getValueAtPath(this.config,t.path),s=t.validator(e,this.config);if(s===!1)throw new O(t.message);if(typeof s=="string")throw new O(s)}}get(){return this.autoValidate&&this.validate(),this.config}getValue(t,e){let s=this.getValueAtPath(this.config,t);return s!==void 0?s:e}setValue(t,e){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){let s=this.getValueAtPath(this.config,t)||{};if(typeof s=="object"&&!Array.isArray(s)){let r=this.deepMerge(s,e);this.setValueAtPath(this.config,t,r);return}}this.setValueAtPath(this.config,t,e)}getHelpText(){let t=`Available configuration options:
3
+
4
+ `;for(let e of this.options)t+=`${e.flag}${e.isFlag?"":" <value>"}
5
+ `,e.description&&(t+=` ${e.description}
6
+ `),e.defaultValue!==void 0&&(t+=` Default: ${JSON.stringify(e.defaultValue)}
7
+ `),t+=`
8
+ `;return t}};var B={int:t=>{let e=t.trim();if(!/^[+-]?\d+$/.test(e))throw new Error(`Cannot parse "${t}" as an integer`);let s=Number.parseInt(e,10);if(Number.isNaN(s))throw new Error(`Cannot parse "${t}" as an integer`);return s},float:t=>{let e=t.trim();if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(e)){if(e==="Infinity"||e==="-Infinity")return e==="Infinity"?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY;throw new Error(`Cannot parse "${t}" as a number`)}let s=Number.parseFloat(e);if(Number.isNaN(s))throw new Error(`Cannot parse "${t}" as a number`);return s},boolean:t=>{let e=t.trim().toLowerCase();if(["true","yes","1","y"].includes(e))return!0;if(["false","no","0","n"].includes(e))return!1;throw new Error(`Cannot parse "${t}" as a boolean`)},array:t=>t.split(",").map(e=>e.trim()),json:t=>{try{return JSON.parse(t)}catch{throw new Error(`Cannot parse "${t}" as JSON`)}}};var v=E(),L=t=>({configFilePath:"mikroserve.config.json",args:process.argv,options:[{flag:"--port",path:"port",defaultValue:v.port},{flag:"--host",path:"host",defaultValue:v.host},{flag:"--https",path:"useHttps",defaultValue:v.useHttps,isFlag:!0},{flag:"--http2",path:"useHttp2",defaultValue:v.useHttp2,isFlag:!0},{flag:"--cert",path:"sslCert",defaultValue:v.sslCert},{flag:"--key",path:"sslKey",defaultValue:v.sslKey},{flag:"--ca",path:"sslCa",defaultValue:v.sslCa},{flag:"--ratelimit",path:"rateLimit.enabled",defaultValue:v.rateLimit.enabled,isFlag:!0},{flag:"--rps",path:"rateLimit.requestsPerMinute",defaultValue:v.rateLimit.requestsPerMinute},{flag:"--allowed",path:"allowedDomains",defaultValue:v.allowedDomains,parser:B.array},{flag:"--debug",path:"debug",defaultValue:v.debug,isFlag:!0},{flag:"--max-body-size",path:"maxBodySize",defaultValue:v.maxBodySize},{flag:"--request-timeout",path:"requestTimeout",defaultValue:v.requestTimeout}],config:t});function q(t,e){let s=e.match(/boundary=(?:"([^"]+)"|([^;]+))/i);if(!s)throw new Error("Invalid multipart/form-data: missing boundary");let r=s[1]||s[2],o=Buffer.from(`--${r}`),n=Buffer.from(`--${r}--`),i={},c={},a=ht(t,o);for(let l of a){if(l.length===0||l.equals(n.subarray(o.length)))continue;let f=gt(l);if(!f)continue;let{name:u,filename:d,contentType:h,data:m}=f;if(d){let p={filename:d,contentType:h||"application/octet-stream",data:m,size:m.length};c[u]?Array.isArray(c[u])?c[u].push(p):c[u]=[c[u],p]:c[u]=p}else{let p=m.toString("utf8");i[u]?Array.isArray(i[u])?i[u].push(p):i[u]=[i[u],p]:i[u]=p}}return{fields:i,files:c}}function ht(t,e){let s=[],r=0;for(;r<t.length;){let o=t.indexOf(e,r);if(o===-1)break;r!==o&&s.push(t.subarray(r,o)),r=o+e.length,r<t.length&&t[r]===13&&t[r+1]===10&&(r+=2)}return s}function gt(t){let e=Buffer.from(`\r
9
+ \r
10
+ `),s=t.indexOf(e);if(s===-1)return null;let r=t.subarray(0,s),o=t.subarray(s+4),i=r.toString("utf8").split(`\r
11
+ `),c="",a="",l,f;for(let d of i){let h=d.toLowerCase();if(h.startsWith("content-disposition:")){c=d.substring(20).trim();let m=c.match(/name="([^"]+)"/);m&&(a=m[1]);let p=c.match(/filename="([^"]+)"/);p&&(l=p[1])}else h.startsWith("content-type:")&&(f=d.substring(13).trim())}if(!a)return null;let u=o;return u.length>=2&&u[u.length-2]===13&&u[u.length-1]===10&&(u=u.subarray(0,u.length-2)),{disposition:c,name:a,filename:l,contentType:f,data:u}}import{readFileSync as P}from"fs";import M from"http";import yt from"http2";import bt from"https";var T=class{config;rateLimiter;router;shutdownHandlers=[];constructor(t){let e=new I(L(t||{})).get();e.debug&&console.log("Using configuration:",e),this.config=e,this.router=new H;let s=e.rateLimit.requestsPerMinute||E().rateLimit.requestsPerMinute;this.rateLimiter=new $(s,60),e.rateLimit.enabled===!0&&this.use(this.rateLimitMiddleware.bind(this))}use(t){return this.router.use(t),this}get(t,...e){return this.router.get(t,...e),this}post(t,...e){return this.router.post(t,...e),this}put(t,...e){return this.router.put(t,...e),this}delete(t,...e){return this.router.delete(t,...e),this}patch(t,...e){return this.router.patch(t,...e),this}any(t,...e){return this.router.any(t,...e),this}options(t,...e){return this.router.options(t,...e),this}start(){let t=this.createServer(),{port:e,host:s}=this.config;return this.setupGracefulShutdown(t),t.listen(e,s,()=>{let r=t.address(),o=this.config.useHttps||this.config.useHttp2?"https":"http";console.log(`MikroServe running at ${o}://${r.address!=="::"?r.address:"localhost"}:${r.port}`)}),t}createServer(){let t=this.requestHandler.bind(this);if(this.config.useHttp2){if(!this.config.sslCert||!this.config.sslKey)throw new Error("SSL certificate and key paths are required when useHttp2 is true");try{let e={key:P(this.config.sslKey),cert:P(this.config.sslCert),...this.config.sslCa?{ca:P(this.config.sslCa)}:{}};return yt.createSecureServer(e,t)}catch(e){throw e.message.includes("key values mismatch")?new Error(`SSL certificate and key do not match: ${e.message}`):e}}else if(this.config.useHttps){if(!this.config.sslCert||!this.config.sslKey)throw new Error("SSL certificate and key paths are required when useHttps is true");try{let e={key:P(this.config.sslKey),cert:P(this.config.sslCert),...this.config.sslCa?{ca:P(this.config.sslCa)}:{}};return bt.createServer(e,t)}catch(e){throw e.message.includes("key values mismatch")?new Error(`SSL certificate and key do not match: ${e.message}`):e}}return M.createServer(t)}async rateLimitMiddleware(t,e){let s=t.req.socket.remoteAddress||"unknown";return t.res.setHeader("X-RateLimit-Limit",this.rateLimiter.getLimit().toString()),t.res.setHeader("X-RateLimit-Remaining",this.rateLimiter.getRemainingRequests(s).toString()),t.res.setHeader("X-RateLimit-Reset",this.rateLimiter.getResetTime(s).toString()),this.rateLimiter.isAllowed(s)?e():{statusCode:429,body:{error:"Too Many Requests",message:"Rate limit exceeded, please try again later"},headers:{"Content-Type":"application/json"}}}async requestHandler(t,e){let s=Date.now(),r=t.method||"UNKNOWN",o=t.url||"/unknown",n=this.config.debug;try{if(this.setCorsHeaders(e,t),this.setSecurityHeaders(e,this.config.useHttps),n&&console.log(`${r} ${o}`),t.method==="OPTIONS"){if(e instanceof M.ServerResponse)e.statusCode=204,e.end();else{let c=e;c.writeHead(204),c.end()}return}try{t.body=await this.parseBody(t)}catch(c){return n&&console.error("Body parsing error:",c.message),this.respond(e,{statusCode:400,body:{error:"Bad Request",message:c.message}})}let i=await this.router.handle(t,e);return i?i._handled?void 0:this.respond(e,i):this.respond(e,{statusCode:404,body:{error:"Not Found",message:"The requested endpoint does not exist"}})}catch(i){return console.error("Server error:",i),this.respond(e,{statusCode:500,body:{error:"Internal Server Error",message:n?i.message:"An unexpected error occurred"}})}finally{n&&this.logDuration(s,r,o)}}logDuration(t,e,s){let r=Date.now()-t;console.log(`${e} ${s} completed in ${r}ms`)}async parseBody(t){return new Promise((e,s)=>{let r=[],o=0,n=this.config.maxBodySize,i=!1,c=null,a=this.config.debug,l=t.headers["content-type"]||"";a&&console.log("Content-Type:",l),this.config.requestTimeout>0&&(c=setTimeout(()=>{i||(i=!0,a&&console.log("Request timeout exceeded"),s(new Error("Request timeout")))},this.config.requestTimeout));let f=()=>{c&&(clearTimeout(c),c=null)};t.on("data",u=>{if(!i){if(o+=u.length,a&&console.log(`Received chunk: ${u.length} bytes, total size: ${o}`),o>n){i=!0,f(),a&&console.log(`Body size exceeded limit: ${o} > ${n}`),s(new Error("Request body too large"));return}r.push(u)}}),t.on("end",()=>{if(!i){i=!0,f(),a&&console.log(`Request body complete: ${o} bytes`);try{if(r.length>0){let u=Buffer.concat(r);if(l.includes("application/json"))try{let d=u.toString("utf8");e(JSON.parse(d))}catch(d){s(new Error(`Invalid JSON in request body: ${d.message}`))}else if(l.includes("application/x-www-form-urlencoded")){let d=u.toString("utf8"),h={};new URLSearchParams(d).forEach((m,p)=>{h[p]=m}),e(h)}else if(l.includes("multipart/form-data"))try{let d=q(u,l);e(d)}catch(d){s(new Error(`Invalid multipart form data: ${d.message}`))}else this.isBinaryContentType(l)?e(u):e(u.toString("utf8"))}else e({})}catch(u){s(new Error(`Invalid request body: ${u}`))}}}),t.on("error",u=>{i||(i=!0,f(),s(new Error(`Error reading request body: ${u.message}`)))}),t.on("close",()=>{f()})})}isBinaryContentType(t){return["application/octet-stream","application/pdf","application/zip","application/gzip","application/x-tar","application/x-rar-compressed","application/x-7z-compressed","image/","video/","audio/","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument","application/msword","application/vnd.ms-powerpoint"].some(s=>t.includes(s))}setCorsHeaders(t,e){let s=e.headers.origin,{allowedDomains:r=["*"]}=this.config;!s||r.length===0||r.includes("*")?t.setHeader("Access-Control-Allow-Origin","*"):r.includes(s)&&(t.setHeader("Access-Control-Allow-Origin",s),t.setHeader("Vary","Origin")),t.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, PATCH, OPTIONS"),t.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),t.setHeader("Access-Control-Max-Age","86400")}setSecurityHeaders(t,e=!1){let s={"X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","Content-Security-Policy":"default-src 'self'; script-src 'self'; object-src 'none'","X-XSS-Protection":"1; mode=block"};if((e||this.config.useHttp2)&&(s["Strict-Transport-Security"]="max-age=31536000; includeSubDomains"),t instanceof M.ServerResponse)Object.entries(s).forEach(([r,o])=>{t.setHeader(r,o)});else{let r=t;Object.entries(s).forEach(([o,n])=>{r.setHeader(o,n)})}}respond(t,e){let s={...e.headers||{}};(o=>typeof o.writeHead=="function"&&typeof o.end=="function")(t)?(t.writeHead(e.statusCode,s),e.body===null||e.body===void 0?t.end():e.isRaw||typeof e.body=="string"?t.end(e.body):t.end(JSON.stringify(e.body))):(console.warn("Unexpected response object type without writeHead/end methods"),t.writeHead?.(e.statusCode,s),e.body===null||e.body===void 0?t.end?.():e.isRaw||typeof e.body=="string"?t.end?.(e.body):t.end?.(JSON.stringify(e.body)))}setupGracefulShutdown(t){let e=i=>{console.log("Shutting down MikroServe server..."),i&&console.error("Error:",i),this.cleanupShutdownHandlers(),t.close(()=>{console.log("Server closed successfully"),process.env.NODE_ENV!=="test"&&process.env.VITEST!=="true"&&setImmediate(()=>process.exit(i?1:0))})},s=()=>e(),r=()=>e(),o=i=>e(i),n=i=>e(i);this.shutdownHandlers=[s,r,o,n],process.on("SIGINT",s),process.on("SIGTERM",r),process.on("uncaughtException",o),process.on("unhandledRejection",n)}cleanupShutdownHandlers(){if(this.shutdownHandlers.length>0){let[t,e,s,r]=this.shutdownHandlers;process.removeListener("SIGINT",t),process.removeListener("SIGTERM",e),process.removeListener("uncaughtException",s),process.removeListener("unhandledRejection",r),this.shutdownHandlers=[]}}};import{join as w,dirname as $t}from"node:path";import{promises as b}from"node:fs";function g(t,e="An error occurred"){let s=t?.message||t||e,r=t?.cause?.statusCode||t?.statusCode||400;return{message:s,status:r}}function N(t,e,s={}){let r=Array.isArray(e)?e:[e];if(!t||!t.roles||!Array.isArray(t.roles)){let i=new Error("Unauthorized: User or roles missing");throw i.cause={statusCode:403},i}let o=t.roles.flatMap(i=>i?.policies?.flatMap(c=>(c?.permissions||[]).flatMap(l=>typeof l=="string"?l:l&&typeof l=="object"&&l.actions?l.actions:[]))||[]);if(!r.every(i=>o.includes(i)||o.includes("*")?!0:o.some(c=>{if(c.endsWith(".*")){let a=c.slice(0,-2);return i.startsWith(`${a}.`)}return!1}))){let i=new Error("Unauthorized");throw i.cause={statusCode:403},i}return!0}function V(t,e,s,r,o){let n=t.find(a=>a.service===e);if(!n){let a=new Error(`Function bindings do not include access to service: ${e}`);throw a.cause={statusCode:403},a}if(!n.permissions||n.permissions.length===0)return;for(let a of n.permissions)if(!(a.resource&&a.resource!==s)){if(!a.resource||!a.actions||a.actions.length===0)return;if(a.actions.includes(r)){if(a.targets&&a.targets.length>0){if(!o)return;if(!a.targets.includes(o))continue}return}}let i=o?`:${o}`:"",c=new Error(`Function bindings do not allow: ${e}.${s}.${r}${i}`);throw c.cause={statusCode:403},c}async function y(t,e,s,r,o,n,i){if(!e)return null;let c=t.state.user;if(!c){let l=t.headers.authorization;if(!l){let u=new Error("Unauthorized: No authentication provided");throw u.cause={statusCode:401},u}let f=l.replace(/^Bearer\s+/i,"");if(c=await e.getUserFromToken(f),!c){let u=new Error("Unauthorized: Invalid token");throw u.cause={statusCode:401},u}}N(c,s,{});let a=t.headers["x-function-bindings"];if(a)try{let l=Array.isArray(a)?a[0]:a,f=JSON.parse(l);V(f,r,o,n,i)}catch(l){if(l.cause?.statusCode===403)throw l;let f=new Error("Invalid function bindings header");throw f.cause={statusCode:400},f}return c}async function D(t,e,s){try{await y(t,s,"storage.bucket.list","storage","bucket","list");let r=await e.listBuckets();return t.json({buckets:r},200)}catch(r){let{message:o,status:n}=g(r,"Error listing buckets");return t.json({error:o},n)}}var k=class{isSilent;propertyPath="";constructor(t=!1){this.isSilent=t}test(t,e){if(!e)throw new Error("Missing input!");this.updatePropertyPath();let{results:s,errors:r}=this.validate(t.properties,e),o=this.compileErrors(s,r),n=this.isSuccessful(s,o);return{errors:o,success:n}}compileErrors(t,e){let s=t.filter(r=>r.success===!1);return[...e,...s].flatMap(r=>r)}isSuccessful(t,e){return t.every(s=>s.success===!0)&&e.length===0}validate(t,e,s=[],r=[]){let o=t?.additionalProperties??!0,n=t?.required||[];r=this.checkForRequiredKeysErrors(n,e,r),r=this.checkForDisallowedProperties(Object.keys(e),Object.keys(t),r,o);for(let i in t){let c=n.includes(i)&&i!=="required",a=t[i],l=e[i],f=a.additionalProperties??!0;c&&(r=this.checkForRequiredKeysErrors(a.required||[],l,r)),this.isDefined(l)&&(this.handleValidation(i,l,a,s),r=this.checkForDisallowedProperties(Object.keys(l),Object.keys(a),r,f),this.handleNestedObject(l,a,s,r))}return{results:s,errors:r}}updatePropertyPath(t,e=""){if(!t){this.propertyPath="";return}e&&(this.propertyPath=e),this.propertyPath=`${this.propertyPath}.${t}`,this.propertyPath.startsWith(".")&&(this.propertyPath=this.propertyPath.substring(1,this.propertyPath.length))}isDefined(t){return!!(typeof t=="number"&&t===0||t||t===""||typeof t=="boolean")}checkForRequiredKeysErrors(t,e,s){if(!this.areRequiredKeysPresent(t,e)){let r=e?Object.keys(e):[],o=this.findNonOverlappingElements(t,r),n=o.length>0?`Missing the required key: '${o.join(", ")}'!`:`Missing values for required keys: '${r.filter(i=>!e[i]).join(", ")}'!`;s.push({key:"",value:e,success:!1,error:n})}return s}checkForDisallowedProperties(t,e,s,r){if(!r){let o=this.findNonOverlappingElements(t,e);o.length>0&&s.push({key:`${e}`,value:t,success:!1,error:`Has additional (disallowed) properties: '${o.join(", ")}'!`})}return s}handleValidation(t,e,s,r){this.updatePropertyPath(t);let o=this.validateProperty(this.propertyPath,s,e);r.push(...o);let n=(c,a)=>{c.forEach(l=>{let f=this.validateProperty(this.propertyPath,a.items,l);r.push(...f)}),this.updatePropertyPath()},i=c=>{let a=Object.keys(c),l=this.propertyPath;a.forEach(f=>{if(this.updatePropertyPath(f,l),this.isArray(c[f])&&s[f]?.items!=null)n(c[f],s[f]);else{let u=this.validateProperty(this.propertyPath,s[f],c[f]);r.push(...u)}})};this.isArray(e)&&s.items!=null?n(e,s):this.isObject(e)?i(e):this.updatePropertyPath()}handleNestedObject(t,e,s,r){if(this.isObject(t)){let o=this.getNestedObjects(t);for(let n of o){let i=e[n],c=t[n];i&&typeof c=="object"&&this.validate(i,c,s,r)}}}getNestedObjects(t){return Object.keys(t).filter(e=>{if(this.isObject(t))return e})}findNonOverlappingElements(t,e){return t.filter(s=>!e.includes(s))}areRequiredKeysPresent(t,e=[]){return t.every(s=>Object.keys(e).includes(s)?this.isDefined(e[s]):!1)}validateProperty(t,e,s){return this.validateInput(e,s).map(o=>{let{success:n,error:i}=o;return{key:t,value:s,success:n,error:i??""}})}validateInput(t,e){if(t){let s=[{condition:()=>t.type,validator:()=>this.isCorrectType(t.type,e),error:"Invalid type"},{condition:()=>t.format,validator:()=>this.isCorrectFormat(t.format,e),error:"Invalid format"},{condition:()=>t.minLength,validator:()=>this.isMinimumLength(t.minLength,e),error:"Length too short"},{condition:()=>t.maxLength,validator:()=>this.isMaximumLength(t.maxLength,e),error:"Length too long"},{condition:()=>t.minValue,validator:()=>this.isMinimumValue(t.minValue,e),error:"Value too small"},{condition:()=>t.maxValue,validator:()=>this.isMaximumValue(t.maxValue,e),error:"Value too large"},{condition:()=>t.matchesPattern,validator:()=>this.matchesPattern(t.matchesPattern,e),error:"Pattern does not match"}],r=[];for(let o of s)o.condition()&&!o.validator()&&r.push({success:!1,error:o.error});return r}else this.isSilent||console.warn(`Missing property '${t}' for match '${e}'. Skipping...`);return[{success:!0}]}isCorrectType(t,e){return Array.isArray(t)||(t=[t]),t.some(s=>{switch(s){case"string":return typeof e=="string";case"number":return typeof e=="number"&&!isNaN(e);case"boolean":return typeof e=="boolean";case"object":return this.isObject(e);case"array":return this.isArray(e)}})}isObject(t){return t!==null&&!this.isArray(t)&&typeof t=="object"&&t instanceof Object&&Object.prototype.toString.call(t)==="[object Object]"}isArray(t){return Array.isArray(t)}isCorrectFormat(t,e){switch(t){case"alphanumeric":return new RegExp(/^[a-zA-Z0-9]+$/).test(e);case"numeric":return new RegExp(/^-?\d+(\.\d+)?$/).test(e);case"email":return new RegExp(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/).test(e);case"date":return new RegExp(/^\d{4}-\d{2}-\d{2}$/).test(e);case"url":return new RegExp(/^(https?):\/\/[^\s$.?#].[^\s]*$/).test(e);case"hexColor":return new RegExp(/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i).test(e)}}isMinimumLength(t,e){return Array.isArray(e)?e.length>=t:e?.toString().length>=t}isMaximumLength(t,e){return Array.isArray(e)?e.length<=t:e.toString().length<=t}isMinimumValue(t,e){return e>=t}isMaximumValue(t,e){return e<=t}matchesPattern(t,e){return new RegExp(t).test(e)}schemaFrom(t){let e={properties:{additionalProperties:!1,required:[]}};for(let s in t){let r=t[s];e.properties.required.push(s),Array.isArray(r)?e.properties[s]=this.generateArraySchema(r):typeof r=="object"&&r!==null?e.properties[s]=this.generateNestedObjectSchema(r):e.properties[s]=this.generatePropertySchema(r)}return e}generateArraySchema(t){let e={type:"array"},s=t.filter(r=>r);if(s.length>0){let r=s[0];s.every(n=>typeof n==typeof r)?typeof r=="object"&&!Array.isArray(r)?e.items=this.generateNestedObjectSchema(r):e.items=this.generatePropertySchema(r):console.warn("All elements in array are not of the same type. Unable to generate a schema for these elements.")}return e}generateNestedObjectSchema(t){let e={type:"object",additionalProperties:!1,required:[]};for(let s in t){let r=t[s];e.required.push(s),typeof r=="object"&&!Array.isArray(r)&&r!==null?e[s]=this.generateNestedObjectSchema(r):e[s]=this.generatePropertySchema(r)}return e}generatePropertySchema(t){let e=typeof t,s={type:e};return e==="string"&&(s.minLength=1),s}};async function S(t){return t.body||{}}var U={properties:{public:{type:"boolean"}},additionalProperties:!1};var vt=new k;async function F(t,e,s){try{let r=t.params.bucket;if(!r)return t.json({error:"bucket parameter is required"},400);let o=await S(t),n=vt.test(U,o||{});if(!n.success)return t.json({error:"Invalid input",details:n.errors},400);await y(t,s,"storage.bucket.create","storage","bucket","create");let{public:i}=o||{};return await e.createBucket(r,i),t.json({success:!0,bucket:r,public:i||!1},200)}catch(r){let{message:o,status:n}=g(r,"Error creating bucket");return t.json({error:o},n)}}async function z(t,e,s){try{let r=t.params.bucket;if(!r)return t.json({error:"bucket parameter is required"},400);await y(t,s,"storage.bucket.read","storage","bucket","read",r);let o=await e.getBucketStats(r),n=await e.isBucketPublic(r);return t.json({bucket:r,...o,public:n},200)}catch(r){let{message:o,status:n}=g(r,"Error getting bucket stats");return t.json({error:o},n)}}var G={properties:{public:{type:"boolean"}},required:["public"],additionalProperties:!1};var St=new k;async function J(t,e,s){try{let r=t.params.bucket;if(!r)return t.json({error:"bucket parameter is required"},400);let o;try{o=await S(t)}catch{return t.json({error:"Invalid JSON body"},400)}let{public:n}=o;if(n===void 0)return t.json({error:"No valid configuration provided"},400);let i=St.test(G,o);if(!i.success)return t.json({error:"Invalid input",details:i.errors},400);if(await y(t,s,"storage.bucket.update","storage","bucket","update",r),!await e.bucketExists(r))return t.json({error:"Bucket not found"},404);await e.updateBucket(r,{public:n});let a=await e.isBucketPublic(r);return t.json({success:!0,bucket:r,public:a},200)}catch(r){let{message:o,status:n}=g(r,"Error updating bucket");return t.json({error:o},n)}}async function W(t,e,s){try{let r=t.params.bucket;return r?(await y(t,s,"storage.bucket.delete","storage","bucket","delete",r),await e.bucketExists(r)?(await e.deleteBucket(r),t.json({success:!0,bucket:r},200)):t.json({error:"Bucket not found"},404)):t.json({error:"bucket parameter is required"},400)}catch(r){let{message:o,status:n}=g(r,"Error deleting bucket");return t.json({error:o},n)}}async function _(t,e,s){try{let r=t.params.bucket;if(!r)return t.json({error:"bucket parameter is required"},400);let o=t.query.prefix||"";await y(t,s,"storage.object.list","storage","object","list");let n=await e.listObjects(r,o);return t.json({objects:n,prefix:o},200)}catch(r){let{message:o,status:n}=g(r,"Error listing objects");return t.json({error:o},n)}}var X={properties:{key:{type:"string",minLength:1},content:{type:"string"}},required:["key"],additionalProperties:!1};var xt=new k;async function Z(t,e,s){try{let r=t.params.bucket,o=t.headers["content-type"]||"";if(!r)return t.json({error:"bucket parameter is required"},400);if(await y(t,s,"storage.object.write","storage","object","write"),o.includes("multipart/form-data")){let{fields:u,files:d}=t.body,h=u?.key,m=d?.file;if(!h)return t.json({error:"key is required"},400);if(!m)return t.json({error:"file is required"},400);let p;return Buffer.isBuffer(m)?p=m:m.data&&Buffer.isBuffer(m.data)?p=m.data:m.data?p=Buffer.from(m.data):p=Buffer.from(m),await e.putObject(r,h,p),t.json({success:!0,bucket:r,key:h},200)}if(o.includes("application/json")){let u=t.body;if(typeof t.body=="string")try{u=JSON.parse(t.body)}catch{u=t.body}if(u&&typeof u=="object"&&("fields"in u||"files"in u)){let{fields:d,files:h}=u,m=d?.key,p=h?.file;if(!m)return t.json({error:"key is required"},400);if(!p)return t.json({error:"file is required"},400);let x;return Buffer.isBuffer(p)?x=p:p.data&&Buffer.isBuffer(p.data)?x=p.data:p.data?p.data.type==="Buffer"&&Array.isArray(p.data.data)?x=Buffer.from(p.data.data):x=Buffer.from(p.data):typeof p=="object"&&p.type==="Buffer"&&Array.isArray(p.data)?x=Buffer.from(p.data):x=Buffer.from(p),await e.putObject(r,m,x),t.json({success:!0,bucket:r,key:m},200)}}if(o.includes("application/octet-stream")||o.includes("video/")||o.includes("image/")){let u=t.query.key;if(!u)return t.json({error:"key query parameter is required for binary uploads"},400);let d=Buffer.isBuffer(t.body)?t.body:Buffer.from(t.body);return await e.putObject(r,u,d),t.json({success:!0,bucket:r,key:u},200)}let n=await S(t),i=xt.test(X,n);if(!i.success)return t.json({error:"Invalid input",details:i.errors},400);let{key:c,content:a}=n;if(!c)return t.json({error:"key is required"},400);if(!a)return t.json({error:"content is required"},400);let f=a.length>=20&&a.length%4===0&&/^[A-Za-z0-9+/]*={0,2}$/.test(a)?Buffer.from(a,"base64"):a;return await e.putObject(r,c,f),t.json({success:!0,bucket:r,key:c},200)}catch(r){let{message:o,status:n}=g(r,"Error storing object");return t.json({error:o},n)}}var K={properties:{key:{type:"string",minLength:1}},required:["key"],additionalProperties:!1};var Pt=new k;async function Y(t,e,s){try{let r=t.params.bucket;if(!r)return t.json({error:"bucket parameter is required"},400);let o=await S(t),n=Pt.test(K,o);if(!n.success)return t.json({error:"Invalid input",details:n.errors},400);await y(t,s,"storage.object.read","storage","object","read");let{key:i}=o;if(!await e.objectExists(r,i))return t.json({error:"Object not found"},404);let a=await e.getObject(r,i);return t.json({bucket:r,key:i,content:a.toString()},200)}catch(r){let{message:o,status:n}=g(r,"Error getting object");return t.json({error:o},n)}}var Q={properties:{key:{type:"string",minLength:1}},required:["key"],additionalProperties:!1};var Rt=new k;async function tt(t,e,s){try{let r=t.params.bucket;if(!r)return t.json({error:"bucket parameter is required"},400);let o=await S(t),n=Rt.test(Q,o);if(!n.success)return t.json({error:"Invalid input",details:n.errors},400);await y(t,s,"storage.object.delete","storage","object","delete");let{key:i}=o;return await e.objectExists(r,i)?(await e.deleteObject(r,i),t.json({success:!0,bucket:r,key:i},200)):t.json({error:"Object not found"},404)}catch(r){let{message:o,status:n}=g(r,"Error deleting object");return t.json({error:o},n)}}import Bt from"node:crypto";import{readFileSync as Ot,existsSync as It}from"node:fs";function C(){let t=process.env.MOLNOS_RUNTIME_CONFIG,e={molnos:{dataPath:"data",rateLimit:{global:{enabled:!1,requestsPerMinute:0}},signedUrlSecret:"molnos-default-signed-url-secret"},server:{host:"127.0.0.1",port:3e3},identity:{apiUrl:""},services:{storage:{host:"127.0.0.1",port:3001,url:"http://127.0.0.1:3001"},functions:{host:"127.0.0.1",port:3002,url:"http://127.0.0.1:3002"},sites:{host:"127.0.0.1",port:3003,url:"http://127.0.0.1:3003"},databases:{host:"127.0.0.1",port:3004,url:"http://127.0.0.1:3004"},observability:{host:"127.0.0.1",port:3005,url:"http://127.0.0.1:3005"}}};if(!t||!It(t))return e;try{let s=Ot(t,"utf-8");return JSON.parse(s)}catch(s){return console.error("[loadRuntimeConfig] Failed to load runtime config:",s),e}}function et(t,e,s,r){try{let[o,n]=t.split(".");if(!o||!n)return!1;let i=Buffer.from(o,"base64url").toString("utf-8"),c=JSON.parse(i);if(Date.now()>=c.expiresAt||c.bucket!==e||c.key!==s)return!1;let a=C().molnos.signedUrlSecret,l=Bt.createHmac("sha256",r||a).update(i).digest("base64url");return n===l}catch{return!1}}import{extname as Mt}from"node:path";function rt(t){let e=Mt(t).toLowerCase();return{".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".ico":"image/x-icon",".txt":"text/plain",".pdf":"application/pdf",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject",".otf":"font/otf",".xml":"application/xml",".mp4":"video/mp4",".webm":"video/webm",".mp3":"audio/mpeg",".wav":"audio/wav"}[e]||"application/octet-stream"}async function st(t,e,s){try{let r=t.params.bucket,n=new URL(t.req.url||"","http://localhost").pathname.match(/^\/buckets\/[^/]+\/objects\/(.+)$/);if(!n)return t.json({error:"Invalid object path"},400);let i=decodeURIComponent(n[1]);if(!r)return t.json({error:"bucket parameter is required"},400);if(!await e.isBucketPublic(r)){let u=t.query.token;if(u){if(!et(u,r,i))return t.json({error:"Invalid or expired token"},401)}else await y(t,s,"storage.object.read","storage","object","read")}if(!await e.objectExists(r,i))return t.json({error:"Object not found"},404);let l=await e.getObject(r,i),f=rt(i);return t.binary(l,f)}catch(r){let{message:o,status:n}=g(r,"Error retrieving object");return t.json({error:o},n)}}import Tt from"node:crypto";function ot(t,e,s,r){let o=JSON.stringify({bucket:t,key:e,expiresAt:s}),n=C().molnos.signedUrlSecret,i=Tt.createHmac("sha256",r||n).update(o).digest("base64url");return`${Buffer.from(o).toString("base64url")}.${i}`}var At=3600;function it(t,e,s){let r=parseInt(t.query.expiresIn,10),o=Number.isNaN(r)?At:r,n=Date.now()+o*1e3,i=ot(e,s,n),c=t.req.headers["x-forwarded-proto"]||"http",a=t.req.headers.host||"localhost:3000";return{signedUrl:`${c}://${a}/buckets/${e}/objects/${encodeURIComponent(s)}?token=${i}`,expiresAt:n,expirySeconds:o}}async function nt(t,e,s){try{let r=t.params.bucket,n=new URL(t.req.url||"","http://localhost").pathname.match(/^\/buckets\/[^/]+\/objects\/(.+)\/sign$/);if(!n)return t.json({error:"Invalid object path"},400);let i=decodeURIComponent(n[1]);if(!r)return t.json({error:"bucket parameter is required"},400);if(await y(t,s,"storage.object.read","storage","object","read"),!await e.objectExists(r,i))return t.json({error:"Object not found"},404);let{signedUrl:a,expiresAt:l,expirySeconds:f}=it(t,r,i);return t.json({url:a,expiresAt:new Date(l).toISOString(),expiresIn:f})}catch(r){let{message:o,status:n}=g(r,"Error signing object URL");return t.json({error:o},n)}}var j=class extends Error{constructor(e){super(),this.name="NotFoundError",this.message=e||"Resource not found",this.cause={statusCode:404}}};function at(t){return t&&typeof t=="number"&&t>0?t*1024*1024:0}function ct(t,e){let s={enabled:!1,requestsPerMinute:0};if(!e)return s;let r=e.services?.[t];return r||(e.global?e.global:s)}function ut(t,e){let s=t?.api?.port;if(!s)throw new Error('Missing "port" input when create API service!');let r=C(),o=t?.dataPath||r.molnos.dataPath,n=t?.api?.host||r.server.host,i=t?.identityApiUrl!==void 0?t.identityApiUrl:r.identity.apiUrl,c=t?.debug||!1,a;return e&&(a=ct(e,r.molnos.rateLimit)),{dataPath:o,api:{port:s,host:n},...i?{identityApiUrl:i}:{},...a?{rateLimit:a}:{},debug:c}}var R=class{baseUrl;authToken;constructor(e,s){this.baseUrl=e.replace(/\/$/,""),this.authToken=s}async createCustomRole(e,s,r,o){let n=await fetch(`${this.baseUrl}/identity/roles`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({roleId:e,name:s,description:r,permissions:o})});if(!n.ok){let i=`Failed to create role: ${n.statusText}`;try{i=(await n.json()).error||i}catch{i=await n.text().catch(()=>n.statusText)||i}throw new Error(i)}}async updateRole(e,s){let r=await fetch(`${this.baseUrl}/identity/roles/${e}`,{method:"PATCH",headers:this.getHeaders(),body:JSON.stringify(s)});if(!r.ok){let o=await r.json();throw new Error(o.error||`Failed to update role: ${r.statusText}`)}}async deleteRole(e){let s=await fetch(`${this.baseUrl}/identity/roles/${e}`,{method:"DELETE",headers:this.getHeaders()});if(!s.ok){let r=await s.json();throw new Error(r.error||`Failed to delete role: ${s.statusText}`)}}async addServiceAccount(e,s,r){let o=await fetch(`${this.baseUrl}/identity/service-accounts`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:e,description:s,roles:r})});if(!o.ok){let i=`Failed to create service account: ${o.statusText}`;try{i=(await o.json()).error||i}catch{i=await o.text().catch(()=>o.statusText)||i}throw new Error(i)}let n=await o.json();return{id:n.id,apiKey:n.apiKey}}async deleteIdentity(e){let s=await fetch(`${this.baseUrl}/identity/service-accounts/${e}`,{method:"DELETE",headers:this.getHeaders()});if(!s.ok){let r=await s.json();throw new Error(r.error||`Failed to delete service account: ${s.statusText}`)}}async getUserFromToken(e){try{let s=await fetch(`${this.baseUrl}/identity/whoami`,{method:"GET",headers:{Authorization:`Bearer ${e}`}});return s.ok?await s.json():null}catch{return null}}getHeaders(){let e={"Content-Type":"application/json"};return this.authToken&&(e.Authorization=`Bearer ${this.authToken}`),e}};function lt(t){return t?new R(t):null}var A=class{rootPath;metadataPath;constructor(e){this.rootPath=e.path||"storage-data",this.metadataPath=w(this.rootPath,".metadata")}async start(){await b.mkdir(this.rootPath,{recursive:!0}),await b.mkdir(this.metadataPath,{recursive:!0})}getBucketMetadataPath(e){return w(this.metadataPath,`${e}.json`)}async readBucketMetadata(e){let s=this.getBucketMetadataPath(e);try{let r=await b.readFile(s,"utf-8");return JSON.parse(r)}catch{return{public:!1}}}async writeBucketMetadata(e,s){let r=this.getBucketMetadataPath(e);await b.writeFile(r,JSON.stringify(s,null,2))}async deleteBucketMetadata(e){let s=this.getBucketMetadataPath(e);try{await b.unlink(s)}catch{}}async putObject(e,s,r){let o=w(this.rootPath,e,s);await b.mkdir($t(o),{recursive:!0}),await b.writeFile(o,r)}async getObject(e,s){let r=w(this.rootPath,e,s);return await b.readFile(r)}async deleteObject(e,s){let r=w(this.rootPath,e,s);await b.unlink(r)}async objectExists(e,s){let r=w(this.rootPath,e,s);try{return await b.access(r),!0}catch{return!1}}async createBucket(e,s=!1){let r=w(this.rootPath,e);await b.mkdir(r,{recursive:!0}),await this.writeBucketMetadata(e,{public:s})}async deleteBucket(e){let s=w(this.rootPath,e);await b.rm(s,{recursive:!0,force:!0}),await this.deleteBucketMetadata(e)}async bucketExists(e){let s=w(this.rootPath,e);try{return(await b.stat(s)).isDirectory()}catch{return!1}}async isBucketPublic(e){return(await this.readBucketMetadata(e)).public}async updateBucket(e,s){if(!await this.bucketExists(e))throw new Error("Bucket not found");let n={...await this.readBucketMetadata(e),...s.public!==void 0&&{public:s.public}};await this.writeBucketMetadata(e,n)}async listBuckets(){try{return(await b.readdir(this.rootPath,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name)}catch{return[]}}async getBucketStats(e){let s=w(this.rootPath,e);try{if(!(await b.stat(s)).isDirectory())throw new j("Bucket not found")}catch(i){throw i.code==="ENOENT"?new j("Bucket not found"):i}let r=0,o=0,n=async i=>{let c=await b.readdir(i,{withFileTypes:!0});for(let a of c){let l=w(i,a.name);if(a.isDirectory())await n(l);else if(a.isFile()){r++;let f=await b.stat(l);o+=f.size}}};try{await n(s)}catch{return{objectCount:0,totalSize:0}}return{objectCount:r,totalSize:o}}async listObjects(e,s=""){let r=w(this.rootPath,e);try{if(!(await b.stat(r)).isDirectory())throw new j("Bucket not found")}catch(l){throw l.code==="ENOENT"?new j("Bucket not found"):l}let o=[],n=async(l,f="")=>{let u=await b.readdir(l,{withFileTypes:!0});for(let d of u){let h=w(l,d.name),m=f?`${f}/${d.name}`:d.name;if(d.isDirectory())await n(h,m);else if(d.isFile()){let p=await b.stat(h);o.push({key:m,size:p.size,lastModified:p.mtime,type:"file"})}}};try{await n(r)}catch{return[]}let i=s?o.filter(l=>l.key.startsWith(s)):o,c=[],a=new Set;for(let l of i){let f=s?l.key.substring(s.length):l.key,u=f.indexOf("/");if(u===-1)c.push({key:f,size:l.size,lastModified:l.lastModified,type:"file"});else{let d=f.substring(0,u);a.has(d)||(a.add(d),c.push({key:`${d}/`,size:0,lastModified:l.lastModified,type:"folder"}))}}return c.sort((l,f)=>l.type!==f.type?l.type==="folder"?-1:1:l.key.localeCompare(f.key))}};async function Ht(t){let e=t.dataPath||"data",s=w(e,"storage"),r=new A({path:s});await r.start();let o=lt(t.identityApiUrl),n=C(),i=new T({port:t.api.port||n.services.storage.port,host:t.api.host||n.services.storage.host,maxBodySize:at(1e3),rateLimit:t.rateLimit||{enabled:!1,requestsPerMinute:0}});return i.get("/buckets",async a=>D(a,r,o)),i.post("/buckets/:bucket",async a=>F(a,r,o)),i.get("/buckets/:bucket",async a=>z(a,r,o)),i.patch("/buckets/:bucket",async a=>J(a,r,o)),i.delete("/buckets/:bucket",async a=>W(a,r,o)),i.get("/buckets/:bucket/objects",async a=>_(a,r,o)),i.put("/buckets/:bucket/objects",async a=>Z(a,r,o)),i.post("/buckets/:bucket/objects",async a=>Y(a,r,o)),i.delete("/buckets/:bucket/objects",async a=>tt(a,r,o)),i.post("/buckets/:bucket/objects/*",async a=>new URL(a.req.url||"","http://localhost").pathname.endsWith("/sign")?nt(a,r,o):a.json({error:"Not Found"},404)),i.get("/buckets/:bucket/objects/*",async a=>st(a,r,o)),i.start()}if(import.meta.url===`file://${process.argv[1]}`){let t=C(),s=process.argv.slice(2).find(n=>n.startsWith("--port=")),r=s?parseInt(s.split("=")[1],10):t.services.storage.port,o=ut({api:{port:r}},"storage");Ht(o)}export{A as StorageService,Ht as startServer};
@@ -0,0 +1,97 @@
1
+ mikroauth 1.1.0
2
+ MIT
3
+ Copyright 2025-present Mikael Vesavuori
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10
+
11
+
12
+ mikroconf 1.0.0
13
+ MIT
14
+ Copyright 2025-present Mikael Vesavuori
15
+
16
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+
23
+ mikroevent 1.0.1
24
+ MIT
25
+ Copyright 2025-present Mikael Vesavuori
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
28
+
29
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
30
+
31
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+
33
+
34
+ mikroid 1.0.0
35
+ MIT
36
+ Copyright 2025-present Mikael Vesavuori
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
39
+
40
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43
+
44
+
45
+ mikromail 1.0.0
46
+ MIT
47
+ Copyright 2025-present Mikael Vesavuori
48
+
49
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54
+
55
+
56
+ mikropermit 1.0.0
57
+ MIT
58
+ Copyright 2024-present Mikael Vesavuori
59
+
60
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
61
+
62
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
65
+
66
+
67
+ mikroserve 1.1.1
68
+ MIT
69
+ Copyright 2025-present Mikael Vesavuori
70
+
71
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
72
+
73
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
74
+
75
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76
+
77
+
78
+ mikrovalid 1.0.23
79
+ MIT
80
+ Copyright 2024-present Mikael Vesavuori
81
+
82
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
83
+
84
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
85
+
86
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
87
+
88
+
89
+ pikodb 1.0.1
90
+ MIT
91
+ Copyright 2025-present Mikael Vesavuori
92
+
93
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
94
+
95
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
96
+
97
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "molnos",
3
3
  "description": "The core API for MolnOS.",
4
- "version": "1.0.3",
4
+ "version": "1.1.0",
5
5
  "author": "MolnOS",
6
6
  "license": "COMMERCIAL",
7
7
  "keywords": [],
@@ -21,7 +21,13 @@
21
21
  "files": [
22
22
  "/dist",
23
23
  "!/dist/**/*.map",
24
- "!/tests"
24
+ "!/tests",
25
+ "VERSION",
26
+ "LICENSE",
27
+ "README.md",
28
+ "sbom.json",
29
+ "oss-licenses.txt",
30
+ "Dockerfile"
25
31
  ],
26
32
  "scripts": {
27
33
  "start": "bash clean-build.sh && npm run build:local && npx tsx src/index.ts",
@@ -29,8 +35,8 @@
29
35
  "start:docker": "docker run -d -v $(pwd)/molnos.config.json:/app/molnos.config.json:ro -p 3000:3000 --name molnos ghcr.io/molnos/molnos-core:latest",
30
36
  "inspect": "docker run --rm -it -v $(pwd)/molnos.config.json:/app/molnos.config.json:ro ghcr.io/molnos/molnos-core:latest sh",
31
37
  "build": "npm run clean && node esbuild.config.mjs --esm && cp src/bin.ts dist/bin.mjs && chmod +x dist/bin.mjs",
32
- "build:docker": "docker build -t ghcr.io/molnos/molnos-core:$(node -p \"require('./package.json' with { type: 'json' };).version\") -t ghcr.io/molnos/molnos-core:latest .",
33
- "push:docker": "docker push ghcr.io/molnos/molnos-core:$(node -p \"require('./package.json' with { type: 'json' };).version\") && docker push ghcr.io/molnos/molnos-core:latest",
38
+ "build:docker": "docker build -t ghcr.io/molnos/molnos-core:$npm_package_version -t ghcr.io/molnos/molnos-core:latest .",
39
+ "push:docker": "docker push ghcr.io/molnos/molnos-core:$npm_package_version && docker push ghcr.io/molnos/molnos-core:latest",
34
40
  "build:local": "npm run build && cp dist/*.mjs .",
35
41
  "build:examples": "npx esbuild examples/function-with-import.mjs --bundle --outfile=examples/function-with-import-bundled.mjs --platform=node --format=esm",
36
42
  "test": "npm run lint && npm run test:unit",
@@ -43,10 +49,11 @@
43
49
  "licenses": "grant check sbom.json --config .grant.yaml",
44
50
  "release": "bash release.sh",
45
51
  "clean": "rm -rf lib && rm -rf dist && mkdir lib",
46
- "clean:processes": "lsof -ti:3000,3001,3002,3003,3004,3005 | xargs kill -9 2>/dev/null; sleep 2",
52
+ "clean:processes": "lsof -ti:3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010 | xargs kill -9 2>/dev/null; sleep 2",
47
53
  "lint": "npx @biomejs/biome check --write ./src",
48
54
  "package": "npm pack",
49
- "prepublishOnly": "npm run build",
55
+ "prepublishOnly": "npm run build && echo $npm_package_version > VERSION && npm run sbom && npm run docs:licenses && cp README_PUBLIC.md README.md",
56
+ "postpublish": "git checkout README.md && rm -f VERSION sbom.json oss-licenses.txt",
50
57
  "prepare": "husky",
51
58
  "tunnel": "cloudflared tunnel --url http://localhost:3000"
52
59
  },
@@ -66,14 +73,12 @@
66
73
  "vitest": "4"
67
74
  },
68
75
  "dependencies": {
69
- "@hono/node-server": "1",
70
- "hono": "4",
71
76
  "mikroauth": "1",
72
77
  "mikroconf": "1",
73
- "mikrodb": "1",
74
78
  "mikroevent": "1",
75
79
  "mikroid": "1",
76
80
  "mikropermit": "1",
81
+ "mikroserve": "1",
77
82
  "mikrovalid": "1",
78
83
  "pikodb": "1"
79
84
  }
package/sbom.json ADDED
@@ -0,0 +1 @@
1
+ {"spdxVersion":"SPDX-2.3","dataLicense":"CC0-1.0","SPDXID":"SPDXRef-DOCUMENT","name":"package-lock.json","documentNamespace":"https://anchore.com/syft/file/package-lock.json-ac9d2686-57ec-4725-bbe0-325fffc8a656","creationInfo":{"licenseListVersion":"3.27","creators":["Organization: Anchore, Inc","Tool: syft-1.40.0"],"created":"2026-01-11T16:23:39Z"},"packages":[{"name":"mikroauth","SPDXID":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","versionInfo":"1.1.0","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikroauth/-/mikroauth-1.1.0.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikroauth:mikroauth:1.1.0:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikroauth@1.1.0"}]},{"name":"mikroconf","SPDXID":"SPDXRef-Package-npm-mikroconf-b297d975cb09169c","versionInfo":"1.0.0","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikroconf/-/mikroconf-1.0.0.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikroconf:mikroconf:1.0.0:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikroconf@1.0.0"}]},{"name":"mikroevent","SPDXID":"SPDXRef-Package-npm-mikroevent-5bd10e41dccc0f47","versionInfo":"1.0.1","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikroevent/-/mikroevent-1.0.1.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikroevent:mikroevent:1.0.1:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikroevent@1.0.1"}]},{"name":"mikroid","SPDXID":"SPDXRef-Package-npm-mikroid-505e62805cb5678f","versionInfo":"1.0.0","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikroid/-/mikroid-1.0.0.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikroid:mikroid:1.0.0:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikroid@1.0.0"}]},{"name":"mikromail","SPDXID":"SPDXRef-Package-npm-mikromail-2f017138ed7f39a9","versionInfo":"1.0.0","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikromail/-/mikromail-1.0.0.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikromail:mikromail:1.0.0:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikromail@1.0.0"}]},{"name":"mikropermit","SPDXID":"SPDXRef-Package-npm-mikropermit-0f36ec54f335a15e","versionInfo":"1.0.0","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikropermit/-/mikropermit-1.0.0.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikropermit:mikropermit:1.0.0:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikropermit@1.0.0"}]},{"name":"mikroserve","SPDXID":"SPDXRef-Package-npm-mikroserve-1c5cbf0685852d2c","versionInfo":"1.1.1","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikroserve/-/mikroserve-1.1.1.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikroserve:mikroserve:1.1.1:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikroserve@1.1.1"}]},{"name":"mikrovalid","SPDXID":"SPDXRef-Package-npm-mikrovalid-2873df526a8a0901","versionInfo":"1.0.23","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/mikrovalid/-/mikrovalid-1.0.23.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:mikrovalid:mikrovalid:1.0.23:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/mikrovalid@1.0.23"}]},{"name":"molnos","SPDXID":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","versionInfo":"1.1.0","supplier":"NOASSERTION","downloadLocation":"NOASSERTION","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"LicenseRef-COMMERCIAL","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:molnos:molnos:1.1.0:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/molnos@1.1.0"}]},{"name":"pikodb","SPDXID":"SPDXRef-Package-npm-pikodb-2e1e5824d502124f","versionInfo":"1.0.1","supplier":"NOASSERTION","downloadLocation":"https://registry.npmjs.org/pikodb/-/pikodb-1.0.1.tgz","filesAnalyzed":false,"sourceInfo":"acquired package info from installed node module manifest file: /package-lock.json","licenseConcluded":"NOASSERTION","licenseDeclared":"MIT","copyrightText":"NOASSERTION","externalRefs":[{"referenceCategory":"SECURITY","referenceType":"cpe23Type","referenceLocator":"cpe:2.3:a:pikodb:pikodb:1.0.1:*:*:*:*:*:*:*"},{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:npm/pikodb@1.0.1"}]},{"name":"package-lock.json","SPDXID":"SPDXRef-DocumentRoot-File-package-lock.json","versionInfo":"sha256:7d0943e8c29ad2d51e2ddd8aee80ade4388614d8e4c32066cb0cc2638c72587f","supplier":"NOASSERTION","downloadLocation":"NOASSERTION","filesAnalyzed":false,"checksums":[{"algorithm":"SHA256","checksumValue":"7d0943e8c29ad2d51e2ddd8aee80ade4388614d8e4c32066cb0cc2638c72587f"}],"licenseConcluded":"NOASSERTION","licenseDeclared":"NOASSERTION","copyrightText":"NOASSERTION","primaryPackagePurpose":"FILE"}],"files":[{"fileName":"package-lock.json","SPDXID":"SPDXRef-File-package-lock.json-fd71c2238fc07657","fileTypes":["APPLICATION"],"checksums":[{"algorithm":"SHA1","checksumValue":"2d090f768a28c3d8fae05772a46997c69efc38c9"},{"algorithm":"SHA256","checksumValue":"7d0943e8c29ad2d51e2ddd8aee80ade4388614d8e4c32066cb0cc2638c72587f"}],"licenseConcluded":"NOASSERTION","licenseInfoInFiles":["NOASSERTION"],"copyrightText":"NOASSERTION"}],"hasExtractedLicensingInfos":[{"licenseId":"LicenseRef-COMMERCIAL","extractedText":"NOASSERTION","name":"COMMERCIAL"}],"relationships":[{"spdxElementId":"SPDXRef-Package-npm-mikropermit-0f36ec54f335a15e","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroserve-1c5cbf0685852d2c","relatedSpdxElement":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroserve-1c5cbf0685852d2c","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikrovalid-2873df526a8a0901","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-pikodb-2e1e5824d502124f","relatedSpdxElement":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-pikodb-2e1e5824d502124f","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikromail-2f017138ed7f39a9","relatedSpdxElement":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroid-505e62805cb5678f","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroevent-5bd10e41dccc0f47","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroconf-b297d975cb09169c","relatedSpdxElement":"SPDXRef-Package-npm-mikroserve-1c5cbf0685852d2c","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroconf-b297d975cb09169c","relatedSpdxElement":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikroconf-b297d975cb09169c","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"DEPENDENCY_OF"},{"spdxElementId":"SPDXRef-Package-npm-mikropermit-0f36ec54f335a15e","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikroserve-1c5cbf0685852d2c","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikrovalid-2873df526a8a0901","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-pikodb-2e1e5824d502124f","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikromail-2f017138ed7f39a9","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikroid-505e62805cb5678f","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikroevent-5bd10e41dccc0f47","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-Package-npm-mikroconf-b297d975cb09169c","relatedSpdxElement":"SPDXRef-File-package-lock.json-fd71c2238fc07657","relationshipType":"OTHER","comment":"evident-by: indicates the package's existence is evident by the given file"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikroauth-7520a9fae77ac01a","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikroconf-b297d975cb09169c","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikroevent-5bd10e41dccc0f47","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikroid-505e62805cb5678f","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikromail-2f017138ed7f39a9","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikropermit-0f36ec54f335a15e","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikroserve-1c5cbf0685852d2c","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-mikrovalid-2873df526a8a0901","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-molnos-86e3d29ea570d3eb","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DocumentRoot-File-package-lock.json","relatedSpdxElement":"SPDXRef-Package-npm-pikodb-2e1e5824d502124f","relationshipType":"CONTAINS"},{"spdxElementId":"SPDXRef-DOCUMENT","relatedSpdxElement":"SPDXRef-DocumentRoot-File-package-lock.json","relationshipType":"DESCRIBES"}]}