UNPKG

@clerc/plugin-help

Version:
8 lines (7 loc) 7.3 kB
import{DOUBLE_DASH as e,NoSuchCommandError as t,definePlugin as n,normalizeFlagValue as r,normalizeParameterValue as i,resolveCommand as a}from"@clerc/core";import{formatFlagName as o,formatVersion as s,isTruthy as c,objectIsEmpty as l,toArray as u}from"@clerc/utils";import*as d from"@uttr/tint";import f from"string-width";import p from"text-table";function m(e){if(typeof e==`function`)return e.display??e.name;let t=e[0];return`Array<${t.displayName??t.name}>`}function h(e){return typeof e==`function`&&`display`in e&&e.display?e.display:String(e)}function g(e){return e===``?`(root)`:e}const _={formatTypeValue:m,formatFlagDefault:h},v=`default`,y=e=>p(e,{stringLength:f}),b=e=>y(e).split(` `),x=` `.repeat(2),S=e=>`${x}${e}`;function C(e){let t=new Map;if(e)for(let[n,r]of e)t.set(n,r);return t}function w(e,t,n,r){if(e&&e!==v&&!t.has(e))throw Error(`Unknown ${n} group "${e}" for "${r}". Available groups: ${[...t.keys()].join(`, `)||`(none)`}`)}var T=class{_command;get _commandGroups(){return C(this._getGroups().commands)}get _flagGroups(){return C(this._getGroups().flags)}get _globalFlagGroups(){return C(this._getGroups().globalFlags)}constructor(e,t,n,r,i,a){this._formatters=e,this._cli=t,this._globalFlags=n,this._getGroups=r,this._examples=i,this._notes=a}setCommand(e){e&&(this._command=e,this._examples=e?.help?.examples,this._notes=e?.help?.notes)}renderSections(e){return e.filter(c).map(e=>{let t=Array.isArray(e.body)?e.body.filter(e=>e!==void 0).join(` `):e.body;return e.title?`${d.underline.bold(e.title)}\n${t.split(` `).map(S).join(` `)}`:t}).join(` `)}render(){let e=[this.renderHeader(),this.renderUsage(),this.renderParameters(),this.renderCommandFlags(),this.renderGlobalFlags(),this.renderCommands(),this.renderExamples(),this.renderNotes()];return this.renderSections(e)}renderHeader(){let{_scriptName:e,_version:t,_description:n}=this._cli,r=this._command,i=r?r.description:n,a=`${!r||r.name===``?d.bold(e):d.dim(e)}${r?.name?` ${d.bold(r.name)}`:``}${r?``:` ${s(t)}`}`,o=r?.alias?`Alias${u(r.alias).length>1?`es`:``}: ${u(r.alias).map(e=>d.bold(e)).join(`, `)}`:void 0;return{body:[`${a}${i?` - ${i}`:``}`,o]}}renderUsage(){let{_scriptName:t}=this._cli,n=this._command,r=`$ ${t}`;if(n){if(n.name&&(r+=` ${n.name}`),n.parameters){let t=n.parameters.indexOf(e),i=t!==-1&&n.parameters.slice(t+1).some(e=>(typeof e==`string`?e:e.key).startsWith(`<`)),a=n.parameters.map(t=>{let n=typeof t==`string`?t:t.key;return t===e&&(n=i?e:`[${e}]`),n});r+=` ${a.join(` `)}`}}else this._cli._commands.size>0&&(!this._cli._commands.has(``)||this._cli._commands.size!==1)&&(r+=this._cli._commands.has(``)?` ${d.dim(`[command]`)}`:` ${d.dim(`<command>`)}`);return(n?.flags&&!l(n.flags)||!l(this._globalFlags))&&(r+=` ${d.dim(`[flags]`)}`),{title:`Usage`,body:[r]}}renderParameters(){let t=this._command;if(!(!t?.parameters||t.parameters.length===0))return{title:`Parameters`,body:b(t.parameters.filter(t=>t!==e).map(i).map(({key:e,type:t,description:n})=>{let r=t?this._formatters.formatTypeValue(t):`string`;return[d.bold(e),d.dim(r),n].filter(c)}))}}getSubcommands(e){let t=new Map;if(e===``)return t;let n=`${e} `;for(let[e,r]of this._cli._commands)if(e.startsWith(n)){let i=e.slice(n.length);t.set(i,r)}return t}buildGroupedCommandsBody(e,t){let n=new Map,r=[],i=[];for(let a of e.values()){if(a.__isAlias||a.help?.show===!1)continue;let e=a.help?.group;w(e,this._commandGroups,`command`,a.name);let o=[`${d.bold(g(a.name.slice(t.length)))}${a.alias?` (${u(a.alias).join(`, `)})`:``}`,a.description].filter(c);if(a.name===``)i=o;else if(e&&e!==v){let t=n.get(e)??[];t.push(o),n.set(e,t)}else r.push(o)}let a=[],o=[];i.length>0&&o.push(i),r.length>0&&o.push(...r),o.length>0&&a.push(...b(o));for(let[e,t]of this._commandGroups){let r=n.get(e);r&&r.length>0&&(a.length>0&&a.push(``),a.push(`${d.dim(t)}`),a.push(...b(r).map(S)))}return a}renderAvailableSubcommands(e){let t=this.getSubcommands(e);if(t.size===0)return null;let n=`${e} `,r=this.buildGroupedCommandsBody(t,n);if(r.length===0)return null;let i=[{body:`${this._cli._scriptName} ${d.bold(e)} not found`},{title:`Available Subcommands`,body:r}];return this.renderSections(i)}renderCommands(){let e=this._cli._commands,t,n=`Commands`,r=``;if(this._command){if(r=this._command.name?`${this._command.name} `:``,n=`Subcommands`,t=this.getSubcommands(this._command.name),t.size===0)return}else t=e;if(t.size===0)return;let i=this.buildGroupedCommandsBody(t,r);return{title:n,body:i}}renderFlagItem(e,t){t=r(t);let n=o(e);t.short&&(n+=`, ${o(t.short)}`);let i=this._formatters.formatTypeValue(t.type),a=t.default!==void 0&&d.dim(`[default: ${d.bold(this._formatters.formatFlagDefault(t.default))}]`);return[d.bold(n),d.dim(i),t.description,a].filter(c)}renderGroupedFlags(e,t,n){let r=new Map,i=[];for(let[a,o]of Object.entries(e)){let e=o.help?.group;w(e,t,n,a);let s=this.renderFlagItem(a,o);if(e&&e!==v){let t=r.get(e)??[];t.push(s),r.set(e,t)}else i.push(s)}let a=[];i.length>0&&a.push(...b(i));for(let[e,n]of t){let t=r.get(e);t&&t.length>0&&(a.length>0&&a.push(``),a.push(`${d.dim(n)}`),a.push(...b(t).map(S)))}return a}renderCommandFlags(){let e=this._command;if(!(!e?.flags||l(e.flags)))return{title:`Flags`,body:this.renderGroupedFlags(e.flags,this._flagGroups,`flag`)}}renderGlobalFlags(){if(!(!this._globalFlags||l(this._globalFlags)))return{title:`Global Flags`,body:this.renderGroupedFlags(this._globalFlags,this._globalFlagGroups,`global flag`)}}renderNotes(){if(this._notes?.length)return{title:`Notes`,body:this._notes}}renderExamples(){if(this._examples?.length)return{title:`Examples`,body:b(this._examples.map(([e,t])=>[e,`-`,t]))}}};function E(e,{groups:t}){e.store.help={addGroup:e=>{e.commands&&(t.commands=[...t.commands??[],...e.commands]),e.flags&&(t.flags=[...t.flags??[],...e.flags]),e.globalFlags&&(t.globalFlags=[...t.globalFlags??[],...e.globalFlags])}}}const D=({command:e=!0,flag:r=!0,showHelpWhenNoCommandSpecified:i=!0,notes:o,examples:s,header:l,footer:u,formatters:d,groups:f={}}={})=>n({setup:n=>{E(n,{groups:f});let p={..._,...d};function m(e){l&&console.log(l),console.log(e),u&&console.log(u)}let h=new T(p,n,n._globalFlags,()=>f,s,o);function g(e){let t=h.renderAvailableSubcommands(e);return t?(m(t),!0):!1}e&&n.command(`help`,`Show help`,{parameters:[`[command...]`],help:{notes:[`If no command is specified, show help for the CLI.`,`If a command is specified, show help for the command.`,r&&`-h is an alias for --help.`].filter(c),examples:[e&&[`$ ${n._scriptName} help`,`Show help`],e&&[`$ ${n._scriptName} help <command>`,`Show help for a specific command`],r&&[`$ ${n._scriptName} <command> --help`,`Show help for a specific command`]].filter(c)}}).on(`help`,e=>{let r=e.parameters.command,i;if(r.length>0&&([i]=a(n._commands,r),!i)){let e=r.join(` `);if(g(e))return;throw new t(e)}h.setCommand(i),m(h.render())}),r&&n.globalFlag(`help`,`Show help`,{short:`h`,type:Boolean,default:!1}),n.interceptor({enforce:`post`,handler:async(e,t)=>{if(e.flags.help){let n=e.command;if(!n&&e.rawParsed.parameters.length>0){if(g(e.rawParsed.parameters.join(` `)))return;await t()}h.setCommand(n),m(h.render())}else i&&!e.command&&e.rawParsed.parameters.length===0?(console.log(`No command specified. Showing help: `),m(h.render())):await t()}})}});export{_ as defaultFormatters,D as helpPlugin};