UNPKG

serverless-spy

Version:

CDK-based library for writing elegant integration tests on AWS serverless architecture and an additional web console to monitor events in real time.

160 lines (158 loc) 6.97 kB
#!/usr/bin/env node const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js'); const require_listener_iot_connection = require('../listener/iot-connection.js'); const require_listener_topic = require('../listener/topic.js'); let fs = require("fs"); fs = require_rolldown_runtime.__toESM(fs); let path = require("path"); path = require_rolldown_runtime.__toESM(path); let http = require("http"); http = require_rolldown_runtime.__toESM(http); let util = require("util"); util = require_rolldown_runtime.__toESM(util); let caporal = require("caporal"); caporal = require_rolldown_runtime.__toESM(caporal); let open = require("open"); open = require_rolldown_runtime.__toESM(open); let ws = require("ws"); ws = require_rolldown_runtime.__toESM(ws); //#region cli/cli.ts const readFileAsync = (0, util.promisify)(fs.readFile); let opener = open; if (open.default) opener = open.default; async function run() { let stackList; let cdkOutput; let options; caporal.description("ServerlessSpy web console").option("--ws <ws>", "Websocket link").option("--cdkoutput <cdkoutput>", "CDK output file that contains IoT Endpoint link in a property ServerlessSpyWsUrl").option("--cdkstack <cdkstack>", "CDK stack in cdk output file. If not specified the first one is picked.").option("--open <open>", "Open browser", caporal.BOOL, true).option("--port <p>", `A port on localhost where ServerlessSpy web console is accessible.`, caporal.INT, "3456").option("--wsport <wsp>", `A port on localhost where ServerlessSpy websocket is accessible.`, caporal.INT, "3457").action((_args, opt, _logger) => { options = opt; }); caporal.parse(process.argv); if (!options.ws && !options.cdkoutput) throw new Error("--ws or --cdkoutput parameter not specified"); if (options.cdkoutput) { const rawdata = fs.readFileSync(options.cdkoutput); cdkOutput = JSON.parse(rawdata.toString()); stackList = Object.keys(cdkOutput); } const wss = new ws.WebSocketServer({ port: options.wsport }); let connection = void 0; wss.on("close", async () => { if (connection) connection.end(true); }); wss.on("connection", async function connect(ws$1) { console.log("Connection"); ws$1.on("message", function message(data) { console.log("received: %s", data); }); let wsUrl; if (options.ws) wsUrl = options.ws; else if (cdkOutput) { if (cdkOutput[options.cdkstack]) wsUrl = cdkOutput[options.cdkstack].ServerlessSpyWsUrl; else if (cdkOutput[Object.keys(cdkOutput)[0]]) wsUrl = cdkOutput[Object.keys(cdkOutput)[0]].ServerlessSpyWsUrl; } if (!wsUrl) throw new Error("Missing IoT endpoint url"); const wsUrlWithoutScope = wsUrl.split("/")[0]; connection = await require_listener_iot_connection.getConnection(true, wsUrlWithoutScope); const topic = require_listener_topic.getTopic("#"); console.log(`Subscribing to ${topic}`); connection.on("connect", () => { console.log("Connection opened"); if (connection) connection.subscribe(topic); }); connection.on("message", (topic$1, data) => { ws$1.send(JSON.stringify({ ...JSON.parse(JSON.parse(data.toString()).data), topic: topic$1 })); }); }); http.createServer((request, response) => { (async () => { try { let filePath = `.${request.url}`; filePath = filePath.split("?")[0]; let rootFolder = __dirname; if (request.url?.startsWith("/webServerlessSpy.js")) rootFolder = getCompiledJsPath(); else if (request.url?.startsWith("/bootstrap/")) { filePath = filePath.substring(11); rootFolder = await getNpmModuleInstalledPath("bootstrap"); } else if (request.url?.startsWith("/bootstrap-icons/")) { filePath = filePath.substring(17); rootFolder = await getNpmModuleInstalledPath("bootstrap-icons"); } else if (filePath === "./") filePath = "./index.html"; filePath = path.join(rootFolder, filePath); const extname = String(path.extname(filePath)).toLowerCase(); const contentType = { ".html": "text/html", ".js": "text/javascript", ".css": "text/css", ".json": "application/json", ".png": "image/png", ".jpg": "image/jpg", ".gif": "image/gif", ".svg": "image/svg+xml", ".wav": "audio/wav", ".mp4": "video/mp4", ".woff": "application/font-woff", ".ttf": "application/font-ttf", ".eot": "application/vnd.ms-fontobject", ".otf": "application/font-otf", ".wasm": "application/wasm" }[extname] || "application/octet-stream"; if (request.url === "/stackList") { response.writeHead(200, { "Content-Type": "application/json" }); response.end(JSON.stringify(stackList), "utf-8"); } else if (request.url === "/stackTopicMappings") { response.writeHead(200, { "Content-Type": "application/json" }); const mappings = {}; if (cdkOutput) { for (const [stackName, stack] of Object.entries(cdkOutput)) if (stack.ServerlessSpyWsUrl) { const [_, scope] = stack.ServerlessSpyWsUrl.split("/"); if (scope) mappings[stackName] = scope; } } response.end(JSON.stringify(mappings), "utf-8"); } else if (request.url?.match("^/wsUrl")) { response.writeHead(200, { "Content-Type": "text/html" }); response.end(`ws:localhost:${options.wsport}`, "utf-8"); } else try { const content = await readFileAsync(filePath); response.writeHead(200, { "Content-Type": contentType }); response.end(content, "utf-8"); } catch (error) { if (error.code === "ENOENT") { response.writeHead(404, { "Content-Type": "text/html" }); response.end(`No such file or directory ${request.url}`, "utf-8"); } else { response.writeHead(500); response.end(`Error: ${error.code} ..\n`); } } } catch (err) { response.writeHead(500, { "Content-Type": "text/html" }); response.end(err.message, "utf-8"); } })(); }).listen(options.port); console.log(`ServerlessSpy console runing at http://localhost:${options.port}`); if (options.open) await opener(`http://localhost:${options.port}`); } run().catch(console.error); function getNpmModuleInstalledPath(npm) { let folder = path.join(__dirname, "../", "node_modules", npm); if (fs.existsSync(folder)) return folder; let folderAsPackage = path.join(__dirname, "../../", "node_modules", npm); if (fs.existsSync(folderAsPackage)) return folderAsPackage; folderAsPackage = path.join(__dirname, "../../../../", "node_modules", npm); if (fs.existsSync(folderAsPackage)) return folderAsPackage; throw new Error(`Can not find package in folder ${folder} and ${folderAsPackage}`); } function getCompiledJsPath() { let folder = path.join(__dirname, "../", "lib/cli"); if (fs.existsSync(folder)) return folder; let folderAsPackage = path.join(__dirname, "../../", "lib/cli"); if (fs.existsSync(folderAsPackage)) return folderAsPackage; throw new Error(`Can not find compiled files in folder ${folder} and ${folderAsPackage}`); } //#endregion //# sourceMappingURL=cli.js.map