@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.
Files changed (77) hide show
  1. package/README.md +112 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +6 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/commands/app/create.d.ts +13 -0
  7. package/dist/commands/app/create.js +77 -0
  8. package/dist/commands/app/delete.d.ts +9 -0
  9. package/dist/commands/app/delete.js +84 -0
  10. package/dist/commands/app/deploy.d.ts +6 -0
  11. package/dist/commands/app/deploy.js +69 -0
  12. package/dist/commands/app/stop.d.ts +6 -0
  13. package/dist/commands/app/stop.js +69 -0
  14. package/dist/commands/authenticate.d.ts +10 -0
  15. package/dist/commands/authenticate.js +79 -0
  16. package/dist/commands/database/mariadb/create.d.ts +9 -0
  17. package/dist/commands/database/mariadb/create.js +105 -0
  18. package/dist/commands/database/mariadb/delete.d.ts +9 -0
  19. package/dist/commands/database/mariadb/delete.js +95 -0
  20. package/dist/commands/database/mariadb/deploy.d.ts +6 -0
  21. package/dist/commands/database/mariadb/deploy.js +69 -0
  22. package/dist/commands/database/mariadb/stop.d.ts +6 -0
  23. package/dist/commands/database/mariadb/stop.js +69 -0
  24. package/dist/commands/database/mongo/create.d.ts +9 -0
  25. package/dist/commands/database/mongo/create.js +107 -0
  26. package/dist/commands/database/mongo/delete.d.ts +9 -0
  27. package/dist/commands/database/mongo/delete.js +95 -0
  28. package/dist/commands/database/mongo/deploy.d.ts +6 -0
  29. package/dist/commands/database/mongo/deploy.js +69 -0
  30. package/dist/commands/database/mongo/stop.d.ts +6 -0
  31. package/dist/commands/database/mongo/stop.js +69 -0
  32. package/dist/commands/database/mysql/create.d.ts +9 -0
  33. package/dist/commands/database/mysql/create.js +112 -0
  34. package/dist/commands/database/mysql/delete.d.ts +9 -0
  35. package/dist/commands/database/mysql/delete.js +97 -0
  36. package/dist/commands/database/mysql/deploy.d.ts +6 -0
  37. package/dist/commands/database/mysql/deploy.js +69 -0
  38. package/dist/commands/database/mysql/stop.d.ts +6 -0
  39. package/dist/commands/database/mysql/stop.js +69 -0
  40. package/dist/commands/database/postgres/create.d.ts +9 -0
  41. package/dist/commands/database/postgres/create.js +107 -0
  42. package/dist/commands/database/postgres/delete.d.ts +9 -0
  43. package/dist/commands/database/postgres/delete.js +94 -0
  44. package/dist/commands/database/postgres/deploy.d.ts +6 -0
  45. package/dist/commands/database/postgres/deploy.js +69 -0
  46. package/dist/commands/database/postgres/stop.d.ts +6 -0
  47. package/dist/commands/database/postgres/stop.js +69 -0
  48. package/dist/commands/database/redis/create.d.ts +9 -0
  49. package/dist/commands/database/redis/create.js +95 -0
  50. package/dist/commands/database/redis/delete.d.ts +9 -0
  51. package/dist/commands/database/redis/delete.js +96 -0
  52. package/dist/commands/database/redis/deploy.d.ts +6 -0
  53. package/dist/commands/database/redis/deploy.js +69 -0
  54. package/dist/commands/database/redis/stop.d.ts +6 -0
  55. package/dist/commands/database/redis/stop.js +69 -0
  56. package/dist/commands/project/create.d.ts +10 -0
  57. package/dist/commands/project/create.js +74 -0
  58. package/dist/commands/project/info.d.ts +10 -0
  59. package/dist/commands/project/info.js +122 -0
  60. package/dist/commands/project/list.d.ts +6 -0
  61. package/dist/commands/project/list.js +43 -0
  62. package/dist/commands/verify.d.ts +6 -0
  63. package/dist/commands/verify.js +45 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +1 -0
  66. package/dist/utils/http.d.ts +4 -0
  67. package/dist/utils/http.js +4 -0
  68. package/dist/utils/shared.d.ts +10 -0
  69. package/dist/utils/shared.js +55 -0
  70. package/dist/utils/slug.d.ts +1 -0
  71. package/dist/utils/slug.js +12 -0
  72. package/dist/utils/slugify.d.ts +3 -0
  73. package/dist/utils/slugify.js +2 -0
  74. package/dist/utils/utils.d.ts +6 -0
  75. package/dist/utils/utils.js +19 -0
  76. package/oclif.manifest.json +895 -0
  77. 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,6 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class ProjectList extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -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,6 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Verify extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -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
+ }
@@ -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,4 @@
1
+ export declare const headers: {
2
+ "Content-Type": string;
3
+ "User-Agent": string;
4
+ };
@@ -0,0 +1,4 @@
1
+ export const headers = {
2
+ "Content-Type": "application/json",
3
+ "User-Agent": "Dokploy CLI",
4
+ };
@@ -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,3 @@
1
+ import slugify from "slugify";
2
+ declare const _default: typeof slugify.default;
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import slugify from "slugify";
2
+ export default slugify;
@@ -0,0 +1,6 @@
1
+ import type { Command } from "@oclif/core";
2
+ export type AuthConfig = {
3
+ token: string;
4
+ url: string;
5
+ };
6
+ export declare const readAuthConfig: (command: Command) => Promise<AuthConfig>;
@@ -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
+ };