@dokploy/cli 0.2.3
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/README.md +112 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +6 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/dist/commands/app/create.d.ts +13 -0
- package/dist/commands/app/create.js +77 -0
- package/dist/commands/app/delete.d.ts +9 -0
- package/dist/commands/app/delete.js +84 -0
- package/dist/commands/app/deploy.d.ts +6 -0
- package/dist/commands/app/deploy.js +69 -0
- package/dist/commands/app/stop.d.ts +6 -0
- package/dist/commands/app/stop.js +69 -0
- package/dist/commands/authenticate.d.ts +10 -0
- package/dist/commands/authenticate.js +79 -0
- package/dist/commands/database/mariadb/create.d.ts +9 -0
- package/dist/commands/database/mariadb/create.js +105 -0
- package/dist/commands/database/mariadb/delete.d.ts +9 -0
- package/dist/commands/database/mariadb/delete.js +95 -0
- package/dist/commands/database/mariadb/deploy.d.ts +6 -0
- package/dist/commands/database/mariadb/deploy.js +69 -0
- package/dist/commands/database/mariadb/stop.d.ts +6 -0
- package/dist/commands/database/mariadb/stop.js +69 -0
- package/dist/commands/database/mongo/create.d.ts +9 -0
- package/dist/commands/database/mongo/create.js +107 -0
- package/dist/commands/database/mongo/delete.d.ts +9 -0
- package/dist/commands/database/mongo/delete.js +95 -0
- package/dist/commands/database/mongo/deploy.d.ts +6 -0
- package/dist/commands/database/mongo/deploy.js +69 -0
- package/dist/commands/database/mongo/stop.d.ts +6 -0
- package/dist/commands/database/mongo/stop.js +69 -0
- package/dist/commands/database/mysql/create.d.ts +9 -0
- package/dist/commands/database/mysql/create.js +112 -0
- package/dist/commands/database/mysql/delete.d.ts +9 -0
- package/dist/commands/database/mysql/delete.js +97 -0
- package/dist/commands/database/mysql/deploy.d.ts +6 -0
- package/dist/commands/database/mysql/deploy.js +69 -0
- package/dist/commands/database/mysql/stop.d.ts +6 -0
- package/dist/commands/database/mysql/stop.js +69 -0
- package/dist/commands/database/postgres/create.d.ts +9 -0
- package/dist/commands/database/postgres/create.js +107 -0
- package/dist/commands/database/postgres/delete.d.ts +9 -0
- package/dist/commands/database/postgres/delete.js +94 -0
- package/dist/commands/database/postgres/deploy.d.ts +6 -0
- package/dist/commands/database/postgres/deploy.js +69 -0
- package/dist/commands/database/postgres/stop.d.ts +6 -0
- package/dist/commands/database/postgres/stop.js +69 -0
- package/dist/commands/database/redis/create.d.ts +9 -0
- package/dist/commands/database/redis/create.js +95 -0
- package/dist/commands/database/redis/delete.d.ts +9 -0
- package/dist/commands/database/redis/delete.js +96 -0
- package/dist/commands/database/redis/deploy.d.ts +6 -0
- package/dist/commands/database/redis/deploy.js +69 -0
- package/dist/commands/database/redis/stop.d.ts +6 -0
- package/dist/commands/database/redis/stop.js +69 -0
- package/dist/commands/project/create.d.ts +10 -0
- package/dist/commands/project/create.js +74 -0
- package/dist/commands/project/info.d.ts +10 -0
- package/dist/commands/project/info.js +122 -0
- package/dist/commands/project/list.d.ts +6 -0
- package/dist/commands/project/list.js +43 -0
- package/dist/commands/verify.d.ts +6 -0
- package/dist/commands/verify.js +45 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/utils/http.d.ts +4 -0
- package/dist/utils/http.js +4 -0
- package/dist/utils/shared.d.ts +10 -0
- package/dist/utils/shared.js +55 -0
- package/dist/utils/slug.d.ts +1 -0
- package/dist/utils/slug.js +12 -0
- package/dist/utils/slugify.d.ts +3 -0
- package/dist/utils/slugify.js +2 -0
- package/dist/utils/utils.d.ts +6 -0
- package/dist/utils/utils.js +19 -0
- package/oclif.manifest.json +895 -0
- package/package.json +87 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Command, Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import inquirer from "inquirer";
|
|
4
|
+
import { readAuthConfig } from "../../utils/utils.js";
|
|
5
|
+
import { getProject, getProjects } from "../../utils/shared.js";
|
|
6
|
+
export default class ProjectInfo extends Command {
|
|
7
|
+
static description = "Get detailed information about a project, including the number of applications and databases.";
|
|
8
|
+
static examples = [
|
|
9
|
+
"$ <%= config.bin %> project info",
|
|
10
|
+
"$ <%= config.bin %> project info -p <projectId>",
|
|
11
|
+
];
|
|
12
|
+
static flags = {
|
|
13
|
+
projectId: Flags.string({
|
|
14
|
+
char: "p",
|
|
15
|
+
description: "ID of the project",
|
|
16
|
+
required: false,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const auth = await readAuthConfig(this);
|
|
21
|
+
const { flags } = await this.parse(ProjectInfo);
|
|
22
|
+
if (flags.projectId) {
|
|
23
|
+
await this.showProjectInfo(auth, flags.projectId);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
|
27
|
+
try {
|
|
28
|
+
const projects = await getProjects(auth, this);
|
|
29
|
+
if (projects.length === 0) {
|
|
30
|
+
this.log(chalk.yellow("No projects found."));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const answers = await inquirer.prompt([
|
|
34
|
+
{
|
|
35
|
+
choices: projects.map((project) => ({
|
|
36
|
+
name: project.name,
|
|
37
|
+
value: project.projectId,
|
|
38
|
+
})),
|
|
39
|
+
message: "Select a project to view details:",
|
|
40
|
+
name: "selectedProject",
|
|
41
|
+
type: "list",
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
const selectedProjectId = answers.selectedProject;
|
|
45
|
+
await this.showProjectInfo(auth, selectedProjectId);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// @ts-expect-error hola
|
|
49
|
+
this.error(chalk.red(`Failed to fetch project list: ${error.message}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async showProjectInfo(auth, projectId) {
|
|
54
|
+
console.log(chalk.blue.bold(`\n Information for Project ID: ${projectId} \n`));
|
|
55
|
+
try {
|
|
56
|
+
const projectInfo = await getProject(projectId, auth, this);
|
|
57
|
+
this.log(chalk.green(`Project Name: ${projectInfo.name}`));
|
|
58
|
+
this.log(chalk.green(`Description: ${projectInfo?.description || "No description"}`));
|
|
59
|
+
this.log(chalk.green(`Number of Applications: ${projectInfo.applications.length}`));
|
|
60
|
+
this.log(chalk.green(`Number of Compose Services: ${projectInfo.compose.length}`));
|
|
61
|
+
this.log(chalk.green(`Number of MariaDB Databases: ${projectInfo.mariadb.length}`));
|
|
62
|
+
this.log(chalk.green(`Number of MongoDB Databases: ${projectInfo.mongo.length}`));
|
|
63
|
+
this.log(chalk.green(`Number of MySQL Databases: ${projectInfo.mysql.length}`));
|
|
64
|
+
this.log(chalk.green(`Number of PostgreSQL Databases: ${projectInfo.postgres.length}`));
|
|
65
|
+
this.log(chalk.green(`Number of Redis Databases: ${projectInfo.redis.length}`));
|
|
66
|
+
if (projectInfo.applications.length > 0) {
|
|
67
|
+
this.log(chalk.blue("\nApplications:"));
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
projectInfo.applications.forEach((app, index) => {
|
|
70
|
+
this.log(` ${index + 1}. ${app.name}`);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (projectInfo.compose.length > 0) {
|
|
74
|
+
this.log(chalk.blue("\nCompose Services:"));
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
projectInfo.compose.forEach((service, index) => {
|
|
77
|
+
this.log(` ${index + 1}. ${service.name}`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (projectInfo.mariadb.length > 0) {
|
|
81
|
+
this.log(chalk.blue("\nMariaDB Databases:"));
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
projectInfo.mariadb.forEach((db, index) => {
|
|
84
|
+
this.log(` ${index + 1}. ${db.name}`);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (projectInfo.mongo.length > 0) {
|
|
88
|
+
this.log(chalk.blue("\nMongoDB Databases:"));
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
projectInfo.mongo.forEach((db, index) => {
|
|
91
|
+
this.log(` ${index + 1}. ${db.name}`);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (projectInfo.mysql.length > 0) {
|
|
95
|
+
this.log(chalk.blue("\nMySQL Databases:"));
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
projectInfo.mysql.forEach((db, index) => {
|
|
98
|
+
this.log(` ${index + 1}. ${db.name}`);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (projectInfo.postgres.length > 0) {
|
|
102
|
+
this.log(chalk.blue("\nPostgreSQL Databases:"));
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
projectInfo.postgres.forEach((db, index) => {
|
|
105
|
+
this.log(` ${index + 1}. ${db.name}`);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (projectInfo.redis.length > 0) {
|
|
109
|
+
this.log(chalk.blue("\nRedis Databases:"));
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
projectInfo.redis.forEach((db, index) => {
|
|
112
|
+
this.log(` ${index + 1}. ${db.name}`);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
this.error(
|
|
118
|
+
// @ts-expect-error
|
|
119
|
+
chalk.red(`Failed to fetch project information: ${error.message}`));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import Table from "cli-table3";
|
|
4
|
+
import { readAuthConfig } from "../../utils/utils.js";
|
|
5
|
+
import { getProjects } from "../../utils/shared.js";
|
|
6
|
+
export default class ProjectList extends Command {
|
|
7
|
+
static description = "List all projects.";
|
|
8
|
+
static examples = ["$ <%= config.bin %> project list"];
|
|
9
|
+
async run() {
|
|
10
|
+
const auth = await readAuthConfig(this);
|
|
11
|
+
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
|
12
|
+
try {
|
|
13
|
+
const projects = await getProjects(auth, this);
|
|
14
|
+
if (projects.length === 0) {
|
|
15
|
+
this.log(chalk.yellow("No projects found."));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this.log(chalk.green("Projects:"));
|
|
19
|
+
const table = new Table({
|
|
20
|
+
colWidths: [10, 30, 50],
|
|
21
|
+
head: [
|
|
22
|
+
chalk.cyan("Index"),
|
|
23
|
+
chalk.cyan("Name"),
|
|
24
|
+
chalk.cyan("Description"),
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
const index = 1;
|
|
28
|
+
for (const project of projects) {
|
|
29
|
+
table.push([
|
|
30
|
+
chalk.white(index + 1),
|
|
31
|
+
chalk.white(project.name),
|
|
32
|
+
chalk.gray(project.description || "No description"),
|
|
33
|
+
]);
|
|
34
|
+
}
|
|
35
|
+
this.log(table.toString());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
// @ts-expect-error error is not defined
|
|
40
|
+
this.error(chalk.red(`Failed to list projects: ${error?.message}`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import * as fs from "node:fs";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const configPath = path.join(__dirname, "..", "..", "config.json");
|
|
10
|
+
export default class Verify extends Command {
|
|
11
|
+
static description = "Verify if the saved authentication token is valid";
|
|
12
|
+
static examples = ["$ <%= config.bin %> <%= command.id %>"];
|
|
13
|
+
async run() {
|
|
14
|
+
console.log(chalk.blue.bold("\nVerifying Authentication Token"));
|
|
15
|
+
if (!fs.existsSync(configPath)) {
|
|
16
|
+
this.error(chalk.red("No configuration file found. Please authenticate first using `authenticate` command."));
|
|
17
|
+
}
|
|
18
|
+
const configFileContent = fs.readFileSync(configPath, "utf8");
|
|
19
|
+
const config = JSON.parse(configFileContent);
|
|
20
|
+
const { token, url } = config;
|
|
21
|
+
if (!url || !token) {
|
|
22
|
+
this.error(chalk.red("Incomplete authentication details. Please authenticate again using `authenticate` command."));
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
console.log(`\n${chalk.blue("Validating token...")}`);
|
|
26
|
+
const response = await axios.post(`${url}/api/trpc/auth.verifyToken`, {}, {
|
|
27
|
+
headers: {
|
|
28
|
+
Authorization: `Bearer ${token}`,
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
if (response.data.result.data.json) {
|
|
33
|
+
this.log(chalk.green("Token is valid."));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this.error(chalk.red("Invalid token. Please authenticate again using `authenticate` command."));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
this.error(chalk.red(
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
`Failed to verify token: ${error.message}. Please authenticate again using 'authenticate' command.`));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from "@oclif/core";
|
|
2
|
+
import type { AuthConfig } from "./utils.js";
|
|
3
|
+
export type Project = {
|
|
4
|
+
adminId: string;
|
|
5
|
+
name: string;
|
|
6
|
+
projectId?: string | undefined;
|
|
7
|
+
description?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare const getProjects: (auth: AuthConfig, command: Command) => Promise<Project[]>;
|
|
10
|
+
export declare const getProject: (projectId: string | undefined, auth: AuthConfig, command: Command) => Promise<any>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
export const getProjects = async (auth, command) => {
|
|
4
|
+
try {
|
|
5
|
+
const response = await axios.get(`${auth.url}/api/trpc/project.all`, {
|
|
6
|
+
headers: {
|
|
7
|
+
Authorization: `Bearer ${auth.token}`,
|
|
8
|
+
"Content-Type": "application/json",
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
if (!response.data.result.data.json) {
|
|
12
|
+
command.error(chalk.red("Error fetching projects"));
|
|
13
|
+
}
|
|
14
|
+
const projects = response.data.result.data.json;
|
|
15
|
+
if (projects.length === 0) {
|
|
16
|
+
command.log(chalk.yellow("No projects found."));
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
return projects;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
// @ts-expect-error TODO: Fix this
|
|
23
|
+
command.error(chalk.red(`Failed to fetch project list: ${error.message}`));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export const getProject = async (projectId, auth, command) => {
|
|
27
|
+
try {
|
|
28
|
+
if (!projectId) {
|
|
29
|
+
command.error(chalk.red("Project ID is required"));
|
|
30
|
+
}
|
|
31
|
+
const response = await axios.get(`${auth.url}/api/trpc/project.one`, {
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${auth.token}`,
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
params: {
|
|
37
|
+
input: JSON.stringify({
|
|
38
|
+
json: { projectId },
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
if (!response.data.result.data.json) {
|
|
43
|
+
command.error(chalk.red("Error fetching project"));
|
|
44
|
+
}
|
|
45
|
+
const project = response.data.result.data.json;
|
|
46
|
+
if (!project) {
|
|
47
|
+
command.error(chalk.red("Error fetching project"));
|
|
48
|
+
}
|
|
49
|
+
return project;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// @ts-expect-error TODO: Fix this
|
|
53
|
+
command.error(chalk.red(`Failed to fetch project: ${error.message}`));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const slugify: (text: string | undefined) => string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import slug from "./slugify.js";
|
|
2
|
+
export const slugify = (text) => {
|
|
3
|
+
if (!text) {
|
|
4
|
+
return "";
|
|
5
|
+
}
|
|
6
|
+
const cleanedText = text.trim().replaceAll(/[^\d\sA-Za-z]/g, "");
|
|
7
|
+
return slug(cleanedText, {
|
|
8
|
+
lower: true,
|
|
9
|
+
strict: true,
|
|
10
|
+
trim: true,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
const configPath = path.join(__dirname, "..", "..", "config.json");
|
|
8
|
+
export const readAuthConfig = async (command) => {
|
|
9
|
+
if (!fs.existsSync(configPath)) {
|
|
10
|
+
command.error(chalk.red("No configuration file found. Please authenticate first using the 'authenticate' command."));
|
|
11
|
+
}
|
|
12
|
+
const configFileContent = fs.readFileSync(configPath, "utf8");
|
|
13
|
+
const config = JSON.parse(configFileContent);
|
|
14
|
+
const { token, url } = config;
|
|
15
|
+
if (!url || !token) {
|
|
16
|
+
command.error(chalk.red("Incomplete authentication details. Please authenticate again using the 'authenticate' command."));
|
|
17
|
+
}
|
|
18
|
+
return { token, url };
|
|
19
|
+
};
|