adonisjs-server-stats 1.16.1 → 1.17.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/README.md +14 -2
- package/dist/core/core/dashboard-api.d.ts +6 -4
- package/dist/core/index.js +9 -6
- package/dist/core/types.d.ts +24 -1
- package/dist/react/{CacheSection-DkLtukWz.js → CacheSection-C-X2Tnca.js} +48 -44
- package/dist/react/{CacheTab-DWeXnEBI.js → CacheTab-D55mfmeE.js} +1 -1
- package/dist/react/{ConfigSection-DaVbFPDg.js → ConfigSection-C-HGnZfd.js} +1 -1
- package/dist/react/{ConfigTab-D4640WJZ.js → ConfigTab-CNnsOXBh.js} +1 -1
- package/dist/react/{CustomPaneTab-DglmAVMC.js → CustomPaneTab-D-267UVd.js} +1 -1
- package/dist/react/{EmailsSection-vYx6ExTb.js → EmailsSection-Bqw4DI4r.js} +65 -57
- package/dist/react/{EmailsTab-DKDrRmRH.js → EmailsTab-CkHOhj2F.js} +1 -1
- package/dist/react/{EventsSection-CapH5xut.js → EventsSection-CMeyjzVC.js} +1 -1
- package/dist/react/{EventsTab-BNVEySAm.js → EventsTab-DgS2v1HX.js} +1 -1
- package/dist/react/{JobsSection-ZIQsJWid.js → JobsSection-oWH6pbrG.js} +1 -1
- package/dist/react/{JobsTab-DXQzXrDt.js → JobsTab-zdxX_as-.js} +1 -1
- package/dist/react/{LogEntryRow-BWkHE51-.js → LogEntryRow-Cn8Ee_X0.js} +1 -1
- package/dist/react/{LogsSection-ConXdBkL.js → LogsSection-XmiI2MMs.js} +2 -2
- package/dist/react/{LogsTab-CJM47LPn.js → LogsTab-ixusY4v7.js} +2 -2
- package/dist/react/{OverviewSection-DOMu2qvl.js → OverviewSection-CvhObTLP.js} +119 -111
- package/dist/react/{QueriesSection-DFsaOSJI.js → QueriesSection-BvledwBI.js} +1 -1
- package/dist/react/{QueriesTab-CY9CG_7L.js → QueriesTab-smQQJvJa.js} +1 -1
- package/dist/react/{RequestsSection-CC-eVHsl.js → RequestsSection-DKuYpViv.js} +2 -2
- package/dist/react/{RoutesSection-p1DMq41y.js → RoutesSection-5RNVurQ6.js} +1 -1
- package/dist/react/{RoutesTab-Cnqy8UcK.js → RoutesTab-CpXNO-Rx.js} +1 -1
- package/dist/react/{SplitPaneWrapper-XgkA0QxE.js → SplitPaneWrapper-DQvJnsuk.js} +1 -1
- package/dist/react/{TimelineTab-1YOERxe5.js → TimelineTab-LHQHHKkO.js} +2 -2
- package/dist/react/components/Dashboard/overview-data-context.d.ts +15 -0
- package/dist/react/components/Dashboard/sections/OverviewSection.d.ts +9 -0
- package/dist/react/{index-DOSlCpZ9.js → index-LlFvooUN.js} +148 -141
- package/dist/react/index.js +1 -1
- package/dist/src/collectors/app_collector.d.ts +11 -0
- package/dist/src/collectors/app_collector.js +11 -0
- package/dist/src/collectors/redis_collector.js +13 -13
- package/dist/src/dashboard/cache_handlers.d.ts +17 -3
- package/dist/src/dashboard/cache_handlers.js +14 -19
- package/dist/src/dashboard/coalesce_cache.d.ts +2 -8
- package/dist/src/dashboard/coalesce_cache.js +25 -0
- package/dist/src/dashboard/dashboard_controller.d.ts +1 -0
- package/dist/src/dashboard/dashboard_controller.js +8 -3
- package/dist/src/dashboard/dashboard_store.d.ts +0 -1
- package/dist/src/dashboard/dashboard_store.js +14 -6
- package/dist/src/dashboard/filter_handlers.js +26 -4
- package/dist/src/dashboard/flush_manager.d.ts +1 -0
- package/dist/src/dashboard/flush_manager.js +6 -1
- package/dist/src/dashboard/format_helpers.d.ts +0 -4
- package/dist/src/dashboard/format_helpers.js +0 -19
- package/dist/src/dashboard/integrations/config_inspector.js +6 -3
- package/dist/src/dashboard/migrator_tables.js +4 -0
- package/dist/src/dashboard/paginate_helper.js +21 -11
- package/dist/src/dashboard/sensitive_patterns.d.ts +37 -0
- package/dist/src/dashboard/sensitive_patterns.js +146 -5
- package/dist/src/dashboard/write_queue.d.ts +20 -21
- package/dist/src/dashboard/write_queue.js +37 -60
- package/dist/src/debug/query_collector.js +6 -1
- package/dist/src/debug/trace_collector.js +26 -13
- package/dist/src/edge/client/dashboard.js +2 -2
- package/dist/src/edge/client-vue/dashboard.js +5 -5
- package/dist/src/edge/views/dashboard.edge +1 -1
- package/dist/src/edge/views/debug-panel.edge +1 -1
- package/dist/src/edge/views/stats-bar.edge +1 -1
- package/dist/src/middleware/request_tracking_middleware.js +7 -2
- package/dist/src/provider/dashboard_init.d.ts +9 -1
- package/dist/src/provider/dashboard_init.js +10 -0
- package/dist/src/provider/email_helpers.js +20 -5
- package/dist/src/provider/server_stats_provider.d.ts +9 -0
- package/dist/src/provider/server_stats_provider.js +26 -7
- package/dist/src/provider/shutdown_helpers.js +3 -1
- package/dist/src/provider/toolbar_setup.js +21 -15
- package/dist/src/types.d.ts +24 -1
- package/dist/vue/CacheSection-Bm0goqX6.js +161 -0
- package/dist/vue/{ConfigSection-BiRAiaHj.js → ConfigSection-BrYslIMN.js} +1 -1
- package/dist/vue/{EmailsSection-Dl44qyqY.js → EmailsSection-B8N5vaWA.js} +89 -85
- package/dist/vue/{EventsSection-CWjeitjU.js → EventsSection-D2Y_xt0m.js} +1 -1
- package/dist/vue/{JobsSection-DOBb4LjZ.js → JobsSection-cEKqELLC.js} +1 -1
- package/dist/vue/{LogsSection-CXx-HOWJ.js → LogsSection-C3H2c0S3.js} +1 -1
- package/dist/vue/{OverviewSection-CyfNQ8uV.js → OverviewSection-I2swuHDa.js} +1 -1
- package/dist/vue/{QueriesSection-CXBsFp-y.js → QueriesSection-CF1IE3SN.js} +1 -1
- package/dist/vue/{RequestsSection-YTIaZGZd.js → RequestsSection-CuwgXzmU.js} +1 -1
- package/dist/vue/{RoutesSection-CDKMey49.js → RoutesSection-BhJCF7Rn.js} +1 -1
- package/dist/vue/composables/useDashboardData.d.ts +1 -1
- package/dist/vue/{index-14x39RI_.js → index-DUsImuIN.js} +95 -95
- package/dist/vue/index.js +1 -1
- package/package.json +12 -3
- package/dist/src/dashboard/explain_query.d.ts +0 -8
- package/dist/src/dashboard/explain_query.js +0 -22
- package/dist/src/provider/boot_initializer.d.ts +0 -28
- package/dist/src/provider/boot_initializer.js +0 -35
- package/dist/vue/CacheSection-CxEBVVkF.js +0 -156
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ Drop a single Edge tag into your layout and get a live stats bar showing CPU, me
|
|
|
13
13
|
|
|
14
14
|
Zero frontend dependencies. Zero build step. Just `@serverStats()` and go.
|
|
15
15
|
|
|
16
|
+
**Zero runtime dependencies.** Everything this package needs at runtime is either built into Node or an optional peer dependency you already chose to install (`@adonisjs/lucid`, `better-sqlite3`, ...). Nothing extra lands in your production `node_modules` supply chain.
|
|
17
|
+
|
|
16
18
|
**New (alpha):** Native [React & Vue components](#react--vue-inertiajs--alpha) for Inertia.js apps — same features, framework-native.
|
|
17
19
|
|
|
18
20
|

|
|
@@ -265,6 +267,8 @@ The following field names still work but will show deprecation warnings at boot.
|
|
|
265
267
|
| `dbPath` | `string` | `'.adonisjs/server-stats/dashboard.sqlite3'` | Path to the SQLite database file (relative to app root) |
|
|
266
268
|
| `debugEndpoint` | `string` | `'/admin/api/debug'` | Base path for the debug toolbar API endpoints |
|
|
267
269
|
| `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. |
|
|
270
|
+
| `cacheKeyPrefix` | `string` | -- | Allow-list prefix for the Cache tab (e.g. `'myapp:cache:'`). Scopes which Redis keys can be listed, read, and deleted. Unset: unrestricted in dev, single-key access refused in production. Env var `SERVER_STATS_CACHE_KEY_PREFIX` works as a fallback. |
|
|
271
|
+
| `emailBridgeChannel` | `string` | `'adonisjs-server-stats:emails'` | Redis pub/sub channel for the cross-process email bridge. Namespace it on a shared Redis so other subscribers cannot read your outbound mail. |
|
|
268
272
|
| `panes` | `DebugPane[]` | -- | Custom debug panel tabs |
|
|
269
273
|
|
|
270
274
|
---
|
|
@@ -288,6 +292,14 @@ Each collector is a factory function that returns a `MetricCollector`. All colle
|
|
|
288
292
|
| `logCollector(opts?)` | Errors/warnings/entries (5m window), entries/minute | optional | -- |
|
|
289
293
|
| `appCollector()` | Online users, pending webhooks, pending emails | none | `@adonisjs/lucid` |
|
|
290
294
|
|
|
295
|
+
> [!WARNING]
|
|
296
|
+
> `appCollector()` polls **your primary database** -- three `COUNT(*)` queries every collection interval (3s by default), forever. Index the columns it filters on or every tick is a full table scan:
|
|
297
|
+
>
|
|
298
|
+
> ```sql
|
|
299
|
+
> CREATE INDEX webhook_events_status_index ON webhook_events (status);
|
|
300
|
+
> CREATE INDEX scheduled_emails_status_index ON scheduled_emails (status);
|
|
301
|
+
> ```
|
|
302
|
+
|
|
291
303
|
### Collector Options
|
|
292
304
|
|
|
293
305
|
```ts
|
|
@@ -464,9 +476,9 @@ An `authorize` callback may be sync or async -- the route guard awaits it, so `a
|
|
|
464
476
|
|
|
465
477
|
Worth knowing before you expose it, even behind an admin guard:
|
|
466
478
|
|
|
467
|
-
- **One guard, no tiers.** Anyone who passes `authorize` can also `DELETE /api/cache/:key` and `POST /api/jobs/:id/retry`. Scope cache access with `SERVER_STATS_CACHE_KEY_PREFIX` -- unset means unrestricted.
|
|
479
|
+
- **One guard, no tiers.** Anyone who passes `authorize` can also `DELETE /api/cache/:key` and `POST /api/jobs/:id/retry`. Scope cache access with `advanced.cacheKeyPrefix` (or the `SERVER_STATS_CACHE_KEY_PREFIX` env var) -- unset means unrestricted in dev, and in production single-key cache reads/deletes are refused until a prefix is configured.
|
|
468
480
|
- **No audit log and no rate limiting** on those mutating endpoints.
|
|
469
|
-
- **SQL bindings
|
|
481
|
+
- **Redaction is pattern-based, not exhaustive.** SQL bindings, config/env values, stored URLs, and persisted log records are all redacted against a shared rule set (credential-shaped names incl. camelCase, hashes, JWTs, provider key prefixes, long hex/base64 blobs), and anything that survives is truncated at 256 chars. A secret under a name the patterns don't recognise, with an ordinary-looking value, still gets stored.
|
|
470
482
|
|
|
471
483
|
---
|
|
472
484
|
|
|
@@ -45,9 +45,10 @@ export declare class DashboardApi {
|
|
|
45
45
|
/**
|
|
46
46
|
* Fetch the value of a specific cache key.
|
|
47
47
|
*
|
|
48
|
-
* @param key
|
|
48
|
+
* @param key - Cache key (will be URI-encoded).
|
|
49
|
+
* @param init - Optional `RequestInit` overrides (e.g. `{ signal }`).
|
|
49
50
|
*/
|
|
50
|
-
fetchCacheKey(key: string): Promise<Record<string, unknown>>;
|
|
51
|
+
fetchCacheKey(key: string, init?: RequestInit): Promise<Record<string, unknown>>;
|
|
51
52
|
/**
|
|
52
53
|
* Delete a cache entry by key.
|
|
53
54
|
*
|
|
@@ -59,7 +60,8 @@ export declare class DashboardApi {
|
|
|
59
60
|
/**
|
|
60
61
|
* Fetch the HTML preview for an email record.
|
|
61
62
|
*
|
|
62
|
-
* @param id
|
|
63
|
+
* @param id - Email record ID.
|
|
64
|
+
* @param init - Optional `RequestInit` overrides (e.g. `{ signal }`).
|
|
63
65
|
*/
|
|
64
|
-
fetchEmailPreview(id: number): Promise<string>;
|
|
66
|
+
fetchEmailPreview(id: number, init?: RequestInit): Promise<string>;
|
|
65
67
|
}
|
package/dist/core/index.js
CHANGED
|
@@ -1110,11 +1110,13 @@ class At {
|
|
|
1110
1110
|
/**
|
|
1111
1111
|
* Fetch the value of a specific cache key.
|
|
1112
1112
|
*
|
|
1113
|
-
* @param key
|
|
1113
|
+
* @param key - Cache key (will be URI-encoded).
|
|
1114
|
+
* @param init - Optional `RequestInit` overrides (e.g. `{ signal }`).
|
|
1114
1115
|
*/
|
|
1115
|
-
async fetchCacheKey(e) {
|
|
1116
|
+
async fetchCacheKey(e, r) {
|
|
1116
1117
|
return this.client.fetch(
|
|
1117
|
-
`${this.basePath}/cache/${encodeURIComponent(e)}
|
|
1118
|
+
`${this.basePath}/cache/${encodeURIComponent(e)}`,
|
|
1119
|
+
r
|
|
1118
1120
|
);
|
|
1119
1121
|
}
|
|
1120
1122
|
/**
|
|
@@ -1133,10 +1135,11 @@ class At {
|
|
|
1133
1135
|
/**
|
|
1134
1136
|
* Fetch the HTML preview for an email record.
|
|
1135
1137
|
*
|
|
1136
|
-
* @param id
|
|
1138
|
+
* @param id - Email record ID.
|
|
1139
|
+
* @param init - Optional `RequestInit` overrides (e.g. `{ signal }`).
|
|
1137
1140
|
*/
|
|
1138
|
-
async fetchEmailPreview(e) {
|
|
1139
|
-
return this.client.fetch(`${this.basePath}/emails/${e}/preview
|
|
1141
|
+
async fetchEmailPreview(e, r) {
|
|
1142
|
+
return this.client.fetch(`${this.basePath}/emails/${e}/preview`, r);
|
|
1140
1143
|
}
|
|
1141
1144
|
}
|
|
1142
1145
|
function $t(t) {
|
package/dist/core/types.d.ts
CHANGED
|
@@ -461,7 +461,7 @@ export type AccessGuard = (ctx: import('@adonisjs/core/http').HttpContext) => bo
|
|
|
461
461
|
export interface CaptureConfig {
|
|
462
462
|
/** SQL text, bindings, and timings for every query. */
|
|
463
463
|
queries?: boolean;
|
|
464
|
-
/** Application events
|
|
464
|
+
/** Application events, linked to the request that follows them and persisted with it. */
|
|
465
465
|
events?: boolean;
|
|
466
466
|
/** Sent mail, including subject and body. */
|
|
467
467
|
emails?: boolean;
|
|
@@ -622,6 +622,29 @@ export interface AdvancedConfig {
|
|
|
622
622
|
* @default 200
|
|
623
623
|
*/
|
|
624
624
|
maxTraces?: number;
|
|
625
|
+
/**
|
|
626
|
+
* Allow-list prefix for the dashboard's cache inspector.
|
|
627
|
+
*
|
|
628
|
+
* Scopes which Redis keys the Cache tab may list, read, and delete
|
|
629
|
+
* (e.g. `'myapp:cache:'`). Unset keeps full access in development for
|
|
630
|
+
* back-compat, but in production single-key reads and deletes are
|
|
631
|
+
* refused until a prefix is configured — a production dashboard must
|
|
632
|
+
* not be able to read session keys or delete rate-limit counters.
|
|
633
|
+
*
|
|
634
|
+
* The `SERVER_STATS_CACHE_KEY_PREFIX` env var is used as a fallback.
|
|
635
|
+
*/
|
|
636
|
+
cacheKeyPrefix?: string;
|
|
637
|
+
/**
|
|
638
|
+
* Redis pub/sub channel for the cross-process email bridge.
|
|
639
|
+
*
|
|
640
|
+
* Queue workers publish captured mail on this channel and the web
|
|
641
|
+
* process persists it. On a Redis instance shared between apps or
|
|
642
|
+
* tenants, namespace this (e.g. `myapp:server-stats:emails`) so
|
|
643
|
+
* other subscribers cannot read your outbound mail.
|
|
644
|
+
*
|
|
645
|
+
* @default 'adonisjs-server-stats:emails'
|
|
646
|
+
*/
|
|
647
|
+
emailBridgeChannel?: string;
|
|
625
648
|
}
|
|
626
649
|
/**
|
|
627
650
|
* Top-level configuration for `adonisjs-server-stats`.
|
|
@@ -1,46 +1,50 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { formatCacheSize as
|
|
4
|
-
import { a as
|
|
5
|
-
import { C as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
function
|
|
9
|
-
const [
|
|
10
|
-
...
|
|
11
|
-
search:
|
|
12
|
-
}), a =
|
|
1
|
+
import { jsxs as u, jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useState as d, useRef as N, useCallback as v, useEffect as V } from "react";
|
|
3
|
+
import { formatCacheSize as L, formatTtl as R } from "adonisjs-server-stats/core";
|
|
4
|
+
import { a as E, J as F } from "./index-LlFvooUN.js";
|
|
5
|
+
import { C as T } from "./CacheStatsBar-CRodCOeP.js";
|
|
6
|
+
import { F as A } from "./FilterBar-CQ7bD669.js";
|
|
7
|
+
import { D as z } from "./DataTable-YyShr5B-.js";
|
|
8
|
+
function M({ options: g = {} }) {
|
|
9
|
+
const [y, w] = d(""), [r, h] = d(null), [C, n] = d(null), [K, m] = d(!1), [p, c] = d(null), s = N(null), { data: f, isLoading: S, mutate: k, getApi: b } = E("cache", {
|
|
10
|
+
...g,
|
|
11
|
+
search: y
|
|
12
|
+
}), a = f, x = v(
|
|
13
13
|
async (e) => {
|
|
14
14
|
if (confirm(`Delete cache key "${e}"?`))
|
|
15
15
|
try {
|
|
16
|
-
await
|
|
16
|
+
await k(`cache/${encodeURIComponent(e)}`, "delete"), r === e && (h(null), n(null), c(null));
|
|
17
17
|
} catch {
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
[
|
|
21
|
-
),
|
|
20
|
+
[k, r]
|
|
21
|
+
), D = v(
|
|
22
22
|
async (e) => {
|
|
23
|
-
if (
|
|
24
|
-
|
|
23
|
+
if (s.current?.abort(), r === e) {
|
|
24
|
+
s.current = null, h(null), n(null), c(null);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
h(e), n(null), c(null), m(!0);
|
|
28
|
+
const l = new AbortController();
|
|
29
|
+
s.current = l;
|
|
28
30
|
try {
|
|
29
|
-
const
|
|
31
|
+
const i = await b().fetchCacheKey(e, { signal: l.signal });
|
|
32
|
+
if (s.current !== l) return;
|
|
30
33
|
n(
|
|
31
|
-
|
|
32
|
-
),
|
|
33
|
-
} catch {
|
|
34
|
-
|
|
34
|
+
i.value !== void 0 ? i.value : i.data !== void 0 ? i.data : i
|
|
35
|
+
), c(null);
|
|
36
|
+
} catch (o) {
|
|
37
|
+
if (o instanceof Error && o.name === "AbortError" || s.current !== l) return;
|
|
38
|
+
n(null), c("Failed to fetch key value");
|
|
35
39
|
} finally {
|
|
36
|
-
|
|
40
|
+
s.current === l && m(!1);
|
|
37
41
|
}
|
|
38
42
|
},
|
|
39
|
-
[
|
|
43
|
+
[r, b]
|
|
40
44
|
);
|
|
41
|
-
return /* @__PURE__ */
|
|
45
|
+
return V(() => () => s.current?.abort(), []), /* @__PURE__ */ u("div", { children: [
|
|
42
46
|
a?.available && a?.stats && /* @__PURE__ */ t(
|
|
43
|
-
|
|
47
|
+
T,
|
|
44
48
|
{
|
|
45
49
|
hitRate: a.stats.hitRate ?? 0,
|
|
46
50
|
hits: a.stats.hits ?? 0,
|
|
@@ -49,16 +53,16 @@ function _({ options: v = {} }) {
|
|
|
49
53
|
}
|
|
50
54
|
),
|
|
51
55
|
/* @__PURE__ */ t(
|
|
52
|
-
|
|
56
|
+
A,
|
|
53
57
|
{
|
|
54
|
-
search:
|
|
55
|
-
onSearchChange:
|
|
58
|
+
search: y,
|
|
59
|
+
onSearchChange: w,
|
|
56
60
|
placeholder: "Filter cache keys...",
|
|
57
61
|
summary: `${(a?.keys || a?.data || []).length} keys`
|
|
58
62
|
}
|
|
59
63
|
),
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
S && !f ? /* @__PURE__ */ t("div", { className: "ss-dash-empty", children: "Loading cache..." }) : !a || !a.available ? /* @__PURE__ */ t("div", { className: "ss-dash-empty", children: "Cache inspector not available" }) : /* @__PURE__ */ t("div", { className: "ss-dash-table-wrap", children: /* @__PURE__ */ t(
|
|
65
|
+
z,
|
|
62
66
|
{
|
|
63
67
|
columns: [
|
|
64
68
|
{
|
|
@@ -89,25 +93,25 @@ function _({ options: v = {} }) {
|
|
|
89
93
|
key: "size",
|
|
90
94
|
label: "Size",
|
|
91
95
|
width: "60px",
|
|
92
|
-
render: (e) => e != null && e > 0 ?
|
|
96
|
+
render: (e) => e != null && e > 0 ? L(e) : "-"
|
|
93
97
|
},
|
|
94
98
|
{
|
|
95
99
|
key: "ttl",
|
|
96
100
|
label: "TTL",
|
|
97
101
|
width: "70px",
|
|
98
|
-
render: (e) => e > 0 ?
|
|
102
|
+
render: (e) => e > 0 ? R(e) : "-"
|
|
99
103
|
},
|
|
100
104
|
{
|
|
101
105
|
key: "_actions",
|
|
102
106
|
label: "",
|
|
103
107
|
width: "60px",
|
|
104
|
-
render: (e,
|
|
108
|
+
render: (e, l) => /* @__PURE__ */ t(
|
|
105
109
|
"button",
|
|
106
110
|
{
|
|
107
111
|
type: "button",
|
|
108
112
|
className: "ss-dash-retry-btn",
|
|
109
|
-
onClick: (
|
|
110
|
-
|
|
113
|
+
onClick: (o) => {
|
|
114
|
+
o.stopPropagation(), x(l.key);
|
|
111
115
|
},
|
|
112
116
|
children: "Delete"
|
|
113
117
|
}
|
|
@@ -116,20 +120,20 @@ function _({ options: v = {} }) {
|
|
|
116
120
|
],
|
|
117
121
|
data: a.keys || a.data || [],
|
|
118
122
|
keyField: "key",
|
|
119
|
-
onRowClick: (e) =>
|
|
123
|
+
onRowClick: (e) => D(e.key),
|
|
120
124
|
emptyMessage: "No cache keys found"
|
|
121
125
|
}
|
|
122
126
|
) }),
|
|
123
|
-
|
|
124
|
-
/* @__PURE__ */
|
|
127
|
+
r && /* @__PURE__ */ u("div", { className: "ss-dash-cache-detail", children: [
|
|
128
|
+
/* @__PURE__ */ u("h4", { children: [
|
|
125
129
|
"Key: ",
|
|
126
|
-
|
|
130
|
+
r
|
|
127
131
|
] }),
|
|
128
|
-
|
|
132
|
+
K ? /* @__PURE__ */ t("div", { className: "ss-dash-empty", children: "Loading value..." }) : p ? /* @__PURE__ */ t("div", { className: "ss-dash-empty", style: { color: "var(--ss-red-fg)" }, children: p }) : /* @__PURE__ */ t(F, { data: C })
|
|
129
133
|
] })
|
|
130
134
|
] });
|
|
131
135
|
}
|
|
132
136
|
export {
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
M as CacheSection,
|
|
138
|
+
M as default
|
|
135
139
|
};
|
|
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as p, useRef as z, useMemo as A, useCallback as K, useEffect as L } from "react";
|
|
3
3
|
import { formatTtl as $, formatCacheSize as j } from "adonisjs-server-stats/core";
|
|
4
4
|
import { u as F } from "./useDashboardApiBase-Bi36pJ2L.js";
|
|
5
|
-
import { u as D, J as E } from "./index-
|
|
5
|
+
import { u as D, J as E } from "./index-LlFvooUN.js";
|
|
6
6
|
import { u as V } from "./useResizableTable-CNJmACdt.js";
|
|
7
7
|
import { C as J } from "./CacheStatsBar-CRodCOeP.js";
|
|
8
8
|
import { F as M } from "./FilterBar-CQ7bD669.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { a as i } from "./index-
|
|
2
|
+
import { a as i } from "./index-LlFvooUN.js";
|
|
3
3
|
import { C as n } from "./ConfigContent-Bwvfl_G7.js";
|
|
4
4
|
function m({ options: o = {} }) {
|
|
5
5
|
const { data: a, isLoading: s } = i("config", o);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as i, jsx as n } from "react/jsx-runtime";
|
|
2
2
|
import { u as f } from "./useDashboardApiBase-Bi36pJ2L.js";
|
|
3
|
-
import { u as m } from "./index-
|
|
3
|
+
import { u as m } from "./index-LlFvooUN.js";
|
|
4
4
|
import { C as d } from "./ConfigContent-Bwvfl_G7.js";
|
|
5
5
|
function b({ options: r, dashboardPath: o }) {
|
|
6
6
|
const { resolvedOptions: a } = f(o, r), { data: e, isLoading: t, error: s } = m("config", a);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as l, jsx as r } from "react/jsx-runtime";
|
|
2
2
|
import { useState as w, useMemo as f } from "react";
|
|
3
3
|
import { compactPreview as k, formatDuration as x, durationClassName as M } from "adonisjs-server-stats/core";
|
|
4
|
-
import { u as L, B as A, M as B } from "./index-
|
|
4
|
+
import { u as L, B as A, M as B } from "./index-LlFvooUN.js";
|
|
5
5
|
import { T as b } from "./TimeAgoCell-o3KigGfM.js";
|
|
6
6
|
import { u as D } from "./useResizableTable-CNJmACdt.js";
|
|
7
7
|
import { F as P } from "./FilterBar-CQ7bD669.js";
|
|
@@ -1,65 +1,73 @@
|
|
|
1
|
-
import { jsx as s, jsxs as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { resolveCcAddr as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { P as
|
|
10
|
-
function
|
|
11
|
-
const [
|
|
12
|
-
|
|
13
|
-
const
|
|
1
|
+
import { jsx as s, jsxs as b, Fragment as E } from "react/jsx-runtime";
|
|
2
|
+
import { useState as o, useRef as N, useEffect as y, useCallback as F } from "react";
|
|
3
|
+
import { resolveCcAddr as _, resolveToAddr as g, resolveFromAddr as x, resolveAttachmentCount as $, resolveTimestamp as D } from "adonisjs-server-stats/core";
|
|
4
|
+
import { a as O } from "./index-LlFvooUN.js";
|
|
5
|
+
import { E as R } from "./EmailPreviewOverlay-BmXOAvqG.js";
|
|
6
|
+
import { F as B } from "./FilterBar-CQ7bD669.js";
|
|
7
|
+
import { T as H } from "./TimeAgoCell-o3KigGfM.js";
|
|
8
|
+
import { D as I } from "./DataTable-YyShr5B-.js";
|
|
9
|
+
import { P as L } from "./Pagination-BkmzUDY8.js";
|
|
10
|
+
function X({ options: n = {} }) {
|
|
11
|
+
const [k, m] = o(1), [i, A] = o(""), [p, c] = o(null), [h, d] = o(null), a = N(null), { data: u, meta: l, isLoading: C } = O("emails", { ...n, page: k, search: i }), w = u || [];
|
|
12
|
+
y(() => m(1), [i]);
|
|
13
|
+
const S = F(
|
|
14
14
|
async (e) => {
|
|
15
|
-
if (e.html) {
|
|
16
|
-
|
|
15
|
+
if (a.current?.abort(), e.html) {
|
|
16
|
+
a.current = null, c(e.id), d(e.html);
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
+
const t = new AbortController();
|
|
20
|
+
a.current = t;
|
|
19
21
|
try {
|
|
20
|
-
const { baseUrl:
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const { baseUrl: r = "", dashboardEndpoint: P = "/__stats/api", authToken: v } = n, T = `${r}${P}/emails/${e.id}/preview`, f = { Accept: "text/html" };
|
|
23
|
+
v && (f.Authorization = `Bearer ${v}`);
|
|
24
|
+
const j = await (await fetch(T, {
|
|
25
|
+
headers: f,
|
|
26
|
+
credentials: "same-origin",
|
|
27
|
+
signal: t.signal
|
|
28
|
+
})).text();
|
|
29
|
+
if (a.current !== t) return;
|
|
30
|
+
c(e.id), d(j);
|
|
31
|
+
} catch (r) {
|
|
32
|
+
if (r instanceof Error && r.name === "AbortError") return;
|
|
25
33
|
}
|
|
26
34
|
},
|
|
27
|
-
[
|
|
35
|
+
[n]
|
|
28
36
|
);
|
|
29
|
-
if (
|
|
30
|
-
const e =
|
|
37
|
+
if (y(() => () => a.current?.abort(), []), p && h) {
|
|
38
|
+
const e = w.find((r) => r.id === p), t = e ? {
|
|
31
39
|
subject: e.subject,
|
|
32
|
-
from:
|
|
33
|
-
to:
|
|
34
|
-
cc:
|
|
40
|
+
from: x(e),
|
|
41
|
+
to: g(e),
|
|
42
|
+
cc: _(e) || null,
|
|
35
43
|
status: e.status,
|
|
36
44
|
mailer: e.mailer
|
|
37
45
|
} : null;
|
|
38
46
|
return /* @__PURE__ */ s(
|
|
39
|
-
|
|
47
|
+
R,
|
|
40
48
|
{
|
|
41
49
|
email: t,
|
|
42
|
-
previewHtml:
|
|
50
|
+
previewHtml: h,
|
|
43
51
|
onClose: () => {
|
|
44
|
-
|
|
52
|
+
c(null), d(null);
|
|
45
53
|
},
|
|
46
54
|
className: "ss-dash-email-preview"
|
|
47
55
|
}
|
|
48
56
|
);
|
|
49
57
|
}
|
|
50
|
-
return /* @__PURE__ */
|
|
58
|
+
return /* @__PURE__ */ b("div", { children: [
|
|
51
59
|
/* @__PURE__ */ s(
|
|
52
|
-
|
|
60
|
+
B,
|
|
53
61
|
{
|
|
54
62
|
search: i,
|
|
55
|
-
onSearchChange:
|
|
63
|
+
onSearchChange: A,
|
|
56
64
|
placeholder: "Filter emails...",
|
|
57
|
-
summary: `${
|
|
65
|
+
summary: `${l?.total ?? 0} emails`
|
|
58
66
|
}
|
|
59
67
|
),
|
|
60
|
-
|
|
68
|
+
C && !u ? /* @__PURE__ */ s("div", { className: "ss-dash-empty", children: "Loading emails..." }) : /* @__PURE__ */ b(E, { children: [
|
|
61
69
|
/* @__PURE__ */ s("div", { className: "ss-dash-table-wrap", children: /* @__PURE__ */ s(
|
|
62
|
-
|
|
70
|
+
I,
|
|
63
71
|
{
|
|
64
72
|
columns: [
|
|
65
73
|
{
|
|
@@ -73,11 +81,11 @@ function Q({ options: o = {} }) {
|
|
|
73
81
|
label: "From",
|
|
74
82
|
width: "150px",
|
|
75
83
|
render: (e, t) => {
|
|
76
|
-
const
|
|
84
|
+
const r = x(t);
|
|
77
85
|
return /* @__PURE__ */ s(
|
|
78
86
|
"span",
|
|
79
87
|
{
|
|
80
|
-
title:
|
|
88
|
+
title: r,
|
|
81
89
|
style: {
|
|
82
90
|
color: "var(--ss-text-secondary)",
|
|
83
91
|
overflow: "hidden",
|
|
@@ -85,7 +93,7 @@ function Q({ options: o = {} }) {
|
|
|
85
93
|
whiteSpace: "nowrap",
|
|
86
94
|
display: "block"
|
|
87
95
|
},
|
|
88
|
-
children:
|
|
96
|
+
children: r
|
|
89
97
|
}
|
|
90
98
|
);
|
|
91
99
|
}
|
|
@@ -95,11 +103,11 @@ function Q({ options: o = {} }) {
|
|
|
95
103
|
label: "To",
|
|
96
104
|
width: "150px",
|
|
97
105
|
render: (e, t) => {
|
|
98
|
-
const
|
|
106
|
+
const r = g(t);
|
|
99
107
|
return /* @__PURE__ */ s(
|
|
100
108
|
"span",
|
|
101
109
|
{
|
|
102
|
-
title:
|
|
110
|
+
title: r,
|
|
103
111
|
style: {
|
|
104
112
|
color: "var(--ss-text-secondary)",
|
|
105
113
|
overflow: "hidden",
|
|
@@ -107,7 +115,7 @@ function Q({ options: o = {} }) {
|
|
|
107
115
|
whiteSpace: "nowrap",
|
|
108
116
|
display: "block"
|
|
109
117
|
},
|
|
110
|
-
children:
|
|
118
|
+
children: r
|
|
111
119
|
}
|
|
112
120
|
);
|
|
113
121
|
}
|
|
@@ -147,12 +155,12 @@ function Q({ options: o = {} }) {
|
|
|
147
155
|
label: "ATT",
|
|
148
156
|
width: "40px",
|
|
149
157
|
render: (e, t) => {
|
|
150
|
-
const
|
|
151
|
-
return
|
|
158
|
+
const r = $(t);
|
|
159
|
+
return r > 0 ? /* @__PURE__ */ s(
|
|
152
160
|
"span",
|
|
153
161
|
{
|
|
154
162
|
style: { color: "var(--ss-dim)", textAlign: "center", display: "block" },
|
|
155
|
-
children:
|
|
163
|
+
children: r
|
|
156
164
|
}
|
|
157
165
|
) : /* @__PURE__ */ s(
|
|
158
166
|
"span",
|
|
@@ -190,11 +198,11 @@ function Q({ options: o = {} }) {
|
|
|
190
198
|
label: "Time",
|
|
191
199
|
width: "80px",
|
|
192
200
|
render: (e, t) => {
|
|
193
|
-
const
|
|
201
|
+
const r = D(t);
|
|
194
202
|
return /* @__PURE__ */ s(
|
|
195
|
-
|
|
203
|
+
H,
|
|
196
204
|
{
|
|
197
|
-
ts:
|
|
205
|
+
ts: r,
|
|
198
206
|
className: "ss-dash-event-time",
|
|
199
207
|
style: { whiteSpace: "nowrap" }
|
|
200
208
|
}
|
|
@@ -202,25 +210,25 @@ function Q({ options: o = {} }) {
|
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
212
|
],
|
|
205
|
-
data:
|
|
206
|
-
onRowClick:
|
|
213
|
+
data: w,
|
|
214
|
+
onRowClick: S,
|
|
207
215
|
rowClassName: "ss-dash-email-row",
|
|
208
216
|
emptyMessage: "No emails captured yet"
|
|
209
217
|
}
|
|
210
218
|
) }),
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
l && /* @__PURE__ */ s(
|
|
220
|
+
L,
|
|
213
221
|
{
|
|
214
|
-
page:
|
|
215
|
-
lastPage:
|
|
216
|
-
total:
|
|
217
|
-
onPageChange:
|
|
222
|
+
page: l.page,
|
|
223
|
+
lastPage: l.lastPage,
|
|
224
|
+
total: l.total,
|
|
225
|
+
onPageChange: m
|
|
218
226
|
}
|
|
219
227
|
)
|
|
220
228
|
] })
|
|
221
229
|
] });
|
|
222
230
|
}
|
|
223
231
|
export {
|
|
224
|
-
|
|
225
|
-
|
|
232
|
+
X as EmailsSection,
|
|
233
|
+
X as default
|
|
226
234
|
};
|
|
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as i } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as c, useRef as A, useMemo as v, useCallback as y, useEffect as S } from "react";
|
|
3
3
|
import { resolveTimestamp as j } from "adonisjs-server-stats/core";
|
|
4
4
|
import { T as q } from "./TimeAgoCell-o3KigGfM.js";
|
|
5
|
-
import { u as $ } from "./index-
|
|
5
|
+
import { u as $ } from "./index-LlFvooUN.js";
|
|
6
6
|
import { u as F } from "./useResizableTable-CNJmACdt.js";
|
|
7
7
|
import { F as R } from "./FilterBar-CQ7bD669.js";
|
|
8
8
|
import { E as M } from "./EmailPreviewOverlay-BmXOAvqG.js";
|
|
@@ -2,7 +2,7 @@ import { jsxs as i, jsx as e, Fragment as g } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as m, useEffect as f } from "react";
|
|
3
3
|
import { resolveEventName as y, resolveTimestamp as u } from "adonisjs-server-stats/core";
|
|
4
4
|
import { T as w } from "./TimeAgoCell-o3KigGfM.js";
|
|
5
|
-
import { a as b, J as N } from "./index-
|
|
5
|
+
import { a as b, J as N } from "./index-LlFvooUN.js";
|
|
6
6
|
import { D as x } from "./DataTable-YyShr5B-.js";
|
|
7
7
|
import { F as P } from "./FilterBar-CQ7bD669.js";
|
|
8
8
|
import { P as k } from "./Pagination-BkmzUDY8.js";
|
|
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as p, useMemo as u } from "react";
|
|
3
3
|
import { resolveTimestamp as g } from "adonisjs-server-stats/core";
|
|
4
4
|
import { T as b } from "./TimeAgoCell-o3KigGfM.js";
|
|
5
|
-
import { u as f, J as v } from "./index-
|
|
5
|
+
import { u as f, J as v } from "./index-LlFvooUN.js";
|
|
6
6
|
import { u as w } from "./useResizableTable-CNJmACdt.js";
|
|
7
7
|
import { F as y } from "./FilterBar-CQ7bD669.js";
|
|
8
8
|
function E({ options: c }) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as y, jsx as t, Fragment as T } from "react/jsx-runtime";
|
|
2
2
|
import { useState as l, useCallback as C } from "react";
|
|
3
3
|
import { extractJobs as D, extractJobStats as F, JOB_STATUS_FILTERS as j, getJobStatusBadgeColor as B, formatDuration as A, resolveJobTimestamp as L } from "adonisjs-server-stats/core";
|
|
4
|
-
import { a as R, B as _, J as $ } from "./index-
|
|
4
|
+
import { a as R, B as _, J as $ } from "./index-LlFvooUN.js";
|
|
5
5
|
import { J as M } from "./JobStatsBar-C7RslAFE.js";
|
|
6
6
|
import { T as O } from "./TimeAgoCell-o3KigGfM.js";
|
|
7
7
|
import { D as U } from "./DataTable-YyShr5B-.js";
|
|
@@ -3,7 +3,7 @@ import { useState as m, useMemo as C, useCallback as A } from "react";
|
|
|
3
3
|
import { extractJobs as B, extractJobStats as $, JOB_STATUS_FILTERS as D, getJobStatusCssClass as F, formatDuration as L, resolveJobTimestamp as R } from "adonisjs-server-stats/core";
|
|
4
4
|
import { T as P } from "./TimeAgoCell-o3KigGfM.js";
|
|
5
5
|
import { u as k } from "./useDashboardApiBase-Bi36pJ2L.js";
|
|
6
|
-
import { u as E, J as O } from "./index-
|
|
6
|
+
import { u as E, J as O } from "./index-LlFvooUN.js";
|
|
7
7
|
import { u as q } from "./useResizableTable-CNJmACdt.js";
|
|
8
8
|
import { F as z } from "./FilterBar-CQ7bD669.js";
|
|
9
9
|
import { J as M } from "./JobStatsBar-C7RslAFE.js";
|
|
@@ -2,7 +2,7 @@ import { jsxs as i, jsx as s } from "react/jsx-runtime";
|
|
|
2
2
|
import g from "react";
|
|
3
3
|
import { T as v } from "./TimeAgoCell-o3KigGfM.js";
|
|
4
4
|
import { resolveLogLevel as u, resolveLogMessage as f, resolveLogTimestamp as h, resolveLogRequestId as L, getStructuredData as x, getLogLevelCssClass as N } from "adonisjs-server-stats/core";
|
|
5
|
-
import { J as y } from "./index-
|
|
5
|
+
import { J as y } from "./index-LlFvooUN.js";
|
|
6
6
|
function $({ log: o, index: c, expanded: l, onToggleExpand: m, onReqIdClick: e }) {
|
|
7
7
|
const n = u(o), d = f(o), p = h(o), a = L(o), t = x(o);
|
|
8
8
|
return /* @__PURE__ */ i(g.Fragment, { children: [
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsxs as l, jsx as t } from "react/jsx-runtime";
|
|
2
2
|
import { useState as a, useCallback as c } from "react";
|
|
3
3
|
import { LOG_LEVELS as B } from "adonisjs-server-stats/core";
|
|
4
|
-
import { a as G } from "./index-
|
|
4
|
+
import { a as G } from "./index-LlFvooUN.js";
|
|
5
5
|
import { F as T } from "./FilterBar-CQ7bD669.js";
|
|
6
|
-
import { L as z } from "./LogEntryRow-
|
|
6
|
+
import { L as z } from "./LogEntryRow-Cn8Ee_X0.js";
|
|
7
7
|
import { P as H } from "./Pagination-BkmzUDY8.js";
|
|
8
8
|
function Z({ options: L = {} }) {
|
|
9
9
|
const [E, i] = a(1), [b, x] = a(""), [r, q] = a("all"), [n, h] = a(""), [u, p] = a(""), [m, y] = a([]), [v, R] = a("level"), [g, $] = a("equals"), [f, C] = a(""), [F, P] = a(null), o = {};
|