-
Notifications
You must be signed in to change notification settings - Fork 30.6k
/
Copy pathinspector.js
110 lines (99 loc) Β· 3.58 KB
/
inspector.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
'use strict';
const {
ArrayPrototypeSome,
ArrayPrototypePushApply,
FunctionPrototypeBind,
ObjectDefineProperty,
ObjectKeys,
ObjectPrototypeHasOwnProperty,
RegExpPrototypeExec,
SafeWeakMap,
} = primordials;
const { validatePort } = require('internal/validators');
const kMinPort = 1024;
const kMaxPort = 65535;
const kInspectArgRegex = /--inspect(?:-brk|-port)?|--debug-port/;
const kInspectMsgRegex = /Debugger listening on ws:\/\/\[?(.+?)\]?:(\d+)\/|For help, see: https:\/\/nodejs\.org\/en\/docs\/inspector|Debugger attached|Waiting for the debugger to disconnect\.\.\./;
const _isUsingInspector = new SafeWeakMap();
function isUsingInspector(execArgv = process.execArgv) {
if (!_isUsingInspector.has(execArgv)) {
_isUsingInspector.set(execArgv,
ArrayPrototypeSome(execArgv, (arg) => RegExpPrototypeExec(kInspectArgRegex, arg) !== null) ||
RegExpPrototypeExec(kInspectArgRegex, process.env.NODE_OPTIONS) !== null);
}
return _isUsingInspector.get(execArgv);
}
let debugPortOffset = 1;
function getInspectPort(inspectPort) {
if (typeof inspectPort === 'function') {
inspectPort = inspectPort();
} else if (inspectPort == null) {
inspectPort = process.debugPort + debugPortOffset;
if (inspectPort > kMaxPort)
inspectPort = inspectPort - kMaxPort + kMinPort - 1;
debugPortOffset++;
}
validatePort(inspectPort);
return inspectPort;
}
let session;
function sendInspectorCommand(cb, onError) {
const { hasInspector } = internalBinding('config');
if (!hasInspector) return onError();
const inspector = require('inspector');
if (session === undefined) session = new inspector.Session();
session.connect();
try {
return cb(session);
} finally {
session.disconnect();
}
}
function isInspectorMessage(string) {
return isUsingInspector() && RegExpPrototypeExec(kInspectMsgRegex, string) !== null;
}
// Create a special require function for the inspector command line API
function installConsoleExtensions(commandLineApi) {
if (commandLineApi.require) { return; }
const { tryGetCwd } = require('internal/process/execution');
const CJSModule = require('internal/modules/cjs/loader').Module;
const { makeRequireFunction } = require('internal/modules/helpers');
const consoleAPIModule = new CJSModule('<inspector console>');
const cwd = tryGetCwd();
consoleAPIModule.paths = [];
ArrayPrototypePushApply(consoleAPIModule.paths, CJSModule._nodeModulePaths(cwd));
ArrayPrototypePushApply(consoleAPIModule.paths, CJSModule.globalPaths);
commandLineApi.require = makeRequireFunction(consoleAPIModule);
}
// Wrap a console implemented by Node.js with features from the VM inspector
function wrapConsole(consoleFromNode) {
const { consoleCall, console: consoleFromVM } = internalBinding('inspector');
for (const key of ObjectKeys(consoleFromVM)) {
// If global console has the same method as inspector console,
// then wrap these two methods into one. Native wrapper will preserve
// the original stack.
if (ObjectPrototypeHasOwnProperty(consoleFromNode, key)) {
consoleFromNode[key] = FunctionPrototypeBind(
consoleCall,
consoleFromNode,
consoleFromVM[key],
consoleFromNode[key],
);
ObjectDefineProperty(consoleFromNode[key], 'name', {
__proto__: null,
value: key,
});
} else {
// Add additional console APIs from the inspector
consoleFromNode[key] = consoleFromVM[key];
}
}
}
module.exports = {
getInspectPort,
installConsoleExtensions,
isInspectorMessage,
isUsingInspector,
sendInspectorCommand,
wrapConsole,
};