Skip to content

LinbuduLab/Mustard

Repository files navigation

npm dev dependency version GitHub Workflow Status

GitHub package.json version (subfolder of monorepo) npm bundle size codecov

IoC & Native ECMAScript Decorator based command line app builder.

Requires

  • Node.js >= 16.0.0
  • TypeScript >= 5.0.0

Features

  • Born to be type safe
  • Nest command support
  • Validator support by Zod
  • Automatic usage info generation
  • Build decoupled applications using IoC concepts
  • Essential built-in utils for CLI app

Getting Started

$ pnpx create-mustard-app

Sample with root command only:

import { MustardFactory, MustardUtils } from "mustard-cli";
import { RootCommand, App, Input } from "mustard-cli/decorator";
import { CommandStruct, MustardApp } from "mustard-cli/cli";

@RootCommand()
class RootCommandHandle implements CommandStruct {
  @Input()
  public name: string = "Harold";

  public run(): void {
    console.log(`Hi, ${this.name}`);
  }
}

@App({
  name: "hi",
  commands: [RootCommandHandle],
})
class Project implements MustardApp {}

MustardFactory.init(Project).start();
$ hi
# Hi, Harold
$ hi John
# Hi, John

Sample with root command and sub commands:

import { MustardFactory } from "mustard-cli";
import {
  Command,
  RootCommand,
  Option,
  VariadicOption,
  App,
  Input,
} from "mustard-cli/decorator";
import { Validator } from "mustard-cli/validator";
import { CommandStruct, MustardApp } from "mustard-cli/cli";

import path from "path";

@RootCommand()
class RootCommandHandle implements CommandStruct {
  @Option("m")
  public msg = "default value of msg";

  public run(): void {
    console.log(`Root command executed with: msg: ${this.msg}`);
  }
}

@Command("update", "u", "update project dependencies")
class UpdateCommand implements CommandStruct {
  @Option("depth", "depth of packages to update", Validator.Number().Gte(1))
  public depth = 10;

  @Option(Validator.Boolean())
  public dry = false;

  @Option({ name: "target", alias: "t" })
  public targetOption: string;

  @Input()
  public input: string[] = [];

  @VariadicOption()
  public packages: string[] = [];

  public run(): void {
    console.log(
      `Update command executed with: depth: ${this.depth}, dry: ${
        this.dry
      }, targetOption: ${this.targetOption}, input: ${JSON.stringify(
        this.input
      )}, packages: ${JSON.stringify(this.packages)}`
    );
  }
}

@App({
  name: "mm",
  commands: [RootCommandHandle, UpdateCommand],
  configurations: {
    allowUnknownOptions: true,
    enableVersion: require(path.resolve("./package.json")).version,
  },
})
class Project implements MustardApp {
  onStart() {}

  onComplete() {}
}

MustardFactory.init(Project).start();
$ mm
# Root command executed with: msg: default value of msg
$ mm -m=hello
# Root command executed with: msg: hello
$ mm update
# Update command executed with: depth: 10, dry: false, targetOption: undefined, input: [], packages: []
$ mm update --depth=1 --target=dep --packages p1 p2 p3
# Update command executed with: depth: 1, dry: false, targetOption: dep, input: [], packages: ["p1","p2","p3"]
$ mm update p1 p2 p3 -t=dev
# Update command executed with: depth: 10, dry: false, targetOption: dev, input: ["p1","p2","p3"], packages: []

Samples

You can find more samples Here.

License

MIT