nestjs-command
TypeScript icon, indicating that this package has built-in type declarations

3.1.4 • Public • Published

Nestjs Command

npm version npm download by month npm peer dependency version - @nestjs/core

Description

Nest.js Command tools, based on yargs.

Dependency

  • Use version 3.* for nestjs 6.*, 7.*, 8.*, 9.*, 10.*, yargs 16.*, 17.*
  • Use version 2.* for nestjs 6.*, 7.*, 8.*, yargs 11.*, 12.*, 13.*, 14.*, 15.*
  • Use version 1.* for nestjs 6.*, 7.*
  • Use version 0.* for nestjs 5.*

BREAKING CHANGES (3.*)

In version 3.* has changes:

  • Drop: autoExit
  • Drop: CommandService.isRunning
  • Drop: CommandLogService
  • New: CommandService.exec() return Promise (Support async/await)
  • yargs only support 15.1.*, 16.*, 17.*

Installation

$ npm install --save nestjs-command yargs

# if you use typescript
$ npm install --save-dev @types/yargs

Quick Start

Register the command module in your base module: ./src/app.module.ts

import { Module } from '@nestjs/common';
import { CommandModule } from 'nestjs-command';

@Module({
  imports: [CommandModule]
})
export class AppModule {}

Create a Cli entrypoint: ./src/cli.ts

import { NestFactory } from '@nestjs/core';
import { CommandModule, CommandService } from 'nestjs-command';
import { AppModule } from './app.module.ts';

async function bootstrap () {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: false
  });

  try {
    await app
      .select(CommandModule)
      .get(CommandService)
      .exec();
    await app.close()
  } catch (error) {
    console.error(error);
    await app.close();
    process.exit(1);
  }
}

bootstrap();

And create your command providers (see the example below).

Run your program in either ways:

  • npx nestjs-command: run by default ./src/cli.ts
  • CLI_PATH=./dist/cli.js npx nestjs-command: run /dist/cli.js with the CLI_PATH env

Notice

Make sure to set CLI_ENV=./dist/cli.js when using commands in production with pre-compiled typescript

Usage example

Note: you will find documentation about yargs command positional here, and yargs command options here.

Create a simple Command File: ./src/user/user.command.ts

import { Command, Positional, Option } from 'nestjs-command';
import { Injectable } from '@nestjs/common';
import { UserService } from './user.service';

@Injectable()
export class UserCommand {
  constructor(private readonly userService: UserService) {}

  @Command({
    command: 'create:user <username>',
    describe: 'create a user',
  })
  async create(
    @Positional({
      name: 'username',
      describe: 'the username',
      type: 'string'
    })
    username: string,
    @Option({
      name: 'group',
      describe: 'user group (ex: "jedi")',
      type: 'string',
      alias: 'g',
      required: false
    })
    group: string,
    @Option({
      name: 'saber',
      describe: 'if user has a lightsaber',
      type: 'boolean',
      default: false,
      required: false
    })
    saber: boolean
  ) {
    this.userService.add({
      username,
      group,
      saber
    });
  }
}

Create a simple Service File: ./src/user/user.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class UserService {
  async add(user: any): Promise<any> {
    return Promise.resolve().then(() => {
      console.log('user added:', user);
    });
  }
}

Register this UserCommand and UserService as providers in your base module: ./src/app.module.ts

import { Module } from '@nestjs/common';
import { CommandModule } from 'nestjs-command';
import { UserCommand } from './user/user.command';
import { UserService } from './user/user.service';

@Module({
  imports: [CommandModule],
  providers: [UserCommand, UserService]
})
export class AppModule {}

And create a cli entrypoint: ./src/cli.ts

import { NestFactory } from '@nestjs/core';
import { CommandModule, CommandService } from 'nestjs-command';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error'] // only errors
  });

  try {
    await app
      .select(CommandModule)
      .get(CommandService)
      .exec();
    await app.close()
  } catch (error) {
    console.error(error);
    await app.close();
    process.exit(1);
  }
}
bootstrap();

Run your program in a terminal

Get some help:

$ npx nestjs-command create:user --help
cli create:user <username>

create a user

Positionals:
  username  the username                                     [string] [required]

Options:
  -h, --help     Show help                                             [boolean]
  --saber        if user has a lightsaber             [boolean] [default: false]
  --group, -g    user group (ex: "jedi")                                [string]
  -v, --version  Show version number                                   [boolean]

Add a new user:

$ npx nestjs-command create:user anakin --group jedi --no-saber
user added: { username: 'anakin', group: 'jedi', saber: false }

$ npx nestjs-command create:user yoda --group jedi --saber
user added: { username: 'yoda', group: 'jedi', saber: true }

How to test it?

import { Test } from '@nestjs/testing';
import { CommandModule, CommandModuleTest } from 'nestjs-command';
import { AppModule } from './app.module';

describe('AppModule', () => {
  let commandModule: CommandModuleTest;

  beforeEach(async () => {
    const moduleFixture = await Test.createTestingModule({
      imports: [AppModule]
    }).compile();

    const app = moduleFixture.createNestApplication();
    await app.init();
    commandModule = new CommandModuleTest(app.select(CommandModule));
  });

  it('test command module', async () => {
    const command = 'create:user <username>';
    const args = { username: 'Foo', group: 'Bar', saber: false };

    const user = await commandModule.execute(command, args);
    expect(user.username).toBe('Foo')
    expect(user.group).toBe('Bar')
  });
});

Readme

Keywords

Package Sidebar

Install

npm i nestjs-command

Weekly Downloads

28,221

Version

3.1.4

License

MIT

Unpacked Size

28.7 kB

Total Files

16

Last publish

Collaborators

  • aa900031