@discordjs/proxy 1.1.0-dev.1658103010-dda2895 → 1.1.0-dev.1660478704-bc06cc6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +16 -13
- package/dist/handlers/proxyRequests.cjs +46 -0
- package/dist/handlers/proxyRequests.cjs.map +1 -0
- package/dist/handlers/proxyRequests.d.ts +9 -0
- package/dist/handlers/proxyRequests.d.ts.map +1 -0
- package/dist/handlers/proxyRequests.mjs +42 -0
- package/dist/handlers/proxyRequests.mjs.map +1 -0
- package/dist/index.cjs +15 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -49
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +3 -83
- package/dist/index.mjs.map +1 -1
- package/dist/util/responseHelpers.cjs +37 -0
- package/dist/util/responseHelpers.cjs.map +1 -0
- package/dist/util/responseHelpers.d.ts +32 -0
- package/dist/util/responseHelpers.d.ts.map +1 -0
- package/dist/util/responseHelpers.mjs +30 -0
- package/dist/util/responseHelpers.mjs.map +1 -0
- package/dist/util/util.d.ts +11 -0
- package/dist/util/util.d.ts.map +1 -0
- package/package.json +19 -18
- package/dist/index.js +0 -112
- package/dist/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
# [@discordjs/proxy@1.
|
|
5
|
+
# [@discordjs/proxy@1.0.0](https://github.com/discordjs/discord.js/tree/@discordjs/proxy@1.1.0) - (2022-07-17)
|
|
6
6
|
|
|
7
7
|
## Bug Fixes
|
|
8
8
|
|
package/README.md
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
<br />
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://discord.js.org"><img src="https://discord.js.org/static/logo.svg" width="546" alt="discord.js" /></a>
|
|
5
|
+
</p>
|
|
6
|
+
<br />
|
|
7
|
+
<p>
|
|
8
|
+
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@discordjs/proxy"><img src="https://img.shields.io/npm/v/@discordjs/proxy.svg?maxAge=3600" alt="npm version" /></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/@discordjs/proxy"><img src="https://img.shields.io/npm/dt/@discordjs/proxy.svg?maxAge=3600" alt="npm downloads" /></a>
|
|
11
|
+
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
|
|
12
|
+
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=proxy" alt="Code coverage" /></a>
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
|
|
16
|
+
</p>
|
|
14
17
|
</div>
|
|
15
18
|
|
|
16
19
|
## About
|
|
@@ -32,7 +35,7 @@ pnpm add @discordjs/proxy
|
|
|
32
35
|
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/discord.js/tree/main/packages/website))
|
|
33
36
|
- [Documentation](https://discord.js.org/#/docs/proxy)
|
|
34
37
|
- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide))
|
|
35
|
-
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-
|
|
38
|
+
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v14.html), including updated and removed items in the library.
|
|
36
39
|
- [discord.js Discord server](https://discord.gg/djs)
|
|
37
40
|
- [Discord API Discord server](https://discord.gg/discord-api)
|
|
38
41
|
- [GitHub](https://github.com/discordjs/discord.js/tree/main/packages/proxy)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const node_url = require('node:url');
|
|
6
|
+
const rest = require('@discordjs/rest');
|
|
7
|
+
const responseHelpers = require('../util/responseHelpers.cjs');
|
|
8
|
+
|
|
9
|
+
function proxyRequests(rest$1) {
|
|
10
|
+
return async (req, res) => {
|
|
11
|
+
const { method, url } = req;
|
|
12
|
+
if (!method || !url) {
|
|
13
|
+
throw new TypeError(
|
|
14
|
+
"Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage"
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
const fullRoute = new node_url.URL(url, "http://noop").pathname.replace(/^\/api(\/v\d+)?/, "");
|
|
18
|
+
try {
|
|
19
|
+
const discordResponse = await rest$1.raw({
|
|
20
|
+
body: req,
|
|
21
|
+
fullRoute,
|
|
22
|
+
method,
|
|
23
|
+
passThroughBody: true,
|
|
24
|
+
headers: {
|
|
25
|
+
"Content-Type": req.headers["content-type"]
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
await responseHelpers.populateSuccessfulResponse(res, discordResponse);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (error instanceof rest.DiscordAPIError || error instanceof rest.HTTPError) {
|
|
31
|
+
responseHelpers.populateGeneralErrorResponse(res, error);
|
|
32
|
+
} else if (error instanceof rest.RateLimitError) {
|
|
33
|
+
responseHelpers.populateRatelimitErrorResponse(res, error);
|
|
34
|
+
} else if (error instanceof Error && error.name === "AbortError") {
|
|
35
|
+
responseHelpers.populateAbortErrorResponse(res);
|
|
36
|
+
} else {
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
} finally {
|
|
40
|
+
res.end();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
exports.proxyRequests = proxyRequests;
|
|
46
|
+
//# sourceMappingURL=proxyRequests.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyRequests.cjs","sources":["../../src/handlers/proxyRequests.ts"],"sourcesContent":["import { URL } from 'node:url';\nimport { DiscordAPIError, HTTPError, RateLimitError, RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport {\n\tpopulateAbortErrorResponse,\n\tpopulateGeneralErrorResponse,\n\tpopulateSuccessfulResponse,\n\tpopulateRatelimitErrorResponse,\n} from '../util/responseHelpers';\nimport type { RequestHandler } from '../util/util';\n\n/**\n * Creates an HTTP handler used to forward requests to Discord\n *\n * @param rest - REST instance to use for the requests\n */\nexport function proxyRequests(rest: REST): RequestHandler {\n\treturn async (req, res) => {\n\t\tconst { method, url } = req;\n\n\t\tif (!method || !url) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage',\n\t\t\t);\n\t\t}\n\n\t\t// The 2nd parameter is here so the URL constructor doesn't complain about an \"invalid url\" when the origin is missing\n\t\t// we don't actually care about the origin and the value passed is irrelevant\n\t\tconst fullRoute = new URL(url, 'http://noop').pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.raw({\n\t\t\t\tbody: req,\n\t\t\t\tfullRoute,\n\t\t\t\t// This type cast is technically incorrect, but we want Discord to throw Method Not Allowed for us\n\t\t\t\tmethod: method as RequestMethod,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\t\t\tpopulateGeneralErrorResponse(res, error);\n\t\t\t} else if (error instanceof RateLimitError) {\n\t\t\t\tpopulateRatelimitErrorResponse(res, error);\n\t\t\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\t\t\tpopulateAbortErrorResponse(res);\n\t\t\t} else {\n\t\t\t\t// Unclear if there's better course of action here for unknown erorrs. Any web framework allows to pass in an error handler for something like this\n\t\t\t\t// at which point the user could dictate what to do with the error - otherwise we could just 500\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} finally {\n\t\t\tres.end();\n\t\t}\n\t};\n}\n"],"names":["rest","URL","populateSuccessfulResponse","DiscordAPIError","HTTPError","populateGeneralErrorResponse","RateLimitError","populateRatelimitErrorResponse","populateAbortErrorResponse"],"mappings":";;;;;;;;AAQO,SAAS,aAAa,CAACA,MAAI,EAAE;AACpC,EAAE,OAAO,OAAO,GAAG,EAAE,GAAG,KAAK;AAC7B,IAAI,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;AAChC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE;AACzB,MAAM,MAAM,IAAI,SAAS;AACzB,QAAQ,+FAA+F;AACvG,OAAO,CAAC;AACR,KAAK;AACL,IAAI,MAAM,SAAS,GAAG,IAAIC,YAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;AAC1F,IAAI,IAAI;AACR,MAAM,MAAM,eAAe,GAAG,MAAMD,MAAI,CAAC,GAAG,CAAC;AAC7C,QAAQ,IAAI,EAAE,GAAG;AACjB,QAAQ,SAAS;AACjB,QAAQ,MAAM;AACd,QAAQ,eAAe,EAAE,IAAI;AAC7B,QAAQ,OAAO,EAAE;AACjB,UAAU,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;AACrD,SAAS;AACT,OAAO,CAAC,CAAC;AACT,MAAM,MAAME,0CAA0B,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;AAC7D,KAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAM,IAAI,KAAK,YAAYC,oBAAe,IAAI,KAAK,YAAYC,cAAS,EAAE;AAC1E,QAAQC,4CAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACjD,OAAO,MAAM,IAAI,KAAK,YAAYC,mBAAc,EAAE;AAClD,QAAQC,8CAA8B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACnD,OAAO,MAAM,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE;AACxE,QAAQC,0CAA0B,CAAC,GAAG,CAAC,CAAC;AACxC,OAAO,MAAM;AACb,QAAQ,MAAM,KAAK,CAAC;AACpB,OAAO;AACP,KAAK,SAAS;AACd,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;AAChB,KAAK;AACL,GAAG,CAAC;AACJ;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { REST } from '@discordjs/rest';
|
|
2
|
+
import type { RequestHandler } from '../util/util';
|
|
3
|
+
/**
|
|
4
|
+
* Creates an HTTP handler used to forward requests to Discord
|
|
5
|
+
*
|
|
6
|
+
* @param rest - REST instance to use for the requests
|
|
7
|
+
*/
|
|
8
|
+
export declare function proxyRequests(rest: REST): RequestHandler;
|
|
9
|
+
//# sourceMappingURL=proxyRequests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyRequests.d.ts","sourceRoot":"","sources":["../../src/handlers/proxyRequests.ts"],"names":[],"mappings":"AACA,OAAO,EAA6D,IAAI,EAAa,MAAM,iBAAiB,CAAC;AAO7G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,CA2CxD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { URL } from 'node:url';
|
|
2
|
+
import { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';
|
|
3
|
+
import { populateSuccessfulResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateAbortErrorResponse } from '../util/responseHelpers.mjs';
|
|
4
|
+
|
|
5
|
+
function proxyRequests(rest) {
|
|
6
|
+
return async (req, res) => {
|
|
7
|
+
const { method, url } = req;
|
|
8
|
+
if (!method || !url) {
|
|
9
|
+
throw new TypeError(
|
|
10
|
+
"Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage"
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
const fullRoute = new URL(url, "http://noop").pathname.replace(/^\/api(\/v\d+)?/, "");
|
|
14
|
+
try {
|
|
15
|
+
const discordResponse = await rest.raw({
|
|
16
|
+
body: req,
|
|
17
|
+
fullRoute,
|
|
18
|
+
method,
|
|
19
|
+
passThroughBody: true,
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": req.headers["content-type"]
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
await populateSuccessfulResponse(res, discordResponse);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (error instanceof DiscordAPIError || error instanceof HTTPError) {
|
|
27
|
+
populateGeneralErrorResponse(res, error);
|
|
28
|
+
} else if (error instanceof RateLimitError) {
|
|
29
|
+
populateRatelimitErrorResponse(res, error);
|
|
30
|
+
} else if (error instanceof Error && error.name === "AbortError") {
|
|
31
|
+
populateAbortErrorResponse(res);
|
|
32
|
+
} else {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
} finally {
|
|
36
|
+
res.end();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { proxyRequests };
|
|
42
|
+
//# sourceMappingURL=proxyRequests.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyRequests.mjs","sources":["../../src/handlers/proxyRequests.ts"],"sourcesContent":["import { URL } from 'node:url';\nimport { DiscordAPIError, HTTPError, RateLimitError, RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport {\n\tpopulateAbortErrorResponse,\n\tpopulateGeneralErrorResponse,\n\tpopulateSuccessfulResponse,\n\tpopulateRatelimitErrorResponse,\n} from '../util/responseHelpers';\nimport type { RequestHandler } from '../util/util';\n\n/**\n * Creates an HTTP handler used to forward requests to Discord\n *\n * @param rest - REST instance to use for the requests\n */\nexport function proxyRequests(rest: REST): RequestHandler {\n\treturn async (req, res) => {\n\t\tconst { method, url } = req;\n\n\t\tif (!method || !url) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage',\n\t\t\t);\n\t\t}\n\n\t\t// The 2nd parameter is here so the URL constructor doesn't complain about an \"invalid url\" when the origin is missing\n\t\t// we don't actually care about the origin and the value passed is irrelevant\n\t\tconst fullRoute = new URL(url, 'http://noop').pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.raw({\n\t\t\t\tbody: req,\n\t\t\t\tfullRoute,\n\t\t\t\t// This type cast is technically incorrect, but we want Discord to throw Method Not Allowed for us\n\t\t\t\tmethod: method as RequestMethod,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\t\t\tpopulateGeneralErrorResponse(res, error);\n\t\t\t} else if (error instanceof RateLimitError) {\n\t\t\t\tpopulateRatelimitErrorResponse(res, error);\n\t\t\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\t\t\tpopulateAbortErrorResponse(res);\n\t\t\t} else {\n\t\t\t\t// Unclear if there's better course of action here for unknown erorrs. Any web framework allows to pass in an error handler for something like this\n\t\t\t\t// at which point the user could dictate what to do with the error - otherwise we could just 500\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} finally {\n\t\t\tres.end();\n\t\t}\n\t};\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,aAAa,CAAC,IAAI,EAAE;AACpC,EAAE,OAAO,OAAO,GAAG,EAAE,GAAG,KAAK;AAC7B,IAAI,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;AAChC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE;AACzB,MAAM,MAAM,IAAI,SAAS;AACzB,QAAQ,+FAA+F;AACvG,OAAO,CAAC;AACR,KAAK;AACL,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;AAC1F,IAAI,IAAI;AACR,MAAM,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC;AAC7C,QAAQ,IAAI,EAAE,GAAG;AACjB,QAAQ,SAAS;AACjB,QAAQ,MAAM;AACd,QAAQ,eAAe,EAAE,IAAI;AAC7B,QAAQ,OAAO,EAAE;AACjB,UAAU,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;AACrD,SAAS;AACT,OAAO,CAAC,CAAC;AACT,MAAM,MAAM,0BAA0B,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;AAC7D,KAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAM,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,YAAY,SAAS,EAAE;AAC1E,QAAQ,4BAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACjD,OAAO,MAAM,IAAI,KAAK,YAAY,cAAc,EAAE;AAClD,QAAQ,8BAA8B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACnD,OAAO,MAAM,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE;AACxE,QAAQ,0BAA0B,CAAC,GAAG,CAAC,CAAC;AACxC,OAAO,MAAM;AACb,QAAQ,MAAM,KAAK,CAAC;AACpB,OAAO;AACP,KAAK,SAAS;AACd,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;AAChB,KAAK;AACL,GAAG,CAAC;AACJ;;;;"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const proxyRequests = require('./handlers/proxyRequests.cjs');
|
|
6
|
+
const responseHelpers = require('./util/responseHelpers.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.proxyRequests = proxyRequests.proxyRequests;
|
|
11
|
+
exports.populateAbortErrorResponse = responseHelpers.populateAbortErrorResponse;
|
|
12
|
+
exports.populateGeneralErrorResponse = responseHelpers.populateGeneralErrorResponse;
|
|
13
|
+
exports.populateRatelimitErrorResponse = responseHelpers.populateRatelimitErrorResponse;
|
|
14
|
+
exports.populateSuccessfulResponse = responseHelpers.populateSuccessfulResponse;
|
|
15
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,49 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Represents a potentially awaitable value
|
|
7
|
-
*/
|
|
8
|
-
declare type Awaitable<T> = T | PromiseLike<T>;
|
|
9
|
-
/**
|
|
10
|
-
* Represents a simple HTTP request handler
|
|
11
|
-
*/
|
|
12
|
-
declare type RequestHandler = (req: IncomingMessage, res: ServerResponse) => Awaitable<void>;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Creates an HTTP handler used to forward requests to Discord
|
|
16
|
-
*
|
|
17
|
-
* @param rest - REST instance to use for the requests
|
|
18
|
-
*/
|
|
19
|
-
declare function proxyRequests(rest: REST): RequestHandler;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Populates a server response with the data from a Discord 2xx REST response
|
|
23
|
-
*
|
|
24
|
-
* @param res - The server response to populate
|
|
25
|
-
* @param data - The data to populate the response with
|
|
26
|
-
*/
|
|
27
|
-
declare function populateSuccessfulResponse(res: ServerResponse, data: Dispatcher.ResponseData): Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
* Populates a server response with the data from a Discord non-2xx REST response that is NOT a 429
|
|
30
|
-
*
|
|
31
|
-
* @param res - The server response to populate
|
|
32
|
-
* @param error - The error to populate the response with
|
|
33
|
-
*/
|
|
34
|
-
declare function populateGeneralErrorResponse(res: ServerResponse, error: DiscordAPIError | HTTPError): void;
|
|
35
|
-
/**
|
|
36
|
-
* Populates a server response with the data from a Discord 429 REST response
|
|
37
|
-
*
|
|
38
|
-
* @param res - The server response to populate
|
|
39
|
-
* @param error - The error to populate the response with
|
|
40
|
-
*/
|
|
41
|
-
declare function populateRatelimitErrorResponse(res: ServerResponse, error: RateLimitError): void;
|
|
42
|
-
/**
|
|
43
|
-
* Populates a server response with data relevant for a timeout
|
|
44
|
-
*
|
|
45
|
-
* @param res - The sever response to populate
|
|
46
|
-
*/
|
|
47
|
-
declare function populateAbortErrorResponse(res: ServerResponse): void;
|
|
48
|
-
|
|
49
|
-
export { RequestHandler, populateAbortErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse, proxyRequests };
|
|
1
|
+
export * from './handlers/proxyRequests';
|
|
2
|
+
export * from './util/responseHelpers';
|
|
3
|
+
export type { RequestHandler } from './util/util';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,83 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// src/handlers/proxyRequests.ts
|
|
6
|
-
import { URL } from "node:url";
|
|
7
|
-
import { DiscordAPIError, HTTPError, RateLimitError } from "@discordjs/rest";
|
|
8
|
-
|
|
9
|
-
// src/util/responseHelpers.ts
|
|
10
|
-
import { pipeline } from "node:stream/promises";
|
|
11
|
-
async function populateSuccessfulResponse(res, data) {
|
|
12
|
-
res.statusCode = data.statusCode;
|
|
13
|
-
for (const header of Object.keys(data.headers)) {
|
|
14
|
-
if (header.startsWith("x-ratelimit")) {
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
res.setHeader(header, data.headers[header]);
|
|
18
|
-
}
|
|
19
|
-
await pipeline(data.body, res);
|
|
20
|
-
}
|
|
21
|
-
__name(populateSuccessfulResponse, "populateSuccessfulResponse");
|
|
22
|
-
function populateGeneralErrorResponse(res, error) {
|
|
23
|
-
res.statusCode = error.status;
|
|
24
|
-
if ("rawError" in error) {
|
|
25
|
-
res.setHeader("Content-Type", "application/json");
|
|
26
|
-
res.write(JSON.stringify(error.rawError));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
__name(populateGeneralErrorResponse, "populateGeneralErrorResponse");
|
|
30
|
-
function populateRatelimitErrorResponse(res, error) {
|
|
31
|
-
res.statusCode = 429;
|
|
32
|
-
res.setHeader("Retry-After", error.timeToReset / 1e3);
|
|
33
|
-
}
|
|
34
|
-
__name(populateRatelimitErrorResponse, "populateRatelimitErrorResponse");
|
|
35
|
-
function populateAbortErrorResponse(res) {
|
|
36
|
-
res.statusCode = 504;
|
|
37
|
-
res.statusMessage = "Upstream timed out";
|
|
38
|
-
}
|
|
39
|
-
__name(populateAbortErrorResponse, "populateAbortErrorResponse");
|
|
40
|
-
|
|
41
|
-
// src/handlers/proxyRequests.ts
|
|
42
|
-
function proxyRequests(rest) {
|
|
43
|
-
return async (req, res) => {
|
|
44
|
-
const { method, url } = req;
|
|
45
|
-
if (!method || !url) {
|
|
46
|
-
throw new TypeError("Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage");
|
|
47
|
-
}
|
|
48
|
-
const fullRoute = new URL(url, "http://noop").pathname.replace(/^\/api(\/v\d+)?/, "");
|
|
49
|
-
try {
|
|
50
|
-
const discordResponse = await rest.raw({
|
|
51
|
-
body: req,
|
|
52
|
-
fullRoute,
|
|
53
|
-
method,
|
|
54
|
-
passThroughBody: true,
|
|
55
|
-
headers: {
|
|
56
|
-
"Content-Type": req.headers["content-type"]
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
await populateSuccessfulResponse(res, discordResponse);
|
|
60
|
-
} catch (error) {
|
|
61
|
-
if (error instanceof DiscordAPIError || error instanceof HTTPError) {
|
|
62
|
-
populateGeneralErrorResponse(res, error);
|
|
63
|
-
} else if (error instanceof RateLimitError) {
|
|
64
|
-
populateRatelimitErrorResponse(res, error);
|
|
65
|
-
} else if (error instanceof Error && error.name === "AbortError") {
|
|
66
|
-
populateAbortErrorResponse(res);
|
|
67
|
-
} else {
|
|
68
|
-
throw error;
|
|
69
|
-
}
|
|
70
|
-
} finally {
|
|
71
|
-
res.end();
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
__name(proxyRequests, "proxyRequests");
|
|
76
|
-
export {
|
|
77
|
-
populateAbortErrorResponse,
|
|
78
|
-
populateGeneralErrorResponse,
|
|
79
|
-
populateRatelimitErrorResponse,
|
|
80
|
-
populateSuccessfulResponse,
|
|
81
|
-
proxyRequests
|
|
82
|
-
};
|
|
83
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export { proxyRequests } from './handlers/proxyRequests.mjs';
|
|
2
|
+
export { populateAbortErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse } from './util/responseHelpers.mjs';
|
|
3
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const promises = require('node:stream/promises');
|
|
6
|
+
|
|
7
|
+
async function populateSuccessfulResponse(res, data) {
|
|
8
|
+
res.statusCode = data.statusCode;
|
|
9
|
+
for (const header of Object.keys(data.headers)) {
|
|
10
|
+
if (header.startsWith("x-ratelimit")) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
res.setHeader(header, data.headers[header]);
|
|
14
|
+
}
|
|
15
|
+
await promises.pipeline(data.body, res);
|
|
16
|
+
}
|
|
17
|
+
function populateGeneralErrorResponse(res, error) {
|
|
18
|
+
res.statusCode = error.status;
|
|
19
|
+
if ("rawError" in error) {
|
|
20
|
+
res.setHeader("Content-Type", "application/json");
|
|
21
|
+
res.write(JSON.stringify(error.rawError));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function populateRatelimitErrorResponse(res, error) {
|
|
25
|
+
res.statusCode = 429;
|
|
26
|
+
res.setHeader("Retry-After", error.timeToReset / 1e3);
|
|
27
|
+
}
|
|
28
|
+
function populateAbortErrorResponse(res) {
|
|
29
|
+
res.statusCode = 504;
|
|
30
|
+
res.statusMessage = "Upstream timed out";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.populateAbortErrorResponse = populateAbortErrorResponse;
|
|
34
|
+
exports.populateGeneralErrorResponse = populateGeneralErrorResponse;
|
|
35
|
+
exports.populateRatelimitErrorResponse = populateRatelimitErrorResponse;
|
|
36
|
+
exports.populateSuccessfulResponse = populateSuccessfulResponse;
|
|
37
|
+
//# sourceMappingURL=responseHelpers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responseHelpers.cjs","sources":["../../src/util/responseHelpers.ts"],"sourcesContent":["import type { ServerResponse } from 'node:http';\nimport { pipeline } from 'node:stream/promises';\nimport type { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';\nimport type { Dispatcher } from 'undici';\n\n/**\n * Populates a server response with the data from a Discord 2xx REST response\n *\n * @param res - The server response to populate\n * @param data - The data to populate the response with\n */\nexport async function populateSuccessfulResponse(res: ServerResponse, data: Dispatcher.ResponseData): Promise<void> {\n\tres.statusCode = data.statusCode;\n\n\tfor (const header of Object.keys(data.headers)) {\n\t\t// Strip ratelimit headers\n\t\tif (header.startsWith('x-ratelimit')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, data.headers[header]!);\n\t}\n\n\tawait pipeline(data.body, res);\n}\n\n/**\n * Populates a server response with the data from a Discord non-2xx REST response that is NOT a 429\n *\n * @param res - The server response to populate\n * @param error - The error to populate the response with\n */\nexport function populateGeneralErrorResponse(res: ServerResponse, error: DiscordAPIError | HTTPError): void {\n\tres.statusCode = error.status;\n\n\tif ('rawError' in error) {\n\t\tres.setHeader('Content-Type', 'application/json');\n\t\tres.write(JSON.stringify(error.rawError));\n\t}\n}\n\n/**\n * Populates a server response with the data from a Discord 429 REST response\n *\n * @param res - The server response to populate\n * @param error - The error to populate the response with\n */\nexport function populateRatelimitErrorResponse(res: ServerResponse, error: RateLimitError): void {\n\tres.statusCode = 429;\n\tres.setHeader('Retry-After', error.timeToReset / 1000);\n}\n\n/**\n * Populates a server response with data relevant for a timeout\n *\n * @param res - The sever response to populate\n */\nexport function populateAbortErrorResponse(res: ServerResponse): void {\n\tres.statusCode = 504;\n\tres.statusMessage = 'Upstream timed out';\n}\n"],"names":["pipeline"],"mappings":";;;;;;AACO,eAAe,0BAA0B,CAAC,GAAG,EAAE,IAAI,EAAE;AAC5D,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;AACnC,EAAE,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AAClD,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;AAC1C,MAAM,SAAS;AACf,KAAK;AACL,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAChD,GAAG;AACH,EAAE,MAAMA,iBAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AACM,SAAS,4BAA4B,CAAC,GAAG,EAAE,KAAK,EAAE;AACzD,EAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;AAChC,EAAE,IAAI,UAAU,IAAI,KAAK,EAAE;AAC3B,IAAI,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;AACtD,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9C,GAAG;AACH,CAAC;AACM,SAAS,8BAA8B,CAAC,GAAG,EAAE,KAAK,EAAE;AAC3D,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;AACvB,EAAE,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;AACxD,CAAC;AACM,SAAS,0BAA0B,CAAC,GAAG,EAAE;AAChD,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;AACvB,EAAE,GAAG,CAAC,aAAa,GAAG,oBAAoB,CAAC;AAC3C;;;;;;;"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { ServerResponse } from 'node:http';
|
|
3
|
+
import type { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';
|
|
4
|
+
import type { Dispatcher } from 'undici';
|
|
5
|
+
/**
|
|
6
|
+
* Populates a server response with the data from a Discord 2xx REST response
|
|
7
|
+
*
|
|
8
|
+
* @param res - The server response to populate
|
|
9
|
+
* @param data - The data to populate the response with
|
|
10
|
+
*/
|
|
11
|
+
export declare function populateSuccessfulResponse(res: ServerResponse, data: Dispatcher.ResponseData): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Populates a server response with the data from a Discord non-2xx REST response that is NOT a 429
|
|
14
|
+
*
|
|
15
|
+
* @param res - The server response to populate
|
|
16
|
+
* @param error - The error to populate the response with
|
|
17
|
+
*/
|
|
18
|
+
export declare function populateGeneralErrorResponse(res: ServerResponse, error: DiscordAPIError | HTTPError): void;
|
|
19
|
+
/**
|
|
20
|
+
* Populates a server response with the data from a Discord 429 REST response
|
|
21
|
+
*
|
|
22
|
+
* @param res - The server response to populate
|
|
23
|
+
* @param error - The error to populate the response with
|
|
24
|
+
*/
|
|
25
|
+
export declare function populateRatelimitErrorResponse(res: ServerResponse, error: RateLimitError): void;
|
|
26
|
+
/**
|
|
27
|
+
* Populates a server response with data relevant for a timeout
|
|
28
|
+
*
|
|
29
|
+
* @param res - The sever response to populate
|
|
30
|
+
*/
|
|
31
|
+
export declare function populateAbortErrorResponse(res: ServerResponse): void;
|
|
32
|
+
//# sourceMappingURL=responseHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responseHelpers.d.ts","sourceRoot":"","sources":["../../src/util/responseHelpers.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,CAAC,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAalH;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAO1G;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAG/F;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAGpE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { pipeline } from 'node:stream/promises';
|
|
2
|
+
|
|
3
|
+
async function populateSuccessfulResponse(res, data) {
|
|
4
|
+
res.statusCode = data.statusCode;
|
|
5
|
+
for (const header of Object.keys(data.headers)) {
|
|
6
|
+
if (header.startsWith("x-ratelimit")) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
res.setHeader(header, data.headers[header]);
|
|
10
|
+
}
|
|
11
|
+
await pipeline(data.body, res);
|
|
12
|
+
}
|
|
13
|
+
function populateGeneralErrorResponse(res, error) {
|
|
14
|
+
res.statusCode = error.status;
|
|
15
|
+
if ("rawError" in error) {
|
|
16
|
+
res.setHeader("Content-Type", "application/json");
|
|
17
|
+
res.write(JSON.stringify(error.rawError));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function populateRatelimitErrorResponse(res, error) {
|
|
21
|
+
res.statusCode = 429;
|
|
22
|
+
res.setHeader("Retry-After", error.timeToReset / 1e3);
|
|
23
|
+
}
|
|
24
|
+
function populateAbortErrorResponse(res) {
|
|
25
|
+
res.statusCode = 504;
|
|
26
|
+
res.statusMessage = "Upstream timed out";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { populateAbortErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse };
|
|
30
|
+
//# sourceMappingURL=responseHelpers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responseHelpers.mjs","sources":["../../src/util/responseHelpers.ts"],"sourcesContent":["import type { ServerResponse } from 'node:http';\nimport { pipeline } from 'node:stream/promises';\nimport type { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';\nimport type { Dispatcher } from 'undici';\n\n/**\n * Populates a server response with the data from a Discord 2xx REST response\n *\n * @param res - The server response to populate\n * @param data - The data to populate the response with\n */\nexport async function populateSuccessfulResponse(res: ServerResponse, data: Dispatcher.ResponseData): Promise<void> {\n\tres.statusCode = data.statusCode;\n\n\tfor (const header of Object.keys(data.headers)) {\n\t\t// Strip ratelimit headers\n\t\tif (header.startsWith('x-ratelimit')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, data.headers[header]!);\n\t}\n\n\tawait pipeline(data.body, res);\n}\n\n/**\n * Populates a server response with the data from a Discord non-2xx REST response that is NOT a 429\n *\n * @param res - The server response to populate\n * @param error - The error to populate the response with\n */\nexport function populateGeneralErrorResponse(res: ServerResponse, error: DiscordAPIError | HTTPError): void {\n\tres.statusCode = error.status;\n\n\tif ('rawError' in error) {\n\t\tres.setHeader('Content-Type', 'application/json');\n\t\tres.write(JSON.stringify(error.rawError));\n\t}\n}\n\n/**\n * Populates a server response with the data from a Discord 429 REST response\n *\n * @param res - The server response to populate\n * @param error - The error to populate the response with\n */\nexport function populateRatelimitErrorResponse(res: ServerResponse, error: RateLimitError): void {\n\tres.statusCode = 429;\n\tres.setHeader('Retry-After', error.timeToReset / 1000);\n}\n\n/**\n * Populates a server response with data relevant for a timeout\n *\n * @param res - The sever response to populate\n */\nexport function populateAbortErrorResponse(res: ServerResponse): void {\n\tres.statusCode = 504;\n\tres.statusMessage = 'Upstream timed out';\n}\n"],"names":[],"mappings":";;AACO,eAAe,0BAA0B,CAAC,GAAG,EAAE,IAAI,EAAE;AAC5D,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;AACnC,EAAE,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AAClD,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;AAC1C,MAAM,SAAS;AACf,KAAK;AACL,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAChD,GAAG;AACH,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AACM,SAAS,4BAA4B,CAAC,GAAG,EAAE,KAAK,EAAE;AACzD,EAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;AAChC,EAAE,IAAI,UAAU,IAAI,KAAK,EAAE;AAC3B,IAAI,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;AACtD,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9C,GAAG;AACH,CAAC;AACM,SAAS,8BAA8B,CAAC,GAAG,EAAE,KAAK,EAAE;AAC3D,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;AACvB,EAAE,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;AACxD,CAAC;AACM,SAAS,0BAA0B,CAAC,GAAG,EAAE;AAChD,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;AACvB,EAAE,GAAG,CAAC,aAAa,GAAG,oBAAoB,CAAC;AAC3C;;;;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a potentially awaitable value
|
|
5
|
+
*/
|
|
6
|
+
export declare type Awaitable<T> = T | PromiseLike<T>;
|
|
7
|
+
/**
|
|
8
|
+
* Represents a simple HTTP request handler
|
|
9
|
+
*/
|
|
10
|
+
export declare type RequestHandler = (req: IncomingMessage, res: ServerResponse) => Awaitable<void>;
|
|
11
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util/util.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE;;GAEG;AACH,oBAAY,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AAE9C;;GAEG;AACH,oBAAY,cAAc,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discordjs/proxy",
|
|
3
|
-
"version": "1.1.0-dev.
|
|
3
|
+
"version": "1.1.0-dev.1660478704-bc06cc6.0",
|
|
4
4
|
"description": "Tools for running an HTTP proxy for Discord's API",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "vitest run",
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "unbuild",
|
|
8
8
|
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
|
|
9
9
|
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"fmt": "yarn format",
|
|
11
|
+
"docs": "downlevel-dts . docs --to=3.7 && docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
|
|
12
|
+
"prepack": "yarn lint && yarn test && yarn build",
|
|
12
13
|
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/proxy/*'",
|
|
13
14
|
"release": "cliff-jumper"
|
|
14
15
|
},
|
|
15
|
-
"main": "./dist/index.
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
16
17
|
"module": "./dist/index.mjs",
|
|
17
18
|
"typings": "./dist/index.d.ts",
|
|
18
19
|
"exports": {
|
|
19
20
|
"import": "./dist/index.mjs",
|
|
20
|
-
"require": "./dist/index.
|
|
21
|
+
"require": "./dist/index.cjs",
|
|
21
22
|
"types": "./dist/index.d.ts"
|
|
22
23
|
},
|
|
23
24
|
"directories": {
|
|
@@ -55,28 +56,28 @@
|
|
|
55
56
|
"dependencies": {
|
|
56
57
|
"@discordjs/rest": "^1.0.0",
|
|
57
58
|
"tslib": "^2.4.0",
|
|
58
|
-
"undici": "^5.
|
|
59
|
+
"undici": "^5.8.2"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
|
-
"@discordjs/docgen": "^0.12.0
|
|
62
|
-
"@
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@types/node": "^16.11.45",
|
|
62
|
+
"@discordjs/docgen": "^0.12.0",
|
|
63
|
+
"@favware/cliff-jumper": "^1.8.6",
|
|
64
|
+
"@microsoft/api-extractor": "^7.29.2",
|
|
65
|
+
"@types/node": "^16.11.47",
|
|
66
66
|
"@types/supertest": "^2.0.12",
|
|
67
|
-
"c8": "^7.
|
|
68
|
-
"
|
|
67
|
+
"c8": "^7.12.0",
|
|
68
|
+
"downlevel-dts": "^0.10.0",
|
|
69
|
+
"eslint": "^8.21.0",
|
|
69
70
|
"prettier": "^2.7.1",
|
|
71
|
+
"rollup-plugin-typescript2": "0.32.1",
|
|
70
72
|
"supertest": "^6.2.4",
|
|
71
|
-
"tsup": "^6.1.3",
|
|
72
73
|
"typescript": "^4.7.4",
|
|
73
|
-
"
|
|
74
|
+
"unbuild": "^0.8.4",
|
|
75
|
+
"vitest": "^0.21.1"
|
|
74
76
|
},
|
|
75
77
|
"engines": {
|
|
76
78
|
"node": ">=16.9.0"
|
|
77
79
|
},
|
|
78
80
|
"publishConfig": {
|
|
79
81
|
"access": "public"
|
|
80
|
-
}
|
|
81
|
-
"stableVersion": "1.1.0-dev"
|
|
82
|
+
}
|
|
82
83
|
}
|
package/dist/index.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
"use strict";
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
-
|
|
22
|
-
// src/index.ts
|
|
23
|
-
var src_exports = {};
|
|
24
|
-
__export(src_exports, {
|
|
25
|
-
populateAbortErrorResponse: () => populateAbortErrorResponse,
|
|
26
|
-
populateGeneralErrorResponse: () => populateGeneralErrorResponse,
|
|
27
|
-
populateRatelimitErrorResponse: () => populateRatelimitErrorResponse,
|
|
28
|
-
populateSuccessfulResponse: () => populateSuccessfulResponse,
|
|
29
|
-
proxyRequests: () => proxyRequests
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(src_exports);
|
|
32
|
-
|
|
33
|
-
// src/handlers/proxyRequests.ts
|
|
34
|
-
var import_node_url = require("url");
|
|
35
|
-
var import_rest = require("@discordjs/rest");
|
|
36
|
-
|
|
37
|
-
// src/util/responseHelpers.ts
|
|
38
|
-
var import_promises = require("stream/promises");
|
|
39
|
-
async function populateSuccessfulResponse(res, data) {
|
|
40
|
-
res.statusCode = data.statusCode;
|
|
41
|
-
for (const header of Object.keys(data.headers)) {
|
|
42
|
-
if (header.startsWith("x-ratelimit")) {
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
res.setHeader(header, data.headers[header]);
|
|
46
|
-
}
|
|
47
|
-
await (0, import_promises.pipeline)(data.body, res);
|
|
48
|
-
}
|
|
49
|
-
__name(populateSuccessfulResponse, "populateSuccessfulResponse");
|
|
50
|
-
function populateGeneralErrorResponse(res, error) {
|
|
51
|
-
res.statusCode = error.status;
|
|
52
|
-
if ("rawError" in error) {
|
|
53
|
-
res.setHeader("Content-Type", "application/json");
|
|
54
|
-
res.write(JSON.stringify(error.rawError));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
__name(populateGeneralErrorResponse, "populateGeneralErrorResponse");
|
|
58
|
-
function populateRatelimitErrorResponse(res, error) {
|
|
59
|
-
res.statusCode = 429;
|
|
60
|
-
res.setHeader("Retry-After", error.timeToReset / 1e3);
|
|
61
|
-
}
|
|
62
|
-
__name(populateRatelimitErrorResponse, "populateRatelimitErrorResponse");
|
|
63
|
-
function populateAbortErrorResponse(res) {
|
|
64
|
-
res.statusCode = 504;
|
|
65
|
-
res.statusMessage = "Upstream timed out";
|
|
66
|
-
}
|
|
67
|
-
__name(populateAbortErrorResponse, "populateAbortErrorResponse");
|
|
68
|
-
|
|
69
|
-
// src/handlers/proxyRequests.ts
|
|
70
|
-
function proxyRequests(rest) {
|
|
71
|
-
return async (req, res) => {
|
|
72
|
-
const { method, url } = req;
|
|
73
|
-
if (!method || !url) {
|
|
74
|
-
throw new TypeError("Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage");
|
|
75
|
-
}
|
|
76
|
-
const fullRoute = new import_node_url.URL(url, "http://noop").pathname.replace(/^\/api(\/v\d+)?/, "");
|
|
77
|
-
try {
|
|
78
|
-
const discordResponse = await rest.raw({
|
|
79
|
-
body: req,
|
|
80
|
-
fullRoute,
|
|
81
|
-
method,
|
|
82
|
-
passThroughBody: true,
|
|
83
|
-
headers: {
|
|
84
|
-
"Content-Type": req.headers["content-type"]
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
await populateSuccessfulResponse(res, discordResponse);
|
|
88
|
-
} catch (error) {
|
|
89
|
-
if (error instanceof import_rest.DiscordAPIError || error instanceof import_rest.HTTPError) {
|
|
90
|
-
populateGeneralErrorResponse(res, error);
|
|
91
|
-
} else if (error instanceof import_rest.RateLimitError) {
|
|
92
|
-
populateRatelimitErrorResponse(res, error);
|
|
93
|
-
} else if (error instanceof Error && error.name === "AbortError") {
|
|
94
|
-
populateAbortErrorResponse(res);
|
|
95
|
-
} else {
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
} finally {
|
|
99
|
-
res.end();
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
__name(proxyRequests, "proxyRequests");
|
|
104
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
-
0 && (module.exports = {
|
|
106
|
-
populateAbortErrorResponse,
|
|
107
|
-
populateGeneralErrorResponse,
|
|
108
|
-
populateRatelimitErrorResponse,
|
|
109
|
-
populateSuccessfulResponse,
|
|
110
|
-
proxyRequests
|
|
111
|
-
});
|
|
112
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/handlers/proxyRequests.ts","../src/util/responseHelpers.ts"],"sourcesContent":["export * from './handlers/proxyRequests';\nexport * from './util/responseHelpers';\nexport { RequestHandler } from './util/util';\n","import { URL } from 'node:url';\nimport { DiscordAPIError, HTTPError, RateLimitError, RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport {\n\tpopulateAbortErrorResponse,\n\tpopulateGeneralErrorResponse,\n\tpopulateSuccessfulResponse,\n\tpopulateRatelimitErrorResponse,\n} from '../util/responseHelpers';\nimport type { RequestHandler } from '../util/util';\n\n/**\n * Creates an HTTP handler used to forward requests to Discord\n *\n * @param rest - REST instance to use for the requests\n */\nexport function proxyRequests(rest: REST): RequestHandler {\n\treturn async (req, res) => {\n\t\tconst { method, url } = req;\n\n\t\tif (!method || !url) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage',\n\t\t\t);\n\t\t}\n\n\t\t// The 2nd parameter is here so the URL constructor doesn't complain about an \"invalid url\" when the origin is missing\n\t\t// we don't actually care about the origin and the value passed is irrelevant\n\t\tconst fullRoute = new URL(url, 'http://noop').pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.raw({\n\t\t\t\tbody: req,\n\t\t\t\tfullRoute,\n\t\t\t\t// This type cast is technically incorrect, but we want Discord to throw Method Not Allowed for us\n\t\t\t\tmethod: method as RequestMethod,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\t\t\tpopulateGeneralErrorResponse(res, error);\n\t\t\t} else if (error instanceof RateLimitError) {\n\t\t\t\tpopulateRatelimitErrorResponse(res, error);\n\t\t\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\t\t\tpopulateAbortErrorResponse(res);\n\t\t\t} else {\n\t\t\t\t// Unclear if there's better course of action here for unknown erorrs. Any web framework allows to pass in an error handler for something like this\n\t\t\t\t// at which point the user could dictate what to do with the error - otherwise we could just 500\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} finally {\n\t\t\tres.end();\n\t\t}\n\t};\n}\n","import type { ServerResponse } from 'node:http';\nimport { pipeline } from 'node:stream/promises';\nimport type { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';\nimport type { Dispatcher } from 'undici';\n\n/**\n * Populates a server response with the data from a Discord 2xx REST response\n *\n * @param res - The server response to populate\n * @param data - The data to populate the response with\n */\nexport async function populateSuccessfulResponse(res: ServerResponse, data: Dispatcher.ResponseData): Promise<void> {\n\tres.statusCode = data.statusCode;\n\n\tfor (const header of Object.keys(data.headers)) {\n\t\t// Strip ratelimit headers\n\t\tif (header.startsWith('x-ratelimit')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, data.headers[header]!);\n\t}\n\n\tawait pipeline(data.body, res);\n}\n\n/**\n * Populates a server response with the data from a Discord non-2xx REST response that is NOT a 429\n *\n * @param res - The server response to populate\n * @param error - The error to populate the response with\n */\nexport function populateGeneralErrorResponse(res: ServerResponse, error: DiscordAPIError | HTTPError): void {\n\tres.statusCode = error.status;\n\n\tif ('rawError' in error) {\n\t\tres.setHeader('Content-Type', 'application/json');\n\t\tres.write(JSON.stringify(error.rawError));\n\t}\n}\n\n/**\n * Populates a server response with the data from a Discord 429 REST response\n *\n * @param res - The server response to populate\n * @param error - The error to populate the response with\n */\nexport function populateRatelimitErrorResponse(res: ServerResponse, error: RateLimitError): void {\n\tres.statusCode = 429;\n\tres.setHeader('Retry-After', error.timeToReset / 1000);\n}\n\n/**\n * Populates a server response with data relevant for a timeout\n *\n * @param res - The sever response to populate\n */\nexport function populateAbortErrorResponse(res: ServerResponse): void {\n\tres.statusCode = 504;\n\tres.statusMessage = 'Upstream timed out';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,sBAAoB;AACpB,kBAA2F;;;ACA3F,sBAAyB;AAUzB,0CAAiD,KAAqB,MAA8C;AACnH,MAAI,aAAa,KAAK;AAEtB,aAAW,UAAU,OAAO,KAAK,KAAK,OAAO,GAAG;AAE/C,QAAI,OAAO,WAAW,aAAa,GAAG;AACrC;AAAA,IACD;AAEA,QAAI,UAAU,QAAQ,KAAK,QAAQ,OAAQ;AAAA,EAC5C;AAEA,QAAM,8BAAS,KAAK,MAAM,GAAG;AAC9B;AAbsB;AAqBf,sCAAsC,KAAqB,OAA0C;AAC3G,MAAI,aAAa,MAAM;AAEvB,MAAI,cAAc,OAAO;AACxB,QAAI,UAAU,gBAAgB,kBAAkB;AAChD,QAAI,MAAM,KAAK,UAAU,MAAM,QAAQ,CAAC;AAAA,EACzC;AACD;AAPgB;AAeT,wCAAwC,KAAqB,OAA6B;AAChG,MAAI,aAAa;AACjB,MAAI,UAAU,eAAe,MAAM,cAAc,GAAI;AACtD;AAHgB;AAUT,oCAAoC,KAA2B;AACrE,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACrB;AAHgB;;;AD1CT,uBAAuB,MAA4B;AACzD,SAAO,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,QAAQ,QAAQ;AAExB,QAAI,CAAC,UAAU,CAAC,KAAK;AACpB,YAAM,IAAI,UACT,+FACD;AAAA,IACD;AAIA,UAAM,YAAY,IAAI,oBAAI,KAAK,aAAa,EAAE,SAAS,QAAQ,mBAAmB,EAAE;AAEpF,QAAI;AACH,YAAM,kBAAkB,MAAM,KAAK,IAAI;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QAEA;AAAA,QACA,iBAAiB;AAAA,QACjB,SAAS;AAAA,UACR,gBAAgB,IAAI,QAAQ;AAAA,QAC7B;AAAA,MACD,CAAC;AAED,YAAM,2BAA2B,KAAK,eAAe;AAAA,IACtD,SAAS,OAAP;AACD,UAAI,iBAAiB,+BAAmB,iBAAiB,uBAAW;AACnE,qCAA6B,KAAK,KAAK;AAAA,MACxC,WAAW,iBAAiB,4BAAgB;AAC3C,uCAA+B,KAAK,KAAK;AAAA,MAC1C,WAAW,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACjE,mCAA2B,GAAG;AAAA,MAC/B,OAAO;AAGN,cAAM;AAAA,MACP;AAAA,IACD,UAAE;AACD,UAAI,IAAI;AAAA,IACT;AAAA,EACD;AACD;AA3CgB;","names":[]}
|