@forinda/kickjs-devtools 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +118 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +396 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +28 -11
- package/public/devtools/index.html +557 -41
- package/dist/adapter.d.ts +0 -109
- package/dist/adapter.d.ts.map +0 -1
- package/dist/devtools/index.html +0 -575
- package/dist/devtools/tailwind.global.js +0 -897
- package/dist/devtools/vue.global.min.js +0 -25
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -205
package/dist/index.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
import { Router as v, static as A } from "express";
|
|
3
|
-
import { dirname as b, join as c } from "node:path";
|
|
4
|
-
import { fileURLToPath as R } from "node:url";
|
|
5
|
-
import { existsSync as y, readFileSync as E } from "node:fs";
|
|
6
|
-
import { randomBytes as D } from "node:crypto";
|
|
7
|
-
import { METADATA as f, computed as p, createLogger as S, reactive as C, ref as l, watch as m } from "@forinda/kickjs";
|
|
8
|
-
var h = S("DevTools"), j = class {
|
|
9
|
-
name = "DevToolsAdapter";
|
|
10
|
-
basePath;
|
|
11
|
-
enabled;
|
|
12
|
-
exposeConfig;
|
|
13
|
-
configPrefixes;
|
|
14
|
-
errorRateThreshold;
|
|
15
|
-
secret;
|
|
16
|
-
requestCount;
|
|
17
|
-
errorCount;
|
|
18
|
-
clientErrorCount;
|
|
19
|
-
startedAt;
|
|
20
|
-
errorRate;
|
|
21
|
-
uptimeSeconds;
|
|
22
|
-
routeLatency;
|
|
23
|
-
routes = [];
|
|
24
|
-
container = null;
|
|
25
|
-
appRef = null;
|
|
26
|
-
adapterStatuses = {};
|
|
27
|
-
stopErrorWatch = null;
|
|
28
|
-
peerAdapters = [];
|
|
29
|
-
constructor(s = {}) {
|
|
30
|
-
if (this.basePath = s.basePath ?? "/_debug", this.enabled = s.enabled ?? process.env.NODE_ENV !== "production", this.exposeConfig = s.exposeConfig ?? !1, this.configPrefixes = s.configPrefixes ?? ["APP_", "NODE_ENV"], this.errorRateThreshold = s.errorRateThreshold ?? 0.5, this.peerAdapters = s.adapters ?? [], s.secret === !1 ? this.secret = !1 : s.secret ? this.secret = s.secret : this.secret = D(16).toString("hex"), this.requestCount = l(0), this.errorCount = l(0), this.clientErrorCount = l(0), this.startedAt = l(Date.now()), this.routeLatency = C({}), this.errorRate = p(() => this.requestCount.value > 0 ? this.errorCount.value / this.requestCount.value : 0), this.uptimeSeconds = p(() => Math.floor((Date.now() - this.startedAt.value) / 1e3)), s.onErrorRateExceeded) {
|
|
31
|
-
const n = s.onErrorRateExceeded, r = this.errorRateThreshold;
|
|
32
|
-
this.stopErrorWatch = m(this.errorRate, (i) => {
|
|
33
|
-
i > r && n(i);
|
|
34
|
-
});
|
|
35
|
-
} else this.stopErrorWatch = m(this.errorRate, (n) => {
|
|
36
|
-
n > this.errorRateThreshold && h.warn(`Error rate elevated: ${(n * 100).toFixed(1)}%`);
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
getPeerAdapters() {
|
|
40
|
-
const s = this.appRef?.__kickApp;
|
|
41
|
-
return s && typeof s.getAdapters == "function" ? s.getAdapters() : this.peerAdapters;
|
|
42
|
-
}
|
|
43
|
-
beforeMount({ app: s, container: n }) {
|
|
44
|
-
if (!this.enabled) return;
|
|
45
|
-
this.appRef = s, this.container = n, this.startedAt.value = Date.now(), this.routes = [], this.adapterStatuses[this.name] = "running";
|
|
46
|
-
const r = v();
|
|
47
|
-
if (this.secret !== !1) {
|
|
48
|
-
const o = this.secret;
|
|
49
|
-
r.use((e, t, a) => {
|
|
50
|
-
if ((e.headers["x-devtools-token"] ?? e.query?.token) === o || e.path === "/" && e.method === "GET" && !e.query?.token || e.path.endsWith(".js") || e.path.endsWith(".css")) return a();
|
|
51
|
-
t.status(403).json({ error: "Forbidden — invalid or missing devtools token" });
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
r.get("/routes", (o, e) => {
|
|
55
|
-
e.json({ routes: this.routes });
|
|
56
|
-
}), r.get("/container", (o, e) => {
|
|
57
|
-
const t = this.container?.getRegistrations() ?? [];
|
|
58
|
-
e.json({
|
|
59
|
-
registrations: t,
|
|
60
|
-
count: t.length
|
|
61
|
-
});
|
|
62
|
-
}), r.get("/metrics", (o, e) => {
|
|
63
|
-
e.json({
|
|
64
|
-
requests: this.requestCount.value,
|
|
65
|
-
serverErrors: this.errorCount.value,
|
|
66
|
-
clientErrors: this.clientErrorCount.value,
|
|
67
|
-
errorRate: this.errorRate.value,
|
|
68
|
-
uptimeSeconds: this.uptimeSeconds.value,
|
|
69
|
-
startedAt: new Date(this.startedAt.value).toISOString(),
|
|
70
|
-
routeLatency: this.routeLatency
|
|
71
|
-
});
|
|
72
|
-
}), r.get("/health", (o, e) => {
|
|
73
|
-
const t = this.errorRate.value < this.errorRateThreshold, a = t ? "healthy" : "degraded";
|
|
74
|
-
e.status(t ? 200 : 503).json({
|
|
75
|
-
status: a,
|
|
76
|
-
errorRate: this.errorRate.value,
|
|
77
|
-
uptime: this.uptimeSeconds.value,
|
|
78
|
-
adapters: this.adapterStatuses
|
|
79
|
-
});
|
|
80
|
-
}), r.get("/state", (o, e) => {
|
|
81
|
-
const t = this.getPeerAdapters().find((a) => a.name === "WsAdapter" && typeof a.getStats == "function");
|
|
82
|
-
e.json({
|
|
83
|
-
reactive: {
|
|
84
|
-
requestCount: this.requestCount.value,
|
|
85
|
-
errorCount: this.errorCount.value,
|
|
86
|
-
clientErrorCount: this.clientErrorCount.value,
|
|
87
|
-
errorRate: this.errorRate.value,
|
|
88
|
-
uptimeSeconds: this.uptimeSeconds.value,
|
|
89
|
-
startedAt: new Date(this.startedAt.value).toISOString()
|
|
90
|
-
},
|
|
91
|
-
routes: this.routes.length,
|
|
92
|
-
container: this.container?.getRegistrations().length ?? 0,
|
|
93
|
-
routeLatency: this.routeLatency,
|
|
94
|
-
...t ? { ws: t.getStats() } : {}
|
|
95
|
-
});
|
|
96
|
-
}), r.get("/ws", (o, e) => {
|
|
97
|
-
const t = this.getPeerAdapters().find((a) => a.name === "WsAdapter" && typeof a.getStats == "function");
|
|
98
|
-
if (!t) {
|
|
99
|
-
e.json({
|
|
100
|
-
enabled: !1,
|
|
101
|
-
message: "WsAdapter not found"
|
|
102
|
-
});
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
e.json({
|
|
106
|
-
enabled: !0,
|
|
107
|
-
...t.getStats()
|
|
108
|
-
});
|
|
109
|
-
}), r.get("/queues", async (o, e) => {
|
|
110
|
-
const t = this.getPeerAdapters().find((a) => a.name === "QueueAdapter" && typeof a.getQueueNames == "function");
|
|
111
|
-
if (!t) {
|
|
112
|
-
e.json({
|
|
113
|
-
enabled: !1,
|
|
114
|
-
message: "QueueAdapter not found"
|
|
115
|
-
});
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
try {
|
|
119
|
-
const a = t.getQueueNames?.() ?? [], u = [];
|
|
120
|
-
for (const d of a) {
|
|
121
|
-
const g = await t.getQueueStats?.(d);
|
|
122
|
-
u.push({
|
|
123
|
-
name: d,
|
|
124
|
-
...g
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
e.json({
|
|
128
|
-
enabled: !0,
|
|
129
|
-
queues: u
|
|
130
|
-
});
|
|
131
|
-
} catch {
|
|
132
|
-
e.json({
|
|
133
|
-
enabled: !0,
|
|
134
|
-
queues: [],
|
|
135
|
-
error: "Failed to fetch queue stats"
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}), this.exposeConfig && r.get("/config", (o, e) => {
|
|
139
|
-
const t = {};
|
|
140
|
-
for (const [a, u] of Object.entries(process.env))
|
|
141
|
-
u !== void 0 && (t[a] = this.configPrefixes.some((d) => a.startsWith(d)) ? u : "[REDACTED]");
|
|
142
|
-
e.json({ config: t });
|
|
143
|
-
});
|
|
144
|
-
const i = this.resolvePublicDir();
|
|
145
|
-
if (i) {
|
|
146
|
-
r.use(A(i));
|
|
147
|
-
const o = E(c(i, "index.html"), "utf-8");
|
|
148
|
-
r.get("/", (e, t) => {
|
|
149
|
-
const a = o.replace("<body", `<body data-base="${this.basePath}"`);
|
|
150
|
-
t.type("html").send(a);
|
|
151
|
-
});
|
|
152
|
-
} else r.get("/", (o, e) => {
|
|
153
|
-
e.type("html").send("<h1>DevTools: public directory not found</h1>");
|
|
154
|
-
});
|
|
155
|
-
s.use(this.basePath, r), this.secret ? (h.info(`DevTools mounted at ${this.basePath} [token: ${this.secret}]`), h.info(`Access: ${this.basePath}?token=${this.secret}`)) : h.info(`DevTools mounted at ${this.basePath} [no guard]`);
|
|
156
|
-
}
|
|
157
|
-
middleware() {
|
|
158
|
-
return this.enabled ? [{
|
|
159
|
-
handler: (s, n, r) => {
|
|
160
|
-
const i = Date.now();
|
|
161
|
-
this.requestCount.value++, n.on("finish", () => {
|
|
162
|
-
n.statusCode >= 500 ? this.errorCount.value++ : n.statusCode >= 400 && this.clientErrorCount.value++;
|
|
163
|
-
const o = `${s.method} ${s.route?.path ?? s.path}`, e = Date.now() - i;
|
|
164
|
-
this.routeLatency[o] || (this.routeLatency[o] = {
|
|
165
|
-
count: 0,
|
|
166
|
-
totalMs: 0,
|
|
167
|
-
minMs: 1 / 0,
|
|
168
|
-
maxMs: 0
|
|
169
|
-
});
|
|
170
|
-
const t = this.routeLatency[o];
|
|
171
|
-
t.count++, t.totalMs += e, t.minMs = Math.min(t.minMs, e), t.maxMs = Math.max(t.maxMs, e);
|
|
172
|
-
}), r();
|
|
173
|
-
},
|
|
174
|
-
phase: "beforeGlobal"
|
|
175
|
-
}] : [];
|
|
176
|
-
}
|
|
177
|
-
onRouteMount(s, n) {
|
|
178
|
-
if (!this.enabled) return;
|
|
179
|
-
const r = Reflect.getMetadata(f.ROUTES, s) ?? [], i = Reflect.getMetadata(f.CLASS_MIDDLEWARES, s) ?? [];
|
|
180
|
-
for (const o of r) {
|
|
181
|
-
const e = Reflect.getMetadata(f.METHOD_MIDDLEWARES, s.prototype, o.handlerName) ?? [];
|
|
182
|
-
this.routes.push({
|
|
183
|
-
method: o.method.toUpperCase(),
|
|
184
|
-
path: `${n}${o.path === "/" ? "" : o.path}`,
|
|
185
|
-
controller: s.name,
|
|
186
|
-
handler: o.handlerName,
|
|
187
|
-
middleware: [...i.map((t) => t.name || "anonymous"), ...e.map((t) => t.name || "anonymous")]
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
afterStart({}) {
|
|
192
|
-
this.enabled && h.info(`DevTools ready — ${this.routes.length} routes tracked, ${this.container?.getRegistrations().length ?? 0} DI bindings`);
|
|
193
|
-
}
|
|
194
|
-
shutdown() {
|
|
195
|
-
this.stopErrorWatch?.(), this.adapterStatuses[this.name] = "stopped";
|
|
196
|
-
}
|
|
197
|
-
resolvePublicDir() {
|
|
198
|
-
const s = b(R(import.meta.url)), n = [c(s, "..", "public", "devtools"), c(s, "..", "..", "public", "devtools")];
|
|
199
|
-
for (const r of n) if (y(c(r, "index.html"))) return r;
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
export {
|
|
204
|
-
j as DevToolsAdapter
|
|
205
|
-
};
|