balda 0.0.9 → 0.0.11

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.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import {glob}from'glob';import Pe from'pino';import ie from'fs';import re from'path';import {execSync}from'child_process';import*as ve from'readline';var Ce=Object.defineProperty;var p=(r,e,t,s)=>{for(var i=void 0,o=r.length-1,l;o>=0;o--)(l=r[o])&&(i=(l(e,t,i))||i);return i&&Ce(e,t,i),i};var le=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")}},b=new le;var ce=class{getCliArgs(){switch(b.type){case "bun":return this.getBunArgs();case "node":return this.getNodeArgs();case "deno":return Deno.args;default:throw new Error("Unsupported runtime")}}getCliCaller(){switch(b.type){case "bun":return "bun";case "node":return process.argv[0];case "deno":return "deno";default:throw new Error("Unsupported runtime")}}getBunArgs(){let e=Bun.argv,t=this.findScriptIndex(e);return e.slice(t+1)}getNodeArgs(){let e=process.argv,t=this.findScriptIndex(e);return e.slice(t+1)}findScriptIndex(e){if(e.length>=3&&e[1].includes(".bin/"))return 1;for(let t=0;t<e.length;t++){let s=e[t],i=s.split("/").pop()||s;if(!s.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(s))return t;if(/^(tsx|ts-node|node|bun)$/.test(i)){for(let o=t+1;o<e.length;o++)if(!e[o].startsWith("-")&&/\.(js|ts|mjs|cjs)$/.test(e[o]))return o;return t}}}for(let t=e.length-1;t>=0;t--)if(!e[t].startsWith("-"))return t;return 1}},W=new ce;var he=(r,e)=>{let t=Array(e.length+1).fill(null).map(()=>Array(r.length+1).fill(null));for(let s=0;s<=r.length;s++)t[0][s]=s;for(let s=0;s<=e.length;s++)t[s][0]=s;for(let s=1;s<=e.length;s++)for(let i=1;i<=r.length;i++){let o=r[i-1]===e[s-1]?0:1;t[s][i]=Math.min(t[s][i-1]+1,t[s-1][i]+1,t[s-1][i-1]+o);}return t[e.length][r.length]},X=r=>r.toLowerCase().replace(/[-_.]/g,"_").replace(/([A-Z])/g,"_$1").replace(/^_+/,"").replace(/_+$/,"").toLowerCase(),ee=r=>r.split(/[-_.]/g).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),ye=r=>r.split(/[-_.]/g).map(e=>e.toLowerCase()).join("-");var Te=r=>{if(!r||r==="-"||r==="--")return null;let e=r.indexOf("=");if(e>0){let t=r.substring(0,e),s=r.substring(e+1);return {name:t,value:be(s)}}return {name:r,value:true}},be=r=>{if(r.toLowerCase()==="true")return true;if(r.toLowerCase()==="false")return false;let e=Number(r);return !Number.isNaN(e)&&Number.isFinite(e)?e:r},M=()=>{let r=W.getCliArgs(),e=[],t={};if(!r||!r.length)return {args:e,flags:t};for(let s=0;s<r.length;s++){let i=r[s];if(!(!i||typeof i!="string")){if(i.startsWith("-")){let o=Te(i);if(o){if(o.value===true&&s+1<r.length){let l=r[s+1];l&&typeof l=="string"&&!l.startsWith("-")&&(o.value=be(l),s++);}if(o.name in t){let l=t[o.name];Array.isArray(l)?l.push(o.value):t[o.name]=[l,o.value];}else t[o.name]=o.value;}continue}e.push(i);}}return {args:e,flags:t}},xe=(r,e)=>{if(!r||typeof r!="string"||!e||!Array.isArray(e)||e.length===0)return "";let t=r.toLowerCase().trim(),s=e.filter(l=>{let a=l.toLowerCase();if(a===t||a.includes(t)||t.includes(a))return true;let m=he(a,t),n=Math.max(t.length,a.length)*.4;return m<=n});if(s.length===0)return "";let o=s.slice(0,3).map(l=>`\x1B[36m${l}\x1B[0m`).join(", ");return `\x1B[31m\u2717\x1B[0m Command \x1B[33m${r}\x1B[0m not found
3
- \x1B[32m\u{1F4A1}\x1B[0m Did you mean: ${o}?`},te=()=>W.getCliArgs()[0]||null;var Se=()=>Pe({level:"info",formatters:{level:e=>({level:e})}}),se=Se();var me=class{getCwd(){switch(b.type){case "node":case "bun":return process.cwd();case "deno":return Deno.cwd();default:throw new Error("Unsupported runtime")}}},G=new me;var T=class{static metadata=new WeakMap;static set(e,t,s){this.metadata.has(e)||this.metadata.set(e,new Map),this.metadata.get(e).set(t,s);}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 O="VALIDATION_ERROR";var we=M().args.slice(1),v=r=>(e,t)=>{let s=te();if(!s||s!==e.commandName)return;let i=t;T.set(e,t,{type:"arg",name:i,description:r.description});let o=we.length?we.shift():r.defaultValue;if(r.required&&!o){let l=T.get(e,O);T.set(e,O,[...l||[],{type:"arg",name:i,message:"Required argument not provided"}]);return}r.parse&&o&&(o=r.parse(o)),Object.defineProperty(e,t,{value:o,enumerable:true,configurable:true,writable:true});};var j=r=>(e,t)=>{let s=te();if(!s||s!==e.commandName)return;let i=r.name||t,o=M().flags,l=r.aliases||[],a=[i,...l],m=r.defaultValue;for(let n of a){let g=[n,`-${n}`,`--${n}`];for(let $ of g)if($ in o){let N=o[$];r.type==="list"?m=(Array.isArray(N)?N:[N]).map(h=>{let w=String(h);return r.parse?r.parse(w):w}):(m=N,r.type==="boolean"?m=!!m:r.type==="number"&&(m=Number(m)),r.parse&&(m=r.parse(m)));break}if(m!==r.defaultValue)break}if(T.set(e,t,{type:"flag",name:i,aliases:l||[],description:r.description}),r.required&&(r.type==="list"?!m||Array.isArray(m)&&m.length===0:!m)){let g=T.get(e,O);T.set(e,O,[...g||[],{type:"flag",name:i,message:"Required flag not provided"}]);return}Object.defineProperty(e,t,{value:m,enumerable:true,configurable:true,writable:true});};j.boolean=r=>j({...r,type:"boolean"});j.string=r=>j({...r,type:"string"});j.number=r=>j({...r,type:"number"});j.list=r=>j({...r,type:"list"});var u=j;var de=class{exit(e){switch(b.type){case "bun":case "node":process.exit(e);case "deno":Deno.exit(e);default:throw new Error("Unsupported runtime")}}},E=new de;var y=class{static commandName=this.name;static calledBy=this.name;static description="";static help=[];static options={keepAlive:false};static args=M().args.slice(1);static flags=M().flags;static logger=se;static handle(){throw new Error(`Handle method not implemented in command class ${this.name}`)}static handleHelpFlag(e){let t=["-h","--help"];if(!Object.keys(e).some(n=>t.includes(n)))return;let i=this.commandName,o=this.description||"No description available",l=this.help||[],a=this.options,m=this.generateHelpOutput({name:i,description:o,helpText:l,options:a,args:this.args,flags:this.flags},this);console.log(m),E.exit(0);}static generateHelpOutput=(e,t)=>{let{name:s,description:i,helpText:o,options:l,args:a,flags:m}=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"},g=[`${n.title}${s}${n.reset}`,`${n.description}${i}${n.reset}`,"",`${n.subtitle}Usage:${n.reset}`,` ${n.code}${s}${n.reset} [options] [arguments]`,"",`${n.subtitle}Options:${n.reset}`,` ${n.flag}-h, --help${n.reset} Show this help message`,"",`${n.subtitle}Command Options:${n.reset}`,` ${n.flag}keepAlive${n.reset} ${l?.keepAlive??false?n.success+"Enabled"+n.reset:n.error+"Disabled"+n.reset}`,""];if(o){let h=Array.isArray(o)?o:[o];g.push(`${n.subtitle}Help:${n.reset}`),h.forEach(w=>{g.push(` ${n.description}${w}${n.reset}`);}),g.push("");}let $=T.getAll(t),N=Array.from($.values()).filter(h=>h.type==="arg"),Z=Array.from($.values()).filter(h=>h.type==="flag");return N.length&&(g.push(`${n.subtitle}Available Arguments:${n.reset}`),N.forEach(h=>{let w=h.required?` ${n.error}(required)${n.reset}`:"",R=h.description?` ${n.description}${h.description}${n.reset}`:"";g.push(` ${n.code}${h.name}${n.reset}${w}${R}`);}),g.push("")),Z.length&&(g.push(`${n.subtitle}Available Flags:${n.reset}`),Z.forEach(h=>{h.aliases&&!Array.isArray(h.aliases)&&(h.aliases=[h.aliases]);let w=h.aliases.length?` ${n.flag}(${h.aliases.join(", ")})${n.reset}`:"",R=h.required?` ${n.error}(required)${n.reset}`:"",J=h.description?` ${n.description}${h.description}${n.reset}`:"";g.push(` ${n.flag}--${h.name}${w}${n.reset}${R}${J}`);}),g.push("")),((a?.length??0)>0||m&&Object.keys(m).length>0)&&(g.push(`${n.subtitle}Current Context:${n.reset}`),a?.length&&g.push(` ${n.info}Provided Arguments:${n.reset} ${n.code}${a.join(" ")}${n.reset}`),m&&Object.keys(m).length>0&&(g.push(` ${n.info}Provided Flags:${n.reset}`),Object.keys(m).forEach(h=>{let w=m[h],R=w!=null?` = ${n.code}${w}${n.reset}`:"";g.push(` ${n.flag}${h}${n.reset}${R}`);})),g.push("")),o&&(Array.isArray(o)?o.some(h=>h.includes("example")):o.includes("example"))&&(g.push(`${n.subtitle}Examples:${n.reset}`),(Array.isArray(o)?o.filter(w=>w.includes("example")):[o.split("example")[1].trim()]).forEach(w=>{g.push(` ${n.code}${w}${n.reset}`);}),g.push("")),g.join(`
4
- `)};static validateContext=e=>{let t=Array.from(T.get(e,O)||[]);if(t.length){let s={error:"\x1B[0;31m",title:"\x1B[1;31m",reset:"\x1B[0m",info:"\x1B[0;34m",code:"\x1B[0;32m"};console.error(`${s.title}\u274C Validation Errors:${s.reset}`),console.error(""),t.forEach((i,o)=>{let l=`${s.info}${o+1}.${s.reset}`,a=`${s.error}${i.type.toUpperCase()}${s.reset}`,m=`${s.code}${i.name}${s.reset}`;console.error(` ${l} ${a} ${m}: ${s.error}${i.message}${s.reset}`);}),console.error(""),console.error(`${s.info}\u{1F4A1} Tip: Use --help for usage information${s.reset}`),E.exit(1);}}};var pe=class{async mkdir(e,t){switch(b.type){case "bun":case "node":await(await import('fs/promises')).mkdir(e,{recursive:t?.recursive??false,mode:t?.mode});break;case "deno":typeof t?.mode=="string"&&(t.mode=Number.parseInt(t.mode)),await Deno.mkdir(e,{recursive:t?.recursive??false,mode:t?.mode});break}}async exists(e){switch(b.type){case "node":return (await import('fs')).existsSync(e);case "bun":return (await import('fs')).existsSync(e);case "deno":return Deno.stat(e).then(()=>true).catch(()=>false);default:throw new Error("Unsupported runtime")}}async readFile(e,t){switch(b.type){case "node":let i=await(await import('fs/promises')).readFile(e,{encoding:t?.encoding??null});return t?.encoding==="utf8"?i:new Uint8Array(i);case "bun":let o=Bun.file(e);return t?.encoding==="utf8"?o.text():new Uint8Array(await o.arrayBuffer());case "deno":let l=await Deno.readFile(e);return t?.encoding==="utf8"?new TextDecoder().decode(l):new Uint8Array(l)}}async writeFile(e,t){switch(b.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(b.type){case "node":let s=await(await import('fs/promises')).stat(e);return {isDirectory:s.isDirectory(),isFile:s.isFile(),isSymbolicLink:s.isSymbolicLink(),size:s.size};case "bun":let o=await(await import('fs/promises')).stat(e);return {isDirectory:o.isDirectory(),isFile:o.isFile(),isSymbolicLink:o.isSymbolicLink(),size:o.size};case "deno":let l=await Deno.stat(e);return {isDirectory:l.isDirectory,isFile:l.isFile,isSymbolicLink:false,size:l.size}}}async unlink(e){switch(b.type){case "node":await(await import('fs/promises')).unlink(e);break;case "bun":await Bun.file(e).delete();break;case "deno":await Deno.remove(e);break;default:throw new Error("Unsupported runtime")}}async streamFile(e){switch(b.type){case "node":let t=await import('fs'),{Readable:s}=await import('stream'),i=t.createReadStream(e);return s.toWeb(i);case "bun":return Bun.file(e).stream();case "deno":return (await Deno.open(e)).readable;default:throw new Error("Unsupported runtime")}}async readdir(e){switch(b.type){case "bun":case "node":return (await import('fs/promises')).readdir(e);case "deno":let s=[];for await(let i of Deno.readDir(e))s.push(i.name);return s;default:throw new Error("Unsupported runtime")}}},c=new pe;var ue=class{basename(e){switch(b.type){case "node":case "bun":case "deno":return re.basename(e);default:throw new Error("Unsupported runtime")}}join(...e){switch(b.type){case "node":case "bun":case "deno":return re.join(...e);default:throw new Error("Unsupported runtime")}}extName(e){switch(b.type){case "bun":case "node":case "deno":return re.extname(e);default:throw new Error("Unsupported runtime")}}resolve(...e){switch(b.type){case "bun":case "node":case "deno":return re.resolve(...e);default:throw new Error("Unsupported runtime")}}},d=new ue;var K=async r=>{let e=d.join(process.cwd(),"node_modules");if(!await c.exists(e))return r;let s=[];for(let i of r){let o=d.join(e,i);await c.exists(o)||s.push(i);}return s},S=async()=>await c.exists(d.join(process.cwd(),"yarn.lock"))?["yarn","add","-D"]:await c.exists(d.join(process.cwd(),"pnpm-lock.yaml"))?["pnpm","add","-D"]:await c.exists(d.join(process.cwd(),"package-lock.json"))?["npm","install","-D"]:await c.exists(d.join(process.cwd(),"bun.lockb"))?["bun","add","-D"]:await c.exists(d.join(process.cwd(),"deno.lock"))?["deno","add","-D"]:["npm","install","-D"],q=async(r,e,t,s,i=true)=>{let o=ve.createInterface({input:process.stdin,output:process.stdout}),l=t.join(", "),a=`Do you want to install the following ${i?"dev":""} dependencies using ${e}?
2
+ import {glob}from'glob';import Pe from'pino';import ie from'fs';import re from'path';import {execSync}from'child_process';import*as ve from'readline';var Ce=Object.defineProperty;var p=(r,e,t,s)=>{for(var i=void 0,o=r.length-1,l;o>=0;o--)(l=r[o])&&(i=(l(e,t,i))||i);return i&&Ce(e,t,i),i};var le=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")}},b=new le;var ce=class{getCliArgs(){switch(b.type){case "bun":return this.getBunArgs();case "node":return this.getNodeArgs();case "deno":return Deno.args;default:throw new Error("Unsupported runtime")}}getCliCaller(){switch(b.type){case "bun":return "bun";case "node":return process.argv[0];case "deno":return "deno";default:throw new Error("Unsupported runtime")}}getBunArgs(){let e=Bun.argv,t=this.findScriptIndex(e);return e.slice(t+1)}getNodeArgs(){let e=process.argv,t=this.findScriptIndex(e);return e.slice(t+1)}findScriptIndex(e){if(e.length>=3&&e[1].includes(".bin/"))return 1;for(let t=0;t<e.length;t++){let s=e[t],i=s.split("/").pop()||s;if(!s.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(s))return t;if(/^(tsx|ts-node|node|bun)$/.test(i)){for(let o=t+1;o<e.length;o++)if(!e[o].startsWith("-")&&/\.(js|ts|mjs|cjs)$/.test(e[o]))return o;return t}}}for(let t=e.length-1;t>=0;t--)if(!e[t].startsWith("-"))return t;return 1}},W=new ce;var he=(r,e)=>{let t=Array(e.length+1).fill(null).map(()=>Array(r.length+1).fill(null));for(let s=0;s<=r.length;s++)t[0][s]=s;for(let s=0;s<=e.length;s++)t[s][0]=s;for(let s=1;s<=e.length;s++)for(let i=1;i<=r.length;i++){let o=r[i-1]===e[s-1]?0:1;t[s][i]=Math.min(t[s][i-1]+1,t[s-1][i]+1,t[s-1][i-1]+o);}return t[e.length][r.length]},X=r=>r.toLowerCase().replace(/[-_.]/g,"_").replace(/([A-Z])/g,"_$1").replace(/^_+/,"").replace(/_+$/,"").toLowerCase(),ee=r=>r.split(/[-_.]/g).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),ye=r=>r.split(/[-_.]/g).map(e=>e.toLowerCase()).join("-");var Te=r=>{if(!r||r==="-"||r==="--")return null;let e=r.indexOf("=");if(e>0){let t=r.substring(0,e),s=r.substring(e+1);return {name:t,value:be(s)}}return {name:r,value:true}},be=r=>{if(r.toLowerCase()==="true")return true;if(r.toLowerCase()==="false")return false;let e=Number(r);return !Number.isNaN(e)&&Number.isFinite(e)?e:r},M=()=>{let r=W.getCliArgs(),e=[],t={};if(!r||!r.length)return {args:e,flags:t};for(let s=0;s<r.length;s++){let i=r[s];if(!(!i||typeof i!="string")){if(i.startsWith("-")){let o=Te(i);if(o){if(o.value===true&&s+1<r.length){let l=r[s+1];l&&typeof l=="string"&&!l.startsWith("-")&&(o.value=be(l),s++);}if(o.name in t){let l=t[o.name];Array.isArray(l)?l.push(o.value):t[o.name]=[l,o.value];}else t[o.name]=o.value;}continue}e.push(i);}}return {args:e,flags:t}},xe=(r,e)=>{if(!r||typeof r!="string"||!e||!Array.isArray(e)||e.length===0)return "";let t=r.toLowerCase().trim(),s=e.filter(l=>{let n=l.toLowerCase();if(n===t||n.includes(t)||t.includes(n))return true;let m=he(n,t),a=Math.max(t.length,n.length)*.4;return m<=a});if(s.length===0)return "";let o=s.slice(0,3).map(l=>`\x1B[36m${l}\x1B[0m`).join(", ");return `\x1B[31m\u2717\x1B[0m Command \x1B[33m${r}\x1B[0m not found
3
+ \x1B[32m\u{1F4A1}\x1B[0m Did you mean: ${o}?`},te=()=>W.getCliArgs()[0]||null;var Se=()=>Pe({level:"info",formatters:{level:e=>({level:e})}}),se=Se();var me=class{getCwd(){switch(b.type){case "node":case "bun":return process.cwd();case "deno":return Deno.cwd();default:throw new Error("Unsupported runtime")}}},G=new me;var T=class{static metadata=new WeakMap;static set(e,t,s){this.metadata.has(e)||this.metadata.set(e,new Map),this.metadata.get(e).set(t,s);}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 O="VALIDATION_ERROR";var we=M().args.slice(1),v=r=>(e,t)=>{let s=te();if(!s||s!==e.commandName)return;let i=t;T.set(e,t,{type:"arg",name:i,description:r.description});let o=we.length?we.shift():r.defaultValue;if(r.required&&!o){let l=T.get(e,O);T.set(e,O,[...l||[],{type:"arg",name:i,message:"Required argument not provided"}]);return}r.parse&&o&&(o=r.parse(o)),Object.defineProperty(e,t,{value:o,enumerable:true,configurable:true,writable:true});};var j=r=>(e,t)=>{let s=te();if(!s||s!==e.commandName)return;let i=r.name||t,o=M().flags,l=r.aliases||[],n=[i,...l],m=r.defaultValue;for(let a of n){let g=[a,`-${a}`,`--${a}`];for(let $ of g)if($ in o){let N=o[$];r.type==="list"?m=(Array.isArray(N)?N:[N]).map(h=>{let w=String(h);return r.parse?r.parse(w):w}):(m=N,r.type==="boolean"?m=!!m:r.type==="number"&&(m=Number(m)),r.parse&&(m=r.parse(m)));break}if(m!==r.defaultValue)break}if(T.set(e,t,{type:"flag",name:i,aliases:l||[],description:r.description}),r.required&&(r.type==="list"?!m||Array.isArray(m)&&m.length===0:!m)){let g=T.get(e,O);T.set(e,O,[...g||[],{type:"flag",name:i,message:"Required flag not provided"}]);return}Object.defineProperty(e,t,{value:m,enumerable:true,configurable:true,writable:true});};j.boolean=r=>j({...r,type:"boolean"});j.string=r=>j({...r,type:"string"});j.number=r=>j({...r,type:"number"});j.list=r=>j({...r,type:"list"});var u=j;var de=class{exit(e){switch(b.type){case "bun":case "node":process.exit(e);case "deno":Deno.exit(e);default:throw new Error("Unsupported runtime")}}},E=new de;var y=class{static commandName=this.name;static calledBy=this.name;static description="";static help=[];static options={keepAlive:false};static args=M().args.slice(1);static flags=M().flags;static logger=se;static handle(){throw new Error(`Handle method not implemented in command class ${this.name}`)}static handleHelpFlag(e){let t=["-h","--help"];if(!Object.keys(e).some(a=>t.includes(a)))return;let i=this.commandName,o=this.description||"No description available",l=this.help||[],n=this.options,m=this.generateHelpOutput({name:i,description:o,helpText:l,options:n,args:this.args,flags:this.flags},this);console.log(m),E.exit(0);}static generateHelpOutput=(e,t)=>{let{name:s,description:i,helpText:o,options:l,args:n,flags:m}=e,a={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"},g=[`${a.title}${s}${a.reset}`,`${a.description}${i}${a.reset}`,"",`${a.subtitle}Usage:${a.reset}`,` ${a.code}${s}${a.reset} [options] [arguments]`,"",`${a.subtitle}Options:${a.reset}`,` ${a.flag}-h, --help${a.reset} Show this help message`,"",`${a.subtitle}Command Options:${a.reset}`,` ${a.flag}keepAlive${a.reset} ${l?.keepAlive??false?a.success+"Enabled"+a.reset:a.error+"Disabled"+a.reset}`,""];if(o){let h=Array.isArray(o)?o:[o];g.push(`${a.subtitle}Help:${a.reset}`),h.forEach(w=>{g.push(` ${a.description}${w}${a.reset}`);}),g.push("");}let $=T.getAll(t),N=Array.from($.values()).filter(h=>h.type==="arg"),Z=Array.from($.values()).filter(h=>h.type==="flag");return N.length&&(g.push(`${a.subtitle}Available Arguments:${a.reset}`),N.forEach(h=>{let w=h.required?` ${a.error}(required)${a.reset}`:"",R=h.description?` ${a.description}${h.description}${a.reset}`:"";g.push(` ${a.code}${h.name}${a.reset}${w}${R}`);}),g.push("")),Z.length&&(g.push(`${a.subtitle}Available Flags:${a.reset}`),Z.forEach(h=>{h.aliases&&!Array.isArray(h.aliases)&&(h.aliases=[h.aliases]);let w=h.aliases.length?` ${a.flag}(${h.aliases.join(", ")})${a.reset}`:"",R=h.required?` ${a.error}(required)${a.reset}`:"",J=h.description?` ${a.description}${h.description}${a.reset}`:"";g.push(` ${a.flag}--${h.name}${w}${a.reset}${R}${J}`);}),g.push("")),((n?.length??0)>0||m&&Object.keys(m).length>0)&&(g.push(`${a.subtitle}Current Context:${a.reset}`),n?.length&&g.push(` ${a.info}Provided Arguments:${a.reset} ${a.code}${n.join(" ")}${a.reset}`),m&&Object.keys(m).length>0&&(g.push(` ${a.info}Provided Flags:${a.reset}`),Object.keys(m).forEach(h=>{let w=m[h],R=w!=null?` = ${a.code}${w}${a.reset}`:"";g.push(` ${a.flag}${h}${a.reset}${R}`);})),g.push("")),o&&(Array.isArray(o)?o.some(h=>h.includes("example")):o.includes("example"))&&(g.push(`${a.subtitle}Examples:${a.reset}`),(Array.isArray(o)?o.filter(w=>w.includes("example")):[o.split("example")[1].trim()]).forEach(w=>{g.push(` ${a.code}${w}${a.reset}`);}),g.push("")),g.join(`
4
+ `)};static validateContext=e=>{let t=Array.from(T.get(e,O)||[]);if(t.length){let s={error:"\x1B[0;31m",title:"\x1B[1;31m",reset:"\x1B[0m",info:"\x1B[0;34m",code:"\x1B[0;32m"};console.error(`${s.title}\u274C Validation Errors:${s.reset}`),console.error(""),t.forEach((i,o)=>{let l=`${s.info}${o+1}.${s.reset}`,n=`${s.error}${i.type.toUpperCase()}${s.reset}`,m=`${s.code}${i.name}${s.reset}`;console.error(` ${l} ${n} ${m}: ${s.error}${i.message}${s.reset}`);}),console.error(""),console.error(`${s.info}\u{1F4A1} Tip: Use --help for usage information${s.reset}`),E.exit(1);}}};var pe=class{async mkdir(e,t){switch(b.type){case "bun":case "node":await(await import('fs/promises')).mkdir(e,{recursive:t?.recursive??false,mode:t?.mode});break;case "deno":typeof t?.mode=="string"&&(t.mode=Number.parseInt(t.mode)),await Deno.mkdir(e,{recursive:t?.recursive??false,mode:t?.mode});break}}async exists(e){switch(b.type){case "node":return (await import('fs')).existsSync(e);case "bun":return (await import('fs')).existsSync(e);case "deno":return Deno.stat(e).then(()=>true).catch(()=>false);default:throw new Error("Unsupported runtime")}}async readFile(e,t){switch(b.type){case "node":let i=await(await import('fs/promises')).readFile(e,{encoding:t?.encoding??null});return t?.encoding==="utf8"?i:new Uint8Array(i);case "bun":let o=Bun.file(e);return t?.encoding==="utf8"?o.text():new Uint8Array(await o.arrayBuffer());case "deno":let l=await Deno.readFile(e);return t?.encoding==="utf8"?new TextDecoder().decode(l):new Uint8Array(l)}}async writeFile(e,t){switch(b.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(b.type){case "node":let s=await(await import('fs/promises')).stat(e);return {isDirectory:s.isDirectory(),isFile:s.isFile(),isSymbolicLink:s.isSymbolicLink(),size:s.size};case "bun":let o=await(await import('fs/promises')).stat(e);return {isDirectory:o.isDirectory(),isFile:o.isFile(),isSymbolicLink:o.isSymbolicLink(),size:o.size};case "deno":let l=await Deno.stat(e);return {isDirectory:l.isDirectory,isFile:l.isFile,isSymbolicLink:false,size:l.size}}}async unlink(e){switch(b.type){case "node":await(await import('fs/promises')).unlink(e);break;case "bun":await Bun.file(e).delete();break;case "deno":await Deno.remove(e);break;default:throw new Error("Unsupported runtime")}}async streamFile(e){switch(b.type){case "node":let t=await import('fs'),{Readable:s}=await import('stream'),i=t.createReadStream(e);return s.toWeb(i);case "bun":return Bun.file(e).stream();case "deno":return (await Deno.open(e)).readable;default:throw new Error("Unsupported runtime")}}async readdir(e){switch(b.type){case "bun":case "node":return (await import('fs/promises')).readdir(e);case "deno":let s=[];for await(let i of Deno.readDir(e))s.push(i.name);return s;default:throw new Error("Unsupported runtime")}}},c=new pe;var ue=class{basename(e){switch(b.type){case "node":case "bun":case "deno":return re.basename(e);default:throw new Error("Unsupported runtime")}}join(...e){switch(b.type){case "node":case "bun":case "deno":return re.join(...e);default:throw new Error("Unsupported runtime")}}extName(e){switch(b.type){case "bun":case "node":case "deno":return re.extname(e);default:throw new Error("Unsupported runtime")}}resolve(...e){switch(b.type){case "bun":case "node":case "deno":return re.resolve(...e);default:throw new Error("Unsupported runtime")}}},d=new ue;var K=async r=>{let e=d.join(process.cwd(),"node_modules");if(!await c.exists(e))return r;let s=[];for(let i of r){let o=d.join(e,i);await c.exists(o)||s.push(i);}return s},S=async()=>await c.exists(d.join(process.cwd(),"yarn.lock"))?["yarn","add","-D"]:await c.exists(d.join(process.cwd(),"pnpm-lock.yaml"))?["pnpm","add","-D"]:await c.exists(d.join(process.cwd(),"package-lock.json"))?["npm","install","-D"]:await c.exists(d.join(process.cwd(),"bun.lockb"))?["bun","add","-D"]:await c.exists(d.join(process.cwd(),"deno.lock"))?["deno","add","-D"]:["npm","install","-D"],q=async(r,e,t,s,i=true)=>{let o=ve.createInterface({input:process.stdin,output:process.stdout}),l=t.join(", "),n=`Do you want to install the following ${i?"dev":""} dependencies using ${e}?
5
5
  ${l}
6
- (y/n): `;return new Promise(m=>{o.question(a,n=>{if(o.close(),n.toLowerCase()==="y"||n.toLowerCase()==="yes"){execSync(r,s),m(true);return}m(false);});})};var P=class extends y{static commandName="build";static description="Build the project for production, node.js only";static help=["Build the project for production, node.js only","It will create a production build of the project in the dist directory","Must have a tsconfig.json file in the root of the project","Must have esbuild installed as a dependency while running the command","Must have esbuild-plugin-copy installed as a dependency while running the command if you want to copy assets to the output directory","Example: npx balda build -t ./tsconfig.json -a ./assets"];static clearDist;static entry;static output;static tsconfig;static assets;static format;static packages;static sourcemap;static async handle(){if(typeof process===void 0&&(this.logger.error("Build command is only supported in node.js"),process.exit(1)),["esm","cjs"].includes(this.format)||(this.logger.error("Invalid format, must be 'esm' or 'cjs'"),process.exit(1)),["bundle","external"].includes(this.packages)||(this.logger.error("Invalid packages, must be 'bundle' or 'external'"),process.exit(1)),!await import('esbuild').then(a=>true).catch(()=>false)){let[a,m,n]=await S();await q(`${a} ${m} esbuild ${n}`,a,["esbuild"],{stdio:"inherit"})||(this.logger.warn("User chose to not continue with the installation of esbuild, exiting..."),process.exit(0));}let t=await import('esbuild').catch(a=>{throw this.logger.error("esbuild is not installed, please install it with `npm install -D esbuild` to use the build command"),new Error("esbuild is not installed")}),s=re.join(this.output,"assets"),i=[];if(this.assets){let{copy:a}=await import('esbuild-plugin-copy').catch(m=>{throw this.logger.error("esbuild-plugin-copy is not installed, please install it with `npm install -D esbuild-plugin-copy` to use the build command"),new Error("esbuild-plugin-copy is not installed")});ie.existsSync(s)||ie.mkdirSync(s,{recursive:true}),i.push(a({assets:{from:this.assets,to:s}}));}this.clearDist&&ie.existsSync(this.output)&&(this.logger.info("Clearing dist directory..."),ie.rmSync(this.output,{recursive:true})),this.logger.info("Building project...");let o=re.join(this.output,"server.js"),l=await t.build({tsconfig:this.tsconfig,entryPoints:[this.entry],bundle:true,platform:"node",outfile:o,minify:true,sourcemap:this.sourcemap,plugins:i,format:this.format,packages:this.packages});l.errors.length&&(this.logger.error(JSON.stringify({message:"Failed to build the project",errors:l.errors},null,2)),process.exit(1)),l.warnings.length&&this.logger.warn(JSON.stringify({message:"Failed to build the project",warnings:l.warnings},null,2)),this.logger.info(JSON.stringify({message:`Project built successfully in ${o}`,output:o,assets:!!this.assets},null,2)),process.exit(0);}};p([u({type:"boolean",aliases:["c"],name:"clear-dist",required:false,defaultValue:false,description:"Whether to clear the dist directory before building the project"})],P,"clearDist"),p([u({type:"string",aliases:["e"],name:"entry",required:false,defaultValue:"./src/index.ts",description:"The entry point of the project, default is ./src/index.ts"})],P,"entry"),p([u({type:"string",aliases:["o"],name:"output",required:false,defaultValue:"./dist",description:"The path to the output directory, default is ./dist"})],P,"output"),p([u({type:"string",aliases:["t"],name:"tsconfig",required:false,defaultValue:"./tsconfig.json",description:"The path to the tsconfig.json file, default is ./tsconfig.json"})],P,"tsconfig"),p([u({type:"string",aliases:["a"],name:"assets",required:false,description:"The path to the assets directory that will be loaded in the production build"})],P,"assets"),p([u({type:"string",aliases:["f"],name:"format",required:false,defaultValue:"esm",description:"The format to build the project, default is esm, can be 'esm' or 'cjs'"})],P,"format"),p([u({type:"string",aliases:["p"],name:"packages",required:false,defaultValue:"external",description:"Weather to bundle node_modules or not, default is external, can be 'bundle' or 'external'"})],P,"packages"),p([u({type:"boolean",aliases:["s"],name:"sourcemap",required:false,defaultValue:true,description:"Whether to generate sourcemaps or not, default is true"})],P,"sourcemap");var H=class extends y{static commandName="generate-command";static description="Generate a new command in the specified path";static help=["Generate a new cli command in the specified path","Example: npx balda generate-command my-command -p src/commands"];static path="src/commands";static name;static async handle(){if(A.getCommand(this.name)){let i=A.isBuiltInCommand(this.name)?"built-in":"user-defined";this.logger.error({commandName:this.name,type:i},`Command "${this.name}" already exists as a ${i} command. Cannot override existing commands.`);return}let t=this.getCommandTemplate();this.path=d.join(this.path,`${this.name}.ts`),await c.exists(d.join(process.cwd(),this.path))||await c.mkdir(d.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await c.writeFile(this.path,new TextEncoder().encode(t)),this.logger.info(`Command ${this.name} created successfully at ${this.path}`);}static getCommandTemplate(){return `import { Command, CommandOptions } from "balda";
6
+ (y/n): `;return new Promise(m=>{o.question(n,a=>{if(o.close(),a.toLowerCase()==="y"||a.toLowerCase()==="yes"){execSync(r,s),m(true);return}m(false);});})};var P=class extends y{static commandName="build";static description="Build the project for production, node.js only";static help=["Build the project for production, node.js only","It will create a production build of the project in the dist directory","Must have a tsconfig.json file in the root of the project","Must have esbuild installed as a dependency while running the command","Must have esbuild-plugin-copy installed as a dependency while running the command if you want to copy assets to the output directory","Example: npx balda build -t ./tsconfig.json -a ./assets"];static clearDist;static entry;static output;static tsconfig;static assets;static format;static packages;static sourcemap;static async handle(){if(typeof process===void 0&&(this.logger.error("Build command is only supported in node.js"),process.exit(1)),["esm","cjs"].includes(this.format)||(this.logger.error("Invalid format, must be 'esm' or 'cjs'"),process.exit(1)),["bundle","external"].includes(this.packages)||(this.logger.error("Invalid packages, must be 'bundle' or 'external'"),process.exit(1)),!await import('esbuild').then(n=>true).catch(()=>false)){let[n,m,a]=await S();await q(`${n} ${m} esbuild ${a}`,n,["esbuild"],{stdio:"inherit"})||(this.logger.warn("User chose to not continue with the installation of esbuild, exiting..."),process.exit(0));}let t=await import('esbuild').catch(n=>{throw this.logger.error("esbuild is not installed, please install it with `npm install -D esbuild` to use the build command"),new Error("esbuild is not installed")}),s=re.join(this.output,"assets"),i=[];if(this.assets){let{copy:n}=await import('esbuild-plugin-copy').catch(m=>{throw this.logger.error("esbuild-plugin-copy is not installed, please install it with `npm install -D esbuild-plugin-copy` to use the build command"),new Error("esbuild-plugin-copy is not installed")});ie.existsSync(s)||ie.mkdirSync(s,{recursive:true}),i.push(n({assets:{from:this.assets,to:s}}));}this.clearDist&&ie.existsSync(this.output)&&(this.logger.info("Clearing dist directory..."),ie.rmSync(this.output,{recursive:true})),this.logger.info("Building project...");let o=re.join(this.output,"server.js"),l=await t.build({tsconfig:this.tsconfig,entryPoints:[this.entry],bundle:true,platform:"node",outfile:o,minify:true,sourcemap:this.sourcemap,plugins:i,format:this.format,packages:this.packages});l.errors.length&&(this.logger.error(JSON.stringify({message:"Failed to build the project",errors:l.errors},null,2)),process.exit(1)),l.warnings.length&&this.logger.warn(JSON.stringify({message:"Failed to build the project",warnings:l.warnings},null,2)),this.logger.info(JSON.stringify({message:`Project built successfully in ${o}`,output:o,assets:!!this.assets},null,2)),process.exit(0);}};p([u({type:"boolean",aliases:["c"],name:"clear-dist",required:false,defaultValue:false,description:"Whether to clear the dist directory before building the project"})],P,"clearDist"),p([u({type:"string",aliases:["e"],name:"entry",required:false,defaultValue:"./src/index.ts",description:"The entry point of the project, default is ./src/index.ts"})],P,"entry"),p([u({type:"string",aliases:["o"],name:"output",required:false,defaultValue:"./dist",description:"The path to the output directory, default is ./dist"})],P,"output"),p([u({type:"string",aliases:["t"],name:"tsconfig",required:false,defaultValue:"./tsconfig.json",description:"The path to the tsconfig.json file, default is ./tsconfig.json"})],P,"tsconfig"),p([u({type:"string",aliases:["a"],name:"assets",required:false,description:"The path to the assets directory that will be loaded in the production build"})],P,"assets"),p([u({type:"string",aliases:["f"],name:"format",required:false,defaultValue:"esm",description:"The format to build the project, default is esm, can be 'esm' or 'cjs'"})],P,"format"),p([u({type:"string",aliases:["p"],name:"packages",required:false,defaultValue:"external",description:"Weather to bundle node_modules or not, default is external, can be 'bundle' or 'external'"})],P,"packages"),p([u({type:"boolean",aliases:["s"],name:"sourcemap",required:false,defaultValue:true,description:"Whether to generate sourcemaps or not, default is true"})],P,"sourcemap");var H=class extends y{static commandName="generate-command";static description="Generate a new command in the specified path";static help=["Generate a new cli command in the specified path","Example: npx balda generate-command my-command -p src/commands"];static path="src/commands";static name;static async handle(){if(A.getCommand(this.name)){let i=A.isBuiltInCommand(this.name)?"built-in":"user-defined";this.logger.error({commandName:this.name,type:i},`Command "${this.name}" already exists as a ${i} command. Cannot override existing commands.`);return}let t=this.getCommandTemplate();this.path=d.join(this.path,`${this.name}.ts`),await c.exists(d.join(process.cwd(),this.path))||await c.mkdir(d.join(process.cwd(),this.path.split("/").slice(0,-1).join("/")),{recursive:true}),await c.writeFile(this.path,new TextEncoder().encode(t)),this.logger.info(`Command ${this.name} created successfully at ${this.path}`);}static getCommandTemplate(){return `import { Command, CommandOptions } from "balda";
7
7
 
8
8
  export default class extends Command {
9
9
  static commandName = "${this.name}";
@@ -33,12 +33,12 @@ export default class ${e}Controller {
33
33
 
34
34
  @post("/")
35
35
  async create(req: Request, res: Response) {
36
- return { message: \`Create ${this.controllerName.toLowerCase()}\`, data: req.body };
36
+ return { message: \`Create ${this.controllerName.toLowerCase()}\`, data: req.parsedBody };
37
37
  }
38
38
 
39
39
  @put("/:id")
40
40
  async update(req: Request, res: Response) {
41
- return { message: \`Update ${this.controllerName.toLowerCase()} with id \${req.params.id}\`, data: req.body };
41
+ return { message: \`Update ${this.controllerName.toLowerCase()} with id \${req.params.id}\`, data: req.parsedBody };
42
42
  }
43
43
 
44
44
  @del("/:id")
@@ -112,28 +112,30 @@ export default class extends BaseQueue {
112
112
  }`}};p([v({description:"The name of the queue to generate",required:true})],F,"queueName"),p([u({description:"The path to the queue to generate, default is src/queues",type:"string",aliases:"p",name:"path",required:false,defaultValue:"src/queues"})],F,"path"),p([u({description:"The provider of the queue to generate, default is bullmq",type:"string",aliases:["pr"],name:"provider",required:false,defaultValue:"bullmq"})],F,"provider");var C=class extends y{static commandName="generate-sdk";static description="Generate a TypeScript SDK from your server's OpenAPI specification";static help=["Generate a TypeScript SDK from your server's OpenAPI specification","This command imports your server instance, starts it if needed, downloads the OpenAPI spec, and generates an SDK","","Arguments:"," serverPath Path to the server instance file (default: test/server/instance.ts)","","Flags:"," -o, --output <path> Output directory for generated SDK (default: sdk)"," -s, --swagger-path <path> Swagger UI path on your server (default: /docs)"," -c, --client <type> HTTP client to use: axios or fetch (default: fetch)"," --unwrap-response-data Automatically unwrap response data property"," --single-http-client Generate single HTTP client instance"," --type-prefix <prefix> Add prefix to all generated types"," --type-suffix <suffix> Add suffix to all generated types"," --enum-names-as-values Use enum names as values"," --sort-types Sort types alphabetically","","Examples:"," npx balda generate-sdk"," npx balda generate-sdk src/server/index.ts -o ./client-sdk"," npx balda generate-sdk src/server.ts --client axios"," npx balda generate-sdk --unwrap-response-data --single-http-client"," npx balda generate-sdk --type-prefix Api --sort-types"];static serverPath;static outputPath;static swaggerPath;static httpClient;static unwrapResponseData;static singleHttpClient;static typePrefix;static typeSuffix;static enumNamesAsValues;static sortTypes;static async handle(){console.log(`
113
113
  \u{1F680} Starting SDK generation...
114
114
  `);let e="swagger-typescript-api",t=d.join(process.cwd(),"node_modules"),s=await c.exists(t),i=d.join(t,e);if(!(s?await c.exists(i):false)){console.log(`\u{1F4E6} ${e} not found. Installing as dev dependency...
115
- `);let[f,x,ae]=await S();if(!await q(`${f} ${x} ${e} ${ae}`,f,[e],{stdio:"inherit"},true)){console.log(`\x1B[33m\u26A0\uFE0F SDK generation cancelled: swagger-typescript-api installation was skipped.\x1B[0m
115
+ `);let[f,x,ne]=await S();if(!await q(`${f} ${x} ${e} ${ne}`,f,[e],{stdio:"inherit"},true)){console.log(`\x1B[33m\u26A0\uFE0F SDK generation cancelled: swagger-typescript-api installation was skipped.\x1B[0m
116
116
  `);return}console.log(`
117
117
  \x1B[32m\u2705 ${e} installed successfully!\x1B[0m
118
118
  `);}let l=d.resolve(process.cwd(),this.serverPath);if(!await c.exists(l)){console.error(`\x1B[31m\u274C Error: Server file not found at ${l}\x1B[0m
119
- `);return}console.log(`\u{1F4C2} Loading server from: ${this.serverPath}`);let m;try{m=await import(`file://${l}`);}catch(f){console.error("\x1B[31m\u274C Error importing server module:\x1B[0m",f);return}let n=Object.keys(m),g=null;for(let f of n){let x=m[f];if("default"in x&&x.default&&(x=x.default),x&&"_brand"in x&&x._brand==="BaldaServer"&&typeof x=="object"&&"listen"in x){g=x,console.log(`\u2705 Found server instance in export: "${f}"
120
- `);break}}if(!g){console.error(`\x1B[31m\u274C Error: No Server instance found in ${this.serverPath}\x1B[0m`),console.log(`\x1B[90mExpected exports: ${n.join(", ")}\x1B[0m
119
+ `);return}console.log(`\u{1F4C2} Loading server from: ${this.serverPath}`);let m;try{m=await import(`file://${l}`);}catch(f){console.error("\x1B[31m\u274C Error importing server module:\x1B[0m",f);return}let a=Object.keys(m),g=null;for(let f of a){let x=m[f];if("default"in x&&x.default&&(x=x.default),x&&"_brand"in x&&x._brand==="BaldaServer"&&typeof x=="object"&&"listen"in x){g=x,console.log(`\u2705 Found server instance in export: "${f}"
120
+ `);break}}if(!g){console.error(`\x1B[31m\u274C Error: No Server instance found in ${this.serverPath}\x1B[0m`),console.log(`\x1B[90mExpected exports: ${a.join(", ")}\x1B[0m
121
121
  `);return}let $=false,N="";N="http://localhost:80";try{if(console.log(`\u{1F310} Starting server on ${N}...`),typeof g.listen=="function"&&!g.isListening)await new Promise((f,x)=>{try{g.listen(()=>{$=!0,console.log(`\u2705 Server started successfully!
122
- `),f();});}catch(ae){x(ae);}}).catch(f=>{console.error("Failed to start the server, continuing...");});else throw new Error("Server instance does not have a listen() method")}catch(f){console.error("\x1B[31m\u274C Error starting server:\x1B[0m",f);return}let w=this.swaggerPath??(typeof g.serverOptions.swagger!="boolean"?g.serverOptions.swagger?.path:"/docs"),R=d.join(N,w??"/docs","/json");console.log(`\u{1F4E5} Downloading OpenAPI spec from: ${R}`);let J;try{let f=await globalThis.fetch(R);if(!f.ok)throw new Error(`Failed to fetch OpenAPI spec: ${f.status} ${f.statusText}`);J=await f.json(),console.log(`\u2705 OpenAPI spec downloaded successfully!
123
- `);}catch(f){if(console.error("\x1B[31m\u274C Error downloading OpenAPI spec:\x1B[0m",f),$){let x=g;try{await x.close?.();}catch{}}return}let oe=d.join(process.cwd(),".openapi-spec.json");try{await c.writeFile(oe,new TextEncoder().encode(JSON.stringify(J,null,2)));}catch(f){if(console.error("\x1B[31m\u274C Error saving OpenAPI spec to file:\x1B[0m",f),$){let x=g;try{await x.close?.();}catch{}}return}let ne=d.resolve(process.cwd(),this.outputPath);console.log(`\u{1F528} Generating SDK...
124
- `);try{await c.exists(ne)||await c.mkdir(ne,{recursive:!0});let f=["npx swagger-typescript-api generate",`--path="${oe}"`,`--output="${this.outputPath}"`,`--http-client ${this.httpClient}`,"--modular","--extract-request-params","--extract-request-body","--extract-response-body","--extract-response-error"];this.unwrapResponseData&&f.push("--unwrap-response-data"),this.singleHttpClient&&f.push("--single-http-client"),this.typePrefix&&f.push(`--type-prefix "${this.typePrefix}"`),this.typeSuffix&&f.push(`--type-suffix "${this.typeSuffix}"`),this.enumNamesAsValues&&f.push("--enum-names-as-values"),this.sortTypes&&f.push("--sort-types");let x=f.join(" ");execSync(x,{stdio:"inherit",cwd:process.cwd()}),console.log(`
125
- \x1B[32m\u2705 SDK generated successfully!\x1B[0m`),console.log(`\x1B[32m\u{1F4C1} SDK location: ${ne}\x1B[0m
122
+ `),f();});}catch(ne){x(ne);}}).catch(f=>{console.error("Failed to start the server, continuing...");});else throw new Error("Server instance does not have a listen() method")}catch(f){console.error("\x1B[31m\u274C Error starting server:\x1B[0m",f);return}let w=this.swaggerPath??(typeof g.serverOptions.swagger!="boolean"?g.serverOptions.swagger?.path:"/docs"),R=d.join(N,w??"/docs","/json");console.log(`\u{1F4E5} Downloading OpenAPI spec from: ${R}`);let J;try{let f=await globalThis.fetch(R);if(!f.ok)throw new Error(`Failed to fetch OpenAPI spec: ${f.status} ${f.statusText}`);J=await f.json(),console.log(`\u2705 OpenAPI spec downloaded successfully!
123
+ `);}catch(f){if(console.error("\x1B[31m\u274C Error downloading OpenAPI spec:\x1B[0m",f),$){let x=g;try{await x.close?.();}catch{}}return}let oe=d.join(process.cwd(),".openapi-spec.json");try{await c.writeFile(oe,new TextEncoder().encode(JSON.stringify(J,null,2)));}catch(f){if(console.error("\x1B[31m\u274C Error saving OpenAPI spec to file:\x1B[0m",f),$){let x=g;try{await x.close?.();}catch{}}return}let ae=d.resolve(process.cwd(),this.outputPath);console.log(`\u{1F528} Generating SDK...
124
+ `);try{await c.exists(ae)||await c.mkdir(ae,{recursive:!0});let f=["npx swagger-typescript-api generate",`--path="${oe}"`,`--output="${this.outputPath}"`,`--http-client ${this.httpClient}`,"--modular","--extract-request-params","--extract-request-body","--extract-response-body","--extract-response-error"];this.unwrapResponseData&&f.push("--unwrap-response-data"),this.singleHttpClient&&f.push("--single-http-client"),this.typePrefix&&f.push(`--type-prefix "${this.typePrefix}"`),this.typeSuffix&&f.push(`--type-suffix "${this.typeSuffix}"`),this.enumNamesAsValues&&f.push("--enum-names-as-values"),this.sortTypes&&f.push("--sort-types");let x=f.join(" ");execSync(x,{stdio:"inherit",cwd:process.cwd()}),console.log(`
125
+ \x1B[32m\u2705 SDK generated successfully!\x1B[0m`),console.log(`\x1B[32m\u{1F4C1} SDK location: ${ae}\x1B[0m
126
126
  `);}catch(f){console.error("\x1B[31m\u274C Error generating SDK:\x1B[0m",f);}finally{try{await c.unlink(oe);}catch{}if($){let f=g;try{console.log("\u{1F6D1} Stopping server..."),await f.close?.(),console.log(`\u2705 Server stopped.
127
127
  `);}catch{console.log(`\x1B[33m\u26A0\uFE0F Could not stop server gracefully.\x1B[0m
128
128
  `);}}}console.log(`\x1B[32m\u2728 SDK generation complete!\x1B[0m
129
- `);}};p([v({description:"Path to the server instance file (should export a Server instance)",required:false,defaultValue:"test/server/instance.ts"})],C,"serverPath"),p([u({description:"Output directory for generated SDK",type:"string",aliases:["o"],name:"output",required:false,defaultValue:"sdk"})],C,"outputPath"),p([u({description:"Swagger UI path on your server",type:"string",aliases:["s"],name:"swagger-path",required:false})],C,"swaggerPath"),p([u({description:"HTTP client to use (axios or fetch)",type:"string",aliases:["c"],name:"client",required:false,defaultValue:"fetch"})],C,"httpClient"),p([u({description:"Unwrap response data automatically",type:"boolean",name:"unwrap-response-data",required:false,defaultValue:false})],C,"unwrapResponseData"),p([u({description:"Generate single HTTP client instance",type:"boolean",name:"single-http-client",required:false,defaultValue:false})],C,"singleHttpClient"),p([u({description:"Add prefix to all generated types",type:"string",name:"type-prefix",required:false})],C,"typePrefix"),p([u({description:"Add suffix to all generated types",type:"string",name:"type-suffix",required:false})],C,"typeSuffix"),p([u({description:"Use enum names as values",type:"boolean",name:"enum-names-as-values",required:false,defaultValue:false})],C,"enumNamesAsValues"),p([u({description:"Sort types alphabetically",type:"boolean",name:"sort-types",required:false,defaultValue:false})],C,"sortTypes");var k=class extends y{static commandName="init";static description="Initialize a new balda project in the current directory";static help=["Initialize a new balda project, it is given for granted that balda is installed in the project as a dependency","All the files are created in the /src directory (created if not exists)","It adds a server.ts for the file instance and a index.ts for the entry point with a dummy hello world route","Example: npx balda init -p ./src -t true"];static srcPath;static typescript;static mqtt;static cron;static devDependencies=["esbuild","esbuild-plugin-copy","tsx","typescript"];static async handle(){this.logger.info("Initializing project...");let[e,t,s]=await S();if(["npm","yarn","pnpm"].includes(e)){let a=await K(this.devDependencies);if(a.length&&(this.logger.info(`Found ${a.length} missing dev dependencies`),!await q(`${e} ${t} ${a.join(" ")} -${s}`,e,a,{stdio:"inherit"}))){this.logger.info("Installation cancelled by user. Project initialization aborted.");return}a.length||this.logger.info("All dev dependencies are already installed");}if(this.mqtt&&["npm","yarn","pnpm"].includes(e)){let a=await K(["mqtt"]);a.length&&(await q(`${e} ${t} mqtt`,e,["mqtt"],{stdio:"inherit"},false)||(this.logger.info("MQTT installation cancelled by user. Skipping MQTT scaffolding."),this.mqtt=false)),a.length||this.logger.info("MQTT package is already installed");}if(this.cron&&["npm","yarn","pnpm"].includes(e)){let a=await K(["node-cron"]);a.length>0&&(await q(`${e} ${t} node-cron`,e,["node-cron"],{stdio:"inherit"},false)||(this.logger.info("node-cron installation cancelled by user. Skipping Cron scaffolding."),this.cron=false)),a.length||this.logger.info("node-cron package is already installed");}let i=this.typescript?"ts":"js",o=this.getServerTemplate(),l=this.getIndexTemplate();if(c.exists(this.srcPath)||await c.mkdir(this.srcPath,{recursive:true}),this.logger.info(`Creating server.${i} file...`),await c.writeFile(`${this.srcPath}/server.${i}`,new TextEncoder().encode(o)),this.logger.info(`Creating index.${i} file...`),await c.writeFile(`${this.srcPath}/index.${i}`,new TextEncoder().encode(l)),this.mqtt){let a=d.join(this.srcPath,"mqtt");await c.exists(a)||await c.mkdir(a,{recursive:true});let m=this.getMqttConfigTemplate();this.logger.info(`Creating mqtt/mqtt.config.${i} file...`),await c.writeFile(d.join(a,`mqtt.config.${i}`),new TextEncoder().encode(m));}if(this.cron){let a=d.join(this.srcPath,"cron");await c.exists(a)||await c.mkdir(a,{recursive:true});let m=this.getCronConfigTemplate();this.logger.info(`Creating cron/cron.config.${i} file...`),await c.writeFile(d.join(a,`cron.config.${i}`),new TextEncoder().encode(m));}this.logger.info("Project initialized successfully!");}static getServerTemplate(){return `import { Server } from "balda";
129
+ `);}};p([v({description:"Path to the server instance file (should export a Server instance)",required:false,defaultValue:"test/server/instance.ts"})],C,"serverPath"),p([u({description:"Output directory for generated SDK",type:"string",aliases:["o"],name:"output",required:false,defaultValue:"sdk"})],C,"outputPath"),p([u({description:"Swagger UI path on your server",type:"string",aliases:["s"],name:"swagger-path",required:false})],C,"swaggerPath"),p([u({description:"HTTP client to use (axios or fetch)",type:"string",aliases:["c"],name:"client",required:false,defaultValue:"fetch"})],C,"httpClient"),p([u({description:"Unwrap response data automatically",type:"boolean",name:"unwrap-response-data",required:false,defaultValue:false})],C,"unwrapResponseData"),p([u({description:"Generate single HTTP client instance",type:"boolean",name:"single-http-client",required:false,defaultValue:false})],C,"singleHttpClient"),p([u({description:"Add prefix to all generated types",type:"string",name:"type-prefix",required:false})],C,"typePrefix"),p([u({description:"Add suffix to all generated types",type:"string",name:"type-suffix",required:false})],C,"typeSuffix"),p([u({description:"Use enum names as values",type:"boolean",name:"enum-names-as-values",required:false,defaultValue:false})],C,"enumNamesAsValues"),p([u({description:"Sort types alphabetically",type:"boolean",name:"sort-types",required:false,defaultValue:false})],C,"sortTypes");var k=class extends y{static commandName="init";static description="Initialize a new balda project in the current directory";static help=["Initialize a new balda project, it is given for granted that balda is installed in the project as a dependency","All the files are created in the /src directory (created if not exists)","It adds a server.ts for the file instance and a index.ts for the entry point with a dummy hello world route","Example: npx balda init -p ./src -t true"];static srcPath;static typescript;static mqtt;static cron;static devDependencies=["esbuild","esbuild-plugin-copy","tsx","typescript"];static async handle(){this.logger.info("Initializing project...");let[e,t,s]=await S();if(["npm","yarn","pnpm"].includes(e)){let n=await K(this.devDependencies);if(n.length&&(this.logger.info(`Found ${n.length} missing dev dependencies`),!await q(`${e} ${t} ${n.join(" ")} -${s}`,e,n,{stdio:"inherit"}))){this.logger.info("Installation cancelled by user. Project initialization aborted.");return}n.length||this.logger.info("All dev dependencies are already installed");}if(this.mqtt&&["npm","yarn","pnpm"].includes(e)){let n=await K(["mqtt"]);n.length&&(await q(`${e} ${t} mqtt`,e,["mqtt"],{stdio:"inherit"},false)||(this.logger.info("MQTT installation cancelled by user. Skipping MQTT scaffolding."),this.mqtt=false)),n.length||this.logger.info("MQTT package is already installed");}if(this.cron&&["npm","yarn","pnpm"].includes(e)){let n=await K(["node-cron"]);n.length>0&&(await q(`${e} ${t} node-cron`,e,["node-cron"],{stdio:"inherit"},false)||(this.logger.info("node-cron installation cancelled by user. Skipping Cron scaffolding."),this.cron=false)),n.length||this.logger.info("node-cron package is already installed");}let i=this.typescript?"ts":"js",o=this.getServerTemplate(),l=this.getIndexTemplate();if(c.exists(this.srcPath)||await c.mkdir(this.srcPath,{recursive:true}),this.logger.info(`Creating server.${i} file...`),await c.writeFile(`${this.srcPath}/server.${i}`,new TextEncoder().encode(o)),this.logger.info(`Creating index.${i} file...`),await c.writeFile(`${this.srcPath}/index.${i}`,new TextEncoder().encode(l)),this.mqtt){let n=d.join(this.srcPath,"mqtt");await c.exists(n)||await c.mkdir(n,{recursive:true});let m=this.getMqttConfigTemplate();this.logger.info(`Creating mqtt/mqtt.config.${i} file...`),await c.writeFile(d.join(n,`mqtt.config.${i}`),new TextEncoder().encode(m));}if(this.cron){let n=d.join(this.srcPath,"cron");await c.exists(n)||await c.mkdir(n,{recursive:true});let m=this.getCronConfigTemplate();this.logger.info(`Creating cron/cron.config.${i} file...`),await c.writeFile(d.join(n,`cron.config.${i}`),new TextEncoder().encode(m));}this.logger.info("Project initialized successfully!");}static getServerTemplate(){return `import { Server } from "balda";
130
130
 
131
131
  const serverInstance = new Server({
132
132
  port: 80,
133
133
  host: "0.0.0.0",
134
134
  plugins: {
135
- json: {
136
- sizeLimit: "100kb",
135
+ bodyParser: {
136
+ json: {
137
+ sizeLimit: "100kb",
138
+ }
137
139
  },
138
140
  },
139
141
  });
@@ -166,7 +168,7 @@ server.listen(({ url }) => {
166
168
  // This file is imported to set up Cron jobs
167
169
  // Add your cron jobs in separate files within this directory
168
170
  // Use: npx balda generate-cron <job-name> to create new cron jobs
169
- `}};p([u.string({description:"The path to the project, default is the current directory /src",aliases:"p",name:"path",required:false,defaultValue:"./src"})],k,"srcPath"),p([u.boolean({description:"Whether to use typescript, default is true",aliases:"t",name:"typescript",required:false,defaultValue:true})],k,"typescript"),p([u.boolean({description:"Initialize MQTT service connection",aliases:"m",name:"mqtt",required:false,defaultValue:false})],k,"mqtt"),p([u.boolean({description:"Initialize Cron service",aliases:"c",name:"cron",required:false,defaultValue:false})],k,"cron");var V=class extends y{static commandName="init-queue";static description="Initialize queue provider configuration with required dependencies";static help=["Initialize a queue provider configuration file with basic credentials","Automatically installs required packages for the selected provider","Only scaffolds the connection, handlers should be created with generate-queue command","Example: npx balda init-queue -t bullmq -o src/queue"];static queueType;static outputPath;static queueDependencies={bullmq:["bullmq","ioredis"],sqs:["@aws-sdk/client-sqs","sqs-consumer"],pgboss:["pg-boss","pg"]};static async handle(){if(this.logger.info(`Initializing ${this.queueType} queue provider...`),!["bullmq","sqs","pgboss"].includes(this.queueType)){this.logger.error(`Invalid queue type: ${this.queueType}. Must be one of: bullmq, sqs, pgboss`);return}let[e,t]=await S();if(["npm","yarn","pnpm"].includes(e)){let l=this.queueDependencies[this.queueType],a=await K(l);if(a.length>0&&(this.logger.info(`Found ${a.length} missing dependencies for ${this.queueType}`),!await q(`${e} ${t} ${a.join(" ")}`,e,a,{stdio:"inherit"},false))){this.logger.info("Installation cancelled by user. Queue initialization aborted.");return}a.length===0&&this.logger.info(`All ${this.queueType} dependencies are already installed`);}let s=this.getConfigTemplate(),i=`${this.queueType}.config.ts`,o=d.join(this.outputPath,i);await c.exists(this.outputPath)||await c.mkdir(this.outputPath,{recursive:true}),this.logger.info(`Creating ${i} file at ${this.outputPath}...`),await c.writeFile(o,new TextEncoder().encode(s)),this.logger.info(`Queue configuration initialized successfully at ${o}`),this.logger.info("Remember to update the configuration with your actual credentials"),this.logger.info("Use 'npx balda generate-queue' to create queue handlers");}static getConfigTemplate(){return this.queueType==="bullmq"?this.getBullMQTemplate():this.queueType==="sqs"?this.getSQSTemplate():this.queueType==="pgboss"?this.getPGBossTemplate():""}static getBullMQTemplate(){return `import { defineBullMQConfiguration } from "balda";
171
+ `}};p([u.string({description:"The path to the project, default is the current directory /src",aliases:"p",name:"path",required:false,defaultValue:"./src"})],k,"srcPath"),p([u.boolean({description:"Whether to use typescript, default is true",aliases:"t",name:"typescript",required:false,defaultValue:true})],k,"typescript"),p([u.boolean({description:"Initialize MQTT service connection",aliases:"m",name:"mqtt",required:false,defaultValue:false})],k,"mqtt"),p([u.boolean({description:"Initialize Cron service",aliases:"c",name:"cron",required:false,defaultValue:false})],k,"cron");var V=class extends y{static commandName="init-queue";static description="Initialize queue provider configuration with required dependencies";static help=["Initialize a queue provider configuration file with basic credentials","Automatically installs required packages for the selected provider","Only scaffolds the connection, handlers should be created with generate-queue command","Example: npx balda init-queue -t bullmq -o src/queue"];static queueType;static outputPath;static queueDependencies={bullmq:["bullmq","ioredis"],sqs:["@aws-sdk/client-sqs","sqs-consumer"],pgboss:["pg-boss","pg"]};static async handle(){if(this.logger.info(`Initializing ${this.queueType} queue provider...`),!["bullmq","sqs","pgboss"].includes(this.queueType)){this.logger.error(`Invalid queue type: ${this.queueType}. Must be one of: bullmq, sqs, pgboss`);return}let[e,t]=await S();if(["npm","yarn","pnpm"].includes(e)){let l=this.queueDependencies[this.queueType],n=await K(l);if(n.length>0&&(this.logger.info(`Found ${n.length} missing dependencies for ${this.queueType}`),!await q(`${e} ${t} ${n.join(" ")}`,e,n,{stdio:"inherit"},false))){this.logger.info("Installation cancelled by user. Queue initialization aborted.");return}n.length===0&&this.logger.info(`All ${this.queueType} dependencies are already installed`);}let s=this.getConfigTemplate(),i=`${this.queueType}.config.ts`,o=d.join(this.outputPath,i);await c.exists(this.outputPath)||await c.mkdir(this.outputPath,{recursive:true}),this.logger.info(`Creating ${i} file at ${this.outputPath}...`),await c.writeFile(o,new TextEncoder().encode(s)),this.logger.info(`Queue configuration initialized successfully at ${o}`),this.logger.info("Remember to update the configuration with your actual credentials"),this.logger.info("Use 'npx balda generate-queue' to create queue handlers");}static getConfigTemplate(){return this.queueType==="bullmq"?this.getBullMQTemplate():this.queueType==="sqs"?this.getSQSTemplate():this.queueType==="pgboss"?this.getPGBossTemplate():""}static getBullMQTemplate(){return `import { defineBullMQConfiguration } from "balda";
170
172
 
171
173
  // Configure BullMQ connection and default options
172
174
  defineBullMQConfiguration({
@@ -339,8 +341,8 @@ definePGBossConfiguration({
339
341
  \u2728 Available Balda Commands:
340
342
  `),t.length>0){console.log(`\x1B[1;33mUser Commands:\x1B[0m
341
343
  `);let s=this.groupByCategory(t);this.displayCategorizedCommands(s);}if(e.length>0){console.log(`\x1B[1;32mBuilt-in Commands:\x1B[0m
342
- `);let s=Math.max(...e.map(i=>i.commandName.length));for(let i of e){let o=i.commandName.padEnd(s+2),l=i.description||"No description available",a="";i.options?.deprecated&&(a=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${o}\x1B[0m ${l}${a}`);}console.log("");}console.log(`\x1B[90mRun 'npx balda <command> -h' for more information on a specific command.\x1B[0m
343
- `);}static groupByCategory(e){let t=new Map;for(let s of e){let i=s.options?.category||"other";t.has(i)||t.set(i,[]),t.get(i).push(s);}return t}static displayCategorizedCommands(e){let t=Array.from(e.keys()).sort();for(let s of t){let i=e.get(s).filter(m=>m&&m.commandName);if(i.length===0)continue;let l={generator:"\x1B[35m",setup:"\x1B[34m",production:"\x1B[32m",utility:"\x1B[36m",other:"\x1B[37m"}[s]||"\x1B[37m";console.log(` ${l}${s.toUpperCase()}:\x1B[0m`);let a=Math.max(...i.map(m=>m.commandName.length));for(let m of i){let n=m.commandName.padEnd(a+2),g=m.description||"No description available",$="";m.options?.deprecated&&($=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${n}\x1B[0m ${g}${$}`);}console.log("");}}};var z=class extends y{static commandName="serve";static description="Run the server in dev mode with hot reload";static help=["This command is intended to be run from the root of the project","Bun and Deno have native dev hot reload","Runtime is automatically inferred","Node.js requires tsx to be installed for both typescript and javascript files","Node.js dev dependencies (tsx) are installed automatically if not detected"];static runtime=b.type;static options={keepAlive:true};static entry;static denoImportMap;static async handle(){if(this.runtime==="bun"){execSync(`bun run --watch ${this.entry}`,{stdio:"inherit",cwd:G.getCwd()});return}if(this.runtime==="deno"){let e="deno run --watch --unstable-sloppy-imports --allow-all";this.denoImportMap&&(e=`${e} --import-map ${this.denoImportMap}`),execSync(`${e} ${this.entry}`,{stdio:"inherit",cwd:G.getCwd()});return}this.handleNodeHotReload();}static async handleNodeHotReload(){if(!ie.existsSync("node_modules/.bin/tsx")){let[s,i,o]=await S();if(!await q(`${s} ${i} tsx ${o}`,s,["tsx"],{stdio:"inherit"})){this.logger.info("Installation cancelled by user. Cannot start dev server without tsx.");return}}let t=this.calledBy!=="node"?this.calledBy:"npx";execSync(`${t} tsx watch ${this.entry}`,{stdio:"inherit",cwd:process.cwd()});}};p([v({required:false,defaultValue:"src/index.ts",description:"The entry point of the project, default is src/index.ts"})],z,"entry"),p([u.string({aliases:["d"],name:"deno-import-map",required:false,description:"Path to deno import map"})],z,"denoImportMap");var Q=class extends y{static commandName="setup-storage";static description="Setup storage provider with required dependencies";static help=["Install dependencies and create storage configuration for a specific provider","Flags:"," -t, --type <provider> Storage provider type (s3, azure, local)"," -o, --output <path> Output directory for storage setup (default: src/storage/)","","Examples:"," npx balda setup:storage -t s3"," npx balda setup:storage --type azure --output src/config/"];static storageType;static outputPath;static async handle(){if(!this.storageType){console.error("\x1B[31m\u274C Error: Storage type is required. Use -t or --type flag.\x1B[0m"),console.log(`\x1B[90mExample: npx balda setup:storage -t s3\x1B[0m
344
+ `);let s=Math.max(...e.map(i=>i.commandName.length));for(let i of e){let o=i.commandName.padEnd(s+2),l=i.description||"No description available",n="";i.options?.deprecated&&(n=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${o}\x1B[0m ${l}${n}`);}console.log("");}console.log(`\x1B[90mRun 'npx balda <command> -h' for more information on a specific command.\x1B[0m
345
+ `);}static groupByCategory(e){let t=new Map;for(let s of e){let i=s.options?.category||"other";t.has(i)||t.set(i,[]),t.get(i).push(s);}return t}static displayCategorizedCommands(e){let t=Array.from(e.keys()).sort();for(let s of t){let i=e.get(s).filter(m=>m&&m.commandName);if(i.length===0)continue;let l={generator:"\x1B[35m",setup:"\x1B[34m",production:"\x1B[32m",utility:"\x1B[36m",other:"\x1B[37m"}[s]||"\x1B[37m";console.log(` ${l}${s.toUpperCase()}:\x1B[0m`);let n=Math.max(...i.map(m=>m.commandName.length));for(let m of i){let a=m.commandName.padEnd(n+2),g=m.description||"No description available",$="";m.options?.deprecated&&($=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${a}\x1B[0m ${g}${$}`);}console.log("");}}};var z=class extends y{static commandName="serve";static description="Run the server in dev mode with hot reload";static help=["This command is intended to be run from the root of the project","Bun and Deno have native dev hot reload","Runtime is automatically inferred","Node.js requires tsx to be installed for both typescript and javascript files","Node.js dev dependencies (tsx) are installed automatically if not detected"];static runtime=b.type;static options={keepAlive:true};static entry;static denoImportMap;static async handle(){if(this.runtime==="bun"){execSync(`bun run --watch ${this.entry}`,{stdio:"inherit",cwd:G.getCwd()});return}if(this.runtime==="deno"){let e="deno run --watch --unstable-sloppy-imports --allow-all";this.denoImportMap&&(e=`${e} --import-map ${this.denoImportMap}`),execSync(`${e} ${this.entry}`,{stdio:"inherit",cwd:G.getCwd()});return}this.handleNodeHotReload();}static async handleNodeHotReload(){if(!ie.existsSync("node_modules/.bin/tsx")){let[s,i,o]=await S();if(!await q(`${s} ${i} tsx ${o}`,s,["tsx"],{stdio:"inherit"})){this.logger.info("Installation cancelled by user. Cannot start dev server without tsx.");return}}let t=this.calledBy!=="node"?this.calledBy:"npx";execSync(`${t} tsx watch ${this.entry}`,{stdio:"inherit",cwd:process.cwd()});}};p([v({required:false,defaultValue:"src/index.ts",description:"The entry point of the project, default is src/index.ts"})],z,"entry"),p([u.string({aliases:["d"],name:"deno-import-map",required:false,description:"Path to deno import map"})],z,"denoImportMap");var Q=class extends y{static commandName="setup-storage";static description="Setup storage provider with required dependencies";static help=["Install dependencies and create storage configuration for a specific provider","Flags:"," -t, --type <provider> Storage provider type (s3, azure, local)"," -o, --output <path> Output directory for storage setup (default: src/storage/)","","Examples:"," npx balda setup:storage -t s3"," npx balda setup:storage --type azure --output src/config/"];static storageType;static outputPath;static async handle(){if(!this.storageType){console.error("\x1B[31m\u274C Error: Storage type is required. Use -t or --type flag.\x1B[0m"),console.log(`\x1B[90mExample: npx balda setup:storage -t s3\x1B[0m
344
346
  `);return}this.outputPath||await c.mkdir(d.join(process.cwd(),this.outputPath),{recursive:true});let e=["s3","azure","local"];if(!e.includes(this.storageType)){console.error(`\x1B[31m\u274C Error: Invalid storage type '${this.storageType}'. Valid types: ${e.join(", ")}\x1B[0m
345
347
  `);return}console.log(`
346
348
  \u{1F680} Setting up ${this.storageType.toUpperCase()} storage provider...
@@ -350,7 +352,7 @@ definePGBossConfiguration({
350
352
  `);return}console.log(`
351
353
  \x1B[32m\u2705 Dependencies installed successfully!\x1B[0m
352
354
  `);}}await this.createStorageSetup(this.storageType,this.outputPath),console.log(`\x1B[32m\u2728 ${this.storageType.toUpperCase()} storage setup complete!\x1B[0m
353
- `);}static getDependencies(e){return {s3:["@aws-sdk/client-s3","@aws-sdk/s3-request-presigner","@aws-sdk/cloudfront-signer"],azure:["@azure/storage-blob"],local:[]}[e]||[]}static async checkMissingDependencies(e){let t=d.join(process.cwd(),"package.json");if(!await c.exists(t))return e;let i=d.join(process.cwd(),"node_modules");if(!await c.exists(i))return e;let l=[];for(let a of e){let m=d.join(i,a);await c.exists(m)||l.push(a);}return l}static async createStorageSetup(e,t){let s=d.join(process.cwd(),t);await c.exists(s)||await c.mkdir(s,{recursive:true});let o=d.join(s,"storage.ts");if(await c.exists(o)){console.log(`\x1B[33m\u26A0\uFE0F Configuration file already exists: ${o}\x1B[0m`);return}let a=this.getConfigTemplate(e);await c.writeFile(o,new TextEncoder().encode(a)),console.log(`\x1B[32m\u2705 Created configuration file: ${o}\x1B[0m`);}static getConfigTemplate(e){return {s3:`import { Storage, S3StorageProvider } from "balda";
355
+ `);}static getDependencies(e){return {s3:["@aws-sdk/client-s3","@aws-sdk/s3-request-presigner","@aws-sdk/cloudfront-signer"],azure:["@azure/storage-blob"],local:[]}[e]||[]}static async checkMissingDependencies(e){let t=d.join(process.cwd(),"package.json");if(!await c.exists(t))return e;let i=d.join(process.cwd(),"node_modules");if(!await c.exists(i))return e;let l=[];for(let n of e){let m=d.join(i,n);await c.exists(m)||l.push(n);}return l}static async createStorageSetup(e,t){let s=d.join(process.cwd(),t);await c.exists(s)||await c.mkdir(s,{recursive:true});let o=d.join(s,"storage.ts");if(await c.exists(o)){console.log(`\x1B[33m\u26A0\uFE0F Configuration file already exists: ${o}\x1B[0m`);return}let n=this.getConfigTemplate(e);await c.writeFile(o,new TextEncoder().encode(n)),console.log(`\x1B[32m\u2705 Created configuration file: ${o}\x1B[0m`);}static getConfigTemplate(e){return {s3:`import { Storage, S3StorageProvider } from "balda";
354
356
 
355
357
  /**
356
358
  * S3 Storage Configuration
@@ -430,11 +432,11 @@ export const storage = new Storage(
430
432
  defaultProvider: "local",
431
433
  },
432
434
  );
433
- `}[e]||""}};p([u({description:"Storage provider type (s3, azure, local)",type:"string",aliases:["t"],name:"type",required:true})],Q,"storageType"),p([u({description:"Output directory for storage setup",type:"string",aliases:["o"],name:"output",required:false,defaultValue:"src/storage/"})],Q,"outputPath");var ke=[B,H,_,L,F,D,U,C,k,V,Y,P,z,Q],I=class r{commands;builtInCommands;static commandsPattern="src/commands/**/*.{ts,js}";static logger=se;constructor(){this.commands=new Map,this.builtInCommands=new Set;}static getInstance(){return new r}static setCommandsPattern(e){this.commandsPattern=e;}getCommand(e){return this.commands.get(e)??null}getCommands(){return Array.from(this.commands.values())}getBuiltInCommands(){return Array.from(this.commands.values()).filter(e=>this.builtInCommands.has(e.commandName))}getUserDefinedCommands(){return Array.from(this.commands.values()).filter(e=>!this.builtInCommands.has(e.commandName))}isBuiltInCommand(e){return this.builtInCommands.has(e)}async loadCommands(e){r.logger.info(`Loading commands from ${e}`);let t=await glob(e,{absolute:true,cwd:G.getCwd()});if(t.some(s=>s.endsWith(".ts")))try{let{register:s}=await import('module');s("ts-node/esm",import.meta.url);}catch{r.logger.error("Failed to register ts-node/esm, you need to install it in your project in order to use typescript in the cli\ntry running: `npm install -D ts-node`"),process.exit(1);}for(let s of t){let i=await import(s).then(o=>o.default?o.default:o).catch(o=>(r.logger.error(`Error loading command ${s}: ${o}`),null));i&&this.commands.set(i.commandName,i);}for(let s of ke)this.commands.set(s.commandName,s),this.builtInCommands.add(s.commandName);}},A=I.getInstance();var Ie=r=>{let e=new Map;for(let t of r){let s=t.options?.category||"other";e.has(s)||e.set(s,[]),e.get(s).push(t);}return e},Re=r=>{let e=Array.from(r.keys()).sort();for(let t of e){let s=r.get(t).filter(a=>a&&a.commandName);if(!s.length)continue;let o={generator:"\x1B[35m",setup:"\x1B[34m",production:"\x1B[32m",utility:"\x1B[36m",other:"\x1B[37m"}[t]||"\x1B[37m";console.log(` ${o}${t.toUpperCase()}:\x1B[0m`);let l=Math.max(...s.map(a=>a.commandName.length));for(let a of s){let m=a.commandName.padEnd(l+2),n=a.description||"No description available",g="";a.options?.deprecated&&(g=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${m}\x1B[0m ${n}${g}`);}console.log("");}},fe=async()=>{await A.loadCommands(I.commandsPattern);let[r,...e]=W.getCliArgs();if(!r||r==="-h"||r==="--help"){let o=A.getBuiltInCommands(),l=A.getUserDefinedCommands();if(console.log(`
435
+ `}[e]||""}};p([u({description:"Storage provider type (s3, azure, local)",type:"string",aliases:["t"],name:"type",required:true})],Q,"storageType"),p([u({description:"Output directory for storage setup",type:"string",aliases:["o"],name:"output",required:false,defaultValue:"src/storage/"})],Q,"outputPath");var ke=[B,H,_,L,F,D,U,C,k,V,Y,P,z,Q],I=class r{commands;builtInCommands;static commandsPattern="src/commands/**/*.{ts,js}";static logger=se;constructor(){this.commands=new Map,this.builtInCommands=new Set;}static getInstance(){return new r}static setCommandsPattern(e){this.commandsPattern=e;}getCommand(e){return this.commands.get(e)??null}getCommands(){return Array.from(this.commands.values())}getBuiltInCommands(){return Array.from(this.commands.values()).filter(e=>this.builtInCommands.has(e.commandName))}getUserDefinedCommands(){return Array.from(this.commands.values()).filter(e=>!this.builtInCommands.has(e.commandName))}isBuiltInCommand(e){return this.builtInCommands.has(e)}async loadCommands(e){r.logger.info(`Loading commands from ${e}`);let t=await glob(e,{absolute:true,cwd:G.getCwd()});if(t.some(s=>s.endsWith(".ts")))try{let{register:s}=await import('module');s("ts-node/esm",import.meta.url);}catch{r.logger.error("Failed to register ts-node/esm, you need to install it in your project in order to use typescript in the cli\ntry running: `npm install -D ts-node`"),process.exit(1);}for(let s of t){let i=await import(s).then(o=>o.default?o.default:o).catch(o=>(r.logger.error(`Error loading command ${s}: ${o}`),null));i&&this.commands.set(i.commandName,i);}for(let s of ke)this.commands.set(s.commandName,s),this.builtInCommands.add(s.commandName);}},A=I.getInstance();var Ie=r=>{let e=new Map;for(let t of r){let s=t.options?.category||"other";e.has(s)||e.set(s,[]),e.get(s).push(t);}return e},Re=r=>{let e=Array.from(r.keys()).sort();for(let t of e){let s=r.get(t).filter(n=>n&&n.commandName);if(!s.length)continue;let o={generator:"\x1B[35m",setup:"\x1B[34m",production:"\x1B[32m",utility:"\x1B[36m",other:"\x1B[37m"}[t]||"\x1B[37m";console.log(` ${o}${t.toUpperCase()}:\x1B[0m`);let l=Math.max(...s.map(n=>n.commandName.length));for(let n of s){let m=n.commandName.padEnd(l+2),a=n.description||"No description available",g="";n.options?.deprecated&&(g=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${m}\x1B[0m ${a}${g}`);}console.log("");}},fe=async()=>{await A.loadCommands(I.commandsPattern);let[r,...e]=W.getCliArgs();if(!r||r==="-h"||r==="--help"){let o=A.getBuiltInCommands(),l=A.getUserDefinedCommands();if(console.log(`
434
436
  \u2728 Available Balda Commands:
435
437
  `),l.length&&(console.log(`\x1B[1;33mUser Commands:\x1B[0m
436
438
  `),Re(Ie(l))),o.length){console.log(`\x1B[1;32mBuilt-in Commands:\x1B[0m
437
- `);let a=Math.max(...o.map(m=>m.commandName.length));for(let m of o){let n=m.commandName.padEnd(a+2),g=m.description||"No description available",$="";m.options?.deprecated&&($=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${n}\x1B[0m ${g}${$}`);}console.log("");}console.log(`\x1B[90mRun 'npx balda <command> -h' for more information on a specific command.\x1B[0m
439
+ `);let n=Math.max(...o.map(m=>m.commandName.length));for(let m of o){let a=m.commandName.padEnd(n+2),g=m.description||"No description available",$="";m.options?.deprecated&&($=" \x1B[33m[deprecated]\x1B[0m"),console.log(` \x1B[36m${a}\x1B[0m ${g}${$}`);}console.log("");}console.log(`\x1B[90mRun 'npx balda <command> -h' for more information on a specific command.\x1B[0m
438
440
  `),E.exit(0);return}let t=A.getCommand(r);if(!t){console.error(xe(r,A.getCommands().filter(o=>o&&o.commandName).map(o=>o.commandName))||`Command ${r} not found`),E.exit(1);return}let s=t;if(s.calledBy=d.basename(W.getCliCaller()),s.options?.deprecated){let o=s.options.deprecated.message||"This command is deprecated",l=s.options.deprecated.replacement;console.warn(`\x1B[33m\u26A0\uFE0F Warning: ${o}\x1B[0m`),l&&console.warn(`\x1B[33m Use '${l}' instead.\x1B[0m
439
441
  `);}if(s.handleHelpFlag(s.flags),s.validateContext(s),s.options?.validate&&!await s.options.validate(s)){console.error("Command validation failed"),E.exit(1);return}await s.handle(),(t.options?.keepAlive??false)||E.exit(0);};typeof process<"u"?fe().catch(async r=>{if(r?.message?.includes("SyntaxError")||r?.code==="ERR_UNKNOWN_FILE_EXTENSION")try{let{register:e}=await import('module');e("ts-node/esm",import.meta.url),fe().catch(t=>{I.logger.error(t),process.exit(1);});}catch{I.logger.error("Failed to register ts-node/esm, you need to install it in your project in order to use typescript in the cli\ntry running: `npm install -D ts-node`"),process.exit(1);}else I.logger.error(r),process.exit(1);}):fe().catch(r=>{I.logger.error(r),E.exit(1);});export{fe as cli};//# sourceMappingURL=cli.js.map
440
442
  //# sourceMappingURL=cli.js.map