0.2.41 • Published 2 months ago

@anchan828/nest-commands v0.2.41

Weekly downloads
245
License
MIT
Repository
github
Last release
2 months ago

@anchan828/nest-commands

Make command line tools based on yargs.

$ nest-commands-example --help
nest-commands-example <command>

Commands:
  nest-commands-example author  Show author information
  nest-commands-example file    Show file information

Options:
  --help     Show help                           [boolean]
  --version  Show version number                 [boolean]

Install

$ npm i @anchan828/nest-commands
$ npm i --save-dev @types/yargs

Usage

cli.ts

import { Commander, Command, CommandModule, CommandService } from "@anchan828/nest-commands";

@Commander()
class TestCommander {
  @Command({ name: "basic" })
  public basic() {
    console.log("hello!");
  }
}

@Module({
  imports: [CommandModule.register()],
  providers: [TestCommander],
})
class TestAppModule {}

(async () => {
  const app = await NestFactory.createApplicationContext(TestAppModule, { logger: false });
  app.get(CommandService).exec();
})();
$ ts-node cli.ts basic
hello!

CommandModule.register

You can set some options

CommandModule.register({
   /**
   * Set to yargs.scriptName
   *
   * @type {string}
   * @memberof CommandModuleOptions
   */
  scriptName?: string;

  /**
   * Set to yargs.usage
   *
   * @type {string}
   * @memberof CommandModuleOptions
   */
  usage?: string;

  /**
   * Set to yargs.locale
   *
   * @type {string}
   * @memberof CommandModuleOptions
   */
  locale?: string;
})

Nested command

If you want to use nested command, add name to commander.

@Commander({ name: "nested" })
class TestCommander {
  @Command({ name: "command1" })
  public command1(): void {
    console.log("Run nested command1");
  }

  @Command({ name: "command2" })
  public command2(): void {
    console.log("Run nested command2");
  }
}

Global options

You can set options to top level. Use @CommanderOption and no set commander name

@Commander()
class GlobalOptions {
  @CommanderOption({
    description: "Output as json",
    name: "json",
    type: "boolean",
  })
  public json!: boolean;
}

positional and option

@Commander()
class TestCommander {
  // See: https://github.com/yargs/yargs#complex-example
  @Command({ describe: "start the server", name: "serve" })
  public serve(
    @CommandPositional({
      default: 5000,
      describe: "port to bind on",
      name: "port",
    })
    port: number,
    @CommandOption({
      alias: "v",
      default: false,
      description: "Run with verbose logging",
      name: "verbose",
      type: "boolean",
    })
    verbose: boolean,
  ): void {
    console.log(`port is ${port}`);
    console.log(`verbose is ${verbose}`);
  }
}

Array positional

If you want to array positional, add .. at the end.

@Commander()
class TestCommander {
  @Command({ describe: "array positional", name: "list" })
  public serve(
    @CommandPositional({
      describe: "show files",
      name: "files..",
    })
    files: string[],
  ): void {
    console.log("Run array positional command");
    console.log(files);
  }
}

Pipe

@Injectable()
class StringPipe implements PipeTransform<string, string> {
  transform(value: string): string {
    return `updated ${value}`;
  }
}

@Commander()
class TestCommander {
  @Command({ describe: "start the server", name: "serve" })
  public serve(): void {
    // token is 'updated token'
    console.log(`token is '${this.token}'`);
  }

  @CommanderOption({ demandOption: true, name: "token", type: "string" }, StringPipe)
  public token!: string;
}

Load config file (cosmiconfig)

You can load config file from user project.

If you want to load config, set configName. Then CLI will search and load them

  • A {configName} property in a package.json file.
  • A .{configName}rc file with JSON or YAML syntax.
  • A .{configName}rc.json file.
  • A .{configName}rc.yaml, .{configName}rc.yml, or .{configName}rc.js file.
  • A {configName}.config.js JS file exporting the object.

Please see cosmiconfig about more details

Also, You can add custom config filename

@Module({
  imports: [
    CommandModule.register({
      configName: "nest-commands",
      searchPlaces: ["custom-config-name.json"],
    }),
  ],
  providers: [TestCommander],
})
class TestAppModule {}

Customize config object

You can customize config after loading it.

@Module({
  imports: [
    CommandModule.register({
      config: {
        name: "nest-commands",
        processor: async (config: TestConfig): Promise<TestConfig> => {
          if (config.date === "today") {
            config.date = new Date().toDateString();
          }
          return config;
        },
      },
    }),
  ],
  providers: [TestCommander],
})
class TestAppModule {}

Also, you can use decorators!

@GlobalConfig({ name: "nest-commands", searchPlaces: ["custom-config-name.json"] })
class TestGlobalConfig {
  @GlobalConfigProcessor()
  public async processor(config: TestConfig): Promise<TestConfig> {
    if (config.date === "today") {
      config.date = new Date().toDateString();
    }
    return config;
  }
}

@Module({
  imports: [CommandModule.register()],
  providers: [TestCommander, TestGlobalConfig],
})
class TestAppModule {}

Example

You can try to run command!

npx ts-node -T ./examples/basic.ts basic --help
npx ts-node -T ./examples/nested-commands.ts nested show --help
npx ts-node -T ./examples/positional-and-option.ts serve --help
npx ts-node -T ./examples/many-modules.ts --help
npx ts-node -T ./examples/many-modules.ts user show
npx ts-node -T ./examples/array-positional.ts list test1 test2
npx ts-node -T ./examples/merge-commanders merge --help
npx ts-node -T ./examples/commander-option.ts --token token serve
npx ts-node -T ./examples/global-options.ts --json test show
npx ts-node -T ./examples/use-pipes.ts --token token serve
npx ts-node -T ./examples/config.ts test
npx ts-node -T ./examples/config.processor.ts test

Tips

You can create single executable file using ncc / pkg / nexe.

See: @anchan828/nest-commands-example

0.2.41

2 months ago

0.2.40

2 months ago

0.2.39

2 months ago

0.2.38

2 months ago

0.2.37

2 months ago

0.2.36

3 months ago

0.2.35

3 months ago

0.2.27

5 months ago

0.2.26

5 months ago

0.2.25

5 months ago

0.2.24

6 months ago

0.2.23

6 months ago

0.2.30

4 months ago

0.2.34

3 months ago

0.2.33

3 months ago

0.2.32

4 months ago

0.2.31

4 months ago

0.2.29

4 months ago

0.2.28

5 months ago

0.2.22

6 months ago

0.2.21

6 months ago

0.2.20

6 months ago

0.2.19

7 months ago

0.2.18

7 months ago

0.2.17

7 months ago

0.2.16

7 months ago

0.2.15

8 months ago

0.2.14

8 months ago

0.2.13

8 months ago

0.2.12

8 months ago

0.2.11

9 months ago

0.2.10

9 months ago

0.2.9

9 months ago

0.2.8

9 months ago

0.2.7

9 months ago

0.2.6

10 months ago

0.2.5

10 months ago

0.2.4

10 months ago

0.2.3

10 months ago

0.2.2

10 months ago

0.2.1

11 months ago

0.2.0

11 months ago

0.1.79

11 months ago

0.1.78

11 months ago

0.1.77

11 months ago

0.1.76

12 months ago

0.1.75

12 months ago

0.1.74

12 months ago

0.1.72

1 year ago

0.1.73

1 year ago

0.1.70

1 year ago

0.1.71

1 year ago

0.1.69

1 year ago

0.1.68

1 year ago

0.1.67

1 year ago

0.1.66

1 year ago

0.1.65

1 year ago

0.1.64

1 year ago

0.1.63

1 year ago

0.1.62

1 year ago

0.1.61

1 year ago

0.1.60

1 year ago

0.1.59

1 year ago

0.1.58

1 year ago

0.1.57

1 year ago

0.1.56

1 year ago

0.1.55

1 year ago

0.1.54

1 year ago

0.1.53

1 year ago

0.1.52

1 year ago

0.1.51

1 year ago

0.1.50

1 year ago

0.1.49

1 year ago

0.1.48

1 year ago

0.1.47

2 years ago

0.1.46

2 years ago

0.1.45

2 years ago

0.1.44

2 years ago

0.1.43

2 years ago

0.1.42

2 years ago

0.1.41

2 years ago

0.1.40

2 years ago

0.1.39

2 years ago

0.1.38

2 years ago

0.1.37

2 years ago

0.1.36

2 years ago

0.1.35

2 years ago

0.1.34

2 years ago

0.1.33

2 years ago

0.1.32

2 years ago

0.1.31

2 years ago

0.1.30

2 years ago

0.1.29

2 years ago

0.1.28

2 years ago

0.1.27

2 years ago

0.1.26

2 years ago

0.1.25

2 years ago

0.1.24

2 years ago

0.1.23

2 years ago

0.1.22

2 years ago

0.1.21

2 years ago

0.1.20

2 years ago

0.1.19

2 years ago

0.1.18

2 years ago

0.1.17

2 years ago

0.1.16

2 years ago

0.1.15

2 years ago

0.1.14

2 years ago

0.1.13

2 years ago

0.1.12

2 years ago

0.1.11

2 years ago

0.1.10

2 years ago

0.1.9

2 years ago

0.1.8

2 years ago

0.1.7

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago

0.0.35

2 years ago

0.0.36

2 years ago

0.0.34

2 years ago

0.0.33

2 years ago

0.0.32

2 years ago

0.0.31

2 years ago

0.0.30

2 years ago

0.0.28

2 years ago

0.0.29

2 years ago

0.0.27

2 years ago

0.0.25

2 years ago

0.0.26

2 years ago

0.0.24

2 years ago

0.0.23

2 years ago

0.0.22

2 years ago

0.0.21

2 years ago

0.0.20

2 years ago

0.0.19

2 years ago

0.0.18

2 years ago

0.0.17

2 years ago

0.0.16

2 years ago

0.0.15

3 years ago

0.0.14

3 years ago

0.0.13

3 years ago

0.0.12

3 years ago

0.0.11

3 years ago

0.0.10

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.6

3 years ago

0.0.5

3 years ago

0.0.4

3 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago