meocord 4.2.1 → 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 +188 -0
- package/dist/cjs/_shared/{controller.decorator-XKMlcUZz.cjs → controller.decorator-hp5xdJU4.cjs} +550 -189
- package/dist/cjs/_shared/{startup-roots-CgfPQrNl.cjs → event-sources-DzqTODXg.cjs} +274 -88
- package/dist/cjs/_shared/{providers-BZgJyfZS.cjs → providers-BBvbnmLP.cjs} +837 -295
- package/dist/cjs/_shared/{sharded-cooldown-store-CsJJyCZd.cjs → sharded-cooldown-store-B62g5O88.cjs} +11 -9
- package/dist/cjs/_shared/{translate-error-BUAR1WYG.cjs → translate-error-wsgfsUET.cjs} +1 -1
- package/dist/cjs/common/index.cjs +4 -104
- package/dist/cjs/core/index.cjs +435 -182
- package/dist/cjs/decorator/index.cjs +116 -121
- package/dist/cjs/testing/index.cjs +1923 -808
- 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 +32 -10
- package/dist/esm/common/sharded-cooldown-store.js +11 -9
- package/dist/esm/common/theme.js +3 -1
- package/dist/esm/common/translator.js +27 -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 +92 -66
- 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 +6 -6
- 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 +54 -32
- 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 +83 -54
- package/dist/esm/core/meocord.app.js +174 -89
- package/dist/esm/core/message-help.js +37 -15
- 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 +4 -2
- package/dist/esm/core/process-state.js +19 -0
- package/dist/esm/core/providers.js +39 -4
- 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/stage-scope.js +2 -1
- 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 +31 -30
- package/dist/esm/core/theme-validation.js +1 -1
- package/dist/esm/decorator/app.decorator.js +37 -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 +4 -4
- 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 +32 -25
- package/dist/esm/testing/cooldown-store-suite.js +3 -3
- package/dist/esm/testing/discord-defaults.js +449 -335
- package/dist/esm/testing/inspect-handler.js +91 -10
- package/dist/esm/testing/meocord-testing-module.js +217 -91
- package/dist/esm/testing/mock-fn.js +8 -2
- package/dist/esm/testing/mock-interaction.js +864 -124
- 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 +8 -4
- 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 +33 -5
- package/dist/types/common/index.d.cts +17 -10
- package/dist/types/common/index.d.ts +17 -10
- 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 +158 -61
- package/dist/types/testing/index.d.ts +158 -61
- 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
|
@@ -4,8 +4,21 @@
|
|
|
4
4
|
*/ /** Set by `meocord register`: register the commands over REST and exit, without logging in. */ const REGISTER_ONLY_ENV = 'MEOCORD_REGISTER_ONLY';
|
|
5
5
|
/** Set by `meocord register --guild <id>`: register every command to that guild only. */ const REGISTER_GUILD_ENV = 'MEOCORD_REGISTER_GUILD';
|
|
6
6
|
/** Set by `meocord start --force-register` and by `meocord register`: send even an unchanged payload. */ const FORCE_REGISTER_ENV = 'MEOCORD_FORCE_REGISTER';
|
|
7
|
+
/**
|
|
8
|
+
* Set by the CLI for every bot it starts: `development` or `production`, the mode the command runs in. A bundle built
|
|
9
|
+
* with `bundleDependencies` has `process.env.NODE_ENV` written in as the mode it was built in, MeoCord's own reads
|
|
10
|
+
* included, so the command's mode reaches it through this variable instead.
|
|
11
|
+
*/ const REGISTER_MODE_ENV = 'MEOCORD_REGISTER_MODE';
|
|
12
|
+
/**
|
|
13
|
+
* Whether commands register as development does, to `commands.developmentGuild`: as the CLI command that started the
|
|
14
|
+
* bot says, else as `NODE_ENV` says.
|
|
15
|
+
*/ function registersAsDevelopment(env = process.env) {
|
|
16
|
+
const mode = env[REGISTER_MODE_ENV];
|
|
17
|
+
if (mode === 'development' || mode === 'production') return mode === 'development';
|
|
18
|
+
return process.env.NODE_ENV === 'development';
|
|
19
|
+
}
|
|
7
20
|
/** Whether this process was started to register commands and exit. */ function isRegisterOnly(env = process.env) {
|
|
8
21
|
return env[REGISTER_ONLY_ENV] === '1';
|
|
9
22
|
}
|
|
10
23
|
|
|
11
|
-
export { FORCE_REGISTER_ENV, REGISTER_GUILD_ENV, REGISTER_ONLY_ENV, isRegisterOnly };
|
|
24
|
+
export { FORCE_REGISTER_ENV, REGISTER_GUILD_ENV, REGISTER_MODE_ENV, REGISTER_ONLY_ENV, isRegisterOnly, registersAsDevelopment };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/** The longest delay a timer keeps: 2^31 - 1 ms, about 24.8 days. Node fires a longer one at once. */ const MAX_TIMER_MS = 2147483647;
|
|
2
|
+
const MS_PER_SECOND = 1000;
|
|
3
|
+
/** The most whole seconds a timer keeps, as a message about an option given in seconds names the limit. */ const MAX_TIMER_SECONDS = Math.floor(MAX_TIMER_MS / MS_PER_SECOND);
|
|
4
|
+
/** Whether a timer keeps a delay given in seconds, a fraction of a second included. */ const timerKeepsSeconds = (seconds)=>seconds * MS_PER_SECOND <= MAX_TIMER_MS;
|
|
2
5
|
/** A value as a refusal quotes it: a number as itself, `Infinity` and `NaN` included, a string in quotes. */ function quoted(value) {
|
|
3
6
|
if (typeof value === 'string') return JSON.stringify(value);
|
|
4
7
|
if (typeof value === 'number' || typeof value === 'boolean' || value === null) return String(value);
|
|
@@ -12,4 +15,4 @@
|
|
|
12
15
|
return `must be a number of milliseconds ${allowZero ? '0 or more' : 'above 0'}, at most ${max} (got ${quoted(value)})`;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
export { MAX_TIMER_MS, timeoutProblem };
|
|
18
|
+
export { MAX_TIMER_MS, MAX_TIMER_SECONDS, timeoutProblem, timerKeepsSeconds };
|
|
@@ -11,13 +11,15 @@ const STAR = '__meocord_paths_star__';
|
|
|
11
11
|
*/ function projectPaths(cwd = process.cwd()) {
|
|
12
12
|
const configPath = path.join(cwd, 'tsconfig.json');
|
|
13
13
|
if (!existsSync(configPath)) return undefined;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const paths = tsconfig.config.compilerOptions?.paths;
|
|
14
|
+
return absolutePaths(configPath, parseTsconfig(configPath));
|
|
15
|
+
}
|
|
16
|
+
/** A parsed tsconfig's `paths`, each target absolute, as {@link projectPaths} gives them. */ function absolutePaths(configPath, config) {
|
|
17
|
+
const paths = config.compilerOptions?.paths;
|
|
19
18
|
// The matcher resolves each target from the file that declares it, or from baseUrl, as tsc does
|
|
20
|
-
const match = createPathsMatcher(
|
|
19
|
+
const match = createPathsMatcher({
|
|
20
|
+
path: configPath,
|
|
21
|
+
config
|
|
22
|
+
});
|
|
21
23
|
if (!paths || !match) return undefined;
|
|
22
24
|
// Resolved, so each is the platform's own absolute path: get-tsconfig writes Windows paths with forward slashes
|
|
23
25
|
return Object.fromEntries(Object.keys(paths).map((alias)=>[
|
|
@@ -25,5 +27,34 @@ const STAR = '__meocord_paths_star__';
|
|
|
25
27
|
match(alias.replace('*', STAR)).map((target)=>path.resolve(target).replace(STAR, '*'))
|
|
26
28
|
]));
|
|
27
29
|
}
|
|
30
|
+
/** The top-level lists of files and globs. */ const FILE_LISTS = [
|
|
31
|
+
'include',
|
|
32
|
+
'exclude',
|
|
33
|
+
'files'
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* The project's tsconfig as the bundler resolves modules with it, written as one file with no `extends`: `baseUrl`
|
|
37
|
+
* and `paths` as `tsc` reads them through `extends` (`paths` as {@link projectPaths} gives them), and `include`,
|
|
38
|
+
* `exclude` and `files`, each absolute, from the file that declares it and with `${configDir}` as the project. Rspack's
|
|
39
|
+
* resolver reads no other compiler option, so no other is written: one inferred by a TypeScript other than the
|
|
40
|
+
* project's can't reach the copy. Undefined when there is no tsconfig.json.
|
|
41
|
+
*/ function resolutionTsconfig(cwd = process.cwd()) {
|
|
42
|
+
const configPath = path.join(cwd, 'tsconfig.json');
|
|
43
|
+
if (!existsSync(configPath)) return undefined;
|
|
44
|
+
const resolved = parseTsconfig(configPath);
|
|
45
|
+
const absolute = (entry)=>path.resolve(cwd, String(entry));
|
|
46
|
+
const tsconfig = {
|
|
47
|
+
compilerOptions: {}
|
|
48
|
+
};
|
|
49
|
+
const baseUrl = resolved.compilerOptions?.baseUrl;
|
|
50
|
+
if (typeof baseUrl === 'string') tsconfig.compilerOptions.baseUrl = absolute(baseUrl);
|
|
51
|
+
const paths = absolutePaths(configPath, resolved);
|
|
52
|
+
if (paths) tsconfig.compilerOptions.paths = paths;
|
|
53
|
+
for (const key of FILE_LISTS){
|
|
54
|
+
const value = resolved[key];
|
|
55
|
+
if (Array.isArray(value)) tsconfig[key] = value.map(absolute);
|
|
56
|
+
}
|
|
57
|
+
return tsconfig;
|
|
58
|
+
}
|
|
28
59
|
|
|
29
|
-
export { projectPaths };
|
|
60
|
+
export { projectPaths, resolutionTsconfig };
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync, mkdtempSync, rmSync, readlinkSync, readdirSync } from 'fs';
|
|
3
3
|
import { tmpdir, hostname } from 'os';
|
|
4
|
-
import { createRequire } from 'module';
|
|
5
4
|
import { parseJsonc } from './json.util.js';
|
|
6
|
-
import {
|
|
5
|
+
import { resolutionTsconfig } from './tsconfig-paths.util.js';
|
|
7
6
|
|
|
8
|
-
/**
|
|
9
|
-
* An `extends` made to work from another directory: a relative path made absolute, and a package
|
|
10
|
-
* resolved from the project's `node_modules`, or kept as it is when it cannot be found there.
|
|
11
|
-
*/ function resolveExtends(value, cwd) {
|
|
12
|
-
const projectRequire = createRequire(path.join(cwd, 'tsconfig.json'));
|
|
13
|
-
const resolve = (entry)=>{
|
|
14
|
-
if (entry.startsWith('.') || path.isAbsolute(entry)) return path.resolve(cwd, entry);
|
|
15
|
-
try {
|
|
16
|
-
return projectRequire.resolve(entry);
|
|
17
|
-
} catch {
|
|
18
|
-
return entry;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
return Array.isArray(value) ? value.map(resolve) : resolve(value);
|
|
22
|
-
}
|
|
23
7
|
// The directory this process writes its copies in, and how many it has written there
|
|
24
8
|
let copiesDir;
|
|
25
9
|
let copies = 0;
|
|
@@ -89,12 +73,11 @@ function isRunning(pid) {
|
|
|
89
73
|
return dir;
|
|
90
74
|
}
|
|
91
75
|
/**
|
|
92
|
-
* Writes a copy of the project's tsconfig.json for the bundler and returns its path
|
|
93
|
-
*
|
|
94
|
-
* process's directory, removed at exit; the project's file is never written.
|
|
76
|
+
* Writes a copy of the project's tsconfig.json for the bundler and returns its path. The copy is for module resolution
|
|
77
|
+
* only: what {@link resolutionTsconfig} gives, with no `extends`, and the project's own references. One file per call
|
|
78
|
+
* in this process's directory, removed at exit; the project's file is never written.
|
|
95
79
|
* @throws When `tsconfig.json` is missing or cannot be parsed.
|
|
96
80
|
*/ function prepareModifiedTsConfig() {
|
|
97
|
-
var _parsedConfig;
|
|
98
81
|
const tsConfigPath = path.resolve(process.cwd(), 'tsconfig.json');
|
|
99
82
|
// Ensure tsconfig.json exists
|
|
100
83
|
if (!existsSync(tsConfigPath)) {
|
|
@@ -108,46 +91,21 @@ function isRunning(pid) {
|
|
|
108
91
|
} catch (error) {
|
|
109
92
|
throw new Error(`Could not parse tsconfig.json in ${process.cwd()}: ${error instanceof Error ? error.message : String(error)}. ` + `Fix the JSON, then build again.`);
|
|
110
93
|
}
|
|
111
|
-
// The copy lives in the temp directory
|
|
94
|
+
// The copy lives in the temp directory and is for module resolution alone: what the bundler resolves with, every path
|
|
95
|
+
// absolute and no `extends` left, since the bundler's own lookup of one can't read a Windows absolute path
|
|
112
96
|
const cwd = process.cwd();
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
'
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// Process compilerOptions
|
|
125
|
-
if (parsedConfig?.compilerOptions) {
|
|
126
|
-
const pathOptions = [
|
|
127
|
-
'outDir',
|
|
128
|
-
'rootDir',
|
|
129
|
-
'baseUrl',
|
|
130
|
-
'tsBuildInfoFile'
|
|
131
|
-
];
|
|
132
|
-
// Convert relative paths to absolute paths in `compilerOptions`
|
|
133
|
-
pathOptions.forEach((option)=>{
|
|
134
|
-
if (parsedConfig.compilerOptions[option]) {
|
|
135
|
-
parsedConfig.compilerOptions[option] = path.resolve(process.cwd(), parsedConfig.compilerOptions[option]);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
if (Array.isArray(parsedConfig.compilerOptions.typeRoots)) {
|
|
139
|
-
parsedConfig.compilerOptions.typeRoots = parsedConfig.compilerOptions.typeRoots.map((p)=>path.resolve(cwd, p));
|
|
140
|
-
}
|
|
141
|
-
// Remove `noEmit` option if it exists
|
|
142
|
-
if ('noEmit' in parsedConfig.compilerOptions) {
|
|
143
|
-
delete parsedConfig.compilerOptions.noEmit;
|
|
144
|
-
}
|
|
97
|
+
const copy = {
|
|
98
|
+
...resolutionTsconfig(cwd)
|
|
99
|
+
};
|
|
100
|
+
// Project references, which tsc reads from this file alone and resolves from the project, `${configDir}` as written
|
|
101
|
+
if (Array.isArray(parsedConfig?.references)) {
|
|
102
|
+
copy.references = parsedConfig.references.map((reference)=>typeof reference?.path === 'string' ? {
|
|
103
|
+
...reference,
|
|
104
|
+
path: path.resolve(cwd, reference.path)
|
|
105
|
+
} : reference);
|
|
145
106
|
}
|
|
146
|
-
// The paths as tsc reads them, inherited ones included, written absolute so the copy in the temp directory keeps them
|
|
147
|
-
const paths = projectPaths(cwd);
|
|
148
|
-
if (paths) ((_parsedConfig = parsedConfig).compilerOptions ?? (_parsedConfig.compilerOptions = {})).paths = paths;
|
|
149
107
|
const tempTsConfigPath = path.join(copiesDirectory(), `modified-tsconfig-${++copies}.json`);
|
|
150
|
-
writeFileSync(tempTsConfigPath, JSON.stringify(
|
|
108
|
+
writeFileSync(tempTsConfigPath, JSON.stringify(copy, null, 2));
|
|
151
109
|
return tempTsConfigPath;
|
|
152
110
|
}
|
|
153
111
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { escapeMarkdown } from 'discord.js';
|
|
2
2
|
|
|
3
|
-
/** Characters a log line shows escaped: C0 and C1 controls, DEL, line and paragraph separators, and bidi controls. */ const UNSAFE_IN_LOG = /[\u0000-\u001f\u007f-\u009f\u2028\u2029\
|
|
4
|
-
/** The same, with the quote and the backslash, for text shown between quotes. */ const UNSAFE_IN_QUOTES = /[\u0000-\u001f\u007f-\u009f\u2028\u2029\
|
|
3
|
+
/** Characters a log line shows escaped: C0 and C1 controls, DEL, line and paragraph separators, and bidi controls. */ const UNSAFE_IN_LOG = /[\u0000-\u001f\u007f-\u009f\u2028\u2029\p{Bidi_Control}]/gu;
|
|
4
|
+
/** The same, with the quote and the backslash, for text shown between quotes. */ const UNSAFE_IN_QUOTES = /[\u0000-\u001f\u007f-\u009f\u2028\u2029\p{Bidi_Control}"\\]/gu;
|
|
5
5
|
const SHORT_ESCAPES = {
|
|
6
6
|
'\n': '\\n',
|
|
7
7
|
'\r': '\\r',
|
|
@@ -25,8 +25,12 @@ const escapeChar = (char)=>SHORT_ESCAPES[char] ?? `\\u${char.charCodeAt(0).toStr
|
|
|
25
25
|
if (characters.length <= LOGGED_CHARACTERS) return quoted(text);
|
|
26
26
|
return `${quoted(`${characters.slice(0, LOGGED_CHARACTERS).join('')}…`)} (${characters.length} characters)`;
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Words a user wrote, as a reply quotes them: on one line, with their markdown, masked links included, shown as typed.
|
|
30
|
+
* Each run of whitespace reads as one space, and the spaces around the words are kept, since a word in quotes can
|
|
31
|
+
* carry them and be refused for them.
|
|
32
|
+
*/ function userWords(text) {
|
|
33
|
+
return escapeMarkdown(text.replace(/\s+/g, ' '), {
|
|
30
34
|
maskedLink: true
|
|
31
35
|
});
|
|
32
36
|
}
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { quoteForLog } from './user-text.util.js';
|
|
2
2
|
|
|
3
|
-
/** Whether a value
|
|
3
|
+
/** Whether `new` takes a value, as `instanceof` needs of its right side, such as a `@Catch` type. */ function isConstructible(value) {
|
|
4
|
+
if (typeof value !== 'function') return false;
|
|
5
|
+
try {
|
|
6
|
+
// Fails unless value can be new.target, which only a constructor can; none of value's constructor code runs
|
|
7
|
+
Reflect.construct(String, [], value);
|
|
8
|
+
return true;
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Whether a value is a class, which a stage entry or an app option must be: constructible, with an object prototype for
|
|
15
|
+
* the metadata MeoCord reads. An arrow function, a method, an async or a generator function is none.
|
|
16
|
+
*/ function isConstructor(value) {
|
|
17
|
+
if (!isConstructible(value)) return false;
|
|
18
|
+
const prototype = value.prototype;
|
|
19
|
+
return typeof prototype === 'object' && prototype !== null;
|
|
20
|
+
}
|
|
4
21
|
/** A value as a refusal or a warning names it: a string quoted, `null` and `undefined` as written, else its kind. */ function describeValue(value) {
|
|
5
22
|
if (value === null || value === undefined) return String(value);
|
|
6
23
|
if (typeof value === 'string') return quoteForLog(value);
|
|
@@ -9,15 +26,26 @@ import { quoteForLog } from './user-text.util.js';
|
|
|
9
26
|
}
|
|
10
27
|
/** A class's name after its article, such as `an AutocompleteInteraction`; a `U` name reads as "you", so takes `a`. */ const withArticle = (name)=>`${/^[AEIO]/i.test(name) ? 'an' : 'a'} ${name}`;
|
|
11
28
|
/**
|
|
12
|
-
* Sets `key` on `target` as an own, enumerable data property: unlike `target[key] = value`, a key
|
|
13
|
-
* is a key like any other rather than the object's prototype
|
|
29
|
+
* Sets `key` on a plain object `target` as an own, enumerable data property: unlike `target[key] = value`, a key
|
|
30
|
+
* named `__proto__` is a key like any other rather than the object's prototype, and a key such as `toString` is set
|
|
31
|
+
* even where `Object.prototype` is frozen.
|
|
14
32
|
*/ function setOwn(target, key, value) {
|
|
15
|
-
Object.
|
|
33
|
+
// An assignment would call __proto__'s setter, and throw for a member of a frozen Object.prototype. Any other key
|
|
34
|
+
// assigned is an own data property already; defining each would cost V8 its fast object shape
|
|
35
|
+
if (key in Object.prototype) Object.defineProperty(target, key, {
|
|
16
36
|
value,
|
|
17
37
|
enumerable: true,
|
|
18
38
|
writable: true,
|
|
19
39
|
configurable: true
|
|
20
40
|
});
|
|
41
|
+
else target[key] = value;
|
|
42
|
+
}
|
|
43
|
+
/** `target`'s own value for `key`, never one it inherits, such as `Object.prototype.toString` for `toString`. */ const ownValue = (target, key)=>Object.hasOwn(target, key) ? target[key] : undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Gives each of `keys`, names `Object.prototype` has such as `toString` or `constructor`, that `target` doesn't hold
|
|
46
|
+
* an own `undefined`, so reading one left out gives `undefined` rather than the inherited member.
|
|
47
|
+
*/ function shadowInherited(target, keys) {
|
|
48
|
+
for (const key of keys)if (!Object.hasOwn(target, key)) setOwn(target, key, undefined);
|
|
21
49
|
}
|
|
22
50
|
|
|
23
|
-
export { describeValue, isConstructor, setOwn, withArticle };
|
|
51
|
+
export { describeValue, isConstructible, isConstructor, ownValue, setOwn, shadowInherited, withArticle };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ColorResolvable, Interaction, Message, Locale } from 'discord.js';
|
|
2
|
-
import { C as CooldownStore, a as CooldownLimit, b as CooldownVerdict, c as CooldownEntry, d as CooldownBatchVerdict } from '../index-
|
|
2
|
+
import { C as CooldownStore, a as CooldownLimit, b as CooldownVerdict, c as CooldownEntry, d as CooldownBatchVerdict } from '../index-CqXImwF_.cjs';
|
|
3
3
|
import { Token, ProviderToken, FactoryProvider, DeepReadonly, MeoCordTheme } from '../interface/index.cjs';
|
|
4
|
-
export { e as CommandNotFoundError, f as CooldownError, g as CooldownScope, h as CooldownStoreError, E as ExecutionContext, i as ExecutionContextType, G as GuardDeniedError, I as InstallContext, j as MemoryCooldownStore, k as MessageUsageError, l as MessageUsageIssue, m as MetadataDecorator, R as ResponseCall, n as ResponseEditFlags, o as ResponseEditPayload, p as ResponseErrorOptions, q as ResponseFlags, r as ResponseLockOptions, s as ResponsePayload, t as ResponsePhase, u as ResponseSendOptions, v as ResponseState, U as UserError, w as UserErrorOptions, V as ValidationError, x as ValidationIssue, y as cooldownMessage, z as cooldownStoreMessage, A as createMetadata, B as getInstallContext, H as respond } from '../index-
|
|
5
|
-
export { R as Route, a as RouteParams, b as RouteValue, c as RouteValues, r as route } from '../route-
|
|
6
|
-
import { T as Translator } from '../translator-
|
|
7
|
-
export { C as CatalogDefinition, a as CatalogShape, L as LocaleCatalog, b as LocalizationKey, M as MessageKey, c as MessageParams, P as PluralCategory, d as PluralMessage, S as StringMessageKey, e as Translate, f as TranslatorOptions, g as createTranslator, h as defineCatalog } from '../translator-
|
|
8
|
-
export { T as ThemeCache } from '../theme-resolvers-
|
|
4
|
+
export { e as CommandNotFoundError, f as CooldownError, g as CooldownScope, h as CooldownStoreError, E as ExecutionContext, i as ExecutionContextType, G as GuardDeniedError, I as InstallContext, j as MemoryCooldownStore, k as MessageUsageError, l as MessageUsageIssue, m as MetadataDecorator, R as ResponseCall, n as ResponseEditFlags, o as ResponseEditPayload, p as ResponseErrorOptions, q as ResponseFlags, r as ResponseLockOptions, s as ResponsePayload, t as ResponsePhase, u as ResponseSendOptions, v as ResponseState, U as UserError, w as UserErrorOptions, V as ValidationError, x as ValidationIssue, y as cooldownMessage, z as cooldownStoreMessage, A as createMetadata, B as getInstallContext, H as respond } from '../index-CqXImwF_.cjs';
|
|
5
|
+
export { R as Route, a as RouteParams, b as RouteValue, c as RouteValues, r as route } from '../route-IQrK-MN2.cjs';
|
|
6
|
+
import { T as Translator } from '../translator-iJhDlgwL.cjs';
|
|
7
|
+
export { C as CatalogDefinition, a as CatalogShape, L as LocaleCatalog, b as LocalizationKey, M as MessageKey, c as MessageParams, P as PluralCategory, d as PluralMessage, S as StringMessageKey, e as Translate, f as TranslatorOptions, g as createTranslator, h as defineCatalog } from '../translator-iJhDlgwL.cjs';
|
|
8
|
+
export { T as ThemeCache } from '../theme-resolvers-AtgeaYqF.cjs';
|
|
9
9
|
import '@rsbuild/core';
|
|
10
10
|
import '../controller.enum-DTDn69N9.cjs';
|
|
11
11
|
|
|
@@ -532,7 +532,10 @@ declare function translateError(error: unknown, t: Translator<any>, target: Inte
|
|
|
532
532
|
*
|
|
533
533
|
* Use it where a bot logs a startup failure, so an error MeoCord explained is not logged twice: an app
|
|
534
534
|
* `MeoCordFactory.create()` refuses, such as two handlers for one command, or Discord refusing the bot token or a
|
|
535
|
-
* privileged intent at login.
|
|
535
|
+
* privileged intent at login. A built bot has `process.exitCode` set for such an error already, and a start that a stop
|
|
536
|
+
* ended, which is explained too, leaves it as it was, so the process exits 0. Outside a build, as a script run by hand,
|
|
537
|
+
* `MeoCordFactory.create()` sets no code for an app it refuses, so a catch that returns early for an explained error,
|
|
538
|
+
* as below, sets `process.exitCode` itself there. The error is otherwise unchanged.
|
|
536
539
|
*
|
|
537
540
|
* @param error - An error `MeoCordFactory.create()` threw or `app.start()` rejected with.
|
|
538
541
|
* @returns `true` when MeoCord explained the error.
|
|
@@ -548,9 +551,10 @@ declare function translateError(error: unknown, t: Translator<any>, target: Inte
|
|
|
548
551
|
* await app.start()
|
|
549
552
|
* }
|
|
550
553
|
*
|
|
551
|
-
* // An error MeoCord explained, such as an app it refuses or a token Discord refused, is already logged
|
|
554
|
+
* // An error MeoCord explained, such as an app it refuses or a token Discord refused, is already logged, with the exit code set
|
|
552
555
|
* bootstrap().catch(error => {
|
|
553
|
-
* if (
|
|
556
|
+
* if (isExplainedError(error)) return
|
|
557
|
+
* logger.error('Error during startup:', error)
|
|
554
558
|
* process.exitCode = 1
|
|
555
559
|
* })
|
|
556
560
|
* ```
|
|
@@ -596,6 +600,9 @@ declare function useTheme(): ResolvedTheme;
|
|
|
596
600
|
* Such a listener runs in its emitter's context, so without it a `useTheme()` inside reads the theme outside any call.
|
|
597
601
|
* Timers and promises the handler starts keep its theme without it.
|
|
598
602
|
*
|
|
603
|
+
* The theme is the binding call's whole theme, its server's and user's themes included, so every later call, whoever
|
|
604
|
+
* it is for, is answered in the starting member's theme.
|
|
605
|
+
*
|
|
599
606
|
* @param fn - The function to run in the call's theme; `this` and its arguments are passed through.
|
|
600
607
|
* @returns A function that runs `fn` in the theme `useTheme()` returns where `bindTheme` is called.
|
|
601
608
|
*
|
|
@@ -605,7 +612,7 @@ declare function useTheme(): ResolvedTheme;
|
|
|
605
612
|
* async poll(message: Message) {
|
|
606
613
|
* const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button, time: 60_000 })
|
|
607
614
|
* collector.on('collect', bindTheme(async (click: ButtonInteraction) => {
|
|
608
|
-
* const { emojis } = useTheme() // the
|
|
615
|
+
* const { emojis } = useTheme() // the starting member's theme, @UseTheme included
|
|
609
616
|
* await click.reply(`${emojis.success} Picked`)
|
|
610
617
|
* }))
|
|
611
618
|
* }
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ColorResolvable, Interaction, Message, Locale } from 'discord.js';
|
|
2
|
-
import { C as CooldownStore, a as CooldownLimit, b as CooldownVerdict, c as CooldownEntry, d as CooldownBatchVerdict } from '../index-
|
|
2
|
+
import { C as CooldownStore, a as CooldownLimit, b as CooldownVerdict, c as CooldownEntry, d as CooldownBatchVerdict } from '../index-Brkd6QGL.js';
|
|
3
3
|
import { Token, ProviderToken, FactoryProvider, DeepReadonly, MeoCordTheme } from '../interface/index.js';
|
|
4
|
-
export { e as CommandNotFoundError, f as CooldownError, g as CooldownScope, h as CooldownStoreError, E as ExecutionContext, i as ExecutionContextType, G as GuardDeniedError, I as InstallContext, j as MemoryCooldownStore, k as MessageUsageError, l as MessageUsageIssue, m as MetadataDecorator, R as ResponseCall, n as ResponseEditFlags, o as ResponseEditPayload, p as ResponseErrorOptions, q as ResponseFlags, r as ResponseLockOptions, s as ResponsePayload, t as ResponsePhase, u as ResponseSendOptions, v as ResponseState, U as UserError, w as UserErrorOptions, V as ValidationError, x as ValidationIssue, y as cooldownMessage, z as cooldownStoreMessage, A as createMetadata, B as getInstallContext, H as respond } from '../index-
|
|
5
|
-
export { R as Route, a as RouteParams, b as RouteValue, c as RouteValues, r as route } from '../route-
|
|
6
|
-
import { T as Translator } from '../translator-
|
|
7
|
-
export { C as CatalogDefinition, a as CatalogShape, L as LocaleCatalog, b as LocalizationKey, M as MessageKey, c as MessageParams, P as PluralCategory, d as PluralMessage, S as StringMessageKey, e as Translate, f as TranslatorOptions, g as createTranslator, h as defineCatalog } from '../translator-
|
|
8
|
-
export { T as ThemeCache } from '../theme-resolvers-
|
|
4
|
+
export { e as CommandNotFoundError, f as CooldownError, g as CooldownScope, h as CooldownStoreError, E as ExecutionContext, i as ExecutionContextType, G as GuardDeniedError, I as InstallContext, j as MemoryCooldownStore, k as MessageUsageError, l as MessageUsageIssue, m as MetadataDecorator, R as ResponseCall, n as ResponseEditFlags, o as ResponseEditPayload, p as ResponseErrorOptions, q as ResponseFlags, r as ResponseLockOptions, s as ResponsePayload, t as ResponsePhase, u as ResponseSendOptions, v as ResponseState, U as UserError, w as UserErrorOptions, V as ValidationError, x as ValidationIssue, y as cooldownMessage, z as cooldownStoreMessage, A as createMetadata, B as getInstallContext, H as respond } from '../index-Brkd6QGL.js';
|
|
5
|
+
export { R as Route, a as RouteParams, b as RouteValue, c as RouteValues, r as route } from '../route-bI-okq7g.js';
|
|
6
|
+
import { T as Translator } from '../translator-D8aydlCE.js';
|
|
7
|
+
export { C as CatalogDefinition, a as CatalogShape, L as LocaleCatalog, b as LocalizationKey, M as MessageKey, c as MessageParams, P as PluralCategory, d as PluralMessage, S as StringMessageKey, e as Translate, f as TranslatorOptions, g as createTranslator, h as defineCatalog } from '../translator-D8aydlCE.js';
|
|
8
|
+
export { T as ThemeCache } from '../theme-resolvers-BgqysV8d.js';
|
|
9
9
|
import '@rsbuild/core';
|
|
10
10
|
import '../controller.enum-DTDn69N9.js';
|
|
11
11
|
|
|
@@ -532,7 +532,10 @@ declare function translateError(error: unknown, t: Translator<any>, target: Inte
|
|
|
532
532
|
*
|
|
533
533
|
* Use it where a bot logs a startup failure, so an error MeoCord explained is not logged twice: an app
|
|
534
534
|
* `MeoCordFactory.create()` refuses, such as two handlers for one command, or Discord refusing the bot token or a
|
|
535
|
-
* privileged intent at login.
|
|
535
|
+
* privileged intent at login. A built bot has `process.exitCode` set for such an error already, and a start that a stop
|
|
536
|
+
* ended, which is explained too, leaves it as it was, so the process exits 0. Outside a build, as a script run by hand,
|
|
537
|
+
* `MeoCordFactory.create()` sets no code for an app it refuses, so a catch that returns early for an explained error,
|
|
538
|
+
* as below, sets `process.exitCode` itself there. The error is otherwise unchanged.
|
|
536
539
|
*
|
|
537
540
|
* @param error - An error `MeoCordFactory.create()` threw or `app.start()` rejected with.
|
|
538
541
|
* @returns `true` when MeoCord explained the error.
|
|
@@ -548,9 +551,10 @@ declare function translateError(error: unknown, t: Translator<any>, target: Inte
|
|
|
548
551
|
* await app.start()
|
|
549
552
|
* }
|
|
550
553
|
*
|
|
551
|
-
* // An error MeoCord explained, such as an app it refuses or a token Discord refused, is already logged
|
|
554
|
+
* // An error MeoCord explained, such as an app it refuses or a token Discord refused, is already logged, with the exit code set
|
|
552
555
|
* bootstrap().catch(error => {
|
|
553
|
-
* if (
|
|
556
|
+
* if (isExplainedError(error)) return
|
|
557
|
+
* logger.error('Error during startup:', error)
|
|
554
558
|
* process.exitCode = 1
|
|
555
559
|
* })
|
|
556
560
|
* ```
|
|
@@ -596,6 +600,9 @@ declare function useTheme(): ResolvedTheme;
|
|
|
596
600
|
* Such a listener runs in its emitter's context, so without it a `useTheme()` inside reads the theme outside any call.
|
|
597
601
|
* Timers and promises the handler starts keep its theme without it.
|
|
598
602
|
*
|
|
603
|
+
* The theme is the binding call's whole theme, its server's and user's themes included, so every later call, whoever
|
|
604
|
+
* it is for, is answered in the starting member's theme.
|
|
605
|
+
*
|
|
599
606
|
* @param fn - The function to run in the call's theme; `this` and its arguments are passed through.
|
|
600
607
|
* @returns A function that runs `fn` in the theme `useTheme()` returns where `bindTheme` is called.
|
|
601
608
|
*
|
|
@@ -605,7 +612,7 @@ declare function useTheme(): ResolvedTheme;
|
|
|
605
612
|
* async poll(message: Message) {
|
|
606
613
|
* const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button, time: 60_000 })
|
|
607
614
|
* collector.on('collect', bindTheme(async (click: ButtonInteraction) => {
|
|
608
|
-
* const { emojis } = useTheme() // the
|
|
615
|
+
* const { emojis } = useTheme() // the starting member's theme, @UseTheme included
|
|
609
616
|
* await click.reply(`${emojis.success} Picked`)
|
|
610
617
|
* }))
|
|
611
618
|
* }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServiceIdentifier } from 'inversify';
|
|
2
|
-
import { J as MeoCordApplication } from '../index-
|
|
2
|
+
import { J as MeoCordApplication } from '../index-CqXImwF_.cjs';
|
|
3
3
|
import { MetadataDecorator } from '../common/index.cjs';
|
|
4
4
|
import { MessageScope, MessageCommandOptions, MessageHelp } from '../interface/index.cjs';
|
|
5
5
|
import { RESTPostAPIApplicationCommandsJSONBody, ClientEvents, Message, Client } from 'discord.js';
|
|
@@ -172,7 +172,10 @@ interface MessageHandlerEntry extends HandlerEntryBase {
|
|
|
172
172
|
aliases: readonly string[];
|
|
173
173
|
/** What the command does, from its `description` option. */
|
|
174
174
|
description: string | undefined;
|
|
175
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* Where the command works: its `scope` option, narrowed to servers by a `member`, `role` or `channel` param, or
|
|
177
|
+
* required flag.
|
|
178
|
+
*/
|
|
176
179
|
scope: MessageScope;
|
|
177
180
|
/** Whether its `hidden` option leaves it out of help's lists, including a parent's list of subcommands. */
|
|
178
181
|
hidden: boolean;
|
|
@@ -269,16 +272,19 @@ declare class HandlerRegistry {
|
|
|
269
272
|
private readonly classes;
|
|
270
273
|
private readonly messages;
|
|
271
274
|
private readonly translator;
|
|
275
|
+
private readonly controllers;
|
|
272
276
|
private entries?;
|
|
273
|
-
/** Built from
|
|
277
|
+
/** Built from the controllers for a registry no dispatcher shares its routes with yet. */
|
|
274
278
|
private messageRoutes?;
|
|
275
279
|
/**
|
|
276
|
-
* @param classes - The app's classes to read handlers from. The factory fills the
|
|
277
|
-
* once the app is bound; entries are read on the first {@link list}.
|
|
280
|
+
* @param classes - The app's classes to read handlers from, controllers and services alike. The factory fills the
|
|
281
|
+
* list once the app is bound; entries are read on the first {@link list}.
|
|
278
282
|
* @param messages - The app's `messages` options, whose `caseSensitive` message entries' `matches` follows.
|
|
279
283
|
* @param translator - The app's translator, read when {@link messageHelp} words its labels; none for English.
|
|
284
|
+
* @param controllers - The app's controllers, the classes dispatch routes messages to, which {@link messageHelp}
|
|
285
|
+
* lists; `classes` when not given.
|
|
280
286
|
*/
|
|
281
|
-
constructor(classes: readonly HandlerClass[], messages?: MessageCommandOptions, translator?: () => Translator<any> | undefined);
|
|
287
|
+
constructor(classes: readonly HandlerClass[], messages?: MessageCommandOptions, translator?: () => Translator<any> | undefined, controllers?: readonly HandlerClass[]);
|
|
282
288
|
/**
|
|
283
289
|
* Lists the registered handlers.
|
|
284
290
|
*
|
|
@@ -364,6 +370,10 @@ type JsonObject<T> = {
|
|
|
364
370
|
*
|
|
365
371
|
* A `BigInt` cannot be written, so it is `never`.
|
|
366
372
|
*
|
|
373
|
+
* An object arrives with its own enumerable fields only. A class's getters are left out, yet stay in this type, as
|
|
374
|
+
* TypeScript can't tell a getter from a field: return a plain object, or give the class a `toJSON`, for a value
|
|
375
|
+
* with getters.
|
|
376
|
+
*
|
|
367
377
|
* @typeParam T - The value before it is sent.
|
|
368
378
|
* @group Types
|
|
369
379
|
* @see {@link ShardContext.call}
|
|
@@ -446,11 +456,11 @@ declare class ShardContext {
|
|
|
446
456
|
*
|
|
447
457
|
* With process sharding that is one result per shard; with one process, a single result listing every
|
|
448
458
|
* shard. The arguments and the result pass as JSON in every mode, one process and tests included, so a
|
|
449
|
-
* `Date` arrives as a string
|
|
450
|
-
* `BigInt`, fails the call. A method whose params JSON would
|
|
451
|
-
* the argument is refused, naming what to declare instead. An
|
|
452
|
-
* that throws, lacks the service, or does not answer within
|
|
453
|
-
* others.
|
|
459
|
+
* `Date` arrives as a string, a `Map` as `{}` and a class instance as its own fields, without its getters, wherever
|
|
460
|
+
* it runs, and a value JSON cannot carry, such as a `BigInt`, fails the call. A method whose params JSON would
|
|
461
|
+
* change, such as one taking a `Date`, cannot be called: the argument is refused, naming what to declare instead. An
|
|
462
|
+
* `undefined` argument arrives as `undefined`. A process that throws, lacks the service, or does not answer within
|
|
463
|
+
* 10 seconds gives an error result instead of failing the others.
|
|
454
464
|
*
|
|
455
465
|
* @param service - The controller, the service, or a class a provider stands in for; each process resolves its own
|
|
456
466
|
* instance.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServiceIdentifier } from 'inversify';
|
|
2
|
-
import { J as MeoCordApplication } from '../index-
|
|
2
|
+
import { J as MeoCordApplication } from '../index-Brkd6QGL.js';
|
|
3
3
|
import { MetadataDecorator } from '../common/index.js';
|
|
4
4
|
import { MessageScope, MessageCommandOptions, MessageHelp } from '../interface/index.js';
|
|
5
5
|
import { RESTPostAPIApplicationCommandsJSONBody, ClientEvents, Message, Client } from 'discord.js';
|
|
@@ -172,7 +172,10 @@ interface MessageHandlerEntry extends HandlerEntryBase {
|
|
|
172
172
|
aliases: readonly string[];
|
|
173
173
|
/** What the command does, from its `description` option. */
|
|
174
174
|
description: string | undefined;
|
|
175
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* Where the command works: its `scope` option, narrowed to servers by a `member`, `role` or `channel` param, or
|
|
177
|
+
* required flag.
|
|
178
|
+
*/
|
|
176
179
|
scope: MessageScope;
|
|
177
180
|
/** Whether its `hidden` option leaves it out of help's lists, including a parent's list of subcommands. */
|
|
178
181
|
hidden: boolean;
|
|
@@ -269,16 +272,19 @@ declare class HandlerRegistry {
|
|
|
269
272
|
private readonly classes;
|
|
270
273
|
private readonly messages;
|
|
271
274
|
private readonly translator;
|
|
275
|
+
private readonly controllers;
|
|
272
276
|
private entries?;
|
|
273
|
-
/** Built from
|
|
277
|
+
/** Built from the controllers for a registry no dispatcher shares its routes with yet. */
|
|
274
278
|
private messageRoutes?;
|
|
275
279
|
/**
|
|
276
|
-
* @param classes - The app's classes to read handlers from. The factory fills the
|
|
277
|
-
* once the app is bound; entries are read on the first {@link list}.
|
|
280
|
+
* @param classes - The app's classes to read handlers from, controllers and services alike. The factory fills the
|
|
281
|
+
* list once the app is bound; entries are read on the first {@link list}.
|
|
278
282
|
* @param messages - The app's `messages` options, whose `caseSensitive` message entries' `matches` follows.
|
|
279
283
|
* @param translator - The app's translator, read when {@link messageHelp} words its labels; none for English.
|
|
284
|
+
* @param controllers - The app's controllers, the classes dispatch routes messages to, which {@link messageHelp}
|
|
285
|
+
* lists; `classes` when not given.
|
|
280
286
|
*/
|
|
281
|
-
constructor(classes: readonly HandlerClass[], messages?: MessageCommandOptions, translator?: () => Translator<any> | undefined);
|
|
287
|
+
constructor(classes: readonly HandlerClass[], messages?: MessageCommandOptions, translator?: () => Translator<any> | undefined, controllers?: readonly HandlerClass[]);
|
|
282
288
|
/**
|
|
283
289
|
* Lists the registered handlers.
|
|
284
290
|
*
|
|
@@ -364,6 +370,10 @@ type JsonObject<T> = {
|
|
|
364
370
|
*
|
|
365
371
|
* A `BigInt` cannot be written, so it is `never`.
|
|
366
372
|
*
|
|
373
|
+
* An object arrives with its own enumerable fields only. A class's getters are left out, yet stay in this type, as
|
|
374
|
+
* TypeScript can't tell a getter from a field: return a plain object, or give the class a `toJSON`, for a value
|
|
375
|
+
* with getters.
|
|
376
|
+
*
|
|
367
377
|
* @typeParam T - The value before it is sent.
|
|
368
378
|
* @group Types
|
|
369
379
|
* @see {@link ShardContext.call}
|
|
@@ -446,11 +456,11 @@ declare class ShardContext {
|
|
|
446
456
|
*
|
|
447
457
|
* With process sharding that is one result per shard; with one process, a single result listing every
|
|
448
458
|
* shard. The arguments and the result pass as JSON in every mode, one process and tests included, so a
|
|
449
|
-
* `Date` arrives as a string
|
|
450
|
-
* `BigInt`, fails the call. A method whose params JSON would
|
|
451
|
-
* the argument is refused, naming what to declare instead. An
|
|
452
|
-
* that throws, lacks the service, or does not answer within
|
|
453
|
-
* others.
|
|
459
|
+
* `Date` arrives as a string, a `Map` as `{}` and a class instance as its own fields, without its getters, wherever
|
|
460
|
+
* it runs, and a value JSON cannot carry, such as a `BigInt`, fails the call. A method whose params JSON would
|
|
461
|
+
* change, such as one taking a `Date`, cannot be called: the argument is refused, naming what to declare instead. An
|
|
462
|
+
* `undefined` argument arrives as `undefined`. A process that throws, lacks the service, or does not answer within
|
|
463
|
+
* 10 seconds gives an error result instead of failing the others.
|
|
454
464
|
*
|
|
455
465
|
* @param service - The controller, the service, or a class a provider stands in for; each process resolves its own
|
|
456
466
|
* instance.
|