moost 0.6.18 → 0.6.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _wooksjs_event_core from '@wooksjs/event-core';
2
- import { EventContext, Logger } from '@wooksjs/event-core';
2
+ import { EventContext, Logger, Key } from '@wooksjs/event-core';
3
3
  export { Cached, ContextInjector, EventContext, EventContextOptions, Key, Logger, cached, createEventContext, current, eventTypeKey, getContextInjector, key, replaceContextInjector, resetContextInjector, run, useLogger } from '@wooksjs/event-core';
4
- import { TProvideRegistry, Infact, TReplaceRegistry, TProvideFn } from '@prostojs/infact';
4
+ import { TProvideRegistry, TReplaceRegistry, Infact, TProvideFn } from '@prostojs/infact';
5
5
  export { TProvideRegistry, createProvideRegistry, createReplaceRegistry } from '@prostojs/infact';
6
6
  import * as _prostojs_mate from '@prostojs/mate';
7
7
  import { TMateParamMeta, Mate } from '@prostojs/mate';
@@ -131,13 +131,46 @@ declare function ImportController(controller: TFunction | TObject, provide?: TPr
131
131
  */
132
132
  declare function ImportController(prefix: string, controller: TFunction | TObject, provide?: TProvideRegistry): ClassDecorator;
133
133
 
134
- /**
135
- * ## Inherit
136
- * ### @Decorator
137
- * Inherit metadata from super class
138
- * @returns
139
- */
140
- declare const Inherit: () => MethodDecorator & ClassDecorator & ParameterDecorator & PropertyDecorator;
134
+ type TDecoratorLevel = 'CLASS' | 'METHOD' | 'PROP' | 'PARAM';
135
+
136
+ /** Metadata context passed to pipe functions during argument/property resolution. */
137
+ interface TPipeMetas<T extends TObject = TEmpty> {
138
+ classMeta?: TMoostMetadata & T;
139
+ methodMeta?: TMoostMetadata & T;
140
+ propMeta?: TMoostMetadata & T;
141
+ paramMeta?: TMoostParamsMetadata & T;
142
+ targetMeta?: TMoostParamsMetadata & T;
143
+ instance?: TObject;
144
+ scopeId?: string | symbol;
145
+ type: TFunction;
146
+ index?: number;
147
+ key: string | symbol;
148
+ instantiate: <T extends TObject>(t: TClassConstructor<T>) => Promise<T>;
149
+ }
150
+ /** A pipe function that transforms, resolves, or validates a value during the pipe pipeline. */
151
+ interface TPipeFn<T extends TObject = TEmpty> {
152
+ (value: unknown, metas: TPipeMetas<T>, level: TDecoratorLevel): unknown | Promise<unknown>;
153
+ priority?: TPipePriority;
154
+ }
155
+ /** Execution priority for pipes. Lower values run first. */
156
+ declare enum TPipePriority {
157
+ BEFORE_RESOLVE = 0,
158
+ RESOLVE = 1,
159
+ AFTER_RESOLVE = 2,
160
+ BEFORE_TRANSFORM = 3,
161
+ TRANSFORM = 4,
162
+ AFTER_TRANSFORM = 5,
163
+ BEFORE_VALIDATE = 6,
164
+ VALIDATE = 7,
165
+ AFTER_VALIDATE = 8
166
+ }
167
+ /** A pipe entry pairing a handler function with its execution priority. */
168
+ interface TPipeData {
169
+ handler: TPipeFn;
170
+ priority: TPipePriority;
171
+ }
172
+
173
+ declare const resolvePipe: TPipeFn<TEmpty>;
141
174
 
142
175
  type TInterceptorBeforeFn = (reply: (response: TAny) => void) => void | Promise<void>;
143
176
  type TInterceptorAfterFn = (response: TAny, reply: (response: TAny) => void) => void | Promise<void>;
@@ -188,7 +221,81 @@ declare enum TInterceptorPriority {
188
221
  */
189
222
  declare function Intercept(handler: TClassConstructor | TInterceptorDef, priority?: TInterceptorPriority, name?: string): ClassDecorator & MethodDecorator;
190
223
 
191
- type TDecoratorLevel = 'CLASS' | 'METHOD' | 'PROP' | 'PARAM';
224
+ /** Core metadata shape attached to classes, methods, and properties by Moost decorators. */
225
+ interface TMoostMetadata<H extends TObject = TEmpty> extends TCommonMetaFields, TCommonMoostMeta {
226
+ requiredProps?: (string | symbol)[];
227
+ controller?: {
228
+ prefix?: string;
229
+ };
230
+ importController?: {
231
+ prefix?: string;
232
+ typeResolver?: TClassConstructor | (() => TClassConstructor | TObject | Promise<TClassConstructor | TObject>);
233
+ provide?: TProvideRegistry;
234
+ }[];
235
+ properties?: (string | symbol)[];
236
+ injectable?: true | TInjectableScope;
237
+ interceptor?: {
238
+ priority: TInterceptorPriority;
239
+ };
240
+ interceptorHook?: 'before' | 'after' | 'error';
241
+ interceptors?: TInterceptorData[];
242
+ handlers?: TMoostHandler<H>[];
243
+ returnType?: TFunction;
244
+ provide?: TProvideRegistry;
245
+ replace?: TReplaceRegistry;
246
+ loggerTopic?: string;
247
+ /**
248
+ * Set by `@MoostInit()` — marks a method to run once after all controllers
249
+ * are bound and before adapters start serving. `priority` orders hooks
250
+ * (ascending) across all controllers.
251
+ */
252
+ moostInit?: {
253
+ priority: number;
254
+ };
255
+ params: (TMateParamMeta & TMoostParamsMetadata)[];
256
+ }
257
+ /** Metadata attached to constructor/method parameters by Moost decorators. */
258
+ interface TMoostParamsMetadata extends TCommonMetaFields, TCommonMoostMeta {
259
+ circular?: () => TAny;
260
+ inject?: string | symbol | TClassConstructor;
261
+ nullable?: boolean;
262
+ paramSource?: string;
263
+ paramName?: string;
264
+ fromScope?: string | symbol;
265
+ }
266
+ /** DI scope for injectable classes: per-event or application-wide singleton. */
267
+ type TInjectableScope = 'FOR_EVENT' | 'SINGLETON';
268
+ /** Describes a registered handler (HTTP route, CLI command, workflow step, etc.). */
269
+ type TMoostHandler<T> = {
270
+ type: string;
271
+ path?: string;
272
+ } & T;
273
+ /** Stored interceptor entry attached to a class or method via `@Intercept`. */
274
+ interface TInterceptorData {
275
+ handler: TClassConstructor | TInterceptorDef;
276
+ priority: TInterceptorPriority;
277
+ name: string;
278
+ }
279
+ /** Returns the shared `Mate` instance operating in the `'moost'` metadata workspace. */
280
+ declare function getMoostMate<Class extends TObject = TEmpty, Prop extends TObject = TEmpty, Param extends TObject = TEmpty>(): Mate<TMoostMetadata & Class & {
281
+ params: (Param & TMateParamMeta)[];
282
+ }, TMoostMetadata & Prop & {
283
+ params: (Param & TMateParamMeta)[];
284
+ }>;
285
+ interface TCommonMetaFields {
286
+ id?: string;
287
+ label?: string;
288
+ value?: unknown;
289
+ description?: string;
290
+ optional?: boolean;
291
+ required?: boolean;
292
+ }
293
+ interface TCommonMoostMeta {
294
+ inherit?: boolean;
295
+ pipes?: TPipeData[];
296
+ resolver?: (metas: TPipeMetas<TAny>, level: TDecoratorLevel) => unknown;
297
+ type?: TFunction;
298
+ }
192
299
 
193
300
  interface TInfactLoggingOptions {
194
301
  newInstance?: true | false | 'FOR_EVENT' | 'SINGLETON';
@@ -221,112 +328,303 @@ declare function getInfactScopeVars<T extends object>(name: string | symbol): T
221
328
  */
222
329
  declare function getNewMoostInfact(): Infact<TMoostMetadata<TEmpty>, TMoostMetadata<TEmpty>, TMoostParamsMetadata, TCustom>;
223
330
 
224
- /** Metadata context passed to pipe functions during argument/property resolution. */
225
- interface TPipeMetas<T extends TObject = TEmpty> {
226
- classMeta?: TMoostMetadata & T;
227
- methodMeta?: TMoostMetadata & T;
228
- propMeta?: TMoostMetadata & T;
229
- paramMeta?: TMoostParamsMetadata & T;
230
- targetMeta?: TMoostParamsMetadata & T;
231
- instance?: TObject;
232
- scopeId?: string | symbol;
233
- type: TFunction;
234
- index?: number;
235
- key: string | symbol;
236
- instantiate: <T extends TObject>(t: TClassConstructor<T>) => Promise<T>;
237
- }
238
- /** A pipe function that transforms, resolves, or validates a value during the pipe pipeline. */
239
- interface TPipeFn<T extends TObject = TEmpty> {
240
- (value: unknown, metas: TPipeMetas<T>, level: TDecoratorLevel): unknown | Promise<unknown>;
241
- priority?: TPipePriority;
331
+ /**
332
+ * A `@MoostInit`-decorated controller method, collected at bind time and run
333
+ * once by `Moost.init()` after all controllers are bound. Interceptors are not
334
+ * applied; params resolve through the RESOLVE pipe only.
335
+ */
336
+ interface TInitHook {
337
+ priority: number;
338
+ method: string;
339
+ computedPrefix: string;
340
+ getInstance: () => Promise<TObject> | TObject;
341
+ resolveArgs?: () => unknown[] | Promise<unknown[]>;
242
342
  }
243
- /** Execution priority for pipes. Lower values run first. */
244
- declare enum TPipePriority {
245
- BEFORE_RESOLVE = 0,
246
- RESOLVE = 1,
247
- AFTER_RESOLVE = 2,
248
- BEFORE_TRANSFORM = 3,
249
- TRANSFORM = 4,
250
- AFTER_TRANSFORM = 5,
251
- BEFORE_VALIDATE = 6,
252
- VALIDATE = 7,
253
- AFTER_VALIDATE = 8
343
+
344
+ /** Summary of a registered controller, its metadata, prefix, and handlers. */
345
+ interface TControllerOverview {
346
+ meta: TMoostMetadata;
347
+ computedPrefix: string;
348
+ type: TFunction;
349
+ handlers: THandlerOverview[];
254
350
  }
255
- /** A pipe entry pairing a handler function with its execution priority. */
256
- interface TPipeData {
257
- handler: TPipeFn;
258
- priority: TPipePriority;
351
+ /** Summary of a registered handler method within a controller. */
352
+ interface THandlerOverview {
353
+ meta: TMoostMetadata;
354
+ path?: string;
355
+ type: string;
356
+ method: string;
357
+ handler: TMoostHandler<TEmpty>;
358
+ registeredAs: {
359
+ path: string;
360
+ args: string[];
361
+ }[];
259
362
  }
363
+ /** Hook points in the event handler lifecycle where context injectors are invoked. */
364
+ type TContextInjectorHook = 'Event:start' | 'Interceptors:init' | 'Arguments:resolve' | 'Interceptors:before' | 'Handler' | 'Interceptors:after';
260
365
 
261
- declare const resolvePipe: TPipeFn<TEmpty>;
262
-
263
- /** Core metadata shape attached to classes, methods, and properties by Moost decorators. */
264
- interface TMoostMetadata<H extends TObject = TEmpty> extends TCommonMetaFields, TCommonMoostMeta {
265
- requiredProps?: (string | symbol)[];
266
- controller?: {
267
- prefix?: string;
268
- };
269
- importController?: {
270
- prefix?: string;
271
- typeResolver?: TClassConstructor | (() => TClassConstructor | TObject | Promise<TClassConstructor | TObject>);
272
- provide?: TProvideRegistry;
273
- }[];
274
- properties?: (string | symbol)[];
275
- injectable?: true | TInjectableScope;
276
- interceptor?: {
277
- priority: TInterceptorPriority;
278
- };
279
- interceptorHook?: 'before' | 'after' | 'error';
280
- interceptors?: TInterceptorData[];
281
- handlers?: TMoostHandler<H>[];
282
- returnType?: TFunction;
283
- provide?: TProvideRegistry;
284
- replace?: TReplaceRegistry;
285
- loggerTopic?: string;
286
- params: (TMateParamMeta & TMoostParamsMetadata)[];
366
+ interface TMoostOptions {
367
+ /**
368
+ * Prefix that is used for each event path
369
+ */
370
+ globalPrefix?: string;
371
+ logger?: TConsoleBase;
287
372
  }
288
- /** Metadata attached to constructor/method parameters by Moost decorators. */
289
- interface TMoostParamsMetadata extends TCommonMetaFields, TCommonMoostMeta {
290
- circular?: () => TAny;
291
- inject?: string | symbol | TClassConstructor;
292
- nullable?: boolean;
293
- paramSource?: string;
294
- paramName?: string;
295
- fromScope?: string | symbol;
373
+ /**
374
+ * ## Moost
375
+ * Main moostjs class that serves as a shell for Moost Adapters
376
+ *
377
+ * ### Usage with HTTP Adapter
378
+ * ```ts
379
+ * │ // HTTP server example
380
+ * │ import { MoostHttp, Get } from '@moostjs/event-http'
381
+ * │ import { Moost, Param } from 'moost'
382
+ * │
383
+ * │ class MyServer extends Moost {
384
+ * │ @Get('test/:name')
385
+ * │ test(@Param('name') name: string) {
386
+ * │ return { message: `Hello ${name}!` }
387
+ * │ }
388
+ * │ }
389
+ * │
390
+ * │ const app = new MyServer()
391
+ * │ const http = new MoostHttp()
392
+ * │ app.adapter(http).listen(3000, () => {
393
+ * │ app.getLogger('MyApp').log('Up on port 3000')
394
+ * │ })
395
+ * │ app.init()
396
+ * ```
397
+ * ### Usage with CLI Adapter
398
+ * ```ts
399
+ * │ // CLI example
400
+ * │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
401
+ * │ import { Moost, Param } from 'moost'
402
+ * │
403
+ * │ class MyApp extends Moost {
404
+ * │ @Cli('command/:arg')
405
+ * │ command(
406
+ * │ @Param('arg')
407
+ * │ arg: string,
408
+ * │ @CliOption('test', 't')
409
+ * │ test: boolean,
410
+ * │ ) {
411
+ * │ return `command run with flag arg=${ arg }, test=${ test }`
412
+ * │ }
413
+ * │ }
414
+ * │
415
+ * │ const app = new MyApp()
416
+ * │ app.applyGlobalInterceptors(cliHelpInterceptor())
417
+ * │
418
+ * │ const cli = new MoostCli()
419
+ * │ app.adapter(cli)
420
+ * │ app.init()
421
+ * ```
422
+ */
423
+ declare class Moost extends Hookable {
424
+ protected options?: TMoostOptions | undefined;
425
+ protected logger: TConsoleBase;
426
+ protected pipes: TPipeData[];
427
+ protected interceptors: TInterceptorData[];
428
+ protected adapters: TMoostAdapter<TAny>[];
429
+ protected controllersOverview: TControllerOverview[];
430
+ protected handlerOverviewIndex?: Map<TFunction, Map<string, THandlerOverview[]>>;
431
+ protected initHooks: TInitHook[];
432
+ protected provide: TProvideRegistry;
433
+ protected replace: TReplaceRegistry;
434
+ protected unregisteredControllers: (TObject | TFunction | [string, TObject | TFunction])[];
435
+ constructor(options?: TMoostOptions | undefined);
436
+ _fireEventStart(source: TMoostAdapter<unknown>): void;
437
+ _fireEventEnd(source: TMoostAdapter<unknown>): void;
438
+ /**
439
+ * ### getLogger
440
+ * Provides application logger
441
+ * ```js
442
+ * // get logger with topic = "App"
443
+ * const logger = app.getLogger('App')
444
+ * logger.log('...')
445
+ * ```
446
+ * @param topic
447
+ * @returns
448
+ */
449
+ getLogger(topic?: string): TConsoleBase;
450
+ adapter<T extends TMoostAdapter<TAny>>(a: T): T;
451
+ getControllersOverview(): TControllerOverview[];
452
+ /**
453
+ * @internal Memoized index of the controllers overview (controller class →
454
+ * method name → handler records), built once and reused for fast handler
455
+ * lookups (see `getHandlerPaths`). Rebuilt whenever controllers are (re)bound.
456
+ */
457
+ getHandlerOverviewIndex(): Map<TFunction, Map<string, THandlerOverview[]>>;
458
+ /**
459
+ * ### init
460
+ * Ititializes adapter. Must be called after adapters are attached.
461
+ */
462
+ init(): Promise<void>;
463
+ /**
464
+ * Runs every `@MoostInit`-decorated controller method exactly once, after all
465
+ * controllers are bound (complete `getControllersOverview()`) and before the
466
+ * `adapter.onInit` loop. Hooks run in ascending `priority`, then registration
467
+ * order. Each runs on its controller's SINGLETON instance inside a synthetic
468
+ * init context (no interceptors; params resolve via the RESOLVE pipe only).
469
+ * A throwing hook rejects `init()` (fail-fast).
470
+ */
471
+ protected runInitHooks(): Promise<void>;
472
+ protected bindControllers(): Promise<void>;
473
+ protected bindController(controller: TFunction | TObject, provide: TProvideRegistry, replace: TReplaceRegistry, globalPrefix: string, replaceOwnPrefix?: string): Promise<void>;
474
+ applyGlobalPipes(...items: (TPipeFn | TPipeData)[]): this;
475
+ protected globalInterceptorHandler?: () => InterceptorHandler | undefined;
476
+ /**
477
+ * Provides InterceptorHandler with global interceptors and pipes.
478
+ * Used to process interceptors when event handler was not found.
479
+ *
480
+ * @returns IterceptorHandler
481
+ */
482
+ getGlobalInterceptorHandler(): InterceptorHandler | undefined;
483
+ applyGlobalInterceptors(...items: (TClassConstructor | TInterceptorDef | TInterceptorData)[]): this;
484
+ /**
485
+ * Register new entries to provide as dependency injections
486
+ * @param provide - Provide Registry (use createProvideRegistry from '\@prostojs/infact')
487
+ * @returns
488
+ */
489
+ setProvideRegistry(provide: TProvideRegistry): this;
490
+ /**
491
+ * Register replace classes to provide as dependency injections
492
+ * @param replace - Replace Registry (use createReplaceRegistry from '\@prostojs/infact')
493
+ * @returns
494
+ */
495
+ setReplaceRegistry(replace: TReplaceRegistry): this;
496
+ /**
497
+ * Register controllers (similar to @ImportController decorator)
498
+ * @param controllers - list of target controllers (instances)
499
+ * @returns
500
+ */
501
+ registerControllers(...controllers: (TObject | TFunction | [string, TObject | TFunction])[]): this;
502
+ logMappedHandler(eventName: string, classConstructor: Function, method: string, stroke?: boolean, prefix?: string): void;
296
503
  }
297
- /** DI scope for injectable classes: per-event or application-wide singleton. */
298
- type TInjectableScope = 'FOR_EVENT' | 'SINGLETON';
299
- /** Describes a registered handler (HTTP route, CLI command, workflow step, etc.). */
300
- type TMoostHandler<T> = {
301
- type: string;
302
- path?: string;
303
- } & T;
304
- /** Stored interceptor entry attached to a class or method via `@Intercept`. */
305
- interface TInterceptorData {
306
- handler: TClassConstructor | TInterceptorDef;
307
- priority: TInterceptorPriority;
308
- name: string;
504
+ interface TMoostAdapterOptions<H, T> {
505
+ prefix: string;
506
+ fakeInstance: T;
507
+ getInstance: () => Promise<T> | T;
508
+ method: keyof T;
509
+ handlers: TMoostHandler<H>[];
510
+ getIterceptorHandler: () => InterceptorHandler | undefined;
511
+ resolveArgs?: () => Promise<unknown[]> | unknown[];
512
+ controllerName?: string;
513
+ logHandler: (eventName: string) => void;
514
+ register: (handler: TMoostHandler<TEmpty>, path: string, args: string[]) => void;
309
515
  }
310
- /** Returns the shared `Mate` instance operating in the `'moost'` metadata workspace. */
311
- declare function getMoostMate<Class extends TObject = TEmpty, Prop extends TObject = TEmpty, Param extends TObject = TEmpty>(): Mate<TMoostMetadata & Class & {
312
- params: (Param & TMateParamMeta)[];
313
- }, TMoostMetadata & Prop & {
314
- params: (Param & TMateParamMeta)[];
315
- }>;
316
- interface TCommonMetaFields {
317
- id?: string;
318
- label?: string;
319
- value?: unknown;
320
- description?: string;
321
- optional?: boolean;
322
- required?: boolean;
516
+ interface TMoostAdapter<H> {
517
+ name: string;
518
+ bindHandler: <T extends TObject = TObject>(options: TMoostAdapterOptions<H, T>) => void | Promise<void>;
519
+ onInit?: (moost: Moost) => void | Promise<void>;
520
+ getProvideRegistry?: () => TProvideRegistry;
323
521
  }
324
- interface TCommonMoostMeta {
325
- inherit?: boolean;
326
- pipes?: TPipeData[];
327
- resolver?: (metas: TPipeMetas<TAny>, level: TDecoratorLevel) => unknown;
328
- type?: TFunction;
522
+
523
+ interface TGetHandlerPathsOptions {
524
+ /** Restrict to handlers of this event type, e.g. `'HTTP'`. */
525
+ type?: string;
526
+ /**
527
+ * Custom predicate to select handlers — keeps event-specific knowledge out of
528
+ * core, e.g. filter by HTTP verb: `(h) => (h.handler as { method: string }).method === 'GET'`.
529
+ */
530
+ predicate?: (handler: THandlerOverview) => boolean;
329
531
  }
532
+ /**
533
+ * Returns every actual mounted path under which `controller.method` is registered,
534
+ * read from the post-bind controllers overview. Accounts for multi-prefix mounts
535
+ * (`@ImportController` at several places), multiple verbs on one method, and
536
+ * multiple `registeredAs` entries. Returns **distinct** paths; empty array if none
537
+ * match.
538
+ *
539
+ * Only meaningful after `Moost.init()` has bound controllers — typically called
540
+ * from a `@MoostInit` method (see [MoostInit](./decorators/init.decorator.ts)).
541
+ *
542
+ * @param controller class constructor or instance whose method to look up
543
+ * @param method controller method name (e.g. the one carrying `@Get('refresh')`)
544
+ */
545
+ declare function getHandlerPaths(moost: Moost, controller: TClassConstructor | TObject, method: string, opts?: TGetHandlerPathsOptions): string[];
546
+ /**
547
+ * Composable form of {@link getHandlerPaths}. Resolves the running Moost app and
548
+ * defaults the controller to the current one from context — designed for use
549
+ * inside a `@MoostInit` method or an event handler. `method` defaults to the
550
+ * current context method; pass it explicitly from `@MoostInit` to target a
551
+ * handler method (the init method itself is not a handler).
552
+ */
553
+ declare function useHandlerPaths(method?: string, opts?: TGetHandlerPathsOptions): Promise<string[]>;
554
+
555
+ /**
556
+ * ## HandlerPaths
557
+ * ### @Decorator
558
+ * Injects the actual mounted path(s) (`string[]`) of a handler method on the
559
+ * current controller, read from the post-bind overview. Built for `@MoostInit`
560
+ * method parameters:
561
+ *
562
+ * ```ts
563
+ * @MoostInit()
564
+ * init(@HandlerPaths('refresh') paths: string[]) {
565
+ * const path = paths[0] // e.g. '/api/auth/refresh'
566
+ * }
567
+ * ```
568
+ *
569
+ * `method` defaults to the current context method (useful inside event handlers);
570
+ * pass it explicitly in `@MoostInit`, where the current method is the init method,
571
+ * not the handler. Returns all distinct paths — see {@link useHandlerPaths}.
572
+ */
573
+ declare function HandlerPaths(method?: string, opts?: TGetHandlerPathsOptions): ParameterDecorator & PropertyDecorator;
574
+
575
+ /**
576
+ * ## Inherit
577
+ * ### @Decorator
578
+ * Inherit metadata from super class
579
+ * @returns
580
+ */
581
+ declare const Inherit: () => MethodDecorator & ClassDecorator & ParameterDecorator & PropertyDecorator;
582
+
583
+ /**
584
+ * ## MoostInit
585
+ * ### @Decorator
586
+ * Marks a controller method to run **once**, after Moost has bound every
587
+ * controller (so the full `getControllersOverview()` is available) and
588
+ * **before** adapters begin serving.
589
+ *
590
+ * The method runs on the controller's SINGLETON instance inside a synthetic
591
+ * init context. Argument injection goes through the RESOLVE pipe only —
592
+ * constructor injection, `@InjectMoost`, `@Inject`, and other `@Resolve`-based
593
+ * params work; transform/validate pipes and interceptors are **not** applied
594
+ * (init is application setup, not an event). Request-scoped composables
595
+ * (`useRequest`, `useHeaders`, `useRouteParams`, …) are unavailable. Async
596
+ * methods are awaited; a throwing hook rejects `Moost.init()` (fail-fast).
597
+ *
598
+ * Applying `@MoostInit` to a `FOR_EVENT` controller is a configuration error and
599
+ * throws at bind time (there is no singleton instance / event at init).
600
+ *
601
+ * @param opts.priority lower runs first across all `@MoostInit` methods (default 0)
602
+ *
603
+ * @example
604
+ * ```ts
605
+ * │ @Controller('auth')
606
+ * │ export class AuthController {
607
+ * │ constructor(private readonly holder: RefreshPathHolder) {}
608
+ * │
609
+ * │ @MoostInit()
610
+ * │ initRefreshCookiePath(@InjectMoost() moost: Moost) {
611
+ * │ // overview is COMPLETE here — this controller's route is mounted
612
+ * │ this.holder.value = resolveRefreshCookiePath(moost)
613
+ * │ }
614
+ * │ }
615
+ * ```
616
+ */
617
+ declare function MoostInit(opts?: {
618
+ priority?: number;
619
+ }): MethodDecorator;
620
+ /**
621
+ * ## InjectMoost
622
+ * ### @Decorator
623
+ * Injects the running {@link Moost} application instance into a method (or
624
+ * constructor) parameter. Intended for `@MoostInit` methods that need the wired
625
+ * app (e.g. `getControllersOverview()`), but works in any DI-resolved position.
626
+ */
627
+ declare function InjectMoost(): ParameterDecorator & PropertyDecorator;
330
628
 
331
629
  /**
332
630
  * ## Injectable
@@ -609,168 +907,6 @@ declare function mergeSorted<T extends {
609
907
  priority: number;
610
908
  }>(...lists: (T[] | readonly T[] | undefined)[]): T[];
611
909
 
612
- /** Summary of a registered controller, its metadata, prefix, and handlers. */
613
- interface TControllerOverview {
614
- meta: TMoostMetadata;
615
- computedPrefix: string;
616
- type: TFunction;
617
- handlers: THandlerOverview[];
618
- }
619
- /** Summary of a registered handler method within a controller. */
620
- interface THandlerOverview {
621
- meta: TMoostMetadata;
622
- path?: string;
623
- type: string;
624
- method: string;
625
- handler: TMoostHandler<TEmpty>;
626
- registeredAs: {
627
- path: string;
628
- args: string[];
629
- }[];
630
- }
631
- /** Hook points in the event handler lifecycle where context injectors are invoked. */
632
- type TContextInjectorHook = 'Event:start' | 'Interceptors:init' | 'Arguments:resolve' | 'Interceptors:before' | 'Handler' | 'Interceptors:after';
633
-
634
- interface TMoostOptions {
635
- /**
636
- * Prefix that is used for each event path
637
- */
638
- globalPrefix?: string;
639
- logger?: TConsoleBase;
640
- }
641
- /**
642
- * ## Moost
643
- * Main moostjs class that serves as a shell for Moost Adapters
644
- *
645
- * ### Usage with HTTP Adapter
646
- * ```ts
647
- * │ // HTTP server example
648
- * │ import { MoostHttp, Get } from '@moostjs/event-http'
649
- * │ import { Moost, Param } from 'moost'
650
- * │
651
- * │ class MyServer extends Moost {
652
- * │ @Get('test/:name')
653
- * │ test(@Param('name') name: string) {
654
- * │ return { message: `Hello ${name}!` }
655
- * │ }
656
- * │ }
657
- * │
658
- * │ const app = new MyServer()
659
- * │ const http = new MoostHttp()
660
- * │ app.adapter(http).listen(3000, () => {
661
- * │ app.getLogger('MyApp').log('Up on port 3000')
662
- * │ })
663
- * │ app.init()
664
- * ```
665
- * ### Usage with CLI Adapter
666
- * ```ts
667
- * │ // CLI example
668
- * │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
669
- * │ import { Moost, Param } from 'moost'
670
- * │
671
- * │ class MyApp extends Moost {
672
- * │ @Cli('command/:arg')
673
- * │ command(
674
- * │ @Param('arg')
675
- * │ arg: string,
676
- * │ @CliOption('test', 't')
677
- * │ test: boolean,
678
- * │ ) {
679
- * │ return `command run with flag arg=${ arg }, test=${ test }`
680
- * │ }
681
- * │ }
682
- * │
683
- * │ const app = new MyApp()
684
- * │ app.applyGlobalInterceptors(cliHelpInterceptor())
685
- * │
686
- * │ const cli = new MoostCli()
687
- * │ app.adapter(cli)
688
- * │ app.init()
689
- * ```
690
- */
691
- declare class Moost extends Hookable {
692
- protected options?: TMoostOptions | undefined;
693
- protected logger: TConsoleBase;
694
- protected pipes: TPipeData[];
695
- protected interceptors: TInterceptorData[];
696
- protected adapters: TMoostAdapter<TAny>[];
697
- protected controllersOverview: TControllerOverview[];
698
- protected provide: TProvideRegistry;
699
- protected replace: TReplaceRegistry;
700
- protected unregisteredControllers: (TObject | TFunction | [string, TObject | TFunction])[];
701
- constructor(options?: TMoostOptions | undefined);
702
- _fireEventStart(source: TMoostAdapter<unknown>): void;
703
- _fireEventEnd(source: TMoostAdapter<unknown>): void;
704
- /**
705
- * ### getLogger
706
- * Provides application logger
707
- * ```js
708
- * // get logger with topic = "App"
709
- * const logger = app.getLogger('App')
710
- * logger.log('...')
711
- * ```
712
- * @param topic
713
- * @returns
714
- */
715
- getLogger(topic?: string): TConsoleBase;
716
- adapter<T extends TMoostAdapter<TAny>>(a: T): T;
717
- getControllersOverview(): TControllerOverview[];
718
- /**
719
- * ### init
720
- * Ititializes adapter. Must be called after adapters are attached.
721
- */
722
- init(): Promise<void>;
723
- protected bindControllers(): Promise<void>;
724
- protected bindController(controller: TFunction | TObject, provide: TProvideRegistry, replace: TReplaceRegistry, globalPrefix: string, replaceOwnPrefix?: string): Promise<void>;
725
- applyGlobalPipes(...items: (TPipeFn | TPipeData)[]): this;
726
- protected globalInterceptorHandler?: () => InterceptorHandler | undefined;
727
- /**
728
- * Provides InterceptorHandler with global interceptors and pipes.
729
- * Used to process interceptors when event handler was not found.
730
- *
731
- * @returns IterceptorHandler
732
- */
733
- getGlobalInterceptorHandler(): InterceptorHandler | undefined;
734
- applyGlobalInterceptors(...items: (TClassConstructor | TInterceptorDef | TInterceptorData)[]): this;
735
- /**
736
- * Register new entries to provide as dependency injections
737
- * @param provide - Provide Registry (use createProvideRegistry from '\@prostojs/infact')
738
- * @returns
739
- */
740
- setProvideRegistry(provide: TProvideRegistry): this;
741
- /**
742
- * Register replace classes to provide as dependency injections
743
- * @param replace - Replace Registry (use createReplaceRegistry from '\@prostojs/infact')
744
- * @returns
745
- */
746
- setReplaceRegistry(replace: TReplaceRegistry): this;
747
- /**
748
- * Register controllers (similar to @ImportController decorator)
749
- * @param controllers - list of target controllers (instances)
750
- * @returns
751
- */
752
- registerControllers(...controllers: (TObject | TFunction | [string, TObject | TFunction])[]): this;
753
- logMappedHandler(eventName: string, classConstructor: Function, method: string, stroke?: boolean, prefix?: string): void;
754
- }
755
- interface TMoostAdapterOptions<H, T> {
756
- prefix: string;
757
- fakeInstance: T;
758
- getInstance: () => Promise<T> | T;
759
- method: keyof T;
760
- handlers: TMoostHandler<H>[];
761
- getIterceptorHandler: () => InterceptorHandler | undefined;
762
- resolveArgs?: () => Promise<unknown[]> | unknown[];
763
- controllerName?: string;
764
- logHandler: (eventName: string) => void;
765
- register: (handler: TMoostHandler<TEmpty>, path: string, args: string[]) => void;
766
- }
767
- interface TMoostAdapter<H> {
768
- name: string;
769
- bindHandler: <T extends TObject = TObject>(options: TMoostAdapterOptions<H, T>) => void | Promise<void>;
770
- onInit?: (moost: Moost) => void | Promise<void>;
771
- getProvideRegistry?: () => TProvideRegistry;
772
- }
773
-
774
910
  /**
775
911
  * Sets the controller context for the current event scope.
776
912
  * Called internally by adapters when dispatching events to handlers.
@@ -811,6 +947,15 @@ declare function useControllerContext<T extends object>(ctx?: EventContext): {
811
947
  } & _prostojs_mate.TMateClassMeta<_prostojs_mate.TMateParamMeta & TMoostParamsMetadata & object> & _prostojs_mate.TMatePropMeta<_prostojs_mate.TMateParamMeta & TMoostParamsMetadata & object>) | undefined;
812
948
  };
813
949
 
950
+ /**
951
+ * Creates a typed event-context key that stays a single instance across duplicate
952
+ * moost loads (dual ESM/CJS, or duplicate installs). Use this for every
953
+ * moost-owned context key instead of `key()` directly.
954
+ *
955
+ * @param name - Debug label AND the registry lookup key; must be unique per slot.
956
+ */
957
+ declare function globalKey<T>(name: string): Key<T>;
958
+
814
959
  /**
815
960
  * Define a before-phase interceptor.
816
961
  *
@@ -889,5 +1034,5 @@ declare function createLogger(opts?: Partial<TProstoLoggerOptions>): ProstoLogge
889
1034
  /** Default colored console transport used by Moost loggers. */
890
1035
  declare const loggerConsoleTransport: _prostojs_logger.TProstoLoggerTransportFn<any>;
891
1036
 
892
- export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, LoggerTopic, Moost, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, getInfactScopeVars, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptResult, setOvertake, useControllerContext, useInterceptResult, useOvertake, useScopeId };
893
- export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TEmpty, TFunction, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives };
1037
+ export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, LoggerTopic, Moost, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, getHandlerPaths, getInfactScopeVars, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, globalKey, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptResult, setOvertake, useControllerContext, useHandlerPaths, useInterceptResult, useOvertake, useScopeId };
1038
+ export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TEmpty, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives };