@guren/server 1.0.0-rc.9 → 1.0.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/{Application-DtWDHXr1.d.ts → Application-BnsyCKXY.d.ts} +79 -8
- package/dist/AuthManager-SfhCNkAU.d.ts +79 -0
- package/dist/{BroadcastManager-AkIWUGJo.d.ts → BroadcastManager-CGWl9rUO.d.ts} +5 -0
- package/dist/{ConsoleKernel-CqCVrdZs.d.ts → ConsoleKernel-BDtBETjm.d.ts} +1 -1
- package/dist/{Gate-CNkBYf8m.d.ts → Gate-CynjZCtS.d.ts} +5 -0
- package/dist/{I18nManager-Dtgzsf5n.d.ts → I18nManager-BiSoczfV.d.ts} +6 -1
- package/dist/McpServiceProvider-JW6PDVMD.js +7 -0
- package/dist/api-token-BSSCLlFW.d.ts +541 -0
- package/dist/auth/index.d.ts +9 -327
- package/dist/auth/index.js +59 -6684
- package/dist/authorization/index.d.ts +2 -2
- package/dist/authorization/index.js +19 -604
- package/dist/broadcasting/index.d.ts +2 -2
- package/dist/broadcasting/index.js +12 -895
- package/dist/cache/index.js +8 -809
- package/dist/chunk-2T6JN4VR.js +1563 -0
- package/dist/chunk-44F7JQ7I.js +950 -0
- package/dist/chunk-74HTZG3V.js +331 -0
- package/dist/chunk-A3ISJVEV.js +598 -0
- package/dist/chunk-CSDKWLFD.js +652 -0
- package/dist/chunk-CSRQTEQA.js +839 -0
- package/dist/chunk-DAQKYKLH.js +182 -0
- package/dist/chunk-EDRGAM6G.js +647 -0
- package/dist/chunk-EGU5KB7V.js +818 -0
- package/dist/chunk-H32L2NE3.js +372 -0
- package/dist/chunk-HKQSAFSN.js +837 -0
- package/dist/chunk-IOTWFHZU.js +558 -0
- package/dist/chunk-ONSDE37A.js +125 -0
- package/dist/chunk-QQKTH5KX.js +114 -0
- package/dist/chunk-R2TCP7D7.js +409 -0
- package/dist/chunk-SIP34GBE.js +380 -0
- package/dist/chunk-THSX7OOR.js +454 -0
- package/dist/chunk-UY3AZSYL.js +14 -0
- package/dist/chunk-VT5KRDPH.js +134 -0
- package/dist/chunk-VXXZIXAP.js +255 -0
- package/dist/chunk-WJJ5CTNI.js +907 -0
- package/dist/chunk-WVY45EIW.js +359 -0
- package/dist/chunk-ZRBLZY3M.js +462 -0
- package/dist/client-CKXJLsTe.d.ts +232 -0
- package/dist/email-verification-CAeArjui.d.ts +327 -0
- package/dist/encryption/index.js +48 -556
- package/dist/errors-JOOPDDQ6.js +34 -0
- package/dist/events/index.js +14 -316
- package/dist/health/index.js +12 -367
- package/dist/i18n/index.d.ts +2 -2
- package/dist/i18n/index.js +14 -583
- package/dist/index.d.ts +37 -239
- package/dist/index.js +2873 -19166
- package/dist/lambda/index.d.ts +9 -7
- package/dist/lambda/index.js +4 -9
- package/dist/logging/index.js +12 -545
- package/dist/mail/index.d.ts +29 -1
- package/dist/mail/index.js +15 -684
- package/dist/mcp/index.d.ts +7 -5
- package/dist/mcp/index.js +5 -378
- package/dist/notifications/index.d.ts +8 -6
- package/dist/notifications/index.js +13 -730
- package/dist/queue/index.d.ts +37 -7
- package/dist/queue/index.js +22 -940
- package/dist/redis/index.d.ts +366 -0
- package/dist/redis/index.js +597 -0
- package/dist/runtime/index.d.ts +8 -6
- package/dist/runtime/index.js +26 -244
- package/dist/scheduling/index.js +14 -822
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +6 -824
- package/package.json +15 -7
- package/dist/api-token-JOif2CtG.d.ts +0 -1792
package/dist/events/index.js
CHANGED
|
@@ -1,319 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* Get the event name from an instance.
|
|
16
|
-
*/
|
|
17
|
-
get eventName() {
|
|
18
|
-
return this.constructor.eventName;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
// src/events/EventManager.ts
|
|
23
|
-
var EventManager = class {
|
|
24
|
-
listeners = /* @__PURE__ */ new Map();
|
|
25
|
-
/**
|
|
26
|
-
* Queue dispatcher function (set when Queue system is integrated).
|
|
27
|
-
*/
|
|
28
|
-
queueDispatcher;
|
|
29
|
-
/**
|
|
30
|
-
* Register a listener for an event.
|
|
31
|
-
*
|
|
32
|
-
* @param event - Event class to listen for
|
|
33
|
-
* @param listener - Listener function
|
|
34
|
-
* @param options - Listener options
|
|
35
|
-
* @returns Subscription handle for unsubscribing
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* // Basic usage
|
|
40
|
-
* events.on(UserRegistered, (e) => console.log(e.email))
|
|
41
|
-
*
|
|
42
|
-
* // With options
|
|
43
|
-
* events.on(UserRegistered, (e) => sendEmail(e), { priority: 10 })
|
|
44
|
-
*
|
|
45
|
-
* // Unsubscribe later
|
|
46
|
-
* const sub = events.on(UserRegistered, handler)
|
|
47
|
-
* sub.unsubscribe()
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
on(event, listener, options = {}) {
|
|
51
|
-
const eventName = typeof event === "string" ? event : event.eventName;
|
|
52
|
-
const registeredListeners = this.listeners.get(eventName) ?? [];
|
|
53
|
-
const registered = {
|
|
54
|
-
listener,
|
|
55
|
-
options: { once: false, priority: 0, ...options }
|
|
56
|
-
};
|
|
57
|
-
registeredListeners.push(registered);
|
|
58
|
-
registeredListeners.sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0));
|
|
59
|
-
this.listeners.set(eventName, registeredListeners);
|
|
60
|
-
return {
|
|
61
|
-
unsubscribe: () => this.off(event, listener)
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Register a one-time listener for an event.
|
|
66
|
-
* The listener will be automatically removed after the first invocation.
|
|
67
|
-
*
|
|
68
|
-
* @param event - Event class to listen for
|
|
69
|
-
* @param listener - Listener function
|
|
70
|
-
* @param options - Additional listener options (once is always true)
|
|
71
|
-
* @returns Subscription handle for unsubscribing
|
|
72
|
-
*/
|
|
73
|
-
once(event, listener, options = {}) {
|
|
74
|
-
return this.on(event, listener, { ...options, once: true });
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Remove a listener for an event.
|
|
78
|
-
*
|
|
79
|
-
* @param event - Event class
|
|
80
|
-
* @param listener - Listener to remove (if omitted, all listeners for the event are removed)
|
|
81
|
-
*/
|
|
82
|
-
off(event, listener) {
|
|
83
|
-
const eventName = typeof event === "string" ? event : event.eventName;
|
|
84
|
-
const registeredListeners = this.listeners.get(eventName);
|
|
85
|
-
if (!registeredListeners) return;
|
|
86
|
-
if (!listener) {
|
|
87
|
-
this.listeners.delete(eventName);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const index = registeredListeners.findIndex((r) => r.listener === listener);
|
|
91
|
-
if (index !== -1) {
|
|
92
|
-
registeredListeners.splice(index, 1);
|
|
93
|
-
if (registeredListeners.length === 0) {
|
|
94
|
-
this.listeners.delete(eventName);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Emit an event to all registered listeners.
|
|
100
|
-
* Listeners are executed in order of priority (highest first).
|
|
101
|
-
* Async listeners are awaited sequentially.
|
|
102
|
-
*
|
|
103
|
-
* @param event - Event instance to emit
|
|
104
|
-
*
|
|
105
|
-
* @example
|
|
106
|
-
* ```ts
|
|
107
|
-
* await events.emit(new UserRegistered('123', 'user@example.com'))
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
async emit(event) {
|
|
111
|
-
const eventName = event.eventName;
|
|
112
|
-
const registeredListeners = this.listeners.get(eventName);
|
|
113
|
-
if (!registeredListeners || registeredListeners.length === 0) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
const listenersToCall = [...registeredListeners];
|
|
117
|
-
const toRemove = [];
|
|
118
|
-
for (const registered of listenersToCall) {
|
|
119
|
-
if (registered.options.queue && this.queueDispatcher) {
|
|
120
|
-
await this.queueDispatcher(registered.options.queue, eventName, event);
|
|
121
|
-
} else {
|
|
122
|
-
await registered.listener(event);
|
|
123
|
-
}
|
|
124
|
-
if (registered.options.once) {
|
|
125
|
-
toRemove.push(registered);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
for (const registered of toRemove) {
|
|
129
|
-
const index = registeredListeners.indexOf(registered);
|
|
130
|
-
if (index !== -1) {
|
|
131
|
-
registeredListeners.splice(index, 1);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
if (registeredListeners.length === 0) {
|
|
135
|
-
this.listeners.delete(eventName);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Emit an event to all registered listeners in parallel.
|
|
140
|
-
* Use this when listener execution order doesn't matter and you want faster execution.
|
|
141
|
-
*
|
|
142
|
-
* @param event - Event instance to emit
|
|
143
|
-
*/
|
|
144
|
-
async emitParallel(event) {
|
|
145
|
-
const eventName = event.eventName;
|
|
146
|
-
const registeredListeners = this.listeners.get(eventName);
|
|
147
|
-
if (!registeredListeners || registeredListeners.length === 0) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const listenersToCall = [...registeredListeners];
|
|
151
|
-
const toRemove = [];
|
|
152
|
-
await Promise.all(
|
|
153
|
-
listenersToCall.map(async (registered) => {
|
|
154
|
-
if (registered.options.queue && this.queueDispatcher) {
|
|
155
|
-
await this.queueDispatcher(registered.options.queue, eventName, event);
|
|
156
|
-
} else {
|
|
157
|
-
await registered.listener(event);
|
|
158
|
-
}
|
|
159
|
-
if (registered.options.once) {
|
|
160
|
-
toRemove.push(registered);
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
);
|
|
164
|
-
for (const registered of toRemove) {
|
|
165
|
-
const index = registeredListeners.indexOf(registered);
|
|
166
|
-
if (index !== -1) {
|
|
167
|
-
registeredListeners.splice(index, 1);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (registeredListeners.length === 0) {
|
|
171
|
-
this.listeners.delete(eventName);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Check if an event has any listeners registered.
|
|
176
|
-
*
|
|
177
|
-
* @param event - Event class or event name
|
|
178
|
-
*/
|
|
179
|
-
hasListeners(event) {
|
|
180
|
-
const eventName = typeof event === "string" ? event : event.eventName;
|
|
181
|
-
const listeners = this.listeners.get(eventName);
|
|
182
|
-
return listeners !== void 0 && listeners.length > 0;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Get all listeners for an event.
|
|
186
|
-
*
|
|
187
|
-
* @param event - Event class or event name
|
|
188
|
-
*/
|
|
189
|
-
getListeners(event) {
|
|
190
|
-
const eventName = typeof event === "string" ? event : event.eventName;
|
|
191
|
-
const registeredListeners = this.listeners.get(eventName);
|
|
192
|
-
if (!registeredListeners) return [];
|
|
193
|
-
return registeredListeners.map((r) => r.listener);
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Get the count of listeners for an event.
|
|
197
|
-
*
|
|
198
|
-
* @param event - Event class or event name
|
|
199
|
-
*/
|
|
200
|
-
listenerCount(event) {
|
|
201
|
-
const eventName = typeof event === "string" ? event : event.eventName;
|
|
202
|
-
return this.listeners.get(eventName)?.length ?? 0;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Get all registered event names.
|
|
206
|
-
*/
|
|
207
|
-
eventNames() {
|
|
208
|
-
return Array.from(this.listeners.keys());
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Remove all listeners for all events.
|
|
212
|
-
*/
|
|
213
|
-
removeAllListeners() {
|
|
214
|
-
this.listeners.clear();
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Set the queue dispatcher function.
|
|
218
|
-
* This is called by the Queue system when it's integrated.
|
|
219
|
-
*/
|
|
220
|
-
setQueueDispatcher(dispatcher) {
|
|
221
|
-
this.queueDispatcher = dispatcher;
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
function createEventManager() {
|
|
225
|
-
return new EventManager();
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// src/events/Listener.ts
|
|
229
|
-
var Listener = class {
|
|
230
|
-
/**
|
|
231
|
-
* The event class this listener handles.
|
|
232
|
-
* Must be set by subclasses.
|
|
233
|
-
*/
|
|
234
|
-
static event;
|
|
235
|
-
/**
|
|
236
|
-
* Whether this listener should be queued instead of executed immediately.
|
|
237
|
-
* @default false
|
|
238
|
-
*/
|
|
239
|
-
static shouldQueue = false;
|
|
240
|
-
/**
|
|
241
|
-
* The queue name to dispatch to when shouldQueue is true.
|
|
242
|
-
* @default 'default'
|
|
243
|
-
*/
|
|
244
|
-
static queue = "default";
|
|
245
|
-
/**
|
|
246
|
-
* Priority of this listener. Higher values are executed first.
|
|
247
|
-
* @default 0
|
|
248
|
-
*/
|
|
249
|
-
static priority = 0;
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// src/events/builtin.ts
|
|
253
|
-
var RequestReceived = class extends Event {
|
|
254
|
-
constructor(method, path, requestId) {
|
|
255
|
-
super();
|
|
256
|
-
this.method = method;
|
|
257
|
-
this.path = path;
|
|
258
|
-
this.requestId = requestId;
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
var RequestFinished = class extends Event {
|
|
262
|
-
constructor(method, path, status, durationMs, requestId) {
|
|
263
|
-
super();
|
|
264
|
-
this.method = method;
|
|
265
|
-
this.path = path;
|
|
266
|
-
this.status = status;
|
|
267
|
-
this.durationMs = durationMs;
|
|
268
|
-
this.requestId = requestId;
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
var UserAuthenticated = class extends Event {
|
|
272
|
-
constructor(userId, guard = "default") {
|
|
273
|
-
super();
|
|
274
|
-
this.userId = userId;
|
|
275
|
-
this.guard = guard;
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
var UserLoggedOut = class extends Event {
|
|
279
|
-
constructor(userId, guard = "default") {
|
|
280
|
-
super();
|
|
281
|
-
this.userId = userId;
|
|
282
|
-
this.guard = guard;
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
var JobProcessed = class extends Event {
|
|
286
|
-
constructor(jobId, jobName, queue, durationMs) {
|
|
287
|
-
super();
|
|
288
|
-
this.jobId = jobId;
|
|
289
|
-
this.jobName = jobName;
|
|
290
|
-
this.queue = queue;
|
|
291
|
-
this.durationMs = durationMs;
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
var JobFailed = class extends Event {
|
|
295
|
-
constructor(jobId, jobName, queue, error, attempts) {
|
|
296
|
-
super();
|
|
297
|
-
this.jobId = jobId;
|
|
298
|
-
this.jobName = jobName;
|
|
299
|
-
this.queue = queue;
|
|
300
|
-
this.error = error;
|
|
301
|
-
this.attempts = attempts;
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
var ApplicationStarted = class extends Event {
|
|
305
|
-
constructor(port, host) {
|
|
306
|
-
super();
|
|
307
|
-
this.port = port;
|
|
308
|
-
this.host = host;
|
|
309
|
-
}
|
|
310
|
-
};
|
|
311
|
-
var ApplicationShutdown = class extends Event {
|
|
312
|
-
constructor(reason) {
|
|
313
|
-
super();
|
|
314
|
-
this.reason = reason;
|
|
315
|
-
}
|
|
316
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
ApplicationShutdown,
|
|
3
|
+
ApplicationStarted,
|
|
4
|
+
Event,
|
|
5
|
+
EventManager,
|
|
6
|
+
JobFailed,
|
|
7
|
+
JobProcessed,
|
|
8
|
+
Listener,
|
|
9
|
+
RequestFinished,
|
|
10
|
+
RequestReceived,
|
|
11
|
+
UserAuthenticated,
|
|
12
|
+
UserLoggedOut,
|
|
13
|
+
createEventManager
|
|
14
|
+
} from "../chunk-74HTZG3V.js";
|
|
317
15
|
export {
|
|
318
16
|
ApplicationShutdown,
|
|
319
17
|
ApplicationStarted,
|
package/dist/health/index.js
CHANGED
|
@@ -1,370 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return this.result("degraded", message, meta);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Create an unhealthy result.
|
|
17
|
-
*/
|
|
18
|
-
unhealthy(message, meta) {
|
|
19
|
-
return this.result("unhealthy", message, meta);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Create an unhealthy result from a caught error.
|
|
23
|
-
*/
|
|
24
|
-
handleError(error, fallbackMessage) {
|
|
25
|
-
return this.unhealthy(
|
|
26
|
-
error instanceof Error ? error.message : fallbackMessage
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Create a check result.
|
|
31
|
-
*/
|
|
32
|
-
result(status, message, meta) {
|
|
33
|
-
const result = {
|
|
34
|
-
name: this.name,
|
|
35
|
-
status,
|
|
36
|
-
duration: 0
|
|
37
|
-
// Will be set by HealthManager
|
|
38
|
-
};
|
|
39
|
-
if (message !== void 0) {
|
|
40
|
-
result.message = message;
|
|
41
|
-
}
|
|
42
|
-
if (meta !== void 0) {
|
|
43
|
-
result.meta = meta;
|
|
44
|
-
}
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// src/health/HealthManager.ts
|
|
50
|
-
var HealthManager = class {
|
|
51
|
-
checks = /* @__PURE__ */ new Map();
|
|
52
|
-
/**
|
|
53
|
-
* Register a health check.
|
|
54
|
-
*/
|
|
55
|
-
register(check, options = {}) {
|
|
56
|
-
this.checks.set(check.name, {
|
|
57
|
-
check,
|
|
58
|
-
options: {
|
|
59
|
-
timeout: options.timeout ?? 5e3,
|
|
60
|
-
critical: options.critical ?? false
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
return this;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Unregister a health check.
|
|
67
|
-
*/
|
|
68
|
-
unregister(name) {
|
|
69
|
-
this.checks.delete(name);
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Get all registered check names.
|
|
74
|
-
*/
|
|
75
|
-
getCheckNames() {
|
|
76
|
-
return Array.from(this.checks.keys());
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Run all health checks.
|
|
80
|
-
*/
|
|
81
|
-
async check() {
|
|
82
|
-
return this.runChecks(this.getCheckNames());
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Run specific health checks.
|
|
86
|
-
*/
|
|
87
|
-
async checkOnly(names) {
|
|
88
|
-
const validNames = names.filter((name) => this.checks.has(name));
|
|
89
|
-
return this.runChecks(validNames);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Get a specific check result.
|
|
93
|
-
*/
|
|
94
|
-
async getCheck(name) {
|
|
95
|
-
const registered = this.checks.get(name);
|
|
96
|
-
if (!registered) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
return this.runCheck(registered);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Create middleware for health endpoints.
|
|
103
|
-
*/
|
|
104
|
-
middleware(options = {}) {
|
|
105
|
-
return async (ctx, next) => {
|
|
106
|
-
const report = options.checks ? await this.checkOnly(options.checks) : await this.check();
|
|
107
|
-
const statusCode = report.status === "healthy" ? 200 : report.status === "degraded" ? 200 : 503;
|
|
108
|
-
if (options.detailed === false) {
|
|
109
|
-
ctx.status(statusCode);
|
|
110
|
-
ctx.json({
|
|
111
|
-
status: report.status,
|
|
112
|
-
timestamp: report.timestamp.toISOString()
|
|
113
|
-
});
|
|
114
|
-
} else {
|
|
115
|
-
ctx.status(statusCode);
|
|
116
|
-
ctx.json({
|
|
117
|
-
status: report.status,
|
|
118
|
-
timestamp: report.timestamp.toISOString(),
|
|
119
|
-
checks: report.checks.map((check) => ({
|
|
120
|
-
name: check.name,
|
|
121
|
-
status: check.status,
|
|
122
|
-
message: check.message,
|
|
123
|
-
duration: check.duration,
|
|
124
|
-
meta: check.meta
|
|
125
|
-
}))
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Run the specified checks.
|
|
132
|
-
*/
|
|
133
|
-
async runChecks(names) {
|
|
134
|
-
const results = [];
|
|
135
|
-
let overallStatus = "healthy";
|
|
136
|
-
await Promise.all(
|
|
137
|
-
names.map(async (name) => {
|
|
138
|
-
const registered = this.checks.get(name);
|
|
139
|
-
if (!registered) return;
|
|
140
|
-
const result = await this.runCheck(registered);
|
|
141
|
-
results.push(result);
|
|
142
|
-
if (result.status === "unhealthy") {
|
|
143
|
-
if (registered.options.critical) {
|
|
144
|
-
overallStatus = "unhealthy";
|
|
145
|
-
} else if (overallStatus !== "unhealthy") {
|
|
146
|
-
overallStatus = "degraded";
|
|
147
|
-
}
|
|
148
|
-
} else if (result.status === "degraded" && overallStatus === "healthy") {
|
|
149
|
-
overallStatus = "degraded";
|
|
150
|
-
}
|
|
151
|
-
})
|
|
152
|
-
);
|
|
153
|
-
results.sort((a, b) => a.name.localeCompare(b.name));
|
|
154
|
-
return {
|
|
155
|
-
status: overallStatus,
|
|
156
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
157
|
-
checks: results
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Run a single check with timeout.
|
|
162
|
-
*/
|
|
163
|
-
async runCheck(registered) {
|
|
164
|
-
const { check, options } = registered;
|
|
165
|
-
const start = performance.now();
|
|
166
|
-
try {
|
|
167
|
-
const result = await Promise.race([
|
|
168
|
-
check.check(),
|
|
169
|
-
this.timeoutPromise(options.timeout)
|
|
170
|
-
]);
|
|
171
|
-
result.duration = Math.round(performance.now() - start);
|
|
172
|
-
return result;
|
|
173
|
-
} catch (error) {
|
|
174
|
-
const duration = Math.round(performance.now() - start);
|
|
175
|
-
return {
|
|
176
|
-
name: check.name,
|
|
177
|
-
status: "unhealthy",
|
|
178
|
-
message: error instanceof Error ? error.message : "Check failed with error",
|
|
179
|
-
duration
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Create a timeout promise.
|
|
185
|
-
*/
|
|
186
|
-
timeoutPromise(ms) {
|
|
187
|
-
return new Promise((_, reject) => {
|
|
188
|
-
setTimeout(() => {
|
|
189
|
-
reject(new Error(`Health check timed out after ${ms}ms`));
|
|
190
|
-
}, ms);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
function createHealthManager() {
|
|
195
|
-
return new HealthManager();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// src/health/checks/DatabaseCheck.ts
|
|
199
|
-
var DatabaseCheck = class extends HealthCheck {
|
|
200
|
-
name;
|
|
201
|
-
db;
|
|
202
|
-
query;
|
|
203
|
-
constructor(db, options = {}) {
|
|
204
|
-
super();
|
|
205
|
-
this.db = db;
|
|
206
|
-
this.name = options.name ?? "database";
|
|
207
|
-
this.query = options.query ?? "SELECT 1";
|
|
208
|
-
}
|
|
209
|
-
async check() {
|
|
210
|
-
try {
|
|
211
|
-
await this.db.query(this.query);
|
|
212
|
-
return this.healthy("Database connection is healthy");
|
|
213
|
-
} catch (error) {
|
|
214
|
-
return this.handleError(error, "Database connection failed");
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// src/health/checks/RedisCheck.ts
|
|
220
|
-
var RedisCheck = class extends HealthCheck {
|
|
221
|
-
name;
|
|
222
|
-
redis;
|
|
223
|
-
constructor(redis, options = {}) {
|
|
224
|
-
super();
|
|
225
|
-
this.redis = redis;
|
|
226
|
-
this.name = options.name ?? "redis";
|
|
227
|
-
}
|
|
228
|
-
async check() {
|
|
229
|
-
try {
|
|
230
|
-
const response = await this.redis.ping();
|
|
231
|
-
if (response === "PONG") {
|
|
232
|
-
return this.healthy("Redis connection is healthy");
|
|
233
|
-
}
|
|
234
|
-
return this.degraded(`Redis ping returned: ${response}`);
|
|
235
|
-
} catch (error) {
|
|
236
|
-
return this.handleError(error, "Redis connection failed");
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
// src/health/checks/CacheCheck.ts
|
|
242
|
-
var CacheCheck = class extends HealthCheck {
|
|
243
|
-
name;
|
|
244
|
-
cache;
|
|
245
|
-
testKey;
|
|
246
|
-
constructor(cache, options = {}) {
|
|
247
|
-
super();
|
|
248
|
-
this.cache = cache;
|
|
249
|
-
this.name = options.name ?? "cache";
|
|
250
|
-
this.testKey = options.testKey ?? "__health_check__";
|
|
251
|
-
}
|
|
252
|
-
async check() {
|
|
253
|
-
const testValue = `health_check_${Date.now()}`;
|
|
254
|
-
try {
|
|
255
|
-
await this.cache.put(this.testKey, testValue, 60);
|
|
256
|
-
const retrieved = await this.cache.get(this.testKey);
|
|
257
|
-
await this.cache.forget(this.testKey);
|
|
258
|
-
if (retrieved === testValue) {
|
|
259
|
-
return this.healthy("Cache is functioning correctly");
|
|
260
|
-
}
|
|
261
|
-
return this.degraded(
|
|
262
|
-
`Cache read/write mismatch: expected "${testValue}", got "${retrieved}"`
|
|
263
|
-
);
|
|
264
|
-
} catch (error) {
|
|
265
|
-
return this.handleError(error, "Cache operation failed");
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
// src/health/checks/StorageCheck.ts
|
|
271
|
-
var StorageCheck = class extends HealthCheck {
|
|
272
|
-
name;
|
|
273
|
-
storage;
|
|
274
|
-
testPath;
|
|
275
|
-
constructor(storage, options = {}) {
|
|
276
|
-
super();
|
|
277
|
-
this.storage = storage;
|
|
278
|
-
this.name = options.name ?? "storage";
|
|
279
|
-
this.testPath = options.testPath ?? "__health_check__.txt";
|
|
280
|
-
}
|
|
281
|
-
async check() {
|
|
282
|
-
const testContent = `health_check_${Date.now()}`;
|
|
283
|
-
try {
|
|
284
|
-
await this.storage.put(this.testPath, testContent);
|
|
285
|
-
const retrieved = await this.storage.get(this.testPath);
|
|
286
|
-
await this.storage.delete(this.testPath);
|
|
287
|
-
if (retrieved && retrieved.toString() === testContent) {
|
|
288
|
-
return this.healthy("Storage is functioning correctly");
|
|
289
|
-
}
|
|
290
|
-
return this.degraded("Storage read/write mismatch");
|
|
291
|
-
} catch (error) {
|
|
292
|
-
return this.handleError(error, "Storage operation failed");
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// src/health/checks/MemoryCheck.ts
|
|
298
|
-
var MemoryCheck = class extends HealthCheck {
|
|
299
|
-
name;
|
|
300
|
-
thresholdMb;
|
|
301
|
-
criticalThresholdMb;
|
|
302
|
-
constructor(options = {}) {
|
|
303
|
-
super();
|
|
304
|
-
this.name = options.name ?? "memory";
|
|
305
|
-
this.thresholdMb = options.thresholdMb ?? 512;
|
|
306
|
-
this.criticalThresholdMb = options.criticalThresholdMb ?? 1024;
|
|
307
|
-
}
|
|
308
|
-
async check() {
|
|
309
|
-
const usage = process.memoryUsage();
|
|
310
|
-
const usedMb = Math.round(usage.heapUsed / 1024 / 1024);
|
|
311
|
-
const totalMb = Math.round(usage.heapTotal / 1024 / 1024);
|
|
312
|
-
const rssMb = Math.round(usage.rss / 1024 / 1024);
|
|
313
|
-
const meta = {
|
|
314
|
-
usedMb,
|
|
315
|
-
totalMb,
|
|
316
|
-
rssMb,
|
|
317
|
-
thresholdMb: this.thresholdMb,
|
|
318
|
-
criticalThresholdMb: this.criticalThresholdMb
|
|
319
|
-
};
|
|
320
|
-
if (usedMb >= this.criticalThresholdMb) {
|
|
321
|
-
return this.unhealthy(
|
|
322
|
-
`Memory usage critical: ${usedMb}MB (threshold: ${this.criticalThresholdMb}MB)`,
|
|
323
|
-
meta
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
if (usedMb >= this.thresholdMb) {
|
|
327
|
-
return this.degraded(
|
|
328
|
-
`Memory usage elevated: ${usedMb}MB (threshold: ${this.thresholdMb}MB)`,
|
|
329
|
-
meta
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
return this.healthy(`Memory usage normal: ${usedMb}MB`, meta);
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
// src/health/checks/CustomCheck.ts
|
|
337
|
-
var CustomCheck = class extends HealthCheck {
|
|
338
|
-
name;
|
|
339
|
-
callback;
|
|
340
|
-
constructor(name, callback) {
|
|
341
|
-
super();
|
|
342
|
-
this.name = name;
|
|
343
|
-
this.callback = callback;
|
|
344
|
-
}
|
|
345
|
-
async check() {
|
|
346
|
-
try {
|
|
347
|
-
const result = await this.callback();
|
|
348
|
-
switch (result.status) {
|
|
349
|
-
case "healthy":
|
|
350
|
-
return this.healthy(result.message, result.meta);
|
|
351
|
-
case "degraded":
|
|
352
|
-
return this.degraded(result.message, result.meta);
|
|
353
|
-
case "unhealthy":
|
|
354
|
-
return this.unhealthy(result.message, result.meta);
|
|
355
|
-
default:
|
|
356
|
-
return this.unhealthy("Unknown status returned from check");
|
|
357
|
-
}
|
|
358
|
-
} catch (error) {
|
|
359
|
-
return this.unhealthy(
|
|
360
|
-
error instanceof Error ? error.message : "Custom check failed"
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
function customCheck(name, callback) {
|
|
366
|
-
return new CustomCheck(name, callback);
|
|
367
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
CacheCheck,
|
|
3
|
+
CustomCheck,
|
|
4
|
+
DatabaseCheck,
|
|
5
|
+
HealthCheck,
|
|
6
|
+
HealthManager,
|
|
7
|
+
MemoryCheck,
|
|
8
|
+
RedisCheck,
|
|
9
|
+
StorageCheck,
|
|
10
|
+
createHealthManager,
|
|
11
|
+
customCheck
|
|
12
|
+
} from "../chunk-SIP34GBE.js";
|
|
368
13
|
export {
|
|
369
14
|
CacheCheck,
|
|
370
15
|
CustomCheck,
|