roku-debug 0.20.6 → 0.20.7
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/CHANGELOG.md +6 -0
- package/dist/CompileErrorProcessor.d.ts +7 -2
- package/dist/CompileErrorProcessor.js +64 -69
- package/dist/CompileErrorProcessor.js.map +1 -1
- package/dist/DeviceInfo.d.ts +1 -0
- package/dist/adapters/DebugProtocolAdapter.d.ts +64 -17
- package/dist/adapters/DebugProtocolAdapter.js +264 -157
- package/dist/adapters/DebugProtocolAdapter.js.map +1 -1
- package/dist/adapters/TelnetAdapter.d.ts +8 -3
- package/dist/adapters/TelnetAdapter.js +14 -6
- package/dist/adapters/TelnetAdapter.js.map +1 -1
- package/dist/debugProtocol/Constants.d.ts +171 -81
- package/dist/debugProtocol/Constants.js +206 -126
- package/dist/debugProtocol/Constants.js.map +1 -1
- package/dist/debugProtocol/DebugProtocolClientReplaySession.d.ts +46 -0
- package/dist/debugProtocol/DebugProtocolClientReplaySession.js +278 -0
- package/dist/debugProtocol/DebugProtocolClientReplaySession.js.map +1 -0
- package/dist/debugProtocol/PluginInterface.d.ts +38 -0
- package/dist/debugProtocol/PluginInterface.js +86 -0
- package/dist/debugProtocol/PluginInterface.js.map +1 -0
- package/dist/debugProtocol/ProtocolUtil.d.ts +56 -0
- package/dist/debugProtocol/ProtocolUtil.js +164 -0
- package/dist/debugProtocol/ProtocolUtil.js.map +1 -0
- package/dist/debugProtocol/client/DebugProtocolClient.d.ts +310 -0
- package/dist/debugProtocol/client/DebugProtocolClient.js +1079 -0
- package/dist/debugProtocol/client/DebugProtocolClient.js.map +1 -0
- package/dist/debugProtocol/client/DebugProtocolClientPlugin.d.ts +44 -0
- package/dist/debugProtocol/client/DebugProtocolClientPlugin.js +3 -0
- package/dist/debugProtocol/client/DebugProtocolClientPlugin.js.map +1 -0
- package/dist/debugProtocol/events/ProtocolEvent.d.ts +66 -0
- package/dist/debugProtocol/events/ProtocolEvent.js +3 -0
- package/dist/debugProtocol/events/ProtocolEvent.js.map +1 -0
- package/dist/debugProtocol/events/requests/AddBreakpointsRequest.d.ts +30 -0
- package/dist/debugProtocol/events/requests/AddBreakpointsRequest.js +63 -0
- package/dist/debugProtocol/events/requests/AddBreakpointsRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/AddConditionalBreakpointsRequest.d.ts +48 -0
- package/dist/debugProtocol/events/requests/AddConditionalBreakpointsRequest.js +69 -0
- package/dist/debugProtocol/events/requests/AddConditionalBreakpointsRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/ContinueRequest.d.ts +20 -0
- package/dist/debugProtocol/events/requests/ContinueRequest.js +40 -0
- package/dist/debugProtocol/events/requests/ContinueRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/ExecuteRequest.d.ts +26 -0
- package/dist/debugProtocol/events/requests/ExecuteRequest.js +49 -0
- package/dist/debugProtocol/events/requests/ExecuteRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/ExitChannelRequest.d.ts +20 -0
- package/dist/debugProtocol/events/requests/ExitChannelRequest.js +40 -0
- package/dist/debugProtocol/events/requests/ExitChannelRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/HandshakeRequest.d.ts +26 -0
- package/dist/debugProtocol/events/requests/HandshakeRequest.js +47 -0
- package/dist/debugProtocol/events/requests/HandshakeRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/ListBreakpointsRequest.d.ts +20 -0
- package/dist/debugProtocol/events/requests/ListBreakpointsRequest.js +40 -0
- package/dist/debugProtocol/events/requests/ListBreakpointsRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/RemoveBreakpointsRequest.d.ts +29 -0
- package/dist/debugProtocol/events/requests/RemoveBreakpointsRequest.js +60 -0
- package/dist/debugProtocol/events/requests/RemoveBreakpointsRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/StackTraceRequest.d.ts +22 -0
- package/dist/debugProtocol/events/requests/StackTraceRequest.js +43 -0
- package/dist/debugProtocol/events/requests/StackTraceRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/StepRequest.d.ts +25 -0
- package/dist/debugProtocol/events/requests/StepRequest.js +46 -0
- package/dist/debugProtocol/events/requests/StepRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/StopRequest.d.ts +20 -0
- package/dist/debugProtocol/events/requests/StopRequest.js +39 -0
- package/dist/debugProtocol/events/requests/StopRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/ThreadsRequest.d.ts +20 -0
- package/dist/debugProtocol/events/requests/ThreadsRequest.js +40 -0
- package/dist/debugProtocol/events/requests/ThreadsRequest.js.map +1 -0
- package/dist/debugProtocol/events/requests/VariablesRequest.d.ts +59 -0
- package/dist/debugProtocol/events/requests/VariablesRequest.js +123 -0
- package/dist/debugProtocol/events/requests/VariablesRequest.js.map +1 -0
- package/dist/debugProtocol/events/responses/AddBreakpointsResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/AddConditionalBreakpointsResponse.d.ts +3 -0
- package/dist/debugProtocol/events/responses/AddConditionalBreakpointsResponse.js +9 -0
- package/dist/debugProtocol/events/responses/AddConditionalBreakpointsResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/ExecuteV3Response.d.ts +42 -0
- package/dist/debugProtocol/events/responses/ExecuteV3Response.js +94 -0
- package/dist/debugProtocol/events/responses/ExecuteV3Response.js.map +1 -0
- package/dist/debugProtocol/events/responses/GenericResponse.d.ts +17 -0
- package/dist/debugProtocol/events/responses/GenericResponse.js +40 -0
- package/dist/debugProtocol/events/responses/GenericResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/GenericV3Response.d.ts +15 -0
- package/dist/debugProtocol/events/responses/GenericV3Response.js +38 -0
- package/dist/debugProtocol/events/responses/GenericV3Response.js.map +1 -0
- package/dist/debugProtocol/events/responses/HandshakeResponse.d.ts +28 -0
- package/dist/debugProtocol/events/responses/HandshakeResponse.js +69 -0
- package/dist/debugProtocol/events/responses/HandshakeResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/HandshakeV3Response.d.ts +42 -0
- package/dist/debugProtocol/events/responses/HandshakeV3Response.js +98 -0
- package/dist/debugProtocol/events/responses/HandshakeV3Response.js.map +1 -0
- package/dist/debugProtocol/events/responses/ListBreakpointsResponse.d.ts +35 -0
- package/dist/debugProtocol/events/responses/ListBreakpointsResponse.js +68 -0
- package/dist/debugProtocol/events/responses/ListBreakpointsResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/RemoveBreakpointsResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/StackTraceResponse.d.ts +24 -0
- package/dist/debugProtocol/events/responses/StackTraceResponse.js +72 -0
- package/dist/debugProtocol/events/responses/StackTraceResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/StackTraceV3Response.d.ts +37 -0
- package/dist/debugProtocol/events/responses/StackTraceV3Response.js +67 -0
- package/dist/debugProtocol/events/responses/StackTraceV3Response.js.map +1 -0
- package/dist/debugProtocol/events/responses/ThreadsResponse.d.ts +54 -0
- package/dist/debugProtocol/events/responses/ThreadsResponse.js +80 -0
- package/dist/debugProtocol/events/responses/ThreadsResponse.js.map +1 -0
- package/dist/debugProtocol/events/responses/VariablesResponse.d.ts +117 -0
- package/dist/debugProtocol/events/responses/VariablesResponse.js +335 -0
- package/dist/debugProtocol/events/responses/VariablesResponse.js.map +1 -0
- package/dist/debugProtocol/events/updates/AllThreadsStoppedUpdate.d.ts +35 -0
- package/dist/debugProtocol/events/updates/AllThreadsStoppedUpdate.js +58 -0
- package/dist/debugProtocol/events/updates/AllThreadsStoppedUpdate.js.map +1 -0
- package/dist/debugProtocol/events/updates/BreakpointErrorUpdate.d.ts +42 -0
- package/dist/debugProtocol/events/updates/BreakpointErrorUpdate.js +97 -0
- package/dist/debugProtocol/events/updates/BreakpointErrorUpdate.js.map +1 -0
- package/dist/debugProtocol/events/updates/BreakpointVerifiedUpdate.d.ts +41 -0
- package/dist/debugProtocol/events/updates/BreakpointVerifiedUpdate.js +74 -0
- package/dist/debugProtocol/events/updates/BreakpointVerifiedUpdate.js.map +1 -0
- package/dist/debugProtocol/events/updates/CompileErrorUpdate.d.ts +60 -0
- package/dist/debugProtocol/events/updates/CompileErrorUpdate.js +89 -0
- package/dist/debugProtocol/events/updates/CompileErrorUpdate.js.map +1 -0
- package/dist/debugProtocol/events/updates/IOPortOpenedUpdate.d.ts +23 -0
- package/dist/debugProtocol/events/updates/IOPortOpenedUpdate.js +49 -0
- package/dist/debugProtocol/events/updates/IOPortOpenedUpdate.js.map +1 -0
- package/dist/debugProtocol/events/updates/ThreadAttachedUpdate.d.ts +26 -0
- package/dist/debugProtocol/events/updates/ThreadAttachedUpdate.js +50 -0
- package/dist/debugProtocol/events/updates/ThreadAttachedUpdate.js.map +1 -0
- package/dist/debugProtocol/server/DebugProtocolServer.d.ts +110 -0
- package/dist/debugProtocol/server/DebugProtocolServer.js +306 -0
- package/dist/debugProtocol/server/DebugProtocolServer.js.map +1 -0
- package/dist/debugProtocol/server/DebugProtocolServerPlugin.d.ts +41 -0
- package/dist/debugProtocol/server/DebugProtocolServerPlugin.js +3 -0
- package/dist/debugProtocol/server/DebugProtocolServerPlugin.js.map +1 -0
- package/dist/debugSession/BrightScriptDebugSession.d.ts +9 -1
- package/dist/debugSession/BrightScriptDebugSession.js +178 -89
- package/dist/debugSession/BrightScriptDebugSession.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/logging.d.ts +1 -0
- package/dist/logging.js +4 -2
- package/dist/logging.js.map +1 -1
- package/dist/managers/ActionQueue.d.ts +7 -1
- package/dist/managers/ActionQueue.js +27 -5
- package/dist/managers/ActionQueue.js.map +1 -1
- package/dist/managers/BreakpointManager.d.ts +82 -27
- package/dist/managers/BreakpointManager.js +168 -63
- package/dist/managers/BreakpointManager.js.map +1 -1
- package/dist/managers/ProjectManager.d.ts +3 -0
- package/dist/managers/ProjectManager.js +42 -36
- package/dist/managers/ProjectManager.js.map +1 -1
- package/dist/util.d.ts +8 -6
- package/dist/util.js +36 -19
- package/dist/util.js.map +1 -1
- package/package.json +14 -5
- package/roku-debug-0.20.7.tgz +0 -0
- package/dist/debugProtocol/Debugger.d.ts +0 -161
- package/dist/debugProtocol/Debugger.js +0 -635
- package/dist/debugProtocol/Debugger.js.map +0 -1
- package/dist/debugProtocol/responses/AddBreakpointsResponse.js.map +0 -1
- package/dist/debugProtocol/responses/BreakpointErrorUpdateResponse.d.ts +0 -32
- package/dist/debugProtocol/responses/BreakpointErrorUpdateResponse.js +0 -67
- package/dist/debugProtocol/responses/BreakpointErrorUpdateResponse.js.map +0 -1
- package/dist/debugProtocol/responses/BreakpointVerifiedUpdateResponse.d.ts +0 -32
- package/dist/debugProtocol/responses/BreakpointVerifiedUpdateResponse.js +0 -56
- package/dist/debugProtocol/responses/BreakpointVerifiedUpdateResponse.js.map +0 -1
- package/dist/debugProtocol/responses/ConnectIOPortResponse.d.ts +0 -10
- package/dist/debugProtocol/responses/ConnectIOPortResponse.js +0 -39
- package/dist/debugProtocol/responses/ConnectIOPortResponse.js.map +0 -1
- package/dist/debugProtocol/responses/ExecuteResponseV3.d.ts +0 -23
- package/dist/debugProtocol/responses/ExecuteResponseV3.js +0 -54
- package/dist/debugProtocol/responses/ExecuteResponseV3.js.map +0 -1
- package/dist/debugProtocol/responses/HandshakeResponse.d.ts +0 -12
- package/dist/debugProtocol/responses/HandshakeResponse.js +0 -39
- package/dist/debugProtocol/responses/HandshakeResponse.js.map +0 -1
- package/dist/debugProtocol/responses/HandshakeResponseV3.d.ts +0 -14
- package/dist/debugProtocol/responses/HandshakeResponseV3.js +0 -47
- package/dist/debugProtocol/responses/HandshakeResponseV3.js.map +0 -1
- package/dist/debugProtocol/responses/ListBreakpointsResponse.d.ts +0 -25
- package/dist/debugProtocol/responses/ListBreakpointsResponse.js +0 -65
- package/dist/debugProtocol/responses/ListBreakpointsResponse.js.map +0 -1
- package/dist/debugProtocol/responses/ProtocolEvent.d.ts +0 -11
- package/dist/debugProtocol/responses/ProtocolEvent.js +0 -38
- package/dist/debugProtocol/responses/ProtocolEvent.js.map +0 -1
- package/dist/debugProtocol/responses/ProtocolEventV3.d.ts +0 -11
- package/dist/debugProtocol/responses/ProtocolEventV3.js +0 -42
- package/dist/debugProtocol/responses/ProtocolEventV3.js.map +0 -1
- package/dist/debugProtocol/responses/RemoveBreakpointsResponse.js.map +0 -1
- package/dist/debugProtocol/responses/StackTraceResponse.d.ts +0 -18
- package/dist/debugProtocol/responses/StackTraceResponse.js +0 -58
- package/dist/debugProtocol/responses/StackTraceResponse.js.map +0 -1
- package/dist/debugProtocol/responses/StackTraceResponseV3.d.ts +0 -18
- package/dist/debugProtocol/responses/StackTraceResponseV3.js +0 -58
- package/dist/debugProtocol/responses/StackTraceResponseV3.js.map +0 -1
- package/dist/debugProtocol/responses/ThreadsResponse.d.ts +0 -22
- package/dist/debugProtocol/responses/ThreadsResponse.js +0 -63
- package/dist/debugProtocol/responses/ThreadsResponse.js.map +0 -1
- package/dist/debugProtocol/responses/UndefinedResponse.d.ts +0 -10
- package/dist/debugProtocol/responses/UndefinedResponse.js +0 -39
- package/dist/debugProtocol/responses/UndefinedResponse.js.map +0 -1
- package/dist/debugProtocol/responses/UpdateThreadsResponse.d.ts +0 -25
- package/dist/debugProtocol/responses/UpdateThreadsResponse.js +0 -91
- package/dist/debugProtocol/responses/UpdateThreadsResponse.js.map +0 -1
- package/dist/debugProtocol/responses/VariableResponse.d.ts +0 -27
- package/dist/debugProtocol/responses/VariableResponse.js +0 -141
- package/dist/debugProtocol/responses/VariableResponse.js.map +0 -1
- package/dist/debugProtocol/responses/index.d.ts +0 -11
- package/dist/debugProtocol/responses/index.js +0 -24
- package/dist/debugProtocol/responses/index.js.map +0 -1
- package/roku-debug-0.20.6.tgz +0 -0
- /package/dist/debugProtocol/{responses → events/responses}/AddBreakpointsResponse.d.ts +0 -0
- /package/dist/debugProtocol/{responses → events/responses}/AddBreakpointsResponse.js +0 -0
- /package/dist/debugProtocol/{responses → events/responses}/RemoveBreakpointsResponse.d.ts +0 -0
- /package/dist/debugProtocol/{responses → events/responses}/RemoveBreakpointsResponse.js +0 -0
|
@@ -1,635 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Debugger = void 0;
|
|
4
|
-
const Net = require("net");
|
|
5
|
-
const EventEmitter = require("eventemitter3");
|
|
6
|
-
const semver = require("semver");
|
|
7
|
-
const responses_1 = require("./responses");
|
|
8
|
-
const Constants_1 = require("./Constants");
|
|
9
|
-
const smart_buffer_1 = require("smart-buffer");
|
|
10
|
-
const logging_1 = require("../logging");
|
|
11
|
-
const ExecuteResponseV3_1 = require("./responses/ExecuteResponseV3");
|
|
12
|
-
const ListBreakpointsResponse_1 = require("./responses/ListBreakpointsResponse");
|
|
13
|
-
const AddBreakpointsResponse_1 = require("./responses/AddBreakpointsResponse");
|
|
14
|
-
const RemoveBreakpointsResponse_1 = require("./responses/RemoveBreakpointsResponse");
|
|
15
|
-
const util_1 = require("../util");
|
|
16
|
-
const BreakpointErrorUpdateResponse_1 = require("./responses/BreakpointErrorUpdateResponse");
|
|
17
|
-
const BreakpointVerifiedUpdateResponse_1 = require("./responses/BreakpointVerifiedUpdateResponse");
|
|
18
|
-
class Debugger {
|
|
19
|
-
constructor(options) {
|
|
20
|
-
this.logger = logging_1.logger.createLogger(`[${Debugger.name}]`);
|
|
21
|
-
// The highest tested version of the protocol we support.
|
|
22
|
-
this.supportedVersionRange = '<=3.0.0';
|
|
23
|
-
this.handshakeComplete = false;
|
|
24
|
-
this.connectedToIoPort = false;
|
|
25
|
-
this.watchPacketLength = false;
|
|
26
|
-
this.emitter = new EventEmitter();
|
|
27
|
-
this.stopped = false;
|
|
28
|
-
this.totalRequests = 0;
|
|
29
|
-
this.activeRequests = {};
|
|
30
|
-
this.options = {
|
|
31
|
-
controllerPort: 8081,
|
|
32
|
-
host: undefined,
|
|
33
|
-
//override the defaults with the options from parameters
|
|
34
|
-
...options !== null && options !== void 0 ? options : {}
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
get isStopped() {
|
|
38
|
-
return this.stopped;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Prior to protocol v3.1.0, the Roku device would regularly set the wrong thread as "active",
|
|
42
|
-
* so this flag lets us know if we should use our better-than-nothing workaround
|
|
43
|
-
*/
|
|
44
|
-
get enableThreadHoppingWorkaround() {
|
|
45
|
-
return semver.satisfies(this.protocolVersion, '<3.1.0');
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Starting in protocol v3.1.0, component libary breakpoints must be added in the format `lib:/<library_name>/<filepath>`, but prior they didn't require this.
|
|
49
|
-
* So this flag tells us which format to support
|
|
50
|
-
*/
|
|
51
|
-
get enableComponentLibrarySpecificBreakpoints() {
|
|
52
|
-
return semver.satisfies(this.protocolVersion, '>=3.1.0');
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Starting in protocol v3.1.0, breakpoints can support conditional expressions. This flag indicates whether the current sessuion supports that functionality.
|
|
56
|
-
*/
|
|
57
|
-
get supportsConditionalBreakpoints() {
|
|
58
|
-
return semver.satisfies(this.protocolVersion, '>=3.1.0');
|
|
59
|
-
}
|
|
60
|
-
get supportsBreakpointRegistrationWhileRunning() {
|
|
61
|
-
return semver.satisfies(this.protocolVersion, '>=3.2.0');
|
|
62
|
-
}
|
|
63
|
-
get supportsBreakpointVerification() {
|
|
64
|
-
return semver.satisfies(this.protocolVersion, '>=3.2.0');
|
|
65
|
-
}
|
|
66
|
-
once(eventName) {
|
|
67
|
-
return new Promise((resolve) => {
|
|
68
|
-
const disconnect = this.on(eventName, (...args) => {
|
|
69
|
-
disconnect();
|
|
70
|
-
resolve(...args);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
// public on(eventname: 'rendezvous', handler: (output: RendezvousHistory) => void);
|
|
75
|
-
// public on(eventName: 'runtime-error', handler: (error: BrightScriptRuntimeError) => void);
|
|
76
|
-
on(eventName, handler) {
|
|
77
|
-
this.emitter.on(eventName, handler);
|
|
78
|
-
return () => {
|
|
79
|
-
var _a;
|
|
80
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.removeListener(eventName, handler);
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
emit(eventName, data) {
|
|
84
|
-
//emit these events on next tick, otherwise they will be processed immediately which could cause issues
|
|
85
|
-
setTimeout(() => {
|
|
86
|
-
var _a;
|
|
87
|
-
//in rare cases, this event is fired after the debugger has closed, so make sure the event emitter still exists
|
|
88
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit(eventName, data);
|
|
89
|
-
}, 0);
|
|
90
|
-
}
|
|
91
|
-
async establishControllerConnection() {
|
|
92
|
-
const pendingSockets = new Set();
|
|
93
|
-
const connection = await new Promise((resolve) => {
|
|
94
|
-
var _a;
|
|
95
|
-
util_1.util.setInterval((cancelInterval) => {
|
|
96
|
-
const socket = new Net.Socket();
|
|
97
|
-
pendingSockets.add(socket);
|
|
98
|
-
socket.on('error', (error) => {
|
|
99
|
-
console.debug(Date.now(), 'Encountered an error connecting to the debug protocol socket. Ignoring and will try again soon', error);
|
|
100
|
-
});
|
|
101
|
-
socket.connect({ port: this.options.controllerPort, host: this.options.host }, () => {
|
|
102
|
-
cancelInterval();
|
|
103
|
-
this.logger.debug(`Connected to debug protocol controller port. Socket ${[...pendingSockets].indexOf(socket)} of ${pendingSockets.size} was the winner`);
|
|
104
|
-
//clean up all remaining pending sockets
|
|
105
|
-
for (const pendingSocket of pendingSockets) {
|
|
106
|
-
pendingSocket.removeAllListeners();
|
|
107
|
-
//cleanup and destroy all other sockets
|
|
108
|
-
if (pendingSocket !== socket) {
|
|
109
|
-
pendingSocket.end();
|
|
110
|
-
pendingSocket === null || pendingSocket === void 0 ? void 0 : pendingSocket.destroy();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
pendingSockets.clear();
|
|
114
|
-
resolve(socket);
|
|
115
|
-
});
|
|
116
|
-
}, (_a = this.options.controllerConnectInterval) !== null && _a !== void 0 ? _a : 250);
|
|
117
|
-
});
|
|
118
|
-
return connection;
|
|
119
|
-
}
|
|
120
|
-
async connect() {
|
|
121
|
-
this.logger.log('connect', this.options);
|
|
122
|
-
// If there is no error, the server has accepted the request and created a new dedicated control socket
|
|
123
|
-
this.controllerClient = await this.establishControllerConnection();
|
|
124
|
-
this.controllerClient.on('data', (buffer) => {
|
|
125
|
-
var _a, _b;
|
|
126
|
-
this.writeToBufferLog('server-to-client', buffer);
|
|
127
|
-
if (this.unhandledData) {
|
|
128
|
-
this.unhandledData = Buffer.concat([this.unhandledData, buffer]);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
this.unhandledData = buffer;
|
|
132
|
-
}
|
|
133
|
-
this.logger.debug(`on('data'): incoming bytes`, buffer.length, buffer.toJSON());
|
|
134
|
-
const startBufferSize = this.unhandledData.length;
|
|
135
|
-
this.parseUnhandledData(this.unhandledData);
|
|
136
|
-
const endBufferSize = (_b = (_a = this.unhandledData) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
137
|
-
this.logger.debug(`buffer size before:`, startBufferSize, ', buffer size after:', endBufferSize, ', bytes consumed:', startBufferSize - endBufferSize);
|
|
138
|
-
});
|
|
139
|
-
this.controllerClient.on('end', () => {
|
|
140
|
-
this.logger.log('TCP connection closed');
|
|
141
|
-
this.shutdown('app-exit');
|
|
142
|
-
});
|
|
143
|
-
// Don't forget to catch error, for your own sake.
|
|
144
|
-
this.controllerClient.once('error', (error) => {
|
|
145
|
-
//the Roku closed the connection for some unknown reason...
|
|
146
|
-
console.error(`TCP connection error on control port`, error);
|
|
147
|
-
this.shutdown('close');
|
|
148
|
-
});
|
|
149
|
-
//send the magic, which triggers the debug session
|
|
150
|
-
this.sendMagic();
|
|
151
|
-
//wait for the handshake response from the device
|
|
152
|
-
const isConnected = await this.once('connected');
|
|
153
|
-
return isConnected;
|
|
154
|
-
}
|
|
155
|
-
sendMagic() {
|
|
156
|
-
let buffer = new smart_buffer_1.SmartBuffer({ size: Buffer.byteLength(Debugger.DEBUGGER_MAGIC) + 1 }).writeStringNT(Debugger.DEBUGGER_MAGIC).toBuffer();
|
|
157
|
-
this.logger.log('Sending magic to server');
|
|
158
|
-
this.writeToBufferLog('client-to-server', buffer);
|
|
159
|
-
this.controllerClient.write(buffer);
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Write a specific buffer log entry to the logger, which, when file logging is enabled
|
|
163
|
-
* can be extracted and processed through the DebugProtocolClientReplaySession
|
|
164
|
-
*/
|
|
165
|
-
writeToBufferLog(type, buffer) {
|
|
166
|
-
this.logger.log('[[bufferLog]]:', JSON.stringify({
|
|
167
|
-
type: type,
|
|
168
|
-
timestamp: new Date().toISOString(),
|
|
169
|
-
buffer: buffer.toJSON()
|
|
170
|
-
}));
|
|
171
|
-
}
|
|
172
|
-
async continue() {
|
|
173
|
-
if (this.stopped) {
|
|
174
|
-
this.stopped = false;
|
|
175
|
-
return this.makeRequest(new smart_buffer_1.SmartBuffer({ size: 12 }), Constants_1.COMMANDS.CONTINUE);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
async pause(force = false) {
|
|
179
|
-
if (!this.stopped || force) {
|
|
180
|
-
return this.makeRequest(new smart_buffer_1.SmartBuffer({ size: 12 }), Constants_1.COMMANDS.STOP);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
async exitChannel() {
|
|
184
|
-
return this.makeRequest(new smart_buffer_1.SmartBuffer({ size: 12 }), Constants_1.COMMANDS.EXIT_CHANNEL);
|
|
185
|
-
}
|
|
186
|
-
async stepIn(threadId = this.primaryThread) {
|
|
187
|
-
return this.step(Constants_1.STEP_TYPE.STEP_TYPE_LINE, threadId);
|
|
188
|
-
}
|
|
189
|
-
async stepOver(threadId = this.primaryThread) {
|
|
190
|
-
return this.step(Constants_1.STEP_TYPE.STEP_TYPE_OVER, threadId);
|
|
191
|
-
}
|
|
192
|
-
async stepOut(threadId = this.primaryThread) {
|
|
193
|
-
return this.step(Constants_1.STEP_TYPE.STEP_TYPE_OUT, threadId);
|
|
194
|
-
}
|
|
195
|
-
async step(stepType, threadId) {
|
|
196
|
-
this.logger.log('[step]', { stepType: Constants_1.STEP_TYPE[stepType], threadId, stopped: this.stopped });
|
|
197
|
-
let buffer = new smart_buffer_1.SmartBuffer({ size: 17 });
|
|
198
|
-
buffer.writeUInt32LE(threadId); // thread_index
|
|
199
|
-
buffer.writeUInt8(stepType); // step_type
|
|
200
|
-
if (this.stopped) {
|
|
201
|
-
this.stopped = false;
|
|
202
|
-
let stepResult = await this.makeRequest(buffer, Constants_1.COMMANDS.STEP);
|
|
203
|
-
if (stepResult.errorCode === Constants_1.ERROR_CODES.OK) {
|
|
204
|
-
// this.stopped = true;
|
|
205
|
-
// this.emit('suspend');
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
// there is a CANT_CONTINUE error code but we can likely treat all errors like a CANT_CONTINUE
|
|
209
|
-
this.emit('cannot-continue');
|
|
210
|
-
}
|
|
211
|
-
return stepResult;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
async threads() {
|
|
215
|
-
if (this.stopped) {
|
|
216
|
-
let result = await this.makeRequest(new smart_buffer_1.SmartBuffer({ size: 12 }), Constants_1.COMMANDS.THREADS);
|
|
217
|
-
if (result.errorCode === Constants_1.ERROR_CODES.OK) {
|
|
218
|
-
//older versions of the debug protocol had issues with maintaining the active thread, so our workaround is to keep track of it elsewhere
|
|
219
|
-
if (this.enableThreadHoppingWorkaround) {
|
|
220
|
-
//ignore the `isPrimary` flag on threads
|
|
221
|
-
this.logger.debug(`Ignoring the 'isPrimary' flag from threads because protocol version ${this.protocolVersion} and lower has a bug`);
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
//trust the debug protocol's `isPrimary` flag on threads
|
|
225
|
-
for (let i = 0; i < result.threadsCount; i++) {
|
|
226
|
-
let thread = result.threads[i];
|
|
227
|
-
if (thread.isPrimary) {
|
|
228
|
-
this.primaryThread = i;
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return result;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
async stackTrace(threadIndex = this.primaryThread) {
|
|
238
|
-
let buffer = new smart_buffer_1.SmartBuffer({ size: 16 });
|
|
239
|
-
buffer.writeUInt32LE(threadIndex); // thread_index
|
|
240
|
-
if (this.stopped && threadIndex > -1) {
|
|
241
|
-
return this.makeRequest(buffer, Constants_1.COMMANDS.STACKTRACE);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* @param variablePathEntries One or more path entries to the variable to be inspected. E.g., m.top.myObj["someKey"] can be accessed with ["m","top","myobj","\"someKey\""].
|
|
246
|
-
*
|
|
247
|
-
* If no path is specified, the variables accessible from the specified stack frame are returned.
|
|
248
|
-
*
|
|
249
|
-
* Starting in protocol v3.1.0, The keys for indexed gets (i.e. obj["key"]) should be wrapped in quotes so they can be handled in a case-sensitive fashion (if applicable on device).
|
|
250
|
-
* All non-quoted keys (i.e. strings without leading and trailing quotes inside them) will be treated as case-insensitive).
|
|
251
|
-
* @param getChildKeys If set, VARIABLES response include the child keys for container types like lists and associative arrays
|
|
252
|
-
* @param stackFrameIndex 0 = first function called, nframes-1 = last function. This indexing does not match the order of the frames returned from the STACKTRACE command
|
|
253
|
-
* @param threadIndex the index (or perhaps ID?) of the thread to get variables for
|
|
254
|
-
*/
|
|
255
|
-
async getVariables(variablePathEntries = [], getChildKeys = true, stackFrameIndex = this.stackFrameIndex, threadIndex = this.primaryThread) {
|
|
256
|
-
if (this.stopped && threadIndex > -1) {
|
|
257
|
-
//starting in protocol v3.1.0, it supports marking certain path items as case-insensitive (i.e. parts of DottedGet expressions)
|
|
258
|
-
const sendCaseInsensitiveData = semver.satisfies(this.protocolVersion, '>=3.1.0') && variablePathEntries.length > 0;
|
|
259
|
-
let buffer = new smart_buffer_1.SmartBuffer({ size: 17 });
|
|
260
|
-
let flags = 0;
|
|
261
|
-
if (getChildKeys) {
|
|
262
|
-
// eslint-disable-next-line no-bitwise
|
|
263
|
-
flags |= Constants_1.VARIABLE_REQUEST_FLAGS.GET_CHILD_KEYS;
|
|
264
|
-
}
|
|
265
|
-
if (sendCaseInsensitiveData) {
|
|
266
|
-
// eslint-disable-next-line no-bitwise
|
|
267
|
-
flags |= Constants_1.VARIABLE_REQUEST_FLAGS.CASE_SENSITIVITY_OPTIONS;
|
|
268
|
-
}
|
|
269
|
-
buffer.writeUInt8(flags); // variable_request_flags
|
|
270
|
-
buffer.writeUInt32LE(threadIndex); // thread_index
|
|
271
|
-
buffer.writeUInt32LE(stackFrameIndex); // stack_frame_index
|
|
272
|
-
buffer.writeUInt32LE(variablePathEntries.length); // variable_path_len
|
|
273
|
-
variablePathEntries.forEach(entry => {
|
|
274
|
-
if (entry.startsWith('"') && entry.endsWith('"')) {
|
|
275
|
-
//remove leading and trailing quotes
|
|
276
|
-
entry = entry.substring(1, entry.length - 1);
|
|
277
|
-
}
|
|
278
|
-
buffer.writeStringNT(entry); // variable_path_entries - optional
|
|
279
|
-
});
|
|
280
|
-
if (sendCaseInsensitiveData) {
|
|
281
|
-
variablePathEntries.forEach(entry => {
|
|
282
|
-
buffer.writeUInt8(
|
|
283
|
-
//0 means case SENSITIVE lookup, 1 means case INsensitive lookup
|
|
284
|
-
entry.startsWith('"') ? 0 : 1);
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
return this.makeRequest(buffer, Constants_1.COMMANDS.VARIABLES, variablePathEntries);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
async executeCommand(sourceCode, stackFrameIndex = this.stackFrameIndex, threadIndex = this.primaryThread) {
|
|
291
|
-
if (this.stopped && threadIndex > -1) {
|
|
292
|
-
console.log(sourceCode);
|
|
293
|
-
let buffer = new smart_buffer_1.SmartBuffer({ size: 8 });
|
|
294
|
-
buffer.writeUInt32LE(threadIndex); // thread_index
|
|
295
|
-
buffer.writeUInt32LE(stackFrameIndex); // stack_frame_index
|
|
296
|
-
buffer.writeStringNT(sourceCode); // source_code
|
|
297
|
-
return this.makeRequest(buffer, Constants_1.COMMANDS.EXECUTE, sourceCode);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
async addBreakpoints(breakpoints) {
|
|
301
|
-
var _a, _b;
|
|
302
|
-
const { enableComponentLibrarySpecificBreakpoints } = this;
|
|
303
|
-
if ((breakpoints === null || breakpoints === void 0 ? void 0 : breakpoints.length) > 0) {
|
|
304
|
-
const useConditionalBreakpoints = (
|
|
305
|
-
//does this protocol version support conditional breakpoints?
|
|
306
|
-
this.supportsConditionalBreakpoints &&
|
|
307
|
-
//is there at least one conditional breakpoint present?
|
|
308
|
-
!!breakpoints.find(x => { var _a; return !!((_a = x === null || x === void 0 ? void 0 : x.conditionalExpression) === null || _a === void 0 ? void 0 : _a.trim()); }));
|
|
309
|
-
let buffer = new smart_buffer_1.SmartBuffer();
|
|
310
|
-
//set the `FLAGS` value if supported
|
|
311
|
-
if (useConditionalBreakpoints) {
|
|
312
|
-
buffer.writeUInt32LE(0); // flags - Should always be passed as 0. Unused, reserved for future use.
|
|
313
|
-
}
|
|
314
|
-
buffer.writeUInt32LE(breakpoints.length); // num_breakpoints - The number of breakpoints in the breakpoints array.
|
|
315
|
-
for (const breakpoint of breakpoints) {
|
|
316
|
-
let { filePath } = breakpoint;
|
|
317
|
-
//protocol >= v3.1.0 requires complib breakpoints have a special prefix
|
|
318
|
-
if (enableComponentLibrarySpecificBreakpoints) {
|
|
319
|
-
if (breakpoint.componentLibraryName) {
|
|
320
|
-
filePath = filePath.replace(/^pkg:\//i, `lib:/${breakpoint.componentLibraryName}/`);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
buffer.writeStringNT(filePath); // file_path - The path of the source file where the breakpoint is to be inserted.
|
|
324
|
-
buffer.writeUInt32LE(breakpoint.lineNumber); // line_number - The line number in the channel application code where the breakpoint is to be executed.
|
|
325
|
-
buffer.writeUInt32LE((_a = breakpoint.hitCount) !== null && _a !== void 0 ? _a : 0); // ignore_count - The number of times to ignore the breakpoint condition before executing the breakpoint. This number is decremented each time the channel application reaches the breakpoint.
|
|
326
|
-
//if the protocol supports conditional breakpoints, add any present condition
|
|
327
|
-
if (useConditionalBreakpoints) {
|
|
328
|
-
//There's a bug in 3.1 where empty conditional expressions would crash the breakpoints, so just default to `true` which always succeeds
|
|
329
|
-
buffer.writeStringNT((_b = breakpoint.conditionalExpression) !== null && _b !== void 0 ? _b : 'true'); // cond_expr - the condition that must evaluate to `true` in order to hit the breakpoint
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
const response = await this.makeRequest(buffer, useConditionalBreakpoints ? Constants_1.COMMANDS.ADD_CONDITIONAL_BREAKPOINTS : Constants_1.COMMANDS.ADD_BREAKPOINTS);
|
|
333
|
-
//if the device does not support breakpoint verification, then auto-mark all of these as verified
|
|
334
|
-
if (!this.supportsBreakpointVerification) {
|
|
335
|
-
this.emit('breakpoints-verified', response);
|
|
336
|
-
}
|
|
337
|
-
return response;
|
|
338
|
-
}
|
|
339
|
-
const response = new AddBreakpointsResponse_1.AddBreakpointsResponse(null);
|
|
340
|
-
response.success = true;
|
|
341
|
-
response.errorCode = Constants_1.ERROR_CODES.OK;
|
|
342
|
-
return response;
|
|
343
|
-
}
|
|
344
|
-
async listBreakpoints() {
|
|
345
|
-
return this.makeRequest(new smart_buffer_1.SmartBuffer({ size: 12 }), Constants_1.COMMANDS.LIST_BREAKPOINTS);
|
|
346
|
-
}
|
|
347
|
-
async removeBreakpoints(breakpointIds) {
|
|
348
|
-
if ((breakpointIds === null || breakpointIds === void 0 ? void 0 : breakpointIds.length) > 0) {
|
|
349
|
-
let buffer = new smart_buffer_1.SmartBuffer();
|
|
350
|
-
buffer.writeUInt32LE(breakpointIds.length); // num_breakpoints - The number of breakpoints in the breakpoints array.
|
|
351
|
-
breakpointIds.forEach((breakpointId) => {
|
|
352
|
-
buffer.writeUInt32LE(breakpointId); // breakpoint_ids - An array of breakpoint IDs representing the breakpoints to be removed.
|
|
353
|
-
});
|
|
354
|
-
return this.makeRequest(buffer, Constants_1.COMMANDS.REMOVE_BREAKPOINTS);
|
|
355
|
-
}
|
|
356
|
-
return new RemoveBreakpointsResponse_1.RemoveBreakpointsResponse(null);
|
|
357
|
-
}
|
|
358
|
-
async makeRequest(buffer, command, extraData) {
|
|
359
|
-
this.totalRequests++;
|
|
360
|
-
let requestId = this.totalRequests;
|
|
361
|
-
buffer.insertUInt32LE(command, 0); // command_code - An enum representing the debugging command being sent. See the COMMANDS enum
|
|
362
|
-
buffer.insertUInt32LE(requestId, 0); // request_id - The ID of the debugger request (must be >=1). This ID is included in the debugger response.
|
|
363
|
-
buffer.insertUInt32LE(buffer.writeOffset + 4, 0); // packet_length - The size of the packet to be sent.
|
|
364
|
-
this.activeRequests[requestId] = {
|
|
365
|
-
commandType: command,
|
|
366
|
-
commandTypeText: Constants_1.COMMANDS[command],
|
|
367
|
-
extraData: extraData
|
|
368
|
-
};
|
|
369
|
-
return new Promise((resolve, reject) => {
|
|
370
|
-
let unsubscribe = this.on('data', (data) => {
|
|
371
|
-
if (data.requestId === requestId) {
|
|
372
|
-
unsubscribe();
|
|
373
|
-
resolve(data);
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
this.logger.debug('makeRequest', `requestId=${requestId}`, this.activeRequests[requestId]);
|
|
377
|
-
if (this.controllerClient) {
|
|
378
|
-
const buff = buffer.toBuffer();
|
|
379
|
-
this.writeToBufferLog('client-to-server', buff);
|
|
380
|
-
this.controllerClient.write(buff);
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
throw new Error(`Controller connection was closed - Command: ${Constants_1.COMMANDS[command]}`);
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
parseUnhandledData(buffer) {
|
|
388
|
-
if (buffer.length < 1) {
|
|
389
|
-
// short circuit if the buffer is empty
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
392
|
-
if (this.handshakeComplete) {
|
|
393
|
-
let debuggerRequestResponse = this.watchPacketLength ? new responses_1.ProtocolEventV3(buffer) : new responses_1.ProtocolEvent(buffer);
|
|
394
|
-
let packetLength = debuggerRequestResponse.packetLength;
|
|
395
|
-
let slicedBuffer = packetLength ? buffer.slice(4) : buffer;
|
|
396
|
-
this.logger.log(`incoming bytes: ${buffer.length}`, debuggerRequestResponse, slicedBuffer.toJSON());
|
|
397
|
-
if (debuggerRequestResponse.success) {
|
|
398
|
-
if (debuggerRequestResponse.requestId > this.totalRequests) {
|
|
399
|
-
this.removedProcessedBytes(debuggerRequestResponse, slicedBuffer, packetLength);
|
|
400
|
-
return true;
|
|
401
|
-
}
|
|
402
|
-
if (debuggerRequestResponse.errorCode !== Constants_1.ERROR_CODES.OK) {
|
|
403
|
-
this.logger.error(debuggerRequestResponse.errorCode, debuggerRequestResponse);
|
|
404
|
-
this.removedProcessedBytes(debuggerRequestResponse, buffer, packetLength);
|
|
405
|
-
return true;
|
|
406
|
-
}
|
|
407
|
-
if (debuggerRequestResponse.updateType > 0) {
|
|
408
|
-
this.logger.log('Update Type:', Constants_1.UPDATE_TYPES[debuggerRequestResponse.updateType]);
|
|
409
|
-
switch (debuggerRequestResponse.updateType) {
|
|
410
|
-
case Constants_1.UPDATE_TYPES.IO_PORT_OPENED:
|
|
411
|
-
return this.connectToIoPort(new responses_1.ConnectIOPortResponse(slicedBuffer), buffer, packetLength);
|
|
412
|
-
case Constants_1.UPDATE_TYPES.ALL_THREADS_STOPPED:
|
|
413
|
-
case Constants_1.UPDATE_TYPES.THREAD_ATTACHED:
|
|
414
|
-
let debuggerUpdateThreads = new responses_1.UpdateThreadsResponse(slicedBuffer);
|
|
415
|
-
this.logger.log(debuggerUpdateThreads);
|
|
416
|
-
if (debuggerUpdateThreads.success) {
|
|
417
|
-
this.handleThreadsUpdate(debuggerUpdateThreads);
|
|
418
|
-
this.removedProcessedBytes(debuggerUpdateThreads, slicedBuffer, packetLength);
|
|
419
|
-
return true;
|
|
420
|
-
}
|
|
421
|
-
return false;
|
|
422
|
-
case Constants_1.UPDATE_TYPES.UNDEF:
|
|
423
|
-
return this.checkResponse(new responses_1.UndefinedResponse(slicedBuffer), buffer, packetLength);
|
|
424
|
-
case Constants_1.UPDATE_TYPES.BREAKPOINT_ERROR:
|
|
425
|
-
const response = new BreakpointErrorUpdateResponse_1.BreakpointErrorUpdateResponse(slicedBuffer);
|
|
426
|
-
//we do nothing with breakpoint errors at this time.
|
|
427
|
-
return this.checkResponse(response, buffer, packetLength);
|
|
428
|
-
case Constants_1.UPDATE_TYPES.COMPILE_ERROR:
|
|
429
|
-
return this.checkResponse(new responses_1.UndefinedResponse(slicedBuffer), buffer, packetLength);
|
|
430
|
-
case Constants_1.UPDATE_TYPES.BREAKPOINT_VERIFIED:
|
|
431
|
-
const bpVerifiedResponse = new BreakpointVerifiedUpdateResponse_1.BreakpointVerifiedUpdateResponse(slicedBuffer);
|
|
432
|
-
console.log('breakpoints verified', bpVerifiedResponse.breakpoints.map(x => x.breakpointId));
|
|
433
|
-
if (this.checkResponse(bpVerifiedResponse, buffer, packetLength)) {
|
|
434
|
-
this.emit('breakpoints-verified', {
|
|
435
|
-
breakpoints: bpVerifiedResponse.breakpoints
|
|
436
|
-
});
|
|
437
|
-
return true;
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
default:
|
|
443
|
-
return this.checkResponse(new responses_1.UndefinedResponse(slicedBuffer), buffer, packetLength);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
this.logger.log('Command Type:', Constants_1.COMMANDS[this.activeRequests[debuggerRequestResponse.requestId].commandType]);
|
|
448
|
-
switch (this.activeRequests[debuggerRequestResponse.requestId].commandType) {
|
|
449
|
-
case Constants_1.COMMANDS.STOP:
|
|
450
|
-
case Constants_1.COMMANDS.CONTINUE:
|
|
451
|
-
case Constants_1.COMMANDS.STEP:
|
|
452
|
-
case Constants_1.COMMANDS.EXIT_CHANNEL:
|
|
453
|
-
this.removedProcessedBytes(debuggerRequestResponse, buffer, packetLength);
|
|
454
|
-
return true;
|
|
455
|
-
case Constants_1.COMMANDS.EXECUTE:
|
|
456
|
-
return this.checkResponse(new ExecuteResponseV3_1.ExecuteResponseV3(slicedBuffer), buffer, packetLength);
|
|
457
|
-
case Constants_1.COMMANDS.ADD_BREAKPOINTS:
|
|
458
|
-
case Constants_1.COMMANDS.ADD_CONDITIONAL_BREAKPOINTS:
|
|
459
|
-
return this.checkResponse(new AddBreakpointsResponse_1.AddBreakpointsResponse(slicedBuffer), buffer, packetLength);
|
|
460
|
-
case Constants_1.COMMANDS.LIST_BREAKPOINTS:
|
|
461
|
-
return this.checkResponse(new ListBreakpointsResponse_1.ListBreakpointsResponse(slicedBuffer), buffer, packetLength);
|
|
462
|
-
case Constants_1.COMMANDS.REMOVE_BREAKPOINTS:
|
|
463
|
-
return this.checkResponse(new RemoveBreakpointsResponse_1.RemoveBreakpointsResponse(slicedBuffer), buffer, packetLength);
|
|
464
|
-
case Constants_1.COMMANDS.VARIABLES:
|
|
465
|
-
return this.checkResponse(new responses_1.VariableResponse(slicedBuffer), buffer, packetLength);
|
|
466
|
-
case Constants_1.COMMANDS.STACKTRACE:
|
|
467
|
-
return this.checkResponse(packetLength ? new responses_1.StackTraceResponseV3(slicedBuffer) : new responses_1.StackTraceResponse(slicedBuffer), buffer, packetLength);
|
|
468
|
-
case Constants_1.COMMANDS.THREADS:
|
|
469
|
-
return this.checkResponse(new responses_1.ThreadsResponse(slicedBuffer), buffer, packetLength);
|
|
470
|
-
default:
|
|
471
|
-
return this.checkResponse(debuggerRequestResponse, buffer, packetLength);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
else {
|
|
477
|
-
let debuggerHandshake;
|
|
478
|
-
debuggerHandshake = new responses_1.HandshakeResponseV3(buffer);
|
|
479
|
-
this.logger.log(`incoming bytes: ${buffer.length}`, debuggerHandshake);
|
|
480
|
-
if (!debuggerHandshake.success) {
|
|
481
|
-
debuggerHandshake = new responses_1.HandshakeResponse(buffer);
|
|
482
|
-
}
|
|
483
|
-
if (debuggerHandshake.success) {
|
|
484
|
-
this.handshakeComplete = true;
|
|
485
|
-
this.verifyHandshake(debuggerHandshake);
|
|
486
|
-
this.removedProcessedBytes(debuggerHandshake, buffer);
|
|
487
|
-
//once the handshake is complete, we have successfully "connected"
|
|
488
|
-
this.emit('connected', true);
|
|
489
|
-
return true;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return false;
|
|
493
|
-
}
|
|
494
|
-
checkResponse(responseClass, unhandledData, packetLength = 0) {
|
|
495
|
-
if (responseClass.success) {
|
|
496
|
-
this.removedProcessedBytes(responseClass, unhandledData, packetLength);
|
|
497
|
-
return true;
|
|
498
|
-
}
|
|
499
|
-
else if (packetLength > 0 && unhandledData.length >= packetLength) {
|
|
500
|
-
this.removedProcessedBytes(responseClass, unhandledData, packetLength);
|
|
501
|
-
}
|
|
502
|
-
return false;
|
|
503
|
-
}
|
|
504
|
-
removedProcessedBytes(responseHandler, unhandledData, packetLength = 0) {
|
|
505
|
-
var _a, _b, _c;
|
|
506
|
-
const activeRequest = this.activeRequests[responseHandler.requestId];
|
|
507
|
-
if (responseHandler.requestId > 0 && this.activeRequests[responseHandler.requestId]) {
|
|
508
|
-
delete this.activeRequests[responseHandler.requestId];
|
|
509
|
-
}
|
|
510
|
-
this.emit('data', responseHandler);
|
|
511
|
-
this.unhandledData = unhandledData.slice(packetLength ? packetLength : responseHandler.readOffset);
|
|
512
|
-
this.logger.debug('[raw]', `requestId=${responseHandler === null || responseHandler === void 0 ? void 0 : responseHandler.requestId}`, activeRequest, (_c = (_b = (_a = responseHandler) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '', responseHandler);
|
|
513
|
-
this.parseUnhandledData(this.unhandledData);
|
|
514
|
-
}
|
|
515
|
-
verifyHandshake(debuggerHandshake) {
|
|
516
|
-
const magicIsValid = (Debugger.DEBUGGER_MAGIC === debuggerHandshake.magic);
|
|
517
|
-
if (magicIsValid) {
|
|
518
|
-
this.logger.log('Magic is valid.');
|
|
519
|
-
this.protocolVersion = [debuggerHandshake.majorVersion, debuggerHandshake.minorVersion, debuggerHandshake.patchVersion].join('.');
|
|
520
|
-
this.logger.log('Protocol Version:', this.protocolVersion);
|
|
521
|
-
this.watchPacketLength = debuggerHandshake.watchPacketLength;
|
|
522
|
-
let handshakeVerified = true;
|
|
523
|
-
if (semver.satisfies(this.protocolVersion, this.supportedVersionRange)) {
|
|
524
|
-
this.logger.log('supported');
|
|
525
|
-
this.emit('protocol-version', {
|
|
526
|
-
message: `Protocol Version ${this.protocolVersion} is supported!`,
|
|
527
|
-
errorCode: Constants_1.PROTOCOL_ERROR_CODES.SUPPORTED
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
else if (semver.gtr(this.protocolVersion, this.supportedVersionRange)) {
|
|
531
|
-
this.logger.log('roku-debug has not been tested against protocol version', this.protocolVersion);
|
|
532
|
-
this.emit('protocol-version', {
|
|
533
|
-
message: `Protocol Version ${this.protocolVersion} has not been tested and my not work as intended.\nPlease open any issues you have with this version to https://github.com/rokucommunity/roku-debug/issues`,
|
|
534
|
-
errorCode: Constants_1.PROTOCOL_ERROR_CODES.NOT_TESTED
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
this.logger.log('not supported');
|
|
539
|
-
this.emit('protocol-version', {
|
|
540
|
-
message: `Protocol Version ${this.protocolVersion} is not supported.\nIf you believe this is an error please open an issue at https://github.com/rokucommunity/roku-debug/issues`,
|
|
541
|
-
errorCode: Constants_1.PROTOCOL_ERROR_CODES.NOT_SUPPORTED
|
|
542
|
-
});
|
|
543
|
-
this.shutdown('close');
|
|
544
|
-
handshakeVerified = false;
|
|
545
|
-
}
|
|
546
|
-
this.emit('handshake-verified', handshakeVerified);
|
|
547
|
-
return handshakeVerified;
|
|
548
|
-
}
|
|
549
|
-
else {
|
|
550
|
-
this.logger.log('Closing connection due to bad debugger magic', debuggerHandshake.magic);
|
|
551
|
-
this.emit('handshake-verified', false);
|
|
552
|
-
this.shutdown('close');
|
|
553
|
-
return false;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
connectToIoPort(connectIoPortResponse, unhandledData, packetLength = 0) {
|
|
557
|
-
this.logger.log('Connecting to IO port. response status success =', connectIoPortResponse.success);
|
|
558
|
-
if (connectIoPortResponse.success) {
|
|
559
|
-
// Create a new TCP client.
|
|
560
|
-
this.ioClient = new Net.Socket();
|
|
561
|
-
// Send a connection request to the server.
|
|
562
|
-
this.logger.log('Connect to IO Port: port', connectIoPortResponse.data, 'host', this.options.host);
|
|
563
|
-
this.ioClient.connect({ port: connectIoPortResponse.data, host: this.options.host }, () => {
|
|
564
|
-
// If there is no error, the server has accepted the request
|
|
565
|
-
this.logger.log('TCP connection established with the IO Port.');
|
|
566
|
-
this.connectedToIoPort = true;
|
|
567
|
-
let lastPartialLine = '';
|
|
568
|
-
this.ioClient.on('data', (buffer) => {
|
|
569
|
-
this.writeToBufferLog('io', buffer);
|
|
570
|
-
let responseText = buffer.toString();
|
|
571
|
-
if (!responseText.endsWith('\n')) {
|
|
572
|
-
// buffer was split, save the partial line
|
|
573
|
-
lastPartialLine += responseText;
|
|
574
|
-
}
|
|
575
|
-
else {
|
|
576
|
-
if (lastPartialLine) {
|
|
577
|
-
// there was leftover lines, join the partial lines back together
|
|
578
|
-
responseText = lastPartialLine + responseText;
|
|
579
|
-
lastPartialLine = '';
|
|
580
|
-
}
|
|
581
|
-
// Emit the completed io string.
|
|
582
|
-
this.emit('io-output', responseText.trim());
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
this.ioClient.on('end', () => {
|
|
586
|
-
this.ioClient.end();
|
|
587
|
-
this.logger.log('Requested an end to the IO connection');
|
|
588
|
-
});
|
|
589
|
-
// Don't forget to catch error, for your own sake.
|
|
590
|
-
this.ioClient.once('error', (err) => {
|
|
591
|
-
this.ioClient.end();
|
|
592
|
-
this.logger.error(err);
|
|
593
|
-
});
|
|
594
|
-
});
|
|
595
|
-
this.removedProcessedBytes(connectIoPortResponse, unhandledData, packetLength);
|
|
596
|
-
return true;
|
|
597
|
-
}
|
|
598
|
-
return false;
|
|
599
|
-
}
|
|
600
|
-
handleThreadsUpdate(update) {
|
|
601
|
-
this.stopped = true;
|
|
602
|
-
let stopReason = update.data.stopReason;
|
|
603
|
-
let eventName = stopReason === Constants_1.STOP_REASONS.RUNTIME_ERROR ? 'runtime-error' : 'suspend';
|
|
604
|
-
if (update.updateType === Constants_1.UPDATE_TYPES.ALL_THREADS_STOPPED) {
|
|
605
|
-
if (stopReason === Constants_1.STOP_REASONS.RUNTIME_ERROR || stopReason === Constants_1.STOP_REASONS.BREAK || stopReason === Constants_1.STOP_REASONS.STOP_STATEMENT) {
|
|
606
|
-
this.primaryThread = update.data.primaryThreadIndex;
|
|
607
|
-
this.stackFrameIndex = 0;
|
|
608
|
-
this.emit(eventName, update);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
else if (stopReason === Constants_1.STOP_REASONS.RUNTIME_ERROR || stopReason === Constants_1.STOP_REASONS.BREAK || stopReason === Constants_1.STOP_REASONS.STOP_STATEMENT) {
|
|
612
|
-
this.primaryThread = update.data.threadIndex;
|
|
613
|
-
this.emit(eventName, update);
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
destroy() {
|
|
617
|
-
this.shutdown('close');
|
|
618
|
-
}
|
|
619
|
-
shutdown(eventName) {
|
|
620
|
-
if (this.controllerClient) {
|
|
621
|
-
this.controllerClient.removeAllListeners();
|
|
622
|
-
this.controllerClient.destroy();
|
|
623
|
-
this.controllerClient = undefined;
|
|
624
|
-
}
|
|
625
|
-
if (this.ioClient) {
|
|
626
|
-
this.ioClient.removeAllListeners();
|
|
627
|
-
this.ioClient.destroy();
|
|
628
|
-
this.ioClient = undefined;
|
|
629
|
-
}
|
|
630
|
-
this.emit(eventName);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
exports.Debugger = Debugger;
|
|
634
|
-
Debugger.DEBUGGER_MAGIC = 'bsdebug'; // 64-bit = [b'bsdebug\0' little-endian]
|
|
635
|
-
//# sourceMappingURL=Debugger.js.map
|