balda-js 0.0.13 → 0.0.14
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/lib/cli.d.ts +6 -0
- package/lib/cli.js +50 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.cjs +108 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +1695 -0
- package/lib/index.d.ts +1695 -0
- package/lib/index.js +108 -0
- package/lib/index.js.map +1 -0
- package/package.json +1 -1
package/lib/cli.d.ts
ADDED
package/lib/cli.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var G=Object.defineProperty;var X=Object.getOwnPropertyDescriptor;var g=(s,e,t,r)=>{for(var i=r>1?void 0:r?X(e,t):e,a=s.length-1,o;a>=0;a--)(o=s[a])&&(i=(r?o(e,t,i):o(i))||i);return r&&i&&G(e,t,i),i};var L=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")}},h=new L;var I=class{getCliArgs(){switch(h.type){case"bun":return this.getBunArgs();case"node":return this.getNodeArgs();case"deno":return Deno.args;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],i=r.split("/").pop()||r;if(!r.startsWith("-")){if(i==="yarn"&&t+1<e.length&&e[t+1]==="run"||i==="npx"&&t+1<e.length)return t+1;if(i==="yarn"||i==="pnpm")return t;if(i==="npm"&&t+1<e.length&&e[t+1]==="run"||i==="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(i)){for(let a=t+1;a<e.length;a++)if(!e[a].startsWith("-")&&/\.(js|ts|mjs|cjs)$/.test(e[a]))return a;return t}}}for(let t=e.length-1;t>=0;t--)if(!e[t].startsWith("-"))return t;return 1}},k=new I;var U=(s,e)=>{let t=Array(e.length+1).fill(null).map(()=>Array(s.length+1).fill(null));for(let r=0;r<=s.length;r++)t[0][r]=r;for(let r=0;r<=e.length;r++)t[r][0]=r;for(let r=1;r<=e.length;r++)for(let i=1;i<=s.length;i++){let a=s[i-1]===e[r-1]?0:1;t[r][i]=Math.min(t[r][i-1]+1,t[r-1][i]+1,t[r-1][i-1]+a)}return t[e.length][s.length]};var J=s=>{if(!s||s==="-"||s==="--")return null;let e=s.indexOf("=");if(e>0){let t=s.substring(0,e),r=s.substring(e+1);return{name:t,value:z(r)}}return{name:s,value:!0}},z=s=>{if(s.toLowerCase()==="true")return!0;if(s.toLowerCase()==="false")return!1;let e=Number(s);return!Number.isNaN(e)&&Number.isFinite(e)?e:s},w=()=>{let s=k.getCliArgs(),e=[],t={};if(!s||!s.length)return{args:e,flags:t};for(let r=0;r<s.length;r++){let i=s[r];if(!(!i||typeof i!="string")){if(i.startsWith("-")){let a=J(i);if(a){if(a.value===!0&&r+1<s.length){let o=s[r+1];o&&typeof o=="string"&&!o.startsWith("-")&&(a.value=z(o),r++)}t[a.name]=a.value}continue}e.push(i)}}return{args:e,flags:t}},H=(s,e)=>{if(!s||typeof s!="string"||!e||!Array.isArray(e)||e.length===0)return"";let t=s.toLowerCase().trim(),r=e.filter(o=>{let p=o.toLowerCase();if(p===t||p.includes(t)||t.includes(p))return!0;let c=U(p,t),n=Math.max(t.length,p.length)*.4;return c<=n});if(r.length===0)return"";let a=r.slice(0,3).map(o=>`\x1B[36m${o}\x1B[0m`).join(", ");return`\x1B[31m\u2717\x1B[0m Command \x1B[33m${s}\x1B[0m not found
|
|
3
|
+
\x1B[32m\u{1F4A1}\x1B[0m Did you mean: ${a}?`},R=()=>k.getCliArgs()[0]||null;var q=class{exit(e){switch(h.type){case"bun":case"node":process.exit(e);case"deno":Deno.exit(e);default:throw new Error("Unsupported runtime")}}},$=new q;import{glob as re}from"glob";import{join as K}from"path";var u=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.toString())}static clear(e){this.metadata.delete(e)}};var v="VALIDATION_ERROR";var W=w().args.slice(1),j=s=>(e,t)=>{let r=R();if(!r||r!==e.commandName)return;let i=t;u.set(e,t,{type:"arg",name:i,description:s.description});let a=W.length?W.shift():s.defaultValue;if(s.required&&!a){let o=u.get(e,v);u.set(e,v,[...o||[],{type:"arg",name:i,message:"Required argument not provided"}]);return}s.parse&&a&&(a=s.parse(a)),Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0})};import Q from"pino";var Z=()=>Q({level:"info",formatters:{level:e=>({level:e})}}),D=Z();var f=class{static commandName=this.name;static description="";static help=[];static options={keepAlive:!1};static args=w().args.slice(1);static flags=w().flags;static logger=D;static handle(){throw new Error(`Handle method not implemented in command class ${this.name}`)}static handleHelpFlag(e){let t=["-h","--help","-?","--usage"];if(!Object.keys(e).some(n=>t.includes(n)))return;let i=this.commandName,a=this.description||"No description available",o=this.help||[],p=this.options,c=this.generateHelpOutput({name:i,description:a,helpText:o,options:p,args:this.args,flags:this.flags},this);console.log(c),$.exit(0)}static generateHelpOutput=(e,t)=>{let{name:r,description:i,helpText:a,options:o,args:p,flags:c}=e,n={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=[`${n.title}${r}${n.reset}`,`${n.description}${i}${n.reset}`,"",`${n.subtitle}Usage:${n.reset}`,` ${n.code}${r}${n.reset} [options] [arguments]`,"",`${n.subtitle}Options:${n.reset}`,` ${n.flag}-h, --help${n.reset} Show this help message`,` ${n.flag}-?, --usage${n.reset} Show usage information`,"",`${n.subtitle}Command Options:${n.reset}`,` ${n.flag}keepAlive${n.reset} ${o?.keepAlive??!1?n.success+"Enabled"+n.reset:n.error+"Disabled"+n.reset}`,""];if(a){let m=Array.isArray(a)?a:[a];l.push(`${n.subtitle}Help:${n.reset}`),m.forEach(d=>{l.push(` ${n.description}${d}${n.reset}`)}),l.push("")}let S=u.getAll(t),V=Array.from(S.values()).filter(m=>m.type==="arg"),_=Array.from(S.values()).filter(m=>m.type==="flag");return V.length&&(l.push(`${n.subtitle}Available Arguments:${n.reset}`),V.forEach(m=>{let d=m.required?` ${n.error}(required)${n.reset}`:"",E=m.description?` ${n.description}${m.description}${n.reset}`:"";l.push(` ${n.code}${m.name}${n.reset}${d}${E}`)}),l.push("")),_.length&&(l.push(`${n.subtitle}Available Flags:${n.reset}`),_.forEach(m=>{m.aliases&&!Array.isArray(m.aliases)&&(m.aliases=[m.aliases]);let d=m.aliases.length?` ${n.flag}(${m.aliases.join(", ")})${n.reset}`:"",E=m.required?` ${n.error}(required)${n.reset}`:"",Y=m.description?` ${n.description}${m.description}${n.reset}`:"";l.push(` ${n.flag}--${m.name}${d}${n.reset}${E}${Y}`)}),l.push("")),((p?.length??0)>0||c&&Object.keys(c).length>0)&&(l.push(`${n.subtitle}Current Context:${n.reset}`),p?.length&&l.push(` ${n.info}Provided Arguments:${n.reset} ${n.code}${p.join(" ")}${n.reset}`),c&&Object.keys(c).length>0&&(l.push(` ${n.info}Provided Flags:${n.reset}`),Object.keys(c).forEach(m=>{let d=c[m],E=d!=null?` = ${n.code}${d}${n.reset}`:"";l.push(` ${n.flag}${m}${n.reset}${E}`)})),l.push("")),a&&(Array.isArray(a)?a.some(m=>m.includes("example")):a.includes("example"))&&(l.push(`${n.subtitle}Examples:${n.reset}`),(Array.isArray(a)?a.filter(d=>d.includes("example")):[a.split("example")[1].trim()]).forEach(d=>{l.push(` ${n.code}${d}${n.reset}`)}),l.push("")),l.join(`
|
|
4
|
+
`)};static validateContext=e=>{let t=Array.from(u.get(e,v)||[]);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((i,a)=>{let o=`${r.info}${a+1}.${r.reset}`,p=`${r.error}${i.type.toUpperCase()}${r.reset}`,c=`${r.code}${i.name}${r.reset}`;console.error(` ${o} ${p} ${c}: ${r.error}${i.message}${r.reset}`)}),console.error(""),console.error(`${r.info}\u{1F4A1} Tip: Use --help for usage information${r.reset}`),$.exit(1)}}};var A=s=>(e,t)=>{let r=R();if(!r||r!==e.commandName)return;let i=s.name||t,a=w().flags,o=s.aliases||[],p=[i,...o],c=s.defaultValue;for(let n of p){let l=[n,`-${n}`,`--${n}`];for(let S of l)if(S in a){c=a[S];break}if(c!==s.defaultValue)break}if(u.set(e,t,{type:"flag",name:i,aliases:o||[],description:s.description}),s.required&&!c){let n=u.get(e,v);u.set(e,v,[...n||[],{type:"flag",name:i,message:"Required flag not provided"}]);return}Object.defineProperty(e,t,{value:c,enumerable:!0,configurable:!0,writable:!0})};A.boolean=s=>A({...s,type:"boolean"});A.string=s=>A({...s,type:"string"});A.number=s=>A({...s,type:"number"});var b=A;var B=class{async mkdir(e,t){switch(h.type){case"bun":case"node":await(await import("fs/promises")).mkdir(e,{recursive:t?.recursive??!1});break;case"deno":await Deno.mkdir(e,{recursive:t?.recursive??!1});break}}async exists(e){switch(h.type){case"node":return(await import("fs")).existsSync(e);case"bun":return Bun.file(e).exists();case"deno":return Deno.stat(e).then(()=>!0).catch(()=>!1);default:throw new Error("Unsupported runtime")}}async readFile(e){switch(h.type){case"node":let r=await(await import("fs/promises")).readFile(e);return new Uint8Array(r);case"bun":let i=await Bun.file(e).arrayBuffer();return new Uint8Array(i);case"deno":return new Uint8Array(await Deno.readFile(e))}}async writeFile(e,t){switch(h.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(h.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 i=await Bun.file(e).stat();return{isDirectory:i.isDirectory(),isFile:i.isFile(),isSymbolicLink:i.isSymbolicLink(),size:i.size};case"deno":let a=await Deno.stat(e);return{isDirectory:a.isDirectory,isFile:a.isFile,isSymbolicLink:!1,size:a.size}}}async unlink(e){switch(h.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")}}},y=new B;var C=class extends f{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=K(this.pluginPath,`${this.pluginName}.ts`),await y.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-js";
|
|
5
|
+
|
|
6
|
+
export default class extends BasePlugin {
|
|
7
|
+
async handle(): Promise<ServerRouteMiddleware> {
|
|
8
|
+
return async (req: Request, res: Response, next: NextFunction) => {
|
|
9
|
+
console.log("${this.pluginName} plugin is running");
|
|
10
|
+
await next();
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}`}};g([j({description:"The name of the plugin to generate",required:!0})],C,"pluginName",2),g([b({description:"The path to the plugin to generate, default is src/plugins",type:"string",aliases:"p",name:"path",required:!1,defaultValue:"src/plugins"})],C,"pluginPath",2);import{join as ee}from"path";var F=class extends f{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 name;static path;static async handle(){let e=this.getCommandTemplate();this.path=ee(this.path,`${this.name}.ts`),await y.writeFile(this.path,new TextEncoder().encode(e)),this.logger.info(`Command ${this.name} created successfully at ${this.path}`)}static getCommandTemplate(){return`import { Command } from "balda-js";
|
|
14
|
+
|
|
15
|
+
export default class extends Command {
|
|
16
|
+
static commandName = "${this.name}";
|
|
17
|
+
static description = "${this.description}";
|
|
18
|
+
|
|
19
|
+
static options = {};
|
|
20
|
+
|
|
21
|
+
static async handle(): Promise<void> {
|
|
22
|
+
// Implement your command logic here
|
|
23
|
+
}
|
|
24
|
+
}`}};g([j({description:"The name of the command to generate",required:!0})],F,"name",2),g([b({description:"The path to the command to generate, default is src/commands",type:"string",aliases:"p",name:"path",required:!1,defaultValue:"src/commands"})],F,"path",2);import{join as te}from"path";var N=class extends f{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=te(this.path,`${this.fileName}.ts`),await y.writeFile(this.path,new TextEncoder().encode(e)),this.logger.info(`Cron job ${this.fileName} created successfully at ${this.path}`)}static getCronTemplate(){return`import { cron } from "balda-js";
|
|
25
|
+
|
|
26
|
+
export default class {
|
|
27
|
+
@cron("* * * * *")
|
|
28
|
+
handle() {
|
|
29
|
+
// Implement your cron job logic here
|
|
30
|
+
}
|
|
31
|
+
}`}};g([j({description:"The name of the cron job file to generate",required:!0})],N,"fileName",2),g([b({description:"The path to the cron job to generate, default is src/cron",type:"string",aliases:"p",name:"path",required:!1,defaultValue:"src/cron"})],N,"path",2);var T=class extends f{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-js 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 async handle(){let e=this.typescript?"ts":"js",t=this.getServerTemplate(),r=this.getIndexTemplate();y.exists(this.srcPath)||await y.mkdir(this.srcPath,{recursive:!0}),await y.writeFile(`${this.srcPath}/server.${e}`,new TextEncoder().encode(t)),await y.writeFile(`${this.srcPath}/index.${e}`,new TextEncoder().encode(r))}static getServerTemplate(){return`import { Server } from "balda-js";
|
|
32
|
+
|
|
33
|
+
const serverInstance = new Server({
|
|
34
|
+
port: 80,
|
|
35
|
+
host: "0.0.0.0",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export { serverInstance as server };
|
|
39
|
+
`}static getIndexTemplate(){return`import { server } from "./server";
|
|
40
|
+
|
|
41
|
+
server.listen(({ url }) => {
|
|
42
|
+
console.log(\`Server is running on \${url}\`);
|
|
43
|
+
});
|
|
44
|
+
`}};g([b.string({description:"The path to the project, default is the current directory /src",aliases:"p",name:"path",required:!1,defaultValue:"./src"})],T,"srcPath",2),g([b.boolean({description:"Whether to use typescript, default is true",aliases:"t",name:"typescript",required:!1,defaultValue:!0})],T,"typescript",2);var P=class extends f{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=O.getCommands();console.log(`
|
|
45
|
+
\u2728 Available Balda Commands:
|
|
46
|
+
`);let t=Math.max(...e.map(r=>r.commandName.length));for(let r of e){let i=r.commandName.padEnd(t+2),a=r.description||"No description available";console.log(` \x1B[36m${i}\x1B[0m ${a}`)}console.log(`
|
|
47
|
+
\x1B[90mRun 'npx balda <command> -h' for more information on a specific command.\x1B[0m
|
|
48
|
+
`)}};var x=class s{commands;static commandsPattern="commands/**/*.{ts,js}";static logger=D;constructor(){this.commands=new Map}static getInstance(){return new s}static setCommandsPattern(e){this.commandsPattern=e}getCommand(e){return this.commands.get(e)??null}getCommands(){return Array.from(this.commands.values())}async loadCommands(e){s.logger.info(`Loading commands from ${e}`);let t=await re(e);for(let i of t){let a=await import(i).then(o=>o.default?o.default:o).catch(o=>(s.logger.error(`Error loading command ${i}: ${o}`),null));a&&this.commands.set(a.commandName,a)}let r=[C,F,N,T,P];for(let i of r)this.commands.set(i.commandName,i)}},O=x.getInstance();var M=async()=>{await O.loadCommands(x.commandsPattern);let s=k.getCliArgs()[0];if(!s){console.error(`No command provided, available commands: ${O.getCommands().map(i=>i.commandName).join(", ")}`),$.exit(1);return}let e=O.getCommand(s);if(!e){console.error(H(s,O.getCommands().map(i=>i.commandName))||`Command ${s} not found`),$.exit(1);return}let t=e;t.handleHelpFlag(t.flags),t.validateContext(t),await t.handle(),(e.options?.keepAlive??!1)||$.exit(0)};typeof process<"u"?M().catch(async s=>{if(s?.message?.includes("SyntaxError")||s?.code==="ERR_UNKNOWN_FILE_EXTENSION")try{let{register:e}=await import("module");e("ts-node/esm",import.meta.url),M().catch(t=>{x.logger.error(t),process.exit(1)})}catch{x.logger.error(`Failed to register ts-node/esm, you need to install it in your project in order to use typescript in the cli
|
|
49
|
+
try running: npm install -D ts-node`),process.exit(1)}else x.logger.error(s),process.exit(1)}):M().catch(s=>{x.logger.error(s),$.exit(1)});export{M as cli};
|
|
50
|
+
//# sourceMappingURL=cli.js.map
|
package/lib/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/runtime.ts","../src/runtime/native_args.ts","../src/utils.ts","../src/commands/arg_parser.ts","../src/runtime/native_exit.ts","../src/commands/command_registry.ts","../src/commands/base_commands/generate_plugin.ts","../src/metadata_store.ts","../src/decorators/command/arg.ts","../src/logger/logger.ts","../src/commands/base_command.ts","../src/decorators/command/flag.ts","../src/runtime/native_fs.ts","../src/commands/base_commands/generate_command.ts","../src/commands/base_commands/generate_cron.ts","../src/commands/base_commands/init_command.ts","../src/commands/base_commands/list_command.ts","../src/cli.ts"],"sourcesContent":["export type RunTimeType = \"bun\" | \"node\" | \"deno\";\n\nclass RunTime {\n type: RunTimeType;\n\n constructor() {\n this.type = this.getRunTime();\n }\n\n private getRunTime(): RunTimeType {\n if (typeof Bun !== \"undefined\") {\n return \"bun\";\n } else if (typeof Deno !== \"undefined\") {\n return \"deno\";\n } else if (typeof process !== \"undefined\") {\n return \"node\";\n }\n\n throw new Error(\"No environment detected\");\n }\n}\n\nexport const runtime = new RunTime();\n","import { runtime } from \"./runtime\";\n\nclass NativeArgs {\n /**\n * Gets CLI arguments, dynamically determining where they start\n * Handles different execution contexts (direct execution, tsx, ts-node, etc.)\n */\n getCliArgs(): string[] {\n switch (runtime.type) {\n case \"bun\":\n return this.getBunArgs();\n case \"node\":\n return this.getNodeArgs();\n case \"deno\":\n return Deno.args;\n default:\n throw new Error(\"Unsupported runtime\");\n }\n }\n\n /**\n * Gets Bun arguments, handling different execution contexts\n */\n private getBunArgs(): string[] {\n const args = Bun.argv;\n const scriptIndex = this.findScriptIndex(args);\n return args.slice(scriptIndex + 1);\n }\n\n /**\n * Gets Node.js arguments, handling different execution contexts\n */\n private getNodeArgs(): string[] {\n const args = process.argv;\n const scriptIndex = this.findScriptIndex(args);\n return args.slice(scriptIndex + 1);\n }\n\n private findScriptIndex(args: string[]): number {\n if (args.length >= 3 && args[1].includes(\".bin/\")) {\n return 1;\n }\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n const argBasename = arg.split(\"/\").pop() || arg;\n\n if (arg.startsWith(\"-\")) {\n continue;\n }\n\n if (\n argBasename === \"yarn\" &&\n i + 1 < args.length &&\n args[i + 1] === \"run\"\n ) {\n return i + 1;\n }\n\n if (argBasename === \"npx\" && i + 1 < args.length) {\n return i + 1;\n }\n\n if (argBasename === \"yarn\" || argBasename === \"pnpm\") {\n return i;\n }\n\n if (\n argBasename === \"npm\" &&\n i + 1 < args.length &&\n args[i + 1] === \"run\"\n ) {\n return i + 1;\n }\n\n if (\n argBasename === \"bun\" &&\n i + 1 < args.length &&\n args[i + 1] === \"run\"\n ) {\n return i + 1;\n }\n\n if (/\\.(js|ts|mjs|cjs)$/.test(arg)) {\n return i;\n }\n\n if (/^(tsx|ts-node|node|bun)$/.test(argBasename)) {\n for (let j = i + 1; j < args.length; j++) {\n if (!args[j].startsWith(\"-\") && /\\.(js|ts|mjs|cjs)$/.test(args[j])) {\n return j;\n }\n }\n return i;\n }\n }\n\n for (let i = args.length - 1; i >= 0; i--) {\n const arg = args[i];\n if (!arg.startsWith(\"-\")) {\n return i;\n }\n }\n\n return 1;\n }\n}\n\nexport const nativeArgs = new NativeArgs();\n","/**\n * Calculates Levenshtein distance between two strings for fuzzy matching\n * @param str1 - First string\n * @param str2 - Second string\n * @returns Distance between the strings\n */\nexport const levenshteinDistance = (str1: string, str2: string): number => {\n const matrix = Array(str2.length + 1)\n .fill(null)\n .map(() => Array(str1.length + 1).fill(null));\n\n for (let i = 0; i <= str1.length; i++) {\n matrix[0][i] = i;\n }\n\n for (let j = 0; j <= str2.length; j++) {\n matrix[j][0] = j;\n }\n\n for (let j = 1; j <= str2.length; j++) {\n for (let i = 1; i <= str1.length; i++) {\n const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;\n matrix[j][i] = Math.min(\n matrix[j][i - 1] + 1,\n matrix[j - 1][i] + 1,\n matrix[j - 1][i - 1] + indicator,\n );\n }\n }\n\n return matrix[str2.length][str1.length];\n};\n","import { nativeArgs } from \"src/runtime/native_args\";\nimport { levenshteinDistance } from \"src/utils\";\n\nexport type Argument = string;\nexport type FlagSchema = Record<string, string | number | boolean>;\n\n/**\n * Parses a single flag argument\n * Supports formats: -f, --flag, -f=value, --flag=value, -f value, --flag value\n */\nconst parseFlag = (\n arg: string,\n): { name: string; value: string | number | boolean } | null => {\n if (!arg || arg === \"-\" || arg === \"--\") {\n return null;\n }\n\n const equalIndex = arg.indexOf(\"=\");\n if (equalIndex > 0) {\n const name = arg.substring(0, equalIndex);\n const value = arg.substring(equalIndex + 1);\n return {\n name,\n value: parseFlagValue(value),\n };\n }\n\n return { name: arg, value: true };\n};\n\n/**\n * Parses flag value, attempting to convert to appropriate type\n */\nconst parseFlagValue = (value: string): string | number | boolean => {\n if (value.toLowerCase() === \"true\") {\n return true;\n }\n\n if (value.toLowerCase() === \"false\") {\n return false;\n }\n\n const numValue = Number(value);\n if (!Number.isNaN(numValue) && Number.isFinite(numValue)) {\n return numValue;\n }\n\n return value;\n};\n\n/**\n * Parses CLI arguments and flags from command line input\n * Supports various flag formats: -f, --flag, -f=value, --flag=value, -f value, --flag value\n * @returns Object containing parsed arguments and flags\n */\nexport const parseCliArgsAndFlags = (): {\n args: Argument[];\n flags: FlagSchema;\n} => {\n const cliArgs = nativeArgs.getCliArgs();\n const parsedArgs: Argument[] = [];\n const parsedFlags = {} as FlagSchema;\n\n if (!cliArgs || !cliArgs.length) {\n return { args: parsedArgs, flags: parsedFlags };\n }\n\n for (let i = 0; i < cliArgs.length; i++) {\n const arg = cliArgs[i];\n\n if (!arg || typeof arg !== \"string\") {\n continue;\n }\n\n if (arg.startsWith(\"-\")) {\n const flag = parseFlag(arg);\n if (flag) {\n // Check if this is a boolean flag that might have a value in the next argument\n if (flag.value === true && i + 1 < cliArgs.length) {\n const nextArg = cliArgs[i + 1];\n if (\n nextArg &&\n typeof nextArg === \"string\" &&\n !nextArg.startsWith(\"-\")\n ) {\n flag.value = parseFlagValue(nextArg);\n i++; // Skip the next argument since we consumed it\n }\n }\n parsedFlags[flag.name] = flag.value;\n }\n continue;\n }\n\n parsedArgs.push(arg);\n }\n\n return { args: parsedArgs, flags: parsedFlags };\n};\n\n/**\n * Finds similar commands using fuzzy matching\n * @param notFoundCommand - The command that was not found\n * @param availableCommands - Array of available commands to search through\n * @returns Formatted string with suggestions or empty string if no matches\n */\nexport const findSimilarCommands = (\n notFoundCommand: string,\n availableCommands: string[],\n): string => {\n if (!notFoundCommand || typeof notFoundCommand !== \"string\") {\n return \"\";\n }\n\n if (\n !availableCommands ||\n !Array.isArray(availableCommands) ||\n availableCommands.length === 0\n ) {\n return \"\";\n }\n\n const searchTerm = notFoundCommand.toLowerCase().trim();\n\n const similarCommands = availableCommands.filter((command) => {\n const normalizedCommand = command.toLowerCase();\n\n if (normalizedCommand === searchTerm) {\n return true;\n }\n\n if (\n normalizedCommand.includes(searchTerm) ||\n searchTerm.includes(normalizedCommand)\n ) {\n return true;\n }\n\n const distance = levenshteinDistance(normalizedCommand, searchTerm);\n const maxDistance =\n Math.max(searchTerm.length, normalizedCommand.length) * 0.4; // 40% threshold\n\n return distance <= maxDistance;\n });\n\n if (similarCommands.length === 0) {\n return \"\";\n }\n\n const topSuggestions = similarCommands.slice(0, 3);\n const suggestions = topSuggestions\n .map((cmd) => `\\x1b[36m${cmd}\\x1b[0m`)\n .join(\", \");\n return `\\x1b[31m✗\\x1b[0m Command \\x1b[33m${notFoundCommand}\\x1b[0m not found\\n\\x1b[32m💡\\x1b[0m Did you mean: ${suggestions}?`;\n};\n\nexport const getCalledCommandName = (): string | null => {\n const cliArgs = nativeArgs.getCliArgs();\n return cliArgs[0] || null;\n};\n","import { runtime } from \"./runtime\";\n\nclass NativeExit {\n exit(code: number): void {\n switch (runtime.type) {\n case \"bun\":\n case \"node\":\n process.exit(code);\n case \"deno\":\n Deno.exit(code);\n default:\n throw new Error(\"Unsupported runtime\");\n }\n }\n}\n\nexport const nativeExit = new NativeExit();\n","import { glob } from \"glob\";\nimport type { Command } from \"./base_command\";\nimport GeneratePluginCommand from \"src/commands/base_commands/generate_plugin\";\nimport GenerateCommand from \"src/commands/base_commands/generate_command\";\nimport GenerateCronCommand from \"./base_commands/generate_cron\";\nimport { logger } from \"src/logger/logger\";\nimport InitCommand from \"./base_commands/init_command\";\nimport ListCommand from \"./base_commands/list_command\";\n\n/**\n * Singleton that registers all commands and provides a way to execute them.\n * Commands are loaded from the commands directory, and are expected to have a default export with the command class that extends the base command class.\n * Commands can be run both as `.js` or `.ts` files. If the file is a ts file `typescript` npm package must be installed.\n * You can use the `CommandRegistry.setCommandsPattern` method to change the pattern of the commands to load.\n * @example\n * // commands/test.ts\n * export default class TestCommand extends Command {\n * static name = \"test\";\n * async handle() {\n * console.log(\"Test command\");\n * }\n * }\n */\nexport class CommandRegistry {\n private commands: Map<string, typeof Command>;\n static commandsPattern = \"commands/**/*.{ts,js}\";\n static logger = logger;\n\n /**\n * Private constructor to prevent direct instantiation\n * @internal Not meant to be used outside by the user\n */\n private constructor() {\n this.commands = new Map();\n }\n\n static getInstance() {\n return new CommandRegistry();\n }\n\n static setCommandsPattern(pattern: string) {\n this.commandsPattern = pattern;\n }\n\n getCommand(name: string): typeof Command | null {\n return this.commands.get(name) ?? null;\n }\n\n getCommands(): (typeof Command)[] {\n return Array.from(this.commands.values());\n }\n\n async loadCommands(commandsPattern: string) {\n CommandRegistry.logger.info(`Loading commands from ${commandsPattern}`);\n const commandFiles = await glob(commandsPattern);\n\n for (const commandFile of commandFiles) {\n const command = await import(commandFile)\n .then((module) => {\n if (module.default) {\n return module.default;\n }\n\n return module;\n })\n .catch((error) => {\n CommandRegistry.logger.error(\n `Error loading command ${commandFile}: ${error}`,\n );\n return null;\n });\n\n if (command) {\n this.commands.set(command.commandName, command);\n }\n }\n\n const baseCommands = [\n GeneratePluginCommand,\n GenerateCommand,\n GenerateCronCommand,\n InitCommand,\n ListCommand,\n ];\n\n for (const command of baseCommands) {\n this.commands.set(command.commandName, command);\n }\n }\n}\n\nexport const commandRegistry = CommandRegistry.getInstance();\n","import { join } from \"node:path\";\nimport { Command } from \"src/commands/base_command\";\nimport { arg } from \"src/decorators/command/arg\";\nimport { flag } from \"src/decorators/command/flag\";\nimport { nativeFs } from \"src/runtime/native_fs\";\n\nexport default class GeneratePluginCommand extends Command {\n static commandName = \"generate-plugin\";\n static description = \"Generate a new plugin in the specified path\";\n static help = [\n \"Generate a new plugin in the specified path\",\n \"Example: npx balda generate-plugin my-plugin -p src/plugins\",\n ];\n\n @arg({\n description: \"The name of the plugin to generate\",\n required: true,\n })\n static pluginName: string;\n\n @flag({\n description: \"The path to the plugin to generate, default is src/plugins\",\n type: \"string\",\n aliases: \"p\",\n name: \"path\",\n required: false,\n defaultValue: \"src/plugins\",\n })\n static pluginPath: string;\n\n static async handle(): Promise<void> {\n const pluginTemplate = this.getPluginTemplate();\n this.pluginPath = join(this.pluginPath, `${this.pluginName}.ts`);\n await nativeFs.writeFile(\n this.pluginPath,\n new TextEncoder().encode(pluginTemplate),\n );\n\n this.logger.info(\n `Plugin ${this.name} created successfully at ${this.pluginPath}`,\n );\n }\n\n static getPluginTemplate() {\n return `import { BasePlugin, Request, Response, NextFunction, ServerRouteMiddleware } from \"balda-js\";\n\nexport default class extends BasePlugin {\n async handle(): Promise<ServerRouteMiddleware> {\n return async (req: Request, res: Response, next: NextFunction) => {\n console.log(\"${this.pluginName} plugin is running\");\n await next();\n };\n }\n}`;\n }\n}\n","/**\n * Cross-runtime metadata store used to store metadata for the decorators without using reflect-metadata\n */\nexport class MetadataStore {\n private static metadata = new WeakMap<any, Map<string | symbol, any>>();\n\n /**\n * Set the metadata for the given target and property key\n */\n static set(target: any, propertyKey: string, value: any): void {\n if (!this.metadata.has(target)) {\n this.metadata.set(target, new Map());\n }\n this.metadata.get(target)!.set(propertyKey, value);\n }\n\n /**\n * Get the metadata for the given target and property key\n */\n static get(target: any, propertyKey: string): any {\n return this.metadata.get(target)?.get(propertyKey);\n }\n\n /**\n * Get all the metadata for the given target\n */\n static getAll(target: any): Map<string | symbol, any> {\n return this.metadata.get(target) || new Map();\n }\n\n /**\n * Delete the metadata for the given target and property key\n */\n static delete(target: any, propertyKey: string | symbol): void {\n this.metadata.get(target)?.delete(propertyKey.toString());\n }\n\n /**\n * Clear all the metadata for the given target\n */\n static clear(target: any): void {\n this.metadata.delete(target);\n }\n}\n","import {\n getCalledCommandName,\n parseCliArgsAndFlags,\n} from \"src/commands/arg_parser\";\nimport type { Command } from \"src/commands/base_command\";\nimport { MetadataStore } from \"src/metadata_store\";\nimport type { ArgOptions } from \"./command_decorator_types\";\n\nexport const VALIDATION_ERROR_SYMBOL = \"VALIDATION_ERROR\";\nexport const ARG_SYMBOL = \"ARG\";\n\n/**\n * The arguments of the current command. Shifted to get the next argument each time for each argument decorator.\n */\nlet args = parseCliArgsAndFlags().args.slice(1);\n\n/**\n * Decorator to mark a field of a command class as an argument.\n * @param options - The options for the argument.\n * @warning Arguments are evaluated in the order they are defined in the Command class.\n */\nexport const arg = (options: ArgOptions) => {\n return (target: any, propertyKey: string) => {\n const currentCommandName = getCalledCommandName();\n // If the called command is not the same as the command class, skip the decorator\n if (\n !currentCommandName ||\n currentCommandName !== (target as typeof Command).commandName\n ) {\n return;\n }\n\n const argName = propertyKey;\n MetadataStore.set(target, propertyKey, {\n type: \"arg\",\n name: argName,\n description: options.description,\n });\n\n let argValue = args.length ? args.shift() : options.defaultValue;\n if (options.required && !argValue) {\n const errorChain = MetadataStore.get(target, VALIDATION_ERROR_SYMBOL);\n MetadataStore.set(target, VALIDATION_ERROR_SYMBOL, [\n ...(errorChain || []),\n {\n type: \"arg\",\n name: argName,\n message: \"Required argument not provided\",\n },\n ]);\n\n return;\n }\n\n if (options.parse && argValue) {\n argValue = options.parse(argValue);\n }\n\n Object.defineProperty(target, propertyKey, {\n value: argValue,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n };\n};\n","import pino from \"pino\";\nimport type { LoggerOptions } from \"./logger_types\";\n\nconst createBaseLogger = () => {\n const baseOptions: LoggerOptions = {\n level: \"info\",\n formatters: {\n level: (label) => {\n return { level: label };\n },\n },\n };\n\n return pino(baseOptions);\n};\n\n/**\n * The logger instance, can be overridden by the `defineLoggerConfig` function\n */\nexport let logger = createBaseLogger();\n\n/**\n * Define the logger config, this will override the logger instance with the given options\n * @param options - The logger options\n */\nexport const defineLoggerConfig = (options?: LoggerOptions) => {\n logger = pino(options);\n};\n","import { VALIDATION_ERROR_SYMBOL } from \"src/decorators/command/arg\";\nimport { MetadataStore } from \"src/metadata_store\";\nimport { nativeExit } from \"src/runtime/native_exit\";\nimport { Argument, type FlagSchema, parseCliArgsAndFlags } from \"./arg_parser\";\nimport type { CommandOptions } from \"./command_types\";\nimport { logger } from \"src/logger/logger\";\n\n/**\n * Base class for all cli commands.\n * @abstract\n */\nexport abstract class Command {\n /**\n * The name of the command.\n */\n static commandName: string = this.name;\n /**\n * The description of the command.\n */\n static description: string = \"\";\n /**\n * The help text of the command.\n */\n static help: string[] | string = [];\n /**\n * The options of the command.\n */\n static options: CommandOptions = {\n keepAlive: false,\n };\n\n /**\n * Static arguments in order to be validated by decorators. Will be fetched in the command instance.\n */\n static args: Argument[] = parseCliArgsAndFlags().args.slice(1);\n\n /**\n * Static flags in order to be validated by decorators. Will be fetched in the command instance.\n */\n static flags: FlagSchema = parseCliArgsAndFlags().flags;\n\n static readonly logger = logger;\n\n /**\n * Main entry point for the command.\n */\n static handle(): Promise<void> {\n throw new Error(\n `Handle method not implemented in command class ${this.name}`,\n );\n }\n\n /**\n * Enhanced help flag handler with rich formatting and command information\n */\n static handleHelpFlag(flags: FlagSchema): void {\n const helpFlags = [\"-h\", \"--help\", \"-?\", \"--usage\"];\n const hasHelpFlag = Object.keys(flags).some((flag) =>\n helpFlags.includes(flag),\n );\n\n if (!hasHelpFlag) {\n return;\n }\n\n const commandName = this.commandName;\n const description = this.description || \"No description available\";\n const helpText = this.help || [];\n const options = this.options;\n\n const helpOutput = this.generateHelpOutput(\n {\n name: commandName,\n description,\n helpText,\n options,\n args: this.args,\n flags: this.flags,\n },\n this,\n );\n\n console.log(helpOutput);\n nativeExit.exit(0);\n }\n\n private static readonly generateHelpOutput = (\n info: {\n name: string;\n description: string;\n helpText: string[] | string;\n options: CommandOptions;\n args: Argument[];\n flags: FlagSchema;\n },\n commandClass: any,\n ): string => {\n const { name, description, helpText, options, args, flags } = info;\n\n const colors = {\n title: \"\\x1b[1;36m\", // Bright cyan\n subtitle: \"\\x1b[1;33m\", // Bright yellow\n description: \"\\x1b[0;37m\", // White\n code: \"\\x1b[0;32m\", // Green\n flag: \"\\x1b[0;35m\", // Magenta\n reset: \"\\x1b[0m\", // Reset\n error: \"\\x1b[0;31m\", // Red\n success: \"\\x1b[0;32m\", // Green\n info: \"\\x1b[0;34m\", // Blue\n };\n\n const lines = [\n `${colors.title}${name}${colors.reset}`,\n `${colors.description}${description}${colors.reset}`,\n \"\",\n `${colors.subtitle}Usage:${colors.reset}`,\n ` ${colors.code}${name}${colors.reset} [options] [arguments]`,\n \"\",\n `${colors.subtitle}Options:${colors.reset}`,\n ` ${colors.flag}-h, --help${colors.reset} Show this help message`,\n ` ${colors.flag}-?, --usage${colors.reset} Show usage information`,\n \"\",\n `${colors.subtitle}Command Options:${colors.reset}`,\n ` ${colors.flag}keepAlive${colors.reset} ${(options?.keepAlive ?? false) ? colors.success + \"Enabled\" + colors.reset : colors.error + \"Disabled\" + colors.reset}`,\n \"\",\n ];\n\n if (helpText) {\n const helpLines = Array.isArray(helpText) ? helpText : [helpText];\n lines.push(`${colors.subtitle}Help:${colors.reset}`);\n helpLines.forEach((line) => {\n lines.push(` ${colors.description}${line}${colors.reset}`);\n });\n lines.push(\"\");\n }\n\n // Always show available arguments and flags from decorators\n const allMeta = MetadataStore.getAll(commandClass);\n const argsMeta = Array.from(allMeta.values()).filter(\n (meta) => meta.type === \"arg\",\n );\n const flagsMeta = Array.from(allMeta.values()).filter(\n (meta) => meta.type === \"flag\",\n );\n\n if (argsMeta.length) {\n lines.push(`${colors.subtitle}Available Arguments:${colors.reset}`);\n argsMeta.forEach((meta) => {\n const required = meta.required\n ? ` ${colors.error}(required)${colors.reset}`\n : \"\";\n const description = meta.description\n ? ` ${colors.description}${meta.description}${colors.reset}`\n : \"\";\n lines.push(\n ` ${colors.code}${meta.name}${colors.reset}${required}${description}`,\n );\n });\n lines.push(\"\");\n }\n\n if (flagsMeta.length) {\n lines.push(`${colors.subtitle}Available Flags:${colors.reset}`);\n flagsMeta.forEach((meta) => {\n if (meta.aliases && !Array.isArray(meta.aliases)) {\n meta.aliases = [meta.aliases];\n }\n\n const aliases = meta.aliases.length\n ? ` ${colors.flag}(${meta.aliases.join(\", \")})${colors.reset}`\n : \"\";\n const required = meta.required\n ? ` ${colors.error}(required)${colors.reset}`\n : \"\";\n const description = meta.description\n ? ` ${colors.description}${meta.description}${colors.reset}`\n : \"\";\n lines.push(\n ` ${colors.flag}--${meta.name}${aliases}${colors.reset}${required}${description}`,\n );\n });\n lines.push(\"\");\n }\n\n // Show current context if arguments or flags were provided\n if ((args?.length ?? 0) > 0 || (flags && Object.keys(flags).length > 0)) {\n lines.push(`${colors.subtitle}Current Context:${colors.reset}`);\n\n if (args?.length) {\n lines.push(\n ` ${colors.info}Provided Arguments:${colors.reset} ${colors.code}${args.join(\" \")}${colors.reset}`,\n );\n }\n\n if (flags && Object.keys(flags).length > 0) {\n lines.push(` ${colors.info}Provided Flags:${colors.reset}`);\n Object.keys(flags).forEach((flagKey) => {\n const flagValue = flags[flagKey];\n const valueDisplay =\n flagValue !== undefined && flagValue !== null\n ? ` = ${colors.code}${flagValue}${colors.reset}`\n : \"\";\n lines.push(\n ` ${colors.flag}${flagKey}${colors.reset}${valueDisplay}`,\n );\n });\n }\n lines.push(\"\");\n }\n\n if (\n helpText &&\n (Array.isArray(helpText)\n ? helpText.some((line) => line.includes(\"example\"))\n : helpText.includes(\"example\"))\n ) {\n lines.push(`${colors.subtitle}Examples:${colors.reset}`);\n const examples = Array.isArray(helpText)\n ? helpText.filter((line) => line.includes(\"example\"))\n : [helpText.split(\"example\")[1].trim()];\n examples.forEach((example) => {\n lines.push(` ${colors.code}${example}${colors.reset}`);\n });\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n };\n\n static readonly validateContext = (target: any): void => {\n const errorChain = Array.from(\n MetadataStore.get(target, VALIDATION_ERROR_SYMBOL) || [],\n ) as Array<{ type: string; name: string; message: string }>;\n\n if (errorChain.length) {\n const colors = {\n error: \"\\x1b[0;31m\", // Red\n title: \"\\x1b[1;31m\", // Bright red\n reset: \"\\x1b[0m\", // Reset\n info: \"\\x1b[0;34m\", // Blue\n code: \"\\x1b[0;32m\", // Green\n };\n\n console.error(`${colors.title}❌ Validation Errors:${colors.reset}`);\n console.error(\"\");\n\n errorChain.forEach((error, index) => {\n const errorNumber = `${colors.info}${index + 1}.${colors.reset}`;\n const errorType = `${colors.error}${error.type.toUpperCase()}${colors.reset}`;\n const errorName = `${colors.code}${error.name}${colors.reset}`;\n\n console.error(\n ` ${errorNumber} ${errorType} ${errorName}: ${colors.error}${error.message}${colors.reset}`,\n );\n });\n\n console.error(\"\");\n console.error(\n `${colors.info}💡 Tip: Use --help for usage information${colors.reset}`,\n );\n nativeExit.exit(1);\n }\n };\n}\n","import {\n getCalledCommandName,\n parseCliArgsAndFlags,\n} from \"src/commands/arg_parser\";\nimport type { Command } from \"src/commands/base_command\";\nimport { VALIDATION_ERROR_SYMBOL } from \"src/decorators/command/arg\";\nimport type {\n FlagOptions,\n FlagType,\n InferFlagType,\n} from \"src/decorators/command/command_decorator_types\";\nimport { MetadataStore } from \"src/metadata_store\";\n\nconst flagDecorator = <T extends FlagType>(options: FlagOptions<T>) => {\n return (target: any, propertyKey: string) => {\n const currentCommandName = getCalledCommandName();\n // If the called command is not the same as the command class, skip the decorator\n if (\n !currentCommandName ||\n currentCommandName !== (target as typeof Command).commandName\n ) {\n return;\n }\n\n const primaryFlagName = options.name || propertyKey;\n const parsedFlags = parseCliArgsAndFlags().flags;\n const flagAliases = options.aliases || [];\n const allFlagVariants = [primaryFlagName, ...flagAliases];\n\n // Find the actual flag value by checking all possible flag names\n let resolvedFlagValue = options.defaultValue;\n\n for (const flagVariant of allFlagVariants) {\n // Check both with and without prefixes\n const possibleNames = [\n flagVariant,\n `-${flagVariant}`,\n `--${flagVariant}`,\n ];\n\n for (const flagName of possibleNames) {\n if (flagName in parsedFlags) {\n resolvedFlagValue = parsedFlags[flagName] as InferFlagType<T>;\n break;\n }\n }\n\n if (resolvedFlagValue !== options.defaultValue) {\n break;\n }\n }\n\n MetadataStore.set(target, propertyKey, {\n type: \"flag\",\n name: primaryFlagName,\n aliases: flagAliases || [],\n description: options.description,\n });\n\n if (options.required && !resolvedFlagValue) {\n const errorChain = MetadataStore.get(target, VALIDATION_ERROR_SYMBOL);\n MetadataStore.set(target, VALIDATION_ERROR_SYMBOL, [\n ...(errorChain || []),\n {\n type: \"flag\",\n name: primaryFlagName,\n message: \"Required flag not provided\",\n },\n ]);\n return;\n }\n\n Object.defineProperty(target, propertyKey, {\n value: resolvedFlagValue,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n };\n};\n\n/** Shorthand decorator for boolean flags */\nflagDecorator.boolean = (options: Omit<FlagOptions<\"boolean\">, \"type\">) => {\n return flagDecorator({ ...options, type: \"boolean\" });\n};\n\n/** Shorthand decorator for string flags */\nflagDecorator.string = (options: Omit<FlagOptions<\"string\">, \"type\">) => {\n return flagDecorator({ ...options, type: \"string\" });\n};\n\n/** Shorthand decorator for number flags */\nflagDecorator.number = (options: Omit<FlagOptions<\"number\">, \"type\">) => {\n return flagDecorator({ ...options, type: \"number\" });\n};\n\nexport const flag = flagDecorator;\n","import { runtime } from \"./runtime\";\n\nclass NativeFs {\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n switch (runtime.type) {\n case \"bun\":\n case \"node\":\n const fs = await import(\"fs/promises\");\n await fs.mkdir(path, { recursive: options?.recursive ?? false });\n break;\n case \"deno\":\n await Deno.mkdir(path, { recursive: options?.recursive ?? false });\n break;\n }\n }\n\n async exists(path: string): Promise<boolean> {\n switch (runtime.type) {\n case \"node\":\n const fs = await import(\"fs\");\n return fs.existsSync(path);\n case \"bun\":\n return Bun.file(path).exists();\n case \"deno\":\n return Deno.stat(path)\n .then(() => true)\n .catch(() => false);\n default:\n throw new Error(\"Unsupported runtime\");\n }\n }\n\n async readFile(path: string): Promise<Uint8Array> {\n switch (runtime.type) {\n case \"node\":\n const fs = await import(\"fs/promises\");\n const buffer = await fs.readFile(path);\n return new Uint8Array(buffer);\n case \"bun\":\n const arrayBuffer = await Bun.file(path).arrayBuffer();\n return new Uint8Array(arrayBuffer);\n case \"deno\":\n return new Uint8Array(await Deno.readFile(path));\n }\n }\n\n async writeFile(path: string, data: Uint8Array): Promise<void> {\n switch (runtime.type) {\n case \"node\":\n const fs = await import(\"fs/promises\");\n await fs.writeFile(path, data);\n break;\n case \"bun\":\n await Bun.write(path, data);\n break;\n case \"deno\":\n await Deno.writeFile(path, data);\n break;\n }\n }\n\n async stat(path: string): Promise<{\n isDirectory: boolean;\n isFile: boolean;\n isSymbolicLink: boolean;\n size: number;\n }> {\n switch (runtime.type) {\n case \"node\":\n const fs = await import(\"fs/promises\");\n const stats = await fs.stat(path);\n return {\n isDirectory: stats.isDirectory(),\n isFile: stats.isFile(),\n isSymbolicLink: stats.isSymbolicLink(),\n size: stats.size,\n };\n case \"bun\":\n const bunStats = await Bun.file(path).stat();\n return {\n isDirectory: bunStats.isDirectory(),\n isFile: bunStats.isFile(),\n isSymbolicLink: bunStats.isSymbolicLink(),\n size: bunStats.size,\n };\n case \"deno\":\n const denoStats = await Deno.stat(path);\n return {\n isDirectory: denoStats.isDirectory,\n isFile: denoStats.isFile,\n isSymbolicLink: false,\n size: denoStats.size,\n };\n }\n }\n\n async unlink(path: string): Promise<void> {\n switch (runtime.type) {\n case \"node\":\n const fs = await import(\"fs/promises\");\n await fs.unlink(path);\n break;\n case \"bun\":\n await Bun.file(path).delete();\n break;\n case \"deno\":\n await Deno.remove(path);\n break;\n default:\n throw new Error(\"Unsupported runtime\");\n }\n }\n}\n\nexport const nativeFs = new NativeFs();\n","import { join } from \"node:path\";\nimport { Command } from \"src/commands/base_command\";\nimport { arg } from \"src/decorators/command/arg\";\nimport { flag } from \"src/decorators/command/flag\";\nimport { nativeFs } from \"src/runtime/native_fs\";\n\nexport default class GenerateCommand extends Command {\n static commandName = \"generate-command\";\n static description = \"Generate a new command in the specified path\";\n static help = [\n \"Generate a new cli command in the specified path\",\n \"Example: npx balda generate-command my-command -p src/commands\",\n ];\n\n @arg({\n description: \"The name of the command to generate\",\n required: true,\n })\n static name: string;\n\n @flag({\n description: \"The path to the command to generate, default is src/commands\",\n type: \"string\",\n aliases: \"p\",\n name: \"path\",\n required: false,\n defaultValue: \"src/commands\",\n })\n static path: string;\n\n static async handle(): Promise<void> {\n const commandTemplate = this.getCommandTemplate();\n this.path = join(this.path, `${this.name}.ts`);\n await nativeFs.writeFile(\n this.path,\n new TextEncoder().encode(commandTemplate),\n );\n\n this.logger.info(\n `Command ${this.name} created successfully at ${this.path}`,\n );\n }\n\n static getCommandTemplate() {\n return `import { Command } from \"balda-js\";\n\nexport default class extends Command {\n static commandName = \"${this.name}\";\n static description = \"${this.description}\";\n\n static options = {};\n\n static async handle(): Promise<void> {\n // Implement your command logic here\n }\n}`;\n }\n}\n","import { join } from \"node:path\";\nimport { Command } from \"src/commands/base_command\";\nimport { arg } from \"src/decorators/command/arg\";\nimport { flag } from \"src/decorators/command/flag\";\nimport { nativeFs } from \"src/runtime/native_fs\";\n\nexport default class GenerateCron extends Command {\n static commandName = \"generate-cron\";\n static description = \"Generate a new cron job in the specified path\";\n static help = [\n \"Generate a new cron job in the specified path\",\n \"Example: npx balda generate-cron my-cron -p src/cron\",\n ];\n\n @arg({\n description: \"The name of the cron job file to generate\",\n required: true,\n })\n static fileName: string;\n\n @flag({\n description: \"The path to the cron job to generate, default is src/cron\",\n type: \"string\",\n aliases: \"p\",\n name: \"path\",\n required: false,\n defaultValue: \"src/cron\",\n })\n static path: string;\n\n static async handle(): Promise<void> {\n const cronTemplate = this.getCronTemplate();\n this.path = join(this.path, `${this.fileName}.ts`);\n await nativeFs.writeFile(this.path, new TextEncoder().encode(cronTemplate));\n\n this.logger.info(\n `Cron job ${this.fileName} created successfully at ${this.path}`,\n );\n }\n\n static getCronTemplate() {\n return `import { cron } from \"balda-js\";\n\nexport default class {\n @cron(\"* * * * *\")\n handle() {\n // Implement your cron job logic here\n }\n}`;\n }\n}\n","import { Command } from \"src/commands/base_command\";\nimport { flag } from \"src/decorators/command/flag\";\nimport { nativeFs } from \"src/runtime/native_fs\";\n\nexport default class InitCommand extends Command {\n static commandName = \"init\";\n static description =\n \"Initialize a new balda project in the current directory\";\n static help = [\n \"Initialize a new balda project, it is given for granted that balda-js is installed in the project as a dependency\",\n \"All the files are created in the /src directory (created if not exists)\",\n \"It adds a server.ts for the file instance and a index.ts for the entry point with a dummy hello world route\",\n \"Example: npx balda init -p ./src -t true\",\n ];\n\n @flag.string({\n description:\n \"The path to the project, default is the current directory /src\",\n aliases: \"p\",\n name: \"path\",\n required: false,\n defaultValue: \"./src\",\n })\n static srcPath: string;\n\n @flag.boolean({\n description: \"Whether to use typescript, default is true\",\n aliases: \"t\",\n name: \"typescript\",\n required: false,\n defaultValue: true,\n })\n static typescript: boolean;\n\n static async handle(): Promise<void> {\n const ext = this.typescript ? \"ts\" : \"js\";\n const serverTemplate = this.getServerTemplate();\n const indexTemplate = this.getIndexTemplate();\n\n if (!nativeFs.exists(this.srcPath)) {\n await nativeFs.mkdir(this.srcPath, { recursive: true });\n }\n\n await nativeFs.writeFile(\n `${this.srcPath}/server.${ext}`,\n new TextEncoder().encode(serverTemplate),\n );\n\n await nativeFs.writeFile(\n `${this.srcPath}/index.${ext}`,\n new TextEncoder().encode(indexTemplate),\n );\n }\n\n static getServerTemplate() {\n return `import { Server } from \"balda-js\";\n\nconst serverInstance = new Server({\n port: 80,\n host: \"0.0.0.0\",\n});\n\nexport { serverInstance as server };\n`;\n }\n\n static getIndexTemplate() {\n return `import { server } from \"./server\";\n\nserver.listen(({ url }) => {\n console.log(\\`Server is running on \\${url}\\`);\n});\n`;\n }\n}\n","import { Command } from \"src/commands/base_command\";\nimport { commandRegistry } from \"src/commands/command_registry\";\n\nexport default class ListCommand extends Command {\n static commandName = \"list\";\n static description = \"List all available commands\";\n static help = [\n \"Display all registered Balda CLI commands with their descriptions\",\n \"Example: npx balda list\",\n ];\n\n static async handle(): Promise<void> {\n const commands = commandRegistry.getCommands();\n\n console.log(\"\\n✨ Available Balda Commands:\\n\");\n\n const maxNameLength = Math.max(\n ...commands.map((cmd) => cmd.commandName.length),\n );\n\n for (const command of commands) {\n const name = command.commandName.padEnd(maxNameLength + 2);\n const desc = command.description || \"No description available\";\n console.log(` \\x1b[36m${name}\\x1b[0m ${desc}`);\n }\n\n console.log(\n \"\\n\\x1b[90mRun 'npx balda <command> -h' for more information on a specific command.\\x1b[0m\\n\",\n );\n }\n}\n","import { findSimilarCommands } from \"src/commands/arg_parser\";\nimport type { Command } from \"src/commands/base_command\";\nimport { nativeArgs } from \"src/runtime/native_args\";\nimport { nativeExit } from \"src/runtime/native_exit\";\nimport { CommandRegistry, commandRegistry } from \"./commands/command_registry\";\n\n/**\n * CLI entry point\n */\nexport const cli = async () => {\n await commandRegistry.loadCommands(CommandRegistry.commandsPattern);\n const commandName = nativeArgs.getCliArgs()[0];\n\n if (!commandName) {\n console.error(\n `No command provided, available commands: ${commandRegistry\n .getCommands()\n .map((command) => command.commandName)\n .join(\", \")}`,\n );\n nativeExit.exit(1);\n return;\n }\n\n const CommandClass = commandRegistry.getCommand(commandName);\n if (!CommandClass) {\n console.error(\n findSimilarCommands(\n commandName,\n commandRegistry.getCommands().map((command) => command.commandName),\n ) || `Command ${commandName} not found`,\n );\n\n nativeExit.exit(1);\n return;\n }\n\n const commandClass = CommandClass as unknown as typeof Command;\n // Check if the command has the help flag\n commandClass.handleHelpFlag(commandClass.flags);\n\n // Validate the command context\n commandClass.validateContext(commandClass);\n\n // Handle the command\n await commandClass.handle();\n\n // Exit the process if the command is not keepAlive\n const keepAlive =\n (CommandClass as unknown as typeof Command).options?.keepAlive ?? false;\n if (!keepAlive) {\n nativeExit.exit(0);\n }\n};\n\nif (typeof process !== \"undefined\") {\n // Try to run CLI without ts-node first\n cli().catch(async (err) => {\n if (\n err?.message?.includes(\"SyntaxError\") ||\n err?.code === \"ERR_UNKNOWN_FILE_EXTENSION\"\n ) {\n try {\n const { register } = await import(\"node:module\");\n register(\"ts-node/esm\", import.meta.url);\n cli().catch((retryErr) => {\n CommandRegistry.logger.error(retryErr);\n process.exit(1);\n });\n } catch (registerErr) {\n CommandRegistry.logger.error(\n `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`,\n );\n process.exit(1);\n }\n } else {\n CommandRegistry.logger.error(err);\n process.exit(1);\n }\n });\n} else {\n cli().catch((err) => {\n CommandRegistry.logger.error(err);\n nativeExit.exit(1);\n });\n}\n"],"mappings":"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","names":["RunTime","runtime","NativeArgs","runtime","args","scriptIndex","i","arg","argBasename","j","nativeArgs","levenshteinDistance","str1","str2","matrix","i","j","indicator","parseFlag","arg","equalIndex","name","value","parseFlagValue","numValue","parseCliArgsAndFlags","cliArgs","nativeArgs","parsedArgs","parsedFlags","i","flag","nextArg","findSimilarCommands","notFoundCommand","availableCommands","searchTerm","similarCommands","command","normalizedCommand","distance","levenshteinDistance","maxDistance","suggestions","cmd","getCalledCommandName","NativeExit","code","runtime","nativeExit","glob","join","MetadataStore","target","propertyKey","value","VALIDATION_ERROR_SYMBOL","args","parseCliArgsAndFlags","arg","options","target","propertyKey","currentCommandName","getCalledCommandName","argName","MetadataStore","argValue","errorChain","VALIDATION_ERROR_SYMBOL","pino","createBaseLogger","label","logger","Command","parseCliArgsAndFlags","logger","flags","helpFlags","flag","commandName","description","helpText","options","helpOutput","nativeExit","info","commandClass","name","args","colors","lines","helpLines","line","allMeta","MetadataStore","argsMeta","meta","flagsMeta","required","aliases","flagKey","flagValue","valueDisplay","example","target","errorChain","VALIDATION_ERROR_SYMBOL","error","index","errorNumber","errorType","errorName","flagDecorator","options","target","propertyKey","currentCommandName","getCalledCommandName","primaryFlagName","parsedFlags","parseCliArgsAndFlags","flagAliases","allFlagVariants","resolvedFlagValue","flagVariant","possibleNames","flagName","MetadataStore","errorChain","VALIDATION_ERROR_SYMBOL","flag","NativeFs","path","options","runtime","buffer","arrayBuffer","data","stats","bunStats","denoStats","nativeFs","GeneratePluginCommand","Command","pluginTemplate","join","nativeFs","__decorateClass","arg","flag","join","GenerateCommand","Command","commandTemplate","join","nativeFs","__decorateClass","arg","flag","join","GenerateCron","Command","cronTemplate","join","nativeFs","__decorateClass","arg","flag","InitCommand","Command","ext","serverTemplate","indexTemplate","nativeFs","__decorateClass","flag","ListCommand","Command","commands","commandRegistry","maxNameLength","cmd","command","name","desc","CommandRegistry","_CommandRegistry","logger","pattern","name","commandsPattern","commandFiles","glob","commandFile","command","module","error","baseCommands","GeneratePluginCommand","GenerateCommand","GenerateCron","InitCommand","ListCommand","commandRegistry","cli","commandRegistry","CommandRegistry","commandName","nativeArgs","command","nativeExit","CommandClass","findSimilarCommands","commandClass","err","register","retryErr"]}
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";var tt=Object.create;var J=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var ot=Object.getOwnPropertyNames;var st=Object.getPrototypeOf,nt=Object.prototype.hasOwnProperty;var it=(o,e)=>{for(var t in e)J(o,t,{get:e[t],enumerable:!0})},He=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ot(e))!nt.call(o,s)&&s!==t&&J(o,s,{get:()=>e[s],enumerable:!(r=rt(e,s))||r.enumerable});return o};var O=(o,e,t)=>(t=o!=null?tt(st(o)):{},He(e||!o||!o.__esModule?J(t,"default",{value:o,enumerable:!0}):t,o)),at=o=>He(J({},"__esModule",{value:!0}),o);var jt={};it(jt,{BasePlugin:()=>Ee,Request:()=>x,Response:()=>P,Server:()=>Me,controller:()=>dt,cookie:()=>fe,cors:()=>Re,del:()=>pt,fileParser:()=>be,get:()=>ut,getContentType:()=>Y,helmet:()=>Oe,json:()=>xe,log:()=>he,middleware:()=>ft,patch:()=>ct,post:()=>lt,put:()=>mt,rateLimiter:()=>ye,router:()=>Ut,serveStatic:()=>me,session:()=>ge,timeout:()=>ve,trustProxy:()=>we,urlencoded:()=>Se,validate:()=>ht});module.exports=at(jt);var Ae=require("path");var f=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.toString())}static clear(e){this.metadata.delete(e)}};var D=class{staticChildren;paramChild;wildcardChild;middleware;handler;constructor(){this.staticChildren=new Map,this.paramChild=null,this.wildcardChild=null,this.middleware=null,this.handler=null}},de=class o{trees;routes;middlewares;basePath;constructor(e="",t=[]){this.trees=new Map,this.routes=[],this.middlewares=t,this.basePath=this.normalizeBasePath(e)}getRoutes(){return this.routes.slice()}addOrUpdate(e,t,r,s,n){e=e.toUpperCase();let i=this.trees.get(e);i||(i=new D,this.trees.set(e,i));let a=t.split("?")[0].replace(/^\/+|\/+$/g,""),p=a.length===0?[]:a.split("/"),u=i;for(let m of p){if(m==="*"){u.wildcardChild||(u.wildcardChild=new D),u=u.wildcardChild;break}if(m.startsWith(":")){let h=m.slice(1);u.paramChild||(u.paramChild={node:new D,name:h}),u=u.paramChild.node;continue}u.staticChildren.has(m)||u.staticChildren.set(m,new D),u=u.staticChildren.get(m)}u.middleware=r,u.handler=s;let c=this.routes.findIndex(m=>m.method===e&&m.path===t);if(c!==-1){this.routes[c].middleware=r,this.routes[c].handler=s;return}this.routes.push({method:e,path:t,middleware:r,handler:s,swaggerOptions:n})}find(e,t){e=e.toUpperCase();let r=this.trees.get(e);if(!r)return null;let n=t.split("?")[0].replace(/^\/+|\/+$/g,""),i=n.length===0?[]:n.split("/"),d={},a=r;for(let p=0;p<i.length;p++){let u=i[p];if(a.staticChildren.has(u)){a=a.staticChildren.get(u);continue}if(a.paramChild){d[a.paramChild.name]=u,a=a.paramChild.node;continue}if(a.wildcardChild){d["*"]=i.slice(p).join("/"),a=a.wildcardChild;break}return null}return!a.handler||!a.middleware?null:{middleware:a.middleware,handler:a.handler,params:d}}get(e,t,r,s){let n=this.joinPath(e),i=typeof t=="function"&&t.length!==3,d=i?t:r,a=i?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...a],u=i?r:s;this.addOrUpdate("GET",n,p,d,u)}post(e,t,r,s){let n=this.joinPath(e),i=typeof t=="function"&&t.length!==3,d=i?t:r,a=i?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...a],u=i?r:s;this.addOrUpdate("POST",n,p,d,u)}patch(e,t,r,s){let n=this.joinPath(e),i=typeof t=="function"&&t.length!==3,d=i?t:r,a=i?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...a],u=i?r:s;this.addOrUpdate("PATCH",n,p,d,u)}put(e,t,r,s){let n=this.joinPath(e),i=typeof t=="function"&&t.length!==3,d=i?t:r,a=i?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...a],u=i?r:s;this.addOrUpdate("PUT",n,p,d,u)}delete(e,t,r,s){let n=this.joinPath(e),i=typeof t=="function"&&t.length!==3,d=i?t:r,a=i?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...a],u=i?r:s;this.addOrUpdate("DELETE",n,p,d,u)}options(e,t,r,s){let n=this.joinPath(e),i=typeof t=="function"&&t.length!==3,d=i?t:r,a=i?[]:Array.isArray(t)?t:[t],p=[...this.middlewares,...a],u=i?r:s;this.addOrUpdate("OPTIONS",n,p,d,u)}group(e,t,r){let s=Array.isArray(t)?t:typeof t=="function"?[]:t?[t]:[],n=Array.isArray(t)?r:typeof t=="function"?t:void 0,i=this.joinPath(e),d=new o(i,[...this.middlewares,...s]);n?.(d);for(let a of d.getRoutes())this.addOrUpdate(a.method,a.path,a.middleware,a.handler,a.swaggerOptions)}applyGlobalMiddlewaresToAllRoutes(e){for(let t of this.routes)this.addOrUpdate(t.method,t.path,[...e,...t.middleware||[]],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}},l=new de;var dt=(o,e)=>t=>{let s=f.get(t.prototype,"__class__")?.middlewares||[],n=f.getAll(t.prototype);for(let[i,d]of n.entries()){if(!d.route)continue;let a=t.prototype[i],p=o?(0,Ae.join)(o,d.route.path):d.route.path,u=[...s,...d.middlewares||[]];l.addOrUpdate(d.route.method,p,u,a,{service:t.name.replace(/Controller$/,""),...e,...d.documentation})}f.clear(t.prototype)};var pt=(o,e)=>(t,r,s)=>{let n=f.get(t,r);return n||(n={middlewares:[],route:{path:o,method:"DELETE"}}),n.documentation={...n.documentation||{},name:r,...e},n.route={path:o,method:"DELETE"},f.set(t,r,n),s};var ut=(o,e)=>(t,r,s)=>{let n=f.get(t,r);return n||(n={middlewares:[],route:{path:o,method:"GET"}}),n.documentation={...n.documentation||{},name:r,...e},n.route={path:o,method:"GET"},f.set(t,r,n),s};var ct=(o,e)=>(t,r,s)=>{let n=f.get(t,r);return n||(n={middlewares:[],route:{path:o,method:"PATCH"}}),n.documentation={...n.documentation||{},name:r,...e},n.route={path:o,method:"PATCH"},f.set(t,r,n),s};var lt=(o,e)=>(t,r,s)=>{let n=f.get(t,r);return n||(n={middlewares:[],route:{path:o,method:"POST"}}),n.documentation={...n.documentation||{},name:r,...e},n.route={path:o,method:"POST"},f.set(t,r,n),s};var mt=(o,e)=>(t,r,s)=>{let n=f.get(t,r);return n||(n={middlewares:[],route:{path:o,method:"PUT"}}),n.documentation={...n.documentation||{},name:r,...e},n.route={path:o,method:"PUT"},f.set(t,r,n),s};var ft=o=>(e,t,r)=>{if(typeof t>"u"){let n=f.get(e.prototype,"__class__");if(n||(n={middlewares:[]}),n.middlewares||(n.middlewares=[]),!o)throw new Error(`Middleware ${String(o)} not found, are you sure you defined it before using it?`);return Array.isArray(o)||(o=[o]),n.middlewares.push(...o),f.set(e.prototype,"__class__",n),e}let s=f.get(e,t);return s||(s={middlewares:[]}),s.middlewares||(s.middlewares=[]),Array.isArray(o)||(o=[o]),s.middlewares.push(...o),f.set(e,t,s),r};var ke=require("ajv");var A=o=>(e,t,r)=>{let s=r.value,n=f.get(e,t);return n||(n={middlewares:[],route:{}}),n.documentation||(n.documentation={}),o.body&&(n.documentation.requestBody=o.body),o.query&&(n.documentation.query=o.query),f.set(e,t,n),r.value=async function(...i){let d=i[0],a=i[1];try{let p,u,c;o.body&&(p=d.validate(o.body,o.safe)),o.query&&(u=d.validateQuery(o.query,o.safe)),o.all&&(c=d.validateAll(o.all,o.safe));let m=[...i];return p!==void 0&&m.push(p),u!==void 0&&m.push(u),c!==void 0&&m.push(c),s.apply(this,m)}catch(p){if(!(p instanceof ke.ValidationError))throw p;return o.customError?a.status(o.customError.status||400).json({received:d.body,schema:o.body,error:p.errors}):a.badRequest(p)}},r};A.query=(o,e)=>A({query:o,customError:e});A.body=(o,e)=>A({body:o,customError:e});A.all=(o,e)=>A({all:o,customError:e});var ht=A;var _=require("@sinclair/typebox");var V=O(require("ajv"),1),_e=O(require("ajv-formats"),1),yt=(0,_e.default)(new V.default,["date-time","time","date","email","hostname","ipv4","ipv6","uri","uri-reference","uuid","uri-template","json-pointer","relative-json-pointer","regex","password","binary","byte","iso-date-time","iso-time"]),k=(o,e,t=!1)=>{let r=yt.compile(o);if(!r(e)){if(t)return e;throw new V.ValidationError(r.errors||[])}return e};var W=class extends Request{};var Fe=require("crypto"),x=class o extends W{static fromRequest(e){return new o(e.url,{method:e.method,body:e.body,headers:e.headers})}static enrichRequest(e){return e.validate=(t,r=!1)=>(typeof t=="function"&&(t=t(_.Type)),k(t,e.body||{},r)),e.validateQuery=(t,r=!1)=>(typeof t=="function"&&(t=t(_.Type)),k(t,e.query||{},r)),e.validateAll=(t,r=!1)=>(typeof t=="function"&&(t=t(_.Type)),k(t,{...e.body?{body:e.body}:{},...e.query?{query:e.query}:{}},r)),e.file=t=>e.files.find(r=>r.formName===t)??null,e.files=[],e.saveSession=async()=>{},e.destroySession=async()=>{},e.session={},e.cookies={},e.cookie=t=>e.cookies[t],e}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={};query={};get id(){return this._id||(this._id=(0,Fe.randomUUID)()),this._id}body;validate(e,t=!1){return typeof e=="function"&&(e=e(_.Type)),k(e,this.body||{},t)}validateQuery(e,t=!1){return typeof e=="function"&&(e=e(_.Type)),k(e,this.query||{},t)}validateAll(e,t=!1){return typeof e=="function"&&(e=e(_.Type)),k(e,{...this.body?{body:this.body}:{},...this.query?{query:this.query}:{}},t)}};var pe=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")}},y=new pe;var $e=O(require("fs/promises"),1),ue=class{file(e){switch(y.type){case"bun":return Bun.file(e);case"node":return $e.default.readFile(e);case"deno":return Deno.readFile(e);default:throw new Error("Unsupported runtime")}}},K=new ue;var U=require("path");var g=o=>({name:o.constructor.name,cause:o.cause,message:o.message,stack:o.stack});var R=class extends Error{constructor(e){super(e)}};var X=class extends R{constructor(e,t){super(`METHOD_NOT_ALLOWED: Cannot ${t} ${e}`)}};var w=class extends R{constructor(e,t){super(`ROUTE_NOT_FOUND: Cannot ${t} ${e}`)}};var De=new Map([[".html","text/html"],[".css","text/css"],[".js","application/javascript"],[".png","image/png"],[".jpg","image/jpeg"],[".gif","image/gif"],[".svg","image/svg+xml"],[".json","application/json"],[".txt","text/plain"],[".ico","image/x-icon"],[".webp","image/webp"],[".mp4","video/mp4"],[".mp3","audio/mpeg"],[".wav","audio/wav"],[".ogg","audio/ogg"],[".webm","video/webm"]]);var ce=class{getCwd(){switch(y.type){case"node":case"bun":return process.cwd();case"deno":return Deno.cwd();default:throw new Error("Unsupported runtime")}}},q=new ce;var le=class{async mkdir(e,t){switch(y.type){case"bun":case"node":await(await import("fs/promises")).mkdir(e,{recursive:t?.recursive??!1});break;case"deno":await Deno.mkdir(e,{recursive:t?.recursive??!1});break}}async exists(e){switch(y.type){case"node":return(await import("fs")).existsSync(e);case"bun":return Bun.file(e).exists();case"deno":return Deno.stat(e).then(()=>!0).catch(()=>!1);default:throw new Error("Unsupported runtime")}}async readFile(e){switch(y.type){case"node":let r=await(await import("fs/promises")).readFile(e);return new Uint8Array(r);case"bun":let s=await Bun.file(e).arrayBuffer();return new Uint8Array(s);case"deno":return new Uint8Array(await Deno.readFile(e))}}async writeFile(e,t){switch(y.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(y.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 s=await Bun.file(e).stat();return{isDirectory:s.isDirectory(),isFile:s.isFile(),isSymbolicLink:s.isSymbolicLink(),size:s.size};case"deno":let n=await Deno.stat(e);return{isDirectory:n.isDirectory,isFile:n.isFile,isSymbolicLink:!1,size:n.size}}}async unlink(e){switch(y.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")}}},N=new le;var me=(o="public",e)=>(l.addOrUpdate("GET",`${o}/*`,[],async(t,r)=>gt(t,r,o),{service:"StaticFiles",...e}),async(t,r,s)=>s());async function gt(o,e,t){if(o.method!=="GET"&&o.method!=="HEAD")return e.status(405).json({...g(new X(o.url,o.method))});let r=o.params["*"]||"",s=(0,U.join)(t,r),n=(0,U.resolve)(q.getCwd(),s);try{if(!(await N.stat(n)).isFile)return e.notFound({...g(new w(o.url,o.method))})}catch(a){if(a.code==="ENOENT")return e.notFound({...g(new w(o.url,o.method))});throw a}let i=Y((0,U.extname)(n));e.setHeader("Content-Type",i);let d=await K.file(n);e.raw(d)}function Y(o){return De.get(o)||"application/octet-stream"}var P=class{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.text(String(e));if(e instanceof Date)return this.text(e.toISOString());if(e instanceof RegExp)return this.text(e.toString());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=="function")return this.text(e.toString());if(typeof e=="symbol")return this.text(e.toString());this.body=e}raw(e){this.body=e}text(e){this.body=e,this.headers={...this.headers,"Content-Type":"text/plain"}}json(e){this.body=e,this.headers={...this.headers,"Content-Type":"application/json"}}html(e){this.body=e,this.headers={...this.headers,"Content-Type":"text/html"}}xml(e){this.body=e,this.headers={...this.headers,"Content-Type":"application/xml"}}download(e){this.body=e,this.headers={...this.headers,"Content-Type":"application/octet-stream"}}file(e){let t=Y(e),r=K.file(e);this.headers={...this.headers,"Content-Type":t}}ok(e){this.status(200).send(e)}created(e){this.status(201).send(e)}accepted(e){this.status(202).send(e)}noContent(){this.status(204).send("")}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.status(304).send("")}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)}getBody(){return this.body}};var Ye=require("glob"),Te=require("path");var je=require("glob");var Ue=O(require("pino"),1),vt=()=>(0,Ue.default)({level:"info",formatters:{level:e=>({level:e})}}),v=vt();var j=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 R("node-cron not installed as a dependency, it is required in order to run cron jobs with the @cron decorator")})).default;if(v.info("Scheduling cron jobs"),!this.scheduledJobs.length){v.info("No cron jobs to schedule");return}for(let{name:t,args:r}of this.scheduledJobs)v.info(`Scheduling cron job: ${t}`),e.schedule(...r).on("execution:failed",n=>this.globalErrorHandler(n));v.info("Cron jobs scheduled")}static globalErrorHandler(e){v.error(e.execution?.error)}static async massiveImportCronJobs(e){let t=[];for(let r of e){let s=await(0,je.glob)(r);t.push(...s)}await Promise.all(t.map(async r=>{await import(r).catch(s=>{v.error(`Error importing cron job: ${r}`),v.error(s)})}))}};var B=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 n=r===""?s:`${r}.${s}`,i=e[s],d=t[s];if(!(s in e))throw new Error(`Expected ${r} to have key ${s}, but it was not found`);if(this.isObject(d)&&this.isObject(i))this.assertSubset(i,d,n);else if(Array.isArray(d)&&Array.isArray(i))this.assertArraySubset(i,d,n);else if(i!==d)throw new Error(`Expected ${n} to be ${d}, but got ${i}`)}}assertDeepEqual(e,t,r){if(this.isObject(e)&&this.isObject(t)){let s=Object.keys(e),n=Object.keys(t);if(s.length!==n.length)throw new Error(`Expected ${r} to have ${n.length} keys, but got ${s.length}`);for(let i of n){let d=r==="body"?i:`${r}.${i}`;this.assertDeepEqual(e[i],t[i],d)}}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 n=`${r}[${s}]`,i=e[s],d=t[s];if(this.isObject(d)&&this.isObject(i))this.assertSubset(i,d,n);else if(Array.isArray(d)&&Array.isArray(i))this.assertArraySubset(i,d,n);else if(i!==d)throw new Error(`Expected ${n} to be ${d}, but got ${i}`)}}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 n=`${r}[${s}]`;this.assertDeepEqual(e[s],t[s],n)}}isObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}};var C=async(o,e,t,r=new P)=>{let s=0;if(!o.length)return await e(t,r),r;let n=async()=>{if(s++,s>=o.length){await e(t,r);return}let d=o[s];await d(t,r,n)},i=o[0];return await i(t,r,n),r},H=o=>o?["post","put","patch","delete"].includes(o.toLowerCase()):!0;var Q=class{server;constructor(e){this.server=e}async request(e,t,r={}){let{headers:s={},query:n={},cookies:i={},ip:d}=r;this.validateOptions(r);let a=l.find(e.toUpperCase(),t);if(!a){let h=new P(404);return h.json({caller:"MockServer",error:"Route not found",path:t,method:e}),new B(h)}let p=r.body,u="application/json";if(p&&typeof p=="object"&&!(p instanceof Uint8Array)&&!(p instanceof ArrayBuffer)&&(p=JSON.stringify(p)),r.formData){let h=`----WebKitFormBoundary${Math.random().toString(36).substring(2)}`;u=`multipart/form-data; boundary=${h}`,p=await this.formDataToMultipart(r.formData,h)}r.urlencoded&&(u="application/x-www-form-urlencoded",p=new URLSearchParams(r.urlencoded).toString());let c=new URL(`http://${this.server.host}:${this.server.port}${t}`);c.search=new URLSearchParams(n).toString();let m=new x(c.toString(),{method:e.toUpperCase(),body:H(e)?p:void 0,headers:{"content-type":u,...s}});m.query={...Object.fromEntries(c.searchParams.entries()),...n},m.params=a.params,m.cookies=i,m.ip=d;try{let h=await C(a.middleware,a.handler,m);return new B(h)}catch(h){v.error(`Error processing mock request ${e} ${t}:`,h);let F=new P(500);return F.json({error:"Internal server error",message:h instanceof Error?h.message:String(h)}),new B(F)}}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[a,p]of e.entries()){s.push(r.encode(`--${t}\r
|
|
2
|
+
`));let u=`Content-Disposition: form-data; name="${a}"`,c="";if(p instanceof File&&(u+=`; filename="${p.name}"`,c=`Content-Type: ${p.type||"application/octet-stream"}\r
|
|
3
|
+
`),s.push(r.encode(`${u}\r
|
|
4
|
+
${c}\r
|
|
5
|
+
`)),p instanceof File){let m=await p.arrayBuffer();s.push(new Uint8Array(m)),s.push(r.encode(`\r
|
|
6
|
+
`))}else s.push(r.encode(`${String(p)}\r
|
|
7
|
+
`))}s.push(r.encode(`--${t}--\r
|
|
8
|
+
`));let n=s.reduce((a,p)=>a+p.byteLength,0),i=new Uint8Array(n),d=0;for(let a of s)i.set(a,d),d+=a.byteLength;return i}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 fe=o=>{let e={secret:o?.secret??"",defaults:{path:"/",httpOnly:!0,secure:!1,sameSite:"Lax",...o?.defaults},parse:o?.parse??!0,sign:o?.sign??!1};return async(t,r,s)=>{if(e.parse){let n=wt(t.headers.get("cookie")||"");t.cookies={};for(let[i,d]of Object.entries(n)){if(e.sign&&e.secret){let a=await bt(d,e.secret);a!==!1&&(t.cookies[i]=a);continue}t.cookies[i]=d}}r.cookie=(n,i,d)=>{Be(r,n,i,{...e.defaults,...d},e)},r.clearCookie=(n,i)=>{St(r,n,{...e.defaults,...i})},await s()}};function wt(o){let e={};if(!o)return e;let t=o.split(";");for(let r of t){let[s,n]=r.trim().split("=");s&&n&&(e[decodeURIComponent(s)]=decodeURIComponent(n))}return e}async function Be(o,e,t,r,s){let n=`${encodeURIComponent(e)}=${encodeURIComponent(t)}`;r.domain&&(n+=`; Domain=${r.domain}`),r.path&&(n+=`; Path=${r.path}`),r.expires&&(n+=`; Expires=${r.expires.toUTCString()}`),r.maxAge&&(n+=`; Max-Age=${r.maxAge}`),r.secure&&(n+="; Secure"),r.httpOnly&&(n+="; HttpOnly"),r.sameSite&&(n+=`; SameSite=${r.sameSite}`),r.priority&&(n+=`; Priority=${r.priority}`),s.sign&&s.secret&&(n=await Rt(n,s.secret));let i=o.headers["set-cookie"]||"",d=i?`${i}, ${n}`:n;o.setHeader("Set-Cookie",d)}function St(o,e,t){let r={...t,expires:new Date(0),maxAge:0};Be(o,e,"",r,{secret:"",defaults:{},parse:!0,sign:!1})}async function Rt(o,e){let t=new TextEncoder,r=t.encode(e),s=t.encode(o),n=await crypto.subtle.importKey("raw",r,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),i=await crypto.subtle.sign("HMAC",n,s),d=new Uint8Array(i),a=Array.from(d).map(p=>p.toString(16).padStart(2,"0")).join("");return`${o}.${a}`}async function bt(o,e){let t=o.split(".");if(t.length!==2)return!1;let[r,s]=t,n=new TextEncoder,i=n.encode(e),d=n.encode(r),a=await crypto.subtle.importKey("raw",i,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),p=await crypto.subtle.sign("HMAC",a,d),u=new Uint8Array(p),c=Array.from(u).map(m=>m.toString(16).padStart(2,"0")).join("");return s===c?r:!1}var he=o=>async(e,t,r)=>{try{let s=e.body;(o?.logRequest??!0)&&v.info({type:"request",requestId:e.id,method:o?.requestPayload?.method??!0?e.method:void 0,url:o?.requestPayload?.url??!0?e.url:void 0,ip:o?.requestPayload?.ip??!0?e.ip:void 0,headers:o?.requestPayload?.headers??!0?e.headers:void 0,body:o?.requestPayload?.body??!1?qe(s):void 0}),await r(),(o?.logResponse??!0)&&v.info({type:"response",requestId:e.id,status:o?.responsePayload?.status??t.responseStatus,body:o?.responsePayload?.body??!1?qe(t.getBody()):void 0,headers:o?.responsePayload?.headers??!1?t.headers:void 0})}catch(s){throw v.error(s),s}};function qe(o){if(typeof o=="string"||o&&typeof o=="object"&&o.constructor===Object)return o}var Z=class{storage=new Map;windowMs;constructor(e){this.windowMs=e}async set(e,t){this.storage.set(e,t),setTimeout(()=>{this.storage.delete(e)},this.windowMs)}async get(e){let t=this.storage.get(e);return t||0}async delete(e){this.storage.delete(e)}};var ye=(o,e)=>{let t={type:"ip",limit:100,message:"ERR_RATE_LIMIT_EXCEEDED",statusCode:429,...o},r={type:"memory",...e};r.type==="memory"&&!r.windowMs&&(r.windowMs=6e4);let s=r.type==="memory"?new Z(r.windowMs):{get:r.get,set:r.set};return async(n,i,d)=>{let a=t.type==="ip"?n.ip:t.key(n),p=await s.get(a);return p>=t.limit?i.status(t.statusCode).json({message:t.message}):(await s.set(a,p+1),d())}};var Ne=require("crypto");var ee=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 ge=o=>{let e=o?.name??"sid",t=o?.ttl??60*60*24,r=o?.store??new ee,s={path:"/",httpOnly:!0,secure:!1,sameSite:"Lax",...o?.cookie??{}};return async(n,i,d)=>{let p=n.cookies&&n.cookies[e],u=p?await r.get(p):void 0;(!p||!u)&&(p||=(0,Ne.randomUUID)(),u||={},await r.set(p,u,t),i.cookie?.(e,p,s)),n.session=u,n.saveSession=async()=>r.set(p,u,t),n.destroySession=async()=>{await r.destroy(p),i.clearCookie?.(e,s)},await d(),await r.set(p,u,t)}};var ve=o=>async(e,t,r)=>{e.timeout=!1;let s=setTimeout(()=>{e.timeout=!0},o.ms);try{await r()}finally{clearTimeout(s)}};var we=o=>{let e=o?.header??"x-forwarded-for",t=o?.trust??!0,r=o?.hop??"first";return async(s,n,i)=>{if(!t)return i();let d=s.headers.get(e);if(d&&typeof d=="string"){let a=d.split(",").map(p=>p.trim()).filter(Boolean);a.length&&(s.ip=r==="first"?a[0]:a[a.length-1])}return i()}};var Se=o=>{let e={limit:1048576,extended:!1,charset:"utf8",allowEmpty:!0,parameterLimit:1e3,...o};return async(t,r,s)=>{if(!(t.headers.get("content-type")||"").includes("application/x-www-form-urlencoded"))return s();try{await Ot(t,e),await s()}catch(i){if(i instanceof Error&&i.message.includes("limit")){r.status(413).json({error:"Payload too large",message:"Request body exceeds the size limit"});return}throw i}}};async function Ot(o,e){let t=o.rawBody;if(t.byteLength>e.limit)throw new Error(`Body size ${t.byteLength} exceeds limit ${e.limit}`);let s=new TextDecoder(e.charset).decode(t),n=xt(s,e);o.body=n}function xt(o,e){let t={},r=new URLSearchParams(o);if(r.size>e.parameterLimit)throw new Error(`Too many parameters: ${r.size} exceeds limit ${e.parameterLimit}`);for(let[s,n]of r.entries())!e.allowEmpty&&n===""||(e.extended?Tt(t,s,n):t[s]=n);return t}function Tt(o,e,t){let r=e.match(/\[([^\]]*)\]/g);if(!r){o[e]=t;return}let s=o,n=e.split("[")[0];for(let d=0;d<r.length-1;d++){let a=r[d].slice(1,-1);if(s[n]||(s[n]={}),a===""){Array.isArray(s[n])||(s[n]=[]),s=s[n];continue}s[n][a]||(s[n][a]={}),s=s[n][a]}let i=r[r.length-1].slice(1,-1);if(i===""){Array.isArray(s)||(s=[]),s.push(t);return}s[i]=t}var Ie=()=>async(o,e,t)=>(H(o.method)&&(o.rawBody=await o.arrayBuffer(),Object.defineProperty(o,"body",{value:void 0,writable:!0,configurable:!0,enumerable:!0})),t());var Re=o=>{let e={origin:"*",methods:["GET","HEAD","PUT","PATCH","POST","DELETE"],allowedHeaders:"",exposedHeaders:"",credentials:!1,maxAge:void 0,preflightContinue:!1,optionsSuccessStatus:204,...o};return async(t,r,s)=>{let n=t.headers.get("origin")||"";if(t.method==="OPTIONS")return Mt(t,r,e,n,s);Et(t,r,e,n),await s()}};function Mt(o,e,t,r,s){let n=Le(t,r);if(!n){e.forbidden("CORS origin not allowed");return}if(ze(e,t,n),t.preflightContinue){s();return}e.status(t.optionsSuccessStatus||204),e.send("")}function Et(o,e,t,r){let s=Le(t,r);s&&ze(e,t,s)}function Le(o,e){if(typeof o.origin=="string")return o.origin;if(Array.isArray(o.origin)){let t=o.origin.find(r=>typeof r=="string"?r===e:r instanceof RegExp&&r.test(e));return typeof t=="string"?t:!1}return"*"}function ze(o,e,t){if(o.setHeader("Access-Control-Allow-Origin",t),e.credentials&&o.setHeader("Access-Control-Allow-Credentials","true"),e.exposedHeaders&&e.exposedHeaders!==""){let s=Array.isArray(e.exposedHeaders)?e.exposedHeaders.join(","):e.exposedHeaders;o.setHeader("Access-Control-Expose-Headers",s)}if(e.allowedHeaders&&e.allowedHeaders!==""){let s=Array.isArray(e.allowedHeaders)?e.allowedHeaders.join(","):e.allowedHeaders;o.setHeader("Access-Control-Allow-Headers",s)}let r=Array.isArray(e.methods)?e.methods.join(","):e.methods;o.setHeader("Access-Control-Allow-Methods",String(r||"")),typeof e.maxAge=="number"&&o.setHeader("Access-Control-Max-Age",e.maxAge.toString())}var Je=require("os"),re=require("path");var te=class extends R{constructor(e,t,r){super(`FILE_TOO_LARGE: "${e}" is too large. Max size is ${r} bytes, but got ${t} bytes`)}};var be=o=>async(e,t,r)=>{let s=[];try{let n=e.headers.get("content-type")??e.headers.get("Content-Type");if(!n||!n.startsWith("multipart/form-data")||!e.rawBody)return r();let i=n.match(/boundary=(.*)(;|$)/i);if(!i)return r();let d=i[1].replace(/(^\s*"?|"?\s*$)/g,""),a=new Uint8Array(e.rawBody),p=new TextEncoder().encode(`--${d}`),u=new Uint8Array([13,10,13,10]),c=[],m=(S,E,$=0)=>{e:for(let T=$;T<=S.length-E.length;T++){for(let b=0;b<E.length;b++)if(S[T+b]!==E[b])continue e;return T}return-1},h=m(a,p);for(;h!==-1&&(h+=p.length,!(a[h]===45&&a[h+1]===45));){a[h]===13&&a[h+1]===10&&(h+=2);let S=m(a,u,h);if(S===-1)break;let E=a.subarray(h,S),$=new TextDecoder().decode(E),T=S+u.length,b=m(a,p,T);if(b===-1)break;let M=b-1;a[M]===10&&M--,a[M]===13&&M--;let Ce=a.subarray(T,M+1);c.push({headers:$,data:Ce}),h=b}let F=[],Pe={};for(let S of c){let E=S.headers.split(`\r
|
|
9
|
+
`).find(G=>G.toLowerCase().startsWith("content-disposition:"));if(!E)continue;let $=E.match(/name="([^"]+)"/);if(!$)continue;let T=$[1],b=E.match(/filename="([^"]*)"/),M=b?b[1]:"";if(!!M){if(o?.maxFileSize&&S.data.length>o.maxFileSize)return t.badRequest({...g(new te(M,S.data.length,o.maxFileSize))});let G=S.headers.split(`\r
|
|
10
|
+
`).find(et=>et.toLowerCase().startsWith("content-type:")),Qe=G?G.split(":")[1].trim():"application/octet-stream",Ze=(0,re.extname)(M),ae=(0,re.join)((0,Je.tmpdir)(),`${Pt(10)}${Ze}`);await N.writeFile(ae,S.data),s.push(ae),F.push({formName:T,mimeType:Qe,size:S.data.length,tmpPath:ae,originalName:M})}else Pe[T]=new TextDecoder().decode(S.data)}e.files=F,e.body=Pe,await r(),await Ge(s)}catch(n){throw await Ge(s),n}};async function Ge(o){await Promise.allSettled(o.map(e=>N.unlink(e)))}function Pt(o){return Math.random().toString(36).substring(2,2+o)}var Oe=o=>{let e={dnsPrefetchControl:!0,frameguard:{action:"SAMEORIGIN"},hsts:{maxAge:15552e3,includeSubDomains:!0,preload:!1},contentTypeOptions:!0,ieNoOpen:!0,xssFilter:!0,referrerPolicy:"no-referrer",crossOriginResourcePolicy:"same-origin",crossOriginOpenerPolicy:"same-origin",crossOriginEmbedderPolicy:"require-corp",contentSecurityPolicy:!1,...o};return async(t,r,s)=>{if(e.dnsPrefetchControl&&r.setHeader("X-DNS-Prefetch-Control","off"),e.frameguard){let n="SAMEORIGIN";typeof e.frameguard=="object"&&(n=e.frameguard.action),r.setHeader("X-Frame-Options",n)}if(e.hsts){let n={};typeof e.hsts=="object"&&(n=e.hsts);let i=n.maxAge!==void 0?n.maxAge:15552e3,d=n.includeSubDomains!==void 0?n.includeSubDomains:!0,a=n.preload!==void 0?n.preload:!1,p=`max-age=${i}`;d!==!1&&(p+="; includeSubDomains"),a&&(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 I=class extends R{constructor(e){super(`JSON_NOT_VALID: "${JSON.stringify(e)}" is not a valid JSON`)}};var xe=o=>async(e,t,r)=>{if(!Ct(e)||!H(e.method))return r();let s=o?.sizeLimit??5*1024*1024,n=e.rawBody;if(!n)return o?.parseEmptyBodyAsObject&&(e.body={}),r();let i=n.byteLength;if(!i)return o?.parseEmptyBodyAsObject&&(e.body={}),r();if(i>s){let d={status:413,message:"ERR_REQUEST_BODY_TOO_LARGE",...o?.customErrorMessage};return t.status(d.status).json({error:d.message})}try{let d=o?.encoding??"utf-8",a=new TextDecoder(d).decode(n);e.body=JSON.parse(a)}catch(d){return d instanceof SyntaxError?t.badRequest({...g(new I("Invalid JSON syntax"))}):t.badRequest({...g(new I("Invalid request body encoding"))})}await r()};function Ct(o){let e=Ht(o);return e?At(e)==="application/json":!1}function Ht(o){let e=o.headers.get("content-type")??o.headers.get("Content-Type");return e?Array.isArray(e)?e[0]||null:e:null}function At(o){let e=o.trim(),t=e.indexOf(";");return t===-1?e.toLowerCase():e.substring(0,t).trim().toLowerCase()}var We=o=>{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:{}};typeof o!="boolean"&&(e={...e,...o});let t=kt(e),r=`${e.path}`,s=`${r}/json`,n=e.type==="redoc"?Ft(s,e):e.type==="rapidoc"?$t(s,e):_t(s,e);l.addOrUpdate("GET",r,[],(i,d)=>{d.html(n)}),l.addOrUpdate("GET",s,[],(i,d)=>{d.json(t)})};function kt(o){let e=l.getRoutes(),t={},r={...o.components,securitySchemes:o.securitySchemes||{},schemas:o.models?{...o.components?.schemas||{},...o.models}:o.components?.schemas?{...o.components.schemas}:void 0};for(let s of e){let n=s.swaggerOptions;if(n?.excludeFromSwagger)continue;t[s.path]||(t[s.path]={});let i=s.method.toLowerCase(),d={summary:n?.name||`${i.toUpperCase()} ${s.path}`,description:n?.description||"",tags:n?.service?[n.service]:[],deprecated:n?.deprecated||!1},a=[];if(n?.query&&n.query.type==="object"&&n.query.properties)for(let[p,u]of Object.entries(n.query.properties))a.push({name:p,in:"query",required:Array.isArray(n.query.required)?n.query.required.includes(p):!1,schema:L(u)});if(n&&n.params?a=a.concat(Ve(s.path,n.params)):a=a.concat(Ve(s.path)),a.length>0&&(d.parameters=a),n?.requestBody){let p="application/json";n.bodyType==="form-data"?p="multipart/form-data":n.bodyType==="urlencoded"&&(p="application/x-www-form-urlencoded"),d.requestBody={content:{[p]:{schema:L(n.requestBody)}},required:!0}}else n?.bodyType&&(n.bodyType.includes("form-data")||n.bodyType.includes("urlencoded"))&&(d.requestBody={content:{[n.bodyType]:{schema:{type:"object"}}},required:!0});if(d.responses={},n?.responses)for(let[p,u]of Object.entries(n.responses))d.responses[p]={description:`Response for ${p}`,content:{"application/json":{schema:L(u)}}};if(n?.errors)for(let[p,u]of Object.entries(n.errors))d.responses[p]={description:`Error response for ${p}`,content:{"application/json":{schema:L(u)}}};if(Object.keys(d.responses).length===0&&(d.responses[200]={description:"Successful response",content:{"application/json":{schema:{type:"object"}}}}),n?.security){let p=[];Array.isArray(n.security)||(n.security=[n.security]);for(let u of n.security)if(u.type==="bearer")r.securitySchemes.bearer||(r.securitySchemes.bearer={type:"http",scheme:"bearer",bearerFormat:u.bearerFormat||"JWT",description:u.description}),p.push({bearer:[]});else if(u.type==="apiKey")r.securitySchemes[u.name]||(r.securitySchemes[u.name]={type:"apiKey",name:u.name,in:u.in,description:u.description}),p.push({[u.name]:[]});else if(u.type==="oauth2"){let c=u.name||"oauth2";r.securitySchemes[c]||(r.securitySchemes[c]={type:"oauth2",flows:u.flows,description:u.description}),p.push({[c]:[]})}else if(u.type==="openIdConnect"){let c=u.name||"openIdConnect";r.securitySchemes[c]||(r.securitySchemes[c]={type:"openIdConnect",openIdConnectUrl:u.openIdConnectUrl,description:u.description}),p.push({[c]:[]})}p.length&&(d.security=p)}else o.security&&(d.security=o.security);t[s.path][i]=d}return{openapi:"3.0.0",info:{title:o.title,description:o.description,version:o.version,...o.info},servers:o.servers?.map(s=>({url:s}))||[{url:"/"}],paths:t,components:r,security:o.security||[],tags:o.tags?Object.entries(o.tags).map(([s,n])=>({name:s,...n})):[]}}function _t(o,e){return`
|
|
11
|
+
<!DOCTYPE html>
|
|
12
|
+
<html lang="en">
|
|
13
|
+
<head>
|
|
14
|
+
<meta charset="utf-8" />
|
|
15
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
16
|
+
<meta name="description" content="${e.description}" />
|
|
17
|
+
<title>${e.title}</title>
|
|
18
|
+
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css" />
|
|
19
|
+
<style>
|
|
20
|
+
html {
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
overflow: -moz-scrollbars-vertical;
|
|
23
|
+
overflow-y: scroll;
|
|
24
|
+
}
|
|
25
|
+
*, *:before, *:after {
|
|
26
|
+
box-sizing: inherit;
|
|
27
|
+
}
|
|
28
|
+
body {
|
|
29
|
+
margin:0;
|
|
30
|
+
background: #fafafa;
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<div id="swagger-ui"></div>
|
|
36
|
+
<script src="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js"></script>
|
|
37
|
+
<script src="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-standalone-preset.js"></script>
|
|
38
|
+
<script>
|
|
39
|
+
window.onload = function() {
|
|
40
|
+
const ui = SwaggerUIBundle({
|
|
41
|
+
url: '${o}',
|
|
42
|
+
dom_id: '#swagger-ui',
|
|
43
|
+
deepLinking: true,
|
|
44
|
+
presets: [
|
|
45
|
+
SwaggerUIBundle.presets.apis,
|
|
46
|
+
SwaggerUIStandalonePreset
|
|
47
|
+
],
|
|
48
|
+
plugins: [
|
|
49
|
+
SwaggerUIBundle.plugins.DownloadUrl
|
|
50
|
+
],
|
|
51
|
+
layout: "StandaloneLayout",
|
|
52
|
+
validatorUrl: null,
|
|
53
|
+
oauth2RedirectUrl: window.location.origin + '/swagger-ui/oauth2-redirect.html'
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
</script>
|
|
57
|
+
</body>
|
|
58
|
+
</html>`}function Ft(o,e){return`
|
|
59
|
+
<!DOCTYPE html>
|
|
60
|
+
<html>
|
|
61
|
+
<head>
|
|
62
|
+
<title>${e.title}</title>
|
|
63
|
+
<meta charset="utf-8"/>
|
|
64
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
65
|
+
<meta name="description" content="${e.description}" />
|
|
66
|
+
<link rel="icon" type="image/png" href="https://redocly.github.io/redoc/favicon.ico">
|
|
67
|
+
<style>
|
|
68
|
+
body { margin: 0; padding: 0; }
|
|
69
|
+
</style>
|
|
70
|
+
</head>
|
|
71
|
+
<body>
|
|
72
|
+
<redoc spec-url="${o}"></redoc>
|
|
73
|
+
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script>
|
|
74
|
+
</body>
|
|
75
|
+
</html>
|
|
76
|
+
`}function $t(o,e){return`
|
|
77
|
+
<!DOCTYPE html>
|
|
78
|
+
<html>
|
|
79
|
+
<head>
|
|
80
|
+
<title>${e.title}</title>
|
|
81
|
+
<meta charset="utf-8"/>
|
|
82
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
83
|
+
<meta name="description" content="${e.description}" />
|
|
84
|
+
<link rel="icon" type="image/png" href="https://mrin9.github.io/RapiDoc/images/favicon.png">
|
|
85
|
+
<style>
|
|
86
|
+
body { margin: 0; padding: 0; }
|
|
87
|
+
</style>
|
|
88
|
+
</head>
|
|
89
|
+
<body>
|
|
90
|
+
<rapi-doc
|
|
91
|
+
spec-url="${o}"
|
|
92
|
+
render-style="read"
|
|
93
|
+
layout="column"
|
|
94
|
+
show-header="true"
|
|
95
|
+
allow-server-selection="true"
|
|
96
|
+
allow-authentication="true"
|
|
97
|
+
allow-server-variables="true"
|
|
98
|
+
theme="light"
|
|
99
|
+
primary-color="#009688"
|
|
100
|
+
regular-font="Open Sans, sans-serif"
|
|
101
|
+
mono-font="Fira Mono, monospace"
|
|
102
|
+
>
|
|
103
|
+
</rapi-doc>
|
|
104
|
+
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
|
107
|
+
`}function L(o){if(!o)return;let{$id:e,$schema:t,...r}=o;return r}function Ve(o,e){let t=[],r=/:([a-zA-Z0-9_]+)/g,s;for(;(s=r.exec(o))!==null;){let n=s[1],i={type:"string"};e&&e.type==="object"&&e.properties&&e.properties[n]&&(i=L(e.properties[n])||{type:"string"}),t.push({name:n,in:"path",required:!0,schema:i})}return t}var oe=class{port;hostname;host;routes;tapOptions;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.tapOptions=e?.tapOptions}listen(){let e=this.tapOptions?.options,{fetch:t,...r}=e??{};this.runtimeServer=Bun.serve({port:this.port,hostname:this.hostname,fetch:async(s,n)=>{let i=new URL(s.url),d=l.find(s.method,i.pathname);x.enrichRequest(s),s.params=d?.params??{},s.query=Object.fromEntries(i.searchParams.entries()),s.ip=s.headers.get("x-forwarded-for")?.split(",")[0]??n.requestIP(s)?.address,await t?.call(this,s,n);let a=await C(d?.middleware??[],d?.handler??((u,c)=>{c.notFound({...g(new w(u.url,u.method))})}),s);return a.headers["Content-Type"]==="application/json"?Response.json(a.getBody(),{status:a.responseStatus,headers:a.headers}):new Response(a.getBody(),{status:a.responseStatus,headers:a.headers})},...r}),this.url=this.runtimeServer.url.toString()}async close(){if(!this.runtimeServer)throw new Error("Server is not listening or not initialized");await this.runtimeServer.stop()}};var se=class{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.tapOptions=e?.tapOptions}listen(){let e=this.tapOptions?.options,{handler:t,...r}=e??{};this.runtimeServer=Deno.serve({port:this.port,hostname:this.hostname,handler:async(s,n)=>{let i=new URL(s.url),d=l.find(s.method,i.pathname);x.enrichRequest(s),s.params=d?.params??{},s.query=Object.fromEntries(i.searchParams.entries()),s.ip=s.headers.get("x-forwarded-for")?.split(",")[0]??n.remoteAddr?.hostname,await t?.(s,n);let a=await C(d?.middleware??[],d?.handler??((u,c)=>{c.notFound({...g(new w(u.url,u.method))})}),s);return a.headers["Content-Type"]==="application/json"?Response.json(a.getBody(),{status:a.responseStatus,headers:a.headers}):new Response(a.getBody(),{status:a.responseStatus,headers:a.headers})},...r}),this.url=`http://${this.host}:${this.port}`}async close(){if(!this.runtimeServer)throw new Error("Server is not listening or not initialized");await this.runtimeServer.shutdown()}};var Ke=require("http");async function Dt(o,e){let t=o.getReader();try{for(;;){let{done:r,value:s}=await t.read();if(r){e.end();break}e.write(s)}}catch(r){e.destroy(r)}}var ne=class{port;host;url;routes;tapOptions;runtimeServer;constructor(e){this.routes=e?.routes??[],this.port=e?.port??80,this.host=e?.host??"0.0.0.0",this.url=`http://${this.host}:${this.port}`,this.tapOptions=e?.tapOptions,this.runtimeServer=(0,Ke.createServer)(async(t,r)=>{if(this.tapOptions){let{options:c}=this.tapOptions;await c?.(t)}let s=l.find(t.method,t.url),n=new x(`${this.url}${t.url}`,{method:t.method,body:H(t.method)?await this.readRequestBody(t):void 0,headers:t.headers}),i=t.headers["x-forwarded-for"];Array.isArray(i)&&(i=i[0]),n.ip=i??t.socket.remoteAddress;let[d,a=""]=t.url?.split("?",2)??[];n.query=Object.fromEntries(new URLSearchParams(a)),n.params=s?.params??{};let p=await C(s?.middleware??[],s?.handler??((c,m)=>{m.notFound({...g(new w(c.url,c.method))})}),n),u=p.getBody();if(u instanceof ReadableStream){Dt(u,r);return}u instanceof Buffer||u instanceof Uint8Array||typeof u=="string"?u=u:p.headers["Content-Type"]==="application/json"?u=JSON.stringify(u):u=String(u),r.writeHead(p.responseStatus,p.headers),r.end(u)})}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()})})}async readRequestBody(e){return new Promise((t,r)=>{let s=[];e.on("data",n=>s.push(Buffer.from(n))),e.on("error",r),e.on("end",()=>t(Buffer.concat(s).toString()))})}};var ie=class{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()}close(){return this.server.close()}getRuntimeServer(e){if(e?.runtime==="bun")return new oe(e);if(e?.runtime==="node")return new ne(e);if(e?.runtime==="deno")return new se(e);throw new Error("No server implementation found for runtime: "+e?.runtime)}};var Xe=["isListening","url","port","host","routes","embed","constructor","get","post","put","patch","delete","getNodeServer","getBunServer","getDenoServer","use","setErrorHandler","listen","close","tapOptions","startUpOptions","tmpDir","logger","getMockServer"];var z=class{get(e){switch(y.type){case"node":return process.env[e]??"";case"bun":return Bun.env[e]??"";case"deno":return Deno.env.get(e)??"";default:throw new Error(`Unsupported runtime: ${y.type}`)}}};var Me=class{isListening;router=l;wasInitialized;serverConnector;globalMiddlewares=[];serverOptions;controllerImportBlacklistedPaths=["node_modules"];constructor(e){this.wasInitialized=!1,this.serverOptions={port:e?.port??Number(new z().get("PORT"))??80,host:e?.host??new z().get("HOST")??"0.0.0.0",controllerPatterns:e?.controllerPatterns??[],plugins:e?.plugins??{},tapOptions:e?.tapOptions??{},swagger:e?.swagger??!0,useBodyParser:e?.useBodyParser??!0},this.serverConnector=new ie({routes:[],port:this.serverOptions.port,host:this.serverOptions.host,tapOptions:this.serverOptions.tapOptions,runtime:y.type}),this.serverOptions.useBodyParser&&this.use(Ie()),this.isListening=!1}get url(){return this.serverConnector.url}get port(){return this.serverConnector.port}get host(){return this.serverConnector.host}get routes(){return l.getRoutes()}tmpDir(...e){let t="tmp";return e?(0,Te.join)(t,...e):(0,Te.join)(q.getCwd(),t)}get(e,t,r){let{middlewares:s,handler:n,swaggerOptions:i}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);l.addOrUpdate("GET",e,s,n,i)}post(e,t,r){let{middlewares:s,handler:n,swaggerOptions:i}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);l.addOrUpdate("POST",e,s,n,i)}patch(e,t,r){let{middlewares:s,handler:n,swaggerOptions:i}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);l.addOrUpdate("PATCH",e,s,n,i)}put(e,t,r){let{middlewares:s,handler:n,swaggerOptions:i}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);l.addOrUpdate("PUT",e,s,n,i)}delete(e,t,r){let{middlewares:s,handler:n,swaggerOptions:i}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);l.addOrUpdate("DELETE",e,s,n,i)}options(e,t,r){let{middlewares:s,handler:n,swaggerOptions:i}=this.extractOptionsAndHandlerFromRouteRegistration(t,r);l.addOrUpdate("OPTIONS",e,s,n,i)}group(e,t,r){this.router.group(e,t,r)}getNodeServer(){if(y.type!=="node")throw new Error("Server is not using node runtime, you can't call `.getNodeServer()`");return this.serverConnector.getServer("node")}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(Xe.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:!1,configurable:!0,enumerable:!0})}exit(e=0){switch(y.type){case"bun":case"node":process.exit(e);case"deno":Deno.exit(e);default:throw new Error(`Unsupported runtime: ${y.type}`)}}on(e,t){switch(y.type){case"bun":case"node":process.on(e,t);break;case"deno":Deno.addSignalListener(e,t);break;default:throw new Error(`Unsupported runtime: ${y.type}, only node, bun and deno are supported`)}}once(e,t){switch(y.type){case"bun":case"node":process.once(e,t);break;case"deno":Deno.addSignalListener(e,t);break;default:throw new Error(`Unsupported runtime: ${y.type}, only node, bun and deno are supported`)}}use(...e){this.globalMiddlewares.push(...e)}setErrorHandler(e){this.globalMiddlewares.unshift(async(t,r,s)=>{try{await s()}catch(n){await e?.(t,r,s,n)}})}setGlobalCronErrorHandler(e){j.globalErrorHandler=e}startRegisteredCrons=async(e,t)=>{e?.length&&await j.massiveImportCronJobs(e),j.run().then(()=>{t?.()})};listen(e){if(this.isListening)throw new Error("Server is already listening, you can't call `.listen()` multiple times");this.bootstrap().then(()=>{this.serverConnector.listen(),this.isListening=!0,this.serverOptions.swagger&&We(this.serverOptions.swagger),e?.({port:this.port,host:this.host,url:this.url})})}async close(){await this.serverConnector.close(),this.isListening=!1}async getMockServer(){return await this.bootstrap(),new Q(this)}async importControllers(){let e=this.serverOptions.controllerPatterns,t=await Promise.all(e.map(async r=>(0,Ye.glob)(r,{cwd:q.getCwd()}))).then(r=>r.flat());t=t.flat(),t=t.filter(r=>!this.controllerImportBlacklistedPaths.some(s=>r.includes(s))),v.debug(`Found ${t.length} controllers to import`),await Promise.all(t.map(async r=>{v.debug(`Importing controller ${r}`),await import(r).catch(s=>{v.error(`Error importing controller ${r}: ${s}`)})}))}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"cors":this.use(Re(r));break;case"json":this.use(xe(r));break;case"static":this.use(me(r));break;case"fileParser":this.use(be(r));break;case"helmet":this.use(Oe(r));break;case"cookie":this.use(fe(r));break;case"log":this.use(he(r));break;case"rateLimiter":let{keyOptions:s,storageOptions:n}=r;this.use(ye(s,n));break;case"urlencoded":this.use(Se(r));break;case"trustProxy":this.use(we(r));break;case"timeout":this.use(ve(r));break;case"session":this.use(ge(r));break;default:v.warn(`Unknown plugin ${t}`);break}})}async bootstrap(){this.wasInitialized||(await this.importControllers(),this.applyPlugins(this.serverOptions.plugins),this.registerNotFoundRoutes(),this.globalMiddlewares.length&&l.applyGlobalMiddlewaresToAllRoutes(this.globalMiddlewares),this.wasInitialized=!0)}registerNotFoundRoutes(){l.addOrUpdate("GET","*",[],(e,t)=>{let r=new w(e.url,e.method);t.notFound({...g(r)})},{excludeFromSwagger:!0}),l.addOrUpdate("POST","*",[],(e,t)=>{let r=new w(e.url,e.method);t.notFound({...g(r)})},{excludeFromSwagger:!0}),l.addOrUpdate("PUT","*",[],(e,t)=>{let r=new w(e.url,e.method);t.notFound({...g(r)})},{excludeFromSwagger:!0}),l.addOrUpdate("PATCH","*",[],(e,t)=>{let r=new w(e.url,e.method);t.notFound({...g(r)})},{excludeFromSwagger:!0}),l.addOrUpdate("DELETE","*",[],(e,t)=>{let r=new w(e.url,e.method);t.notFound({...g(r)})},{excludeFromSwagger:!0})}};var Ee=class{};var Ut=l;0&&(module.exports={BasePlugin,Request,Response,Server,controller,cookie,cors,del,fileParser,get,getContentType,helmet,json,log,middleware,patch,post,put,rateLimiter,router,serveStatic,session,timeout,trustProxy,urlencoded,validate});
|
|
108
|
+
//# sourceMappingURL=index.cjs.map
|