mirror of
https://github.com/Dokploy/cli.git
synced 2026-06-15 20:25:22 +02:00
feat: enhance CLI commands with improved flags and error handling
This commit introduces several improvements across multiple CLI commands: - Added new flags for more flexible command usage - Implemented interactive mode for commands when flags are not provided - Improved error handling and messaging - Added support for environment variable authentication - Standardized confirmation prompts and error messages - Enhanced type safety with TypeScript improvements
This commit is contained in:
@@ -22,65 +22,112 @@ export default class AppCreate extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Application name",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Application description",
|
||||
required: false,
|
||||
}),
|
||||
appName: Flags.string({
|
||||
description: "Docker app name",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(AppCreate);
|
||||
let { projectId, name, description, appName } = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !name || !appName) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the application in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
if (!name || !appName) {
|
||||
const appDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the application name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Application name is required"),
|
||||
default: name,
|
||||
},
|
||||
{
|
||||
message: "Enter the application description (optional):",
|
||||
name: "appDescription",
|
||||
type: "input",
|
||||
default: description,
|
||||
},
|
||||
]);
|
||||
|
||||
name = appDetails.name;
|
||||
description = appDetails.appDescription;
|
||||
|
||||
const appNamePrompt = await inquirer.prompt([
|
||||
{
|
||||
default: appName || `${slugify(name)}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
appName = appNamePrompt.appName;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the application in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this application?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
projectId = project.projectId;
|
||||
|
||||
const appDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the application name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Application name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the application description (optional):",
|
||||
name: "appDescription",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
const appName = await inquirer.prompt([
|
||||
{
|
||||
default: `${slugify(project.name)}-${appDetails.name}`,
|
||||
message: "Enter the App name: (optional):",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("Application creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/application.create`,
|
||||
{
|
||||
json: {
|
||||
...appDetails,
|
||||
appName: appName.appName,
|
||||
projectId: project.projectId,
|
||||
name,
|
||||
appDescription: description,
|
||||
appName,
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -95,9 +142,9 @@ export default class AppCreate extends Command {
|
||||
this.error(chalk.red("Error creating application"));
|
||||
}
|
||||
|
||||
this.log(
|
||||
chalk.green(`Application '${appDetails.name}' created successfully.`),
|
||||
);
|
||||
this.log(chalk.green(`Application '${name}' created successfully.`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating application: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,55 +21,68 @@ export default class AppDelete extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
applicationId: Flags.string({
|
||||
char: 'a',
|
||||
description: 'ID of the application to delete',
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: 'y',
|
||||
description: 'Skip confirmation prompt',
|
||||
default: false,
|
||||
})
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(AppDelete);
|
||||
let { projectId, applicationId } = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !applicationId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the application in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to delete the application from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
projectId = project.projectId;
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.applications.length === 0) {
|
||||
this.error(chalk.yellow("No applications found in this project."));
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.applications.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.applicationId,
|
||||
})),
|
||||
message: "Select the application to delete:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
if (!applicationId) {
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.applications.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.applicationId,
|
||||
})),
|
||||
message: "Select the application to delete:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
applicationId = appAnswers.selectedApp;
|
||||
}
|
||||
}
|
||||
|
||||
const applicationId = appAnswers.selectedApp;
|
||||
|
||||
// // Confirmar eliminación
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
@@ -82,7 +95,9 @@ export default class AppDelete extends Command {
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("Application deletion cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const deleteResponse = await axios.post(
|
||||
`${auth.url}/api/trpc/application.delete`,
|
||||
{
|
||||
@@ -103,6 +118,8 @@ export default class AppDelete extends Command {
|
||||
}
|
||||
|
||||
this.log(chalk.green("Application deleted successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Failed to delete application: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../utils/shared.js";
|
||||
@@ -9,81 +9,116 @@ import axios from "axios";
|
||||
export default class AppDeploy extends Command {
|
||||
static description = "Deploy an application to a project.";
|
||||
|
||||
static examples = ["$ <%= config.bin %> app deploy"];
|
||||
static examples = [
|
||||
"$ <%= config.bin %> app deploy",
|
||||
"$ <%= config.bin %> app deploy --applicationId myAppId",
|
||||
"$ DOKPLOY_URL=xxx DOKPLOY_AUTH_TOKEN=xxx <%= config.bin %> app deploy --applicationId myAppId"
|
||||
];
|
||||
|
||||
static flags = {
|
||||
applicationId: Flags.string({
|
||||
char: 'a',
|
||||
description: 'ID of the application to deploy',
|
||||
required: false,
|
||||
}),
|
||||
projectId: Flags.string({
|
||||
char: 'p',
|
||||
description: 'ID of the project',
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: 'y',
|
||||
description: 'Skip confirmation prompt',
|
||||
default: false,
|
||||
})
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(AppDeploy);
|
||||
let { projectId, applicationId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !applicationId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the application from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the application in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.applications.length === 0) {
|
||||
this.error(chalk.yellow("No applications found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.applications.length === 0) {
|
||||
this.error(chalk.yellow("No applications found in this project."));
|
||||
if (!applicationId) {
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.applications.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.applicationId,
|
||||
})),
|
||||
message: "Select the application to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
applicationId = appAnswers.selectedApp;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.applications.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.applicationId,
|
||||
})),
|
||||
message: "Select the application to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const applicationId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this application?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("Application deployment cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/application.deploy`,
|
||||
{
|
||||
json: {
|
||||
applicationId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this application?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying application"));
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("Application deployment cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/application.deploy`,
|
||||
{
|
||||
json: {
|
||||
applicationId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying application"));
|
||||
}
|
||||
this.log(chalk.green("Application deploy successful."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deploying application: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Application deploy successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
@@ -11,79 +11,109 @@ export default class AppStop extends Command {
|
||||
|
||||
static examples = ["$ <%= config.bin %> app stop"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: 'p',
|
||||
description: 'ID of the project',
|
||||
required: false,
|
||||
}),
|
||||
applicationId: Flags.string({
|
||||
char: 'a',
|
||||
description: 'ID of the application to stop',
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: 'y',
|
||||
description: 'Skip confirmation prompt',
|
||||
default: false,
|
||||
})
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(AppStop);
|
||||
let { projectId, applicationId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !applicationId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the application from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the application in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.applications.length === 0) {
|
||||
this.error(chalk.yellow("No applications found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.applications.length === 0) {
|
||||
this.error(chalk.yellow("No applications found in this project."));
|
||||
if (!applicationId) {
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
choices: projectSelected.applications.map((app: { name: string; applicationId: string }) => ({
|
||||
name: app.name,
|
||||
value: app.applicationId,
|
||||
})),
|
||||
message: "Select the application to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
applicationId = appAnswers.selectedApp;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.applications.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.applicationId,
|
||||
})),
|
||||
message: "Select the application to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const applicationId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this application?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("Application stop cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/application.stop`,
|
||||
{
|
||||
json: {
|
||||
applicationId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this application?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping application"));
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("Application stop cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/application.stop`,
|
||||
{
|
||||
json: {
|
||||
applicationId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping application"));
|
||||
}
|
||||
this.log(chalk.green("Application stop successful."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error stopping application: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Application stop successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,93 +18,194 @@ export default class DatabaseMariadbCreate extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Database name",
|
||||
required: false,
|
||||
}),
|
||||
databaseName: Flags.string({
|
||||
description: "MariaDB database name",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Database description",
|
||||
required: false,
|
||||
}),
|
||||
databaseRootPassword: Flags.string({
|
||||
description: "Database root password",
|
||||
required: false,
|
||||
}),
|
||||
databasePassword: Flags.string({
|
||||
description: "Database password",
|
||||
required: false,
|
||||
}),
|
||||
databaseUser: Flags.string({
|
||||
description: "Database user",
|
||||
default: "mariadb",
|
||||
}),
|
||||
dockerImage: Flags.string({
|
||||
description: "Docker image",
|
||||
default: "mariadb:11",
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
appName: Flags.string({
|
||||
description: "App name",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseMariadbCreate);
|
||||
let {
|
||||
projectId,
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databaseRootPassword,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName
|
||||
} = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !name || !databaseName || !appName) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the MariaDB instance in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
if (!name || !databaseName || !appName) {
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: name,
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: databaseName,
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
default: description,
|
||||
},
|
||||
{
|
||||
message: "Database Root Password (optional):",
|
||||
name: "databaseRootPassword",
|
||||
type: "password",
|
||||
default: databaseRootPassword,
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
default: databasePassword,
|
||||
},
|
||||
{
|
||||
default: dockerImage || "mariadb:11",
|
||||
message: "Docker Image (default: mariadb:11):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: databaseUser || "mariadb",
|
||||
message: "Database User: (default: mariadb):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
name = dbDetails.name;
|
||||
databaseName = dbDetails.databaseName;
|
||||
description = dbDetails.description;
|
||||
databaseRootPassword = dbDetails.databaseRootPassword;
|
||||
databasePassword = dbDetails.databasePassword;
|
||||
dockerImage = dbDetails.dockerImage;
|
||||
databaseUser = dbDetails.databaseUser;
|
||||
|
||||
const appNamePrompt = await inquirer.prompt([
|
||||
{
|
||||
default: appName || `${slugify(name)}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
appName = appNamePrompt.appName;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the MariaDB database in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this MariaDB instance?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
projectId = project.projectId;
|
||||
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
message: "Database Root Password (optional):",
|
||||
name: "databaseRootPassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
default: "mariadb:11",
|
||||
message: "Docker Image (default: mariadb:11):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: "mariadb",
|
||||
message: "Database User: (default: mariadb):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
const appName = await inquirer.prompt([
|
||||
{
|
||||
default: `${slugify(project.name)}-${dbDetails.name}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("MariaDB creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(JSON.stringify({
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databaseRootPassword,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
}, null, 2));
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mariadb.create`,
|
||||
{
|
||||
json: {
|
||||
...dbDetails,
|
||||
appName: appName.appName,
|
||||
projectId: project.projectId,
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databaseRootPassword,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -116,14 +217,12 @@ export default class DatabaseMariadbCreate extends Command {
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating MariaDB database"));
|
||||
this.error(chalk.red("Error creating MariaDB instance", response.data.result.data.json));
|
||||
}
|
||||
|
||||
this.log(
|
||||
chalk.green(
|
||||
`MariaDB database '${dbDetails.name}' created successfully.`,
|
||||
),
|
||||
);
|
||||
this.log(chalk.green(`MariaDB instance '${name}' created successfully.`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating MariaDB instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,73 +18,82 @@ export default class DatabaseMariadbDelete extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mariadbId: Flags.string({
|
||||
char: "m",
|
||||
description: "ID of the MariaDB instance to delete",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMariadbDelete);
|
||||
let { projectId } = flags;
|
||||
let { projectId, mariadbId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
if (!projectId || !mariadbId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
if (projects.length === 0) {
|
||||
this.log(chalk.yellow("No projects found."));
|
||||
return;
|
||||
if (!projectId) {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the MariaDB instance from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = answers.selectedProject;
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "selectedProject",
|
||||
message: "Select a project to delete the MariaDB database from:",
|
||||
choices: projects.map((project: any) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
},
|
||||
]);
|
||||
projectId = answers.selectedProject;
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (!projectSelected.mariadb || projectSelected.mariadb.length === 0) {
|
||||
this.error(chalk.yellow("No MariaDB instances found in this project."));
|
||||
}
|
||||
|
||||
if (!mariadbId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mariadb.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mariadbId,
|
||||
})),
|
||||
message: "Select the MariaDB instance to delete:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mariadbId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const project = await getProject(projectId, auth, this);
|
||||
|
||||
if (!project.mariadb || project.mariadb.length === 0) {
|
||||
this.log(chalk.yellow("No MariaDB databases found in this project."));
|
||||
return;
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "selectedDb",
|
||||
message: "Select the MariaDB database to delete:",
|
||||
choices: project.mariadb.map((db: any) => ({
|
||||
name: db.name,
|
||||
value: db.mariadbId,
|
||||
})),
|
||||
},
|
||||
]);
|
||||
|
||||
const mariadbId = appAnswers.selectedDb;
|
||||
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
type: "confirm",
|
||||
name: "confirmDelete",
|
||||
message: "Are you sure you want to delete this MariaDB database?",
|
||||
default: false,
|
||||
message: "Are you sure you want to delete this MariaDB instance?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.log(chalk.yellow("Database deletion cancelled."));
|
||||
return;
|
||||
this.error(chalk.yellow("MariaDB deletion cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
const deleteResponse = await axios.post(
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mariadb.remove`,
|
||||
{
|
||||
json: {
|
||||
@@ -99,15 +108,12 @@ export default class DatabaseMariadbDelete extends Command {
|
||||
},
|
||||
);
|
||||
|
||||
if (!deleteResponse.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting mariadb database"));
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting MariaDB instance"));
|
||||
}
|
||||
this.log(chalk.green("MariaDB database deleted successfully."));
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-ignore
|
||||
chalk.red(`Failed to delete MariaDB database: ${error.message}`),
|
||||
);
|
||||
this.log(chalk.green("MariaDB instance deleted successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deleting MariaDB instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
@@ -11,79 +11,110 @@ export default class DatabaseMariadbDeploy extends Command {
|
||||
|
||||
static examples = ["$ <%= config.bin %> app deploy"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mariadbId: Flags.string({
|
||||
char: "m",
|
||||
description: "ID of the MariaDB instance to deploy",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMariadbDeploy);
|
||||
let { projectId, mariadbId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mariadbId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the MariaDB in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the mariadb in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.mariadb.length === 0) {
|
||||
this.error(chalk.yellow("No MariaDB instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.mariadb.length === 0) {
|
||||
this.error(chalk.yellow("No mariadb found in this project."));
|
||||
if (!mariadbId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mariadb.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mariadbId,
|
||||
})),
|
||||
message: "Select the MariaDB instance to deploy:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mariadbId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mariadb.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.mariadbId,
|
||||
})),
|
||||
message: "Select the mariadb to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mariadbId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this mariadb?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("mariadb deployment cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mariadb.deploy`,
|
||||
{
|
||||
json: {
|
||||
mariadbId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this MariaDB instance?",
|
||||
name: "confirmDeploy",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying mariadb"));
|
||||
if (!confirmAnswers.confirmDeploy) {
|
||||
this.error(chalk.yellow("MariaDB deployment cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mariadb.deploy`,
|
||||
{
|
||||
json: {
|
||||
mariadbId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying MariaDB instance"));
|
||||
}
|
||||
this.log(chalk.green("MariaDB instance deployed successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deploying MariaDB instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Mariadb deploy successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
import axios from "axios";
|
||||
@@ -11,79 +11,110 @@ export default class DatabaseMariadbStop extends Command {
|
||||
|
||||
static examples = ["$ <%= config.bin %> mariadb stop"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mariadbId: Flags.string({
|
||||
char: "m",
|
||||
description: "ID of the MariaDB instance to stop",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMariadbStop);
|
||||
let { projectId, mariadbId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mariadbId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the MariaDB instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the mariadb in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.mariadb.length === 0) {
|
||||
this.error(chalk.yellow("No MariaDB instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.mariadb.length === 0) {
|
||||
this.error(chalk.yellow("No mariadb found in this project."));
|
||||
if (!mariadbId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mariadb.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mariadbId,
|
||||
})),
|
||||
message: "Select the MariaDB instance to stop:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mariadbId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mariadb.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.mariadbId,
|
||||
})),
|
||||
message: "Select the mariadb to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mariadbId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this mariadb?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("Mariadb stop cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mariadb.stop`,
|
||||
{
|
||||
json: {
|
||||
mariadbId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this MariaDB instance?",
|
||||
name: "confirmStop",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping mariadb"));
|
||||
if (!confirmAnswers.confirmStop) {
|
||||
this.error(chalk.yellow("MariaDB stop cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mariadb.stop`,
|
||||
{
|
||||
json: {
|
||||
mariadbId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping MariaDB instance"));
|
||||
}
|
||||
this.log(chalk.green("MariaDB instance stopped successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error stopping MariaDB instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Mariadb stop successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,114 +18,187 @@ export default class DatabaseMongoCreate extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Database name",
|
||||
required: false,
|
||||
}),
|
||||
databaseName: Flags.string({
|
||||
description: "MongoDB database name",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Database description",
|
||||
required: false,
|
||||
}),
|
||||
databasePassword: Flags.string({
|
||||
description: "Database password",
|
||||
required: false,
|
||||
}),
|
||||
databaseUser: Flags.string({
|
||||
description: "Database user",
|
||||
default: "mongo",
|
||||
}),
|
||||
dockerImage: Flags.string({
|
||||
description: "Docker image",
|
||||
default: "mongo:6",
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
appName: Flags.string({
|
||||
description: "App name",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseMongoCreate);
|
||||
let {
|
||||
projectId,
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName
|
||||
} = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !name || !databaseName || !appName || !databasePassword) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the MongoDB database in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
projectId = project.projectId;
|
||||
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
default: "mongo:6",
|
||||
message: "Docker Image (default: mongo:6):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: "mongo",
|
||||
message: "Database User: (default: mongo):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
const appName = await inquirer.prompt([
|
||||
{
|
||||
default: `${slugify(project.name)}-${dbDetails.name}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.create`,
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
json: {
|
||||
...dbDetails,
|
||||
appName: appName.appName,
|
||||
projectId: project.projectId,
|
||||
},
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the MongoDB instance in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating MongoDB database"));
|
||||
}
|
||||
|
||||
this.log(
|
||||
chalk.green(
|
||||
`MongoDB database '${dbDetails.name}' created successfully.`,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-ignore
|
||||
chalk.red(`Failed to create MongoDB database: ${error.message}`),
|
||||
);
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
if (!name || !databaseName || !appName || !databasePassword) {
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: name,
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: databaseName,
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
default: description,
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
default: databasePassword,
|
||||
},
|
||||
{
|
||||
default: dockerImage || "mongo:6",
|
||||
message: "Docker Image (default: mongo:6):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: databaseUser || "mongo",
|
||||
message: "Database User: (default: mongo):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
name = dbDetails.name;
|
||||
databaseName = dbDetails.databaseName;
|
||||
description = dbDetails.description;
|
||||
databasePassword = dbDetails.databasePassword;
|
||||
dockerImage = dbDetails.dockerImage;
|
||||
databaseUser = dbDetails.databaseUser;
|
||||
|
||||
const appNamePrompt = await inquirer.prompt([
|
||||
{
|
||||
default: appName || `${slugify(name)}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
appName = appNamePrompt.appName;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this MongoDB instance?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("MongoDB creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.create`,
|
||||
{
|
||||
json: {
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating MongoDB instance"));
|
||||
}
|
||||
|
||||
this.log(chalk.green(`MongoDB instance '${name}' created successfully.`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating MongoDB instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,76 +20,84 @@ export default class DatabaseMongoDelete extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mongoId: Flags.string({
|
||||
char: "m",
|
||||
description: "ID of the MongoDB instance to delete",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseMongoDelete);
|
||||
let { projectId } = flags;
|
||||
let { projectId, mongoId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mongoId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
if (projects.length === 0) {
|
||||
this.log(chalk.yellow("No projects found."));
|
||||
return;
|
||||
if (!projectId) {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the MongoDB instance from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = answers.selectedProject;
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project: any) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the MongoDB database from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
projectId = answers.selectedProject;
|
||||
if (!projectSelected.mongo || projectSelected.mongo.length === 0) {
|
||||
this.error(chalk.yellow("No MongoDB instances found in this project."));
|
||||
}
|
||||
|
||||
if (!mongoId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mongo.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mongoId,
|
||||
})),
|
||||
message: "Select the MongoDB instance to delete:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mongoId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const project = await getProject(projectId, auth, this);
|
||||
|
||||
if (!project.mongo || project.mongo.length === 0) {
|
||||
this.log(chalk.yellow("No MongoDB databases found in this project."));
|
||||
return;
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
choices: project.mongo.map((db: any) => ({
|
||||
name: db.name,
|
||||
value: db.mongoId,
|
||||
})),
|
||||
message: "Select the MongoDB database to delete:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mongoId = appAnswers.selectedApp;
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to delete this MongoDB database?",
|
||||
message: "Are you sure you want to delete this MongoDB instance?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.log(chalk.yellow("Database deletion cancelled."));
|
||||
return;
|
||||
this.error(chalk.yellow("MongoDB deletion cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
const deleteResponse = await axios.post(
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.remove`,
|
||||
{
|
||||
json: {
|
||||
@@ -104,16 +112,12 @@ export default class DatabaseMongoDelete extends Command {
|
||||
},
|
||||
);
|
||||
|
||||
if (!deleteResponse.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting MongoDB database"));
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting MongoDB instance"));
|
||||
}
|
||||
|
||||
this.log(chalk.green("MongoDB database deleted successfully."));
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-ignore
|
||||
chalk.red(`Failed to delete MongoDB database: ${error.message}`),
|
||||
);
|
||||
this.log(chalk.green("MongoDB instance deleted successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deleting MongoDB instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
@@ -11,79 +11,110 @@ export default class DatabaseMongoDeploy extends Command {
|
||||
|
||||
static examples = ["$ <%= config.bin %> app deploy"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mongoId: Flags.string({
|
||||
char: "m",
|
||||
description: "ID of the MongoDB instance to deploy",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMongoDeploy);
|
||||
let { projectId, mongoId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mongoId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the MongoDB instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the mongo in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.mongo.length === 0) {
|
||||
this.error(chalk.yellow("No MongoDB instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.mongo.length === 0) {
|
||||
this.error(chalk.yellow("No mongo found in this project."));
|
||||
if (!mongoId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mongo.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mongoId,
|
||||
})),
|
||||
message: "Select the MongoDB instance to deploy:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mongoId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mongo.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.mongoId,
|
||||
})),
|
||||
message: "Select the mongo to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mongoId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this mongo?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("mongo deployment cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.deploy`,
|
||||
{
|
||||
json: {
|
||||
mongoId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this MongoDB instance?",
|
||||
name: "confirmDeploy",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying mongo"));
|
||||
if (!confirmAnswers.confirmDeploy) {
|
||||
this.error(chalk.yellow("MongoDB deployment cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.deploy`,
|
||||
{
|
||||
json: {
|
||||
mongoId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying MongoDB instance"));
|
||||
}
|
||||
this.log(chalk.green("MongoDB instance deployed successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deploying MongoDB instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Mongo deploy successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
import axios from "axios";
|
||||
@@ -11,79 +11,110 @@ export default class DatabaseMongoStop extends Command {
|
||||
|
||||
static examples = ["$ <%= config.bin %> mongo stop"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mongoId: Flags.string({
|
||||
char: "m",
|
||||
description: "ID of the MongoDB instance to stop",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMongoStop);
|
||||
let { projectId, mongoId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mongoId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the MongoDB instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the mongo in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.mongo.length === 0) {
|
||||
this.error(chalk.yellow("No MongoDB instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.mongo.length === 0) {
|
||||
this.error(chalk.yellow("No mongo found in this project."));
|
||||
if (!mongoId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mongo.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mongoId,
|
||||
})),
|
||||
message: "Select the MongoDB instance to stop:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mongoId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mongo.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.mongoId,
|
||||
})),
|
||||
message: "Select the mongo to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mongoId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this mongo?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("mongo stop cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.stop`,
|
||||
{
|
||||
json: {
|
||||
mongoId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this MongoDB instance?",
|
||||
name: "confirmStop",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping mongo"));
|
||||
if (!confirmAnswers.confirmStop) {
|
||||
this.error(chalk.yellow("MongoDB stop cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mongo.stop`,
|
||||
{
|
||||
json: {
|
||||
mongoId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping MongoDB instance"));
|
||||
}
|
||||
this.log(chalk.green("MongoDB instance stopped successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error stopping MongoDB instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Mongo stop successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,119 +19,212 @@ export default class DatabaseMysqlCreate extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Database name",
|
||||
required: false,
|
||||
}),
|
||||
databaseName: Flags.string({
|
||||
description: "MySQL database name",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Database description",
|
||||
required: false,
|
||||
}),
|
||||
databaseRootPassword: Flags.string({
|
||||
description: "Database root password",
|
||||
required: false,
|
||||
}),
|
||||
databasePassword: Flags.string({
|
||||
description: "Database password",
|
||||
required: false,
|
||||
}),
|
||||
databaseUser: Flags.string({
|
||||
description: "Database user",
|
||||
default: "mysql",
|
||||
}),
|
||||
dockerImage: Flags.string({
|
||||
description: "Docker image",
|
||||
default: "mysql:8",
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
appName: Flags.string({
|
||||
description: "App name",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseMysqlCreate);
|
||||
let {
|
||||
projectId,
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databaseRootPassword,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName
|
||||
} = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !name || !databaseName || !appName || !databasePassword || !databaseRootPassword) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the MySQL database in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
projectId = project.projectId;
|
||||
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
message: "Database Root Password (optional):",
|
||||
name: "databaseRootPassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
default: "mysql:8",
|
||||
message: "Docker Image (default: mysql:8):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: "mysql",
|
||||
message: "Database User: (default: mysql):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
const appName = await inquirer.prompt([
|
||||
{
|
||||
default: `${slugify(project.name)}-${dbDetails.name}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.create`,
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
json: {
|
||||
...dbDetails,
|
||||
appName: appName.appName,
|
||||
projectId: project.projectId,
|
||||
},
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the MySQL instance in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating MySQL database"));
|
||||
}
|
||||
|
||||
this.log(
|
||||
chalk.green(
|
||||
`MySQL database '${dbDetails.name}' created successfully.`,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-ignore
|
||||
chalk.red(`Failed to create MySQL database: ${error.message}`),
|
||||
);
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
if (!name || !databaseName || !appName || !databasePassword || !databaseRootPassword) {
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: name,
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: databaseName,
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
default: description,
|
||||
},
|
||||
{
|
||||
message: "Database Root Password:",
|
||||
name: "databaseRootPassword",
|
||||
type: "password",
|
||||
default: databaseRootPassword,
|
||||
},
|
||||
{
|
||||
message: "Database password:",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
default: databasePassword,
|
||||
},
|
||||
{
|
||||
default: dockerImage || "mysql:8",
|
||||
message: "Docker Image (default: mysql:8):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: databaseUser || "mysql",
|
||||
message: "Database User: (default: mysql):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
name = dbDetails.name;
|
||||
databaseName = dbDetails.databaseName;
|
||||
description = dbDetails.description;
|
||||
databaseRootPassword = dbDetails.databaseRootPassword;
|
||||
databasePassword = dbDetails.databasePassword;
|
||||
dockerImage = dbDetails.dockerImage;
|
||||
databaseUser = dbDetails.databaseUser;
|
||||
|
||||
const appNamePrompt = await inquirer.prompt([
|
||||
{
|
||||
default: appName || `${slugify(name)}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
appName = appNamePrompt.appName;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this MySQL instance?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("MySQL creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(JSON.stringify({
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databaseRootPassword,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
}, null, 2));
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.create`,
|
||||
{
|
||||
json: {
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databaseRootPassword,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating MySQL instance", response.data.result.data.json));
|
||||
}
|
||||
|
||||
this.log(chalk.green(`MySQL instance '${name}' created successfully.`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating MySQL instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,79 +20,84 @@ export default class DatabaseMysqlDelete extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
mysqlId: Flags.string({
|
||||
char: "i",
|
||||
description: "ID of the MySQL database",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseMysqlDelete);
|
||||
let { projectId } = flags;
|
||||
let { projectId, mysqlId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mysqlId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
if (projects.length === 0) {
|
||||
this.log(chalk.yellow("No projects found."));
|
||||
return;
|
||||
if (!projectId) {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the MySQL instance from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = answers.selectedProject;
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project: any) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the MySQL database from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
projectId = answers.selectedProject;
|
||||
if (!projectSelected.mysql || projectSelected.mysql.length === 0) {
|
||||
this.error(chalk.yellow("No MySQL instances found in this project."));
|
||||
}
|
||||
|
||||
if (!mysqlId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mysql.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mysqlId,
|
||||
})),
|
||||
message: "Select the MySQL instance to delete:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mysqlId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const project = await getProject(projectId, auth, this);
|
||||
|
||||
if (!project.mysql || project.mysql.length === 0) {
|
||||
this.log(chalk.yellow("No MySQL databases found in this project."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Permitir al usuario seleccionar una aplicación
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
choices: project.mysql.map((app: any) => ({
|
||||
name: app.name,
|
||||
value: app.mysqlId,
|
||||
})),
|
||||
message: "Select the MySQL database to delete:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mysqlId = appAnswers.selectedApp;
|
||||
|
||||
// Confirmar eliminación
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to delete this mysql database?",
|
||||
message: "Are you sure you want to delete this MySQL instance?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.log(chalk.yellow("Application deletion cancelled."));
|
||||
return;
|
||||
this.error(chalk.yellow("MySQL deletion cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
// Eliminar la aplicación seleccionada
|
||||
const deleteResponse = await axios.post(
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.remove`,
|
||||
{
|
||||
json: {
|
||||
@@ -107,14 +112,12 @@ export default class DatabaseMysqlDelete extends Command {
|
||||
},
|
||||
);
|
||||
|
||||
if (!deleteResponse.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting application"));
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting MySQL instance"));
|
||||
}
|
||||
|
||||
this.log(chalk.green("Application deleted successfully."));
|
||||
} catch (error) {
|
||||
// @ts-expect-error - TS2339: Property 'data' does not exist on type 'AxiosError<any>'.
|
||||
this.error(chalk.red(`Failed to delete application: ${error.message}`));
|
||||
this.log(chalk.green("MySQL instance deleted successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deleting MySQL instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,77 +13,90 @@ export default class DatabaseMysqlDeploy extends Command {
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMysqlDeploy);
|
||||
let { projectId, mysqlId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mysqlId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the MySQL instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the mysql in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.mysql.length === 0) {
|
||||
this.error(chalk.yellow("No MySQL instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.mysql.length === 0) {
|
||||
this.error(chalk.yellow("No mysql found in this project."));
|
||||
if (!mysqlId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mysql.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mysqlId,
|
||||
})),
|
||||
message: "Select the MySQL instance to deploy:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mysqlId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mysql.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.mysqlId,
|
||||
})),
|
||||
message: "Select the mysql to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mysqlId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this mysql?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("mysql deployment cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.deploy`,
|
||||
{
|
||||
json: {
|
||||
mysqlId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this MySQL instance?",
|
||||
name: "confirmDeploy",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying mysql"));
|
||||
if (!confirmAnswers.confirmDeploy) {
|
||||
this.error(chalk.yellow("MySQL deployment cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.deploy`,
|
||||
{
|
||||
json: {
|
||||
mysqlId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying MySQL instance"));
|
||||
}
|
||||
this.log(chalk.green("MySQL instance deployed successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deploying MySQL instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Mysql deployed successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,77 +13,90 @@ export default class DatabaseMysqlStop extends Command {
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseMysqlStop);
|
||||
let { projectId, mysqlId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !mysqlId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the MySQL instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the mysql in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.mysql.length === 0) {
|
||||
this.error(chalk.yellow("No MySQL instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.mysql.length === 0) {
|
||||
this.error(chalk.yellow("No mysql found in this project."));
|
||||
if (!mysqlId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mysql.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.mysqlId,
|
||||
})),
|
||||
message: "Select the MySQL instance to stop:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
mysqlId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.mysql.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.mysqlId,
|
||||
})),
|
||||
message: "Select the mysql to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const mysqlId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this mysql?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("mysql stop cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.stop`,
|
||||
{
|
||||
json: {
|
||||
mysqlId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this MySQL instance?",
|
||||
name: "confirmStop",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping mysql"));
|
||||
if (!confirmAnswers.confirmStop) {
|
||||
this.error(chalk.yellow("MySQL stop cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/mysql.stop`,
|
||||
{
|
||||
json: {
|
||||
mysqlId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping MySQL instance"));
|
||||
}
|
||||
this.log(chalk.green("MySQL instance stopped successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error stopping MySQL instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Mysql stop successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,114 +17,198 @@ export default class DatabasePostgresCreate extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Database name",
|
||||
required: false,
|
||||
}),
|
||||
databaseName: Flags.string({
|
||||
description: "PostgreSQL database name",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Database description",
|
||||
required: false,
|
||||
}),
|
||||
databasePassword: Flags.string({
|
||||
description: "Database password",
|
||||
required: false,
|
||||
}),
|
||||
databaseUser: Flags.string({
|
||||
description: "Database user",
|
||||
default: "postgres",
|
||||
}),
|
||||
dockerImage: Flags.string({
|
||||
description: "Docker image",
|
||||
default: "postgres:15",
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
appName: Flags.string({
|
||||
description: "App name",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabasePostgresCreate);
|
||||
let {
|
||||
projectId,
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName
|
||||
} = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !name || !databaseName || !appName || !databasePassword) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the PostgreSQL database in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
projectId = project.projectId;
|
||||
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
default: "postgres:15",
|
||||
message: "Docker Image (default: postgres:15):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: "postgres",
|
||||
message: "Database User: (default: postgres):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
const appName = await inquirer.prompt([
|
||||
{
|
||||
default: `${slugify(project.name)}-${dbDetails.name}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.create`,
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
json: {
|
||||
...dbDetails,
|
||||
appName: appName.appName,
|
||||
projectId: project.projectId,
|
||||
},
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the PostgreSQL instance in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating PostgreSQL database"));
|
||||
}
|
||||
|
||||
this.log(
|
||||
chalk.green(
|
||||
`PostgreSQL database '${dbDetails.name}' created successfully.`,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-ignore
|
||||
chalk.red(`Failed to create PostgreSQL database: ${error.message}`),
|
||||
);
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
if (!name || !databaseName || !appName || !databasePassword) {
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: name,
|
||||
},
|
||||
{
|
||||
message: "Database name:",
|
||||
name: "databaseName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
default: databaseName,
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
default: description,
|
||||
},
|
||||
{
|
||||
message: "Database password:",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
default: databasePassword,
|
||||
},
|
||||
{
|
||||
default: dockerImage || "postgres:15",
|
||||
message: "Docker Image (default: postgres:15):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
default: databaseUser || "postgres",
|
||||
message: "Database User: (default: postgres):",
|
||||
name: "databaseUser",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
name = dbDetails.name;
|
||||
databaseName = dbDetails.databaseName;
|
||||
description = dbDetails.description;
|
||||
databasePassword = dbDetails.databasePassword;
|
||||
dockerImage = dbDetails.dockerImage;
|
||||
databaseUser = dbDetails.databaseUser;
|
||||
|
||||
const appNamePrompt = await inquirer.prompt([
|
||||
{
|
||||
default: appName || `${slugify(name)}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
appName = appNamePrompt.appName;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this PostgreSQL instance?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("PostgreSQL creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(JSON.stringify({
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
}, null, 2));
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.create`,
|
||||
{
|
||||
json: {
|
||||
name,
|
||||
databaseName,
|
||||
description,
|
||||
databasePassword,
|
||||
databaseUser,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating PostgreSQL instance", response.data.result.data.json));
|
||||
}
|
||||
|
||||
this.log(chalk.green(`PostgreSQL instance '${name}' created successfully.`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating PostgreSQL instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,78 +20,84 @@ export default class DatabasePostgresDelete extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
postgresId: Flags.string({
|
||||
char: "d",
|
||||
description: "ID of the PostgreSQL database",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabasePostgresDelete);
|
||||
let { projectId } = flags;
|
||||
let { projectId, postgresId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !postgresId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
if (projects.length === 0) {
|
||||
this.log(chalk.yellow("No projects found."));
|
||||
return;
|
||||
if (!projectId) {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the PostgreSQL instance from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = answers.selectedProject;
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project: any) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the PostgreSQL database from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
projectId = answers.selectedProject;
|
||||
if (!projectSelected.postgres || projectSelected.postgres.length === 0) {
|
||||
this.error(chalk.yellow("No PostgreSQL instances found in this project."));
|
||||
}
|
||||
|
||||
if (!postgresId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.postgres.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.postgresId,
|
||||
})),
|
||||
message: "Select the PostgreSQL instance to delete:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
postgresId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const project = await getProject(projectId, auth, this);
|
||||
|
||||
if (!project.postgres || project.postgres.length === 0) {
|
||||
this.log(
|
||||
chalk.yellow("No PostgreSQL databases found in this project."),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
choices: project.postgres.map((db: any) => ({
|
||||
name: db.name,
|
||||
value: db.postgresId,
|
||||
})),
|
||||
message: "Select the PostgreSQL database to delete:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const postgresId = appAnswers.selectedApp;
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to delete this postgres database?",
|
||||
message: "Are you sure you want to delete this PostgreSQL instance?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.log(chalk.yellow("Database deletion cancelled."));
|
||||
return;
|
||||
this.error(chalk.yellow("PostgreSQL deletion cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
const deleteResponse = await axios.post(
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.remove`,
|
||||
{
|
||||
json: {
|
||||
@@ -106,14 +112,12 @@ export default class DatabasePostgresDelete extends Command {
|
||||
},
|
||||
);
|
||||
|
||||
if (!deleteResponse.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting PostgreSQL database"));
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting PostgreSQL instance"));
|
||||
}
|
||||
|
||||
this.log(chalk.green("PostgreSQL database deleted successfully."));
|
||||
} catch (error) {
|
||||
// @ts-expect-error - TS2339: Property 'data' does not exist on type 'AxiosError<any>'.
|
||||
this.error(chalk.red(`Failed to delete application: ${error.message}`));
|
||||
this.log(chalk.green("PostgreSQL instance deleted successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deleting PostgreSQL instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
@@ -7,83 +7,114 @@ import type { Answers } from "../../app/create.js";
|
||||
import axios from "axios";
|
||||
|
||||
export default class DatabasePostgresDeploy extends Command {
|
||||
static description = "Deploy an postgres to a project.";
|
||||
static description = "Deploy a PostgreSQL instance to a project.";
|
||||
|
||||
static examples = ["$ <%= config.bin %> app deploy"];
|
||||
static examples = ["$ <%= config.bin %> postgres deploy"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
postgresId: Flags.string({
|
||||
char: "d",
|
||||
description: "ID of the PostgreSQL instance to deploy",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabasePostgresDeploy);
|
||||
let { projectId, postgresId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !postgresId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the PostgreSQL instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the postgres in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.postgres.length === 0) {
|
||||
this.error(chalk.yellow("No PostgreSQL instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.postgres.length === 0) {
|
||||
this.error(chalk.yellow("No postgres found in this project."));
|
||||
if (!postgresId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.postgres.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.postgresId,
|
||||
})),
|
||||
message: "Select the PostgreSQL instance to deploy:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
postgresId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.postgres.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.postgresId,
|
||||
})),
|
||||
message: "Select the postgres to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const postgresId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this postgres?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("postgres deployment cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.deploy`,
|
||||
{
|
||||
json: {
|
||||
postgresId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this PostgreSQL instance?",
|
||||
name: "confirmDeploy",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying postgres"));
|
||||
if (!confirmAnswers.confirmDeploy) {
|
||||
this.error(chalk.yellow("PostgreSQL deployment cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.deploy`,
|
||||
{
|
||||
json: {
|
||||
postgresId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying PostgreSQL instance"));
|
||||
}
|
||||
this.log(chalk.green("PostgreSQL instance deployed successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deploying PostgreSQL instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Postgres deployed successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,89 +1,120 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
import axios from "axios";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
import inquirer from "inquirer";
|
||||
import type { Answers } from "../../app/create.js";
|
||||
import axios from "axios";
|
||||
|
||||
export default class DatabasePostgresStop extends Command {
|
||||
static description = "Stop an postgres from a project.";
|
||||
static description = "Stop a PostgreSQL instance in a project.";
|
||||
|
||||
static examples = ["$ <%= config.bin %> postgres stop"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
postgresId: Flags.string({
|
||||
char: "d",
|
||||
description: "ID of the PostgreSQL instance to stop",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabasePostgresStop);
|
||||
let { projectId, postgresId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !postgresId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the PostgreSQL instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the postgres in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.postgres.length === 0) {
|
||||
this.error(chalk.yellow("No PostgreSQL instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.postgres.length === 0) {
|
||||
this.error(chalk.yellow("No postgres found in this project."));
|
||||
if (!postgresId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.postgres.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.postgresId,
|
||||
})),
|
||||
message: "Select the PostgreSQL instance to stop:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
postgresId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.postgres.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.postgresId,
|
||||
})),
|
||||
message: "Select the postgres to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const postgresId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this postgres?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("postgres stop cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.stop`,
|
||||
{
|
||||
json: {
|
||||
postgresId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this PostgreSQL instance?",
|
||||
name: "confirmStop",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping postgres"));
|
||||
if (!confirmAnswers.confirmStop) {
|
||||
this.error(chalk.yellow("PostgreSQL stop cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/postgres.stop`,
|
||||
{
|
||||
json: {
|
||||
postgresId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping PostgreSQL instance"));
|
||||
}
|
||||
this.log(chalk.green("PostgreSQL instance stopped successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error stopping PostgreSQL instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Postgres stop successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { getProjects } from "../../../utils/shared.js";
|
||||
import type { Answers } from "../../app/create.js";
|
||||
|
||||
export default class DatabaseRedisCreate extends Command {
|
||||
static description = "Create a new Redis database within a project.";
|
||||
static description = "Create a new Redis instance within a project.";
|
||||
|
||||
static examples = ["$ <%= config.bin %> redis create"];
|
||||
|
||||
@@ -18,102 +18,169 @@ export default class DatabaseRedisCreate extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Instance name",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Instance description",
|
||||
required: false,
|
||||
}),
|
||||
databasePassword: Flags.string({
|
||||
description: "Redis password",
|
||||
required: false,
|
||||
}),
|
||||
dockerImage: Flags.string({
|
||||
description: "Docker image",
|
||||
default: "redis:7",
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
appName: Flags.string({
|
||||
description: "App name",
|
||||
required: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseRedisCreate);
|
||||
let {
|
||||
projectId,
|
||||
name,
|
||||
description,
|
||||
databasePassword,
|
||||
dockerImage,
|
||||
appName
|
||||
} = flags;
|
||||
|
||||
let { projectId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !name || !appName || !databasePassword) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the Redis database in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
projectId = project.projectId;
|
||||
|
||||
const dbDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Database name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the database description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
message: "Database password (optional):",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
},
|
||||
{
|
||||
default: "redis:7",
|
||||
message: "Docker Image (default: redis:7):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
const appName = await inquirer.prompt([
|
||||
{
|
||||
default: `${slugify(project.name)}-${dbDetails.name}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.create`,
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
json: {
|
||||
...dbDetails,
|
||||
appName: appName.appName,
|
||||
projectId: project.projectId,
|
||||
},
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to create the Redis instance in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating Redis database"));
|
||||
}
|
||||
|
||||
this.log(
|
||||
chalk.green(
|
||||
`Redis database '${dbDetails.name}' created successfully.`,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-ignore
|
||||
chalk.red(`Failed to create Redis database: ${error.message}`),
|
||||
);
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
if (!name || !appName || !databasePassword) {
|
||||
const redisDetails = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Instance name is required"),
|
||||
default: name,
|
||||
},
|
||||
{
|
||||
message: "Enter the instance description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
default: description,
|
||||
},
|
||||
{
|
||||
message: "Redis password:",
|
||||
name: "databasePassword",
|
||||
type: "password",
|
||||
default: databasePassword,
|
||||
},
|
||||
{
|
||||
default: dockerImage || "redis:7",
|
||||
message: "Docker Image (default: redis:7):",
|
||||
name: "dockerImage",
|
||||
type: "input",
|
||||
},
|
||||
]);
|
||||
|
||||
name = redisDetails.name;
|
||||
description = redisDetails.description;
|
||||
databasePassword = redisDetails.databasePassword;
|
||||
dockerImage = redisDetails.dockerImage;
|
||||
|
||||
const appNamePrompt = await inquirer.prompt([
|
||||
{
|
||||
default: appName || `${slugify(name)}`,
|
||||
message: "Enter the App name:",
|
||||
name: "appName",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "App name is required"),
|
||||
},
|
||||
]);
|
||||
|
||||
appName = appNamePrompt.appName;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this Redis instance?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("Redis creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(JSON.stringify({
|
||||
name,
|
||||
description,
|
||||
databasePassword,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
}, null, 2));
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.create`,
|
||||
{
|
||||
json: {
|
||||
name,
|
||||
description,
|
||||
databasePassword,
|
||||
dockerImage,
|
||||
appName,
|
||||
projectId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error creating Redis instance", response.data.result.data.json));
|
||||
}
|
||||
|
||||
this.log(chalk.green(`Redis instance '${name}' created successfully.`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating Redis instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import axios from "axios";
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
import inquirer from "inquirer";
|
||||
import type { Answers } from "../../app/create.js";
|
||||
import axios from "axios";
|
||||
|
||||
export default class DatabaseRedisDelete extends Command {
|
||||
static description = "Delete an redis database from a project.";
|
||||
static description = "Delete a Redis instance from a project.";
|
||||
|
||||
static examples = [
|
||||
"$ <%= config.bin %> redis delete",
|
||||
@@ -20,77 +20,84 @@ export default class DatabaseRedisDelete extends Command {
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
redisId: Flags.string({
|
||||
char: "r",
|
||||
description: "ID of the Redis instance to delete",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
const { flags } = await this.parse(DatabaseRedisDelete);
|
||||
let { projectId } = flags;
|
||||
let { projectId, redisId } = flags;
|
||||
|
||||
if (!projectId) {
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !redisId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
if (projects.length === 0) {
|
||||
this.log(chalk.yellow("No projects found."));
|
||||
return;
|
||||
if (!projectId) {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the Redis instance from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = answers.selectedProject;
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
choices: projects.map((project: any) => ({
|
||||
name: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
message: "Select a project to delete the redis database from:",
|
||||
name: "selectedProject",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
projectId = answers.selectedProject;
|
||||
if (!projectSelected.redis || projectSelected.redis.length === 0) {
|
||||
this.error(chalk.yellow("No Redis instances found in this project."));
|
||||
}
|
||||
|
||||
if (!redisId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.redis.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.redisId,
|
||||
})),
|
||||
message: "Select the Redis instance to delete:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
redisId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const project = await getProject(projectId, auth, this);
|
||||
|
||||
if (!project.redis || project.redis.length === 0) {
|
||||
this.log(chalk.yellow("No redis databases found in this project."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Permitir al usuario seleccionar una aplicación
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
choices: project.redis.map((db: any) => ({
|
||||
name: db.name,
|
||||
value: db.redisId,
|
||||
})),
|
||||
message: "Select the redis database to delete:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const redisId = appAnswers.selectedApp;
|
||||
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to delete this redis database?",
|
||||
message: "Are you sure you want to delete this Redis instance?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.log(chalk.yellow("Database deletion cancelled."));
|
||||
return;
|
||||
this.error(chalk.yellow("Redis deletion cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
const deleteResponse = await axios.post(
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.remove`,
|
||||
{
|
||||
json: {
|
||||
@@ -105,16 +112,12 @@ export default class DatabaseRedisDelete extends Command {
|
||||
},
|
||||
);
|
||||
|
||||
if (!deleteResponse.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting redis database"));
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error deleting Redis instance"));
|
||||
}
|
||||
|
||||
this.log(chalk.green("Redis database deleted successfully."));
|
||||
} catch (error) {
|
||||
this.error(
|
||||
// @ts-expect-error - TS2339: Property 'data' does not exist on type 'AxiosError<any>'.
|
||||
chalk.red(`Failed to delete redis database: ${error.message}`),
|
||||
);
|
||||
this.log(chalk.green("Redis instance deleted successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deleting Redis instance: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
@@ -7,83 +7,114 @@ import type { Answers } from "../../app/create.js";
|
||||
import axios from "axios";
|
||||
|
||||
export default class DatabaseRedisDeploy extends Command {
|
||||
static description = "Deploy an redis to a project.";
|
||||
static description = "Deploy a Redis instance to a project.";
|
||||
|
||||
static examples = ["$ <%= config.bin %> app deploy"];
|
||||
static examples = ["$ <%= config.bin %> redis deploy"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
redisId: Flags.string({
|
||||
char: "r",
|
||||
description: "ID of the Redis instance to deploy",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseRedisDeploy);
|
||||
let { projectId, redisId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !redisId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the Redis instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to deploy the redis in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.redis.length === 0) {
|
||||
this.error(chalk.yellow("No Redis instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.redis.length === 0) {
|
||||
this.error(chalk.yellow("No redis found in this project."));
|
||||
if (!redisId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.redis.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.redisId,
|
||||
})),
|
||||
message: "Select the Redis instance to deploy:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
redisId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.redis.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.redisId,
|
||||
})),
|
||||
message: "Select the redis to deploy:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const redisId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this redis?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("redis deployment cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.deploy`,
|
||||
{
|
||||
json: {
|
||||
redisId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to deploy this Redis instance?",
|
||||
name: "confirmDeploy",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying redis"));
|
||||
if (!confirmAnswers.confirmDeploy) {
|
||||
this.error(chalk.yellow("Redis deployment cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.deploy`,
|
||||
{
|
||||
json: {
|
||||
redisId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error deploying Redis instance"));
|
||||
}
|
||||
this.log(chalk.green("Redis instance deployed successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error deploying Redis instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Redis deployed successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,89 +1,120 @@
|
||||
import { Command } from "@oclif/core";
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
import axios from "axios";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import { readAuthConfig } from "../../../utils/utils.js";
|
||||
import chalk from "chalk";
|
||||
import { getProject, getProjects } from "../../../utils/shared.js";
|
||||
import inquirer from "inquirer";
|
||||
import type { Answers } from "../../app/create.js";
|
||||
import axios from "axios";
|
||||
|
||||
export default class DatabaseRedisStop extends Command {
|
||||
static description = "Stop an redis from a project.";
|
||||
static description = "Stop a Redis instance in a project.";
|
||||
|
||||
static examples = ["$ <%= config.bin %> redis stop"];
|
||||
|
||||
static flags = {
|
||||
projectId: Flags.string({
|
||||
char: "p",
|
||||
description: "ID of the project",
|
||||
required: false,
|
||||
}),
|
||||
redisId: Flags.string({
|
||||
char: "r",
|
||||
description: "ID of the Redis instance to stop",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
const { flags } = await this.parse(DatabaseRedisStop);
|
||||
let { projectId, redisId } = flags;
|
||||
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!projectId || !redisId) {
|
||||
console.log(chalk.blue.bold("\n Listing all Projects \n"));
|
||||
const projects = await getProjects(auth, this);
|
||||
|
||||
const projects = await getProjects(auth, this);
|
||||
if (!projectId) {
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the Redis instance from:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
projectId = project.projectId;
|
||||
}
|
||||
|
||||
const { project } = await inquirer.prompt<Answers>([
|
||||
{
|
||||
choices: projects.map((project) => ({
|
||||
name: project.name,
|
||||
value: project,
|
||||
})),
|
||||
message: "Select a project to stop the redis in:",
|
||||
name: "project",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
const projectId = project.projectId;
|
||||
if (projectSelected.redis.length === 0) {
|
||||
this.error(chalk.yellow("No Redis instances found in this project."));
|
||||
}
|
||||
|
||||
const projectSelected = await getProject(projectId, auth, this);
|
||||
|
||||
if (projectSelected.redis.length === 0) {
|
||||
this.error(chalk.yellow("No redis found in this project."));
|
||||
if (!redisId) {
|
||||
const dbAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.redis.map((db) => ({
|
||||
name: db.name,
|
||||
value: db.redisId,
|
||||
})),
|
||||
message: "Select the Redis instance to stop:",
|
||||
name: "selectedDb",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
redisId = dbAnswers.selectedDb;
|
||||
}
|
||||
}
|
||||
|
||||
const appAnswers = await inquirer.prompt([
|
||||
{
|
||||
// @ts-ignore
|
||||
choices: projectSelected.redis.map((app) => ({
|
||||
name: app.name,
|
||||
value: app.redisId,
|
||||
})),
|
||||
message: "Select the redis to stop:",
|
||||
name: "selectedApp",
|
||||
type: "list",
|
||||
},
|
||||
]);
|
||||
|
||||
const redisId = appAnswers.selectedApp;
|
||||
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this redis?",
|
||||
name: "confirmDelete",
|
||||
type: "confirm",
|
||||
},
|
||||
]);
|
||||
|
||||
if (!confirmAnswers.confirmDelete) {
|
||||
this.error(chalk.yellow("redis stop cancelled."));
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.stop`,
|
||||
{
|
||||
json: {
|
||||
redisId,
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirmAnswers = await inquirer.prompt([
|
||||
{
|
||||
default: false,
|
||||
message: "Are you sure you want to stop this Redis instance?",
|
||||
name: "confirmStop",
|
||||
type: "confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
]);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping redis"));
|
||||
if (!confirmAnswers.confirmStop) {
|
||||
this.error(chalk.yellow("Redis stop cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/redis.stop`,
|
||||
{
|
||||
json: {
|
||||
redisId,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
this.error(chalk.red("Error stopping Redis instance"));
|
||||
}
|
||||
this.log(chalk.green("Redis instance stopped successfully."));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error stopping Redis instance: ${error.message}`));
|
||||
}
|
||||
this.log(chalk.green("Redis stop successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +1,91 @@
|
||||
import { Command, Flags } from "@oclif/core";
|
||||
import axios from "axios";
|
||||
import chalk from "chalk";
|
||||
import inquirer, { type Answers, type QuestionCollection } from "inquirer";
|
||||
|
||||
import inquirer from "inquirer";
|
||||
import { readAuthConfig } from "../../utils/utils.js";
|
||||
|
||||
export default class ProjectCreate extends Command {
|
||||
static override description =
|
||||
"Create a new project with an optional description.";
|
||||
static description = "Create a new project.";
|
||||
|
||||
static override examples = [
|
||||
"$ <%= config.bin %> <%= command.id %> -n MyProject -d 'This is my project description'",
|
||||
"$ <%= config.bin %> <%= command.id %> -n MyProject",
|
||||
"$ <%= config.bin %> <%= command.id %>",
|
||||
static examples = [
|
||||
"$ <%= config.bin %> project create",
|
||||
"$ <%= config.bin %> project create -n MyProject -d 'Project description'",
|
||||
"$ <%= config.bin %> project create --name MyProject --skipConfirm",
|
||||
];
|
||||
|
||||
static override flags = {
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Description of the project",
|
||||
required: false,
|
||||
}),
|
||||
static flags = {
|
||||
name: Flags.string({
|
||||
char: "n",
|
||||
description: "Name of the project",
|
||||
required: false,
|
||||
}),
|
||||
description: Flags.string({
|
||||
char: "d",
|
||||
description: "Description of the project",
|
||||
required: false,
|
||||
}),
|
||||
skipConfirm: Flags.boolean({
|
||||
char: "y",
|
||||
description: "Skip confirmation prompt",
|
||||
default: false,
|
||||
}),
|
||||
};
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const auth = await readAuthConfig(this);
|
||||
|
||||
console.log(chalk.blue.bold("\n Create a New Project \n"));
|
||||
|
||||
const { flags } = await this.parse(ProjectCreate);
|
||||
let { name, description } = flags;
|
||||
|
||||
let answers: Answers = {};
|
||||
// Modo interactivo si no se proporcionan los flags necesarios
|
||||
if (!name) {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
message: "Enter the project name:",
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Project name is required"),
|
||||
},
|
||||
{
|
||||
message: "Enter the project description (optional):",
|
||||
name: "description",
|
||||
type: "input",
|
||||
default: description || "",
|
||||
},
|
||||
]);
|
||||
|
||||
const questions: QuestionCollection[] = [];
|
||||
|
||||
if (!flags.name) {
|
||||
questions.push({
|
||||
message: chalk.green("Enter the project name:"),
|
||||
name: "name",
|
||||
type: "input",
|
||||
validate: (input) => (input ? true : "Project name is required"),
|
||||
});
|
||||
name = answers.name;
|
||||
description = answers.description;
|
||||
}
|
||||
|
||||
if (!flags.description) {
|
||||
questions.push({
|
||||
default: "",
|
||||
message: chalk.green("Enter the project description (optional):"),
|
||||
name: "description",
|
||||
type: "input",
|
||||
});
|
||||
}
|
||||
// Confirmar si no se especifica --skipConfirm
|
||||
if (!flags.skipConfirm) {
|
||||
const confirm = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'proceed',
|
||||
message: 'Do you want to create this project?',
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
|
||||
if (questions.length > 0) {
|
||||
answers = await inquirer.prompt(questions);
|
||||
if (!confirm.proceed) {
|
||||
this.error(chalk.yellow("Project creation cancelled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const name = flags.name || answers.name;
|
||||
const description = flags.description || answers.description;
|
||||
|
||||
try {
|
||||
console.log(JSON.stringify({
|
||||
name,
|
||||
description,
|
||||
}, null, 2));
|
||||
|
||||
const response = await axios.post(
|
||||
`${auth.url}/api/trpc/project.create`,
|
||||
{
|
||||
json: {
|
||||
description,
|
||||
name,
|
||||
description,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -82,13 +97,12 @@ export default class ProjectCreate extends Command {
|
||||
);
|
||||
|
||||
if (!response.data.result.data.json) {
|
||||
this.error(chalk.red("Error`"));
|
||||
this.error(chalk.red("Error creating project", response.data.result.data.json));
|
||||
}
|
||||
|
||||
this.log(chalk.green(`Project '${name}' created successfully.`));
|
||||
} catch (error) {
|
||||
// @ts-expect-error hola
|
||||
this.error(chalk.red(`Failed to create project: ${error.message}`));
|
||||
} catch (error: any) {
|
||||
this.error(chalk.red(`Error creating project: ${error.message}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,19 @@ export type AuthConfig = {
|
||||
};
|
||||
|
||||
export const readAuthConfig = async (command: Command): Promise<AuthConfig> => {
|
||||
// Primero intentar leer desde variables de entorno
|
||||
const envToken = process.env.DOKPLOY_AUTH_TOKEN;
|
||||
const envUrl = process.env.DOKPLOY_URL;
|
||||
|
||||
if (envToken && envUrl) {
|
||||
return { token: envToken, url: envUrl };
|
||||
}
|
||||
|
||||
// Si no hay variables de entorno, usar el archivo de configuración
|
||||
if (!fs.existsSync(configPath)) {
|
||||
command.error(
|
||||
chalk.red(
|
||||
"No configuration file found. Please authenticate first using the 'authenticate' command.",
|
||||
"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.",
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -30,7 +39,7 @@ export const readAuthConfig = async (command: Command): Promise<AuthConfig> => {
|
||||
if (!url || !token) {
|
||||
command.error(
|
||||
chalk.red(
|
||||
"Incomplete authentication details. Please authenticate again using the 'authenticate' command.",
|
||||
"Incomplete authentication details. Please authenticate again using the 'authenticate' command or set environment variables.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user