superjolt
Version:
AI-powered deployment platform with MCP support - Deploy JavaScript apps using natural language with Claude Desktop
173 lines • 8.5 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceListCommand = void 0;
const nest_commander_1 = require("nest-commander");
const api_service_1 = require("../services/api.service");
const auth_service_1 = require("../services/auth.service");
const logger_service_1 = require("../services/logger.service");
const common_1 = require("@nestjs/common");
const authenticated_command_1 = require("./authenticated.command");
const table_utils_1 = require("../utils/table.utils");
const chalk_1 = __importDefault(require("chalk"));
let ServiceListCommand = class ServiceListCommand extends authenticated_command_1.AuthenticatedCommand {
apiService;
authService;
logger;
constructor(apiService, authService, logger) {
super();
this.apiService = apiService;
this.authService = authService;
this.logger = logger;
}
async execute(passedParams, options) {
try {
const machineId = options.machineId || passedParams[0];
if (machineId) {
this.logger.log(chalk_1.default.dim(`Fetching services for machine: ${machineId}...`));
}
else {
this.logger.log(chalk_1.default.dim('Fetching services...'));
}
const response = await this.apiService.listServices(machineId);
if (response.needsSelection) {
this.logger.log(chalk_1.default.cyan('\n🖥️ Multiple machines available. Please select one:'));
const machines = response.availableMachines;
const selectionTable = (0, table_utils_1.createResourceTable)([
'#',
'ID',
'Name',
'Status',
]);
machines.forEach((machine, index) => {
selectionTable.push([
chalk_1.default.yellow(`${index + 1}`),
machine.id,
machine.name,
(0, table_utils_1.formatStatus)(machine.status || 'unknown'),
]);
});
this.logger.log(selectionTable.toString());
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const selection = await new Promise((resolve) => {
rl.question(chalk_1.default.cyan('\nSelect a machine (enter number): '), (answer) => {
rl.close();
resolve(parseInt(answer));
});
});
if (selection < 1 || selection > machines.length) {
this.logger.error(chalk_1.default.red('Invalid selection'));
process.exit(1);
}
const selectedMachine = machines[selection - 1];
this.logger.log(chalk_1.default.dim(`\nFetching services for machine: ${selectedMachine.id}...`));
const retryResponse = await this.apiService.listServices(selectedMachine.id);
Object.assign(response, retryResponse);
}
if (response.total === 0) {
this.logger.log(chalk_1.default.yellow('\nNo services found for this machine.'));
this.logger.log(chalk_1.default.dim('\nDeploy a service with:'));
this.logger.log(chalk_1.default.cyan(' superjolt deploy'));
return;
}
const displayMachineId = response.machineId || machineId;
this.logger.log(chalk_1.default.cyan(`\nServices for machine ${displayMachineId}:`));
const table = (0, table_utils_1.createResourceTable)(['ID', 'Name', 'Status', 'CPU %', 'Memory', 'Created'], {
wordWrap: true,
wrapOnWordBoundary: false,
});
const sortedServices = [...response.services].sort((a, b) => {
const aRunning = (a.state || a.status || '').toLowerCase() === 'running' ? 0 : 1;
const bRunning = (b.state || b.status || '').toLowerCase() === 'running' ? 0 : 1;
return aRunning - bRunning;
});
sortedServices.forEach((service) => {
const state = service.state || 'unknown';
const statusText = service.status && service.status !== state
? `${(0, table_utils_1.formatStatus)(state)} (${service.status})`
: (0, table_utils_1.formatStatus)(state);
const cpuUsage = service.stats?.cpuPercent !== undefined
? `${service.stats.cpuPercent.toFixed(1)}%`
: '-';
const memoryUsage = service.stats?.memoryUsage !== undefined
? (0, table_utils_1.formatBytes)(service.stats.memoryUsage)
: '-';
const nameWithUrl = service.url
? `${service.name}\n${chalk_1.default.dim(service.url)}`
: service.name;
table.push([
service.id,
nameWithUrl,
statusText,
cpuUsage,
memoryUsage,
(0, table_utils_1.formatDate)(service.createdAt || new Date().toISOString()),
]);
});
this.logger.log(table.toString());
const statusCounts = response.services.reduce((acc, s) => {
const state = (s.state || s.status || 'unknown').toLowerCase();
acc[state] = (acc[state] || 0) + 1;
return acc;
}, {});
let summary = chalk_1.default.dim(`\nTotal: ${response.total} service${response.total === 1 ? '' : 's'}`);
const statusParts = [];
if (statusCounts.running)
statusParts.push(`${statusCounts.running} running`);
if (statusCounts.stopped)
statusParts.push(`${statusCounts.stopped} stopped`);
if (statusCounts.deployed)
statusParts.push(`${statusCounts.deployed} deployed`);
if (statusCounts.unknown)
statusParts.push(`${statusCounts.unknown} pending`);
if (statusParts.length > 0) {
summary += chalk_1.default.dim(` (${statusParts.join(', ')})`);
}
this.logger.log(summary);
}
catch (error) {
this.logger.error(`\n${error.message}`);
process.exit(1);
}
}
parseMachineId(val) {
return val;
}
};
exports.ServiceListCommand = ServiceListCommand;
__decorate([
(0, nest_commander_1.Option)({
flags: '-m, --machineId <machineId>',
description: 'Machine ID to list services for',
}),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", String)
], ServiceListCommand.prototype, "parseMachineId", null);
exports.ServiceListCommand = ServiceListCommand = __decorate([
(0, common_1.Injectable)(),
(0, nest_commander_1.Command)({
name: 'service:list',
aliases: ['list', 'services'],
description: 'List services for a machine',
}),
__metadata("design:paramtypes", [api_service_1.ApiService,
auth_service_1.AuthService,
logger_service_1.LoggerService])
], ServiceListCommand);
//# sourceMappingURL=service-list.command.js.map