@beignet/devtools 0.0.1
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/CHANGELOG.md +5 -0
- package/README.md +464 -0
- package/dist/access.d.ts +21 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +20 -0
- package/dist/access.js.map +1 -0
- package/dist/audit.d.ts +10 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +49 -0
- package/dist/audit.js.map +1 -0
- package/dist/events.d.ts +143 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +20 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation.d.ts +74 -0
- package/dist/instrumentation.d.ts.map +1 -0
- package/dist/instrumentation.js +293 -0
- package/dist/instrumentation.js.map +1 -0
- package/dist/persistence.d.ts +30 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/persistence.js +100 -0
- package/dist/persistence.js.map +1 -0
- package/dist/provider-instrumentation.d.ts +9 -0
- package/dist/provider-instrumentation.d.ts.map +1 -0
- package/dist/provider-instrumentation.js +25 -0
- package/dist/provider-instrumentation.js.map +1 -0
- package/dist/provider.d.ts +79 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +293 -0
- package/dist/provider.js.map +1 -0
- package/dist/redaction.d.ts +5 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +20 -0
- package/dist/redaction.js.map +1 -0
- package/dist/routes.d.ts +113 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +247 -0
- package/dist/routes.js.map +1 -0
- package/dist/trace-context.d.ts +29 -0
- package/dist/trace-context.d.ts.map +1 -0
- package/dist/trace-context.js +74 -0
- package/dist/trace-context.js.map +1 -0
- package/dist/ui.d.ts +14 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +795 -0
- package/dist/ui.js.map +1 -0
- package/dist/watchers.d.ts +22 -0
- package/dist/watchers.d.ts.map +1 -0
- package/dist/watchers.js +171 -0
- package/dist/watchers.js.map +1 -0
- package/package.json +66 -0
- package/src/access.ts +52 -0
- package/src/audit.ts +71 -0
- package/src/events.ts +193 -0
- package/src/index.ts +136 -0
- package/src/instrumentation.ts +451 -0
- package/src/persistence.ts +163 -0
- package/src/provider-instrumentation.ts +50 -0
- package/src/provider.ts +375 -0
- package/src/redaction.ts +26 -0
- package/src/routes.ts +317 -0
- package/src/trace-context.ts +115 -0
- package/src/ui.ts +807 -0
- package/src/watchers.ts +235 -0
package/dist/routes.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP handlers for devtools API
|
|
3
|
+
*
|
|
4
|
+
* These handlers can be used to expose devtools data via HTTP endpoints
|
|
5
|
+
* in Next.js or any other framework that uses the Fetch API Request/Response.
|
|
6
|
+
*/
|
|
7
|
+
import { authorizeDevtoolsRequest, } from "./access";
|
|
8
|
+
import { isDevtoolsEventType } from "./events";
|
|
9
|
+
import { handleDevtoolsUIRequest } from "./ui";
|
|
10
|
+
/**
|
|
11
|
+
* Handle GET requests to list devtools events with optional filtering.
|
|
12
|
+
*
|
|
13
|
+
* Query parameters:
|
|
14
|
+
* - type: Filter by event type (request, error, usecase, eventBus, job, schedule, provider)
|
|
15
|
+
* - requestId: Filter by request correlation ID
|
|
16
|
+
* - traceId: Filter by W3C trace ID
|
|
17
|
+
* - limit: Maximum number of events to return (default: 200)
|
|
18
|
+
*
|
|
19
|
+
* @param req - The incoming HTTP request
|
|
20
|
+
* @param devtools - The DevtoolsPort instance to query
|
|
21
|
+
* @returns JSON response with events array
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* // In a Next.js route handler:
|
|
26
|
+
* // app/api/devtools/core/events/route.ts
|
|
27
|
+
* import { handleDevtoolsEventsRequest } from "@beignet/devtools";
|
|
28
|
+
*
|
|
29
|
+
* export async function GET(req: Request) {
|
|
30
|
+
* const devtools = getAppDevtoolsPort(); // app-specific helper
|
|
31
|
+
* return handleDevtoolsEventsRequest(req, devtools);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export async function handleDevtoolsEventsRequest(req, devtools, options = {}) {
|
|
36
|
+
const denied = await authorizeDevtoolsRequest(req, options);
|
|
37
|
+
if (denied)
|
|
38
|
+
return denied;
|
|
39
|
+
const url = new URL(req.url);
|
|
40
|
+
const type = url.searchParams.get("type");
|
|
41
|
+
const requestId = url.searchParams.get("requestId");
|
|
42
|
+
const traceId = url.searchParams.get("traceId");
|
|
43
|
+
const limitParam = url.searchParams.get("limit");
|
|
44
|
+
if (type !== null && !isDevtoolsEventType(type)) {
|
|
45
|
+
return new Response(JSON.stringify({ error: "Invalid event type" }), {
|
|
46
|
+
status: 400,
|
|
47
|
+
headers: {
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
"Cache-Control": "no-store",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
let limit;
|
|
54
|
+
if (limitParam !== null) {
|
|
55
|
+
const parsed = Number.parseInt(limitParam, 10);
|
|
56
|
+
if (!Number.isNaN(parsed)) {
|
|
57
|
+
limit = parsed;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const filter = {
|
|
61
|
+
type: type ?? undefined,
|
|
62
|
+
requestId: requestId ?? undefined,
|
|
63
|
+
traceId: traceId ?? undefined,
|
|
64
|
+
limit,
|
|
65
|
+
};
|
|
66
|
+
const events = devtools.getEvents(filter);
|
|
67
|
+
return new Response(JSON.stringify({
|
|
68
|
+
events,
|
|
69
|
+
watchers: devtools.getWatchers(),
|
|
70
|
+
}), {
|
|
71
|
+
status: 200,
|
|
72
|
+
headers: {
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
"Cache-Control": "no-store",
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Handle POST requests to clear all devtools events.
|
|
80
|
+
*
|
|
81
|
+
* This endpoint requires a POST request and will clear the in-memory event buffer.
|
|
82
|
+
*
|
|
83
|
+
* @param req - The incoming HTTP request
|
|
84
|
+
* @param devtools - The DevtoolsPort instance to clear
|
|
85
|
+
* @returns JSON response with success status
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* // In a Next.js route handler:
|
|
90
|
+
* // app/api/devtools/clear/route.ts
|
|
91
|
+
* import { handleDevtoolsClearRequest } from "@beignet/devtools";
|
|
92
|
+
*
|
|
93
|
+
* export async function POST(req: Request) {
|
|
94
|
+
* const devtools = getAppDevtoolsPort(); // app-specific helper
|
|
95
|
+
* return handleDevtoolsClearRequest(req, devtools);
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export async function handleDevtoolsClearRequest(req, devtools, options = {}) {
|
|
100
|
+
const denied = await authorizeDevtoolsRequest(req, options);
|
|
101
|
+
if (denied)
|
|
102
|
+
return denied;
|
|
103
|
+
if (req.method !== "POST") {
|
|
104
|
+
return new Response("Method Not Allowed", { status: 405 });
|
|
105
|
+
}
|
|
106
|
+
await devtools.clear();
|
|
107
|
+
return new Response(JSON.stringify({ ok: true }), {
|
|
108
|
+
status: 200,
|
|
109
|
+
headers: {
|
|
110
|
+
"Content-Type": "application/json",
|
|
111
|
+
"Cache-Control": "no-store",
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function encodeSse(event, data) {
|
|
116
|
+
return new TextEncoder().encode(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handle GET requests for a live Server-Sent Events stream.
|
|
120
|
+
*
|
|
121
|
+
* The stream emits:
|
|
122
|
+
* - `snapshot` with the current event buffer
|
|
123
|
+
* - `event` when a new event is recorded
|
|
124
|
+
* - `clear` when the buffer is cleared
|
|
125
|
+
*/
|
|
126
|
+
export async function handleDevtoolsStreamRequest(req, devtools, options = {}) {
|
|
127
|
+
const denied = await authorizeDevtoolsRequest(req, options);
|
|
128
|
+
if (denied)
|
|
129
|
+
return denied;
|
|
130
|
+
if (req.method !== "GET") {
|
|
131
|
+
return new Response("Method Not Allowed", { status: 405 });
|
|
132
|
+
}
|
|
133
|
+
let unsubscribe;
|
|
134
|
+
const stream = new ReadableStream({
|
|
135
|
+
start(controller) {
|
|
136
|
+
let closed = false;
|
|
137
|
+
const enqueue = (event, data) => {
|
|
138
|
+
if (closed)
|
|
139
|
+
return;
|
|
140
|
+
try {
|
|
141
|
+
controller.enqueue(encodeSse(event, data));
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
closed = true;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
enqueue("snapshot", {
|
|
148
|
+
events: devtools.getEvents({ limit: 500 }),
|
|
149
|
+
watchers: devtools.getWatchers(),
|
|
150
|
+
});
|
|
151
|
+
unsubscribe = devtools.subscribe((event) => {
|
|
152
|
+
if (event.type === "record") {
|
|
153
|
+
enqueue("event", { event: event.event });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
enqueue("clear", { ok: true });
|
|
157
|
+
});
|
|
158
|
+
req.signal.addEventListener("abort", () => {
|
|
159
|
+
closed = true;
|
|
160
|
+
unsubscribe?.();
|
|
161
|
+
try {
|
|
162
|
+
controller.close();
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// The stream may already be closed by the client.
|
|
166
|
+
}
|
|
167
|
+
}, { once: true });
|
|
168
|
+
},
|
|
169
|
+
cancel() {
|
|
170
|
+
unsubscribe?.();
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
return new Response(stream, {
|
|
174
|
+
status: 200,
|
|
175
|
+
headers: {
|
|
176
|
+
"Content-Type": "text/event-stream; charset=utf-8",
|
|
177
|
+
"Cache-Control": "no-store, no-transform",
|
|
178
|
+
Connection: "keep-alive",
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Unified devtools request handler.
|
|
184
|
+
*
|
|
185
|
+
* Routes requests to the appropriate handler based on the URL path:
|
|
186
|
+
* - `{basePath}/core/events` → event list (GET)
|
|
187
|
+
* - `{basePath}/stream` → live event stream (GET)
|
|
188
|
+
* - `{basePath}/clear` → clear buffer (POST)
|
|
189
|
+
* - `{basePath}` → dashboard UI (GET)
|
|
190
|
+
*
|
|
191
|
+
* This lets you wire up a single catch-all route instead of three separate ones.
|
|
192
|
+
*
|
|
193
|
+
* @param req - The incoming HTTP request
|
|
194
|
+
* @param devtools - The DevtoolsPort instance
|
|
195
|
+
* @param options - Devtools route options including base path and access policy
|
|
196
|
+
* @returns Response for the matched sub-route
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* // Next.js catch-all route: app/api/devtools/[[...path]]/route.ts
|
|
201
|
+
* import { createDevtoolsRoute } from "@beignet/devtools";
|
|
202
|
+
* import { getDevtools } from "@/server";
|
|
203
|
+
*
|
|
204
|
+
* export const { GET, POST } = createDevtoolsRoute(getDevtools(), {
|
|
205
|
+
* basePath: "/api/devtools",
|
|
206
|
+
* });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export async function handleDevtoolsRequest(req, devtools, options) {
|
|
210
|
+
const denied = await authorizeDevtoolsRequest(req, options);
|
|
211
|
+
if (denied)
|
|
212
|
+
return denied;
|
|
213
|
+
const url = new URL(req.url);
|
|
214
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
215
|
+
const normalizedBase = options.basePath.replace(/\/+$/, "");
|
|
216
|
+
const accessChecked = { enabled: true };
|
|
217
|
+
if (path === `${normalizedBase}/core/events`) {
|
|
218
|
+
return handleDevtoolsEventsRequest(req, devtools, accessChecked);
|
|
219
|
+
}
|
|
220
|
+
if (path === `${normalizedBase}/clear`) {
|
|
221
|
+
return handleDevtoolsClearRequest(req, devtools, accessChecked);
|
|
222
|
+
}
|
|
223
|
+
if (path === `${normalizedBase}/stream`) {
|
|
224
|
+
return handleDevtoolsStreamRequest(req, devtools, accessChecked);
|
|
225
|
+
}
|
|
226
|
+
if (path === normalizedBase) {
|
|
227
|
+
if (req.method !== "GET") {
|
|
228
|
+
return new Response("Method Not Allowed", { status: 405 });
|
|
229
|
+
}
|
|
230
|
+
return handleDevtoolsUIRequest(options.basePath, accessChecked);
|
|
231
|
+
}
|
|
232
|
+
return new Response("Not Found", { status: 404 });
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Create GET and POST handlers for a devtools catch-all route.
|
|
236
|
+
*
|
|
237
|
+
* This is the recommended integration for frameworks such as Next.js that
|
|
238
|
+
* export HTTP method functions from route modules.
|
|
239
|
+
*/
|
|
240
|
+
export function createDevtoolsRoute(devtools, options) {
|
|
241
|
+
const handle = (req) => handleDevtoolsRequest(req, devtools, options);
|
|
242
|
+
return {
|
|
243
|
+
GET: handle,
|
|
244
|
+
POST: handle,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface DevtoolsTraceContext {
|
|
2
|
+
traceId: string;
|
|
3
|
+
spanId: string;
|
|
4
|
+
parentSpanId?: string;
|
|
5
|
+
traceparent: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ParsedTraceparent {
|
|
8
|
+
traceId: string;
|
|
9
|
+
spanId: string;
|
|
10
|
+
traceFlags: string;
|
|
11
|
+
traceparent: string;
|
|
12
|
+
}
|
|
13
|
+
export interface DevtoolsTraceContextInput {
|
|
14
|
+
traceId?: string;
|
|
15
|
+
spanId?: string;
|
|
16
|
+
parentSpanId?: string;
|
|
17
|
+
traceparent?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function createTraceId(): string;
|
|
20
|
+
export declare function createSpanId(): string;
|
|
21
|
+
export declare function createTraceparent(args: {
|
|
22
|
+
traceId: string;
|
|
23
|
+
spanId: string;
|
|
24
|
+
traceFlags?: string;
|
|
25
|
+
}): string;
|
|
26
|
+
export declare function parseTraceparent(value: string | null | undefined): ParsedTraceparent | undefined;
|
|
27
|
+
export declare function createDevtoolsTraceContext(input?: DevtoolsTraceContextInput): DevtoolsTraceContext;
|
|
28
|
+
export declare function createChildDevtoolsTraceContext(parent: DevtoolsTraceContextInput): DevtoolsTraceContext;
|
|
29
|
+
//# sourceMappingURL=trace-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-context.d.ts","sourceRoot":"","sources":["../src/trace-context.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsBD,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAET;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,iBAAiB,GAAG,SAAS,CAe/B;AAED,wBAAgB,0BAA0B,CACxC,KAAK,GAAE,yBAA8B,GACpC,oBAAoB,CAgBtB;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,yBAAyB,GAChC,oBAAoB,CAMtB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const TRACEPARENT_PATTERN = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
|
|
2
|
+
function createHexId(length) {
|
|
3
|
+
const bytes = new Uint8Array(length / 2);
|
|
4
|
+
if (typeof crypto !== "undefined" && "getRandomValues" in crypto) {
|
|
5
|
+
crypto.getRandomValues(bytes);
|
|
6
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
7
|
+
}
|
|
8
|
+
let value = "";
|
|
9
|
+
while (value.length < length) {
|
|
10
|
+
value += Math.floor(Math.random() * 16).toString(16);
|
|
11
|
+
}
|
|
12
|
+
return value.slice(0, length);
|
|
13
|
+
}
|
|
14
|
+
function isNonZeroHex(value) {
|
|
15
|
+
return !/^0+$/.test(value);
|
|
16
|
+
}
|
|
17
|
+
export function createTraceId() {
|
|
18
|
+
let traceId = createHexId(32);
|
|
19
|
+
while (!isNonZeroHex(traceId)) {
|
|
20
|
+
traceId = createHexId(32);
|
|
21
|
+
}
|
|
22
|
+
return traceId;
|
|
23
|
+
}
|
|
24
|
+
export function createSpanId() {
|
|
25
|
+
let spanId = createHexId(16);
|
|
26
|
+
while (!isNonZeroHex(spanId)) {
|
|
27
|
+
spanId = createHexId(16);
|
|
28
|
+
}
|
|
29
|
+
return spanId;
|
|
30
|
+
}
|
|
31
|
+
export function createTraceparent(args) {
|
|
32
|
+
return `00-${args.traceId}-${args.spanId}-${args.traceFlags ?? "01"}`;
|
|
33
|
+
}
|
|
34
|
+
export function parseTraceparent(value) {
|
|
35
|
+
if (!value)
|
|
36
|
+
return undefined;
|
|
37
|
+
const normalized = value.trim().toLowerCase();
|
|
38
|
+
const match = TRACEPARENT_PATTERN.exec(normalized);
|
|
39
|
+
if (!match)
|
|
40
|
+
return undefined;
|
|
41
|
+
const [, traceId, spanId, traceFlags] = match;
|
|
42
|
+
if (!isNonZeroHex(traceId) || !isNonZeroHex(spanId))
|
|
43
|
+
return undefined;
|
|
44
|
+
return {
|
|
45
|
+
traceId,
|
|
46
|
+
spanId,
|
|
47
|
+
traceFlags,
|
|
48
|
+
traceparent: normalized,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function createDevtoolsTraceContext(input = {}) {
|
|
52
|
+
const parsed = parseTraceparent(input.traceparent);
|
|
53
|
+
const traceId = input.traceId ?? parsed?.traceId ?? createTraceId();
|
|
54
|
+
const parentSpanId = input.parentSpanId ?? parsed?.spanId;
|
|
55
|
+
const spanId = input.spanId ?? createSpanId();
|
|
56
|
+
return {
|
|
57
|
+
traceId,
|
|
58
|
+
spanId,
|
|
59
|
+
...(parentSpanId ? { parentSpanId } : {}),
|
|
60
|
+
traceparent: createTraceparent({
|
|
61
|
+
traceId,
|
|
62
|
+
spanId,
|
|
63
|
+
traceFlags: parsed?.traceFlags,
|
|
64
|
+
}),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function createChildDevtoolsTraceContext(parent) {
|
|
68
|
+
return createDevtoolsTraceContext({
|
|
69
|
+
traceId: parent.traceId,
|
|
70
|
+
parentSpanId: parent.spanId,
|
|
71
|
+
traceparent: parent.traceparent,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=trace-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-context.js","sourceRoot":"","sources":["../src/trace-context.ts"],"names":[],"mappings":"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"}
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type DevtoolsRouteAccessOptions } from "./access";
|
|
2
|
+
/**
|
|
3
|
+
* Devtools UI handler
|
|
4
|
+
*
|
|
5
|
+
* Serves a self-contained HTML dashboard for viewing devtools events.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Handle requests for the devtools dashboard UI.
|
|
9
|
+
*
|
|
10
|
+
* @param basePath - The URL path prefix where devtools routes are mounted (e.g. "/api/devtools")
|
|
11
|
+
* @returns HTML response with the devtools dashboard
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleDevtoolsUIRequest(basePath: string, options?: DevtoolsRouteAccessOptions): Response;
|
|
14
|
+
//# sourceMappingURL=ui.d.ts.map
|
package/dist/ui.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAGhC,MAAM,UAAU,CAAC;AAElB;;;;GAIG;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,0BAA+B,GACvC,QAAQ,CAWV"}
|