cli-kiss 0.0.4 → 0.0.5
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.d.ts +21 -18
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/Command.ts +19 -19
- package/src/lib/Execution.ts +2 -2
- package/src/lib/Option.ts +2 -0
- package/src/lib/Reader.ts +4 -4
- package/src/lib/Run.ts +62 -46
- package/src/lib/Typo.ts +5 -2
- package/tests/{unit.command.runArgv.ts → unit.command.execute.ts} +17 -8
- package/tests/unit.command.usage.ts +5 -4
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ type ReaderPositionals = {
|
|
|
3
3
|
};
|
|
4
4
|
declare class ReaderTokenizer {
|
|
5
5
|
#private;
|
|
6
|
-
constructor(
|
|
6
|
+
constructor(args: Array<string>);
|
|
7
7
|
registerFlag(definition: {
|
|
8
8
|
key: string;
|
|
9
9
|
shorts: Array<string>;
|
|
@@ -106,7 +106,7 @@ declare function optionSingleValue<Value>(definition: {
|
|
|
106
106
|
|
|
107
107
|
type Execution<Context, Result> = {
|
|
108
108
|
computeUsage(): ExecutionUsage;
|
|
109
|
-
|
|
109
|
+
createResolver(readerTokenizer: ReaderTokenizer): ExecutionResolver<Context, Result>;
|
|
110
110
|
};
|
|
111
111
|
type ExecutionResolver<Context, Result> = () => ExecutionCallback<Context, Result>;
|
|
112
112
|
type ExecutionCallback<Context, Result> = (context: Context) => Promise<Result>;
|
|
@@ -130,9 +130,13 @@ declare function execution<Context, Result, Options extends {
|
|
|
130
130
|
|
|
131
131
|
type Command<Context, Result> = {
|
|
132
132
|
getDescription(): string | undefined;
|
|
133
|
-
|
|
133
|
+
buildInterpreter(readerTokenizer: ReaderTokenizer): CommandInterpreter<Context, Result>;
|
|
134
134
|
};
|
|
135
|
-
type
|
|
135
|
+
type CommandMetadata = {
|
|
136
|
+
description: string;
|
|
137
|
+
details?: Array<string>;
|
|
138
|
+
};
|
|
139
|
+
type CommandInterpreter<Context, Result> = {
|
|
136
140
|
computeUsage(): CommandUsage;
|
|
137
141
|
execute(context: Context): Promise<Result>;
|
|
138
142
|
};
|
|
@@ -152,14 +156,8 @@ type CommandUsageBreadcrumb = {
|
|
|
152
156
|
} | {
|
|
153
157
|
command: string;
|
|
154
158
|
};
|
|
155
|
-
declare function command<Context, Result>(metadata:
|
|
156
|
-
|
|
157
|
-
details?: Array<string>;
|
|
158
|
-
}, execution: Execution<Context, Result>): Command<Context, Result>;
|
|
159
|
-
declare function commandWithSubcommands<Context, Payload, Result>(metadata: {
|
|
160
|
-
description: string;
|
|
161
|
-
details?: Array<string>;
|
|
162
|
-
}, execution: Execution<Context, Payload>, subcommands: {
|
|
159
|
+
declare function command<Context, Result>(metadata: CommandMetadata, execution: Execution<Context, Result>): Command<Context, Result>;
|
|
160
|
+
declare function commandWithSubcommands<Context, Payload, Result>(metadata: CommandMetadata, execution: Execution<Context, Payload>, subcommands: {
|
|
163
161
|
[subcommand: Lowercase<string>]: Command<Payload, Result>;
|
|
164
162
|
}): Command<Context, Result>;
|
|
165
163
|
|
|
@@ -170,7 +168,7 @@ type TypoText = {
|
|
|
170
168
|
bold?: boolean;
|
|
171
169
|
};
|
|
172
170
|
declare function typoPrintableString(typoSupport: TypoSupport, typoText: TypoText): string;
|
|
173
|
-
declare function
|
|
171
|
+
declare function typoInferProcessSupport(): TypoSupport;
|
|
174
172
|
declare const colorCodes: {
|
|
175
173
|
darkBlack: string;
|
|
176
174
|
darkRed: string;
|
|
@@ -195,10 +193,15 @@ type GridRow = Array<GridCell>;
|
|
|
195
193
|
type GridCell = Array<TypoText>;
|
|
196
194
|
declare function gridToPrintableLines(grid: Grid, typoSupport: TypoSupport, delimiter?: string): Array<string>;
|
|
197
195
|
|
|
198
|
-
declare function
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
declare function runAndExit<Context>(cliName: Lowercase<string>, cliArgs: Array<string>, context: Context, command: Command<Context, void>, application?: {
|
|
197
|
+
usageOnError?: boolean;
|
|
198
|
+
usageOnHelp?: boolean;
|
|
199
|
+
buildVersion?: string;
|
|
200
|
+
useColors?: boolean;
|
|
201
|
+
onMessage?: (message: string) => void;
|
|
202
|
+
onError?: (error: any) => void;
|
|
203
|
+
onExit?: (code: number) => never;
|
|
204
|
+
}): Promise<never>;
|
|
202
205
|
|
|
203
206
|
declare function usageToPrintableLines(params: {
|
|
204
207
|
cliName: Lowercase<string>;
|
|
@@ -206,4 +209,4 @@ declare function usageToPrintableLines(params: {
|
|
|
206
209
|
typoSupport: TypoSupport;
|
|
207
210
|
}): string[];
|
|
208
211
|
|
|
209
|
-
export { type Argument, type ArgumentUsage, type Command, type
|
|
212
|
+
export { type Argument, type ArgumentUsage, type Command, type CommandInterpreter, type CommandMetadata, type CommandUsage, type CommandUsageBreadcrumb, type Execution, type ExecutionCallback, type ExecutionResolver, type ExecutionUsage, type Grid, type GridCell, type GridRow, type Option, type OptionConsumer, type OptionUsage, type ReaderPositionals, ReaderTokenizer, type Type, type TypoSupport, type TypoText, argumentOptional, argumentRequired, argumentVariadics, command, commandWithSubcommands, execution, gridToPrintableLines, optionFlag, optionRepeatable, optionSingleValue, runAndExit, typeBigInt, typeBoolean, typeCommaList, typeCommaTuple, typeDate, typeNumber, typeString, typoInferProcessSupport, typoPrintableString, usageToPrintableLines };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";var F=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.prototype.hasOwnProperty;var Y=r=>{throw TypeError(r)};var oe=(r,e)=>{for(var t in e)F(r,t,{get:e[t],enumerable:!0})},se=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of te(e))!ne.call(r,o)&&o!==t&&F(r,o,{get:()=>e[o],enumerable:!(n=re(e,o))||n.enumerable});return r};var ae=r=>se(F({},"__esModule",{value:!0}),r);var N=(r,e,t)=>e.has(r)||Y("Cannot "+t);var i=(r,e,t)=>(N(r,e,"read from private field"),t?t.call(r):e.get(r)),m=(r,e,t)=>e.has(r)?Y("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),g=(r,e,t,n)=>(N(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t),c=(r,e,t)=>(N(r,e,"access private method"),t);var J=(r,e,t,n)=>({set _(o){g(r,e,o,t)},get _(){return i(r,e,n)}});var Oe={};oe(Oe,{ReaderTokenizer:()=>B,argumentOptional:()=>ue,argumentRequired:()=>ie,argumentVariadics:()=>le,command:()=>pe,commandWithSubcommands:()=>ce,execution:()=>ge,gridToPrintableLines:()=>V,optionFlag:()=>fe,optionRepeatable:()=>ye,optionSingleValue:()=>be,runCommand:()=>we,typeBigInt:()=>ve,typeBoolean:()=>Ce,typeCommaList:()=>Ee,typeCommaTuple:()=>$e,typeDate:()=>Re,typeNumber:()=>Ae,typeString:()=>Ue,typoInferSupport:()=>M,typoPrintableString:()=>d,usageToPrintableLines:()=>L});module.exports=ae(Oe);function ie(r){return{generateUsage(){return{description:r.description,label:`<${r.label??r.type.label}>`}},consumeValue(e){let t=e.consumePositional();if(t===void 0)throw new Error(`Missing required arg: <${r.label??r.type.label}>`);return r.type.decoder(t)}}}function ue(r){return{generateUsage(){return{description:r.description,label:`[${r.label??r.type.label}]`}},consumeValue(e){let t=e.consumePositional();return t===void 0?r.default():r.type.decoder(t)}}}function le(r){return{generateUsage(){return{description:r.description,label:`[${r.label??r.type.label}...]`+(r.endDelimiter?` (end with ${r.endDelimiter})`:"")}},consumeValue(e){let t=[];for(;;){let n=e.consumePositional();if(n===void 0||n===r.endDelimiter)break;t.push(r.type.decoder(n))}return t}}}function pe(r,e){return{getDescription(){return r.description},prepareRunner(t){function n(){let o=e.computeUsage();return{breadcrumbs:o.arguments.map(s=>z(s.label)),description:r.description,details:r.details,options:o.options,arguments:o.arguments,subcommands:[]}}try{let o=e.prepareResolver(t),s=t.consumePositional();if(s!==void 0)throw Error(`Unprocessed positional: ${s}`);let a=o();return{computeUsage:n,async execute(l){return await a(l)}}}catch(o){return{computeUsage:n,async execute(s){throw o}}}}}}function ce(r,e,t){return{getDescription(){return r.description},prepareRunner(n){try{let o=e.prepareResolver(n),s=n.consumePositional();if(s===void 0)throw new Error("Expected a subcommand");let a=t[s];if(a===void 0)throw new Error(`Unknown subcommand: ${s}`);let l=a.prepareRunner(n),p=o();return{computeUsage(){let b=e.computeUsage(),h=l.computeUsage();return{breadcrumbs:b.arguments.map(D=>z(D.label)).concat([H(s)]).concat(h.breadcrumbs),description:h.description,details:h.details,options:b.options.concat(h.options),arguments:b.arguments.concat(h.arguments),subcommands:h.subcommands}},async execute(b){let h=await p(b);return await l.execute(h)}}}catch(o){return{computeUsage(){let s=e.computeUsage();return{breadcrumbs:s.arguments.map(a=>z(a.label)).concat([H("<SUBCOMMAND>")]),description:r.description,details:r.details,options:s.options,arguments:s.arguments,subcommands:Object.entries(t).map(([a,l])=>({name:a,description:l.getDescription()}))}},async execute(s){throw o}}}}}}function z(r){return{argument:r}}function H(r){return{command:r}}function ge(r,e){return{computeUsage(){let t=new Array;for(let o in r.options){let s=r.options[o];t.push(s.generateUsage())}let n=new Array;for(let o of r.arguments)n.push(o.generateUsage());return{options:t,arguments:n}},prepareResolver(t){let n={};for(let s in r.options){let a=r.options[s];n[s]=a.prepareConsumer(t)}let o=[];for(let s of r.arguments)o.push(s.consumeValue(t));return()=>{let s={};for(let a in n)s[a]=n[a]();return async a=>await e(a,{options:s,arguments:o})}}}}function d(r,e){if(r==="none")return e.value;if(r==="tty"){let t=e.color?he[e.color]:"",n=e.bold?de:"";return`${t}${n}${e.value}${me}`}if(r==="html"){let t=e.color?`<span style="color: ${e.color}">`:"",n=e.color?"</span>":"",o=e.bold?"<b>":"",s=e.bold?"</b>":"";return`${t}${o}${e.value}${s}${n}`}if(r==="mock")return e.color&&e.bold?`{${e.value}}@${e.color}+`:e.color?`{${e.value}}@${e.color}`:e.bold?`{${e.value}}+`:`{${e.value}}`;throw new Error(`Unknown typo support: ${r}`)}function M(){if(process.env){if(process.env.FORCE_COLOR==="0")return"none";if(process.env.FORCE_COLOR)return"tty";if("NO_COLOR"in process.env)return"none"}return!process||!process.stdout||!process.stdout.isTTY?"none":"tty"}var me="\x1B[0m",de="\x1B[1m",he={darkBlack:"\x1B[30m",darkRed:"\x1B[31m",darkGreen:"\x1B[32m",darkYellow:"\x1B[33m",darkBlue:"\x1B[34m",darkMagenta:"\x1B[35m",darkCyan:"\x1B[36m",darkWhite:"\x1B[37m",brightBlack:"\x1B[90m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m"};function V(r,e,t=""){let n=new Array,o=new Array;for(let s of r)for(let a=0;a<s.length;a++){let l=s[a],p=Q(l);(o[a]===void 0||p>o[a])&&(o[a]=p)}for(let s of r){let a=new Array;for(let l=0;l<s.length;l++){let p=s[l],b=p.map(h=>d(e,h));if(l<s.length-1){let h=Q(p),D=" ".repeat(o[l]-h);a.push(b.join("")+D)}else a.push(b.join(""))}n.push(a.join(t))}return n}function Q(r){let e=0;for(let t of r)e+=t.value.length;return e}function fe(r){return{generateUsage(){return{description:r.description,long:r.long,short:r.short,label:void 0}},prepareConsumer(e){let t=r.long,n=[r.long];r.aliases?.longs&&n.push(...r.aliases?.longs);let o=r.short?[r.short]:[];return r.aliases?.shorts&&o.push(...r.aliases?.shorts),e.registerFlag({key:t,longs:n,shorts:o}),()=>{let s=e.consumeFlag(t);return s===void 0?r.default?r.default():!1:s}}}}function ye(r){return{generateUsage(){return{description:r.description,long:r.long,short:r.short,label:`<${r.label??r.type.label}>`}},prepareConsumer(e){let t=r.long,n=r.long?[r.long]:[];r.aliases?.longs&&n.push(...r.aliases?.longs);let o=r.short?[r.short]:[];return r.aliases?.shorts&&o.push(...r.aliases?.shorts),e.registerOption({key:t,longs:n,shorts:o}),()=>e.consumeOption(t).map(r.type.decoder)}}}function be(r){return{generateUsage(){return{description:r.description,long:r.long,short:r.short,label:`<${r.label??r.type.label}>`}},prepareConsumer(e){let t=r.long,n=[r.long];r.aliases?.longs&&n.push(...r.aliases?.longs);let o=r.short?[r.short]:[];return r.aliases?.shorts&&o.push(...r.aliases?.shorts),e.registerOption({key:t,longs:n,shorts:o}),()=>{let s=e.consumeOption(r.long);if(s.length>1)throw new Error(`Multiple values provided for option: ${r.long}`);let a=s[0];return a===void 0?r.default():r.type.decoder(a)}}}}var I,E,x,w,C,R,f,U,A,v,y,u,K,W,Z,j,ee,k,$,q,P,B=class{constructor(e){m(this,u);m(this,I);m(this,E);m(this,x);m(this,w);m(this,C);m(this,R);m(this,f);m(this,U);m(this,A);m(this,v);m(this,y);g(this,I,e),g(this,E,0),g(this,x,!1),g(this,w,new Map),g(this,C,new Map),g(this,R,new Map),g(this,f,new Map),g(this,U,new Map),g(this,A,new Map),g(this,v,new Map),g(this,y,new Map)}registerFlag(e){c(this,u,q).call(this,e.key),i(this,R).set(e.key,{});for(let t of e.shorts)c(this,u,P).call(this,t),i(this,w).set(t,e.key);for(let t of e.longs)c(this,u,P).call(this,t),i(this,C).set(t,e.key)}registerOption(e){c(this,u,q).call(this,e.key),i(this,v).set(e.key,{});for(let t of e.shorts)c(this,u,P).call(this,t),i(this,U).set(t,e.key);for(let t of e.longs)c(this,u,P).call(this,t),i(this,A).set(t,e.key)}consumeFlag(e){if(i(this,R).get(e)===void 0)throw new Error(`Option flag not registered: ${e}`);let n=i(this,f).get(e);if(n===void 0){i(this,f).set(e,null);return}if(n===null)throw new Error(`Option flag already consumed: ${e}`);return i(this,f).set(e,null),n}consumeOption(e){if(i(this,v).get(e)===void 0)throw new Error(`Option values not registered: ${e}`);let n=i(this,y).get(e);if(n===void 0)return i(this,y).set(e,null),new Array;if(n===null)throw new Error(`Option values already consumed: ${e}`);return i(this,y).set(e,null),n}consumePositional(){for(;;){let e=c(this,u,K).call(this);if(e===null)return;let t=c(this,u,Z).call(this,e);if(t!==null)return t}}};I=new WeakMap,E=new WeakMap,x=new WeakMap,w=new WeakMap,C=new WeakMap,R=new WeakMap,f=new WeakMap,U=new WeakMap,A=new WeakMap,v=new WeakMap,y=new WeakMap,u=new WeakSet,K=function(){let e=i(this,I)[i(this,E)];return e===void 0?null:(J(this,E)._++,!i(this,x)&&e==="--"?(g(this,x,!0),c(this,u,K).call(this)):e)},W=function(e){let t=c(this,u,K).call(this);if(t===null)throw new Error(`Option ${e} requires a value`);if(i(this,x))throw new Error(`Option ${e} requires a value before --`);if(t.startsWith("-"))throw new Error(`Option ${e} requires a value, got: ${t}`);return t},Z=function(e){if(i(this,x))return e;if(e.startsWith("--")){let t=e.indexOf("=");return t===-1?c(this,u,j).call(this,e.slice(2),null):c(this,u,j).call(this,e.slice(2,t),e.slice(t+1)),null}if(e.startsWith("-")){let t=1,n=2;for(;n<=e.length;){let o=e.slice(t,n),s=e.slice(n),a=c(this,u,ee).call(this,o,s);if(a===!0)return null;a===!1&&(t=n),n++}throw new Error(`Unknown short flags or options: ${e.slice(t)}`)}return e},j=function(e,t){let n=i(this,C).get(e);if(n!==void 0){if(t!==null){let s=X(t);if(s!==void 0)return c(this,u,k).call(this,n,s);throw new Error(`Invalid parameter for long flag: ${n}, value: ${t}`)}return c(this,u,k).call(this,n,!0)}let o=i(this,A).get(e);if(o!==void 0)return t!==null?c(this,u,$).call(this,o,t):c(this,u,$).call(this,o,c(this,u,W).call(this,e));throw new Error(`Unknown long flag or option: ${e}`)},ee=function(e,t){let n=i(this,w).get(e);if(n!==void 0){if(t.startsWith("=")){let s=X(t.slice(1));if(s!==void 0)return c(this,u,k).call(this,n,s),!0;throw new Error(`Invalid parameter for short flag: ${e}, value: ${t}`)}return c(this,u,k).call(this,n,!0),t===""}let o=i(this,U).get(e);return o!==void 0?t===""?(c(this,u,$).call(this,o,c(this,u,W).call(this,e)),!0):(t.startsWith("=")?c(this,u,$).call(this,o,t.slice(1)):c(this,u,$).call(this,o,t),!0):null},k=function(e,t){if(i(this,f).has(e))throw new Error(`Flag already set: ${e}`);i(this,f).set(e,t)},$=function(e,t){let n=i(this,y).get(e)??new Array;n.push(t),i(this,y).set(e,n)},q=function(e){if(i(this,R).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,v).has(e))throw new Error(`Option already registered: ${e}`)},P=function(e){if(i(this,w).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,C).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,U).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,A).has(e))throw new Error(`Option already registered: ${e}`)};function X(r){let e=r.toLowerCase();if(e==="true"||e==="t"||e==="y"||e==="yes")return!0;if(e==="false"||e==="f"||e==="n"||e==="no")return!1}function L(r){let{cliName:e,commandUsage:t,typoSupport:n}=r,o=new Array;if(o.push(d(n,S(t.description))),t.details)for(let a of t.details)o.push(d(n,xe(a)));o.push(""),o.push(d(n,G("Usage:")));let s=[" ",d(n,O(e))].concat(t.breadcrumbs.map(a=>{if("argument"in a)return d(n,_(a.argument));if("command"in a)return d(n,O(a.command));throw new Error(`Unknown breadcrumb: ${JSON.stringify(a)}`)}));if(o.push(s.join(" ")),t.arguments.length>0){o.push(""),o.push(d(n,G("Arguments:")));let a=new Array;for(let l of t.arguments){let p=new Array;p.push([T()]),p.push([_(l.label)]),l.description&&(p.push([T()]),p.push([S(l.description)])),a.push(p)}o.push(...V(a,n))}if(t.subcommands.length>0){o.push(""),o.push(d(n,G("Subcommands:")));let a=new Array;for(let l of t.subcommands){let p=new Array;p.push([T()]),p.push([O(l.name)]),l.description&&(p.push([T()]),p.push([S(l.description)])),a.push(p)}o.push(...V(a,n))}if(t.options.length>0){o.push(""),o.push(d(n,G("Options:")));let a=new Array;for(let l of t.options){let p=new Array;p.push([T()]),l.short?p.push([O(`-${l.short}`),{value:", "}]):p.push([]),l.label?p.push([O(`--${l.long} `),_(l.label)]):p.push([O(`--${l.long}`)]),l.description&&(p.push([T()]),p.push([S(l.description)])),a.push(p)}o.push(...V(a,n))}return o.push(""),o}function G(r){return{value:r,color:"brightGreen",bold:!0}}function S(r){return{value:r,bold:!0}}function xe(r){return{value:r,color:"brightBlack"}}function O(r){return{value:r,color:"brightCyan",bold:!0}}function _(r){return{value:r,color:"brightBlue"}}function T(){return{value:" "}}async function we(r,e,t,n,o){let s=new B(e);o?.version&&s.registerFlag({key:"version",shorts:[],longs:["version"]}),s.registerFlag({key:"help",shorts:[],longs:["help"]});try{let a=n.prepareRunner(s);o?.version&&s.consumeFlag("version")&&(console.log(r,o.version),process.exit(0)),s.consumeFlag("help")&&(console.log(L({cliName:r,commandUsage:a.computeUsage(),typoSupport:M()}).join(`
|
|
2
|
-
`)),
|
|
3
|
-
`)),console.error(l),process.exit(1)}}catch(a){console.error(a),process.exit(1)}}var Ce={label:"BOOLEAN",decoder(r){if(r==="true")return!0;if(r==="false")return!1;throw new Error(`Invalid boolean value: ${r}`)}},Re={label:"DATE",decoder(r){let e=Date.parse(r);if(isNaN(e))throw new Error(`Invalid date value: ${r}`);return new Date(e)}},Ue={label:"STRING",decoder(r){return r}},Ae={label:"NUMBER",decoder(r){return Number(r)}},ve={label:"BIGINT",decoder(r){return BigInt(r)}};function $e(r){return{label:r.map(e=>e.label).join(","),decoder(e){let t=e.split(",",r.length);if(t.length!==r.length)throw new Error(`Invalid tuple value: ${e}, expected ${r.length} parts`);return t.map((n,o)=>r[o].decoder(n))}}}function Ee(r){return{label:`${r.label}[,${r.label}...]`,decoder(e){return e.split(",").map(r.decoder)}}}0&&(module.exports={ReaderTokenizer,argumentOptional,argumentRequired,argumentVariadics,command,commandWithSubcommands,execution,gridToPrintableLines,optionFlag,optionRepeatable,optionSingleValue,runCommand,typeBigInt,typeBoolean,typeCommaList,typeCommaTuple,typeDate,typeNumber,typeString,typoInferSupport,typoPrintableString,usageToPrintableLines});
|
|
1
|
+
"use strict";var L=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var H=r=>{throw TypeError(r)};var se=(r,e)=>{for(var t in e)L(r,t,{get:e[t],enumerable:!0})},ae=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ne(e))!oe.call(r,n)&&n!==t&&L(r,n,{get:()=>e[n],enumerable:!(o=te(e,n))||o.enumerable});return r};var ie=r=>ae(L({},"__esModule",{value:!0}),r);var D=(r,e,t)=>e.has(r)||H("Cannot "+t);var i=(r,e,t)=>(D(r,e,"read from private field"),t?t.call(r):e.get(r)),d=(r,e,t)=>e.has(r)?H("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),c=(r,e,t,o)=>(D(r,e,"write to private field"),o?o.call(r,t):e.set(r,t),t),g=(r,e,t)=>(D(r,e,"access private method"),t);var Y=(r,e,t,o)=>({set _(n){c(r,e,n,t)},get _(){return i(r,e,o)}});var Ve={};se(Ve,{ReaderTokenizer:()=>P,argumentOptional:()=>le,argumentRequired:()=>ue,argumentVariadics:()=>pe,command:()=>ge,commandWithSubcommands:()=>ce,execution:()=>de,gridToPrintableLines:()=>V,optionFlag:()=>ye,optionRepeatable:()=>be,optionSingleValue:()=>xe,runAndExit:()=>Ce,typeBigInt:()=>$e,typeBoolean:()=>Ae,typeCommaList:()=>Te,typeCommaTuple:()=>Oe,typeDate:()=>Re,typeNumber:()=>ve,typeString:()=>Ee,typoInferProcessSupport:()=>N,typoPrintableString:()=>m,usageToPrintableLines:()=>_});module.exports=ie(Ve);function ue(r){return{generateUsage(){return{description:r.description,label:`<${r.label??r.type.label}>`}},consumeValue(e){let t=e.consumePositional();if(t===void 0)throw new Error(`Missing required arg: <${r.label??r.type.label}>`);return r.type.decoder(t)}}}function le(r){return{generateUsage(){return{description:r.description,label:`[${r.label??r.type.label}]`}},consumeValue(e){let t=e.consumePositional();return t===void 0?r.default():r.type.decoder(t)}}}function pe(r){return{generateUsage(){return{description:r.description,label:`[${r.label??r.type.label}...]`+(r.endDelimiter?` (end with ${r.endDelimiter})`:"")}},consumeValue(e){let t=[];for(;;){let o=e.consumePositional();if(o===void 0||o===r.endDelimiter)break;t.push(r.type.decoder(o))}return t}}}function ge(r,e){return{getDescription(){return r.description},buildInterpreter(t){function o(){let n=e.computeUsage();return{breadcrumbs:n.arguments.map(s=>F(s.label)),description:r.description,details:r.details,options:n.options,arguments:n.arguments,subcommands:[]}}try{let n=e.createResolver(t),s=t.consumePositional();if(s!==void 0)throw Error(`Unprocessed positional: ${s}`);let a=n();return{computeUsage:o,async execute(l){return await a(l)}}}catch(n){return{computeUsage:o,async execute(s){throw n}}}}}}function ce(r,e,t){return{getDescription(){return r.description},buildInterpreter(o){try{let n=e.createResolver(o),s=o.consumePositional();if(s===void 0)throw new Error("Expected a subcommand");let a=t[s];if(a===void 0)throw new Error(`Unknown subcommand: ${s}`);let l=a.buildInterpreter(o),p=n();return{computeUsage(){let b=e.computeUsage(),h=l.computeUsage();return{breadcrumbs:b.arguments.map(G=>F(G.label)).concat([J(s)]).concat(h.breadcrumbs),description:h.description,details:h.details,options:b.options.concat(h.options),arguments:b.arguments.concat(h.arguments),subcommands:h.subcommands}},async execute(b){let h=await p(b);return await l.execute(h)}}}catch(n){return{computeUsage(){let s=e.computeUsage();return{breadcrumbs:s.arguments.map(a=>F(a.label)).concat([J("<SUBCOMMAND>")]),description:r.description,details:r.details,options:s.options,arguments:s.arguments,subcommands:Object.entries(t).map(([a,l])=>({name:a,description:l.getDescription()}))}},async execute(s){throw n}}}}}}function F(r){return{argument:r}}function J(r){return{command:r}}function de(r,e){return{computeUsage(){let t=new Array;for(let n in r.options){let s=r.options[n];t.push(s.generateUsage())}let o=new Array;for(let n of r.arguments)o.push(n.generateUsage());return{options:t,arguments:o}},createResolver(t){let o={};for(let s in r.options){let a=r.options[s];o[s]=a.prepareConsumer(t)}let n=[];for(let s of r.arguments)n.push(s.consumeValue(t));return()=>{let s={};for(let a in o)s[a]=o[a]();return async a=>await e(a,{options:s,arguments:n})}}}}function m(r,e){if(r==="none")return e.value;if(r==="tty"){let t=e.color?fe[e.color]:"",o=e.bold?he:"";return`${t}${o}${e.value}${me}`}if(r==="html"){let t=e.color?`<span style="color: ${e.color}">`:"",o=e.color?"</span>":"",n=e.bold?"<b>":"",s=e.bold?"</b>":"";return`${t}${n}${e.value}${s}${o}`}if(r==="mock")return e.color&&e.bold?`{${e.value}}@${e.color}+`:e.color?`{${e.value}}@${e.color}`:e.bold?`{${e.value}}+`:`{${e.value}}`;throw new Error(`Unknown typo support: ${r}`)}function N(){if(!process)return"none";if(process.env){if(process.env.FORCE_COLOR==="0")return"none";if(process.env.FORCE_COLOR)return"tty";if("NO_COLOR"in process.env)return"none"}return!process.stdout||!process.stdout.isTTY?"none":"tty"}var me="\x1B[0m",he="\x1B[1m",fe={darkBlack:"\x1B[30m",darkRed:"\x1B[31m",darkGreen:"\x1B[32m",darkYellow:"\x1B[33m",darkBlue:"\x1B[34m",darkMagenta:"\x1B[35m",darkCyan:"\x1B[36m",darkWhite:"\x1B[37m",brightBlack:"\x1B[90m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m"};function V(r,e,t=""){let o=new Array,n=new Array;for(let s of r)for(let a=0;a<s.length;a++){let l=s[a],p=Q(l);(n[a]===void 0||p>n[a])&&(n[a]=p)}for(let s of r){let a=new Array;for(let l=0;l<s.length;l++){let p=s[l],b=p.map(h=>m(e,h));if(l<s.length-1){let h=Q(p),G=" ".repeat(n[l]-h);a.push(b.join("")+G)}else a.push(b.join(""))}o.push(a.join(t))}return o}function Q(r){let e=0;for(let t of r)e+=t.value.length;return e}function ye(r){return{generateUsage(){return{description:r.description,long:r.long,short:r.short,label:void 0}},prepareConsumer(e){let t=r.long,o=[r.long];r.aliases?.longs&&o.push(...r.aliases?.longs);let n=r.short?[r.short]:[];return r.aliases?.shorts&&n.push(...r.aliases?.shorts),e.registerFlag({key:t,longs:o,shorts:n}),()=>{let s=e.consumeFlag(t);return s===void 0?r.default?r.default():!1:s}}}}function be(r){return{generateUsage(){return{description:r.description,long:r.long,short:r.short,label:`<${r.label??r.type.label}>`}},prepareConsumer(e){let t=r.long,o=r.long?[r.long]:[];r.aliases?.longs&&o.push(...r.aliases?.longs);let n=r.short?[r.short]:[];return r.aliases?.shorts&&n.push(...r.aliases?.shorts),e.registerOption({key:t,longs:o,shorts:n}),()=>e.consumeOption(t).map(r.type.decoder)}}}function xe(r){return{generateUsage(){return{description:r.description,long:r.long,short:r.short,label:`<${r.label??r.type.label}>`}},prepareConsumer(e){let t=r.long,o=[r.long];r.aliases?.longs&&o.push(...r.aliases?.longs);let n=r.short?[r.short]:[];return r.aliases?.shorts&&n.push(...r.aliases?.shorts),e.registerOption({key:t,longs:o,shorts:n}),()=>{let s=e.consumeOption(r.long);if(s.length>1)throw new Error(`Multiple values provided for option: ${r.long}`);let a=s[0];return a===void 0?r.default():r.type.decoder(a)}}}}var M,$,x,w,C,U,f,A,R,E,y,u,B,z,Z,W,ee,I,v,j,k,P=class{constructor(e){d(this,u);d(this,M);d(this,$);d(this,x);d(this,w);d(this,C);d(this,U);d(this,f);d(this,A);d(this,R);d(this,E);d(this,y);c(this,M,e),c(this,$,0),c(this,x,!1),c(this,w,new Map),c(this,C,new Map),c(this,U,new Map),c(this,f,new Map),c(this,A,new Map),c(this,R,new Map),c(this,E,new Map),c(this,y,new Map)}registerFlag(e){g(this,u,j).call(this,e.key),i(this,U).set(e.key,{});for(let t of e.shorts)g(this,u,k).call(this,t),i(this,w).set(t,e.key);for(let t of e.longs)g(this,u,k).call(this,t),i(this,C).set(t,e.key)}registerOption(e){g(this,u,j).call(this,e.key),i(this,E).set(e.key,{});for(let t of e.shorts)g(this,u,k).call(this,t),i(this,A).set(t,e.key);for(let t of e.longs)g(this,u,k).call(this,t),i(this,R).set(t,e.key)}consumeFlag(e){if(i(this,U).get(e)===void 0)throw new Error(`Option flag not registered: ${e}`);let o=i(this,f).get(e);if(o===void 0){i(this,f).set(e,null);return}if(o===null)throw new Error(`Option flag already consumed: ${e}`);return i(this,f).set(e,null),o}consumeOption(e){if(i(this,E).get(e)===void 0)throw new Error(`Option values not registered: ${e}`);let o=i(this,y).get(e);if(o===void 0)return i(this,y).set(e,null),new Array;if(o===null)throw new Error(`Option values already consumed: ${e}`);return i(this,y).set(e,null),o}consumePositional(){for(;;){let e=g(this,u,B).call(this);if(e===null)return;let t=g(this,u,Z).call(this,e);if(t!==null)return t}}};M=new WeakMap,$=new WeakMap,x=new WeakMap,w=new WeakMap,C=new WeakMap,U=new WeakMap,f=new WeakMap,A=new WeakMap,R=new WeakMap,E=new WeakMap,y=new WeakMap,u=new WeakSet,B=function(){let e=i(this,M)[i(this,$)];return e===void 0?null:(Y(this,$)._++,!i(this,x)&&e==="--"?(c(this,x,!0),g(this,u,B).call(this)):e)},z=function(e){let t=g(this,u,B).call(this);if(t===null)throw new Error(`Option ${e} requires a value`);if(i(this,x))throw new Error(`Option ${e} requires a value before --`);if(t.startsWith("-"))throw new Error(`Option ${e} requires a value, got: ${t}`);return t},Z=function(e){if(i(this,x))return e;if(e.startsWith("--")){let t=e.indexOf("=");return t===-1?g(this,u,W).call(this,e.slice(2),null):g(this,u,W).call(this,e.slice(2,t),e.slice(t+1)),null}if(e.startsWith("-")){let t=1,o=2;for(;o<=e.length;){let n=e.slice(t,o),s=e.slice(o),a=g(this,u,ee).call(this,n,s);if(a===!0)return null;a===!1&&(t=o),o++}throw new Error(`Unknown short flags or options: ${e.slice(t)}`)}return e},W=function(e,t){let o=i(this,C).get(e);if(o!==void 0){if(t!==null){let s=X(t);if(s!==void 0)return g(this,u,I).call(this,o,s);throw new Error(`Invalid parameter for long flag: ${o}, value: ${t}`)}return g(this,u,I).call(this,o,!0)}let n=i(this,R).get(e);if(n!==void 0)return t!==null?g(this,u,v).call(this,n,t):g(this,u,v).call(this,n,g(this,u,z).call(this,e));throw new Error(`Unknown long flag or option: ${e}`)},ee=function(e,t){let o=i(this,w).get(e);if(o!==void 0){if(t.startsWith("=")){let s=X(t.slice(1));if(s!==void 0)return g(this,u,I).call(this,o,s),!0;throw new Error(`Invalid parameter for short flag: ${e}, value: ${t}`)}return g(this,u,I).call(this,o,!0),t===""}let n=i(this,A).get(e);return n!==void 0?t===""?(g(this,u,v).call(this,n,g(this,u,z).call(this,e)),!0):(t.startsWith("=")?g(this,u,v).call(this,n,t.slice(1)):g(this,u,v).call(this,n,t),!0):null},I=function(e,t){if(i(this,f).has(e))throw new Error(`Flag already set: ${e}`);i(this,f).set(e,t)},v=function(e,t){let o=i(this,y).get(e)??new Array;o.push(t),i(this,y).set(e,o)},j=function(e){if(i(this,U).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,E).has(e))throw new Error(`Option already registered: ${e}`)},k=function(e){if(i(this,w).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,C).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,A).has(e))throw new Error(`Option already registered: ${e}`);if(i(this,R).has(e))throw new Error(`Option already registered: ${e}`)};function X(r){let e=r.toLowerCase();if(e==="true"||e==="t"||e==="y"||e==="yes")return!0;if(e==="false"||e==="f"||e==="n"||e==="no")return!1}function _(r){let{cliName:e,commandUsage:t,typoSupport:o}=r,n=new Array;if(n.push(m(o,S(t.description))),t.details)for(let a of t.details)n.push(m(o,we(a)));n.push(""),n.push(m(o,K("Usage:")));let s=[" ",m(o,O(e))].concat(t.breadcrumbs.map(a=>{if("argument"in a)return m(o,q(a.argument));if("command"in a)return m(o,O(a.command));throw new Error(`Unknown breadcrumb: ${JSON.stringify(a)}`)}));if(n.push(s.join(" ")),t.arguments.length>0){n.push(""),n.push(m(o,K("Arguments:")));let a=new Array;for(let l of t.arguments){let p=new Array;p.push([T()]),p.push([q(l.label)]),l.description&&(p.push([T()]),p.push([S(l.description)])),a.push(p)}n.push(...V(a,o))}if(t.subcommands.length>0){n.push(""),n.push(m(o,K("Subcommands:")));let a=new Array;for(let l of t.subcommands){let p=new Array;p.push([T()]),p.push([O(l.name)]),l.description&&(p.push([T()]),p.push([S(l.description)])),a.push(p)}n.push(...V(a,o))}if(t.options.length>0){n.push(""),n.push(m(o,K("Options:")));let a=new Array;for(let l of t.options){let p=new Array;p.push([T()]),l.short?p.push([O(`-${l.short}`),{value:", "}]):p.push([]),l.label?p.push([O(`--${l.long} `),q(l.label)]):p.push([O(`--${l.long}`)]),l.description&&(p.push([T()]),p.push([S(l.description)])),a.push(p)}n.push(...V(a,o))}return n.push(""),n}function K(r){return{value:r,color:"brightGreen",bold:!0}}function S(r){return{value:r,bold:!0}}function we(r){return{value:r,color:"brightBlack"}}function O(r){return{value:r,color:"brightCyan",bold:!0}}function q(r){return{value:r,color:"brightBlue"}}function T(){return{value:" "}}async function Ce(r,e,t,o,n){let s=new P(e);n?.buildVersion&&s.registerFlag({key:"version",shorts:[],longs:["version"]}),(n?.usageOnHelp??!0)&&s.registerFlag({key:"help",shorts:[],longs:["help"]});let a=o.buildInterpreter(s);if(n?.buildVersion&&s.consumeFlag("version"))return(n?.onMessage??console.log)([r,n.buildVersion].join(" ")),(n?.onExit??process.exit)(0);if((n?.usageOnHelp??!0)&&s.consumeFlag("help"))return re(r,a,n),(n?.onExit??process.exit)(0);try{return await a.execute(t),(n?.onExit??process.exit)(0)}catch(l){return(n?.usageOnError??!0)&&re(r,a,n),(n?.onError??console.error)(l),(n?.onExit??process.exit)(1)}}function re(r,e,t){(t?.onMessage??console.log)(_({cliName:r,commandUsage:e.computeUsage(),typoSupport:Ue(t?.useColors)}).join(`
|
|
2
|
+
`))}function Ue(r){return r===void 0?N():r?"tty":"none"}var Ae={label:"BOOLEAN",decoder(r){if(r==="true")return!0;if(r==="false")return!1;throw new Error(`Invalid boolean value: ${r}`)}},Re={label:"DATE",decoder(r){let e=Date.parse(r);if(isNaN(e))throw new Error(`Invalid date value: ${r}`);return new Date(e)}},Ee={label:"STRING",decoder(r){return r}},ve={label:"NUMBER",decoder(r){return Number(r)}},$e={label:"BIGINT",decoder(r){return BigInt(r)}};function Oe(r){return{label:r.map(e=>e.label).join(","),decoder(e){let t=e.split(",",r.length);if(t.length!==r.length)throw new Error(`Invalid tuple value: ${e}, expected ${r.length} parts`);return t.map((o,n)=>r[n].decoder(o))}}}function Te(r){return{label:`${r.label}[,${r.label}...]`,decoder(e){return e.split(",").map(r.decoder)}}}0&&(module.exports={ReaderTokenizer,argumentOptional,argumentRequired,argumentVariadics,command,commandWithSubcommands,execution,gridToPrintableLines,optionFlag,optionRepeatable,optionSingleValue,runAndExit,typeBigInt,typeBoolean,typeCommaList,typeCommaTuple,typeDate,typeNumber,typeString,typoInferProcessSupport,typoPrintableString,usageToPrintableLines});
|
|
4
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/Argument.ts","../src/lib/Command.ts","../src/lib/Execution.ts","../src/lib/Typo.ts","../src/lib/Grid.ts","../src/lib/Option.ts","../src/lib/Reader.ts","../src/lib/Usage.ts","../src/lib/Run.ts","../src/lib/Type.ts"],"sourcesContent":["export * from \"./lib/Argument\";\nexport * from \"./lib/Command\";\nexport * from \"./lib/Execution\";\nexport * from \"./lib/Grid\";\nexport * from \"./lib/Option\";\nexport * from \"./lib/Reader\";\nexport * from \"./lib/Run\";\nexport * from \"./lib/Type\";\nexport * from \"./lib/Typo\";\nexport * from \"./lib/Usage\";\n","import { ReaderPositionals } from \"./Reader\";\nimport { Type } from \"./Type\";\n\nexport type Argument<Value> = {\n generateUsage(): ArgumentUsage;\n consumeValue(readerPositionals: ReaderPositionals): Value;\n};\n\nexport type ArgumentUsage = {\n description: string | undefined;\n label: string;\n};\n\nexport function argumentRequired<Value>(definition: {\n description?: string;\n type: Type<Value>;\n label?: Uppercase<string>;\n}): Argument<Value> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n label: `<${definition.label ?? definition.type.label}>`,\n };\n },\n consumeValue(readerPositionals: ReaderPositionals) {\n const positional = readerPositionals.consumePositional();\n if (positional === undefined) {\n throw new Error(\n `Missing required arg: <${definition.label ?? definition.type.label}>`,\n );\n }\n return definition.type.decoder(positional);\n },\n };\n}\n\nexport function argumentOptional<Value>(definition: {\n description?: string;\n type: Type<Value>;\n label?: Uppercase<string>;\n default: () => Value;\n}): Argument<Value> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n label: `[${definition.label ?? definition.type.label}]`,\n };\n },\n consumeValue(readerPositionals: ReaderPositionals) {\n const positional = readerPositionals.consumePositional();\n if (positional === undefined) {\n return definition.default();\n }\n return definition.type.decoder(positional);\n },\n };\n}\n\nexport function argumentVariadics<Value>(definition: {\n description?: string;\n type: Type<Value>;\n label?: Uppercase<string>;\n endDelimiter?: string;\n}): Argument<Array<Value>> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n label:\n `[${definition.label ?? definition.type.label}...]` +\n (definition.endDelimiter\n ? ` (end with ${definition.endDelimiter})`\n : \"\"),\n };\n },\n consumeValue(readerPositionals: ReaderPositionals) {\n const values: Array<Value> = [];\n while (true) {\n const positional = readerPositionals.consumePositional();\n if (\n positional === undefined ||\n positional === definition.endDelimiter\n ) {\n break;\n }\n values.push(definition.type.decoder(positional));\n }\n return values;\n },\n };\n}\n","import { ArgumentUsage } from \"./Argument\";\nimport { Execution } from \"./Execution\";\nimport { OptionUsage } from \"./Option\";\nimport { ReaderTokenizer } from \"./Reader\";\n\nexport type Command<Context, Result> = {\n getDescription(): string | undefined;\n prepareRunner(\n readerTokenizer: ReaderTokenizer,\n ): CommandRunner<Context, Result>;\n};\n\nexport type CommandRunner<Context, Result> = {\n computeUsage(): CommandUsage;\n execute(context: Context): Promise<Result>;\n};\n\nexport type CommandUsage = {\n breadcrumbs: Array<CommandUsageBreadcrumb>;\n description: string;\n details: Array<string> | undefined;\n options: Array<OptionUsage>;\n arguments: Array<ArgumentUsage>;\n subcommands: Array<{ name: string; description: string | undefined }>;\n};\n\nexport type CommandUsageBreadcrumb = { argument: string } | { command: string };\n\nexport function command<Context, Result>(\n metadata: {\n description: string;\n details?: Array<string>;\n // TODO - examples ?\n },\n execution: Execution<Context, Result>,\n): Command<Context, Result> {\n return {\n getDescription() {\n return metadata.description;\n },\n prepareRunner(readerTokenizer: ReaderTokenizer) {\n function computeUsage(): CommandUsage {\n const executionUsage = execution.computeUsage();\n return {\n breadcrumbs: executionUsage.arguments.map((argument) =>\n breadcrumbArgument(argument.label),\n ),\n description: metadata.description,\n details: metadata.details,\n options: executionUsage.options,\n arguments: executionUsage.arguments,\n subcommands: [],\n };\n }\n try {\n const executionResolver = execution.prepareResolver(readerTokenizer);\n const lastPositional = readerTokenizer.consumePositional();\n if (lastPositional !== undefined) {\n throw Error(`Unprocessed positional: ${lastPositional}`);\n }\n const executionCallback = executionResolver();\n return {\n computeUsage,\n async execute(context: Context) {\n return await executionCallback(context);\n },\n };\n } catch (error) {\n return {\n computeUsage,\n async execute(_context: Context) {\n throw error;\n },\n };\n }\n },\n };\n}\n\nexport function commandWithSubcommands<Context, Payload, Result>(\n metadata: {\n description: string;\n details?: Array<string>;\n },\n execution: Execution<Context, Payload>,\n subcommands: { [subcommand: Lowercase<string>]: Command<Payload, Result> },\n): Command<Context, Result> {\n return {\n getDescription() {\n return metadata.description;\n },\n prepareRunner(readerTokenizer: ReaderTokenizer) {\n try {\n const executionResolver = execution.prepareResolver(readerTokenizer);\n const subcommandName = readerTokenizer.consumePositional();\n if (subcommandName === undefined) {\n throw new Error(\"Expected a subcommand\");\n }\n const subcommandInput =\n subcommands[subcommandName as Lowercase<string>];\n if (subcommandInput === undefined) {\n throw new Error(`Unknown subcommand: ${subcommandName}`);\n }\n const subcommandRunner = subcommandInput.prepareRunner(readerTokenizer);\n const executionCallback = executionResolver();\n return {\n computeUsage() {\n const executionUsage = execution.computeUsage();\n const subcommandUsage = subcommandRunner.computeUsage();\n return {\n breadcrumbs: executionUsage.arguments\n .map((argument) => breadcrumbArgument(argument.label))\n .concat([breadcrumbCommand(subcommandName)])\n .concat(subcommandUsage.breadcrumbs),\n description: subcommandUsage.description,\n details: subcommandUsage.details,\n options: executionUsage.options.concat(subcommandUsage.options),\n arguments: executionUsage.arguments.concat(\n subcommandUsage.arguments,\n ),\n subcommands: subcommandUsage.subcommands,\n };\n },\n async execute(context: Context) {\n const payload = await executionCallback(context);\n return await subcommandRunner.execute(payload);\n },\n };\n } catch (error) {\n return {\n computeUsage() {\n const executionUsage = execution.computeUsage();\n return {\n breadcrumbs: executionUsage.arguments\n .map((argument) => breadcrumbArgument(argument.label))\n .concat([breadcrumbCommand(\"<SUBCOMMAND>\")]),\n description: metadata.description,\n details: metadata.details,\n options: executionUsage.options,\n arguments: executionUsage.arguments,\n subcommands: Object.entries(subcommands).map(\n ([name, subcommand]) => ({\n name,\n description: subcommand.getDescription(),\n }),\n ),\n };\n },\n async execute(_context: Context) {\n throw error;\n },\n };\n }\n },\n };\n}\n\nfunction breadcrumbArgument(value: string): CommandUsageBreadcrumb {\n return { argument: value };\n}\n\nfunction breadcrumbCommand(value: string): CommandUsageBreadcrumb {\n return { command: value };\n}\n","import { Argument, ArgumentUsage } from \"./Argument\";\nimport { Option, OptionUsage } from \"./Option\";\nimport { ReaderTokenizer } from \"./Reader\";\n\nexport type Execution<Context, Result> = {\n computeUsage(): ExecutionUsage;\n prepareResolver(\n readerTokenizer: ReaderTokenizer,\n ): ExecutionResolver<Context, Result>;\n};\n\nexport type ExecutionResolver<Context, Result> = () => ExecutionCallback<\n Context,\n Result\n>;\n\nexport type ExecutionCallback<Context, Result> = (\n context: Context,\n) => Promise<Result>;\n\nexport type ExecutionUsage = {\n options: Array<OptionUsage>;\n arguments: Array<ArgumentUsage>;\n};\n\nexport function execution<\n Context,\n Result,\n Options extends { [option: string]: any },\n const Arguments extends Array<any>,\n>(\n inputs: {\n options: { [K in keyof Options]: Option<Options[K]> };\n arguments: { [K in keyof Arguments]: Argument<Arguments[K]> };\n },\n handler: (\n context: Context,\n inputs: {\n options: Options;\n arguments: Arguments;\n },\n ) => Promise<Result>,\n): Execution<Context, Result> {\n return {\n computeUsage() {\n const optionsUsage = new Array<OptionUsage>();\n for (const optionKey in inputs.options) {\n const optionInput = inputs.options[optionKey]!;\n optionsUsage.push(optionInput.generateUsage());\n }\n const argumentsUsage = new Array<ArgumentUsage>();\n for (const argumentInput of inputs.arguments) {\n argumentsUsage.push(argumentInput.generateUsage());\n }\n return { options: optionsUsage, arguments: argumentsUsage };\n },\n prepareResolver(readerTokenizer: ReaderTokenizer) {\n const optionsConsumers: any = {};\n for (const optionKey in inputs.options) {\n const optionInput = inputs.options[optionKey]!;\n optionsConsumers[optionKey] =\n optionInput.prepareConsumer(readerTokenizer);\n }\n const argumentsValues: any = [];\n for (const argumentInput of inputs.arguments) {\n argumentsValues.push(argumentInput.consumeValue(readerTokenizer));\n }\n return () => {\n const optionsValues: any = {};\n for (const optionKey in optionsConsumers) {\n optionsValues[optionKey] = optionsConsumers[optionKey]!();\n }\n return async (context: Context) => {\n return await handler(context, {\n options: optionsValues,\n arguments: argumentsValues,\n });\n };\n };\n },\n };\n}\n","export type TypoSupport = \"none\" | \"tty\" | \"html\" | \"mock\";\n\nexport type TypoText = {\n value: string;\n color?: keyof typeof colorCodes;\n bold?: boolean;\n};\n\nexport function typoPrintableString(\n typoSupport: TypoSupport,\n typoText: TypoText,\n): string {\n if (typoSupport === \"none\") {\n return typoText.value;\n }\n if (typoSupport === \"tty\") {\n const colorStartCode = typoText.color ? colorCodes[typoText.color] : \"\";\n const colorBoldCode = typoText.bold ? boldCode : \"\";\n return `${colorStartCode}${colorBoldCode}${typoText.value}${resetCode}`;\n }\n if (typoSupport === \"html\") {\n const colorStartTag = typoText.color\n ? `<span style=\"color: ${typoText.color}\">`\n : \"\";\n const colorEndTag = typoText.color ? \"</span>\" : \"\";\n const boldStartTag = typoText.bold ? \"<b>\" : \"\";\n const boldEndTag = typoText.bold ? \"</b>\" : \"\";\n return `${colorStartTag}${boldStartTag}${typoText.value}${boldEndTag}${colorEndTag}`;\n }\n if (typoSupport === \"mock\") {\n if (typoText.color && typoText.bold) {\n return `{${typoText.value}}@${typoText.color}+`;\n }\n if (typoText.color) {\n return `{${typoText.value}}@${typoText.color}`;\n }\n if (typoText.bold) {\n return `{${typoText.value}}+`;\n }\n return `{${typoText.value}}`;\n }\n throw new Error(`Unknown typo support: ${typoSupport}`);\n}\n\nexport function typoInferSupport(): TypoSupport {\n if (process.env) {\n if (process.env[\"FORCE_COLOR\"] === \"0\") {\n return \"none\";\n }\n if (process.env[\"FORCE_COLOR\"]) {\n return \"tty\";\n }\n if (\"NO_COLOR\" in process.env) {\n return \"none\";\n }\n }\n if (!process || !process.stdout || !process.stdout.isTTY) {\n return \"none\";\n }\n return \"tty\";\n}\n\nconst resetCode = \"\\x1b[0m\";\nconst boldCode = \"\\x1b[1m\";\nconst colorCodes = {\n darkBlack: \"\\x1b[30m\",\n darkRed: \"\\x1b[31m\",\n darkGreen: \"\\x1b[32m\",\n darkYellow: \"\\x1b[33m\",\n darkBlue: \"\\x1b[34m\",\n darkMagenta: \"\\x1b[35m\",\n darkCyan: \"\\x1b[36m\",\n darkWhite: \"\\x1b[37m\",\n brightBlack: \"\\x1b[90m\",\n brightRed: \"\\x1b[91m\",\n brightGreen: \"\\x1b[92m\",\n brightYellow: \"\\x1b[93m\",\n brightBlue: \"\\x1b[94m\",\n brightMagenta: \"\\x1b[95m\",\n brightCyan: \"\\x1b[96m\",\n brightWhite: \"\\x1b[97m\",\n};\n","import { TypoSupport, TypoText, typoPrintableString } from \"./Typo\";\n\nexport type Grid = Array<GridRow>;\nexport type GridRow = Array<GridCell>;\nexport type GridCell = Array<TypoText>;\n\nexport function gridToPrintableLines(\n grid: Grid,\n typoSupport: TypoSupport,\n delimiter: string = \"\",\n): Array<string> {\n const lines = new Array<string>();\n const gridWidths = new Array<number>();\n for (const gridRow of grid) {\n for (\n let gridColumnIndex = 0;\n gridColumnIndex < gridRow.length;\n gridColumnIndex++\n ) {\n const gridCell = gridRow[gridColumnIndex]!;\n const length = gridCellLength(gridCell);\n if (\n gridWidths[gridColumnIndex] === undefined ||\n length > gridWidths[gridColumnIndex]!\n ) {\n gridWidths[gridColumnIndex] = length;\n }\n }\n }\n for (const gridRow of grid) {\n const lineColumns = new Array<string>();\n for (\n let gridColumnIndex = 0;\n gridColumnIndex < gridRow.length;\n gridColumnIndex++\n ) {\n const gridCell = gridRow[gridColumnIndex]!;\n const parts = gridCell.map((text) =>\n typoPrintableString(typoSupport, text),\n );\n if (gridColumnIndex < gridRow.length - 1) {\n const length = gridCellLength(gridCell);\n const padding = \" \".repeat(gridWidths[gridColumnIndex]! - length);\n lineColumns.push(parts.join(\"\") + padding);\n } else {\n lineColumns.push(parts.join(\"\"));\n }\n }\n lines.push(lineColumns.join(delimiter));\n }\n return lines;\n}\n\nfunction gridCellLength(cell: GridCell): number {\n let length = 0;\n for (const text of cell) {\n length += text.value.length;\n }\n return length;\n}\n","import { ReaderTokenizer } from \"./Reader\";\nimport { Type } from \"./Type\";\n\nexport type Option<Value> = {\n generateUsage(): OptionUsage;\n prepareConsumer(readerTokenizer: ReaderTokenizer): OptionConsumer<Value>;\n};\n\nexport type OptionUsage = {\n description: string | undefined;\n long: Lowercase<string>; // TODO - better type for long option names ?\n short: string | undefined;\n label: Uppercase<string> | undefined;\n};\n\nexport type OptionConsumer<Value> = () => Value;\n\nexport function optionFlag(definition: {\n description?: string;\n long: Lowercase<string>;\n short?: string;\n aliases?: { longs?: Array<Lowercase<string>>; shorts?: Array<string> };\n default?: () => boolean;\n}): Option<boolean> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n long: definition.long,\n short: definition.short,\n label: undefined,\n };\n },\n prepareConsumer(readerTokenizer: ReaderTokenizer) {\n const key = definition.long;\n const longs = [definition.long];\n if (definition.aliases?.longs) {\n longs.push(...definition.aliases?.longs);\n }\n const shorts = definition.short ? [definition.short] : [];\n if (definition.aliases?.shorts) {\n shorts.push(...definition.aliases?.shorts);\n }\n readerTokenizer.registerFlag({ key, longs, shorts });\n return () => {\n const value = readerTokenizer.consumeFlag(key);\n if (value === undefined) {\n return definition.default ? definition.default() : false;\n }\n return value;\n };\n },\n };\n}\n\n// TODO - option with comma-separated values, e.g. --names=alice,bob,charlie\n\nexport function optionRepeatable<Value>(definition: {\n description?: string;\n type: Type<Value>;\n long: Lowercase<string>;\n short?: string;\n aliases?: { longs?: Array<Lowercase<string>>; shorts?: Array<string> };\n label?: Uppercase<string>;\n}): Option<Array<Value>> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n long: definition.long,\n short: definition.short,\n label:\n `<${definition.label ?? definition.type.label}>` as Uppercase<string>,\n };\n },\n prepareConsumer(readerTokenizer: ReaderTokenizer) {\n const key = definition.long;\n const longs = definition.long ? [definition.long] : [];\n if (definition.aliases?.longs) {\n longs.push(...definition.aliases?.longs);\n }\n const shorts = definition.short ? [definition.short] : [];\n if (definition.aliases?.shorts) {\n shorts.push(...definition.aliases?.shorts);\n }\n readerTokenizer.registerOption({ key, longs, shorts });\n return () => {\n return readerTokenizer.consumeOption(key).map(definition.type.decoder);\n };\n },\n };\n}\n\nexport function optionSingleValue<Value>(definition: {\n description?: string;\n type: Type<Value>;\n long: Lowercase<string>;\n short?: string;\n aliases?: { longs?: Array<Lowercase<string>>; shorts?: Array<string> };\n label?: Uppercase<string>;\n default: () => Value;\n}): Option<Value> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n long: definition.long,\n short: definition.short,\n label:\n `<${definition.label ?? definition.type.label}>` as Uppercase<string>,\n };\n },\n prepareConsumer(readerTokenizer: ReaderTokenizer) {\n const key = definition.long;\n const longs = [definition.long];\n if (definition.aliases?.longs) {\n longs.push(...definition.aliases?.longs);\n }\n const shorts = definition.short ? [definition.short] : [];\n if (definition.aliases?.shorts) {\n shorts.push(...definition.aliases?.shorts);\n }\n readerTokenizer.registerOption({ key, longs, shorts });\n return () => {\n // TODO - smooth and beautiful error handling\n const values = readerTokenizer.consumeOption(definition.long);\n if (values.length > 1) {\n throw new Error(\n `Multiple values provided for option: ${definition.long}`,\n );\n }\n const firstValue = values[0];\n if (firstValue === undefined) {\n return definition.default();\n }\n return definition.type.decoder(firstValue);\n };\n },\n };\n}\n","export type ReaderPositionals = {\n consumePositional(): string | undefined;\n};\n\nexport class ReaderTokenizer {\n #parsedArgv: Array<string>;\n #parsedIndex: number;\n #parsedDouble: boolean;\n\n #flagKeyByShort: Map<string, string>;\n #flagKeyByLong: Map<string, string>;\n #flagInfoByKey: Map<string, {}>;\n #flagResultByKey: Map<string, boolean | null>;\n\n #optionKeyByShort: Map<string, string>;\n #optionKeyByLong: Map<string, string>;\n #optionInfoByKey: Map<string, {}>; // TODO - what dis for\n #optionResultByKey: Map<string, Array<string> | null>;\n\n constructor(argv: Array<string>) {\n this.#parsedArgv = argv;\n this.#parsedIndex = 0;\n this.#parsedDouble = false;\n\n // TODO - this seems like a good candidate for abstraction\n this.#flagKeyByShort = new Map();\n this.#flagKeyByLong = new Map();\n this.#flagInfoByKey = new Map();\n this.#flagResultByKey = new Map();\n\n this.#optionKeyByShort = new Map();\n this.#optionKeyByLong = new Map();\n this.#optionInfoByKey = new Map();\n this.#optionResultByKey = new Map();\n }\n\n registerFlag(definition: {\n key: string;\n shorts: Array<string>;\n longs: Array<string>;\n }) {\n this.#ensureUniqueKey(definition.key);\n this.#flagInfoByKey.set(definition.key, {});\n for (const short of definition.shorts) {\n this.#ensureUniqueName(short);\n this.#flagKeyByShort.set(short, definition.key);\n }\n for (const long of definition.longs) {\n this.#ensureUniqueName(long);\n this.#flagKeyByLong.set(long, definition.key);\n }\n }\n\n registerOption(definition: {\n key: string;\n shorts: Array<string>;\n longs: Array<string>;\n }) {\n this.#ensureUniqueKey(definition.key);\n this.#optionInfoByKey.set(definition.key, {});\n for (const short of definition.shorts) {\n this.#ensureUniqueName(short);\n this.#optionKeyByShort.set(short, definition.key);\n }\n for (const long of definition.longs) {\n this.#ensureUniqueName(long);\n this.#optionKeyByLong.set(long, definition.key);\n }\n }\n\n consumeFlag(key: string): boolean | undefined {\n const flagInfo = this.#flagInfoByKey.get(key);\n if (flagInfo === undefined) {\n throw new Error(`Option flag not registered: ${key}`);\n }\n const result = this.#flagResultByKey.get(key);\n if (result === undefined) {\n this.#flagResultByKey.set(key, null);\n return undefined;\n }\n if (result === null) {\n throw new Error(`Option flag already consumed: ${key}`);\n }\n this.#flagResultByKey.set(key, null);\n return result;\n }\n\n consumeOption(key: string): Array<string> {\n const optionInfo = this.#optionInfoByKey.get(key);\n if (optionInfo === undefined) {\n throw new Error(`Option values not registered: ${key}`);\n }\n const result = this.#optionResultByKey.get(key);\n if (result === undefined) {\n this.#optionResultByKey.set(key, null);\n return new Array<string>();\n }\n if (result === null) {\n throw new Error(`Option values already consumed: ${key}`);\n }\n this.#optionResultByKey.set(key, null);\n return result;\n }\n\n consumePositional(): string | undefined {\n while (true) {\n const arg = this.#consumeArg();\n if (arg === null) {\n return undefined;\n }\n const positional = this.#parseAsPositional(arg);\n if (positional !== null) {\n return positional;\n }\n }\n }\n\n #consumeArg(): string | null {\n const arg = this.#parsedArgv[this.#parsedIndex];\n if (arg === undefined) {\n return null;\n }\n this.#parsedIndex++;\n if (!this.#parsedDouble) {\n if (arg === \"--\") {\n this.#parsedDouble = true;\n return this.#consumeArg();\n }\n }\n return arg;\n }\n\n #consumeOptionValue(name: string) {\n const arg = this.#consumeArg();\n if (arg === null) {\n throw new Error(`Option ${name} requires a value`);\n }\n if (this.#parsedDouble) {\n throw new Error(`Option ${name} requires a value before --`);\n }\n // TODO - is that weird, could a valid value start with dash ?\n if (arg.startsWith(\"-\")) {\n throw new Error(`Option ${name} requires a value, got: ${arg}`);\n }\n return arg;\n }\n\n #parseAsPositional(arg: string): string | null {\n if (this.#parsedDouble) {\n return arg;\n }\n if (arg.startsWith(\"--\")) {\n const valueIndexStart = arg.indexOf(\"=\");\n if (valueIndexStart === -1) {\n this.#consumeOptionLong(arg.slice(2), null);\n } else {\n this.#consumeOptionLong(\n arg.slice(2, valueIndexStart),\n arg.slice(valueIndexStart + 1),\n );\n }\n return null;\n }\n if (arg.startsWith(\"-\")) {\n let shortIndexStart = 1;\n let shortIndexEnd = 2;\n while (shortIndexEnd <= arg.length) {\n const short = arg.slice(shortIndexStart, shortIndexEnd);\n const rest = arg.slice(shortIndexEnd);\n const result = this.#tryConsumeOptionShort(short, rest);\n if (result === true) {\n return null;\n }\n if (result === false) {\n shortIndexStart = shortIndexEnd;\n }\n shortIndexEnd++;\n }\n throw new Error(\n `Unknown short flags or options: ${arg.slice(shortIndexStart)}`,\n );\n }\n return arg;\n }\n\n #consumeOptionLong(long: string, direct: string | null): void {\n const flagKey = this.#flagKeyByLong.get(long);\n if (flagKey !== undefined) {\n if (direct !== null) {\n const value = asBoolean(direct);\n if (value !== undefined) {\n return this.#acknowledgeFlag(flagKey, value);\n }\n throw new Error(\n `Invalid parameter for long flag: ${flagKey}, value: ${direct}`,\n );\n }\n return this.#acknowledgeFlag(flagKey, true);\n }\n const optionKey = this.#optionKeyByLong.get(long);\n if (optionKey !== undefined) {\n if (direct !== null) {\n return this.#acknowledgeOption(optionKey, direct);\n }\n return this.#acknowledgeOption(optionKey, this.#consumeOptionValue(long));\n }\n throw new Error(`Unknown long flag or option: ${long}`);\n }\n\n #tryConsumeOptionShort(short: string, rest: string): boolean | null {\n const flagKey = this.#flagKeyByShort.get(short);\n if (flagKey !== undefined) {\n if (rest.startsWith(\"=\")) {\n const value = asBoolean(rest.slice(1));\n if (value !== undefined) {\n this.#acknowledgeFlag(flagKey, value);\n return true;\n }\n throw new Error(\n `Invalid parameter for short flag: ${short}, value: ${rest}`,\n );\n }\n this.#acknowledgeFlag(flagKey, true);\n return rest === \"\";\n }\n const optionKey = this.#optionKeyByShort.get(short);\n if (optionKey !== undefined) {\n if (rest === \"\") {\n this.#acknowledgeOption(optionKey, this.#consumeOptionValue(short));\n return true;\n }\n if (rest.startsWith(\"=\")) {\n this.#acknowledgeOption(optionKey, rest.slice(1));\n } else {\n this.#acknowledgeOption(optionKey, rest);\n }\n return true;\n }\n return null;\n }\n\n #acknowledgeFlag(key: string, value: boolean) {\n if (this.#flagResultByKey.has(key)) {\n throw new Error(`Flag already set: ${key}`);\n }\n this.#flagResultByKey.set(key, value);\n }\n\n #acknowledgeOption(key: string, value: string) {\n const values = this.#optionResultByKey.get(key) ?? new Array<string>();\n values.push(value);\n this.#optionResultByKey.set(key, values);\n }\n\n #ensureUniqueKey(key: string) {\n if (this.#flagInfoByKey.has(key)) {\n throw new Error(`Option already registered: ${key}`);\n }\n if (this.#optionInfoByKey.has(key)) {\n throw new Error(`Option already registered: ${key}`);\n }\n }\n\n #ensureUniqueName(nameShortOrLong: string) {\n // TODO - overall better error handling\n // TODO - short flag overlap might be annoying here\n if (this.#flagKeyByShort.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n if (this.#flagKeyByLong.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n if (this.#optionKeyByShort.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n if (this.#optionKeyByLong.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n }\n}\n\nfunction asBoolean(value: string): boolean | undefined {\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"t\" || lower === \"y\" || lower === \"yes\") {\n return true;\n }\n if (lower === \"false\" || lower === \"f\" || lower === \"n\" || lower === \"no\") {\n return false;\n }\n return undefined;\n}\n","import { CommandUsage } from \"./Command\";\nimport { GridCell, GridRow, gridToPrintableLines } from \"./Grid\";\nimport { TypoSupport, TypoText, typoPrintableString } from \"./Typo\";\n\nexport function usageToPrintableLines(params: {\n cliName: Lowercase<string>;\n commandUsage: CommandUsage;\n typoSupport: TypoSupport;\n}) {\n const { cliName, commandUsage, typoSupport } = params;\n\n const lines = new Array<string>();\n\n lines.push(\n typoPrintableString(typoSupport, textDescription(commandUsage.description)),\n );\n if (commandUsage.details) {\n for (const detailLine of commandUsage.details) {\n lines.push(typoPrintableString(typoSupport, textDetails(detailLine)));\n }\n }\n\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Usage:\")));\n const breadcrumbs = [\n \" \",\n typoPrintableString(typoSupport, textFixed(cliName)),\n ].concat(\n commandUsage.breadcrumbs.map((breadcrumb) => {\n if (\"argument\" in breadcrumb) {\n return typoPrintableString(typoSupport, textInput(breadcrumb.argument));\n }\n if (\"command\" in breadcrumb) {\n return typoPrintableString(typoSupport, textFixed(breadcrumb.command));\n }\n throw new Error(`Unknown breadcrumb: ${JSON.stringify(breadcrumb)}`);\n }),\n );\n lines.push(breadcrumbs.join(\" \"));\n\n if (commandUsage.arguments.length > 0) {\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Arguments:\")));\n const grid = new Array<GridRow>();\n for (const argumentUsage of commandUsage.arguments) {\n const gridRow = new Array<GridCell>();\n gridRow.push([textDelimiter()]);\n gridRow.push([textInput(argumentUsage.label)]);\n if (argumentUsage.description) {\n gridRow.push([textDelimiter()]);\n gridRow.push([textDescription(argumentUsage.description)]);\n }\n grid.push(gridRow);\n }\n lines.push(...gridToPrintableLines(grid, typoSupport));\n }\n\n if (commandUsage.subcommands.length > 0) {\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Subcommands:\")));\n const grid = new Array<GridRow>();\n for (const subcommand of commandUsage.subcommands) {\n const gridRow = new Array<GridCell>();\n gridRow.push([textDelimiter()]);\n gridRow.push([textFixed(subcommand.name)]);\n if (subcommand.description) {\n gridRow.push([textDelimiter()]);\n gridRow.push([textDescription(subcommand.description)]);\n }\n grid.push(gridRow);\n }\n lines.push(...gridToPrintableLines(grid, typoSupport));\n }\n\n if (commandUsage.options.length > 0) {\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Options:\")));\n const grid = new Array<GridRow>();\n for (const optionUsage of commandUsage.options) {\n const gridRow = new Array<GridCell>();\n gridRow.push([textDelimiter()]);\n if (optionUsage.short) {\n gridRow.push([textFixed(`-${optionUsage.short}`), { value: \", \" }]);\n } else {\n gridRow.push([]);\n }\n if (optionUsage.label) {\n gridRow.push([\n textFixed(`--${optionUsage.long} `),\n textInput(optionUsage.label),\n ]);\n } else {\n gridRow.push([textFixed(`--${optionUsage.long}`)]);\n }\n if (optionUsage.description) {\n gridRow.push([textDelimiter()]);\n gridRow.push([textDescription(optionUsage.description)]);\n }\n grid.push(gridRow);\n }\n lines.push(...gridToPrintableLines(grid, typoSupport));\n }\n\n lines.push(\"\");\n return lines;\n}\n\nfunction textCategory(text: string): TypoText {\n return { value: text, color: \"brightGreen\", bold: true };\n}\n\nfunction textDescription(text: string): TypoText {\n return { value: text, bold: true };\n}\n\nfunction textDetails(text: string): TypoText {\n return { value: text, color: \"brightBlack\" };\n}\n\nfunction textFixed(text: string): TypoText {\n return { value: text, color: \"brightCyan\", bold: true };\n}\n\nfunction textInput(text: string): TypoText {\n return { value: text, color: \"brightBlue\" };\n}\n\nfunction textDelimiter(): TypoText {\n return { value: \" \" };\n}\n","import { Command } from \"./Command\";\nimport { ReaderTokenizer } from \"./Reader\";\nimport { typoInferSupport } from \"./Typo\";\nimport { usageToPrintableLines } from \"./Usage\";\n\nexport async function runCommand<Context, Result>(\n cliName: Lowercase<string>,\n cliArgs: Array<string>,\n context: Context,\n command: Command<Context, Result>,\n cliInfo?: {\n version?: string;\n helpOnError?: boolean;\n },\n): Promise<Result> {\n const readerTokenizer = new ReaderTokenizer(cliArgs);\n if (cliInfo?.version) {\n readerTokenizer.registerFlag({\n key: \"version\",\n shorts: [],\n longs: [\"version\"],\n });\n }\n readerTokenizer.registerFlag({\n key: \"help\",\n shorts: [],\n longs: [\"help\"],\n });\n /*\n // TODO - handle completions ?\n readerTokenizer.registerFlag({\n key: \"completion\",\n shorts: [],\n longs: [\"completion\"],\n });\n */\n try {\n const commandRunner = command.prepareRunner(readerTokenizer);\n if (cliInfo?.version) {\n if (readerTokenizer.consumeFlag(\"version\")) {\n console.log(cliName, cliInfo.version);\n process.exit(0);\n }\n }\n if (readerTokenizer.consumeFlag(\"help\")) {\n console.log(\n usageToPrintableLines({\n cliName,\n commandUsage: commandRunner.computeUsage(),\n typoSupport: typoInferSupport(),\n }).join(\"\\n\"),\n );\n process.exit(0);\n }\n try {\n return await commandRunner.execute(context);\n } catch (error) {\n if (cliInfo?.helpOnError ?? true) {\n console.log(\n usageToPrintableLines({\n cliName,\n commandUsage: commandRunner.computeUsage(),\n typoSupport: typoInferSupport(),\n }).join(\"\\n\"),\n );\n }\n console.error(error); // TODO - better, prettier errors\n process.exit(1);\n }\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n}\n","export type Type<Value> = {\n label: Uppercase<string>; // TODO - is there a better way to enforce uppercase labels?\n decoder(value: string): Value;\n};\n\nexport const typeBoolean: Type<boolean> = {\n label: \"BOOLEAN\",\n decoder(value: string) {\n if (value === \"true\") {\n return true;\n }\n if (value === \"false\") {\n return false;\n }\n throw new Error(`Invalid boolean value: ${value}`);\n },\n};\n\nexport const typeDate: Type<Date> = {\n label: \"DATE\",\n decoder(value: string) {\n const timestamp = Date.parse(value);\n if (isNaN(timestamp)) {\n throw new Error(`Invalid date value: ${value}`);\n }\n return new Date(timestamp);\n },\n};\n\nexport const typeString: Type<string> = {\n label: \"STRING\",\n decoder(value: string) {\n return value;\n },\n};\n\nexport const typeNumber: Type<number> = {\n label: \"NUMBER\",\n decoder(value: string) {\n return Number(value);\n },\n};\n\nexport const typeBigInt: Type<bigint> = {\n label: \"BIGINT\",\n decoder(value: string) {\n return BigInt(value);\n },\n};\n\nexport function typeCommaTuple<\n const Elements extends Array<any>,\n>(elementTypes: {\n [K in keyof Elements]: Type<Elements[K]>;\n}): Type<Elements> {\n return {\n label: elementTypes\n .map((elementType) => elementType.label)\n .join(\",\") as Uppercase<string>,\n decoder(value: string) {\n const parts = value.split(\",\", elementTypes.length);\n if (parts.length !== elementTypes.length) {\n throw new Error(\n `Invalid tuple value: ${value}, expected ${elementTypes.length} parts`,\n );\n }\n return parts.map((part, index) =>\n elementTypes[index]!.decoder(part),\n ) as Elements;\n },\n };\n}\n\nexport function typeCommaList<Value>(\n elementType: Type<Value>,\n): Type<Array<Value>> {\n return {\n label:\n `${elementType.label}[,${elementType.label}...]` as Uppercase<string>,\n decoder(value: string) {\n return value.split(\",\").map(elementType.decoder);\n },\n };\n}\n"],"mappings":"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","names":["index_exports","__export","ReaderTokenizer","argumentOptional","argumentRequired","argumentVariadics","command","commandWithSubcommands","execution","gridToPrintableLines","optionFlag","optionRepeatable","optionSingleValue","runCommand","typeBigInt","typeBoolean","typeCommaList","typeCommaTuple","typeDate","typeNumber","typeString","typoInferSupport","typoPrintableString","usageToPrintableLines","__toCommonJS","argumentRequired","definition","readerPositionals","positional","argumentOptional","argumentVariadics","values","command","metadata","execution","readerTokenizer","computeUsage","executionUsage","argument","breadcrumbArgument","executionResolver","lastPositional","executionCallback","context","error","_context","commandWithSubcommands","subcommands","subcommandName","subcommandInput","subcommandRunner","subcommandUsage","breadcrumbCommand","payload","name","subcommand","value","execution","inputs","handler","optionsUsage","optionKey","optionInput","argumentsUsage","argumentInput","readerTokenizer","optionsConsumers","argumentsValues","optionsValues","context","typoPrintableString","typoSupport","typoText","colorStartCode","colorCodes","colorBoldCode","boldCode","resetCode","colorStartTag","colorEndTag","boldStartTag","boldEndTag","typoInferSupport","gridToPrintableLines","grid","typoSupport","delimiter","lines","gridWidths","gridRow","gridColumnIndex","gridCell","length","gridCellLength","lineColumns","parts","text","typoPrintableString","padding","cell","optionFlag","definition","readerTokenizer","key","longs","shorts","value","optionRepeatable","optionSingleValue","values","firstValue","_parsedArgv","_parsedIndex","_parsedDouble","_flagKeyByShort","_flagKeyByLong","_flagInfoByKey","_flagResultByKey","_optionKeyByShort","_optionKeyByLong","_optionInfoByKey","_optionResultByKey","_ReaderTokenizer_instances","consumeArg_fn","consumeOptionValue_fn","parseAsPositional_fn","consumeOptionLong_fn","tryConsumeOptionShort_fn","acknowledgeFlag_fn","acknowledgeOption_fn","ensureUniqueKey_fn","ensureUniqueName_fn","ReaderTokenizer","argv","__privateAdd","__privateSet","definition","__privateMethod","__privateGet","short","long","key","result","arg","positional","__privateWrapper","name","valueIndexStart","shortIndexStart","shortIndexEnd","rest","direct","flagKey","value","asBoolean","optionKey","values","nameShortOrLong","lower","usageToPrintableLines","params","cliName","commandUsage","typoSupport","lines","typoPrintableString","textDescription","detailLine","textDetails","textCategory","breadcrumbs","textFixed","breadcrumb","textInput","grid","argumentUsage","gridRow","textDelimiter","gridToPrintableLines","subcommand","optionUsage","text","runCommand","cliName","cliArgs","context","command","cliInfo","readerTokenizer","ReaderTokenizer","commandRunner","usageToPrintableLines","typoInferSupport","error","typeBoolean","value","typeDate","timestamp","typeString","typeNumber","typeBigInt","typeCommaTuple","elementTypes","elementType","parts","part","index","typeCommaList"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/Argument.ts","../src/lib/Command.ts","../src/lib/Execution.ts","../src/lib/Typo.ts","../src/lib/Grid.ts","../src/lib/Option.ts","../src/lib/Reader.ts","../src/lib/Usage.ts","../src/lib/Run.ts","../src/lib/Type.ts"],"sourcesContent":["export * from \"./lib/Argument\";\nexport * from \"./lib/Command\";\nexport * from \"./lib/Execution\";\nexport * from \"./lib/Grid\";\nexport * from \"./lib/Option\";\nexport * from \"./lib/Reader\";\nexport * from \"./lib/Run\";\nexport * from \"./lib/Type\";\nexport * from \"./lib/Typo\";\nexport * from \"./lib/Usage\";\n","import { ReaderPositionals } from \"./Reader\";\nimport { Type } from \"./Type\";\n\nexport type Argument<Value> = {\n generateUsage(): ArgumentUsage;\n consumeValue(readerPositionals: ReaderPositionals): Value;\n};\n\nexport type ArgumentUsage = {\n description: string | undefined;\n label: string;\n};\n\nexport function argumentRequired<Value>(definition: {\n description?: string;\n type: Type<Value>;\n label?: Uppercase<string>;\n}): Argument<Value> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n label: `<${definition.label ?? definition.type.label}>`,\n };\n },\n consumeValue(readerPositionals: ReaderPositionals) {\n const positional = readerPositionals.consumePositional();\n if (positional === undefined) {\n throw new Error(\n `Missing required arg: <${definition.label ?? definition.type.label}>`,\n );\n }\n return definition.type.decoder(positional);\n },\n };\n}\n\nexport function argumentOptional<Value>(definition: {\n description?: string;\n type: Type<Value>;\n label?: Uppercase<string>;\n default: () => Value;\n}): Argument<Value> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n label: `[${definition.label ?? definition.type.label}]`,\n };\n },\n consumeValue(readerPositionals: ReaderPositionals) {\n const positional = readerPositionals.consumePositional();\n if (positional === undefined) {\n return definition.default();\n }\n return definition.type.decoder(positional);\n },\n };\n}\n\nexport function argumentVariadics<Value>(definition: {\n description?: string;\n type: Type<Value>;\n label?: Uppercase<string>;\n endDelimiter?: string;\n}): Argument<Array<Value>> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n label:\n `[${definition.label ?? definition.type.label}...]` +\n (definition.endDelimiter\n ? ` (end with ${definition.endDelimiter})`\n : \"\"),\n };\n },\n consumeValue(readerPositionals: ReaderPositionals) {\n const values: Array<Value> = [];\n while (true) {\n const positional = readerPositionals.consumePositional();\n if (\n positional === undefined ||\n positional === definition.endDelimiter\n ) {\n break;\n }\n values.push(definition.type.decoder(positional));\n }\n return values;\n },\n };\n}\n","import { ArgumentUsage } from \"./Argument\";\nimport { Execution } from \"./Execution\";\nimport { OptionUsage } from \"./Option\";\nimport { ReaderTokenizer } from \"./Reader\";\n\nexport type Command<Context, Result> = {\n getDescription(): string | undefined;\n buildInterpreter(\n readerTokenizer: ReaderTokenizer,\n ): CommandInterpreter<Context, Result>;\n};\n\nexport type CommandMetadata = {\n description: string;\n details?: Array<string>;\n // TODO - printable examples ?\n};\n\nexport type CommandInterpreter<Context, Result> = {\n computeUsage(): CommandUsage;\n execute(context: Context): Promise<Result>;\n};\n\nexport type CommandUsage = {\n breadcrumbs: Array<CommandUsageBreadcrumb>;\n description: string;\n details: Array<string> | undefined;\n options: Array<OptionUsage>;\n arguments: Array<ArgumentUsage>;\n subcommands: Array<{ name: string; description: string | undefined }>;\n};\n\nexport type CommandUsageBreadcrumb = { argument: string } | { command: string };\n\nexport function command<Context, Result>(\n metadata: CommandMetadata,\n execution: Execution<Context, Result>,\n): Command<Context, Result> {\n return {\n getDescription() {\n return metadata.description;\n },\n buildInterpreter(readerTokenizer: ReaderTokenizer) {\n function computeUsage(): CommandUsage {\n const executionUsage = execution.computeUsage();\n return {\n breadcrumbs: executionUsage.arguments.map((argument) =>\n breadcrumbArgument(argument.label),\n ),\n description: metadata.description,\n details: metadata.details,\n options: executionUsage.options,\n arguments: executionUsage.arguments,\n subcommands: [],\n };\n }\n try {\n const executionResolver = execution.createResolver(readerTokenizer);\n const lastPositional = readerTokenizer.consumePositional();\n if (lastPositional !== undefined) {\n throw Error(`Unprocessed positional: ${lastPositional}`);\n }\n const executionCallback = executionResolver();\n return {\n computeUsage,\n async execute(context: Context) {\n return await executionCallback(context);\n },\n };\n } catch (error) {\n return {\n computeUsage,\n async execute(_context: Context) {\n throw error;\n },\n };\n }\n },\n };\n}\n\nexport function commandWithSubcommands<Context, Payload, Result>(\n metadata: CommandMetadata,\n execution: Execution<Context, Payload>,\n subcommands: { [subcommand: Lowercase<string>]: Command<Payload, Result> },\n): Command<Context, Result> {\n return {\n getDescription() {\n return metadata.description;\n },\n buildInterpreter(readerTokenizer: ReaderTokenizer) {\n try {\n const executionResolver = execution.createResolver(readerTokenizer);\n const subcommandName = readerTokenizer.consumePositional();\n if (subcommandName === undefined) {\n throw new Error(\"Expected a subcommand\");\n }\n const subcommandInput =\n subcommands[subcommandName as Lowercase<string>];\n if (subcommandInput === undefined) {\n throw new Error(`Unknown subcommand: ${subcommandName}`);\n }\n const subcommandInterpreter =\n subcommandInput.buildInterpreter(readerTokenizer);\n const executionCallback = executionResolver();\n return {\n computeUsage() {\n const executionUsage = execution.computeUsage();\n const subcommandUsage = subcommandInterpreter.computeUsage();\n return {\n breadcrumbs: executionUsage.arguments\n .map((argument) => breadcrumbArgument(argument.label))\n .concat([breadcrumbCommand(subcommandName)])\n .concat(subcommandUsage.breadcrumbs),\n description: subcommandUsage.description,\n details: subcommandUsage.details,\n options: executionUsage.options.concat(subcommandUsage.options),\n arguments: executionUsage.arguments.concat(\n subcommandUsage.arguments,\n ),\n subcommands: subcommandUsage.subcommands,\n };\n },\n async execute(context: Context) {\n const payload = await executionCallback(context);\n return await subcommandInterpreter.execute(payload);\n },\n };\n } catch (error) {\n return {\n computeUsage() {\n const executionUsage = execution.computeUsage();\n return {\n breadcrumbs: executionUsage.arguments\n .map((argument) => breadcrumbArgument(argument.label))\n .concat([breadcrumbCommand(\"<SUBCOMMAND>\")]),\n description: metadata.description,\n details: metadata.details,\n options: executionUsage.options,\n arguments: executionUsage.arguments,\n subcommands: Object.entries(subcommands).map(\n ([name, subcommand]) => ({\n name,\n description: subcommand.getDescription(),\n }),\n ),\n };\n },\n async execute(_context: Context) {\n throw error;\n },\n };\n }\n },\n };\n}\n\nfunction breadcrumbArgument(value: string): CommandUsageBreadcrumb {\n return { argument: value };\n}\n\nfunction breadcrumbCommand(value: string): CommandUsageBreadcrumb {\n return { command: value };\n}\n","import { Argument, ArgumentUsage } from \"./Argument\";\nimport { Option, OptionUsage } from \"./Option\";\nimport { ReaderTokenizer } from \"./Reader\";\n\nexport type Execution<Context, Result> = {\n computeUsage(): ExecutionUsage;\n createResolver(\n readerTokenizer: ReaderTokenizer,\n ): ExecutionResolver<Context, Result>;\n};\n\nexport type ExecutionResolver<Context, Result> = () => ExecutionCallback<\n Context,\n Result\n>;\n\nexport type ExecutionCallback<Context, Result> = (\n context: Context,\n) => Promise<Result>;\n\nexport type ExecutionUsage = {\n options: Array<OptionUsage>;\n arguments: Array<ArgumentUsage>;\n};\n\nexport function execution<\n Context,\n Result,\n Options extends { [option: string]: any },\n const Arguments extends Array<any>,\n>(\n inputs: {\n options: { [K in keyof Options]: Option<Options[K]> };\n arguments: { [K in keyof Arguments]: Argument<Arguments[K]> };\n },\n handler: (\n context: Context,\n inputs: {\n options: Options;\n arguments: Arguments;\n },\n ) => Promise<Result>,\n): Execution<Context, Result> {\n return {\n computeUsage() {\n const optionsUsage = new Array<OptionUsage>();\n for (const optionKey in inputs.options) {\n const optionInput = inputs.options[optionKey]!;\n optionsUsage.push(optionInput.generateUsage());\n }\n const argumentsUsage = new Array<ArgumentUsage>();\n for (const argumentInput of inputs.arguments) {\n argumentsUsage.push(argumentInput.generateUsage());\n }\n return { options: optionsUsage, arguments: argumentsUsage };\n },\n createResolver(readerTokenizer: ReaderTokenizer) {\n const optionsConsumers: any = {};\n for (const optionKey in inputs.options) {\n const optionInput = inputs.options[optionKey]!;\n optionsConsumers[optionKey] =\n optionInput.prepareConsumer(readerTokenizer);\n }\n const argumentsValues: any = [];\n for (const argumentInput of inputs.arguments) {\n argumentsValues.push(argumentInput.consumeValue(readerTokenizer));\n }\n return () => {\n const optionsValues: any = {};\n for (const optionKey in optionsConsumers) {\n optionsValues[optionKey] = optionsConsumers[optionKey]!();\n }\n return async (context: Context) => {\n return await handler(context, {\n options: optionsValues,\n arguments: argumentsValues,\n });\n };\n };\n },\n };\n}\n","export type TypoSupport = \"none\" | \"tty\" | \"html\" | \"mock\";\n\nexport type TypoText = {\n value: string;\n color?: keyof typeof colorCodes;\n bold?: boolean;\n};\n\nexport function typoPrintableString(\n typoSupport: TypoSupport,\n typoText: TypoText,\n): string {\n if (typoSupport === \"none\") {\n return typoText.value;\n }\n if (typoSupport === \"tty\") {\n const colorStartCode = typoText.color ? colorCodes[typoText.color] : \"\";\n const colorBoldCode = typoText.bold ? boldCode : \"\";\n return `${colorStartCode}${colorBoldCode}${typoText.value}${resetCode}`;\n }\n if (typoSupport === \"html\") {\n const colorStartTag = typoText.color\n ? `<span style=\"color: ${typoText.color}\">`\n : \"\";\n const colorEndTag = typoText.color ? \"</span>\" : \"\";\n const boldStartTag = typoText.bold ? \"<b>\" : \"\";\n const boldEndTag = typoText.bold ? \"</b>\" : \"\";\n return `${colorStartTag}${boldStartTag}${typoText.value}${boldEndTag}${colorEndTag}`;\n }\n if (typoSupport === \"mock\") {\n if (typoText.color && typoText.bold) {\n return `{${typoText.value}}@${typoText.color}+`;\n }\n if (typoText.color) {\n return `{${typoText.value}}@${typoText.color}`;\n }\n if (typoText.bold) {\n return `{${typoText.value}}+`;\n }\n return `{${typoText.value}}`;\n }\n throw new Error(`Unknown typo support: ${typoSupport}`);\n}\n\nexport function typoInferProcessSupport(): TypoSupport {\n if (!process) {\n return \"none\";\n }\n if (process.env) {\n if (process.env[\"FORCE_COLOR\"] === \"0\") {\n return \"none\";\n }\n if (process.env[\"FORCE_COLOR\"]) {\n return \"tty\";\n }\n if (\"NO_COLOR\" in process.env) {\n return \"none\";\n }\n }\n if (!process.stdout || !process.stdout.isTTY) {\n return \"none\";\n }\n return \"tty\";\n}\n\nconst resetCode = \"\\x1b[0m\";\nconst boldCode = \"\\x1b[1m\";\nconst colorCodes = {\n darkBlack: \"\\x1b[30m\",\n darkRed: \"\\x1b[31m\",\n darkGreen: \"\\x1b[32m\",\n darkYellow: \"\\x1b[33m\",\n darkBlue: \"\\x1b[34m\",\n darkMagenta: \"\\x1b[35m\",\n darkCyan: \"\\x1b[36m\",\n darkWhite: \"\\x1b[37m\",\n brightBlack: \"\\x1b[90m\",\n brightRed: \"\\x1b[91m\",\n brightGreen: \"\\x1b[92m\",\n brightYellow: \"\\x1b[93m\",\n brightBlue: \"\\x1b[94m\",\n brightMagenta: \"\\x1b[95m\",\n brightCyan: \"\\x1b[96m\",\n brightWhite: \"\\x1b[97m\",\n};\n","import { TypoSupport, TypoText, typoPrintableString } from \"./Typo\";\n\nexport type Grid = Array<GridRow>;\nexport type GridRow = Array<GridCell>;\nexport type GridCell = Array<TypoText>;\n\nexport function gridToPrintableLines(\n grid: Grid,\n typoSupport: TypoSupport,\n delimiter: string = \"\",\n): Array<string> {\n const lines = new Array<string>();\n const gridWidths = new Array<number>();\n for (const gridRow of grid) {\n for (\n let gridColumnIndex = 0;\n gridColumnIndex < gridRow.length;\n gridColumnIndex++\n ) {\n const gridCell = gridRow[gridColumnIndex]!;\n const length = gridCellLength(gridCell);\n if (\n gridWidths[gridColumnIndex] === undefined ||\n length > gridWidths[gridColumnIndex]!\n ) {\n gridWidths[gridColumnIndex] = length;\n }\n }\n }\n for (const gridRow of grid) {\n const lineColumns = new Array<string>();\n for (\n let gridColumnIndex = 0;\n gridColumnIndex < gridRow.length;\n gridColumnIndex++\n ) {\n const gridCell = gridRow[gridColumnIndex]!;\n const parts = gridCell.map((text) =>\n typoPrintableString(typoSupport, text),\n );\n if (gridColumnIndex < gridRow.length - 1) {\n const length = gridCellLength(gridCell);\n const padding = \" \".repeat(gridWidths[gridColumnIndex]! - length);\n lineColumns.push(parts.join(\"\") + padding);\n } else {\n lineColumns.push(parts.join(\"\"));\n }\n }\n lines.push(lineColumns.join(delimiter));\n }\n return lines;\n}\n\nfunction gridCellLength(cell: GridCell): number {\n let length = 0;\n for (const text of cell) {\n length += text.value.length;\n }\n return length;\n}\n","import { ReaderTokenizer } from \"./Reader\";\nimport { Type } from \"./Type\";\n\nexport type Option<Value> = {\n generateUsage(): OptionUsage;\n prepareConsumer(readerTokenizer: ReaderTokenizer): OptionConsumer<Value>;\n};\n\nexport type OptionUsage = {\n description: string | undefined;\n long: Lowercase<string>; // TODO - better type for long option names ?\n short: string | undefined;\n label: Uppercase<string> | undefined;\n // TODO - default value for usage ? but it can be dynamic, so maybe not\n};\n\nexport type OptionConsumer<Value> = () => Value;\n\nexport function optionFlag(definition: {\n description?: string;\n long: Lowercase<string>;\n short?: string;\n aliases?: { longs?: Array<Lowercase<string>>; shorts?: Array<string> };\n default?: () => boolean;\n}): Option<boolean> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n long: definition.long,\n short: definition.short,\n label: undefined,\n };\n },\n prepareConsumer(readerTokenizer: ReaderTokenizer) {\n const key = definition.long;\n const longs = [definition.long];\n if (definition.aliases?.longs) {\n longs.push(...definition.aliases?.longs);\n }\n const shorts = definition.short ? [definition.short] : [];\n if (definition.aliases?.shorts) {\n shorts.push(...definition.aliases?.shorts);\n }\n readerTokenizer.registerFlag({ key, longs, shorts });\n return () => {\n const value = readerTokenizer.consumeFlag(key);\n if (value === undefined) {\n return definition.default ? definition.default() : false;\n }\n return value;\n };\n },\n };\n}\n\n// TODO - option with comma-separated values, e.g. --names=alice,bob,charlie\n\nexport function optionRepeatable<Value>(definition: {\n description?: string;\n type: Type<Value>;\n long: Lowercase<string>;\n short?: string;\n aliases?: { longs?: Array<Lowercase<string>>; shorts?: Array<string> };\n label?: Uppercase<string>;\n}): Option<Array<Value>> {\n return {\n generateUsage() {\n // TODO - showcase that it can be repeated ?\n return {\n description: definition.description,\n long: definition.long,\n short: definition.short,\n label:\n `<${definition.label ?? definition.type.label}>` as Uppercase<string>,\n };\n },\n prepareConsumer(readerTokenizer: ReaderTokenizer) {\n const key = definition.long;\n const longs = definition.long ? [definition.long] : [];\n if (definition.aliases?.longs) {\n longs.push(...definition.aliases?.longs);\n }\n const shorts = definition.short ? [definition.short] : [];\n if (definition.aliases?.shorts) {\n shorts.push(...definition.aliases?.shorts);\n }\n readerTokenizer.registerOption({ key, longs, shorts });\n return () => {\n return readerTokenizer.consumeOption(key).map(definition.type.decoder);\n };\n },\n };\n}\n\nexport function optionSingleValue<Value>(definition: {\n description?: string;\n type: Type<Value>;\n long: Lowercase<string>;\n short?: string;\n aliases?: { longs?: Array<Lowercase<string>>; shorts?: Array<string> };\n label?: Uppercase<string>;\n default: () => Value;\n}): Option<Value> {\n return {\n generateUsage() {\n return {\n description: definition.description,\n long: definition.long,\n short: definition.short,\n label:\n `<${definition.label ?? definition.type.label}>` as Uppercase<string>,\n };\n },\n prepareConsumer(readerTokenizer: ReaderTokenizer) {\n const key = definition.long;\n const longs = [definition.long];\n if (definition.aliases?.longs) {\n longs.push(...definition.aliases?.longs);\n }\n const shorts = definition.short ? [definition.short] : [];\n if (definition.aliases?.shorts) {\n shorts.push(...definition.aliases?.shorts);\n }\n readerTokenizer.registerOption({ key, longs, shorts });\n return () => {\n // TODO - smooth and beautiful error handling\n const values = readerTokenizer.consumeOption(definition.long);\n if (values.length > 1) {\n throw new Error(\n `Multiple values provided for option: ${definition.long}`,\n );\n }\n const firstValue = values[0];\n if (firstValue === undefined) {\n return definition.default();\n }\n return definition.type.decoder(firstValue);\n };\n },\n };\n}\n","export type ReaderPositionals = {\n consumePositional(): string | undefined;\n};\n\nexport class ReaderTokenizer {\n #parsedArgs: Array<string>;\n #parsedIndex: number;\n #parsedDouble: boolean;\n\n #flagKeyByShort: Map<string, string>;\n #flagKeyByLong: Map<string, string>;\n #flagInfoByKey: Map<string, {}>;\n #flagResultByKey: Map<string, boolean | null>;\n\n #optionKeyByShort: Map<string, string>;\n #optionKeyByLong: Map<string, string>;\n #optionInfoByKey: Map<string, {}>; // TODO - what dis for\n #optionResultByKey: Map<string, Array<string> | null>;\n\n constructor(args: Array<string>) {\n this.#parsedArgs = args;\n this.#parsedIndex = 0;\n this.#parsedDouble = false;\n\n // TODO - this seems like a good candidate for abstraction\n this.#flagKeyByShort = new Map();\n this.#flagKeyByLong = new Map();\n this.#flagInfoByKey = new Map();\n this.#flagResultByKey = new Map();\n\n this.#optionKeyByShort = new Map();\n this.#optionKeyByLong = new Map();\n this.#optionInfoByKey = new Map();\n this.#optionResultByKey = new Map();\n }\n\n registerFlag(definition: {\n key: string;\n shorts: Array<string>;\n longs: Array<string>;\n }) {\n this.#ensureUniqueKey(definition.key);\n this.#flagInfoByKey.set(definition.key, {});\n for (const short of definition.shorts) {\n this.#ensureUniqueName(short);\n this.#flagKeyByShort.set(short, definition.key);\n }\n for (const long of definition.longs) {\n this.#ensureUniqueName(long);\n this.#flagKeyByLong.set(long, definition.key);\n }\n }\n\n registerOption(definition: {\n key: string;\n shorts: Array<string>;\n longs: Array<string>;\n }) {\n this.#ensureUniqueKey(definition.key);\n this.#optionInfoByKey.set(definition.key, {});\n for (const short of definition.shorts) {\n this.#ensureUniqueName(short);\n this.#optionKeyByShort.set(short, definition.key);\n }\n for (const long of definition.longs) {\n this.#ensureUniqueName(long);\n this.#optionKeyByLong.set(long, definition.key);\n }\n }\n\n consumeFlag(key: string): boolean | undefined {\n const flagInfo = this.#flagInfoByKey.get(key);\n if (flagInfo === undefined) {\n throw new Error(`Option flag not registered: ${key}`);\n }\n const result = this.#flagResultByKey.get(key);\n if (result === undefined) {\n this.#flagResultByKey.set(key, null);\n return undefined;\n }\n if (result === null) {\n throw new Error(`Option flag already consumed: ${key}`);\n }\n this.#flagResultByKey.set(key, null);\n return result;\n }\n\n consumeOption(key: string): Array<string> {\n const optionInfo = this.#optionInfoByKey.get(key);\n if (optionInfo === undefined) {\n throw new Error(`Option values not registered: ${key}`);\n }\n const result = this.#optionResultByKey.get(key);\n if (result === undefined) {\n this.#optionResultByKey.set(key, null);\n return new Array<string>();\n }\n if (result === null) {\n throw new Error(`Option values already consumed: ${key}`);\n }\n this.#optionResultByKey.set(key, null);\n return result;\n }\n\n consumePositional(): string | undefined {\n while (true) {\n const arg = this.#consumeArg();\n if (arg === null) {\n return undefined;\n }\n const positional = this.#parseAsPositional(arg);\n if (positional !== null) {\n return positional;\n }\n }\n }\n\n #consumeArg(): string | null {\n const arg = this.#parsedArgs[this.#parsedIndex];\n if (arg === undefined) {\n return null;\n }\n this.#parsedIndex++;\n if (!this.#parsedDouble) {\n if (arg === \"--\") {\n this.#parsedDouble = true;\n return this.#consumeArg();\n }\n }\n return arg;\n }\n\n #consumeOptionValue(name: string) {\n const arg = this.#consumeArg();\n if (arg === null) {\n throw new Error(`Option ${name} requires a value`);\n }\n if (this.#parsedDouble) {\n throw new Error(`Option ${name} requires a value before --`);\n }\n // TODO - is that weird, could a valid value start with dash ?\n if (arg.startsWith(\"-\")) {\n throw new Error(`Option ${name} requires a value, got: ${arg}`);\n }\n return arg;\n }\n\n #parseAsPositional(arg: string): string | null {\n if (this.#parsedDouble) {\n return arg;\n }\n if (arg.startsWith(\"--\")) {\n const valueIndexStart = arg.indexOf(\"=\");\n if (valueIndexStart === -1) {\n this.#consumeOptionLong(arg.slice(2), null);\n } else {\n this.#consumeOptionLong(\n arg.slice(2, valueIndexStart),\n arg.slice(valueIndexStart + 1),\n );\n }\n return null;\n }\n if (arg.startsWith(\"-\")) {\n let shortIndexStart = 1;\n let shortIndexEnd = 2;\n while (shortIndexEnd <= arg.length) {\n const short = arg.slice(shortIndexStart, shortIndexEnd);\n const rest = arg.slice(shortIndexEnd);\n const result = this.#tryConsumeOptionShort(short, rest);\n if (result === true) {\n return null;\n }\n if (result === false) {\n shortIndexStart = shortIndexEnd;\n }\n shortIndexEnd++;\n }\n throw new Error(\n `Unknown short flags or options: ${arg.slice(shortIndexStart)}`,\n );\n }\n return arg;\n }\n\n #consumeOptionLong(long: string, direct: string | null): void {\n const flagKey = this.#flagKeyByLong.get(long);\n if (flagKey !== undefined) {\n if (direct !== null) {\n const value = asBoolean(direct);\n if (value !== undefined) {\n return this.#acknowledgeFlag(flagKey, value);\n }\n throw new Error(\n `Invalid parameter for long flag: ${flagKey}, value: ${direct}`,\n );\n }\n return this.#acknowledgeFlag(flagKey, true);\n }\n const optionKey = this.#optionKeyByLong.get(long);\n if (optionKey !== undefined) {\n if (direct !== null) {\n return this.#acknowledgeOption(optionKey, direct);\n }\n return this.#acknowledgeOption(optionKey, this.#consumeOptionValue(long));\n }\n throw new Error(`Unknown long flag or option: ${long}`);\n }\n\n #tryConsumeOptionShort(short: string, rest: string): boolean | null {\n const flagKey = this.#flagKeyByShort.get(short);\n if (flagKey !== undefined) {\n if (rest.startsWith(\"=\")) {\n const value = asBoolean(rest.slice(1));\n if (value !== undefined) {\n this.#acknowledgeFlag(flagKey, value);\n return true;\n }\n throw new Error(\n `Invalid parameter for short flag: ${short}, value: ${rest}`,\n );\n }\n this.#acknowledgeFlag(flagKey, true);\n return rest === \"\";\n }\n const optionKey = this.#optionKeyByShort.get(short);\n if (optionKey !== undefined) {\n if (rest === \"\") {\n this.#acknowledgeOption(optionKey, this.#consumeOptionValue(short));\n return true;\n }\n if (rest.startsWith(\"=\")) {\n this.#acknowledgeOption(optionKey, rest.slice(1));\n } else {\n this.#acknowledgeOption(optionKey, rest);\n }\n return true;\n }\n return null;\n }\n\n #acknowledgeFlag(key: string, value: boolean) {\n if (this.#flagResultByKey.has(key)) {\n throw new Error(`Flag already set: ${key}`);\n }\n this.#flagResultByKey.set(key, value);\n }\n\n #acknowledgeOption(key: string, value: string) {\n const values = this.#optionResultByKey.get(key) ?? new Array<string>();\n values.push(value);\n this.#optionResultByKey.set(key, values);\n }\n\n #ensureUniqueKey(key: string) {\n if (this.#flagInfoByKey.has(key)) {\n throw new Error(`Option already registered: ${key}`);\n }\n if (this.#optionInfoByKey.has(key)) {\n throw new Error(`Option already registered: ${key}`);\n }\n }\n\n #ensureUniqueName(nameShortOrLong: string) {\n // TODO - overall better error handling\n // TODO - short flag overlap might be annoying here\n if (this.#flagKeyByShort.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n if (this.#flagKeyByLong.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n if (this.#optionKeyByShort.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n if (this.#optionKeyByLong.has(nameShortOrLong)) {\n throw new Error(`Option already registered: ${nameShortOrLong}`);\n }\n }\n}\n\nfunction asBoolean(value: string): boolean | undefined {\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"t\" || lower === \"y\" || lower === \"yes\") {\n return true;\n }\n if (lower === \"false\" || lower === \"f\" || lower === \"n\" || lower === \"no\") {\n return false;\n }\n return undefined;\n}\n","import { CommandUsage } from \"./Command\";\nimport { GridCell, GridRow, gridToPrintableLines } from \"./Grid\";\nimport { TypoSupport, TypoText, typoPrintableString } from \"./Typo\";\n\nexport function usageToPrintableLines(params: {\n cliName: Lowercase<string>;\n commandUsage: CommandUsage;\n typoSupport: TypoSupport;\n}) {\n const { cliName, commandUsage, typoSupport } = params;\n\n const lines = new Array<string>();\n\n lines.push(\n typoPrintableString(typoSupport, textDescription(commandUsage.description)),\n );\n if (commandUsage.details) {\n for (const detailLine of commandUsage.details) {\n lines.push(typoPrintableString(typoSupport, textDetails(detailLine)));\n }\n }\n\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Usage:\")));\n const breadcrumbs = [\n \" \",\n typoPrintableString(typoSupport, textFixed(cliName)),\n ].concat(\n commandUsage.breadcrumbs.map((breadcrumb) => {\n if (\"argument\" in breadcrumb) {\n return typoPrintableString(typoSupport, textInput(breadcrumb.argument));\n }\n if (\"command\" in breadcrumb) {\n return typoPrintableString(typoSupport, textFixed(breadcrumb.command));\n }\n throw new Error(`Unknown breadcrumb: ${JSON.stringify(breadcrumb)}`);\n }),\n );\n lines.push(breadcrumbs.join(\" \"));\n\n if (commandUsage.arguments.length > 0) {\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Arguments:\")));\n const grid = new Array<GridRow>();\n for (const argumentUsage of commandUsage.arguments) {\n const gridRow = new Array<GridCell>();\n gridRow.push([textDelimiter()]);\n gridRow.push([textInput(argumentUsage.label)]);\n if (argumentUsage.description) {\n gridRow.push([textDelimiter()]);\n gridRow.push([textDescription(argumentUsage.description)]);\n }\n grid.push(gridRow);\n }\n lines.push(...gridToPrintableLines(grid, typoSupport));\n }\n\n if (commandUsage.subcommands.length > 0) {\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Subcommands:\")));\n const grid = new Array<GridRow>();\n for (const subcommand of commandUsage.subcommands) {\n const gridRow = new Array<GridCell>();\n gridRow.push([textDelimiter()]);\n gridRow.push([textFixed(subcommand.name)]);\n if (subcommand.description) {\n gridRow.push([textDelimiter()]);\n gridRow.push([textDescription(subcommand.description)]);\n }\n grid.push(gridRow);\n }\n lines.push(...gridToPrintableLines(grid, typoSupport));\n }\n\n if (commandUsage.options.length > 0) {\n lines.push(\"\");\n lines.push(typoPrintableString(typoSupport, textCategory(\"Options:\")));\n const grid = new Array<GridRow>();\n for (const optionUsage of commandUsage.options) {\n const gridRow = new Array<GridCell>();\n gridRow.push([textDelimiter()]);\n if (optionUsage.short) {\n gridRow.push([textFixed(`-${optionUsage.short}`), { value: \", \" }]);\n } else {\n gridRow.push([]);\n }\n if (optionUsage.label) {\n gridRow.push([\n textFixed(`--${optionUsage.long} `),\n textInput(optionUsage.label),\n ]);\n } else {\n gridRow.push([textFixed(`--${optionUsage.long}`)]);\n }\n if (optionUsage.description) {\n gridRow.push([textDelimiter()]);\n gridRow.push([textDescription(optionUsage.description)]);\n }\n grid.push(gridRow);\n }\n lines.push(...gridToPrintableLines(grid, typoSupport));\n }\n\n lines.push(\"\");\n return lines;\n}\n\nfunction textCategory(text: string): TypoText {\n return { value: text, color: \"brightGreen\", bold: true };\n}\n\nfunction textDescription(text: string): TypoText {\n return { value: text, bold: true };\n}\n\nfunction textDetails(text: string): TypoText {\n return { value: text, color: \"brightBlack\" };\n}\n\nfunction textFixed(text: string): TypoText {\n return { value: text, color: \"brightCyan\", bold: true };\n}\n\nfunction textInput(text: string): TypoText {\n return { value: text, color: \"brightBlue\" };\n}\n\nfunction textDelimiter(): TypoText {\n return { value: \" \" };\n}\n","import { Command, CommandInterpreter } from \"./Command\";\nimport { ReaderTokenizer } from \"./Reader\";\nimport { typoInferProcessSupport, TypoSupport } from \"./Typo\";\nimport { usageToPrintableLines } from \"./Usage\";\n\nexport async function runAndExit<Context>(\n cliName: Lowercase<string>,\n cliArgs: Array<string>,\n context: Context,\n command: Command<Context, void>,\n application?: {\n usageOnError?: boolean;\n usageOnHelp?: boolean;\n buildVersion?: string;\n useColors?: boolean;\n onMessage?: (message: string) => void;\n onError?: (error: any) => void;\n onExit?: (code: number) => never;\n },\n): Promise<never> {\n const readerTokenizer = new ReaderTokenizer(cliArgs);\n if (application?.buildVersion) {\n readerTokenizer.registerFlag({\n key: \"version\",\n shorts: [],\n longs: [\"version\"],\n });\n }\n if (application?.usageOnHelp ?? true) {\n readerTokenizer.registerFlag({\n key: \"help\",\n shorts: [],\n longs: [\"help\"],\n });\n }\n /*\n // TODO - handle completions ?\n readerTokenizer.registerFlag({\n key: \"completion\",\n shorts: [],\n longs: [\"completion\"],\n });\n */\n const commandInterpreter = command.buildInterpreter(readerTokenizer);\n if (application?.buildVersion) {\n if (readerTokenizer.consumeFlag(\"version\")) {\n (application?.onMessage ?? console.log)(\n [cliName, application.buildVersion].join(\" \"),\n );\n return (application?.onExit ?? process.exit)(0);\n }\n }\n if (application?.usageOnHelp ?? true) {\n if (readerTokenizer.consumeFlag(\"help\")) {\n logUsageMessage(cliName, commandInterpreter, application);\n return (application?.onExit ?? process.exit)(0);\n }\n }\n try {\n await commandInterpreter.execute(context);\n return (application?.onExit ?? process.exit)(0);\n } catch (error) {\n if (application?.usageOnError ?? true) {\n logUsageMessage(cliName, commandInterpreter, application);\n }\n (application?.onError ?? console.error)(error);\n return (application?.onExit ?? process.exit)(1);\n }\n}\n\nfunction logUsageMessage<Context, Result>(\n cliName: Lowercase<string>,\n commandInterpreter: CommandInterpreter<Context, Result>,\n application?: { useColors?: boolean; onMessage?: (message: string) => void },\n) {\n (application?.onMessage ?? console.log)(\n usageToPrintableLines({\n cliName,\n commandUsage: commandInterpreter.computeUsage(),\n typoSupport: chooseTypoSupport(application?.useColors),\n }).join(\"\\n\"),\n );\n}\n\nfunction chooseTypoSupport(useColors?: boolean): TypoSupport {\n if (useColors === undefined) {\n return typoInferProcessSupport();\n }\n return useColors ? \"tty\" : \"none\";\n}\n","export type Type<Value> = {\n label: Uppercase<string>; // TODO - is there a better way to enforce uppercase labels?\n decoder(value: string): Value;\n};\n\nexport const typeBoolean: Type<boolean> = {\n label: \"BOOLEAN\",\n decoder(value: string) {\n if (value === \"true\") {\n return true;\n }\n if (value === \"false\") {\n return false;\n }\n throw new Error(`Invalid boolean value: ${value}`);\n },\n};\n\nexport const typeDate: Type<Date> = {\n label: \"DATE\",\n decoder(value: string) {\n const timestamp = Date.parse(value);\n if (isNaN(timestamp)) {\n throw new Error(`Invalid date value: ${value}`);\n }\n return new Date(timestamp);\n },\n};\n\nexport const typeString: Type<string> = {\n label: \"STRING\",\n decoder(value: string) {\n return value;\n },\n};\n\nexport const typeNumber: Type<number> = {\n label: \"NUMBER\",\n decoder(value: string) {\n return Number(value);\n },\n};\n\nexport const typeBigInt: Type<bigint> = {\n label: \"BIGINT\",\n decoder(value: string) {\n return BigInt(value);\n },\n};\n\nexport function typeCommaTuple<\n const Elements extends Array<any>,\n>(elementTypes: {\n [K in keyof Elements]: Type<Elements[K]>;\n}): Type<Elements> {\n return {\n label: elementTypes\n .map((elementType) => elementType.label)\n .join(\",\") as Uppercase<string>,\n decoder(value: string) {\n const parts = value.split(\",\", elementTypes.length);\n if (parts.length !== elementTypes.length) {\n throw new Error(\n `Invalid tuple value: ${value}, expected ${elementTypes.length} parts`,\n );\n }\n return parts.map((part, index) =>\n elementTypes[index]!.decoder(part),\n ) as Elements;\n },\n };\n}\n\nexport function typeCommaList<Value>(\n elementType: Type<Value>,\n): Type<Array<Value>> {\n return {\n label:\n `${elementType.label}[,${elementType.label}...]` as Uppercase<string>,\n decoder(value: string) {\n return value.split(\",\").map(elementType.decoder);\n },\n };\n}\n"],"mappings":"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","names":["index_exports","__export","ReaderTokenizer","argumentOptional","argumentRequired","argumentVariadics","command","commandWithSubcommands","execution","gridToPrintableLines","optionFlag","optionRepeatable","optionSingleValue","runAndExit","typeBigInt","typeBoolean","typeCommaList","typeCommaTuple","typeDate","typeNumber","typeString","typoInferProcessSupport","typoPrintableString","usageToPrintableLines","__toCommonJS","argumentRequired","definition","readerPositionals","positional","argumentOptional","argumentVariadics","values","command","metadata","execution","readerTokenizer","computeUsage","executionUsage","argument","breadcrumbArgument","executionResolver","lastPositional","executionCallback","context","error","_context","commandWithSubcommands","subcommands","subcommandName","subcommandInput","subcommandInterpreter","subcommandUsage","breadcrumbCommand","payload","name","subcommand","value","execution","inputs","handler","optionsUsage","optionKey","optionInput","argumentsUsage","argumentInput","readerTokenizer","optionsConsumers","argumentsValues","optionsValues","context","typoPrintableString","typoSupport","typoText","colorStartCode","colorCodes","colorBoldCode","boldCode","resetCode","colorStartTag","colorEndTag","boldStartTag","boldEndTag","typoInferProcessSupport","gridToPrintableLines","grid","typoSupport","delimiter","lines","gridWidths","gridRow","gridColumnIndex","gridCell","length","gridCellLength","lineColumns","parts","text","typoPrintableString","padding","cell","optionFlag","definition","readerTokenizer","key","longs","shorts","value","optionRepeatable","optionSingleValue","values","firstValue","_parsedArgs","_parsedIndex","_parsedDouble","_flagKeyByShort","_flagKeyByLong","_flagInfoByKey","_flagResultByKey","_optionKeyByShort","_optionKeyByLong","_optionInfoByKey","_optionResultByKey","_ReaderTokenizer_instances","consumeArg_fn","consumeOptionValue_fn","parseAsPositional_fn","consumeOptionLong_fn","tryConsumeOptionShort_fn","acknowledgeFlag_fn","acknowledgeOption_fn","ensureUniqueKey_fn","ensureUniqueName_fn","ReaderTokenizer","args","__privateAdd","__privateSet","definition","__privateMethod","__privateGet","short","long","key","result","arg","positional","__privateWrapper","name","valueIndexStart","shortIndexStart","shortIndexEnd","rest","direct","flagKey","value","asBoolean","optionKey","values","nameShortOrLong","lower","usageToPrintableLines","params","cliName","commandUsage","typoSupport","lines","typoPrintableString","textDescription","detailLine","textDetails","textCategory","breadcrumbs","textFixed","breadcrumb","textInput","grid","argumentUsage","gridRow","textDelimiter","gridToPrintableLines","subcommand","optionUsage","text","runAndExit","cliName","cliArgs","context","command","application","readerTokenizer","ReaderTokenizer","commandInterpreter","logUsageMessage","error","usageToPrintableLines","chooseTypoSupport","useColors","typoInferProcessSupport","typeBoolean","value","typeDate","timestamp","typeString","typeNumber","typeBigInt","typeCommaTuple","elementTypes","elementType","parts","part","index","typeCommaList"]}
|
package/package.json
CHANGED
package/src/lib/Command.ts
CHANGED
|
@@ -5,12 +5,18 @@ import { ReaderTokenizer } from "./Reader";
|
|
|
5
5
|
|
|
6
6
|
export type Command<Context, Result> = {
|
|
7
7
|
getDescription(): string | undefined;
|
|
8
|
-
|
|
8
|
+
buildInterpreter(
|
|
9
9
|
readerTokenizer: ReaderTokenizer,
|
|
10
|
-
):
|
|
10
|
+
): CommandInterpreter<Context, Result>;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export type
|
|
13
|
+
export type CommandMetadata = {
|
|
14
|
+
description: string;
|
|
15
|
+
details?: Array<string>;
|
|
16
|
+
// TODO - printable examples ?
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type CommandInterpreter<Context, Result> = {
|
|
14
20
|
computeUsage(): CommandUsage;
|
|
15
21
|
execute(context: Context): Promise<Result>;
|
|
16
22
|
};
|
|
@@ -27,18 +33,14 @@ export type CommandUsage = {
|
|
|
27
33
|
export type CommandUsageBreadcrumb = { argument: string } | { command: string };
|
|
28
34
|
|
|
29
35
|
export function command<Context, Result>(
|
|
30
|
-
metadata:
|
|
31
|
-
description: string;
|
|
32
|
-
details?: Array<string>;
|
|
33
|
-
// TODO - examples ?
|
|
34
|
-
},
|
|
36
|
+
metadata: CommandMetadata,
|
|
35
37
|
execution: Execution<Context, Result>,
|
|
36
38
|
): Command<Context, Result> {
|
|
37
39
|
return {
|
|
38
40
|
getDescription() {
|
|
39
41
|
return metadata.description;
|
|
40
42
|
},
|
|
41
|
-
|
|
43
|
+
buildInterpreter(readerTokenizer: ReaderTokenizer) {
|
|
42
44
|
function computeUsage(): CommandUsage {
|
|
43
45
|
const executionUsage = execution.computeUsage();
|
|
44
46
|
return {
|
|
@@ -53,7 +55,7 @@ export function command<Context, Result>(
|
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
57
|
try {
|
|
56
|
-
const executionResolver = execution.
|
|
58
|
+
const executionResolver = execution.createResolver(readerTokenizer);
|
|
57
59
|
const lastPositional = readerTokenizer.consumePositional();
|
|
58
60
|
if (lastPositional !== undefined) {
|
|
59
61
|
throw Error(`Unprocessed positional: ${lastPositional}`);
|
|
@@ -78,10 +80,7 @@ export function command<Context, Result>(
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
export function commandWithSubcommands<Context, Payload, Result>(
|
|
81
|
-
metadata:
|
|
82
|
-
description: string;
|
|
83
|
-
details?: Array<string>;
|
|
84
|
-
},
|
|
83
|
+
metadata: CommandMetadata,
|
|
85
84
|
execution: Execution<Context, Payload>,
|
|
86
85
|
subcommands: { [subcommand: Lowercase<string>]: Command<Payload, Result> },
|
|
87
86
|
): Command<Context, Result> {
|
|
@@ -89,9 +88,9 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
89
88
|
getDescription() {
|
|
90
89
|
return metadata.description;
|
|
91
90
|
},
|
|
92
|
-
|
|
91
|
+
buildInterpreter(readerTokenizer: ReaderTokenizer) {
|
|
93
92
|
try {
|
|
94
|
-
const executionResolver = execution.
|
|
93
|
+
const executionResolver = execution.createResolver(readerTokenizer);
|
|
95
94
|
const subcommandName = readerTokenizer.consumePositional();
|
|
96
95
|
if (subcommandName === undefined) {
|
|
97
96
|
throw new Error("Expected a subcommand");
|
|
@@ -101,12 +100,13 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
101
100
|
if (subcommandInput === undefined) {
|
|
102
101
|
throw new Error(`Unknown subcommand: ${subcommandName}`);
|
|
103
102
|
}
|
|
104
|
-
const
|
|
103
|
+
const subcommandInterpreter =
|
|
104
|
+
subcommandInput.buildInterpreter(readerTokenizer);
|
|
105
105
|
const executionCallback = executionResolver();
|
|
106
106
|
return {
|
|
107
107
|
computeUsage() {
|
|
108
108
|
const executionUsage = execution.computeUsage();
|
|
109
|
-
const subcommandUsage =
|
|
109
|
+
const subcommandUsage = subcommandInterpreter.computeUsage();
|
|
110
110
|
return {
|
|
111
111
|
breadcrumbs: executionUsage.arguments
|
|
112
112
|
.map((argument) => breadcrumbArgument(argument.label))
|
|
@@ -123,7 +123,7 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
123
123
|
},
|
|
124
124
|
async execute(context: Context) {
|
|
125
125
|
const payload = await executionCallback(context);
|
|
126
|
-
return await
|
|
126
|
+
return await subcommandInterpreter.execute(payload);
|
|
127
127
|
},
|
|
128
128
|
};
|
|
129
129
|
} catch (error) {
|
package/src/lib/Execution.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { ReaderTokenizer } from "./Reader";
|
|
|
4
4
|
|
|
5
5
|
export type Execution<Context, Result> = {
|
|
6
6
|
computeUsage(): ExecutionUsage;
|
|
7
|
-
|
|
7
|
+
createResolver(
|
|
8
8
|
readerTokenizer: ReaderTokenizer,
|
|
9
9
|
): ExecutionResolver<Context, Result>;
|
|
10
10
|
};
|
|
@@ -54,7 +54,7 @@ export function execution<
|
|
|
54
54
|
}
|
|
55
55
|
return { options: optionsUsage, arguments: argumentsUsage };
|
|
56
56
|
},
|
|
57
|
-
|
|
57
|
+
createResolver(readerTokenizer: ReaderTokenizer) {
|
|
58
58
|
const optionsConsumers: any = {};
|
|
59
59
|
for (const optionKey in inputs.options) {
|
|
60
60
|
const optionInput = inputs.options[optionKey]!;
|
package/src/lib/Option.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type OptionUsage = {
|
|
|
11
11
|
long: Lowercase<string>; // TODO - better type for long option names ?
|
|
12
12
|
short: string | undefined;
|
|
13
13
|
label: Uppercase<string> | undefined;
|
|
14
|
+
// TODO - default value for usage ? but it can be dynamic, so maybe not
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
export type OptionConsumer<Value> = () => Value;
|
|
@@ -65,6 +66,7 @@ export function optionRepeatable<Value>(definition: {
|
|
|
65
66
|
}): Option<Array<Value>> {
|
|
66
67
|
return {
|
|
67
68
|
generateUsage() {
|
|
69
|
+
// TODO - showcase that it can be repeated ?
|
|
68
70
|
return {
|
|
69
71
|
description: definition.description,
|
|
70
72
|
long: definition.long,
|
package/src/lib/Reader.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type ReaderPositionals = {
|
|
|
3
3
|
};
|
|
4
4
|
|
|
5
5
|
export class ReaderTokenizer {
|
|
6
|
-
#
|
|
6
|
+
#parsedArgs: Array<string>;
|
|
7
7
|
#parsedIndex: number;
|
|
8
8
|
#parsedDouble: boolean;
|
|
9
9
|
|
|
@@ -17,8 +17,8 @@ export class ReaderTokenizer {
|
|
|
17
17
|
#optionInfoByKey: Map<string, {}>; // TODO - what dis for
|
|
18
18
|
#optionResultByKey: Map<string, Array<string> | null>;
|
|
19
19
|
|
|
20
|
-
constructor(
|
|
21
|
-
this.#
|
|
20
|
+
constructor(args: Array<string>) {
|
|
21
|
+
this.#parsedArgs = args;
|
|
22
22
|
this.#parsedIndex = 0;
|
|
23
23
|
this.#parsedDouble = false;
|
|
24
24
|
|
|
@@ -116,7 +116,7 @@ export class ReaderTokenizer {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
#consumeArg(): string | null {
|
|
119
|
-
const arg = this.#
|
|
119
|
+
const arg = this.#parsedArgs[this.#parsedIndex];
|
|
120
120
|
if (arg === undefined) {
|
|
121
121
|
return null;
|
|
122
122
|
}
|
package/src/lib/Run.ts
CHANGED
|
@@ -1,31 +1,38 @@
|
|
|
1
|
-
import { Command } from "./Command";
|
|
1
|
+
import { Command, CommandInterpreter } from "./Command";
|
|
2
2
|
import { ReaderTokenizer } from "./Reader";
|
|
3
|
-
import {
|
|
3
|
+
import { typoInferProcessSupport, TypoSupport } from "./Typo";
|
|
4
4
|
import { usageToPrintableLines } from "./Usage";
|
|
5
5
|
|
|
6
|
-
export async function
|
|
6
|
+
export async function runAndExit<Context>(
|
|
7
7
|
cliName: Lowercase<string>,
|
|
8
8
|
cliArgs: Array<string>,
|
|
9
9
|
context: Context,
|
|
10
|
-
command: Command<Context,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
command: Command<Context, void>,
|
|
11
|
+
application?: {
|
|
12
|
+
usageOnError?: boolean;
|
|
13
|
+
usageOnHelp?: boolean;
|
|
14
|
+
buildVersion?: string;
|
|
15
|
+
useColors?: boolean;
|
|
16
|
+
onMessage?: (message: string) => void;
|
|
17
|
+
onError?: (error: any) => void;
|
|
18
|
+
onExit?: (code: number) => never;
|
|
14
19
|
},
|
|
15
|
-
): Promise<
|
|
20
|
+
): Promise<never> {
|
|
16
21
|
const readerTokenizer = new ReaderTokenizer(cliArgs);
|
|
17
|
-
if (
|
|
22
|
+
if (application?.buildVersion) {
|
|
18
23
|
readerTokenizer.registerFlag({
|
|
19
24
|
key: "version",
|
|
20
25
|
shorts: [],
|
|
21
26
|
longs: ["version"],
|
|
22
27
|
});
|
|
23
28
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
if (application?.usageOnHelp ?? true) {
|
|
30
|
+
readerTokenizer.registerFlag({
|
|
31
|
+
key: "help",
|
|
32
|
+
shorts: [],
|
|
33
|
+
longs: ["help"],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
29
36
|
/*
|
|
30
37
|
// TODO - handle completions ?
|
|
31
38
|
readerTokenizer.registerFlag({
|
|
@@ -34,41 +41,50 @@ export async function runCommand<Context, Result>(
|
|
|
34
41
|
longs: ["completion"],
|
|
35
42
|
});
|
|
36
43
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
process.exit(0);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (readerTokenizer.consumeFlag("help")) {
|
|
46
|
-
console.log(
|
|
47
|
-
usageToPrintableLines({
|
|
48
|
-
cliName,
|
|
49
|
-
commandUsage: commandRunner.computeUsage(),
|
|
50
|
-
typoSupport: typoInferSupport(),
|
|
51
|
-
}).join("\n"),
|
|
44
|
+
const commandInterpreter = command.buildInterpreter(readerTokenizer);
|
|
45
|
+
if (application?.buildVersion) {
|
|
46
|
+
if (readerTokenizer.consumeFlag("version")) {
|
|
47
|
+
(application?.onMessage ?? console.log)(
|
|
48
|
+
[cliName, application.buildVersion].join(" "),
|
|
52
49
|
);
|
|
53
|
-
process.exit(0);
|
|
50
|
+
return (application?.onExit ?? process.exit)(0);
|
|
54
51
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
usageToPrintableLines({
|
|
61
|
-
cliName,
|
|
62
|
-
commandUsage: commandRunner.computeUsage(),
|
|
63
|
-
typoSupport: typoInferSupport(),
|
|
64
|
-
}).join("\n"),
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
console.error(error); // TODO - better, prettier errors
|
|
68
|
-
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
if (application?.usageOnHelp ?? true) {
|
|
54
|
+
if (readerTokenizer.consumeFlag("help")) {
|
|
55
|
+
logUsageMessage(cliName, commandInterpreter, application);
|
|
56
|
+
return (application?.onExit ?? process.exit)(0);
|
|
69
57
|
}
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await commandInterpreter.execute(context);
|
|
61
|
+
return (application?.onExit ?? process.exit)(0);
|
|
70
62
|
} catch (error) {
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
if (application?.usageOnError ?? true) {
|
|
64
|
+
logUsageMessage(cliName, commandInterpreter, application);
|
|
65
|
+
}
|
|
66
|
+
(application?.onError ?? console.error)(error);
|
|
67
|
+
return (application?.onExit ?? process.exit)(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function logUsageMessage<Context, Result>(
|
|
72
|
+
cliName: Lowercase<string>,
|
|
73
|
+
commandInterpreter: CommandInterpreter<Context, Result>,
|
|
74
|
+
application?: { useColors?: boolean; onMessage?: (message: string) => void },
|
|
75
|
+
) {
|
|
76
|
+
(application?.onMessage ?? console.log)(
|
|
77
|
+
usageToPrintableLines({
|
|
78
|
+
cliName,
|
|
79
|
+
commandUsage: commandInterpreter.computeUsage(),
|
|
80
|
+
typoSupport: chooseTypoSupport(application?.useColors),
|
|
81
|
+
}).join("\n"),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function chooseTypoSupport(useColors?: boolean): TypoSupport {
|
|
86
|
+
if (useColors === undefined) {
|
|
87
|
+
return typoInferProcessSupport();
|
|
73
88
|
}
|
|
89
|
+
return useColors ? "tty" : "none";
|
|
74
90
|
}
|
package/src/lib/Typo.ts
CHANGED
|
@@ -42,7 +42,10 @@ export function typoPrintableString(
|
|
|
42
42
|
throw new Error(`Unknown typo support: ${typoSupport}`);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export function
|
|
45
|
+
export function typoInferProcessSupport(): TypoSupport {
|
|
46
|
+
if (!process) {
|
|
47
|
+
return "none";
|
|
48
|
+
}
|
|
46
49
|
if (process.env) {
|
|
47
50
|
if (process.env["FORCE_COLOR"] === "0") {
|
|
48
51
|
return "none";
|
|
@@ -54,7 +57,7 @@ export function typoInferSupport(): TypoSupport {
|
|
|
54
57
|
return "none";
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
|
-
if (!process
|
|
60
|
+
if (!process.stdout || !process.stdout.isTTY) {
|
|
58
61
|
return "none";
|
|
59
62
|
}
|
|
60
63
|
return "tty";
|
|
@@ -3,19 +3,20 @@ import {
|
|
|
3
3
|
argumentOptional,
|
|
4
4
|
argumentRequired,
|
|
5
5
|
argumentVariadics,
|
|
6
|
+
Command,
|
|
6
7
|
command,
|
|
7
8
|
commandWithSubcommands,
|
|
8
9
|
execution,
|
|
9
10
|
optionFlag,
|
|
10
11
|
optionRepeatable,
|
|
11
12
|
optionSingleValue,
|
|
12
|
-
|
|
13
|
+
ReaderTokenizer,
|
|
13
14
|
typeCommaList,
|
|
14
15
|
typeNumber,
|
|
15
16
|
typeString,
|
|
16
17
|
} from "../src";
|
|
17
18
|
|
|
18
|
-
const
|
|
19
|
+
const rootCommand = commandWithSubcommands<string, any, any>(
|
|
19
20
|
{ description: "Root command description" },
|
|
20
21
|
execution(
|
|
21
22
|
{
|
|
@@ -73,11 +74,10 @@ const cmd = commandWithSubcommands<string, any, any>(
|
|
|
73
74
|
);
|
|
74
75
|
|
|
75
76
|
it("run", async () => {
|
|
76
|
-
const res1 = await
|
|
77
|
-
"script",
|
|
77
|
+
const res1 = await executeInterpreted(
|
|
78
78
|
["50", "51", "sub1", "final"],
|
|
79
79
|
"Run Context Input",
|
|
80
|
-
|
|
80
|
+
rootCommand,
|
|
81
81
|
);
|
|
82
82
|
expect(res1).toStrictEqual({
|
|
83
83
|
context: {
|
|
@@ -99,8 +99,7 @@ it("run", async () => {
|
|
|
99
99
|
at: "sub1",
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
const res2 = await
|
|
103
|
-
"script",
|
|
102
|
+
const res2 = await executeInterpreted(
|
|
104
103
|
[
|
|
105
104
|
"40",
|
|
106
105
|
"41",
|
|
@@ -116,7 +115,7 @@ it("run", async () => {
|
|
|
116
115
|
"--boolean-flag",
|
|
117
116
|
],
|
|
118
117
|
"Run Context Input",
|
|
119
|
-
|
|
118
|
+
rootCommand,
|
|
120
119
|
);
|
|
121
120
|
expect(res2).toStrictEqual({
|
|
122
121
|
context: {
|
|
@@ -138,3 +137,13 @@ it("run", async () => {
|
|
|
138
137
|
at: "sub2",
|
|
139
138
|
});
|
|
140
139
|
});
|
|
140
|
+
|
|
141
|
+
async function executeInterpreted<Context, Result>(
|
|
142
|
+
args: Array<string>,
|
|
143
|
+
context: Context,
|
|
144
|
+
command: Command<Context, Result>,
|
|
145
|
+
) {
|
|
146
|
+
const readerTokenizer = new ReaderTokenizer(args);
|
|
147
|
+
const commandInterpreter = command.buildInterpreter(readerTokenizer);
|
|
148
|
+
return await commandInterpreter.execute(context);
|
|
149
|
+
}
|
|
@@ -221,20 +221,21 @@ it("run", async () => {
|
|
|
221
221
|
});
|
|
222
222
|
|
|
223
223
|
async function getUsage<Context, Result>(
|
|
224
|
-
|
|
224
|
+
args: Array<string>,
|
|
225
225
|
command: Command<Context, Result>,
|
|
226
226
|
) {
|
|
227
|
-
const
|
|
227
|
+
const readerTokenizer = new ReaderTokenizer(args);
|
|
228
|
+
const commandInterpreter = command.buildInterpreter(readerTokenizer);
|
|
228
229
|
/*
|
|
229
230
|
try {
|
|
230
|
-
console.log(await
|
|
231
|
+
console.log(await commandInterpreter.execute({} as Context));
|
|
231
232
|
} catch (error) {
|
|
232
233
|
console.error("Error during execution:", error);
|
|
233
234
|
}
|
|
234
235
|
*/
|
|
235
236
|
return usageToPrintableLines({
|
|
236
237
|
cliName: "my-cli",
|
|
237
|
-
commandUsage:
|
|
238
|
+
commandUsage: commandInterpreter.computeUsage(),
|
|
238
239
|
typoSupport: "mock",
|
|
239
240
|
});
|
|
240
241
|
}
|