molnos 1.4.3 → 1.5.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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.3
1
+ 1.5.0
@@ -8,4 +8,4 @@ var q=class{requests=new Map;limit;windowMs;constructor(e=100,t=60){this.limit=e
8
8
  `;return e}};var k={int:e=>{let t=e.trim();if(!/^[+-]?\d+$/.test(t))throw new Error(`Cannot parse "${e}" as an integer`);let s=Number.parseInt(t,10);if(Number.isNaN(s))throw new Error(`Cannot parse "${e}" as an integer`);return s},float:e=>{let t=e.trim();if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(t)){if(t==="Infinity"||t==="-Infinity")return t==="Infinity"?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY;throw new Error(`Cannot parse "${e}" as a number`)}let s=Number.parseFloat(t);if(Number.isNaN(s))throw new Error(`Cannot parse "${e}" as a number`);return s},boolean:e=>{let t=e.trim().toLowerCase();if(["true","yes","1","y"].includes(t))return!0;if(["false","no","0","n"].includes(t))return!1;throw new Error(`Cannot parse "${e}" as a boolean`)},array:e=>e.split(",").map(t=>t.trim()),json:e=>{try{return JSON.parse(e)}catch{throw new Error(`Cannot parse "${e}" as JSON`)}}};var b=E(),B=e=>({configFilePath:"mikroserve.config.json",args:process.argv,options:[{flag:"--port",path:"port",defaultValue:b.port},{flag:"--host",path:"host",defaultValue:b.host},{flag:"--https",path:"useHttps",defaultValue:b.useHttps,isFlag:!0},{flag:"--http2",path:"useHttp2",defaultValue:b.useHttp2,isFlag:!0},{flag:"--cert",path:"sslCert",defaultValue:b.sslCert},{flag:"--key",path:"sslKey",defaultValue:b.sslKey},{flag:"--ca",path:"sslCa",defaultValue:b.sslCa},{flag:"--ratelimit",path:"rateLimit.enabled",defaultValue:b.rateLimit.enabled,isFlag:!0},{flag:"--rps",path:"rateLimit.requestsPerMinute",defaultValue:b.rateLimit.requestsPerMinute},{flag:"--allowed",path:"allowedDomains",defaultValue:b.allowedDomains,parser:k.array},{flag:"--debug",path:"debug",defaultValue:b.debug,isFlag:!0},{flag:"--max-body-size",path:"maxBodySize",defaultValue:b.maxBodySize},{flag:"--request-timeout",path:"requestTimeout",defaultValue:b.requestTimeout}],config:e});function F(e,t){let s=t.match(/boundary=(?:"([^"]+)"|([^;]+))/i);if(!s)throw new Error("Invalid multipart/form-data: missing boundary");let r=s[1]||s[2],i=Buffer.from(`--${r}`),n=Buffer.from(`--${r}--`),o={},a={},d=ve(e,i);for(let l of d){if(l.length===0||l.equals(n.subarray(i.length)))continue;let f=Ce(l);if(!f)continue;let{name:c,filename:u,contentType:g,data:v}=f;if(u){let w={filename:u,contentType:g||"application/octet-stream",data:v,size:v.length};a[c]?Array.isArray(a[c])?a[c].push(w):a[c]=[a[c],w]:a[c]=w}else{let w=v.toString("utf8");o[c]?Array.isArray(o[c])?o[c].push(w):o[c]=[o[c],w]:o[c]=w}}return{fields:o,files:a}}function ve(e,t){let s=[],r=0;for(;r<e.length;){let i=e.indexOf(t,r);if(i===-1)break;r!==i&&s.push(e.subarray(r,i)),r=i+t.length,r<e.length&&e[r]===13&&e[r+1]===10&&(r+=2)}return s}function Ce(e){let t=Buffer.from(`\r
9
9
  \r
10
10
  `),s=e.indexOf(t);if(s===-1)return null;let r=e.subarray(0,s),i=e.subarray(s+4),o=r.toString("utf8").split(`\r
11
- `),a="",d="",l,f;for(let u of o){let g=u.toLowerCase();if(g.startsWith("content-disposition:")){a=u.substring(20).trim();let v=a.match(/name="([^"]+)"/);v&&(d=v[1]);let w=a.match(/filename="([^"]+)"/);w&&(l=w[1])}else g.startsWith("content-type:")&&(f=u.substring(13).trim())}if(!d)return null;let c=i;return c.length>=2&&c[c.length-2]===13&&c[c.length-1]===10&&(c=c.subarray(0,c.length-2)),{disposition:a,name:d,filename:l,contentType:f,data:c}}import{readFileSync as T}from"fs";import N from"http";import Se from"http2";import xe from"https";var L=class{config;rateLimiter;router;shutdownHandlers=[];constructor(e){let t=new $(B(e||{})).get();t.debug&&console.log("Using configuration:",t),this.config=t,this.router=new z;let s=t.rateLimit.requestsPerMinute||E().rateLimit.requestsPerMinute;this.rateLimiter=new q(s,60),t.rateLimit.enabled===!0&&this.use(this.rateLimitMiddleware.bind(this))}use(e){return this.router.use(e),this}get(e,...t){return this.router.get(e,...t),this}post(e,...t){return this.router.post(e,...t),this}put(e,...t){return this.router.put(e,...t),this}delete(e,...t){return this.router.delete(e,...t),this}patch(e,...t){return this.router.patch(e,...t),this}any(e,...t){return this.router.any(e,...t),this}options(e,...t){return this.router.options(e,...t),this}start(){let e=this.createServer(),{port:t,host:s}=this.config;return this.setupGracefulShutdown(e),e.listen(t,s,()=>{let r=e.address(),i=this.config.useHttps||this.config.useHttp2?"https":"http";console.log(`MikroServe running at ${i}://${r.address!=="::"?r.address:"localhost"}:${r.port}`)}),e}createServer(){let e=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 t={key:T(this.config.sslKey),cert:T(this.config.sslCert),...this.config.sslCa?{ca:T(this.config.sslCa)}:{}};return Se.createSecureServer(t,e)}catch(t){throw t.message.includes("key values mismatch")?new Error(`SSL certificate and key do not match: ${t.message}`):t}}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 t={key:T(this.config.sslKey),cert:T(this.config.sslCert),...this.config.sslCa?{ca:T(this.config.sslCa)}:{}};return xe.createServer(t,e)}catch(t){throw t.message.includes("key values mismatch")?new Error(`SSL certificate and key do not match: ${t.message}`):t}}return N.createServer(e)}async rateLimitMiddleware(e,t){let s=e.req.socket.remoteAddress||"unknown";return e.res.setHeader("X-RateLimit-Limit",this.rateLimiter.getLimit().toString()),e.res.setHeader("X-RateLimit-Remaining",this.rateLimiter.getRemainingRequests(s).toString()),e.res.setHeader("X-RateLimit-Reset",this.rateLimiter.getResetTime(s).toString()),this.rateLimiter.isAllowed(s)?t():{statusCode:429,body:{error:"Too Many Requests",message:"Rate limit exceeded, please try again later"},headers:{"Content-Type":"application/json"}}}async requestHandler(e,t){let s=Date.now(),r=e.method||"UNKNOWN",i=e.url||"/unknown",n=this.config.debug;try{if(this.setCorsHeaders(t,e),this.setSecurityHeaders(t,this.config.useHttps),n&&console.log(`${r} ${i}`),e.method==="OPTIONS"){if(t instanceof N.ServerResponse)t.statusCode=204,t.end();else{let a=t;a.writeHead(204),a.end()}return}try{e.body=await this.parseBody(e)}catch(a){return n&&console.error("Body parsing error:",a.message),this.respond(t,{statusCode:400,body:{error:"Bad Request",message:a.message}})}let o=await this.router.handle(e,t);return o?o._handled?void 0:this.respond(t,o):this.respond(t,{statusCode:404,body:{error:"Not Found",message:"The requested endpoint does not exist"}})}catch(o){return console.error("Server error:",o),this.respond(t,{statusCode:500,body:{error:"Internal Server Error",message:n?o.message:"An unexpected error occurred"}})}finally{n&&this.logDuration(s,r,i)}}logDuration(e,t,s){let r=Date.now()-e;console.log(`${t} ${s} completed in ${r}ms`)}async parseBody(e){return new Promise((t,s)=>{let r=[],i=0,n=this.config.maxBodySize,o=!1,a=null,d=this.config.debug,l=e.headers["content-type"]||"";d&&console.log("Content-Type:",l),this.config.requestTimeout>0&&(a=setTimeout(()=>{o||(o=!0,d&&console.log("Request timeout exceeded"),s(new Error("Request timeout")))},this.config.requestTimeout));let f=()=>{a&&(clearTimeout(a),a=null)};e.on("data",c=>{if(!o){if(i+=c.length,d&&console.log(`Received chunk: ${c.length} bytes, total size: ${i}`),i>n){o=!0,f(),d&&console.log(`Body size exceeded limit: ${i} > ${n}`),s(new Error("Request body too large"));return}r.push(c)}}),e.on("end",()=>{if(!o){o=!0,f(),d&&console.log(`Request body complete: ${i} bytes`);try{if(r.length>0){let c=Buffer.concat(r);if(l.includes("application/json"))try{let u=c.toString("utf8");t(JSON.parse(u))}catch(u){s(new Error(`Invalid JSON in request body: ${u.message}`))}else if(l.includes("application/x-www-form-urlencoded")){let u=c.toString("utf8"),g={};new URLSearchParams(u).forEach((v,w)=>{g[w]=v}),t(g)}else if(l.includes("multipart/form-data"))try{let u=F(c,l);t(u)}catch(u){s(new Error(`Invalid multipart form data: ${u.message}`))}else this.isBinaryContentType(l)?t(c):t(c.toString("utf8"))}else t({})}catch(c){s(new Error(`Invalid request body: ${c}`))}}}),e.on("error",c=>{o||(o=!0,f(),s(new Error(`Error reading request body: ${c.message}`)))}),e.on("close",()=>{f()})})}isBinaryContentType(e){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=>e.includes(s))}setCorsHeaders(e,t){let s=t.headers.origin,{allowedDomains:r=["*"]}=this.config;!s||r.length===0||r.includes("*")?e.setHeader("Access-Control-Allow-Origin","*"):r.includes(s)&&(e.setHeader("Access-Control-Allow-Origin",s),e.setHeader("Vary","Origin")),e.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, PATCH, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),e.setHeader("Access-Control-Max-Age","86400")}setSecurityHeaders(e,t=!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((t||this.config.useHttp2)&&(s["Strict-Transport-Security"]="max-age=31536000; includeSubDomains"),e instanceof N.ServerResponse)Object.entries(s).forEach(([r,i])=>{e.setHeader(r,i)});else{let r=e;Object.entries(s).forEach(([i,n])=>{r.setHeader(i,n)})}}respond(e,t){let s={...t.headers||{}};(i=>typeof i.writeHead=="function"&&typeof i.end=="function")(e)?(e.writeHead(t.statusCode,s),t.body===null||t.body===void 0?e.end():t.isRaw||typeof t.body=="string"?e.end(t.body):e.end(JSON.stringify(t.body))):(console.warn("Unexpected response object type without writeHead/end methods"),e.writeHead?.(t.statusCode,s),t.body===null||t.body===void 0?e.end?.():t.isRaw||typeof t.body=="string"?e.end?.(t.body):e.end?.(JSON.stringify(t.body)))}setupGracefulShutdown(e){let t=o=>{console.log("Shutting down MikroServe server..."),o&&console.error("Error:",o),this.cleanupShutdownHandlers(),e.close(()=>{console.log("Server closed successfully"),process.env.NODE_ENV!=="test"&&process.env.VITEST!=="true"&&setImmediate(()=>process.exit(o?1:0))})},s=()=>t(),r=()=>t(),i=o=>t(o),n=o=>t(o);this.shutdownHandlers=[s,r,i,n],process.on("SIGINT",s),process.on("SIGTERM",r),process.on("uncaughtException",i),process.on("unhandledRejection",n)}cleanupShutdownHandlers(){if(this.shutdownHandlers.length>0){let[e,t,s,r]=this.shutdownHandlers;process.removeListener("SIGINT",e),process.removeListener("SIGTERM",t),process.removeListener("uncaughtException",s),process.removeListener("unhandledRejection",r),this.shutdownHandlers=[]}}};function R(e){if(!e.deflate&&!e.inflate)throw new Error("Dictionary must provide either deflate or inflate mapping");if(e.deflate&&e.inflate)throw new Error("Dictionary should provide only one of deflate or inflate (not both). The inverse will be auto-generated.");return e.deflate?{deflate:e.deflate,inflate:U(e.deflate)}:{deflate:U(e.inflate),inflate:e.inflate}}function U(e){let t={};for(let[s,r]of Object.entries(e))t[r]=s;return t}function P(e,t){if(e==null||typeof e!="object")return e;if(Array.isArray(e))return e.map(r=>P(r,t));let s={};for(let[r,i]of Object.entries(e)){let n=t[r]||r;s[n]=P(i,t)}return s}function S(e){if(!e||typeof e!="string")throw new Error("Table name must be a non-empty string");if(e.length>255)throw new Error("Table name must not exceed 255 characters");if(e.includes("/")||e.includes("\\"))throw new Error("Table name must not contain path separators");if(e.includes(".."))throw new Error('Table name must not contain ".."');if(e.startsWith("."))throw new Error('Table name must not start with "."');if(e.includes("\0"))throw new Error("Table name must not contain null bytes");if(["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"].includes(e.toUpperCase()))throw new Error(`Table name "${e}" is reserved by the filesystem`)}function j(e){if(e==null)throw new Error("Key must be defined");if(typeof e!="string")throw new Error("Key must be a string");if(e.length===0)throw new Error("Key must not be empty");if(e.length>1024)throw new Error("Key must not exceed 1024 characters");if(e.includes("\0"))throw new Error("Key must not contain null bytes")}function G(e){if(e===void 0)throw new Error("Value must not be undefined (use null instead)");let t=typeof e;if(t==="function")throw new Error("Value must be JSON-serializable: functions are not supported");if(t==="symbol")throw new Error("Value must be JSON-serializable: symbols are not supported");try{if(JSON.stringify(e)===void 0)throw new Error("Value must be JSON-serializable: value cannot be serialized")}catch(s){throw new Error(`Value must be JSON-serializable: ${s instanceof Error?s.message:String(s)}`)}}import{existsSync as H,mkdirSync as Te,readdirSync as Pe,openSync as Ee,closeSync as Re}from"fs";import{readFile as je,writeFile as Ie,rename as Me,unlink as _,open as Oe}from"fs/promises";import{join as V,dirname as Ae}from"path";var D=class{data=new Map;databaseDirectory;dictionaries=new Map;useFsync;constructor(e){this.databaseDirectory=e.databaseDirectory,this.useFsync=e.durableWrites??!1,e.dictionaries&&Object.entries(e.dictionaries).forEach(([t,s])=>{let r=R(s);this.dictionaries.set(t,r)}),H(this.databaseDirectory)||Te(this.databaseDirectory,{recursive:!0})}async start(){try{let e=Pe(this.databaseDirectory);for(let t of e)!t.endsWith(".tmp")&&!t.startsWith(".")&&await this.loadTable(t)}catch(e){throw console.error("Failed to start database:",e),e}}async write(e,t,s,r,i){if(S(e),j(t),G(s),i&&!this.dictionaries.has(i))throw new Error(`Dictionary "${i}" not found. Available dictionaries: ${Array.from(this.dictionaries.keys()).join(", ")||"none"}`);try{this.data.has(e)||this.data.set(e,new Map);let n=this.data.get(e),a=(n.get(t)?.version||0)+1,d={value:s,version:a,timestamp:Date.now(),expiration:r||null,dictionaryName:i||void 0};return n.set(t,d),await this.persistTable(e),!0}catch(n){return console.error(`Write failed for ${e}:${t}:`,n),!1}}async get(e,t){S(e),t!==void 0&&j(t);try{this.data.has(e)||await this.loadTable(e);let s=this.data.get(e);if(!s)return t?void 0:[];if(t!==void 0){let n=s.get(t);if(!n)return;if(this.isExpired(n)){s.delete(t),await this.persistTable(e);return}return n.value}let r=[],i=[];for(let[n,o]of s.entries())this.isExpired(o)?i.push(n):r.push([n,o.value]);if(i.length>0){for(let n of i)s.delete(n);await this.persistTable(e)}return r}catch(s){return console.error(`Read failed for ${e}:${t}:`,s),t?void 0:[]}}async delete(e,t){S(e),j(t);try{this.data.has(e)||await this.loadTable(e);let s=this.data.get(e);if(!s||!s.has(t))return!1;let r=s.get(t);return r?this.isExpired(r)?(s.delete(t),await this.persistTable(e),!1):(s.delete(t),await this.persistTable(e),!0):!1}catch(s){return console.error(`Delete failed for ${e}:${t}:`,s),!1}}async getTableSize(e){S(e);try{this.data.has(e)||await this.loadTable(e);let t=this.data.get(e);if(!t)return 0;let s=0,r=[];for(let[i,n]of t.entries())this.isExpired(n)?r.push(i):s++;if(r.length>0){for(let i of r)t.delete(i);await this.persistTable(e)}return s}catch(t){return console.error(`Get table size failed for ${e}:`,t),0}}isExpired(e){return e.expiration===null?!1:Date.now()>e.expiration}async cleanupExpired(e){S(e);try{this.data.has(e)||await this.loadTable(e);let t=this.data.get(e);if(!t)return 0;let s=[];for(let[r,i]of t.entries())this.isExpired(i)&&s.push(r);for(let r of s)t.delete(r);return s.length>0&&await this.persistTable(e),s.length}catch(t){return console.error(`Cleanup failed for ${e}:`,t),0}}async cleanupAllExpired(){let e=0;for(let t of this.data.keys())e+=await this.cleanupExpired(t);return e}async deleteTable(e){S(e);try{this.data.delete(e);let t=V(this.databaseDirectory,e);return H(t)&&await _(t),!0}catch(t){return console.error(`Delete table failed for ${e}:`,t),!1}}listTables(){return Array.from(this.data.keys())}async flush(){try{let e=Array.from(this.data.keys()).map(t=>this.persistTable(t));await Promise.all(e)}catch(e){throw console.error("Flush failed:",e),e}}async close(){await this.flush()}addDictionary(e,t){let s=R(t);this.dictionaries.set(e,s)}removeDictionary(e){return this.dictionaries.delete(e)}listDictionaries(){return Array.from(this.dictionaries.keys())}async loadTable(e){let t=V(this.databaseDirectory,e);if(!H(t)){this.data.set(e,new Map);return}try{let s=await je(t);if(s.length===0){this.data.set(e,new Map);return}let r=this.deserializeTable(s);this.data.set(e,r)}catch(s){console.error(`Failed to load table ${e}:`,s),this.data.set(e,new Map)}}async persistTable(e){let t=this.data.get(e);if(!t)return;let s=this.serializeTable(t),r=V(this.databaseDirectory,e),i=`${r}.tmp.${Date.now()}.${Math.random().toString(36).substring(7)}`;try{if(await Ie(i,s),this.useFsync){let n=await Oe(i,"r+");try{await n.sync()}finally{await n.close()}}if(await Me(i,r),this.useFsync){let n=Ae(r),o=Ee(n,"r");try{Re(o)}catch{}}}catch(n){try{await _(i)}catch{}throw n}}serializeTable(e){let t=Array.from(e.entries()).map(([s,r])=>{let i=r.dictionaryName?this.dictionaries.get(r.dictionaryName):void 0,n={d:i?P(r.value,i.deflate):r.value,v:r.version,t:r.timestamp,x:r.expiration};return r.dictionaryName&&(n.n=r.dictionaryName),[s,n]});return Buffer.from(JSON.stringify(t),"utf8")}deserializeTable(e){let s=JSON.parse(e.toString("utf8")).map(([r,i])=>{let n=i.n,o=n?this.dictionaries.get(n):void 0;return[r,{value:o?P(i.d,o.inflate):i.d,version:i.v,timestamp:i.t,expiration:i.x,dictionaryName:n||void 0}]});return new Map(s)}};import{join as me}from"node:path";import{statSync as Ke}from"node:fs";var y=class{isSilent;propertyPath="";constructor(e=!1){this.isSilent=e}test(e,t){if(!t)throw new Error("Missing input!");this.updatePropertyPath();let{results:s,errors:r}=this.validate(e.properties,t),i=this.compileErrors(s,r),n=this.isSuccessful(s,i);return{errors:i,success:n}}compileErrors(e,t){let s=e.filter(r=>r.success===!1);return[...t,...s].flatMap(r=>r)}isSuccessful(e,t){return e.every(s=>s.success===!0)&&t.length===0}validate(e,t,s=[],r=[]){let i=e?.additionalProperties??!0,n=e?.required||[];r=this.checkForRequiredKeysErrors(n,t,r),r=this.checkForDisallowedProperties(Object.keys(t),Object.keys(e),r,i);for(let o in e){let a=n.includes(o)&&o!=="required",d=e[o],l=t[o],f=d.additionalProperties??!0;a&&(r=this.checkForRequiredKeysErrors(d.required||[],l,r)),this.isDefined(l)&&(this.handleValidation(o,l,d,s),r=this.checkForDisallowedProperties(Object.keys(l),Object.keys(d),r,f),this.handleNestedObject(l,d,s,r))}return{results:s,errors:r}}updatePropertyPath(e,t=""){if(!e){this.propertyPath="";return}t&&(this.propertyPath=t),this.propertyPath=`${this.propertyPath}.${e}`,this.propertyPath.startsWith(".")&&(this.propertyPath=this.propertyPath.substring(1,this.propertyPath.length))}isDefined(e){return!!(typeof e=="number"&&e===0||e||e===""||typeof e=="boolean")}checkForRequiredKeysErrors(e,t,s){if(!this.areRequiredKeysPresent(e,t)){let r=t?Object.keys(t):[],i=this.findNonOverlappingElements(e,r),n=i.length>0?`Missing the required key: '${i.join(", ")}'!`:`Missing values for required keys: '${r.filter(o=>!t[o]).join(", ")}'!`;s.push({key:"",value:t,success:!1,error:n})}return s}checkForDisallowedProperties(e,t,s,r){if(!r){let i=this.findNonOverlappingElements(e,t);i.length>0&&s.push({key:`${t}`,value:e,success:!1,error:`Has additional (disallowed) properties: '${i.join(", ")}'!`})}return s}handleValidation(e,t,s,r){this.updatePropertyPath(e);let i=this.validateProperty(this.propertyPath,s,t);r.push(...i);let n=(a,d)=>{a.forEach(l=>{let f=this.validateProperty(this.propertyPath,d.items,l);r.push(...f)}),this.updatePropertyPath()},o=a=>{let d=Object.keys(a),l=this.propertyPath;d.forEach(f=>{if(this.updatePropertyPath(f,l),this.isArray(a[f])&&s[f]?.items!=null)n(a[f],s[f]);else{let c=this.validateProperty(this.propertyPath,s[f],a[f]);r.push(...c)}})};this.isArray(t)&&s.items!=null?n(t,s):this.isObject(t)?o(t):this.updatePropertyPath()}handleNestedObject(e,t,s,r){if(this.isObject(e)){let i=this.getNestedObjects(e);for(let n of i){let o=t[n],a=e[n];o&&typeof a=="object"&&this.validate(o,a,s,r)}}}getNestedObjects(e){return Object.keys(e).filter(t=>{if(this.isObject(e))return t})}findNonOverlappingElements(e,t){return e.filter(s=>!t.includes(s))}areRequiredKeysPresent(e,t=[]){return e.every(s=>Object.keys(t).includes(s)?this.isDefined(t[s]):!1)}validateProperty(e,t,s){return this.validateInput(t,s).map(i=>{let{success:n,error:o}=i;return{key:e,value:s,success:n,error:o??""}})}validateInput(e,t){if(e){let s=[{condition:()=>e.type,validator:()=>this.isCorrectType(e.type,t),error:"Invalid type"},{condition:()=>e.format,validator:()=>this.isCorrectFormat(e.format,t),error:"Invalid format"},{condition:()=>e.minLength,validator:()=>this.isMinimumLength(e.minLength,t),error:"Length too short"},{condition:()=>e.maxLength,validator:()=>this.isMaximumLength(e.maxLength,t),error:"Length too long"},{condition:()=>e.minValue,validator:()=>this.isMinimumValue(e.minValue,t),error:"Value too small"},{condition:()=>e.maxValue,validator:()=>this.isMaximumValue(e.maxValue,t),error:"Value too large"},{condition:()=>e.matchesPattern,validator:()=>this.matchesPattern(e.matchesPattern,t),error:"Pattern does not match"}],r=[];for(let i of s)i.condition()&&!i.validator()&&r.push({success:!1,error:i.error});return r}else this.isSilent||console.warn(`Missing property '${e}' for match '${t}'. Skipping...`);return[{success:!0}]}isCorrectType(e,t){return Array.isArray(e)||(e=[e]),e.some(s=>{switch(s){case"string":return typeof t=="string";case"number":return typeof t=="number"&&!isNaN(t);case"boolean":return typeof t=="boolean";case"object":return this.isObject(t);case"array":return this.isArray(t)}})}isObject(e){return e!==null&&!this.isArray(e)&&typeof e=="object"&&e instanceof Object&&Object.prototype.toString.call(e)==="[object Object]"}isArray(e){return Array.isArray(e)}isCorrectFormat(e,t){switch(e){case"alphanumeric":return new RegExp(/^[a-zA-Z0-9]+$/).test(t);case"numeric":return new RegExp(/^-?\d+(\.\d+)?$/).test(t);case"email":return new RegExp(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/).test(t);case"date":return new RegExp(/^\d{4}-\d{2}-\d{2}$/).test(t);case"url":return new RegExp(/^(https?):\/\/[^\s$.?#].[^\s]*$/).test(t);case"hexColor":return new RegExp(/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i).test(t)}}isMinimumLength(e,t){return Array.isArray(t)?t.length>=e:t?.toString().length>=e}isMaximumLength(e,t){return Array.isArray(t)?t.length<=e:t.toString().length<=e}isMinimumValue(e,t){return t>=e}isMaximumValue(e,t){return t<=e}matchesPattern(e,t){return new RegExp(e).test(t)}schemaFrom(e){let t={properties:{additionalProperties:!1,required:[]}};for(let s in e){let r=e[s];t.properties.required.push(s),Array.isArray(r)?t.properties[s]=this.generateArraySchema(r):typeof r=="object"&&r!==null?t.properties[s]=this.generateNestedObjectSchema(r):t.properties[s]=this.generatePropertySchema(r)}return t}generateArraySchema(e){let t={type:"array"},s=e.filter(r=>r);if(s.length>0){let r=s[0];s.every(n=>typeof n==typeof r)?typeof r=="object"&&!Array.isArray(r)?t.items=this.generateNestedObjectSchema(r):t.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 t}generateNestedObjectSchema(e){let t={type:"object",additionalProperties:!1,required:[]};for(let s in e){let r=e[s];t.required.push(s),typeof r=="object"&&!Array.isArray(r)&&r!==null?t[s]=this.generateNestedObjectSchema(r):t[s]=this.generatePropertySchema(r)}return t}generatePropertySchema(e){let t=typeof e,s={type:t};return t==="string"&&(s.minLength=1),s}};async function I(e){return e.body||{}}function h(e,t="An error occurred"){let s=e?.message||e||t,r=e?.cause?.statusCode||e?.statusCode||400;return{message:s,status:r}}function J(e,t,s={}){let r=Array.isArray(t)?t:[t];if(!e||!e.roles||!Array.isArray(e.roles)){let o=new Error("Unauthorized: User or roles missing");throw o.cause={statusCode:403},o}let i=e.roles.flatMap(o=>o?.policies?.flatMap(a=>(a?.permissions||[]).flatMap(l=>typeof l=="string"?l:l&&typeof l=="object"&&l.actions?l.actions:[]))||[]);if(!r.every(o=>i.some(a=>$e(a,o)))){let o=new Error("Unauthorized");throw o.cause={statusCode:403},o}return!0}function $e(e,t){if(e==="*"||e===t)return!0;if(!e.includes("*"))return!1;let s=e.split("*").map(i=>i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${s}$`).test(t)}function K(e,t,s,r,i){let n=e.find(d=>d.service===t);if(!n){let d=new Error(`Function bindings do not include access to service: ${t}`);throw d.cause={statusCode:403},d}if(!n.permissions||n.permissions.length===0)return;for(let d of n.permissions)if(!(d.resource&&d.resource!==s)){if(!d.resource||!d.actions||d.actions.length===0)return;if(d.actions.includes(r)&&!(d.targets&&d.targets.length>0&&(!i||!d.targets.includes(i)&&!d.targets.includes("*"))))return}let o=i?`:${i}`:"",a=new Error(`Function bindings do not allow: ${t}.${s}.${r}${o}`);throw a.cause={statusCode:403},a}import{readFileSync as ke,existsSync as Ne}from"node:fs";function x(){let e=process.env.MOLNOS_RUNTIME_CONFIG,t={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:"http://127.0.0.1:3000"},context:{apiUrl:"http://127.0.0.1:3000"},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(!e||!Ne(e))return t;try{let s=ke(e,"utf-8");return JSON.parse(s)}catch(s){return console.error("[loadRuntimeConfig] Failed to load runtime config:",s),t}}async function m(e,t,s,r,i,n,o){if(!t)return null;let a=e.headers["x-molnos-service-token"];if(a){let f=x();if(f.internalServiceSecret&&a===f.internalServiceSecret)return null}let d=e.state.user;if(!d){let f=e.headers.authorization;if(!f){let u=new Error("Unauthorized: No authentication provided");throw u.cause={statusCode:401},u}let c=f.replace(/^Bearer\s+/i,"");if(d=await t.getUserFromToken(c),!d){let u=new Error("Unauthorized: Invalid token");throw u.cause={statusCode:401},u}}J(d,s,{});let l=e.headers["x-function-bindings"];if(l)try{let f=Array.isArray(l)?l[0]:l,c=JSON.parse(f);K(c,r,i,n,o)}catch(f){if(f.cause?.statusCode===403)throw f;let c=new Error("Invalid function bindings header");throw c.cause={statusCode:400},c}return d}var p={ai:{generation:{generate:"ai.generation.generate",read:"ai.generation.read",apply:"ai.generation.apply",discard:"ai.generation.discard",delete:"ai.generation.delete"}},applications:{application:{create:"applications.application.create",read:"applications.application.read",list:"applications.application.list",update:"applications.application.update",delete:"applications.application.delete"}},contexts:{context:{create:"contexts.context.create",get:"contexts.context.get",update:"contexts.context.update",delete:"contexts.context.delete",deleteResources:"contexts.context.delete-resources"}},databases:{table:{create:"databases.table.create",get:"databases.table.get",update:"databases.table.update",delete:"databases.table.delete"}},functions:{function:{create:"functions.function.create",get:"functions.function.get",update:"functions.function.update",delete:"functions.function.delete",execute:"functions.function.execute"}},iac:{config:{create:"iac.config.create",get:"iac.config.get"}},identity:{identities:{get:"identity.identities.get"},user:{create:"identity.user.create",get:"identity.user.get",update:"identity.user.update",delete:"identity.user.delete"},role:{create:"identity.role.create",get:"identity.role.get",update:"identity.role.update",delete:"identity.role.delete"},serviceAccount:{create:"identity.service-account.create",get:"identity.service-account.get",update:"identity.service-account.update",delete:"identity.service-account.delete"}},management:{service:{create:"management.service.create",get:"management.service.get",update:"management.service.update",delete:"management.service.delete",start:"management.service.start",stop:"management.service.stop"},services:{get:"management.services.get"}},observability:{event:{create:"observability.event.create",read:"observability.event.read",delete:"observability.event.delete"},stats:{read:"observability.stats.read"},buffer:{write:"observability.buffer.write"},metrics:{read:"observability.metrics.read"}},schemas:{schema:{create:"schemas.schema.create",read:"schemas.schema.read",list:"schemas.schema.list",update:"schemas.schema.update",delete:"schemas.schema.delete"}},sites:{project:{create:"sites.project.create",list:"sites.project.list",delete:"sites.project.delete",download:"sites.project.download"}},storage:{bucket:{create:"storage.bucket.create",read:"storage.bucket.read",update:"storage.bucket.update",delete:"storage.bucket.delete",list:"storage.bucket.list"},object:{write:"storage.object.write",read:"storage.object.read",delete:"storage.object.delete",list:"storage.object.list"}}};function W(e,t){if(typeof e=="string"){t.push(e);return}if(!(!e||typeof e!="object"))for(let s of Object.values(e))W(s,t)}var X=[];W(p,X);var Le=[...new Set(X)],fr=Object.freeze(Le);var Y={properties:{tableName:{type:"string",minLength:1},key:{type:"string"}},required:["tableName"],additionalProperties:!1};var Ve=new y(!0);async function Z(e,t,s){try{let r=await I(e),i=Ve.test(Y,r);if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);let{tableName:n,key:o}=r;if(!n)return e.json("tableName is required",400);await m(e,s,p.databases.table.get,"databases","table","read",n);let a=await t.get(n,o);return a===void 0?e.json(null,404):e.json(a,200)}catch(r){let{message:i,status:n}=h(r,"Error getting table data");return e.json({error:i},n)}}var Q={properties:{tableName:{type:"string",minLength:1},key:{type:"string"},value:{},expiration:{type:"number"},dictionaryName:{type:"string"}},required:["tableName"],additionalProperties:!1};var qe=new y(!0);async function ee(e,t,s){try{let r=await I(e),i=qe.test(Q,r);if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);let{tableName:n,key:o,value:a,expiration:d,dictionaryName:l}=r;if(!n||a===void 0)return e.json("tableName and value are required",400);await m(e,s,p.databases.table.update,"databases","table","write",n);let f=await t.write(n,o,a,d,l);return e.json(f,200)}catch(r){let{message:i,status:n}=h(r,"Error writing table data");return e.json({error:i},n)}}var te={properties:{tableName:{type:"string",minLength:1},key:{type:"string",minLength:1}},required:["tableName","key"],additionalProperties:!1};var Be=new y(!0);async function re(e,t,s){try{let r=Be.test(te,e.query);if(!r.success)return e.json({error:"Invalid input",details:r.errors},400);let{tableName:i,key:n}=e.query;if(!i||!n)return e.json("tableName and key are required",400);await m(e,s,p.databases.table.delete,"databases","table","delete",i);let o=await t.delete(i,n);return e.json(o,200)}catch(r){let{message:i,status:n}=h(r,"Error deleting table item");return e.json({error:i},n)}}async function se(e,t,s,r,i,n,o){try{await m(e,s,p.databases.table.get,"databases","table","read");let a=t.listTables(),d=e.query.context;if(d&&r){let f=e.headers.authorization?.replace(/^Bearer\s+/i,""),c=await r.listResourcesByType(d,"database",f);a=a.filter(u=>c.includes(u))}let l=await Promise.all(a.map(async f=>{let c=await t.getTableSize(f),u=n(i,f);return{name:f,items:c,size:o(u)}}));return e.json({tables:l},200)}catch(a){let{message:d,status:l}=h(a,"Error listing tables");return e.json({error:d},l)}}var C={properties:{tableName:{type:"string",minLength:1},context:{type:"string",minLength:1}},required:["tableName"],additionalProperties:!1};var Ue=new y(!0);async function ie(e,t,s){try{let r=e.params.tableName;if(!r)return e.json({error:"tableName is required"},400);let i=Ue.test(C,{tableName:r});return i.success?(await m(e,s,p.databases.table.create,"databases","table","create",r),t.listTables().includes(r)?e.json({error:"Table already exists"},409):(await t.write(r,"__init__",null),await t.delete(r,"__init__"),e.json({success:!0,name:r,message:"Table created successfully"},201))):e.json({error:"Invalid input",details:i.errors},400)}catch(r){let{message:i,status:n}=h(r,"Error creating table");return e.json({error:i},n)}}var Ge=new y(!0);async function ne(e,t,s){try{let r=e.params.tableName;if(!r)return e.json({error:"tableName is required"},400);let i=Ge.test(C,{tableName:r});if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);if(await m(e,s,p.databases.table.delete,"databases","table","delete",r),!t.listTables().includes(r))return e.json({error:"Table not found"},404);let o=await t.deleteTable(r);return e.json({success:o,name:r,message:"Table deleted successfully"},200)}catch(r){let{message:i,status:n}=h(r,"Error deleting table");return e.json({error:i},n)}}var _e=new y(!0);async function oe(e,t,s,r,i,n){try{let o=e.params.tableName;if(!o)return e.json({error:"tableName is required"},400);let a=_e.test(C,{tableName:o});if(!a.success)return e.json({error:"Invalid input",details:a.errors},400);if(await m(e,s,p.databases.table.get,"databases","table","read",o),!t.listTables().includes(o))return e.json({error:"Table not found"},404);let l=await t.getTableSize(o),f=i(r,o);return e.json({name:o,items:l,size:n(f)},200)}catch(o){let{message:a,status:d}=h(o,"Error getting table info");return e.json({error:a},d)}}async function ae(e,t,s){try{if(!e.query.tableName)return e.json({error:"tableName is required"},400);let{tableName:r}=e.query;await m(e,s,p.databases.table.get,"databases","table","read",r);let i=await t.get(r),n=i?i.length:0;return e.json(n,200)}catch(r){let{message:i,status:n}=h(r,"Error getting table size");return e.json({error:i},n)}}var Je=new y(!0);async function le(e,t,s){try{let r=e.params.tableName;if(!r)return e.json({error:"tableName is required"},400);let i=Je.test(C,{tableName:r});if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);if(await m(e,s,p.databases.table.get,"databases","table","read",r),!t.listTables().includes(r))return e.json({error:"Table not found"},404);let o=await t.get(r),a=o?Object.entries(o).map(([d,l])=>Array.isArray(l)&&l.length===2?{key:l[0],value:l[1]}:{key:d,value:l}):[];return e.json({items:a},200)}catch(r){let{message:i,status:n}=h(r,"Error getting table items");return e.json({error:i},n)}}function ce(e,t){let s={enabled:!1,requestsPerMinute:0};if(!t)return s;let r=t.services?.[e];return r||(t.global?t.global:s)}function de(e,t){let s=e?.api?.port;if(!s)throw new Error('Missing "port" input when create API service!');let r=x(),i=e?.dataPath||r.molnos.dataPath,n=e?.api?.host||r.server.host,o=e?.identityApiUrl!==void 0?e.identityApiUrl:r.identity.apiUrl,a=e?.contextApiUrl!==void 0?e.contextApiUrl:r.context.apiUrl,d=e?.debug||!1,l;return t&&(l=ce(t,r.molnos.rateLimit)),{dataPath:i,api:{port:s,host:n},...o?{identityApiUrl:o}:{},...a?{contextApiUrl:a}:{},...l?{rateLimit:l}:{},debug:d}}var M=class{baseUrl;authToken;constructor(t,s){this.baseUrl=t.replace(/\/$/,""),this.authToken=s}async createCustomRole(t,s,r,i){let n=await fetch(`${this.baseUrl}/identity/roles`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({roleId:t,name:s,description:r,permissions:i})});if(!n.ok){let o=`Failed to create role: ${n.statusText}`;try{o=(await n.json()).error||o}catch{o=await n.text().catch(()=>n.statusText)||o}throw new Error(o)}}async updateRole(t,s){let r=await fetch(`${this.baseUrl}/identity/roles/${t}`,{method:"PATCH",headers:this.getHeaders(),body:JSON.stringify(s)});if(!r.ok){let i=await r.json();throw new Error(i.error||`Failed to update role: ${r.statusText}`)}}async deleteRole(t){let s=await fetch(`${this.baseUrl}/identity/roles/${t}`,{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(t,s,r){let i=await fetch(`${this.baseUrl}/identity/service-accounts`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:t,description:s,roles:r})});if(!i.ok){let o=`Failed to create service account: ${i.statusText}`;try{o=(await i.json()).error||o}catch{o=await i.text().catch(()=>i.statusText)||o}throw new Error(o)}let n=await i.json();return{id:n.id,apiKey:n.apiKey}}async deleteIdentity(t){let s=await fetch(`${this.baseUrl}/identity/service-accounts/${t}`,{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(t){try{let s=await fetch(`${this.baseUrl}/identity/whoami`,{method:"GET",headers:{Authorization:`Bearer ${t}`}});return s.ok?await s.json():null}catch{return null}}getHeaders(){let t={"Content-Type":"application/json"};return this.authToken&&(t.Authorization=`Bearer ${this.authToken}`),t}};function ue(e){return e?new M(e):null}var O=class{baseUrl;constructor(t){this.baseUrl=t.replace(/\/$/,"")}async listResourcesByType(t,s,r){let i=`${this.baseUrl}/contexts/${encodeURIComponent(t)}`;try{let n={"Content-Type":"application/json"};r&&(n.Authorization=`Bearer ${r}`);let o=await fetch(i,{method:"GET",headers:n});if(!o.ok)return[];let d=(await o.json()).context?.resources||{};switch(s){case"function":return d.functions||[];case"database":return d.databases||[];case"storage":return d.storage||[];case"site":return d.sites||[];default:return[]}}catch{return[]}}};function fe(e){return e?new O(e):null}function pe(e){if(e===0)return"0 B";let t=["B","KB","MB","GB"],s=Math.floor(Math.log(e)/Math.log(1024));return`${(e/1024**s).toFixed(1)} ${t[s]}`}function he(e,t){try{let s=me(e,t);return Ke(s).size}catch{return 0}}async function We(e){let t=e.dataPath||"data",s=me(t,"databases"),r=new D({databaseDirectory:s});await r.start();let i=ue(e.identityApiUrl),n=fe(e.contextApiUrl),o=x(),a=new L({port:e.api.port||o.services.databases.port,host:e.api.host||o.services.databases.host,rateLimit:e.rateLimit||o.molnos.rateLimit.global});return a.get("/table",async l=>ae(l,r,i)),a.post("/get",async l=>Z(l,r,i)),a.post("/write",async l=>ee(l,r,i)),a.delete("/delete",async l=>re(l,r,i)),a.get("/tables",async l=>se(l,r,i,n,s,he,pe)),a.post("/tables/:tableName",async l=>ie(l,r,i)),a.delete("/tables/:tableName",async l=>ne(l,r,i)),a.get("/tables/:tableName",async l=>oe(l,r,i,s,he,pe)),a.get("/tables/:tableName/items",async l=>le(l,r,i)),a.start()}if(import.meta.url===`file://${process.argv[1]}`){let e=x(),s=process.argv.slice(2).find(n=>n.startsWith("--port=")),r=s?parseInt(s.split("=")[1],10):e.services.databases.port,i=de({api:{port:r}},"databases");We(i)}export{We as startServer};
11
+ `),a="",d="",l,f;for(let u of o){let g=u.toLowerCase();if(g.startsWith("content-disposition:")){a=u.substring(20).trim();let v=a.match(/name="([^"]+)"/);v&&(d=v[1]);let w=a.match(/filename="([^"]+)"/);w&&(l=w[1])}else g.startsWith("content-type:")&&(f=u.substring(13).trim())}if(!d)return null;let c=i;return c.length>=2&&c[c.length-2]===13&&c[c.length-1]===10&&(c=c.subarray(0,c.length-2)),{disposition:a,name:d,filename:l,contentType:f,data:c}}import{readFileSync as T}from"fs";import N from"http";import Se from"http2";import xe from"https";var L=class{config;rateLimiter;router;shutdownHandlers=[];constructor(e){let t=new $(B(e||{})).get();t.debug&&console.log("Using configuration:",t),this.config=t,this.router=new z;let s=t.rateLimit.requestsPerMinute||E().rateLimit.requestsPerMinute;this.rateLimiter=new q(s,60),t.rateLimit.enabled===!0&&this.use(this.rateLimitMiddleware.bind(this))}use(e){return this.router.use(e),this}get(e,...t){return this.router.get(e,...t),this}post(e,...t){return this.router.post(e,...t),this}put(e,...t){return this.router.put(e,...t),this}delete(e,...t){return this.router.delete(e,...t),this}patch(e,...t){return this.router.patch(e,...t),this}any(e,...t){return this.router.any(e,...t),this}options(e,...t){return this.router.options(e,...t),this}start(){let e=this.createServer(),{port:t,host:s}=this.config;return this.setupGracefulShutdown(e),e.listen(t,s,()=>{let r=e.address(),i=this.config.useHttps||this.config.useHttp2?"https":"http";console.log(`MikroServe running at ${i}://${r.address!=="::"?r.address:"localhost"}:${r.port}`)}),e}createServer(){let e=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 t={key:T(this.config.sslKey),cert:T(this.config.sslCert),...this.config.sslCa?{ca:T(this.config.sslCa)}:{}};return Se.createSecureServer(t,e)}catch(t){throw t.message.includes("key values mismatch")?new Error(`SSL certificate and key do not match: ${t.message}`):t}}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 t={key:T(this.config.sslKey),cert:T(this.config.sslCert),...this.config.sslCa?{ca:T(this.config.sslCa)}:{}};return xe.createServer(t,e)}catch(t){throw t.message.includes("key values mismatch")?new Error(`SSL certificate and key do not match: ${t.message}`):t}}return N.createServer(e)}async rateLimitMiddleware(e,t){let s=e.req.socket.remoteAddress||"unknown";return e.res.setHeader("X-RateLimit-Limit",this.rateLimiter.getLimit().toString()),e.res.setHeader("X-RateLimit-Remaining",this.rateLimiter.getRemainingRequests(s).toString()),e.res.setHeader("X-RateLimit-Reset",this.rateLimiter.getResetTime(s).toString()),this.rateLimiter.isAllowed(s)?t():{statusCode:429,body:{error:"Too Many Requests",message:"Rate limit exceeded, please try again later"},headers:{"Content-Type":"application/json"}}}async requestHandler(e,t){let s=Date.now(),r=e.method||"UNKNOWN",i=e.url||"/unknown",n=this.config.debug;try{if(this.setCorsHeaders(t,e),this.setSecurityHeaders(t,this.config.useHttps),n&&console.log(`${r} ${i}`),e.method==="OPTIONS"){if(t instanceof N.ServerResponse)t.statusCode=204,t.end();else{let a=t;a.writeHead(204),a.end()}return}try{e.body=await this.parseBody(e)}catch(a){return n&&console.error("Body parsing error:",a.message),this.respond(t,{statusCode:400,body:{error:"Bad Request",message:a.message}})}let o=await this.router.handle(e,t);return o?o._handled?void 0:this.respond(t,o):this.respond(t,{statusCode:404,body:{error:"Not Found",message:"The requested endpoint does not exist"}})}catch(o){return console.error("Server error:",o),this.respond(t,{statusCode:500,body:{error:"Internal Server Error",message:n?o.message:"An unexpected error occurred"}})}finally{n&&this.logDuration(s,r,i)}}logDuration(e,t,s){let r=Date.now()-e;console.log(`${t} ${s} completed in ${r}ms`)}async parseBody(e){return new Promise((t,s)=>{let r=[],i=0,n=this.config.maxBodySize,o=!1,a=null,d=this.config.debug,l=e.headers["content-type"]||"";d&&console.log("Content-Type:",l),this.config.requestTimeout>0&&(a=setTimeout(()=>{o||(o=!0,d&&console.log("Request timeout exceeded"),s(new Error("Request timeout")))},this.config.requestTimeout));let f=()=>{a&&(clearTimeout(a),a=null)};e.on("data",c=>{if(!o){if(i+=c.length,d&&console.log(`Received chunk: ${c.length} bytes, total size: ${i}`),i>n){o=!0,f(),d&&console.log(`Body size exceeded limit: ${i} > ${n}`),s(new Error("Request body too large"));return}r.push(c)}}),e.on("end",()=>{if(!o){o=!0,f(),d&&console.log(`Request body complete: ${i} bytes`);try{if(r.length>0){let c=Buffer.concat(r);if(l.includes("application/json"))try{let u=c.toString("utf8");t(JSON.parse(u))}catch(u){s(new Error(`Invalid JSON in request body: ${u.message}`))}else if(l.includes("application/x-www-form-urlencoded")){let u=c.toString("utf8"),g={};new URLSearchParams(u).forEach((v,w)=>{g[w]=v}),t(g)}else if(l.includes("multipart/form-data"))try{let u=F(c,l);t(u)}catch(u){s(new Error(`Invalid multipart form data: ${u.message}`))}else this.isBinaryContentType(l)?t(c):t(c.toString("utf8"))}else t({})}catch(c){s(new Error(`Invalid request body: ${c}`))}}}),e.on("error",c=>{o||(o=!0,f(),s(new Error(`Error reading request body: ${c.message}`)))}),e.on("close",()=>{f()})})}isBinaryContentType(e){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=>e.includes(s))}setCorsHeaders(e,t){let s=t.headers.origin,{allowedDomains:r=["*"]}=this.config;!s||r.length===0||r.includes("*")?e.setHeader("Access-Control-Allow-Origin","*"):r.includes(s)&&(e.setHeader("Access-Control-Allow-Origin",s),e.setHeader("Vary","Origin")),e.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, PATCH, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),e.setHeader("Access-Control-Max-Age","86400")}setSecurityHeaders(e,t=!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((t||this.config.useHttp2)&&(s["Strict-Transport-Security"]="max-age=31536000; includeSubDomains"),e instanceof N.ServerResponse)Object.entries(s).forEach(([r,i])=>{e.setHeader(r,i)});else{let r=e;Object.entries(s).forEach(([i,n])=>{r.setHeader(i,n)})}}respond(e,t){let s={...t.headers||{}};(i=>typeof i.writeHead=="function"&&typeof i.end=="function")(e)?(e.writeHead(t.statusCode,s),t.body===null||t.body===void 0?e.end():t.isRaw||typeof t.body=="string"?e.end(t.body):e.end(JSON.stringify(t.body))):(console.warn("Unexpected response object type without writeHead/end methods"),e.writeHead?.(t.statusCode,s),t.body===null||t.body===void 0?e.end?.():t.isRaw||typeof t.body=="string"?e.end?.(t.body):e.end?.(JSON.stringify(t.body)))}setupGracefulShutdown(e){let t=o=>{console.log("Shutting down MikroServe server..."),o&&console.error("Error:",o),this.cleanupShutdownHandlers(),e.close(()=>{console.log("Server closed successfully"),process.env.NODE_ENV!=="test"&&process.env.VITEST!=="true"&&setImmediate(()=>process.exit(o?1:0))})},s=()=>t(),r=()=>t(),i=o=>t(o),n=o=>t(o);this.shutdownHandlers=[s,r,i,n],process.on("SIGINT",s),process.on("SIGTERM",r),process.on("uncaughtException",i),process.on("unhandledRejection",n)}cleanupShutdownHandlers(){if(this.shutdownHandlers.length>0){let[e,t,s,r]=this.shutdownHandlers;process.removeListener("SIGINT",e),process.removeListener("SIGTERM",t),process.removeListener("uncaughtException",s),process.removeListener("unhandledRejection",r),this.shutdownHandlers=[]}}};function R(e){if(!e.deflate&&!e.inflate)throw new Error("Dictionary must provide either deflate or inflate mapping");if(e.deflate&&e.inflate)throw new Error("Dictionary should provide only one of deflate or inflate (not both). The inverse will be auto-generated.");return e.deflate?{deflate:e.deflate,inflate:U(e.deflate)}:{deflate:U(e.inflate),inflate:e.inflate}}function U(e){let t={};for(let[s,r]of Object.entries(e))t[r]=s;return t}function P(e,t){if(e==null||typeof e!="object")return e;if(Array.isArray(e))return e.map(r=>P(r,t));let s={};for(let[r,i]of Object.entries(e)){let n=t[r]||r;s[n]=P(i,t)}return s}function S(e){if(!e||typeof e!="string")throw new Error("Table name must be a non-empty string");if(e.length>255)throw new Error("Table name must not exceed 255 characters");if(e.includes("/")||e.includes("\\"))throw new Error("Table name must not contain path separators");if(e.includes(".."))throw new Error('Table name must not contain ".."');if(e.startsWith("."))throw new Error('Table name must not start with "."');if(e.includes("\0"))throw new Error("Table name must not contain null bytes");if(["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"].includes(e.toUpperCase()))throw new Error(`Table name "${e}" is reserved by the filesystem`)}function j(e){if(e==null)throw new Error("Key must be defined");if(typeof e!="string")throw new Error("Key must be a string");if(e.length===0)throw new Error("Key must not be empty");if(e.length>1024)throw new Error("Key must not exceed 1024 characters");if(e.includes("\0"))throw new Error("Key must not contain null bytes")}function G(e){if(e===void 0)throw new Error("Value must not be undefined (use null instead)");let t=typeof e;if(t==="function")throw new Error("Value must be JSON-serializable: functions are not supported");if(t==="symbol")throw new Error("Value must be JSON-serializable: symbols are not supported");try{if(JSON.stringify(e)===void 0)throw new Error("Value must be JSON-serializable: value cannot be serialized")}catch(s){throw new Error(`Value must be JSON-serializable: ${s instanceof Error?s.message:String(s)}`)}}import{existsSync as H,mkdirSync as Te,readdirSync as Pe,openSync as Ee,closeSync as Re}from"fs";import{readFile as je,writeFile as Ie,rename as Me,unlink as _,open as Oe}from"fs/promises";import{join as V,dirname as Ae}from"path";var D=class{data=new Map;databaseDirectory;dictionaries=new Map;useFsync;constructor(e){this.databaseDirectory=e.databaseDirectory,this.useFsync=e.durableWrites??!1,e.dictionaries&&Object.entries(e.dictionaries).forEach(([t,s])=>{let r=R(s);this.dictionaries.set(t,r)}),H(this.databaseDirectory)||Te(this.databaseDirectory,{recursive:!0})}async start(){try{let e=Pe(this.databaseDirectory);for(let t of e)!t.endsWith(".tmp")&&!t.startsWith(".")&&await this.loadTable(t)}catch(e){throw console.error("Failed to start database:",e),e}}async write(e,t,s,r,i){if(S(e),j(t),G(s),i&&!this.dictionaries.has(i))throw new Error(`Dictionary "${i}" not found. Available dictionaries: ${Array.from(this.dictionaries.keys()).join(", ")||"none"}`);try{this.data.has(e)||this.data.set(e,new Map);let n=this.data.get(e),a=(n.get(t)?.version||0)+1,d={value:s,version:a,timestamp:Date.now(),expiration:r||null,dictionaryName:i||void 0};return n.set(t,d),await this.persistTable(e),!0}catch(n){return console.error(`Write failed for ${e}:${t}:`,n),!1}}async get(e,t){S(e),t!==void 0&&j(t);try{this.data.has(e)||await this.loadTable(e);let s=this.data.get(e);if(!s)return t?void 0:[];if(t!==void 0){let n=s.get(t);if(!n)return;if(this.isExpired(n)){s.delete(t),await this.persistTable(e);return}return n.value}let r=[],i=[];for(let[n,o]of s.entries())this.isExpired(o)?i.push(n):r.push([n,o.value]);if(i.length>0){for(let n of i)s.delete(n);await this.persistTable(e)}return r}catch(s){return console.error(`Read failed for ${e}:${t}:`,s),t?void 0:[]}}async delete(e,t){S(e),j(t);try{this.data.has(e)||await this.loadTable(e);let s=this.data.get(e);if(!s||!s.has(t))return!1;let r=s.get(t);return r?this.isExpired(r)?(s.delete(t),await this.persistTable(e),!1):(s.delete(t),await this.persistTable(e),!0):!1}catch(s){return console.error(`Delete failed for ${e}:${t}:`,s),!1}}async getTableSize(e){S(e);try{this.data.has(e)||await this.loadTable(e);let t=this.data.get(e);if(!t)return 0;let s=0,r=[];for(let[i,n]of t.entries())this.isExpired(n)?r.push(i):s++;if(r.length>0){for(let i of r)t.delete(i);await this.persistTable(e)}return s}catch(t){return console.error(`Get table size failed for ${e}:`,t),0}}isExpired(e){return e.expiration===null?!1:Date.now()>e.expiration}async cleanupExpired(e){S(e);try{this.data.has(e)||await this.loadTable(e);let t=this.data.get(e);if(!t)return 0;let s=[];for(let[r,i]of t.entries())this.isExpired(i)&&s.push(r);for(let r of s)t.delete(r);return s.length>0&&await this.persistTable(e),s.length}catch(t){return console.error(`Cleanup failed for ${e}:`,t),0}}async cleanupAllExpired(){let e=0;for(let t of this.data.keys())e+=await this.cleanupExpired(t);return e}async deleteTable(e){S(e);try{this.data.delete(e);let t=V(this.databaseDirectory,e);return H(t)&&await _(t),!0}catch(t){return console.error(`Delete table failed for ${e}:`,t),!1}}listTables(){return Array.from(this.data.keys())}async flush(){try{let e=Array.from(this.data.keys()).map(t=>this.persistTable(t));await Promise.all(e)}catch(e){throw console.error("Flush failed:",e),e}}async close(){await this.flush()}addDictionary(e,t){let s=R(t);this.dictionaries.set(e,s)}removeDictionary(e){return this.dictionaries.delete(e)}listDictionaries(){return Array.from(this.dictionaries.keys())}async loadTable(e){let t=V(this.databaseDirectory,e);if(!H(t)){this.data.set(e,new Map);return}try{let s=await je(t);if(s.length===0){this.data.set(e,new Map);return}let r=this.deserializeTable(s);this.data.set(e,r)}catch(s){console.error(`Failed to load table ${e}:`,s),this.data.set(e,new Map)}}async persistTable(e){let t=this.data.get(e);if(!t)return;let s=this.serializeTable(t),r=V(this.databaseDirectory,e),i=`${r}.tmp.${Date.now()}.${Math.random().toString(36).substring(7)}`;try{if(await Ie(i,s),this.useFsync){let n=await Oe(i,"r+");try{await n.sync()}finally{await n.close()}}if(await Me(i,r),this.useFsync){let n=Ae(r),o=Ee(n,"r");try{Re(o)}catch{}}}catch(n){try{await _(i)}catch{}throw n}}serializeTable(e){let t=Array.from(e.entries()).map(([s,r])=>{let i=r.dictionaryName?this.dictionaries.get(r.dictionaryName):void 0,n={d:i?P(r.value,i.deflate):r.value,v:r.version,t:r.timestamp,x:r.expiration};return r.dictionaryName&&(n.n=r.dictionaryName),[s,n]});return Buffer.from(JSON.stringify(t),"utf8")}deserializeTable(e){let s=JSON.parse(e.toString("utf8")).map(([r,i])=>{let n=i.n,o=n?this.dictionaries.get(n):void 0;return[r,{value:o?P(i.d,o.inflate):i.d,version:i.v,timestamp:i.t,expiration:i.x,dictionaryName:n||void 0}]});return new Map(s)}};import{join as me}from"node:path";import{statSync as Ke}from"node:fs";var y=class{isSilent;propertyPath="";constructor(e=!1){this.isSilent=e}test(e,t){if(!t)throw new Error("Missing input!");this.updatePropertyPath();let{results:s,errors:r}=this.validate(e.properties,t),i=this.compileErrors(s,r),n=this.isSuccessful(s,i);return{errors:i,success:n}}compileErrors(e,t){let s=e.filter(r=>r.success===!1);return[...t,...s].flatMap(r=>r)}isSuccessful(e,t){return e.every(s=>s.success===!0)&&t.length===0}validate(e,t,s=[],r=[]){let i=e?.additionalProperties??!0,n=e?.required||[];r=this.checkForRequiredKeysErrors(n,t,r),r=this.checkForDisallowedProperties(Object.keys(t),Object.keys(e),r,i);for(let o in e){let a=n.includes(o)&&o!=="required",d=e[o],l=t[o],f=d.additionalProperties??!0;a&&(r=this.checkForRequiredKeysErrors(d.required||[],l,r)),this.isDefined(l)&&(this.handleValidation(o,l,d,s),r=this.checkForDisallowedProperties(Object.keys(l),Object.keys(d),r,f),this.handleNestedObject(l,d,s,r))}return{results:s,errors:r}}updatePropertyPath(e,t=""){if(!e){this.propertyPath="";return}t&&(this.propertyPath=t),this.propertyPath=`${this.propertyPath}.${e}`,this.propertyPath.startsWith(".")&&(this.propertyPath=this.propertyPath.substring(1,this.propertyPath.length))}isDefined(e){return!!(typeof e=="number"&&e===0||e||e===""||typeof e=="boolean")}checkForRequiredKeysErrors(e,t,s){if(!this.areRequiredKeysPresent(e,t)){let r=t?Object.keys(t):[],i=this.findNonOverlappingElements(e,r),n=i.length>0?`Missing the required key: '${i.join(", ")}'!`:`Missing values for required keys: '${r.filter(o=>!t[o]).join(", ")}'!`;s.push({key:"",value:t,success:!1,error:n})}return s}checkForDisallowedProperties(e,t,s,r){if(!r){let i=this.findNonOverlappingElements(e,t);i.length>0&&s.push({key:`${t}`,value:e,success:!1,error:`Has additional (disallowed) properties: '${i.join(", ")}'!`})}return s}handleValidation(e,t,s,r){this.updatePropertyPath(e);let i=this.validateProperty(this.propertyPath,s,t);r.push(...i);let n=(a,d)=>{a.forEach(l=>{let f=this.validateProperty(this.propertyPath,d.items,l);r.push(...f)}),this.updatePropertyPath()},o=a=>{let d=Object.keys(a),l=this.propertyPath;d.forEach(f=>{if(this.updatePropertyPath(f,l),this.isArray(a[f])&&s[f]?.items!=null)n(a[f],s[f]);else{let c=this.validateProperty(this.propertyPath,s[f],a[f]);r.push(...c)}})};this.isArray(t)&&s.items!=null?n(t,s):this.isObject(t)?o(t):this.updatePropertyPath()}handleNestedObject(e,t,s,r){if(this.isObject(e)){let i=this.getNestedObjects(e);for(let n of i){let o=t[n],a=e[n];o&&typeof a=="object"&&this.validate(o,a,s,r)}}}getNestedObjects(e){return Object.keys(e).filter(t=>{if(this.isObject(e))return t})}findNonOverlappingElements(e,t){return e.filter(s=>!t.includes(s))}areRequiredKeysPresent(e,t=[]){return e.every(s=>Object.keys(t).includes(s)?this.isDefined(t[s]):!1)}validateProperty(e,t,s){return this.validateInput(t,s).map(i=>{let{success:n,error:o}=i;return{key:e,value:s,success:n,error:o??""}})}validateInput(e,t){if(e){let s=[{condition:()=>e.type,validator:()=>this.isCorrectType(e.type,t),error:"Invalid type"},{condition:()=>e.format,validator:()=>this.isCorrectFormat(e.format,t),error:"Invalid format"},{condition:()=>e.minLength,validator:()=>this.isMinimumLength(e.minLength,t),error:"Length too short"},{condition:()=>e.maxLength,validator:()=>this.isMaximumLength(e.maxLength,t),error:"Length too long"},{condition:()=>e.minValue,validator:()=>this.isMinimumValue(e.minValue,t),error:"Value too small"},{condition:()=>e.maxValue,validator:()=>this.isMaximumValue(e.maxValue,t),error:"Value too large"},{condition:()=>e.matchesPattern,validator:()=>this.matchesPattern(e.matchesPattern,t),error:"Pattern does not match"}],r=[];for(let i of s)i.condition()&&!i.validator()&&r.push({success:!1,error:i.error});return r}else this.isSilent||console.warn(`Missing property '${e}' for match '${t}'. Skipping...`);return[{success:!0}]}isCorrectType(e,t){return Array.isArray(e)||(e=[e]),e.some(s=>{switch(s){case"string":return typeof t=="string";case"number":return typeof t=="number"&&!isNaN(t);case"boolean":return typeof t=="boolean";case"object":return this.isObject(t);case"array":return this.isArray(t)}})}isObject(e){return e!==null&&!this.isArray(e)&&typeof e=="object"&&e instanceof Object&&Object.prototype.toString.call(e)==="[object Object]"}isArray(e){return Array.isArray(e)}isCorrectFormat(e,t){switch(e){case"alphanumeric":return new RegExp(/^[a-zA-Z0-9]+$/).test(t);case"numeric":return new RegExp(/^-?\d+(\.\d+)?$/).test(t);case"email":return new RegExp(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/).test(t);case"date":return new RegExp(/^\d{4}-\d{2}-\d{2}$/).test(t);case"url":return new RegExp(/^(https?):\/\/[^\s$.?#].[^\s]*$/).test(t);case"hexColor":return new RegExp(/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i).test(t)}}isMinimumLength(e,t){return Array.isArray(t)?t.length>=e:t?.toString().length>=e}isMaximumLength(e,t){return Array.isArray(t)?t.length<=e:t.toString().length<=e}isMinimumValue(e,t){return t>=e}isMaximumValue(e,t){return t<=e}matchesPattern(e,t){return new RegExp(e).test(t)}schemaFrom(e){let t={properties:{additionalProperties:!1,required:[]}};for(let s in e){let r=e[s];t.properties.required.push(s),Array.isArray(r)?t.properties[s]=this.generateArraySchema(r):typeof r=="object"&&r!==null?t.properties[s]=this.generateNestedObjectSchema(r):t.properties[s]=this.generatePropertySchema(r)}return t}generateArraySchema(e){let t={type:"array"},s=e.filter(r=>r);if(s.length>0){let r=s[0];s.every(n=>typeof n==typeof r)?typeof r=="object"&&!Array.isArray(r)?t.items=this.generateNestedObjectSchema(r):t.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 t}generateNestedObjectSchema(e){let t={type:"object",additionalProperties:!1,required:[]};for(let s in e){let r=e[s];t.required.push(s),typeof r=="object"&&!Array.isArray(r)&&r!==null?t[s]=this.generateNestedObjectSchema(r):t[s]=this.generatePropertySchema(r)}return t}generatePropertySchema(e){let t=typeof e,s={type:t};return t==="string"&&(s.minLength=1),s}};async function I(e){return e.body||{}}function h(e,t="An error occurred"){let s=e?.message||e||t,r=e?.cause?.statusCode||e?.statusCode||400;return{message:s,status:r}}function J(e,t,s={}){let r=Array.isArray(t)?t:[t];if(!e||!e.roles||!Array.isArray(e.roles)){let o=new Error("Unauthorized: User or roles missing");throw o.cause={statusCode:403},o}let i=e.roles.flatMap(o=>o?.policies?.flatMap(a=>(a?.permissions||[]).flatMap(l=>typeof l=="string"?l:l&&typeof l=="object"&&l.actions?l.actions:[]))||[]);if(!r.every(o=>i.some(a=>$e(a,o)))){let o=new Error("Unauthorized");throw o.cause={statusCode:403},o}return!0}function $e(e,t){if(e==="*"||e===t)return!0;if(!e.includes("*"))return!1;let s=e.split("*").map(i=>i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${s}$`).test(t)}function K(e,t,s,r,i){let n=e.find(d=>d.service===t);if(!n){let d=new Error(`Function bindings do not include access to service: ${t}`);throw d.cause={statusCode:403},d}if(!n.permissions||n.permissions.length===0)return;for(let d of n.permissions)if(!(d.resource&&d.resource!==s)){if(!d.resource||!d.actions||d.actions.length===0)return;if(d.actions.includes(r)&&!(d.targets&&d.targets.length>0&&(!i||!d.targets.includes(i)&&!d.targets.includes("*"))))return}let o=i?`:${i}`:"",a=new Error(`Function bindings do not allow: ${t}.${s}.${r}${o}`);throw a.cause={statusCode:403},a}import{readFileSync as ke,existsSync as Ne}from"node:fs";function x(){let e=process.env.MOLNOS_RUNTIME_CONFIG,t={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:"http://127.0.0.1:3000"},context:{apiUrl:"http://127.0.0.1:3000"},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(!e||!Ne(e))return t;try{let s=ke(e,"utf-8");return JSON.parse(s)}catch(s){return console.error("[loadRuntimeConfig] Failed to load runtime config:",s),t}}async function m(e,t,s,r,i,n,o){if(!t)return null;let a=e.headers["x-molnos-service-token"];if(a){let f=x();if(f.internalServiceSecret&&a===f.internalServiceSecret)return null}let d=e.state.user;if(!d){let f=e.headers.authorization;if(!f){let u=new Error("Unauthorized: No authentication provided");throw u.cause={statusCode:401},u}let c=f.replace(/^Bearer\s+/i,"");if(d=await t.getUserFromToken(c),!d){let u=new Error("Unauthorized: Invalid token");throw u.cause={statusCode:401},u}}J(d,s,{});let l=e.headers["x-function-bindings"];if(l)try{let f=Array.isArray(l)?l[0]:l,c=JSON.parse(f);K(c,r,i,n,o)}catch(f){if(f.cause?.statusCode===403)throw f;let c=new Error("Invalid function bindings header");throw c.cause={statusCode:400},c}return d}var p={applications:{application:{create:"applications.application.create",read:"applications.application.read",list:"applications.application.list",update:"applications.application.update",delete:"applications.application.delete"}},builder:{artifact:{read:"builder.artifact.read",list:"builder.artifact.list",update:"builder.artifact.update"},revision:{create:"builder.revision.create",read:"builder.revision.read",list:"builder.revision.list",activate:"builder.revision.activate"},run:{plan:"builder.run.plan",import:"builder.run.import",generate:"builder.run.generate",evolve:"builder.run.evolve",apply:"builder.run.apply",evaluate:"builder.run.evaluate",read:"builder.run.read",list:"builder.run.list"}},contexts:{context:{create:"contexts.context.create",get:"contexts.context.get",update:"contexts.context.update",delete:"contexts.context.delete",deleteResources:"contexts.context.delete-resources"}},databases:{table:{create:"databases.table.create",get:"databases.table.get",update:"databases.table.update",delete:"databases.table.delete"}},functions:{function:{create:"functions.function.create",get:"functions.function.get",update:"functions.function.update",delete:"functions.function.delete",execute:"functions.function.execute"}},iac:{config:{create:"iac.config.create",get:"iac.config.get"}},identity:{identities:{get:"identity.identities.get"},user:{create:"identity.user.create",get:"identity.user.get",update:"identity.user.update",delete:"identity.user.delete"},role:{create:"identity.role.create",get:"identity.role.get",update:"identity.role.update",delete:"identity.role.delete"},serviceAccount:{create:"identity.service-account.create",get:"identity.service-account.get",update:"identity.service-account.update",delete:"identity.service-account.delete"}},management:{service:{create:"management.service.create",get:"management.service.get",update:"management.service.update",delete:"management.service.delete",start:"management.service.start",stop:"management.service.stop"},services:{get:"management.services.get"}},observability:{event:{create:"observability.event.create",read:"observability.event.read",delete:"observability.event.delete"},stats:{read:"observability.stats.read"},buffer:{write:"observability.buffer.write"},metrics:{read:"observability.metrics.read"}},schemas:{schema:{create:"schemas.schema.create",read:"schemas.schema.read",list:"schemas.schema.list",update:"schemas.schema.update",delete:"schemas.schema.delete"}},sites:{project:{create:"sites.project.create",list:"sites.project.list",delete:"sites.project.delete",download:"sites.project.download"}},storage:{bucket:{create:"storage.bucket.create",read:"storage.bucket.read",update:"storage.bucket.update",delete:"storage.bucket.delete",list:"storage.bucket.list"},object:{write:"storage.object.write",read:"storage.object.read",delete:"storage.object.delete",list:"storage.object.list"}}};function W(e,t){if(typeof e=="string"){t.push(e);return}if(!(!e||typeof e!="object"))for(let s of Object.values(e))W(s,t)}var X=[];W(p,X);var Le=[...new Set(X)],fr=Object.freeze(Le);var Y={properties:{tableName:{type:"string",minLength:1},key:{type:"string"}},required:["tableName"],additionalProperties:!1};var Ve=new y(!0);async function Z(e,t,s){try{let r=await I(e),i=Ve.test(Y,r);if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);let{tableName:n,key:o}=r;if(!n)return e.json("tableName is required",400);await m(e,s,p.databases.table.get,"databases","table","read",n);let a=await t.get(n,o);return a===void 0?e.json(null,404):e.json(a,200)}catch(r){let{message:i,status:n}=h(r,"Error getting table data");return e.json({error:i},n)}}var Q={properties:{tableName:{type:"string",minLength:1},key:{type:"string"},value:{},expiration:{type:"number"},dictionaryName:{type:"string"}},required:["tableName"],additionalProperties:!1};var qe=new y(!0);async function ee(e,t,s){try{let r=await I(e),i=qe.test(Q,r);if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);let{tableName:n,key:o,value:a,expiration:d,dictionaryName:l}=r;if(!n||a===void 0)return e.json("tableName and value are required",400);await m(e,s,p.databases.table.update,"databases","table","write",n);let f=await t.write(n,o,a,d,l);return e.json(f,200)}catch(r){let{message:i,status:n}=h(r,"Error writing table data");return e.json({error:i},n)}}var te={properties:{tableName:{type:"string",minLength:1},key:{type:"string",minLength:1}},required:["tableName","key"],additionalProperties:!1};var Be=new y(!0);async function re(e,t,s){try{let r=Be.test(te,e.query);if(!r.success)return e.json({error:"Invalid input",details:r.errors},400);let{tableName:i,key:n}=e.query;if(!i||!n)return e.json("tableName and key are required",400);await m(e,s,p.databases.table.delete,"databases","table","delete",i);let o=await t.delete(i,n);return e.json(o,200)}catch(r){let{message:i,status:n}=h(r,"Error deleting table item");return e.json({error:i},n)}}async function se(e,t,s,r,i,n,o){try{await m(e,s,p.databases.table.get,"databases","table","read");let a=t.listTables(),d=e.query.context;if(d&&r){let f=e.headers.authorization?.replace(/^Bearer\s+/i,""),c=await r.listResourcesByType(d,"database",f);a=a.filter(u=>c.includes(u))}let l=await Promise.all(a.map(async f=>{let c=await t.getTableSize(f),u=n(i,f);return{name:f,items:c,size:o(u)}}));return e.json({tables:l},200)}catch(a){let{message:d,status:l}=h(a,"Error listing tables");return e.json({error:d},l)}}var C={properties:{tableName:{type:"string",minLength:1},context:{type:"string",minLength:1}},required:["tableName"],additionalProperties:!1};var Ue=new y(!0);async function ie(e,t,s){try{let r=e.params.tableName;if(!r)return e.json({error:"tableName is required"},400);let i=Ue.test(C,{tableName:r});return i.success?(await m(e,s,p.databases.table.create,"databases","table","create",r),t.listTables().includes(r)?e.json({error:"Table already exists"},409):(await t.write(r,"__init__",null),await t.delete(r,"__init__"),e.json({success:!0,name:r,message:"Table created successfully"},201))):e.json({error:"Invalid input",details:i.errors},400)}catch(r){let{message:i,status:n}=h(r,"Error creating table");return e.json({error:i},n)}}var Ge=new y(!0);async function ne(e,t,s){try{let r=e.params.tableName;if(!r)return e.json({error:"tableName is required"},400);let i=Ge.test(C,{tableName:r});if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);if(await m(e,s,p.databases.table.delete,"databases","table","delete",r),!t.listTables().includes(r))return e.json({error:"Table not found"},404);let o=await t.deleteTable(r);return e.json({success:o,name:r,message:"Table deleted successfully"},200)}catch(r){let{message:i,status:n}=h(r,"Error deleting table");return e.json({error:i},n)}}var _e=new y(!0);async function oe(e,t,s,r,i,n){try{let o=e.params.tableName;if(!o)return e.json({error:"tableName is required"},400);let a=_e.test(C,{tableName:o});if(!a.success)return e.json({error:"Invalid input",details:a.errors},400);if(await m(e,s,p.databases.table.get,"databases","table","read",o),!t.listTables().includes(o))return e.json({error:"Table not found"},404);let l=await t.getTableSize(o),f=i(r,o);return e.json({name:o,items:l,size:n(f)},200)}catch(o){let{message:a,status:d}=h(o,"Error getting table info");return e.json({error:a},d)}}async function ae(e,t,s){try{if(!e.query.tableName)return e.json({error:"tableName is required"},400);let{tableName:r}=e.query;await m(e,s,p.databases.table.get,"databases","table","read",r);let i=await t.get(r),n=i?i.length:0;return e.json(n,200)}catch(r){let{message:i,status:n}=h(r,"Error getting table size");return e.json({error:i},n)}}var Je=new y(!0);async function le(e,t,s){try{let r=e.params.tableName;if(!r)return e.json({error:"tableName is required"},400);let i=Je.test(C,{tableName:r});if(!i.success)return e.json({error:"Invalid input",details:i.errors},400);if(await m(e,s,p.databases.table.get,"databases","table","read",r),!t.listTables().includes(r))return e.json({error:"Table not found"},404);let o=await t.get(r),a=o?Object.entries(o).map(([d,l])=>Array.isArray(l)&&l.length===2?{key:l[0],value:l[1]}:{key:d,value:l}):[];return e.json({items:a},200)}catch(r){let{message:i,status:n}=h(r,"Error getting table items");return e.json({error:i},n)}}function ce(e,t){let s={enabled:!1,requestsPerMinute:0};if(!t)return s;let r=t.services?.[e];return r||(t.global?t.global:s)}function de(e,t){let s=e?.api?.port;if(!s)throw new Error('Missing "port" input when create API service!');let r=x(),i=e?.dataPath||r.molnos.dataPath,n=e?.api?.host||r.server.host,o=e?.identityApiUrl!==void 0?e.identityApiUrl:r.identity.apiUrl,a=e?.contextApiUrl!==void 0?e.contextApiUrl:r.context.apiUrl,d=e?.debug||!1,l;return t&&(l=ce(t,r.molnos.rateLimit)),{dataPath:i,api:{port:s,host:n},...o?{identityApiUrl:o}:{},...a?{contextApiUrl:a}:{},...l?{rateLimit:l}:{},debug:d}}var M=class{baseUrl;authToken;constructor(t,s){this.baseUrl=t.replace(/\/$/,""),this.authToken=s}async createCustomRole(t,s,r,i){let n=await fetch(`${this.baseUrl}/identity/roles`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({roleId:t,name:s,description:r,permissions:i})});if(!n.ok){let o=`Failed to create role: ${n.statusText}`;try{o=(await n.json()).error||o}catch{o=await n.text().catch(()=>n.statusText)||o}throw new Error(o)}}async updateRole(t,s){let r=await fetch(`${this.baseUrl}/identity/roles/${t}`,{method:"PATCH",headers:this.getHeaders(),body:JSON.stringify(s)});if(!r.ok){let i=await r.json();throw new Error(i.error||`Failed to update role: ${r.statusText}`)}}async deleteRole(t){let s=await fetch(`${this.baseUrl}/identity/roles/${t}`,{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(t,s,r){let i=await fetch(`${this.baseUrl}/identity/service-accounts`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:t,description:s,roles:r})});if(!i.ok){let o=`Failed to create service account: ${i.statusText}`;try{o=(await i.json()).error||o}catch{o=await i.text().catch(()=>i.statusText)||o}throw new Error(o)}let n=await i.json();return{id:n.id,apiKey:n.apiKey}}async deleteIdentity(t){let s=await fetch(`${this.baseUrl}/identity/service-accounts/${t}`,{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(t){try{let s=await fetch(`${this.baseUrl}/identity/whoami`,{method:"GET",headers:{Authorization:`Bearer ${t}`}});return s.ok?await s.json():null}catch{return null}}getHeaders(){let t={"Content-Type":"application/json"};return this.authToken&&(t.Authorization=`Bearer ${this.authToken}`),t}};function ue(e){return e?new M(e):null}var O=class{baseUrl;constructor(t){this.baseUrl=t.replace(/\/$/,"")}async listResourcesByType(t,s,r){let i=`${this.baseUrl}/contexts/${encodeURIComponent(t)}`;try{let n={"Content-Type":"application/json"};r&&(n.Authorization=`Bearer ${r}`);let o=await fetch(i,{method:"GET",headers:n});if(!o.ok)return[];let d=(await o.json()).context?.resources||{};switch(s){case"function":return d.functions||[];case"database":return d.databases||[];case"storage":return d.storage||[];case"site":return d.sites||[];default:return[]}}catch{return[]}}};function fe(e){return e?new O(e):null}function pe(e){if(e===0)return"0 B";let t=["B","KB","MB","GB"],s=Math.floor(Math.log(e)/Math.log(1024));return`${(e/1024**s).toFixed(1)} ${t[s]}`}function he(e,t){try{let s=me(e,t);return Ke(s).size}catch{return 0}}async function We(e){let t=e.dataPath||"data",s=me(t,"databases"),r=new D({databaseDirectory:s});await r.start();let i=ue(e.identityApiUrl),n=fe(e.contextApiUrl),o=x(),a=new L({port:e.api.port||o.services.databases.port,host:e.api.host||o.services.databases.host,rateLimit:e.rateLimit||o.molnos.rateLimit.global});return a.get("/table",async l=>ae(l,r,i)),a.post("/get",async l=>Z(l,r,i)),a.post("/write",async l=>ee(l,r,i)),a.delete("/delete",async l=>re(l,r,i)),a.get("/tables",async l=>se(l,r,i,n,s,he,pe)),a.post("/tables/:tableName",async l=>ie(l,r,i)),a.delete("/tables/:tableName",async l=>ne(l,r,i)),a.get("/tables/:tableName",async l=>oe(l,r,i,s,he,pe)),a.get("/tables/:tableName/items",async l=>le(l,r,i)),a.start()}if(import.meta.url===`file://${process.argv[1]}`){let e=x(),s=process.argv.slice(2).find(n=>n.startsWith("--port=")),r=s?parseInt(s.split("=")[1],10):e.services.databases.port,i=de({api:{port:r}},"databases");We(i)}export{We as startServer};
@@ -8,7 +8,7 @@ import{existsSync as V}from"node:fs";import{join as M}from"node:path";import{mkd
8
8
  `;return t}};var G={int:t=>{let e=t.trim();if(!/^[+-]?\d+$/.test(e))throw new Error(`Cannot parse "${t}" as an integer`);let r=Number.parseInt(e,10);if(Number.isNaN(r))throw new Error(`Cannot parse "${t}" as an integer`);return r},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 r=Number.parseFloat(e);if(Number.isNaN(r))throw new Error(`Cannot parse "${t}" as a number`);return r},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 b=H(),ue=t=>({configFilePath:"mikroserve.config.json",args:process.argv,options:[{flag:"--port",path:"port",defaultValue:b.port},{flag:"--host",path:"host",defaultValue:b.host},{flag:"--https",path:"useHttps",defaultValue:b.useHttps,isFlag:!0},{flag:"--http2",path:"useHttp2",defaultValue:b.useHttp2,isFlag:!0},{flag:"--cert",path:"sslCert",defaultValue:b.sslCert},{flag:"--key",path:"sslKey",defaultValue:b.sslKey},{flag:"--ca",path:"sslCa",defaultValue:b.sslCa},{flag:"--ratelimit",path:"rateLimit.enabled",defaultValue:b.rateLimit.enabled,isFlag:!0},{flag:"--rps",path:"rateLimit.requestsPerMinute",defaultValue:b.rateLimit.requestsPerMinute},{flag:"--allowed",path:"allowedDomains",defaultValue:b.allowedDomains,parser:G.array},{flag:"--debug",path:"debug",defaultValue:b.debug,isFlag:!0},{flag:"--max-body-size",path:"maxBodySize",defaultValue:b.maxBodySize},{flag:"--request-timeout",path:"requestTimeout",defaultValue:b.requestTimeout}],config:t});function le(t,e){let r=e.match(/boundary=(?:"([^"]+)"|([^;]+))/i);if(!r)throw new Error("Invalid multipart/form-data: missing boundary");let n=r[1]||r[2],s=Buffer.from(`--${n}`),i=Buffer.from(`--${n}--`),o={},a={},c=ke(t,s);for(let f of c){if(f.length===0||f.equals(i.subarray(s.length)))continue;let l=Me(f);if(!l)continue;let{name:u,filename:d,contentType:h,data:p}=l;if(d){let g={filename:d,contentType:h||"application/octet-stream",data:p,size:p.length};a[u]?Array.isArray(a[u])?a[u].push(g):a[u]=[a[u],g]:a[u]=g}else{let g=p.toString("utf8");o[u]?Array.isArray(o[u])?o[u].push(g):o[u]=[o[u],g]:o[u]=g}}return{fields:o,files:a}}function ke(t,e){let r=[],n=0;for(;n<t.length;){let s=t.indexOf(e,n);if(s===-1)break;n!==s&&r.push(t.subarray(n,s)),n=s+e.length,n<t.length&&t[n]===13&&t[n+1]===10&&(n+=2)}return r}function Me(t){let e=Buffer.from(`\r
9
9
  \r
10
10
  `),r=t.indexOf(e);if(r===-1)return null;let n=t.subarray(0,r),s=t.subarray(r+4),o=n.toString("utf8").split(`\r
11
- `),a="",c="",f,l;for(let d of o){let h=d.toLowerCase();if(h.startsWith("content-disposition:")){a=d.substring(20).trim();let p=a.match(/name="([^"]+)"/);p&&(c=p[1]);let g=a.match(/filename="([^"]+)"/);g&&(f=g[1])}else h.startsWith("content-type:")&&(l=d.substring(13).trim())}if(!c)return null;let u=s;return u.length>=2&&u[u.length-2]===13&&u[u.length-1]===10&&(u=u.subarray(0,u.length-2)),{disposition:a,name:c,filename:f,contentType:l,data:u}}import{readFileSync as R}from"fs";import J from"http";import He from"http2";import Ne from"https";var W=class{config;rateLimiter;router;shutdownHandlers=[];constructor(t){let e=new _(ue(t||{})).get();e.debug&&console.log("Using configuration:",e),this.config=e,this.router=new ce;let r=e.rateLimit.requestsPerMinute||H().rateLimit.requestsPerMinute;this.rateLimiter=new ae(r,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:r}=this.config;return this.setupGracefulShutdown(t),t.listen(e,r,()=>{let n=t.address(),s=this.config.useHttps||this.config.useHttp2?"https":"http";console.log(`MikroServe running at ${s}://${n.address!=="::"?n.address:"localhost"}:${n.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:R(this.config.sslKey),cert:R(this.config.sslCert),...this.config.sslCa?{ca:R(this.config.sslCa)}:{}};return He.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:R(this.config.sslKey),cert:R(this.config.sslCert),...this.config.sslCa?{ca:R(this.config.sslCa)}:{}};return Ne.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 J.createServer(t)}async rateLimitMiddleware(t,e){let r=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(r).toString()),t.res.setHeader("X-RateLimit-Reset",this.rateLimiter.getResetTime(r).toString()),this.rateLimiter.isAllowed(r)?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 r=Date.now(),n=t.method||"UNKNOWN",s=t.url||"/unknown",i=this.config.debug;try{if(this.setCorsHeaders(e,t),this.setSecurityHeaders(e,this.config.useHttps),i&&console.log(`${n} ${s}`),t.method==="OPTIONS"){if(e instanceof J.ServerResponse)e.statusCode=204,e.end();else{let a=e;a.writeHead(204),a.end()}return}try{t.body=await this.parseBody(t)}catch(a){return i&&console.error("Body parsing error:",a.message),this.respond(e,{statusCode:400,body:{error:"Bad Request",message:a.message}})}let o=await this.router.handle(t,e);return o?o._handled?void 0:this.respond(e,o):this.respond(e,{statusCode:404,body:{error:"Not Found",message:"The requested endpoint does not exist"}})}catch(o){return console.error("Server error:",o),this.respond(e,{statusCode:500,body:{error:"Internal Server Error",message:i?o.message:"An unexpected error occurred"}})}finally{i&&this.logDuration(r,n,s)}}logDuration(t,e,r){let n=Date.now()-t;console.log(`${e} ${r} completed in ${n}ms`)}async parseBody(t){return new Promise((e,r)=>{let n=[],s=0,i=this.config.maxBodySize,o=!1,a=null,c=this.config.debug,f=t.headers["content-type"]||"";c&&console.log("Content-Type:",f),this.config.requestTimeout>0&&(a=setTimeout(()=>{o||(o=!0,c&&console.log("Request timeout exceeded"),r(new Error("Request timeout")))},this.config.requestTimeout));let l=()=>{a&&(clearTimeout(a),a=null)};t.on("data",u=>{if(!o){if(s+=u.length,c&&console.log(`Received chunk: ${u.length} bytes, total size: ${s}`),s>i){o=!0,l(),c&&console.log(`Body size exceeded limit: ${s} > ${i}`),r(new Error("Request body too large"));return}n.push(u)}}),t.on("end",()=>{if(!o){o=!0,l(),c&&console.log(`Request body complete: ${s} bytes`);try{if(n.length>0){let u=Buffer.concat(n);if(f.includes("application/json"))try{let d=u.toString("utf8");e(JSON.parse(d))}catch(d){r(new Error(`Invalid JSON in request body: ${d.message}`))}else if(f.includes("application/x-www-form-urlencoded")){let d=u.toString("utf8"),h={};new URLSearchParams(d).forEach((p,g)=>{h[g]=p}),e(h)}else if(f.includes("multipart/form-data"))try{let d=le(u,f);e(d)}catch(d){r(new Error(`Invalid multipart form data: ${d.message}`))}else this.isBinaryContentType(f)?e(u):e(u.toString("utf8"))}else e({})}catch(u){r(new Error(`Invalid request body: ${u}`))}}}),t.on("error",u=>{o||(o=!0,l(),r(new Error(`Error reading request body: ${u.message}`)))}),t.on("close",()=>{l()})})}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(r=>t.includes(r))}setCorsHeaders(t,e){let r=e.headers.origin,{allowedDomains:n=["*"]}=this.config;!r||n.length===0||n.includes("*")?t.setHeader("Access-Control-Allow-Origin","*"):n.includes(r)&&(t.setHeader("Access-Control-Allow-Origin",r),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 r={"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)&&(r["Strict-Transport-Security"]="max-age=31536000; includeSubDomains"),t instanceof J.ServerResponse)Object.entries(r).forEach(([n,s])=>{t.setHeader(n,s)});else{let n=t;Object.entries(r).forEach(([s,i])=>{n.setHeader(s,i)})}}respond(t,e){let r={...e.headers||{}};(s=>typeof s.writeHead=="function"&&typeof s.end=="function")(t)?(t.writeHead(e.statusCode,r),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,r),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=o=>{console.log("Shutting down MikroServe server..."),o&&console.error("Error:",o),this.cleanupShutdownHandlers(),t.close(()=>{console.log("Server closed successfully"),process.env.NODE_ENV!=="test"&&process.env.VITEST!=="true"&&setImmediate(()=>process.exit(o?1:0))})},r=()=>e(),n=()=>e(),s=o=>e(o),i=o=>e(o);this.shutdownHandlers=[r,n,s,i],process.on("SIGINT",r),process.on("SIGTERM",n),process.on("uncaughtException",s),process.on("unhandledRejection",i)}cleanupShutdownHandlers(){if(this.shutdownHandlers.length>0){let[t,e,r,n]=this.shutdownHandlers;process.removeListener("SIGINT",t),process.removeListener("SIGTERM",e),process.removeListener("uncaughtException",r),process.removeListener("unhandledRejection",n),this.shutdownHandlers=[]}}};var v=class extends Error{constructor(e){super(),this.name="ValidationError",this.message=e||"Invalid input",this.cause={statusCode:400}}};var N=class extends Error{constructor(e){super(),this.name="NotFoundError",this.message=e||"Resource not found",this.cause={statusCode:404}}};var F=class extends Error{constructor(e){super(),this.name="InvalidMethodError",this.message=e||"Invalid HTTP method",this.cause={statusCode:400}}};var D=class extends Error{constructor(e){super(),this.name="ServiceRequestError",this.message=e||"Service request failed",this.cause={statusCode:502}}};var L=class{generatePermissionsFromBindings(e){let r=[];for(let n of e){let s=n.service;for(let i of n.permissions){if(!i.resource){r.push(`${s}.*`);continue}let o=i.resource,a=i.actions||["*"];if(i.targets&&i.targets.length>0)for(let c of a)for(let f of i.targets)r.push(`${s}.${o}.${c}:${f}`);else for(let c of a)r.push(`${s}.${o}.${c}`)}}return[...new Set(r)]}validateBindings(e){let r=["databases","storage","observability","sites","functions","events","schemas"];for(let n of e){if(!r.includes(n.service))throw new v(`Invalid service: ${n.service}. Must be one of: ${r.join(", ")}`);if(!n.permissions||n.permissions.length===0)throw new v("Bindings must have at least one permission");for(let s of n.permissions)if(s.targets&&s.targets.length>0){if(!s.resource)throw new v("Action-level bindings (with targets) must specify resource");if(!s.actions||s.actions.length===0)throw new v("Action-level bindings (with targets) must specify actions")}}}};var X=class{constructor(e,r,n){this.baseUrl=e;this.authToken=r;this.bindings=n}async request(e,r,n,s){let i=`${this.baseUrl}${r}`;if(s){let u=new URLSearchParams(s);i+=`?${u.toString()}`}let o={"Content-Type":"application/json"};this.authToken&&(o.Authorization=`Bearer ${this.authToken}`),this.bindings&&this.bindings.length>0&&(o["X-Function-Bindings"]=JSON.stringify(this.bindings));let a={method:e,headers:o};n&&(a.body=JSON.stringify(n));let c=await fetch(i,a),f=c.headers.get("content-type"),l;if(f?.includes("application/json")){let u=await c.text();u?l=JSON.parse(u):l=null}else l=await c.text();if(!c.ok)throw new D(`Service request failed (${c.status}): ${typeof l=="string"?l:JSON.stringify(l)}`);return l}},Y=class extends X{async get(e,r){return this.request("POST","/get",{tableName:e,key:r})}async write(e,r,n,s,i){return this.request("POST","/write",{tableName:e,key:r,value:n,expiration:s,dictionaryName:i})}async delete(e,r){return this.request("DELETE","/delete",void 0,{tableName:e,key:r})}async listTables(){return this.request("GET","/tables")}async getTableSize(e){return this.request("GET","/table",void 0,{tableName:e})}async getTableInfo(e){return this.request("GET",`/tables/${e}`)}async createTable(e){return this.request("POST",`/tables/${e}`)}async deleteTable(e){return this.request("DELETE",`/tables/${e}`)}},Z=class{constructor(e){this.eventBus=e}async emit(e,r){await this.eventBus.emit(e,r)}},K=class{constructor(e){this.schemaRegistry=e}validate(e,r,n){return this.schemaRegistry.validate(e,r,n)}},$=class{constructor(e,r,n,s){this.serviceBaseUrls=e;this.authToken=r;this.eventBus=n;this.schemaRegistry=s}createBindings(e){let r={};for(let n of e)switch(n.service){case"databases":{let s=this.serviceBaseUrls[n.service];if(!s)continue;r.databases=new Y(s,this.authToken,e);break}case"events":this.eventBus&&(r.events=new Z(this.eventBus));break;case"schemas":this.schemaRegistry&&(r.schemas=new K(this.schemaRegistry));break}return r}};var O=class{isSilent;propertyPath="";constructor(t=!1){this.isSilent=t}test(t,e){if(!e)throw new Error("Missing input!");this.updatePropertyPath();let{results:r,errors:n}=this.validate(t.properties,e),s=this.compileErrors(r,n),i=this.isSuccessful(r,s);return{errors:s,success:i}}compileErrors(t,e){let r=t.filter(n=>n.success===!1);return[...e,...r].flatMap(n=>n)}isSuccessful(t,e){return t.every(r=>r.success===!0)&&e.length===0}validate(t,e,r=[],n=[]){let s=t?.additionalProperties??!0,i=t?.required||[];n=this.checkForRequiredKeysErrors(i,e,n),n=this.checkForDisallowedProperties(Object.keys(e),Object.keys(t),n,s);for(let o in t){let a=i.includes(o)&&o!=="required",c=t[o],f=e[o],l=c.additionalProperties??!0;a&&(n=this.checkForRequiredKeysErrors(c.required||[],f,n)),this.isDefined(f)&&(this.handleValidation(o,f,c,r),n=this.checkForDisallowedProperties(Object.keys(f),Object.keys(c),n,l),this.handleNestedObject(f,c,r,n))}return{results:r,errors:n}}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,r){if(!this.areRequiredKeysPresent(t,e)){let n=e?Object.keys(e):[],s=this.findNonOverlappingElements(t,n),i=s.length>0?`Missing the required key: '${s.join(", ")}'!`:`Missing values for required keys: '${n.filter(o=>!e[o]).join(", ")}'!`;r.push({key:"",value:e,success:!1,error:i})}return r}checkForDisallowedProperties(t,e,r,n){if(!n){let s=this.findNonOverlappingElements(t,e);s.length>0&&r.push({key:`${e}`,value:t,success:!1,error:`Has additional (disallowed) properties: '${s.join(", ")}'!`})}return r}handleValidation(t,e,r,n){this.updatePropertyPath(t);let s=this.validateProperty(this.propertyPath,r,e);n.push(...s);let i=(a,c)=>{a.forEach(f=>{let l=this.validateProperty(this.propertyPath,c.items,f);n.push(...l)}),this.updatePropertyPath()},o=a=>{let c=Object.keys(a),f=this.propertyPath;c.forEach(l=>{if(this.updatePropertyPath(l,f),this.isArray(a[l])&&r[l]?.items!=null)i(a[l],r[l]);else{let u=this.validateProperty(this.propertyPath,r[l],a[l]);n.push(...u)}})};this.isArray(e)&&r.items!=null?i(e,r):this.isObject(e)?o(e):this.updatePropertyPath()}handleNestedObject(t,e,r,n){if(this.isObject(t)){let s=this.getNestedObjects(t);for(let i of s){let o=e[i],a=t[i];o&&typeof a=="object"&&this.validate(o,a,r,n)}}}getNestedObjects(t){return Object.keys(t).filter(e=>{if(this.isObject(t))return e})}findNonOverlappingElements(t,e){return t.filter(r=>!e.includes(r))}areRequiredKeysPresent(t,e=[]){return t.every(r=>Object.keys(e).includes(r)?this.isDefined(e[r]):!1)}validateProperty(t,e,r){return this.validateInput(e,r).map(s=>{let{success:i,error:o}=s;return{key:t,value:r,success:i,error:o??""}})}validateInput(t,e){if(t){let r=[{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"}],n=[];for(let s of r)s.condition()&&!s.validator()&&n.push({success:!1,error:s.error});return n}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(r=>{switch(r){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 r in t){let n=t[r];e.properties.required.push(r),Array.isArray(n)?e.properties[r]=this.generateArraySchema(n):typeof n=="object"&&n!==null?e.properties[r]=this.generateNestedObjectSchema(n):e.properties[r]=this.generatePropertySchema(n)}return e}generateArraySchema(t){let e={type:"array"},r=t.filter(n=>n);if(r.length>0){let n=r[0];r.every(i=>typeof i==typeof n)?typeof n=="object"&&!Array.isArray(n)?e.items=this.generateNestedObjectSchema(n):e.items=this.generatePropertySchema(n):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 r in t){let n=t[r];e.required.push(r),typeof n=="object"&&!Array.isArray(n)&&n!==null?e[r]=this.generateNestedObjectSchema(n):e[r]=this.generatePropertySchema(n)}return e}generatePropertySchema(t){let e=typeof t,r={type:e};return e==="string"&&(r.minLength=1),r}};async function j(t){return t.body||{}}function S(t,e="An error occurred"){let r=t?.message||t||e,n=t?.cause?.statusCode||t?.statusCode||400;return{message:r,status:n}}function de(t,e,r={}){let n=Array.isArray(e)?e:[e];if(!t||!t.roles||!Array.isArray(t.roles)){let o=new Error("Unauthorized: User or roles missing");throw o.cause={statusCode:403},o}let s=t.roles.flatMap(o=>o?.policies?.flatMap(a=>(a?.permissions||[]).flatMap(f=>typeof f=="string"?f:f&&typeof f=="object"&&f.actions?f.actions:[]))||[]);if(!n.every(o=>s.some(a=>De(a,o)))){let o=new Error("Unauthorized");throw o.cause={statusCode:403},o}return!0}function De(t,e){if(t==="*"||t===e)return!0;if(!t.includes("*"))return!1;let r=t.split("*").map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${r}$`).test(e)}function fe(t,e,r,n,s){let i=t.find(c=>c.service===e);if(!i){let c=new Error(`Function bindings do not include access to service: ${e}`);throw c.cause={statusCode:403},c}if(!i.permissions||i.permissions.length===0)return;for(let c of i.permissions)if(!(c.resource&&c.resource!==r)){if(!c.resource||!c.actions||c.actions.length===0)return;if(c.actions.includes(n)&&!(c.targets&&c.targets.length>0&&(!s||!c.targets.includes(s)&&!c.targets.includes("*"))))return}let o=s?`:${s}`:"",a=new Error(`Function bindings do not allow: ${e}.${r}.${n}${o}`);throw a.cause={statusCode:403},a}import{readFileSync as Le,existsSync as Ue}from"node:fs";function E(){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:"http://127.0.0.1:3000"},context:{apiUrl:"http://127.0.0.1:3000"},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||!Ue(t))return e;try{let r=Le(t,"utf-8");return JSON.parse(r)}catch(r){return console.error("[loadRuntimeConfig] Failed to load runtime config:",r),e}}async function x(t,e,r,n,s,i,o){if(!e)return null;let a=t.headers["x-molnos-service-token"];if(a){let l=E();if(l.internalServiceSecret&&a===l.internalServiceSecret)return null}let c=t.state.user;if(!c){let l=t.headers.authorization;if(!l){let d=new Error("Unauthorized: No authentication provided");throw d.cause={statusCode:401},d}let u=l.replace(/^Bearer\s+/i,"");if(c=await e.getUserFromToken(u),!c){let d=new Error("Unauthorized: Invalid token");throw d.cause={statusCode:401},d}}de(c,r,{});let f=t.headers["x-function-bindings"];if(f)try{let l=Array.isArray(f)?f[0]:f,u=JSON.parse(l);fe(u,n,s,i,o)}catch(l){if(l.cause?.statusCode===403)throw l;let u=new Error("Invalid function bindings header");throw u.cause={statusCode:400},u}return c}var w={ai:{generation:{generate:"ai.generation.generate",read:"ai.generation.read",apply:"ai.generation.apply",discard:"ai.generation.discard",delete:"ai.generation.delete"}},applications:{application:{create:"applications.application.create",read:"applications.application.read",list:"applications.application.list",update:"applications.application.update",delete:"applications.application.delete"}},contexts:{context:{create:"contexts.context.create",get:"contexts.context.get",update:"contexts.context.update",delete:"contexts.context.delete",deleteResources:"contexts.context.delete-resources"}},databases:{table:{create:"databases.table.create",get:"databases.table.get",update:"databases.table.update",delete:"databases.table.delete"}},functions:{function:{create:"functions.function.create",get:"functions.function.get",update:"functions.function.update",delete:"functions.function.delete",execute:"functions.function.execute"}},iac:{config:{create:"iac.config.create",get:"iac.config.get"}},identity:{identities:{get:"identity.identities.get"},user:{create:"identity.user.create",get:"identity.user.get",update:"identity.user.update",delete:"identity.user.delete"},role:{create:"identity.role.create",get:"identity.role.get",update:"identity.role.update",delete:"identity.role.delete"},serviceAccount:{create:"identity.service-account.create",get:"identity.service-account.get",update:"identity.service-account.update",delete:"identity.service-account.delete"}},management:{service:{create:"management.service.create",get:"management.service.get",update:"management.service.update",delete:"management.service.delete",start:"management.service.start",stop:"management.service.stop"},services:{get:"management.services.get"}},observability:{event:{create:"observability.event.create",read:"observability.event.read",delete:"observability.event.delete"},stats:{read:"observability.stats.read"},buffer:{write:"observability.buffer.write"},metrics:{read:"observability.metrics.read"}},schemas:{schema:{create:"schemas.schema.create",read:"schemas.schema.read",list:"schemas.schema.list",update:"schemas.schema.update",delete:"schemas.schema.delete"}},sites:{project:{create:"sites.project.create",list:"sites.project.list",delete:"sites.project.delete",download:"sites.project.download"}},storage:{bucket:{create:"storage.bucket.create",read:"storage.bucket.read",update:"storage.bucket.update",delete:"storage.bucket.delete",list:"storage.bucket.list"},object:{write:"storage.object.write",read:"storage.object.read",delete:"storage.object.delete",list:"storage.object.list"}}};function pe(t,e){if(typeof t=="string"){e.push(t);return}if(!(!t||typeof t!="object"))for(let r of Object.values(t))pe(r,e)}var he=[];pe(w,he);var qe=[...new Set(he)],pr=Object.freeze(qe);var ge={properties:{id:{type:"string",minLength:1,maxLength:40,pattern:"^[a-zA-Z0-9_-]{1,40}$"},name:{type:"string",minLength:1},code:{type:"string",minLength:1},methods:{type:"array",items:{type:"string"}},bindings:{type:"array"},trigger:{type:"object"},triggers:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["http","event"]},eventName:{type:"string"}},required:["type"]}},passAllHeaders:{type:"boolean"},allowUnauthenticated:{type:"boolean"},context:{type:"string",minLength:1}},required:["name","code"],additionalProperties:!1};var Ve=new O(!0);async function me(t,e,r){try{let n=await j(t),s=Ve.test(ge,n);if(!s.success)return t.json({error:"Invalid input",details:s.errors},400);await x(t,r,w.functions.function.create,"functions","function","create");let{id:i,name:o,code:a,methods:c,bindings:f,trigger:l,triggers:u,passAllHeaders:d,allowUnauthenticated:h}=n,p=u||(l?[l]:void 0),g=await e.deployFunction(o,a,c,f,p,d,h,i);return t.json({success:!0,function:g},201)}catch(n){let{message:s,status:i}=S(n,"Error deploying function");return t.json({error:s},i)}}async function ye(t,e,r){try{let n=t.params.functionId;if(!n)return t.json({error:"functionId is required"},400);let s=e.getFunction(n);return s?s.triggers&&s.triggers.length>0&&!s.triggers.some(i=>i.type==="http")?t.json({error:"Not Found",message:"Function not found"},404):(s.allowUnauthenticated!==!0&&await x(t,r,w.functions.function.execute,"functions","function","execute",n),await e.executeFunction(n,t)):t.json({error:"Not Found",message:"Function not found"},404)}catch(n){let{message:s,status:i}=S(n,"Error executing function");return t.json({error:s},i)}}var ve={properties:{code:{type:"string",minLength:1},methods:{type:"array",items:{type:"string"}},bindings:{type:"array"},trigger:{type:"object"},triggers:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["http","event"]},eventName:{type:"string"}},required:["type"]}},passAllHeaders:{type:"boolean"},allowUnauthenticated:{type:"boolean"}},additionalProperties:!1};var _e=new O(!0);async function be(t,e,r){try{let n=t.params.functionId,s=await j(t);if(!n)return t.json({error:"functionId is required"},400);let i=_e.test(ve,s);if(!i.success)return t.json({error:"Invalid input",details:i.errors},400);await x(t,r,w.functions.function.update,"functions","function","update",n);let{code:o,methods:a,bindings:c,trigger:f,triggers:l,passAllHeaders:u,allowUnauthenticated:d}=s,h=l||(f?[f]:void 0),p=await e.updateFunction(n,{code:o,methods:a,bindings:c,triggers:h,passAllHeaders:u,allowUnauthenticated:d});return p?t.json({success:!0,function:p},200):t.json({error:"Function not found"},404)}catch(n){let{message:s,status:i}=S(n,"Error updating function");return t.json({error:s},i)}}async function we(t,e,r){try{let n=t.params.functionId;return n?(await x(t,r,w.functions.function.delete,"functions","function","delete",n),await e.deleteFunction(n)?t.json({success:!0,message:"Function deleted"},200):t.json({error:"Function not found"},404)):t.json({error:"functionId is required"},400)}catch(n){let{message:s,status:i}=S(n,"Error deleting function");return t.json({error:s},i)}}async function Se(t,e,r){try{let n=t.params.functionId;if(!n)return t.json({error:"functionId is required"},400);await x(t,r,w.functions.function.get,"functions","function","read",n);let s=e.getFunction(n);return s?t.json({success:!0,function:s},200):t.json({error:"Function not found"},404)}catch(n){let{message:s,status:i}=S(n,"Error getting function");return t.json({error:s},i)}}async function xe(t,e,r,n){try{await x(t,r,w.functions.function.get,"functions","function","read");let s=e.getFunctions(),i=t.query.context;if(i&&n){let o=t.headers.authorization?.replace(/^Bearer\s+/i,""),a=await n.listResourcesByType(i,"function",o);s=s.filter(c=>a.includes(c.id))}return t.json({success:!0,count:s.length,functions:s},200)}catch(s){let{message:i,status:o}=S(s,"Error listing functions");return t.json({error:i},o)}}import{EventEmitter as Ge}from"node:events";var Q=class t{static instance;constructor(){}static getInstance(){return t.instance||(t.instance=new Ge,t.instance.setMaxListeners(100)),t.instance}};function ee(){return Q.getInstance()}function Ee(t){let e=ee();try{e.emit("function.log",t)}catch(r){console.error("Failed to emit function log event:",r)}}import{getRandomValues as Je}from"node:crypto";var te=class{options;defaultLength=16;defaultOnlyLowerCase=!1;defaultStyle="extended";defaultUrlSafe=!0;constructor(t){if(this.options={},t)for(let[e,r]of Object.entries(t))this.options[e]=this.generateConfig(r)}add(t){if(!t?.name)throw new Error("Missing name for the ID configuration");let e=this.generateConfig(t);this.options[t.name]=e}remove(t){if(!t?.name)throw new Error("Missing name for the ID configuration");delete this.options[t.name]}create(t,e,r,n){let s=this.generateConfig({length:t,style:e,onlyLowerCase:r,urlSafe:n});return this.generateId(s)}custom(t){if(this.options[t])return this.generateId(this.options[t]);throw new Error(`No configuration found with name: ${t}`)}generateConfig(t){return{name:t?.name||"",length:t?.length||this.defaultLength,onlyLowerCase:t?.onlyLowerCase??this.defaultOnlyLowerCase,style:t?.style||this.defaultStyle,urlSafe:t?.urlSafe??this.defaultUrlSafe}}getCharacterSet(t,e,r){if(t==="hex")return e?"0123456789abcdef":"0123456789ABCDEFabcdef";if(t==="alphanumeric")return e?"abcdefghijklmnopqrstuvwxyz0123456789":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";if(t==="extended")return r?e?"abcdefghijklmnopqrstuvwxyz0123456789-._~":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~":e?"abcdefghijklmnopqrstuvwxyz0123456789-._~!$()*+,;=:":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$()*+,;=:";throw new Error(`Unknown ID style "${t} provided. Must be one of "extended" (default), "alphanumeric", or "hex".`)}generateId(t){let{length:e,onlyLowerCase:r,style:n,urlSafe:s}=t;if(e<0||e===0)throw new Error("ID length cannot be negative");let i=this.getCharacterSet(n,r,s),o=(2<<Math.log(i.length-1)/Math.LN2)-1,a=Math.ceil(1.6*o*e/i.length),c="";for(;c.length<e;){let f=new Uint8Array(a);Je(f);for(let l=0;l<a;l++){let u=f[l]&o;if(u<i.length&&(c+=i[u],c.length===e))break}}return c}};var We=8,Xe=40,Ye=/^[a-zA-Z0-9_-]{1,40}$/;function Ze(){return new te().create(We,"alphanumeric",!1,!0)}function Ke(t){return Ye.test(t)}function Qe(t){if(!Ke(t))throw new Error(`Invalid ID format: "${t}". IDs must be 1-${Xe} characters using only alphanumeric characters, underscores, and hyphens.`)}function re(t){return t?(Qe(t),t):Ze()}import{EventEmitter as et}from"events";var ne=class{emitter;targets={};options;constructor(t){this.emitter=new et,t?.maxListeners===0?this.emitter.setMaxListeners(0):this.emitter.setMaxListeners(t?.maxListeners||10),this.options={errorHandler:t?.errorHandler||(e=>console.error(e)),isSilent:t?.isSilent||!1}}addTarget(t){return(Array.isArray(t)?t:[t]).map(n=>this.targets[n.name]?(this.options.isSilent||console.error(`Target with name '${n.name}' already exists.`),!1):(this.targets[n.name]={name:n.name,url:n.url,headers:n.headers||{},events:n.events||[]},!0)).every(n=>n===!0)}updateTarget(t,e){if(!this.targets[t])return console.error(`Target with name '${t}' does not exist.`),!1;let r=this.targets[t];return e.url!==void 0&&(r.url=e.url),e.headers&&(r.headers={...r.headers,...e.headers}),e.events&&(r.events=e.events),!0}removeTarget(t){return this.targets[t]?(delete this.targets[t],!0):(console.error(`Target with name '${t}' does not exist.`),!1)}addEventToTarget(t,e){if(!this.targets[t])return console.error(`Target with name '${t}' does not exist.`),!1;let r=Array.isArray(e)?e:[e],n=this.targets[t];return r.forEach(s=>{n.events.includes(s)||n.events.push(s)}),!0}on(t,e){return this.emitter.on(t,e),this}off(t,e){return this.emitter.off(t,e),this}once(t,e){return this.emitter.once(t,e),this}async emit(t,e){let r={success:!0,errors:[]},n=(o,a,c)=>({target:o,event:a,error:c}),s=Object.values(this.targets).filter(o=>o.events.includes(t)||o.events.includes("*"));s.filter(o=>!o.url).forEach(o=>{try{this.emitter.emit(t,e)}catch(a){let c=a instanceof Error?a:new Error(String(a));r.errors.push({target:o.name,event:t,error:c}),this.options.errorHandler(c,t,e),r.success=!1}});let i=s.filter(o=>o.url);if(i.length>0){let o=i.map(async a=>{try{let c=await fetch(a.url,{method:"POST",headers:{"Content-Type":"application/json",...a.headers},body:JSON.stringify({eventName:t,data:e})});if(!c.ok){let f=`HTTP error! Status: ${c.status}: ${c.statusText}`,l=new Error(f);r.errors.push(n(a.name,t,l)),this.options.errorHandler(l,t,e),r.success=!1}}catch(c){let f=c instanceof Error?c:new Error(String(c));r.errors.push(n(a.name,t,f)),this.options.errorHandler(f,t,e),r.success=!1}});await Promise.allSettled(o)}return r}async handleIncomingEvent(t){try{let{eventName:e,data:r}=typeof t=="string"?JSON.parse(t):t;process.nextTick(()=>{try{this.emitter.emit(e,r)}catch(n){this.options.errorHandler(n instanceof Error?n:new Error(String(n)),e,r)}})}catch(e){throw this.options.errorHandler(e instanceof Error?e:new Error(String(e)),"parse_event"),e}}createMiddleware(){return async(t,e,r)=>{if(t.method!=="POST"){r&&r();return}if(t.body)try{await this.handleIncomingEvent(t.body),e.statusCode=202,e.end()}catch(n){e.statusCode=400,e.end(JSON.stringify({error:"Invalid event format"})),r&&r(n)}else{let n="";t.on("data",s=>n+=s.toString()),t.on("end",async()=>{try{await this.handleIncomingEvent(n),e.statusCode=202,e.end()}catch(s){e.statusCode=400,e.end(JSON.stringify({error:"Invalid event format"})),r&&r(s)}})}}}};var U=null;function k(){return U||(U=new ne,U.addTarget({name:"molnos-internal",events:["*"]})),U}var tt=null;function se(){return tt||void 0}function Ce(t,e){let r={enabled:!1,requestsPerMinute:0};if(!e)return r;let n=e.services?.[t];return n||(e.global?e.global:r)}function Pe(t,e){let r=t?.api?.port;if(!r)throw new Error('Missing "port" input when create API service!');let n=E(),s=t?.dataPath||n.molnos.dataPath,i=t?.api?.host||n.server.host,o=t?.identityApiUrl!==void 0?t.identityApiUrl:n.identity.apiUrl,a=t?.contextApiUrl!==void 0?t.contextApiUrl:n.context.apiUrl,c=t?.debug||!1,f;return e&&(f=Ce(e,n.molnos.rateLimit)),{dataPath:s,api:{port:r,host:i},...o?{identityApiUrl:o}:{},...a?{contextApiUrl:a}:{},...f?{rateLimit:f}:{},debug:c}}var q=class{baseUrl;authToken;constructor(e,r){this.baseUrl=e.replace(/\/$/,""),this.authToken=r}async createCustomRole(e,r,n,s){let i=await fetch(`${this.baseUrl}/identity/roles`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({roleId:e,name:r,description:n,permissions:s})});if(!i.ok){let o=`Failed to create role: ${i.statusText}`;try{o=(await i.json()).error||o}catch{o=await i.text().catch(()=>i.statusText)||o}throw new Error(o)}}async updateRole(e,r){let n=await fetch(`${this.baseUrl}/identity/roles/${e}`,{method:"PATCH",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let s=await n.json();throw new Error(s.error||`Failed to update role: ${n.statusText}`)}}async deleteRole(e){let r=await fetch(`${this.baseUrl}/identity/roles/${e}`,{method:"DELETE",headers:this.getHeaders()});if(!r.ok){let n=await r.json();throw new Error(n.error||`Failed to delete role: ${r.statusText}`)}}async addServiceAccount(e,r,n){let s=await fetch(`${this.baseUrl}/identity/service-accounts`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:e,description:r,roles:n})});if(!s.ok){let o=`Failed to create service account: ${s.statusText}`;try{o=(await s.json()).error||o}catch{o=await s.text().catch(()=>s.statusText)||o}throw new Error(o)}let i=await s.json();return{id:i.id,apiKey:i.apiKey}}async deleteIdentity(e){let r=await fetch(`${this.baseUrl}/identity/service-accounts/${e}`,{method:"DELETE",headers:this.getHeaders()});if(!r.ok){let n=await r.json();throw new Error(n.error||`Failed to delete service account: ${r.statusText}`)}}async getUserFromToken(e){try{let r=await fetch(`${this.baseUrl}/identity/whoami`,{method:"GET",headers:{Authorization:`Bearer ${e}`}});return r.ok?await r.json():null}catch{return null}}getHeaders(){let e={"Content-Type":"application/json"};return this.authToken&&(e.Authorization=`Bearer ${this.authToken}`),e}};function Te(t){return t?new q(t):null}var B=class{baseUrl;constructor(e){this.baseUrl=e.replace(/\/$/,"")}async listResourcesByType(e,r,n){let s=`${this.baseUrl}/contexts/${encodeURIComponent(e)}`;try{let i={"Content-Type":"application/json"};n&&(i.Authorization=`Bearer ${n}`);let o=await fetch(s,{method:"GET",headers:i});if(!o.ok)return[];let c=(await o.json()).context?.resources||{};switch(r){case"function":return c.functions||[];case"database":return c.databases||[];case"storage":return c.storage||[];case"site":return c.sites||[];default:return[]}}catch{return[]}}};function Ie(t){return t?new B(t):null}var oe=class t{static MAX_EVENT_CHAIN_DEPTH=10;functionsDir;functions=new Map;eventHandlers=new Map;eventChainDepth=0;debug;bindingService;constructor(e){this.functionsDir=e.functionsDir||M(process.cwd(),"functions-data"),this.debug=e.debug||!1,this.bindingService=new L}async start(){await this.ensureFunctionsDirExists(),await this.loadExistingFunctions(),this.subscribeEventTriggeredFunctions()}getFunction(e){return this.functions.get(e)}getFunctions(){return Array.from(this.functions.values()).map(e=>({name:e.name,endpoint:e.endpoint,id:e.id,filePath:e.filePath,methods:e.methods,...e.bindings?{bindings:e.bindings}:{},...e.triggers&&e.triggers.length>0?{triggers:e.triggers}:{},...e.passAllHeaders!==void 0?{passAllHeaders:e.passAllHeaders}:{},...e.allowUnauthenticated!==void 0?{allowUnauthenticated:e.allowUnauthenticated}:{},createdAt:e.createdAt,updatedAt:e.updatedAt}))}async ensureFunctionsDirExists(){V(this.functionsDir)||await rt(this.functionsDir,{recursive:!0})}async loadExistingFunctions(){try{let e=M(this.functionsDir,"functions.json");if(V(e)){let r=await je(e,"utf8"),n=JSON.parse(r);for(let s of n)V(s.filePath)&&this.functions.set(s.id,s)}}catch{}}async saveFunctionsMetadata(){try{let e=M(this.functionsDir,"functions.json"),r=Array.from(this.functions.values());await ie(e,JSON.stringify(r,null,2),"utf8")}catch{}}async deployFunction(e,r,n,s,i,o,a,c){if(!e||typeof e!="string")throw new v("Function name is required and must be a string");if(!r||typeof r!="string")throw new v("Function code is required and must be a string");if(n!==void 0){if(!Array.isArray(n))throw new v("Methods must be an array");let p=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];for(let g of n)if(!p.includes(g.toUpperCase()))throw new F(`Invalid HTTP method: ${g}. Must be one of: ${p.join(", ")}`)}if(s&&s.length>0&&this.bindingService.validateBindings(s),i&&i.length>0){for(let p of i)if(p.type==="event"&&!p.eventName)throw new v("Event trigger must specify an eventName")}let f=re(c),l=M(this.functionsDir,`${f}.mjs`),u=this.wrapFunctionCode(r);await ie(l,u,"utf8");let d=Date.now(),h={id:f,name:e,filePath:l,endpoint:`/functions/run/${f}`,...n&&n.length>0?{methods:n.map(p=>p.toUpperCase())}:{},...s?{bindings:s}:{},...i&&i.length>0?{triggers:i}:{},...o!==void 0?{passAllHeaders:o}:{},...a!==void 0?{allowUnauthenticated:a}:{},createdAt:d,updatedAt:d};return this.functions.set(f,h),await this.saveFunctionsMetadata(),this.subscribeToEvents(h),h}async updateFunction(e,r){let n=this.functions.get(e);if(!n)throw new N(`Function with ID ${e} not found`);let{code:s,methods:i,bindings:o,triggers:a,passAllHeaders:c,allowUnauthenticated:f}=r;if(s===void 0&&i===void 0&&o===void 0&&a===void 0&&c===void 0&&f===void 0)throw new v("At least one parameter (code, methods, bindings, triggers, passAllHeaders, or allowUnauthenticated) must be provided");if(s!==void 0&&(typeof s!="string"||!s))throw new v("Function code must be a non-empty string");if(i!==void 0){if(!Array.isArray(i))throw new v("Methods must be an array");let l=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];for(let u of i)if(!l.includes(u.toUpperCase()))throw new F(`Invalid HTTP method: ${u}. Must be one of: ${l.join(", ")}`)}if(s!==void 0){let l=this.wrapFunctionCode(s);await ie(n.filePath,l,"utf8")}if(i!==void 0&&(i.length>0?n.methods=i.map(l=>l.toUpperCase()):delete n.methods),o!==void 0&&(o.length>0&&this.bindingService.validateBindings(o),n.bindings=o.length>0?o:void 0),c!==void 0&&(c?n.passAllHeaders=!0:delete n.passAllHeaders),a!==void 0){for(let l of a)if(l.type==="event"&&!l.eventName)throw new v("Event trigger must specify an eventName");this.unsubscribeFromEvents(e),n.triggers=a.length>0?a:void 0,this.subscribeToEvents(n)}return f!==void 0&&(n.allowUnauthenticated=f),n.updatedAt=Date.now(),this.functions.set(e,n),await this.saveFunctionsMetadata(),n}async deleteFunction(e){let r=this.functions.get(e);if(!r)return!1;try{return this.unsubscribeFromEvents(e),V(r.filePath)&&await nt(r.filePath),this.functions.delete(e),await this.saveFunctionsMetadata(),!0}catch(n){throw console.error(`Error deleting function ${e}:`,n.message),n}}wrapFunctionCode(e){let r=e;if(/export\s+default\s+\w+/.test(e))return`// FunctionsService generated module
11
+ `),a="",c="",f,l;for(let d of o){let h=d.toLowerCase();if(h.startsWith("content-disposition:")){a=d.substring(20).trim();let p=a.match(/name="([^"]+)"/);p&&(c=p[1]);let g=a.match(/filename="([^"]+)"/);g&&(f=g[1])}else h.startsWith("content-type:")&&(l=d.substring(13).trim())}if(!c)return null;let u=s;return u.length>=2&&u[u.length-2]===13&&u[u.length-1]===10&&(u=u.subarray(0,u.length-2)),{disposition:a,name:c,filename:f,contentType:l,data:u}}import{readFileSync as R}from"fs";import J from"http";import He from"http2";import Ne from"https";var W=class{config;rateLimiter;router;shutdownHandlers=[];constructor(t){let e=new _(ue(t||{})).get();e.debug&&console.log("Using configuration:",e),this.config=e,this.router=new ce;let r=e.rateLimit.requestsPerMinute||H().rateLimit.requestsPerMinute;this.rateLimiter=new ae(r,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:r}=this.config;return this.setupGracefulShutdown(t),t.listen(e,r,()=>{let n=t.address(),s=this.config.useHttps||this.config.useHttp2?"https":"http";console.log(`MikroServe running at ${s}://${n.address!=="::"?n.address:"localhost"}:${n.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:R(this.config.sslKey),cert:R(this.config.sslCert),...this.config.sslCa?{ca:R(this.config.sslCa)}:{}};return He.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:R(this.config.sslKey),cert:R(this.config.sslCert),...this.config.sslCa?{ca:R(this.config.sslCa)}:{}};return Ne.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 J.createServer(t)}async rateLimitMiddleware(t,e){let r=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(r).toString()),t.res.setHeader("X-RateLimit-Reset",this.rateLimiter.getResetTime(r).toString()),this.rateLimiter.isAllowed(r)?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 r=Date.now(),n=t.method||"UNKNOWN",s=t.url||"/unknown",i=this.config.debug;try{if(this.setCorsHeaders(e,t),this.setSecurityHeaders(e,this.config.useHttps),i&&console.log(`${n} ${s}`),t.method==="OPTIONS"){if(e instanceof J.ServerResponse)e.statusCode=204,e.end();else{let a=e;a.writeHead(204),a.end()}return}try{t.body=await this.parseBody(t)}catch(a){return i&&console.error("Body parsing error:",a.message),this.respond(e,{statusCode:400,body:{error:"Bad Request",message:a.message}})}let o=await this.router.handle(t,e);return o?o._handled?void 0:this.respond(e,o):this.respond(e,{statusCode:404,body:{error:"Not Found",message:"The requested endpoint does not exist"}})}catch(o){return console.error("Server error:",o),this.respond(e,{statusCode:500,body:{error:"Internal Server Error",message:i?o.message:"An unexpected error occurred"}})}finally{i&&this.logDuration(r,n,s)}}logDuration(t,e,r){let n=Date.now()-t;console.log(`${e} ${r} completed in ${n}ms`)}async parseBody(t){return new Promise((e,r)=>{let n=[],s=0,i=this.config.maxBodySize,o=!1,a=null,c=this.config.debug,f=t.headers["content-type"]||"";c&&console.log("Content-Type:",f),this.config.requestTimeout>0&&(a=setTimeout(()=>{o||(o=!0,c&&console.log("Request timeout exceeded"),r(new Error("Request timeout")))},this.config.requestTimeout));let l=()=>{a&&(clearTimeout(a),a=null)};t.on("data",u=>{if(!o){if(s+=u.length,c&&console.log(`Received chunk: ${u.length} bytes, total size: ${s}`),s>i){o=!0,l(),c&&console.log(`Body size exceeded limit: ${s} > ${i}`),r(new Error("Request body too large"));return}n.push(u)}}),t.on("end",()=>{if(!o){o=!0,l(),c&&console.log(`Request body complete: ${s} bytes`);try{if(n.length>0){let u=Buffer.concat(n);if(f.includes("application/json"))try{let d=u.toString("utf8");e(JSON.parse(d))}catch(d){r(new Error(`Invalid JSON in request body: ${d.message}`))}else if(f.includes("application/x-www-form-urlencoded")){let d=u.toString("utf8"),h={};new URLSearchParams(d).forEach((p,g)=>{h[g]=p}),e(h)}else if(f.includes("multipart/form-data"))try{let d=le(u,f);e(d)}catch(d){r(new Error(`Invalid multipart form data: ${d.message}`))}else this.isBinaryContentType(f)?e(u):e(u.toString("utf8"))}else e({})}catch(u){r(new Error(`Invalid request body: ${u}`))}}}),t.on("error",u=>{o||(o=!0,l(),r(new Error(`Error reading request body: ${u.message}`)))}),t.on("close",()=>{l()})})}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(r=>t.includes(r))}setCorsHeaders(t,e){let r=e.headers.origin,{allowedDomains:n=["*"]}=this.config;!r||n.length===0||n.includes("*")?t.setHeader("Access-Control-Allow-Origin","*"):n.includes(r)&&(t.setHeader("Access-Control-Allow-Origin",r),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 r={"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)&&(r["Strict-Transport-Security"]="max-age=31536000; includeSubDomains"),t instanceof J.ServerResponse)Object.entries(r).forEach(([n,s])=>{t.setHeader(n,s)});else{let n=t;Object.entries(r).forEach(([s,i])=>{n.setHeader(s,i)})}}respond(t,e){let r={...e.headers||{}};(s=>typeof s.writeHead=="function"&&typeof s.end=="function")(t)?(t.writeHead(e.statusCode,r),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,r),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=o=>{console.log("Shutting down MikroServe server..."),o&&console.error("Error:",o),this.cleanupShutdownHandlers(),t.close(()=>{console.log("Server closed successfully"),process.env.NODE_ENV!=="test"&&process.env.VITEST!=="true"&&setImmediate(()=>process.exit(o?1:0))})},r=()=>e(),n=()=>e(),s=o=>e(o),i=o=>e(o);this.shutdownHandlers=[r,n,s,i],process.on("SIGINT",r),process.on("SIGTERM",n),process.on("uncaughtException",s),process.on("unhandledRejection",i)}cleanupShutdownHandlers(){if(this.shutdownHandlers.length>0){let[t,e,r,n]=this.shutdownHandlers;process.removeListener("SIGINT",t),process.removeListener("SIGTERM",e),process.removeListener("uncaughtException",r),process.removeListener("unhandledRejection",n),this.shutdownHandlers=[]}}};var v=class extends Error{constructor(e){super(),this.name="ValidationError",this.message=e||"Invalid input",this.cause={statusCode:400}}};var N=class extends Error{constructor(e){super(),this.name="NotFoundError",this.message=e||"Resource not found",this.cause={statusCode:404}}};var F=class extends Error{constructor(e){super(),this.name="InvalidMethodError",this.message=e||"Invalid HTTP method",this.cause={statusCode:400}}};var D=class extends Error{constructor(e){super(),this.name="ServiceRequestError",this.message=e||"Service request failed",this.cause={statusCode:502}}};var L=class{generatePermissionsFromBindings(e){let r=[];for(let n of e){let s=n.service;for(let i of n.permissions){if(!i.resource){r.push(`${s}.*`);continue}let o=i.resource,a=i.actions||["*"];if(i.targets&&i.targets.length>0)for(let c of a)for(let f of i.targets)r.push(`${s}.${o}.${c}:${f}`);else for(let c of a)r.push(`${s}.${o}.${c}`)}}return[...new Set(r)]}validateBindings(e){let r=["databases","storage","observability","sites","functions","events","schemas","builder"];for(let n of e){if(!r.includes(n.service))throw new v(`Invalid service: ${n.service}. Must be one of: ${r.join(", ")}`);if(!n.permissions||n.permissions.length===0)throw new v("Bindings must have at least one permission");for(let s of n.permissions)if(s.targets&&s.targets.length>0){if(!s.resource)throw new v("Action-level bindings (with targets) must specify resource");if(!s.actions||s.actions.length===0)throw new v("Action-level bindings (with targets) must specify actions")}}}};var X=class{constructor(e,r,n){this.baseUrl=e;this.authToken=r;this.bindings=n}async request(e,r,n,s){let i=`${this.baseUrl}${r}`;if(s){let u=new URLSearchParams(s);i+=`?${u.toString()}`}let o={"Content-Type":"application/json"};this.authToken&&(o.Authorization=`Bearer ${this.authToken}`),this.bindings&&this.bindings.length>0&&(o["X-Function-Bindings"]=JSON.stringify(this.bindings));let a={method:e,headers:o};n&&(a.body=JSON.stringify(n));let c=await fetch(i,a),f=c.headers.get("content-type"),l;if(f?.includes("application/json")){let u=await c.text();u?l=JSON.parse(u):l=null}else l=await c.text();if(!c.ok)throw new D(`Service request failed (${c.status}): ${typeof l=="string"?l:JSON.stringify(l)}`);return l}},Y=class extends X{async get(e,r){return this.request("POST","/get",{tableName:e,key:r})}async write(e,r,n,s,i){return this.request("POST","/write",{tableName:e,key:r,value:n,expiration:s,dictionaryName:i})}async delete(e,r){return this.request("DELETE","/delete",void 0,{tableName:e,key:r})}async listTables(){return this.request("GET","/tables")}async getTableSize(e){return this.request("GET","/table",void 0,{tableName:e})}async getTableInfo(e){return this.request("GET",`/tables/${e}`)}async createTable(e){return this.request("POST",`/tables/${e}`)}async deleteTable(e){return this.request("DELETE",`/tables/${e}`)}},Z=class{constructor(e){this.eventBus=e}async emit(e,r){await this.eventBus.emit(e,r)}},K=class{constructor(e){this.schemaRegistry=e}validate(e,r,n){return this.schemaRegistry.validate(e,r,n)}},$=class{constructor(e,r,n,s){this.serviceBaseUrls=e;this.authToken=r;this.eventBus=n;this.schemaRegistry=s}createBindings(e){let r={};for(let n of e)switch(n.service){case"databases":{let s=this.serviceBaseUrls[n.service];if(!s)continue;r.databases=new Y(s,this.authToken,e);break}case"events":this.eventBus&&(r.events=new Z(this.eventBus));break;case"schemas":this.schemaRegistry&&(r.schemas=new K(this.schemaRegistry));break}return r}};var O=class{isSilent;propertyPath="";constructor(t=!1){this.isSilent=t}test(t,e){if(!e)throw new Error("Missing input!");this.updatePropertyPath();let{results:r,errors:n}=this.validate(t.properties,e),s=this.compileErrors(r,n),i=this.isSuccessful(r,s);return{errors:s,success:i}}compileErrors(t,e){let r=t.filter(n=>n.success===!1);return[...e,...r].flatMap(n=>n)}isSuccessful(t,e){return t.every(r=>r.success===!0)&&e.length===0}validate(t,e,r=[],n=[]){let s=t?.additionalProperties??!0,i=t?.required||[];n=this.checkForRequiredKeysErrors(i,e,n),n=this.checkForDisallowedProperties(Object.keys(e),Object.keys(t),n,s);for(let o in t){let a=i.includes(o)&&o!=="required",c=t[o],f=e[o],l=c.additionalProperties??!0;a&&(n=this.checkForRequiredKeysErrors(c.required||[],f,n)),this.isDefined(f)&&(this.handleValidation(o,f,c,r),n=this.checkForDisallowedProperties(Object.keys(f),Object.keys(c),n,l),this.handleNestedObject(f,c,r,n))}return{results:r,errors:n}}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,r){if(!this.areRequiredKeysPresent(t,e)){let n=e?Object.keys(e):[],s=this.findNonOverlappingElements(t,n),i=s.length>0?`Missing the required key: '${s.join(", ")}'!`:`Missing values for required keys: '${n.filter(o=>!e[o]).join(", ")}'!`;r.push({key:"",value:e,success:!1,error:i})}return r}checkForDisallowedProperties(t,e,r,n){if(!n){let s=this.findNonOverlappingElements(t,e);s.length>0&&r.push({key:`${e}`,value:t,success:!1,error:`Has additional (disallowed) properties: '${s.join(", ")}'!`})}return r}handleValidation(t,e,r,n){this.updatePropertyPath(t);let s=this.validateProperty(this.propertyPath,r,e);n.push(...s);let i=(a,c)=>{a.forEach(f=>{let l=this.validateProperty(this.propertyPath,c.items,f);n.push(...l)}),this.updatePropertyPath()},o=a=>{let c=Object.keys(a),f=this.propertyPath;c.forEach(l=>{if(this.updatePropertyPath(l,f),this.isArray(a[l])&&r[l]?.items!=null)i(a[l],r[l]);else{let u=this.validateProperty(this.propertyPath,r[l],a[l]);n.push(...u)}})};this.isArray(e)&&r.items!=null?i(e,r):this.isObject(e)?o(e):this.updatePropertyPath()}handleNestedObject(t,e,r,n){if(this.isObject(t)){let s=this.getNestedObjects(t);for(let i of s){let o=e[i],a=t[i];o&&typeof a=="object"&&this.validate(o,a,r,n)}}}getNestedObjects(t){return Object.keys(t).filter(e=>{if(this.isObject(t))return e})}findNonOverlappingElements(t,e){return t.filter(r=>!e.includes(r))}areRequiredKeysPresent(t,e=[]){return t.every(r=>Object.keys(e).includes(r)?this.isDefined(e[r]):!1)}validateProperty(t,e,r){return this.validateInput(e,r).map(s=>{let{success:i,error:o}=s;return{key:t,value:r,success:i,error:o??""}})}validateInput(t,e){if(t){let r=[{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"}],n=[];for(let s of r)s.condition()&&!s.validator()&&n.push({success:!1,error:s.error});return n}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(r=>{switch(r){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 r in t){let n=t[r];e.properties.required.push(r),Array.isArray(n)?e.properties[r]=this.generateArraySchema(n):typeof n=="object"&&n!==null?e.properties[r]=this.generateNestedObjectSchema(n):e.properties[r]=this.generatePropertySchema(n)}return e}generateArraySchema(t){let e={type:"array"},r=t.filter(n=>n);if(r.length>0){let n=r[0];r.every(i=>typeof i==typeof n)?typeof n=="object"&&!Array.isArray(n)?e.items=this.generateNestedObjectSchema(n):e.items=this.generatePropertySchema(n):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 r in t){let n=t[r];e.required.push(r),typeof n=="object"&&!Array.isArray(n)&&n!==null?e[r]=this.generateNestedObjectSchema(n):e[r]=this.generatePropertySchema(n)}return e}generatePropertySchema(t){let e=typeof t,r={type:e};return e==="string"&&(r.minLength=1),r}};async function j(t){return t.body||{}}function S(t,e="An error occurred"){let r=t?.message||t||e,n=t?.cause?.statusCode||t?.statusCode||400;return{message:r,status:n}}function de(t,e,r={}){let n=Array.isArray(e)?e:[e];if(!t||!t.roles||!Array.isArray(t.roles)){let o=new Error("Unauthorized: User or roles missing");throw o.cause={statusCode:403},o}let s=t.roles.flatMap(o=>o?.policies?.flatMap(a=>(a?.permissions||[]).flatMap(f=>typeof f=="string"?f:f&&typeof f=="object"&&f.actions?f.actions:[]))||[]);if(!n.every(o=>s.some(a=>De(a,o)))){let o=new Error("Unauthorized");throw o.cause={statusCode:403},o}return!0}function De(t,e){if(t==="*"||t===e)return!0;if(!t.includes("*"))return!1;let r=t.split("*").map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${r}$`).test(e)}function fe(t,e,r,n,s){let i=t.find(c=>c.service===e);if(!i){let c=new Error(`Function bindings do not include access to service: ${e}`);throw c.cause={statusCode:403},c}if(!i.permissions||i.permissions.length===0)return;for(let c of i.permissions)if(!(c.resource&&c.resource!==r)){if(!c.resource||!c.actions||c.actions.length===0)return;if(c.actions.includes(n)&&!(c.targets&&c.targets.length>0&&(!s||!c.targets.includes(s)&&!c.targets.includes("*"))))return}let o=s?`:${s}`:"",a=new Error(`Function bindings do not allow: ${e}.${r}.${n}${o}`);throw a.cause={statusCode:403},a}import{readFileSync as Le,existsSync as Ue}from"node:fs";function E(){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:"http://127.0.0.1:3000"},context:{apiUrl:"http://127.0.0.1:3000"},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||!Ue(t))return e;try{let r=Le(t,"utf-8");return JSON.parse(r)}catch(r){return console.error("[loadRuntimeConfig] Failed to load runtime config:",r),e}}async function x(t,e,r,n,s,i,o){if(!e)return null;let a=t.headers["x-molnos-service-token"];if(a){let l=E();if(l.internalServiceSecret&&a===l.internalServiceSecret)return null}let c=t.state.user;if(!c){let l=t.headers.authorization;if(!l){let d=new Error("Unauthorized: No authentication provided");throw d.cause={statusCode:401},d}let u=l.replace(/^Bearer\s+/i,"");if(c=await e.getUserFromToken(u),!c){let d=new Error("Unauthorized: Invalid token");throw d.cause={statusCode:401},d}}de(c,r,{});let f=t.headers["x-function-bindings"];if(f)try{let l=Array.isArray(f)?f[0]:f,u=JSON.parse(l);fe(u,n,s,i,o)}catch(l){if(l.cause?.statusCode===403)throw l;let u=new Error("Invalid function bindings header");throw u.cause={statusCode:400},u}return c}var w={applications:{application:{create:"applications.application.create",read:"applications.application.read",list:"applications.application.list",update:"applications.application.update",delete:"applications.application.delete"}},builder:{artifact:{read:"builder.artifact.read",list:"builder.artifact.list",update:"builder.artifact.update"},revision:{create:"builder.revision.create",read:"builder.revision.read",list:"builder.revision.list",activate:"builder.revision.activate"},run:{plan:"builder.run.plan",import:"builder.run.import",generate:"builder.run.generate",evolve:"builder.run.evolve",apply:"builder.run.apply",evaluate:"builder.run.evaluate",read:"builder.run.read",list:"builder.run.list"}},contexts:{context:{create:"contexts.context.create",get:"contexts.context.get",update:"contexts.context.update",delete:"contexts.context.delete",deleteResources:"contexts.context.delete-resources"}},databases:{table:{create:"databases.table.create",get:"databases.table.get",update:"databases.table.update",delete:"databases.table.delete"}},functions:{function:{create:"functions.function.create",get:"functions.function.get",update:"functions.function.update",delete:"functions.function.delete",execute:"functions.function.execute"}},iac:{config:{create:"iac.config.create",get:"iac.config.get"}},identity:{identities:{get:"identity.identities.get"},user:{create:"identity.user.create",get:"identity.user.get",update:"identity.user.update",delete:"identity.user.delete"},role:{create:"identity.role.create",get:"identity.role.get",update:"identity.role.update",delete:"identity.role.delete"},serviceAccount:{create:"identity.service-account.create",get:"identity.service-account.get",update:"identity.service-account.update",delete:"identity.service-account.delete"}},management:{service:{create:"management.service.create",get:"management.service.get",update:"management.service.update",delete:"management.service.delete",start:"management.service.start",stop:"management.service.stop"},services:{get:"management.services.get"}},observability:{event:{create:"observability.event.create",read:"observability.event.read",delete:"observability.event.delete"},stats:{read:"observability.stats.read"},buffer:{write:"observability.buffer.write"},metrics:{read:"observability.metrics.read"}},schemas:{schema:{create:"schemas.schema.create",read:"schemas.schema.read",list:"schemas.schema.list",update:"schemas.schema.update",delete:"schemas.schema.delete"}},sites:{project:{create:"sites.project.create",list:"sites.project.list",delete:"sites.project.delete",download:"sites.project.download"}},storage:{bucket:{create:"storage.bucket.create",read:"storage.bucket.read",update:"storage.bucket.update",delete:"storage.bucket.delete",list:"storage.bucket.list"},object:{write:"storage.object.write",read:"storage.object.read",delete:"storage.object.delete",list:"storage.object.list"}}};function pe(t,e){if(typeof t=="string"){e.push(t);return}if(!(!t||typeof t!="object"))for(let r of Object.values(t))pe(r,e)}var he=[];pe(w,he);var qe=[...new Set(he)],pr=Object.freeze(qe);var ge={properties:{id:{type:"string",minLength:1,maxLength:40,pattern:"^[a-zA-Z0-9_-]{1,40}$"},name:{type:"string",minLength:1},code:{type:"string",minLength:1},methods:{type:"array",items:{type:"string"}},bindings:{type:"array"},trigger:{type:"object"},triggers:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["http","event"]},eventName:{type:"string"}},required:["type"]}},passAllHeaders:{type:"boolean"},allowUnauthenticated:{type:"boolean"},context:{type:"string",minLength:1}},required:["name","code"],additionalProperties:!1};var Ve=new O(!0);async function me(t,e,r){try{let n=await j(t),s=Ve.test(ge,n);if(!s.success)return t.json({error:"Invalid input",details:s.errors},400);await x(t,r,w.functions.function.create,"functions","function","create");let{id:i,name:o,code:a,methods:c,bindings:f,trigger:l,triggers:u,passAllHeaders:d,allowUnauthenticated:h}=n,p=u||(l?[l]:void 0),g=await e.deployFunction(o,a,c,f,p,d,h,i);return t.json({success:!0,function:g},201)}catch(n){let{message:s,status:i}=S(n,"Error deploying function");return t.json({error:s},i)}}async function ye(t,e,r){try{let n=t.params.functionId;if(!n)return t.json({error:"functionId is required"},400);let s=e.getFunction(n);return s?s.triggers&&s.triggers.length>0&&!s.triggers.some(i=>i.type==="http")?t.json({error:"Not Found",message:"Function not found"},404):(s.allowUnauthenticated!==!0&&await x(t,r,w.functions.function.execute,"functions","function","execute",n),await e.executeFunction(n,t)):t.json({error:"Not Found",message:"Function not found"},404)}catch(n){let{message:s,status:i}=S(n,"Error executing function");return t.json({error:s},i)}}var ve={properties:{code:{type:"string",minLength:1},methods:{type:"array",items:{type:"string"}},bindings:{type:"array"},trigger:{type:"object"},triggers:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["http","event"]},eventName:{type:"string"}},required:["type"]}},passAllHeaders:{type:"boolean"},allowUnauthenticated:{type:"boolean"}},additionalProperties:!1};var _e=new O(!0);async function be(t,e,r){try{let n=t.params.functionId,s=await j(t);if(!n)return t.json({error:"functionId is required"},400);let i=_e.test(ve,s);if(!i.success)return t.json({error:"Invalid input",details:i.errors},400);await x(t,r,w.functions.function.update,"functions","function","update",n);let{code:o,methods:a,bindings:c,trigger:f,triggers:l,passAllHeaders:u,allowUnauthenticated:d}=s,h=l||(f?[f]:void 0),p=await e.updateFunction(n,{code:o,methods:a,bindings:c,triggers:h,passAllHeaders:u,allowUnauthenticated:d});return p?t.json({success:!0,function:p},200):t.json({error:"Function not found"},404)}catch(n){let{message:s,status:i}=S(n,"Error updating function");return t.json({error:s},i)}}async function we(t,e,r){try{let n=t.params.functionId;return n?(await x(t,r,w.functions.function.delete,"functions","function","delete",n),await e.deleteFunction(n)?t.json({success:!0,message:"Function deleted"},200):t.json({error:"Function not found"},404)):t.json({error:"functionId is required"},400)}catch(n){let{message:s,status:i}=S(n,"Error deleting function");return t.json({error:s},i)}}async function Se(t,e,r){try{let n=t.params.functionId;if(!n)return t.json({error:"functionId is required"},400);await x(t,r,w.functions.function.get,"functions","function","read",n);let s=e.getFunction(n);return s?t.json({success:!0,function:s},200):t.json({error:"Function not found"},404)}catch(n){let{message:s,status:i}=S(n,"Error getting function");return t.json({error:s},i)}}async function xe(t,e,r,n){try{await x(t,r,w.functions.function.get,"functions","function","read");let s=e.getFunctions(),i=t.query.context;if(i&&n){let o=t.headers.authorization?.replace(/^Bearer\s+/i,""),a=await n.listResourcesByType(i,"function",o);s=s.filter(c=>a.includes(c.id))}return t.json({success:!0,count:s.length,functions:s},200)}catch(s){let{message:i,status:o}=S(s,"Error listing functions");return t.json({error:i},o)}}import{EventEmitter as Ge}from"node:events";var Q=class t{static instance;constructor(){}static getInstance(){return t.instance||(t.instance=new Ge,t.instance.setMaxListeners(100)),t.instance}};function ee(){return Q.getInstance()}function Ee(t){let e=ee();try{e.emit("function.log",t)}catch(r){console.error("Failed to emit function log event:",r)}}import{getRandomValues as Je}from"node:crypto";var te=class{options;defaultLength=16;defaultOnlyLowerCase=!1;defaultStyle="extended";defaultUrlSafe=!0;constructor(t){if(this.options={},t)for(let[e,r]of Object.entries(t))this.options[e]=this.generateConfig(r)}add(t){if(!t?.name)throw new Error("Missing name for the ID configuration");let e=this.generateConfig(t);this.options[t.name]=e}remove(t){if(!t?.name)throw new Error("Missing name for the ID configuration");delete this.options[t.name]}create(t,e,r,n){let s=this.generateConfig({length:t,style:e,onlyLowerCase:r,urlSafe:n});return this.generateId(s)}custom(t){if(this.options[t])return this.generateId(this.options[t]);throw new Error(`No configuration found with name: ${t}`)}generateConfig(t){return{name:t?.name||"",length:t?.length||this.defaultLength,onlyLowerCase:t?.onlyLowerCase??this.defaultOnlyLowerCase,style:t?.style||this.defaultStyle,urlSafe:t?.urlSafe??this.defaultUrlSafe}}getCharacterSet(t,e,r){if(t==="hex")return e?"0123456789abcdef":"0123456789ABCDEFabcdef";if(t==="alphanumeric")return e?"abcdefghijklmnopqrstuvwxyz0123456789":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";if(t==="extended")return r?e?"abcdefghijklmnopqrstuvwxyz0123456789-._~":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~":e?"abcdefghijklmnopqrstuvwxyz0123456789-._~!$()*+,;=:":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$()*+,;=:";throw new Error(`Unknown ID style "${t} provided. Must be one of "extended" (default), "alphanumeric", or "hex".`)}generateId(t){let{length:e,onlyLowerCase:r,style:n,urlSafe:s}=t;if(e<0||e===0)throw new Error("ID length cannot be negative");let i=this.getCharacterSet(n,r,s),o=(2<<Math.log(i.length-1)/Math.LN2)-1,a=Math.ceil(1.6*o*e/i.length),c="";for(;c.length<e;){let f=new Uint8Array(a);Je(f);for(let l=0;l<a;l++){let u=f[l]&o;if(u<i.length&&(c+=i[u],c.length===e))break}}return c}};var We=8,Xe=40,Ye=/^[a-zA-Z0-9_-]{1,40}$/;function Ze(){return new te().create(We,"alphanumeric",!1,!0)}function Ke(t){return Ye.test(t)}function Qe(t){if(!Ke(t))throw new Error(`Invalid ID format: "${t}". IDs must be 1-${Xe} characters using only alphanumeric characters, underscores, and hyphens.`)}function re(t){return t?(Qe(t),t):Ze()}import{EventEmitter as et}from"events";var ne=class{emitter;targets={};options;constructor(t){this.emitter=new et,t?.maxListeners===0?this.emitter.setMaxListeners(0):this.emitter.setMaxListeners(t?.maxListeners||10),this.options={errorHandler:t?.errorHandler||(e=>console.error(e)),isSilent:t?.isSilent||!1}}addTarget(t){return(Array.isArray(t)?t:[t]).map(n=>this.targets[n.name]?(this.options.isSilent||console.error(`Target with name '${n.name}' already exists.`),!1):(this.targets[n.name]={name:n.name,url:n.url,headers:n.headers||{},events:n.events||[]},!0)).every(n=>n===!0)}updateTarget(t,e){if(!this.targets[t])return console.error(`Target with name '${t}' does not exist.`),!1;let r=this.targets[t];return e.url!==void 0&&(r.url=e.url),e.headers&&(r.headers={...r.headers,...e.headers}),e.events&&(r.events=e.events),!0}removeTarget(t){return this.targets[t]?(delete this.targets[t],!0):(console.error(`Target with name '${t}' does not exist.`),!1)}addEventToTarget(t,e){if(!this.targets[t])return console.error(`Target with name '${t}' does not exist.`),!1;let r=Array.isArray(e)?e:[e],n=this.targets[t];return r.forEach(s=>{n.events.includes(s)||n.events.push(s)}),!0}on(t,e){return this.emitter.on(t,e),this}off(t,e){return this.emitter.off(t,e),this}once(t,e){return this.emitter.once(t,e),this}async emit(t,e){let r={success:!0,errors:[]},n=(o,a,c)=>({target:o,event:a,error:c}),s=Object.values(this.targets).filter(o=>o.events.includes(t)||o.events.includes("*"));s.filter(o=>!o.url).forEach(o=>{try{this.emitter.emit(t,e)}catch(a){let c=a instanceof Error?a:new Error(String(a));r.errors.push({target:o.name,event:t,error:c}),this.options.errorHandler(c,t,e),r.success=!1}});let i=s.filter(o=>o.url);if(i.length>0){let o=i.map(async a=>{try{let c=await fetch(a.url,{method:"POST",headers:{"Content-Type":"application/json",...a.headers},body:JSON.stringify({eventName:t,data:e})});if(!c.ok){let f=`HTTP error! Status: ${c.status}: ${c.statusText}`,l=new Error(f);r.errors.push(n(a.name,t,l)),this.options.errorHandler(l,t,e),r.success=!1}}catch(c){let f=c instanceof Error?c:new Error(String(c));r.errors.push(n(a.name,t,f)),this.options.errorHandler(f,t,e),r.success=!1}});await Promise.allSettled(o)}return r}async handleIncomingEvent(t){try{let{eventName:e,data:r}=typeof t=="string"?JSON.parse(t):t;process.nextTick(()=>{try{this.emitter.emit(e,r)}catch(n){this.options.errorHandler(n instanceof Error?n:new Error(String(n)),e,r)}})}catch(e){throw this.options.errorHandler(e instanceof Error?e:new Error(String(e)),"parse_event"),e}}createMiddleware(){return async(t,e,r)=>{if(t.method!=="POST"){r&&r();return}if(t.body)try{await this.handleIncomingEvent(t.body),e.statusCode=202,e.end()}catch(n){e.statusCode=400,e.end(JSON.stringify({error:"Invalid event format"})),r&&r(n)}else{let n="";t.on("data",s=>n+=s.toString()),t.on("end",async()=>{try{await this.handleIncomingEvent(n),e.statusCode=202,e.end()}catch(s){e.statusCode=400,e.end(JSON.stringify({error:"Invalid event format"})),r&&r(s)}})}}}};var U=null;function k(){return U||(U=new ne,U.addTarget({name:"molnos-internal",events:["*"]})),U}var tt=null;function se(){return tt||void 0}function Ce(t,e){let r={enabled:!1,requestsPerMinute:0};if(!e)return r;let n=e.services?.[t];return n||(e.global?e.global:r)}function Pe(t,e){let r=t?.api?.port;if(!r)throw new Error('Missing "port" input when create API service!');let n=E(),s=t?.dataPath||n.molnos.dataPath,i=t?.api?.host||n.server.host,o=t?.identityApiUrl!==void 0?t.identityApiUrl:n.identity.apiUrl,a=t?.contextApiUrl!==void 0?t.contextApiUrl:n.context.apiUrl,c=t?.debug||!1,f;return e&&(f=Ce(e,n.molnos.rateLimit)),{dataPath:s,api:{port:r,host:i},...o?{identityApiUrl:o}:{},...a?{contextApiUrl:a}:{},...f?{rateLimit:f}:{},debug:c}}var q=class{baseUrl;authToken;constructor(e,r){this.baseUrl=e.replace(/\/$/,""),this.authToken=r}async createCustomRole(e,r,n,s){let i=await fetch(`${this.baseUrl}/identity/roles`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({roleId:e,name:r,description:n,permissions:s})});if(!i.ok){let o=`Failed to create role: ${i.statusText}`;try{o=(await i.json()).error||o}catch{o=await i.text().catch(()=>i.statusText)||o}throw new Error(o)}}async updateRole(e,r){let n=await fetch(`${this.baseUrl}/identity/roles/${e}`,{method:"PATCH",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let s=await n.json();throw new Error(s.error||`Failed to update role: ${n.statusText}`)}}async deleteRole(e){let r=await fetch(`${this.baseUrl}/identity/roles/${e}`,{method:"DELETE",headers:this.getHeaders()});if(!r.ok){let n=await r.json();throw new Error(n.error||`Failed to delete role: ${r.statusText}`)}}async addServiceAccount(e,r,n){let s=await fetch(`${this.baseUrl}/identity/service-accounts`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:e,description:r,roles:n})});if(!s.ok){let o=`Failed to create service account: ${s.statusText}`;try{o=(await s.json()).error||o}catch{o=await s.text().catch(()=>s.statusText)||o}throw new Error(o)}let i=await s.json();return{id:i.id,apiKey:i.apiKey}}async deleteIdentity(e){let r=await fetch(`${this.baseUrl}/identity/service-accounts/${e}`,{method:"DELETE",headers:this.getHeaders()});if(!r.ok){let n=await r.json();throw new Error(n.error||`Failed to delete service account: ${r.statusText}`)}}async getUserFromToken(e){try{let r=await fetch(`${this.baseUrl}/identity/whoami`,{method:"GET",headers:{Authorization:`Bearer ${e}`}});return r.ok?await r.json():null}catch{return null}}getHeaders(){let e={"Content-Type":"application/json"};return this.authToken&&(e.Authorization=`Bearer ${this.authToken}`),e}};function Te(t){return t?new q(t):null}var B=class{baseUrl;constructor(e){this.baseUrl=e.replace(/\/$/,"")}async listResourcesByType(e,r,n){let s=`${this.baseUrl}/contexts/${encodeURIComponent(e)}`;try{let i={"Content-Type":"application/json"};n&&(i.Authorization=`Bearer ${n}`);let o=await fetch(s,{method:"GET",headers:i});if(!o.ok)return[];let c=(await o.json()).context?.resources||{};switch(r){case"function":return c.functions||[];case"database":return c.databases||[];case"storage":return c.storage||[];case"site":return c.sites||[];default:return[]}}catch{return[]}}};function Ie(t){return t?new B(t):null}var oe=class t{static MAX_EVENT_CHAIN_DEPTH=10;functionsDir;functions=new Map;eventHandlers=new Map;eventChainDepth=0;debug;bindingService;constructor(e){this.functionsDir=e.functionsDir||M(process.cwd(),"functions-data"),this.debug=e.debug||!1,this.bindingService=new L}async start(){await this.ensureFunctionsDirExists(),await this.loadExistingFunctions(),this.subscribeEventTriggeredFunctions()}getFunction(e){return this.functions.get(e)}getFunctions(){return Array.from(this.functions.values()).map(e=>({name:e.name,endpoint:e.endpoint,id:e.id,filePath:e.filePath,methods:e.methods,...e.bindings?{bindings:e.bindings}:{},...e.triggers&&e.triggers.length>0?{triggers:e.triggers}:{},...e.passAllHeaders!==void 0?{passAllHeaders:e.passAllHeaders}:{},...e.allowUnauthenticated!==void 0?{allowUnauthenticated:e.allowUnauthenticated}:{},createdAt:e.createdAt,updatedAt:e.updatedAt}))}async ensureFunctionsDirExists(){V(this.functionsDir)||await rt(this.functionsDir,{recursive:!0})}async loadExistingFunctions(){try{let e=M(this.functionsDir,"functions.json");if(V(e)){let r=await je(e,"utf8"),n=JSON.parse(r);for(let s of n)V(s.filePath)&&this.functions.set(s.id,s)}}catch{}}async saveFunctionsMetadata(){try{let e=M(this.functionsDir,"functions.json"),r=Array.from(this.functions.values());await ie(e,JSON.stringify(r,null,2),"utf8")}catch{}}async deployFunction(e,r,n,s,i,o,a,c){if(!e||typeof e!="string")throw new v("Function name is required and must be a string");if(!r||typeof r!="string")throw new v("Function code is required and must be a string");if(n!==void 0){if(!Array.isArray(n))throw new v("Methods must be an array");let p=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];for(let g of n)if(!p.includes(g.toUpperCase()))throw new F(`Invalid HTTP method: ${g}. Must be one of: ${p.join(", ")}`)}if(s&&s.length>0&&this.bindingService.validateBindings(s),i&&i.length>0){for(let p of i)if(p.type==="event"&&!p.eventName)throw new v("Event trigger must specify an eventName")}let f=re(c),l=M(this.functionsDir,`${f}.mjs`),u=this.wrapFunctionCode(r);await ie(l,u,"utf8");let d=Date.now(),h={id:f,name:e,filePath:l,endpoint:`/functions/run/${f}`,...n&&n.length>0?{methods:n.map(p=>p.toUpperCase())}:{},...s?{bindings:s}:{},...i&&i.length>0?{triggers:i}:{},...o!==void 0?{passAllHeaders:o}:{},...a!==void 0?{allowUnauthenticated:a}:{},createdAt:d,updatedAt:d};return this.functions.set(f,h),await this.saveFunctionsMetadata(),this.subscribeToEvents(h),h}async updateFunction(e,r){let n=this.functions.get(e);if(!n)throw new N(`Function with ID ${e} not found`);let{code:s,methods:i,bindings:o,triggers:a,passAllHeaders:c,allowUnauthenticated:f}=r;if(s===void 0&&i===void 0&&o===void 0&&a===void 0&&c===void 0&&f===void 0)throw new v("At least one parameter (code, methods, bindings, triggers, passAllHeaders, or allowUnauthenticated) must be provided");if(s!==void 0&&(typeof s!="string"||!s))throw new v("Function code must be a non-empty string");if(i!==void 0){if(!Array.isArray(i))throw new v("Methods must be an array");let l=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];for(let u of i)if(!l.includes(u.toUpperCase()))throw new F(`Invalid HTTP method: ${u}. Must be one of: ${l.join(", ")}`)}if(s!==void 0){let l=this.wrapFunctionCode(s);await ie(n.filePath,l,"utf8")}if(i!==void 0&&(i.length>0?n.methods=i.map(l=>l.toUpperCase()):delete n.methods),o!==void 0&&(o.length>0&&this.bindingService.validateBindings(o),n.bindings=o.length>0?o:void 0),c!==void 0&&(c?n.passAllHeaders=!0:delete n.passAllHeaders),a!==void 0){for(let l of a)if(l.type==="event"&&!l.eventName)throw new v("Event trigger must specify an eventName");this.unsubscribeFromEvents(e),n.triggers=a.length>0?a:void 0,this.subscribeToEvents(n)}return f!==void 0&&(n.allowUnauthenticated=f),n.updatedAt=Date.now(),this.functions.set(e,n),await this.saveFunctionsMetadata(),n}async deleteFunction(e){let r=this.functions.get(e);if(!r)return!1;try{return this.unsubscribeFromEvents(e),V(r.filePath)&&await nt(r.filePath),this.functions.delete(e),await this.saveFunctionsMetadata(),!0}catch(n){throw console.error(`Error deleting function ${e}:`,n.message),n}}wrapFunctionCode(e){let r=e;if(/export\s+default\s+\w+/.test(e))return`// FunctionsService generated module
12
12
  // Generated at: ${new Date().toISOString()}
13
13
 
14
14
  // User function code starts here