import { styleText } from "node:util"; import { createLogger, exec, termost } from "termost"; import package_ from "../package.json" with { type: "json" }; type ProgramContext = { computedFromOtherTaskValues: "big" | "small"; execOutput: string; size: number; }; const logger = createLogger({ name: "task", level: "debug", }); const program = termost({ name: package_.name, description: "Example to showcase the `task` API", version: package_.version, }); program .task({ key: "size", label: "Task with returned value (persisted)", handler() { return 45; }, }) .task({ label: "Task with side-effect only (no persisted value)", async handler() { // @note: side-effect only handler await wait(500); }, }) .task({ key: "computedFromOtherTaskValues", label: "Task can also access other persisted task values", handler(context) { if (context.size > 2000) { return "big" as const; } return "small" as const; }, validate({ computedFromOtherTaskValues }) { if (computedFromOtherTaskValues === "big") { return new Error("Invalid input"); } return undefined; }, }) .task({ key: "execOutput", label: "Or even execute external commands thanks to its provided helpers", async handler() { return exec("echo 'Hello from shell'"); }, }) .task({ label: "A task can be skipped as well", async handler() { await wait(2000); }, skip(context) { const isNeedOptimization = context.size > 2000; return !isNeedOptimization; }, }) .task({ label: (context) => { return `A task can have a dynamic label generated from contextual values: ${context.computedFromOtherTaskValues}`; }, handler() { // No op }, }) .task({ handler(context) { logger.info( 'If you don\'t specify a label, the handler is executed in "live mode" (the output is not hidden by the label and is displayed gradually).', ); logger.info( `A task with a specified "key" can be retrieved here. Size = ${context.size}. If no "key" was specified the task returned value cannot be persisted across program instructions.`, ); }, }) .task({ handler(context) { const content = "The logger helper can be used to display task content in a nice way"; logger.debug(content); logger.info(content); logger.warn(content); logger.error(content); logger.success(content); logger.info("👋 You can also namespace the logger name"); console.log( styleText( "cyan", `\nYou can also have a total control on the formatting through \`styleText\` from \`node:util\`.\n${JSON.stringify(context, undefined, 2)}`, ), ); }, }); const wait = async (delay: number) => { return new Promise((resolve) => { setTimeout(resolve, delay); }); };