A lightweight library for writing task oriented scripts.
Uses the following:
npm i task-script-support
This library helps you write task-based scripts and cli apps where you define a series of tasks that run in sequence, each receiving and optionally updating shared state.
Note: see the examples directory for an example in JavaScript.
import { AppState } from "task-script-support";
export interface MyData {
// App data goes here
result?: string;
}
export interface MyArgs {
// CLI arguments
name?: string;
verbose?: boolean;
}
export type MyState = AppState<MyData, MyArgs>;import { Task } from "task-script-support";
import { MyData, MyArgs, MyState } from "./types";
export class GreetTask extends Task<MyData, MyArgs> {
async run(state: MyState): Promise<void | Partial<MyState>> {
const name = state.args.name || "World";
console.log(`Hello ${name}!`);
// Return partial state to merge with existing state
return { data: { result: `Greeted ${name}` } };
}
}
export class LogTask extends Task<MyData, MyArgs> {
async run(state: MyState): Promise<void | Partial<MyState>> {
console.log("Final state:", state);
}
}import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { CommandService } from "task-script-support";
import { GreetTask, LogTask } from "./tasks";
import { MyData, MyArgs } from "./types";
const commandService = new CommandService<MyData, MyArgs>();
// Configure the args provider for yargs
commandService.argsProvider = commandService.argsProvider_Yargs;
const argv = yargs(hideBin(process.argv))
.command(
"greet [name]",
"Greet a user",
(yargs) => {
yargs.positional("name", { default: "User" });
},
commandService.fromTasks([GreetTask, LogTask]),
)
.option("v", { alias: "verbose", type: "boolean" })
.help()
.parse();- Task: Extend the
Taskclass to create reusable task units - run(): Each task implements a
runmethod that receives the current state and optionally returns partial state updates - CommandService: Orchestrates running tasks in sequence, manages state history, and configures argument providers
- State merging: Return
Partial<AppState>from the task's run method to merge updates into the shared state
import commander from "commander";
import { CommandService } from "task-script-support";
import { Task1, Task2, Task3 } from "./tasks";
const commandService = new CommandService<MyData, MyArgs>();
// Configure args provider for commander
commandService.argsProvider = commandService.argsProvider_Commander;
const { program } = commander;
program
.command("mycommand")
.option("-d, --debug", "enable debug mode")
.action(commandService.fromTasks([Task1, Task2, Task3]));
program.parse(process.argv);The library includes built-in logging support via pino:
import { PinoLogger } from "task-script-support";
const pinoLogger = new PinoLogger(/* options */).getLogger();
pinoLogger.info("Starting task...");
pinoLogger.error(new Error("Something went wrong"), "Task failed");Quickstart
# install dependencies
npm i
# set up the git hooks to format on commit
npm run hooks-one-time-setup
# build the project
npm run build
# run the example
cd ./examples/example-1
npm i
npm startUse the following for development:
PINO_LOG_LEVEL=debug
NODE_ENV=development
To build the project, run:
npm run buildThis will compile the TypeScript code and output it to the dist directory.
To lint the code, run:
npm run lintTo format the code using Prettier, run:
npm run formator automatically run formatting on file changes:
npm run prettier-watchTo clean up the project (delete dist folder):
npm run cleanRun the tests:
npm run test
or automatically run them on file changes:
npm run test-watch
Additional Links: