Skip to content

Commit

Permalink
feat: support number arg type (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
Barbapapazes committed Mar 18, 2024
1 parent 02f4fdb commit 7ee947b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
23 changes: 19 additions & 4 deletions playground/hello.ts
Expand Up @@ -17,16 +17,31 @@ const command = defineCommand({
type: "boolean",
description: "Use friendly greeting",
},
adjective: {
age: {
type: "number",
description: "Your age",
required: false,
},
adj: {
type: "enum",
description: "Adjective to use in greeting",
options: ["awesome", "cool", "nice"],
default: "awesome",
require: false,
}
required: false,
},
},
run({ args }) {
consola.log(`${args.friendly ? "Hi" : "Greetings"} ${args.adjective} ${args.name}!`);
consola.log(args);
const msg = [
args.friendly ? "Hi" : "Greetings",
args.adj || "",
args.name,
args.age ? `You are ${args.age} years old.` : "",
]
.filter(Boolean)
.join(" ");

consola.log(msg);
},
});

Expand Down
17 changes: 15 additions & 2 deletions src/args.ts
Expand Up @@ -10,10 +10,11 @@ export function parseArgs<T extends ArgsDef = ArgsDef>(
const parseOptions = {
boolean: [] as string[],
string: [] as string[],
number: [] as string[],
enum: [] as (number | string)[],
mixed: [] as string[],
alias: {} as Record<string, string | string[]>,
default: {} as Record<string, boolean | string>,
default: {} as Record<string, boolean | number | string>,
};

const args = resolveArgs(argsDef);
Expand All @@ -23,7 +24,7 @@ export function parseArgs<T extends ArgsDef = ArgsDef>(
continue;
}
// eslint-disable-next-line unicorn/prefer-switch
if (arg.type === "string") {
if (arg.type === "string" || arg.type === "number") {
parseOptions.string.push(arg.name);
} else if (arg.type === "boolean") {
parseOptions.boolean.push(arg.name);
Expand All @@ -49,6 +50,7 @@ export function parseArgs<T extends ArgsDef = ArgsDef>(
});

for (const [, arg] of args.entries()) {
// eslint-disable-next-line unicorn/prefer-switch
if (arg.type === "positional") {
const nextPositionalArgument = positionalArguments.shift();
if (nextPositionalArgument !== undefined) {
Expand All @@ -74,6 +76,17 @@ export function parseArgs<T extends ArgsDef = ArgsDef>(
"EARG",
);
}
} else if (arg.type === "number") {
const _originalValue = parsedArgsProxy[arg.name];
parsedArgsProxy[arg.name] = Number.parseFloat(
parsedArgsProxy[arg.name] as string,
);
if (Number.isNaN(parsedArgsProxy[arg.name])) {
throw new CLIError(
`Invalid value for argument: \`--${arg.name}\` (\`${_originalValue}\`). Expected a number.`,
"EARG",
);
}
} else if (arg.required && parsedArgsProxy[arg.name] === undefined) {
throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
}
Expand Down
25 changes: 21 additions & 4 deletions src/types.ts
@@ -1,8 +1,14 @@
// ----- Args -----

export type ArgType = "boolean" | "string" | "positional" | "enum" | undefined;
export type ArgType =
| "boolean"
| "string"
| "number"
| "enum"
| "positional"
| undefined;

export type _ArgDef<T extends ArgType, VT extends boolean | string> = {
export type _ArgDef<T extends ArgType, VT extends boolean | number | string> = {
type?: T;
description?: string;
valueHint?: string;
Expand All @@ -14,17 +20,22 @@ export type _ArgDef<T extends ArgType, VT extends boolean | string> = {

export type BooleanArgDef = Omit<_ArgDef<"boolean", boolean>, "options">;
export type StringArgDef = Omit<_ArgDef<"string", string>, "options">;
export type NumberArgDef = Omit<_ArgDef<"number", boolean>, "options">;
export type EnumArgDef = _ArgDef<"enum", string>;
export type PositionalArgDef = Omit<
_ArgDef<"positional", string>,
"alias" | "options"
>;
export type EnumArgDef = _ArgDef<"enum", string>;

export type ArgDef =
| BooleanArgDef
| StringArgDef
| NumberArgDef
| PositionalArgDef
| EnumArgDef;

export type ArgsDef = Record<string, ArgDef>;

export type Arg = ArgDef & { name: string; alias: string[] };

export type ParsedArgs<T extends ArgsDef = ArgsDef> = { _: string[] } & Record<
Expand All @@ -37,6 +48,12 @@ export type ParsedArgs<T extends ArgsDef = ArgsDef> = { _: string[] } & Record<
}[keyof T],
string
> &
Record<
{
[K in keyof T]: T[K] extends { type: "number" } ? K : never;
}[keyof T],
number
> &
Record<
{
[K in keyof T]: T[K] extends { type: "boolean" } ? K : never;
Expand All @@ -51,7 +68,7 @@ export type ParsedArgs<T extends ArgsDef = ArgsDef> = { _: string[] } & Record<
[K in keyof T]: T[K] extends { options: infer U } ? U : never;
}[keyof T]
> &
Record<string, string | boolean | string[]>;
Record<string, string | number | boolean | string[]>;

// ----- Command -----

Expand Down

0 comments on commit 7ee947b

Please sign in to comment.