CVE-2024-34712 (published 2024-05-14T16:17Z)

Oceanic is a NodeJS library for interfacing with Discord. Prior to version 1.10.4, input to functions such as `Client.rest.channels.removeBan` is not url-encoded, resulting in specially crafted input such as `../../../channels/{id}` being normalized into the url `/api/v10/channels/{id}`, and deleting a channel rather than removing a ban. Version 1.10.4 fixes this issue. Some workarounds are available. One may sanitize user input, ensuring strings are valid for the purpose they are being used for. One may also encode input with `encodeURIComponent` before providing it to the library.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/OceanicJS/Oceanic
commit_details: repo_url: https://github.com/OceanicJS/Oceanic
author: Donovan Daniels
author_date: 2024-05-13 18:52:45-05:00
msg: sanitize route parameters
repository: repo_url: https://github.com/OceanicJS/Oceanic
repo_name: OceanicJS/Oceanic
description: A NodeJS library for interfacing with Discord.
repo_language: TypeScript
owner: OceanicJS
file_changes: filename: Routes.ts
change_type: ModificationType.MODIFY
diff: @@ -2,141 +2,145 @@
 /* eslint-disable @typescript-eslint/explicit-function-return-type */
 export const CDN_URL = "https://cdn.discordapp.com";
 
+function encode(strings: TemplateStringsArray, ...args: Array<string | number>): string {
+    return strings.reduce((acc, str, i) => `${acc}${str}${encodeURIComponent(args[i] ?? "")}`, "");
+}
+
 // Webhooks
-export const CHANNEL_WEBHOOKS = (channelID: string) => `/channels/${channelID}/webhooks` as const;
-export const GUILD_WEBHOOKS   = (guildID: string) => `/guilds/${guildID}/webhooks` as const;
-export const WEBHOOK          = (webhookID: string, webhookToken?: string) => (webhookToken ? `/webhooks/${webhookID}/${webhookToken}` : `/webhooks/${webhookID}`) as `/webhooks/${string}` | `/webhooks/${string}/${string}`;
-export const WEBHOOK_MESSAGE  = (webhookID: string, webhookToken: string, messageID: string) => `/webhooks/${webhookID}/${webhookToken}/messages/${messageID}` as const;
-export const WEBHOOK_PLATFORM = (webhookID: string, webhookToken: string, platform: "github" | "slack") => `/webhooks/${webhookID}/${webhookToken}/${platform}` as const;
+export const CHANNEL_WEBHOOKS = (channelID: string) => encode`/channels/${channelID}/webhooks`;
+export const GUILD_WEBHOOKS   = (guildID: string) => encode`/guilds/${guildID}/webhooks`;
+export const WEBHOOK          = (webhookID: string, webhookToken?: string) => (webhookToken ? encode`/webhooks/${webhookID}/${webhookToken}` : `/webhooks/${webhookID}`) as `/webhooks/${string}` | `/webhooks/${string}/${string}`;
+export const WEBHOOK_MESSAGE  = (webhookID: string, webhookToken: string, messageID: string) => encode`/webhooks/${webhookID}/${webhookToken}/messages/${messageID}`;
+export const WEBHOOK_PLATFORM = (webhookID: string, webhookToken: string, platform: "github" | "slack") => encode`/webhooks/${webhookID}/${webhookToken}/${platform}`;
 
 // Guilds
-export const GUILD                       = (userID: string) => `/guilds/${userID}` as const;
-export const GUILDS                      = "/guilds" as const;
-export const GUILD_BANS                  = (guildID: string) => `/guilds/${guildID}/bans` as const;
-export const GUILD_BAN                   = (guildID: string, userID: string) => `/guilds/${guildID}/bans/${userID}` as const;
-export const GUILD_AUTOMOD_RULE          = (guildID: string, autoModerationRuleID: string) => `/guilds/${guildID}/auto-moderation/rules/${autoModerationRuleID}` as const;
-export const GUILD_AUTOMOD_RULES         = (guildID: string) => `/guilds/${guildID}/auto-moderation/rules` as const;
-export const GUILD_EMOJI                 = (guildID: string, emojiID: string) => `/guilds/${guildID}/emojis/${emojiID}` as const;
-export const GUILD_EMOJIS                = (guildID: string) => `/guilds/${guildID}/emojis` as const;
-export const GUILD_AUDIT_LOG             = (guildID: string) => `/guilds/${guildID}/audit-logs` as const;
-export const GUILD_SCHEDULED_EVENT       = (guildID: string, eventID: string) => `/guilds/${guildID}/scheduled-events/${eventID}` as const;
-export const GUILD_SCHEDULED_EVENTS      = (guildID: string) => `/guilds/${guildID}/scheduled-events` as const;
-export const GUILD_SCHEDULED_EVENT_USERS = (guildID: string, eventID: string) => `/guilds/${guildID}/scheduled-events/${eventID}/users` as const;
-export const GUILD_TEMPLATE_CODE         = (code: string) => `/guilds/templates/${code}` as const;
-export const GUILD_TEMPLATE              = (guildID: string, templateID: string) => `/guilds/${guildID}/templates/${templateID}` as const;
-export const GUILD_TEMPLATES             = (guildID: string) => `/guilds/${guildID}/templates` as const;
-export const GUILD_PREVIEW               = (guildID: string) => `/guilds/${guildID}/preview` as const;
-export const GUILD_CHANNELS              = (guildID: string) => `/guilds/${guildID}/channels` as const;
-export const GUILD_ACTIVE_THREADS        = (guildID: string) => `/guilds/${guildID}/threads/active` as const;
-export const GUILD_MEMBERS               = (guildID: string) => `/guilds/${guildID}/members` as const;
-export const GUILD_MEMBER                = (guildID: string, userID: string) => `/guilds/${guildID}/members/${userID}` as const;
-export const GUILD_SEARCH_MEMBERS        = (guildID: string) => `/guilds/${guildID}/members/search` as const;
-export const GUILD_MEMBER_ROLE           = (guildID: string, userID: string, roleID: string) => `/guilds/${guildID}/members/${userID}/roles/${roleID}` as const;
-export const GUILD_ROLES                 = (guildID: string) => `/guilds/${guildID}/roles` as const;
-export const GUILD_ROLE                  = (guildID: string, roleID: string) => `/guilds/${guildID}/roles/${roleID}` as const;
-export const GUILD_MFA                   = (guildID: string) => `/guilds/${guildID}/mfa` as const;
-export const GUILD_PRUNE                 = (guildID: string) => `/guilds/${guildID}/prune` as const;
-export const GUILD_INVITES               = (guildID: string) => `/guilds/${guildID}/invites` as const;
-export const GUILD_INTEGRATION           = (guildID: string, integrationID: string) => `/guilds/${guildID}/integrations/${integrationID}` as const;
-export const GUILD_INTEGRATIONS          = (guildID: string) => `/guilds/${guildID}/integrations` as const;
-export const GUILD_WIDGET                = (guildID: string) => `/guilds/${guildID}/widget` as const;
-export const GUILD_VANITY_URL            = (guildID: string) => `/guilds/${guildID}/vanity-url` as const;
-export const GUILD_WIDGET_IMAGE          = (guildID: string) => `/guilds/${guildID}/widget.png` as const;
-export const GUILD_WIDGET_JSON           = (guildID: string) => `/guilds/${guildID}/widget.json` as const;
-export const GUILD_WELCOME_SCREEN        = (guildID: string) => `/guilds/${guildID}/welcome-screen` as const;
-export const GUILD_VOICE_STATE           = (guildID: string, userID: string) => `/guilds/${guildID}/voice-states/${userID}` as const;
-export const GUILD_STICKER			     = (guildID: string, stickerID: string) => `/guilds/${guildID}/stickers/${stickerID}` as const;
-export const GUILD_STICKERS			     = (guildID: string) => `/guilds/${guildID}/stickers` as const;
-export const GUILD_ONBOARDING            = (guildID: string) => `/guilds/${guildID}/onboarding` as const;
-export const GUILD_INCIDENT_ACTIONS      = (guildID: string) => `/guilds/${guildID}/incident-actions` as const;
-export const GUILD_BULK_BAN              = (guildID: string) => `/guilds/${guildID}/bulk-ban` as const;
+export const GUILD                       = (userID: string) => encode`/guilds/${userID}`;
+export const GUILDS                      = "/guilds";
+export const GUILD_BANS                  = (guildID: string) => encode`/guilds/${guildID}/bans`;
+export const GUILD_BAN                   = (guildID: string, userID: string) => encode`/guilds/${guildID}/bans/${userID}`;
+export const GUILD_AUTOMOD_RULE          = (guildID: string, autoModerationRuleID: string) => encode`/guilds/${guildID}/auto-moderation/rules/${autoModerationRuleID}`;
+export const GUILD_AUTOMOD_RULES         = (guildID: string) => encode`/guilds/${guildID}/auto-moderation/rules`;
+export const GUILD_EMOJI                 = (guildID: string, emojiID: string) => encode`/guilds/${guildID}/emojis/${emojiID}`;
+export const GUILD_EMOJIS                = (guildID: string) => encode`/guilds/${guildID}/emojis`;
+export const GUILD_AUDIT_LOG             = (guildID: string) => encode`/guilds/${guildID}/audit-logs`;
+export const GUILD_SCHEDULED_EVENT       = (guildID: string, eventID: string) => encode`/guilds/${guildID}/scheduled-events/${eventID}`;
+export const GUILD_SCHEDULED_EVENTS      = (guildID: string) => encode`/guilds/${guildID}/scheduled-events`;
+export const GUILD_SCHEDULED_EVENT_USERS = (guildID: string, eventID: string) => encode`/guilds/${guildID}/scheduled-events/${eventID}/users`;
+export const GUILD_TEMPLATE_CODE         = (code: string) => encode`/guilds/templates/${code}`;
+export const GUILD_TEMPLATE              = (guildID: string, templateID: string) => encode`/guilds/${guildID}/templates/${templateID}`;
+export const GUILD_TEMPLATES             = (guildID: string) => encode`/guilds/${guildID}/templates`;
+export const GUILD_PREVIEW               = (guildID: string) => encode`/guilds/${guildID}/preview`;
+export const GUILD_CHANNELS              = (guildID: string) => encode`/guilds/${guildID}/channels`;
+export const GUILD_ACTIVE_THREADS        = (guildID: string) => encode`/guilds/${guildID}/threads/active`;
+export const GUILD_MEMBERS               = (guildID: string) => encode`/guilds/${guildID}/members`;
+export const GUILD_MEMBER                = (guildID: string, userID: string) => encode`/guilds/${guildID}/members/${userID}`;
+export const GUILD_SEARCH_MEMBERS        = (guildID: string) => encode`/guilds/${guildID}/members/search`;
+export const GUILD_MEMBER_ROLE           = (guildID: string, userID: string, roleID: string) => encode`/guilds/${guildID}/members/${userID}/roles/${roleID}`;
+export const GUILD_ROLES                 = (guildID: string) => encode`/guilds/${guildID}/roles`;
+export const GUILD_ROLE                  = (guildID: string, roleID: string) => encode`/guilds/${guildID}/roles/${roleID}`;
+export const GUILD_MFA                   = (guildID: string) => encode`/guilds/${guildID}/mfa`;
+export const GUILD_PRUNE                 = (guildID: string) => encode`/guilds/${guildID}/prune`;
+export const GUILD_INVITES               = (guildID: string) => encode`/guilds/${guildID}/invites`;
+export const GUILD_INTEGRATION           = (guildID: string, integrationID: string) => encode`/guilds/${guildID}/integrations/${integrationID}`;
+export const GUILD_INTEGRATIONS          = (guildID: string) => encode`/guilds/${guildID}/integrations`;
+export const GUILD_WIDGET                = (guildID: string) => encode`/guilds/${guildID}/widget`;
+export const GUILD_VANITY_URL            = (guildID: string) => encode`/guilds/${guildID}/vanity-url`;
+export const GUILD_WIDGET_IMAGE          = (guildID: string) => encode`/guilds/${guildID}/widget.png`;
+export const GUILD_WIDGET_JSON           = (guildID: string) => encode`/guilds/${guildID}/widget.json`;
+export const GUILD_WELCOME_SCREEN        = (guildID: string) => encode`/guilds/${guildID}/welcome-screen`;
+export const GUILD_VOICE_STATE           = (guildID: string, userID: string) => encode`/guilds/${guildID}/voice-states/${userID}`;
+export const GUILD_STICKER			     = (guildID: string, stickerID: string) => encode`/guilds/${guildID}/stickers/${stickerID}`;
+export const GUILD_STICKERS			     = (guildID: string) => encode`/guilds/${guildID}/stickers`;
+export const GUILD_ONBOARDING            = (guildID: string) => encode`/guilds/${guildID}/onboarding`;
+export const GUILD_INCIDENT_ACTIONS      = (guildID: string) => encode`/guilds/${guildID}/incident-actions`;
+export const GUILD_BULK_BAN              = (guildID: string) => encode`/guilds/${guildID}/bulk-ban`;
 
 // Channels
-export const CHANNEL                                 = (channelID: string) => `/channels/${channelID}` as const;
-export const CHANNEL_BULK_DELETE_MESSAGES            = (channelID: string) => `/channels/${channelID}/messages/bulk-delete` as const;
-export const CHANNEL_FOLLOWERS                       = (channelID: string) => `/channels/${channelID}/followers` as const;
-export const CHANNEL_INVITES                         = (channelID: string) => `/channels/${channelID}/invites` as const;
-export const CHANNEL_JOINED_PRIVATE_ARCHIVED_THREADS = (channelID: string) => `/channels/${channelID}/users/@me/threads/archived/private` as const;
-export const CHANNEL_MESSAGE                         = (channelID: string, messageID: string) => `/channels/${channelID}/messages/${messageID}` as const;
-export const CHANNEL_MESSAGES                        = (channelID: string) => `/channels/${channelID}/messages` as const;
-export const CHANNEL_MESSAGES_CROSSPOST              = (channelID: string, messageID: string) => `/channels/${channelID}/messages/${messageID}/crosspost` as const;
-export const CHANNEL_MESSAGE_THREADS                 = (channelID: string, messageID: string) => `/channels/${channelID}/messages/${messageID}/threads` as const;
-export const CHANNEL_PERMISSION                      = (channelID: string, overwriteID: string) => `/channels/${channelID}/permissions/${overwriteID}` as const;
-export const CHANNEL_PERMISSIONS                     = (channelID: string) => `/channels/${channelID}/permissions` as const;
-export const CHANNEL_PINNED_MESSAGE                  = (channelID: string, messageID: string) => `/channels/${channelID}/pins/${messageID}` as const;
-export const CHANNEL_PINS                            = (channelID: string) => `/channels/${channelID}/pins` as const;
-export const CHANNEL_PRIVATE_ARCHIVED_THREADS        = (channelID: string) => `/channels/${channelID}/threads/archived/private` as const;
-export const CHANNEL_PUBLIC_ARCHIVED_THREADS         = (channelID: string) => `/channels/${channelID}/threads/archived/public` as const;
-export const CHANNEL_REACTION                        = (channelID: string, messageID: string, reaction: string) => `/channels/${channelID}/messages/${messageID}/reactions/${reaction}` as const;
-export const CHANNEL_REACTIONS                       = (channelID: string, messageID: string) => `/channels/${channelID}/messages/${messageID}/reactions` as const;
-export const CHANNEL_REACTION_USER                   = (channelID: string, messageID: string, reaction: string, user: string) => `/channels/${channelID}/messages/${messageID}/reactions/${reaction}/${user}` as const;
-export const CHANNEL_THREADS                         = (channelID: string) => `/channels/${channelID}/threads` as const;
-export const CHANNEL_THREAD_MEMBER                   = (channelID: string, userID: string) => `/channels/${channelID}/thread-members/${userID}` as const;
-export const CHANNEL_THREAD_MEMBERS                  = (channelID: string) => `/channels/${channelID}/thread-members` as const;
-export const CHANNEL_TYPING                          = (channelID: string) => `/channels/${channelID}/typing` as const;
-export const GROUP_RECIPIENT                         = (channelID: string, userID: string) => `/channels/${channelID}/recipients/${userID}` as const;
-export const VOICE_REGIONS                           = "/voice/regions" as const;
-export const GUILD_VOICE_REGIONS                     = (guildID: string) => `/guilds/${guildID}/regions` as const;
-export const VOICE_STATUS                            = (channelID: string) => `/channels/${channelID}/voice-status` as const;
-export const POLL_ANSWER_USERS                       = (channelID: string, pollID: string, answerID: number) => `/channels/${channelID}/polls/${pollID}/answers/${answerID}` as const;
-export const POLL_EXPIRE                             = (channelID: string, pollID: string) => `/channels/${channelID}/polls/${pollID}/expire` as const;
+export const CHANNEL                                 = (channelID: string) => encode`/channels/${channelID}`;
+export const CHANNEL_BULK_DELETE_MESSAGES            = (channelID: string) => encode`/channels/${channelID}/messages/bulk-delete`;
+export const CHANNEL_FOLLOWERS                       = (channelID: string) => encode`/channels/${channelID}/followers`;
+export const CHANNEL_INVITES                         = (channelID: string) => encode`/channels/${channelID}/invites`;
+export const CHANNEL_JOINED_PRIVATE_ARCHIVED_THREADS = (channelID: string) => encode`/channels/${channelID}/users/@me/threads/archived/private`;
+export const CHANNEL_MESSAGE                         = (channelID: string, messageID: string) => encode`/channels/${channelID}/messages/${messageID}`;
+export const CHANNEL_MESSAGES                        = (channelID: string) => encode`/channels/${channelID}/messages`;
+export const CHANNEL_MESSAGES_CROSSPOST              = (channelID: string, messageID: string) => encode`/channels/${channelID}/messages/${messageID}/crosspost`;
+export const CHANNEL_MESSAGE_THREADS                 = (channelID: string, messageID: string) => encode`/channels/${channelID}/messages/${messageID}/threads`;
+export const CHANNEL_PERMISSION                      = (channelID: string, overwriteID: string) => encode`/channels/${channelID}/permissions/${overwriteID}`;
+export const CHANNEL_PERMISSIONS                     = (channelID: string) => encode`/channels/${channelID}/permissions`;
+export const CHANNEL_PINNED_MESSAGE                  = (channelID: string, messageID: string) => encode`/channels/${channelID}/pins/${messageID}`;
+export const CHANNEL_PINS                            = (channelID: string) => encode`/channels/${channelID}/pins`;
+export const CHANNEL_PRIVATE_ARCHIVED_THREADS        = (channelID: string) => encode`/channels/${channelID}/threads/archived/private`;
+export const CHANNEL_PUBLIC_ARCHIVED_THREADS         = (channelID: string) => encode`/channels/${channelID}/threads/archived/public`;
+export const CHANNEL_REACTION                        = (channelID: string, messageID: string, reaction: string) => encode`/channels/${channelID}/messages/${messageID}/reactions/${reaction}`;
+export const CHANNEL_REACTIONS                       = (channelID: string, messageID: string) => encode`/channels/${channelID}/messages/${messageID}/reactions`;
+export const CHANNEL_REACTION_USER                   = (channelID: string, messageID: string, reaction: string, user: string) => encode`/channels/${channelID}/messages/${messageID}/reactions/${reaction}/${user}`;
+export const CHANNEL_THREADS                         = (channelID: string) => encode`/channels/${channelID}/threads`;
+export const CHANNEL_THREAD_MEMBER                   = (channelID: string, userID: string) => encode`/channels/${channelID}/thread-members/${userID}`;
+export const CHANNEL_THREAD_MEMBERS                  = (channelID: string) => encode`/channels/${channelID}/thread-members`;
+export const CHANNEL_TYPING                          = (channelID: string) => encode`/channels/${channelID}/typing`;
+export const GROUP_RECIPIENT                         = (channelID: string, userID: string) => encode`/channels/${channelID}/recipients/${userID}`;
+export const VOICE_REGIONS                           = "/voice/regions";
+export const GUILD_VOICE_REGIONS                     = (guildID: string) => encode`/guilds/${guildID}/regions`;
+export const VOICE_STATUS                            = (channelID: string) => encode`/channels/${channelID}/voice-status`;
+export const POLL_ANSWER_USERS                       = (channelID: string, pollID: string, answerID: number) => encode`/channels/${channelID}/polls/${pollID}/answers/${answerID}`;
+export const POLL_EXPIRE                             = (channelID: string, pollID: string) => encode`/channels/${channelID}/polls/${pollID}/expire`;
 
 // OAuth
-export const OAUTH_APPLICATION         = "/oauth2/applications/@me" as const;
-export const OAUTH_AUTHORIZE           = "/oauth2/authorize" as const;
-export const OAUTH_INFO                = "/oauth2/@me" as const;
-export const OAUTH_CURRENT_USER        = "/users/@me" as const;
-export const OAUTH_CHANNELS            = "/users/@me/channels" as const;
-export const OAUTH_CONNECTIONS         = "/users/@me/connections" as const;
-export const OAUTH_GUILD               = (guildID: string) => `/users/@me/guilds/${guildID}` as const;
-export const OAUTH_GUILD_MEMBER        = (guildID: string) => `${OAUTH_GUILD(guildID)}/member` as const;
-export const OAUTH_GUILDS              = "/users/@me/guilds" as const;
-export const OAUTH_TOKEN               = "/oauth2/token" as const;
-export const OAUTH_TOKEN_REVOKE        = "/oauth2/token/revoke" as const;
-export const OAUTH_ROLE_CONNECTION     = (applicationID: string) => `/users/@me/applications/${applicationID}/role-connection` as const;
-export const ROLE_CONNECTIONS_METADATA = (applicationID: string) => `/applications/${applicationID}/role-connections/metadata` as const;
+export const OAUTH_APPLICATION         = "/oauth2/applications/@me";
+export const OAUTH_AUTHORIZE           = "/oauth2/authorize";
+export const OAUTH_INFO                = "/oauth2/@me";
+export const OAUTH_CURRENT_USER        = "/users/@me";
+export const OAUTH_CHANNELS            = "/users/@me/channels";
+export const OAUTH_CONNECTIONS         = "/users/@me/connections";
+export const OAUTH_GUILD               = (guildID: string) => encode`/users/@me/guilds/${guildID}`;
+export const OAUTH_GUILD_MEMBER        = (guildID: string) => encode`${OAUTH_GUILD(guildID)}/member`;
+export const OAUTH_GUILDS              = "/users/@me/guilds";
+export const OAUTH_TOKEN               = "/oauth2/token";
+export const OAUTH_TOKEN_REVOKE        = "/oauth2/token/revoke";
+export const OAUTH_ROLE_CONNECTION     = (applicationID: string) => encode`/users/@me/applications/${applicationID}/role-connection`;
+export const ROLE_CONNECTIONS_METADATA = (applicationID: string) => encode`/applications/${applicationID}/role-connections/metadata`;
 
 // Images
-export const ACHIEVEMENT_ICON            = (applicationID: string, achievementID: string, hash: string) => `/app-assets/${applicationID}/achievements/${achievementID}/icons/${hash}` as const;
-export const APPLICATION_ASSET           = (applicationID: string, assetID: string) => `/applications/${applicationID}/assets/${assetID}` as const;
-export const APPLICATION_COVER           = (applicationID: string, hash: string) => `/app-icons/${applicationID}/${hash}` as const;
+export const ACHIEVEMENT_ICON            = (applicationID: string, achievementID: string, hash: string) => encode`/app-assets/${applicationID}/achievements/${achievementID}/icons/${hash}`;
+export const APPLICATION_ASSET           = (applicationID: string, assetID: string) => encode`/applications/${applicationID}/assets/${assetID}`;
+export const APPLICATION_COVER           = (applicationID: string, hash: string) => encode`/app-icons/${applicationID}/${hash}`;
 export const APPLICATION_ICON            = APPLICATION_COVER;
-export const BANNER                      = (guildOrUserID: string, hash: string) => `/banners/${guildOrUserID}/${hash}` as const;
-export const CUSTOM_EMOJI                = (emojiID: string) => `/emojis/${emojiID}` as const;
-export const EMBED_AVATAR                = (mod: number) => `/embed/avatars/${mod}` as const;
-export const GUILD_AVATAR                = (guildID: string, userID: string, hash: string) => `/guilds/${guildID}/users/${userID}/avatars/${hash}` as const;
-export const GUILD_DISCOVERY_SPLASH      = (guildID: string, hash: string) => `/guilds/${guildID}/splashes/${hash}` as const;
-export const GUILD_ICON                  = (guildID: string, hash: string) => `/icons/${guildID}/${hash}` as const;
-export const GUILD_SCHEDULED_EVENT_COVER = (eventID: string, hash: string) => `/guild-events/${eventID}/${hash}` as const;
-export const GUILD_SPLASH                = (guildID: string, hash: string) => `/splashes/${guildID}/${hash}` as const;
-export const MEMBER_BANNER               = (guildID: string, userID: string, hash: string) => `/guilds/${guildID}/users/${userID}/banners/${hash}` as const;
-export const ROLE_ICON                   = (roleID: string, hash: string) => `/role-icons/${roleID}/${hash}` as const;
-export const STICKER                     = (stickerID: string) => `/stickers/${stickerID}` as const;
+export const BANNER                      = (guildOrUserID: string, hash: string) => encode`/banners/${guildOrUserID}/${hash}`;
+export const CUSTOM_EMOJI                = (emojiID: string) => encode`/emojis/${emojiID}`;
+export const EMBED_AVATAR                = (mod: number) => encode`/embed/avatars/${mod}`;
+export const GUILD_AVATAR                = (guildID: string, userID: string, hash: string) => encode`/guilds/${guildID}/users/${userID}/avatars/${hash}`;
+export const GUILD_DISCOVERY_SPLASH      = (guildID: string, hash: string) => encode`/guilds/${guildID}/splashes/${hash}`;
+export const GUILD_ICON                  = (guildID: string, hash: string) => encode`/icons/${guildID}/${hash}`;
+export const GUILD_SCHEDULED_EVENT_COVER = (eventID: string, hash: string) => encode`/guild-events/${eventID}/${hash}`;
+export const GUILD_SPLASH                = (guildID: string, hash: string) => encode`/splashes/${guildID}/${hash}`;
+export const MEMBER_BANNER               = (guildID: string, userID: string, hash: string) => encode`/guilds/${guildID}/users/${userID}/banners/${hash}`;
+export const ROLE_ICON                   = (roleID: string, hash: string) => encode`/role-icons/${roleID}/${hash}`;
+export const STICKER                     = (stickerID: string) => encode`/stickers/${stickerID}`;
 export const STICKER_PACK_BANNER         = (assetID: string) => APPLICATION_ASSET("710982414301790216", assetID);
-export const TEAM_ICON                   = (teamID: string, hash: string) => `/team-icons/${teamID}/${hash}` as const;
-export const USER_AVATAR                 = (userID: string, hash: string) => `/avatars/${userID}/${hash}` as const;
-export const USER_AVATAR_DECORATION      = (userID: string, hash: string) => `/avatar-decorations/${userID}/${hash}` as const;
+export const TEAM_ICON                   = (teamID: string, hash: string) => encode`/team-icons/${teamID}/${hash}`;
+export const USER_AVATAR                 = (userID: string, hash: string) => encode`/avatars/${userID}/${hash}`;
+export const USER_AVATAR_DECORATION      = (userID: string, hash: string) => encode`/avatar-decorations/${userID}/${hash}`;
 
 // Applications
-export const APPLICATION_COMMAND                   = (applicationID: string, commandID: string) => `/applications/${applicationID}/commands/${commandID}` as const;
-export const APPLICATION_COMMANDS                  = (applicationID: string) => `/applications/${applicationID}/commands` as const;
-export const GUILD_APPLICATION_COMMAND             = (applicationID: string, guildID: string, commandID: string) => `/applications/${applicationID}/guilds/${guildID}/commands/${commandID}` as const;
-export const GUILD_APPLICATION_COMMANDS            = (applicationID: string, guildID: string) => `/applications/${applicationID}/guilds/${guildID}/commands` as const;
-export const GUILD_APPLICATION_COMMAND_PERMISSION  = (applicationID: string, guildID: string, commandID: string) => `/applications/${applicationID}/guilds/${guildID}/commands/${commandID}/permissions` as const;
-export const GUILD_APPLICATION_COMMAND_PERMISSIONS = (applicationID: string, guildID: string) => `/applications/${applicationID}/guilds/${guildID}commands/permissions` as const;
-export const INTERACTION_CALLBACK                  = (interactionID: string, interactionToken: string) => `/interactions/${interactionID}/${interactionToken}/callback` as const;
-export const APPLICATION                           = "/applications/@me" as const;
-export const ENTITLEMENTS                          = (applicationID: string) => `/applications/${applicationID}/entitlements` as const;
-export const ENTITLEMENT                           = (applicationID: string, entitlementID: string) => `/applications/${applicationID}/entitlements/${entitlementID}` as const;
-export const SKUS                                  = (applicationID: string) => `/applications/${applicationID}/skus` as const;
+export const APPLICATION_COMMAND                   = (applicationID: string, commandID: string) => encode`/applications/${applicationID}/commands/${commandID}`;
+export const APPLICATION_COMMANDS                  = (applicationID: string) => encode`/applications/${applicationID}/commands`;
+export const GUILD_APPLICATION_COMMAND             = (applicationID: string, guildID: string, commandID: string) => encode`/applications/${applicationID}/guilds/${guildID}/commands/${commandID}`;
+export const GUILD_APPLICATION_COMMANDS            = (applicationID: string, guildID: string) => encode`/applications/${applicationID}/guilds/${guildID}/commands`;
+export const GUILD_APPLICATION_COMMAND_PERMISSION  = (applicationID: string, guildID: string, commandID: string) => encode`/applications/${applicationID}/guilds/${guildID}/commands/${commandID}/permissions`;
+export const GUILD_APPLICATION_COMMAND_PERMISSIONS = (applicationID: string, guildID: string) => encode`/applications/${applicationID}/guilds/${guildID}commands/permissions`;
+export const INTERACTION_CALLBACK                  = (interactionID: string, interactionToken: string) => encode`/interactions/${interactionID}/${interactionToken}/callback`;
+export const APPLICATION                           = "/applications/@me";
+export const ENTITLEMENTS                          = (applicationID: string) => encode`/applications/${applicationID}/entitlements`;
+export const ENTITLEMENT                           = (applicationID: string, entitlementID: string) => encode`/applications/${applicationID}/entitlements/${entitlementID}`;
+export const SKUS                                  = (applicationID: string) => encode`/applications/${applicationID}/skus`;
 
 // Misc
-export const GATEWAY                   = "/gateway" as const;
-export const GATEWAY_BOT               = "/gateway/bot" as const;
-export const USER                      = (userID: string) => `/users/${userID}` as const;
-export const MESSAGE_LINK              = (guildID: string, channelID: string, messageID: string) => `/channels/${guildID}/${channelID}/${messageID}` as const;
-export const STICKER_PACKS             = "/sticker-packs" as const;
-export const INVITE                    = (code: string) => `/invites/${code}` as const;
-export const STAGE_INSTANCES           = "/stage-instances" as const;
-export const STAGE_INSTANCE            = (channelID: string) => `/stage-instances/${channelID}` as const;
-export const REFRESH_ATTACHMENT_URLS   = "/attachments/refresh-urls" as const;
+export const GATEWAY                   = "/gateway";
+export const GATEWAY_BOT               = "/gateway/bot";
+export const USER                      = (userID: string) => encode`/users/${userID}`;
+export const MESSAGE_LINK              = (guildID: string, channelID: string, messageID: string) => encode`/channels/${guildID}/${channelID}/${messageID}`;
+export const STICKER_PACKS             = "/sticker-packs";
+export const INVITE                    = (code: string) => encode`/invites/${code}`;
+export const STAGE_INSTANCES           = "/stage-instances";
+export const STAGE_INSTANCE            = (channelID: string) => encode`/stage-instances/${channelID}`;
+export const REFRESH_ATTACHMENT_URLS   = "/attachments/refresh-urls";

programming_language: TypeScript