UNPKG

zcatalyst-cli

Version:

Command Line Tool for CATALYST

203 lines (202 loc) 11.6 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 __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _TunnelServer_contextMap, _TunnelServer_server, _TunnelServer_destroyer, _TunnelServer_repel, _TunnelServer_projectId; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const runtime_store_1 = __importDefault(require("../../runtime-store")); const error_1 = __importDefault(require("../../error")); const index_1 = require("../../util_modules/logger/index"); const port_resolver_1 = __importDefault(require("../../port-resolver")); const server_1 = require("../../util_modules/server"); const ansi_colors_1 = require("ansi-colors"); const util_1 = require("util"); const project_1 = require("../../util_modules/project"); const endpoints_1 = require("../../endpoints"); class TunnelServer { constructor(repel) { _TunnelServer_contextMap.set(this, {}); _TunnelServer_server.set(this, void 0); _TunnelServer_destroyer.set(this, void 0); _TunnelServer_repel.set(this, void 0); _TunnelServer_projectId.set(this, (0, project_1.getProjectId)()); __classPrivateFieldSet(this, _TunnelServer_repel, repel, "f"); } isAsyncFn(fnType) { switch (fnType) { case 'cron': case 'event': case 'job': { return true; } } return false; } send(req, res, status = 200, data, contentType) { return __awaiter(this, void 0, void 0, function* () { const body = req.body; if (this.isAsyncFn(body.function_details.function_type)) { const tunnelAPI = yield (0, endpoints_1.tunnelAPI)(); yield tunnelAPI.tunnelCallback(status, body.default, data); return; } contentType && res.contentType(contentType); res.status(status); res.send(data); }); } startServer() { return __awaiter(this, void 0, void 0, function* () { const tunnelPortOpt = Number.parseInt(runtime_store_1.default.get('context.port.tunnel')); if (Number.isNaN(tunnelPortOpt)) { return; } const port = yield port_resolver_1.default.getFreePort(tunnelPortOpt).catch((e) => (0, index_1.debug)(e)); if (!port || tunnelPortOpt !== port) { throw new error_1.default(`Port unavailable ${tunnelPortOpt}`, { exit: 1, errorId: 'TUNNEL-1', arg: [ansi_colors_1.bold.red(tunnelPortOpt + ''), (0, ansi_colors_1.bold)('--tunnel')] }); } const app = (0, express_1.default)(); app.use(express_1.default.json()); app.all('/', (req, res) => __awaiter(this, void 0, void 0, function* () { if (req.method !== 'POST') { res.status(200); res.send(); return; } const body = req.body; if (!body.function_details || !body.function_data || (body.function_details.function_type !== 'integration' && !body.default)) { res.status(400); res.send(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write('Invalid tunnel request: ' + (0, util_1.inspect)(body)); return; } if (this.isAsyncFn(body.function_details.function_type)) { res.status(200); res.send(); } try { __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write((0, ansi_colors_1.bold)(`Received tunnel request from ${body.function_details.function_name}(${body.function_details.function_id})`)); const target = body.function_details.function_id in __classPrivateFieldGet(this, _TunnelServer_contextMap, "f") ? __classPrivateFieldGet(this, _TunnelServer_contextMap, "f")[body.function_details.function_id] : yield (() => __awaiter(this, void 0, void 0, function* () { if (__classPrivateFieldGet(this, _TunnelServer_projectId, "f") !== body.function_details.project_id) { yield this.send(req, res, 403); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write('Invalid access: the tunnel is trying to access the functions from a different project'); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write('[STATUS]'); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write('FORBIDDEN'); return; } const namedFn = __classPrivateFieldGet(this, _TunnelServer_contextMap, "f")[body.function_details.function_name]; if (namedFn) { return namedFn; } yield this.send(req, res, 404); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(`The tunneled function ${(0, ansi_colors_1.bold)(body.function_details.function_name)} is not present in local project directory`); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write('[STATUS]'); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write('NOT_FOUND'); return; })).bind(this)(); if (!target) { return; } const fnData = typeof body.function_data === 'string' ? JSON.parse(body.function_data) : body.function_data; target.call(false)(fnData); const errorHandler = (e) => __awaiter(this, void 0, void 0, function* () { yield this.send(req, res, 500); (0, index_1.debug)('Target error: ' + e); }); target.once('error', errorHandler); const response = yield new Promise((resolve, reject) => { target.once('response', (response) => { target.removeListener('error', errorHandler); if (!response.Status && !response.status) { return reject(response); } resolve(response); }); }); yield this.send(req, res, response.status, response.responseBody, response.ContentType); } catch (e) { yield this.send(req, res, 500); (0, index_1.debug)(e); } })); return new Promise((res, rej) => { try { __classPrivateFieldSet(this, _TunnelServer_server, app.listen(port, 'localhost', () => { __classPrivateFieldGet(this, _TunnelServer_repel, "f").write(); __classPrivateFieldGet(this, _TunnelServer_repel, "f").write((0, ansi_colors_1.bold)('Tunneling server running on port: ' + (0, ansi_colors_1.green)(port + ''))); res(); }), "f"); __classPrivateFieldSet(this, _TunnelServer_destroyer, new server_1.ConnectionDestroyer(__classPrivateFieldGet(this, _TunnelServer_server, "f")), "f"); __classPrivateFieldGet(this, _TunnelServer_server, "f").on('error', (err) => { throw new error_1.default('Tunneling server error', { original: err, exit: 2 }); }); } catch (er) { rej(new error_1.default('Unable to start the tunneling server', { exit: 2, original: er })); } }); }); } addContext(name, target) { if (!__classPrivateFieldGet(this, _TunnelServer_server, "f")) { return this; } __classPrivateFieldGet(this, _TunnelServer_contextMap, "f")[name] = target; return this; } stopServer() { var _a; return __awaiter(this, void 0, void 0, function* () { if (!__classPrivateFieldGet(this, _TunnelServer_server, "f")) { return; } return (_a = __classPrivateFieldGet(this, _TunnelServer_destroyer, "f")) === null || _a === void 0 ? void 0 : _a.destroy(); }); } } exports.default = TunnelServer; _TunnelServer_contextMap = new WeakMap(), _TunnelServer_server = new WeakMap(), _TunnelServer_destroyer = new WeakMap(), _TunnelServer_repel = new WeakMap(), _TunnelServer_projectId = new WeakMap();