cleye 2.2.0 → 2.3.0

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/README.md CHANGED
@@ -263,8 +263,39 @@ argv.flags.someString // => "hello" (string)
263
263
  argv.flags.someNumber // => [1, 2] (number[])
264
264
  ```
265
265
 
266
+ #### Boolean flag negation
267
+ To support `--no-<flag>` syntax for boolean flags, enable `booleanFlagNegation`:
268
+
269
+ ```ts
270
+ cli({
271
+ flags: {
272
+ verbose: Boolean
273
+ },
274
+ booleanFlagNegation: true
275
+ })
276
+ ```
277
+
278
+ ```sh
279
+ $ my-script --no-verbose
280
+ # argv.flags.verbose => false
281
+ ```
282
+
283
+ Last-wins semantics apply between `--flag` and `--no-flag`:
284
+
285
+ ```sh
286
+ $ my-script --verbose --no-verbose
287
+ # argv.flags.verbose => false
288
+
289
+ $ my-script --no-verbose --verbose
290
+ # argv.flags.verbose => true
291
+ ```
292
+
293
+ Only applies to flags defined as `Boolean`. For non-boolean flags, `--no-<flag>` is treated as an unknown flag.
294
+
295
+ Commands inherit `booleanFlagNegation` from the parent CLI, but can override it.
296
+
266
297
  #### Inverting boolean flags
267
- To explicitly set a boolean flag to `false`, pass in the value using the `=` operator:
298
+ Alternatively, a boolean flag can be set to `false` by passing the value using the `=` operator:
268
299
 
269
300
  ```sh
270
301
  $ my-script --some-boolean=false
@@ -335,6 +366,35 @@ $ my-script --version
335
366
 
336
367
  The version is also shown in the help documentation. To opt out of handling `--version` while still showing the version in `--help`, pass the version into `help.version`.
337
368
 
369
+ #### Strict flags
370
+ To reject unknown flags with an error, enable `strictFlags`:
371
+
372
+ ```ts
373
+ cli({
374
+ flags: {
375
+ foo: Boolean,
376
+ bar: String
377
+ },
378
+ strictFlags: true
379
+ })
380
+ ```
381
+
382
+ ```sh
383
+ $ my-script --baz
384
+ Error: Unknown flag: --baz. (Did you mean --bar?)
385
+ ```
386
+
387
+ When enabled, the CLI will exit with an error if any unknown flags are passed. If a similar flag name exists (within 2 edits), it will suggest the closest match.
388
+
389
+ Commands inherit `strictFlags` from the parent CLI, but can override it:
390
+
391
+ ```ts
392
+ command({
393
+ name: 'build',
394
+ strictFlags: false // Disable for this command
395
+ })
396
+ ```
397
+
338
398
  ### Commands
339
399
  Commands allow organizing multiple "scripts" into a single script. An example of this is the [`npm install`](https://docs.npmjs.com/cli/install/) command, which is essentially an "install" script inside the "npm" script, adjacent to other commands like [`npm run`](https://docs.npmjs.com/cli/run-script/).
340
400
 
@@ -424,7 +484,7 @@ _Cleye_ uses all information provided to generate rich help documentation. The m
424
484
  #### Help customization
425
485
  The help document can be customized by passing a `render(nodes, renderers) => string` function to `help.render`.
426
486
 
427
- The `nodes` parameter contains an array of nodes that will be used to render the document. The `renderers` parameter is an object of functions used to render the document. Each node has properties `type` and `data`, where `type` corresponds to a property in `renderers` and `data` is passed into the render function.
487
+ The `nodes` parameter contains an array of nodes that will be used to render the document. The `renderers` parameter is an object of functions used to render the document. Each node has properties `type` and `data`, where `type` corresponds to a property in `renderers` and `data` is passed into the render function. Nodes also have an `id` property to identify sections: `name`, `description`, `usage`, `commands`, `flags`, `examples`, and `aliases`.
428
488
 
429
489
  Default renderers can be found in [`/src/render-help/renderers.ts`](/src/render-help/renderers.ts).
430
490
 
@@ -492,8 +552,8 @@ type ParsedArgv = {
492
552
  // Method to print version
493
553
  showVersion: () => void
494
554
 
495
- // Method to print help
496
- showHelp: (options: HelpOptions) => void
555
+ // Method to print help (pass HelpOptions to override content)
556
+ showHelp: (options?: HelpOptions) => void
497
557
  }
498
558
  ```
499
559
 
@@ -552,7 +612,7 @@ Type: `false` or an object with the following properties.
552
612
  | - | - | - |
553
613
  | `version` | `string` | Version shown in `--help`. |
554
614
  | `description` | `string` | Description shown in `--help`. |
555
- | `usage` | `string \| string[]` | Usage code examples shown in `--help`. |
615
+ | `usage` | `string \| string[] \| false` | Usage code examples shown in `--help`. Pass `false` to disable auto-generated usage. |
556
616
  | `examples` | `string \| string[]` | Example code snippets shown in `--help`. |
557
617
  | `render` | `(nodes, renderers) => string` | Function to customize the help document. |
558
618
 
@@ -577,11 +637,23 @@ type IgnoreArgvCallback = (
577
637
 
578
638
  A callback to ignore argv tokens from being parsed.
579
639
 
640
+ ##### strictFlags
641
+
642
+ Type: `boolean`
643
+
644
+ When enabled, prints an error and exits if unknown flags are passed. Suggests the closest matching flag name when possible. See [Strict flags](#strict-flags).
645
+
646
+ ##### booleanFlagNegation
647
+
648
+ Type: `boolean`
649
+
650
+ Enable `--no-<flag>` negation for boolean flags. See [Boolean flag negation](#boolean-flag-negation).
651
+
580
652
  #### callback(parsed)
581
653
 
582
- Type:
654
+ Type:
583
655
 
584
- Optional callback function that is called when the script is invoked without a command.
656
+ Optional callback function that is called when the script is invoked without a command. If the callback returns a Promise, the `cli()` return value will also be a Promise, allowing `await cli(...)` for async workflows.
585
657
 
586
658
  #### argvs
587
659
 
@@ -598,16 +670,30 @@ The raw parameters array to parse.
598
670
  | Property | Type | Description |
599
671
  | - | - | - |
600
672
  | `name` | `string` | Required name used to invoke the command. |
601
- | `alias` | `string \| string[]` | Aliases used to invoke the command. |
673
+ | `alias` | `string \| string[]` | Aliases used to invoke the command. Displayed in an "Aliases:" section in `--help`. |
602
674
  | `parameters` | `string[]` | Parameters for the command. Same as [`parameters`](#parameters-1). |
603
675
  | `flags` | `Flags` | Flags for the command. Same as [`flags`](#flags-1). |
604
676
  | `help` | `false \| HelpOptions` | Help options for the command. Same as [`help`](#help-1). |
677
+ | `ignoreArgv` | `IgnoreArgvCallback` | Same as [`ignoreArgv`](#ignoreargv). |
678
+ | `strictFlags` | `boolean` | Same as [`strictFlags`](#strictflags). Inherits from parent CLI if not specified. |
679
+ | `booleanFlagNegation` | `boolean` | Same as [`booleanFlagNegation`](#booleanflagnegation). Inherits from parent CLI if not specified. |
605
680
 
606
681
  #### callback(parsed)
607
682
 
608
- Type:
683
+ Type:
684
+
685
+ Optional callback function that is called when the command is invoked. If the callback returns a Promise, the `cli()` return value will also be a Promise.
686
+
687
+ ### Type exports
688
+ The following types are exported for use in TypeScript:
689
+
690
+ ```ts
691
+ import type { Flags, Renderers, TypeFlag } from 'cleye'
692
+ ```
609
693
 
610
- Optional callback function that is called when the command is invoked.
694
+ - `Flags` Type for the `flags` option object.
695
+ - `Renderers` — Class type for help document renderers, useful when customizing `help.render`.
696
+ - `TypeFlag` — Re-exported from [`type-flag`](https://github.com/privatenumber/type-flag) for portable type declarations.
611
697
 
612
698
  ## Sponsors
613
699
  <p align="center">
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
- "use strict";var M=Object.defineProperty;var o=(t,e)=>M(t,"name",{value:e,configurable:!0});var R=require("type-flag"),D=require("tty"),N=require("terminal-columns");const b=new Uint32Array(65536),U=o((t,e)=>{const r=t.length,a=e.length,n=1<<r-1;let s=-1,i=0,f=r,l=r;for(;l--;)b[t.charCodeAt(l)]|=1<<l;for(l=0;l<a;l++){let h=b[e.charCodeAt(l)];const u=h|i;h|=(h&s)+s^s,i|=~(h|s),s&=h,i&n&&f++,s&n&&f--,i=i<<1|1,s=s<<1|~(u|i),i&=u}for(l=r;l--;)b[t.charCodeAt(l)]=0;return f},"myers_32"),L=o((t,e)=>{const r=e.length,a=t.length,n=[],s=[],i=Math.ceil(r/32),f=Math.ceil(a/32);for(let c=0;c<i;c++)s[c]=-1,n[c]=0;let l=0;for(;l<f-1;l++){let c=0,g=-1;const m=l*32,y=Math.min(32,a)+m;for(let d=m;d<y;d++)b[t.charCodeAt(d)]|=1<<d;for(let d=0;d<r;d++){const v=b[e.charCodeAt(d)],w=s[d/32|0]>>>d&1,p=n[d/32|0]>>>d&1,q=v|c,F=((v|p)&g)+g^g|v|p;let x=c|~(F|g),j=g&F;x>>>31^w&&(s[d/32|0]^=1<<d),j>>>31^p&&(n[d/32|0]^=1<<d),x=x<<1|w,j=j<<1|p,g=j|~(q|x),c=x&q}for(let d=m;d<y;d++)b[t.charCodeAt(d)]=0}let h=0,u=-1;const $=l*32,C=Math.min(32,a-$)+$;for(let c=$;c<C;c++)b[t.charCodeAt(c)]|=1<<c;let E=a;for(let c=0;c<r;c++){const g=b[e.charCodeAt(c)],m=s[c/32|0]>>>c&1,y=n[c/32|0]>>>c&1,d=g|h,v=((g|y)&u)+u^u|g|y;let w=h|~(v|u),p=u&v;E+=w>>>a-1&1,E-=p>>>a-1&1,w>>>31^m&&(s[c/32|0]^=1<<c),p>>>31^y&&(n[c/32|0]^=1<<c),w=w<<1|m,p=p<<1|y,u=p|~(d|w),h=w&d}for(let c=$;c<C;c++)b[t.charCodeAt(c)]=0;return E},"myers_x"),k=o((t,e)=>{if(t.length<e.length){const r=e;e=t,t=r}return e.length===0?t.length:t.length<=32?U(t,e):L(t,e)},"distance"),T=o((t,e)=>{let r=1/0,a=0;for(let n=0;n<e.length;n++){const s=k(t,e[n]);s<r&&(r=s,a=n)}return e[a]},"closest"),H=o(t=>t.replaceAll(/[\W_]([a-z\d])?/gi,(e,r)=>r?r.toUpperCase():""),"camelCase"),V=o(t=>t.replaceAll(/\B([A-Z])/g,"-$1").toLowerCase(),"kebabCase"),J={"> 80":[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"auto"}],"> 40":[{width:"auto",paddingLeft:2,paddingRight:8,preprocess:o(t=>t.trim(),"preprocess")},{width:"100%",paddingLeft:2,paddingBottom:1}],"> 0":{stdoutColumns:1e3,columns:[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"content-width"}]}};function W(t){let e=!1;return{type:"table",data:{tableData:Object.keys(t).sort((n,s)=>n.localeCompare(s)).map(n=>{const s=t[n],i="alias"in s;return i&&(e=!0),{name:n,flag:s,flagFormatted:`--${V(n)}`,aliasesEnabled:e,aliasFormatted:i?`-${s.alias}`:void 0}}).map(n=>(n.aliasesEnabled=e,[{type:"flagName",data:n},{type:"flagDescription",data:n}])),tableBreakpoints:J}}}o(W,"renderFlags");const B=o(t=>!t||(t.version??(t.help?t.help.version:void 0)),"getVersion"),P=o(t=>{const e="parent"in t&&t.parent?.name;return(e?`${e} `:"")+t.name},"getName");function z(t){const e=[];t.name&&e.push(P(t));const r=B(t)??("parent"in t&&B(t.parent));if(r&&e.push(`v${r}`),e.length!==0)return{id:"name",type:"text",data:`${e.join(" ")}
1
+ "use strict";var D=Object.defineProperty;var o=(t,e)=>D(t,"name",{value:e,configurable:!0});var M=require("type-flag"),R=require("tty"),F=require("terminal-columns");const A=new Uint32Array(65536),U=o((t,e)=>{const r=t.length,a=e.length,n=1<<r-1;let s=-1,i=0,f=r,l=r;for(;l--;)A[t.charCodeAt(l)]|=1<<l;for(l=0;l<a;l++){let h=A[e.charCodeAt(l)];const u=h|i;h|=(h&s)+s^s,i|=~(h|s),s&=h,i&n&&f++,s&n&&f--,i=i<<1|1,s=s<<1|~(u|i),i&=u}for(l=r;l--;)A[t.charCodeAt(l)]=0;return f},"myers_32"),L=o((t,e)=>{const r=e.length,a=t.length,n=[],s=[],i=Math.ceil(r/32),f=Math.ceil(a/32);for(let c=0;c<i;c++)s[c]=-1,n[c]=0;let l=0;for(;l<f-1;l++){let c=0,p=-1;const m=l*32,y=Math.min(32,a)+m;for(let d=m;d<y;d++)A[t.charCodeAt(d)]|=1<<d;for(let d=0;d<r;d++){const v=A[e.charCodeAt(d)],w=s[d/32|0]>>>d&1,g=n[d/32|0]>>>d&1,N=v|c,q=((v|g)&p)+p^p|v|g;let x=c|~(q|p),j=p&q;x>>>31^w&&(s[d/32|0]^=1<<d),j>>>31^g&&(n[d/32|0]^=1<<d),x=x<<1|w,j=j<<1|g,p=j|~(N|x),c=x&N}for(let d=m;d<y;d++)A[t.charCodeAt(d)]=0}let h=0,u=-1;const $=l*32,C=Math.min(32,a-$)+$;for(let c=$;c<C;c++)A[t.charCodeAt(c)]|=1<<c;let E=a;for(let c=0;c<r;c++){const p=A[e.charCodeAt(c)],m=s[c/32|0]>>>c&1,y=n[c/32|0]>>>c&1,d=p|h,v=((p|y)&u)+u^u|p|y;let w=h|~(v|u),g=u&v;E+=w>>>a-1&1,E-=g>>>a-1&1,w>>>31^m&&(s[c/32|0]^=1<<c),g>>>31^y&&(n[c/32|0]^=1<<c),w=w<<1|m,g=g<<1|y,u=g|~(d|w),h=w&d}for(let c=$;c<C;c++)A[t.charCodeAt(c)]=0;return E},"myers_x"),k=o((t,e)=>{if(t.length<e.length){const r=e;e=t,t=r}return e.length===0?t.length:t.length<=32?U(t,e):L(t,e)},"distance"),T=o((t,e)=>{let r=1/0,a=0;for(let n=0;n<e.length;n++){const s=k(t,e[n]);s<r&&(r=s,a=n)}return e[a]},"closest"),H=o(t=>t.replaceAll(/[\W_]([a-z\d])?/gi,(e,r)=>r?r.toUpperCase():""),"camelCase"),V=o(t=>t.replaceAll(/\B([A-Z])/g,"-$1").toLowerCase(),"kebabCase"),J={"> 80":[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"auto"}],"> 40":[{width:"auto",paddingLeft:2,paddingRight:8,preprocess:o(t=>t.trim(),"preprocess")},{width:"100%",paddingLeft:2,paddingBottom:1}],"> 0":{stdoutColumns:1e3,columns:[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"content-width"}]}};function W(t){let e=!1;return{type:"table",data:{tableData:Object.keys(t).sort((n,s)=>n.localeCompare(s)).map(n=>{const s=t[n],i="alias"in s;return i&&(e=!0),{name:n,flag:s,flagFormatted:`--${V(n)}`,aliasesEnabled:e,aliasFormatted:i?`-${s.alias}`:void 0}}).map(n=>(n.aliasesEnabled=e,[{type:"flagName",data:n},{type:"flagDescription",data:n}])),tableBreakpoints:J}}}o(W,"renderFlags");const B=o(t=>!t||(t.version??(t.help?t.help.version:void 0)),"getVersion"),P=o(t=>{const e="parent"in t&&t.parent?.name;return(e?`${e} `:"")+t.name},"getName");function z(t){const e=[];t.name&&e.push(P(t));const r=B(t)??("parent"in t&&B(t.parent));if(r&&e.push(`v${r}`),e.length!==0)return{id:"name",type:"text",data:`${e.join(" ")}
2
2
  `}}o(z,"getNameAndVersion");function K(t){const{help:e}=t;if(!(!e||!e.description))return{id:"description",type:"text",data:`${e.description}
3
3
  `}}o(K,"getDescription");function Z(t){const e=t.help||{};if("usage"in e)return e.usage?{id:"usage",type:"section",data:{title:"Usage:",body:Array.isArray(e.usage)?e.usage.join(`
4
4
  `):e.usage}}:void 0;if(t.name){const r=[],a=[P(t)];if(t.flags&&Object.keys(t.flags).length>0&&a.push("[flags...]"),t.parameters&&t.parameters.length>0){const{parameters:n}=t,s=n.indexOf("--"),i=s!==-1&&n.slice(s+1).some(f=>f.startsWith("<"));a.push(n.map(f=>f!=="--"?f:i?"--":"[--]").join(" "))}if(a.length>1&&r.push(a.join(" ")),"commands"in t&&t.commands?.length&&r.push(`${t.name} <command>`),r.length>0)return{id:"usage",type:"section",data:{title:"Usage:",body:r.join(`
5
5
  `)}}}}o(Z,"getUsage");function G(t){return!("commands"in t)||!t.commands?.length?void 0:{id:"commands",type:"section",data:{title:"Commands:",body:{type:"table",data:{tableData:t.commands.map(a=>{const{help:n}=a.options;return[a.options.name,typeof n=="object"&&n.description||""]}),tableOptions:[{width:"content-width",paddingLeft:2,paddingRight:8}]}},indentBody:0}}}o(G,"getCommands");function Q(t){if(!(!t.flags||Object.keys(t.flags).length===0))return{id:"flags",type:"section",data:{title:"Flags:",body:W(t.flags),indentBody:0}}}o(Q,"getFlags");function X(t){const{help:e}=t;if(!e||!e.examples||e.examples.length===0)return;let{examples:r}=e;if(Array.isArray(r)&&(r=r.join(`
6
- `)),r)return{id:"examples",type:"section",data:{title:"Examples:",body:r}}}o(X,"getExamples");function Y(t){if(!("alias"in t)||!t.alias)return;const{alias:e}=t;return{id:"aliases",type:"section",data:{title:"Aliases:",body:Array.isArray(e)?e.join(", "):e}}}o(Y,"getAliases");const ee=o(t=>[z,K,Z,G,Q,X,Y].map(e=>e(t)).filter(Boolean),"generateHelp"),te=D.WriteStream.prototype.hasColors();class re{static{o(this,"Renderers")}text(e){return e}bold(e){return te?`\x1B[1m${e}\x1B[22m`:e.toLocaleUpperCase()}indentText({text:e,spaces:r}){return e.replaceAll(/^/gm," ".repeat(r))}heading(e){return this.bold(e)}section({title:e,body:r,indentBody:a=2}){return`${(e?`${this.heading(e)}
6
+ `)),r)return{id:"examples",type:"section",data:{title:"Examples:",body:r}}}o(X,"getExamples");function Y(t){if(!("alias"in t)||!t.alias)return;const{alias:e}=t;return{id:"aliases",type:"section",data:{title:"Aliases:",body:Array.isArray(e)?e.join(", "):e}}}o(Y,"getAliases");const ee=o(t=>[z,K,Z,G,Q,X,Y].map(e=>e(t)).filter(Boolean),"generateHelp"),te=R.WriteStream.prototype.hasColors();class re{static{o(this,"Renderers")}text(e){return e}bold(e){return te?`\x1B[1m${e}\x1B[22m`:e.toLocaleUpperCase()}indentText({text:e,spaces:r}){return e.replaceAll(/^/gm," ".repeat(r))}heading(e){return this.bold(e)}section({title:e,body:r,indentBody:a=2}){return`${(e?`${this.heading(e)}
7
7
  `:"")+(r?this.indentText({text:this.render(r),spaces:a}):"")}
8
- `}table({tableData:e,tableOptions:r,tableBreakpoints:a}){return N.terminalColumns(e.map(n=>n.map(s=>this.render(s))),a?N.breakpoints(a):r)}flagParameter(e){return e===Boolean?"":e===String?"<string>":e===Number?"<number>":Array.isArray(e)?this.flagParameter(e[0]):"<value>"}flagOperator(e){return" "}flagName(e){const{flag:r,flagFormatted:a,aliasesEnabled:n,aliasFormatted:s}=e;let i="";if(s?i+=`${s}, `:n&&(i+=" "),i+=a,"placeholder"in r&&typeof r.placeholder=="string")i+=`${this.flagOperator(e)}${r.placeholder}`;else{const f=this.flagParameter("type"in r?r.type:r);f&&(i+=`${this.flagOperator(e)}${f}`)}return i}flagDefault(e){return JSON.stringify(e)}flagDescription({flag:e}){let r="description"in e?e.description??"":"";if("default"in e){let{default:a}=e;typeof a=="function"&&(a=a()),a&&(r+=` (default: ${this.flagDefault(a)})`)}return r}render(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(r=>this.render(r)).join(`
9
- `);if("type"in e&&this[e.type]){const r=this[e.type];if(typeof r=="function")return r.call(this,e.data)}throw new Error(`Invalid node type: ${JSON.stringify(e)}`)}}const O=o(t=>t.length>0&&!t.includes(" "),"isValidScriptName"),{stringify:A}=JSON,ne=/[|\\{}()[\]^$+*?.]/;function S(t){const e=[];let r,a;for(const n of t){if(a)throw new Error(`Invalid parameter: Spread parameter ${A(a)} must be last`);const s=n[0],i=n.at(-1);let f;if(s==="<"&&i===">"&&(f=!0,r))throw new Error(`Invalid parameter: Required parameter ${A(n)} cannot come after optional parameter ${A(r)}`);if(s==="["&&i==="]"&&(f=!1,r=n),f===void 0)throw new Error(`Invalid parameter: ${A(n)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);let l=n.slice(1,-1);const h=l.slice(-3)==="...";h&&(a=n,l=l.slice(0,-3));const u=l.match(ne);if(u)throw new Error(`Invalid parameter: ${A(n)}. Invalid character found ${A(u[0])}`);e.push({name:l,required:f,spread:h})}return e}o(S,"parseParameters");function I(t,e,r,a){for(let n=0;n<e.length;n+=1){const{name:s,required:i,spread:f}=e[n],l=H(s);if(l in t)throw new Error(`Invalid parameter: ${A(s)} is used more than once.`);const h=f?r.slice(n):r[n];if(f&&(n=e.length),i&&(!h||f&&h.length===0))return console.error(`Error: Missing required parameter ${A(s)}
10
- `),a(),process.exit(1);t[l]=h}}o(I,"mapParametersToArguments");function ae(t){return t!==!1}o(ae,"helpEnabled");const se=o(t=>{const e=[];for(const[r,a]of Object.entries(t))if(e.push(r),a&&typeof a=="object"&&"alias"in a){const{alias:n}=a;typeof n=="string"&&n?e.push(n):Array.isArray(n)&&e.push(...n.filter(Boolean))}return e},"getKnownFlagNames"),ie=o((t,e)=>{if(t.length<3||e.length===0)return;const r=T(t,e);return k(t,r)<=2?r:void 0},"findClosestFlag"),oe=o((t,e)=>{const r=Object.keys(t);if(r.length!==0){for(const a of r){const n=ie(a,e),s=n?` (did you mean --${n}?)`:"";console.error(`Error: Unknown flag --${a}${s}`)}process.exit(1)}},"handleUnknownFlags");function _(t,e,r,a){const n={...e.flags},s=e.version&&!("version"in n);s&&(n.version={type:Boolean,description:"Show version"});const{help:i}=e,f=ae(i);f&&!("help"in n)&&(n.help={type:Boolean,alias:"h",description:"Show help"});const l=R.typeFlag(n,a,{ignore:e.ignoreArgv}),h=o(()=>{console.log(e.version)},"showVersion");if(s&&l.flags.version===!0)return h(),process.exit(0);const u=new re,$=f&&i?.render?i.render:m=>u.render(m),C=o(m=>{const y=ee({...e,...m?{help:m}:{},flags:n});console.log($(y,u))},"showHelp");if(f&&l.flags.help===!0)return C(),process.exit(0);if((e.strictFlags??e.parent?.strictFlags)&&oe(l.unknownFlags,se(n)),e.parameters){let{parameters:m}=e,y=l._;const d=m.indexOf("--"),v=m.slice(d+1),w=Object.create(null);let p=[];d>-1&&v.length>0&&(m=m.slice(0,d),p=l._["--"],y=y.slice(0,-p.length||void 0)),I(w,S(m),y,C),d>-1&&v.length>0&&I(w,S(v),p,C),Object.assign(l._,w)}const c={...l,showVersion:h,showHelp:C},g={command:t,...c};if(typeof r=="function"){const m=r(c);if(m&&"then"in m)return Object.assign(Promise.resolve(m),g)}return g}o(_,"cliBase");function le(t,e){const r=new Map;for(const a of e){const n=[a.options.name],{alias:s}=a.options;s&&(Array.isArray(s)?n.push(...s):n.push(s));for(const i of n){if(r.has(i))throw new Error(`Duplicate command name found: ${A(i)}`);r.set(i,a)}}return r.get(t)}o(le,"getCommand");function ce(t,e,r=process.argv.slice(2)){if(!t)throw new Error("Options is required");if("name"in t&&(!t.name||!O(t.name)))throw new Error(`Invalid script name: ${A(t.name)}`);const a=r[0];if(t.commands&&a&&O(a)){const n=le(a,t.commands);if(n)return _(n.options.name,{...n.options,parent:t},n.callback,r.slice(1))}return _(void 0,t,e,r)}o(ce,"cli");function de(t,e){if(!t)throw new Error("Command options are required");const{name:r}=t;if(r===void 0)throw new Error("Command name is required");if(!O(r))throw new Error(`Invalid command name ${JSON.stringify(r)}. Command names must be one word.`);return{options:t,callback:e}}o(de,"command"),exports.cli=ce,exports.command=de;
8
+ `}table({tableData:e,tableOptions:r,tableBreakpoints:a}){return F.terminalColumns(e.map(n=>n.map(s=>this.render(s))),a?F.breakpoints(a):r)}flagParameter(e){return e===Boolean?"":e===String?"<string>":e===Number?"<number>":Array.isArray(e)?this.flagParameter(e[0]):"<value>"}flagOperator(e){return" "}flagName(e){const{flag:r,flagFormatted:a,aliasesEnabled:n,aliasFormatted:s}=e;let i="";if(s?i+=`${s}, `:n&&(i+=" "),i+=a,"placeholder"in r&&typeof r.placeholder=="string")i+=`${this.flagOperator(e)}${r.placeholder}`;else{const f=this.flagParameter("type"in r?r.type:r);f&&(i+=`${this.flagOperator(e)}${f}`)}return i}flagDefault(e){return JSON.stringify(e)}flagDescription({flag:e}){let r="description"in e?e.description??"":"";if("default"in e){let{default:a}=e;typeof a=="function"&&(a=a()),a&&(r+=` (default: ${this.flagDefault(a)})`)}return r}render(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(r=>this.render(r)).join(`
9
+ `);if("type"in e&&this[e.type]){const r=this[e.type];if(typeof r=="function")return r.call(this,e.data)}throw new Error(`Invalid node type: ${JSON.stringify(e)}`)}}const O=o(t=>t.length>0&&!t.includes(" "),"isValidScriptName"),{stringify:b}=JSON,ne=/[|\\{}()[\]^$+*?.]/;function S(t){const e=[];let r,a;for(const n of t){if(a)throw new Error(`Invalid parameter: Spread parameter ${b(a)} must be last`);const s=n[0],i=n.at(-1);let f;if(s==="<"&&i===">"&&(f=!0,r))throw new Error(`Invalid parameter: Required parameter ${b(n)} cannot come after optional parameter ${b(r)}`);if(s==="["&&i==="]"&&(f=!1,r=n),f===void 0)throw new Error(`Invalid parameter: ${b(n)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);let l=n.slice(1,-1);const h=l.slice(-3)==="...";h&&(a=n,l=l.slice(0,-3));const u=l.match(ne);if(u)throw new Error(`Invalid parameter: ${b(n)}. Invalid character found ${b(u[0])}`);e.push({name:l,required:f,spread:h})}return e}o(S,"parseParameters");function I(t,e,r,a){for(let n=0;n<e.length;n+=1){const{name:s,required:i,spread:f}=e[n],l=H(s);if(l in t)throw new Error(`Invalid parameter: ${b(s)} is used more than once.`);const h=f?r.slice(n):r[n];if(f&&(n=e.length),i&&(!h||f&&h.length===0))return console.error(`Error: Missing required parameter ${b(s)}
10
+ `),a(),process.exit(1);t[l]=h}}o(I,"mapParametersToArguments");function ae(t){return t!==!1}o(ae,"helpEnabled");const se=o(t=>{const e=[];for(const[r,a]of Object.entries(t))if(e.push(r),a&&typeof a=="object"&&"alias"in a){const{alias:n}=a;typeof n=="string"&&n?e.push(n):Array.isArray(n)&&e.push(...n.filter(Boolean))}return e},"getKnownFlagNames"),ie=o((t,e)=>{if(t.length<3||e.length===0)return;const r=T(t,e);return k(t,r)<=2?r:void 0},"findClosestFlag"),oe=o((t,e)=>{const r=Object.keys(t);if(r.length!==0){for(const a of r){const n=ie(a,e),s=n?` (Did you mean --${n}?)`:"";console.error(`Error: Unknown flag: --${a}.${s}`)}process.exit(1)}},"handleUnknownFlags");function _(t,e,r,a){const n={...e.flags},s=e.version&&!("version"in n);s&&(n.version={type:Boolean,description:"Show version"});const{help:i}=e,f=ae(i);f&&!("help"in n)&&(n.help={type:Boolean,alias:"h",description:"Show help"});const l=M.typeFlag(n,a,{ignore:e.ignoreArgv,booleanNegation:e.booleanFlagNegation??e.parent?.booleanFlagNegation}),h=o(()=>{console.log(e.version)},"showVersion");if(s&&l.flags.version===!0)return h(),process.exit(0);const u=new re,$=f&&i?.render?i.render:m=>u.render(m),C=o(m=>{const y=ee({...e,...m?{help:m}:{},flags:n});console.log($(y,u))},"showHelp");if(f&&l.flags.help===!0)return C(),process.exit(0);if((e.strictFlags??e.parent?.strictFlags)&&oe(l.unknownFlags,se(n)),e.parameters){let{parameters:m}=e,y=l._;const d=m.indexOf("--"),v=m.slice(d+1),w=Object.create(null);let g=[];d>-1&&v.length>0&&(m=m.slice(0,d),g=l._["--"],y=y.slice(0,-g.length||void 0)),I(w,S(m),y,C),d>-1&&v.length>0&&I(w,S(v),g,C),Object.assign(l._,w)}const c={...l,showVersion:h,showHelp:C},p={command:t,...c};if(typeof r=="function"){const m=r(c);if(m&&"then"in m)return Object.assign(Promise.resolve(m),p)}return p}o(_,"cliBase");function le(t,e){const r=new Map;for(const a of e){const n=[a.options.name],{alias:s}=a.options;s&&(Array.isArray(s)?n.push(...s):n.push(s));for(const i of n){if(r.has(i))throw new Error(`Duplicate command name found: ${b(i)}`);r.set(i,a)}}return r.get(t)}o(le,"getCommand");function ce(t,e,r=process.argv.slice(2)){if(!t)throw new Error("Options is required");if("name"in t&&(!t.name||!O(t.name)))throw new Error(`Invalid script name: ${b(t.name)}`);const a=r[0];if(t.commands&&a&&O(a)){const n=le(a,t.commands);if(n)return _(n.options.name,{...n.options,parent:t},n.callback,r.slice(1))}return _(void 0,t,e,r)}o(ce,"cli");function de(t,e){if(!t)throw new Error("Command options are required");const{name:r}=t;if(r===void 0)throw new Error("Command name is required");if(!O(r))throw new Error(`Invalid command name ${JSON.stringify(r)}. Command names must be one word.`);return{options:t,callback:e}}o(de,"command"),exports.cli=ce,exports.command=de;
package/dist/index.d.cts CHANGED
@@ -38,6 +38,14 @@ type CommandOptions<Parameters = string[]> = {
38
38
  * Inherits from parent CLI if not specified.
39
39
  */
40
40
  strictFlags?: boolean;
41
+ /**
42
+ * Enable `--no-<flag>` negation for boolean flags.
43
+ *
44
+ * When enabled, `--no-verbose` is equivalent to `--verbose=false`.
45
+ * Only applies to flags defined as `Boolean`.
46
+ * Inherits from parent CLI if not specified.
47
+ */
48
+ booleanFlagNegation?: boolean;
41
49
  };
42
50
  declare function command<Options extends CommandOptions<[...Parameters]>, Parameters extends string[]>(options: Readonly<Options> & CommandOptions<[...Parameters]>, callback?: CallbackFunction<ParseArgv<Options, Parameters>>): Command<Options, ParseArgv<Options, Parameters, Options['name']>>;
43
51
  type Command<Options extends CommandOptions = CommandOptions, ParsedType = any> = {
@@ -189,6 +197,13 @@ type CliOptions<Commands = Command[], Parameters extends string[] = string[]> =
189
197
  * Suggests the closest matching flag name when possible.
190
198
  */
191
199
  strictFlags?: boolean;
200
+ /**
201
+ * Enable `--no-<flag>` negation for boolean flags.
202
+ *
203
+ * When enabled, `--no-verbose` is equivalent to `--verbose=false`.
204
+ * Only applies to flags defined as `Boolean`.
205
+ */
206
+ booleanFlagNegation?: boolean;
192
207
  };
193
208
  type AlphabetLowercase = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
194
209
  type Numeric = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
package/dist/index.d.mts CHANGED
@@ -38,6 +38,14 @@ type CommandOptions<Parameters = string[]> = {
38
38
  * Inherits from parent CLI if not specified.
39
39
  */
40
40
  strictFlags?: boolean;
41
+ /**
42
+ * Enable `--no-<flag>` negation for boolean flags.
43
+ *
44
+ * When enabled, `--no-verbose` is equivalent to `--verbose=false`.
45
+ * Only applies to flags defined as `Boolean`.
46
+ * Inherits from parent CLI if not specified.
47
+ */
48
+ booleanFlagNegation?: boolean;
41
49
  };
42
50
  declare function command<Options extends CommandOptions<[...Parameters]>, Parameters extends string[]>(options: Readonly<Options> & CommandOptions<[...Parameters]>, callback?: CallbackFunction<ParseArgv<Options, Parameters>>): Command<Options, ParseArgv<Options, Parameters, Options['name']>>;
43
51
  type Command<Options extends CommandOptions = CommandOptions, ParsedType = any> = {
@@ -189,6 +197,13 @@ type CliOptions<Commands = Command[], Parameters extends string[] = string[]> =
189
197
  * Suggests the closest matching flag name when possible.
190
198
  */
191
199
  strictFlags?: boolean;
200
+ /**
201
+ * Enable `--no-<flag>` negation for boolean flags.
202
+ *
203
+ * When enabled, `--no-verbose` is equivalent to `--verbose=false`.
204
+ * Only applies to flags defined as `Boolean`.
205
+ */
206
+ booleanFlagNegation?: boolean;
192
207
  };
193
208
  type AlphabetLowercase = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
194
209
  type Numeric = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- var _=Object.defineProperty;var o=(t,e)=>_(t,"name",{value:e,configurable:!0});import{typeFlag as M}from"type-flag";import R from"tty";import{terminalColumns as D,breakpoints as U}from"terminal-columns";const b=new Uint32Array(65536),L=o((t,e)=>{const r=t.length,a=e.length,n=1<<r-1;let s=-1,i=0,d=r,l=r;for(;l--;)b[t.charCodeAt(l)]|=1<<l;for(l=0;l<a;l++){let h=b[e.charCodeAt(l)];const u=h|i;h|=(h&s)+s^s,i|=~(h|s),s&=h,i&n&&d++,s&n&&d--,i=i<<1|1,s=s<<1|~(u|i),i&=u}for(l=r;l--;)b[t.charCodeAt(l)]=0;return d},"myers_32"),T=o((t,e)=>{const r=e.length,a=t.length,n=[],s=[],i=Math.ceil(r/32),d=Math.ceil(a/32);for(let c=0;c<i;c++)s[c]=-1,n[c]=0;let l=0;for(;l<d-1;l++){let c=0,g=-1;const m=l*32,y=Math.min(32,a)+m;for(let f=m;f<y;f++)b[t.charCodeAt(f)]|=1<<f;for(let f=0;f<r;f++){const v=b[e.charCodeAt(f)],w=s[f/32|0]>>>f&1,p=n[f/32|0]>>>f&1,N=v|c,q=((v|p)&g)+g^g|v|p;let x=c|~(q|g),j=g&q;x>>>31^w&&(s[f/32|0]^=1<<f),j>>>31^p&&(n[f/32|0]^=1<<f),x=x<<1|w,j=j<<1|p,g=j|~(N|x),c=x&N}for(let f=m;f<y;f++)b[t.charCodeAt(f)]=0}let h=0,u=-1;const C=l*32,$=Math.min(32,a-C)+C;for(let c=C;c<$;c++)b[t.charCodeAt(c)]|=1<<c;let E=a;for(let c=0;c<r;c++){const g=b[e.charCodeAt(c)],m=s[c/32|0]>>>c&1,y=n[c/32|0]>>>c&1,f=g|h,v=((g|y)&u)+u^u|g|y;let w=h|~(v|u),p=u&v;E+=w>>>a-1&1,E-=p>>>a-1&1,w>>>31^m&&(s[c/32|0]^=1<<c),p>>>31^y&&(n[c/32|0]^=1<<c),w=w<<1|m,p=p<<1|y,u=p|~(f|w),h=w&f}for(let c=C;c<$;c++)b[t.charCodeAt(c)]=0;return E},"myers_x"),F=o((t,e)=>{if(t.length<e.length){const r=e;e=t,t=r}return e.length===0?t.length:t.length<=32?L(t,e):T(t,e)},"distance"),H=o((t,e)=>{let r=1/0,a=0;for(let n=0;n<e.length;n++){const s=F(t,e[n]);s<r&&(r=s,a=n)}return e[a]},"closest"),V=o(t=>t.replaceAll(/[\W_]([a-z\d])?/gi,(e,r)=>r?r.toUpperCase():""),"camelCase"),J=o(t=>t.replaceAll(/\B([A-Z])/g,"-$1").toLowerCase(),"kebabCase"),W={"> 80":[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"auto"}],"> 40":[{width:"auto",paddingLeft:2,paddingRight:8,preprocess:o(t=>t.trim(),"preprocess")},{width:"100%",paddingLeft:2,paddingBottom:1}],"> 0":{stdoutColumns:1e3,columns:[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"content-width"}]}};function z(t){let e=!1;return{type:"table",data:{tableData:Object.keys(t).sort((n,s)=>n.localeCompare(s)).map(n=>{const s=t[n],i="alias"in s;return i&&(e=!0),{name:n,flag:s,flagFormatted:`--${J(n)}`,aliasesEnabled:e,aliasFormatted:i?`-${s.alias}`:void 0}}).map(n=>(n.aliasesEnabled=e,[{type:"flagName",data:n},{type:"flagDescription",data:n}])),tableBreakpoints:W}}}o(z,"renderFlags");const k=o(t=>!t||(t.version??(t.help?t.help.version:void 0)),"getVersion"),B=o(t=>{const e="parent"in t&&t.parent?.name;return(e?`${e} `:"")+t.name},"getName");function K(t){const e=[];t.name&&e.push(B(t));const r=k(t)??("parent"in t&&k(t.parent));if(r&&e.push(`v${r}`),e.length!==0)return{id:"name",type:"text",data:`${e.join(" ")}
1
+ var _=Object.defineProperty;var o=(t,e)=>_(t,"name",{value:e,configurable:!0});import{typeFlag as D}from"type-flag";import M from"tty";import{terminalColumns as R,breakpoints as U}from"terminal-columns";const A=new Uint32Array(65536),L=o((t,e)=>{const r=t.length,a=e.length,n=1<<r-1;let s=-1,i=0,d=r,l=r;for(;l--;)A[t.charCodeAt(l)]|=1<<l;for(l=0;l<a;l++){let h=A[e.charCodeAt(l)];const u=h|i;h|=(h&s)+s^s,i|=~(h|s),s&=h,i&n&&d++,s&n&&d--,i=i<<1|1,s=s<<1|~(u|i),i&=u}for(l=r;l--;)A[t.charCodeAt(l)]=0;return d},"myers_32"),T=o((t,e)=>{const r=e.length,a=t.length,n=[],s=[],i=Math.ceil(r/32),d=Math.ceil(a/32);for(let c=0;c<i;c++)s[c]=-1,n[c]=0;let l=0;for(;l<d-1;l++){let c=0,p=-1;const m=l*32,y=Math.min(32,a)+m;for(let f=m;f<y;f++)A[t.charCodeAt(f)]|=1<<f;for(let f=0;f<r;f++){const v=A[e.charCodeAt(f)],w=s[f/32|0]>>>f&1,g=n[f/32|0]>>>f&1,N=v|c,F=((v|g)&p)+p^p|v|g;let x=c|~(F|p),j=p&F;x>>>31^w&&(s[f/32|0]^=1<<f),j>>>31^g&&(n[f/32|0]^=1<<f),x=x<<1|w,j=j<<1|g,p=j|~(N|x),c=x&N}for(let f=m;f<y;f++)A[t.charCodeAt(f)]=0}let h=0,u=-1;const C=l*32,$=Math.min(32,a-C)+C;for(let c=C;c<$;c++)A[t.charCodeAt(c)]|=1<<c;let E=a;for(let c=0;c<r;c++){const p=A[e.charCodeAt(c)],m=s[c/32|0]>>>c&1,y=n[c/32|0]>>>c&1,f=p|h,v=((p|y)&u)+u^u|p|y;let w=h|~(v|u),g=u&v;E+=w>>>a-1&1,E-=g>>>a-1&1,w>>>31^m&&(s[c/32|0]^=1<<c),g>>>31^y&&(n[c/32|0]^=1<<c),w=w<<1|m,g=g<<1|y,u=g|~(f|w),h=w&f}for(let c=C;c<$;c++)A[t.charCodeAt(c)]=0;return E},"myers_x"),q=o((t,e)=>{if(t.length<e.length){const r=e;e=t,t=r}return e.length===0?t.length:t.length<=32?L(t,e):T(t,e)},"distance"),H=o((t,e)=>{let r=1/0,a=0;for(let n=0;n<e.length;n++){const s=q(t,e[n]);s<r&&(r=s,a=n)}return e[a]},"closest"),V=o(t=>t.replaceAll(/[\W_]([a-z\d])?/gi,(e,r)=>r?r.toUpperCase():""),"camelCase"),J=o(t=>t.replaceAll(/\B([A-Z])/g,"-$1").toLowerCase(),"kebabCase"),W={"> 80":[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"auto"}],"> 40":[{width:"auto",paddingLeft:2,paddingRight:8,preprocess:o(t=>t.trim(),"preprocess")},{width:"100%",paddingLeft:2,paddingBottom:1}],"> 0":{stdoutColumns:1e3,columns:[{width:"content-width",paddingLeft:2,paddingRight:8},{width:"content-width"}]}};function z(t){let e=!1;return{type:"table",data:{tableData:Object.keys(t).sort((n,s)=>n.localeCompare(s)).map(n=>{const s=t[n],i="alias"in s;return i&&(e=!0),{name:n,flag:s,flagFormatted:`--${J(n)}`,aliasesEnabled:e,aliasFormatted:i?`-${s.alias}`:void 0}}).map(n=>(n.aliasesEnabled=e,[{type:"flagName",data:n},{type:"flagDescription",data:n}])),tableBreakpoints:W}}}o(z,"renderFlags");const k=o(t=>!t||(t.version??(t.help?t.help.version:void 0)),"getVersion"),B=o(t=>{const e="parent"in t&&t.parent?.name;return(e?`${e} `:"")+t.name},"getName");function K(t){const e=[];t.name&&e.push(B(t));const r=k(t)??("parent"in t&&k(t.parent));if(r&&e.push(`v${r}`),e.length!==0)return{id:"name",type:"text",data:`${e.join(" ")}
2
2
  `}}o(K,"getNameAndVersion");function Z(t){const{help:e}=t;if(!(!e||!e.description))return{id:"description",type:"text",data:`${e.description}
3
3
  `}}o(Z,"getDescription");function G(t){const e=t.help||{};if("usage"in e)return e.usage?{id:"usage",type:"section",data:{title:"Usage:",body:Array.isArray(e.usage)?e.usage.join(`
4
4
  `):e.usage}}:void 0;if(t.name){const r=[],a=[B(t)];if(t.flags&&Object.keys(t.flags).length>0&&a.push("[flags...]"),t.parameters&&t.parameters.length>0){const{parameters:n}=t,s=n.indexOf("--"),i=s!==-1&&n.slice(s+1).some(d=>d.startsWith("<"));a.push(n.map(d=>d!=="--"?d:i?"--":"[--]").join(" "))}if(a.length>1&&r.push(a.join(" ")),"commands"in t&&t.commands?.length&&r.push(`${t.name} <command>`),r.length>0)return{id:"usage",type:"section",data:{title:"Usage:",body:r.join(`
5
5
  `)}}}}o(G,"getUsage");function Q(t){return!("commands"in t)||!t.commands?.length?void 0:{id:"commands",type:"section",data:{title:"Commands:",body:{type:"table",data:{tableData:t.commands.map(a=>{const{help:n}=a.options;return[a.options.name,typeof n=="object"&&n.description||""]}),tableOptions:[{width:"content-width",paddingLeft:2,paddingRight:8}]}},indentBody:0}}}o(Q,"getCommands");function X(t){if(!(!t.flags||Object.keys(t.flags).length===0))return{id:"flags",type:"section",data:{title:"Flags:",body:z(t.flags),indentBody:0}}}o(X,"getFlags");function Y(t){const{help:e}=t;if(!e||!e.examples||e.examples.length===0)return;let{examples:r}=e;if(Array.isArray(r)&&(r=r.join(`
6
- `)),r)return{id:"examples",type:"section",data:{title:"Examples:",body:r}}}o(Y,"getExamples");function ee(t){if(!("alias"in t)||!t.alias)return;const{alias:e}=t;return{id:"aliases",type:"section",data:{title:"Aliases:",body:Array.isArray(e)?e.join(", "):e}}}o(ee,"getAliases");const te=o(t=>[K,Z,G,Q,X,Y,ee].map(e=>e(t)).filter(Boolean),"generateHelp"),re=R.WriteStream.prototype.hasColors();class ne{static{o(this,"Renderers")}text(e){return e}bold(e){return re?`\x1B[1m${e}\x1B[22m`:e.toLocaleUpperCase()}indentText({text:e,spaces:r}){return e.replaceAll(/^/gm," ".repeat(r))}heading(e){return this.bold(e)}section({title:e,body:r,indentBody:a=2}){return`${(e?`${this.heading(e)}
6
+ `)),r)return{id:"examples",type:"section",data:{title:"Examples:",body:r}}}o(Y,"getExamples");function ee(t){if(!("alias"in t)||!t.alias)return;const{alias:e}=t;return{id:"aliases",type:"section",data:{title:"Aliases:",body:Array.isArray(e)?e.join(", "):e}}}o(ee,"getAliases");const te=o(t=>[K,Z,G,Q,X,Y,ee].map(e=>e(t)).filter(Boolean),"generateHelp"),re=M.WriteStream.prototype.hasColors();class ne{static{o(this,"Renderers")}text(e){return e}bold(e){return re?`\x1B[1m${e}\x1B[22m`:e.toLocaleUpperCase()}indentText({text:e,spaces:r}){return e.replaceAll(/^/gm," ".repeat(r))}heading(e){return this.bold(e)}section({title:e,body:r,indentBody:a=2}){return`${(e?`${this.heading(e)}
7
7
  `:"")+(r?this.indentText({text:this.render(r),spaces:a}):"")}
8
- `}table({tableData:e,tableOptions:r,tableBreakpoints:a}){return D(e.map(n=>n.map(s=>this.render(s))),a?U(a):r)}flagParameter(e){return e===Boolean?"":e===String?"<string>":e===Number?"<number>":Array.isArray(e)?this.flagParameter(e[0]):"<value>"}flagOperator(e){return" "}flagName(e){const{flag:r,flagFormatted:a,aliasesEnabled:n,aliasFormatted:s}=e;let i="";if(s?i+=`${s}, `:n&&(i+=" "),i+=a,"placeholder"in r&&typeof r.placeholder=="string")i+=`${this.flagOperator(e)}${r.placeholder}`;else{const d=this.flagParameter("type"in r?r.type:r);d&&(i+=`${this.flagOperator(e)}${d}`)}return i}flagDefault(e){return JSON.stringify(e)}flagDescription({flag:e}){let r="description"in e?e.description??"":"";if("default"in e){let{default:a}=e;typeof a=="function"&&(a=a()),a&&(r+=` (default: ${this.flagDefault(a)})`)}return r}render(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(r=>this.render(r)).join(`
9
- `);if("type"in e&&this[e.type]){const r=this[e.type];if(typeof r=="function")return r.call(this,e.data)}throw new Error(`Invalid node type: ${JSON.stringify(e)}`)}}const O=o(t=>t.length>0&&!t.includes(" "),"isValidScriptName"),{stringify:A}=JSON,ae=/[|\\{}()[\]^$+*?.]/;function P(t){const e=[];let r,a;for(const n of t){if(a)throw new Error(`Invalid parameter: Spread parameter ${A(a)} must be last`);const s=n[0],i=n.at(-1);let d;if(s==="<"&&i===">"&&(d=!0,r))throw new Error(`Invalid parameter: Required parameter ${A(n)} cannot come after optional parameter ${A(r)}`);if(s==="["&&i==="]"&&(d=!1,r=n),d===void 0)throw new Error(`Invalid parameter: ${A(n)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);let l=n.slice(1,-1);const h=l.slice(-3)==="...";h&&(a=n,l=l.slice(0,-3));const u=l.match(ae);if(u)throw new Error(`Invalid parameter: ${A(n)}. Invalid character found ${A(u[0])}`);e.push({name:l,required:d,spread:h})}return e}o(P,"parseParameters");function S(t,e,r,a){for(let n=0;n<e.length;n+=1){const{name:s,required:i,spread:d}=e[n],l=V(s);if(l in t)throw new Error(`Invalid parameter: ${A(s)} is used more than once.`);const h=d?r.slice(n):r[n];if(d&&(n=e.length),i&&(!h||d&&h.length===0))return console.error(`Error: Missing required parameter ${A(s)}
10
- `),a(),process.exit(1);t[l]=h}}o(S,"mapParametersToArguments");function se(t){return t!==!1}o(se,"helpEnabled");const ie=o(t=>{const e=[];for(const[r,a]of Object.entries(t))if(e.push(r),a&&typeof a=="object"&&"alias"in a){const{alias:n}=a;typeof n=="string"&&n?e.push(n):Array.isArray(n)&&e.push(...n.filter(Boolean))}return e},"getKnownFlagNames"),oe=o((t,e)=>{if(t.length<3||e.length===0)return;const r=H(t,e);return F(t,r)<=2?r:void 0},"findClosestFlag"),le=o((t,e)=>{const r=Object.keys(t);if(r.length!==0){for(const a of r){const n=oe(a,e),s=n?` (did you mean --${n}?)`:"";console.error(`Error: Unknown flag --${a}${s}`)}process.exit(1)}},"handleUnknownFlags");function I(t,e,r,a){const n={...e.flags},s=e.version&&!("version"in n);s&&(n.version={type:Boolean,description:"Show version"});const{help:i}=e,d=se(i);d&&!("help"in n)&&(n.help={type:Boolean,alias:"h",description:"Show help"});const l=M(n,a,{ignore:e.ignoreArgv}),h=o(()=>{console.log(e.version)},"showVersion");if(s&&l.flags.version===!0)return h(),process.exit(0);const u=new ne,C=d&&i?.render?i.render:m=>u.render(m),$=o(m=>{const y=te({...e,...m?{help:m}:{},flags:n});console.log(C(y,u))},"showHelp");if(d&&l.flags.help===!0)return $(),process.exit(0);if((e.strictFlags??e.parent?.strictFlags)&&le(l.unknownFlags,ie(n)),e.parameters){let{parameters:m}=e,y=l._;const f=m.indexOf("--"),v=m.slice(f+1),w=Object.create(null);let p=[];f>-1&&v.length>0&&(m=m.slice(0,f),p=l._["--"],y=y.slice(0,-p.length||void 0)),S(w,P(m),y,$),f>-1&&v.length>0&&S(w,P(v),p,$),Object.assign(l._,w)}const c={...l,showVersion:h,showHelp:$},g={command:t,...c};if(typeof r=="function"){const m=r(c);if(m&&"then"in m)return Object.assign(Promise.resolve(m),g)}return g}o(I,"cliBase");function ce(t,e){const r=new Map;for(const a of e){const n=[a.options.name],{alias:s}=a.options;s&&(Array.isArray(s)?n.push(...s):n.push(s));for(const i of n){if(r.has(i))throw new Error(`Duplicate command name found: ${A(i)}`);r.set(i,a)}}return r.get(t)}o(ce,"getCommand");function fe(t,e,r=process.argv.slice(2)){if(!t)throw new Error("Options is required");if("name"in t&&(!t.name||!O(t.name)))throw new Error(`Invalid script name: ${A(t.name)}`);const a=r[0];if(t.commands&&a&&O(a)){const n=ce(a,t.commands);if(n)return I(n.options.name,{...n.options,parent:t},n.callback,r.slice(1))}return I(void 0,t,e,r)}o(fe,"cli");function de(t,e){if(!t)throw new Error("Command options are required");const{name:r}=t;if(r===void 0)throw new Error("Command name is required");if(!O(r))throw new Error(`Invalid command name ${JSON.stringify(r)}. Command names must be one word.`);return{options:t,callback:e}}o(de,"command");export{fe as cli,de as command};
8
+ `}table({tableData:e,tableOptions:r,tableBreakpoints:a}){return R(e.map(n=>n.map(s=>this.render(s))),a?U(a):r)}flagParameter(e){return e===Boolean?"":e===String?"<string>":e===Number?"<number>":Array.isArray(e)?this.flagParameter(e[0]):"<value>"}flagOperator(e){return" "}flagName(e){const{flag:r,flagFormatted:a,aliasesEnabled:n,aliasFormatted:s}=e;let i="";if(s?i+=`${s}, `:n&&(i+=" "),i+=a,"placeholder"in r&&typeof r.placeholder=="string")i+=`${this.flagOperator(e)}${r.placeholder}`;else{const d=this.flagParameter("type"in r?r.type:r);d&&(i+=`${this.flagOperator(e)}${d}`)}return i}flagDefault(e){return JSON.stringify(e)}flagDescription({flag:e}){let r="description"in e?e.description??"":"";if("default"in e){let{default:a}=e;typeof a=="function"&&(a=a()),a&&(r+=` (default: ${this.flagDefault(a)})`)}return r}render(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(r=>this.render(r)).join(`
9
+ `);if("type"in e&&this[e.type]){const r=this[e.type];if(typeof r=="function")return r.call(this,e.data)}throw new Error(`Invalid node type: ${JSON.stringify(e)}`)}}const O=o(t=>t.length>0&&!t.includes(" "),"isValidScriptName"),{stringify:b}=JSON,ae=/[|\\{}()[\]^$+*?.]/;function P(t){const e=[];let r,a;for(const n of t){if(a)throw new Error(`Invalid parameter: Spread parameter ${b(a)} must be last`);const s=n[0],i=n.at(-1);let d;if(s==="<"&&i===">"&&(d=!0,r))throw new Error(`Invalid parameter: Required parameter ${b(n)} cannot come after optional parameter ${b(r)}`);if(s==="["&&i==="]"&&(d=!1,r=n),d===void 0)throw new Error(`Invalid parameter: ${b(n)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);let l=n.slice(1,-1);const h=l.slice(-3)==="...";h&&(a=n,l=l.slice(0,-3));const u=l.match(ae);if(u)throw new Error(`Invalid parameter: ${b(n)}. Invalid character found ${b(u[0])}`);e.push({name:l,required:d,spread:h})}return e}o(P,"parseParameters");function S(t,e,r,a){for(let n=0;n<e.length;n+=1){const{name:s,required:i,spread:d}=e[n],l=V(s);if(l in t)throw new Error(`Invalid parameter: ${b(s)} is used more than once.`);const h=d?r.slice(n):r[n];if(d&&(n=e.length),i&&(!h||d&&h.length===0))return console.error(`Error: Missing required parameter ${b(s)}
10
+ `),a(),process.exit(1);t[l]=h}}o(S,"mapParametersToArguments");function se(t){return t!==!1}o(se,"helpEnabled");const ie=o(t=>{const e=[];for(const[r,a]of Object.entries(t))if(e.push(r),a&&typeof a=="object"&&"alias"in a){const{alias:n}=a;typeof n=="string"&&n?e.push(n):Array.isArray(n)&&e.push(...n.filter(Boolean))}return e},"getKnownFlagNames"),oe=o((t,e)=>{if(t.length<3||e.length===0)return;const r=H(t,e);return q(t,r)<=2?r:void 0},"findClosestFlag"),le=o((t,e)=>{const r=Object.keys(t);if(r.length!==0){for(const a of r){const n=oe(a,e),s=n?` (Did you mean --${n}?)`:"";console.error(`Error: Unknown flag: --${a}.${s}`)}process.exit(1)}},"handleUnknownFlags");function I(t,e,r,a){const n={...e.flags},s=e.version&&!("version"in n);s&&(n.version={type:Boolean,description:"Show version"});const{help:i}=e,d=se(i);d&&!("help"in n)&&(n.help={type:Boolean,alias:"h",description:"Show help"});const l=D(n,a,{ignore:e.ignoreArgv,booleanNegation:e.booleanFlagNegation??e.parent?.booleanFlagNegation}),h=o(()=>{console.log(e.version)},"showVersion");if(s&&l.flags.version===!0)return h(),process.exit(0);const u=new ne,C=d&&i?.render?i.render:m=>u.render(m),$=o(m=>{const y=te({...e,...m?{help:m}:{},flags:n});console.log(C(y,u))},"showHelp");if(d&&l.flags.help===!0)return $(),process.exit(0);if((e.strictFlags??e.parent?.strictFlags)&&le(l.unknownFlags,ie(n)),e.parameters){let{parameters:m}=e,y=l._;const f=m.indexOf("--"),v=m.slice(f+1),w=Object.create(null);let g=[];f>-1&&v.length>0&&(m=m.slice(0,f),g=l._["--"],y=y.slice(0,-g.length||void 0)),S(w,P(m),y,$),f>-1&&v.length>0&&S(w,P(v),g,$),Object.assign(l._,w)}const c={...l,showVersion:h,showHelp:$},p={command:t,...c};if(typeof r=="function"){const m=r(c);if(m&&"then"in m)return Object.assign(Promise.resolve(m),p)}return p}o(I,"cliBase");function ce(t,e){const r=new Map;for(const a of e){const n=[a.options.name],{alias:s}=a.options;s&&(Array.isArray(s)?n.push(...s):n.push(s));for(const i of n){if(r.has(i))throw new Error(`Duplicate command name found: ${b(i)}`);r.set(i,a)}}return r.get(t)}o(ce,"getCommand");function fe(t,e,r=process.argv.slice(2)){if(!t)throw new Error("Options is required");if("name"in t&&(!t.name||!O(t.name)))throw new Error(`Invalid script name: ${b(t.name)}`);const a=r[0];if(t.commands&&a&&O(a)){const n=ce(a,t.commands);if(n)return I(n.options.name,{...n.options,parent:t},n.callback,r.slice(1))}return I(void 0,t,e,r)}o(fe,"cli");function de(t,e){if(!t)throw new Error("Command options are required");const{name:r}=t;if(r===void 0)throw new Error("Command name is required");if(!O(r))throw new Error(`Invalid command name ${JSON.stringify(r)}. Command names must be one word.`);return{options:t,callback:e}}o(de,"command");export{fe as cli,de as command};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cleye",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "The intuitive CLI development tool",
5
5
  "keywords": [
6
6
  "cli",
@@ -43,6 +43,6 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "terminal-columns": "^2.0.0",
46
- "type-flag": "^4.0.3"
46
+ "type-flag": "^4.1.0"
47
47
  }
48
48
  }