The ultimate solution to execute simple tasks in Nest.js environment fully supporting import of Nest.js classes, basic tools and approaches.
List tasks:
Call task:
@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.
CJS and ESM.bear) for a more human-friendly and guided experience.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.
Via NPM:
npm install @polar-rules/nest-task
Via Yarn:
yarn add @polar-rules/nest-task
From command line you can call help prompt to receive a list of available commands:
npx nest-task help
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:
nest-cli.json and create new key task theretasks under srcmain.ts and tasks.module.tsexample task for education purposesTo 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
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
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
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.
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"
}
}
}
}
distDirectoryOptional.
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}}
pathRequired.
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.
entryPointRequired.
The main file name entrypoint should be present here, this file should be present with in
directory specified in path key.
conventionsRequired.
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 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.
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 {}
tasksRequired.
Array of Task classes.
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.
nameRequired.
Unique.
Name of the tasks. Should be unique for @Decorators.Module. Used to located task, provider information about the task.
descriptionRequired.
Short description of the task. Even if we do not have any limitation for length, we still recommend to keep it simple as possible.
runnerRequired.
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.
moduleRequired.
Main Nest.js application module is required to correctly initialise Nest.js environment.
providersOptional.
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.
deprecatedOptional.
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
}
}
providersAre matched from @Decorators.Task providers field into constructor by type. The same way as you do with Nest.js.
appBy using @Decorators.App() for an argument you can pass the Nest.js application variable.
loggerBy 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")
argsIf 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:
If you want to use more complex type we recommend to use string and JSON combination.
class and variable naming.
More details CLI documentation you can read CLI Documentation section.
Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.
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.We welcome contributions! Please read our Contribution Guidelines before submitting a pull request.
@nestjs/cli for providing a solid foundation for Nest.js projects.class-validator and class-transformer for easy class validationReleased under MIT by @polar-rules.
Generated using TypeDoc