serverless-spy 2.3.10 → 2.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/.jsii +2 -2
  2. package/dist/releasetag.txt +1 -1
  3. package/lib/_virtual/rolldown_runtime.js +25 -0
  4. package/lib/_virtual/rolldown_runtime.mjs +11 -0
  5. package/lib/cli/cli.d.mts +1 -0
  6. package/lib/cli/cli.d.ts +1 -2
  7. package/lib/cli/cli.js +151 -208
  8. package/lib/cli/cli.js.map +1 -0
  9. package/lib/cli/cli.mjs +144 -205
  10. package/lib/cli/cli.mjs.map +1 -0
  11. package/lib/cli/sampleData.d.mts +896 -0
  12. package/lib/cli/sampleData.d.ts +860 -856
  13. package/lib/cli/sampleData.js +496 -480
  14. package/lib/cli/sampleData.js.map +1 -0
  15. package/lib/cli/sampleData.mjs +495 -477
  16. package/lib/cli/sampleData.mjs.map +1 -0
  17. package/lib/common/SpyEventSender.d.mts +26 -0
  18. package/lib/common/SpyEventSender.d.ts +23 -18
  19. package/lib/common/SpyEventSender.js +180 -230
  20. package/lib/common/SpyEventSender.js.map +1 -0
  21. package/lib/common/SpyEventSender.mjs +180 -227
  22. package/lib/common/SpyEventSender.mjs.map +1 -0
  23. package/lib/common/getWebSocketUrl.d.mts +7 -0
  24. package/lib/common/getWebSocketUrl.d.ts +7 -2
  25. package/lib/common/getWebSocketUrl.js +51 -62
  26. package/lib/common/getWebSocketUrl.js.map +1 -0
  27. package/lib/common/getWebSocketUrl.mjs +49 -60
  28. package/lib/common/getWebSocketUrl.mjs.map +1 -0
  29. package/lib/common/spyEvents/DynamoDBSpyEvent.d.mts +15 -0
  30. package/lib/common/spyEvents/DynamoDBSpyEvent.d.ts +14 -9
  31. package/lib/common/spyEvents/DynamoDBSpyEvent.js +0 -3
  32. package/lib/common/spyEvents/DynamoDBSpyEvent.mjs +1 -2
  33. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.d.mts +14 -0
  34. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.d.ts +13 -8
  35. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.js +0 -3
  36. package/lib/common/spyEvents/EventBridgeBaseSpyEvent.mjs +1 -2
  37. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.d.mts +9 -0
  38. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.d.ts +8 -3
  39. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.js +0 -3
  40. package/lib/common/spyEvents/EventBridgeRuleSpyEvent.mjs +1 -2
  41. package/lib/common/spyEvents/EventBridgeSpyEvent.d.mts +9 -0
  42. package/lib/common/spyEvents/EventBridgeSpyEvent.d.ts +8 -3
  43. package/lib/common/spyEvents/EventBridgeSpyEvent.js +0 -3
  44. package/lib/common/spyEvents/EventBridgeSpyEvent.mjs +1 -2
  45. package/lib/common/spyEvents/FunctionBaseSpyEvent.d.mts +11 -0
  46. package/lib/common/spyEvents/FunctionBaseSpyEvent.d.ts +10 -5
  47. package/lib/common/spyEvents/FunctionBaseSpyEvent.js +0 -3
  48. package/lib/common/spyEvents/FunctionBaseSpyEvent.mjs +1 -2
  49. package/lib/common/spyEvents/FunctionConsole.d.mts +10 -0
  50. package/lib/common/spyEvents/FunctionConsole.d.ts +9 -5
  51. package/lib/common/spyEvents/FunctionConsole.js +0 -3
  52. package/lib/common/spyEvents/FunctionConsole.mjs +1 -2
  53. package/lib/common/spyEvents/FunctionConsoleSpyEvent.d.mts +11 -0
  54. package/lib/common/spyEvents/FunctionConsoleSpyEvent.d.ts +10 -5
  55. package/lib/common/spyEvents/FunctionConsoleSpyEvent.js +0 -3
  56. package/lib/common/spyEvents/FunctionConsoleSpyEvent.mjs +1 -2
  57. package/lib/common/spyEvents/FunctionContext.d.mts +12 -0
  58. package/lib/common/spyEvents/FunctionContext.d.ts +11 -6
  59. package/lib/common/spyEvents/FunctionContext.js +0 -3
  60. package/lib/common/spyEvents/FunctionContext.mjs +1 -2
  61. package/lib/common/spyEvents/FunctionErrorSpyEvent.d.mts +13 -0
  62. package/lib/common/spyEvents/FunctionErrorSpyEvent.d.ts +12 -7
  63. package/lib/common/spyEvents/FunctionErrorSpyEvent.js +0 -3
  64. package/lib/common/spyEvents/FunctionErrorSpyEvent.mjs +1 -2
  65. package/lib/common/spyEvents/FunctionRequestSpyEvent.d.mts +12 -0
  66. package/lib/common/spyEvents/FunctionRequestSpyEvent.d.ts +11 -6
  67. package/lib/common/spyEvents/FunctionRequestSpyEvent.js +0 -3
  68. package/lib/common/spyEvents/FunctionRequestSpyEvent.mjs +1 -2
  69. package/lib/common/spyEvents/FunctionResponseSpyEvent.d.mts +10 -0
  70. package/lib/common/spyEvents/FunctionResponseSpyEvent.d.ts +9 -4
  71. package/lib/common/spyEvents/FunctionResponseSpyEvent.js +0 -3
  72. package/lib/common/spyEvents/FunctionResponseSpyEvent.mjs +1 -2
  73. package/lib/common/spyEvents/S3SpyEvent.d.mts +13 -0
  74. package/lib/common/spyEvents/S3SpyEvent.d.ts +12 -7
  75. package/lib/common/spyEvents/S3SpyEvent.js +0 -3
  76. package/lib/common/spyEvents/S3SpyEvent.mjs +1 -2
  77. package/lib/common/spyEvents/SnsSpyEventBase.d.mts +15 -0
  78. package/lib/common/spyEvents/SnsSpyEventBase.d.ts +14 -9
  79. package/lib/common/spyEvents/SnsSpyEventBase.js +0 -3
  80. package/lib/common/spyEvents/SnsSpyEventBase.mjs +1 -2
  81. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.d.mts +9 -0
  82. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.d.ts +8 -3
  83. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.js +0 -3
  84. package/lib/common/spyEvents/SnsSubscriptionSpyEvent.mjs +1 -2
  85. package/lib/common/spyEvents/SnsTopicSpyEvent.d.mts +9 -0
  86. package/lib/common/spyEvents/SnsTopicSpyEvent.d.ts +8 -3
  87. package/lib/common/spyEvents/SnsTopicSpyEvent.js +0 -3
  88. package/lib/common/spyEvents/SnsTopicSpyEvent.mjs +1 -2
  89. package/lib/common/spyEvents/SpyEvent.d.mts +7 -0
  90. package/lib/common/spyEvents/SpyEvent.d.ts +6 -2
  91. package/lib/common/spyEvents/SpyEvent.js +0 -3
  92. package/lib/common/spyEvents/SpyEvent.mjs +1 -2
  93. package/lib/common/spyEvents/SpyMessage.d.mts +11 -0
  94. package/lib/common/spyEvents/SpyMessage.d.ts +10 -5
  95. package/lib/common/spyEvents/SpyMessage.js +0 -3
  96. package/lib/common/spyEvents/SpyMessage.mjs +1 -2
  97. package/lib/common/spyEvents/SqsSpyEvent.d.mts +12 -0
  98. package/lib/common/spyEvents/SqsSpyEvent.d.ts +11 -6
  99. package/lib/common/spyEvents/SqsSpyEvent.js +0 -3
  100. package/lib/common/spyEvents/SqsSpyEvent.mjs +1 -2
  101. package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js +2 -2
  102. package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js.map +2 -2
  103. package/lib/functions/onConnect.d.mts +1 -0
  104. package/lib/functions/onConnect.d.ts +1 -1
  105. package/lib/functions/onConnect.js +28 -26
  106. package/lib/functions/onConnect.js.map +1 -0
  107. package/lib/functions/onConnect.mjs +35 -26
  108. package/lib/functions/onConnect.mjs.map +1 -0
  109. package/lib/functions/onDisconnect.d.mts +10 -0
  110. package/lib/functions/onDisconnect.d.ts +9 -4
  111. package/lib/functions/onDisconnect.js +28 -27
  112. package/lib/functions/onDisconnect.js.map +1 -0
  113. package/lib/functions/onDisconnect.mjs +29 -25
  114. package/lib/functions/onDisconnect.mjs.map +1 -0
  115. package/lib/functions/sendMessage.d.mts +8 -0
  116. package/lib/functions/sendMessage.d.ts +7 -3
  117. package/lib/functions/sendMessage.js +26 -21
  118. package/lib/functions/sendMessage.js.map +1 -0
  119. package/lib/functions/sendMessage.mjs +28 -19
  120. package/lib/functions/sendMessage.mjs.map +1 -0
  121. package/lib/functions/sqsSubscriptionAndDropAllMessages.d.mts +5 -0
  122. package/lib/functions/sqsSubscriptionAndDropAllMessages.d.ts +5 -1
  123. package/lib/functions/sqsSubscriptionAndDropAllMessages.js +6 -5
  124. package/lib/functions/sqsSubscriptionAndDropAllMessages.js.map +1 -0
  125. package/lib/functions/sqsSubscriptionAndDropAllMessages.mjs +7 -3
  126. package/lib/functions/sqsSubscriptionAndDropAllMessages.mjs.map +1 -0
  127. package/lib/index.d.mts +4 -0
  128. package/lib/index.d.ts +4 -2
  129. package/lib/index.js +6 -19
  130. package/lib/index.mjs +5 -3
  131. package/lib/listener/PrettifyForDisplay.d.mts +5 -0
  132. package/lib/listener/PrettifyForDisplay.d.ts +5 -3
  133. package/lib/listener/PrettifyForDisplay.js +0 -3
  134. package/lib/listener/PrettifyForDisplay.mjs +1 -2
  135. package/lib/listener/RecursivePartial.d.mts +7 -0
  136. package/lib/listener/RecursivePartial.d.ts +7 -4
  137. package/lib/listener/RecursivePartial.js +0 -3
  138. package/lib/listener/RecursivePartial.mjs +1 -2
  139. package/lib/listener/ServerlessSpyListener.d.mts +23 -0
  140. package/lib/listener/ServerlessSpyListener.d.ts +22 -42
  141. package/lib/listener/ServerlessSpyListener.js +0 -3
  142. package/lib/listener/ServerlessSpyListener.mjs +1 -2
  143. package/lib/listener/ServerlessSpyListenerParams.d.mts +14 -0
  144. package/lib/listener/ServerlessSpyListenerParams.d.ts +13 -8
  145. package/lib/listener/ServerlessSpyListenerParams.js +0 -3
  146. package/lib/listener/ServerlessSpyListenerParams.mjs +1 -2
  147. package/lib/listener/SpyHandlers.ts.d.mts +158 -0
  148. package/lib/listener/SpyHandlers.ts.d.ts +144 -144
  149. package/lib/listener/SpyHandlers.ts.js +0 -3
  150. package/lib/listener/SpyHandlers.ts.mjs +1 -2
  151. package/lib/listener/WaitForParams.d.mts +10 -0
  152. package/lib/listener/WaitForParams.d.ts +9 -4
  153. package/lib/listener/WaitForParams.js +0 -3
  154. package/lib/listener/WaitForParams.mjs +1 -2
  155. package/lib/listener/WsListener.d.mts +27 -0
  156. package/lib/listener/WsListener.d.ts +26 -21
  157. package/lib/listener/WsListener.js +173 -231
  158. package/lib/listener/WsListener.js.map +1 -0
  159. package/lib/listener/WsListener.mjs +174 -228
  160. package/lib/listener/WsListener.mjs.map +1 -0
  161. package/lib/listener/createServerlessSpyListener.d.mts +8 -0
  162. package/lib/listener/createServerlessSpyListener.d.ts +8 -2
  163. package/lib/listener/createServerlessSpyListener.js +25 -25
  164. package/lib/listener/createServerlessSpyListener.js.map +1 -0
  165. package/lib/listener/createServerlessSpyListener.mjs +26 -23
  166. package/lib/listener/createServerlessSpyListener.mjs.map +1 -0
  167. package/lib/listener/index.d.mts +3 -0
  168. package/lib/listener/index.d.ts +3 -2
  169. package/lib/listener/index.js +3 -19
  170. package/lib/listener/index.mjs +3 -3
  171. package/lib/listener/iot-connection.d.mts +13 -0
  172. package/lib/listener/iot-connection.d.ts +12 -7
  173. package/lib/listener/iot-connection.js +48 -46
  174. package/lib/listener/iot-connection.js.map +1 -0
  175. package/lib/listener/iot-connection.mjs +46 -44
  176. package/lib/listener/iot-connection.mjs.map +1 -0
  177. package/lib/listener/matchers.d.mts +1 -0
  178. package/lib/listener/matchers.d.ts +1 -0
  179. package/lib/listener/matchers.js +0 -55
  180. package/lib/listener/matchers.mjs +1 -55
  181. package/lib/listener/setup.d.mts +1 -0
  182. package/lib/listener/setup.d.ts +1 -0
  183. package/lib/listener/setup.js +0 -21
  184. package/lib/listener/setup.mjs +1 -21
  185. package/lib/listener/topic.d.mts +6 -0
  186. package/lib/listener/topic.d.ts +6 -2
  187. package/lib/listener/topic.js +9 -7
  188. package/lib/listener/topic.js.map +1 -0
  189. package/lib/listener/topic.mjs +8 -4
  190. package/lib/listener/topic.mjs.map +1 -0
  191. package/lib/node_modules/tsdown/esm-shims.mjs +11 -0
  192. package/lib/node_modules/tsdown/esm-shims.mjs.map +1 -0
  193. package/lib/node_modules/uuid/dist/esm-node/native.js +10 -0
  194. package/lib/node_modules/uuid/dist/esm-node/native.js.map +1 -0
  195. package/lib/node_modules/uuid/dist/esm-node/native.mjs +8 -0
  196. package/lib/node_modules/uuid/dist/esm-node/native.mjs.map +1 -0
  197. package/lib/node_modules/uuid/dist/esm-node/rng.js +18 -0
  198. package/lib/node_modules/uuid/dist/esm-node/rng.js.map +1 -0
  199. package/lib/node_modules/uuid/dist/esm-node/rng.mjs +16 -0
  200. package/lib/node_modules/uuid/dist/esm-node/rng.mjs.map +1 -0
  201. package/lib/node_modules/uuid/dist/esm-node/stringify.js +15 -0
  202. package/lib/node_modules/uuid/dist/esm-node/stringify.js.map +1 -0
  203. package/lib/node_modules/uuid/dist/esm-node/stringify.mjs +14 -0
  204. package/lib/node_modules/uuid/dist/esm-node/stringify.mjs.map +1 -0
  205. package/lib/node_modules/uuid/dist/esm-node/v4.js +23 -0
  206. package/lib/node_modules/uuid/dist/esm-node/v4.js.map +1 -0
  207. package/lib/node_modules/uuid/dist/esm-node/v4.mjs +23 -0
  208. package/lib/node_modules/uuid/dist/esm-node/v4.mjs.map +1 -0
  209. package/lib/src/ServerlessSpy.d.mts +77 -0
  210. package/lib/src/ServerlessSpy.js +1 -1
  211. package/lib/src/ServerlessSpy.js.map +1 -0
  212. package/lib/src/ServerlessSpy.mjs +441 -618
  213. package/lib/src/ServerlessSpy.mjs.map +1 -0
  214. package/lib/src/common/envVariableNames.d.mts +35 -0
  215. package/lib/src/common/envVariableNames.js.map +1 -0
  216. package/lib/src/common/envVariableNames.mjs +43 -35
  217. package/lib/src/common/envVariableNames.mjs.map +1 -0
  218. package/lib/src/index.d.mts +2 -0
  219. package/lib/src/index.mjs +3 -2
  220. package/node_modules/debug/package.json +2 -3
  221. package/node_modules/debug/src/browser.js +1 -1
  222. package/node_modules/debug/src/common.js +1 -1
  223. package/package.json +2 -1
  224. package/tsdown.config.ts +16 -0
package/.jsii CHANGED
@@ -4346,6 +4346,6 @@
4346
4346
  "symbolId": "src/ServerlessSpy:SpyFilter"
4347
4347
  }
4348
4348
  },
4349
- "version": "2.3.10",
4350
- "fingerprint": "TU4oJvNkOtBlBVGV1FUWaFUBSFowv2X/zsXzp/Xu5cI="
4349
+ "version": "2.3.11",
4350
+ "fingerprint": "DGV3KCEJCJOs0Mw4Taz6Z5jZSOAWZQssE5fu6MYac90="
4351
4351
  }
@@ -1 +1 @@
1
- v2.3.10
1
+ v2.3.11
@@ -0,0 +1,25 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+
25
+ exports.__toESM = __toESM;
@@ -0,0 +1,11 @@
1
+ //#region rolldown:runtime
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __commonJS = (cb, mod) => function() {
7
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
8
+ };
9
+
10
+ //#endregion
11
+ export { __commonJS, __esm };
@@ -0,0 +1 @@
1
+ export { };
package/lib/cli/cli.d.ts CHANGED
@@ -1,2 +1 @@
1
- #!/usr/bin/env node
2
- export {};
1
+ export { };
package/lib/cli/cli.js CHANGED
@@ -1,217 +1,160 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const fs = require("fs");
5
- const http = require("http");
6
- const path = require("path");
7
- const util_1 = require("util");
8
- const progam = require("caporal");
9
- const open = require("open");
10
- const ws_1 = require("ws");
11
- // @ts-ignore
12
- const iot_connection_1 = require("../listener/iot-connection");
13
- const topic_1 = require("../listener/topic");
14
- const readFileAsync = (0, util_1.promisify)(fs.readFile);
15
- //resolve issue with module import
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
3
+ const require_listener_iot_connection = require('../listener/iot-connection.js');
4
+ const require_listener_topic = require('../listener/topic.js');
5
+ let fs = require("fs");
6
+ fs = require_rolldown_runtime.__toESM(fs);
7
+ let path = require("path");
8
+ path = require_rolldown_runtime.__toESM(path);
9
+ let http = require("http");
10
+ http = require_rolldown_runtime.__toESM(http);
11
+ let util = require("util");
12
+ util = require_rolldown_runtime.__toESM(util);
13
+ let caporal = require("caporal");
14
+ caporal = require_rolldown_runtime.__toESM(caporal);
15
+ let open = require("open");
16
+ open = require_rolldown_runtime.__toESM(open);
17
+ let ws = require("ws");
18
+ ws = require_rolldown_runtime.__toESM(ws);
19
+
20
+ //#region cli/cli.ts
21
+ const readFileAsync = (0, util.promisify)(fs.readFile);
16
22
  let opener = open;
17
- if (open.default) {
18
- opener = open.default;
19
- }
23
+ if (open.default) opener = open.default;
20
24
  async function run() {
21
- let stackList;
22
- let cdkOutput;
23
- let options;
24
- progam
25
- .description('ServerlessSpy web console')
26
- .option('--ws <ws>', 'Websocket link')
27
- .option('--cdkoutput <cdkoutput>', 'CDK output file that contains IoT Endpoint link in a property ServerlessSpyWsUrl')
28
- .option('--cdkstack <cdkstack>', 'CDK stack in cdk output file. If not specified the first one is picked.')
29
- .option('--open <open>', 'Open browser', progam.BOOL, true)
30
- .option('--port <p>', `A port on localhost where ServerlessSpy web console is accessible.`, progam.INT, '3456')
31
- .option('--wsport <wsp>', `A port on localhost where ServerlessSpy websocket is accessible.`, progam.INT, '3457')
32
- .action((_args, opt, _logger) => {
33
- options = opt;
34
- });
35
- progam.parse(process.argv);
36
- if (!options.ws && !options.cdkoutput) {
37
- throw new Error('--ws or --cdkoutput parameter not specified');
38
- }
39
- if (options.cdkoutput) {
40
- const rawdata = fs.readFileSync(options.cdkoutput);
41
- cdkOutput = JSON.parse(rawdata.toString());
42
- stackList = Object.keys(cdkOutput);
43
- }
44
- const wss = new ws_1.WebSocketServer({ port: options.wsport });
45
- let connection = undefined;
46
- wss.on('close', async () => {
47
- if (connection)
48
- connection.end(true);
49
- });
50
- wss.on('connection', async function connect(ws) {
51
- console.log('Connection');
52
- ws.on('message', function message(data) {
53
- console.log('received: %s', data);
54
- });
55
- let wsUrl;
56
- if (options.ws) {
57
- wsUrl = options.ws;
58
- }
59
- else if (cdkOutput) {
60
- if (cdkOutput[options.cdkstack]) {
61
- wsUrl = cdkOutput[options.cdkstack].ServerlessSpyWsUrl;
62
- }
63
- else if (cdkOutput[Object.keys(cdkOutput)[0]]) {
64
- wsUrl = cdkOutput[Object.keys(cdkOutput)[0]].ServerlessSpyWsUrl;
65
- }
66
- }
67
- if (!wsUrl) {
68
- throw new Error('Missing IoT endpoint url');
69
- }
70
- const wsUrlWithoutScope = wsUrl.split('/')[0];
71
- connection = await (0, iot_connection_1.getConnection)(true, wsUrlWithoutScope);
72
- const topic = (0, topic_1.getTopic)('#');
73
- console.log(`Subscribing to ${topic}`);
74
- connection.on('connect', () => {
75
- console.log('Connection opened');
76
- if (connection) {
77
- connection.subscribe(topic);
78
- }
79
- });
80
- connection.on('message', (topic, data) => {
81
- ws.send(JSON.stringify({
82
- ...JSON.parse(JSON.parse(data.toString()).data),
83
- topic,
84
- }));
85
- });
86
- });
87
- http
88
- .createServer((request, response) => {
89
- void (async () => {
90
- try {
91
- //console.log('request ', request.url);
92
- let filePath = `.${request.url}`;
93
- //remove query parameters
94
- filePath = filePath.split('?')[0];
95
- let rootFolder = __dirname;
96
- if (request.url?.startsWith('/webServerlessSpy.js')) {
97
- //get transpiled TS to JS files
98
- rootFolder = getCompiledJsPath();
99
- }
100
- else if (request.url?.startsWith('/bootstrap/')) {
101
- filePath = filePath.substring('/bootstrap/'.length);
102
- const bootstrapFolder = await getNpmModuleInstalledPath('bootstrap');
103
- rootFolder = bootstrapFolder;
104
- }
105
- else if (request.url?.startsWith('/bootstrap-icons/')) {
106
- filePath = filePath.substring('/bootstrap-icons/'.length);
107
- const bootstrapFolder = await getNpmModuleInstalledPath('bootstrap-icons');
108
- rootFolder = bootstrapFolder;
109
- }
110
- else {
111
- if (filePath === './') {
112
- filePath = './index.html';
113
- }
114
- }
115
- filePath = path.join(rootFolder, filePath);
116
- //console.log(`${request.url} --> ${filePath}`);
117
- const extname = String(path.extname(filePath)).toLowerCase();
118
- const mimeTypes = {
119
- '.html': 'text/html',
120
- '.js': 'text/javascript',
121
- '.css': 'text/css',
122
- '.json': 'application/json',
123
- '.png': 'image/png',
124
- '.jpg': 'image/jpg',
125
- '.gif': 'image/gif',
126
- '.svg': 'image/svg+xml',
127
- '.wav': 'audio/wav',
128
- '.mp4': 'video/mp4',
129
- '.woff': 'application/font-woff',
130
- '.ttf': 'application/font-ttf',
131
- '.eot': 'application/vnd.ms-fontobject',
132
- '.otf': 'application/font-otf',
133
- '.wasm': 'application/wasm',
134
- };
135
- const contentType = mimeTypes[extname] || 'application/octet-stream';
136
- if (request.url === '/stackList') {
137
- response.writeHead(200, { 'Content-Type': 'application/json' });
138
- response.end(JSON.stringify(stackList), 'utf-8');
139
- }
140
- else if (request.url === '/stackTopicMappings') {
141
- response.writeHead(200, { 'Content-Type': 'application/json' });
142
- const mappings = {};
143
- if (cdkOutput) {
144
- for (const [stackName, stack] of Object.entries(cdkOutput)) {
145
- if (stack.ServerlessSpyWsUrl) {
146
- const [_, scope] = stack.ServerlessSpyWsUrl.split('/');
147
- if (scope) {
148
- mappings[stackName] = scope;
149
- }
150
- }
151
- }
152
- }
153
- response.end(JSON.stringify(mappings), 'utf-8');
154
- }
155
- else if (request.url?.match('^/wsUrl')) {
156
- response.writeHead(200, { 'Content-Type': 'text/html' });
157
- response.end(`ws:localhost:${options.wsport}`, 'utf-8');
158
- }
159
- else {
160
- try {
161
- const content = await readFileAsync(filePath);
162
- response.writeHead(200, { 'Content-Type': contentType });
163
- response.end(content, 'utf-8');
164
- }
165
- catch (error) {
166
- if (error.code === 'ENOENT') {
167
- response.writeHead(404, { 'Content-Type': 'text/html' });
168
- response.end(`No such file or directory ${request.url}`, 'utf-8');
169
- }
170
- else {
171
- response.writeHead(500);
172
- response.end(`Error: ${error.code} ..\n`);
173
- }
174
- }
175
- }
176
- }
177
- catch (err) {
178
- response.writeHead(500, { 'Content-Type': 'text/html' });
179
- response.end(err.message, 'utf-8');
180
- }
181
- })();
182
- })
183
- .listen(options.port);
184
- console.log(`ServerlessSpy console runing at http://localhost:${options.port}`);
185
- if (options.open) {
186
- await opener(`http://localhost:${options.port}`);
187
- }
25
+ let stackList;
26
+ let cdkOutput;
27
+ let options;
28
+ 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) => {
29
+ options = opt;
30
+ });
31
+ caporal.parse(process.argv);
32
+ if (!options.ws && !options.cdkoutput) throw new Error("--ws or --cdkoutput parameter not specified");
33
+ if (options.cdkoutput) {
34
+ const rawdata = fs.readFileSync(options.cdkoutput);
35
+ cdkOutput = JSON.parse(rawdata.toString());
36
+ stackList = Object.keys(cdkOutput);
37
+ }
38
+ const wss = new ws.WebSocketServer({ port: options.wsport });
39
+ let connection = void 0;
40
+ wss.on("close", async () => {
41
+ if (connection) connection.end(true);
42
+ });
43
+ wss.on("connection", async function connect(ws$1) {
44
+ console.log("Connection");
45
+ ws$1.on("message", function message(data) {
46
+ console.log("received: %s", data);
47
+ });
48
+ let wsUrl;
49
+ if (options.ws) wsUrl = options.ws;
50
+ else if (cdkOutput) {
51
+ if (cdkOutput[options.cdkstack]) wsUrl = cdkOutput[options.cdkstack].ServerlessSpyWsUrl;
52
+ else if (cdkOutput[Object.keys(cdkOutput)[0]]) wsUrl = cdkOutput[Object.keys(cdkOutput)[0]].ServerlessSpyWsUrl;
53
+ }
54
+ if (!wsUrl) throw new Error("Missing IoT endpoint url");
55
+ const wsUrlWithoutScope = wsUrl.split("/")[0];
56
+ connection = await require_listener_iot_connection.getConnection(true, wsUrlWithoutScope);
57
+ const topic = require_listener_topic.getTopic("#");
58
+ console.log(`Subscribing to ${topic}`);
59
+ connection.on("connect", () => {
60
+ console.log("Connection opened");
61
+ if (connection) connection.subscribe(topic);
62
+ });
63
+ connection.on("message", (topic$1, data) => {
64
+ ws$1.send(JSON.stringify({
65
+ ...JSON.parse(JSON.parse(data.toString()).data),
66
+ topic: topic$1
67
+ }));
68
+ });
69
+ });
70
+ http.createServer((request, response) => {
71
+ (async () => {
72
+ try {
73
+ let filePath = `.${request.url}`;
74
+ filePath = filePath.split("?")[0];
75
+ let rootFolder = __dirname;
76
+ if (request.url?.startsWith("/webServerlessSpy.js")) rootFolder = getCompiledJsPath();
77
+ else if (request.url?.startsWith("/bootstrap/")) {
78
+ filePath = filePath.substring(11);
79
+ rootFolder = await getNpmModuleInstalledPath("bootstrap");
80
+ } else if (request.url?.startsWith("/bootstrap-icons/")) {
81
+ filePath = filePath.substring(17);
82
+ rootFolder = await getNpmModuleInstalledPath("bootstrap-icons");
83
+ } else if (filePath === "./") filePath = "./index.html";
84
+ filePath = path.join(rootFolder, filePath);
85
+ const extname = String(path.extname(filePath)).toLowerCase();
86
+ const contentType = {
87
+ ".html": "text/html",
88
+ ".js": "text/javascript",
89
+ ".css": "text/css",
90
+ ".json": "application/json",
91
+ ".png": "image/png",
92
+ ".jpg": "image/jpg",
93
+ ".gif": "image/gif",
94
+ ".svg": "image/svg+xml",
95
+ ".wav": "audio/wav",
96
+ ".mp4": "video/mp4",
97
+ ".woff": "application/font-woff",
98
+ ".ttf": "application/font-ttf",
99
+ ".eot": "application/vnd.ms-fontobject",
100
+ ".otf": "application/font-otf",
101
+ ".wasm": "application/wasm"
102
+ }[extname] || "application/octet-stream";
103
+ if (request.url === "/stackList") {
104
+ response.writeHead(200, { "Content-Type": "application/json" });
105
+ response.end(JSON.stringify(stackList), "utf-8");
106
+ } else if (request.url === "/stackTopicMappings") {
107
+ response.writeHead(200, { "Content-Type": "application/json" });
108
+ const mappings = {};
109
+ if (cdkOutput) {
110
+ for (const [stackName, stack] of Object.entries(cdkOutput)) if (stack.ServerlessSpyWsUrl) {
111
+ const [_, scope] = stack.ServerlessSpyWsUrl.split("/");
112
+ if (scope) mappings[stackName] = scope;
113
+ }
114
+ }
115
+ response.end(JSON.stringify(mappings), "utf-8");
116
+ } else if (request.url?.match("^/wsUrl")) {
117
+ response.writeHead(200, { "Content-Type": "text/html" });
118
+ response.end(`ws:localhost:${options.wsport}`, "utf-8");
119
+ } else try {
120
+ const content = await readFileAsync(filePath);
121
+ response.writeHead(200, { "Content-Type": contentType });
122
+ response.end(content, "utf-8");
123
+ } catch (error) {
124
+ if (error.code === "ENOENT") {
125
+ response.writeHead(404, { "Content-Type": "text/html" });
126
+ response.end(`No such file or directory ${request.url}`, "utf-8");
127
+ } else {
128
+ response.writeHead(500);
129
+ response.end(`Error: ${error.code} ..\n`);
130
+ }
131
+ }
132
+ } catch (err) {
133
+ response.writeHead(500, { "Content-Type": "text/html" });
134
+ response.end(err.message, "utf-8");
135
+ }
136
+ })();
137
+ }).listen(options.port);
138
+ console.log(`ServerlessSpy console runing at http://localhost:${options.port}`);
139
+ if (options.open) await opener(`http://localhost:${options.port}`);
188
140
  }
189
141
  run().catch(console.error);
190
142
  function getNpmModuleInstalledPath(npm) {
191
- let folder = path.join(__dirname, '../', 'node_modules', npm);
192
- if (fs.existsSync(folder)) {
193
- return folder;
194
- }
195
- let folderAsPackage = path.join(__dirname, '../../', 'node_modules', npm);
196
- if (fs.existsSync(folderAsPackage)) {
197
- return folderAsPackage;
198
- }
199
- // When boostrap ends up in importing projects root node_modules and not in serverless-spys node_modules
200
- folderAsPackage = path.join(__dirname, '../../../../', 'node_modules', npm);
201
- if (fs.existsSync(folderAsPackage)) {
202
- return folderAsPackage;
203
- }
204
- throw new Error(`Can not find package in folder ${folder} and ${folderAsPackage}`);
143
+ let folder = path.join(__dirname, "../", "node_modules", npm);
144
+ if (fs.existsSync(folder)) return folder;
145
+ let folderAsPackage = path.join(__dirname, "../../", "node_modules", npm);
146
+ if (fs.existsSync(folderAsPackage)) return folderAsPackage;
147
+ folderAsPackage = path.join(__dirname, "../../../../", "node_modules", npm);
148
+ if (fs.existsSync(folderAsPackage)) return folderAsPackage;
149
+ throw new Error(`Can not find package in folder ${folder} and ${folderAsPackage}`);
205
150
  }
206
151
  function getCompiledJsPath() {
207
- let folder = path.join(__dirname, '../', 'lib/cli');
208
- if (fs.existsSync(folder)) {
209
- return folder;
210
- }
211
- let folderAsPackage = path.join(__dirname, '../../', 'lib/cli');
212
- if (fs.existsSync(folderAsPackage)) {
213
- return folderAsPackage;
214
- }
215
- throw new Error(`Can not find compiled files in folder ${folder} and ${folderAsPackage}`);
152
+ let folder = path.join(__dirname, "../", "lib/cli");
153
+ if (fs.existsSync(folder)) return folder;
154
+ let folderAsPackage = path.join(__dirname, "../../", "lib/cli");
155
+ if (fs.existsSync(folderAsPackage)) return folderAsPackage;
156
+ throw new Error(`Can not find compiled files in folder ${folder} and ${folderAsPackage}`);
216
157
  }
217
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY2xpL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLDZCQUE2QjtBQUM3QiwrQkFBaUM7QUFFakMsa0NBQWtDO0FBQ2xDLDZCQUE2QjtBQUM3QiwyQkFBcUM7QUFDckMsYUFBYTtBQUNiLCtEQUEyRDtBQUMzRCw2Q0FBNkM7QUFFN0MsTUFBTSxhQUFhLEdBQUcsSUFBQSxnQkFBUyxFQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUU3QyxrQ0FBa0M7QUFDbEMsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDO0FBQ2xCLElBQUssSUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzFCLE1BQU0sR0FBSSxJQUFZLENBQUMsT0FBTyxDQUFDO0FBQ2pDLENBQUM7QUFFRCxLQUFLLFVBQVUsR0FBRztJQUNoQixJQUFJLFNBQStCLENBQUM7SUFDcEMsSUFBSSxTQUFpRCxDQUFDO0lBRXRELElBQUksT0FBWSxDQUFDO0lBRWpCLE1BQU07U0FDSCxXQUFXLENBQUMsMkJBQTJCLENBQUM7U0FDeEMsTUFBTSxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQztTQUNyQyxNQUFNLENBQ0wseUJBQXlCLEVBQ3pCLGtGQUFrRixDQUNuRjtTQUNBLE1BQU0sQ0FDTCx1QkFBdUIsRUFDdkIseUVBQXlFLENBQzFFO1NBQ0EsTUFBTSxDQUFDLGVBQWUsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7U0FDMUQsTUFBTSxDQUNMLFlBQVksRUFDWixvRUFBb0UsRUFDcEUsTUFBTSxDQUFDLEdBQUcsRUFDVixNQUFNLENBQ1A7U0FDQSxNQUFNLENBQ0wsZ0JBQWdCLEVBQ2hCLGtFQUFrRSxFQUNsRSxNQUFNLENBQUMsR0FBRyxFQUNWLE1BQU0sQ0FDUDtTQUNBLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxHQUFH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VUFBVSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDbkMsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQ2Isa0NBQWtDLE1BQU0sUUFBUSxlQUFlLEVBQUUsQ0FDbEUsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGlCQUFpQjtJQUN4QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDcEQsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDMUIsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUVoRSxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxPQUFPLGVBQWUsQ0FBQztJQUN6QixDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYix5Q0FBeUMsTUFBTSxRQUFRLGVBQWUsRUFBRSxDQUN6RSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBkZXZpY2UgfSBmcm9tICdhd3MtaW90LWRldmljZS1zZGsnO1xuaW1wb3J0ICogYXMgcHJvZ2FtIGZyb20gJ2NhcG9yYWwnO1xuaW1wb3J0ICogYXMgb3BlbiBmcm9tICdvcGVuJztcbmltcG9ydCB7IFdlYlNvY2tldFNlcnZlciB9IGZyb20gJ3dzJztcbi8vIEB0cy1pZ25vcmVcbmltcG9ydCB7IGdldENvbm5lY3Rpb24gfSBmcm9tICcuLi9saXN0ZW5lci9pb3QtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBnZXRUb3BpYyB9IGZyb20gJy4uL2xpc3RlbmVyL3RvcGljJztcblxuY29uc3QgcmVhZEZpbGVBc3luYyA9IHByb21pc2lmeShmcy5yZWFkRmlsZSk7XG5cbi8vcmVzb2x2ZSBpc3N1ZSB3aXRoIG1vZHVsZSBpbXBvcnRcbmxldCBvcGVuZXIgPSBvcGVuO1xuaWYgKChvcGVuIGFzIGFueSkuZGVmYXVsdCkge1xuICBvcGVuZXIgPSAob3BlbiBhcyBhbnkpLmRlZmF1bHQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bigpIHtcbiAgbGV0IHN0YWNrTGlzdDogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIGxldCBjZGtPdXRwdXQ6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xuXG4gIGxldCBvcHRpb25zOiBhbnk7XG5cbiAgcHJvZ2FtXG4gICAgLmRlc2NyaXB0aW9uKCdTZXJ2ZXJsZXNzU3B5IHdlYiBjb25zb2xlJylcbiAgICAub3B0aW9uKCctLXdzIDx3cz4nLCAnV2Vic29ja2V0IGxpbmsnKVxuICAgIC5vcHRpb24oXG4gICAgICAnLS1jZGtvdXRwdXQgPGNka291dHB1dD4nLFxuICAgICAgJ0NESyBvdXRwdXQgZmlsZSB0aGF0IGNvbnRhaW5zIElvVCBFbmRwb2ludCBsaW5rIGluIGEgcHJvcGVydHkgU2VydmVybGVzc1NweVdzVXJsJ1xuICAgIClcbiAgICAub3B0aW9uKFxuICAgICAgJy0tY2Rrc3RhY2sgPGNka3N0YWNrPicsXG4gICAgICAnQ0RLIHN0YWNrIGluIGNkayBvdXRwdXQgZmlsZS4gSWYgbm90IHNwZWNpZmllZCB0aGUgZmlyc3Qgb25lIGlzIHBpY2tlZC4nXG4gICAgKVxuICAgIC5vcHRpb24oJy0tb3BlbiA8b3Blbj4nLCAnT3BlbiBicm93c2VyJywgcHJvZ2FtLkJPT0wsIHRydWUpXG4gICAgLm9wdGlvbihcbiAgICAgICctLXBvcnQgPHA+JyxcbiAgICAgIGBBIHBvcnQgb24gbG9jYWxob3N0IHdoZXJlIFNlcnZlcmxlc3NTcHkgd2ViIGNvbnNvbGUgaXMgYWNjZXNzaWJsZS5gLFxuICAgICAgcHJvZ2FtLklOVCxcbiAgICAgICczNDU2J1xuICAgIClcbiAgICAub3B0aW9uKFxuICAgICAgJy0td3Nwb3J0IDx3c3A+JyxcbiAgICAgIGBBIHBvcnQgb24gbG9jYWxob3N0IHdoZXJlIFNlcnZlcmxlc3NTcHkgd2Vic29ja2V0IGlzIGFjY2Vzc2libGUuYCxcbiAgICAgIHByb2dhbS5JTlQsXG4gICAgICAnMzQ1NydcbiAgICApXG4gICAgLmFjdGlvbigoX2FyZ3MsIG9wdCwgX2xvZ2dlcikgPT4ge1xuICAgICAgb3B0aW9ucyA9IG9wdDtcbiAgICB9KTtcblxuICBwcm9nYW0ucGFyc2UocHJvY2Vzcy5hcmd2KTtcblxuICBpZiAoIW9wdGlvbnMud3MgJiYgIW9wdGlvbnMuY2Rrb3V0cHV0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCctLXdzIG9yIC0tY2Rrb3V0cHV0IHBhcmFtZXRlciBub3Qgc3BlY2lmaWVkJyk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5jZGtvdXRwdXQpIHtcbiAgICBjb25zdCByYXdkYXRhID0gZnMucmVhZEZpbGVTeW5jKG9wdGlvbnMuY2Rrb3V0cHV0KTtcbiAgICBjZGtPdXRwdXQgPSBKU09OLnBhcnNlKHJhd2RhdGEudG9TdHJpbmcoKSk7XG4gICAgc3RhY2tMaXN0ID0gT2JqZWN0LmtleXMoY2RrT3V0cHV0KTtcbiAgfVxuXG4gIGNvbnN0IHdzcyA9IG5ldyBXZWJTb2NrZXRTZXJ2ZXIoeyBwb3J0OiBvcHRpb25zLndzcG9ydCB9KTtcbiAgbGV0IGNvbm5lY3Rpb246IGRldmljZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICB3c3Mub24oJ2Nsb3NlJywgYXN5bmMgKCkgPT4ge1xuICAgIGlmIChjb25uZWN0aW9uKSBjb25uZWN0aW9uLmVuZCh0cnVlKTtcbiAgfSk7XG5cbiAgd3NzLm9uKCdjb25uZWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gY29ubmVjdCh3cykge1xuICAgIGNvbnNvbGUubG9nKCdDb25uZWN0aW9uJyk7XG4gICAgd3Mub24oJ21lc3NhZ2UnLCBmdW5jdGlvbiBtZXNzYWdlKGRhdGEpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdyZWNlaXZlZDogJXMnLCBkYXRhKTtcbiAgICB9KTtcblxuICAgIGxldCB3c1VybDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmIChvcHRpb25zLndzKSB7XG4gICAgICB3c1VybCA9IG9wdGlvbnMud3M7XG4gICAgfSBlbHNlIGlmIChjZGtPdXRwdXQpIHtcbiAgICAgIGlmIChjZGtPdXRwdXRbb3B0aW9ucy5jZGtzdGFja10pIHtcbiAgICAgICAgd3NVcmwgPSBjZGtPdXRwdXRbb3B0aW9ucy5jZGtzdGFja10uU2VydmVybGVzc1NweVdzVXJsO1xuICAgICAgfSBlbHNlIGlmIChjZGtPdXRwdXRbT2JqZWN0LmtleXMoY2RrT3V0cHV0KVswXV0pIHtcbiAgICAgICAgd3NVcmwgPSBjZGtPdXRwdXRbT2JqZWN0LmtleXMoY2RrT3V0cHV0KVswXV0uU2VydmVybGVzc1NweVdzVXJsO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghd3NVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBJb1QgZW5kcG9pbnQgdXJsJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgd3NVcmxXaXRob3V0U2NvcGUgPSB3c1VybC5zcGxpdCgnLycpWzBdO1xuXG4gICAgY29ubmVjdGlvbiA9IGF3YWl0IGdldENvbm5lY3Rpb24odHJ1ZSwgd3NVcmxXaXRob3V0U2NvcGUpO1xuXG4gICAgY29uc3QgdG9waWMgPSBnZXRUb3BpYygnIycpO1xuICAgIGNvbnNvbGUubG9nKGBTdWJzY3JpYmluZyB0byAke3RvcGljfWApO1xuXG4gICAgY29ubmVjdGlvbi5vbignY29ubmVjdCcsICgpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKCdDb25uZWN0aW9uIG9wZW5lZCcpO1xuICAgICAgaWYgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgY29ubmVjdGlvbi5zdWJzY3JpYmUodG9waWMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29ubmVjdGlvbi5vbignbWVzc2FnZScsICh0b3BpYzogc3RyaW5nLCBkYXRhOiBCdWZmZXIpID0+IHtcbiAgICAgIHdzLnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAuLi5KU09OLnBhcnNlKEpTT04ucGFyc2UoZGF0YS50b1N0cmluZygpKS5kYXRhKSxcbiAgICAgICAgICB0b3BpYyxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGh0dHBcbiAgICAuY3JlYXRlU2VydmVyKChyZXF1ZXN0LCByZXNwb25zZSkgPT4ge1xuICAgICAgdm9pZCAoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vY29uc29sZS5sb2coJ3JlcXVlc3QgJywgcmVxdWVzdC51cmwpO1xuICAgICAgICAgIGxldCBmaWxlUGF0aDogc3RyaW5nID0gYC4ke3JlcXVlc3QudXJsfWA7XG4gICAgICAgICAgLy9yZW1vdmUgcXVlcnkgcGFyYW1ldGVyc1xuICAgICAgICAgIGZpbGVQYXRoID0gZmlsZVBhdGguc3BsaXQoJz8nKVswXTtcbiAgICAgICAgICBsZXQgcm9vdEZvbGRlciA9IF9fZGlybmFtZTtcblxuICAgICAgICAgIGlmIChyZXF1ZXN0LnVybD8uc3RhcnRzV2l0aCgnL3dlYlNlcnZlcmxlc3NTcHkuanMnKSkge1xuICAgICAgICAgICAgLy9nZXQgdHJhbnNwaWxlZCBUUyB0byBKUyBmaWxlc1xuICAgICAgICAgICAgcm9vdEZvbGRlciA9IGdldENvbXBpbGVkSnNQYXRoKCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnVybD8uc3RhcnRzV2l0aCgnL2Jvb3RzdHJhcC8nKSkge1xuICAgICAgICAgICAgZmlsZVBhdGggPSBmaWxlUGF0aC5zdWJzdHJpbmcoJy9ib290c3RyYXAvJy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgYm9vdHN0cmFwRm9sZGVyID0gYXdhaXQgZ2V0TnBtTW9kdWxlSW5zdGFsbGVkUGF0aChcbiAgICAgICAgICAgICAgJ2Jvb3RzdHJhcCdcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJvb3RGb2xkZXIgPSBib290c3RyYXBGb2xkZXI7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnVybD8uc3RhcnRzV2l0aCgnL2Jvb3RzdHJhcC1pY29ucy8nKSkge1xuICAgICAgICAgICAgZmlsZVBhdGggPSBmaWxlUGF0aC5zdWJzdHJpbmcoJy9ib290c3RyYXAtaWNvbnMvJy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgYm9vdHN0cmFwRm9sZGVyID0gYXdhaXQgZ2V0TnBtTW9kdWxlSW5zdGFsbGVkUGF0aChcbiAgICAgICAgICAgICAgJ2Jvb3RzdHJhcC1pY29ucydcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJvb3RGb2xkZXIgPSBib290c3RyYXBGb2xkZXI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmaWxlUGF0aCA9PT0gJy4vJykge1xuICAgICAgICAgICAgICBmaWxlUGF0aCA9ICcuL2luZGV4Lmh0bWwnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZpbGVQYXRoID0gcGF0aC5qb2luKHJvb3RGb2xkZXIsIGZpbGVQYXRoKTtcbiAgICAgICAgICAvL2NvbnNvbGUubG9nKGAke3JlcXVlc3QudXJsfSAtLT4gJHtmaWxlUGF0aH1gKTtcblxuICAgICAgICAgIGNvbnN0IGV4dG5hbWUgPSBTdHJpbmcocGF0aC5leHRuYW1lKGZpbGVQYXRoKSkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICBjb25zdCBtaW1lVHlwZXM6IGFueSA9IHtcbiAgICAgICAgICAgICcuaHRtbCc6ICd0ZXh0L2h0bWwnLFxuICAgICAgICAgICAgJy5qcyc6ICd0ZXh0L2phdmFzY3JpcHQnLFxuICAgICAgICAgICAgJy5jc3MnOiAndGV4dC9jc3MnLFxuICAgICAgICAgICAgJy5qc29uJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgJy5wbmcnOiAnaW1hZ2UvcG5nJyxcbiAgICAgICAgICAgICcuanBnJzogJ2ltYWdlL2pwZycsXG4gICAgICAgICAgICAnLmdpZic6ICdpbWFnZS9naWYnLFxuICAgICAgICAgICAgJy5zdmcnOiAnaW1hZ2Uvc3ZnK3htbCcsXG4gICAgICAgICAgICAnLndhdic6ICdhdWRpby93YXYnLFxuICAgICAgICAgICAgJy5tcDQnOiAndmlkZW8vbXA0JyxcbiAgICAgICAgICAgICcud29mZic6ICdhcHBsaWNhdGlvbi9mb250LXdvZmYnLFxuICAgICAgICAgICAgJy50dGYnOiAnYXBwbGljYXRpb24vZm9udC10dGYnLFxuICAgICAgICAgICAgJy5lb3QnOiAnYXBwbGljYXRpb24vdm5kLm1zLWZvbnRvYmplY3QnLFxuICAgICAgICAgICAgJy5vdGYnOiAnYXBwbGljYXRpb24vZm9udC1vdGYnLFxuICAgICAgICAgICAgJy53YXNtJzogJ2FwcGxpY2F0aW9uL3dhc20nLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCBjb250ZW50VHlwZSA9IG1pbWVUeXBlc1tleHRuYW1lXSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcblxuICAgICAgICAgIGlmIChyZXF1ZXN0LnVybCA9PT0gJy9zdGFja0xpc3QnKSB7XG4gICAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICByZXNwb25zZS5lbmQoSlNPTi5zdHJpbmdpZnkoc3RhY2tMaXN0KSwgJ3V0Zi04Jyk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnVybCA9PT0gJy9zdGFja1RvcGljTWFwcGluZ3MnKSB7XG4gICAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICBjb25zdCBtYXBwaW5nczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgICAgICAgICAgaWYgKGNka091dHB1dCkge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtzdGFja05hbWUsIHN0YWNrXSBvZiBPYmplY3QuZW50cmllcyhjZGtPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YWNrLlNlcnZlcmxlc3NTcHlXc1VybCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgW18sIHNjb3BlXSA9IHN0YWNrLlNlcnZlcmxlc3NTcHlXc1VybC5zcGxpdCgnLycpO1xuICAgICAgICAgICAgICAgICAgaWYgKHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcHBpbmdzW3N0YWNrTmFtZV0gPSBzY29wZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3BvbnNlLmVuZChKU09OLnN0cmluZ2lmeShtYXBwaW5ncyksICd1dGYtOCcpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdC51cmw/Lm1hdGNoKCdeL3dzVXJsJykpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCgyMDAsIHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L2h0bWwnIH0pO1xuICAgICAgICAgICAgcmVzcG9uc2UuZW5kKGB3czpsb2NhbGhvc3Q6JHtvcHRpb25zLndzcG9ydH1gLCAndXRmLTgnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlQXN5bmMoZmlsZVBhdGgpO1xuXG4gICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCgyMDAsIHsgJ0NvbnRlbnQtVHlwZSc6IGNvbnRlbnRUeXBlIH0pO1xuICAgICAgICAgICAgICByZXNwb25zZS5lbmQoY29udGVudCwgJ3V0Zi04Jyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCg0MDQsIHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L2h0bWwnIH0pO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmVuZChcbiAgICAgICAgICAgICAgICAgIGBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5ICR7cmVxdWVzdC51cmx9YCxcbiAgICAgICAgICAgICAgICAgICd1dGYtOCdcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCg1MDApO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmVuZChgRXJyb3I6ICR7ZXJyb3IuY29kZX0gLi5cXG5gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoNTAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9odG1sJyB9KTtcbiAgICAgICAgICByZXNwb25zZS5lbmQoZXJyLm1lc3NhZ2UsICd1dGYtOCcpO1xuICAgICAgICB9XG4gICAgICB9KSgpO1xuICAgIH0pXG4gICAgLmxpc3RlbihvcHRpb25zLnBvcnQpO1xuXG4gIGNvbnNvbGUubG9nKFxuICAgIGBTZXJ2ZXJsZXNzU3B5IGNvbnNvbGUgcnVuaW5nIGF0IGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRpb25zLnBvcnR9YFxuICApO1xuICBpZiAob3B0aW9ucy5vcGVuKSB7XG4gICAgYXdhaXQgb3BlbmVyKGBodHRwOi8vbG9jYWxob3N0OiR7b3B0aW9ucy5wb3J0fWApO1xuICB9XG59XG5cbnJ1bigpLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuXG5mdW5jdGlvbiBnZXROcG1Nb2R1bGVJbnN0YWxsZWRQYXRoKG5wbTogc3RyaW5nKSB7XG4gIGxldCBmb2xkZXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vJywgJ25vZGVfbW9kdWxlcycsIG5wbSk7XG4gIGlmIChmcy5leGlzdHNTeW5jKGZvbGRlcikpIHtcbiAgICByZXR1cm4gZm9sZGVyO1xuICB9XG5cbiAgbGV0IGZvbGRlckFzUGFja2FnZSA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8uLi8nLCAnbm9kZV9tb2R1bGVzJywgbnBtKTtcblxuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXJBc1BhY2thZ2UpKSB7XG4gICAgcmV0dXJuIGZvbGRlckFzUGFja2FnZTtcbiAgfVxuXG4gIC8vIFdoZW4gYm9vc3RyYXAgZW5kcyB1cCBpbiBpbXBvcnRpbmcgcHJvamVjdHMgcm9vdCBub2RlX21vZHVsZXMgYW5kIG5vdCBpbiBzZXJ2ZXJsZXNzLXNweXMgbm9kZV9tb2R1bGVzXG4gIGZvbGRlckFzUGFja2FnZSA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8uLi8uLi8uLi8nLCAnbm9kZV9tb2R1bGVzJywgbnBtKTtcblxuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXJBc1BhY2thZ2UpKSB7XG4gICAgcmV0dXJuIGZvbGRlckFzUGFja2FnZTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgQ2FuIG5vdCBmaW5kIHBhY2thZ2UgaW4gZm9sZGVyICR7Zm9sZGVyfSBhbmQgJHtmb2xkZXJBc1BhY2thZ2V9YFxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRDb21waWxlZEpzUGF0aCgpIHtcbiAgbGV0IGZvbGRlciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8nLCAnbGliL2NsaScpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXIpKSB7XG4gICAgcmV0dXJuIGZvbGRlcjtcbiAgfVxuXG4gIGxldCBmb2xkZXJBc1BhY2thZ2UgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vJywgJ2xpYi9jbGknKTtcblxuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXJBc1BhY2thZ2UpKSB7XG4gICAgcmV0dXJuIGZvbGRlckFzUGFja2FnZTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgQ2FuIG5vdCBmaW5kIGNvbXBpbGVkIGZpbGVzIGluIGZvbGRlciAke2ZvbGRlcn0gYW5kICR7Zm9sZGVyQXNQYWNrYWdlfWBcbiAgKTtcbn1cbiJdfQ==
158
+
159
+ //#endregion
160
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","names":["stackList: string[] | undefined","cdkOutput: Record<string, Record<string, string>>","options: any","progam","WebSocketServer","connection: device | undefined","wsUrl: string | undefined","getConnection","getTopic","filePath: string","mappings: Record<string, string>","error: any","err: any"],"sources":["../../cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport * as fs from 'fs';\nimport * as http from 'http';\nimport * as path from 'path';\nimport { promisify } from 'util';\nimport { device } from 'aws-iot-device-sdk';\nimport * as progam from 'caporal';\nimport * as open from 'open';\nimport { WebSocketServer } from 'ws';\n// @ts-ignore\nimport { getConnection } from '../listener/iot-connection';\nimport { getTopic } from '../listener/topic';\n\nconst readFileAsync = promisify(fs.readFile);\n\n//resolve issue with module import\nlet opener = open;\nif ((open as any).default) {\n opener = (open as any).default;\n}\n\nasync function run() {\n let stackList: string[] | undefined;\n let cdkOutput: Record<string, Record<string, string>>;\n\n let options: any;\n\n progam\n .description('ServerlessSpy web console')\n .option('--ws <ws>', 'Websocket link')\n .option(\n '--cdkoutput <cdkoutput>',\n 'CDK output file that contains IoT Endpoint link in a property ServerlessSpyWsUrl'\n )\n .option(\n '--cdkstack <cdkstack>',\n 'CDK stack in cdk output file. If not specified the first one is picked.'\n )\n .option('--open <open>', 'Open browser', progam.BOOL, true)\n .option(\n '--port <p>',\n `A port on localhost where ServerlessSpy web console is accessible.`,\n progam.INT,\n '3456'\n )\n .option(\n '--wsport <wsp>',\n `A port on localhost where ServerlessSpy websocket is accessible.`,\n progam.INT,\n '3457'\n )\n .action((_args, opt, _logger) => {\n options = opt;\n });\n\n progam.parse(process.argv);\n\n if (!options.ws && !options.cdkoutput) {\n throw new Error('--ws or --cdkoutput parameter not specified');\n }\n\n if (options.cdkoutput) {\n const rawdata = fs.readFileSync(options.cdkoutput);\n cdkOutput = JSON.parse(rawdata.toString());\n stackList = Object.keys(cdkOutput);\n }\n\n const wss = new WebSocketServer({ port: options.wsport });\n let connection: device | undefined = undefined;\n\n wss.on('close', async () => {\n if (connection) connection.end(true);\n });\n\n wss.on('connection', async function connect(ws) {\n console.log('Connection');\n ws.on('message', function message(data) {\n console.log('received: %s', data);\n });\n\n let wsUrl: string | undefined;\n if (options.ws) {\n wsUrl = options.ws;\n } else if (cdkOutput) {\n if (cdkOutput[options.cdkstack]) {\n wsUrl = cdkOutput[options.cdkstack].ServerlessSpyWsUrl;\n } else if (cdkOutput[Object.keys(cdkOutput)[0]]) {\n wsUrl = cdkOutput[Object.keys(cdkOutput)[0]].ServerlessSpyWsUrl;\n }\n }\n\n if (!wsUrl) {\n throw new Error('Missing IoT endpoint url');\n }\n\n const wsUrlWithoutScope = wsUrl.split('/')[0];\n\n connection = await getConnection(true, wsUrlWithoutScope);\n\n const topic = getTopic('#');\n console.log(`Subscribing to ${topic}`);\n\n connection.on('connect', () => {\n console.log('Connection opened');\n if (connection) {\n connection.subscribe(topic);\n }\n });\n\n connection.on('message', (topic: string, data: Buffer) => {\n ws.send(\n JSON.stringify({\n ...JSON.parse(JSON.parse(data.toString()).data),\n topic,\n })\n );\n });\n });\n\n http\n .createServer((request, response) => {\n void (async () => {\n try {\n //console.log('request ', request.url);\n let filePath: string = `.${request.url}`;\n //remove query parameters\n filePath = filePath.split('?')[0];\n let rootFolder = __dirname;\n\n if (request.url?.startsWith('/webServerlessSpy.js')) {\n //get transpiled TS to JS files\n rootFolder = getCompiledJsPath();\n } else if (request.url?.startsWith('/bootstrap/')) {\n filePath = filePath.substring('/bootstrap/'.length);\n const bootstrapFolder = await getNpmModuleInstalledPath(\n 'bootstrap'\n );\n\n rootFolder = bootstrapFolder;\n } else if (request.url?.startsWith('/bootstrap-icons/')) {\n filePath = filePath.substring('/bootstrap-icons/'.length);\n const bootstrapFolder = await getNpmModuleInstalledPath(\n 'bootstrap-icons'\n );\n\n rootFolder = bootstrapFolder;\n } else {\n if (filePath === './') {\n filePath = './index.html';\n }\n }\n\n filePath = path.join(rootFolder, filePath);\n //console.log(`${request.url} --> ${filePath}`);\n\n const extname = String(path.extname(filePath)).toLowerCase();\n const mimeTypes: any = {\n '.html': 'text/html',\n '.js': 'text/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.png': 'image/png',\n '.jpg': 'image/jpg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.wav': 'audio/wav',\n '.mp4': 'video/mp4',\n '.woff': 'application/font-woff',\n '.ttf': 'application/font-ttf',\n '.eot': 'application/vnd.ms-fontobject',\n '.otf': 'application/font-otf',\n '.wasm': 'application/wasm',\n };\n\n const contentType = mimeTypes[extname] || 'application/octet-stream';\n\n if (request.url === '/stackList') {\n response.writeHead(200, { 'Content-Type': 'application/json' });\n response.end(JSON.stringify(stackList), 'utf-8');\n } else if (request.url === '/stackTopicMappings') {\n response.writeHead(200, { 'Content-Type': 'application/json' });\n const mappings: Record<string, string> = {};\n if (cdkOutput) {\n for (const [stackName, stack] of Object.entries(cdkOutput)) {\n if (stack.ServerlessSpyWsUrl) {\n const [_, scope] = stack.ServerlessSpyWsUrl.split('/');\n if (scope) {\n mappings[stackName] = scope;\n }\n }\n }\n }\n response.end(JSON.stringify(mappings), 'utf-8');\n } else if (request.url?.match('^/wsUrl')) {\n response.writeHead(200, { 'Content-Type': 'text/html' });\n response.end(`ws:localhost:${options.wsport}`, 'utf-8');\n } else {\n try {\n const content = await readFileAsync(filePath);\n\n response.writeHead(200, { 'Content-Type': contentType });\n response.end(content, 'utf-8');\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n response.writeHead(404, { 'Content-Type': 'text/html' });\n response.end(\n `No such file or directory ${request.url}`,\n 'utf-8'\n );\n } else {\n response.writeHead(500);\n response.end(`Error: ${error.code} ..\\n`);\n }\n }\n }\n } catch (err: any) {\n response.writeHead(500, { 'Content-Type': 'text/html' });\n response.end(err.message, 'utf-8');\n }\n })();\n })\n .listen(options.port);\n\n console.log(\n `ServerlessSpy console runing at http://localhost:${options.port}`\n );\n if (options.open) {\n await opener(`http://localhost:${options.port}`);\n }\n}\n\nrun().catch(console.error);\n\nfunction getNpmModuleInstalledPath(npm: string) {\n let folder = path.join(__dirname, '../', 'node_modules', npm);\n if (fs.existsSync(folder)) {\n return folder;\n }\n\n let folderAsPackage = path.join(__dirname, '../../', 'node_modules', npm);\n\n if (fs.existsSync(folderAsPackage)) {\n return folderAsPackage;\n }\n\n // When boostrap ends up in importing projects root node_modules and not in serverless-spys node_modules\n folderAsPackage = path.join(__dirname, '../../../../', 'node_modules', npm);\n\n if (fs.existsSync(folderAsPackage)) {\n return folderAsPackage;\n }\n\n throw new Error(\n `Can not find package in folder ${folder} and ${folderAsPackage}`\n );\n}\n\nfunction getCompiledJsPath() {\n let folder = path.join(__dirname, '../', 'lib/cli');\n if (fs.existsSync(folder)) {\n return folder;\n }\n\n let folderAsPackage = path.join(__dirname, '../../', 'lib/cli');\n\n if (fs.existsSync(folderAsPackage)) {\n return folderAsPackage;\n }\n\n throw new Error(\n `Can not find compiled files in folder ${folder} and ${folderAsPackage}`\n );\n}\n"],"mappings":"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"}