@ooneex/cli 1.9.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,38 +1,38 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var ca=Object.create;var{getPrototypeOf:pa,defineProperty:Wt,getOwnPropertyNames:ma}=Object;var ua=Object.prototype.hasOwnProperty;function ha(e){return this[e]}var fa,ya,ee=(e,t,s)=>{var r=e!=null&&typeof e==="object";if(r){var o=t?fa??=new WeakMap:ya??=new WeakMap,i=o.get(e);if(i)return i}s=e!=null?ca(pa(e)):{};let a=t||!e||!e.__esModule?Wt(s,"default",{value:e,enumerable:!0}):s;for(let n of ma(e))if(!ua.call(a,n))Wt(a,n,{get:ha.bind(e,n),enumerable:!0});if(r)o.set(e,a);return a};var x=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var b=function(e,t,s,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,s):r,a;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")i=Reflect.decorate(e,t,s,r);else for(var n=e.length-1;n>=0;n--)if(a=e[n])i=(o<3?a(i):o>3?a(t,s,i):a(t,s))||i;return o>3&&i&&Object.defineProperty(t,s,i),i};var ge=import.meta.require;var Zt=x((Vp,be)=>{var Na=typeof process<"u"&&process.env.TERM_PROGRAM==="Hyper",Sa=typeof process<"u"&&process.platform==="win32",Vt=typeof process<"u"&&process.platform==="linux",nt={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",question:"?",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},Yt=Object.assign({},nt,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),zt=Object.assign({},nt,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:Vt?"\u25B8":"\u276F",pointerSmall:Vt?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});be.exports=Sa&&!Na?Yt:zt;Reflect.defineProperty(be.exports,"common",{enumerable:!1,value:nt});Reflect.defineProperty(be.exports,"windows",{enumerable:!1,value:Yt});Reflect.defineProperty(be.exports,"other",{enumerable:!1,value:zt})});var Re=x((Yp,dt)=>{var Ta=(e)=>e!==null&&typeof e==="object"&&!Array.isArray(e),Ra=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,Ma=()=>{if(typeof process<"u")return process.env.FORCE_COLOR!=="0";return!1},Qt=()=>{let e={enabled:Ma(),visible:!0,styles:{},keys:{}},t=(i)=>{let a=i.open=`\x1B[${i.codes[0]}m`,n=i.close=`\x1B[${i.codes[1]}m`,d=i.regex=new RegExp(`\\u001b\\[${i.codes[1]}m`,"g");return i.wrap=(l,p)=>{if(l.includes(n))l=l.replace(d,n+a);let u=a+l+n;return p?u.replace(/\r*\n/g,`${n}$&${a}`):u},i},s=(i,a,n)=>{return typeof i==="function"?i(a):i.wrap(a,n)},r=(i,a)=>{if(i===""||i==null)return"";if(e.enabled===!1)return i;if(e.visible===!1)return"";let n=""+i,d=n.includes(`
4
- `),l=a.length;if(l>0&&a.includes("unstyle"))a=[...new Set(["unstyle",...a])].reverse();while(l-- >0)n=s(e.styles[a[l]],n,d);return n},o=(i,a,n)=>{e.styles[i]=t({name:i,codes:a}),(e.keys[n]||(e.keys[n]=[])).push(i),Reflect.defineProperty(e,i,{configurable:!0,enumerable:!0,set(l){e.alias(i,l)},get(){let l=(p)=>r(p,l.stack);return Reflect.setPrototypeOf(l,e),l.stack=this.stack?this.stack.concat(i):[i],l}})};return o("reset",[0,0],"modifier"),o("bold",[1,22],"modifier"),o("dim",[2,22],"modifier"),o("italic",[3,23],"modifier"),o("underline",[4,24],"modifier"),o("inverse",[7,27],"modifier"),o("hidden",[8,28],"modifier"),o("strikethrough",[9,29],"modifier"),o("black",[30,39],"color"),o("red",[31,39],"color"),o("green",[32,39],"color"),o("yellow",[33,39],"color"),o("blue",[34,39],"color"),o("magenta",[35,39],"color"),o("cyan",[36,39],"color"),o("white",[37,39],"color"),o("gray",[90,39],"color"),o("grey",[90,39],"color"),o("bgBlack",[40,49],"bg"),o("bgRed",[41,49],"bg"),o("bgGreen",[42,49],"bg"),o("bgYellow",[43,49],"bg"),o("bgBlue",[44,49],"bg"),o("bgMagenta",[45,49],"bg"),o("bgCyan",[46,49],"bg"),o("bgWhite",[47,49],"bg"),o("blackBright",[90,39],"bright"),o("redBright",[91,39],"bright"),o("greenBright",[92,39],"bright"),o("yellowBright",[93,39],"bright"),o("blueBright",[94,39],"bright"),o("magentaBright",[95,39],"bright"),o("cyanBright",[96,39],"bright"),o("whiteBright",[97,39],"bright"),o("bgBlackBright",[100,49],"bgBright"),o("bgRedBright",[101,49],"bgBright"),o("bgGreenBright",[102,49],"bgBright"),o("bgYellowBright",[103,49],"bgBright"),o("bgBlueBright",[104,49],"bgBright"),o("bgMagentaBright",[105,49],"bgBright"),o("bgCyanBright",[106,49],"bgBright"),o("bgWhiteBright",[107,49],"bgBright"),e.ansiRegex=Ra,e.hasColor=e.hasAnsi=(i)=>{return e.ansiRegex.lastIndex=0,typeof i==="string"&&i!==""&&e.ansiRegex.test(i)},e.alias=(i,a)=>{let n=typeof a==="string"?e[a]:a;if(typeof n!=="function")throw TypeError("Expected alias to be the name of an existing color (string) or a function");if(!n.stack)Reflect.defineProperty(n,"name",{value:i}),e.styles[i]=n,n.stack=[i];Reflect.defineProperty(e,i,{configurable:!0,enumerable:!0,set(d){e.alias(i,d)},get(){let d=(l)=>r(l,d.stack);return Reflect.setPrototypeOf(d,e),d.stack=this.stack?this.stack.concat(n.stack):n.stack,d}})},e.theme=(i)=>{if(!Ta(i))throw TypeError("Expected theme to be an object");for(let a of Object.keys(i))e.alias(a,i[a]);return e},e.alias("unstyle",(i)=>{if(typeof i==="string"&&i!=="")return e.ansiRegex.lastIndex=0,i.replace(e.ansiRegex,"");return""}),e.alias("noop",(i)=>i),e.none=e.clear=e.noop,e.stripColor=e.unstyle,e.symbols=Zt(),e.define=o,e};dt.exports=Qt();dt.exports.create=Qt});var M=x((_a)=>{var Ca=Object.prototype.toString,D=Re(),Xt=!1,we=new Set,Jt={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};_a.longest=(e,t)=>{return e.reduce((s,r)=>Math.max(s,t?r[t].length:r.length),0)};_a.hasColor=(e)=>!!e&&D.hasColor(e);var Me=_a.isObject=(e)=>{return e!==null&&typeof e==="object"&&!Array.isArray(e)};_a.nativeType=(e)=>{return Ca.call(e).slice(8,-1).toLowerCase().replace(/\s/g,"")};_a.isAsyncFn=(e)=>{return _a.nativeType(e)==="asyncfunction"};_a.isPrimitive=(e)=>{return e!=null&&typeof e!=="object"&&typeof e!=="function"};_a.resolve=(e,t,...s)=>{if(typeof t==="function")return t.call(e,...s);return t};_a.scrollDown=(e=[])=>[...e.slice(1),e[0]];_a.scrollUp=(e=[])=>[e.pop(),...e];_a.reorder=(e=[])=>{let t=e.slice();return t.sort((s,r)=>{if(s.index>r.index)return 1;if(s.index<r.index)return-1;return 0}),t};_a.swap=(e,t,s)=>{let r=e.length,o=s===r?0:s<0?r-1:s,i=e[t];e[t]=e[o],e[o]=i};_a.width=(e,t=80)=>{let s=e&&e.columns?e.columns:t;if(e&&typeof e.getWindowSize==="function")s=e.getWindowSize()[0];if(process.platform==="win32")return s-1;return s};_a.height=(e,t=20)=>{let s=e&&e.rows?e.rows:t;if(e&&typeof e.getWindowSize==="function")s=e.getWindowSize()[1];return s};_a.wordWrap=(e,t={})=>{if(!e)return e;if(typeof t==="number")t={width:t};let{indent:s="",newline:r=`
5
- `+s,width:o=80}=t,i=(r+s).match(/[^\S\n]/g)||[];o-=i.length;let a=`.{1,${o}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,n=e.trim(),d=new RegExp(a,"g"),l=n.match(d)||[];if(l=l.map((p)=>p.replace(/\n$/,"")),t.padEnd)l=l.map((p)=>p.padEnd(o," "));if(t.padStart)l=l.map((p)=>p.padStart(o," "));return s+l.join(r)};_a.unmute=(e)=>{let t=e.stack.find((r)=>D.keys.color.includes(r));if(t)return D[t];if(e.stack.find((r)=>r.slice(2)==="bg"))return D[t.slice(2)];return(r)=>r};_a.pascal=(e)=>e?e[0].toUpperCase()+e.slice(1):"";_a.inverse=(e)=>{if(!e||!e.stack)return e;let t=e.stack.find((r)=>D.keys.color.includes(r));if(t){let r=D["bg"+_a.pascal(t)];return r?r.black:e}let s=e.stack.find((r)=>r.slice(0,2)==="bg");if(s)return D[s.slice(2).toLowerCase()]||e;return D.none};_a.complement=(e)=>{if(!e||!e.stack)return e;let t=e.stack.find((r)=>D.keys.color.includes(r)),s=e.stack.find((r)=>r.slice(0,2)==="bg");if(t&&!s)return D[Jt[t]||t];if(s){let r=s.slice(2).toLowerCase(),o=Jt[r];if(!o)return e;return D["bg"+_a.pascal(o)]||e}return D.none};_a.meridiem=(e)=>{let t=e.getHours(),s=e.getMinutes(),r=t>=12?"pm":"am";t=t%12;let o=t===0?12:t,i=s<10?"0"+s:s;return o+":"+i+" "+r};_a.set=(e={},t="",s)=>{return t.split(".").reduce((r,o,i,a)=>{let n=a.length-1>i?r[o]||{}:s;if(!_a.isObject(n)&&i<a.length-1)n={};return r[o]=n},e)};_a.get=(e={},t="",s)=>{let r=e[t]==null?t.split(".").reduce((o,i)=>o&&o[i],e):e[t];return r==null?s:r};_a.mixin=(e,t)=>{if(!Me(e))return t;if(!Me(t))return e;for(let s of Object.keys(t)){let r=Object.getOwnPropertyDescriptor(t,s);if(hasOwnProperty.call(r,"value"))if(hasOwnProperty.call(e,s)&&Me(r.value)){let o=Object.getOwnPropertyDescriptor(e,s);if(Me(o.value)&&o.value!==r.value)e[s]=_a.merge({},e[s],t[s]);else Reflect.defineProperty(e,s,r)}else Reflect.defineProperty(e,s,r);else Reflect.defineProperty(e,s,r)}return e};_a.merge=(...e)=>{let t={};for(let s of e)_a.mixin(t,s);return t};_a.mixinEmitter=(e,t)=>{let s=t.constructor.prototype;for(let r of Object.keys(s)){let o=s[r];if(typeof o==="function")_a.define(e,r,o.bind(t));else _a.define(e,r,o)}};var Ce=(e,t)=>{if(Xt)return;if(Xt=!0,we.forEach((s)=>s()),e===!0)process.exit(128+t)},jt=Ce.bind(null,!0,15),es=Ce.bind(null,!0,2);_a.onExit=(e)=>{if(we.size===0)process.once("SIGTERM",jt),process.once("SIGINT",es),process.once("exit",Ce);return we.add(e),()=>{if(we.delete(e),we.size===0)process.off("SIGTERM",jt),process.off("SIGINT",es),process.off("exit",Ce)}};_a.define=(e,t,s)=>{Reflect.defineProperty(e,t,{value:s})};_a.defineExport=(e,t,s)=>{let r;Reflect.defineProperty(e,t,{enumerable:!0,configurable:!0,set(o){r=o},get(){return r?r():s()}})}});var is=x((Zp,os)=>{os.exports=({onlyFirst:e=!1}={})=>{let t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}});var te=x((Qp,as)=>{var en=is();as.exports=(e)=>typeof e==="string"?e.replace(en(),""):e});var ns=x((tn)=>{tn.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};tn.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};tn.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};tn.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};tn.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var ls=x((Jp,ds)=>{ds.exports=class{_queue=[];_executing=!1;_jobRunner=null;constructor(t){this._jobRunner=t}enqueue=(...t)=>{this._queue.push(t),this._dequeue()};destroy(){this._queue.length=0,this._jobRunner=null}_dequeue(){if(this._executing||!this._queue.length)return;this._executing=!0,this._jobRunner(...this._queue.shift()),setTimeout(()=>{this._executing=!1,this._dequeue()})}}});var ct=x((jp,ps)=>{var cs=ge("readline"),dn=ns(),ln=ls(),cn=/^(?:\x1b)([a-zA-Z0-9])$/,pn=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,mn={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function un(e){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(e)}function hn(e){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(e)}var _e=(e="",t={})=>{let s,r={name:t.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:e,raw:e,...t};if(Buffer.isBuffer(e))if(e[0]>127&&e[1]===void 0)e[0]-=128,e="\x1B"+String(e);else e=String(e);else if(e!==void 0&&typeof e!=="string")e=String(e);else if(!e)e=r.sequence||"";if(r.sequence=r.sequence||e||r.name,e==="\r")r.raw=void 0,r.name="return";else if(e===`
6
- `)r.name="enter";else if(e==="\t")r.name="tab";else if(e==="\b"||e==="\x7F"||e==="\x1B\x7F"||e==="\x1B\b")r.name="backspace",r.meta=e.charAt(0)==="\x1B";else if(e==="\x1B"||e==="\x1B\x1B")r.name="escape",r.meta=e.length===2;else if(e===" "||e==="\x1B ")r.name="space",r.meta=e.length===2;else if(e<="\x1A")r.name=String.fromCharCode(e.charCodeAt(0)+97-1),r.ctrl=!0;else if(e.length===1&&e>="0"&&e<="9")r.name="number";else if(e.length===1&&e>="a"&&e<="z")r.name=e;else if(e.length===1&&e>="A"&&e<="Z")r.name=e.toLowerCase(),r.shift=!0;else if(s=cn.exec(e))r.meta=!0,r.shift=/^[A-Z]$/.test(s[1]);else if(s=pn.exec(e)){let o=[...e];if(o[0]==="\x1B"&&o[1]==="\x1B")r.option=!0;let i=[s[1],s[2],s[4],s[6]].filter(Boolean).join(""),a=(s[3]||s[5]||1)-1;r.ctrl=!!(a&4),r.meta=!!(a&10),r.shift=!!(a&1),r.code=i,r.name=mn[i],r.shift=un(i)||r.shift,r.ctrl=hn(i)||r.ctrl}return r};_e.listen=(e={},t)=>{let{stdin:s}=e;if(!s||s!==process.stdin&&!s.isTTY)throw Error("Invalid stream passed");let r=cs.createInterface({terminal:!0,input:s});cs.emitKeypressEvents(s,r);let o=new ln((n,d)=>t(n,_e(n,d),r)),i=s.isRaw;if(s.isTTY)s.setRawMode(!0);return s.on("keypress",o.enqueue),r.resume(),()=>{if(s.isTTY)s.setRawMode(i);s.removeListener("keypress",o.enqueue),o.destroy(),r.pause(),r.close()}};_e.action=(e,t,s)=>{let r={...dn,...s};if(t.ctrl)return t.action=r.ctrl[t.name],t;if(t.option&&r.option)return t.action=r.option[t.name],t;if(t.shift)return t.action=r.shift[t.name],t;return t.action=r.keys[t.name],t};ps.exports=_e});var us=x((em,ms)=>{ms.exports=(e)=>{e.timers=e.timers||{};let t=e.options.timers;if(!t)return;for(let s of Object.keys(t)){let r=t[s];if(typeof r==="number")r={interval:r};fn(e,s,r)}};function fn(e,t,s={}){let r=e.timers[t]={name:t,start:Date.now(),ms:0,tick:0},o=s.interval||120;r.frames=s.frames||[],r.loading=!0;let i=setInterval(()=>{r.ms=Date.now()-r.start,r.tick++,e.render()},o);return r.stop=()=>{r.loading=!1,clearInterval(i)},Reflect.defineProperty(r,"interval",{value:i}),e.once("close",()=>r.stop()),r.stop}});var ys=x((tm,fs)=>{var{define:yn,width:gn}=M();class hs{constructor(e){let t=e.options;yn(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=gn(t.stdout||process.stdout),Object.assign(this,t),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e={...this};return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let t=this._color||e[this.status];return typeof t==="function"?t:e.pending}set loading(e){this._loading=e}get loading(){if(typeof this._loading==="boolean")return this._loading;if(this.loadingChoices)return"choices";return!1}get status(){if(this.cancelled)return"cancelled";if(this.submitted)return"submitted";return"pending"}}fs.exports=hs});var bs=x((sm,gs)=>{var pt=M(),R=Re(),mt={default:R.noop,noop:R.noop,set inverse(e){this._inverse=e},get inverse(){return this._inverse||pt.inverse(this.primary)},set complement(e){this._complement=e},get complement(){return this._complement||pt.complement(this.primary)},primary:R.cyan,success:R.green,danger:R.magenta,strong:R.bold,warning:R.yellow,muted:R.dim,disabled:R.gray,dark:R.dim.gray,underline:R.underline,set info(e){this._info=e},get info(){return this._info||this.primary},set em(e){this._em=e},get em(){return this._em||this.primary.underline},set heading(e){this._heading=e},get heading(){return this._heading||this.muted.underline},set pending(e){this._pending=e},get pending(){return this._pending||this.primary},set submitted(e){this._submitted=e},get submitted(){return this._submitted||this.success},set cancelled(e){this._cancelled=e},get cancelled(){return this._cancelled||this.danger},set typing(e){this._typing=e},get typing(){return this._typing||this.dim},set placeholder(e){this._placeholder=e},get placeholder(){return this._placeholder||this.primary.dim},set highlight(e){this._highlight=e},get highlight(){return this._highlight||this.inverse}};mt.merge=(e={})=>{if(e.styles&&typeof e.styles.enabled==="boolean")R.enabled=e.styles.enabled;if(e.styles&&typeof e.styles.visible==="boolean")R.visible=e.styles.visible;let t=pt.merge({},mt,e.styles);delete t.merge;for(let s of Object.keys(R))if(!hasOwnProperty.call(t,s))Reflect.defineProperty(t,s,{get:()=>R[s]});for(let s of Object.keys(R.styles))if(!hasOwnProperty.call(t,s))Reflect.defineProperty(t,s,{get:()=>R[s]});return t};gs.exports=mt});var xs=x((rm,ws)=>{var ut=process.platform==="win32",K=Re(),bn=M(),ht={...K.symbols,upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:K.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:K.symbols.question,submitted:K.symbols.check,cancelled:K.symbols.cross},separator:{pending:K.symbols.pointerSmall,submitted:K.symbols.middot,cancelled:K.symbols.middot},radio:{off:ut?"( )":"\u25EF",on:ut?"(*)":"\u25C9",disabled:ut?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]};ht.merge=(e)=>{let t=bn.merge({},K.symbols,ht,e.symbols);return delete t.merge,t};ws.exports=ht});var As=x((om,Es)=>{var wn=bs(),xn=xs(),En=M();Es.exports=(e)=>{e.options=En.merge({},e.options.theme,e.options),e.symbols=xn.merge(e.options),e.styles=wn.merge(e.options)}});var Ts=x((Ns,Ss)=>{var vs=process.env.TERM_PROGRAM==="Apple_Terminal",An=te(),ft=M(),P=Ss.exports=Ns,yt=!1,se=P.code={bell:"\x07",beep:"\x07",beginning:"\x1B[G",down:"\x1B[J",esc:"\x1B[",getPosition:"\x1B[6n",hide:"\x1B[?25l",line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",restorePosition:"\x1B["+(vs?"8":"u"),savePosition:"\x1B["+(vs?"7":"s"),screen:"\x1B[2J",show:"\x1B[?25h",up:"\x1B[1J"},ae=P.cursor={get hidden(){return yt},hide(){return yt=!0,se.hide},show(){return yt=!1,se.show},forward:(e=1)=>`\x1B[${e}C`,backward:(e=1)=>`\x1B[${e}D`,nextLine:(e=1)=>"\x1B[E".repeat(e),prevLine:(e=1)=>"\x1B[F".repeat(e),up:(e=1)=>e?`\x1B[${e}A`:"",down:(e=1)=>e?`\x1B[${e}B`:"",right:(e=1)=>e?`\x1B[${e}C`:"",left:(e=1)=>e?`\x1B[${e}D`:"",to(e,t){return t?`\x1B[${t+1};${e+1}H`:`\x1B[${e+1}G`},move(e=0,t=0){let s="";return s+=e<0?ae.left(-e):e>0?ae.right(e):"",s+=t<0?ae.up(-t):t>0?ae.down(t):"",s},strLen(e){var t=0,s=e.length,r=-1;for(var o=0;o<s;o++)if(r=e.charCodeAt(o),r>=0&&r<=128)t+=1;else t+=2;return t},restore(e={}){let{after:t,cursor:s,initial:r,input:o,prompt:i,size:a,value:n}=e;if(r=ft.isPrimitive(r)?String(r):"",o=ft.isPrimitive(o)?String(o):"",n=ft.isPrimitive(n)?String(n):"",a){let d=P.cursor.up(a)+P.cursor.to(this.strLen(i)),l=o.length-s;if(l>0)d+=P.cursor.left(l);return d}if(n||t){let d=!o&&!!r?-this.strLen(r):-this.strLen(o)+s;if(t)d-=this.strLen(t);if(o===""&&r&&!i.includes(r))d+=this.strLen(r);return P.cursor.move(d)}}},gt=P.erase={screen:se.screen,up:se.up,down:se.down,line:se.line,lineEnd:se.lineEnd,lineStart:se.lineStart,lines(e){let t="";for(let s=0;s<e;s++)t+=P.erase.line+(s<e-1?P.cursor.up(1):"");if(e)t+=P.code.beginning;return t}};P.clear=(e="",t=process.stdout.columns)=>{if(!t)return gt.line+ae.to(0);let s=(i)=>[...An(i)].length,r=e.split(/\r?\n/),o=0;for(let i of r)o+=1+Math.floor(Math.max(s(i)-1,0)/t);return(gt.line+ae.prevLine()).repeat(o-1)+gt.line+ae.to(0)}});var me=x((im,Ms)=>{var vn=ge("events"),Rs=te(),bt=ct(),Nn=us(),Sn=ys(),Tn=As(),_=M(),ne=Ts();class wt extends vn{constructor(e={}){super();this.name=e.name,this.type=e.type,this.options=e,Tn(this),Nn(this),this.state=new Sn(this),this.initial=[e.initial,e.default].find((t)=>t!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=Mn(this.options.margin),this.setMaxListeners(0),Rn(this)}async keypress(e,t={}){this.keypressed=!0;let s=bt.action(e,bt(e,t),this.options.actions);this.state.keypress=s,this.emit("keypress",e,s),this.emit("state",this.state.clone());let r=this.options[s.action]||this[s.action]||this.dispatch;if(typeof r==="function")return await r.call(this,e,s);this.alert()}alert(){if(delete this.state.alert,this.options.show===!1)this.emit("alert");else this.stdout.write(ne.code.beep)}cursorHide(){this.stdout.write(ne.cursor.hide());let e=_.onExit(()=>this.cursorShow());this.on("close",()=>{this.cursorShow(),e()})}cursorShow(){this.stdout.write(ne.cursor.show())}write(e){if(!e)return;if(this.stdout&&this.state.show!==!1)this.stdout.write(e);this.state.buffer+=e}clear(e=0){let t=this.state.buffer;if(this.state.buffer="",!t&&!e||this.options.show===!1)return;this.stdout.write(ne.cursor.down(e)+ne.clear(t,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:t,rest:s}=this.sections(),{cursor:r,initial:o="",input:i="",value:a=""}=this,n=this.state.size=s.length,d={after:t,cursor:r,initial:o,input:i,prompt:e,size:n,value:a},l=ne.cursor.restore(d);if(l)this.stdout.write(l)}sections(){let{buffer:e,input:t,prompt:s}=this.state;s=Rs(s);let r=Rs(e),o=r.indexOf(s),i=r.slice(0,o),n=r.slice(o).split(`
7
- `),d=n[0],l=n[n.length-1],u=(s+(t?" "+t:"")).length,m=u<d.length?d.slice(u+1):"";return{header:i,prompt:d,after:m,rest:n.slice(1),last:l}}async submit(){if(this.state.submitted=!0,this.state.validating=!0,this.options.onSubmit)await this.options.onSubmit.call(this,this.name,this.value,this);let e=this.state.error||await this.validate(this.value,this.state);if(e!==!0){let t=`
3
+ var Sa=Object.create;var{getPrototypeOf:Na,defineProperty:Kt,getOwnPropertyNames:Ra}=Object;var Ca=Object.prototype.hasOwnProperty;function Ma(e){return this[e]}var _a,Ba,te=(e,t,s)=>{var o=e!=null&&typeof e==="object";if(o){var r=t?_a??=new WeakMap:Ba??=new WeakMap,i=r.get(e);if(i)return i}s=e!=null?Sa(Na(e)):{};let a=t||!e||!e.__esModule?Kt(s,"default",{value:e,enumerable:!0}):s;for(let n of Ra(e))if(!Ca.call(a,n))Kt(a,n,{get:Ma.bind(e,n),enumerable:!0});if(o)r.set(e,a);return a};var E=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var b=function(e,t,s,o){var r=arguments.length,i=r<3?t:o===null?o=Object.getOwnPropertyDescriptor(t,s):o,a;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")i=Reflect.decorate(e,t,s,o);else for(var n=e.length-1;n>=0;n--)if(a=e[n])i=(r<3?a(i):r>3?a(t,s,i):a(t,s))||i;return r>3&&i&&Object.defineProperty(t,s,i),i};var ve=import.meta.require;var Xt=E((Em,Ae)=>{var Ga=typeof process<"u"&&process.env.TERM_PROGRAM==="Hyper",$a=typeof process<"u"&&process.platform==="win32",Yt=typeof process<"u"&&process.platform==="linux",dt={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",question:"?",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},Qt=Object.assign({},dt,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),Zt=Object.assign({},dt,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:Yt?"\u25B8":"\u276F",pointerSmall:Yt?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});Ae.exports=$a&&!Ga?Qt:Zt;Reflect.defineProperty(Ae.exports,"common",{enumerable:!1,value:dt});Reflect.defineProperty(Ae.exports,"windows",{enumerable:!1,value:Qt});Reflect.defineProperty(Ae.exports,"other",{enumerable:!1,value:Zt})});var Ie=E((vm,pt)=>{var qa=(e)=>e!==null&&typeof e==="object"&&!Array.isArray(e),Wa=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,Fa=()=>{if(typeof process<"u")return process.env.FORCE_COLOR!=="0";return!1},Jt=()=>{let e={enabled:Fa(),visible:!0,styles:{},keys:{}},t=(i)=>{let a=i.open=`\x1B[${i.codes[0]}m`,n=i.close=`\x1B[${i.codes[1]}m`,l=i.regex=new RegExp(`\\u001b\\[${i.codes[1]}m`,"g");return i.wrap=(d,c)=>{if(d.includes(n))d=d.replace(l,n+a);let u=a+d+n;return c?u.replace(/\r*\n/g,`${n}$&${a}`):u},i},s=(i,a,n)=>{return typeof i==="function"?i(a):i.wrap(a,n)},o=(i,a)=>{if(i===""||i==null)return"";if(e.enabled===!1)return i;if(e.visible===!1)return"";let n=""+i,l=n.includes(`
4
+ `),d=a.length;if(d>0&&a.includes("unstyle"))a=[...new Set(["unstyle",...a])].reverse();while(d-- >0)n=s(e.styles[a[d]],n,l);return n},r=(i,a,n)=>{e.styles[i]=t({name:i,codes:a}),(e.keys[n]||(e.keys[n]=[])).push(i),Reflect.defineProperty(e,i,{configurable:!0,enumerable:!0,set(d){e.alias(i,d)},get(){let d=(c)=>o(c,d.stack);return Reflect.setPrototypeOf(d,e),d.stack=this.stack?this.stack.concat(i):[i],d}})};return r("reset",[0,0],"modifier"),r("bold",[1,22],"modifier"),r("dim",[2,22],"modifier"),r("italic",[3,23],"modifier"),r("underline",[4,24],"modifier"),r("inverse",[7,27],"modifier"),r("hidden",[8,28],"modifier"),r("strikethrough",[9,29],"modifier"),r("black",[30,39],"color"),r("red",[31,39],"color"),r("green",[32,39],"color"),r("yellow",[33,39],"color"),r("blue",[34,39],"color"),r("magenta",[35,39],"color"),r("cyan",[36,39],"color"),r("white",[37,39],"color"),r("gray",[90,39],"color"),r("grey",[90,39],"color"),r("bgBlack",[40,49],"bg"),r("bgRed",[41,49],"bg"),r("bgGreen",[42,49],"bg"),r("bgYellow",[43,49],"bg"),r("bgBlue",[44,49],"bg"),r("bgMagenta",[45,49],"bg"),r("bgCyan",[46,49],"bg"),r("bgWhite",[47,49],"bg"),r("blackBright",[90,39],"bright"),r("redBright",[91,39],"bright"),r("greenBright",[92,39],"bright"),r("yellowBright",[93,39],"bright"),r("blueBright",[94,39],"bright"),r("magentaBright",[95,39],"bright"),r("cyanBright",[96,39],"bright"),r("whiteBright",[97,39],"bright"),r("bgBlackBright",[100,49],"bgBright"),r("bgRedBright",[101,49],"bgBright"),r("bgGreenBright",[102,49],"bgBright"),r("bgYellowBright",[103,49],"bgBright"),r("bgBlueBright",[104,49],"bgBright"),r("bgMagentaBright",[105,49],"bgBright"),r("bgCyanBright",[106,49],"bgBright"),r("bgWhiteBright",[107,49],"bgBright"),e.ansiRegex=Wa,e.hasColor=e.hasAnsi=(i)=>{return e.ansiRegex.lastIndex=0,typeof i==="string"&&i!==""&&e.ansiRegex.test(i)},e.alias=(i,a)=>{let n=typeof a==="string"?e[a]:a;if(typeof n!=="function")throw TypeError("Expected alias to be the name of an existing color (string) or a function");if(!n.stack)Reflect.defineProperty(n,"name",{value:i}),e.styles[i]=n,n.stack=[i];Reflect.defineProperty(e,i,{configurable:!0,enumerable:!0,set(l){e.alias(i,l)},get(){let l=(d)=>o(d,l.stack);return Reflect.setPrototypeOf(l,e),l.stack=this.stack?this.stack.concat(n.stack):n.stack,l}})},e.theme=(i)=>{if(!qa(i))throw TypeError("Expected theme to be an object");for(let a of Object.keys(i))e.alias(a,i[a]);return e},e.alias("unstyle",(i)=>{if(typeof i==="string"&&i!=="")return e.ansiRegex.lastIndex=0,i.replace(e.ansiRegex,"");return""}),e.alias("noop",(i)=>i),e.none=e.clear=e.noop,e.stripColor=e.unstyle,e.symbols=Xt(),e.define=r,e};pt.exports=Jt();pt.exports.create=Jt});var M=E((Ha)=>{var Ka=Object.prototype.toString,D=Ie(),jt=!1,Te=new Set,es={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};Ha.longest=(e,t)=>{return e.reduce((s,o)=>Math.max(s,t?o[t].length:o.length),0)};Ha.hasColor=(e)=>!!e&&D.hasColor(e);var Oe=Ha.isObject=(e)=>{return e!==null&&typeof e==="object"&&!Array.isArray(e)};Ha.nativeType=(e)=>{return Ka.call(e).slice(8,-1).toLowerCase().replace(/\s/g,"")};Ha.isAsyncFn=(e)=>{return Ha.nativeType(e)==="asyncfunction"};Ha.isPrimitive=(e)=>{return e!=null&&typeof e!=="object"&&typeof e!=="function"};Ha.resolve=(e,t,...s)=>{if(typeof t==="function")return t.call(e,...s);return t};Ha.scrollDown=(e=[])=>[...e.slice(1),e[0]];Ha.scrollUp=(e=[])=>[e.pop(),...e];Ha.reorder=(e=[])=>{let t=e.slice();return t.sort((s,o)=>{if(s.index>o.index)return 1;if(s.index<o.index)return-1;return 0}),t};Ha.swap=(e,t,s)=>{let o=e.length,r=s===o?0:s<0?o-1:s,i=e[t];e[t]=e[r],e[r]=i};Ha.width=(e,t=80)=>{let s=e&&e.columns?e.columns:t;if(e&&typeof e.getWindowSize==="function")s=e.getWindowSize()[0];if(process.platform==="win32")return s-1;return s};Ha.height=(e,t=20)=>{let s=e&&e.rows?e.rows:t;if(e&&typeof e.getWindowSize==="function")s=e.getWindowSize()[1];return s};Ha.wordWrap=(e,t={})=>{if(!e)return e;if(typeof t==="number")t={width:t};let{indent:s="",newline:o=`
5
+ `+s,width:r=80}=t,i=(o+s).match(/[^\S\n]/g)||[];r-=i.length;let a=`.{1,${r}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,n=e.trim(),l=new RegExp(a,"g"),d=n.match(l)||[];if(d=d.map((c)=>c.replace(/\n$/,"")),t.padEnd)d=d.map((c)=>c.padEnd(r," "));if(t.padStart)d=d.map((c)=>c.padStart(r," "));return s+d.join(o)};Ha.unmute=(e)=>{let t=e.stack.find((o)=>D.keys.color.includes(o));if(t)return D[t];if(e.stack.find((o)=>o.slice(2)==="bg"))return D[t.slice(2)];return(o)=>o};Ha.pascal=(e)=>e?e[0].toUpperCase()+e.slice(1):"";Ha.inverse=(e)=>{if(!e||!e.stack)return e;let t=e.stack.find((o)=>D.keys.color.includes(o));if(t){let o=D["bg"+Ha.pascal(t)];return o?o.black:e}let s=e.stack.find((o)=>o.slice(0,2)==="bg");if(s)return D[s.slice(2).toLowerCase()]||e;return D.none};Ha.complement=(e)=>{if(!e||!e.stack)return e;let t=e.stack.find((o)=>D.keys.color.includes(o)),s=e.stack.find((o)=>o.slice(0,2)==="bg");if(t&&!s)return D[es[t]||t];if(s){let o=s.slice(2).toLowerCase(),r=es[o];if(!r)return e;return D["bg"+Ha.pascal(r)]||e}return D.none};Ha.meridiem=(e)=>{let t=e.getHours(),s=e.getMinutes(),o=t>=12?"pm":"am";t=t%12;let r=t===0?12:t,i=s<10?"0"+s:s;return r+":"+i+" "+o};Ha.set=(e={},t="",s)=>{return t.split(".").reduce((o,r,i,a)=>{let n=a.length-1>i?o[r]||{}:s;if(!Ha.isObject(n)&&i<a.length-1)n={};return o[r]=n},e)};Ha.get=(e={},t="",s)=>{let o=e[t]==null?t.split(".").reduce((r,i)=>r&&r[i],e):e[t];return o==null?s:o};Ha.mixin=(e,t)=>{if(!Oe(e))return t;if(!Oe(t))return e;for(let s of Object.keys(t)){let o=Object.getOwnPropertyDescriptor(t,s);if(hasOwnProperty.call(o,"value"))if(hasOwnProperty.call(e,s)&&Oe(o.value)){let r=Object.getOwnPropertyDescriptor(e,s);if(Oe(r.value)&&r.value!==o.value)e[s]=Ha.merge({},e[s],t[s]);else Reflect.defineProperty(e,s,o)}else Reflect.defineProperty(e,s,o);else Reflect.defineProperty(e,s,o)}return e};Ha.merge=(...e)=>{let t={};for(let s of e)Ha.mixin(t,s);return t};Ha.mixinEmitter=(e,t)=>{let s=t.constructor.prototype;for(let o of Object.keys(s)){let r=s[o];if(typeof r==="function")Ha.define(e,o,r.bind(t));else Ha.define(e,o,r)}};var De=(e,t)=>{if(jt)return;if(jt=!0,Te.forEach((s)=>s()),e===!0)process.exit(128+t)},ts=De.bind(null,!0,15),ss=De.bind(null,!0,2);Ha.onExit=(e)=>{if(Te.size===0)process.once("SIGTERM",ts),process.once("SIGINT",ss),process.once("exit",De);return Te.add(e),()=>{if(Te.delete(e),Te.size===0)process.off("SIGTERM",ts),process.off("SIGINT",ss),process.off("exit",De)}};Ha.define=(e,t,s)=>{Reflect.defineProperty(e,t,{value:s})};Ha.defineExport=(e,t,s)=>{let o;Reflect.defineProperty(e,t,{enumerable:!0,configurable:!0,set(r){o=r},get(){return o?o():s()}})}});var ns=E((Tm,as)=>{as.exports=({onlyFirst:e=!1}={})=>{let t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}});var se=E((Sm,ls)=>{var yn=ns();ls.exports=(e)=>typeof e==="string"?e.replace(yn(),""):e});var ds=E((gn)=>{gn.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};gn.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};gn.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};gn.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};gn.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var cs=E((Rm,ps)=>{ps.exports=class{_queue=[];_executing=!1;_jobRunner=null;constructor(t){this._jobRunner=t}enqueue=(...t)=>{this._queue.push(t),this._dequeue()};destroy(){this._queue.length=0,this._jobRunner=null}_dequeue(){if(this._executing||!this._queue.length)return;this._executing=!0,this._jobRunner(...this._queue.shift()),setTimeout(()=>{this._executing=!1,this._dequeue()})}}});var mt=E((Cm,us)=>{var ms=ve("readline"),An=ds(),Tn=cs(),Sn=/^(?:\x1b)([a-zA-Z0-9])$/,Nn=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,Rn={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function Cn(e){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(e)}function Mn(e){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(e)}var Pe=(e="",t={})=>{let s,o={name:t.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:e,raw:e,...t};if(Buffer.isBuffer(e))if(e[0]>127&&e[1]===void 0)e[0]-=128,e="\x1B"+String(e);else e=String(e);else if(e!==void 0&&typeof e!=="string")e=String(e);else if(!e)e=o.sequence||"";if(o.sequence=o.sequence||e||o.name,e==="\r")o.raw=void 0,o.name="return";else if(e===`
6
+ `)o.name="enter";else if(e==="\t")o.name="tab";else if(e==="\b"||e==="\x7F"||e==="\x1B\x7F"||e==="\x1B\b")o.name="backspace",o.meta=e.charAt(0)==="\x1B";else if(e==="\x1B"||e==="\x1B\x1B")o.name="escape",o.meta=e.length===2;else if(e===" "||e==="\x1B ")o.name="space",o.meta=e.length===2;else if(e<="\x1A")o.name=String.fromCharCode(e.charCodeAt(0)+97-1),o.ctrl=!0;else if(e.length===1&&e>="0"&&e<="9")o.name="number";else if(e.length===1&&e>="a"&&e<="z")o.name=e;else if(e.length===1&&e>="A"&&e<="Z")o.name=e.toLowerCase(),o.shift=!0;else if(s=Sn.exec(e))o.meta=!0,o.shift=/^[A-Z]$/.test(s[1]);else if(s=Nn.exec(e)){let r=[...e];if(r[0]==="\x1B"&&r[1]==="\x1B")o.option=!0;let i=[s[1],s[2],s[4],s[6]].filter(Boolean).join(""),a=(s[3]||s[5]||1)-1;o.ctrl=!!(a&4),o.meta=!!(a&10),o.shift=!!(a&1),o.code=i,o.name=Rn[i],o.shift=Cn(i)||o.shift,o.ctrl=Mn(i)||o.ctrl}return o};Pe.listen=(e={},t)=>{let{stdin:s}=e;if(!s||s!==process.stdin&&!s.isTTY)throw Error("Invalid stream passed");let o=ms.createInterface({terminal:!0,input:s});ms.emitKeypressEvents(s,o);let r=new Tn((n,l)=>t(n,Pe(n,l),o)),i=s.isRaw;if(s.isTTY)s.setRawMode(!0);return s.on("keypress",r.enqueue),o.resume(),()=>{if(s.isTTY)s.setRawMode(i);s.removeListener("keypress",r.enqueue),r.destroy(),o.pause(),o.close()}};Pe.action=(e,t,s)=>{let o={...An,...s};if(t.ctrl)return t.action=o.ctrl[t.name],t;if(t.option&&o.option)return t.action=o.option[t.name],t;if(t.shift)return t.action=o.shift[t.name],t;return t.action=o.keys[t.name],t};us.exports=Pe});var fs=E((Mm,hs)=>{hs.exports=(e)=>{e.timers=e.timers||{};let t=e.options.timers;if(!t)return;for(let s of Object.keys(t)){let o=t[s];if(typeof o==="number")o={interval:o};_n(e,s,o)}};function _n(e,t,s={}){let o=e.timers[t]={name:t,start:Date.now(),ms:0,tick:0},r=s.interval||120;o.frames=s.frames||[],o.loading=!0;let i=setInterval(()=>{o.ms=Date.now()-o.start,o.tick++,e.render()},r);return o.stop=()=>{o.loading=!1,clearInterval(i)},Reflect.defineProperty(o,"interval",{value:i}),e.once("close",()=>o.stop()),o.stop}});var bs=E((_m,gs)=>{var{define:Bn,width:In}=M();class ys{constructor(e){let t=e.options;Bn(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=In(t.stdout||process.stdout),Object.assign(this,t),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e={...this};return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let t=this._color||e[this.status];return typeof t==="function"?t:e.pending}set loading(e){this._loading=e}get loading(){if(typeof this._loading==="boolean")return this._loading;if(this.loadingChoices)return"choices";return!1}get status(){if(this.cancelled)return"cancelled";if(this.submitted)return"submitted";return"pending"}}gs.exports=ys});var ws=E((Bm,xs)=>{var ut=M(),R=Ie(),ht={default:R.noop,noop:R.noop,set inverse(e){this._inverse=e},get inverse(){return this._inverse||ut.inverse(this.primary)},set complement(e){this._complement=e},get complement(){return this._complement||ut.complement(this.primary)},primary:R.cyan,success:R.green,danger:R.magenta,strong:R.bold,warning:R.yellow,muted:R.dim,disabled:R.gray,dark:R.dim.gray,underline:R.underline,set info(e){this._info=e},get info(){return this._info||this.primary},set em(e){this._em=e},get em(){return this._em||this.primary.underline},set heading(e){this._heading=e},get heading(){return this._heading||this.muted.underline},set pending(e){this._pending=e},get pending(){return this._pending||this.primary},set submitted(e){this._submitted=e},get submitted(){return this._submitted||this.success},set cancelled(e){this._cancelled=e},get cancelled(){return this._cancelled||this.danger},set typing(e){this._typing=e},get typing(){return this._typing||this.dim},set placeholder(e){this._placeholder=e},get placeholder(){return this._placeholder||this.primary.dim},set highlight(e){this._highlight=e},get highlight(){return this._highlight||this.inverse}};ht.merge=(e={})=>{if(e.styles&&typeof e.styles.enabled==="boolean")R.enabled=e.styles.enabled;if(e.styles&&typeof e.styles.visible==="boolean")R.visible=e.styles.visible;let t=ut.merge({},ht,e.styles);delete t.merge;for(let s of Object.keys(R))if(!hasOwnProperty.call(t,s))Reflect.defineProperty(t,s,{get:()=>R[s]});for(let s of Object.keys(R.styles))if(!hasOwnProperty.call(t,s))Reflect.defineProperty(t,s,{get:()=>R[s]});return t};xs.exports=ht});var vs=E((Im,Es)=>{var ft=process.platform==="win32",K=Ie(),On=M(),yt={...K.symbols,upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:K.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:K.symbols.question,submitted:K.symbols.check,cancelled:K.symbols.cross},separator:{pending:K.symbols.pointerSmall,submitted:K.symbols.middot,cancelled:K.symbols.middot},radio:{off:ft?"( )":"\u25EF",on:ft?"(*)":"\u25C9",disabled:ft?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]};yt.merge=(e)=>{let t=On.merge({},K.symbols,yt,e.symbols);return delete t.merge,t};Es.exports=yt});var Ts=E((Om,As)=>{var Dn=ws(),Pn=vs(),Ln=M();As.exports=(e)=>{e.options=Ln.merge({},e.options.theme,e.options),e.symbols=Pn.merge(e.options),e.styles=Dn.merge(e.options)}});var Cs=E((Ns,Rs)=>{var Ss=process.env.TERM_PROGRAM==="Apple_Terminal",kn=se(),gt=M(),L=Rs.exports=Ns,bt=!1,oe=L.code={bell:"\x07",beep:"\x07",beginning:"\x1B[G",down:"\x1B[J",esc:"\x1B[",getPosition:"\x1B[6n",hide:"\x1B[?25l",line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",restorePosition:"\x1B["+(Ss?"8":"u"),savePosition:"\x1B["+(Ss?"7":"s"),screen:"\x1B[2J",show:"\x1B[?25h",up:"\x1B[1J"},de=L.cursor={get hidden(){return bt},hide(){return bt=!0,oe.hide},show(){return bt=!1,oe.show},forward:(e=1)=>`\x1B[${e}C`,backward:(e=1)=>`\x1B[${e}D`,nextLine:(e=1)=>"\x1B[E".repeat(e),prevLine:(e=1)=>"\x1B[F".repeat(e),up:(e=1)=>e?`\x1B[${e}A`:"",down:(e=1)=>e?`\x1B[${e}B`:"",right:(e=1)=>e?`\x1B[${e}C`:"",left:(e=1)=>e?`\x1B[${e}D`:"",to(e,t){return t?`\x1B[${t+1};${e+1}H`:`\x1B[${e+1}G`},move(e=0,t=0){let s="";return s+=e<0?de.left(-e):e>0?de.right(e):"",s+=t<0?de.up(-t):t>0?de.down(t):"",s},strLen(e){var t=0,s=e.length,o=-1;for(var r=0;r<s;r++)if(o=e.charCodeAt(r),o>=0&&o<=128)t+=1;else t+=2;return t},restore(e={}){let{after:t,cursor:s,initial:o,input:r,prompt:i,size:a,value:n}=e;if(o=gt.isPrimitive(o)?String(o):"",r=gt.isPrimitive(r)?String(r):"",n=gt.isPrimitive(n)?String(n):"",a){let l=L.cursor.up(a)+L.cursor.to(this.strLen(i)),d=r.length-s;if(d>0)l+=L.cursor.left(d);return l}if(n||t){let l=!r&&!!o?-this.strLen(o):-this.strLen(r)+s;if(t)l-=this.strLen(t);if(r===""&&o&&!i.includes(o))l+=this.strLen(o);return L.cursor.move(l)}}},xt=L.erase={screen:oe.screen,up:oe.up,down:oe.down,line:oe.line,lineEnd:oe.lineEnd,lineStart:oe.lineStart,lines(e){let t="";for(let s=0;s<e;s++)t+=L.erase.line+(s<e-1?L.cursor.up(1):"");if(e)t+=L.code.beginning;return t}};L.clear=(e="",t=process.stdout.columns)=>{if(!t)return xt.line+de.to(0);let s=(i)=>[...kn(i)].length,o=e.split(/\r?\n/),r=0;for(let i of o)r+=1+Math.floor(Math.max(s(i)-1,0)/t);return(xt.line+de.prevLine()).repeat(r-1)+xt.line+de.to(0)}});var fe=E((Dm,_s)=>{var Un=ve("events"),Ms=se(),wt=mt(),Gn=fs(),$n=bs(),qn=Ts(),B=M(),pe=Cs();class Et extends Un{constructor(e={}){super();this.name=e.name,this.type=e.type,this.options=e,qn(this),Gn(this),this.state=new $n(this),this.initial=[e.initial,e.default].find((t)=>t!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=Fn(this.options.margin),this.setMaxListeners(0),Wn(this)}async keypress(e,t={}){this.keypressed=!0;let s=wt.action(e,wt(e,t),this.options.actions);this.state.keypress=s,this.emit("keypress",e,s),this.emit("state",this.state.clone());let o=this.options[s.action]||this[s.action]||this.dispatch;if(typeof o==="function")return await o.call(this,e,s);this.alert()}alert(){if(delete this.state.alert,this.options.show===!1)this.emit("alert");else this.stdout.write(pe.code.beep)}cursorHide(){this.stdout.write(pe.cursor.hide());let e=B.onExit(()=>this.cursorShow());this.on("close",()=>{this.cursorShow(),e()})}cursorShow(){this.stdout.write(pe.cursor.show())}write(e){if(!e)return;if(this.stdout&&this.state.show!==!1)this.stdout.write(e);this.state.buffer+=e}clear(e=0){let t=this.state.buffer;if(this.state.buffer="",!t&&!e||this.options.show===!1)return;this.stdout.write(pe.cursor.down(e)+pe.clear(t,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:t,rest:s}=this.sections(),{cursor:o,initial:r="",input:i="",value:a=""}=this,n=this.state.size=s.length,l={after:t,cursor:o,initial:r,input:i,prompt:e,size:n,value:a},d=pe.cursor.restore(l);if(d)this.stdout.write(d)}sections(){let{buffer:e,input:t,prompt:s}=this.state;s=Ms(s);let o=Ms(e),r=o.indexOf(s),i=o.slice(0,r),n=o.slice(r).split(`
7
+ `),l=n[0],d=n[n.length-1],u=(s+(t?" "+t:"")).length,m=u<l.length?l.slice(u+1):"";return{header:i,prompt:l,after:m,rest:n.slice(1),last:d}}async submit(){if(this.state.submitted=!0,this.state.validating=!0,this.options.onSubmit)await this.options.onSubmit.call(this,this.name,this.value,this);let e=this.state.error||await this.validate(this.value,this.state);if(e!==!0){let t=`
8
8
  `+this.symbols.pointer+" ";if(typeof e==="string")t+=e.trim();else t+="Invalid input";this.state.error=`
9
- `+this.styles.danger(t),this.state.submitted=!1,await this.render(),await this.alert(),this.state.validating=!1,this.state.error=void 0;return}this.state.validating=!1,await this.render(),await this.close(),this.value=await this.result(this.value),this.emit("submit",this.value)}async cancel(e){if(this.state.cancelled=this.state.submitted=!0,await this.render(),await this.close(),typeof this.options.onCancel==="function")await this.options.onCancel.call(this,this.name,this.value,this);this.emit("cancel",await this.error(e))}async close(){this.state.closed=!0;try{let e=this.sections(),t=Math.ceil(e.prompt.length/this.width);if(e.rest)this.write(ne.cursor.down(e.rest.length));this.write(`
10
- `.repeat(t))}catch(e){}this.emit("close")}start(){if(!this.stop&&this.options.show!==!1)this.stop=bt.listen(this,this.keypress.bind(this)),this.once("close",this.stop),this.emit("start",this)}async skip(){if(this.skipped=this.options.skip===!0,typeof this.options.skip==="function")this.skipped=await this.options.skip.call(this,this.name,this.value);return this.skipped}async initialize(){let{format:e,options:t,result:s}=this;if(this.format=()=>e.call(this,this.value),this.result=()=>s.call(this,this.value),typeof t.initial==="function")this.initial=await t.initial.call(this,this);if(typeof t.onRun==="function")await t.onRun.call(this,this);if(typeof t.onSubmit==="function"){let r=t.onSubmit.bind(this),o=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>{return await r(this.name,this.value,this),o()}}await this.start(),await this.render()}render(){throw Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,t)=>{if(this.once("submit",e),this.once("cancel",t),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,t,s){let{options:r,state:o,symbols:i,timers:a}=this,n=a&&a[e];o.timer=n;let d=r[e]||o[e]||i[e],l=t&&t[e]!=null?t[e]:await d;if(l==="")return l;let p=await this.resolve(l,o,t,s);if(!p&&t&&t[e])return this.resolve(d,o,t,s);return p}async prefix(){let e=await this.element("prefix")||this.symbols,t=this.timers&&this.timers.prefix,s=this.state;if(s.timer=t,_.isObject(e))e=e[s.status]||e.pending;if(!_.hasColor(e))return(this.styles[s.status]||this.styles.pending)(e);return e}async message(){let e=await this.element("message");if(!_.hasColor(e))return this.styles.strong(e);return e}async separator(){let e=await this.element("separator")||this.symbols,t=this.timers&&this.timers.separator,s=this.state;s.timer=t;let r=e[s.status]||e.pending||s.separator,o=await this.resolve(r,s);if(_.isObject(o))o=o[s.status]||o.pending;if(!_.hasColor(o))return this.styles.muted(o);return o}async pointer(e,t){let s=await this.element("pointer",e,t);if(typeof s==="string"&&_.hasColor(s))return s;if(s){let r=this.styles,o=this.index===t,i=o?r.primary:(d)=>d,a=await this.resolve(s[o?"on":"off"]||s,this.state),n=!_.hasColor(a)?i(a):a;return o?n:" ".repeat(a.length)}}async indicator(e,t){let s=await this.element("indicator",e,t);if(typeof s==="string"&&_.hasColor(s))return s;if(s){let r=this.styles,o=e.enabled===!0,i=o?r.success:r.dark,a=s[o?"on":"off"]||s;return!_.hasColor(a)?i(a):a}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");if(!_.hasColor(e))return this.styles.muted(e);return e}}error(e){return!this.state.submitted?e||this.state.error:""}format(e){return e}result(e){return e}validate(e){if(this.options.required===!0)return this.isValue(e);return!0}isValue(e){return e!=null&&e!==""}resolve(e,...t){return _.resolve(this,e,...t)}get base(){return wt.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||_.height(this.stdout,25)}get width(){return this.options.columns||_.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:t}=this.state,s=[t,e].find(this.isValue.bind(this));return this.isValue(s)?s:this.initial}static get prompt(){return(e)=>new this(e).run()}}function Rn(e){let t=(o)=>{return e[o]===void 0||typeof e[o]==="function"},s=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],r=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let o of Object.keys(e.options)){if(s.includes(o))continue;if(/^on[A-Z]/.test(o))continue;let i=e.options[o];if(typeof i==="function"&&t(o)){if(!r.includes(o))e[o]=i.bind(e)}else if(typeof e[o]!=="function")e[o]=i}}function Mn(e){if(typeof e==="number")e=[e,e,e,e];let t=[].concat(e||[]),s=(o)=>o%2===0?`
11
- `:" ",r=[];for(let o=0;o<4;o++){let i=s(o);if(t[o])r.push(i.repeat(t[o]));else r.push("")}return r}Ms.exports=wt});var Is=x((am,_s)=>{var Cn=M(),Cs={default(e,t){return t},checkbox(e,t){throw Error("checkbox role is not implemented yet")},editable(e,t){throw Error("editable role is not implemented yet")},expandable(e,t){throw Error("expandable role is not implemented yet")},heading(e,t){return t.disabled="",t.indicator=[t.indicator," "].find((s)=>s!=null),t.message=t.message||"",t},input(e,t){throw Error("input role is not implemented yet")},option(e,t){return Cs.default(e,t)},radio(e,t){throw Error("radio role is not implemented yet")},separator(e,t){return t.disabled="",t.indicator=[t.indicator," "].find((s)=>s!=null),t.message=t.message||e.symbols.line.repeat(5),t},spacer(e,t){return t}};_s.exports=(e,t={})=>{let s=Cn.merge({},Cs,t.roles);return s[e]||s.default}});var xe=x((nm,Ps)=>{var _n=te(),In=me(),On=Is(),Ie=M(),{reorder:xt,scrollUp:Dn,scrollDown:Bn,isObject:Os,swap:Pn}=Ie;class Bs extends In{constructor(e){super(e);this.cursorHide(),this.maxSelected=e.maxSelected||1/0,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){if(typeof this.options.initial==="function")this.initial=await this.options.initial.call(this);await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:t,autofocus:s,suggest:r}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach((o)=>o.enabled=!1),typeof r!=="function"&&this.selectable.length===0)throw Error("At least one choice must be selectable");if(Os(t))t=Object.keys(t);if(Array.isArray(t)){if(s!=null)this.index=this.findIndex(s);t.forEach((o)=>this.enable(this.find(o))),await this.render()}else{if(s!=null)t=s;if(typeof t==="string")t=this.findIndex(t);if(typeof t==="number"&&t>-1)this.index=Math.max(0,Math.min(t,this.choices.length)),this.enable(this.find(this.index))}if(this.isDisabled(this.focused))await this.down()}async toChoices(e,t){this.state.loadingChoices=!0;let s=[],r=0,o=async(i,a)=>{if(typeof i==="function")i=await i.call(this);if(i instanceof Promise)i=await i;for(let n=0;n<i.length;n++){let d=i[n]=await this.toChoice(i[n],r++,a);if(s.push(d),d.choices)await o(d.choices,d)}return s};return o(e,t).then((i)=>{return this.state.loadingChoices=!1,i})}async toChoice(e,t,s){if(typeof e==="function")e=await e.call(this,this);if(e instanceof Promise)e=await e;if(typeof e==="string")e={name:e};if(e.normalized)return e;e.normalized=!0;let r=e.value;if(e=On(e.role,this.options)(this,e),typeof e.disabled==="string"&&!e.hint)e.hint=e.disabled,e.disabled=!0;if(e.disabled===!0&&e.hint==null)e.hint="(disabled)";if(e.index!=null)return e;if(e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=t,e.cursor=0,Ie.define(e,"parent",s),e.level=s?s.level+1:1,e.indent==null)e.indent=s?s.indent+" ":e.indent||"";if(e.path=s?s.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),!this.isDisabled(e))this.longest=Math.max(this.longest,_n(e.message).length);let i={...e};if(e.reset=(a=i.input,n=i.value)=>{for(let d of Object.keys(i))e[d]=i[d];e.input=a,e.value=n},r==null&&typeof e.initial==="function")e.input=await e.initial.call(this,this.state,e,t);return e}async onChoice(e,t){if(this.emit("choice",e,t,this),typeof e.onChoice==="function")await e.onChoice.call(this,this.state,e,t)}async addChoice(e,t,s){let r=await this.toChoice(e,t,s);return this.choices.push(r),this.index=this.choices.length-1,this.limit=this.choices.length,r}async newItem(e,t,s){let r={name:"New choice name?",editable:!0,newChoice:!0,...e},o=await this.addChoice(r,t,s);return o.updateChoice=()=>{delete o.newChoice,o.name=o.message=o.input,o.input="",o.cursor=0},this.render()}indent(e){if(e.indent==null)return e.level>1?" ".repeat(e.level-1):"";return e.indent}dispatch(e,t){if(this.multiple&&this[t.name])return this[t.name]();this.alert()}focus(e,t){if(typeof t!=="boolean")t=e.enabled;if(t&&!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();return this.index=e.index,e.enabled=t&&!this.isDisabled(e),e}space(){if(!this.multiple)return this.alert();if(!this.focused)return;return this.toggle(this.focused),this.render()}a(){if(this.maxSelected<this.choices.length)return this.alert();let e=this.selectable.every((t)=>t.enabled);return this.choices.forEach((t)=>t.enabled=!e),this.render()}i(){if(this.choices.length-this.selected.length>this.maxSelected)return this.alert();return this.choices.forEach((e)=>e.enabled=!e.enabled),this.render()}g(){if(!this.choices.some((t)=>!!t.parent))return this.a();let e=this.focused;return this.toggle(e.parent&&!e.choices?e.parent:e),this.render()}toggle(e,t){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(typeof t!=="boolean")t=!e.enabled;if(e.enabled=t,e.choices)e.choices.forEach((r)=>this.toggle(r,t));let s=e.parent;while(s){let r=s.choices.filter((o)=>this.isDisabled(o));s.enabled=r.every((o)=>o.enabled===!0),s=s.parent}return Ds(this,this.choices),this.emit("toggle",e,this),e}enable(e){if(this.selected.length>=this.maxSelected)return this.alert();return e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let t=(s)=>{let r=Number(s);if(r>this.choices.length-1)return this.alert();let o=this.focused,i=this.choices.find((a)=>r===a.index);if(!i.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(i)===-1){let a=xt(this.choices),n=a.indexOf(i);if(o.index>n){let d=a.slice(n,n+this.limit),l=a.filter((p)=>!d.includes(p));this.choices=d.concat(l)}else{let d=n-this.limit+1;this.choices=a.slice(d).concat(a.slice(0,d))}}return this.index=this.choices.indexOf(i),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise((s)=>{let r=this.choices.length,o=this.num,i=(a=!1,n)=>{if(clearTimeout(this.numberTimeout),a)n=t(o);this.num="",s(n)};if(o==="0"||o.length===1&&Number(o+"0")>r)return i(!0);if(Number(o)>r)return i(!1,this.alert());this.numberTimeout=setTimeout(()=>i(!0),this.delay)})}home(){return this.choices=xt(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,t=xt(this.choices);return this.choices=t.slice(e).concat(t.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){if(this.visible.length<=1)return this.alert();return this.up()}next(){if(this.visible.length<=1)return this.alert();return this.down()}right(){if(this.cursor>=this.input.length)return this.alert();return this.cursor++,this.render()}left(){if(this.cursor<=0)return this.alert();return this.cursor--,this.render()}up(){let e=this.choices.length,t=this.visible.length,s=this.index;if(this.options.scroll===!1&&s===0)return this.alert();if(e>t&&s===0)return this.scrollUp();if(this.index=(s-1%e+e)%e,this.isDisabled()&&!this.allChoicesAreDisabled())return this.up();return this.render()}down(){let e=this.choices.length,t=this.visible.length,s=this.index;if(this.options.scroll===!1&&s===t-1)return this.alert();if(e>t&&s===t-1)return this.scrollDown();if(this.index=(s+1)%e,this.isDisabled()&&!this.allChoicesAreDisabled())return this.down();return this.render()}scrollUp(e=0){if(this.choices=Dn(this.choices),this.index=e,this.isDisabled())return this.up();return this.render()}scrollDown(e=this.visible.length-1){if(this.choices=Bn(this.choices),this.index=e,this.isDisabled())return this.down();return this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){if(this.visible.length<=1)return this.alert();if(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled())return this.up();return this.render()}pageDown(){if(this.visible.length>=this.choices.length)return this.alert();if(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled())return this.down();return this.render()}swap(e){Pn(this.choices,this.index,e)}allChoicesAreDisabled(e=this.choices){return e.every((t)=>this.isDisabled(t))}isDisabled(e=this.focused){if(e&&["disabled","collapsed","hidden","completing","readonly"].some((s)=>e[s]===!0))return!0;return e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every((t)=>this.isEnabled(t));if(e.choices){let t=e.choices.filter((s)=>!this.isDisabled(s));return e.enabled&&t.every((s)=>this.isEnabled(s))}return e.enabled&&!this.isDisabled(e)}isChoice(e,t){return e.name===t||e.index===Number(t)}isSelected(e){if(Array.isArray(this.initial))return this.initial.some((t)=>this.isChoice(e,t));return this.isChoice(e,this.initial)}map(e=[],t="value"){return[].concat(e||[]).reduce((s,r)=>{return s[r]=this.find(r,t),s},{})}filter(e,t){let r=typeof e==="function"?e:(a,n)=>[a.name,n].includes(e),i=(this.options.multiple?this.state._choices:this.choices).filter(r);if(t)return i.map((a)=>a[t]);return i}find(e,t){if(Os(e))return t?e[t]:e;let r=typeof e==="function"?e:(i,a)=>[i.name,a].includes(e),o=this.choices.find(r);if(o)return t?o[t]:o}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice){if(!e.input)return this.alert();return e.updateChoice(),this.render()}if(this.choices.some((i)=>i.newChoice))return this.alert();let{reorder:t,sort:s}=this.options,r=this.multiple===!0,o=this.selected;if(o===void 0)return this.alert();if(Array.isArray(o)&&t!==!1&&s!==!0)o=Ie.reorder(o);return this.value=r?o.map((i)=>i.name):o.name,super.submit()}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let t of e)if(!this.state._choices.some((s)=>s.name===t.name))this.state._choices.push(t);if(!this._initial&&this.options.initial){this._initial=!0;let t=this.initial;if(typeof t==="string"||typeof t==="number"){let s=this.find(t);if(s)this.initial=s.index,this.focus(s,!0)}}}get choices(){return Ds(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:t,choices:s}=this,r=e.limit||this._limit||t.limit||s.length;return Math.min(r,this.height)}set value(e){super.value=e}get value(){if(typeof super.value!=="string"&&super.value===this.initial)return this.input;return super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];if(e&&this.state.submitted&&this.multiple!==!0)e.enabled=!0;return e}get selectable(){return this.choices.filter((e)=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}}function Ds(e,t){if(t instanceof Promise)return t;if(typeof t==="function"){if(Ie.isAsyncFn(t))return t;t=t.call(e,e)}for(let s of t){if(Array.isArray(s.choices)){let r=s.choices.filter((o)=>!e.isDisabled(o));s.enabled=r.every((o)=>o.enabled===!0)}if(e.isDisabled(s)===!0)delete s.enabled}return t}Ps.exports=Bs});var re=x((dm,Us)=>{var Ln=xe(),Et=M();class Ls extends Ln{constructor(e){super(e);this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,t){return!this.multiple||this.options.pointer?super.pointer(e,t):""}indicator(e,t){return this.multiple?super.indicator(e,t):""}choiceMessage(e,t){let s=this.resolve(e.message,this.state,e,t);if(e.role==="heading"&&!Et.hasColor(s))s=this.styles.strong(s);return this.resolve(s,this.state,e,t)}choiceSeparator(){return":"}async renderChoice(e,t){await this.onChoice(e,t);let s=this.index===t,r=await this.pointer(e,t),o=await this.indicator(e,t)+(e.pad||""),i=await this.resolve(e.hint,this.state,e,t);if(i&&!Et.hasColor(i))i=this.styles.muted(i);let a=this.indent(e),n=await this.choiceMessage(e,t),d=()=>[this.margin[3],a+r+o,n,this.margin[1],i].filter(Boolean).join(" ");if(e.role==="heading")return d();if(e.disabled){if(!Et.hasColor(n))n=this.styles.disabled(n);return d()}if(s)n=this.styles.em(n);return d()}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(o,i)=>await this.renderChoice(o,i)),t=await Promise.all(e);if(!t.length)t.push(this.styles.danger("No matching choices"));let s=this.margin[0]+t.join(`
12
- `),r;if(this.options.choicesHeader)r=await this.resolve(this.options.choicesHeader,this.state);return[r,s].filter(Boolean).join(`
13
- `)}format(){if(!this.state.submitted||this.state.cancelled)return"";if(Array.isArray(this.selected))return this.selected.map((e)=>this.styles.primary(e.name)).join(", ");return this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:t}=this.state,s="",r=await this.header(),o=await this.prefix(),i=await this.separator(),a=await this.message();if(this.options.promptLine!==!1)s=[o,a,i,""].join(" "),this.state.prompt=s;let n=await this.format(),d=await this.error()||await this.hint(),l=await this.renderChoices(),p=await this.footer();if(n)s+=n;if(d&&!s.includes(d))s+=" "+d;if(e&&!n&&!l.trim()&&this.multiple&&this.emptyError!=null)s+=this.styles.danger(this.emptyError);this.clear(t),this.write([r,s,l,p].filter(Boolean).join(`
14
- `)),this.write(this.margin[2]),this.restore()}}Us.exports=Ls});var $s=x((lm,ks)=>{var Un=re(),Gn=(e,t)=>{let s=e?new RegExp(e,"ig"):/$^/;return(r)=>{return e?r.replace(s,(o)=>t(o)):r}};class Gs extends Un{constructor(e){super(e);this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:t,input:s}=this.state;return this.input=s.slice(0,t)+e+s.slice(t),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:t}=this.state;if(!t)return this.alert();return this.input=t.slice(0,e-1)+t.slice(e),this.moveCursor(-1),this.complete()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();return this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.complete()}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,t=this.state._choices){if(typeof this.options.suggest==="function")return this.options.suggest.call(this,e,t);let s=e.toLowerCase();return t.filter((r)=>r.message.toLowerCase().includes(s))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map((e)=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight||this.styles.complement,t=(o,i)=>{if(!o)return o;if(e.stack)return e(o);return e.call(this,o)},s=Gn(this.input,t),r=this.choices;this.choices=r.map((o)=>({...o,message:s(o.message)})),await super.render(),this.choices=r}submit(){if(this.options.multiple)this.value=this.selected.map((e)=>e.name);return super.submit()}}ks.exports=Gs});var vt=x((cm,qs)=>{var At=M();qs.exports=(e,t={})=>{e.cursorHide();let{input:s="",initial:r="",pos:o,showCursor:i=!0,color:a}=t,n=a||e.styles.placeholder,d=At.inverse(e.styles.primary),l=(f)=>d(e.styles.black(f)),p=s,u=" ",m=l(u);if(e.blink&&e.blink.off===!0)l=(f)=>f,m="";if(i&&o===0&&r===""&&s==="")return l(u);if(i&&o===0&&(s===r||s===""))return l(r[0])+n(r.slice(1));r=At.isPrimitive(r)?`${r}`:"",s=At.isPrimitive(s)?`${s}`:"";let c=r&&r.startsWith(s)&&r!==s,h=c?l(r[s.length]):m;if(o!==s.length&&i===!0)p=s.slice(0,o)+l(s[o])+s.slice(o+1),h="";if(i===!1)h="";if(c){let f=e.styles.unstyle(p+h);return p+h+n(r.slice(f.length))}return p+h}});var Oe=x((pm,Ks)=>{var kn=te(),$n=re(),qn=vt();class Ws extends $n{constructor(e){super({...e,multiple:!0});this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find((t)=>t!=null),this.emptyError="",this.values={}}async reset(e){if(await super.reset(),e===!0)this._index=this.index;return this.index=this._index,this.values={},this.choices.forEach((t)=>t.reset&&t.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let t=this.focused;if(!t)return this.alert();let{cursor:s,input:r}=t;return t.value=t.input=r.slice(0,s)+e+r.slice(s),t.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:t,input:s}=e;return e.value=e.input=s.slice(0,t-1)+s.slice(t),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:t,input:s}=e;if(s[t]===void 0)return this.alert();let r=`${s}`.slice(0,t)+`${s}`.slice(t+1);return e.value=e.input=r,this.render()}right(){let e=this.focused;if(!e)return this.alert();if(e.cursor>=e.input.length)return this.alert();return e.cursor++,this.render()}left(){let e=this.focused;if(!e)return this.alert();if(e.cursor<=0)return this.alert();return e.cursor--,this.render()}space(e,t){return this.dispatch(e,t)}number(e,t){return this.dispatch(e,t)}next(){let e=this.focused;if(!e)return this.alert();let{initial:t,input:s}=e;if(t&&t.startsWith(s)&&s!==t)return e.value=e.input=t,e.cursor=e.value.length,this.render();return super.next()}prev(){let e=this.focused;if(!e)return this.alert();if(e.cursor===0)return super.prev();return e.value=e.input="",e.cursor=0,this.render()}separator(){return""}format(e){return!this.state.submitted?super.format(e):""}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,t){let s=await this.resolve(e.separator,this.state,e,t)||":";return s?" "+this.styles.disabled(s):""}async renderChoice(e,t){await this.onChoice(e,t);let{state:s,styles:r}=this,{cursor:o,initial:i="",name:a,input:n=""}=e,{muted:d,submitted:l,primary:p,danger:u}=r,m=this.index===t,c=e.validate||(()=>!0),h=await this.choiceSeparator(e,t),f=e.message;if(this.align==="right")f=f.padStart(this.longest+1," ");if(this.align==="left")f=f.padEnd(this.longest+1," ");let g=this.values[a]=n||i,y=n?"success":"dark";if(await c.call(e,g,this.state)!==!0)y="danger";let E=r[y],A=E(await this.indicator(e,t))+(e.pad||""),N=this.indent(e),C=()=>[N,A,f+h,n].filter(Boolean).join(" ");if(s.submitted)return f=kn(f),n=l(n),C();if(e.format)n=await e.format.call(this,n,e,t);else{let O=this.styles.muted;n=qn(this,{input:n,initial:i,pos:o,showCursor:m,color:O})}if(!this.isValue(n))n=this.styles.muted(this.symbols.ellipsis);if(e.result)this.values[a]=await e.result.call(this,g,e,t);if(m)f=p(f);if(e.error)n+=(n?" ":"")+u(e.error.trim());else if(e.hint)n+=(n?" ":"")+d(e.hint.trim());return C()}async submit(){return this.value=this.values,super.base.submit.call(this)}}Ks.exports=Ws});var Nt=x((mm,Hs)=>{var Wn=Oe(),Kn=()=>{throw Error("expected prompt to have a custom authenticate method")},Fs=(e=Kn)=>{class t extends Wn{constructor(s){super(s)}async submit(){this.value=await e.call(this,this.values,this.state),super.base.submit.call(this)}static create(s){return Fs(s)}}return t};Hs.exports=Fs()});var zs=x((um,Ys)=>{var Fn=Nt();function Hn(e,t){if(e.username===this.options.username&&e.password===this.options.password)return!0;return!1}var Vs=(e=Hn)=>{let t=[{name:"username",message:"username"},{name:"password",message:"password",format(r){if(this.options.showPassword)return r;return(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(r.length))}}];class s extends Fn.create(e){constructor(r){super({...r,choices:t})}static create(r){return Vs(r)}}return s};Ys.exports=Vs()});var De=x((hm,Qs)=>{var Vn=me(),{isPrimitive:Yn,hasColor:zn}=M();class Zs extends Vn{constructor(e){super(e);this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){if(!this.isValue(e))return this.alert();return this.input=e,this.submit()}format(e){let{styles:t,state:s}=this;return!s.submitted?t.primary(e):t.success(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return Yn(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");if(!zn(e))return this.styles.muted(e);return e}}async render(){let{input:e,size:t}=this.state,s=await this.prefix(),r=await this.separator(),o=await this.message(),i=this.styles.muted(this.default),a=[s,o,i,r].filter(Boolean).join(" ");this.state.prompt=a;let n=await this.header(),d=this.value=this.cast(e),l=await this.format(d),p=await this.error()||await this.hint(),u=await this.footer();if(p&&!a.includes(p))l+=" "+p;a+=" "+l,this.clear(t),this.write([n,a,u].filter(Boolean).join(`
15
- `)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}}Qs.exports=Zs});var js=x((fm,Js)=>{var Zn=De();class Xs extends Zn{constructor(e){super(e);this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}}Js.exports=Xs});var sr=x((ym,tr)=>{var Qn=re(),Xn=Oe(),ue=Xn.prototype;class er extends Qn{constructor(e){super({...e,multiple:!0});this.align=[this.options.align,"left"].find((t)=>t!=null),this.emptyError="",this.values={}}dispatch(e,t){let s=this.focused,r=s.parent||{};if(!s.editable&&!r.editable){if(e==="a"||e==="i")return super[e]()}return ue.dispatch.call(this,e,t)}append(e,t){return ue.append.call(this,e,t)}delete(e,t){return ue.delete.call(this,e,t)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?ue.next.call(this):super.next()}prev(){return this.focused.editable?ue.prev.call(this):super.prev()}async indicator(e,t){let s=e.indicator||"",r=e.editable?s:super.indicator(e,t);return await this.resolve(r,this.state,e,t)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,t){if(e.indent="",e.editable)return ue.renderChoice.call(this,e,t);return super.renderChoice(e,t)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let t of this.choices){if(typeof t.validate!=="function")continue;if(t.role==="heading")continue;let s=t.parent?this.value[t.parent.name]:this.value;if(t.editable)s=t.value===t.name?t.initial||"":t.value;else if(!this.isDisabled(t))s=t.enabled===!0;if(e=await t.validate(s,this.state),e!==!0)break}if(e!==!0)this.state.error=typeof e==="string"?e:"Invalid Input";return e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some((e)=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let t=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}if(e.editable)t[e.name]=e.value===e.name?e.initial||"":e.value;else if(!this.isDisabled(e))t[e.name]=e.enabled===!0}return this.base.submit.call(this)}}tr.exports=er});var de=x((gm,or)=>{var Jn=me(),jn=ct(),ed=vt(),{isPrimitive:td}=M();class rr extends Jn{constructor(e){super(e);if(this.initial=td(this.initial)?String(this.initial):"",this.initial)this.cursorHide();this.state.prevCursor=0,this.state.clipboard=[],this.keypressTimeout=this.options.keypressTimeout!==void 0?this.options.keypressTimeout:null}async keypress(e,t=e?jn(e,{}):{}){let s=Date.now(),r=s-this.lastKeypress;this.lastKeypress=s;let o=t.name==="return"||t.name==="enter",i=this.state.prevKeypress,a;if(this.state.prevKeypress=t,this.keypressTimeout!=null&&o){if(r<this.keypressTimeout)return this.submit();this.state.multilineBuffer=this.state.multilineBuffer||"",this.state.multilineBuffer+=e,a=!0,i=null}if(a||this.options.multiline&&o){if(!i||i.name!=="return")return this.append(`
16
- `,t)}return super.keypress(e,t)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,t){if(!e||t.ctrl||t.code)return this.alert();this.append(e)}append(e){let{cursor:t,input:s}=this.state;this.input=`${s}`.slice(0,t)+e+`${s}`.slice(t),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:t}=this.state;if(e<=0)return this.alert();this.input=`${t}`.slice(0,e-1)+`${t}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let t=this.input.slice(0,e),s=this.input.slice(e),r=t.split(" ");this.state.clipboard.push(r.pop()),this.input=r.join(" "),this.cursor=this.input.length,this.input+=s,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){if(this.state.prevCursor)this.cursor=this.state.prevCursor,this.state.prevCursor=0;else this.state.prevCursor=this.cursor,this.cursor=0;this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){if(this.cursor>=this.input.length)return this.alert();return this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();return this.moveCursor(-1),this.render()}isValue(e){return!!e}async format(e=this.value){let t=await this.resolve(this.initial,this.state);if(!this.state.submitted)return ed(this,{input:e,initial:t,pos:this.cursor});return this.styles.submitted(e||t)}async render(){let e=this.state.size,t=await this.prefix(),s=await this.separator(),r=await this.message(),o=[t,r,s].filter(Boolean).join(" ");this.state.prompt=o;let i=await this.header(),a=await this.format(),n=await this.error()||await this.hint(),d=await this.footer();if(n&&!a.includes(n))a+=" "+n;o+=" "+a,this.clear(e),this.write([i,o,d].filter(Boolean).join(`
17
- `)),this.restore()}}or.exports=rr});var ar=x((bm,ir)=>{var sd=(e)=>e.filter((t,s)=>e.lastIndexOf(t)===s),Be=(e)=>sd(e).filter(Boolean);ir.exports=(e,t={},s="")=>{let{past:r=[],present:o=""}=t,i,a;switch(e){case"prev":case"undo":return i=r.slice(0,r.length-1),a=r[r.length-1]||"",{past:Be([s,...i]),present:a};case"next":case"redo":return i=r.slice(1),a=r[0]||"",{past:Be([...i,s]),present:a};case"save":return{past:Be([...r,s]),present:""};case"remove":if(a=Be(r.filter((n)=>n!==s)),o="",a.length)o=a.pop();return{past:a,present:o};default:throw Error(`Invalid action: "${e}"`)}}});var St=x((wm,lr)=>{var rd=de(),nr=ar();class dr extends rd{constructor(e){super(e);let t=this.options.history;if(t&&t.store){let s=t.values||this.initial;this.autosave=!!t.autosave,this.store=t.store,this.data=this.store.get("values")||{past:[],present:s},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){if(!this.store)return this.alert();if(this.data=nr(e,this.data,this.input),!this.data.present)return this.alert();return this.input=this.data.present,this.cursor=this.input.length,this.render()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){if(!this.store)return;this.data=nr("save",this.data,this.input),this.store.set("values",this.data)}submit(){if(this.store&&this.autosave===!0)this.save();return super.submit()}}lr.exports=dr});var mr=x((xm,pr)=>{var od=de();class cr extends od{format(){return""}}pr.exports=cr});var fr=x((Em,hr)=>{var id=de();class ur extends id{constructor(e={}){super(e);this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:(t)=>t;return this.list.map(e).join(", ")}async submit(e){let t=this.state.error||await this.validate(this.list,this.state);if(t!==!0)return this.state.error=t,super.submit();return this.value=this.list,super.submit()}get list(){return this.split()}}hr.exports=ur});var br=x((Am,gr)=>{var ad=re();class yr extends ad{constructor(e){super({...e,multiple:!0})}}gr.exports=yr});var Tt=x((vm,xr)=>{var nd=de();class wr extends nd{constructor(e={}){super({style:"number",...e});this.min=this.isValue(e.min)?this.toNumber(e.min):-1/0,this.max=this.isValue(e.max)?this.toNumber(e.max):1/0,this.delay=e.delay!=null?e.delay:1000,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){if(!/[-+.]/.test(e)||e==="."&&this.input.includes("."))return this.alert("invalid number");return super.append(e)}number(e){return super.append(e)}next(){if(this.input&&this.input!==this.initial)return this.alert();if(!this.isValue(this.initial))return this.alert();return this.input=this.initial,this.cursor=String(this.initial).length,this.render()}up(e){let t=e||this.minor,s=this.toNumber(this.input);if(s>this.max+t)return this.alert();return this.input=`${s+t}`,this.render()}down(e){let t=e||this.minor,s=this.toNumber(this.input);if(s<this.min-t)return this.alert();return this.input=`${s-t}`,this.render()}shiftDown(){return this.down(this.major)}shiftUp(){return this.up(this.major)}format(e=this.input){if(typeof this.options.format==="function")return this.options.format.call(this,e);return this.styles.info(e)}toNumber(e=""){return this.float?+e:Math.round(+e)}isValue(e){return/^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(e)}submit(){let e=[this.input,this.initial].find((t)=>this.isValue(t));return this.value=this.toNumber(e||0),super.submit()}}xr.exports=wr});var vr=x((Nm,Ar)=>{var dd=de();class Er extends dd{constructor(e){super(e);this.cursorShow()}format(e=this.input){if(!this.keypressed)return"";return(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length))}}Ar.exports=Er});var Rr=x((Sm,Tr)=>{var ld=te(),cd=xe(),Nr=M();class Sr extends cd{constructor(e={}){super(e);this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||`
18
- `;let t=e.startNumber||1;if(typeof this.scale==="number")this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((s,r)=>({name:r+t}))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let t of this.choices){e=Math.max(e,t.message.length),t.scaleIndex=t.initial||2,t.scale=[];for(let s=0;s<this.scale.length;s++)t.scale.push({index:s})}this.widths[0]=Math.min(this.widths[0],e+3)}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}heading(e,t,s){return this.styles.strong(e)}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;if(e.scaleIndex>=this.scale.length-1)return this.alert();return e.scaleIndex++,this.render()}left(){let e=this.focused;if(e.scaleIndex<=0)return this.alert();return e.scaleIndex--,this.render()}indent(){return""}format(){if(this.state.submitted)return this.choices.map((t)=>this.styles.info(t.index)).join(", ");return""}pointer(){return""}renderScaleKey(){if(this.scaleKey===!1)return"";if(this.state.submitted)return"";return["",...this.scale.map((s)=>` ${s.name} - ${s.message}`)].map((s)=>this.styles.muted(s)).join(`
19
- `)}renderScaleHeading(e){let t=this.scale.map((n)=>n.name);if(typeof this.options.renderScaleHeading==="function")t=this.options.renderScaleHeading.call(this,e);let s=this.scaleLength-t.join("").length,r=Math.round(s/(t.length-1)),i=t.map((n)=>this.styles.strong(n)).join(" ".repeat(r)),a=" ".repeat(this.widths[0]);return this.margin[3]+a+this.margin[1]+i}scaleIndicator(e,t,s){if(typeof this.options.scaleIndicator==="function")return this.options.scaleIndicator.call(this,e,t,s);let r=e.scaleIndex===t.index;if(t.disabled)return this.styles.hint(this.symbols.radio.disabled);if(r)return this.styles.success(this.symbols.radio.on);return this.symbols.radio.off}renderScale(e,t){let s=e.scale.map((o)=>this.scaleIndicator(e,o,t)),r=this.term==="Hyper"?"":" ";return s.join(r+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,t){await this.onChoice(e,t);let s=this.index===t,r=await this.pointer(e,t),o=await e.hint;if(o&&!Nr.hasColor(o))o=this.styles.muted(o);let i=(c)=>this.margin[3]+c.replace(/\s+$/,"").padEnd(this.widths[0]," "),a=this.newline,n=this.indent(e),d=await this.resolve(e.message,this.state,e,t),l=await this.renderScale(e,t),p=this.margin[1]+this.margin[3];this.scaleLength=ld(l).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-p.length);let m=Nr.wordWrap(d,{width:this.widths[0],newline:a}).split(`
20
- `).map((c)=>i(c)+this.margin[1]);if(s)l=this.styles.info(l),m=m.map((c)=>this.styles.info(c));if(m[0]+=l,this.linebreak)m.push("");return[n+r,m.join(`
21
- `)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(r,o)=>await this.renderChoice(r,o)),t=await Promise.all(e),s=await this.renderScaleHeading();return this.margin[0]+[s,...t.map((r)=>r.join(" "))].join(`
22
- `)}async render(){let{submitted:e,size:t}=this.state,s=await this.prefix(),r=await this.separator(),o=await this.message(),i="";if(this.options.promptLine!==!1)i=[s,o,r,""].join(" "),this.state.prompt=i;let a=await this.header(),n=await this.format(),d=await this.renderScaleKey(),l=await this.error()||await this.hint(),p=await this.renderChoices(),u=await this.footer(),m=this.emptyError;if(n)i+=n;if(l&&!i.includes(l))i+=" "+l;if(e&&!n&&!p.trim()&&this.multiple&&m!=null)i+=this.styles.danger(m);if(this.clear(t),this.write([a,i,d,p,u].filter(Boolean).join(`
23
- `)),!this.state.submitted)this.write(this.margin[2]);this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}}Tr.exports=Sr});var Ir=x((Tm,_r)=>{var Mr=te(),pd=(e="")=>{return typeof e==="string"?e.replace(/^['"]|['"]$/g,""):""};class Cr{constructor(e){this.name=e.key,this.field=e.field||{},this.value=pd(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}}var md=async(e={},t={},s=(r)=>r)=>{let r=new Set,o=e.fields||[],i=e.template,a=[],n=[],d=[],l=1;if(typeof i==="function")i=await i();let p=-1,u=()=>i[++p],m=()=>i[p+1],c=(h)=>{h.line=l,a.push(h)};c({type:"bos",value:""});while(p<i.length-1){let h=u();if(/^[^\S\n ]$/.test(h)){c({type:"text",value:h});continue}if(h===`
24
- `){c({type:"newline",value:h}),l++;continue}if(h==="\\"){h+=u(),c({type:"text",value:h});continue}if((h==="$"||h==="#"||h==="{")&&m()==="{"){let g=u();h+=g;let y={type:"template",open:h,inner:"",close:"",value:h},E;while(E=u()){if(E==="}"){if(m()==="}")E+=u();y.value+=E,y.close=E;break}if(E===":")y.initial="",y.key=y.inner;else if(y.initial!==void 0)y.initial+=E;y.value+=E,y.inner+=E}if(y.template=y.open+(y.initial||y.inner)+y.close,y.key=y.key||y.inner,hasOwnProperty.call(t,y.key))y.initial=t[y.key];y=s(y),c(y),d.push(y.key),r.add(y.key);let A=n.find((N)=>N.name===y.key);if(y.field=o.find((N)=>N.name===y.key),!A)A=new Cr(y),n.push(A);A.lines.push(y.line-1);continue}let f=a[a.length-1];if(f.type==="text"&&f.line===l)f.value+=h;else c({type:"text",value:h})}return c({type:"eos",value:""}),{input:i,tabstops:a,unique:r,keys:d,items:n}};_r.exports=async(e)=>{let t=e.options,s=new Set(t.required===!0?[]:t.required||[]),r={...t.values,...t.initial},{tabstops:o,items:i,keys:a}=await md(t,r),n=Rt("result",e,t),d=Rt("format",e,t),l=Rt("validate",e,t,!0),p=e.isValue.bind(e);return async(u={},m=!1)=>{let c=0;u.required=s,u.items=i,u.keys=a,u.output="";let h=async(E,A,N,C)=>{let O=await l(E,A,N,C);if(O===!1)return"Invalid field "+N.name;return O};for(let E of o){let{value:A,key:N}=E;if(E.type!=="template"){if(A)u.output+=A;continue}if(E.type==="template"){let C=i.find((pe)=>pe.name===N);if(t.required===!0)u.required.add(C.name);let O=[C.input,u.values[C.value],C.value,A].find(p),Ne=(C.field||{}).message||E.inner;if(m){let pe=await h(u.values[N],u,C,c);if(pe&&typeof pe==="string"||pe===!1){u.invalid.set(N,pe);continue}u.invalid.delete(N);let la=await n(u.values[N],u,C,c);u.output+=Mr(la);continue}C.placeholder=!1;let da=A;if(A=await d(A,u,C,c),O!==A)u.values[N]=O,A=e.styles.typing(O),u.missing.delete(Ne);else if(u.values[N]=void 0,O=`<${Ne}>`,A=e.styles.primary(O),C.placeholder=!0,u.required.has(N))u.missing.add(Ne);if(u.missing.has(Ne)&&u.validating)A=e.styles.warning(O);if(u.invalid.has(N)&&u.validating)A=e.styles.danger(O);if(c===u.index)if(da!==A)A=e.styles.underline(A);else A=e.styles.heading(Mr(A));c++}if(A)u.output+=A}let f=u.output.split(`
25
- `).map((E)=>" "+E),g=i.length,y=0;for(let E of i){if(u.invalid.has(E.name))E.lines.forEach((A)=>{if(f[A][0]!==" ")return;f[A]=u.styles.danger(u.symbols.bullet)+f[A].slice(1)});if(e.isValue(u.values[E.name]))y++}return u.completed=(y/g*100).toFixed(0),u.output=f.join(`
26
- `),u.output}};function Rt(e,t,s,r){return(o,i,a,n)=>{if(typeof a.field[e]==="function")return a.field[e].call(t,o,i,a,n);return[r,o].find((d)=>t.isValue(d))}}});var Br=x((Rm,Dr)=>{var ud=te(),hd=Ir(),fd=me();class Or extends fd{constructor(e){super(e);this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await hd(this),await super.initialize()}async reset(e){if(this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0)await this.initialize(),await this.render()}moveCursor(e){let t=this.getItem();this.cursor+=e,t.cursor+=e}dispatch(e,t){if(!t.code&&!t.ctrl&&e!=null&&this.getItem()){this.append(e,t);return}this.alert()}append(e,t){let s=this.getItem(),r=s.input.slice(0,this.cursor),o=s.input.slice(this.cursor);this.input=s.input=`${r}${e}${o}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let t=e.input.slice(this.cursor),s=e.input.slice(0,this.cursor-1);this.input=e.input=`${s}${t}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let t=this.state.completed<100?this.styles.warning:this.styles.success;if(this.state.submitted===!0&&this.state.completed!==100)t=this.styles.danger;return t(`${this.state.completed}% completed`)}async render(){let{index:e,keys:t=[],submitted:s,size:r}=this.state,o=[this.options.newline,`
27
- `].find((y)=>y!=null),i=await this.prefix(),a=await this.separator(),n=await this.message(),d=[i,n,a].filter(Boolean).join(" ");this.state.prompt=d;let l=await this.header(),p=await this.error()||"",u=await this.hint()||"",m=s?"":await this.interpolate(this.state),c=this.state.key=t[e]||"",h=await this.format(c),f=await this.footer();if(h)d+=" "+h;if(u&&!h&&this.state.completed===0)d+=" "+u;this.clear(r);let g=[l,d,m,f,p.trim()];this.write(g.filter(Boolean).join(o)),this.restore()}getItem(e){let{items:t,keys:s,index:r}=this.state,o=t.find((i)=>i.name===s[r]);if(o&&o.input!=null)this.input=o.input,this.cursor=o.cursor;return o}async submit(){if(typeof this.interpolate!=="function")await this.initialize();await this.interpolate(this.state,!0);let{invalid:e,missing:t,output:s,values:r}=this.state;if(e.size){let a="";for(let[n,d]of e)a+=`Invalid ${n}: ${d}
28
- `;return this.state.error=a,super.submit()}if(t.size)return this.state.error="Required: "+[...t.keys()].join(", "),super.submit();let i=ud(s).split(`
9
+ `+this.styles.danger(t),this.state.submitted=!1,await this.render(),await this.alert(),this.state.validating=!1,this.state.error=void 0;return}this.state.validating=!1,await this.render(),await this.close(),this.value=await this.result(this.value),this.emit("submit",this.value)}async cancel(e){if(this.state.cancelled=this.state.submitted=!0,await this.render(),await this.close(),typeof this.options.onCancel==="function")await this.options.onCancel.call(this,this.name,this.value,this);this.emit("cancel",await this.error(e))}async close(){this.state.closed=!0;try{let e=this.sections(),t=Math.ceil(e.prompt.length/this.width);if(e.rest)this.write(pe.cursor.down(e.rest.length));this.write(`
10
+ `.repeat(t))}catch(e){}this.emit("close")}start(){if(!this.stop&&this.options.show!==!1)this.stop=wt.listen(this,this.keypress.bind(this)),this.once("close",this.stop),this.emit("start",this)}async skip(){if(this.skipped=this.options.skip===!0,typeof this.options.skip==="function")this.skipped=await this.options.skip.call(this,this.name,this.value);return this.skipped}async initialize(){let{format:e,options:t,result:s}=this;if(this.format=()=>e.call(this,this.value),this.result=()=>s.call(this,this.value),typeof t.initial==="function")this.initial=await t.initial.call(this,this);if(typeof t.onRun==="function")await t.onRun.call(this,this);if(typeof t.onSubmit==="function"){let o=t.onSubmit.bind(this),r=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>{return await o(this.name,this.value,this),r()}}await this.start(),await this.render()}render(){throw Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,t)=>{if(this.once("submit",e),this.once("cancel",t),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,t,s){let{options:o,state:r,symbols:i,timers:a}=this,n=a&&a[e];r.timer=n;let l=o[e]||r[e]||i[e],d=t&&t[e]!=null?t[e]:await l;if(d==="")return d;let c=await this.resolve(d,r,t,s);if(!c&&t&&t[e])return this.resolve(l,r,t,s);return c}async prefix(){let e=await this.element("prefix")||this.symbols,t=this.timers&&this.timers.prefix,s=this.state;if(s.timer=t,B.isObject(e))e=e[s.status]||e.pending;if(!B.hasColor(e))return(this.styles[s.status]||this.styles.pending)(e);return e}async message(){let e=await this.element("message");if(!B.hasColor(e))return this.styles.strong(e);return e}async separator(){let e=await this.element("separator")||this.symbols,t=this.timers&&this.timers.separator,s=this.state;s.timer=t;let o=e[s.status]||e.pending||s.separator,r=await this.resolve(o,s);if(B.isObject(r))r=r[s.status]||r.pending;if(!B.hasColor(r))return this.styles.muted(r);return r}async pointer(e,t){let s=await this.element("pointer",e,t);if(typeof s==="string"&&B.hasColor(s))return s;if(s){let o=this.styles,r=this.index===t,i=r?o.primary:(l)=>l,a=await this.resolve(s[r?"on":"off"]||s,this.state),n=!B.hasColor(a)?i(a):a;return r?n:" ".repeat(a.length)}}async indicator(e,t){let s=await this.element("indicator",e,t);if(typeof s==="string"&&B.hasColor(s))return s;if(s){let o=this.styles,r=e.enabled===!0,i=r?o.success:o.dark,a=s[r?"on":"off"]||s;return!B.hasColor(a)?i(a):a}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");if(!B.hasColor(e))return this.styles.muted(e);return e}}error(e){return!this.state.submitted?e||this.state.error:""}format(e){return e}result(e){return e}validate(e){if(this.options.required===!0)return this.isValue(e);return!0}isValue(e){return e!=null&&e!==""}resolve(e,...t){return B.resolve(this,e,...t)}get base(){return Et.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||B.height(this.stdout,25)}get width(){return this.options.columns||B.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:t}=this.state,s=[t,e].find(this.isValue.bind(this));return this.isValue(s)?s:this.initial}static get prompt(){return(e)=>new this(e).run()}}function Wn(e){let t=(r)=>{return e[r]===void 0||typeof e[r]==="function"},s=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],o=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let r of Object.keys(e.options)){if(s.includes(r))continue;if(/^on[A-Z]/.test(r))continue;let i=e.options[r];if(typeof i==="function"&&t(r)){if(!o.includes(r))e[r]=i.bind(e)}else if(typeof e[r]!=="function")e[r]=i}}function Fn(e){if(typeof e==="number")e=[e,e,e,e];let t=[].concat(e||[]),s=(r)=>r%2===0?`
11
+ `:" ",o=[];for(let r=0;r<4;r++){let i=s(r);if(t[r])o.push(i.repeat(t[r]));else o.push("")}return o}_s.exports=Et});var Os=E((Pm,Is)=>{var Kn=M(),Bs={default(e,t){return t},checkbox(e,t){throw Error("checkbox role is not implemented yet")},editable(e,t){throw Error("editable role is not implemented yet")},expandable(e,t){throw Error("expandable role is not implemented yet")},heading(e,t){return t.disabled="",t.indicator=[t.indicator," "].find((s)=>s!=null),t.message=t.message||"",t},input(e,t){throw Error("input role is not implemented yet")},option(e,t){return Bs.default(e,t)},radio(e,t){throw Error("radio role is not implemented yet")},separator(e,t){return t.disabled="",t.indicator=[t.indicator," "].find((s)=>s!=null),t.message=t.message||e.symbols.line.repeat(5),t},spacer(e,t){return t}};Is.exports=(e,t={})=>{let s=Kn.merge({},Bs,t.roles);return s[e]||s.default}});var Se=E((Lm,ks)=>{var Hn=se(),Vn=fe(),zn=Os(),Le=M(),{reorder:vt,scrollUp:Yn,scrollDown:Qn,isObject:Ds,swap:Zn}=Le;class Ls extends Vn{constructor(e){super(e);this.cursorHide(),this.maxSelected=e.maxSelected||1/0,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){if(typeof this.options.initial==="function")this.initial=await this.options.initial.call(this);await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:t,autofocus:s,suggest:o}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach((r)=>r.enabled=!1),typeof o!=="function"&&this.selectable.length===0)throw Error("At least one choice must be selectable");if(Ds(t))t=Object.keys(t);if(Array.isArray(t)){if(s!=null)this.index=this.findIndex(s);t.forEach((r)=>this.enable(this.find(r))),await this.render()}else{if(s!=null)t=s;if(typeof t==="string")t=this.findIndex(t);if(typeof t==="number"&&t>-1)this.index=Math.max(0,Math.min(t,this.choices.length)),this.enable(this.find(this.index))}if(this.isDisabled(this.focused))await this.down()}async toChoices(e,t){this.state.loadingChoices=!0;let s=[],o=0,r=async(i,a)=>{if(typeof i==="function")i=await i.call(this);if(i instanceof Promise)i=await i;for(let n=0;n<i.length;n++){let l=i[n]=await this.toChoice(i[n],o++,a);if(s.push(l),l.choices)await r(l.choices,l)}return s};return r(e,t).then((i)=>{return this.state.loadingChoices=!1,i})}async toChoice(e,t,s){if(typeof e==="function")e=await e.call(this,this);if(e instanceof Promise)e=await e;if(typeof e==="string")e={name:e};if(e.normalized)return e;e.normalized=!0;let o=e.value;if(e=zn(e.role,this.options)(this,e),typeof e.disabled==="string"&&!e.hint)e.hint=e.disabled,e.disabled=!0;if(e.disabled===!0&&e.hint==null)e.hint="(disabled)";if(e.index!=null)return e;if(e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=t,e.cursor=0,Le.define(e,"parent",s),e.level=s?s.level+1:1,e.indent==null)e.indent=s?s.indent+" ":e.indent||"";if(e.path=s?s.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),!this.isDisabled(e))this.longest=Math.max(this.longest,Hn(e.message).length);let i={...e};if(e.reset=(a=i.input,n=i.value)=>{for(let l of Object.keys(i))e[l]=i[l];e.input=a,e.value=n},o==null&&typeof e.initial==="function")e.input=await e.initial.call(this,this.state,e,t);return e}async onChoice(e,t){if(this.emit("choice",e,t,this),typeof e.onChoice==="function")await e.onChoice.call(this,this.state,e,t)}async addChoice(e,t,s){let o=await this.toChoice(e,t,s);return this.choices.push(o),this.index=this.choices.length-1,this.limit=this.choices.length,o}async newItem(e,t,s){let o={name:"New choice name?",editable:!0,newChoice:!0,...e},r=await this.addChoice(o,t,s);return r.updateChoice=()=>{delete r.newChoice,r.name=r.message=r.input,r.input="",r.cursor=0},this.render()}indent(e){if(e.indent==null)return e.level>1?" ".repeat(e.level-1):"";return e.indent}dispatch(e,t){if(this.multiple&&this[t.name])return this[t.name]();this.alert()}focus(e,t){if(typeof t!=="boolean")t=e.enabled;if(t&&!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();return this.index=e.index,e.enabled=t&&!this.isDisabled(e),e}space(){if(!this.multiple)return this.alert();if(!this.focused)return;return this.toggle(this.focused),this.render()}a(){if(this.maxSelected<this.choices.length)return this.alert();let e=this.selectable.every((t)=>t.enabled);return this.choices.forEach((t)=>t.enabled=!e),this.render()}i(){if(this.choices.length-this.selected.length>this.maxSelected)return this.alert();return this.choices.forEach((e)=>e.enabled=!e.enabled),this.render()}g(){if(!this.choices.some((t)=>!!t.parent))return this.a();let e=this.focused;return this.toggle(e.parent&&!e.choices?e.parent:e),this.render()}toggle(e,t){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(typeof t!=="boolean")t=!e.enabled;if(e.enabled=t,e.choices)e.choices.forEach((o)=>this.toggle(o,t));let s=e.parent;while(s){let o=s.choices.filter((r)=>this.isDisabled(r));s.enabled=o.every((r)=>r.enabled===!0),s=s.parent}return Ps(this,this.choices),this.emit("toggle",e,this),e}enable(e){if(this.selected.length>=this.maxSelected)return this.alert();return e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let t=(s)=>{let o=Number(s);if(o>this.choices.length-1)return this.alert();let r=this.focused,i=this.choices.find((a)=>o===a.index);if(!i.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(i)===-1){let a=vt(this.choices),n=a.indexOf(i);if(r.index>n){let l=a.slice(n,n+this.limit),d=a.filter((c)=>!l.includes(c));this.choices=l.concat(d)}else{let l=n-this.limit+1;this.choices=a.slice(l).concat(a.slice(0,l))}}return this.index=this.choices.indexOf(i),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise((s)=>{let o=this.choices.length,r=this.num,i=(a=!1,n)=>{if(clearTimeout(this.numberTimeout),a)n=t(r);this.num="",s(n)};if(r==="0"||r.length===1&&Number(r+"0")>o)return i(!0);if(Number(r)>o)return i(!1,this.alert());this.numberTimeout=setTimeout(()=>i(!0),this.delay)})}home(){return this.choices=vt(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,t=vt(this.choices);return this.choices=t.slice(e).concat(t.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){if(this.visible.length<=1)return this.alert();return this.up()}next(){if(this.visible.length<=1)return this.alert();return this.down()}right(){if(this.cursor>=this.input.length)return this.alert();return this.cursor++,this.render()}left(){if(this.cursor<=0)return this.alert();return this.cursor--,this.render()}up(){let e=this.choices.length,t=this.visible.length,s=this.index;if(this.options.scroll===!1&&s===0)return this.alert();if(e>t&&s===0)return this.scrollUp();if(this.index=(s-1%e+e)%e,this.isDisabled()&&!this.allChoicesAreDisabled())return this.up();return this.render()}down(){let e=this.choices.length,t=this.visible.length,s=this.index;if(this.options.scroll===!1&&s===t-1)return this.alert();if(e>t&&s===t-1)return this.scrollDown();if(this.index=(s+1)%e,this.isDisabled()&&!this.allChoicesAreDisabled())return this.down();return this.render()}scrollUp(e=0){if(this.choices=Yn(this.choices),this.index=e,this.isDisabled())return this.up();return this.render()}scrollDown(e=this.visible.length-1){if(this.choices=Qn(this.choices),this.index=e,this.isDisabled())return this.down();return this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){if(this.visible.length<=1)return this.alert();if(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled())return this.up();return this.render()}pageDown(){if(this.visible.length>=this.choices.length)return this.alert();if(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled())return this.down();return this.render()}swap(e){Zn(this.choices,this.index,e)}allChoicesAreDisabled(e=this.choices){return e.every((t)=>this.isDisabled(t))}isDisabled(e=this.focused){if(e&&["disabled","collapsed","hidden","completing","readonly"].some((s)=>e[s]===!0))return!0;return e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every((t)=>this.isEnabled(t));if(e.choices){let t=e.choices.filter((s)=>!this.isDisabled(s));return e.enabled&&t.every((s)=>this.isEnabled(s))}return e.enabled&&!this.isDisabled(e)}isChoice(e,t){return e.name===t||e.index===Number(t)}isSelected(e){if(Array.isArray(this.initial))return this.initial.some((t)=>this.isChoice(e,t));return this.isChoice(e,this.initial)}map(e=[],t="value"){return[].concat(e||[]).reduce((s,o)=>{return s[o]=this.find(o,t),s},{})}filter(e,t){let o=typeof e==="function"?e:(a,n)=>[a.name,n].includes(e),i=(this.options.multiple?this.state._choices:this.choices).filter(o);if(t)return i.map((a)=>a[t]);return i}find(e,t){if(Ds(e))return t?e[t]:e;let o=typeof e==="function"?e:(i,a)=>[i.name,a].includes(e),r=this.choices.find(o);if(r)return t?r[t]:r}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice){if(!e.input)return this.alert();return e.updateChoice(),this.render()}if(this.choices.some((i)=>i.newChoice))return this.alert();let{reorder:t,sort:s}=this.options,o=this.multiple===!0,r=this.selected;if(r===void 0)return this.alert();if(Array.isArray(r)&&t!==!1&&s!==!0)r=Le.reorder(r);return this.value=o?r.map((i)=>i.name):r.name,super.submit()}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let t of e)if(!this.state._choices.some((s)=>s.name===t.name))this.state._choices.push(t);if(!this._initial&&this.options.initial){this._initial=!0;let t=this.initial;if(typeof t==="string"||typeof t==="number"){let s=this.find(t);if(s)this.initial=s.index,this.focus(s,!0)}}}get choices(){return Ps(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:t,choices:s}=this,o=e.limit||this._limit||t.limit||s.length;return Math.min(o,this.height)}set value(e){super.value=e}get value(){if(typeof super.value!=="string"&&super.value===this.initial)return this.input;return super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];if(e&&this.state.submitted&&this.multiple!==!0)e.enabled=!0;return e}get selectable(){return this.choices.filter((e)=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}}function Ps(e,t){if(t instanceof Promise)return t;if(typeof t==="function"){if(Le.isAsyncFn(t))return t;t=t.call(e,e)}for(let s of t){if(Array.isArray(s.choices)){let o=s.choices.filter((r)=>!e.isDisabled(r));s.enabled=o.every((r)=>r.enabled===!0)}if(e.isDisabled(s)===!0)delete s.enabled}return t}ks.exports=Ls});var re=E((km,Gs)=>{var Xn=Se(),At=M();class Us extends Xn{constructor(e){super(e);this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,t){return!this.multiple||this.options.pointer?super.pointer(e,t):""}indicator(e,t){return this.multiple?super.indicator(e,t):""}choiceMessage(e,t){let s=this.resolve(e.message,this.state,e,t);if(e.role==="heading"&&!At.hasColor(s))s=this.styles.strong(s);return this.resolve(s,this.state,e,t)}choiceSeparator(){return":"}async renderChoice(e,t){await this.onChoice(e,t);let s=this.index===t,o=await this.pointer(e,t),r=await this.indicator(e,t)+(e.pad||""),i=await this.resolve(e.hint,this.state,e,t);if(i&&!At.hasColor(i))i=this.styles.muted(i);let a=this.indent(e),n=await this.choiceMessage(e,t),l=()=>[this.margin[3],a+o+r,n,this.margin[1],i].filter(Boolean).join(" ");if(e.role==="heading")return l();if(e.disabled){if(!At.hasColor(n))n=this.styles.disabled(n);return l()}if(s)n=this.styles.em(n);return l()}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(r,i)=>await this.renderChoice(r,i)),t=await Promise.all(e);if(!t.length)t.push(this.styles.danger("No matching choices"));let s=this.margin[0]+t.join(`
12
+ `),o;if(this.options.choicesHeader)o=await this.resolve(this.options.choicesHeader,this.state);return[o,s].filter(Boolean).join(`
13
+ `)}format(){if(!this.state.submitted||this.state.cancelled)return"";if(Array.isArray(this.selected))return this.selected.map((e)=>this.styles.primary(e.name)).join(", ");return this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:t}=this.state,s="",o=await this.header(),r=await this.prefix(),i=await this.separator(),a=await this.message();if(this.options.promptLine!==!1)s=[r,a,i,""].join(" "),this.state.prompt=s;let n=await this.format(),l=await this.error()||await this.hint(),d=await this.renderChoices(),c=await this.footer();if(n)s+=n;if(l&&!s.includes(l))s+=" "+l;if(e&&!n&&!d.trim()&&this.multiple&&this.emptyError!=null)s+=this.styles.danger(this.emptyError);this.clear(t),this.write([o,s,d,c].filter(Boolean).join(`
14
+ `)),this.write(this.margin[2]),this.restore()}}Gs.exports=Us});var Ws=E((Um,qs)=>{var Jn=re(),jn=(e,t)=>{let s=e?new RegExp(e,"ig"):/$^/;return(o)=>{return e?o.replace(s,(r)=>t(r)):o}};class $s extends Jn{constructor(e){super(e);this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:t,input:s}=this.state;return this.input=s.slice(0,t)+e+s.slice(t),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:t}=this.state;if(!t)return this.alert();return this.input=t.slice(0,e-1)+t.slice(e),this.moveCursor(-1),this.complete()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();return this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.complete()}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,t=this.state._choices){if(typeof this.options.suggest==="function")return this.options.suggest.call(this,e,t);let s=e.toLowerCase();return t.filter((o)=>o.message.toLowerCase().includes(s))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map((e)=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight||this.styles.complement,t=(r,i)=>{if(!r)return r;if(e.stack)return e(r);return e.call(this,r)},s=jn(this.input,t),o=this.choices;this.choices=o.map((r)=>({...r,message:s(r.message)})),await super.render(),this.choices=o}submit(){if(this.options.multiple)this.value=this.selected.map((e)=>e.name);return super.submit()}}qs.exports=$s});var St=E((Gm,Fs)=>{var Tt=M();Fs.exports=(e,t={})=>{e.cursorHide();let{input:s="",initial:o="",pos:r,showCursor:i=!0,color:a}=t,n=a||e.styles.placeholder,l=Tt.inverse(e.styles.primary),d=(f)=>l(e.styles.black(f)),c=s,u=" ",m=d(u);if(e.blink&&e.blink.off===!0)d=(f)=>f,m="";if(i&&r===0&&o===""&&s==="")return d(u);if(i&&r===0&&(s===o||s===""))return d(o[0])+n(o.slice(1));o=Tt.isPrimitive(o)?`${o}`:"",s=Tt.isPrimitive(s)?`${s}`:"";let p=o&&o.startsWith(s)&&o!==s,h=p?d(o[s.length]):m;if(r!==s.length&&i===!0)c=s.slice(0,r)+d(s[r])+s.slice(r+1),h="";if(i===!1)h="";if(p){let f=e.styles.unstyle(c+h);return c+h+n(o.slice(f.length))}return c+h}});var ke=E(($m,Hs)=>{var el=se(),tl=re(),sl=St();class Ks extends tl{constructor(e){super({...e,multiple:!0});this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find((t)=>t!=null),this.emptyError="",this.values={}}async reset(e){if(await super.reset(),e===!0)this._index=this.index;return this.index=this._index,this.values={},this.choices.forEach((t)=>t.reset&&t.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let t=this.focused;if(!t)return this.alert();let{cursor:s,input:o}=t;return t.value=t.input=o.slice(0,s)+e+o.slice(s),t.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:t,input:s}=e;return e.value=e.input=s.slice(0,t-1)+s.slice(t),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:t,input:s}=e;if(s[t]===void 0)return this.alert();let o=`${s}`.slice(0,t)+`${s}`.slice(t+1);return e.value=e.input=o,this.render()}right(){let e=this.focused;if(!e)return this.alert();if(e.cursor>=e.input.length)return this.alert();return e.cursor++,this.render()}left(){let e=this.focused;if(!e)return this.alert();if(e.cursor<=0)return this.alert();return e.cursor--,this.render()}space(e,t){return this.dispatch(e,t)}number(e,t){return this.dispatch(e,t)}next(){let e=this.focused;if(!e)return this.alert();let{initial:t,input:s}=e;if(t&&t.startsWith(s)&&s!==t)return e.value=e.input=t,e.cursor=e.value.length,this.render();return super.next()}prev(){let e=this.focused;if(!e)return this.alert();if(e.cursor===0)return super.prev();return e.value=e.input="",e.cursor=0,this.render()}separator(){return""}format(e){return!this.state.submitted?super.format(e):""}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,t){let s=await this.resolve(e.separator,this.state,e,t)||":";return s?" "+this.styles.disabled(s):""}async renderChoice(e,t){await this.onChoice(e,t);let{state:s,styles:o}=this,{cursor:r,initial:i="",name:a,input:n=""}=e,{muted:l,submitted:d,primary:c,danger:u}=o,m=this.index===t,p=e.validate||(()=>!0),h=await this.choiceSeparator(e,t),f=e.message;if(this.align==="right")f=f.padStart(this.longest+1," ");if(this.align==="left")f=f.padEnd(this.longest+1," ");let g=this.values[a]=n||i,y=n?"success":"dark";if(await p.call(e,g,this.state)!==!0)y="danger";let w=o[y],v=w(await this.indicator(e,t))+(e.pad||""),T=this.indent(e),_=()=>[T,v,f+h,n].filter(Boolean).join(" ");if(s.submitted)return f=el(f),n=d(n),_();if(e.format)n=await e.format.call(this,n,e,t);else{let O=this.styles.muted;n=sl(this,{input:n,initial:i,pos:r,showCursor:m,color:O})}if(!this.isValue(n))n=this.styles.muted(this.symbols.ellipsis);if(e.result)this.values[a]=await e.result.call(this,g,e,t);if(m)f=c(f);if(e.error)n+=(n?" ":"")+u(e.error.trim());else if(e.hint)n+=(n?" ":"")+l(e.hint.trim());return _()}async submit(){return this.value=this.values,super.base.submit.call(this)}}Hs.exports=Ks});var Nt=E((qm,zs)=>{var ol=ke(),rl=()=>{throw Error("expected prompt to have a custom authenticate method")},Vs=(e=rl)=>{class t extends ol{constructor(s){super(s)}async submit(){this.value=await e.call(this,this.values,this.state),super.base.submit.call(this)}static create(s){return Vs(s)}}return t};zs.exports=Vs()});var Zs=E((Wm,Qs)=>{var il=Nt();function al(e,t){if(e.username===this.options.username&&e.password===this.options.password)return!0;return!1}var Ys=(e=al)=>{let t=[{name:"username",message:"username"},{name:"password",message:"password",format(o){if(this.options.showPassword)return o;return(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(o.length))}}];class s extends il.create(e){constructor(o){super({...o,choices:t})}static create(o){return Ys(o)}}return s};Qs.exports=Ys()});var Ue=E((Fm,Js)=>{var nl=fe(),{isPrimitive:ll,hasColor:dl}=M();class Xs extends nl{constructor(e){super(e);this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){if(!this.isValue(e))return this.alert();return this.input=e,this.submit()}format(e){let{styles:t,state:s}=this;return!s.submitted?t.primary(e):t.success(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return ll(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");if(!dl(e))return this.styles.muted(e);return e}}async render(){let{input:e,size:t}=this.state,s=await this.prefix(),o=await this.separator(),r=await this.message(),i=this.styles.muted(this.default),a=[s,r,i,o].filter(Boolean).join(" ");this.state.prompt=a;let n=await this.header(),l=this.value=this.cast(e),d=await this.format(l),c=await this.error()||await this.hint(),u=await this.footer();if(c&&!a.includes(c))d+=" "+c;a+=" "+d,this.clear(t),this.write([n,a,u].filter(Boolean).join(`
15
+ `)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}}Js.exports=Xs});var to=E((Km,eo)=>{var pl=Ue();class js extends pl{constructor(e){super(e);this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}}eo.exports=js});var ro=E((Hm,oo)=>{var cl=re(),ml=ke(),ye=ml.prototype;class so extends cl{constructor(e){super({...e,multiple:!0});this.align=[this.options.align,"left"].find((t)=>t!=null),this.emptyError="",this.values={}}dispatch(e,t){let s=this.focused,o=s.parent||{};if(!s.editable&&!o.editable){if(e==="a"||e==="i")return super[e]()}return ye.dispatch.call(this,e,t)}append(e,t){return ye.append.call(this,e,t)}delete(e,t){return ye.delete.call(this,e,t)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?ye.next.call(this):super.next()}prev(){return this.focused.editable?ye.prev.call(this):super.prev()}async indicator(e,t){let s=e.indicator||"",o=e.editable?s:super.indicator(e,t);return await this.resolve(o,this.state,e,t)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,t){if(e.indent="",e.editable)return ye.renderChoice.call(this,e,t);return super.renderChoice(e,t)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let t of this.choices){if(typeof t.validate!=="function")continue;if(t.role==="heading")continue;let s=t.parent?this.value[t.parent.name]:this.value;if(t.editable)s=t.value===t.name?t.initial||"":t.value;else if(!this.isDisabled(t))s=t.enabled===!0;if(e=await t.validate(s,this.state),e!==!0)break}if(e!==!0)this.state.error=typeof e==="string"?e:"Invalid Input";return e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some((e)=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let t=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}if(e.editable)t[e.name]=e.value===e.name?e.initial||"":e.value;else if(!this.isDisabled(e))t[e.name]=e.enabled===!0}return this.base.submit.call(this)}}oo.exports=so});var ce=E((Vm,ao)=>{var ul=fe(),hl=mt(),fl=St(),{isPrimitive:yl}=M();class io extends ul{constructor(e){super(e);if(this.initial=yl(this.initial)?String(this.initial):"",this.initial)this.cursorHide();this.state.prevCursor=0,this.state.clipboard=[],this.keypressTimeout=this.options.keypressTimeout!==void 0?this.options.keypressTimeout:null}async keypress(e,t=e?hl(e,{}):{}){let s=Date.now(),o=s-this.lastKeypress;this.lastKeypress=s;let r=t.name==="return"||t.name==="enter",i=this.state.prevKeypress,a;if(this.state.prevKeypress=t,this.keypressTimeout!=null&&r){if(o<this.keypressTimeout)return this.submit();this.state.multilineBuffer=this.state.multilineBuffer||"",this.state.multilineBuffer+=e,a=!0,i=null}if(a||this.options.multiline&&r){if(!i||i.name!=="return")return this.append(`
16
+ `,t)}return super.keypress(e,t)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,t){if(!e||t.ctrl||t.code)return this.alert();this.append(e)}append(e){let{cursor:t,input:s}=this.state;this.input=`${s}`.slice(0,t)+e+`${s}`.slice(t),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:t}=this.state;if(e<=0)return this.alert();this.input=`${t}`.slice(0,e-1)+`${t}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let t=this.input.slice(0,e),s=this.input.slice(e),o=t.split(" ");this.state.clipboard.push(o.pop()),this.input=o.join(" "),this.cursor=this.input.length,this.input+=s,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){if(this.state.prevCursor)this.cursor=this.state.prevCursor,this.state.prevCursor=0;else this.state.prevCursor=this.cursor,this.cursor=0;this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){if(this.cursor>=this.input.length)return this.alert();return this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();return this.moveCursor(-1),this.render()}isValue(e){return!!e}async format(e=this.value){let t=await this.resolve(this.initial,this.state);if(!this.state.submitted)return fl(this,{input:e,initial:t,pos:this.cursor});return this.styles.submitted(e||t)}async render(){let e=this.state.size,t=await this.prefix(),s=await this.separator(),o=await this.message(),r=[t,o,s].filter(Boolean).join(" ");this.state.prompt=r;let i=await this.header(),a=await this.format(),n=await this.error()||await this.hint(),l=await this.footer();if(n&&!a.includes(n))a+=" "+n;r+=" "+a,this.clear(e),this.write([i,r,l].filter(Boolean).join(`
17
+ `)),this.restore()}}ao.exports=io});var lo=E((zm,no)=>{var gl=(e)=>e.filter((t,s)=>e.lastIndexOf(t)===s),Ge=(e)=>gl(e).filter(Boolean);no.exports=(e,t={},s="")=>{let{past:o=[],present:r=""}=t,i,a;switch(e){case"prev":case"undo":return i=o.slice(0,o.length-1),a=o[o.length-1]||"",{past:Ge([s,...i]),present:a};case"next":case"redo":return i=o.slice(1),a=o[0]||"",{past:Ge([...i,s]),present:a};case"save":return{past:Ge([...o,s]),present:""};case"remove":if(a=Ge(o.filter((n)=>n!==s)),r="",a.length)r=a.pop();return{past:a,present:r};default:throw Error(`Invalid action: "${e}"`)}}});var Rt=E((Ym,mo)=>{var bl=ce(),po=lo();class co extends bl{constructor(e){super(e);let t=this.options.history;if(t&&t.store){let s=t.values||this.initial;this.autosave=!!t.autosave,this.store=t.store,this.data=this.store.get("values")||{past:[],present:s},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){if(!this.store)return this.alert();if(this.data=po(e,this.data,this.input),!this.data.present)return this.alert();return this.input=this.data.present,this.cursor=this.input.length,this.render()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){if(!this.store)return;this.data=po("save",this.data,this.input),this.store.set("values",this.data)}submit(){if(this.store&&this.autosave===!0)this.save();return super.submit()}}mo.exports=co});var fo=E((Qm,ho)=>{var xl=ce();class uo extends xl{format(){return""}}ho.exports=uo});var bo=E((Zm,go)=>{var wl=ce();class yo extends wl{constructor(e={}){super(e);this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:(t)=>t;return this.list.map(e).join(", ")}async submit(e){let t=this.state.error||await this.validate(this.list,this.state);if(t!==!0)return this.state.error=t,super.submit();return this.value=this.list,super.submit()}get list(){return this.split()}}go.exports=yo});var Eo=E((Xm,wo)=>{var El=re();class xo extends El{constructor(e){super({...e,multiple:!0})}}wo.exports=xo});var Ct=E((Jm,Ao)=>{var vl=ce();class vo extends vl{constructor(e={}){super({style:"number",...e});this.min=this.isValue(e.min)?this.toNumber(e.min):-1/0,this.max=this.isValue(e.max)?this.toNumber(e.max):1/0,this.delay=e.delay!=null?e.delay:1000,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){if(!/[-+.]/.test(e)||e==="."&&this.input.includes("."))return this.alert("invalid number");return super.append(e)}number(e){return super.append(e)}next(){if(this.input&&this.input!==this.initial)return this.alert();if(!this.isValue(this.initial))return this.alert();return this.input=this.initial,this.cursor=String(this.initial).length,this.render()}up(e){let t=e||this.minor,s=this.toNumber(this.input);if(s>this.max+t)return this.alert();return this.input=`${s+t}`,this.render()}down(e){let t=e||this.minor,s=this.toNumber(this.input);if(s<this.min-t)return this.alert();return this.input=`${s-t}`,this.render()}shiftDown(){return this.down(this.major)}shiftUp(){return this.up(this.major)}format(e=this.input){if(typeof this.options.format==="function")return this.options.format.call(this,e);return this.styles.info(e)}toNumber(e=""){return this.float?+e:Math.round(+e)}isValue(e){return/^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(e)}submit(){let e=[this.input,this.initial].find((t)=>this.isValue(t));return this.value=this.toNumber(e||0),super.submit()}}Ao.exports=vo});var No=E((jm,So)=>{var Al=ce();class To extends Al{constructor(e){super(e);this.cursorShow()}format(e=this.input){if(!this.keypressed)return"";return(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length))}}So.exports=To});var _o=E((eu,Mo)=>{var Tl=se(),Sl=Se(),Ro=M();class Co extends Sl{constructor(e={}){super(e);this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||`
18
+ `;let t=e.startNumber||1;if(typeof this.scale==="number")this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((s,o)=>({name:o+t}))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let t of this.choices){e=Math.max(e,t.message.length),t.scaleIndex=t.initial||2,t.scale=[];for(let s=0;s<this.scale.length;s++)t.scale.push({index:s})}this.widths[0]=Math.min(this.widths[0],e+3)}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}heading(e,t,s){return this.styles.strong(e)}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;if(e.scaleIndex>=this.scale.length-1)return this.alert();return e.scaleIndex++,this.render()}left(){let e=this.focused;if(e.scaleIndex<=0)return this.alert();return e.scaleIndex--,this.render()}indent(){return""}format(){if(this.state.submitted)return this.choices.map((t)=>this.styles.info(t.index)).join(", ");return""}pointer(){return""}renderScaleKey(){if(this.scaleKey===!1)return"";if(this.state.submitted)return"";return["",...this.scale.map((s)=>` ${s.name} - ${s.message}`)].map((s)=>this.styles.muted(s)).join(`
19
+ `)}renderScaleHeading(e){let t=this.scale.map((n)=>n.name);if(typeof this.options.renderScaleHeading==="function")t=this.options.renderScaleHeading.call(this,e);let s=this.scaleLength-t.join("").length,o=Math.round(s/(t.length-1)),i=t.map((n)=>this.styles.strong(n)).join(" ".repeat(o)),a=" ".repeat(this.widths[0]);return this.margin[3]+a+this.margin[1]+i}scaleIndicator(e,t,s){if(typeof this.options.scaleIndicator==="function")return this.options.scaleIndicator.call(this,e,t,s);let o=e.scaleIndex===t.index;if(t.disabled)return this.styles.hint(this.symbols.radio.disabled);if(o)return this.styles.success(this.symbols.radio.on);return this.symbols.radio.off}renderScale(e,t){let s=e.scale.map((r)=>this.scaleIndicator(e,r,t)),o=this.term==="Hyper"?"":" ";return s.join(o+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,t){await this.onChoice(e,t);let s=this.index===t,o=await this.pointer(e,t),r=await e.hint;if(r&&!Ro.hasColor(r))r=this.styles.muted(r);let i=(p)=>this.margin[3]+p.replace(/\s+$/,"").padEnd(this.widths[0]," "),a=this.newline,n=this.indent(e),l=await this.resolve(e.message,this.state,e,t),d=await this.renderScale(e,t),c=this.margin[1]+this.margin[3];this.scaleLength=Tl(d).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-c.length);let m=Ro.wordWrap(l,{width:this.widths[0],newline:a}).split(`
20
+ `).map((p)=>i(p)+this.margin[1]);if(s)d=this.styles.info(d),m=m.map((p)=>this.styles.info(p));if(m[0]+=d,this.linebreak)m.push("");return[n+o,m.join(`
21
+ `)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(o,r)=>await this.renderChoice(o,r)),t=await Promise.all(e),s=await this.renderScaleHeading();return this.margin[0]+[s,...t.map((o)=>o.join(" "))].join(`
22
+ `)}async render(){let{submitted:e,size:t}=this.state,s=await this.prefix(),o=await this.separator(),r=await this.message(),i="";if(this.options.promptLine!==!1)i=[s,r,o,""].join(" "),this.state.prompt=i;let a=await this.header(),n=await this.format(),l=await this.renderScaleKey(),d=await this.error()||await this.hint(),c=await this.renderChoices(),u=await this.footer(),m=this.emptyError;if(n)i+=n;if(d&&!i.includes(d))i+=" "+d;if(e&&!n&&!c.trim()&&this.multiple&&m!=null)i+=this.styles.danger(m);if(this.clear(t),this.write([a,i,l,c,u].filter(Boolean).join(`
23
+ `)),!this.state.submitted)this.write(this.margin[2]);this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}}Mo.exports=Co});var Do=E((tu,Oo)=>{var Bo=se(),Nl=(e="")=>{return typeof e==="string"?e.replace(/^['"]|['"]$/g,""):""};class Io{constructor(e){this.name=e.key,this.field=e.field||{},this.value=Nl(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}}var Rl=async(e={},t={},s=(o)=>o)=>{let o=new Set,r=e.fields||[],i=e.template,a=[],n=[],l=[],d=1;if(typeof i==="function")i=await i();let c=-1,u=()=>i[++c],m=()=>i[c+1],p=(h)=>{h.line=d,a.push(h)};p({type:"bos",value:""});while(c<i.length-1){let h=u();if(/^[^\S\n ]$/.test(h)){p({type:"text",value:h});continue}if(h===`
24
+ `){p({type:"newline",value:h}),d++;continue}if(h==="\\"){h+=u(),p({type:"text",value:h});continue}if((h==="$"||h==="#"||h==="{")&&m()==="{"){let g=u();h+=g;let y={type:"template",open:h,inner:"",close:"",value:h},w;while(w=u()){if(w==="}"){if(m()==="}")w+=u();y.value+=w,y.close=w;break}if(w===":")y.initial="",y.key=y.inner;else if(y.initial!==void 0)y.initial+=w;y.value+=w,y.inner+=w}if(y.template=y.open+(y.initial||y.inner)+y.close,y.key=y.key||y.inner,hasOwnProperty.call(t,y.key))y.initial=t[y.key];y=s(y),p(y),l.push(y.key),o.add(y.key);let v=n.find((T)=>T.name===y.key);if(y.field=r.find((T)=>T.name===y.key),!v)v=new Io(y),n.push(v);v.lines.push(y.line-1);continue}let f=a[a.length-1];if(f.type==="text"&&f.line===d)f.value+=h;else p({type:"text",value:h})}return p({type:"eos",value:""}),{input:i,tabstops:a,unique:o,keys:l,items:n}};Oo.exports=async(e)=>{let t=e.options,s=new Set(t.required===!0?[]:t.required||[]),o={...t.values,...t.initial},{tabstops:r,items:i,keys:a}=await Rl(t,o),n=Mt("result",e,t),l=Mt("format",e,t),d=Mt("validate",e,t,!0),c=e.isValue.bind(e);return async(u={},m=!1)=>{let p=0;u.required=s,u.items=i,u.keys=a,u.output="";let h=async(w,v,T,_)=>{let O=await d(w,v,T,_);if(O===!1)return"Invalid field "+T.name;return O};for(let w of r){let{value:v,key:T}=w;if(w.type!=="template"){if(v)u.output+=v;continue}if(w.type==="template"){let _=i.find((he)=>he.name===T);if(t.required===!0)u.required.add(_.name);let O=[_.input,u.values[_.value],_.value,v].find(c),Me=(_.field||{}).message||w.inner;if(m){let he=await h(u.values[T],u,_,p);if(he&&typeof he==="string"||he===!1){u.invalid.set(T,he);continue}u.invalid.delete(T);let Ta=await n(u.values[T],u,_,p);u.output+=Bo(Ta);continue}_.placeholder=!1;let Aa=v;if(v=await l(v,u,_,p),O!==v)u.values[T]=O,v=e.styles.typing(O),u.missing.delete(Me);else if(u.values[T]=void 0,O=`<${Me}>`,v=e.styles.primary(O),_.placeholder=!0,u.required.has(T))u.missing.add(Me);if(u.missing.has(Me)&&u.validating)v=e.styles.warning(O);if(u.invalid.has(T)&&u.validating)v=e.styles.danger(O);if(p===u.index)if(Aa!==v)v=e.styles.underline(v);else v=e.styles.heading(Bo(v));p++}if(v)u.output+=v}let f=u.output.split(`
25
+ `).map((w)=>" "+w),g=i.length,y=0;for(let w of i){if(u.invalid.has(w.name))w.lines.forEach((v)=>{if(f[v][0]!==" ")return;f[v]=u.styles.danger(u.symbols.bullet)+f[v].slice(1)});if(e.isValue(u.values[w.name]))y++}return u.completed=(y/g*100).toFixed(0),u.output=f.join(`
26
+ `),u.output}};function Mt(e,t,s,o){return(r,i,a,n)=>{if(typeof a.field[e]==="function")return a.field[e].call(t,r,i,a,n);return[o,r].find((l)=>t.isValue(l))}}});var ko=E((su,Lo)=>{var Cl=se(),Ml=Do(),_l=fe();class Po extends _l{constructor(e){super(e);this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await Ml(this),await super.initialize()}async reset(e){if(this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0)await this.initialize(),await this.render()}moveCursor(e){let t=this.getItem();this.cursor+=e,t.cursor+=e}dispatch(e,t){if(!t.code&&!t.ctrl&&e!=null&&this.getItem()){this.append(e,t);return}this.alert()}append(e,t){let s=this.getItem(),o=s.input.slice(0,this.cursor),r=s.input.slice(this.cursor);this.input=s.input=`${o}${e}${r}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let t=e.input.slice(this.cursor),s=e.input.slice(0,this.cursor-1);this.input=e.input=`${s}${t}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let t=this.state.completed<100?this.styles.warning:this.styles.success;if(this.state.submitted===!0&&this.state.completed!==100)t=this.styles.danger;return t(`${this.state.completed}% completed`)}async render(){let{index:e,keys:t=[],submitted:s,size:o}=this.state,r=[this.options.newline,`
27
+ `].find((y)=>y!=null),i=await this.prefix(),a=await this.separator(),n=await this.message(),l=[i,n,a].filter(Boolean).join(" ");this.state.prompt=l;let d=await this.header(),c=await this.error()||"",u=await this.hint()||"",m=s?"":await this.interpolate(this.state),p=this.state.key=t[e]||"",h=await this.format(p),f=await this.footer();if(h)l+=" "+h;if(u&&!h&&this.state.completed===0)l+=" "+u;this.clear(o);let g=[d,l,m,f,c.trim()];this.write(g.filter(Boolean).join(r)),this.restore()}getItem(e){let{items:t,keys:s,index:o}=this.state,r=t.find((i)=>i.name===s[o]);if(r&&r.input!=null)this.input=r.input,this.cursor=r.cursor;return r}async submit(){if(typeof this.interpolate!=="function")await this.initialize();await this.interpolate(this.state,!0);let{invalid:e,missing:t,output:s,values:o}=this.state;if(e.size){let a="";for(let[n,l]of e)a+=`Invalid ${n}: ${l}
28
+ `;return this.state.error=a,super.submit()}if(t.size)return this.state.error="Required: "+[...t.keys()].join(", "),super.submit();let i=Cl(s).split(`
29
29
  `).map((a)=>a.slice(1)).join(`
30
- `);return this.value={values:r,result:i},super.submit()}}Dr.exports=Or});var Ur=x((Mm,Lr)=>{var yd=re();class Pr extends yd{constructor(e){super({...e,reorder:!1,sort:!0,multiple:!0});this.state.hint=[this.options.hint,"(Use <shift>+<up/down> to sort)"].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,t){let s=await super.renderChoice(e,t),r=this.symbols.identicalTo+" ",o=this.index===t&&this.sorting?this.styles.muted(r):" ";if(this.options.drag===!1)o="";if(this.options.numbered===!0)return o+`${t+1} - `+s;return o+s}get selected(){return this.choices}submit(){return this.value=this.choices.map((e)=>e.value),super.submit()}}Lr.exports=Pr});var $r=x((Cm,kr)=>{var gd=xe();class Gr extends gd{constructor(e={}){super(e);if(this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let t=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];t=t.map((s)=>this.styles.muted(s)),this.state.header=t.join(`
31
- `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let t=await super.toChoices(...e);for(let s of t)s.scale=bd(5,this.options),s.scaleIdx=2;return t}dispatch(){this.alert()}space(){let e=this.focused,t=e.scale[e.scaleIdx],s=t.selected;return e.scale.forEach((r)=>r.selected=!1),t.selected=!s,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;if(e.scaleIdx>=e.scale.length-1)return this.alert();return e.scaleIdx++,this.render()}left(){let e=this.focused;if(e.scaleIdx<=0)return this.alert();return e.scaleIdx--,this.render()}indent(){return" "}async renderChoice(e,t){await this.onChoice(e,t);let s=this.index===t,r=this.term==="Hyper",o=!r?8:9,i=!r?" ":"",a=this.symbols.line.repeat(o),n=" ".repeat(o+(r?0:1)),d=(E)=>(E?this.styles.success("\u25C9"):"\u25EF")+i,l=t+1+".",p=s?this.styles.heading:this.styles.noop,u=await this.resolve(e.message,this.state,e,t),m=this.indent(e),c=m+e.scale.map((E,A)=>d(A===e.scaleIdx)).join(a),h=(E)=>E===e.scaleIdx?p(E):E,f=m+e.scale.map((E,A)=>h(A)).join(n),g=()=>[l,u].filter(Boolean).join(" "),y=()=>[g(),c,f," "].filter(Boolean).join(`
32
- `);if(s)c=this.styles.cyan(c),f=this.styles.cyan(f);return y()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(s,r)=>await this.renderChoice(s,r)),t=await Promise.all(e);if(!t.length)t.push(this.styles.danger("No matching choices"));return t.join(`
33
- `)}format(){if(this.state.submitted)return this.choices.map((t)=>this.styles.info(t.scaleIdx)).join(", ");return""}async render(){let{submitted:e,size:t}=this.state,s=await this.prefix(),r=await this.separator(),o=await this.message(),i=[s,o,r].filter(Boolean).join(" ");this.state.prompt=i;let a=await this.header(),n=await this.format(),d=await this.error()||await this.hint(),l=await this.renderChoices(),p=await this.footer();if(n||!d)i+=" "+n;if(d&&!i.includes(d))i+=" "+d;if(e&&!n&&!l&&this.multiple&&this.type!=="form")i+=this.styles.danger(this.emptyError);this.clear(t),this.write([i,a,l,p].filter(Boolean).join(`
34
- `)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}}function bd(e,t={}){if(Array.isArray(t.scale))return t.scale.map((r)=>({...r}));let s=[];for(let r=1;r<e+1;r++)s.push({i:r,selected:!1});return s}kr.exports=Gr});var Kr=x((_m,Wr)=>{var wd=De();class qr extends wd{async initialize(){await super.initialize(),this.value=this.initial=this.resolve(this.options.initial),this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",t){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=(s)=>this.styles.primary.underline(s);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,t=await this.header(),s=await this.prefix(),r=await this.separator(),o=await this.message(),i=await this.format(),a=await this.error()||await this.hint(),n=await this.footer(),d=[s,o,r,i].join(" ");if(this.state.prompt=d,a&&!d.includes(a))d+=" "+a;this.clear(e),this.write([t,d,n].filter(Boolean).join(`
35
- `)),this.write(this.margin[2]),this.restore()}}Wr.exports=qr});var Vr=x((Im,Hr)=>{var xd=re();class Fr extends xd{constructor(e){super(e);if(typeof this.options.correctChoice!=="number"||this.options.correctChoice<0)throw Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,t){let s=await super.toChoices(e,t);if(s.length<2)throw Error("Please give at least two choices to the user");if(this.options.correctChoice>s.length)throw Error("Please specify the index of the correct answer from the list of choices");return s}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}}Hr.exports=Fr});var zr=x((Mt)=>{var Yr=M(),S=(e,t)=>{Yr.defineExport(Mt,e,t),Yr.defineExport(Mt,e.toLowerCase(),t)};S("AutoComplete",()=>$s());S("BasicAuth",()=>zs());S("Confirm",()=>js());S("Editable",()=>sr());S("Form",()=>Oe());S("Input",()=>St());S("Invisible",()=>mr());S("List",()=>fr());S("MultiSelect",()=>br());S("Numeral",()=>Tt());S("Password",()=>vr());S("Scale",()=>Rr());S("Select",()=>re());S("Snippet",()=>Br());S("Sort",()=>Ur());S("Survey",()=>$r());S("Text",()=>St());S("Toggle",()=>Kr());S("Quiz",()=>Vr())});var Qr=x((Dm,Zr)=>{Zr.exports={ArrayPrompt:xe(),AuthPrompt:Nt(),BooleanPrompt:De(),NumberPrompt:Tt(),StringPrompt:de()}});var ie=x((Bm,Jr)=>{var Xr=ge("assert"),_t=ge("events"),oe=M();class L extends _t{constructor(e,t){super();this.options=oe.merge({},e),this.answers={...t}}register(e,t){if(oe.isObject(e)){for(let r of Object.keys(e))this.register(r,e[r]);return this}Xr.equal(typeof t,"function","expected a function");let s=e.toLowerCase();if(t.prototype instanceof this.Prompt)this.prompts[s]=t;else this.prompts[s]=t(this.Prompt,this);return this}async prompt(e=[]){for(let t of[].concat(e))try{if(typeof t==="function")t=await t.call(this);await this.ask(oe.merge({},this.options,t))}catch(s){return Promise.reject(s)}return this.answers}async ask(e){if(typeof e==="function")e=await e.call(this);let t=oe.merge({},this.options,e),{type:s,name:r}=e,{set:o,get:i}=oe;if(typeof s==="function")s=await s.call(this,e,this.answers);if(!s)return this.answers[r];if(s==="number")s="numeral";Xr(this.prompts[s],`Prompt "${s}" is not registered`);let a=new this.prompts[s](t),n=i(this.answers,r);if(a.state.answers=this.answers,a.enquirer=this,r)a.on("submit",(l)=>{this.emit("answer",r,l,a),o(this.answers,r,l)});let d=a.emit.bind(a);if(a.emit=(...l)=>{return this.emit.call(this,...l),d(...l)},this.emit("prompt",a,this),t.autofill&&n!=null){if(a.value=a.input=n,t.autofill==="show")await a.submit()}else n=a.value=await a.run();return n}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||me()}static get prompts(){return zr()}static get types(){return Qr()}static get prompt(){let e=(t,...s)=>{let r=new this(...s),o=r.emit.bind(r);return r.emit=(...i)=>{return e.emit(...i),o(...i)},r.prompt(t)};return oe.mixinEmitter(e,new _t),e}}oe.mixinEmitter(L,new _t);var Ct=L.prompts;for(let e of Object.keys(Ct)){let t=e.toLowerCase(),s=(r)=>new Ct[e](r).run();if(L.prompt[t]=s,L[t]=s,!L[e])Reflect.defineProperty(L,e,{get:()=>Ct[e]})}var Ee=(e)=>{oe.defineExport(L,e,()=>L.types[e])};Ee("ArrayPrompt");Ee("AuthPrompt");Ee("BooleanPrompt");Ee("NumberPrompt");Ee("StringPrompt");Jr.exports=L});var Ii=x((Lt,Ut)=>{(function(e,t){if(typeof Lt==="object"&&typeof Ut==="object")Ut.exports=t();else if(typeof define==="function"&&define.amd)define(function(){return t()});else e.pluralize=t()})(Lt,function(){var e=[],t=[],s={},r={},o={};function i(c){if(typeof c==="string")return new RegExp("^"+c+"$","i");return c}function a(c,h){if(c===h)return h;if(c===c.toLowerCase())return h.toLowerCase();if(c===c.toUpperCase())return h.toUpperCase();if(c[0]===c[0].toUpperCase())return h.charAt(0).toUpperCase()+h.substr(1).toLowerCase();return h.toLowerCase()}function n(c,h){return c.replace(/\$(\d{1,2})/g,function(f,g){return h[g]||""})}function d(c,h){return c.replace(h[0],function(f,g){var y=n(h[1],arguments);if(f==="")return a(c[g-1],y);return a(f,y)})}function l(c,h,f){if(!c.length||s.hasOwnProperty(c))return h;var g=f.length;while(g--){var y=f[g];if(y[0].test(h))return d(h,y)}return h}function p(c,h,f){return function(g){var y=g.toLowerCase();if(h.hasOwnProperty(y))return a(g,y);if(c.hasOwnProperty(y))return a(g,c[y]);return l(y,g,f)}}function u(c,h,f,g){return function(y){var E=y.toLowerCase();if(h.hasOwnProperty(E))return!0;if(c.hasOwnProperty(E))return!1;return l(E,E,f)===E}}function m(c,h,f){var g=h===1?m.singular(c):m.plural(c);return(f?h+" ":"")+g}return m.plural=p(o,r,e),m.isPlural=u(o,r,e),m.singular=p(r,o,t),m.isSingular=u(r,o,t),m.addPluralRule=function(c,h){e.push([i(c),h])},m.addSingularRule=function(c,h){t.push([i(c),h])},m.addUncountableRule=function(c){if(typeof c==="string"){s[c.toLowerCase()]=!0;return}m.addPluralRule(c,"$0"),m.addSingularRule(c,"$0")},m.addIrregularRule=function(c,h){h=h.toLowerCase(),c=c.toLowerCase(),o[c]=h,r[h]=c},[["I","we"],["me","us"],["he","they"],["she","they"],["them","them"],["myself","ourselves"],["yourself","yourselves"],["itself","themselves"],["herself","themselves"],["himself","themselves"],["themself","themselves"],["is","are"],["was","were"],["has","have"],["this","these"],["that","those"],["echo","echoes"],["dingo","dingoes"],["volcano","volcanoes"],["tornado","tornadoes"],["torpedo","torpedoes"],["genus","genera"],["viscus","viscera"],["stigma","stigmata"],["stoma","stomata"],["dogma","dogmata"],["lemma","lemmata"],["schema","schemata"],["anathema","anathemata"],["ox","oxen"],["axe","axes"],["die","dice"],["yes","yeses"],["foot","feet"],["eave","eaves"],["goose","geese"],["tooth","teeth"],["quiz","quizzes"],["human","humans"],["proof","proofs"],["carve","carves"],["valve","valves"],["looey","looies"],["thief","thieves"],["groove","grooves"],["pickaxe","pickaxes"],["passerby","passersby"]].forEach(function(c){return m.addIrregularRule(c[0],c[1])}),[[/s?$/i,"s"],[/[^\u0000-\u007F]$/i,"$0"],[/([^aeiou]ese)$/i,"$1"],[/(ax|test)is$/i,"$1es"],[/(alias|[^aou]us|t[lm]as|gas|ris)$/i,"$1es"],[/(e[mn]u)s?$/i,"$1s"],[/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i,"$1"],[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i,"$1i"],[/(alumn|alg|vertebr)(?:a|ae)$/i,"$1ae"],[/(seraph|cherub)(?:im)?$/i,"$1im"],[/(her|at|gr)o$/i,"$1oes"],[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i,"$1a"],[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i,"$1a"],[/sis$/i,"ses"],[/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i,"$1$2ves"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/([^ch][ieo][ln])ey$/i,"$1ies"],[/(x|ch|ss|sh|zz)$/i,"$1es"],[/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i,"$1ices"],[/\b((?:tit)?m|l)(?:ice|ouse)$/i,"$1ice"],[/(pe)(?:rson|ople)$/i,"$1ople"],[/(child)(?:ren)?$/i,"$1ren"],[/eaux$/i,"$0"],[/m[ae]n$/i,"men"],["thou","you"]].forEach(function(c){return m.addPluralRule(c[0],c[1])}),[[/s$/i,""],[/(ss)$/i,"$1"],[/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i,"$1fe"],[/(ar|(?:wo|[ae])l|[eo][ao])ves$/i,"$1f"],[/ies$/i,"y"],[/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i,"$1ie"],[/\b(mon|smil)ies$/i,"$1ey"],[/\b((?:tit)?m|l)ice$/i,"$1ouse"],[/(seraph|cherub)im$/i,"$1"],[/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i,"$1"],[/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i,"$1sis"],[/(movie|twelve|abuse|e[mn]u)s$/i,"$1"],[/(test)(?:is|es)$/i,"$1is"],[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i,"$1us"],[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i,"$1um"],[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i,"$1on"],[/(alumn|alg|vertebr)ae$/i,"$1a"],[/(cod|mur|sil|vert|ind)ices$/i,"$1ex"],[/(matr|append)ices$/i,"$1ix"],[/(pe)(rson|ople)$/i,"$1rson"],[/(child)ren$/i,"$1"],[/(eau)x?$/i,"$1"],[/men$/i,"man"]].forEach(function(c){return m.addSingularRule(c[0],c[1])}),["adulthood","advice","agenda","aid","aircraft","alcohol","ammo","analytics","anime","athletics","audio","bison","blood","bream","buffalo","butter","carp","cash","chassis","chess","clothing","cod","commerce","cooperation","corps","debris","diabetes","digestion","elk","energy","equipment","excretion","expertise","firmware","flounder","fun","gallows","garbage","graffiti","hardware","headquarters","health","herpes","highjinks","homework","housework","information","jeans","justice","kudos","labour","literature","machinery","mackerel","mail","media","mews","moose","music","mud","manga","news","only","personnel","pike","plankton","pliers","police","pollution","premises","rain","research","rice","salmon","scissors","series","sewage","shambles","shrimp","software","species","staff","swine","tennis","traffic","transportation","trout","tuna","wealth","welfare","whiting","wildebeest","wildlife","you",/pok[e\u00E9]mon$/i,/[^aeiou]ese$/i,/deer$/i,/fish$/i,/measles$/i,/o[iu]s$/i,/pox$/i,/sheep$/i].forEach(m.addUncountableRule),m})});import{parseArgs as Np}from"util";import{Exception as oa}from"@ooneex/exception";import{TerminalLogger as Sp}from"@ooneex/logger";import{container as ga}from"@ooneex/container";var Se=[];var Kt=(e)=>{let t=null;return Se.find((s)=>{return t=ga.get(s),t.getName()===e}),t};import{homedir as Aa}from"os";import{join as at}from"path";import{TerminalLogger as va}from"@ooneex/logger";import{container as ba,EContainerScope as wa}from"@ooneex/container";var w={command:(e=wa.Singleton)=>{return(t)=>{ba.add(t,e),Se.push(t)}}};var Ft=`#compdef oo ooneex
30
+ `);return this.value={values:o,result:i},super.submit()}}Lo.exports=Po});var $o=E((ou,Go)=>{var Bl=re();class Uo extends Bl{constructor(e){super({...e,reorder:!1,sort:!0,multiple:!0});this.state.hint=[this.options.hint,"(Use <shift>+<up/down> to sort)"].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,t){let s=await super.renderChoice(e,t),o=this.symbols.identicalTo+" ",r=this.index===t&&this.sorting?this.styles.muted(o):" ";if(this.options.drag===!1)r="";if(this.options.numbered===!0)return r+`${t+1} - `+s;return r+s}get selected(){return this.choices}submit(){return this.value=this.choices.map((e)=>e.value),super.submit()}}Go.exports=Uo});var Fo=E((ru,Wo)=>{var Il=Se();class qo extends Il{constructor(e={}){super(e);if(this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let t=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];t=t.map((s)=>this.styles.muted(s)),this.state.header=t.join(`
31
+ `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let t=await super.toChoices(...e);for(let s of t)s.scale=Ol(5,this.options),s.scaleIdx=2;return t}dispatch(){this.alert()}space(){let e=this.focused,t=e.scale[e.scaleIdx],s=t.selected;return e.scale.forEach((o)=>o.selected=!1),t.selected=!s,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;if(e.scaleIdx>=e.scale.length-1)return this.alert();return e.scaleIdx++,this.render()}left(){let e=this.focused;if(e.scaleIdx<=0)return this.alert();return e.scaleIdx--,this.render()}indent(){return" "}async renderChoice(e,t){await this.onChoice(e,t);let s=this.index===t,o=this.term==="Hyper",r=!o?8:9,i=!o?" ":"",a=this.symbols.line.repeat(r),n=" ".repeat(r+(o?0:1)),l=(w)=>(w?this.styles.success("\u25C9"):"\u25EF")+i,d=t+1+".",c=s?this.styles.heading:this.styles.noop,u=await this.resolve(e.message,this.state,e,t),m=this.indent(e),p=m+e.scale.map((w,v)=>l(v===e.scaleIdx)).join(a),h=(w)=>w===e.scaleIdx?c(w):w,f=m+e.scale.map((w,v)=>h(v)).join(n),g=()=>[d,u].filter(Boolean).join(" "),y=()=>[g(),p,f," "].filter(Boolean).join(`
32
+ `);if(s)p=this.styles.cyan(p),f=this.styles.cyan(f);return y()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(s,o)=>await this.renderChoice(s,o)),t=await Promise.all(e);if(!t.length)t.push(this.styles.danger("No matching choices"));return t.join(`
33
+ `)}format(){if(this.state.submitted)return this.choices.map((t)=>this.styles.info(t.scaleIdx)).join(", ");return""}async render(){let{submitted:e,size:t}=this.state,s=await this.prefix(),o=await this.separator(),r=await this.message(),i=[s,r,o].filter(Boolean).join(" ");this.state.prompt=i;let a=await this.header(),n=await this.format(),l=await this.error()||await this.hint(),d=await this.renderChoices(),c=await this.footer();if(n||!l)i+=" "+n;if(l&&!i.includes(l))i+=" "+l;if(e&&!n&&!d&&this.multiple&&this.type!=="form")i+=this.styles.danger(this.emptyError);this.clear(t),this.write([i,a,d,c].filter(Boolean).join(`
34
+ `)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}}function Ol(e,t={}){if(Array.isArray(t.scale))return t.scale.map((o)=>({...o}));let s=[];for(let o=1;o<e+1;o++)s.push({i:o,selected:!1});return s}Wo.exports=qo});var Vo=E((iu,Ho)=>{var Dl=Ue();class Ko extends Dl{async initialize(){await super.initialize(),this.value=this.initial=this.resolve(this.options.initial),this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",t){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=(s)=>this.styles.primary.underline(s);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,t=await this.header(),s=await this.prefix(),o=await this.separator(),r=await this.message(),i=await this.format(),a=await this.error()||await this.hint(),n=await this.footer(),l=[s,r,o,i].join(" ");if(this.state.prompt=l,a&&!l.includes(a))l+=" "+a;this.clear(e),this.write([t,l,n].filter(Boolean).join(`
35
+ `)),this.write(this.margin[2]),this.restore()}}Ho.exports=Ko});var Qo=E((au,Yo)=>{var Pl=re();class zo extends Pl{constructor(e){super(e);if(typeof this.options.correctChoice!=="number"||this.options.correctChoice<0)throw Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,t){let s=await super.toChoices(e,t);if(s.length<2)throw Error("Please give at least two choices to the user");if(this.options.correctChoice>s.length)throw Error("Please specify the index of the correct answer from the list of choices");return s}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}}Yo.exports=zo});var Xo=E((_t)=>{var Zo=M(),S=(e,t)=>{Zo.defineExport(_t,e,t),Zo.defineExport(_t,e.toLowerCase(),t)};S("AutoComplete",()=>Ws());S("BasicAuth",()=>Zs());S("Confirm",()=>to());S("Editable",()=>ro());S("Form",()=>ke());S("Input",()=>Rt());S("Invisible",()=>fo());S("List",()=>bo());S("MultiSelect",()=>Eo());S("Numeral",()=>Ct());S("Password",()=>No());S("Scale",()=>_o());S("Select",()=>re());S("Snippet",()=>ko());S("Sort",()=>$o());S("Survey",()=>Fo());S("Text",()=>Rt());S("Toggle",()=>Vo());S("Quiz",()=>Qo())});var jo=E((lu,Jo)=>{Jo.exports={ArrayPrompt:Se(),AuthPrompt:Nt(),BooleanPrompt:Ue(),NumberPrompt:Ct(),StringPrompt:ce()}});var ae=E((du,tr)=>{var er=ve("assert"),It=ve("events"),ie=M();class k extends It{constructor(e,t){super();this.options=ie.merge({},e),this.answers={...t}}register(e,t){if(ie.isObject(e)){for(let o of Object.keys(e))this.register(o,e[o]);return this}er.equal(typeof t,"function","expected a function");let s=e.toLowerCase();if(t.prototype instanceof this.Prompt)this.prompts[s]=t;else this.prompts[s]=t(this.Prompt,this);return this}async prompt(e=[]){for(let t of[].concat(e))try{if(typeof t==="function")t=await t.call(this);await this.ask(ie.merge({},this.options,t))}catch(s){return Promise.reject(s)}return this.answers}async ask(e){if(typeof e==="function")e=await e.call(this);let t=ie.merge({},this.options,e),{type:s,name:o}=e,{set:r,get:i}=ie;if(typeof s==="function")s=await s.call(this,e,this.answers);if(!s)return this.answers[o];if(s==="number")s="numeral";er(this.prompts[s],`Prompt "${s}" is not registered`);let a=new this.prompts[s](t),n=i(this.answers,o);if(a.state.answers=this.answers,a.enquirer=this,o)a.on("submit",(d)=>{this.emit("answer",o,d,a),r(this.answers,o,d)});let l=a.emit.bind(a);if(a.emit=(...d)=>{return this.emit.call(this,...d),l(...d)},this.emit("prompt",a,this),t.autofill&&n!=null){if(a.value=a.input=n,t.autofill==="show")await a.submit()}else n=a.value=await a.run();return n}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||fe()}static get prompts(){return Xo()}static get types(){return jo()}static get prompt(){let e=(t,...s)=>{let o=new this(...s),r=o.emit.bind(o);return o.emit=(...i)=>{return e.emit(...i),r(...i)},o.prompt(t)};return ie.mixinEmitter(e,new It),e}}ie.mixinEmitter(k,new It);var Bt=k.prompts;for(let e of Object.keys(Bt)){let t=e.toLowerCase(),s=(o)=>new Bt[e](o).run();if(k.prompt[t]=s,k[t]=s,!k[e])Reflect.defineProperty(k,e,{get:()=>Bt[e]})}var Ne=(e)=>{ie.defineExport(k,e,()=>k.types[e])};Ne("ArrayPrompt");Ne("AuthPrompt");Ne("BooleanPrompt");Ne("NumberPrompt");Ne("StringPrompt");tr.exports=k});var Oi=E((Ut,Gt)=>{(function(e,t){if(typeof Ut==="object"&&typeof Gt==="object")Gt.exports=t();else if(typeof define==="function"&&define.amd)define(function(){return t()});else e.pluralize=t()})(Ut,function(){var e=[],t=[],s={},o={},r={};function i(p){if(typeof p==="string")return new RegExp("^"+p+"$","i");return p}function a(p,h){if(p===h)return h;if(p===p.toLowerCase())return h.toLowerCase();if(p===p.toUpperCase())return h.toUpperCase();if(p[0]===p[0].toUpperCase())return h.charAt(0).toUpperCase()+h.substr(1).toLowerCase();return h.toLowerCase()}function n(p,h){return p.replace(/\$(\d{1,2})/g,function(f,g){return h[g]||""})}function l(p,h){return p.replace(h[0],function(f,g){var y=n(h[1],arguments);if(f==="")return a(p[g-1],y);return a(f,y)})}function d(p,h,f){if(!p.length||s.hasOwnProperty(p))return h;var g=f.length;while(g--){var y=f[g];if(y[0].test(h))return l(h,y)}return h}function c(p,h,f){return function(g){var y=g.toLowerCase();if(h.hasOwnProperty(y))return a(g,y);if(p.hasOwnProperty(y))return a(g,p[y]);return d(y,g,f)}}function u(p,h,f,g){return function(y){var w=y.toLowerCase();if(h.hasOwnProperty(w))return!0;if(p.hasOwnProperty(w))return!1;return d(w,w,f)===w}}function m(p,h,f){var g=h===1?m.singular(p):m.plural(p);return(f?h+" ":"")+g}return m.plural=c(r,o,e),m.isPlural=u(r,o,e),m.singular=c(o,r,t),m.isSingular=u(o,r,t),m.addPluralRule=function(p,h){e.push([i(p),h])},m.addSingularRule=function(p,h){t.push([i(p),h])},m.addUncountableRule=function(p){if(typeof p==="string"){s[p.toLowerCase()]=!0;return}m.addPluralRule(p,"$0"),m.addSingularRule(p,"$0")},m.addIrregularRule=function(p,h){h=h.toLowerCase(),p=p.toLowerCase(),r[p]=h,o[h]=p},[["I","we"],["me","us"],["he","they"],["she","they"],["them","them"],["myself","ourselves"],["yourself","yourselves"],["itself","themselves"],["herself","themselves"],["himself","themselves"],["themself","themselves"],["is","are"],["was","were"],["has","have"],["this","these"],["that","those"],["echo","echoes"],["dingo","dingoes"],["volcano","volcanoes"],["tornado","tornadoes"],["torpedo","torpedoes"],["genus","genera"],["viscus","viscera"],["stigma","stigmata"],["stoma","stomata"],["dogma","dogmata"],["lemma","lemmata"],["schema","schemata"],["anathema","anathemata"],["ox","oxen"],["axe","axes"],["die","dice"],["yes","yeses"],["foot","feet"],["eave","eaves"],["goose","geese"],["tooth","teeth"],["quiz","quizzes"],["human","humans"],["proof","proofs"],["carve","carves"],["valve","valves"],["looey","looies"],["thief","thieves"],["groove","grooves"],["pickaxe","pickaxes"],["passerby","passersby"]].forEach(function(p){return m.addIrregularRule(p[0],p[1])}),[[/s?$/i,"s"],[/[^\u0000-\u007F]$/i,"$0"],[/([^aeiou]ese)$/i,"$1"],[/(ax|test)is$/i,"$1es"],[/(alias|[^aou]us|t[lm]as|gas|ris)$/i,"$1es"],[/(e[mn]u)s?$/i,"$1s"],[/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i,"$1"],[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i,"$1i"],[/(alumn|alg|vertebr)(?:a|ae)$/i,"$1ae"],[/(seraph|cherub)(?:im)?$/i,"$1im"],[/(her|at|gr)o$/i,"$1oes"],[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i,"$1a"],[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i,"$1a"],[/sis$/i,"ses"],[/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i,"$1$2ves"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/([^ch][ieo][ln])ey$/i,"$1ies"],[/(x|ch|ss|sh|zz)$/i,"$1es"],[/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i,"$1ices"],[/\b((?:tit)?m|l)(?:ice|ouse)$/i,"$1ice"],[/(pe)(?:rson|ople)$/i,"$1ople"],[/(child)(?:ren)?$/i,"$1ren"],[/eaux$/i,"$0"],[/m[ae]n$/i,"men"],["thou","you"]].forEach(function(p){return m.addPluralRule(p[0],p[1])}),[[/s$/i,""],[/(ss)$/i,"$1"],[/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i,"$1fe"],[/(ar|(?:wo|[ae])l|[eo][ao])ves$/i,"$1f"],[/ies$/i,"y"],[/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i,"$1ie"],[/\b(mon|smil)ies$/i,"$1ey"],[/\b((?:tit)?m|l)ice$/i,"$1ouse"],[/(seraph|cherub)im$/i,"$1"],[/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i,"$1"],[/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i,"$1sis"],[/(movie|twelve|abuse|e[mn]u)s$/i,"$1"],[/(test)(?:is|es)$/i,"$1is"],[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i,"$1us"],[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i,"$1um"],[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i,"$1on"],[/(alumn|alg|vertebr)ae$/i,"$1a"],[/(cod|mur|sil|vert|ind)ices$/i,"$1ex"],[/(matr|append)ices$/i,"$1ix"],[/(pe)(rson|ople)$/i,"$1rson"],[/(child)ren$/i,"$1"],[/(eau)x?$/i,"$1"],[/men$/i,"man"]].forEach(function(p){return m.addSingularRule(p[0],p[1])}),["adulthood","advice","agenda","aid","aircraft","alcohol","ammo","analytics","anime","athletics","audio","bison","blood","bream","buffalo","butter","carp","cash","chassis","chess","clothing","cod","commerce","cooperation","corps","debris","diabetes","digestion","elk","energy","equipment","excretion","expertise","firmware","flounder","fun","gallows","garbage","graffiti","hardware","headquarters","health","herpes","highjinks","homework","housework","information","jeans","justice","kudos","labour","literature","machinery","mackerel","mail","media","mews","moose","music","mud","manga","news","only","personnel","pike","plankton","pliers","police","pollution","premises","rain","research","rice","salmon","scissors","series","sewage","shambles","shrimp","software","species","staff","swine","tennis","traffic","transportation","trout","tuna","wealth","welfare","whiting","wildebeest","wildlife","you",/pok[e\u00E9]mon$/i,/[^aeiou]ese$/i,/deer$/i,/fish$/i,/measles$/i,/o[iu]s$/i,/pox$/i,/sheep$/i].forEach(m.addUncountableRule),m})});import{parseArgs as jc}from"util";import{Exception as xa}from"@ooneex/exception";import{TerminalLogger as em}from"@ooneex/logger";import{container as Ia}from"@ooneex/container";var _e=[];var Ht=(e)=>{let t=null;return _e.find((s)=>{return t=Ia.get(s),t.getName()===e}),t};import{homedir as ka}from"os";import{join as lt}from"path";import{TerminalLogger as Ua}from"@ooneex/logger";import{container as Oa,EContainerScope as Da}from"@ooneex/container";var x={command:(e=Da.Singleton)=>{return(t)=>{Oa.add(t,e),_e.push(t)}}};var Vt=`#compdef oo ooneex
36
36
 
37
37
  _oo_modules() {
38
38
  local -a modules
@@ -65,6 +65,7 @@ _oo() {
65
65
  'make\\:pubsub:Generate a new PubSub event class'
66
66
  'make\\:release:Release packages with version bump, changelog, and git tag'
67
67
  'make\\:repository:Generate a new repository class'
68
+ 'make\\:resource\\:book:Generate book resource (entity, migration, repository)'
68
69
  'make\\:seed:Generate a new seed file'
69
70
  'make\\:service:Generate a new service class'
70
71
  'make\\:storage:Generate a new storage class'
@@ -137,7 +138,7 @@ _oo() {
137
138
  '--name=[Name of the resource]:name' \\
138
139
  '--module=[Module name]:module:_oo_modules'
139
140
  ;;
140
- make:release|make:claude:skill|completion:zsh)
141
+ make:release|make:resource:book|make:claude:skill|completion:zsh)
141
142
  ;;
142
143
  esac
143
144
  ;;
@@ -145,7 +146,7 @@ _oo() {
145
146
  }
146
147
 
147
148
  _oo "$@"
148
- `;var Ht=`#compdef oo ooneex
149
+ `;var zt=`#compdef oo ooneex
149
150
 
150
151
  _ooneex_modules() {
151
152
  local -a modules
@@ -178,6 +179,7 @@ _ooneex() {
178
179
  'make\\:pubsub:Generate a new PubSub event class'
179
180
  'make\\:release:Release packages with version bump, changelog, and git tag'
180
181
  'make\\:repository:Generate a new repository class'
182
+ 'make\\:resource\\:book:Generate book resource (entity, migration, repository)'
181
183
  'make\\:seed:Generate a new seed file'
182
184
  'make\\:service:Generate a new service class'
183
185
  'make\\:storage:Generate a new storage class'
@@ -250,7 +252,7 @@ _ooneex() {
250
252
  '--name=[Name of the resource]:name' \\
251
253
  '--module=[Module name]:module:_ooneex_modules'
252
254
  ;;
253
- make:release|make:claude:skill|completion:zsh)
255
+ make:release|make:resource:book|make:claude:skill|completion:zsh)
254
256
  ;;
255
257
  esac
256
258
  ;;
@@ -258,9 +260,9 @@ _ooneex() {
258
260
  }
259
261
 
260
262
  _ooneex "$@"
261
- `;class Te{getName(){return"completion:zsh"}getDescription(){return"Install Zsh completion for oo command"}async run(){let e=at(Aa(),".zsh"),t=at(e,"_oo");await Bun.write(t,Ft);let s=at(e,"_ooneex");await Bun.write(s,Ht);let r=new va;r.success(`${t} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),r.success(`${s} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),r.info(`Add the following to your .zshrc if not already present:
263
+ `;class Be{getName(){return"completion:zsh"}getDescription(){return"Install Zsh completion for oo command"}async run(){let e=lt(ka(),".zsh"),t=lt(e,"_oo");await Bun.write(t,Vt);let s=lt(e,"_ooneex");await Bun.write(s,zt);let o=new Ua;o.success(`${t} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),o.success(`${s} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),o.info(`Add the following to your .zshrc if not already present:
262
264
  fpath=(~/.zsh $fpath)
263
- autoload -Uz compinit && compinit`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}Te=b([w.command()],Te);import{join as F}from"path";import{TerminalLogger as Rd}from"@ooneex/logger";import{toPascalCase as Md}from"@ooneex/utils";var jr=ee(ie(),1);import{Assert as Ed,Validation as Ad}from"@ooneex/validation";var vd=1,Nd=/^[a-zA-Z][a-zA-Z0-9-]*$/;class Ae extends Ad{getConstraint(){return Ed(`string >= ${vd}`)}getErrorMessage(){return"Name must start with a letter and contain only letters, numbers, and hyphens"}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let r=e;if(!Nd.test(r))return{isValid:!1,message:this.getErrorMessage()||"Invalid name format"};return{isValid:!0}}}var v=async(e)=>{return(await jr.prompt({type:"input",name:"name",message:e.message,validate:(s)=>{let o=new Ae().validate(s);if(!o.isValid)return o.message||"Controller name is invalid";return!0}})).name};var eo=`import { describe, expect, test } from "bun:test";
265
+ autoload -Uz compinit && compinit`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}Be=b([x.command()],Be);import{join as H}from"path";import{TerminalLogger as Wl}from"@ooneex/logger";import{toPascalCase as Fl}from"@ooneex/utils";var sr=te(ae(),1);import{Assert as Ll,Validation as kl}from"@ooneex/validation";var Ul=1,Gl=/^[a-zA-Z][a-zA-Z0-9-]*$/;class Re extends kl{getConstraint(){return Ll(`string >= ${Ul}`)}getErrorMessage(){return"Name must start with a letter and contain only letters, numbers, and hyphens"}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let o=e;if(!Gl.test(o))return{isValid:!1,message:this.getErrorMessage()||"Invalid name format"};return{isValid:!0}}}var A=async(e)=>{return(await sr.prompt({type:"input",name:"name",message:e.message,validate:(s)=>{let r=new Re().validate(s);if(!r.isValid)return r.message||"Controller name is invalid";return!0}})).name};var or=`import { describe, expect, test } from "bun:test";
264
266
  import { {{NAME}}Ai } from "@/ai/{{NAME}}Ai";
265
267
 
266
268
  describe("{{NAME}}Ai", () => {
@@ -278,7 +280,7 @@ describe("{{NAME}}Ai", () => {
278
280
  expect(typeof {{NAME}}Ai.prototype.runStream).toBe("function");
279
281
  });
280
282
  });
281
- `;var to=`import { decorator, type IAiChat, OpenAi, type OpenAiConfigType } from "@ooneex/ai";
283
+ `;var rr=`import { decorator, type IAiChat, OpenAi, type OpenAiConfigType } from "@ooneex/ai";
282
284
  import { inject } from "@ooneex/container";
283
285
 
284
286
  @decorator.ai()
@@ -296,7 +298,7 @@ export class {{NAME}}Ai implements IAiChat<OpenAiConfigType> {
296
298
  yield* this.ai.runStream(prompt || "My prompt", config);
297
299
  }
298
300
  }
299
- `;class Pe{getName(){return"make:ai"}getDescription(){return"Generate a new AI class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter name"});t=Md(t).replace(/Ai$/,"");let r=to.replace(/{{NAME}}/g,t),o=s?F("modules",s):".",i=F(o,"src","ai"),a=F(process.cwd(),i),n=F(a,`${t}Ai.ts`);await Bun.write(n,r);let d=eo.replace(/{{NAME}}/g,t),l=F(o,"tests","ai"),p=F(process.cwd(),l),u=F(p,`${t}Ai.spec.ts`);await Bun.write(u,d);let m=new Rd;m.success(`${F(i,t)}Ai.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${F(l,t)}Ai.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/ai"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Pe=b([w.command()],Pe);import{join as H}from"path";import{TerminalLogger as Id}from"@ooneex/logger";import{toPascalCase as Od}from"@ooneex/utils";var so=`import { describe, expect, test } from "bun:test";
301
+ `;class $e{getName(){return"make:ai"}getDescription(){return"Generate a new AI class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter name"});t=Fl(t).replace(/Ai$/,"");let o=rr.replace(/{{NAME}}/g,t),r=s?H("modules",s):".",i=H(r,"src","ai"),a=H(process.cwd(),i),n=H(a,`${t}Ai.ts`);await Bun.write(n,o);let l=or.replace(/{{NAME}}/g,t),d=H(r,"tests","ai"),c=H(process.cwd(),d),u=H(c,`${t}Ai.spec.ts`);await Bun.write(u,l);let m=new Wl;m.success(`${H(i,t)}Ai.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${H(d,t)}Ai.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/ai"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}$e=b([x.command()],$e);import{join as V}from"path";import{TerminalLogger as Vl}from"@ooneex/logger";import{toPascalCase as zl}from"@ooneex/utils";var ir=`import { describe, expect, test } from "bun:test";
300
302
  import { {{NAME}}Analytics } from "@/analytics/{{NAME}}Analytics";
301
303
 
302
304
  describe("{{NAME}}Analytics", () => {
@@ -309,7 +311,7 @@ describe("{{NAME}}Analytics", () => {
309
311
  expect(typeof {{NAME}}Analytics.prototype.capture).toBe("function");
310
312
  });
311
313
  });
312
- `;var ro=`import { decorator } from "@ooneex/analytics";
314
+ `;var ar=`import { decorator } from "@ooneex/analytics";
313
315
  import type { IAnalytics } from "@ooneex/analytics";
314
316
 
315
317
  type CaptureOptionsType = Record<string, unknown>;
@@ -320,7 +322,7 @@ export class {{NAME}}Analytics<T extends CaptureOptionsType = CaptureOptionsType
320
322
  // console.log("Analytics captured:", options);
321
323
  }
322
324
  }
323
- `;class Le{getName(){return"make:analytics"}getDescription(){return"Generate a new analytics class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter analytics name"});t=Od(t).replace(/Analytics$/,"");let r=ro.replace(/{{NAME}}/g,t),o=s?H("modules",s):".",i=H(o,"src","analytics"),a=H(process.cwd(),i),n=H(a,`${t}Analytics.ts`);await Bun.write(n,r);let d=so.replace(/{{NAME}}/g,t),l=H(o,"tests","analytics"),p=H(process.cwd(),l),u=H(p,`${t}Analytics.spec.ts`);await Bun.write(u,d);let m=new Id;m.success(`${H(i,t)}Analytics.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${H(l,t)}Analytics.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/analytics"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Le=b([w.command()],Le);import{join as T}from"path";import{TerminalLogger as bl}from"@ooneex/logger";import{toKebabCase as wl,toSnakeCase as xl}from"@ooneex/utils";var oo=ee(ie(),1);var io=async(e)=>{let t=new Ae;return(await oo.prompt({type:"input",name:"destination",message:e.message,initial:e.initial||".",validate:(r)=>{let o=t.validate(r);if(!o.isValid)return o.message||"Invalid destination";return!0}})).destination};var ao=`import { RuleConfigSeverity, type UserConfig } from "@commitlint/types";
325
+ `;class qe{getName(){return"make:analytics"}getDescription(){return"Generate a new analytics class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter analytics name"});t=zl(t).replace(/Analytics$/,"");let o=ar.replace(/{{NAME}}/g,t),r=s?V("modules",s):".",i=V(r,"src","analytics"),a=V(process.cwd(),i),n=V(a,`${t}Analytics.ts`);await Bun.write(n,o);let l=ir.replace(/{{NAME}}/g,t),d=V(r,"tests","analytics"),c=V(process.cwd(),d),u=V(c,`${t}Analytics.spec.ts`);await Bun.write(u,l);let m=new Vl;m.success(`${V(i,t)}Analytics.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${V(d,t)}Analytics.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/analytics"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}qe=b([x.command()],qe);import{join as N}from"path";import{TerminalLogger as Od}from"@ooneex/logger";import{toKebabCase as Dd,toSnakeCase as Pd}from"@ooneex/utils";var nr=te(ae(),1);var lr=async(e)=>{let t=new Re;return(await nr.prompt({type:"input",name:"destination",message:e.message,initial:e.initial||".",validate:(o)=>{let r=t.validate(o);if(!r.isValid)return r.message||"Invalid destination";return!0}})).destination};var dr=`import { RuleConfigSeverity, type UserConfig } from "@commitlint/types";
324
326
 
325
327
  const Configuration: UserConfig = {
326
328
  extends: ["@commitlint/config-conventional"],
@@ -460,7 +462,7 @@ const Configuration: UserConfig = {
460
462
  };
461
463
 
462
464
  export default Configuration;
463
- `;var no=`# Logs
465
+ `;var pr=`# Logs
464
466
  logs
465
467
  *.log
466
468
  npm-debug.log*
@@ -610,7 +612,7 @@ vite.config.ts.timestamp-*
610
612
 
611
613
  # Application
612
614
  var/
613
- `;var lo=`import { inject } from "@ooneex/container";
615
+ `;var cr=`import { inject } from "@ooneex/container";
614
616
  import { AppEnv } from "@ooneex/app-env";
615
617
  import { DataSource } from "typeorm";
616
618
  import { TypeormDatabase, DatabaseException, decorator } from "@ooneex/database";
@@ -644,7 +646,7 @@ export class AppDatabase extends TypeormDatabase {
644
646
  return this.source;
645
647
  }
646
648
  }
647
- `;var co=`{
649
+ `;var mr=`{
648
650
  "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
649
651
  "vcs": {
650
652
  "enabled": true,
@@ -723,7 +725,7 @@ export class AppDatabase extends TypeormDatabase {
723
725
  }
724
726
  }
725
727
  }
726
- `;var po=`[test]
728
+ `;var ur=`[test]
727
729
  coverage = true
728
730
 
729
731
  [workspace]
@@ -754,7 +756,7 @@ buildDependencies = [
754
756
  "@swc/core",
755
757
  "nx",
756
758
  ]
757
- `;var mo=`# use the official Bun image
759
+ `;var hr=`# use the official Bun image
758
760
  # see all versions at https://hub.docker.com/r/oven/bun/tags
759
761
  FROM oven/bun:1 AS base
760
762
  WORKDIR /{{NAME}}
@@ -801,7 +803,7 @@ COPY --from=prerelease /{{NAME}}/dist .
801
803
  USER bun
802
804
  EXPOSE 3000/tcp
803
805
  ENTRYPOINT [ "bun", "run", "index.js" ]
804
- `;var uo=`services:
806
+ `;var fr=`services:
805
807
  # PostgreSQL - Primary relational database
806
808
  # Docs: https://www.postgresql.org/docs/
807
809
  # Connection: postgresql://ooneex:ooneex@localhost:5432/ooneex
@@ -835,7 +837,7 @@ ENTRYPOINT [ "bun", "run", "index.js" ]
835
837
  volumes:
836
838
  {{NAME}}_db_data:
837
839
  {{NAME}}_redis_data:
838
- `;var It=`# =============================================================================
840
+ `;var Ot=`# =============================================================================
839
841
  # App
840
842
  # =============================================================================
841
843
 
@@ -1036,7 +1038,7 @@ SYSTEM_USERS=
1036
1038
  SUPER_ADMIN_USERS=
1037
1039
  # Comma-separated admin user emails
1038
1040
  ADMIN_USERS=
1039
- `;var ho=`import { PostHogAnalytics } from "@ooneex/analytics";
1041
+ `;var yr=`import { PostHogAnalytics } from "@ooneex/analytics";
1040
1042
  import { App } from "@ooneex/app";
1041
1043
  import { RedisCache } from "@ooneex/cache";
1042
1044
  import { LogtailLogger, ExceptionLogger, TerminalLogger } from "@ooneex/logger";
@@ -1065,7 +1067,7 @@ const app = new App({
1065
1067
  });
1066
1068
 
1067
1069
  await app.run();
1068
- `;var fo=`{
1070
+ `;var gr=`{
1069
1071
  "$schema": "./node_modules/nx/schemas/nx-schema.json",
1070
1072
  "targetDefaults": {
1071
1073
  "build": {
@@ -1095,7 +1097,7 @@ await app.run();
1095
1097
  ],
1096
1098
  "packageManager": "bun"
1097
1099
  }
1098
- `;var yo=`{
1100
+ `;var br=`{
1099
1101
  "name": "{{NAME}}",
1100
1102
  "scripts": {
1101
1103
  "dev": "bun run --filter app dev",
@@ -1118,7 +1120,7 @@ await app.run();
1118
1120
  ]
1119
1121
  }
1120
1122
  }
1121
- `;var go=`# {{NAME}}
1123
+ `;var xr=`# {{NAME}}
1122
1124
 
1123
1125
  A modular, enterprise-grade backend framework built with TypeScript and Bun, powered by the **@ooneex** ecosystem.
1124
1126
 
@@ -1274,7 +1276,7 @@ This creates \`.claude/skills/\` in your project with skill guides for each \`ma
1274
1276
  ## License
1275
1277
 
1276
1278
  Proprietary - All rights reserved.
1277
- `;var bo=`{
1279
+ `;var wr=`{
1278
1280
  "compilerOptions": {
1279
1281
  "jsx": "react-jsx",
1280
1282
  "lib": ["ES2022", "DOM"],
@@ -1303,7 +1305,7 @@ Proprietary - All rights reserved.
1303
1305
  },
1304
1306
  "exclude": ["node_modules", ".github", ".husky", ".nx", ".zed", ".vscode"]
1305
1307
  }
1306
- `;var wo=`{
1308
+ `;var Er=`{
1307
1309
  "formatter": "language_server",
1308
1310
  "format_on_save": "on",
1309
1311
  "languages": {
@@ -1405,7 +1407,7 @@ Proprietary - All rights reserved.
1405
1407
  }
1406
1408
  }
1407
1409
  }
1408
- `;import{basename as nl,join as U}from"path";import{TerminalLogger as dl}from"@ooneex/logger";import{toKebabCase as ll,toPascalCase as Ue,trim as cl}from"@ooneex/utils";var xo=ee(ie(),1),he=async(e)=>{return(await xo.prompt({type:"confirm",name:"confirm",message:e.message})).confirm};var ve=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD"];var Eo=ee(ie(),1);import{Assert as Yd,Validation as zd}from"@ooneex/validation";class Ot extends zd{getConstraint(){return Yd("string >= 3")}getErrorMessage(){return`Route method must be one of: ${ve.join(", ")}`}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let r=e;if(r.trim()!==r)return{isValid:!1,message:this.getErrorMessage()||"Invalid route method format"};let o=r.toUpperCase();if(!ve.includes(o))return{isValid:!1,message:this.getErrorMessage()||"Invalid route method"};return{isValid:!0}}}var Ao=async(e)=>{return(await Eo.prompt({type:"select",name:"method",message:e.message,initial:e.initial??0,choices:ve.map((s)=>s),validate:(s)=>{let o=new Ot().validate(s);if(!o.isValid)return o.message||"Route method is invalid";return!0}})).method};var vo=ee(ie(),1);import{Assert as Zd,Validation as Qd}from"@ooneex/validation";var Xd=/^[a-zA-Z0-9]+\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/;class Dt extends Qd{getConstraint(){return Zd("string >= 7")}getErrorMessage(){return"Route name must follow format: namespace.resource.action (e.g., 'api.users.list')"}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let r=e;if(r.trim()!==r)return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};if(!Xd.test(r))return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};let o=r.split(".");if(o.length!==3)return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};let[i,a,n]=o;if(!i||!a||!n)return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};return{isValid:!0}}}var No=async(e)=>{return(await vo.prompt({type:"input",name:"routeName",message:e.message,validate:(s)=>{let o=new Dt().validate(s);if(!o.isValid)return o.message||"Route name is invalid";return!0}})).routeName};var So=ee(ie(),1);import{Assert as Jd,Validation as jd}from"@ooneex/validation";var el=1,tl=/^\/[\w\-/:]*$/,sl=/^[a-zA-Z0-9\-_]+$/,rl=/^:[a-zA-Z][a-zA-Z0-9]*$/;class Bt extends jd{getConstraint(){return Jd(`string >= ${el}`)}getErrorMessage(){return"Route path must start with '/' and contain only valid segments (e.g., '/users', '/api/users/:id')"}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let r=e;if(r.trim()!==r)return{isValid:!1,message:this.getErrorMessage()||"Invalid route path format"};if(!r.startsWith("/"))return{isValid:!1,message:"Route path must start with '/'"};if(r.length>1&&r.endsWith("/"))return{isValid:!1,message:"Route path cannot end with '/' (except for root path)"};if(!tl.test(r))return{isValid:!1,message:this.getErrorMessage()||"Invalid route path format"};if(r==="/")return{isValid:!0};let o=r.slice(1).split("/");for(let i of o){if(!i)return{isValid:!1,message:"Route path cannot contain empty segments (double slashes)"};if(i.startsWith(":")){if(!rl.test(i))return{isValid:!1,message:`Invalid parameter segment '${i}'. Parameters must follow format ':paramName' with alphanumeric characters only`}}else if(!sl.test(i))return{isValid:!1,message:`Invalid path segment '${i}'. Segments must contain only letters, numbers, hyphens, and underscores`}}return{isValid:!0}}}var To=async(e)=>{return(await So.prompt({type:"input",name:"path",message:e.message,initial:e.initial??"/",validate:(s)=>{let o=new Bt().validate(s);if(!o.isValid)return o.message||"Route path is invalid";return!0}})).path};var Ro=`import type { ContextType } from "@ooneex/socket";
1410
+ `;import{basename as vd,join as U}from"path";import{TerminalLogger as Ad}from"@ooneex/logger";import{toKebabCase as Td,toPascalCase as We,trim as Sd}from"@ooneex/utils";var vr=te(ae(),1),ge=async(e)=>{return(await vr.prompt({type:"confirm",name:"confirm",message:e.message})).confirm};var Ce=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD"];var Ar=te(ae(),1);import{Assert as ld,Validation as dd}from"@ooneex/validation";class Dt extends dd{getConstraint(){return ld("string >= 3")}getErrorMessage(){return`Route method must be one of: ${Ce.join(", ")}`}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let o=e;if(o.trim()!==o)return{isValid:!1,message:this.getErrorMessage()||"Invalid route method format"};let r=o.toUpperCase();if(!Ce.includes(r))return{isValid:!1,message:this.getErrorMessage()||"Invalid route method"};return{isValid:!0}}}var Tr=async(e)=>{return(await Ar.prompt({type:"select",name:"method",message:e.message,initial:e.initial??0,choices:Ce.map((s)=>s),validate:(s)=>{let r=new Dt().validate(s);if(!r.isValid)return r.message||"Route method is invalid";return!0}})).method};var Sr=te(ae(),1);import{Assert as pd,Validation as cd}from"@ooneex/validation";var md=/^[a-zA-Z0-9]+\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/;class Pt extends cd{getConstraint(){return pd("string >= 7")}getErrorMessage(){return"Route name must follow format: namespace.resource.action (e.g., 'api.users.list')"}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let o=e;if(o.trim()!==o)return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};if(!md.test(o))return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};let r=o.split(".");if(r.length!==3)return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};let[i,a,n]=r;if(!i||!a||!n)return{isValid:!1,message:this.getErrorMessage()||"Invalid route name format"};return{isValid:!0}}}var Nr=async(e)=>{return(await Sr.prompt({type:"input",name:"routeName",message:e.message,validate:(s)=>{let r=new Pt().validate(s);if(!r.isValid)return r.message||"Route name is invalid";return!0}})).routeName};var Rr=te(ae(),1);import{Assert as ud,Validation as hd}from"@ooneex/validation";var fd=1,yd=/^\/[\w\-/:]*$/,gd=/^[a-zA-Z0-9\-_]+$/,bd=/^:[a-zA-Z][a-zA-Z0-9]*$/;class Lt extends hd{getConstraint(){return ud(`string >= ${fd}`)}getErrorMessage(){return"Route path must start with '/' and contain only valid segments (e.g., '/users', '/api/users/:id')"}validate(e,t){let s=super.validate(e,t);if(!s.isValid)return s;let o=e;if(o.trim()!==o)return{isValid:!1,message:this.getErrorMessage()||"Invalid route path format"};if(!o.startsWith("/"))return{isValid:!1,message:"Route path must start with '/'"};if(o.length>1&&o.endsWith("/"))return{isValid:!1,message:"Route path cannot end with '/' (except for root path)"};if(!yd.test(o))return{isValid:!1,message:this.getErrorMessage()||"Invalid route path format"};if(o==="/")return{isValid:!0};let r=o.slice(1).split("/");for(let i of r){if(!i)return{isValid:!1,message:"Route path cannot contain empty segments (double slashes)"};if(i.startsWith(":")){if(!bd.test(i))return{isValid:!1,message:`Invalid parameter segment '${i}'. Parameters must follow format ':paramName' with alphanumeric characters only`}}else if(!gd.test(i))return{isValid:!1,message:`Invalid path segment '${i}'. Segments must contain only letters, numbers, hyphens, and underscores`}}return{isValid:!0}}}var Cr=async(e)=>{return(await Rr.prompt({type:"input",name:"path",message:e.message,initial:e.initial??"/",validate:(s)=>{let r=new Lt().validate(s);if(!r.isValid)return r.message||"Route path is invalid";return!0}})).path};var Mr=`import type { ContextType } from "@ooneex/socket";
1409
1411
  import { ERole } from "@ooneex/role";
1410
1412
  import { Route } from "@ooneex/routing";
1411
1413
  import { Assert } from "@ooneex/validation";
@@ -1452,7 +1454,7 @@ export class {{NAME}}Controller {
1452
1454
  });
1453
1455
  }
1454
1456
  }
1455
- `;var Mo=`import { describe, expect, test } from "bun:test";
1457
+ `;var _r=`import { describe, expect, test } from "bun:test";
1456
1458
  import { {{NAME}}Controller } from "@/controllers/{{NAME}}Controller";
1457
1459
 
1458
1460
  describe("{{NAME}}Controller", () => {
@@ -1465,7 +1467,7 @@ describe("{{NAME}}Controller", () => {
1465
1467
  expect(typeof {{NAME}}Controller.prototype.index).toBe("function");
1466
1468
  });
1467
1469
  });
1468
- `;var Co=`import type { ContextType } from "@ooneex/controller";
1470
+ `;var Br=`import type { ContextType } from "@ooneex/controller";
1469
1471
  import { ERole } from "@ooneex/role";
1470
1472
  import { Route } from "@ooneex/routing";
1471
1473
  import { Assert } from "@ooneex/validation";
@@ -1512,9 +1514,9 @@ export class {{NAME}}Controller {
1512
1514
  });
1513
1515
  }
1514
1516
  }
1515
- `;class fe{getName(){return"make:controller"}getDescription(){return"Generate a new controller class"}async addToModule(e,t){let s=await Bun.file(e).text(),r=`${t}Controller`,o=`import { ${r} } from "./controllers/${r}";
1517
+ `;class ne{getName(){return"make:controller"}getDescription(){return"Generate a new controller class"}async addToModule(e,t){let s=await Bun.file(e).text(),o=`${t}Controller`,r=`import { ${o} } from "./controllers/${o}";
1516
1518
  `,i=s.lastIndexOf("import "),a=s.indexOf(`
1517
- `,i);s=`${s.slice(0,a+1)}${o}${s.slice(a+1)}`;let n=/(controllers:\s*\[)([^\]]*)/s,d=s.match(n);if(d){let l=d[2]?.trim(),p=l?`${l}, ${r}`:r;s=s.replace(n,`$1${p}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,isSocket:r}=e;if(!t)t=await v({message:"Enter controller name"});if(r===void 0)r=await he({message:"Is this a socket controller?"});t=Ue(t).replace(/Controller$/,"");let{route:o={}}=e,a=(r?Ro:Co).replaceAll("{{NAME}}",t);if(!o.name)o.name=await No({message:"Enter route name (e.g., api.user.create)"});let n=Ue(o.name);if(a=a.replaceAll("{{ROUTE_NAME}}",o.name).replaceAll("{{TYPE_NAME}}",n),!o.path)o.path=await To({message:"Enter route path",initial:"/"});let d=`/${ll(cl(o.path,"/"))}`;if(a=a.replaceAll("{{ROUTE_PATH}}",d),!r&&!o.method)o.method=await Ao({message:"Enter route method"});if(!r&&o.method)a=a.replaceAll("{{ROUTE_METHOD}}",o.method.toLowerCase());let l=s?U("modules",s):".",p=U(l,"src","controllers"),u=U(process.cwd(),p),m=U(u,`${t}Controller.ts`);await Bun.write(m,a);let c=Mo.replace(/{{NAME}}/g,t),h=U(l,"tests","controllers"),f=U(process.cwd(),h),g=U(f,`${t}Controller.spec.ts`);await Bun.write(g,c);let y=s?Ue(s):Ue(nl(process.cwd())),E=U(process.cwd(),l,"src",`${y}Module.ts`);if(await Bun.file(E).exists())await this.addToModule(E,t);let A=new dl;A.success(`${U(p,t)}Controller.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),A.success(`${U(h,t)}Controller.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/controller"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}fe=b([w.command()],fe);import{join as B}from"path";import{TerminalLogger as fl}from"@ooneex/logger";import{toKebabCase as yl,toPascalCase as gl}from"@ooneex/utils";var _o=`import type { ModuleType } from "@ooneex/module";
1519
+ `,i);s=`${s.slice(0,a+1)}${r}${s.slice(a+1)}`;let n=/(controllers:\s*\[)([^\]]*)/s,l=s.match(n);if(l){let d=l[2]?.trim(),c=d?`${d}, ${o}`:o;s=s.replace(n,`$1${c}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,isSocket:o}=e;if(!t)t=await A({message:"Enter controller name"});if(o===void 0)o=await ge({message:"Is this a socket controller?"});t=We(t).replace(/Controller$/,"");let{route:r={}}=e,a=(o?Mr:Br).replaceAll("{{NAME}}",t);if(!r.name)r.name=await Nr({message:"Enter route name (e.g., api.user.create)"});let n=We(r.name);if(a=a.replaceAll("{{ROUTE_NAME}}",r.name).replaceAll("{{TYPE_NAME}}",n),!r.path)r.path=await Cr({message:"Enter route path",initial:"/"});let l=`/${Td(Sd(r.path,"/"))}`;if(a=a.replaceAll("{{ROUTE_PATH}}",l),!o&&!r.method)r.method=await Tr({message:"Enter route method"});if(!o&&r.method)a=a.replaceAll("{{ROUTE_METHOD}}",r.method.toLowerCase());let d=s?U("modules",s):".",c=U(d,"src","controllers"),u=U(process.cwd(),c),m=U(u,`${t}Controller.ts`);await Bun.write(m,a);let p=_r.replace(/{{NAME}}/g,t),h=U(d,"tests","controllers"),f=U(process.cwd(),h),g=U(f,`${t}Controller.spec.ts`);await Bun.write(g,p);let y=s?We(s):We(vd(process.cwd())),w=U(process.cwd(),d,"src",`${y}Module.ts`);if(await Bun.file(w).exists())await this.addToModule(w,t);let v=new Ad;v.success(`${U(c,t)}Controller.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),v.success(`${U(h,t)}Controller.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/controller"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}ne=b([x.command()],ne);import{join as P}from"path";import{TerminalLogger as _d}from"@ooneex/logger";import{toKebabCase as Bd,toPascalCase as Id}from"@ooneex/utils";var Ir=`import type { ModuleType } from "@ooneex/module";
1518
1520
 
1519
1521
  export const {{NAME}}Module: ModuleType = {
1520
1522
  controllers: [],
@@ -1523,7 +1525,7 @@ export const {{NAME}}Module: ModuleType = {
1523
1525
  cronJobs: [],
1524
1526
  events: [],
1525
1527
  };
1526
- `;var Io=`{
1528
+ `;var Or=`{
1527
1529
  "name": "@module/{{NAME}}",
1528
1530
  "description": "",
1529
1531
  "version": "0.0.1",
@@ -1532,7 +1534,7 @@ export const {{NAME}}Module: ModuleType = {
1532
1534
  "lint": "tsgo --noEmit && bunx biome lint"
1533
1535
  }
1534
1536
  }
1535
- `;var Oo=`import { describe, expect, test } from "bun:test";
1537
+ `;var Dr=`import { describe, expect, test } from "bun:test";
1536
1538
  import { {{NAME}}Module } from "@/{{NAME}}Module";
1537
1539
 
1538
1540
  describe("{{NAME}}Module", () => {
@@ -1556,7 +1558,7 @@ describe("{{NAME}}Module", () => {
1556
1558
  expect(Array.isArray({{NAME}}Module.events)).toBe(true);
1557
1559
  });
1558
1560
  });
1559
- `;var Do=`{
1561
+ `;var Pr=`{
1560
1562
  "extends": "../../tsconfig.json",
1561
1563
  "compilerOptions": {
1562
1564
  "types": ["@types/bun"],
@@ -1567,13 +1569,13 @@ describe("{{NAME}}Module", () => {
1567
1569
  "include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx"],
1568
1570
  "exclude": ["node_modules", "dist"]
1569
1571
  }
1570
- `;class ye{getName(){return"make:module"}getDescription(){return"Generate a new module"}async addToAppModule(e,t,s){let r=await Bun.file(e).text(),o=`${t}Module`,i=`@${s}/${o}`,a=`import { ${o} } from "${i}";
1571
- `,n=r.lastIndexOf("import "),d=r.indexOf(`
1572
- `,n);r=`${r.slice(0,d+1)}${a}${r.slice(d+1)}`;let l=["controllers","entities","middlewares","cronJobs","events"];for(let p of l){let u=new RegExp(`(${p}:\\s*\\[)([^\\]]*)`,"s"),m=r.match(u);if(m){let c=m[2]?.trim(),h=`...${o}.${p}`,f=c?`${c}, ${h}`:h;r=r.replace(u,`$1${f}`)}}await Bun.write(e,r)}async addModuleScope(e,t){let s=await Bun.file(e).text(),r=/("scope-enum":\s*\[\s*RuleConfigSeverity\.Error,\s*"always",\s*\[)([\s\S]*?)(\])/,o=s.match(r);if(o){let i=o[2]?.trim()??"",a=`"${t}"`;if(!i.includes(a)){let n=i?`${i}
1572
+ `;class le{getName(){return"make:module"}getDescription(){return"Generate a new module"}async addToAppModule(e,t,s){let o=await Bun.file(e).text(),r=`${t}Module`,i=`@${s}/${r}`,a=`import { ${r} } from "${i}";
1573
+ `,n=o.lastIndexOf("import "),l=o.indexOf(`
1574
+ `,n);o=`${o.slice(0,l+1)}${a}${o.slice(l+1)}`;let d=["controllers","entities","middlewares","cronJobs","events"];for(let c of d){let u=new RegExp(`(${c}:\\s*\\[)([^\\]]*)`,"s"),m=o.match(u);if(m){let p=m[2]?.trim(),h=`...${r}.${c}`,f=p?`${p}, ${h}`:h;o=o.replace(u,`$1${f}`)}}await Bun.write(e,o)}async addModuleScope(e,t){let s=await Bun.file(e).text(),o=/("scope-enum":\s*\[\s*RuleConfigSeverity\.Error,\s*"always",\s*\[)([\s\S]*?)(\])/,r=s.match(o);if(r){let i=r[2]?.trim()??"",a=`"${t}"`;if(!i.includes(a)){let n=i?`${i}
1573
1575
  ${a},`:`
1574
- ${a},`;s=s.replace(r,`$1${n}
1575
- $3`),await Bun.write(e,s)}}}async addPathAlias(e,t){let s=await Bun.file(e).text(),r=JSON.parse(s);r.compilerOptions??={},r.compilerOptions.paths??={},r.compilerOptions.paths[`@${t}/*`]=[`../${t}/src/*`],await Bun.write(e,`${JSON.stringify(r,null,2)}
1576
- `)}async run(e){let{cwd:t=process.cwd(),silent:s=!1,skipMigrations:r=!1,skipSeeds:o=!1}=e,{name:i}=e;if(!i)i=await v({message:"Enter module name"});let a=gl(i).replace(/Module$/,""),n=yl(a),d=B(t,"modules",n),l=B(d,"src"),p=B(d,"tests"),u=_o.replace(/{{NAME}}/g,a),m=Io.replace(/{{NAME}}/g,n),c=Oo.replace(/{{NAME}}/g,a);if(await Bun.write(B(l,`${a}Module.ts`),u),!r)await Bun.write(B(l,"migrations","migrations.ts"),"");if(!o)await Bun.write(B(l,"seeds","seeds.ts"),"");if(await Bun.write(B(d,"package.json"),m),await Bun.write(B(d,"tsconfig.json"),Do),await Bun.write(B(p,`${a}Module.spec.ts`),c),n!=="app"){let g=B(t,"modules","app","src","AppModule.ts");if(await Bun.file(g).exists())await this.addToAppModule(g,a,n);let y=B(t,"modules","app","tsconfig.json");if(await Bun.file(y).exists())await this.addPathAlias(y,n)}let h=B(t,".commitlintrc.ts");if(await Bun.file(h).exists())await this.addModuleScope(h,n);if(!s)new fl().success(`modules/${n} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0});await Bun.spawn(["bun","add","@ooneex/module"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}ye=b([w.command()],ye);class Ge{getName(){return"make:app"}getDescription(){return"Generate a new application"}async run(e){let{name:t,destination:s}=e;if(!t)t=await v({message:"Enter application name"});let r=wl(t);if(!s)s=await io({message:"Enter destination path",initial:r});let o=yo.replace(/{{NAME}}/g,r);await Bun.write(T(s,".commitlintrc.ts"),ao),await Bun.write(T(s,".gitignore"),no),await Bun.write(T(s,"biome.jsonc"),co),await Bun.write(T(s,"bunfig.toml"),po),await Bun.write(T(s,"nx.json"),fo),await Bun.write(T(s,"package.json"),o),await Bun.write(T(s,"README.md"),go.replace(/{{NAME}}/g,r)),await Bun.write(T(s,"tsconfig.json"),bo),await Bun.write(T(s,".zed","settings.json"),wo),await new ye().run({name:"app",cwd:s,silent:!0,skipMigrations:!0,skipSeeds:!0});let a=T(s,"modules","app","package.json"),n=await Bun.file(a).json();n.scripts.dev="docker compose up -d && bun --hot run ./src/index.ts",n.scripts.build="bun build ./src/index.ts --outdir ./dist --target bun",await Bun.write(a,JSON.stringify(n,null,2));let d=It.replace(/^DATABASE_URL=/m,'DATABASE_URL="postgresql://ooneex:ooneex@localhost:5432/ooneex"').replace(/^CACHE_REDIS_URL=/m,'CACHE_REDIS_URL="redis://localhost:6379"').replace(/^PUBSUB_REDIS_URL=/m,'PUBSUB_REDIS_URL="redis://localhost:6379"').replace(/^RATE_LIMIT_REDIS_URL=/m,'RATE_LIMIT_REDIS_URL="redis://localhost:6379"').replace(/^DATABASE_REDIS_URL=/m,'DATABASE_REDIS_URL="redis://localhost:6379"');await Bun.write(T(s,"modules","app",".env"),d),await Bun.write(T(s,"modules","app",".env.example"),It),await Bun.write(T(s,"modules","app","src","databases","AppDatabase.ts"),lo),await Bun.write(T(s,"modules","app","src","index.ts"),ho);let l=xl(t),p=uo.replace(/{{NAME}}/g,l);await Bun.write(T(s,"modules","app","docker-compose.yml"),p);let u=mo.replace(/{{NAME}}/g,l);await Bun.write(T(s,"modules","app","Dockerfile"),u),await Bun.write(T(s,"modules","app","var",".gitkeep"),""),await new fe().run({name:"HealthCheck",isSocket:!1,module:"app",route:{name:"api.health.check",path:"/healthcheck",method:"GET"}}),await Bun.spawn(["git","init"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.spawn(["bun","add","@ooneex/analytics","@ooneex/app","@ooneex/app-env","@ooneex/auth","@ooneex/cache","@ooneex/container","@ooneex/database","@ooneex/logger","@ooneex/mailer","@ooneex/middleware","@ooneex/module","@ooneex/rate-limit","@ooneex/role","@ooneex/routing","@ooneex/storage","@ooneex/translation","@ooneex/types","@ooneex/user","@ooneex/utils","@ooneex/validation","@ooneex/controller","pg","apache-arrow","reflect-metadata","typeorm"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.spawn(["bun","add","-D","@biomejs/biome","@commitlint/cli","@commitlint/config-conventional","@commitlint/prompt-cli","@commitlint/types","@nx/js","@nx/workspace","@swc-node/register","@swc/core","@swc/helpers","@types/bun","@types/node","@typescript/native-preview","husky","lint-staged","nx","typescript","undici-types"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.spawn(["bunx","husky","init"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.write(T(s,".husky","pre-commit"),"lint-staged"),await Bun.write(T(s,".husky","commit-msg"),'bunx commitlint --edit "$1"'),new bl().success(`${r} created successfully at ${s}`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}Ge=b([w.command()],Ge);import{join as V}from"path";import{TerminalLogger as vl}from"@ooneex/logger";import{toPascalCase as Nl}from"@ooneex/utils";var Bo=`import { describe, expect, test } from "bun:test";
1576
+ ${a},`;s=s.replace(o,`$1${n}
1577
+ $3`),await Bun.write(e,s)}}}async addPathAlias(e,t){let s=await Bun.file(e).text(),o=JSON.parse(s);o.compilerOptions??={},o.compilerOptions.paths??={},o.compilerOptions.paths[`@${t}/*`]=[`../${t}/src/*`],await Bun.write(e,`${JSON.stringify(o,null,2)}
1578
+ `)}async run(e){let{cwd:t=process.cwd(),silent:s=!1,skipMigrations:o=!1,skipSeeds:r=!1}=e,{name:i}=e;if(!i)i=await A({message:"Enter module name"});let a=Id(i).replace(/Module$/,""),n=Bd(a),l=P(t,"modules",n),d=P(l,"src"),c=P(l,"tests"),u=Ir.replace(/{{NAME}}/g,a),m=Or.replace(/{{NAME}}/g,n),p=Dr.replace(/{{NAME}}/g,a);if(await Bun.write(P(d,`${a}Module.ts`),u),!o)await Bun.write(P(d,"migrations","migrations.ts"),"");if(!r)await Bun.write(P(d,"seeds","seeds.ts"),"");if(await Bun.write(P(l,"package.json"),m),await Bun.write(P(l,"tsconfig.json"),Pr),await Bun.write(P(c,`${a}Module.spec.ts`),p),n!=="app"){let g=P(t,"modules","app","src","AppModule.ts");if(await Bun.file(g).exists())await this.addToAppModule(g,a,n);let y=P(t,"modules","app","tsconfig.json");if(await Bun.file(y).exists())await this.addPathAlias(y,n)}let h=P(t,".commitlintrc.ts");if(await Bun.file(h).exists())await this.addModuleScope(h,n);if(!s)new _d().success(`modules/${n} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0});await Bun.spawn(["bun","add","@ooneex/module"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}le=b([x.command()],le);class Fe{getName(){return"make:app"}getDescription(){return"Generate a new application"}async run(e){let{name:t,destination:s}=e;if(!t)t=await A({message:"Enter application name"});let o=Dd(t);if(!s)s=await lr({message:"Enter destination path",initial:o});let r=br.replace(/{{NAME}}/g,o);await Bun.write(N(s,".commitlintrc.ts"),dr),await Bun.write(N(s,".gitignore"),pr),await Bun.write(N(s,"biome.jsonc"),mr),await Bun.write(N(s,"bunfig.toml"),ur),await Bun.write(N(s,"nx.json"),gr),await Bun.write(N(s,"package.json"),r),await Bun.write(N(s,"README.md"),xr.replace(/{{NAME}}/g,o)),await Bun.write(N(s,"tsconfig.json"),wr),await Bun.write(N(s,".zed","settings.json"),Er),await new le().run({name:"app",cwd:s,silent:!0,skipMigrations:!0,skipSeeds:!0});let a=N(s,"modules","app","package.json"),n=await Bun.file(a).json();n.scripts.dev="docker compose up -d && bun --hot run ./src/index.ts",n.scripts.build="bun build ./src/index.ts --outdir ./dist --target bun",await Bun.write(a,JSON.stringify(n,null,2));let l=Ot.replace(/^DATABASE_URL=/m,'DATABASE_URL="postgresql://ooneex:ooneex@localhost:5432/ooneex"').replace(/^CACHE_REDIS_URL=/m,'CACHE_REDIS_URL="redis://localhost:6379"').replace(/^PUBSUB_REDIS_URL=/m,'PUBSUB_REDIS_URL="redis://localhost:6379"').replace(/^RATE_LIMIT_REDIS_URL=/m,'RATE_LIMIT_REDIS_URL="redis://localhost:6379"').replace(/^DATABASE_REDIS_URL=/m,'DATABASE_REDIS_URL="redis://localhost:6379"');await Bun.write(N(s,"modules","app",".env"),l),await Bun.write(N(s,"modules","app",".env.example"),Ot),await Bun.write(N(s,"modules","app","src","databases","AppDatabase.ts"),cr),await Bun.write(N(s,"modules","app","src","index.ts"),yr);let d=Pd(t),c=fr.replace(/{{NAME}}/g,d);await Bun.write(N(s,"modules","app","docker-compose.yml"),c);let u=hr.replace(/{{NAME}}/g,d);await Bun.write(N(s,"modules","app","Dockerfile"),u),await Bun.write(N(s,"modules","app","var",".gitkeep"),""),await new ne().run({name:"HealthCheck",isSocket:!1,module:"app",route:{name:"api.health.check",path:"/healthcheck",method:"GET"}}),await Bun.spawn(["git","init"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.spawn(["bun","add","@ooneex/analytics","@ooneex/app","@ooneex/app-env","@ooneex/auth","@ooneex/cache","@ooneex/container","@ooneex/database","@ooneex/logger","@ooneex/mailer","@ooneex/middleware","@ooneex/module","@ooneex/rate-limit","@ooneex/role","@ooneex/routing","@ooneex/storage","@ooneex/translation","@ooneex/types","@ooneex/user","@ooneex/utils","@ooneex/validation","@ooneex/controller","pg","apache-arrow","reflect-metadata","typeorm"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.spawn(["bun","add","-D","@biomejs/biome","@commitlint/cli","@commitlint/config-conventional","@commitlint/prompt-cli","@commitlint/types","@nx/js","@nx/workspace","@swc-node/register","@swc/core","@swc/helpers","@types/bun","@types/node","@typescript/native-preview","husky","lint-staged","nx","typescript","undici-types"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.spawn(["bunx","husky","init"],{cwd:s,stdout:"ignore",stderr:"inherit"}).exited,await Bun.write(N(s,".husky","pre-commit"),"lint-staged"),await Bun.write(N(s,".husky","commit-msg"),'bunx commitlint --edit "$1"'),new Od().success(`${o} created successfully at ${s}`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}Fe=b([x.command()],Fe);import{join as z}from"path";import{TerminalLogger as Ud}from"@ooneex/logger";import{toPascalCase as Gd}from"@ooneex/utils";var Lr=`import { describe, expect, test } from "bun:test";
1577
1579
  import { {{NAME}}Cache } from "@/cache/{{NAME}}Cache";
1578
1580
 
1579
1581
  describe("{{NAME}}Cache", () => {
@@ -1601,7 +1603,7 @@ describe("{{NAME}}Cache", () => {
1601
1603
  expect(typeof {{NAME}}Cache.prototype.has).toBe("function");
1602
1604
  });
1603
1605
  });
1604
- `;var Po=`import { CacheException, decorator } from "@ooneex/cache";
1606
+ `;var kr=`import { CacheException, decorator } from "@ooneex/cache";
1605
1607
  import type { ICache } from "@ooneex/cache";
1606
1608
 
1607
1609
  @decorator.cache()
@@ -1622,7 +1624,7 @@ export class {{NAME}}Cache implements ICache {
1622
1624
  throw new CacheException(\`Failed to check if key "\${key}" exists: Not implemented\`);
1623
1625
  }
1624
1626
  }
1625
- `;class ke{getName(){return"make:cache"}getDescription(){return"Generate a new cache class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter cache name"});t=Nl(t).replace(/Cache$/,"");let r=Po.replace(/{{NAME}}/g,t),o=s?V("modules",s):".",i=V(o,"src","cache"),a=V(process.cwd(),i),n=V(a,`${t}Cache.ts`);await Bun.write(n,r);let d=Bo.replace(/{{NAME}}/g,t),l=V(o,"tests","cache"),p=V(process.cwd(),l),u=V(p,`${t}Cache.spec.ts`);await Bun.write(u,d);let m=new vl;m.success(`${V(i,t)}Cache.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${V(l,t)}Cache.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/cache"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}ke=b([w.command()],ke);import{join as $e}from"path";import{TerminalLogger as Hl}from"@ooneex/logger";var Lo=`---
1627
+ `;class Ke{getName(){return"make:cache"}getDescription(){return"Generate a new cache class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter cache name"});t=Gd(t).replace(/Cache$/,"");let o=kr.replace(/{{NAME}}/g,t),r=s?z("modules",s):".",i=z(r,"src","cache"),a=z(process.cwd(),i),n=z(a,`${t}Cache.ts`);await Bun.write(n,o);let l=Lr.replace(/{{NAME}}/g,t),d=z(r,"tests","cache"),c=z(process.cwd(),d),u=z(c,`${t}Cache.spec.ts`);await Bun.write(u,l);let m=new Ud;m.success(`${z(i,t)}Cache.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${z(d,t)}Cache.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/cache"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ke=b([x.command()],Ke);import{join as He}from"path";import{TerminalLogger as ap}from"@ooneex/logger";var Ur=`---
1626
1628
  name: commit
1627
1629
  description: Create commit messages grouped by module. Analyzes git changes, groups files under modules/ by module name, and creates separate commits following commitlint conventions. Uses common scope for non-module changes.
1628
1630
  ---
@@ -1815,7 +1817,7 @@ Use \`refactor\` for file reorganization:
1815
1817
  git add modules/product/
1816
1818
  git commit -m "refactor(product): Reorganize service file structure"
1817
1819
  \`\`\`
1818
- `;var Uo="---\nname: make:ai\ndescription: Generate a new AI class with its test file, then complete the generated code. Use when creating a new AI chat class that uses OpenAI via the @ooneex/ai package.\n---\n\n# Make AI Class\n\nGenerate a new AI class and its test file using the `make:ai` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the AI class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:ai --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/ai/<Name>Ai.ts` - The AI class file (or `modules/<module>/src/ai/<Name>Ai.ts` with `--module`)\n- `tests/ai/<Name>Ai.spec.ts` - The test file (or `modules/<module>/tests/ai/<Name>Ai.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the AI class\n\nEdit `src/ai/<Name>Ai.ts` to complete the implementation:\n\n- Update the prompt in the `run` method from `\"My prompt\"` to a meaningful prompt based on the class purpose\n- Update the prompt in the `runStream` method from `\"My prompt\"` to a meaningful prompt based on the class purpose\n- Add any additional configuration or methods relevant to the AI class purpose\n- Ensure proper typing for the `run<T>()` generic return type\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator, type IAiChat, OpenAi, type OpenAiConfigType } from \"@ooneex/ai\";\nimport { inject } from \"@ooneex/container\";\n\n@decorator.ai()\nexport class <Name>Ai implements IAiChat<OpenAiConfigType> {\n constructor(@inject(OpenAi) private readonly ai: OpenAi) {}\n\n public async run<T>(prompt?: string, config?: Omit<OpenAiConfigType, \"prompt\">): Promise<T> {\n return this.ai.run<T>(prompt || \"My prompt\", config);\n }\n\n public async *runStream(\n prompt?: string,\n config?: Omit<OpenAiConfigType, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n yield* this.ai.runStream(prompt || \"My prompt\", config);\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/ai/<Name>Ai.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, run method, runStream method)\n- Add tests relevant to the specific AI class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Ai } from \"@/ai/<Name>Ai\";\n\ndescribe(\"<Name>Ai\", () => {\n test(\"should have class name ending with 'Ai'\", () => {\n expect(<Name>Ai.name.endsWith(\"Ai\")).toBe(true);\n });\n\n test(\"should have 'run' method\", () => {\n expect(<Name>Ai.prototype.run).toBeDefined();\n expect(typeof <Name>Ai.prototype.run).toBe(\"function\");\n });\n\n test(\"should have 'runStream' method\", () => {\n expect(<Name>Ai.prototype.runStream).toBeDefined();\n expect(typeof <Name>Ai.prototype.runStream).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/ai/<Name>Ai.ts tests/ai/<Name>Ai.spec.ts\n```\n";var Go="---\nname: make:analytics\ndescription: Generate a new analytics class with its test file, then complete the generated code. Use when creating a new analytics tracking class that uses the @ooneex/analytics package.\n---\n\n# Make Analytics Class\n\nGenerate a new analytics class and its test file using the `make:analytics` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the analytics class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:analytics --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/analytics/<Name>Analytics.ts` - The analytics class file (or `modules/<module>/src/analytics/<Name>Analytics.ts` with `--module`)\n- `tests/analytics/<Name>Analytics.spec.ts` - The test file (or `modules/<module>/tests/analytics/<Name>Analytics.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the analytics class\n\nEdit `src/analytics/<Name>Analytics.ts` to complete the implementation:\n\n- Implement the `capture` method with actual analytics tracking logic\n- Define a proper type for `CaptureOptionsType` instead of `Record<string, unknown>` based on the analytics purpose\n- Add any additional methods or properties relevant to the analytics class purpose\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator } from \"@ooneex/analytics\";\nimport type { IAnalytics } from \"@ooneex/analytics\";\n\ntype CaptureOptionsType = Record<string, unknown>;\n\n@decorator.analytics()\nexport class <Name>Analytics<T extends CaptureOptionsType = CaptureOptionsType> implements IAnalytics<T> {\n public capture(options: T): void {\n // console.log(\"Analytics captured:\", options);\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/analytics/<Name>Analytics.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, capture method)\n- Add tests relevant to the specific analytics class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Analytics } from \"@/analytics/<Name>Analytics\";\n\ndescribe(\"<Name>Analytics\", () => {\n test(\"should have class name ending with 'Analytics'\", () => {\n expect(<Name>Analytics.name.endsWith(\"Analytics\")).toBe(true);\n });\n\n test(\"should have 'capture' method\", () => {\n expect(<Name>Analytics.prototype.capture).toBeDefined();\n expect(typeof <Name>Analytics.prototype.capture).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/analytics/<Name>Analytics.ts tests/analytics/<Name>Analytics.spec.ts\n```\n";var ko="---\nname: make:cache\ndescription: Generate a new cache adapter class with its test file, then complete the generated code. Use when creating a new cache adapter that implements the ICache interface from @ooneex/cache.\n---\n\n# Make Cache Class\n\nGenerate a new cache class and its test file using the `make:cache` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the cache class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:cache --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/cache/<Name>Cache.ts` - The cache class file (or `modules/<module>/src/cache/<Name>Cache.ts` with `--module`)\n- `tests/cache/<Name>Cache.spec.ts` - The test file (or `modules/<module>/tests/cache/<Name>Cache.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the cache class\n\nEdit `src/cache/<Name>Cache.ts` to complete the implementation:\n\n- Implement the `get` method to retrieve cached values by key\n- Implement the `set` method to store values with optional TTL\n- Implement the `delete` method to remove cached entries\n- Implement the `has` method to check key existence\n- Replace the `CacheException` throws with actual cache logic\n- Inject any required dependencies (e.g., Redis client) via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { CacheException, decorator } from \"@ooneex/cache\";\nimport type { ICache } from \"@ooneex/cache\";\n\n@decorator.cache()\nexport class <Name>Cache implements ICache {\n public async get<T = unknown>(key: string): Promise<T | undefined> {\n throw new CacheException(`Failed to get key \"${key}\": Not implemented`);\n }\n\n public async set<T = unknown>(key: string, value: T, ttl?: number): Promise<void> {\n throw new CacheException(`Failed to set key \"${key}\": Not implemented`);\n }\n\n public async delete(key: string): Promise<boolean> {\n throw new CacheException(`Failed to delete key \"${key}\": Not implemented`);\n }\n\n public async has(key: string): Promise<boolean> {\n throw new CacheException(`Failed to check if key \"${key}\" exists: Not implemented`);\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/cache/<Name>Cache.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, get, set, delete, has methods)\n- Add tests relevant to the specific cache class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Cache } from \"@/cache/<Name>Cache\";\n\ndescribe(\"<Name>Cache\", () => {\n test(\"should have class name ending with 'Cache'\", () => {\n expect(<Name>Cache.name.endsWith(\"Cache\")).toBe(true);\n });\n\n test(\"should have 'get' method\", () => {\n expect(<Name>Cache.prototype.get).toBeDefined();\n expect(typeof <Name>Cache.prototype.get).toBe(\"function\");\n });\n\n test(\"should have 'set' method\", () => {\n expect(<Name>Cache.prototype.set).toBeDefined();\n expect(typeof <Name>Cache.prototype.set).toBe(\"function\");\n });\n\n test(\"should have 'delete' method\", () => {\n expect(<Name>Cache.prototype.delete).toBeDefined();\n expect(typeof <Name>Cache.prototype.delete).toBe(\"function\");\n });\n\n test(\"should have 'has' method\", () => {\n expect(<Name>Cache.prototype.has).toBeDefined();\n expect(typeof <Name>Cache.prototype.has).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/cache/<Name>Cache.ts tests/cache/<Name>Cache.spec.ts\n```\n";var $o="---\nname: make:controller\ndescription: Generate a new controller class with route type and test file, then complete the generated code. Use when creating a new HTTP or WebSocket controller with routing, validation, and role-based access.\n---\n\n# Make Controller Class\n\nGenerate a new controller class, its route type, and test file using the `make:controller` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the controller class and related files:\n\n```bash\nbunx @ooneex/cli@latest make:controller --name <name> --module <module> --is-socket <true|false> --route.name <route.name> --route.path <route.path> --route.method <route.method>\n```\n\nWhere:\n- `<name>` is the controller name provided by the user\n- `--module` is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root\n- `--is-socket` determines HTTP vs WebSocket controller (defaults to `false`)\n- `--route.name` is the route name using dot notation: `<resource>.<action>` (e.g., `user.create`, `book.list`, `flashcard.delete`)\n- `--route.path` is the route path (e.g., `/api/users`)\n- `--route.method` is the HTTP method (e.g., `get`, `post`, `put`, `patch`, `delete`) \u2014 only for HTTP controllers\n\nThe command will generate (paths prefixed with `modules/<module>/` when `--module` is provided):\n- `src/controllers/<Name>Controller.ts` - The controller class file\n- `src/types/routes/<route.name>.ts` - The route type file (will be moved into the controller file \u2014 see step 3)\n- `tests/controllers/<Name>Controller.spec.ts` - The test file\n\n### 2. Read the generated files\n\nRead all three generated files to understand the scaffolded code.\n\n### 3. Complete the route type\n\n**IMPORTANT: Keep the route type inside the controller file**, not in a separate type file. Define the type directly in `src/controllers/<Name>Controller.ts` above the class definition. Delete the generated `src/types/routes/<route.name>.ts` file if it was created.\n\n**Remove unnecessary `params`, `payload`, and `queries` \u2014 only include what the route actually needs:**\n\n- **`params`** \u2014 Include only when the route path contains dynamic segments (e.g., `/api/users/:id`). Remove entirely for routes with no URL parameters (e.g., `/api/users`).\n- **`payload`** \u2014 Include only for methods that accept a request body (`post`, `put`, `patch`). Remove entirely for `get` and `delete` routes.\n- **`queries`** \u2014 Include only when the route supports query string filtering, pagination, or sorting (e.g., list/search endpoints). Remove entirely when not needed.\n- **`response`** \u2014 Always include.\n\nThe route type structure follows this pattern (remove unused sections):\n\n```typescript\n// Example: GET /api/users (list) \u2014 no params, no payload, has queries\ntype <TypeName>RouteType = {\n queries: {\n\n },\n response: {\n\n },\n};\n\n// Example: POST /api/users (create) \u2014 no params, has payload, no queries\ntype <TypeName>RouteType = {\n payload: {\n\n },\n response: {\n\n },\n};\n\n// Example: GET /api/users/:id (detail) \u2014 has params, no payload, no queries\ntype <TypeName>RouteType = {\n params: {\n\n },\n response: {\n\n },\n};\n\n// Example: PUT /api/users/:id (update) \u2014 has params, has payload, no queries\ntype <TypeName>RouteType = {\n params: {\n\n },\n payload: {\n\n },\n response: {\n\n },\n};\n```\n\n### 4. Complete the controller class\n\nEdit `src/controllers/<Name>Controller.ts` to complete the implementation:\n\n- Set appropriate `roles` for access control\n- Add a meaningful `description` for the route that explains what the endpoint does (e.g., `\"Create a new user account\"`, `\"List all books with pagination\"`)\n- **Keep the controller thin** \u2014 do NOT put business logic in the controller. Put all logic in the corresponding service and inject the service into the controller via the constructor. The controller's `index` method should only delegate to the service.\n- **Remove unnecessary `params`, `payload`, and `queries`** from both the route type and the `@Route` decorator \u2014 only include what the route actually needs (see step 3 rules).\n\n**Add or remove `params`, `payload`, and `queries` in the `@Route` decorator to match the route type (step 3):**\n\n- **`params`** \u2014 Include with `Assert()` validators only when the route has URL parameters. Remove the `params` key entirely otherwise.\n- **`payload`** \u2014 Include with `Assert({...})` only for `post`, `put`, `patch` methods. Remove the `payload` key entirely for `get` and `delete`.\n- **`queries`** \u2014 Include with `Assert({...})` only when query parameters are expected. Remove the `queries` key entirely otherwise.\n- **`response`** \u2014 Always include with `Assert({...})`.\n\n**HTTP controller** generated structure (remove `params`, `payload`, `queries` as needed \u2014 see rules above):\n\n```typescript\nimport type { ContextType } from \"@ooneex/controller\";\nimport { ERole } from \"@ooneex/role\";\nimport { Route } from \"@ooneex/routing\";\nimport { Assert } from \"@ooneex/validation\";\n\ntype <TypeName>RouteType = {\n // Only include params, payload, queries as needed (see step 3)\n response: {\n\n },\n};\n\n@Route.<method>(\"<route.path>\", {\n name: \"<route.name>\",\n version: 1,\n description: \"\",\n // Only include params, payload, queries as needed (see step 3)\n response: Assert({\n\n }),\n roles: [ERole.USER],\n})\nexport class <Name>Controller {\n public async index(context: ContextType<<TypeName>RouteType>) {\n return context.response.json({\n\n });\n }\n}\n```\n\n**Socket controller** generated structure (remove `params`, `payload`, `queries` as needed \u2014 see rules above):\n\n```typescript\nimport type { ContextType } from \"@ooneex/socket\";\nimport { ERole } from \"@ooneex/role\";\nimport { Route } from \"@ooneex/routing\";\nimport { Assert } from \"@ooneex/validation\";\n\ntype <TypeName>RouteType = {\n // Only include params, payload, queries as needed (see step 3)\n response: {\n\n },\n};\n\n@Route.socket(\"<route.path>\", {\n name: \"<route.name>\",\n version: 1,\n description: \"\",\n // Only include params, payload, queries as needed (see step 3)\n response: Assert({\n\n }),\n roles: [ERole.USER],\n})\nexport class <Name>Controller {\n public async index(context: ContextType<<TypeName>RouteType>) {\n return context.response.json({\n\n });\n }\n}\n```\n\n### 5. Complete the test file\n\nEdit `tests/controllers/<Name>Controller.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, index method)\n- Add tests relevant to the specific controller behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Controller } from \"@/controllers/<Name>Controller\";\n\ndescribe(\"<Name>Controller\", () => {\n test(\"should have class name ending with 'Controller'\", () => {\n expect(<Name>Controller.name.endsWith(\"Controller\")).toBe(true);\n });\n\n test(\"should have 'index' method\", () => {\n expect(<Name>Controller.prototype.index).toBeDefined();\n expect(typeof <Name>Controller.prototype.index).toBe(\"function\");\n });\n});\n```\n\n### 6. Register the controller in the module\n\nAdd the new controller to the module's `controllers` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Controller } from \"./controllers/<Name>Controller\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [<Name>Controller],\n entities: [],\n permissions: [],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other controllers registered, append the new controller to the existing `controllers` array and add the import alongside existing imports.\n\n### 7. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/controllers/<Name>Controller.ts tests/controllers/<Name>Controller.spec.ts\n```\n\n### 8. Create the service\n\nAfter the controller is created, generate a service class for the controller's business logic using the `make:service` skill:\n\n```\n/make:service --name <Name>\n```\n\nWhere `<Name>` matches the controller name (e.g., if the controller is `CreateUserController`, the service is `CreateUserService`).\n\n### 9. Create the pubsub event\n\nAfter the service is created, generate a pubsub event class for the controller's domain events using the `make:pubsub` skill:\n\n```\n/make:pubsub --name <Name> --channel <resource>.<action>\n```\n\nWhere:\n- `<Name>` matches the controller name (e.g., if the controller is `CreateUserController`, the event is `CreateUserEvent`)\n- `<resource>.<action>` follows the same dot notation as the route name (e.g., `user.create`, `book.delete`)\n\nOnce the event is created:\n- Inject the **service** into the **event** via the constructor, and call the service's `execute` method from the event's `handler` method.\n- Inject the **event** into the **controller** via the constructor, and publish the event from the controller's `index` method.\n";var qo="---\nname: make:cron\ndescription: Generate a new cron job class with its test file, then complete the generated code. Use when creating a new scheduled task that extends the Cron base class from @ooneex/cron.\n---\n\n# Make Cron Class\n\nGenerate a new cron class and its test file using the `make:cron` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the cron class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:cron --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/cron/<Name>Cron.ts` - The cron class file (or `modules/<module>/src/cron/<Name>Cron.ts` with `--module`)\n- `tests/cron/<Name>Cron.spec.ts` - The test file (or `modules/<module>/tests/cron/<Name>Cron.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the cron class\n\nEdit `src/cron/<Name>Cron.ts` to complete the implementation:\n\n- Set the appropriate cron schedule in `getTime()` (e.g., `\"every 5 minutes\"`, `\"every 1 hours\"`, `\"every 30 seconds\"`)\n- Set the timezone in `getTimeZone()` if needed, or keep `null` for server timezone\n- Implement the `handler()` method with the actual cron job logic\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { TimeZoneType } from \"@ooneex/country\";\nimport type { CronTimeType } from \"@ooneex/cron\";\nimport { Cron, decorator } from \"@ooneex/cron\";\n\n@decorator.cron()\nexport class <Name>Cron extends Cron {\n public getTime(): CronTimeType {\n // Examples: \"every 5 minutes\", \"every 1 hours\", \"every 30 seconds\"\n return \"every 1 hours\";\n }\n\n public getTimeZone(): TimeZoneType | null {\n // Return null to use server timezone, or specify a timezone like \"Europe/Paris\"\n return null;\n }\n\n public async handler(): Promise<void> {\n // Implement your cron handler logic here\n // console.log(\"<Name>Cron handler executed\");\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/cron/<Name>Cron.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getTime, getTimeZone, handler methods)\n- Add tests relevant to the specific cron class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Cron } from \"@/cron/<Name>Cron\";\n\ndescribe(\"<Name>Cron\", () => {\n test(\"should have class name ending with 'Cron'\", () => {\n expect(<Name>Cron.name.endsWith(\"Cron\")).toBe(true);\n });\n\n test(\"should have 'getTime' method\", () => {\n expect(<Name>Cron.prototype.getTime).toBeDefined();\n expect(typeof <Name>Cron.prototype.getTime).toBe(\"function\");\n });\n\n test(\"should have 'getTimeZone' method\", () => {\n expect(<Name>Cron.prototype.getTimeZone).toBeDefined();\n expect(typeof <Name>Cron.prototype.getTimeZone).toBe(\"function\");\n });\n\n test(\"should have 'handler' method\", () => {\n expect(<Name>Cron.prototype.handler).toBeDefined();\n expect(typeof <Name>Cron.prototype.handler).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the cron job in the module\n\nAdd the new cron job to the module's `cronJobs` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Cron } from \"./cron/<Name>Cron\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [],\n middlewares: [],\n cronJobs: [<Name>Cron],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other cron jobs registered, append the new cron job to the existing `cronJobs` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/cron/<Name>Cron.ts tests/cron/<Name>Cron.spec.ts\n```\n";var Wo="---\nname: make:database\ndescription: Generate a new database class with its test file, then complete the generated code. Use when creating a new database adapter that extends TypeormDatabase from @ooneex/database.\n---\n\n# Make Database Class\n\nGenerate a new database class and its test file using the `make:database` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the database class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:database --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/databases/<Name>Database.ts` - The database class file (or `modules/<module>/src/databases/<Name>Database.ts` with `--module`)\n- `tests/databases/<Name>Database.spec.ts` - The test file (or `modules/<module>/tests/databases/<Name>Database.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the database class\n\nEdit `src/databases/<Name>Database.ts` to complete the implementation:\n\n- Add entity imports and register them in the `entities` array\n- Adjust the database path if needed (default is `\"var/db\"`)\n- Configure DataSource options as appropriate (type, synchronize, etc.)\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { DataSource } from \"typeorm\";\nimport { TypeormDatabase, DatabaseException, decorator } from \"@ooneex/database\";\n\n@decorator.database()\nexport class <Name>Database extends TypeormDatabase {\n public getSource(database?: string): DataSource {\n database = database || \"var/db\";\n\n this.source = new DataSource({\n synchronize: false,\n entities: [\n // TODO: Load your entities here\n ],\n enableWAL: true,\n busyErrorRetry: 2000,\n busyTimeout: 30_000,\n database,\n type: \"sqlite\",\n });\n\n return this.source;\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/databases/<Name>Database.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getSource method)\n- Add tests relevant to the specific database class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Database } from \"@/databases/<Name>Database\";\n\ndescribe(\"<Name>Database\", () => {\n test(\"should have class name ending with 'Database'\", () => {\n expect(<Name>Database.name.endsWith(\"Database\")).toBe(true);\n });\n\n test(\"should have 'getSource' method\", () => {\n expect(<Name>Database.prototype.getSource).toBeDefined();\n expect(typeof <Name>Database.prototype.getSource).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/databases/<Name>Database.ts tests/databases/<Name>Database.spec.ts\n```\n";var Ko="---\nname: make:entity\ndescription: Generate a new TypeORM entity class with its test file, then complete the generated code. Use when creating a new database entity with columns, relations, and table mapping.\n---\n\n# Make Entity Class\n\nGenerate a new entity class and its test file using the `make:entity` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the entity class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:entity --name <name> --module <module> --table-name <table_name>\n```\n\nWhere `<name>` is the name provided by the user. The `--table-name` option is optional \u2014 if omitted, it defaults to the snake_case pluralized form of the name (e.g., `UserProfile` becomes `user_profiles`). The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/entities/<Name>Entity.ts` - The entity class file (or `modules/<module>/src/entities/<Name>Entity.ts` with `--module`)\n- `tests/entities/<Name>Entity.spec.ts` - The test file (or `modules/<module>/tests/entities/<Name>Entity.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the entity class\n\nEdit `src/entities/<Name>Entity.ts` to complete the implementation:\n\n- Add entity-specific columns with appropriate TypeORM decorators (`@Column`)\n- Add relations if needed (`@ManyToOne`, `@OneToMany`, `@ManyToMany`, etc.)\n- Remove any scaffolded columns that are not relevant to the entity\n- Adjust column types, lengths, and constraints as needed\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { LocaleType } from \"@ooneex/translation\";\nimport { random } from \"@ooneex/utils\";\nimport { Column, CreateDateColumn, DeleteDateColumn, PrimaryColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({\n name: \"<table_name>\",\n})\nexport class <Name>Entity extends BaseEntity {\n @PrimaryColumn({ name: \"id\", type: \"varchar\", length: 25 })\n id: string = random.nanoid(25);\n\n @Column({\n name: \"is_locked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isLocked?: boolean;\n\n @Column({ name: \"locked_at\", type: \"timestamptz\", nullable: true })\n lockedAt?: Date;\n\n @Column({\n name: \"is_blocked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isBlocked?: boolean;\n\n @Column({ name: \"blocked_at\", type: \"timestamptz\", nullable: true })\n blockedAt?: Date;\n\n @Column({ name: \"block_reason\", type: \"text\", nullable: true })\n blockReason?: string;\n\n @Column({ name: \"is_public\", type: \"boolean\", default: true, nullable: true })\n isPublic?: boolean;\n\n @Column({ name: \"lang\", type: \"varchar\", length: 10, nullable: true })\n lang?: LocaleType;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt?: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt?: Date;\n\n @DeleteDateColumn({ name: \"deleted_at\" })\n deletedAt?: Date;\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/entities/<Name>Entity.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, id, default columns)\n- Add tests for any new entity-specific columns and relations\n- Update tests if scaffolded columns were removed\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Entity } from \"@/entities/<Name>Entity\";\n\ndescribe(\"<Name>Entity\", () => {\n test(\"should have class name ending with 'Entity'\", () => {\n expect(<Name>Entity.name.endsWith(\"Entity\")).toBe(true);\n });\n\n test(\"should have 'id' property with default nanoid\", () => {\n const entity = new <Name>Entity();\n expect(entity.id).toBeDefined();\n expect(typeof entity.id).toBe(\"string\");\n expect(entity.id.length).toBe(25);\n });\n\n test(\"should have 'isLocked' property\", () => {\n const entity = new <Name>Entity();\n expect(\"isLocked\" in entity).toBe(true);\n });\n\n // ... additional property tests\n});\n```\n\n### 5. Register the entity in the module\n\nAdd the new entity to the module's `entities` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Entity } from \"./entities/<Name>Entity\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [<Name>Entity],\n permissions: [],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other entities registered, append the new entity to the existing `entities` array and add the import alongside existing imports.\n\n### 6. Create a migration for the entity\n\nAfter creating or updating an entity, generate a migration to apply the corresponding schema changes to the database.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:migration\n```\n\nThen read the generated migration file in `src/migrations/` and complete it:\n\n- In the `up` method, write the SQL to create the table (or alter it if updating an existing entity). Include all columns, types, constraints, defaults, and indexes matching the entity definition.\n- In the `down` method, write the reverse SQL to undo the changes (e.g., `DROP TABLE` or `ALTER TABLE DROP COLUMN`).\n- If the migration depends on another migration (e.g., a foreign key referencing another table), add that migration class to the `getDependencies()` return array.\n\nExample `up` method for a new entity:\n\n```typescript\npublic async up(tx: TransactionSQL): Promise<void> {\n await tx`\n CREATE TABLE IF NOT EXISTS <table_name> (\n id VARCHAR(25) PRIMARY KEY,\n is_locked BOOLEAN DEFAULT false,\n locked_at TIMESTAMPTZ,\n is_blocked BOOLEAN DEFAULT false,\n blocked_at TIMESTAMPTZ,\n block_reason TEXT,\n is_public BOOLEAN DEFAULT true,\n lang VARCHAR(10),\n created_at TIMESTAMPTZ DEFAULT NOW(),\n updated_at TIMESTAMPTZ DEFAULT NOW(),\n deleted_at TIMESTAMPTZ\n )\n `;\n}\n```\n\n### 7. Create a repository for the entity\n\nAfter creating the entity, generate a repository to handle database operations for it.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name <name>\n```\n\nWhere `<name>` is the same name used for the entity. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class\n- `tests/repositories/<Name>Repository.spec.ts` - The test file\n\nThen read the generated files and complete the repository implementation:\n\n- Adjust search fields in the `find()` method to match the entity's searchable columns\n- Customize relations loading in `findOne`/`findOneBy` if the entity has relations\n- Add any domain-specific methods relevant to the entity\n- Remove methods that don't apply to the entity\n- Update tests to match the final repository methods\n\n### 8. Lint and format\n\nRun linting and formatting on all generated files:\n\n```bash\nbunx biome check --fix src/entities/<Name>Entity.ts tests/entities/<Name>Entity.spec.ts src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts src/migrations/\n```\n";var Fo="---\nname: make:logger\ndescription: Generate a new logger class with its test file, then complete the generated code. Use when creating a new logger that implements the ILogger interface from @ooneex/logger.\n---\n\n# Make Logger Class\n\nGenerate a new logger class and its test file using the `make:logger` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the logger class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:logger --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/loggers/<Name>Logger.ts` - The logger class file (or `modules/<module>/src/loggers/<Name>Logger.ts` with `--module`)\n- `tests/loggers/<Name>Logger.spec.ts` - The test file (or `modules/<module>/tests/loggers/<Name>Logger.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the logger class\n\nEdit `src/loggers/<Name>Logger.ts` to complete the implementation:\n\n- Implement the `init()` method to set up the logger (e.g., open file handles, configure transports)\n- Implement `log`, `debug`, `info`, `success`, `warn`, and `error` methods with actual logging logic\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { IException } from \"@ooneex/exception\";\nimport type { ILogger } from \"@ooneex/logger\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { decorator } from \"@ooneex/logger\";\n\n@decorator.logger()\nexport class <Name>Logger implements ILogger {\n public async init(): Promise<void> {\n // Initialize your logger here\n }\n\n public log(message: string, data?: Record<string, ScalarType>): void {\n // Handle general logging\n }\n\n public debug(message: string, data?: Record<string, ScalarType>): void {\n // Handle debug logging\n }\n\n public info(message: string, data?: Record<string, ScalarType>): void {\n // Handle info logging\n }\n\n public success(message: string, data?: Record<string, ScalarType>): void {\n // Handle success logging\n }\n\n public warn(message: string, data?: Record<string, ScalarType>): void {\n // Handle warning logging\n }\n\n public error(message: string | IException, data?: Record<string, ScalarType>): void {\n // Handle error logging\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/loggers/<Name>Logger.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, init, log, debug, info, success, warn, error methods)\n- Add tests relevant to the specific logger class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Logger } from \"@/loggers/<Name>Logger\";\n\ndescribe(\"<Name>Logger\", () => {\n test(\"should have class name ending with 'Logger'\", () => {\n expect(<Name>Logger.name.endsWith(\"Logger\")).toBe(true);\n });\n\n test(\"should have 'init' method\", () => {\n expect(<Name>Logger.prototype.init).toBeDefined();\n expect(typeof <Name>Logger.prototype.init).toBe(\"function\");\n });\n\n test(\"should have 'log' method\", () => {\n expect(<Name>Logger.prototype.log).toBeDefined();\n expect(typeof <Name>Logger.prototype.log).toBe(\"function\");\n });\n\n test(\"should have 'debug' method\", () => {\n expect(<Name>Logger.prototype.debug).toBeDefined();\n expect(typeof <Name>Logger.prototype.debug).toBe(\"function\");\n });\n\n test(\"should have 'info' method\", () => {\n expect(<Name>Logger.prototype.info).toBeDefined();\n expect(typeof <Name>Logger.prototype.info).toBe(\"function\");\n });\n\n test(\"should have 'success' method\", () => {\n expect(<Name>Logger.prototype.success).toBeDefined();\n expect(typeof <Name>Logger.prototype.success).toBe(\"function\");\n });\n\n test(\"should have 'warn' method\", () => {\n expect(<Name>Logger.prototype.warn).toBeDefined();\n expect(typeof <Name>Logger.prototype.warn).toBe(\"function\");\n });\n\n test(\"should have 'error' method\", () => {\n expect(<Name>Logger.prototype.error).toBeDefined();\n expect(typeof <Name>Logger.prototype.error).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/loggers/<Name>Logger.ts tests/loggers/<Name>Logger.spec.ts\n```\n";var Ho="---\nname: make:mailer\ndescription: Generate a new mailer class with its template and test files, then complete the generated code. Use when creating a new email sender with JSX template using @ooneex/mailer.\n---\n\n# Make Mailer Class\n\nGenerate a new mailer class, its JSX template, and test files using the `make:mailer` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the mailer class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:mailer --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate (paths prefixed with `modules/<module>/` when `--module` is provided):\n- `src/mailers/<Name>Mailer.ts` - The mailer class file\n- `src/mailers/<Name>MailerTemplate.tsx` - The JSX email template\n- `tests/mailers/<Name>Mailer.spec.ts` - The mailer test file\n- `tests/mailers/<Name>MailerTemplate.spec.ts` - The template test file\n\n### 2. Read the generated files\n\nRead all four generated files to understand the scaffolded code.\n\n### 3. Complete the mailer class\n\nEdit `src/mailers/<Name>Mailer.ts` to complete the implementation:\n\n- Adjust the `send` method config type if additional parameters are needed\n- Add any pre-send logic (validation, data transformation, etc.)\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { IMailer } from \"@ooneex/mailer\";\nimport { type <Name>MailerPropsType, <Name>MailerTemplate } from \"./<Name>MailerTemplate\";\n\nexport class <Name>Mailer implements IMailer {\n constructor(\n @inject(\"mailer\")\n private readonly mailer: IMailer,\n ) {}\n\n public send = async (config: {\n to: string[];\n subject: string;\n from?: { name: string; address: string };\n data?: <Name>MailerPropsType;\n }): Promise<void> => {\n const { data, ...rest } = config;\n\n await this.mailer.send({\n ...rest,\n content: <Name>MailerTemplate(data),\n });\n };\n}\n```\n\n### 4. Complete the mailer template\n\nEdit `src/mailers/<Name>MailerTemplate.tsx` to complete the implementation:\n\n- Update `<Name>MailerPropsType` with the actual props needed for the email\n- Build the email body using `MailerLayout` components (Header, Body, Footer)\n- Add email content, styling, and dynamic data rendering\n\nThe generated template structure follows this pattern:\n\n```tsx\nimport { MailerLayout } from \"@ooneex/mailer\";\n\nexport type <Name>MailerPropsType = {\n link: string;\n};\n\nexport const <Name>MailerTemplate = (props?: <Name>MailerPropsType) => (\n <MailerLayout>\n <MailerLayout.Header />\n <MailerLayout.Body>\n <a href={props?.link}>Login</a>\n </MailerLayout.Body>\n <MailerLayout.Footer />\n </MailerLayout>\n);\n```\n\n### 5. Complete the test files\n\nEdit `tests/mailers/<Name>Mailer.spec.ts` and `tests/mailers/<Name>MailerTemplate.spec.ts` to add meaningful tests beyond the scaffolded ones.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/mailers/<Name>Mailer.ts src/mailers/<Name>MailerTemplate.tsx tests/mailers/<Name>Mailer.spec.ts tests/mailers/<Name>MailerTemplate.spec.ts\n```\n";var Vo="---\nname: make:middleware\ndescription: Generate a new middleware class with its test file, then complete the generated code. Use when creating a new HTTP or WebSocket middleware that implements IMiddleware from @ooneex/middleware.\n---\n\n# Make Middleware Class\n\nGenerate a new middleware class and its test file using the `make:middleware` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the middleware class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:middleware --name <name> --module <module> --is-socket <true|false>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The `--is-socket` option determines whether to generate an HTTP middleware or a WebSocket middleware (defaults to `false` if omitted). The command will generate:\n- `src/middlewares/<Name>Middleware.ts` - The middleware class file (or `modules/<module>/src/middlewares/<Name>Middleware.ts` with `--module`)\n- `tests/middlewares/<Name>Middleware.spec.ts` - The test file (or `modules/<module>/tests/middlewares/<Name>Middleware.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the middleware class\n\nEdit `src/middlewares/<Name>Middleware.ts` to complete the implementation:\n\n- Implement the `handler` method with actual middleware logic\n- Add request/response transformations, authentication checks, logging, etc.\n- Inject any required dependencies via the constructor\n\n**HTTP middleware** generated structure:\n\n```typescript\nimport type { ContextType } from \"@ooneex/controller\";\nimport { decorator, type IMiddleware } from \"@ooneex/middleware\";\n\n@decorator.middleware()\nexport class <Name>Middleware implements IMiddleware {\n public async handler(context: ContextType): Promise<ContextType> {\n // Example: Add custom header\n // context.response.header(\"X-Custom-Header\", \"value\");\n\n return context\n }\n}\n```\n\n**Socket middleware** generated structure:\n\n```typescript\nimport type { ContextType } from \"@ooneex/socket\";\nimport { decorator, type IMiddleware } from \"@ooneex/middleware\";\n\n@decorator.middleware()\nexport class <Name>Middleware implements IMiddleware {\n public async handler(context: ContextType): Promise<ContextType> {\n // Example: Add custom header\n // context.response.header(\"X-Custom-Header\", \"value\");\n\n return context\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/middlewares/<Name>Middleware.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, handler method)\n- Add tests relevant to the specific middleware behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Middleware } from \"@/middlewares/<Name>Middleware\";\n\ndescribe(\"<Name>Middleware\", () => {\n test(\"should have class name ending with 'Middleware'\", () => {\n expect(<Name>Middleware.name.endsWith(\"Middleware\")).toBe(true);\n });\n\n test(\"should have 'handler' method\", () => {\n expect(<Name>Middleware.prototype.handler).toBeDefined();\n expect(typeof <Name>Middleware.prototype.handler).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the middleware in the module\n\nAdd the new middleware to the module's `middlewares` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Middleware } from \"./middlewares/<Name>Middleware\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [],\n middlewares: [<Name>Middleware],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other middlewares registered, append the new middleware to the existing `middlewares` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/middlewares/<Name>Middleware.ts tests/middlewares/<Name>Middleware.spec.ts\n```\n";var Yo="---\nname: make:migration\ndescription: Generate a new database migration file, then complete the generated code. Use when creating a new database migration for schema changes using @ooneex/migrations.\n---\n\n# Make Migration\n\nGenerate a new migration file using the `make:migration` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the migration file:\n\n```bash\nbunx @ooneex/cli@latest make:migration --module <module>\n```\n\nThe `--module` option is optional \u2014 if provided, the migration file is generated under `modules/<module>/src/migrations/` instead of `src/migrations/`. The command will:\n- Generate a timestamped migration file in `src/migrations/` (or `modules/<module>/src/migrations/` with `--module`)\n- Add a `migration:up` script to `package.json` if not already present\n\n### 2. Read the generated file\n\nRead the generated migration file in `src/migrations/` to understand the scaffolded code.\n\n### 3. Complete the migration\n\nEdit the generated migration file to implement:\n\n- The `up` method with the schema changes (create tables, add columns, create indexes, etc.)\n- The `down` method with the reverse operations to undo the migration\n\n### 4. Lint and format\n\nRun linting and formatting on the generated file:\n\n```bash\nbunx biome check --fix src/migrations/\n```\n";var zo="---\nname: make:permission\ndescription: Generate a new permission class with its test file, then complete the generated code. Use when creating a new permission that extends Permission from @ooneex/permission.\n---\n\n# Make Permission Class\n\nGenerate a new permission class and its test file using the `make:permission` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the permission class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:permission --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/permissions/<Name>Permission.ts` - The permission class file (or `modules/<module>/src/permissions/<Name>Permission.ts` with `--module`)\n- `tests/permissions/<Name>Permission.spec.ts` - The test file (or `modules/<module>/tests/permissions/<Name>Permission.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the permission class\n\nEdit `src/permissions/<Name>Permission.ts` to complete the implementation:\n\n- Implement the `allow()` method with permission rules using `this.ability.can()`\n- Implement the `setUserPermissions()` method with role-based permission logic\n- Define which actions (read, create, update, delete, manage) are allowed on which entities\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator, Permission } from \"@ooneex/permission\";\nimport type { IUser } from \"@ooneex/user\";\n\n@decorator.permission()\nexport class <Name>Permission extends Permission {\n public allow(): this {\n // Example: Add permissions using this.ability.can()\n // this.ability.can(\"read\", \"YourEntity\");\n // this.ability.can([\"read\", \"update\"], \"YourEntity\", { userId: user.id });\n\n return this;\n }\n\n public setUserPermissions(user: IUser | null): this {\n if (!user) {\n return this;\n }\n\n // Example: Grant full access to admins\n // const { roles } = user;\n // if (roles.includes(ERole.ADMIN)) {\n // this.ability.can(\"manage\", \"all\");\n // return this;\n // }\n\n // Example: Grant specific permissions based on roles\n // for (const role of roles) {\n // if (role === ERole.USER) {\n // this.ability.can([\"read\", \"update\"], \"YourEntity\", { userId: user.id });\n // }\n //\n // if (role === ERole.GUEST) {\n // this.ability.can(\"read\", \"YourEntity\", { public: true });\n // }\n // }\n\n return this;\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/permissions/<Name>Permission.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, extends Permission, allow, setUserPermissions methods)\n- Add tests relevant to the specific permission rules\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { Permission } from \"@ooneex/permission\";\nimport { <Name>Permission } from \"@/permissions/<Name>Permission\";\n\ndescribe(\"<Name>Permission\", () => {\n test(\"should have class name ending with 'Permission'\", () => {\n expect(<Name>Permission.name.endsWith(\"Permission\")).toBe(true);\n });\n\n test(\"should extend Permission\", () => {\n const permission = new <Name>Permission();\n expect(permission).toBeInstanceOf(Permission);\n });\n\n test(\"should have 'allow' method\", () => {\n expect(<Name>Permission.prototype.allow).toBeDefined();\n expect(typeof <Name>Permission.prototype.allow).toBe(\"function\");\n });\n\n test(\"should have 'setUserPermissions' method\", () => {\n expect(<Name>Permission.prototype.setUserPermissions).toBeDefined();\n expect(typeof <Name>Permission.prototype.setUserPermissions).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the permission in the module\n\nAdd the new permission to the module's `permissions` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Permission } from \"./permissions/<Name>Permission\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [<Name>Permission],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other permissions registered, append the new permission to the existing `permissions` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/permissions/<Name>Permission.ts tests/permissions/<Name>Permission.spec.ts\n```\n";var Zo="---\nname: make:pubsub\ndescription: Generate a new PubSub event class with its test file, then complete the generated code. Use when creating a new publish/subscribe event that extends PubSub from @ooneex/pub-sub.\n---\n\n# Make PubSub Event Class\n\nGenerate a new PubSub event class and its test file using the `make:pubsub` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the PubSub event class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:pubsub --name <name> --module <module> --channel <channel>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The `--channel` option is optional \u2014 if omitted, it defaults to the kebab-case form of the name (e.g., `UserCreated` becomes `user-created`). The command will generate:\n- `src/events/<Name>Event.ts` - The event class file (or `modules/<module>/src/events/<Name>Event.ts` with `--module`)\n- `tests/events/<Name>Event.spec.ts` - The test file (or `modules/<module>/tests/events/<Name>Event.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the PubSub event class\n\nEdit `src/events/<Name>Event.ts` to complete the implementation:\n\n- Define a proper data type instead of `Record<string, ScalarType>` for the event payload\n- Implement the `handler()` method with actual event handling logic\n- Set the appropriate channel name in `getChannel()`\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { decorator, PubSub, RedisPubSub } from \"@ooneex/pub-sub\";\n\n@decorator.pubSub()\nexport class <Name>Event<Data extends Record<string, ScalarType> = Record<string, ScalarType>> extends PubSub<Data> {\n constructor(\n @inject(RedisPubSub)\n client: RedisPubSub<Data>,\n ) {\n super(client);\n }\n\n public getChannel(): string {\n return \"<channel>\";\n }\n\n public async handler(context: { data: Data; channel: string }): Promise<void> {\n console.log(context);\n // TODO: Implement handler logic here\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/events/<Name>Event.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getChannel, handler, publish, subscribe, unsubscribe, unsubscribeAll methods)\n- Add tests relevant to the specific event behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>PubSub } from \"@/pubsub/<Name>PubSub\";\n\ndescribe(\"<Name>PubSub\", () => {\n test(\"should have class name ending with 'PubSub'\", () => {\n expect(<Name>PubSub.name.endsWith(\"PubSub\")).toBe(true);\n });\n\n test(\"should have 'getChannel' method\", () => {\n expect(<Name>PubSub.prototype.getChannel).toBeDefined();\n expect(typeof <Name>PubSub.prototype.getChannel).toBe(\"function\");\n });\n\n test(\"should have 'handler' method\", () => {\n expect(<Name>PubSub.prototype.handler).toBeDefined();\n expect(typeof <Name>PubSub.prototype.handler).toBe(\"function\");\n });\n\n test(\"should have 'publish' method\", () => {\n expect(<Name>PubSub.prototype.publish).toBeDefined();\n expect(typeof <Name>PubSub.prototype.publish).toBe(\"function\");\n });\n\n test(\"should have 'subscribe' method\", () => {\n expect(<Name>PubSub.prototype.subscribe).toBeDefined();\n expect(typeof <Name>PubSub.prototype.subscribe).toBe(\"function\");\n });\n\n test(\"should have 'unsubscribe' method\", () => {\n expect(<Name>PubSub.prototype.unsubscribe).toBeDefined();\n expect(typeof <Name>PubSub.prototype.unsubscribe).toBe(\"function\");\n });\n\n test(\"should have 'unsubscribeAll' method\", () => {\n expect(<Name>PubSub.prototype.unsubscribeAll).toBeDefined();\n expect(typeof <Name>PubSub.prototype.unsubscribeAll).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the event in the module\n\nAdd the new event to the module's `events` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Event } from \"./events/<Name>Event\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [],\n middlewares: [],\n cronJobs: [],\n events: [<Name>Event],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other events registered, append the new event to the existing `events` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/events/<Name>Event.ts tests/events/<Name>Event.spec.ts\n```\n";var Qo="---\nname: make:repository\ndescription: Generate a new repository class with its test file, then complete the generated code. Use when creating a new TypeORM repository for database operations on an entity.\n---\n\n# Make Repository Class\n\nGenerate a new repository class and its test file using the `make:repository` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the repository class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class file (or `modules/<module>/src/repositories/<Name>Repository.ts` with `--module`)\n- `tests/repositories/<Name>Repository.spec.ts` - The test file (or `modules/<module>/tests/repositories/<Name>Repository.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the repository class\n\nEdit `src/repositories/<Name>Repository.ts` to complete the implementation:\n\n- Verify the entity import path matches the actual entity location\n- Adjust the `find` method's search fields (default searches `name` with `ILike`)\n- Customize relations loading in `findOne`/`findOneBy` if needed\n\n#### Adding methods\n\nLook at the entity's fields, relations, and business context to determine if custom domain-specific methods are needed. For example:\n- A `SessionRepository` might need `revokeSession(sessionId: string)` and `revokeAllUserSessions(userId: string)`\n- A `NotificationRepository` might need `markAsRead(id: string)` and `markAllAsRead(userId: string)`\n- Entities with status fields may need methods like `archive(id: string)` or `activate(id: string)`\n\nRead related entities, services, or actions in the module to understand what operations the repository should support, then add the appropriate methods.\n\n#### Removing methods\n\nRemove scaffolded methods that don't make sense for the entity's context:\n- Remove `createMany`/`updateMany` if the entity is always managed individually (e.g., user profiles, settings)\n- Remove `delete` if the entity uses soft deletes only (use a custom `softDelete` or `archive` method instead)\n- Remove `find` if the entity is only ever accessed by ID or specific criteria (e.g., singleton config entities)\n- Remove `count` if there's no use case for counting records of this entity\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { ITypeormDatabase } from \"@ooneex/database\";\nimport { decorator } from \"@ooneex/repository\";\nimport type { FilterResultType } from \"@ooneex/types\";\nimport type { FindManyOptions, FindOptionsWhere, Repository, SaveOptions, UpdateResult } from \"typeorm\";\nimport { ILike } from \"typeorm\";\nimport { <Name>Entity } from \"../entities/<Name>Entity\";\n\n@decorator.repository()\nexport class <Name>Repository {\n constructor(\n @inject(\"database\")\n private readonly database: ITypeormDatabase,\n ) {}\n\n public async open(): Promise<Repository<<Name>Entity>> {\n return await this.database.open(<Name>Entity);\n }\n\n public async close(): Promise<void> {\n await this.database.close();\n }\n\n public async find(\n criteria: FindManyOptions<<Name>Entity> & { page?: number; limit?: number; q?: string },\n ): Promise<FilterResultType<<Name>Entity>> {\n // ... pagination and search logic\n }\n\n public async findOne(id: string): Promise<<Name>Entity | null> { ... }\n public async findOneBy(criteria: FindOptionsWhere<<Name>Entity>): Promise<<Name>Entity | null> { ... }\n public async create(entity: <Name>Entity, options?: SaveOptions): Promise<<Name>Entity> { ... }\n public async createMany(entities: <Name>Entity[], options?: SaveOptions): Promise<<Name>Entity[]> { ... }\n public async update(entity: <Name>Entity, options?: SaveOptions): Promise<<Name>Entity> { ... }\n public async updateMany(entities: <Name>Entity[], options?: SaveOptions): Promise<<Name>Entity[]> { ... }\n public async delete(criteria: FindOptionsWhere<<Name>Entity> | FindOptionsWhere<<Name>Entity>[]): Promise<UpdateResult> { ... }\n public async count(criteria?: FindOptionsWhere<<Name>Entity> | FindOptionsWhere<<Name>Entity>[]): Promise<number> { ... }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/repositories/<Name>Repository.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep scaffolded tests for methods that remain in the repository (remove tests for methods that were removed)\n- Add tests for any custom domain-specific methods added to the repository\n- Add tests relevant to the specific repository behavior\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts\n```\n";var Xo="---\nname: make:seed\ndescription: Generate a new database seed file, then complete the generated code. Use when creating seed data for populating the database using @ooneex/seeds.\n---\n\n# Make Seed\n\nGenerate a new seed file using the `make:seed` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the seed file:\n\n```bash\nbunx @ooneex/cli@latest make:seed --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, the seed file is generated under `modules/<module>/src/seeds/` instead of `src/seeds/`. The command will:\n- Generate a seed file in `src/seeds/` (or `modules/<module>/src/seeds/` with `--module`)\n- Add a `seed:run` script to `package.json` if not already present\n\n### 2. Read the generated file\n\nRead the generated seed file in `src/seeds/` to understand the scaffolded code.\n\n### 3. Complete the seed\n\nEdit the generated seed file to implement:\n\n- Import the relevant entity classes\n- Create seed data with hardcoded nanoid values for `id` fields (generate via `bun -e \"import { random } from '@ooneex/utils'; console.log(random.nanoid())\"`)\n- Do NOT use sequential IDs like `\"item-1\"`, `\"item-2\"`\n- Ensure the same entity uses the same ID everywhere it appears\n\n### 4. Lint and format\n\nRun linting and formatting on the generated file:\n\n```bash\nbunx biome check --fix src/seeds/\n```\n";var Jo="---\nname: make:service\ndescription: Generate a new service class with its test file, then complete the generated code. Use when creating a new business logic service that implements IService from @ooneex/service.\n---\n\n# Make Service Class\n\nGenerate a new service class and its test file using the `make:service` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the service class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:service --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/services/<Name>Service.ts` - The service class file (or `modules/<module>/src/services/<Name>Service.ts` with `--module`)\n- `tests/services/<Name>Service.spec.ts` - The test file (or `modules/<module>/tests/services/<Name>Service.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the service class\n\nEdit `src/services/<Name>Service.ts` to complete the implementation:\n\n- Define a proper type for `ServiceDataType` instead of `Record<string, unknown>`\n- Implement the `execute()` method with actual business logic\n- Inject any required dependencies (repositories, other services, etc.) via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator } from \"@ooneex/service\";\nimport type { IService } from \"@ooneex/service\";\n\ntype ServiceDataType = Record<string, unknown>;\n\n@decorator.service()\nexport class <Name>Service<T extends ServiceDataType = ServiceDataType> implements IService<T> {\n public async execute(data?: T): Promise<void> {\n // TODO: Implement service logic\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/services/<Name>Service.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, execute method)\n- Add tests relevant to the specific service behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Service } from \"@/services/<Name>Service\";\n\ndescribe(\"<Name>Service\", () => {\n test(\"should have class name ending with 'Service'\", () => {\n expect(<Name>Service.name.endsWith(\"Service\")).toBe(true);\n });\n\n test(\"should have 'execute' method\", () => {\n expect(<Name>Service.prototype.execute).toBeDefined();\n expect(typeof <Name>Service.prototype.execute).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/services/<Name>Service.ts tests/services/<Name>Service.spec.ts\n```\n";var jo="---\nname: make:storage\ndescription: Generate a new storage class with its test file, then complete the generated code. Use when creating a new S3-compatible storage adapter that extends Storage from @ooneex/storage.\n---\n\n# Make Storage Class\n\nGenerate a new storage class and its test file using the `make:storage` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the storage class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:storage --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/storage/<Name>Storage.ts` - The storage class file (or `modules/<module>/src/storage/<Name>Storage.ts` with `--module`)\n- `tests/storage/<Name>Storage.spec.ts` - The test file (or `modules/<module>/tests/storage/<Name>Storage.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the storage class\n\nEdit `src/storage/<Name>Storage.ts` to complete the implementation:\n\n- Set the `bucket` property to the appropriate bucket name\n- Verify the environment variable names match the project configuration (`STORAGE_<NAME_UPPER>_ACCESS_KEY`, `STORAGE_<NAME_UPPER>_SECRET_KEY`, `STORAGE_<NAME_UPPER>_ENDPOINT`, `STORAGE_<NAME_UPPER>_REGION`)\n- Add any additional storage-specific methods if needed\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { Storage, decorator, StorageException } from \"@ooneex/storage\";\nimport type { S3Options } from \"bun\";\n\n@decorator.storage()\nexport class <Name>Storage extends Storage {\n protected bucket: string;\n private readonly accessKey: string;\n private readonly secretKey: string;\n private readonly endpoint: string;\n private readonly region: string;\n\n constructor(options?: {\n accessKey?: string;\n secretKey?: string;\n endpoint?: string;\n region?: string;\n }) {\n super();\n\n const accessKey = options?.accessKey || Bun.env.STORAGE_<NAME_UPPER>_ACCESS_KEY;\n const secretKey = options?.secretKey || Bun.env.STORAGE_<NAME_UPPER>_SECRET_KEY;\n const endpoint = options?.endpoint || Bun.env.STORAGE_<NAME_UPPER>_ENDPOINT;\n\n // ... validation throws StorageException if missing ...\n\n this.accessKey = accessKey;\n this.secretKey = secretKey;\n this.endpoint = endpoint;\n this.region = options?.region || Bun.env.STORAGE_<NAME_UPPER>_REGION || \"auto\";\n }\n\n public getOptions(): S3Options {\n return {\n accessKeyId: this.accessKey,\n secretAccessKey: this.secretKey,\n endpoint: this.endpoint,\n bucket: this.bucket,\n region: this.region,\n };\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/storage/<Name>Storage.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, bucket field, getOptions method)\n- Add tests relevant to the specific storage class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>StorageAdapter } from \"@/storage/<Name>StorageAdapter\";\n\ndescribe(\"<Name>StorageAdapter\", () => {\n test(\"should have class name ending with 'StorageAdapter'\", () => {\n expect(<Name>StorageAdapter.name.endsWith(\"StorageAdapter\")).toBe(true);\n });\n\n test(\"should have 'bucket' field\", () => {\n expect(\"bucket\" in <Name>StorageAdapter.prototype || \"bucket\" in Object.getOwnPropertyNames(<Name>StorageAdapter.prototype)).toBe(true);\n });\n\n test(\"should have 'getOptions' method\", () => {\n expect(<Name>StorageAdapter.prototype.getOptions).toBeDefined();\n expect(typeof <Name>StorageAdapter.prototype.getOptions).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/storage/<Name>Storage.ts tests/storage/<Name>Storage.spec.ts\n```\n";var ei="---\nname: make:vector-database\ndescription: Generate a new vector database class with its test file, then complete the generated code. Use when creating a new vector database that extends VectorDatabase from @ooneex/rag.\n---\n\n# Make Vector Database Class\n\nGenerate a new vector database class and its test file using the `make:vector-database` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the vector database class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:vector-database --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/databases/<Name>VectorDatabase.ts` - The vector database class file (or `modules/<module>/src/databases/<Name>VectorDatabase.ts` with `--module`)\n- `tests/databases/<Name>VectorDatabase.spec.ts` - The test file (or `modules/<module>/tests/databases/<Name>VectorDatabase.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the vector database class\n\nEdit `src/databases/<Name>VectorDatabase.ts` to complete the implementation:\n\n- Set the `getDatabaseUri()` return value to the actual LanceDB database path\n- Configure the embedding provider and model in `getEmbeddingModel()`\n- Define the custom data fields in `DataType` and map them in `getSchema()`\n- Import the appropriate Apache Arrow types for your schema fields\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { VectorDatabase, decorator } from \"@ooneex/rag\";\nimport type { EmbeddingModelType, EmbeddingProviderType, FieldValueType } from \"@ooneex/rag\";\nimport { Utf8 } from \"apache-arrow\";\n\ntype DataType = {\n name: string;\n};\n\n@decorator.vectorDatabase()\nexport class <Name>VectorDatabase extends VectorDatabase<DataType> {\n public getDatabaseUri(): string {\n return \"\";\n }\n\n public getEmbeddingModel(): { provider: EmbeddingProviderType; model: EmbeddingModelType[\"model\"] } {\n return { provider: \"openai\", model: \"text-embedding-ada-002\" };\n }\n\n public getSchema(): { [K in keyof DataType]: FieldValueType } {\n return {\n name: new Utf8(),\n };\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/databases/<Name>VectorDatabase.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getDatabaseUri, getEmbeddingModel, getSchema methods)\n- Add tests relevant to the specific vector database class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>VectorDatabase } from \"@/databases/<Name>VectorDatabase\";\n\ndescribe(\"<Name>VectorDatabase\", () => {\n test(\"should have class name ending with 'VectorDatabase'\", () => {\n expect(<Name>VectorDatabase.name.endsWith(\"VectorDatabase\")).toBe(true);\n });\n\n test(\"should have 'getDatabaseUri' method\", () => {\n expect(<Name>VectorDatabase.prototype.getDatabaseUri).toBeDefined();\n expect(typeof <Name>VectorDatabase.prototype.getDatabaseUri).toBe(\"function\");\n });\n\n test(\"should have 'getEmbeddingModel' method\", () => {\n expect(<Name>VectorDatabase.prototype.getEmbeddingModel).toBeDefined();\n expect(typeof <Name>VectorDatabase.prototype.getEmbeddingModel).toBe(\"function\");\n });\n\n test(\"should have 'getSchema' method\", () => {\n expect(<Name>VectorDatabase.prototype.getSchema).toBeDefined();\n expect(typeof <Name>VectorDatabase.prototype.getSchema).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/databases/<Name>VectorDatabase.ts tests/databases/<Name>VectorDatabase.spec.ts\n```\n";var ti="---\nname: optimize\ndescription: Optimize a module's codebase for quality, performance, and clean conventions. Enforces arrow functions (except class methods), type/interface naming, removes duplication, and ensures only important tests remain.\n---\n\n# Optimize Codebase\n\nOptimize a module's codebase for quality, performance, and clean conventions.\n\n## Coding Conventions\n\nApply these conventions across all files in the target module:\n\n- **Arrow functions everywhere** \u2014 use arrow functions for all function expressions, callbacks, standalone functions, and variable declarations. The ONLY exception is class methods, which must use regular method syntax.\n- **Type naming** \u2014 all type aliases must end with the `Type` suffix (e.g., `UserDataType`, `ConfigOptionsType`). Rename any that don't comply.\n- **Interface naming** \u2014 all interface names must start with the `I` prefix (e.g., `IUser`, `IService`, `IRepository`). Rename any that don't comply.\n- **No definite assignment assertions** \u2014 never use `!` on class properties (e.g., `email!: string`). Use a default value or make the property optional (`?`) instead.\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`).\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Identify the target\n\nDetermine the module to optimize. If the user specifies a module name, work in `modules/<module>/`. If no module is specified, ask the user which module to optimize.\n\n### 2. Read and analyze the module\n\nRead all source files (`src/**/*.ts`) and test files (`tests/**/*.ts`) in the target module. Build a full picture of:\n\n- All types, interfaces, classes, and functions\n- Dependencies between files\n- Existing test coverage\n\n### 3. Enforce naming conventions\n\nScan every file and fix:\n\n- **Types not ending with `Type`** \u2014 rename the type and update all references across the module\n- **Interfaces not starting with `I`** \u2014 rename the interface and update all references across the module\n- **Non-arrow functions** \u2014 convert all function expressions, callbacks, and standalone functions to arrow functions. Do NOT convert class methods.\n- **Missing visibility modifiers** \u2014 add explicit `public`, `private`, or `protected` to all class methods and properties\n\n### 4. Remove code duplication\n\nIdentify duplicated or near-duplicated code within the module:\n\n- Extract shared logic into well-named helper arrow functions or base classes\n- Consolidate repeated type definitions\n- Merge similar utility functions\n- Remove dead code (unused imports, unreachable branches, unused variables)\n\n### 5. Optimize for performance\n\nReview and improve:\n\n- Replace inefficient loops or repeated iterations with single-pass approaches where possible\n- Use `Map`/`Set` instead of arrays for lookups when appropriate\n- Avoid unnecessary object spreads or deep clones\n- Prefer early returns to reduce nesting\n- Remove unnecessary `async`/`await` where a direct return suffices\n- Eliminate redundant null/undefined checks when the type system already guarantees the value\n\n### 6. Optimize tests\n\nReview all test files and restructure:\n\n- **Remove trivial tests** \u2014 delete tests that only check obvious things (e.g., \"class name ends with X\", \"method exists\") unless they serve as smoke tests for generated code\n- **Keep and improve important tests** \u2014 focus on tests that verify actual business logic, edge cases, error handling, and integration behavior\n- **Write fewer but more meaningful tests** \u2014 each test should validate a real scenario or invariant, not just existence checks\n- **Consolidate redundant test cases** \u2014 merge tests that cover the same code path with slightly different inputs into parameterized patterns\n- **Ensure critical paths are covered** \u2014 every public method with logic should have at least one test covering its happy path and one covering its error/edge case\n\n### 7. Final cleanup\n\n- Remove all unused imports\n- Remove empty files or files with no exports\n- Ensure consistent formatting\n\n### 8. Lint and format\n\nRun linting and formatting on all modified files:\n\n```bash\nbunx biome check --fix <list of modified files>\n```\n\n### 9. Run tests\n\nRun the module's tests to verify nothing is broken:\n\n```bash\nbun test <module test directory>\n```\n\nIf any test fails, fix the issue and re-run until all tests pass.\n";var Vl={"make.ai":Uo,"make.analytics":Go,"make.cache":ko,"make.controller":$o,"make.cron":qo,"make.database":Wo,"make.entity":Ko,"make.logger":Fo,"make.mailer":Ho,"make.middleware":Vo,"make.migration":Yo,"make.permission":zo,"make.pubsub":Zo,"make.repository":Qo,"make.seed":Xo,"make.service":Jo,"make.storage":jo,"make.vector-database":ei,commit:Lo,optimize:ti};class qe{getName(){return"make:claude:skill"}getDescription(){return"Generate Claude skills from templates"}async run(){let e=$e(".claude","skills"),t=$e(process.cwd(),e),s=new Hl;for(let[r,o]of Object.entries(Vl)){let i=r.replace(/\./g,"-"),a=$e(t,i,"SKILL.md");await Bun.write(a,o),s.success(`${$e(e,i,"SKILL.md")} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}}qe=b([w.command()],qe);import{basename as Zl,join as G}from"path";import{TerminalLogger as Ql}from"@ooneex/logger";import{toPascalCase as Pt}from"@ooneex/utils";var si=`import { describe, expect, test } from "bun:test";
1820
+ `;var Gr="---\nname: make:ai\ndescription: Generate a new AI class with its test file, then complete the generated code. Use when creating a new AI chat class that uses OpenAI via the @ooneex/ai package.\n---\n\n# Make AI Class\n\nGenerate a new AI class and its test file using the `make:ai` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the AI class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:ai --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/ai/<Name>Ai.ts` - The AI class file (or `modules/<module>/src/ai/<Name>Ai.ts` with `--module`)\n- `tests/ai/<Name>Ai.spec.ts` - The test file (or `modules/<module>/tests/ai/<Name>Ai.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the AI class\n\nEdit `src/ai/<Name>Ai.ts` to complete the implementation:\n\n- Update the prompt in the `run` method from `\"My prompt\"` to a meaningful prompt based on the class purpose\n- Update the prompt in the `runStream` method from `\"My prompt\"` to a meaningful prompt based on the class purpose\n- Add any additional configuration or methods relevant to the AI class purpose\n- Ensure proper typing for the `run<T>()` generic return type\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator, type IAiChat, OpenAi, type OpenAiConfigType } from \"@ooneex/ai\";\nimport { inject } from \"@ooneex/container\";\n\n@decorator.ai()\nexport class <Name>Ai implements IAiChat<OpenAiConfigType> {\n constructor(@inject(OpenAi) private readonly ai: OpenAi) {}\n\n public async run<T>(prompt?: string, config?: Omit<OpenAiConfigType, \"prompt\">): Promise<T> {\n return this.ai.run<T>(prompt || \"My prompt\", config);\n }\n\n public async *runStream(\n prompt?: string,\n config?: Omit<OpenAiConfigType, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n yield* this.ai.runStream(prompt || \"My prompt\", config);\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/ai/<Name>Ai.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, run method, runStream method)\n- Add tests relevant to the specific AI class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Ai } from \"@/ai/<Name>Ai\";\n\ndescribe(\"<Name>Ai\", () => {\n test(\"should have class name ending with 'Ai'\", () => {\n expect(<Name>Ai.name.endsWith(\"Ai\")).toBe(true);\n });\n\n test(\"should have 'run' method\", () => {\n expect(<Name>Ai.prototype.run).toBeDefined();\n expect(typeof <Name>Ai.prototype.run).toBe(\"function\");\n });\n\n test(\"should have 'runStream' method\", () => {\n expect(<Name>Ai.prototype.runStream).toBeDefined();\n expect(typeof <Name>Ai.prototype.runStream).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/ai/<Name>Ai.ts tests/ai/<Name>Ai.spec.ts\n```\n";var $r="---\nname: make:analytics\ndescription: Generate a new analytics class with its test file, then complete the generated code. Use when creating a new analytics tracking class that uses the @ooneex/analytics package.\n---\n\n# Make Analytics Class\n\nGenerate a new analytics class and its test file using the `make:analytics` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the analytics class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:analytics --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/analytics/<Name>Analytics.ts` - The analytics class file (or `modules/<module>/src/analytics/<Name>Analytics.ts` with `--module`)\n- `tests/analytics/<Name>Analytics.spec.ts` - The test file (or `modules/<module>/tests/analytics/<Name>Analytics.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the analytics class\n\nEdit `src/analytics/<Name>Analytics.ts` to complete the implementation:\n\n- Implement the `capture` method with actual analytics tracking logic\n- Define a proper type for `CaptureOptionsType` instead of `Record<string, unknown>` based on the analytics purpose\n- Add any additional methods or properties relevant to the analytics class purpose\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator } from \"@ooneex/analytics\";\nimport type { IAnalytics } from \"@ooneex/analytics\";\n\ntype CaptureOptionsType = Record<string, unknown>;\n\n@decorator.analytics()\nexport class <Name>Analytics<T extends CaptureOptionsType = CaptureOptionsType> implements IAnalytics<T> {\n public capture(options: T): void {\n // console.log(\"Analytics captured:\", options);\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/analytics/<Name>Analytics.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, capture method)\n- Add tests relevant to the specific analytics class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Analytics } from \"@/analytics/<Name>Analytics\";\n\ndescribe(\"<Name>Analytics\", () => {\n test(\"should have class name ending with 'Analytics'\", () => {\n expect(<Name>Analytics.name.endsWith(\"Analytics\")).toBe(true);\n });\n\n test(\"should have 'capture' method\", () => {\n expect(<Name>Analytics.prototype.capture).toBeDefined();\n expect(typeof <Name>Analytics.prototype.capture).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/analytics/<Name>Analytics.ts tests/analytics/<Name>Analytics.spec.ts\n```\n";var qr="---\nname: make:cache\ndescription: Generate a new cache adapter class with its test file, then complete the generated code. Use when creating a new cache adapter that implements the ICache interface from @ooneex/cache.\n---\n\n# Make Cache Class\n\nGenerate a new cache class and its test file using the `make:cache` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the cache class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:cache --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/cache/<Name>Cache.ts` - The cache class file (or `modules/<module>/src/cache/<Name>Cache.ts` with `--module`)\n- `tests/cache/<Name>Cache.spec.ts` - The test file (or `modules/<module>/tests/cache/<Name>Cache.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the cache class\n\nEdit `src/cache/<Name>Cache.ts` to complete the implementation:\n\n- Implement the `get` method to retrieve cached values by key\n- Implement the `set` method to store values with optional TTL\n- Implement the `delete` method to remove cached entries\n- Implement the `has` method to check key existence\n- Replace the `CacheException` throws with actual cache logic\n- Inject any required dependencies (e.g., Redis client) via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { CacheException, decorator } from \"@ooneex/cache\";\nimport type { ICache } from \"@ooneex/cache\";\n\n@decorator.cache()\nexport class <Name>Cache implements ICache {\n public async get<T = unknown>(key: string): Promise<T | undefined> {\n throw new CacheException(`Failed to get key \"${key}\": Not implemented`);\n }\n\n public async set<T = unknown>(key: string, value: T, ttl?: number): Promise<void> {\n throw new CacheException(`Failed to set key \"${key}\": Not implemented`);\n }\n\n public async delete(key: string): Promise<boolean> {\n throw new CacheException(`Failed to delete key \"${key}\": Not implemented`);\n }\n\n public async has(key: string): Promise<boolean> {\n throw new CacheException(`Failed to check if key \"${key}\" exists: Not implemented`);\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/cache/<Name>Cache.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, get, set, delete, has methods)\n- Add tests relevant to the specific cache class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Cache } from \"@/cache/<Name>Cache\";\n\ndescribe(\"<Name>Cache\", () => {\n test(\"should have class name ending with 'Cache'\", () => {\n expect(<Name>Cache.name.endsWith(\"Cache\")).toBe(true);\n });\n\n test(\"should have 'get' method\", () => {\n expect(<Name>Cache.prototype.get).toBeDefined();\n expect(typeof <Name>Cache.prototype.get).toBe(\"function\");\n });\n\n test(\"should have 'set' method\", () => {\n expect(<Name>Cache.prototype.set).toBeDefined();\n expect(typeof <Name>Cache.prototype.set).toBe(\"function\");\n });\n\n test(\"should have 'delete' method\", () => {\n expect(<Name>Cache.prototype.delete).toBeDefined();\n expect(typeof <Name>Cache.prototype.delete).toBe(\"function\");\n });\n\n test(\"should have 'has' method\", () => {\n expect(<Name>Cache.prototype.has).toBeDefined();\n expect(typeof <Name>Cache.prototype.has).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/cache/<Name>Cache.ts tests/cache/<Name>Cache.spec.ts\n```\n";var Wr="---\nname: make:controller\ndescription: Generate a new controller class with route type and test file, then complete the generated code. Use when creating a new HTTP or WebSocket controller with routing, validation, and role-based access.\n---\n\n# Make Controller Class\n\nGenerate a new controller class, its route type, and test file using the `make:controller` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the controller class and related files:\n\n```bash\nbunx @ooneex/cli@latest make:controller --name <name> --module <module> --is-socket <true|false> --route.name <route.name> --route.path <route.path> --route.method <route.method>\n```\n\nWhere:\n- `<name>` is the controller name provided by the user\n- `--module` is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root\n- `--is-socket` determines HTTP vs WebSocket controller (defaults to `false`)\n- `--route.name` is the route name using dot notation: `<resource>.<action>` (e.g., `user.create`, `book.list`, `flashcard.delete`)\n- `--route.path` is the route path (e.g., `/api/users`)\n- `--route.method` is the HTTP method (e.g., `get`, `post`, `put`, `patch`, `delete`) \u2014 only for HTTP controllers\n\nThe command will generate (paths prefixed with `modules/<module>/` when `--module` is provided):\n- `src/controllers/<Name>Controller.ts` - The controller class file\n- `src/types/routes/<route.name>.ts` - The route type file (will be moved into the controller file \u2014 see step 3)\n- `tests/controllers/<Name>Controller.spec.ts` - The test file\n\n### 2. Read the generated files\n\nRead all three generated files to understand the scaffolded code.\n\n### 3. Complete the route type\n\n**IMPORTANT: Keep the route type inside the controller file**, not in a separate type file. Define the type directly in `src/controllers/<Name>Controller.ts` above the class definition. Delete the generated `src/types/routes/<route.name>.ts` file if it was created.\n\n**Remove unnecessary `params`, `payload`, and `queries` \u2014 only include what the route actually needs:**\n\n- **`params`** \u2014 Include only when the route path contains dynamic segments (e.g., `/api/users/:id`). Remove entirely for routes with no URL parameters (e.g., `/api/users`).\n- **`payload`** \u2014 Include only for methods that accept a request body (`post`, `put`, `patch`). Remove entirely for `get` and `delete` routes.\n- **`queries`** \u2014 Include only when the route supports query string filtering, pagination, or sorting (e.g., list/search endpoints). Remove entirely when not needed.\n- **`response`** \u2014 Always include.\n\nThe route type structure follows this pattern (remove unused sections):\n\n```typescript\n// Example: GET /api/users (list) \u2014 no params, no payload, has queries\ntype <TypeName>RouteType = {\n queries: {\n\n },\n response: {\n\n },\n};\n\n// Example: POST /api/users (create) \u2014 no params, has payload, no queries\ntype <TypeName>RouteType = {\n payload: {\n\n },\n response: {\n\n },\n};\n\n// Example: GET /api/users/:id (detail) \u2014 has params, no payload, no queries\ntype <TypeName>RouteType = {\n params: {\n\n },\n response: {\n\n },\n};\n\n// Example: PUT /api/users/:id (update) \u2014 has params, has payload, no queries\ntype <TypeName>RouteType = {\n params: {\n\n },\n payload: {\n\n },\n response: {\n\n },\n};\n```\n\n### 4. Complete the controller class\n\nEdit `src/controllers/<Name>Controller.ts` to complete the implementation:\n\n- Set appropriate `roles` for access control\n- Add a meaningful `description` for the route that explains what the endpoint does (e.g., `\"Create a new user account\"`, `\"List all books with pagination\"`)\n- **Keep the controller thin** \u2014 do NOT put business logic in the controller. Put all logic in the corresponding service and inject the service into the controller via the constructor. The controller's `index` method should only delegate to the service.\n- **Remove unnecessary `params`, `payload`, and `queries`** from both the route type and the `@Route` decorator \u2014 only include what the route actually needs (see step 3 rules).\n\n**Add or remove `params`, `payload`, and `queries` in the `@Route` decorator to match the route type (step 3):**\n\n- **`params`** \u2014 Include with `Assert()` validators only when the route has URL parameters. Remove the `params` key entirely otherwise.\n- **`payload`** \u2014 Include with `Assert({...})` only for `post`, `put`, `patch` methods. Remove the `payload` key entirely for `get` and `delete`.\n- **`queries`** \u2014 Include with `Assert({...})` only when query parameters are expected. Remove the `queries` key entirely otherwise.\n- **`response`** \u2014 Always include with `Assert({...})`.\n\n**HTTP controller** generated structure (remove `params`, `payload`, `queries` as needed \u2014 see rules above):\n\n```typescript\nimport type { ContextType } from \"@ooneex/controller\";\nimport { ERole } from \"@ooneex/role\";\nimport { Route } from \"@ooneex/routing\";\nimport { Assert } from \"@ooneex/validation\";\n\ntype <TypeName>RouteType = {\n // Only include params, payload, queries as needed (see step 3)\n response: {\n\n },\n};\n\n@Route.<method>(\"<route.path>\", {\n name: \"<route.name>\",\n version: 1,\n description: \"\",\n // Only include params, payload, queries as needed (see step 3)\n response: Assert({\n\n }),\n roles: [ERole.USER],\n})\nexport class <Name>Controller {\n public async index(context: ContextType<<TypeName>RouteType>) {\n return context.response.json({\n\n });\n }\n}\n```\n\n**Socket controller** generated structure (remove `params`, `payload`, `queries` as needed \u2014 see rules above):\n\n```typescript\nimport type { ContextType } from \"@ooneex/socket\";\nimport { ERole } from \"@ooneex/role\";\nimport { Route } from \"@ooneex/routing\";\nimport { Assert } from \"@ooneex/validation\";\n\ntype <TypeName>RouteType = {\n // Only include params, payload, queries as needed (see step 3)\n response: {\n\n },\n};\n\n@Route.socket(\"<route.path>\", {\n name: \"<route.name>\",\n version: 1,\n description: \"\",\n // Only include params, payload, queries as needed (see step 3)\n response: Assert({\n\n }),\n roles: [ERole.USER],\n})\nexport class <Name>Controller {\n public async index(context: ContextType<<TypeName>RouteType>) {\n return context.response.json({\n\n });\n }\n}\n```\n\n### 5. Complete the test file\n\nEdit `tests/controllers/<Name>Controller.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, index method)\n- Add tests relevant to the specific controller behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Controller } from \"@/controllers/<Name>Controller\";\n\ndescribe(\"<Name>Controller\", () => {\n test(\"should have class name ending with 'Controller'\", () => {\n expect(<Name>Controller.name.endsWith(\"Controller\")).toBe(true);\n });\n\n test(\"should have 'index' method\", () => {\n expect(<Name>Controller.prototype.index).toBeDefined();\n expect(typeof <Name>Controller.prototype.index).toBe(\"function\");\n });\n});\n```\n\n### 6. Register the controller in the module\n\nAdd the new controller to the module's `controllers` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Controller } from \"./controllers/<Name>Controller\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [<Name>Controller],\n entities: [],\n permissions: [],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other controllers registered, append the new controller to the existing `controllers` array and add the import alongside existing imports.\n\n### 7. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/controllers/<Name>Controller.ts tests/controllers/<Name>Controller.spec.ts\n```\n\n### 8. Create the service\n\nAfter the controller is created, generate a service class for the controller's business logic using the `make:service` skill:\n\n```\n/make:service --name <Name>\n```\n\nWhere `<Name>` matches the controller name (e.g., if the controller is `CreateUserController`, the service is `CreateUserService`).\n\n### 9. Create the pubsub event\n\nAfter the service is created, generate a pubsub event class for the controller's domain events using the `make:pubsub` skill:\n\n```\n/make:pubsub --name <Name> --channel <resource>.<action>\n```\n\nWhere:\n- `<Name>` matches the controller name (e.g., if the controller is `CreateUserController`, the event is `CreateUserEvent`)\n- `<resource>.<action>` follows the same dot notation as the route name (e.g., `user.create`, `book.delete`)\n\nOnce the event is created:\n- Inject the **service** into the **event** via the constructor, and call the service's `execute` method from the event's `handler` method.\n- Inject the **event** into the **controller** via the constructor, and publish the event from the controller's `index` method.\n";var Fr="---\nname: make:cron\ndescription: Generate a new cron job class with its test file, then complete the generated code. Use when creating a new scheduled task that extends the Cron base class from @ooneex/cron.\n---\n\n# Make Cron Class\n\nGenerate a new cron class and its test file using the `make:cron` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the cron class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:cron --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/cron/<Name>Cron.ts` - The cron class file (or `modules/<module>/src/cron/<Name>Cron.ts` with `--module`)\n- `tests/cron/<Name>Cron.spec.ts` - The test file (or `modules/<module>/tests/cron/<Name>Cron.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the cron class\n\nEdit `src/cron/<Name>Cron.ts` to complete the implementation:\n\n- Set the appropriate cron schedule in `getTime()` (e.g., `\"every 5 minutes\"`, `\"every 1 hours\"`, `\"every 30 seconds\"`)\n- Set the timezone in `getTimeZone()` if needed, or keep `null` for server timezone\n- Implement the `handler()` method with the actual cron job logic\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { TimeZoneType } from \"@ooneex/country\";\nimport type { CronTimeType } from \"@ooneex/cron\";\nimport { Cron, decorator } from \"@ooneex/cron\";\n\n@decorator.cron()\nexport class <Name>Cron extends Cron {\n public getTime(): CronTimeType {\n // Examples: \"every 5 minutes\", \"every 1 hours\", \"every 30 seconds\"\n return \"every 1 hours\";\n }\n\n public getTimeZone(): TimeZoneType | null {\n // Return null to use server timezone, or specify a timezone like \"Europe/Paris\"\n return null;\n }\n\n public async handler(): Promise<void> {\n // Implement your cron handler logic here\n // console.log(\"<Name>Cron handler executed\");\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/cron/<Name>Cron.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getTime, getTimeZone, handler methods)\n- Add tests relevant to the specific cron class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Cron } from \"@/cron/<Name>Cron\";\n\ndescribe(\"<Name>Cron\", () => {\n test(\"should have class name ending with 'Cron'\", () => {\n expect(<Name>Cron.name.endsWith(\"Cron\")).toBe(true);\n });\n\n test(\"should have 'getTime' method\", () => {\n expect(<Name>Cron.prototype.getTime).toBeDefined();\n expect(typeof <Name>Cron.prototype.getTime).toBe(\"function\");\n });\n\n test(\"should have 'getTimeZone' method\", () => {\n expect(<Name>Cron.prototype.getTimeZone).toBeDefined();\n expect(typeof <Name>Cron.prototype.getTimeZone).toBe(\"function\");\n });\n\n test(\"should have 'handler' method\", () => {\n expect(<Name>Cron.prototype.handler).toBeDefined();\n expect(typeof <Name>Cron.prototype.handler).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the cron job in the module\n\nAdd the new cron job to the module's `cronJobs` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Cron } from \"./cron/<Name>Cron\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [],\n middlewares: [],\n cronJobs: [<Name>Cron],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other cron jobs registered, append the new cron job to the existing `cronJobs` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/cron/<Name>Cron.ts tests/cron/<Name>Cron.spec.ts\n```\n";var Kr="---\nname: make:database\ndescription: Generate a new database class with its test file, then complete the generated code. Use when creating a new database adapter that extends TypeormDatabase from @ooneex/database.\n---\n\n# Make Database Class\n\nGenerate a new database class and its test file using the `make:database` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the database class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:database --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/databases/<Name>Database.ts` - The database class file (or `modules/<module>/src/databases/<Name>Database.ts` with `--module`)\n- `tests/databases/<Name>Database.spec.ts` - The test file (or `modules/<module>/tests/databases/<Name>Database.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the database class\n\nEdit `src/databases/<Name>Database.ts` to complete the implementation:\n\n- Add entity imports and register them in the `entities` array\n- Adjust the database path if needed (default is `\"var/db\"`)\n- Configure DataSource options as appropriate (type, synchronize, etc.)\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { DataSource } from \"typeorm\";\nimport { TypeormDatabase, DatabaseException, decorator } from \"@ooneex/database\";\n\n@decorator.database()\nexport class <Name>Database extends TypeormDatabase {\n public getSource(database?: string): DataSource {\n database = database || \"var/db\";\n\n this.source = new DataSource({\n synchronize: false,\n entities: [\n // TODO: Load your entities here\n ],\n enableWAL: true,\n busyErrorRetry: 2000,\n busyTimeout: 30_000,\n database,\n type: \"sqlite\",\n });\n\n return this.source;\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/databases/<Name>Database.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getSource method)\n- Add tests relevant to the specific database class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Database } from \"@/databases/<Name>Database\";\n\ndescribe(\"<Name>Database\", () => {\n test(\"should have class name ending with 'Database'\", () => {\n expect(<Name>Database.name.endsWith(\"Database\")).toBe(true);\n });\n\n test(\"should have 'getSource' method\", () => {\n expect(<Name>Database.prototype.getSource).toBeDefined();\n expect(typeof <Name>Database.prototype.getSource).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/databases/<Name>Database.ts tests/databases/<Name>Database.spec.ts\n```\n";var Hr="---\nname: make:entity\ndescription: Generate a new TypeORM entity class with its test file, then complete the generated code. Use when creating a new database entity with columns, relations, and table mapping.\n---\n\n# Make Entity Class\n\nGenerate a new entity class and its test file using the `make:entity` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the entity class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:entity --name <name> --module <module> --table-name <table_name>\n```\n\nWhere `<name>` is the name provided by the user. The `--table-name` option is optional \u2014 if omitted, it defaults to the snake_case pluralized form of the name (e.g., `UserProfile` becomes `user_profiles`). The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/entities/<Name>Entity.ts` - The entity class file (or `modules/<module>/src/entities/<Name>Entity.ts` with `--module`)\n- `tests/entities/<Name>Entity.spec.ts` - The test file (or `modules/<module>/tests/entities/<Name>Entity.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the entity class\n\nEdit `src/entities/<Name>Entity.ts` to complete the implementation:\n\n- Add entity-specific columns with appropriate TypeORM decorators (`@Column`)\n- Add relations if needed (`@ManyToOne`, `@OneToMany`, `@ManyToMany`, etc.)\n- Remove any scaffolded columns that are not relevant to the entity\n- Adjust column types, lengths, and constraints as needed\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { LocaleType } from \"@ooneex/translation\";\nimport { random } from \"@ooneex/utils\";\nimport { Column, CreateDateColumn, DeleteDateColumn, PrimaryColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({\n name: \"<table_name>\",\n})\nexport class <Name>Entity extends BaseEntity {\n @PrimaryColumn({ name: \"id\", type: \"varchar\", length: 25 })\n id: string = random.nanoid(25);\n\n @Column({\n name: \"is_locked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isLocked?: boolean;\n\n @Column({ name: \"locked_at\", type: \"timestamptz\", nullable: true })\n lockedAt?: Date;\n\n @Column({\n name: \"is_blocked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isBlocked?: boolean;\n\n @Column({ name: \"blocked_at\", type: \"timestamptz\", nullable: true })\n blockedAt?: Date;\n\n @Column({ name: \"block_reason\", type: \"text\", nullable: true })\n blockReason?: string;\n\n @Column({ name: \"is_public\", type: \"boolean\", default: true, nullable: true })\n isPublic?: boolean;\n\n @Column({ name: \"lang\", type: \"varchar\", length: 10, nullable: true })\n lang?: LocaleType;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt?: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt?: Date;\n\n @DeleteDateColumn({ name: \"deleted_at\" })\n deletedAt?: Date;\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/entities/<Name>Entity.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, id, default columns)\n- Add tests for any new entity-specific columns and relations\n- Update tests if scaffolded columns were removed\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Entity } from \"@/entities/<Name>Entity\";\n\ndescribe(\"<Name>Entity\", () => {\n test(\"should have class name ending with 'Entity'\", () => {\n expect(<Name>Entity.name.endsWith(\"Entity\")).toBe(true);\n });\n\n test(\"should have 'id' property with default nanoid\", () => {\n const entity = new <Name>Entity();\n expect(entity.id).toBeDefined();\n expect(typeof entity.id).toBe(\"string\");\n expect(entity.id.length).toBe(25);\n });\n\n test(\"should have 'isLocked' property\", () => {\n const entity = new <Name>Entity();\n expect(\"isLocked\" in entity).toBe(true);\n });\n\n // ... additional property tests\n});\n```\n\n### 5. Register the entity in the module\n\nAdd the new entity to the module's `entities` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Entity } from \"./entities/<Name>Entity\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [<Name>Entity],\n permissions: [],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other entities registered, append the new entity to the existing `entities` array and add the import alongside existing imports.\n\n### 6. Create a migration for the entity\n\nAfter creating or updating an entity, generate a migration to apply the corresponding schema changes to the database.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:migration\n```\n\nThen read the generated migration file in `src/migrations/` and complete it:\n\n- In the `up` method, write the SQL to create the table (or alter it if updating an existing entity). Include all columns, types, constraints, defaults, and indexes matching the entity definition.\n- In the `down` method, write the reverse SQL to undo the changes (e.g., `DROP TABLE` or `ALTER TABLE DROP COLUMN`).\n- If the migration depends on another migration (e.g., a foreign key referencing another table), add that migration class to the `getDependencies()` return array.\n\nExample `up` method for a new entity:\n\n```typescript\npublic async up(tx: TransactionSQL): Promise<void> {\n await tx`\n CREATE TABLE IF NOT EXISTS <table_name> (\n id VARCHAR(25) PRIMARY KEY,\n is_locked BOOLEAN DEFAULT false,\n locked_at TIMESTAMPTZ,\n is_blocked BOOLEAN DEFAULT false,\n blocked_at TIMESTAMPTZ,\n block_reason TEXT,\n is_public BOOLEAN DEFAULT true,\n lang VARCHAR(10),\n created_at TIMESTAMPTZ DEFAULT NOW(),\n updated_at TIMESTAMPTZ DEFAULT NOW(),\n deleted_at TIMESTAMPTZ\n )\n `;\n}\n```\n\n### 7. Create a repository for the entity\n\nAfter creating the entity, generate a repository to handle database operations for it.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name <name>\n```\n\nWhere `<name>` is the same name used for the entity. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class\n- `tests/repositories/<Name>Repository.spec.ts` - The test file\n\nThen read the generated files and complete the repository implementation:\n\n- Adjust search fields in the `find()` method to match the entity's searchable columns\n- Customize relations loading in `findOne`/`findOneBy` if the entity has relations\n- Add any domain-specific methods relevant to the entity\n- Remove methods that don't apply to the entity\n- Update tests to match the final repository methods\n\n### 8. Lint and format\n\nRun linting and formatting on all generated files:\n\n```bash\nbunx biome check --fix src/entities/<Name>Entity.ts tests/entities/<Name>Entity.spec.ts src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts src/migrations/\n```\n";var Vr="---\nname: make:logger\ndescription: Generate a new logger class with its test file, then complete the generated code. Use when creating a new logger that implements the ILogger interface from @ooneex/logger.\n---\n\n# Make Logger Class\n\nGenerate a new logger class and its test file using the `make:logger` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the logger class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:logger --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/loggers/<Name>Logger.ts` - The logger class file (or `modules/<module>/src/loggers/<Name>Logger.ts` with `--module`)\n- `tests/loggers/<Name>Logger.spec.ts` - The test file (or `modules/<module>/tests/loggers/<Name>Logger.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the logger class\n\nEdit `src/loggers/<Name>Logger.ts` to complete the implementation:\n\n- Implement the `init()` method to set up the logger (e.g., open file handles, configure transports)\n- Implement `log`, `debug`, `info`, `success`, `warn`, and `error` methods with actual logging logic\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { IException } from \"@ooneex/exception\";\nimport type { ILogger } from \"@ooneex/logger\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { decorator } from \"@ooneex/logger\";\n\n@decorator.logger()\nexport class <Name>Logger implements ILogger {\n public async init(): Promise<void> {\n // Initialize your logger here\n }\n\n public log(message: string, data?: Record<string, ScalarType>): void {\n // Handle general logging\n }\n\n public debug(message: string, data?: Record<string, ScalarType>): void {\n // Handle debug logging\n }\n\n public info(message: string, data?: Record<string, ScalarType>): void {\n // Handle info logging\n }\n\n public success(message: string, data?: Record<string, ScalarType>): void {\n // Handle success logging\n }\n\n public warn(message: string, data?: Record<string, ScalarType>): void {\n // Handle warning logging\n }\n\n public error(message: string | IException, data?: Record<string, ScalarType>): void {\n // Handle error logging\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/loggers/<Name>Logger.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, init, log, debug, info, success, warn, error methods)\n- Add tests relevant to the specific logger class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Logger } from \"@/loggers/<Name>Logger\";\n\ndescribe(\"<Name>Logger\", () => {\n test(\"should have class name ending with 'Logger'\", () => {\n expect(<Name>Logger.name.endsWith(\"Logger\")).toBe(true);\n });\n\n test(\"should have 'init' method\", () => {\n expect(<Name>Logger.prototype.init).toBeDefined();\n expect(typeof <Name>Logger.prototype.init).toBe(\"function\");\n });\n\n test(\"should have 'log' method\", () => {\n expect(<Name>Logger.prototype.log).toBeDefined();\n expect(typeof <Name>Logger.prototype.log).toBe(\"function\");\n });\n\n test(\"should have 'debug' method\", () => {\n expect(<Name>Logger.prototype.debug).toBeDefined();\n expect(typeof <Name>Logger.prototype.debug).toBe(\"function\");\n });\n\n test(\"should have 'info' method\", () => {\n expect(<Name>Logger.prototype.info).toBeDefined();\n expect(typeof <Name>Logger.prototype.info).toBe(\"function\");\n });\n\n test(\"should have 'success' method\", () => {\n expect(<Name>Logger.prototype.success).toBeDefined();\n expect(typeof <Name>Logger.prototype.success).toBe(\"function\");\n });\n\n test(\"should have 'warn' method\", () => {\n expect(<Name>Logger.prototype.warn).toBeDefined();\n expect(typeof <Name>Logger.prototype.warn).toBe(\"function\");\n });\n\n test(\"should have 'error' method\", () => {\n expect(<Name>Logger.prototype.error).toBeDefined();\n expect(typeof <Name>Logger.prototype.error).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/loggers/<Name>Logger.ts tests/loggers/<Name>Logger.spec.ts\n```\n";var zr="---\nname: make:mailer\ndescription: Generate a new mailer class with its template and test files, then complete the generated code. Use when creating a new email sender with JSX template using @ooneex/mailer.\n---\n\n# Make Mailer Class\n\nGenerate a new mailer class, its JSX template, and test files using the `make:mailer` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the mailer class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:mailer --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate (paths prefixed with `modules/<module>/` when `--module` is provided):\n- `src/mailers/<Name>Mailer.ts` - The mailer class file\n- `src/mailers/<Name>MailerTemplate.tsx` - The JSX email template\n- `tests/mailers/<Name>Mailer.spec.ts` - The mailer test file\n- `tests/mailers/<Name>MailerTemplate.spec.ts` - The template test file\n\n### 2. Read the generated files\n\nRead all four generated files to understand the scaffolded code.\n\n### 3. Complete the mailer class\n\nEdit `src/mailers/<Name>Mailer.ts` to complete the implementation:\n\n- Adjust the `send` method config type if additional parameters are needed\n- Add any pre-send logic (validation, data transformation, etc.)\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { IMailer } from \"@ooneex/mailer\";\nimport { type <Name>MailerPropsType, <Name>MailerTemplate } from \"./<Name>MailerTemplate\";\n\nexport class <Name>Mailer implements IMailer {\n constructor(\n @inject(\"mailer\")\n private readonly mailer: IMailer,\n ) {}\n\n public send = async (config: {\n to: string[];\n subject: string;\n from?: { name: string; address: string };\n data?: <Name>MailerPropsType;\n }): Promise<void> => {\n const { data, ...rest } = config;\n\n await this.mailer.send({\n ...rest,\n content: <Name>MailerTemplate(data),\n });\n };\n}\n```\n\n### 4. Complete the mailer template\n\nEdit `src/mailers/<Name>MailerTemplate.tsx` to complete the implementation:\n\n- Update `<Name>MailerPropsType` with the actual props needed for the email\n- Build the email body using `MailerLayout` components (Header, Body, Footer)\n- Add email content, styling, and dynamic data rendering\n\nThe generated template structure follows this pattern:\n\n```tsx\nimport { MailerLayout } from \"@ooneex/mailer\";\n\nexport type <Name>MailerPropsType = {\n link: string;\n};\n\nexport const <Name>MailerTemplate = (props?: <Name>MailerPropsType) => (\n <MailerLayout>\n <MailerLayout.Header />\n <MailerLayout.Body>\n <a href={props?.link}>Login</a>\n </MailerLayout.Body>\n <MailerLayout.Footer />\n </MailerLayout>\n);\n```\n\n### 5. Complete the test files\n\nEdit `tests/mailers/<Name>Mailer.spec.ts` and `tests/mailers/<Name>MailerTemplate.spec.ts` to add meaningful tests beyond the scaffolded ones.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/mailers/<Name>Mailer.ts src/mailers/<Name>MailerTemplate.tsx tests/mailers/<Name>Mailer.spec.ts tests/mailers/<Name>MailerTemplate.spec.ts\n```\n";var Yr="---\nname: make:middleware\ndescription: Generate a new middleware class with its test file, then complete the generated code. Use when creating a new HTTP or WebSocket middleware that implements IMiddleware from @ooneex/middleware.\n---\n\n# Make Middleware Class\n\nGenerate a new middleware class and its test file using the `make:middleware` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the middleware class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:middleware --name <name> --module <module> --is-socket <true|false>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The `--is-socket` option determines whether to generate an HTTP middleware or a WebSocket middleware (defaults to `false` if omitted). The command will generate:\n- `src/middlewares/<Name>Middleware.ts` - The middleware class file (or `modules/<module>/src/middlewares/<Name>Middleware.ts` with `--module`)\n- `tests/middlewares/<Name>Middleware.spec.ts` - The test file (or `modules/<module>/tests/middlewares/<Name>Middleware.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the middleware class\n\nEdit `src/middlewares/<Name>Middleware.ts` to complete the implementation:\n\n- Implement the `handler` method with actual middleware logic\n- Add request/response transformations, authentication checks, logging, etc.\n- Inject any required dependencies via the constructor\n\n**HTTP middleware** generated structure:\n\n```typescript\nimport type { ContextType } from \"@ooneex/controller\";\nimport { decorator, type IMiddleware } from \"@ooneex/middleware\";\n\n@decorator.middleware()\nexport class <Name>Middleware implements IMiddleware {\n public async handler(context: ContextType): Promise<ContextType> {\n // Example: Add custom header\n // context.response.header(\"X-Custom-Header\", \"value\");\n\n return context\n }\n}\n```\n\n**Socket middleware** generated structure:\n\n```typescript\nimport type { ContextType } from \"@ooneex/socket\";\nimport { decorator, type IMiddleware } from \"@ooneex/middleware\";\n\n@decorator.middleware()\nexport class <Name>Middleware implements IMiddleware {\n public async handler(context: ContextType): Promise<ContextType> {\n // Example: Add custom header\n // context.response.header(\"X-Custom-Header\", \"value\");\n\n return context\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/middlewares/<Name>Middleware.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, handler method)\n- Add tests relevant to the specific middleware behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Middleware } from \"@/middlewares/<Name>Middleware\";\n\ndescribe(\"<Name>Middleware\", () => {\n test(\"should have class name ending with 'Middleware'\", () => {\n expect(<Name>Middleware.name.endsWith(\"Middleware\")).toBe(true);\n });\n\n test(\"should have 'handler' method\", () => {\n expect(<Name>Middleware.prototype.handler).toBeDefined();\n expect(typeof <Name>Middleware.prototype.handler).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the middleware in the module\n\nAdd the new middleware to the module's `middlewares` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Middleware } from \"./middlewares/<Name>Middleware\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [],\n middlewares: [<Name>Middleware],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other middlewares registered, append the new middleware to the existing `middlewares` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/middlewares/<Name>Middleware.ts tests/middlewares/<Name>Middleware.spec.ts\n```\n";var Qr="---\nname: make:migration\ndescription: Generate a new database migration file, then complete the generated code. Use when creating a new database migration for schema changes using @ooneex/migrations.\n---\n\n# Make Migration\n\nGenerate a new migration file using the `make:migration` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the migration file:\n\n```bash\nbunx @ooneex/cli@latest make:migration --module <module>\n```\n\nThe `--module` option is optional \u2014 if provided, the migration file is generated under `modules/<module>/src/migrations/` instead of `src/migrations/`. The command will:\n- Generate a timestamped migration file in `src/migrations/` (or `modules/<module>/src/migrations/` with `--module`)\n- Add a `migration:up` script to `package.json` if not already present\n\n### 2. Read the generated file\n\nRead the generated migration file in `src/migrations/` to understand the scaffolded code.\n\n### 3. Complete the migration\n\nEdit the generated migration file to implement:\n\n- The `up` method with the schema changes (create tables, add columns, create indexes, etc.)\n- The `down` method with the reverse operations to undo the migration\n\n### 4. Lint and format\n\nRun linting and formatting on the generated file:\n\n```bash\nbunx biome check --fix src/migrations/\n```\n";var Zr="---\nname: make:permission\ndescription: Generate a new permission class with its test file, then complete the generated code. Use when creating a new permission that extends Permission from @ooneex/permission.\n---\n\n# Make Permission Class\n\nGenerate a new permission class and its test file using the `make:permission` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the permission class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:permission --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/permissions/<Name>Permission.ts` - The permission class file (or `modules/<module>/src/permissions/<Name>Permission.ts` with `--module`)\n- `tests/permissions/<Name>Permission.spec.ts` - The test file (or `modules/<module>/tests/permissions/<Name>Permission.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the permission class\n\nEdit `src/permissions/<Name>Permission.ts` to complete the implementation:\n\n- Implement the `allow()` method with permission rules using `this.ability.can()`\n- Implement the `setUserPermissions()` method with role-based permission logic\n- Define which actions (read, create, update, delete, manage) are allowed on which entities\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator, Permission } from \"@ooneex/permission\";\nimport type { IUser } from \"@ooneex/user\";\n\n@decorator.permission()\nexport class <Name>Permission extends Permission {\n public allow(): this {\n // Example: Add permissions using this.ability.can()\n // this.ability.can(\"read\", \"YourEntity\");\n // this.ability.can([\"read\", \"update\"], \"YourEntity\", { userId: user.id });\n\n return this;\n }\n\n public setUserPermissions(user: IUser | null): this {\n if (!user) {\n return this;\n }\n\n // Example: Grant full access to admins\n // const { roles } = user;\n // if (roles.includes(ERole.ADMIN)) {\n // this.ability.can(\"manage\", \"all\");\n // return this;\n // }\n\n // Example: Grant specific permissions based on roles\n // for (const role of roles) {\n // if (role === ERole.USER) {\n // this.ability.can([\"read\", \"update\"], \"YourEntity\", { userId: user.id });\n // }\n //\n // if (role === ERole.GUEST) {\n // this.ability.can(\"read\", \"YourEntity\", { public: true });\n // }\n // }\n\n return this;\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/permissions/<Name>Permission.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, extends Permission, allow, setUserPermissions methods)\n- Add tests relevant to the specific permission rules\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { Permission } from \"@ooneex/permission\";\nimport { <Name>Permission } from \"@/permissions/<Name>Permission\";\n\ndescribe(\"<Name>Permission\", () => {\n test(\"should have class name ending with 'Permission'\", () => {\n expect(<Name>Permission.name.endsWith(\"Permission\")).toBe(true);\n });\n\n test(\"should extend Permission\", () => {\n const permission = new <Name>Permission();\n expect(permission).toBeInstanceOf(Permission);\n });\n\n test(\"should have 'allow' method\", () => {\n expect(<Name>Permission.prototype.allow).toBeDefined();\n expect(typeof <Name>Permission.prototype.allow).toBe(\"function\");\n });\n\n test(\"should have 'setUserPermissions' method\", () => {\n expect(<Name>Permission.prototype.setUserPermissions).toBeDefined();\n expect(typeof <Name>Permission.prototype.setUserPermissions).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the permission in the module\n\nAdd the new permission to the module's `permissions` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Permission } from \"./permissions/<Name>Permission\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [<Name>Permission],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other permissions registered, append the new permission to the existing `permissions` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/permissions/<Name>Permission.ts tests/permissions/<Name>Permission.spec.ts\n```\n";var Xr="---\nname: make:pubsub\ndescription: Generate a new PubSub event class with its test file, then complete the generated code. Use when creating a new publish/subscribe event that extends PubSub from @ooneex/pub-sub.\n---\n\n# Make PubSub Event Class\n\nGenerate a new PubSub event class and its test file using the `make:pubsub` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the PubSub event class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:pubsub --name <name> --module <module> --channel <channel>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The `--channel` option is optional \u2014 if omitted, it defaults to the kebab-case form of the name (e.g., `UserCreated` becomes `user-created`). The command will generate:\n- `src/events/<Name>Event.ts` - The event class file (or `modules/<module>/src/events/<Name>Event.ts` with `--module`)\n- `tests/events/<Name>Event.spec.ts` - The test file (or `modules/<module>/tests/events/<Name>Event.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the PubSub event class\n\nEdit `src/events/<Name>Event.ts` to complete the implementation:\n\n- Define a proper data type instead of `Record<string, ScalarType>` for the event payload\n- Implement the `handler()` method with actual event handling logic\n- Set the appropriate channel name in `getChannel()`\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { decorator, PubSub, RedisPubSub } from \"@ooneex/pub-sub\";\n\n@decorator.pubSub()\nexport class <Name>Event<Data extends Record<string, ScalarType> = Record<string, ScalarType>> extends PubSub<Data> {\n constructor(\n @inject(RedisPubSub)\n client: RedisPubSub<Data>,\n ) {\n super(client);\n }\n\n public getChannel(): string {\n return \"<channel>\";\n }\n\n public async handler(context: { data: Data; channel: string }): Promise<void> {\n console.log(context);\n // TODO: Implement handler logic here\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/events/<Name>Event.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getChannel, handler, publish, subscribe, unsubscribe, unsubscribeAll methods)\n- Add tests relevant to the specific event behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>PubSub } from \"@/pubsub/<Name>PubSub\";\n\ndescribe(\"<Name>PubSub\", () => {\n test(\"should have class name ending with 'PubSub'\", () => {\n expect(<Name>PubSub.name.endsWith(\"PubSub\")).toBe(true);\n });\n\n test(\"should have 'getChannel' method\", () => {\n expect(<Name>PubSub.prototype.getChannel).toBeDefined();\n expect(typeof <Name>PubSub.prototype.getChannel).toBe(\"function\");\n });\n\n test(\"should have 'handler' method\", () => {\n expect(<Name>PubSub.prototype.handler).toBeDefined();\n expect(typeof <Name>PubSub.prototype.handler).toBe(\"function\");\n });\n\n test(\"should have 'publish' method\", () => {\n expect(<Name>PubSub.prototype.publish).toBeDefined();\n expect(typeof <Name>PubSub.prototype.publish).toBe(\"function\");\n });\n\n test(\"should have 'subscribe' method\", () => {\n expect(<Name>PubSub.prototype.subscribe).toBeDefined();\n expect(typeof <Name>PubSub.prototype.subscribe).toBe(\"function\");\n });\n\n test(\"should have 'unsubscribe' method\", () => {\n expect(<Name>PubSub.prototype.unsubscribe).toBeDefined();\n expect(typeof <Name>PubSub.prototype.unsubscribe).toBe(\"function\");\n });\n\n test(\"should have 'unsubscribeAll' method\", () => {\n expect(<Name>PubSub.prototype.unsubscribeAll).toBeDefined();\n expect(typeof <Name>PubSub.prototype.unsubscribeAll).toBe(\"function\");\n });\n});\n```\n\n### 5. Register the event in the module\n\nAdd the new event to the module's `events` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Event } from \"./events/<Name>Event\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [],\n permissions: [],\n middlewares: [],\n cronJobs: [],\n events: [<Name>Event],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other events registered, append the new event to the existing `events` array and add the import alongside existing imports.\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/events/<Name>Event.ts tests/events/<Name>Event.spec.ts\n```\n";var Jr="---\nname: make:repository\ndescription: Generate a new repository class with its test file, then complete the generated code. Use when creating a new TypeORM repository for database operations on an entity.\n---\n\n# Make Repository Class\n\nGenerate a new repository class and its test file using the `make:repository` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the repository class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class file (or `modules/<module>/src/repositories/<Name>Repository.ts` with `--module`)\n- `tests/repositories/<Name>Repository.spec.ts` - The test file (or `modules/<module>/tests/repositories/<Name>Repository.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the repository class\n\nEdit `src/repositories/<Name>Repository.ts` to complete the implementation:\n\n- Verify the entity import path matches the actual entity location\n- Adjust the `find` method's search fields (default searches `name` with `ILike`)\n- Customize relations loading in `findOne`/`findOneBy` if needed\n\n#### Adding methods\n\nLook at the entity's fields, relations, and business context to determine if custom domain-specific methods are needed. For example:\n- A `SessionRepository` might need `revokeSession(sessionId: string)` and `revokeAllUserSessions(userId: string)`\n- A `NotificationRepository` might need `markAsRead(id: string)` and `markAllAsRead(userId: string)`\n- Entities with status fields may need methods like `archive(id: string)` or `activate(id: string)`\n\nRead related entities, services, or actions in the module to understand what operations the repository should support, then add the appropriate methods.\n\n#### Removing methods\n\nRemove scaffolded methods that don't make sense for the entity's context:\n- Remove `createMany`/`updateMany` if the entity is always managed individually (e.g., user profiles, settings)\n- Remove `delete` if the entity uses soft deletes only (use a custom `softDelete` or `archive` method instead)\n- Remove `find` if the entity is only ever accessed by ID or specific criteria (e.g., singleton config entities)\n- Remove `count` if there's no use case for counting records of this entity\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { ITypeormDatabase } from \"@ooneex/database\";\nimport { decorator } from \"@ooneex/repository\";\nimport type { FilterResultType } from \"@ooneex/types\";\nimport type { FindManyOptions, FindOptionsWhere, Repository, SaveOptions, UpdateResult } from \"typeorm\";\nimport { ILike } from \"typeorm\";\nimport { <Name>Entity } from \"../entities/<Name>Entity\";\n\n@decorator.repository()\nexport class <Name>Repository {\n constructor(\n @inject(\"database\")\n private readonly database: ITypeormDatabase,\n ) {}\n\n public async open(): Promise<Repository<<Name>Entity>> {\n return await this.database.open(<Name>Entity);\n }\n\n public async close(): Promise<void> {\n await this.database.close();\n }\n\n public async find(\n criteria: FindManyOptions<<Name>Entity> & { page?: number; limit?: number; q?: string },\n ): Promise<FilterResultType<<Name>Entity>> {\n // ... pagination and search logic\n }\n\n public async findOne(id: string): Promise<<Name>Entity | null> { ... }\n public async findOneBy(criteria: FindOptionsWhere<<Name>Entity>): Promise<<Name>Entity | null> { ... }\n public async create(entity: <Name>Entity, options?: SaveOptions): Promise<<Name>Entity> { ... }\n public async createMany(entities: <Name>Entity[], options?: SaveOptions): Promise<<Name>Entity[]> { ... }\n public async update(entity: <Name>Entity, options?: SaveOptions): Promise<<Name>Entity> { ... }\n public async updateMany(entities: <Name>Entity[], options?: SaveOptions): Promise<<Name>Entity[]> { ... }\n public async delete(criteria: FindOptionsWhere<<Name>Entity> | FindOptionsWhere<<Name>Entity>[]): Promise<UpdateResult> { ... }\n public async count(criteria?: FindOptionsWhere<<Name>Entity> | FindOptionsWhere<<Name>Entity>[]): Promise<number> { ... }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/repositories/<Name>Repository.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep scaffolded tests for methods that remain in the repository (remove tests for methods that were removed)\n- Add tests for any custom domain-specific methods added to the repository\n- Add tests relevant to the specific repository behavior\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts\n```\n";var jr="---\nname: make:seed\ndescription: Generate a new database seed file, then complete the generated code. Use when creating seed data for populating the database using @ooneex/seeds.\n---\n\n# Make Seed\n\nGenerate a new seed file using the `make:seed` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the seed file:\n\n```bash\nbunx @ooneex/cli@latest make:seed --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, the seed file is generated under `modules/<module>/src/seeds/` instead of `src/seeds/`. The command will:\n- Generate a seed file in `src/seeds/` (or `modules/<module>/src/seeds/` with `--module`)\n- Add a `seed:run` script to `package.json` if not already present\n\n### 2. Read the generated file\n\nRead the generated seed file in `src/seeds/` to understand the scaffolded code.\n\n### 3. Complete the seed\n\nEdit the generated seed file to implement:\n\n- Import the relevant entity classes\n- Create seed data with hardcoded nanoid values for `id` fields (generate via `bun -e \"import { random } from '@ooneex/utils'; console.log(random.nanoid())\"`)\n- Do NOT use sequential IDs like `\"item-1\"`, `\"item-2\"`\n- Ensure the same entity uses the same ID everywhere it appears\n\n### 4. Lint and format\n\nRun linting and formatting on the generated file:\n\n```bash\nbunx biome check --fix src/seeds/\n```\n";var ei="---\nname: make:service\ndescription: Generate a new service class with its test file, then complete the generated code. Use when creating a new business logic service that implements IService from @ooneex/service.\n---\n\n# Make Service Class\n\nGenerate a new service class and its test file using the `make:service` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the service class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:service --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/services/<Name>Service.ts` - The service class file (or `modules/<module>/src/services/<Name>Service.ts` with `--module`)\n- `tests/services/<Name>Service.spec.ts` - The test file (or `modules/<module>/tests/services/<Name>Service.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the service class\n\nEdit `src/services/<Name>Service.ts` to complete the implementation:\n\n- Define a proper type for `ServiceDataType` instead of `Record<string, unknown>`\n- Implement the `execute()` method with actual business logic\n- Inject any required dependencies (repositories, other services, etc.) via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { decorator } from \"@ooneex/service\";\nimport type { IService } from \"@ooneex/service\";\n\ntype ServiceDataType = Record<string, unknown>;\n\n@decorator.service()\nexport class <Name>Service<T extends ServiceDataType = ServiceDataType> implements IService<T> {\n public async execute(data?: T): Promise<void> {\n // TODO: Implement service logic\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/services/<Name>Service.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, execute method)\n- Add tests relevant to the specific service behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Service } from \"@/services/<Name>Service\";\n\ndescribe(\"<Name>Service\", () => {\n test(\"should have class name ending with 'Service'\", () => {\n expect(<Name>Service.name.endsWith(\"Service\")).toBe(true);\n });\n\n test(\"should have 'execute' method\", () => {\n expect(<Name>Service.prototype.execute).toBeDefined();\n expect(typeof <Name>Service.prototype.execute).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/services/<Name>Service.ts tests/services/<Name>Service.spec.ts\n```\n";var ti="---\nname: make:storage\ndescription: Generate a new storage class with its test file, then complete the generated code. Use when creating a new S3-compatible storage adapter that extends Storage from @ooneex/storage.\n---\n\n# Make Storage Class\n\nGenerate a new storage class and its test file using the `make:storage` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the storage class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:storage --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/storage/<Name>Storage.ts` - The storage class file (or `modules/<module>/src/storage/<Name>Storage.ts` with `--module`)\n- `tests/storage/<Name>Storage.spec.ts` - The test file (or `modules/<module>/tests/storage/<Name>Storage.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the storage class\n\nEdit `src/storage/<Name>Storage.ts` to complete the implementation:\n\n- Set the `bucket` property to the appropriate bucket name\n- Verify the environment variable names match the project configuration (`STORAGE_<NAME_UPPER>_ACCESS_KEY`, `STORAGE_<NAME_UPPER>_SECRET_KEY`, `STORAGE_<NAME_UPPER>_ENDPOINT`, `STORAGE_<NAME_UPPER>_REGION`)\n- Add any additional storage-specific methods if needed\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { Storage, decorator, StorageException } from \"@ooneex/storage\";\nimport type { S3Options } from \"bun\";\n\n@decorator.storage()\nexport class <Name>Storage extends Storage {\n protected bucket: string;\n private readonly accessKey: string;\n private readonly secretKey: string;\n private readonly endpoint: string;\n private readonly region: string;\n\n constructor(options?: {\n accessKey?: string;\n secretKey?: string;\n endpoint?: string;\n region?: string;\n }) {\n super();\n\n const accessKey = options?.accessKey || Bun.env.STORAGE_<NAME_UPPER>_ACCESS_KEY;\n const secretKey = options?.secretKey || Bun.env.STORAGE_<NAME_UPPER>_SECRET_KEY;\n const endpoint = options?.endpoint || Bun.env.STORAGE_<NAME_UPPER>_ENDPOINT;\n\n // ... validation throws StorageException if missing ...\n\n this.accessKey = accessKey;\n this.secretKey = secretKey;\n this.endpoint = endpoint;\n this.region = options?.region || Bun.env.STORAGE_<NAME_UPPER>_REGION || \"auto\";\n }\n\n public getOptions(): S3Options {\n return {\n accessKeyId: this.accessKey,\n secretAccessKey: this.secretKey,\n endpoint: this.endpoint,\n bucket: this.bucket,\n region: this.region,\n };\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/storage/<Name>Storage.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, bucket field, getOptions method)\n- Add tests relevant to the specific storage class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>StorageAdapter } from \"@/storage/<Name>StorageAdapter\";\n\ndescribe(\"<Name>StorageAdapter\", () => {\n test(\"should have class name ending with 'StorageAdapter'\", () => {\n expect(<Name>StorageAdapter.name.endsWith(\"StorageAdapter\")).toBe(true);\n });\n\n test(\"should have 'bucket' field\", () => {\n expect(\"bucket\" in <Name>StorageAdapter.prototype || \"bucket\" in Object.getOwnPropertyNames(<Name>StorageAdapter.prototype)).toBe(true);\n });\n\n test(\"should have 'getOptions' method\", () => {\n expect(<Name>StorageAdapter.prototype.getOptions).toBeDefined();\n expect(typeof <Name>StorageAdapter.prototype.getOptions).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/storage/<Name>Storage.ts tests/storage/<Name>Storage.spec.ts\n```\n";var si="---\nname: make:vector-database\ndescription: Generate a new vector database class with its test file, then complete the generated code. Use when creating a new vector database that extends VectorDatabase from @ooneex/rag.\n---\n\n# Make Vector Database Class\n\nGenerate a new vector database class and its test file using the `make:vector-database` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the vector database class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:vector-database --name <name> --module <module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/databases/<Name>VectorDatabase.ts` - The vector database class file (or `modules/<module>/src/databases/<Name>VectorDatabase.ts` with `--module`)\n- `tests/databases/<Name>VectorDatabase.spec.ts` - The test file (or `modules/<module>/tests/databases/<Name>VectorDatabase.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the vector database class\n\nEdit `src/databases/<Name>VectorDatabase.ts` to complete the implementation:\n\n- Set the `getDatabaseUri()` return value to the actual LanceDB database path\n- Configure the embedding provider and model in `getEmbeddingModel()`\n- Define the custom data fields in `DataType` and map them in `getSchema()`\n- Import the appropriate Apache Arrow types for your schema fields\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { VectorDatabase, decorator } from \"@ooneex/rag\";\nimport type { EmbeddingModelType, EmbeddingProviderType, FieldValueType } from \"@ooneex/rag\";\nimport { Utf8 } from \"apache-arrow\";\n\ntype DataType = {\n name: string;\n};\n\n@decorator.vectorDatabase()\nexport class <Name>VectorDatabase extends VectorDatabase<DataType> {\n public getDatabaseUri(): string {\n return \"\";\n }\n\n public getEmbeddingModel(): { provider: EmbeddingProviderType; model: EmbeddingModelType[\"model\"] } {\n return { provider: \"openai\", model: \"text-embedding-ada-002\" };\n }\n\n public getSchema(): { [K in keyof DataType]: FieldValueType } {\n return {\n name: new Utf8(),\n };\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/databases/<Name>VectorDatabase.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getDatabaseUri, getEmbeddingModel, getSchema methods)\n- Add tests relevant to the specific vector database class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>VectorDatabase } from \"@/databases/<Name>VectorDatabase\";\n\ndescribe(\"<Name>VectorDatabase\", () => {\n test(\"should have class name ending with 'VectorDatabase'\", () => {\n expect(<Name>VectorDatabase.name.endsWith(\"VectorDatabase\")).toBe(true);\n });\n\n test(\"should have 'getDatabaseUri' method\", () => {\n expect(<Name>VectorDatabase.prototype.getDatabaseUri).toBeDefined();\n expect(typeof <Name>VectorDatabase.prototype.getDatabaseUri).toBe(\"function\");\n });\n\n test(\"should have 'getEmbeddingModel' method\", () => {\n expect(<Name>VectorDatabase.prototype.getEmbeddingModel).toBeDefined();\n expect(typeof <Name>VectorDatabase.prototype.getEmbeddingModel).toBe(\"function\");\n });\n\n test(\"should have 'getSchema' method\", () => {\n expect(<Name>VectorDatabase.prototype.getSchema).toBeDefined();\n expect(typeof <Name>VectorDatabase.prototype.getSchema).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/databases/<Name>VectorDatabase.ts tests/databases/<Name>VectorDatabase.spec.ts\n```\n";var oi="---\nname: optimize\ndescription: Optimize a module's codebase for quality, performance, and clean conventions. Enforces arrow functions (except class methods), type/interface naming, removes duplication, and ensures only important tests remain.\n---\n\n# Optimize Codebase\n\nOptimize a module's codebase for quality, performance, and clean conventions.\n\n## Coding Conventions\n\nApply these conventions across all files in the target module:\n\n- **Arrow functions everywhere** \u2014 use arrow functions for all function expressions, callbacks, standalone functions, and variable declarations. The ONLY exception is class methods, which must use regular method syntax.\n- **Type naming** \u2014 all type aliases must end with the `Type` suffix (e.g., `UserDataType`, `ConfigOptionsType`). Rename any that don't comply.\n- **Interface naming** \u2014 all interface names must start with the `I` prefix (e.g., `IUser`, `IService`, `IRepository`). Rename any that don't comply.\n- **No definite assignment assertions** \u2014 never use `!` on class properties (e.g., `email!: string`). Use a default value or make the property optional (`?`) instead.\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`).\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Identify the target\n\nDetermine the module to optimize. If the user specifies a module name, work in `modules/<module>/`. If no module is specified, ask the user which module to optimize.\n\n### 2. Read and analyze the module\n\nRead all source files (`src/**/*.ts`) and test files (`tests/**/*.ts`) in the target module. Build a full picture of:\n\n- All types, interfaces, classes, and functions\n- Dependencies between files\n- Existing test coverage\n\n### 3. Enforce naming conventions\n\nScan every file and fix:\n\n- **Types not ending with `Type`** \u2014 rename the type and update all references across the module\n- **Interfaces not starting with `I`** \u2014 rename the interface and update all references across the module\n- **Non-arrow functions** \u2014 convert all function expressions, callbacks, and standalone functions to arrow functions. Do NOT convert class methods.\n- **Missing visibility modifiers** \u2014 add explicit `public`, `private`, or `protected` to all class methods and properties\n\n### 4. Remove code duplication\n\nIdentify duplicated or near-duplicated code within the module:\n\n- Extract shared logic into well-named helper arrow functions or base classes\n- Consolidate repeated type definitions\n- Merge similar utility functions\n- Remove dead code (unused imports, unreachable branches, unused variables)\n\n### 5. Optimize for performance\n\nReview and improve:\n\n- Replace inefficient loops or repeated iterations with single-pass approaches where possible\n- Use `Map`/`Set` instead of arrays for lookups when appropriate\n- Avoid unnecessary object spreads or deep clones\n- Prefer early returns to reduce nesting\n- Remove unnecessary `async`/`await` where a direct return suffices\n- Eliminate redundant null/undefined checks when the type system already guarantees the value\n\n### 6. Optimize tests\n\nReview all test files and restructure:\n\n- **Remove trivial tests** \u2014 delete tests that only check obvious things (e.g., \"class name ends with X\", \"method exists\") unless they serve as smoke tests for generated code\n- **Keep and improve important tests** \u2014 focus on tests that verify actual business logic, edge cases, error handling, and integration behavior\n- **Write fewer but more meaningful tests** \u2014 each test should validate a real scenario or invariant, not just existence checks\n- **Consolidate redundant test cases** \u2014 merge tests that cover the same code path with slightly different inputs into parameterized patterns\n- **Ensure critical paths are covered** \u2014 every public method with logic should have at least one test covering its happy path and one covering its error/edge case\n\n### 7. Final cleanup\n\n- Remove all unused imports\n- Remove empty files or files with no exports\n- Ensure consistent formatting\n\n### 8. Lint and format\n\nRun linting and formatting on all modified files:\n\n```bash\nbunx biome check --fix <list of modified files>\n```\n\n### 9. Run tests\n\nRun the module's tests to verify nothing is broken:\n\n```bash\nbun test <module test directory>\n```\n\nIf any test fails, fix the issue and re-run until all tests pass.\n";var np={"make.ai":Gr,"make.analytics":$r,"make.cache":qr,"make.controller":Wr,"make.cron":Fr,"make.database":Kr,"make.entity":Hr,"make.logger":Vr,"make.mailer":zr,"make.middleware":Yr,"make.migration":Qr,"make.permission":Zr,"make.pubsub":Xr,"make.repository":Jr,"make.seed":jr,"make.service":ei,"make.storage":ti,"make.vector-database":si,commit:Ur,optimize:oi};class Ve{getName(){return"make:claude:skill"}getDescription(){return"Generate Claude skills from templates"}async run(){let e=He(".claude","skills"),t=He(process.cwd(),e),s=new ap;for(let[o,r]of Object.entries(np)){let i=o.replace(/\./g,"-"),a=He(t,i,"SKILL.md");await Bun.write(a,r),s.success(`${He(e,i,"SKILL.md")} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}}Ve=b([x.command()],Ve);import{basename as pp,join as G}from"path";import{TerminalLogger as cp}from"@ooneex/logger";import{toPascalCase as kt}from"@ooneex/utils";var ri=`import { describe, expect, test } from "bun:test";
1819
1821
  import { {{NAME}}Cron } from "@/cron/{{NAME}}Cron";
1820
1822
 
1821
1823
  describe("{{NAME}}Cron", () => {
@@ -1838,7 +1840,7 @@ describe("{{NAME}}Cron", () => {
1838
1840
  expect(typeof {{NAME}}Cron.prototype.handler).toBe("function");
1839
1841
  });
1840
1842
  });
1841
- `;var ri=`import type { TimeZoneType } from "@ooneex/country";
1843
+ `;var ii=`import type { TimeZoneType } from "@ooneex/country";
1842
1844
  import type { CronTimeType } from "@ooneex/cron";
1843
1845
  import { Cron, decorator } from "@ooneex/cron";
1844
1846
 
@@ -1859,9 +1861,9 @@ export class {{NAME}}Cron extends Cron {
1859
1861
  // console.log("{{NAME}}Cron handler executed");
1860
1862
  }
1861
1863
  }
1862
- `;class We{getName(){return"make:cron"}getDescription(){return"Generate a new cron class"}async addToModule(e,t){let s=await Bun.file(e).text(),r=`${t}Cron`,o=`import { ${r} } from "./cron/${r}";
1864
+ `;class ze{getName(){return"make:cron"}getDescription(){return"Generate a new cron class"}async addToModule(e,t){let s=await Bun.file(e).text(),o=`${t}Cron`,r=`import { ${o} } from "./cron/${o}";
1863
1865
  `,i=s.lastIndexOf("import "),a=s.indexOf(`
1864
- `,i);s=`${s.slice(0,a+1)}${o}${s.slice(a+1)}`;let n=/(cronJobs:\s*\[)([^\]]*)/s,d=s.match(n);if(d){let l=d[2]?.trim(),p=l?`${l}, ${r}`:r;s=s.replace(n,`$1${p}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter cron name"});t=Pt(t).replace(/Cron$/,"");let r=ri.replace(/{{NAME}}/g,t),o=s?G("modules",s):".",i=G(o,"src","cron"),a=G(process.cwd(),i),n=G(a,`${t}Cron.ts`);await Bun.write(n,r);let d=si.replace(/{{NAME}}/g,t),l=G(o,"tests","cron"),p=G(process.cwd(),l),u=G(p,`${t}Cron.spec.ts`);await Bun.write(u,d);let m=s?Pt(s):Pt(Zl(process.cwd())),c=G(process.cwd(),o,"src",`${m}Module.ts`);if(await Bun.file(c).exists())await this.addToModule(c,t);let h=new Ql;h.success(`${G(i,t)}Cron.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),h.success(`${G(l,t)}Cron.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/cron"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}We=b([w.command()],We);import{join as Y}from"path";import{TerminalLogger as jl}from"@ooneex/logger";import{toPascalCase as ec}from"@ooneex/utils";var oi=`import { describe, expect, test } from "bun:test";
1866
+ `,i);s=`${s.slice(0,a+1)}${r}${s.slice(a+1)}`;let n=/(cronJobs:\s*\[)([^\]]*)/s,l=s.match(n);if(l){let d=l[2]?.trim(),c=d?`${d}, ${o}`:o;s=s.replace(n,`$1${c}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter cron name"});t=kt(t).replace(/Cron$/,"");let o=ii.replace(/{{NAME}}/g,t),r=s?G("modules",s):".",i=G(r,"src","cron"),a=G(process.cwd(),i),n=G(a,`${t}Cron.ts`);await Bun.write(n,o);let l=ri.replace(/{{NAME}}/g,t),d=G(r,"tests","cron"),c=G(process.cwd(),d),u=G(c,`${t}Cron.spec.ts`);await Bun.write(u,l);let m=s?kt(s):kt(pp(process.cwd())),p=G(process.cwd(),r,"src",`${m}Module.ts`);if(await Bun.file(p).exists())await this.addToModule(p,t);let h=new cp;h.success(`${G(i,t)}Cron.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),h.success(`${G(d,t)}Cron.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/cron"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}ze=b([x.command()],ze);import{join as Y}from"path";import{TerminalLogger as hp}from"@ooneex/logger";import{toPascalCase as fp}from"@ooneex/utils";var ai=`import { describe, expect, test } from "bun:test";
1865
1867
  import { {{NAME}}Database } from "@/databases/{{NAME}}Database";
1866
1868
 
1867
1869
  describe("{{NAME}}Database", () => {
@@ -1874,7 +1876,7 @@ describe("{{NAME}}Database", () => {
1874
1876
  expect(typeof {{NAME}}Database.prototype.getSource).toBe("function");
1875
1877
  });
1876
1878
  });
1877
- `;var ii=`import { DataSource } from "typeorm";
1879
+ `;var ni=`import { DataSource } from "typeorm";
1878
1880
  import { TypeormDatabase, DatabaseException, decorator } from "@ooneex/database";
1879
1881
 
1880
1882
  @decorator.database()
@@ -1897,7 +1899,7 @@ export class {{NAME}}Database extends TypeormDatabase {
1897
1899
  return this.source;
1898
1900
  }
1899
1901
  }
1900
- `;class Ke{getName(){return"make:database"}getDescription(){return"Generate a new database class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter database name"});t=ec(t).replace(/DatabaseAdapter$/,"").replace(/Database$/,"");let r=ii.replace(/{{NAME}}/g,t),o=s?Y("modules",s):".",i=Y(o,"src","databases"),a=Y(process.cwd(),i),n=Y(a,`${t}Database.ts`);await Bun.write(n,r);let d=oi.replace(/{{NAME}}/g,t),l=Y(o,"tests","databases"),p=Y(process.cwd(),l),u=Y(p,`${t}Database.spec.ts`);await Bun.write(u,d);let m=new jl;m.success(`${Y(i,t)}Database.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${Y(l,t)}Database.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/database"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ke=b([w.command()],Ke);import{join as Ci}from"path";import{TerminalLogger as xc}from"@ooneex/logger";var{YAML:_i}=globalThis.Bun;var ni=ee(ie(),1),ai=["clickhouse","elasticsearch","grafana","jaeger","keycloak","libretranslate","maildev","memcached","minio","mongodb","mysql","nats","postgres","prometheus","rabbitmq","redis","temporal","vault"],di=async(e)=>{return(await ni.prompt({type:"autocomplete",name:"service",message:e.message,initial:e.initial,choices:ai.map((s)=>s),validate:(s)=>{if(!ai.includes(s))return"Docker service is invalid";return!0}})).service};var li=`services:
1902
+ `;class Ye{getName(){return"make:database"}getDescription(){return"Generate a new database class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter database name"});t=fp(t).replace(/DatabaseAdapter$/,"").replace(/Database$/,"");let o=ni.replace(/{{NAME}}/g,t),r=s?Y("modules",s):".",i=Y(r,"src","databases"),a=Y(process.cwd(),i),n=Y(a,`${t}Database.ts`);await Bun.write(n,o);let l=ai.replace(/{{NAME}}/g,t),d=Y(r,"tests","databases"),c=Y(process.cwd(),d),u=Y(c,`${t}Database.spec.ts`);await Bun.write(u,l);let m=new hp;m.success(`${Y(i,t)}Database.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${Y(d,t)}Database.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/database"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ye=b([x.command()],Ye);import{join as Bi}from"path";import{TerminalLogger as Pp}from"@ooneex/logger";var{YAML:Ii}=globalThis.Bun;var di=te(ae(),1),li=["clickhouse","elasticsearch","grafana","jaeger","keycloak","libretranslate","maildev","memcached","minio","mongodb","mysql","nats","postgres","prometheus","rabbitmq","redis","temporal","vault"],pi=async(e)=>{return(await di.prompt({type:"autocomplete",name:"service",message:e.message,initial:e.initial,choices:li.map((s)=>s),validate:(s)=>{if(!li.includes(s))return"Docker service is invalid";return!0}})).service};var ci=`services:
1901
1903
  # ClickHouse - Column-oriented OLAP database for analytics
1902
1904
  # Docs: https://clickhouse.com/docs
1903
1905
  # HTTP API: http://localhost:8123
@@ -1918,7 +1920,7 @@ export class {{NAME}}Database extends TypeormDatabase {
1918
1920
 
1919
1921
  volumes:
1920
1922
  clickhouse_data:
1921
- `;var ci=`services:
1923
+ `;var mi=`services:
1922
1924
  # Elasticsearch - Full-text search and analytics engine
1923
1925
  # Docs: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
1924
1926
  # HTTP API: http://localhost:9200
@@ -1939,7 +1941,7 @@ volumes:
1939
1941
 
1940
1942
  volumes:
1941
1943
  elasticsearch_data:
1942
- `;var pi=`services:
1944
+ `;var ui=`services:
1943
1945
  # Grafana - Metrics visualization and dashboards
1944
1946
  # Docs: https://grafana.com/docs/grafana/latest/
1945
1947
  # Web UI: http://localhost:3000 (ooneex/ooneex)
@@ -1957,7 +1959,7 @@ volumes:
1957
1959
 
1958
1960
  volumes:
1959
1961
  grafana_data:
1960
- `;var mi=`services:
1962
+ `;var hi=`services:
1961
1963
  # Jaeger - Distributed tracing system
1962
1964
  # Docs: https://www.jaegertracing.io/docs/
1963
1965
  # Web UI: http://localhost:16686
@@ -1971,7 +1973,7 @@ volumes:
1971
1973
  - "16686:16686"
1972
1974
  - "6831:6831/udp"
1973
1975
  - "14268:14268"
1974
- `;var ui=`services:
1976
+ `;var fi=`services:
1975
1977
  # Keycloak - Identity and access management
1976
1978
  # Docs: https://www.keycloak.org/documentation
1977
1979
  # Admin Console: http://localhost:8080 (ooneex/ooneex)
@@ -1985,7 +1987,7 @@ volumes:
1985
1987
  - KEYCLOAK_ADMIN=ooneex
1986
1988
  - KEYCLOAK_ADMIN_PASSWORD=ooneex
1987
1989
  command: start-dev
1988
- `;var hi=`services:
1990
+ `;var yi=`services:
1989
1991
  # LibreTranslate - Self-hosted machine translation API
1990
1992
  # Docs: https://libretranslate.com/docs/
1991
1993
  # API: http://localhost:4000
@@ -2012,7 +2014,7 @@ volumes:
2012
2014
 
2013
2015
  volumes:
2014
2016
  libretranslate_models:
2015
- `;var fi=`services:
2017
+ `;var gi=`services:
2016
2018
  # MailDev - Email testing tool with web UI
2017
2019
  # Docs: https://github.com/maildev/maildev
2018
2020
  # Web UI: http://localhost:1080
@@ -2023,7 +2025,7 @@ volumes:
2023
2025
  ports:
2024
2026
  - "1080:1080"
2025
2027
  - "1025:1025"
2026
- `;var yi=`services:
2028
+ `;var bi=`services:
2027
2029
  # Memcached - Distributed memory caching system
2028
2030
  # Docs: https://memcached.org/
2029
2031
  # Connection: localhost:11211
@@ -2033,7 +2035,7 @@ volumes:
2033
2035
  restart: "on-failure"
2034
2036
  ports:
2035
2037
  - "11211:11211"
2036
- `;var gi=`services:
2038
+ `;var xi=`services:
2037
2039
  # MinIO - S3-compatible object storage
2038
2040
  # Docs: https://min.io/docs/minio/container/index.html
2039
2041
  # API: http://localhost:9000
@@ -2054,7 +2056,7 @@ volumes:
2054
2056
 
2055
2057
  volumes:
2056
2058
  minio_data:
2057
- `;var bi=`services:
2059
+ `;var wi=`services:
2058
2060
  # MongoDB - NoSQL document database
2059
2061
  # Docs: https://www.mongodb.com/docs/
2060
2062
  # Connection: mongodb://ooneex:ooneex@localhost:27017/ooneex
@@ -2073,7 +2075,7 @@ volumes:
2073
2075
 
2074
2076
  volumes:
2075
2077
  mongodb_data:
2076
- `;var wi=`services:
2078
+ `;var Ei=`services:
2077
2079
  # MySQL - Alternative relational database
2078
2080
  # Docs: https://dev.mysql.com/doc/
2079
2081
  # Connection: mysql://ooneex:ooneex@localhost:3306/ooneex
@@ -2093,7 +2095,7 @@ volumes:
2093
2095
 
2094
2096
  volumes:
2095
2097
  mysql_db:
2096
- `;var xi=`services:
2098
+ `;var vi=`services:
2097
2099
  # NATS - High-performance messaging system with JetStream
2098
2100
  # Docs: https://docs.nats.io/
2099
2101
  # Client: localhost:4222
@@ -2106,7 +2108,7 @@ volumes:
2106
2108
  - "4222:4222"
2107
2109
  - "8222:8222"
2108
2110
  command: "--jetstream --http_port 8222"
2109
- `;var Ei=`services:
2111
+ `;var Ai=`services:
2110
2112
  # Jade - FastAPI REST API to fetch YouTube metadata and download videos or audio via Dockerized microservice.
2111
2113
  # API: http://localhost:8000
2112
2114
  # Docs: http://localhost:8000/docs
@@ -2124,7 +2126,7 @@ volumes:
2124
2126
 
2125
2127
  volumes:
2126
2128
  jade_data:
2127
- `;var Ai=`services:
2129
+ `;var Ti=`services:
2128
2130
  # PostgreSQL - Primary relational database
2129
2131
  # Docs: https://www.postgresql.org/docs/
2130
2132
  # Connection: postgresql://ooneex:ooneex@localhost:5432/ooneex
@@ -2145,7 +2147,7 @@ volumes:
2145
2147
 
2146
2148
  volumes:
2147
2149
  postgres_db:
2148
- `;var vi=`services:
2150
+ `;var Si=`services:
2149
2151
  # Prometheus - Metrics collection and monitoring
2150
2152
  # Docs: https://prometheus.io/docs/
2151
2153
  # Web UI: http://localhost:9090
@@ -2182,7 +2184,7 @@ volumes:
2182
2184
 
2183
2185
  volumes:
2184
2186
  rabbitmq_data:
2185
- `;var Si=`services:
2187
+ `;var Ri=`services:
2186
2188
  # Redis - In-memory data store for caching and sessions
2187
2189
  # Docs: https://redis.io/docs/
2188
2190
  # Connection: redis://localhost:6379
@@ -2197,7 +2199,7 @@ volumes:
2197
2199
 
2198
2200
  volumes:
2199
2201
  redis_data:
2200
- `;var Ti=`services:
2202
+ `;var Ci=`services:
2201
2203
  # Temporal - Workflow orchestration engine
2202
2204
  # Docs: https://docs.temporal.io/
2203
2205
  # gRPC: localhost:7233
@@ -2214,7 +2216,7 @@ volumes:
2214
2216
  - POSTGRES_USER=ooneex
2215
2217
  - POSTGRES_PWD=ooneex
2216
2218
  - POSTGRES_SEEDS=postgres
2217
- `;var Ri=`services:
2219
+ `;var Mi=`services:
2218
2220
  # Vault - Secrets management and encryption
2219
2221
  # Docs: https://developer.hashicorp.com/vault/docs
2220
2222
  # Web UI: http://localhost:8200 (token: ooneex)
@@ -2229,20 +2231,20 @@ volumes:
2229
2231
  - VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200
2230
2232
  cap_add:
2231
2233
  - IPC_LOCK
2232
- `;var Mi={clickhouse:li,elasticsearch:ci,grafana:pi,"ooneex-jade":Ei,jaeger:mi,keycloak:ui,libretranslate:hi,maildev:fi,memcached:yi,minio:gi,mongodb:bi,mysql:wi,nats:xi,postgres:Ai,prometheus:vi,rabbitmq:Ni,redis:Si,temporal:Ti,vault:Ri};function Ec(e){let t=e.split(`
2233
- `),s=[],r=!1;for(let o of t){if(o.startsWith("services:")){r=!0;continue}if(r){if(o.startsWith("volumes:")||o.startsWith("networks:"))break;s.push(o)}}return s.join(`
2234
- `)}function Ac(e){let t=_i.parse(e);return t.volumes?Object.keys(t.volumes):[]}class Fe{getName(){return"make:docker"}getDescription(){return"Add a docker service to docker-compose.yml"}async run(e){let{name:t}=e;if(!t)t=await di({message:"Select docker service"});let s=Mi[t],r=Ci(process.cwd(),"docker-compose.yml"),o=new xc,i=Bun.file(r);if(await i.exists()){let d=await i.text(),l=_i.parse(d);if(l.services&&t in l.services){o.warn(`Service "${t}" already exists in docker-compose.yml`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0});return}let p=Ec(s),u=Ac(s),m=d,c=m.indexOf(`
2234
+ `;var _i={clickhouse:ci,elasticsearch:mi,grafana:ui,"ooneex-jade":Ai,jaeger:hi,keycloak:fi,libretranslate:yi,maildev:gi,memcached:bi,minio:xi,mongodb:wi,mysql:Ei,nats:vi,postgres:Ti,prometheus:Si,rabbitmq:Ni,redis:Ri,temporal:Ci,vault:Mi};function Lp(e){let t=e.split(`
2235
+ `),s=[],o=!1;for(let r of t){if(r.startsWith("services:")){o=!0;continue}if(o){if(r.startsWith("volumes:")||r.startsWith("networks:"))break;s.push(r)}}return s.join(`
2236
+ `)}function kp(e){let t=Ii.parse(e);return t.volumes?Object.keys(t.volumes):[]}class Qe{getName(){return"make:docker"}getDescription(){return"Add a docker service to docker-compose.yml"}async run(e){let{name:t}=e;if(!t)t=await pi({message:"Select docker service"});let s=_i[t],o=Bi(process.cwd(),"docker-compose.yml"),r=new Pp,i=Bun.file(o);if(await i.exists()){let l=await i.text(),d=Ii.parse(l);if(d.services&&t in d.services){r.warn(`Service "${t}" already exists in docker-compose.yml`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0});return}let c=Lp(s),u=kp(s),m=l,p=m.indexOf(`
2235
2237
  volumes:`),h=m.indexOf(`
2236
- networks:`),f=-1;if(c!==-1&&h!==-1)f=Math.min(c,h);else if(c!==-1)f=c;else if(h!==-1)f=h;if(f!==-1)m=`${m.slice(0,f)}
2237
- ${p}${m.slice(f)}`;else m=`${m.trimEnd()}
2238
- ${p}`;for(let g of u)if(!m.includes(` ${g}:`))if(m.includes(`
2238
+ networks:`),f=-1;if(p!==-1&&h!==-1)f=Math.min(p,h);else if(p!==-1)f=p;else if(h!==-1)f=h;if(f!==-1)m=`${m.slice(0,f)}
2239
+ ${c}${m.slice(f)}`;else m=`${m.trimEnd()}
2240
+ ${c}`;for(let g of u)if(!m.includes(` ${g}:`))if(m.includes(`
2239
2241
  volumes:`)){let y=m.indexOf(`
2240
- volumes:`),E=m.slice(y+9);m=`${m.slice(0,y+9)}
2241
- ${g}:${E}`}else m=`${m.trimEnd()}
2242
+ volumes:`),w=m.slice(y+9);m=`${m.slice(0,y+9)}
2243
+ ${g}:${w}`}else m=`${m.trimEnd()}
2242
2244
 
2243
2245
  volumes:
2244
2246
  ${g}:
2245
- `;await Bun.write(r,m)}else await Bun.write(r,s);let a=Ci(process.cwd(),"package.json"),n=Bun.file(a);if(await n.exists()){let d=await n.json();d.scripts=d.scripts||{},d.scripts.docker="docker compose up -d",await Bun.write(a,JSON.stringify(d,null,2))}o.success(`Service "${t}" added to docker-compose.yml`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),o.info("Run 'bun run docker' to start docker containers",void 0,{showTimestamp:!1,showArrow:!0,showLevel:!1})}}Fe=b([w.command()],Fe);var Bi=ee(Ii(),1);import{basename as Sc,join as k}from"path";import{TerminalLogger as Tc}from"@ooneex/logger";import{toPascalCase as Gt,toSnakeCase as Rc}from"@ooneex/utils";var Oi=`import { describe, expect, test } from "bun:test";
2247
+ `;await Bun.write(o,m)}else await Bun.write(o,s);let a=Bi(process.cwd(),"package.json"),n=Bun.file(a);if(await n.exists()){let l=await n.json();l.scripts=l.scripts||{},l.scripts.docker="docker compose up -d",await Bun.write(a,JSON.stringify(l,null,2))}r.success(`Service "${t}" added to docker-compose.yml`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),r.info("Run 'bun run docker' to start docker containers",void 0,{showTimestamp:!1,showArrow:!0,showLevel:!1})}}Qe=b([x.command()],Qe);var Li=te(Oi(),1);import{basename as $p,join as $}from"path";import{TerminalLogger as qp}from"@ooneex/logger";import{toPascalCase as $t,toSnakeCase as Wp}from"@ooneex/utils";var Di=`import { describe, expect, test } from "bun:test";
2246
2248
  import { {{NAME}}Entity } from "@/entities/{{NAME}}Entity";
2247
2249
 
2248
2250
  describe("{{NAME}}Entity", () => {
@@ -2307,7 +2309,7 @@ describe("{{NAME}}Entity", () => {
2307
2309
  expect("deletedAt" in entity).toBe(true);
2308
2310
  });
2309
2311
  });
2310
- `;var Di=`import type { LocaleType } from "@ooneex/translation";
2312
+ `;var Pi=`import type { LocaleType } from "@ooneex/translation";
2311
2313
  import { random } from "@ooneex/utils";
2312
2314
  import { Column, CreateDateColumn, DeleteDateColumn, Entity, PrimaryColumn, UpdateDateColumn } from "typeorm";
2313
2315
 
@@ -2358,9 +2360,9 @@ export class {{NAME}}Entity {
2358
2360
  @DeleteDateColumn({ name: "deleted_at" })
2359
2361
  deletedAt?: Date;
2360
2362
  }
2361
- `;class He{getName(){return"make:entity"}getDescription(){return"Generate a new entity class"}async addToModule(e,t){let s=await Bun.file(e).text(),r=`${t}Entity`,o=`import { ${r} } from "./entities/${r}";
2363
+ `;class be{getName(){return"make:entity"}getDescription(){return"Generate a new entity class"}async addToModule(e,t){let s=await Bun.file(e).text(),o=`${t}Entity`,r=`import { ${o} } from "./entities/${o}";
2362
2364
  `,i=s.lastIndexOf("import "),a=s.indexOf(`
2363
- `,i);s=`${s.slice(0,a+1)}${o}${s.slice(a+1)}`;let n=/(entities:\s*\[)([^\]]*)/s,d=s.match(n);if(d){let l=d[2]?.trim(),p=l?`${l}, ${r}`:r;s=s.replace(n,`$1${p}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,tableName:r}=e;if(!t)t=await v({message:"Enter entity name"});if(t=Gt(t).replace(/Entity$/,""),!r)r=Rc(Bi.default(t));let o=Di.replace(/{{NAME}}/g,t).replace(/{{TABLE_NAME}}/g,r),i=s?k("modules",s):".",a=k(i,"src","entities"),n=k(process.cwd(),a),d=k(n,`${t}Entity.ts`);await Bun.write(d,o);let l=Oi.replace(/{{NAME}}/g,t),p=k(i,"tests","entities"),u=k(process.cwd(),p),m=k(u,`${t}Entity.spec.ts`);await Bun.write(m,l);let c=s?Gt(s):Gt(Sc(process.cwd())),h=k(process.cwd(),i,"src",`${c}Module.ts`);if(await Bun.file(h).exists())await this.addToModule(h,t);let f=new Tc;f.success(`${k(a,t)}Entity.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),f.success(`${k(p,t)}Entity.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}He=b([w.command()],He);import{join as z}from"path";import{TerminalLogger as _c}from"@ooneex/logger";import{toPascalCase as Ic}from"@ooneex/utils";var Pi=`import { describe, expect, test } from "bun:test";
2365
+ `,i);s=`${s.slice(0,a+1)}${r}${s.slice(a+1)}`;let n=/(entities:\s*\[)([^\]]*)/s,l=s.match(n);if(l){let d=l[2]?.trim(),c=d?`${d}, ${o}`:o;s=s.replace(n,`$1${c}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,tableName:o}=e;if(!t)t=await A({message:"Enter entity name"});if(t=$t(t).replace(/Entity$/,""),!o)o=Wp(Li.default(t));let r=Pi.replace(/{{NAME}}/g,t).replace(/{{TABLE_NAME}}/g,o),i=s?$("modules",s):".",a=$(i,"src","entities"),n=$(process.cwd(),a),l=$(n,`${t}Entity.ts`);await Bun.write(l,r);let d=Di.replace(/{{NAME}}/g,t),c=$(i,"tests","entities"),u=$(process.cwd(),c),m=$(u,`${t}Entity.spec.ts`);await Bun.write(m,d);let p=s?$t(s):$t($p(process.cwd())),h=$(process.cwd(),i,"src",`${p}Module.ts`);if(await Bun.file(h).exists())await this.addToModule(h,t);let f=new qp;f.success(`${$(a,t)}Entity.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),f.success(`${$(c,t)}Entity.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0})}}be=b([x.command()],be);import{join as Q}from"path";import{TerminalLogger as Hp}from"@ooneex/logger";import{toPascalCase as Vp}from"@ooneex/utils";var ki=`import { describe, expect, test } from "bun:test";
2364
2366
  import { {{NAME}}Logger } from "@/loggers/{{NAME}}Logger";
2365
2367
 
2366
2368
  describe("{{NAME}}Logger", () => {
@@ -2403,7 +2405,7 @@ describe("{{NAME}}Logger", () => {
2403
2405
  expect(typeof {{NAME}}Logger.prototype.error).toBe("function");
2404
2406
  });
2405
2407
  });
2406
- `;var Li=`import type { IException } from "@ooneex/exception";
2408
+ `;var Ui=`import type { IException } from "@ooneex/exception";
2407
2409
  import type { ILogger } from "@ooneex/logger";
2408
2410
  import type { ScalarType } from "@ooneex/types";
2409
2411
  import { decorator } from "@ooneex/logger";
@@ -2438,7 +2440,7 @@ export class {{NAME}}Logger implements ILogger {
2438
2440
  // Handle error logging
2439
2441
  }
2440
2442
  }
2441
- `;class Ve{getName(){return"make:logger"}getDescription(){return"Generate a new logger class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter logger name"});t=Ic(t).replace(/Logger$/,"");let r=Li.replace(/{{NAME}}/g,t),o=s?z("modules",s):".",i=z(o,"src","loggers"),a=z(process.cwd(),i),n=z(a,`${t}Logger.ts`);await Bun.write(n,r);let d=Pi.replace(/{{NAME}}/g,t),l=z(o,"tests","loggers"),p=z(process.cwd(),l),u=z(p,`${t}Logger.spec.ts`);await Bun.write(u,d);let m=new _c;m.success(`${z(i,t)}Logger.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${z(l,t)}Logger.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/logger"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ve=b([w.command()],Ve);import{join as I}from"path";import{TerminalLogger as Lc}from"@ooneex/logger";import{toPascalCase as Uc}from"@ooneex/utils";var Ui=`import { describe, expect, test } from "bun:test";
2443
+ `;class Ze{getName(){return"make:logger"}getDescription(){return"Generate a new logger class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter logger name"});t=Vp(t).replace(/Logger$/,"");let o=Ui.replace(/{{NAME}}/g,t),r=s?Q("modules",s):".",i=Q(r,"src","loggers"),a=Q(process.cwd(),i),n=Q(a,`${t}Logger.ts`);await Bun.write(n,o);let l=ki.replace(/{{NAME}}/g,t),d=Q(r,"tests","loggers"),c=Q(process.cwd(),d),u=Q(c,`${t}Logger.spec.ts`);await Bun.write(u,l);let m=new Hp;m.success(`${Q(i,t)}Logger.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${Q(d,t)}Logger.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/logger"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ze=b([x.command()],Ze);import{join as I}from"path";import{TerminalLogger as Xp}from"@ooneex/logger";import{toPascalCase as Jp}from"@ooneex/utils";var Gi=`import { describe, expect, test } from "bun:test";
2442
2444
  import { {{NAME}}Mailer } from "@/mailers/{{NAME}}Mailer";
2443
2445
 
2444
2446
  describe("{{NAME}}Mailer", () => {
@@ -2451,7 +2453,7 @@ describe("{{NAME}}Mailer", () => {
2451
2453
  expect(typeof {{NAME}}Mailer.prototype.send).toBe("function");
2452
2454
  });
2453
2455
  });
2454
- `;var Gi=`import { inject } from "@ooneex/container";
2456
+ `;var $i=`import { inject } from "@ooneex/container";
2455
2457
  import type { IMailer } from "@ooneex/mailer";
2456
2458
  import { type {{NAME}}MailerPropsType, {{NAME}}MailerTemplate } from "./{{NAME}}MailerTemplate";
2457
2459
 
@@ -2475,7 +2477,7 @@ export class {{NAME}}Mailer implements IMailer {
2475
2477
  });
2476
2478
  }
2477
2479
  }
2478
- `;var ki=`import { describe, expect, test } from "bun:test";
2480
+ `;var qi=`import { describe, expect, test } from "bun:test";
2479
2481
  import { {{NAME}}MailerTemplate } from "@/mailers/{{NAME}}MailerTemplate";
2480
2482
 
2481
2483
  describe("{{NAME}}MailerTemplate", () => {
@@ -2487,7 +2489,7 @@ describe("{{NAME}}MailerTemplate", () => {
2487
2489
  expect(typeof {{NAME}}MailerTemplate).toBe("function");
2488
2490
  });
2489
2491
  });
2490
- `;var $i=`import { MailerLayout } from "@ooneex/mailer";
2492
+ `;var Wi=`import { MailerLayout } from "@ooneex/mailer";
2491
2493
 
2492
2494
  export type {{NAME}}MailerPropsType = {
2493
2495
  link: string;
@@ -2502,7 +2504,7 @@ export const {{NAME}}MailerTemplate = (props?: {{NAME}}MailerPropsType) => (
2502
2504
  <MailerLayout.Footer />
2503
2505
  </MailerLayout>
2504
2506
  );
2505
- `;class Ye{getName(){return"make:mailer"}getDescription(){return"Generate a new mailer class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter mailer name"});t=Uc(t).replace(/Mailer$/,"");let r=Gi.replace(/{{NAME}}/g,t),o=$i.replace(/{{NAME}}/g,t),i=s?I("modules",s):".",a=I(i,"src","mailers"),n=I(process.cwd(),a),d=I(n,`${t}Mailer.ts`),l=I(n,`${t}MailerTemplate.tsx`);await Bun.write(d,r),await Bun.write(l,o);let p=Ui.replace(/{{NAME}}/g,t),u=ki.replace(/{{NAME}}/g,t),m=I(i,"tests","mailers"),c=I(process.cwd(),m),h=I(c,`${t}Mailer.spec.ts`),f=I(c,`${t}MailerTemplate.spec.ts`);await Bun.write(h,p),await Bun.write(f,u);let g=new Lc;g.success(`${I(a,t)}Mailer.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${I(a,t)}MailerTemplate.tsx created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${I(m,t)}Mailer.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${I(m,t)}MailerTemplate.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/mailer"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ye=b([w.command()],Ye);import{basename as qc,join as $}from"path";import{TerminalLogger as Wc}from"@ooneex/logger";import{toPascalCase as kt}from"@ooneex/utils";var qi=`import type { ContextType } from "@ooneex/socket";
2507
+ `;class Xe{getName(){return"make:mailer"}getDescription(){return"Generate a new mailer class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter mailer name"});t=Jp(t).replace(/Mailer$/,"");let o=$i.replace(/{{NAME}}/g,t),r=Wi.replace(/{{NAME}}/g,t),i=s?I("modules",s):".",a=I(i,"src","mailers"),n=I(process.cwd(),a),l=I(n,`${t}Mailer.ts`),d=I(n,`${t}MailerTemplate.tsx`);await Bun.write(l,o),await Bun.write(d,r);let c=Gi.replace(/{{NAME}}/g,t),u=qi.replace(/{{NAME}}/g,t),m=I(i,"tests","mailers"),p=I(process.cwd(),m),h=I(p,`${t}Mailer.spec.ts`),f=I(p,`${t}MailerTemplate.spec.ts`);await Bun.write(h,c),await Bun.write(f,u);let g=new Xp;g.success(`${I(a,t)}Mailer.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${I(a,t)}MailerTemplate.tsx created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${I(m,t)}Mailer.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${I(m,t)}MailerTemplate.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/mailer"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Xe=b([x.command()],Xe);import{basename as sc,join as q}from"path";import{TerminalLogger as oc}from"@ooneex/logger";import{toPascalCase as qt}from"@ooneex/utils";var Fi=`import type { ContextType } from "@ooneex/socket";
2506
2508
  import { decorator, type IMiddleware } from "@ooneex/middleware";
2507
2509
 
2508
2510
  @decorator.middleware()
@@ -2514,7 +2516,7 @@ export class {{NAME}}Middleware implements IMiddleware {
2514
2516
  return context
2515
2517
  }
2516
2518
  }
2517
- `;var Wi=`import { describe, expect, test } from "bun:test";
2519
+ `;var Ki=`import { describe, expect, test } from "bun:test";
2518
2520
  import { {{NAME}}Middleware } from "@/middlewares/{{NAME}}Middleware";
2519
2521
 
2520
2522
  describe("{{NAME}}Middleware", () => {
@@ -2527,7 +2529,7 @@ describe("{{NAME}}Middleware", () => {
2527
2529
  expect(typeof {{NAME}}Middleware.prototype.handler).toBe("function");
2528
2530
  });
2529
2531
  });
2530
- `;var Ki=`import type { ContextType } from "@ooneex/controller";
2532
+ `;var Hi=`import type { ContextType } from "@ooneex/controller";
2531
2533
  import { decorator, type IMiddleware } from "@ooneex/middleware";
2532
2534
 
2533
2535
  @decorator.middleware()
@@ -2539,18 +2541,18 @@ export class {{NAME}}Middleware implements IMiddleware {
2539
2541
  return context
2540
2542
  }
2541
2543
  }
2542
- `;class ze{getName(){return"make:middleware"}getDescription(){return"Generate a new middleware class"}async addToModule(e,t){let s=await Bun.file(e).text(),r=`${t}Middleware`,o=`import { ${r} } from "./middlewares/${r}";
2544
+ `;class Je{getName(){return"make:middleware"}getDescription(){return"Generate a new middleware class"}async addToModule(e,t){let s=await Bun.file(e).text(),o=`${t}Middleware`,r=`import { ${o} } from "./middlewares/${o}";
2543
2545
  `,i=s.lastIndexOf("import "),a=s.indexOf(`
2544
- `,i);s=`${s.slice(0,a+1)}${o}${s.slice(a+1)}`;let n=/(middlewares:\s*\[)([^\]]*)/s,d=s.match(n);if(d){let l=d[2]?.trim(),p=l?`${l}, ${r}`:r;s=s.replace(n,`$1${p}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,isSocket:r}=e;if(!t)t=await v({message:"Enter middleware name"});if(r===void 0)r=await he({message:"Is this a socket middleware?"});t=kt(t).replace(/Middleware$/,"");let i=(r?qi:Ki).replace(/{{NAME}}/g,t),a=s?$("modules",s):".",n=$(a,"src","middlewares"),d=$(process.cwd(),n),l=$(d,`${t}Middleware.ts`);await Bun.write(l,i);let p=Wi.replace(/{{NAME}}/g,t),u=$(a,"tests","middlewares"),m=$(process.cwd(),u),c=$(m,`${t}Middleware.spec.ts`);await Bun.write(c,p);let h=s?kt(s):kt(qc(process.cwd())),f=$(process.cwd(),a,"src",`${h}Module.ts`);if(await Bun.file(f).exists())await this.addToModule(f,t);let g=new Wc;g.success(`${$(n,t)}Middleware.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${$(u,t)}Middleware.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/middleware"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}ze=b([w.command()],ze);import{join as Ze}from"path";import{TerminalLogger as Fc}from"@ooneex/logger";import{migrationCreate as Hc}from"@ooneex/migrations";var Fi=`#!/usr/bin/env bun
2546
+ `,i);s=`${s.slice(0,a+1)}${r}${s.slice(a+1)}`;let n=/(middlewares:\s*\[)([^\]]*)/s,l=s.match(n);if(l){let d=l[2]?.trim(),c=d?`${d}, ${o}`:o;s=s.replace(n,`$1${c}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,isSocket:o}=e;if(!t)t=await A({message:"Enter middleware name"});if(o===void 0)o=await ge({message:"Is this a socket middleware?"});t=qt(t).replace(/Middleware$/,"");let i=(o?Fi:Hi).replace(/{{NAME}}/g,t),a=s?q("modules",s):".",n=q(a,"src","middlewares"),l=q(process.cwd(),n),d=q(l,`${t}Middleware.ts`);await Bun.write(d,i);let c=Ki.replace(/{{NAME}}/g,t),u=q(a,"tests","middlewares"),m=q(process.cwd(),u),p=q(m,`${t}Middleware.spec.ts`);await Bun.write(p,c);let h=s?qt(s):qt(sc(process.cwd())),f=q(process.cwd(),a,"src",`${h}Module.ts`);if(await Bun.file(f).exists())await this.addToModule(f,t);let g=new oc;g.success(`${q(n,t)}Middleware.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),g.success(`${q(u,t)}Middleware.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/middleware"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Je=b([x.command()],Je);import{join as je}from"path";import{TerminalLogger as ic}from"@ooneex/logger";import{migrationCreate as ac}from"@ooneex/migrations";var Vi=`#!/usr/bin/env bun
2545
2547
 
2546
2548
  import { migrationUp } from "@ooneex/migrations";
2547
2549
  import "@/migrations/migrations";
2548
2550
 
2549
2551
  await migrationUp({
2550
- databaseUrl: Bun.env.DATABASE_URL || ":memory:",
2552
+ databaseUrl: Bun.env.DATABASE_URL,
2551
2553
  tableName: "migrations",
2552
2554
  });
2553
- `;class Qe{getName(){return"make:migration"}getDescription(){return"Generate a new migration file"}async run(e){let{module:t}=e,s=t?Ze("modules",t):".",r=await Hc({dir:Ze(s,"src/migrations")}),o=Ze(process.cwd(),s,"bin","migration","up.ts");if(!await Bun.file(o).exists())await Bun.write(o,Fi);let a=Ze(process.cwd(),"package.json"),n=Bun.file(a);if(await n.exists()){let p=await n.json();p.scripts=p.scripts||{},p.scripts["migration:up"]="bun ./bin/migration/up.ts",await Bun.write(a,JSON.stringify(p,null,2))}let d=new Fc;d.success(`${r} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),d.info("Run 'bun run migration:up' to execute migrations",void 0,{showTimestamp:!1,showArrow:!0,showLevel:!1}),await Bun.spawn(["bun","add","--dev","@ooneex/migrations"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Qe=b([w.command()],Qe);import{join as Z}from"path";import{TerminalLogger as zc}from"@ooneex/logger";import{toPascalCase as Zc}from"@ooneex/utils";var Hi=`import { describe, expect, test } from "bun:test";
2555
+ `;class xe{getName(){return"make:migration"}getDescription(){return"Generate a new migration file"}async run(e){let{module:t}=e,s=t?je("modules",t):".",o=await ac({dir:je(s,"src/migrations")}),r=je(process.cwd(),s,"bin","migration","up.ts");if(!await Bun.file(r).exists())await Bun.write(r,Vi);let a=je(process.cwd(),"package.json"),n=Bun.file(a);if(await n.exists()){let c=await n.json();c.scripts=c.scripts||{},c.scripts["migration:up"]="bun ./bin/migration/up.ts",await Bun.write(a,JSON.stringify(c,null,2))}let l=new ic;l.success(`${o} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),l.info("Run 'bun run migration:up' to execute migrations",void 0,{showTimestamp:!1,showArrow:!0,showLevel:!1}),await Bun.spawn(["bun","add","--dev","@ooneex/migrations"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}xe=b([x.command()],xe);import{join as Z}from"path";import{TerminalLogger as dc}from"@ooneex/logger";import{toPascalCase as pc}from"@ooneex/utils";var zi=`import { describe, expect, test } from "bun:test";
2554
2556
  import { Permission } from "@ooneex/permission";
2555
2557
  import { {{NAME}}Permission } from "@/permissions/{{NAME}}Permission";
2556
2558
 
@@ -2575,7 +2577,7 @@ describe("{{NAME}}Permission", () => {
2575
2577
  });
2576
2578
 
2577
2579
  });
2578
- `;var Vi=`import { decorator, Permission } from "@ooneex/permission";
2580
+ `;var Yi=`import { decorator, Permission } from "@ooneex/permission";
2579
2581
  import type { IUser } from "@ooneex/user";
2580
2582
 
2581
2583
  @decorator.permission()
@@ -2614,7 +2616,7 @@ export class {{NAME}}Permission extends Permission {
2614
2616
  return this;
2615
2617
  }
2616
2618
  }
2617
- `;class Xe{getName(){return"make:permission"}getDescription(){return"Generate a new permission class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter permission name"});t=Zc(t).replace(/Permission$/,"");let r=Vi.replace(/{{NAME}}/g,t),o=s?Z("modules",s):".",i=Z(o,"src","permissions"),a=Z(process.cwd(),i),n=Z(a,`${t}Permission.ts`);await Bun.write(n,r);let d=Hi.replace(/{{NAME}}/g,t),l=Z(o,"tests","permissions"),p=Z(process.cwd(),l),u=Z(p,`${t}Permission.spec.ts`);await Bun.write(u,d);let m=new zc;m.success(`${Z(i,t)}Permission.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${Z(l,t)}Permission.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/permission"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Xe=b([w.command()],Xe);import{basename as Jc,join as q}from"path";import{TerminalLogger as jc}from"@ooneex/logger";import{toKebabCase as ep,toPascalCase as $t}from"@ooneex/utils";var Yi=`import { describe, expect, test } from "bun:test";
2619
+ `;class et{getName(){return"make:permission"}getDescription(){return"Generate a new permission class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter permission name"});t=pc(t).replace(/Permission$/,"");let o=Yi.replace(/{{NAME}}/g,t),r=s?Z("modules",s):".",i=Z(r,"src","permissions"),a=Z(process.cwd(),i),n=Z(a,`${t}Permission.ts`);await Bun.write(n,o);let l=zi.replace(/{{NAME}}/g,t),d=Z(r,"tests","permissions"),c=Z(process.cwd(),d),u=Z(c,`${t}Permission.spec.ts`);await Bun.write(u,l);let m=new dc;m.success(`${Z(i,t)}Permission.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${Z(d,t)}Permission.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/permission"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}et=b([x.command()],et);import{basename as uc,join as W}from"path";import{TerminalLogger as hc}from"@ooneex/logger";import{toKebabCase as fc,toPascalCase as Wt}from"@ooneex/utils";var Qi=`import { describe, expect, test } from "bun:test";
2618
2620
  import { {{NAME}}PubSub } from "@/pubsub/{{NAME}}PubSub";
2619
2621
 
2620
2622
  describe("{{NAME}}PubSub", () => {
@@ -2652,7 +2654,7 @@ describe("{{NAME}}PubSub", () => {
2652
2654
  expect(typeof {{NAME}}PubSub.prototype.unsubscribeAll).toBe("function");
2653
2655
  });
2654
2656
  });
2655
- `;var zi=`import { inject } from "@ooneex/container";
2657
+ `;var Zi=`import { inject } from "@ooneex/container";
2656
2658
  import type { ScalarType } from "@ooneex/types";
2657
2659
  import { decorator, PubSub, RedisPubSub } from "@ooneex/pub-sub";
2658
2660
 
@@ -2674,27 +2676,27 @@ export class {{NAME}}Event<Data extends Record<string, ScalarType> = Record<stri
2674
2676
  // TODO: Implement handler logic here
2675
2677
  }
2676
2678
  }
2677
- `;class Je{getName(){return"make:pubsub"}getDescription(){return"Generate a new PubSub event class"}async addToModule(e,t){let s=await Bun.file(e).text(),r=`${t}Event`,o=`import { ${r} } from "./events/${r}";
2679
+ `;class tt{getName(){return"make:pubsub"}getDescription(){return"Generate a new PubSub event class"}async addToModule(e,t){let s=await Bun.file(e).text(),o=`${t}Event`,r=`import { ${o} } from "./events/${o}";
2678
2680
  `,i=s.lastIndexOf("import "),a=s.indexOf(`
2679
- `,i);s=`${s.slice(0,a+1)}${o}${s.slice(a+1)}`;let n=/(events:\s*\[)([^\]]*)/s,d=s.match(n);if(d){let l=d[2]?.trim(),p=l?`${l}, ${r}`:r;s=s.replace(n,`$1${p}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,channel:r}=e;if(!t)t=await v({message:"Enter name"});if(t=$t(t).replace(/PubSub$/,""),!r)r=ep(t);let o=zi.replace(/{{NAME}}/g,t).replace(/{{CHANNEL}}/g,r),i=s?q("modules",s):".",a=q(i,"src","events"),n=q(process.cwd(),a),d=q(n,`${t}Event.ts`);await Bun.write(d,o);let l=Yi.replace(/{{NAME}}/g,t),p=q(i,"tests","events"),u=q(process.cwd(),p),m=q(u,`${t}Event.spec.ts`);await Bun.write(m,l);let c=s?$t(s):$t(Jc(process.cwd())),h=q(process.cwd(),i,"src",`${c}Module.ts`);if(await Bun.file(h).exists())await this.addToModule(h,t);let f=new jc;f.success(`${q(a,t)}Event.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),f.success(`${q(p,t)}Event.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/pub-sub"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Je=b([w.command()],Je);import{readdir as tp}from"fs/promises";import{join as le}from"path";import{TerminalLogger as sp}from"@ooneex/logger";var{$:ce}=globalThis.Bun;var rp={feat:"Added",fix:"Fixed",refactor:"Changed",perf:"Changed",style:"Changed",docs:"Changed",build:"Changed",ci:"Changed",chore:"Changed",revert:"Removed"};class je{getName(){return"make:release"}getDescription(){return"Release packages with version bump, changelog, and git tag"}async run(){let e=new sp,t=process.cwd(),s=[];for(let{name:a,type:n}of[{name:"packages",type:"package"},{name:"modules",type:"module"}])try{let d=await tp(le(t,a),{withFileTypes:!0});s.push(...d.filter((l)=>l.isDirectory()).map((l)=>({base:le(a,l.name),type:n})))}catch{}let r={showTimestamp:!1,showArrow:!1,useSymbol:!0};if(s.length===0){e.error("No packages or modules found",void 0,r);return}let o=0;for(let a of s){let n=le(t,a.base),d=le(n,"package.json"),l=Bun.file(d);if(!await l.exists())continue;let p=await l.json(),u=await this.getLastTag(p.name),m=await this.getCommitsSinceTag(u,a.base);if(m.length===0)continue;let c=this.determineBumpType(m),h=this.bumpVersion(p.version,c);p.version=h;let f=`${p.name}@${h}`;await Bun.write(d,`${JSON.stringify(p,null,2)}
2680
- `),await this.updateChangelog(n,h,f,m),await this.gitAdd(le(a.base,"package.json"),le(a.base,"CHANGELOG.md")),await this.gitCommit(`chore(release): ${p.name}@${h}`),await this.gitTag(f,`chore(release): ${p.name}@${h}`),e.success(`${p.name}@${h} released (${c} bump, ${m.length} commit(s))`,void 0,r),o++}if(o===0){e.info(`No packages have unreleased commits
2681
- `,void 0,{showArrow:!1,showTimestamp:!1,showLevel:!1,useSymbol:!1});return}if(e.success(`${o} package(s) released`,void 0,r),await he({message:"Push commits and tags to remote?"}))try{await ce`git push && git push --tags`,e.success("Pushed commits and tags to remote",void 0,r)}catch{e.error("Failed to push to remote",void 0,r)}}async getLastTag(e){try{let s=(await ce`git --no-pager tag --list "${e}@*" --sort=-v:refname`.quiet()).text().trim();if(!s)return null;return s.split(`
2682
- `)[0]??null}catch{return null}}async getCommitsSinceTag(e,t){let s=e?`${e}..HEAD`:"HEAD",r="%H|%an|%s";try{let i=(await ce`git --no-pager log ${s} --format=${"%H|%an|%s"} -- ${t}`.quiet()).text().trim();if(!i)return[];let a=[],n=/^([a-z]+)\(([^)]+)\):\s*(.+)$/;for(let d of i.split(`
2683
- `)){let[l,p,...u]=d.split("|"),m=u.join("|");if(!l||!p||!m)continue;let c=m.match(n);if(c){let[,h,f,g]=c;if(h&&f&&g)a.push({hash:l.substring(0,8),type:h,scope:f,subject:g,author:p})}}return a}catch{return[]}}determineBumpType(e){for(let t of e)if(t.type==="feat")return"minor";return"patch"}bumpVersion(e,t){let s=e.split(".").map(Number),[r=0,o=0,i=0]=s;if(t==="minor")return`${r}.${o+1}.0`;return`${r}.${o}.${i+1}`}async getRepoUrl(){try{return(await ce`git --no-pager remote get-url origin`.quiet()).text().trim().replace(/\.git$/,"").replace(/^git@([^:]+):/,"https://$1/")}catch{return null}}async updateChangelog(e,t,s,r){let o=le(e,"CHANGELOG.md"),i=new Date().toISOString().split("T")[0],a=await this.getRepoUrl(),n=new Map;for(let h of r){let f=rp[h.type]??"Changed",g=n.get(f)??[];g.push(h),n.set(f,g)}let d=["Added","Changed","Deprecated","Removed","Fixed","Security"],p=`## ${a?`[${t}](${a}/releases/tag/${s})`:`[${t}]`} - ${i}
2684
- `;for(let h of d){let f=n.get(h);if(!f||f.length===0)continue;p+=`
2681
+ `,i);s=`${s.slice(0,a+1)}${r}${s.slice(a+1)}`;let n=/(events:\s*\[)([^\]]*)/s,l=s.match(n);if(l){let d=l[2]?.trim(),c=d?`${d}, ${o}`:o;s=s.replace(n,`$1${c}`)}await Bun.write(e,s)}async run(e){let{name:t,module:s,channel:o}=e;if(!t)t=await A({message:"Enter name"});if(t=Wt(t).replace(/PubSub$/,""),!o)o=fc(t);let r=Zi.replace(/{{NAME}}/g,t).replace(/{{CHANNEL}}/g,o),i=s?W("modules",s):".",a=W(i,"src","events"),n=W(process.cwd(),a),l=W(n,`${t}Event.ts`);await Bun.write(l,r);let d=Qi.replace(/{{NAME}}/g,t),c=W(i,"tests","events"),u=W(process.cwd(),c),m=W(u,`${t}Event.spec.ts`);await Bun.write(m,d);let p=s?Wt(s):Wt(uc(process.cwd())),h=W(process.cwd(),i,"src",`${p}Module.ts`);if(await Bun.file(h).exists())await this.addToModule(h,t);let f=new hc;f.success(`${W(a,t)}Event.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),f.success(`${W(c,t)}Event.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/pub-sub"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}tt=b([x.command()],tt);import{readdir as yc}from"fs/promises";import{join as me}from"path";import{TerminalLogger as gc}from"@ooneex/logger";var{$:ue}=globalThis.Bun;var bc={feat:"Added",fix:"Fixed",refactor:"Changed",perf:"Changed",style:"Changed",docs:"Changed",build:"Changed",ci:"Changed",chore:"Changed",revert:"Removed"};class st{getName(){return"make:release"}getDescription(){return"Release packages with version bump, changelog, and git tag"}async run(){let e=new gc,t=process.cwd(),s=[];for(let{name:a,type:n}of[{name:"packages",type:"package"},{name:"modules",type:"module"}])try{let l=await yc(me(t,a),{withFileTypes:!0});s.push(...l.filter((d)=>d.isDirectory()).map((d)=>({base:me(a,d.name),type:n})))}catch{}let o={showTimestamp:!1,showArrow:!1,useSymbol:!0};if(s.length===0){e.error("No packages or modules found",void 0,o);return}let r=0;for(let a of s){let n=me(t,a.base),l=me(n,"package.json"),d=Bun.file(l);if(!await d.exists())continue;let c=await d.json(),u=await this.getLastTag(c.name),m=await this.getCommitsSinceTag(u,a.base);if(m.length===0)continue;let p=this.determineBumpType(m),h=this.bumpVersion(c.version,p);c.version=h;let f=`${c.name}@${h}`;await Bun.write(l,`${JSON.stringify(c,null,2)}
2682
+ `),await this.updateChangelog(n,h,f,m),await this.gitAdd(me(a.base,"package.json"),me(a.base,"CHANGELOG.md")),await this.gitCommit(`chore(release): ${c.name}@${h}`),await this.gitTag(f,`chore(release): ${c.name}@${h}`),e.success(`${c.name}@${h} released (${p} bump, ${m.length} commit(s))`,void 0,o),r++}if(r===0){e.info(`No packages have unreleased commits
2683
+ `,void 0,{showArrow:!1,showTimestamp:!1,showLevel:!1,useSymbol:!1});return}if(e.success(`${r} package(s) released`,void 0,o),await ge({message:"Push commits and tags to remote?"}))try{await ue`git push && git push --tags`,e.success("Pushed commits and tags to remote",void 0,o)}catch{e.error("Failed to push to remote",void 0,o)}}async getLastTag(e){try{let s=(await ue`git --no-pager tag --list "${e}@*" --sort=-v:refname`.quiet()).text().trim();if(!s)return null;return s.split(`
2684
+ `)[0]??null}catch{return null}}async getCommitsSinceTag(e,t){let s=e?`${e}..HEAD`:"HEAD",o="%H|%an|%s";try{let i=(await ue`git --no-pager log ${s} --format=${"%H|%an|%s"} -- ${t}`.quiet()).text().trim();if(!i)return[];let a=[],n=/^([a-z]+)\(([^)]+)\):\s*(.+)$/;for(let l of i.split(`
2685
+ `)){let[d,c,...u]=l.split("|"),m=u.join("|");if(!d||!c||!m)continue;let p=m.match(n);if(p){let[,h,f,g]=p;if(h&&f&&g)a.push({hash:d.substring(0,8),type:h,scope:f,subject:g,author:c})}}return a}catch{return[]}}determineBumpType(e){for(let t of e)if(t.type==="feat")return"minor";return"patch"}bumpVersion(e,t){let s=e.split(".").map(Number),[o=0,r=0,i=0]=s;if(t==="minor")return`${o}.${r+1}.0`;return`${o}.${r}.${i+1}`}async getRepoUrl(){try{return(await ue`git --no-pager remote get-url origin`.quiet()).text().trim().replace(/\.git$/,"").replace(/^git@([^:]+):/,"https://$1/")}catch{return null}}async updateChangelog(e,t,s,o){let r=me(e,"CHANGELOG.md"),i=new Date().toISOString().split("T")[0],a=await this.getRepoUrl(),n=new Map;for(let h of o){let f=bc[h.type]??"Changed",g=n.get(f)??[];g.push(h),n.set(f,g)}let l=["Added","Changed","Deprecated","Removed","Fixed","Security"],c=`## ${a?`[${t}](${a}/releases/tag/${s})`:`[${t}]`} - ${i}
2686
+ `;for(let h of l){let f=n.get(h);if(!f||f.length===0)continue;c+=`
2685
2687
  ### ${h}
2686
2688
 
2687
- `;for(let g of f){let y=a?` ([${g.hash}](${a}/commit/${g.hash}))`:"";p+=`- ${g.subject} \u2014 ${g.author}${y}
2688
- `}}let u=Bun.file(o),m="";if(await u.exists())m=await u.text();let c;if(m){let h=m.match(/## \[Unreleased\][^\n]*\n/),f=m.match(/## \[\d+\.\d+\.\d+\]/);if(h){let g=(h.index??0)+h[0].length;c=`${m.slice(0,g)}
2689
- ${p}
2690
- ${m.slice(g)}`}else if(f&&f.index!==void 0)c=`${m.slice(0,f.index)}${p}
2691
- ${m.slice(f.index)}`;else c=`${m.trimEnd()}
2689
+ `;for(let g of f){let y=a?` ([${g.hash}](${a}/commit/${g.hash}))`:"";c+=`- ${g.subject} \u2014 ${g.author}${y}
2690
+ `}}let u=Bun.file(r),m="";if(await u.exists())m=await u.text();let p;if(m){let h=m.match(/## \[Unreleased\][^\n]*\n/),f=m.match(/## \[\d+\.\d+\.\d+\]/);if(h){let g=(h.index??0)+h[0].length;p=`${m.slice(0,g)}
2691
+ ${c}
2692
+ ${m.slice(g)}`}else if(f&&f.index!==void 0)p=`${m.slice(0,f.index)}${c}
2693
+ ${m.slice(f.index)}`;else p=`${m.trimEnd()}
2692
2694
 
2693
- ${p}
2694
- `}else c=`# Changelog
2695
+ ${c}
2696
+ `}else p=`# Changelog
2695
2697
 
2696
- ${p}
2697
- `;await Bun.write(o,c)}async gitAdd(...e){await ce`git add ${e}`}async gitCommit(e){await ce`git commit --no-verify -m ${e}`}async gitTag(e,t){await ce`git tag -a ${e} -m ${t}`}}je=b([w.command()],je);import{join as Q}from"path";import{TerminalLogger as ap}from"@ooneex/logger";import{toPascalCase as np}from"@ooneex/utils";var Zi=`import { describe, expect, test } from "bun:test";
2698
+ ${c}
2699
+ `;await Bun.write(r,p)}async gitAdd(...e){await ue`git add ${e}`}async gitCommit(e){await ue`git commit --no-verify -m ${e}`}async gitTag(e,t){await ue`git tag -a ${e} -m ${t}`}}st=b([x.command()],st);import{join as X}from"path";import{TerminalLogger as Ec}from"@ooneex/logger";import{toPascalCase as vc}from"@ooneex/utils";var Xi=`import { describe, expect, test } from "bun:test";
2698
2700
  import { {{NAME}}Repository } from "@/repositories/{{NAME}}Repository";
2699
2701
 
2700
2702
  describe("{{NAME}}Repository", () => {
@@ -2757,7 +2759,7 @@ describe("{{NAME}}Repository", () => {
2757
2759
  expect(typeof {{NAME}}Repository.prototype.count).toBe("function");
2758
2760
  });
2759
2761
  });
2760
- `;var Qi=`import { inject } from "@ooneex/container";
2762
+ `;var Ji=`import { inject } from "@ooneex/container";
2761
2763
  import type { ITypeormDatabase } from "@ooneex/database";
2762
2764
  import { decorator } from "@ooneex/repository";
2763
2765
  import type { FilterResultType } from "@ooneex/types";
@@ -2881,13 +2883,655 @@ export class {{NAME}}Repository {
2881
2883
  return await repository.count(criteria ? { where: criteria } : {});
2882
2884
  }
2883
2885
  }
2884
- `;class et{getName(){return"make:repository"}getDescription(){return"Generate a new repository class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter repository name"});t=np(t).replace(/Repository$/,"");let r=Qi.replace(/{{NAME}}/g,t),o=s?Q("modules",s):".",i=Q(o,"src","repositories"),a=Q(process.cwd(),i),n=Q(a,`${t}Repository.ts`);await Bun.write(n,r);let d=Zi.replace(/{{NAME}}/g,t),l=Q(o,"tests","repositories"),p=Q(process.cwd(),l),u=Q(p,`${t}Repository.spec.ts`);await Bun.write(u,d);let m=new ap;m.success(`${Q(i,t)}Repository.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${Q(l,t)}Repository.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/repository"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}et=b([w.command()],et);import{join as tt}from"path";import{TerminalLogger as lp}from"@ooneex/logger";import{seedCreate as cp}from"@ooneex/seeds";var Xi=`#!/usr/bin/env bun
2886
+ `;class we{getName(){return"make:repository"}getDescription(){return"Generate a new repository class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter repository name"});t=vc(t).replace(/Repository$/,"");let o=Ji.replace(/{{NAME}}/g,t),r=s?X("modules",s):".",i=X(r,"src","repositories"),a=X(process.cwd(),i),n=X(a,`${t}Repository.ts`);await Bun.write(n,o);let l=Xi.replace(/{{NAME}}/g,t),d=X(r,"tests","repositories"),c=X(process.cwd(),d),u=X(c,`${t}Repository.spec.ts`);await Bun.write(u,l);let m=new Ec;m.success(`${X(i,t)}Repository.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${X(d,t)}Repository.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/repository"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}we=b([x.command()],we);import{join as C}from"path";var{Glob:$c}=globalThis.Bun;var ji=`import type { LocaleType } from "@ooneex/translation";
2887
+ import { random } from "@ooneex/utils";
2888
+ import {
2889
+ Column,
2890
+ CreateDateColumn,
2891
+ Entity,
2892
+ PrimaryColumn,
2893
+ UpdateDateColumn,
2894
+ } from "typeorm";
2885
2895
 
2886
- import { seedRun } from "@ooneex/seeds";
2887
- import "@/seeds/seeds";
2896
+ @Entity({
2897
+ name: "books",
2898
+ })
2899
+ export class BookEntity {
2900
+ @PrimaryColumn({ name: "id", type: "varchar", length: 25 })
2901
+ id: string = random.id();
2888
2902
 
2889
- await seedRun();
2890
- `;class st{getName(){return"make:seed"}getDescription(){return"Generate a new seed file"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter seed name"});let r=s?tt("modules",s):".",o=await cp({name:t,dir:tt(r,"src/seeds")}),i=tt(process.cwd(),r,"bin","seed","run.ts");if(!await Bun.file(i).exists())await Bun.write(i,Xi);let n=tt(process.cwd(),"package.json"),d=Bun.file(n);if(await d.exists()){let u=await d.json();u.scripts=u.scripts||{},u.scripts["seed:run"]="bun ./bin/seed/run.ts",await Bun.write(n,JSON.stringify(u,null,2))}let l=new lp;l.success(`${o} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),l.info("Run 'bun run seed:run' to execute seeds",void 0,{showTimestamp:!1,showArrow:!0,showLevel:!1}),await Bun.spawn(["bun","add","--dev","@ooneex/seeds"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}st=b([w.command()],st);import{join as X}from"path";import{TerminalLogger as up}from"@ooneex/logger";import{toPascalCase as hp}from"@ooneex/utils";var Ji=`import { describe, expect, test } from "bun:test";
2903
+ @Column({ name: "title", type: "varchar", length: 255 })
2904
+ title: string;
2905
+
2906
+ @Column({ name: "color", type: "varchar", length: 50, nullable: true })
2907
+ color?: string | null;
2908
+
2909
+ @Column({ name: "description", type: "text", nullable: true })
2910
+ description?: string | null;
2911
+
2912
+ @Column({ name: "summarize", type: "text", nullable: true })
2913
+ summarize?: string | null;
2914
+
2915
+ @Column({ name: "page_count", type: "int", nullable: true })
2916
+ pageCount?: number | null;
2917
+
2918
+ @Column({ name: "src", type: "varchar", length: 255 })
2919
+ src: string;
2920
+
2921
+ @Column({ name: "cover_image", type: "varchar", length: 255, nullable: true })
2922
+ coverImage?: string | null;
2923
+
2924
+ @Column({ name: "tags", type: "text", array: true, nullable: true })
2925
+ tags?: string[] | null;
2926
+
2927
+ @Column({ name: "topics", type: "text", array: true, nullable: true })
2928
+ topics?: string[] | null;
2929
+
2930
+ @Column({ name: "categories", type: "text", array: true, nullable: true })
2931
+ categories?: string[] | null;
2932
+
2933
+ @Column({ name: "lang", type: "varchar", length: 10, nullable: true })
2934
+ lang?: LocaleType | null;
2935
+
2936
+ @Column({ name: "status", type: "varchar", length: 50, nullable: true })
2937
+ status?: string | null;
2938
+
2939
+ @CreateDateColumn({ name: "created_at" })
2940
+ createdAt?: Date | null;
2941
+
2942
+ @UpdateDateColumn({ name: "updated_at" })
2943
+ updatedAt?: Date | null;
2944
+ }
2945
+ `;var ea=`import { decorator, type IMigration, type MigrationClassType } from '@ooneex/migrations';
2946
+ import type { TransactionSQL } from 'bun';
2947
+
2948
+ @decorator.migration()
2949
+ export class {{ name }} implements IMigration {
2950
+ public async up(tx: TransactionSQL): Promise<void> {
2951
+ await tx\`
2952
+ CREATE TABLE IF NOT EXISTS books (
2953
+ id VARCHAR(25) PRIMARY KEY,
2954
+ title VARCHAR(255) NOT NULL,
2955
+ color VARCHAR(50),
2956
+ description TEXT,
2957
+ summarize TEXT,
2958
+ page_count INT,
2959
+ src VARCHAR(255) NOT NULL,
2960
+ cover_image VARCHAR(255),
2961
+ tags TEXT[],
2962
+ topics TEXT[],
2963
+ categories TEXT[],
2964
+ lang VARCHAR(10),
2965
+ status VARCHAR(50),
2966
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
2967
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
2968
+ )
2969
+ \`;
2970
+
2971
+ await tx\`
2972
+ CREATE INDEX IF NOT EXISTS idx_books_title ON books (title)
2973
+ \`;
2974
+ }
2975
+
2976
+ public async down(tx: TransactionSQL): Promise<void> {
2977
+ await tx\`DROP TABLE IF EXISTS books\`;
2978
+ }
2979
+
2980
+ public getVersion(): string {
2981
+ return '{{ version }}';
2982
+ }
2983
+
2984
+ public getDependencies(): MigrationClassType[] {
2985
+ return [];
2986
+ }
2987
+ }
2988
+ `;var ta=`import { inject } from "@ooneex/container";
2989
+ import type { ITypeormDatabase } from "@ooneex/database";
2990
+ import { decorator } from "@ooneex/repository";
2991
+ import type { FilterResultType } from "@ooneex/types";
2992
+ import type { FindManyOptions, FindOptionsWhere, Repository, SaveOptions, UpdateResult } from "typeorm";
2993
+ import { ILike } from "typeorm";
2994
+ import { BookEntity } from "../entities/BookEntity";
2995
+
2996
+ @decorator.repository()
2997
+ export class BookRepository {
2998
+ constructor(
2999
+ @inject("database")
3000
+ private readonly database: ITypeormDatabase,
3001
+ ) {}
3002
+
3003
+ public async open(): Promise<Repository<BookEntity>> {
3004
+ return await this.database.open(BookEntity);
3005
+ }
3006
+
3007
+ public async close(): Promise<void> {
3008
+ await this.database.close();
3009
+ }
3010
+
3011
+ public async find(
3012
+ criteria: FindManyOptions<BookEntity> & { page?: number; limit?: number; q?: string },
3013
+ ): Promise<FilterResultType<BookEntity>> {
3014
+ const repository = await this.open();
3015
+
3016
+ const { page = 1, limit = 100, q, ...rest } = criteria;
3017
+
3018
+ let skip: number | undefined;
3019
+ const take = limit === 0 ? 100 : limit;
3020
+
3021
+ if (page && page > 0 && limit && limit > 0) {
3022
+ skip = (page - 1) * take;
3023
+ }
3024
+
3025
+ let findOptions = { ...rest, take, ...(skip !== undefined && { skip }) };
3026
+ if (q) {
3027
+ findOptions = {
3028
+ ...findOptions,
3029
+ where: {
3030
+ ...rest.where,
3031
+ title: ILike(\`%\${q}%\`),
3032
+ },
3033
+ };
3034
+ }
3035
+
3036
+ const result = await repository.find(findOptions);
3037
+
3038
+ let countWhere = rest.where;
3039
+ if (q) {
3040
+ countWhere = {
3041
+ ...rest.where,
3042
+ title: ILike(\`%\${q}%\`),
3043
+ };
3044
+ }
3045
+
3046
+ const total = await this.count(countWhere);
3047
+ const totalPages = Math.ceil(total / limit);
3048
+
3049
+ return {
3050
+ resources: result,
3051
+ total,
3052
+ totalPages,
3053
+ page,
3054
+ limit,
3055
+ };
3056
+ }
3057
+
3058
+ public async findOne(id: string): Promise<BookEntity | null> {
3059
+ const repository = await this.open();
3060
+
3061
+ return await repository.findOne({
3062
+ where: { id },
3063
+ });
3064
+ }
3065
+
3066
+ public async findOneBy(criteria: FindOptionsWhere<BookEntity>): Promise<BookEntity | null> {
3067
+ const repository = await this.open();
3068
+
3069
+ return await repository.findOne({
3070
+ where: criteria,
3071
+ });
3072
+ }
3073
+
3074
+ public async create(entity: BookEntity, options?: SaveOptions): Promise<BookEntity> {
3075
+ const repository = await this.open();
3076
+
3077
+ return await repository.save(entity, options);
3078
+ }
3079
+
3080
+ public async createMany(entities: BookEntity[], options?: SaveOptions): Promise<BookEntity[]> {
3081
+ const repository = await this.open();
3082
+
3083
+ return await repository.save(entities, options);
3084
+ }
3085
+
3086
+ public async update(entity: Partial<BookEntity> & { id: string }): Promise<UpdateResult> {
3087
+ const repository = await this.open();
3088
+
3089
+ return await repository.update(entity.id, entity);
3090
+ }
3091
+
3092
+ public async updateMany(entities: (Partial<BookEntity> & { id: string })[]): Promise<UpdateResult[]> {
3093
+ const repository = await this.open();
3094
+
3095
+ return await Promise.all(entities.map((entity) => repository.update(entity.id, entity)));
3096
+ }
3097
+
3098
+ public async delete(
3099
+ criteria: FindOptionsWhere<BookEntity> | FindOptionsWhere<BookEntity>[],
3100
+ ): Promise<UpdateResult> {
3101
+ const repository = await this.open();
3102
+
3103
+ return await repository.softDelete(criteria);
3104
+ }
3105
+
3106
+ public async count(criteria?: FindOptionsWhere<BookEntity> | FindOptionsWhere<BookEntity>[]): Promise<number> {
3107
+ const repository = await this.open();
3108
+
3109
+ return await repository.count(criteria ? { where: criteria } : {});
3110
+ }
3111
+ }
3112
+ `;var sa=`import type { ContextType } from "@ooneex/controller";
3113
+ import { inject } from "@ooneex/container";
3114
+ import { ERole } from "@ooneex/role";
3115
+ import { Route } from "@ooneex/routing";
3116
+ import type { LocaleType } from "@ooneex/translation";
3117
+ import { Assert } from "@ooneex/validation";
3118
+ import type { BookEntity } from "../entities/BookEntity";
3119
+ import { CreateBookService } from "../services/CreateBookService";
3120
+
3121
+ type CreateBookRouteType = {
3122
+ payload: {
3123
+ title: string;
3124
+ color?: string;
3125
+ description?: string;
3126
+ summarize?: string;
3127
+ pageCount?: number;
3128
+ src: string;
3129
+ coverImage?: string;
3130
+ tags?: string[];
3131
+ topics?: string[];
3132
+ categories?: string[];
3133
+ lang?: LocaleType;
3134
+ status?: string;
3135
+ };
3136
+ response: BookEntity | null;
3137
+ };
3138
+
3139
+ @Route.post("/books", {
3140
+ name: "book.create",
3141
+ version: 1,
3142
+ description: "Create a new book",
3143
+ payload: Assert({
3144
+ title: "string",
3145
+ color: "string?",
3146
+ description: "string?",
3147
+ summarize: "string?",
3148
+ pageCount: "number?",
3149
+ src: "string",
3150
+ coverImage: "string?",
3151
+ tags: "string[]?",
3152
+ topics: "string[]?",
3153
+ categories: "string[]?",
3154
+ lang: "string?",
3155
+ status: "string?",
3156
+ }),
3157
+ response: Assert({
3158
+ id: "string",
3159
+ title: "string",
3160
+ color: "string?",
3161
+ description: "string?",
3162
+ summarize: "string?",
3163
+ pageCount: "number?",
3164
+ src: "string",
3165
+ coverImage: "string?",
3166
+ tags: "string[]?",
3167
+ topics: "string[]?",
3168
+ categories: "string[]?",
3169
+ lang: "string?",
3170
+ status: "string?",
3171
+ }),
3172
+ roles: [ERole.USER],
3173
+ })
3174
+ export class CreateBookController {
3175
+ constructor(
3176
+ @inject(CreateBookService) private readonly service: CreateBookService,
3177
+ ) {}
3178
+
3179
+ public async index(context: ContextType<CreateBookRouteType>) {
3180
+ const { title, color, description, summarize, pageCount, src, coverImage, tags, topics, categories, lang, status } = context.payload;
3181
+
3182
+ const book = await this.service.execute({ title, color, description, summarize, pageCount, src, coverImage, tags, topics, categories, lang, status });
3183
+
3184
+ return context.response.json(book);
3185
+ }
3186
+ }
3187
+ `;var oa=`import type { ContextType } from "@ooneex/controller";
3188
+ import { inject } from "@ooneex/container";
3189
+ import { ERole } from "@ooneex/role";
3190
+ import { Route } from "@ooneex/routing";
3191
+ import { Assert } from "@ooneex/validation";
3192
+ import { DeleteBookService } from "../services/DeleteBookService";
3193
+
3194
+ type DeleteBookRouteType = {
3195
+ params: { id: string };
3196
+ response: { id: string };
3197
+ };
3198
+
3199
+ @Route.delete("/books/:id", {
3200
+ name: "book.delete",
3201
+ version: 1,
3202
+ description: "Delete a book",
3203
+ params: {
3204
+ id: Assert("string"),
3205
+ },
3206
+ response: Assert({
3207
+ id: "string",
3208
+ }),
3209
+ roles: [ERole.USER],
3210
+ })
3211
+ export class DeleteBookController {
3212
+ constructor(
3213
+ @inject(DeleteBookService) private readonly service: DeleteBookService,
3214
+ ) {}
3215
+
3216
+ public async index(context: ContextType<DeleteBookRouteType>) {
3217
+ const { id } = context.params;
3218
+
3219
+ await this.service.execute({ id });
3220
+
3221
+ return context.response.json({ id });
3222
+ }
3223
+ }
3224
+ `;var ra=`import type { ContextType } from "@ooneex/controller";
3225
+ import { inject } from "@ooneex/container";
3226
+ import { ERole } from "@ooneex/role";
3227
+ import { Route } from "@ooneex/routing";
3228
+ import { Assert } from "@ooneex/validation";
3229
+ import type { BookEntity } from "../entities/BookEntity";
3230
+ import { GetBookService } from "../services/GetBookService";
3231
+
3232
+ type GetBookRouteType = {
3233
+ params: { id: string };
3234
+ response: BookEntity | null;
3235
+ };
3236
+
3237
+ @Route.get("/books/:id", {
3238
+ name: "book.get",
3239
+ version: 1,
3240
+ description: "Get a book by id",
3241
+ params: {
3242
+ id: Assert("string"),
3243
+ },
3244
+ roles: [ERole.USER],
3245
+ })
3246
+ export class GetBookController {
3247
+ constructor(
3248
+ @inject(GetBookService) private readonly service: GetBookService,
3249
+ ) {}
3250
+
3251
+ public async index(context: ContextType<GetBookRouteType>) {
3252
+ const { id } = context.params;
3253
+
3254
+ const book = await this.service.execute({ id });
3255
+
3256
+ return context.response.json(book);
3257
+ }
3258
+ }
3259
+ `;var ia=`import type { ContextType } from "@ooneex/controller";
3260
+ import { inject } from "@ooneex/container";
3261
+ import { ERole } from "@ooneex/role";
3262
+ import { Route } from "@ooneex/routing";
3263
+ import type { FilterResultType } from "@ooneex/types";
3264
+ import { Assert } from "@ooneex/validation";
3265
+ import type { BookEntity } from "../entities/BookEntity";
3266
+ import { ListBooksService } from "../services/ListBooksService";
3267
+
3268
+ type ListBooksRouteType = {
3269
+ query: { page?: number; limit?: number; q?: string };
3270
+ response: FilterResultType<BookEntity>;
3271
+ };
3272
+
3273
+ @Route.get("/books", {
3274
+ name: "book.list",
3275
+ version: 1,
3276
+ description: "List all books",
3277
+ query: Assert({
3278
+ page: "number?",
3279
+ limit: "number?",
3280
+ q: "string?",
3281
+ }),
3282
+ roles: [ERole.USER],
3283
+ })
3284
+ export class ListBooksController {
3285
+ constructor(
3286
+ @inject(ListBooksService) private readonly service: ListBooksService,
3287
+ ) {}
3288
+
3289
+ public async index(context: ContextType<ListBooksRouteType>) {
3290
+ const { page, limit, q } = context.query;
3291
+
3292
+ const result = await this.service.execute({ page, limit, q });
3293
+
3294
+ return context.response.json(result);
3295
+ }
3296
+ }
3297
+ `;var aa=`import type { ContextType } from "@ooneex/controller";
3298
+ import { inject } from "@ooneex/container";
3299
+ import { ERole } from "@ooneex/role";
3300
+ import { Route } from "@ooneex/routing";
3301
+ import type { LocaleType } from "@ooneex/translation";
3302
+ import { Assert } from "@ooneex/validation";
3303
+ import type { BookEntity } from "../entities/BookEntity";
3304
+ import { UpdateBookService } from "../services/UpdateBookService";
3305
+
3306
+ type UpdateBookRouteType = {
3307
+ params: { id: string };
3308
+ payload: {
3309
+ title?: string;
3310
+ color?: string;
3311
+ description?: string;
3312
+ summarize?: string;
3313
+ pageCount?: number;
3314
+ src?: string;
3315
+ coverImage?: string;
3316
+ tags?: string[];
3317
+ topics?: string[];
3318
+ categories?: string[];
3319
+ lang?: LocaleType;
3320
+ status?: string;
3321
+ };
3322
+ response: BookEntity | null;
3323
+ };
3324
+
3325
+ @Route.patch("/books/:id", {
3326
+ name: "book.update",
3327
+ version: 1,
3328
+ description: "Update a book",
3329
+ params: {
3330
+ id: Assert("string"),
3331
+ },
3332
+ payload: Assert({
3333
+ title: "string?",
3334
+ color: "string?",
3335
+ description: "string?",
3336
+ summarize: "string?",
3337
+ pageCount: "number?",
3338
+ src: "string?",
3339
+ coverImage: "string?",
3340
+ tags: "string[]?",
3341
+ topics: "string[]?",
3342
+ categories: "string[]?",
3343
+ lang: "string?",
3344
+ status: "string?",
3345
+ }),
3346
+ response: Assert({
3347
+ id: "string",
3348
+ title: "string",
3349
+ color: "string?",
3350
+ description: "string?",
3351
+ summarize: "string?",
3352
+ pageCount: "number?",
3353
+ src: "string",
3354
+ coverImage: "string?",
3355
+ tags: "string[]?",
3356
+ topics: "string[]?",
3357
+ categories: "string[]?",
3358
+ lang: "string?",
3359
+ status: "string?",
3360
+ }),
3361
+ roles: [ERole.USER],
3362
+ })
3363
+ export class UpdateBookController {
3364
+ constructor(
3365
+ @inject(UpdateBookService) private readonly service: UpdateBookService,
3366
+ ) {}
3367
+
3368
+ public async index(context: ContextType<UpdateBookRouteType>) {
3369
+ const { id } = context.params;
3370
+ const { title, color, description, summarize, pageCount, src, coverImage, tags, topics, categories, lang, status } = context.payload;
3371
+
3372
+ const book = await this.service.execute({ id, title, color, description, summarize, pageCount, src, coverImage, tags, topics, categories, lang, status });
3373
+
3374
+ return context.response.json(book);
3375
+ }
3376
+ }
3377
+ `;var na=`import { inject } from "@ooneex/container";
3378
+ import { decorator } from "@ooneex/service";
3379
+ import type { IService } from "@ooneex/service";
3380
+ import type { LocaleType } from "@ooneex/translation";
3381
+ import { BookEntity } from "../entities/BookEntity";
3382
+ import { BookRepository } from "../repositories/BookRepository";
3383
+
3384
+ type ServiceDataType = {
3385
+ title: string;
3386
+ color?: string;
3387
+ description?: string;
3388
+ summarize?: string;
3389
+ pageCount?: number;
3390
+ src: string;
3391
+ coverImage?: string;
3392
+ tags?: string[];
3393
+ topics?: string[];
3394
+ categories?: string[];
3395
+ lang?: LocaleType;
3396
+ status?: string;
3397
+ };
3398
+
3399
+ @decorator.service()
3400
+ export class CreateBookService<T extends ServiceDataType = ServiceDataType> implements IService<T> {
3401
+ constructor(
3402
+ @inject(BookRepository) private readonly repository: BookRepository,
3403
+ ) {}
3404
+
3405
+ public async execute(data?: T): Promise<BookEntity | null> {
3406
+ if (!data) return null;
3407
+
3408
+ const book = new BookEntity();
3409
+ book.title = data.title;
3410
+ book.color = data.color;
3411
+ book.description = data.description;
3412
+ book.summarize = data.summarize;
3413
+ book.pageCount = data.pageCount;
3414
+ book.src = data.src;
3415
+ book.coverImage = data.coverImage;
3416
+ book.tags = data.tags;
3417
+ book.topics = data.topics;
3418
+ book.categories = data.categories;
3419
+ book.lang = data.lang;
3420
+ book.status = data.status;
3421
+
3422
+ return await this.repository.create(book);
3423
+ }
3424
+ }
3425
+ `;var la=`import { inject } from "@ooneex/container";
3426
+ import { decorator } from "@ooneex/service";
3427
+ import type { IService } from "@ooneex/service";
3428
+ import { BookRepository } from "../repositories/BookRepository";
3429
+
3430
+ type ServiceDataType = {
3431
+ id: string;
3432
+ };
3433
+
3434
+ @decorator.service()
3435
+ export class DeleteBookService<T extends ServiceDataType = ServiceDataType> implements IService<T> {
3436
+ constructor(
3437
+ @inject(BookRepository) private readonly repository: BookRepository,
3438
+ ) {}
3439
+
3440
+ public async execute(data?: T): Promise<void> {
3441
+ if (!data) return;
3442
+
3443
+ await this.repository.delete({ id: data.id });
3444
+ }
3445
+ }
3446
+ `;var da=`import { inject } from "@ooneex/container";
3447
+ import { decorator } from "@ooneex/service";
3448
+ import type { IService } from "@ooneex/service";
3449
+ import { BookEntity } from "../entities/BookEntity";
3450
+ import { BookRepository } from "../repositories/BookRepository";
3451
+
3452
+ type ServiceDataType = {
3453
+ id: string;
3454
+ };
3455
+
3456
+ @decorator.service()
3457
+ export class GetBookService<T extends ServiceDataType = ServiceDataType> implements IService<T> {
3458
+ constructor(
3459
+ @inject(BookRepository) private readonly repository: BookRepository,
3460
+ ) {}
3461
+
3462
+ public async execute(data?: T): Promise<BookEntity | null> {
3463
+ if (!data) return null;
3464
+
3465
+ return await this.repository.findOne(data.id);
3466
+ }
3467
+ }
3468
+ `;var pa=`import { inject } from "@ooneex/container";
3469
+ import { decorator } from "@ooneex/service";
3470
+ import type { IService } from "@ooneex/service";
3471
+ import type { FilterResultType } from "@ooneex/types";
3472
+ import { BookEntity } from "../entities/BookEntity";
3473
+ import { BookRepository } from "../repositories/BookRepository";
3474
+
3475
+ type ServiceDataType = {
3476
+ page?: number;
3477
+ limit?: number;
3478
+ q?: string;
3479
+ };
3480
+
3481
+ @decorator.service()
3482
+ export class ListBooksService<T extends ServiceDataType = ServiceDataType> implements IService<T> {
3483
+ constructor(
3484
+ @inject(BookRepository) private readonly repository: BookRepository,
3485
+ ) {}
3486
+
3487
+ public async execute(data?: T): Promise<FilterResultType<BookEntity>> {
3488
+ return await this.repository.find({
3489
+ page: data?.page,
3490
+ limit: data?.limit,
3491
+ q: data?.q,
3492
+ });
3493
+ }
3494
+ }
3495
+ `;var ca=`import { inject } from "@ooneex/container";
3496
+ import { decorator } from "@ooneex/service";
3497
+ import type { IService } from "@ooneex/service";
3498
+ import type { LocaleType } from "@ooneex/translation";
3499
+ import { BookEntity } from "../entities/BookEntity";
3500
+ import { BookRepository } from "../repositories/BookRepository";
3501
+
3502
+ type ServiceDataType = {
3503
+ id: string;
3504
+ title?: string;
3505
+ color?: string;
3506
+ description?: string;
3507
+ summarize?: string;
3508
+ pageCount?: number;
3509
+ src?: string;
3510
+ coverImage?: string;
3511
+ tags?: string[];
3512
+ topics?: string[];
3513
+ categories?: string[];
3514
+ lang?: LocaleType;
3515
+ status?: string;
3516
+ };
3517
+
3518
+ @decorator.service()
3519
+ export class UpdateBookService<T extends ServiceDataType = ServiceDataType> implements IService<T> {
3520
+ constructor(
3521
+ @inject(BookRepository) private readonly repository: BookRepository,
3522
+ ) {}
3523
+
3524
+ public async execute(data?: T): Promise<BookEntity | null> {
3525
+ if (!data) return null;
3526
+
3527
+ const { id, ...fields } = data;
3528
+
3529
+ await this.repository.update({ id, ...fields });
3530
+
3531
+ return await this.repository.findOne(id);
3532
+ }
3533
+ }
3534
+ `;import{join as J}from"path";import{TerminalLogger as Uc}from"@ooneex/logger";import{toPascalCase as Gc}from"@ooneex/utils";var ma=`import { describe, expect, test } from "bun:test";
2891
3535
  import { {{NAME}}Service } from "@/services/{{NAME}}Service";
2892
3536
 
2893
3537
  describe("{{NAME}}Service", () => {
@@ -2900,7 +3544,7 @@ describe("{{NAME}}Service", () => {
2900
3544
  expect(typeof {{NAME}}Service.prototype.execute).toBe("function");
2901
3545
  });
2902
3546
  });
2903
- `;var ji=`import { decorator } from "@ooneex/service";
3547
+ `;var ua=`import { decorator } from "@ooneex/service";
2904
3548
  import type { IService } from "@ooneex/service";
2905
3549
 
2906
3550
  type ServiceDataType = Record<string, unknown>;
@@ -2911,7 +3555,13 @@ export class {{NAME}}Service<T extends ServiceDataType = ServiceDataType> implem
2911
3555
  // TODO: Implement service logic
2912
3556
  }
2913
3557
  }
2914
- `;class rt{getName(){return"make:service"}getDescription(){return"Generate a new service class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter service name"});t=hp(t).replace(/Service$/,"");let r=ji.replace(/{{NAME}}/g,t),o=s?X("modules",s):".",i=X(o,"src","services"),a=X(process.cwd(),i),n=X(a,`${t}Service.ts`);await Bun.write(n,r);let d=Ji.replace(/{{NAME}}/g,t),l=X(o,"tests","services"),p=X(process.cwd(),l),u=X(p,`${t}Service.spec.ts`);await Bun.write(u,d);let m=new up;m.success(`${X(i,t)}Service.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${X(l,t)}Service.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/service"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}rt=b([w.command()],rt);import{join as J}from"path";import{TerminalLogger as gp}from"@ooneex/logger";import{toPascalCase as bp,toSnakeCase as wp}from"@ooneex/utils";var ea=`import { describe, expect, test } from "bun:test";
3558
+ `;class Ee{getName(){return"make:service"}getDescription(){return"Generate a new service class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter service name"});t=Gc(t).replace(/Service$/,"");let o=ua.replace(/{{NAME}}/g,t),r=s?J("modules",s):".",i=J(r,"src","services"),a=J(process.cwd(),i),n=J(a,`${t}Service.ts`);await Bun.write(n,o);let l=ma.replace(/{{NAME}}/g,t),d=J(r,"tests","services"),c=J(process.cwd(),d),u=J(c,`${t}Service.spec.ts`);await Bun.write(u,l);let m=new Uc;m.success(`${J(i,t)}Service.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${J(d,t)}Service.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/service"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}Ee=b([x.command()],Ee);class ot{getName(){return"make:resource:book"}getDescription(){return"Generate book resource (entity, migration, repository)"}async run(){let t=C("modules","book");await new le().run({name:"book",silent:!0,skipMigrations:!1,skipSeeds:!0}),await new be().run({name:"Book",module:"book",tableName:"books"}),await new xe().run({module:"book"}),await new we().run({name:"Book",module:"book"});let a=new ne,n=[{name:"CreateBook",route:{name:"book.create",path:"/books",method:"POST"}},{name:"GetBook",route:{name:"book.get",path:"/books/:id",method:"GET"}},{name:"ListBooks",route:{name:"book.list",path:"/books",method:"GET"}},{name:"UpdateBook",route:{name:"book.update",path:"/books/:id",method:"PATCH"}},{name:"DeleteBook",route:{name:"book.delete",path:"/books/:id",method:"DELETE"}}];for(let g of n)await a.run({...g,module:"book",isSocket:!1});let l=C(process.cwd(),t,"src","controllers");await Bun.write(C(l,"CreateBookController.ts"),sa),await Bun.write(C(l,"GetBookController.ts"),ra),await Bun.write(C(l,"ListBooksController.ts"),ia),await Bun.write(C(l,"UpdateBookController.ts"),aa),await Bun.write(C(l,"DeleteBookController.ts"),oa);let d=new Ee,c=["CreateBook","GetBook","ListBooks","UpdateBook","DeleteBook"];for(let g of c)await d.run({name:g,module:"book"});let u=C(process.cwd(),t,"src","services");await Bun.write(C(u,"CreateBookService.ts"),na),await Bun.write(C(u,"GetBookService.ts"),da),await Bun.write(C(u,"ListBooksService.ts"),pa),await Bun.write(C(u,"UpdateBookService.ts"),ca),await Bun.write(C(u,"DeleteBookService.ts"),la);let m=C(process.cwd(),t,"src","entities","BookEntity.ts");await Bun.write(m,ji);let p=C(process.cwd(),t,"src","migrations"),h=new $c("Migration*.ts");for await(let g of h.scan(p)){if(g==="migrations.ts")continue;let y=g.replace(/\.ts$/,""),w=y.replace("Migration",""),v=ea.replaceAll("{{ name }}",y).replaceAll("{{ version }}",w);await Bun.write(C(p,g),v)}let f=C(process.cwd(),t,"src","repositories","BookRepository.ts");await Bun.write(f,ta)}}ot=b([x.command()],ot);import{join as rt}from"path";import{TerminalLogger as Wc}from"@ooneex/logger";import{seedCreate as Fc}from"@ooneex/seeds";var ha=`#!/usr/bin/env bun
3559
+
3560
+ import { seedRun } from "@ooneex/seeds";
3561
+ import "@/seeds/seeds";
3562
+
3563
+ await seedRun();
3564
+ `;class it{getName(){return"make:seed"}getDescription(){return"Generate a new seed file"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter seed name"});let o=s?rt("modules",s):".",r=await Fc({name:t,dir:rt(o,"src/seeds")}),i=rt(process.cwd(),o,"bin","seed","run.ts");if(!await Bun.file(i).exists())await Bun.write(i,ha);let n=rt(process.cwd(),"package.json"),l=Bun.file(n);if(await l.exists()){let u=await l.json();u.scripts=u.scripts||{},u.scripts["seed:run"]="bun ./bin/seed/run.ts",await Bun.write(n,JSON.stringify(u,null,2))}let d=new Wc;d.success(`${r} created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),d.info("Run 'bun run seed:run' to execute seeds",void 0,{showTimestamp:!1,showArrow:!0,showLevel:!1}),await Bun.spawn(["bun","add","--dev","@ooneex/seeds"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}it=b([x.command()],it);import{join as j}from"path";import{TerminalLogger as Vc}from"@ooneex/logger";import{toPascalCase as zc,toSnakeCase as Yc}from"@ooneex/utils";var fa=`import { describe, expect, test } from "bun:test";
2915
3565
  import { {{NAME}}StorageAdapter } from "@/storage/{{NAME}}StorageAdapter";
2916
3566
 
2917
3567
  describe("{{NAME}}StorageAdapter", () => {
@@ -2928,7 +3578,7 @@ describe("{{NAME}}StorageAdapter", () => {
2928
3578
  expect(typeof {{NAME}}StorageAdapter.prototype.getOptions).toBe("function");
2929
3579
  });
2930
3580
  });
2931
- `;var ta=`import { Storage, decorator, StorageException } from "@ooneex/storage";
3581
+ `;var ya=`import { Storage, decorator, StorageException } from "@ooneex/storage";
2932
3582
  import type { S3Options } from "bun";
2933
3583
 
2934
3584
  @decorator.storage()
@@ -2983,7 +3633,7 @@ export class {{NAME}}Storage extends Storage {
2983
3633
  };
2984
3634
  }
2985
3635
  }
2986
- `;class ot{getName(){return"make:storage"}getDescription(){return"Generate a new storage class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter storage name"});t=bp(t).replace(/Storage$/,"");let r=wp(t).toUpperCase(),o=ta.replace(/{{NAME}}/g,t).replace(/{{NAME_UPPER}}/g,r),i=s?J("modules",s):".",a=J(i,"src","storage"),n=J(process.cwd(),a),d=J(n,`${t}Storage.ts`);await Bun.write(d,o);let l=ea.replace(/{{NAME}}/g,t),p=J(i,"tests","storage"),u=J(process.cwd(),p),m=J(u,`${t}Storage.spec.ts`);await Bun.write(m,l);let c=new gp;c.success(`${J(a,t)}Storage.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),c.success(`${J(p,t)}Storage.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/storage"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}ot=b([w.command()],ot);import{join as j}from"path";import{TerminalLogger as Ap}from"@ooneex/logger";import{toPascalCase as vp}from"@ooneex/utils";var sa=`import { describe, expect, test } from "bun:test";
3636
+ `;class at{getName(){return"make:storage"}getDescription(){return"Generate a new storage class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter storage name"});t=zc(t).replace(/Storage$/,"");let o=Yc(t).toUpperCase(),r=ya.replace(/{{NAME}}/g,t).replace(/{{NAME_UPPER}}/g,o),i=s?j("modules",s):".",a=j(i,"src","storage"),n=j(process.cwd(),a),l=j(n,`${t}Storage.ts`);await Bun.write(l,r);let d=fa.replace(/{{NAME}}/g,t),c=j(i,"tests","storage"),u=j(process.cwd(),c),m=j(u,`${t}Storage.spec.ts`);await Bun.write(m,d);let p=new Vc;p.success(`${j(a,t)}Storage.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),p.success(`${j(c,t)}Storage.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/storage"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}at=b([x.command()],at);import{join as ee}from"path";import{TerminalLogger as Xc}from"@ooneex/logger";import{toPascalCase as Jc}from"@ooneex/utils";var ga=`import { describe, expect, test } from "bun:test";
2987
3637
  import { {{NAME}}VectorDatabase } from "@/databases/{{NAME}}VectorDatabase";
2988
3638
 
2989
3639
  describe("{{NAME}}VectorDatabase", () => {
@@ -3006,7 +3656,7 @@ describe("{{NAME}}VectorDatabase", () => {
3006
3656
  expect(typeof {{NAME}}VectorDatabase.prototype.getSchema).toBe("function");
3007
3657
  });
3008
3658
  });
3009
- `;var ra=`import { VectorDatabase, decorator } from "@ooneex/rag";
3659
+ `;var ba=`import { VectorDatabase, decorator } from "@ooneex/rag";
3010
3660
  import type { EmbeddingModelType, EmbeddingProviderType, FieldValueType } from "@ooneex/rag";
3011
3661
  import { Utf8 } from "apache-arrow";
3012
3662
 
@@ -3030,8 +3680,8 @@ export class {{NAME}}VectorDatabase extends VectorDatabase<DataType> {
3030
3680
  };
3031
3681
  }
3032
3682
  }
3033
- `;class it{getName(){return"make:vector-database"}getDescription(){return"Generate a new vector database class"}async run(e){let{name:t,module:s}=e;if(!t)t=await v({message:"Enter vector database name"});t=vp(t).replace(/VectorDatabase$/,"").replace(/Database$/,"");let r=ra.replace(/{{NAME}}/g,t),o=s?j("modules",s):".",i=j(o,"src","databases"),a=j(process.cwd(),i),n=j(a,`${t}VectorDatabase.ts`);await Bun.write(n,r);let d=sa.replace(/{{NAME}}/g,t),l=j(o,"tests","databases"),p=j(process.cwd(),l),u=j(p,`${t}VectorDatabase.spec.ts`);await Bun.write(u,d);let m=new Ap;m.success(`${j(i,t)}VectorDatabase.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${j(l,t)}VectorDatabase.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/rag"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}it=b([w.command()],it);var{values:W,positionals:Tp}=Np({args:Bun.argv,options:{name:{type:"string"},"route-name":{type:"string"},"route-path":{type:"string"},"route-method":{type:"string"},"is-socket":{type:"boolean"},dir:{type:"string"},channel:{type:"string"},"table-name":{type:"string"},module:{type:"string"},destination:{type:"string"}},strict:!1,allowPositionals:!0}),qt=new Sp,ia=Tp[2];if(!ia)qt.error(`Command name is required
3034
- `),process.exit(1);var aa=Kt(ia);if(!aa)qt.info(`No commands found
3035
- `),process.exit(1);var Rp={name:W.name,dir:W.dir,channel:W.channel,isSocket:W["is-socket"],tableName:W["table-name"],module:W.module,destination:W.destination,route:{name:W["route-name"],path:W["route-path"],method:W["route-method"]}};try{await aa.run(Rp)}catch(e){let t=e instanceof oa?e:new oa(e instanceof Error?e:String(e));qt.error(t,void 0,{showArrow:!1,showTimestamp:!1,showLevel:!1}),process.exit(1)}
3683
+ `;class nt{getName(){return"make:vector-database"}getDescription(){return"Generate a new vector database class"}async run(e){let{name:t,module:s}=e;if(!t)t=await A({message:"Enter vector database name"});t=Jc(t).replace(/VectorDatabase$/,"").replace(/Database$/,"");let o=ba.replace(/{{NAME}}/g,t),r=s?ee("modules",s):".",i=ee(r,"src","databases"),a=ee(process.cwd(),i),n=ee(a,`${t}VectorDatabase.ts`);await Bun.write(n,o);let l=ga.replace(/{{NAME}}/g,t),d=ee(r,"tests","databases"),c=ee(process.cwd(),d),u=ee(c,`${t}VectorDatabase.spec.ts`);await Bun.write(u,l);let m=new Xc;m.success(`${ee(i,t)}VectorDatabase.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),m.success(`${ee(d,t)}VectorDatabase.spec.ts created successfully`,void 0,{showTimestamp:!1,showArrow:!1,useSymbol:!0}),await Bun.spawn(["bun","add","@ooneex/rag"],{cwd:process.cwd(),stdout:"ignore",stderr:"inherit"}).exited}}nt=b([x.command()],nt);var{values:F,positionals:tm}=jc({args:Bun.argv,options:{name:{type:"string"},"route-name":{type:"string"},"route-path":{type:"string"},"route-method":{type:"string"},"is-socket":{type:"boolean"},dir:{type:"string"},channel:{type:"string"},"table-name":{type:"string"},module:{type:"string"},destination:{type:"string"}},strict:!1,allowPositionals:!0}),Ft=new em,wa=tm[2];if(!wa)Ft.error(`Command name is required
3684
+ `),process.exit(1);var Ea=Ht(wa);if(!Ea)Ft.info(`No commands found
3685
+ `),process.exit(1);var sm={name:F.name,dir:F.dir,channel:F.channel,isSocket:F["is-socket"],tableName:F["table-name"],module:F.module,destination:F.destination,route:{name:F["route-name"],path:F["route-path"],method:F["route-method"]}};try{await Ea.run(sm)}catch(e){let t=e instanceof xa?e:new xa(e instanceof Error?e:String(e));Ft.error(t,void 0,{showArrow:!1,showTimestamp:!1,showLevel:!1}),process.exit(1)}
3036
3686
 
3037
- //# debugId=6D3A3A873965FB0D64756E2164756E21
3687
+ //# debugId=48E3E606F858027064756E2164756E21