UNPKG

zcatalyst-cli

Version:

Command Line Tool for CATALYST

590 lines (589 loc) 30.4 kB
'use strict'; 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;