Skip to content

Commit

Permalink
fix: support global flag types
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley committed Aug 1, 2022
1 parent c4f2998 commit 648978e
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 8 deletions.
3 changes: 2 additions & 1 deletion src/command.ts
Expand Up @@ -148,6 +148,7 @@ export default abstract class Command {

static set flags(flags: Interfaces.FlagInput<any>) {
this._flags = Object.assign({}, this._flags ?? {}, this.globalFlags, flags)
// this._flags = Object.assign({}, this._flags ?? {}, flags)
}

id: string | undefined
Expand Down Expand Up @@ -242,7 +243,7 @@ export default abstract class Command {
g['http-call']!.userAgent = this.config.userAgent
}

protected async parse<F, A extends { [name: string]: any }>(options?: Interfaces.Input<F>, argv = this.argv): Promise<Interfaces.ParserOutput<F, A>> {
protected async parse<F, G, A extends { [name: string]: any }>(options?: Interfaces.Input<F, G>, argv = this.argv): Promise<Interfaces.ParserOutput<F, G, A>> {
if (!options) options = this.constructor as any
const opts = {context: this, ...options}
// the spread operator doesn't work with getters so we have to manually add it here
Expand Down
9 changes: 5 additions & 4 deletions src/interfaces/parser.ts
Expand Up @@ -43,17 +43,17 @@ export type ArgInput = Arg<any>[]
export interface CLIParseErrorOptions {
parse: {
input?: ParserInput;
output?: ParserOutput<any, any>;
output?: ParserOutput;
};
}

export type OutputArgs = { [name: string]: any }
export type OutputFlags<T extends ParserInput['flags']> = { [P in keyof T]: any }
export type ParserOutput<TFlags extends OutputFlags<any>, TArgs extends OutputArgs> = {
export type ParserOutput<TFlags extends OutputFlags<any> = any, GFlags extends OutputFlags<any> = any, TArgs extends OutputArgs = any> = {
// Add in global flags so that they show up in the types
// This is necessary because there's no easy way to optionally return
// the individual flags based on wether they're enabled or not
flags: TFlags & { json: boolean | undefined };
flags: TFlags & GFlags & { json: boolean | undefined };
args: TArgs;
argv: string[];
raw: ParsingToken[];
Expand Down Expand Up @@ -162,8 +162,9 @@ export type EnumFlagOptions<T> = Partial<OptionFlag<T>> & {

export type Flag<T> = BooleanFlag<T> | OptionFlag<T>

export type Input<TFlags extends FlagOutput> = {
export type Input<TFlags extends FlagOutput, GFlags extends FlagOutput> = {
flags?: FlagInput<TFlags>;
globalFlags?: FlagInput<GFlags>;
args?: ArgInput;
strict?: boolean;
context?: any;
Expand Down
4 changes: 2 additions & 2 deletions src/parser/index.ts
Expand Up @@ -15,7 +15,7 @@ const m = Deps()
// eslint-disable-next-line node/no-missing-require
.add('validate', () => require('./validate').validate as typeof Validate.validate)

export async function parse<TFlags, TArgs extends { [name: string]: string }>(argv: string[], options: Input<TFlags>): Promise<ParserOutput<TFlags, TArgs>> {
export async function parse<TFlags, GFlags, TArgs extends { [name: string]: string }>(argv: string[], options: Input<TFlags, GFlags>): Promise<ParserOutput<TFlags, GFlags, TArgs>> {
const input = {
argv,
context: options.context,
Expand All @@ -30,7 +30,7 @@ export async function parse<TFlags, TArgs extends { [name: string]: string }>(ar
const parser = new Parser(input)
const output = await parser.parse()
m.validate({input, output})
return output as ParserOutput<TFlags, TArgs>
return output as ParserOutput<TFlags, GFlags, TArgs>
}

const {boolean, integer, url, directory, file} = flags
Expand Down
2 changes: 1 addition & 1 deletion src/parser/validate.ts
Expand Up @@ -10,7 +10,7 @@ import {ParserArg, ParserInput, ParserOutput, Flag} from '../interfaces'

export function validate(parse: {
input: ParserInput;
output: ParserOutput<any, any>;
output: ParserOutput;
}) {
function validateArgs() {
const maxArgs = parse.input.args.length
Expand Down

0 comments on commit 648978e

Please sign in to comment.