Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@dokploy/cli",
"description": "A CLI to manage dokploy server remotely",
"version": "v0.2.7",
"version": "v0.2.8",
"author": "Mauricio Siu",
"licenses": [{
"type": "MIT",
Expand Down
36 changes: 34 additions & 2 deletions src/commands/app/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export default class AppCreate extends Command {
description: "ID of the project",
required: false,
}),
environmentId: Flags.string({
char: "e",
description: "ID of the environment",
required: false,
}),
name: Flags.string({
char: "n",
description: "Application name",
Expand All @@ -46,13 +51,16 @@ export default class AppCreate extends Command {
public async run(): Promise<void> {
const auth = await readAuthConfig(this);
const { flags } = await this.parse(AppCreate);
let { projectId, name, description, appName } = flags;
let { projectId, environmentId, name, description, appName } = flags;

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

let selectedProject;

// 1. Seleccionar proyecto
if (!projectId) {
const { project } = await inquirer.prompt<Answers>([
{
Expand All @@ -65,7 +73,30 @@ export default class AppCreate extends Command {
type: "list",
},
]);
selectedProject = project;
projectId = project.projectId;
} else {
selectedProject = projects.find(p => p.projectId === projectId);
}

// 2. Seleccionar environment del proyecto
if (!environmentId) {
if (!selectedProject?.environments || selectedProject.environments.length === 0) {
this.error(chalk.yellow("No environments found in this project."));
}

const { environment } = await inquirer.prompt([
{
choices: selectedProject.environments.map((env) => ({
name: `${env.name} (${env.description})`,
value: env,
})),
message: "Select an environment:",
name: "environment",
type: "list",
},
]);
environmentId = environment.environmentId;
}

if (!name || !appName) {
Expand Down Expand Up @@ -128,6 +159,7 @@ export default class AppCreate extends Command {
appDescription: description,
appName,
projectId,
environmentId,
},
},
{
Expand Down
49 changes: 41 additions & 8 deletions src/commands/app/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import axios from "axios";
import chalk from "chalk";
import inquirer from "inquirer";

import { getProject, getProjects } from "../../utils/shared.js";
import { getProject, getProjects, type Application } from "../../utils/shared.js";
import { readAuthConfig } from "../../utils/utils.js";
import type { Answers } from "./create.js";

Expand All @@ -21,6 +21,11 @@ export default class AppDelete extends Command {
description: "ID of the project",
required: false,
}),
environmentId: Flags.string({
char: "e",
description: "ID of the environment",
required: false,
}),
applicationId: Flags.string({
char: 'a',
description: 'ID of the application to delete',
Expand All @@ -36,13 +41,17 @@ export default class AppDelete extends Command {
public async run(): Promise<void> {
const auth = await readAuthConfig(this);
const { flags } = await this.parse(AppDelete);
let { projectId, applicationId } = flags;
let { projectId, environmentId, applicationId } = flags;

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

let selectedProject;
let selectedEnvironment;

// 1. Seleccionar proyecto
if (!projectId) {
const { project } = await inquirer.prompt<Answers>([
{
Expand All @@ -55,20 +64,44 @@ export default class AppDelete extends Command {
type: "list",
},
]);
selectedProject = project;
projectId = project.projectId;
} else {
selectedProject = projects.find(p => p.projectId === projectId);
}

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

if (projectSelected.applications.length === 0) {
this.error(chalk.yellow("No applications found in this project."));
const { environment } = await inquirer.prompt([
{
choices: selectedProject.environments.map((env) => ({
name: `${env.name} (${env.description})`,
value: env,
})),
message: "Select an environment:",
name: "environment",
type: "list",
},
]);
selectedEnvironment = environment;
environmentId = environment.environmentId;
} else {
selectedEnvironment = selectedProject?.environments?.find(e => e.environmentId === environmentId);
}

// 3. Seleccionar application del environment
if (!applicationId) {
if (!selectedEnvironment?.applications || selectedEnvironment.applications.length === 0) {
this.error(chalk.yellow("No applications found in this environment."));
}

const appAnswers = await inquirer.prompt([
{
// @ts-ignore
choices: projectSelected.applications.map((app) => ({
choices: selectedEnvironment.applications.map((app: Application) => ({
name: app.name,
value: app.applicationId,
})),
Expand Down
49 changes: 41 additions & 8 deletions src/commands/app/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Command, Flags } from "@oclif/core";
import { readAuthConfig } from "../../utils/utils.js";
import chalk from "chalk";
import { getProject, getProjects } from "../../utils/shared.js";
import { getProject, getProjects, type Application } from "../../utils/shared.js";
import inquirer from "inquirer";
import type { Answers } from "./create.js";
import axios from "axios";
Expand All @@ -26,6 +26,11 @@ export default class AppDeploy extends Command {
description: 'ID of the project',
required: false,
}),
environmentId: Flags.string({
char: 'e',
description: 'ID of the environment',
required: false,
}),
skipConfirm: Flags.boolean({
char: 'y',
description: 'Skip confirmation prompt',
Expand All @@ -36,13 +41,17 @@ export default class AppDeploy extends Command {
public async run(): Promise<void> {
const auth = await readAuthConfig(this);
const { flags } = await this.parse(AppDeploy);
let { projectId, applicationId } = flags;
let { projectId, applicationId, environmentId } = flags;

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

let selectedProject;
let selectedEnvironment;

// 1. Seleccionar proyecto
if (!projectId) {
const { project } = await inquirer.prompt<Answers>([
{
Expand All @@ -55,20 +64,44 @@ export default class AppDeploy extends Command {
type: "list",
},
]);
selectedProject = project;
projectId = project.projectId;
} else {
selectedProject = projects.find(p => p.projectId === projectId);
}

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

if (projectSelected.applications.length === 0) {
this.error(chalk.yellow("No applications found in this project."));
const { environment } = await inquirer.prompt([
{
choices: selectedProject.environments.map((env) => ({
name: `${env.name} (${env.description})`,
value: env,
})),
message: "Select an environment:",
name: "environment",
type: "list",
},
]);
selectedEnvironment = environment;
environmentId = environment.environmentId;
} else {
selectedEnvironment = selectedProject?.environments?.find(e => e.environmentId === environmentId);
}

// 3. Seleccionar application del environment
if (!applicationId) {
if (!selectedEnvironment?.applications || selectedEnvironment.applications.length === 0) {
this.error(chalk.yellow("No applications found in this environment."));
}

const appAnswers = await inquirer.prompt([
{
// @ts-ignore
choices: projectSelected.applications.map((app) => ({
choices: selectedEnvironment.applications.map((app: Application) => ({
name: app.name,
value: app.applicationId,
})),
Expand Down
48 changes: 41 additions & 7 deletions src/commands/app/stop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Command, Flags } from "@oclif/core";
import { readAuthConfig } from "../../utils/utils.js";
import chalk from "chalk";
import inquirer from "inquirer";
import { getProject, getProjects } from "../../utils/shared.js";
import { getProject, getProjects, type Application } from "../../utils/shared.js";
import type { Answers } from "./create.js";
import axios from "axios";

Expand All @@ -17,6 +17,11 @@ export default class AppStop extends Command {
description: 'ID of the project',
required: false,
}),
environmentId: Flags.string({
char: 'e',
description: 'ID of the environment',
required: false,
}),
applicationId: Flags.string({
char: 'a',
description: 'ID of the application to stop',
Expand All @@ -32,13 +37,17 @@ export default class AppStop extends Command {
public async run(): Promise<void> {
const auth = await readAuthConfig(this);
const { flags } = await this.parse(AppStop);
let { projectId, applicationId } = flags;
let { projectId, environmentId, applicationId } = flags;

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

let selectedProject;
let selectedEnvironment;

// 1. Seleccionar proyecto
if (!projectId) {
const { project } = await inquirer.prompt<Answers>([
{
Expand All @@ -51,19 +60,44 @@ export default class AppStop extends Command {
type: "list",
},
]);
selectedProject = project;
projectId = project.projectId;
} else {
selectedProject = projects.find(p => p.projectId === projectId);
}

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

if (projectSelected.applications.length === 0) {
this.error(chalk.yellow("No applications found in this project."));
const { environment } = await inquirer.prompt([
{
choices: selectedProject.environments.map((env) => ({
name: `${env.name} (${env.description})`,
value: env,
})),
message: "Select an environment:",
name: "environment",
type: "list",
},
]);
selectedEnvironment = environment;
environmentId = environment.environmentId;
} else {
selectedEnvironment = selectedProject?.environments?.find(e => e.environmentId === environmentId);
}

// 3. Seleccionar application del environment
if (!applicationId) {
if (!selectedEnvironment?.applications || selectedEnvironment.applications.length === 0) {
this.error(chalk.yellow("No applications found in this environment."));
}

const appAnswers = await inquirer.prompt([
{
choices: projectSelected.applications.map((app: { name: string; applicationId: string }) => ({
choices: selectedEnvironment.applications.map((app: Application) => ({
name: app.name,
value: app.applicationId,
})),
Expand Down
4 changes: 0 additions & 4 deletions src/commands/authenticate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,3 @@ export default class Authenticate extends Command {
}
}
}
// curl -X 'GET' \
// 'https://panel.jinza.app/api/project.all' \
// -H 'accept: application/json' \
// -H 'x-api-key: EawCkTREMhxoAqvCxJFZurgCGoDZPjYHHrLgUPghRjJTpXLaahFdhCOGfABZXTRP'
Loading
Loading