@seedcord/core 0.1.3 → 0.2.0-next.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/README.md +35 -5
- package/dist/{subscribers-nEpbJj3Z.mjs → Bus-DcuUtOEL.mjs} +401 -31
- package/dist/Bus-DcuUtOEL.mjs.map +1 -0
- package/dist/{HmrModuleHandler-KxRP8lqJ.mjs → HmrModuleHandler-9AUfKXRl.mjs} +2 -2
- package/dist/{HmrModuleHandler-KxRP8lqJ.mjs.map → HmrModuleHandler-9AUfKXRl.mjs.map} +1 -1
- package/dist/{Plugin-CDAV7P9l.mjs → Plugin-Bkeqcjy6.mjs} +12 -3
- package/dist/Plugin-Bkeqcjy6.mjs.map +1 -0
- package/dist/{Plugin-qRc7Ch4g.d.mts → Plugin-Cl5P7-PO.d.mts} +19 -7
- package/dist/{cursor-D207VrRo.mjs → cursor-B07ArwDz.mjs} +4 -4
- package/dist/cursor-B07ArwDz.mjs.map +1 -0
- package/dist/{cursor-C77xH5QT.d.mts → cursor-__0_F4rW.d.mts} +10 -3
- package/dist/hmr.index.mjs +1 -1
- package/dist/{index-C0k7lRDi.d.mts → index-TYnQ-ztr.d.mts} +15 -4
- package/dist/index.d.mts +24 -11
- package/dist/index.mjs +26 -6
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.d.mts +13 -18
- package/dist/internal.index.mjs +16 -48
- package/dist/internal.index.mjs.map +1 -1
- package/dist/node-internal.index.d.mts +6 -5
- package/dist/node-internal.index.mjs +54 -49
- package/dist/node-internal.index.mjs.map +1 -1
- package/dist/plugin.index.d.mts +1 -1
- package/dist/plugin.index.mjs +1 -1
- package/dist/subscribers-DuHg-bGT.mjs +3 -0
- package/package.json +27 -35
- package/dist/HmrModuleHandler-CxGOo1LT.cjs +0 -182
- package/dist/HmrModuleHandler-CxGOo1LT.cjs.map +0 -1
- package/dist/Plugin-CDAV7P9l.mjs.map +0 -1
- package/dist/Plugin-DVNh1kvX.cjs +0 -95
- package/dist/Plugin-DVNh1kvX.cjs.map +0 -1
- package/dist/cursor-D207VrRo.mjs.map +0 -1
- package/dist/cursor-DFgJ70_B.cjs +0 -1339
- package/dist/cursor-DFgJ70_B.cjs.map +0 -1
- package/dist/devChannel-Cdnmz6hd.cjs +0 -25
- package/dist/devChannel-Cdnmz6hd.cjs.map +0 -1
- package/dist/hmr.index.cjs +0 -4
- package/dist/hmr.index.d.cts +0 -1
- package/dist/index.cjs +0 -889
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1
- package/dist/internal.index.cjs +0 -717
- package/dist/internal.index.cjs.map +0 -1
- package/dist/internal.index.d.cts +0 -1
- package/dist/node-internal.index.cjs +0 -799
- package/dist/node-internal.index.cjs.map +0 -1
- package/dist/node-internal.index.d.cts +0 -1
- package/dist/phases-8qiiLKjS.cjs +0 -42
- package/dist/phases-8qiiLKjS.cjs.map +0 -1
- package/dist/plugin.index.cjs +0 -4
- package/dist/plugin.index.d.cts +0 -1
- package/dist/publishDefault-BCrMG9T8.mjs +0 -273
- package/dist/publishDefault-BCrMG9T8.mjs.map +0 -1
- package/dist/publishDefault-D52iT8mF.cjs +0 -368
- package/dist/publishDefault-D52iT8mF.cjs.map +0 -1
- package/dist/slashRouteLeaves-HVl6Ymr0.cjs +0 -28
- package/dist/slashRouteLeaves-HVl6Ymr0.cjs.map +0 -1
- package/dist/subscribers-6x4xw39Z.cjs +0 -531
- package/dist/subscribers-6x4xw39Z.cjs.map +0 -1
- package/dist/subscribers-nEpbJj3Z.mjs.map +0 -1
package/dist/cursor-DFgJ70_B.cjs
DELETED
|
@@ -1,1339 +0,0 @@
|
|
|
1
|
-
const require_publishDefault = require('./publishDefault-D52iT8mF.cjs');
|
|
2
|
-
require("reflect-metadata");
|
|
3
|
-
let _discordjs_builders = require("@discordjs/builders");
|
|
4
|
-
let _seedcord_logger = require("@seedcord/logger");
|
|
5
|
-
let _seedcord_utils_internal = require("@seedcord/utils/internal");
|
|
6
|
-
let discord_api_types_v10 = require("discord-api-types/v10");
|
|
7
|
-
let _seedcord_errors = require("@seedcord/errors");
|
|
8
|
-
let _seedcord_errors_internal = require("@seedcord/errors/internal");
|
|
9
|
-
let _seedcord_utils = require("@seedcord/utils");
|
|
10
|
-
|
|
11
|
-
//#region src/miscellaneous/guarded.ts
|
|
12
|
-
function accessorStore() {
|
|
13
|
-
return Object.create(null);
|
|
14
|
-
}
|
|
15
|
-
function clearStore(store) {
|
|
16
|
-
for (const key of Object.keys(store)) Reflect.deleteProperty(store, key);
|
|
17
|
-
}
|
|
18
|
-
function guardedAccessor(accessor, storage) {
|
|
19
|
-
return new Proxy(storage, { get(target, key, receiver) {
|
|
20
|
-
if (typeof key !== "string" || Object.hasOwn(target, key)) return Reflect.get(target, key, receiver);
|
|
21
|
-
throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CoreAccessorUnresolved, [accessor, key]);
|
|
22
|
-
} });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/commands/CommandInjector.ts
|
|
27
|
-
const commandStorage = accessorStore();
|
|
28
|
-
const userMenuStorage = accessorStore();
|
|
29
|
-
const messageMenuStorage = accessorStore();
|
|
30
|
-
/**
|
|
31
|
-
* The bot's deployed slash commands, keyed by {@link SlashOptionRegistry}. Filled by
|
|
32
|
-
* {@link CommandInjector} after each deploy, and a read before that throws.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* import { Commands } from '@seedcord/gateway';
|
|
37
|
-
*
|
|
38
|
-
* await this.reply(`Try ${Commands['config/set'].mention}`);
|
|
39
|
-
*
|
|
40
|
-
* // a help listing
|
|
41
|
-
* const lines = Object.values(Commands).map((c) => `${c.mention} ${c.description}`);
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
const Commands = guardedAccessor("Commands", commandStorage);
|
|
45
|
-
/**
|
|
46
|
-
* The bot's deployed context-menu commands. Filled by {@link CommandInjector} after each deploy, and a read
|
|
47
|
-
* before that throws.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```ts
|
|
51
|
-
* import { ContextMenus } from '@seedcord/gateway';
|
|
52
|
-
*
|
|
53
|
-
* const id = ContextMenus.user['View Profile'].id;
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
const ContextMenus = {
|
|
57
|
-
user: guardedAccessor("ContextMenus.user", userMenuStorage),
|
|
58
|
-
message: guardedAccessor("ContextMenus.message", messageMenuStorage)
|
|
59
|
-
};
|
|
60
|
-
const MULTI_GUILD = Symbol("seedcord:commands:multi-guild");
|
|
61
|
-
function commandKey(type, name) {
|
|
62
|
-
return `${type}:${name}`;
|
|
63
|
-
}
|
|
64
|
-
function slashBuildersOf(all) {
|
|
65
|
-
const slash = all.filter((command) => command instanceof _discordjs_builders.SlashCommandBuilder);
|
|
66
|
-
return [...new Set(slash)];
|
|
67
|
-
}
|
|
68
|
-
/** @internal */
|
|
69
|
-
var CommandInjector = class {
|
|
70
|
-
logger = new _seedcord_logger.Logger("Commands", { channel: "bot" });
|
|
71
|
-
inject(deploy, all) {
|
|
72
|
-
this.clear();
|
|
73
|
-
const ids = {
|
|
74
|
-
global: this.indexByKey(deploy.global),
|
|
75
|
-
guild: this.indexGuilds(deploy.guilds),
|
|
76
|
-
warned: /* @__PURE__ */ new Set()
|
|
77
|
-
};
|
|
78
|
-
let clickable = 0;
|
|
79
|
-
for (const command of slashBuildersOf(all)) {
|
|
80
|
-
const id = this.resolveId(discord_api_types_v10.ApplicationCommandType.ChatInput, command.name, ids, "falling back to plain text (not clickable)");
|
|
81
|
-
for (const leaf of (0, _seedcord_utils_internal.routeLeavesOf)(command.toJSON())) {
|
|
82
|
-
commandStorage[leaf.route] = {
|
|
83
|
-
mention: id ? this.toMention(leaf.route, id) : this.toPlain(leaf.route),
|
|
84
|
-
...id && { id },
|
|
85
|
-
route: leaf.route,
|
|
86
|
-
description: leaf.description
|
|
87
|
-
};
|
|
88
|
-
if (id) clickable++;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const menus = require_publishDefault.contextMenuLeaves(all);
|
|
92
|
-
this.injectMenus(menus.user, discord_api_types_v10.ApplicationCommandType.User, userMenuStorage, ids);
|
|
93
|
-
this.injectMenus(menus.message, discord_api_types_v10.ApplicationCommandType.Message, messageMenuStorage, ids);
|
|
94
|
-
this.logger.utils.summary("Linked commands", {
|
|
95
|
-
clickable,
|
|
96
|
-
plain: Object.keys(commandStorage).length - clickable,
|
|
97
|
-
"context menus": menus.user.size + menus.message.size
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
injectMenus(names, kind, storage, ids) {
|
|
101
|
-
for (const name of names) {
|
|
102
|
-
const id = this.resolveId(kind, name, ids, "leaving its id unset");
|
|
103
|
-
storage[name] = {
|
|
104
|
-
...id && { id },
|
|
105
|
-
name,
|
|
106
|
-
kind
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
indexByKey(collection) {
|
|
111
|
-
const map = /* @__PURE__ */ new Map();
|
|
112
|
-
for (const command of collection.values()) map.set(commandKey(command.type, command.name), command.id);
|
|
113
|
-
return map;
|
|
114
|
-
}
|
|
115
|
-
indexGuilds(guilds) {
|
|
116
|
-
const map = /* @__PURE__ */ new Map();
|
|
117
|
-
for (const collection of guilds.values()) for (const command of collection.values()) {
|
|
118
|
-
const key = commandKey(command.type, command.name);
|
|
119
|
-
const existing = map.get(key);
|
|
120
|
-
if (existing === void 0) map.set(key, command.id);
|
|
121
|
-
else if (existing !== command.id) map.set(key, MULTI_GUILD);
|
|
122
|
-
}
|
|
123
|
-
return map;
|
|
124
|
-
}
|
|
125
|
-
resolveId(type, name, ids, consequence) {
|
|
126
|
-
const key = commandKey(type, name);
|
|
127
|
-
const global = ids.global.get(key);
|
|
128
|
-
if (global) return global;
|
|
129
|
-
const guild = ids.guild.get(key);
|
|
130
|
-
if (guild === void 0) return void 0;
|
|
131
|
-
if (guild === MULTI_GUILD) {
|
|
132
|
-
if (!ids.warned.has(key)) {
|
|
133
|
-
this.logger.warn(`${_seedcord_logger.paint.sky.bold(name)} is deployed to multiple guilds, ${consequence}.`);
|
|
134
|
-
ids.warned.add(key);
|
|
135
|
-
}
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
return guild;
|
|
139
|
-
}
|
|
140
|
-
toMention(route, id) {
|
|
141
|
-
return `</${route.replaceAll("/", " ")}:${id}>`;
|
|
142
|
-
}
|
|
143
|
-
toPlain(route) {
|
|
144
|
-
return `/${route.replaceAll("/", " ")}`;
|
|
145
|
-
}
|
|
146
|
-
clear() {
|
|
147
|
-
for (const store of [
|
|
148
|
-
commandStorage,
|
|
149
|
-
userMenuStorage,
|
|
150
|
-
messageMenuStorage
|
|
151
|
-
]) clearStore(store);
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
//#endregion
|
|
156
|
-
//#region src/stops/Notice.ts
|
|
157
|
-
/**
|
|
158
|
-
* Base class for a user-facing refusal or a reported fault.
|
|
159
|
-
*
|
|
160
|
-
* Throw a `Notice` to stop a handler and reply to the user. The framework catches it at the controller
|
|
161
|
-
* boundary and renders {@link Notice.render}, which always decides what the user sees. With `report`
|
|
162
|
-
* false that render is all that happens. With `report` true the framework also logs the fault and
|
|
163
|
-
* publishes it to the `handledException` bus. A raw, non-Notice throw shows the generic message.
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* ```ts
|
|
167
|
-
* import { Notice, BuilderComponent, type RenderContext, type ReplyResponse } from '@seedcord/gateway';
|
|
168
|
-
* import { TextDisplayBuilder } from '@discordjs/builders';
|
|
169
|
-
*
|
|
170
|
-
* // reading `.component` applies the configured bot color to the container accent
|
|
171
|
-
* class TooPoorCard extends BuilderComponent<'container'> {
|
|
172
|
-
* constructor(balance: number) {
|
|
173
|
-
* super('container');
|
|
174
|
-
* this.instance.addTextDisplayComponents(
|
|
175
|
-
* new TextDisplayBuilder().setContent(`### Insufficient balance\nYou need more than ${balance} coins.`)
|
|
176
|
-
* );
|
|
177
|
-
* }
|
|
178
|
-
* }
|
|
179
|
-
*
|
|
180
|
-
* class TooPoor extends Notice {
|
|
181
|
-
* constructor(private readonly balance: number) {
|
|
182
|
-
* super(`balance ${balance} is below the cost`);
|
|
183
|
-
* }
|
|
184
|
-
*
|
|
185
|
-
* render(_ctx: RenderContext): ReplyResponse {
|
|
186
|
-
* return { components: [new TooPoorCard(this.balance).component] };
|
|
187
|
-
* }
|
|
188
|
-
* }
|
|
189
|
-
*
|
|
190
|
-
* // in a handler, throwing stops the handler and replies with render(ctx)
|
|
191
|
-
* if (wallet.balance < cost) throw new TooPoor(wallet.balance);
|
|
192
|
-
* ```
|
|
193
|
-
*/
|
|
194
|
-
var Notice = class extends Error {
|
|
195
|
-
/**
|
|
196
|
-
* Whether this denial is a reported fault. True also logs it and publishes it to the `handledException`
|
|
197
|
-
* bus. The user always sees {@link Notice.render} either way.
|
|
198
|
-
*
|
|
199
|
-
* @defaultValue `false`
|
|
200
|
-
*/
|
|
201
|
-
report = false;
|
|
202
|
-
/**
|
|
203
|
-
* Whether the reply is ephemeral, seen only by the invoking user. Set it false for a refusal the
|
|
204
|
-
* whole channel should see.
|
|
205
|
-
*
|
|
206
|
-
* @defaultValue `true`
|
|
207
|
-
*/
|
|
208
|
-
ephemeral = true;
|
|
209
|
-
/**
|
|
210
|
-
* A short one-line reason. When every arm of an `or` gate refuses and each refusal sets this, `or`
|
|
211
|
-
* lists them as the reply.
|
|
212
|
-
*/
|
|
213
|
-
summary;
|
|
214
|
-
constructor(message, options) {
|
|
215
|
-
super(message, options);
|
|
216
|
-
this.name = new.target.name;
|
|
217
|
-
Error.captureStackTrace(this, this.constructor);
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
//#endregion
|
|
222
|
-
//#region src/stops/NoticeCard.ts
|
|
223
|
-
var NoticeCard = class extends require_publishDefault.BuilderComponent {
|
|
224
|
-
constructor(description, title = "Cannot Proceed") {
|
|
225
|
-
super("container");
|
|
226
|
-
this.instance.addTextDisplayComponents(new _discordjs_builders.TextDisplayBuilder().setContent(`### ${title}\n${description}`));
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
//#endregion
|
|
231
|
-
//#region src/customId/Errors.ts
|
|
232
|
-
/**
|
|
233
|
-
* Thrown when a customId was minted by an older version of its shape.
|
|
234
|
-
*
|
|
235
|
-
* This is normal after the shape changes.
|
|
236
|
-
*/
|
|
237
|
-
var StaleCustomId = class extends Notice {
|
|
238
|
-
constructor(prefix) {
|
|
239
|
-
super(`Stale customId for "${prefix}".`);
|
|
240
|
-
}
|
|
241
|
-
render() {
|
|
242
|
-
return { components: [new NoticeCard("This button or menu is from an older version. Please run the command again.", "Outdated").component] };
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
/**
|
|
246
|
-
* Thrown when a customId wire is corrupt or tampered with and cannot be trusted.
|
|
247
|
-
*
|
|
248
|
-
* It reports because this is an odd case that should not happen.
|
|
249
|
-
*/
|
|
250
|
-
var InvalidCustomId = class extends Notice {
|
|
251
|
-
constructor(detail) {
|
|
252
|
-
super(`Invalid customId. ${detail}`);
|
|
253
|
-
this.report = true;
|
|
254
|
-
}
|
|
255
|
-
render() {
|
|
256
|
-
return { components: [new NoticeCard("Something went wrong. Please try again.").component] };
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
//#endregion
|
|
261
|
-
//#region src/customId/codec.ts
|
|
262
|
-
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
263
|
-
const BASE = 64n;
|
|
264
|
-
const CHAR_TO_VALUE = new Map([...ALPHABET].map((char, index) => [char, index]));
|
|
265
|
-
const DELIMITER = "";
|
|
266
|
-
const ESCAPE = "\x1B";
|
|
267
|
-
/** @internal */
|
|
268
|
-
const HASH_LENGTH = 3;
|
|
269
|
-
const SAFE_MAX = BigInt(Number.MAX_SAFE_INTEGER);
|
|
270
|
-
const SAFE_MIN = BigInt(Number.MIN_SAFE_INTEGER);
|
|
271
|
-
function bigintToBase64(value) {
|
|
272
|
-
if (value === 0n) return ALPHABET.charAt(0);
|
|
273
|
-
let text = "";
|
|
274
|
-
for (let remaining = value; remaining > 0n; remaining /= BASE) text = ALPHABET.charAt(Number(remaining % BASE)) + text;
|
|
275
|
-
return text;
|
|
276
|
-
}
|
|
277
|
-
function base64ToBigint(text) {
|
|
278
|
-
let value = 0n;
|
|
279
|
-
for (const char of text) {
|
|
280
|
-
const digit = CHAR_TO_VALUE.get(char);
|
|
281
|
-
if (digit === void 0) throw new InvalidCustomId(`bad character ${JSON.stringify(char)}`);
|
|
282
|
-
value = value * BASE + BigInt(digit);
|
|
283
|
-
}
|
|
284
|
-
return value;
|
|
285
|
-
}
|
|
286
|
-
function zigzagEncode(value) {
|
|
287
|
-
const big = BigInt(value);
|
|
288
|
-
return big >= 0n ? big << 1n : (-big << 1n) - 1n;
|
|
289
|
-
}
|
|
290
|
-
function zigzagDecode(encoded) {
|
|
291
|
-
return (encoded & 1n) === 1n ? -(encoded + 1n >> 1n) : encoded >> 1n;
|
|
292
|
-
}
|
|
293
|
-
function escapeToken(text) {
|
|
294
|
-
return text.replaceAll(/[\x1B\x1F]/g, (char) => ESCAPE + char);
|
|
295
|
-
}
|
|
296
|
-
function unescapeToken(text) {
|
|
297
|
-
let out = "";
|
|
298
|
-
for (let i = 0; i < text.length; i++) {
|
|
299
|
-
if (text.charAt(i) !== ESCAPE) {
|
|
300
|
-
out += text.charAt(i);
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
const next = text.charAt(i + 1);
|
|
304
|
-
if (next === "") throw new InvalidCustomId("dangling escape at end of token");
|
|
305
|
-
out += next;
|
|
306
|
-
i++;
|
|
307
|
-
}
|
|
308
|
-
return out;
|
|
309
|
-
}
|
|
310
|
-
function splitTokens(body) {
|
|
311
|
-
const pieces = [];
|
|
312
|
-
let current = "";
|
|
313
|
-
for (let i = 0; i < body.length; i++) {
|
|
314
|
-
const char = body.charAt(i);
|
|
315
|
-
if (char === ESCAPE) {
|
|
316
|
-
current += char + body.charAt(i + 1);
|
|
317
|
-
i++;
|
|
318
|
-
} else if (char === DELIMITER) {
|
|
319
|
-
pieces.push(current);
|
|
320
|
-
current = "";
|
|
321
|
-
} else current += char;
|
|
322
|
-
}
|
|
323
|
-
pieces.push(current);
|
|
324
|
-
return pieces;
|
|
325
|
-
}
|
|
326
|
-
function isBounded(field) {
|
|
327
|
-
if (field.kind === "int") return field.min !== void 0 && field.max !== void 0;
|
|
328
|
-
return field.kind === "snowflake" || field.kind === "uuid" || field.kind === "bool" || field.kind === "oneOf";
|
|
329
|
-
}
|
|
330
|
-
function radixOf(field) {
|
|
331
|
-
switch (field.kind) {
|
|
332
|
-
case "snowflake": return 1n << 64n;
|
|
333
|
-
case "uuid": return 1n << 128n;
|
|
334
|
-
case "bool": return 2n;
|
|
335
|
-
case "oneOf":
|
|
336
|
-
if (!field.choices?.length) throw new InvalidCustomId("oneOf field has no choices");
|
|
337
|
-
return BigInt(field.choices.length);
|
|
338
|
-
case "int":
|
|
339
|
-
if (field.min === void 0 || field.max === void 0) throw new InvalidCustomId("bounded int field is missing a bound");
|
|
340
|
-
return BigInt(field.max) - BigInt(field.min) + 1n;
|
|
341
|
-
default: throw new InvalidCustomId(`field kind ${field.kind} has no radix`);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
function boundedToBigint(field, name, value) {
|
|
345
|
-
const slot = boundedSlot(field, name, value);
|
|
346
|
-
if (slot < 0n || slot >= radixOf(field)) outOfRange(name, value);
|
|
347
|
-
return slot;
|
|
348
|
-
}
|
|
349
|
-
function boundedSlot(field, name, value) {
|
|
350
|
-
switch (field.kind) {
|
|
351
|
-
case "snowflake":
|
|
352
|
-
if (typeof value !== "string" || !/^\d+$/.test(value)) return outOfRange(name, value);
|
|
353
|
-
return BigInt(value);
|
|
354
|
-
case "uuid": {
|
|
355
|
-
if (typeof value !== "string") return outOfRange(name, value);
|
|
356
|
-
const hex = value.replaceAll("-", "");
|
|
357
|
-
if (!/^[0-9a-fA-F]{32}$/.test(hex)) return outOfRange(name, value);
|
|
358
|
-
return BigInt(`0x${hex}`);
|
|
359
|
-
}
|
|
360
|
-
case "bool": return value ? 1n : 0n;
|
|
361
|
-
case "oneOf": {
|
|
362
|
-
const index = (field.choices ?? []).indexOf(value);
|
|
363
|
-
return index === -1 ? outOfRange(name, value) : BigInt(index);
|
|
364
|
-
}
|
|
365
|
-
case "int":
|
|
366
|
-
if (!Number.isInteger(value)) return outOfRange(name, value);
|
|
367
|
-
return BigInt(value - (field.min ?? 0));
|
|
368
|
-
default: return outOfRange(name, value);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
function outOfRange(name, value) {
|
|
372
|
-
throw new _seedcord_errors_internal.SeedcordRangeError(_seedcord_errors.SeedcordErrorCode.CustomIdValueOutOfRange, [name, String(value)]);
|
|
373
|
-
}
|
|
374
|
-
function bigintToBoundedValue(field, slot) {
|
|
375
|
-
switch (field.kind) {
|
|
376
|
-
case "snowflake": return slot.toString();
|
|
377
|
-
case "uuid": return bigintToUuid(slot);
|
|
378
|
-
case "bool": return slot === 1n;
|
|
379
|
-
case "oneOf": return (field.choices ?? [])[Number(slot)];
|
|
380
|
-
case "int": return Number(slot) + (field.min ?? 0);
|
|
381
|
-
default: throw new InvalidCustomId(`field kind ${field.kind} is not bounded`);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
function bigintToUuid(value) {
|
|
385
|
-
const hex = value.toString(16).padStart(32, "0");
|
|
386
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
387
|
-
}
|
|
388
|
-
function encodeUnboundedToken(field, name, value) {
|
|
389
|
-
if (field.kind === "int") {
|
|
390
|
-
if (!Number.isSafeInteger(value)) outOfRange(name, value);
|
|
391
|
-
return bigintToBase64(zigzagEncode(value));
|
|
392
|
-
}
|
|
393
|
-
return escapeToken(value);
|
|
394
|
-
}
|
|
395
|
-
function decodeUnboundedToken(field, piece) {
|
|
396
|
-
if (field.kind !== "int") return unescapeToken(piece);
|
|
397
|
-
if (piece === "") throw new InvalidCustomId("empty integer token");
|
|
398
|
-
const decoded = zigzagDecode(base64ToBigint(piece));
|
|
399
|
-
if (decoded > SAFE_MAX || decoded < SAFE_MIN) throw new InvalidCustomId("integer out of safe range");
|
|
400
|
-
return Number(decoded);
|
|
401
|
-
}
|
|
402
|
-
/** @internal */
|
|
403
|
-
function computeLayoutHash(shape) {
|
|
404
|
-
const signature = JSON.stringify(Object.entries(shape).map(([name, field]) => [
|
|
405
|
-
name,
|
|
406
|
-
field.kind,
|
|
407
|
-
isBounded(field),
|
|
408
|
-
field.kind === "oneOf" ? field.choices ?? [] : null,
|
|
409
|
-
field.kind === "int" ? [field.min ?? null, field.max ?? null] : null
|
|
410
|
-
]));
|
|
411
|
-
const modulus = BASE ** BigInt(3);
|
|
412
|
-
let hash = 0n;
|
|
413
|
-
for (const char of signature) hash = (hash * 131n + BigInt(char.charCodeAt(0))) % modulus;
|
|
414
|
-
let text = "";
|
|
415
|
-
for (let i = 0; i < 3; i++) {
|
|
416
|
-
text = ALPHABET.charAt(Number(hash % BASE)) + text;
|
|
417
|
-
hash /= BASE;
|
|
418
|
-
}
|
|
419
|
-
return text;
|
|
420
|
-
}
|
|
421
|
-
/** @internal */
|
|
422
|
-
function encodeBody(shape, values) {
|
|
423
|
-
const fields = Object.entries(shape);
|
|
424
|
-
const pieces = [];
|
|
425
|
-
const bounded = fields.filter(([, field]) => isBounded(field));
|
|
426
|
-
if (bounded.length > 0) {
|
|
427
|
-
let packed = 0n;
|
|
428
|
-
for (const [name, field] of bounded) packed = packed * radixOf(field) + boundedToBigint(field, name, values[name]);
|
|
429
|
-
pieces.push(bigintToBase64(packed));
|
|
430
|
-
}
|
|
431
|
-
for (const [name, field] of fields) if (!isBounded(field)) pieces.push(encodeUnboundedToken(field, name, values[name]));
|
|
432
|
-
return pieces.join(DELIMITER);
|
|
433
|
-
}
|
|
434
|
-
function unpackBounded(bounded, blob, result) {
|
|
435
|
-
if (blob === void 0 || blob === "") throw new InvalidCustomId("empty packed block");
|
|
436
|
-
let packed = base64ToBigint(blob);
|
|
437
|
-
for (const [name, field] of [...bounded].reverse()) {
|
|
438
|
-
const radix = radixOf(field);
|
|
439
|
-
result[name] = bigintToBoundedValue(field, packed % radix);
|
|
440
|
-
packed /= radix;
|
|
441
|
-
}
|
|
442
|
-
if (packed !== 0n) throw new InvalidCustomId("leftover bits after unpacking");
|
|
443
|
-
}
|
|
444
|
-
/** @internal */
|
|
445
|
-
function decodeBody(shape, body) {
|
|
446
|
-
const fields = Object.entries(shape);
|
|
447
|
-
const bounded = fields.filter(([, field]) => isBounded(field));
|
|
448
|
-
const unbounded = fields.filter(([, field]) => !isBounded(field));
|
|
449
|
-
const expected = (bounded.length > 0 ? 1 : 0) + unbounded.length;
|
|
450
|
-
if (expected === 0) {
|
|
451
|
-
if (body !== "") throw new InvalidCustomId(`expected an empty body, got ${JSON.stringify(body)}`);
|
|
452
|
-
return {};
|
|
453
|
-
}
|
|
454
|
-
const pieces = splitTokens(body);
|
|
455
|
-
if (pieces.length !== expected) throw new InvalidCustomId(`expected ${expected} piece(s), got ${pieces.length}`);
|
|
456
|
-
const result = {};
|
|
457
|
-
let cursor = 0;
|
|
458
|
-
if (bounded.length > 0) {
|
|
459
|
-
unpackBounded(bounded, pieces[cursor], result);
|
|
460
|
-
cursor++;
|
|
461
|
-
}
|
|
462
|
-
for (const [name, field] of unbounded) {
|
|
463
|
-
const piece = pieces[cursor];
|
|
464
|
-
cursor++;
|
|
465
|
-
if (piece === void 0) throw new InvalidCustomId("missing trailing piece");
|
|
466
|
-
result[name] = decodeUnboundedToken(field, piece);
|
|
467
|
-
}
|
|
468
|
-
return result;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
//#endregion
|
|
472
|
-
//#region src/customId/CustomId.ts
|
|
473
|
-
const MAX_WIRE_LENGTH = 100;
|
|
474
|
-
function routeKeyOf(wire) {
|
|
475
|
-
const colon = wire.indexOf(":");
|
|
476
|
-
return colon === -1 ? "" : wire.slice(0, colon);
|
|
477
|
-
}
|
|
478
|
-
/** Strip the layout hash off the routeKey to recover the stable prefix the controller routes by. @internal */
|
|
479
|
-
function prefixOf(wire) {
|
|
480
|
-
const key = routeKeyOf(wire);
|
|
481
|
-
return key.length <= 3 ? "" : key.slice(0, key.length - 3);
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* A typed customId. The single source of truth shared by the component that mints it and the handler
|
|
485
|
-
* that reads it. This gives you typed reads on the `.customId` field in components. Values are packed
|
|
486
|
-
* into a compact wire string, which fits more of them inside Discord's 100-char limit.
|
|
487
|
-
*
|
|
488
|
-
* @typeParam Prefix - The stable route prefix, e.g. 'approve'.
|
|
489
|
-
* @typeParam Shape - The accumulated fields, filled in by the chain.
|
|
490
|
-
*
|
|
491
|
-
* @example
|
|
492
|
-
* ```ts
|
|
493
|
-
* const ApproveId = new CustomId('approve')
|
|
494
|
-
* .snowflake('userId')
|
|
495
|
-
* .oneOf('action', ['approve', 'deny']);
|
|
496
|
-
*
|
|
497
|
-
* // Set the custom id on a button when creating it.
|
|
498
|
-
* new ButtonBuilder().setCustomId(ApproveId.encode({ userId: '123', action: 'approve' }));
|
|
499
|
-
*
|
|
500
|
-
* // in the handler, userId comes back a string
|
|
501
|
-
* const { userId, action } = this.params; // userId: string, action: 'approve' | 'deny'
|
|
502
|
-
* await this.event.guild?.members.fetch(userId);
|
|
503
|
-
* ```
|
|
504
|
-
*/
|
|
505
|
-
var CustomId = class CustomId {
|
|
506
|
-
/** The stable route prefix, e.g. 'approve'. */
|
|
507
|
-
prefix;
|
|
508
|
-
/** The field definitions accumulated by the chain, keyed by name. */
|
|
509
|
-
shape;
|
|
510
|
-
/** The prefix plus a short hash of the shape, the part of the wire before the colon. */
|
|
511
|
-
routeKey;
|
|
512
|
-
constructor(prefix, shape = {}) {
|
|
513
|
-
if (!prefix || /[:\x1B\x1F]/.test(prefix)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdInvalidPrefix, [prefix]);
|
|
514
|
-
this.prefix = prefix;
|
|
515
|
-
this.shape = shape;
|
|
516
|
-
this.routeKey = prefix + computeLayoutHash(shape);
|
|
517
|
-
}
|
|
518
|
-
add(name, field) {
|
|
519
|
-
if (/^(?:0|[1-9]\d*)$/.test(name)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdReservedFieldName, [name]);
|
|
520
|
-
if (name in this.shape) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdDuplicateFieldName, [name]);
|
|
521
|
-
const shape = {
|
|
522
|
-
...this.shape,
|
|
523
|
-
[name]: field
|
|
524
|
-
};
|
|
525
|
-
return new CustomId(this.prefix, shape);
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Add a Discord ID field, decoded as a string (the `Snowflake` type from discord-api-types).
|
|
529
|
-
*
|
|
530
|
-
* @example
|
|
531
|
-
* ```ts
|
|
532
|
-
* new CustomId('ban').snowflake('userId');
|
|
533
|
-
* ```
|
|
534
|
-
*/
|
|
535
|
-
snowflake(name) {
|
|
536
|
-
return this.add(name, { kind: "snowflake" });
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Add a UUID field, decoded as a lowercase uuid string.
|
|
540
|
-
*
|
|
541
|
-
* @example
|
|
542
|
-
* ```ts
|
|
543
|
-
* new CustomId('ticket').uuid('ticketId');
|
|
544
|
-
* ```
|
|
545
|
-
*/
|
|
546
|
-
uuid(name) {
|
|
547
|
-
return this.add(name, { kind: "uuid" });
|
|
548
|
-
}
|
|
549
|
-
int(name, min, max) {
|
|
550
|
-
if (min !== void 0 && max !== void 0 && min > max) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdInvalidBounds, [
|
|
551
|
-
name,
|
|
552
|
-
min,
|
|
553
|
-
max
|
|
554
|
-
]);
|
|
555
|
-
const field = min === void 0 || max === void 0 ? { kind: "int" } : {
|
|
556
|
-
kind: "int",
|
|
557
|
-
min,
|
|
558
|
-
max
|
|
559
|
-
};
|
|
560
|
-
return this.add(name, field);
|
|
561
|
-
}
|
|
562
|
-
/**
|
|
563
|
-
* Add a boolean flag.
|
|
564
|
-
*
|
|
565
|
-
* @example
|
|
566
|
-
* ```ts
|
|
567
|
-
* new CustomId('settings').bool('silent');
|
|
568
|
-
* ```
|
|
569
|
-
*/
|
|
570
|
-
bool(name) {
|
|
571
|
-
return this.add(name, { kind: "bool" });
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* Add a field that is one value from a fixed list, decoded as the literal union. No `as const` needed.
|
|
575
|
-
*
|
|
576
|
-
* @example
|
|
577
|
-
* ```ts
|
|
578
|
-
* new CustomId('poll').oneOf('choice', ['yes', 'no', 'abstain']);
|
|
579
|
-
* ```
|
|
580
|
-
*/
|
|
581
|
-
oneOf(name, choices) {
|
|
582
|
-
if (choices.length === 0) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdEmptyChoices, [name]);
|
|
583
|
-
return this.add(name, {
|
|
584
|
-
kind: "oneOf",
|
|
585
|
-
choices
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* Add a free short text field. Avoid it where possible. It cannot be packed, which makes it the most
|
|
590
|
-
* expensive field on the wire.
|
|
591
|
-
*
|
|
592
|
-
* @example
|
|
593
|
-
* ```ts
|
|
594
|
-
* new CustomId('note').str('message');
|
|
595
|
-
* ```
|
|
596
|
-
*/
|
|
597
|
-
str(name) {
|
|
598
|
-
return this.add(name, { kind: "string" });
|
|
599
|
-
}
|
|
600
|
-
/**
|
|
601
|
-
* Mint a wire string from values. Throws if a value is out of its field's range or the wire is over 100 chars.
|
|
602
|
-
*
|
|
603
|
-
* @param values - One value per field, typed by the chain.
|
|
604
|
-
* @returns The wire string to put on the component's customId.
|
|
605
|
-
*/
|
|
606
|
-
encode(values) {
|
|
607
|
-
const wire = `${this.routeKey}:${encodeBody(this.shape, values)}`;
|
|
608
|
-
if (wire.length > MAX_WIRE_LENGTH) throw new _seedcord_errors_internal.SeedcordRangeError(_seedcord_errors.SeedcordErrorCode.CustomIdWireTooLong, [wire.length]);
|
|
609
|
-
return wire;
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Read a wire string back into values.
|
|
613
|
-
*
|
|
614
|
-
* - This will refuse with a default Notice when the shape changed since the wire was minted.
|
|
615
|
-
* - Or refuse with a different default Notice on a corrupt or foreign wire.
|
|
616
|
-
*
|
|
617
|
-
* @param wire - The customId string from the interaction.
|
|
618
|
-
* @returns The decoded values, typed by the chain.
|
|
619
|
-
*/
|
|
620
|
-
decode(wire) {
|
|
621
|
-
const key = routeKeyOf(wire);
|
|
622
|
-
if (key !== this.routeKey) {
|
|
623
|
-
if (prefixOf(wire) === this.prefix) throw new StaleCustomId(this.prefix);
|
|
624
|
-
throw new InvalidCustomId(`routeKey ${JSON.stringify(key)} is not ${JSON.stringify(this.routeKey)}`);
|
|
625
|
-
}
|
|
626
|
-
return decodeBody(this.shape, wire.slice(key.length + 1));
|
|
627
|
-
}
|
|
628
|
-
/** True if this wire was minted from this customId's prefix, ignoring the shape hash. */
|
|
629
|
-
owns(wire) {
|
|
630
|
-
return prefixOf(wire) === this.prefix;
|
|
631
|
-
}
|
|
632
|
-
};
|
|
633
|
-
/** @internal */
|
|
634
|
-
function decodeFor(defs, wire) {
|
|
635
|
-
const match = defs.find((def) => def.owns(wire));
|
|
636
|
-
if (!match) throw new InvalidCustomId(`no customId owns ${JSON.stringify(routeKeyOf(wire))}`);
|
|
637
|
-
return {
|
|
638
|
-
prefix: match.prefix,
|
|
639
|
-
params: match.decode(wire)
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
//#endregion
|
|
644
|
-
//#region src/customId/routing.ts
|
|
645
|
-
/**
|
|
646
|
-
* route decorators store a handler's customId defs here, so the component base can decode
|
|
647
|
-
* against them at runtime.
|
|
648
|
-
*
|
|
649
|
-
* @internal
|
|
650
|
-
*/
|
|
651
|
-
const ComponentDefsKey = Symbol("seedcord:customId:componentDefs");
|
|
652
|
-
/**
|
|
653
|
-
* throws `CustomIdHandlerRouteMissing` when the class has no stored defs. a drifted or corrupt wire
|
|
654
|
-
* throws `StaleCustomId` or `InvalidCustomId`.
|
|
655
|
-
*
|
|
656
|
-
* @internal
|
|
657
|
-
*/
|
|
658
|
-
function decodeComponentRoute(handlerClass, wire) {
|
|
659
|
-
const defs = Reflect.getMetadata(ComponentDefsKey, handlerClass);
|
|
660
|
-
if (!defs) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdHandlerRouteMissing, [handlerClass.name]);
|
|
661
|
-
return decodeFor(defs, wire);
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
//#endregion
|
|
665
|
-
//#region src/decorators/interactionRoutes.ts
|
|
666
|
-
/** The select menu kinds the select route decorators take. */
|
|
667
|
-
let SelectMenuKind = /* @__PURE__ */ function(SelectMenuKind) {
|
|
668
|
-
SelectMenuKind["String"] = "string";
|
|
669
|
-
SelectMenuKind["User"] = "user";
|
|
670
|
-
SelectMenuKind["Role"] = "role";
|
|
671
|
-
SelectMenuKind["Channel"] = "channel";
|
|
672
|
-
SelectMenuKind["Mentionable"] = "mentionable";
|
|
673
|
-
return SelectMenuKind;
|
|
674
|
-
}({});
|
|
675
|
-
function areRoutes(routes) {
|
|
676
|
-
return Array.isArray(routes) && routes.every((route) => typeof route === "string");
|
|
677
|
-
}
|
|
678
|
-
/**
|
|
679
|
-
* every stored route kind and its route strings on a decorated constructor. the build's manifest
|
|
680
|
-
* emitter reads the same pairs.
|
|
681
|
-
*/
|
|
682
|
-
function interactionRoutesOf(constructor) {
|
|
683
|
-
const pairs = [];
|
|
684
|
-
for (const route of Object.values(require_publishDefault.InteractionRoutes)) {
|
|
685
|
-
const meta = Reflect.getMetadata(require_publishDefault.InteractionRouteKeys[route], constructor);
|
|
686
|
-
if (areRoutes(meta)) pairs.push([route, meta]);
|
|
687
|
-
}
|
|
688
|
-
return pairs;
|
|
689
|
-
}
|
|
690
|
-
function storeInteractionRoute(route, routes, constructor) {
|
|
691
|
-
const key = require_publishDefault.InteractionRouteKeys[route];
|
|
692
|
-
const saved = Reflect.getMetadata(key, constructor);
|
|
693
|
-
const existing = areRoutes(saved) ? saved : [];
|
|
694
|
-
const toStore = typeof routes === "string" ? [routes] : routes;
|
|
695
|
-
Reflect.defineMetadata(key, [...existing, ...toStore], constructor);
|
|
696
|
-
Reflect.defineMetadata(require_publishDefault.InteractionMetadataKey, true, constructor);
|
|
697
|
-
}
|
|
698
|
-
function storeComponentRoute(route, defs, constructor) {
|
|
699
|
-
storeInteractionRoute(route, defs.map((def) => def.prefix), constructor);
|
|
700
|
-
Reflect.defineMetadata(ComponentDefsKey, defs, constructor);
|
|
701
|
-
}
|
|
702
|
-
const SELECT_ROUTES = {
|
|
703
|
-
["string"]: "stringMenu",
|
|
704
|
-
["user"]: "userMenu",
|
|
705
|
-
["role"]: "roleMenu",
|
|
706
|
-
["channel"]: "channelMenu",
|
|
707
|
-
["mentionable"]: "mentionableMenu"
|
|
708
|
-
};
|
|
709
|
-
function selectMenuRouteOf(kind) {
|
|
710
|
-
return SELECT_ROUTES[kind];
|
|
711
|
-
}
|
|
712
|
-
function contextMenuRouteOf(kind) {
|
|
713
|
-
return kind === discord_api_types_v10.ApplicationCommandType.User ? "userContextMenu" : "messageContextMenu";
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
//#endregion
|
|
717
|
-
//#region src/gates/Gate.ts
|
|
718
|
-
/**
|
|
719
|
-
* Builds a {@link Gate} from a check. The check refuses by throwing a Notice or a Silence and passes
|
|
720
|
-
* by returning. The required context is inferred from `ctx`, so annotate it as narrowly as the fields
|
|
721
|
-
* the check reads. No annotation defaults to {@link GateContextBase}, an agnostic gate that fits every
|
|
722
|
-
* handler.
|
|
723
|
-
*
|
|
724
|
-
* @typeParam Name - The gate's name, captured as a literal for mismatch errors.
|
|
725
|
-
* @typeParam Ctx - The context the check reads, inferred from the `ctx` annotation.
|
|
726
|
-
*
|
|
727
|
-
* @param name - The gate's name, used in mismatch errors.
|
|
728
|
-
* @param fn - The check, which refuses by throwing a Notice or a Silence and passes by returning.
|
|
729
|
-
*
|
|
730
|
-
* @see {@link defineEffectGate}
|
|
731
|
-
* @see the `@Gated` decorator from `seedcord`
|
|
732
|
-
*
|
|
733
|
-
* @example
|
|
734
|
-
* ```ts
|
|
735
|
-
* // a gate factory that takes its own option and closes over it
|
|
736
|
-
* function MinRoles(min: number): Gate<GateContextBase, 'MinRoles'> {
|
|
737
|
-
* return defineGate('MinRoles', (ctx) => {
|
|
738
|
-
* if (ctx.memberRoleIds.length < min) throw new NotEnoughRoles(min);
|
|
739
|
-
* });
|
|
740
|
-
* }
|
|
741
|
-
* ```
|
|
742
|
-
*
|
|
743
|
-
* @example
|
|
744
|
-
* ```ts
|
|
745
|
-
* // agnostic gate (no ctx annotation): fits any handler
|
|
746
|
-
* const Owner = defineGate('owner', (ctx) => {
|
|
747
|
-
* if (!ctx.userId) throw new NotOwner();
|
|
748
|
-
* });
|
|
749
|
-
* ```
|
|
750
|
-
*/
|
|
751
|
-
function defineGate(name, fn) {
|
|
752
|
-
return {
|
|
753
|
-
name,
|
|
754
|
-
check: async (ctx) => fn(ctx)
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* Builds an {@link EffectGate} from a `check` and a `commit`. `check` peeks and refuses by throwing, and
|
|
759
|
-
* `commit` applies the side effect, running only once the whole gate set passes so a later refusal never
|
|
760
|
-
* commits. In an `or`, a refusing arm's queued commit is rolled back. This is how {@link Cooldown} peeks
|
|
761
|
-
* in `check` and charges the slot in `commit`.
|
|
762
|
-
*
|
|
763
|
-
* @typeParam Name - The gate's literal name, used to name a mismatch error.
|
|
764
|
-
* @typeParam Ctx - The context both `check` and `commit` read, inferred from the `ctx` annotation.
|
|
765
|
-
*
|
|
766
|
-
* @param name - The gate's name, used in mismatch errors.
|
|
767
|
-
* @param check - Peeks and refuses by throwing, without applying the side effect.
|
|
768
|
-
* @param commit - Applies the side effect, running only after the whole gate set passes.
|
|
769
|
-
*
|
|
770
|
-
* @see {@link defineGate}
|
|
771
|
-
* @see the `@Gated` decorator from `seedcord`
|
|
772
|
-
* @see {@link Cooldown}
|
|
773
|
-
*
|
|
774
|
-
* @example
|
|
775
|
-
* ```ts
|
|
776
|
-
* // an effect-gate factory that takes its own limit and closes over it
|
|
777
|
-
* function UsesPerDay(max: number): EffectGate<GateContextBase, 'UsesPerDay'> {
|
|
778
|
-
* return defineEffectGate(
|
|
779
|
-
* 'UsesPerDay',
|
|
780
|
-
* (ctx) => {
|
|
781
|
-
* // peek and refuse by throwing. do not mutate yet
|
|
782
|
-
* if (usedToday(ctx.userId) >= max) throw new OutOfUsesNotice(max);
|
|
783
|
-
* },
|
|
784
|
-
* (ctx) => {
|
|
785
|
-
* // runs only after the whole gate set passes
|
|
786
|
-
* recordUse(ctx.userId);
|
|
787
|
-
* }
|
|
788
|
-
* );
|
|
789
|
-
* }
|
|
790
|
-
* ```
|
|
791
|
-
*/
|
|
792
|
-
function defineEffectGate(name, check, commit) {
|
|
793
|
-
return {
|
|
794
|
-
name,
|
|
795
|
-
check: async (ctx) => check(ctx),
|
|
796
|
-
commit: async (ctx) => commit(ctx)
|
|
797
|
-
};
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
//#endregion
|
|
801
|
-
//#region src/notices/index.ts
|
|
802
|
-
var GateNotice = class extends Notice {
|
|
803
|
-
render() {
|
|
804
|
-
return { components: [new NoticeCard(this.message).component] };
|
|
805
|
-
}
|
|
806
|
-
};
|
|
807
|
-
var NotOwner = class extends GateNotice {
|
|
808
|
-
constructor(message = "Only the bot owner can use this.") {
|
|
809
|
-
super(message);
|
|
810
|
-
}
|
|
811
|
-
};
|
|
812
|
-
var NotInGuild = class extends GateNotice {
|
|
813
|
-
constructor(message = "This can only be used in a server.") {
|
|
814
|
-
super(message);
|
|
815
|
-
}
|
|
816
|
-
};
|
|
817
|
-
var NotInDm = class extends GateNotice {
|
|
818
|
-
constructor(message = "This can only be used in a direct message.") {
|
|
819
|
-
super(message);
|
|
820
|
-
}
|
|
821
|
-
};
|
|
822
|
-
var OnCooldown = class extends GateNotice {
|
|
823
|
-
resetAt;
|
|
824
|
-
constructor(resetAt, message) {
|
|
825
|
-
super(message ?? `You are doing that too fast. Try again <t:${(0, _seedcord_utils.toEpochSeconds)(resetAt)}:R>.`);
|
|
826
|
-
this.resetAt = resetAt;
|
|
827
|
-
}
|
|
828
|
-
};
|
|
829
|
-
var NotAllowed = class extends Notice {
|
|
830
|
-
constructor() {
|
|
831
|
-
super("not allowed");
|
|
832
|
-
}
|
|
833
|
-
render() {
|
|
834
|
-
return { components: [new NoticeCard("You are not allowed to use this command.").component] };
|
|
835
|
-
}
|
|
836
|
-
};
|
|
837
|
-
var NeedsAny = class extends Notice {
|
|
838
|
-
summaries;
|
|
839
|
-
constructor(summaries) {
|
|
840
|
-
super("not allowed");
|
|
841
|
-
this.summaries = summaries;
|
|
842
|
-
}
|
|
843
|
-
render() {
|
|
844
|
-
const bullets = this.summaries.map((summary) => `• ${summary}`).join("\n");
|
|
845
|
-
return { components: [new NoticeCard(`You need any of:\n${bullets}`).component] };
|
|
846
|
-
}
|
|
847
|
-
};
|
|
848
|
-
var MissingRole = class extends GateNotice {
|
|
849
|
-
constructor(message, roleId) {
|
|
850
|
-
super(message ?? (roleId ? `You need the <@&${roleId}> role to use this.` : "You do not have the required role."));
|
|
851
|
-
}
|
|
852
|
-
};
|
|
853
|
-
var MissingPermissions = class extends Notice {
|
|
854
|
-
subject;
|
|
855
|
-
missingPerms;
|
|
856
|
-
customLead;
|
|
857
|
-
constructor(message, subject, missingPerms) {
|
|
858
|
-
super(message ?? "A required permission is missing.");
|
|
859
|
-
this.subject = subject;
|
|
860
|
-
this.missingPerms = missingPerms;
|
|
861
|
-
this.customLead = message;
|
|
862
|
-
}
|
|
863
|
-
render() {
|
|
864
|
-
const bullets = this.missingPerms.map((perm) => `• ${perm}`).join("\n");
|
|
865
|
-
const lead = this.customLead ?? `${this.subject === null ? "You are" : `${this.subject} is`} missing the following permission entries:`;
|
|
866
|
-
return { components: [new NoticeCard(`${lead}\n\n${bullets}`).component] };
|
|
867
|
-
}
|
|
868
|
-
};
|
|
869
|
-
var HasDangerousPermissions = class extends Notice {
|
|
870
|
-
subject;
|
|
871
|
-
dangerousPerms;
|
|
872
|
-
customLead;
|
|
873
|
-
constructor(message, subject, dangerousPerms) {
|
|
874
|
-
super(message ?? "A dangerous permission is enabled.");
|
|
875
|
-
this.subject = subject;
|
|
876
|
-
this.dangerousPerms = dangerousPerms;
|
|
877
|
-
this.customLead = message;
|
|
878
|
-
}
|
|
879
|
-
render() {
|
|
880
|
-
const bullets = this.dangerousPerms.map((perm) => `• ${perm}`).join("\n");
|
|
881
|
-
const lead = this.customLead ?? `${this.subject} has the following permission entries that must not be enabled:`;
|
|
882
|
-
return { components: [new NoticeCard(`${lead}\n\n${bullets}`).component] };
|
|
883
|
-
}
|
|
884
|
-
};
|
|
885
|
-
|
|
886
|
-
//#endregion
|
|
887
|
-
//#region src/gates/effects.ts
|
|
888
|
-
const commitQueues = /* @__PURE__ */ new WeakMap();
|
|
889
|
-
function isEffectGate(gate) {
|
|
890
|
-
return typeof gate.commit === "function";
|
|
891
|
-
}
|
|
892
|
-
async function runCheck(gate, ctx) {
|
|
893
|
-
await gate.check(ctx);
|
|
894
|
-
if (!isEffectGate(gate)) return;
|
|
895
|
-
let queue = commitQueues.get(ctx);
|
|
896
|
-
if (!queue) {
|
|
897
|
-
queue = [];
|
|
898
|
-
commitQueues.set(ctx, queue);
|
|
899
|
-
}
|
|
900
|
-
queue.push(() => gate.commit(ctx));
|
|
901
|
-
}
|
|
902
|
-
async function runCommits(ctx) {
|
|
903
|
-
const queue = commitQueues.get(ctx);
|
|
904
|
-
if (!queue) return;
|
|
905
|
-
for (const commit of queue) await commit();
|
|
906
|
-
}
|
|
907
|
-
function discardCommits(ctx) {
|
|
908
|
-
commitQueues.delete(ctx);
|
|
909
|
-
}
|
|
910
|
-
function markCommits(ctx) {
|
|
911
|
-
return commitQueues.get(ctx)?.length ?? 0;
|
|
912
|
-
}
|
|
913
|
-
function rollbackCommits(ctx, mark) {
|
|
914
|
-
const queue = commitQueues.get(ctx);
|
|
915
|
-
if (queue && queue.length > mark) queue.length = mark;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
//#endregion
|
|
919
|
-
//#region src/gates/catalog/options.ts
|
|
920
|
-
function pickNotice(options, makeDefault) {
|
|
921
|
-
return options?.notice ?? makeDefault(options?.message);
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
//#endregion
|
|
925
|
-
//#region src/permissions/bits.ts
|
|
926
|
-
const PermissionNames = new Map(Object.entries(discord_api_types_v10.PermissionFlagsBits).map(([key, bit]) => [bit, (0, _seedcord_utils.prettify)(key)]));
|
|
927
|
-
const ADMINISTRATOR = discord_api_types_v10.PermissionFlagsBits.Administrator;
|
|
928
|
-
function nameOf(bit) {
|
|
929
|
-
return PermissionNames.get(bit) ?? String(bit);
|
|
930
|
-
}
|
|
931
|
-
function holds(held, bit) {
|
|
932
|
-
return (held & ADMINISTRATOR) === ADMINISTRATOR || (held & bit) === bit;
|
|
933
|
-
}
|
|
934
|
-
/** @internal */
|
|
935
|
-
function hasAll(held, scope) {
|
|
936
|
-
return scope.every((bit) => holds(held, bit));
|
|
937
|
-
}
|
|
938
|
-
/** @internal only reached once hasAll failed, so the administrator bit is absent */
|
|
939
|
-
function missingNames(held, scope) {
|
|
940
|
-
return scope.reduce((names, bit) => {
|
|
941
|
-
if ((held & bit) !== bit) names.push(nameOf(bit));
|
|
942
|
-
return names;
|
|
943
|
-
}, []);
|
|
944
|
-
}
|
|
945
|
-
/** @internal */
|
|
946
|
-
function presentNames(held, scope) {
|
|
947
|
-
return scope.reduce((names, bit) => {
|
|
948
|
-
if (holds(held, bit)) names.push(nameOf(bit));
|
|
949
|
-
return names;
|
|
950
|
-
}, []);
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
//#endregion
|
|
954
|
-
//#region src/gates/catalog/permissions.ts
|
|
955
|
-
const MEMBER_CHECK = {
|
|
956
|
-
unresolved: "Your server member data could not be resolved. Try again.",
|
|
957
|
-
subject: null
|
|
958
|
-
};
|
|
959
|
-
const BOT_CHECK = {
|
|
960
|
-
unresolved: "The bot's permissions could not be resolved. Try again.",
|
|
961
|
-
subject: "The bot"
|
|
962
|
-
};
|
|
963
|
-
function refusePermissions(held, scope, options, guildId, kind) {
|
|
964
|
-
if (held === null) throw pickNotice(options?.notInGuild, (message) => new NotInGuild(message ?? (guildId ? kind.unresolved : void 0)));
|
|
965
|
-
if (hasAll(held, scope)) return;
|
|
966
|
-
throw pickNotice(options?.missing, (message) => new MissingPermissions(message, kind.subject, missingNames(held, scope)));
|
|
967
|
-
}
|
|
968
|
-
function RequirePermissions(scope, options) {
|
|
969
|
-
if (options?.in === "guild") return defineGate("RequirePermissions", (ctx) => {
|
|
970
|
-
refusePermissions(ctx.memberGuildPermissions, scope, options, ctx.guildId, MEMBER_CHECK);
|
|
971
|
-
});
|
|
972
|
-
return defineGate("RequirePermissions", (ctx) => {
|
|
973
|
-
refusePermissions(ctx.memberPermissions, scope, options, ctx.guildId, MEMBER_CHECK);
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
function RequireBotPermissions(scope, options) {
|
|
977
|
-
if (options?.in === "guild") return defineGate("RequireBotPermissions", (ctx) => {
|
|
978
|
-
refusePermissions(ctx.appGuildPermissions, scope, options, ctx.guildId, BOT_CHECK);
|
|
979
|
-
});
|
|
980
|
-
return defineGate("RequireBotPermissions", (ctx) => {
|
|
981
|
-
refusePermissions(ctx.appPermissions, scope, options, ctx.guildId, BOT_CHECK);
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Requires the caller to hold `roleId`, read from the member's role ids. Refuses outside a guild first,
|
|
986
|
-
* then when the role is missing. Roles are guild-global, so there is no scope dimension.
|
|
987
|
-
*
|
|
988
|
-
* @param roleId - The role snowflake the caller must hold.
|
|
989
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-role one with `missingRole`.
|
|
990
|
-
*
|
|
991
|
-
* @see the `@Gated` decorator from `seedcord`
|
|
992
|
-
*
|
|
993
|
-
* @example
|
|
994
|
-
* ```ts
|
|
995
|
-
* \@Gated(RequireRole('123456789012345678'))
|
|
996
|
-
* \@SlashRoute('vip')
|
|
997
|
-
* class VipHandler extends SlashHandler<'vip'> {
|
|
998
|
-
* async execute() {
|
|
999
|
-
* // ...
|
|
1000
|
-
* }
|
|
1001
|
-
* }
|
|
1002
|
-
* ```
|
|
1003
|
-
*/
|
|
1004
|
-
function RequireRole(roleId, options) {
|
|
1005
|
-
return defineGate("RequireRole", (ctx) => {
|
|
1006
|
-
if (!ctx.guildId) throw pickNotice(options?.notInGuild, (message) => new NotInGuild(message));
|
|
1007
|
-
if (ctx.memberRoleIds.includes(roleId)) return;
|
|
1008
|
-
throw pickNotice(options?.missingRole, (message) => new MissingRole(message, roleId));
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
//#endregion
|
|
1013
|
-
//#region src/stops/Silence.ts
|
|
1014
|
-
/**
|
|
1015
|
-
* Throw to stop a handler with no reply and no report.
|
|
1016
|
-
*
|
|
1017
|
-
* The framework boundary catches `Silence` before {@link Notice}, makes zero Discord calls, and stops.
|
|
1018
|
-
* Ideally you'd only throw this in `EventHandlers` (or `Gates` for those), because it doesn't make sense to
|
|
1019
|
-
* leave the user with no reply for an interaction.
|
|
1020
|
-
*
|
|
1021
|
-
* @example
|
|
1022
|
-
* ```ts
|
|
1023
|
-
* import { Silence } from '@seedcord/gateway';
|
|
1024
|
-
*
|
|
1025
|
-
* // before any reply or defer, drop the interaction with no reply and no report
|
|
1026
|
-
* if (await isBlacklisted(interaction.user.id)) throw new Silence('blacklisted user');
|
|
1027
|
-
* ```
|
|
1028
|
-
*/
|
|
1029
|
-
var Silence = class extends Error {
|
|
1030
|
-
reason;
|
|
1031
|
-
/**
|
|
1032
|
-
* @param reason - Optional note written only to a debug log, never shown to the user or reported.
|
|
1033
|
-
*/
|
|
1034
|
-
constructor(reason) {
|
|
1035
|
-
super(reason ?? "Silence");
|
|
1036
|
-
this.reason = reason;
|
|
1037
|
-
Error.captureStackTrace(this, this.constructor);
|
|
1038
|
-
}
|
|
1039
|
-
};
|
|
1040
|
-
|
|
1041
|
-
//#endregion
|
|
1042
|
-
//#region src/pagination/cursor.ts
|
|
1043
|
-
const PAGE_MAX = 1e6;
|
|
1044
|
-
const SLOT_MAX = 4;
|
|
1045
|
-
/** Build the page cursor for a paginator. */
|
|
1046
|
-
function pageCursor(prefix) {
|
|
1047
|
-
return new CustomId(prefix).int("page", 0, PAGE_MAX).int("slot", 0, SLOT_MAX);
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
//#endregion
|
|
1051
|
-
Object.defineProperty(exports, 'CommandInjector', {
|
|
1052
|
-
enumerable: true,
|
|
1053
|
-
get: function () {
|
|
1054
|
-
return CommandInjector;
|
|
1055
|
-
}
|
|
1056
|
-
});
|
|
1057
|
-
Object.defineProperty(exports, 'Commands', {
|
|
1058
|
-
enumerable: true,
|
|
1059
|
-
get: function () {
|
|
1060
|
-
return Commands;
|
|
1061
|
-
}
|
|
1062
|
-
});
|
|
1063
|
-
Object.defineProperty(exports, 'ComponentDefsKey', {
|
|
1064
|
-
enumerable: true,
|
|
1065
|
-
get: function () {
|
|
1066
|
-
return ComponentDefsKey;
|
|
1067
|
-
}
|
|
1068
|
-
});
|
|
1069
|
-
Object.defineProperty(exports, 'ContextMenus', {
|
|
1070
|
-
enumerable: true,
|
|
1071
|
-
get: function () {
|
|
1072
|
-
return ContextMenus;
|
|
1073
|
-
}
|
|
1074
|
-
});
|
|
1075
|
-
Object.defineProperty(exports, 'CustomId', {
|
|
1076
|
-
enumerable: true,
|
|
1077
|
-
get: function () {
|
|
1078
|
-
return CustomId;
|
|
1079
|
-
}
|
|
1080
|
-
});
|
|
1081
|
-
Object.defineProperty(exports, 'GateNotice', {
|
|
1082
|
-
enumerable: true,
|
|
1083
|
-
get: function () {
|
|
1084
|
-
return GateNotice;
|
|
1085
|
-
}
|
|
1086
|
-
});
|
|
1087
|
-
Object.defineProperty(exports, 'HasDangerousPermissions', {
|
|
1088
|
-
enumerable: true,
|
|
1089
|
-
get: function () {
|
|
1090
|
-
return HasDangerousPermissions;
|
|
1091
|
-
}
|
|
1092
|
-
});
|
|
1093
|
-
Object.defineProperty(exports, 'MissingPermissions', {
|
|
1094
|
-
enumerable: true,
|
|
1095
|
-
get: function () {
|
|
1096
|
-
return MissingPermissions;
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
Object.defineProperty(exports, 'MissingRole', {
|
|
1100
|
-
enumerable: true,
|
|
1101
|
-
get: function () {
|
|
1102
|
-
return MissingRole;
|
|
1103
|
-
}
|
|
1104
|
-
});
|
|
1105
|
-
Object.defineProperty(exports, 'NeedsAny', {
|
|
1106
|
-
enumerable: true,
|
|
1107
|
-
get: function () {
|
|
1108
|
-
return NeedsAny;
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
Object.defineProperty(exports, 'NotAllowed', {
|
|
1112
|
-
enumerable: true,
|
|
1113
|
-
get: function () {
|
|
1114
|
-
return NotAllowed;
|
|
1115
|
-
}
|
|
1116
|
-
});
|
|
1117
|
-
Object.defineProperty(exports, 'NotInDm', {
|
|
1118
|
-
enumerable: true,
|
|
1119
|
-
get: function () {
|
|
1120
|
-
return NotInDm;
|
|
1121
|
-
}
|
|
1122
|
-
});
|
|
1123
|
-
Object.defineProperty(exports, 'NotInGuild', {
|
|
1124
|
-
enumerable: true,
|
|
1125
|
-
get: function () {
|
|
1126
|
-
return NotInGuild;
|
|
1127
|
-
}
|
|
1128
|
-
});
|
|
1129
|
-
Object.defineProperty(exports, 'NotOwner', {
|
|
1130
|
-
enumerable: true,
|
|
1131
|
-
get: function () {
|
|
1132
|
-
return NotOwner;
|
|
1133
|
-
}
|
|
1134
|
-
});
|
|
1135
|
-
Object.defineProperty(exports, 'Notice', {
|
|
1136
|
-
enumerable: true,
|
|
1137
|
-
get: function () {
|
|
1138
|
-
return Notice;
|
|
1139
|
-
}
|
|
1140
|
-
});
|
|
1141
|
-
Object.defineProperty(exports, 'NoticeCard', {
|
|
1142
|
-
enumerable: true,
|
|
1143
|
-
get: function () {
|
|
1144
|
-
return NoticeCard;
|
|
1145
|
-
}
|
|
1146
|
-
});
|
|
1147
|
-
Object.defineProperty(exports, 'OnCooldown', {
|
|
1148
|
-
enumerable: true,
|
|
1149
|
-
get: function () {
|
|
1150
|
-
return OnCooldown;
|
|
1151
|
-
}
|
|
1152
|
-
});
|
|
1153
|
-
Object.defineProperty(exports, 'PAGE_MAX', {
|
|
1154
|
-
enumerable: true,
|
|
1155
|
-
get: function () {
|
|
1156
|
-
return PAGE_MAX;
|
|
1157
|
-
}
|
|
1158
|
-
});
|
|
1159
|
-
Object.defineProperty(exports, 'PermissionNames', {
|
|
1160
|
-
enumerable: true,
|
|
1161
|
-
get: function () {
|
|
1162
|
-
return PermissionNames;
|
|
1163
|
-
}
|
|
1164
|
-
});
|
|
1165
|
-
Object.defineProperty(exports, 'RequireBotPermissions', {
|
|
1166
|
-
enumerable: true,
|
|
1167
|
-
get: function () {
|
|
1168
|
-
return RequireBotPermissions;
|
|
1169
|
-
}
|
|
1170
|
-
});
|
|
1171
|
-
Object.defineProperty(exports, 'RequirePermissions', {
|
|
1172
|
-
enumerable: true,
|
|
1173
|
-
get: function () {
|
|
1174
|
-
return RequirePermissions;
|
|
1175
|
-
}
|
|
1176
|
-
});
|
|
1177
|
-
Object.defineProperty(exports, 'RequireRole', {
|
|
1178
|
-
enumerable: true,
|
|
1179
|
-
get: function () {
|
|
1180
|
-
return RequireRole;
|
|
1181
|
-
}
|
|
1182
|
-
});
|
|
1183
|
-
Object.defineProperty(exports, 'SelectMenuKind', {
|
|
1184
|
-
enumerable: true,
|
|
1185
|
-
get: function () {
|
|
1186
|
-
return SelectMenuKind;
|
|
1187
|
-
}
|
|
1188
|
-
});
|
|
1189
|
-
Object.defineProperty(exports, 'Silence', {
|
|
1190
|
-
enumerable: true,
|
|
1191
|
-
get: function () {
|
|
1192
|
-
return Silence;
|
|
1193
|
-
}
|
|
1194
|
-
});
|
|
1195
|
-
Object.defineProperty(exports, 'accessorStore', {
|
|
1196
|
-
enumerable: true,
|
|
1197
|
-
get: function () {
|
|
1198
|
-
return accessorStore;
|
|
1199
|
-
}
|
|
1200
|
-
});
|
|
1201
|
-
Object.defineProperty(exports, 'areRoutes', {
|
|
1202
|
-
enumerable: true,
|
|
1203
|
-
get: function () {
|
|
1204
|
-
return areRoutes;
|
|
1205
|
-
}
|
|
1206
|
-
});
|
|
1207
|
-
Object.defineProperty(exports, 'clearStore', {
|
|
1208
|
-
enumerable: true,
|
|
1209
|
-
get: function () {
|
|
1210
|
-
return clearStore;
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
1213
|
-
Object.defineProperty(exports, 'contextMenuRouteOf', {
|
|
1214
|
-
enumerable: true,
|
|
1215
|
-
get: function () {
|
|
1216
|
-
return contextMenuRouteOf;
|
|
1217
|
-
}
|
|
1218
|
-
});
|
|
1219
|
-
Object.defineProperty(exports, 'decodeComponentRoute', {
|
|
1220
|
-
enumerable: true,
|
|
1221
|
-
get: function () {
|
|
1222
|
-
return decodeComponentRoute;
|
|
1223
|
-
}
|
|
1224
|
-
});
|
|
1225
|
-
Object.defineProperty(exports, 'decodeFor', {
|
|
1226
|
-
enumerable: true,
|
|
1227
|
-
get: function () {
|
|
1228
|
-
return decodeFor;
|
|
1229
|
-
}
|
|
1230
|
-
});
|
|
1231
|
-
Object.defineProperty(exports, 'defineEffectGate', {
|
|
1232
|
-
enumerable: true,
|
|
1233
|
-
get: function () {
|
|
1234
|
-
return defineEffectGate;
|
|
1235
|
-
}
|
|
1236
|
-
});
|
|
1237
|
-
Object.defineProperty(exports, 'defineGate', {
|
|
1238
|
-
enumerable: true,
|
|
1239
|
-
get: function () {
|
|
1240
|
-
return defineGate;
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1243
|
-
Object.defineProperty(exports, 'discardCommits', {
|
|
1244
|
-
enumerable: true,
|
|
1245
|
-
get: function () {
|
|
1246
|
-
return discardCommits;
|
|
1247
|
-
}
|
|
1248
|
-
});
|
|
1249
|
-
Object.defineProperty(exports, 'guardedAccessor', {
|
|
1250
|
-
enumerable: true,
|
|
1251
|
-
get: function () {
|
|
1252
|
-
return guardedAccessor;
|
|
1253
|
-
}
|
|
1254
|
-
});
|
|
1255
|
-
Object.defineProperty(exports, 'hasAll', {
|
|
1256
|
-
enumerable: true,
|
|
1257
|
-
get: function () {
|
|
1258
|
-
return hasAll;
|
|
1259
|
-
}
|
|
1260
|
-
});
|
|
1261
|
-
Object.defineProperty(exports, 'interactionRoutesOf', {
|
|
1262
|
-
enumerable: true,
|
|
1263
|
-
get: function () {
|
|
1264
|
-
return interactionRoutesOf;
|
|
1265
|
-
}
|
|
1266
|
-
});
|
|
1267
|
-
Object.defineProperty(exports, 'markCommits', {
|
|
1268
|
-
enumerable: true,
|
|
1269
|
-
get: function () {
|
|
1270
|
-
return markCommits;
|
|
1271
|
-
}
|
|
1272
|
-
});
|
|
1273
|
-
Object.defineProperty(exports, 'missingNames', {
|
|
1274
|
-
enumerable: true,
|
|
1275
|
-
get: function () {
|
|
1276
|
-
return missingNames;
|
|
1277
|
-
}
|
|
1278
|
-
});
|
|
1279
|
-
Object.defineProperty(exports, 'pageCursor', {
|
|
1280
|
-
enumerable: true,
|
|
1281
|
-
get: function () {
|
|
1282
|
-
return pageCursor;
|
|
1283
|
-
}
|
|
1284
|
-
});
|
|
1285
|
-
Object.defineProperty(exports, 'pickNotice', {
|
|
1286
|
-
enumerable: true,
|
|
1287
|
-
get: function () {
|
|
1288
|
-
return pickNotice;
|
|
1289
|
-
}
|
|
1290
|
-
});
|
|
1291
|
-
Object.defineProperty(exports, 'prefixOf', {
|
|
1292
|
-
enumerable: true,
|
|
1293
|
-
get: function () {
|
|
1294
|
-
return prefixOf;
|
|
1295
|
-
}
|
|
1296
|
-
});
|
|
1297
|
-
Object.defineProperty(exports, 'presentNames', {
|
|
1298
|
-
enumerable: true,
|
|
1299
|
-
get: function () {
|
|
1300
|
-
return presentNames;
|
|
1301
|
-
}
|
|
1302
|
-
});
|
|
1303
|
-
Object.defineProperty(exports, 'rollbackCommits', {
|
|
1304
|
-
enumerable: true,
|
|
1305
|
-
get: function () {
|
|
1306
|
-
return rollbackCommits;
|
|
1307
|
-
}
|
|
1308
|
-
});
|
|
1309
|
-
Object.defineProperty(exports, 'runCheck', {
|
|
1310
|
-
enumerable: true,
|
|
1311
|
-
get: function () {
|
|
1312
|
-
return runCheck;
|
|
1313
|
-
}
|
|
1314
|
-
});
|
|
1315
|
-
Object.defineProperty(exports, 'runCommits', {
|
|
1316
|
-
enumerable: true,
|
|
1317
|
-
get: function () {
|
|
1318
|
-
return runCommits;
|
|
1319
|
-
}
|
|
1320
|
-
});
|
|
1321
|
-
Object.defineProperty(exports, 'selectMenuRouteOf', {
|
|
1322
|
-
enumerable: true,
|
|
1323
|
-
get: function () {
|
|
1324
|
-
return selectMenuRouteOf;
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
Object.defineProperty(exports, 'storeComponentRoute', {
|
|
1328
|
-
enumerable: true,
|
|
1329
|
-
get: function () {
|
|
1330
|
-
return storeComponentRoute;
|
|
1331
|
-
}
|
|
1332
|
-
});
|
|
1333
|
-
Object.defineProperty(exports, 'storeInteractionRoute', {
|
|
1334
|
-
enumerable: true,
|
|
1335
|
-
get: function () {
|
|
1336
|
-
return storeInteractionRoute;
|
|
1337
|
-
}
|
|
1338
|
-
});
|
|
1339
|
-
//# sourceMappingURL=cursor-DFgJ70_B.cjs.map
|