bob-core 1.3.0 → 1.3.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/{bob-core.cjs → cjs/bob-core.cjs} +4 -4
- package/dist/cjs/package-BU-CgS6n.cjs +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/{bob-core.js → esm/bob-core.js} +44 -41
- package/dist/esm/package-Cth9f9Cv.js +27 -0
- package/dist/types/src/Command.d.ts +1 -7
- package/dist/types/src/index.d.ts +1 -0
- package/package.json +3 -3
- package/dist/package-CYbLjAxY.js +0 -27
- package/dist/package-CxLyePN6.cjs +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("minimist"),o=require("chalk"),f=require("prompts"),x=require("node:fs")
|
|
2
|
-
`,s=await this.io.askForInput(
|
|
3
|
-
`),e(o` {green ${a} ${c.command}}`)}return-1}}class
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("minimist"),o=require("chalk"),f=require("prompts"),x=require("node:fs"),$=require("path"),V=require("string-similarity");function b(l){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const t in l)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(l,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>l[t]})}}return e.default=l,Object.freeze(e)}const E=b(x),j=b(V);class p extends Error{}class S extends p{constructor(e){super(`Argument "${e.name}" is required.`),this.paramSignature=e}pretty(){const e=console.log;e(o`{white.bgRed ERROR } Argument {bold.yellow ${this.paramSignature.name}} is required.`)}}class y extends p{constructor(e,t){super(`Missing ${e} in the command signature`),this.option=e,this.optionsSignature=t}pretty(){const e=console.log;if(this.optionsSignature.length){e(o`{yellow Available options}:`);for(const t of this.optionsSignature){const n=t.type?o`{white (${t.type})}`:"",s=" ".repeat(20-t.name.length);e(o` {green ${t.name}} ${s} ${t.help??"\b"} ${n}`)}e("")}e(o`{white.bgRed ERROR } Option {bold.yellow ${this.option}} is missing in the signature.`)}}class w extends p{constructor(e,t){super(`Missing ${e} in the command signature`),this.argument=e,this.argumentSignatures=t}pretty(){const e=console.log;if(this.argumentSignatures.length){e(o`\n{yellow Available arguments}:`);for(const t of this.argumentSignatures){const n=t.type?o`{white (${t.type})}`:"",s=" ".repeat(20-t.name.length);e(o` {green ${t.name}} ${s} ${t.help??"\b"} ${n}`)}e("")}e(o`{white.bgRed ERROR } Argument {bold.yellow ${this.argument}} is missing in the signature.`)}}class k extends p{constructor(e,t){super(`Invalid option ${e} in not recognized`),this.option=e,this.optionsSignature=t}pretty(){const e=console.log;if(this.optionsSignature.length>0){e(o`\n{yellow Available options}:`);for(const t of this.optionsSignature){const n=t.type?o`{white (${t.type})}`:"",s=`--${t.name}${t.alias?.map(i=>`, -${i}`).join("")??""}`,r=" ".repeat(30-s.length);e(o` {green ${s}} ${r} ${t.help??"\b"} ${n}`)}e("")}e(o`{white.bgRed ERROR } Option {bold.yellow ${this.option}} is not recognized.`)}}class F{constructor(e,t,n,s,...r){this.io=e,this.signature=t,this.helperDefinitions=n,this.defaultCommandOptions=s;const[i,...u]=t.split(/\{(.*?)\}/g).map(c=>c.trim()).filter(Boolean),{_:a,...m}=A(r);this.command=i,this.parseSignature(u),this.parseDefaultOptions(),this.handleArguments(a),this.handleOptions(m)}command;arguments={};options={};argumentsSignature={};optionSignatures={};optionAliases={};option(e){if(!this.optionSignatures[e])throw new y(e,Object.values(this.optionSignatures));return this.options[e]}setOption(e,t){if(!this.optionSignatures[e])throw new y(e,Object.values(this.optionSignatures));this.options[e]=t}optionHelp(e){if(!this.optionSignatures[e])throw new y(e,Object.values(this.optionSignatures));return this.optionSignatures[e].help}argument(e){if(!this.argumentsSignature[e])throw new w(e,Object.values(this.argumentsSignature));return this.arguments[e]}setArgument(e,t){if(!this.argumentsSignature[e])throw new w(e,Object.values(this.argumentsSignature));this.arguments[e]=t}argumentHelp(e){if(!this.argumentsSignature[e])throw new w(e,Object.values(this.argumentsSignature));return this.argumentsSignature[e].help}getArgumentSignatures(){return this.argumentsSignature}getOptionSignatures(){return this.optionSignatures}getParamValue(e,t){return t.type==="boolean"?e==="true"||e==="1"?!0:e==="false"||e==="0"?!1:!!e:t.type==="array"?e?Array.isArray(e)?e:[e]:[]:e??t.defaultValue}handleArguments(e){for(const[t,n]of Object.entries(this.arguments)){const s=this.argumentsSignature[t];if(s.variadic)this.arguments[t]=e;else{const r=e.shift();this.arguments[t]=this.getParamValue(r,s)}}}handleOptions(e){for(const[t,n]of Object.entries(e)){const s=this.optionAliases[t],r=this.optionSignatures[t]??this.optionSignatures[s];if(!r)throw new k(t,Object.values(this.optionSignatures));this.options[t]=this.getParamValue(n,r);for(const i of r.alias??[])e[i]&&(this.options[r.name]=e[i])}}parseSignature(e){for(const t of e){const n=this.parseParamSignature(t);if(n.isOption){this.options[n.name]=n.defaultValue??null,this.optionSignatures[n.name]=n;for(const s of n.alias??[])this.optionAliases[s]=n.name}else this.arguments[n.name]=n.defaultValue??null,this.argumentsSignature[n.name]=n}}parseDefaultOptions(){if(this.defaultCommandOptions.length){for(const e of this.defaultCommandOptions)if(this.optionSignatures[e.option]={name:e.option,type:e.defaultValue==null?"string":typeof e.defaultValue=="boolean"?"boolean":Array.isArray(e.defaultValue)?"array":"string",optional:!0,alias:e.alias,variadic:!1,help:e.description,defaultValue:e.defaultValue??null,isOption:!0},this.options[e.option]=e.defaultValue,e.alias)for(const t of e.alias)this.optionAliases[t]=e.option}}parseParamSignature(e){const t={name:e,optional:!1,type:"string",help:void 0,defaultValue:null,variadic:!1,isOption:!1};if(t.name.includes(":")){const[n,s]=t.name.split(":");t.name=n.trim(),t.help=s.trim()}if(t.name.includes("=")){const[n,s]=t.name.split("=");t.name=n.trim(),t.defaultValue=s.trim(),t.optional=!0,t.defaultValue.length?t.defaultValue==="true"?(t.defaultValue=!0,t.type="boolean"):t.defaultValue==="false"&&(t.defaultValue=!1,t.type="boolean"):t.defaultValue=null}else t.name.startsWith("--")&&(t.optional=!0,t.defaultValue=!1,t.type="boolean");if(t.name.includes("|")){const[n,...s]=t.name.split("|");t.name=n.trim(),t.alias=s.map(r=>r.trim())}return t.name.startsWith("--")&&(t.isOption=!0,t.name=t.name.slice(2)),t.defaultValue==="*"&&(t.defaultValue=[],t.type="array"),t.name.endsWith("?")&&(t.optional=!0,t.name=t.name.slice(0,-1)),t.name.endsWith("*")&&(t.type="array",t.variadic=!0,t.defaultValue=[],t.name=t.name.slice(0,-1)),t.help=t.help??this.helperDefinitions[t.name]??this.helperDefinitions[`--${t.name}`],t}async validate(){for(const[e,t]of Object.entries(this.arguments)){const n=this.argumentsSignature[e];if(!t&&!n.optional){let s=null;switch(n.type){case"string":let r=o`{yellow.bold ${n.name}} is required`;n.help&&(r+=o`: {gray (${n.help})}`),r+=`
|
|
2
|
+
`,s=await this.io.askForInput(r,n.defaultValue,{validate:i=>i?.trim()?.length?!0:`${n.name} cannot be empty`});break}if(s)this.setArgument(e,s);else throw new S(n)}if(!t?.length&&n.variadic&&!n.optional)throw new S(n)}}}function C(l){return new Array(l+5).join(" ")}class O{option="help";alias=["h"];defaultValue=!1;description=o`Display help for the given command. When no command is given display help for the {green list} command`;async handler(){const e=console.log,t=Object.values(this.parser.getArgumentSignatures()),n=Object.values(this.parser.getOptionSignatures()).map(a=>({...a,optionWithAlias:`--${a.name}${a.alias?.map(m=>`, -${m}`).join("")??""}`})),s=t.filter(a=>!a.optional);e(o`{yellow Description}:`),e(o` ${this.description}\n`),e(o`{yellow Usage}:`),e(o` ${this.command} ${s.length>0?s.map(a=>`<${a.name}>`).join(" "):"\b"} [options]`);const r=Math.max(...n.map(a=>a.optionWithAlias.length))??0,i=Math.max(...t.map(a=>a.name.length))??0,u=i>r?i:r;if(t.length>0){e(o`\n{yellow Arguments}:`);for(const a of t){const m=C(u-a.name.length);let c=o` {green ${a.name}} ${m} ${a.help??"\b"}`;if(a.defaultValue!==void 0&&a.optional){const h=a.type==="array"?JSON.stringify(a.defaultValue):a.defaultValue;c+=o` {yellow [default: ${h}]}`}a.variadic&&(c+=o` {white (variadic)}`),e(c)}}if(n.length>0){e(o`\n{yellow Options}:`);for(const a of n){const m=C(u-a.optionWithAlias.length);let c=o`{green ${a.optionWithAlias}} ${m} ${a.help??"\b"}`;if(a.type&&(c+=o` {white (${a.type})}`),a.defaultValue!==void 0&&a.optional){const h=a.type==="array"?JSON.stringify(a.defaultValue):a.defaultValue;c+=o` {yellow [default: ${h}]}`}e(c)}}if(this.commandsExamples.length>0){e(o`\n{yellow Examples}:`);let a=process.argv[0].split("/").pop();a==="node"&&(a+=" "+process.argv[1].split("/").pop());for(const[m,c]of this.commandsExamples.entries())m>0&&e(""),e(` ${c.description}
|
|
3
|
+
`),e(o` {green ${a} ${c.command}}`)}return-1}}class v{async askForConfirmation(e="Do you want to continue?",t){return(await f({type:"confirm",name:"value",message:e,initial:t??!1})).value}async askForInput(e,t,n){return(await f({type:"text",name:"value",message:e,initial:t,...n}))?.value??null}async askForToggle(e,t,n){return(await f({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 s=[];for(const i of t)typeof i=="string"?s.push({title:i,value:i}):s.push(i);return(await f({type:"select",name:"value",message:e,choices:s,...n}))?.value??null}newLoader(e="",t=["⠙","⠘","⠰","⠴","⠤","⠦","⠆","⠃","⠋","⠉"],n=100){let s=e,r=null,i=0;const u=setInterval(function(){r&&(process.stdout.write(new TextEncoder().encode("\r"+" ".repeat(r.length+5)+"\r")),r=null),process.stdout.write(new TextEncoder().encode("\r"+t[i++]+" "+s)),i=i%t.length},n),a=()=>{clearInterval(u),process.stdout.write(new TextEncoder().encode("\r"+" ".repeat(s.length+5)+"\r"))};return{[Symbol.dispose]:a,[Symbol.asyncDispose]:a,updateText:m=>{r=s,s=m},stop:a}}}class R{ctx;helperDefinitions={};commandsExamples=[];parser;io;get CommandParserClass(){return F}get CommandIOClass(){return v}defaultOptions(){return[new O]}get command(){return this.parser?this.parser.command:this.signature.split(" ")[0]}async run(e,...t){this.ctx=e;const n=this.defaultOptions();this.io=new this.CommandIOClass,this.parser=new this.CommandParserClass(this.io,this.signature,this.helperDefinitions,n,...t);for(const r of n)if(this.parser.option(r.option)){const i=await r.handler.call(this);if(i&&i!==0)return i}await this.parser.validate();const s=this.preHandle?await this.preHandle():null;return s&&s!==0?s:await this.handle()??0}setOption(e,t){this.parser.setOption(e,t)}setArgument(e,t){this.parser.setArgument(e,t)}option(e,t=null){return this.parser.option(e)??t}optionBoolean(e,t=!1){return this.parser.option(e)??t}optionArray(e,t=[]){const n=this.parser.option(e);if(!Array.isArray(n))throw new Error(`Option ${e} is not an array`);return n.length?n:t}optionNumber(e,t=null){const n=this.parser.option(e);return n?typeof n=="number"?n:parseInt(n):t}argument(e,t=null){return this.parser.argument(e)??t}argumentArray(e,t=[]){const n=this.parser.argument(e);if(!Array.isArray(n))throw new Error(`Argument ${e} is not an array`);return n?.length?n:t}argumentBoolean(e,t=!1){return this.parser.argument(e)??t}argumentNumber(e,t=null){const n=this.parser.argument(e);return n?typeof n=="number"?n:parseInt(n):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 H extends p{constructor(e){super(`Command "${e}" not found.`),this.command=e}pretty(){const e=console.log;e(o`{bgRed ERROR } Command {yellow ${this.command}} not found.`)}}class I{commands={};io;get commandSuffix(){return"Command"}get CommandIOClass(){return v}constructor(){this.io=new this.CommandIOClass}getAvailableCommands(){return Object.keys(this.commands)}getCommands(){return Object.values(this.commands)}commandResolver=async e=>{const t=(await import(e)).default;let n;return t?.default?n=new t.default:n=new t,n};setCommandResolver(e){this.commandResolver=e}registerCommand(e,t=!1){const n=e.signature.split(" ")[0];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}`)}}async runCommand(e,t,...n){const s=typeof t=="string"?this.commands[t]:t,r=typeof t=="string"?t:s.command;if(!s){const i=await this.suggestCommand(r);return i?await this.runCommand(e,i,...n):1}return await s.run(e,...n)}async suggestCommand(e){const t=this.getAvailableCommands(),{bestMatch:n,bestMatchIndex:s,ratings:r}=j.findBestMatch(e,t),i=r.filter(u=>u.rating>.3).map(u=>u.target);if(n.rating>0&&i.length<=1||n.rating>.7&&i.length>1){const u=t[s];return await this.askRunSimilarCommand(e,u)?u:null}if(i.length){console.log(o`{bgRed ERROR } Command {yellow ${e}} not found.\n`);const u=await this.io.askForSelect(o`{green Did you mean to run one of these commands instead?}`,i);if(u)return u}throw new H(e)}async askRunSimilarCommand(e,t){return console.log(o`{bgRed ERROR } Command {yellow ${e}} not found.\n`),this.io.askForConfirmation(o`{green Do you want to run {yellow ${t}} instead?} `)}async*listCommandsFiles(e){const t=E.readdirSync(e,{withFileTypes:!0});for(const n of t){const s=$.resolve(e,n.name);if(n.isDirectory())yield*this.listCommandsFiles($.resolve(e,n.name));else{if(!s.endsWith(`${this.commandSuffix}.ts`)&&!s.endsWith(`${this.commandSuffix}.js`))continue;yield s}}}}class D extends R{constructor(e){super(),this.opts=e}signature="help";description="Show help";async handle(){const e=this.opts.commandRegistry.getCommands(),t=this.opts.cliName??"Bob CLI",n=this.opts.cliVersion??"0.0.0",s=(await Promise.resolve().then(()=>require("./package-BU-CgS6n.cjs")))?.default?.version??"0.0.0";console.log(o`${t} {green ${n}} (core: {yellow ${s}})
|
|
4
4
|
|
|
5
5
|
{yellow Usage}:
|
|
6
6
|
command [options] [arguments]
|
|
7
7
|
|
|
8
8
|
{yellow Available commands}:
|
|
9
|
-
`);const
|
|
9
|
+
`);const r=Math.max(...e.map(a=>a.command.length))??0,i={};for(const a of e){const m=a.command.split(":")[0];i[m]||(i[m]=[]),i[m].push(a)}const u=Object.entries(i).sort(([a],[m])=>a.toLowerCase().localeCompare(m.toLowerCase())).sort(([,a],[,m])=>a.length-m.length);for(const[a,m]of u){const c=m.length>1;c&&console.log(o`{yellow ${a}}:`);const h=m.sort((d,g)=>d.command.toLowerCase().localeCompare(g.command.toLowerCase()));for(const d of h){let g=C(r-d.command.length);c&&(g=g.slice(2)),console.log(o`${c?" ":""}{green ${d.command}} ${g} ${d.description}`)}}}}class P extends p{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(){const e=console.log;e(o` {white.bgRed ERROR } Argument {bold.yellow ${this.param.param}} value is invalid. `),(this.param.value||this.param.reason)&&e(""),this.param.value&&e(o` {blue Value}: ${this.param.value}`),this.param.reason&&e(o` {yellow Reason}: ${this.param.reason}`)}}class B extends p{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(){const e=console.log;e(o` {white.bgRed ERROR } Option {bold.yellow ${this.param.option}} value is invalid. `),(this.param.value||this.param.reason)&&e(""),this.param.value&&e(o` {blue Value}: ${this.param.value}`),this.param.reason&&e(o` {yellow Reason}: ${this.param.reason}`)}}class M{handle(e){if(e instanceof p)return e.pretty(),-1;throw e}}class T{commandRegistry;exceptionHandler;ctx;helpCommand;get CommandRegistryClass(){return I}get HelpCommandClass(){return D}get ExceptionHandlerClass(){return M}constructor(e={}){this.ctx=e.ctx,this.commandRegistry=new this.CommandRegistryClass,this.exceptionHandler=new this.ExceptionHandlerClass,this.helpCommand=new this.HelpCommandClass({cliName:e.name,cliVersion:e.version,commandRegistry:this.commandRegistry})}setCommandResolver(e){this.commandRegistry.setCommandResolver(e)}async withCommands(...e){for(const t of e)typeof t=="string"?await this.commandRegistry.loadCommandsPath(t):typeof t=="function"?this.registerCommand(new t):this.registerCommand(t)}async runCommand(e,...t){return e?await this.commandRegistry.runCommand(this.ctx,e,...t).catch(this.exceptionHandler.handle):await this.runHelpCommand()}async runHelpCommand(){return await this.runCommand(this.helpCommand)}registerCommand(e){this.commandRegistry.registerCommand(e)}}exports.BadCommandOption=B;exports.BadCommandParameter=P;exports.BobError=p;exports.Cli=T;exports.Command=R;exports.CommandIO=v;exports.HelpOption=O;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",s="1.3.2",t="BOB Core",i="module",r=["/dist"],n={".":{types:"./dist/types/src/index.d.ts",import:"./dist/esm/bob-core.js",require:"./dist/cjs/bob-core.cjs"}},o={start:"node -r @swc-node/register debug/main.ts",build:"rimraf ./dist && vite build",prepare:"npm run build",test:"vitest run"},c="Léo Hubert",p="ISC",d={"@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",rimraf:"^6.0.1",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"},a={name:e,version:s,description:t,type:i,files:r,exports:n,scripts:o,author:c,license:p,devDependencies:d,dependencies:m};exports.author=c;exports.default=a;exports.dependencies=m;exports.description=t;exports.devDependencies=d;exports.exports=n;exports.files=r;exports.license=p;exports.name=e;exports.scripts=o;exports.type=i;exports.version=s;
|
|
@@ -58,8 +58,8 @@ class A extends c {
|
|
|
58
58
|
if (this.optionsSignature.length > 0) {
|
|
59
59
|
t(o`\n{yellow Available options}:`);
|
|
60
60
|
for (const e of this.optionsSignature) {
|
|
61
|
-
const n = e.type ? o`{white (${e.type})}` : "", s = `--${e.name}${e.alias?.map((
|
|
62
|
-
t(o` {green ${s}} ${
|
|
61
|
+
const n = e.type ? o`{white (${e.type})}` : "", s = `--${e.name}${e.alias?.map((i) => `, -${i}`).join("") ?? ""}`, r = " ".repeat(30 - s.length);
|
|
62
|
+
t(o` {green ${s}} ${r} ${e.help ?? "\b"} ${n}`);
|
|
63
63
|
}
|
|
64
64
|
t("");
|
|
65
65
|
}
|
|
@@ -67,10 +67,10 @@ class A extends c {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
class x {
|
|
70
|
-
constructor(t, e, n, s, ...
|
|
70
|
+
constructor(t, e, n, s, ...r) {
|
|
71
71
|
this.io = t, this.signature = e, this.helperDefinitions = n, this.defaultCommandOptions = s;
|
|
72
|
-
const [
|
|
73
|
-
this.command =
|
|
72
|
+
const [i, ...m] = e.split(/\{(.*?)\}/g).map((p) => p.trim()).filter(Boolean), { _: a, ...l } = b(r);
|
|
73
|
+
this.command = i, this.parseSignature(m), this.parseDefaultOptions(), this.handleArguments(a), this.handleOptions(l);
|
|
74
74
|
}
|
|
75
75
|
command;
|
|
76
76
|
arguments = {};
|
|
@@ -123,19 +123,19 @@ class x {
|
|
|
123
123
|
if (s.variadic)
|
|
124
124
|
this.arguments[e] = t;
|
|
125
125
|
else {
|
|
126
|
-
const
|
|
127
|
-
this.arguments[e] = this.getParamValue(
|
|
126
|
+
const r = t.shift();
|
|
127
|
+
this.arguments[e] = this.getParamValue(r, s);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
handleOptions(t) {
|
|
132
132
|
for (const [e, n] of Object.entries(t)) {
|
|
133
|
-
const s = this.optionAliases[e],
|
|
134
|
-
if (!
|
|
133
|
+
const s = this.optionAliases[e], r = this.optionSignatures[e] ?? this.optionSignatures[s];
|
|
134
|
+
if (!r)
|
|
135
135
|
throw new A(e, Object.values(this.optionSignatures));
|
|
136
|
-
this.options[e] = this.getParamValue(n,
|
|
137
|
-
for (const
|
|
138
|
-
t[
|
|
136
|
+
this.options[e] = this.getParamValue(n, r);
|
|
137
|
+
for (const i of r.alias ?? [])
|
|
138
|
+
t[i] && (this.options[r.name] = t[i]);
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
parseSignature(t) {
|
|
@@ -187,7 +187,7 @@ class x {
|
|
|
187
187
|
e.name.startsWith("--") && (e.optional = !0, e.defaultValue = !1, e.type = "boolean");
|
|
188
188
|
if (e.name.includes("|")) {
|
|
189
189
|
const [n, ...s] = e.name.split("|");
|
|
190
|
-
e.name = n.trim(), e.alias = s.map((
|
|
190
|
+
e.name = n.trim(), e.alias = s.map((r) => r.trim());
|
|
191
191
|
}
|
|
192
192
|
return e.name.startsWith("--") && (e.isOption = !0, e.name = e.name.slice(2)), e.defaultValue === "*" && (e.defaultValue = [], e.type = "array"), e.name.endsWith("?") && (e.optional = !0, e.name = e.name.slice(0, -1)), e.name.endsWith("*") && (e.type = "array", e.variadic = !0, e.defaultValue = [], e.name = e.name.slice(0, -1)), e.help = e.help ?? this.helperDefinitions[e.name] ?? this.helperDefinitions[`--${e.name}`], e;
|
|
193
193
|
}
|
|
@@ -198,10 +198,10 @@ class x {
|
|
|
198
198
|
let s = null;
|
|
199
199
|
switch (n.type) {
|
|
200
200
|
case "string":
|
|
201
|
-
let
|
|
202
|
-
n.help && (
|
|
203
|
-
`, s = await this.io.askForInput(
|
|
204
|
-
validate: (
|
|
201
|
+
let r = o`{yellow.bold ${n.name}} is required`;
|
|
202
|
+
n.help && (r += o`: {gray (${n.help})}`), r += `
|
|
203
|
+
`, s = await this.io.askForInput(r, n.defaultValue, {
|
|
204
|
+
validate: (i) => i?.trim()?.length ? !0 : `${n.name} cannot be empty`
|
|
205
205
|
});
|
|
206
206
|
break;
|
|
207
207
|
}
|
|
@@ -229,7 +229,7 @@ class V {
|
|
|
229
229
|
optionWithAlias: `--${a.name}${a.alias?.map((l) => `, -${l}`).join("") ?? ""}`
|
|
230
230
|
})), s = e.filter((a) => !a.optional);
|
|
231
231
|
t(o`{yellow Description}:`), t(o` ${this.description}\n`), t(o`{yellow Usage}:`), t(o` ${this.command} ${s.length > 0 ? s.map((a) => `<${a.name}>`).join(" ") : "\b"} [options]`);
|
|
232
|
-
const
|
|
232
|
+
const r = Math.max(...n.map((a) => a.optionWithAlias.length)) ?? 0, i = Math.max(...e.map((a) => a.name.length)) ?? 0, m = i > r ? i : r;
|
|
233
233
|
if (e.length > 0) {
|
|
234
234
|
t(o`\n{yellow Arguments}:`);
|
|
235
235
|
for (const a of e) {
|
|
@@ -299,8 +299,8 @@ class S {
|
|
|
299
299
|
if (e.length === 0)
|
|
300
300
|
throw new Error("No options provided");
|
|
301
301
|
const s = [];
|
|
302
|
-
for (const
|
|
303
|
-
typeof
|
|
302
|
+
for (const i of e)
|
|
303
|
+
typeof i == "string" ? s.push({ title: i, value: i }) : s.push(i);
|
|
304
304
|
return (await f({
|
|
305
305
|
type: "select",
|
|
306
306
|
name: "value",
|
|
@@ -310,9 +310,9 @@ class S {
|
|
|
310
310
|
}))?.value ?? null;
|
|
311
311
|
}
|
|
312
312
|
newLoader(t = "", e = ["⠙", "⠘", "⠰", "⠴", "⠤", "⠦", "⠆", "⠃", "⠋", "⠉"], n = 100) {
|
|
313
|
-
let s = t,
|
|
313
|
+
let s = t, r = null, i = 0;
|
|
314
314
|
const m = setInterval(function() {
|
|
315
|
-
|
|
315
|
+
r && (process.stdout.write(new TextEncoder().encode("\r" + " ".repeat(r.length + 5) + "\r")), r = null), process.stdout.write(new TextEncoder().encode("\r" + e[i++] + " " + s)), i = i % e.length;
|
|
316
316
|
}, n), a = () => {
|
|
317
317
|
clearInterval(m), process.stdout.write(new TextEncoder().encode("\r" + " ".repeat(s.length + 5) + "\r"));
|
|
318
318
|
};
|
|
@@ -320,7 +320,7 @@ class S {
|
|
|
320
320
|
[Symbol.dispose]: a,
|
|
321
321
|
[Symbol.asyncDispose]: a,
|
|
322
322
|
updateText: (l) => {
|
|
323
|
-
|
|
323
|
+
r = s, s = l;
|
|
324
324
|
},
|
|
325
325
|
stop: a
|
|
326
326
|
};
|
|
@@ -348,13 +348,15 @@ class E {
|
|
|
348
348
|
this.ctx = t;
|
|
349
349
|
const n = this.defaultOptions();
|
|
350
350
|
this.io = new this.CommandIOClass(), this.parser = new this.CommandParserClass(this.io, this.signature, this.helperDefinitions, n, ...e);
|
|
351
|
-
for (const
|
|
352
|
-
if (this.parser.option(
|
|
353
|
-
const i = await
|
|
351
|
+
for (const r of n)
|
|
352
|
+
if (this.parser.option(r.option)) {
|
|
353
|
+
const i = await r.handler.call(this);
|
|
354
354
|
if (i && i !== 0)
|
|
355
355
|
return i;
|
|
356
356
|
}
|
|
357
|
-
|
|
357
|
+
await this.parser.validate();
|
|
358
|
+
const s = this.preHandle ? await this.preHandle() : null;
|
|
359
|
+
return s && s !== 0 ? s : await this.handle() ?? 0;
|
|
358
360
|
}
|
|
359
361
|
setOption(t, e) {
|
|
360
362
|
this.parser.setOption(t, e);
|
|
@@ -463,24 +465,24 @@ class F {
|
|
|
463
465
|
}
|
|
464
466
|
}
|
|
465
467
|
async runCommand(t, e, ...n) {
|
|
466
|
-
const s = typeof e == "string" ? this.commands[e] : e,
|
|
468
|
+
const s = typeof e == "string" ? this.commands[e] : e, r = typeof e == "string" ? e : s.command;
|
|
467
469
|
if (!s) {
|
|
468
|
-
const
|
|
469
|
-
return
|
|
470
|
+
const i = await this.suggestCommand(r);
|
|
471
|
+
return i ? await this.runCommand(t, i, ...n) : 1;
|
|
470
472
|
}
|
|
471
473
|
return await s.run(t, ...n);
|
|
472
474
|
}
|
|
473
475
|
async suggestCommand(t) {
|
|
474
|
-
const e = this.getAvailableCommands(), { bestMatch: n, bestMatchIndex: s, ratings:
|
|
475
|
-
if (n.rating > 0 &&
|
|
476
|
+
const e = this.getAvailableCommands(), { bestMatch: n, bestMatchIndex: s, ratings: r } = O.findBestMatch(t, e), i = r.filter((m) => m.rating > 0.3).map((m) => m.target);
|
|
477
|
+
if (n.rating > 0 && i.length <= 1 || n.rating > 0.7 && i.length > 1) {
|
|
476
478
|
const m = e[s];
|
|
477
479
|
return await this.askRunSimilarCommand(t, m) ? m : null;
|
|
478
480
|
}
|
|
479
|
-
if (
|
|
481
|
+
if (i.length) {
|
|
480
482
|
console.log(o`{bgRed ERROR } Command {yellow ${t}} not found.\n`);
|
|
481
483
|
const m = await this.io.askForSelect(
|
|
482
484
|
o`{green Did you mean to run one of these commands instead?}`,
|
|
483
|
-
|
|
485
|
+
i
|
|
484
486
|
);
|
|
485
487
|
if (m)
|
|
486
488
|
return m;
|
|
@@ -511,7 +513,7 @@ class k extends E {
|
|
|
511
513
|
signature = "help";
|
|
512
514
|
description = "Show help";
|
|
513
515
|
async handle() {
|
|
514
|
-
const t = this.opts.commandRegistry.getCommands(), e = this.opts.cliName ?? "Bob CLI", n = this.opts.cliVersion ?? "0.0.0", s = (await import("./package-
|
|
516
|
+
const t = this.opts.commandRegistry.getCommands(), e = this.opts.cliName ?? "Bob CLI", n = this.opts.cliVersion ?? "0.0.0", s = (await import("./package-Cth9f9Cv.js"))?.default?.version ?? "0.0.0";
|
|
515
517
|
console.log(o`${e} {green ${n}} (core: {yellow ${s}})
|
|
516
518
|
|
|
517
519
|
{yellow Usage}:
|
|
@@ -519,18 +521,18 @@ class k extends E {
|
|
|
519
521
|
|
|
520
522
|
{yellow Available commands}:
|
|
521
523
|
`);
|
|
522
|
-
const
|
|
524
|
+
const r = Math.max(...t.map((a) => a.command.length)) ?? 0, i = {};
|
|
523
525
|
for (const a of t) {
|
|
524
526
|
const l = a.command.split(":")[0];
|
|
525
|
-
|
|
527
|
+
i[l] || (i[l] = []), i[l].push(a);
|
|
526
528
|
}
|
|
527
|
-
const m = Object.entries(
|
|
529
|
+
const m = Object.entries(i).sort(([a], [l]) => a.toLowerCase().localeCompare(l.toLowerCase())).sort(([, a], [, l]) => a.length - l.length);
|
|
528
530
|
for (const [a, l] of m) {
|
|
529
531
|
const p = l.length > 1;
|
|
530
532
|
p && console.log(o`{yellow ${a}}:`);
|
|
531
533
|
const h = l.sort((d, g) => d.command.toLowerCase().localeCompare(g.command.toLowerCase()));
|
|
532
534
|
for (const d of h) {
|
|
533
|
-
let g = C(
|
|
535
|
+
let g = C(r - d.command.length);
|
|
534
536
|
p && (g = g.slice(2)), console.log(o`${p ? " " : ""}{green ${d.command}} ${g} ${d.description}`);
|
|
535
537
|
}
|
|
536
538
|
}
|
|
@@ -556,7 +558,7 @@ class M extends c {
|
|
|
556
558
|
t(o` {white.bgRed ERROR } Option {bold.yellow ${this.param.option}} value is invalid. `), (this.param.value || this.param.reason) && t(""), this.param.value && t(o` {blue Value}: ${this.param.value}`), this.param.reason && t(o` {yellow Reason}: ${this.param.reason}`);
|
|
557
559
|
}
|
|
558
560
|
}
|
|
559
|
-
class
|
|
561
|
+
class H {
|
|
560
562
|
handle(t) {
|
|
561
563
|
if (t instanceof c)
|
|
562
564
|
return t.pretty(), -1;
|
|
@@ -575,7 +577,7 @@ class N {
|
|
|
575
577
|
return k;
|
|
576
578
|
}
|
|
577
579
|
get ExceptionHandlerClass() {
|
|
578
|
-
return
|
|
580
|
+
return H;
|
|
579
581
|
}
|
|
580
582
|
constructor(t = {}) {
|
|
581
583
|
this.ctx = t.ctx, this.commandRegistry = new this.CommandRegistryClass(), this.exceptionHandler = new this.ExceptionHandlerClass(), this.helpCommand = new this.HelpCommandClass({
|
|
@@ -607,5 +609,6 @@ export {
|
|
|
607
609
|
c as BobError,
|
|
608
610
|
N as Cli,
|
|
609
611
|
E as Command,
|
|
612
|
+
S as CommandIO,
|
|
610
613
|
V as HelpOption
|
|
611
614
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const s = "bob-core", t = "1.3.2", e = "BOB Core", i = "module", r = ["/dist"], n = { ".": { types: "./dist/types/src/index.d.ts", import: "./dist/esm/bob-core.js", require: "./dist/cjs/bob-core.cjs" } }, o = { start: "node -r @swc-node/register debug/main.ts", build: "rimraf ./dist && vite build", prepare: "npm run build", test: "vitest run" }, c = "Léo Hubert", p = "ISC", d = { "@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", rimraf: "^6.0.1", 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" }, a = {
|
|
2
|
+
name: s,
|
|
3
|
+
version: t,
|
|
4
|
+
description: e,
|
|
5
|
+
type: i,
|
|
6
|
+
files: r,
|
|
7
|
+
exports: n,
|
|
8
|
+
scripts: o,
|
|
9
|
+
author: c,
|
|
10
|
+
license: p,
|
|
11
|
+
devDependencies: d,
|
|
12
|
+
dependencies: m
|
|
13
|
+
};
|
|
14
|
+
export {
|
|
15
|
+
c as author,
|
|
16
|
+
a as default,
|
|
17
|
+
m as dependencies,
|
|
18
|
+
e as description,
|
|
19
|
+
d as devDependencies,
|
|
20
|
+
n as exports,
|
|
21
|
+
r as files,
|
|
22
|
+
p as license,
|
|
23
|
+
s as name,
|
|
24
|
+
o as scripts,
|
|
25
|
+
i as type,
|
|
26
|
+
t as version
|
|
27
|
+
};
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { CommandParser } from './CommandParser.js';
|
|
2
2
|
import { CommandOption } from './contracts/index.js';
|
|
3
3
|
import { CommandIO } from './CommandIO.js';
|
|
4
|
-
export type SelectOption = {
|
|
5
|
-
title: string;
|
|
6
|
-
value?: any;
|
|
7
|
-
disabled?: boolean | undefined;
|
|
8
|
-
selected?: boolean | undefined;
|
|
9
|
-
description?: string | undefined;
|
|
10
|
-
};
|
|
11
4
|
export type CommandExample = {
|
|
12
5
|
description: string;
|
|
13
6
|
command: string;
|
|
@@ -23,6 +16,7 @@ export declare abstract class Command<C = any> {
|
|
|
23
16
|
protected parser: CommandParser;
|
|
24
17
|
protected io: CommandIO;
|
|
25
18
|
protected abstract handle(): Promise<void | number>;
|
|
19
|
+
protected preHandle?(): Promise<void | number>;
|
|
26
20
|
protected get CommandParserClass(): typeof CommandParser;
|
|
27
21
|
protected get CommandIOClass(): typeof CommandIO;
|
|
28
22
|
protected defaultOptions(): CommandOption<Command<C>>[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bob-core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "BOB Core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/types/src/index.d.ts",
|
|
12
|
-
"import": "./dist/bob-core.js",
|
|
13
|
-
"require": "./dist/bob-core.cjs"
|
|
12
|
+
"import": "./dist/esm/bob-core.js",
|
|
13
|
+
"require": "./dist/cjs/bob-core.cjs"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
package/dist/package-CYbLjAxY.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const t = "bob-core", s = "1.3.0", e = "BOB Core", i = "module", r = ["/dist"], n = { ".": { types: "./dist/types/src/index.d.ts", import: "./dist/bob-core.js", require: "./dist/bob-core.cjs" } }, o = { start: "node -r @swc-node/register debug/main.ts", build: "rimraf ./dist && vite build", prepare: "npm run build", test: "vitest run" }, c = "Léo Hubert", p = "ISC", d = { "@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", rimraf: "^6.0.1", 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" }, a = {
|
|
2
|
-
name: t,
|
|
3
|
-
version: s,
|
|
4
|
-
description: e,
|
|
5
|
-
type: i,
|
|
6
|
-
files: r,
|
|
7
|
-
exports: n,
|
|
8
|
-
scripts: o,
|
|
9
|
-
author: c,
|
|
10
|
-
license: p,
|
|
11
|
-
devDependencies: d,
|
|
12
|
-
dependencies: m
|
|
13
|
-
};
|
|
14
|
-
export {
|
|
15
|
-
c as author,
|
|
16
|
-
a as default,
|
|
17
|
-
m as dependencies,
|
|
18
|
-
e as description,
|
|
19
|
-
d as devDependencies,
|
|
20
|
-
n as exports,
|
|
21
|
-
r as files,
|
|
22
|
-
p as license,
|
|
23
|
-
t as name,
|
|
24
|
-
o as scripts,
|
|
25
|
-
i as type,
|
|
26
|
-
s as version
|
|
27
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",t="1.3.0",s="BOB Core",i="module",r=["/dist"],n={".":{types:"./dist/types/src/index.d.ts",import:"./dist/bob-core.js",require:"./dist/bob-core.cjs"}},o={start:"node -r @swc-node/register debug/main.ts",build:"rimraf ./dist && vite build",prepare:"npm run build",test:"vitest run"},c="Léo Hubert",p="ISC",d={"@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",rimraf:"^6.0.1",typescript:"^5.7.3",vite:"^7.1.6","vite-plugin-dts":"^4.5.4",vitest:"^3.2.4"},a={chalk:"^4.1.2",minimist:"^1.2.8",prompts:"^2.4.2","string-similarity":"^4.0.4"},m={name:e,version:t,description:s,type:i,files:r,exports:n,scripts:o,author:c,license:p,devDependencies:d,dependencies:a};exports.author=c;exports.default=m;exports.dependencies=a;exports.description=s;exports.devDependencies=d;exports.exports=n;exports.files=r;exports.license=p;exports.name=e;exports.scripts=o;exports.type=i;exports.version=t;
|