import type { BSDebugDiagnostic } from '../CompileErrorProcessor'; import type { RendezvousTracker } from '../RendezvousTracker'; import type { ChanperfData } from '../ChanperfTracker'; import type { AdapterOptions, RokuAdapterEvaluateResponse } from '../interfaces'; import { TelnetRequestPipeline } from './TelnetRequestPipeline'; import type { DebugProtocolAdapter, EvaluateContainer } from './DebugProtocolAdapter'; import type { ExceptionBreakpoint } from '../debugProtocol/events/requests/SetExceptionBreakpointsRequest'; /** * A class that connects to a Roku device over telnet debugger port and provides a standardized way of interacting with it. */ export declare class TelnetAdapter { private options; private rendezvousTracker; constructor(options: AdapterOptions & { enableDebuggerAutoRecovery?: boolean; }, rendezvousTracker: RendezvousTracker); private connectionDeferred; isConnected(): Promise; logger: import("@rokucommunity/logger").Logger; /** * Indicates whether the adapter has successfully established a connection with the device */ connected: boolean; private compileErrorProcessor; requestPipeline: TelnetRequestPipeline; private emitter; private isNextBreakpointSkipped; private isInMicroDebugger; private debugStartRegex; private debugEndRegex; private chanperfTracker; private stackFramesCache; private cache; /** * Does this adapter support the `execute` command (known as `eval` in telnet) */ supportsExecute: boolean; supportsExceptionBreakpoints: boolean; supportsConditionalBreakpoints: boolean; supportsHitConditionalBreakpoints: boolean; once(eventName: 'app-ready'): Promise; once(eventName: 'connected'): Promise; /** * Subscribe to various events * @param eventName * @param handler */ on(eventName: 'cannot-continue', handler: () => any): any; on(eventname: 'chanperf', handler: (output: ChanperfData) => any): any; on(eventName: 'close', handler: () => any): any; on(eventName: 'app-exit', handler: () => any): any; on(eventName: 'diagnostics', handler: (params: BSDebugDiagnostic[]) => any): any; on(eventName: 'launch-status', handler: (message: string) => any): any; on(eventName: 'connected', handler: (params: boolean) => any): any; on(eventname: 'console-output', handler: (output: string) => any): any; on(eventName: 'runtime-error', handler: (error: BrightScriptRuntimeError) => any): any; on(eventName: 'suspend', handler: () => any): any; on(eventName: 'start', handler: () => any): any; on(eventname: 'device-unresponsive', handler: (data: { lastCommand: string; }) => any): any; on(eventname: 'unhandled-console-output', handler: (output: string) => any): any; private emit; /** * The debugger needs to tell us when to be active (i.e. when the package was deployed) */ isActivated: boolean; /** * This will be set to true When the roku emits the [scrpt.ctx.run.enter] text, * which indicates that the app is running on the Roku */ isAppRunning: boolean; /** * Every time we get a message that ends with the debugger prompt, * this will be set to true. Otherwise, it will be set to false */ isAtDebuggerPrompt: boolean; activate(): Promise; sendErrors(): Promise; private handleStartupIfReady; /** * Wait until the client has stopped sending messages. This is used mainly during .connect so we can ignore all old messages from the server * @param client * @param maxWaitMilliseconds */ private settleTelnetConnection; private processBreakpoints; private firstConnectDeferred; onReady(): Promise; /** * Connect to the telnet session. This should be called before the channel is launched. */ connect(): Promise; private beginAppExit; /** * Look through response text for the "Can't continue" text * @param responseText */ private isAtCannotContinue; /** * Look through the given response text for a runtime error * @param responseText */ private checkForRuntimeError; /** * Send command to step over */ stepOver(): Promise; stepInto(): Promise; stepOut(): Promise; /** * Tell the brightscript program to continue (i.e. resume program) */ continue(): Promise; /** * Tell the brightscript program to pause (fall into debug mode) */ pause(): void; /** * Clears the state, which means that everything will be retrieved fresh next time it is requested */ clearCache(clearStackFrameCache?: boolean): void; /** * Execute a command directly on the roku. Returns the output of the command. * @param command the command to execute. If the command does not start with `print` the command will be prefixed with `print ` because */ evaluate(command: string): Promise; getStackTrace(): Promise; getStackFrameById(frameId: number): StackFrame; /** * Runs a regex to check if the target is an object and get the type if it is * @param value */ private getObjectType; /** * Runs a regex to get the first work of a line * @param value */ private getFirstWord; /** * Gets a string array of all the local variables using the var command */ getScopeVariables(): Promise; /** * Given an expression, evaluate that statement ON the roku * @param expression * @param frameId unused but added to match signature of DebugProtocolAdapter */ getVariable(expression: string, frameId?: number): Promise; /** * In order to get around the `...` issue in printed arrays, `getVariable` now prints every value from an array or associative array in a for loop. * As such, we need to iterate over every printed result to produce the children array */ private getForLoopPrintedChildren; private getPrimativeTypeFromValue; isScrapableContainObject(objectType: string): boolean; private getObjectChildren; /** * Determine if this value is a primative type * @param expressionType */ private getHighLevelType; /** * Get the type of the provided expression * @param expression */ getVariableType(expression: string): Promise; /** * Cache items by a unique key * @param expression * @param factory */ private resolve; /** * Get a list of threads. The first thread in the list is the active thread */ getThreads(): Promise; removeAllListeners(): void; /** * Indicates whether this class has had `.destroy()` called at least once. Mostly used for checking externally to see if * the whole debug session has been terminated or is in a bad state. */ isDestroyed: boolean; /** * Disconnect from the telnet session and unset all objects */ destroy(): Promise; /** * Passes the log level down to the RendezvousTracker and ChanperfTracker * @param outputLevel the consoleOutput from the launch config */ setConsoleOutput(outputLevel: string): void; /** * Sends a call to the RendezvousTracker to clear the current rendezvous history */ clearRendezvousHistory(): void; /** * Sends a call to the ChanperfTracker to clear the current chanperf history */ clearChanperfHistory(): void; setExceptionBreakpoints(filters: ExceptionBreakpoint[]): Promise; syncBreakpoints(): Promise; isTelnetAdapter(): this is TelnetAdapter; isDebugProtocolAdapter(): this is DebugProtocolAdapter; } export interface StackFrame { frameId: number; filePath: string; lineNumber: number; functionIdentifier: string; } export declare enum EventName { suspend = "suspend" } export declare enum KeyType { string = "String", integer = "Integer", legacy = "Legacy" } export interface Thread { /** * Is this thread selected */ isSelected: boolean; isDetached?: boolean; /** * The 1-based line number */ lineNumber: number; /** * The pkgPath to the file on-device */ filePath: string; /** * The contents of the line (i.e. the code for the line) */ lineContents: string; /** * The id of this thread */ threadId: number; osThreadId?: string; name?: string; type?: string; } export declare enum PrimativeType { invalid = "Invalid", boolean = "Boolean", string = "String", integer = "Integer", float = "Float" } interface BrightScriptRuntimeError { message: string; errorCode: string; } export {};