@dokploy/cli 0.2.3 → 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 (57) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/commands/app/create.d.ts +4 -0
  3. package/dist/commands/app/create.js +87 -37
  4. package/dist/commands/app/delete.d.ts +2 -0
  5. package/dist/commands/app/delete.js +50 -28
  6. package/dist/commands/app/deploy.d.ts +5 -0
  7. package/dist/commands/app/deploy.js +93 -55
  8. package/dist/commands/app/stop.d.ts +5 -0
  9. package/dist/commands/app/stop.js +87 -54
  10. package/dist/commands/database/mariadb/create.d.ts +9 -0
  11. package/dist/commands/database/mariadb/create.js +160 -66
  12. package/dist/commands/database/mariadb/delete.d.ts +2 -0
  13. package/dist/commands/database/mariadb/delete.js +56 -47
  14. package/dist/commands/database/mariadb/deploy.d.ts +5 -0
  15. package/dist/commands/database/mariadb/deploy.js +88 -54
  16. package/dist/commands/database/mariadb/stop.d.ts +5 -0
  17. package/dist/commands/database/mariadb/stop.js +88 -54
  18. package/dist/commands/database/mongo/create.d.ts +8 -0
  19. package/dist/commands/database/mongo/create.js +145 -76
  20. package/dist/commands/database/mongo/delete.d.ts +2 -0
  21. package/dist/commands/database/mongo/delete.js +56 -45
  22. package/dist/commands/database/mongo/deploy.d.ts +5 -0
  23. package/dist/commands/database/mongo/deploy.js +88 -54
  24. package/dist/commands/database/mongo/stop.d.ts +5 -0
  25. package/dist/commands/database/mongo/stop.js +88 -54
  26. package/dist/commands/database/mysql/create.d.ts +9 -0
  27. package/dist/commands/database/mysql/create.js +168 -81
  28. package/dist/commands/database/mysql/delete.d.ts +2 -0
  29. package/dist/commands/database/mysql/delete.js +56 -47
  30. package/dist/commands/database/mysql/deploy.js +70 -53
  31. package/dist/commands/database/mysql/stop.js +70 -53
  32. package/dist/commands/database/postgres/create.d.ts +8 -0
  33. package/dist/commands/database/postgres/create.js +155 -76
  34. package/dist/commands/database/postgres/delete.d.ts +2 -0
  35. package/dist/commands/database/postgres/delete.js +56 -44
  36. package/dist/commands/database/postgres/deploy.d.ts +5 -0
  37. package/dist/commands/database/postgres/deploy.js +90 -56
  38. package/dist/commands/database/postgres/stop.d.ts +5 -0
  39. package/dist/commands/database/postgres/stop.js +91 -57
  40. package/dist/commands/database/redis/create.d.ts +6 -0
  41. package/dist/commands/database/redis/create.js +129 -65
  42. package/dist/commands/database/redis/delete.d.ts +2 -0
  43. package/dist/commands/database/redis/delete.js +60 -50
  44. package/dist/commands/database/redis/deploy.d.ts +5 -0
  45. package/dist/commands/database/redis/deploy.js +90 -56
  46. package/dist/commands/database/redis/stop.d.ts +5 -0
  47. package/dist/commands/database/redis/stop.js +91 -57
  48. package/dist/commands/env/pull.d.ts +10 -0
  49. package/dist/commands/env/pull.js +68 -0
  50. package/dist/commands/env/push.d.ts +10 -0
  51. package/dist/commands/env/push.js +106 -0
  52. package/dist/commands/project/create.d.ts +2 -1
  53. package/dist/commands/project/create.js +53 -34
  54. package/dist/utils/utils.js +9 -2
  55. package/oclif.manifest.json +895 -110
  56. package/package.json +3 -2
  57. package/{README.md → readme.md} +16 -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
  }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class EnvPull extends Command {
3
+ static args: {
4
+ file: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {};
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,68 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import { readAuthConfig } from "../../utils/utils.js";
3
+ import chalk from "chalk";
4
+ import { getProject, getProjects } from "../../utils/shared.js";
5
+ import inquirer from "inquirer";
6
+ import fs from 'fs';
7
+ export default class EnvPull extends Command {
8
+ static args = {
9
+ file: Args.string({ description: 'write to file', required: true }),
10
+ };
11
+ static description = 'Store remote environment variables in local';
12
+ static examples = [
13
+ '<%= config.bin %> <%= command.id %> .env.stage.local',
14
+ ];
15
+ static flags = {};
16
+ async run() {
17
+ const { args } = await this.parse(EnvPull);
18
+ if (fs.existsSync(args.file)) {
19
+ const { override } = await inquirer.prompt([
20
+ {
21
+ message: `Do you want to override ${args.file} file?`,
22
+ name: "override",
23
+ default: false,
24
+ type: "confirm",
25
+ },
26
+ ]);
27
+ if (!override) {
28
+ return;
29
+ }
30
+ }
31
+ const auth = await readAuthConfig(this);
32
+ console.log(chalk.blue.bold("\n Listing all Projects \n"));
33
+ const projects = await getProjects(auth, this);
34
+ const { project } = await inquirer.prompt([
35
+ {
36
+ choices: projects.map((project) => ({
37
+ name: project.name,
38
+ value: project,
39
+ })),
40
+ message: "Select the project:",
41
+ name: "project",
42
+ type: "list",
43
+ },
44
+ ]);
45
+ const projectId = project.projectId;
46
+ const projectSelected = await getProject(projectId, auth, this);
47
+ const choices = [
48
+ ...projectSelected.applications.map((app) => ({
49
+ name: `${app.name} (Application)`,
50
+ value: app.env,
51
+ })),
52
+ ...projectSelected.compose.map((compose) => ({
53
+ name: `${compose.name} (Compose)`,
54
+ value: compose.env,
55
+ })),
56
+ ];
57
+ const { env } = await inquirer.prompt([
58
+ {
59
+ choices,
60
+ message: "Select a service to pull the environment variables:",
61
+ name: "env",
62
+ type: "list",
63
+ },
64
+ ]);
65
+ fs.writeFileSync(args.file, env || "");
66
+ this.log(chalk.green("Environment variable write to file successful."));
67
+ }
68
+ }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class EnvPush extends Command {
3
+ static args: {
4
+ file: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {};
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,106 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import fs from "fs";
3
+ import chalk from "chalk";
4
+ import inquirer from "inquirer";
5
+ import { readAuthConfig } from "../../utils/utils.js";
6
+ import { getProject, getProjects } from "../../utils/shared.js";
7
+ import axios from "axios";
8
+ export default class EnvPush extends Command {
9
+ static args = {
10
+ file: Args.string({ description: '.env file to push', required: true }),
11
+ };
12
+ static description = 'Push dotenv file to remote service';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %> .env.stage.local',
15
+ ];
16
+ static flags = {};
17
+ async run() {
18
+ const { args, flags } = await this.parse(EnvPush);
19
+ if (!fs.existsSync(args.file)) {
20
+ console.log(chalk.red.bold(`\n File ${args.file} doesn't exists \n`));
21
+ return;
22
+ }
23
+ const { override } = await inquirer.prompt([
24
+ {
25
+ message: `This command will override entire remote environment variables. Do you want to continue?`,
26
+ name: "override",
27
+ default: false,
28
+ type: "confirm",
29
+ },
30
+ ]);
31
+ if (!override) {
32
+ return;
33
+ }
34
+ const fileContent = fs.readFileSync(args.file, 'utf-8');
35
+ const auth = await readAuthConfig(this);
36
+ console.log(chalk.blue.bold("\n Listing all Projects \n"));
37
+ const projects = await getProjects(auth, this);
38
+ const { project } = await inquirer.prompt([
39
+ {
40
+ choices: projects.map((project) => ({
41
+ name: project.name,
42
+ value: project,
43
+ })),
44
+ message: "Select the project:",
45
+ name: "project",
46
+ type: "list",
47
+ },
48
+ ]);
49
+ const projectId = project.projectId;
50
+ const projectSelected = await getProject(projectId, auth, this);
51
+ const choices = [
52
+ ...projectSelected.applications.map((app) => ({
53
+ name: `${app.name} (Application)`,
54
+ value: { serviceType: 'app', service: app },
55
+ })),
56
+ ...projectSelected.compose.map((compose) => ({
57
+ name: `${compose.name} (Compose)`,
58
+ value: { serviceType: 'compose', service: compose }
59
+ })),
60
+ ];
61
+ const { result: { serviceType, service } } = await inquirer.prompt([
62
+ {
63
+ choices,
64
+ message: "Select a service to pull the environment variables:",
65
+ name: "result",
66
+ type: "list",
67
+ },
68
+ ]);
69
+ if (serviceType === 'app') {
70
+ const { applicationId } = service;
71
+ const response = await axios.post(`${auth.url}/api/trpc/application.update`, {
72
+ json: {
73
+ applicationId,
74
+ env: fileContent
75
+ }
76
+ }, {
77
+ headers: {
78
+ Authorization: `Bearer ${auth.token}`,
79
+ "Content-Type": "application/json",
80
+ },
81
+ });
82
+ if (response.status !== 200) {
83
+ this.error(chalk.red("Error stopping application"));
84
+ }
85
+ this.log(chalk.green("Environment variable push successful."));
86
+ }
87
+ if (serviceType === 'compose') {
88
+ const { composeId } = service;
89
+ const response = await axios.post(`${auth.url}/api/trpc/compose.update`, {
90
+ json: {
91
+ composeId,
92
+ env: fileContent
93
+ }
94
+ }, {
95
+ headers: {
96
+ Authorization: `Bearer ${auth.token}`,
97
+ "Content-Type": "application/json",
98
+ },
99
+ });
100
+ if (response.status !== 200) {
101
+ this.error(chalk.red("Error stopping application"));
102
+ }
103
+ this.log(chalk.green("Environment variable push successful."));
104
+ }
105
+ }
106
+ }
@@ -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
  }