adonisjs-server-stats 1.5.2 → 1.5.4

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/README.md CHANGED
@@ -159,170 +159,15 @@ export default defineConfig({
159
159
  })
160
160
  ```
161
161
 
162
- ### 4. Add routes
162
+ ### 4. Render the stats bar
163
163
 
164
- The package has three layers of functionality, each with its own routes:
164
+ That's it for setup -- **all API routes are auto-registered by the package**. No controllers or route definitions needed. On startup you'll see:
165
165
 
166
- #### Stats bar API route (required)
167
-
168
- The stats bar polls this endpoint for live metrics. Create a controller and route:
169
-
170
- ```ts
171
- // app/controllers/admin/server_stats_controller.ts
172
- import app from '@adonisjs/core/services/app'
173
- import type { HttpContext } from '@adonisjs/core/http'
174
- import type { StatsEngine } from 'adonisjs-server-stats'
175
-
176
- export default class ServerStatsController {
177
- async index({ response }: HttpContext) {
178
- const engine = (await app.container.make('server_stats.engine')) as StatsEngine
179
- return response.json(engine.getLatestStats())
180
- }
181
- }
182
- ```
183
-
184
- ```ts
185
- // start/routes.ts
186
- router
187
- .get('/admin/api/server-stats', '#controllers/admin/server_stats_controller.index')
188
- .use(middleware.superadmin())
189
- ```
190
-
191
- > The route path must match `endpoint` in your config (default: `/admin/api/server-stats`).
192
-
193
- #### Debug toolbar routes (optional -- when `devToolbar.enabled: true`)
194
-
195
- The debug toolbar panels fetch data from these API endpoints. Create a controller and routes:
196
-
197
- ```ts
198
- // app/controllers/admin/debug_controller.ts
199
- import app from '@adonisjs/core/services/app'
200
- import type { HttpContext } from '@adonisjs/core/http'
201
- import type { DebugStore } from 'adonisjs-server-stats/debug'
202
-
203
- export default class DebugController {
204
- private async getStore(): Promise<DebugStore | null> {
205
- try {
206
- return (await app.container.make('debug.store')) as DebugStore
207
- } catch {
208
- return null
209
- }
210
- }
211
-
212
- async queries({ response }: HttpContext) {
213
- const store = await this.getStore()
214
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
215
- return response.json({ queries: store.queries.getLatest(500), summary: store.queries.getSummary() })
216
- }
217
-
218
- async events({ response }: HttpContext) {
219
- const store = await this.getStore()
220
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
221
- return response.json({ events: store.events.getLatest(200), total: store.events.getTotalCount() })
222
- }
223
-
224
- async routes({ response }: HttpContext) {
225
- const store = await this.getStore()
226
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
227
- return response.json({ routes: store.routes.getRoutes(), total: store.routes.getRouteCount() })
228
- }
229
-
230
- async logs({ response }: HttpContext) {
231
- const store = await this.getStore()
232
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
233
- return response.json({ logs: store.logs.getLatest(500), total: store.logs.getTotalCount() })
234
- }
235
-
236
- async emails({ response }: HttpContext) {
237
- const store = await this.getStore()
238
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
239
- const emails = store.emails.getLatest(100)
240
- const stripped = emails.map(({ html, text, ...rest }) => rest)
241
- return response.json({ emails: stripped, total: store.emails.getTotalCount() })
242
- }
243
-
244
- async emailPreview({ params, response }: HttpContext) {
245
- const store = await this.getStore()
246
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
247
- const html = store.emails.getEmailHtml(Number(params.id))
248
- if (!html) return response.notFound({ error: 'Email not found' })
249
- return response.header('Content-Type', 'text/html; charset=utf-8').send(html)
250
- }
251
-
252
- async traces({ response }: HttpContext) {
253
- const store = await this.getStore()
254
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
255
- if (!store.traces) return response.json({ traces: [], total: 0 })
256
- const traces = store.traces.getLatest(100)
257
- const list = traces.map(({ spans, warnings, ...rest }: any) => ({
258
- ...rest,
259
- warningCount: warnings.length,
260
- }))
261
- return response.json({ traces: list, total: store.traces.getTotalCount() })
262
- }
263
-
264
- async traceDetail({ params, response }: HttpContext) {
265
- const store = await this.getStore()
266
- if (!store) return response.notFound({ error: 'Debug toolbar not enabled' })
267
- if (!store.traces) return response.notFound({ error: 'Tracing not enabled' })
268
- const trace = store.traces.getTrace(Number(params.id))
269
- if (!trace) return response.notFound({ error: 'Trace not found' })
270
- return response.json(trace)
271
- }
272
- }
273
166
  ```
274
-
275
- ```ts
276
- // start/routes.ts
277
- router
278
- .group(() => {
279
- router.get('queries', '#controllers/admin/debug_controller.queries')
280
- router.get('events', '#controllers/admin/debug_controller.events')
281
- router.get('routes', '#controllers/admin/debug_controller.routes')
282
- router.get('logs', '#controllers/admin/debug_controller.logs')
283
- router.get('emails', '#controllers/admin/debug_controller.emails')
284
- router.get('emails/:id/preview', '#controllers/admin/debug_controller.emailPreview')
285
- router.get('traces', '#controllers/admin/debug_controller.traces')
286
- router.get('traces/:id', '#controllers/admin/debug_controller.traceDetail')
287
- })
288
- .prefix('/admin/api/debug')
289
- .use(middleware.superadmin())
167
+ [server-stats] auto-registered routes: /admin/api/server-stats, /admin/api/debug/*, /__stats/*
290
168
  ```
291
169
 
292
- #### Dashboard routes (automatic -- when `devToolbar.dashboard: true`)
293
-
294
- The full-page dashboard at `/__stats` **registers its own routes automatically** -- no manual route setup needed. The following routes are created under the configured `dashboardPath` (default: `/__stats`):
295
-
296
- | Method | Path | Description |
297
- |--------|------|-------------|
298
- | GET | `/` | Dashboard page (HTML) |
299
- | GET | `/api/overview` | Overview metrics |
300
- | GET | `/api/overview/chart` | Time-series chart data |
301
- | GET | `/api/requests` | Paginated request history |
302
- | GET | `/api/requests/:id` | Request detail with queries/trace |
303
- | GET | `/api/queries` | Paginated query list |
304
- | GET | `/api/queries/grouped` | Queries grouped by normalized SQL |
305
- | GET | `/api/queries/:id/explain` | EXPLAIN plan for a query |
306
- | GET | `/api/events` | Paginated event list |
307
- | GET | `/api/routes` | Route table |
308
- | GET | `/api/logs` | Paginated log entries |
309
- | GET | `/api/emails` | Paginated email list |
310
- | GET | `/api/emails/:id/preview` | Email HTML preview |
311
- | GET | `/api/traces` | Paginated trace list |
312
- | GET | `/api/traces/:id` | Trace detail with spans |
313
- | GET | `/api/cache` | Cache stats and key listing |
314
- | GET | `/api/cache/:key` | Cache key detail |
315
- | GET | `/api/jobs` | Job queue overview |
316
- | GET | `/api/jobs/:id` | Job detail |
317
- | POST | `/api/jobs/:id/retry` | Retry a failed job |
318
- | GET | `/api/config` | App config (secrets redacted) |
319
- | GET | `/api/filters` | Saved filters |
320
- | POST | `/api/filters` | Create saved filter |
321
- | DELETE | `/api/filters/:id` | Delete saved filter |
322
-
323
- All dashboard routes are gated by the `shouldShow` callback if configured.
324
-
325
- ### 5. Render the stats bar
170
+ All routes are gated by the `shouldShow` callback if configured (see [Visibility Control](#visibility-control-shouldshow)).
326
171
 
327
172
  **Edge** (add before `</body>`):
328
173
 
@@ -364,6 +209,7 @@ All dashboard routes are gated by the `shouldShow` callback if configured.
364
209
  | `dashboardPath` | `string` | `'/__stats'` | URL path for the dashboard page |
365
210
  | `retentionDays` | `number` | `7` | Days to keep historical data in SQLite |
366
211
  | `dbPath` | `string` | `'.adonisjs/server-stats/dashboard.sqlite3'` | Path to the SQLite database file (relative to app root) |
212
+ | `debugEndpoint` | `string` | `'/admin/api/debug'` | Base path for the debug toolbar API endpoints |
367
213
  | `excludeFromTracing` | `string[]` | `['/admin/api/debug', '/admin/api/server-stats']` | URL prefixes to exclude from tracing and dashboard persistence. Requests still count toward HTTP metrics but won't appear in the timeline or be stored. The stats endpoint is always excluded automatically. |
368
214
  | `panes` | `DebugPane[]` | -- | Custom debug panel tabs |
369
215
 
@@ -457,7 +303,7 @@ interface MetricCollector {
457
303
 
458
304
  ## Visibility Control (`shouldShow`)
459
305
 
460
- By default the stats bar renders for every request. Use `shouldShow` to restrict it. The callback receives the AdonisJS `HttpContext` and should return `true` to show the bar, `false` to hide it.
306
+ Use `shouldShow` to control who can see the stats bar and access all auto-registered API routes (stats, debug, dashboard). The callback receives the AdonisJS `HttpContext` and should return `true` to allow access, `false` to deny (403).
461
307
 
462
308
  Because `shouldShow` runs **after** middleware (including auth), you have full access to `ctx.auth`.
463
309
 
@@ -485,7 +331,71 @@ export default defineConfig({
485
331
  })
486
332
  ```
487
333
 
488
- > **Tip:** When `shouldShow` is not set, the bar renders for everyone. In production you almost always want to set this.
334
+ > **Tip:** When `shouldShow` is not set, the bar and all routes are accessible to everyone. In production you almost always want to set this.
335
+
336
+ ---
337
+
338
+ ## Auto-Registered Routes
339
+
340
+ All API routes are registered automatically by the package during `boot()` -- no manual controllers or route definitions needed. Each route group is gated by the `shouldShow` callback if configured.
341
+
342
+ ### Stats bar endpoint
343
+
344
+ Registered when `endpoint` is a string (default: `/admin/api/server-stats`). Returns the latest stats snapshot as JSON.
345
+
346
+ ### Debug toolbar routes
347
+
348
+ Registered when `devToolbar.enabled: true`. Base path configurable via `devToolbar.debugEndpoint` (default: `/admin/api/debug`).
349
+
350
+ | Method | Path | Description |
351
+ |--------|------|-------------|
352
+ | GET | `/queries` | SQL queries with summary stats |
353
+ | GET | `/events` | Application events |
354
+ | GET | `/routes` | Registered route table |
355
+ | GET | `/logs` | Log file entries (last 256KB) |
356
+ | GET | `/emails` | Captured emails (stripped HTML) |
357
+ | GET | `/emails/:id/preview` | Email HTML preview |
358
+ | GET | `/traces` | Request traces |
359
+ | GET | `/traces/:id` | Trace detail with spans |
360
+
361
+ ### Dashboard routes
362
+
363
+ Registered when `devToolbar.dashboard: true`. Base path configurable via `devToolbar.dashboardPath` (default: `/__stats`).
364
+
365
+ | Method | Path | Description |
366
+ |--------|------|-------------|
367
+ | GET | `/` | Dashboard page (HTML) |
368
+ | GET | `/api/overview` | Overview metrics |
369
+ | GET | `/api/overview/chart` | Time-series chart data |
370
+ | GET | `/api/requests` | Paginated request history |
371
+ | GET | `/api/requests/:id` | Request detail with queries/trace |
372
+ | GET | `/api/queries` | Paginated query list |
373
+ | GET | `/api/queries/grouped` | Queries grouped by normalized SQL |
374
+ | GET | `/api/queries/:id/explain` | EXPLAIN plan for a query |
375
+ | GET | `/api/events` | Paginated event list |
376
+ | GET | `/api/routes` | Route table |
377
+ | GET | `/api/logs` | Paginated log entries |
378
+ | GET | `/api/emails` | Paginated email list |
379
+ | GET | `/api/emails/:id/preview` | Email HTML preview |
380
+ | GET | `/api/traces` | Paginated trace list |
381
+ | GET | `/api/traces/:id` | Trace detail with spans |
382
+ | GET | `/api/cache` | Cache stats and key listing |
383
+ | GET | `/api/cache/:key` | Cache key detail |
384
+ | GET | `/api/jobs` | Job queue overview |
385
+ | GET | `/api/jobs/:id` | Job detail |
386
+ | POST | `/api/jobs/:id/retry` | Retry a failed job |
387
+ | GET | `/api/config` | App config (secrets redacted) |
388
+ | GET | `/api/filters` | Saved filters |
389
+ | POST | `/api/filters` | Create saved filter |
390
+ | DELETE | `/api/filters/:id` | Delete saved filter |
391
+
392
+ ### Global middleware note
393
+
394
+ Auto-registered routes bypass route-level middleware but are still subject to global/server middleware. If you have auth middleware (like `silentAuth`) registered globally, each polling request will trigger a DB query every few seconds.
395
+
396
+ To avoid this, either:
397
+ - Move auth middleware to a named route group instead of global middleware
398
+ - Use the `shouldShow` callback for access control (recommended)
489
399
 
490
400
  ---
491
401
 
@@ -531,7 +441,7 @@ export default defineConfig({
531
441
  })
532
442
  ```
533
443
 
534
- Register the debug API routes (see [step 4](#4-add-routes) for the full controller and route setup).
444
+ Debug routes are auto-registered by the package at `/admin/api/debug/*` (configurable via `debugEndpoint`).
535
445
 
536
446
  ### Built-in Emails Tab
537
447
 
@@ -2,7 +2,8 @@ import type { DebugStore } from '../debug/debug_store.js';
2
2
  import type { HttpContext } from '@adonisjs/core/http';
3
3
  export default class DebugController {
4
4
  private store;
5
- constructor(store: DebugStore);
5
+ private logPath;
6
+ constructor(store: DebugStore, logPath: string);
6
7
  queries({ response }: HttpContext): Promise<void>;
7
8
  events({ response }: HttpContext): Promise<void>;
8
9
  routes({ response }: HttpContext): Promise<void>;
@@ -10,5 +11,6 @@ export default class DebugController {
10
11
  emailPreview({ params, response }: HttpContext): Promise<void>;
11
12
  traces({ response }: HttpContext): Promise<void>;
12
13
  traceDetail({ params, response }: HttpContext): Promise<void>;
14
+ logs({ response }: HttpContext): Promise<void>;
13
15
  }
14
16
  //# sourceMappingURL=debug_controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug_controller.d.ts","sourceRoot":"","sources":["../../../src/controller/debug_controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,CAAC,OAAO,OAAO,eAAe;IACtB,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,UAAU;IAE/B,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAMjC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAKhC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAKhC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAOhC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,WAAW;IAS9C,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAahC,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,WAAW;CAWpD"}
1
+ {"version":3,"file":"debug_controller.d.ts","sourceRoot":"","sources":["../../../src/controller/debug_controller.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAWtD,MAAM,CAAC,OAAO,OAAO,eAAe;IAIhC,OAAO,CAAC,KAAK;IAHf,OAAO,CAAC,OAAO,CAAQ;gBAGb,KAAK,EAAE,UAAU,EACzB,OAAO,EAAE,MAAM;IAKX,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAMjC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAKhC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAKhC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAOhC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,WAAW;IAS9C,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAahC,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,WAAW;IAY7C,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;CAgDrC"}
@@ -1,7 +1,18 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ const LEVEL_NAMES = {
3
+ 10: 'trace',
4
+ 20: 'debug',
5
+ 30: 'info',
6
+ 40: 'warn',
7
+ 50: 'error',
8
+ 60: 'fatal',
9
+ };
1
10
  export default class DebugController {
2
11
  store;
3
- constructor(store) {
12
+ logPath;
13
+ constructor(store, logPath) {
4
14
  this.store = store;
15
+ this.logPath = logPath;
5
16
  }
6
17
  async queries({ response }) {
7
18
  const queries = this.store.queries.getLatest(500);
@@ -53,4 +64,53 @@ export default class DebugController {
53
64
  }
54
65
  return response.json(trace);
55
66
  }
67
+ async logs({ response }) {
68
+ try {
69
+ const stats = await stat(this.logPath);
70
+ // Only read last 256KB to keep response fast
71
+ const maxBytes = 256 * 1024;
72
+ let content;
73
+ if (stats.size > maxBytes) {
74
+ const { createReadStream } = await import('node:fs');
75
+ const stream = createReadStream(this.logPath, {
76
+ start: stats.size - maxBytes,
77
+ encoding: 'utf-8',
78
+ });
79
+ const chunks = [];
80
+ for await (const chunk of stream) {
81
+ chunks.push(chunk);
82
+ }
83
+ content = chunks.join('');
84
+ // Skip first potentially incomplete line
85
+ const firstNewline = content.indexOf('\n');
86
+ if (firstNewline !== -1)
87
+ content = content.slice(firstNewline + 1);
88
+ }
89
+ else {
90
+ content = await readFile(this.logPath, 'utf-8');
91
+ }
92
+ const entries = content
93
+ .trim()
94
+ .split('\n')
95
+ .filter(Boolean)
96
+ .map((line) => {
97
+ try {
98
+ const entry = JSON.parse(line);
99
+ return {
100
+ ...entry,
101
+ levelName: LEVEL_NAMES[entry.level] || 'unknown',
102
+ timestamp: new Date(entry.time).toISOString(),
103
+ };
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ })
109
+ .filter(Boolean);
110
+ return response.json(entries);
111
+ }
112
+ catch {
113
+ return response.json([]);
114
+ }
115
+ }
56
116
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard_routes.d.ts","sourceRoot":"","sources":["../../../src/dashboard/dashboard_routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAA;AAEhE;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,GAAG,EACX,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,mBAAmB,GAAG,IAAI,EAC/C,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,QA8EnC"}
1
+ {"version":3,"file":"dashboard_routes.d.ts","sourceRoot":"","sources":["../../../src/dashboard/dashboard_routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAA;AAEhE;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,GAAG,EACX,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,mBAAmB,GAAG,IAAI,EAC/C,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,QA8EnC"}
@@ -1,3 +1,4 @@
1
+ import { createAccessMiddleware } from '../routes/access_middleware.js';
1
2
  /**
2
3
  * Register all dashboard routes under the configured path.
3
4
  *
@@ -74,20 +75,3 @@ export function registerDashboardRoutes(router, dashboardPath, getController, sh
74
75
  .prefix(base)
75
76
  .use(middleware);
76
77
  }
77
- /**
78
- * Create a middleware function that gates access using the shouldShow callback.
79
- * Returns 403 if the callback returns false.
80
- */
81
- function createAccessMiddleware(shouldShow) {
82
- return async (ctx, next) => {
83
- try {
84
- if (!shouldShow(ctx)) {
85
- return ctx.response.forbidden({ error: 'Access denied' });
86
- }
87
- }
88
- catch {
89
- return ctx.response.forbidden({ error: 'Access denied' });
90
- }
91
- await next();
92
- };
93
- }
@@ -175,6 +175,8 @@ export interface DevToolbarConfig {
175
175
  retentionDays: number;
176
176
  /** Path to the SQLite database file for historical persistence. */
177
177
  dbPath: string;
178
+ /** Base path for the debug toolbar API endpoints. */
179
+ debugEndpoint: string;
178
180
  }
179
181
  /**
180
182
  * Color names available for the `badge` column format.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/debug/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/debug/types.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IAEV,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAA;IAEX,yDAAyD;IACzD,QAAQ,EAAE,GAAG,EAAE,CAAA;IAEf,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IAEd,wEAAwE;IACxE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAEpB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAA;IAElB,mDAAmD;IACnD,aAAa,EAAE,OAAO,CAAA;IAEtB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IAEV,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAA;IAEb,oEAAoE;IACpE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAEnB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IAEV,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAA;IAEZ,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAA;IAEV,wCAAwC;IACxC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IAEjB,yCAAyC;IACzC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAElB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAA;IAEf,oDAAoD;IACpD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAEnB,kCAAkC;IAClC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAEnB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAA;IAEd,+BAA+B;IAC/B,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;IAEhD,8DAA8D;IAC9D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAExB,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAA;IAEvB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAA;IAEd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAA;IAEf,oDAAoD;IACpD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAEnB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAA;IAEf;;;;OAIG;IACH,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAA;IAEV,sDAAsD;IACtD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAEvB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IAEb,8DAA8D;IAC9D,QAAQ,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;IAEhF,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAA;IAEnB,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAA;IAEhB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IAEV,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAA;IAEd,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAA;IAEX,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAElB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAA;IAErB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAA;IAEjB,8CAA8C;IAC9C,KAAK,EAAE,SAAS,EAAE,CAAA;IAElB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,EAAE,CAAA;IAElB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAA;IAEhB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAA;IAElB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAA;IAEjB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAA;IAEjB,0DAA0D;IAC1D,oBAAoB,EAAE,MAAM,CAAA;IAE5B,mEAAmE;IACnE,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAAA;IAElC,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAA;IAEhB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;IAEjB,kDAAkD;IAClD,SAAS,EAAE,OAAO,CAAA;IAElB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAA;IAErB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAA;IAErB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAA;IAEd,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAA;CACtB;AAMD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEhF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAC3B,MAAM,GACN,MAAM,GACN,SAAS,GACT,UAAU,GACV,QAAQ,GACR,MAAM,GACN,OAAO,CAAA;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAA;IAEX,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IAEb;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;;OAIG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAE5B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,EAAE,EAAE,MAAM,CAAA;IAEV,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IAEb,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAA;IAEhB;;;OAGG;IACH,OAAO,EAAE,eAAe,EAAE,CAAA;IAE1B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IAExB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB"}
@@ -8,10 +8,10 @@
8
8
  * data-logs-endpoint — logs API URL
9
9
  */
10
10
  ;(function () {
11
- const BASE = '/admin/api/debug'
12
11
  const REFRESH_INTERVAL = 3000
13
12
  const panel = document.getElementById('ss-dbg-panel')
14
13
  const wrench = document.getElementById('ss-dbg-wrench')
14
+ const BASE = (panel && panel.dataset.debugEndpoint) || '/admin/api/debug'
15
15
  const closeBtn = document.getElementById('ss-dbg-close')
16
16
 
17
17
  if (!panel || !wrench) return
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/edge/plugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAKpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,IACrD,MAAM,GAAG,UAmHlB"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/edge/plugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAKpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,IACrD,MAAM,GAAG,UAqHlB"}
@@ -93,9 +93,11 @@ export function edgePluginServerStats(config) {
93
93
  groups,
94
94
  };
95
95
  if (showDebug) {
96
+ const debugEndpoint = config.devToolbar?.debugEndpoint || '/admin/api/debug';
96
97
  state.debugCss = read('client/debug-panel.css');
97
98
  state.debugJs = read('client/debug-panel.js');
98
- state.logsEndpoint = '/admin/api/debug/logs';
99
+ state.debugEndpoint = debugEndpoint;
100
+ state.logsEndpoint = debugEndpoint + '/logs';
99
101
  state.customPanes = config.devToolbar?.panes || [];
100
102
  state.showTracing = !!config.devToolbar?.tracing;
101
103
  state.dashboardPath = config.devToolbar?.dashboard
@@ -1,4 +1,4 @@
1
- <div id="ss-dbg-panel" class="ss-dbg-panel" data-logs-endpoint="{{ logsEndpoint }}" data-tracing="{{ showTracing ? '1' : '0' }}"@if(dashboardPath) data-dashboard-path="{{ dashboardPath }}"@end>
1
+ <div id="ss-dbg-panel" class="ss-dbg-panel" data-logs-endpoint="{{ logsEndpoint }}" data-tracing="{{ showTracing ? '1' : '0' }}" data-debug-endpoint="{{ debugEndpoint }}"@if(dashboardPath) data-dashboard-path="{{ dashboardPath }}"@end>
2
2
  <div class="ss-dbg-tabs">
3
3
  <div class="ss-dbg-tabs-scroll">
4
4
  @if(showTracing)
@@ -11,8 +11,17 @@ export default class ServerStatsProvider {
11
11
  private debugBroadcastTimer;
12
12
  private persistPath;
13
13
  private flushTimer;
14
+ private statsController;
15
+ private debugController;
14
16
  constructor(app: ApplicationService);
15
17
  boot(): Promise<void>;
18
+ /**
19
+ * Read start/kernel.ts and detect auth-related middleware in server.use()
20
+ * or router.use() blocks. Returns import paths of problematic middleware.
21
+ *
22
+ * Ignores initialize_auth_middleware (no DB query — just sets up ctx.auth).
23
+ */
24
+ private detectGlobalAuthMiddleware;
16
25
  ready(): Promise<void>;
17
26
  private setupDevToolbar;
18
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"server_stats_provider.d.ts","sourceRoot":"","sources":["../../../src/provider/server_stats_provider.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAY1B,SAAS,CAAC,GAAG,EAAE,kBAAkB;IAX7C,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,mBAAmB,CAAmC;IAC9D,OAAO,CAAC,kBAAkB,CAAgC;IAC1D,OAAO,CAAC,uBAAuB,CAA8C;IAC7E,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,UAAU,CAA8C;gBAE1C,GAAG,EAAE,kBAAkB;IAEvC,IAAI;IAkCJ,KAAK;YA+EG,eAAe;IAmF7B;;;;;;OAMG;YACW,cAAc;IAoGtB,QAAQ;CAwCf"}
1
+ {"version":3,"file":"server_stats_provider.d.ts","sourceRoot":"","sources":["../../../src/provider/server_stats_provider.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAc1B,SAAS,CAAC,GAAG,EAAE,kBAAkB;IAb7C,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,mBAAmB,CAAmC;IAC9D,OAAO,CAAC,kBAAkB,CAAgC;IAC1D,OAAO,CAAC,uBAAuB,CAA8C;IAC7E,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,eAAe,CAA+B;gBAEhC,GAAG,EAAE,kBAAkB;IAEvC,IAAI;IA4GV;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IAmD5B,KAAK;YAuFG,eAAe;IAwF7B;;;;;;OAMG;YACW,cAAc;IAoGtB,QAAQ;CAwCf"}
@@ -1,9 +1,12 @@
1
+ import { readFileSync } from 'node:fs';
1
2
  import { registerDashboardRoutes } from '../dashboard/dashboard_routes.js';
2
3
  import { DashboardStore } from '../dashboard/dashboard_store.js';
3
4
  import { DebugStore } from '../debug/debug_store.js';
4
5
  import { StatsEngine } from '../engine/stats_engine.js';
5
6
  import { LogStreamService } from '../log_stream/log_stream_service.js';
6
7
  import { setShouldShow, setTraceCollector, setDashboardPath, setExcludedPrefixes, setOnRequestComplete, } from '../middleware/request_tracking_middleware.js';
8
+ import { registerDebugRoutes } from '../routes/debug_routes.js';
9
+ import { registerStatsRoutes } from '../routes/stats_routes.js';
7
10
  export default class ServerStatsProvider {
8
11
  app;
9
12
  intervalId = null;
@@ -16,6 +19,8 @@ export default class ServerStatsProvider {
16
19
  debugBroadcastTimer = null;
17
20
  persistPath = null;
18
21
  flushTimer = null;
22
+ statsController = null;
23
+ debugController = null;
19
24
  constructor(app) {
20
25
  this.app = app;
21
26
  }
@@ -27,17 +32,66 @@ export default class ServerStatsProvider {
27
32
  if (config.shouldShow) {
28
33
  setShouldShow(config.shouldShow);
29
34
  }
30
- // Register dashboard routes early (before router commits).
31
- // The controller is created later in ready() — routes use a lazy getter.
32
- const toolbarConfig = config.devToolbar;
33
- if (toolbarConfig?.enabled && toolbarConfig.dashboard && !this.app.inProduction) {
34
- try {
35
- const router = await this.app.container.make('router');
36
- const dashPath = toolbarConfig.dashboardPath ?? '/__stats';
37
- registerDashboardRoutes(router, dashPath, () => this.dashboardController, config.shouldShow);
35
+ let router = null;
36
+ try {
37
+ router = await this.app.container.make('router');
38
+ }
39
+ catch {
40
+ // Router not available — skip all route registration
41
+ }
42
+ if (router && !this.app.inProduction) {
43
+ const registeredPaths = [];
44
+ // ── Auto-register stats bar endpoint ───────────────────────
45
+ if (typeof config.endpoint === 'string') {
46
+ registerStatsRoutes(router, config.endpoint, () => this.statsController, config.shouldShow);
47
+ registeredPaths.push(config.endpoint);
38
48
  }
39
- catch {
40
- // Router not available — skip route registration
49
+ // ── Auto-register debug toolbar routes ─────────────────────
50
+ const toolbarConfig = config.devToolbar;
51
+ if (toolbarConfig?.enabled) {
52
+ const debugEndpoint = toolbarConfig.debugEndpoint ?? '/admin/api/debug';
53
+ registerDebugRoutes(router, debugEndpoint, () => this.debugController, config.shouldShow);
54
+ registeredPaths.push(debugEndpoint + '/*');
55
+ // ── Auto-register dashboard routes ─────────────────────────
56
+ if (toolbarConfig.dashboard) {
57
+ const dashPath = toolbarConfig.dashboardPath ?? '/__stats';
58
+ registerDashboardRoutes(router, dashPath, () => this.dashboardController, config.shouldShow);
59
+ registeredPaths.push(dashPath + '/*');
60
+ }
61
+ }
62
+ // Log registered routes
63
+ if (registeredPaths.length > 0) {
64
+ const tag = '\x1b[36m[ \x1b[1m🔍 server-stats\x1b[0m\x1b[36m ]\x1b[0m';
65
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
66
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
67
+ console.log(`\n${tag} routes registered:\n` +
68
+ registeredPaths.map((p) => ` ${dim('→')} ${bold(p)}`).join('\n'));
69
+ // Only warn about global auth middleware if:
70
+ // 1. shouldShow is NOT configured (user hasn't set up access control)
71
+ // 2. There IS auth middleware in server.use() or router.use()
72
+ if (!config.shouldShow) {
73
+ const authMiddleware = this.detectGlobalAuthMiddleware();
74
+ if (authMiddleware.length > 0) {
75
+ console.log(`\n${tag} ${bold('found global auth middleware that will run on every poll:')}\n` +
76
+ authMiddleware.map((m) => ` ${dim('→')} ${m}`).join('\n') +
77
+ '\n\n' +
78
+ ` ${dim('these routes get polled every ~3s, so auth middleware will')}\n` +
79
+ ` ${dim('trigger a DB query on each poll. here are two ways to fix it:')}\n` +
80
+ '\n' +
81
+ ` ${bold('option 1:')} add a shouldShow callback to your config:\n` +
82
+ '\n' +
83
+ ` ${dim('// config/server_stats.ts')}\n` +
84
+ ` ${dim("shouldShow: (ctx) => ctx.auth?.user?.role === 'admin'")}\n` +
85
+ '\n' +
86
+ ` ${bold('option 2:')} move auth middleware from router.use() to a route group:\n` +
87
+ '\n' +
88
+ ` ${dim('// start/kernel.ts — remove from router.use()')}\n` +
89
+ ` ${dim("// () => import('#middleware/silent_auth_middleware')")}\n` +
90
+ '\n' +
91
+ ` ${dim('// start/routes.ts — add to your route groups instead')}\n` +
92
+ ` ${dim("router.group(() => { ... }).use(middleware.silentAuth())")}\n`);
93
+ }
94
+ }
41
95
  }
42
96
  }
43
97
  if (!this.app.usingEdgeJS)
@@ -51,6 +105,56 @@ export default class ServerStatsProvider {
51
105
  // Edge not available — skip tag registration
52
106
  }
53
107
  }
108
+ /**
109
+ * Read start/kernel.ts and detect auth-related middleware in server.use()
110
+ * or router.use() blocks. Returns import paths of problematic middleware.
111
+ *
112
+ * Ignores initialize_auth_middleware (no DB query — just sets up ctx.auth).
113
+ */
114
+ detectGlobalAuthMiddleware() {
115
+ const found = [];
116
+ try {
117
+ // Try both .ts and .js extensions
118
+ let source = '';
119
+ for (const ext of ['ts', 'js']) {
120
+ try {
121
+ source = readFileSync(this.app.makePath('start', `kernel.${ext}`), 'utf-8');
122
+ if (source)
123
+ break;
124
+ }
125
+ catch {
126
+ // Try next extension
127
+ }
128
+ }
129
+ if (!source)
130
+ return found;
131
+ // Extract server.use([...]) and router.use([...]) blocks
132
+ const useBlockRegex = /(?:server|router)\.use\(\s*\[([\s\S]*?)\]\s*\)/g;
133
+ let match;
134
+ while ((match = useBlockRegex.exec(source)) !== null) {
135
+ const block = match[1];
136
+ // Find all import paths in this block
137
+ const importRegex = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
138
+ let importMatch;
139
+ while ((importMatch = importRegex.exec(block)) !== null) {
140
+ const importPath = importMatch[1];
141
+ // Skip initialize_auth_middleware — it just sets up ctx.auth, no DB query
142
+ if (importPath.includes('initialize_auth'))
143
+ continue;
144
+ // Detect auth-related middleware
145
+ if (importPath.includes('auth') ||
146
+ importPath.includes('silent_auth') ||
147
+ importPath.includes('silentAuth')) {
148
+ found.push(importPath);
149
+ }
150
+ }
151
+ }
152
+ }
153
+ catch {
154
+ // Can't read kernel file — skip detection
155
+ }
156
+ return found;
157
+ }
54
158
  async ready() {
55
159
  const config = this.app.config.get('server_stats');
56
160
  if (!config)
@@ -60,6 +164,9 @@ export default class ServerStatsProvider {
60
164
  this.engine = new StatsEngine(config.collectors);
61
165
  this.app.container.singleton('server_stats.engine', () => this.engine);
62
166
  await this.engine.start();
167
+ // Create the stats controller (makes the stats route functional)
168
+ const StatsControllerClass = (await import('../controller/server_stats_controller.js')).default;
169
+ this.statsController = new StatsControllerClass(this.engine);
63
170
  // Dev toolbar setup
64
171
  const toolbarConfig = config.devToolbar;
65
172
  if (toolbarConfig?.enabled && !this.app.inProduction) {
@@ -76,12 +183,14 @@ export default class ServerStatsProvider {
76
183
  dashboardPath: toolbarConfig.dashboardPath ?? '/__stats',
77
184
  retentionDays: toolbarConfig.retentionDays ?? 7,
78
185
  dbPath: toolbarConfig.dbPath ?? '.adonisjs/server-stats/dashboard.sqlite3',
186
+ debugEndpoint: toolbarConfig.debugEndpoint ?? '/admin/api/debug',
79
187
  });
80
188
  // Exclude the stats endpoint and user-specified prefixes from tracing
81
189
  // so the debug panel's own polling doesn't flood the timeline
82
- const defaultExcludes = ['/admin/api/debug', '/admin/api/server-stats'];
190
+ const debugEndpoint = toolbarConfig.debugEndpoint ?? '/admin/api/debug';
191
+ const defaultExcludes = [debugEndpoint, config.endpoint].filter((p) => typeof p === 'string');
83
192
  const prefixes = [...(toolbarConfig.excludeFromTracing ?? defaultExcludes)];
84
- if (typeof config.endpoint === 'string') {
193
+ if (typeof config.endpoint === 'string' && !prefixes.includes(config.endpoint)) {
85
194
  prefixes.push(config.endpoint);
86
195
  }
87
196
  if (prefixes.length > 0) {
@@ -149,6 +258,10 @@ export default class ServerStatsProvider {
149
258
  // Router not available
150
259
  }
151
260
  await this.debugStore.start(emitter, router);
261
+ // Create the debug controller (makes the debug routes functional)
262
+ const logPath = this.app.makePath('logs', 'adonisjs.log');
263
+ const DebugControllerClass = (await import('../controller/debug_controller.js')).default;
264
+ this.debugController = new DebugControllerClass(this.debugStore, logPath);
152
265
  // Wire trace collector into the request tracking middleware
153
266
  if (this.debugStore.traces) {
154
267
  setTraceCollector(this.debugStore.traces);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Create a middleware function that gates access using the shouldShow callback.
3
+ * Returns 403 if the callback returns false.
4
+ *
5
+ * Shared by stats, debug, and dashboard route registrars.
6
+ */
7
+ export declare function createAccessMiddleware(shouldShow: (ctx: any) => boolean): (ctx: any, next: () => Promise<void>) => Promise<any>;
8
+ //# sourceMappingURL=access_middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access_middleware.d.ts","sourceRoot":"","sources":["../../../src/routes/access_middleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,IACxD,KAAK,GAAG,EAAE,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC,kBAUlD"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Create a middleware function that gates access using the shouldShow callback.
3
+ * Returns 403 if the callback returns false.
4
+ *
5
+ * Shared by stats, debug, and dashboard route registrars.
6
+ */
7
+ export function createAccessMiddleware(shouldShow) {
8
+ return async (ctx, next) => {
9
+ try {
10
+ if (!shouldShow(ctx)) {
11
+ return ctx.response.forbidden({ error: 'Access denied' });
12
+ }
13
+ }
14
+ catch {
15
+ return ctx.response.forbidden({ error: 'Access denied' });
16
+ }
17
+ await next();
18
+ };
19
+ }
@@ -0,0 +1,14 @@
1
+ import type DebugController from '../controller/debug_controller.js';
2
+ /**
3
+ * Register all debug toolbar API routes under the given base path.
4
+ *
5
+ * Uses a lazy controller getter so routes can be registered during
6
+ * `boot()` while the DebugStore/controller is created during `ready()`.
7
+ *
8
+ * @param router The AdonisJS router instance.
9
+ * @param basePath The base path (e.g. `/admin/api/debug`).
10
+ * @param getController Lazy getter for the debug controller.
11
+ * @param shouldShow Optional access-control callback.
12
+ */
13
+ export declare function registerDebugRoutes(router: any, basePath: string, getController: () => DebugController | null, shouldShow?: (ctx: any) => boolean): void;
14
+ //# sourceMappingURL=debug_routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug_routes.d.ts","sourceRoot":"","sources":["../../../src/routes/debug_routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,eAAe,MAAM,mCAAmC,CAAA;AAEpE;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,eAAe,GAAG,IAAI,EAC3C,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,QAgCnC"}
@@ -0,0 +1,42 @@
1
+ import { createAccessMiddleware } from './access_middleware.js';
2
+ /**
3
+ * Register all debug toolbar API routes under the given base path.
4
+ *
5
+ * Uses a lazy controller getter so routes can be registered during
6
+ * `boot()` while the DebugStore/controller is created during `ready()`.
7
+ *
8
+ * @param router The AdonisJS router instance.
9
+ * @param basePath The base path (e.g. `/admin/api/debug`).
10
+ * @param getController Lazy getter for the debug controller.
11
+ * @param shouldShow Optional access-control callback.
12
+ */
13
+ export function registerDebugRoutes(router, basePath, getController, shouldShow) {
14
+ const base = basePath.replace(/\/+$/, '');
15
+ const middleware = shouldShow ? [createAccessMiddleware(shouldShow)] : [];
16
+ const bind = (method) => {
17
+ return async (ctx) => {
18
+ const controller = getController();
19
+ if (!controller) {
20
+ return ctx.response.serviceUnavailable({
21
+ error: 'Debug toolbar is starting up, please retry',
22
+ });
23
+ }
24
+ return controller[method].call(controller, ctx);
25
+ };
26
+ };
27
+ router
28
+ .group(() => {
29
+ router.get('/queries', bind('queries')).as('server-stats.debug.queries');
30
+ router.get('/events', bind('events')).as('server-stats.debug.events');
31
+ router.get('/routes', bind('routes')).as('server-stats.debug.routes');
32
+ router.get('/logs', bind('logs')).as('server-stats.debug.logs');
33
+ router.get('/emails', bind('emails')).as('server-stats.debug.emails');
34
+ router
35
+ .get('/emails/:id/preview', bind('emailPreview'))
36
+ .as('server-stats.debug.emailPreview');
37
+ router.get('/traces', bind('traces')).as('server-stats.debug.traces');
38
+ router.get('/traces/:id', bind('traceDetail')).as('server-stats.debug.traceDetail');
39
+ })
40
+ .prefix(base)
41
+ .use(middleware);
42
+ }
@@ -0,0 +1,14 @@
1
+ import type ServerStatsController from '../controller/server_stats_controller.js';
2
+ /**
3
+ * Register the stats bar API endpoint.
4
+ *
5
+ * Uses a lazy controller getter so the route can be registered during
6
+ * `boot()` while the engine/controller is created during `ready()`.
7
+ *
8
+ * @param router The AdonisJS router instance.
9
+ * @param endpoint The endpoint path (e.g. `/admin/api/server-stats`).
10
+ * @param getController Lazy getter for the stats controller.
11
+ * @param shouldShow Optional access-control callback.
12
+ */
13
+ export declare function registerStatsRoutes(router: any, endpoint: string, getController: () => ServerStatsController | null, shouldShow?: (ctx: any) => boolean): void;
14
+ //# sourceMappingURL=stats_routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats_routes.d.ts","sourceRoot":"","sources":["../../../src/routes/stats_routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,qBAAqB,MAAM,0CAA0C,CAAA;AAEjF;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,qBAAqB,GAAG,IAAI,EACjD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,QAgBnC"}
@@ -0,0 +1,27 @@
1
+ import { createAccessMiddleware } from './access_middleware.js';
2
+ /**
3
+ * Register the stats bar API endpoint.
4
+ *
5
+ * Uses a lazy controller getter so the route can be registered during
6
+ * `boot()` while the engine/controller is created during `ready()`.
7
+ *
8
+ * @param router The AdonisJS router instance.
9
+ * @param endpoint The endpoint path (e.g. `/admin/api/server-stats`).
10
+ * @param getController Lazy getter for the stats controller.
11
+ * @param shouldShow Optional access-control callback.
12
+ */
13
+ export function registerStatsRoutes(router, endpoint, getController, shouldShow) {
14
+ const middleware = shouldShow ? [createAccessMiddleware(shouldShow)] : [];
15
+ router
16
+ .get(endpoint, async (ctx) => {
17
+ const controller = getController();
18
+ if (!controller) {
19
+ return ctx.response.serviceUnavailable({
20
+ error: 'Stats engine is starting up, please retry',
21
+ });
22
+ }
23
+ return controller.index(ctx);
24
+ })
25
+ .as('server-stats.api')
26
+ .use(middleware);
27
+ }
@@ -287,6 +287,17 @@ export interface DevToolbarOptions {
287
287
  * @default ['/admin/api/debug', '/admin/api/server-stats']
288
288
  */
289
289
  excludeFromTracing?: string[];
290
+ /**
291
+ * Base path for the debug toolbar API endpoints.
292
+ *
293
+ * The debug panel fetches data from endpoints under this path
294
+ * (e.g. `{debugEndpoint}/queries`, `{debugEndpoint}/events`).
295
+ *
296
+ * Must start with `/`.
297
+ *
298
+ * @default '/admin/api/debug'
299
+ */
300
+ debugEndpoint?: string;
290
301
  }
291
302
  /**
292
303
  * Top-level configuration for `adonisjs-server-stats`.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adonisjs-server-stats",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "Real-time server monitoring for AdonisJS v6 applications",
5
5
  "keywords": [
6
6
  "adonisjs",