@polar-rules/nest-task
TypeScript icon, indicating that this package has built-in type declarations

0.2.0 • Public • Published

Nest Logo

The ultimate solution to execute simple tasks in Nest.js environment fully supporting import of Nest.js classes, basic tools and approaches.

Main NPM Version Package License

Coverage

Preview

List tasks:

Call task:

Description

@polar-rules/nest-task is the ultimate tool for generating and executing tasks within Nest.js environment using its classes, services, etc. We are fully following Nest.js conventions, rules and approaches to make our library as simple and as familiar as Nest.js itself.

Under the hood we are using the same tool set as Nest.js do: Reflect, class-transformer, class-validator, etc.

More documentation can be found on our website.

Features

  • Easy Setup: Quickly set up and integrate tasks within your Nest.js environment with a simple setup command.
  • Support ESM & CJS: Fully support latest modules, CJS and ESM.
  • Convention-based: Follows Nest.js conventions and supports different file naming conventions for flexibility.
  • Interactive Assistant: Use the interactive assistant (bear) for a more human-friendly and guided experience.
  • CLI Commands: Execute a variety of commands for task creation, information retrieval, and task execution.
  • Documentation: Well-documented with examples and explanations to guide users through the process.

Table of content

Getting started

Nest.js version

At this point we support only 10.x.x version of Nest.js (at least this is the version that is fully tested), however this package should theoretically work with 9.x.x and lower, but it wasn't tested.

Installation

Via NPM:

npm install @polar-rules/nest-task

Via Yarn:

yarn add @polar-rules/nest-task

Help

From command line you can call help prompt to receive a list of available commands:

npx nest-task help

Guides

Once you've installed you will have available nest-task binary available to run. We recommend you to run npx to run binary, but you choose whatever suits you the best.

Now you need to run:

npx nest-task setup --convention kebab-case

In case you have project key inside your nest-cli.json you need to add --project-name flag and specify project name. For example:

npx nest-task setup --project-name <project> --convention kebab-case

Or run interactive assistant and pick Setup option, and then just follow installation steps:

npx nest-task bear

This action will do the following:

  • modify the nest-cli.json and create new key task there
  • create the folder tasks under src
  • create main.ts and tasks.module.ts
  • create a simple example task for education purposes

Creating task

To create a task you need to run:

npx nest-task create --name <name> --description <description>

Or if you have project key inside your nest-cli.json you need to add --project-name flag and specify project name.

npx nest-task create --project-name <project> --name <name> --description <description>

You can run interactive assistant and pick create option and just follow proposed steps to generate task:

npx nest-task bear

Receiving the list of tasks

IMPORTANT. In purpose for your tasks run correctly you need to build your project firstly.

To receive a list of tasks

npx nest-task info

Or if you have project key inside your nest-cli.json you need to add --project-name flag and specify project name.

npx nest-task info --project-name <project>

You can run interactive assistant and pick info option and just follow proposed steps to generate task:

npx nest-task bear

Running task

IMPORTANT. In purpose for your tasks run correctly you need to build your project firstly.

To create a task you need to run:

npx nest-task run --name <name> <other-arguments>

Or if you have project key inside your nest-cli.json you need to add --project-name flag and specify project name.

npx nest-task run --project-name <project> --name <name> <other-arguments>

You can run interactive assistant and pick run option and just follow proposed steps to generate task:

npx nest-task bear

Running task without CLI

Yes, starting from 0.2.0 you can run tasks without CLI and directly using node command totally bypassing the case when default Nest.js configuration is not available. All you need to do is to call compiled main.js file with correct arguments.

Note: In case you don't have package.json or for some reason you're missing nest-cli.json on your server youre force to run this commands directly.

To pass arguments you need literally to do the same thing as you do with default CLI command.

For example:

node ./dist/task/main.js --name <name> <other-arguments>

Since you're calling main.ts file directly you don't need to handle project name at all, since we assume that you're that location of main.js already in default or under correct directory.

If you want to pass additional arguments, it's easy to do with the following syntax:

node ./dist/task/main.js --name <name> --argument1 value

Note: --argument1 - can have any desired name, except pre-defined fields, like name, projectName and other.

Documentation

Nest integration

In purpose to integrate with Nest.js we modify nest-cli.json file located inside your root directory. We add key task in this file on top level. The object should have the following format:

<root>/nest-cli.json

{
    "task": {
        "path": "src/tasks",
        "entryPoint": "main.ts",
        "convention": "kebab-case",
        "distDirectory": "dist"
    }
}

Or if you use projects feature from Nest.js then your nest-cli.json should look like this: <root>/nest-cli.json

{
    "projects": {
        "example": {
            "task": {
                "path": "src/tasks",
                "entryPoint": "main.ts",
                "convention": "kebab-case",
                "distDirectory": "dist"
            }
        }
    }
}

distDirectory

Optional.

By default, we assume that your script is compiled to the "dist" directory.

So for example, in default setup, you use your "dist" folder as compiled folder. This is basically where we will be looking for tasks when you're using CLI. (This will be ignored when you're using node command on entrypoint directly).

But, sometimes your configuration on server may be a bit different, since sometimes you're deploying your project as is, which may include you dist folder, and in this case you don't need to do anything, but there may the cases when transpiled code is located in other directory (not the on that is mentioned in tsconfig). So in this case we will recommend you to use specific path to this directory.

We're heavy really on package.json location and build our path to task from package.json and we assume that this is the project root. Then we will use distDirectory as a next folder from there.

For example this is how we build path <package.json root folder>/${distDirectory}/${path.replace("src", "")/${entryPoint}}

path

Required.

Refers to directory where tasks will be held. By default, we set it to src/tasks but you're free to change it to another directory as you will.

entryPoint

Required.

The main file name entrypoint should be present here, this file should be present with in directory specified in path key.

conventions

Required.

Directive the specifies what kind of file naming convention we should use when using create command. Available options are: "camel-case", "snake-case", "kebab-case" or "polar-rules".


Entrypoint

Entrypoint file, main.ts it's similar to Nest.js main.ts file. Basically after you run npx nest-task setup you don't need to change it, except the cases when you want to use custom paths.

Its implementation is straight forward, and one time. You don't need make changes afterward.

<root>/src/tasks/main.ts

import { Factory } from "@polar-rules/nest-task";

import { TasksModule } from "./tasks.module";

async function main(): Promise<void> {
    const app = await Factory.create(TasksModule);

    await app.run();
}

main();

The only thing that you can possibly would like to change here is path to TasksModule in case of custom setup.

TasksModule

The implementation is close to Nest.js @Module implementation.

<root>/src/tasks/tasks.module.ts

import { Decorators } from "@polar-rules/nest-task";

import { ExampleTask } from "./example/example.task";

@Decorators.Module({
    tasks: [
        ExampleTask,
    ],
})
export class _Module {}

tasks

Required.

Array of Task classes.


Task

Defining Task class.

<root>/src/tasks/example/example.task.ts

import { Decorators } from "@polar-rules/nest-task";

import { AppModule } from "../../app.module";
import { AppService } from "../../app.service";

import { ExampleRunner } from "./example.runner";

@Decorators.Task({
    name: "Example",
    description: "Task created for demonstration how to create basic example of task",
    runner: ExampleRunner,
    module: AppModule,
    providers: [AppService],
    deprecated: false,
})
export class ExampleTask {}

Overall, you already familiar with the syntax of this approach.

name

Required.

Unique.

Name of the tasks. Should be unique for @Decorators.Module. Used to located task, provider information about the task.

description

Required.

Short description of the task. Even if we do not have any limitation for length, we still recommend to keep it simple as possible.

runner

Required.

Your @Decorators.Runner class that will be covered in the next step. This class wil be the only class that will be executed by the task.

module

Required.

Main Nest.js application module is required to correctly initialise Nest.js environment.

providers

Optional.

Array of Nest.js services, entities and just classes that you want to use withing task in a same way as you do this within @Controller, @Injectable, etc.

deprecated

Optional.

Boolean value. Literally a flag that blocks you from running the task. Useful in cases when your task is meant to be run only one time and you want to avoid issues with running it second time.


Defining Runner class.

<root>/src/tasks/example/example.runner.ts

import { INestApplication, Logger } from "@nestjs/common";

import { Decorators } from "@polar-rules/nest-task";

import { ExampleDto } from "./example.dto";

@Decorators.Runner()
export class _Runner {
    public constructor(private readonly appService: AppService) {}
    
    public async perform(@Decorators.App() app: INestApplication, @Decorators.Logger() logger: Logger, @Decorators.Arguments() args: ExampleDto): Promise<void> {
        // Your code goes here
    }
}

providers

Are matched from @Decorators.Task providers field into constructor by type. The same way as you do with Nest.js.

app

By using @Decorators.App() for an argument you can pass the Nest.js application variable.

logger

By using @Decorators.Logger() for an argument you can pass the Nest.js default logger.

Now you can use as you would use default logger that is coming from Nest.js.

logger.log("Example")

args

If you need to pass additional arguments from command line to the task you can use @Decorators.Arguments() with DTO in a same way as you do for Nest.js @Controller.


Defining DTO class.

<root>/src/tasks/example/example.dto.ts

import { Type } from "class-transformer";
import { IsNumber, IsString } from "class-validator";

import { Decorators } from "@polar-rules/nest-task";

export class ExampleDto {
    @Decorators.Property()
    @Type(() => String)
    @IsString()
    data: string;

    @Decorators.Property()
    @Type(() => IsNumber)
    @IsNumber()
    userId: number;
}

The same way that you do with Nest.js DTO.

However

Even due class-transformer library do support complex types, as array, object, etc. And theoretically we can do this too, but we still recommend to use simple primitive types like:

  • string
  • number
  • boolean
  • null
  • undefined

If you want to use more complex type we recommend to use string and JSON combination.

class and variable naming.

CLI

More details CLI documentation you can read CLI Documentation section.

Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

  • We're heavy really on package.json location and build our path to task from package.json and we assume that this is the project root, when you're using our CLI, hence do development be sure that you have package.json inside your project. Same rules applied when you're running our CLI on server that's why you need to be sure that you have package.json on your server, if you want to use CLI. In case, for some reason you don't have package.json on server - then you can run your tasks with node entrypoint.js command.

Contributing

We welcome contributions! Please read our Contribution Guidelines before submitting a pull request.

Stay in touch

Acknowledgments

  • The @nestjs/cli for providing a solid foundation for Nest.js projects.
  • The class-validator and class-transformer for easy class validation

License

Released under MIT by @polar-rules.

Package Sidebar

Install

npm i @polar-rules/nest-task

Weekly Downloads

2

Version

0.2.0

License

MIT

Unpacked Size

1.33 MB

Total Files

1742

Last publish

Collaborators

  • andrii.drozdov