Skip to content

Commit a0307d2

Browse files
committed
πŸ› fix: global flag
1 parent 83ae9ec commit a0307d2

File tree

7 files changed

+58
-21
lines changed

7 files changed

+58
-21
lines changed

β€Žpackages/core/src/cli.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import type {
2222
CommandType,
2323
CommandWithHandler,
2424
Commands,
25-
FlagWithoutDescription,
2625
Flags,
27-
FlagsWithoutDescription,
26+
GlobalFlagOption,
27+
GlobalFlagOptions,
2828
Handler,
2929
HandlerContext,
3030
I18N,
@@ -50,7 +50,7 @@ import { locales } from "./locales";
5050
export const Root = Symbol.for("Clerc.Root");
5151
export type RootType = typeof Root;
5252

53-
export class Clerc<C extends Commands = {}, GF extends FlagsWithoutDescription = {}> {
53+
export class Clerc<C extends Commands = {}, GF extends GlobalFlagOptions = {}> {
5454
#name = "";
5555
#description = "";
5656
#version = "";
@@ -289,18 +289,19 @@ export class Clerc<C extends Commands = {}, GF extends FlagsWithoutDescription =
289289
/**
290290
* Register a global flag
291291
* @param name
292+
* @param description
292293
* @param options
293294
* @returns
294295
* @example
295296
* ```ts
296297
* Clerc.create()
297-
* .flag("help", {
298+
* .flag("help", "help", {
298299
* alias: "h",
299-
* description: "help",
300+
* type: Boolean,
300301
* })
301302
* ```
302303
*/
303-
flag<N extends string, O extends FlagWithoutDescription>(name: N, description: string, options: O): this & Clerc<C, GF & Record<N, O>> {
304+
flag<N extends string, O extends GlobalFlagOption>(name: N, description: string, options: O): this & Clerc<C, GF & Record<N, O>> {
304305
this.#flags[name] = {
305306
description,
306307
...options,
@@ -408,8 +409,12 @@ export class Clerc<C extends Commands = {}, GF extends FlagsWithoutDescription =
408409
const { t } = this.i18n;
409410
const [command, called] = getCommand();
410411
const isCommandResolved = !!command;
412+
const flagsMerged = {
413+
...this.#flags,
414+
...command?.flags,
415+
};
411416
// [...argv] is a workaround since TypeFlag modifies argv
412-
const parsed = typeFlag(command?.flags || {}, [...argv]);
417+
const parsed = typeFlag(flagsMerged, [...argv]);
413418
const { _: args, flags, unknownFlags } = parsed;
414419
let parameters = !isCommandResolved || command.name === Root ? args : args.slice(command.name.split(" ").length);
415420
let commandParameters = command?.parameters || [];

β€Žpackages/core/src/types/index.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ import type { FlagSchema, ParsedFlags, TypeFlag } from "./type-flag";
55
import type { ParseFlag, ParseParameters, ParseRaw } from "./utils";
66

77
export type CommandType = RootType | string;
8-
98
export type FlagOptions = FlagSchema & {
109
description: string
1110
};
1211
export type Flag = FlagOptions & {
1312
name: string
1413
};
15-
export type FlagWithoutDescription = Omit<Flag, "description">;
14+
export type GlobalFlagOption = FlagSchema;
1615
export type Flags = Dict<FlagOptions>;
17-
export type FlagsWithoutDescription = Dict<FlagWithoutDescription>;
16+
export type GlobalFlagOptions = Dict<GlobalFlagOption>;
1817

1918
export declare interface CommandCustomProperties {}
2019
export interface CommandOptions<P extends string[] = string[], A extends MaybeArray<string | RootType> = MaybeArray<string | RootType>, F extends Flags = Flags> extends CommandCustomProperties {
@@ -39,7 +38,7 @@ export interface ParseOptions {
3938
run?: boolean
4039
}
4140

42-
export interface HandlerContext<C extends Commands = Commands, N extends keyof C = keyof C, GF extends FlagsWithoutDescription = {}> {
41+
export interface HandlerContext<C extends Commands = Commands, N extends keyof C = keyof C, GF extends GlobalFlagOptions = {}> {
4342
name?: LiteralUnion<N, string>
4443
called?: string | RootType
4544
resolved: boolean
@@ -51,7 +50,7 @@ export interface HandlerContext<C extends Commands = Commands, N extends keyof C
5150
flags: Simplify<ParseFlag<C, N, GF> & Record<string, any>>
5251
cli: Clerc<C, GF>
5352
}
54-
export type Handler<C extends Commands = Commands, K extends keyof C = keyof C, GF extends FlagsWithoutDescription = {}> = (ctx: HandlerContext<C, K, GF>) => void;
53+
export type Handler<C extends Commands = Commands, K extends keyof C = keyof C, GF extends GlobalFlagOptions = {}> = (ctx: HandlerContext<C, K, GF>) => void;
5554
export type HandlerInCommand<C extends HandlerContext> = (ctx: { [K in keyof C]: C[K] }) => void;
5655
export type FallbackType<T, U> = {} extends T ? U : T;
5756
export type InspectorContext<C extends Commands = Commands> = HandlerContext<C> & {

β€Žpackages/core/src/types/type-flag.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export type FlagSchemaDefault<TF, DefaultType = any> = FlagSchemaBase<TF> & {
5454
};
5555
export type FlagSchema<TF = FlagType> = (FlagSchemaBase<TF> | FlagSchemaDefault<TF>);
5656
export type FlagTypeOrSchema<ExtraOptions = Record<string, unknown>> = FlagType | (FlagSchema & ExtraOptions);
57-
type Flags<ExtraOptions = Record<string, unknown>> = Record<string, FlagTypeOrSchema<ExtraOptions>>;
57+
export type Flags<ExtraOptions = Record<string, unknown>> = Record<string, FlagTypeOrSchema<ExtraOptions>>;
5858
export type InferFlagType<Flag extends FlagTypeOrSchema> = (Flag extends (TypeFunctionArray<infer T> | FlagSchema<TypeFunctionArray<infer T>>) ? (Flag extends FlagSchemaDefault<TypeFunctionArray<T>, infer D> ? T[] | D : T[]) : (Flag extends TypeFunction<infer T> | FlagSchema<TypeFunction<infer T>> ? (Flag extends FlagSchemaDefault<TypeFunction<T>, infer D> ? T | D : T | undefined) : never));
5959
export interface ParsedFlags<Schemas = Record<string, unknown>> {
6060
flags: Schemas
@@ -73,3 +73,9 @@ export interface IgnoreFunction {
7373
(type: typeof ARGUMENT, argvElement: string): boolean | void
7474
(type: typeof KNOWN_FLAG | typeof UNKNOWN_FLAG, flagName: string, flagValue: string | undefined): boolean | void
7575
}
76+
export interface TypeFlagOptions {
77+
/**
78+
* Which argv elements to ignore from parsing
79+
*/
80+
ignore?: IgnoreFunction
81+
}

β€Žpackages/core/src/types/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { CamelCase, Dict, Equals } from "@clerc/utils";
22
import type { OmitIndexSignature } from "type-fest";
33
import type { TypeFlag } from "./type-flag";
4-
import type { Command, Commands, Flags, FlagsWithoutDescription, InspectorContext } from ".";
4+
import type { Command, Commands, Flags, GlobalFlagOptions, InspectorContext } from ".";
55

66
type StripBrackets<Parameter extends string> = (
77
Parameter extends `<${infer ParameterName}>` | `[${infer ParameterName}]`
@@ -32,8 +32,8 @@ export type MakeEventMap<T extends Commands> = { [K in keyof T]: [InspectorConte
3232

3333
type FallbackFlags<F extends Flags | undefined> = Equals<NonNullableFlag<F>["flags"], {}> extends true ? Dict<any> : NonNullableFlag<F>["flags"];
3434
type NonNullableFlag<F extends Flags | undefined> = TypeFlag<NonNullable<F>>;
35-
export type ParseFlag<C extends Commands, N extends keyof C, GF extends FlagsWithoutDescription = {}> = N extends keyof C ? OmitIndexSignature<NonNullableFlag<C[N]["flags"] & GF>["flags"]> : FallbackFlags<C[N]["flags"] & GF>["flags"];
36-
export type ParseRaw<C extends Command, GF extends FlagsWithoutDescription = {}> = NonNullableFlag<C["flags"] & GF> & {
35+
export type ParseFlag<C extends Commands, N extends keyof C, GF extends GlobalFlagOptions = {}> = N extends keyof C ? OmitIndexSignature<NonNullableFlag<C[N]["flags"] & GF>["flags"]> : FallbackFlags<C[N]["flags"] & GF>["flags"];
36+
export type ParseRaw<C extends Command, GF extends GlobalFlagOptions = {}> = NonNullableFlag<C["flags"] & GF> & {
3737
flags: FallbackFlags<C["flags"] & GF>
3838
parameters: string[]
3939
mergedFlags: FallbackFlags<C["flags"] & GF> & NonNullableFlag<C["flags"] & GF>["unknownFlags"]

β€Žpackages/plugin-help/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export const helpPlugin = ({
172172
};
173173

174174
if (command) {
175-
cli = cli.command("help", t("help.comamndDescription")!, {
175+
cli = cli.command("help", t("help.commandDescription")!, {
176176
parameters: [
177177
"[command...]",
178178
],

β€Žpackages/plugin-help/src/utils.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ export const table = (items: string[][]) => textTable(items, { stringLength: str
1111

1212
export const splitTable = (items: string[][]) => table(items).split("\n");
1313

14-
const primitiveMap = new Map<any, string>([
15-
[Boolean, ""],
14+
const primitiveMap = new Map<any, string | undefined>([
15+
[Boolean, undefined],
1616
[String, "string"],
1717
[Number, "number"],
1818
]);
1919
export const stringifyType = (type: any, hasDefault = false) => {
2020
const res = primitiveMap.has(type)
2121
? primitiveMap.get(type)
2222
: "value";
23-
return hasDefault ? `[${res}]` : `<${res}>`;
23+
return res
24+
? hasDefault ? `[${res}]` : `<${res}>`
25+
: "";
2426
};
2527

2628
export const sortName = (a: CommandType, b: CommandType) => {
@@ -78,7 +80,7 @@ export const formatFlags = (flags: Flags) => Object.entries(flags).map(([name, f
7880
items.push(DELIMITER, flag.description);
7981
if (flag.type) {
8082
const type = stringifyType(flag.type);
81-
items.push(pc.gray(`(${type})`));
83+
type && items.push(pc.gray(`(${type})`));
8284
}
8385
return items;
8486
});

β€Žt.mts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Clerc, helpPlugin } from "./packages/clerc/src/index";
2+
3+
Clerc.create("1", "1", "1")
4+
.use(helpPlugin())
5+
.command("a a", "a", {
6+
flags: {
7+
aa: {
8+
type: Boolean,
9+
description: "",
10+
},
11+
},
12+
})
13+
.flag("hel", "1", {
14+
type: Boolean,
15+
})
16+
.on("a a", (ctx) => {
17+
console.log(ctx.flags.b);
18+
})
19+
.inspector((ctx, next) => {
20+
next();
21+
return () => {
22+
console.log(ctx.flags);
23+
};
24+
})
25+
.parse();

0 commit comments

Comments
Β (0)