balda 0.0.21 → 0.0.22
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/README.md +15 -5
- package/bun.lock +2918 -0
- package/package.json +14 -11
- package/lib/cli.js +0 -596
- package/lib/cli.js.map +0 -1
- package/lib/index.cjs +0 -730
- package/lib/index.cjs.map +0 -1
- package/lib/index.d.cts +0 -4049
- package/lib/index.d.ts +0 -4049
- package/lib/index.js +0 -730
- package/lib/index.js.map +0 -1
package/lib/index.cjs
DELETED
|
@@ -1,730 +0,0 @@
|
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var ajv=require('ajv'),er=require('pino'),Ve=require('fs'),st=require('path'),async_hooks=require('async_hooks'),zlib=require('zlib'),http=require('http'),http2=require('http2'),https=require('https'),stream=require('stream'),promises=require('stream/promises'),glob=require('glob'),child_process=require('child_process'),zr=require('readline'),po=require('crypto');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var er__default=/*#__PURE__*/_interopDefault(er);var Ve__default=/*#__PURE__*/_interopDefault(Ve);var st__default=/*#__PURE__*/_interopDefault(st);var zr__namespace=/*#__PURE__*/_interopNamespace(zr);var po__default=/*#__PURE__*/_interopDefault(po);var Yt=Object.defineProperty;var is=(i,e)=>()=>(i&&(e=i(i=0)),e);var ns=(i,e)=>{for(var t in e)Yt(i,t,{get:e[t],enumerable:true});};var w=(i,e,t,r)=>{for(var s=void 0,o=i.length-1,n;o>=0;o--)(n=i[o])&&(s=(n(e,t,s))||s);return s&&Yt(e,t,s),s};var Xt={};ns(Xt,{runtime:()=>C});var Ct,C,W=is(()=>{Ct=class{type;constructor(){this.type=this.getRunTime();}getRunTime(){if(typeof Bun<"u")return "bun";if(typeof Deno<"u")return "deno";if(typeof process<"u")return "node";throw new Error("No environment detected")}},C=new Ct;});var H=class{static ajv=new ajv.Ajv({validateSchema:false,strict:false});static{this.ajv.addFormat("email",/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/),this.ajv.addFormat("url",/^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/),this.ajv.addFormat("date",/^\d{4}-\d{2}-\d{2}$/),this.ajv.addFormat("datetime",/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})$/),this.ajv.addFormat("time",/^\d{2}:\d{2}:\d{2}$/),this.ajv.addFormat("binary",/^(?:[0-9a-fA-F]{2})+$/),this.ajv.addFormat("base64",/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/),this.ajv.addFormat("uuid",/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);}static setGlobalInstance(e){this.ajv=e,this.ajv.opts.strict=false,this.ajv.opts.validateSchema=false;}};W();var ke=class{get(e){switch(C.type){case "node":case "bun":case "deno":return process.env[e];default:throw new Error(`Unsupported runtime: ${C.type}`)}}getEnvironment(){switch(C.type){case "node":case "deno":case "bun":return Object.fromEntries(Object.entries(process.env).filter(([e,t])=>t!==void 0))}}};var cs=new ke,B=i=>{let e=cs.get("NODE_ENV")!=="production";return {code:i.name||"INTERNAL_ERROR",message:i.message,...e&&{stack:i.stack,cause:i.cause}}};var T=class extends Error{constructor(e){super(e);}};var $e=class extends T{constructor(e,t){super(`METHOD_NOT_ALLOWED: Cannot ${t} ${e}`);}};var D=class extends T{constructor(e,t){super(`ROUTE_NOT_FOUND: Cannot ${t} ${e}`);}};var ee=class{schemaOptions;apolloOptions;isEnabled;constructor(e){let t=this.initializeConfiguration(e);this.schemaOptions=t.schemaOptions,this.apolloOptions=t.apolloOptions,this.isEnabled=t.isEnabled;}getSchemaOptions(){return this.schemaOptions}getApolloOptions(){return this.apolloOptions}addTypeDef(e){if(typeof e=="function"){this.addTypeDef(e());return}if(Array.isArray(e)){this.addTypeDefArray(e);return}this.ensureTypeDefsArray(),this.schemaOptions.typeDefs.push(e);}addResolver(e,t){if(typeof e=="string"&&t){this.addResolverByType(e,t);return}this.addFullResolver(e);}initializeConfiguration(e){return e?this.createEnabledConfiguration(e):this.createDisabledConfiguration()}createDisabledConfiguration(){return {schemaOptions:{typeDefs:"",resolvers:{}},apolloOptions:{},isEnabled:false}}createEnabledConfiguration(e){return {schemaOptions:this.resolveSchemaOptions(e.schema),apolloOptions:this.resolveApolloOptions(e.apolloOptions),isEnabled:true}}resolveSchemaOptions(e){return e!==void 0?e:{typeDefs:"",resolvers:{}}}resolveApolloOptions(e){return e!==void 0?e:{}}addResolverByType(e,t){if(this.ensureResolversInitialized(),Array.isArray(this.schemaOptions.resolvers)){this.schemaOptions.resolvers.push({[e]:t});return}this.mergeResolverIntoObject(e,t);}ensureResolversInitialized(){!this.schemaOptions.resolvers&&(this.schemaOptions.resolvers={});}mergeResolverIntoObject(e,t){let r=this.schemaOptions.resolvers,s=r[e];if(s&&typeof s=="object"){r[e]={...s,...t};return}r[e]=t;}addFullResolver(e){if(this.ensureResolversInitialized(),Array.isArray(e)){this.addResolverArray(e);return}if(typeof e=="object"&&e!==null){this.addResolverObject(e);return}this.schemaOptions.resolvers=e;}addResolverArray(e){if(Array.isArray(this.schemaOptions.resolvers)){this.schemaOptions.resolvers=[...this.schemaOptions.resolvers,...e];return}this.schemaOptions.resolvers=[this.schemaOptions.resolvers,...e];}addResolverObject(e){if(Array.isArray(this.schemaOptions.resolvers)){this.schemaOptions.resolvers=[...this.schemaOptions.resolvers,e];return}this.schemaOptions.resolvers={...this.schemaOptions.resolvers,...e};}addTypeDefArray(e){for(let t of e)this.addTypeDef(t);}ensureTypeDefsArray(){if(Array.isArray(this.schemaOptions.typeDefs))return;if(this.schemaOptions.typeDefs!==void 0){this.schemaOptions.typeDefs=[this.schemaOptions.typeDefs];return}this.schemaOptions.typeDefs=[];}};var ps=()=>er__default.default({level:"info",formatters:{level:e=>({level:e})}});exports.logger=ps();var jo=i=>{exports.logger=er__default.default(i);};var le=async(i,e,t,r)=>{if(!i||i.length===0)return await e(t,r),r;let s=0,o=i.length,n=async()=>{if(s>=o)return;let a=i[s++];await a(t,r,n);};return await n(),s>=o&&await e(t,r),r},ls=new Set(["post","put","patch"]),te=i=>i?ls.has(i.toLowerCase()):true,tt=async(i,e,t,r,s)=>{try{let{HeaderMap:o}=await import('@apollo/server'),n=new o;e.headers.forEach((h,g)=>{n.set(g,h);});let c=(e.headers.get("content-type")??"").includes("application/json"),p="";if(t!=="GET"){let h=await e.text();p=c&&h?JSON.parse(h):h;}let l={method:t.toUpperCase(),headers:n,body:p,search:r?`?${r}`:""},d=await i.executeHTTPGraphQLRequest({httpGraphQLRequest:l,context:async()=>s}),m={};for(let[h,g]of d.headers)m[h]=g;if(d.body.kind==="complete")return new globalThis.Response(d.body.string,{status:d.status??200,headers:m});let y=new ReadableStream({async start(h){if(d.body.kind==="chunked")for await(let g of d.body.asyncIterator)h.enqueue(new TextEncoder().encode(g));h.close();}});return new globalThis.Response(y,{status:d.status??200,headers:m})}catch{return new globalThis.Response(JSON.stringify({errors:[{message:"Internal server error"}]}),{status:500,headers:{"Content-Type":"application/json"}})}},tr=async(i,e,t,r,s,o,n)=>{try{let{HeaderMap:a}=await import('@apollo/server'),c=new a;for(let[g,b]of Object.entries(e))b!==void 0&&c.set(g,Array.isArray(b)?b.join(", "):b);let d=(c.get("content-type")??"").includes("application/json")&&r?JSON.parse(r):r,m={method:t?.toUpperCase()??"POST",headers:c,body:d,search:s?`?${s}`:""},y=await i.executeHTTPGraphQLRequest({httpGraphQLRequest:m,context:async()=>o}),h=y.status??200;y.body.kind==="complete"?await n(y.headers,h,y.body.string):await n(y.headers,h,y.body.asyncIterator);}catch{await n(new Map([["Content-Type","application/json"]]),500,JSON.stringify({errors:[{message:"Internal server error"}]}));}},de=i=>{let e=null,t=false,r=async()=>{for(;t;)await new Promise(o=>setTimeout(o,10));},s=async()=>{try{let{ApolloServer:o}=await import('@apollo/server'),{makeExecutableSchema:n}=await import('@graphql-tools/schema'),a=i.getSchemaOptions(),c=i.getApolloOptions(),p=n({typeDefs:a.typeDefs,resolvers:a.resolvers}),l=new o({schema:p,...c});return await l.start(),{server:l,url:"/graphql"}}catch(o){throw o instanceof Error&&(o.message.includes("Cannot find module")||o.message.includes("Cannot find package"))?new Error("GraphQL is enabled but '@apollo/server' is not installed. Install it with: npm install @apollo/server @graphql-tools/schema graphql"):o}};return async()=>{if(!i.isEnabled)return null;if(e!==null)return e;if(t)return await r(),e;t=true;try{return e=s(),await e}catch(c){throw e=null,c}finally{t=false;}}};var Q=new Map;var qt=class{randomUUID(){return crypto.randomUUID()}},J=new qt;var Be=class{static typeboxModule=null;static loadPromise=null;static async load(){return this.typeboxModule?this.typeboxModule:this.loadPromise?this.loadPromise:(this.loadPromise=(async()=>{try{return this.typeboxModule=await import('@sinclair/typebox'),this.typeboxModule}catch{throw new Error(`TypeBox is not installed. Install it with: npm install @sinclair/typebox
|
|
2
|
-
TypeBox is a peer dependency required when using TypeBox schemas for validation.`)}})(),this.loadPromise)}static get(){if(!this.typeboxModule)throw new Error("TypeBox has not been loaded yet. Call TypeBoxLoader.load() first.");return this.typeboxModule}static isTypeBoxSchema(e){return typeof e=="object"&&e!==null&&"type"in e&&Object.getOwnPropertySymbols(e).some(t=>t.toString()==="Symbol(TypeBox.Kind)")}};var U=(i,e,t=false)=>{if(!i(e)){if(t)return e;throw new ajv.ValidationError(i.errors||[])}return e};var ae=class{static zodModule=null;static loadPromise=null;static async load(){return this.zodModule?this.zodModule:this.loadPromise?this.loadPromise:(this.loadPromise=(async()=>{try{return this.zodModule=await import('zod'),this.zodModule}catch{throw new Error(`Zod is not installed. Install it with: npm install zod
|
|
3
|
-
Zod is a peer dependency required when using Zod schemas for validation.`)}})(),this.loadPromise)}static get(){if(!this.zodModule)throw new Error("Zod has not been loaded yet. Call ZodLoader.load() first.");return this.zodModule}static isZodSchema(e){let t=typeof e=="object"&&e!==null&&"_def"in e&&typeof e.parse=="function"&&typeof e.safeParse=="function";if(t&&!("toJSONSchema"in e))throw new Error("Zod4 is required with the toJSONSchema() method in order to work. Install it with: npm install zod with minimum version 4.0.0");return t}};var Le=new WeakMap,Z=class i{static fromRequest(e){let t=new i,r=e.method;return t.url=e.url,t.method=r,t.headers=e.headers,t.signal=e.signal,t.referrer=e.referrer,t.referrerPolicy=e.referrerPolicy,t.mode=e.mode,t.credentials=e.credentials,t.cache=e.cache,t.redirect=e.redirect,t.integrity=e.integrity,t.keepalive=e.keepalive,t.#s=e,t}toWebApi(){if(this.#s)return this.#s;let e=this.method==="POST"||this.method==="PUT"||this.method==="PATCH";return new globalThis.Request(this.url,{method:this.method,...e&&this.body?{body:this.body,duplex:"half"}:{},headers:this.headers,signal:this.signal,referrer:this.referrer,referrerPolicy:this.referrerPolicy,mode:this.mode,credentials:this.credentials,cache:this.cache,redirect:this.redirect,integrity:this.integrity,keepalive:this.keepalive})}static compileAndValidate(e,t,r){let s,o;if(ae.isZodSchema(e)){let p=e,l=Le.get(p);l||(l=Symbol("zod_schema"),Le.set(p,l));let d=Q.get(l);if(d)return U(d,t,r);s=p.toJSONSchema();let m=H.ajv.compile(s);return Q.set(l,m),U(m,t,r)}if(Be.isTypeBoxSchema(e)){let p=e,l=Le.get(p);l||(l=Symbol("typebox_schema"),Le.set(p,l));let d=Q.get(l);if(d)return U(d,t,r);let m=H.ajv.compile(p);return Q.set(l,m),U(m,t,r)}let n=e;if(typeof n=="object"&&n!==null){let p=Le.get(n);p||(p=Symbol("json_schema"),Le.set(n,p));let l=Q.get(p);if(l)return U(l,t,r);let d=H.ajv.compile(n);return Q.set(p,d),U(d,t,r)}o=JSON.stringify(n);let a=Q.get(o);if(a)return U(a,t,r);let c=H.ajv.compile(n);return Q.set(o,c),U(c,t,r)}#s;url="";method="GET";headers=new Headers;signal;referrer;referrerPolicy;mode;credentials;cache;redirect;integrity;keepalive;body=void 0;bodyUsed=false;ctx={};file=e=>this.files.find(t=>t.formName===e)??null;cookies={};cookie=e=>this.cookies[e];timeout;session=void 0;saveSession=async()=>{};destroySession=async()=>{};ip;files=[];params={};#t;#e;#r=false;get query(){if(this.#r)return this.#t;if(!this.#e||this.#e==="")this.#t={};else if(this.#e.length<50&&!this.#e.includes("&")){let e=this.#e.indexOf("=");if(e===-1)this.#t={[this.#e]:""};else {let t=this.#e.slice(0,e),r=decodeURIComponent(this.#e.slice(e+1));this.#t={[t]:r};}}else this.#t=Object.fromEntries(new URLSearchParams(this.#e));return this.#r=true,this.#t}set query(e){this.#t=e,this.#r=true;}setQueryString(e){this.#e=e,this.#r=false,this.#t=void 0;}#o;get id(){return this.#o||(this.#o=J.randomUUID()),this.#o}set id(e){this.#o=e;}validate(e,t=false){return i.compileAndValidate(e,this.body||{},t)}validateQuery(e,t=false){return i.compileAndValidate(e,this.query||{},t)}validateAll(e,t=false){return i.compileAndValidate(e,{...this.body??{},...this.query??{}},t)}};W();var Et=class{file(e,t){switch(C.type){case "bun":case "node":return Ve__default.default.readFileSync(e,t);case "deno":return Deno.readFileSync(e);default:throw new Error("Unsupported runtime")}}},rt=new Et;W();var jt=class{basename(e){switch(C.type){case "node":case "bun":case "deno":return st__default.default.basename(e);default:throw new Error("Unsupported runtime")}}join(...e){switch(C.type){case "node":case "bun":case "deno":return st__default.default.join(...e);default:throw new Error("Unsupported runtime")}}extName(e){switch(C.type){case "bun":case "node":case "deno":return st__default.default.extname(e);default:throw new Error("Unsupported runtime")}}resolve(...e){switch(C.type){case "bun":case "node":case "deno":return st__default.default.resolve(...e);default:throw new Error("Unsupported runtime")}}},f=new jt;var rr=new Map([[".html","text/html"],[".htm","text/html"],[".css","text/css"],[".js","application/javascript"],[".mjs","application/javascript"],[".cjs","application/javascript"],[".ts","application/typescript"],[".jsx","text/jsx"],[".tsx","text/tsx"],[".json","application/json"],[".xml","application/xml"],[".yaml","application/yaml"],[".yml","application/yaml"],[".csv","text/csv"],[".txt","text/plain"],[".md","text/markdown"],[".markdown","text/markdown"],[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".gif","image/gif"],[".svg","image/svg+xml"],[".ico","image/x-icon"],[".webp","image/webp"],[".avif","image/avif"],[".bmp","image/bmp"],[".tiff","image/tiff"],[".tif","image/tiff"],[".heic","image/heic"],[".heif","image/heif"],[".mp4","video/mp4"],[".webm","video/webm"],[".avi","video/x-msvideo"],[".mov","video/quicktime"],[".mkv","video/x-matroska"],[".wmv","video/x-ms-wmv"],[".flv","video/x-flv"],[".m4v","video/x-m4v"],[".mpeg","video/mpeg"],[".mpg","video/mpeg"],[".3gp","video/3gpp"],[".mp3","audio/mpeg"],[".wav","audio/wav"],[".ogg","audio/ogg"],[".flac","audio/flac"],[".aac","audio/aac"],[".m4a","audio/mp4"],[".wma","audio/x-ms-wma"],[".opus","audio/opus"],[".mid","audio/midi"],[".midi","audio/midi"],[".woff","font/woff"],[".woff2","font/woff2"],[".ttf","font/ttf"],[".otf","font/otf"],[".eot","application/vnd.ms-fontobject"],[".pdf","application/pdf"],[".doc","application/msword"],[".docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"],[".xls","application/vnd.ms-excel"],[".xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],[".ppt","application/vnd.ms-powerpoint"],[".pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"],[".odt","application/vnd.oasis.opendocument.text"],[".ods","application/vnd.oasis.opendocument.spreadsheet"],[".odp","application/vnd.oasis.opendocument.presentation"],[".rtf","application/rtf"],[".epub","application/epub+zip"],[".zip","application/zip"],[".tar","application/x-tar"],[".gz","application/gzip"],[".gzip","application/gzip"],[".bz2","application/x-bzip2"],[".xz","application/x-xz"],[".rar","application/vnd.rar"],[".7z","application/x-7z-compressed"],[".wasm","application/wasm"],[".map","application/json"],[".webmanifest","application/manifest+json"],[".ics","text/calendar"],[".vcf","text/vcard"],[".sql","application/sql"],[".sh","application/x-sh"],[".bat","application/x-msdos-program"],[".exe","application/x-msdownload"],[".dll","application/x-msdownload"],[".bin","application/octet-stream"],[".iso","application/x-iso9660-image"],[".dmg","application/x-apple-diskimage"],[".apk","application/vnd.android.package-archive"],[".jar","application/java-archive"],[".swf","application/x-shockwave-flash"]]);W();var Mt=class{getCwd(){switch(C.type){case "node":case "bun":return process.cwd();case "deno":return Deno.cwd();default:throw new Error("Unsupported runtime")}}},I=new Mt;W();var At=class{async mkdir(e,t){switch(C.type){case "bun":case "node":await(await import('fs/promises')).mkdir(e,{recursive:t?.recursive??false,mode:t?.mode});break;case "deno":typeof t?.mode=="string"&&(t.mode=Number.parseInt(t.mode)),await Deno.mkdir(e,{recursive:t?.recursive??false,mode:t?.mode});break}}async exists(e){switch(C.type){case "node":return (await import('fs')).existsSync(e);case "bun":return (await import('fs')).existsSync(e);case "deno":return Deno.stat(e).then(()=>true).catch(()=>false);default:throw new Error("Unsupported runtime")}}async readFile(e,t){switch(C.type){case "node":let s=await(await import('fs/promises')).readFile(e,{encoding:t?.encoding??null});return t?.encoding==="utf8"?s:new Uint8Array(s);case "bun":let o=Bun.file(e);return t?.encoding==="utf8"?o.text():new Uint8Array(await o.arrayBuffer());case "deno":let n=await Deno.readFile(e);return t?.encoding==="utf8"?new TextDecoder().decode(n):new Uint8Array(n)}}async writeFile(e,t){switch(C.type){case "node":await(await import('fs/promises')).writeFile(e,t);break;case "bun":await Bun.write(e,t);break;case "deno":await Deno.writeFile(e,t);break}}async stat(e){switch(C.type){case "node":let r=await(await import('fs/promises')).stat(e);return {isDirectory:r.isDirectory(),isFile:r.isFile(),isSymbolicLink:r.isSymbolicLink(),size:r.size};case "bun":let o=await(await import('fs/promises')).stat(e);return {isDirectory:o.isDirectory(),isFile:o.isFile(),isSymbolicLink:o.isSymbolicLink(),size:o.size};case "deno":let n=await Deno.stat(e);return {isDirectory:n.isDirectory,isFile:n.isFile,isSymbolicLink:false,size:n.size}}}async unlink(e){switch(C.type){case "node":await(await import('fs/promises')).unlink(e);break;case "bun":await Bun.file(e).delete();break;case "deno":await Deno.remove(e);break;default:throw new Error("Unsupported runtime")}}async streamFile(e){switch(C.type){case "node":let t=await import('fs'),{Readable:r}=await import('stream'),s=t.createReadStream(e);return r.toWeb(s);case "bun":return Bun.file(e).stream();case "deno":return (await Deno.open(e)).readable;default:throw new Error("Unsupported runtime")}}async readdir(e){switch(C.type){case "bun":case "node":return (await import('fs/promises')).readdir(e);case "deno":let r=[];for await(let s of Deno.readDir(e))r.push(s.name);return r;default:throw new Error("Unsupported runtime")}}},u=new At;var Qe=class{staticChildren;paramChild;wildcardChild;middleware;handler;constructor(){this.staticChildren=new Map,this.paramChild=null,this.wildcardChild=null,this.middleware=null,this.handler=null;}},kt=class i{trees;routes;middlewares;basePath;staticRouteCache;constructor(e="",t=[]){this.trees=new Map,this.routes=[],this.middlewares=t,this.basePath=this.normalizeBasePath(e),this.staticRouteCache=new Map;}getRoutes(){return this.routes.slice()}addOrUpdate(e,t,r,s,o){e=e.toUpperCase();let n=t.split("?")[0],a=this.trees.get(e);a||(a=new Qe,this.trees.set(e,a));let c=n.replace(/^\/+|\/+$/g,""),p=c.length===0?[]:c.split("/"),l=a;for(let m of p){if(m==="*"){l.wildcardChild||(l.wildcardChild=new Qe),l=l.wildcardChild;break}if(m.startsWith(":")){let y=m.slice(1);l.paramChild||(l.paramChild={node:new Qe,name:y}),l=l.paramChild.node;continue}l.staticChildren.has(m)||l.staticChildren.set(m,new Qe),l=l.staticChildren.get(m);}l.middleware=r,l.handler=s;let d=this.routes.findIndex(m=>m.method===e&&m.path===t);if(d!==-1){this.routes[d].middleware=r,this.routes[d].handler=s;return}this.routes.push({method:e,path:t,middleware:r,handler:s,swaggerOptions:o});}find(e,t){e=e.toUpperCase();let r=t.indexOf("?"),s=r===-1?t:t.slice(0,r),o=`${e}:${s}`,n=this.staticRouteCache.get(o);if(n)return n;let a=this.trees.get(e);if(!a)return null;let c=s.replace(/^\/+|\/+$/g,""),p=c.length===0?[]:c.split("/"),l={},d=a;for(let m=0;m<p.length;m++){let y=p[m];if(d.staticChildren.has(y)){d=d.staticChildren.get(y);continue}if(d.paramChild){l[d.paramChild.name]=y,d=d.paramChild.node;continue}if(d.wildcardChild){l["*"]=p.slice(m).join("/"),d=d.wildcardChild;break}return null}return !d.handler||!d.middleware?null:{middleware:d.middleware,handler:d.handler,params:l}}get(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("GET",o,p,a,l);}post(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("POST",o,p,a,l);}patch(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("PATCH",o,p,a,l);}put(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("PUT",o,p,a,l);}delete(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("DELETE",o,p,a,l);}options(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("OPTIONS",o,p,a,l);}head(e,t,r,s){let o=this.joinPath(e),n=typeof t=="function"&&t.length!==3,a=n?t:r,c=n?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...c],l=n?r:s;this.addOrUpdate("HEAD",o,p,a,l);}group(e,t,r){let s=Array.isArray(t)?t:typeof t=="function"?[]:t?[t]:[],o=Array.isArray(t)?r:typeof t=="function"?t:void 0,n=this.joinPath(e),a=new i(n,[...this.middlewares,...s]);o?.(a);for(let c of a.getRoutes())this.addOrUpdate(c.method,c.path,c.middleware,c.handler,c.swaggerOptions);}applyGlobalMiddlewaresToAllRoutes(e){for(let t of this.routes){let r=[...e,...t.middleware||[]];this.addOrUpdate(t.method,t.path,r,t.handler);}}normalizeBasePath(e){if(!e)return "";let t=e.replace(/\s+/g,"");return t=t.replace(/\/+/g,"/"),t.startsWith("/")||(t="/"+t),t.length>1&&(t=t.replace(/\/+$/g,"")),t}joinPath(e){let r=[this.basePath,e].filter(s=>typeof s=="string"&&s.length>0).join("/");return r=r.replace(/\/+/g,"/"),r.startsWith("/")||(r="/"+r),r.length>1&&(r=r.replace(/\/+$/g,"")),r}},M=new kt;var sr=(i,e)=>{let{source:t,path:r}=i,s=r;return s.startsWith("/")||(s="/"+s),s!=="/"&&s.endsWith("/")&&(s=s.slice(0,-1)),M.addOrUpdate("GET",`${s}/*`,[],async(o,n)=>ms(o,n,t),{service:"StaticFiles",...e}),async(o,n,a)=>a()};async function ms(i,e,t){if(i.method!=="GET"&&i.method!=="HEAD")return e.status(405).json({...B(new $e(i.url,i.method))});let r=i.params["*"]||"",s=f.join(t,r),o=f.resolve(I.getCwd(),s),n=f.resolve(I.getCwd(),t);if(!o.startsWith(n))return e.notFound({...B(new D(i.url,i.method))});try{if(!(await u.stat(o)).isFile)return e.notFound({...B(new D(i.url,i.method))})}catch(p){if(p.code==="ENOENT")return e.notFound({...B(new D(i.url,i.method))});throw p}let a=$t(f.extName(o));e.setHeader("Content-Type",a);let c=rt.file(o);e.raw(c);}function $t(i){return rr.get(i)||"application/octet-stream"}var _=class{static toWebResponse(e){let t=e.getBody();return e.headers["Content-Type"]?.toLowerCase()==="application/json"&&typeof t=="object"?globalThis.Response.json(t,{status:e.responseStatus,headers:e.headers}):new globalThis.Response(t,{status:e.responseStatus,headers:e.headers})}responseStatus;headers;body;constructor(e=200){this.responseStatus=e,this.headers={};}setHeader(e,t){return this.headers[e]=t,this}status(e){return this.responseStatus=e,this}send(e){if(e==null)return this.text("");if(typeof e=="string")return this.text(e);if(typeof e=="number"||typeof e=="boolean"||typeof e=="bigint")return this.raw(e);if(typeof Buffer<"u"&&e instanceof Buffer)return this.download(new Uint8Array(e));if(e instanceof ArrayBuffer||e instanceof Uint8Array)return this.download(new Uint8Array(e));if(typeof e=="object"&&e!==null)try{return this.json(e)}catch{return this.text(String(e))}if(typeof e=="symbol")return this.text(e.toString());this.body=e;}raw(e){this.body=e;}text(e){this.body=e,this.headers["Content-Type"]="text/plain";}json(e){this.body=e,this.headers["Content-Type"]="application/json";}html(e){this.body=e,this.headers["Content-Type"]="text/html";}xml(e){this.body=e,this.headers["Content-Type"]="application/xml";}download(e){this.body=e,this.headers["Content-Type"]="application/octet-stream";}file(e,t){let r=f.extName(e),s=$t(r);this.body=rt.file(e,t),this.headers["Content-Type"]=s;}ok(e){this.status(200).send(e);}created(e){this.status(201).send(e);}accepted(e){this.status(202).send(e);}noContent(){this.responseStatus=204,this.body="";}partialContent(e){this.status(206).send(e);}multipleChoices(e){this.status(300).setHeader("Location",e);}redirect(e){this.status(302).setHeader("Location",e);}movedPermanently(e){this.status(301).setHeader("Location",e);}found(e){this.status(302).setHeader("Location",e);}seeOther(e){this.status(303).setHeader("Location",e);}notModified(){this.responseStatus=304,this.body="";}temporaryRedirect(e){this.status(307).setHeader("Location",e);}permanentRedirect(e){this.status(308).setHeader("Location",e);}badRequest(e){this.status(400).send(e);}unauthorized(e){this.status(401).send(e);}forbidden(e){this.status(403).send(e);}notFound(e){this.status(404).send(e);}methodNotAllowed(e){this.status(405).send(e);}notAcceptable(e){this.status(406).send(e);}conflict(e){this.status(409).send(e);}gone(e){this.status(410).send(e);}payloadTooLarge(e){this.status(413).send(e);}unsupportedMediaType(e){this.status(415).send(e);}unprocessableEntity(e){this.status(422).send(e);}tooManyRequests(e){this.status(429).send(e);}internalServerError(e){this.status(500).send(e);}notImplemented(e){this.status(501).send(e);}badGateway(e){this.status(502).send(e);}serviceUnavailable(e){this.status(503).send(e);}gatewayTimeout(e){this.status(504).send(e);}httpVersionNotSupported(e){this.status(505).send(e);}stream(e,t){if(this.headers["Content-Type"]="text/event-stream",this.headers["Cache-Control"]="no-cache",this.headers.Connection="keep-alive",t?.customHeaders)for(let r in t.customHeaders)this.headers[r]=t.customHeaders[r];if(e instanceof ReadableStream){this.body=e;return}this.body=new ReadableStream({async start(r){for await(let s of e)r.enqueue(new TextEncoder().encode(s));r.close();}});}getBody(){return this.body}};var ce=class{constructor(e){this.response=e;}body(){return this.response.getBody()}statusCode(){return this.response.responseStatus}headers(){return this.response.headers}assertStatus(e){if(this.response.responseStatus!==e)throw new Error(`Expected status ${e}, but got ${this.response.responseStatus}`);return this}assertHeader(e,t){if(this.response.headers[e]!==t)throw new Error(`Expected header ${e} to be ${t}, but got ${this.response.headers[e]}`);return this}assertHeaderExists(e){if(!(e in this.response.headers))throw new Error(`Expected header ${e} to exist, but it was not found`);return this}assertHeaderNotExists(e){if(e in this.response.headers)throw new Error(`Expected header ${e} to not exist, but it was found with value: ${this.response.headers[e]}`);return this}assertBodySubset(e){return this.assertSubset(this.body(),e,"body"),this}assertBodyDeepEqual(e){return this.assertDeepEqual(this.body(),e,"body"),this}assertBodyNotSubset(e){return this.assertNotSubset(this.body(),e,"body"),this}assertBodyNotDeepEqual(e){return this.assertNotDeepEqual(this.body(),e,"body"),this}assertCustom(e){return e(this.response),this}assertSubset(e,t,r){for(let s in t){let o=r===""?s:`${r}.${s}`,n=e[s],a=t[s];if(!(s in e))throw new Error(`Expected ${r} to have key ${s}, but it was not found`);if(this.isObject(a)&&this.isObject(n))this.assertSubset(n,a,o);else if(Array.isArray(a)&&Array.isArray(n))this.assertArraySubset(n,a,o);else if(n!==a)throw new Error(`Expected ${o} to be ${a}, but got ${n}`)}}assertDeepEqual(e,t,r){if(this.isObject(e)&&this.isObject(t)){let s=Object.keys(e),o=Object.keys(t);if(s.length!==o.length)throw new Error(`Expected ${r} to have ${o.length} keys, but got ${s.length}`);for(let n of o){let a=r==="body"?n:`${r}.${n}`;this.assertDeepEqual(e[n],t[n],a);}}else if(Array.isArray(e)&&Array.isArray(t))this.assertArrayDeepEqual(e,t,r);else if(e!==t)throw new Error(`Expected ${r} to be ${t}, but got ${e}`)}assertNotSubset(e,t,r){try{throw this.assertSubset(e,t,r),new Error(`Expected ${r} to NOT contain the subset, but it does`)}catch(s){if(s instanceof Error&&s.message.includes("Expected"))return;throw s}}assertNotDeepEqual(e,t,r){try{throw this.assertDeepEqual(e,t,r),new Error(`Expected ${r} to NOT be deeply equal, but it is`)}catch(s){if(s instanceof Error&&s.message.includes("Expected"))return;throw s}}assertArraySubset(e,t,r){if(t.length>e.length)throw new Error(`Expected ${r} to have at least ${t.length} elements, but got ${e.length}`);for(let s=0;s<t.length;s++){let o=`${r}[${s}]`,n=e[s],a=t[s];if(this.isObject(a)&&this.isObject(n))this.assertSubset(n,a,o);else if(Array.isArray(a)&&Array.isArray(n))this.assertArraySubset(n,a,o);else if(n!==a)throw new Error(`Expected ${o} to be ${a}, but got ${n}`)}}assertArrayDeepEqual(e,t,r){if(e.length!==t.length)throw new Error(`Expected ${r} to have ${t.length} elements, but got ${e.length}`);for(let s=0;s<t.length;s++){let o=`${r}[${s}]`;this.assertDeepEqual(e[s],t[s],o);}}isObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}};var ot=class{server;ensureGraphQLHandler;constructor(e){this.server=e,this.ensureGraphQLHandler=de(this.server.graphql);}async request(e,t,r={}){let{headers:s={},query:o={},cookies:n={},ip:a}=r;this.validateOptions(r);let c=this.server.graphql.isEnabled,p=t.startsWith("/graphql");if(c&&p)return this.handleGraphQLRequest(e,t,r);let l=M.find(e.toUpperCase(),t);if(!l){let b=new _(404);return b.json({caller:"MockServer",error:"Route not found",path:t,method:e}),new ce(b)}let d,m="application/json";if(r.body!==void 0&&(typeof r.body=="object"&&!(r.body instanceof Uint8Array)&&!(r.body instanceof ArrayBuffer)?d=JSON.stringify(r.body):d=r.body),r.formData){let b=`----WebKitFormBoundary${Math.random().toString(36).substring(2)}`;m=`multipart/form-data; boundary=${b}`,d=await this.formDataToMultipart(r.formData,b);}r.urlencoded&&(m="application/x-www-form-urlencoded",d=new URLSearchParams(r.urlencoded).toString());let y=new URL(`http://${this.server.host}:${this.server.port}${t}`);y.search=new URLSearchParams(o).toString();let h=new globalThis.Request(y.toString(),{method:e.toUpperCase(),body:te(e)?d:void 0,headers:{"content-type":m,...s}}),g=Z.fromRequest(h);g.query={...Object.fromEntries(y.searchParams.entries()),...o},g.params=l.params,g.cookies=n,g.ip=a;try{let b=await le(l.middleware,l.handler,g,new _);return new ce(b)}catch(b){exports.logger.error({error:b},`Error processing mock request ${e} ${t}:`);let P=new _(500);return P.json({error:"Internal server error",message:b instanceof Error?b.message:String(b)}),new ce(P)}}async get(e,t){return this.request("GET",e,t)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async formDataToMultipart(e,t){let r=new TextEncoder,s=[];for(let[c,p]of e.entries()){s.push(r.encode(`--${t}\r
|
|
4
|
-
`));let l=`Content-Disposition: form-data; name="${c}"`,d="";if(p instanceof File&&(l+=`; filename="${p.name}"`,d=`Content-Type: ${p.type||"application/octet-stream"}\r
|
|
5
|
-
`),s.push(r.encode(`${l}\r
|
|
6
|
-
${d}\r
|
|
7
|
-
`)),p instanceof File){let m=await p.arrayBuffer();s.push(new Uint8Array(m)),s.push(r.encode(`\r
|
|
8
|
-
`));}else s.push(r.encode(`${String(p)}\r
|
|
9
|
-
`));}s.push(r.encode(`--${t}--\r
|
|
10
|
-
`));let o=s.reduce((c,p)=>c+p.byteLength,0),n=new Uint8Array(o),a=0;for(let c of s)n.set(c,a),a+=c.byteLength;return n}async handleGraphQLRequest(e,t,r={}){let s=await this.ensureGraphQLHandler();if(!s){let d=new _(500);return d.json({errors:[{message:"GraphQL handler not initialized"}]}),new ce(d)}let{headers:o={},query:n={}}=r,a=new URL(`http://${this.server.host}:${this.server.port}${t}`);a.search=new URLSearchParams(n).toString();let c;r.body!==void 0&&te(e)&&(typeof r.body=="object"&&!(r.body instanceof Uint8Array)&&!(r.body instanceof ArrayBuffer)?c=JSON.stringify(r.body):c=r.body);let p=new globalThis.Request(a.toString(),{method:e.toUpperCase(),body:c,headers:{"content-type":"application/json",...o}}),l=Z.fromRequest(p);l.query={...Object.fromEntries(a.searchParams.entries()),...n};try{let{HeaderMap:d}=await import('@apollo/server'),m=new d;for(let[k,L]of Object.entries(o))L!==void 0&&m.set(k,Array.isArray(L)?L.join(", "):String(L));let h=(m.get("content-type")??"").includes("application/json"),g="";typeof c=="string"?g=c:c instanceof Uint8Array?g=new TextDecoder().decode(c):c&&typeof c=="object"&&(g=new TextDecoder().decode(new Uint8Array(c)));let b=h&&g?JSON.parse(g):g,P={method:e.toUpperCase(),headers:m,body:b,search:a.search},j=this.server.graphql.getApolloOptions(),A=j.context&&typeof j.context=="function"?await j.context({req:l}):{req:l},x=await s.server.executeHTTPGraphQLRequest({httpGraphQLRequest:P,context:async()=>A}),R=x.status??200,q=new _(R);for(let[k,L]of x.headers)q.setHeader(k,L);if(x.body.kind==="complete"){let k=x.body.string;try{q.json(JSON.parse(k));}catch{q.text(k);}}else {let k="";for await(let L of x.body.asyncIterator)k+=L;try{q.json(JSON.parse(k));}catch{q.text(k);}}return new ce(q)}catch(d){exports.logger.error({error:d},`Error processing GraphQL request ${e} ${t}:`);let m=new _(500);return m.json({errors:[{message:"Internal server error"}]}),new ce(m)}}validateOptions(e){let{body:t,formData:r,urlencoded:s}=e;if(t&&(r||s))throw new Error("Only one of body, formData, urlencoded can be provided");if(r&&(s||t))throw new Error("Only one of formData, urlencoded can be provided");if(s&&(t||r))throw new Error("Only one of urlencoded, body can be provided")}};var Ie=new async_hooks.AsyncLocalStorage,Bt=i=>async(e,t,r)=>{let s={};for(let[o,n]of Object.entries(i))s[o]=n(e);Ie.run(s,()=>{e.ctx=new Proxy({},{get(o,n){return Ie.getStore()?.[n]},set(o,n,a){let c=Ie.getStore();return c?(c[n]=a,true):false},ownKeys(){let o=Ie.getStore();return o?Object.keys(o):[]},has(o,n){let a=Ie.getStore();return a?n in a:false}}),r();});};var it=class extends T{constructor(e,t,r){super(`FILE_TOO_LARGE: "${e}" is too large. Max size is ${r} bytes, but got ${t} bytes`);}};W();var Lt=class{async tmpdir(){switch(C.type){case "node":case "bun":return (await import('os')).tmpdir();case "deno":return Deno.makeTempDir();default:throw new Error("Unsupported runtime")}}},or=new Lt;var nt=i=>i.toLowerCase().replace(/[-_.]/g,"_").replace(/([A-Z])/g,"_$1").replace(/^_+/,"").replace(/_+$/,"").toLowerCase(),at=i=>i.split(/[-_.]/g).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),ir=i=>i.split(/[-_.]/g).map(e=>e.toLowerCase()).join("-");var fe=(i,e)=>{if(!i||typeof i!="string")return e;let t=i.toLowerCase().trim(),r=t.match(/^(\d+(?:\.\d+)?)kb$/),s=t.match(/^(\d+(?:\.\d+)?)mb$/);if(r){let o=Number.parseFloat(r[1]);return Number.isNaN(o)||o<0?e:Math.floor(o*1024)}if(s){let o=Number.parseFloat(s[1]);return Number.isNaN(o)||o<0?e:Math.floor(o*1024*1024)}return e};var nr=1024*1024,ar=10*1024*1024,pr=i=>async(e,t,r)=>{let s=[];try{let o=e.headers.get("content-type")??e.headers.get("Content-Type");if(!o||!o.startsWith("multipart/form-data")||e.body||e.bodyUsed)return r();let n=e.headers.get("content-length"),a=fe(i?.maxFileSize,ar)??ar;if(n&&parseInt(n)>a)return t.status(413).json({error:"Payload too large",message:`Total request size exceeds ${a} bytes`});let c=o.match(/boundary=(.*)(;|$)/i);if(!c)return r();let p=c[1].replace(/(^\s*"?|"?\s*$)/g,""),l=new Uint8Array(await e.toWebApi().arrayBuffer());if(l.length>a)return t.status(413).json({error:"Payload too large",message:`Total request size exceeds ${a} bytes`});let d=new TextEncoder().encode(`--${p}`),m=new Uint8Array([13,10,13,10]),y=[],h=(A,x,R=0)=>{e:for(let q=R;q<=A.length-x.length;q++){for(let k=0;k<x.length;k++)if(A[q+k]!==x[k])continue e;return q}return -1},g=h(l,d);for(;g!==-1&&(g+=d.length,!(l[g]===45&&l[g+1]===45));){l[g]===13&&l[g+1]===10&&(g+=2);let A=h(l,m,g);if(A===-1)break;let x=l.subarray(g,A),R=new TextDecoder().decode(x),q=A+m.length,k=h(l,d,q);if(k===-1)break;let L=k-1;l[L]===10&&L--,l[L]===13&&L--;let Zt=l.subarray(q,L+1);y.push({headers:R,data:Zt}),g=k;}let b=[],P={},j=fe(i?.maxFileSize,nr)??nr;for(let A of y){let x=A.headers.split(`\r
|
|
11
|
-
`).find(Xe=>Xe.toLowerCase().startsWith("content-disposition:"));if(!x)continue;let R=x.match(/name="([^"]+)"/);if(!R)continue;let q=R[1],k=x.match(/filename="([^"]*)"/),L=k?k[1]:"";if(!!L){if(i?.maxFiles&&b.length>=i.maxFiles)return t.badRequest({...B(new T(`Too many files: Maximum ${i.maxFiles} files allowed`))});if(j&&A.data.length>j)return t.badRequest({...B(new it(L,A.data.length,j))});let Xe=A.headers.split(`\r
|
|
12
|
-
`).find(ss=>ss.toLowerCase().startsWith("content-type:")),et=Xe?Xe.split(":")[1].trim():"application/octet-stream";if(i?.allowedMimeTypes&&!i.allowedMimeTypes.includes(et))return t.badRequest({...B(new T(`Invalid file type: "${et}" is not allowed. Allowed types: ${i.allowedMimeTypes.join(", ")}`))});let rs=gs(et),Ot=f.join(await or.tmpdir(),`${J.randomUUID()}${rs}`);await u.writeFile(Ot,A.data),s.push(Ot),b.push({formName:q,mimeType:et,size:A.data.length,tmpPath:Ot,originalName:L});}else P[q]=new TextDecoder().decode(A.data);}e.files=b,e.body=P,e.bodyUsed=!0,await r(),await cr(s);}catch(o){throw await cr(s),o}},cr=async i=>{await Promise.allSettled(i.map(e=>u.unlink(e)));};var gs=i=>({"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","application/pdf":".pdf","text/plain":".txt","application/json":".json","text/csv":".csv","application/octet-stream":".bin","application/x-www-form-urlencoded":".urlencoded","application/xml":".xml","application/yaml":".yaml","application/yml":".yml","application/csv":".csv","application/txt":".txt","application/markdown":".markdown"})[i.toLowerCase()]||".bin";var Ge=class extends T{constructor(e){super(`JSON_NOT_VALID: "${JSON.stringify(e)}" is not a valid JSON`);}};var lr=100*1024,dr=i=>async(e,t,r)=>{if(!fs(e)||!te(e.method)||e.bodyUsed)return r();let s=fe(i?.sizeLimit,lr)??lr,o=e.headers.get("content-length");if(o&&Number.parseInt(o)>s){let n={status:413,message:"ERR_REQUEST_BODY_TOO_LARGE",...i?.customErrorMessage};return t.status(n.status).json({error:n.message})}if(e.body||e.bodyUsed)return r();try{let n=e.toWebApi();e.body=await n.json(),e.bodyUsed=!0;}catch(n){return n instanceof SyntaxError?t.badRequest({...B(new Ge("Invalid JSON syntax"))}):t.badRequest({...B(new Ge("Invalid request body encoding"))})}await r();};function fs(i){let e=ys(i);return e?vs(e)==="application/json":false}function ys(i){let e=i.headers.get("content-type")??i.headers.get("Content-Type");return e?Array.isArray(e)?e[0]||null:e:null}function vs(i){let e=i.trim(),t=e.indexOf(";");return t===-1?e.toLowerCase():e.substring(0,t).trim().toLowerCase()}var ur=1024*1024,mr=i=>{let t={limit:fe(i?.limit,ur)??ur,extended:i?.extended??false,charset:i?.charset??"utf8",allowEmpty:i?.allowEmpty??true,parameterLimit:i?.parameterLimit??1e3};return async(r,s,o)=>{if(!(r.headers.get("content-type")||"").includes("application/x-www-form-urlencoded"))return o();let a=r.headers.get("content-length");if(a&&parseInt(a)>t.limit){s.status(413).json({error:"Payload too large",message:"Request body exceeds the size limit"});return}try{await ws(r,t),await o();}catch(c){if(c instanceof Error&&c.message.includes("limit")){s.status(413).json({error:"Payload too large",message:"Request body exceeds the size limit"});return}throw c}}};async function ws(i,e){if(i.body||i.bodyUsed)return;let r=await i.toWebApi().arrayBuffer();if(r.byteLength>e.limit)throw new Error(`Body size ${r.byteLength} exceeds limit ${e.limit}`);let o=new TextDecoder(e.charset).decode(r),n=bs(o,e);i.body=n,i.bodyUsed=true;}function bs(i,e){let t={},r=new URLSearchParams(i);if(r.size>e.parameterLimit)throw new Error(`Too many parameters: ${r.size} exceeds limit ${e.parameterLimit}`);for(let[s,o]of r.entries())!e.allowEmpty&&o===""||(e.extended?Ps(t,s,o):t[s]=o);return t}function Ps(i,e,t){let r=["__proto__","constructor","prototype"];if(r.includes(e))return;let s=e.match(/\[([^\]]*)\]/g);if(!s){r.includes(e)||(i[e]=t);return}let o=i,n=e.split("[")[0];if(r.includes(n))return;for(let c=0;c<s.length-1;c++){let p=s[c].slice(1,-1);if(r.includes(p))return;if(o[n]||(o[n]={}),p===""){Array.isArray(o[n])||(o[n]=[]),o=o[n];continue}o[n][p]||(o[n][p]={}),o=o[n][p];}let a=s[s.length-1].slice(1,-1);if(!r.includes(a)){if(a===""){Array.isArray(o)||(o=[]),o.push(t);return}o[a]=t;}}var Ss=i=>(i.headers.get("content-type")??i.headers.get("Content-Type"))?.split(";")[0]??null,hr=i=>{let e=i.json,t=i.urlencoded,r=i.fileParser;return async(s,o,n)=>{if(!te(s.method)||s.bodyUsed)return n();let a=Ss(s);if(a==="application/json"&&e)return dr(e)(s,o,n);if(a==="multipart/form-data"&&r)return pr(r)(s,o,n);if(a==="application/x-www-form-urlencoded"&&t)return mr(t)(s,o,n);if(a?.includes("text/")){let c=new TextDecoder,p=s.toWebApi();s.body=c.decode(await p.arrayBuffer()),s.bodyUsed=true;}return !s.body&&!s.bodyUsed&&(s.body=await s.toWebApi().arrayBuffer()),n()}};var Ts=1024,Rs=6,Os=[/text\/.+/,/application\/json/,/application\/javascript/,/application\/xml/,/application\/.*\+json/,/application\/.*\+xml/],gr=i=>{let e=i?.threshold??Ts,t=Math.max(0,Math.min(9,i?.level??Rs)),r=i?.filter??Os;return async(s,o,n)=>{if(!(s.headers.get("accept-encoding")||"").includes("gzip"))return n();let p=o.send.bind(o),l=o.json.bind(o),d=o.text.bind(o),m=(y,h)=>{if(!Cs(y,h,e,r))return y;let g=fr(y);if(!g||g.length<e)return y;let b=zlib.gzipSync(g,{level:t});return o.setHeader("Content-Encoding","gzip"),o.setHeader("Content-Length",b.length.toString()),b};o.send=function(y){let h=o.headers["content-type"],g=m(y,h);return p(g)},o.json=function(y){let h=JSON.stringify(y),g=m(h,"application/json");return g!==h?(o.setHeader("Content-Type","application/json"),p(g)):l(y)},o.text=function(y){let h=m(y,"text/plain");return h!==y?(o.setHeader("Content-Type","text/plain"),p(h)):d(y)},await n();}},Cs=(i,e,t,r)=>{if(!i||!e)return false;let s=fr(i);return !s||s.length<t?false:r.some(o=>o.test(e))},fr=i=>typeof i=="string"?Buffer.from(i,"utf-8"):Buffer.isBuffer(i)?i:i instanceof Uint8Array?Buffer.from(i):typeof i=="object"?Buffer.from(JSON.stringify(i),"utf-8"):null;var yr=i=>{let e={secret:i?.secret??"",defaults:{path:"/",httpOnly:true,secure:true,sameSite:"Lax",...i?.defaults},parse:i?.parse??true,sign:i?.sign??false};return async(t,r,s)=>{if(e.parse){let o=qs(t.headers.get("cookie")||"");t.cookies={};for(let[n,a]of Object.entries(o)){if(e.sign&&e.secret){let c=await Ms(a,e.secret);c!==false&&(t.cookies[n]=c);continue}t.cookies[n]=a;}}r.cookie=(o,n,a)=>{vr(r,o,n,{...e.defaults,...a},e);},r.clearCookie=(o,n)=>{Es(r,o,{...e.defaults,...n});},await s();}};function qs(i){let e={};if(!i)return e;let t=i.split(";");for(let r of t){let[s,o]=r.trim().split("=");s&&o&&(e[decodeURIComponent(s)]=decodeURIComponent(o));}return e}async function vr(i,e,t,r,s){let o=`${encodeURIComponent(e)}=${encodeURIComponent(t)}`;r.domain&&(o+=`; Domain=${r.domain}`),r.path&&(o+=`; Path=${r.path}`),r.expires&&(o+=`; Expires=${r.expires.toUTCString()}`),r.maxAge&&(o+=`; Max-Age=${r.maxAge}`),r.secure&&(o+="; Secure"),r.httpOnly&&(o+="; HttpOnly"),r.sameSite&&(o+=`; SameSite=${r.sameSite}`),r.priority&&(o+=`; Priority=${r.priority}`),s.sign&&s.secret&&(o=await js(o,s.secret));let n=i.headers["set-cookie"]||"",a=n?`${n}, ${o}`:o;i.setHeader("Set-Cookie",a);}function Es(i,e,t){let r={...t,expires:new Date(0),maxAge:0};vr(i,e,"",r,{secret:"",sign:false});}async function js(i,e){let t=new TextEncoder,r=t.encode(e),s=t.encode(i),o=await crypto.subtle.importKey("raw",r,{name:"HMAC",hash:"SHA-256"},false,["sign"]),n=await crypto.subtle.sign("HMAC",o,s),a=new Uint8Array(n),c=Array.from(a).map(p=>p.toString(16).padStart(2,"0")).join("");return `${i}.${c}`}async function Ms(i,e){let t=i.split(".");if(t.length!==2)return false;let[r,s]=t,o=new TextEncoder,n=o.encode(e),a=o.encode(r),c=await crypto.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},false,["sign"]),p=await crypto.subtle.sign("HMAC",c,a),l=new Uint8Array(p),d=Array.from(l).map(m=>m.toString(16).padStart(2,"0")).join("");return s===d?r:false}var wr=i=>{let e={origin:"*",methods:["GET","HEAD","PUT","PATCH","POST","DELETE"],allowedHeaders:"",exposedHeaders:"",credentials:false,maxAge:void 0,preflightContinue:false,optionsSuccessStatus:204,...i};return async(t,r,s)=>{let o=t.headers.get("origin")||"";if(t.method==="OPTIONS")return As(t,r,e,o,s);ks(t,r,e,o),await s();}};function As(i,e,t,r,s){let o=br(t,r);if(!o){e.forbidden("CORS origin not allowed");return}if(Pr(e,t,o),t.preflightContinue){s();return}e.status(t.optionsSuccessStatus||204),e.send("");}function ks(i,e,t,r){let s=br(t,r);s&&Pr(e,t,s);}function br(i,e){if(typeof i.origin=="string")return i.origin;if(Array.isArray(i.origin)){let t=i.origin.find(r=>typeof r=="string"?r===e:r instanceof RegExp&&r.test(e));return typeof t=="string"?t:false}return "*"}function Pr(i,e,t){if(i.setHeader("Access-Control-Allow-Origin",t),e.credentials&&i.setHeader("Access-Control-Allow-Credentials","true"),e.exposedHeaders&&e.exposedHeaders!==""){let s=Array.isArray(e.exposedHeaders)?e.exposedHeaders.join(","):e.exposedHeaders;i.setHeader("Access-Control-Expose-Headers",s);}if(e.allowedHeaders&&e.allowedHeaders!==""){let s=Array.isArray(e.allowedHeaders)?e.allowedHeaders.join(","):e.allowedHeaders;i.setHeader("Access-Control-Allow-Headers",s);}let r=Array.isArray(e.methods)?e.methods.join(","):e.methods;i.setHeader("Access-Control-Allow-Methods",String(r||"")),typeof e.maxAge=="number"&&i.setHeader("Access-Control-Max-Age",e.maxAge.toString());}function Sr(i,e=""){let t=new URL(i.url),r=Object.fromEntries(i.headers.entries());return {body:i.body,query:i.query,params:i.params,cookies:i.cookies,session:i.session,originalUrl:t.pathname+t.search,baseUrl:e,path:t.pathname.replace(e,"")||"/",method:i.method,ip:i.ip,headers:r,url:t.pathname,get(o){return i.headers.get(o.toLowerCase())??void 0},header(o){return i.headers.get(o.toLowerCase())??void 0},app:{},res:null,route:null,protocol:t.protocol.replace(":",""),secure:t.protocol==="https:",hostname:t.hostname,host:t.host,fresh:false,stale:true,xhr:r["x-requested-with"]?.toLowerCase()==="xmlhttprequest",accepts:()=>{},acceptsCharsets:()=>{},acceptsEncodings:()=>{},acceptsLanguages:()=>{},is:()=>null,range:()=>{},param:o=>i.params[o]??i.query[o],files:i.files,file:i.file,rawBody:i.body}}function xr(i){return {locals:{},headersSent:false,statusCode:i.responseStatus,status(t){return i.status(t),this.statusCode=t,this},sendStatus(t){return this.status(t).send(String(t)),this},send(t){if(this.headersSent=true,!!!i.headers["Content-Type"]&&typeof t=="string"){let s=t.trim();if(s.startsWith("<!DOCTYPE")||s.startsWith("<html")||s.startsWith("<HTML"))return i.html(t),this}return i.send(t),this},json(t){return this.headersSent=true,i.json(t),this},redirect(t,r){this.headersSent=true;let s=typeof t=="string"?t:r,o=typeof t=="number"?t:302;return i.status(o).setHeader("Location",s),i.send(""),this},setHeader(t,r){let s=Array.isArray(r)?r.join(", "):String(r);return i.setHeader(t,s),this},set(t,r){if(typeof t=="object")for(let[s,o]of Object.entries(t))i.setHeader(s,o);else r!==void 0&&i.setHeader(t,r);return this},header(t,r){return this.set(t,r)},type(t){return i.setHeader("Content-Type",t),this},contentType(t){return this.type(t)},end(t){return this.headersSent=true,i.send(t??""),this},write(t){return true},get(t){return i.headers[t]},getHeader(t){return i.headers[t]},removeHeader(t){return delete i.headers[t],this},append(t,r){let s=i.headers[t],o=Array.isArray(r)?r.join(", "):r;return i.setHeader(t,s?`${s}, ${o}`:o),this},cookie(t,r,s){return i.cookie?.(t,r,s),this},clearCookie(t,r){return i.clearCookie?.(t,r),this},render(t,r,s){throw new Error("render() is not supported in Express compatibility layer")},format(t){return this},attachment(t){return t?i.setHeader("Content-Disposition",`attachment; filename="${t}"`):i.setHeader("Content-Disposition","attachment"),this},sendFile(t,r,s){i.file(t);},download(t,r,s,o){let n=typeof r=="string"?r:t.split("/").pop();this.attachment(n),i.file(t);},links(t){let r=Object.entries(t).map(([s,o])=>`<${o}>; rel="${s}"`).join(", ");return i.setHeader("Link",r),this},location(t){return i.setHeader("Location",t),this},vary(t){return i.setHeader("Vary",t),this},app:{},req:null}}function _e(i,e=""){return async(t,r,s)=>{let o=Sr(t,e),n=xr(r);await new Promise((a,c)=>{let p=l=>{if(l){c(l);return}a();};try{let l=i(o,n,p);l instanceof Promise&&l.catch(c);}catch(l){c(l);}}),await s();}}function $s(i,e=""){return async(t,r)=>{let s=Sr(t,e),o=xr(r);await i(s,o,()=>{});}}function ct(i,e){let t=Qt(i),r=e.stack;if(!r){console.warn("Express router has no stack - routes may not be registered");return}for(let s of r)Tr(s,t);}function Tr(i,e){if(i.route){let t=Qt(e+i.route.path),r=Object.keys(i.route.methods).filter(s=>i.route.methods[s]);for(let s of r){let o=i.route.stack.map(n=>n.handle);Bs(s.toUpperCase(),t,o,e);}return}if(i.handle&&typeof i.handle=="function"){let t=i.path||"",r=Qt(e+t),s=i.handle.stack;if(s&&Array.isArray(s)){for(let c of s)Tr(c,r);return}let o=r==="/"?"/*":`${r}/*`,n=_e(i.handle,e),a=["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"];for(let c of a)M.addOrUpdate(c,o,[n],async()=>{},{excludeFromSwagger:true});}}function Bs(i,e,t,r){let s=t.slice(0,-1).map(a=>_e(a,r)),o=t[t.length-1],n=$s(o,r);M.addOrUpdate(i,e,s,n,{excludeFromSwagger:true});}function Qt(i){let e=i.replace(/\/+/g,"/");return e.startsWith("/")||(e="/"+e),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e}function Rr(i){return {use(e,t){if(typeof e=="string"){let o=e,n=t,a=n.stack;if(a&&Array.isArray(a)){ct(o,n);return}i.use(_e(n,o));return}let r=e,s=r.stack;if(s&&Array.isArray(s)){ct("/",r);return}i.use(_e(r));}}}var Or=i=>{let e={dnsPrefetchControl:true,frameguard:{action:"SAMEORIGIN"},hsts:{maxAge:15552e3,includeSubDomains:true,preload:false},contentTypeOptions:true,ieNoOpen:true,xssFilter:true,referrerPolicy:"no-referrer",crossOriginResourcePolicy:"same-origin",crossOriginOpenerPolicy:"same-origin",crossOriginEmbedderPolicy:"require-corp",contentSecurityPolicy:false,...i};return async(t,r,s)=>{if(e.dnsPrefetchControl&&r.setHeader("X-DNS-Prefetch-Control","off"),e.frameguard){let o="SAMEORIGIN";typeof e.frameguard=="object"&&(o=e.frameguard.action),r.setHeader("X-Frame-Options",o);}if(e.hsts){let o={};typeof e.hsts=="object"&&(o=e.hsts);let n=o.maxAge!==void 0?o.maxAge:15552e3,a=o.includeSubDomains!==void 0?o.includeSubDomains:true,c=o.preload!==void 0?o.preload:false,p=`max-age=${n}`;a!==false&&(p+="; includeSubDomains"),c&&(p+="; preload"),r.setHeader("Strict-Transport-Security",p);}e.contentTypeOptions&&r.setHeader("X-Content-Type-Options","nosniff"),e.ieNoOpen&&r.setHeader("X-Download-Options","noopen"),e.xssFilter&&r.setHeader("X-XSS-Protection","0"),e.referrerPolicy&&r.setHeader("Referrer-Policy",e.referrerPolicy),e.crossOriginResourcePolicy&&r.setHeader("Cross-Origin-Resource-Policy",e.crossOriginResourcePolicy),e.crossOriginOpenerPolicy&&r.setHeader("Cross-Origin-Opener-Policy",e.crossOriginOpenerPolicy),e.crossOriginEmbedderPolicy&&r.setHeader("Cross-Origin-Embedder-Policy",e.crossOriginEmbedderPolicy),e.contentSecurityPolicy&&r.setHeader("Content-Security-Policy",e.contentSecurityPolicy),await s();}};var qr=i=>async(e,t,r)=>{try{let s=e.body;(i?.logRequest??!0)&&exports.logger.info({type:"request",requestId:e.id,method:i?.requestPayload?.method??!0?e.method:void 0,url:i?.requestPayload?.url??!0?e.url:void 0,ip:i?.requestPayload?.ip??!0?e.ip:void 0,headers:i?.requestPayload?.headers??!0?e.headers:void 0,body:i?.requestPayload?.body??!1?Cr(s):void 0});let o=performance.now();await r();let a=performance.now()-o;(i?.logResponse??!0)&&exports.logger.info({type:"response",requestId:e.id,status:i?.responsePayload?.status??t.responseStatus,duration:`${a.toFixed(2)}ms`,body:i?.responsePayload?.body??!1?Cr(t.getBody()):void 0,headers:i?.responsePayload?.headers??!1?t.headers:void 0});}catch(s){throw exports.logger.error(s),s}};function Cr(i){if(typeof i=="string"||i&&typeof i=="object"&&i.constructor===Object)return i}var Ls=["POST"],Qs="X-HTTP-Method-Override",Is=["GET","POST","PUT","PATCH","DELETE"],Er=i=>{let e=(i?.methods??Ls).map(r=>r.toUpperCase()),t=i?.header??Qs;return async(r,s,o)=>{let n=r.method.toUpperCase();if(!e.includes(n))return o();let a=r.headers.get(t);if(!a)return o();let c=a.toUpperCase();if(!Is.includes(c))return o();r.method=c,await o();}};var pt=class{storage=new Map;timers=new Map;windowMs;constructor(e){this.windowMs=e;}async set(e,t){let r=this.timers.get(e);r&&clearTimeout(r),this.storage.set(e,t);let s=setTimeout(()=>{this.storage.delete(e),this.timers.delete(e);},this.windowMs);this.timers.set(e,s);}async get(e){let t=this.storage.get(e);return t||0}async delete(e){let t=this.timers.get(e);t&&clearTimeout(t),this.storage.delete(e),this.timers.delete(e);}};var jr=(i,e)=>{let t={type:"ip",limit:100,message:"ERR_RATE_LIMIT_EXCEEDED",statusCode:429,...i},r={type:"memory",...e};r.type==="memory"&&!r.windowMs&&(r.windowMs=6e4);let s=r.type==="memory"?new pt(r.windowMs):{get:r.get,set:r.set};return async(o,n,a)=>{let c=t.type==="ip"?o.ip:t.key(o),p=await s.get(c);return p>=t.limit?n.status(t.statusCode).json({message:t.message}):(await s.set(c,p+1),a())}};var lt=class{store=new Map;async get(e){let t=this.store.get(e);if(t){if(t.exp&&Date.now()>t.exp){this.store.delete(e);return}return t.value}}async set(e,t,r){let s=r?Date.now()+r*1e3:void 0;this.store.set(e,{value:t,exp:s});}async destroy(e){this.store.delete(e);}};var Mr=i=>{let e=i?.name??"sid",t=i?.ttl??3600*24,r=i?.store??new lt,s={path:"/",httpOnly:true,secure:false,sameSite:"Lax",...i?.cookie??{}};return async(o,n,a)=>{let p=o.cookies&&o.cookies[e],l=p?await r.get(p):void 0;(!p||!l)&&(p||=J.randomUUID(),l||={},await r.set(p,l,t),n.cookie?.(e,p,s)),o.session=l,o.saveSession=async()=>r.set(p,l,t),o.destroySession=async()=>{await r.destroy(p),n.clearCookie?.(e,s);},await a(),await r.set(p,l,t);}};var kr=i=>{let e={type:"standard",path:"/docs",title:"Balda API Documentation",description:"API Documentation from the Balda Framework",version:"1.0.0",servers:["http://localhost"],security:[],tags:[],components:{},securitySchemes:{},models:{}};i&&typeof i!="boolean"&&(e={...e,...i});let t=_s(e),r=`${e.path}`,s=`${r}/json`,o;e.type==="rapidoc"?o=Ns(s,e):e.type==="scalar"?o=Hs(s,e):e.type==="elements"?o=Ds(s,e):e.type==="custom"?o=e.customUIGenerator(s,e):o=Fs(s,e),M.addOrUpdate("GET",r,[],(n,a)=>{a.html(o);}),M.addOrUpdate("GET",s,[],(n,a)=>{a.json(t);});},ue=i=>i?i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):"";function ye(i){return !i||typeof i!="object"?{type:"string"}:i}function _s(i){let e=M.getRoutes(),t={},r;if(i.models)if(Array.isArray(i.models))r=i.models.reduce((o,n,a)=>{let c=ye(n),p=c.$id||c.title||`Model${a}`;return o[p]=c,o},{});else {r={};for(let[o,n]of Object.entries(i.models))r[o]=ye(n);}let s={...i.components,securitySchemes:i.securitySchemes||{},schemas:r?{...i.components?.schemas||{},...r}:i.components?.schemas?{...i.components.schemas}:void 0};for(let o of e){let n=o.swaggerOptions;if(n?.excludeFromSwagger)continue;t[o.path]||(t[o.path]={});let a=o.method.toLowerCase(),c={summary:n?.name||`${a.toUpperCase()} ${o.path}`,description:n?.description||"",tags:n?.service?[n.service]:[],deprecated:n?.deprecated||false},p=[];if(n?.query&&n.query.type==="object"&&n.query.shape)for(let[l,d]of Object.entries(n.query.shape))!d||typeof d!="object"||p.push({name:l,in:"query",required:Array.isArray(n.query.shape[l].required)?n.query.shape[l].required.includes(l):false,schema:ye(d)});if(n&&n.params?p=p.concat(Ar(o.path,n.params)):p=p.concat(Ar(o.path)),p.length>0&&(c.parameters=p),n?.requestBody){let l="application/json";n.bodyType==="form-data"?l="multipart/form-data":n.bodyType==="urlencoded"&&(l="application/x-www-form-urlencoded"),c.requestBody={content:{[l]:{schema:ye(n.requestBody)}},required:true};}else n?.bodyType&&(n.bodyType.includes("form-data")||n.bodyType.includes("urlencoded"))&&(c.requestBody={content:{[n.bodyType]:{schema:{type:"object"}}},required:true});if(c.responses={},n?.responses)for(let[l,d]of Object.entries(n.responses))c.responses[l]={description:`Response for ${l}`,content:{"application/json":{schema:ye(d)}}};if(n?.errors)for(let[l,d]of Object.entries(n.errors))c.responses[l]={description:`Error response for ${l}`,content:{"application/json":{schema:ye(d)}}};if(Object.keys(c.responses).length===0&&(c.responses[200]={description:"Successful response",content:{"application/json":{schema:{type:"object"}}}}),n?.security){let l=[];Array.isArray(n.security)||(n.security=[n.security]);for(let d of n.security)if(d.type==="bearer")s.securitySchemes.bearer||(s.securitySchemes.bearer={type:"http",scheme:"bearer",bearerFormat:d.bearerFormat||"JWT",description:d.description}),l.push({bearer:[]});else if(d.type==="apiKey")s.securitySchemes[d.name]||(s.securitySchemes[d.name]={type:"apiKey",name:d.name,in:d.in,description:d.description}),l.push({[d.name]:[]});else if(d.type==="oauth2"){let m=d.name||"oauth2";s.securitySchemes[m]||(s.securitySchemes[m]={type:"oauth2",flows:d.flows,description:d.description}),l.push({[m]:[]});}else if(d.type==="openIdConnect"){let m=d.name||"openIdConnect";s.securitySchemes[m]||(s.securitySchemes[m]={type:"openIdConnect",openIdConnectUrl:d.openIdConnectUrl,description:d.description}),l.push({[m]:[]});}l.length&&(c.security=l);}else i.security&&(c.security=i.security);t[o.path][a]=c;}return {openapi:"3.0.0",info:{title:i.title,description:i.description,version:i.version,...i.info},servers:i.servers?.map(o=>({url:o}))||[{url:"/"}],paths:t,components:s,security:i.security||[],tags:i.tags?Object.entries(i.tags).map(([o,n])=>({name:o,...n})):[]}}function Fs(i,e){return `
|
|
13
|
-
<!DOCTYPE html>
|
|
14
|
-
<html lang="en">
|
|
15
|
-
<head>
|
|
16
|
-
<meta charset="utf-8" />
|
|
17
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
18
|
-
<meta name="description" content="${ue(e.description)}" />
|
|
19
|
-
<title>${ue(e.title)}</title>
|
|
20
|
-
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css" />
|
|
21
|
-
<style>
|
|
22
|
-
html {
|
|
23
|
-
box-sizing: border-box;
|
|
24
|
-
overflow: -moz-scrollbars-vertical;
|
|
25
|
-
overflow-y: scroll;
|
|
26
|
-
}
|
|
27
|
-
*, *:before, *:after {
|
|
28
|
-
box-sizing: inherit;
|
|
29
|
-
}
|
|
30
|
-
body {
|
|
31
|
-
margin:0;
|
|
32
|
-
background: #fafafa;
|
|
33
|
-
}
|
|
34
|
-
</style>
|
|
35
|
-
</head>
|
|
36
|
-
<body>
|
|
37
|
-
<div id="swagger-ui"></div>
|
|
38
|
-
<script src="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js"></script>
|
|
39
|
-
<script src="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-standalone-preset.js"></script>
|
|
40
|
-
<script>
|
|
41
|
-
window.onload = function() {
|
|
42
|
-
const ui = SwaggerUIBundle({
|
|
43
|
-
url: '${i}',
|
|
44
|
-
dom_id: '#swagger-ui',
|
|
45
|
-
deepLinking: true,
|
|
46
|
-
presets: [
|
|
47
|
-
SwaggerUIBundle.presets.apis,
|
|
48
|
-
SwaggerUIStandalonePreset
|
|
49
|
-
],
|
|
50
|
-
plugins: [
|
|
51
|
-
SwaggerUIBundle.plugins.DownloadUrl
|
|
52
|
-
],
|
|
53
|
-
layout: "StandaloneLayout",
|
|
54
|
-
validatorUrl: null,
|
|
55
|
-
oauth2RedirectUrl: window.location.origin + '/swagger-ui/oauth2-redirect.html'
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
</script>
|
|
59
|
-
</body>
|
|
60
|
-
</html>`}function Ns(i,e){return `
|
|
61
|
-
<!DOCTYPE html>
|
|
62
|
-
<html>
|
|
63
|
-
<head>
|
|
64
|
-
<title>${ue(e.title)}</title>
|
|
65
|
-
<meta charset="utf-8"/>
|
|
66
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
67
|
-
<meta name="description" content="${ue(e.description)}" />
|
|
68
|
-
<link rel="icon" type="image/png" href="https://mrin9.github.io/RapiDoc/images/favicon.png">
|
|
69
|
-
<style>
|
|
70
|
-
body { margin: 0; padding: 0; }
|
|
71
|
-
</style>
|
|
72
|
-
</head>
|
|
73
|
-
<body>
|
|
74
|
-
<rapi-doc
|
|
75
|
-
spec-url="${i}"
|
|
76
|
-
render-style="read"
|
|
77
|
-
layout="column"
|
|
78
|
-
show-header="true"
|
|
79
|
-
allow-server-selection="true"
|
|
80
|
-
allow-authentication="true"
|
|
81
|
-
allow-server-variables="true"
|
|
82
|
-
theme="light"
|
|
83
|
-
primary-color="#009688"
|
|
84
|
-
regular-font="Open Sans, sans-serif"
|
|
85
|
-
mono-font="Fira Mono, monospace"
|
|
86
|
-
>
|
|
87
|
-
</rapi-doc>
|
|
88
|
-
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
|
|
89
|
-
</body>
|
|
90
|
-
</html>
|
|
91
|
-
`}function Hs(i,e){return `
|
|
92
|
-
<!DOCTYPE html>
|
|
93
|
-
<html lang="en">
|
|
94
|
-
<head>
|
|
95
|
-
<meta charset="utf-8" />
|
|
96
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
97
|
-
<meta name="description" content="${ue(e.description)}" />
|
|
98
|
-
<title>${ue(e.title)}</title>
|
|
99
|
-
<style>
|
|
100
|
-
body {
|
|
101
|
-
margin: 0;
|
|
102
|
-
padding: 0;
|
|
103
|
-
}
|
|
104
|
-
</style>
|
|
105
|
-
</head>
|
|
106
|
-
<body>
|
|
107
|
-
<script
|
|
108
|
-
id="api-reference"
|
|
109
|
-
type="application/json"
|
|
110
|
-
data-configuration='{"spec":{"url":"${i}"},"theme":"default"}'
|
|
111
|
-
></script>
|
|
112
|
-
<script src="https://unpkg.com/@scalar/api-reference@latest/dist/browser/standalone.js"></script>
|
|
113
|
-
</body>
|
|
114
|
-
</html>
|
|
115
|
-
`}function Ds(i,e){return `
|
|
116
|
-
<!DOCTYPE html>
|
|
117
|
-
<html lang="en">
|
|
118
|
-
<head>
|
|
119
|
-
<meta charset="utf-8" />
|
|
120
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
121
|
-
<meta name="description" content="${ue(e.description)}" />
|
|
122
|
-
<title>${ue(e.title)}</title>
|
|
123
|
-
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements@7.7.9/styles.min.css">
|
|
124
|
-
<style>
|
|
125
|
-
body {
|
|
126
|
-
margin: 0;
|
|
127
|
-
padding: 0;
|
|
128
|
-
height: 100vh;
|
|
129
|
-
overflow: hidden;
|
|
130
|
-
}
|
|
131
|
-
</style>
|
|
132
|
-
</head>
|
|
133
|
-
<body>
|
|
134
|
-
<elements-api
|
|
135
|
-
apiDescriptionUrl="${i}"
|
|
136
|
-
router="hash"
|
|
137
|
-
layout="sidebar"
|
|
138
|
-
/>
|
|
139
|
-
<script src="https://unpkg.com/@stoplight/elements@7.7.9/web-components.min.js"></script>
|
|
140
|
-
</body>
|
|
141
|
-
</html>
|
|
142
|
-
`}function Ar(i,e){let t=[],r=/:([a-zA-Z0-9_]+)/g,s;for(;(s=r.exec(i))!==null;){let o=s[1],n={type:"string"};e&&e.shape&&e.shape[o]&&(n=ye(e.shape[o])||{type:"string"}),t.push({name:o,in:"path",required:true,schema:n});}return t}var $r=i=>async(e,t,r)=>{e.timeout=false;let s=setTimeout(()=>{e.timeout=true;},i.ms);try{await r();}finally{clearTimeout(s);}};var Br=i=>{let e=i?.header??"x-forwarded-for",t=i?.trust??true,r=i?.hop??"first";return async(s,o,n)=>{if(!t)return n();let a=s.headers.get(e);if(a&&typeof a=="string"){let c=a.split(",").map(p=>p.trim()).filter(Boolean);c.length&&(s.ip=r==="first"?c[0]:c[c.length-1]);}return n()}};var It=class{ITERATIONS=6e5;SALT_LENGTH=16;KEY_LENGTH=256;configure(e){if(e.iterations!==void 0){if(e.iterations<1)throw new Error("Iterations must be at least 1");this.ITERATIONS=e.iterations;}if(e.saltLength!==void 0){if(e.saltLength<8)throw new Error("Salt length must be at least 8 bytes");this.SALT_LENGTH=e.saltLength;}if(e.keyLength!==void 0){if(e.keyLength<128)throw new Error("Key length must be at least 128 bits");this.KEY_LENGTH=e.keyLength;}}async hash(e){if(!e)throw new Error("Data to hash cannot be empty");let r=new TextEncoder().encode(e),s=crypto.getRandomValues(new Uint8Array(this.SALT_LENGTH)),o=await crypto.subtle.importKey("raw",r,{name:"PBKDF2"},false,["deriveBits"]),n=await crypto.subtle.deriveBits({name:"PBKDF2",salt:s,iterations:this.ITERATIONS,hash:"SHA-256"},o,this.KEY_LENGTH),a=this.encodeBase64(s),c=this.encodeBase64(new Uint8Array(n));return `${a}:${c}`}async compare(e,t){if(!e||!t)return false;try{let s=new TextEncoder().encode(t),o=e.split(":");if(o.length!==2)throw new Error("Invalid hash format");let[n,a]=o,c=this.decodeBase64(n),p=this.decodeBase64(a),l=await crypto.subtle.importKey("raw",s,{name:"PBKDF2"},!1,["deriveBits"]),d=await crypto.subtle.deriveBits({name:"PBKDF2",salt:c,iterations:this.ITERATIONS,hash:"SHA-256"},l,this.KEY_LENGTH),m=new Uint8Array(d);if(m.length!==p.length)return !1;let y=0;for(let h=0;h<m.length;h++)y|=m[h]^p[h];return y===0}catch{return false}}encodeBase64(e){let t="",r=e.byteLength;for(let s=0;s<r;s++)t+=String.fromCharCode(e[s]);return btoa(t)}decodeBase64(e){let t=atob(e),r=t.length,s=new Uint8Array(r);for(let o=0;o<r;o++)s[o]=t.charCodeAt(o);return s}},ze=new It;var dt=class{port;hostname;host;routes;tapOptions;graphql;ensureGraphQLHandler;constructor(e){this.routes=e?.routes??[],this.port=e?.port??80,this.hostname=e?.host??"0.0.0.0",this.host=e?.host??"0.0.0.0",this.url=`http://${this.host}:${this.port}`,this.tapOptions=e?.tapOptions,this.graphql=e?.graphql??new ee,this.ensureGraphQLHandler=de(this.graphql);}listen(){let e=this.tapOptions?.bun,{fetch:t,websocket:r,...s}=e??{},o=this.graphql.isEnabled,n="/graphql";this.runtimeServer=Bun.serve({port:this.port,hostname:this.hostname,fetch:async(a,c)=>{let p=a.url,l=p.indexOf("://")+3,d=p.indexOf("/",l),m=d===-1?"/":p.slice(d),y=m.indexOf("?"),h=y===-1?m:m.slice(0,y),g=y===-1?"":m.slice(y+1),b=M.find(a.method,h),P=Z.fromRequest(a);P.params=b?.params??{},P.setQueryString(g);let j=a.headers.get("x-forwarded-for");if(P.ip=j?j.split(",")[0].trim():c.requestIP(a)?.address,await t?.call(this,P,c),o&&h.startsWith(n)){let R=await this.ensureGraphQLHandler();if(R){let q=P.toWebApi();return tt(R.server,q,a.method,g,{req:P,server:c})}}if(r&&P.headers.get("upgrade")==="websocket"){let R=P.toWebApi();if(c.upgrade(R,{data:{}}))return}let A=new _;return await le(b?.middleware??[],b?.handler??((R,q)=>{q.notFound({...B(new D(R.url,R.method))});}),P,A),_.toWebResponse(A)},...r?{websocket:r}:{},...s}),this.url=this.runtimeServer.url.toString();}async close(){this.runtimeServer&&await this.runtimeServer.stop();}};var ut=class{graphql;ensureGraphQLHandler;constructor(e){this.routes=e?.routes??[],this.port=e?.port??80,this.hostname=e?.host??"0.0.0.0",this.host=e?.host??"0.0.0.0",this.url=`http://${this.host}:${this.port}`,this.tapOptions=e?.tapOptions,this.graphql=e?.graphql??new ee,this.ensureGraphQLHandler=de(this.graphql);}listen(){let e=this.tapOptions?.deno,{handler:t,...r}=e??{},s=this.graphql.isEnabled,o="/graphql";this.runtimeServer=Deno.serve({port:this.port,hostname:this.hostname,handler:async(n,a)=>{let c=n.url,p=c.indexOf("://")+3,l=c.indexOf("/",p),d=l===-1?"/":c.slice(l),m=d.indexOf("?"),y=m===-1?d:d.slice(0,m),h=m===-1?"":d.slice(m+1),g=M.find(n.method,y),b=Z.fromRequest(n);b.params=g?.params??{},b.setQueryString(h);let P=n.headers.get("x-forwarded-for");if(b.ip=P?P.split(",")[0].trim():a.remoteAddr?.hostname,await t?.(n,a))return new globalThis.Response(null,{status:426});if(s&&y.startsWith(o)){let R=await this.ensureGraphQLHandler();if(R){let q=b.toWebApi();return tt(R.server,q,n.method,h,{req:b,info:a})}}if(b.headers.get("upgrade")==="websocket"&&this.tapOptions?.deno?.websocket){let R=b.toWebApi(),{socket:q,response:k}=Deno.upgradeWebSocket(R);return this.tapOptions?.deno?.websocket?.open&&(q.onopen=()=>this.tapOptions?.deno?.websocket?.open?.(q)),this.tapOptions?.deno?.websocket?.message&&(q.onmessage=L=>{this.tapOptions?.deno?.websocket?.message?.(q,L.data);}),this.tapOptions?.deno?.websocket?.close&&(q.onclose=()=>this.tapOptions?.deno?.websocket?.close?.(q)),k}let A=new _;return await le(g?.middleware??[],g?.handler??((R,q)=>{q.notFound({...B(new D(R.url,R.method))});}),b,A),_.toWebResponse(A)},...r}),this.url=`http://${this.host}:${this.port}`;}async close(){this.runtimeServer&&await this.runtimeServer.shutdown();}};var Js=async(i,e)=>{let t=stream.Readable.fromWeb(i);return promises.pipeline(t,e)},mt=class{port;host;url;routes;tapOptions;runtimeServer;nodeHttpClient;httpsOptions;graphql;ensureGraphQLHandler;needsHeaderFiltering;constructor(e){this.routes=e?.routes??[],this.port=e?.port??80,this.host=e?.host??"0.0.0.0",this.tapOptions=e?.tapOptions,this.nodeHttpClient=e?.nodeHttpClient??"http",this.httpsOptions=e?.nodeHttpClient==="https"||e?.nodeHttpClient==="http2-secure"?e?.httpsOptions:void 0,this.graphql=e?.graphql??new ee,this.ensureGraphQLHandler=de(this.graphql);let t=this.nodeHttpClient==="https"||this.nodeHttpClient==="http2-secure"?"https":"http";this.url=`${t}://${this.host}:${this.port}`,this.needsHeaderFiltering=this.nodeHttpClient==="http2"||this.nodeHttpClient==="http2-secure";let r=this.graphql.isEnabled,s="/graphql";this.runtimeServer=this.createServer(async(o,n)=>{if(this.tapOptions&&this.tapOptions.node){let P=this.tapOptions.node;await P?.(o);}let a=o.url,c=a.indexOf("?"),p=c===-1?a:a.slice(0,c),l=c===-1?"":a.slice(c+1);if(r&&p.startsWith(s)){let P=await this.ensureGraphQLHandler();if(P){let j=te(o.method)?await this.readRequestBody(o):"";await tr(P.server,o.headers,o.method??"POST",j,l,{req:o},async(A,x,R)=>{for(let[q,k]of A)n.setHeader(q,k);if(n.statusCode=x,typeof R=="string")n.end(R);else {for await(let q of R)n.write(q);n.end();}});return}}let d=M.find(o.method,p),m=this.processHeaders(o.headers),y=new Z;y.url=`${this.url}${a}`,y.method=o.method,y.body=te(o.method)?await this.readRequestBody(o):void 0,y.headers=new Headers(m),y.ip=this.extractClientIp(o),y.setQueryString(l),y.params=d?.params??{};let h=new _;h.nodeResponse=n;let g=await le(d?.middleware??[],d?.handler??((P,j)=>{j.notFound({...B(new D(P.url,P.method))});}),y,h);if(n.headersSent||n.writableEnded)return;let b=g.getBody();if(b instanceof ReadableStream){n.writeHead(g.responseStatus,g.headers),Js(b,n);return}n.writeHead(g.responseStatus,g.headers),b instanceof Buffer||b instanceof Uint8Array||typeof b=="string"?n.end(b):g.headers["Content-Type"]==="application/json"?n.end(JSON.stringify(b)):n.end(b!=null?String(b):void 0);});}listen(){this.runtimeServer.listen(this.port,this.host);}async close(){return new Promise((e,t)=>{this.runtimeServer.close(r=>{r&&"code"in r&&r.code!=="ERR_SERVER_NOT_RUNNING"?t(r):e();});})}processHeaders(e){let t={};if(this.needsHeaderFiltering){for(let s in e){if(s.charCodeAt(0)===58)continue;let o=e[s];o!==void 0&&(t[s]=Array.isArray(o)?o.join(", "):o);}return t}for(let r in e){let s=e[r];s!==void 0&&(t[r]=Array.isArray(s)?s.join(", "):s);}return t}extractClientIp(e){let t=e.headers["x-forwarded-for"];return t?Array.isArray(t)?t[0].trim():t.split(",")[0].trim():e.socket.remoteAddress}async readRequestBody(e){return new Promise((t,r)=>{let s=[];e.on("data",o=>s.push(Buffer.from(o))),e.on("error",r),e.on("end",()=>t(Buffer.concat(s).toString()));})}createServer(e){if(this.nodeHttpClient==="http")return http.createServer(e);if(this.nodeHttpClient==="http2")return http2.createServer(e);if(this.nodeHttpClient==="http2-secure"){if(!this.httpsOptions)throw new Error("httpsOptions (key, cert) are required when using http2-secure client");return http2.createSecureServer(this.httpsOptions,e)}if(!this.httpsOptions)throw new Error("httpsOptions (key, cert) are required when using https client");return https.createServer(this.httpsOptions,e)}};var ht=class{routes;server;constructor(e){this.server=this.getRuntimeServer(e),this.routes=this.server.routes;}get url(){return this.server.url}get port(){return this.server.port}get host(){return this.server.host}getServer(e){return this.server.runtimeServer}listen(){return this.server.listen()}async close(){return this.server.close()}getRuntimeServer(e){if(e?.runtime==="bun")return new dt(e);if(e?.runtime==="node")return new mt(e);if(e?.runtime==="deno")return new ut(e);throw new Error("No server implementation found for runtime: "+e?.runtime)}};W();var Lr=["isListening","url","port","host","routes","embed","constructor","get","post","put","patch","delete","getNodeServer","getBunServer","getDenoServer","use","setErrorHandler","listen","close","tapOptions","startUpOptions","tmpDir","logger","getMockServer","useExpress","expressMiddleware","mountExpressRouter","setNotFoundHandler","setGlobalCronErrorHandler","startRegisteredCrons","bootstrap","handleNotFound","registerNotFoundRoutes","importControllers","applyPlugins"];var gt=class{_brand="BaldaServer";serverOptions;router=M;#s=new ke;isListening;isProduction;graphql;#t;#e;#r=[];#o=["node_modules"];#i;#n;constructor(e){this.#t=false,this.serverOptions={nodeHttpClient:e?.nodeHttpClient??"http",port:e?.port??Number(this.#s.get("PORT"))??80,host:e?.host??this.#s.get("HOST")??"0.0.0.0",controllerPatterns:e?.controllerPatterns??[],plugins:e?.plugins??{},tapOptions:e?.tapOptions??{},swagger:e?.swagger??true,graphql:e?.graphql??void 0,abortSignal:e?.abortSignal},e?.ajvInstance&&H.setGlobalInstance(e.ajvInstance),this.#n=e?.nodeHttpClient==="https"||e?.nodeHttpClient==="http2-secure"?e.httpsOptions:void 0,this.isListening=false,this.isProduction=this.#s.get("NODE_ENV")==="production",this.graphql=new ee(this.serverOptions.graphql),this.#e=new ht({routes:[],port:this.serverOptions.port,host:this.serverOptions.host,tapOptions:this.serverOptions.tapOptions,runtime:C.type,nodeHttpClient:this.serverOptions.nodeHttpClient,httpsOptions:this.#n,graphql:this.graphql}),this.setupAbortSignalHandler();}get url(){return this.#e.url}get port(){return this.#e.port}get host(){return this.#e.host}get routes(){return M.getRoutes()||[]}async hash(e){return ze.hash(e)}async compareHash(e,t){return ze.compare(e,t)}getEnvironment(){return this.#s.getEnvironment()}tmpDir(...e){return f.join("tmp",...e)}async mkdir(e,t){await u.mkdir(e,t);}get(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("GET",e,s,o,n);}post(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("POST",e,s,o,n);}patch(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("PATCH",e,s,o,n);}put(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("PUT",e,s,o,n);}delete(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("DELETE",e,s,o,n);}options(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("OPTIONS",e,s,o,n);}head(e,t,r){let{middlewares:s,handler:o,swaggerOptions:n}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);M.addOrUpdate("HEAD",e,s,o,n);}group(e,t,r){this.router.group(e,t,r);}getNodeServer(){if(C.type!=="node")throw new Error("Server is not using node runtime, you can't call `.getNodeServer()`");return this.#e.getServer("node")}getBunServer(){if(C.type!=="bun")throw new Error("Server is not using bun runtime, you can't call `.getBunServer()`");return this.#e.getServer("bun")}getDenoServer(){if(C.type!=="deno")throw new Error("Server is not using deno runtime, you can't call `.getDenoServer()`");return this.#e.getServer("deno")}embed(e,t){if(typeof e!="string"||e.trim()==="")throw new Error(`Invalid key provided to embed: ${e}. Key must be a non-empty string.`);if(Lr.includes(e))throw new Error(`Cannot embed value with key '${e}' as it conflicts with a protected server property.`);Object.defineProperty(this,e,{value:t,writable:false,configurable:true,enumerable:true});}exit(e=0){switch(C.type){case "bun":case "node":process.exit(e);case "deno":Deno.exit(e);default:throw new Error(`Unsupported runtime: ${C.type}`)}}on(e,t){switch(C.type){case "bun":case "node":process.on(e,t);break;case "deno":Deno.addSignalListener(e,t);break;default:throw new Error(`Unsupported runtime: ${C.type}, only node, bun and deno are supported`)}}once(e,t){switch(C.type){case "bun":case "node":process.once(e,t);break;case "deno":Deno.addSignalListener(e,t);break;default:throw new Error(`Unsupported runtime: ${C.type}, only node, bun and deno are supported`)}}use(...e){this.#r.push(...e);}useExpress(e,t){Rr(this).use(e,t);}expressMiddleware(e){return _e(e)}mountExpressRouter(e,t){ct(e,t);}setErrorHandler(e){this.#r.unshift(async(t,r,s)=>{try{await s();}catch(o){await e?.(t,r,s,o);}});}setNotFoundHandler(e){this.#i=e?.bind(this);}listen(e){if(this.isListening)throw new Error("Server is already listening, you can't call `.listen()` multiple times");this.bootstrap().then(()=>{this.#e.listen(),this.isListening=true,this.serverOptions.swagger&&kr(this.serverOptions.swagger),e?.({port:this.port,host:this.host,url:this.url});});}async waitUntilListening(){return new Promise((e,t)=>{try{this.listen(()=>{e();});}catch(r){t(r);}})}async close(){await this.disconnect();}async disconnect(){if(!this.isListening){exports.logger.warn("Trying to disconnect the server that is not listening, ignoring");return}try{await this.#e.close();}catch(e){throw exports.logger.error({error:e},"Error closing server connector"),e}finally{this.isListening=false;}}configureHash(e){ze.configure(e);}async getMockServer(e){return await this.bootstrap(e),new ot(this)}async importControllers(e){let t=e??this.serverOptions.controllerPatterns;if(!(!t||t.length===0))try{let{glob:r}=await import('glob'),s=await Promise.all(t.map(async o=>r(o,{absolute:!0,cwd:I.getCwd()}))).then(o=>o.flat());s=s.flat(),s=s.filter(o=>!this.#o.some(n=>o.includes(n))),exports.logger.debug(`Found ${s.length} controllers to import`),await Promise.all(s.map(async o=>{exports.logger.debug(`Importing controller ${o}`),await import(o).catch(n=>{exports.logger.error(`Error importing controller ${o}: ${n}`);});}));}catch(r){exports.logger.warn(`Could not auto-import controllers: ${r instanceof Error?r.message:String(r)}`);}}extractOptionsAndHandlerFromRouteRegistration(e,t){if(typeof e=="function")return {middlewares:[],handler:e,swaggerOptions:void 0};let r=e;return {middlewares:Array.isArray(r.middlewares)?r.middlewares:r.middlewares?[r.middlewares]:[],handler:t,swaggerOptions:r.swagger}}applyPlugins(e){Object.entries(e).forEach(([t,r])=>{switch(t){case "bodyParser":this.use(hr(r));break;case "cors":this.use(wr(r));break;case "static":this.use(sr(r));break;case "helmet":this.use(Or(r));break;case "cookie":this.use(yr(r));break;case "methodOverride":this.use(Er(r));break;case "compression":this.use(gr(r));break;case "log":this.use(qr(r));break;case "rateLimiter":let{keyOptions:s,storageOptions:o}=r;this.use(jr(s,o));break;case "trustProxy":this.use(Br(r));break;case "timeout":this.use($r(r));break;case "session":this.use(Mr(r));break;case "asyncLocalStorage":this.use(Bt(r));break;default:exports.logger.warn(`Unknown plugin ${t}`);break}});}async bootstrap(e){this.#t||(await this.importControllers(e?.controllerPatterns),this.applyPlugins(this.serverOptions.plugins),this.registerNotFoundRoutes(),this.#r.length&&M.applyGlobalMiddlewaresToAllRoutes(this.#r),this.#t=true);}handleNotFound=(e,t)=>{if(this.#i){this.#i(e,t);return}let r=new URL(e.url).pathname,s=["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"],o=[];for(let a of s){if(a===e.method.toUpperCase())continue;let c=M.find(a,r);c&&c.handler!==this.handleNotFound&&o.push(a);}if(o.length){t.setHeader("Allow",o.join(", "));let a=new $e(r,e.method);t.methodNotAllowed({...B(a)});return}let n=new D(r,e.method);t.notFound({...B(n)});};registerNotFoundRoutes(){let e=["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"];for(let t of e)M.addOrUpdate(t,"*",[],this.handleNotFound,{excludeFromSwagger:true});}setupAbortSignalHandler(){if(!this.serverOptions.abortSignal)return;let e=this.serverOptions.abortSignal;if(e.aborted){exports.logger.warn("AbortSignal was already aborted, server will not start");return}e.addEventListener("abort",async()=>{exports.logger.info("AbortSignal received, shutting down server gracefully");try{await this.disconnect(),exports.logger.info("Server shutdown completed");}catch(t){exports.logger.error({error:t},"Error during server shutdown from abort signal");}});}};var re=class{static scheduledJobs=[];static register(e,...t){t[2]={name:e,...t[2]},this.scheduledJobs.push({name:e,args:t});}static async run(){let e=(await import('node-cron').catch(()=>{throw new T("node-cron not installed as a dependency, it is required in order to run cron jobs with the @cron decorator")})).default;if(exports.logger.info("Scheduling cron jobs"),!this.scheduledJobs.length){exports.logger.info("No cron jobs to schedule");return}for(let{name:t,args:r}of this.scheduledJobs)exports.logger.info(`Scheduling cron job: ${t}`),e.schedule(...r).on("execution:failed",o=>this.globalErrorHandler(o));exports.logger.info("Cron jobs scheduled");}static globalErrorHandler(e){exports.logger.error(e.execution?.error);}static async massiveImportCronJobs(e){let t=[];for(let r of e){let s=await glob.glob(r,{absolute:true,cwd:I.getCwd()});t.push(...s);}await Promise.all(t.map(async r=>{await import(r).catch(s=>{exports.logger.error(`Error importing cron job: ${r}`),exports.logger.error(s);});}));}},Ha=i=>{re.globalErrorHandler=i.bind(re);};var Ga=(i,e)=>function(t,r,s){let o=s.value,n=async(...a)=>{let c=new t.constructor;return await o.apply(c,a)};return re.register(`${t.constructor.name}.${r}`,i,n,e),s};W();var _t=class{getCliArgs(){switch(C.type){case "bun":return this.getBunArgs();case "node":return this.getNodeArgs();case "deno":return Deno.args;default:throw new Error("Unsupported runtime")}}getCliCaller(){switch(C.type){case "bun":return "bun";case "node":return process.argv[0];case "deno":return "deno";default:throw new Error("Unsupported runtime")}}getBunArgs(){let e=Bun.argv,t=this.findScriptIndex(e);return e.slice(t+1)}getNodeArgs(){let e=process.argv,t=this.findScriptIndex(e);return e.slice(t+1)}findScriptIndex(e){if(e.length>=3&&e[1].includes(".bin/"))return 1;for(let t=0;t<e.length;t++){let r=e[t],s=r.split("/").pop()||r;if(!r.startsWith("-")){if(s==="yarn"&&t+1<e.length&&e[t+1]==="run"||s==="npx"&&t+1<e.length)return t+1;if(s==="yarn"||s==="pnpm")return t;if(s==="npm"&&t+1<e.length&&e[t+1]==="run"||s==="bun"&&t+1<e.length&&e[t+1]==="run")return t+1;if(/\.(js|ts|mjs|cjs)$/.test(r))return t;if(/^(tsx|ts-node|node|bun)$/.test(s)){for(let o=t+1;o<e.length;o++)if(!e[o].startsWith("-")&&/\.(js|ts|mjs|cjs)$/.test(e[o]))return o;return t}}}for(let t=e.length-1;t>=0;t--)if(!e[t].startsWith("-"))return t;return 1}},Ft=new _t;var Ys=i=>{if(!i||i==="-"||i==="--")return null;let e=i.indexOf("=");if(e>0){let t=i.substring(0,e),r=i.substring(e+1);return {name:t,value:Qr(r)}}return {name:i,value:true}},Qr=i=>{if(i.toLowerCase()==="true")return true;if(i.toLowerCase()==="false")return false;let e=Number(i);return !Number.isNaN(e)&&Number.isFinite(e)?e:i},ve=()=>{let i=Ft.getCliArgs(),e=[],t={};if(!i||!i.length)return {args:e,flags:t};for(let r=0;r<i.length;r++){let s=i[r];if(!(!s||typeof s!="string")){if(s.startsWith("-")){let o=Ys(s);if(o){if(o.value===true&&r+1<i.length){let n=i[r+1];n&&typeof n=="string"&&!n.startsWith("-")&&(o.value=Qr(n),r++);}if(o.name in t){let n=t[o.name];Array.isArray(n)?n.push(o.value):t[o.name]=[n,o.value];}else t[o.name]=o.value;}continue}e.push(s);}}return {args:e,flags:t}};var ft=()=>Ft.getCliArgs()[0]||null;var O=class{static metadata=new WeakMap;static set(e,t,r){this.metadata.has(e)||this.metadata.set(e,new Map),this.metadata.get(e).set(t,r);}static get(e,t){return this.metadata.get(e)?.get(t)}static getAll(e){return this.metadata.get(e)||new Map}static delete(e,t){this.metadata.get(e)?.delete(t);}static clear(e){this.metadata.delete(e);}};var we="VALIDATION_ERROR",rc="ARG",Ir=ve().args.slice(1),$=i=>(e,t)=>{let r=ft();if(!r||r!==e.commandName)return;let s=t;O.set(e,t,{type:"arg",name:s,description:i.description});let o=Ir.length?Ir.shift():i.defaultValue;if(i.required&&!o){let n=O.get(e,we);O.set(e,we,[...n||[],{type:"arg",name:s,message:"Required argument not provided"}]);return}i.parse&&o&&(o=i.parse(o)),Object.defineProperty(e,t,{value:o,enumerable:true,configurable:true,writable:true});};var Y=i=>(e,t)=>{let r=ft();if(!r||r!==e.commandName)return;let s=i.name||t,o=ve().flags,n=i.aliases?Array.isArray(i.aliases)?i.aliases:[i.aliases]:[],a=[s,...n],c=i.defaultValue;for(let p of a){let l=[p,`-${p}`,`--${p}`];for(let d of l)if(d in o){let m=o[d];i.type==="list"?c=(Array.isArray(m)?m:[m]).map(h=>{let g=String(h);return i.parse?i.parse(g):g}):(c=m,i.type==="boolean"?c=!!c:i.type==="number"?c=Number(c):i.type==="string"&&(c=String(c)),i.parse&&(c=i.parse(c)));break}if(c!==i.defaultValue)break}if(O.set(e,t,{type:"flag",name:s,aliases:n||[],description:i.description}),i.required&&(i.type==="list"?!c||Array.isArray(c)&&c.length===0:!c)){let l=O.get(e,we);O.set(e,we,[...l||[],{type:"flag",name:s,message:"Required flag not provided"}]);return}Object.defineProperty(e,t,{value:c,enumerable:true,configurable:true,writable:true});};Y.boolean=i=>Y({...i,type:"boolean"});Y.string=i=>Y({...i,type:"string"});Y.number=i=>Y({...i,type:"number"});Y.list=i=>Y({...i,type:"list"});Y.array=i=>Y({...i,type:"list"});var S=Y;var Xs=i=>async(e,t,r)=>{for(let s of i)if(!await s.manager.canAccess(s.scope,s.handler,e))return t.unauthorized({error:"Unauthorized"});return r()},dc=(i,e)=>t=>{let r=O.get(t.prototype,"__class__"),s=r?.middlewares||[],o=r?.policies||[],n=O.getAll(t.prototype),a=new t;for(let[c,p]of n.entries()){if(!p.route)continue;let l=t.prototype[c].bind(a),d=i?f.join(i,p.route.path):p.route.path,m=[...o,...p.policies||[]],y=m.length>0?[Xs(m)]:[],h=[...s,...y,...p.middlewares||[]];M.addOrUpdate(p.route.method,d,h,l,{service:t.name.replace(/Controller$/,""),...e,...p.documentation});}O.clear(t.prototype);};var hc=(i,e)=>(t,r,s)=>{let o=O.get(t,r);return o||(o={middlewares:[],route:{path:i,method:"DELETE"}}),o.documentation={...o.documentation||{},name:r,...e},o.route={path:i,method:"DELETE"},O.set(t,r,o),s};var yc=(i,e)=>(t,r,s)=>{let o=O.get(t,r);return o||(o={middlewares:[],route:{path:i,method:"GET"}}),o.documentation={...o.documentation||{},name:r,...e},o.route={path:i,method:"GET"},O.set(t,r,o),s};var bc=(i,e)=>(t,r,s)=>{let o=O.get(t,r);return o||(o={middlewares:[],route:{path:i,method:"PATCH"}}),o.documentation={...o.documentation||{},name:r,...e},o.route={path:i,method:"PATCH"},O.set(t,r,o),s};var xc=(i,e)=>(t,r,s)=>{let o=O.get(t,r);return o||(o={middlewares:[],route:{path:i,method:"POST"}}),o.documentation={...o.documentation||{},name:r,...e},o.route={path:i,method:"POST"},O.set(t,r,o),s};var Oc=(i,e)=>(t,r,s)=>{let o=O.get(t,r);return o||(o={middlewares:[],route:{path:i,method:"PUT"}}),o.documentation={...o.documentation||{},name:r,...e},o.route={path:i,method:"PUT"},O.set(t,r,o),s};var Ec=i=>(e,t,r)=>{if(typeof t>"u"){let o=O.get(e.prototype,"__class__");if(o||(o={middlewares:[]}),o.middlewares||(o.middlewares=[]),!i)throw new Error(`Middleware ${String(i)} not found, are you sure you defined it before using it?`);return Array.isArray(i)||(i=[i]),o.middlewares.push(...i),O.set(e.prototype,"__class__",o),e}let s=O.get(e,t);return s||(s={middlewares:[]}),s.middlewares||(s.middlewares=[]),Array.isArray(i)||(i=[i]),s.middlewares.push(...i),O.set(e,t,s),r};var _r=Symbol("serializeWrapped"),Fe=Symbol("serializeMetadata"),Ne=new WeakMap,Qc=(i,e)=>(t,r,s)=>{let o=O.get(t,r)||{middlewares:[],route:{}};o.documentation||(o.documentation={}),o.documentation.responses||(o.documentation.responses={}),o.serializeOptions||(o.serializeOptions={});let n=Number(e?.status??200);if(o.documentation.responses[n]=i,o.serializeOptions[n]=e?.safe??true,O.set(t,r,o),s.value[Fe]||(s.value[Fe]={}),s.value[Fe][n]={name:r,schema:i,safe:e?.safe??true},!s.value[_r]){let a=s.value,c=async function(...p){let l=p[1];await a.apply(this,p);let d=l.responseStatus,m=c[Fe],y=m?.[d]?.schema,h=m?.[d]?.safe??true;if(y&&!h){let g=l.getBody();try{let b;if(ae.isZodSchema(y)){let P=Ne.get(y);P||(P=Symbol("serialize_zod_schema"),Ne.set(y,P));let j=Q.get(P);if(!j){let A=y.toJSONSchema();j=H.ajv.compile(A),Q.set(P,j);}await U(j,g,h),l.send(g);}else if(Be.isTypeBoxSchema(y)){let P=Ne.get(y);P||(P=Symbol("serialize_typebox_schema"),Ne.set(y,P));let j=Q.get(P);j||(j=H.ajv.compile(y),Q.set(P,j)),await U(j,g,h),l.send(g);}else if(typeof y=="object"&&y!==null){let P=Ne.get(y);P||(P=Symbol("serialize_json_schema"),Ne.set(y,P));let j=Q.get(P);j||(j=H.ajv.compile(y),Q.set(P,j)),await U(j,g,h),l.send(g);}else {b=JSON.stringify(y);let P=Q.get(b);P||(P=H.ajv.compile(y),Q.set(b,P)),await U(P,g,h),l.send(g);}}catch(b){let P=await ae.load();if(b instanceof P.ZodError){l.internalServerError({received:g,schema:y,error:b});return}throw b}}};c[_r]=true,c[Fe]=a[Fe],s.value=c;}};var be=i=>(e,t,r)=>{let s=r.value,o=O.get(e,t);return o||(o={middlewares:[],route:{}}),o.documentation||(o.documentation={}),i.body&&(o.documentation.requestBody=i.body),i.query&&(o.documentation.query=i.query),i.all&&(o.documentation.requestBody=i.body,o.documentation.query=i.query),O.set(e,t,o),r.value=async function(...n){let a=n[0],c=n[1];try{let p,l,d;i.body&&(p=a.validate(i.body,i.safe)),i.query&&(l=a.validateQuery(i.query,i.safe)),i.all&&(d=a.validateAll(i.all,i.safe));let m=[...n];return p!==void 0&&m.push(p),l!==void 0&&m.push(l),d!==void 0&&m.push(d),s.apply(this,m)}catch(p){let l=await ae.load();if(!(p instanceof l.ZodError))throw p;return i.customError?c.status(i.customError.status||400).json({received:a.body,schema:i.body,error:p}):c.badRequest(p)}},r};be.query=(i,e)=>be({query:i,customError:e});be.body=(i,e)=>be({body:i,customError:e});be.all=(i,e)=>be({all:i,customError:e});var Nc=be;var Fr=class{logger=exports.logger.child({scope:this.constructor.name})};var Nr=class{logger=exports.logger.child({scope:this.constructor.name})};var to=i=>{if(!Buffer.isBuffer(i))return i;let e=i.toString();if(!e.length)return e;try{let t=JSON.parse(e);return typeof t=="object"&&t!==null?t:e}catch{return e}},We=class i{static subscriptions=[];static client=null;static connectionOptions={};static register(e,t,r,s){this.subscriptions.push({name:e,topic:t,handler:r,options:s});}static async connect(e={}){let t=await import('mqtt').catch(()=>{throw new T("mqtt not installed as a dependency, it is required in order to use MQTT subscriptions with the @mqtt decorator")});this.connectionOptions=e,exports.logger.info("Starting MQTT client"),this.subscriptions.length||exports.logger.info("No MQTT subscriptions to register");let{host:r="localhost",port:s=1883,protocol:o="mqtt",...n}=e,a=`${o}://${r}:${s}`;this.client=await t.connectAsync(a,n),exports.logger.info("MQTT client connected"),this.client.on("error",async c=>{await this.globalErrorHandler(c);}),this.client.on("message",(c,p)=>{this.handleMessage(c,p);}),this.client.on("disconnect",()=>{exports.logger.info("MQTT client disconnected");}),this.client.on("reconnect",async()=>{await this.globalErrorHandler(new Error("MQTT client reconnecting"));}),this.subscribeToTopics();}static subscribeToTopics(){if(this.client)for(let{name:e,topic:t,options:r}of this.subscriptions)exports.logger.info(`Subscribing to MQTT topic: ${t} (${e})`),this.client.subscribe(t,r||{},s=>{if(s){exports.logger.error(`Failed to subscribe to topic ${t}: ${s.message}`);return}exports.logger.info(`Successfully subscribed to topic: ${t}`);});}static async handleMessage(e,t){let r=this.subscriptions.filter(s=>{if(s.topic===e)return true;if(!e||typeof e!="string")return false;let o=s.topic.replace(/\+/g,"[^/]+").replace(/#$/,".*");return new RegExp(`^${o}$`).test(e)});for(let s of r)try{await s.handler(e,t);}catch(o){exports.logger.error(`Error handling MQTT message for topic ${e} in ${s.name}`),this.globalErrorHandler(o);}}static globalErrorHandler(e){exports.logger.error(e);}static setOnDisconnectHandler(e){this.client?.on("disconnect",e);}static setOnReconnectHandler(e){this.client?.on("reconnect",e);}static async massiveImportMqttHandlers(e){let t=[];for(let r of e){let s=await glob.glob(r,{absolute:true,cwd:I.getCwd()});t.push(...s);}await Promise.all(t.map(async r=>{await import(r).catch(s=>{exports.logger.error(`Error importing MQTT handler: ${r}`),exports.logger.error(s);});}));}subscribe(e,t){return function(r,s,o){let n=o.value;if(!n)return o;let a=async(c,p)=>{let l=new r.constructor,d=to(p);if(n.length===1){await n.call(l,d);return}await n.call(l,c,d);};return i.register(`${r.constructor.name}.${s}`,e,a,t),o}}async unsubscribe(e){if(!i.client)throw new T("MQTT client is not connected. Call MqttService.connect() first.");if(!i.client.connected)throw new T("MQTT client is not connected. Call MqttService.connect() first.");try{await i.client.unsubscribeAsync(e),i.subscriptions=i.subscriptions.filter(t=>t.topic!==e),exports.logger.debug(`Unsubscribed from topic: ${String(e)}`);}catch(t){throw exports.logger.error(`Failed to unsubscribe from topic ${String(e)}: ${t.message}`),t}}async publish(e,t,r){if(!i.client)throw new T("MQTT client is not connected. Call MqttService.connect() first.");if(!i.client.connected)throw new T("MQTT client is not connected. Call MqttService.connect() first.");let s;Buffer.isBuffer(t)?s=t:typeof t=="object"?s=JSON.stringify(t):s=String(t);try{await i.client.publishAsync(e,s,r||{}),exports.logger.debug(`Published message to topic: ${String(e)}`);}catch(o){throw exports.logger.error(`Failed to publish to topic ${String(e)}: ${o.message}`),o}}static async disconnect(){if(this.client)return new Promise(e=>{let t=this.client;t?.end(false,{},()=>{exports.logger.info("MQTT client disconnected gracefully"),t?.emit("disconnect",{cmd:"disconnect"}),this.client=null,e();});})}},Zc=i=>{We.globalErrorHandler=i.bind(We);},Yc=new We;var Hr=class{logger=exports.logger.child({scope:this.constructor.name})};var K=class extends T{constructor(...e){super(`Library not installed: ${e.join(", ")}, try run npm install ${e.join(" ")}`);}};var se=class{static options={connection:{}}},Dr=i=>{se.options=i??{connection:{}};};var yt=class{queues=new Map;workers=new Map;async publish(e,t,r){let s=await this.getQueue(e),o=J.randomUUID();return await s.add(e,t,{jobId:o,...se.options?.defaultJobOptions,...r}),{id:o}}async subscribe(e,t){if(this.workers.has(e))throw new Error(`[BullMQ] Already subscribed to topic "${e}"`);let{errorHandler:r,...s}=se.options??{},o=await this.getBullMQClient(),n=new o.Worker(e,async a=>{try{await t(a.data);}catch(c){await r?.(a,c)??Promise.reject(c);}},{...s});this.workers.set(e,n);}async unsubscribe(e){let t=this.workers.get(e);t&&(await t.close(),this.workers.delete(e));}async getQueue(e){if(!this.queues.has(e)){let t=await import('bullmq').catch(()=>{throw new K("bullmq","ioredis")}),r=new t.Queue(e,{...se.options||{connection:{}}});this.queues.set(e,r);}return this.queues.get(e)}async getBullMQClient(){return this.bullmqClient||(this.bullmqClient=await import('bullmq').catch(()=>{throw new K("bullmq","ioredis")})),this.bullmqClient}async publishWithConfig(e,t,r,s){let o=await this.getQueueWithConfig(e,s),n=J.randomUUID(),a={jobId:n,...se.options?.defaultJobOptions,...s?.defaultJobOptions,...r};return await o.add(e,t,a),{id:n}}async subscribeWithConfig(e,t,r){let s=this.getWorkerKey(e,r);if(this.workers.has(s))throw new Error(`[BullMQ] Already subscribed to topic "${e}"`);let o=se.options??{},{errorHandler:n}=o,a=await this.getBullMQClient(),c={...o,...r};delete c.errorHandler,delete c.defaultJobOptions;let p=new a.Worker(e,async l=>{try{await t(l.data);}catch(d){await n?.(l,d)??Promise.reject(d);}},c);this.workers.set(s,p);}async getQueueWithConfig(e,t){let r=this.getQueueKey(e,t);if(!this.queues.has(r)){let s=await import('bullmq').catch(()=>{throw new K("bullmq","ioredis")}),o={...se.options||{connection:{}},...t},n=new s.Queue(e,o);this.queues.set(r,n);}return this.queues.get(r)}getQueueKey(e,t){return t?.connection?`${e}:${JSON.stringify(t.connection)}`:e}getWorkerKey(e,t){return this.getQueueKey(e,t)}};var vt=class{subscribers=new Map;messageQueue=[];maxQueueSize;processingPromise=null;constructor(e=1e4){this.maxQueueSize=e;}clear(){this.subscribers.clear(),this.messageQueue=[],this.processingPromise=null;}async publish(e,t,r){if(this.messageQueue.length>=this.maxQueueSize)throw new Error(`Queue full: ${this.maxQueueSize} messages pending`);let s=J.randomUUID();return this.messageQueue.push({topic:e,payload:t}),this.processingPromise||(this.processingPromise=this.processQueue().catch(o=>{console.error("[MemoryPubSub] Fatal queue processing error:",o);}).finally(()=>{this.processingPromise=null;})),{id:s}}async subscribe(e,t){this.subscribers.has(e)||this.subscribers.set(e,new Set);let r=t;this.subscribers.get(e).add(r);}async unsubscribe(e){this.subscribers.delete(e);}async processQueue(){for(;this.messageQueue.length>0;){let e=this.messageQueue.shift();if(!e)break;let t=this.subscribers.get(e.topic);t&&t.size>0&&await Promise.allSettled(Array.from(t).map(r=>r(e.payload).catch(s=>{console.error(`[MemoryPubSub] Handler error for topic "${e.topic}":`,s);})));}}};var X=class{static options={}},Ur=i=>{X.options=i??{};};var wt=class{createdQueues=new Set;workers=new Map;async publish(e,t,r){let s=await this.getBoss();await this.ensureQueue(e);let o=r||{},n=await s.send(e,t,o);return {id:String(n??"")}}async subscribe(e,t){let r=await this.getBoss();await this.ensureQueue(e);let s=X.options;s.errorHandler&&r.on("error",s.errorHandler);let o=await r.work(e,async n=>{let a=Array.isArray(n)?n:[n];for(let c of a)await t(c.data);});this.workers.set(e,o);}async unsubscribe(e){let t=await this.getBoss(),r=this.workers.get(e);r&&(await t.offWork(r),this.workers.delete(e));}async getBoss(){if(this.boss)return this.boss;let e=await import('pg-boss').catch(()=>{throw new K("pg-boss","pg")}),r=e.PgBoss.default??e.PgBoss,{connectionString:s,boss:o}=X.options,n=s??o,a=new r(n);return X.options?.errorHandler&&a.on("error",X.options.errorHandler),await a.start(),this.boss=a,this.boss}async ensureQueue(e){if(this.createdQueues.has(e))return;let t=await this.getBoss();typeof t.createQueue=="function"&&await t.createQueue(e),this.createdQueues.add(e);}async publishWithConfig(e,t,r,s){let o=await this.getBossWithConfig(s);await this.ensureQueueWithBoss(e,o);let n=r||{},a=await o.send(e,t,n);return {id:String(a??"")}}async subscribeWithConfig(e,t,r){let s=await this.getBossWithConfig(r);await this.ensureQueueWithBoss(e,s);let o=X.options;o.errorHandler&&s.on("error",o.errorHandler);let n=`${e}:${r?.connectionString??"default"}`,a=await s.work(e,async c=>{let p=Array.isArray(c)?c:[c];for(let l of p)await t(l.data);});this.workers.set(n,a);}bossInstances=new Map;async getBossWithConfig(e){if(!e?.connectionString)return this.getBoss();let t=e.connectionString;if(this.bossInstances.has(t))return this.bossInstances.get(t);let r=await import('pg-boss').catch(()=>{throw new K("pg-boss","pg")}),o=r.PgBoss.default??r.PgBoss,n=new o(e.connectionString);return X.options?.errorHandler&&n.on("error",X.options.errorHandler),await n.start(),this.bossInstances.set(t,n),n}async ensureQueueWithBoss(e,t){this.createdQueues.has(e)||(typeof t.createQueue=="function"&&await t.createQueue(e),this.createdQueues.add(e));}};var me=class{static options={}},Gr=i=>{me.options=i??{};};var bt=class{consumers=new Map;client;async publish(e,t,r){let s=await this.getClient(),{SendMessageCommand:o}=await this.getSqsLib(),n=await this.resolveQueueUrl(e);if(!n)throw new Error(`[SQS] Queue url not configured for topic "${e}"`);let a=new o({MessageBody:JSON.stringify(t),MessageAttributes:{topic:{DataType:"String",StringValue:e}},QueueUrl:n,...r??{}});return {id:(await s.send(a)).MessageId??""}}async subscribe(e,t){if(this.consumers.has(e))throw new Error(`[SQS] Already subscribed to topic "${e}"`);let r=me.options,s=await this.getSqsConsumerLib(),o={...r.consumer||{},sqs:await this.getClient(),queueUrl:await this.resolveQueueUrl(e),handleMessage:async c=>{let p=JSON.parse(c.Body||"{}");await t(p);}},n=s.Consumer.create(o),a=r.errorHandler;a&&(n.on("error",a),n.on("processing_error",a)),n.start(),this.consumers.set(e,n);}async unsubscribe(e){let t=this.consumers.get(e);t&&(t.stop(),this.consumers.delete(e));}async getClient(){if(this.client)return this.client;let{SQSClient:e}=await this.getSqsLib(),t=me.options.client;return this.client=new e(t??{}),this.client}async getSqsLib(){return this.sqsLib||(this.sqsLib=await import('@aws-sdk/client-sqs').catch(()=>{throw new K("@aws-sdk/client-sqs","sqs-consumer")})),this.sqsLib}async getSqsConsumerLib(){return this.sqsConsumerLib||(this.sqsConsumerLib=await import('sqs-consumer').catch(()=>{throw new K("sqs-consumer")})),this.sqsConsumerLib}async resolveQueueUrl(e){let r=me.options.consumer?.queueUrlMap;if(!r?.[e])throw new Error(`[SQS] Queue url not configured for topic "${e}"`);return r[e]}async publishWithConfig(e,t,r,s){let{...o}=r??{},n=await this.getClientWithConfig(s?.client),{SendMessageCommand:a}=await this.getSqsLib(),c=s?.queueUrl??await this.resolveQueueUrl(e),p=new a({...o,MessageBody:JSON.stringify(t),MessageAttributes:{topic:{DataType:"String",StringValue:e}},QueueUrl:c});return {id:(await n.send(p)).MessageId??""}}async subscribeWithConfig(e,t,r){if(this.consumers.has(e))throw new Error(`[SQS] Already subscribed to topic "${e}"`);let s=me.options,o=await this.getSqsConsumerLib(),n=r?.queueUrl??await this.resolveQueueUrl(e),a={...s.consumer||{},sqs:await this.getClientWithConfig(r?.client),queueUrl:n,handleMessage:async l=>{let d=JSON.parse(l.Body||"{}");await t(d);}},c=o.Consumer.create(a),p=s.errorHandler;p&&(c.on("error",p),c.on("processing_error",p)),c.start(),this.consumers.set(e,c);}async getClientWithConfig(e){if(e){let{SQSClient:t}=await this.getSqsLib();return new t(e)}return this.getClient()}};var oe=class{static map=new Map;static{this.map.set("bullmq",new yt),this.map.set("sqs",new bt),this.map.set("pgboss",new wt),this.map.set("memory",new vt);}static getProvider(e){if(!this.map.has(e))throw new Error(`[QueueSubscriber] Provider ${e} not found`);return this.map.get(e)}static setProvider(e,t){this.map.set(e,t);}static clearMemoryProvider(){let e=this.map.get("memory");e&&"clear"in e&&e.clear();}};var V=class{static typedQueueSubscribers=new Map;static customQueueSubscribers=new Map;static instanceFactory=e=>new e;static registerTypedQueue(e,t,r,s,o){let n=`${s}:${t}:${e}`;this.typedQueueSubscribers.has(n)&&exports.logger.warn(`Queue handler for ${n} already registered, overwriting previous handler`),this.typedQueueSubscribers.set(n,{name:e,topic:t,handler:r,provider:s,queueOptions:o});}static registerCustomQueue(e,t,r,s){let o=`${s.constructor.name}:${t}:${e}`;this.customQueueSubscribers.has(o)&&exports.logger.warn(`Custom queue handler for ${o} already registered, overwriting previous handler`),this.customQueueSubscribers.set(o,{name:e,topic:t,handler:r,pubsub:s});}static async run(){exports.logger.info("Subscribing queue handlers");let e=this.typedQueueSubscribers.size>0,t=this.customQueueSubscribers.size>0;if(!e&&!t){exports.logger.info("No queue handlers to subscribe");return}for(let r of this.typedQueueSubscribers.values()){let{topic:s,handler:o,provider:n,queueOptions:a}=r;exports.logger.info(`Subscribing to queue: ${s}`);let c=oe.getProvider(n);a&&"subscribeWithConfig"in c&&typeof c.subscribeWithConfig=="function"?await c.subscribeWithConfig(s,o,a):await c.subscribe(s,o);}for(let{topic:r,handler:s,pubsub:o}of this.customQueueSubscribers.values())exports.logger.info(`Subscribing to custom queue: ${r}`),await o.subscribe(r,s);exports.logger.info("Queue handlers subscribed");}static async massiveImportQueues(e,t={}){let r=[];for(let s of e){let o=await glob.glob(s,{absolute:true,cwd:I.getCwd()});exports.logger.info(`Pattern "${s}" matched ${o.length} file(s)`),r.push(...o);}if(r.length===0){exports.logger.warn("No files matched the provided patterns");return}exports.logger.info(`Importing ${r.length} queue handler file(s)`),await Promise.all(r.map(async s=>{exports.logger.debug(`Importing: ${s}`),await import(s).catch(o=>{if(exports.logger.error(`Error importing queue handler: ${s}`),exports.logger.error(o),t.throwOnError)throw o});})),exports.logger.info(`Successfully imported ${r.length} file(s)`);}};var Pt=new WeakMap,he=class{constructor(e,t,r){this.topic=e;this.provider=t;this.queueOptions=r;}async publish(e,t){let r=oe.getProvider(this.provider);return this.queueOptions?r.publishWithConfig(this.topic,e,t,this.queueOptions):r.publish(this.topic,e,t??{})}subscribe(e){return e?this.subscribeWithCallback(e):this.createSubscribeDecorator()}async unsubscribe(){await oe.getProvider(this.provider).unsubscribe(this.topic);}createSubscribeDecorator(){let e=this.topic,t=this.provider,r=this.queueOptions;return function(s,o,n){let a=n.value,c=async p=>{let l=Pt.get(s.constructor);return l||(l=V.instanceFactory(s.constructor),Pt.set(s.constructor,l)),a.apply(l,[p])};return V.registerTypedQueue(`${s.constructor.name}.${String(o)}`,e,c,t,r),n}}async subscribeWithCallback(e){let t=oe.getProvider(this.provider);if(this.queueOptions){await t.subscribeWithConfig(this.topic,e,this.queueOptions);return}await t.subscribe(this.topic,e);}},Ke=class{constructor(e,t){this.topic=e;this.pubsub=t;}async publish(e,t){return this.pubsub.publish(this.topic,e,t)}subscribe(e){return e?this.pubsub.subscribe(this.topic,e):this.createSubscribeDecorator()}async unsubscribe(){await this.pubsub.unsubscribe(this.topic);}createSubscribeDecorator(){let e=this.topic,t=this.pubsub;return function(r,s,o){let n=o.value,a=async c=>{let p=Pt.get(r.constructor);return p||(p=V.instanceFactory(r.constructor),Pt.set(r.constructor,p)),n.apply(p,[c])};return V.registerCustomQueue(`${r.constructor.name}.${String(s)}`,e,a,t),o}}};function so(i,e){return new he(i,"sqs",e)}function oo(i,e){return new he(i,"bullmq",e)}function io(i,e){return new he(i,"pgboss",e)}function Nt(i){return new he(i,"memory")}function no(i,e){return new Ke(i,e)}var Ip=i=>{let e=["bullmq","pgboss","sqs"];i.bullmq&&Dr(i.bullmq),i.pgboss&&Ur(i.pgboss),i.sqs&&Gr(i.sqs);for(let t of Object.keys(i)){let r=t;e.includes(r)||oe.setProvider(r,i[r]);}};W();var Ht=class{exit(e){switch(C.type){case "bun":case "node":process.exit(e);case "deno":Deno.exit(e);default:throw new Error("Unsupported runtime")}}},Dt=new Ht;var E=class{static commandName=this.name;static calledBy=this.name;static description="";static help=[];static options={keepAlive:false};static args=ve().args.slice(1);static flags=ve().flags;static logger=exports.logger;static handle(){throw new Error(`Handle method not implemented in command class ${this.name}`)}static handleHelpFlag(e){let t=["-h","--help"];if(!Object.keys(e).some(p=>t.includes(p)))return;let s=this.commandName,o=this.description||"No description available",n=this.help||[],a=this.options,c=this.generateHelpOutput({name:s,description:o,helpText:n,options:a,args:this.args,flags:this.flags},this);console.log(c),Dt.exit(0);}static generateHelpOutput=(e,t)=>{let{name:r,description:s,helpText:o,options:n,args:a,flags:c}=e,p={title:"\x1B[1;36m",subtitle:"\x1B[1;33m",description:"\x1B[0;37m",code:"\x1B[0;32m",flag:"\x1B[0;35m",reset:"\x1B[0m",error:"\x1B[0;31m",success:"\x1B[0;32m",info:"\x1B[0;34m"},l=[`${p.title}${r}${p.reset}`,`${p.description}${s}${p.reset}`,"",`${p.subtitle}Usage:${p.reset}`,` ${p.code}${r}${p.reset} [options] [arguments]`,"",`${p.subtitle}Options:${p.reset}`,` ${p.flag}-h, --help${p.reset} Show this help message`,"",`${p.subtitle}Command Options:${p.reset}`,` ${p.flag}keepAlive${p.reset} ${n?.keepAlive??false?p.success+"Enabled"+p.reset:p.error+"Disabled"+p.reset}`,""];if(o){let h=Array.isArray(o)?o:[o];l.push(`${p.subtitle}Help:${p.reset}`),h.forEach(g=>{l.push(` ${p.description}${g}${p.reset}`);}),l.push("");}let d=O.getAll(t),m=Array.from(d.values()).filter(h=>h.type==="arg"),y=Array.from(d.values()).filter(h=>h.type==="flag");return m.length&&(l.push(`${p.subtitle}Available Arguments:${p.reset}`),m.forEach(h=>{let g=h.required?` ${p.error}(required)${p.reset}`:"",b=h.description?` ${p.description}${h.description}${p.reset}`:"";l.push(` ${p.code}${h.name}${p.reset}${g}${b}`);}),l.push("")),y.length&&(l.push(`${p.subtitle}Available Flags:${p.reset}`),y.forEach(h=>{h.aliases&&!Array.isArray(h.aliases)&&(h.aliases=[h.aliases]);let g=h.aliases.length?` ${p.flag}(${h.aliases.join(", ")})${p.reset}`:"",b=h.required?` ${p.error}(required)${p.reset}`:"",P=h.description?` ${p.description}${h.description}${p.reset}`:"";l.push(` ${p.flag}--${h.name}${g}${p.reset}${b}${P}`);}),l.push("")),((a?.length??0)>0||c&&Object.keys(c).length>0)&&(l.push(`${p.subtitle}Current Context:${p.reset}`),a?.length&&l.push(` ${p.info}Provided Arguments:${p.reset} ${p.code}${a.join(" ")}${p.reset}`),c&&Object.keys(c).length>0&&(l.push(` ${p.info}Provided Flags:${p.reset}`),Object.keys(c).forEach(h=>{let g=c[h],b=g!=null?` = ${p.code}${g}${p.reset}`:"";l.push(` ${p.flag}${h}${p.reset}${b}`);})),l.push("")),o&&(Array.isArray(o)?o.some(h=>h.includes("example")):o.includes("example"))&&(l.push(`${p.subtitle}Examples:${p.reset}`),(Array.isArray(o)?o.filter(g=>g.includes("example")):[o.split("example")[1].trim()]).forEach(g=>{l.push(` ${p.code}${g}${p.reset}`);}),l.push("")),l.join(`
|
|
143
|
-
`)};static validateContext=e=>{let t=Array.from(O.get(e,we)||[]);if(t.length){let r={error:"\x1B[0;31m",title:"\x1B[1;31m",reset:"\x1B[0m",info:"\x1B[0;34m",code:"\x1B[0;32m"};console.error(`${r.title}\u274C Validation Errors:${r.reset}`),console.error(""),t.forEach((s,o)=>{let n=`${r.info}${o+1}.${r.reset}`,a=`${r.error}${s.type.toUpperCase()}${r.reset}`,c=`${r.code}${s.name}${r.reset}`;console.error(` ${n} ${a} ${c}: ${r.error}${s.message}${r.reset}`);}),console.error(""),console.error(`${r.info}\u{1F4A1} Tip: Use --help for usage information${r.reset}`),Dt.exit(1);}}};var pe=async i=>{let e=f.join(process.cwd(),"node_modules");if(!await u.exists(e))return i;let r=[];for(let s of i){let o=f.join(e,s);await u.exists(o)||r.push(s);}return r},G=async()=>await u.exists(f.join(process.cwd(),"yarn.lock"))?["yarn","add","-D"]:await u.exists(f.join(process.cwd(),"pnpm-lock.yaml"))?["pnpm","add","-D"]:await u.exists(f.join(process.cwd(),"package-lock.json"))?["npm","install","-D"]:await u.exists(f.join(process.cwd(),"bun.lockb"))?["bun","add","-D"]:await u.exists(f.join(process.cwd(),"deno.lock"))?["deno","add","-D"]:["npm","install","-D"],F=async(i,e,t,r,s=true)=>{let o=zr__namespace.createInterface({input:process.stdin,output:process.stdout}),n=t.join(", "),a=`Do you want to install the following ${s?"dev":""} dependencies using ${e}?
|
|
144
|
-
${n}
|
|
145
|
-
(y/n): `;return new Promise(c=>{o.question(a,p=>{if(o.close(),p.toLowerCase()==="y"||p.toLowerCase()==="yes"){child_process.execSync(i,r),c(true);return}c(false);});})};var z=class extends E{static commandName="build";static description="Build the project for production, node.js only";static help=["Build the project for production, node.js only","It will create a production build of the project in the dist directory","Must have a tsconfig.json file in the root of the project","Must have esbuild installed as a dependency while running the command","Must have esbuild-plugin-copy installed as a dependency while running the command if you want to copy assets to the output directory","Example: npx balda build -t ./tsconfig.json -a ./assets"];static clearDist;static entry;static output;static tsconfig;static assets;static format;static packages;static sourcemap;static async handle(){if(typeof process===void 0&&(this.logger.error("Build command is only supported in node.js"),process.exit(1)),["esm","cjs"].includes(this.format)||(this.logger.error("Invalid format, must be 'esm' or 'cjs'"),process.exit(1)),["bundle","external"].includes(this.packages)||(this.logger.error("Invalid packages, must be 'bundle' or 'external'"),process.exit(1)),!await import('esbuild').then(a=>true).catch(()=>false)){let[a,c,p]=await G();await F(`${a} ${c} esbuild ${p}`,a,["esbuild"],{stdio:"inherit"})||(this.logger.warn("User chose to not continue with the installation of esbuild, exiting..."),process.exit(0));}let t=await import('esbuild').catch(a=>{throw this.logger.error("esbuild is not installed, please install it with `npm install -D esbuild` to use the build command"),new Error("esbuild is not installed")}),r=st__default.default.join(this.output,"assets"),s=[];if(this.assets){let{copy:a}=await import('esbuild-plugin-copy').catch(c=>{throw this.logger.error("esbuild-plugin-copy is not installed, please install it with `npm install -D esbuild-plugin-copy` to use the build command"),new Error("esbuild-plugin-copy is not installed")});Ve__default.default.existsSync(r)||Ve__default.default.mkdirSync(r,{recursive:true}),s.push(a({assets:{from:this.assets,to:r}}));}this.clearDist&&Ve__default.default.existsSync(this.output)&&(this.logger.info("Clearing dist directory..."),Ve__default.default.rmSync(this.output,{recursive:true})),this.logger.info("Building project...");let o=st__default.default.join(this.output,"server.js"),n=await t.build({tsconfig:this.tsconfig,entryPoints:[this.entry],bundle:true,platform:"node",outfile:o,minify:true,sourcemap:this.sourcemap,plugins:s,format:this.format,packages:this.packages});n.errors.length&&(this.logger.error(JSON.stringify({message:"Failed to build the project",errors:n.errors},null,2)),process.exit(1)),n.warnings.length&&this.logger.warn(JSON.stringify({message:"Failed to build the project",warnings:n.warnings},null,2)),this.logger.info(JSON.stringify({message:`Project built successfully in ${o}`,output:o,assets:!!this.assets},null,2)),process.exit(0);}};w([S({type:"boolean",aliases:["c"],name:"clear-dist",required:false,defaultValue:false,description:"Whether to clear the dist directory before building the project"})],z,"clearDist"),w([S({type:"string",aliases:["e"],name:"entry",required:false,defaultValue:"./src/index.ts",description:"The entry point of the project, default is ./src/index.ts"})],z,"entry"),w([S({type:"string",aliases:["o"],name:"output",required:false,defaultValue:"./dist",description:"The path to the output directory, default is ./dist"})],z,"output"),w([S({type:"string",aliases:["t"],name:"tsconfig",required:false,defaultValue:"./tsconfig.json",description:"The path to the tsconfig.json file, default is ./tsconfig.json"})],z,"tsconfig"),w([S({type:"string",aliases:["a"],name:"assets",required:false,description:"The path to the assets directory that will be loaded in the production build"})],z,"assets"),w([S({type:"string",aliases:["f"],name:"format",required:false,defaultValue:"esm",description:"The format to build the project, default is esm, can be 'esm' or 'cjs'"})],z,"format"),w([S({type:"string",aliases:["p"],name:"packages",required:false,defaultValue:"external",description:"Weather to bundle node_modules or not, default is external, can be 'bundle' or 'external'"})],z,"packages"),w([S({type:"boolean",aliases:["s"],name:"sourcemap",required:false,defaultValue:true,description:"Whether to generate sourcemaps or not, default is true"})],z,"sourcemap");var Pe=class extends E{static commandName="cron-start";static description="Start cron job scheduler";static help=["Start the cron job scheduler to run scheduled tasks","Loads cron jobs from specified patterns and starts scheduling","Example: npx balda cron-start","Example: npx balda cron-start src/crons/**/*.ts --patterns src/schedules/**/*.ts"];static options={keepAlive:true};static pattern;static additionalPatterns;static async handle(){this.logger.info("Starting cron scheduler...");let e=[this.pattern];this.additionalPatterns&&this.additionalPatterns.length>0&&e.push(...this.additionalPatterns),this.logger.info(`Loading cron jobs from patterns: ${e.join(", ")}`),await re.massiveImportCronJobs(e);let t=re.scheduledJobs.length;if(t===0){this.logger.warn("No cron jobs found. Make sure your cron jobs are decorated with @cron decorator");return}this.logger.info(`Found ${t} cron job(s)`),re.run().then(()=>{this.logger.info("Cron scheduler started successfully. Press Ctrl+C to stop.");}).catch(r=>{this.logger.error("Error starting cron scheduler",r);});}};w([$({required:false,defaultValue:"src/crons/**/*.{ts,js}",description:"Primary glob pattern for cron jobs (default: src/crons/**/*.{ts,js})"})],Pe,"pattern"),w([S.array({aliases:["p"],name:"patterns",required:false,description:"Additional glob patterns for cron jobs"})],Pe,"additionalPatterns");var He=class extends E{static commandName="generate-command";static description="Generate a new command in the specified path";static help=["Generate a new cli command in the specified path","Example: npx balda generate-command my-command -p src/commands"];static path="src/commands";static name;static async handle(){if(De.getCommand(this.name)){let s=De.isBuiltInCommand(this.name)?"built-in":"user-defined";this.logger.error({commandName:this.name,type:s},`Command "${this.name}" already exists as a ${s} command. Cannot override existing commands.`);return}let t=this.getCommandTemplate();this.path=f.join(this.path,`${this.name}.ts`),await u.exists(f.join(process.cwd(),this.path))||await u.mkdir(f.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.path,new TextEncoder().encode(t)),this.logger.info(`Command ${this.name} created successfully at ${this.path}`);}static getCommandTemplate(){return `import { Command, CommandOptions } from "balda";
|
|
146
|
-
|
|
147
|
-
export default class extends Command {
|
|
148
|
-
static commandName = "${this.name}";
|
|
149
|
-
static description = "Command description";
|
|
150
|
-
|
|
151
|
-
static options: CommandOptions = {
|
|
152
|
-
// Define your command options here
|
|
153
|
-
keepAlive: false,
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
static async handle(): Promise<void> {
|
|
157
|
-
// Implement your command logic here
|
|
158
|
-
}
|
|
159
|
-
}`}};w([$({description:"The name of the command to generate",required:true})],He,"name");var Se=class extends E{static commandName="generate-controller";static description="Generate a new controller in the specified path";static help=["Generate a new controller in the specified path","Example: npx balda generate-controller user -p src/controllers"];static controllerName;static path;static async handle(){let e=this.getControllerTemplate(),t=`${this.controllerName.toLowerCase()}.ts`;this.path=f.join(this.path,t),await u.exists(f.join(process.cwd(),this.path))||await u.mkdir(f.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.path,new TextEncoder().encode(e)),this.logger.info(`Controller ${this.controllerName} created successfully at ${this.path}`);}static getControllerTemplate(){let e=at(this.controllerName);return `import { controller, get, post, put, del, Request, Response } from "balda";
|
|
160
|
-
|
|
161
|
-
@controller("/${ir(this.controllerName)}")
|
|
162
|
-
export default class ${e}Controller {
|
|
163
|
-
@get("/")
|
|
164
|
-
async index(req: Request, res: Response) {
|
|
165
|
-
return { message: "List all ${this.controllerName.toLowerCase()}s" };
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
@get("/:id")
|
|
169
|
-
async show(req: Request, res: Response) {
|
|
170
|
-
return { message: \`Get ${this.controllerName.toLowerCase()} with id \${req.params.id}\` };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
@post("/")
|
|
174
|
-
async create(req: Request, res: Response) {
|
|
175
|
-
return { message: \`Create ${this.controllerName.toLowerCase()}\`, data: req.body };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
@put("/:id")
|
|
179
|
-
async update(req: Request, res: Response) {
|
|
180
|
-
return { message: \`Update ${this.controllerName.toLowerCase()} with id \${req.params.id}\`, data: req.body };
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
@del("/:id")
|
|
184
|
-
async destroy(req: Request, res: Response) {
|
|
185
|
-
return { message: \`Delete ${this.controllerName.toLowerCase()} with id \${req.params.id}\` };
|
|
186
|
-
}
|
|
187
|
-
}`}};w([$({description:"The name of the controller to generate",required:true})],Se,"controllerName"),w([S({description:"The path to the controller to generate, default is src/controllers",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/controllers"})],Se,"path");var xe=class extends E{static commandName="generate-cron";static description="Generate a new cron job in the specified path";static help=["Generate a new cron job in the specified path","Example: npx balda generate-cron my-cron -p src/cron"];static fileName;static path;static async handle(){let e=this.getCronTemplate();this.path=f.join(this.path,`${this.fileName}.ts`),await u.exists(f.join(process.cwd(),this.path))||await u.mkdir(f.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.path,new TextEncoder().encode(e)),this.logger.info(`Cron job ${this.fileName} created successfully at ${this.path}`);}static getCronTemplate(){return `import { BaseCron, cron } from "balda";
|
|
188
|
-
|
|
189
|
-
export default class extends BaseCron {
|
|
190
|
-
@cron("* * * * *")
|
|
191
|
-
handle() {
|
|
192
|
-
this.logger.info("Running cron job");
|
|
193
|
-
// Implement your cron job logic here
|
|
194
|
-
}
|
|
195
|
-
}`}};w([$({description:"The name of the cron job file to generate",required:true})],xe,"fileName"),w([S({description:"The path to the cron job to generate, default is src/cron",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/cron"})],xe,"path");var Te=class extends E{static commandName="generate-middleware";static description="Generate a new middleware in the specified path";static help=["Generate a new middleware in the specified path","Example: npx balda generate-middleware auth -p src/middlewares"];static middlewareName;static path;static async handle(){let e=this.getMiddlewareTemplate(),t=`${this.middlewareName.toLowerCase()}.ts`;this.path=f.join(this.path,t),await u.exists(f.join(process.cwd(),this.path))||await u.mkdir(f.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.path,new TextEncoder().encode(e)),this.logger.info(`Middleware ${this.middlewareName} created successfully at ${this.path}`);}static getMiddlewareTemplate(){let e=at(this.middlewareName);return `import type { Request, Response, NextFunction, ServerRouteMiddleware } from "balda";
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* ${e} middleware
|
|
199
|
-
* @description Add your middleware logic here
|
|
200
|
-
*/
|
|
201
|
-
export const ${e}: ServerRouteMiddleware = async () => {
|
|
202
|
-
return async (req: Request, res: Response, next: NextFunction) => {
|
|
203
|
-
// Add your middleware logic here
|
|
204
|
-
return next();
|
|
205
|
-
};
|
|
206
|
-
};`}};w([$({description:"The name of the middleware to generate",required:true})],Te,"middlewareName"),w([S({description:"The path to the middleware to generate, default is src/middlewares",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/middlewares"})],Te,"path");var Re=class extends E{static commandName="generate-mqtt";static description="Generate a new MQTT handler in the specified path";static help=["Generate a new MQTT handler in the specified path","Example: npx balda generate-mqtt temperature-handler -p src/mqtt"];static path;static topic;static async handle(){let e=this.topic.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/),t=this.getMqttTemplate(!!e);this.path=f.join(this.path,`${nt(this.topic.replace(/\//g,"_"))}.ts`),await u.exists(f.join(process.cwd(),this.path))||await u.mkdir(f.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.path,new TextEncoder().encode(t)),this.logger.info(`MQTT handler for topic ${this.topic} created successfully at ${this.path}`);}static getMqttTemplate(e){return `import { BaseMqtt, mqtt } from "balda";
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Define your MQTT topics interface for type safety
|
|
210
|
-
*/
|
|
211
|
-
declare module "balda" {
|
|
212
|
-
interface MqttTopics {
|
|
213
|
-
${e?`${this.topic}: string;`:`'${this.topic}': string;`}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export default class extends BaseMqtt {
|
|
218
|
-
@mqtt.subscribe("${this.topic}")
|
|
219
|
-
async handle(message: string) {
|
|
220
|
-
this.logger.info({ message }, "Message received");
|
|
221
|
-
// Implement your MQTT handler logic here
|
|
222
|
-
}
|
|
223
|
-
}`}};w([S({description:"The path to the MQTT handler to generate, default is src/mqtt",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/mqtt"})],Re,"path"),w([$({description:"The MQTT topic to subscribe to",required:true})],Re,"topic");var Oe=class extends E{static commandName="generate-plugin";static description="Generate a new plugin in the specified path";static help=["Generate a new plugin in the specified path","Example: npx balda generate-plugin my-plugin -p src/plugins"];static pluginName;static pluginPath;static async handle(){let e=this.getPluginTemplate();this.pluginPath=f.join(this.pluginPath,`${this.pluginName}.ts`),await u.exists(f.join(process.cwd(),this.pluginPath))||await u.mkdir(f.join(process.cwd(),this.pluginPath.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.pluginPath,new TextEncoder().encode(e)),this.logger.info(`Plugin ${this.name} created successfully at ${this.pluginPath}`);}static getPluginTemplate(){return `import { BasePlugin, Request, Response, NextFunction, ServerRouteMiddleware } from "balda";
|
|
224
|
-
|
|
225
|
-
export default class extends BasePlugin {
|
|
226
|
-
async handle(): Promise<ServerRouteMiddleware> {
|
|
227
|
-
return async (req: Request, res: Response, next: NextFunction) => {
|
|
228
|
-
console.log("${this.pluginName} plugin is running");
|
|
229
|
-
await next();
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
}`}};w([$({description:"The name of the plugin to generate",required:true})],Oe,"pluginName"),w([S({description:"The path to the plugin to generate, default is src/plugins",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/plugins"})],Oe,"pluginPath");var ge=class extends E{static commandName="generate-queue";static description="Generate a new queue in the specified path";static help=["Generate a new queue in the specified path","Example: npx balda generate-queue my-queue -p src/queues --provider bullmq"];static queueName;static path;static provider;static async handle(){let e=this.queueName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/),t=this.getQueueTemplate(!!e);this.path=f.join(this.path,`${nt(this.queueName)}.ts`),await u.exists(f.join(process.cwd(),this.path))||await u.mkdir(f.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await u.writeFile(this.path,new TextEncoder().encode(t)),this.logger.info(`Queue ${this.queueName} created successfully at ${this.path}`);}static getQueueTemplate(e){return `import { BaseQueue, queue } from "balda";
|
|
233
|
-
|
|
234
|
-
export type Payload = {
|
|
235
|
-
// Add your payload here
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
declare module "balda" {
|
|
239
|
-
export interface QueueTopic {
|
|
240
|
-
${e?this.queueName:`'${this.queueName}'`}: Payload;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export default class extends BaseQueue {
|
|
245
|
-
@queue('${this.provider}', '${this.queueName}')
|
|
246
|
-
async handle(payload: Payload) {
|
|
247
|
-
// Implement your queue logic here
|
|
248
|
-
this.logger.info({ payload }, 'Payload received');
|
|
249
|
-
return Promise.resolve();
|
|
250
|
-
}
|
|
251
|
-
}`}};w([$({description:"The name of the queue to generate",required:true})],ge,"queueName"),w([S({description:"The path to the queue to generate, default is src/queues",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/queues"})],ge,"path"),w([S({description:"The provider of the queue to generate, default is bullmq",type:"string",aliases:["pr"],name:"provider",required:false,defaultValue:"bullmq"})],ge,"provider");var N=class extends E{static commandName="generate-sdk";static description="Generate a TypeScript SDK from your server's OpenAPI specification";static help=["Generate a TypeScript SDK from your server's OpenAPI specification","This command imports your server instance, starts it if needed, downloads the OpenAPI spec, and generates an SDK","","Arguments:"," serverPath Path to the server instance file (default: test/server/instance.ts)","","Flags:"," -o, --output <path> Output directory for generated SDK (default: sdk)"," -s, --swagger-path <path> Swagger UI path on your server (default: /docs)"," -c, --client <type> HTTP client to use: axios or fetch (default: fetch)"," --unwrap-response-data Automatically unwrap response data property"," --single-http-client Generate single HTTP client instance"," --type-prefix <prefix> Add prefix to all generated types"," --type-suffix <suffix> Add suffix to all generated types"," --enum-names-as-values Use enum names as values"," --sort-types Sort types alphabetically","","Examples:"," npx balda generate-sdk"," npx balda generate-sdk src/server/index.ts -o ./client-sdk"," npx balda generate-sdk src/server.ts --client axios"," npx balda generate-sdk --unwrap-response-data --single-http-client"," npx balda generate-sdk --type-prefix Api --sort-types"];static serverPath;static outputPath;static swaggerPath;static httpClient;static unwrapResponseData;static singleHttpClient;static typePrefix;static typeSuffix;static enumNamesAsValues;static sortTypes;static async handle(){console.log(`
|
|
252
|
-
\u{1F680} Starting SDK generation...
|
|
253
|
-
`);let e="swagger-typescript-api",t=f.join(process.cwd(),"node_modules"),r=await u.exists(t),s=f.join(t,e);if(!(r?await u.exists(s):false)){console.log(`\u{1F4E6} ${e} not found. Installing as dev dependency...
|
|
254
|
-
`);let[x,R,q]=await G();if(!await F(`${x} ${R} ${e} ${q}`,x,[e],{stdio:"inherit"},true)){console.log(`\x1B[33m\u26A0\uFE0F SDK generation cancelled: swagger-typescript-api installation was skipped.\x1B[0m
|
|
255
|
-
`);return}console.log(`
|
|
256
|
-
\x1B[32m\u2705 ${e} installed successfully!\x1B[0m
|
|
257
|
-
`);}let n=f.resolve(process.cwd(),this.serverPath);if(!await u.exists(n)){console.error(`\x1B[31m\u274C Error: Server file not found at ${n}\x1B[0m
|
|
258
|
-
`);return}console.log(`\u{1F4C2} Loading server from: ${this.serverPath}`);let c;try{c=await import(`file://${n}`);}catch(x){console.error("\x1B[31m\u274C Error importing server module:\x1B[0m",x);return}let p=Object.keys(c),l=null;for(let x of p){let R=c[x];if("default"in R&&R.default&&(R=R.default),R&&"_brand"in R&&R._brand==="BaldaServer"&&typeof R=="object"&&"listen"in R){l=R,console.log(`\u2705 Found server instance in export: "${x}"
|
|
259
|
-
`);break}}if(!l){console.error(`\x1B[31m\u274C Error: No Server instance found in ${this.serverPath}\x1B[0m`),console.log(`\x1B[90mExpected exports: ${p.join(", ")}\x1B[0m
|
|
260
|
-
`);return}let d=false,m="";m="http://localhost:80";try{if(console.log(`\u{1F310} Starting server on ${m}...`),typeof l.listen=="function"&&!l.isListening)await new Promise((x,R)=>{try{l.listen(()=>{d=!0,console.log(`\u2705 Server started successfully!
|
|
261
|
-
`),x();});}catch(q){R(q);}}).catch(x=>{console.error("Failed to start the server, continuing...");});else throw new Error("Server instance does not have a listen() method")}catch(x){console.error("\x1B[31m\u274C Error starting server:\x1B[0m",x);return}let g=this.swaggerPath??(typeof l.serverOptions.swagger!="boolean"?l.serverOptions.swagger?.path:"/docs"),b=f.join(m,g??"/docs","/json");console.log(`\u{1F4E5} Downloading OpenAPI spec from: ${b}`);let P;try{let x=await globalThis.fetch(b);if(!x.ok)throw new Error(`Failed to fetch OpenAPI spec: ${x.status} ${x.statusText}`);P=await x.json(),console.log(`\u2705 OpenAPI spec downloaded successfully!
|
|
262
|
-
`);}catch(x){if(console.error("\x1B[31m\u274C Error downloading OpenAPI spec:\x1B[0m",x),d){let R=l;try{await R.close?.();}catch{}}return}let j=f.join(process.cwd(),".openapi-spec.json");try{await u.writeFile(j,new TextEncoder().encode(JSON.stringify(P,null,2)));}catch(x){if(console.error("\x1B[31m\u274C Error saving OpenAPI spec to file:\x1B[0m",x),d){let R=l;try{await R.close?.();}catch{}}return}let A=f.resolve(process.cwd(),this.outputPath);console.log(`\u{1F528} Generating SDK...
|
|
263
|
-
`);try{await u.exists(A)||await u.mkdir(A,{recursive:!0});let x=["npx swagger-typescript-api generate",`--path="${j}"`,`--output="${this.outputPath}"`,`--http-client ${this.httpClient}`,"--modular","--extract-request-params","--extract-request-body","--extract-response-body","--extract-response-error"];this.unwrapResponseData&&x.push("--unwrap-response-data"),this.singleHttpClient&&x.push("--single-http-client"),this.typePrefix&&x.push(`--type-prefix "${this.typePrefix}"`),this.typeSuffix&&x.push(`--type-suffix "${this.typeSuffix}"`),this.enumNamesAsValues&&x.push("--enum-names-as-values"),this.sortTypes&&x.push("--sort-types");let R=x.join(" ");child_process.execSync(R,{stdio:"inherit",cwd:process.cwd()}),console.log(`
|
|
264
|
-
\x1B[32m\u2705 SDK generated successfully!\x1B[0m`),console.log(`\x1B[32m\u{1F4C1} SDK location: ${A}\x1B[0m
|
|
265
|
-
`);}catch(x){console.error("\x1B[31m\u274C Error generating SDK:\x1B[0m",x);}finally{try{await u.unlink(j);}catch{}if(d){let x=l;try{console.log("\u{1F6D1} Stopping server..."),await x.close?.(),console.log(`\u2705 Server stopped.
|
|
266
|
-
`);}catch{console.log(`\x1B[33m\u26A0\uFE0F Could not stop server gracefully.\x1B[0m
|
|
267
|
-
`);}}}console.log(`\x1B[32m\u2728 SDK generation complete!\x1B[0m
|
|
268
|
-
`);}};w([$({description:"Path to the server instance file (should export a Server instance)",required:false,defaultValue:"test/server/instance.ts"})],N,"serverPath"),w([S({description:"Output directory for generated SDK",type:"string",aliases:["o"],name:"output",required:false,defaultValue:"sdk"})],N,"outputPath"),w([S({description:"Swagger UI path on your server",type:"string",aliases:["s"],name:"swagger-path",required:false})],N,"swaggerPath"),w([S({description:"HTTP client to use (axios or fetch)",type:"string",aliases:["c"],name:"client",required:false,defaultValue:"fetch"})],N,"httpClient"),w([S({description:"Unwrap response data automatically",type:"boolean",name:"unwrap-response-data",required:false,defaultValue:false})],N,"unwrapResponseData"),w([S({description:"Generate single HTTP client instance",type:"boolean",name:"single-http-client",required:false,defaultValue:false})],N,"singleHttpClient"),w([S({description:"Add prefix to all generated types",type:"string",name:"type-prefix",required:false})],N,"typePrefix"),w([S({description:"Add suffix to all generated types",type:"string",name:"type-suffix",required:false})],N,"typeSuffix"),w([S({description:"Use enum names as values",type:"boolean",name:"enum-names-as-values",required:false,defaultValue:false})],N,"enumNamesAsValues"),w([S({description:"Sort types alphabetically",type:"boolean",name:"sort-types",required:false,defaultValue:false})],N,"sortTypes");var ie=class extends E{static commandName="init";static description="Initialize a new balda project in the current directory";static help=["Initialize a new balda project, it is given for granted that balda is installed in the project as a dependency","All the files are created in the /src directory (created if not exists)","It adds a server.ts for the file instance and a index.ts for the entry point with a dummy hello world route","Example: npx balda init -p ./src -t true"];static srcPath;static typescript;static mqtt;static cron;static graphql;static devDependencies=["esbuild","esbuild-plugin-copy","tsx","typescript"];static async handle(){this.logger.info("Initializing project...");let[e,t,r]=await G();if(["npm","yarn","pnpm"].includes(e)){let a=await pe(this.devDependencies);if(a.length&&(this.logger.info(`Found ${a.length} missing dev dependencies`),!await F(`${e} ${t} ${a.join(" ")} -${r}`,e,a,{stdio:"inherit"}))){this.logger.info("Installation cancelled by user. Project initialization aborted.");return}a.length||this.logger.info("All dev dependencies are already installed");}if(this.mqtt&&["npm","yarn","pnpm"].includes(e)){let a=await pe(["mqtt"]);a.length&&(await F(`${e} ${t} mqtt`,e,["mqtt"],{stdio:"inherit"},false)||(this.logger.info("MQTT installation cancelled by user. Skipping MQTT scaffolding."),this.mqtt=false)),a.length||this.logger.info("MQTT package is already installed");}if(this.cron&&["npm","yarn","pnpm"].includes(e)){let a=await pe(["node-cron"]);a.length>0&&(await F(`${e} ${t} node-cron`,e,["node-cron"],{stdio:"inherit"},false)||(this.logger.info("node-cron installation cancelled by user. Skipping Cron scaffolding."),this.cron=false)),a.length||this.logger.info("node-cron package is already installed");}if(this.graphql&&["npm","yarn","pnpm"].includes(e)){let a=await pe(["@apollo/server","@graphql-tools/schema","graphql"]);a.length>0&&(await F(`${e} ${t} ${a.join(" ")}`,e,a,{stdio:"inherit"},false)||(this.logger.info("GraphQL installation cancelled by user. Skipping GraphQL scaffolding."),this.graphql=false)),a.length||this.logger.info("GraphQL packages are already installed");}let s=this.typescript?"ts":"js",o=this.getServerTemplate(),n=this.getIndexTemplate();if(u.exists(this.srcPath)||await u.mkdir(this.srcPath,{recursive:true}),this.logger.info(`Creating server.${s} file...`),await u.writeFile(`${this.srcPath}/server.${s}`,new TextEncoder().encode(o)),this.logger.info(`Creating index.${s} file...`),await u.writeFile(`${this.srcPath}/index.${s}`,new TextEncoder().encode(n)),this.mqtt){let a=f.join(this.srcPath,"mqtt");await u.exists(a)||await u.mkdir(a,{recursive:true});let c=this.getMqttConfigTemplate();this.logger.info(`Creating mqtt/mqtt.config.${s} file...`),await u.writeFile(f.join(a,`mqtt.config.${s}`),new TextEncoder().encode(c));}if(this.cron){let a=f.join(this.srcPath,"cron");await u.exists(a)||await u.mkdir(a,{recursive:true});let c=this.getCronConfigTemplate();this.logger.info(`Creating cron/cron.config.${s} file...`),await u.writeFile(f.join(a,`cron.config.${s}`),new TextEncoder().encode(c));}if(this.graphql){let a=f.join(this.srcPath,"graphql");await u.exists(a)||await u.mkdir(a,{recursive:true});let c=this.getGraphqlConfigTemplate();this.logger.info(`Creating graphql/graphql.config.${s} file...`),await u.writeFile(f.join(a,`graphql.config.${s}`),new TextEncoder().encode(c));}this.logger.info("Project initialized successfully!");}static getServerTemplate(){return `import { Server } from "balda";
|
|
269
|
-
|
|
270
|
-
const serverInstance = new Server({
|
|
271
|
-
port: 80,
|
|
272
|
-
host: "0.0.0.0",
|
|
273
|
-
plugins: {
|
|
274
|
-
bodyParser: {
|
|
275
|
-
json: {
|
|
276
|
-
sizeLimit: "100kb",
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
}${this.graphql?`,
|
|
280
|
-
graphql: {
|
|
281
|
-
schema: {
|
|
282
|
-
typeDefs: \`
|
|
283
|
-
type Query {
|
|
284
|
-
hello: String
|
|
285
|
-
}
|
|
286
|
-
\`,
|
|
287
|
-
resolvers: {
|
|
288
|
-
Query: {
|
|
289
|
-
hello: () => "Hello from GraphQL!"
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}`:""}
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
export { serverInstance as server };
|
|
297
|
-
`}static getIndexTemplate(){let e=['import { server } from "./server.js";'],t=[];this.mqtt&&(e.push('import "./mqtt/mqtt.config.js";'),e.push('import { MqttService } from "balda";'),t.push(`
|
|
298
|
-
// Initialize MQTT service
|
|
299
|
-
await MqttService.connect({
|
|
300
|
-
host: "localhost",
|
|
301
|
-
port: 1883,
|
|
302
|
-
protocol: "mqtt",
|
|
303
|
-
});
|
|
304
|
-
console.log("MQTT service connected");`)),this.cron&&(e.push('import "./cron/cron.config.js";'),e.push('import { CronService } from "balda";'),t.push(`
|
|
305
|
-
// Initialize Cron service
|
|
306
|
-
await CronService.run();
|
|
307
|
-
console.log("Cron service started");`)),this.graphql&&(e.push('import "./graphql/graphql.config.js";'),t.push(`
|
|
308
|
-
// GraphQL endpoint available at /graphql
|
|
309
|
-
console.log("GraphQL service configured");`));let r=e.join(`
|
|
310
|
-
`),s=t.length>0?t.join(`
|
|
311
|
-
`):"";return `${r}
|
|
312
|
-
${s?`
|
|
313
|
-
${s}
|
|
314
|
-
`:""}
|
|
315
|
-
server.listen(({ url }) => {
|
|
316
|
-
console.log(\`Server is running on \${url}\`);
|
|
317
|
-
});
|
|
318
|
-
`}static getMqttConfigTemplate(){return `// MQTT Configuration
|
|
319
|
-
// This file is imported to set up MQTT connection options
|
|
320
|
-
// Add your MQTT handlers in separate files within this directory
|
|
321
|
-
// Use: npx balda generate-mqtt <handler-name> to create new handlers
|
|
322
|
-
`}static getCronConfigTemplate(){return `// Cron Configuration
|
|
323
|
-
// This file is imported to set up Cron jobs
|
|
324
|
-
// Add your cron jobs in separate files within this directory
|
|
325
|
-
// Use: npx balda generate-cron <job-name> to create new cron jobs
|
|
326
|
-
`}static getGraphqlConfigTemplate(){return `// GraphQL Configuration
|
|
327
|
-
// This file is imported to set up GraphQL schema and resolvers
|
|
328
|
-
// Add your GraphQL type definitions and resolvers in separate files within this directory
|
|
329
|
-
// The GraphQL endpoint is automatically available at /graphql
|
|
330
|
-
// You can extend the schema using server.graphql.addTypeDef() and server.graphql.addResolver()
|
|
331
|
-
`}};w([S.string({description:"The path to the project, default is the current directory /src",aliases:"p",name:"path",required:false,defaultValue:"./src"})],ie,"srcPath"),w([S.boolean({description:"Whether to use typescript, default is true",aliases:"t",name:"typescript",required:false,defaultValue:true})],ie,"typescript"),w([S.boolean({description:"Initialize MQTT service connection",aliases:"m",name:"mqtt",required:false,defaultValue:false})],ie,"mqtt"),w([S.boolean({description:"Initialize Cron service",aliases:"c",name:"cron",required:false,defaultValue:false})],ie,"cron"),w([S.boolean({description:"Initialize GraphQL service",aliases:"g",name:"graphql",required:false,defaultValue:false})],ie,"graphql");var Ce=class extends E{static commandName="init-mailer";static description="Initialize mailer configuration with required dependencies";static help=["Initialize a mailer configuration file with basic setup","Automatically installs required packages for nodemailer and optional template engines","Supports Handlebars, EJS, Edge.js, Mustache, or custom adapters","Example: npx balda init-mailer -t handlebars -o src/mailer"];static templateEngine;static outputPath;static mailerDependencies={base:["nodemailer","@types/nodemailer"],handlebars:["handlebars","@types/handlebars"],ejs:["ejs","@types/ejs"],edge:["edge.js"],mustache:["mustache","@types/mustache"]};static async handle(){if(this.logger.info("Initializing mailer configuration..."),!["handlebars","ejs","edge","mustache","custom","none"].includes(this.templateEngine)){this.logger.error(`Invalid template engine: ${this.templateEngine}. Must be one of: handlebars, ejs, edge, mustache, custom, none`);return}let[e,t]=await G();if(["npm","yarn","pnpm"].includes(e)){let n=[...this.mailerDependencies.base,...this.templateEngine!=="none"&&this.templateEngine!=="custom"?this.mailerDependencies[this.templateEngine]||[]:[]],a=await pe(n);if(a.length>0&&(this.logger.info(`Found ${a.length} missing dependencies for mailer`),!await F(`${e} ${t} ${a.join(" ")}`,e,a,{stdio:"inherit"},false))){this.logger.info("Installation cancelled by user. Mailer initialization aborted.");return}a.length===0&&this.logger.info("All mailer dependencies are already installed");}let r=this.getConfigTemplate(),s="mailer.config.ts",o=f.join(this.outputPath,s);await u.exists(this.outputPath)||await u.mkdir(this.outputPath,{recursive:true}),this.logger.info(`Creating ${s} file at ${this.outputPath}...`),await u.writeFile(o,new TextEncoder().encode(r)),this.logger.info(`Mailer configuration initialized successfully at ${o}`),this.logger.info("Remember to update the configuration with your actual SMTP credentials"),this.templateEngine!=="none"&&this.logger.info(`Template engine '${this.templateEngine}' configured and ready to use`);}static getConfigTemplate(){let e=this.templateEngine!=="none";return `import { createTransport } from "nodemailer";
|
|
332
|
-
import { Mailer${e?`, ${this.getAdapterImport()}`:""} } from "balda";
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Configure your email transporter
|
|
336
|
-
* For development, you can use MailCatcher (docker-compose up mailcatcher)
|
|
337
|
-
* For production, use your SMTP service (Gmail, SendGrid, AWS SES, etc.)
|
|
338
|
-
*/
|
|
339
|
-
const transporter = createTransport({
|
|
340
|
-
host: process.env.SMTP_HOST || "localhost",
|
|
341
|
-
port: parseInt(process.env.SMTP_PORT || "1025", 10),
|
|
342
|
-
secure: process.env.SMTP_SECURE === "true", // true for 465, false for other ports
|
|
343
|
-
auth: process.env.SMTP_USER && process.env.SMTP_PASSWORD
|
|
344
|
-
? {
|
|
345
|
-
user: process.env.SMTP_USER,
|
|
346
|
-
pass: process.env.SMTP_PASSWORD,
|
|
347
|
-
}
|
|
348
|
-
: undefined,
|
|
349
|
-
});
|
|
350
|
-
${this.getTemplateAdapterSetup()}
|
|
351
|
-
/**
|
|
352
|
-
* Initialize the Mailer with multiple providers (optional)
|
|
353
|
-
* You can define different providers for different purposes
|
|
354
|
-
*/
|
|
355
|
-
export const mailer = new Mailer(
|
|
356
|
-
{
|
|
357
|
-
default: {
|
|
358
|
-
transporter,${e?`
|
|
359
|
-
templateAdapter: adapter,`:""}
|
|
360
|
-
from: process.env.DEFAULT_FROM_EMAIL || "noreply@example.com",
|
|
361
|
-
},
|
|
362
|
-
// Add more providers as needed
|
|
363
|
-
// transactional: { transporter: transactionalTransporter, from: "..." },
|
|
364
|
-
// marketing: { transporter: marketingTransporter, from: "..." },
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
defaultProvider: "default",
|
|
368
|
-
}
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Example usage:
|
|
373
|
-
*
|
|
374
|
-
* // Send a simple email
|
|
375
|
-
* await mailer.send({
|
|
376
|
-
* to: "user@example.com",
|
|
377
|
-
* subject: "Welcome!",
|
|
378
|
-
* text: "Hello from Balda!",
|
|
379
|
-
* html: "<h1>Hello from Balda!</h1>",
|
|
380
|
-
* });
|
|
381
|
-
${this.getTemplateExample()}
|
|
382
|
-
* // Use a different provider
|
|
383
|
-
* await mailer.use("transactional").send({
|
|
384
|
-
* to: "user@example.com",
|
|
385
|
-
* subject: "Transaction Complete",
|
|
386
|
-
* text: "Your order has been processed",
|
|
387
|
-
* });
|
|
388
|
-
*
|
|
389
|
-
* // Verify connection
|
|
390
|
-
* const isValid = await mailer.verify();
|
|
391
|
-
* console.log("Mail provider connection:", isValid ? "OK" : "Failed");
|
|
392
|
-
*/
|
|
393
|
-
`}static getAdapterImport(){return {handlebars:"HandlebarsAdapter",ejs:"EjsAdapter",edge:"EdgeAdapter",mustache:"MustacheAdapter",custom:"CustomAdapter"}[this.templateEngine]||""}static getTemplateAdapterSetup(){return this.templateEngine==="none"?"":this.templateEngine==="handlebars"?`
|
|
394
|
-
/**
|
|
395
|
-
* Configure Handlebars template adapter
|
|
396
|
-
* Supports helpers, partials, and custom compilation options
|
|
397
|
-
*/
|
|
398
|
-
const adapter = new HandlebarsAdapter();
|
|
399
|
-
|
|
400
|
-
// Register custom helpers (optional)
|
|
401
|
-
// await adapter.registerHelper("uppercase", (str: string) => str.toUpperCase());
|
|
402
|
-
|
|
403
|
-
// Register partials (optional)
|
|
404
|
-
// await adapter.registerPartial("header", "<header>{{title}}</header>");
|
|
405
|
-
`:this.templateEngine==="ejs"?`
|
|
406
|
-
/**
|
|
407
|
-
* Configure EJS template adapter
|
|
408
|
-
* Pass custom options to the EJS compiler
|
|
409
|
-
*/
|
|
410
|
-
const adapter = new EjsAdapter({
|
|
411
|
-
// Custom EJS options (optional)
|
|
412
|
-
// cache: true,
|
|
413
|
-
// delimiter: "%",
|
|
414
|
-
});
|
|
415
|
-
`:this.templateEngine==="edge"?`
|
|
416
|
-
/**
|
|
417
|
-
* Configure Edge.js template adapter
|
|
418
|
-
* Supports global helpers and custom tags
|
|
419
|
-
*/
|
|
420
|
-
const adapter = new EdgeAdapter();
|
|
421
|
-
|
|
422
|
-
// Register globals (optional)
|
|
423
|
-
// await adapter.global("appName", "My App");
|
|
424
|
-
|
|
425
|
-
// Register custom tags (optional)
|
|
426
|
-
// await adapter.registerTag(myCustomTag);
|
|
427
|
-
`:this.templateEngine==="mustache"?`
|
|
428
|
-
/**
|
|
429
|
-
* Configure Mustache template adapter
|
|
430
|
-
* Supports partials for template composition
|
|
431
|
-
*/
|
|
432
|
-
const adapter = new MustacheAdapter();
|
|
433
|
-
|
|
434
|
-
// Register partials (optional)
|
|
435
|
-
// adapter.registerPartial("header", "<header>{{title}}</header>");
|
|
436
|
-
`:this.templateEngine==="custom"?`
|
|
437
|
-
/**
|
|
438
|
-
* Configure Custom template adapter
|
|
439
|
-
* Simple {{variable}} interpolation with helper support
|
|
440
|
-
*/
|
|
441
|
-
const adapter = new CustomAdapter();
|
|
442
|
-
|
|
443
|
-
// Register custom helpers (optional)
|
|
444
|
-
// adapter.registerHelper("uppercase", (value: unknown) =>
|
|
445
|
-
// String(value).toUpperCase()
|
|
446
|
-
// );
|
|
447
|
-
`:""}static getTemplateExample(){return this.templateEngine==="none"?"":`
|
|
448
|
-
* // Send email with template
|
|
449
|
-
* await mailer.sendWithTemplate({
|
|
450
|
-
* to: "user@example.com",
|
|
451
|
-
* subject: "Welcome {{name}}!",
|
|
452
|
-
* template: "<h1>Hello {{name}}</h1><p>Welcome to {{appName}}!</p>",
|
|
453
|
-
* data: {
|
|
454
|
-
* name: "John Doe",
|
|
455
|
-
* appName: "My App",
|
|
456
|
-
* },
|
|
457
|
-
* });
|
|
458
|
-
*`}};w([S.string({description:"Template engine (handlebars, ejs, edge, mustache, custom, none) - optional",aliases:"t",name:"template",required:false,defaultValue:"none"})],Ce,"templateEngine"),w([S.string({description:"Output directory for mailer configuration, default is src/mailer",aliases:"o",name:"output",required:false,defaultValue:"src/mailer"})],Ce,"outputPath");var qe=class extends E{static commandName="init-queue";static description="Initialize queue provider configuration with required dependencies";static help=["Initialize a queue provider configuration file with basic credentials","Automatically installs required packages for the selected provider","Only scaffolds the connection, handlers should be created with generate-queue command","Example: npx balda init-queue -t bullmq -o src/queue"];static queueType;static outputPath;static queueDependencies={bullmq:["bullmq","ioredis"],sqs:["@aws-sdk/client-sqs","sqs-consumer"],pgboss:["pg-boss","pg"]};static async handle(){if(this.logger.info(`Initializing ${this.queueType} queue provider...`),!["bullmq","sqs","pgboss"].includes(this.queueType)){this.logger.error(`Invalid queue type: ${this.queueType}. Must be one of: bullmq, sqs, pgboss`);return}let[e,t]=await G();if(["npm","yarn","pnpm"].includes(e)){let n=this.queueDependencies[this.queueType],a=await pe(n);if(a.length>0&&(this.logger.info(`Found ${a.length} missing dependencies for ${this.queueType}`),!await F(`${e} ${t} ${a.join(" ")}`,e,a,{stdio:"inherit"},false))){this.logger.info("Installation cancelled by user. Queue initialization aborted.");return}a.length===0&&this.logger.info(`All ${this.queueType} dependencies are already installed`);}let r=this.getConfigTemplate(),s=`${this.queueType}.config.ts`,o=f.join(this.outputPath,s);await u.exists(this.outputPath)||await u.mkdir(this.outputPath,{recursive:true}),this.logger.info(`Creating ${s} file at ${this.outputPath}...`),await u.writeFile(o,new TextEncoder().encode(r)),this.logger.info(`Queue configuration initialized successfully at ${o}`),this.logger.info("Remember to update the configuration with your actual credentials"),this.logger.info("Use 'npx balda generate-queue' to create queue handlers");}static getConfigTemplate(){return this.queueType==="bullmq"?this.getBullMQTemplate():this.queueType==="sqs"?this.getSQSTemplate():this.queueType==="pgboss"?this.getPGBossTemplate():""}static getBullMQTemplate(){return `import { defineBullMQConfiguration } from "balda";
|
|
459
|
-
|
|
460
|
-
// Configure BullMQ connection and default options
|
|
461
|
-
defineBullMQConfiguration({
|
|
462
|
-
connection: {
|
|
463
|
-
host: process.env.REDIS_HOST || "localhost",
|
|
464
|
-
port: parseInt(process.env.REDIS_PORT || "6379", 10),
|
|
465
|
-
password: process.env.REDIS_PASSWORD,
|
|
466
|
-
},
|
|
467
|
-
defaultJobOptions: {
|
|
468
|
-
attempts: 3,
|
|
469
|
-
backoff: {
|
|
470
|
-
type: "exponential",
|
|
471
|
-
delay: 1000,
|
|
472
|
-
},
|
|
473
|
-
},
|
|
474
|
-
errorHandler: async (job, error) => {
|
|
475
|
-
console.error(\`Job \${job.id} failed:\`, error);
|
|
476
|
-
},
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
/**
|
|
480
|
-
* Best Practice: Create a centralized queue registry
|
|
481
|
-
* Define all your queues in one place for better organization and type safety
|
|
482
|
-
*
|
|
483
|
-
* Example usage:
|
|
484
|
-
*
|
|
485
|
-
* // queues.ts
|
|
486
|
-
* import { bullmqQueue } from "balda";
|
|
487
|
-
*
|
|
488
|
-
* export const queues = {
|
|
489
|
-
* emailNotifications: bullmqQueue<{ email: string; subject: string }>("email-notifications"),
|
|
490
|
-
* orderProcessing: bullmqQueue<{ orderId: string; userId: string }>("order-processing"),
|
|
491
|
-
* };
|
|
492
|
-
*
|
|
493
|
-
* // Publish to queue
|
|
494
|
-
* await queues.emailNotifications.publish({
|
|
495
|
-
* email: "user@example.com",
|
|
496
|
-
* subject: "Welcome!"
|
|
497
|
-
* });
|
|
498
|
-
*
|
|
499
|
-
* // Subscribe with decorator
|
|
500
|
-
* import { queues } from "./queues.js";
|
|
501
|
-
*
|
|
502
|
-
* export class EmailHandler {
|
|
503
|
-
* @queues.emailNotifications.subscribe()
|
|
504
|
-
* async handle(payload: { email: string; subject: string }) {
|
|
505
|
-
* console.log("Sending email:", payload);
|
|
506
|
-
* }
|
|
507
|
-
* }
|
|
508
|
-
*
|
|
509
|
-
* // Or subscribe with callback
|
|
510
|
-
* await queues.emailNotifications.subscribe(async (payload) => {
|
|
511
|
-
* console.log("Processing:", payload);
|
|
512
|
-
* });
|
|
513
|
-
*/
|
|
514
|
-
`}static getSQSTemplate(){return `import { defineSQSConfiguration } from "balda";
|
|
515
|
-
|
|
516
|
-
// Configure SQS connection and consumer options
|
|
517
|
-
defineSQSConfiguration({
|
|
518
|
-
client: {
|
|
519
|
-
region: process.env.AWS_REGION || "us-east-1",
|
|
520
|
-
credentials: {
|
|
521
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
|
|
522
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
|
|
523
|
-
},
|
|
524
|
-
},
|
|
525
|
-
consumer: {
|
|
526
|
-
batchSize: 10,
|
|
527
|
-
visibilityTimeout: 30,
|
|
528
|
-
waitTimeSeconds: 20,
|
|
529
|
-
queueUrlMap: {
|
|
530
|
-
// Map your queue topics to SQS queue URLs
|
|
531
|
-
// Example: "user-notifications": process.env.USER_NOTIFICATIONS_QUEUE_URL || "",
|
|
532
|
-
},
|
|
533
|
-
},
|
|
534
|
-
errorHandler: (error) => {
|
|
535
|
-
console.error("SQS error:", error);
|
|
536
|
-
},
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Best Practice: Create a centralized queue registry
|
|
541
|
-
* Define all your queues in one place for better organization and type safety
|
|
542
|
-
*
|
|
543
|
-
* Example usage:
|
|
544
|
-
*
|
|
545
|
-
* // queues.ts
|
|
546
|
-
* import { sqsQueue } from "balda";
|
|
547
|
-
*
|
|
548
|
-
* export const queues = {
|
|
549
|
-
* emailNotifications: sqsQueue<{ email: string; subject: string }>(
|
|
550
|
-
* "email-notifications",
|
|
551
|
-
* { queueUrl: process.env.EMAIL_QUEUE_URL || "" }
|
|
552
|
-
* ),
|
|
553
|
-
* orderProcessing: sqsQueue<{ orderId: string; userId: string }>(
|
|
554
|
-
* "order-processing",
|
|
555
|
-
* { queueUrl: process.env.ORDER_QUEUE_URL || "" }
|
|
556
|
-
* ),
|
|
557
|
-
* };
|
|
558
|
-
*
|
|
559
|
-
* // Publish to queue
|
|
560
|
-
* await queues.emailNotifications.publish({
|
|
561
|
-
* email: "user@example.com",
|
|
562
|
-
* subject: "Welcome!"
|
|
563
|
-
* });
|
|
564
|
-
*
|
|
565
|
-
* // Subscribe with decorator
|
|
566
|
-
* import { queues } from "./queues.js";
|
|
567
|
-
*
|
|
568
|
-
* export class EmailHandler {
|
|
569
|
-
* @queues.emailNotifications.subscribe()
|
|
570
|
-
* async handle(payload: { email: string; subject: string }) {
|
|
571
|
-
* console.log("Sending email:", payload);
|
|
572
|
-
* }
|
|
573
|
-
* }
|
|
574
|
-
*
|
|
575
|
-
* // Or subscribe with callback
|
|
576
|
-
* await queues.emailNotifications.subscribe(async (payload) => {
|
|
577
|
-
* console.log("Processing:", payload);
|
|
578
|
-
* });
|
|
579
|
-
*/
|
|
580
|
-
`}static getPGBossTemplate(){return `import { definePGBossConfiguration } from "balda";
|
|
581
|
-
|
|
582
|
-
// Configure PGBoss connection
|
|
583
|
-
definePGBossConfiguration({
|
|
584
|
-
connectionString:
|
|
585
|
-
process.env.DATABASE_URL ||
|
|
586
|
-
"postgresql://user:password@localhost:5432/database",
|
|
587
|
-
errorHandler: (error) => {
|
|
588
|
-
console.error("PG-Boss error:", error);
|
|
589
|
-
},
|
|
590
|
-
});
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* Best Practice: Create a centralized queue registry
|
|
594
|
-
* Define all your queues in one place for better organization and type safety
|
|
595
|
-
*
|
|
596
|
-
* Example usage:
|
|
597
|
-
*
|
|
598
|
-
* // queues.ts
|
|
599
|
-
* import { pgbossQueue } from "balda";
|
|
600
|
-
*
|
|
601
|
-
* export const queues = {
|
|
602
|
-
* emailNotifications: pgbossQueue<{ email: string; subject: string }>("email-notifications"),
|
|
603
|
-
* orderProcessing: pgbossQueue<{ orderId: string; userId: string }>("order-processing"),
|
|
604
|
-
* };
|
|
605
|
-
*
|
|
606
|
-
* // Publish to queue
|
|
607
|
-
* await queues.emailNotifications.publish({
|
|
608
|
-
* email: "user@example.com",
|
|
609
|
-
* subject: "Welcome!"
|
|
610
|
-
* });
|
|
611
|
-
*
|
|
612
|
-
* // Subscribe with decorator
|
|
613
|
-
* import { queues } from "./queues.js";
|
|
614
|
-
*
|
|
615
|
-
* export class EmailHandler {
|
|
616
|
-
* @queues.emailNotifications.subscribe()
|
|
617
|
-
* async handle(payload: { email: string; subject: string }) {
|
|
618
|
-
* console.log("Sending email:", payload);
|
|
619
|
-
* }
|
|
620
|
-
* }
|
|
621
|
-
*
|
|
622
|
-
* // Or subscribe with callback
|
|
623
|
-
* await queues.emailNotifications.subscribe(async (payload) => {
|
|
624
|
-
* console.log("Processing:", payload);
|
|
625
|
-
* });
|
|
626
|
-
*/
|
|
627
|
-
`}};w([S.string({description:"Queue provider type (bullmq, sqs, pgboss) - required",aliases:"t",name:"type",required:true})],qe,"queueType"),w([S.string({description:"Output directory for queue configuration, default is src/queue",aliases:"o",name:"output",required:false,defaultValue:"src/queue"})],qe,"outputPath");var Ue=class extends E{static commandName="key-generate";static description="Generate application encryption key pairs";static help=["Generate secure RSA public/private key pairs for application encryption","Keys are automatically saved to .env file","Example: npx balda key-generate","Example: npx balda key-generate --type async"];static type;static async handle(){let e=this.type??"sync";if(!["sync","async"].includes(e)){this.logger.error(`Invalid key type: ${e}. Must be sync or async`);return}let{publicKey:t,privateKey:r}=po__default.default.generateKeyPairSync("rsa",{modulusLength:2048,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}}),s=e==="sync"?"APP_PUBLIC_KEY":"APP_PUBLIC_KEY_ASYNC",o=e==="sync"?"APP_PRIVATE_KEY":"APP_PRIVATE_KEY_ASYNC";console.log(`
|
|
628
|
-
\u2728 Generated ${e==="sync"?"Sync":"Async"} Key Pair:
|
|
629
|
-
`),console.log(`\x1B[33mPublic Key (${s}):\x1B[0m`),console.log(`\x1B[32m${t}\x1B[0m`),console.log(`\x1B[33mPrivate Key (${o}):\x1B[0m`),console.log(`\x1B[32m${r}\x1B[0m`),await this.saveKeyToEnvFile(s,t),await this.saveKeyToEnvFile(o,r),console.log(`\x1B[90m\u{1F4A1} Keys saved to .env file as ${s} and ${o}\x1B[0m
|
|
630
|
-
`);}static async saveKeyToEnvFile(e,t){let r=st__default.default.join(I.getCwd(),".env"),s=`${e}="${t}"`;if(Ve__default.default.existsSync(r)){let o=Ve__default.default.readFileSync(r,"utf-8"),n=new RegExp(`^${e}=.*$`,"m");if(n.test(o)){let a=o.replace(n,s);Ve__default.default.writeFileSync(r,a),this.logger.info(`Updated ${e} in .env file`);return}Ve__default.default.appendFileSync(r,`
|
|
631
|
-
${s}
|
|
632
|
-
`),this.logger.info(`Added ${e} to .env file`);return}Ve__default.default.writeFileSync(r,`${s}
|
|
633
|
-
`),this.logger.info(`Created .env file with ${e}`);}};w([S.string({aliases:["t"],name:"type",required:false,defaultValue:"sync",description:"Key type: sync or async (default: sync)"})],Ue,"type");var Je=class extends E{static commandName="list";static description="List all available commands";static help=["Display all registered Balda CLI commands with their descriptions","Example: npx balda list"];static async handle(){let e=De.getBuiltInCommands(),t=De.getUserDefinedCommands();if(console.log(`
|
|
634
|
-
\u2728 Available Balda Commands:
|
|
635
|
-
`),t.length>0){console.log(`\x1B[1;33mUser Commands:\x1B[0m
|
|
636
|
-
`);let r=this.groupByCategory(t);this.displayCategorizedCommands(r);}if(e.length>0){console.log(`\x1B[1;32mBuilt-in Commands:\x1B[0m
|
|
637
|
-
`);let r=e.sort((o,n)=>o.commandName.localeCompare(n.commandName)),s=Math.max(...r.map(o=>o.commandName.length));for(let o of r){let n=o.commandName.padEnd(s+2),a=o.description||"No description available",c="";o.options?.deprecated&&(c=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${n}\x1B[0m ${a}${c}`);}console.log("");}console.log(`\x1B[90mRun 'npx balda <command> -h' for more information on a specific command.\x1B[0m
|
|
638
|
-
`);}static groupByCategory(e){let t=new Map;for(let r of e){let s=r.options?.category||"other";t.has(s)||t.set(s,[]),t.get(s).push(r);}return t}static displayCategorizedCommands(e){let t=Array.from(e.keys()).sort();for(let r of t){let s=e.get(r).filter(c=>c&&c.commandName).sort((c,p)=>c.commandName.localeCompare(p.commandName));if(s.length===0)continue;let n={generator:"\x1B[35m",setup:"\x1B[34m",production:"\x1B[32m",utility:"\x1B[36m",other:"\x1B[37m"}[r]||"\x1B[37m";console.log(` ${n}${r.toUpperCase()}:\x1B[0m`);let a=Math.max(...s.map(c=>c.commandName.length));for(let c of s){let p=c.commandName.padEnd(a+2),l=c.description||"No description available",d="";c.options?.deprecated&&(d=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${p}\x1B[0m ${l}${d}`);}console.log("");}}};var Ee=class extends E{static commandName="queue-start";static description="Start queue workers to process jobs";static help=["Start queue workers to process jobs from registered queues","Loads queue handlers from specified patterns and starts processing","Example: npx balda queue-start","Example: npx balda queue-start src/queues/**/*.ts --patterns src/jobs/**/*.ts"];static options={keepAlive:true};static pattern;static additionalPatterns;static async handle(){this.logger.info("Starting queue workers...");let e=[this.pattern];this.additionalPatterns&&this.additionalPatterns.length>0&&e.push(...this.additionalPatterns),this.logger.info(`Loading queue handlers from patterns: ${e.join(", ")}`),await V.massiveImportQueues(e,{throwOnError:false});let t=V.typedQueueSubscribers.size,r=V.customQueueSubscribers.size,s=t+r;if(s===0){this.logger.warn("No queue handlers found. Make sure your queue handlers are decorated with @queue decorator");return}this.logger.info(`Found ${s} queue handler(s) (${t} typed, ${r} custom)`),V.run().then(()=>{this.logger.info("Queue workers started successfully. Press Ctrl+C to stop.");}).catch(o=>{this.logger.error("Error starting queue workers",o);});}};w([$({required:false,defaultValue:"src/queues/**/*.{ts,js}",description:"Primary glob pattern for queue handlers (default: src/queues/**/*.{ts,js})"})],Ee,"pattern"),w([S.list({aliases:["p"],name:"patterns",required:false,description:"Additional glob patterns for queue handlers"})],Ee,"additionalPatterns");W();var je=class extends E{static commandName="serve";static description="Run the server in dev mode with hot reload";static help=["This command is intended to be run from the root of the project","Bun and Deno have native dev hot reload","Runtime is automatically inferred","Node.js requires tsx to be installed for both typescript and javascript files","Node.js dev dependencies (tsx) are installed automatically if not detected"];static runtime=C.type;static options={keepAlive:true};static entry;static denoImportMap;static async handle(){if(this.runtime==="bun"){child_process.execSync(`bun run --watch ${this.entry}`,{stdio:"inherit",cwd:I.getCwd()});return}if(this.runtime==="deno"){let e="deno run --watch --unstable-sloppy-imports --allow-all";this.denoImportMap&&(e=`${e} --import-map ${this.denoImportMap}`),child_process.execSync(`${e} ${this.entry}`,{stdio:"inherit",cwd:I.getCwd()});return}this.handleNodeHotReload();}static async handleNodeHotReload(){if(!Ve__default.default.existsSync("node_modules/.bin/tsx")){let[r,s,o]=await G();if(!await F(`${r} ${s} tsx ${o}`,r,["tsx"],{stdio:"inherit"})){this.logger.info("Installation cancelled by user. Cannot start dev server without tsx.");return}}let t=this.calledBy!=="node"?this.calledBy:"npx";child_process.execSync(`${t} tsx watch ${this.entry}`,{stdio:"inherit",cwd:process.cwd()});}};w([$({required:false,defaultValue:"src/index.ts",description:"The entry point of the project, default is src/index.ts"})],je,"entry"),w([S.string({aliases:["d"],name:"deno-import-map",required:false,description:"Path to deno import map"})],je,"denoImportMap");var Me=class extends E{static commandName="init-storage";static description="Setup storage provider with required dependencies";static help=["Install dependencies and create storage configuration for a specific provider","Flags:"," -t, --type <provider> Storage provider type (s3, azure, local)"," -o, --output <path> Output directory for storage setup (default: src/storage/)","","Examples:"," npx balda setup:storage -t s3"," npx balda setup:storage --type azure --output src/config/"];static storageType;static outputPath;static async handle(){if(!this.storageType){console.error("\x1B[31m\u274C Error: Storage type is required. Use -t or --type flag.\x1B[0m"),console.log(`\x1B[90mExample: npx balda setup:storage -t s3\x1B[0m
|
|
639
|
-
`);return}this.outputPath||await u.mkdir(f.join(process.cwd(),this.outputPath),{recursive:true});let e=["s3","azure","local"];if(!e.includes(this.storageType)){console.error(`\x1B[31m\u274C Error: Invalid storage type '${this.storageType}'. Valid types: ${e.join(", ")}\x1B[0m
|
|
640
|
-
`);return}console.log(`
|
|
641
|
-
\u{1F680} Setting up ${this.storageType.toUpperCase()} storage provider...
|
|
642
|
-
`);let t=this.getDependencies(this.storageType);if(t.length===0&&console.log(`\x1B[32m\u2705 ${this.storageType.toUpperCase()} storage doesn't require additional dependencies.\x1B[0m
|
|
643
|
-
`),t.length){let r=await this.checkMissingDependencies(t);if(r.length===0&&console.log(`\x1B[32m\u2705 All required dependencies are already installed.\x1B[0m
|
|
644
|
-
`),r.length){let[s,o]=await G(),n=`${s} ${o} ${r.join(" ")}`;if(!await F(n,s,r,{stdio:"inherit"},false)){console.log(`\x1B[33m\u26A0\uFE0F Dependency installation skipped by user.\x1B[0m
|
|
645
|
-
`);return}console.log(`
|
|
646
|
-
\x1B[32m\u2705 Dependencies installed successfully!\x1B[0m
|
|
647
|
-
`);}}await this.createStorageSetup(this.storageType,this.outputPath),console.log(`\x1B[32m\u2728 ${this.storageType.toUpperCase()} storage setup complete!\x1B[0m
|
|
648
|
-
`);}static getDependencies(e){return {s3:["@aws-sdk/client-s3","@aws-sdk/s3-request-presigner","@aws-sdk/cloudfront-signer"],azure:["@azure/storage-blob"],local:[]}[e]||[]}static async checkMissingDependencies(e){let t=f.join(process.cwd(),"package.json");if(!await u.exists(t))return e;let s=f.join(process.cwd(),"node_modules");if(!await u.exists(s))return e;let n=[];for(let a of e){let c=f.join(s,a);await u.exists(c)||n.push(a);}return n}static async createStorageSetup(e,t){let r=f.join(process.cwd(),t);await u.exists(r)||await u.mkdir(r,{recursive:true});let o=f.join(r,"storage.ts");if(await u.exists(o)){console.log(`\x1B[33m\u26A0\uFE0F Configuration file already exists: ${o}\x1B[0m`);return}let a=this.getConfigTemplate(e);await u.writeFile(o,new TextEncoder().encode(a)),console.log(`\x1B[32m\u2705 Created configuration file: ${o}\x1B[0m`);}static getConfigTemplate(e){return {s3:`import { Storage, S3StorageProvider } from "balda";
|
|
649
|
-
|
|
650
|
-
/**
|
|
651
|
-
* S3 Storage Configuration
|
|
652
|
-
*
|
|
653
|
-
* Environment variables required:
|
|
654
|
-
* - AWS_ACCESS_KEY_ID
|
|
655
|
-
* - AWS_SECRET_ACCESS_KEY
|
|
656
|
-
* - AWS_REGION
|
|
657
|
-
* - S3_BUCKET
|
|
658
|
-
*
|
|
659
|
-
* Optional for CloudFront:
|
|
660
|
-
* - CLOUDFRONT_DOMAIN
|
|
661
|
-
* - CLOUDFRONT_KEY_PAIR_ID
|
|
662
|
-
* - CLOUDFRONT_PRIVATE_KEY
|
|
663
|
-
*/
|
|
664
|
-
|
|
665
|
-
export const storage = new Storage(
|
|
666
|
-
{
|
|
667
|
-
s3: new S3StorageProvider({
|
|
668
|
-
s3ClientConfig: {
|
|
669
|
-
bucketName: process.env.S3_BUCKET || "your-bucket-name",
|
|
670
|
-
region: process.env.AWS_REGION || "us-east-1",
|
|
671
|
-
credentials: {
|
|
672
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
|
|
673
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
|
|
674
|
-
},
|
|
675
|
-
},
|
|
676
|
-
// Uncomment to enable CloudFront signed URLs
|
|
677
|
-
// cloudfrontOptions: {
|
|
678
|
-
// domainName: process.env.CLOUDFRONT_DOMAIN || "",
|
|
679
|
-
// keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID || "",
|
|
680
|
-
// privateKey: process.env.CLOUDFRONT_PRIVATE_KEY || "",
|
|
681
|
-
// },
|
|
682
|
-
}),
|
|
683
|
-
},
|
|
684
|
-
{
|
|
685
|
-
defaultProvider: "s3",
|
|
686
|
-
},
|
|
687
|
-
);
|
|
688
|
-
`,azure:`import { Storage, AzureBlobStorageProvider } from "balda";
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
* Azure Blob Storage Configuration
|
|
692
|
-
*
|
|
693
|
-
* Environment variables required:
|
|
694
|
-
* - AZURE_STORAGE_CONNECTION_STRING
|
|
695
|
-
* - AZURE_CONTAINER_NAME
|
|
696
|
-
* - AZURE_STORAGE_ACCOUNT
|
|
697
|
-
* - AZURE_STORAGE_KEY
|
|
698
|
-
*/
|
|
699
|
-
|
|
700
|
-
export const storage = new Storage(
|
|
701
|
-
{
|
|
702
|
-
azure: new AzureBlobStorageProvider({
|
|
703
|
-
containerName: process.env.AZURE_CONTAINER_NAME || "your-container-name",
|
|
704
|
-
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING || "",
|
|
705
|
-
storageAccountName: process.env.AZURE_STORAGE_ACCOUNT || "",
|
|
706
|
-
storageAccountKey: process.env.AZURE_STORAGE_KEY || "",
|
|
707
|
-
}),
|
|
708
|
-
},
|
|
709
|
-
{
|
|
710
|
-
defaultProvider: "azure",
|
|
711
|
-
},
|
|
712
|
-
);
|
|
713
|
-
`,local:`import { Storage, LocalStorageProvider } from "balda";
|
|
714
|
-
|
|
715
|
-
/**
|
|
716
|
-
* Local Storage Configuration
|
|
717
|
-
*/
|
|
718
|
-
export const storage = new Storage(
|
|
719
|
-
{
|
|
720
|
-
local: new LocalStorageProvider({
|
|
721
|
-
directory: "./uploads",
|
|
722
|
-
}),
|
|
723
|
-
},
|
|
724
|
-
{
|
|
725
|
-
defaultProvider: "local",
|
|
726
|
-
},
|
|
727
|
-
);
|
|
728
|
-
`}[e]||""}};w([S({description:"Storage provider type (s3, azure, local)",type:"string",aliases:["t"],name:"type",required:true})],Me,"storageType"),w([S({description:"Output directory for storage setup",type:"string",aliases:["o"],name:"output",required:false,defaultValue:"src/storage/"})],Me,"outputPath");var ho=[Oe,He,xe,Re,ge,Se,Te,N,ie,Ce,qe,Je,z,je,Me,Ue,Ee,Pe],Gt=class i{commands;builtInCommands;static commandsPattern="src/commands/**/*.{ts,js}";static logger=exports.logger;constructor(){this.commands=new Map,this.builtInCommands=new Set;}static getInstance(){return new i}static setCommandsPattern(e){this.commandsPattern=e;}getCommand(e){return this.commands.get(e)??null}getCommands(){return Array.from(this.commands.values())}getBuiltInCommands(){return Array.from(this.commands.values()).filter(e=>this.builtInCommands.has(e.commandName))}getUserDefinedCommands(){return Array.from(this.commands.values()).filter(e=>!this.builtInCommands.has(e.commandName))}isBuiltInCommand(e){return this.builtInCommands.has(e)}async loadCommands(e){i.logger.info(`Loading commands from ${e}`);let t=await glob.glob(e,{absolute:true,cwd:I.getCwd()});if(t.some(r=>r.endsWith(".ts")))try{let{register:r}=await import('module');r("ts-node/esm",(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));}catch{i.logger.error("Failed to register ts-node/esm, you need to install it in your project in order to use typescript in the cli\ntry running: `npm install -D ts-node`"),process.exit(1);}for(let r of t){let s=await import(r).then(o=>o.default?o.default:o).catch(o=>(i.logger.error(`Error loading command ${r}: ${o}`),null));s&&this.commands.set(s.commandName,s);}for(let r of ho)this.commands.set(r.commandName,r),this.builtInCommands.add(r.commandName);}},De=Gt.getInstance();var ne=class extends T{constructor(e){super(`File not found: ${e}`);}};var Kr=class{constructor(e){this.options=e;}async getDownloadUrl(e,t=3600){await this.ensureClient();let r=this.containerClient.getBlockBlobClient(e),s=new Date(Date.now()-300*1e3),o=new Date(Date.now()+t*1e3),n=this.azureBlobLib.BlobSASPermissions.parse("r"),a=this.azureBlobLib.generateBlobSASQueryParameters({containerName:this.options.containerName,blobName:e,permissions:n,startsOn:s,expiresOn:o},this.sharedKeyCredential).toString();return `${r.url}?${a}`}async getUploadUrl(e,t=3600){await this.ensureClient();let r=this.containerClient.getBlockBlobClient(e),s=new Date(Date.now()-300*1e3),o=new Date(Date.now()+t*1e3),n=this.azureBlobLib.BlobSASPermissions.parse("w"),a=this.azureBlobLib.generateBlobSASQueryParameters({containerName:this.options.containerName,blobName:e,permissions:n,startsOn:s,expiresOn:o},this.sharedKeyCredential).toString();return `${r.url}?${a}`}async getPublicUrl(e){return await this.ensureClient(),this.containerClient.getBlockBlobClient(e).url}async listObjects(e){await this.ensureClient();let t=[],r=e?e.endsWith("/")?e:`${e}/`:void 0;for await(let s of this.containerClient.listBlobsFlat({prefix:r}))t.push(s.name);return t}async getObject(e,t="raw"){await this.ensureClient();try{let s=await this.containerClient.getBlockBlobClient(e).download();if(!s.readableStreamBody)throw new ne(e);let o=t;if(o==="stream")return stream.Readable.toWeb(s.readableStreamBody);let n=[];for await(let c of s.readableStreamBody)n.push(Buffer.isBuffer(c)?c:Buffer.from(c));let a=Buffer.concat(n);switch(o){case "raw":return new Uint8Array(a);case "text":return a.toString();default:throw new T("Invalid return type")}}catch(r){throw r&&typeof r=="object"&&"statusCode"in r&&r.statusCode===404?new ne(e):r}}async putObject(e,t,r){await this.ensureClient();let s=this.containerClient.getBlockBlobClient(e),o=t;await s.upload(o,o.length,{blobHTTPHeaders:{blobContentType:r||"application/octet-stream"}});}async deleteObject(e){await this.ensureClient();let t=this.containerClient.getBlockBlobClient(e);try{await t.delete();}catch(r){if(r&&typeof r=="object"&&"statusCode"in r&&r.statusCode===404)return;throw r}}async ensureClient(){if(this.azureBlobLib)return;this.azureBlobLib=await import('@azure/storage-blob').catch(()=>{throw new T("Library not installed: @azure/storage-blob, try run npm install @azure/storage-blob")}),this.blobServiceClient=this.azureBlobLib.BlobServiceClient.fromConnectionString(this.options.connectionString),this.containerClient=this.blobServiceClient.getContainerClient(this.options.containerName);let e=this.blobServiceClient.credential;if(!(e instanceof this.azureBlobLib.StorageSharedKeyCredential))throw new T("BlobStorage requires a shared key credential to generate SAS URLs");this.sharedKeyCredential=e;}};var Vr=class{constructor(e){this.options=e;}wasDirectoryEnsured=false;async getDownloadUrl(e,t=3600){throw new T("LocalStorageProvider does not support getDownloadUrl. Use S3 or Azure Blob storage for signed URLs.")}async getUploadUrl(e,t=3600){throw new T("LocalStorageProvider does not support getUploadUrl. Use S3 or Azure Blob storage for signed URLs.")}async getPublicUrl(e){throw new T("`getPublicUrl` is not available in local storage provider")}async listObjects(e){this.wasDirectoryEnsured||await this.ensureDirectoryExists();let t=f.resolve(this.options.directory),r=e?f.join(t,e):t;if(!await u.exists(r))return [];let o=[];return await this.listFilesRecursively(r,t,o),o}async getObject(e,t="raw"){this.wasDirectoryEnsured||await this.ensureDirectoryExists();let r=f.join(this.options.directory,e);if(!await u.exists(r))throw new ne(e);switch(t){case "raw":return await u.readFile(r);case "text":return await u.readFile(r,{encoding:"utf8"});case "stream":return await u.streamFile(r);default:throw new T("Invalid return type")}}async putObject(e,t,r){this.wasDirectoryEnsured||await this.ensureDirectoryExists();let s=f.join(this.options.directory,e),o=f.join(s,"..");await u.mkdir(o,{recursive:true}),await u.writeFile(s,t);}async deleteObject(e){this.wasDirectoryEnsured||await this.ensureDirectoryExists();let t=f.join(this.options.directory,e);await u.exists(t)&&await u.unlink(t);}async listFilesRecursively(e,t,r){let s=await u.stat(e);if(s.isFile){let n=e.replace(t,"").replace(/^\//,"");r.push(n);return}if(!s.isDirectory)return;let o=await this.readDirectory(e);for(let n of o){let a=f.join(e,n);await this.listFilesRecursively(a,t,r);}}async readDirectory(e){let{runtime:t}=await Promise.resolve().then(()=>(W(),Xt));switch(t.type){case "node":return await(await import('fs/promises')).readdir(e);case "bun":return await(await import('fs/promises')).readdir(e);case "deno":{let r=[];for await(let s of Deno.readDir(e))r.push(s.name);return r}default:throw new T("Unsupported runtime")}}async ensureDirectoryExists(){if(await u.exists(this.options.directory)){this.wasDirectoryEnsured=true;return}await u.mkdir(this.options.directory,{recursive:true}),this.wasDirectoryEnsured=true;}};var Jr=class{options;constructor(e){this.options=e;}async getDownloadUrl(e,t=3600){if(await this.ensureClient(),!this.options.cloudfrontOptions)throw new T("getDownloadUrl requires CloudFront configuration");let{domainName:r,keyPairId:s,privateKey:o}=this.options.cloudfrontOptions,n=`https://${r}/${e}`,a=new Date(Date.now()+t*1e3).toISOString();return this.cloudfrontSignerLib.getSignedUrl({url:n,keyPairId:s,privateKey:o,dateLessThan:a})}async getUploadUrl(e,t=3600){await this.ensureClient();let r=new this.s3Lib.PutObjectCommand({Bucket:this.options.s3ClientConfig.bucketName,Key:e});return this.s3PresignerLib.getSignedUrl(this.s3Client,r,{expiresIn:t})}async getPublicUrl(e){await this.ensureClient();let{region:t,endpoint:r}=this.options.s3ClientConfig,s=this.options.s3ClientConfig.bucketName;return r?`${typeof r=="string"?r:r.toString()}/${s}/${e}`:`https://${s}.s3.${t}.amazonaws.com/${e}`}async listObjects(e){await this.ensureClient();let t=new this.s3Lib.ListObjectsV2Command({Bucket:this.options.s3ClientConfig.bucketName,Prefix:e});return (await this.s3Client.send(t)).Contents?.map(s=>s.Key).filter(Boolean)??[]}async getObject(e,t="raw"){await this.ensureClient();let r=new this.s3Lib.GetObjectCommand({Bucket:this.options.s3ClientConfig.bucketName,Key:e});try{let s=await this.s3Client.send(r);if(!s.Body)throw new ne(e);switch(t){case "raw":return await s.Body.transformToByteArray();case "text":return await s.Body.transformToString();case "stream":return s.Body.transformToWebStream();default:throw new T("Invalid return type")}}catch(s){throw s&&typeof s=="object"&&"name"in s&&s.name==="NoSuchKey"?new ne(e):s}}async putObject(e,t,r){await this.ensureClient();let s=new this.s3Lib.PutObjectCommand({Bucket:this.options.s3ClientConfig.bucketName,Key:e,Body:t,ContentType:r});await this.s3Client.send(s);}async deleteObject(e){await this.ensureClient();let t=new this.s3Lib.DeleteObjectCommand({Bucket:this.options.s3ClientConfig.bucketName,Key:e});await this.s3Client.send(t);}async ensureClient(){this.s3Lib||(this.s3Lib=await import('@aws-sdk/client-s3').then(e=>e.default).catch(()=>{throw new T("Library not installed: @aws-sdk/client-s3, try run npm install @aws-sdk/client-s3")}),this.s3PresignerLib=await import('@aws-sdk/s3-request-presigner').then(e=>e.default).catch(()=>{throw new T("Library not installed: @aws-sdk/s3-request-presigner, try run npm install @aws-sdk/s3-request-presigner")}),this.options.cloudfrontOptions&&(this.cloudfrontSignerLib=await import('@aws-sdk/cloudfront-signer').then(e=>e.default).catch(()=>{throw new T("Library not installed: @aws-sdk/cloudfront-signer, try run npm install @aws-sdk/cloudfront-signer")})),this.s3Client=new this.s3Lib.S3Client(this.options.s3ClientConfig??{}));}};var Zr=class{providerOptions;defaultProvider;providerMap;constructor(e,t){this.providerOptions=e,this.defaultProvider=t.defaultProvider,this.providerMap=new Map(Object.entries(e).map(([r,s])=>[r,s]));}use(e){let t=this.providerMap.get(e);if(!t)throw new Error(`[Storage] Provider ${String(e)} not found`);return t}async getDownloadUrl(e,t){return this.providerOptions[this.defaultProvider].getDownloadUrl(e,t)}async getUploadUrl(e,t){return this.providerOptions[this.defaultProvider].getUploadUrl(e,t)}async getPublicUrl(e){return this.providerOptions[this.defaultProvider].getPublicUrl(e)}async listObjects(e){return this.providerOptions[this.defaultProvider].listObjects(e)}async getObject(e,t="raw"){return this.providerOptions[this.defaultProvider].getObject(e,t)}async putObject(e,t,r){return this.providerOptions[this.defaultProvider].putObject(e,t,r)}async deleteObject(e){return this.providerOptions[this.defaultProvider].deleteObject(e)}};var zt=class{async render(e,t){return await this.ensureHandlebars(),this.handlebars.compile(e)(t)}async renderFromFile(e,t){let r=await u.readFile(e,{encoding:"utf8"});return this.render(r,t)}async registerHelper(e,t){await this.ensureHandlebars(),this.handlebars.registerHelper(e,t);}async registerPartial(e,t){await this.ensureHandlebars(),this.handlebars.registerPartial(e,t);}async ensureHandlebars(){if(this.handlebars)return;let t=await import('handlebars').catch(()=>{throw new T("Library not installed: handlebars, try run npm install handlebars @types/handlebars")});this.handlebars=t.default?.default||t.default||t;}};var Wt=class{async render(e,t){return await this.ensureEdge(),this.edge.renderRaw(e,t)}async renderFromFile(e,t){return await this.ensureEdge(),this.edge.render(e,t)}async global(e,t){await this.ensureEdge(),this.edge.global(e,t);}async registerTag(e){await this.ensureEdge(),this.edge.registerTag(e);}async ensureEdge(){if(this.edge)return;let e=await import('edge.js').catch(()=>{throw new T("Library not installed: edge.js, try run npm install edge.js")}),{Edge:t}=e;this.edge=new t;}};var Kt=class{partials={};async render(e,t){return await this.ensureMustache(),this.mustache.render(e,t,this.partials)}async renderFromFile(e,t){let r=await u.readFile(e,{encoding:"utf8"});return this.render(r,t)}registerPartial(e,t){this.partials[e]=t;}async ensureMustache(){if(this.mustache)return;let e=await import('mustache').catch(()=>{throw new T("Library not installed: mustache, try run npm install mustache @types/mustache")});this.mustache=e.default||e;}};var Vt=class{options;constructor(e={}){this.options=e;}async render(e,t){return await this.ensureEjs(),this.ejs.render(e,t,this.options)}async renderFromFile(e,t){return await this.ensureEjs(),this.ejs.renderFile(e,t,this.options)}async ensureEjs(){if(this.ejs)return;let e=await import('ejs').catch(()=>{throw new T("Library not installed: ejs, try run npm install ejs @types/ejs")});this.ejs=e.default||e;}};var Jt=class{helpers=new Map;render(e,t){return e.replace(/\{\{(\w+)(?::(\w+))?\}\}/g,(r,s,o)=>{let n=t[s];return n===void 0?r:o&&this.helpers.has(o)?this.helpers.get(o)(n):String(n)})}async renderFromFile(e,t){let r=await u.readFile(e,{encoding:"utf8"});return this.render(r,t)}registerHelper(e,t){this.helpers.set(e,t);}};var Ae=class{options={};templateOptions;from(e){return this.options.from=e,this}to(e){return this.options.to=e,this}cc(e){return this.options.cc=e,this}bcc(e){return this.options.bcc=e,this}subject(e){return this.options.subject=e,this}text(e){return this.options.text=e,this}html(e){return this.options.html=e,this}template(e,t){return this.templateOptions={template:e,data:t,isFilePath:false},this}templateFile(e,t){return this.templateOptions={template:e,data:t,isFilePath:true},this}attachment(e){return this.options.attachments||(this.options.attachments=[]),this.options.attachments.push(e),this}attachments(e){return this.options.attachments||(this.options.attachments=[]),this.options.attachments.push(...e),this}hasTemplate(){return !!this.templateOptions}isTemplateFile(){return !!this.templateOptions?.isFilePath}build(){if(!this.options.to)throw new Error("[MailOptionsBuilder] 'to' field is required");if(!this.options.subject)throw new Error("[MailOptionsBuilder] 'subject' field is required");if(this.templateOptions){let{text:e,html:t,...r}=this.options;return {...r,template:this.templateOptions.template,data:this.templateOptions.data,isFilePath:this.templateOptions.isFilePath}}return this.options}},Sm=()=>new Ae;var Ze=class extends T{constructor(e){super(e),this.name="MailerError";}},Ye=class extends Ze{constructor(e){super(`[Mailer] Provider '${e}' not found`),this.name="ProviderNotFoundError";}},xt=class extends Ze{constructor(){super("[MailProvider] Template adapter not configured for this provider"),this.name="TemplateAdapterNotConfiguredError";}},Tt=class extends Ze{constructor(e){super(`[Mailer] Default provider '${e}' not found in provider options`),this.name="InvalidDefaultProviderError";}};var Rt=class{transporter;templateAdapter;defaultFrom;constructor(e){this.transporter=e.transporter,this.templateAdapter=e.templateAdapter,this.defaultFrom=e.from;}async send(e){let t=new Ae,s=e(t)??t,o=s.build();return s.hasTemplate()?this.sendWithTemplate(o):this.sendDirect(o)}async sendDirect(e){let t={...e,from:e.from||this.defaultFrom};return this.transporter.sendMail(t)}async sendWithTemplate(e){if(!this.templateAdapter)throw new xt;let t=e.isFilePath?await this.templateAdapter.renderFromFile(e.template,e.data):await this.templateAdapter.render(e.template,e.data),r={...e,html:t,from:e.from||this.defaultFrom};await this.sendDirect(r);}async verify(){return this.transporter.verify()}};var Yr=class{defaultProvider;providerMap;emailQueue=null;queueInitialized=false;constructor(e,t){if(!e[t.defaultProvider])throw new Tt(String(t.defaultProvider));this.defaultProvider=t.defaultProvider,this.providerMap=new Map(Object.keys(e).map(r=>[r,new Rt(e[r])]));}use(e){let t=this.providerMap.get(e);if(!t)throw new Ye(String(e));return t}async send(e){return this.getDefaultProvider().send(e)}async later(e){await this.initializeQueue();let t=new Ae,s=e(t)??t,o=s.build(),n=s.hasTemplate();await this.emailQueue.publish({options:o,isTemplate:n});}async initializeQueue(){this.queueInitialized||(this.emailQueue=Nt("mailer-emails"),await this.emailQueue.subscribe(async e=>{await this.processEmail(e);}),this.queueInitialized=true);}async processEmail(e){try{await this.getDefaultProvider().send(r=>{let s=e.options;if(r.to(s.to).subject(s.subject),s.from&&r.from(s.from),s.cc&&r.cc(s.cc),s.bcc&&r.bcc(s.bcc),"text"in s&&s.text&&r.text(s.text),"html"in s&&s.html&&r.html(s.html),s.attachments&&r.attachments(s.attachments),e.isTemplate){let o=s;o.isFilePath?r.templateFile(o.template,o.data):r.template(o.template,o.data);}}),await new Promise(r=>setTimeout(r,1e3));}catch(t){console.error("[Mailer] Failed to send queued email:",t);}}async verify(){return this.getDefaultProvider().verify()}getDefaultProvider(){let e=this.providerMap.get(this.defaultProvider);if(!e)throw new Ye(String(this.defaultProvider));return e}};var Xr=class{};var es=i=>(e,t)=>(r,s,o)=>{let n={scope:e,handler:t,manager:i};if(typeof s>"u"){let c=O.get(r.prototype,"__class__");return c||(c={policies:[]}),c.policies||(c.policies=[]),c.policies.push(n),O.set(r.prototype,"__class__",c),r}let a=O.get(r,s);return a||(a={policies:[]}),a.policies||(a.policies=[]),a.policies.push(n),O.set(r,s,a),o};var ts=class{providers;constructor(e){this.providers=e;}createDecorator(){return es(this)}canAccess(e,t,...r){let s=this.providers[e];if(!s)throw new T(`Policy provider for ${String(e)} not found`);return s[t](...r)}};var Hm=M,Dm=gt;
|
|
729
|
-
exports.ARG_SYMBOL=rc;exports.AzureBlobStorageProvider=Kr;exports.BaseCron=Fr;exports.BaseMqtt=Nr;exports.BasePlugin=Xr;exports.BaseQueue=Hr;exports.BullMQPubSub=yt;exports.Command=E;exports.CommandRegistry=Gt;exports.CronService=re;exports.CustomAdapter=Jt;exports.CustomTypedQueue=Ke;exports.EdgeAdapter=Wt;exports.EjsAdapter=Vt;exports.GraphQL=ee;exports.HandlebarsAdapter=zt;exports.InvalidDefaultProviderError=Tt;exports.LocalStorageProvider=Vr;exports.MailOptionsBuilder=Ae;exports.MailProvider=Rt;exports.Mailer=Yr;exports.MailerError=Ze;exports.MemoryPubSub=vt;exports.MqttService=We;exports.MustacheAdapter=Kt;exports.PGBossPubSub=wt;exports.PolicyManager=ts;exports.ProviderNotFoundError=Ye;exports.QueueManager=oe;exports.QueueService=V;exports.Request=Z;exports.Response=_;exports.S3StorageProvider=Jr;exports.SQSPubSub=bt;exports.Server=gt;exports.Storage=Zr;exports.TemplateAdapterNotConfiguredError=xt;exports.TypedQueue=he;exports.VALIDATION_ERROR_SYMBOL=we;exports.arg=$;exports.asyncLocalStorage=Bt;exports.asyncStorage=Ie;exports.baseCommands=ho;exports.bullmqQueue=oo;exports.commandRegistry=De;exports.compression=gr;exports.controller=dc;exports.cookie=yr;exports.cors=wr;exports.createExpressAdapter=Rr;exports.createPolicyDecorator=es;exports.createQueue=no;exports.cron=Ga;exports.default=Dm;exports.defineLoggerConfig=jo;exports.defineQueueConfiguration=Ip;exports.del=hc;exports.expressHandler=$s;exports.expressMiddleware=_e;exports.flag=S;exports.get=yc;exports.getContentType=$t;exports.hash=ze;exports.helmet=Or;exports.log=qr;exports.mailOptions=Sm;exports.memoryQueue=Nt;exports.methodOverride=Er;exports.middleware=Ec;exports.mountExpressRouter=ct;exports.mqtt=Yc;exports.patch=bc;exports.pgbossQueue=io;exports.post=xc;exports.put=Oc;exports.rateLimiter=jr;exports.router=Hm;exports.serialize=Qc;exports.serveStatic=sr;exports.session=Mr;exports.setCronGlobalErrorHandler=Ha;exports.setMqttGlobalErrorHandler=Zc;exports.sqsQueue=so;exports.timeout=$r;exports.trustProxy=Br;exports.validate=Nc;//# sourceMappingURL=index.cjs.map
|
|
730
|
-
//# sourceMappingURL=index.cjs.map
|