Skip to content

Commit

Permalink
Added 'transform' (types to be fixed)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sukairo-02 committed Jul 5, 2024
1 parent 1f26761 commit 2069b16
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@drizzle-team/brocli",
"type": "module",
"author": "Drizzle Team",
"version": "0.4.0",
"version": "0.5.0",
"description": "Typed CLI command runner",
"license": "Apache-2.0",
"sideEffects": false,
Expand Down
57 changes: 44 additions & 13 deletions src/command-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,62 @@ export type RawCommand<
TOpts extends Record<string, GenericBuilderInternals> | undefined =
| Record<string, GenericBuilderInternals>
| undefined,
> = TOpts extends Record<string, GenericBuilderInternalsLimited> | undefined ? RawCommandWithSubcommands<TOpts>
: RawCommandWithPositionals<TOpts>;
TOptsData = TOpts extends Record<string, GenericBuilderInternals> ? TypeOf<TOpts> : undefined,
TTransformed = TOptsData,
> = TOpts extends Record<string, GenericBuilderInternalsLimited> | undefined
? RawCommandWithSubcommands<TOpts, TOptsData, TTransformed>
: RawCommandWithPositionals<TOpts, TOptsData, TTransformed>;

export type RawCommandWithPositionals<
TOpts extends Record<string, GenericBuilderInternals> | undefined =
| Record<string, GenericBuilderInternals>
| undefined,
TOptsData = TOpts extends Record<string, GenericBuilderInternals> ? TypeOf<TOpts> : undefined,
TTransformed = TOptsData,
> = {
name?: string;
aliases?: [string, ...string[]];
description?: string;
hidden?: boolean;
options?: TOpts;
help?: string | Function;
handler?: CommandHandler<TOpts>;
transform?: (options: TOptsData) => TTransformed;
handler?: (options: Awaited<TTransformed>) => any;
};

export type RawCommandWithSubcommands<
TOpts extends Record<string, GenericBuilderInternalsLimited> | undefined =
| Record<string, GenericBuilderInternalsLimited>
| undefined,
TOptsData = TOpts extends Record<string, GenericBuilderInternals> ? TypeOf<TOpts> : undefined,
TTransformed = TOptsData,
> = {
name?: string;
aliases?: [string, ...string[]];
description?: string;
hidden?: boolean;
options?: TOpts;
help?: string | Function;
handler?: CommandHandler<TOpts>;
transform?: (options: TOptsData) => TTransformed;
handler?: (options: Awaited<TTransformed>) => any;
subcommands?: [Command, ...Command[]];
};

export type RawCommandUniversal<
TOpts extends Record<string, GenericBuilderInternals> | undefined =
| Record<string, GenericBuilderInternals>
| undefined,
TOptsData = TOpts extends Record<string, GenericBuilderInternals> ? TypeOf<TOpts> : undefined,
TTransformed = TOptsData,
> = {
name?: string;
aliases?: [string, ...string[]];
description?: string;
hidden?: boolean;
options?: TOpts;
help?: string | Function;
transform?: (options: TOptsData) => TTransformed;
handler?: (options: Awaited<TTransformed>) => any;
subcommands?: [Command, ...Command[]];
};

Expand All @@ -81,7 +108,8 @@ export type AnyRawCommand<
hidden?: boolean;
options?: TOpts;
help?: string | Function;
handler?: CommandHandler<TOpts>;
transform?: GenericCommandHandler;
handler?: GenericCommandHandler;
subcommands?: [Command, ...Command[]];
};

Expand All @@ -92,6 +120,7 @@ export type Command = {
hidden?: boolean;
options?: ProcessedOptions;
help?: string | Function;
transform?: GenericCommandHandler;
handler: GenericCommandHandler;
subcommands?: [Command, ...Command[]];
parent?: Command;
Expand Down Expand Up @@ -125,7 +154,7 @@ const unknownSubcommand = (command: Command, caller: string) => {
return new Error(msg);
};

const missingRequired = (command: RawCommand<any>, missingOpts: [string[], ...string[][]]) => {
const missingRequired = (command: RawCommand<any, any, any>, missingOpts: [string[], ...string[][]]) => {
const msg = `Command '${command.name}' is missing following required options: ${
missingOpts.map((opt) => {
const name = opt.shift()!;
Expand All @@ -140,7 +169,7 @@ const missingRequired = (command: RawCommand<any>, missingOpts: [string[], ...st
return new Error(msg);
};

const unrecognizedOptions = (command: RawCommand<any>, unrecognizedArgs: [string, ...string[]]) => {
const unrecognizedOptions = (command: RawCommand<any, any, any>, unrecognizedArgs: [string, ...string[]]) => {
const msg = `Unrecognized options for command '${command.name}': ${unrecognizedArgs.join(', ')}`;

return new Error(msg);
Expand Down Expand Up @@ -304,11 +333,15 @@ const validateOptions = <TOptionConfig extends Record<string, GenericBuilderInte

export const command = <
TOpts extends Record<string, GenericBuilderInternals> | undefined,
>(command: RawCommand<TOpts>) => commandCheckBypass(command);
TOptsData = TOpts extends Record<string, GenericBuilderInternals> ? TypeOf<TOpts> : undefined,
TTransformed = TOptsData,
>(command: RawCommandUniversal<TOpts, TOptsData, TTransformed>) => commandCheckBypass(command);

const commandCheckBypass = <
TOpts extends Record<string, GenericBuilderInternals> | undefined,
>(command: RawCommand<TOpts>, ignoreReserved = true) => {
TOptsData = TOpts extends Record<string, GenericBuilderInternals> ? TypeOf<TOpts> : undefined,
TTransformed = TOptsData,
>(command: RawCommandUniversal<TOpts, TOptsData, TTransformed>, ignoreReserved = true) => {
const allNames = command.aliases ? [command.name, ...command.aliases] : [command.name];

const processedOptions = command.options ? validateOptions(command.options) : undefined;
Expand Down Expand Up @@ -725,7 +758,7 @@ export const rawCli = async (commands: Command[], config?: BroCliConfig) => {
options = parseOptions(command, newArgs, omitKeysOfUndefinedOptions);
cmd = command;

await cmd.handler(options);
await cmd.handler(command.transform ? await command.transform(options) : options);
return undefined;
};

Expand All @@ -740,9 +773,7 @@ export const runCli = async (commands: Command[], config?: BroCliConfig) => {
try {
await rawCli(commands, config);
} catch (e) {
if (e instanceof BroCliError) throw e;

console.log(typeof e === 'object' && e !== null && 'message' in e ? e.message : e);
console.error(typeof e === 'object' && e !== null && 'message' in e ? e.message : e);

process.exit(1);
}
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type {
HelpHandler,
InnerCommandParseRes,
RawCommand,
RawCommandUniversal,
RawCommandWithPositionals,
RawCommandWithSubcommands,
} from './command-core';
Expand Down

0 comments on commit 2069b16

Please sign in to comment.