discord-embed-router 0.2.0 → 0.2.3

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/index.mjs CHANGED
@@ -5,6 +5,20 @@ import { match } from "path-to-regexp";
5
5
 
6
6
  // src/consts.ts
7
7
  var ID_PREFIX = "der";
8
+ var METHOD_TO_ENCODING = {
9
+ GET: "G",
10
+ POST: "P",
11
+ PUT: "U",
12
+ PATCH: "A",
13
+ DELETE: "D"
14
+ };
15
+ var ENCODING_TO_METHOD = {
16
+ G: "GET",
17
+ P: "POST",
18
+ U: "PUT",
19
+ A: "PATCH",
20
+ D: "DELETE"
21
+ };
8
22
  var BASE_URL = "discord://embed.router";
9
23
  var PUA_START = 57344;
10
24
  var PUA_END = 63743;
@@ -21,34 +35,38 @@ var pathToString = (path2, checkValidity = true) => {
21
35
 
22
36
  // src/helpers/decodePath.ts
23
37
  import { compile } from "path-to-regexp";
24
- var decodePath = (idPrefix, interaction) => {
38
+ var decodePath = ({
39
+ idPrefix,
40
+ interaction
41
+ }) => {
25
42
  const customId = interaction.customId;
26
43
  if (!customId.startsWith(idPrefix)) return false;
27
44
  if (interaction.isButton()) {
28
- return customId.slice(idPrefix.length);
29
- } else if (interaction.isStringSelectMenu()) {
30
- if (interaction.values.length === 0) return false;
31
- return fillParams(customId.slice(idPrefix.length), {
32
- to: interaction.values[0].split("/").slice(1)
33
- });
34
- } else if (interaction.isChannelSelectMenu()) {
45
+ return parseMethodAndPath(customId.slice(idPrefix.length));
46
+ } else if (interaction.isAnySelectMenu()) {
35
47
  if (interaction.values.length === 0) return false;
36
- return fillParams(customId.slice(idPrefix.length), {
37
- channelId: interaction.values[0]
38
- });
39
- } else if (interaction.isRoleSelectMenu()) {
40
- if (interaction.values.length === 0) return false;
41
- return fillParams(customId.slice(idPrefix.length), {
42
- roleId: interaction.values[0]
43
- });
44
- } else if (interaction.isUserSelectMenu()) {
45
- if (interaction.values.length === 0) return false;
46
- return fillParams(customId.slice(idPrefix.length), {
47
- userId: interaction.values[0]
48
- });
48
+ const res = parseMethodAndPath(customId.slice(idPrefix.length));
49
+ if (!res) return false;
50
+ const { method, path: path2 } = res;
51
+ return {
52
+ method,
53
+ path: fillParams(path2, {
54
+ [interaction.isStringSelectMenu() ? "to" : interaction.isChannelSelectMenu() ? "channelId" : interaction.isRoleSelectMenu() ? "roleId" : "userId"]: interaction.values[0].split("/").slice(1)
55
+ })
56
+ };
49
57
  }
50
58
  return false;
51
59
  };
60
+ var parseMethodAndPath = (pathWithMethod) => {
61
+ const firstSlash = pathWithMethod.indexOf("/");
62
+ if (firstSlash <= 0) return false;
63
+ const method = ENCODING_TO_METHOD[pathWithMethod.slice(0, firstSlash)];
64
+ if (method === void 0) return false;
65
+ return {
66
+ method,
67
+ path: pathWithMethod.slice(firstSlash)
68
+ };
69
+ };
52
70
  var fillParams = (path2, params = {}) => {
53
71
  const url = new URL(path2, BASE_URL);
54
72
  const toPath = compile(url.pathname);
@@ -72,17 +90,17 @@ var fillParams = (path2, params = {}) => {
72
90
  // src/EmbedRouter.ts
73
91
  var EmbedRouter = class _EmbedRouter {
74
92
  // identifier -> embedRouter
75
- static usedIdentifiers = /* @__PURE__ */ new Map();
93
+ static #usedIdentifiers = /* @__PURE__ */ new Map();
76
94
  // Name used to generate prefixes
77
- name = "";
95
+ #name = "";
78
96
  // Prefix for customIds of RouteButtonBuilders
79
- idPrefix;
80
- identifier = "";
97
+ #idPrefix;
98
+ #identifier = "";
81
99
  getIdPrefix() {
82
- return `${this.idPrefix}${this.identifier}`;
100
+ return `${this.#idPrefix}${this.#identifier}`;
83
101
  }
84
102
  // All added routes
85
- routes = [];
103
+ #routes = /* @__PURE__ */ new Map();
86
104
  /**
87
105
  *
88
106
  * @param name the name to give the router. ensures buttons stay connected across restarts
@@ -92,40 +110,50 @@ var EmbedRouter = class _EmbedRouter {
92
110
  name = "",
93
111
  idPrefix = ID_PREFIX
94
112
  } = {}) {
95
- if (_EmbedRouter.usedIdentifiers.size >= PUA_RANGE) {
113
+ if (_EmbedRouter.#usedIdentifiers.size >= PUA_RANGE) {
96
114
  throw new Error(`You can not have more than ${PUA_RANGE} routers`);
97
115
  }
98
116
  if (idPrefix.includes("/")) {
99
117
  throw new Error(`Prefix can't contain "/": ${idPrefix}`);
100
118
  }
101
- this.idPrefix = idPrefix;
102
- this.name = name;
103
- this.updateIdentifier();
119
+ this.#idPrefix = idPrefix;
120
+ this.#name = name;
121
+ this.#updateIdentifier();
104
122
  }
105
- updateIdentifier() {
106
- const hash = createHash("sha256").update(this.name).digest();
123
+ #updateIdentifier() {
124
+ const hash = createHash("sha256").update(this.#name).digest();
107
125
  let raw = hash.readUint32BE(0);
108
126
  let char;
109
127
  const nameCollisions = [];
110
128
  while (true) {
111
129
  const codepoint = PUA_START + raw++ % PUA_RANGE;
112
130
  char = String.fromCodePoint(codepoint);
113
- const collisionRouter = _EmbedRouter.usedIdentifiers.get(char);
131
+ const collisionRouter = _EmbedRouter.#usedIdentifiers.get(char);
114
132
  if (collisionRouter === void 0) break;
115
- if (this.name.length > 0 && collisionRouter.name.length === 0) {
116
- collisionRouter.updateIdentifier();
133
+ if (this.#name.length > 0 && collisionRouter.#name.length === 0) {
134
+ collisionRouter.#updateIdentifier();
117
135
  break;
118
136
  }
119
137
  nameCollisions.push(collisionRouter);
120
138
  }
121
- _EmbedRouter.usedIdentifiers.set(char, this);
122
- if (nameCollisions.length > 0 && this.name.length > 0) {
139
+ _EmbedRouter.#usedIdentifiers.set(char, this);
140
+ if (nameCollisions.length > 0 && this.#name.length > 0) {
123
141
  process.emitWarning(
124
- `EmbedRouter identifier collision for name "${this.name}" with ${nameCollisions.map((c) => `"${c.name}"`).join(", ")}`,
142
+ `EmbedRouter identifier collision for name "${this.#name}" with ${nameCollisions.map((c) => `"${c.#name}"`).join(", ")}`,
125
143
  "EmbedRouterWarning"
126
144
  );
127
145
  }
128
- this.identifier = char;
146
+ this.#identifier = char;
147
+ }
148
+ #addRoute(method, routePath, handler) {
149
+ const methodRoutes = this.#routes.get(method) ?? [];
150
+ methodRoutes.push({
151
+ method,
152
+ path: Array.isArray(routePath) ? routePath : [routePath],
153
+ matchFunction: match(routePath),
154
+ handler
155
+ });
156
+ this.#routes.set(method, methodRoutes);
129
157
  }
130
158
  /**
131
159
  * Registers a path with the router
@@ -134,11 +162,43 @@ var EmbedRouter = class _EmbedRouter {
134
162
  * @param handler function that generates the message when a path is matched
135
163
  */
136
164
  get(routePath, handler) {
137
- this.routes.push({
138
- path: Array.isArray(routePath) ? routePath : [routePath],
139
- matchFunction: match(routePath),
140
- handler
141
- });
165
+ this.#addRoute("GET", routePath, handler);
166
+ }
167
+ /**
168
+ * Registers a path with the router
169
+ *
170
+ * @param routePath path to match with
171
+ * @param handler function that generates the message when a path is matched
172
+ */
173
+ post(routePath, handler) {
174
+ this.#addRoute("POST", routePath, handler);
175
+ }
176
+ /**
177
+ * Registers a path with the router
178
+ *
179
+ * @param routePath path to match with
180
+ * @param handler function that generates the message when a path is matched
181
+ */
182
+ put(routePath, handler) {
183
+ this.#addRoute("PUT", routePath, handler);
184
+ }
185
+ /**
186
+ * Registers a path with the router
187
+ *
188
+ * @param routePath path to match with
189
+ * @param handler function that generates the message when a path is matched
190
+ */
191
+ patch(routePath, handler) {
192
+ this.#addRoute("PATCH", routePath, handler);
193
+ }
194
+ /**
195
+ * Registers a path with the router
196
+ *
197
+ * @param routePath path to match with
198
+ * @param handler function that generates the message when a path is matched
199
+ */
200
+ delete(routePath, handler) {
201
+ this.#addRoute("DELETE", routePath, handler);
142
202
  }
143
203
  /**
144
204
  * Adds a subrouter to the router
@@ -148,11 +208,14 @@ var EmbedRouter = class _EmbedRouter {
148
208
  */
149
209
  use(routePath, embedRouter) {
150
210
  const pathString = pathToString(routePath);
151
- for (const route of embedRouter.routes) {
152
- this.get(
153
- route.path.map((p) => path.posix.join(pathString, pathToString(p))),
154
- route.handler
155
- );
211
+ for (const [method, routes] of embedRouter.#routes) {
212
+ for (const route of routes) {
213
+ this.#addRoute(
214
+ method,
215
+ route.path.map((p) => path.posix.join(pathString, pathToString(p))),
216
+ route.handler
217
+ );
218
+ }
156
219
  }
157
220
  }
158
221
  /**
@@ -161,34 +224,49 @@ var EmbedRouter = class _EmbedRouter {
161
224
  * @param interaction interactions from "interactionCreate" (filter for ButtonInteractions)
162
225
  */
163
226
  async listener(interaction, locals) {
164
- const path2 = decodePath(this.getIdPrefix(), interaction);
165
- if (!path2)
227
+ const res = decodePath({ idPrefix: this.getIdPrefix(), interaction });
228
+ if (!res)
166
229
  throw new Error(`Invalid component found: id ${interaction.customId}`);
167
- this.dispatch(interaction, path2, locals);
230
+ this.dispatch({ interaction, method: res.method, path: res.path, locals });
168
231
  }
169
232
  /**
170
- * Connect or update an interaction message to a path
233
+ * Replies to or editReplies to an interaction based on the route output
171
234
  *
172
235
  * @param interaction interaction to connect to
173
236
  * @param path path to route the interaction to
174
- * @param flags optional discord flags to send with message (only allowed on first reply)
237
+ * @param method method to send to route
238
+ * @param flags discord flags to send with message (optional, only allowed on first reply)
239
+ * @param locals additional info to pass in to page through state.local (optional)
175
240
  */
176
- async dispatch(interaction, path2, locals, flags) {
241
+ async dispatch({
242
+ interaction,
243
+ method = "GET",
244
+ path: path2,
245
+ flags,
246
+ locals
247
+ }) {
177
248
  if (interaction.isAutocomplete())
178
249
  throw new Error("Autocomplete Interactions aren't supported");
179
- const resolvedRoute = this.resolve(pathToString(path2, false));
180
- if (!resolvedRoute)
181
- throw new Error(`No route found for ${pathToString(path2, false)}`);
182
- const routeResponse = await resolvedRoute.handler(interaction, {
183
- ...resolvedRoute.state,
250
+ const routeResponse = await this.#resolve({
251
+ interaction,
252
+ method,
253
+ path: path2,
184
254
  locals
185
255
  });
256
+ if (routeResponse === false)
257
+ throw new Error(`No route found for ${pathToString(path2, false)}`);
186
258
  if (interaction.replied || interaction.deferred) {
187
259
  if (flags)
188
260
  throw new Error(
189
261
  "You can only set flags for interactions that haven't been replied to"
190
262
  );
191
- await interaction.editReply(routeResponse);
263
+ if (routeResponse) await interaction.editReply(routeResponse);
264
+ } else if (!routeResponse) {
265
+ if ("deferUpdate" in interaction) {
266
+ await interaction.deferUpdate();
267
+ } else {
268
+ await interaction.deferReply();
269
+ }
192
270
  } else if ("update" in interaction) {
193
271
  if (flags)
194
272
  throw new Error(
@@ -202,19 +280,31 @@ var EmbedRouter = class _EmbedRouter {
202
280
  });
203
281
  }
204
282
  }
205
- resolve(routePath) {
206
- const url = new URL(routePath, BASE_URL);
207
- for (const route of this.routes) {
283
+ /**
284
+ * Resolves a route to the associated message (DOES NOT UPDATE MESSAGE)
285
+ *
286
+ * @param interaction interaction to connect to
287
+ * @param path path to route the interaction to
288
+ * @param method method to send to route
289
+ * @param locals additional info to pass in to page through state.local (optional)
290
+ * @returns discord message associated with route OR false
291
+ */
292
+ async #resolve({
293
+ interaction,
294
+ method = "GET",
295
+ path: path2,
296
+ locals
297
+ }) {
298
+ const url = new URL(pathToString(path2, false), BASE_URL);
299
+ for (const route of this.#routes.get(method) ?? []) {
208
300
  const result = route.matchFunction(url.pathname);
209
301
  if (result) {
210
- return {
211
- state: {
212
- ...result,
213
- query: url.searchParams,
214
- embedRouter: this
215
- },
216
- handler: route.handler
217
- };
302
+ return await route.handler(interaction, {
303
+ ...result,
304
+ query: url.searchParams,
305
+ embedRouter: this,
306
+ locals
307
+ });
218
308
  }
219
309
  }
220
310
  return false;
@@ -225,19 +315,29 @@ var EmbedRouter = class _EmbedRouter {
225
315
  import { ButtonBuilder } from "discord.js";
226
316
 
227
317
  // src/helpers/encodePath.ts
228
- var encodePath = (idPrefix, path2, query) => {
318
+ var encodePath = ({
319
+ idPrefix,
320
+ method,
321
+ path: path2,
322
+ query
323
+ }) => {
229
324
  const url = new URL(pathToString(path2), BASE_URL);
230
325
  if (query) {
231
326
  for (const [key, value] of new URLSearchParams(query)) {
232
327
  url.searchParams.set(key, value);
233
328
  }
234
329
  }
235
- return `${idPrefix}${url.pathname}${url.search}`;
330
+ return `${idPrefix}${METHOD_TO_ENCODING[method]}${url.pathname}${url.search}`;
331
+ };
332
+
333
+ // src/types/componentBuilders.ts
334
+ var isSetOptions = (u) => {
335
+ return typeof u === "object" && u !== null && (!("method" in u) || "method" in u && typeof u.method === "string" || u.method === void 0) && "path" in u && typeof u.path === "string" && (!("query" in u) || "query" in u && ["object", "string"].includes(typeof u.query) || u.query === void 0);
236
336
  };
237
337
 
238
338
  // src/componentBuilders/RouteButtonBuilder.ts
239
339
  var RouteButtonBuilder = class extends ButtonBuilder {
240
- embedRouter;
340
+ #embedRouter;
241
341
  /**
242
342
  *
243
343
  * @param embedRouter the router you want to route with
@@ -245,7 +345,7 @@ var RouteButtonBuilder = class extends ButtonBuilder {
245
345
  */
246
346
  constructor(embedRouter, data) {
247
347
  super(data);
248
- this.embedRouter = embedRouter;
348
+ this.#embedRouter = embedRouter;
249
349
  }
250
350
  /**
251
351
  * Not supported for RouteButtonBuilder
@@ -265,14 +365,20 @@ var RouteButtonBuilder = class extends ButtonBuilder {
265
365
  setCustomId() {
266
366
  throw new Error("setCustomId is not supported on RouteButtonBuilder");
267
367
  }
268
- /**
269
- * Sets the path to route to when clicked
270
- *
271
- * @param path the path to route to
272
- * @param query any query parameters you want to add
273
- */
274
- setTo(path2, query) {
275
- super.setCustomId(encodePath(this.embedRouter.getIdPrefix(), path2, query));
368
+ setTo(arg) {
369
+ const {
370
+ method = "GET",
371
+ path: path2,
372
+ query
373
+ } = isSetOptions(arg) ? arg : { path: arg };
374
+ super.setCustomId(
375
+ encodePath({
376
+ idPrefix: this.#embedRouter.getIdPrefix(),
377
+ method,
378
+ path: path2,
379
+ query
380
+ })
381
+ );
276
382
  return this;
277
383
  }
278
384
  };
@@ -284,21 +390,8 @@ import {
284
390
  } from "discord.js";
285
391
 
286
392
  // src/componentBuilders/RouteStringMenuOptionBuilder.ts
287
- import {
288
- StringSelectMenuOptionBuilder
289
- } from "discord.js";
393
+ import { StringSelectMenuOptionBuilder } from "discord.js";
290
394
  var RouteStringSelectMenuOptionBuilder = class extends StringSelectMenuOptionBuilder {
291
- /**
292
- *
293
- * @param data the data to construct a component out of
294
- */
295
- constructor(data) {
296
- const stringSelectData = data ? {
297
- ...data,
298
- value: encodePath("", data.to)
299
- } : void 0;
300
- super(stringSelectData);
301
- }
302
395
  /**
303
396
  * Not supported for RouteStringSelectMenuOptionBuilder (use setTo)
304
397
  *
@@ -310,21 +403,27 @@ var RouteStringSelectMenuOptionBuilder = class extends StringSelectMenuOptionBui
310
403
  "setValue is not supported on RouteStringSelectMenuOptionBuilder"
311
404
  );
312
405
  }
313
- /**
314
- * Sets the path to route to when clicked
315
- *
316
- * @param path the path to route to
317
- * @param query any query parameters you want to add
318
- */
319
- setTo(path2, query) {
320
- super.setValue(encodePath("", path2, query));
406
+ setTo(arg) {
407
+ const {
408
+ method = "GET",
409
+ path: path2,
410
+ query
411
+ } = isSetOptions(arg) ? arg : { path: arg };
412
+ super.setValue(
413
+ encodePath({
414
+ idPrefix: "",
415
+ method,
416
+ path: path2,
417
+ query
418
+ })
419
+ );
321
420
  return this;
322
421
  }
323
422
  };
324
423
 
325
424
  // src/componentBuilders/RouteStringSelectMenuBuilder.ts
326
425
  var RouteStringSelectMenuBuilder = class extends StringSelectMenuBuilder {
327
- embedRouter;
426
+ #embedRouter;
328
427
  /**
329
428
  *
330
429
  * @param embedRouter the router you want to route with
@@ -332,15 +431,15 @@ var RouteStringSelectMenuBuilder = class extends StringSelectMenuBuilder {
332
431
  * @param query any query parameters you want to add, :to will be replaced with the selected user's id
333
432
  * @param data the data to construct a component out of
334
433
  */
335
- constructor(embedRouter, path2 = "/*to", query, data) {
434
+ constructor(embedRouter, data) {
336
435
  super(data);
337
- this.embedRouter = embedRouter;
436
+ this.#embedRouter = embedRouter;
338
437
  super.setCustomId(
339
- encodePath(
340
- this.embedRouter.getIdPrefix(),
341
- path2,
342
- new URLSearchParams(query)
343
- )
438
+ encodePath({
439
+ idPrefix: this.#embedRouter.getIdPrefix(),
440
+ method: "GET",
441
+ path: "/*to"
442
+ })
344
443
  );
345
444
  }
346
445
  /**
@@ -404,6 +503,22 @@ var RouteStringSelectMenuBuilder = class extends StringSelectMenuBuilder {
404
503
  );
405
504
  return this;
406
505
  }
506
+ setPattern(arg) {
507
+ const {
508
+ method = "GET",
509
+ path: path2,
510
+ query
511
+ } = isSetOptions(arg) ? arg : { path: arg };
512
+ super.setCustomId(
513
+ encodePath({
514
+ idPrefix: this.#embedRouter.getIdPrefix(),
515
+ method,
516
+ path: path2,
517
+ query
518
+ })
519
+ );
520
+ return this;
521
+ }
407
522
  };
408
523
 
409
524
  // src/componentBuilders/RouteChannelSelectMenuBuilder.ts
@@ -411,18 +526,15 @@ import {
411
526
  ChannelSelectMenuBuilder
412
527
  } from "discord.js";
413
528
  var RouteChannelSelectMenuBuilder = class extends ChannelSelectMenuBuilder {
414
- embedRouter;
529
+ #embedRouter;
415
530
  /**
416
531
  *
417
532
  * @param embedRouter the router you want to route with
418
- * @param path the path to redirect to, :channelId in path will be replaced with the selected user's id
419
- * @param query any query parameters you want to add, :channelId will be replaced with the selected user's id
420
533
  * @param data the data to construct a component out of
421
534
  */
422
- constructor(embedRouter, path2, query, data) {
535
+ constructor(embedRouter, data) {
423
536
  super(data);
424
- this.embedRouter = embedRouter;
425
- super.setCustomId(encodePath(this.embedRouter.getIdPrefix(), path2, query));
537
+ this.#embedRouter = embedRouter;
426
538
  }
427
539
  /**
428
540
  * Not supported for RouteChannelSelectMenuBuilder (customId set from embedRouter)
@@ -435,6 +547,22 @@ var RouteChannelSelectMenuBuilder = class extends ChannelSelectMenuBuilder {
435
547
  "setCustomId is not supported on RouteChannelSelectMenuBuilder"
436
548
  );
437
549
  }
550
+ setPattern(arg) {
551
+ const {
552
+ method = "GET",
553
+ path: path2,
554
+ query
555
+ } = isSetOptions(arg) ? arg : { path: arg };
556
+ super.setCustomId(
557
+ encodePath({
558
+ idPrefix: this.#embedRouter.getIdPrefix(),
559
+ method,
560
+ path: path2,
561
+ query
562
+ })
563
+ );
564
+ return this;
565
+ }
438
566
  };
439
567
 
440
568
  // src/componentBuilders/RouteRoleSelectMenuBuilder.ts
@@ -442,18 +570,15 @@ import {
442
570
  RoleSelectMenuBuilder
443
571
  } from "discord.js";
444
572
  var RouteRoleSelectMenuBuilder = class extends RoleSelectMenuBuilder {
445
- embedRouter;
573
+ #embedRouter;
446
574
  /**
447
575
  *
448
576
  * @param embedRouter the router you want to route with
449
- * @param path the path to redirect to, :roleId in path will be replaced with the selected user's id
450
- * @param query any query parameters you want to add, :roleId will be replaced with the selected user's id
451
577
  * @param data the data to construct a component out of
452
578
  */
453
- constructor(embedRouter, path2, query, data) {
579
+ constructor(embedRouter, data) {
454
580
  super(data);
455
- this.embedRouter = embedRouter;
456
- super.setCustomId(encodePath(this.embedRouter.getIdPrefix(), path2, query));
581
+ this.#embedRouter = embedRouter;
457
582
  }
458
583
  /**
459
584
  * Not supported for RouteRoleSelectMenuBuilder (customId set from embedRouter)
@@ -466,6 +591,22 @@ var RouteRoleSelectMenuBuilder = class extends RoleSelectMenuBuilder {
466
591
  "setCustomId is not supported on RouteRoleSelectMenuBuilder"
467
592
  );
468
593
  }
594
+ setPattern(arg) {
595
+ const {
596
+ method = "GET",
597
+ path: path2,
598
+ query
599
+ } = isSetOptions(arg) ? arg : { path: arg };
600
+ super.setCustomId(
601
+ encodePath({
602
+ idPrefix: this.#embedRouter.getIdPrefix(),
603
+ method,
604
+ path: path2,
605
+ query
606
+ })
607
+ );
608
+ return this;
609
+ }
469
610
  };
470
611
 
471
612
  // src/componentBuilders/RouteUserSelectMenuBuilder.ts
@@ -473,24 +614,15 @@ import {
473
614
  UserSelectMenuBuilder
474
615
  } from "discord.js";
475
616
  var RouteUserSelectMenuBuilder = class extends UserSelectMenuBuilder {
476
- embedRouter;
617
+ #embedRouter;
477
618
  /**
478
619
  *
479
620
  * @param embedRouter the router you want to route with
480
- * @param path the path to redirect to, :userId in path will be replaced with the selected user's id
481
- * @param query any query parameters you want to add, :userId will be replaced with the selected user's id
482
621
  * @param data the data to construct a component out of
483
622
  */
484
- constructor(embedRouter, path2, query, data) {
623
+ constructor(embedRouter, data) {
485
624
  super(data);
486
- this.embedRouter = embedRouter;
487
- super.setCustomId(
488
- encodePath(
489
- this.embedRouter.getIdPrefix(),
490
- path2,
491
- new URLSearchParams(query)
492
- )
493
- );
625
+ this.#embedRouter = embedRouter;
494
626
  }
495
627
  /**
496
628
  * Not supported for RouteUserSelectMenuBuilder (customId set from embedRouter)
@@ -503,6 +635,22 @@ var RouteUserSelectMenuBuilder = class extends UserSelectMenuBuilder {
503
635
  "setCustomId is not supported on RouteUserSelectMenuBuilder"
504
636
  );
505
637
  }
638
+ setPattern(arg) {
639
+ const {
640
+ method = "GET",
641
+ path: path2,
642
+ query
643
+ } = isSetOptions(arg) ? arg : { path: arg };
644
+ super.setCustomId(
645
+ encodePath({
646
+ idPrefix: this.#embedRouter.getIdPrefix(),
647
+ method,
648
+ path: path2,
649
+ query
650
+ })
651
+ );
652
+ return this;
653
+ }
506
654
  };
507
655
  export {
508
656
  EmbedRouter,