zcatalyst-cli
Version:
Command Line Tool for CATALYST
590 lines (589 loc) • 30.4 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const error_1 = __importDefault(require("../../error"));
const runtime_store_1 = __importDefault(require("../../runtime-store"));
const constants_1 = require("../../util_modules/constants");
const runtime_1 = __importDefault(require("../../util_modules/constants/lib/runtime"));
const js_1 = require("../../util_modules/js");
const logger_1 = require("../../util_modules/logger");
const master_1 = __importDefault(require("./lib/master"));
const index_js_1 = __importDefault(require("./lib/java/index.js"));
const index_js_2 = __importDefault(require("./lib/node/index.js"));
const index_js_3 = __importDefault(require("./lib/python/index.js"));
const index_js_4 = __importDefault(require("./lib/web_client/index.js"));
const index_js_5 = __importDefault(require("./lib/appsail/index.js"));
const index_js_6 = __importDefault(require("./lib/slate/index.js"));
const cli_table_1 = require("../../cli_table");
const ansi_colors_1 = require("ansi-colors");
const bioLogUrl = (details, masterPort, addSpaces) => {
var _a, _b, _c, _d;
const labelMap = {
bio: 'BasicIO',
browserlogic: 'Browser Logic'
};
const label = addSpaces
? ((_a = details.target) === null || _a === void 0 ? void 0 : _a.name) + ''
: `${labelMap[(_b = details.target) === null || _b === void 0 ? void 0 : _b.type]}[${(_c = details.target) === null || _c === void 0 ? void 0 : _c.name}]`;
(0, logger_1.labeled)(label + ' '.repeat((addSpaces || label.length) - label.length), 'http://localhost:' +
(masterPort === -1 ? details.httpPort : masterPort) +
new URL(((_d = details.target) === null || _d === void 0 ? void 0 : _d.url) || '').pathname).MESSAGE();
};
const aioLogUrl = (details, masterPort, addSpaces) => {
var _a, _b, _c;
const label = addSpaces ? ((_a = details.target) === null || _a === void 0 ? void 0 : _a.name) + '' : `AdvancedIO[${(_b = details.target) === null || _b === void 0 ? void 0 : _b.name}]`;
(0, logger_1.labeled)(label + ' '.repeat((addSpaces || label.length) - label.length), `http://localhost:${masterPort}/server/${(_c = details.target) === null || _c === void 0 ? void 0 : _c.name}/`).MESSAGE();
};
class Server {
constructor() {
this.targetsMap = {
functions: [],
server: [],
client: [],
appSail: [],
slate: []
};
}
_addBasicFnDetails(bioUrlLogs) {
const fnTargets = runtime_store_1.default.get('context.functions.targets', []);
if (fnTargets.length === 0) {
(0, logger_1.debug)('No basic functions to add');
}
const httpPort = parseInt(runtime_store_1.default.get('context.port.http.' + constants_1.FN_TYPE.basic), 10);
const debugPort = parseInt(runtime_store_1.default.get('context.port.debug.' + constants_1.FN_TYPE.basic, '-1'), 10);
if (!isNaN(httpPort)) {
fnTargets
.filter((t) => {
var _a;
return t.url !== undefined &&
t.type === constants_1.FN_TYPE.basic &&
!((_a = t.stack) === null || _a === void 0 ? void 0 : _a.startsWith(runtime_1.default.language.python.value));
})
.map((t) => js_1.JS.omit(t, ['zip_stream', 'localFn']))
.forEach((t) => {
const target = {
type: 'functions',
httpPort,
debugPort,
target: t
};
this.targetsMap.functions.push(target);
bioUrlLogs.targs.push(target);
bioUrlLogs.nameMaxLength =
t.name.length > bioUrlLogs.nameMaxLength
? t.name.length
: bioUrlLogs.nameMaxLength;
});
}
}
add(type, target) {
if (type === 'appsail') {
this.targetsMap.appSail.push({
type,
target: target,
httpPort: -1,
debugPort: -1
});
return;
}
if (type === 'slate') {
this.targetsMap.slate.push({
type,
target: target,
httpPort: -1,
debugPort: -1
});
return;
}
const httpPort = runtime_store_1.default.get(`context.port.http.${type === 'server' ? 'functions' : type}.${target.name}`, -1);
const debugPort = runtime_store_1.default.get(`context.port.debug.${type === 'server' ? 'functions' : type}.${target.name}`, -1);
if (httpPort === -1) {
throw new error_1.default('http port is mandatory for target : ' +
target.name +
' to start advanced server', { exit: 2 });
}
type === 'client'
? this.targetsMap.client.push({
type,
target: target,
httpPort,
debugPort
})
: this.targetsMap.server.push({
type,
target: target,
httpPort,
debugPort
});
}
startServer(details, masterPort) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
if (details.target === undefined) {
return details;
}
try {
let currentProcess;
switch (details.type) {
case 'appsail': {
currentProcess = yield (0, index_js_5.default)(details);
break;
}
case 'slate': {
currentProcess = yield (0, index_js_6.default)(details);
break;
}
case 'client': {
currentProcess = yield (0, index_js_4.default)(details, masterPort);
break;
}
case 'functions':
case 'server': {
if ((_a = details.target.stack) === null || _a === void 0 ? void 0 : _a.startsWith(runtime_1.default.language.java.value)) {
currentProcess = yield (0, index_js_1.default)(details, masterPort);
}
else if ((_b = details.target.stack) === null || _b === void 0 ? void 0 : _b.startsWith(runtime_1.default.language.node.value)) {
currentProcess = yield (0, index_js_2.default)(details, masterPort);
}
else {
currentProcess = yield (0, index_js_3.default)(details);
}
break;
}
default: {
throw new error_1.default('Invalid feature type', { exit: 2 });
}
}
details.process = currentProcess;
const stdout = currentProcess.stdout;
if (stdout) {
stdout.on('data', (chunk) => {
process.stdout.write(chunk.toString());
});
}
const stderr = currentProcess.stderr;
if (stderr) {
stderr.on('data', (chunk) => {
process.stderr.write(chunk.toString());
});
}
return new Promise((res) => setTimeout(() => res(details), 100));
}
catch (er) {
const error = 'Unable to start the server: ' + error_1.default.getErrorInstance(er).message;
if (details.type === 'appsail') {
const target = details.target;
target.validity.valid = false;
(0, logger_1.labeled)(`AppSail[${target.name}]`, error).ERROR();
}
else if (details.type === 'client') {
const target = details.target;
target.valid = false;
(0, logger_1.labeled)(`WebClient[${details.target}]`, error).ERROR();
}
else if (details.type === 'slate') {
const target = details.target;
target.validity.valid = false;
(0, logger_1.labeled)(`Slate[${target.name}]`, error).ERROR();
}
else {
const target = details.target;
target.valid = false;
(0, logger_1.labeled)(`${target.type}[${target.name}]`, error).ERROR();
}
return details;
}
});
}
start() {
return __awaiter(this, void 0, void 0, function* () {
const logUrls = {
functions: {
bio: { targs: [], nameMaxLength: 0 },
aio: { targs: [], nameMaxLength: 0 },
browserlogic: { targs: [], nameMaxLength: 0 }
},
appsail: { targs: [], nameMaxLength: 0 },
slate: { targs: [], nameMaxLength: 0 },
client: {}
};
this._addBasicFnDetails(logUrls.functions.bio);
const masterTargets = ['functions', 'client', 'server'].reduce((_masterTargets, targ) => {
if (this.targetsMap[targ]) {
_masterTargets.targets[targ] = this.targetsMap[targ];
_masterTargets.length += this.targetsMap[targ].length;
}
return _masterTargets;
}, {
targets: {},
length: 0
});
const serveTargets = Object.values(masterTargets.targets);
const serveTargetsArr = serveTargets.flat();
const masterPort = runtime_store_1.default.get(`context.port.http.master`, -1);
let startPromise = Promise.resolve();
if (masterTargets.length > 0) {
if (masterPort === -1) {
throw new error_1.default('master port cannot be undefined', { exit: 2 });
}
yield Promise.all(serveTargets.map((targetDetails) => Promise.all(targetDetails.map((details) => {
var _a, _b;
const _details = details;
if (((_a = _details.target) === null || _a === void 0 ? void 0 : _a.type) === 'bio' &&
!((_b = _details.target.stack) === null || _b === void 0 ? void 0 : _b.includes('python'))) {
return;
}
return this.startServer(_details, masterPort).then((t) => {
var _a, _b, _c, _d;
const serverDetails = t;
if (!((_a = serverDetails.target) === null || _a === void 0 ? void 0 : _a.valid)) {
return;
}
if (serverDetails.type === 'client') {
logUrls.client = serverDetails;
}
else {
const _details = serverDetails;
const targType = (_b = _details.target) === null || _b === void 0 ? void 0 : _b.type;
logUrls.functions[targType].targs.push(_details);
logUrls.functions[targType].nameMaxLength =
((_c = _details.target) === null || _c === void 0 ? void 0 : _c.name) &&
_details.target.name.length >
logUrls.functions[targType].nameMaxLength
? (_d = _details.target) === null || _d === void 0 ? void 0 : _d.name.length
: logUrls.functions[targType].nameMaxLength;
}
});
}))));
if (serveTargetsArr.length === 0) {
throw new error_1.default('Trying to start master server before other server', {
exit: 2
});
}
this.masterServer =
masterTargets.length > 0
? yield (0, master_1.default)(masterPort, { otherServerDetails: masterTargets.targets })
: undefined;
startPromise = new Promise((res) => {
this.masterServer
? this.masterServer.on('listening', () => {
serveTargetsArr.forEach((targetDetails) => {
var _a;
if (targetDetails.process &&
'send' in targetDetails.process) {
targetDetails.process.send('start');
return;
}
(_a = targetDetails.process) === null || _a === void 0 ? void 0 : _a.emit('start');
});
res();
})
: res();
});
this.targetsMap.server.every((t) => {
var _a;
if (t.debugPort !== -1 &&
((_a = t.target.stack) === null || _a === void 0 ? void 0 : _a.startsWith(runtime_1.default.language.python.value))) {
const table = (0, cli_table_1.getCustomColourTable)(ansi_colors_1.yellow);
table.push(['As of now, local debugging for python is not supported']);
(0, logger_1.info)(table.toString());
return true;
}
return false;
});
}
if (this.targetsMap.appSail.length > 0) {
yield Promise.all(this.targetsMap.appSail.map((targSail) => this.startServer(targSail, -1).then((details) => {
var _a, _b, _c, _d;
const serverDetails = details;
if (!((_a = serverDetails.target) === null || _a === void 0 ? void 0 : _a.validity.valid)) {
return;
}
logUrls.appsail.targs.push(targSail);
logUrls.appsail.nameMaxLength =
((_b = targSail.target) === null || _b === void 0 ? void 0 : _b.name) &&
((_c = targSail.target) === null || _c === void 0 ? void 0 : _c.name.length) > logUrls.appsail.nameMaxLength
? (_d = targSail.target) === null || _d === void 0 ? void 0 : _d.name.length
: logUrls.appsail.nameMaxLength;
})));
}
if (this.targetsMap.slate.length > 0) {
yield Promise.all(this.targetsMap.slate.map((targSlate) => this.startServer(targSlate, -1).then((details) => {
var _a, _b, _c, _d;
const serverDetails = details;
if (!((_a = serverDetails.target) === null || _a === void 0 ? void 0 : _a.validity.valid)) {
return;
}
logUrls.slate.targs.push(targSlate);
logUrls.slate.nameMaxLength =
((_b = targSlate.target) === null || _b === void 0 ? void 0 : _b.name) &&
((_c = targSlate.target) === null || _c === void 0 ? void 0 : _c.name.length) > logUrls.slate.nameMaxLength
? (_d = targSlate.target) === null || _d === void 0 ? void 0 : _d.name.length
: logUrls.slate.nameMaxLength;
})));
}
let loggedEntries = 0;
Object.entries(logUrls).forEach(([targType, logTarg]) => {
var _a;
switch (targType) {
case 'functions': {
const headersDisplayed = {
bio: false,
aio: false,
blo: false
};
Object.entries(logTarg).forEach((x) => {
const [_targType, _logTarg] = x;
if (_logTarg.targs.length === 0) {
return;
}
loggedEntries++;
switch (_targType) {
case 'bio': {
_logTarg.targs.forEach((t) => {
var _a, _b;
const target = t;
if (!((_a = target.target) === null || _a === void 0 ? void 0 : _a.valid)) {
return;
}
if (!((_b = target.target) === null || _b === void 0 ? void 0 : _b.url)) {
throw new error_1.default('Target URL not found', {
exit: 2
});
}
if (headersDisplayed.bio === false) {
(0, logger_1.info)();
(0, logger_1.info)((0, ansi_colors_1.bold)(' >>>>>>>>>>>>>> BasicIO <<<<<<<<<<<<<< '));
headersDisplayed.bio = true;
}
bioLogUrl(target, masterPort, _logTarg.nameMaxLength);
});
(0, logger_1.info)();
break;
}
case 'aio': {
_logTarg.targs.forEach((t) => {
var _a, _b;
const _target = t;
if (!((_a = _target.target) === null || _a === void 0 ? void 0 : _a.valid)) {
return;
}
if (!((_b = _target.target) === null || _b === void 0 ? void 0 : _b.url)) {
throw new error_1.default('Target URL not found', {
exit: 2
});
}
if (headersDisplayed.aio === false) {
(0, logger_1.info)();
(0, logger_1.info)((0, ansi_colors_1.bold)(' >>>>>>>>>>>>> AdvancedIO <<<<<<<<<<<< '));
headersDisplayed.aio = true;
}
aioLogUrl(_target, masterPort, _logTarg.nameMaxLength);
});
(0, logger_1.info)();
break;
}
case 'browserlogic': {
_logTarg.targs.forEach((t) => {
var _a, _b;
const target = t;
if (!((_a = target.target) === null || _a === void 0 ? void 0 : _a.valid)) {
return;
}
if (!((_b = target.target) === null || _b === void 0 ? void 0 : _b.url)) {
throw new error_1.default('Target URL not found', {
exit: 2
});
}
if (headersDisplayed.blo === false) {
(0, logger_1.info)();
(0, logger_1.info)((0, ansi_colors_1.bold)(' >>>>>>>>>>>> BrowserLogic <<<<<<<<<<< '));
headersDisplayed.blo = true;
}
bioLogUrl(target, masterPort, _logTarg.nameMaxLength);
});
(0, logger_1.info)();
break;
}
}
});
break;
}
case 'appsail': {
const _logTarg = logTarg;
if (_logTarg.targs.length === 0) {
return;
}
loggedEntries++;
let isHeaderDisplayed = false;
_logTarg.targs.forEach((t) => {
const targetSail = t.target;
if (!targetSail.validity.valid) {
return;
}
if (isHeaderDisplayed === false) {
(0, logger_1.info)();
(0, logger_1.info)((0, ansi_colors_1.bold)(' >>>>>>>>>>>>>> AppSail <<<<<<<<<<<<<< '));
isHeaderDisplayed = true;
}
const targName = targetSail.name + '';
(0, logger_1.labeled)(targName +
' '.repeat((_logTarg.nameMaxLength || targName.length) - targName.length), `http://localhost:${targetSail.port.proxy}`).MESSAGE();
});
(0, logger_1.info)();
break;
}
case 'client': {
if (Object.keys(logTarg).length === 0) {
return;
}
loggedEntries++;
(0, logger_1.info)();
const targApp = logTarg;
const appUrl = 'http://localhost:' + masterPort;
const label = `client[${(_a = targApp.target) === null || _a === void 0 ? void 0 : _a.name}]`;
(0, logger_1.info)((0, ansi_colors_1.bold)(' >>>>>>>>>>>>> Web Client <<<<<<<<<<<<'));
(0, logger_1.labeled)(label, `${appUrl}/app/`).MESSAGE();
(0, logger_1.info)();
break;
}
case 'slate': {
const _logTarg = logTarg;
if (_logTarg.targs.length === 0) {
return;
}
loggedEntries++;
let isHeaderDisplayed = false;
_logTarg.targs.forEach((t) => {
const targetSlate = t.target;
if (!targetSlate.validity.valid) {
return;
}
if (isHeaderDisplayed === false) {
(0, logger_1.info)();
(0, logger_1.info)((0, ansi_colors_1.bold)(' >>>>>>>>>>>>>> Slate <<<<<<<<<<<<<< '));
isHeaderDisplayed = true;
}
const targName = targetSlate.name + '';
(0, logger_1.labeled)(targName +
' '.repeat((_logTarg.nameMaxLength || targName.length) - targName.length), `http://localhost:${targetSlate.port.proxy}`).MESSAGE();
});
(0, logger_1.info)();
break;
}
}
});
return loggedEntries > 0
? startPromise
: Promise.reject(new error_1.default('No Resources served', { exit: 1, errorId: 'SERVE-IDX-2' }));
});
}
wait() {
return __awaiter(this, void 0, void 0, function* () {
if (this.masterServer) {
const masterPort = runtime_store_1.default.get(`context.port.http.master`, -1);
Object.values(this.targetsMap).forEach((details) => {
details.forEach((targetdetails) => {
var _a, _b;
const target = targetdetails.target;
if (!target || !targetdetails.process) {
return;
}
(_a = target.watcher) === null || _a === void 0 ? void 0 : _a.on('preparing', () => __awaiter(this, void 0, void 0, function* () {
yield this.kill(targetdetails.process);
}));
(_b = target.watcher) === null || _b === void 0 ? void 0 : _b.on('compiled', () => __awaiter(this, void 0, void 0, function* () {
yield this.restart(targetdetails);
if (target.type === constants_1.FN_TYPE.basic) {
(0, logger_1.labeled)(`functions[${target.name}]`, 'ready!').MESSAGE();
if (!target.url) {
throw new error_1.default('Target URL not found while restarting server', {
exit: 2
});
}
bioLogUrl(targetdetails, masterPort);
}
else if (target.type === constants_1.FN_TYPE.advanced) {
(0, logger_1.labeled)(`AdvancedIO[${target.name}]`, 'ready!').MESSAGE();
aioLogUrl(targetdetails, masterPort);
}
setTimeout(() => {
var _a;
(_a = target.watcher) === null || _a === void 0 ? void 0 : _a.emit('next');
}, 1000);
}));
}, this);
});
}
return new Promise((res) => {
['SIGINT', 'SIGTERM'].forEach((sig) => process.on(sig, res));
});
});
}
kill(serverProcess) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
if (serverProcess.pid === undefined) {
try {
serverProcess.close(() => resolve());
}
catch (e) {
serverProcess.emit('close');
}
}
if (serverProcess.exitCode === null) {
serverProcess.kill('SIGINT');
}
resolve();
});
});
}
restart(target) {
return __awaiter(this, void 0, void 0, function* () {
if (!target.process) {
throw new error_1.default('Process is not defined for this target.', { exit: 2 });
}
yield this.kill(target.process);
yield this.startServer(target, runtime_store_1.default.get(`context.port.http.master`, -1));
});
}
stop() {
return __awaiter(this, void 0, void 0, function* () {
yield Promise.all(Object.values(this.targetsMap).map((details) => Promise.all(details.map((targetdetails) => __awaiter(this, void 0, void 0, function* () {
var _a;
const target = targetdetails.target;
if (!target) {
return;
}
yield ((_a = target.watcher) === null || _a === void 0 ? void 0 : _a.close());
if (targetdetails.process) {
return this.kill(targetdetails.process);
}
}))))).catch((err) => (0, logger_1.debug)('Error stopping the servers: ', err));
if (this.masterServer) {
const masterServer = this.masterServer;
return new Promise((res, rej) => {
masterServer.close((err) => {
if (err) {
(0, logger_1.debug)('Error stopping the master server: ', err);
return rej(err);
}
res();
});
});
}
});
}
}
exports.default = Server;