redirector-cli
Version:
Global CLI tool for managing Redirector backend services with Docker Compose
231 lines • 9.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupCommand = setupCommand;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const inquirer_1 = __importDefault(require("inquirer"));
const logger_1 = require("../utils/logger");
const config_1 = require("../utils/config");
const docker_compose_template_1 = require("../templates/docker-compose.template");
async function setupCommand(options) {
try {
logger_1.Logger.header("Redirector Setup");
const projectPath = process.cwd();
const projectName = path.basename(projectPath);
// Check if already initialized
const isExisting = await config_1.ConfigManager.isRedirectorProject(projectPath);
if (isExisting && !options.force) {
const { overwrite } = await inquirer_1.default.prompt([
{
type: "confirm",
name: "overwrite",
message: "Redirector project already exists. Overwrite?",
default: false,
},
]);
if (!overwrite) {
logger_1.Logger.info("Setup cancelled");
return;
}
}
// Validate Docker installation
logger_1.Logger.startSpinner("Checking Docker installation...");
const dockerInstalled = await config_1.ConfigManager.validateDockerInstallation();
if (!dockerInstalled) {
logger_1.Logger.failSpinner("Docker not found");
logger_1.Logger.error("Docker and Docker Compose are required. Please install Docker first.");
logger_1.Logger.info("Visit: https://docs.docker.com/get-docker/");
process.exit(1);
}
logger_1.Logger.succeedSpinner("Docker installation verified");
// Check if Docker is running
logger_1.Logger.startSpinner("Checking Docker daemon...");
const dockerRunning = await config_1.ConfigManager.validateDockerRunning();
if (!dockerRunning) {
logger_1.Logger.failSpinner("Docker daemon not running");
logger_1.Logger.error("Docker daemon is not running. Please start Docker first.");
process.exit(1);
}
logger_1.Logger.succeedSpinner("Docker daemon is running");
// Get configuration
let config;
if (options.interactive !== false) {
config = await getInteractiveConfig(options, projectName);
}
else {
config = {
backendPort: options.port || 3000,
postgresPort: options.postgresPort || 5432,
dockerUsername: options.dockerUsername || "shivarajbakale",
projectName,
environment: "production",
};
}
// Create project files
logger_1.Logger.startSpinner("Creating project files...");
await createProjectFiles(projectPath, config);
logger_1.Logger.succeedSpinner("Project files created");
// Save configuration
await config_1.ConfigManager.saveConfig(config, projectPath);
await config_1.ConfigManager.createEnvFile(config, projectPath);
// Success message
logger_1.Logger.success("Project initialized successfully!");
logger_1.Logger.newLine();
logger_1.Logger.subheader("Project Configuration:");
logger_1.Logger.table({
"Project Name": config.projectName,
"Backend Port": config.backendPort.toString(),
"PostgreSQL Port": config.postgresPort.toString(),
"Docker Username": config.dockerUsername,
Environment: config.environment,
});
logger_1.Logger.newLine();
logger_1.Logger.subheader("Next Steps:");
logger_1.Logger.list([
"Run `redirector start` to start the services",
"Run `redirector status` to check service status",
"Visit http://localhost:" + config.backendPort + " to access the API",
"Visit http://localhost:" +
config.backendPort +
"/health for health check",
]);
}
catch (error) {
logger_1.Logger.error(`Setup failed: ${error}`);
process.exit(1);
}
}
async function getInteractiveConfig(options, projectName) {
logger_1.Logger.info("Configure your Redirector project:");
logger_1.Logger.newLine();
const answers = await inquirer_1.default.prompt([
{
type: "input",
name: "projectName",
message: "Project name:",
default: projectName,
validate: (input) => {
if (!input.trim()) {
return "Project name is required";
}
return true;
},
},
{
type: "number",
name: "backendPort",
message: "Backend API port:",
default: options.port || 3000,
validate: (input) => {
if (input < 1 || input > 65535) {
return "Port must be between 1 and 65535";
}
return true;
},
},
{
type: "number",
name: "postgresPort",
message: "PostgreSQL port:",
default: options.postgresPort || 5432,
validate: (input) => {
if (input < 1 || input > 65535) {
return "Port must be between 1 and 65535";
}
return true;
},
},
{
type: "input",
name: "dockerUsername",
message: "Docker Hub username:",
default: options.dockerUsername || "shivarajbakale",
validate: (input) => {
if (!input.trim()) {
return "Docker username is required";
}
return true;
},
},
{
type: "list",
name: "environment",
message: "Environment:",
choices: ["production", "development"],
default: "production",
},
]);
return {
projectName: answers.projectName.trim(),
backendPort: answers.backendPort,
postgresPort: answers.postgresPort,
dockerUsername: answers.dockerUsername.trim(),
environment: answers.environment,
};
}
async function createProjectFiles(projectPath, config) {
// Create docker-compose.yml
const dockerComposePath = path.join(projectPath, "docker-compose.yml");
await fs.writeFile(dockerComposePath, docker_compose_template_1.dockerComposeTemplate);
// Create .env file
const envPath = path.join(projectPath, ".env");
const customEnvContent = docker_compose_template_1.envTemplate
.replace("BACKEND_PORT=3000", `BACKEND_PORT=${config.backendPort}`)
.replace("POSTGRES_PORT=5432", `POSTGRES_PORT=${config.postgresPort}`)
.replace("DOCKER_USERNAME=shivarajbakale", `DOCKER_USERNAME=${config.dockerUsername}`)
.replace("PROJECT_NAME=redirector", `PROJECT_NAME=${config.projectName}`);
await fs.writeFile(envPath, customEnvContent);
// Create .gitignore if it doesn't exist
const gitignorePath = path.join(projectPath, ".gitignore");
if (!(await fs.pathExists(gitignorePath))) {
await fs.writeFile(gitignorePath, docker_compose_template_1.gitignoreTemplate);
}
// Create README.md if it doesn't exist
const readmePath = path.join(projectPath, "README.md");
if (!(await fs.pathExists(readmePath))) {
const customReadme = docker_compose_template_1.readmeTemplate
.replace(/localhost:3000/g, `localhost:${config.backendPort}`)
.replace(/localhost:5432/g, `localhost:${config.postgresPort}`);
await fs.writeFile(readmePath, customReadme);
}
// Create data directory for volumes
const dataPath = path.join(projectPath, "data");
await fs.ensureDir(dataPath);
}
//# sourceMappingURL=setup.js.map