meocord 4.1.1 → 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.
- package/CHANGELOG.md +104 -0
- package/README.md +23 -23
- package/dist/cjs/_shared/{controller.decorator-BywwkU9O.cjs → controller.decorator-CRn9kWob.cjs} +295 -87
- package/dist/cjs/_shared/{providers-BMMLp2SN.cjs → providers-ChvMqnLd.cjs} +74 -40
- package/dist/cjs/_shared/{sharded-cooldown-store-B65iaiAy.cjs → sharded-cooldown-store-BdAUTdYs.cjs} +1 -1
- package/dist/cjs/_shared/{startup-roots-lFc69AxC.cjs → startup-roots-CQo8mSP8.cjs} +158 -72
- package/dist/cjs/_shared/{translate-error-BnM8FbSH.cjs → translate-error-DhDVbT5M.cjs} +12 -3
- package/dist/cjs/common/index.cjs +4 -4
- package/dist/cjs/core/index.cjs +195 -157
- package/dist/cjs/decorator/index.cjs +66 -57
- package/dist/cjs/testing/index.cjs +736 -307
- package/dist/cli.json +1 -1
- package/dist/esm/bin/app-template/README.md.template +3 -1
- package/dist/esm/bin/app-template/src/controllers/button/sample.button.controller.spec.ts.template +8 -4
- package/dist/esm/bin/app-template/src/controllers/button/sample.button.controller.ts.template +2 -2
- package/dist/esm/bin/app-template/src/guards/owner.guard.spec.ts.template +8 -4
- package/dist/esm/bin/app-template/src/guards/owner.guard.ts.template +1 -1
- package/dist/esm/bin/app-template/vitest.config.ts.template +1 -1
- package/dist/esm/bin/app-template/vitest.setup.ts.template +7 -3
- package/dist/esm/build/load-config.pre-entry.js +4 -1
- package/dist/esm/common/decorator.js +6 -6
- package/dist/esm/common/deprecation.js +2 -2
- package/dist/esm/common/errors.js +2 -2
- package/dist/esm/common/execution-context.js +1 -1
- package/dist/esm/common/metadata.js +1 -1
- package/dist/esm/common/route.js +10 -1
- package/dist/esm/common/translate-error.js +1 -1
- package/dist/esm/core/command-conflicts.js +34 -34
- package/dist/esm/core/component-routes.js +74 -31
- package/dist/esm/core/dispatcher.js +51 -7
- package/dist/esm/core/filter-runner.js +2 -2
- package/dist/esm/core/handler-pipeline.js +27 -14
- package/dist/esm/core/handler-registry.js +1 -1
- package/dist/esm/core/interceptor-runner.js +2 -2
- package/dist/esm/core/meocord-factory.js +196 -157
- package/dist/esm/core/message-routes.js +4 -3
- package/dist/esm/core/observer-runner.js +4 -3
- package/dist/esm/core/providers.js +38 -21
- package/dist/esm/core/route-specificity.js +4 -4
- package/dist/esm/core/scalar-types.js +15 -3
- package/dist/esm/core/shard-context.js +1 -1
- package/dist/esm/core/startup-roots.js +2 -3
- package/dist/esm/core/theme-runtime.js +2 -2
- package/dist/esm/decorator/app.decorator.js +12 -7
- package/dist/esm/decorator/command-builder.decorator.js +4 -4
- package/dist/esm/decorator/controller-class.decorator.js +9 -4
- package/dist/esm/decorator/controller.decorator.js +110 -67
- package/dist/esm/decorator/cooldown.decorator.js +3 -3
- package/dist/esm/decorator/defer.decorator.js +4 -4
- package/dist/esm/decorator/event.decorator.js +5 -5
- package/dist/esm/decorator/filter.decorator.js +7 -7
- package/dist/esm/decorator/guard.decorator.js +8 -8
- package/dist/esm/decorator/inject.decorator.js +4 -4
- package/dist/esm/decorator/interceptor.decorator.js +7 -7
- package/dist/esm/decorator/observer.decorator.js +4 -4
- package/dist/esm/decorator/service.decorator.js +4 -4
- package/dist/esm/decorator/theme.decorator.js +3 -3
- package/dist/esm/decorator/validation.decorator.js +10 -10
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/testing/catalog.js +1 -1
- package/dist/esm/testing/cooldown-store-suite.js +18 -10
- package/dist/esm/testing/discord-defaults.js +60 -7
- package/dist/esm/testing/index.js +4 -2
- package/dist/esm/testing/inspect-handler.js +20 -3
- package/dist/esm/testing/meocord-testing-module.js +229 -188
- package/dist/esm/testing/mock-fn.js +80 -10
- package/dist/esm/testing/mock-interaction.js +226 -78
- package/dist/esm/testing/response.js +1 -1
- package/dist/esm/testing/routing.js +39 -14
- package/dist/esm/testing/startup-errors.js +26 -0
- package/dist/esm/testing/strict-mocks.js +45 -0
- package/dist/esm/testing/theme.js +1 -1
- package/dist/esm/util/bundle-entry.util.js +2 -1
- package/dist/esm/util/interaction.util.js +1 -1
- package/dist/esm/util/meocord-config-validation.util.js +1 -0
- package/dist/esm/util/metadata-keys.js +1 -0
- package/dist/esm/util/refusal.util.js +148 -8
- package/dist/types/common/index.d.cts +8 -8
- package/dist/types/common/index.d.ts +8 -8
- package/dist/types/core/index.d.cts +8 -6
- package/dist/types/core/index.d.ts +8 -6
- package/dist/types/decorator/index.d.cts +30 -29
- package/dist/types/decorator/index.d.ts +30 -29
- package/dist/types/{index-D7n0FBMm.d.ts → index-CdXsFgjE.d.ts} +62 -15
- package/dist/types/{index-DEP0NYrU.d.cts → index-nn5p7OoX.d.cts} +62 -15
- package/dist/types/interface/index.d.cts +1 -1
- package/dist/types/interface/index.d.ts +1 -1
- package/dist/types/{route-C-aMI7Sl.d.cts → route-BZgFoNeB.d.cts} +5 -2
- package/dist/types/{route-C-aMI7Sl.d.ts → route-BZgFoNeB.d.ts} +5 -2
- package/dist/types/testing/index.d.cts +245 -31
- package/dist/types/testing/index.d.ts +245 -31
- package/dist/types/{theme-resolvers-DedxyscT.d.ts → theme-resolvers-BcOJVzR9.d.ts} +1 -1
- package/dist/types/{theme-resolvers-COHdX5g6.d.cts → theme-resolvers-UKr3-6Ys.d.cts} +1 -1
- package/dist/types/{translator-J6tIUfdp.d.ts → translator-BViWKtLJ.d.ts} +1 -1
- package/dist/types/{translator-B4mc1lzJ.d.cts → translator-DHMkkCpg.d.cts} +1 -1
- 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-
|
|
5
|
-
var controller_decorator = require('../_shared/controller.decorator-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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;
|