@wolfstar/http-framework 6.2.2 → 6.3.0-next-20261007181329
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/README.md +129 -0
- package/dist/esm/index.d.ts +597 -135
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +425 -65
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -35,19 +35,29 @@ let Events = /* @__PURE__ */ function(Events) {
|
|
|
35
35
|
Events["CommandNameMissing"] = "commandNameMissing";
|
|
36
36
|
Events["CommandNameUnknown"] = "commandNameUnknown";
|
|
37
37
|
Events["CommandMethodUnknown"] = "commandMethodUnknown";
|
|
38
|
+
Events["PreChatInputCommandRun"] = "preChatInputCommandRun";
|
|
39
|
+
Events["PreContextMenuCommandRun"] = "preContextMenuCommandRun";
|
|
40
|
+
Events["ChatInputCommandAccepted"] = "chatInputCommandAccepted";
|
|
41
|
+
Events["ContextMenuCommandAccepted"] = "contextMenuCommandAccepted";
|
|
38
42
|
Events["CommandRun"] = "commandRun";
|
|
39
43
|
Events["CommandSuccess"] = "commandSuccess";
|
|
40
44
|
Events["CommandError"] = "commandError";
|
|
45
|
+
Events["ChatInputCommandDenied"] = "chatInputCommandDenied";
|
|
46
|
+
Events["ContextMenuCommandDenied"] = "contextMenuCommandDenied";
|
|
41
47
|
Events["CommandFinish"] = "commandFinish";
|
|
48
|
+
Events["AutocompleteAccepted"] = "autocompleteAccepted";
|
|
42
49
|
Events["AutocompleteRun"] = "autocompleteRun";
|
|
43
50
|
Events["AutocompleteSuccess"] = "autocompleteSuccess";
|
|
44
51
|
Events["AutocompleteError"] = "autocompleteError";
|
|
52
|
+
Events["AutocompleteDenied"] = "autocompleteDenied";
|
|
45
53
|
Events["AutocompleteFinish"] = "autocompleteFinish";
|
|
46
54
|
Events["InteractionHandlerNameInvalid"] = "interactionHandlerNameInvalid";
|
|
47
55
|
Events["InteractionHandlerNameUnknown"] = "interactionHandlerNameUnknown";
|
|
56
|
+
Events["InteractionHandlerAccepted"] = "interactionHandlerAccepted";
|
|
48
57
|
Events["InteractionHandlerRun"] = "interactionHandlerRun";
|
|
49
58
|
Events["InteractionHandlerSuccess"] = "interactionHandlerSuccess";
|
|
50
59
|
Events["InteractionHandlerError"] = "interactionHandlerError";
|
|
60
|
+
Events["InteractionHandlerDenied"] = "interactionHandlerDenied";
|
|
51
61
|
Events["InteractionHandlerFinish"] = "interactionHandlerFinish";
|
|
52
62
|
Events["HmrStart"] = "hmrStart";
|
|
53
63
|
Events["HmrStop"] = "hmrStop";
|
|
@@ -884,6 +894,62 @@ function _useLegacy(plugin) {
|
|
|
884
894
|
}
|
|
885
895
|
}
|
|
886
896
|
|
|
897
|
+
//#endregion
|
|
898
|
+
//#region src/lib/errors/UserError.ts
|
|
899
|
+
/**
|
|
900
|
+
* The UserError class to be thrown and emitted by the pieces of the framework.
|
|
901
|
+
*
|
|
902
|
+
* @remarks
|
|
903
|
+
* This class is the root of every framework-thrown error, allowing consumers to distinguish
|
|
904
|
+
* errors that are meant to be shown to the user from unexpected, internal ones.
|
|
905
|
+
*
|
|
906
|
+
* When a command, an autocomplete handler, or an interaction handler throws a `UserError` (or any subclass), the
|
|
907
|
+
* client emits the matching `*Denied` event ({@link Events.ChatInputCommandDenied}, {@link Events.ContextMenuCommandDenied},
|
|
908
|
+
* {@link Events.AutocompleteDenied}, or {@link Events.InteractionHandlerDenied}) instead of the `*Error` one, so listeners
|
|
909
|
+
* can reply to the user without reporting an expected failure as a bug. Use {@link isUserError} to apply the same check.
|
|
910
|
+
*
|
|
911
|
+
* @property name This will be `'UserError'` and can be used to distinguish the type of error when any error gets thrown.
|
|
912
|
+
* @since 3.2.0
|
|
913
|
+
* @example
|
|
914
|
+
* ```typescript
|
|
915
|
+
* throw new UserError({
|
|
916
|
+
* identifier: Identifiers.ArgumentIntegerTooSmall,
|
|
917
|
+
* message: 'The number you provided is too small.',
|
|
918
|
+
* context: { received: 2, minimum: 3 }
|
|
919
|
+
* });
|
|
920
|
+
* ```
|
|
921
|
+
*/
|
|
922
|
+
var UserError = class extends Error {
|
|
923
|
+
/**
|
|
924
|
+
* Constructs an UserError.
|
|
925
|
+
* @param options The UserError options
|
|
926
|
+
*/
|
|
927
|
+
constructor(options) {
|
|
928
|
+
super(options.message);
|
|
929
|
+
_defineProperty(this, "identifier", void 0);
|
|
930
|
+
_defineProperty(this, "context", void 0);
|
|
931
|
+
this.identifier = options.identifier;
|
|
932
|
+
this.context = options.context ?? null;
|
|
933
|
+
}
|
|
934
|
+
get name() {
|
|
935
|
+
return "UserError";
|
|
936
|
+
}
|
|
937
|
+
};
|
|
938
|
+
/**
|
|
939
|
+
* Checks whether a value is a {@link UserError}, which is how the client tells an expected failure from an unexpected
|
|
940
|
+
* one.
|
|
941
|
+
*
|
|
942
|
+
* @remarks `instanceof` is tried first. A bundle that inlines the framework, or a second installed copy of it, has its
|
|
943
|
+
* own `UserError` class that `instanceof` does not recognise, so any `Error` with a string `identifier` and a `context`
|
|
944
|
+
* property is accepted too.
|
|
945
|
+
* @param error The value to check.
|
|
946
|
+
* @returns Whether the value is a `UserError`.
|
|
947
|
+
* @since 6.3.0
|
|
948
|
+
*/
|
|
949
|
+
function isUserError(error) {
|
|
950
|
+
return error instanceof UserError || error instanceof Error && typeof error.identifier === "string" && "context" in error;
|
|
951
|
+
}
|
|
952
|
+
|
|
887
953
|
//#endregion
|
|
888
954
|
//#region src/lib/utils/decorators.ts
|
|
889
955
|
/**
|
|
@@ -3078,6 +3144,8 @@ let Identifiers = /* @__PURE__ */ function(Identifiers) {
|
|
|
3078
3144
|
Identifiers["PreconditionClientPermissionsNoPermissions"] = "preconditionClientPermissionsNoPermissions";
|
|
3079
3145
|
Identifiers["PreconditionCooldown"] = "preconditionCooldown";
|
|
3080
3146
|
Identifiers["PreconditionGuildIds"] = "preconditionGuildIds";
|
|
3147
|
+
Identifiers["PreconditionMissingChatInputHandler"] = "preconditionMissingChatInputHandler";
|
|
3148
|
+
Identifiers["PreconditionMissingContextMenuHandler"] = "preconditionMissingContextMenuHandler";
|
|
3081
3149
|
Identifiers["PreconditionNSFW"] = "preconditionNsfw";
|
|
3082
3150
|
Identifiers["PreconditionRunIn"] = "preconditionRunIn";
|
|
3083
3151
|
Identifiers["PreconditionUnavailable"] = "preconditionUnavailable";
|
|
@@ -3091,41 +3159,134 @@ let Identifiers = /* @__PURE__ */ function(Identifiers) {
|
|
|
3091
3159
|
}({});
|
|
3092
3160
|
|
|
3093
3161
|
//#endregion
|
|
3094
|
-
//#region src/lib/
|
|
3162
|
+
//#region src/lib/utils/preconditions.ts
|
|
3095
3163
|
/**
|
|
3096
|
-
*
|
|
3164
|
+
* How the entries of an array of preconditions are run.
|
|
3097
3165
|
*
|
|
3098
|
-
* @
|
|
3099
|
-
|
|
3100
|
-
|
|
3166
|
+
* @since 6.3.0
|
|
3167
|
+
*/
|
|
3168
|
+
let PreconditionRunMode = /* @__PURE__ */ function(PreconditionRunMode) {
|
|
3169
|
+
/**
|
|
3170
|
+
* The entries are run one after the other. This is the default, and it stops as soon as the result is known.
|
|
3171
|
+
* @since 6.3.0
|
|
3172
|
+
*/
|
|
3173
|
+
PreconditionRunMode[PreconditionRunMode["Sequential"] = 0] = "Sequential";
|
|
3174
|
+
/**
|
|
3175
|
+
* Every entry is started at once and awaited with `Promise.all`, then the results are read. It is faster when the
|
|
3176
|
+
* checks are slow, but none of them is skipped once another one has settled the result.
|
|
3177
|
+
* @since 6.3.0
|
|
3178
|
+
*/
|
|
3179
|
+
PreconditionRunMode[PreconditionRunMode["Parallel"] = 1] = "Parallel";
|
|
3180
|
+
return PreconditionRunMode;
|
|
3181
|
+
}({});
|
|
3182
|
+
/**
|
|
3183
|
+
* How the results of the entries of an array of preconditions are combined.
|
|
3101
3184
|
*
|
|
3102
|
-
* @
|
|
3103
|
-
* @since 3.2.0
|
|
3104
|
-
* @example
|
|
3105
|
-
* ```typescript
|
|
3106
|
-
* throw new UserError({
|
|
3107
|
-
* identifier: Identifiers.ArgumentIntegerTooSmall,
|
|
3108
|
-
* message: 'The number you provided is too small.',
|
|
3109
|
-
* context: { received: 2, minimum: 3 }
|
|
3110
|
-
* });
|
|
3111
|
-
* ```
|
|
3185
|
+
* @since 6.3.0
|
|
3112
3186
|
*/
|
|
3113
|
-
|
|
3187
|
+
let PreconditionRunCondition = /* @__PURE__ */ function(PreconditionRunCondition) {
|
|
3114
3188
|
/**
|
|
3115
|
-
*
|
|
3116
|
-
* @
|
|
3189
|
+
* Every entry has to pass: the first `Err` is the result.
|
|
3190
|
+
* @since 6.3.0
|
|
3117
3191
|
*/
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3192
|
+
PreconditionRunCondition[PreconditionRunCondition["And"] = 0] = "And";
|
|
3193
|
+
/**
|
|
3194
|
+
* One entry has to pass: the first `Ok` is the result, and when none does, the last `Err`.
|
|
3195
|
+
* @since 6.3.0
|
|
3196
|
+
*/
|
|
3197
|
+
PreconditionRunCondition[PreconditionRunCondition["Or"] = 1] = "Or";
|
|
3198
|
+
return PreconditionRunCondition;
|
|
3199
|
+
}({});
|
|
3200
|
+
/**
|
|
3201
|
+
* Runs a {@link Precondition} piece for the given kind of interaction.
|
|
3202
|
+
*
|
|
3203
|
+
* @param precondition The precondition to run.
|
|
3204
|
+
* @param kind What is being run.
|
|
3205
|
+
* @param interaction The interaction being handled.
|
|
3206
|
+
* @param target The command or interaction handler being run.
|
|
3207
|
+
* @param context The context of the check.
|
|
3208
|
+
* @returns The result of the precondition. A chat input or context menu command is denied when the piece has no method
|
|
3209
|
+
* for it, an autocomplete or an interaction handler is let through.
|
|
3210
|
+
* @since 6.3.0
|
|
3211
|
+
*/
|
|
3212
|
+
function runPrecondition(precondition, kind, interaction, target, context = {}) {
|
|
3213
|
+
return checkPrecondition(precondition, kind, interaction, target, context) ?? precondition.ok();
|
|
3214
|
+
}
|
|
3215
|
+
/**
|
|
3216
|
+
* Like {@link runPrecondition}, but `null` when the piece does not apply: it has no method for an autocomplete or an
|
|
3217
|
+
* interaction handler.
|
|
3218
|
+
*/
|
|
3219
|
+
function checkPrecondition(precondition, kind, interaction, target, context) {
|
|
3220
|
+
switch (kind) {
|
|
3221
|
+
case "chatInput": return precondition.chatInputRun ? precondition.chatInputRun(interaction, target, context) : precondition.error({
|
|
3222
|
+
identifier: "preconditionMissingChatInputHandler",
|
|
3223
|
+
message: `The precondition "${precondition.name}" is missing a "chatInputRun" handler, but it was requested for the "${target.name}" command.`
|
|
3224
|
+
});
|
|
3225
|
+
case "contextMenu": return precondition.contextMenuRun ? precondition.contextMenuRun(interaction, target, context) : precondition.error({
|
|
3226
|
+
identifier: "preconditionMissingContextMenuHandler",
|
|
3227
|
+
message: `The precondition "${precondition.name}" is missing a "contextMenuRun" handler, but it was requested for the "${target.name}" command.`
|
|
3228
|
+
});
|
|
3229
|
+
case "autocomplete": return precondition.autocompleteRun ? precondition.autocompleteRun(interaction, target, context) : null;
|
|
3230
|
+
case "interactionHandler": return precondition.interactionHandlerRun ? precondition.interactionHandlerRun(interaction, target, context) : null;
|
|
3127
3231
|
}
|
|
3128
|
-
}
|
|
3232
|
+
}
|
|
3233
|
+
/**
|
|
3234
|
+
* Runs the preconditions of a command or an interaction handler: first the global ones of the `preconditions` store,
|
|
3235
|
+
* then the entries of its `preconditions` option, stopping at the first denial.
|
|
3236
|
+
*
|
|
3237
|
+
* @remarks
|
|
3238
|
+
* - The `preconditions` option is an array that runs with {@link PreconditionRunCondition.And}: every entry has to pass.
|
|
3239
|
+
* An array nested in it runs with `Or`, one nested in that with `And` again, and so on, so
|
|
3240
|
+
* `['Connect', ['Moderator', ['DJ', 'SongAuthor']]]` is `Connect && (Moderator || (DJ && SongAuthor))`.
|
|
3241
|
+
* - The {@link PreconditionRunMode} is `Sequential`, or the `mode` of the array written as `{ entries, mode }`, which the
|
|
3242
|
+
* arrays nested in it inherit.
|
|
3243
|
+
* - An entry that names a precondition missing from the store denies the interaction with
|
|
3244
|
+
* {@linkcode Identifiers.PreconditionUnavailable}.
|
|
3245
|
+
* - An entry that does not apply to the interaction, such as a function for an autocomplete or a piece with no method for
|
|
3246
|
+
* it, is left out of the result. An array in which no entry applies is left out as well.
|
|
3247
|
+
* @param target The command or interaction handler being run.
|
|
3248
|
+
* @param kind What is being run.
|
|
3249
|
+
* @param interaction The interaction being handled.
|
|
3250
|
+
* @returns The first `Err`, or `Result.ok()` when every precondition lets it run.
|
|
3251
|
+
* @since 6.3.0
|
|
3252
|
+
*/
|
|
3253
|
+
async function runPreconditions(target, kind, interaction) {
|
|
3254
|
+
const global = await container$1.stores.get("preconditions").run(kind, interaction, target);
|
|
3255
|
+
if (global.isErr()) return global;
|
|
3256
|
+
return await runArray(target.options.preconditions ?? [], 0, 0, kind, interaction, target) ?? Result.ok();
|
|
3257
|
+
}
|
|
3258
|
+
async function runArray(array, condition, inheritedMode, kind, interaction, target) {
|
|
3259
|
+
const entries = Array.isArray(array) ? array : array.entries;
|
|
3260
|
+
const mode = Array.isArray(array) ? inheritedMode : array.mode;
|
|
3261
|
+
const nested = condition === 0 ? 1 : 0;
|
|
3262
|
+
const run = (entry) => isSingle(entry) ? runSingle(entry, kind, interaction, target) : runArray(entry, nested, mode, kind, interaction, target);
|
|
3263
|
+
const outcomes = mode === 1 ? await Promise.all(entries.map(run)) : null;
|
|
3264
|
+
let applied = false;
|
|
3265
|
+
let error = null;
|
|
3266
|
+
for (const [index, entry] of entries.entries()) {
|
|
3267
|
+
const outcome = outcomes ? outcomes[index] : await run(entry);
|
|
3268
|
+
if (outcome === null) continue;
|
|
3269
|
+
applied = true;
|
|
3270
|
+
if (condition === 0) {
|
|
3271
|
+
if (outcome.isErr()) return outcome;
|
|
3272
|
+
} else if (outcome.isOk()) return outcome;
|
|
3273
|
+
else error = outcome;
|
|
3274
|
+
}
|
|
3275
|
+
return error ?? (applied ? Result.ok() : null);
|
|
3276
|
+
}
|
|
3277
|
+
function isSingle(entry) {
|
|
3278
|
+
return typeof entry === "string" || typeof entry === "function" || !Array.isArray(entry) && "name" in entry;
|
|
3279
|
+
}
|
|
3280
|
+
async function runSingle(entry, kind, interaction, target) {
|
|
3281
|
+
if (typeof entry === "function") return kind === "autocomplete" ? null : entry(interaction, target);
|
|
3282
|
+
const name = typeof entry === "string" ? entry : entry.name;
|
|
3283
|
+
const precondition = container$1.stores.get("preconditions").get(name);
|
|
3284
|
+
if (!precondition) return Result.err(new UserError({
|
|
3285
|
+
identifier: "preconditionUnavailable",
|
|
3286
|
+
message: `The precondition "${name}" is not available.`
|
|
3287
|
+
}));
|
|
3288
|
+
return checkPrecondition(precondition, kind, interaction, target, typeof entry === "string" ? {} : entry.context ?? {});
|
|
3289
|
+
}
|
|
3129
3290
|
|
|
3130
3291
|
//#endregion
|
|
3131
3292
|
//#region src/lib/errors/ChatInputRouterError.ts
|
|
@@ -3644,8 +3805,26 @@ var CommandStore = class extends Store$1 {
|
|
|
3644
3805
|
response.statusCode = 501;
|
|
3645
3806
|
return response.end(ErrorMessages.UnknownCommandHandler);
|
|
3646
3807
|
}
|
|
3808
|
+
const kind = interaction.data.type === ApplicationCommandType.ChatInput ? "chatInput" : "contextMenu";
|
|
3809
|
+
if (kind === "chatInput") container$1.client.emit("preChatInputCommandRun", context);
|
|
3810
|
+
else container$1.client.emit("preContextMenuCommandRun", context);
|
|
3811
|
+
const checked = await Result.fromAsync(async () => {
|
|
3812
|
+
const commandInteraction = makeInteraction(response, interaction);
|
|
3813
|
+
const preconditions = await runPreconditions(command, kind, commandInteraction);
|
|
3814
|
+
if (preconditions.isErr()) throw preconditions.unwrapErr();
|
|
3815
|
+
return commandInteraction;
|
|
3816
|
+
});
|
|
3817
|
+
if (checked.isErr()) {
|
|
3818
|
+
const error = checked.unwrapErr();
|
|
3819
|
+
_assertClassBrand(_CommandStore_brand, this, _emitCommandFailure).call(this, error, context);
|
|
3820
|
+
handleError(response, error);
|
|
3821
|
+
container$1.client.emit("commandFinish", context);
|
|
3822
|
+
return response;
|
|
3823
|
+
}
|
|
3824
|
+
if (kind === "chatInput") container$1.client.emit("chatInputCommandAccepted", context);
|
|
3825
|
+
else container$1.client.emit("contextMenuCommandAccepted", context);
|
|
3647
3826
|
container$1.client.emit("commandRun", context);
|
|
3648
|
-
(await Result.fromAsync(() => _assertClassBrand(_CommandStore_brand, this, _runCommandMethod).call(this, command, method,
|
|
3827
|
+
(await Result.fromAsync(() => _assertClassBrand(_CommandStore_brand, this, _runCommandMethod).call(this, command, method, checked.unwrap()))).inspect((value) => container$1.client.emit("commandSuccess", context, value)).inspectErr((error) => (_assertClassBrand(_CommandStore_brand, this, _emitCommandFailure).call(this, error, context), handleError(response, error)));
|
|
3649
3828
|
container$1.client.emit("commandFinish", context);
|
|
3650
3829
|
return response;
|
|
3651
3830
|
}
|
|
@@ -3675,13 +3854,49 @@ var CommandStore = class extends Store$1 {
|
|
|
3675
3854
|
response
|
|
3676
3855
|
};
|
|
3677
3856
|
const options = transformAutocompleteInteraction(interaction.data.resolved ?? {}, interaction.data.options);
|
|
3857
|
+
const checked = await Result.fromAsync(async () => {
|
|
3858
|
+
const autocompleteInteraction = makeInteraction(response, interaction);
|
|
3859
|
+
const preconditions = await runPreconditions(command, "autocomplete", autocompleteInteraction);
|
|
3860
|
+
if (preconditions.isErr()) throw preconditions.unwrapErr();
|
|
3861
|
+
return autocompleteInteraction;
|
|
3862
|
+
});
|
|
3863
|
+
if (checked.isErr()) {
|
|
3864
|
+
_assertClassBrand(_CommandStore_brand, this, _emitAutocompleteFailure).call(this, checked.unwrapErr(), context, response);
|
|
3865
|
+
container$1.client.emit("autocompleteFinish", context);
|
|
3866
|
+
return response;
|
|
3867
|
+
}
|
|
3868
|
+
container$1.client.emit("autocompleteAccepted", context);
|
|
3678
3869
|
container$1.client.emit("autocompleteRun", context);
|
|
3679
|
-
(await Result.fromAsync(() => command.autocompleteRun(
|
|
3870
|
+
(await Result.fromAsync(() => command.autocompleteRun(checked.unwrap(), options))).inspect((value) => container$1.client.emit("autocompleteSuccess", context, value)).inspectErr((error) => _assertClassBrand(_CommandStore_brand, this, _emitAutocompleteFailure).call(this, error, context, response));
|
|
3680
3871
|
container$1.client.emit("autocompleteFinish", context);
|
|
3681
3872
|
return response;
|
|
3682
3873
|
}
|
|
3683
3874
|
};
|
|
3684
3875
|
/**
|
|
3876
|
+
* Emits `autocompleteDenied` for a {@link UserError} and `autocompleteError` otherwise, then replies as for any
|
|
3877
|
+
* other thrown error.
|
|
3878
|
+
*
|
|
3879
|
+
* @param error - The value that was thrown.
|
|
3880
|
+
* @param context - The context of the run.
|
|
3881
|
+
* @param response - The server response object.
|
|
3882
|
+
*/
|
|
3883
|
+
function _emitAutocompleteFailure(error, context, response) {
|
|
3884
|
+
if (isUserError(error)) container$1.client.emit("autocompleteDenied", error, context);
|
|
3885
|
+
else container$1.client.emit("autocompleteError", error, context);
|
|
3886
|
+
handleError(response, error);
|
|
3887
|
+
}
|
|
3888
|
+
/**
|
|
3889
|
+
* Emits the event matching a failed command run: a `*Denied` one for a {@link UserError}, `commandError` otherwise.
|
|
3890
|
+
*
|
|
3891
|
+
* @param error - The value the command threw.
|
|
3892
|
+
* @param context - The context of the run.
|
|
3893
|
+
*/
|
|
3894
|
+
function _emitCommandFailure(error, context) {
|
|
3895
|
+
if (!isUserError(error)) container$1.client.emit("commandError", error, context);
|
|
3896
|
+
else if (context.interaction.data.type === ApplicationCommandType.ChatInput) container$1.client.emit("chatInputCommandDenied", error, context);
|
|
3897
|
+
else container$1.client.emit("contextMenuCommandDenied", error, context);
|
|
3898
|
+
}
|
|
3899
|
+
/**
|
|
3685
3900
|
* Executes a command method on a command object.
|
|
3686
3901
|
*
|
|
3687
3902
|
* @since 1.0.0
|
|
@@ -3737,9 +3952,11 @@ var InteractionHandler = class extends Piece$1 {
|
|
|
3737
3952
|
|
|
3738
3953
|
//#endregion
|
|
3739
3954
|
//#region src/lib/structures/InteractionHandlerStore.ts
|
|
3955
|
+
var _InteractionHandlerStore_brand = /* @__PURE__ */ new WeakSet();
|
|
3740
3956
|
var InteractionHandlerStore = class extends Store$1 {
|
|
3741
3957
|
constructor() {
|
|
3742
3958
|
super(InteractionHandler, { name: "interaction-handlers" });
|
|
3959
|
+
_classPrivateMethodInitSpec(this, _InteractionHandlerStore_brand);
|
|
3743
3960
|
}
|
|
3744
3961
|
async runHandler(response, interaction) {
|
|
3745
3962
|
const parsed = container$1.idParser.run(interaction.data.custom_id);
|
|
@@ -3759,12 +3976,37 @@ var InteractionHandlerStore = class extends Store$1 {
|
|
|
3759
3976
|
interaction,
|
|
3760
3977
|
response
|
|
3761
3978
|
};
|
|
3979
|
+
const checked = await Result.fromAsync(async () => {
|
|
3980
|
+
const handlerInteraction = makeInteraction(response, interaction);
|
|
3981
|
+
const preconditions = await runPreconditions(handler, "interactionHandler", handlerInteraction);
|
|
3982
|
+
if (preconditions.isErr()) throw preconditions.unwrapErr();
|
|
3983
|
+
return handlerInteraction;
|
|
3984
|
+
});
|
|
3985
|
+
if (checked.isErr()) {
|
|
3986
|
+
_assertClassBrand(_InteractionHandlerStore_brand, this, _emitFailure).call(this, checked.unwrapErr(), context, response);
|
|
3987
|
+
container$1.client.emit("interactionHandlerFinish", context);
|
|
3988
|
+
return response;
|
|
3989
|
+
}
|
|
3990
|
+
container$1.client.emit("interactionHandlerAccepted", context);
|
|
3762
3991
|
container$1.client.emit("interactionHandlerRun", context);
|
|
3763
|
-
(await Result.fromAsync(() => handler.run(
|
|
3992
|
+
(await Result.fromAsync(() => handler.run(checked.unwrap(), parsed.content))).inspect((value) => container$1.client.emit("interactionHandlerSuccess", context, value)).inspectErr((error) => _assertClassBrand(_InteractionHandlerStore_brand, this, _emitFailure).call(this, error, context, response));
|
|
3764
3993
|
container$1.client.emit("interactionHandlerFinish", context);
|
|
3765
3994
|
return response;
|
|
3766
3995
|
}
|
|
3767
3996
|
};
|
|
3997
|
+
/**
|
|
3998
|
+
* Emits `interactionHandlerDenied` for a {@link UserError} and `interactionHandlerError` otherwise, then replies as
|
|
3999
|
+
* for any other thrown error.
|
|
4000
|
+
*
|
|
4001
|
+
* @param error - The value that was thrown.
|
|
4002
|
+
* @param context - The context of the run.
|
|
4003
|
+
* @param response - The server response object.
|
|
4004
|
+
*/
|
|
4005
|
+
function _emitFailure(error, context, response) {
|
|
4006
|
+
if (isUserError(error)) container$1.client.emit("interactionHandlerDenied", error, context);
|
|
4007
|
+
else container$1.client.emit("interactionHandlerError", error, context);
|
|
4008
|
+
handleError(response, error);
|
|
4009
|
+
}
|
|
3768
4010
|
|
|
3769
4011
|
//#endregion
|
|
3770
4012
|
//#region src/lib/structures/Listener.ts
|
|
@@ -3829,6 +4071,152 @@ var ListenerStore = class extends Store$1 {
|
|
|
3829
4071
|
}
|
|
3830
4072
|
};
|
|
3831
4073
|
|
|
4074
|
+
//#endregion
|
|
4075
|
+
//#region src/lib/errors/PreconditionError.ts
|
|
4076
|
+
/**
|
|
4077
|
+
* Errors thrown by preconditions, that is, any check that runs before a command or an interaction
|
|
4078
|
+
* handler is executed, such as the guild restrictions applied by
|
|
4079
|
+
* {@link RestrictGuildIds}.
|
|
4080
|
+
*
|
|
4081
|
+
* @remarks Being a {@link UserError}, it is emitted as a `*Denied` event when thrown from a command, an autocomplete
|
|
4082
|
+
* handler, or an interaction handler, and not as `commandError`. The framework has no precondition store: the
|
|
4083
|
+
* decorators of `@wolfstar/decorators` are what throws it.
|
|
4084
|
+
*
|
|
4085
|
+
* @property name This will be `'PreconditionError'` and can be used to distinguish the type of error when any error gets thrown.
|
|
4086
|
+
* @since 3.2.0
|
|
4087
|
+
* @example
|
|
4088
|
+
* ```typescript
|
|
4089
|
+
* throw new PreconditionError({
|
|
4090
|
+
* precondition: 'GuildIds',
|
|
4091
|
+
* identifier: Identifiers.PreconditionGuildIds,
|
|
4092
|
+
* message: 'This command can only be used in specific guilds.',
|
|
4093
|
+
* context: { guildIds: ['737141877803057244'] }
|
|
4094
|
+
* });
|
|
4095
|
+
* ```
|
|
4096
|
+
*/
|
|
4097
|
+
var PreconditionError = class extends UserError {
|
|
4098
|
+
constructor(options) {
|
|
4099
|
+
super({
|
|
4100
|
+
...options,
|
|
4101
|
+
identifier: options.identifier ?? options.precondition
|
|
4102
|
+
});
|
|
4103
|
+
_defineProperty(this, "precondition", void 0);
|
|
4104
|
+
this.precondition = options.precondition;
|
|
4105
|
+
}
|
|
4106
|
+
get name() {
|
|
4107
|
+
return "PreconditionError";
|
|
4108
|
+
}
|
|
4109
|
+
};
|
|
4110
|
+
|
|
4111
|
+
//#endregion
|
|
4112
|
+
//#region src/lib/structures/Precondition.ts
|
|
4113
|
+
/**
|
|
4114
|
+
* A check that runs before a command method does, loaded from the `preconditions` directory into the
|
|
4115
|
+
* `preconditions` store.
|
|
4116
|
+
*
|
|
4117
|
+
* @remarks A precondition with a `position` is global: it runs, in ascending order of `position`, before the
|
|
4118
|
+
* preconditions of every chat input and context menu command, and of every autocomplete and interaction handler that
|
|
4119
|
+
* it has a method for. Any other one runs only for the commands that list its
|
|
4120
|
+
* name in the `preconditions` option. The method it needs depends on the command, and a precondition that is asked to
|
|
4121
|
+
* run for a kind of command it has no method for denies the command with
|
|
4122
|
+
* {@linkcode Identifiers.PreconditionMissingChatInputHandler} or
|
|
4123
|
+
* {@linkcode Identifiers.PreconditionMissingContextMenuHandler}.
|
|
4124
|
+
* @since 6.3.0
|
|
4125
|
+
* @example
|
|
4126
|
+
* ```typescript
|
|
4127
|
+
* import { Precondition } from '@wolfstar/http-framework';
|
|
4128
|
+
*
|
|
4129
|
+
* export class UserPrecondition extends Precondition {
|
|
4130
|
+
* public override chatInputRun(interaction: Precondition.ChatInputInteraction) {
|
|
4131
|
+
* return interaction.user.id === process.env.OWNER_ID ? this.ok() : this.error({ message: 'Only the owner can use this command.' });
|
|
4132
|
+
* }
|
|
4133
|
+
* }
|
|
4134
|
+
* ```
|
|
4135
|
+
*/
|
|
4136
|
+
var Precondition = class extends Piece$1 {
|
|
4137
|
+
constructor(context, options = {}) {
|
|
4138
|
+
super(context, options);
|
|
4139
|
+
_defineProperty(this, "position", void 0);
|
|
4140
|
+
this.position = options.position ?? null;
|
|
4141
|
+
}
|
|
4142
|
+
/**
|
|
4143
|
+
* Lets the command run.
|
|
4144
|
+
* @since 6.3.0
|
|
4145
|
+
*/
|
|
4146
|
+
ok() {
|
|
4147
|
+
return Result.ok();
|
|
4148
|
+
}
|
|
4149
|
+
/**
|
|
4150
|
+
* Denies the command with a {@link PreconditionError} whose `precondition` is the name of this piece.
|
|
4151
|
+
*
|
|
4152
|
+
* @param options The message, identifier and context of the error.
|
|
4153
|
+
* @since 6.3.0
|
|
4154
|
+
*/
|
|
4155
|
+
error(options = {}) {
|
|
4156
|
+
return Result.err(new PreconditionError({
|
|
4157
|
+
precondition: this.name,
|
|
4158
|
+
...options
|
|
4159
|
+
}));
|
|
4160
|
+
}
|
|
4161
|
+
};
|
|
4162
|
+
/**
|
|
4163
|
+
* A {@link Precondition} that has to implement the check for every kind of command.
|
|
4164
|
+
*
|
|
4165
|
+
* @since 6.3.0
|
|
4166
|
+
*/
|
|
4167
|
+
var AllFlowsPrecondition = class extends Precondition {};
|
|
4168
|
+
|
|
4169
|
+
//#endregion
|
|
4170
|
+
//#region src/lib/structures/PreconditionStore.ts
|
|
4171
|
+
var _globalPreconditions = /* @__PURE__ */ new WeakMap();
|
|
4172
|
+
var _PreconditionStore_brand = /* @__PURE__ */ new WeakSet();
|
|
4173
|
+
var PreconditionStore = class extends Store$1 {
|
|
4174
|
+
constructor() {
|
|
4175
|
+
super(Precondition, { name: "preconditions" });
|
|
4176
|
+
_classPrivateMethodInitSpec(this, _PreconditionStore_brand);
|
|
4177
|
+
_classPrivateFieldInitSpec(this, _globalPreconditions, []);
|
|
4178
|
+
}
|
|
4179
|
+
/**
|
|
4180
|
+
* Runs the global preconditions, the ones with a `position`, in ascending order of it, stopping at the first one
|
|
4181
|
+
* that denies the interaction.
|
|
4182
|
+
*
|
|
4183
|
+
* @since 6.3.0
|
|
4184
|
+
* @param kind What is being run.
|
|
4185
|
+
* @param interaction The interaction being handled.
|
|
4186
|
+
* @param target The command or interaction handler being run.
|
|
4187
|
+
* @param context The context of the checks.
|
|
4188
|
+
* @returns The first `Err`, or `Result.ok()` when every global precondition lets the command run.
|
|
4189
|
+
*/
|
|
4190
|
+
async run(kind, interaction, target, context = {}) {
|
|
4191
|
+
for (const precondition of _classPrivateFieldGet2(_globalPreconditions, this)) {
|
|
4192
|
+
const result = await runPrecondition(precondition, kind, interaction, target, context);
|
|
4193
|
+
if (result.isErr()) return result;
|
|
4194
|
+
}
|
|
4195
|
+
return Result.ok();
|
|
4196
|
+
}
|
|
4197
|
+
set(key, value) {
|
|
4198
|
+
_assertClassBrand(_PreconditionStore_brand, this, _removeGlobal).call(this, key);
|
|
4199
|
+
if (value.position !== null) {
|
|
4200
|
+
const index = _classPrivateFieldGet2(_globalPreconditions, this).findIndex((precondition) => precondition.position >= value.position);
|
|
4201
|
+
if (index === -1) _classPrivateFieldGet2(_globalPreconditions, this).push(value);
|
|
4202
|
+
else _classPrivateFieldGet2(_globalPreconditions, this).splice(index, 0, value);
|
|
4203
|
+
}
|
|
4204
|
+
return super.set(key, value);
|
|
4205
|
+
}
|
|
4206
|
+
delete(key) {
|
|
4207
|
+
_assertClassBrand(_PreconditionStore_brand, this, _removeGlobal).call(this, key);
|
|
4208
|
+
return super.delete(key);
|
|
4209
|
+
}
|
|
4210
|
+
clear() {
|
|
4211
|
+
_classPrivateFieldGet2(_globalPreconditions, this).length = 0;
|
|
4212
|
+
return super.clear();
|
|
4213
|
+
}
|
|
4214
|
+
};
|
|
4215
|
+
function _removeGlobal(key) {
|
|
4216
|
+
const index = _classPrivateFieldGet2(_globalPreconditions, this).findIndex((precondition) => precondition.name === key);
|
|
4217
|
+
if (index !== -1) _classPrivateFieldGet2(_globalPreconditions, this).splice(index, 1);
|
|
4218
|
+
}
|
|
4219
|
+
|
|
3832
4220
|
//#endregion
|
|
3833
4221
|
//#region src/lib/utils/fetch-bridge.ts
|
|
3834
4222
|
function toIncomingMessage(request) {
|
|
@@ -4029,6 +4417,7 @@ async function getSafeTextBody(request) {
|
|
|
4029
4417
|
container$1.stores.register(new CommandStore());
|
|
4030
4418
|
container$1.stores.register(new InteractionHandlerStore());
|
|
4031
4419
|
container$1.stores.register(new ListenerStore());
|
|
4420
|
+
container$1.stores.register(new PreconditionStore());
|
|
4032
4421
|
container$1.logger ??= new Logger();
|
|
4033
4422
|
var _discordPublicKey = /* @__PURE__ */ new WeakMap();
|
|
4034
4423
|
var _fetchKey = /* @__PURE__ */ new WeakMap();
|
|
@@ -4218,6 +4607,10 @@ _defineProperty(Client, "plugins", new PluginManager());
|
|
|
4218
4607
|
/**
|
|
4219
4608
|
* Errors thrown while resolving the options (arguments) of an interaction.
|
|
4220
4609
|
*
|
|
4610
|
+
* @remarks The framework never throws this error by itself: Discord validates the type and the bounds of the options
|
|
4611
|
+
* before sending the interaction. It is meant to be thrown from a command that rejects a value, and, being a
|
|
4612
|
+
* {@link UserError}, it is emitted as a `*Denied` event.
|
|
4613
|
+
*
|
|
4221
4614
|
* @property name This will be `'ArgumentError'` and can be used to distinguish the type of error when any error gets thrown.
|
|
4222
4615
|
* @since 3.2.0
|
|
4223
4616
|
* @example
|
|
@@ -4249,39 +4642,6 @@ var ArgumentError = class extends UserError {
|
|
|
4249
4642
|
}
|
|
4250
4643
|
};
|
|
4251
4644
|
|
|
4252
|
-
//#endregion
|
|
4253
|
-
//#region src/lib/errors/PreconditionError.ts
|
|
4254
|
-
/**
|
|
4255
|
-
* Errors thrown by preconditions, that is, any check that runs before a command or an interaction
|
|
4256
|
-
* handler is executed, such as the guild restrictions applied by
|
|
4257
|
-
* {@link RestrictGuildIds}.
|
|
4258
|
-
*
|
|
4259
|
-
* @property name This will be `'PreconditionError'` and can be used to distinguish the type of error when any error gets thrown.
|
|
4260
|
-
* @since 3.2.0
|
|
4261
|
-
* @example
|
|
4262
|
-
* ```typescript
|
|
4263
|
-
* throw new PreconditionError({
|
|
4264
|
-
* precondition: 'GuildIds',
|
|
4265
|
-
* identifier: Identifiers.PreconditionGuildIds,
|
|
4266
|
-
* message: 'This command can only be used in specific guilds.',
|
|
4267
|
-
* context: { guildIds: ['737141877803057244'] }
|
|
4268
|
-
* });
|
|
4269
|
-
* ```
|
|
4270
|
-
*/
|
|
4271
|
-
var PreconditionError = class extends UserError {
|
|
4272
|
-
constructor(options) {
|
|
4273
|
-
super({
|
|
4274
|
-
...options,
|
|
4275
|
-
identifier: options.identifier ?? options.precondition
|
|
4276
|
-
});
|
|
4277
|
-
_defineProperty(this, "precondition", void 0);
|
|
4278
|
-
this.precondition = options.precondition;
|
|
4279
|
-
}
|
|
4280
|
-
get name() {
|
|
4281
|
-
return "PreconditionError";
|
|
4282
|
-
}
|
|
4283
|
-
};
|
|
4284
|
-
|
|
4285
4645
|
//#endregion
|
|
4286
4646
|
//#region src/lib/plugins/Plugin.ts
|
|
4287
4647
|
/**
|
|
@@ -4348,5 +4708,5 @@ function toPermissionNames(bits) {
|
|
|
4348
4708
|
}
|
|
4349
4709
|
|
|
4350
4710
|
//#endregion
|
|
4351
|
-
export { AliasPiece, AliasStore, ApplicationCommandRegistry, ApplicationCommandRegistryEntry, ArgumentError, AutocompleteInteraction, BaseInteraction, ChatInputCommandInteraction, ChatInputRouterError, ChatInputRouterErrors, Client, Command, CommandInteraction, CommandLoaderStrategy, CommandRegistry, CommandRouter, CommandStore, CommandStoreRouter, Events, HotModuleReloader, HttpCodes, Identifiers, InteractionHandler, InteractionHandlerStore, Listener, ListenerLoaderStrategy, ListenerStore, LoaderError, LogLevel, Logger, Message, MessageComponentButtonInteraction, MessageComponentChannelSelectInteraction, MessageComponentInteraction, MessageComponentMentionableSelectInteraction, MessageComponentRoleSelectInteraction, MessageComponentStringSelectInteraction as MessageComponentSelectMenuInteraction, MessageComponentStringSelectInteraction, MessageComponentUserSelectInteraction, MessageContextMenuCommandInteraction, MissingExportsError, ModalSubmitInteraction, PartialMessage, Piece, Plugin, PluginHook, PluginHookError, PluginManager, PreconditionError, RegisterCommand, RegisterMessageCommand, RegisterSubcommand, RegisterSubcommandGroup, RegisterUserCommand, RestrictGuildIds, Store, StoreRegistry, StringIdParser, UserContextMenuCommandInteraction, UserError, applicationCommandRegistry, container, definePlugin, extractTopLevelOptions, getMissingPermissions, makeInteraction, postInitialization, postListen, preGenericsInitialization, preInitialization, preLoad, resolvePermissions, restrictedGuildIdRegistry, toPermissionNames, toPluginEntries, transformAutocompleteInteraction, transformInteraction, transformMessageInteraction, transformUserInteraction };
|
|
4711
|
+
export { AliasPiece, AliasStore, AllFlowsPrecondition, ApplicationCommandRegistry, ApplicationCommandRegistryEntry, ArgumentError, AutocompleteInteraction, BaseInteraction, ChatInputCommandInteraction, ChatInputRouterError, ChatInputRouterErrors, Client, Command, CommandInteraction, CommandLoaderStrategy, CommandRegistry, CommandRouter, CommandStore, CommandStoreRouter, Events, HotModuleReloader, HttpCodes, Identifiers, InteractionHandler, InteractionHandlerStore, Listener, ListenerLoaderStrategy, ListenerStore, LoaderError, LogLevel, Logger, Message, MessageComponentButtonInteraction, MessageComponentChannelSelectInteraction, MessageComponentInteraction, MessageComponentMentionableSelectInteraction, MessageComponentRoleSelectInteraction, MessageComponentStringSelectInteraction as MessageComponentSelectMenuInteraction, MessageComponentStringSelectInteraction, MessageComponentUserSelectInteraction, MessageContextMenuCommandInteraction, MissingExportsError, ModalSubmitInteraction, PartialMessage, Piece, Plugin, PluginHook, PluginHookError, PluginManager, Precondition, PreconditionError, PreconditionRunCondition, PreconditionRunMode, PreconditionStore, RegisterCommand, RegisterMessageCommand, RegisterSubcommand, RegisterSubcommandGroup, RegisterUserCommand, RestrictGuildIds, Store, StoreRegistry, StringIdParser, UserContextMenuCommandInteraction, UserError, applicationCommandRegistry, container, definePlugin, extractTopLevelOptions, getMissingPermissions, isUserError, makeInteraction, postInitialization, postListen, preGenericsInitialization, preInitialization, preLoad, resolvePermissions, restrictedGuildIdRegistry, runPrecondition, runPreconditions, toPermissionNames, toPluginEntries, transformAutocompleteInteraction, transformInteraction, transformMessageInteraction, transformUserInteraction };
|
|
4352
4712
|
//# sourceMappingURL=index.js.map
|