@stacksjs/buddy 0.70.59 → 0.70.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +162 -4
- package/dist/commands/about.js +35 -0
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +33 -0
- package/dist/commands/auth.js +68 -0
- package/dist/commands/build.js +153 -0
- package/dist/commands/cd.js +39 -0
- package/dist/commands/changelog.js +32 -0
- package/dist/commands/clean.js +37 -0
- package/dist/commands/cloud.js +503 -0
- package/dist/commands/commit.js +16 -0
- package/dist/commands/completion.js +143 -0
- package/dist/commands/config-migrate.js +94 -0
- package/dist/commands/configure.js +48 -0
- package/dist/commands/create.js +137 -0
- package/dist/commands/deploy.js +1404 -0
- package/dist/commands/dev.js +911 -0
- package/dist/commands/dns.js +62 -0
- package/dist/commands/doctor.js +280 -0
- package/dist/commands/domains.js +159 -0
- package/dist/commands/email.js +526 -0
- package/dist/commands/env.js +246 -0
- package/dist/commands/features.js +422 -0
- package/dist/commands/fresh.js +39 -0
- package/dist/commands/generate.js +104 -0
- package/dist/commands/http.js +30 -0
- package/dist/commands/index.js +53 -0
- package/dist/commands/install.js +23 -0
- package/dist/commands/key.js +23 -0
- package/dist/commands/lint.js +50 -0
- package/dist/commands/list.js +108 -0
- package/dist/commands/mail.js +693 -0
- package/dist/commands/maintenance.d.ts +2 -0
- package/dist/commands/maintenance.js +141 -0
- package/dist/commands/make.js +375 -0
- package/dist/commands/migrate-project.js +49 -0
- package/dist/commands/migrate.js +373 -0
- package/dist/commands/outdated.js +19 -0
- package/dist/commands/package.d.ts +2 -0
- package/dist/commands/package.js +17 -0
- package/dist/commands/phone.js +188 -0
- package/dist/commands/ports.js +118 -0
- package/dist/commands/prepublish.js +17 -0
- package/dist/commands/projects.js +29 -0
- package/dist/commands/publish.js +169 -0
- package/dist/commands/queue.js +249 -0
- package/dist/commands/release.js +30 -0
- package/dist/commands/route.js +21 -0
- package/dist/commands/saas.js +25 -0
- package/dist/commands/schedule.js +61 -0
- package/dist/commands/search.js +84 -0
- package/dist/commands/seed.js +71 -0
- package/dist/commands/serve.js +176 -0
- package/dist/commands/setup.js +203 -0
- package/dist/commands/share.d.ts +2 -0
- package/dist/commands/share.js +209 -0
- package/dist/commands/sms.js +328 -0
- package/dist/commands/stacks.d.ts +2 -0
- package/dist/commands/stacks.js +69 -0
- package/dist/commands/telemetry.js +74 -0
- package/dist/commands/test.js +130 -0
- package/dist/commands/tinker.js +37 -0
- package/dist/commands/types.js +18 -0
- package/dist/commands/upgrade.js +97 -0
- package/dist/commands/version.js +16 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +223 -0
- package/dist/custom-cli.d.ts +1 -0
- package/dist/custom-cli.js +23 -0
- package/dist/index.js +1 -3424
- package/dist/lazy-commands.d.ts +61 -0
- package/dist/lazy-commands.js +182 -0
- package/dist/migrators/index.js +62 -0
- package/dist/migrators/laravel/index.js +148 -0
- package/dist/migrators/laravel/migrations.js +231 -0
- package/dist/migrators/laravel/models.js +132 -0
- package/dist/migrators/rails/index.js +11 -0
- package/dist/migrators/types.js +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { $ } from "bun";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { intro, italic, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { ports as projectPorts } from "@stacksjs/config";
|
|
5
|
+
import { log } from "@stacksjs/logging";
|
|
6
|
+
import { findProjectPath, path as p, projectPath } from "@stacksjs/path";
|
|
7
|
+
import { ExitCode } from "@stacksjs/types";
|
|
8
|
+
import { findStacksProjects } from "@stacksjs/utils";
|
|
9
|
+
export function ports(buddy) {
|
|
10
|
+
const descriptions = {
|
|
11
|
+
command: "Let buddy check your project for potential issues and misconfigurations",
|
|
12
|
+
ports: "Check if the ports are available",
|
|
13
|
+
project: "Target a specific project",
|
|
14
|
+
verbose: "Enable verbose output"
|
|
15
|
+
};
|
|
16
|
+
buddy.command("ports", descriptions.command).option("-l, --list", "List the used ports", { default: !0 }).option("-c, --check", "Check if the ports are available", {
|
|
17
|
+
default: !1
|
|
18
|
+
}).option("-p, --project [name]", descriptions.project, {
|
|
19
|
+
default: void 0
|
|
20
|
+
}).option("-q, --quiet", "Use minimal output", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
21
|
+
log.debug("Running `buddy ports` ...", options);
|
|
22
|
+
let perf;
|
|
23
|
+
if (!options.quiet)
|
|
24
|
+
perf = await intro("buddy ports");
|
|
25
|
+
if (options.project) {
|
|
26
|
+
const path = await findProjectPath(options.project);
|
|
27
|
+
log.debug(`Path: ${path}`);
|
|
28
|
+
const ports = await getPortsForProjectPath(path, options);
|
|
29
|
+
log.debug(`./buddy ports --quiet response for ${projectPath}`, ports);
|
|
30
|
+
outputPorts(ports, options);
|
|
31
|
+
} else
|
|
32
|
+
outputPorts(projectPorts, options);
|
|
33
|
+
if (!options.quiet)
|
|
34
|
+
await outro("Exited", { startTime: perf, useSeconds: !1 });
|
|
35
|
+
process.exit(ExitCode.Success);
|
|
36
|
+
});
|
|
37
|
+
buddy.command("ports:list", descriptions.ports).option("-p, --project [name]", descriptions.project, {
|
|
38
|
+
default: void 0
|
|
39
|
+
}).option("-q, --quiet", "Use minimal output", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
40
|
+
log.debug("Running `buddy ports:list` ...", options);
|
|
41
|
+
let perf;
|
|
42
|
+
if (!options.quiet)
|
|
43
|
+
perf = await intro("buddy ports:list");
|
|
44
|
+
if (options.project) {
|
|
45
|
+
if (!options.quiet)
|
|
46
|
+
log.info(`Listing ports for project: ${italic(options.project)}`);
|
|
47
|
+
const path = await findProjectPath(options.project);
|
|
48
|
+
log.debug(`Path: ${path}`);
|
|
49
|
+
const ports = await getPortsForProjectPath(path, options);
|
|
50
|
+
outputPorts(ports, options);
|
|
51
|
+
} else
|
|
52
|
+
outputPorts(projectPorts, options);
|
|
53
|
+
if (!options.quiet)
|
|
54
|
+
await outro("Exited", { startTime: perf, useSeconds: !1 });
|
|
55
|
+
process.exit(ExitCode.Success);
|
|
56
|
+
});
|
|
57
|
+
buddy.command("ports:check", descriptions.ports).option("-p, --project [name]", descriptions.project, {
|
|
58
|
+
default: projectPath()
|
|
59
|
+
}).option("-q, --quiet", "Use minimal output", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
60
|
+
log.debug("Running `buddy ports:check` ...", options);
|
|
61
|
+
let perf;
|
|
62
|
+
if (!options.quiet)
|
|
63
|
+
perf = await intro("buddy ports:check");
|
|
64
|
+
const projects = await findStacksProjects(void 0, { quiet: !0 });
|
|
65
|
+
log.debug("Running `buddy ports`");
|
|
66
|
+
log.debug(`Found ${projects.length} projects`);
|
|
67
|
+
log.debug("Projects:", projects);
|
|
68
|
+
const projectsPorts = {};
|
|
69
|
+
for (const project of projects)
|
|
70
|
+
projectsPorts[project] = await getPortsForProjectPath(project, options);
|
|
71
|
+
log.info("ProjectsPorts:", projectsPorts);
|
|
72
|
+
if (!options.quiet)
|
|
73
|
+
await outro("Exited", { startTime: perf, useSeconds: !1 });
|
|
74
|
+
process.exit(ExitCode.Success);
|
|
75
|
+
});
|
|
76
|
+
onUnknownSubcommand(buddy, "ports");
|
|
77
|
+
}
|
|
78
|
+
async function getPortsForProjectPath(path, options) {
|
|
79
|
+
if (!options.quiet)
|
|
80
|
+
log.info(`Checking ports for project: ${italic(path)}`);
|
|
81
|
+
$.cwd(path);
|
|
82
|
+
try {
|
|
83
|
+
$.env(await import(`${path}/.env`));
|
|
84
|
+
} catch (err) {
|
|
85
|
+
if (!options.quiet)
|
|
86
|
+
log.warn(`[ports] Failed to load ${path}/.env (${err.message}). Falling back to current environment.`);
|
|
87
|
+
}
|
|
88
|
+
const projectList = await $`./buddy projects:list --quiet`.text();
|
|
89
|
+
log.debug("ProjectListResponse", projectList);
|
|
90
|
+
const projects = projectList.split(`
|
|
91
|
+
`).filter((line) => line.startsWith(" - ")).map((line) => line.trim().substring(4));
|
|
92
|
+
log.debug("Projects:", projects);
|
|
93
|
+
const ppath = options.project ?? p.projectPath();
|
|
94
|
+
let projectPath = projects.find((project) => project.includes(ppath));
|
|
95
|
+
log.debug(`Checking ports for project: ${projectPath}`);
|
|
96
|
+
if (projectPath === "" || !projectPath)
|
|
97
|
+
projectPath = p.projectPath();
|
|
98
|
+
log.debug(`$ Running: ./buddy ports:list --quiet via ${projectPath}`);
|
|
99
|
+
const response = await $`./buddy ports:list --quiet`.json();
|
|
100
|
+
log.debug(`Response for ./buddy ports:list --quiet via ${projectPath}`, response);
|
|
101
|
+
let validJsonString = response.replace(/(\w+)(?=\s*:)/g, '"$1"');
|
|
102
|
+
validJsonString = validJsonString.replace(/,(\s*\})/g, "$1");
|
|
103
|
+
let ports;
|
|
104
|
+
try {
|
|
105
|
+
ports = JSON.parse(validJsonString);
|
|
106
|
+
} catch {
|
|
107
|
+
throw Error(`Failed to parse ports configuration: ${validJsonString.slice(0, 200)}`);
|
|
108
|
+
}
|
|
109
|
+
log.debug(`Ports for ${projectPath}`, ports);
|
|
110
|
+
return ports;
|
|
111
|
+
}
|
|
112
|
+
function outputPorts(ports, options) {
|
|
113
|
+
if (!options.quiet)
|
|
114
|
+
console.log("");
|
|
115
|
+
console.log(ports);
|
|
116
|
+
if (!options.quiet)
|
|
117
|
+
console.log("");
|
|
118
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { Action } from "@stacksjs/enums";
|
|
4
|
+
import { log } from "@stacksjs/logging";
|
|
5
|
+
import { onUnknownSubcommand } from "@stacksjs/cli";
|
|
6
|
+
export function prepublish(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
command: "Run your prepublish script",
|
|
9
|
+
project: "Target a specific project",
|
|
10
|
+
verbose: "Enable verbose output"
|
|
11
|
+
};
|
|
12
|
+
buddy.command("prepublish", descriptions.command).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
13
|
+
log.debug("Running `buddy prepublish` ...", options);
|
|
14
|
+
await runAction(Action.Prepublish, options);
|
|
15
|
+
});
|
|
16
|
+
onUnknownSubcommand(buddy, "prepublish");
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { intro, log, onUnknownSubcommand } from "@stacksjs/cli";
|
|
3
|
+
import { ExitCode } from "@stacksjs/types";
|
|
4
|
+
import { findStacksProjects } from "@stacksjs/utils";
|
|
5
|
+
export function projects(buddy) {
|
|
6
|
+
const descriptions = {
|
|
7
|
+
projects: "Find all Stacks projects on your system",
|
|
8
|
+
verbose: "Enable verbose output"
|
|
9
|
+
};
|
|
10
|
+
buddy.command("projects", descriptions.projects).option("-q, --quiet", "Use minimal output", { default: !1 }).option("-l, --list", "List all local Stacks projects", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
11
|
+
log.debug("Running `buddy projects` ...", options);
|
|
12
|
+
if (!options.quiet)
|
|
13
|
+
await intro("buddy projects");
|
|
14
|
+
const projects = await findStacksProjects(void 0, options);
|
|
15
|
+
for (const project of projects)
|
|
16
|
+
console.log(" - ", project);
|
|
17
|
+
process.exit(ExitCode.Success);
|
|
18
|
+
});
|
|
19
|
+
buddy.command("projects:list", descriptions.projects).option("-q, --quiet", "Use minimal output", { default: !1 }).option("-l, --list", "List all local Stacks projects", { default: !0 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
20
|
+
log.debug("Running `buddy projects` ...", options);
|
|
21
|
+
if (!options.quiet)
|
|
22
|
+
await intro("buddy projects:list");
|
|
23
|
+
const projects = await findStacksProjects(void 0, options);
|
|
24
|
+
for (const project of projects)
|
|
25
|
+
console.log(" - ", project);
|
|
26
|
+
process.exit(ExitCode.Success);
|
|
27
|
+
});
|
|
28
|
+
onUnknownSubcommand(buddy, "projects");
|
|
29
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { cp, readdir, stat } from "node:fs/promises";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { italic, log, onUnknownSubcommand } from "@stacksjs/cli";
|
|
6
|
+
import { path } from "@stacksjs/path";
|
|
7
|
+
import { fs, globSync } from "@stacksjs/storage";
|
|
8
|
+
import { ExitCode } from "@stacksjs/types";
|
|
9
|
+
export function publish(buddy) {
|
|
10
|
+
const descriptions = {
|
|
11
|
+
command: "Publish a Stacks default into your userland (app/) directory so you can customize it",
|
|
12
|
+
model: "Publish a default model from storage/framework/defaults/app/Models/ to app/Models/",
|
|
13
|
+
controller: "Publish a default controller from storage/framework/defaults/app/Controllers/ to app/Controllers/",
|
|
14
|
+
middleware: "Publish a default middleware from storage/framework/defaults/app/Middleware/ to app/Middleware/",
|
|
15
|
+
action: "Publish a default action from storage/framework/defaults/app/Actions/ to app/Actions/",
|
|
16
|
+
core: "Publish a framework package source from node_modules/@stacksjs/<pkg>/ into storage/framework/core/<pkg>/ for editing",
|
|
17
|
+
name: "The name of the resource to publish (e.g. Cart, User)",
|
|
18
|
+
pkg: "The name of the framework package (e.g. router, orm, faker \u2014 without @stacksjs/ prefix)",
|
|
19
|
+
force: "Overwrite an existing userland file",
|
|
20
|
+
verbose: "Enable verbose output"
|
|
21
|
+
};
|
|
22
|
+
buddy.command("publish:model <name>", descriptions.model).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
|
|
23
|
+
await publishResource({
|
|
24
|
+
kind: "model",
|
|
25
|
+
name,
|
|
26
|
+
defaultsDir: path.frameworkPath("defaults/app/Models"),
|
|
27
|
+
userDir: path.userModelsPath(),
|
|
28
|
+
force: !!options.force
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
buddy.command("publish:controller <name>", descriptions.controller).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
|
|
32
|
+
await publishResource({
|
|
33
|
+
kind: "controller",
|
|
34
|
+
name,
|
|
35
|
+
defaultsDir: path.frameworkPath("defaults/app/Controllers"),
|
|
36
|
+
userDir: path.userControllersPath(),
|
|
37
|
+
force: !!options.force
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
buddy.command("publish:middleware <name>", descriptions.middleware).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
|
|
41
|
+
await publishResource({
|
|
42
|
+
kind: "middleware",
|
|
43
|
+
name,
|
|
44
|
+
defaultsDir: path.frameworkPath("defaults/app/Middleware"),
|
|
45
|
+
userDir: path.userMiddlewarePath(),
|
|
46
|
+
force: !!options.force
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
buddy.command("publish:action <name>", descriptions.action).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
|
|
50
|
+
await publishResource({
|
|
51
|
+
kind: "action",
|
|
52
|
+
name,
|
|
53
|
+
defaultsDir: path.frameworkPath("defaults/app/Actions"),
|
|
54
|
+
userDir: path.userActionsPath(),
|
|
55
|
+
force: !!options.force
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
buddy.command("publish:core <pkg>", descriptions.core).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (pkg, options) => {
|
|
59
|
+
await publishCorePackage(pkg, !!options.force);
|
|
60
|
+
});
|
|
61
|
+
buddy.command("publish [resource] [name]", descriptions.command).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (resource, name, options) => {
|
|
62
|
+
if (!resource || !name) {
|
|
63
|
+
log.error("Usage: buddy publish:<resource> <Name> (e.g. buddy publish:model Cart)");
|
|
64
|
+
process.exit(ExitCode.FatalError);
|
|
65
|
+
}
|
|
66
|
+
const handler = {
|
|
67
|
+
model: () => publishResource({
|
|
68
|
+
kind: "model",
|
|
69
|
+
name,
|
|
70
|
+
defaultsDir: path.frameworkPath("defaults/app/Models"),
|
|
71
|
+
userDir: path.userModelsPath(),
|
|
72
|
+
force: !!options.force
|
|
73
|
+
}),
|
|
74
|
+
controller: () => publishResource({
|
|
75
|
+
kind: "controller",
|
|
76
|
+
name,
|
|
77
|
+
defaultsDir: path.frameworkPath("defaults/app/Controllers"),
|
|
78
|
+
userDir: path.userControllersPath(),
|
|
79
|
+
force: !!options.force
|
|
80
|
+
}),
|
|
81
|
+
middleware: () => publishResource({
|
|
82
|
+
kind: "middleware",
|
|
83
|
+
name,
|
|
84
|
+
defaultsDir: path.frameworkPath("defaults/app/Middleware"),
|
|
85
|
+
userDir: path.userMiddlewarePath(),
|
|
86
|
+
force: !!options.force
|
|
87
|
+
}),
|
|
88
|
+
action: () => publishResource({
|
|
89
|
+
kind: "action",
|
|
90
|
+
name,
|
|
91
|
+
defaultsDir: path.frameworkPath("defaults/app/Actions"),
|
|
92
|
+
userDir: path.userActionsPath(),
|
|
93
|
+
force: !!options.force
|
|
94
|
+
}),
|
|
95
|
+
core: () => publishCorePackage(name, !!options.force)
|
|
96
|
+
}[resource.toLowerCase()];
|
|
97
|
+
if (!handler) {
|
|
98
|
+
log.error(`Unknown publishable resource: ${italic(resource)}`);
|
|
99
|
+
log.info("Available: model, controller, middleware, action, core");
|
|
100
|
+
process.exit(ExitCode.FatalError);
|
|
101
|
+
}
|
|
102
|
+
await handler();
|
|
103
|
+
});
|
|
104
|
+
onUnknownSubcommand(buddy, "publish");
|
|
105
|
+
}
|
|
106
|
+
async function publishCorePackage(pkg, force) {
|
|
107
|
+
const shortName = pkg.replace(/^@stacksjs\//, "").replace(/^core\//, ""), fail = (msg, hint) => {
|
|
108
|
+
process.stderr.write(`${msg}
|
|
109
|
+
`);
|
|
110
|
+
if (hint)
|
|
111
|
+
process.stderr.write(` ${hint}
|
|
112
|
+
`);
|
|
113
|
+
process.exit(ExitCode.FatalError);
|
|
114
|
+
};
|
|
115
|
+
if (!shortName || shortName.includes("/") || shortName.includes(".."))
|
|
116
|
+
fail(`Invalid package name: ${pkg}`, "Use a short name like `router` or the fully qualified `@stacksjs/router`.");
|
|
117
|
+
const sourceDir = resolve(process.cwd(), "node_modules", "@stacksjs", shortName), targetDir = path.frameworkPath(`core/${shortName}`);
|
|
118
|
+
try {
|
|
119
|
+
if (!(await stat(sourceDir)).isDirectory())
|
|
120
|
+
fail(`${sourceDir} is not a directory.`);
|
|
121
|
+
} catch {
|
|
122
|
+
fail(`Could not find @stacksjs/${shortName} in node_modules.`, "Run `bun install` first, or check the package name.");
|
|
123
|
+
}
|
|
124
|
+
if (existsSync(targetDir) && !force)
|
|
125
|
+
fail(`Already published: ${targetDir.replace(`${process.cwd()}/`, "")}`, "Pass --force to overwrite.");
|
|
126
|
+
mkdirSync(dirname(targetDir), { recursive: !0 });
|
|
127
|
+
const SKIP = new Set(["node_modules", "dist", ".bun", ".cache", "tsconfig.tsbuildinfo"]);
|
|
128
|
+
let copied = 0;
|
|
129
|
+
await copyTreeFiltered(sourceDir, targetDir, SKIP, () => copied++);
|
|
130
|
+
log.success(`Published @stacksjs/${shortName} \u2192 ${italic(targetDir.replace(`${process.cwd()}/`, ""))} (${copied} files)`);
|
|
131
|
+
log.info("Edit freely \u2014 local changes win over the installed package.");
|
|
132
|
+
}
|
|
133
|
+
async function copyTreeFiltered(sourceDir, targetDir, skip, onFile) {
|
|
134
|
+
mkdirSync(targetDir, { recursive: !0 });
|
|
135
|
+
const entries = await readdir(sourceDir, { withFileTypes: !0 });
|
|
136
|
+
for (const entry of entries) {
|
|
137
|
+
if (skip.has(entry.name))
|
|
138
|
+
continue;
|
|
139
|
+
const src = `${sourceDir}/${entry.name}`, dst = `${targetDir}/${entry.name}`;
|
|
140
|
+
if (entry.isDirectory()) {
|
|
141
|
+
await copyTreeFiltered(src, dst, skip, onFile);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
await cp(src, dst, { force: !0, dereference: !0 });
|
|
145
|
+
onFile();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function publishResource(ctx) {
|
|
149
|
+
const { kind, name, defaultsDir, userDir, force } = ctx, fileName = name.endsWith(".ts") ? name : `${name}.ts`, matches = globSync([`${defaultsDir}/**/${fileName}`], { absolute: !0 });
|
|
150
|
+
if (!matches.length) {
|
|
151
|
+
log.error(`Could not find default ${kind}: ${italic(fileName)}`);
|
|
152
|
+
log.info(`Looked under: ${italic(defaultsDir)}`);
|
|
153
|
+
process.exit(ExitCode.FatalError);
|
|
154
|
+
}
|
|
155
|
+
if (matches.length > 1) {
|
|
156
|
+
log.warn(`Multiple defaults match ${italic(fileName)}; using the first:`);
|
|
157
|
+
for (const m of matches)
|
|
158
|
+
log.info(` ${m}`);
|
|
159
|
+
}
|
|
160
|
+
const sourcePath = matches[0], targetPath = `${userDir.replace(/\/$/, "")}/${fileName}`;
|
|
161
|
+
if (existsSync(targetPath) && !force) {
|
|
162
|
+
log.error(`Already exists: ${italic(targetPath)}`);
|
|
163
|
+
log.info("Pass --force to overwrite.");
|
|
164
|
+
process.exit(ExitCode.FatalError);
|
|
165
|
+
}
|
|
166
|
+
mkdirSync(dirname(targetPath), { recursive: !0 });
|
|
167
|
+
await fs.promises.copyFile(sourcePath, targetPath);
|
|
168
|
+
log.success(`Published ${kind} ${italic(name)} \u2192 ${italic(targetPath.replace(`${process.cwd()}/`, ""))}`);
|
|
169
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { Action } from "@stacksjs/enums";
|
|
5
|
+
import { ExitCode } from "@stacksjs/types";
|
|
6
|
+
export function queue(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
project: "Target a specific project",
|
|
9
|
+
queue: "Specify queue name",
|
|
10
|
+
verbose: "Enable verbose output",
|
|
11
|
+
id: "Job or batch ID",
|
|
12
|
+
all: "Apply to all items",
|
|
13
|
+
force: "Force the operation without confirmation",
|
|
14
|
+
connection: "Queue connection to use",
|
|
15
|
+
concurrency: "Number of concurrent workers"
|
|
16
|
+
};
|
|
17
|
+
buddy.command("queue:work", "Start processing jobs on the queue").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("-c, --connection [connection]", descriptions.connection, { default: !1 }).option("--concurrency [concurrency]", descriptions.concurrency, { default: "1" }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
18
|
+
log.debug("Running `buddy queue:work` ...", options);
|
|
19
|
+
const SHUTDOWN_GRACE_MS = 1e4;
|
|
20
|
+
let shuttingDown = !1;
|
|
21
|
+
const cleanup = (signal) => {
|
|
22
|
+
if (shuttingDown)
|
|
23
|
+
return;
|
|
24
|
+
shuttingDown = !0;
|
|
25
|
+
log.info(`[queue] Received ${signal}, draining workers (max ${SHUTDOWN_GRACE_MS / 1000}s)\u2026`);
|
|
26
|
+
import("@stacksjs/queue").then(({ stopProcessor }) => stopProcessor({ graceMs: SHUTDOWN_GRACE_MS })).catch((error) => log.error("[queue] stopProcessor failed", error));
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
log.warn("[queue] Drain timeout exceeded \u2014 forcing shutdown.");
|
|
29
|
+
process.exit(ExitCode.FatalError);
|
|
30
|
+
}, SHUTDOWN_GRACE_MS).unref();
|
|
31
|
+
};
|
|
32
|
+
process.on("SIGINT", () => cleanup("SIGINT"));
|
|
33
|
+
process.on("SIGTERM", () => cleanup("SIGTERM"));
|
|
34
|
+
const perf = await intro("buddy queue:work"), result = await runAction(Action.QueueWork, options);
|
|
35
|
+
if (result.isErr) {
|
|
36
|
+
await outro("While running the queue:work command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
37
|
+
process.exit(ExitCode.FatalError);
|
|
38
|
+
}
|
|
39
|
+
process.exit(ExitCode.Success);
|
|
40
|
+
});
|
|
41
|
+
buddy.command("queue:failed", "List all failed jobs").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--since [duration]", "Only show jobs failed since (e.g. 1h, 30m, 2d)", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
42
|
+
log.debug("Running `buddy queue:failed` ...", options);
|
|
43
|
+
const perf = await intro("buddy queue:failed"), result = await runAction(Action.QueueFailed, options);
|
|
44
|
+
if (result.isErr) {
|
|
45
|
+
await outro("While running the queue:failed command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
46
|
+
process.exit(ExitCode.FatalError);
|
|
47
|
+
}
|
|
48
|
+
await outro("Listed all failed jobs", {
|
|
49
|
+
startTime: perf,
|
|
50
|
+
useSeconds: !0
|
|
51
|
+
});
|
|
52
|
+
process.exit(ExitCode.Success);
|
|
53
|
+
});
|
|
54
|
+
buddy.command("queue:retry [id]", "Retry failed jobs").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--all", descriptions.all, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (id, options) => {
|
|
55
|
+
log.debug("Running `buddy queue:retry` ...", options);
|
|
56
|
+
const perf = await intro("buddy queue:retry"), result = await runAction(Action.QueueRetry, { ...options, id });
|
|
57
|
+
if (result.isErr) {
|
|
58
|
+
await outro("While running the queue:retry command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
59
|
+
process.exit(ExitCode.FatalError);
|
|
60
|
+
}
|
|
61
|
+
const message = options.all ? "Retried all failed jobs" : `Retried failed job ${id}`;
|
|
62
|
+
await outro(message, {
|
|
63
|
+
startTime: perf,
|
|
64
|
+
useSeconds: !0
|
|
65
|
+
});
|
|
66
|
+
process.exit(ExitCode.Success);
|
|
67
|
+
});
|
|
68
|
+
buddy.command("queue:clear", "Clear all jobs from the queue").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
69
|
+
log.debug("Running `buddy queue:clear` ...", options);
|
|
70
|
+
const perf = await intro("buddy queue:clear"), result = await runAction(Action.QueueClear, options);
|
|
71
|
+
if (result.isErr) {
|
|
72
|
+
await outro("While running the queue:clear command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
73
|
+
process.exit(ExitCode.FatalError);
|
|
74
|
+
}
|
|
75
|
+
const queueName = options.queue || "default";
|
|
76
|
+
await outro(`Cleared all jobs from the "${queueName}" queue`, {
|
|
77
|
+
startTime: perf,
|
|
78
|
+
useSeconds: !0
|
|
79
|
+
});
|
|
80
|
+
process.exit(ExitCode.Success);
|
|
81
|
+
});
|
|
82
|
+
buddy.command("queue:list", "List queued jobs (flat row view, filterable by queue/status)").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--status [status]", "Filter by pending | reserved | delayed", { default: !1 }).option("--limit [limit]", "Maximum rows to display (default 50)", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
83
|
+
log.debug("Running `buddy queue:list` ...", options);
|
|
84
|
+
const perf = await intro("buddy queue:list"), result = await runAction(Action.QueueList, options);
|
|
85
|
+
if (result.isErr) {
|
|
86
|
+
await outro("While running the queue:list command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
87
|
+
process.exit(ExitCode.FatalError);
|
|
88
|
+
}
|
|
89
|
+
await outro("Listed queued jobs", {
|
|
90
|
+
startTime: perf,
|
|
91
|
+
useSeconds: !0
|
|
92
|
+
});
|
|
93
|
+
process.exit(ExitCode.Success);
|
|
94
|
+
});
|
|
95
|
+
buddy.command("queue:status", "Display the status of queue workers").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
96
|
+
log.debug("Running `buddy queue:status` ...", options);
|
|
97
|
+
const perf = await intro("buddy queue:status"), result = await runAction(Action.QueueStatus, options);
|
|
98
|
+
if (result.isErr) {
|
|
99
|
+
await outro("While running the queue:status command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
100
|
+
process.exit(ExitCode.FatalError);
|
|
101
|
+
}
|
|
102
|
+
await outro("Queue status displayed", {
|
|
103
|
+
startTime: perf,
|
|
104
|
+
useSeconds: !0
|
|
105
|
+
});
|
|
106
|
+
process.exit(ExitCode.Success);
|
|
107
|
+
});
|
|
108
|
+
buddy.command("queue:flush", "Delete all failed jobs").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
109
|
+
log.debug("Running `buddy queue:flush` ...", options);
|
|
110
|
+
const perf = await intro("buddy queue:flush"), result = await runAction(Action.QueueFlush, options);
|
|
111
|
+
if (result.isErr) {
|
|
112
|
+
await outro("While running the queue:flush command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
113
|
+
process.exit(ExitCode.FatalError);
|
|
114
|
+
}
|
|
115
|
+
await outro("Flushed all failed jobs", {
|
|
116
|
+
startTime: perf,
|
|
117
|
+
useSeconds: !0
|
|
118
|
+
});
|
|
119
|
+
process.exit(ExitCode.Success);
|
|
120
|
+
});
|
|
121
|
+
buddy.command("queue:dlq", "List dead-letter jobs (jobs that re-failed after retry)").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("--reason [reason]", "Filter by reason (repeat-failure | poison-detected | circuit-broken | manual)", { default: !1 }).option("--since [duration]", "Only show rows dead-lettered since (e.g. 1h, 30m, 2d)", { default: !1 }).option("--limit [limit]", "Maximum rows to display (default 100)", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
122
|
+
log.debug("Running `buddy queue:dlq` ...", options);
|
|
123
|
+
const perf = await intro("buddy queue:dlq"), result = await runAction(Action.QueueDlq, options);
|
|
124
|
+
if (result.isErr) {
|
|
125
|
+
await outro("While running queue:dlq there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
126
|
+
process.exit(ExitCode.FatalError);
|
|
127
|
+
}
|
|
128
|
+
await outro("Listed dead-letter jobs", { startTime: perf, useSeconds: !0 });
|
|
129
|
+
process.exit(ExitCode.Success);
|
|
130
|
+
});
|
|
131
|
+
buddy.command("queue:dlq:retry", "Re-enqueue a dead-letter job back into its queue").option("--id [id]", "Dead-letter row id to retry", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
132
|
+
log.debug("Running `buddy queue:dlq:retry` ...", options);
|
|
133
|
+
const perf = await intro("buddy queue:dlq:retry"), result = await runAction(Action.QueueDlqRetry, options);
|
|
134
|
+
if (result.isErr) {
|
|
135
|
+
await outro("While running queue:dlq:retry there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
136
|
+
process.exit(ExitCode.FatalError);
|
|
137
|
+
}
|
|
138
|
+
await outro("Re-enqueued dead-letter job", { startTime: perf, useSeconds: !0 });
|
|
139
|
+
process.exit(ExitCode.Success);
|
|
140
|
+
});
|
|
141
|
+
buddy.command("queue:dlq:purge", "Delete dead-letter rows older than a retention window").option("--older-than-days [days]", "Retention window in days (default 30)", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
142
|
+
log.debug("Running `buddy queue:dlq:purge` ...", options);
|
|
143
|
+
const perf = await intro("buddy queue:dlq:purge"), result = await runAction(Action.QueueDlqPurge, options);
|
|
144
|
+
if (result.isErr) {
|
|
145
|
+
await outro("While running queue:dlq:purge there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
146
|
+
process.exit(ExitCode.FatalError);
|
|
147
|
+
}
|
|
148
|
+
await outro("Purged dead-letter rows", { startTime: perf, useSeconds: !0 });
|
|
149
|
+
process.exit(ExitCode.Success);
|
|
150
|
+
});
|
|
151
|
+
buddy.command("queue:quarantine", "List quarantined jobs (or --add a manual quarantine)").option("--add [jobName]", "Manually quarantine a job class", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
152
|
+
log.debug("Running `buddy queue:quarantine` ...", options);
|
|
153
|
+
const perf = await intro("buddy queue:quarantine"), result = await runAction(Action.QueueQuarantine, options);
|
|
154
|
+
if (result.isErr) {
|
|
155
|
+
await outro("While running queue:quarantine there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
156
|
+
process.exit(ExitCode.FatalError);
|
|
157
|
+
}
|
|
158
|
+
await outro("queue:quarantine done", { startTime: perf, useSeconds: !0 });
|
|
159
|
+
process.exit(ExitCode.Success);
|
|
160
|
+
});
|
|
161
|
+
buddy.command("queue:unquarantine", "Lift the quarantine on a job class").option("--name [name]", "Job class name to unquarantine", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
162
|
+
log.debug("Running `buddy queue:unquarantine` ...", options);
|
|
163
|
+
const perf = await intro("buddy queue:unquarantine"), result = await runAction(Action.QueueUnquarantine, options);
|
|
164
|
+
if (result.isErr) {
|
|
165
|
+
await outro("While running queue:unquarantine there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
166
|
+
process.exit(ExitCode.FatalError);
|
|
167
|
+
}
|
|
168
|
+
await outro("Unquarantined", { startTime: perf, useSeconds: !0 });
|
|
169
|
+
process.exit(ExitCode.Success);
|
|
170
|
+
});
|
|
171
|
+
buddy.command("queue:pause", "Manually pause a queue (circuit-breaker)").option("--queue [name]", "Queue name to pause", { default: !1 }).option("--for [seconds]", "Pause duration in seconds (default 300)", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
172
|
+
log.debug("Running `buddy queue:pause` ...", options);
|
|
173
|
+
const perf = await intro("buddy queue:pause"), result = await runAction(Action.QueuePause, options);
|
|
174
|
+
if (result.isErr) {
|
|
175
|
+
await outro("While running queue:pause there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
176
|
+
process.exit(ExitCode.FatalError);
|
|
177
|
+
}
|
|
178
|
+
await outro("Paused queue", { startTime: perf, useSeconds: !0 });
|
|
179
|
+
process.exit(ExitCode.Success);
|
|
180
|
+
});
|
|
181
|
+
buddy.command("queue:resume", "Resume a paused queue (circuit-breaker)").option("--queue [name]", "Queue name to resume", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
182
|
+
log.debug("Running `buddy queue:resume` ...", options);
|
|
183
|
+
const perf = await intro("buddy queue:resume"), result = await runAction(Action.QueueResume, options);
|
|
184
|
+
if (result.isErr) {
|
|
185
|
+
await outro("While running queue:resume there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
186
|
+
process.exit(ExitCode.FatalError);
|
|
187
|
+
}
|
|
188
|
+
await outro("Resumed queue", { startTime: perf, useSeconds: !0 });
|
|
189
|
+
process.exit(ExitCode.Success);
|
|
190
|
+
});
|
|
191
|
+
buddy.command("queue:table", "Create a migration for the jobs database table").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
192
|
+
log.debug("Running `buddy queue:table` ...", options);
|
|
193
|
+
const perf = await intro("buddy queue:table"), result = await runAction(Action.QueueTable, options);
|
|
194
|
+
if (result.isErr) {
|
|
195
|
+
await outro("While running the queue:table command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
196
|
+
process.exit(ExitCode.FatalError);
|
|
197
|
+
}
|
|
198
|
+
await outro("Jobs table migration created", {
|
|
199
|
+
startTime: perf,
|
|
200
|
+
useSeconds: !0
|
|
201
|
+
});
|
|
202
|
+
process.exit(ExitCode.Success);
|
|
203
|
+
});
|
|
204
|
+
buddy.command("queue:monitor", "Monitor queue status in real-time").option("-p, --project [project]", descriptions.project, { default: !1 }).option("-q, --queue [queue]", descriptions.queue, { default: !1 }).option("-i, --interval [interval]", "Refresh interval in milliseconds", { default: "2000" }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
205
|
+
log.debug("Running `buddy queue:monitor` ...", options);
|
|
206
|
+
const result = await runAction(Action.QueueMonitor, options);
|
|
207
|
+
if (result.isErr) {
|
|
208
|
+
log.error("While running the queue:monitor command, there was an issue", result.error);
|
|
209
|
+
process.exit(ExitCode.FatalError);
|
|
210
|
+
}
|
|
211
|
+
process.exit(ExitCode.Success);
|
|
212
|
+
});
|
|
213
|
+
buddy.command("queue:inspect [id]", "Inspect a specific job").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--failed", "Inspect a failed job", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (id, options) => {
|
|
214
|
+
log.debug("Running `buddy queue:inspect` ...", options);
|
|
215
|
+
const perf = await intro("buddy queue:inspect"), result = await runAction(Action.QueueInspect, { ...options, id });
|
|
216
|
+
if (result.isErr) {
|
|
217
|
+
await outro("While running the queue:inspect command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
218
|
+
process.exit(ExitCode.FatalError);
|
|
219
|
+
}
|
|
220
|
+
await outro("Job inspection complete", {
|
|
221
|
+
startTime: perf,
|
|
222
|
+
useSeconds: !0
|
|
223
|
+
});
|
|
224
|
+
process.exit(ExitCode.Success);
|
|
225
|
+
});
|
|
226
|
+
buddy.command("queue:schedule", "Start the job scheduler for cron-based jobs").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
227
|
+
log.debug("Running `buddy queue:schedule` ...", options);
|
|
228
|
+
const result = await runAction(Action.QueueSchedule, options);
|
|
229
|
+
if (result.isErr) {
|
|
230
|
+
log.error("While running the queue:schedule command, there was an issue", result.error);
|
|
231
|
+
process.exit(ExitCode.FatalError);
|
|
232
|
+
}
|
|
233
|
+
process.exit(ExitCode.Success);
|
|
234
|
+
});
|
|
235
|
+
buddy.command("queue:schedule:list", "List all scheduled jobs").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
236
|
+
log.debug("Running `buddy queue:schedule:list` ...", options);
|
|
237
|
+
const perf = await intro("buddy queue:schedule:list"), result = await runAction(Action.QueueScheduleList, options);
|
|
238
|
+
if (result.isErr) {
|
|
239
|
+
await outro("While running the queue:schedule:list command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
240
|
+
process.exit(ExitCode.FatalError);
|
|
241
|
+
}
|
|
242
|
+
await outro("Listed all scheduled jobs", {
|
|
243
|
+
startTime: perf,
|
|
244
|
+
useSeconds: !0
|
|
245
|
+
});
|
|
246
|
+
process.exit(ExitCode.Success);
|
|
247
|
+
});
|
|
248
|
+
onUnknownSubcommand(buddy, "queue");
|
|
249
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { intro, italic, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { Action } from "@stacksjs/enums";
|
|
5
|
+
import { ExitCode } from "@stacksjs/types";
|
|
6
|
+
const descriptions = {
|
|
7
|
+
release: "Release a new version of your libraries/packages",
|
|
8
|
+
project: "Target a specific project",
|
|
9
|
+
dryRun: "Run the release without actually releasing",
|
|
10
|
+
bump: "Non-interactive bump: patch | minor | major | prepatch | preminor | premajor | prerelease | x.y.z",
|
|
11
|
+
verbose: "Enable verbose output"
|
|
12
|
+
};
|
|
13
|
+
export function release(buddy) {
|
|
14
|
+
buddy.command("release", descriptions.release).option("--dry-run", descriptions.dryRun, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--bump <type>", descriptions.bump).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
15
|
+
log.debug("Running `buddy release` ...", options);
|
|
16
|
+
if (options.dryRun)
|
|
17
|
+
log.warn("Dry run enabled. No changes will be made or committed.");
|
|
18
|
+
const startTime = await intro("buddy release"), result = await runAction(Action.Release, options);
|
|
19
|
+
if (result.isErr) {
|
|
20
|
+
log.error("Failed to release", result.error);
|
|
21
|
+
process.exit(ExitCode.FatalError);
|
|
22
|
+
}
|
|
23
|
+
await outro("Triggered CI/CD Release via GitHub Actions", {
|
|
24
|
+
startTime,
|
|
25
|
+
useSeconds: !0
|
|
26
|
+
});
|
|
27
|
+
log.info(`Follow along: ${italic("https://github.com/stacksjs/stacks/actions")}`);
|
|
28
|
+
});
|
|
29
|
+
onUnknownSubcommand(buddy, "release");
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { intro, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { Action } from "@stacksjs/enums";
|
|
5
|
+
import { ExitCode } from "@stacksjs/types";
|
|
6
|
+
export function route(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
route: "Lists your routes",
|
|
9
|
+
verbose: "Enable verbose output"
|
|
10
|
+
};
|
|
11
|
+
buddy.command("route:list", descriptions.route).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
12
|
+
const perf = await intro("buddy route:list"), result = await runAction(Action.RouteList, options);
|
|
13
|
+
if (result.isErr) {
|
|
14
|
+
await outro("While running the route:list command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
15
|
+
process.exit(ExitCode.FatalError);
|
|
16
|
+
}
|
|
17
|
+
await outro("Successfully listed routes");
|
|
18
|
+
process.exit(ExitCode.Success);
|
|
19
|
+
});
|
|
20
|
+
onUnknownSubcommand(buddy, "route");
|
|
21
|
+
}
|