Skip to content

Commit 1f1d671

Browse files
authored
Merge pull request #12 from Dokploy/fix/environments
Fix/environments
2 parents 1a01289 + 2647a59 commit 1f1d671

File tree

30 files changed

+1453
-316
lines changed

30 files changed

+1453
-316
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@dokploy/cli",
33
"description": "A CLI to manage dokploy server remotely",
4-
"version": "v0.2.7",
4+
"version": "v0.2.8",
55
"author": "Mauricio Siu",
66
"licenses": [{
77
"type": "MIT",

src/commands/app/create.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export default class AppCreate extends Command {
2222
description: "ID of the project",
2323
required: false,
2424
}),
25+
environmentId: Flags.string({
26+
char: "e",
27+
description: "ID of the environment",
28+
required: false,
29+
}),
2530
name: Flags.string({
2631
char: "n",
2732
description: "Application name",
@@ -46,13 +51,16 @@ export default class AppCreate extends Command {
4651
public async run(): Promise<void> {
4752
const auth = await readAuthConfig(this);
4853
const { flags } = await this.parse(AppCreate);
49-
let { projectId, name, description, appName } = flags;
54+
let { projectId, environmentId, name, description, appName } = flags;
5055

5156
// Modo interactivo si no se proporcionan los flags necesarios
52-
if (!projectId || !name || !appName) {
57+
if (!projectId || !environmentId || !name || !appName) {
5358
console.log(chalk.blue.bold("\n Listing all Projects \n"));
5459
const projects = await getProjects(auth, this);
5560

61+
let selectedProject;
62+
63+
// 1. Seleccionar proyecto
5664
if (!projectId) {
5765
const { project } = await inquirer.prompt<Answers>([
5866
{
@@ -65,7 +73,30 @@ export default class AppCreate extends Command {
6573
type: "list",
6674
},
6775
]);
76+
selectedProject = project;
6877
projectId = project.projectId;
78+
} else {
79+
selectedProject = projects.find(p => p.projectId === projectId);
80+
}
81+
82+
// 2. Seleccionar environment del proyecto
83+
if (!environmentId) {
84+
if (!selectedProject?.environments || selectedProject.environments.length === 0) {
85+
this.error(chalk.yellow("No environments found in this project."));
86+
}
87+
88+
const { environment } = await inquirer.prompt([
89+
{
90+
choices: selectedProject.environments.map((env) => ({
91+
name: `${env.name} (${env.description})`,
92+
value: env,
93+
})),
94+
message: "Select an environment:",
95+
name: "environment",
96+
type: "list",
97+
},
98+
]);
99+
environmentId = environment.environmentId;
69100
}
70101

71102
if (!name || !appName) {
@@ -128,6 +159,7 @@ export default class AppCreate extends Command {
128159
appDescription: description,
129160
appName,
130161
projectId,
162+
environmentId,
131163
},
132164
},
133165
{

src/commands/app/delete.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import axios from "axios";
33
import chalk from "chalk";
44
import inquirer from "inquirer";
55

6-
import { getProject, getProjects } from "../../utils/shared.js";
6+
import { getProject, getProjects, type Application } from "../../utils/shared.js";
77
import { readAuthConfig } from "../../utils/utils.js";
88
import type { Answers } from "./create.js";
99

@@ -21,6 +21,11 @@ export default class AppDelete extends Command {
2121
description: "ID of the project",
2222
required: false,
2323
}),
24+
environmentId: Flags.string({
25+
char: "e",
26+
description: "ID of the environment",
27+
required: false,
28+
}),
2429
applicationId: Flags.string({
2530
char: 'a',
2631
description: 'ID of the application to delete',
@@ -36,13 +41,17 @@ export default class AppDelete extends Command {
3641
public async run(): Promise<void> {
3742
const auth = await readAuthConfig(this);
3843
const { flags } = await this.parse(AppDelete);
39-
let { projectId, applicationId } = flags;
44+
let { projectId, environmentId, applicationId } = flags;
4045

4146
// Modo interactivo si no se proporcionan los flags necesarios
42-
if (!projectId || !applicationId) {
47+
if (!projectId || !environmentId || !applicationId) {
4348
console.log(chalk.blue.bold("\n Listing all Projects \n"));
4449
const projects = await getProjects(auth, this);
4550

51+
let selectedProject;
52+
let selectedEnvironment;
53+
54+
// 1. Seleccionar proyecto
4655
if (!projectId) {
4756
const { project } = await inquirer.prompt<Answers>([
4857
{
@@ -55,20 +64,44 @@ export default class AppDelete extends Command {
5564
type: "list",
5665
},
5766
]);
67+
selectedProject = project;
5868
projectId = project.projectId;
69+
} else {
70+
selectedProject = projects.find(p => p.projectId === projectId);
5971
}
6072

61-
const projectSelected = await getProject(projectId, auth, this);
73+
// 2. Seleccionar environment del proyecto
74+
if (!environmentId) {
75+
if (!selectedProject?.environments || selectedProject.environments.length === 0) {
76+
this.error(chalk.yellow("No environments found in this project."));
77+
}
6278

63-
if (projectSelected.applications.length === 0) {
64-
this.error(chalk.yellow("No applications found in this project."));
79+
const { environment } = await inquirer.prompt([
80+
{
81+
choices: selectedProject.environments.map((env) => ({
82+
name: `${env.name} (${env.description})`,
83+
value: env,
84+
})),
85+
message: "Select an environment:",
86+
name: "environment",
87+
type: "list",
88+
},
89+
]);
90+
selectedEnvironment = environment;
91+
environmentId = environment.environmentId;
92+
} else {
93+
selectedEnvironment = selectedProject?.environments?.find(e => e.environmentId === environmentId);
6594
}
6695

96+
// 3. Seleccionar application del environment
6797
if (!applicationId) {
98+
if (!selectedEnvironment?.applications || selectedEnvironment.applications.length === 0) {
99+
this.error(chalk.yellow("No applications found in this environment."));
100+
}
101+
68102
const appAnswers = await inquirer.prompt([
69103
{
70-
// @ts-ignore
71-
choices: projectSelected.applications.map((app) => ({
104+
choices: selectedEnvironment.applications.map((app: Application) => ({
72105
name: app.name,
73106
value: app.applicationId,
74107
})),

src/commands/app/deploy.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Command, Flags } from "@oclif/core";
22
import { readAuthConfig } from "../../utils/utils.js";
33
import chalk from "chalk";
4-
import { getProject, getProjects } from "../../utils/shared.js";
4+
import { getProject, getProjects, type Application } from "../../utils/shared.js";
55
import inquirer from "inquirer";
66
import type { Answers } from "./create.js";
77
import axios from "axios";
@@ -26,6 +26,11 @@ export default class AppDeploy extends Command {
2626
description: 'ID of the project',
2727
required: false,
2828
}),
29+
environmentId: Flags.string({
30+
char: 'e',
31+
description: 'ID of the environment',
32+
required: false,
33+
}),
2934
skipConfirm: Flags.boolean({
3035
char: 'y',
3136
description: 'Skip confirmation prompt',
@@ -36,13 +41,17 @@ export default class AppDeploy extends Command {
3641
public async run(): Promise<void> {
3742
const auth = await readAuthConfig(this);
3843
const { flags } = await this.parse(AppDeploy);
39-
let { projectId, applicationId } = flags;
44+
let { projectId, applicationId, environmentId } = flags;
4045

4146
// Modo interactivo si no se proporcionan los flags necesarios
42-
if (!projectId || !applicationId) {
47+
if (!projectId || !applicationId || !environmentId) {
4348
console.log(chalk.blue.bold("\n Listing all Projects \n"));
4449
const projects = await getProjects(auth, this);
4550

51+
let selectedProject;
52+
let selectedEnvironment;
53+
54+
// 1. Seleccionar proyecto
4655
if (!projectId) {
4756
const { project } = await inquirer.prompt<Answers>([
4857
{
@@ -55,20 +64,44 @@ export default class AppDeploy extends Command {
5564
type: "list",
5665
},
5766
]);
67+
selectedProject = project;
5868
projectId = project.projectId;
69+
} else {
70+
selectedProject = projects.find(p => p.projectId === projectId);
5971
}
6072

61-
const projectSelected = await getProject(projectId, auth, this);
73+
// 2. Seleccionar environment del proyecto
74+
if (!environmentId) {
75+
if (!selectedProject?.environments || selectedProject.environments.length === 0) {
76+
this.error(chalk.yellow("No environments found in this project."));
77+
}
6278

63-
if (projectSelected.applications.length === 0) {
64-
this.error(chalk.yellow("No applications found in this project."));
79+
const { environment } = await inquirer.prompt([
80+
{
81+
choices: selectedProject.environments.map((env) => ({
82+
name: `${env.name} (${env.description})`,
83+
value: env,
84+
})),
85+
message: "Select an environment:",
86+
name: "environment",
87+
type: "list",
88+
},
89+
]);
90+
selectedEnvironment = environment;
91+
environmentId = environment.environmentId;
92+
} else {
93+
selectedEnvironment = selectedProject?.environments?.find(e => e.environmentId === environmentId);
6594
}
6695

96+
// 3. Seleccionar application del environment
6797
if (!applicationId) {
98+
if (!selectedEnvironment?.applications || selectedEnvironment.applications.length === 0) {
99+
this.error(chalk.yellow("No applications found in this environment."));
100+
}
101+
68102
const appAnswers = await inquirer.prompt([
69103
{
70-
// @ts-ignore
71-
choices: projectSelected.applications.map((app) => ({
104+
choices: selectedEnvironment.applications.map((app: Application) => ({
72105
name: app.name,
73106
value: app.applicationId,
74107
})),

src/commands/app/stop.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Command, Flags } from "@oclif/core";
22
import { readAuthConfig } from "../../utils/utils.js";
33
import chalk from "chalk";
44
import inquirer from "inquirer";
5-
import { getProject, getProjects } from "../../utils/shared.js";
5+
import { getProject, getProjects, type Application } from "../../utils/shared.js";
66
import type { Answers } from "./create.js";
77
import axios from "axios";
88

@@ -17,6 +17,11 @@ export default class AppStop extends Command {
1717
description: 'ID of the project',
1818
required: false,
1919
}),
20+
environmentId: Flags.string({
21+
char: 'e',
22+
description: 'ID of the environment',
23+
required: false,
24+
}),
2025
applicationId: Flags.string({
2126
char: 'a',
2227
description: 'ID of the application to stop',
@@ -32,13 +37,17 @@ export default class AppStop extends Command {
3237
public async run(): Promise<void> {
3338
const auth = await readAuthConfig(this);
3439
const { flags } = await this.parse(AppStop);
35-
let { projectId, applicationId } = flags;
40+
let { projectId, environmentId, applicationId } = flags;
3641

3742
// Modo interactivo si no se proporcionan los flags necesarios
38-
if (!projectId || !applicationId) {
43+
if (!projectId || !environmentId || !applicationId) {
3944
console.log(chalk.blue.bold("\n Listing all Projects \n"));
4045
const projects = await getProjects(auth, this);
4146

47+
let selectedProject;
48+
let selectedEnvironment;
49+
50+
// 1. Seleccionar proyecto
4251
if (!projectId) {
4352
const { project } = await inquirer.prompt<Answers>([
4453
{
@@ -51,19 +60,44 @@ export default class AppStop extends Command {
5160
type: "list",
5261
},
5362
]);
63+
selectedProject = project;
5464
projectId = project.projectId;
65+
} else {
66+
selectedProject = projects.find(p => p.projectId === projectId);
5567
}
5668

57-
const projectSelected = await getProject(projectId, auth, this);
69+
// 2. Seleccionar environment del proyecto
70+
if (!environmentId) {
71+
if (!selectedProject?.environments || selectedProject.environments.length === 0) {
72+
this.error(chalk.yellow("No environments found in this project."));
73+
}
5874

59-
if (projectSelected.applications.length === 0) {
60-
this.error(chalk.yellow("No applications found in this project."));
75+
const { environment } = await inquirer.prompt([
76+
{
77+
choices: selectedProject.environments.map((env) => ({
78+
name: `${env.name} (${env.description})`,
79+
value: env,
80+
})),
81+
message: "Select an environment:",
82+
name: "environment",
83+
type: "list",
84+
},
85+
]);
86+
selectedEnvironment = environment;
87+
environmentId = environment.environmentId;
88+
} else {
89+
selectedEnvironment = selectedProject?.environments?.find(e => e.environmentId === environmentId);
6190
}
6291

92+
// 3. Seleccionar application del environment
6393
if (!applicationId) {
94+
if (!selectedEnvironment?.applications || selectedEnvironment.applications.length === 0) {
95+
this.error(chalk.yellow("No applications found in this environment."));
96+
}
97+
6498
const appAnswers = await inquirer.prompt([
6599
{
66-
choices: projectSelected.applications.map((app: { name: string; applicationId: string }) => ({
100+
choices: selectedEnvironment.applications.map((app: Application) => ({
67101
name: app.name,
68102
value: app.applicationId,
69103
})),

src/commands/authenticate.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,3 @@ export default class Authenticate extends Command {
103103
}
104104
}
105105
}
106-
// curl -X 'GET' \
107-
// 'https://panel.jinza.app/api/project.all' \
108-
// -H 'accept: application/json' \
109-
// -H 'x-api-key: EawCkTREMhxoAqvCxJFZurgCGoDZPjYHHrLgUPghRjJTpXLaahFdhCOGfABZXTRP'

0 commit comments

Comments
 (0)