serverless-spy 2.3.9 → 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.
- package/.jsii +2 -2
- package/dist/releasetag.txt +1 -1
- package/lib/_virtual/rolldown_runtime.js +25 -0
- package/lib/_virtual/rolldown_runtime.mjs +11 -0
- package/lib/cli/cli.d.mts +1 -0
- package/lib/cli/cli.d.ts +1 -2
- package/lib/cli/cli.js +151 -208
- package/lib/cli/cli.js.map +1 -0
- package/lib/cli/cli.mjs +144 -205
- package/lib/cli/cli.mjs.map +1 -0
- package/lib/cli/sampleData.d.mts +896 -0
- package/lib/cli/sampleData.d.ts +860 -856
- package/lib/cli/sampleData.js +496 -480
- package/lib/cli/sampleData.js.map +1 -0
- package/lib/cli/sampleData.mjs +495 -477
- package/lib/cli/sampleData.mjs.map +1 -0
- package/lib/common/SpyEventSender.d.mts +26 -0
- package/lib/common/SpyEventSender.d.ts +23 -18
- package/lib/common/SpyEventSender.js +180 -230
- package/lib/common/SpyEventSender.js.map +1 -0
- package/lib/common/SpyEventSender.mjs +180 -227
- package/lib/common/SpyEventSender.mjs.map +1 -0
- package/lib/common/getWebSocketUrl.d.mts +7 -0
- package/lib/common/getWebSocketUrl.d.ts +7 -2
- package/lib/common/getWebSocketUrl.js +51 -62
- package/lib/common/getWebSocketUrl.js.map +1 -0
- package/lib/common/getWebSocketUrl.mjs +49 -60
- package/lib/common/getWebSocketUrl.mjs.map +1 -0
- package/lib/common/spyEvents/DynamoDBSpyEvent.d.mts +15 -0
- package/lib/common/spyEvents/DynamoDBSpyEvent.d.ts +14 -9
- package/lib/common/spyEvents/DynamoDBSpyEvent.js +0 -3
- package/lib/common/spyEvents/DynamoDBSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/EventBridgeBaseSpyEvent.d.mts +14 -0
- package/lib/common/spyEvents/EventBridgeBaseSpyEvent.d.ts +13 -8
- package/lib/common/spyEvents/EventBridgeBaseSpyEvent.js +0 -3
- package/lib/common/spyEvents/EventBridgeBaseSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/EventBridgeRuleSpyEvent.d.mts +9 -0
- package/lib/common/spyEvents/EventBridgeRuleSpyEvent.d.ts +8 -3
- package/lib/common/spyEvents/EventBridgeRuleSpyEvent.js +0 -3
- package/lib/common/spyEvents/EventBridgeRuleSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/EventBridgeSpyEvent.d.mts +9 -0
- package/lib/common/spyEvents/EventBridgeSpyEvent.d.ts +8 -3
- package/lib/common/spyEvents/EventBridgeSpyEvent.js +0 -3
- package/lib/common/spyEvents/EventBridgeSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/FunctionBaseSpyEvent.d.mts +11 -0
- package/lib/common/spyEvents/FunctionBaseSpyEvent.d.ts +10 -5
- package/lib/common/spyEvents/FunctionBaseSpyEvent.js +0 -3
- package/lib/common/spyEvents/FunctionBaseSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/FunctionConsole.d.mts +10 -0
- package/lib/common/spyEvents/FunctionConsole.d.ts +9 -5
- package/lib/common/spyEvents/FunctionConsole.js +0 -3
- package/lib/common/spyEvents/FunctionConsole.mjs +1 -2
- package/lib/common/spyEvents/FunctionConsoleSpyEvent.d.mts +11 -0
- package/lib/common/spyEvents/FunctionConsoleSpyEvent.d.ts +10 -5
- package/lib/common/spyEvents/FunctionConsoleSpyEvent.js +0 -3
- package/lib/common/spyEvents/FunctionConsoleSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/FunctionContext.d.mts +12 -0
- package/lib/common/spyEvents/FunctionContext.d.ts +11 -6
- package/lib/common/spyEvents/FunctionContext.js +0 -3
- package/lib/common/spyEvents/FunctionContext.mjs +1 -2
- package/lib/common/spyEvents/FunctionErrorSpyEvent.d.mts +13 -0
- package/lib/common/spyEvents/FunctionErrorSpyEvent.d.ts +12 -7
- package/lib/common/spyEvents/FunctionErrorSpyEvent.js +0 -3
- package/lib/common/spyEvents/FunctionErrorSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/FunctionRequestSpyEvent.d.mts +12 -0
- package/lib/common/spyEvents/FunctionRequestSpyEvent.d.ts +11 -6
- package/lib/common/spyEvents/FunctionRequestSpyEvent.js +0 -3
- package/lib/common/spyEvents/FunctionRequestSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/FunctionResponseSpyEvent.d.mts +10 -0
- package/lib/common/spyEvents/FunctionResponseSpyEvent.d.ts +9 -4
- package/lib/common/spyEvents/FunctionResponseSpyEvent.js +0 -3
- package/lib/common/spyEvents/FunctionResponseSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/S3SpyEvent.d.mts +13 -0
- package/lib/common/spyEvents/S3SpyEvent.d.ts +12 -7
- package/lib/common/spyEvents/S3SpyEvent.js +0 -3
- package/lib/common/spyEvents/S3SpyEvent.mjs +1 -2
- package/lib/common/spyEvents/SnsSpyEventBase.d.mts +15 -0
- package/lib/common/spyEvents/SnsSpyEventBase.d.ts +14 -9
- package/lib/common/spyEvents/SnsSpyEventBase.js +0 -3
- package/lib/common/spyEvents/SnsSpyEventBase.mjs +1 -2
- package/lib/common/spyEvents/SnsSubscriptionSpyEvent.d.mts +9 -0
- package/lib/common/spyEvents/SnsSubscriptionSpyEvent.d.ts +8 -3
- package/lib/common/spyEvents/SnsSubscriptionSpyEvent.js +0 -3
- package/lib/common/spyEvents/SnsSubscriptionSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/SnsTopicSpyEvent.d.mts +9 -0
- package/lib/common/spyEvents/SnsTopicSpyEvent.d.ts +8 -3
- package/lib/common/spyEvents/SnsTopicSpyEvent.js +0 -3
- package/lib/common/spyEvents/SnsTopicSpyEvent.mjs +1 -2
- package/lib/common/spyEvents/SpyEvent.d.mts +7 -0
- package/lib/common/spyEvents/SpyEvent.d.ts +6 -2
- package/lib/common/spyEvents/SpyEvent.js +0 -3
- package/lib/common/spyEvents/SpyEvent.mjs +1 -2
- package/lib/common/spyEvents/SpyMessage.d.mts +11 -0
- package/lib/common/spyEvents/SpyMessage.d.ts +10 -5
- package/lib/common/spyEvents/SpyMessage.js +0 -3
- package/lib/common/spyEvents/SpyMessage.mjs +1 -2
- package/lib/common/spyEvents/SqsSpyEvent.d.mts +12 -0
- package/lib/common/spyEvents/SqsSpyEvent.d.ts +11 -6
- package/lib/common/spyEvents/SqsSpyEvent.js +0 -3
- package/lib/common/spyEvents/SqsSpyEvent.mjs +1 -2
- package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js +2 -2
- package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js.map +2 -2
- package/lib/functions/onConnect.d.mts +1 -0
- package/lib/functions/onConnect.d.ts +1 -1
- package/lib/functions/onConnect.js +28 -26
- package/lib/functions/onConnect.js.map +1 -0
- package/lib/functions/onConnect.mjs +35 -26
- package/lib/functions/onConnect.mjs.map +1 -0
- package/lib/functions/onDisconnect.d.mts +10 -0
- package/lib/functions/onDisconnect.d.ts +9 -4
- package/lib/functions/onDisconnect.js +28 -27
- package/lib/functions/onDisconnect.js.map +1 -0
- package/lib/functions/onDisconnect.mjs +29 -25
- package/lib/functions/onDisconnect.mjs.map +1 -0
- package/lib/functions/sendMessage.d.mts +8 -0
- package/lib/functions/sendMessage.d.ts +7 -3
- package/lib/functions/sendMessage.js +26 -21
- package/lib/functions/sendMessage.js.map +1 -0
- package/lib/functions/sendMessage.mjs +28 -19
- package/lib/functions/sendMessage.mjs.map +1 -0
- package/lib/functions/sqsSubscriptionAndDropAllMessages.d.mts +5 -0
- package/lib/functions/sqsSubscriptionAndDropAllMessages.d.ts +5 -1
- package/lib/functions/sqsSubscriptionAndDropAllMessages.js +6 -5
- package/lib/functions/sqsSubscriptionAndDropAllMessages.js.map +1 -0
- package/lib/functions/sqsSubscriptionAndDropAllMessages.mjs +7 -3
- package/lib/functions/sqsSubscriptionAndDropAllMessages.mjs.map +1 -0
- package/lib/index.d.mts +4 -0
- package/lib/index.d.ts +4 -2
- package/lib/index.js +6 -19
- package/lib/index.mjs +5 -3
- package/lib/listener/PrettifyForDisplay.d.mts +5 -0
- package/lib/listener/PrettifyForDisplay.d.ts +5 -3
- package/lib/listener/PrettifyForDisplay.js +0 -3
- package/lib/listener/PrettifyForDisplay.mjs +1 -2
- package/lib/listener/RecursivePartial.d.mts +7 -0
- package/lib/listener/RecursivePartial.d.ts +7 -4
- package/lib/listener/RecursivePartial.js +0 -3
- package/lib/listener/RecursivePartial.mjs +1 -2
- package/lib/listener/ServerlessSpyListener.d.mts +23 -0
- package/lib/listener/ServerlessSpyListener.d.ts +22 -42
- package/lib/listener/ServerlessSpyListener.js +0 -3
- package/lib/listener/ServerlessSpyListener.mjs +1 -2
- package/lib/listener/ServerlessSpyListenerParams.d.mts +14 -0
- package/lib/listener/ServerlessSpyListenerParams.d.ts +13 -8
- package/lib/listener/ServerlessSpyListenerParams.js +0 -3
- package/lib/listener/ServerlessSpyListenerParams.mjs +1 -2
- package/lib/listener/SpyHandlers.ts.d.mts +158 -0
- package/lib/listener/SpyHandlers.ts.d.ts +144 -144
- package/lib/listener/SpyHandlers.ts.js +0 -3
- package/lib/listener/SpyHandlers.ts.mjs +1 -2
- package/lib/listener/WaitForParams.d.mts +10 -0
- package/lib/listener/WaitForParams.d.ts +9 -4
- package/lib/listener/WaitForParams.js +0 -3
- package/lib/listener/WaitForParams.mjs +1 -2
- package/lib/listener/WsListener.d.mts +27 -0
- package/lib/listener/WsListener.d.ts +26 -21
- package/lib/listener/WsListener.js +173 -231
- package/lib/listener/WsListener.js.map +1 -0
- package/lib/listener/WsListener.mjs +174 -228
- package/lib/listener/WsListener.mjs.map +1 -0
- package/lib/listener/createServerlessSpyListener.d.mts +8 -0
- package/lib/listener/createServerlessSpyListener.d.ts +8 -2
- package/lib/listener/createServerlessSpyListener.js +25 -25
- package/lib/listener/createServerlessSpyListener.js.map +1 -0
- package/lib/listener/createServerlessSpyListener.mjs +26 -23
- package/lib/listener/createServerlessSpyListener.mjs.map +1 -0
- package/lib/listener/index.d.mts +3 -0
- package/lib/listener/index.d.ts +3 -2
- package/lib/listener/index.js +3 -19
- package/lib/listener/index.mjs +3 -3
- package/lib/listener/iot-connection.d.mts +13 -0
- package/lib/listener/iot-connection.d.ts +12 -7
- package/lib/listener/iot-connection.js +48 -46
- package/lib/listener/iot-connection.js.map +1 -0
- package/lib/listener/iot-connection.mjs +46 -44
- package/lib/listener/iot-connection.mjs.map +1 -0
- package/lib/listener/matchers.d.mts +1 -0
- package/lib/listener/matchers.d.ts +1 -0
- package/lib/listener/matchers.js +0 -55
- package/lib/listener/matchers.mjs +1 -55
- package/lib/listener/setup.d.mts +1 -0
- package/lib/listener/setup.d.ts +1 -0
- package/lib/listener/setup.js +0 -21
- package/lib/listener/setup.mjs +1 -21
- package/lib/listener/topic.d.mts +6 -0
- package/lib/listener/topic.d.ts +6 -2
- package/lib/listener/topic.js +9 -7
- package/lib/listener/topic.js.map +1 -0
- package/lib/listener/topic.mjs +8 -4
- package/lib/listener/topic.mjs.map +1 -0
- package/lib/node_modules/tsdown/esm-shims.mjs +11 -0
- package/lib/node_modules/tsdown/esm-shims.mjs.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/native.js +10 -0
- package/lib/node_modules/uuid/dist/esm-node/native.js.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/native.mjs +8 -0
- package/lib/node_modules/uuid/dist/esm-node/native.mjs.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/rng.js +18 -0
- package/lib/node_modules/uuid/dist/esm-node/rng.js.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/rng.mjs +16 -0
- package/lib/node_modules/uuid/dist/esm-node/rng.mjs.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/stringify.js +15 -0
- package/lib/node_modules/uuid/dist/esm-node/stringify.js.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/stringify.mjs +14 -0
- package/lib/node_modules/uuid/dist/esm-node/stringify.mjs.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/v4.js +23 -0
- package/lib/node_modules/uuid/dist/esm-node/v4.js.map +1 -0
- package/lib/node_modules/uuid/dist/esm-node/v4.mjs +23 -0
- package/lib/node_modules/uuid/dist/esm-node/v4.mjs.map +1 -0
- package/lib/src/ServerlessSpy.d.mts +77 -0
- package/lib/src/ServerlessSpy.js +1 -1
- package/lib/src/ServerlessSpy.js.map +1 -0
- package/lib/src/ServerlessSpy.mjs +441 -618
- package/lib/src/ServerlessSpy.mjs.map +1 -0
- package/lib/src/common/envVariableNames.d.mts +35 -0
- package/lib/src/common/envVariableNames.js.map +1 -0
- package/lib/src/common/envVariableNames.mjs +43 -35
- package/lib/src/common/envVariableNames.mjs.map +1 -0
- package/lib/src/index.d.mts +2 -0
- package/lib/src/index.mjs +3 -2
- package/node_modules/debug/package.json +2 -3
- package/node_modules/debug/src/browser.js +1 -1
- package/node_modules/debug/src/common.js +1 -1
- package/package.json +3 -1
- package/tsdown.config.ts +16 -0
- package/node_modules/micromist/yarn.lock +0 -75
- package/node_modules/tmp/lib/tmp.js.orig +0 -471
package/lib/cli/cli.mjs
CHANGED
|
@@ -1,215 +1,154 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
2
|
+
import { __dirname } from "../node_modules/tsdown/esm-shims.mjs";
|
|
3
|
+
import { getConnection } from "../listener/iot-connection.mjs";
|
|
4
|
+
import { getTopic } from "../listener/topic.mjs";
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import * as http from "http";
|
|
8
|
+
import { promisify } from "util";
|
|
9
|
+
import * as progam from "caporal";
|
|
10
|
+
import * as open from "open";
|
|
11
|
+
import { WebSocketServer } from "ws";
|
|
12
|
+
|
|
13
|
+
//#region cli/cli.ts
|
|
12
14
|
const readFileAsync = promisify(fs.readFile);
|
|
13
|
-
//resolve issue with module import
|
|
14
15
|
let opener = open;
|
|
15
|
-
if (open.default)
|
|
16
|
-
opener = open.default;
|
|
17
|
-
}
|
|
16
|
+
if (open.default) opener = open.default;
|
|
18
17
|
async function run() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (request.url === '/stackList') {
|
|
135
|
-
response.writeHead(200, { 'Content-Type': 'application/json' });
|
|
136
|
-
response.end(JSON.stringify(stackList), 'utf-8');
|
|
137
|
-
}
|
|
138
|
-
else if (request.url === '/stackTopicMappings') {
|
|
139
|
-
response.writeHead(200, { 'Content-Type': 'application/json' });
|
|
140
|
-
const mappings = {};
|
|
141
|
-
if (cdkOutput) {
|
|
142
|
-
for (const [stackName, stack] of Object.entries(cdkOutput)) {
|
|
143
|
-
if (stack.ServerlessSpyWsUrl) {
|
|
144
|
-
const [_, scope] = stack.ServerlessSpyWsUrl.split('/');
|
|
145
|
-
if (scope) {
|
|
146
|
-
mappings[stackName] = scope;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
response.end(JSON.stringify(mappings), 'utf-8');
|
|
152
|
-
}
|
|
153
|
-
else if (request.url?.match('^/wsUrl')) {
|
|
154
|
-
response.writeHead(200, { 'Content-Type': 'text/html' });
|
|
155
|
-
response.end(`ws:localhost:${options.wsport}`, 'utf-8');
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
try {
|
|
159
|
-
const content = await readFileAsync(filePath);
|
|
160
|
-
response.writeHead(200, { 'Content-Type': contentType });
|
|
161
|
-
response.end(content, 'utf-8');
|
|
162
|
-
}
|
|
163
|
-
catch (error) {
|
|
164
|
-
if (error.code === 'ENOENT') {
|
|
165
|
-
response.writeHead(404, { 'Content-Type': 'text/html' });
|
|
166
|
-
response.end(`No such file or directory ${request.url}`, 'utf-8');
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
response.writeHead(500);
|
|
170
|
-
response.end(`Error: ${error.code} ..\n`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
catch (err) {
|
|
176
|
-
response.writeHead(500, { 'Content-Type': 'text/html' });
|
|
177
|
-
response.end(err.message, 'utf-8');
|
|
178
|
-
}
|
|
179
|
-
})();
|
|
180
|
-
})
|
|
181
|
-
.listen(options.port);
|
|
182
|
-
console.log(`ServerlessSpy console runing at http://localhost:${options.port}`);
|
|
183
|
-
if (options.open) {
|
|
184
|
-
await opener(`http://localhost:${options.port}`);
|
|
185
|
-
}
|
|
18
|
+
let stackList;
|
|
19
|
+
let cdkOutput;
|
|
20
|
+
let options;
|
|
21
|
+
progam.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", progam.BOOL, true).option("--port <p>", `A port on localhost where ServerlessSpy web console is accessible.`, progam.INT, "3456").option("--wsport <wsp>", `A port on localhost where ServerlessSpy websocket is accessible.`, progam.INT, "3457").action((_args, opt, _logger) => {
|
|
22
|
+
options = opt;
|
|
23
|
+
});
|
|
24
|
+
progam.parse(process.argv);
|
|
25
|
+
if (!options.ws && !options.cdkoutput) throw new Error("--ws or --cdkoutput parameter not specified");
|
|
26
|
+
if (options.cdkoutput) {
|
|
27
|
+
const rawdata = fs.readFileSync(options.cdkoutput);
|
|
28
|
+
cdkOutput = JSON.parse(rawdata.toString());
|
|
29
|
+
stackList = Object.keys(cdkOutput);
|
|
30
|
+
}
|
|
31
|
+
const wss = new WebSocketServer({ port: options.wsport });
|
|
32
|
+
let connection = void 0;
|
|
33
|
+
wss.on("close", async () => {
|
|
34
|
+
if (connection) connection.end(true);
|
|
35
|
+
});
|
|
36
|
+
wss.on("connection", async function connect(ws) {
|
|
37
|
+
console.log("Connection");
|
|
38
|
+
ws.on("message", function message(data) {
|
|
39
|
+
console.log("received: %s", data);
|
|
40
|
+
});
|
|
41
|
+
let wsUrl;
|
|
42
|
+
if (options.ws) wsUrl = options.ws;
|
|
43
|
+
else if (cdkOutput) {
|
|
44
|
+
if (cdkOutput[options.cdkstack]) wsUrl = cdkOutput[options.cdkstack].ServerlessSpyWsUrl;
|
|
45
|
+
else if (cdkOutput[Object.keys(cdkOutput)[0]]) wsUrl = cdkOutput[Object.keys(cdkOutput)[0]].ServerlessSpyWsUrl;
|
|
46
|
+
}
|
|
47
|
+
if (!wsUrl) throw new Error("Missing IoT endpoint url");
|
|
48
|
+
const wsUrlWithoutScope = wsUrl.split("/")[0];
|
|
49
|
+
connection = await getConnection(true, wsUrlWithoutScope);
|
|
50
|
+
const topic = getTopic("#");
|
|
51
|
+
console.log(`Subscribing to ${topic}`);
|
|
52
|
+
connection.on("connect", () => {
|
|
53
|
+
console.log("Connection opened");
|
|
54
|
+
if (connection) connection.subscribe(topic);
|
|
55
|
+
});
|
|
56
|
+
connection.on("message", (topic$1, data) => {
|
|
57
|
+
ws.send(JSON.stringify({
|
|
58
|
+
...JSON.parse(JSON.parse(data.toString()).data),
|
|
59
|
+
topic: topic$1
|
|
60
|
+
}));
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
http.createServer((request, response) => {
|
|
64
|
+
(async () => {
|
|
65
|
+
try {
|
|
66
|
+
let filePath = `.${request.url}`;
|
|
67
|
+
filePath = filePath.split("?")[0];
|
|
68
|
+
let rootFolder = __dirname;
|
|
69
|
+
if (request.url?.startsWith("/webServerlessSpy.js")) rootFolder = getCompiledJsPath();
|
|
70
|
+
else if (request.url?.startsWith("/bootstrap/")) {
|
|
71
|
+
filePath = filePath.substring(11);
|
|
72
|
+
rootFolder = await getNpmModuleInstalledPath("bootstrap");
|
|
73
|
+
} else if (request.url?.startsWith("/bootstrap-icons/")) {
|
|
74
|
+
filePath = filePath.substring(17);
|
|
75
|
+
rootFolder = await getNpmModuleInstalledPath("bootstrap-icons");
|
|
76
|
+
} else if (filePath === "./") filePath = "./index.html";
|
|
77
|
+
filePath = path.join(rootFolder, filePath);
|
|
78
|
+
const extname = String(path.extname(filePath)).toLowerCase();
|
|
79
|
+
const contentType = {
|
|
80
|
+
".html": "text/html",
|
|
81
|
+
".js": "text/javascript",
|
|
82
|
+
".css": "text/css",
|
|
83
|
+
".json": "application/json",
|
|
84
|
+
".png": "image/png",
|
|
85
|
+
".jpg": "image/jpg",
|
|
86
|
+
".gif": "image/gif",
|
|
87
|
+
".svg": "image/svg+xml",
|
|
88
|
+
".wav": "audio/wav",
|
|
89
|
+
".mp4": "video/mp4",
|
|
90
|
+
".woff": "application/font-woff",
|
|
91
|
+
".ttf": "application/font-ttf",
|
|
92
|
+
".eot": "application/vnd.ms-fontobject",
|
|
93
|
+
".otf": "application/font-otf",
|
|
94
|
+
".wasm": "application/wasm"
|
|
95
|
+
}[extname] || "application/octet-stream";
|
|
96
|
+
if (request.url === "/stackList") {
|
|
97
|
+
response.writeHead(200, { "Content-Type": "application/json" });
|
|
98
|
+
response.end(JSON.stringify(stackList), "utf-8");
|
|
99
|
+
} else if (request.url === "/stackTopicMappings") {
|
|
100
|
+
response.writeHead(200, { "Content-Type": "application/json" });
|
|
101
|
+
const mappings = {};
|
|
102
|
+
if (cdkOutput) {
|
|
103
|
+
for (const [stackName, stack] of Object.entries(cdkOutput)) if (stack.ServerlessSpyWsUrl) {
|
|
104
|
+
const [_, scope] = stack.ServerlessSpyWsUrl.split("/");
|
|
105
|
+
if (scope) mappings[stackName] = scope;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
response.end(JSON.stringify(mappings), "utf-8");
|
|
109
|
+
} else if (request.url?.match("^/wsUrl")) {
|
|
110
|
+
response.writeHead(200, { "Content-Type": "text/html" });
|
|
111
|
+
response.end(`ws:localhost:${options.wsport}`, "utf-8");
|
|
112
|
+
} else try {
|
|
113
|
+
const content = await readFileAsync(filePath);
|
|
114
|
+
response.writeHead(200, { "Content-Type": contentType });
|
|
115
|
+
response.end(content, "utf-8");
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error.code === "ENOENT") {
|
|
118
|
+
response.writeHead(404, { "Content-Type": "text/html" });
|
|
119
|
+
response.end(`No such file or directory ${request.url}`, "utf-8");
|
|
120
|
+
} else {
|
|
121
|
+
response.writeHead(500);
|
|
122
|
+
response.end(`Error: ${error.code} ..\n`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
response.writeHead(500, { "Content-Type": "text/html" });
|
|
127
|
+
response.end(err.message, "utf-8");
|
|
128
|
+
}
|
|
129
|
+
})();
|
|
130
|
+
}).listen(options.port);
|
|
131
|
+
console.log(`ServerlessSpy console runing at http://localhost:${options.port}`);
|
|
132
|
+
if (options.open) await opener(`http://localhost:${options.port}`);
|
|
186
133
|
}
|
|
187
134
|
run().catch(console.error);
|
|
188
135
|
function getNpmModuleInstalledPath(npm) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
// When boostrap ends up in importing projects root node_modules and not in serverless-spys node_modules
|
|
198
|
-
folderAsPackage = path.join(__dirname, '../../../../', 'node_modules', npm);
|
|
199
|
-
if (fs.existsSync(folderAsPackage)) {
|
|
200
|
-
return folderAsPackage;
|
|
201
|
-
}
|
|
202
|
-
throw new Error(`Can not find package in folder ${folder} and ${folderAsPackage}`);
|
|
136
|
+
let folder = path.join(__dirname, "../", "node_modules", npm);
|
|
137
|
+
if (fs.existsSync(folder)) return folder;
|
|
138
|
+
let folderAsPackage = path.join(__dirname, "../../", "node_modules", npm);
|
|
139
|
+
if (fs.existsSync(folderAsPackage)) return folderAsPackage;
|
|
140
|
+
folderAsPackage = path.join(__dirname, "../../../../", "node_modules", npm);
|
|
141
|
+
if (fs.existsSync(folderAsPackage)) return folderAsPackage;
|
|
142
|
+
throw new Error(`Can not find package in folder ${folder} and ${folderAsPackage}`);
|
|
203
143
|
}
|
|
204
144
|
function getCompiledJsPath() {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (fs.existsSync(folderAsPackage)) {
|
|
211
|
-
return folderAsPackage;
|
|
212
|
-
}
|
|
213
|
-
throw new Error(`Can not find compiled files in folder ${folder} and ${folderAsPackage}`);
|
|
145
|
+
let folder = path.join(__dirname, "../", "lib/cli");
|
|
146
|
+
if (fs.existsSync(folder)) return folder;
|
|
147
|
+
let folderAsPackage = path.join(__dirname, "../../", "lib/cli");
|
|
148
|
+
if (fs.existsSync(folderAsPackage)) return folderAsPackage;
|
|
149
|
+
throw new Error(`Can not find compiled files in folder ${folder} and ${folderAsPackage}`);
|
|
214
150
|
}
|
|
215
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY2xpL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVqQyxPQUFPLEtBQUssTUFBTSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3JDLGFBQWE7QUFDYixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTdDLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7QUFFN0Msa0NBQWtDO0FBQ2xDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQztBQUNsQixJQUFLLElBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMxQixNQUFNLEdBQUksSUFBWSxDQUFDLE9BQU8sQ0FBQztBQUNqQyxDQUFDO0FBRUQsS0FBSyxVQUFVLEdBQUc7SUFDaEIsSUFBSSxTQUErQixDQUFDO0lBQ3BDLElBQUksU0FBaUQsQ0FBQztJQUV0RCxJQUFJLE9BQVksQ0FBQztJQUVqQixNQUFNO1NBQ0gsV0FBVyxDQUFDLDJCQUEyQixDQUFDO1NBQ3hDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUM7U0FDckMsTUFBTSxDQUNMLHlCQUF5QixFQUN6QixrRkFBa0YsQ0FDbkY7U0FDQSxNQUFNLENBQ0wsdUJBQXVCLEVBQ3ZCLHlFQUF5RSxDQUMxRTtTQUNBLE1BQU0sQ0FBQyxl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QUcsQ0FBQyxDQUFDO0lBRTFFLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1FBQ25DLE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFFRCx3R0FBd0c7SUFDeEcsZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFFNUUsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDbkMsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQ2Isa0NBQWtDLE1BQU0sUUFBUSxlQUFlLEVBQUUsQ0FDbEUsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGlCQUFpQjtJQUN4QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDcEQsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDMUIsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUVoRSxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxPQUFPLGVBQWUsQ0FBQztJQUN6QixDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYix5Q0FBeUMsTUFBTSxRQUFRLGVBQWUsRUFBRSxDQUN6RSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBkZXZpY2UgfSBmcm9tICdhd3MtaW90LWRldmljZS1zZGsnO1xuaW1wb3J0ICogYXMgcHJvZ2FtIGZyb20gJ2NhcG9yYWwnO1xuaW1wb3J0ICogYXMgb3BlbiBmcm9tICdvcGVuJztcbmltcG9ydCB7IFdlYlNvY2tldFNlcnZlciB9IGZyb20gJ3dzJztcbi8vIEB0cy1pZ25vcmVcbmltcG9ydCB7IGdldENvbm5lY3Rpb24gfSBmcm9tICcuLi9saXN0ZW5lci9pb3QtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBnZXRUb3BpYyB9IGZyb20gJy4uL2xpc3RlbmVyL3RvcGljJztcblxuY29uc3QgcmVhZEZpbGVBc3luYyA9IHByb21pc2lmeShmcy5yZWFkRmlsZSk7XG5cbi8vcmVzb2x2ZSBpc3N1ZSB3aXRoIG1vZHVsZSBpbXBvcnRcbmxldCBvcGVuZXIgPSBvcGVuO1xuaWYgKChvcGVuIGFzIGFueSkuZGVmYXVsdCkge1xuICBvcGVuZXIgPSAob3BlbiBhcyBhbnkpLmRlZmF1bHQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bigpIHtcbiAgbGV0IHN0YWNrTGlzdDogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIGxldCBjZGtPdXRwdXQ6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xuXG4gIGxldCBvcHRpb25zOiBhbnk7XG5cbiAgcHJvZ2FtXG4gICAgLmRlc2NyaXB0aW9uKCdTZXJ2ZXJsZXNzU3B5IHdlYiBjb25zb2xlJylcbiAgICAub3B0aW9uKCctLXdzIDx3cz4nLCAnV2Vic29ja2V0IGxpbmsnKVxuICAgIC5vcHRpb24oXG4gICAgICAnLS1jZGtvdXRwdXQgPGNka291dHB1dD4nLFxuICAgICAgJ0NESyBvdXRwdXQgZmlsZSB0aGF0IGNvbnRhaW5zIElvVCBFbmRwb2ludCBsaW5rIGluIGEgcHJvcGVydHkgU2VydmVybGVzc1NweVdzVXJsJ1xuICAgIClcbiAgICAub3B0aW9uKFxuICAgICAgJy0tY2Rrc3RhY2sgPGNka3N0YWNrPicsXG4gICAgICAnQ0RLIHN0YWNrIGluIGNkayBvdXRwdXQgZmlsZS4gSWYgbm90IHNwZWNpZmllZCB0aGUgZmlyc3Qgb25lIGlzIHBpY2tlZC4nXG4gICAgKVxuICAgIC5vcHRpb24oJy0tb3BlbiA8b3Blbj4nLCAnT3BlbiBicm93c2VyJywgcHJvZ2FtLkJPT0wsIHRydWUpXG4gICAgLm9wdGlvbihcbiAgICAgICctLXBvcnQgPHA+JyxcbiAgICAgIGBBIHBvcnQgb24gbG9jYWxob3N0IHdoZXJlIFNlcnZlcmxlc3NTcHkgd2ViIGNvbnNvbGUgaXMgYWNjZXNzaWJsZS5gLFxuICAgICAgcHJvZ2FtLklOVCxcbiAgICAgICczNDU2J1xuICAgIClcbiAgICAub3B0aW9uKFxuICAgICAgJy0td3Nwb3J0IDx3c3A+JyxcbiAgICAgIGBBIHBvcnQgb24gbG9jYWxob3N0IHdoZXJlIFNlcnZlcmxlc3NTcHkgd2Vic29ja2V0IGlzIGFjY2Vzc2libGUuYCxcbiAgICAgIHByb2dhbS5JTlQsXG4gICAgICAnMzQ1NydcbiAgICApXG4gICAgLmFjdGlvbigoX2FyZ3MsIG9wdCwgX2xvZ2dlcikgPT4ge1xuICAgICAgb3B0aW9ucyA9IG9wdDtcbiAgICB9KTtcblxuICBwcm9nYW0ucGFyc2UocHJvY2Vzcy5hcmd2KTtcblxuICBpZiAoIW9wdGlvbnMud3MgJiYgIW9wdGlvbnMuY2Rrb3V0cHV0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCctLXdzIG9yIC0tY2Rrb3V0cHV0IHBhcmFtZXRlciBub3Qgc3BlY2lmaWVkJyk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5jZGtvdXRwdXQpIHtcbiAgICBjb25zdCByYXdkYXRhID0gZnMucmVhZEZpbGVTeW5jKG9wdGlvbnMuY2Rrb3V0cHV0KTtcbiAgICBjZGtPdXRwdXQgPSBKU09OLnBhcnNlKHJhd2RhdGEudG9TdHJpbmcoKSk7XG4gICAgc3RhY2tMaXN0ID0gT2JqZWN0LmtleXMoY2RrT3V0cHV0KTtcbiAgfVxuXG4gIGNvbnN0IHdzcyA9IG5ldyBXZWJTb2NrZXRTZXJ2ZXIoeyBwb3J0OiBvcHRpb25zLndzcG9ydCB9KTtcbiAgbGV0IGNvbm5lY3Rpb246IGRldmljZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICB3c3Mub24oJ2Nsb3NlJywgYXN5bmMgKCkgPT4ge1xuICAgIGlmIChjb25uZWN0aW9uKSBjb25uZWN0aW9uLmVuZCh0cnVlKTtcbiAgfSk7XG5cbiAgd3NzLm9uKCdjb25uZWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gY29ubmVjdCh3cykge1xuICAgIGNvbnNvbGUubG9nKCdDb25uZWN0aW9uJyk7XG4gICAgd3Mub24oJ21lc3NhZ2UnLCBmdW5jdGlvbiBtZXNzYWdlKGRhdGEpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdyZWNlaXZlZDogJXMnLCBkYXRhKTtcbiAgICB9KTtcblxuICAgIGxldCB3c1VybDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmIChvcHRpb25zLndzKSB7XG4gICAgICB3c1VybCA9IG9wdGlvbnMud3M7XG4gICAgfSBlbHNlIGlmIChjZGtPdXRwdXQpIHtcbiAgICAgIGlmIChjZGtPdXRwdXRbb3B0aW9ucy5jZGtzdGFja10pIHtcbiAgICAgICAgd3NVcmwgPSBjZGtPdXRwdXRbb3B0aW9ucy5jZGtzdGFja10uU2VydmVybGVzc1NweVdzVXJsO1xuICAgICAgfSBlbHNlIGlmIChjZGtPdXRwdXRbT2JqZWN0LmtleXMoY2RrT3V0cHV0KVswXV0pIHtcbiAgICAgICAgd3NVcmwgPSBjZGtPdXRwdXRbT2JqZWN0LmtleXMoY2RrT3V0cHV0KVswXV0uU2VydmVybGVzc1NweVdzVXJsO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghd3NVcmwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBJb1QgZW5kcG9pbnQgdXJsJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgd3NVcmxXaXRob3V0U2NvcGUgPSB3c1VybC5zcGxpdCgnLycpWzBdO1xuXG4gICAgY29ubmVjdGlvbiA9IGF3YWl0IGdldENvbm5lY3Rpb24odHJ1ZSwgd3NVcmxXaXRob3V0U2NvcGUpO1xuXG4gICAgY29uc3QgdG9waWMgPSBnZXRUb3BpYygnIycpO1xuICAgIGNvbnNvbGUubG9nKGBTdWJzY3JpYmluZyB0byAke3RvcGljfWApO1xuXG4gICAgY29ubmVjdGlvbi5vbignY29ubmVjdCcsICgpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKCdDb25uZWN0aW9uIG9wZW5lZCcpO1xuICAgICAgaWYgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgY29ubmVjdGlvbi5zdWJzY3JpYmUodG9waWMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29ubmVjdGlvbi5vbignbWVzc2FnZScsICh0b3BpYzogc3RyaW5nLCBkYXRhOiBCdWZmZXIpID0+IHtcbiAgICAgIHdzLnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAuLi5KU09OLnBhcnNlKEpTT04ucGFyc2UoZGF0YS50b1N0cmluZygpKS5kYXRhKSxcbiAgICAgICAgICB0b3BpYyxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGh0dHBcbiAgICAuY3JlYXRlU2VydmVyKChyZXF1ZXN0LCByZXNwb25zZSkgPT4ge1xuICAgICAgdm9pZCAoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vY29uc29sZS5sb2coJ3JlcXVlc3QgJywgcmVxdWVzdC51cmwpO1xuICAgICAgICAgIGxldCBmaWxlUGF0aDogc3RyaW5nID0gYC4ke3JlcXVlc3QudXJsfWA7XG4gICAgICAgICAgLy9yZW1vdmUgcXVlcnkgcGFyYW1ldGVyc1xuICAgICAgICAgIGZpbGVQYXRoID0gZmlsZVBhdGguc3BsaXQoJz8nKVswXTtcbiAgICAgICAgICBsZXQgcm9vdEZvbGRlciA9IF9fZGlybmFtZTtcblxuICAgICAgICAgIGlmIChyZXF1ZXN0LnVybD8uc3RhcnRzV2l0aCgnL3dlYlNlcnZlcmxlc3NTcHkuanMnKSkge1xuICAgICAgICAgICAgLy9nZXQgdHJhbnNwaWxlZCBUUyB0byBKUyBmaWxlc1xuICAgICAgICAgICAgcm9vdEZvbGRlciA9IGdldENvbXBpbGVkSnNQYXRoKCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnVybD8uc3RhcnRzV2l0aCgnL2Jvb3RzdHJhcC8nKSkge1xuICAgICAgICAgICAgZmlsZVBhdGggPSBmaWxlUGF0aC5zdWJzdHJpbmcoJy9ib290c3RyYXAvJy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgYm9vdHN0cmFwRm9sZGVyID0gYXdhaXQgZ2V0TnBtTW9kdWxlSW5zdGFsbGVkUGF0aChcbiAgICAgICAgICAgICAgJ2Jvb3RzdHJhcCdcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJvb3RGb2xkZXIgPSBib290c3RyYXBGb2xkZXI7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnVybD8uc3RhcnRzV2l0aCgnL2Jvb3RzdHJhcC1pY29ucy8nKSkge1xuICAgICAgICAgICAgZmlsZVBhdGggPSBmaWxlUGF0aC5zdWJzdHJpbmcoJy9ib290c3RyYXAtaWNvbnMvJy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgYm9vdHN0cmFwRm9sZGVyID0gYXdhaXQgZ2V0TnBtTW9kdWxlSW5zdGFsbGVkUGF0aChcbiAgICAgICAgICAgICAgJ2Jvb3RzdHJhcC1pY29ucydcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJvb3RGb2xkZXIgPSBib290c3RyYXBGb2xkZXI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmaWxlUGF0aCA9PT0gJy4vJykge1xuICAgICAgICAgICAgICBmaWxlUGF0aCA9ICcuL2luZGV4Lmh0bWwnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZpbGVQYXRoID0gcGF0aC5qb2luKHJvb3RGb2xkZXIsIGZpbGVQYXRoKTtcbiAgICAgICAgICAvL2NvbnNvbGUubG9nKGAke3JlcXVlc3QudXJsfSAtLT4gJHtmaWxlUGF0aH1gKTtcblxuICAgICAgICAgIGNvbnN0IGV4dG5hbWUgPSBTdHJpbmcocGF0aC5leHRuYW1lKGZpbGVQYXRoKSkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICBjb25zdCBtaW1lVHlwZXM6IGFueSA9IHtcbiAgICAgICAgICAgICcuaHRtbCc6ICd0ZXh0L2h0bWwnLFxuICAgICAgICAgICAgJy5qcyc6ICd0ZXh0L2phdmFzY3JpcHQnLFxuICAgICAgICAgICAgJy5jc3MnOiAndGV4dC9jc3MnLFxuICAgICAgICAgICAgJy5qc29uJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgJy5wbmcnOiAnaW1hZ2UvcG5nJyxcbiAgICAgICAgICAgICcuanBnJzogJ2ltYWdlL2pwZycsXG4gICAgICAgICAgICAnLmdpZic6ICdpbWFnZS9naWYnLFxuICAgICAgICAgICAgJy5zdmcnOiAnaW1hZ2Uvc3ZnK3htbCcsXG4gICAgICAgICAgICAnLndhdic6ICdhdWRpby93YXYnLFxuICAgICAgICAgICAgJy5tcDQnOiAndmlkZW8vbXA0JyxcbiAgICAgICAgICAgICcud29mZic6ICdhcHBsaWNhdGlvbi9mb250LXdvZmYnLFxuICAgICAgICAgICAgJy50dGYnOiAnYXBwbGljYXRpb24vZm9udC10dGYnLFxuICAgICAgICAgICAgJy5lb3QnOiAnYXBwbGljYXRpb24vdm5kLm1zLWZvbnRvYmplY3QnLFxuICAgICAgICAgICAgJy5vdGYnOiAnYXBwbGljYXRpb24vZm9udC1vdGYnLFxuICAgICAgICAgICAgJy53YXNtJzogJ2FwcGxpY2F0aW9uL3dhc20nLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCBjb250ZW50VHlwZSA9IG1pbWVUeXBlc1tleHRuYW1lXSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcblxuICAgICAgICAgIGlmIChyZXF1ZXN0LnVybCA9PT0gJy9zdGFja0xpc3QnKSB7XG4gICAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICByZXNwb25zZS5lbmQoSlNPTi5zdHJpbmdpZnkoc3RhY2tMaXN0KSwgJ3V0Zi04Jyk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LnVybCA9PT0gJy9zdGFja1RvcGljTWFwcGluZ3MnKSB7XG4gICAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICBjb25zdCBtYXBwaW5nczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgICAgICAgICAgaWYgKGNka091dHB1dCkge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtzdGFja05hbWUsIHN0YWNrXSBvZiBPYmplY3QuZW50cmllcyhjZGtPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YWNrLlNlcnZlcmxlc3NTcHlXc1VybCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgW18sIHNjb3BlXSA9IHN0YWNrLlNlcnZlcmxlc3NTcHlXc1VybC5zcGxpdCgnLycpO1xuICAgICAgICAgICAgICAgICAgaWYgKHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcHBpbmdzW3N0YWNrTmFtZV0gPSBzY29wZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3BvbnNlLmVuZChKU09OLnN0cmluZ2lmeShtYXBwaW5ncyksICd1dGYtOCcpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdC51cmw/Lm1hdGNoKCdeL3dzVXJsJykpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCgyMDAsIHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L2h0bWwnIH0pO1xuICAgICAgICAgICAgcmVzcG9uc2UuZW5kKGB3czpsb2NhbGhvc3Q6JHtvcHRpb25zLndzcG9ydH1gLCAndXRmLTgnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlQXN5bmMoZmlsZVBhdGgpO1xuXG4gICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCgyMDAsIHsgJ0NvbnRlbnQtVHlwZSc6IGNvbnRlbnRUeXBlIH0pO1xuICAgICAgICAgICAgICByZXNwb25zZS5lbmQoY29udGVudCwgJ3V0Zi04Jyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCg0MDQsIHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L2h0bWwnIH0pO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmVuZChcbiAgICAgICAgICAgICAgICAgIGBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5ICR7cmVxdWVzdC51cmx9YCxcbiAgICAgICAgICAgICAgICAgICd1dGYtOCdcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCg1MDApO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmVuZChgRXJyb3I6ICR7ZXJyb3IuY29kZX0gLi5cXG5gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoNTAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9odG1sJyB9KTtcbiAgICAgICAgICByZXNwb25zZS5lbmQoZXJyLm1lc3NhZ2UsICd1dGYtOCcpO1xuICAgICAgICB9XG4gICAgICB9KSgpO1xuICAgIH0pXG4gICAgLmxpc3RlbihvcHRpb25zLnBvcnQpO1xuXG4gIGNvbnNvbGUubG9nKFxuICAgIGBTZXJ2ZXJsZXNzU3B5IGNvbnNvbGUgcnVuaW5nIGF0IGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRpb25zLnBvcnR9YFxuICApO1xuICBpZiAob3B0aW9ucy5vcGVuKSB7XG4gICAgYXdhaXQgb3BlbmVyKGBodHRwOi8vbG9jYWxob3N0OiR7b3B0aW9ucy5wb3J0fWApO1xuICB9XG59XG5cbnJ1bigpLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuXG5mdW5jdGlvbiBnZXROcG1Nb2R1bGVJbnN0YWxsZWRQYXRoKG5wbTogc3RyaW5nKSB7XG4gIGxldCBmb2xkZXIgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vJywgJ25vZGVfbW9kdWxlcycsIG5wbSk7XG4gIGlmIChmcy5leGlzdHNTeW5jKGZvbGRlcikpIHtcbiAgICByZXR1cm4gZm9sZGVyO1xuICB9XG5cbiAgbGV0IGZvbGRlckFzUGFja2FnZSA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8uLi8nLCAnbm9kZV9tb2R1bGVzJywgbnBtKTtcblxuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXJBc1BhY2thZ2UpKSB7XG4gICAgcmV0dXJuIGZvbGRlckFzUGFja2FnZTtcbiAgfVxuXG4gIC8vIFdoZW4gYm9vc3RyYXAgZW5kcyB1cCBpbiBpbXBvcnRpbmcgcHJvamVjdHMgcm9vdCBub2RlX21vZHVsZXMgYW5kIG5vdCBpbiBzZXJ2ZXJsZXNzLXNweXMgbm9kZV9tb2R1bGVzXG4gIGZvbGRlckFzUGFja2FnZSA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8uLi8uLi8uLi8nLCAnbm9kZV9tb2R1bGVzJywgbnBtKTtcblxuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXJBc1BhY2thZ2UpKSB7XG4gICAgcmV0dXJuIGZvbGRlckFzUGFja2FnZTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgQ2FuIG5vdCBmaW5kIHBhY2thZ2UgaW4gZm9sZGVyICR7Zm9sZGVyfSBhbmQgJHtmb2xkZXJBc1BhY2thZ2V9YFxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRDb21waWxlZEpzUGF0aCgpIHtcbiAgbGV0IGZvbGRlciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8nLCAnbGliL2NsaScpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXIpKSB7XG4gICAgcmV0dXJuIGZvbGRlcjtcbiAgfVxuXG4gIGxldCBmb2xkZXJBc1BhY2thZ2UgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vJywgJ2xpYi9jbGknKTtcblxuICBpZiAoZnMuZXhpc3RzU3luYyhmb2xkZXJBc1BhY2thZ2UpKSB7XG4gICAgcmV0dXJuIGZvbGRlckFzUGFja2FnZTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgQ2FuIG5vdCBmaW5kIGNvbXBpbGVkIGZpbGVzIGluIGZvbGRlciAke2ZvbGRlcn0gYW5kICR7Zm9sZGVyQXNQYWNrYWdlfWBcbiAgKTtcbn1cbiJdfQ==
|
|
151
|
+
|
|
152
|
+
//#endregion
|
|
153
|
+
export { };
|
|
154
|
+
//# sourceMappingURL=cli.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["stackList: string[] | undefined","cdkOutput: Record<string, Record<string, string>>","options: any","connection: device | undefined","wsUrl: string | undefined","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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"}
|