Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

blueshell

Package Overview
Dependencies
Maintainers
6
Versions
241
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blueshell - npm Package Compare versions

Comparing version 3.6.0-btvBreakpoints.9 to 3.6.0-btvBreakpoints.10

dist/utils/nodeManagerHelper.d.ts

6

dist/utils/nodeManager.d.ts
import { BaseNode, BlueshellState } from '../models';
export declare class DuplicateNodeAdded extends Error {
constructor(path: string);
}
export declare class APIFunctionNotFound extends Error {
constructor(apiFunction: string);
}
export declare class NodeManager<S extends BlueshellState, E> {

@@ -3,0 +9,0 @@ private nodePathMap;

379

dist/utils/nodeManager.js
"use strict";
/* eslint-disable no-console */
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeManager = void 0;
exports.NodeManager = exports.APIFunctionNotFound = exports.DuplicateNodeAdded = void 0;
const models_1 = require("../models");
const ws_1 = require("ws");
const inspector_1 = require("inspector");
const nodeManagerHelper_1 = require("./nodeManagerHelper");
class DuplicateNodeAdded extends Error {
constructor(path) {
super(`Key ${path} already exists! Cannot add new node.`);
}
}
exports.DuplicateNodeAdded = DuplicateNodeAdded;
class APIFunctionNotFound extends Error {
constructor(apiFunction) {
super(`Unknown request type: ${apiFunction}`);
}
}
exports.APIFunctionNotFound = APIFunctionNotFound;
// Manages information about what nodes are available in the BT for debugging (nodes must be registered

@@ -24,91 +37,96 @@ // when they become available and unregistered when they are no longer available)

this.session.post('Debugger.enable', () => { });
if (process.env.NODE_ENV !== 'test') {
this.server = new ws_1.Server({
host: 'localhost',
port: 8990,
});
// should be empty but clear everything for good measure
this.breakpointInfoMap.forEach((breakpointInfo, nodePathAndMethodName) => {
this.session.post('Debugger.removeBreakpoint', {
breakpointId: breakpointInfo.breakpointId,
}, () => {
this.breakpointInfoMap.delete(nodePathAndMethodName);
this.server = new ws_1.Server({
host: 'localhost',
port: 8990,
});
// should be empty but clear everything for good measure
this.breakpointInfoMap.forEach(async (breakpointInfo, nodePathAndMethodName) => {
const success = await nodeManagerHelper_1.RuntimeWrappers.removeBreakpointFromFunction(this.session, breakpointInfo);
if (success) {
this.breakpointInfoMap.delete(nodePathAndMethodName);
}
});
this.breakpointInfoMap.clear();
global.breakpointMethods.clear();
// setup the connection handler
this.server.on('connection', (clientSocket) => {
// send the current cached breakpoints to the client if the client reconnects
this.breakpointInfoMap.forEach((breakpointInfo) => {
breakpointInfo.breakpoints.forEach((breakpoint) => {
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: breakpoint.nodePath,
methodName: breakpointInfo.methodInfo.methodName,
nodeName: breakpoint.nodeName,
nodeParent: breakpoint.nodeParent,
condition: breakpoint.condition,
success: true,
}));
});
});
this.breakpointInfoMap.clear();
global.breakpointMethods.clear();
// setup the connection handler
this.server.on('connection', (clientSocket) => {
// send the current cached breakpoints to the client if the client reconnects
this.breakpointInfoMap.forEach((breakpointInfo) => {
breakpointInfo.breakpoints.forEach((breakpoint) => {
clientSocket.on('message', async (data) => {
const dataObj = JSON.parse(data);
// message should always have a request and nodePath
const request = dataObj.request;
const nodePath = dataObj.nodePath;
switch (request) {
// client is requesting the methods for a given node path
case 'getMethodsForNode': {
let methodInfo;
let success = true;
try {
methodInfo = this.getMethodsForNode(nodePath);
}
catch (_a) {
success = false;
}
clientSocket.send(JSON.stringify({
request: 'getMethodsForNode',
success,
nodePath,
...methodInfo,
}));
break;
}
// client is requesting to add (or modify) a breakpoint for a given node path/method
case 'placeBreakpoint': {
const methodName = dataObj.methodName;
const condition = dataObj.condition;
const success = await this.setBreakpoint(nodePath, methodName, condition);
const node = this.nodePathMap.get(nodePath);
const nodeName = node === null || node === void 0 ? void 0 : node.name;
const nodeParent = node === null || node === void 0 ? void 0 : node.parent;
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: breakpoint.nodePath,
methodName: breakpointInfo.methodInfo.methodName,
nodeName: breakpoint.nodeName,
nodeParent: breakpoint.nodeParent,
condition: breakpoint.condition,
success: true,
nodePath: node === null || node === void 0 ? void 0 : node.path,
methodName,
nodeName,
nodeParent,
condition,
success,
}));
});
});
clientSocket.on('message', (data) => {
const dataObj = JSON.parse(data);
// message should always have a request and nodePath
const request = dataObj.request;
const nodePath = dataObj.nodePath;
switch (request) {
// client is requesting the methods for a given node path
case 'getMethodsForNode': {
const methodInfo = this.getMethodsForNode(nodePath);
clientSocket.send(JSON.stringify({
request: 'getMethodsForNode',
nodePath,
...methodInfo,
}));
break;
}
// client is requesting to add (or modify) a breakpoint for a given node path/method
case 'placeBreakpoint': {
const methodName = dataObj.methodName;
const condition = dataObj.condition;
this.setBreakpoint(nodePath, methodName, condition, (success) => {
const node = this.nodePathMap.get(nodePath);
const nodeName = node === null || node === void 0 ? void 0 : node.name;
const nodeParent = node === null || node === void 0 ? void 0 : node.parent;
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: node === null || node === void 0 ? void 0 : node.path,
methodName,
nodeName,
nodeParent,
condition,
success,
}));
});
break;
}
// client is requesting to remove a breakpoint by node path and method name
case 'removeBreakpoint': {
const methodName = dataObj.methodName;
this.removeBreakpoint(nodePath, methodName, (success) => {
const node = this.nodePathMap.get(nodePath);
const nodeName = node === null || node === void 0 ? void 0 : node.name;
const nodeParent = node === null || node === void 0 ? void 0 : node.parent;
clientSocket.send(JSON.stringify({
request: 'removeBreakpoint',
nodePath: node === null || node === void 0 ? void 0 : node.path,
methodName,
success,
}));
});
break;
}
default:
throw new Error(`Unknown request type: ${dataObj.request}`);
break;
}
});
// client is requesting to remove a breakpoint by node path and method name
case 'removeBreakpoint': {
const methodName = dataObj.methodName;
const success = await this.removeBreakpoint(nodePath, methodName);
const node = this.nodePathMap.get(nodePath);
clientSocket.send(JSON.stringify({
request: 'removeBreakpoint',
nodePath: node === null || node === void 0 ? void 0 : node.path,
methodName,
success,
}));
break;
}
default:
clientSocket.send(JSON.stringify({
request: dataObj.request,
success: false,
err: new APIFunctionNotFound(dataObj.request).message
}));
}
});
}
});
}

@@ -122,38 +140,8 @@ // Returns the list of methods (and which class they are inherited from) for the

else {
let node = this.nodePathMap.get(nodePath);
const node = this.nodePathMap.get(nodePath);
const nodeName = node.name;
const nodeParent = node.parent;
const setOfMethods = new Set();
const methodsData = [];
do {
const methods = Object.getOwnPropertyNames(node).filter((prop) => {
const nodePropDescriptor = Object.getOwnPropertyDescriptor(node, prop);
// if the prop name is a getter or setter, if we simply just check that it's a function
// that will end up invoking the getter or setter, which could lead to a crash
if (nodePropDescriptor && (nodePropDescriptor.get || nodePropDescriptor.set)) {
return true;
}
return typeof node[prop] === 'function';
});
const className = node.constructor.name;
methods.forEach((methodName) => {
// de-duplicate any inherited methods
if (!setOfMethods.has(methodName)) {
setOfMethods.add(methodName);
methodsData.push({ methodName, className });
}
});
// climb up the inheritance tree until we get to Object
node = Object.getPrototypeOf(node);
} while (!!node && node.constructor.name !== 'Object');
const listOfMethods = nodeManagerHelper_1.Utils.getMethodInfoForObject(node);
return {
listOfMethods: methodsData.sort((a, b) => {
if (a.methodName < b.methodName) {
return -1;
}
if (a.methodName > b.methodName) {
return 1;
}
return 0;
}),
listOfMethods,
nodeName,

@@ -165,3 +153,3 @@ nodeParent

// Uses the node inspector to set a breakpoint using the specified node and the details in breakpointInfo
_setBreakpoint(key, node, breakpointInfo, callback) {
async _setBreakpoint(key, node, breakpointInfo) {
const nodeName = node.name;

@@ -176,4 +164,3 @@ // find the class in the inheritance chain which contains the method or property

console.error(`Could not find method ${breakpointInfo.methodInfo.methodName} in inheritance chain for ${nodeName}`);
callback(false);
return;
return false;
}

@@ -191,60 +178,19 @@ const methodPropertyDescriptor = Object.getOwnPropertyDescriptor(node, breakpointInfo.methodInfo.methodName);

}
this.session.post('Runtime.evaluate', { expression: `global.breakpointMethods.get('${key}')` }, (err, { result }) => {
if (err) {
console.error(`NodeManager - set breakpoint - Error in Runtime.evaluate for: ${key}`, err);
callback(false);
return;
}
console.log(`NodeManager - set breakpoint - got result from Runtime.evaluate for: ${key}`);
const objectId = result.objectId;
this.session.post('Runtime.getProperties', { objectId }, (err, result) => {
if (err) {
console.error(`NodeManager - set breakpoint - Error in Runtime.getProperties for ${key}`, err);
callback(false);
return;
}
console.log(`NodeManager - set breakpoint - got result from Runtime.getProperties for: ${key}`);
const funcObjId = result.internalProperties[0].value.objectId;
// build up the condition for each node that has a breakpoint at this class/method
let condition = '';
let first = true;
[...breakpointInfo.breakpoints].forEach(([key, breakpointData]) => {
if (first) {
first = false;
}
else {
condition = condition + ' || ';
}
condition = condition +
`(this.path === '${breakpointData.nodePath}'` +
(!!breakpointData.condition ? ` && ${breakpointData.condition}` : '')
+ ')';
});
// do the magic!
this.session.post('Debugger.setBreakpointOnFunctionCall', {
objectId: funcObjId,
condition,
}, (err, result) => {
if (err) {
console.error(`NodeManager - set breakpoint - Error in \
Debugger.setBreakpointOnFunctionCall for: ${key}`, err);
callback(false);
return;
}
if (!result) {
console.error(`NodeManager - set breakpoint - Got no result in \
Debugger.setBreakpointOnFunctionCall for: ${key}`);
callback(false);
return;
}
console.log(`NodeManager - set breakpoint - breakpoint set successfully: ${key}`);
breakpointInfo.breakpointId = result.breakpointId; // HACK: types are not defined
callback(true);
});
});
});
const runtimeEvaluate = await nodeManagerHelper_1.RuntimeWrappers.getObjectIdFromRuntimeEvaluate(this.session, key);
if (runtimeEvaluate.err) {
return false;
}
const runtimeProperties = await nodeManagerHelper_1.RuntimeWrappers.getFunctionObjectIdFromRuntimeProperties(this.session, runtimeEvaluate.objectId);
if (runtimeProperties.err) {
return false;
}
// build up the condition for each node that has a breakpoint at this class/method
const condition = nodeManagerHelper_1.Utils.createConditionString(Array.from(breakpointInfo.breakpoints.values()));
const setBreakpointSuccess = await nodeManagerHelper_1.RuntimeWrappers.setBreakpointOnFunctionCall(this.session, runtimeProperties.functionObjectId, condition, breakpointInfo);
return setBreakpointSuccess;
}
// Returns the NodeMethodInfo for the method in the specified node
getNodeMethodInfo(node, methodName) {
return this.getMethodsForNode(node.path).listOfMethods.find((method) => method.methodName === methodName);
return this.getMethodsForNode(node.path)
.listOfMethods.find((method) => method.methodName === methodName);
}

@@ -254,3 +200,3 @@ // Sets a breakpoint on the specified method for the specified node with an optional additional condition.

// _setBreakpoint which will create the breakpoint with the new details provided as input here
setBreakpoint(nodePath, methodName, breakpointCondition, callback) {
async setBreakpoint(nodePath, methodName, breakpointCondition) {
var _a;

@@ -261,3 +207,3 @@ const debugString = `${nodePath}::${methodName}`;

but node does not exist.`);
callback(false);
return false;
}

@@ -270,2 +216,3 @@ else {

but method does not exist`);
return false;
}

@@ -296,25 +243,17 @@ else {

// breakpoint exists for this class/method, need to remove it and then re-create it
this.session.post('Debugger.removeBreakpoint', {
breakpointId: breakpointInfo.breakpointId,
}, (err) => {
if (err) {
console.error(`NodeManager - remove breakpoint - error removing breakpoint for: ${key}`, err);
callback(false);
}
else {
console.log(`NodeManager - remove breakpoint - removed breakpoint successfully for: ${key}`);
this._setBreakpoint(key, node, breakpointInfo, (success) => {
callback(success);
});
}
});
const success = await nodeManagerHelper_1.RuntimeWrappers.removeBreakpointFromFunction(this.session, breakpointInfo);
if (!success) {
return false;
}
else {
return await this._setBreakpoint(key, node, breakpointInfo);
}
}
else {
// breakpoint doesn't exist, so just create it
this._setBreakpoint(key, node, breakpointInfo, (success) => {
if (success) {
this.breakpointInfoMap.set(key, breakpointInfo);
}
callback(success);
});
const success = await this._setBreakpoint(key, node, breakpointInfo);
if (success) {
this.breakpointInfoMap.set(key, breakpointInfo);
}
return success;
}

@@ -324,3 +263,3 @@ }

console.error(`NodeManager - set breakpoint - breakpoint already exists: ${key}`);
callback(false);
return false;
}

@@ -332,8 +271,7 @@ }

// breakpoints set for the same method on the same class the node is inheriting the method from
removeBreakpoint(nodePath, methodName, callback) {
async removeBreakpoint(nodePath, methodName) {
const node = this.nodePathMap.get(nodePath);
if (!node) {
console.error(`NodeManager - remove breakpoint - node does not exist ${nodePath}`);
callback(false);
return;
return false;
}

@@ -343,4 +281,3 @@ const methodInfo = this.getNodeMethodInfo(node, methodName);

console.error(`NodeManager - remove breakpoint - method ${methodName} does not exist on node ${nodePath}`);
callback(false);
return;
return false;
}

@@ -355,27 +292,23 @@ const key = `${methodInfo.className}::${methodInfo.methodName}`;

console.log(`NodeManager - remove breakpoint - found breakpoint id: ${breakpointInfo.breakpointId} for: ${keyAndPath}`);
this.session.post('Debugger.removeBreakpoint', {
breakpointId: breakpointInfo.breakpointId,
}, (err) => {
if (err) {
console.error(`NodeManager - remove breakpoint - error removing breakpoint for: ${keyAndPath}`, err);
callback(false);
const success = await nodeManagerHelper_1.RuntimeWrappers.removeBreakpointFromFunction(this.session, breakpointInfo);
if (!success) {
return false;
}
else {
console.log(`NodeManager - remove breakpoint - removed breakpoint successfully for: ${keyAndPath}`);
breakpointInfo.breakpoints.delete(nodePath);
if (breakpointInfo.breakpoints.size === 0) {
// this was the only breakpoint set for the key
this.breakpointInfoMap.delete(key);
global.breakpointMethods.delete(key);
return true;
}
else {
console.log(`NodeManager - remove breakpoint - removed breakpoint successfully for: ${keyAndPath}`);
breakpointInfo.breakpoints.delete(nodePath);
if (breakpointInfo.breakpoints.size === 0) {
// this was the only breakpoint set for the key
this.breakpointInfoMap.delete(key);
global.breakpointMethods.delete(key);
}
else {
this._setBreakpoint(key, this.nodePathMap.get([...breakpointInfo.breakpoints][0][1].nodePath), breakpointInfo, () => { });
}
callback(true);
return await this._setBreakpoint(key, this.nodePathMap.get([...breakpointInfo.breakpoints][0][1].nodePath), breakpointInfo);
}
});
}
}
else {
console.log(`NodeManager - remove breakpoint - did not find breakpoint for path: ${keyAndPath}`);
callback(false);
return false;
}

@@ -385,4 +318,4 @@ }

console.log(`NodeManager - remove breakpoint - did not find breakpoint id at all: ${keyAndPath}`);
callback(false);
global.breakpointMethods.delete(key);
return false;
}

@@ -401,3 +334,3 @@ }

if (this.nodePathMap.has(path)) {
throw new Error(`Key ${path} already exists! Cannot add new node.`);
throw new DuplicateNodeAdded(path);
}

@@ -404,0 +337,0 @@ else {

@@ -5,38 +5,24 @@ /* eslint-disable no-console */

import {Server} from 'ws';
import {Session, Debugger} from 'inspector';
import {Session} from 'inspector';
import {RuntimeWrappers, Utils} from './nodeManagerHelper';
import {
NodePathKey,
ClassMethodNameKey,
NodeMethodInfo,
BreakpointInfo,
NodeMethodsInfo
} from './nodeManagerTypes';
// Map key that is the path property of a bt node
type NodePathKey = string;
// Map key that is the class plus method name of a bt node method
type ClassMethodNameKey = string;
// the two parts of a ClassMethodNameKey - the className is the class the method comes from
// which might be a super class
interface NodeMethodInfo {
className: string;
methodName: string;
export class DuplicateNodeAdded extends Error {
constructor(path: string) {
super(`Key ${path} already exists! Cannot add new node.`);
}
}
// the information about a breakpoint from one node on a particular class/method
interface BreakpointData {
nodePath: string;
condition?: string;
nodeName?: string;
nodeParent?: string;
export class APIFunctionNotFound extends Error {
constructor(apiFunction: string) {
super(`Unknown request type: ${apiFunction}`);
}
}
// the information about a breakpoint set on a particular class/method (for 1 or more nodes)
interface BreakpointInfo {
methodInfo: NodeMethodInfo,
breakpointId?: Debugger.BreakpointId;
breakpoints: Map<NodePathKey, BreakpointData>,
}
// the information for the methods available for a particuliar node as well as the node name and parent
interface NodeMethodsInfo {
listOfMethods: NodeMethodInfo[];
nodeName: string;
nodeParent: string;
}
// Manages information about what nodes are available in the BT for debugging (nodes must be registered

@@ -65,100 +51,104 @@ // when they become available and unregistered when they are no longer available)

if (process.env.NODE_ENV !== 'test') {
this.server = new Server({
host: 'localhost',
port: 8990,
});
this.server = new Server({
host: 'localhost',
port: 8990,
});
// should be empty but clear everything for good measure
this.breakpointInfoMap.forEach((breakpointInfo, nodePathAndMethodName) => {
this.session.post('Debugger.removeBreakpoint', {
breakpointId: breakpointInfo.breakpointId,
}, () => {
this.breakpointInfoMap.delete(nodePathAndMethodName);
// should be empty but clear everything for good measure
this.breakpointInfoMap.forEach(async (breakpointInfo, nodePathAndMethodName) => {
const success = await RuntimeWrappers.removeBreakpointFromFunction(this.session, breakpointInfo);
if (success) {
this.breakpointInfoMap.delete(nodePathAndMethodName);
}
});
this.breakpointInfoMap.clear();
(<any>global).breakpointMethods.clear();
// setup the connection handler
this.server.on('connection', (clientSocket) => {
// send the current cached breakpoints to the client if the client reconnects
this.breakpointInfoMap.forEach((breakpointInfo) => {
breakpointInfo.breakpoints.forEach((breakpoint) => {
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: breakpoint.nodePath,
methodName: breakpointInfo.methodInfo.methodName,
nodeName: breakpoint.nodeName,
nodeParent: breakpoint.nodeParent,
condition: breakpoint.condition,
success: true,
}));
});
});
this.breakpointInfoMap.clear();
(<any>global).breakpointMethods.clear();
// setup the connection handler
this.server.on('connection', (clientSocket) => {
// send the current cached breakpoints to the client if the client reconnects
this.breakpointInfoMap.forEach((breakpointInfo) => {
breakpointInfo.breakpoints.forEach((breakpoint) => {
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: breakpoint.nodePath,
methodName: breakpointInfo.methodInfo.methodName,
nodeName: breakpoint.nodeName,
nodeParent: breakpoint.nodeParent,
condition: breakpoint.condition,
success: true,
}));
});
});
clientSocket.on('message', async (data: string) => {
const dataObj = JSON.parse(data);
// message should always have a request and nodePath
const request = dataObj.request;
const nodePath = dataObj.nodePath;
switch (request) {
// client is requesting the methods for a given node path
case 'getMethodsForNode': {
let methodInfo;
let success = true;
try {
methodInfo = this.getMethodsForNode(nodePath);
} catch {
success = false;
}
clientSocket.on('message', (data: string) => {
const dataObj = JSON.parse(data);
// message should always have a request and nodePath
const request = dataObj.request;
const nodePath = dataObj.nodePath;
switch (request) {
// client is requesting the methods for a given node path
case 'getMethodsForNode': {
const methodInfo = this.getMethodsForNode(nodePath);
clientSocket.send(JSON.stringify({
request: 'getMethodsForNode',
success,
nodePath,
...methodInfo,
}));
clientSocket.send(JSON.stringify({
request: 'getMethodsForNode',
nodePath,
...methodInfo,
}));
break;
}
// client is requesting to add (or modify) a breakpoint for a given node path/method
case 'placeBreakpoint': {
const methodName = dataObj.methodName;
const condition = dataObj.condition;
break;
}
// client is requesting to add (or modify) a breakpoint for a given node path/method
case 'placeBreakpoint': {
const methodName = dataObj.methodName;
const condition = dataObj.condition;
const success = await this.setBreakpoint(nodePath, methodName, condition);
const node = this.nodePathMap.get(nodePath);
const nodeName = node?.name;
const nodeParent = node?.parent;
this.setBreakpoint(nodePath, methodName, condition, (success) => {
const node = this.nodePathMap.get(nodePath);
const nodeName = node?.name;
const nodeParent = node?.parent;
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: node?.path,
methodName,
nodeName,
nodeParent,
condition,
success,
}));
clientSocket.send(JSON.stringify({
request: 'placeBreakpoint',
nodePath: node?.path,
methodName,
nodeName,
nodeParent,
condition,
success,
}));
});
break;
}
// client is requesting to remove a breakpoint by node path and method name
case 'removeBreakpoint': {
const methodName = dataObj.methodName;
const success = await this.removeBreakpoint(nodePath, methodName);
const node = this.nodePathMap.get(nodePath);
break;
}
// client is requesting to remove a breakpoint by node path and method name
case 'removeBreakpoint': {
const methodName = dataObj.methodName;
this.removeBreakpoint(nodePath, methodName, (success) => {
const node = this.nodePathMap.get(nodePath);
const nodeName = node?.name;
const nodeParent = node?.parent;
clientSocket.send(JSON.stringify({
request: 'removeBreakpoint',
nodePath: node?.path,
methodName,
success,
}));
});
break;
}
default:
throw new Error(`Unknown request type: ${dataObj.request}`);
}
});
clientSocket.send(JSON.stringify({
request: 'removeBreakpoint',
nodePath: node?.path,
methodName,
success,
}));
break;
}
default:
clientSocket.send(JSON.stringify({
request: dataObj.request,
success: false,
err: new APIFunctionNotFound(dataObj.request).message
}));
}
});
}
});
}

@@ -172,39 +162,9 @@

} else {
let node = this.nodePathMap.get(nodePath)!;
const node = this.nodePathMap.get(nodePath)!;
const nodeName = node.name;
const nodeParent = node.parent;
const setOfMethods: Set<string> = new Set();
const methodsData: NodeMethodInfo[] = [];
do {
const methods = Object.getOwnPropertyNames(node).filter((prop) => {
const nodePropDescriptor = Object.getOwnPropertyDescriptor(node, prop);
// if the prop name is a getter or setter, if we simply just check that it's a function
// that will end up invoking the getter or setter, which could lead to a crash
if (nodePropDescriptor && (nodePropDescriptor.get || nodePropDescriptor.set)) {
return true;
}
return typeof (node as any)[prop] === 'function';
});
const className = node.constructor.name;
methods.forEach((methodName) => {
// de-duplicate any inherited methods
if (!setOfMethods.has(methodName)) {
setOfMethods.add(methodName);
methodsData.push({methodName, className});
}
});
// climb up the inheritance tree until we get to Object
node = Object.getPrototypeOf(node);
} while (!!node && node.constructor.name !== 'Object');
const listOfMethods = Utils.getMethodInfoForObject(node);
return {
listOfMethods: methodsData.sort((a, b) => {
if (a.methodName < b.methodName) {
return -1;
}
if (a.methodName > b.methodName) {
return 1;
}
return 0;
}),
listOfMethods,
nodeName,

@@ -217,8 +177,7 @@ nodeParent

// Uses the node inspector to set a breakpoint using the specified node and the details in breakpointInfo
private _setBreakpoint(
private async _setBreakpoint(
key: string,
node: BaseNode<S, E>,
breakpointInfo: BreakpointInfo,
callback: (success: boolean) => void
) {
breakpointInfo: BreakpointInfo
): Promise<boolean> {
const nodeName = node.name;

@@ -234,4 +193,3 @@ // find the class in the inheritance chain which contains the method or property

`Could not find method ${breakpointInfo.methodInfo.methodName} in inheritance chain for ${nodeName}`);
callback(false);
return;
return false;
}

@@ -249,60 +207,20 @@

this.session.post('Runtime.evaluate', {expression: `global.breakpointMethods.get('${key}')`},
(err, {result}) => {
if (err) {
console.error(`NodeManager - set breakpoint - Error in Runtime.evaluate for: ${key}`, err);
callback(false);
return;
}
console.log(`NodeManager - set breakpoint - got result from Runtime.evaluate for: ${key}`);
const objectId = result.objectId;
const runtimeEvaluate = await RuntimeWrappers.getObjectIdFromRuntimeEvaluate(
this.session, key);
if (runtimeEvaluate.err) {
return false;
}
this.session.post('Runtime.getProperties', {objectId}, (err, result) => {
if (err) {
console.error(`NodeManager - set breakpoint - Error in Runtime.getProperties for ${key}`, err);
callback(false);
return;
}
console.log(`NodeManager - set breakpoint - got result from Runtime.getProperties for: ${key}`);
const funcObjId = (<any>result).internalProperties[0].value.objectId;
const runtimeProperties = await RuntimeWrappers.getFunctionObjectIdFromRuntimeProperties(
this.session, runtimeEvaluate.objectId!);
if (runtimeProperties.err) {
return false;
}
// build up the condition for each node that has a breakpoint at this class/method
let condition = '';
let first = true;
[...breakpointInfo.breakpoints].forEach(([key, breakpointData]) => {
if (first) {
first = false;
} else {
condition = condition + ' || ';
}
condition = condition +
`(this.path === '${breakpointData.nodePath}'` +
(!!breakpointData.condition ? ` && ${breakpointData.condition}` : '')
+ ')';
});
// build up the condition for each node that has a breakpoint at this class/method
const condition = Utils.createConditionString(Array.from(breakpointInfo.breakpoints.values()));
// do the magic!
this.session.post('Debugger.setBreakpointOnFunctionCall', {
objectId: funcObjId,
condition,
},
(err, result) => {
if (err) {
console.error(`NodeManager - set breakpoint - Error in \
Debugger.setBreakpointOnFunctionCall for: ${key}`, err);
callback(false);
return;
}
if (!result) {
console.error(`NodeManager - set breakpoint - Got no result in \
Debugger.setBreakpointOnFunctionCall for: ${key}`);
callback(false);
return;
}
console.log(`NodeManager - set breakpoint - breakpoint set successfully: ${key}`);
breakpointInfo.breakpointId = (result as any).breakpointId; // HACK: types are not defined
callback(true);
});
});
});
const setBreakpointSuccess = await RuntimeWrappers.setBreakpointOnFunctionCall(
this.session, runtimeProperties.functionObjectId!, condition, breakpointInfo);
return setBreakpointSuccess;
}

@@ -312,3 +230,4 @@

private getNodeMethodInfo(node: BaseNode<S, E>, methodName: string) {
return this.getMethodsForNode(node.path).listOfMethods.find((method) => method.methodName === methodName);
return this.getMethodsForNode(node.path)
.listOfMethods.find((method) => method.methodName === methodName);
}

@@ -319,8 +238,7 @@

// _setBreakpoint which will create the breakpoint with the new details provided as input here
private setBreakpoint(
private async setBreakpoint(
nodePath: string,
methodName: string,
breakpointCondition: string,
callback: (success: boolean) => void
) {
): Promise<boolean> {
const debugString = `${nodePath}::${methodName}`;

@@ -330,3 +248,3 @@ if (!this.nodePathMap.has(nodePath)) {

but node does not exist.`);
callback(false);
return false;
} else {

@@ -338,2 +256,3 @@ const node = this.nodePathMap.get(nodePath)!;

but method does not exist`);
return false;
} else {

@@ -364,27 +283,19 @@ const key = `${className}::${methodName}`;

// breakpoint exists for this class/method, need to remove it and then re-create it
this.session.post('Debugger.removeBreakpoint', {
breakpointId: breakpointInfo.breakpointId,
}, (err: Error|null) => {
if (err) {
console.error(`NodeManager - remove breakpoint - error removing breakpoint for: ${key}`, err);
callback(false);
} else {
console.log(`NodeManager - remove breakpoint - removed breakpoint successfully for: ${key}`);
this._setBreakpoint(key, node, breakpointInfo!, (success) => {
callback(success);
});
}
});
const success = await RuntimeWrappers.removeBreakpointFromFunction(this.session, breakpointInfo);
if (!success) {
return false;
} else {
return await this._setBreakpoint(key, node, breakpointInfo!);
}
} else {
// breakpoint doesn't exist, so just create it
this._setBreakpoint(key, node, breakpointInfo!, (success) => {
if (success) {
this.breakpointInfoMap.set(key, breakpointInfo!);
}
callback(success);
});
const success = await this._setBreakpoint(key, node, breakpointInfo!);
if (success) {
this.breakpointInfoMap.set(key, breakpointInfo!);
}
return success;
}
} else {
console.error(`NodeManager - set breakpoint - breakpoint already exists: ${key}`);
callback(false);
return false;
}

@@ -397,8 +308,7 @@ }

// breakpoints set for the same method on the same class the node is inheriting the method from
private removeBreakpoint(nodePath: string, methodName: string, callback: (success: boolean) => void) {
private async removeBreakpoint(nodePath: string, methodName: string): Promise<boolean> {
const node = this.nodePathMap.get(nodePath);
if (!node) {
console.error(`NodeManager - remove breakpoint - node does not exist ${nodePath}`);
callback(false);
return;
return false;
}

@@ -408,4 +318,3 @@ const methodInfo = this.getNodeMethodInfo(node, methodName);

console.error(`NodeManager - remove breakpoint - method ${methodName} does not exist on node ${nodePath}`);
callback(false);
return;
return false;
}

@@ -423,30 +332,26 @@ const key = `${methodInfo.className}::${methodInfo.methodName}`;

`NodeManager - remove breakpoint - found breakpoint id: ${breakpointInfo.breakpointId} for: ${keyAndPath}`);
this.session.post('Debugger.removeBreakpoint', {
breakpointId: breakpointInfo.breakpointId,
}, (err: Error|null) => {
if (err) {
console.error(`NodeManager - remove breakpoint - error removing breakpoint for: ${keyAndPath}`, err);
callback(false);
const success = await RuntimeWrappers.removeBreakpointFromFunction(this.session, breakpointInfo);
if (!success) {
return false;
} else {
console.log(`NodeManager - remove breakpoint - removed breakpoint successfully for: ${keyAndPath}`);
breakpointInfo.breakpoints.delete(nodePath);
if (breakpointInfo.breakpoints.size === 0) {
// this was the only breakpoint set for the key
this.breakpointInfoMap.delete(key);
(<any>global).breakpointMethods.delete(key);
return true;
} else {
console.log(`NodeManager - remove breakpoint - removed breakpoint successfully for: ${keyAndPath}`);
breakpointInfo.breakpoints.delete(nodePath);
if (breakpointInfo.breakpoints.size === 0) {
// this was the only breakpoint set for the key
this.breakpointInfoMap.delete(key);
(<any>global).breakpointMethods.delete(key);
} else {
this._setBreakpoint(
key, this.nodePathMap.get([...breakpointInfo.breakpoints][0][1].nodePath)!, breakpointInfo, () => {});
}
callback(true);
return await this._setBreakpoint(
key, this.nodePathMap.get([...breakpointInfo.breakpoints][0][1].nodePath)!, breakpointInfo);
}
});
}
} else {
console.log(`NodeManager - remove breakpoint - did not find breakpoint for path: ${keyAndPath}`);
callback(false);
return false;
}
} else {
console.log(`NodeManager - remove breakpoint - did not find breakpoint id at all: ${keyAndPath}`);
callback(false);
(<any>global).breakpointMethods.delete(key);
return false;
}

@@ -467,3 +372,3 @@ }

if (this.nodePathMap.has(path)) {
throw new Error(`Key ${path} already exists! Cannot add new node.`);
throw new DuplicateNodeAdded(path);
} else {

@@ -470,0 +375,0 @@ this.nodePathMap.set(path, node);

@@ -100,3 +100,3 @@ {

"test:no-cover": "NODE_ENV=test mocha",
"test:debug": "npm run test:no-cover -- --debug-brk test",
"test:debug": "npm run test:no-cover -- --inspect-brk test",
"coverage": "NODE_ENV=test nyc report --reporter=text-lcov \u003e coverage.lcov \u0026\u0026 codecov",

@@ -106,3 +106,3 @@ "prepublish": "npm-run-all compile"

"types": "dist/index.d.ts",
"version": "3.6.0-btvBreakpoints.9"
"version": "3.6.0-btvBreakpoints.10"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc