@geeth.io/command-engine
Version:
A minimal, class-based CLI command engine with support for nested commands, options, and attributes.
8 lines (7 loc) • 3.92 kB
JavaScript
;var $=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var N=(m,o)=>{for(var c in o)$(m,c,{get:o[c],enumerable:!0})},j=(m,o,c,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of x(o))!A.call(m,n)&&n!==c&&$(m,n,{get:()=>o[n],enumerable:!(r=w(o,n))||r.enumerable});return m};var y=m=>j($({},"__esModule",{value:!0}),m);var V={};N(V,{CommandEngine:()=>b});module.exports=y(V);var b=class{constructor(){this.commands=[];this.currentContext=[]}withContext(o,c){this.currentContext.push(o),c(),this.currentContext.pop()}command(o,c){let r=[...this.currentContext,o].join(" ").trim(),n={name:r,description:c,attributes:[],options:[],action:()=>{console.log(`No action defined for command: ${r}`)}};n.help=()=>{if(console.log(`
Usage: ${n.name} ${n.attributes.map(t=>t.required?`<${t.name}>`:`[${t.name}]`).join(" ")}`),console.log(`
${n.description}
`),n.attributes.length){console.log("Attributes:");for(let t of n.attributes)console.log(` ${t.name.padEnd(15)} ${t.description}${t.required?" (required)":""}${t.default!==void 0?` [default: ${JSON.stringify(t.default)}]`:""}`)}if(n.options.length){console.log(`
Options:`);for(let t of n.options){let l=t.alias?`, -${t.alias}`:"",a=t.default!==void 0?` [default: ${JSON.stringify(t.default)}]`:"";console.log(` --${t.flag}${l}`.padEnd(20)+t.description+(t.required?" (required)":"")+a)}}console.log("")},this.commands.push(n);let p={addAttribute:(t,l,a={})=>{let{required:g,default:u}=a;return n.attributes.push({name:t,description:l,required:g,default:u}),p},addOption:(t,l,a={})=>{let{required:g,alias:u,default:h}=a;return n.options.push({flag:t,description:l,required:g,alias:u,default:h}),p},action:t=>(n.action=t,p)};return p}parseValue(o){if(o==="true")return!0;if(o==="false")return!1;if(!isNaN(Number(o)))return Number(o);try{return JSON.parse(o)}catch{return o}}parse(o){let[,,...c]=o,r=c.filter(e=>e.trim()!=="");if(r.includes("--help")){for(let e=r.length;e>0;e--){let d=r.slice(0,e).join(" ").replace(/\s+/g," ").trim(),i=this.commands.find(f=>f.name===d);if(i?.help)return i.help()}return this.showHelp()}let n,p=[];for(let e=r.length;e>0;e--){let d=r.slice(0,e).join(" ").replace(/\s+/g," ").trim();if(n=this.commands.find(i=>i.name===d),n){p=r.slice(0,e);break}}if(!n)return console.error(`
\u274C Unknown command: ${r.join(" ")}`),this.showHelp();let t=r.slice(p.length),l={},a={},g=0,u=n.attributes,h=n.options;for(let e=0;e<t.length;e++){let d=t[e];if(d.startsWith("--")){let i=d.slice(2),f=h.find(s=>s.flag===i);if(f){let s=t[e+1];s&&!s.startsWith("-")?(a[i]=this.parseValue(s),e++):a[i]=f.default??!0}else console.warn(`\u26A0\uFE0F Unknown option: --${i}`)}else if(d.startsWith("-")){let i=d.slice(1),f=h.find(s=>s.alias===i);if(f){let s=t[e+1];s&&!s.startsWith("-")?(a[f.flag]=this.parseValue(s),e++):a[f.flag]=f.default??!0}else console.warn(`\u26A0\uFE0F Unknown alias: -${i}`)}else{let i=t[e+1];if(u.find(s=>s.name===d)&&i&&!i.startsWith("-"))l[d]=this.parseValue(i),e++;else if(g<u.length){let s=u[g++];l[s.name]=this.parseValue(d)}else console.warn(`\u26A0\uFE0F Unrecognized input: ${d}`)}}for(let e of u)!(e.name in l)&&e.default!==void 0&&(l[e.name]=e.default);for(let e of h)!(e.flag in a)&&e.default!==void 0&&(a[e.flag]=e.default);let C=u.filter(e=>e.required&&!(e.name in l));if(C.length>0)return console.error(`\u274C Missing required attributes: ${C.map(e=>`<${e.name}>`).join(", ")}`),n.help?.();let q=h.filter(e=>e.required&&!(e.flag in a));if(q.length>0)return console.error(`\u274C Missing required options: ${q.map(e=>`--${e.flag}`).join(", ")}`),n.help?.();n.action({attributes:l,options:a})}showHelp(){console.log(`
Available Commands:`);for(let o of this.commands)console.log(` ${o.name.padEnd(25)} ${o.description}`);console.log("\nUse `--help` with a command to learn more.\n")}};0&&(module.exports={CommandEngine});