@mt0926/node-network-devtools 0.1.3 → 0.3.0
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/README.md +96 -1
- package/dist/cjs/adapters/axios.js +2 -0
- package/dist/cjs/adapters/axios.js.map +1 -0
- package/dist/cjs/adapters/nextjs.js +133 -0
- package/dist/cjs/adapters/nextjs.js.map +1 -0
- package/dist/cjs/cli.js +223 -0
- package/dist/cjs/cli.js.map +1 -0
- package/dist/cjs/config.js +150 -0
- package/dist/cjs/config.js.map +1 -0
- package/dist/cjs/context/context-manager.js +139 -0
- package/dist/cjs/context/context-manager.js.map +1 -0
- package/dist/cjs/gui/browser-detector.js +263 -0
- package/dist/cjs/gui/browser-detector.js.map +1 -0
- package/dist/cjs/gui/browser-launcher.js +365 -0
- package/dist/cjs/gui/browser-launcher.js.map +1 -0
- package/dist/cjs/gui/event-bridge.js +197 -0
- package/dist/cjs/gui/event-bridge.js.map +1 -0
- package/dist/cjs/gui/port-utils.js +85 -0
- package/dist/cjs/gui/port-utils.js.map +1 -0
- package/dist/cjs/gui/server.js +251 -0
- package/dist/cjs/gui/server.js.map +1 -0
- package/dist/cjs/gui/websocket-hub.js +336 -0
- package/dist/cjs/gui/websocket-hub.js.map +1 -0
- package/dist/cjs/index.js +170 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/interceptors/http-patcher.js +275 -0
- package/dist/cjs/interceptors/http-patcher.js.map +1 -0
- package/dist/cjs/interceptors/undici-patcher.js +362 -0
- package/dist/cjs/interceptors/undici-patcher.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/register.js +95 -0
- package/dist/cjs/register.js.map +1 -0
- package/dist/cjs/store/ring-buffer.js +241 -0
- package/dist/cjs/store/ring-buffer.js.map +1 -0
- package/dist/cjs/test-setup.js +8 -0
- package/dist/cjs/test-setup.js.map +1 -0
- package/dist/cjs/utils/module-compat.js +83 -0
- package/dist/cjs/utils/module-compat.js.map +1 -0
- package/dist/esm/cli.js +22 -4
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/gui/server.js +25 -6
- package/dist/esm/gui/server.js.map +1 -1
- package/dist/esm/interceptors/undici-patcher.js +9 -4
- package/dist/esm/interceptors/undici-patcher.js.map +1 -1
- package/dist/esm/utils/module-compat.js +78 -0
- package/dist/esm/utils/module-compat.js.map +1 -0
- package/dist/types/gui/server.d.ts.map +1 -1
- package/dist/types/interceptors/undici-patcher.d.ts.map +1 -1
- package/dist/types/utils/module-compat.d.ts +34 -0
- package/dist/types/utils/module-compat.d.ts.map +1 -0
- package/package.json +22 -8
package/README.md
CHANGED
|
@@ -70,7 +70,9 @@ pnpm add node-network-devtools puppeteer
|
|
|
70
70
|
yarn add node-network-devtools puppeteer
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
**Note**:
|
|
73
|
+
**Note**:
|
|
74
|
+
- Puppeteer is required for the GUI browser window. If not installed, you'll see a friendly error message with installation instructions.
|
|
75
|
+
- This package supports both **ESM** and **CommonJS** module systems. See [Module System Support](#module-system-support) for details.
|
|
74
76
|
|
|
75
77
|
### Usage
|
|
76
78
|
|
|
@@ -86,12 +88,19 @@ The CLI automatically injects the interceptor and opens the GUI.
|
|
|
86
88
|
|
|
87
89
|
#### Method 2: Using `-r` flag
|
|
88
90
|
|
|
91
|
+
**ESM:**
|
|
92
|
+
```bash
|
|
93
|
+
node --import node-network-devtools/register your-script.js
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**CommonJS:**
|
|
89
97
|
```bash
|
|
90
98
|
node -r node-network-devtools/register your-script.js
|
|
91
99
|
```
|
|
92
100
|
|
|
93
101
|
#### Method 3: Programmatic
|
|
94
102
|
|
|
103
|
+
**ESM:**
|
|
95
104
|
```typescript
|
|
96
105
|
import { install } from 'node-network-devtools';
|
|
97
106
|
|
|
@@ -103,6 +112,20 @@ const app = express();
|
|
|
103
112
|
// ...
|
|
104
113
|
```
|
|
105
114
|
|
|
115
|
+
**CommonJS:**
|
|
116
|
+
```javascript
|
|
117
|
+
const { install } = require('node-network-devtools');
|
|
118
|
+
|
|
119
|
+
(async () => {
|
|
120
|
+
await install();
|
|
121
|
+
|
|
122
|
+
// Your application code
|
|
123
|
+
const express = require('express');
|
|
124
|
+
const app = express();
|
|
125
|
+
// ...
|
|
126
|
+
})();
|
|
127
|
+
```
|
|
128
|
+
|
|
106
129
|
### Viewing Requests
|
|
107
130
|
|
|
108
131
|
After starting your application:
|
|
@@ -257,6 +280,7 @@ Or configure in `package.json`:
|
|
|
257
280
|
|
|
258
281
|
### Express
|
|
259
282
|
|
|
283
|
+
**ESM:**
|
|
260
284
|
```typescript
|
|
261
285
|
import express from 'express';
|
|
262
286
|
import { install } from 'node-network-devtools';
|
|
@@ -267,10 +291,80 @@ const app = express();
|
|
|
267
291
|
// Your routes...
|
|
268
292
|
```
|
|
269
293
|
|
|
294
|
+
**CommonJS:**
|
|
295
|
+
```javascript
|
|
296
|
+
const express = require('express');
|
|
297
|
+
const { install } = require('node-network-devtools');
|
|
298
|
+
|
|
299
|
+
(async () => {
|
|
300
|
+
await install();
|
|
301
|
+
|
|
302
|
+
const app = express();
|
|
303
|
+
// Your routes...
|
|
304
|
+
})();
|
|
305
|
+
```
|
|
306
|
+
|
|
270
307
|
### Other Frameworks
|
|
271
308
|
|
|
272
309
|
Works with any Node.js framework! Just install the interceptor before your application code.
|
|
273
310
|
|
|
311
|
+
## 📦 Module System Support
|
|
312
|
+
|
|
313
|
+
This package supports both **ESM (ECMAScript Modules)** and **CommonJS** module systems, making it compatible with all Node.js projects.
|
|
314
|
+
|
|
315
|
+
### ESM (ECMAScript Modules)
|
|
316
|
+
|
|
317
|
+
Use `import` statements in projects with `"type": "module"` in package.json or `.mjs` files:
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { install, getRequestStore } from 'node-network-devtools';
|
|
321
|
+
import 'node-network-devtools/register';
|
|
322
|
+
|
|
323
|
+
await install();
|
|
324
|
+
const store = getRequestStore();
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### CommonJS
|
|
328
|
+
|
|
329
|
+
Use `require()` statements in traditional Node.js projects or `.cjs` files:
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
const { install, getRequestStore } = require('node-network-devtools');
|
|
333
|
+
require('node-network-devtools/register');
|
|
334
|
+
|
|
335
|
+
(async () => {
|
|
336
|
+
await install();
|
|
337
|
+
const store = getRequestStore();
|
|
338
|
+
})();
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### TypeScript
|
|
342
|
+
|
|
343
|
+
Full TypeScript support with type definitions for both module systems:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
import type { Config, IRequestStore } from 'node-network-devtools';
|
|
347
|
+
import { install, getRequestStore } from 'node-network-devtools';
|
|
348
|
+
|
|
349
|
+
const config: Config = {
|
|
350
|
+
maxRequests: 500,
|
|
351
|
+
guiEnabled: true,
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
await install();
|
|
355
|
+
const store: IRequestStore = getRequestStore();
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Module Resolution
|
|
359
|
+
|
|
360
|
+
The package uses Node.js [Conditional Exports](https://nodejs.org/api/packages.html#conditional-exports) to automatically provide the correct module format:
|
|
361
|
+
|
|
362
|
+
- **ESM projects**: Resolves to `dist/esm/index.js`
|
|
363
|
+
- **CommonJS projects**: Resolves to `dist/cjs/index.js`
|
|
364
|
+
- **TypeScript**: Uses `dist/types/index.d.ts` for both
|
|
365
|
+
|
|
366
|
+
No configuration needed - it just works! 🎉
|
|
367
|
+
|
|
274
368
|
## 📚 API Reference
|
|
275
369
|
|
|
276
370
|
### Main Exports
|
|
@@ -320,6 +414,7 @@ Check the [examples](./examples) directory for more usage examples:
|
|
|
320
414
|
|
|
321
415
|
- [basic-http](./examples/basic-http) - Basic HTTP request monitoring
|
|
322
416
|
- [fetch-api](./examples/fetch-api) - Fetch API monitoring
|
|
417
|
+
- [commonjs-usage](./examples/commonjs-usage) - CommonJS module usage
|
|
323
418
|
- [request-tracing](./examples/request-tracing) - Request tracing
|
|
324
419
|
- [express-server](./examples/express-server) - Express server example
|
|
325
420
|
- [programmatic-api](./examples/programmatic-api) - Programmatic API usage
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axios.js","sourceRoot":"","sources":["../../../src/adapters/axios.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Next.js 框架适配器
|
|
4
|
+
*
|
|
5
|
+
* 确保与 Next.js 的 Data Cache 和 Request Memoization 兼容
|
|
6
|
+
* 保留 next.revalidate、next.tags 等选项
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.NextJsAdapter = void 0;
|
|
10
|
+
exports.isNextJsEnvironment = isNextJsEnvironment;
|
|
11
|
+
exports.getCurrentRoute = getCurrentRoute;
|
|
12
|
+
exports.runWithRoute = runWithRoute;
|
|
13
|
+
exports.runWithRouteAsync = runWithRouteAsync;
|
|
14
|
+
exports.extractNextJsOptions = extractNextJsOptions;
|
|
15
|
+
exports.extractNextJsMetadata = extractNextJsMetadata;
|
|
16
|
+
exports.createInstrumentationConfig = createInstrumentationConfig;
|
|
17
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
18
|
+
// 用于存储当前路由信息的 AsyncLocalStorage
|
|
19
|
+
const routeStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
20
|
+
/**
|
|
21
|
+
* 检测是否在 Next.js 环境中
|
|
22
|
+
*/
|
|
23
|
+
function isNextJsEnvironment() {
|
|
24
|
+
// 检查 Next.js 特有的环境变量
|
|
25
|
+
return !!(process.env.NEXT_RUNTIME ||
|
|
26
|
+
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT ||
|
|
27
|
+
process.env.NEXT_DEPLOYMENT_ID);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 获取当前路由信息
|
|
31
|
+
*/
|
|
32
|
+
function getCurrentRoute() {
|
|
33
|
+
return routeStorage.getStore();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 在指定路由上下文中运行函数
|
|
37
|
+
*/
|
|
38
|
+
function runWithRoute(route, type, fn) {
|
|
39
|
+
return routeStorage.run({ route, type }, fn);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 异步版本的 runWithRoute
|
|
43
|
+
*/
|
|
44
|
+
async function runWithRouteAsync(route, type, fn) {
|
|
45
|
+
return routeStorage.run({ route, type }, fn);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 提取 Next.js fetch 选项
|
|
49
|
+
*/
|
|
50
|
+
function extractNextJsOptions(init) {
|
|
51
|
+
if (!init)
|
|
52
|
+
return undefined;
|
|
53
|
+
const options = {};
|
|
54
|
+
// 提取 next 选项
|
|
55
|
+
if ('next' in init && init.next) {
|
|
56
|
+
const nextOpts = init.next;
|
|
57
|
+
options.next = {
|
|
58
|
+
revalidate: nextOpts.revalidate,
|
|
59
|
+
tags: nextOpts.tags,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// 提取 cache 选项
|
|
63
|
+
if ('cache' in init && init.cache) {
|
|
64
|
+
options.cache = init.cache;
|
|
65
|
+
}
|
|
66
|
+
return Object.keys(options).length > 0 ? options : undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 从请求中提取 Next.js 元数据
|
|
70
|
+
*/
|
|
71
|
+
function extractNextJsMetadata(init, responseHeaders) {
|
|
72
|
+
const metadata = {};
|
|
73
|
+
// 获取当前路由
|
|
74
|
+
const routeInfo = getCurrentRoute();
|
|
75
|
+
if (routeInfo) {
|
|
76
|
+
metadata.route = routeInfo.route;
|
|
77
|
+
metadata.requestType = routeInfo.type;
|
|
78
|
+
}
|
|
79
|
+
// 提取 fetch 选项
|
|
80
|
+
const nextOptions = extractNextJsOptions(init);
|
|
81
|
+
if (nextOptions?.next) {
|
|
82
|
+
metadata.revalidate = nextOptions.next.revalidate;
|
|
83
|
+
metadata.tags = nextOptions.next.tags;
|
|
84
|
+
}
|
|
85
|
+
// 从响应头提取缓存状态
|
|
86
|
+
if (responseHeaders) {
|
|
87
|
+
const cacheStatus = getHeader(responseHeaders, 'x-nextjs-cache');
|
|
88
|
+
if (cacheStatus) {
|
|
89
|
+
metadata.cacheStatus = cacheStatus;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return metadata;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 辅助函数:获取响应头
|
|
96
|
+
*/
|
|
97
|
+
function getHeader(headers, name) {
|
|
98
|
+
if (headers instanceof Headers) {
|
|
99
|
+
return headers.get(name) ?? undefined;
|
|
100
|
+
}
|
|
101
|
+
return headers[name] || headers[name.toLowerCase()];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 创建 Next.js instrumentation 配置
|
|
105
|
+
*/
|
|
106
|
+
function createInstrumentationConfig() {
|
|
107
|
+
return `// instrumentation.ts
|
|
108
|
+
// 将此文件放在 Next.js 项目根目录
|
|
109
|
+
|
|
110
|
+
export async function register() {
|
|
111
|
+
// 仅在服务端运行
|
|
112
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
113
|
+
// 动态导入以避免客户端打包
|
|
114
|
+
const { install } = await import('node-network-devtools');
|
|
115
|
+
await install();
|
|
116
|
+
console.log('[node-network-devtools] 已在 Next.js 服务端初始化');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Next.js 适配器对象
|
|
123
|
+
*/
|
|
124
|
+
exports.NextJsAdapter = {
|
|
125
|
+
isNextJsEnvironment,
|
|
126
|
+
getCurrentRoute,
|
|
127
|
+
runWithRoute,
|
|
128
|
+
runWithRouteAsync,
|
|
129
|
+
extractNextJsOptions,
|
|
130
|
+
extractNextJsMetadata,
|
|
131
|
+
createInstrumentationConfig,
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=nextjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../../src/adapters/nextjs.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/cli.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* CLI 入口
|
|
5
|
+
*
|
|
6
|
+
* 使用方式:npx node-network-devtools your-script.js [args...]
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const node_child_process_1 = require("node:child_process");
|
|
10
|
+
const node_path_1 = require("node:path");
|
|
11
|
+
const node_url_1 = require("node:url");
|
|
12
|
+
const node_path_2 = require("node:path");
|
|
13
|
+
// 获取当前文件的 __filename 和 __dirname
|
|
14
|
+
// 在 ESM 中使用 import.meta.url,在 CommonJS 中使用全局变量
|
|
15
|
+
let currentFilename;
|
|
16
|
+
let currentDirname;
|
|
17
|
+
// 检测是否在 CommonJS 环境中
|
|
18
|
+
// @ts-ignore - __filename 在 CommonJS 中可用
|
|
19
|
+
if (typeof __filename !== 'undefined') {
|
|
20
|
+
// CommonJS 环境
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
currentFilename = __filename;
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
currentDirname = __dirname;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// ESM 环境
|
|
28
|
+
// @ts-ignore - import.meta 在 ESM 中可用
|
|
29
|
+
currentFilename = (0, node_url_1.fileURLToPath)(import.meta.url);
|
|
30
|
+
currentDirname = (0, node_path_2.dirname)(currentFilename);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 输出帮助信息
|
|
34
|
+
*/
|
|
35
|
+
function printHelp() {
|
|
36
|
+
console.log(`
|
|
37
|
+
\x1b[36mnode-network-devtools\x1b[0m - Node.js 网络请求监听工具
|
|
38
|
+
|
|
39
|
+
\x1b[33m用法:\x1b[0m
|
|
40
|
+
npx node-network-devtools [选项] <脚本> [脚本参数...]
|
|
41
|
+
|
|
42
|
+
\x1b[33m选项:\x1b[0m
|
|
43
|
+
--help, -h 显示帮助信息
|
|
44
|
+
--version, -v 显示版本号
|
|
45
|
+
--inspect-port=PORT 指定 Inspector 端口(默认: 9229)
|
|
46
|
+
--inspect-brk 在脚本开始时暂停执行
|
|
47
|
+
--gui 启用 Web GUI(默认: false)
|
|
48
|
+
--gui-port=PORT 指定 GUI 端口(默认: auto)
|
|
49
|
+
--ws-port=PORT 指定 WebSocket 端口(默认: auto)
|
|
50
|
+
--no-open 不自动打开浏览器
|
|
51
|
+
|
|
52
|
+
\x1b[33m示例:\x1b[0m
|
|
53
|
+
npx node-network-devtools server.js
|
|
54
|
+
npx node-network-devtools --gui server.js
|
|
55
|
+
npx node-network-devtools --gui --gui-port=8080 app.js
|
|
56
|
+
npx node-network-devtools --inspect-port=9230 app.js
|
|
57
|
+
npx node-network-devtools --inspect-brk test.js
|
|
58
|
+
|
|
59
|
+
\x1b[33m环境变量:\x1b[0m
|
|
60
|
+
NND_MAX_REQUESTS 最大存储请求数(默认: 1000)
|
|
61
|
+
NND_MAX_BODY_SIZE 最大 body 大小(默认: 1048576)
|
|
62
|
+
NND_INTERCEPT_HTTP 是否拦截 http/https(默认: true)
|
|
63
|
+
NND_INTERCEPT_UNDICI 是否拦截 undici/fetch(默认: true)
|
|
64
|
+
NND_REDACT_HEADERS 要脱敏的头(逗号分隔,默认: authorization,cookie)
|
|
65
|
+
NND_GUI_ENABLED 是否启用 GUI(默认: false)
|
|
66
|
+
NND_GUI_PORT GUI 端口(默认: auto)
|
|
67
|
+
NND_WS_PORT WebSocket 端口(默认: auto)
|
|
68
|
+
NND_AUTO_OPEN 是否自动打开浏览器(默认: true)
|
|
69
|
+
|
|
70
|
+
\x1b[33m说明:\x1b[0m
|
|
71
|
+
此工具会自动添加 --inspect 和 --experimental-network-inspection 标志。
|
|
72
|
+
启动后,打开 Chrome DevTools (chrome://inspect) 即可查看网络请求。
|
|
73
|
+
使用 --gui 选项可以启用内置的 Web GUI 界面。
|
|
74
|
+
|
|
75
|
+
\x1b[33m注意:\x1b[0m
|
|
76
|
+
Network 面板功能需要 Node.js 20.18.0+ 版本。
|
|
77
|
+
Chrome DevTools Network 面板目前可能还不支持显示这些事件。
|
|
78
|
+
请求数据仍会被捕获并可通过编程 API 或控制台日志访问。
|
|
79
|
+
`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 输出版本号
|
|
83
|
+
*/
|
|
84
|
+
function printVersion() {
|
|
85
|
+
// 从 package.json 读取版本号
|
|
86
|
+
console.log('0.1.0');
|
|
87
|
+
}
|
|
88
|
+
function parseArgs(args) {
|
|
89
|
+
const result = {
|
|
90
|
+
help: false,
|
|
91
|
+
version: false,
|
|
92
|
+
inspectPort: 9229,
|
|
93
|
+
inspectBrk: false,
|
|
94
|
+
gui: false,
|
|
95
|
+
guiPort: 'auto',
|
|
96
|
+
wsPort: 'auto',
|
|
97
|
+
autoOpen: true,
|
|
98
|
+
script: null,
|
|
99
|
+
scriptArgs: [],
|
|
100
|
+
};
|
|
101
|
+
let i = 0;
|
|
102
|
+
while (i < args.length) {
|
|
103
|
+
const arg = args[i];
|
|
104
|
+
if (arg === '--help' || arg === '-h') {
|
|
105
|
+
result.help = true;
|
|
106
|
+
}
|
|
107
|
+
else if (arg === '--version' || arg === '-v') {
|
|
108
|
+
result.version = true;
|
|
109
|
+
}
|
|
110
|
+
else if (arg === '--inspect-brk') {
|
|
111
|
+
result.inspectBrk = true;
|
|
112
|
+
}
|
|
113
|
+
else if (arg.startsWith('--inspect-port=')) {
|
|
114
|
+
result.inspectPort = parseInt(arg.split('=')[1], 10) || 9229;
|
|
115
|
+
}
|
|
116
|
+
else if (arg === '--gui') {
|
|
117
|
+
result.gui = true;
|
|
118
|
+
}
|
|
119
|
+
else if (arg.startsWith('--gui-port=')) {
|
|
120
|
+
const port = parseInt(arg.split('=')[1], 10);
|
|
121
|
+
result.guiPort = isNaN(port) ? 'auto' : port;
|
|
122
|
+
}
|
|
123
|
+
else if (arg.startsWith('--ws-port=')) {
|
|
124
|
+
const port = parseInt(arg.split('=')[1], 10);
|
|
125
|
+
result.wsPort = isNaN(port) ? 'auto' : port;
|
|
126
|
+
}
|
|
127
|
+
else if (arg === '--no-open') {
|
|
128
|
+
result.autoOpen = false;
|
|
129
|
+
}
|
|
130
|
+
else if (!arg.startsWith('-')) {
|
|
131
|
+
// 第一个非选项参数是脚本路径
|
|
132
|
+
result.script = arg;
|
|
133
|
+
result.scriptArgs = args.slice(i + 1);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
i++;
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 主函数
|
|
142
|
+
*/
|
|
143
|
+
function main() {
|
|
144
|
+
const args = process.argv.slice(2);
|
|
145
|
+
const parsed = parseArgs(args);
|
|
146
|
+
if (parsed.help) {
|
|
147
|
+
printHelp();
|
|
148
|
+
process.exit(0);
|
|
149
|
+
}
|
|
150
|
+
if (parsed.version) {
|
|
151
|
+
printVersion();
|
|
152
|
+
process.exit(0);
|
|
153
|
+
}
|
|
154
|
+
if (!parsed.script) {
|
|
155
|
+
console.error('\x1b[31m错误:\x1b[0m 请指定要运行的脚本');
|
|
156
|
+
console.error('使用 --help 查看帮助信息');
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
// 解析脚本路径
|
|
160
|
+
const scriptPath = (0, node_path_1.resolve)(process.cwd(), parsed.script);
|
|
161
|
+
// 构建 Node.js 参数
|
|
162
|
+
const nodeArgs = [];
|
|
163
|
+
// 添加 inspect 标志
|
|
164
|
+
if (parsed.inspectBrk) {
|
|
165
|
+
nodeArgs.push(`--inspect-brk=${parsed.inspectPort}`);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
nodeArgs.push(`--inspect=${parsed.inspectPort}`);
|
|
169
|
+
}
|
|
170
|
+
// 添加实验性网络检查标志(Node.js 20.18.0+)
|
|
171
|
+
nodeArgs.push('--experimental-network-inspection');
|
|
172
|
+
// 添加 register 入口
|
|
173
|
+
// 计算 register.js 的路径(相对于 CLI 脚本)
|
|
174
|
+
const registerPath = (0, node_path_1.resolve)(currentDirname, 'register.js');
|
|
175
|
+
nodeArgs.push('--import', registerPath);
|
|
176
|
+
// 添加用户脚本和参数
|
|
177
|
+
nodeArgs.push(scriptPath, ...parsed.scriptArgs);
|
|
178
|
+
// 设置 GUI 相关环境变量
|
|
179
|
+
const env = { ...process.env };
|
|
180
|
+
if (parsed.gui) {
|
|
181
|
+
env.NND_GUI_ENABLED = 'true';
|
|
182
|
+
if (parsed.guiPort !== 'auto') {
|
|
183
|
+
env.NND_GUI_PORT = String(parsed.guiPort);
|
|
184
|
+
}
|
|
185
|
+
if (parsed.wsPort !== 'auto') {
|
|
186
|
+
env.NND_WS_PORT = String(parsed.wsPort);
|
|
187
|
+
}
|
|
188
|
+
env.NND_AUTO_OPEN = parsed.autoOpen ? 'true' : 'false';
|
|
189
|
+
}
|
|
190
|
+
console.log(`\x1b[36m[node-network-devtools]\x1b[0m 启动脚本: ${parsed.script}`);
|
|
191
|
+
console.log(`\x1b[36m[node-network-devtools]\x1b[0m Inspector 端口: ${parsed.inspectPort}`);
|
|
192
|
+
console.log(`\x1b[36m[node-network-devtools]\x1b[0m 实验性网络检查已启用`);
|
|
193
|
+
if (parsed.gui) {
|
|
194
|
+
console.log(`\x1b[36m[node-network-devtools]\x1b[0m Web GUI 已启用`);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
console.log(`\x1b[36m[node-network-devtools]\x1b[0m 打开 chrome://inspect 查看网络请求`);
|
|
198
|
+
}
|
|
199
|
+
console.log('');
|
|
200
|
+
// 启动子进程
|
|
201
|
+
const child = (0, node_child_process_1.spawn)('node', nodeArgs, {
|
|
202
|
+
stdio: 'inherit',
|
|
203
|
+
env,
|
|
204
|
+
});
|
|
205
|
+
// 转发退出码
|
|
206
|
+
child.on('exit', (code) => {
|
|
207
|
+
process.exit(code ?? 0);
|
|
208
|
+
});
|
|
209
|
+
// 处理错误
|
|
210
|
+
child.on('error', (error) => {
|
|
211
|
+
console.error(`\x1b[31m错误:\x1b[0m 无法启动脚本: ${error.message}`);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
});
|
|
214
|
+
// 处理信号
|
|
215
|
+
process.on('SIGINT', () => {
|
|
216
|
+
child.kill('SIGINT');
|
|
217
|
+
});
|
|
218
|
+
process.on('SIGTERM', () => {
|
|
219
|
+
child.kill('SIGTERM');
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
main();
|
|
223
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 配置管理模块
|
|
4
|
+
*
|
|
5
|
+
* 支持通过环境变量和编程方式配置工具行为
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.getConfig = getConfig;
|
|
9
|
+
exports.setConfig = setConfig;
|
|
10
|
+
exports.resetConfig = resetConfig;
|
|
11
|
+
exports.getDefaultConfig = getDefaultConfig;
|
|
12
|
+
/**
|
|
13
|
+
* 默认配置
|
|
14
|
+
*/
|
|
15
|
+
const defaultConfig = {
|
|
16
|
+
maxRequests: 1000,
|
|
17
|
+
maxBodySize: 1024 * 1024, // 1MB
|
|
18
|
+
interceptHttp: true,
|
|
19
|
+
interceptUndici: true,
|
|
20
|
+
ignoreUrls: [],
|
|
21
|
+
redactHeaders: ['authorization', 'cookie'],
|
|
22
|
+
disableBodyCapture: false,
|
|
23
|
+
// GUI 配置默认值
|
|
24
|
+
guiEnabled: true,
|
|
25
|
+
guiPort: 'auto',
|
|
26
|
+
wsPort: 'auto',
|
|
27
|
+
guiHost: '127.0.0.1',
|
|
28
|
+
autoOpen: true,
|
|
29
|
+
// 浏览器窗口默认配置
|
|
30
|
+
browserWindowSize: {
|
|
31
|
+
width: 800,
|
|
32
|
+
height: 600,
|
|
33
|
+
},
|
|
34
|
+
browserWindowTitle: 'Node Network DevTools',
|
|
35
|
+
browserPath: undefined,
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* 当前配置(合并后的结果)
|
|
39
|
+
*/
|
|
40
|
+
let currentConfig = { ...defaultConfig };
|
|
41
|
+
/**
|
|
42
|
+
* 从环境变量解析布尔值
|
|
43
|
+
*/
|
|
44
|
+
function parseEnvBoolean(value, defaultValue) {
|
|
45
|
+
if (value === undefined)
|
|
46
|
+
return defaultValue;
|
|
47
|
+
const lower = value.toLowerCase();
|
|
48
|
+
if (lower === 'true' || lower === '1' || lower === 'yes')
|
|
49
|
+
return true;
|
|
50
|
+
if (lower === 'false' || lower === '0' || lower === 'no')
|
|
51
|
+
return false;
|
|
52
|
+
return defaultValue;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 从环境变量解析数字
|
|
56
|
+
*/
|
|
57
|
+
function parseEnvNumber(value, defaultValue) {
|
|
58
|
+
if (value === undefined)
|
|
59
|
+
return defaultValue;
|
|
60
|
+
const num = parseInt(value, 10);
|
|
61
|
+
return isNaN(num) ? defaultValue : num;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 从环境变量解析字符串数组(逗号分隔)
|
|
65
|
+
*/
|
|
66
|
+
function parseEnvStringArray(value, defaultValue) {
|
|
67
|
+
if (value === undefined || value.trim() === '')
|
|
68
|
+
return defaultValue;
|
|
69
|
+
return value.split(',').map(s => s.trim().toLowerCase()).filter(s => s.length > 0);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 从环境变量解析端口(支持 'auto' 或数字)
|
|
73
|
+
*/
|
|
74
|
+
function parseEnvPort(value, defaultValue) {
|
|
75
|
+
if (value === undefined)
|
|
76
|
+
return defaultValue;
|
|
77
|
+
if (value.toLowerCase() === 'auto')
|
|
78
|
+
return 'auto';
|
|
79
|
+
const num = parseInt(value, 10);
|
|
80
|
+
return isNaN(num) ? defaultValue : num;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 从环境变量加载配置
|
|
84
|
+
*/
|
|
85
|
+
function loadFromEnv() {
|
|
86
|
+
const env = process.env;
|
|
87
|
+
return {
|
|
88
|
+
maxRequests: parseEnvNumber(env.NND_MAX_REQUESTS, defaultConfig.maxRequests),
|
|
89
|
+
maxBodySize: parseEnvNumber(env.NND_MAX_BODY_SIZE, defaultConfig.maxBodySize),
|
|
90
|
+
interceptHttp: parseEnvBoolean(env.NND_INTERCEPT_HTTP, defaultConfig.interceptHttp),
|
|
91
|
+
interceptUndici: parseEnvBoolean(env.NND_INTERCEPT_UNDICI, defaultConfig.interceptUndici),
|
|
92
|
+
redactHeaders: parseEnvStringArray(env.NND_REDACT_HEADERS, defaultConfig.redactHeaders),
|
|
93
|
+
disableBodyCapture: parseEnvBoolean(env.NND_DISABLE_BODY_CAPTURE, defaultConfig.disableBodyCapture),
|
|
94
|
+
// GUI 配置
|
|
95
|
+
guiEnabled: parseEnvBoolean(env.NND_GUI_ENABLED, defaultConfig.guiEnabled),
|
|
96
|
+
guiPort: parseEnvPort(env.NND_GUI_PORT, defaultConfig.guiPort),
|
|
97
|
+
wsPort: parseEnvPort(env.NND_WS_PORT, defaultConfig.wsPort),
|
|
98
|
+
guiHost: env.NND_GUI_HOST || defaultConfig.guiHost,
|
|
99
|
+
autoOpen: parseEnvBoolean(env.NND_AUTO_OPEN, defaultConfig.autoOpen),
|
|
100
|
+
// 浏览器窗口配置
|
|
101
|
+
browserWindowSize: {
|
|
102
|
+
width: parseEnvNumber(env.NND_BROWSER_WIDTH, defaultConfig.browserWindowSize?.width ?? 800),
|
|
103
|
+
height: parseEnvNumber(env.NND_BROWSER_HEIGHT, defaultConfig.browserWindowSize?.height ?? 600),
|
|
104
|
+
},
|
|
105
|
+
browserWindowTitle: env.NND_BROWSER_TITLE || defaultConfig.browserWindowTitle,
|
|
106
|
+
browserPath: env.NND_BROWSER_PATH,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 初始化配置(合并默认值和环境变量)
|
|
111
|
+
*/
|
|
112
|
+
function initConfig() {
|
|
113
|
+
const envConfig = loadFromEnv();
|
|
114
|
+
return {
|
|
115
|
+
...defaultConfig,
|
|
116
|
+
...envConfig,
|
|
117
|
+
// ignoreUrls 需要特殊处理,环境变量不支持正则
|
|
118
|
+
ignoreUrls: defaultConfig.ignoreUrls,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// 初始化时加载配置
|
|
122
|
+
currentConfig = initConfig();
|
|
123
|
+
/**
|
|
124
|
+
* 获取当前配置
|
|
125
|
+
*/
|
|
126
|
+
function getConfig() {
|
|
127
|
+
return currentConfig;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 设置配置(合并到当前配置)
|
|
131
|
+
*/
|
|
132
|
+
function setConfig(config) {
|
|
133
|
+
currentConfig = {
|
|
134
|
+
...currentConfig,
|
|
135
|
+
...config,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 重置配置为默认值
|
|
140
|
+
*/
|
|
141
|
+
function resetConfig() {
|
|
142
|
+
currentConfig = initConfig();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 获取默认配置(用于测试)
|
|
146
|
+
*/
|
|
147
|
+
function getDefaultConfig() {
|
|
148
|
+
return defaultConfig;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
|