@seedcord/core 0.1.0-next.4 → 0.1.0-next.6
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/{CustomId--QizzBOn.d.mts → AutocompleteOptions-eKhIe6Qt.d.mts} +496 -163
- package/dist/Plugin-C2-VHrsX.cjs +114 -0
- package/dist/Plugin-C2-VHrsX.cjs.map +1 -0
- package/dist/Plugin-CNyRKDHT.d.mts +226 -0
- package/dist/Plugin-PcdPjAzc.mjs +97 -0
- package/dist/Plugin-PcdPjAzc.mjs.map +1 -0
- package/dist/devChannel-CQU7hq7Q.mjs +14 -0
- package/dist/devChannel-CQU7hq7Q.mjs.map +1 -0
- package/dist/devChannel-CoCmAVDx.cjs +26 -0
- package/dist/devChannel-CoCmAVDx.cjs.map +1 -0
- package/dist/index.cjs +239 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +182 -25
- package/dist/index.mjs +199 -79
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.cjs +463 -57
- package/dist/internal.index.cjs.map +1 -1
- package/dist/internal.index.d.mts +146 -28
- package/dist/internal.index.mjs +415 -29
- package/dist/internal.index.mjs.map +1 -1
- package/dist/is-never-Ddaba1Su.d.mts +58 -0
- package/dist/node-internal.index.cjs +645 -0
- package/dist/node-internal.index.cjs.map +1 -0
- package/dist/node-internal.index.d.cts +1 -0
- package/dist/node-internal.index.d.mts +2352 -0
- package/dist/node-internal.index.mjs +636 -0
- package/dist/node-internal.index.mjs.map +1 -0
- package/dist/{CustomId-DV7daU7r.cjs → permissions-DSW_EZfN.cjs} +448 -89
- package/dist/permissions-DSW_EZfN.cjs.map +1 -0
- package/dist/{CustomId-epJayEGO.mjs → permissions-RVCBhL2n.mjs} +341 -90
- package/dist/permissions-RVCBhL2n.mjs.map +1 -0
- package/dist/phases-BfpAG6w3.mjs +31 -0
- package/dist/phases-BfpAG6w3.mjs.map +1 -0
- package/dist/phases-C_BGNyVo.cjs +43 -0
- package/dist/phases-C_BGNyVo.cjs.map +1 -0
- package/dist/plugin.index.cjs +4 -0
- package/dist/plugin.index.d.cts +1 -0
- package/dist/plugin.index.d.mts +3 -0
- package/dist/plugin.index.mjs +3 -0
- package/package.json +32 -10
- package/dist/CustomId-DV7daU7r.cjs.map +0 -1
- package/dist/CustomId-epJayEGO.mjs.map +0 -1
package/dist/internal.index.cjs
CHANGED
|
@@ -1,51 +1,80 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_rolldown_runtime = require('./rolldown-runtime-C_NdSu1c.cjs');
|
|
3
|
-
const
|
|
4
|
-
|
|
3
|
+
const require_permissions = require('./permissions-DSW_EZfN.cjs');
|
|
4
|
+
const require_devChannel = require('./devChannel-CoCmAVDx.cjs');
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
let _seedcord_errors = require("@seedcord/errors");
|
|
7
|
+
let _seedcord_errors_internal = require("@seedcord/errors/internal");
|
|
8
|
+
let discord_api_types_v10 = require("discord-api-types/v10");
|
|
9
|
+
let _discordjs_builders = require("@discordjs/builders");
|
|
5
10
|
let _seedcord_logger = require("@seedcord/logger");
|
|
11
|
+
let _seedcord_utils = require("@seedcord/utils");
|
|
12
|
+
let envapt = require("envapt");
|
|
6
13
|
let chalk = require("chalk");
|
|
7
14
|
chalk = require_rolldown_runtime.__toESM(chalk, 1);
|
|
8
|
-
let envapt = require("envapt");
|
|
9
15
|
|
|
10
16
|
//#region src/gates/runGates.ts
|
|
11
17
|
function routeIdOf(handlerCtor) {
|
|
12
|
-
for (const [kind, key] of Object.entries(
|
|
18
|
+
for (const [kind, key] of Object.entries(require_permissions.InteractionRouteKeys)) {
|
|
13
19
|
const routes = Reflect.getMetadata(key, handlerCtor);
|
|
14
20
|
if (routes?.length) return `${kind}:${routes.join(",")}`;
|
|
15
21
|
}
|
|
16
22
|
return null;
|
|
17
23
|
}
|
|
24
|
+
async function timedCheck(gate, ctx, observe) {
|
|
25
|
+
const start = performance.now();
|
|
26
|
+
try {
|
|
27
|
+
await require_permissions.runCheck(gate, ctx);
|
|
28
|
+
} finally {
|
|
29
|
+
observe(gate.name, performance.now() - start);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
18
32
|
/**
|
|
19
33
|
* Runs each gate's check in order, so the first refusal propagates to the dispatcher boundary. An effect
|
|
20
|
-
* gate's commit runs once the whole set passes.
|
|
34
|
+
* gate's commit runs once the whole set passes. When `observe` is given, each check is timed and reported,
|
|
35
|
+
* commits excluded.
|
|
21
36
|
*/
|
|
22
|
-
async function runGates(gates, ctx) {
|
|
37
|
+
async function runGates(gates, ctx, observe) {
|
|
23
38
|
try {
|
|
24
|
-
for (const gate of gates) await
|
|
25
|
-
await
|
|
39
|
+
for (const gate of gates) await (observe ? timedCheck(gate, ctx, observe) : require_permissions.runCheck(gate, ctx));
|
|
40
|
+
await require_permissions.runCommits(ctx);
|
|
26
41
|
} finally {
|
|
27
|
-
|
|
42
|
+
require_permissions.discardCommits(ctx);
|
|
28
43
|
}
|
|
29
44
|
}
|
|
30
|
-
async function runHandlerGates(handlerCtor, ctx) {
|
|
31
|
-
const gates = Reflect.getMetadata(
|
|
45
|
+
async function runHandlerGates(handlerCtor, ctx, routeId, observe) {
|
|
46
|
+
const gates = Reflect.getMetadata(require_permissions.GatedMetadataKey, handlerCtor);
|
|
32
47
|
if (!gates) return;
|
|
33
48
|
await runGates(gates, {
|
|
34
49
|
...ctx,
|
|
35
|
-
routeId: routeIdOf(handlerCtor)
|
|
36
|
-
});
|
|
50
|
+
routeId: routeId ?? routeIdOf(handlerCtor)
|
|
51
|
+
}, observe);
|
|
37
52
|
}
|
|
38
53
|
|
|
39
54
|
//#endregion
|
|
40
|
-
//#region src/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function
|
|
44
|
-
|
|
55
|
+
//#region src/gates/slowGate.ts
|
|
56
|
+
const SLOW_GATE_MS = 750;
|
|
57
|
+
let gateLogger;
|
|
58
|
+
function logger() {
|
|
59
|
+
gateLogger ??= new _seedcord_logger.Logger("Gates");
|
|
60
|
+
return gateLogger;
|
|
45
61
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
function slowGateMonitor() {
|
|
63
|
+
if (envapt.Envapter.isProduction) return void 0;
|
|
64
|
+
const readings = [];
|
|
65
|
+
return {
|
|
66
|
+
observe: (name, ms) => readings.push({
|
|
67
|
+
name,
|
|
68
|
+
ms
|
|
69
|
+
}),
|
|
70
|
+
report(routeId) {
|
|
71
|
+
const total = readings.reduce((sum, reading) => sum + reading.ms, 0);
|
|
72
|
+
if (total < SLOW_GATE_MS) return;
|
|
73
|
+
const shares = readings.toSorted((a, b) => b.ms - a.ms).map((reading) => `${_seedcord_logger.paint.sky.bold(reading.name)} ${Math.round(reading.ms)}ms`);
|
|
74
|
+
const headline = `gates${routeId === null ? "" : ` for ${_seedcord_logger.paint.sky.bold(routeId)}`} took ${_seedcord_logger.paint.amber(`${Math.round(total)}ms`)} of the 3s ack budget`;
|
|
75
|
+
logger().utils.block(headline, shares, "warn", (text) => text);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
49
78
|
}
|
|
50
79
|
|
|
51
80
|
//#endregion
|
|
@@ -71,7 +100,7 @@ var HmrManager = class {
|
|
|
71
100
|
init() {
|
|
72
101
|
if (!{}.hot) return;
|
|
73
102
|
const channel = wrapHot({}.hot);
|
|
74
|
-
setDevChannel(channel);
|
|
103
|
+
require_devChannel.setDevChannel(channel);
|
|
75
104
|
if (envapt.Envapter.isDevelopment || envapt.Envapter.isTest) {
|
|
76
105
|
this.logger.info("Enabled");
|
|
77
106
|
channel.on("seedcord:hmr", (payload) => {
|
|
@@ -95,61 +124,438 @@ var HmrManager = class {
|
|
|
95
124
|
try {
|
|
96
125
|
await listener.onHmr(event);
|
|
97
126
|
} catch (error) {
|
|
98
|
-
this.logger.error(`Error handling HMR update in ${chalk.default.bold(listener.name)}: `, error);
|
|
127
|
+
this.logger.error(`Error handling HMR update in ${chalk.default.bold(listener.constructor.name)}: `, error);
|
|
99
128
|
}
|
|
100
129
|
});
|
|
101
130
|
await Promise.all(promises);
|
|
102
131
|
}
|
|
103
132
|
};
|
|
104
133
|
|
|
105
|
-
//#endregion
|
|
106
|
-
//#region src/customId/routing.ts
|
|
107
|
-
/**
|
|
108
|
-
* The route decorators store a handler's customId definitions here so the component base can decode
|
|
109
|
-
* against them at runtime.
|
|
110
|
-
*
|
|
111
|
-
* @internal
|
|
112
|
-
*/
|
|
113
|
-
const ComponentDefsKey = Symbol("seedcord:customId:componentDefs");
|
|
114
|
-
|
|
115
134
|
//#endregion
|
|
116
135
|
//#region src/pagination/cursor.ts
|
|
117
136
|
const PAGE_MAX = 1e6;
|
|
118
137
|
const SLOT_MAX = 4;
|
|
119
138
|
/** Build the page cursor for a paginator. */
|
|
120
139
|
function pageCursor(prefix) {
|
|
121
|
-
return new
|
|
140
|
+
return new require_permissions.CustomId(prefix).int("page", 0, PAGE_MAX).int("slot", 0, SLOT_MAX);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/reply/flags.ts
|
|
145
|
+
/** IsComponentsV2 is unconditional, every framework reply is v2. */
|
|
146
|
+
function sendFlags(opts) {
|
|
147
|
+
let flags = discord_api_types_v10.MessageFlags.IsComponentsV2;
|
|
148
|
+
if (opts?.ephemeral ?? true) flags |= discord_api_types_v10.MessageFlags.Ephemeral;
|
|
149
|
+
if (opts?.silent) flags |= discord_api_types_v10.MessageFlags.SuppressNotifications;
|
|
150
|
+
return flags;
|
|
151
|
+
}
|
|
152
|
+
/** A deferral carries no content, so only Ephemeral applies. */
|
|
153
|
+
function deferFlags(opts) {
|
|
154
|
+
return opts?.ephemeral ?? true ? discord_api_types_v10.MessageFlags.Ephemeral : 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/reply/ackLegality.ts
|
|
159
|
+
const showModalReason = {
|
|
160
|
+
reason: "this interaction was already acknowledged",
|
|
161
|
+
alternative: "showModal() must be the initial response."
|
|
162
|
+
};
|
|
163
|
+
function deferReason(what) {
|
|
164
|
+
return {
|
|
165
|
+
reason: `this interaction was already acknowledged with ${what}`,
|
|
166
|
+
alternative: "A deferral can only be the initial response."
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const ILLEGAL = {
|
|
170
|
+
reply: {
|
|
171
|
+
"deferred-reply": {
|
|
172
|
+
reason: "this interaction was already deferred",
|
|
173
|
+
alternative: "Use edit() to fill the deferred reply or followUp() for a new message."
|
|
174
|
+
},
|
|
175
|
+
"deferred-update": {
|
|
176
|
+
reason: "this interaction was already acknowledged with a deferred update",
|
|
177
|
+
alternative: "Use followUp() for a new message."
|
|
178
|
+
},
|
|
179
|
+
replied: {
|
|
180
|
+
reason: "this interaction was already replied to",
|
|
181
|
+
alternative: "Use followUp() for a new message or edit() to rewrite the reply."
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
defer: {
|
|
185
|
+
"deferred-reply": deferReason("a deferred reply"),
|
|
186
|
+
"deferred-update": deferReason("a deferred update"),
|
|
187
|
+
replied: deferReason("a reply")
|
|
188
|
+
},
|
|
189
|
+
deferUpdate: {
|
|
190
|
+
"deferred-reply": deferReason("a deferred reply"),
|
|
191
|
+
"deferred-update": deferReason("a deferred update"),
|
|
192
|
+
replied: deferReason("a reply")
|
|
193
|
+
},
|
|
194
|
+
update: {
|
|
195
|
+
"deferred-reply": {
|
|
196
|
+
reason: "this interaction was deferred as a reply",
|
|
197
|
+
alternative: "The placeholder is yours via edit(). update() rewrites a source message."
|
|
198
|
+
},
|
|
199
|
+
replied: {
|
|
200
|
+
reason: "this interaction was already replied to",
|
|
201
|
+
alternative: "update() rewrites a source message. Use edit() or followUp() instead."
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
followUp: { unacked: {
|
|
205
|
+
reason: "this interaction has not been acknowledged yet",
|
|
206
|
+
alternative: "Ack first with reply() or defer()."
|
|
207
|
+
} },
|
|
208
|
+
edit: { unacked: {
|
|
209
|
+
reason: "nothing has been sent yet",
|
|
210
|
+
alternative: "Send with reply() or defer() first, then edit() rewrites it."
|
|
211
|
+
} },
|
|
212
|
+
delete: { unacked: {
|
|
213
|
+
reason: "nothing has been sent yet",
|
|
214
|
+
alternative: "Acknowledge first with reply() or defer(), then delete() removes it."
|
|
215
|
+
} },
|
|
216
|
+
showModal: {
|
|
217
|
+
"deferred-reply": showModalReason,
|
|
218
|
+
"deferred-update": showModalReason,
|
|
219
|
+
replied: showModalReason
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const SEND_TARGET = {
|
|
223
|
+
unacked: "reply",
|
|
224
|
+
"deferred-reply": "edit",
|
|
225
|
+
"deferred-update": "followUp",
|
|
226
|
+
replied: "followUp"
|
|
227
|
+
};
|
|
228
|
+
/** Throws before any API call. `ackedBy` becomes the throw cause, its stack points at the first ack. */
|
|
229
|
+
function checkAckLegality(method, state, routeId, ackedBy) {
|
|
230
|
+
if (method === "send") return;
|
|
231
|
+
const illegal = ILLEGAL[method][state];
|
|
232
|
+
if (!illegal) return;
|
|
233
|
+
throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ReplyIllegalAckState, [
|
|
234
|
+
method,
|
|
235
|
+
illegal.reason,
|
|
236
|
+
illegal.alternative,
|
|
237
|
+
routeId
|
|
238
|
+
], { cause: ackedBy });
|
|
239
|
+
}
|
|
240
|
+
function sendTarget(state) {
|
|
241
|
+
return SEND_TARGET[state];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/reply/AckTrace.ts
|
|
246
|
+
/** The first ack's stack, passed as the throw cause so a double-ack points to both lines. */
|
|
247
|
+
var AckTrace = class extends Error {
|
|
248
|
+
constructor(method) {
|
|
249
|
+
super(`${method}() acknowledged this interaction`);
|
|
250
|
+
this.name = "AckTrace";
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/reply/translateSerialization.ts
|
|
256
|
+
const MAX_DEPTH = 8;
|
|
257
|
+
const OPERATOR_WORD = {
|
|
258
|
+
"<=": "at most",
|
|
259
|
+
">=": "at least",
|
|
260
|
+
"<": "fewer than",
|
|
261
|
+
">": "more than"
|
|
262
|
+
};
|
|
263
|
+
const KIND_WORD = {
|
|
264
|
+
string: "a string",
|
|
265
|
+
number: "a number",
|
|
266
|
+
boolean: "a boolean",
|
|
267
|
+
bigint: "a bigint",
|
|
268
|
+
array: "a list",
|
|
269
|
+
tuple: "a list",
|
|
270
|
+
date: "a date",
|
|
271
|
+
object: "an object"
|
|
272
|
+
};
|
|
273
|
+
function asRecord(value) {
|
|
274
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
275
|
+
}
|
|
276
|
+
function firstLine(message) {
|
|
277
|
+
if (typeof message !== "string") return "unknown validation failure";
|
|
278
|
+
return message.split("\n")[0] ?? message;
|
|
279
|
+
}
|
|
280
|
+
const GIVEN_PREVIEW_LIMIT = 40;
|
|
281
|
+
function gotPhrase(given) {
|
|
282
|
+
if (given === void 0) return "nothing";
|
|
283
|
+
if (given === null) return "null";
|
|
284
|
+
if (typeof given === "string") {
|
|
285
|
+
if (given.length === 0) return "an empty string";
|
|
286
|
+
if (given.length > GIVEN_PREVIEW_LIMIT) return `${given.length} characters`;
|
|
287
|
+
return JSON.stringify(given);
|
|
288
|
+
}
|
|
289
|
+
if (Array.isArray(given)) return given.length === 0 ? "an empty list" : `${given.length} items`;
|
|
290
|
+
if (typeof given === "number" || typeof given === "bigint" || typeof given === "boolean") return String(given);
|
|
291
|
+
if (typeof given === "object") return given.constructor?.name ?? "an object";
|
|
292
|
+
return typeof given;
|
|
122
293
|
}
|
|
294
|
+
function needPhrase(expected, given) {
|
|
295
|
+
const bounds = [...expected.matchAll(/expected(\.length)?\s*(<=|>=|<|>)\s*(\d+)/g)];
|
|
296
|
+
if (bounds.length === 0) return null;
|
|
297
|
+
return bounds.map(([, lengthPart, operator, limit]) => {
|
|
298
|
+
const word = OPERATOR_WORD[operator ?? ""] ?? operator ?? "";
|
|
299
|
+
if (!lengthPart) return `${word} ${limit}`;
|
|
300
|
+
const unit = typeof given === "string" ? "character" : "item";
|
|
301
|
+
return `${word} ${limit} ${Number(limit) === 1 ? unit : `${unit}s`}`;
|
|
302
|
+
}).join(" and ");
|
|
303
|
+
}
|
|
304
|
+
function instanceName(expected) {
|
|
305
|
+
if (typeof expected === "function" && expected.name) return expected.name;
|
|
306
|
+
return "specific class instance";
|
|
307
|
+
}
|
|
308
|
+
function describeLeaf(record) {
|
|
309
|
+
if (typeof record.constraint === "string") {
|
|
310
|
+
const need = typeof record.expected === "string" ? needPhrase(record.expected, record.given) : null;
|
|
311
|
+
if (need) return `need ${need}, got ${gotPhrase(record.given)}`;
|
|
312
|
+
return `${firstLine(record.message)}${"given" in record ? ` (got ${gotPhrase(record.given)})` : ""}`;
|
|
313
|
+
}
|
|
314
|
+
if (typeof record.expected === "function") return `need a ${instanceName(record.expected)}, got ${gotPhrase(record.given)}`;
|
|
315
|
+
if (typeof record.validator === "string") {
|
|
316
|
+
const kind = KIND_WORD[record.validator.replace(/^s\./, "").replace(/\(.*$/, "")];
|
|
317
|
+
if (kind) return `need ${kind}, got ${gotPhrase(record.given)}`;
|
|
318
|
+
return `${firstLine(record.message)}, got ${gotPhrase(record.given)}`;
|
|
319
|
+
}
|
|
320
|
+
return firstLine(record.message);
|
|
321
|
+
}
|
|
322
|
+
function describeUnion(branches, depth) {
|
|
323
|
+
const records = [];
|
|
324
|
+
for (const branch of branches) {
|
|
325
|
+
const record = asRecord(branch);
|
|
326
|
+
if (record) records.push(record);
|
|
327
|
+
}
|
|
328
|
+
const bounded = records.find((record) => typeof record.constraint === "string");
|
|
329
|
+
if (bounded) return describeLeaf(bounded);
|
|
330
|
+
const names = [];
|
|
331
|
+
let allInstances = records.length > 0;
|
|
332
|
+
for (const record of records) if (typeof record.expected === "function") names.push(instanceName(record.expected));
|
|
333
|
+
else allInstances = false;
|
|
334
|
+
if (allInstances) return `need a ${[...new Set(names)].join(" or ")}, got ${gotPhrase(records[0]?.given)}`;
|
|
335
|
+
return detailOf(branches[0], depth + 1);
|
|
336
|
+
}
|
|
337
|
+
function detailOf(value, depth) {
|
|
338
|
+
const record = asRecord(value);
|
|
339
|
+
if (!record || depth >= MAX_DEPTH) return firstLine(record?.message);
|
|
340
|
+
if (Array.isArray(record.errors) && record.errors.length > 0) {
|
|
341
|
+
const errors = record.errors;
|
|
342
|
+
const [first] = errors;
|
|
343
|
+
if (Array.isArray(first)) {
|
|
344
|
+
const [key, inner] = first;
|
|
345
|
+
return `${String(key)}: ${detailOf(inner, depth + 1)}`;
|
|
346
|
+
}
|
|
347
|
+
return describeUnion(errors, depth);
|
|
348
|
+
}
|
|
349
|
+
return describeLeaf(record);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Translates a shapeshift throw into an actionable message, keeping the original as `cause`. Any other
|
|
353
|
+
* throw contributes its message as the detail.
|
|
354
|
+
*/
|
|
355
|
+
function translateSerializationError(error, componentClass, index, routeId) {
|
|
356
|
+
const detail = detailOf(error, 0);
|
|
357
|
+
return new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ReplyComponentSerialization, [
|
|
358
|
+
componentClass,
|
|
359
|
+
index,
|
|
360
|
+
detail,
|
|
361
|
+
routeId
|
|
362
|
+
], { cause: error });
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region src/reply/serializeReply.ts
|
|
367
|
+
/** Wraps a string in a TextDisplay component. */
|
|
368
|
+
function serializeReply(response, routeId) {
|
|
369
|
+
if (typeof response === "string") try {
|
|
370
|
+
return { components: [new _discordjs_builders.TextDisplayBuilder().setContent(response).toJSON()] };
|
|
371
|
+
} catch (error) {
|
|
372
|
+
throw translateSerializationError(error, "TextDisplayBuilder", 0, routeId);
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
components: response.components.map((component, index) => {
|
|
376
|
+
try {
|
|
377
|
+
return component.toJSON();
|
|
378
|
+
} catch (error) {
|
|
379
|
+
const name = component.constructor?.name;
|
|
380
|
+
throw translateSerializationError(error, !name || name === "Object" ? "component" : name, index, routeId);
|
|
381
|
+
}
|
|
382
|
+
}),
|
|
383
|
+
...response.allowedMentions && { allowedMentions: response.allowedMentions },
|
|
384
|
+
...response.files && { files: response.files }
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/reply/BaseReplySender.ts
|
|
390
|
+
/**
|
|
391
|
+
* Tracks acknowledgement state and throws a translated `SeedcordError` on an illegal verb before any
|
|
392
|
+
* transport call. Verbs execute the legality check, control the transport wire writer, then update the
|
|
393
|
+
* state and ack trace. Each transport binds `TMessage` to its created-message lens and supplies the
|
|
394
|
+
* writers.
|
|
395
|
+
*/
|
|
396
|
+
var BaseReplySender = class {
|
|
397
|
+
routeId;
|
|
398
|
+
state;
|
|
399
|
+
sent = /* @__PURE__ */ new Set();
|
|
400
|
+
ackedBy;
|
|
401
|
+
constructor(routeId, initialState = "unacked") {
|
|
402
|
+
this.routeId = routeId;
|
|
403
|
+
this.state = initialState;
|
|
404
|
+
}
|
|
405
|
+
async reply(response, opts) {
|
|
406
|
+
this.checkLegality("reply");
|
|
407
|
+
const created = await this.writeReply(response, opts);
|
|
408
|
+
this.transition("reply", "replied");
|
|
409
|
+
return this.remember(this.requireMessage(created, "reply"));
|
|
410
|
+
}
|
|
411
|
+
async defer(opts) {
|
|
412
|
+
this.checkLegality("defer");
|
|
413
|
+
await this.writeDefer(opts);
|
|
414
|
+
this.transition("defer", "deferred-reply");
|
|
415
|
+
}
|
|
416
|
+
async deferUpdate() {
|
|
417
|
+
this.checkLegality("deferUpdate");
|
|
418
|
+
await this.writeDeferUpdate();
|
|
419
|
+
this.transition("deferUpdate", "deferred-update");
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* After a deferUpdate the state stays deferred-update, so the rewrite repeats. The returned message
|
|
423
|
+
* is the source message, editable only through a bare `update` or `edit`. A targeted `edit` or `delete`
|
|
424
|
+
* of it throws the foreign-target error.
|
|
425
|
+
*/
|
|
426
|
+
async update(response) {
|
|
427
|
+
this.checkLegality("update");
|
|
428
|
+
if (this.state === "deferred-update") return await this.editOriginal(response);
|
|
429
|
+
const created = await this.writeUpdate(response);
|
|
430
|
+
this.transition("update", "replied");
|
|
431
|
+
return this.remember(this.requireMessage(created, "update"));
|
|
432
|
+
}
|
|
433
|
+
async followUp(response, opts) {
|
|
434
|
+
this.checkLegality("followUp");
|
|
435
|
+
const created = await this.writeFollowUp(response, opts);
|
|
436
|
+
return this.remember(created);
|
|
437
|
+
}
|
|
438
|
+
async edit(targetOrResponse, maybeResponse) {
|
|
439
|
+
this.checkLegality("edit");
|
|
440
|
+
if (maybeResponse === void 0) return await this.editOriginal(targetOrResponse);
|
|
441
|
+
const target = targetOrResponse;
|
|
442
|
+
if (!this.sent.has(target.id)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ReplyForeignEditTarget, [
|
|
443
|
+
"edit",
|
|
444
|
+
target.id,
|
|
445
|
+
this.routeId
|
|
446
|
+
]);
|
|
447
|
+
return this.remember(await this.writeEditTarget(target.id, maybeResponse));
|
|
448
|
+
}
|
|
449
|
+
async delete(target) {
|
|
450
|
+
this.checkLegality("delete");
|
|
451
|
+
if (target === void 0) {
|
|
452
|
+
await this.writeDeleteOriginal();
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
if (!this.sent.has(target.id)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ReplyForeignEditTarget, [
|
|
456
|
+
"delete",
|
|
457
|
+
target.id,
|
|
458
|
+
this.routeId
|
|
459
|
+
]);
|
|
460
|
+
await this.writeDeleteTarget(target.id);
|
|
461
|
+
this.sent.delete(target.id);
|
|
462
|
+
}
|
|
463
|
+
/** Routes to the verb the current ack state permits. Every state has a route, so the illegal-ack throw is unreachable. */
|
|
464
|
+
async send(response, opts) {
|
|
465
|
+
const target = sendTarget(this.state);
|
|
466
|
+
if (target === "reply") return await this.reply(response, opts);
|
|
467
|
+
if (target === "edit") return await this.edit(response);
|
|
468
|
+
return await this.followUp(response, opts);
|
|
469
|
+
}
|
|
470
|
+
/** Must be the initial response. */
|
|
471
|
+
async showModal(modal) {
|
|
472
|
+
this.checkLegality("showModal");
|
|
473
|
+
this.guardModalSource();
|
|
474
|
+
let data;
|
|
475
|
+
try {
|
|
476
|
+
data = modal.toJSON();
|
|
477
|
+
} catch (error) {
|
|
478
|
+
const name = modal.constructor?.name;
|
|
479
|
+
throw translateSerializationError(error, !name || name === "Object" ? "modal" : name, 0, this.routeId);
|
|
480
|
+
}
|
|
481
|
+
await this.writeModal(data);
|
|
482
|
+
this.transition("showModal", "replied");
|
|
483
|
+
}
|
|
484
|
+
serialize(response) {
|
|
485
|
+
return serializeReply(response, this.routeId);
|
|
486
|
+
}
|
|
487
|
+
remember(created) {
|
|
488
|
+
this.sent.add(created.id);
|
|
489
|
+
return created;
|
|
490
|
+
}
|
|
491
|
+
requireMessage(created, method) {
|
|
492
|
+
if (!created) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ReplyCallbackMissingMessage, [method, this.routeId]);
|
|
493
|
+
return created;
|
|
494
|
+
}
|
|
495
|
+
async editOriginal(response) {
|
|
496
|
+
const edited = await this.writeEditOriginal(response);
|
|
497
|
+
if (this.state !== "deferred-update") this.remember(edited);
|
|
498
|
+
return edited;
|
|
499
|
+
}
|
|
500
|
+
checkLegality(method) {
|
|
501
|
+
checkAckLegality(method, this.state, this.routeId, this.ackedBy);
|
|
502
|
+
}
|
|
503
|
+
transition(method, state) {
|
|
504
|
+
this.state = state;
|
|
505
|
+
this.ackedBy = new AckTrace(method);
|
|
506
|
+
}
|
|
507
|
+
guardModalSource() {}
|
|
508
|
+
};
|
|
123
509
|
|
|
124
510
|
//#endregion
|
|
125
|
-
exports.
|
|
126
|
-
exports.
|
|
127
|
-
exports.
|
|
128
|
-
exports.
|
|
129
|
-
exports.
|
|
511
|
+
exports.AckTrace = AckTrace;
|
|
512
|
+
exports.BaseReplySender = BaseReplySender;
|
|
513
|
+
exports.CommandMetadataKey = require_permissions.CommandMetadataKey;
|
|
514
|
+
exports.ComponentDefsKey = require_permissions.ComponentDefsKey;
|
|
515
|
+
exports.EventMetadataKey = require_permissions.EventMetadataKey;
|
|
516
|
+
exports.GateNotice = require_permissions.GateNotice;
|
|
517
|
+
exports.GatedMetadataKey = require_permissions.GatedMetadataKey;
|
|
130
518
|
exports.HmrManager = HmrManager;
|
|
131
|
-
exports.InteractionMetadataKey =
|
|
132
|
-
exports.InteractionRouteKeys =
|
|
133
|
-
exports.InteractionRoutes =
|
|
134
|
-
exports.MiddlewareMetadataKey =
|
|
135
|
-
exports.
|
|
136
|
-
exports.
|
|
137
|
-
exports.
|
|
138
|
-
exports.
|
|
139
|
-
exports.
|
|
140
|
-
exports.
|
|
141
|
-
exports.
|
|
519
|
+
exports.InteractionMetadataKey = require_permissions.InteractionMetadataKey;
|
|
520
|
+
exports.InteractionRouteKeys = require_permissions.InteractionRouteKeys;
|
|
521
|
+
exports.InteractionRoutes = require_permissions.InteractionRoutes;
|
|
522
|
+
exports.MiddlewareMetadataKey = require_permissions.MiddlewareMetadataKey;
|
|
523
|
+
exports.MissingPermissions = require_permissions.MissingPermissions;
|
|
524
|
+
exports.MissingRole = require_permissions.MissingRole;
|
|
525
|
+
exports.NeedsAny = require_permissions.NeedsAny;
|
|
526
|
+
exports.NotAllowed = require_permissions.NotAllowed;
|
|
527
|
+
exports.NotInDm = require_permissions.NotInDm;
|
|
528
|
+
exports.NotInGuild = require_permissions.NotInGuild;
|
|
529
|
+
exports.NotOwner = require_permissions.NotOwner;
|
|
530
|
+
exports.NoticeCard = require_permissions.NoticeCard;
|
|
531
|
+
exports.OnCooldown = require_permissions.OnCooldown;
|
|
142
532
|
exports.PAGE_MAX = PAGE_MAX;
|
|
143
|
-
exports.
|
|
144
|
-
exports.
|
|
145
|
-
exports.
|
|
533
|
+
exports.PermissionNames = require_permissions.PermissionNames;
|
|
534
|
+
exports.SubscribeMetadataKey = require_permissions.SubscribeMetadataKey;
|
|
535
|
+
exports.WebhookUrlMetadataKey = require_permissions.WebhookUrlMetadataKey;
|
|
536
|
+
exports.areRoutes = require_permissions.areRoutes;
|
|
537
|
+
exports.checkAckLegality = checkAckLegality;
|
|
538
|
+
exports.contextMenuRouteOf = require_permissions.contextMenuRouteOf;
|
|
539
|
+
exports.decodeComponentRoute = require_permissions.decodeComponentRoute;
|
|
540
|
+
exports.decodeFor = require_permissions.decodeFor;
|
|
541
|
+
exports.deferFlags = deferFlags;
|
|
542
|
+
exports.getDevChannel = require_devChannel.getDevChannel;
|
|
543
|
+
exports.interactionRoutesOf = require_permissions.interactionRoutesOf;
|
|
146
544
|
exports.pageCursor = pageCursor;
|
|
147
|
-
exports.pickNotice =
|
|
148
|
-
exports.prefixOf =
|
|
545
|
+
exports.pickNotice = require_permissions.pickNotice;
|
|
546
|
+
exports.prefixOf = require_permissions.prefixOf;
|
|
149
547
|
exports.routeIdOf = routeIdOf;
|
|
150
548
|
exports.runGates = runGates;
|
|
151
549
|
exports.runHandlerGates = runHandlerGates;
|
|
152
|
-
exports.
|
|
153
|
-
exports.
|
|
550
|
+
exports.selectMenuRouteOf = require_permissions.selectMenuRouteOf;
|
|
551
|
+
exports.sendFlags = sendFlags;
|
|
552
|
+
exports.sendTarget = sendTarget;
|
|
553
|
+
exports.serializeReply = serializeReply;
|
|
554
|
+
exports.setBotColor = require_permissions.setBotColor;
|
|
555
|
+
exports.setDevChannel = require_devChannel.setDevChannel;
|
|
556
|
+
exports.slowGateMonitor = slowGateMonitor;
|
|
557
|
+
exports.storeComponentRoute = require_permissions.storeComponentRoute;
|
|
558
|
+
exports.storeInteractionRoute = require_permissions.storeInteractionRoute;
|
|
559
|
+
exports.translateSerializationError = translateSerializationError;
|
|
154
560
|
exports.wrapHot = wrapHot;
|
|
155
561
|
//# sourceMappingURL=internal.index.cjs.map
|