stratal 0.0.20 → 0.0.22
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 +1 -1
- package/dist/{base-email.provider-CfQCA08m.mjs → base-email.provider-BWZHIjt8.mjs} +1 -1
- package/dist/{base-email.provider-CfQCA08m.mjs.map → base-email.provider-BWZHIjt8.mjs.map} +1 -1
- package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
- package/dist/bin/quarry.mjs +46 -109
- package/dist/bin/quarry.mjs.map +1 -1
- package/dist/cache/index.d.mts +6 -46
- package/dist/cache/index.d.mts.map +1 -1
- package/dist/cache/index.mjs +22 -67
- package/dist/cache/index.mjs.map +1 -1
- package/dist/{cache.service-DsnKuNyO.d.mts → cache.service-e34gV6tz.d.mts} +8 -8
- package/dist/{cache.service-DsnKuNyO.d.mts.map → cache.service-e34gV6tz.d.mts.map} +1 -1
- package/dist/{cache.tokens-B7Rw1C9Q.mjs → cache.tokens-ovi_c52J.mjs} +1 -1
- package/dist/{cache.tokens-B7Rw1C9Q.mjs.map → cache.tokens-ovi_c52J.mjs.map} +1 -1
- package/dist/{colors-DJaRDXoS.mjs → colors-axmupKdp.mjs} +1 -1
- package/dist/{colors-DJaRDXoS.mjs.map → colors-axmupKdp.mjs.map} +1 -1
- package/dist/{command-BgSlsS4M.mjs → command-BU4ApTo5.mjs} +2 -3
- package/dist/command-BU4ApTo5.mjs.map +1 -0
- package/dist/{command-Bu-PjJrX.d.mts → command-wXfvHbBZ.d.mts} +3 -2
- package/dist/command-wXfvHbBZ.d.mts.map +1 -0
- package/dist/config/index.d.mts +24 -11
- package/dist/config/index.d.mts.map +1 -1
- package/dist/config/index.mjs +33 -57
- package/dist/config/index.mjs.map +1 -1
- package/dist/{consumer-registry-B7yUNh0q.d.mts → consumer-registry-DHQtypr1.d.mts} +1 -1
- package/dist/{consumer-registry-B7yUNh0q.d.mts.map → consumer-registry-DHQtypr1.d.mts.map} +1 -1
- package/dist/container-storage-GpNNz79X.mjs +52 -0
- package/dist/container-storage-GpNNz79X.mjs.map +1 -0
- package/dist/{controller.decorator-DQzenvSN.mjs → controller.decorator-DIUazNU7.mjs} +8 -8
- package/dist/controller.decorator-DIUazNU7.mjs.map +1 -0
- package/dist/cron/index.d.mts +26 -5
- package/dist/cron/index.d.mts.map +1 -1
- package/dist/cron/index.mjs +1 -1
- package/dist/{cron-manager-7Symz_TE.mjs → cron-manager-9bpN9bu4.mjs} +42 -16
- package/dist/cron-manager-9bpN9bu4.mjs.map +1 -0
- package/dist/{cron-manager-BEsH1mjW.d.mts → cron-manager-CSTIBPcM.d.mts} +6 -13
- package/dist/cron-manager-CSTIBPcM.d.mts.map +1 -0
- package/dist/decorate-HgTKAYK8.mjs +16 -0
- package/dist/deep-merge-C8NgcXw4.mjs +18 -0
- package/dist/deep-merge-C8NgcXw4.mjs.map +1 -0
- package/dist/di/index.d.mts +2 -2
- package/dist/di/index.mjs +4 -3
- package/dist/di-BO1QIb5H.mjs +415 -0
- package/dist/di-BO1QIb5H.mjs.map +1 -0
- package/dist/email/index.d.mts +14 -89
- package/dist/email/index.d.mts.map +1 -1
- package/dist/email/index.mjs +30 -125
- package/dist/email/index.mjs.map +1 -1
- package/dist/en-BPP6h6y5.mjs +202 -0
- package/dist/en-BPP6h6y5.mjs.map +1 -0
- package/dist/{env-D1rcZ8_r.d.mts → env-DKSbuBi5.d.mts} +1 -1
- package/dist/env-DKSbuBi5.d.mts.map +1 -0
- package/dist/errors/index.d.mts +2 -2
- package/dist/errors/index.mjs +4 -2
- package/dist/errors-BBZTnjdq.mjs +333 -0
- package/dist/errors-BBZTnjdq.mjs.map +1 -0
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.d.mts.map +1 -1
- package/dist/events/index.mjs +1 -1
- package/dist/{events-COKixqnG.mjs → events-D1KdDaiP.mjs} +13 -11
- package/dist/events-D1KdDaiP.mjs.map +1 -0
- package/dist/exception-context-B4kM-M53.mjs +429 -0
- package/dist/exception-context-B4kM-M53.mjs.map +1 -0
- package/dist/{gateway-context-CdJjpUCW.mjs → gateway-context-CFe6a9gz.mjs} +20 -31
- package/dist/gateway-context-CFe6a9gz.mjs.map +1 -0
- package/dist/guards/index.d.mts +3 -3
- package/dist/guards/index.d.mts.map +1 -1
- package/dist/guards/index.mjs +1 -1
- package/dist/{guards-DUk_Kzst.mjs → guards-Ced-uNIF.mjs} +7 -5
- package/dist/guards-Ced-uNIF.mjs.map +1 -0
- package/dist/{http-method.decorator-DXwxAfb_.mjs → http-method.decorator-CdjKFJZZ.mjs} +7 -6
- package/dist/http-method.decorator-CdjKFJZZ.mjs.map +1 -0
- package/dist/i18n/index.d.mts +238 -3
- package/dist/i18n/index.d.mts.map +1 -0
- package/dist/i18n/index.mjs +39 -3
- package/dist/i18n/index.mjs.map +1 -0
- package/dist/i18n/messages/en/index.d.mts +2 -2
- package/dist/i18n/messages/en/index.mjs +2 -2
- package/dist/i18n/utils/index.d.mts +4 -26
- package/dist/i18n/utils/index.d.mts.map +1 -1
- package/dist/i18n/utils/index.mjs +2 -2
- package/dist/i18n/validation/index.d.mts +3 -2
- package/dist/i18n/validation/index.mjs +4 -2
- package/dist/i18n.module-BlXrtAlV.mjs +219 -0
- package/dist/i18n.module-BlXrtAlV.mjs.map +1 -0
- package/dist/i18n.tokens-hwRpmjRq.mjs +19 -0
- package/dist/i18n.tokens-hwRpmjRq.mjs.map +1 -0
- package/dist/{index-7-hU3GTV.d.mts → index-B4UBK-2T.d.mts} +1 -1
- package/dist/{index-7-hU3GTV.d.mts.map → index-B4UBK-2T.d.mts.map} +1 -1
- package/dist/index-BtlE9RuO.d.mts +124 -0
- package/dist/index-BtlE9RuO.d.mts.map +1 -0
- package/dist/{index-CjaQ6_tZ.d.mts → index-CW1YHSft.d.mts} +71 -167
- package/dist/index-CW1YHSft.d.mts.map +1 -0
- package/dist/{index-D0US0X14.d.mts → index-DEncMcC6.d.mts} +559 -2239
- package/dist/index-DEncMcC6.d.mts.map +1 -0
- package/dist/index-Dj5IMwtr.d.mts +44 -0
- package/dist/index-Dj5IMwtr.d.mts.map +1 -0
- package/dist/{index-C1KvMncZ.d.mts → index-KMgSCSM7.d.mts} +3 -108
- package/dist/index-KMgSCSM7.d.mts.map +1 -0
- package/dist/index.d.mts +5 -43
- package/dist/index.mjs +1 -1
- package/dist/{is-command-C6a7WTPw.mjs → is-command-CX5rAfZW.mjs} +2 -2
- package/dist/{is-command-C6a7WTPw.mjs.map → is-command-CX5rAfZW.mjs.map} +1 -1
- package/dist/{is-seeder-CebjZCDn.mjs → is-seeder-CYCtELlm.mjs} +1 -1
- package/dist/{is-seeder-CebjZCDn.mjs.map → is-seeder-CYCtELlm.mjs.map} +1 -1
- package/dist/logger/index.d.mts +2 -2
- package/dist/logger/index.mjs +170 -2
- package/dist/logger/index.mjs.map +1 -0
- package/dist/macroable/index.d.mts +1 -1
- package/dist/macroable/index.mjs +1 -1
- package/dist/{macroable-BmufBshB.mjs → macroable-DzlfzT50.mjs} +1 -1
- package/dist/{macroable-BmufBshB.mjs.map → macroable-DzlfzT50.mjs.map} +1 -1
- package/dist/metadata-BVkc4aUu.mjs +39 -0
- package/dist/metadata-BVkc4aUu.mjs.map +1 -0
- package/dist/module/index.d.mts +6 -24
- package/dist/module/index.d.mts.map +1 -1
- package/dist/module/index.mjs +2 -2
- package/dist/module-xYoHba6B.mjs +422 -0
- package/dist/module-xYoHba6B.mjs.map +1 -0
- package/dist/openapi/index.d.mts +3 -3
- package/dist/openapi/index.d.mts.map +1 -1
- package/dist/openapi/index.mjs +1 -2
- package/dist/openapi-C6lm0RmV.mjs +483 -0
- package/dist/openapi-C6lm0RmV.mjs.map +1 -0
- package/dist/{openapi.service-BLgvn3hJ.d.mts → openapi.service-CrLlsXAd.d.mts} +3 -3
- package/dist/openapi.service-CrLlsXAd.d.mts.map +1 -0
- package/dist/quarry/index.d.mts +5 -163
- package/dist/quarry/index.d.mts.map +1 -1
- package/dist/quarry/index.mjs +5 -5
- package/dist/quarry/runner.d.mts +184 -0
- package/dist/quarry/runner.d.mts.map +1 -0
- package/dist/quarry/runner.mjs +775 -0
- package/dist/quarry/runner.mjs.map +1 -0
- package/dist/quarry-registry-D4hIGScf.d.mts +69 -0
- package/dist/quarry-registry-D4hIGScf.d.mts.map +1 -0
- package/dist/quarry-registry-DkraZNwn.mjs +311 -0
- package/dist/quarry-registry-DkraZNwn.mjs.map +1 -0
- package/dist/queue/index.d.mts +3 -3
- package/dist/queue/index.mjs +27 -28
- package/dist/queue/index.mjs.map +1 -1
- package/dist/{queue.module-BCdCiySt.mjs → queue.module-DeWJ0tQM.mjs} +67 -112
- package/dist/queue.module-DeWJ0tQM.mjs.map +1 -0
- package/dist/{r2-storage.provider-Co6F0ZYV.mjs → r2-storage.provider-Hfm6LdZQ.mjs} +8 -5
- package/dist/r2-storage.provider-Hfm6LdZQ.mjs.map +1 -0
- package/dist/{rate-limit.decorator--o6Q6p9w.mjs → rate-limit.decorator-D69zdZbp.mjs} +6 -11
- package/dist/rate-limit.decorator-D69zdZbp.mjs.map +1 -0
- package/dist/rate-limiter/index.d.mts +11 -50
- package/dist/rate-limiter/index.d.mts.map +1 -1
- package/dist/rate-limiter/index.mjs +25 -30
- package/dist/rate-limiter/index.mjs.map +1 -1
- package/dist/{resend.provider-M6qRLrcy.mjs → resend.provider-Ur6tU7fK.mjs} +8 -7
- package/dist/resend.provider-Ur6tU7fK.mjs.map +1 -0
- package/dist/router/index.d.mts +2 -2
- package/dist/router/index.mjs +8 -7
- package/dist/{i18n.module-BBlNNlcG.mjs → router-Cy6DjkvP.mjs} +215 -855
- package/dist/router-Cy6DjkvP.mjs.map +1 -0
- package/dist/seeder/index.d.mts +6 -11
- package/dist/seeder/index.d.mts.map +1 -1
- package/dist/seeder/index.mjs +3 -3
- package/dist/{seeder-CJAOHEIo.mjs → seeder-BADTig4n.mjs} +17 -22
- package/dist/seeder-BADTig4n.mjs.map +1 -0
- package/dist/{signed-url-BQPbv2In.mjs → signed-url-BqUqt5dF.mjs} +1 -1
- package/dist/{signed-url-BQPbv2In.mjs.map → signed-url-BqUqt5dF.mjs.map} +1 -1
- package/dist/{smtp.provider-w0Ve52Xg.mjs → smtp.provider-C129sNBT.mjs} +7 -6
- package/dist/smtp.provider-C129sNBT.mjs.map +1 -0
- package/dist/storage/index.d.mts +15 -39
- package/dist/storage/index.d.mts.map +1 -1
- package/dist/storage/index.mjs +3 -3
- package/dist/storage/providers/index.d.mts +2 -2
- package/dist/storage/providers/index.mjs +1 -1
- package/dist/{storage-1zw-6Yiz.mjs → storage-BA3ppVYM.mjs} +70 -59
- package/dist/storage-BA3ppVYM.mjs.map +1 -0
- package/dist/{storage-provider.interface-Bd6vA4ak.d.mts → storage-provider.interface-DQMtT42e.d.mts} +2 -3
- package/dist/storage-provider.interface-DQMtT42e.d.mts.map +1 -0
- package/dist/storage.error-C6FY037a.mjs +8 -0
- package/dist/storage.error-C6FY037a.mjs.map +1 -0
- package/dist/{stratal-DeEcGgdq.mjs → stratal-Bdq4IdB3.mjs} +31 -183
- package/dist/stratal-Bdq4IdB3.mjs.map +1 -0
- package/dist/stratal-BsKmvP6J.d.mts +43 -0
- package/dist/stratal-BsKmvP6J.d.mts.map +1 -0
- package/dist/{types-cySNS_lp.d.mts → types-BaeHi67f.d.mts} +1 -1
- package/dist/types-BaeHi67f.d.mts.map +1 -0
- package/dist/{usage-generator-BUdlhnCK.mjs → usage-generator-DTqaUMR9.mjs} +6 -3
- package/dist/usage-generator-DTqaUMR9.mjs.map +1 -0
- package/dist/validation-DUzcjb8Q.mjs +49 -0
- package/dist/validation-DUzcjb8Q.mjs.map +1 -0
- package/dist/validation.context-XTysWJ3b.mjs +117 -0
- package/dist/validation.context-XTysWJ3b.mjs.map +1 -0
- package/dist/websocket/index.d.mts +7 -14
- package/dist/websocket/index.d.mts.map +1 -1
- package/dist/websocket/index.mjs +2 -2
- package/dist/workers/index.d.mts +2 -2
- package/dist/workers/index.mjs +3 -2
- package/dist/workers/index.mjs.map +1 -1
- package/dist/{index-Bnpfq6uk.d.mts → zod-DvWTfRpI.d.mts} +58 -133
- package/dist/zod-DvWTfRpI.d.mts.map +1 -0
- package/dist/zod-hMa3rSHV.mjs +72 -0
- package/dist/zod-hMa3rSHV.mjs.map +1 -0
- package/package.json +20 -20
- package/dist/command-BgSlsS4M.mjs.map +0 -1
- package/dist/command-Bu-PjJrX.d.mts.map +0 -1
- package/dist/controller.decorator-DQzenvSN.mjs.map +0 -1
- package/dist/cron-manager-7Symz_TE.mjs.map +0 -1
- package/dist/cron-manager-BEsH1mjW.d.mts.map +0 -1
- package/dist/en-DSH_bhh6.mjs +0 -308
- package/dist/en-DSH_bhh6.mjs.map +0 -1
- package/dist/env-D1rcZ8_r.d.mts.map +0 -1
- package/dist/errors-BdyV5PnY.mjs +0 -1725
- package/dist/errors-BdyV5PnY.mjs.map +0 -1
- package/dist/errors-Da3Pz2X7.mjs +0 -74
- package/dist/errors-Da3Pz2X7.mjs.map +0 -1
- package/dist/events-COKixqnG.mjs.map +0 -1
- package/dist/gateway-context-CdJjpUCW.mjs.map +0 -1
- package/dist/guards-DUk_Kzst.mjs.map +0 -1
- package/dist/http-method.decorator-DXwxAfb_.mjs.map +0 -1
- package/dist/i18n.module-BBlNNlcG.mjs.map +0 -1
- package/dist/index-Bnpfq6uk.d.mts.map +0 -1
- package/dist/index-C1KvMncZ.d.mts.map +0 -1
- package/dist/index-CjaQ6_tZ.d.mts.map +0 -1
- package/dist/index-D0US0X14.d.mts.map +0 -1
- package/dist/index-DBd_2wv8.d.mts +0 -263
- package/dist/index-DBd_2wv8.d.mts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/logger-V6Ms3QnQ.mjs +0 -436
- package/dist/logger-V6Ms3QnQ.mjs.map +0 -1
- package/dist/module-Dk2qTa77.mjs +0 -860
- package/dist/module-Dk2qTa77.mjs.map +0 -1
- package/dist/openapi-tools.service-Zs-Ewv7F.mjs +0 -200
- package/dist/openapi-tools.service-Zs-Ewv7F.mjs.map +0 -1
- package/dist/openapi.service-BLgvn3hJ.d.mts.map +0 -1
- package/dist/quarry-registry-DNEej-Db.mjs +0 -688
- package/dist/quarry-registry-DNEej-Db.mjs.map +0 -1
- package/dist/queue.module-BCdCiySt.mjs.map +0 -1
- package/dist/r2-storage.provider-Co6F0ZYV.mjs.map +0 -1
- package/dist/rate-limit.decorator--o6Q6p9w.mjs.map +0 -1
- package/dist/resend.provider-M6qRLrcy.mjs.map +0 -1
- package/dist/seeder-CJAOHEIo.mjs.map +0 -1
- package/dist/setup-CefZKV_e.mjs +0 -37
- package/dist/setup-CefZKV_e.mjs.map +0 -1
- package/dist/smtp.provider-w0Ve52Xg.mjs.map +0 -1
- package/dist/storage-1zw-6Yiz.mjs.map +0 -1
- package/dist/storage-provider.interface-Bd6vA4ak.d.mts.map +0 -1
- package/dist/stratal-DeEcGgdq.mjs.map +0 -1
- package/dist/types-cySNS_lp.d.mts.map +0 -1
- package/dist/usage-generator-BUdlhnCK.mjs.map +0 -1
- package/dist/validation-DtJwAv7O.mjs +0 -248
- package/dist/validation-DtJwAv7O.mjs.map +0 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { a as ApplicationError } from "./container-storage-GpNNz79X.mjs";
|
|
2
|
+
import { c as DI_TOKENS, d as Transient, m as inject, s as CONTAINER_TOKEN } from "./di-BO1QIb5H.mjs";
|
|
3
|
+
import { n as __decorateParam, t as __decorate } from "./decorate-HgTKAYK8.mjs";
|
|
4
|
+
import { LOGGER_TOKENS } from "./logger/index.mjs";
|
|
5
|
+
import "./exception-context-B4kM-M53.mjs";
|
|
6
|
+
//#region src/errors/http-exception.ts
|
|
7
|
+
const HTTP_STATUS_MESSAGES = {
|
|
8
|
+
400: "Bad Request",
|
|
9
|
+
401: "Unauthorized",
|
|
10
|
+
402: "Payment Required",
|
|
11
|
+
403: "Forbidden",
|
|
12
|
+
404: "Not Found",
|
|
13
|
+
409: "Conflict",
|
|
14
|
+
413: "Content Too Large",
|
|
15
|
+
422: "Unprocessable Entity",
|
|
16
|
+
423: "Locked",
|
|
17
|
+
429: "Too Many Requests",
|
|
18
|
+
500: "Internal Server Error",
|
|
19
|
+
502: "Bad Gateway",
|
|
20
|
+
503: "Service Unavailable"
|
|
21
|
+
};
|
|
22
|
+
var HttpException = class extends ApplicationError {
|
|
23
|
+
httpStatus;
|
|
24
|
+
constructor(httpStatus, message, cause) {
|
|
25
|
+
super(message ?? HTTP_STATUS_MESSAGES[httpStatus] ?? "Internal Server Error", cause);
|
|
26
|
+
this.httpStatus = httpStatus;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
function abort(status, message) {
|
|
30
|
+
throw new HttpException(status, message);
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/errors/internal-error.ts
|
|
34
|
+
var InternalError = class extends ApplicationError {
|
|
35
|
+
constructor(cause) {
|
|
36
|
+
super("Internal Server Error", cause);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/errors/is-application-error.ts
|
|
41
|
+
function isApplicationError(error) {
|
|
42
|
+
if (error instanceof ApplicationError) return true;
|
|
43
|
+
return error instanceof Error && typeof error.timestamp === "string";
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/errors/exception-handler.ts
|
|
47
|
+
let ExceptionHandler = class ExceptionHandler {
|
|
48
|
+
logger;
|
|
49
|
+
env;
|
|
50
|
+
container;
|
|
51
|
+
executionContext;
|
|
52
|
+
reportables = [];
|
|
53
|
+
renderables = [];
|
|
54
|
+
dontReportSet = /* @__PURE__ */ new Set();
|
|
55
|
+
levelOverrides = /* @__PURE__ */ new Map();
|
|
56
|
+
contextCallbacks = [];
|
|
57
|
+
respondCallbacks = [];
|
|
58
|
+
errorPages = [];
|
|
59
|
+
environment;
|
|
60
|
+
constructor(logger, env, container, executionContext) {
|
|
61
|
+
this.logger = logger;
|
|
62
|
+
this.env = env;
|
|
63
|
+
this.container = container;
|
|
64
|
+
this.executionContext = executionContext;
|
|
65
|
+
this.environment = this.env.ENVIRONMENT;
|
|
66
|
+
}
|
|
67
|
+
reportable(errorClass, callback) {
|
|
68
|
+
const entry = {
|
|
69
|
+
errorClass,
|
|
70
|
+
callback,
|
|
71
|
+
shouldStop: false
|
|
72
|
+
};
|
|
73
|
+
this.reportables.push(entry);
|
|
74
|
+
return { stop: () => {
|
|
75
|
+
entry.shouldStop = true;
|
|
76
|
+
} };
|
|
77
|
+
}
|
|
78
|
+
renderable(errorClass, callback) {
|
|
79
|
+
this.renderables.push({
|
|
80
|
+
errorClass,
|
|
81
|
+
callback
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
dontReport(errorClasses) {
|
|
85
|
+
for (const cls of errorClasses) this.dontReportSet.add(cls);
|
|
86
|
+
}
|
|
87
|
+
level(errorClass, severity) {
|
|
88
|
+
this.levelOverrides.set(errorClass, severity);
|
|
89
|
+
}
|
|
90
|
+
context(callback) {
|
|
91
|
+
this.contextCallbacks.push(callback);
|
|
92
|
+
}
|
|
93
|
+
respond(callback) {
|
|
94
|
+
this.respondCallbacks.push(callback);
|
|
95
|
+
}
|
|
96
|
+
errorPage(callback) {
|
|
97
|
+
this.errorPages.push(callback);
|
|
98
|
+
}
|
|
99
|
+
resolve(token) {
|
|
100
|
+
return this.container.resolve(token);
|
|
101
|
+
}
|
|
102
|
+
async handle(error, context) {
|
|
103
|
+
const appError = this.normalizeError(error);
|
|
104
|
+
this.executionContext.waitUntil(this.performReport(appError, context));
|
|
105
|
+
const response = await this.performRender(appError, context);
|
|
106
|
+
return this.applyRespondCallbacks(response, appError, context);
|
|
107
|
+
}
|
|
108
|
+
normalizeError(error) {
|
|
109
|
+
if (isApplicationError(error)) return error;
|
|
110
|
+
return new InternalError(error);
|
|
111
|
+
}
|
|
112
|
+
async performReport(error, context) {
|
|
113
|
+
if (this.shouldNotReport(error)) return;
|
|
114
|
+
const entry = this.findReportable(error);
|
|
115
|
+
if (entry) {
|
|
116
|
+
await entry.callback(error, context);
|
|
117
|
+
if (entry.shouldStop) return;
|
|
118
|
+
}
|
|
119
|
+
this.defaultReport(error);
|
|
120
|
+
}
|
|
121
|
+
async performRender(error, context) {
|
|
122
|
+
const entry = this.findRenderable(error);
|
|
123
|
+
if (entry) {
|
|
124
|
+
const result = entry.callback(error, context);
|
|
125
|
+
if (result !== void 0) return this.toResponse(await result, error);
|
|
126
|
+
}
|
|
127
|
+
return await this.defaultRender(error, context);
|
|
128
|
+
}
|
|
129
|
+
applyRespondCallbacks(response, error, context) {
|
|
130
|
+
let result = response;
|
|
131
|
+
for (const callback of this.respondCallbacks) result = callback(result, error, context);
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
shouldNotReport(error) {
|
|
135
|
+
for (const cls of this.dontReportSet) if (error instanceof cls) return true;
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
findReportable(error) {
|
|
139
|
+
let best;
|
|
140
|
+
for (const entry of this.reportables) if (this.matchesErrorClass(error, entry.errorClass)) {
|
|
141
|
+
if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) best = entry;
|
|
142
|
+
}
|
|
143
|
+
return best;
|
|
144
|
+
}
|
|
145
|
+
findRenderable(error) {
|
|
146
|
+
let best;
|
|
147
|
+
for (const entry of this.renderables) if (this.matchesErrorClass(error, entry.errorClass)) {
|
|
148
|
+
if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) best = entry;
|
|
149
|
+
}
|
|
150
|
+
return best;
|
|
151
|
+
}
|
|
152
|
+
matchesErrorClass(error, cls) {
|
|
153
|
+
if (error instanceof cls) return true;
|
|
154
|
+
return error.constructor.name === cls.name;
|
|
155
|
+
}
|
|
156
|
+
defaultReport(error) {
|
|
157
|
+
const severity = this.resolveSeverity(error);
|
|
158
|
+
const globalContext = this.gatherContext();
|
|
159
|
+
const logData = {
|
|
160
|
+
message: error.message,
|
|
161
|
+
timestamp: error.timestamp,
|
|
162
|
+
name: error.name,
|
|
163
|
+
stack: error.stack,
|
|
164
|
+
...globalContext
|
|
165
|
+
};
|
|
166
|
+
const chain = serializeErrorChain(error);
|
|
167
|
+
if (chain) logData.cause = chain;
|
|
168
|
+
switch (severity) {
|
|
169
|
+
case "debug":
|
|
170
|
+
this.logger.debug("[ApplicationError]", logData);
|
|
171
|
+
break;
|
|
172
|
+
case "info":
|
|
173
|
+
this.logger.info("[ApplicationError]", logData);
|
|
174
|
+
break;
|
|
175
|
+
case "warn":
|
|
176
|
+
this.logger.warn("[ApplicationError]", logData);
|
|
177
|
+
break;
|
|
178
|
+
case "error":
|
|
179
|
+
this.logger.error("[ApplicationError]", logData);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async defaultRender(error, context) {
|
|
184
|
+
const status = this.resolveStatus(error);
|
|
185
|
+
const errorResponse = this.buildErrorResponse(error, status);
|
|
186
|
+
if (context.type === "http" && this.wantsHtml(context)) {
|
|
187
|
+
for (const callback of this.errorPages) try {
|
|
188
|
+
const result = await callback(errorResponse, status, context, error);
|
|
189
|
+
if (result !== void 0) return result;
|
|
190
|
+
} catch (callbackError) {
|
|
191
|
+
this.logger.warn("errorPage callback failed, falling back to next handler", { error: callbackError instanceof Error ? callbackError.message : String(callbackError) });
|
|
192
|
+
}
|
|
193
|
+
return this.renderDefaultHtml(errorResponse, status);
|
|
194
|
+
}
|
|
195
|
+
return Response.json(errorResponse, { status });
|
|
196
|
+
}
|
|
197
|
+
wantsHtml(context) {
|
|
198
|
+
return (context.ctx.c.req.header("accept") ?? "").includes("text/html");
|
|
199
|
+
}
|
|
200
|
+
renderDefaultHtml(errorResponse, status) {
|
|
201
|
+
const title = this.escapeHtml(errorResponse.message);
|
|
202
|
+
const html = `<!DOCTYPE html>
|
|
203
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
204
|
+
<title>${status} - ${title}</title>
|
|
205
|
+
<link rel="icon" type="image/x-icon" href="/favicon.svg">
|
|
206
|
+
<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,-apple-system,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f8fafc;color:#334155}.container{text-align:center;padding:2rem}.status{font-size:6rem;font-weight:800;color:#13c397;line-height:1}.message{font-size:1.25rem;color:#64748b;margin-top:1rem}</style>
|
|
207
|
+
</head><body><div class="container"><div class="status">${status}</div><div class="message">${title}</div></div></body></html>`;
|
|
208
|
+
return new Response(html, {
|
|
209
|
+
status,
|
|
210
|
+
headers: { "content-type": "text/html; charset=utf-8" }
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
resolveStatus(error) {
|
|
214
|
+
if (error instanceof HttpException) return error.httpStatus;
|
|
215
|
+
const httpStatus = error.httpStatus;
|
|
216
|
+
if (typeof httpStatus === "number") return httpStatus;
|
|
217
|
+
return 500;
|
|
218
|
+
}
|
|
219
|
+
buildErrorResponse(error, status) {
|
|
220
|
+
const isServerError = status >= 500;
|
|
221
|
+
const isDev = this.environment === "development";
|
|
222
|
+
return {
|
|
223
|
+
message: isServerError && !isDev ? HTTP_STATUS_MESSAGES[status] ?? "Internal Server Error" : error.message,
|
|
224
|
+
timestamp: error.timestamp,
|
|
225
|
+
stack: isDev ? error.stack : void 0
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
escapeHtml(str) {
|
|
229
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
230
|
+
}
|
|
231
|
+
toResponse(result, error) {
|
|
232
|
+
if (result instanceof Response) return result;
|
|
233
|
+
const status = this.resolveStatus(error);
|
|
234
|
+
return Response.json(result, { status });
|
|
235
|
+
}
|
|
236
|
+
resolveSeverity(error) {
|
|
237
|
+
let bestClass;
|
|
238
|
+
let bestSeverity;
|
|
239
|
+
for (const [cls, severity] of this.levelOverrides) if (error instanceof cls) {
|
|
240
|
+
if (!bestClass || cls.prototype instanceof bestClass) {
|
|
241
|
+
bestClass = cls;
|
|
242
|
+
bestSeverity = severity;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (bestSeverity) return bestSeverity;
|
|
246
|
+
const status = this.resolveStatus(error);
|
|
247
|
+
return this.getDefaultSeverity(status);
|
|
248
|
+
}
|
|
249
|
+
getDefaultSeverity(status) {
|
|
250
|
+
if (status >= 500) return "error";
|
|
251
|
+
if (status >= 400) return "warn";
|
|
252
|
+
return "error";
|
|
253
|
+
}
|
|
254
|
+
gatherContext() {
|
|
255
|
+
if (this.contextCallbacks.length === 0) return {};
|
|
256
|
+
const merged = {};
|
|
257
|
+
for (const callback of this.contextCallbacks) Object.assign(merged, callback());
|
|
258
|
+
return merged;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
ExceptionHandler = __decorate([
|
|
262
|
+
Transient(),
|
|
263
|
+
__decorateParam(0, inject(LOGGER_TOKENS.LoggerService)),
|
|
264
|
+
__decorateParam(1, inject(DI_TOKENS.CloudflareEnv)),
|
|
265
|
+
__decorateParam(2, inject(CONTAINER_TOKEN)),
|
|
266
|
+
__decorateParam(3, inject(DI_TOKENS.ExecutionContext))
|
|
267
|
+
], ExceptionHandler);
|
|
268
|
+
const MAX_CAUSE_DEPTH = 5;
|
|
269
|
+
function serializeErrorChain(error) {
|
|
270
|
+
const cause = error.cause;
|
|
271
|
+
const aggregated = error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0;
|
|
272
|
+
if (cause === void 0 && !aggregated) return;
|
|
273
|
+
if (cause !== void 0) return cause instanceof Error ? serializeErrorNode(cause, 0) : { value: cause };
|
|
274
|
+
return {
|
|
275
|
+
name: error.name,
|
|
276
|
+
message: error.message,
|
|
277
|
+
errors: error.errors.map((inner) => inner instanceof Error ? serializeErrorNode(inner, 0) : {
|
|
278
|
+
name: "Unknown",
|
|
279
|
+
message: String(inner)
|
|
280
|
+
})
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function serializeErrorNode(error, depth) {
|
|
284
|
+
const out = {
|
|
285
|
+
name: error.name,
|
|
286
|
+
message: error.message,
|
|
287
|
+
stack: error.stack
|
|
288
|
+
};
|
|
289
|
+
if (depth >= MAX_CAUSE_DEPTH) return out;
|
|
290
|
+
if (error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0) out.errors = error.errors.map((inner) => inner instanceof Error ? serializeErrorNode(inner, depth + 1) : {
|
|
291
|
+
name: "Unknown",
|
|
292
|
+
message: String(inner)
|
|
293
|
+
});
|
|
294
|
+
const cause = error.cause;
|
|
295
|
+
if (cause !== void 0) out.cause = cause instanceof Error ? serializeErrorNode(cause, depth + 1) : { value: cause };
|
|
296
|
+
return out;
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/errors/default-exception-handler.ts
|
|
300
|
+
let DefaultExceptionHandler = class DefaultExceptionHandler extends ExceptionHandler {
|
|
301
|
+
register() {}
|
|
302
|
+
};
|
|
303
|
+
DefaultExceptionHandler = __decorate([Transient()], DefaultExceptionHandler);
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region src/errors/error-response.ts
|
|
306
|
+
function isErrorResponse(obj) {
|
|
307
|
+
return typeof obj === "object" && obj !== null && "message" in obj && typeof obj.message === "string" && "timestamp" in obj && typeof obj.timestamp === "string";
|
|
308
|
+
}
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/errors/stratal-not-initialized.error.ts
|
|
311
|
+
var StratalNotInitializedError = class extends ApplicationError {
|
|
312
|
+
constructor() {
|
|
313
|
+
super("Stratal has not been initialized. Ensure you export a Stratal instance as the default export.");
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/errors/database.error.ts
|
|
318
|
+
var DatabaseError = class extends ApplicationError {
|
|
319
|
+
constructor(message, cause) {
|
|
320
|
+
super(message ?? "Database error", cause);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/errors/auth.error.ts
|
|
325
|
+
var AuthError = class extends ApplicationError {
|
|
326
|
+
constructor(message, cause) {
|
|
327
|
+
super(message ?? "Authentication error", cause);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
//#endregion
|
|
331
|
+
export { DefaultExceptionHandler as a, InternalError as c, abort as d, isErrorResponse as i, HTTP_STATUS_MESSAGES as l, DatabaseError as n, ExceptionHandler as o, StratalNotInitializedError as r, isApplicationError as s, AuthError as t, HttpException as u };
|
|
332
|
+
|
|
333
|
+
//# sourceMappingURL=errors-BBZTnjdq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-BBZTnjdq.mjs","names":[],"sources":["../src/errors/http-exception.ts","../src/errors/internal-error.ts","../src/errors/is-application-error.ts","../src/errors/exception-handler.ts","../src/errors/default-exception-handler.ts","../src/errors/error-response.ts","../src/errors/stratal-not-initialized.error.ts","../src/errors/database.error.ts","../src/errors/auth.error.ts"],"sourcesContent":["import type { ContentfulStatusCode } from 'hono/utils/http-status'\nimport { ApplicationError } from './application-error'\n\nexport const HTTP_STATUS_MESSAGES: Partial<Record<number, string>> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 409: 'Conflict',\n 413: 'Content Too Large',\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n}\n\nexport class HttpException extends ApplicationError {\n public readonly httpStatus: ContentfulStatusCode\n\n constructor(httpStatus: ContentfulStatusCode, message?: string, cause?: unknown) {\n super(message ?? HTTP_STATUS_MESSAGES[httpStatus] ?? 'Internal Server Error', cause)\n this.httpStatus = httpStatus\n }\n}\n\nexport function abort(\n status: ContentfulStatusCode,\n message?: string,\n): never {\n throw new HttpException(status, message)\n}\n","import { ApplicationError } from './application-error'\n\nexport class InternalError extends ApplicationError {\n constructor(cause?: unknown) {\n super('Internal Server Error', cause)\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport function isApplicationError(error: unknown): error is ApplicationError {\n if (error instanceof ApplicationError) return true\n return error instanceof Error\n && typeof (error as ApplicationError).timestamp === 'string'\n}\n","import type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { inject } from '../di';\nimport { CONTAINER_TOKEN, type Container } from '../di';\nimport { Transient } from '../di/decorators';\nimport { DI_TOKENS } from '../di/tokens';\nimport { type StratalEnv } from '../env';\nimport type { StratalExecutionContext } from '../execution-context';\nimport { LOGGER_TOKENS, type LoggerService } from '../logger';\nimport type { ApplicationError } from './application-error';\nimport type { Environment, ErrorResponse } from './error-response';\nimport type { ExceptionContext, HttpExceptionContext } from './exception-context';\nimport type {\n ApplicationErrorConstructor,\n ContextCallback,\n ErrorPageCallback,\n LogSeverity,\n RenderableCallback,\n Reportable,\n ReportableCallback,\n RespondCallback,\n} from './exception-handler.types';\nimport { HTTP_STATUS_MESSAGES, HttpException } from './http-exception';\nimport { InternalError } from './internal-error';\nimport { isApplicationError } from './is-application-error';\n\ninterface ReportableEntry {\n errorClass: ApplicationErrorConstructor\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: ReportableCallback<any>\n shouldStop: boolean\n}\n\ninterface RenderableEntry {\n errorClass: ApplicationErrorConstructor\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: RenderableCallback<any>\n}\n\n@Transient()\nexport abstract class ExceptionHandler {\n private readonly reportables: ReportableEntry[] = []\n private readonly renderables: RenderableEntry[] = []\n private readonly dontReportSet = new Set<ApplicationErrorConstructor>()\n private readonly levelOverrides = new Map<ApplicationErrorConstructor, LogSeverity>()\n private readonly contextCallbacks: ContextCallback[] = []\n private readonly respondCallbacks: RespondCallback[] = []\n private readonly errorPages: ErrorPageCallback[] = []\n private readonly environment: Environment\n\n constructor(\n @inject(LOGGER_TOKENS.LoggerService) protected readonly logger: LoggerService,\n @inject(DI_TOKENS.CloudflareEnv) protected readonly env: StratalEnv,\n @inject(CONTAINER_TOKEN) private readonly container: Container,\n @inject(DI_TOKENS.ExecutionContext) private readonly executionContext: StratalExecutionContext,\n ) {\n this.environment = this.env.ENVIRONMENT as Environment\n }\n\n abstract register(): void\n\n // ── Public Configuration API ──────────────────────────────────────\n\n reportable<T extends ApplicationError>(\n errorClass: ApplicationErrorConstructor<T>,\n callback: ReportableCallback<T>,\n ): Reportable {\n const entry: ReportableEntry = { errorClass, callback, shouldStop: false }\n this.reportables.push(entry)\n return {\n stop: () => { entry.shouldStop = true },\n }\n }\n\n renderable<T extends ApplicationError>(\n errorClass: ApplicationErrorConstructor<T>,\n callback: RenderableCallback<T>,\n ): void {\n this.renderables.push({ errorClass, callback })\n }\n\n dontReport(errorClasses: ApplicationErrorConstructor[]): void {\n for (const cls of errorClasses) {\n this.dontReportSet.add(cls)\n }\n }\n\n level(errorClass: ApplicationErrorConstructor, severity: LogSeverity): void {\n this.levelOverrides.set(errorClass, severity)\n }\n\n context(callback: ContextCallback): void {\n this.contextCallbacks.push(callback)\n }\n\n respond(callback: RespondCallback): void {\n this.respondCallbacks.push(callback)\n }\n\n errorPage(callback: ErrorPageCallback): void {\n this.errorPages.push(callback)\n }\n\n resolve<T>(token: symbol | (new (...args: unknown[]) => T)): T {\n return this.container.resolve<T>(token)\n }\n\n // ── Pipeline Entry Point ──────────────────────────────────────────\n\n async handle(error: unknown, context: ExceptionContext): Promise<Response> {\n const appError = this.normalizeError(error)\n\n this.executionContext.waitUntil(this.performReport(appError, context))\n\n const response = await this.performRender(appError, context)\n\n return this.applyRespondCallbacks(response, appError, context)\n }\n\n // ── Internals ─────────────────────────────────────────────────────\n\n private normalizeError(error: unknown): ApplicationError {\n if (isApplicationError(error)) {\n return error\n }\n\n return new InternalError(error)\n }\n\n private async performReport(error: ApplicationError, context: ExceptionContext): Promise<void> {\n if (this.shouldNotReport(error)) return\n\n const entry = this.findReportable(error)\n if (entry) {\n await entry.callback(error, context)\n if (entry.shouldStop) return\n }\n\n this.defaultReport(error)\n }\n\n private async performRender(error: ApplicationError, context: ExceptionContext): Promise<Response> {\n const entry = this.findRenderable(error)\n if (entry) {\n const result = entry.callback(error, context)\n if (result !== undefined) {\n return this.toResponse(await result, error)\n }\n }\n\n return await this.defaultRender(error, context)\n }\n\n private applyRespondCallbacks(\n response: Response,\n error: ApplicationError,\n context: ExceptionContext,\n ): Response {\n let result = response\n for (const callback of this.respondCallbacks) {\n result = callback(result, error, context)\n }\n return result\n }\n\n private shouldNotReport(error: ApplicationError): boolean {\n for (const cls of this.dontReportSet) {\n if (error instanceof cls) return true\n }\n return false\n }\n\n private findReportable(error: ApplicationError): ReportableEntry | undefined {\n let best: ReportableEntry | undefined\n for (const entry of this.reportables) {\n if (this.matchesErrorClass(error, entry.errorClass)) {\n if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) {\n best = entry\n }\n }\n }\n return best\n }\n\n private findRenderable(error: ApplicationError): RenderableEntry | undefined {\n let best: RenderableEntry | undefined\n for (const entry of this.renderables) {\n if (this.matchesErrorClass(error, entry.errorClass)) {\n if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) {\n best = entry\n }\n }\n }\n return best\n }\n\n private matchesErrorClass(error: ApplicationError, cls: ApplicationErrorConstructor): boolean {\n if (error instanceof cls) return true\n return (error as Error).constructor.name === cls.name\n }\n\n private defaultReport(error: ApplicationError): void {\n const severity = this.resolveSeverity(error)\n const globalContext = this.gatherContext()\n\n const logData: Record<string, unknown> = {\n message: error.message,\n timestamp: error.timestamp,\n name: error.name,\n stack: error.stack,\n ...globalContext,\n }\n\n const chain = serializeErrorChain(error)\n if (chain) {\n logData.cause = chain\n }\n\n switch (severity) {\n case 'debug':\n this.logger.debug('[ApplicationError]', logData)\n break\n case 'info':\n this.logger.info('[ApplicationError]', logData)\n break\n case 'warn':\n this.logger.warn('[ApplicationError]', logData)\n break\n case 'error':\n this.logger.error('[ApplicationError]', logData)\n break\n }\n }\n\n private async defaultRender(error: ApplicationError, context: ExceptionContext): Promise<Response> {\n const status = this.resolveStatus(error)\n const errorResponse = this.buildErrorResponse(error, status)\n\n if (context.type === 'http' && this.wantsHtml(context)) {\n for (const callback of this.errorPages) {\n try {\n const result = await callback(errorResponse, status, context, error)\n if (result !== undefined) return result\n } catch (callbackError) {\n this.logger.warn('errorPage callback failed, falling back to next handler', {\n error: callbackError instanceof Error ? callbackError.message : String(callbackError),\n })\n }\n }\n return this.renderDefaultHtml(errorResponse, status)\n }\n\n return Response.json(errorResponse, { status })\n }\n\n // ── Content Negotiation ──────────────────────────────────────────\n\n protected wantsHtml(context: HttpExceptionContext): boolean {\n const accept = context.ctx.c.req.header('accept') ?? ''\n return accept.includes('text/html')\n }\n\n protected renderDefaultHtml(\n errorResponse: ErrorResponse,\n status: ContentfulStatusCode,\n ): Response {\n const title = this.escapeHtml(errorResponse.message)\n const html = `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${status} - ${title}</title>\n<link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.svg\">\n<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,-apple-system,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f8fafc;color:#334155}.container{text-align:center;padding:2rem}.status{font-size:6rem;font-weight:800;color:#13c397;line-height:1}.message{font-size:1.25rem;color:#64748b;margin-top:1rem}</style>\n</head><body><div class=\"container\"><div class=\"status\">${status}</div><div class=\"message\">${title}</div></div></body></html>`\n return new Response(html, {\n status,\n headers: { 'content-type': 'text/html; charset=utf-8' },\n })\n }\n\n private resolveStatus(error: ApplicationError): ContentfulStatusCode {\n if (error instanceof HttpException) return error.httpStatus\n const httpStatus = (error as { httpStatus?: number }).httpStatus\n if (typeof httpStatus === 'number') return httpStatus as ContentfulStatusCode\n return 500\n }\n\n private buildErrorResponse(error: ApplicationError, status: ContentfulStatusCode): ErrorResponse {\n const isServerError = status >= 500\n const isDev = this.environment === 'development'\n const message = isServerError && !isDev\n ? (HTTP_STATUS_MESSAGES[status] ?? 'Internal Server Error')\n : error.message\n\n return {\n message,\n timestamp: error.timestamp,\n stack: isDev ? error.stack : undefined,\n }\n }\n\n private escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n }\n\n private toResponse(result: Response | ErrorResponse, error: ApplicationError): Response {\n if (result instanceof Response) return result\n const status = this.resolveStatus(error)\n return Response.json(result, { status })\n }\n\n private resolveSeverity(error: ApplicationError): LogSeverity {\n let bestClass: ApplicationErrorConstructor | undefined\n let bestSeverity: LogSeverity | undefined\n\n for (const [cls, severity] of this.levelOverrides) {\n if (error instanceof cls) {\n if (!bestClass || cls.prototype instanceof bestClass) {\n bestClass = cls\n bestSeverity = severity\n }\n }\n }\n\n if (bestSeverity) return bestSeverity\n\n const status = this.resolveStatus(error)\n return this.getDefaultSeverity(status)\n }\n\n private getDefaultSeverity(status: number): LogSeverity {\n if (status >= 500) return 'error'\n if (status >= 400) return 'warn'\n return 'error'\n }\n\n private gatherContext(): Record<string, unknown> {\n if (this.contextCallbacks.length === 0) return {}\n const merged: Record<string, unknown> = {}\n for (const callback of this.contextCallbacks) {\n Object.assign(merged, callback())\n }\n return merged\n }\n}\n\ninterface SerializedErrorNode {\n name: string\n message: string\n stack?: string\n cause?: SerializedErrorNode | { value: unknown }\n errors?: SerializedErrorNode[]\n}\n\nconst MAX_CAUSE_DEPTH = 5\n\nfunction serializeErrorChain(error: Error): SerializedErrorNode | undefined {\n const cause = (error as { cause?: unknown }).cause\n const aggregated = error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0\n if (cause === undefined && !aggregated) {\n return undefined\n }\n if (cause !== undefined) {\n return cause instanceof Error\n ? serializeErrorNode(cause, 0)\n : ({ value: cause } as unknown as SerializedErrorNode)\n }\n return {\n name: error.name,\n message: error.message,\n errors: (error as AggregateError).errors.map((inner) =>\n inner instanceof Error\n ? serializeErrorNode(inner, 0)\n : { name: 'Unknown', message: String(inner) },\n ),\n }\n}\n\nfunction serializeErrorNode(error: Error, depth: number): SerializedErrorNode {\n const out: SerializedErrorNode = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n\n if (depth >= MAX_CAUSE_DEPTH) return out\n\n if (error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0) {\n out.errors = error.errors.map((inner) =>\n inner instanceof Error\n ? serializeErrorNode(inner, depth + 1)\n : { name: 'Unknown', message: String(inner) },\n )\n }\n\n const cause = (error as { cause?: unknown }).cause\n if (cause !== undefined) {\n out.cause = cause instanceof Error\n ? serializeErrorNode(cause, depth + 1)\n : { value: cause }\n }\n\n return out\n}\n","import { Transient } from '../di/decorators';\nimport { ExceptionHandler } from './exception-handler';\n\n/**\n * DefaultExceptionHandler — the built-in exception handler used when no\n * custom handler is provided via `ApplicationConfig.exceptionHandler`.\n *\n * Has an empty `register()` method, so all exceptions flow through the\n * default pipeline: severity-based logging, i18n translation, and JSON\n * error response serialization.\n *\n * To customize exception handling, extend {@link ExceptionHandler} and\n * override `register()`, then pass your class to the Stratal config:\n *\n * @example\n * ```typescript\n * new Stratal({\n * module: AppModule,\n * exceptionHandler: AppExceptionHandler,\n * })\n * ```\n */\n@Transient()\nexport class DefaultExceptionHandler extends ExceptionHandler {\n register(): void {\n // No custom configuration — uses all defaults\n }\n}\n","export type Environment = 'development' | 'staging' | 'production'\n\nexport interface ErrorResponse {\n message: string\n timestamp: string\n stack?: string\n}\n\nexport function isErrorResponse(obj: unknown): obj is ErrorResponse {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'message' in obj &&\n typeof (obj as ErrorResponse).message === 'string' &&\n 'timestamp' in obj &&\n typeof (obj as ErrorResponse).timestamp === 'string'\n )\n}\n","import { ApplicationError } from './application-error'\n\nexport class StratalNotInitializedError extends ApplicationError {\n constructor() {\n super('Stratal has not been initialized. Ensure you export a Stratal instance as the default export.')\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport class DatabaseError extends ApplicationError {\n constructor(message?: string, cause?: unknown) {\n super(message ?? 'Database error', cause)\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport class AuthError extends ApplicationError {\n constructor(message?: string, cause?: unknown) {\n super(message ?? 'Authentication error', cause)\n }\n}\n"],"mappings":"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"}
|
package/dist/events/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as LoggerService } from "../index-BtlE9RuO.mjs";
|
|
2
|
+
import { t as Constructor } from "../types-BaeHi67f.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/events/constants.d.ts
|
|
5
5
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/events/constants.ts","../../src/events/decorators/listener.decorator.ts","../../src/events/types.ts","../../src/events/decorators/on.decorator.ts","../../src/events/event-registry.ts"],"mappings":";;;;;;;;AAMA;;cAAa,sBAAA;EAAA,SAGH,WAAA;EAAA,SAAA,cAAA;AAAA;;;;;;AAHV;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/events/constants.ts","../../src/events/decorators/listener.decorator.ts","../../src/events/types.ts","../../src/events/decorators/on.decorator.ts","../../src/events/event-registry.ts"],"mappings":";;;;;;;;AAMA;;cAAa,sBAAA;EAAA,SAGH,WAAA;EAAA,SAAA,cAAA;AAAA;;;;;;AAHV;;;;;;;;ACgBA;;;;;;iBAAgB,QAAA,CAAA,cACa,WAAA,EAAa,MAAA,EAAQ,CAAA,KAAC,CAAA;;;;iBAUnC,UAAA,CAAW,MAAA,EAAQ,WAAA;;;;;;;AD3BnC;;;;;;;;ACgBA;;;;;;;;;;;;;;;AAWA;;;;;;;;ACSA;;UAAiB,mBAAA;;AAMjB;;;KAAY,SAAA,SAAkB,mBAAA,0BAE1B,OAAA,OAAc,mBAAA;;;;;;;;;;AAkBlB;;;UAAiB,kBAAA;EACf,IAAA,EAAM,KAAA;EACN,QAAA,GAAW,MAAA;AAAA;;;;;AAQb;KAAY,YAAA,WAAuB,SAAA,GAAY,SAAA,IAC7C,CAAA,eAAgB,mBAAA,GACd,mBAAA,CAAoB,CAAA;EAClB,IAAA;EAAgB,MAAA;AAAA;;;;UASL,YAAA;EAVQ;EAYvB,QAAA;EAduB;;;;;;;;EAuBvB,QAAA;AAAA;;AAXF;;KAiBY,YAAA,WAAuB,SAAA,GAAY,SAAA,KAC7C,OAAA,EAAS,YAAA,CAAa,CAAA,MACnB,OAAA;;;AAFL;;UAQiB,iBAAA;EACf,OAAA,EAAS,YAAA;EACT,QAAA;EACA,QAAA;AAAA;;;;UAMe,cAAA;EACf,EAAA,WAAa,SAAA,EACX,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,YAAA,CAAa,CAAA,GACtB,OAAA,GAAU,YAAA;EAGZ,IAAA,WAAe,SAAA,EACb,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,OAAA,CAAQ,YAAA,CAAa,CAAA,KAC9B,OAAA;EAEH,GAAA,WAAc,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA;EAEzD,IAAA,WAAe,SAAA,EACb,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,YAAA,CAAa,CAAA,GACtB,OAAA,GAAU,YAAA;AAAA;;;;UAWG,uBAAA;EACf,UAAA;EACA,KAAA;EACA,OAAA,GAAU,YAAA;AAAA;;;;;;AFrJZ;;;;;;;;ACgBA;;;;;;;;;;iBEGgB,EAAA,WAAa,SAAA,CAAA,CAAW,KAAA,EAAO,CAAA,EAAG,OAAA,GAAU,YAAA,IAExD,MAAA,UACA,WAAA,UACA,WAAA,EAAa,kBAAA;;;;iBAsBD,mBAAA,CAAoB,MAAA,WAAiB,uBAAA;;;cCrCxC,aAAA,YAAyB,cAAA;EAAA,iBAImB,GAAA;EAAA,iBACC,MAAA;EAAA,QAJhD,QAAA;cAG+C,GAAA,EAAK,gBAAA,EACJ,MAAA,EAAQ,aAAA;EAGhE,EAAA,WAAa,SAAA,CAAA,CAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA,GAAI,OAAA,GAAU,YAAA;EAkBhE,IAAA,WAAe,SAAA,CAAA,CACnB,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,OAAA,CAAQ,YAAA,CAAa,CAAA,KAC9B,OAAA;EAmCH,GAAA,WAAc,SAAA,CAAA,CAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA;EAczD,IAAA,WAAe,SAAA,CAAA,CAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA,GAAI,OAAA,GAAU,YAAA;;AHtE1E;;;UGmFU,oBAAA;EHlFwC;;;EAAA,QGuHxC,kBAAA;EHvHS;;;EAAA,QG0IH,cAAA;AAAA"}
|
package/dist/events/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as isListener, i as Listener, n as On, o as LISTENER_METADATA_KEYS, r as getListenerHandlers, t as EventRegistry } from "../events-
|
|
1
|
+
import { a as isListener, i as Listener, n as On, o as LISTENER_METADATA_KEYS, r as getListenerHandlers, t as EventRegistry } from "../events-D1KdDaiP.mjs";
|
|
2
2
|
export { EventRegistry, LISTENER_METADATA_KEYS, Listener, On, getListenerHandlers, isListener };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as DI_TOKENS, d as Transient, m as inject } from "./di-BO1QIb5H.mjs";
|
|
2
|
+
import { n as getMetadata, t as defineMetadata } from "./metadata-BVkc4aUu.mjs";
|
|
3
|
+
import { n as __decorateParam, t as __decorate } from "./decorate-HgTKAYK8.mjs";
|
|
4
|
+
import { LOGGER_TOKENS } from "./logger/index.mjs";
|
|
3
5
|
//#region src/events/constants.ts
|
|
4
6
|
/**
|
|
5
7
|
* Metadata keys for event listener decorators.
|
|
@@ -33,7 +35,7 @@ const LISTENER_METADATA_KEYS = {
|
|
|
33
35
|
function Listener() {
|
|
34
36
|
return function(target) {
|
|
35
37
|
Transient()(target);
|
|
36
|
-
|
|
38
|
+
defineMetadata(LISTENER_METADATA_KEYS.IS_LISTENER, true, target);
|
|
37
39
|
return target;
|
|
38
40
|
};
|
|
39
41
|
}
|
|
@@ -41,7 +43,7 @@ function Listener() {
|
|
|
41
43
|
* Check if a class is decorated with `@Listener()`
|
|
42
44
|
*/
|
|
43
45
|
function isListener(target) {
|
|
44
|
-
return
|
|
46
|
+
return getMetadata(LISTENER_METADATA_KEYS.IS_LISTENER, target) === true;
|
|
45
47
|
}
|
|
46
48
|
//#endregion
|
|
47
49
|
//#region src/events/decorators/on.decorator.ts
|
|
@@ -68,13 +70,13 @@ function isListener(target) {
|
|
|
68
70
|
*/
|
|
69
71
|
function On(event, options) {
|
|
70
72
|
return function(target, propertyKey, _descriptor) {
|
|
71
|
-
const existingHandlers =
|
|
73
|
+
const existingHandlers = getMetadata(LISTENER_METADATA_KEYS.EVENT_HANDLERS, target.constructor) ?? [];
|
|
72
74
|
existingHandlers.push({
|
|
73
75
|
methodName: propertyKey,
|
|
74
76
|
event,
|
|
75
77
|
options
|
|
76
78
|
});
|
|
77
|
-
|
|
79
|
+
defineMetadata(LISTENER_METADATA_KEYS.EVENT_HANDLERS, existingHandlers, target.constructor);
|
|
78
80
|
};
|
|
79
81
|
}
|
|
80
82
|
/**
|
|
@@ -82,12 +84,13 @@ function On(event, options) {
|
|
|
82
84
|
*/
|
|
83
85
|
function getListenerHandlers(target) {
|
|
84
86
|
const metadataTarget = typeof target === "function" ? target : target.constructor;
|
|
85
|
-
return
|
|
87
|
+
return getMetadata(LISTENER_METADATA_KEYS.EVENT_HANDLERS, metadataTarget) ?? [];
|
|
86
88
|
}
|
|
87
89
|
//#endregion
|
|
88
90
|
//#region src/events/event-registry.ts
|
|
89
|
-
var _ref;
|
|
90
91
|
let EventRegistry = class EventRegistry {
|
|
92
|
+
ctx;
|
|
93
|
+
logger;
|
|
91
94
|
handlers = /* @__PURE__ */ new Map();
|
|
92
95
|
constructor(ctx, logger) {
|
|
93
96
|
this.ctx = ctx;
|
|
@@ -181,10 +184,9 @@ let EventRegistry = class EventRegistry {
|
|
|
181
184
|
EventRegistry = __decorate([
|
|
182
185
|
Transient(),
|
|
183
186
|
__decorateParam(0, inject(DI_TOKENS.ExecutionContext)),
|
|
184
|
-
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService))
|
|
185
|
-
__decorateMetadata("design:paramtypes", [typeof (_ref = typeof ExecutionContext !== "undefined" && ExecutionContext) === "function" ? _ref : Object, Object])
|
|
187
|
+
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService))
|
|
186
188
|
], EventRegistry);
|
|
187
189
|
//#endregion
|
|
188
190
|
export { isListener as a, Listener as i, On as n, LISTENER_METADATA_KEYS as o, getListenerHandlers as r, EventRegistry as t };
|
|
189
191
|
|
|
190
|
-
//# sourceMappingURL=events-
|
|
192
|
+
//# sourceMappingURL=events-D1KdDaiP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-D1KdDaiP.mjs","names":[],"sources":["../src/events/constants.ts","../src/events/decorators/listener.decorator.ts","../src/events/decorators/on.decorator.ts","../src/events/event-registry.ts"],"sourcesContent":["/**\n * Metadata keys for event listener decorators.\n *\n * Uses `Symbol.for()` (global symbol registry) so that both core and\n * framework packages can reference the same symbols without cross-imports.\n */\nexport const LISTENER_METADATA_KEYS = {\n IS_LISTENER: Symbol.for('stratal:listener'),\n EVENT_HANDLERS: Symbol.for('stratal:listener:handlers'),\n} as const\n","import { Transient } from '../../di/decorators'\nimport { defineMetadata, getMetadata } from '../../di/metadata'\nimport type { Constructor } from '../../types'\nimport { LISTENER_METADATA_KEYS } from '../constants'\n\n/**\n * Mark a class as an event listener.\n *\n * Applies `@Transient()` for DI and sets metadata so the module system\n * can auto-discover and wire listener handlers at bootstrap time.\n *\n * @example\n * ```typescript\n * @Listener()\n * export class UserCreatedListener {\n * @On('after.User.create')\n * async sendWelcomeEmail(context: EventContext<'after.User.create'>) {\n * // ...\n * }\n * }\n * ```\n */\nexport function Listener() {\n return function <T extends Constructor>(target: T) {\n Transient()(target)\n defineMetadata(LISTENER_METADATA_KEYS.IS_LISTENER, true, target)\n return target\n }\n}\n\n/**\n * Check if a class is decorated with `@Listener()`\n */\nexport function isListener(target: Constructor): boolean {\n return getMetadata(LISTENER_METADATA_KEYS.IS_LISTENER, target) === true\n}\n","import { defineMetadata, getMetadata } from '../../di/metadata'\nimport { LISTENER_METADATA_KEYS } from '../constants'\nimport type { EventName, EventOptions, ListenerHandlerMetadata } from '../types'\n\n/**\n * Register a method as an event handler within a `@Listener()` class.\n *\n * Accumulates handler metadata on the class so the framework can\n * auto-wire handlers with the EventRegistry at bootstrap time.\n *\n * @param event - Event name to listen for (fully typed with autocomplete)\n * @param options - Optional handler options (priority, blocking)\n *\n * @example\n * ```typescript\n * @Listener()\n * export class AuditListener {\n * @On('after.User.create')\n * async logCreate(context: EventContext<'after.User.create'>) { ... }\n *\n * @On('after.User.delete', { priority: 10 })\n * async logDelete(context: EventContext<'after.User.delete'>) { ... }\n * }\n * ```\n */\nexport function On<E extends EventName>(event: E, options?: EventOptions) {\n return function (\n target: object,\n propertyKey: string,\n _descriptor: PropertyDescriptor\n ) {\n const existingHandlers: ListenerHandlerMetadata[] =\n getMetadata<ListenerHandlerMetadata[]>(LISTENER_METADATA_KEYS.EVENT_HANDLERS, target.constructor) ?? []\n\n existingHandlers.push({\n methodName: propertyKey,\n event: event as string,\n options,\n })\n\n defineMetadata(\n LISTENER_METADATA_KEYS.EVENT_HANDLERS,\n existingHandlers,\n target.constructor\n )\n }\n}\n\n/**\n * Get all `@On()` handler metadata from a listener class\n */\nexport function getListenerHandlers(target: object): ListenerHandlerMetadata[] {\n const metadataTarget = typeof target === 'function' ? target : target.constructor\n return getMetadata<ListenerHandlerMetadata[]>(LISTENER_METADATA_KEYS.EVENT_HANDLERS, metadataTarget) ?? []\n}\n","import { inject } from '../di'\nimport { Transient } from '../di/decorators'\nimport { DI_TOKENS } from '../di/tokens'\nimport { LOGGER_TOKENS, type LoggerService } from '../logger'\nimport type {\n EventContext,\n EventHandler,\n EventName,\n EventOptions,\n IEventRegistry,\n RegisteredHandler\n} from './types'\n\n@Transient()\nexport class EventRegistry implements IEventRegistry {\n private handlers = new Map<string, RegisteredHandler[]>()\n\n constructor(\n @inject(DI_TOKENS.ExecutionContext) private readonly ctx: ExecutionContext,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService\n ) { }\n\n on<E extends EventName>(event: E, handler: EventHandler<E>, options?: EventOptions): void {\n const registered: RegisteredHandler = {\n handler: handler as EventHandler,\n priority: options?.priority ?? 0,\n blocking: options?.blocking\n }\n\n const existingHandlers = this.handlers.get(event) ?? []\n existingHandlers.push(registered)\n this.handlers.set(event, existingHandlers)\n\n this.logger.debug('Event handler registered', {\n event,\n priority: registered.priority,\n blocking: registered.blocking\n })\n }\n\n async emit<E extends EventName>(\n event: E,\n context?: Partial<EventContext<E>>\n ): Promise<void> {\n // Build full context with caller-provided fields\n const fullContext = {\n ...context\n } as EventContext<E>\n\n // Find matching handlers using pattern matching\n const matchingHandlers = this.findMatchingHandlers(event)\n\n if (matchingHandlers.length === 0) {\n return\n }\n\n // Sort by priority (higher first)\n const sortedHandlers = [...matchingHandlers].sort(\n (a, b) => b.priority - a.priority\n )\n\n // Determine if we should use waitUntil\n const shouldUseWaitUntil = this.shouldUseWaitUntil(event, sortedHandlers)\n\n // Execute handlers\n const promises = sortedHandlers.map((registered) =>\n this.executeHandler(registered.handler, fullContext, event)\n )\n\n if (shouldUseWaitUntil) {\n // Non-blocking: use ctx.waitUntil\n this.ctx.waitUntil(Promise.all(promises))\n } else {\n // Blocking: await all handlers\n await Promise.all(promises)\n }\n }\n\n off<E extends EventName>(event: E, handler: EventHandler<E>): void {\n const existingHandlers = this.handlers.get(event)\n if (!existingHandlers) return\n\n const filtered = existingHandlers.filter((h) => h.handler !== handler)\n if (filtered.length > 0) {\n this.handlers.set(event, filtered)\n } else {\n this.handlers.delete(event)\n }\n\n this.logger.debug('Event handler unregistered', { event })\n }\n\n once<E extends EventName>(event: E, handler: EventHandler<E>, options?: EventOptions): void {\n const wrappedHandler = (async (context: EventContext<E>) => {\n await handler(context)\n this.off(event, wrappedHandler)\n }) as EventHandler<E>\n\n this.on(event, wrappedHandler, options)\n }\n\n /**\n * Find all handlers matching the event using pattern matching.\n * Order: exact match -> model wildcard -> operation wildcard -> global wildcard\n */\n private findMatchingHandlers(event: string): RegisteredHandler[] {\n const handlers: RegisteredHandler[] = []\n\n const parts = event.split('.')\n\n if (parts.length === 3) {\n // Database event: \"phase.model.operation\"\n const [phase, model, operation] = parts\n\n // 1. Exact match: \"after.user.create\"\n handlers.push(...(this.handlers.get(event) ?? []))\n\n // 2. Model wildcard: \"after.user\"\n handlers.push(...(this.handlers.get(`${phase}.${model}`) ?? []))\n\n // 3. Operation wildcard: \"after.create\"\n handlers.push(...(this.handlers.get(`${phase}.${operation}`) ?? []))\n\n // 4. Global wildcard: \"after\"\n handlers.push(...(this.handlers.get(phase) ?? []))\n } else if (parts.length === 2) {\n // Could be wildcard like \"after.user\" or custom event like \"auth.verified\"\n handlers.push(...(this.handlers.get(event) ?? []))\n\n if (parts[0] === 'before' || parts[0] === 'after') {\n handlers.push(...(this.handlers.get(parts[0]) ?? []))\n }\n } else {\n handlers.push(...(this.handlers.get(event) ?? []))\n }\n\n return handlers\n }\n\n /**\n * Determine if we should use ctx.waitUntil (non-blocking) or await (blocking)\n */\n private shouldUseWaitUntil(\n event: string,\n handlers: RegisteredHandler[]\n ): boolean {\n const hasBlockingHandler = handlers.some((h) => h.blocking === true)\n if (hasBlockingHandler) return false\n\n const hasNonBlockingHandler = handlers.some((h) => h.blocking === false)\n if (hasNonBlockingHandler) return true\n\n const phase = event.split('.')[0]\n if (phase === 'before') return false\n if (phase === 'after') return true\n return false // Custom events block by default\n }\n\n /**\n * Execute a single handler with error isolation\n */\n private async executeHandler<E extends EventName>(\n handler: EventHandler,\n context: EventContext<E>,\n event: string\n ): Promise<void> {\n try {\n await handler(context as EventContext)\n } catch (error) {\n this.logger.error('Event handler error', {\n event,\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n })\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAMA,MAAa,yBAAyB;CACpC,aAAa,OAAO,IAAI,mBAAmB;CAC3C,gBAAgB,OAAO,IAAI,4BAA4B;CACxD;;;;;;;;;;;;;;;;;;;;ACaD,SAAgB,WAAW;CACzB,OAAO,SAAiC,QAAW;EACjD,WAAW,CAAC,OAAO;EACnB,eAAe,uBAAuB,aAAa,MAAM,OAAO;EAChE,OAAO;;;;;;AAOX,SAAgB,WAAW,QAA8B;CACvD,OAAO,YAAY,uBAAuB,aAAa,OAAO,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;ACTrE,SAAgB,GAAwB,OAAU,SAAwB;CACxE,OAAO,SACL,QACA,aACA,aACA;EACA,MAAM,mBACJ,YAAuC,uBAAuB,gBAAgB,OAAO,YAAY,IAAI,EAAE;EAEzG,iBAAiB,KAAK;GACpB,YAAY;GACL;GACP;GACD,CAAC;EAEF,eACE,uBAAuB,gBACvB,kBACA,OAAO,YACR;;;;;;AAOL,SAAgB,oBAAoB,QAA2C;CAC7E,MAAM,iBAAiB,OAAO,WAAW,aAAa,SAAS,OAAO;CACtE,OAAO,YAAuC,uBAAuB,gBAAgB,eAAe,IAAI,EAAE;;;;ACvCrG,IAAA,gBAAA,MAAM,cAAwC;CAII;CACC;CAJxD,2BAAmB,IAAI,KAAkC;CAEzD,YACE,KACA,QACA;EAFqD,KAAA,MAAA;EACC,KAAA,SAAA;;CAGxD,GAAwB,OAAU,SAA0B,SAA8B;EACxF,MAAM,aAAgC;GAC3B;GACT,UAAU,SAAS,YAAY;GAC/B,UAAU,SAAS;GACpB;EAED,MAAM,mBAAmB,KAAK,SAAS,IAAI,MAAM,IAAI,EAAE;EACvD,iBAAiB,KAAK,WAAW;EACjC,KAAK,SAAS,IAAI,OAAO,iBAAiB;EAE1C,KAAK,OAAO,MAAM,4BAA4B;GAC5C;GACA,UAAU,WAAW;GACrB,UAAU,WAAW;GACtB,CAAC;;CAGJ,MAAM,KACJ,OACA,SACe;EAEf,MAAM,cAAc,EAClB,GAAG,SACJ;EAGD,MAAM,mBAAmB,KAAK,qBAAqB,MAAM;EAEzD,IAAI,iBAAiB,WAAW,GAC9B;EAIF,MAAM,iBAAiB,CAAC,GAAG,iBAAiB,CAAC,MAC1C,GAAG,MAAM,EAAE,WAAW,EAAE,SAC1B;EAGD,MAAM,qBAAqB,KAAK,mBAAmB,OAAO,eAAe;EAGzE,MAAM,WAAW,eAAe,KAAK,eACnC,KAAK,eAAe,WAAW,SAAS,aAAa,MAAM,CAC5D;EAED,IAAI,oBAEF,KAAK,IAAI,UAAU,QAAQ,IAAI,SAAS,CAAC;OAGzC,MAAM,QAAQ,IAAI,SAAS;;CAI/B,IAAyB,OAAU,SAAgC;EACjE,MAAM,mBAAmB,KAAK,SAAS,IAAI,MAAM;EACjD,IAAI,CAAC,kBAAkB;EAEvB,MAAM,WAAW,iBAAiB,QAAQ,MAAM,EAAE,YAAY,QAAQ;EACtE,IAAI,SAAS,SAAS,GACpB,KAAK,SAAS,IAAI,OAAO,SAAS;OAElC,KAAK,SAAS,OAAO,MAAM;EAG7B,KAAK,OAAO,MAAM,8BAA8B,EAAE,OAAO,CAAC;;CAG5D,KAA0B,OAAU,SAA0B,SAA8B;EAC1F,MAAM,kBAAkB,OAAO,YAA6B;GAC1D,MAAM,QAAQ,QAAQ;GACtB,KAAK,IAAI,OAAO,eAAe;;EAGjC,KAAK,GAAG,OAAO,gBAAgB,QAAQ;;;;;;CAOzC,qBAA6B,OAAoC;EAC/D,MAAM,WAAgC,EAAE;EAExC,MAAM,QAAQ,MAAM,MAAM,IAAI;EAE9B,IAAI,MAAM,WAAW,GAAG;GAEtB,MAAM,CAAC,OAAO,OAAO,aAAa;GAGlC,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,MAAM,IAAI,EAAE,CAAE;GAGlD,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,GAAG,MAAM,GAAG,QAAQ,IAAI,EAAE,CAAE;GAGhE,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,GAAG,MAAM,GAAG,YAAY,IAAI,EAAE,CAAE;GAGpE,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,MAAM,IAAI,EAAE,CAAE;SAC7C,IAAI,MAAM,WAAW,GAAG;GAE7B,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,MAAM,IAAI,EAAE,CAAE;GAElD,IAAI,MAAM,OAAO,YAAY,MAAM,OAAO,SACxC,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,MAAM,GAAG,IAAI,EAAE,CAAE;SAGvD,SAAS,KAAK,GAAI,KAAK,SAAS,IAAI,MAAM,IAAI,EAAE,CAAE;EAGpD,OAAO;;;;;CAMT,mBACE,OACA,UACS;EAET,IAD2B,SAAS,MAAM,MAAM,EAAE,aAAa,KACzC,EAAE,OAAO;EAG/B,IAD8B,SAAS,MAAM,MAAM,EAAE,aAAa,MACzC,EAAE,OAAO;EAElC,MAAM,QAAQ,MAAM,MAAM,IAAI,CAAC;EAC/B,IAAI,UAAU,UAAU,OAAO;EAC/B,IAAI,UAAU,SAAS,OAAO;EAC9B,OAAO;;;;;CAMT,MAAc,eACZ,SACA,SACA,OACe;EACf,IAAI;GACF,MAAM,QAAQ,QAAwB;WAC/B,OAAO;GACd,KAAK,OAAO,MAAM,uBAAuB;IACvC;IACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAC7D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ,KAAA;IAC/C,CAAC;;;;;CAhKP,WAAW;oBAKP,OAAO,UAAU,iBAAiB,CAAA;oBAClC,OAAO,cAAc,cAAc,CAAA"}
|