@discordjs/proxy 2.0.3-dev.1699920555-75fc7f245 → 2.0.3-dev.1700006966-cab60142f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -50,4 +50,12 @@ declare function populateAbortErrorResponse(res: ServerResponse): void;
50
50
  */
51
51
  declare function populateErrorResponse(res: ServerResponse, error: unknown): boolean;
52
52
 
53
- export { RequestHandler, populateAbortErrorResponse, populateErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse, proxyRequests };
53
+ /**
54
+ * The {@link https://github.com/discordjs/discord.js/blob/main/packages/proxy#readme | @discordjs/proxy} version
55
+ * that you are currently using.
56
+ *
57
+ * @privateRemarks This needs to explicitly be `string` so it is not typed as a "const string" that gets injected by esbuild.
58
+ */
59
+ declare const version: string;
60
+
61
+ export { RequestHandler, populateAbortErrorResponse, populateErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse, proxyRequests, version };
package/dist/index.d.ts CHANGED
@@ -50,4 +50,12 @@ declare function populateAbortErrorResponse(res: ServerResponse): void;
50
50
  */
51
51
  declare function populateErrorResponse(res: ServerResponse, error: unknown): boolean;
52
52
 
53
- export { RequestHandler, populateAbortErrorResponse, populateErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse, proxyRequests };
53
+ /**
54
+ * The {@link https://github.com/discordjs/discord.js/blob/main/packages/proxy#readme | @discordjs/proxy} version
55
+ * that you are currently using.
56
+ *
57
+ * @privateRemarks This needs to explicitly be `string` so it is not typed as a "const string" that gets injected by esbuild.
58
+ */
59
+ declare const version: string;
60
+
61
+ export { RequestHandler, populateAbortErrorResponse, populateErrorResponse, populateGeneralErrorResponse, populateRatelimitErrorResponse, populateSuccessfulResponse, proxyRequests, version };
package/dist/index.js CHANGED
@@ -26,7 +26,8 @@ __export(src_exports, {
26
26
  populateGeneralErrorResponse: () => populateGeneralErrorResponse,
27
27
  populateRatelimitErrorResponse: () => populateRatelimitErrorResponse,
28
28
  populateSuccessfulResponse: () => populateSuccessfulResponse,
29
- proxyRequests: () => proxyRequests
29
+ proxyRequests: () => proxyRequests,
30
+ version: () => version
30
31
  });
31
32
  module.exports = __toCommonJS(src_exports);
32
33
 
@@ -126,6 +127,9 @@ function proxyRequests(rest) {
126
127
  };
127
128
  }
128
129
  __name(proxyRequests, "proxyRequests");
130
+
131
+ // src/index.ts
132
+ var version = "2.0.3-dev.1700006966-cab60142f";
129
133
  // Annotate the CommonJS export names for ESM import in node:
130
134
  0 && (module.exports = {
131
135
  populateAbortErrorResponse,
@@ -133,6 +137,7 @@ __name(proxyRequests, "proxyRequests");
133
137
  populateGeneralErrorResponse,
134
138
  populateRatelimitErrorResponse,
135
139
  populateSuccessfulResponse,
136
- proxyRequests
140
+ proxyRequests,
141
+ version
137
142
  });
138
143
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/handlers/proxyRequests.ts","../src/util/responseHelpers.ts"],"sourcesContent":["export * from './handlers/proxyRequests.js';\nexport * from './util/responseHelpers.js';\nexport type { RequestHandler } from './util/util.js';\n","import { URL } from 'node:url';\nimport type { RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport { populateSuccessfulResponse, populateErrorResponse } from '../util/responseHelpers.js';\nimport type { RequestHandler } from '../util/util.js';\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 IncomingMessage',\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 parsedUrl = new URL(url, 'http://noop');\n\t\t// eslint-disable-next-line prefer-named-capture-group\n\t\tconst fullRoute = parsedUrl.pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t};\n\n\t\tif (req.headers.authorization) {\n\t\t\theaders.authorization = req.headers.authorization;\n\t\t}\n\n\t\tif (req.headers['x-audit-log-reason']) {\n\t\t\theaders['x-audit-log-reason'] = req.headers['x-audit-log-reason'] as string;\n\t\t}\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.queueRequest({\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\t// We forward the auth header anyway\n\t\t\t\tauth: false,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\tquery: parsedUrl.searchParams,\n\t\t\t\theaders,\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tconst knownError = populateErrorResponse(res, error);\n\t\t\tif (!knownError) {\n\t\t\t\t// Unclear if there's better course of action here for unknown errors.\n\t\t\t\t// 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 { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { DiscordAPIError, HTTPError, RateLimitError, type ResponseLike } from '@discordjs/rest';\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: ResponseLike): Promise<void> {\n\tres.statusCode = data.status;\n\n\tfor (const [header, value] of data.headers) {\n\t\t// Strip ratelimit headers\n\t\tif (/^x-ratelimit/i.test(header)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, value);\n\t}\n\n\tif (data.body) {\n\t\tawait pipeline(data.body instanceof Readable ? data.body : Readable.fromWeb(data.body), res);\n\t}\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 / 1_000);\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\n/**\n * Tries to populate a server response from an error object\n *\n * @param res - The server response to populate\n * @param error - The error to check and use\n * @returns - True if the error is known and the response object was populated, otherwise false\n */\nexport function populateErrorResponse(res: ServerResponse, error: unknown): boolean {\n\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\tpopulateGeneralErrorResponse(res, error);\n\t} else if (error instanceof RateLimitError) {\n\t\tpopulateRatelimitErrorResponse(res, error);\n\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\tpopulateAbortErrorResponse(res);\n\t} else {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,sBAAoB;;;ACCpB,yBAAyB;AACzB,sBAAyB;AACzB,kBAA8E;AAQ9E,eAAsB,2BAA2B,KAAqB,MAAmC;AACxG,MAAI,aAAa,KAAK;AAEtB,aAAW,CAAC,QAAQ,KAAK,KAAK,KAAK,SAAS;AAE3C,QAAI,gBAAgB,KAAK,MAAM,GAAG;AACjC;AAAA,IACD;AAEA,QAAI,UAAU,QAAQ,KAAK;AAAA,EAC5B;AAEA,MAAI,KAAK,MAAM;AACd,cAAM,0BAAS,KAAK,gBAAgB,8BAAW,KAAK,OAAO,4BAAS,QAAQ,KAAK,IAAI,GAAG,GAAG;AAAA,EAC5F;AACD;AAfsB;AAuBf,SAAS,6BAA6B,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,SAAS,+BAA+B,KAAqB,OAA6B;AAChG,MAAI,aAAa;AACjB,MAAI,UAAU,eAAe,MAAM,cAAc,GAAK;AACvD;AAHgB;AAUT,SAAS,2BAA2B,KAA2B;AACrE,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACrB;AAHgB;AAYT,SAAS,sBAAsB,KAAqB,OAAyB;AACnF,MAAI,iBAAiB,+BAAmB,iBAAiB,uBAAW;AACnE,iCAA6B,KAAK,KAAK;AAAA,EACxC,WAAW,iBAAiB,4BAAgB;AAC3C,mCAA+B,KAAK,KAAK;AAAA,EAC1C,WAAW,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACjE,+BAA2B,GAAG;AAAA,EAC/B,OAAO;AACN,WAAO;AAAA,EACR;AAEA,SAAO;AACR;AAZgB;;;AD7DT,SAAS,cAAc,MAA4B;AACzD,SAAO,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,QAAQ,IAAI,IAAI;AAExB,QAAI,CAAC,UAAU,CAAC,KAAK;AACpB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAIA,UAAM,YAAY,IAAI,oBAAI,KAAK,aAAa;AAE5C,UAAM,YAAY,UAAU,SAAS,QAAQ,mBAAmB,EAAE;AAElE,UAAM,UAAkC;AAAA,MACvC,gBAAgB,IAAI,QAAQ,cAAc;AAAA,IAC3C;AAEA,QAAI,IAAI,QAAQ,eAAe;AAC9B,cAAQ,gBAAgB,IAAI,QAAQ;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ,oBAAoB,GAAG;AACtC,cAAQ,oBAAoB,IAAI,IAAI,QAAQ,oBAAoB;AAAA,IACjE;AAEA,QAAI;AACH,YAAM,kBAAkB,MAAM,KAAK,aAAa;AAAA,QAC/C,MAAM;AAAA,QACN;AAAA;AAAA,QAEA;AAAA;AAAA,QAEA,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,OAAO,UAAU;AAAA,QACjB;AAAA,MACD,CAAC;AAED,YAAM,2BAA2B,KAAK,eAAe;AAAA,IACtD,SAAS,OAAO;AACf,YAAM,aAAa,sBAAsB,KAAK,KAAK;AACnD,UAAI,CAAC,YAAY;AAIhB,cAAM;AAAA,MACP;AAAA,IACD,UAAE;AACD,UAAI,IAAI;AAAA,IACT;AAAA,EACD;AACD;AAtDgB;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/handlers/proxyRequests.ts","../src/util/responseHelpers.ts"],"sourcesContent":["export * from './handlers/proxyRequests.js';\nexport * from './util/responseHelpers.js';\nexport type { RequestHandler } from './util/util.js';\n\n/**\n * The {@link https://github.com/discordjs/discord.js/blob/main/packages/proxy#readme | @discordjs/proxy} version\n * that you are currently using.\n *\n * @privateRemarks This needs to explicitly be `string` so it is not typed as a \"const string\" that gets injected by esbuild.\n */\nexport const version = '2.0.3-dev.1700006966-cab60142f' as string;\n","import { URL } from 'node:url';\nimport type { RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport { populateSuccessfulResponse, populateErrorResponse } from '../util/responseHelpers.js';\nimport type { RequestHandler } from '../util/util.js';\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 IncomingMessage',\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 parsedUrl = new URL(url, 'http://noop');\n\t\t// eslint-disable-next-line prefer-named-capture-group\n\t\tconst fullRoute = parsedUrl.pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t};\n\n\t\tif (req.headers.authorization) {\n\t\t\theaders.authorization = req.headers.authorization;\n\t\t}\n\n\t\tif (req.headers['x-audit-log-reason']) {\n\t\t\theaders['x-audit-log-reason'] = req.headers['x-audit-log-reason'] as string;\n\t\t}\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.queueRequest({\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\t// We forward the auth header anyway\n\t\t\t\tauth: false,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\tquery: parsedUrl.searchParams,\n\t\t\t\theaders,\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tconst knownError = populateErrorResponse(res, error);\n\t\t\tif (!knownError) {\n\t\t\t\t// Unclear if there's better course of action here for unknown errors.\n\t\t\t\t// 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 { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { DiscordAPIError, HTTPError, RateLimitError, type ResponseLike } from '@discordjs/rest';\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: ResponseLike): Promise<void> {\n\tres.statusCode = data.status;\n\n\tfor (const [header, value] of data.headers) {\n\t\t// Strip ratelimit headers\n\t\tif (/^x-ratelimit/i.test(header)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, value);\n\t}\n\n\tif (data.body) {\n\t\tawait pipeline(data.body instanceof Readable ? data.body : Readable.fromWeb(data.body), res);\n\t}\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 / 1_000);\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\n/**\n * Tries to populate a server response from an error object\n *\n * @param res - The server response to populate\n * @param error - The error to check and use\n * @returns - True if the error is known and the response object was populated, otherwise false\n */\nexport function populateErrorResponse(res: ServerResponse, error: unknown): boolean {\n\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\tpopulateGeneralErrorResponse(res, error);\n\t} else if (error instanceof RateLimitError) {\n\t\tpopulateRatelimitErrorResponse(res, error);\n\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\tpopulateAbortErrorResponse(res);\n\t} else {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,sBAAoB;;;ACCpB,yBAAyB;AACzB,sBAAyB;AACzB,kBAA8E;AAQ9E,eAAsB,2BAA2B,KAAqB,MAAmC;AACxG,MAAI,aAAa,KAAK;AAEtB,aAAW,CAAC,QAAQ,KAAK,KAAK,KAAK,SAAS;AAE3C,QAAI,gBAAgB,KAAK,MAAM,GAAG;AACjC;AAAA,IACD;AAEA,QAAI,UAAU,QAAQ,KAAK;AAAA,EAC5B;AAEA,MAAI,KAAK,MAAM;AACd,cAAM,0BAAS,KAAK,gBAAgB,8BAAW,KAAK,OAAO,4BAAS,QAAQ,KAAK,IAAI,GAAG,GAAG;AAAA,EAC5F;AACD;AAfsB;AAuBf,SAAS,6BAA6B,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,SAAS,+BAA+B,KAAqB,OAA6B;AAChG,MAAI,aAAa;AACjB,MAAI,UAAU,eAAe,MAAM,cAAc,GAAK;AACvD;AAHgB;AAUT,SAAS,2BAA2B,KAA2B;AACrE,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACrB;AAHgB;AAYT,SAAS,sBAAsB,KAAqB,OAAyB;AACnF,MAAI,iBAAiB,+BAAmB,iBAAiB,uBAAW;AACnE,iCAA6B,KAAK,KAAK;AAAA,EACxC,WAAW,iBAAiB,4BAAgB;AAC3C,mCAA+B,KAAK,KAAK;AAAA,EAC1C,WAAW,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACjE,+BAA2B,GAAG;AAAA,EAC/B,OAAO;AACN,WAAO;AAAA,EACR;AAEA,SAAO;AACR;AAZgB;;;AD7DT,SAAS,cAAc,MAA4B;AACzD,SAAO,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,QAAQ,IAAI,IAAI;AAExB,QAAI,CAAC,UAAU,CAAC,KAAK;AACpB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAIA,UAAM,YAAY,IAAI,oBAAI,KAAK,aAAa;AAE5C,UAAM,YAAY,UAAU,SAAS,QAAQ,mBAAmB,EAAE;AAElE,UAAM,UAAkC;AAAA,MACvC,gBAAgB,IAAI,QAAQ,cAAc;AAAA,IAC3C;AAEA,QAAI,IAAI,QAAQ,eAAe;AAC9B,cAAQ,gBAAgB,IAAI,QAAQ;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ,oBAAoB,GAAG;AACtC,cAAQ,oBAAoB,IAAI,IAAI,QAAQ,oBAAoB;AAAA,IACjE;AAEA,QAAI;AACH,YAAM,kBAAkB,MAAM,KAAK,aAAa;AAAA,QAC/C,MAAM;AAAA,QACN;AAAA;AAAA,QAEA;AAAA;AAAA,QAEA,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,OAAO,UAAU;AAAA,QACjB;AAAA,MACD,CAAC;AAED,YAAM,2BAA2B,KAAK,eAAe;AAAA,IACtD,SAAS,OAAO;AACf,YAAM,aAAa,sBAAsB,KAAK,KAAK;AACnD,UAAI,CAAC,YAAY;AAIhB,cAAM;AAAA,MACP;AAAA,IACD,UAAE;AACD,UAAI,IAAI;AAAA,IACT;AAAA,EACD;AACD;AAtDgB;;;ADAT,IAAM,UAAU;","names":[]}
package/dist/index.mjs CHANGED
@@ -97,12 +97,16 @@ function proxyRequests(rest) {
97
97
  };
98
98
  }
99
99
  __name(proxyRequests, "proxyRequests");
100
+
101
+ // src/index.ts
102
+ var version = "2.0.3-dev.1700006966-cab60142f";
100
103
  export {
101
104
  populateAbortErrorResponse,
102
105
  populateErrorResponse,
103
106
  populateGeneralErrorResponse,
104
107
  populateRatelimitErrorResponse,
105
108
  populateSuccessfulResponse,
106
- proxyRequests
109
+ proxyRequests,
110
+ version
107
111
  };
108
112
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/handlers/proxyRequests.ts","../src/util/responseHelpers.ts"],"sourcesContent":["import { URL } from 'node:url';\nimport type { RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport { populateSuccessfulResponse, populateErrorResponse } from '../util/responseHelpers.js';\nimport type { RequestHandler } from '../util/util.js';\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 IncomingMessage',\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 parsedUrl = new URL(url, 'http://noop');\n\t\t// eslint-disable-next-line prefer-named-capture-group\n\t\tconst fullRoute = parsedUrl.pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t};\n\n\t\tif (req.headers.authorization) {\n\t\t\theaders.authorization = req.headers.authorization;\n\t\t}\n\n\t\tif (req.headers['x-audit-log-reason']) {\n\t\t\theaders['x-audit-log-reason'] = req.headers['x-audit-log-reason'] as string;\n\t\t}\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.queueRequest({\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\t// We forward the auth header anyway\n\t\t\t\tauth: false,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\tquery: parsedUrl.searchParams,\n\t\t\t\theaders,\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tconst knownError = populateErrorResponse(res, error);\n\t\t\tif (!knownError) {\n\t\t\t\t// Unclear if there's better course of action here for unknown errors.\n\t\t\t\t// 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 { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { DiscordAPIError, HTTPError, RateLimitError, type ResponseLike } from '@discordjs/rest';\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: ResponseLike): Promise<void> {\n\tres.statusCode = data.status;\n\n\tfor (const [header, value] of data.headers) {\n\t\t// Strip ratelimit headers\n\t\tif (/^x-ratelimit/i.test(header)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, value);\n\t}\n\n\tif (data.body) {\n\t\tawait pipeline(data.body instanceof Readable ? data.body : Readable.fromWeb(data.body), res);\n\t}\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 / 1_000);\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\n/**\n * Tries to populate a server response from an error object\n *\n * @param res - The server response to populate\n * @param error - The error to check and use\n * @returns - True if the error is known and the response object was populated, otherwise false\n */\nexport function populateErrorResponse(res: ServerResponse, error: unknown): boolean {\n\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\tpopulateGeneralErrorResponse(res, error);\n\t} else if (error instanceof RateLimitError) {\n\t\tpopulateRatelimitErrorResponse(res, error);\n\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\tpopulateAbortErrorResponse(res);\n\t} else {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n"],"mappings":";;;;AAAA,SAAS,WAAW;;;ACCpB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB,WAAW,sBAAyC;AAQ9E,eAAsB,2BAA2B,KAAqB,MAAmC;AACxG,MAAI,aAAa,KAAK;AAEtB,aAAW,CAAC,QAAQ,KAAK,KAAK,KAAK,SAAS;AAE3C,QAAI,gBAAgB,KAAK,MAAM,GAAG;AACjC;AAAA,IACD;AAEA,QAAI,UAAU,QAAQ,KAAK;AAAA,EAC5B;AAEA,MAAI,KAAK,MAAM;AACd,UAAM,SAAS,KAAK,gBAAgB,WAAW,KAAK,OAAO,SAAS,QAAQ,KAAK,IAAI,GAAG,GAAG;AAAA,EAC5F;AACD;AAfsB;AAuBf,SAAS,6BAA6B,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,SAAS,+BAA+B,KAAqB,OAA6B;AAChG,MAAI,aAAa;AACjB,MAAI,UAAU,eAAe,MAAM,cAAc,GAAK;AACvD;AAHgB;AAUT,SAAS,2BAA2B,KAA2B;AACrE,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACrB;AAHgB;AAYT,SAAS,sBAAsB,KAAqB,OAAyB;AACnF,MAAI,iBAAiB,mBAAmB,iBAAiB,WAAW;AACnE,iCAA6B,KAAK,KAAK;AAAA,EACxC,WAAW,iBAAiB,gBAAgB;AAC3C,mCAA+B,KAAK,KAAK;AAAA,EAC1C,WAAW,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACjE,+BAA2B,GAAG;AAAA,EAC/B,OAAO;AACN,WAAO;AAAA,EACR;AAEA,SAAO;AACR;AAZgB;;;AD7DT,SAAS,cAAc,MAA4B;AACzD,SAAO,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,QAAQ,IAAI,IAAI;AAExB,QAAI,CAAC,UAAU,CAAC,KAAK;AACpB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAIA,UAAM,YAAY,IAAI,IAAI,KAAK,aAAa;AAE5C,UAAM,YAAY,UAAU,SAAS,QAAQ,mBAAmB,EAAE;AAElE,UAAM,UAAkC;AAAA,MACvC,gBAAgB,IAAI,QAAQ,cAAc;AAAA,IAC3C;AAEA,QAAI,IAAI,QAAQ,eAAe;AAC9B,cAAQ,gBAAgB,IAAI,QAAQ;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ,oBAAoB,GAAG;AACtC,cAAQ,oBAAoB,IAAI,IAAI,QAAQ,oBAAoB;AAAA,IACjE;AAEA,QAAI;AACH,YAAM,kBAAkB,MAAM,KAAK,aAAa;AAAA,QAC/C,MAAM;AAAA,QACN;AAAA;AAAA,QAEA;AAAA;AAAA,QAEA,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,OAAO,UAAU;AAAA,QACjB;AAAA,MACD,CAAC;AAED,YAAM,2BAA2B,KAAK,eAAe;AAAA,IACtD,SAAS,OAAO;AACf,YAAM,aAAa,sBAAsB,KAAK,KAAK;AACnD,UAAI,CAAC,YAAY;AAIhB,cAAM;AAAA,MACP;AAAA,IACD,UAAE;AACD,UAAI,IAAI;AAAA,IACT;AAAA,EACD;AACD;AAtDgB;","names":[]}
1
+ {"version":3,"sources":["../src/handlers/proxyRequests.ts","../src/util/responseHelpers.ts","../src/index.ts"],"sourcesContent":["import { URL } from 'node:url';\nimport type { RequestMethod, REST, RouteLike } from '@discordjs/rest';\nimport { populateSuccessfulResponse, populateErrorResponse } from '../util/responseHelpers.js';\nimport type { RequestHandler } from '../util/util.js';\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 IncomingMessage',\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 parsedUrl = new URL(url, 'http://noop');\n\t\t// eslint-disable-next-line prefer-named-capture-group\n\t\tconst fullRoute = parsedUrl.pathname.replace(/^\\/api(\\/v\\d+)?/, '') as RouteLike;\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': req.headers['content-type']!,\n\t\t};\n\n\t\tif (req.headers.authorization) {\n\t\t\theaders.authorization = req.headers.authorization;\n\t\t}\n\n\t\tif (req.headers['x-audit-log-reason']) {\n\t\t\theaders['x-audit-log-reason'] = req.headers['x-audit-log-reason'] as string;\n\t\t}\n\n\t\ttry {\n\t\t\tconst discordResponse = await rest.queueRequest({\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\t// We forward the auth header anyway\n\t\t\t\tauth: false,\n\t\t\t\tpassThroughBody: true,\n\t\t\t\tquery: parsedUrl.searchParams,\n\t\t\t\theaders,\n\t\t\t});\n\n\t\t\tawait populateSuccessfulResponse(res, discordResponse);\n\t\t} catch (error) {\n\t\t\tconst knownError = populateErrorResponse(res, error);\n\t\t\tif (!knownError) {\n\t\t\t\t// Unclear if there's better course of action here for unknown errors.\n\t\t\t\t// 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 { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { DiscordAPIError, HTTPError, RateLimitError, type ResponseLike } from '@discordjs/rest';\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: ResponseLike): Promise<void> {\n\tres.statusCode = data.status;\n\n\tfor (const [header, value] of data.headers) {\n\t\t// Strip ratelimit headers\n\t\tif (/^x-ratelimit/i.test(header)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tres.setHeader(header, value);\n\t}\n\n\tif (data.body) {\n\t\tawait pipeline(data.body instanceof Readable ? data.body : Readable.fromWeb(data.body), res);\n\t}\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 / 1_000);\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\n/**\n * Tries to populate a server response from an error object\n *\n * @param res - The server response to populate\n * @param error - The error to check and use\n * @returns - True if the error is known and the response object was populated, otherwise false\n */\nexport function populateErrorResponse(res: ServerResponse, error: unknown): boolean {\n\tif (error instanceof DiscordAPIError || error instanceof HTTPError) {\n\t\tpopulateGeneralErrorResponse(res, error);\n\t} else if (error instanceof RateLimitError) {\n\t\tpopulateRatelimitErrorResponse(res, error);\n\t} else if (error instanceof Error && error.name === 'AbortError') {\n\t\tpopulateAbortErrorResponse(res);\n\t} else {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n","export * from './handlers/proxyRequests.js';\nexport * from './util/responseHelpers.js';\nexport type { RequestHandler } from './util/util.js';\n\n/**\n * The {@link https://github.com/discordjs/discord.js/blob/main/packages/proxy#readme | @discordjs/proxy} version\n * that you are currently using.\n *\n * @privateRemarks This needs to explicitly be `string` so it is not typed as a \"const string\" that gets injected by esbuild.\n */\nexport const version = '2.0.3-dev.1700006966-cab60142f' as string;\n"],"mappings":";;;;AAAA,SAAS,WAAW;;;ACCpB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB,WAAW,sBAAyC;AAQ9E,eAAsB,2BAA2B,KAAqB,MAAmC;AACxG,MAAI,aAAa,KAAK;AAEtB,aAAW,CAAC,QAAQ,KAAK,KAAK,KAAK,SAAS;AAE3C,QAAI,gBAAgB,KAAK,MAAM,GAAG;AACjC;AAAA,IACD;AAEA,QAAI,UAAU,QAAQ,KAAK;AAAA,EAC5B;AAEA,MAAI,KAAK,MAAM;AACd,UAAM,SAAS,KAAK,gBAAgB,WAAW,KAAK,OAAO,SAAS,QAAQ,KAAK,IAAI,GAAG,GAAG;AAAA,EAC5F;AACD;AAfsB;AAuBf,SAAS,6BAA6B,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,SAAS,+BAA+B,KAAqB,OAA6B;AAChG,MAAI,aAAa;AACjB,MAAI,UAAU,eAAe,MAAM,cAAc,GAAK;AACvD;AAHgB;AAUT,SAAS,2BAA2B,KAA2B;AACrE,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACrB;AAHgB;AAYT,SAAS,sBAAsB,KAAqB,OAAyB;AACnF,MAAI,iBAAiB,mBAAmB,iBAAiB,WAAW;AACnE,iCAA6B,KAAK,KAAK;AAAA,EACxC,WAAW,iBAAiB,gBAAgB;AAC3C,mCAA+B,KAAK,KAAK;AAAA,EAC1C,WAAW,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACjE,+BAA2B,GAAG;AAAA,EAC/B,OAAO;AACN,WAAO;AAAA,EACR;AAEA,SAAO;AACR;AAZgB;;;AD7DT,SAAS,cAAc,MAA4B;AACzD,SAAO,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,QAAQ,IAAI,IAAI;AAExB,QAAI,CAAC,UAAU,CAAC,KAAK;AACpB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAIA,UAAM,YAAY,IAAI,IAAI,KAAK,aAAa;AAE5C,UAAM,YAAY,UAAU,SAAS,QAAQ,mBAAmB,EAAE;AAElE,UAAM,UAAkC;AAAA,MACvC,gBAAgB,IAAI,QAAQ,cAAc;AAAA,IAC3C;AAEA,QAAI,IAAI,QAAQ,eAAe;AAC9B,cAAQ,gBAAgB,IAAI,QAAQ;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ,oBAAoB,GAAG;AACtC,cAAQ,oBAAoB,IAAI,IAAI,QAAQ,oBAAoB;AAAA,IACjE;AAEA,QAAI;AACH,YAAM,kBAAkB,MAAM,KAAK,aAAa;AAAA,QAC/C,MAAM;AAAA,QACN;AAAA;AAAA,QAEA;AAAA;AAAA,QAEA,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,OAAO,UAAU;AAAA,QACjB;AAAA,MACD,CAAC;AAED,YAAM,2BAA2B,KAAK,eAAe;AAAA,IACtD,SAAS,OAAO;AACf,YAAM,aAAa,sBAAsB,KAAK,KAAK;AACnD,UAAI,CAAC,YAAY;AAIhB,cAAM;AAAA,MACP;AAAA,IACD,UAAE;AACD,UAAI,IAAI;AAAA,IACT;AAAA,EACD;AACD;AAtDgB;;;AEAT,IAAM,UAAU;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@discordjs/proxy",
4
- "version": "2.0.3-dev.1699920555-75fc7f245",
4
+ "version": "2.0.3-dev.1700006966-cab60142f",
5
5
  "description": "Tools for running an HTTP proxy for Discord's API",
6
6
  "exports": {
7
7
  ".": {
@@ -63,10 +63,11 @@
63
63
  "@types/supertest": "^2.0.16",
64
64
  "@vitest/coverage-v8": "^0.34.6",
65
65
  "cross-env": "^7.0.3",
66
+ "esbuild-plugin-version-injector": "^1.2.1",
66
67
  "eslint": "^8.53.0",
67
68
  "eslint-config-neon": "^0.1.57",
68
69
  "eslint-formatter-pretty": "^5.0.0",
69
- "prettier": "^3.0.3",
70
+ "prettier": "^3.1.0",
70
71
  "supertest": "^6.3.3",
71
72
  "tsup": "^7.2.0",
72
73
  "turbo": "^1.10.17-canary.0",
@@ -87,7 +88,7 @@
87
88
  "lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
88
89
  "format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
89
90
  "fmt": "pnpm run format",
90
- "docs": "pnpm run build:docs && api-extractor run --local",
91
+ "docs": "pnpm run build:docs && api-extractor run --local --minify",
91
92
  "changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/proxy/*'",
92
93
  "release": "cliff-jumper"
93
94
  }