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