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.
- package/CHANGELOG.md +98 -0
- 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 +733 -301
- 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 +223 -72
- 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,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var controller_decorator = require('./controller.decorator-
|
|
3
|
+
var controller_decorator = require('./controller.decorator-CRn9kWob.cjs');
|
|
4
4
|
require('reflect-metadata');
|
|
5
5
|
var node_async_hooks = require('node:async_hooks');
|
|
6
6
|
var inversify = require('inversify');
|
|
@@ -101,7 +101,7 @@ var Table__default = /*#__PURE__*/_interopDefaultCompat(Table);
|
|
|
101
101
|
|
|
102
102
|
function eventDecorator(event, once) {
|
|
103
103
|
// Generic over the method, so it is checked against the event's arguments rather than required to match exactly
|
|
104
|
-
return function(target, propertyKey, _descriptor) {
|
|
104
|
+
return controller_decorator.declaring(function(target, propertyKey, _descriptor) {
|
|
105
105
|
controller_decorator.refuseOnClass(once ? '@Once' : '@On', target, propertyKey);
|
|
106
106
|
const handlers = controller_decorator.ownHandlerList(controller_decorator.META.eventHandlers, target);
|
|
107
107
|
handlers.push({
|
|
@@ -110,7 +110,7 @@ function eventDecorator(event, once) {
|
|
|
110
110
|
once
|
|
111
111
|
});
|
|
112
112
|
Reflect.defineMetadata(controller_decorator.META.eventHandlers, handlers, target);
|
|
113
|
-
};
|
|
113
|
+
});
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
116
|
* Handles a discord.js client event every time it is emitted, on a controller or a service.
|
|
@@ -138,7 +138,7 @@ function eventDecorator(event, once) {
|
|
|
138
138
|
* @group Decorators
|
|
139
139
|
* @category Handlers
|
|
140
140
|
* @see {@link Once}
|
|
141
|
-
* @see {@link https://meocord.dev/docs/4.
|
|
141
|
+
* @see {@link https://meocord.dev/docs/4.2/gateway-events | Gateway events}
|
|
142
142
|
*/ function On(event) {
|
|
143
143
|
return eventDecorator(event, false);
|
|
144
144
|
}
|
|
@@ -165,7 +165,7 @@ function eventDecorator(event, once) {
|
|
|
165
165
|
* @group Decorators
|
|
166
166
|
* @category Handlers
|
|
167
167
|
* @see {@link On}
|
|
168
|
-
* @see {@link https://meocord.dev/docs/4.
|
|
168
|
+
* @see {@link https://meocord.dev/docs/4.2/gateway-events | Gateway events}
|
|
169
169
|
*/ function Once(event) {
|
|
170
170
|
return eventDecorator(event, true);
|
|
171
171
|
}
|
|
@@ -1376,7 +1376,7 @@ function isInterceptorWithParams(entry) {
|
|
|
1376
1376
|
});
|
|
1377
1377
|
/** Binds `cls` and its unbound dependencies as singletons, refusing any that injects `ExecutionContext`. */ function bindShared(container, cls) {
|
|
1378
1378
|
if (container.isBound(cls)) return;
|
|
1379
|
-
if (injectedTokens(cls).includes(controller_decorator.ExecutionContext))
|
|
1379
|
+
if (injectedTokens(cls).includes(controller_decorator.ExecutionContext)) return controller_decorator.startupError(singletonContextError(cls));
|
|
1380
1380
|
assertStartupChecked(container, cls);
|
|
1381
1381
|
makeInjectable(cls);
|
|
1382
1382
|
container.bind(cls).toSelf().inSingletonScope();
|
|
@@ -1571,7 +1571,7 @@ function isInterceptorWithParams(entry) {
|
|
|
1571
1571
|
/** Binds a filter as a singleton, after checking it is one. */ function prepareFilter(container, entry) {
|
|
1572
1572
|
const cls = filterClass(entry);
|
|
1573
1573
|
if (!Reflect.hasOwnMetadata(controller_decorator.META.catchTypes, cls)) {
|
|
1574
|
-
|
|
1574
|
+
return controller_decorator.startupError(new Error(`${cls.name || 'A filter'}: used as an exception filter, but not decorated with @Catch().`));
|
|
1575
1575
|
}
|
|
1576
1576
|
bindShared(container, cls);
|
|
1577
1577
|
}
|
|
@@ -1683,11 +1683,12 @@ const asList = (entries)=>Array.isArray(entries) ? entries : [
|
|
|
1683
1683
|
|
|
1684
1684
|
/** Where a container keeps the observers its calls are reported to, in order. */ const OBSERVERS = Symbol('observers');
|
|
1685
1685
|
const logger$1 = new controller_decorator.Logger('Observer');
|
|
1686
|
-
/**
|
|
1686
|
+
/** Reports each entry that is not an `@Observer` class, naming where it was listed. */ function assertObservers(where, observers) {
|
|
1687
1687
|
for (const observer of observers){
|
|
1688
1688
|
if (typeof observer !== 'function' || !Reflect.getMetadata(controller_decorator.META.observerClass, observer)) {
|
|
1689
1689
|
const name = typeof observer === 'function' ? observer.name : String(observer);
|
|
1690
|
-
|
|
1690
|
+
controller_decorator.startupError(new Error(`${where} takes classes decorated with @Observer(), not ${name}.`));
|
|
1691
|
+
continue;
|
|
1691
1692
|
}
|
|
1692
1693
|
}
|
|
1693
1694
|
}
|
|
@@ -1942,12 +1943,16 @@ const NO_GLOBAL_STAGES = {
|
|
|
1942
1943
|
*/ function bindAppPresenter(container, app, client) {
|
|
1943
1944
|
const options = Reflect.getMetadata(controller_decorator.META.appOptions, app);
|
|
1944
1945
|
if (!options?.presenter) return undefined;
|
|
1945
|
-
|
|
1946
|
+
prepareAppPresenter(container, app);
|
|
1946
1947
|
const presenter = container.get(options.presenter);
|
|
1947
1948
|
container.bind(APP_PRESENTER).toConstantValue(presenter);
|
|
1948
1949
|
if (client) controller_decorator.setPresenter(client, presenter);
|
|
1949
1950
|
return presenter;
|
|
1950
1951
|
}
|
|
1952
|
+
/** Binds the app's presenter class as a shared stage, checking it as one, without making it. */ function prepareAppPresenter(container, app) {
|
|
1953
|
+
const options = Reflect.getMetadata(controller_decorator.META.appOptions, app);
|
|
1954
|
+
if (options?.presenter) bindShared(container, options.presenter);
|
|
1955
|
+
}
|
|
1951
1956
|
/** Where a container keeps the application's presenter. */ const APP_PRESENTER = Symbol('app_presenter');
|
|
1952
1957
|
/** The presenter `bindAppPresenter` resolved into `container`, if any. */ function appPresenterOf(container) {
|
|
1953
1958
|
return container.isBound(APP_PRESENTER) ? container.get(APP_PRESENTER) : undefined;
|
|
@@ -2037,18 +2042,21 @@ const stagesByGlobals = new WeakMap();
|
|
|
2037
2042
|
/**
|
|
2038
2043
|
* Binds the interceptors, filters and pipes every handler of `controllers` uses, and the global ones, as singletons, so
|
|
2039
2044
|
* one that cannot be shared, or a filter without `@Catch`, fails at startup; refuses there `@Defer`, `@Validate`,
|
|
2040
|
-
* `@UsePipe` and `@Cooldown` where they cannot apply, and two classes that keep state under one name.
|
|
2045
|
+
* `@UsePipe` and `@Cooldown` where they cannot apply, and two classes that keep state under one name. Binds only; it
|
|
2046
|
+
* makes nothing, so it runs with the other startup checks.
|
|
2041
2047
|
*/ function prepareHandlerStages(container, controllers) {
|
|
2042
2048
|
assertDistinctNamesWhereKeyed(controllers);
|
|
2043
2049
|
const globals = globalStagesOf(container);
|
|
2044
|
-
configureThemes(container, globals.theme, controllers, globals.themeFor);
|
|
2045
2050
|
for (const entry of globals.interceptors)prepareInterceptor(container, entry);
|
|
2046
2051
|
for (const entry of globals.filters)prepareFilter(container, entry);
|
|
2047
2052
|
for (const controller of controllers){
|
|
2048
2053
|
const prototype = controller.prototype;
|
|
2049
2054
|
for (const method of handlerMethods(prototype)){
|
|
2050
2055
|
const kind = handlerDefer(prototype, method) ? nonInteractionHandler(prototype, method) : undefined;
|
|
2051
|
-
if (kind)
|
|
2056
|
+
if (kind) {
|
|
2057
|
+
controller_decorator.startupError(deferMisuseError(controller.name, method, kind));
|
|
2058
|
+
continue;
|
|
2059
|
+
}
|
|
2052
2060
|
for (const entry of handlerInterceptors(prototype, method))prepareInterceptor(container, entry);
|
|
2053
2061
|
for (const entry of handlerFilterLevels(prototype, method, []).flat())prepareFilter(container, entry);
|
|
2054
2062
|
for (const { entry } of handlerInputStages(prototype, method).pipes)preparePipe(container, entry);
|
|
@@ -2056,6 +2064,10 @@ const stagesByGlobals = new WeakMap();
|
|
|
2056
2064
|
assertInputStagesOnInteractions(controller, prototype);
|
|
2057
2065
|
}
|
|
2058
2066
|
}
|
|
2067
|
+
/** Records the app's theme for the handlers of `controllers`, once the startup checks have passed: it makes the theme cache. */ function prepareThemes(container, controllers) {
|
|
2068
|
+
const globals = globalStagesOf(container);
|
|
2069
|
+
configureThemes(container, globals.theme, controllers, globals.themeFor);
|
|
2070
|
+
}
|
|
2059
2071
|
/** Whether a class has state keyed by its name: a cooldown on a handler, or a `@Once` handler. */ function keyedByName(cls) {
|
|
2060
2072
|
const prototype = cls.prototype;
|
|
2061
2073
|
const handlers = [
|
|
@@ -2072,7 +2084,8 @@ const stagesByGlobals = new WeakMap();
|
|
|
2072
2084
|
for (const cls of classes){
|
|
2073
2085
|
const other = byName.get(cls.name);
|
|
2074
2086
|
if (other && other !== cls && (keyedByName(cls) || keyedByName(other))) {
|
|
2075
|
-
|
|
2087
|
+
controller_decorator.startupError(new Error(`${cls.name}: two classes have this name; @Cooldown and @Once tell classes apart by name, so they would share ` + `their counts. Rename one of them.`));
|
|
2088
|
+
continue;
|
|
2076
2089
|
}
|
|
2077
2090
|
byName.set(cls.name, cls);
|
|
2078
2091
|
}
|
|
@@ -2100,11 +2113,12 @@ const stagesByGlobals = new WeakMap();
|
|
|
2100
2113
|
const { schema, pipes } = handlerInputStages(prototype, method);
|
|
2101
2114
|
const handler = kind === 'message' ? 'a message handler without a pattern' : `${kind === 'autocomplete' || kind === 'event' ? 'an' : 'a'} ${kind} handler`;
|
|
2102
2115
|
if (schema || pipes.length > 0) {
|
|
2103
|
-
|
|
2116
|
+
controller_decorator.startupError(new Error(`${controller.name}.${method}: @Validate and @UsePipe are for interaction and patterned message handlers, ` + `whose options, customId params, modal fields and pattern params they check, and this is ${handler}.`));
|
|
2117
|
+
continue;
|
|
2104
2118
|
}
|
|
2105
2119
|
// A controller's own @Cooldown skips these handlers; one on the method itself is a mistake.
|
|
2106
2120
|
if (kind !== 'message' && methodCooldowns(prototype, method).length > 0) {
|
|
2107
|
-
|
|
2121
|
+
controller_decorator.startupError(new Error(`${controller.name}.${method}: @Cooldown is for interaction and message handlers, and this is ${handler}.`));
|
|
2108
2122
|
}
|
|
2109
2123
|
}
|
|
2110
2124
|
}
|
|
@@ -3261,7 +3275,8 @@ const FLAG = /^\{--(\w+)(?::([\w-]+(?:\|[\w-]+)*))?(\?)?\}$/;
|
|
|
3261
3275
|
if (own.hidden !== undefined && typeof own.hidden !== 'boolean') throw new Error(`hidden is true or false, not ${JSON.stringify(own.hidden)}.`);
|
|
3262
3276
|
aliases = aliasPatterns(pattern, parsed.tokens, own.aliases);
|
|
3263
3277
|
} catch (error) {
|
|
3264
|
-
|
|
3278
|
+
controller_decorator.startupError(new Error(`${controllerClass.name}.${method}: @MessageHandler('${pattern}'): ${error.message}`));
|
|
3279
|
+
continue;
|
|
3265
3280
|
}
|
|
3266
3281
|
const shared = {
|
|
3267
3282
|
controllerClass,
|
|
@@ -3300,7 +3315,7 @@ const FLAG = /^\{--(\w+)(?::([\w-]+(?:\|[\w-]+)*))?(\?)?\}$/;
|
|
|
3300
3315
|
routes.splice(j--, 1);
|
|
3301
3316
|
continue;
|
|
3302
3317
|
}
|
|
3303
|
-
|
|
3318
|
+
controller_decorator.startupError(new Error(`${a.controllerClass.name}.${a.method}: ${describeRoute(a)} and ${describeRoute(b)} in ${b.controllerClass.name}.${b.method} ` + `match the same messages, so only one of them could ever answer those. Change one pattern, or give one its own prefix.`));
|
|
3304
3319
|
}
|
|
3305
3320
|
}
|
|
3306
3321
|
return routes;
|
|
@@ -4179,7 +4194,7 @@ const COMMAND_TYPES = new Set([
|
|
|
4179
4194
|
*
|
|
4180
4195
|
* @group Controllers
|
|
4181
4196
|
* @see {@link HandlerEntry}
|
|
4182
|
-
* @see {@link https://meocord.dev/docs/4.
|
|
4197
|
+
* @see {@link https://meocord.dev/docs/4.2/handler-discovery | Handler discovery}
|
|
4183
4198
|
*/ class HandlerRegistry {
|
|
4184
4199
|
/**
|
|
4185
4200
|
* Lists the registered handlers.
|
|
@@ -4424,7 +4439,7 @@ async function withTimeout(promise, ms, what) {
|
|
|
4424
4439
|
*
|
|
4425
4440
|
* @group Controllers
|
|
4426
4441
|
* @see {@link ShardCallResult}
|
|
4427
|
-
* @see {@link https://meocord.dev/docs/4.
|
|
4442
|
+
* @see {@link https://meocord.dev/docs/4.2/sharding | Sharding}
|
|
4428
4443
|
*/ class ShardContext {
|
|
4429
4444
|
/** The ids of the shards this process runs. With process sharding, one id; otherwise every shard, once ready. */ get ids() {
|
|
4430
4445
|
if (this.client?.shard) return [
|
|
@@ -4601,9 +4616,9 @@ const isFactoryProvider = (provider)=>'useFactory' in provider;
|
|
|
4601
4616
|
}
|
|
4602
4617
|
const isToken = (value)=>typeof value === 'function' || typeof value === 'string' || typeof value === 'symbol';
|
|
4603
4618
|
/**
|
|
4604
|
-
* Checks each provider's shape and indexes them by token,
|
|
4605
|
-
*
|
|
4606
|
-
*
|
|
4619
|
+
* Checks each provider's shape and indexes them by token, reporting each that cannot be bound, such as one with no
|
|
4620
|
+
* token, not exactly one of `useValue`, `useClass` and `useFactory`, one that injects `ExecutionContext`, or a token
|
|
4621
|
+
* provided twice, as a startup error; see `startupError`.
|
|
4607
4622
|
*/ function providerMap(providers, where) {
|
|
4608
4623
|
const map = new Map();
|
|
4609
4624
|
for (const provider of providers){
|
|
@@ -4612,10 +4627,12 @@ const isToken = (value)=>typeof value === 'function' || typeof value === 'string
|
|
|
4612
4627
|
if (typeof entry === 'function') {
|
|
4613
4628
|
const name = tokenName(entry);
|
|
4614
4629
|
const listing = where.includes('@MeoCord') ? 'list a service in @MeoCord({ services })' : 'a class a controller or service injects is bound for you, so it needs no listing';
|
|
4615
|
-
|
|
4630
|
+
controller_decorator.startupError(new Error(`${where}: ${name} is a class, not a provider: ${listing}. To put something in its place, write ` + `{ provide: ${name}, useValue } or { provide: ${name}, useClass }.`));
|
|
4631
|
+
continue;
|
|
4616
4632
|
}
|
|
4617
4633
|
if (!entry || typeof entry !== 'object' || !isToken(entry.provide)) {
|
|
4618
|
-
|
|
4634
|
+
controller_decorator.startupError(new Error(`${where}: a provider has no token: set provide to a class, a string or a symbol.`));
|
|
4635
|
+
continue;
|
|
4619
4636
|
}
|
|
4620
4637
|
const name = tokenName(entry.provide);
|
|
4621
4638
|
const kinds = [
|
|
@@ -4624,26 +4641,35 @@ const isToken = (value)=>typeof value === 'function' || typeof value === 'string
|
|
|
4624
4641
|
'useFactory'
|
|
4625
4642
|
].filter((kind)=>kind in entry);
|
|
4626
4643
|
if (kinds.length !== 1) {
|
|
4627
|
-
|
|
4644
|
+
controller_decorator.startupError(new Error(`${where}: the provider for ${name} needs exactly one of useValue, useClass and useFactory.`));
|
|
4645
|
+
continue;
|
|
4628
4646
|
}
|
|
4629
4647
|
if ('useClass' in entry && typeof entry.useClass !== 'function') {
|
|
4630
|
-
|
|
4648
|
+
controller_decorator.startupError(new Error(`${where}: the provider for ${name} has a useClass that is not a class.`));
|
|
4649
|
+
continue;
|
|
4631
4650
|
}
|
|
4632
4651
|
if ('useClass' in entry && injectedTokens(entry.useClass).includes(controller_decorator.ExecutionContext)) {
|
|
4633
|
-
|
|
4652
|
+
controller_decorator.startupError(new Error(`${where}: the provider for ${name} uses ${tokenName(entry.useClass)}, which injects ExecutionContext, but it is ` + "made once and shared, so it would keep the first call's context for every later call. Inject " + 'ExecutionContext only into guards.'));
|
|
4653
|
+
continue;
|
|
4634
4654
|
}
|
|
4635
4655
|
if ('useFactory' in entry) {
|
|
4636
4656
|
if (typeof entry.useFactory !== 'function') {
|
|
4637
|
-
|
|
4657
|
+
controller_decorator.startupError(new Error(`${where}: the provider for ${name} has a useFactory that is not a function.`));
|
|
4658
|
+
continue;
|
|
4638
4659
|
}
|
|
4639
4660
|
if (entry.inject !== undefined && !(Array.isArray(entry.inject) && entry.inject.every(isToken))) {
|
|
4640
|
-
|
|
4661
|
+
controller_decorator.startupError(new Error(`${where}: the provider for ${name} has an inject that is not a list of tokens.`));
|
|
4662
|
+
continue;
|
|
4641
4663
|
}
|
|
4642
4664
|
if (entry.inject?.includes(controller_decorator.ExecutionContext)) {
|
|
4643
|
-
|
|
4665
|
+
controller_decorator.startupError(new Error(`${where}: the provider for ${name} injects ExecutionContext, but its factory runs once and its value is ` + "shared, so it would keep the first call's context for every later call. Inject ExecutionContext only into guards."));
|
|
4666
|
+
continue;
|
|
4644
4667
|
}
|
|
4645
4668
|
}
|
|
4646
|
-
if (map.has(entry.provide))
|
|
4669
|
+
if (map.has(entry.provide)) {
|
|
4670
|
+
controller_decorator.startupError(new Error(`${where}: ${name} is provided twice.`));
|
|
4671
|
+
continue;
|
|
4672
|
+
}
|
|
4647
4673
|
map.set(entry.provide, provider);
|
|
4648
4674
|
}
|
|
4649
4675
|
return map;
|
|
@@ -4696,22 +4722,23 @@ const isToken = (value)=>typeof value === 'function' || typeof value === 'string
|
|
|
4696
4722
|
for (const dependency of inject)if (isAppClassToken(dependency)) bindClass(dependency);
|
|
4697
4723
|
}
|
|
4698
4724
|
/**
|
|
4699
|
-
*
|
|
4700
|
-
*
|
|
4701
|
-
* never missing.
|
|
4725
|
+
* Reports a class or a factory that asks for a string or symbol token nothing binds, naming both, rather than failing
|
|
4726
|
+
* when the class is first resolved. A class token is bound on demand, so it is never missing.
|
|
4702
4727
|
*/ function assertProvided(container, providers, classes, where) {
|
|
4703
4728
|
const missing = (token)=>(typeof token === 'string' || typeof token === 'symbol') && !container.isBound(token);
|
|
4704
4729
|
for (const cls of classes){
|
|
4705
4730
|
const token = injectedTokens(cls).find(missing);
|
|
4706
4731
|
if (token !== undefined) {
|
|
4707
|
-
|
|
4732
|
+
controller_decorator.startupError(new Error(`${cls.name}: it injects ${tokenName(token)}, which nothing provides: add a provider for it to ${where}.`));
|
|
4733
|
+
continue;
|
|
4708
4734
|
}
|
|
4709
4735
|
}
|
|
4710
4736
|
for (const [provided, provider] of providers){
|
|
4711
4737
|
const dependencies = isFactoryProvider(provider) ? provider.inject ?? [] : isClassProvider(provider) ? injectedTokens(provider.useClass) : [];
|
|
4712
4738
|
const token = dependencies.find(missing);
|
|
4713
4739
|
if (token !== undefined) {
|
|
4714
|
-
|
|
4740
|
+
controller_decorator.startupError(new Error(`${tokenName(provided)}: its provider injects ${tokenName(token)}, which nothing provides: add a provider for it to ${where}.`));
|
|
4741
|
+
continue;
|
|
4715
4742
|
}
|
|
4716
4743
|
}
|
|
4717
4744
|
}
|
|
@@ -4744,16 +4771,21 @@ const isToken = (value)=>typeof value === 'function' || typeof value === 'string
|
|
|
4744
4771
|
*/ function assertTypedParameters(classes, decorators) {
|
|
4745
4772
|
for (const cls of classes){
|
|
4746
4773
|
const instead = meocordClassAdvice(cls);
|
|
4747
|
-
if (instead && undecoratedConstructor(cls))
|
|
4774
|
+
if (instead && undecoratedConstructor(cls)) {
|
|
4775
|
+
controller_decorator.startupError(new Error(`${cls.name}: MeoCord does not inject it; ${instead}.`));
|
|
4776
|
+
continue;
|
|
4777
|
+
}
|
|
4748
4778
|
if (undecoratedConstructor(cls)) {
|
|
4749
4779
|
const decorator = decorators.get(cls);
|
|
4750
|
-
|
|
4780
|
+
controller_decorator.startupError(new Error(`${cls.name}: its constructor takes parameters, but ${cls.name} has no decorator, so TypeScript recorded none of ` + `their types and it cannot be created. ${decorator ? `Decorate it with ${decorator}.` : 'Decorate it with @Service(), or give a class from a package a provider in @MeoCord({ providers }).'}`));
|
|
4781
|
+
continue;
|
|
4751
4782
|
}
|
|
4752
4783
|
const index = untypedParameter(cls);
|
|
4753
4784
|
if (index === -1) continue;
|
|
4754
4785
|
const injectors = classes.filter((other)=>other !== cls && injectedTokens(other).includes(cls)).map((other)=>other.name);
|
|
4755
4786
|
const injectedBy = injectors.length === 0 ? '' : ` (${injectors.length === 1 ? injectors[0] : `${injectors.slice(0, -1).join(', ')} and ${injectors.at(-1)}`} ` + `inject${injectors.length === 1 ? 's' : ''} ${cls.name})`;
|
|
4756
|
-
|
|
4787
|
+
controller_decorator.startupError(new Error(`${cls.name}: parameter ${index + 1} of its constructor has no runtime type, so it cannot be created. Usually ` + `${cls.name} and a class it injects import each other${injectedBy}, or the parameter is typed with an ` + 'interface or an `import type`. Move what they both need into a third service, or inject the parameter ' + 'with @Inject(token).'));
|
|
4788
|
+
continue;
|
|
4757
4789
|
}
|
|
4758
4790
|
}
|
|
4759
4791
|
/** For each container, the tokens MeoCord binds itself, each to the app's class it stands for, if any. */ const ownTokens = new WeakMap();
|
|
@@ -4904,7 +4936,9 @@ exports.messageStartsFor = messageStartsFor;
|
|
|
4904
4936
|
exports.needsGuild = needsGuild;
|
|
4905
4937
|
exports.nonInteractionHandler = nonInteractionHandler;
|
|
4906
4938
|
exports.observeUnclaimed = observeUnclaimed;
|
|
4939
|
+
exports.prepareAppPresenter = prepareAppPresenter;
|
|
4907
4940
|
exports.prepareHandlerStages = prepareHandlerStages;
|
|
4941
|
+
exports.prepareThemes = prepareThemes;
|
|
4908
4942
|
exports.providerMap = providerMap;
|
|
4909
4943
|
exports.reachableClasses = reachableClasses;
|
|
4910
4944
|
exports.registerClientTheme = registerClientTheme;
|
package/dist/cjs/_shared/{sharded-cooldown-store-B65iaiAy.cjs → sharded-cooldown-store-BdAUTdYs.cjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var node_crypto = require('node:crypto');
|
|
4
|
-
var controller_decorator = require('./controller.decorator-
|
|
4
|
+
var controller_decorator = require('./controller.decorator-CRn9kWob.cjs');
|
|
5
5
|
|
|
6
6
|
/** The `fatal` code of a shard whose app MeoCord refused, which every shard would refuse alike. */ const REFUSED_CODE = 'Refused';
|
|
7
7
|
/** Whether an IPC message is one of MeoCord's own, rather than one of discord.js's. */ function isShardMessage(message) {
|