meocord 4.2.2 → 4.2.3
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 +130 -0
- package/dist/cjs/_shared/{controller.decorator-U2NBWcoU.cjs → controller.decorator-hp5xdJU4.cjs} +512 -183
- package/dist/cjs/_shared/{startup-roots-lA5xkBFq.cjs → event-sources-DzqTODXg.cjs} +265 -80
- package/dist/cjs/_shared/{providers-B4MOFBrW.cjs → providers-BBvbnmLP.cjs} +780 -281
- package/dist/cjs/_shared/{sharded-cooldown-store-HTUb3Ii_.cjs → sharded-cooldown-store-B62g5O88.cjs} +11 -9
- package/dist/cjs/_shared/{translate-error-CbBHUu5P.cjs → translate-error-wsgfsUET.cjs} +1 -1
- package/dist/cjs/common/index.cjs +4 -104
- package/dist/cjs/core/index.cjs +432 -181
- package/dist/cjs/decorator/index.cjs +85 -120
- package/dist/cjs/testing/index.cjs +1664 -784
- package/dist/cli.json +1 -1
- package/dist/esm/bin/app-template/package.json.template +9 -9
- package/dist/esm/bin/app-template/src/main.ts.template +3 -2
- package/dist/esm/bin/generator.js +6 -4
- package/dist/esm/bin/helper/filter-generator.helper.js +6 -4
- package/dist/esm/bin/helper/guard-generator.helper.js +6 -4
- package/dist/esm/bin/helper/interceptor-generator.helper.js +6 -4
- package/dist/esm/bin/helper/observer-generator.helper.js +6 -4
- package/dist/esm/bin/helper/pipe-generator.helper.js +6 -4
- package/dist/esm/bin/helper/service-generator.helper.js +6 -4
- package/dist/esm/bin/meocord.js +106 -48
- package/dist/esm/build/native-addons.js +75 -19
- package/dist/esm/build/rsbuild-config.js +11 -3
- package/dist/esm/build/typed-externals.js +15 -2
- package/dist/esm/common/cooldown-store.js +38 -14
- package/dist/esm/common/deprecation.js +4 -1
- package/dist/esm/common/execution-context.js +3 -1
- package/dist/esm/common/explained-error.js +7 -3
- package/dist/esm/common/log-level.js +13 -9
- package/dist/esm/common/logger.js +4 -2
- package/dist/esm/common/meocord-text.js +11 -6
- package/dist/esm/common/redis-cooldown-store.js +3 -7
- package/dist/esm/common/response/flags.js +17 -1
- package/dist/esm/common/response/install-context.js +27 -16
- package/dist/esm/common/response/presenter.js +7 -3
- package/dist/esm/common/response/response-state.js +27 -5
- package/dist/esm/common/sharded-cooldown-store.js +11 -9
- package/dist/esm/common/theme.js +3 -1
- package/dist/esm/common/translator.js +17 -8
- package/dist/esm/core/autocomplete-routes.js +26 -0
- package/dist/esm/core/command-conflicts.js +15 -7
- package/dist/esm/core/command-registration.js +15 -1
- package/dist/esm/core/cooldown-runner.js +7 -9
- package/dist/esm/core/defer.js +2 -5
- package/dist/esm/core/dispatcher.js +83 -58
- package/dist/esm/core/event-requirements.js +67 -19
- package/dist/esm/core/event-sources.js +100 -0
- package/dist/esm/core/fallback.js +3 -1
- package/dist/esm/core/filter-runner.js +4 -4
- package/dist/esm/core/guard-runner.js +173 -52
- package/dist/esm/core/handler-input.js +24 -3
- package/dist/esm/core/handler-pipeline.js +44 -28
- package/dist/esm/core/handler-registry.js +51 -21
- package/dist/esm/core/input-runner.js +7 -8
- package/dist/esm/core/interceptor-runner.js +4 -5
- package/dist/esm/core/lifecycle-hooks.js +3 -8
- package/dist/esm/core/lifecycle-order.js +1 -15
- package/dist/esm/core/meocord-classes.js +14 -1
- package/dist/esm/core/meocord-factory.js +80 -53
- package/dist/esm/core/meocord.app.js +174 -89
- package/dist/esm/core/message-help.js +5 -9
- package/dist/esm/core/message-params.js +126 -46
- package/dist/esm/core/message-routes.js +225 -45
- package/dist/esm/core/message-words.js +30 -2
- package/dist/esm/core/observer-runner.js +2 -1
- package/dist/esm/core/process-state.js +19 -0
- package/dist/esm/core/providers.js +28 -3
- package/dist/esm/core/scalar-types.js +57 -16
- package/dist/esm/core/shard-context.js +11 -10
- package/dist/esm/core/shard-exit.js +3 -3
- package/dist/esm/core/shard-manager.js +16 -6
- package/dist/esm/core/startup-roots.js +28 -8
- package/dist/esm/core/theme-resolvers.js +26 -11
- package/dist/esm/core/theme-runtime.js +23 -13
- package/dist/esm/core/theme-scope.js +27 -29
- package/dist/esm/core/theme-validation.js +1 -1
- package/dist/esm/decorator/app.decorator.js +6 -1
- package/dist/esm/decorator/command-builder.decorator.js +14 -0
- package/dist/esm/decorator/controller-class.decorator.js +1 -1
- package/dist/esm/decorator/controller.decorator.js +48 -19
- package/dist/esm/decorator/defer.decorator.js +2 -2
- package/dist/esm/decorator/event.decorator.js +4 -5
- package/dist/esm/decorator/filter.decorator.js +2 -2
- package/dist/esm/decorator/guard.decorator.js +4 -61
- package/dist/esm/decorator/inject.decorator.js +4 -1
- package/dist/esm/decorator/interceptor.decorator.js +2 -2
- package/dist/esm/decorator/theme.decorator.js +4 -3
- package/dist/esm/decorator/validation.decorator.js +5 -5
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/testing/catalog.js +29 -13
- package/dist/esm/testing/cooldown-store-suite.js +3 -3
- package/dist/esm/testing/discord-defaults.js +449 -355
- package/dist/esm/testing/inspect-handler.js +91 -10
- package/dist/esm/testing/meocord-testing-module.js +195 -77
- package/dist/esm/testing/mock-fn.js +8 -2
- package/dist/esm/testing/mock-interaction.js +639 -113
- package/dist/esm/testing/response-log.js +8 -0
- package/dist/esm/testing/response.js +7 -5
- package/dist/esm/testing/routing.js +48 -6
- package/dist/esm/testing/strict-mocks.js +1 -0
- package/dist/esm/testing/theme.js +3 -2
- package/dist/esm/util/common.util.js +30 -9
- package/dist/esm/util/generator-cli.util.js +6 -4
- package/dist/esm/util/inherited-env.util.js +72 -13
- package/dist/esm/util/json.util.js +10 -3
- package/dist/esm/util/meocord-cli.util.js +3 -2
- package/dist/esm/util/meocord-config-loader.util.js +14 -1
- package/dist/esm/util/meocord-config-validation.util.js +13 -3
- package/dist/esm/util/meocord-source-config.util.js +13 -3
- package/dist/esm/util/platform.util.js +3 -2
- package/dist/esm/util/refusal.util.js +29 -11
- package/dist/esm/util/registration-mode.util.js +14 -1
- package/dist/esm/util/timer-limit.util.js +4 -1
- package/dist/esm/util/tsconfig-paths.util.js +38 -7
- package/dist/esm/util/tsconfig.util.js +16 -58
- package/dist/esm/util/user-text.util.js +8 -4
- package/dist/esm/util/value.util.js +15 -4
- package/dist/types/common/index.d.cts +13 -9
- package/dist/types/common/index.d.ts +13 -9
- package/dist/types/core/index.d.cts +21 -11
- package/dist/types/core/index.d.ts +21 -11
- package/dist/types/decorator/index.d.cts +63 -63
- package/dist/types/decorator/index.d.ts +63 -63
- package/dist/types/{index-DKJclIi-.d.ts → index-Brkd6QGL.d.ts} +81 -35
- package/dist/types/{index-Dlf0ZZtS.d.cts → index-CqXImwF_.d.cts} +81 -35
- package/dist/types/interface/index.d.cts +1 -1
- package/dist/types/interface/index.d.ts +1 -1
- package/dist/types/{route-Bh1U13yy.d.ts → route-IQrK-MN2.d.cts} +11 -3
- package/dist/types/{route-Bh1U13yy.d.cts → route-bI-okq7g.d.ts} +11 -3
- package/dist/types/testing/index.d.cts +137 -54
- package/dist/types/testing/index.d.ts +137 -54
- package/dist/types/{theme-resolvers-CyEz9pnv.d.cts → theme-resolvers-AtgeaYqF.d.cts} +1 -1
- package/dist/types/{theme-resolvers-DA204O-q.d.ts → theme-resolvers-BgqysV8d.d.ts} +1 -1
- package/dist/types/{translator-Bg7hwxDF.d.cts → translator-D8aydlCE.d.ts} +12 -11
- package/dist/types/{translator-CeP4bCzp.d.ts → translator-iJhDlgwL.d.cts} +12 -11
- package/package.json +5 -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-BBvbnmLP.cjs');
|
|
5
|
+
var controller_decorator = require('../_shared/controller.decorator-hp5xdJU4.cjs');
|
|
6
6
|
var inversify = require('inversify');
|
|
7
7
|
require('node:async_hooks');
|
|
8
8
|
require('../enum/index.cjs');
|
|
@@ -12,14 +12,14 @@ require('fs');
|
|
|
12
12
|
require('path');
|
|
13
13
|
require('cli-table3');
|
|
14
14
|
require('node:crypto');
|
|
15
|
-
require('node:fs');
|
|
16
|
-
require('node:url');
|
|
17
15
|
require('node:util');
|
|
18
16
|
require('dayjs');
|
|
19
17
|
require('dayjs/plugin/utc.js');
|
|
20
18
|
require('dayjs/plugin/timezone.js');
|
|
21
19
|
require('module');
|
|
20
|
+
require('node:fs');
|
|
22
21
|
require('chalk');
|
|
22
|
+
require('node:url');
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Marks a class as a service, which controllers and other services inject by its type.
|
|
@@ -54,6 +54,13 @@ require('chalk');
|
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
const logger$3 = new controller_decorator.Logger('CommandBuilder');
|
|
58
|
+
/** The nearest base class of `target` that gives `guilds`, which `target` inherits when it gives none. */ function guildsBase(target) {
|
|
59
|
+
for(let base = Object.getPrototypeOf(target); base && base !== Function.prototype; base = Object.getPrototypeOf(base)){
|
|
60
|
+
if (Reflect.hasOwnMetadata(controller_decorator.META.builderGuilds, base)) return base;
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
57
64
|
/**
|
|
58
65
|
* Marks a class as a command's builder, which describes the command MeoCord registers with Discord.
|
|
59
66
|
*
|
|
@@ -91,45 +98,61 @@ require('chalk');
|
|
|
91
98
|
if (options.guilds) Reflect.defineMetadata(controller_decorator.META.builderGuilds, [
|
|
92
99
|
...options.guilds
|
|
93
100
|
], target);
|
|
101
|
+
else {
|
|
102
|
+
const base = guildsBase(target);
|
|
103
|
+
if (base) {
|
|
104
|
+
logger$3.warn(`${target.name} gives no guilds and inherits ${base.name}'s; declare guilds on ${target.name} to keep them. ` + 'The next major version (5.0) registers it in the configured scope.');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
94
107
|
});
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
111
|
+
* Marks a class as a controller, whose methods handle commands, components, messages, reactions or events.
|
|
112
|
+
*
|
|
113
|
+
* Use it on every class of handlers, and list the class in `@MeoCord({ controllers })`. Logic the handlers
|
|
114
|
+
* share, such as database access, belongs in a service it injects.
|
|
115
|
+
*
|
|
116
|
+
* @remarks
|
|
117
|
+
* A controller's class-level guards and filters apply to every handler it declares or inherits, its interceptors to
|
|
118
|
+
* all but autocomplete, and its cooldowns to its command, component and message handlers; each also applies to the
|
|
119
|
+
* handlers of a class that extends it. A base wraps what extends it: guards and interceptors
|
|
120
|
+
* run the top base's first, then each subclass's, then the method's, and filters are tried the other way, the
|
|
121
|
+
* method's first. `inheritStages: false` keeps the handlers a subclass declares to its own stages.
|
|
122
|
+
*
|
|
123
|
+
* @param options - Whether the handlers it declares take the stages of the classes it extends.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* @Controller()
|
|
128
|
+
* export class ProfileSlashController {
|
|
129
|
+
* constructor(private readonly profiles: ProfileService) {}
|
|
130
|
+
*
|
|
131
|
+
* @Command('profile', CommandType.SLASH)
|
|
132
|
+
* async profile(interaction: ChatInputCommandInteraction) {
|
|
133
|
+
* await respond(interaction).send({ embeds: [await this.profiles.render(interaction.user.id)] })
|
|
134
|
+
* }
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @group Decorators
|
|
139
|
+
* @category Controllers
|
|
140
|
+
* @see {@link Command}
|
|
141
|
+
* @see {@link ControllerOptions}
|
|
142
|
+
* @see {@link https://meocord.dev/docs/4.2/how-a-call-runs | How a call runs}
|
|
143
|
+
*/ function Controller(options = {}) {
|
|
144
|
+
return controller_decorator.declaring(function(target, propertyKey) {
|
|
145
|
+
if (controller_decorator.deprecatedOnMethod('@Controller', target, propertyKey)) return;
|
|
146
|
+
providers.makeInjectable(target);
|
|
147
|
+
if (options.inheritStages === false) Reflect.defineMetadata(controller_decorator.META.inheritStages, false, target);
|
|
148
|
+
if (options.inheritedRoutes === 'replace') {
|
|
149
|
+
controller_decorator.dropInheritedRoutes(target.prototype);
|
|
150
|
+
Reflect.defineMetadata(controller_decorator.META.replacesInheritedRoutes, true, target.prototype);
|
|
151
|
+
}
|
|
152
|
+
providers.guardOwnHandlersWithBaseGuards(target);
|
|
153
|
+
});
|
|
132
154
|
}
|
|
155
|
+
|
|
133
156
|
/**
|
|
134
157
|
* The class's own descriptor for a handler. An inherited handler gets one that calls the inherited
|
|
135
158
|
* method, starting from its guard lists and wrapper count, so class guards wrap it like an own method.
|
|
@@ -157,26 +180,6 @@ require('chalk');
|
|
|
157
180
|
...inherited
|
|
158
181
|
};
|
|
159
182
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Gives each handler a controller declares itself the class-level guards of the classes it extends,
|
|
162
|
-
* as its inherited handlers have: recorded under `META.guards`, and wrapped so a direct call
|
|
163
|
-
* runs them when no other guard wraps the handler. `@Controller` calls this.
|
|
164
|
-
*/ function guardOwnHandlersWithBaseGuards(target) {
|
|
165
|
-
const prototype = target.prototype;
|
|
166
|
-
for (const methodName of providers.handlerMethods(prototype)){
|
|
167
|
-
const descriptor = Object.getOwnPropertyDescriptor(prototype, methodName);
|
|
168
|
-
// Inherited handlers have the chain of the class that declares them
|
|
169
|
-
if (typeof descriptor?.value !== 'function' || Reflect.getOwnMetadata(controller_decorator.META.inheritedFrom, prototype, methodName)) continue;
|
|
170
|
-
// Base first, as dispatch runs them
|
|
171
|
-
const guards = providers.classChain(prototype, prototype).slice(1).reverse().flatMap(providers.classLevelGuards);
|
|
172
|
-
if (guards.length === 0) continue;
|
|
173
|
-
if (!Reflect.getOwnMetadata(controller_decorator.META.guardWrappers, prototype, methodName)) {
|
|
174
|
-
applyGuards(descriptor, prototype, methodName);
|
|
175
|
-
Object.defineProperty(prototype, methodName, descriptor);
|
|
176
|
-
}
|
|
177
|
-
recordGuards(controller_decorator.META.inheritedGuards, guards, prototype, methodName);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
183
|
/**
|
|
181
184
|
* Marks a class as a guard, which decides whether a handler runs.
|
|
182
185
|
*
|
|
@@ -250,12 +253,12 @@ require('chalk');
|
|
|
250
253
|
*/ function UseGuard(...entries) {
|
|
251
254
|
const guards = entries;
|
|
252
255
|
return controller_decorator.declaring(function(target, propertyKey, descriptor) {
|
|
253
|
-
const where =
|
|
256
|
+
const where = controller_decorator.decoratedName(target, propertyKey);
|
|
254
257
|
providers.assertStageEntries('@UseGuard', 'guard', where, guards);
|
|
255
258
|
if (descriptor && propertyKey) {
|
|
256
259
|
// Method Decorator
|
|
257
|
-
applyGuards(descriptor, target, String(propertyKey));
|
|
258
|
-
recordGuards(controller_decorator.META.methodGuards, guards, target, String(propertyKey));
|
|
260
|
+
providers.applyGuards(descriptor, target, String(propertyKey));
|
|
261
|
+
providers.recordGuards(controller_decorator.META.methodGuards, guards, target, String(propertyKey));
|
|
259
262
|
} else if (typeof target === 'function' && !propertyKey && !descriptor) {
|
|
260
263
|
// Class Decorator
|
|
261
264
|
const prototype = target.prototype;
|
|
@@ -268,61 +271,15 @@ require('chalk');
|
|
|
268
271
|
for (const methodName of methods){
|
|
269
272
|
const methodDescriptor = ownHandlerDescriptor(prototype, methodName);
|
|
270
273
|
if (methodDescriptor) {
|
|
271
|
-
applyGuards(methodDescriptor, prototype, methodName);
|
|
274
|
+
providers.applyGuards(methodDescriptor, prototype, methodName);
|
|
272
275
|
Object.defineProperty(prototype, methodName, methodDescriptor);
|
|
273
|
-
recordGuards(controller_decorator.META.classGuards, guards, prototype, methodName);
|
|
276
|
+
providers.recordGuards(controller_decorator.META.classGuards, guards, prototype, methodName);
|
|
274
277
|
}
|
|
275
278
|
}
|
|
276
279
|
}
|
|
277
280
|
});
|
|
278
281
|
}
|
|
279
282
|
|
|
280
|
-
/**
|
|
281
|
-
* Marks a class as a controller, whose methods handle commands, components, messages, reactions or events.
|
|
282
|
-
*
|
|
283
|
-
* Use it on every class of handlers, and list the class in `@MeoCord({ controllers })`. Logic the handlers
|
|
284
|
-
* share, such as database access, belongs in a service it injects.
|
|
285
|
-
*
|
|
286
|
-
* @remarks
|
|
287
|
-
* A controller's class-level guards and filters apply to every handler it declares or inherits, its interceptors to
|
|
288
|
-
* all but autocomplete, and its cooldowns to its command, component and message handlers; each also applies to the
|
|
289
|
-
* handlers of a class that extends it. A base wraps what extends it: guards and interceptors
|
|
290
|
-
* run the top base's first, then each subclass's, then the method's, and filters are tried the other way, the
|
|
291
|
-
* method's first. `inheritStages: false` keeps the handlers a subclass declares to its own stages.
|
|
292
|
-
*
|
|
293
|
-
* @param options - Whether the handlers it declares take the stages of the classes it extends.
|
|
294
|
-
*
|
|
295
|
-
* @example
|
|
296
|
-
* ```ts
|
|
297
|
-
* @Controller()
|
|
298
|
-
* export class ProfileSlashController {
|
|
299
|
-
* constructor(private readonly profiles: ProfileService) {}
|
|
300
|
-
*
|
|
301
|
-
* @Command('profile', CommandType.SLASH)
|
|
302
|
-
* async profile(interaction: ChatInputCommandInteraction) {
|
|
303
|
-
* await respond(interaction).send({ embeds: [await this.profiles.render(interaction.user.id)] })
|
|
304
|
-
* }
|
|
305
|
-
* }
|
|
306
|
-
* ```
|
|
307
|
-
*
|
|
308
|
-
* @group Decorators
|
|
309
|
-
* @category Controllers
|
|
310
|
-
* @see {@link Command}
|
|
311
|
-
* @see {@link ControllerOptions}
|
|
312
|
-
* @see {@link https://meocord.dev/docs/4.2/how-a-call-runs | How a call runs}
|
|
313
|
-
*/ function Controller(options = {}) {
|
|
314
|
-
return controller_decorator.declaring(function(target, propertyKey) {
|
|
315
|
-
if (controller_decorator.deprecatedOnMethod('@Controller', target, propertyKey)) return;
|
|
316
|
-
providers.makeInjectable(target);
|
|
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
|
-
}
|
|
322
|
-
guardOwnHandlersWithBaseGuards(target);
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
|
|
326
283
|
/**
|
|
327
284
|
* Marks a class as an interceptor, which wraps a handler to act before and after it.
|
|
328
285
|
*
|
|
@@ -395,7 +352,7 @@ require('chalk');
|
|
|
395
352
|
* @see {@link https://meocord.dev/docs/4.2/interceptors | Interceptors}
|
|
396
353
|
*/ function UseInterceptor(...interceptors) {
|
|
397
354
|
return controller_decorator.declaring(function(target, propertyKey) {
|
|
398
|
-
const where =
|
|
355
|
+
const where = controller_decorator.decoratedName(target, propertyKey);
|
|
399
356
|
providers.assertStageEntries('@UseInterceptor', 'interceptor', where, interceptors);
|
|
400
357
|
// Decorators apply bottom-up, so a higher decorator's interceptors go first, as with @UseGuard.
|
|
401
358
|
if (propertyKey === undefined) {
|
|
@@ -449,12 +406,12 @@ require('chalk');
|
|
|
449
406
|
errorTypes.forEach((type, index)=>{
|
|
450
407
|
if (controller_decorator.isConstructible(type)) return;
|
|
451
408
|
const entry = ORDINALS[index] ? `${ORDINALS[index]} entry` : `entry ${index + 1}`;
|
|
452
|
-
controller_decorator.warnDeprecatedBehaviour(logger$
|
|
409
|
+
controller_decorator.warnDeprecatedBehaviour(logger$2, `${target.name}: @Catch's ${entry}, ${controller_decorator.describeValue(type)}, which matches no error,`, 'is refused', 'an error class, such as @Catch(CooldownError),');
|
|
453
410
|
});
|
|
454
411
|
Reflect.defineMetadata(controller_decorator.META.catchTypes, errorTypes, target);
|
|
455
412
|
});
|
|
456
413
|
}
|
|
457
|
-
const logger$
|
|
414
|
+
const logger$2 = new controller_decorator.Logger('Catch');
|
|
458
415
|
const ORDINALS = [
|
|
459
416
|
'first',
|
|
460
417
|
'second',
|
|
@@ -495,7 +452,7 @@ const ORDINALS = [
|
|
|
495
452
|
* @see {@link https://meocord.dev/docs/4.2/exception-filters | Exception filters}
|
|
496
453
|
*/ function UseFilter(...filters) {
|
|
497
454
|
return controller_decorator.declaring(function(target, propertyKey) {
|
|
498
|
-
const where =
|
|
455
|
+
const where = controller_decorator.decoratedName(target, propertyKey);
|
|
499
456
|
providers.assertStageEntries('@UseFilter', 'filter', where, filters);
|
|
500
457
|
// Decorators apply bottom-up, so a higher decorator's filters are tried first.
|
|
501
458
|
if (propertyKey === undefined) {
|
|
@@ -514,6 +471,7 @@ const ORDINALS = [
|
|
|
514
471
|
});
|
|
515
472
|
}
|
|
516
473
|
|
|
474
|
+
const logger$1 = new controller_decorator.Logger('MeoCord');
|
|
517
475
|
/** Refuses a `messages` option of the wrong type where the app is declared, rather than at the first message. */ function assertMessageOptions(appName, messages, i18n) {
|
|
518
476
|
if (!messages) return;
|
|
519
477
|
const { prefix, mention, caseSensitive } = messages;
|
|
@@ -541,6 +499,9 @@ const ORDINALS = [
|
|
|
541
499
|
if (deleteUsageRepliesAfter !== undefined && !(typeof deleteUsageRepliesAfter === 'number' && deleteUsageRepliesAfter >= 0 && Number.isFinite(deleteUsageRepliesAfter))) {
|
|
542
500
|
throw controller_decorator.refuse(new TypeError(`${appName}: @MeoCord({ messages: { deleteUsageRepliesAfter } }) takes a number of seconds, or 0 to keep usage replies.`));
|
|
543
501
|
}
|
|
502
|
+
if (deleteUsageRepliesAfter !== undefined && !providers.timerKeepsSeconds(deleteUsageRepliesAfter)) {
|
|
503
|
+
logger$1.warn(`${appName}: @MeoCord({ messages: { deleteUsageRepliesAfter } }) is ${deleteUsageRepliesAfter} seconds, longer than a timer ` + `can wait (${providers.MAX_TIMER_SECONDS}), so usage replies are kept. The next major version (5.0) refuses it.`);
|
|
504
|
+
}
|
|
544
505
|
const { help } = messages;
|
|
545
506
|
// One word each, since help is asked for by its first word
|
|
546
507
|
const isWord = (value)=>typeof value === 'string' && /^\S+$/.test(value);
|
|
@@ -723,15 +684,15 @@ const ORDINALS = [
|
|
|
723
684
|
controller_decorator.refuseOnClass('@Validate', target, propertyKey);
|
|
724
685
|
// Checked where it applies, so the refusal names the handler
|
|
725
686
|
if (typeof schema?.['~standard']?.validate !== 'function') {
|
|
726
|
-
throw controller_decorator.refuse(new Error(`${target
|
|
687
|
+
throw controller_decorator.refuse(new Error(`${controller_decorator.decoratedName(target, propertyKey)}: @Validate takes a Standard Schema, such as a zod, valibot or arktype schema.`));
|
|
727
688
|
}
|
|
728
689
|
if (Reflect.hasOwnMetadata(controller_decorator.META.methodValidation, target, propertyKey)) {
|
|
729
|
-
throw controller_decorator.refuse(new Error(`${target
|
|
690
|
+
throw controller_decorator.refuse(new Error(`${controller_decorator.decoratedName(target, propertyKey)}: more than one @Validate; one @Validate per handler: combine the schemas into one.`));
|
|
730
691
|
}
|
|
731
692
|
const inlinePipes = Object.values(options.pipes ?? {}).flatMap((entries)=>Array.isArray(entries) ? entries : [
|
|
732
693
|
entries
|
|
733
694
|
]);
|
|
734
|
-
providers.assertStageEntries('@Validate', 'pipe',
|
|
695
|
+
providers.assertStageEntries('@Validate', 'pipe', controller_decorator.decoratedName(target, propertyKey), inlinePipes);
|
|
735
696
|
const metadata = {
|
|
736
697
|
schema,
|
|
737
698
|
pipes: options.pipes ?? {}
|
|
@@ -773,7 +734,7 @@ const ORDINALS = [
|
|
|
773
734
|
*/ function UsePipe(key, ...pipes) {
|
|
774
735
|
return controller_decorator.declaring(function(target, propertyKey, _descriptor) {
|
|
775
736
|
controller_decorator.refuseOnClass('@UsePipe', target, propertyKey);
|
|
776
|
-
providers.assertStageEntries('@UsePipe', 'pipe',
|
|
737
|
+
providers.assertStageEntries('@UsePipe', 'pipe', controller_decorator.decoratedName(target, propertyKey), pipes);
|
|
777
738
|
// Decorators apply bottom-up, so a higher @UsePipe's pipes go first, in the order they read.
|
|
778
739
|
const existing = Reflect.getOwnMetadata(controller_decorator.META.methodPipes, target, propertyKey) ?? [];
|
|
779
740
|
Reflect.defineMetadata(controller_decorator.META.methodPipes, [
|
|
@@ -921,7 +882,7 @@ const logger = new controller_decorator.Logger('Cooldown');
|
|
|
921
882
|
controller_decorator.refuseOnClass('@Defer', target, propertyKey);
|
|
922
883
|
const methodName = String(propertyKey);
|
|
923
884
|
const kind = providers.nonInteractionHandler(target, methodName);
|
|
924
|
-
if (kind) throw controller_decorator.refuse(providers.deferMisuseError(target
|
|
885
|
+
if (kind) throw controller_decorator.refuse(providers.deferMisuseError(controller_decorator.ownerName(target), methodName, kind));
|
|
925
886
|
Reflect.defineMetadata(controller_decorator.META.deferOptions, {
|
|
926
887
|
...options
|
|
927
888
|
}, target, methodName);
|
|
@@ -957,6 +918,9 @@ const logger = new controller_decorator.Logger('Cooldown');
|
|
|
957
918
|
return controller_decorator.declaring((target, propertyKey, parameterIndex)=>{
|
|
958
919
|
// A constructor parameter has no property key either, but has an index
|
|
959
920
|
if (typeof parameterIndex !== 'number') controller_decorator.refuseOnClass('@Inject', target, propertyKey, 'a constructor parameter or a property');
|
|
921
|
+
else if (propertyKey !== undefined) {
|
|
922
|
+
throw controller_decorator.refuse(new Error(`${controller_decorator.decoratedName(target, propertyKey)}: @Inject goes on a constructor parameter or a property, not a method parameter.`));
|
|
923
|
+
}
|
|
960
924
|
decorate(target, propertyKey, parameterIndex);
|
|
961
925
|
});
|
|
962
926
|
}
|
|
@@ -1037,8 +1001,9 @@ const logger = new controller_decorator.Logger('Cooldown');
|
|
|
1037
1001
|
*/ function UseTheme(theme) {
|
|
1038
1002
|
return controller_decorator.declaring(function(target, propertyKey) {
|
|
1039
1003
|
const onClass = propertyKey === undefined;
|
|
1040
|
-
|
|
1041
|
-
const
|
|
1004
|
+
// The class it themes: the target itself on a class or a static member, else the target's constructor
|
|
1005
|
+
const owner = onClass || typeof target === 'function' ? target : target.constructor;
|
|
1006
|
+
const where = `${controller_decorator.decoratedName(target, propertyKey)}: @UseTheme`;
|
|
1042
1007
|
controller_decorator.assertValidTheme(theme, where);
|
|
1043
1008
|
const key = onClass ? controller_decorator.META.classTheme : controller_decorator.META.methodTheme;
|
|
1044
1009
|
const existing = onClass ? Reflect.getOwnMetadata(key, target) : Reflect.getOwnMetadata(key, target, propertyKey);
|