@mt0926/node-network-devtools 0.1.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/BUILD.md +204 -0
- package/LICENSE +21 -0
- package/README.md +310 -0
- package/README.zh-CN.md +310 -0
- package/dist/esm/adapters/nextjs.js +123 -0
- package/dist/esm/adapters/nextjs.js.map +1 -0
- package/dist/esm/cdp/cdp-bridge.js +312 -0
- package/dist/esm/cdp/cdp-bridge.js.map +1 -0
- package/dist/esm/cli.js +203 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/config.js +136 -0
- package/dist/esm/config.js.map +1 -0
- package/dist/esm/context/context-manager.js +126 -0
- package/dist/esm/context/context-manager.js.map +1 -0
- package/dist/esm/gui/browser-launcher.js +165 -0
- package/dist/esm/gui/browser-launcher.js.map +1 -0
- package/dist/esm/gui/event-bridge.js +192 -0
- package/dist/esm/gui/event-bridge.js.map +1 -0
- package/dist/esm/gui/port-utils.js +80 -0
- package/dist/esm/gui/port-utils.js.map +1 -0
- package/dist/esm/gui/server.js +227 -0
- package/dist/esm/gui/server.js.map +1 -0
- package/dist/esm/gui/websocket-hub.js +326 -0
- package/dist/esm/gui/websocket-hub.js.map +1 -0
- package/dist/esm/index.js +90 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/interceptors/http-patcher.js +203 -0
- package/dist/esm/interceptors/http-patcher.js.map +1 -0
- package/dist/esm/interceptors/undici-patcher.js +324 -0
- package/dist/esm/interceptors/undici-patcher.js.map +1 -0
- package/dist/esm/register.js +132 -0
- package/dist/esm/register.js.map +1 -0
- package/dist/esm/store/ring-buffer.js +236 -0
- package/dist/esm/store/ring-buffer.js.map +1 -0
- package/dist/esm/test-setup.js +7 -0
- package/dist/esm/test-setup.js.map +1 -0
- package/dist/gui/assets/index.css +1 -0
- package/dist/gui/assets/index.js +40 -0
- package/dist/gui/index.html +14 -0
- package/dist/types/adapters/nextjs.d.ts +80 -0
- package/dist/types/adapters/nextjs.d.ts.map +1 -0
- package/dist/types/cdp/cdp-bridge.d.ts +86 -0
- package/dist/types/cdp/cdp-bridge.d.ts.map +1 -0
- package/dist/types/cli.d.ts +8 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/config.d.ts +57 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/context/context-manager.d.ts +96 -0
- package/dist/types/context/context-manager.d.ts.map +1 -0
- package/dist/types/gui/browser-launcher.d.ts +52 -0
- package/dist/types/gui/browser-launcher.d.ts.map +1 -0
- package/dist/types/gui/event-bridge.d.ts +36 -0
- package/dist/types/gui/event-bridge.d.ts.map +1 -0
- package/dist/types/gui/port-utils.d.ts +25 -0
- package/dist/types/gui/port-utils.d.ts.map +1 -0
- package/dist/types/gui/server.d.ts +50 -0
- package/dist/types/gui/server.d.ts.map +1 -0
- package/dist/types/gui/websocket-hub.d.ts +67 -0
- package/dist/types/gui/websocket-hub.d.ts.map +1 -0
- package/dist/types/index.d.ts +44 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interceptors/http-patcher.d.ts +32 -0
- package/dist/types/interceptors/http-patcher.d.ts.map +1 -0
- package/dist/types/interceptors/undici-patcher.d.ts +37 -0
- package/dist/types/interceptors/undici-patcher.d.ts.map +1 -0
- package/dist/types/register.d.ts +18 -0
- package/dist/types/register.d.ts.map +1 -0
- package/dist/types/store/ring-buffer.d.ts +148 -0
- package/dist/types/store/ring-buffer.d.ts.map +1 -0
- package/dist/types/test-setup.d.ts +7 -0
- package/dist/types/test-setup.d.ts.map +1 -0
- package/package.json +103 -0
- package/templates/instrumentation.ts +32 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 🔍 Node Network DevTools
|
|
4
|
+
|
|
5
|
+
**Node.js 网络请求监控工具,集成 Chrome DevTools 和内置 Web GUI**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/node-network-devtools)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
|
|
11
|
+
[English](./README.md) | [中文文档](#)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ✨ 特性
|
|
18
|
+
|
|
19
|
+
- 🔍 **双栈拦截** - 同时支持 `http/https` 模块和 `undici/fetch` API
|
|
20
|
+
- 🎯 **零侵入** - 通过 `-r` 或 `--import` 自动注入,无需修改业务代码
|
|
21
|
+
- 📊 **DevTools 集成** - 在 Chrome DevTools Network 面板中查看所有请求
|
|
22
|
+
- 🖥️ **内置 Web GUI** - 类似 Chrome DevTools 的 Web 界面,实时更新
|
|
23
|
+
- 🔗 **请求追踪** - 基于 AsyncLocalStorage 的请求关联
|
|
24
|
+
- 🛡️ **安全脱敏** - 自动脱敏敏感头(Authorization、Cookie 等)
|
|
25
|
+
- ⚡ **Next.js 兼容** - 保留 `next.revalidate`、`next.tags` 等选项
|
|
26
|
+
- 📦 **TypeScript** - 完整的 TypeScript 支持和类型定义
|
|
27
|
+
|
|
28
|
+
## 📸 截图
|
|
29
|
+
|
|
30
|
+
### Web GUI 界面
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
### Chrome DevTools 集成
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
## 🚀 快速开始
|
|
37
|
+
|
|
38
|
+
### 安装
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install node-network-devtools
|
|
42
|
+
# 或
|
|
43
|
+
pnpm add node-network-devtools
|
|
44
|
+
# 或
|
|
45
|
+
yarn add node-network-devtools
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 使用
|
|
49
|
+
|
|
50
|
+
#### 方式一:CLI(推荐)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx node-network-devtools your-script.js
|
|
54
|
+
# 或使用短别名
|
|
55
|
+
npx nnd your-script.js
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
CLI 会自动添加 `--inspect` 标志并注入拦截器。
|
|
59
|
+
|
|
60
|
+
#### 方式二:使用 `-r` 标志
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
node --inspect -r node-network-devtools/register your-script.js
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### 方式三:编程方式
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { install } from 'node-network-devtools';
|
|
70
|
+
|
|
71
|
+
await install();
|
|
72
|
+
|
|
73
|
+
// 你的应用代码
|
|
74
|
+
import express from 'express';
|
|
75
|
+
const app = express();
|
|
76
|
+
// ...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 查看请求
|
|
80
|
+
|
|
81
|
+
启动应用后:
|
|
82
|
+
|
|
83
|
+
1. **Web GUI**(默认):浏览器会自动打开显示 GUI 界面
|
|
84
|
+
2. **Chrome DevTools**:打开 Chrome 浏览器,访问 `chrome://inspect`,然后点击 "Open dedicated DevTools for Node"
|
|
85
|
+
|
|
86
|
+
## 🖥️ Web GUI
|
|
87
|
+
|
|
88
|
+
内置的 Web GUI 提供类似 Chrome DevTools 的网络请求监控体验。
|
|
89
|
+
|
|
90
|
+
### 功能特性
|
|
91
|
+
|
|
92
|
+
- 📋 **请求列表** - 实时显示所有网络请求
|
|
93
|
+
- 🔍 **搜索过滤** - 按 URL、方法、状态码和类型过滤
|
|
94
|
+
- 📝 **详情面板** - 查看请求头、请求体、响应体和时序信息
|
|
95
|
+
- 🎨 **主题切换** - 支持深色/浅色主题
|
|
96
|
+
- ⏸️ **暂停/恢复** - 暂停请求捕获以便分析
|
|
97
|
+
- 🔄 **实时更新** - 基于 WebSocket 的实时更新
|
|
98
|
+
|
|
99
|
+
### GUI 配置
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 指定 GUI 端口
|
|
103
|
+
NND_GUI_PORT=9230 npx nnd your-script.js
|
|
104
|
+
|
|
105
|
+
# 指定 WebSocket 端口
|
|
106
|
+
NND_WS_PORT=9231 npx nnd your-script.js
|
|
107
|
+
|
|
108
|
+
# 禁用 GUI
|
|
109
|
+
NND_GUI_ENABLED=false npx nnd your-script.js
|
|
110
|
+
|
|
111
|
+
# 禁用自动打开浏览器
|
|
112
|
+
NND_AUTO_OPEN=false npx nnd your-script.js
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 🔧 配置
|
|
116
|
+
|
|
117
|
+
### 环境变量
|
|
118
|
+
|
|
119
|
+
#### 核心设置
|
|
120
|
+
|
|
121
|
+
| 变量名 | 说明 | 默认值 |
|
|
122
|
+
|--------|------|--------|
|
|
123
|
+
| `NND_MAX_REQUESTS` | 最大存储请求数 | 1000 |
|
|
124
|
+
| `NND_MAX_BODY_SIZE` | 最大 body 大小(字节) | 1048576 (1MB) |
|
|
125
|
+
| `NND_INTERCEPT_HTTP` | 拦截 http/https | true |
|
|
126
|
+
| `NND_INTERCEPT_UNDICI` | 拦截 undici/fetch | true |
|
|
127
|
+
| `NND_REDACT_HEADERS` | 要脱敏的头(逗号分隔) | authorization,cookie |
|
|
128
|
+
| `NND_AUTO_CONNECT` | 自动连接 CDP | true |
|
|
129
|
+
|
|
130
|
+
#### GUI 设置
|
|
131
|
+
|
|
132
|
+
| 变量名 | 说明 | 默认值 |
|
|
133
|
+
|--------|------|--------|
|
|
134
|
+
| `NND_GUI_ENABLED` | 启用 GUI 服务器 | true |
|
|
135
|
+
| `NND_GUI_PORT` | GUI 服务器端口 | 自动 |
|
|
136
|
+
| `NND_WS_PORT` | WebSocket 端口 | 自动 |
|
|
137
|
+
| `NND_AUTO_OPEN` | 自动打开浏览器 | true |
|
|
138
|
+
|
|
139
|
+
### 编程配置
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { setConfig } from 'node-network-devtools';
|
|
143
|
+
|
|
144
|
+
setConfig({
|
|
145
|
+
maxRequests: 500,
|
|
146
|
+
maxBodySize: 512 * 1024,
|
|
147
|
+
redactHeaders: ['authorization', 'cookie', 'x-api-key'],
|
|
148
|
+
guiEnabled: true,
|
|
149
|
+
autoOpen: false,
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## 🎯 框架集成
|
|
154
|
+
|
|
155
|
+
### Next.js
|
|
156
|
+
|
|
157
|
+
1. 复制 `templates/instrumentation.ts` 到项目根目录
|
|
158
|
+
2. 在 `next.config.js` 中启用 instrumentation:
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
module.exports = {
|
|
162
|
+
experimental: {
|
|
163
|
+
instrumentationHook: true,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
3. 使用 `--inspect` 启动:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
NODE_OPTIONS='--inspect' npm run dev
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
或在 `package.json` 中配置:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"scripts": {
|
|
179
|
+
"dev:debug": "NODE_OPTIONS='--inspect' next dev"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Express
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
import express from 'express';
|
|
188
|
+
import { install } from 'node-network-devtools';
|
|
189
|
+
|
|
190
|
+
await install();
|
|
191
|
+
|
|
192
|
+
const app = express();
|
|
193
|
+
// 你的路由...
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 其他框架
|
|
197
|
+
|
|
198
|
+
适用于任何 Node.js 框架!只需在应用代码之前安装拦截器即可。
|
|
199
|
+
|
|
200
|
+
## 📚 API 参考
|
|
201
|
+
|
|
202
|
+
### 主要导出
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// 快速安装
|
|
206
|
+
import { install, startGUI, stopGUI } from 'node-network-devtools';
|
|
207
|
+
|
|
208
|
+
// 配置
|
|
209
|
+
import { getConfig, setConfig, resetConfig } from 'node-network-devtools';
|
|
210
|
+
|
|
211
|
+
// 请求存储
|
|
212
|
+
import { getRequestStore } from 'node-network-devtools';
|
|
213
|
+
|
|
214
|
+
// 上下文追踪
|
|
215
|
+
import {
|
|
216
|
+
runWithTrace,
|
|
217
|
+
getCurrentTraceId,
|
|
218
|
+
generateTraceId
|
|
219
|
+
} from 'node-network-devtools';
|
|
220
|
+
|
|
221
|
+
// 拦截器
|
|
222
|
+
import { HttpPatcher, UndiciPatcher } from 'node-network-devtools';
|
|
223
|
+
|
|
224
|
+
// CDP 桥接
|
|
225
|
+
import { getCDPBridge, isInspectorEnabled } from 'node-network-devtools';
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### 请求追踪
|
|
229
|
+
|
|
230
|
+
关联同一业务流程中的多个请求:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { runWithTrace, getRequestStore } from 'node-network-devtools';
|
|
234
|
+
|
|
235
|
+
await runWithTrace('user-login', async () => {
|
|
236
|
+
// 这些请求会被关联到同一个 traceId
|
|
237
|
+
await fetch('https://api.example.com/auth');
|
|
238
|
+
await fetch('https://api.example.com/user');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// 查询关联的请求
|
|
242
|
+
const store = getRequestStore();
|
|
243
|
+
const requests = store.getByTraceId('user-login');
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## 📖 示例
|
|
247
|
+
|
|
248
|
+
查看 [examples](./examples) 目录获取更多使用示例:
|
|
249
|
+
|
|
250
|
+
- [basic-http](./examples/basic-http) - 基础 HTTP 请求监听
|
|
251
|
+
- [fetch-api](./examples/fetch-api) - Fetch API 监听
|
|
252
|
+
- [request-tracing](./examples/request-tracing) - 请求追踪
|
|
253
|
+
- [express-server](./examples/express-server) - Express 服务器示例
|
|
254
|
+
- [programmatic-api](./examples/programmatic-api) - 编程式 API 使用
|
|
255
|
+
- [nextjs-app](./examples/nextjs-app) - Next.js App Router 集成
|
|
256
|
+
|
|
257
|
+
## 🔬 工作原理
|
|
258
|
+
|
|
259
|
+
1. **HTTP 拦截**:使用 `@mswjs/interceptors` 拦截 http/https 模块请求
|
|
260
|
+
2. **Undici 拦截**:使用 `Agent.compose()` 注册拦截器捕获 fetch 请求
|
|
261
|
+
3. **CDP 桥接**:通过 `node:inspector` 模块连接到 V8 Inspector 并发送 Network 域事件
|
|
262
|
+
4. **上下文传递**:使用 `AsyncLocalStorage` 在异步调用链中传递 TraceID
|
|
263
|
+
5. **事件桥接**:将拦截的请求转发到 WebSocket 客户端以实现 GUI 实时更新
|
|
264
|
+
|
|
265
|
+
## 🤝 贡献
|
|
266
|
+
|
|
267
|
+
欢迎贡献!请阅读我们的[贡献指南](./CONTRIBUTING.md)了解详情。
|
|
268
|
+
|
|
269
|
+
### 开发设置
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
# 克隆仓库
|
|
273
|
+
git clone https://github.com/dong0926/node-network-devtools.git
|
|
274
|
+
cd node-network-devtools
|
|
275
|
+
|
|
276
|
+
# 安装依赖
|
|
277
|
+
pnpm install
|
|
278
|
+
|
|
279
|
+
# 构建项目
|
|
280
|
+
pnpm build
|
|
281
|
+
|
|
282
|
+
# 运行测试
|
|
283
|
+
pnpm test:all
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## 📝 许可证
|
|
287
|
+
|
|
288
|
+
MIT © [ddddd](https://github.com/dong0926)
|
|
289
|
+
|
|
290
|
+
## 🙏 致谢
|
|
291
|
+
|
|
292
|
+
- [@mswjs/interceptors](https://github.com/mswjs/interceptors) - HTTP 请求拦截
|
|
293
|
+
- [undici](https://github.com/nodejs/undici) - HTTP/1.1 客户端
|
|
294
|
+
- [ws](https://github.com/websockets/ws) - WebSocket 实现
|
|
295
|
+
|
|
296
|
+
## 📮 支持
|
|
297
|
+
|
|
298
|
+
- 🐛 [报告问题](https://github.com/dong0926/node-network-devtools/issues)
|
|
299
|
+
- 💬 [讨论](https://github.com/dong0926/node-network-devtools/discussions)
|
|
300
|
+
- 📧 邮箱:your.email@example.com
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
<div align="center">
|
|
305
|
+
|
|
306
|
+
**如果这个项目对你有帮助,请给它一个 ⭐️!**
|
|
307
|
+
|
|
308
|
+
用 ❤️ 制作 by [ddddd](https://github.com/dong0926)
|
|
309
|
+
|
|
310
|
+
</div>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js 框架适配器
|
|
3
|
+
*
|
|
4
|
+
* 确保与 Next.js 的 Data Cache 和 Request Memoization 兼容
|
|
5
|
+
* 保留 next.revalidate、next.tags 等选项
|
|
6
|
+
*/
|
|
7
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
8
|
+
// 用于存储当前路由信息的 AsyncLocalStorage
|
|
9
|
+
const routeStorage = new AsyncLocalStorage();
|
|
10
|
+
/**
|
|
11
|
+
* 检测是否在 Next.js 环境中
|
|
12
|
+
*/
|
|
13
|
+
export function isNextJsEnvironment() {
|
|
14
|
+
// 检查 Next.js 特有的环境变量
|
|
15
|
+
return !!(process.env.NEXT_RUNTIME ||
|
|
16
|
+
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT ||
|
|
17
|
+
process.env.NEXT_DEPLOYMENT_ID);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 获取当前路由信息
|
|
21
|
+
*/
|
|
22
|
+
export function getCurrentRoute() {
|
|
23
|
+
return routeStorage.getStore();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 在指定路由上下文中运行函数
|
|
27
|
+
*/
|
|
28
|
+
export function runWithRoute(route, type, fn) {
|
|
29
|
+
return routeStorage.run({ route, type }, fn);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 异步版本的 runWithRoute
|
|
33
|
+
*/
|
|
34
|
+
export async function runWithRouteAsync(route, type, fn) {
|
|
35
|
+
return routeStorage.run({ route, type }, fn);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 提取 Next.js fetch 选项
|
|
39
|
+
*/
|
|
40
|
+
export function extractNextJsOptions(init) {
|
|
41
|
+
if (!init)
|
|
42
|
+
return undefined;
|
|
43
|
+
const options = {};
|
|
44
|
+
// 提取 next 选项
|
|
45
|
+
if ('next' in init && init.next) {
|
|
46
|
+
const nextOpts = init.next;
|
|
47
|
+
options.next = {
|
|
48
|
+
revalidate: nextOpts.revalidate,
|
|
49
|
+
tags: nextOpts.tags,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// 提取 cache 选项
|
|
53
|
+
if ('cache' in init && init.cache) {
|
|
54
|
+
options.cache = init.cache;
|
|
55
|
+
}
|
|
56
|
+
return Object.keys(options).length > 0 ? options : undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 从请求中提取 Next.js 元数据
|
|
60
|
+
*/
|
|
61
|
+
export function extractNextJsMetadata(init, responseHeaders) {
|
|
62
|
+
const metadata = {};
|
|
63
|
+
// 获取当前路由
|
|
64
|
+
const routeInfo = getCurrentRoute();
|
|
65
|
+
if (routeInfo) {
|
|
66
|
+
metadata.route = routeInfo.route;
|
|
67
|
+
metadata.requestType = routeInfo.type;
|
|
68
|
+
}
|
|
69
|
+
// 提取 fetch 选项
|
|
70
|
+
const nextOptions = extractNextJsOptions(init);
|
|
71
|
+
if (nextOptions?.next) {
|
|
72
|
+
metadata.revalidate = nextOptions.next.revalidate;
|
|
73
|
+
metadata.tags = nextOptions.next.tags;
|
|
74
|
+
}
|
|
75
|
+
// 从响应头提取缓存状态
|
|
76
|
+
if (responseHeaders) {
|
|
77
|
+
const cacheStatus = getHeader(responseHeaders, 'x-nextjs-cache');
|
|
78
|
+
if (cacheStatus) {
|
|
79
|
+
metadata.cacheStatus = cacheStatus;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return metadata;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 辅助函数:获取响应头
|
|
86
|
+
*/
|
|
87
|
+
function getHeader(headers, name) {
|
|
88
|
+
if (headers instanceof Headers) {
|
|
89
|
+
return headers.get(name) ?? undefined;
|
|
90
|
+
}
|
|
91
|
+
return headers[name] || headers[name.toLowerCase()];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 创建 Next.js instrumentation 配置
|
|
95
|
+
*/
|
|
96
|
+
export function createInstrumentationConfig() {
|
|
97
|
+
return `// instrumentation.ts
|
|
98
|
+
// 将此文件放在 Next.js 项目根目录
|
|
99
|
+
|
|
100
|
+
export async function register() {
|
|
101
|
+
// 仅在服务端运行
|
|
102
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
103
|
+
// 动态导入以避免客户端打包
|
|
104
|
+
const { install } = await import('node-network-devtools');
|
|
105
|
+
await install();
|
|
106
|
+
console.log('[node-network-devtools] 已在 Next.js 服务端初始化');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Next.js 适配器对象
|
|
113
|
+
*/
|
|
114
|
+
export const NextJsAdapter = {
|
|
115
|
+
isNextJsEnvironment,
|
|
116
|
+
getCurrentRoute,
|
|
117
|
+
runWithRoute,
|
|
118
|
+
runWithRouteAsync,
|
|
119
|
+
extractNextJsOptions,
|
|
120
|
+
extractNextJsMetadata,
|
|
121
|
+
createInstrumentationConfig,
|
|
122
|
+
};
|
|
123
|
+
//# 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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"}
|