bob-core 2.0.0-beta.1 → 2.0.0-beta.2
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/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("minimist"),a=require("chalk"),w=require("prompts"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("minimist"),a=require("chalk"),w=require("prompts"),W=require("node:fs"),D=require("path"),B=require("string-similarity");function L(r){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const t in r)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>r[t]})}}return e.default=r,Object.freeze(e)}const _=L(W),G=L(B);class y extends Error{}class U extends y{constructor(e){let t=`Argument "${e.param}" value is invalid.`;e.reason?t+=` Reason: ${e.reason}`:t+=` Value: "${e.value}"`,super(t),this.param=e}pretty(e){e.log(a` {white.bgRed ERROR } Argument {bold.yellow ${this.param.param}} value is invalid. `),(this.param.value||this.param.reason)&&e.log(""),this.param.value&&e.log(a` {blue Value}: ${this.param.value}`),this.param.reason&&e.log(a` {yellow Reason}: ${this.param.reason}`)}}class C extends y{constructor(e){let t=`Option "${e.option}" value is invalid.`;e.reason?t+=` Reason: ${e.reason}`:t+=` Value: "${e.value}"`,super(t),this.param=e}pretty(e){e.log(a` {white.bgRed ERROR } Option {bold.yellow ${this.param.option}} value is invalid. `),(this.param.value||this.param.reason)&&e.log(""),this.param.value&&e.log(a` {blue Value}: ${this.param.value}`),this.param.reason&&e.log(a` {yellow Reason}: ${this.param.reason}`)}}function k(r){if(r==="string"||r==="number")return null;if(r==="boolean")return!1;if(Array.isArray(r)&&r.length===1){if(r[0]==="string")return[];if(r[0]==="number")return[]}throw new Error("Invalid option type: "+r)}function N(r){return typeof r=="string"?k(r):Array.isArray(r)?[]:typeof r=="object"&&r.type?r.default!==void 0?r.default:k(r.type):null}function f(r){return typeof r=="string"||Array.isArray(r)?{type:r,default:N(r),description:"",alias:[],required:!1,variadic:!1}:{type:r.type,default:r.default??N(r.type),description:r.description??"",alias:r.alias?Array.isArray(r.alias)?r.alias:[r.alias]:[],required:r.required??!1,variadic:r.variadic??!1}}class I extends y{constructor(e,t={}){super(`Invalid option ${e} in not recognized`),this.option=e,this.optionsSchema=t}pretty(e){const t=Object.entries(this.optionsSchema);if(t.length>0){e.log(a`\n{yellow Available options}:`);for(const[n,i]of t){const s=f(i),o=typeof s.alias=="string"?[s.alias]:s.alias,l=Array.isArray(s.type)?`[${s.type[0]}]`:s.type,u=`--${n}${o.length>0?o.map(m=>`, -${m}`).join(""):""}`,d=" ".repeat(30-u.length);e.log(a` {green ${u}} ${d} ${s.description||"\b"} {white (${l})}`)}e.log("")}e.log(a`{white.bgRed ERROR } Option {bold.yellow ${this.option}} is not recognized.`)}}class j extends y{constructor(e){super(`Command "${e}" not found.`),this.command=e}pretty(e){e.log(a`{bgRed ERROR } Command {yellow ${this.command}} not found.`)}}class v extends y{constructor(e,t){super(`Missing ${e} in the command signature`),this.argument=e,this.argumentsSchema=t}pretty(e){const t=Object.entries(this.argumentsSchema);if(t.length){e.log(a`\n{yellow Available arguments}:`);for(const[n,i]of t){const s=f(i),o=Array.isArray(s.type)?`[${s.type[0]}]`:s.type,l=o?a`{white (${o})}`:"",u=" ".repeat(20-n.length);e.log(a` {green ${n}} ${u} ${s.description??"\b"} ${l}`)}e.log("")}e.log(a`{white.bgRed ERROR } Argument {bold.yellow ${this.argument}} is missing in the signature.`)}}class b extends y{constructor(e,t){super(`Missing ${e} in the command signature`),this.option=e,this.optionsSchema=t}pretty(e){const t=Object.entries(this.optionsSchema);if(t.length){e.log(a`{yellow Available options}:`);for(const[n,i]of t){const s=f(i),o=Array.isArray(s.type)?`[${s.type[0]}]`:s.type,l=o?a`{white (${o})}`:"",u=" ".repeat(20-n.length);e.log(a` {green ${n}} ${u} ${s.description??"\b"} ${l}`)}e.log("")}e.log(a`{white.bgRed ERROR } Option {bold.yellow ${this.option}} is missing in the signature.`)}}class O extends y{constructor(e){super(`Argument "${e}" is required.`),this.argument=e}pretty(e){e.log(a`{white.bgRed ERROR } Argument {bold.yellow ${this.argument}} is required.`)}}class F extends y{constructor(e){super(`Argument "${e}" is required.`),this.option=e}pretty(e){e.log(a`{white.bgRed ERROR } Option {bold.yellow ${this.option}} is required.`)}}function $(r,e,t,n){if(r==null)return n??null;if(e==="string")return String(r);if(e==="number"){const i=Number(r);if(isNaN(i))throw new C({option:t,reason:`Expected a number, got "${r}"`});return i}if(e==="boolean")return typeof r=="boolean"?r:r==="true"||r==="1"?!0:r==="false"||r==="0"?!1:!!r;if(Array.isArray(e)){const i=e[0],s=Array.isArray(r)?r:[r];if(i==="string")return s.map(o=>String(o));if(i==="number")return s.map(o=>{const l=Number(o);if(isNaN(l))throw new C({option:t,reason:`Expected array of numbers, got "${o}" in array`});return l})}return r}class S{options;parsedOptions=null;arguments;parsedArguments=null;io;constructor(e){this.options=e.options,this.arguments=e.arguments,this.io=e.io}init(e){const{_:t,...n}=P(e);return this.validateUnknownOptions(n),this.parsedOptions=this.handleOptions(n),this.parsedArguments=this.handleArguments(t),{options:this.parsedOptions,arguments:this.parsedArguments}}async validate(){for(const e in this.options)if(f(this.options[e]).required&&(this.parsedOptions?.[e]===void 0||this.parsedOptions?.[e]===null))throw new F(e);for(const e in this.arguments)if(f(this.arguments[e]).required&&(this.parsedArguments?.[e]===void 0||this.parsedArguments?.[e]===null))throw new O(e)}option(e){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");return this.parsedOptions[e]}argument(e){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");return this.parsedArguments[e]}validateUnknownOptions(e){const t=new Set;for(const n in this.options){t.add(n);const i=f(this.options[n]);for(const s of i.alias)t.add(s)}for(const n in e)if(!t.has(n))throw new I(n,this.options)}handleOptions(e){const t={};for(const n in this.options){const i=f(this.options[n]);t[n]=this.resolveOptionValue(n,i,e,"option")}return t}handleArguments(e){const t={},n=[...e];for(const i in this.arguments){const s=f(this.arguments[i]);if(s.variadic){t[i]=this.handleVariadicArgument(i,s,n);continue}t[i]=this.resolveArgumentValue(i,s,n.shift())}return t}handleVariadicArgument(e,t,n){return n.length?$(n,t.type,e,t.default):t.default}resolveArgumentValue(e,t,n){return n===void 0?t.default:$(n,t.type,e,t.default)}resolveOptionValue(e,t,n,i){let s;const o=[e,...t.alias];for(const l of o)if(l in n){s=n[l];break}if(s===void 0){if(t.required)throw new C({option:e,reason:`${i==="option"?"Option":"Argument"} is required but not provided`});return t.default}return $(s,t.type,e,t.default)}optionDefinitions(){const e={};for(const t in this.options)e[t]=f(this.options[t]);return e}argumentDefinitions(){const e={};for(const t in this.arguments)e[t]=f(this.arguments[t]);return e}availableOptions(){return Object.keys(this.options)}availableArguments(){return Object.keys(this.arguments)}}function R(r){return new Array(r+5).join(" ")}class V{type="boolean";option="help";alias=["h"];default=!1;description=a`Display help for the given command. When no command is given display help for the {green list} command`;async handler(){const e=this.parser.argumentDefinitions(),t=this.parser.optionDefinitions(),n=Object.entries(e),i=Object.entries(t),s=i.map(([m,c])=>{const h=Array.isArray(c.alias)?c.alias:c.alias?[c.alias]:[];return{name:m,...c,optionWithAlias:`--${m}${h.map(p=>`, -${p}`).join("")}`}}),o=n.filter(([,m])=>m.required);this.io.log(a`{yellow Description}:`),this.io.log(a` ${this.description}\n`),this.io.log(a`{yellow Usage}:`),this.io.log(a` ${this.command} ${o.length>0?o.map(([m])=>`<${m}>`).join(" "):"\b"} [options]`);const l=Math.max(...s.map(m=>m.optionWithAlias.length),0),u=Math.max(...n.map(([m])=>m.length),0),d=u>l?u:l;if(n.length>0){this.io.log(a`\n{yellow Arguments}:`);for(const[m,c]of n){const h=R(d-m.length);let p=a` {green ${m}} ${h} ${c.description??"\b"}`;if(c.default!==void 0&&!c.required){const T=(Array.isArray(c.type)?`[${c.type[0]}]`:c.type)==="array"||Array.isArray(c.type)?JSON.stringify(c.default):c.default;p+=a` {yellow [default: ${T}]}`}c.variadic&&(p+=a` {white (variadic)}`),this.io.log(p)}}if(i.length>0){this.io.log(a`\n{yellow Options}:`);for(const m of s){const c=R(d-m.optionWithAlias.length);let h=a`{green ${m.optionWithAlias}} ${c} ${m.description??"\b"}`;if(m.type){const p=Array.isArray(m.type)?`[${m.type[0]}]`:m.type;h+=a` {white (${p})}`}if(m.default!==void 0&&!m.required){const q=(Array.isArray(m.type)?`[${m.type[0]}]`:m.type)==="array"||Array.isArray(m.type)?JSON.stringify(m.default):m.default;h+=a` {yellow [default: ${q}]}`}this.io.log(h)}}if(this.commandsExamples.length>0){this.io.log(a`\n{yellow Examples}:`);let m=process.argv[0].split("/").pop();m==="node"&&(m+=" "+process.argv[1].split("/").pop());for(const[c,h]of this.commandsExamples.entries())c>0&&this.io.log(""),this.io.log(` ${h.description}
|
|
2
2
|
`),this.io.log(a` {green ${m} ${h.command}}`)}return-1}}class x{logger;constructor(e){this.logger=e}log(...e){this.logger.log(...e)}info(...e){this.logger.info(...e)}warn(...e){this.logger.warn(...e)}error(...e){this.logger.error(...e)}debug(...e){this.logger.debug(...e)}verbose(...e){this.logger.verbose(...e)}async askForConfirmation(e="Do you want to continue?",t){return(await w({type:"confirm",name:"value",message:e,initial:t??!1})).value}async askForInput(e,t,n){return(await w({type:"text",name:"value",message:e,initial:t,...n}))?.value??null}async askForToggle(e,t,n){return(await w({type:"toggle",name:"value",message:e,initial:t,...n}))?.value??null}async askForSelect(e,t,n){if(t.length===0)throw new Error("No options provided");const i=[];for(const o of t)typeof o=="string"?i.push({title:o,value:o}):i.push(o);return(await w({type:"select",name:"value",message:e,choices:i,...n}))?.value??null}newLoader(e="",t=["⠙","⠘","⠰","⠴","⠤","⠦","⠆","⠃","⠋","⠉"],n=100){let i=e,s=null,o=0;const l=setInterval(function(){s&&(process.stdout.write(new TextEncoder().encode("\r"+" ".repeat(s.length+5)+"\r")),s=null),process.stdout.write(new TextEncoder().encode("\r"+t[o++]+" "+i)),o=o%t.length},n),u=()=>{clearInterval(l),process.stdout.write(new TextEncoder().encode("\r"+" ".repeat(i.length+5)+"\r"))};return{[Symbol.dispose]:u,[Symbol.asyncDispose]:u,updateText:d=>{s=i,i=d},stop:u}}}class A{_command;description="";commandsExamples=[];get command(){return this._command}ctx;io;logger;_handler;parser;tmp;defaultOptions(){return[new V]}newCommandParser(e){return new S({io:e.io,options:e.options,arguments:e.arguments})}newCommandIO(e){return new x(e.logger)}constructor(e,t){this._command=e,this.description=t?.description??"";const n=this.defaultOptions();if(n.length>0){this.tmp={options:{},arguments:{}};for(const i of n)this.tmp.options[i.option]=i}}handler(e){return this._handler=e,this}options(e){return this.tmp={options:{...this.tmp?.options??{},...e},arguments:this.tmp?.arguments??{}},this}arguments(e){return this.tmp={options:this.tmp?.options??{},arguments:{...this.tmp?.arguments??{},...e}},this}async run(e){if(!this._handler&&!this.handle)throw new Error(`No handler defined for command ${this.command||"(unknown)"}`);let t;if(this.ctx=e.ctx,this.logger=e.logger,this.io=this.newCommandIO({logger:e.logger}),e&&"args"in e){const s=this.tmp?.options??{};for(const o of this.defaultOptions())o.option in s||(s[o.option]=o);this.parser=this.newCommandParser({io:this.io,options:s,arguments:this.tmp?.arguments??{}}),t=this.parser.init(e.args);for(const o of this.defaultOptions())if(t.options[o.option]===!0){const l=await o.handler.call(this);if(l&&l!==0)return l}await this.parser.validate()}else t={options:e.options,arguments:e.arguments};const n=this.preHandle?await this.preHandle():null;if(n&&n!==0)return n;if(!this._handler&&this.handle)this._handler=this.handle.bind(this);else if(!this._handler)throw new Error(`No handler defined for command ${this.command||"(unknown)"}`);return await this._handler(e.ctx,t)??0}}class g extends S{command;argumentsSchema;optionsSchema;constructor(e){const t=g.parseSignature(e.signature,e.helperDefinitions,e.defaultOptions);super({io:e.io,options:t.options,arguments:t.arguments}),this.command=t.command,this.optionsSchema=t.options,this.argumentsSchema=t.arguments}static parseSignature(e,t,n){const[i,...s]=e.split(/\{(.*?)\}/g).map(u=>u.trim()).filter(Boolean),o={},l={};for(const u of s){const{name:d,isOption:m,definition:c}=g.parseParamSignature(u,t);m?o[d]=c:l[d]=c}for(const u of n)o[u.option]={type:u.type,required:u.required,alias:u.alias,variadic:u.variadic??!1,description:u.description,default:u.default??null};return{command:i,options:o,arguments:l}}option(e){if(!this.optionsSchema[e])throw new b(e,this.optionsSchema);return super.option(e)}setOption(e,t){if(!this.optionsSchema[e])throw new b(e,this.optionsSchema);this.parsedOptions&&(this.parsedOptions[e]=t)}optionHelp(e){if(!this.optionsSchema[e])throw new b(e,this.optionsSchema);return f(this.optionsSchema[e]).description}argumentHelp(e){if(!this.argumentsSchema[e])throw new v(e,this.argumentsSchema);return f(this.argumentsSchema[e]).description}argument(e){if(!this.argumentsSchema[e])throw new v(e,this.argumentsSchema);return super.argument(e)}setArgument(e,t){if(!this.argumentsSchema[e])throw new v(e,this.argumentsSchema);this.parsedArguments&&(this.parsedArguments[e]=t)}getArgumentSignatures(){return this.argumentsSchema}getOptionSignatures(){return this.optionsSchema}static parseParamSignature(e,t){let n=e,i=!1;const s={required:!0,type:"string",description:void 0,default:null,variadic:!1};if(n.includes(":")){const[o,l]=n.split(":");n=o.trim(),s.description=l.trim()}if(n.includes("=")){const[o,l]=n.split("=");n=o.trim(),s.default=l.trim(),s.required=!1,s.default.length?s.default==="true"?(s.default=!0,s.type="boolean"):s.default==="false"&&(s.default=!1,s.type="boolean"):s.default=null}else n.startsWith("--")&&(s.required=!1,s.default=!1,s.type="boolean");if(n.includes("|")){const[o,...l]=n.split("|");n=o.trim(),s.alias=l.map(u=>u.trim())}return n.startsWith("--")&&(i=!0,n=n.slice(2)),s.default==="*"&&(s.default=[],s.type=["string"]),n.endsWith("?")&&(s.required=!1,n=n.slice(0,-1)),n.endsWith("*")&&(s.type=["string"],s.variadic=!0,s.default=[],n=n.slice(0,-1)),s.description=s.description??t[n]??t[`--${n}`],{name:n,isOption:i,definition:s}}async validate(){for(const e in this.argumentsSchema){const t=f(this.argumentsSchema[e]),n=this.argument(e);if(!n&&t.required){const i=await this.promptForArgument(e,t);if(i)this.setArgument(e,i);else throw new O(e)}if(t.variadic&&t.required&&typeof n=="object"&&!n?.length)throw new O(e)}}async promptForArgument(e,t){if(t.type!=="string")return null;let n=a`{yellow.bold ${e}} is required`;return t.description&&(n+=a`: {gray (${t.description})}`),n+=`
|
|
3
|
-
`,await this.io.askForInput(n,t.default,{validate:i=>i?.trim()?.length?!0:`${e} cannot be empty`})}optionValues(){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");return this.parsedOptions}argumentValues(){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");return this.parsedArguments}}class z extends A{helperDefinitions={};get command(){return this.parser?this.parser.command:this.signature.split(" ")[0]}newCommandParser(e){return new g({io:e.io,signature:this.signature,helperDefinitions:this.helperDefinitions,defaultOptions:this.defaultOptions()})}constructor(){super("")}setOption(e,t){this.parser.setOption(e,t)}setArgument(e,t){this.parser instanceof g&&this.parser.setArgument(e,t)}option(e,t=null){return this.parser instanceof g?this.parser.option(e)??t:t}optionBoolean(e,t=!1){return this.parser instanceof g?this.parser.option(e)??t:t}optionArray(e,t=[]){if(this.parser instanceof g){const n=this.parser.option(e);if(!Array.isArray(n))throw new Error(`Option ${e} is not an array`);if(n.length)return n}return t}optionNumber(e,t=null){if(this.parser instanceof g){const n=this.parser.option(e);return n?typeof n=="number"?n:parseInt(n):t}return t}argument(e,t=null){return this.parser instanceof g?this.parser.argument(e)??t:t}argumentArray(e,t=[]){if(this.parser instanceof g){const n=this.parser.argument(e);if(!Array.isArray(n))throw new Error(`Argument ${e} is not an array`);if(n?.length)return n}return t}argumentBoolean(e,t=!1){return this.parser instanceof g?this.parser.argument(e)??t:t}argumentNumber(e,t=null){if(this.parser instanceof g){const n=this.parser.argument(e);return n?typeof n=="number"?n:parseInt(n):t}return t}async askForConfirmation(...e){return this.io.askForConfirmation(...e)}async askForInput(...e){return this.io.askForInput(...e)}async askForSelect(...e){return this.io.askForSelect(...e)}newLoader(...e){return this.io.newLoader(...e)}}class E{level;constructor(e={}){this.level=e.level??"info"}shouldLog(e){const t=["debug","verbose","info","warn","error","silent"],n=t.indexOf(this.level);return t.indexOf(e)>=n}setLevel(e){this.level=e}getLevel(){return this.level}log(...e){console.log(...e)}info(...e){this.shouldLog("info")&&console.log(...e)}warn(...e){this.shouldLog("warn")&&console.warn(...e)}error(...e){this.shouldLog("error")&&console.error(...e)}debug(...e){this.shouldLog("debug")&&console.log(...e)}verbose(...e){this.shouldLog("verbose")&&console.log(...e)}}class H{commands={};io;logger;get CommandIOClass(){return x}constructor(e){this.logger=e??new E,this.io=new this.CommandIOClass(this.logger)}getAvailableCommands(){return Object.keys(this.commands)}getCommands(){return Object.values(this.commands)}commandResolver=async e=>{let t=(await import(e)).default;if(!t)throw new Error(`The command at path ${e} does not have a default export.`);t?.default&&(t=t.default);let n;if(typeof t=="function")n=new t;else if(t instanceof A)n=t;else throw new Error(`The command at path ${e} is not a valid command class.`);return n};setCommandResolver(e){this.commandResolver=e}registerCommand(e,t=!1){const n=e.command;if(!n)throw new Error("Command signature is invalid, it must have a command name.");if(!t&&this.commands[n])throw new Error(`Command ${n} already registered.`);this.commands[n]=e}async loadCommandsPath(e){for await(const t of this.listCommandsFiles(e))try{const n=await this.commandResolver(t);this.registerCommand(n)}catch(n){throw new Error(`Command ${t} failed to load. ${n}`,{cause:n})}}async runCommand(e,t,...n){const i=typeof t=="string"?this.commands[t]:t,s=typeof t=="string"?t:i.command;if(!i){const o=await this.suggestCommand(s);return o?await this.runCommand(e,o,...n):1}return await i.run({ctx:e,logger:this.logger,args:n})??0}async suggestCommand(e){const t=this.getAvailableCommands(),{bestMatch:n,bestMatchIndex:i,ratings:s}=G.findBestMatch(e,t),o=s.filter(l=>l.rating>.3).map(l=>l.target);if(n.rating>0&&o.length<=1||n.rating>.7&&o.length>1){const l=t[i];return await this.askRunSimilarCommand(e,l)?l:null}if(o.length){this.io.error(a`{bgRed ERROR } Command {yellow ${e}} not found.\n`);const l=await this.io.askForSelect(a`{green Did you mean to run one of these commands instead?}`,o);if(l)return l}throw new j(e)}async askRunSimilarCommand(e,t){return this.io.error(a`{bgRed ERROR } Command {yellow ${e}} not found.\n`),this.io.askForConfirmation(a`{green Do you want to run {yellow ${t}} instead?} `)}async*listCommandsFiles(e){const t=
|
|
3
|
+
`,await this.io.askForInput(n,t.default,{validate:i=>i?.trim()?.length?!0:`${e} cannot be empty`})}optionValues(){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");return this.parsedOptions}argumentValues(){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");return this.parsedArguments}}class z extends A{helperDefinitions={};get command(){return this.parser?this.parser.command:this.signature.split(" ")[0]}newCommandParser(e){return new g({io:e.io,signature:this.signature,helperDefinitions:this.helperDefinitions,defaultOptions:this.defaultOptions()})}constructor(){super("")}setOption(e,t){this.parser.setOption(e,t)}setArgument(e,t){this.parser instanceof g&&this.parser.setArgument(e,t)}option(e,t=null){return this.parser instanceof g?this.parser.option(e)??t:t}optionBoolean(e,t=!1){return this.parser instanceof g?this.parser.option(e)??t:t}optionArray(e,t=[]){if(this.parser instanceof g){const n=this.parser.option(e);if(!Array.isArray(n))throw new Error(`Option ${e} is not an array`);if(n.length)return n}return t}optionNumber(e,t=null){if(this.parser instanceof g){const n=this.parser.option(e);return n?typeof n=="number"?n:parseInt(n):t}return t}argument(e,t=null){return this.parser instanceof g?this.parser.argument(e)??t:t}argumentArray(e,t=[]){if(this.parser instanceof g){const n=this.parser.argument(e);if(!Array.isArray(n))throw new Error(`Argument ${e} is not an array`);if(n?.length)return n}return t}argumentBoolean(e,t=!1){return this.parser instanceof g?this.parser.argument(e)??t:t}argumentNumber(e,t=null){if(this.parser instanceof g){const n=this.parser.argument(e);return n?typeof n=="number"?n:parseInt(n):t}return t}async askForConfirmation(...e){return this.io.askForConfirmation(...e)}async askForInput(...e){return this.io.askForInput(...e)}async askForSelect(...e){return this.io.askForSelect(...e)}newLoader(...e){return this.io.newLoader(...e)}}class E{level;constructor(e={}){this.level=e.level??"info"}shouldLog(e){const t=["debug","verbose","info","warn","error","silent"],n=t.indexOf(this.level);return t.indexOf(e)>=n}setLevel(e){this.level=e}getLevel(){return this.level}log(...e){console.log(...e)}info(...e){this.shouldLog("info")&&console.log(...e)}warn(...e){this.shouldLog("warn")&&console.warn(...e)}error(...e){this.shouldLog("error")&&console.error(...e)}debug(...e){this.shouldLog("debug")&&console.log(...e)}verbose(...e){this.shouldLog("verbose")&&console.log(...e)}}class H{commands={};io;logger;get CommandIOClass(){return x}constructor(e){this.logger=e??new E,this.io=new this.CommandIOClass(this.logger)}getAvailableCommands(){return Object.keys(this.commands)}getCommands(){return Object.values(this.commands)}commandResolver=async e=>{let t=(await import(e)).default;if(!t)throw new Error(`The command at path ${e} does not have a default export.`);t?.default&&(t=t.default);let n;if(typeof t=="function")n=new t;else if(t instanceof A)n=t;else throw new Error(`The command at path ${e} is not a valid command class.`);return n};setCommandResolver(e){this.commandResolver=e}registerCommand(e,t=!1){const n=e.command;if(!n)throw new Error("Command signature is invalid, it must have a command name.");if(!t&&this.commands[n])throw new Error(`Command ${n} already registered.`);this.commands[n]=e}async loadCommandsPath(e){for await(const t of this.listCommandsFiles(e))try{const n=await this.commandResolver(t);this.registerCommand(n)}catch(n){throw new Error(`Command ${t} failed to load. ${n}`,{cause:n})}}async runCommand(e,t,...n){const i=typeof t=="string"?this.commands[t]:t,s=typeof t=="string"?t:i.command;if(!i){const o=await this.suggestCommand(s);return o?await this.runCommand(e,o,...n):1}return await i.run({ctx:e,logger:this.logger,args:n})??0}async suggestCommand(e){const t=this.getAvailableCommands(),{bestMatch:n,bestMatchIndex:i,ratings:s}=G.findBestMatch(e,t),o=s.filter(l=>l.rating>.3).map(l=>l.target);if(n.rating>0&&o.length<=1||n.rating>.7&&o.length>1){const l=t[i];return await this.askRunSimilarCommand(e,l)?l:null}if(o.length){this.io.error(a`{bgRed ERROR } Command {yellow ${e}} not found.\n`);const l=await this.io.askForSelect(a`{green Did you mean to run one of these commands instead?}`,o);if(l)return l}throw new j(e)}async askRunSimilarCommand(e,t){return this.io.error(a`{bgRed ERROR } Command {yellow ${e}} not found.\n`),this.io.askForConfirmation(a`{green Do you want to run {yellow ${t}} instead?} `)}async*listCommandsFiles(e){const t=_.readdirSync(e,{withFileTypes:!0});for(const n of t){const i=D.resolve(e,n.name);if(n.isDirectory())yield*this.listCommandsFiles(D.resolve(e,n.name));else{if(!i.endsWith(".ts")&&!i.endsWith(".js"))continue;yield i}}}}class J extends A{constructor(e){super("help",{description:a.bold("Show help information about the CLI and its commands")}),this.opts=e}async handle(){const e=this.opts.commandRegistry.getCommands(),t=this.opts.cliName??"Bob CLI",n=this.opts.cliVersion??"0.0.0",i=(await Promise.resolve().then(()=>require("./package-88kG_8yl.cjs")))?.default?.version??"0.0.0";this.io.log(a`${t} {green ${n}} (core: {yellow ${i}})
|
|
4
4
|
|
|
5
5
|
{yellow Usage}:
|
|
6
6
|
command [options] [arguments]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",s="2.0.0-beta.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",s="2.0.0-beta.2",t="BOB Core",i="module",n=!1,r=["dist/**"],o={".":{import:"./dist/esm/index.js",require:"./dist/cjs/index.js"}},c={"*":{"*":["./dist/cjs/*.d.ts"]}},d={start:"node -r @swc-node/register debug/main.ts",build:"rimraf ./dist && vite build",typecheck:"tsc --noEmit",prepare:"npm run build",test:"vitest run"},p="Léo Hubert",a="ISC",m={"@faker-js/faker":"^10.0.0","@swc-node/register":"^1.11.1","@types/minimist":"^1.2.5","@types/node":"^20.14.5","@types/prompts":"^2.4.9","@types/string-similarity":"^4.0.2","@vitest/coverage-v8":"^3.2.4",rimraf:"^6.0.1",tsx:"^4.20.6",typescript:"^5.7.3",vite:"^7.1.6","vite-plugin-dts":"^4.5.4",vitest:"^3.2.4"},l={chalk:"^4.1.2",minimist:"^1.2.8",prompts:"^2.4.2","string-similarity":"^4.0.4"},u={name:e,version:s,description:t,type:i,sideEffects:n,files:r,exports:o,typesVersions:c,scripts:d,author:p,license:a,devDependencies:m,dependencies:l};exports.author=p;exports.default=u;exports.dependencies=l;exports.description=t;exports.devDependencies=m;exports.exports=o;exports.files=r;exports.license=a;exports.name=e;exports.scripts=d;exports.sideEffects=n;exports.type=i;exports.typesVersions=c;exports.version=s;
|
package/dist/esm/index.js
CHANGED
|
@@ -324,7 +324,7 @@ class k {
|
|
|
324
324
|
function O(r) {
|
|
325
325
|
return new Array(r + 5).join(" ");
|
|
326
326
|
}
|
|
327
|
-
class
|
|
327
|
+
class W {
|
|
328
328
|
type = "boolean";
|
|
329
329
|
option = "help";
|
|
330
330
|
alias = ["h"];
|
|
@@ -480,7 +480,7 @@ class R {
|
|
|
480
480
|
parser;
|
|
481
481
|
tmp;
|
|
482
482
|
defaultOptions() {
|
|
483
|
-
return [new
|
|
483
|
+
return [new W()];
|
|
484
484
|
}
|
|
485
485
|
newCommandParser(t) {
|
|
486
486
|
return new k({
|
|
@@ -859,7 +859,7 @@ class L {
|
|
|
859
859
|
this.shouldLog("verbose") && console.log(...t);
|
|
860
860
|
}
|
|
861
861
|
}
|
|
862
|
-
class
|
|
862
|
+
class M {
|
|
863
863
|
commands = {};
|
|
864
864
|
io;
|
|
865
865
|
logger;
|
|
@@ -947,7 +947,13 @@ class W {
|
|
|
947
947
|
const e = F.readdirSync(t, { withFileTypes: !0 });
|
|
948
948
|
for (const n of e) {
|
|
949
949
|
const i = S.resolve(t, n.name);
|
|
950
|
-
n.isDirectory()
|
|
950
|
+
if (n.isDirectory())
|
|
951
|
+
yield* this.listCommandsFiles(S.resolve(t, n.name));
|
|
952
|
+
else {
|
|
953
|
+
if (!i.endsWith(".ts") && !i.endsWith(".js"))
|
|
954
|
+
continue;
|
|
955
|
+
yield i;
|
|
956
|
+
}
|
|
951
957
|
}
|
|
952
958
|
}
|
|
953
959
|
}
|
|
@@ -958,7 +964,7 @@ class B extends R {
|
|
|
958
964
|
}), this.opts = t;
|
|
959
965
|
}
|
|
960
966
|
async handle() {
|
|
961
|
-
const t = this.opts.commandRegistry.getCommands(), e = this.opts.cliName ?? "Bob CLI", n = this.opts.cliVersion ?? "0.0.0", i = (await import("./package-
|
|
967
|
+
const t = this.opts.commandRegistry.getCommands(), e = this.opts.cliName ?? "Bob CLI", n = this.opts.cliVersion ?? "0.0.0", i = (await import("./package-COKp1myj.js"))?.default?.version ?? "0.0.0";
|
|
962
968
|
this.io.log(a`${e} {green ${n}} (core: {yellow ${i}})
|
|
963
969
|
|
|
964
970
|
{yellow Usage}:
|
|
@@ -1001,7 +1007,7 @@ class Q {
|
|
|
1001
1007
|
exceptionHandler;
|
|
1002
1008
|
helpCommand;
|
|
1003
1009
|
newCommandRegistry(t) {
|
|
1004
|
-
return new
|
|
1010
|
+
return new M(t.logger);
|
|
1005
1011
|
}
|
|
1006
1012
|
newHelpCommand(t) {
|
|
1007
1013
|
return new B(t);
|
|
@@ -1046,11 +1052,11 @@ export {
|
|
|
1046
1052
|
q as CommandIO,
|
|
1047
1053
|
j as CommandNotFoundError,
|
|
1048
1054
|
k as CommandParser,
|
|
1049
|
-
|
|
1055
|
+
M as CommandRegistry,
|
|
1050
1056
|
g as CommandSignatureParser,
|
|
1051
1057
|
K as CommandWithSignature,
|
|
1052
1058
|
P as ExceptionHandler,
|
|
1053
|
-
|
|
1059
|
+
W as HelpOption,
|
|
1054
1060
|
H as InvalidOption,
|
|
1055
1061
|
L as Logger,
|
|
1056
1062
|
C as MissingRequiredArgumentValue,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const s = "bob-core", t = "2.0.0-beta.
|
|
1
|
+
const s = "bob-core", t = "2.0.0-beta.2", e = "BOB Core", i = "module", l = !1, n = ["dist/**"], r = { ".": { import: "./dist/esm/index.js", require: "./dist/cjs/index.js" } }, o = { "*": { "*": ["./dist/cjs/*.d.ts"] } }, c = { start: "node -r @swc-node/register debug/main.ts", build: "rimraf ./dist && vite build", typecheck: "tsc --noEmit", prepare: "npm run build", test: "vitest run" }, d = "Léo Hubert", p = "ISC", a = { "@faker-js/faker": "^10.0.0", "@swc-node/register": "^1.11.1", "@types/minimist": "^1.2.5", "@types/node": "^20.14.5", "@types/prompts": "^2.4.9", "@types/string-similarity": "^4.0.2", "@vitest/coverage-v8": "^3.2.4", rimraf: "^6.0.1", tsx: "^4.20.6", typescript: "^5.7.3", vite: "^7.1.6", "vite-plugin-dts": "^4.5.4", vitest: "^3.2.4" }, m = { chalk: "^4.1.2", minimist: "^1.2.8", prompts: "^2.4.2", "string-similarity": "^4.0.4" }, u = {
|
|
2
2
|
name: s,
|
|
3
3
|
version: t,
|
|
4
4
|
description: e,
|