meocord 4.1.2 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/dist/cjs/_shared/{controller.decorator-BywwkU9O.cjs → controller.decorator-CRn9kWob.cjs} +295 -87
  3. package/dist/cjs/_shared/{providers-BMMLp2SN.cjs → providers-ChvMqnLd.cjs} +74 -40
  4. package/dist/cjs/_shared/{sharded-cooldown-store-B65iaiAy.cjs → sharded-cooldown-store-BdAUTdYs.cjs} +1 -1
  5. package/dist/cjs/_shared/{startup-roots-lFc69AxC.cjs → startup-roots-CQo8mSP8.cjs} +158 -72
  6. package/dist/cjs/_shared/{translate-error-BnM8FbSH.cjs → translate-error-DhDVbT5M.cjs} +12 -3
  7. package/dist/cjs/common/index.cjs +4 -4
  8. package/dist/cjs/core/index.cjs +195 -157
  9. package/dist/cjs/decorator/index.cjs +66 -57
  10. package/dist/cjs/testing/index.cjs +733 -301
  11. package/dist/cli.json +1 -1
  12. package/dist/esm/bin/app-template/README.md.template +3 -1
  13. package/dist/esm/bin/app-template/src/controllers/button/sample.button.controller.spec.ts.template +8 -4
  14. package/dist/esm/bin/app-template/src/controllers/button/sample.button.controller.ts.template +2 -2
  15. package/dist/esm/bin/app-template/src/guards/owner.guard.spec.ts.template +8 -4
  16. package/dist/esm/bin/app-template/src/guards/owner.guard.ts.template +1 -1
  17. package/dist/esm/bin/app-template/vitest.config.ts.template +1 -1
  18. package/dist/esm/bin/app-template/vitest.setup.ts.template +7 -3
  19. package/dist/esm/build/load-config.pre-entry.js +4 -1
  20. package/dist/esm/common/decorator.js +6 -6
  21. package/dist/esm/common/deprecation.js +2 -2
  22. package/dist/esm/common/errors.js +2 -2
  23. package/dist/esm/common/execution-context.js +1 -1
  24. package/dist/esm/common/metadata.js +1 -1
  25. package/dist/esm/common/route.js +10 -1
  26. package/dist/esm/common/translate-error.js +1 -1
  27. package/dist/esm/core/command-conflicts.js +34 -34
  28. package/dist/esm/core/component-routes.js +74 -31
  29. package/dist/esm/core/dispatcher.js +51 -7
  30. package/dist/esm/core/filter-runner.js +2 -2
  31. package/dist/esm/core/handler-pipeline.js +27 -14
  32. package/dist/esm/core/handler-registry.js +1 -1
  33. package/dist/esm/core/interceptor-runner.js +2 -2
  34. package/dist/esm/core/meocord-factory.js +196 -157
  35. package/dist/esm/core/message-routes.js +4 -3
  36. package/dist/esm/core/observer-runner.js +4 -3
  37. package/dist/esm/core/providers.js +38 -21
  38. package/dist/esm/core/route-specificity.js +4 -4
  39. package/dist/esm/core/scalar-types.js +15 -3
  40. package/dist/esm/core/shard-context.js +1 -1
  41. package/dist/esm/core/startup-roots.js +2 -3
  42. package/dist/esm/core/theme-runtime.js +2 -2
  43. package/dist/esm/decorator/app.decorator.js +12 -7
  44. package/dist/esm/decorator/command-builder.decorator.js +4 -4
  45. package/dist/esm/decorator/controller-class.decorator.js +9 -4
  46. package/dist/esm/decorator/controller.decorator.js +110 -67
  47. package/dist/esm/decorator/cooldown.decorator.js +3 -3
  48. package/dist/esm/decorator/defer.decorator.js +4 -4
  49. package/dist/esm/decorator/event.decorator.js +5 -5
  50. package/dist/esm/decorator/filter.decorator.js +7 -7
  51. package/dist/esm/decorator/guard.decorator.js +8 -8
  52. package/dist/esm/decorator/inject.decorator.js +4 -4
  53. package/dist/esm/decorator/interceptor.decorator.js +7 -7
  54. package/dist/esm/decorator/observer.decorator.js +4 -4
  55. package/dist/esm/decorator/service.decorator.js +4 -4
  56. package/dist/esm/decorator/theme.decorator.js +3 -3
  57. package/dist/esm/decorator/validation.decorator.js +10 -10
  58. package/dist/esm/package.json.js +1 -1
  59. package/dist/esm/testing/catalog.js +1 -1
  60. package/dist/esm/testing/cooldown-store-suite.js +18 -10
  61. package/dist/esm/testing/discord-defaults.js +60 -7
  62. package/dist/esm/testing/index.js +4 -2
  63. package/dist/esm/testing/inspect-handler.js +20 -3
  64. package/dist/esm/testing/meocord-testing-module.js +229 -188
  65. package/dist/esm/testing/mock-fn.js +80 -10
  66. package/dist/esm/testing/mock-interaction.js +223 -72
  67. package/dist/esm/testing/response.js +1 -1
  68. package/dist/esm/testing/routing.js +39 -14
  69. package/dist/esm/testing/startup-errors.js +26 -0
  70. package/dist/esm/testing/strict-mocks.js +45 -0
  71. package/dist/esm/testing/theme.js +1 -1
  72. package/dist/esm/util/bundle-entry.util.js +2 -1
  73. package/dist/esm/util/interaction.util.js +1 -1
  74. package/dist/esm/util/meocord-config-validation.util.js +1 -0
  75. package/dist/esm/util/metadata-keys.js +1 -0
  76. package/dist/esm/util/refusal.util.js +148 -8
  77. package/dist/types/common/index.d.cts +8 -8
  78. package/dist/types/common/index.d.ts +8 -8
  79. package/dist/types/core/index.d.cts +8 -6
  80. package/dist/types/core/index.d.ts +8 -6
  81. package/dist/types/decorator/index.d.cts +30 -29
  82. package/dist/types/decorator/index.d.ts +30 -29
  83. package/dist/types/{index-D7n0FBMm.d.ts → index-CdXsFgjE.d.ts} +62 -15
  84. package/dist/types/{index-DEP0NYrU.d.cts → index-nn5p7OoX.d.cts} +62 -15
  85. package/dist/types/interface/index.d.cts +1 -1
  86. package/dist/types/interface/index.d.ts +1 -1
  87. package/dist/types/{route-C-aMI7Sl.d.cts → route-BZgFoNeB.d.cts} +5 -2
  88. package/dist/types/{route-C-aMI7Sl.d.ts → route-BZgFoNeB.d.ts} +5 -2
  89. package/dist/types/testing/index.d.cts +245 -31
  90. package/dist/types/testing/index.d.ts +245 -31
  91. package/dist/types/{theme-resolvers-DedxyscT.d.ts → theme-resolvers-BcOJVzR9.d.ts} +1 -1
  92. package/dist/types/{theme-resolvers-COHdX5g6.d.cts → theme-resolvers-UKr3-6Ys.d.cts} +1 -1
  93. package/dist/types/{translator-J6tIUfdp.d.ts → translator-BViWKtLJ.d.ts} +1 -1
  94. package/dist/types/{translator-B4mc1lzJ.d.cts → translator-DHMkkCpg.d.cts} +1 -1
  95. package/package.json +3 -2
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('reflect-metadata');
4
- var providers = require('../_shared/providers-BMMLp2SN.cjs');
5
- var controller_decorator = require('../_shared/controller.decorator-BywwkU9O.cjs');
4
+ var providers = require('../_shared/providers-ChvMqnLd.cjs');
5
+ var controller_decorator = require('../_shared/controller.decorator-CRn9kWob.cjs');
6
6
  var inversify = require('inversify');
7
7
  require('node:async_hooks');
8
8
  require('../enum/index.cjs');
@@ -46,12 +46,12 @@ require('chalk');
46
46
  * @group Decorators
47
47
  * @category App
48
48
  * @see {@link Inject}
49
- * @see {@link https://meocord.dev/docs/4.1/services | Services}
49
+ * @see {@link https://meocord.dev/docs/4.2/services | Services}
50
50
  */ function Service() {
51
- return function(target, propertyKey) {
51
+ return controller_decorator.declaring(function(target, propertyKey) {
52
52
  if (controller_decorator.deprecatedOnMethod('@Service', target, propertyKey)) return;
53
53
  providers.makeInjectable(target);
54
- };
54
+ });
55
55
  }
56
56
 
57
57
  /**
@@ -81,9 +81,9 @@ require('chalk');
81
81
  * @group Decorators
82
82
  * @category Handlers
83
83
  * @see {@link Command}
84
- * @see {@link https://meocord.dev/docs/4.1/slash-commands | Slash commands}
84
+ * @see {@link https://meocord.dev/docs/4.2/slash-commands | Slash commands}
85
85
  */ function CommandBuilder(commandType, options = {}) {
86
- return function(target, propertyKey) {
86
+ return controller_decorator.declaring(function(target, propertyKey) {
87
87
  if (controller_decorator.deprecatedOnMethod('@CommandBuilder', target, propertyKey)) return;
88
88
  providers.makeInjectable(target);
89
89
  // Define the command type metadata for the target class
@@ -91,7 +91,7 @@ require('chalk');
91
91
  if (options.guilds) Reflect.defineMetadata(controller_decorator.META.builderGuilds, [
92
92
  ...options.guilds
93
93
  ], target);
94
- };
94
+ });
95
95
  }
96
96
 
97
97
  /**
@@ -208,14 +208,14 @@ require('chalk');
208
208
  * @see {@link UseGuard}
209
209
  * @see {@link GuardDeniedError}
210
210
  * @see {@link ExecutionContext}
211
- * @see {@link https://meocord.dev/docs/4.1/guards | Guards}
211
+ * @see {@link https://meocord.dev/docs/4.2/guards | Guards}
212
212
  */ function Guard(options = {}) {
213
- return function(target, propertyKey) {
213
+ return controller_decorator.declaring(function(target, propertyKey) {
214
214
  if (controller_decorator.deprecatedOnMethod('@Guard', target, propertyKey)) return;
215
215
  providers.makeInjectable(target);
216
216
  providers.defineStageTypes(target, options.types, 'Guard');
217
217
  Reflect.defineMetadata(controller_decorator.META.guardClass, true, target);
218
- };
218
+ });
219
219
  }
220
220
  /**
221
221
  * Runs guards before a handler, or before every handler of a controller.
@@ -246,10 +246,10 @@ require('chalk');
246
246
  * @see {@link Guard}
247
247
  * @see {@link GuardDeniedError}
248
248
  * @see {@link ExecutionContext}
249
- * @see {@link https://meocord.dev/docs/4.1/guards | Guards}
249
+ * @see {@link https://meocord.dev/docs/4.2/guards | Guards}
250
250
  */ function UseGuard(...entries) {
251
251
  const guards = entries;
252
- return function(target, propertyKey, descriptor) {
252
+ return controller_decorator.declaring(function(target, propertyKey, descriptor) {
253
253
  const where = propertyKey === undefined ? String(target?.name) : `${target.constructor.name}.${String(propertyKey)}`;
254
254
  providers.assertStageEntries('@UseGuard', 'guard', where, guards);
255
255
  if (descriptor && propertyKey) {
@@ -274,7 +274,7 @@ require('chalk');
274
274
  }
275
275
  }
276
276
  }
277
- };
277
+ });
278
278
  }
279
279
 
280
280
  /**
@@ -309,14 +309,18 @@ require('chalk');
309
309
  * @category Controllers
310
310
  * @see {@link Command}
311
311
  * @see {@link ControllerOptions}
312
- * @see {@link https://meocord.dev/docs/4.1/how-a-call-runs | How a call runs}
312
+ * @see {@link https://meocord.dev/docs/4.2/how-a-call-runs | How a call runs}
313
313
  */ function Controller(options = {}) {
314
- return function(target, propertyKey) {
314
+ return controller_decorator.declaring(function(target, propertyKey) {
315
315
  if (controller_decorator.deprecatedOnMethod('@Controller', target, propertyKey)) return;
316
316
  providers.makeInjectable(target);
317
317
  if (options.inheritStages === false) Reflect.defineMetadata(controller_decorator.META.inheritStages, false, target);
318
+ if (options.inheritedRoutes === 'replace') {
319
+ controller_decorator.dropInheritedRoutes(target.prototype);
320
+ Reflect.defineMetadata(controller_decorator.META.replacesInheritedRoutes, true, target.prototype);
321
+ }
318
322
  guardOwnHandlersWithBaseGuards(target);
319
- };
323
+ });
320
324
  }
321
325
 
322
326
  /**
@@ -351,13 +355,13 @@ require('chalk');
351
355
  * @group Decorators
352
356
  * @category Pipeline stages
353
357
  * @see {@link UseInterceptor}
354
- * @see {@link https://meocord.dev/docs/4.1/interceptors | Interceptors}
358
+ * @see {@link https://meocord.dev/docs/4.2/interceptors | Interceptors}
355
359
  */ function Interceptor(options = {}) {
356
- return function(target, propertyKey) {
360
+ return controller_decorator.declaring(function(target, propertyKey) {
357
361
  controller_decorator.refuseOnMethod('@Interceptor', target, propertyKey);
358
362
  providers.makeInjectable(target);
359
363
  providers.defineStageTypes(target, options.types, 'Interceptor');
360
- };
364
+ });
361
365
  }
362
366
  /**
363
367
  * Runs interceptors around a handler, or around every handler of a controller.
@@ -388,9 +392,9 @@ require('chalk');
388
392
  * @group Decorators
389
393
  * @category Pipeline stages
390
394
  * @see {@link Interceptor}
391
- * @see {@link https://meocord.dev/docs/4.1/interceptors | Interceptors}
395
+ * @see {@link https://meocord.dev/docs/4.2/interceptors | Interceptors}
392
396
  */ function UseInterceptor(...interceptors) {
393
- return function(target, propertyKey) {
397
+ return controller_decorator.declaring(function(target, propertyKey) {
394
398
  const where = propertyKey === undefined ? target.name : `${target.constructor.name}.${String(propertyKey)}`;
395
399
  providers.assertStageEntries('@UseInterceptor', 'interceptor', where, interceptors);
396
400
  // Decorators apply bottom-up, so a higher decorator's interceptors go first, as with @UseGuard.
@@ -407,7 +411,7 @@ require('chalk');
407
411
  ...existing
408
412
  ], target, propertyKey);
409
413
  }
410
- };
414
+ });
411
415
  }
412
416
 
413
417
  /**
@@ -437,9 +441,9 @@ require('chalk');
437
441
  * @group Decorators
438
442
  * @category Pipeline stages
439
443
  * @see {@link UseFilter}
440
- * @see {@link https://meocord.dev/docs/4.1/exception-filters | Exception filters}
444
+ * @see {@link https://meocord.dev/docs/4.2/exception-filters | Exception filters}
441
445
  */ function Catch(...errorTypes) {
442
- return function(target, propertyKey) {
446
+ return controller_decorator.declaring(function(target, propertyKey) {
443
447
  controller_decorator.refuseOnMethod('@Catch', target, propertyKey);
444
448
  providers.makeInjectable(target);
445
449
  errorTypes.forEach((type, index)=>{
@@ -448,7 +452,7 @@ require('chalk');
448
452
  controller_decorator.warnDeprecatedBehaviour(logger, `${target.name}: @Catch's ${entry}, ${controller_decorator.describeValue(type)}, which matches no error,`, 'is refused', 'an error class, such as @Catch(CooldownError),');
449
453
  });
450
454
  Reflect.defineMetadata(controller_decorator.META.catchTypes, errorTypes, target);
451
- };
455
+ });
452
456
  }
453
457
  const logger = new controller_decorator.Logger('Catch');
454
458
  const ORDINALS = [
@@ -488,9 +492,9 @@ const ORDINALS = [
488
492
  * @group Decorators
489
493
  * @category Pipeline stages
490
494
  * @see {@link Catch}
491
- * @see {@link https://meocord.dev/docs/4.1/exception-filters | Exception filters}
495
+ * @see {@link https://meocord.dev/docs/4.2/exception-filters | Exception filters}
492
496
  */ function UseFilter(...filters) {
493
- return function(target, propertyKey) {
497
+ return controller_decorator.declaring(function(target, propertyKey) {
494
498
  const where = propertyKey === undefined ? target.name : `${target.constructor.name}.${String(propertyKey)}`;
495
499
  providers.assertStageEntries('@UseFilter', 'filter', where, filters);
496
500
  // Decorators apply bottom-up, so a higher decorator's filters are tried first.
@@ -507,7 +511,7 @@ const ORDINALS = [
507
511
  ...existing
508
512
  ], target, propertyKey);
509
513
  }
510
- };
514
+ });
511
515
  }
512
516
 
513
517
  /** Refuses a `messages` option of the wrong type where the app is declared, rather than at the first message. */ function assertMessageOptions(appName, messages, i18n) {
@@ -517,14 +521,19 @@ const ORDINALS = [
517
521
  if (prefix !== undefined && !isText(prefix) && typeof prefix !== 'function' && !(Array.isArray(prefix) && prefix.every(isText))) {
518
522
  throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ messages: { prefix } }) takes a string, a list of strings, or a function of the message returning them.`));
519
523
  }
520
- for (const [name, value] of Object.entries({
524
+ const flags = {
521
525
  caseSensitive,
522
526
  replyEmoji: messages.replyEmoji,
523
527
  dmOnError: messages.dmOnError,
524
- dmOnCooldown: messages.dmOnCooldown
525
- })){
528
+ dmOnCooldown: messages.dmOnCooldown,
529
+ slowHandlerWarning: messages.slowHandlerWarning
530
+ };
531
+ for (const [name, value] of Object.entries(flags)){
526
532
  if (value !== undefined && typeof value !== 'boolean') throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ messages: { ${name} } }) takes true or false.`));
527
533
  }
534
+ if (messages.handlers !== undefined && messages.handlers !== 'sequential' && messages.handlers !== 'concurrent') {
535
+ throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ messages: { handlers } }) takes 'sequential' or 'concurrent'.`));
536
+ }
528
537
  if (mention !== undefined && typeof mention !== 'boolean' && mention !== 'only') {
529
538
  throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ messages: { mention } }) takes true, false or 'only'.`));
530
539
  }
@@ -586,9 +595,9 @@ const ORDINALS = [
586
595
  * @see {@link MeoCordOptions}
587
596
  * @see {@link MeoCordFactory}
588
597
  * @see {@link MeoCordConfig}
589
- * @see {@link https://meocord.dev/docs/4.1/configuration | Configuration}
598
+ * @see {@link https://meocord.dev/docs/4.2/configuration | Configuration}
590
599
  */ function MeoCord(options) {
591
- return (target, propertyKey)=>{
600
+ return controller_decorator.declaring((target, propertyKey)=>{
592
601
  if (controller_decorator.deprecatedOnMethod('@MeoCord', target, propertyKey)) return;
593
602
  providers.assertStageEntries('@MeoCord({ guards })', 'guard', target.name, options.guards ?? []);
594
603
  providers.assertStageEntries('@MeoCord({ interceptors })', 'interceptor', target.name, options.interceptors ?? []);
@@ -610,7 +619,7 @@ const ORDINALS = [
610
619
  ...options,
611
620
  theme
612
621
  }, target);
613
- };
622
+ });
614
623
  }
615
624
  /** Refuses theme resolvers and cache options the runtime cannot follow, where the app is declared. */ function assertThemeFor(appName, { themeFor, themeCache, themeForTimeoutMs }) {
616
625
  const problem = themeFor === undefined ? undefined : controller_decorator.themeForProblem(themeFor, `${appName}: @MeoCord({ themeFor })`, 'or a class implementing ThemeResolver.');
@@ -678,9 +687,9 @@ const ORDINALS = [
678
687
  * @category Pipeline stages
679
688
  * @see {@link UsePipe}
680
689
  * @see {@link ValidationError}
681
- * @see {@link https://meocord.dev/docs/4.1/validation | Validation and pipes}
690
+ * @see {@link https://meocord.dev/docs/4.2/validation | Validation and pipes}
682
691
  */ function Validate(schema, options = {}) {
683
- return function(target, propertyKey, _descriptor) {
692
+ return controller_decorator.declaring(function(target, propertyKey, _descriptor) {
684
693
  controller_decorator.refuseOnClass('@Validate', target, propertyKey);
685
694
  // Checked where it applies, so the refusal names the handler
686
695
  if (typeof schema?.['~standard']?.validate !== 'function') {
@@ -698,7 +707,7 @@ const ORDINALS = [
698
707
  pipes: options.pipes ?? {}
699
708
  };
700
709
  Reflect.defineMetadata(controller_decorator.META.methodValidation, metadata, target, propertyKey);
701
- };
710
+ });
702
711
  }
703
712
  /**
704
713
  * Runs pipes on one value of a handler's input, to turn it into what the handler works with.
@@ -730,9 +739,9 @@ const ORDINALS = [
730
739
  * @category Pipeline stages
731
740
  * @see {@link Pipe}
732
741
  * @see {@link Validate}
733
- * @see {@link https://meocord.dev/docs/4.1/validation | Validation and pipes}
742
+ * @see {@link https://meocord.dev/docs/4.2/validation | Validation and pipes}
734
743
  */ function UsePipe(key, ...pipes) {
735
- return function(target, propertyKey, _descriptor) {
744
+ return controller_decorator.declaring(function(target, propertyKey, _descriptor) {
736
745
  controller_decorator.refuseOnClass('@UsePipe', target, propertyKey);
737
746
  providers.assertStageEntries('@UsePipe', 'pipe', `${target.constructor.name}.${propertyKey}`, pipes);
738
747
  // Decorators apply bottom-up, so a higher @UsePipe's pipes go first, in the order they read.
@@ -744,7 +753,7 @@ const ORDINALS = [
744
753
  })),
745
754
  ...existing
746
755
  ], target, propertyKey);
747
- };
756
+ });
748
757
  }
749
758
  /**
750
759
  * Marks a class as a pipe, which turns one input value into what the handler works with.
@@ -770,12 +779,12 @@ const ORDINALS = [
770
779
  * @group Decorators
771
780
  * @category Pipeline stages
772
781
  * @see {@link UsePipe}
773
- * @see {@link https://meocord.dev/docs/4.1/validation | Validation and pipes}
782
+ * @see {@link https://meocord.dev/docs/4.2/validation | Validation and pipes}
774
783
  */ function Pipe() {
775
- return function(target, propertyKey) {
784
+ return controller_decorator.declaring(function(target, propertyKey) {
776
785
  controller_decorator.refuseOnMethod('@Pipe', target, propertyKey);
777
786
  providers.makeInjectable(target);
778
- };
787
+ });
779
788
  }
780
789
 
781
790
  function Cooldown(options) {
@@ -786,7 +795,7 @@ function Cooldown(options) {
786
795
  per,
787
796
  windowMs: Math.round(seconds * 1000)
788
797
  };
789
- return function(target, propertyKey) {
798
+ return controller_decorator.declaring(function(target, propertyKey) {
790
799
  // Checked where it applies, so the refusal names the handler or controller
791
800
  const problem = cooldownProblem(seconds, uses, per, by);
792
801
  if (problem) throw controller_decorator.refuse(new Error(`${controller_decorator.decoratedName(target, propertyKey)}: ${problem}`));
@@ -804,7 +813,7 @@ function Cooldown(options) {
804
813
  ...existing
805
814
  ], target, propertyKey);
806
815
  }
807
- };
816
+ });
808
817
  }
809
818
  /**
810
819
  * The longest window, in seconds: half the furthest time a `Date` holds, 8.64e15 ms, so the moment a wait ends, now
@@ -861,9 +870,9 @@ function Cooldown(options) {
861
870
  * @category Pipeline stages
862
871
  * @see {@link DeferOptions}
863
872
  * @see {@link respond}
864
- * @see {@link https://meocord.dev/docs/4.1/defer | Deferring}
873
+ * @see {@link https://meocord.dev/docs/4.2/defer | Deferring}
865
874
  */ function Defer(options = {}) {
866
- return (target, propertyKey)=>{
875
+ return controller_decorator.declaring((target, propertyKey)=>{
867
876
  controller_decorator.refuseOnClass('@Defer', target, propertyKey);
868
877
  const methodName = String(propertyKey);
869
878
  const kind = providers.nonInteractionHandler(target, methodName);
@@ -871,7 +880,7 @@ function Cooldown(options) {
871
880
  Reflect.defineMetadata(controller_decorator.META.deferOptions, {
872
881
  ...options
873
882
  }, target, methodName);
874
- };
883
+ });
875
884
  }
876
885
 
877
886
  /**
@@ -897,14 +906,14 @@ function Cooldown(options) {
897
906
  * @category Params
898
907
  * @see {@link Service}
899
908
  * @see {@link createToken}
900
- * @see {@link https://meocord.dev/docs/4.1/services | Services}
909
+ * @see {@link https://meocord.dev/docs/4.2/services | Services}
901
910
  */ function Inject(token) {
902
911
  const decorate = inversify.inject(token);
903
- return (target, propertyKey, parameterIndex)=>{
912
+ return controller_decorator.declaring((target, propertyKey, parameterIndex)=>{
904
913
  // A constructor parameter has no property key either, but has an index
905
914
  if (typeof parameterIndex !== 'number') controller_decorator.refuseOnClass('@Inject', target, propertyKey, 'a constructor parameter or a property');
906
915
  decorate(target, propertyKey, parameterIndex);
907
- };
916
+ });
908
917
  }
909
918
 
910
919
  /**
@@ -938,9 +947,9 @@ function Cooldown(options) {
938
947
  * @pipeline observers-settled once the call has settled and been answered, however it ended
939
948
  * @group Decorators
940
949
  * @category Pipeline stages
941
- * @see {@link https://meocord.dev/docs/4.1/observers | Observers}
950
+ * @see {@link https://meocord.dev/docs/4.2/observers | Observers}
942
951
  */ function Observer(options = {}) {
943
- return function(target, propertyKey) {
952
+ return controller_decorator.declaring(function(target, propertyKey) {
944
953
  controller_decorator.refuseOnMethod('@Observer', target, propertyKey);
945
954
  if (typeof target.prototype.onSettled !== 'function') {
946
955
  throw controller_decorator.refuse(new Error(`${target.name}: an @Observer needs an onSettled method, and it has none.`));
@@ -948,7 +957,7 @@ function Cooldown(options) {
948
957
  providers.makeInjectable(target);
949
958
  providers.defineStageTypes(target, options.types, 'Observer');
950
959
  Reflect.defineMetadata(controller_decorator.META.observerClass, true, target);
951
- };
960
+ });
952
961
  }
953
962
 
954
963
  /**
@@ -981,7 +990,7 @@ function Cooldown(options) {
981
990
  * @group Decorators
982
991
  * @category Controllers
983
992
  */ function UseTheme(theme) {
984
- return function(target, propertyKey) {
993
+ return controller_decorator.declaring(function(target, propertyKey) {
985
994
  const onClass = propertyKey === undefined;
986
995
  const owner = onClass ? target : target.constructor;
987
996
  const where = `${owner.name}${onClass ? '' : `.${String(propertyKey)}`}: @UseTheme`;
@@ -993,7 +1002,7 @@ function Cooldown(options) {
993
1002
  if (onClass) Reflect.defineMetadata(key, layer, target);
994
1003
  else Reflect.defineMetadata(key, layer, target, propertyKey);
995
1004
  providers.THEMED_CLASSES.add(owner);
996
- };
1005
+ });
997
1006
  }
998
1007
 
999
1008
  exports.On = providers.On;