@mt0926/node-network-devtools 0.2.0 → 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.
Files changed (51) hide show
  1. package/README.md +96 -1
  2. package/dist/cjs/adapters/axios.js +2 -0
  3. package/dist/cjs/adapters/axios.js.map +1 -0
  4. package/dist/cjs/adapters/nextjs.js +133 -0
  5. package/dist/cjs/adapters/nextjs.js.map +1 -0
  6. package/dist/cjs/cli.js +223 -0
  7. package/dist/cjs/cli.js.map +1 -0
  8. package/dist/cjs/config.js +150 -0
  9. package/dist/cjs/config.js.map +1 -0
  10. package/dist/cjs/context/context-manager.js +139 -0
  11. package/dist/cjs/context/context-manager.js.map +1 -0
  12. package/dist/cjs/gui/browser-detector.js +263 -0
  13. package/dist/cjs/gui/browser-detector.js.map +1 -0
  14. package/dist/cjs/gui/browser-launcher.js +365 -0
  15. package/dist/cjs/gui/browser-launcher.js.map +1 -0
  16. package/dist/cjs/gui/event-bridge.js +197 -0
  17. package/dist/cjs/gui/event-bridge.js.map +1 -0
  18. package/dist/cjs/gui/port-utils.js +85 -0
  19. package/dist/cjs/gui/port-utils.js.map +1 -0
  20. package/dist/cjs/gui/server.js +251 -0
  21. package/dist/cjs/gui/server.js.map +1 -0
  22. package/dist/cjs/gui/websocket-hub.js +336 -0
  23. package/dist/cjs/gui/websocket-hub.js.map +1 -0
  24. package/dist/cjs/index.js +170 -0
  25. package/dist/cjs/index.js.map +1 -0
  26. package/dist/cjs/interceptors/http-patcher.js +275 -0
  27. package/dist/cjs/interceptors/http-patcher.js.map +1 -0
  28. package/dist/cjs/interceptors/undici-patcher.js +362 -0
  29. package/dist/cjs/interceptors/undici-patcher.js.map +1 -0
  30. package/dist/cjs/package.json +3 -0
  31. package/dist/cjs/register.js +95 -0
  32. package/dist/cjs/register.js.map +1 -0
  33. package/dist/cjs/store/ring-buffer.js +241 -0
  34. package/dist/cjs/store/ring-buffer.js.map +1 -0
  35. package/dist/cjs/test-setup.js +8 -0
  36. package/dist/cjs/test-setup.js.map +1 -0
  37. package/dist/cjs/utils/module-compat.js +83 -0
  38. package/dist/cjs/utils/module-compat.js.map +1 -0
  39. package/dist/esm/cli.js +22 -4
  40. package/dist/esm/cli.js.map +1 -1
  41. package/dist/esm/gui/server.js +25 -6
  42. package/dist/esm/gui/server.js.map +1 -1
  43. package/dist/esm/interceptors/undici-patcher.js +9 -4
  44. package/dist/esm/interceptors/undici-patcher.js.map +1 -1
  45. package/dist/esm/utils/module-compat.js +78 -0
  46. package/dist/esm/utils/module-compat.js.map +1 -0
  47. package/dist/types/gui/server.d.ts.map +1 -1
  48. package/dist/types/interceptors/undici-patcher.d.ts.map +1 -1
  49. package/dist/types/utils/module-compat.d.ts +34 -0
  50. package/dist/types/utils/module-compat.d.ts.map +1 -0
  51. 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**: Puppeteer is required for the GUI browser window. If not installed, you'll see a friendly error message with installation instructions.
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,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=axios.js.map
@@ -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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"}
@@ -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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"}