Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support validate in args definition #87

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions playground/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@
description: "Deployment provider",
valueHint: "foo|bar|baz|qux",
},
port: {
type: "string",
description: "Port number to listen on",
required: true,
validate(value) {
return Number(value) >= 1 && Number(value) <= 65_536 ? true : "Port number must be greater than 1 and less than 65536"
},
}

Check warning on line 62 in playground/commands/deploy.ts

View check run for this annotation

Codecov / codecov/patch

playground/commands/deploy.ts#L55-L62

Added lines #L55 - L62 were not covered by tests
},
run({ args }) {
consola.log("Build");
Expand Down
17 changes: 17 additions & 0 deletions src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,20 @@
}
return args;
}

export function resolveArgsValidate(
parsedArgs: ParsedArgs,
argsDef: ArgsDef,
): string | undefined {
for (const [name, argDef] of Object.entries(argsDef || {})) {
const value = parsedArgs[name] as never;
if (argDef.validate) {
const word = argDef.validate(value) || "";
if (argDef.required && typeof word === "string") {
return (
Copy link

@janniks janniks May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should validate always fail and show the failure string if it's a string (even if not an required arg)?

`Argument validation failed: ${name}` + (word ? ` - ${word}` : "")
);
}
}
}
}

Check warning on line 125 in src/args.ts

View check run for this annotation

Codecov / codecov/patch

src/args.ts#L109-L125

Added lines #L109 - L125 were not covered by tests
7 changes: 5 additions & 2 deletions src/command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { CommandContext, CommandDef, ArgsDef } from "./types";
import { CLIError, resolveValue } from "./_utils";
import { parseArgs } from "./args";
import { parseArgs, resolveArgsValidate } from "./args";

Check warning on line 3 in src/command.ts

View check run for this annotation

Codecov / codecov/patch

src/command.ts#L3

Added line #L3 was not covered by tests

export function defineCommand<T extends ArgsDef = ArgsDef>(
def: CommandDef<T>,
Expand Down Expand Up @@ -59,7 +59,10 @@
throw new CLIError(`No command specified.`, "E_NO_COMMAND");
}
}

const word = resolveArgsValidate(parsedArgs, cmdArgs);
if (word) {
throw new CLIError(word, "E_VALIDATE_FAILED");
}

Check warning on line 65 in src/command.ts

View check run for this annotation

Codecov / codecov/patch

src/command.ts#L62-L65

Added lines #L62 - L65 were not covered by tests
// Handle main command
if (typeof cmd.run === "function") {
result = await cmd.run(context);
Expand Down
9 changes: 9 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
alias?: string | string[];
default?: VT;
required?: boolean;
validate?: (value: ParsedArgType<T>) => boolean | string;

Check warning on line 18 in src/types.ts

View check run for this annotation

Codecov / codecov/patch

src/types.ts#L18

Added line #L18 was not covered by tests
options?: (string | number)[];
};

Expand Down Expand Up @@ -70,6 +71,14 @@
> &
Record<string, string | number | boolean | string[]>;

export type ParsedArgType<T extends ArgType = ArgType> = T extends "positional"
? string
: T extends "string"
? string
: T extends "boolean"
? boolean
: string | boolean;

Check warning on line 81 in src/types.ts

View check run for this annotation

Codecov / codecov/patch

src/types.ts#L74-L81

Added lines #L74 - L81 were not covered by tests
// ----- Command -----

// Command: Shared
Expand Down