exec
exec runs your CLI. It reads runtime arguments, picks the right command, then runs your callback. If the user passes --help, the matching help output is shown automatically.
Example
ts
import { SC } from "@duplojs/server-utils";
import { DP } from "@duplojs/utils";
await SC.exec(
{
options: [SC.createBooleanOption("version")],
subject: DP.tuple([DP.string(), DP.string()]),
},
({ subject, options }) => {
if (options.version) {
console.log("1.0.0");
return;
}
const [sourcePath, targetPath] = subject;
console.log(`copy ${sourcePath} to ${targetPath}`);
},
);
// Try with:
// cpCli file.txt file-copy.txt
// output: copy file.txt to file-copy.txt
// Other:
// cpCli --version
// output: 1.0.0Syntax
typescript
function exec(
execute: () => void
): Promise<void>
function exec<
GenericOptions extends readonly Option[],
GenericSubject extends Subject
>(
params: CreateCommandParams<GenericOptions, GenericSubject>,
execute: (
params: CreateCommandExecuteParams<GenericOptions, GenericSubject>
) => MaybePromise<void>
): Promise<void>Parameters
execute: root handler called when noparamsobject is provided.params(CreateCommandParams) : command configuration for root.params.description(string, optional) : displayed in help output.params.options(Option[], optional) : option definitions parsed before execute.params.subject(Subject | Command[], optional) : DataParser subject or sub-command list.execute(overload 2) : receives typedoptionsand optional typedsubject.
Return value
Promise<void>: resolves after command dispatch and execution complete.
Other examples
Minimal root command
ts
import { SC } from "@duplojs/server-utils";
await SC.exec(
{
options: [
SC.createBooleanOption(
"verbose",
{ aliases: ["v"] },
),
],
},
({ options }) => {
if (options.verbose) {
console.log("Verbose output enabled");
}
},
);Advanced
ts
import { SC } from "@duplojs/server-utils";
import { DP } from "@duplojs/utils";
const migrateCommand = SC.create(
"migrate",
{
description: "Run database migrations",
options: [
SC.createBooleanOption(
"dryRun",
{
description: "Preview SQL statements without applying changes",
aliases: ["dr"],
},
),
SC.createOption(
"environment",
DP.literal(["dev", "staging", "prod"]),
{ required: true },
),
],
subject: DP.union([
DP.templateLiteral([
"v",
DP.number(),
".",
DP.number(),
".",
DP.number(),
]),
DP.literal("latest"),
]),
},
({ options: { dryRun, environment }, subject: targetVersion }) => {
const mode = dryRun ? "preview" : "apply";
console.log(
`[${environment}] ${mode} migration to ${targetVersion}`,
);
},
);
const seedCommand = SC.create(
"seed",
{
description: "Populate default data",
options: [
SC.createArrayOption(
"tags",
DP.string(),
{ separator: "," },
),
],
},
({ options: { tags } }) => {
console.log("seeding with tags:", tags ?? []);
},
);
await SC.exec(
{
description: "Project CLI entrypoint",
options: [SC.createBooleanOption("verbose", { aliases: ["v"] })],
subject: [migrateCommand, seedCommand],
},
({ options }) => {
if (options.verbose) {
console.log("verbose mode enabled");
}
},
);
// Try with:
// cli migrate --environment=dev 2026-01-10
// cli seed --tags=users,roles
// cli --helpSee also
create- Builds a command node.createBooleanOption- Builds a boolean flag option.createOption- Builds a single-value option.createArrayOption- Builds an array option.
