Skip to content

Commit

Permalink
refactor: to use classes
Browse files Browse the repository at this point in the history
  • Loading branch information
k2on committed Oct 26, 2024
1 parent 09ddf77 commit e6923db
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 27 deletions.
10 changes: 8 additions & 2 deletions examples/basic/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import z from "zod";
const cli = router({
add: router({
module: command()
.describe("Add a module")
.input(z.object({ name: z.number() }))
.fn(({ name }) => {
console.log(`Name: ${name}`);
}),
package: command()
.describe("Add a package")
.input(
z.object({
name: z.string(),
Expand All @@ -18,8 +20,12 @@ const cli = router({
console.log(`Package name: ${name}`);
}),
}),
help: command().fn(() => console.log("Help command")),
version: command().fn(() => console.log("Version 1.0")),
help: command()
.describe("Show help for the CLI")
.fn(() => console.log("Help command")),
version: command()
.describe("Show the CLI version")
.fn(() => console.log("Version 1.0")),
});

run(cli);
86 changes: 61 additions & 25 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,55 @@
export type Command = {
import { z, ZodNever, ZodSchema, ZodTypeAny } from "zod";
import { commands } from "./util";

class CommandBuilder<T extends ZodSchema> {
private schema: ZodSchema | undefined;
private description: string | undefined;

constructor(builder?: CommandBuilder<T>) {
if (builder) {
this.schema = builder.schema;
this.description = builder.description;
}
}

describe(description: string) {
this.description = description;
return this;
}

input(schema: ZodSchema) {
this.schema = schema;

return new CommandBuilder<z.infer<typeof schema>>(this);
}

fn(fn: (input: T) => void): BuildCommand<any> {
return {
_type: "command",
input: this.schema,
description: this.description,
fn,
};
}
}

export function command() {
return new CommandBuilder();
}

interface BuildCommand<T extends ZodTypeAny> {
_type: "command";
fn: () => void;
};
input?: ZodSchema<T>;
description?: string;
fn: (input: T) => void;
}

export type Commands = {
_type: "cli";
commands: Record<string, CLI>;
};

export type CLI = Command | Commands;

function commands(input: CLI) {
if (input._type == "cli") {
console.log("Commands:");
console.log(Object.keys(input.commands).join("\n"));
} else {
console.log("Command:", input);
}
}
export type CLI = BuildCommand<any> | Commands;

function next(input: CLI, current: string | undefined, args: string[]) {
if (!current) return commands(input);
Expand All @@ -30,7 +62,22 @@ function next(input: CLI, current: string | undefined, args: string[]) {
}

if (handler._type == "command") {
handler.fn();
// @ts-ignore
const shape = handler.input?.shape;
const keys = Object.keys(shape);

const remainingArgs = args.slice(1);

const obj = keys.reduce(
(acc, key, index) => {
// @ts-ignore
acc[key] = remainingArgs[index];
return acc;
},
{} as Record<string, unknown>,
);

handler.fn(obj);
return;
} else {
const nextArg = args[1];
Expand All @@ -56,14 +103,3 @@ export const router = (commands: Commands["commands"]): Commands => {
commands,
};
};

export const command = () => {
return {
fn: (functionInput: () => void): Command => {
return {
_type: "command",
fn: functionInput,
};
},
};
};
20 changes: 20 additions & 0 deletions packages/cli/src/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { CLI } from ".";

function commandDetails(command: CLI) {
if (command._type == "command") {
if (!command.description) return "";
return `${command.description}`;
} else {
return "Menu";
}

}

export function commands(input: CLI) {
if (input._type == "cli") {
console.log("Command List:");
console.log(Object.entries(input.commands).map(([key, value]) => `${key}: ${commandDetails(value)}`).join("\n"));
} else {
console.log("Command:", input);
}
}

0 comments on commit e6923db

Please sign in to comment.