@dokploy/cli 0.2.4 → 0.2.5

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 (51) hide show
  1. package/dist/commands/app/create.d.ts +4 -0
  2. package/dist/commands/app/create.js +87 -37
  3. package/dist/commands/app/delete.d.ts +2 -0
  4. package/dist/commands/app/delete.js +50 -28
  5. package/dist/commands/app/deploy.d.ts +5 -0
  6. package/dist/commands/app/deploy.js +93 -55
  7. package/dist/commands/app/stop.d.ts +5 -0
  8. package/dist/commands/app/stop.js +87 -54
  9. package/dist/commands/database/mariadb/create.d.ts +9 -0
  10. package/dist/commands/database/mariadb/create.js +160 -66
  11. package/dist/commands/database/mariadb/delete.d.ts +2 -0
  12. package/dist/commands/database/mariadb/delete.js +56 -47
  13. package/dist/commands/database/mariadb/deploy.d.ts +5 -0
  14. package/dist/commands/database/mariadb/deploy.js +88 -54
  15. package/dist/commands/database/mariadb/stop.d.ts +5 -0
  16. package/dist/commands/database/mariadb/stop.js +88 -54
  17. package/dist/commands/database/mongo/create.d.ts +8 -0
  18. package/dist/commands/database/mongo/create.js +145 -76
  19. package/dist/commands/database/mongo/delete.d.ts +2 -0
  20. package/dist/commands/database/mongo/delete.js +56 -45
  21. package/dist/commands/database/mongo/deploy.d.ts +5 -0
  22. package/dist/commands/database/mongo/deploy.js +88 -54
  23. package/dist/commands/database/mongo/stop.d.ts +5 -0
  24. package/dist/commands/database/mongo/stop.js +88 -54
  25. package/dist/commands/database/mysql/create.d.ts +9 -0
  26. package/dist/commands/database/mysql/create.js +168 -81
  27. package/dist/commands/database/mysql/delete.d.ts +2 -0
  28. package/dist/commands/database/mysql/delete.js +56 -47
  29. package/dist/commands/database/mysql/deploy.js +70 -53
  30. package/dist/commands/database/mysql/stop.js +70 -53
  31. package/dist/commands/database/postgres/create.d.ts +8 -0
  32. package/dist/commands/database/postgres/create.js +155 -76
  33. package/dist/commands/database/postgres/delete.d.ts +2 -0
  34. package/dist/commands/database/postgres/delete.js +56 -44
  35. package/dist/commands/database/postgres/deploy.d.ts +5 -0
  36. package/dist/commands/database/postgres/deploy.js +90 -56
  37. package/dist/commands/database/postgres/stop.d.ts +5 -0
  38. package/dist/commands/database/postgres/stop.js +91 -57
  39. package/dist/commands/database/redis/create.d.ts +6 -0
  40. package/dist/commands/database/redis/create.js +129 -65
  41. package/dist/commands/database/redis/delete.d.ts +2 -0
  42. package/dist/commands/database/redis/delete.js +60 -50
  43. package/dist/commands/database/redis/deploy.d.ts +5 -0
  44. package/dist/commands/database/redis/deploy.js +90 -56
  45. package/dist/commands/database/redis/stop.d.ts +5 -0
  46. package/dist/commands/database/redis/stop.js +91 -57
  47. package/dist/commands/project/create.d.ts +2 -1
  48. package/dist/commands/project/create.js +53 -34
  49. package/dist/utils/utils.js +9 -2
  50. package/oclif.manifest.json +876 -151
  51. package/package.json +1 -1
@@ -1,69 +1,103 @@
1
- import { Command } from "@oclif/core";
1
+ import { Command, Flags } from "@oclif/core";
2
2
  import { readAuthConfig } from "../../../utils/utils.js";
3
3
  import chalk from "chalk";
4
4
  import { getProject, getProjects } from "../../../utils/shared.js";
5
5
  import inquirer from "inquirer";
6
6
  import axios from "axios";
7
7
  export default class DatabaseRedisDeploy extends Command {
8
- static description = "Deploy an redis to a project.";
9
- static examples = ["$ <%= config.bin %> app deploy"];
8
+ static description = "Deploy a Redis instance to a project.";
9
+ static examples = ["$ <%= config.bin %> redis deploy"];
10
+ static flags = {
11
+ projectId: Flags.string({
12
+ char: "p",
13
+ description: "ID of the project",
14
+ required: false,
15
+ }),
16
+ redisId: Flags.string({
17
+ char: "r",
18
+ description: "ID of the Redis instance to deploy",
19
+ required: false,
20
+ }),
21
+ skipConfirm: Flags.boolean({
22
+ char: "y",
23
+ description: "Skip confirmation prompt",
24
+ default: false,
25
+ }),
26
+ };
10
27
  async run() {
11
28
  const auth = await readAuthConfig(this);
12
- console.log(chalk.blue.bold("\n Listing all Projects \n"));
13
- const projects = await getProjects(auth, this);
14
- const { project } = await inquirer.prompt([
15
- {
16
- choices: projects.map((project) => ({
17
- name: project.name,
18
- value: project,
19
- })),
20
- message: "Select a project to deploy the redis in:",
21
- name: "project",
22
- type: "list",
23
- },
24
- ]);
25
- const projectId = project.projectId;
26
- const projectSelected = await getProject(projectId, auth, this);
27
- if (projectSelected.redis.length === 0) {
28
- this.error(chalk.yellow("No redis found in this project."));
29
+ const { flags } = await this.parse(DatabaseRedisDeploy);
30
+ let { projectId, redisId } = flags;
31
+ // Modo interactivo si no se proporcionan los flags necesarios
32
+ if (!projectId || !redisId) {
33
+ console.log(chalk.blue.bold("\n Listing all Projects \n"));
34
+ const projects = await getProjects(auth, this);
35
+ if (!projectId) {
36
+ const { project } = await inquirer.prompt([
37
+ {
38
+ choices: projects.map((project) => ({
39
+ name: project.name,
40
+ value: project,
41
+ })),
42
+ message: "Select a project to deploy the Redis instance from:",
43
+ name: "project",
44
+ type: "list",
45
+ },
46
+ ]);
47
+ projectId = project.projectId;
48
+ }
49
+ const projectSelected = await getProject(projectId, auth, this);
50
+ if (projectSelected.redis.length === 0) {
51
+ this.error(chalk.yellow("No Redis instances found in this project."));
52
+ }
53
+ if (!redisId) {
54
+ const dbAnswers = await inquirer.prompt([
55
+ {
56
+ // @ts-ignore
57
+ choices: projectSelected.redis.map((db) => ({
58
+ name: db.name,
59
+ value: db.redisId,
60
+ })),
61
+ message: "Select the Redis instance to deploy:",
62
+ name: "selectedDb",
63
+ type: "list",
64
+ },
65
+ ]);
66
+ redisId = dbAnswers.selectedDb;
67
+ }
29
68
  }
30
- const appAnswers = await inquirer.prompt([
31
- {
32
- // @ts-ignore
33
- choices: projectSelected.redis.map((app) => ({
34
- name: app.name,
35
- value: app.redisId,
36
- })),
37
- message: "Select the redis to deploy:",
38
- name: "selectedApp",
39
- type: "list",
40
- },
41
- ]);
42
- const redisId = appAnswers.selectedApp;
43
- const confirmAnswers = await inquirer.prompt([
44
- {
45
- default: false,
46
- message: "Are you sure you want to deploy this redis?",
47
- name: "confirmDelete",
48
- type: "confirm",
49
- },
50
- ]);
51
- if (!confirmAnswers.confirmDelete) {
52
- this.error(chalk.yellow("redis deployment cancelled."));
69
+ // Confirmar si no se especifica --skipConfirm
70
+ if (!flags.skipConfirm) {
71
+ const confirmAnswers = await inquirer.prompt([
72
+ {
73
+ default: false,
74
+ message: "Are you sure you want to deploy this Redis instance?",
75
+ name: "confirmDeploy",
76
+ type: "confirm",
77
+ },
78
+ ]);
79
+ if (!confirmAnswers.confirmDeploy) {
80
+ this.error(chalk.yellow("Redis deployment cancelled."));
81
+ }
53
82
  }
54
- const response = await axios.post(`${auth.url}/api/trpc/redis.deploy`, {
55
- json: {
56
- redisId,
57
- },
58
- }, {
59
- headers: {
60
- Authorization: `Bearer ${auth.token}`,
61
- "Content-Type": "application/json",
62
- },
63
- });
64
- if (response.status !== 200) {
65
- this.error(chalk.red("Error deploying redis"));
83
+ try {
84
+ const response = await axios.post(`${auth.url}/api/trpc/redis.deploy`, {
85
+ json: {
86
+ redisId,
87
+ },
88
+ }, {
89
+ headers: {
90
+ Authorization: `Bearer ${auth.token}`,
91
+ "Content-Type": "application/json",
92
+ },
93
+ });
94
+ if (response.status !== 200) {
95
+ this.error(chalk.red("Error deploying Redis instance"));
96
+ }
97
+ this.log(chalk.green("Redis instance deployed successfully."));
98
+ }
99
+ catch (error) {
100
+ this.error(chalk.red(`Error deploying Redis instance: ${error.message}`));
66
101
  }
67
- this.log(chalk.green("Redis deployed successful."));
68
102
  }
69
103
  }
@@ -2,5 +2,10 @@ import { Command } from "@oclif/core";
2
2
  export default class DatabaseRedisStop extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
+ static flags: {
6
+ projectId: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ redisId: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ skipConfirm: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
9
+ };
5
10
  run(): Promise<void>;
6
11
  }
@@ -1,69 +1,103 @@
1
- import { Command } from "@oclif/core";
1
+ import { Command, Flags } from "@oclif/core";
2
+ import { readAuthConfig } from "../../../utils/utils.js";
2
3
  import chalk from "chalk";
4
+ import { getProject, getProjects } from "../../../utils/shared.js";
3
5
  import inquirer from "inquirer";
4
6
  import axios from "axios";
5
- import { getProject, getProjects } from "../../../utils/shared.js";
6
- import { readAuthConfig } from "../../../utils/utils.js";
7
7
  export default class DatabaseRedisStop extends Command {
8
- static description = "Stop an redis from a project.";
8
+ static description = "Stop a Redis instance in a project.";
9
9
  static examples = ["$ <%= config.bin %> redis stop"];
10
+ static flags = {
11
+ projectId: Flags.string({
12
+ char: "p",
13
+ description: "ID of the project",
14
+ required: false,
15
+ }),
16
+ redisId: Flags.string({
17
+ char: "r",
18
+ description: "ID of the Redis instance to stop",
19
+ required: false,
20
+ }),
21
+ skipConfirm: Flags.boolean({
22
+ char: "y",
23
+ description: "Skip confirmation prompt",
24
+ default: false,
25
+ }),
26
+ };
10
27
  async run() {
11
28
  const auth = await readAuthConfig(this);
12
- console.log(chalk.blue.bold("\n Listing all Projects \n"));
13
- const projects = await getProjects(auth, this);
14
- const { project } = await inquirer.prompt([
15
- {
16
- choices: projects.map((project) => ({
17
- name: project.name,
18
- value: project,
19
- })),
20
- message: "Select a project to stop the redis in:",
21
- name: "project",
22
- type: "list",
23
- },
24
- ]);
25
- const projectId = project.projectId;
26
- const projectSelected = await getProject(projectId, auth, this);
27
- if (projectSelected.redis.length === 0) {
28
- this.error(chalk.yellow("No redis found in this project."));
29
+ const { flags } = await this.parse(DatabaseRedisStop);
30
+ let { projectId, redisId } = flags;
31
+ // Modo interactivo si no se proporcionan los flags necesarios
32
+ if (!projectId || !redisId) {
33
+ console.log(chalk.blue.bold("\n Listing all Projects \n"));
34
+ const projects = await getProjects(auth, this);
35
+ if (!projectId) {
36
+ const { project } = await inquirer.prompt([
37
+ {
38
+ choices: projects.map((project) => ({
39
+ name: project.name,
40
+ value: project,
41
+ })),
42
+ message: "Select a project to stop the Redis instance from:",
43
+ name: "project",
44
+ type: "list",
45
+ },
46
+ ]);
47
+ projectId = project.projectId;
48
+ }
49
+ const projectSelected = await getProject(projectId, auth, this);
50
+ if (projectSelected.redis.length === 0) {
51
+ this.error(chalk.yellow("No Redis instances found in this project."));
52
+ }
53
+ if (!redisId) {
54
+ const dbAnswers = await inquirer.prompt([
55
+ {
56
+ // @ts-ignore
57
+ choices: projectSelected.redis.map((db) => ({
58
+ name: db.name,
59
+ value: db.redisId,
60
+ })),
61
+ message: "Select the Redis instance to stop:",
62
+ name: "selectedDb",
63
+ type: "list",
64
+ },
65
+ ]);
66
+ redisId = dbAnswers.selectedDb;
67
+ }
68
+ }
69
+ // Confirmar si no se especifica --skipConfirm
70
+ if (!flags.skipConfirm) {
71
+ const confirmAnswers = await inquirer.prompt([
72
+ {
73
+ default: false,
74
+ message: "Are you sure you want to stop this Redis instance?",
75
+ name: "confirmStop",
76
+ type: "confirm",
77
+ },
78
+ ]);
79
+ if (!confirmAnswers.confirmStop) {
80
+ this.error(chalk.yellow("Redis stop cancelled."));
81
+ }
29
82
  }
30
- const appAnswers = await inquirer.prompt([
31
- {
32
- // @ts-ignore
33
- choices: projectSelected.redis.map((app) => ({
34
- name: app.name,
35
- value: app.redisId,
36
- })),
37
- message: "Select the redis to stop:",
38
- name: "selectedApp",
39
- type: "list",
40
- },
41
- ]);
42
- const redisId = appAnswers.selectedApp;
43
- const confirmAnswers = await inquirer.prompt([
44
- {
45
- default: false,
46
- message: "Are you sure you want to stop this redis?",
47
- name: "confirmDelete",
48
- type: "confirm",
49
- },
50
- ]);
51
- if (!confirmAnswers.confirmDelete) {
52
- this.error(chalk.yellow("redis stop cancelled."));
83
+ try {
84
+ const response = await axios.post(`${auth.url}/api/trpc/redis.stop`, {
85
+ json: {
86
+ redisId,
87
+ },
88
+ }, {
89
+ headers: {
90
+ Authorization: `Bearer ${auth.token}`,
91
+ "Content-Type": "application/json",
92
+ },
93
+ });
94
+ if (response.status !== 200) {
95
+ this.error(chalk.red("Error stopping Redis instance"));
96
+ }
97
+ this.log(chalk.green("Redis instance stopped successfully."));
53
98
  }
54
- const response = await axios.post(`${auth.url}/api/trpc/redis.stop`, {
55
- json: {
56
- redisId,
57
- },
58
- }, {
59
- headers: {
60
- Authorization: `Bearer ${auth.token}`,
61
- "Content-Type": "application/json",
62
- },
63
- });
64
- if (response.status !== 200) {
65
- this.error(chalk.red("Error stopping redis"));
99
+ catch (error) {
100
+ this.error(chalk.red(`Error stopping Redis instance: ${error.message}`));
66
101
  }
67
- this.log(chalk.green("Redis stop successful."));
68
102
  }
69
103
  }
@@ -3,8 +3,9 @@ export default class ProjectCreate extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
6
  name: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ skipConfirm: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
9
  };
9
10
  run(): Promise<void>;
10
11
  }
@@ -4,56 +4,76 @@ import chalk from "chalk";
4
4
  import inquirer from "inquirer";
5
5
  import { readAuthConfig } from "../../utils/utils.js";
6
6
  export default class ProjectCreate extends Command {
7
- static description = "Create a new project with an optional description.";
7
+ static description = "Create a new project.";
8
8
  static examples = [
9
- "$ <%= config.bin %> <%= command.id %> -n MyProject -d 'This is my project description'",
10
- "$ <%= config.bin %> <%= command.id %> -n MyProject",
11
- "$ <%= config.bin %> <%= command.id %>",
9
+ "$ <%= config.bin %> project create",
10
+ "$ <%= config.bin %> project create -n MyProject -d 'Project description'",
11
+ "$ <%= config.bin %> project create --name MyProject --skipConfirm",
12
12
  ];
13
13
  static flags = {
14
+ name: Flags.string({
15
+ char: "n",
16
+ description: "Name of the project",
17
+ required: false,
18
+ }),
14
19
  description: Flags.string({
15
20
  char: "d",
16
21
  description: "Description of the project",
17
22
  required: false,
18
23
  }),
19
- name: Flags.string({
20
- char: "n",
21
- description: "Name of the project",
22
- required: false,
24
+ skipConfirm: Flags.boolean({
25
+ char: "y",
26
+ description: "Skip confirmation prompt",
27
+ default: false,
23
28
  }),
24
29
  };
25
30
  async run() {
26
31
  const auth = await readAuthConfig(this);
27
- console.log(chalk.blue.bold("\n Create a New Project \n"));
28
32
  const { flags } = await this.parse(ProjectCreate);
29
- let answers = {};
30
- const questions = [];
31
- if (!flags.name) {
32
- questions.push({
33
- message: chalk.green("Enter the project name:"),
34
- name: "name",
35
- type: "input",
36
- validate: (input) => (input ? true : "Project name is required"),
37
- });
38
- }
39
- if (!flags.description) {
40
- questions.push({
41
- default: "",
42
- message: chalk.green("Enter the project description (optional):"),
43
- name: "description",
44
- type: "input",
45
- });
33
+ let { name, description } = flags;
34
+ // Modo interactivo si no se proporcionan los flags necesarios
35
+ if (!name) {
36
+ const answers = await inquirer.prompt([
37
+ {
38
+ message: "Enter the project name:",
39
+ name: "name",
40
+ type: "input",
41
+ validate: (input) => (input ? true : "Project name is required"),
42
+ },
43
+ {
44
+ message: "Enter the project description (optional):",
45
+ name: "description",
46
+ type: "input",
47
+ default: description || "",
48
+ },
49
+ ]);
50
+ name = answers.name;
51
+ description = answers.description;
46
52
  }
47
- if (questions.length > 0) {
48
- answers = await inquirer.prompt(questions);
53
+ // Confirmar si no se especifica --skipConfirm
54
+ if (!flags.skipConfirm) {
55
+ const confirm = await inquirer.prompt([
56
+ {
57
+ type: 'confirm',
58
+ name: 'proceed',
59
+ message: 'Do you want to create this project?',
60
+ default: false,
61
+ },
62
+ ]);
63
+ if (!confirm.proceed) {
64
+ this.error(chalk.yellow("Project creation cancelled."));
65
+ return;
66
+ }
49
67
  }
50
- const name = flags.name || answers.name;
51
- const description = flags.description || answers.description;
52
68
  try {
69
+ console.log(JSON.stringify({
70
+ name,
71
+ description,
72
+ }, null, 2));
53
73
  const response = await axios.post(`${auth.url}/api/trpc/project.create`, {
54
74
  json: {
55
- description,
56
75
  name,
76
+ description,
57
77
  },
58
78
  }, {
59
79
  headers: {
@@ -62,13 +82,12 @@ export default class ProjectCreate extends Command {
62
82
  },
63
83
  });
64
84
  if (!response.data.result.data.json) {
65
- this.error(chalk.red("Error`"));
85
+ this.error(chalk.red("Error creating project", response.data.result.data.json));
66
86
  }
67
87
  this.log(chalk.green(`Project '${name}' created successfully.`));
68
88
  }
69
89
  catch (error) {
70
- // @ts-expect-error hola
71
- this.error(chalk.red(`Failed to create project: ${error.message}`));
90
+ this.error(chalk.red(`Error creating project: ${error.message}`));
72
91
  }
73
92
  }
74
93
  }
@@ -6,14 +6,21 @@ const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
  const configPath = path.join(__dirname, "..", "..", "config.json");
8
8
  export const readAuthConfig = async (command) => {
9
+ // Primero intentar leer desde variables de entorno
10
+ const envToken = process.env.DOKPLOY_AUTH_TOKEN;
11
+ const envUrl = process.env.DOKPLOY_URL;
12
+ if (envToken && envUrl) {
13
+ return { token: envToken, url: envUrl };
14
+ }
15
+ // Si no hay variables de entorno, usar el archivo de configuración
9
16
  if (!fs.existsSync(configPath)) {
10
- command.error(chalk.red("No configuration file found. Please authenticate first using the 'authenticate' command."));
17
+ command.error(chalk.red("No configuration file found and no environment variables set. Please authenticate first using the 'authenticate' command or set DOKPLOY_URL and DOKPLOY_AUTH_TOKEN environment variables."));
11
18
  }
12
19
  const configFileContent = fs.readFileSync(configPath, "utf8");
13
20
  const config = JSON.parse(configFileContent);
14
21
  const { token, url } = config;
15
22
  if (!url || !token) {
16
- command.error(chalk.red("Incomplete authentication details. Please authenticate again using the 'authenticate' command."));
23
+ command.error(chalk.red("Incomplete authentication details. Please authenticate again using the 'authenticate' command or set environment variables."));
17
24
  }
18
25
  return { token, url };
19
26
  };