@mt0926/node-network-devtools 0.2.0 → 0.3.10

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 (56) hide show
  1. package/README.md +134 -109
  2. package/README.zh-CN.md +62 -108
  3. package/dist/cjs/adapters/axios.js +2 -0
  4. package/dist/cjs/adapters/axios.js.map +1 -0
  5. package/dist/cjs/adapters/nextjs.js +133 -0
  6. package/dist/cjs/adapters/nextjs.js.map +1 -0
  7. package/dist/cjs/config.js +150 -0
  8. package/dist/cjs/config.js.map +1 -0
  9. package/dist/cjs/context/context-manager.js +139 -0
  10. package/dist/cjs/context/context-manager.js.map +1 -0
  11. package/dist/cjs/gui/browser-detector.js +263 -0
  12. package/dist/cjs/gui/browser-detector.js.map +1 -0
  13. package/dist/cjs/gui/browser-launcher.js +365 -0
  14. package/dist/cjs/gui/browser-launcher.js.map +1 -0
  15. package/dist/cjs/gui/event-bridge.js +197 -0
  16. package/dist/cjs/gui/event-bridge.js.map +1 -0
  17. package/dist/cjs/gui/port-utils.js +85 -0
  18. package/dist/cjs/gui/port-utils.js.map +1 -0
  19. package/dist/cjs/gui/server.js +267 -0
  20. package/dist/cjs/gui/server.js.map +1 -0
  21. package/dist/cjs/gui/websocket-hub.js +336 -0
  22. package/dist/cjs/gui/websocket-hub.js.map +1 -0
  23. package/dist/cjs/index.js +170 -0
  24. package/dist/cjs/index.js.map +1 -0
  25. package/dist/cjs/interceptors/http-patcher.js +275 -0
  26. package/dist/cjs/interceptors/http-patcher.js.map +1 -0
  27. package/dist/cjs/interceptors/undici-patcher.js +362 -0
  28. package/dist/cjs/interceptors/undici-patcher.js.map +1 -0
  29. package/dist/cjs/package.json +3 -0
  30. package/dist/cjs/register.js +95 -0
  31. package/dist/cjs/register.js.map +1 -0
  32. package/dist/cjs/store/ring-buffer.js +241 -0
  33. package/dist/cjs/store/ring-buffer.js.map +1 -0
  34. package/dist/cjs/test-setup.js +8 -0
  35. package/dist/cjs/test-setup.js.map +1 -0
  36. package/dist/cjs/utils/module-compat.js +83 -0
  37. package/dist/cjs/utils/module-compat.js.map +1 -0
  38. package/dist/esm/gui/server.js +41 -6
  39. package/dist/esm/gui/server.js.map +1 -1
  40. package/dist/esm/index.js +1 -1
  41. package/dist/esm/interceptors/undici-patcher.js +9 -4
  42. package/dist/esm/interceptors/undici-patcher.js.map +1 -1
  43. package/dist/esm/utils/module-compat.js +78 -0
  44. package/dist/esm/utils/module-compat.js.map +1 -0
  45. package/dist/gui/assets/index.css +1 -1
  46. package/dist/gui/assets/index.js +10 -10
  47. package/dist/types/gui/server.d.ts.map +1 -1
  48. package/dist/types/index.d.ts +1 -1
  49. package/dist/types/interceptors/undici-patcher.d.ts.map +1 -1
  50. package/dist/types/utils/module-compat.d.ts +34 -0
  51. package/dist/types/utils/module-compat.d.ts.map +1 -0
  52. package/package.json +42 -35
  53. package/dist/esm/cli.js +0 -203
  54. package/dist/esm/cli.js.map +0 -1
  55. package/dist/types/cli.d.ts +0 -8
  56. package/dist/types/cli.d.ts.map +0 -1
package/README.zh-CN.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  # 🔍 Node Network DevTools
4
4
 
5
- **Node.js 网络请求监控工具,集成 Chrome DevTools 和内置 Web GUI**
5
+ **Node.js 强大的零配置网络调试助手。**
6
+ *实时监控所有 HTTP、HTTPS 和 Fetch/Undici 请求,提供类似 Chrome DevTools 的极简 Web GUI 体验。*
6
7
 
7
- [![npm version](https://img.shields.io/npm/v/node-network-devtools.svg)](https://www.npmjs.com/package/node-network-devtools)
8
+ [![npm version](https://img.shields.io/npm/v/@mt0926/node-network-devtools.svg)](https://www.npmjs.com/package/@mt0926/node-network-devtools)
8
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Node.js Version](https://img.shields.io/node/v/node-network-devtools.svg)](https://nodejs.org)
10
10
 
11
11
  [English](./README.md) | [中文文档](#)
12
12
 
@@ -14,151 +14,105 @@
14
14
 
15
15
  ---
16
16
 
17
- ## ⚠️ 仅限开发环境使用
17
+ ## 🚀 为什么选择 Node Network DevTools?
18
18
 
19
- **本工具仅用于开发环境,请勿在生产环境中使用!**
20
-
21
- - 使用 Puppeteer 启动极简浏览器窗口显示 GUI
22
- - 拦截所有网络请求可能影响性能
23
- - 在内存中存储请求/响应数据
24
- - 不适合生产环境工作负载
25
-
26
- ### 在生产环境中禁用
27
-
28
- ```javascript
29
- // 条件安装
30
- if (process.env.NODE_ENV === 'development') {
31
- await install();
32
- }
33
- ```
34
-
35
- 或使用环境变量:
36
-
37
- ```bash
38
- # 禁用 GUI 和自动打开
39
- NND_GUI_ENABLED=false NND_AUTO_OPEN=false node your-app.js
40
- ```
19
+ 还在用 `console.log` 打印每一个请求和响应吗?**Node Network DevTools** 将浏览器“网络”面板的熟悉体验带到了 Node.js 后端。无论是在调试外部 API 调用、微服务还是 Next.js Server Actions,你都可以实时查看每一个细节。
41
20
 
42
21
  ## ✨ 特性
43
22
 
44
- - 🔍 **双重拦截** - 同时支持 `http/https` 模块和 `undici/fetch` API
45
- - 🎯 **零侵入** - 通过 `-r` `--import` 自动注入,无需修改代码
46
- - 🖥️ **极简浏览器窗口** - Puppeteer 驱动的紧凑 GUI 窗口(800x600)
47
- - 📊 **内置 Web GUI** - 类似 Chrome DevTools 的界面,实时更新
48
- - 🔗 **请求追踪** - 基于 AsyncLocalStorage 的请求关联
49
- - 🛡️ **安全性** - 自动脱敏敏感请求头(AuthorizationCookie 等)
50
- - ⚡ **Next.js 兼容** - 保留 `next.revalidate`、`next.tags` 等选项
51
- - 📦 **TypeScript** - 完整的 TypeScript 支持和类型定义
23
+ - 💎 **类似 DevTools 的体验** - 熟悉的响应式 Web GUI,用于检查 Header、Payload 和 Response。
24
+ - 🔌 **全能拦截** - 原生支持 `http/https` 模块以及现代的 `fetch/undici` (Node.js 18+)。
25
+ - 🛠️ **零侵入开发** - 只需一行代码或一个简单的 CLI 标志即可接入项目。
26
+ - 🖥️ **极简浏览器窗口** - 自动启动基于系统原生浏览器 (Chrome, Edge, 或 Chromium) 的紧凑 App 模式窗口。
27
+ - 🔗 **智能请求追踪** - 利用 `AsyncLocalStorage` 自动关联同一业务流中的多个异步请求。
28
+ - 🛡️ **内置脱敏** - 自动隐藏 `Authorization` 和 `Cookie` 等敏感信息,保障安全。
29
+ - ⚡ **框架友好** - 无缝集成 Next.js, Express, Fastify 等主流框架。
30
+ - 📦 **双模块支持** - 完美兼容 **ESM** 和 **CommonJS**。
52
31
 
53
32
  ## 📸 截图
54
33
 
55
34
  ### Web GUI 界面
56
35
  ![Web GUI](https://via.placeholder.com/800x450?text=Web+GUI+Screenshot)
57
36
 
58
- ### Chrome DevTools 集成
59
- ![Chrome DevTools](https://via.placeholder.com/800x450?text=Chrome+DevTools+Screenshot)
60
-
61
37
  ## 🚀 快速开始
62
38
 
63
- ### 安装
39
+ ### 1. 安装
64
40
 
65
41
  ```bash
66
- npm install node-network-devtools puppeteer
67
- # 或
68
- pnpm add node-network-devtools puppeteer
42
+ npm install @mt0926/node-network-devtools
69
43
  # 或
70
- yarn add node-network-devtools puppeteer
44
+ pnpm add @mt0926/node-network-devtools
71
45
  ```
72
46
 
73
- **注意**:Puppeteer GUI 浏览器窗口所必需的。如果未安装,您会看到友好的错误消息和安装指引。
74
-
75
- ### 使用
76
-
77
- #### 方式一:CLI(推荐)
47
+ > **注意**: 无需安装 Puppeteer 等额外依赖!工具会自动检测并使用系统中已有的浏览器。
78
48
 
79
- ```bash
80
- npx node-network-devtools your-script.js
81
- # 或使用短别名
82
- npx nnd your-script.js
83
- ```
49
+ ### 2. 使用方式 (推荐)
84
50
 
85
- CLI 会自动注入拦截器并打开 GUI。
51
+ 在应用入口文件的最顶部调用 `install()`。
86
52
 
87
- #### 方式二:使用 `-r` 标志
53
+ **ESM:**
54
+ ```typescript
55
+ import { install } from '@mt0926/node-network-devtools';
88
56
 
89
- ```bash
90
- node -r node-network-devtools/register your-script.js
57
+ await install(); // 确保在发送任何网络请求的 import 之前调用
91
58
  ```
92
59
 
93
- #### 方式三:编程方式
94
-
95
- ```typescript
96
- import { install } from 'node-network-devtools';
97
-
98
- await install();
60
+ **CommonJS:**
61
+ ```javascript
62
+ const { install } = require('@mt0926/node-network-devtools');
99
63
 
100
- // 你的应用代码
101
- import express from 'express';
102
- const app = express();
103
- // ...
64
+ (async () => {
65
+ await install();
66
+ })();
104
67
  ```
105
68
 
106
- ### 查看请求
69
+ ### 3. 高级方案:零代码注入
107
70
 
108
- 启动应用后:
71
+ 如果你不想修改源代码,可以使用 Node.js 的命令行参数来注入工具。
109
72
 
110
- - **Web GUI**(默认):极简浏览器窗口会自动打开显示 GUI
111
- - 紧凑的窗口大小(默认 800x600)
112
- - 可自定义窗口大小和标题
113
- - 无浏览器工具栏或地址栏(app 模式)
114
-
115
- 要手动访问 GUI,请查看控制台输出中的 URL:
73
+ **ESM:**
74
+ ```bash
75
+ node --import @mt0926/node-network-devtools/register your-script.js
116
76
  ```
117
- 🚀 Node Network DevTools GUI started at http://localhost:9229
77
+
78
+ **CommonJS:**
79
+ ```bash
80
+ node -r @mt0926/node-network-devtools/register your-script.js
118
81
  ```
119
82
 
120
83
  ## 🖥️ Web GUI
121
84
 
122
- 内置的 Web GUI 提供类似 Chrome DevTools 的网络请求监控体验。
123
-
124
- ### 极简浏览器窗口
125
-
126
- GUI 在极简的 Puppeteer 控制的浏览器窗口中打开:
85
+ 启动后,一个极简的浏览器窗口会自动打开并显示实时请求列表。
127
86
 
128
- - **紧凑尺寸**:默认 800x600,可通过环境变量自定义
129
- - **App 模式**:无浏览器工具栏、地址栏或其他界面元素
130
- - **自定义标题**:默认显示 "Node Network DevTools"
131
- - **快速启动**:3 秒内打开
87
+ - **紧凑尺寸** (800x600),方便分屏调试。
88
+ - **搜索与过滤** - 按 URL、方法或状态码筛选。
89
+ - **详情面板** - 查看 Header、Payload 和 Response。
90
+ - **深色/浅色模式**支持。
132
91
 
133
- ### 功能特性
92
+ 如果需要手动访问,请在控制台输出中查找 URL:
93
+ `🚀 Node Network DevTools GUI started at http://localhost:9229`
134
94
 
135
- - 📋 **请求列表** - 实时显示所有网络请求
136
- - 🔍 **搜索过滤** - 按 URL、方法、状态码和类型过滤
137
- - 📝 **详情面板** - 查看请求头、请求体、响应和时序信息
138
- - 🎨 **主题切换** - 支持深色/浅色主题
139
- - ⏸️ **暂停/恢复** - 暂停请求捕获以便分析
140
- - 🔄 **实时更新** - 基于 WebSocket 的实时更新
141
95
 
142
96
  ### GUI 配置
143
97
 
144
98
  ```bash
145
99
  # 自定义窗口大小
146
- NND_BROWSER_WIDTH=1024 NND_BROWSER_HEIGHT=768 npx nnd your-script.js
100
+ NND_BROWSER_WIDTH=1024 NND_BROWSER_HEIGHT=768 node --import @mt0926/node-network-devtools/register your-script.js
147
101
 
148
102
  # 自定义窗口标题
149
- NND_BROWSER_TITLE="我的应用网络监控" npx nnd your-script.js
103
+ NND_BROWSER_TITLE="我的应用网络监控" node --import @mt0926/node-network-devtools/register your-script.js
150
104
 
151
105
  # 指定 GUI 端口
152
- NND_GUI_PORT=9230 npx nnd your-script.js
106
+ NND_GUI_PORT=9230 node --import @mt0926/node-network-devtools/register your-script.js
153
107
 
154
108
  # 指定 WebSocket 端口
155
- NND_WS_PORT=9231 npx nnd your-script.js
109
+ NND_WS_PORT=9231 node --import @mt0926/node-network-devtools/register your-script.js
156
110
 
157
111
  # 禁用 GUI
158
- NND_GUI_ENABLED=false npx nnd your-script.js
112
+ NND_GUI_ENABLED=false node --import @mt0926/node-network-devtools/register your-script.js
159
113
 
160
114
  # 禁用自动打开浏览器
161
- NND_AUTO_OPEN=false npx nnd your-script.js
115
+ NND_AUTO_OPEN=false node --import @mt0926/node-network-devtools/register your-script.js
162
116
  ```
163
117
 
164
118
  ## 🔧 配置
@@ -190,7 +144,7 @@ NND_AUTO_OPEN=false npx nnd your-script.js
190
144
  ### 编程配置
191
145
 
192
146
  ```typescript
193
- import { setConfig } from 'node-network-devtools';
147
+ import { setConfig } from '@mt0926/node-network-devtools';
194
148
 
195
149
  setConfig({
196
150
  maxRequests: 500,
@@ -210,7 +164,7 @@ setConfig({
210
164
  ```typescript
211
165
  // 根据环境条件安装
212
166
  if (process.env.NODE_ENV === 'development') {
213
- const { install } = await import('node-network-devtools');
167
+ const { install } = await import('@mt0926/node-network-devtools');
214
168
  await install();
215
169
  }
216
170
  ```
@@ -259,7 +213,7 @@ npm run dev
259
213
 
260
214
  ```typescript
261
215
  import express from 'express';
262
- import { install } from 'node-network-devtools';
216
+ import { install } from '@mt0926/node-network-devtools';
263
217
 
264
218
  await install();
265
219
 
@@ -277,23 +231,23 @@ const app = express();
277
231
 
278
232
  ```typescript
279
233
  // 快速安装
280
- import { install, startGUI, stopGUI } from 'node-network-devtools';
234
+ import { install, startGUI, stopGUI } from '@mt0926/node-network-devtools';
281
235
 
282
236
  // 配置
283
- import { getConfig, setConfig, resetConfig } from 'node-network-devtools';
237
+ import { getConfig, setConfig, resetConfig } from '@mt0926/node-network-devtools';
284
238
 
285
239
  // 请求存储
286
- import { getRequestStore } from 'node-network-devtools';
240
+ import { getRequestStore } from '@mt0926/node-network-devtools';
287
241
 
288
242
  // 上下文追踪
289
243
  import {
290
244
  runWithTrace,
291
245
  getCurrentTraceId,
292
246
  generateTraceId
293
- } from 'node-network-devtools';
247
+ } from '@mt0926/node-network-devtools';
294
248
 
295
249
  // 拦截器
296
- import { HttpPatcher, UndiciPatcher } from 'node-network-devtools';
250
+ import { HttpPatcher, UndiciPatcher } from '@mt0926/node-network-devtools';
297
251
  ```
298
252
 
299
253
  ### 请求追踪
@@ -301,7 +255,7 @@ import { HttpPatcher, UndiciPatcher } from 'node-network-devtools';
301
255
  关联同一业务流程中的多个请求:
302
256
 
303
257
  ```typescript
304
- import { runWithTrace, getRequestStore } from 'node-network-devtools';
258
+ import { runWithTrace, getRequestStore } from '@mt0926/node-network-devtools';
305
259
 
306
260
  await runWithTrace('user-login', async () => {
307
261
  // 这些请求会被关联到同一个 traceId
@@ -331,7 +285,7 @@ const requests = store.getByTraceId('user-login');
331
285
  2. **Undici 拦截**:使用 `Agent.compose()` 注册拦截器捕获 fetch 请求
332
286
  3. **上下文传递**:使用 `AsyncLocalStorage` 在异步调用链中传递 TraceID
333
287
  4. **事件桥接**:将拦截的请求转发到 WebSocket 客户端以实现 GUI 实时更新
334
- 5. **极简浏览器**:使用 Puppeteer app 模式下启动紧凑的浏览器窗口
288
+ 5. **原生浏览器启动**:自动检测并启动系统中的浏览器 (Chrome/Edge/Chromium),并以专用的 App 模式窗口运行。
335
289
 
336
290
  ## 🤝 贡献
337
291
 
@@ -369,7 +323,7 @@ MIT © [ddddd](https://github.com/dong0926)
369
323
 
370
324
  - 🐛 [报告问题](https://github.com/dong0926/node-network-devtools/issues)
371
325
  - 💬 [讨论](https://github.com/dong0926/node-network-devtools/discussions)
372
- - 📧 邮箱:your.email@example.com
326
+ - 📧 邮箱:xx630133368@gmail.com
373
327
 
374
328
  ---
375
329
 
@@ -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,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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"}