aurival 0.3.0 → 0.5.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 +218 -0
- package/dist/bot.d.ts +4 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js.map +1 -1
- package/dist/caps.d.ts +60 -0
- package/dist/caps.d.ts.map +1 -0
- package/dist/caps.js +59 -0
- package/dist/caps.js.map +1 -0
- package/dist/embeds.d.ts +138 -0
- package/dist/embeds.d.ts.map +1 -0
- package/dist/embeds.js +545 -0
- package/dist/embeds.js.map +1 -0
- package/dist/errors.d.ts +94 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +120 -0
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +55 -9
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +94 -21
- package/dist/events.js.map +1 -1
- package/dist/http.d.ts +3 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +11 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/embeds.js
ADDED
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discord-shaped `Embed` and `Button` builders (AMENDMENT-05, extended by
|
|
3
|
+
* AMENDMENT-06 with a footer icon, a button emoji and the three structured
|
|
4
|
+
* link targets). Mirrors
|
|
5
|
+
* python's builders field for field; the wire shape and every cap sentence
|
|
6
|
+
* are contractual (`caps.ts`) and must not drift between the two SDKs.
|
|
7
|
+
*
|
|
8
|
+
* Two ways in: a builder chain (`new Embed().addField(...)`), validated as
|
|
9
|
+
* each piece is added, or a plain object literal, accepted anywhere a
|
|
10
|
+
* builder is (the way `mentions` already accepts a raw `{ user }`) and
|
|
11
|
+
* validated to the exact same sentences by `serialiseEmbeds`/
|
|
12
|
+
* `serialiseButtons` before it ever reaches the wire — a plain object is
|
|
13
|
+
* never a bypass.
|
|
14
|
+
*
|
|
15
|
+
* Decoding off the wire (`fromJSON`, used by `embedsFromWire`/
|
|
16
|
+
* `buttonsFromWire` in events.ts) is deliberately tolerant and never
|
|
17
|
+
* throws — the caps are an outbound (client -> server) contract, not an
|
|
18
|
+
* inbound one, and a message already stored by the server is assumed valid.
|
|
19
|
+
*/
|
|
20
|
+
import { BUTTON_STYLES, CAP_AUTHOR_URL_WITHOUT_NAME, CAP_BAD_BUTTON_STYLE, CAP_BUTTON_ID_TOO_LONG, CAP_BUTTON_MISSING_LABEL, CAP_DESCRIPTION_TOO_LONG, CAP_DUPLICATE_BUTTON_ID, CAP_EMBED_FOOTER_TEXT_REQUIRED, CAP_EMBED_URL_WITHOUT_TITLE, CAP_IMAGE_URL_NOT_HTTPS, CAP_INVALID_BUTTON_EMOJI, CAP_LABEL_TOO_LONG, CAP_LINK_BUTTON_MISSING_URL, CAP_LINK_URL_NOT_HTTPS, CAP_LINK_URL_TOO_LONG, CAP_TITLE_TOO_LONG, CAP_TOO_MANY_BUTTONS, CAP_TOO_MANY_EMBEDS, CAP_TOO_MANY_FIELDS, CAP_URL_ON_NON_LINK_BUTTON, MAX_BUTTON_EMOJI_RUNES, MAX_BUTTON_ID_LENGTH, MAX_BUTTONS, MAX_DESCRIPTION_LENGTH, MAX_EMBED_FIELDS, MAX_EMBEDS, MAX_LABEL_RUNES, MAX_LINK_URL_RUNES, MAX_TITLE_LENGTH, } from './caps.js';
|
|
21
|
+
function asRecord(value) {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
23
|
+
? value
|
|
24
|
+
: null;
|
|
25
|
+
}
|
|
26
|
+
function asOptionalString(value) {
|
|
27
|
+
return typeof value === 'string' ? value : undefined;
|
|
28
|
+
}
|
|
29
|
+
function graphemeLength(text) {
|
|
30
|
+
return [...text].length;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* AMENDMENT-06 §11 asks every new url field to reuse this helper; §5 asks a
|
|
34
|
+
* link field to answer with the LINK sentence rather than the image one. The
|
|
35
|
+
* sentence is therefore a parameter: one https check, two wordings, and the
|
|
36
|
+
* caller picks the one that tells its author what to fix.
|
|
37
|
+
*/
|
|
38
|
+
function requireHttps(url, sentence = CAP_IMAGE_URL_NOT_HTTPS) {
|
|
39
|
+
if (!url.startsWith('https://'))
|
|
40
|
+
throw new Error(sentence);
|
|
41
|
+
}
|
|
42
|
+
/** https, then the rune bound — runes, not UTF-16 units, matching the server. */
|
|
43
|
+
function requireLinkUrl(url) {
|
|
44
|
+
requireHttps(url, CAP_LINK_URL_NOT_HTTPS);
|
|
45
|
+
if (graphemeLength(url) > MAX_LINK_URL_RUNES)
|
|
46
|
+
throw new Error(CAP_LINK_URL_TOO_LONG);
|
|
47
|
+
}
|
|
48
|
+
const RUNE_ZWJ = 0x200d;
|
|
49
|
+
const RUNE_VARIATION_TEXT = 0xfe0e;
|
|
50
|
+
const RUNE_VARIATION_EMOJI = 0xfe0f;
|
|
51
|
+
const RUNE_KEYCAP = 0x20e3;
|
|
52
|
+
const RUNE_SKIN_TONE_LOW = 0x1f3fb;
|
|
53
|
+
const RUNE_SKIN_TONE_HIGH = 0x1f3ff;
|
|
54
|
+
const RUNE_REGIONAL_LOW = 0x1f1e6;
|
|
55
|
+
const RUNE_REGIONAL_HIGH = 0x1f1ff;
|
|
56
|
+
const RUNE_TAG_LOW = 0xe0020;
|
|
57
|
+
const RUNE_TAG_HIGH = 0xe007f;
|
|
58
|
+
const RUNE_PICTO_BLOCK_LOW = 0x1f000;
|
|
59
|
+
const RUNE_PICTO_BLOCK_HIGH = 0x1faff;
|
|
60
|
+
const RUNE_SYMBOLS_BLOCK_LOW = 0x2600;
|
|
61
|
+
const RUNE_SYMBOLS_BLOCK_HIGH = 0x27bf;
|
|
62
|
+
/**
|
|
63
|
+
* The unicode symbol classes as the server reads them, floored at U+0080 so
|
|
64
|
+
* ASCII punctuation cannot pass: `+`, `<`, `=`, `|` and `~` are all Sm, and a
|
|
65
|
+
* bare `+` in the emoji slot renders as a pill with a plus sign in it. The two
|
|
66
|
+
* block ranges come first because they carry the emoji the classes miss.
|
|
67
|
+
*/
|
|
68
|
+
const SYMBOL_CLASSES = /[\p{So}\p{Sm}]/u;
|
|
69
|
+
function isPictographic(codePoint) {
|
|
70
|
+
if (codePoint < 0x80)
|
|
71
|
+
return false;
|
|
72
|
+
if (codePoint >= RUNE_SYMBOLS_BLOCK_LOW && codePoint <= RUNE_SYMBOLS_BLOCK_HIGH)
|
|
73
|
+
return true;
|
|
74
|
+
if (codePoint >= RUNE_PICTO_BLOCK_LOW && codePoint <= RUNE_PICTO_BLOCK_HIGH)
|
|
75
|
+
return true;
|
|
76
|
+
return SYMBOL_CLASSES.test(String.fromCodePoint(codePoint));
|
|
77
|
+
}
|
|
78
|
+
function isRegionalIndicator(codePoint) {
|
|
79
|
+
return codePoint >= RUNE_REGIONAL_LOW && codePoint <= RUNE_REGIONAL_HIGH;
|
|
80
|
+
}
|
|
81
|
+
function isSkinTone(codePoint) {
|
|
82
|
+
return codePoint >= RUNE_SKIN_TONE_LOW && codePoint <= RUNE_SKIN_TONE_HIGH;
|
|
83
|
+
}
|
|
84
|
+
function isTagChar(codePoint) {
|
|
85
|
+
return codePoint >= RUNE_TAG_LOW && codePoint <= RUNE_TAG_HIGH;
|
|
86
|
+
}
|
|
87
|
+
/** A keycap's base is a digit, `#` or `*` — the only ASCII legal in an emoji. */
|
|
88
|
+
function isKeycapBase(codePoint) {
|
|
89
|
+
return (codePoint >= 0x30 && codePoint <= 0x39) || codePoint === 0x23 || codePoint === 0x2a;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* "Is this exactly one emoji", AMENDMENT-06 §3. This is a rule-for-rule port
|
|
93
|
+
* of the server's `validEmoji` (`backend-go/internal/botapi/emoji.go`), in its
|
|
94
|
+
* order, and the python SDK carries the same port: §3 lets an SDK be looser
|
|
95
|
+
* than the server, but two SDKs that disagree with each other would hand two
|
|
96
|
+
* bot authors two different answers to the same emoji.
|
|
97
|
+
*
|
|
98
|
+
* True grapheme segmentation is deliberately NOT used even though node has
|
|
99
|
+
* `Intl.Segmenter`. The server approximates segmentation from the unicode
|
|
100
|
+
* tables and is a little permissive on purpose; segmenting here would refuse
|
|
101
|
+
* sequences the server accepts, and a refusal a developer cannot act on is the
|
|
102
|
+
* worse failure (R-10).
|
|
103
|
+
*
|
|
104
|
+
* The empty string is refused rather than treated as absent: an absent emoji
|
|
105
|
+
* is the key missing from the button entirely, so a blank one is a value its
|
|
106
|
+
* author meant, and the honest answer to it is no.
|
|
107
|
+
*/
|
|
108
|
+
function isSingleEmoji(value) {
|
|
109
|
+
const runes = [...value].map((char) => char.codePointAt(0) ?? 0);
|
|
110
|
+
const first = runes[0];
|
|
111
|
+
if (first === undefined)
|
|
112
|
+
return false;
|
|
113
|
+
// The outer bound before the runes are looked at individually. A flag is
|
|
114
|
+
// two, a keycap three, and the longest family sequence in common use is
|
|
115
|
+
// seven; anything past the bound is a paste, not an emoji.
|
|
116
|
+
if (runes.length > MAX_BUTTON_EMOJI_RUNES)
|
|
117
|
+
return false;
|
|
118
|
+
// A flag is EXACTLY TWO regional indicators and nothing else. One is half a
|
|
119
|
+
// flag and renders as a letter in a box; four is two flags.
|
|
120
|
+
if (isRegionalIndicator(first)) {
|
|
121
|
+
const second = runes[1];
|
|
122
|
+
return runes.length === 2 && second !== undefined && isRegionalIndicator(second);
|
|
123
|
+
}
|
|
124
|
+
// A keycap's base is the only place an ASCII rune is legal, and only when
|
|
125
|
+
// U+20E3 actually follows. A bare "1" is a digit, not an emoji.
|
|
126
|
+
if (isKeycapBase(first)) {
|
|
127
|
+
if (runes.length === 2)
|
|
128
|
+
return runes[1] === RUNE_KEYCAP;
|
|
129
|
+
if (runes.length === 3) {
|
|
130
|
+
return runes[1] === RUNE_VARIATION_EMOJI && runes[2] === RUNE_KEYCAP;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
if (!isPictographic(first))
|
|
135
|
+
return false;
|
|
136
|
+
// EXACTLY ONE BASE. A later pictographic rune is legal only when the rune
|
|
137
|
+
// before it was a ZWJ, which is what makes a family one emoji and two dice
|
|
138
|
+
// two.
|
|
139
|
+
let prev = first;
|
|
140
|
+
for (const rune of runes.slice(1)) {
|
|
141
|
+
if (rune === RUNE_ZWJ || rune === RUNE_VARIATION_TEXT || rune === RUNE_VARIATION_EMOJI) {
|
|
142
|
+
// A joiner or a variation selector rides along freely.
|
|
143
|
+
}
|
|
144
|
+
else if (isSkinTone(rune) || isTagChar(rune)) {
|
|
145
|
+
// So do skin tones and the tag characters of a subdivision flag.
|
|
146
|
+
}
|
|
147
|
+
else if (isRegionalIndicator(rune)) {
|
|
148
|
+
// Only ever the two-rune flag handled above; glued onto a pictographic
|
|
149
|
+
// base it is a second emoji.
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
else if (isPictographic(rune)) {
|
|
153
|
+
if (prev !== RUNE_ZWJ)
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
prev = rune;
|
|
160
|
+
}
|
|
161
|
+
// A sequence that ends on a joiner is joined to nothing.
|
|
162
|
+
return prev !== RUNE_ZWJ;
|
|
163
|
+
}
|
|
164
|
+
function requireEmoji(emoji) {
|
|
165
|
+
if (!isSingleEmoji(emoji))
|
|
166
|
+
throw new Error(CAP_INVALID_BUTTON_EMOJI);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* `Embed().addField(...)` builder. Every mutation is validated immediately
|
|
170
|
+
* (the cap sentence, thrown as a plain `Error`); `toJSON()` emits the wire
|
|
171
|
+
* shape, omitting absent keys and omitting `fields` when empty.
|
|
172
|
+
*/
|
|
173
|
+
export class Embed {
|
|
174
|
+
title;
|
|
175
|
+
description;
|
|
176
|
+
color;
|
|
177
|
+
url;
|
|
178
|
+
author;
|
|
179
|
+
thumbnail;
|
|
180
|
+
image;
|
|
181
|
+
fields = [];
|
|
182
|
+
footer;
|
|
183
|
+
timestamp;
|
|
184
|
+
#extra = {};
|
|
185
|
+
constructor(init = {}) {
|
|
186
|
+
if (init.title !== undefined) {
|
|
187
|
+
if (init.title.length > MAX_TITLE_LENGTH)
|
|
188
|
+
throw new Error(CAP_TITLE_TOO_LONG);
|
|
189
|
+
this.title = init.title;
|
|
190
|
+
}
|
|
191
|
+
if (init.description !== undefined) {
|
|
192
|
+
if (init.description.length > MAX_DESCRIPTION_LENGTH) {
|
|
193
|
+
throw new Error(CAP_DESCRIPTION_TOO_LONG);
|
|
194
|
+
}
|
|
195
|
+
this.description = init.description;
|
|
196
|
+
}
|
|
197
|
+
if (init.color !== undefined)
|
|
198
|
+
this.color = init.color;
|
|
199
|
+
if (init.url !== undefined) {
|
|
200
|
+
if (this.title === undefined || this.title === '') {
|
|
201
|
+
throw new Error(CAP_EMBED_URL_WITHOUT_TITLE);
|
|
202
|
+
}
|
|
203
|
+
requireLinkUrl(init.url);
|
|
204
|
+
this.url = init.url;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/** Refuses the 7th field on ONE embed — the whole-message cap (summed across embeds) is enforced by `serialiseEmbeds`. */
|
|
208
|
+
addField(name, value, inline = false) {
|
|
209
|
+
if (this.fields.length >= MAX_EMBED_FIELDS)
|
|
210
|
+
throw new Error(CAP_TOO_MANY_FIELDS);
|
|
211
|
+
this.fields.push({ name, value, inline });
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
setAuthor(name, icon, url) {
|
|
215
|
+
if (icon !== undefined)
|
|
216
|
+
requireHttps(icon);
|
|
217
|
+
if (url !== undefined) {
|
|
218
|
+
if (name === '')
|
|
219
|
+
throw new Error(CAP_AUTHOR_URL_WITHOUT_NAME);
|
|
220
|
+
requireLinkUrl(url);
|
|
221
|
+
}
|
|
222
|
+
const author = { name };
|
|
223
|
+
if (icon !== undefined)
|
|
224
|
+
author.icon = icon;
|
|
225
|
+
if (url !== undefined)
|
|
226
|
+
author.url = url;
|
|
227
|
+
this.author = author;
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
setThumbnail(url) {
|
|
231
|
+
requireHttps(url);
|
|
232
|
+
this.thumbnail = { url };
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
setImage(url) {
|
|
236
|
+
requireHttps(url);
|
|
237
|
+
this.image = { url };
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
setFooter(text, icon) {
|
|
241
|
+
if (text === '')
|
|
242
|
+
throw new Error(CAP_EMBED_FOOTER_TEXT_REQUIRED);
|
|
243
|
+
if (icon !== undefined)
|
|
244
|
+
requireHttps(icon);
|
|
245
|
+
const footer = { text };
|
|
246
|
+
if (icon !== undefined)
|
|
247
|
+
footer.icon = icon;
|
|
248
|
+
this.footer = footer;
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
/** A `Date` becomes UTC RFC3339 (`Z`); a string is assumed already in that form. */
|
|
252
|
+
setTimestamp(value) {
|
|
253
|
+
this.timestamp = value instanceof Date ? value.toISOString() : value;
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
toJSON() {
|
|
257
|
+
const out = { ...this.#extra };
|
|
258
|
+
if (this.title !== undefined)
|
|
259
|
+
out['title'] = this.title;
|
|
260
|
+
if (this.description !== undefined)
|
|
261
|
+
out['description'] = this.description;
|
|
262
|
+
if (this.color !== undefined)
|
|
263
|
+
out['color'] = this.color;
|
|
264
|
+
if (this.url !== undefined)
|
|
265
|
+
out['url'] = this.url;
|
|
266
|
+
if (this.author !== undefined)
|
|
267
|
+
out['author'] = this.author;
|
|
268
|
+
if (this.thumbnail !== undefined)
|
|
269
|
+
out['thumbnail'] = this.thumbnail;
|
|
270
|
+
if (this.image !== undefined)
|
|
271
|
+
out['image'] = this.image;
|
|
272
|
+
if (this.fields.length > 0)
|
|
273
|
+
out['fields'] = this.fields;
|
|
274
|
+
if (this.footer !== undefined)
|
|
275
|
+
out['footer'] = this.footer;
|
|
276
|
+
if (this.timestamp !== undefined)
|
|
277
|
+
out['timestamp'] = this.timestamp;
|
|
278
|
+
return out;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Tolerant decode — never throws, never validates. Used both for wire
|
|
282
|
+
* messages (already server-validated) and to normalise a plain object
|
|
283
|
+
* literal before `serialiseEmbeds` validates it for real. Unknown
|
|
284
|
+
* top-level keys are preserved so a round trip is lossless.
|
|
285
|
+
*/
|
|
286
|
+
static fromJSON(data) {
|
|
287
|
+
const record = asRecord(data) ?? {};
|
|
288
|
+
const { title, description, color, url, author, thumbnail, image, fields, footer, timestamp, ...rest } = record;
|
|
289
|
+
const embed = new Embed();
|
|
290
|
+
const titleStr = asOptionalString(title);
|
|
291
|
+
if (titleStr !== undefined)
|
|
292
|
+
embed.title = titleStr;
|
|
293
|
+
const descriptionStr = asOptionalString(description);
|
|
294
|
+
if (descriptionStr !== undefined)
|
|
295
|
+
embed.description = descriptionStr;
|
|
296
|
+
const colorStr = asOptionalString(color);
|
|
297
|
+
if (colorStr !== undefined)
|
|
298
|
+
embed.color = colorStr;
|
|
299
|
+
const urlStr = asOptionalString(url);
|
|
300
|
+
if (urlStr !== undefined)
|
|
301
|
+
embed.url = urlStr;
|
|
302
|
+
const authorRecord = asRecord(author);
|
|
303
|
+
if (authorRecord) {
|
|
304
|
+
const name = asOptionalString(authorRecord['name']) ?? '';
|
|
305
|
+
const icon = asOptionalString(authorRecord['icon']);
|
|
306
|
+
const authorUrl = asOptionalString(authorRecord['url']);
|
|
307
|
+
const decoded = { name };
|
|
308
|
+
if (icon !== undefined)
|
|
309
|
+
decoded.icon = icon;
|
|
310
|
+
if (authorUrl !== undefined)
|
|
311
|
+
decoded.url = authorUrl;
|
|
312
|
+
embed.author = decoded;
|
|
313
|
+
}
|
|
314
|
+
const thumbnailRecord = asRecord(thumbnail);
|
|
315
|
+
const thumbnailUrl = thumbnailRecord ? asOptionalString(thumbnailRecord['url']) : undefined;
|
|
316
|
+
if (thumbnailUrl !== undefined)
|
|
317
|
+
embed.thumbnail = { url: thumbnailUrl };
|
|
318
|
+
const imageRecord = asRecord(image);
|
|
319
|
+
const imageUrl = imageRecord ? asOptionalString(imageRecord['url']) : undefined;
|
|
320
|
+
if (imageUrl !== undefined)
|
|
321
|
+
embed.image = { url: imageUrl };
|
|
322
|
+
// A footer object with no text still lands, as `{ text: '' }`, so the
|
|
323
|
+
// footer-needs-text cap bites on the raw-object path instead of the key
|
|
324
|
+
// vanishing and the mistake going undiscovered.
|
|
325
|
+
const footerRecord = asRecord(footer);
|
|
326
|
+
if (footerRecord) {
|
|
327
|
+
const footerText = asOptionalString(footerRecord['text']) ?? '';
|
|
328
|
+
const footerIcon = asOptionalString(footerRecord['icon']);
|
|
329
|
+
const decoded = { text: footerText };
|
|
330
|
+
if (footerIcon !== undefined)
|
|
331
|
+
decoded.icon = footerIcon;
|
|
332
|
+
embed.footer = decoded;
|
|
333
|
+
}
|
|
334
|
+
const timestampStr = asOptionalString(timestamp);
|
|
335
|
+
if (timestampStr !== undefined)
|
|
336
|
+
embed.timestamp = timestampStr;
|
|
337
|
+
if (Array.isArray(fields)) {
|
|
338
|
+
for (const raw of fields) {
|
|
339
|
+
const fieldRecord = asRecord(raw);
|
|
340
|
+
if (!fieldRecord)
|
|
341
|
+
continue;
|
|
342
|
+
embed.fields.push({
|
|
343
|
+
name: asOptionalString(fieldRecord['name']) ?? '',
|
|
344
|
+
value: asOptionalString(fieldRecord['value']) ?? '',
|
|
345
|
+
inline: fieldRecord['inline'] === true,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
embed.#extra = rest;
|
|
350
|
+
return embed;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/** Every cap `serialiseEmbeds` enforces on one already-decoded `Embed`, whichever path built it. */
|
|
354
|
+
function validateEmbedShape(embed) {
|
|
355
|
+
if (embed.title !== undefined && embed.title.length > MAX_TITLE_LENGTH) {
|
|
356
|
+
throw new Error(CAP_TITLE_TOO_LONG);
|
|
357
|
+
}
|
|
358
|
+
if (embed.description !== undefined && embed.description.length > MAX_DESCRIPTION_LENGTH) {
|
|
359
|
+
throw new Error(CAP_DESCRIPTION_TOO_LONG);
|
|
360
|
+
}
|
|
361
|
+
if (embed.author?.icon !== undefined)
|
|
362
|
+
requireHttps(embed.author.icon);
|
|
363
|
+
if (embed.url !== undefined) {
|
|
364
|
+
if (embed.title === undefined || embed.title === '') {
|
|
365
|
+
throw new Error(CAP_EMBED_URL_WITHOUT_TITLE);
|
|
366
|
+
}
|
|
367
|
+
requireLinkUrl(embed.url);
|
|
368
|
+
}
|
|
369
|
+
if (embed.author?.url !== undefined) {
|
|
370
|
+
if (embed.author.name === '')
|
|
371
|
+
throw new Error(CAP_AUTHOR_URL_WITHOUT_NAME);
|
|
372
|
+
requireLinkUrl(embed.author.url);
|
|
373
|
+
}
|
|
374
|
+
if (embed.footer !== undefined) {
|
|
375
|
+
if (embed.footer.text === '')
|
|
376
|
+
throw new Error(CAP_EMBED_FOOTER_TEXT_REQUIRED);
|
|
377
|
+
if (embed.footer.icon !== undefined)
|
|
378
|
+
requireHttps(embed.footer.icon);
|
|
379
|
+
}
|
|
380
|
+
if (embed.thumbnail !== undefined && !embed.thumbnail.url.startsWith('https://')) {
|
|
381
|
+
throw new Error(CAP_IMAGE_URL_NOT_HTTPS);
|
|
382
|
+
}
|
|
383
|
+
if (embed.image !== undefined && !embed.image.url.startsWith('https://')) {
|
|
384
|
+
throw new Error(CAP_IMAGE_URL_NOT_HTTPS);
|
|
385
|
+
}
|
|
386
|
+
if (embed.fields.length > MAX_EMBED_FIELDS)
|
|
387
|
+
throw new Error(CAP_TOO_MANY_FIELDS);
|
|
388
|
+
}
|
|
389
|
+
function slugify(label) {
|
|
390
|
+
const slug = label
|
|
391
|
+
.toLowerCase()
|
|
392
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
393
|
+
.replace(/^-+|-+$/g, '');
|
|
394
|
+
return slug.length > MAX_BUTTON_ID_LENGTH
|
|
395
|
+
? slug.slice(0, MAX_BUTTON_ID_LENGTH).replace(/-+$/g, '')
|
|
396
|
+
: slug;
|
|
397
|
+
}
|
|
398
|
+
function validateButtonShape(button) {
|
|
399
|
+
// The label goes first: an emoji-only button is a missing label, not an
|
|
400
|
+
// emoji problem, and saying so is what sends its author to the right fix.
|
|
401
|
+
if (button.label === '')
|
|
402
|
+
throw new Error(CAP_BUTTON_MISSING_LABEL);
|
|
403
|
+
if (graphemeLength(button.label) > MAX_LABEL_RUNES)
|
|
404
|
+
throw new Error(CAP_LABEL_TOO_LONG);
|
|
405
|
+
if (button.id.length > MAX_BUTTON_ID_LENGTH)
|
|
406
|
+
throw new Error(CAP_BUTTON_ID_TOO_LONG);
|
|
407
|
+
if (!BUTTON_STYLES.includes(button.style)) {
|
|
408
|
+
throw new Error(CAP_BAD_BUTTON_STYLE);
|
|
409
|
+
}
|
|
410
|
+
if (button.style === 'link') {
|
|
411
|
+
if (button.url === undefined)
|
|
412
|
+
throw new Error(CAP_LINK_BUTTON_MISSING_URL);
|
|
413
|
+
}
|
|
414
|
+
else if (button.url !== undefined) {
|
|
415
|
+
throw new Error(CAP_URL_ON_NON_LINK_BUTTON);
|
|
416
|
+
}
|
|
417
|
+
if (button.url !== undefined)
|
|
418
|
+
requireLinkUrl(button.url);
|
|
419
|
+
// The emoji never counts toward the label cap (§3): it is its own field,
|
|
420
|
+
// and folding it in would make one cap mean two things.
|
|
421
|
+
if (button.emoji !== undefined)
|
|
422
|
+
requireEmoji(button.emoji);
|
|
423
|
+
}
|
|
424
|
+
/** `new Button({ label: 'Pacific' })` — `id` defaults to a slug of `label`, `style` defaults to `'primary'`. */
|
|
425
|
+
export class Button {
|
|
426
|
+
label;
|
|
427
|
+
id;
|
|
428
|
+
style;
|
|
429
|
+
emoji;
|
|
430
|
+
url;
|
|
431
|
+
constructor(init) {
|
|
432
|
+
this.label = init.label;
|
|
433
|
+
this.style = init.style ?? 'primary';
|
|
434
|
+
this.id = init.id ?? slugify(init.label);
|
|
435
|
+
if (init.emoji !== undefined)
|
|
436
|
+
this.emoji = init.emoji;
|
|
437
|
+
if (init.url !== undefined)
|
|
438
|
+
this.url = init.url;
|
|
439
|
+
validateButtonShape(this);
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* The sanctioned way to build a link pill (AMENDMENT-06 §11): a url is not
|
|
443
|
+
* optional here, so the shape that raises `a link button needs a url` is
|
|
444
|
+
* one a caller has to go out of their way to write. A tap opens the url on
|
|
445
|
+
* the device and stops — a link button never round-trips as `button.pressed`
|
|
446
|
+
* and never flips the row.
|
|
447
|
+
*/
|
|
448
|
+
static link(init) {
|
|
449
|
+
const build = { label: init.label, style: 'link', url: init.url };
|
|
450
|
+
if (init.id !== undefined)
|
|
451
|
+
build.id = init.id;
|
|
452
|
+
if (init.emoji !== undefined)
|
|
453
|
+
build.emoji = init.emoji;
|
|
454
|
+
return new Button(build);
|
|
455
|
+
}
|
|
456
|
+
toJSON() {
|
|
457
|
+
const out = { id: this.id, label: this.label, style: this.style };
|
|
458
|
+
if (this.emoji !== undefined)
|
|
459
|
+
out['emoji'] = this.emoji;
|
|
460
|
+
if (this.url !== undefined)
|
|
461
|
+
out['url'] = this.url;
|
|
462
|
+
return out;
|
|
463
|
+
}
|
|
464
|
+
/** Tolerant decode — never throws. See `Embed.fromJSON` for why. */
|
|
465
|
+
static fromJSON(data) {
|
|
466
|
+
const record = asRecord(data) ?? {};
|
|
467
|
+
const label = asOptionalString(record['label']) ?? '';
|
|
468
|
+
const id = asOptionalString(record['id']);
|
|
469
|
+
const style = asOptionalString(record['style']);
|
|
470
|
+
const emoji = asOptionalString(record['emoji']);
|
|
471
|
+
const url = asOptionalString(record['url']);
|
|
472
|
+
const button = Object.create(Button.prototype);
|
|
473
|
+
button.label = label;
|
|
474
|
+
button.style = style ?? 'primary';
|
|
475
|
+
button.id = id ?? slugify(label);
|
|
476
|
+
if (emoji !== undefined)
|
|
477
|
+
button.emoji = emoji;
|
|
478
|
+
if (url !== undefined)
|
|
479
|
+
button.url = url;
|
|
480
|
+
return button;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
/** `null` for both an absent key and a JSON `null` — a message's `button_used` is never `undefined`. */
|
|
484
|
+
export function buttonUsedFromWire(value) {
|
|
485
|
+
const record = asRecord(value);
|
|
486
|
+
if (!record)
|
|
487
|
+
return null;
|
|
488
|
+
return {
|
|
489
|
+
button: asOptionalString(record['button']) ?? '',
|
|
490
|
+
user: asOptionalString(record['user']) ?? '',
|
|
491
|
+
at: asOptionalString(record['at']) ?? '',
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
/** `[]` for both an absent key and a JSON `null` — `Message.embeds` is never `null`/`undefined`. */
|
|
495
|
+
export function embedsFromWire(value) {
|
|
496
|
+
if (!Array.isArray(value))
|
|
497
|
+
return [];
|
|
498
|
+
return value.map((entry) => Embed.fromJSON(entry));
|
|
499
|
+
}
|
|
500
|
+
/** `[]` for both an absent key and a JSON `null` — `Message.buttons` is never `null`/`undefined`. */
|
|
501
|
+
export function buttonsFromWire(value) {
|
|
502
|
+
if (!Array.isArray(value))
|
|
503
|
+
return [];
|
|
504
|
+
return value.map((entry) => Button.fromJSON(entry));
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Validates and serialises the `embeds` a caller passed to `send`/`reply`,
|
|
508
|
+
* to shape (a). A plain object literal is decoded (tolerant) then validated
|
|
509
|
+
* exactly as a builder is — never a bypass. `[]` when `embeds` is absent or
|
|
510
|
+
* empty, so the caller omits the key.
|
|
511
|
+
*/
|
|
512
|
+
export function serialiseEmbeds(embeds) {
|
|
513
|
+
if (embeds === undefined || embeds.length === 0)
|
|
514
|
+
return [];
|
|
515
|
+
if (embeds.length > MAX_EMBEDS)
|
|
516
|
+
throw new Error(CAP_TOO_MANY_EMBEDS);
|
|
517
|
+
const normalised = embeds.map((entry) => entry instanceof Embed ? entry : Embed.fromJSON(entry));
|
|
518
|
+
for (const embed of normalised)
|
|
519
|
+
validateEmbedShape(embed);
|
|
520
|
+
const totalFields = normalised.reduce((sum, embed) => sum + embed.fields.length, 0);
|
|
521
|
+
if (totalFields > MAX_EMBED_FIELDS)
|
|
522
|
+
throw new Error(CAP_TOO_MANY_FIELDS);
|
|
523
|
+
return normalised.map((embed) => embed.toJSON());
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Validates and serialises the `buttons` a caller passed to `send`/`reply`.
|
|
527
|
+
* `[]` when `buttons` is absent or empty, so the caller omits the key.
|
|
528
|
+
*/
|
|
529
|
+
export function serialiseButtons(buttons) {
|
|
530
|
+
if (buttons === undefined || buttons.length === 0)
|
|
531
|
+
return [];
|
|
532
|
+
if (buttons.length > MAX_BUTTONS)
|
|
533
|
+
throw new Error(CAP_TOO_MANY_BUTTONS);
|
|
534
|
+
const normalised = buttons.map((entry) => entry instanceof Button ? entry : Button.fromJSON(entry));
|
|
535
|
+
for (const button of normalised)
|
|
536
|
+
validateButtonShape(button);
|
|
537
|
+
const seen = new Set();
|
|
538
|
+
for (const button of normalised) {
|
|
539
|
+
if (seen.has(button.id))
|
|
540
|
+
throw new Error(CAP_DUPLICATE_BUTTON_ID);
|
|
541
|
+
seen.add(button.id);
|
|
542
|
+
}
|
|
543
|
+
return normalised.map((button) => button.toJSON());
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=embeds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeds.js","sourceRoot":"","sources":["../src/embeds.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -132,6 +132,100 @@ export declare class BotPlaygroundOnly extends PermissionDeniedError {
|
|
|
132
132
|
/** `message_not_yours` — 403, `edit()`/`delete()` only work on the bot's own messages. */
|
|
133
133
|
export declare class MessageNotYours extends PermissionDeniedError {
|
|
134
134
|
}
|
|
135
|
+
/** `too_many_embeds` — a message carries more than `MAX_EMBEDS` embeds. */
|
|
136
|
+
export declare class TooManyEmbeds extends InvalidRequestError {
|
|
137
|
+
}
|
|
138
|
+
/** `too_many_embed_fields` — one embed carries more than `MAX_EMBED_FIELDS` fields. */
|
|
139
|
+
export declare class TooManyEmbedFields extends InvalidRequestError {
|
|
140
|
+
}
|
|
141
|
+
/** `too_many_buttons` — a message carries more than `MAX_BUTTONS` buttons. */
|
|
142
|
+
export declare class TooManyButtons extends InvalidRequestError {
|
|
143
|
+
}
|
|
144
|
+
/** `button_missing_field` — a button is missing a field it needs to be rendered or pressed. */
|
|
145
|
+
export declare class ButtonMissingField extends InvalidRequestError {
|
|
146
|
+
}
|
|
147
|
+
/** `button_id_too_long` — a button id is longer than `MAX_BUTTON_ID_LENGTH`. */
|
|
148
|
+
export declare class ButtonIDTooLong extends InvalidRequestError {
|
|
149
|
+
}
|
|
150
|
+
/** `duplicate_button_id` — two buttons in the same message share an id. Button ids must be unique within a message. */
|
|
151
|
+
export declare class DuplicateButtonID extends InvalidRequestError {
|
|
152
|
+
}
|
|
153
|
+
/** `button_label_too_long` — a button label is longer than `MAX_LABEL_RUNES`. */
|
|
154
|
+
export declare class ButtonLabelTooLong extends InvalidRequestError {
|
|
155
|
+
}
|
|
156
|
+
/** `link_button_not_supported` — link-style buttons are not supported in v1. */
|
|
157
|
+
export declare class LinkButtonNotSupported extends InvalidRequestError {
|
|
158
|
+
}
|
|
159
|
+
/** `invalid_button_style` — a button's style is not one of `BUTTON_STYLES`. */
|
|
160
|
+
export declare class InvalidButtonStyle extends InvalidRequestError {
|
|
161
|
+
}
|
|
162
|
+
/** `embed_title_too_long` — an embed title is longer than `MAX_TITLE_LENGTH`. */
|
|
163
|
+
export declare class EmbedTitleTooLong extends InvalidRequestError {
|
|
164
|
+
}
|
|
165
|
+
/** `embed_description_too_long` — an embed description is longer than `MAX_DESCRIPTION_LENGTH`. */
|
|
166
|
+
export declare class EmbedDescriptionTooLong extends InvalidRequestError {
|
|
167
|
+
}
|
|
168
|
+
/** `embed_url_not_https` — an embed image url does not start with `https://`. */
|
|
169
|
+
export declare class EmbedURLNotHTTPS extends InvalidRequestError {
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* `link_url_not_https` — a link target does not start with `https://`.
|
|
173
|
+
* Separate from `EmbedURLNotHTTPS` on purpose: that one says "an image url",
|
|
174
|
+
* and a button target is not an image (AMENDMENT-06 §5).
|
|
175
|
+
*/
|
|
176
|
+
export declare class LinkURLNotHTTPS extends InvalidRequestError {
|
|
177
|
+
}
|
|
178
|
+
/** `link_url_too_long` — a link target is longer than `MAX_LINK_URL_RUNES`. */
|
|
179
|
+
export declare class LinkURLTooLong extends InvalidRequestError {
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* `link_button_missing_url` — a button with style `link` carries no url, so
|
|
183
|
+
* there is nothing for the pill to open.
|
|
184
|
+
*/
|
|
185
|
+
export declare class LinkButtonMissingURL extends InvalidRequestError {
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* `url_on_non_link_button` — only a link button carries a url. Refused rather
|
|
189
|
+
* than ignored, matching the contract's stance that a typo is loud.
|
|
190
|
+
*/
|
|
191
|
+
export declare class URLOnNonLinkButton extends InvalidRequestError {
|
|
192
|
+
}
|
|
193
|
+
/** `invalid_button_emoji` — a button emoji is not a single unicode emoji. */
|
|
194
|
+
export declare class InvalidButtonEmoji extends InvalidRequestError {
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* `embed_url_without_title` — an embed carries a url with no title for the tap
|
|
198
|
+
* to attach to.
|
|
199
|
+
*/
|
|
200
|
+
export declare class EmbedURLWithoutTitle extends InvalidRequestError {
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* `author_url_without_name` — an embed author carries a url with no name for
|
|
204
|
+
* the tap to attach to.
|
|
205
|
+
*/
|
|
206
|
+
export declare class AuthorURLWithoutName extends InvalidRequestError {
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* `embed_footer_text_required` — a footer carries an icon but no text, which
|
|
210
|
+
* would render a floating glyph on a line with nothing to say.
|
|
211
|
+
*/
|
|
212
|
+
export declare class EmbedFooterTextRequired extends InvalidRequestError {
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* `embed_empty` — an embed carries none of a title, a description, a field or
|
|
216
|
+
* a footer. A colour on its own is a coloured rectangle, not a message.
|
|
217
|
+
*/
|
|
218
|
+
export declare class EmbedEmpty extends InvalidRequestError {
|
|
219
|
+
}
|
|
220
|
+
/** `buttons_without_message` — buttons were sent with nothing under them. Send text, embeds, or both alongside them. */
|
|
221
|
+
export declare class ButtonsWithoutMessage extends InvalidRequestError {
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* `button_already_used` — a row of actions is spent once a button on it has
|
|
225
|
+
* been pressed; send a new message for another press.
|
|
226
|
+
*/
|
|
227
|
+
export declare class ButtonAlreadyUsed extends InvalidRequestError {
|
|
228
|
+
}
|
|
135
229
|
export declare class RateLimited extends RateLimitError {
|
|
136
230
|
}
|
|
137
231
|
export declare class PairRateLimited extends RateLimitError {
|