Skip to content

Commit fc4e7be

Browse files
committed
fix: skip encoded url parts from re-encoding
DJS or other users may already do a sanity encoding, so we dont need to re-encode
1 parent a81f311 commit fc4e7be

File tree

10 files changed

+170
-22
lines changed

10 files changed

+170
-22
lines changed

deno/rest/v10/mod.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Snowflake } from '../../globals.ts';
2+
import { urlSafeCharacters } from '../../utils/internals.ts';
23

34
export * from '../common.ts';
45
export * from './application.ts';
@@ -1056,7 +1057,18 @@ export const Routes = {
10561057

10571058
for (const [key, fn] of Object.entries(Routes)) {
10581059
Routes[key as keyof typeof Routes] = (...args: (boolean | number | string | undefined)[]) => {
1059-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1060+
const escaped = args.map((arg) => {
1061+
if (arg) {
1062+
// Skip already "safe" urls
1063+
if (urlSafeCharacters.test(String(arg))) {
1064+
return arg;
1065+
}
1066+
1067+
return encodeURIComponent(arg);
1068+
}
1069+
1070+
return arg;
1071+
});
10601072
// eslint-disable-next-line no-useless-call
10611073
return fn.call(null, ...escaped);
10621074
};
@@ -1363,8 +1375,19 @@ export const CDNRoutes = {
13631375
};
13641376

13651377
for (const [key, fn] of Object.entries(CDNRoutes)) {
1366-
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (number | string | undefined)[]) => {
1367-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1378+
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (boolean | number | string | undefined)[]) => {
1379+
const escaped = args.map((arg) => {
1380+
if (arg) {
1381+
// Skip already "safe" urls
1382+
if (urlSafeCharacters.test(String(arg))) {
1383+
return arg;
1384+
}
1385+
1386+
return encodeURIComponent(arg);
1387+
}
1388+
1389+
return arg;
1390+
});
13681391
// eslint-disable-next-line no-useless-call
13691392
return fn.call(null, ...escaped);
13701393
};

deno/rest/v6/mod.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { urlSafeCharacters } from '../../utils/internals.ts';
2+
13
export * from '../common.ts';
24

35
export * from './auditLog.ts';
@@ -521,8 +523,19 @@ export const Routes = {
521523
};
522524

523525
for (const [key, fn] of Object.entries(Routes)) {
524-
Routes[key] = (...args: string[]) => {
525-
const escaped = args.map((arg) => encodeURIComponent(arg));
526+
Routes[key] = (...args: (boolean | number | string | undefined)[]) => {
527+
const escaped = args.map((arg) => {
528+
if (arg) {
529+
// Skip already "safe" urls
530+
if (urlSafeCharacters.test(String(arg))) {
531+
return arg;
532+
}
533+
534+
return encodeURIComponent(arg);
535+
}
536+
537+
return arg;
538+
});
526539
// eslint-disable-next-line no-useless-call
527540
return fn.call(null, ...escaped);
528541
};

deno/rest/v8/mod.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Snowflake } from '../../globals.ts';
2+
import { urlSafeCharacters } from '../../utils/internals.ts';
23

34
export * from '../common.ts';
45

@@ -778,8 +779,19 @@ export const Routes = {
778779
};
779780

780781
for (const [key, fn] of Object.entries(Routes)) {
781-
Routes[key] = (...args: string[]) => {
782-
const escaped = args.map((arg) => encodeURIComponent(arg));
782+
Routes[key] = (...args: (boolean | number | string | undefined)[]) => {
783+
const escaped = args.map((arg) => {
784+
if (arg) {
785+
// Skip already "safe" urls
786+
if (urlSafeCharacters.test(String(arg))) {
787+
return arg;
788+
}
789+
790+
return encodeURIComponent(arg);
791+
}
792+
793+
return arg;
794+
});
783795
// eslint-disable-next-line no-useless-call
784796
return fn.call(null, ...escaped);
785797
};

deno/rest/v9/mod.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Snowflake } from '../../globals.ts';
2+
import { urlSafeCharacters } from '../../utils/internals.ts';
23

34
export * from '../common.ts';
45
export * from './application.ts';
@@ -1065,7 +1066,18 @@ export const Routes = {
10651066

10661067
for (const [key, fn] of Object.entries(Routes)) {
10671068
Routes[key as keyof typeof Routes] = (...args: (boolean | number | string | undefined)[]) => {
1068-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1069+
const escaped = args.map((arg) => {
1070+
if (arg) {
1071+
// Skip already "safe" urls
1072+
if (urlSafeCharacters.test(String(arg))) {
1073+
return arg;
1074+
}
1075+
1076+
return encodeURIComponent(arg);
1077+
}
1078+
1079+
return arg;
1080+
});
10691081
// eslint-disable-next-line no-useless-call
10701082
return fn.call(null, ...escaped);
10711083
};
@@ -1372,8 +1384,19 @@ export const CDNRoutes = {
13721384
};
13731385

13741386
for (const [key, fn] of Object.entries(CDNRoutes)) {
1375-
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (number | string | undefined)[]) => {
1376-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1387+
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (boolean | number | string | undefined)[]) => {
1388+
const escaped = args.map((arg) => {
1389+
if (arg) {
1390+
// Skip already "safe" urls
1391+
if (urlSafeCharacters.test(String(arg))) {
1392+
return arg;
1393+
}
1394+
1395+
return encodeURIComponent(arg);
1396+
}
1397+
1398+
return arg;
1399+
});
13771400
// eslint-disable-next-line no-useless-call
13781401
return fn.call(null, ...escaped);
13791402
};
@@ -1398,8 +1421,8 @@ export type ApplicationCoverFormat = Exclude<ImageFormat, ImageFormat.GIF | Imag
13981421
export type ApplicationAssetFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
13991422
export type AchievementIconFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14001423
export type StickerPackBannerFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
1401-
export type StorePageAssetFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14021424
export type TeamIconFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
1425+
export type StorePageAssetFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14031426
export type StickerFormat = Extract<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie | ImageFormat.PNG>;
14041427
export type RoleIconFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14051428
export type GuildScheduledEventCoverFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
@@ -1417,6 +1440,7 @@ export interface CDNQuery {
14171440
export const RouteBases = {
14181441
api: `https://discord.com/api/v${APIVersion}`,
14191442
cdn: 'https://cdn.discordapp.com',
1443+
media: 'https://media.discordapp.net',
14201444
invite: 'https://discord.gg',
14211445
template: 'https://discord.new',
14221446
gift: 'https://discord.gift',

deno/utils/internals.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ export type DistributiveOmit<T, K extends DistributiveKeys<T>> =
3939
T extends unknown ? { [P in keyof Omit_<T, K>]: Omit_<T, K>[P] } : never;
4040

4141
type Omit_<T, K> = Omit<T, Extract<keyof T, K>>;
42+
43+
export const urlSafeCharacters = /^[\d%A-Za-z-]+$/g;

rest/v10/index.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Snowflake } from '../../globals';
2+
import { urlSafeCharacters } from '../../utils/internals';
23

34
export * from '../common';
45
export * from './application';
@@ -1056,7 +1057,18 @@ export const Routes = {
10561057

10571058
for (const [key, fn] of Object.entries(Routes)) {
10581059
Routes[key as keyof typeof Routes] = (...args: (boolean | number | string | undefined)[]) => {
1059-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1060+
const escaped = args.map((arg) => {
1061+
if (arg) {
1062+
// Skip already "safe" urls
1063+
if (urlSafeCharacters.test(String(arg))) {
1064+
return arg;
1065+
}
1066+
1067+
return encodeURIComponent(arg);
1068+
}
1069+
1070+
return arg;
1071+
});
10601072
// eslint-disable-next-line no-useless-call
10611073
return fn.call(null, ...escaped);
10621074
};
@@ -1363,8 +1375,19 @@ export const CDNRoutes = {
13631375
};
13641376

13651377
for (const [key, fn] of Object.entries(CDNRoutes)) {
1366-
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (number | string | undefined)[]) => {
1367-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1378+
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (boolean | number | string | undefined)[]) => {
1379+
const escaped = args.map((arg) => {
1380+
if (arg) {
1381+
// Skip already "safe" urls
1382+
if (urlSafeCharacters.test(String(arg))) {
1383+
return arg;
1384+
}
1385+
1386+
return encodeURIComponent(arg);
1387+
}
1388+
1389+
return arg;
1390+
});
13681391
// eslint-disable-next-line no-useless-call
13691392
return fn.call(null, ...escaped);
13701393
};

rest/v6/index.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { urlSafeCharacters } from '../../utils/internals';
2+
13
export * from '../common';
24

35
export * from './auditLog';
@@ -521,8 +523,19 @@ export const Routes = {
521523
};
522524

523525
for (const [key, fn] of Object.entries(Routes)) {
524-
Routes[key] = (...args: string[]) => {
525-
const escaped = args.map((arg) => encodeURIComponent(arg));
526+
Routes[key] = (...args: (boolean | number | string | undefined)[]) => {
527+
const escaped = args.map((arg) => {
528+
if (arg) {
529+
// Skip already "safe" urls
530+
if (urlSafeCharacters.test(String(arg))) {
531+
return arg;
532+
}
533+
534+
return encodeURIComponent(arg);
535+
}
536+
537+
return arg;
538+
});
526539
// eslint-disable-next-line no-useless-call
527540
return fn.call(null, ...escaped);
528541
};

rest/v8/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Snowflake } from '../../globals';
2+
import { urlSafeCharacters } from '../../utils/internals';
23

34
export * from '../common';
45

@@ -778,8 +779,19 @@ export const Routes = {
778779
};
779780

780781
for (const [key, fn] of Object.entries(Routes)) {
781-
Routes[key] = (...args: string[]) => {
782-
const escaped = args.map((arg) => encodeURIComponent(arg));
782+
Routes[key] = (...args: (boolean | number | string | undefined)[]) => {
783+
const escaped = args.map((arg) => {
784+
if (arg) {
785+
// Skip already "safe" urls
786+
if (urlSafeCharacters.test(String(arg))) {
787+
return arg;
788+
}
789+
790+
return encodeURIComponent(arg);
791+
}
792+
793+
return arg;
794+
});
783795
// eslint-disable-next-line no-useless-call
784796
return fn.call(null, ...escaped);
785797
};

rest/v9/index.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Snowflake } from '../../globals';
2+
import { urlSafeCharacters } from '../../utils/internals';
23

34
export * from '../common';
45
export * from './application';
@@ -1065,7 +1066,18 @@ export const Routes = {
10651066

10661067
for (const [key, fn] of Object.entries(Routes)) {
10671068
Routes[key as keyof typeof Routes] = (...args: (boolean | number | string | undefined)[]) => {
1068-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1069+
const escaped = args.map((arg) => {
1070+
if (arg) {
1071+
// Skip already "safe" urls
1072+
if (urlSafeCharacters.test(String(arg))) {
1073+
return arg;
1074+
}
1075+
1076+
return encodeURIComponent(arg);
1077+
}
1078+
1079+
return arg;
1080+
});
10691081
// eslint-disable-next-line no-useless-call
10701082
return fn.call(null, ...escaped);
10711083
};
@@ -1372,8 +1384,19 @@ export const CDNRoutes = {
13721384
};
13731385

13741386
for (const [key, fn] of Object.entries(CDNRoutes)) {
1375-
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (number | string | undefined)[]) => {
1376-
const escaped = args.map((arg) => arg && encodeURIComponent(arg));
1387+
CDNRoutes[key as keyof typeof CDNRoutes] = (...args: (boolean | number | string | undefined)[]) => {
1388+
const escaped = args.map((arg) => {
1389+
if (arg) {
1390+
// Skip already "safe" urls
1391+
if (urlSafeCharacters.test(String(arg))) {
1392+
return arg;
1393+
}
1394+
1395+
return encodeURIComponent(arg);
1396+
}
1397+
1398+
return arg;
1399+
});
13771400
// eslint-disable-next-line no-useless-call
13781401
return fn.call(null, ...escaped);
13791402
};
@@ -1398,8 +1421,8 @@ export type ApplicationCoverFormat = Exclude<ImageFormat, ImageFormat.GIF | Imag
13981421
export type ApplicationAssetFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
13991422
export type AchievementIconFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14001423
export type StickerPackBannerFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
1401-
export type StorePageAssetFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14021424
export type TeamIconFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
1425+
export type StorePageAssetFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14031426
export type StickerFormat = Extract<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie | ImageFormat.PNG>;
14041427
export type RoleIconFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
14051428
export type GuildScheduledEventCoverFormat = Exclude<ImageFormat, ImageFormat.GIF | ImageFormat.Lottie>;
@@ -1417,6 +1440,7 @@ export interface CDNQuery {
14171440
export const RouteBases = {
14181441
api: `https://discord.com/api/v${APIVersion}`,
14191442
cdn: 'https://cdn.discordapp.com',
1443+
media: 'https://media.discordapp.net',
14201444
invite: 'https://discord.gg',
14211445
template: 'https://discord.new',
14221446
gift: 'https://discord.gift',

utils/internals.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ export type DistributiveOmit<T, K extends DistributiveKeys<T>> =
3939
T extends unknown ? { [P in keyof Omit_<T, K>]: Omit_<T, K>[P] } : never;
4040

4141
type Omit_<T, K> = Omit<T, Extract<keyof T, K>>;
42+
43+
export const urlSafeCharacters = /^[\d%A-Za-z-]+$/g;

0 commit comments

Comments
 (0)