@seedcord/http 0.1.0-next.2 → 0.1.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/dist/{edge.index-joDL39cK.cjs → edge.index-CweiaQ5R.cjs} +250 -13
- package/dist/edge.index-CweiaQ5R.cjs.map +1 -0
- package/dist/{edge.index-C30OZ55m.d.mts → edge.index-DR0Bjfjq.d.mts} +98 -19
- package/dist/{edge.index-BBRnxxkS.mjs → edge.index-fqANtbsm.mjs} +205 -16
- package/dist/edge.index-fqANtbsm.mjs.map +1 -0
- package/dist/edge.index.cjs +5 -1
- package/dist/edge.index.d.mts +3 -2
- package/dist/edge.index.mjs +2 -2
- package/dist/index.cjs +68 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +15 -8
- package/dist/index.mjs +66 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -8
- package/dist/edge.index-BBRnxxkS.mjs.map +0 -1
- package/dist/edge.index-joDL39cK.cjs.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __exportAll = (all, no_symbols) => {
|
|
7
9
|
let target = {};
|
|
@@ -31,6 +33,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
31
33
|
return to;
|
|
32
34
|
};
|
|
33
35
|
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
36
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
37
|
+
value: mod,
|
|
38
|
+
enumerable: true
|
|
39
|
+
}) : target, mod));
|
|
34
40
|
|
|
35
41
|
//#endregion
|
|
36
42
|
let _seedcord_errors_internal = require("@seedcord/errors/internal");
|
|
@@ -54,11 +60,12 @@ function wireAllowedMentions(mentions) {
|
|
|
54
60
|
};
|
|
55
61
|
}
|
|
56
62
|
function wireAttachments(files) {
|
|
57
|
-
if (!files?.some((file) => file.description)) return null;
|
|
63
|
+
if (!files?.some((file) => file.description ?? file.title)) return null;
|
|
58
64
|
return files.map((file, index) => ({
|
|
59
65
|
id: index,
|
|
60
|
-
|
|
61
|
-
...file.description && { description: file.description }
|
|
66
|
+
filename: file.name,
|
|
67
|
+
...file.description && { description: file.description },
|
|
68
|
+
...file.title && { title: file.title }
|
|
62
69
|
}));
|
|
63
70
|
}
|
|
64
71
|
function callbackData(reply, flags) {
|
|
@@ -143,9 +150,9 @@ var ReplySender = class extends _seedcord_core_internal.BaseReplySender {
|
|
|
143
150
|
});
|
|
144
151
|
}
|
|
145
152
|
rawFiles(files) {
|
|
146
|
-
return files.map((file
|
|
147
|
-
name: file.name
|
|
148
|
-
data: file.
|
|
153
|
+
return files.map((file) => ({
|
|
154
|
+
name: file.name,
|
|
155
|
+
data: file.data
|
|
149
156
|
}));
|
|
150
157
|
}
|
|
151
158
|
createdMessage(result) {
|
|
@@ -177,6 +184,10 @@ function apiFor(rest) {
|
|
|
177
184
|
* @typeParam Event - The repliable interaction type this handler processes
|
|
178
185
|
*/
|
|
179
186
|
var RepliableHandler = class extends _seedcord_core.RepliableHandler {
|
|
187
|
+
/** @internal */
|
|
188
|
+
getEvent() {
|
|
189
|
+
return this.event;
|
|
190
|
+
}
|
|
180
191
|
buildSender(event, core, routeId) {
|
|
181
192
|
return new ReplySender({
|
|
182
193
|
application_id: event.application_id,
|
|
@@ -401,7 +412,7 @@ async function handleRawFault(error, uuid, scope) {
|
|
|
401
412
|
}
|
|
402
413
|
async function handleFault(caught, scope) {
|
|
403
414
|
if (caught instanceof _seedcord_core.Silence) {
|
|
404
|
-
if (caught.reason !== void 0) logger().debug(`Silence: ${caught.reason}`);
|
|
415
|
+
if (caught.reason !== void 0 && (scope.core.config.errors?.logSilences ?? true)) logger().debug(`Silence: ${caught.reason}`);
|
|
405
416
|
return;
|
|
406
417
|
}
|
|
407
418
|
const uuid = crypto.randomUUID();
|
|
@@ -475,8 +486,8 @@ async function loadHandlerCtor(match, payload, core, report) {
|
|
|
475
486
|
}
|
|
476
487
|
/**
|
|
477
488
|
* Runs the pre-ack phase for a matched interaction. Loads the route's handler class, constructs it, and
|
|
478
|
-
* runs its gates
|
|
479
|
-
*
|
|
489
|
+
* runs its gates. The sender posts any refusal. Returns the post-ack execute continuation, or null when a
|
|
490
|
+
* gate refuses or nothing can run.
|
|
480
491
|
*/
|
|
481
492
|
async function dispatchInteraction(args) {
|
|
482
493
|
const { match, payload, core } = args;
|
|
@@ -1056,6 +1067,114 @@ function createSeedcord(config, manifest) {
|
|
|
1056
1067
|
return buildEngine(core, buildRouteMaps(manifest)).handle;
|
|
1057
1068
|
}
|
|
1058
1069
|
|
|
1070
|
+
//#endregion
|
|
1071
|
+
//#region src/applicationId.ts
|
|
1072
|
+
/**
|
|
1073
|
+
* Reads the bot's own application id over REST. A gateway host takes it off the logged-in client, and
|
|
1074
|
+
* an http host has no session to read it from.
|
|
1075
|
+
*
|
|
1076
|
+
* @internal
|
|
1077
|
+
*/
|
|
1078
|
+
async function fetchApplicationId(rest) {
|
|
1079
|
+
try {
|
|
1080
|
+
return (await rest.get(discord_api_types_v10.Routes.currentApplication())).id;
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CoreApplicationUnavailable, { cause: error });
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
//#endregion
|
|
1087
|
+
//#region src/emojis/EmojiInjector.ts
|
|
1088
|
+
var Emoji = class {
|
|
1089
|
+
name;
|
|
1090
|
+
id;
|
|
1091
|
+
animated;
|
|
1092
|
+
constructor(name, id, animated = false) {
|
|
1093
|
+
this.name = name;
|
|
1094
|
+
this.id = id;
|
|
1095
|
+
this.animated = animated;
|
|
1096
|
+
}
|
|
1097
|
+
toString() {
|
|
1098
|
+
return `<${this.animated ? "a" : ""}:${this.name}:${this.id}>`;
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
const emojiStorage = (0, _seedcord_core_internal.accessorStore)();
|
|
1102
|
+
function reasonOf(error) {
|
|
1103
|
+
return Error.isError(error) ? error.message : String(error);
|
|
1104
|
+
}
|
|
1105
|
+
function byName(list) {
|
|
1106
|
+
const map = /* @__PURE__ */ new Map();
|
|
1107
|
+
for (const entry of list) if (entry.name) map.set(entry.name, entry);
|
|
1108
|
+
return map;
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* The bot's resolved emojis, keyed by {@link EmojiMap}. Filled by {@link EmojiInjector} during startup.
|
|
1112
|
+
* A read before that throws.
|
|
1113
|
+
*/
|
|
1114
|
+
const Emojis = (0, _seedcord_core_internal.guardedAccessor)("Emojis", emojiStorage);
|
|
1115
|
+
/**
|
|
1116
|
+
* Resolves the configured emojis over REST at startup.
|
|
1117
|
+
*
|
|
1118
|
+
* @internal
|
|
1119
|
+
*/
|
|
1120
|
+
var EmojiInjector = class {
|
|
1121
|
+
core;
|
|
1122
|
+
applicationId;
|
|
1123
|
+
logger = new _seedcord_logger.Logger("Emojis", { channel: "bot" });
|
|
1124
|
+
constructor(core, applicationId = () => fetchApplicationId(core.rest)) {
|
|
1125
|
+
this.core = core;
|
|
1126
|
+
this.applicationId = applicationId;
|
|
1127
|
+
}
|
|
1128
|
+
async init() {
|
|
1129
|
+
(0, _seedcord_core_internal.clearStore)(emojiStorage);
|
|
1130
|
+
const configured = this.core.config.bot.emojis;
|
|
1131
|
+
if (!configured || Object.keys(configured).length === 0) {
|
|
1132
|
+
this.logger.debug("No emojis configured, skipping emoji injection.");
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
const failures = [];
|
|
1136
|
+
const guilds = /* @__PURE__ */ new Map();
|
|
1137
|
+
let application;
|
|
1138
|
+
for (const [key, value] of Object.entries(configured)) if ((0, _seedcord_core_internal.isEmojiTuple)(value)) await this.resolveTuple(key, value, guilds, failures);
|
|
1139
|
+
else if (typeof value === "string") {
|
|
1140
|
+
application ??= await this.applicationEmojis(failures);
|
|
1141
|
+
this.resolve(key, value, application, failures, "the application");
|
|
1142
|
+
} else failures.push(` - "${key}" has an invalid value (expected a name or [name, guildId])`);
|
|
1143
|
+
if (failures.length > 0) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ConfigEmojiUnresolved, [failures.length, failures.join("\n")]);
|
|
1144
|
+
this.logger.utils.summary("Loaded emojis", { emojis: Object.keys(emojiStorage).length });
|
|
1145
|
+
}
|
|
1146
|
+
async applicationEmojis(failures) {
|
|
1147
|
+
try {
|
|
1148
|
+
const appId = await this.applicationId();
|
|
1149
|
+
return byName((await this.core.rest.get(discord_api_types_v10.Routes.applicationEmojis(appId))).items);
|
|
1150
|
+
} catch (error) {
|
|
1151
|
+
failures.push(` - the application emojis could not be read (${reasonOf(error)})`);
|
|
1152
|
+
return /* @__PURE__ */ new Map();
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
async resolveTuple(key, [name, guildId], guilds, failures) {
|
|
1156
|
+
let guild = guilds.get(guildId);
|
|
1157
|
+
if (!guild) {
|
|
1158
|
+
try {
|
|
1159
|
+
guild = byName(await this.core.rest.get(discord_api_types_v10.Routes.guildEmojis(guildId)));
|
|
1160
|
+
} catch (error) {
|
|
1161
|
+
failures.push(` - "${name}" for "${key}" targets guild ${guildId}, which could not be read (${reasonOf(error)})`);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
guilds.set(guildId, guild);
|
|
1165
|
+
}
|
|
1166
|
+
this.resolve(key, name, guild, failures, `guild ${guildId}`);
|
|
1167
|
+
}
|
|
1168
|
+
resolve(key, name, source, failures, where) {
|
|
1169
|
+
const found = source.get(name);
|
|
1170
|
+
if (!found?.id) {
|
|
1171
|
+
failures.push(` - "${name}" for "${key}" was not found in ${where}`);
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
emojiStorage[key] = new Emoji(name, found.id, found.animated ?? false);
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1059
1178
|
//#endregion
|
|
1060
1179
|
//#region src/handlers/interaction/SlashHandler.ts
|
|
1061
1180
|
/**
|
|
@@ -1236,12 +1355,12 @@ var SelectMenuHandler = class extends ComponentHandler {};
|
|
|
1236
1355
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof ConfigId]`.
|
|
1237
1356
|
*/
|
|
1238
1357
|
var ModalHandler = class extends ComponentHandler {
|
|
1239
|
-
/** Rewrite the message this modal was opened from
|
|
1358
|
+
/** Rewrite the message this modal was opened from. Throws when a command opened the modal. */
|
|
1240
1359
|
update(response) {
|
|
1241
1360
|
this.ensureSourceMessage("update");
|
|
1242
1361
|
return super.update(response);
|
|
1243
1362
|
}
|
|
1244
|
-
/**
|
|
1363
|
+
/** Acknowledge the submit without changing the source message. Throws when a command opened the modal. */
|
|
1245
1364
|
deferUpdate() {
|
|
1246
1365
|
this.ensureSourceMessage("deferUpdate");
|
|
1247
1366
|
return super.deferUpdate();
|
|
@@ -1268,6 +1387,82 @@ var Subscriber = class extends _seedcord_core.Subscriber {};
|
|
|
1268
1387
|
*/
|
|
1269
1388
|
var WebhookLog = class extends _seedcord_core.WebhookLog {};
|
|
1270
1389
|
|
|
1390
|
+
//#endregion
|
|
1391
|
+
//#region src/pagination/Paginator.ts
|
|
1392
|
+
function contextOf(interaction, core) {
|
|
1393
|
+
return {
|
|
1394
|
+
interaction,
|
|
1395
|
+
user: interaction.member?.user ?? interaction.user,
|
|
1396
|
+
guildId: interaction.guild_id ?? null,
|
|
1397
|
+
core
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* A restart-proof paginator. Each nav button's customId encodes its full target page, so clicks are
|
|
1402
|
+
* idempotent and survive a restart. A persistent `@ButtonRoute` on `Handler` dispatches the clicks.
|
|
1403
|
+
*
|
|
1404
|
+
* @typeParam Item - The item type, inferred from the source.
|
|
1405
|
+
* @typeParam Prefix - The route prefix, inferred from `config.prefix`.
|
|
1406
|
+
*
|
|
1407
|
+
* @example
|
|
1408
|
+
* ```ts
|
|
1409
|
+
* export const Bans = new Paginator({
|
|
1410
|
+
* prefix: 'bans',
|
|
1411
|
+
* source: new ArraySource((ctx) => loadBans(ctx.guildId), { perPage: 10 }),
|
|
1412
|
+
* renderItem: (ban) => ban.user.username
|
|
1413
|
+
* });
|
|
1414
|
+
*
|
|
1415
|
+
* \@ButtonRoute(Bans.cursor)
|
|
1416
|
+
* export class BansNav extends Bans.Handler {}
|
|
1417
|
+
* ```
|
|
1418
|
+
*/
|
|
1419
|
+
var Paginator = class extends _seedcord_core.PaginatorBase {
|
|
1420
|
+
/** The nav handler base. Extend it with an empty body and decorate it, `@ButtonRoute(p.cursor)`. */
|
|
1421
|
+
Handler;
|
|
1422
|
+
constructor(config) {
|
|
1423
|
+
super(config);
|
|
1424
|
+
const loadPage = (ctx, n) => this.page(ctx, n);
|
|
1425
|
+
this.Handler = class Nav extends ButtonHandler {
|
|
1426
|
+
async execute() {
|
|
1427
|
+
await this.deferUpdate();
|
|
1428
|
+
const response = await loadPage(contextOf(this.event, this.core), this.params.page);
|
|
1429
|
+
await this.update(response);
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Render page 0 and send it through the handler's sender, which picks reply, edit, or followUp from its
|
|
1435
|
+
* ack state.
|
|
1436
|
+
*
|
|
1437
|
+
* @param handler - The handler starting the paginator, normally `this`.
|
|
1438
|
+
*/
|
|
1439
|
+
async start(handler) {
|
|
1440
|
+
const interaction = handler.getEvent();
|
|
1441
|
+
const response = await this.page(contextOf(interaction, handler.core), 0);
|
|
1442
|
+
return handler.getSender().send(response, { ephemeral: this.config.ephemeral ?? false });
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
|
|
1446
|
+
//#endregion
|
|
1447
|
+
//#region src/pagination/sources.ts
|
|
1448
|
+
/**
|
|
1449
|
+
* A source for a bounded list you can load whole. It loads the full list on every click, then slices the
|
|
1450
|
+
* page, so the real total is known (a real last button, "Page X of Y"). Cache inside your loader if the
|
|
1451
|
+
* load is expensive.
|
|
1452
|
+
*
|
|
1453
|
+
* @typeParam Item - The item type, inferred from the loader's return.
|
|
1454
|
+
*/
|
|
1455
|
+
var ArraySource = class extends _seedcord_core.ArraySource {};
|
|
1456
|
+
/**
|
|
1457
|
+
* A source for a large or unknown-length set you fetch one page at a time (SQL LIMIT/OFFSET, a paged API).
|
|
1458
|
+
* The fetcher receives the page index and the page size and reports whether a next page exists. A cursor
|
|
1459
|
+
* source has no cheap total, so `totalPages` is undefined, the last button is omitted, and the indicator
|
|
1460
|
+
* reads "Page X".
|
|
1461
|
+
*
|
|
1462
|
+
* @typeParam Item - The item type, inferred from the fetcher's slice.
|
|
1463
|
+
*/
|
|
1464
|
+
var CursorSource = class extends _seedcord_core.CursorSource {};
|
|
1465
|
+
|
|
1271
1466
|
//#endregion
|
|
1272
1467
|
//#region src/gates/Gated.ts
|
|
1273
1468
|
/**
|
|
@@ -1312,9 +1507,15 @@ function Gated(...gates) {
|
|
|
1312
1507
|
//#endregion
|
|
1313
1508
|
//#region src/version.ts
|
|
1314
1509
|
/** Package version */
|
|
1315
|
-
const version = "0.1.0
|
|
1510
|
+
const version = "0.1.0";
|
|
1316
1511
|
|
|
1317
1512
|
//#endregion
|
|
1513
|
+
Object.defineProperty(exports, 'ArraySource', {
|
|
1514
|
+
enumerable: true,
|
|
1515
|
+
get: function () {
|
|
1516
|
+
return ArraySource;
|
|
1517
|
+
}
|
|
1518
|
+
});
|
|
1318
1519
|
Object.defineProperty(exports, 'AutocompleteHandler', {
|
|
1319
1520
|
enumerable: true,
|
|
1320
1521
|
get: function () {
|
|
@@ -1339,6 +1540,24 @@ Object.defineProperty(exports, 'ContextMenuHandler', {
|
|
|
1339
1540
|
return ContextMenuHandler;
|
|
1340
1541
|
}
|
|
1341
1542
|
});
|
|
1543
|
+
Object.defineProperty(exports, 'CursorSource', {
|
|
1544
|
+
enumerable: true,
|
|
1545
|
+
get: function () {
|
|
1546
|
+
return CursorSource;
|
|
1547
|
+
}
|
|
1548
|
+
});
|
|
1549
|
+
Object.defineProperty(exports, 'EmojiInjector', {
|
|
1550
|
+
enumerable: true,
|
|
1551
|
+
get: function () {
|
|
1552
|
+
return EmojiInjector;
|
|
1553
|
+
}
|
|
1554
|
+
});
|
|
1555
|
+
Object.defineProperty(exports, 'Emojis', {
|
|
1556
|
+
enumerable: true,
|
|
1557
|
+
get: function () {
|
|
1558
|
+
return Emojis;
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1342
1561
|
Object.defineProperty(exports, 'Gated', {
|
|
1343
1562
|
enumerable: true,
|
|
1344
1563
|
get: function () {
|
|
@@ -1357,6 +1576,12 @@ Object.defineProperty(exports, 'ModalHandler', {
|
|
|
1357
1576
|
return ModalHandler;
|
|
1358
1577
|
}
|
|
1359
1578
|
});
|
|
1579
|
+
Object.defineProperty(exports, 'Paginator', {
|
|
1580
|
+
enumerable: true,
|
|
1581
|
+
get: function () {
|
|
1582
|
+
return Paginator;
|
|
1583
|
+
}
|
|
1584
|
+
});
|
|
1360
1585
|
Object.defineProperty(exports, 'RepliableHandler', {
|
|
1361
1586
|
enumerable: true,
|
|
1362
1587
|
get: function () {
|
|
@@ -1399,6 +1624,12 @@ Object.defineProperty(exports, '__reExport', {
|
|
|
1399
1624
|
return __reExport;
|
|
1400
1625
|
}
|
|
1401
1626
|
});
|
|
1627
|
+
Object.defineProperty(exports, '__toESM', {
|
|
1628
|
+
enumerable: true,
|
|
1629
|
+
get: function () {
|
|
1630
|
+
return __toESM;
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1402
1633
|
Object.defineProperty(exports, 'buildEngine', {
|
|
1403
1634
|
enumerable: true,
|
|
1404
1635
|
get: function () {
|
|
@@ -1417,10 +1648,16 @@ Object.defineProperty(exports, 'createSeedcord', {
|
|
|
1417
1648
|
return createSeedcord;
|
|
1418
1649
|
}
|
|
1419
1650
|
});
|
|
1651
|
+
Object.defineProperty(exports, 'fetchApplicationId', {
|
|
1652
|
+
enumerable: true,
|
|
1653
|
+
get: function () {
|
|
1654
|
+
return fetchApplicationId;
|
|
1655
|
+
}
|
|
1656
|
+
});
|
|
1420
1657
|
Object.defineProperty(exports, 'version', {
|
|
1421
1658
|
enumerable: true,
|
|
1422
1659
|
get: function () {
|
|
1423
1660
|
return version;
|
|
1424
1661
|
}
|
|
1425
1662
|
});
|
|
1426
|
-
//# sourceMappingURL=edge.index-
|
|
1663
|
+
//# sourceMappingURL=edge.index-CweiaQ5R.cjs.map
|