meocord 4.2.0 → 4.2.2
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 +322 -0
- package/THIRD_PARTY_NOTICES.md +14 -13
- package/dist/cjs/_shared/{controller.decorator-CRn9kWob.cjs → controller.decorator-U2NBWcoU.cjs} +416 -108
- package/dist/cjs/_shared/{providers-ChvMqnLd.cjs → providers-B4MOFBrW.cjs} +202 -50
- package/dist/cjs/_shared/{sharded-cooldown-store-BdAUTdYs.cjs → sharded-cooldown-store-HTUb3Ii_.cjs} +10 -7
- package/dist/cjs/_shared/{startup-roots-CQo8mSP8.cjs → startup-roots-lA5xkBFq.cjs} +228 -71
- package/dist/cjs/_shared/{translate-error-DhDVbT5M.cjs → translate-error-CbBHUu5P.cjs} +10 -5
- package/dist/cjs/common/index.cjs +3 -3
- package/dist/cjs/core/index.cjs +188 -169
- package/dist/cjs/decorator/index.cjs +52 -7
- package/dist/cjs/testing/index.cjs +1854 -311
- package/dist/cli.json +1 -1
- package/dist/esm/bin/generator.js +4 -5
- package/dist/esm/bin/helper/filter-generator.helper.js +4 -5
- package/dist/esm/bin/helper/guard-generator.helper.js +4 -5
- package/dist/esm/bin/helper/interceptor-generator.helper.js +4 -5
- package/dist/esm/bin/helper/observer-generator.helper.js +4 -5
- package/dist/esm/bin/helper/pipe-generator.helper.js +4 -5
- package/dist/esm/bin/helper/service-generator.helper.js +4 -5
- package/dist/esm/bin/meocord.js +84 -25
- package/dist/esm/build/load-config.pre-entry.js +13 -3
- package/dist/esm/build/rsbuild-config.js +16 -12
- package/dist/esm/build/typed-externals.js +36 -0
- package/dist/esm/common/cooldown-store.js +10 -2
- package/dist/esm/common/errors.js +25 -0
- package/dist/esm/common/meocord-text.js +11 -8
- package/dist/esm/common/response/call-order.js +9 -4
- package/dist/esm/common/response/presenter.js +33 -6
- package/dist/esm/common/response/response-state.js +89 -15
- package/dist/esm/common/route.js +11 -4
- package/dist/esm/common/sharded-cooldown-store.js +1 -1
- package/dist/esm/common/translator.js +52 -11
- package/dist/esm/core/command-registration.js +93 -24
- package/dist/esm/core/command-routes.js +2 -2
- package/dist/esm/core/cooldown-runner.js +29 -8
- package/dist/esm/core/dispatcher.js +9 -8
- package/dist/esm/core/fallback.js +20 -11
- package/dist/esm/core/filter-runner.js +2 -2
- package/dist/esm/core/guard-runner.js +16 -3
- package/dist/esm/core/handler-input.js +4 -3
- package/dist/esm/core/handler-pipeline.js +10 -4
- package/dist/esm/core/lifecycle-hooks.js +134 -47
- package/dist/esm/core/meocord-factory.js +59 -34
- package/dist/esm/core/meocord.app.js +116 -75
- package/dist/esm/core/message-help.js +32 -6
- package/dist/esm/core/observer-runner.js +2 -1
- package/dist/esm/core/providers.js +19 -4
- package/dist/esm/core/running-calls.js +43 -0
- package/dist/esm/core/shard-context.js +5 -6
- package/dist/esm/core/shard-manager.js +16 -10
- package/dist/esm/core/stage-scope.js +2 -1
- package/dist/esm/core/startup-roots.js +21 -1
- package/dist/esm/core/theme-resolvers.js +4 -1
- package/dist/esm/core/theme-scope.js +7 -2
- package/dist/esm/core/theme-validation.js +17 -10
- package/dist/esm/decorator/app.decorator.js +31 -0
- package/dist/esm/decorator/controller.decorator.js +56 -20
- package/dist/esm/decorator/cooldown.decorator.js +17 -0
- package/dist/esm/decorator/filter.decorator.js +2 -2
- package/dist/esm/decorator/guard.decorator.js +3 -2
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/testing/catalog.js +20 -13
- package/dist/esm/testing/cooldown-store-suite.js +67 -5
- package/dist/esm/testing/discord-defaults.js +225 -30
- package/dist/esm/testing/meocord-testing-module.js +158 -44
- package/dist/esm/testing/mock-fn.js +107 -26
- package/dist/esm/testing/mock-interaction.js +1250 -182
- package/dist/esm/testing/snowflake.js +9 -2
- package/dist/esm/testing/strict-mocks.js +40 -17
- package/dist/esm/util/common.util.js +47 -19
- package/dist/esm/util/dev-runner.util.js +8 -8
- package/dist/esm/util/generator-cli.util.js +4 -5
- package/dist/esm/util/interaction.util.js +2 -2
- package/dist/esm/util/meocord-config-loader.util.js +10 -2
- package/dist/esm/util/meocord-config-validation.util.js +3 -5
- package/dist/esm/util/meocord-source-config.util.js +65 -20
- package/dist/esm/util/method-wrapper.util.js +16 -0
- package/dist/esm/util/platform.util.js +10 -10
- package/dist/esm/util/shard-process.util.js +4 -1
- package/dist/esm/util/sharding-mode.util.js +5 -7
- package/dist/esm/util/shared-state.util.js +21 -0
- package/dist/esm/util/tsconfig-paths.util.js +29 -0
- package/dist/esm/util/tsconfig.util.js +10 -10
- package/dist/esm/util/value.util.js +30 -2
- package/dist/types/common/index.d.cts +10 -7
- package/dist/types/common/index.d.ts +10 -7
- package/dist/types/core/index.d.cts +3 -2
- package/dist/types/core/index.d.ts +3 -2
- package/dist/types/decorator/index.d.cts +1 -0
- package/dist/types/decorator/index.d.ts +1 -0
- package/dist/types/{index-CdXsFgjE.d.ts → index-DKJclIi-.d.ts} +45 -21
- package/dist/types/{index-nn5p7OoX.d.cts → index-Dlf0ZZtS.d.cts} +45 -21
- package/dist/types/interface/index.d.cts +1 -1
- package/dist/types/interface/index.d.ts +1 -1
- package/dist/types/{route-BZgFoNeB.d.cts → route-Bh1U13yy.d.cts} +3 -2
- package/dist/types/{route-BZgFoNeB.d.ts → route-Bh1U13yy.d.ts} +3 -2
- package/dist/types/testing/index.d.cts +198 -62
- package/dist/types/testing/index.d.ts +198 -62
- package/dist/types/{theme-resolvers-UKr3-6Ys.d.cts → theme-resolvers-CyEz9pnv.d.cts} +1 -1
- package/dist/types/{theme-resolvers-BcOJVzR9.d.ts → theme-resolvers-DA204O-q.d.ts} +1 -1
- package/dist/types/{translator-DHMkkCpg.d.cts → translator-Bg7hwxDF.d.cts} +21 -8
- package/dist/types/{translator-BViWKtLJ.d.ts → translator-CeP4bCzp.d.ts} +21 -8
- package/package.json +2 -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-B4MOFBrW.cjs');
|
|
5
|
+
var controller_decorator = require('../_shared/controller.decorator-U2NBWcoU.cjs');
|
|
6
6
|
var inversify = require('inversify');
|
|
7
7
|
require('node:async_hooks');
|
|
8
8
|
require('../enum/index.cjs');
|
|
@@ -123,10 +123,10 @@ require('chalk');
|
|
|
123
123
|
* which has already run the guards, passes through every wrapper.
|
|
124
124
|
*/ function applyGuards(descriptor, prototype, propertyKey) {
|
|
125
125
|
const originalMethod = descriptor.value;
|
|
126
|
-
descriptor.value = async function(...args) {
|
|
126
|
+
descriptor.value = controller_decorator.wrapsMethod(async function(...args) {
|
|
127
127
|
if (providers.consumeDispatchMark(args[0], this, propertyKey)) return originalMethod.apply(this, args);
|
|
128
128
|
return providers.runDirectCall(this, propertyKey, args, ()=>originalMethod.apply(this, args));
|
|
129
|
-
};
|
|
129
|
+
}, originalMethod);
|
|
130
130
|
const wrappers = Reflect.getOwnMetadata(controller_decorator.META.guardWrappers, prototype, propertyKey) ?? 0;
|
|
131
131
|
Reflect.defineMetadata(controller_decorator.META.guardWrappers, wrappers + 1, prototype, propertyKey);
|
|
132
132
|
}
|
|
@@ -447,14 +447,14 @@ require('chalk');
|
|
|
447
447
|
controller_decorator.refuseOnMethod('@Catch', target, propertyKey);
|
|
448
448
|
providers.makeInjectable(target);
|
|
449
449
|
errorTypes.forEach((type, index)=>{
|
|
450
|
-
if (controller_decorator.
|
|
450
|
+
if (controller_decorator.isConstructible(type)) return;
|
|
451
451
|
const entry = ORDINALS[index] ? `${ORDINALS[index]} entry` : `entry ${index + 1}`;
|
|
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),');
|
|
452
|
+
controller_decorator.warnDeprecatedBehaviour(logger$1, `${target.name}: @Catch's ${entry}, ${controller_decorator.describeValue(type)}, which matches no error,`, 'is refused', 'an error class, such as @Catch(CooldownError),');
|
|
453
453
|
});
|
|
454
454
|
Reflect.defineMetadata(controller_decorator.META.catchTypes, errorTypes, target);
|
|
455
455
|
});
|
|
456
456
|
}
|
|
457
|
-
const logger = new controller_decorator.Logger('Catch');
|
|
457
|
+
const logger$1 = new controller_decorator.Logger('Catch');
|
|
458
458
|
const ORDINALS = [
|
|
459
459
|
'first',
|
|
460
460
|
'second',
|
|
@@ -555,6 +555,35 @@ const ORDINALS = [
|
|
|
555
555
|
if (type.labelKey !== undefined) assertLabelKey(appName, name, type.labelKey, i18n);
|
|
556
556
|
}
|
|
557
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Refuses an option that takes a class given anything else, such as an object or an arrow function, where the app is
|
|
560
|
+
* declared: the startup checks read each class's prototype, and would otherwise fail on it without naming the option.
|
|
561
|
+
*/ function assertClassOptions(appName, { presenter, cooldownStore, controllers, services }) {
|
|
562
|
+
for (const [name, value, implementing] of [
|
|
563
|
+
[
|
|
564
|
+
'presenter',
|
|
565
|
+
presenter,
|
|
566
|
+
'ResponsePresenter'
|
|
567
|
+
],
|
|
568
|
+
[
|
|
569
|
+
'cooldownStore',
|
|
570
|
+
cooldownStore,
|
|
571
|
+
'CooldownStore'
|
|
572
|
+
]
|
|
573
|
+
]){
|
|
574
|
+
if (value !== undefined && !controller_decorator.isConstructor(value)) {
|
|
575
|
+
throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ ${name} }) takes a class implementing ${implementing}, not ${controller_decorator.describeValue(value)}.`));
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
for (const controller of controllers ?? []){
|
|
579
|
+
if (!controller_decorator.isConstructor(controller)) throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ controllers }) takes classes, not ${controller_decorator.describeValue(controller)}.`));
|
|
580
|
+
}
|
|
581
|
+
// A string or symbol is a token, which a provider has to provide; that is checked as the app is created
|
|
582
|
+
for (const service of services ?? []){
|
|
583
|
+
if (controller_decorator.isConstructor(service) || typeof service === 'string' || typeof service === 'symbol') continue;
|
|
584
|
+
throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ services }) takes classes, or tokens that providers provide, not ${controller_decorator.describeValue(service)}.`));
|
|
585
|
+
}
|
|
586
|
+
}
|
|
558
587
|
/** Refuses a type's `labelKey` that no message of the app's default catalog has, as it would be shown as the key. */ function assertLabelKey(appName, name, labelKey, i18n) {
|
|
559
588
|
const where = `${appName}: @MeoCord({ messages: { types } }): "${name}" has labelKey`;
|
|
560
589
|
if (typeof labelKey !== 'string') throw controller_decorator.refuse(new TypeError(`${where} ${String(labelKey)}; it takes a message key, such as 'types.${name}'.`));
|
|
@@ -599,6 +628,7 @@ const ORDINALS = [
|
|
|
599
628
|
*/ function MeoCord(options) {
|
|
600
629
|
return controller_decorator.declaring((target, propertyKey)=>{
|
|
601
630
|
if (controller_decorator.deprecatedOnMethod('@MeoCord', target, propertyKey)) return;
|
|
631
|
+
assertClassOptions(target.name, options);
|
|
602
632
|
providers.assertStageEntries('@MeoCord({ guards })', 'guard', target.name, options.guards ?? []);
|
|
603
633
|
providers.assertStageEntries('@MeoCord({ interceptors })', 'interceptor', target.name, options.interceptors ?? []);
|
|
604
634
|
providers.assertStageEntries('@MeoCord({ filters })', 'filter', target.name, options.filters ?? []);
|
|
@@ -799,6 +829,7 @@ function Cooldown(options) {
|
|
|
799
829
|
// Checked where it applies, so the refusal names the handler or controller
|
|
800
830
|
const problem = cooldownProblem(seconds, uses, per, by);
|
|
801
831
|
if (problem) throw controller_decorator.refuse(new Error(`${controller_decorator.decoratedName(target, propertyKey)}: ${problem}`));
|
|
832
|
+
for (const warning of cooldownWarnings(options))logger.warn(`${controller_decorator.decoratedName(target, propertyKey)}: ${warning}`);
|
|
802
833
|
// Decorators apply bottom-up; prepending keeps them in the order they read.
|
|
803
834
|
if (propertyKey === undefined) {
|
|
804
835
|
const existing = Reflect.getOwnMetadata(controller_decorator.META.classCooldowns, target) ?? [];
|
|
@@ -819,6 +850,20 @@ function Cooldown(options) {
|
|
|
819
850
|
* The longest window, in seconds: half the furthest time a `Date` holds, 8.64e15 ms, so the moment a wait ends, now
|
|
820
851
|
* plus the window, is a real date for a refusal's `retryAt` and the time it shows.
|
|
821
852
|
*/ const MAX_SECONDS = 4320000000000;
|
|
853
|
+
const logger = new controller_decorator.Logger('Cooldown');
|
|
854
|
+
/**
|
|
855
|
+
* What a cooldown's options get wrong that the types refuse, yet still counts: a `bypass` that is not a function, which
|
|
856
|
+
* fails every call, and a `seconds` that is not a number, read as one. A falsy `bypass` means none.
|
|
857
|
+
*/ function cooldownWarnings({ seconds, bypass }) {
|
|
858
|
+
const warnings = [];
|
|
859
|
+
if (bypass && typeof bypass !== 'function') {
|
|
860
|
+
warnings.push(`@Cooldown takes bypass as a function of the call, returning whether the call skips the cooldown, not ${controller_decorator.describeValue(bypass)}; ` + 'every call it counts fails with it. In the next major version (5.0) it is refused.');
|
|
861
|
+
}
|
|
862
|
+
if (typeof seconds !== 'number') {
|
|
863
|
+
warnings.push(`@Cooldown takes seconds as a number, not ${controller_decorator.describeValue(seconds)}, which it counts as a window of ` + `${Math.round(seconds * 1000)} ms. In the next major version (5.0) it is refused.`);
|
|
864
|
+
}
|
|
865
|
+
return warnings;
|
|
866
|
+
}
|
|
822
867
|
/** Why a cooldown's options cannot be counted, or undefined when they can. */ function cooldownProblem(seconds, uses, per, by) {
|
|
823
868
|
if (!(seconds >= 0.001 && seconds <= MAX_SECONDS)) return `@Cooldown needs a number of seconds from 0.001 to ${MAX_SECONDS}, not ${seconds}.`;
|
|
824
869
|
if (!Number.isInteger(uses) || uses < 1) return `@Cooldown needs a whole number of uses of at least 1, not ${uses}.`;
|