next-fetch-panel 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.
@@ -0,0 +1,35 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+
3
+ type MiddlewareHandler = (request: NextRequest) => NextResponse | Response | null | undefined | void | Promise<NextResponse | Response | null | undefined | void>;
4
+ /**
5
+ * Wraps your existing middleware with the dev panel session logic.
6
+ *
7
+ * Simple (no other middleware):
8
+ * export const { middleware, config } = withDevPanel()
9
+ *
10
+ * With your own logic:
11
+ * export const { middleware, config } = withDevPanel(async (request) => {
12
+ * if (!isAuthenticated(request))
13
+ * return NextResponse.redirect(new URL("/login", request.url))
14
+ * // return nothing to let the request continue normally
15
+ * })
16
+ *
17
+ * Custom matcher:
18
+ * export const { middleware, config } = withDevPanel(handler, {
19
+ * matcher: ["/api/:path*", "/((?!_next).*)"],
20
+ * })
21
+ */
22
+ declare function withDevPanel(handler?: MiddlewareHandler, options?: {
23
+ matcher?: string[];
24
+ }): {
25
+ middleware: (request: NextRequest) => Promise<NextResponse<unknown>>;
26
+ config: {
27
+ matcher: string[];
28
+ };
29
+ };
30
+ declare const middleware: (request: NextRequest) => Promise<NextResponse<unknown>>;
31
+ declare const config: {
32
+ matcher: string[];
33
+ };
34
+
35
+ export { config, middleware, withDevPanel };
@@ -0,0 +1,35 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+
3
+ type MiddlewareHandler = (request: NextRequest) => NextResponse | Response | null | undefined | void | Promise<NextResponse | Response | null | undefined | void>;
4
+ /**
5
+ * Wraps your existing middleware with the dev panel session logic.
6
+ *
7
+ * Simple (no other middleware):
8
+ * export const { middleware, config } = withDevPanel()
9
+ *
10
+ * With your own logic:
11
+ * export const { middleware, config } = withDevPanel(async (request) => {
12
+ * if (!isAuthenticated(request))
13
+ * return NextResponse.redirect(new URL("/login", request.url))
14
+ * // return nothing to let the request continue normally
15
+ * })
16
+ *
17
+ * Custom matcher:
18
+ * export const { middleware, config } = withDevPanel(handler, {
19
+ * matcher: ["/api/:path*", "/((?!_next).*)"],
20
+ * })
21
+ */
22
+ declare function withDevPanel(handler?: MiddlewareHandler, options?: {
23
+ matcher?: string[];
24
+ }): {
25
+ middleware: (request: NextRequest) => Promise<NextResponse<unknown>>;
26
+ config: {
27
+ matcher: string[];
28
+ };
29
+ };
30
+ declare const middleware: (request: NextRequest) => Promise<NextResponse<unknown>>;
31
+ declare const config: {
32
+ matcher: string[];
33
+ };
34
+
35
+ export { config, middleware, withDevPanel };
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/middleware.ts
21
+ var middleware_exports = {};
22
+ __export(middleware_exports, {
23
+ config: () => config,
24
+ middleware: () => middleware,
25
+ withDevPanel: () => withDevPanel
26
+ });
27
+ module.exports = __toCommonJS(middleware_exports);
28
+ var import_server = require("next/server");
29
+ function withDevPanel(handler, options) {
30
+ async function middleware2(request) {
31
+ const existing = request.cookies.get("__dev_sid")?.value;
32
+ const sid = existing ?? crypto.randomUUID();
33
+ const userResponse = await handler?.(request);
34
+ let response;
35
+ if (userResponse instanceof Response) {
36
+ response = userResponse;
37
+ } else {
38
+ const requestHeaders = new Headers(request.headers);
39
+ requestHeaders.set("x-dev-sid", sid);
40
+ response = import_server.NextResponse.next({ request: { headers: requestHeaders } });
41
+ }
42
+ if (!existing) {
43
+ response.cookies.set("__dev_sid", sid, {
44
+ httpOnly: true,
45
+ sameSite: "lax",
46
+ path: "/",
47
+ maxAge: 60 * 60 * 24 * 365
48
+ });
49
+ }
50
+ return response;
51
+ }
52
+ return {
53
+ middleware: middleware2,
54
+ config: {
55
+ matcher: options?.matcher ?? ["/((?!_next/static|_next/image|favicon.ico).*)"]
56
+ }
57
+ };
58
+ }
59
+ var { middleware, config } = withDevPanel();
60
+ // Annotate the CommonJS export names for ESM import in node:
61
+ 0 && (module.exports = {
62
+ config,
63
+ middleware,
64
+ withDevPanel
65
+ });
@@ -0,0 +1,38 @@
1
+ // src/middleware.ts
2
+ import { NextResponse } from "next/server";
3
+ function withDevPanel(handler, options) {
4
+ async function middleware2(request) {
5
+ const existing = request.cookies.get("__dev_sid")?.value;
6
+ const sid = existing ?? crypto.randomUUID();
7
+ const userResponse = await handler?.(request);
8
+ let response;
9
+ if (userResponse instanceof Response) {
10
+ response = userResponse;
11
+ } else {
12
+ const requestHeaders = new Headers(request.headers);
13
+ requestHeaders.set("x-dev-sid", sid);
14
+ response = NextResponse.next({ request: { headers: requestHeaders } });
15
+ }
16
+ if (!existing) {
17
+ response.cookies.set("__dev_sid", sid, {
18
+ httpOnly: true,
19
+ sameSite: "lax",
20
+ path: "/",
21
+ maxAge: 60 * 60 * 24 * 365
22
+ });
23
+ }
24
+ return response;
25
+ }
26
+ return {
27
+ middleware: middleware2,
28
+ config: {
29
+ matcher: options?.matcher ?? ["/((?!_next/static|_next/image|favicon.ico).*)"]
30
+ }
31
+ };
32
+ }
33
+ var { middleware, config } = withDevPanel();
34
+ export {
35
+ config,
36
+ middleware,
37
+ withDevPanel
38
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Patches globalThis.fetch to capture server-side requests.
3
+ * Call this inside your own register() if you already have one:
4
+ *
5
+ * export async function register() {
6
+ * registerOTel("my-app") // your existing setup
7
+ * await registerDevPanel() // add the panel
8
+ * }
9
+ *
10
+ * For simple use with no other setup:
11
+ * export { register } from "./server-network-panel/patch"
12
+ */
13
+ declare function registerDevPanel(): Promise<void>;
14
+
15
+ export { registerDevPanel as register, registerDevPanel };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Patches globalThis.fetch to capture server-side requests.
3
+ * Call this inside your own register() if you already have one:
4
+ *
5
+ * export async function register() {
6
+ * registerOTel("my-app") // your existing setup
7
+ * await registerDevPanel() // add the panel
8
+ * }
9
+ *
10
+ * For simple use with no other setup:
11
+ * export { register } from "./server-network-panel/patch"
12
+ */
13
+ declare function registerDevPanel(): Promise<void>;
14
+
15
+ export { registerDevPanel as register, registerDevPanel };
package/dist/patch.js ADDED
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // src/store.ts
34
+ var store_exports = {};
35
+ __export(store_exports, {
36
+ devLogStore: () => devLogStore
37
+ });
38
+ function createStore() {
39
+ const subscribers = /* @__PURE__ */ new Set();
40
+ const buffer = [];
41
+ return {
42
+ push(entry) {
43
+ buffer.push(entry);
44
+ if (buffer.length > BUFFER_SIZE) buffer.shift();
45
+ subscribers.forEach((fn) => fn(entry));
46
+ },
47
+ subscribe(fn) {
48
+ subscribers.add(fn);
49
+ return () => subscribers.delete(fn);
50
+ },
51
+ getBuffer() {
52
+ return buffer.slice();
53
+ }
54
+ };
55
+ }
56
+ var BUFFER_SIZE, devLogStore;
57
+ var init_store = __esm({
58
+ "src/store.ts"() {
59
+ "use strict";
60
+ BUFFER_SIZE = 100;
61
+ devLogStore = globalThis.__devLogStore ?? (globalThis.__devLogStore = createStore());
62
+ }
63
+ });
64
+
65
+ // src/redact.ts
66
+ var redact_exports = {};
67
+ __export(redact_exports, {
68
+ redactConfig: () => redactConfig,
69
+ redactEntry: () => redactEntry
70
+ });
71
+ function redactUrl(url, params) {
72
+ try {
73
+ const u = new URL(url);
74
+ for (const key of params) {
75
+ if (u.searchParams.has(key)) u.searchParams.set(key, REDACTED);
76
+ }
77
+ return u.toString();
78
+ } catch {
79
+ return url;
80
+ }
81
+ }
82
+ function redactHeaders(headers, names) {
83
+ const lower = new Set(names.map((n) => n.toLowerCase()));
84
+ const out = {};
85
+ for (const [k, v] of Object.entries(headers)) {
86
+ out[k] = lower.has(k.toLowerCase()) ? REDACTED : v;
87
+ }
88
+ return out;
89
+ }
90
+ function redactBody(body, keys) {
91
+ if (!body) return body;
92
+ try {
93
+ const parsed = JSON.parse(body);
94
+ for (const key of keys) {
95
+ if (key in parsed) parsed[key] = REDACTED;
96
+ }
97
+ return JSON.stringify(parsed, null, 2);
98
+ } catch {
99
+ return body;
100
+ }
101
+ }
102
+ function redactEntry(entry) {
103
+ return {
104
+ ...entry,
105
+ url: redactUrl(entry.url, redactConfig.urlParams),
106
+ requestHeaders: redactHeaders(entry.requestHeaders, redactConfig.headers),
107
+ responseHeaders: redactHeaders(entry.responseHeaders, redactConfig.headers),
108
+ requestBody: redactBody(entry.requestBody, redactConfig.bodyKeys),
109
+ responseBody: redactBody(entry.responseBody, redactConfig.bodyKeys)
110
+ };
111
+ }
112
+ var redactConfig, REDACTED;
113
+ var init_redact = __esm({
114
+ "src/redact.ts"() {
115
+ "use strict";
116
+ redactConfig = {
117
+ urlParams: ["api_key", "apikey", "secret", "token", "access_token", "password", "key"],
118
+ headers: ["authorization", "x-api-key", "x-secret", "x-auth-token"],
119
+ bodyKeys: ["password", "secret", "token", "api_key", "apiKey", "accessToken", "access_token"]
120
+ };
121
+ REDACTED = "[REDACTED]";
122
+ }
123
+ });
124
+
125
+ // src/patch.ts
126
+ var patch_exports = {};
127
+ __export(patch_exports, {
128
+ register: () => registerDevPanel,
129
+ registerDevPanel: () => registerDevPanel
130
+ });
131
+ module.exports = __toCommonJS(patch_exports);
132
+ var BODY_LIMIT = 5e4;
133
+ function headersToObject(headers) {
134
+ if (!headers) return {};
135
+ if (headers instanceof Headers) {
136
+ const obj = {};
137
+ headers.forEach((v, k) => {
138
+ obj[k] = v;
139
+ });
140
+ return obj;
141
+ }
142
+ if (Array.isArray(headers)) return Object.fromEntries(headers);
143
+ return headers;
144
+ }
145
+ function extractRequestBody(init) {
146
+ const body = init?.body;
147
+ if (body == null) return null;
148
+ if (typeof body === "string") return body.slice(0, BODY_LIMIT);
149
+ if (body instanceof URLSearchParams) return body.toString().slice(0, BODY_LIMIT);
150
+ return "[binary]";
151
+ }
152
+ var nextHeaders = null;
153
+ async function getSessionId() {
154
+ try {
155
+ if (!nextHeaders) {
156
+ const mod = await import("next/headers");
157
+ nextHeaders = mod.headers;
158
+ }
159
+ return (await nextHeaders()).get("x-dev-sid");
160
+ } catch {
161
+ return null;
162
+ }
163
+ }
164
+ async function registerDevPanel() {
165
+ if (process.env.NEXT_RUNTIME !== "nodejs") return;
166
+ const { devLogStore: devLogStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
167
+ const { redactEntry: redactEntry2 } = await Promise.resolve().then(() => (init_redact(), redact_exports));
168
+ const originalFetch = globalThis.fetch;
169
+ globalThis.fetch = async function patchedFetch(input, init) {
170
+ const method = (init?.method ?? "GET").toUpperCase();
171
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
172
+ const ts = Date.now();
173
+ const id = `${ts}-${Math.random().toString(36).slice(2, 8)}`;
174
+ const requestHeaders = headersToObject(init?.headers);
175
+ const requestBody = extractRequestBody(init);
176
+ const sessionId = await getSessionId();
177
+ const start = performance.now();
178
+ try {
179
+ const response = await originalFetch(input, init);
180
+ const duration = Math.round(performance.now() - start);
181
+ const responseHeaders = {};
182
+ response.headers.forEach((v, k) => {
183
+ responseHeaders[k] = v;
184
+ });
185
+ response.clone().text().then(
186
+ (text) => devLogStore2.push(redactEntry2({
187
+ id,
188
+ url,
189
+ method,
190
+ ts,
191
+ duration,
192
+ error: void 0,
193
+ status: response.status,
194
+ statusText: response.statusText,
195
+ requestHeaders,
196
+ responseHeaders,
197
+ requestBody,
198
+ responseBody: text.slice(0, BODY_LIMIT),
199
+ sessionId
200
+ })),
201
+ () => devLogStore2.push(redactEntry2({
202
+ id,
203
+ url,
204
+ method,
205
+ ts,
206
+ duration,
207
+ error: void 0,
208
+ status: response.status,
209
+ statusText: response.statusText,
210
+ requestHeaders,
211
+ responseHeaders,
212
+ requestBody,
213
+ responseBody: null,
214
+ sessionId
215
+ }))
216
+ );
217
+ return response;
218
+ } catch (err) {
219
+ const duration = Math.round(performance.now() - start);
220
+ const error = err instanceof Error ? err.message : String(err);
221
+ devLogStore2.push(redactEntry2({
222
+ id,
223
+ url,
224
+ method,
225
+ ts,
226
+ duration,
227
+ error,
228
+ status: null,
229
+ statusText: null,
230
+ requestHeaders,
231
+ responseHeaders: {},
232
+ requestBody,
233
+ responseBody: null,
234
+ sessionId
235
+ }));
236
+ throw err;
237
+ }
238
+ };
239
+ }
240
+ // Annotate the CommonJS export names for ESM import in node:
241
+ 0 && (module.exports = {
242
+ register,
243
+ registerDevPanel
244
+ });
package/dist/patch.mjs ADDED
@@ -0,0 +1,215 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/store.ts
12
+ var store_exports = {};
13
+ __export(store_exports, {
14
+ devLogStore: () => devLogStore
15
+ });
16
+ function createStore() {
17
+ const subscribers = /* @__PURE__ */ new Set();
18
+ const buffer = [];
19
+ return {
20
+ push(entry) {
21
+ buffer.push(entry);
22
+ if (buffer.length > BUFFER_SIZE) buffer.shift();
23
+ subscribers.forEach((fn) => fn(entry));
24
+ },
25
+ subscribe(fn) {
26
+ subscribers.add(fn);
27
+ return () => subscribers.delete(fn);
28
+ },
29
+ getBuffer() {
30
+ return buffer.slice();
31
+ }
32
+ };
33
+ }
34
+ var BUFFER_SIZE, devLogStore;
35
+ var init_store = __esm({
36
+ "src/store.ts"() {
37
+ "use strict";
38
+ BUFFER_SIZE = 100;
39
+ devLogStore = globalThis.__devLogStore ?? (globalThis.__devLogStore = createStore());
40
+ }
41
+ });
42
+
43
+ // src/redact.ts
44
+ var redact_exports = {};
45
+ __export(redact_exports, {
46
+ redactConfig: () => redactConfig,
47
+ redactEntry: () => redactEntry
48
+ });
49
+ function redactUrl(url, params) {
50
+ try {
51
+ const u = new URL(url);
52
+ for (const key of params) {
53
+ if (u.searchParams.has(key)) u.searchParams.set(key, REDACTED);
54
+ }
55
+ return u.toString();
56
+ } catch {
57
+ return url;
58
+ }
59
+ }
60
+ function redactHeaders(headers, names) {
61
+ const lower = new Set(names.map((n) => n.toLowerCase()));
62
+ const out = {};
63
+ for (const [k, v] of Object.entries(headers)) {
64
+ out[k] = lower.has(k.toLowerCase()) ? REDACTED : v;
65
+ }
66
+ return out;
67
+ }
68
+ function redactBody(body, keys) {
69
+ if (!body) return body;
70
+ try {
71
+ const parsed = JSON.parse(body);
72
+ for (const key of keys) {
73
+ if (key in parsed) parsed[key] = REDACTED;
74
+ }
75
+ return JSON.stringify(parsed, null, 2);
76
+ } catch {
77
+ return body;
78
+ }
79
+ }
80
+ function redactEntry(entry) {
81
+ return {
82
+ ...entry,
83
+ url: redactUrl(entry.url, redactConfig.urlParams),
84
+ requestHeaders: redactHeaders(entry.requestHeaders, redactConfig.headers),
85
+ responseHeaders: redactHeaders(entry.responseHeaders, redactConfig.headers),
86
+ requestBody: redactBody(entry.requestBody, redactConfig.bodyKeys),
87
+ responseBody: redactBody(entry.responseBody, redactConfig.bodyKeys)
88
+ };
89
+ }
90
+ var redactConfig, REDACTED;
91
+ var init_redact = __esm({
92
+ "src/redact.ts"() {
93
+ "use strict";
94
+ redactConfig = {
95
+ urlParams: ["api_key", "apikey", "secret", "token", "access_token", "password", "key"],
96
+ headers: ["authorization", "x-api-key", "x-secret", "x-auth-token"],
97
+ bodyKeys: ["password", "secret", "token", "api_key", "apiKey", "accessToken", "access_token"]
98
+ };
99
+ REDACTED = "[REDACTED]";
100
+ }
101
+ });
102
+
103
+ // src/patch.ts
104
+ var BODY_LIMIT = 5e4;
105
+ function headersToObject(headers) {
106
+ if (!headers) return {};
107
+ if (headers instanceof Headers) {
108
+ const obj = {};
109
+ headers.forEach((v, k) => {
110
+ obj[k] = v;
111
+ });
112
+ return obj;
113
+ }
114
+ if (Array.isArray(headers)) return Object.fromEntries(headers);
115
+ return headers;
116
+ }
117
+ function extractRequestBody(init) {
118
+ const body = init?.body;
119
+ if (body == null) return null;
120
+ if (typeof body === "string") return body.slice(0, BODY_LIMIT);
121
+ if (body instanceof URLSearchParams) return body.toString().slice(0, BODY_LIMIT);
122
+ return "[binary]";
123
+ }
124
+ var nextHeaders = null;
125
+ async function getSessionId() {
126
+ try {
127
+ if (!nextHeaders) {
128
+ const mod = await import("next/headers");
129
+ nextHeaders = mod.headers;
130
+ }
131
+ return (await nextHeaders()).get("x-dev-sid");
132
+ } catch {
133
+ return null;
134
+ }
135
+ }
136
+ async function registerDevPanel() {
137
+ if (process.env.NEXT_RUNTIME !== "nodejs") return;
138
+ const { devLogStore: devLogStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
139
+ const { redactEntry: redactEntry2 } = await Promise.resolve().then(() => (init_redact(), redact_exports));
140
+ const originalFetch = globalThis.fetch;
141
+ globalThis.fetch = async function patchedFetch(input, init) {
142
+ const method = (init?.method ?? "GET").toUpperCase();
143
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
144
+ const ts = Date.now();
145
+ const id = `${ts}-${Math.random().toString(36).slice(2, 8)}`;
146
+ const requestHeaders = headersToObject(init?.headers);
147
+ const requestBody = extractRequestBody(init);
148
+ const sessionId = await getSessionId();
149
+ const start = performance.now();
150
+ try {
151
+ const response = await originalFetch(input, init);
152
+ const duration = Math.round(performance.now() - start);
153
+ const responseHeaders = {};
154
+ response.headers.forEach((v, k) => {
155
+ responseHeaders[k] = v;
156
+ });
157
+ response.clone().text().then(
158
+ (text) => devLogStore2.push(redactEntry2({
159
+ id,
160
+ url,
161
+ method,
162
+ ts,
163
+ duration,
164
+ error: void 0,
165
+ status: response.status,
166
+ statusText: response.statusText,
167
+ requestHeaders,
168
+ responseHeaders,
169
+ requestBody,
170
+ responseBody: text.slice(0, BODY_LIMIT),
171
+ sessionId
172
+ })),
173
+ () => devLogStore2.push(redactEntry2({
174
+ id,
175
+ url,
176
+ method,
177
+ ts,
178
+ duration,
179
+ error: void 0,
180
+ status: response.status,
181
+ statusText: response.statusText,
182
+ requestHeaders,
183
+ responseHeaders,
184
+ requestBody,
185
+ responseBody: null,
186
+ sessionId
187
+ }))
188
+ );
189
+ return response;
190
+ } catch (err) {
191
+ const duration = Math.round(performance.now() - start);
192
+ const error = err instanceof Error ? err.message : String(err);
193
+ devLogStore2.push(redactEntry2({
194
+ id,
195
+ url,
196
+ method,
197
+ ts,
198
+ duration,
199
+ error,
200
+ status: null,
201
+ statusText: null,
202
+ requestHeaders,
203
+ responseHeaders: {},
204
+ requestBody,
205
+ responseBody: null,
206
+ sessionId
207
+ }));
208
+ throw err;
209
+ }
210
+ };
211
+ }
212
+ export {
213
+ registerDevPanel as register,
214
+ registerDevPanel
215
+ };
@@ -0,0 +1,23 @@
1
+ declare const dynamic = "force-dynamic";
2
+ type GuardFn = (request: Request) => Response | null | undefined | void | Promise<Response | null | undefined | void>;
3
+ /**
4
+ * Returns a Next.js Route Handler GET function for the SSE stream.
5
+ * Use the guard option to add authentication or any other access control:
6
+ *
7
+ * export const dynamic = "force-dynamic"
8
+ * export const GET = createDevPanelRoute({
9
+ * guard: (request) => {
10
+ * const token = request.headers.get("authorization")
11
+ * if (!isValidToken(token)) return new Response("Forbidden", { status: 403 })
12
+ * },
13
+ * })
14
+ *
15
+ * For simple use with no access control:
16
+ * export { dynamic, GET } from "@/server-network-panel/route"
17
+ */
18
+ declare function createDevPanelRoute(options?: {
19
+ guard?: GuardFn;
20
+ }): (request: Request) => Promise<Response>;
21
+ declare const GET: (request: Request) => Promise<Response>;
22
+
23
+ export { GET, createDevPanelRoute, dynamic };