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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/EmbedRouter.ts","../src/consts.ts","../src/helpers/pathToString.ts","../src/helpers/decodePath.ts","../src/componentBuilders/RouteButtonBuilder.ts","../src/helpers/encodePath.ts","../src/componentBuilders/RouteStringSelectMenuBuilder.ts","../src/componentBuilders/RouteStringMenuOptionBuilder.ts","../src/componentBuilders/RouteChannelSelectMenuBuilder.ts","../src/componentBuilders/RouteRoleSelectMenuBuilder.ts","../src/componentBuilders/RouteUserSelectMenuBuilder.ts"],"sourcesContent":["import path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { match, Path } from \"path-to-regexp\";\nimport type {\n\tCompiledRoute,\n\tResolvedRoute,\n\tRouteHandler,\n\tState,\n} from \"./types/routes\";\nimport type { ExtractParams } from \"./types/ExtractParams\";\nimport {\n\tAnySelectMenuInteraction,\n\tButtonInteraction,\n\tInteraction,\n\tInteractionReplyOptions,\n} from \"discord.js\";\nimport { BASE_URL, ID_PREFIX, PUA_RANGE, PUA_START } from \"./consts\";\nimport { pathToString } from \"./helpers/pathToString\";\nimport { decodePath } from \"./helpers/decodePath\";\n\nexport class EmbedRouter<L> {\n\t// identifier -> embedRouter\n\tprivate static usedIdentifiers = new Map<string, EmbedRouter<unknown>>();\n\n\t// Name used to generate prefixes\n\tprivate name = \"\";\n\t// Prefix for customIds of RouteButtonBuilders\n\tprivate idPrefix: string;\n\tprivate identifier: string = \"\";\n\tpublic getIdPrefix() {\n\t\treturn `${this.idPrefix}${this.identifier}`;\n\t}\n\n\t// All added routes\n\tprivate routes: CompiledRoute<L>[] = [];\n\n\t/**\n\t *\n\t * @param name the name to give the router. ensures buttons stay connected across restarts\n\t * @param idPrefix the prefix for RouteButtonBuilder customIds\n\t */\n\tconstructor({\n\t\tname = \"\",\n\t\tidPrefix = ID_PREFIX,\n\t}: {\n\t\tname?: string;\n\t\tidPrefix?: string;\n\t} = {}) {\n\t\tif (EmbedRouter.usedIdentifiers.size >= PUA_RANGE) {\n\t\t\tthrow new Error(`You can not have more than ${PUA_RANGE} routers`);\n\t\t}\n\t\tif (idPrefix.includes(\"/\")) {\n\t\t\tthrow new Error(`Prefix can't contain \"/\": ${idPrefix}`);\n\t\t}\n\t\tthis.idPrefix = idPrefix;\n\t\tthis.name = name;\n\t\tthis.updateIdentifier();\n\t}\n\n\tprivate updateIdentifier() {\n\t\t// Private Use Area: Unicode Characters not from any language\n\t\tconst hash = createHash(\"sha256\").update(this.name).digest();\n\t\tlet raw = hash.readUint32BE(0);\n\t\tlet char: string;\n\t\tconst nameCollisions = [];\n\t\t// find next available identifier\n\t\twhile (true) {\n\t\t\tconst codepoint = PUA_START + (raw++ % PUA_RANGE);\n\t\t\tchar = String.fromCodePoint(codepoint);\n\n\t\t\tconst collisionRouter = EmbedRouter.usedIdentifiers.get(char);\n\t\t\tif (collisionRouter === undefined) break; // no collisions\n\n\t\t\tif (this.name.length > 0 && collisionRouter.name.length === 0) {\n\t\t\t\t// evict old name; usedIdentifier is still taken\n\t\t\t\tcollisionRouter.updateIdentifier();\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tnameCollisions.push(collisionRouter);\n\t\t}\n\t\tEmbedRouter.usedIdentifiers.set(char, this as EmbedRouter<unknown>);\n\n\t\tif (nameCollisions.length > 0 && this.name.length > 0) {\n\t\t\tprocess.emitWarning(\n\t\t\t\t`EmbedRouter identifier collision for name \"${this.name}\" with ${nameCollisions.map((c) => `\"${c.name}\"`).join(\", \")}`,\n\t\t\t\t\"EmbedRouterWarning\",\n\t\t\t);\n\t\t}\n\t\tthis.identifier = char;\n\t}\n\n\t/**\n\t * Registers a path with the router\n\t *\n\t * @param routePath path to match with\n\t * @param handler function that generates the message when a path is matched\n\t */\n\tpublic get<P extends Path = Path>(\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<L, ExtractParams<P>>,\n\t) {\n\t\tthis.routes.push({\n\t\t\tpath: Array.isArray(routePath) ? routePath : [routePath],\n\t\t\tmatchFunction: match(routePath),\n\t\t\thandler: handler as RouteHandler<L>,\n\t\t});\n\t}\n\n\t/**\n\t * Adds a subrouter to the router\n\t *\n\t * @param routePath path of the router\n\t * @param embedRouter router to add at the path\n\t */\n\tpublic use<P extends Path = Path>(routePath: P, embedRouter: EmbedRouter<L>) {\n\t\tconst pathString = pathToString(routePath);\n\t\tfor (const route of embedRouter.routes) {\n\t\t\tthis.get(\n\t\t\t\troute.path.map((p) => path.posix.join(pathString, pathToString(p))),\n\t\t\t\troute.handler,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Must be attached to \"interactionCreate\" event for RouteButtonBuilder to work\n\t *\n\t * @param interaction interactions from \"interactionCreate\" (filter for ButtonInteractions)\n\t */\n\tpublic async listener(\n\t\tinteraction: ButtonInteraction | AnySelectMenuInteraction,\n\t\tlocals?: L,\n\t) {\n\t\tconst path = decodePath(this.getIdPrefix(), interaction);\n\t\tif (!path)\n\t\t\tthrow new Error(`Invalid component found: id ${interaction.customId}`);\n\n\t\tthis.dispatch(interaction, path, locals);\n\t}\n\n\t/**\n\t * Connect or update an interaction message to a path\n\t *\n\t * @param interaction interaction to connect to\n\t * @param path path to route the interaction to\n\t * @param flags optional discord flags to send with message (only allowed on first reply)\n\t */\n\tpublic async dispatch<P extends Path = Path>(\n\t\tinteraction: Interaction,\n\t\tpath: P,\n\t\tlocals?: L,\n\t\tflags?: InteractionReplyOptions[\"flags\"],\n\t) {\n\t\tif (interaction.isAutocomplete())\n\t\t\tthrow new Error(\"Autocomplete Interactions aren't supported\");\n\n\t\t// don't check validity because url params are considered invalid\n\t\tconst resolvedRoute = this.resolve(pathToString(path, false));\n\t\tif (!resolvedRoute)\n\t\t\tthrow new Error(`No route found for ${pathToString(path, false)}`);\n\n\t\tconst routeResponse = await resolvedRoute.handler(interaction, {\n\t\t\t...resolvedRoute.state,\n\t\t\tlocals,\n\t\t});\n\n\t\tif (interaction.replied || interaction.deferred) {\n\t\t\tif (flags)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"You can only set flags for interactions that haven't been replied to\",\n\t\t\t\t);\n\t\t\tawait interaction.editReply(routeResponse);\n\t\t} else if (\"update\" in interaction) {\n\t\t\tif (flags)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"You can only set flags for interactions that haven't been replied to\",\n\t\t\t\t);\n\t\t\tawait interaction.update(routeResponse);\n\t\t} else {\n\t\t\tinteraction.reply({\n\t\t\t\t...(routeResponse as InteractionReplyOptions),\n\t\t\t\tflags,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate resolve<P extends string>(\n\t\troutePath: P,\n\t): ResolvedRoute<L, ExtractParams<P>> | false {\n\t\tconst url = new URL(routePath, BASE_URL);\n\t\tfor (const route of this.routes) {\n\t\t\tconst result = route.matchFunction(url.pathname);\n\t\t\tif (result) {\n\t\t\t\treturn {\n\t\t\t\t\tstate: {\n\t\t\t\t\t\t...(result as State<L, ExtractParams<P>>),\n\t\t\t\t\t\tquery: url.searchParams,\n\t\t\t\t\t\tembedRouter: this,\n\t\t\t\t\t},\n\t\t\t\t\thandler: route.handler,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}\n","export const ID_PREFIX = \"der\";\n// base url is never sent; only used for processing locally\nexport const BASE_URL = \"discord://embed.router\";\n\nexport const PUA_START = 0xe000;\nexport const PUA_END = 0xf8ff;\nexport const PUA_RANGE = PUA_END - PUA_START + 1;\n","import { parse, Path, stringify, TokenData } from \"path-to-regexp\";\n\nexport const pathToString = <P extends Path>(\n\tpath: P,\n\tcheckValidity = true,\n): string => {\n\tif (checkValidity) {\n\t\treturn stringify(path instanceof TokenData ? path : parse(path));\n\t}\n\treturn typeof path === \"string\" ? path : stringify(path);\n};\n","import { compile, Path } from \"path-to-regexp\";\nimport { AnySelectMenuInteraction, ButtonInteraction } from \"discord.js\";\nimport { BASE_URL } from \"../consts\";\n\nexport const decodePath = (\n\tidPrefix: string,\n\tinteraction: ButtonInteraction | AnySelectMenuInteraction,\n): Path | false => {\n\tconst customId = interaction.customId;\n\tif (!customId.startsWith(idPrefix)) return false;\n\n\tif (interaction.isButton()) {\n\t\treturn customId.slice(idPrefix.length);\n\t} else if (interaction.isStringSelectMenu()) {\n\t\tif (interaction.values.length === 0) return false;\n\t\treturn fillParams(customId.slice(idPrefix.length), {\n\t\t\tto: interaction.values[0]!.split(\"/\").slice(1),\n\t\t});\n\t} else if (interaction.isChannelSelectMenu()) {\n\t\tif (interaction.values.length === 0) return false;\n\t\treturn fillParams(customId.slice(idPrefix.length), {\n\t\t\tchannelId: interaction.values[0],\n\t\t});\n\t} else if (interaction.isRoleSelectMenu()) {\n\t\tif (interaction.values.length === 0) return false;\n\t\treturn fillParams(customId.slice(idPrefix.length), {\n\t\t\troleId: interaction.values[0],\n\t\t});\n\t} else if (interaction.isUserSelectMenu()) {\n\t\tif (interaction.values.length === 0) return false;\n\t\treturn fillParams(customId.slice(idPrefix.length), {\n\t\t\tuserId: interaction.values[0],\n\t\t});\n\t}\n\n\treturn false;\n};\n\nconst fillParams = (\n\tpath: string,\n\tparams: Partial<Record<string, string | string[]>> = {},\n): string => {\n\tconst url = new URL(path, BASE_URL);\n\tconst toPath = compile(url.pathname);\n\n\turl.pathname = toPath(params);\n\tfor (const [key, value] of url.searchParams) {\n\t\tif (value.startsWith(\":\") && key.slice(1) in params) {\n\t\t\tconst paramValue = params?.[key.slice(1)];\n\t\t\tif (paramValue) {\n\t\t\t\turl.searchParams.set(\n\t\t\t\t\tkey,\n\t\t\t\t\tArray.isArray(paramValue) ? paramValue.join(\"/\") : paramValue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\turl.searchParams.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\treturn `${url.pathname}${url.search}`;\n};\n","import { APIButtonComponent, ButtonBuilder } from \"discord.js\";\nimport { Path } from \"path-to-regexp\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { encodePath } from \"../helpers/encodePath\";\n\nexport class RouteButtonBuilder<L> extends ButtonBuilder {\n\tprivate embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tdata?: Omit<Partial<APIButtonComponent>, \"custom_id\" | \"url\">,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.embedRouter = embedRouter;\n\t}\n\n\t/**\n\t * Not supported for RouteButtonBuilder\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setURL(): this {\n\t\tthrow new Error(\"setURL is not supported on RouteButtonBuilder\");\n\t}\n\n\t/**\n\t * Not supported for RouteButtonBuilder (use setTo)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\"setCustomId is not supported on RouteButtonBuilder\");\n\t}\n\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t * @param query any query parameters you want to add\n\t */\n\tpublic setTo<P extends Path>(\n\t\tpath: P,\n\t\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n\t): this {\n\t\tsuper.setCustomId(encodePath(this.embedRouter.getIdPrefix(), path, query));\n\n\t\treturn this;\n\t}\n}\n","import { Path } from \"path-to-regexp\";\nimport { BASE_URL } from \"../consts\";\nimport { pathToString } from \"./pathToString\";\n\nexport const encodePath = (\n\tidPrefix: string,\n\tpath: Path,\n\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n) => {\n\tconst url = new URL(pathToString(path), BASE_URL);\n\tif (query) {\n\t\tfor (const [key, value] of new URLSearchParams(query)) {\n\t\t\turl.searchParams.set(key, value);\n\t\t}\n\t}\n\treturn `${idPrefix}${url.pathname}${url.search}`;\n};\n","import {\n\tAPIStringSelectComponent,\n\tnormalizeArray,\n\tRestOrArray,\n\tStringSelectMenuBuilder,\n\tStringSelectMenuComponentData,\n} from \"discord.js\";\nimport { Path } from \"path-to-regexp\";\nimport { RouteStringSelectMenuOptionBuilder } from \"./RouteStringMenuOptionBuilder\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { encodePath } from \"../helpers/encodePath\";\n\nexport class RouteStringSelectMenuBuilder<\n\tL,\n\tP extends Path,\n> extends StringSelectMenuBuilder {\n\tprivate embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param path the path to redirect to, :to or *to in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :to will be replaced with the selected user's id\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tpath: P | string = \"/*to\",\n\t\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n\t\tdata?: Partial<StringSelectMenuComponentData | APIStringSelectComponent>,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.embedRouter = embedRouter;\n\n\t\tsuper.setCustomId(\n\t\t\tencodePath(\n\t\t\t\tthis.embedRouter.getIdPrefix(),\n\t\t\t\tpath,\n\t\t\t\tnew URLSearchParams(query),\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteStringSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuBuilder (use addTos)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride addOptions(): this {\n\t\tthrow new Error(\n\t\t\t\"addOptions is not supported on RouteStringSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuBuilder (use setTos)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setOptions(): this {\n\t\tthrow new Error(\n\t\t\t\"setOptions is not supported on RouteStringSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Adds route select menu options to builder\n\t *\n\t * @param tos the list of route select menu options\n\t */\n\tpublic addTos(\n\t\t...tos: RestOrArray<\n\t\t\t| RouteStringSelectMenuOptionBuilder\n\t\t\t| ConstructorParameters<typeof RouteStringSelectMenuOptionBuilder>[0]\n\t\t>\n\t): this {\n\t\tconst resolved = normalizeArray(tos);\n\t\tsuper.addOptions(\n\t\t\tresolved.map((o) =>\n\t\t\t\to instanceof RouteStringSelectMenuOptionBuilder\n\t\t\t\t\t? o\n\t\t\t\t\t: new RouteStringSelectMenuOptionBuilder(o),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets route select menu options to builder\n\t *\n\t * @param tos the list of route select menu options\n\t */\n\tpublic setTos(\n\t\t...tos: RestOrArray<\n\t\t\t| RouteStringSelectMenuOptionBuilder\n\t\t\t| ConstructorParameters<typeof RouteStringSelectMenuOptionBuilder>[0]\n\t\t>\n\t): this {\n\t\tconst resolved = normalizeArray(tos);\n\t\tsuper.setOptions(\n\t\t\tresolved.map((o) =>\n\t\t\t\to instanceof RouteStringSelectMenuOptionBuilder\n\t\t\t\t\t? o\n\t\t\t\t\t: new RouteStringSelectMenuOptionBuilder(o),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n}\n","import {\n\tAPISelectMenuOption,\n\tSelectMenuComponentOptionData,\n\tStringSelectMenuOptionBuilder,\n} from \"discord.js\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\n\nexport class RouteStringSelectMenuOptionBuilder extends StringSelectMenuOptionBuilder {\n\t/**\n\t *\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tdata?: Omit<\n\t\t\tSelectMenuComponentOptionData | APISelectMenuOption,\n\t\t\t\"value\"\n\t\t> & { to: string },\n\t) {\n\t\tconst stringSelectData = data\n\t\t\t? {\n\t\t\t\t\t...data,\n\t\t\t\t\tvalue: encodePath(\"\", data.to),\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tsuper(stringSelectData);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuOptionBuilder (use setTo)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setValue(): this {\n\t\tthrow new Error(\n\t\t\t\"setValue is not supported on RouteStringSelectMenuOptionBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t * @param query any query parameters you want to add\n\t */\n\tsetTo<P extends Path>(\n\t\tpath: P,\n\t\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n\t): this {\n\t\tsuper.setValue(encodePath(\"\", path, query));\n\n\t\treturn this;\n\t}\n}\n","import {\n\tAPIChannelSelectComponent,\n\tChannelSelectMenuBuilder,\n\tChannelSelectMenuComponentData,\n} from \"discord.js\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\n\nexport class RouteChannelSelectMenuBuilder<\n\tL,\n\tP extends Path,\n> extends ChannelSelectMenuBuilder {\n\tprivate embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param path the path to redirect to, :channelId in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :channelId will be replaced with the selected user's id\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tpath: P,\n\t\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n\t\tdata?: Partial<ChannelSelectMenuComponentData | APIChannelSelectComponent>,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.embedRouter = embedRouter;\n\n\t\tsuper.setCustomId(encodePath(this.embedRouter.getIdPrefix(), path, query));\n\t}\n\n\t/**\n\t * Not supported for RouteChannelSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteChannelSelectMenuBuilder\",\n\t\t);\n\t}\n}\n","import {\n\tAPIRoleSelectComponent,\n\tRoleSelectMenuBuilder,\n\tRoleSelectMenuComponentData,\n} from \"discord.js\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\n\nexport class RouteRoleSelectMenuBuilder<\n\tL,\n\tP extends Path,\n> extends RoleSelectMenuBuilder {\n\tprivate embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param path the path to redirect to, :roleId in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :roleId will be replaced with the selected user's id\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tpath: P,\n\t\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n\t\tdata?: Partial<RoleSelectMenuComponentData | APIRoleSelectComponent>,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.embedRouter = embedRouter;\n\n\t\tsuper.setCustomId(encodePath(this.embedRouter.getIdPrefix(), path, query));\n\t}\n\n\t/**\n\t * Not supported for RouteRoleSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteRoleSelectMenuBuilder\",\n\t\t);\n\t}\n}\n","import {\n\tAPIUserSelectComponent,\n\tUserSelectMenuBuilder,\n\tUserSelectMenuComponentData,\n} from \"discord.js\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\n\nexport class RouteUserSelectMenuBuilder<\n\tL,\n\tP extends Path,\n> extends UserSelectMenuBuilder {\n\tprivate embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param path the path to redirect to, :userId in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :userId will be replaced with the selected user's id\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tpath: P,\n\t\tquery?: ConstructorParameters<typeof URLSearchParams>[0],\n\t\tdata?: Partial<UserSelectMenuComponentData | APIUserSelectComponent>,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.embedRouter = embedRouter;\n\n\t\tsuper.setCustomId(\n\t\t\tencodePath(\n\t\t\t\tthis.embedRouter.getIdPrefix(),\n\t\t\t\tpath,\n\t\t\t\tnew URLSearchParams(query),\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteUserSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteUserSelectMenuBuilder\",\n\t\t);\n\t}\n}\n"],"mappings":"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","names":["path","path","path","path","path","path","path","path","path","path"]}
1
+ {"version":3,"sources":["../src/EmbedRouter.ts","../src/consts.ts","../src/helpers/pathToString.ts","../src/helpers/decodePath.ts","../src/componentBuilders/RouteButtonBuilder.ts","../src/helpers/encodePath.ts","../src/types/componentBuilders.ts","../src/componentBuilders/RouteStringSelectMenuBuilder.ts","../src/componentBuilders/RouteStringMenuOptionBuilder.ts","../src/componentBuilders/RouteChannelSelectMenuBuilder.ts","../src/componentBuilders/RouteRoleSelectMenuBuilder.ts","../src/componentBuilders/RouteUserSelectMenuBuilder.ts"],"sourcesContent":["import path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { match, MatchResult, Path } from \"path-to-regexp\";\nimport type {\n\tCompiledRoute,\n\tMethod,\n\tRouteHandler,\n\tRouteResponse,\n} from \"./types/routes\";\nimport type { ExtractParams } from \"./types/ExtractParams\";\nimport {\n\tAnySelectMenuInteraction,\n\tButtonInteraction,\n\tInteraction,\n\tInteractionReplyOptions,\n} from \"discord.js\";\nimport { BASE_URL, ID_PREFIX, PUA_RANGE, PUA_START } from \"./consts\";\nimport { pathToString } from \"./helpers/pathToString\";\nimport { decodePath } from \"./helpers/decodePath\";\n\nexport class EmbedRouter<L> {\n\t// identifier -> embedRouter\n\tstatic #usedIdentifiers = new Map<string, EmbedRouter<unknown>>();\n\n\t// Name used to generate prefixes\n\t#name = \"\";\n\t// Prefix for customIds of RouteButtonBuilders\n\t#idPrefix: string;\n\t#identifier: string = \"\";\n\tpublic getIdPrefix() {\n\t\treturn `${this.#idPrefix}${this.#identifier}`;\n\t}\n\n\t// All added routes\n\t#routes: Map<Method, CompiledRoute<Method, L>[]> = new Map();\n\n\t/**\n\t *\n\t * @param name the name to give the router. ensures buttons stay connected across restarts\n\t * @param idPrefix the prefix for RouteButtonBuilder customIds\n\t */\n\tconstructor({\n\t\tname = \"\",\n\t\tidPrefix = ID_PREFIX,\n\t}: {\n\t\tname?: string | undefined;\n\t\tidPrefix?: string | undefined;\n\t} = {}) {\n\t\tif (EmbedRouter.#usedIdentifiers.size >= PUA_RANGE) {\n\t\t\tthrow new Error(`You can not have more than ${PUA_RANGE} routers`);\n\t\t}\n\t\tif (idPrefix.includes(\"/\")) {\n\t\t\tthrow new Error(`Prefix can't contain \"/\": ${idPrefix}`);\n\t\t}\n\t\tthis.#idPrefix = idPrefix;\n\t\tthis.#name = name;\n\t\tthis.#updateIdentifier();\n\t}\n\n\t#updateIdentifier() {\n\t\t// Private Use Area: Unicode Characters not from any language\n\t\tconst hash = createHash(\"sha256\").update(this.#name).digest();\n\t\tlet raw = hash.readUint32BE(0);\n\t\tlet char: string;\n\t\tconst nameCollisions = [];\n\t\t// find next available identifier\n\t\twhile (true) {\n\t\t\tconst codepoint = PUA_START + (raw++ % PUA_RANGE);\n\t\t\tchar = String.fromCodePoint(codepoint);\n\n\t\t\tconst collisionRouter = EmbedRouter.#usedIdentifiers.get(char);\n\t\t\tif (collisionRouter === undefined) break; // no collisions\n\n\t\t\tif (this.#name.length > 0 && collisionRouter.#name.length === 0) {\n\t\t\t\t// evict old name; usedIdentifier is still taken\n\t\t\t\tcollisionRouter.#updateIdentifier();\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tnameCollisions.push(collisionRouter);\n\t\t}\n\t\tEmbedRouter.#usedIdentifiers.set(char, this as EmbedRouter<unknown>);\n\n\t\tif (nameCollisions.length > 0 && this.#name.length > 0) {\n\t\t\tprocess.emitWarning(\n\t\t\t\t`EmbedRouter identifier collision for name \"${this.#name}\" with ${nameCollisions.map((c) => `\"${c.#name}\"`).join(\", \")}`,\n\t\t\t\t\"EmbedRouterWarning\",\n\t\t\t);\n\t\t}\n\t\tthis.#identifier = char;\n\t}\n\n\t#addRoute<M extends Method, P extends Path = Path>(\n\t\tmethod: M,\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<M, L, ExtractParams<P>>,\n\t) {\n\t\tconst methodRoutes = this.#routes.get(method) ?? [];\n\t\tmethodRoutes.push({\n\t\t\tmethod,\n\t\t\tpath: Array.isArray(routePath) ? routePath : [routePath],\n\t\t\tmatchFunction: match(routePath),\n\t\t\thandler: handler as RouteHandler<M, L>,\n\t\t});\n\t\tthis.#routes.set(method, methodRoutes);\n\t}\n\n\t/**\n\t * Registers a path with the router\n\t *\n\t * @param routePath path to match with\n\t * @param handler function that generates the message when a path is matched\n\t */\n\tpublic get<P extends Path = Path>(\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<\"GET\", L, ExtractParams<P>>,\n\t) {\n\t\tthis.#addRoute(\"GET\", routePath, handler);\n\t}\n\n\t/**\n\t * Registers a path with the router\n\t *\n\t * @param routePath path to match with\n\t * @param handler function that generates the message when a path is matched\n\t */\n\tpublic post<P extends Path = Path>(\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<\"POST\", L, ExtractParams<P>>,\n\t) {\n\t\tthis.#addRoute(\"POST\", routePath, handler);\n\t}\n\n\t/**\n\t * Registers a path with the router\n\t *\n\t * @param routePath path to match with\n\t * @param handler function that generates the message when a path is matched\n\t */\n\tpublic put<P extends Path = Path>(\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<\"PUT\", L, ExtractParams<P>>,\n\t) {\n\t\tthis.#addRoute(\"PUT\", routePath, handler);\n\t}\n\n\t/**\n\t * Registers a path with the router\n\t *\n\t * @param routePath path to match with\n\t * @param handler function that generates the message when a path is matched\n\t */\n\tpublic patch<P extends Path = Path>(\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<\"PATCH\", L, ExtractParams<P>>,\n\t) {\n\t\tthis.#addRoute(\"PATCH\", routePath, handler);\n\t}\n\n\t/**\n\t * Registers a path with the router\n\t *\n\t * @param routePath path to match with\n\t * @param handler function that generates the message when a path is matched\n\t */\n\tpublic delete<P extends Path = Path>(\n\t\troutePath: P | P[],\n\t\thandler: RouteHandler<\"DELETE\", L, ExtractParams<P>>,\n\t) {\n\t\tthis.#addRoute(\"DELETE\", routePath, handler);\n\t}\n\n\t/**\n\t * Adds a subrouter to the router\n\t *\n\t * @param routePath path of the router\n\t * @param embedRouter router to add at the path\n\t */\n\tpublic use<P extends Path = Path>(routePath: P, embedRouter: EmbedRouter<L>) {\n\t\tconst pathString = pathToString(routePath);\n\t\tfor (const [method, routes] of embedRouter.#routes) {\n\t\t\tfor (const route of routes) {\n\t\t\t\tthis.#addRoute(\n\t\t\t\t\tmethod,\n\t\t\t\t\troute.path.map((p) => path.posix.join(pathString, pathToString(p))),\n\t\t\t\t\troute.handler,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Must be attached to \"interactionCreate\" event for RouteButtonBuilder to work\n\t *\n\t * @param interaction interactions from \"interactionCreate\" (filter for ButtonInteractions)\n\t */\n\tpublic async listener(\n\t\tinteraction: ButtonInteraction | AnySelectMenuInteraction,\n\t\tlocals?: L | undefined,\n\t) {\n\t\tconst res = decodePath({ idPrefix: this.getIdPrefix(), interaction });\n\t\tif (!res)\n\t\t\tthrow new Error(`Invalid component found: id ${interaction.customId}`);\n\n\t\tthis.dispatch({ interaction, method: res.method, path: res.path, locals });\n\t}\n\n\t/**\n\t * Replies to or editReplies to an interaction based on the route output\n\t *\n\t * @param interaction interaction to connect to\n\t * @param path path to route the interaction to\n\t * @param method method to send to route\n\t * @param flags discord flags to send with message (optional, only allowed on first reply)\n\t * @param locals additional info to pass in to page through state.local (optional)\n\t */\n\tpublic async dispatch<P extends Path = Path>({\n\t\tinteraction,\n\t\tmethod = \"GET\",\n\t\tpath,\n\t\tflags,\n\t\tlocals,\n\t}: {\n\t\tinteraction: Interaction;\n\t\tmethod?: Method;\n\t\tpath: P;\n\t\tflags?: InteractionReplyOptions[\"flags\"] | undefined;\n\t\tlocals?: L | undefined;\n\t}) {\n\t\tif (interaction.isAutocomplete())\n\t\t\tthrow new Error(\"Autocomplete Interactions aren't supported\");\n\n\t\t// don't check validity because url params are considered invalid\n\t\tconst routeResponse = await this.#resolve({\n\t\t\tinteraction,\n\t\t\tmethod,\n\t\t\tpath,\n\t\t\tlocals,\n\t\t});\n\t\tif (routeResponse === false)\n\t\t\tthrow new Error(`No route found for ${pathToString(path, false)}`);\n\n\t\tif (interaction.replied || interaction.deferred) {\n\t\t\tif (flags)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"You can only set flags for interactions that haven't been replied to\",\n\t\t\t\t);\n\t\t\tif (routeResponse) await interaction.editReply(routeResponse);\n\t\t} else if (!routeResponse) {\n\t\t\tif (\"deferUpdate\" in interaction) {\n\t\t\t\tawait interaction.deferUpdate();\n\t\t\t} else {\n\t\t\t\tawait interaction.deferReply();\n\t\t\t}\n\t\t} else if (\"update\" in interaction) {\n\t\t\tif (flags)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"You can only set flags for interactions that haven't been replied to\",\n\t\t\t\t);\n\t\t\tawait interaction.update(routeResponse);\n\t\t} else {\n\t\t\tinteraction.reply({\n\t\t\t\t...(routeResponse as InteractionReplyOptions),\n\t\t\t\tflags,\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Resolves a route to the associated message (DOES NOT UPDATE MESSAGE)\n\t *\n\t * @param interaction interaction to connect to\n\t * @param path path to route the interaction to\n\t * @param method method to send to route\n\t * @param locals additional info to pass in to page through state.local (optional)\n\t * @returns discord message associated with route OR false\n\t */\n\tasync #resolve<P extends Path>({\n\t\tinteraction,\n\t\tmethod = \"GET\",\n\t\tpath,\n\t\tlocals,\n\t}: {\n\t\tinteraction: Interaction;\n\t\tmethod?: Method;\n\t\tpath: P;\n\t\tlocals?: L | undefined;\n\t}): Promise<RouteResponse | false> {\n\t\t// don't check validity because url params are considered invalid\n\t\tconst url = new URL(pathToString(path, false), BASE_URL);\n\t\tfor (const route of this.#routes.get(method) ?? []) {\n\t\t\tconst result = route.matchFunction(url.pathname);\n\t\t\tif (result) {\n\t\t\t\treturn await route.handler(interaction, {\n\t\t\t\t\t...(result as MatchResult<ExtractParams<P>>),\n\t\t\t\t\tquery: url.searchParams,\n\t\t\t\t\tembedRouter: this,\n\t\t\t\t\tlocals,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}\n","import { Method } from \"./types/routes\";\n\nexport const ID_PREFIX = \"der\";\nexport const METHOD_TO_ENCODING: Record<Method, string> = {\n\tGET: \"G\",\n\tPOST: \"P\",\n\tPUT: \"U\",\n\tPATCH: \"A\",\n\tDELETE: \"D\",\n};\nexport const ENCODING_TO_METHOD: Record<string, Method> = {\n\tG: \"GET\",\n\tP: \"POST\",\n\tU: \"PUT\",\n\tA: \"PATCH\",\n\tD: \"DELETE\",\n};\n// base url is never sent; only used for processing locally\nexport const BASE_URL = \"discord://embed.router\";\n\nexport const PUA_START = 0xe000;\nexport const PUA_END = 0xf8ff;\nexport const PUA_RANGE = PUA_END - PUA_START + 1;\n","import { parse, Path, stringify, TokenData } from \"path-to-regexp\";\n\nexport const pathToString = <P extends Path>(\n\tpath: P,\n\tcheckValidity = true,\n): string => {\n\tif (checkValidity) {\n\t\treturn stringify(path instanceof TokenData ? path : parse(path));\n\t}\n\treturn typeof path === \"string\" ? path : stringify(path);\n};\n","import { compile, Path } from \"path-to-regexp\";\nimport { AnySelectMenuInteraction, ButtonInteraction } from \"discord.js\";\nimport { BASE_URL, ENCODING_TO_METHOD } from \"../consts\";\nimport { Method } from \"../types/routes\";\n\nexport const decodePath = ({\n\tidPrefix,\n\tinteraction,\n}: {\n\tidPrefix: string;\n\tinteraction: ButtonInteraction | AnySelectMenuInteraction;\n}): { method: Method; path: Path } | false => {\n\tconst customId = interaction.customId;\n\tif (!customId.startsWith(idPrefix)) return false;\n\n\tif (interaction.isButton()) {\n\t\treturn parseMethodAndPath(customId.slice(idPrefix.length));\n\t} else if (interaction.isAnySelectMenu()) {\n\t\tif (interaction.values.length === 0) return false;\n\t\tconst res = parseMethodAndPath(customId.slice(idPrefix.length));\n\t\tif (!res) return false;\n\n\t\tconst { method, path } = res;\n\t\treturn {\n\t\t\tmethod,\n\t\t\tpath: fillParams(path, {\n\t\t\t\t[interaction.isStringSelectMenu()\n\t\t\t\t\t? \"to\"\n\t\t\t\t\t: interaction.isChannelSelectMenu()\n\t\t\t\t\t\t? \"channelId\"\n\t\t\t\t\t\t: interaction.isRoleSelectMenu()\n\t\t\t\t\t\t\t? \"roleId\"\n\t\t\t\t\t\t\t: \"userId\"]: interaction.values[0]!.split(\"/\").slice(1),\n\t\t\t}),\n\t\t};\n\t}\n\n\treturn false;\n};\n\nexport const parseMethodAndPath = (\n\tpathWithMethod: string,\n): { method: Method; path: string } | false => {\n\t// path always start with \"/\"\n\tconst firstSlash = pathWithMethod.indexOf(\"/\");\n\t// invalid customId\n\tif (firstSlash <= 0) return false;\n\n\tconst method = ENCODING_TO_METHOD[pathWithMethod.slice(0, firstSlash)];\n\tif (method === undefined) return false;\n\treturn {\n\t\tmethod,\n\t\tpath: pathWithMethod.slice(firstSlash),\n\t};\n};\n\nconst fillParams = (\n\tpath: string,\n\tparams: Partial<Record<string, string | string[]>> = {},\n): string => {\n\tconst url = new URL(path, BASE_URL);\n\tconst toPath = compile(url.pathname);\n\n\turl.pathname = toPath(params);\n\tfor (const [key, value] of url.searchParams) {\n\t\tif (value.startsWith(\":\") && key.slice(1) in params) {\n\t\t\tconst paramValue = params?.[key.slice(1)];\n\t\t\tif (paramValue) {\n\t\t\t\turl.searchParams.set(\n\t\t\t\t\tkey,\n\t\t\t\t\tArray.isArray(paramValue) ? paramValue.join(\"/\") : paramValue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\turl.searchParams.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\treturn `${url.pathname}${url.search}`;\n};\n","import { APIButtonComponent, ButtonBuilder } from \"discord.js\";\nimport { Path } from \"path-to-regexp\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { encodePath } from \"../helpers/encodePath\";\nimport { isSetOptions, SetOptions } from \"../types/componentBuilders\";\n\nexport class RouteButtonBuilder<L> extends ButtonBuilder {\n\t#embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tdata?: Omit<Partial<APIButtonComponent>, \"custom_id\" | \"url\"> | undefined,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.#embedRouter = embedRouter;\n\t}\n\n\t/**\n\t * Not supported for RouteButtonBuilder\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setURL(): this {\n\t\tthrow new Error(\"setURL is not supported on RouteButtonBuilder\");\n\t}\n\n\t/**\n\t * Not supported for RouteButtonBuilder (use setTo)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\"setCustomId is not supported on RouteButtonBuilder\");\n\t}\n\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t * @param query any query parameters you want to add\n\t * @param method method to send to route\n\t */\n\tpublic setTo<P extends Path>({ method, path, query }: SetOptions<P>): this;\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t */\n\tpublic setTo<P extends Path>(path: P): this;\n\n\tpublic setTo<P extends Path>(arg: P | SetOptions<P>) {\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\tpath,\n\t\t\tquery,\n\t\t} = isSetOptions(arg) ? arg : { path: arg };\n\n\t\tsuper.setCustomId(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: this.#embedRouter.getIdPrefix(),\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tquery,\n\t\t\t}),\n\t\t);\n\n\t\treturn this;\n\t}\n}\n","import { Path } from \"path-to-regexp\";\nimport { BASE_URL, METHOD_TO_ENCODING } from \"../consts\";\nimport { pathToString } from \"./pathToString\";\nimport { Method } from \"../types/routes\";\n\nexport const encodePath = ({\n\tidPrefix,\n\tmethod,\n\tpath,\n\tquery,\n}: {\n\tidPrefix: string;\n\tmethod: Method;\n\tpath: Path;\n\tquery?: ConstructorParameters<typeof URLSearchParams>[0] | undefined;\n}) => {\n\tconst url = new URL(pathToString(path), BASE_URL);\n\tif (query) {\n\t\tfor (const [key, value] of new URLSearchParams(query)) {\n\t\t\turl.searchParams.set(key, value);\n\t\t}\n\t}\n\treturn `${idPrefix}${METHOD_TO_ENCODING[method]}${url.pathname}${url.search}`;\n};\n","import { Path } from \"path-to-regexp\";\nimport { Method } from \"./routes\";\n\nexport type SetOptions<P extends Path> = {\n\tmethod?: Method;\n\tpath: P;\n\tquery?: ConstructorParameters<typeof URLSearchParams>[0] | undefined;\n};\n\nexport const isSetOptions = <P extends Path>(\n\tu: unknown,\n): u is SetOptions<P> => {\n\treturn (\n\t\ttypeof u === \"object\" &&\n\t\tu !== null &&\n\t\t(!(\"method\" in u) ||\n\t\t\t(\"method\" in u && typeof u.method === \"string\") ||\n\t\t\tu.method === undefined) &&\n\t\t\"path\" in u &&\n\t\ttypeof u.path === \"string\" &&\n\t\t(!(\"query\" in u) ||\n\t\t\t(\"query\" in u && [\"object\", \"string\"].includes(typeof u.query)) ||\n\t\t\tu.query === undefined)\n\t);\n};\n","import {\n\tAPIStringSelectComponent,\n\tnormalizeArray,\n\tRestOrArray,\n\tStringSelectMenuBuilder,\n\tStringSelectMenuComponentData,\n} from \"discord.js\";\nimport { Path } from \"path-to-regexp\";\nimport { RouteStringSelectMenuOptionBuilder } from \"./RouteStringMenuOptionBuilder\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { encodePath } from \"../helpers/encodePath\";\nimport { isSetOptions, SetOptions } from \"../types/componentBuilders\";\n\nexport class RouteStringSelectMenuBuilder<L> extends StringSelectMenuBuilder {\n\t#embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param path the path to redirect to, :to or *to in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :to will be replaced with the selected user's id\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tdata?:\n\t\t\t| Partial<StringSelectMenuComponentData | APIStringSelectComponent>\n\t\t\t| undefined,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.#embedRouter = embedRouter;\n\n\t\tsuper.setCustomId(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: this.#embedRouter.getIdPrefix(),\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/*to\",\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteStringSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuBuilder (use addTos)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride addOptions(): this {\n\t\tthrow new Error(\n\t\t\t\"addOptions is not supported on RouteStringSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Not supported for RouteStringSelectMenuBuilder (use setTos)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setOptions(): this {\n\t\tthrow new Error(\n\t\t\t\"setOptions is not supported on RouteStringSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Adds route select menu options to builder\n\t *\n\t * @param tos the list of route select menu options\n\t */\n\tpublic addTos(\n\t\t...tos: RestOrArray<\n\t\t\t| RouteStringSelectMenuOptionBuilder\n\t\t\t| ConstructorParameters<typeof RouteStringSelectMenuOptionBuilder>[0]\n\t\t>\n\t): this {\n\t\tconst resolved = normalizeArray(tos);\n\t\tsuper.addOptions(\n\t\t\tresolved.map((o) =>\n\t\t\t\to instanceof RouteStringSelectMenuOptionBuilder\n\t\t\t\t\t? o\n\t\t\t\t\t: new RouteStringSelectMenuOptionBuilder(o),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets route select menu options to builder\n\t *\n\t * @param tos the list of route select menu options\n\t */\n\tpublic setTos(\n\t\t...tos: RestOrArray<\n\t\t\t| RouteStringSelectMenuOptionBuilder\n\t\t\t| ConstructorParameters<typeof RouteStringSelectMenuOptionBuilder>[0]\n\t\t>\n\t): this {\n\t\tconst resolved = normalizeArray(tos);\n\t\tsuper.setOptions(\n\t\t\tresolved.map((o) =>\n\t\t\t\to instanceof RouteStringSelectMenuOptionBuilder\n\t\t\t\t\t? o\n\t\t\t\t\t: new RouteStringSelectMenuOptionBuilder(o),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the pattern to redirect to (Required)\n\t *\n\t * @param path the path to redirect to, :to or *to in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :to will be replaced with the selected user's id\n\t * @param method method to send to route\n\t */\n\tpublic setPattern<P extends Path>({\n\t\tmethod,\n\t\tpath,\n\t\tquery,\n\t}: SetOptions<P>): this;\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t */\n\tpublic setPattern<P extends Path>(path: P): this;\n\n\tpublic setPattern<P extends Path>(arg: P | SetOptions<P>) {\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\tpath,\n\t\t\tquery,\n\t\t} = isSetOptions(arg) ? arg : { path: arg };\n\t\tsuper.setCustomId(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: this.#embedRouter.getIdPrefix(),\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tquery,\n\t\t\t}),\n\t\t);\n\n\t\treturn this;\n\t}\n}\n","import { StringSelectMenuOptionBuilder } from \"discord.js\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\nimport { isSetOptions, SetOptions } from \"../types/componentBuilders\";\n\nexport class RouteStringSelectMenuOptionBuilder extends StringSelectMenuOptionBuilder {\n\t/**\n\t * Not supported for RouteStringSelectMenuOptionBuilder (use setTo)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setValue(): this {\n\t\tthrow new Error(\n\t\t\t\"setValue is not supported on RouteStringSelectMenuOptionBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t * @param query any query parameters you want to add\n\t * @param method method to send to route\n\t */\n\tpublic setTo<P extends Path>({ method, path, query }: SetOptions<P>): this;\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t */\n\tpublic setTo<P extends Path>(path: P): this;\n\n\tpublic setTo<P extends Path>(arg: P | SetOptions<P>) {\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\tpath,\n\t\t\tquery,\n\t\t} = isSetOptions(arg) ? arg : { path: arg };\n\t\tsuper.setValue(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: \"\",\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tquery,\n\t\t\t}),\n\t\t);\n\n\t\treturn this;\n\t}\n}\n","import {\n\tAPIChannelSelectComponent,\n\tChannelSelectMenuBuilder,\n\tChannelSelectMenuComponentData,\n} from \"discord.js\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\nimport { isSetOptions, SetOptions } from \"../types/componentBuilders\";\n\nexport class RouteChannelSelectMenuBuilder<L> extends ChannelSelectMenuBuilder {\n\t#embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tdata?:\n\t\t\t| Partial<ChannelSelectMenuComponentData | APIChannelSelectComponent>\n\t\t\t| undefined,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.#embedRouter = embedRouter;\n\t}\n\n\t/**\n\t * Not supported for RouteChannelSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteChannelSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Sets the pattern to redirect to (Required)\n\t *\n\t * @param path the path to redirect to, :channelId in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :channelId will be replaced with the selected user's id\n\t * @param method method to send to route\n\t */\n\tpublic setPattern<P extends Path>({\n\t\tmethod,\n\t\tpath,\n\t\tquery,\n\t}: SetOptions<P>): this;\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t */\n\tpublic setPattern<P extends Path>(path: P): this;\n\n\tpublic setPattern<P extends Path>(arg: P | SetOptions<P>) {\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\tpath,\n\t\t\tquery,\n\t\t} = isSetOptions(arg) ? arg : { path: arg };\n\t\tsuper.setCustomId(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: this.#embedRouter.getIdPrefix(),\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tquery,\n\t\t\t}),\n\t\t);\n\n\t\treturn this;\n\t}\n}\n","import {\n\tAPIRoleSelectComponent,\n\tRoleSelectMenuBuilder,\n\tRoleSelectMenuComponentData,\n} from \"discord.js\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\nimport { isSetOptions, SetOptions } from \"../types/componentBuilders\";\n\nexport class RouteRoleSelectMenuBuilder<L> extends RoleSelectMenuBuilder {\n\t#embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tdata?:\n\t\t\tPartial<RoleSelectMenuComponentData | APIRoleSelectComponent> | undefined,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.#embedRouter = embedRouter;\n\t}\n\n\t/**\n\t * Not supported for RouteRoleSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteRoleSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Sets the pattern to redirect to (Required)\n\t *\n\t * @param path the path to redirect to, :roleId in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :roleId will be replaced with the selected user's id\n\t * @param method method to send to route\n\t */\n\tpublic setPattern<P extends Path>({\n\t\tmethod,\n\t\tpath,\n\t\tquery,\n\t}: SetOptions<P>): this;\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t */\n\tpublic setPattern<P extends Path>(path: P): this;\n\n\tpublic setPattern<P extends Path>(arg: P | SetOptions<P>) {\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\tpath,\n\t\t\tquery,\n\t\t} = isSetOptions(arg) ? arg : { path: arg };\n\t\tsuper.setCustomId(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: this.#embedRouter.getIdPrefix(),\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tquery,\n\t\t\t}),\n\t\t);\n\n\t\treturn this;\n\t}\n}\n","import {\n\tAPIUserSelectComponent,\n\tUserSelectMenuBuilder,\n\tUserSelectMenuComponentData,\n} from \"discord.js\";\nimport { EmbedRouter } from \"../EmbedRouter\";\nimport { Path } from \"path-to-regexp\";\nimport { encodePath } from \"../helpers/encodePath\";\nimport { isSetOptions, SetOptions } from \"../types/componentBuilders\";\n\nexport class RouteUserSelectMenuBuilder<L> extends UserSelectMenuBuilder {\n\t#embedRouter: EmbedRouter<L>;\n\n\t/**\n\t *\n\t * @param embedRouter the router you want to route with\n\t * @param data the data to construct a component out of\n\t */\n\tconstructor(\n\t\tembedRouter: EmbedRouter<L>,\n\t\tdata?:\n\t\t\tPartial<UserSelectMenuComponentData | APIUserSelectComponent> | undefined,\n\t) {\n\t\tsuper(data);\n\n\t\tthis.#embedRouter = embedRouter;\n\t}\n\n\t/**\n\t * Not supported for RouteUserSelectMenuBuilder (customId set from embedRouter)\n\t *\n\t * @remarks\n\t * @param\n\t */\n\toverride setCustomId(): this {\n\t\tthrow new Error(\n\t\t\t\"setCustomId is not supported on RouteUserSelectMenuBuilder\",\n\t\t);\n\t}\n\n\t/**\n\t * Sets the pattern to redirect to (Required)\n\t *\n\t * @param path the path to redirect to, :userId in path will be replaced with the selected user's id\n\t * @param query any query parameters you want to add, :userId will be replaced with the selected user's id\n\t * @param method method to send to route\n\t */\n\tpublic setPattern<P extends Path>({\n\t\tmethod,\n\t\tpath,\n\t\tquery,\n\t}: SetOptions<P>): this;\n\t/**\n\t * Sets the path to route to when clicked\n\t *\n\t * @param path the path to route to\n\t */\n\tpublic setPattern<P extends Path>(path: P): this;\n\n\tpublic setPattern<P extends Path>(arg: P | SetOptions<P>) {\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\tpath,\n\t\t\tquery,\n\t\t} = isSetOptions(arg) ? arg : { path: arg };\n\t\tsuper.setCustomId(\n\t\t\tencodePath({\n\t\t\t\tidPrefix: this.#embedRouter.getIdPrefix(),\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tquery,\n\t\t\t}),\n\t\t);\n\n\t\treturn this;\n\t}\n}\n"],"mappings":"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","names":["path","path","path","path","path","path","path","path","path","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-embed-router",
3
- "version": "0.2.0",
3
+ "version": "0.2.3",
4
4
  "description": "A vite inspired router for discord.js embeds and interactions",
5
5
  "files": [
6
6
  "dist"
@@ -29,6 +29,7 @@
29
29
  "scripts": {
30
30
  "build": "tsup",
31
31
  "lint": "eslint",
32
+ "typecheck": "tsc --noEmit",
32
33
  "format": "prettier . --write"
33
34
  },
34
35
  "homepage": "https://github.com/altrup/discord-embed-router#readme",