stratal 0.0.18 → 0.0.19
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 +8 -8
- package/dist/{base-email.provider-Cuw4OAB0.mjs → base-email.provider-mjynzewK.mjs} +1 -1
- package/dist/{base-email.provider-Cuw4OAB0.mjs.map → base-email.provider-mjynzewK.mjs.map} +1 -1
- package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
- package/dist/bin/quarry.mjs +21 -36
- package/dist/bin/quarry.mjs.map +1 -1
- package/dist/cache/index.d.mts +3 -2
- package/dist/cache/index.d.mts.map +1 -1
- package/dist/cache/index.mjs +3 -3
- package/dist/{colors-BTAnQRGU.mjs → colors-DJaRDXoS.mjs} +1 -1
- package/dist/{colors-BTAnQRGU.mjs.map → colors-DJaRDXoS.mjs.map} +1 -1
- package/dist/{command-DjGqCYHv.mjs → command-BgSlsS4M.mjs} +2 -2
- package/dist/{command-DjGqCYHv.mjs.map → command-BgSlsS4M.mjs.map} +1 -1
- package/dist/{command-B1YuV-UZ.d.mts → command-DsQq56Lp.d.mts} +2 -2
- package/dist/{command-B1YuV-UZ.d.mts.map → command-DsQq56Lp.d.mts.map} +1 -1
- package/dist/config/index.d.mts +81 -37
- package/dist/config/index.d.mts.map +1 -1
- package/dist/config/index.mjs +126 -45
- package/dist/config/index.mjs.map +1 -1
- package/dist/{consumer-registry-BkuHXR_u.d.mts → consumer-registry-Doom7BEh.d.mts} +1 -1
- package/dist/{consumer-registry-BkuHXR_u.d.mts.map → consumer-registry-Doom7BEh.d.mts.map} +1 -1
- package/dist/controller.decorator-LZY9aHYG.mjs +66 -0
- package/dist/controller.decorator-LZY9aHYG.mjs.map +1 -0
- package/dist/cron/index.d.mts +4 -3
- package/dist/cron/index.d.mts.map +1 -1
- package/dist/cron/index.mjs +1 -1
- package/dist/{cron-manager-1KnZvojs.mjs → cron-manager-C30t9UZM.mjs} +29 -19
- package/dist/cron-manager-C30t9UZM.mjs.map +1 -0
- package/dist/{cron-manager-BnEZquBL.d.mts → cron-manager-RuPtFVLy.d.mts} +27 -13
- package/dist/cron-manager-RuPtFVLy.d.mts.map +1 -0
- package/dist/di/index.d.mts +1 -1
- package/dist/di/index.mjs +2 -2
- package/dist/email/index.d.mts +3 -3
- package/dist/email/index.mjs +87 -10
- package/dist/email/index.mjs.map +1 -1
- package/dist/{en-3QnZwP-u.mjs → en-rHmW6vD9.mjs} +5 -31
- package/dist/en-rHmW6vD9.mjs.map +1 -0
- package/dist/env-CamWD-U1.d.mts +25 -0
- package/dist/env-CamWD-U1.d.mts.map +1 -0
- package/dist/errors/index.d.mts +1 -1
- package/dist/errors/index.mjs +1 -1
- package/dist/{errors--RBIvDXr.mjs → errors-B4pYgYON.mjs} +161 -7
- package/dist/errors-B4pYgYON.mjs.map +1 -0
- package/dist/{errors-B7hCnXgB.mjs → errors-BUyUfr2Z.mjs} +14 -7
- package/dist/errors-BUyUfr2Z.mjs.map +1 -0
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.mjs +1 -1
- package/dist/{events-UTJliZhl.mjs → events-COKixqnG.mjs} +2 -2
- package/dist/{events-UTJliZhl.mjs.map → events-COKixqnG.mjs.map} +1 -1
- package/dist/{gateway-context-BdBFoQd8.mjs → gateway-context-cqZ8wMoi.mjs} +4 -65
- package/dist/gateway-context-cqZ8wMoi.mjs.map +1 -0
- package/dist/guards/index.d.mts +14 -5
- package/dist/guards/index.d.mts.map +1 -1
- package/dist/guards/index.mjs +1 -1
- package/dist/{guards-MtDgcHnF.mjs → guards-DMbsAxSX.mjs} +1 -1
- package/dist/guards-DMbsAxSX.mjs.map +1 -0
- package/dist/http-method.decorator-BT3ufnz8.mjs +96 -0
- package/dist/http-method.decorator-BT3ufnz8.mjs.map +1 -0
- package/dist/i18n/index.d.mts +3 -3
- package/dist/i18n/index.mjs +2 -2
- package/dist/i18n/messages/en/index.d.mts +1 -1
- package/dist/i18n/messages/en/index.mjs +1 -1
- package/dist/i18n/utils/index.mjs +1 -1
- package/dist/i18n/validation/index.d.mts +1 -1
- package/dist/i18n/validation/index.mjs +1 -1
- package/dist/{i18n.module-BpLLLCTg.mjs → i18n.module-CI_prYFD.mjs} +74 -196
- package/dist/i18n.module-CI_prYFD.mjs.map +1 -0
- package/dist/{index-Dfpd_ypO.d.mts → index-B437eK7p.d.mts} +26 -12
- package/dist/index-B437eK7p.d.mts.map +1 -0
- package/dist/{index-BR23zDMy.d.mts → index-CWRS7Ri3.d.mts} +1 -1
- package/dist/{index-BR23zDMy.d.mts.map → index-CWRS7Ri3.d.mts.map} +1 -1
- package/dist/{index-BDh9J2KD.d.mts → index-DFhEeFfC.d.mts} +4 -30
- package/dist/{index-BDh9J2KD.d.mts.map → index-DFhEeFfC.d.mts.map} +1 -1
- package/dist/{index-BrmS34sa.d.mts → index-DPFqRs8L.d.mts} +70 -39
- package/dist/index-DPFqRs8L.d.mts.map +1 -0
- package/dist/{index-DPxmo6AY.d.mts → index-Dnqm9ZB6.d.mts} +5 -4
- package/dist/index-Dnqm9ZB6.d.mts.map +1 -0
- package/dist/index-SHx31sBJ.d.mts +101 -0
- package/dist/index-SHx31sBJ.d.mts.map +1 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{is-command-PvULqiTa.mjs → is-command-C6a7WTPw.mjs} +2 -2
- package/dist/{is-command-PvULqiTa.mjs.map → is-command-C6a7WTPw.mjs.map} +1 -1
- package/dist/{is-seeder-BN9Ej1r7.mjs → is-seeder-CebjZCDn.mjs} +1 -1
- package/dist/{is-seeder-BN9Ej1r7.mjs.map → is-seeder-CebjZCDn.mjs.map} +1 -1
- package/dist/logger/index.d.mts +1 -1
- package/dist/logger/index.mjs +1 -1
- package/dist/{logger-c0ftIK4G.mjs → logger-V6Ms3QnQ.mjs} +38 -20
- package/dist/{logger-c0ftIK4G.mjs.map → logger-V6Ms3QnQ.mjs.map} +1 -1
- package/dist/macroable/index.d.mts +2 -0
- package/dist/macroable/index.mjs +2 -0
- package/dist/macroable-BmufBshB.mjs +122 -0
- package/dist/macroable-BmufBshB.mjs.map +1 -0
- package/dist/module/index.d.mts +2 -2
- package/dist/module/index.mjs +1 -1
- package/dist/{module-C3YZ-kZN.mjs → module-qGE_1duv.mjs} +31 -18
- package/dist/module-qGE_1duv.mjs.map +1 -0
- package/dist/openapi/index.d.mts +3 -3
- package/dist/openapi/index.mjs +2 -2
- package/dist/{openapi-tools.service-B77QXD56.mjs → openapi-tools.service-CYWGuhue.mjs} +4 -1
- package/dist/{openapi-tools.service-B77QXD56.mjs.map → openapi-tools.service-CYWGuhue.mjs.map} +1 -1
- package/dist/{openapi.service-6yj0BUY4.d.mts → openapi.service-Bv_NioM9.d.mts} +3 -3
- package/dist/{openapi.service-6yj0BUY4.d.mts.map → openapi.service-Bv_NioM9.d.mts.map} +1 -1
- package/dist/quarry/index.d.mts +7 -7
- package/dist/quarry/index.d.mts.map +1 -1
- package/dist/quarry/index.mjs +4 -4
- package/dist/{quarry-registry-CQCIlYTO.mjs → quarry-registry-DFfRRkA7.mjs} +17 -15
- package/dist/quarry-registry-DFfRRkA7.mjs.map +1 -0
- package/dist/queue/index.d.mts +2 -2
- package/dist/queue/index.mjs +2 -2
- package/dist/{queue.module-DIjD6nr-.mjs → queue.module-P-G-nCYz.mjs} +4 -4
- package/dist/{queue.module-DIjD6nr-.mjs.map → queue.module-P-G-nCYz.mjs.map} +1 -1
- package/dist/r2-storage.provider-LdzK9tfG.mjs +244 -0
- package/dist/r2-storage.provider-LdzK9tfG.mjs.map +1 -0
- package/dist/{resend.provider-Bvw36rQy.mjs → resend.provider-bwILp0WI.mjs} +2 -2
- package/dist/{resend.provider-Bvw36rQy.mjs.map → resend.provider-bwILp0WI.mjs.map} +1 -1
- package/dist/router/index.d.mts +2 -2
- package/dist/router/index.mjs +7 -5
- package/dist/seeder/index.d.mts +3 -3
- package/dist/seeder/index.mjs +2 -2
- package/dist/{seeder-D7VXULXB.mjs → seeder-BcqIFa2X.mjs} +5 -5
- package/dist/{seeder-D7VXULXB.mjs.map → seeder-BcqIFa2X.mjs.map} +1 -1
- package/dist/{setup-BRIN-iYT.mjs → setup-CtekcwuO.mjs} +1 -1
- package/dist/{setup-BRIN-iYT.mjs.map → setup-CtekcwuO.mjs.map} +1 -1
- package/dist/signed-url-COX7cCWR.mjs +74 -0
- package/dist/signed-url-COX7cCWR.mjs.map +1 -0
- package/dist/{smtp.provider-CAwpvzvD.mjs → smtp.provider-B07yuARi.mjs} +2 -2
- package/dist/{smtp.provider-CAwpvzvD.mjs.map → smtp.provider-B07yuARi.mjs.map} +1 -1
- package/dist/storage/index.d.mts +39 -17
- package/dist/storage/index.d.mts.map +1 -1
- package/dist/storage/index.mjs +3 -3
- package/dist/storage/providers/index.d.mts +30 -70
- package/dist/storage/providers/index.d.mts.map +1 -1
- package/dist/storage/providers/index.mjs +2 -2
- package/dist/{storage-CJ-QOwNv.mjs → storage-P6X4h9So.mjs} +101 -27
- package/dist/storage-P6X4h9So.mjs.map +1 -0
- package/dist/{storage-provider.interface-YRtyYBxV.d.mts → storage-provider.interface-CC1nniHk.d.mts} +20 -21
- package/dist/storage-provider.interface-CC1nniHk.d.mts.map +1 -0
- package/dist/{stratal-B7G4i9-N.mjs → stratal-BCiwCFN9.mjs} +57 -26
- package/dist/stratal-BCiwCFN9.mjs.map +1 -0
- package/dist/{types-CN0zONAZ.d.mts → types-DIWemRad.d.mts} +1 -1
- package/dist/types-DIWemRad.d.mts.map +1 -0
- package/dist/{usage-generator-Cl1HPlUp.mjs → usage-generator-MBcRo0Q2.mjs} +2 -2
- package/dist/{usage-generator-Cl1HPlUp.mjs.map → usage-generator-MBcRo0Q2.mjs.map} +1 -1
- package/dist/{validation-B4bePOa_.mjs → validation-Dbg3ehdP.mjs} +1 -1
- package/dist/{validation-B4bePOa_.mjs.map → validation-Dbg3ehdP.mjs.map} +1 -1
- package/dist/websocket/index.d.mts +3 -3
- package/dist/websocket/index.mjs +1 -1
- package/dist/workers/index.d.mts +2 -1
- package/dist/workers/index.d.mts.map +1 -1
- package/dist/workers/index.mjs +2 -2
- package/package.json +27 -39
- package/dist/cron-manager-1KnZvojs.mjs.map +0 -1
- package/dist/cron-manager-BnEZquBL.d.mts.map +0 -1
- package/dist/en-3QnZwP-u.mjs.map +0 -1
- package/dist/errors--RBIvDXr.mjs.map +0 -1
- package/dist/errors-B7hCnXgB.mjs.map +0 -1
- package/dist/gateway-context-BdBFoQd8.mjs.map +0 -1
- package/dist/guards-MtDgcHnF.mjs.map +0 -1
- package/dist/i18n.module-BpLLLCTg.mjs.map +0 -1
- package/dist/index-BrmS34sa.d.mts.map +0 -1
- package/dist/index-DPxmo6AY.d.mts.map +0 -1
- package/dist/index-Dfpd_ypO.d.mts.map +0 -1
- package/dist/module-C3YZ-kZN.mjs.map +0 -1
- package/dist/quarry-registry-CQCIlYTO.mjs.map +0 -1
- package/dist/s3-storage.provider-BAhHDMI3.mjs +0 -343
- package/dist/s3-storage.provider-BAhHDMI3.mjs.map +0 -1
- package/dist/storage-CJ-QOwNv.mjs.map +0 -1
- package/dist/storage-provider.interface-YRtyYBxV.d.mts.map +0 -1
- package/dist/stratal-B7G4i9-N.mjs.map +0 -1
- package/dist/types-CN0zONAZ.d.mts.map +0 -1
|
@@ -141,6 +141,9 @@ const DI_TOKENS = {
|
|
|
141
141
|
Cron: Symbol.for("stratal:cron:manager"),
|
|
142
142
|
EventRegistry: Symbol.for("stratal:event:registry"),
|
|
143
143
|
Quarry: Symbol.for("stratal:quarry"),
|
|
144
|
+
/**
|
|
145
|
+
* AuthContext: Use for services that need user authentication (userId).
|
|
146
|
+
*/
|
|
144
147
|
AuthContext: Symbol.for("stratal:auth:context"),
|
|
145
148
|
DurableObjectState: Symbol.for("stratal:durable:object:state"),
|
|
146
149
|
DurableObjectId: Symbol.for("stratal:durable:object:id")
|
|
@@ -154,10 +157,25 @@ const DI_TOKENS = {
|
|
|
154
157
|
* and prevent naming collisions.
|
|
155
158
|
*/
|
|
156
159
|
const LOGGER_TOKENS = {
|
|
160
|
+
/**
|
|
161
|
+
* Main logger service facade
|
|
162
|
+
*/
|
|
157
163
|
LoggerService: Symbol.for("stratal:logger:service"),
|
|
164
|
+
/**
|
|
165
|
+
* Log formatter (JSON or Pretty)
|
|
166
|
+
*/
|
|
158
167
|
Formatter: Symbol.for("stratal:logger:formatter"),
|
|
168
|
+
/**
|
|
169
|
+
* Array of active transports
|
|
170
|
+
*/
|
|
159
171
|
Transports: Symbol.for("stratal:logger:transports"),
|
|
172
|
+
/**
|
|
173
|
+
* Individual transport tokens (for factory registration)
|
|
174
|
+
*/
|
|
160
175
|
ConsoleTransport: Symbol.for("stratal:logger:console:transport"),
|
|
176
|
+
/**
|
|
177
|
+
* Configured log level for filtering
|
|
178
|
+
*/
|
|
161
179
|
LogLevelOptions: Symbol.for("stratal:logger:log:level:options")
|
|
162
180
|
};
|
|
163
181
|
//#endregion
|
|
@@ -178,25 +196,25 @@ let LogLevel = /* @__PURE__ */ function(LogLevel) {
|
|
|
178
196
|
* Higher numbers = more severe = higher priority
|
|
179
197
|
*/
|
|
180
198
|
const LOG_LEVEL_PRIORITY = {
|
|
181
|
-
[
|
|
182
|
-
[
|
|
183
|
-
[
|
|
184
|
-
[
|
|
199
|
+
["debug"]: 0,
|
|
200
|
+
["info"]: 1,
|
|
201
|
+
["warn"]: 2,
|
|
202
|
+
["error"]: 3
|
|
185
203
|
};
|
|
186
204
|
//#endregion
|
|
187
|
-
//#region \0@oxc-project+runtime@0.
|
|
205
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorateMetadata.js
|
|
188
206
|
function __decorateMetadata(k, v) {
|
|
189
207
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
190
208
|
}
|
|
191
209
|
//#endregion
|
|
192
|
-
//#region \0@oxc-project+runtime@0.
|
|
210
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorateParam.js
|
|
193
211
|
function __decorateParam(paramIndex, decorator) {
|
|
194
212
|
return function(target, key) {
|
|
195
213
|
decorator(target, key, paramIndex);
|
|
196
214
|
};
|
|
197
215
|
}
|
|
198
216
|
//#endregion
|
|
199
|
-
//#region \0@oxc-project+runtime@0.
|
|
217
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
|
|
200
218
|
function __decorate(decorators, target, key, desc) {
|
|
201
219
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
202
220
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -217,19 +235,19 @@ let LoggerService = class LoggerService {
|
|
|
217
235
|
* Log debug message (development only)
|
|
218
236
|
*/
|
|
219
237
|
debug(message, context) {
|
|
220
|
-
this.log(
|
|
238
|
+
this.log("debug", message, context);
|
|
221
239
|
}
|
|
222
240
|
/**
|
|
223
241
|
* Log info message
|
|
224
242
|
*/
|
|
225
243
|
info(message, context) {
|
|
226
|
-
this.log(
|
|
244
|
+
this.log("info", message, context);
|
|
227
245
|
}
|
|
228
246
|
/**
|
|
229
247
|
* Log warning message
|
|
230
248
|
*/
|
|
231
249
|
warn(message, context) {
|
|
232
|
-
this.log(
|
|
250
|
+
this.log("warn", message, context);
|
|
233
251
|
}
|
|
234
252
|
/**
|
|
235
253
|
* Log error message
|
|
@@ -240,7 +258,7 @@ let LoggerService = class LoggerService {
|
|
|
240
258
|
let error;
|
|
241
259
|
if (contextOrError instanceof Error) error = contextOrError;
|
|
242
260
|
else context = contextOrError;
|
|
243
|
-
this.log(
|
|
261
|
+
this.log("error", message, context, error);
|
|
244
262
|
}
|
|
245
263
|
/**
|
|
246
264
|
* Core logging implementation
|
|
@@ -342,10 +360,10 @@ var JsonFormatter = class {
|
|
|
342
360
|
*/
|
|
343
361
|
var PrettyFormatter = class {
|
|
344
362
|
colors = {
|
|
345
|
-
[
|
|
346
|
-
[
|
|
347
|
-
[
|
|
348
|
-
[
|
|
363
|
+
["debug"]: "\x1B[36m",
|
|
364
|
+
["info"]: "\x1B[32m",
|
|
365
|
+
["warn"]: "\x1B[33m",
|
|
366
|
+
["error"]: "\x1B[31m"
|
|
349
367
|
};
|
|
350
368
|
reset = "\x1B[0m";
|
|
351
369
|
format(entry) {
|
|
@@ -403,10 +421,10 @@ let ConsoleTransport = class ConsoleTransport extends BaseTransport {
|
|
|
403
421
|
*/
|
|
404
422
|
getConsoleMethod(level) {
|
|
405
423
|
switch (level) {
|
|
406
|
-
case
|
|
407
|
-
case
|
|
408
|
-
case
|
|
409
|
-
case
|
|
424
|
+
case "debug": return console.debug;
|
|
425
|
+
case "info": return console.info;
|
|
426
|
+
case "warn": return console.warn;
|
|
427
|
+
case "error": return console.error;
|
|
410
428
|
default: return console.log;
|
|
411
429
|
}
|
|
412
430
|
}
|
|
@@ -415,4 +433,4 @@ ConsoleTransport = __decorate([Transient(LOGGER_TOKENS.ConsoleTransport)], Conso
|
|
|
415
433
|
//#endregion
|
|
416
434
|
export { __decorate as a, LOG_LEVEL_PRIORITY as c, CONTAINER_TOKEN as d, DI_TOKENS as f, getMethodInjections as g, InjectParam as h, LoggerService as i, LogLevel as l, INJECT_PARAM_METADATA_KEY as m, PrettyFormatter as n, __decorateParam as o, Transient as p, JsonFormatter as r, __decorateMetadata as s, ConsoleTransport as t, LOGGER_TOKENS as u };
|
|
417
435
|
|
|
418
|
-
//# sourceMappingURL=logger-
|
|
436
|
+
//# sourceMappingURL=logger-V6Ms3QnQ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger-c0ftIK4G.mjs","names":[],"sources":["../src/di/decorators/inject-param.decorator.ts","../src/di/decorators.ts","../src/di/tokens.ts","../src/logger/logger.tokens.ts","../src/logger/contracts/log-level.ts","../src/logger/services/logger.service.ts","../src/logger/formatters/json-formatter.ts","../src/logger/formatters/pretty-formatter.ts","../src/logger/transports/base-transport.ts","../src/logger/transports/console-transport.ts"],"sourcesContent":["/**\n * Method Parameter Injection Decorator\n *\n * Enables DI for controller method parameters. Parameters marked with\n * @InjectParam(token) are resolved from the request-scoped container\n * at method invocation time.\n *\n * @example\n * ```typescript\n * @Route({ response: userSchema })\n * async show(\n * ctx: RouterContext,\n * @InjectParam(UserService) userService: UserService,\n * @InjectParam(CacheService) cache: CacheService\n * ): Promise<Response> {\n * // userService and cache auto-resolved from request container\n * }\n * ```\n */\nimport type InjectionToken from 'tsyringe/dist/typings/providers/injection-token'\n\n/**\n * Metadata key for storing parameter injection information\n */\nexport const INJECT_PARAM_METADATA_KEY = Symbol.for('stratal:inject:param')\n\n/**\n * Describes a parameter injection\n */\nexport interface ParamInjection {\n /** Parameter index in the method signature (0-based) */\n index: number\n /** DI token to resolve */\n token: InjectionToken\n}\n\n/**\n * Mark a method parameter for DI injection\n *\n * The parameter will be resolved from the request-scoped container\n * when the controller method is invoked.\n *\n * @param token - DI token to resolve (class or symbol)\n *\n * @example With class token\n * ```typescript\n * async show(\n * ctx: RouterContext,\n * @InjectParam(UserService) userService: UserService\n * ) { }\n * ```\n *\n * @example With symbol token\n * ```typescript\n * async show(\n * ctx: RouterContext,\n * @InjectParam(DI_TOKENS.Cache) cache: ICacheService\n * ) { }\n * ```\n */\nexport function InjectParam<T>(token: InjectionToken<T>): ParameterDecorator {\n return (target: object, propertyKey: string | symbol | undefined, parameterIndex: number) => {\n if (propertyKey === undefined) {\n throw new Error('@InjectParam can only be used on method parameters, not constructor parameters')\n }\n\n const existingInjections: ParamInjection[] =\n (Reflect.getMetadata(INJECT_PARAM_METADATA_KEY, target, propertyKey) as ParamInjection[] | undefined) ?? []\n\n existingInjections.push({\n index: parameterIndex,\n token,\n })\n\n Reflect.defineMetadata(INJECT_PARAM_METADATA_KEY, existingInjections, target, propertyKey)\n }\n}\n\n/**\n * Get method parameter injections\n *\n * @param target - Controller prototype\n * @param propertyKey - Method name\n * @returns Array of parameter injections sorted by index\n */\nexport function getMethodInjections(target: object, propertyKey: string | symbol): ParamInjection[] {\n const injections: ParamInjection[] =\n (Reflect.getMetadata(INJECT_PARAM_METADATA_KEY, target, propertyKey) as ParamInjection[] | undefined) ?? []\n\n return injections.sort((a, b) => a.index - b.index)\n}\n","/**\n * DI Decorators\n *\n * Provides decorators for dependency injection:\n * - @Transient: Mark classes as injectable (lifecycle controlled at registration)\n * - @InjectParam: Inject dependencies into method parameters\n *\n * Lifecycle (Singleton, Request, Transient) is controlled at registration time\n * via the `scope` property in module providers or Container.register().\n */\nimport { injectable } from 'tsyringe'\nimport type InjectionToken from 'tsyringe/dist/typings/providers/injection-token'\n\n// Re-export method parameter injection\nexport {\n InjectParam,\n getMethodInjections,\n type ParamInjection,\n INJECT_PARAM_METADATA_KEY,\n} from './decorators/inject-param.decorator'\n\n/**\n * Mark a class as injectable\n *\n * This decorator wraps tsyringe's `@injectable` decorator and optionally\n * associates a token with the class. The actual lifecycle (Singleton, Request,\n * Transient) is determined at registration time, not decoration time.\n *\n * **Lifecycle Control:**\n * - Use `scope: Scope.Singleton` in module providers for singleton\n * - Use `scope: Scope.Request` in module providers for request-scoped\n * - Default is Transient (new instance per resolution)\n *\n * @param token - Optional DI token for service resolution\n *\n * @example Basic usage (no token)\n * ```typescript\n * @Transient()\n * export class UserService {\n * constructor(@inject(DI_TOKENS.Database) private db: DatabaseService) {}\n * }\n *\n * // In module:\n * @Module({\n * providers: [UserService] // Transient by default\n * })\n * ```\n *\n * @example With token\n * ```typescript\n * @Transient(DI_TOKENS.ConnectionManager)\n * export class ConnectionManager implements Disposable {\n * // ...\n * }\n *\n * // In Application.ts:\n * container.register(DI_TOKENS.ConnectionManager, ConnectionManager, Scope.Request)\n * ```\n *\n * @example Singleton via provider scope\n * ```typescript\n * @Transient()\n * export class ConsumerRegistry {\n * // ...\n * }\n *\n * // In module:\n * @Module({\n * providers: [\n * { provide: DI_TOKENS.ConsumerRegistry, useClass: ConsumerRegistry, scope: Scope.Singleton }\n * ]\n * })\n * ```\n */\nexport function Transient<T>(token?: InjectionToken<T>) {\n return function <TFunction extends abstract new (...args: never[]) => unknown>(target: TFunction): TFunction {\n const targetConstructor = target as unknown as new (...args: unknown[]) => T\n injectable<T>({ token })(targetConstructor)\n return target\n }\n}\n","/**\n * Token for the Container instance\n * Used for injecting the Container into services that need dynamic resolution\n */\nexport const CONTAINER_TOKEN = Symbol.for('stratal:di:container')\n\nexport const DI_TOKENS = {\n // Cloudflare\n CloudflareEnv: Symbol.for('stratal:cloudflare:env'),\n ExecutionContext: Symbol.for('stratal:execution:context'),\n\n // Infrastructure\n Container: CONTAINER_TOKEN,\n Application: Symbol.for('stratal:application'),\n ModuleRegistry: Symbol.for('stratal:module:registry'),\n ExceptionHandler: Symbol.for('stratal:exception:handler'),\n Database: Symbol.for('stratal:database:service'),\n Queue: Symbol.for('stratal:queue:manager'),\n ConsumerRegistry: Symbol.for('stratal:consumer:registry'),\n Cron: Symbol.for('stratal:cron:manager'),\n EventRegistry: Symbol.for('stratal:event:registry'),\n Quarry: Symbol.for('stratal:quarry'),\n\n // Context\n /**\n * AuthContext: Use for services that need user authentication (userId).\n */\n AuthContext: Symbol.for('stratal:auth:context'),\n\n // Workers\n DurableObjectState: Symbol.for('stratal:durable:object:state'),\n DurableObjectId: Symbol.for('stratal:durable:object:id'),\n} as const\n\nexport type DIToken = typeof DI_TOKENS[keyof typeof DI_TOKENS]\n","/**\n * Dependency Injection Tokens for Logger Module\n *\n * Symbol-based tokens ensure type-safe dependency injection\n * and prevent naming collisions.\n */\nexport const LOGGER_TOKENS = {\n /**\n * Main logger service facade\n */\n LoggerService: Symbol.for('stratal:logger:service'),\n\n /**\n * Log formatter (JSON or Pretty)\n */\n Formatter: Symbol.for('stratal:logger:formatter'),\n\n /**\n * Array of active transports\n */\n Transports: Symbol.for('stratal:logger:transports'),\n\n /**\n * Individual transport tokens (for factory registration)\n */\n ConsoleTransport: Symbol.for('stratal:logger:console:transport'),\n\n /**\n * Configured log level for filtering\n */\n LogLevelOptions: Symbol.for('stratal:logger:log:level:options'),\n} as const\n","/**\n * Log severity levels\n * Ordered from least to most severe\n */\nexport enum LogLevel {\n DEBUG = 'debug',\n INFO = 'info',\n WARN = 'warn',\n ERROR = 'error',\n}\n\n/**\n * Map log levels to numeric priorities (for filtering)\n * Higher numbers = more severe = higher priority\n */\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n [LogLevel.DEBUG]: 0,\n [LogLevel.INFO]: 1,\n [LogLevel.WARN]: 2,\n [LogLevel.ERROR]: 3,\n}\n","import { inject } from 'tsyringe'\nimport { Transient } from '../../di/decorators'\nimport { DI_TOKENS } from '../../di/tokens'\nimport type { InternalLogContext, LogContext, LogEntry } from '../contracts'\nimport { LOG_LEVEL_PRIORITY, LogLevel } from '../contracts/log-level'\nimport type { ILogFormatter } from '../formatters/formatter.interface'\nimport { LOGGER_TOKENS } from '../logger.tokens'\nimport type { ILogTransport } from '../transports/transport.interface'\n\n/**\n * Logger Service\n *\n * Main logging facade.\n *\n * **Features:**\n * - Async logging via ctx.waitUntil() for non-blocking performance\n * - Multi-transport support (console, future Sentry/Cloudflare Analytics)\n * - Configurable formatters (JSON production, Pretty development)\n * - Log level filtering based on environment\n *\n * **Architecture:**\n * - Transports and formatters injected via DI\n *\n * @example Basic usage\n * ```typescript\n * @Transient()\n * export class UserService {\n * constructor(\n * @inject(LOGGER_TOKENS.LoggerService)\n * private readonly logger: LoggerService\n * ) {}\n *\n * async createUser(input: CreateUserInput) {\n * this.logger.info('Creating user', { email: input.email })\n * }\n * }\n * ```\n */\n@Transient()\nexport class LoggerService {\n constructor(\n @inject(LOGGER_TOKENS.LogLevelOptions)\n private readonly logLevel: LogLevel,\n\n @inject(DI_TOKENS.ExecutionContext)\n private readonly executionContext: globalThis.ExecutionContext,\n\n @inject(LOGGER_TOKENS.Formatter)\n private readonly formatter: ILogFormatter,\n\n @inject(LOGGER_TOKENS.Transports)\n private readonly transports: ILogTransport[],\n ) { }\n\n /**\n * Log debug message (development only)\n */\n debug(message: string, context?: LogContext): void {\n this.log(LogLevel.DEBUG, message, context)\n }\n\n /**\n * Log info message\n */\n info(message: string, context?: LogContext): void {\n this.log(LogLevel.INFO, message, context)\n }\n\n /**\n * Log warning message\n */\n warn(message: string, context?: LogContext): void {\n this.log(LogLevel.WARN, message, context)\n }\n\n /**\n * Log error message\n * Accepts Error object or custom context\n */\n error(message: string, contextOrError?: LogContext | Error): void {\n let context: LogContext | undefined\n let error: Error | undefined\n\n if (contextOrError instanceof Error) {\n error = contextOrError\n } else {\n context = contextOrError\n }\n\n this.log(LogLevel.ERROR, message, context, error)\n }\n\n /**\n * Core logging implementation\n * Enriches context, formats message, dispatches to transports\n * Uses ctx.waitUntil() for async non-blocking processing\n */\n private log(\n level: LogLevel,\n message: string,\n userContext?: LogContext,\n error?: Error\n ): void {\n // Filter by configured log level\n if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.logLevel]) {\n return\n }\n\n // Build complete log entry with enriched context\n const entry: LogEntry = {\n level,\n message,\n context: this.enrichContext(userContext ?? {}),\n error: error ? this.serializeError(error) : undefined,\n }\n\n // Format once for all transports\n const formatted = this.formatter.format(entry)\n\n // Dispatch to all transports asynchronously\n const writePromises = this.transports.map(transport =>\n transport.write(entry, formatted).catch((err: unknown) => {\n // Swallow transport errors to prevent log failure from crashing app\n console.error(`Transport ${transport.name} failed:`, err)\n })\n )\n\n // Use waitUntil to ensure logs complete even after response sent\n const allWrites = Promise.all(writePromises)\n try {\n this.executionContext.waitUntil(allWrites)\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes('global scope')) {\n throw error\n }\n }\n }\n\n /**\n * Enrich log context with request info and timestamp\n * Context enrichment can be extended by application modules\n */\n private enrichContext(userContext: LogContext): InternalLogContext {\n return {\n ...userContext,\n timestamp: Date.now(),\n }\n }\n\n /**\n * Serialize Error object for transport\n */\n private serializeError(error: Error): { message: string; stack?: string; name?: string } {\n return {\n message: error.message,\n stack: error.stack,\n name: error.name,\n }\n }\n}\n","import type { LogEntry } from '../contracts'\nimport type { ILogFormatter } from './formatter.interface'\n\n/**\n * JSON Formatter\n *\n * Produces structured JSON logs for production environments.\n * Optimized for log aggregation systems (Cloudflare Analytics, Datadog, etc.)\n *\n * Output format:\n * {\n * \"level\": \"info\",\n * \"message\": \"User logged in\",\n * \"timestamp\": 1234567890,\n * \"userId\": \"user_456\",\n * \"error\": { \"message\": \"...\", \"stack\": \"...\" }\n * }\n */\nexport class JsonFormatter implements ILogFormatter {\n format(entry: LogEntry): string {\n const output = {\n level: entry.level,\n message: entry.message,\n ...entry.context,\n ...(entry.error && { error: entry.error }),\n }\n\n return JSON.stringify(output)\n }\n}\n","import type { LogEntry } from '../contracts'\nimport { LogLevel } from '../contracts'\nimport type { ILogFormatter } from './formatter.interface'\n\n/**\n * Pretty Formatter\n *\n * Human-readable colored output for development environments.\n * Uses ANSI color codes for terminal output.\n *\n * Output format:\n * [2024-01-15 10:30:45] INFO: User logged in\n * userId: user_456\n */\nexport class PrettyFormatter implements ILogFormatter {\n private readonly colors: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: '\\x1b[36m', // Cyan\n [LogLevel.INFO]: '\\x1b[32m', // Green\n [LogLevel.WARN]: '\\x1b[33m', // Yellow\n [LogLevel.ERROR]: '\\x1b[31m', // Red\n }\n\n private readonly reset = '\\x1b[0m'\n\n format(entry: LogEntry): string {\n const color = this.colors[entry.level]\n const timestamp = new Date(entry.context.timestamp).toISOString()\n const levelStr = entry.level.toUpperCase().padEnd(5)\n\n let output = `${color}[${timestamp}] ${levelStr}${this.reset}: ${entry.message}`\n\n // Add context (exclude timestamp)\n const { timestamp: _, ...contextWithoutTimestamp } = entry.context\n const contextEntries = Object.entries(contextWithoutTimestamp)\n\n if (contextEntries.length > 0) {\n output += '\\n'\n contextEntries.forEach(([key, value]) => {\n output += ` ${key}: ${JSON.stringify(value)}\\n`\n })\n }\n\n // Add error stack if present\n if (entry.error?.stack) {\n output += `\\n${entry.error.stack}\\n`\n }\n\n return output.trimEnd()\n }\n}\n","import type { ILogTransport } from './transport.interface'\nimport type { LogEntry } from '../contracts'\n\n/**\n * Base Transport\n *\n * Abstract base class providing shared transport logic.\n * Reduces code duplication across transport implementations.\n */\nexport abstract class BaseTransport implements ILogTransport {\n abstract readonly name: string\n\n /**\n * Write log entry - must be implemented by concrete transports\n */\n abstract write(entry: LogEntry, formatted: string): Promise<void>\n\n /**\n * Handle transport errors gracefully\n * Logs to console.error as fallback to prevent log loss\n *\n * @param error - Error that occurred during write\n * @param entry - Log entry that failed\n */\n protected handleError(error: unknown, entry: LogEntry): void {\n console.error(`[${this.name}] Failed to write log:`, {\n error: error instanceof Error ? error.message : String(error),\n logMessage: entry.message,\n level: entry.level,\n })\n }\n}\n","import { Transient } from '../../di/decorators'\nimport { LOGGER_TOKENS } from '../logger.tokens'\nimport { BaseTransport } from './base-transport'\nimport type { LogEntry } from '../contracts'\nimport { LogLevel } from '../contracts'\n\n/**\n * Console Transport\n *\n * Writes logs to console using appropriate console methods.\n * Maps log levels to console.debug, console.info, console.warn, console.error.\n *\n * Thread-safe for Cloudflare Workers environment.\n */\n@Transient(LOGGER_TOKENS.ConsoleTransport)\nexport class ConsoleTransport extends BaseTransport {\n readonly name = 'console'\n\n write(entry: LogEntry, formatted: string): Promise<void> {\n try {\n const consoleMethod = this.getConsoleMethod(entry.level)\n consoleMethod(formatted)\n } catch (error) {\n this.handleError(error, entry)\n }\n\n return Promise.resolve()\n }\n\n /**\n * Map log level to console method\n */\n private getConsoleMethod(level: LogLevel): typeof console.log {\n switch (level) {\n case LogLevel.DEBUG:\n return console.debug\n case LogLevel.INFO:\n return console.info\n case LogLevel.WARN:\n return console.warn\n case LogLevel.ERROR:\n return console.error\n default:\n return console.log\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logger-V6Ms3QnQ.mjs","names":[],"sources":["../src/di/decorators/inject-param.decorator.ts","../src/di/decorators.ts","../src/di/tokens.ts","../src/logger/logger.tokens.ts","../src/logger/contracts/log-level.ts","../src/logger/services/logger.service.ts","../src/logger/formatters/json-formatter.ts","../src/logger/formatters/pretty-formatter.ts","../src/logger/transports/base-transport.ts","../src/logger/transports/console-transport.ts"],"sourcesContent":["/**\n * Method Parameter Injection Decorator\n *\n * Enables DI for controller method parameters. Parameters marked with\n * @InjectParam(token) are resolved from the request-scoped container\n * at method invocation time.\n *\n * @example\n * ```typescript\n * @Route({ response: userSchema })\n * async show(\n * ctx: RouterContext,\n * @InjectParam(UserService) userService: UserService,\n * @InjectParam(CacheService) cache: CacheService\n * ): Promise<Response> {\n * // userService and cache auto-resolved from request container\n * }\n * ```\n */\nimport type InjectionToken from 'tsyringe/dist/typings/providers/injection-token'\n\n/**\n * Metadata key for storing parameter injection information\n */\nexport const INJECT_PARAM_METADATA_KEY = Symbol.for('stratal:inject:param')\n\n/**\n * Describes a parameter injection\n */\nexport interface ParamInjection {\n /** Parameter index in the method signature (0-based) */\n index: number\n /** DI token to resolve */\n token: InjectionToken\n}\n\n/**\n * Mark a method parameter for DI injection\n *\n * The parameter will be resolved from the request-scoped container\n * when the controller method is invoked.\n *\n * @param token - DI token to resolve (class or symbol)\n *\n * @example With class token\n * ```typescript\n * async show(\n * ctx: RouterContext,\n * @InjectParam(UserService) userService: UserService\n * ) { }\n * ```\n *\n * @example With symbol token\n * ```typescript\n * async show(\n * ctx: RouterContext,\n * @InjectParam(DI_TOKENS.Cache) cache: ICacheService\n * ) { }\n * ```\n */\nexport function InjectParam<T>(token: InjectionToken<T>): ParameterDecorator {\n return (target: object, propertyKey: string | symbol | undefined, parameterIndex: number) => {\n if (propertyKey === undefined) {\n throw new Error('@InjectParam can only be used on method parameters, not constructor parameters')\n }\n\n const existingInjections: ParamInjection[] =\n (Reflect.getMetadata(INJECT_PARAM_METADATA_KEY, target, propertyKey) as ParamInjection[] | undefined) ?? []\n\n existingInjections.push({\n index: parameterIndex,\n token,\n })\n\n Reflect.defineMetadata(INJECT_PARAM_METADATA_KEY, existingInjections, target, propertyKey)\n }\n}\n\n/**\n * Get method parameter injections\n *\n * @param target - Controller prototype\n * @param propertyKey - Method name\n * @returns Array of parameter injections sorted by index\n */\nexport function getMethodInjections(target: object, propertyKey: string | symbol): ParamInjection[] {\n const injections: ParamInjection[] =\n (Reflect.getMetadata(INJECT_PARAM_METADATA_KEY, target, propertyKey) as ParamInjection[] | undefined) ?? []\n\n return injections.sort((a, b) => a.index - b.index)\n}\n","/**\n * DI Decorators\n *\n * Provides decorators for dependency injection:\n * - @Transient: Mark classes as injectable (lifecycle controlled at registration)\n * - @InjectParam: Inject dependencies into method parameters\n *\n * Lifecycle (Singleton, Request, Transient) is controlled at registration time\n * via the `scope` property in module providers or Container.register().\n */\nimport { injectable } from 'tsyringe'\nimport type InjectionToken from 'tsyringe/dist/typings/providers/injection-token'\n\n// Re-export method parameter injection\nexport {\n InjectParam,\n getMethodInjections,\n type ParamInjection,\n INJECT_PARAM_METADATA_KEY,\n} from './decorators/inject-param.decorator'\n\n/**\n * Mark a class as injectable\n *\n * This decorator wraps tsyringe's `@injectable` decorator and optionally\n * associates a token with the class. The actual lifecycle (Singleton, Request,\n * Transient) is determined at registration time, not decoration time.\n *\n * **Lifecycle Control:**\n * - Use `scope: Scope.Singleton` in module providers for singleton\n * - Use `scope: Scope.Request` in module providers for request-scoped\n * - Default is Transient (new instance per resolution)\n *\n * @param token - Optional DI token for service resolution\n *\n * @example Basic usage (no token)\n * ```typescript\n * @Transient()\n * export class UserService {\n * constructor(@inject(DI_TOKENS.Database) private db: DatabaseService) {}\n * }\n *\n * // In module:\n * @Module({\n * providers: [UserService] // Transient by default\n * })\n * ```\n *\n * @example With token\n * ```typescript\n * @Transient(DI_TOKENS.ConnectionManager)\n * export class ConnectionManager implements Disposable {\n * // ...\n * }\n *\n * // In Application.ts:\n * container.register(DI_TOKENS.ConnectionManager, ConnectionManager, Scope.Request)\n * ```\n *\n * @example Singleton via provider scope\n * ```typescript\n * @Transient()\n * export class ConsumerRegistry {\n * // ...\n * }\n *\n * // In module:\n * @Module({\n * providers: [\n * { provide: DI_TOKENS.ConsumerRegistry, useClass: ConsumerRegistry, scope: Scope.Singleton }\n * ]\n * })\n * ```\n */\nexport function Transient<T>(token?: InjectionToken<T>) {\n return function <TFunction extends abstract new (...args: never[]) => unknown>(target: TFunction): TFunction {\n const targetConstructor = target as unknown as new (...args: unknown[]) => T\n injectable<T>({ token })(targetConstructor)\n return target\n }\n}\n","/**\n * Token for the Container instance\n * Used for injecting the Container into services that need dynamic resolution\n */\nexport const CONTAINER_TOKEN = Symbol.for('stratal:di:container')\n\nexport const DI_TOKENS = {\n // Cloudflare\n CloudflareEnv: Symbol.for('stratal:cloudflare:env'),\n ExecutionContext: Symbol.for('stratal:execution:context'),\n\n // Infrastructure\n Container: CONTAINER_TOKEN,\n Application: Symbol.for('stratal:application'),\n ModuleRegistry: Symbol.for('stratal:module:registry'),\n ExceptionHandler: Symbol.for('stratal:exception:handler'),\n Database: Symbol.for('stratal:database:service'),\n Queue: Symbol.for('stratal:queue:manager'),\n ConsumerRegistry: Symbol.for('stratal:consumer:registry'),\n Cron: Symbol.for('stratal:cron:manager'),\n EventRegistry: Symbol.for('stratal:event:registry'),\n Quarry: Symbol.for('stratal:quarry'),\n\n // Context\n /**\n * AuthContext: Use for services that need user authentication (userId).\n */\n AuthContext: Symbol.for('stratal:auth:context'),\n\n // Workers\n DurableObjectState: Symbol.for('stratal:durable:object:state'),\n DurableObjectId: Symbol.for('stratal:durable:object:id'),\n} as const\n\nexport type DIToken = typeof DI_TOKENS[keyof typeof DI_TOKENS]\n","/**\n * Dependency Injection Tokens for Logger Module\n *\n * Symbol-based tokens ensure type-safe dependency injection\n * and prevent naming collisions.\n */\nexport const LOGGER_TOKENS = {\n /**\n * Main logger service facade\n */\n LoggerService: Symbol.for('stratal:logger:service'),\n\n /**\n * Log formatter (JSON or Pretty)\n */\n Formatter: Symbol.for('stratal:logger:formatter'),\n\n /**\n * Array of active transports\n */\n Transports: Symbol.for('stratal:logger:transports'),\n\n /**\n * Individual transport tokens (for factory registration)\n */\n ConsoleTransport: Symbol.for('stratal:logger:console:transport'),\n\n /**\n * Configured log level for filtering\n */\n LogLevelOptions: Symbol.for('stratal:logger:log:level:options'),\n} as const\n","/**\n * Log severity levels\n * Ordered from least to most severe\n */\nexport enum LogLevel {\n DEBUG = 'debug',\n INFO = 'info',\n WARN = 'warn',\n ERROR = 'error',\n}\n\n/**\n * Map log levels to numeric priorities (for filtering)\n * Higher numbers = more severe = higher priority\n */\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n [LogLevel.DEBUG]: 0,\n [LogLevel.INFO]: 1,\n [LogLevel.WARN]: 2,\n [LogLevel.ERROR]: 3,\n}\n","import { inject } from 'tsyringe'\nimport { Transient } from '../../di/decorators'\nimport { DI_TOKENS } from '../../di/tokens'\nimport type { InternalLogContext, LogContext, LogEntry } from '../contracts'\nimport { LOG_LEVEL_PRIORITY, LogLevel } from '../contracts/log-level'\nimport type { ILogFormatter } from '../formatters/formatter.interface'\nimport { LOGGER_TOKENS } from '../logger.tokens'\nimport type { ILogTransport } from '../transports/transport.interface'\n\n/**\n * Logger Service\n *\n * Main logging facade.\n *\n * **Features:**\n * - Async logging via ctx.waitUntil() for non-blocking performance\n * - Multi-transport support (console, future Sentry/Cloudflare Analytics)\n * - Configurable formatters (JSON production, Pretty development)\n * - Log level filtering based on environment\n *\n * **Architecture:**\n * - Transports and formatters injected via DI\n *\n * @example Basic usage\n * ```typescript\n * @Transient()\n * export class UserService {\n * constructor(\n * @inject(LOGGER_TOKENS.LoggerService)\n * private readonly logger: LoggerService\n * ) {}\n *\n * async createUser(input: CreateUserInput) {\n * this.logger.info('Creating user', { email: input.email })\n * }\n * }\n * ```\n */\n@Transient()\nexport class LoggerService {\n constructor(\n @inject(LOGGER_TOKENS.LogLevelOptions)\n private readonly logLevel: LogLevel,\n\n @inject(DI_TOKENS.ExecutionContext)\n private readonly executionContext: globalThis.ExecutionContext,\n\n @inject(LOGGER_TOKENS.Formatter)\n private readonly formatter: ILogFormatter,\n\n @inject(LOGGER_TOKENS.Transports)\n private readonly transports: ILogTransport[],\n ) { }\n\n /**\n * Log debug message (development only)\n */\n debug(message: string, context?: LogContext): void {\n this.log(LogLevel.DEBUG, message, context)\n }\n\n /**\n * Log info message\n */\n info(message: string, context?: LogContext): void {\n this.log(LogLevel.INFO, message, context)\n }\n\n /**\n * Log warning message\n */\n warn(message: string, context?: LogContext): void {\n this.log(LogLevel.WARN, message, context)\n }\n\n /**\n * Log error message\n * Accepts Error object or custom context\n */\n error(message: string, contextOrError?: LogContext | Error): void {\n let context: LogContext | undefined\n let error: Error | undefined\n\n if (contextOrError instanceof Error) {\n error = contextOrError\n } else {\n context = contextOrError\n }\n\n this.log(LogLevel.ERROR, message, context, error)\n }\n\n /**\n * Core logging implementation\n * Enriches context, formats message, dispatches to transports\n * Uses ctx.waitUntil() for async non-blocking processing\n */\n private log(\n level: LogLevel,\n message: string,\n userContext?: LogContext,\n error?: Error\n ): void {\n // Filter by configured log level\n if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.logLevel]) {\n return\n }\n\n // Build complete log entry with enriched context\n const entry: LogEntry = {\n level,\n message,\n context: this.enrichContext(userContext ?? {}),\n error: error ? this.serializeError(error) : undefined,\n }\n\n // Format once for all transports\n const formatted = this.formatter.format(entry)\n\n // Dispatch to all transports asynchronously\n const writePromises = this.transports.map(transport =>\n transport.write(entry, formatted).catch((err: unknown) => {\n // Swallow transport errors to prevent log failure from crashing app\n console.error(`Transport ${transport.name} failed:`, err)\n })\n )\n\n // Use waitUntil to ensure logs complete even after response sent\n const allWrites = Promise.all(writePromises)\n try {\n this.executionContext.waitUntil(allWrites)\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes('global scope')) {\n throw error\n }\n }\n }\n\n /**\n * Enrich log context with request info and timestamp\n * Context enrichment can be extended by application modules\n */\n private enrichContext(userContext: LogContext): InternalLogContext {\n return {\n ...userContext,\n timestamp: Date.now(),\n }\n }\n\n /**\n * Serialize Error object for transport\n */\n private serializeError(error: Error): { message: string; stack?: string; name?: string } {\n return {\n message: error.message,\n stack: error.stack,\n name: error.name,\n }\n }\n}\n","import type { LogEntry } from '../contracts'\nimport type { ILogFormatter } from './formatter.interface'\n\n/**\n * JSON Formatter\n *\n * Produces structured JSON logs for production environments.\n * Optimized for log aggregation systems (Cloudflare Analytics, Datadog, etc.)\n *\n * Output format:\n * {\n * \"level\": \"info\",\n * \"message\": \"User logged in\",\n * \"timestamp\": 1234567890,\n * \"userId\": \"user_456\",\n * \"error\": { \"message\": \"...\", \"stack\": \"...\" }\n * }\n */\nexport class JsonFormatter implements ILogFormatter {\n format(entry: LogEntry): string {\n const output = {\n level: entry.level,\n message: entry.message,\n ...entry.context,\n ...(entry.error && { error: entry.error }),\n }\n\n return JSON.stringify(output)\n }\n}\n","import type { LogEntry } from '../contracts'\nimport { LogLevel } from '../contracts'\nimport type { ILogFormatter } from './formatter.interface'\n\n/**\n * Pretty Formatter\n *\n * Human-readable colored output for development environments.\n * Uses ANSI color codes for terminal output.\n *\n * Output format:\n * [2024-01-15 10:30:45] INFO: User logged in\n * userId: user_456\n */\nexport class PrettyFormatter implements ILogFormatter {\n private readonly colors: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: '\\x1b[36m', // Cyan\n [LogLevel.INFO]: '\\x1b[32m', // Green\n [LogLevel.WARN]: '\\x1b[33m', // Yellow\n [LogLevel.ERROR]: '\\x1b[31m', // Red\n }\n\n private readonly reset = '\\x1b[0m'\n\n format(entry: LogEntry): string {\n const color = this.colors[entry.level]\n const timestamp = new Date(entry.context.timestamp).toISOString()\n const levelStr = entry.level.toUpperCase().padEnd(5)\n\n let output = `${color}[${timestamp}] ${levelStr}${this.reset}: ${entry.message}`\n\n // Add context (exclude timestamp)\n const { timestamp: _, ...contextWithoutTimestamp } = entry.context\n const contextEntries = Object.entries(contextWithoutTimestamp)\n\n if (contextEntries.length > 0) {\n output += '\\n'\n contextEntries.forEach(([key, value]) => {\n output += ` ${key}: ${JSON.stringify(value)}\\n`\n })\n }\n\n // Add error stack if present\n if (entry.error?.stack) {\n output += `\\n${entry.error.stack}\\n`\n }\n\n return output.trimEnd()\n }\n}\n","import type { ILogTransport } from './transport.interface'\nimport type { LogEntry } from '../contracts'\n\n/**\n * Base Transport\n *\n * Abstract base class providing shared transport logic.\n * Reduces code duplication across transport implementations.\n */\nexport abstract class BaseTransport implements ILogTransport {\n abstract readonly name: string\n\n /**\n * Write log entry - must be implemented by concrete transports\n */\n abstract write(entry: LogEntry, formatted: string): Promise<void>\n\n /**\n * Handle transport errors gracefully\n * Logs to console.error as fallback to prevent log loss\n *\n * @param error - Error that occurred during write\n * @param entry - Log entry that failed\n */\n protected handleError(error: unknown, entry: LogEntry): void {\n console.error(`[${this.name}] Failed to write log:`, {\n error: error instanceof Error ? error.message : String(error),\n logMessage: entry.message,\n level: entry.level,\n })\n }\n}\n","import { Transient } from '../../di/decorators'\nimport { LOGGER_TOKENS } from '../logger.tokens'\nimport { BaseTransport } from './base-transport'\nimport type { LogEntry } from '../contracts'\nimport { LogLevel } from '../contracts'\n\n/**\n * Console Transport\n *\n * Writes logs to console using appropriate console methods.\n * Maps log levels to console.debug, console.info, console.warn, console.error.\n *\n * Thread-safe for Cloudflare Workers environment.\n */\n@Transient(LOGGER_TOKENS.ConsoleTransport)\nexport class ConsoleTransport extends BaseTransport {\n readonly name = 'console'\n\n write(entry: LogEntry, formatted: string): Promise<void> {\n try {\n const consoleMethod = this.getConsoleMethod(entry.level)\n consoleMethod(formatted)\n } catch (error) {\n this.handleError(error, entry)\n }\n\n return Promise.resolve()\n }\n\n /**\n * Map log level to console method\n */\n private getConsoleMethod(level: LogLevel): typeof console.log {\n switch (level) {\n case LogLevel.DEBUG:\n return console.debug\n case LogLevel.INFO:\n return console.info\n case LogLevel.WARN:\n return console.warn\n case LogLevel.ERROR:\n return console.error\n default:\n return console.log\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//#region src/macroable/macroable.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for adding macros, instance properties, and getters
|
|
4
|
+
* to classes at runtime.
|
|
5
|
+
*
|
|
6
|
+
* Inspired by [@poppinss/macroable](https://github.com/poppinss/macroable)
|
|
7
|
+
* and Laravel's Macroable trait.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Register a macro
|
|
12
|
+
* RouterContext.macro('flash', function (this: RouterContext, key: string, value: unknown) {
|
|
13
|
+
* const session = this.getContainer().resolve(SessionService)
|
|
14
|
+
* session.flash(key, value)
|
|
15
|
+
* })
|
|
16
|
+
*
|
|
17
|
+
* // Register a getter
|
|
18
|
+
* RouterContext.getter('requestId', function (this: RouterContext) {
|
|
19
|
+
* return this.header('x-request-id') ?? crypto.randomUUID()
|
|
20
|
+
* }, true)
|
|
21
|
+
*
|
|
22
|
+
* // Register a per-instance property (safe for destructuring)
|
|
23
|
+
* RouterContext.instanceProperty('getUser', function (this: RouterContext) {
|
|
24
|
+
* return this.getContainer().resolve(AuthContext).user
|
|
25
|
+
* })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
var Macroable = class {
|
|
29
|
+
/**
|
|
30
|
+
* Per-instance properties. Each entry is applied and bound
|
|
31
|
+
* to `this` inside the constructor so destructuring stays safe.
|
|
32
|
+
*/
|
|
33
|
+
static instanceMacros = /* @__PURE__ */ new Set();
|
|
34
|
+
/**
|
|
35
|
+
* Names registered via macro() — used by hasMacro() and flushMacros().
|
|
36
|
+
*/
|
|
37
|
+
static macroNames = /* @__PURE__ */ new Set();
|
|
38
|
+
/**
|
|
39
|
+
* Names registered via getter() — used by hasMacro() and flushMacros().
|
|
40
|
+
*/
|
|
41
|
+
static getterNames = /* @__PURE__ */ new Set();
|
|
42
|
+
/**
|
|
43
|
+
* Original prototype values saved before macro() overrides them.
|
|
44
|
+
* Used by flushMacros() to restore native methods.
|
|
45
|
+
*/
|
|
46
|
+
static _originals = /* @__PURE__ */ new Map();
|
|
47
|
+
static macro(name, value) {
|
|
48
|
+
if (!Object.prototype.hasOwnProperty.call(this, "macroNames")) this.macroNames = new Set(this.macroNames);
|
|
49
|
+
if (!Object.prototype.hasOwnProperty.call(this, "_originals")) this._originals = new Map(this._originals);
|
|
50
|
+
if (!this._originals.has(name)) {
|
|
51
|
+
const existed = Object.prototype.hasOwnProperty.call(this.prototype, name);
|
|
52
|
+
this._originals.set(name, {
|
|
53
|
+
existed,
|
|
54
|
+
value: existed ? this.prototype[name] : void 0
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
this.macroNames.add(name);
|
|
58
|
+
this.prototype[name] = value;
|
|
59
|
+
}
|
|
60
|
+
static instanceProperty(name, value) {
|
|
61
|
+
if (!Object.prototype.hasOwnProperty.call(this, "instanceMacros")) this.instanceMacros = new Set(this.instanceMacros);
|
|
62
|
+
this.instanceMacros.add({
|
|
63
|
+
key: name,
|
|
64
|
+
value
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
static getter(name, accumulator, singleton = false) {
|
|
68
|
+
if (!Object.prototype.hasOwnProperty.call(this, "getterNames")) this.getterNames = new Set(this.getterNames);
|
|
69
|
+
this.getterNames.add(name);
|
|
70
|
+
Object.defineProperty(this.prototype, name, {
|
|
71
|
+
get() {
|
|
72
|
+
const value = accumulator.call(this);
|
|
73
|
+
if (singleton) Object.defineProperty(this, name, {
|
|
74
|
+
value,
|
|
75
|
+
configurable: false,
|
|
76
|
+
enumerable: false,
|
|
77
|
+
writable: false
|
|
78
|
+
});
|
|
79
|
+
return value;
|
|
80
|
+
},
|
|
81
|
+
configurable: true,
|
|
82
|
+
enumerable: false
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check if a macro, instance property, or getter is registered.
|
|
87
|
+
*
|
|
88
|
+
* @param name - Name to check
|
|
89
|
+
*/
|
|
90
|
+
static hasMacro(name) {
|
|
91
|
+
return this.macroNames.has(name) || [...this.instanceMacros].some((m) => m.key === name) || this.getterNames.has(name);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Remove all macros, instance properties, and getters
|
|
95
|
+
* registered on this class. Does not affect parent classes.
|
|
96
|
+
*/
|
|
97
|
+
static flushMacros() {
|
|
98
|
+
const proto = this.prototype;
|
|
99
|
+
for (const name of this.macroNames) {
|
|
100
|
+
const original = this._originals.get(name);
|
|
101
|
+
if (original?.existed) proto[name] = original.value;
|
|
102
|
+
else Reflect.deleteProperty(proto, name);
|
|
103
|
+
}
|
|
104
|
+
for (const name of this.getterNames) Reflect.deleteProperty(proto, name);
|
|
105
|
+
if (Object.prototype.hasOwnProperty.call(this, "macroNames")) this.macroNames.clear();
|
|
106
|
+
if (Object.prototype.hasOwnProperty.call(this, "instanceMacros")) this.instanceMacros.clear();
|
|
107
|
+
if (Object.prototype.hasOwnProperty.call(this, "getterNames")) this.getterNames.clear();
|
|
108
|
+
if (Object.prototype.hasOwnProperty.call(this, "_originals")) this._originals.clear();
|
|
109
|
+
}
|
|
110
|
+
constructor() {
|
|
111
|
+
const Constructor = this.constructor;
|
|
112
|
+
const self = this;
|
|
113
|
+
Constructor.instanceMacros.forEach(({ key, value }) => {
|
|
114
|
+
if (typeof value === "function") self[key] = value.bind(this);
|
|
115
|
+
else self[key] = value;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
//#endregion
|
|
120
|
+
export { Macroable as t };
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=macroable-BmufBshB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"macroable-BmufBshB.mjs","names":[],"sources":["../src/macroable/macroable.ts"],"sourcesContent":["import type { MacroFunction } from './types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor = abstract new (...args: any[]) => any\n\n/**\n * Abstract base class for adding macros, instance properties, and getters\n * to classes at runtime.\n *\n * Inspired by [@poppinss/macroable](https://github.com/poppinss/macroable)\n * and Laravel's Macroable trait.\n *\n * @example\n * ```typescript\n * // Register a macro\n * RouterContext.macro('flash', function (this: RouterContext, key: string, value: unknown) {\n * const session = this.getContainer().resolve(SessionService)\n * session.flash(key, value)\n * })\n *\n * // Register a getter\n * RouterContext.getter('requestId', function (this: RouterContext) {\n * return this.header('x-request-id') ?? crypto.randomUUID()\n * }, true)\n *\n * // Register a per-instance property (safe for destructuring)\n * RouterContext.instanceProperty('getUser', function (this: RouterContext) {\n * return this.getContainer().resolve(AuthContext).user\n * })\n * ```\n */\nexport abstract class Macroable {\n [key: string | symbol]: unknown\n /**\n * Per-instance properties. Each entry is applied and bound\n * to `this` inside the constructor so destructuring stays safe.\n */\n protected static instanceMacros = new Set<{ key: string | symbol; value: unknown }>()\n\n /**\n * Names registered via macro() — used by hasMacro() and flushMacros().\n */\n protected static macroNames = new Set<string | symbol>()\n\n /**\n * Names registered via getter() — used by hasMacro() and flushMacros().\n */\n protected static getterNames = new Set<string | symbol>()\n\n /**\n * Original prototype values saved before macro() overrides them.\n * Used by flushMacros() to restore native methods.\n */\n private static _originals = new Map<string | symbol, { existed: boolean; value: unknown }>()\n\n // ── Macros (prototype-level) ──────────────────────────────\n\n /**\n * Register a macro on the class prototype.\n * Can override existing methods.\n *\n * When the name matches an existing property, the value type is auto-derived.\n *\n * @param name - Method or property name\n * @param value - Function or value to assign\n */\n static macro<T extends Constructor, K extends keyof InstanceType<T>>(\n this: T,\n name: K,\n value: InstanceType<T>[K],\n ): void\n static macro(name: string | symbol, value: unknown): void\n static macro(name: string | symbol, value: unknown): void {\n if (!Object.prototype.hasOwnProperty.call(this, 'macroNames')) {\n this.macroNames = new Set(this.macroNames)\n }\n if (!Object.prototype.hasOwnProperty.call(this, '_originals')) {\n this._originals = new Map(this._originals)\n }\n\n // Save the original value before first override so flushMacros() can restore it\n if (!this._originals.has(name)) {\n const existed = Object.prototype.hasOwnProperty.call(this.prototype, name)\n this._originals.set(name, {\n existed,\n value: existed ? (this.prototype as Record<string | symbol, unknown>)[name] : undefined,\n })\n }\n\n this.macroNames.add(name);\n (this.prototype as Record<string | symbol, unknown>)[name] = value\n }\n\n // ── Instance properties (bound per-instance) ─────────────\n\n /**\n * Register a per-instance property that is bound to `this`\n * in the constructor. Safe for destructuring.\n *\n * When the name matches an existing property, the value type is auto-derived.\n *\n * @param name - Property name\n * @param value - Function (will be bound) or value\n */\n static instanceProperty<T extends Constructor, K extends keyof InstanceType<T>>(\n this: T,\n name: K,\n value: InstanceType<T>[K],\n ): void\n static instanceProperty(name: string | symbol, value: unknown): void\n static instanceProperty(name: string | symbol, value: unknown): void {\n if (!Object.prototype.hasOwnProperty.call(this, 'instanceMacros')) {\n this.instanceMacros = new Set(this.instanceMacros)\n }\n this.instanceMacros.add({ key: name, value })\n }\n\n // ── Getters (Object.defineProperty on prototype) ──────────\n\n /**\n * Register a computed getter on the class prototype.\n *\n * @param name - Property name\n * @param accumulator - Function that computes the value (called with instance as `this`)\n * @param singleton - If true, cache the value after first access\n */\n static getter<T extends Constructor, K extends keyof InstanceType<T>>(\n this: T,\n name: K,\n accumulator: (this: InstanceType<T>) => InstanceType<T>[K],\n singleton?: boolean,\n ): void\n static getter(name: string | symbol, accumulator: MacroFunction, singleton?: boolean): void\n static getter(\n name: string | symbol,\n accumulator: MacroFunction,\n singleton = false,\n ): void {\n if (!Object.prototype.hasOwnProperty.call(this, 'getterNames')) {\n this.getterNames = new Set(this.getterNames)\n }\n this.getterNames.add(name)\n\n Object.defineProperty(this.prototype, name, {\n get(): unknown {\n const value: unknown = accumulator.call(this)\n if (singleton) {\n Object.defineProperty(this, name, {\n value,\n configurable: false,\n enumerable: false,\n writable: false,\n })\n }\n return value\n },\n configurable: true,\n enumerable: false,\n })\n }\n\n // ── Introspection ─────────────────────────────────────────\n\n /**\n * Check if a macro, instance property, or getter is registered.\n *\n * @param name - Name to check\n */\n static hasMacro(name: string | symbol): boolean {\n return (\n this.macroNames.has(name) ||\n [...this.instanceMacros].some((m) => m.key === name) ||\n this.getterNames.has(name)\n )\n }\n\n // ── Cleanup ───────────────────────────────────────────────\n\n /**\n * Remove all macros, instance properties, and getters\n * registered on this class. Does not affect parent classes.\n */\n static flushMacros(): void {\n const proto = this.prototype as Record<string | symbol, unknown>\n\n // Restore original prototype values or delete if they didn't exist before\n for (const name of this.macroNames) {\n const original = this._originals.get(name)\n if (original?.existed) {\n proto[name] = original.value\n } else {\n Reflect.deleteProperty(proto, name)\n }\n }\n for (const name of this.getterNames) {\n Reflect.deleteProperty(proto, name)\n }\n\n if (Object.prototype.hasOwnProperty.call(this, 'macroNames')) {\n this.macroNames.clear()\n }\n if (Object.prototype.hasOwnProperty.call(this, 'instanceMacros')) {\n this.instanceMacros.clear()\n }\n if (Object.prototype.hasOwnProperty.call(this, 'getterNames')) {\n this.getterNames.clear()\n }\n if (Object.prototype.hasOwnProperty.call(this, '_originals')) {\n this._originals.clear()\n }\n }\n\n // ── Constructor (applies instance properties) ─────────────\n\n constructor() {\n const Constructor = this.constructor as typeof Macroable\n const self = this as Record<string | symbol, unknown>\n Constructor.instanceMacros.forEach(({ key, value }) => {\n if (typeof value === 'function') {\n self[key] = value.bind(this)\n } else {\n self[key] = value\n }\n })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,IAAsB,YAAtB,MAAgC;;;;;CAM9B,OAAiB,iCAAiB,IAAI,KAA+C;;;;CAKrF,OAAiB,6BAAa,IAAI,KAAsB;;;;CAKxD,OAAiB,8BAAc,IAAI,KAAsB;;;;;CAMzD,OAAe,6BAAa,IAAI,KAA4D;CAmB5F,OAAO,MAAM,MAAuB,OAAsB;AACxD,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,aAAa,CAC3D,MAAK,aAAa,IAAI,IAAI,KAAK,WAAW;AAE5C,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,aAAa,CAC3D,MAAK,aAAa,IAAI,IAAI,KAAK,WAAW;AAI5C,MAAI,CAAC,KAAK,WAAW,IAAI,KAAK,EAAE;GAC9B,MAAM,UAAU,OAAO,UAAU,eAAe,KAAK,KAAK,WAAW,KAAK;AAC1E,QAAK,WAAW,IAAI,MAAM;IACxB;IACA,OAAO,UAAW,KAAK,UAA+C,QAAQ,KAAA;IAC/E,CAAC;;AAGJ,OAAK,WAAW,IAAI,KAAK;AACxB,OAAK,UAA+C,QAAQ;;CAoB/D,OAAO,iBAAiB,MAAuB,OAAsB;AACnE,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,iBAAiB,CAC/D,MAAK,iBAAiB,IAAI,IAAI,KAAK,eAAe;AAEpD,OAAK,eAAe,IAAI;GAAE,KAAK;GAAM;GAAO,CAAC;;CAmB/C,OAAO,OACL,MACA,aACA,YAAY,OACN;AACN,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,cAAc,CAC5D,MAAK,cAAc,IAAI,IAAI,KAAK,YAAY;AAE9C,OAAK,YAAY,IAAI,KAAK;AAE1B,SAAO,eAAe,KAAK,WAAW,MAAM;GAC1C,MAAe;IACb,MAAM,QAAiB,YAAY,KAAK,KAAK;AAC7C,QAAI,UACF,QAAO,eAAe,MAAM,MAAM;KAChC;KACA,cAAc;KACd,YAAY;KACZ,UAAU;KACX,CAAC;AAEJ,WAAO;;GAET,cAAc;GACd,YAAY;GACb,CAAC;;;;;;;CAUJ,OAAO,SAAS,MAAgC;AAC9C,SACE,KAAK,WAAW,IAAI,KAAK,IACzB,CAAC,GAAG,KAAK,eAAe,CAAC,MAAM,MAAM,EAAE,QAAQ,KAAK,IACpD,KAAK,YAAY,IAAI,KAAK;;;;;;CAU9B,OAAO,cAAoB;EACzB,MAAM,QAAQ,KAAK;AAGnB,OAAK,MAAM,QAAQ,KAAK,YAAY;GAClC,MAAM,WAAW,KAAK,WAAW,IAAI,KAAK;AAC1C,OAAI,UAAU,QACZ,OAAM,QAAQ,SAAS;OAEvB,SAAQ,eAAe,OAAO,KAAK;;AAGvC,OAAK,MAAM,QAAQ,KAAK,YACtB,SAAQ,eAAe,OAAO,KAAK;AAGrC,MAAI,OAAO,UAAU,eAAe,KAAK,MAAM,aAAa,CAC1D,MAAK,WAAW,OAAO;AAEzB,MAAI,OAAO,UAAU,eAAe,KAAK,MAAM,iBAAiB,CAC9D,MAAK,eAAe,OAAO;AAE7B,MAAI,OAAO,UAAU,eAAe,KAAK,MAAM,cAAc,CAC3D,MAAK,YAAY,OAAO;AAE1B,MAAI,OAAO,UAAU,eAAe,KAAK,MAAM,aAAa,CAC1D,MAAK,WAAW,OAAO;;CAM3B,cAAc;EACZ,MAAM,cAAc,KAAK;EACzB,MAAM,OAAO;AACb,cAAY,eAAe,SAAS,EAAE,KAAK,YAAY;AACrD,OAAI,OAAO,UAAU,WACnB,MAAK,OAAO,MAAM,KAAK,KAAK;OAE5B,MAAK,OAAO;IAEd"}
|
package/dist/module/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Cn as
|
|
2
|
-
import { t as Constructor } from "../types-
|
|
1
|
+
import { $t as ModuleRegistry, Cn as OnInitialize, Dn as ValueProvider, En as RegistryEntry, Sn as OnException, Tn as Provider, _n as FactoryProvider, bn as ModuleContext, gn as ExistingProvider, hn as DynamicModule, mn as ClassProvider, pn as AsyncModuleOptions, vn as InjectionToken, wn as OnShutdown, xn as ModuleOptions, yn as ModuleClass } from "../index-DPFqRs8L.mjs";
|
|
2
|
+
import { t as Constructor } from "../types-DIWemRad.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/module/module.decorator.d.ts
|
|
5
5
|
declare const MODULE_OPTIONS_KEY: unique symbol;
|
package/dist/module/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as Module, S as MODULE_OPTIONS_KEY, T as isModuleClass, t as ModuleRegistry, w as getModuleOptions } from "../module-qGE_1duv.mjs";
|
|
2
2
|
export { MODULE_OPTIONS_KEY, Module, ModuleRegistry, getModuleOptions, isModuleClass };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as Scope, H as ApplicationError, S as HttpException, k as ERROR_CODES } from "./errors
|
|
2
|
-
import { a as isListener } from "./events-
|
|
3
|
-
import { t as isCommand } from "./is-command-
|
|
4
|
-
import { t as isSeeder } from "./is-seeder-
|
|
1
|
+
import { A as Scope, H as ApplicationError, S as HttpException, k as ERROR_CODES } from "./errors-B4pYgYON.mjs";
|
|
2
|
+
import { a as isListener } from "./events-COKixqnG.mjs";
|
|
3
|
+
import { t as isCommand } from "./is-command-C6a7WTPw.mjs";
|
|
4
|
+
import { t as isSeeder } from "./is-seeder-CebjZCDn.mjs";
|
|
5
5
|
import { injectable, instancePerContainerCachingFactory, registry } from "tsyringe";
|
|
6
6
|
//#region src/module/errors/invalid-module-provider.error.ts
|
|
7
7
|
/**
|
|
@@ -312,6 +312,17 @@ var RouterUseScopeError = class extends ApplicationError {
|
|
|
312
312
|
super("errors.routerUseScopeViolation", ERROR_CODES.ROUTER.USE_SCOPE_VIOLATION);
|
|
313
313
|
}
|
|
314
314
|
};
|
|
315
|
+
/**
|
|
316
|
+
* Thrown when a middleware calls next() more than once.
|
|
317
|
+
* This is a programming error — each middleware must call next() at most once.
|
|
318
|
+
*
|
|
319
|
+
* Error Code: 9014
|
|
320
|
+
*/
|
|
321
|
+
var MiddlewareNextCalledMultipleTimesError = class extends ApplicationError {
|
|
322
|
+
constructor(middlewareName) {
|
|
323
|
+
super("errors.middlewareNextCalledMultipleTimes", ERROR_CODES.ROUTER.MIDDLEWARE_NEXT_CALLED_MULTIPLE_TIMES, { middlewareName });
|
|
324
|
+
}
|
|
325
|
+
};
|
|
315
326
|
//#endregion
|
|
316
327
|
//#region src/router/router.internals.ts
|
|
317
328
|
/**
|
|
@@ -514,17 +525,6 @@ var ModuleRegistry = class {
|
|
|
514
525
|
for (const registered of this.modules) {
|
|
515
526
|
const instance = new registered.moduleClass();
|
|
516
527
|
registered.instance = instance;
|
|
517
|
-
if (this.hasRouteConfigurable(instance)) {
|
|
518
|
-
this.logger.debug(`Configuring routes for: ${registered.moduleClass.name}`);
|
|
519
|
-
const router = new Router();
|
|
520
|
-
instance.configureRoutes(router);
|
|
521
|
-
const moduleControllers = registered.options.controllers ?? [];
|
|
522
|
-
this.allRouterConfigs.push({
|
|
523
|
-
router,
|
|
524
|
-
controllers: moduleControllers
|
|
525
|
-
});
|
|
526
|
-
this.logger.debug(`Collected route config from ${registered.moduleClass.name} (${moduleControllers.length} controllers)`);
|
|
527
|
-
}
|
|
528
528
|
if (this.hasOnInitialize(instance)) {
|
|
529
529
|
this.logger.info(`Initializing: ${registered.moduleClass.name}`);
|
|
530
530
|
await instance.onInitialize(context);
|
|
@@ -570,9 +570,22 @@ var ModuleRegistry = class {
|
|
|
570
570
|
return this.allSeeders;
|
|
571
571
|
}
|
|
572
572
|
/**
|
|
573
|
-
* Get all Router configurations from modules implementing RouteConfigurable
|
|
573
|
+
* Get all Router configurations from modules implementing RouteConfigurable.
|
|
574
|
+
* Runs configureRoutes() lazily on first call (deferred from initialize()).
|
|
574
575
|
*/
|
|
575
576
|
getAllRouterConfigs() {
|
|
577
|
+
if (this.allRouterConfigs.length === 0) {
|
|
578
|
+
for (const { moduleClass, options, instance } of this.modules) if (instance && this.hasRouteConfigurable(instance)) {
|
|
579
|
+
this.logger.debug(`Configuring routes for: ${moduleClass.name}`);
|
|
580
|
+
const router = new Router();
|
|
581
|
+
instance.configureRoutes(router);
|
|
582
|
+
const moduleControllers = options.controllers ?? [];
|
|
583
|
+
this.allRouterConfigs.push({
|
|
584
|
+
router,
|
|
585
|
+
controllers: moduleControllers
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
576
589
|
return this.allRouterConfigs;
|
|
577
590
|
}
|
|
578
591
|
/**
|
|
@@ -714,6 +727,6 @@ var ModuleRegistry = class {
|
|
|
714
727
|
}
|
|
715
728
|
};
|
|
716
729
|
//#endregion
|
|
717
|
-
export {
|
|
730
|
+
export { Module as C, MODULE_OPTIONS_KEY as S, isModuleClass as T, OpenAPIValidationError as _, getGroups as a, ControllerRegistrationError as b, InvalidSignatureError as c, MissingRouteParamError as d, ResponseValidationError as f, RouteNotFoundError as g, SchemaValidationError as h, getGlobalMiddleware as i, MiddlewareNextCalledMultipleTimesError as l, RouterUseScopeError as m, Router as n, DomainMismatchError as o, RouteNameNotFoundError as p, getDefaultEntry as r, DuplicateRouteNameError as s, ModuleRegistry as t, MissingEnvironmentVariableError as u, OpenAPIRouteRegistrationError as v, getModuleOptions as w, ControllerMethodNotFoundError as x, HonoAppAlreadyConfiguredError as y };
|
|
718
731
|
|
|
719
|
-
//# sourceMappingURL=module-
|
|
732
|
+
//# sourceMappingURL=module-qGE_1duv.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-qGE_1duv.mjs","names":["internal.getDefaultEntry","internal.getGroups","internal.getGlobalMiddleware"],"sources":["../src/module/errors/invalid-module-provider.error.ts","../src/module/module.decorator.ts","../src/router/errors/controller-method-not-found.error.ts","../src/router/errors/controller-registration.error.ts","../src/router/errors/hono-app-already-configured.error.ts","../src/router/errors/openapi-route-registration.error.ts","../src/router/errors/openapi-validation.error.ts","../src/router/errors/route-not-found.error.ts","../src/router/errors/schema-validation.error.ts","../src/router/errors/index.ts","../src/router/router.internals.ts","../src/router/router.ts","../src/module/module-registry.ts"],"sourcesContent":["import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * InvalidModuleProviderError\n *\n * Thrown when a module provider configuration is invalid.\n * This indicates a misconfiguration in the @Module decorator providers array.\n */\nexport class InvalidModuleProviderError extends ApplicationError {\n constructor(provider: unknown) {\n super(\n 'errors.invalidModuleProvider',\n ERROR_CODES.SYSTEM.INVALID_MODULE_PROVIDER,\n { provider: JSON.stringify(provider) }\n )\n }\n}\n","/**\n * Module Decorator\n *\n * NestJS-style @Module decorator for defining modules with providers, controllers, etc.\n * Encapsulates tsyringe's @registry decorator for auto-registration.\n */\n\nimport type { DependencyContainer, Provider as TsyringeProvider } from 'tsyringe'\nimport { instancePerContainerCachingFactory, type Lifecycle, registry } from 'tsyringe'\nimport type InjectionToken from 'tsyringe/dist/typings/providers/injection-token'\nimport type RegistrationOptions from 'tsyringe/dist/typings/types/registration-options'\nimport type { Constructor } from '../types'\nimport { InvalidModuleProviderError } from './errors'\nimport type { ModuleOptions, Provider } from './types'\n\nexport const MODULE_OPTIONS_KEY = Symbol.for('stratal:module:options')\n\n/**\n * Tsyringe registry entry format\n */\ntype RegistryEntry = {\n token: InjectionToken\n options?: RegistrationOptions\n} & TsyringeProvider\n\n/**\n * `@Module` decorator - defines a module with imports, providers, controllers, consumers, jobs\n *\n * Uses tsyringe's `@registry` internally to auto-register providers when module is imported.\n *\n * @example\n * ```typescript\n * @Module({\n * imports: [OtherModule],\n * providers: [MyService, MyRepository],\n * controllers: [MyController],\n * })\n * export class MyModule {}\n * ```\n */\nexport function Module(options: ModuleOptions) {\n return <TFunction extends abstract new (...args: never[]) => unknown>(target: TFunction): TFunction => {\n // Store module options for runtime access\n Reflect.defineMetadata(MODULE_OPTIONS_KEY, options, target)\n\n // Build tsyringe registry entries from providers\n const registryEntries = buildRegistryEntries(options.providers ?? [])\n\n // Apply tsyringe @registry decorator (encapsulated)\n if (registryEntries.length > 0) {\n registry(registryEntries)(target)\n }\n\n return target\n }\n}\n\n/**\n * Get module options from decorated class\n */\nexport function getModuleOptions(target: Constructor): ModuleOptions | undefined {\n return Reflect.getMetadata(MODULE_OPTIONS_KEY, target) as ModuleOptions | undefined\n}\n\n/**\n * Check if a class is decorated with `@Module`\n */\nexport function isModuleClass(target: unknown): target is Constructor {\n return (\n typeof target === 'function' &&\n Reflect.hasMetadata(MODULE_OPTIONS_KEY, target)\n )\n}\n\n/**\n * Convert our Provider types to tsyringe registry format\n *\n * Maps provider scope to tsyringe's lifecycle option.\n * Scope enum values map directly to Lifecycle enum values.\n */\nfunction buildRegistryEntries(providers: Provider[]): RegistryEntry[] {\n return providers.map((provider): RegistryEntry => {\n // Class-only provider - transient by default\n if (typeof provider === 'function') {\n return {\n token: provider as InjectionToken,\n useClass: provider,\n }\n }\n\n // ClassProvider with optional scope\n if ('useClass' in provider) {\n return {\n token: provider.provide as InjectionToken,\n useClass: provider.useClass,\n options: provider.scope !== undefined\n ? { lifecycle: provider.scope as unknown as Lifecycle }\n : undefined,\n }\n }\n\n // ValueProvider - no scope needed (values are inherently singleton)\n if ('useValue' in provider) {\n return {\n token: provider.provide as InjectionToken,\n useValue: provider.useValue,\n }\n }\n\n // FactoryProvider - use instancePerContainerCachingFactory to:\n // 1. Get the actual container at resolution time (global vs request)\n // 2. Cache result per container\n if ('useFactory' in provider) {\n const { provide, useFactory, inject = [] } = provider\n return {\n token: provide as InjectionToken,\n useFactory: instancePerContainerCachingFactory((dependencyContainer: DependencyContainer): object => {\n const deps = inject.map((token) => dependencyContainer.resolve(token))\n return useFactory(...deps) as object\n }),\n }\n }\n\n // ExistingProvider - alias to another token (uses tsyringe's useToken)\n if ('useExisting' in provider) {\n return {\n token: provider.provide as InjectionToken,\n useToken: provider.useExisting as InjectionToken,\n }\n }\n\n // Fallback (should not reach here with proper types)\n throw new InvalidModuleProviderError(provider)\n })\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * ControllerMethodNotFoundError\n *\n * Thrown when a controller method is registered but doesn't exist on the controller instance.\n * This typically indicates a mismatch between route registration and controller implementation.\n */\nexport class ControllerMethodNotFoundError extends ApplicationError {\n constructor(methodName: string, controllerName: string) {\n super(\n 'errors.controllerMethodNotFound',\n ERROR_CODES.ROUTER.CONTROLLER_METHOD_NOT_FOUND,\n { methodName, controllerName }\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * Error thrown when a controller fails to register\n *\n * This typically happens when:\n * - Controller is missing the `@Controller` decorator\n * - Controller route metadata is not set\n * - Controller class name is invalid\n *\n * Error Code: 9005\n */\nexport class ControllerRegistrationError extends ApplicationError {\n constructor(controllerName: string, reason?: string) {\n super('errors.controllerRegistration', ERROR_CODES.ROUTER.CONTROLLER_REGISTRATION_ERROR, {\n controllerName,\n reason,\n })\n }\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * Error thrown when HonoApp.configure() is called more than once.\n *\n * HonoApp can only be configured a single time during application bootstrap.\n */\nexport class HonoAppAlreadyConfiguredError extends ApplicationError {\n constructor() {\n super(\n 'errors.honoAppAlreadyConfigured',\n ERROR_CODES.SYSTEM.CONFIGURATION_ERROR\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * OpenAPIRouteRegistrationError\n *\n * Thrown when an OpenAPI route fails to register properly\n * This indicates a configuration issue with route decorators or metadata\n * Uses i18n key for localized error messages\n *\n * @example\n * ```typescript\n * throw new OpenAPIRouteRegistrationError('/api/v1/users', 'Missing response schema')\n * ```\n */\nexport class OpenAPIRouteRegistrationError extends ApplicationError {\n constructor(path: string, reason: string) {\n super(\n 'errors.openapiRouteRegistration',\n ERROR_CODES.ROUTER.OPENAPI_ROUTE_REGISTRATION,\n { path, reason }\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * OpenAPIValidationError\n *\n * Thrown when OpenAPI request/response validation fails\n * Uses i18n key for localized error messages\n *\n * HTTP Status: 400 Bad Request\n * Error Code: 1004\n *\n * @example\n * ```typescript\n * throw new OpenAPIValidationError('Request body missing required field: email')\n * ```\n */\nexport class OpenAPIValidationError extends ApplicationError {\n constructor(details: string) {\n super(\n 'errors.openapiValidation',\n ERROR_CODES.VALIDATION.REQUEST_VALIDATION,\n { details }\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * Error thrown when a requested route is not found\n *\n * HTTP Status: 404 Not Found\n * Error Code: 4004\n */\nexport class RouteNotFoundError extends ApplicationError {\n constructor(path: string, method: string) {\n super(\n 'errors.routeNotFound',\n ERROR_CODES.RESOURCE.ROUTE_NOT_FOUND,\n { path, method }\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors';\nimport type { ZodError } from '../../i18n/validation';\nimport { type z } from '../../i18n/validation';\n/**\n * SchemaValidationError\n *\n * Thrown when Zod schema validation fails\n */\nexport class SchemaValidationError extends ApplicationError {\n constructor(zodError: ZodError) {\n const issues = zodError.issues.map((err: z.core.$ZodIssue) => ({\n path: err.path.join('.'),\n message: err.message,\n code: err.code\n }))\n\n super(\n 'errors.schemaValidation',\n ERROR_CODES.VALIDATION.SCHEMA_VALIDATION,\n { issues }\n )\n }\n}\n","import { ApplicationError, ERROR_CODES, HttpException } from '../../errors'\nimport { type z, type ZodError } from '../../i18n/validation'\n\nexport { ControllerMethodNotFoundError } from './controller-method-not-found.error'\n\nexport { ControllerRegistrationError } from './controller-registration.error'\n\n/**\n * Error thrown when a request's host header does not match the expected domain pattern.\n *\n * HTTP Status: 404 Not Found\n */\nexport class DomainMismatchError extends HttpException {\n constructor() {\n super(404, 'errors.domainMismatch')\n }\n}\n\n/**\n * Thrown when registering a named route that conflicts with an existing route name.\n *\n * Error Code: 9010\n */\nexport class DuplicateRouteNameError extends ApplicationError {\n constructor(name: string, existingHandler: string, newHandler: string) {\n super('errors.duplicateRouteName', ERROR_CODES.ROUTER.DUPLICATE_ROUTE_NAME, {\n name,\n existingHandler,\n newHandler,\n })\n }\n}\n\nexport { HonoAppAlreadyConfiguredError } from './hono-app-already-configured.error'\n\n/**\n * Error thrown when a signed URL has an invalid or expired signature.\n *\n * HTTP Status: 403 Forbidden\n */\nexport class InvalidSignatureError extends HttpException {\n constructor() {\n super(403, 'errors.invalidSignature')\n }\n}\n\n/**\n * Thrown when a required environment variable is not set.\n *\n * Maps to HTTP 500 via error code range (9xxx → 500).\n */\nexport class MissingEnvironmentVariableError extends ApplicationError {\n constructor(variable: string) {\n super('errors.missingEnvironmentVariable', ERROR_CODES.SYSTEM.MISSING_ENVIRONMENT_VARIABLE, {\n variable,\n })\n }\n}\n\n/**\n * Thrown when a required path or domain parameter is missing during URL generation.\n *\n * Error Code: 9012\n */\nexport class MissingRouteParamError extends ApplicationError {\n constructor(param: string, name: string, path: string) {\n super('errors.missingRouteParam', ERROR_CODES.ROUTER.MISSING_ROUTE_PARAM, {\n param,\n name,\n path,\n })\n }\n}\n\nexport { OpenAPIRouteRegistrationError } from './openapi-route-registration.error'\nexport { OpenAPIValidationError } from './openapi-validation.error'\n\n/**\n * ResponseValidationError\n *\n * Thrown when a controller's response body does not match the declared Zod response schema.\n * Indicates a server-side schema mismatch — the controller is returning data that\n * violates its own API contract.\n */\nexport class ResponseValidationError extends ApplicationError {\n constructor(zodError: ZodError) {\n const issues = zodError.issues.map((err: z.core.$ZodIssue) => ({\n path: err.path.join('.'),\n message: err.message,\n code: err.code,\n }))\n\n super(\n 'errors.responseValidation',\n ERROR_CODES.VALIDATION.RESPONSE_VALIDATION,\n { issues }\n )\n }\n}\n\n/**\n * Thrown when attempting to generate a URL for a route name that doesn't exist in the registry.\n *\n * Error Code: 9011\n */\nexport class RouteNameNotFoundError extends ApplicationError {\n constructor(name: string) {\n super('errors.routeNameNotFound', ERROR_CODES.ROUTER.ROUTE_NAME_NOT_FOUND, {\n name,\n })\n }\n}\n\nexport { RouteNotFoundError } from './route-not-found.error'\n\n/**\n * Thrown when `router.use()` is called inside a `group()` callback.\n * `use()` registers global middleware and is only allowed on the root Router.\n *\n * Error Code: 9013\n */\nexport class RouterUseScopeError extends ApplicationError {\n constructor() {\n super('errors.routerUseScopeViolation', ERROR_CODES.ROUTER.USE_SCOPE_VIOLATION)\n }\n}\n\n/**\n * Thrown when a middleware calls next() more than once.\n * This is a programming error — each middleware must call next() at most once.\n *\n * Error Code: 9014\n */\nexport class MiddlewareNextCalledMultipleTimesError extends ApplicationError {\n constructor(middlewareName: string) {\n super('errors.middlewareNextCalledMultipleTimes', ERROR_CODES.ROUTER.MIDDLEWARE_NEXT_CALLED_MULTIPLE_TIMES, {\n middlewareName,\n })\n }\n}\n\nexport { SchemaValidationError } from './schema-validation.error'\n","/**\n * Symbol keys for Router internal accessors.\n *\n * These symbols are NOT exported from the public `stratal/router` barrel.\n * Only internal modules (RouterResolver) import them, keeping the Router's\n * public API clean — users never see these methods.\n *\n * Declared as individual unique symbols so TypeScript can distinguish\n * their return types in computed property access.\n *\n * @internal\n */\n\n/** @internal */\nexport const getDefaultEntry: unique symbol = Symbol('Router.getDefaultEntry')\n/** @internal */\nexport const getGroups: unique symbol = Symbol('Router.getGroups')\n/** @internal */\nexport const getGlobalMiddleware: unique symbol = Symbol('Router.getGlobalMiddleware')\n","import type { ZodObject } from '../i18n/validation'\nimport type { Constructor } from '../types'\nimport { RouterUseScopeError } from './errors'\nimport type { Middleware } from './middleware.interface'\nimport * as internal from './router.internals'\n\n/**\n * Configuration for a sub-group created via `router.group()`.\n */\nexport interface RouterGroupConfig {\n prefix?: string\n domain?: string\n name?: string\n middleware?: Constructor<Middleware>[]\n version?: string | string[]\n hideFromDocs?: boolean\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ZodObject generics require any for flexible shape parameter\n params?: ZodObject<any>\n}\n\n/**\n * Internal entry representing a sub-group or the default scope.\n * @internal — used by RouterResolver, not exported publicly.\n */\nexport interface RouterEntry {\n prefix?: string\n domain?: string\n name?: string\n middleware: Constructor<Middleware>[]\n version?: string | string[]\n hideFromDocs?: boolean\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ZodObject generics require any for flexible shape parameter\n params?: ZodObject<any>\n /** Controllers in this entry. undefined = all controllers not in any sub-group */\n controllers?: Constructor[]\n}\n\n/**\n * Modules implement this to configure routes and middleware.\n * Replaces `MiddlewareConfigurable`.\n *\n * @example\n * ```typescript\n * @Module({ controllers: [UsersController, PostsController] })\n * export class ApiModule implements RouteConfigurable {\n * configureRoutes(router: Router): void {\n * router\n * .name('api.')\n * .middleware(CorsMiddleware)\n * .version('1')\n * }\n * }\n * ```\n */\nexport interface RouteConfigurable {\n configureRoutes(router: Router): void\n}\n\n/**\n * Fluent builder for route and middleware configuration.\n *\n * Scoped methods (`middleware()`, `prefix()`, `domain()`, `name()`, `version()`, `hideFromDocs()`)\n * apply only to this module's controllers or the sub-group's controllers.\n *\n * `use()` registers global middleware (all routes in the entire app).\n * Only callable on the root Router — throws inside `group()` callbacks.\n *\n * `group()` creates sub-groups for specific controllers with a callback.\n * Controllers in a sub-group are excluded from the parent scope.\n */\nexport class Router {\n private readonly _isChild: boolean\n private readonly _defaultEntry: RouterEntry = { middleware: [] }\n private readonly _groups: RouterEntry[] = []\n private readonly _globalMiddleware: Constructor<Middleware>[] = []\n\n constructor(isChild = false) {\n this._isChild = isChild\n }\n\n /** Dynamic path prefix. For shared segments like `/:companyId` */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ZodObject generics require any for flexible shape parameter\n prefix(path: string, params?: ZodObject<any>): this {\n this._defaultEntry.prefix = path\n this._defaultEntry.params = params\n return this\n }\n\n /** Domain pattern for controllers in this scope */\n domain(pattern: string): this {\n this._defaultEntry.domain = pattern\n return this\n }\n\n /** Name prefix for routes in this scope */\n name(prefix: string): this {\n this._defaultEntry.name = prefix\n return this\n }\n\n /** Middleware applied to controllers in this scope */\n middleware(...middlewares: Constructor<Middleware>[]): this {\n this._defaultEntry.middleware.push(...middlewares)\n return this\n }\n\n /** API version for controllers in this scope */\n version(version: string | string[]): this {\n this._defaultEntry.version = version\n return this\n }\n\n /** Hide/show routes in this scope from OpenAPI docs */\n hideFromDocs(hide = true): this {\n this._defaultEntry.hideFromDocs = hide\n return this\n }\n\n /**\n * Global middleware — applied to ALL routes in the entire app.\n * Only callable on the root Router. Throws if called inside `group()`.\n */\n use(...middlewares: Constructor<Middleware>[]): this {\n if (this._isChild) {\n throw new RouterUseScopeError()\n }\n this._globalMiddleware.push(...middlewares)\n return this\n }\n\n /**\n * Create a sub-group for specific controllers/gateways.\n * Controllers in a sub-group are excluded from the parent (default) scope.\n * The callback receives a new Router (without `use()`) for fluent configuration.\n */\n group(controllers: Constructor[], callback: (router: Omit<Router, 'use'>) => void): this {\n const childRouter = new Router(true)\n callback(childRouter)\n\n this._groups.push({\n ...childRouter._defaultEntry,\n controllers,\n })\n return this\n }\n\n // --- Internal accessors via symbol keys (invisible to consumers) ---\n\n [internal.getDefaultEntry](): RouterEntry {\n return this._defaultEntry\n }\n\n [internal.getGroups](): RouterEntry[] {\n return this._groups\n }\n\n [internal.getGlobalMiddleware](): Constructor<Middleware>[] {\n return this._globalMiddleware\n }\n}\n","/**\n * Module Registry\n *\n * Manages module lifecycle for the @Module decorator pattern.\n * Simplified for tsyringe's flat container model:\n * - Imports are traversed for registration (organization only)\n * - Modules registered in declaration order\n * - Lifecycle hooks: onInitialize, onShutdown\n */\n\nimport { injectable, instancePerContainerCachingFactory } from 'tsyringe'\nimport type { Container } from '../di/container'\nimport { Scope } from '../di/types'\nimport { isListener } from '../events'\nimport type { LoggerService } from '../logger'\nimport { Router, type RouteConfigurable } from '../router/router'\nimport { isCommand } from '../quarry/is-command'\nimport { isSeeder } from '../seeder/is-seeder'\nimport type { Constructor } from '../types'\nimport { getModuleOptions } from './module.decorator'\nimport type { ExceptionHandler } from '../errors/exception-handler'\nimport type {\n DynamicModule,\n ModuleClass,\n ModuleContext,\n ModuleOptions,\n OnException,\n OnInitialize,\n OnShutdown,\n Provider,\n} from './types'\n\n\ninterface RegisteredModule {\n moduleClass: Constructor\n options: ModuleOptions\n instance: object | null\n}\n\n/**\n * ModuleRegistry - manages module lifecycle\n *\n * @example\n * ```typescript\n * const registry = new ModuleRegistry(container, logger)\n * registry.register(AppModule) // Traverses imports recursively\n * await registry.initialize()\n * // ... application running ...\n * await registry.shutdown()\n * ```\n */\nexport class ModuleRegistry {\n private modules: RegisteredModule[] = []\n private registeredClasses = new Set<Constructor>()\n private initialized = false\n\n // Collected items from all modules for Application to use\n private allControllers: Constructor[] = []\n private allConsumers: Constructor[] = []\n private allJobs: Constructor[] = []\n private allListeners: Constructor[] = []\n private allCommands: Constructor[] = []\n private allSeeders: Constructor[] = []\n private allRouterConfigs: { router: Router; controllers: Constructor[] }[] = []\n\n constructor(\n private readonly container: Container,\n private readonly logger: LoggerService\n ) { }\n\n /**\n * Register a module (static or dynamic)\n *\n * @param moduleOrDynamic - Module class decorated with `@Module` or DynamicModule from configure()\n */\n register(moduleOrDynamic: ModuleClass | DynamicModule): void {\n const { moduleClass, options } = this.resolveModule(moduleOrDynamic)\n const isDynamic = this.isDynamicModule(moduleOrDynamic)\n\n // Check for duplicate registration\n if (this.registeredClasses.has(moduleClass)) {\n // For DynamicModules: Still register the additional providers\n // This allows forRoot() to add configuration even if base module is registered\n if (isDynamic) {\n this.logger.debug(`Module ${moduleClass.name} already registered, registering DynamicModule providers`)\n const { module: _, ...dynamicRest } = moduleOrDynamic\n for (const provider of dynamicRest.providers ?? []) {\n this.registerProvider(provider)\n }\n } else {\n this.logger.debug(`Module ${moduleClass.name} already registered, skipping`)\n }\n return\n }\n\n this.registeredClasses.add(moduleClass)\n this.logger.info(`Registering module: ${moduleClass.name}`)\n\n // First, register imported modules recursively\n for (const ImportedModule of options.imports ?? []) {\n this.register(ImportedModule)\n }\n\n // Register providers in container\n for (const provider of options.providers ?? []) {\n this.registerProvider(provider)\n }\n\n // Register controllers and collect them\n for (const controller of options.controllers ?? []) {\n this.container.register(controller)\n this.allControllers.push(controller)\n }\n\n // Register consumers as singletons by default and collect them\n for (const consumer of options.consumers ?? []) {\n this.container.register(consumer, Scope.Singleton)\n this.allConsumers.push(consumer)\n this.logger.info(`Collected consumer: ${consumer.name}`, { queueCount: this.allConsumers.length })\n }\n\n // Register jobs as singletons by default and collect them\n for (const job of options.jobs ?? []) {\n this.container.register(job, Scope.Singleton)\n this.allJobs.push(job)\n }\n\n this.modules.push({ moduleClass, options, instance: null })\n }\n\n /**\n * Register multiple modules in order\n */\n registerAll(modules: (ModuleClass | DynamicModule)[]): void {\n for (const module of modules) {\n this.register(module)\n }\n }\n\n /**\n * Initialize all modules (call configure and onInitialize hooks)\n */\n async initialize(): Promise<void> {\n if (this.initialized) return\n\n this.logger.info('Initializing modules...')\n\n const context: ModuleContext = {\n container: this.container,\n logger: this.logger,\n }\n\n for (const registered of this.modules) {\n // Instantiate module class\n const instance = new registered.moduleClass()\n registered.instance = instance\n\n // Call onInitialize if implemented\n if (this.hasOnInitialize(instance)) {\n this.logger.info(`Initializing: ${registered.moduleClass.name}`)\n await instance.onInitialize(context)\n }\n }\n\n this.initialized = true\n this.logger.info('All modules initialized')\n }\n\n /**\n * Get all controllers registered from all modules\n */\n getAllControllers(): Constructor[] {\n return this.allControllers\n }\n\n /**\n * Get all consumers registered from all modules\n */\n getAllConsumers(): Constructor[] {\n return this.allConsumers\n }\n\n /**\n * Get all jobs registered from all modules\n */\n getAllJobs(): Constructor[] {\n return this.allJobs\n }\n\n /**\n * Get all listeners registered from all modules\n */\n getAllListeners(): Constructor[] {\n return this.allListeners\n }\n\n /**\n * Get all commands registered from all modules\n */\n getAllCommands(): Constructor[] {\n return this.allCommands\n }\n\n /**\n * Get all seeders registered from all modules\n */\n getAllSeeders(): Constructor[] {\n return this.allSeeders\n }\n\n /**\n * Get all Router configurations from modules implementing RouteConfigurable.\n * Runs configureRoutes() lazily on first call (deferred from initialize()).\n */\n getAllRouterConfigs(): { router: Router; controllers: Constructor[] }[] {\n if (this.allRouterConfigs.length === 0) {\n for (const { moduleClass, options, instance } of this.modules) {\n if (instance && this.hasRouteConfigurable(instance)) {\n this.logger.debug(`Configuring routes for: ${moduleClass.name}`)\n const router = new Router()\n instance.configureRoutes(router)\n const moduleControllers = options.controllers ?? []\n this.allRouterConfigs.push({ router, controllers: moduleControllers })\n }\n }\n }\n return this.allRouterConfigs\n }\n\n /**\n * Call `onException()` on all modules that implement the OnException interface.\n * Invoked by Application after the ExceptionHandler is resolved and `register()` is called.\n *\n * @param handler - The resolved ExceptionHandler instance\n */\n configureExceptionHandlers(handler: ExceptionHandler): void {\n for (const { moduleClass, instance } of this.modules) {\n if (instance && this.hasOnException(instance)) {\n this.logger.debug(`Configuring exception handlers for: ${moduleClass.name}`)\n instance.onException(handler)\n }\n }\n }\n\n /**\n * Shutdown all modules (call onShutdown hooks in reverse order)\n */\n async shutdown(): Promise<void> {\n this.logger.info('Shutting down modules...')\n\n const context: ModuleContext = {\n container: this.container,\n logger: this.logger,\n }\n\n // Reverse order for shutdown\n const reversed = [...this.modules].reverse()\n\n for (const { moduleClass, instance } of reversed) {\n if (instance && this.hasOnShutdown(instance)) {\n try {\n await instance.onShutdown(context)\n } catch (error) {\n this.logger.error(`Error shutting down ${moduleClass.name}:`, error as Error)\n }\n }\n }\n\n this.logger.info('All modules shut down')\n }\n\n /**\n * Type guard for RouteConfigurable\n */\n private hasRouteConfigurable(instance: unknown): instance is RouteConfigurable {\n return (\n typeof instance === 'object' &&\n instance !== null &&\n 'configureRoutes' in instance &&\n typeof (instance as RouteConfigurable).configureRoutes === 'function'\n )\n }\n\n /**\n * Type guard for OnInitialize\n */\n private hasOnInitialize(instance: unknown): instance is OnInitialize {\n return (\n typeof instance === 'object' &&\n instance !== null &&\n 'onInitialize' in instance &&\n typeof (instance as OnInitialize).onInitialize === 'function'\n )\n }\n\n /**\n * Type guard for OnShutdown\n */\n private hasOnShutdown(instance: unknown): instance is OnShutdown {\n return (\n typeof instance === 'object' &&\n instance !== null &&\n 'onShutdown' in instance &&\n typeof (instance as OnShutdown).onShutdown === 'function'\n )\n }\n\n /**\n * Type guard for OnException\n */\n private hasOnException(instance: unknown): instance is OnException {\n return (\n typeof instance === 'object' &&\n instance !== null &&\n 'onException' in instance &&\n typeof (instance as OnException).onException === 'function'\n )\n }\n\n /**\n * Resolve module class and options from static or dynamic module\n *\n * For DynamicModules, merges the decorator metadata (consumers, controllers, jobs)\n * with the DynamicModule options (providers, imports). This ensures modules using\n * forRoot/forRootAsync patterns still have their decorator-defined consumers registered.\n */\n private resolveModule(moduleOrDynamic: ModuleClass | DynamicModule): {\n moduleClass: Constructor\n options: ModuleOptions\n } {\n // DynamicModule (from forRoot/forRootAsync) - has module property\n if (this.isDynamicModule(moduleOrDynamic)) {\n const { module: moduleClass, ...dynamicRest } = moduleOrDynamic\n\n // Get decorator options and merge with dynamic options\n // This ensures consumers/controllers/jobs from @Module decorator are included\n const decoratorOptions = getModuleOptions(moduleClass) ?? {}\n const mergedOptions: ModuleOptions = {\n ...decoratorOptions,\n ...dynamicRest,\n // Merge arrays: decorator providers first, then dynamic providers\n providers: [...(decoratorOptions.providers ?? []), ...(dynamicRest.providers ?? [])],\n imports: [...(decoratorOptions.imports ?? [])],\n }\n\n return { moduleClass: moduleClass, options: mergedOptions }\n }\n\n // Static module (decorated with @Module)\n const moduleClass = moduleOrDynamic as Constructor\n const options = getModuleOptions(moduleClass) ?? {}\n return { moduleClass, options }\n }\n\n /**\n * Type guard for DynamicModule\n */\n private isDynamicModule(value: unknown): value is DynamicModule {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'module' in value && // Required property for dynamic modules\n typeof (value as DynamicModule).module === 'function'\n )\n }\n\n /**\n * Register a single provider in the container\n */\n private registerProvider(provider: Provider): void {\n if (typeof provider === 'function') {\n // Class-only provider - transient by default\n this.container.register(provider as Constructor)\n this.collectIfListener(provider as Constructor)\n this.collectIfCommand(provider as Constructor)\n this.collectIfSeeder(provider as Constructor)\n } else if ('useClass' in provider) {\n // ClassProvider with optional scope\n this.container.register(provider.provide, provider.useClass as Constructor, provider.scope)\n this.collectIfListener(provider.useClass as Constructor)\n this.collectIfCommand(provider.useClass as Constructor)\n this.collectIfSeeder(provider.useClass as Constructor)\n } else if ('useValue' in provider) {\n // ValueProvider - no scope needed (values are inherently singleton)\n this.container.registerValue(provider.provide, provider.useValue)\n } else if ('useFactory' in provider) {\n // FactoryProvider - use instancePerContainerCachingFactory to:\n // 1. Get the actual container at resolution time (global vs request)\n // 2. Cache result per container\n const { provide, useFactory, inject = [] } = provider\n this.container.getTsyringeContainer().register(provide, {\n useFactory: instancePerContainerCachingFactory((dependencyContainer) => {\n const deps = inject.map((token) => dependencyContainer.resolve(token))\n return useFactory(...deps)\n })\n })\n } else if ('useExisting' in provider) {\n // ExistingProvider - alias to another token\n this.container.registerExisting(provider.provide, provider.useExisting)\n }\n }\n\n /**\n * Check if a class is a `Command` and collect it for auto-wiring\n */\n private collectIfCommand(providerClass: Constructor): void {\n if (isCommand(providerClass) && !this.allCommands.includes(providerClass)) {\n injectable()(providerClass)\n this.allCommands.push(providerClass)\n this.logger.debug(`Collected command: ${providerClass.name}`)\n }\n }\n\n /**\n * Check if a class is a `Seeder` and collect it for auto-wiring\n */\n private collectIfSeeder(providerClass: Constructor): void {\n if (isSeeder(providerClass) && !this.allSeeders.includes(providerClass)) {\n this.allSeeders.push(providerClass)\n this.logger.debug(`Collected seeder: ${providerClass.name}`)\n }\n }\n\n /**\n * Check if a class is a `@Listener()` and collect it for auto-wiring\n */\n private collectIfListener(providerClass: Constructor): void {\n if (isListener(providerClass)) {\n // Re-register as singleton so the same instance is used across all event registrations\n this.container.register(providerClass, providerClass, Scope.Singleton)\n this.allListeners.push(providerClass)\n this.logger.debug(`Collected listener: ${providerClass.name}`)\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/openapi/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as OpenAPIObject, r as PathItemObject } from "../index-
|
|
3
|
-
import { t as OpenAPIService } from "../openapi.service-
|
|
1
|
+
import { Xn as RouterEnv, hn as DynamicModule, pn as AsyncModuleOptions } from "../index-DPFqRs8L.mjs";
|
|
2
|
+
import { n as OpenAPIObject, r as PathItemObject } from "../index-B437eK7p.mjs";
|
|
3
|
+
import { t as OpenAPIService } from "../openapi.service-Bv_NioM9.mjs";
|
|
4
4
|
import { MiddlewareHandler } from "hono/types";
|
|
5
5
|
|
|
6
6
|
//#region src/openapi/types.d.ts
|
package/dist/openapi/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as OPENAPI_TOKENS, t as OpenApiToolsService } from "../openapi-tools.service-
|
|
1
|
+
import { A as OpenAPIModule, V as OpenAPIConfigService, j as OpenAPIService } from "../i18n.module-CI_prYFD.mjs";
|
|
2
|
+
import { n as OPENAPI_TOKENS, t as OpenApiToolsService } from "../openapi-tools.service-CYWGuhue.mjs";
|
|
3
3
|
export { OPENAPI_TOKENS, OpenAPIConfigService, OpenAPIModule, OpenAPIService, OpenApiToolsService };
|