diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 16f2f173b..e70d4caf1 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -32,7 +32,7 @@ - { "customColor": "", @@ -57,7 +57,8 @@ "RunOnceActivity.git.unshallow": "true", "javascript.nodejs.core.library.configured.version": "24.8.0", "javascript.nodejs.core.library.typings.version": "24.7.0", - "last_opened_file_path": "/home/Rory/git/spacebar/server-master/src/schemas/api/guilds", + "last.edited.regexp": "\"$ref\": \"#/definitions/name\"", + "last_opened_file_path": "/home/Rory/git/spacebar/server-master/src/api/routes/applications", "node.js.detected.package.eslint": "true", "node.js.selected.package.eslint": "(autodetect)", "node.js.selected.package.tslint": "(autodetect)", @@ -70,7 +71,8 @@ "npm.start.executor": "Debug", "prettierjs.PrettierConfiguration.Package": "/home/Rory/git/spacebar/server-master/node_modules/prettier", "settings.editor.selected.configurable": "preferences.pluginManager", - "ts.external.directory.path": "/home/Rory/git/spacebar/server-master/node_modules/typescript/lib" + "ts.external.directory.path": "/home/Rory/git/spacebar/server-master/node_modules/typescript/lib", + "two.files.diff.last.used.file": "/home/Rory/git/spacebar/server-master/dist/openapi_discord.json" }, "keyToStringList": { "GitStage.ChangesTree.GroupingKeys": [ @@ -82,11 +84,11 @@ } + + - - @@ -141,7 +143,8 @@ - + + diff --git a/assets/openapi.json b/assets/openapi.json index 0da72d2f8..5dfe23eed 100644 Binary files a/assets/openapi.json and b/assets/openapi.json differ diff --git a/assets/schemas.json b/assets/schemas.json index 20a7d9ae0..5d883f48d 100644 Binary files a/assets/schemas.json and b/assets/schemas.json differ diff --git a/scripts/fetch_discord_openapi.js b/scripts/fetch_discord_openapi.js new file mode 100644 index 000000000..62cf8986b --- /dev/null +++ b/scripts/fetch_discord_openapi.js @@ -0,0 +1,91 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +require("module-alias/register"); +const path = require("path"); +const fs = require("fs"); +require("../dist/util/util/extensions"); + +const openapiPathOut = path.join(__dirname, "..", "dist", "openapi_discord.json"); + +async function main() { + console.log("Generating OpenAPI Specification..."); + + const routesRes = await fetch( + "https://raw.githubusercontent.com/discord/discord-api-spec/refs/heads/main/specs/openapi_preview.json", + { + headers: { + Accept: "application/json", + }, + }, + ); + const dOpenApi = await routesRes.json(); + for (const pathName in dOpenApi.paths) { + console.log("Processing path:", pathName); + const path = dOpenApi.paths[pathName]; + for (const methodName in path) { + if (methodName === 'parameters') continue; + console.log(" Processing method:", methodName); + const method = path[methodName]; + if (method.operationId) + // delete dOpenApi.paths[path][methodName].operationId; + delete method.operationId; // we don't care about these + + for (const respCode in method.responses) { + console.log(" Processing response:", respCode); + const resp = method.responses[respCode]; + if(resp.description) + delete resp.description; // we don't care about these + + } + + console.log(" Method security:", JSON.stringify(method.security)); + // if(method.security?.length >= 1 && method.security[0]?.["BotToken"] !== undefined) { + // console.log(" Converting BotToken security to bearer"); + // // BotToken -> bearer + // method.security[0]["bearer"] = []; + // delete method.security[0]["BotToken"]; + // } + for (const securityObj of method.security||[]) { + if(securityObj["BotToken"] !== undefined) { + console.log(" Converting BotToken security to bearer"); + // BotToken -> bearer + securityObj["bearer"] = []; + delete securityObj["BotToken"]; + } + } + } + } + + + + fs.writeFileSync( + openapiPathOut, + JSON.stringify(dOpenApi, null, 2) + ); + console.log("Wrote OpenAPI specification to", openapiPathOut); + console.log( + "Specification contains", + Object.keys(dOpenApi.paths).length, + "paths and", + Object.keys(dOpenApi.components.schemas).length, + "schemas.", + ); +} + +main(); diff --git a/scripts/openapi.js b/scripts/openapi.js index 6d4d63667..33e8c9f96 100644 --- a/scripts/openapi.js +++ b/scripts/openapi.js @@ -20,9 +20,7 @@ require("module-alias/register"); const getRouteDescriptions = require("./util/getRouteDescriptions"); const path = require("path"); const fs = require("fs"); -const { - NO_AUTHORIZATION_ROUTES, -} = require("../dist/api/middlewares/Authentication"); +const { NO_AUTHORIZATION_ROUTES } = require("../dist/api/middlewares/Authentication"); require("../dist/util/util/extensions"); const openapiPath = path.join(__dirname, "..", "assets", "openapi.json"); @@ -39,7 +37,7 @@ let specification = { name: "AGPLV3", url: "https://www.gnu.org/licenses/agpl-3.0.en.html", }, - version: "1.0.0", + version: "9", }, externalDocs: { description: "Spacebar Docs", @@ -47,8 +45,8 @@ let specification = { }, servers: [ { - url: "https://old.server.spacebar.chat/api/", description: "Official Spacebar Instance", + url: "https://old.server.spacebar.chat/api/v9", }, ], components: { @@ -88,8 +86,7 @@ function combineSchemas(schemas) { continue; } specification.components = specification.components || {}; - specification.components.schemas = - specification.components.schemas || {}; + specification.components.schemas = specification.components.schemas || {}; specification.components.schemas[key] = definitions[key]; delete definitions[key].additionalProperties; delete definitions[key].$schema; @@ -134,8 +131,7 @@ function apiRoutes(missingRoutes) { if ( !NO_AUTHORIZATION_ROUTES.some((x) => { - if (typeof x === "string") - return (method.toUpperCase() + " " + path).startsWith(x); + if (typeof x === "string") return (method.toUpperCase() + " " + path).startsWith(x); return x.test(method.toUpperCase() + " " + path); }) ) { @@ -162,10 +158,10 @@ function apiRoutes(missingRoutes) { if (route.responses) { obj.responses = {}; - for (const [k, v] of Object.entries(route.responses)) { + for (const [statusCode, v] of Object.entries(route.responses)) { if (v.body) - obj.responses[k] = { - description: obj?.responses?.[k]?.description || "", + obj.responses[statusCode] = { + description: obj?.responses?.[statusCode]?.description, content: { "application/json": { schema: { @@ -175,12 +171,23 @@ function apiRoutes(missingRoutes) { }, }; else - obj.responses[k] = { - description: - obj?.responses?.[k]?.description || - "No description available", + obj.responses[statusCode] = { + description: obj?.responses?.[statusCode]?.description || "No description available", }; } + + if (route.ratelimitBucket) { + obj["x-ratelimit-bucket"] = route.ratelimitBucket; + obj.responses["429"] = {}; + if (obj.responses["200"]) { + obj.responses["200"].headers ??= {}; + for (const key in ["Limit", "Remaining", "Reset", "Reset-After", "Bucket"]) { + obj.responses["200"].headers[`X-RateLimit-${key}`] = { + $ref: `#/components/headers/X-RateLimit-${key}`, + }; + } + } + } } else { obj.responses = { default: { @@ -224,45 +231,39 @@ function apiRoutes(missingRoutes) { ]; } - specification.paths[path] = Object.assign( - specification.paths[path] || {}, - { - [method]: obj, - }, - ); + specification.paths[path] = Object.assign(specification.paths[path] || {}, { + [method]: obj, + }); }); + + // order top level + const topLevelOrder = ["openapi", "info", "externalDocs", "servers", "paths", "tags", "components"]; + specification = Object.fromEntries( + topLevelOrder + .map((x) => [x, specification[x]]) + .filter((x) => x[1] !== undefined) + .concat(Object.entries(specification).filter((x) => !topLevelOrder.includes(x[0]))), + ); + // order paths alphabetically + specification.paths = Object.fromEntries(Object.entries(specification.paths).sort((a, b) => a[0].localeCompare(b[0]))); } async function main() { console.log("Generating OpenAPI Specification..."); - const routesRes = await fetch( - "https://github.com/spacebarchat/missing-routes/raw/main/missing.json", - { - headers: { - Accept: "application/json", - }, + const routesRes = await fetch("https://github.com/spacebarchat/missing-routes/raw/main/missing.json", { + headers: { + Accept: "application/json", }, - ); + }); const missingRoutes = await routesRes.json(); combineSchemas(schemas); apiRoutes(missingRoutes); - fs.writeFileSync( - openapiPath, - JSON.stringify(specification, null, 4) - .replaceAll("#/definitions", "#/components/schemas") - .replaceAll("bigint", "number"), - ); + fs.writeFileSync(openapiPath, JSON.stringify(specification, null, 4).replaceAll("#/definitions", "#/components/schemas").replaceAll("bigint", "number")); console.log("Wrote OpenAPI specification to", openapiPath); - console.log( - "Specification contains", - Object.keys(specification.paths).length, - "paths and", - Object.keys(specification.components.schemas).length, - "schemas.", - ); + console.log("Specification contains", Object.keys(specification.paths).length, "paths and", Object.keys(specification.components.schemas).length, "schemas."); } main(); diff --git a/scripts/openapi_missing.js b/scripts/openapi_missing.js new file mode 100644 index 000000000..e5cb81d1d --- /dev/null +++ b/scripts/openapi_missing.js @@ -0,0 +1,69 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +require("module-alias/register"); +const path = require("path"); +const fs = require("fs"); +require("../dist/util/util/extensions"); + +const openapiPath = path.join(__dirname, "..", "assets", "openapi.json"); +const openapiPathOut = path.join(__dirname, "..", "dist", "openapi_missing.json"); +const SchemaPath = path.join(__dirname, "..", "assets", "schemas.json"); +const sbOpenApi = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" })); + +async function main() { + console.log("Generating OpenAPI Specification..."); + + const routesRes = await fetch( + "https://raw.githubusercontent.com/discord/discord-api-spec/refs/heads/main/specs/openapi_preview.json", + { + headers: { + Accept: "application/json", + }, + }, + ); + const dOpenApi = await routesRes.json(); + for (const path in dOpenApi.paths) { + if (!sbOpenApi.paths[path]) { + console.log("Missing path:", path); + continue; + } + + for (const method in dOpenApi.paths[path]) { + if(sbOpenApi.paths?.[path]?.[method]) delete sbOpenApi.paths[path][method]; + } + if(Object.keys(sbOpenApi.paths?.[path]||{}).length === 0) delete sbOpenApi.paths[path]; + } + + + + fs.writeFileSync( + openapiPathOut, + JSON.stringify(dOpenApi, null, 4) + ); + console.log("Wrote OpenAPI specification to", openapiPathOut); + console.log( + "Specification contains", + Object.keys(specification.paths).length, + "paths and", + Object.keys(specification.components.schemas).length, + "schemas.", + ); +} + +main(); diff --git a/scripts/schema.js b/scripts/schema.js index 772058316..983eb697a 100644 --- a/scripts/schema.js +++ b/scripts/schema.js @@ -46,6 +46,7 @@ const settings = { const ExcludeAndWarn = [ /^Record/, /^Partial/, + /^import\(/, ] const Excluded = [ "DefaultSchema", @@ -149,6 +150,24 @@ function main() { deleteOneOfKindUndefinedRecursive(definitions, "$"); + // cant do this here: + // let hasUnreferencedSchemas = true; + // while (hasUnreferencedSchemas) { + // hasUnreferencedSchemas = false; + // console.log(`Checking for unreferenced schemas in ${definitions.length}..."`); + // let fullMap = JSON.stringify(definitions); + // for (const [name, schema] of Object.entries(definitions)) { + // const schemaStr = JSON.stringify(schema); + // const refRe = new RegExp(`"\\$ref":"#/definitions/${name}"`, "g"); + // const count = (fullMap.match(refRe) || []).length; + // if (count <= 1) { + // console.log("Deleting unreferenced schema", name); + // delete definitions[name]; + // hasUnreferencedSchemas = true; + // } + // } + // } + fs.writeFileSync(schemaPath, JSON.stringify(definitions, null, 4)); console.log("Successfully wrote", Object.keys(definitions).length, "schemas to", schemaPath); } diff --git a/src/api/routes/applications/#application_id/bot/index.ts b/src/api/routes/applications/#application_id/bot/index.ts index db1d02538..98eafea7c 100644 --- a/src/api/routes/applications/#application_id/bot/index.ts +++ b/src/api/routes/applications/#application_id/bot/index.ts @@ -39,7 +39,7 @@ router.post( 204: { body: "TokenOnlyResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -68,7 +68,7 @@ router.post( 200: { body: "TokenResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -104,7 +104,7 @@ router.patch( 200: { body: "Application", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/applications/#application_id/index.ts b/src/api/routes/applications/#application_id/index.ts index 6701f867c..09e458c8e 100644 --- a/src/api/routes/applications/#application_id/index.ts +++ b/src/api/routes/applications/#application_id/index.ts @@ -37,7 +37,7 @@ router.get( 200: { body: "Application", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -62,7 +62,7 @@ router.patch( 200: { body: "Application", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -128,7 +128,7 @@ router.post( route({ responses: { 200: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/attachments/refresh-urls.ts b/src/api/routes/attachments/refresh-urls.ts index 76954c779..452611d3a 100644 --- a/src/api/routes/attachments/refresh-urls.ts +++ b/src/api/routes/attachments/refresh-urls.ts @@ -33,7 +33,7 @@ router.post( 200: { body: "RefreshUrlsResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/auth/forgot.ts b/src/api/routes/auth/forgot.ts index 12bc9cb07..77d7ea4ce 100644 --- a/src/api/routes/auth/forgot.ts +++ b/src/api/routes/auth/forgot.ts @@ -28,7 +28,7 @@ router.post( requestBody: "ForgotPasswordSchema", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorOrCaptchaResponse", }, }, diff --git a/src/api/routes/auth/login.ts b/src/api/routes/auth/login.ts index 06e3fe43e..e787b5a95 100644 --- a/src/api/routes/auth/login.ts +++ b/src/api/routes/auth/login.ts @@ -41,7 +41,7 @@ router.post( 200: { body: "LoginResponse", }, - 400: { + "4XX": { body: "APIErrorOrCaptchaResponse", }, }, diff --git a/src/api/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts index cc6e8a253..4959db10d 100644 --- a/src/api/routes/auth/mfa/totp.ts +++ b/src/api/routes/auth/mfa/totp.ts @@ -32,7 +32,7 @@ router.post( 200: { body: "TokenResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/auth/mfa/webauthn.ts b/src/api/routes/auth/mfa/webauthn.ts index 80ff57f0f..7ec385cb8 100644 --- a/src/api/routes/auth/mfa/webauthn.ts +++ b/src/api/routes/auth/mfa/webauthn.ts @@ -45,7 +45,7 @@ router.post( requestBody: "WebAuthnTotpSchema", responses: { 200: { body: "TokenResponse" }, - 400: { body: "APIErrorResponse" }, + "4XX": { body: "APIErrorResponse" }, }, }), async (req: Request, res: Response) => { diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts index 2db60abd0..8eaf5eb38 100644 --- a/src/api/routes/auth/register.ts +++ b/src/api/routes/auth/register.ts @@ -45,7 +45,7 @@ router.post( requestBody: "RegisterSchema", responses: { 200: { body: "TokenOnlyResponse" }, - 400: { body: "APIErrorOrCaptchaResponse" }, + "4XX": { body: "APIErrorOrCaptchaResponse" }, }, }), async (req: Request, res: Response) => { diff --git a/src/api/routes/auth/reset.ts b/src/api/routes/auth/reset.ts index b14eb3791..e5ca664a1 100644 --- a/src/api/routes/auth/reset.ts +++ b/src/api/routes/auth/reset.ts @@ -39,7 +39,7 @@ router.post( 200: { body: "TokenOnlyResponse", }, - 400: { + "4XX": { body: "APIErrorOrCaptchaResponse", }, }, diff --git a/src/api/routes/auth/verify/index.ts b/src/api/routes/auth/verify/index.ts index b85120d84..8a641781c 100644 --- a/src/api/routes/auth/verify/index.ts +++ b/src/api/routes/auth/verify/index.ts @@ -46,7 +46,7 @@ router.post( 200: { body: "TokenResponse", }, - 400: { + "4XX": { body: "APIErrorOrCaptchaResponse", }, }, diff --git a/src/api/routes/auth/verify/resend.ts b/src/api/routes/auth/verify/resend.ts index c9696ebdc..9c72cd6ce 100644 --- a/src/api/routes/auth/verify/resend.ts +++ b/src/api/routes/auth/verify/resend.ts @@ -28,7 +28,7 @@ router.post( right: "RESEND_VERIFICATION_EMAIL", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 500: { diff --git a/src/api/routes/auth/verify/view-backup-codes-challenge.ts b/src/api/routes/auth/verify/view-backup-codes-challenge.ts index 811de5084..b040238dd 100644 --- a/src/api/routes/auth/verify/view-backup-codes-challenge.ts +++ b/src/api/routes/auth/verify/view-backup-codes-challenge.ts @@ -29,7 +29,7 @@ router.post( requestBody: "BackupCodesChallengeSchema", responses: { 200: { body: "BackupCodesChallengeResponse" }, - 400: { body: "APIErrorResponse" }, + "4XX": { body: "APIErrorResponse" }, }, }), async (req: Request, res: Response) => { diff --git a/src/api/routes/channels/#channel_id/attachments.ts b/src/api/routes/channels/#channel_id/attachments.ts index 2c08931e8..ebd06b755 100644 --- a/src/api/routes/channels/#channel_id/attachments.ts +++ b/src/api/routes/channels/#channel_id/attachments.ts @@ -39,7 +39,7 @@ router.post( body: "UploadAttachmentResponseSchema", }, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/directory-entries.ts b/src/api/routes/channels/#channel_id/directory-entries.ts index c07b1f751..5d70d8202 100644 --- a/src/api/routes/channels/#channel_id/directory-entries.ts +++ b/src/api/routes/channels/#channel_id/directory-entries.ts @@ -28,7 +28,7 @@ router.get( 200: { body: "HubDirectoryEntriesResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/greet.ts b/src/api/routes/channels/#channel_id/greet.ts index 399e30a22..8a6b80902 100644 --- a/src/api/routes/channels/#channel_id/greet.ts +++ b/src/api/routes/channels/#channel_id/greet.ts @@ -34,7 +34,7 @@ router.post( body: "Message", }, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts index 1535b0051..f56de9204 100644 --- a/src/api/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -137,7 +137,7 @@ router.patch( body: "Channel", }, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/invites.ts b/src/api/routes/channels/#channel_id/invites.ts index fcf6f97cd..9159e35d0 100644 --- a/src/api/routes/channels/#channel_id/invites.ts +++ b/src/api/routes/channels/#channel_id/invites.ts @@ -35,7 +35,7 @@ router.post( body: "Invite", }, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts index bf35dc3d2..154504b09 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts @@ -59,7 +59,7 @@ router.patch( 200: { body: "Message", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, @@ -161,7 +161,7 @@ router.put( 200: { body: "Message", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, @@ -264,7 +264,7 @@ router.get( 200: { body: "Message", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, @@ -297,7 +297,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts index dcd98ff54..040ecfb09 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts @@ -59,7 +59,7 @@ router.delete( permission: "MANAGE_MESSAGES", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -95,7 +95,7 @@ router.delete( permission: "MANAGE_MESSAGES", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -144,7 +144,7 @@ router.get( 200: { body: "PublicUser", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -183,7 +183,7 @@ router.put( right: "SELF_ADD_REACTIONS", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -264,7 +264,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -334,7 +334,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, diff --git a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts index 77fd26d65..cf7d900f4 100644 --- a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts @@ -42,7 +42,7 @@ router.post( requestBody: "BulkDeleteSchema", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index 391b7b6fd..40eef0650 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -70,7 +70,7 @@ router.get( 200: { body: "APIMessageArray", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, @@ -281,7 +281,7 @@ router.post( 200: { body: "Message", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, diff --git a/src/api/routes/channels/#channel_id/messages/pins/index.ts b/src/api/routes/channels/#channel_id/messages/pins/index.ts index b12d59577..9499d1a65 100644 --- a/src/api/routes/channels/#channel_id/messages/pins/index.ts +++ b/src/api/routes/channels/#channel_id/messages/pins/index.ts @@ -40,7 +40,7 @@ router.put( 204: {}, 403: {}, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -126,7 +126,7 @@ router.delete( 204: {}, 403: {}, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -173,7 +173,7 @@ router.get( 200: { body: "APIMessageArray", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts index e0feb3f95..4ef6b112e 100644 --- a/src/api/routes/channels/#channel_id/permissions.ts +++ b/src/api/routes/channels/#channel_id/permissions.ts @@ -35,7 +35,7 @@ router.put( 204: {}, 404: {}, 501: {}, - 400: { body: "APIErrorResponse" }, + "4XX": { body: "APIErrorResponse" }, }, }), async (req: Request, res: Response) => { diff --git a/src/api/routes/channels/#channel_id/pins.ts b/src/api/routes/channels/#channel_id/pins.ts index a5aecda78..5c69739e6 100644 --- a/src/api/routes/channels/#channel_id/pins.ts +++ b/src/api/routes/channels/#channel_id/pins.ts @@ -41,7 +41,7 @@ router.put( 204: {}, 403: {}, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -127,7 +127,7 @@ router.delete( 204: {}, 403: {}, 404: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -174,7 +174,7 @@ router.get( 200: { body: "APIMessageArray", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/channels/#channel_id/purge.ts b/src/api/routes/channels/#channel_id/purge.ts index c8a2efab9..a710b723d 100644 --- a/src/api/routes/channels/#channel_id/purge.ts +++ b/src/api/routes/channels/#channel_id/purge.ts @@ -43,7 +43,7 @@ router.post( /*body: "PurgeSchema",*/ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, diff --git a/src/api/routes/channels/#channel_id/webhooks.ts b/src/api/routes/channels/#channel_id/webhooks.ts index cddff7135..0c1d4b7aa 100644 --- a/src/api/routes/channels/#channel_id/webhooks.ts +++ b/src/api/routes/channels/#channel_id/webhooks.ts @@ -86,7 +86,7 @@ router.post( 200: { body: "WebhookCreateResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, diff --git a/src/api/routes/channels/preload-messages.ts b/src/api/routes/channels/preload-messages.ts index 47795703c..42e1aadd1 100644 --- a/src/api/routes/channels/preload-messages.ts +++ b/src/api/routes/channels/preload-messages.ts @@ -30,7 +30,7 @@ router.post( 200: { body: "PreloadMessagesResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/guilds/#guild_id/auto-moderation/rules.ts b/src/api/routes/guilds/#guild_id/auto-moderation/rules.ts index e2a84f66e..559477fa8 100644 --- a/src/api/routes/guilds/#guild_id/auto-moderation/rules.ts +++ b/src/api/routes/guilds/#guild_id/auto-moderation/rules.ts @@ -53,7 +53,7 @@ router.post( 200: { body: "AutomodRuleSchemaWithId", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { @@ -102,7 +102,7 @@ router.patch( 200: { body: "AutomodRuleSchemaWithId", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts index 69fa94762..d73fa4578 100644 --- a/src/api/routes/guilds/#guild_id/bans.ts +++ b/src/api/routes/guilds/#guild_id/bans.ts @@ -200,7 +200,7 @@ router.put( permission: "BAN_MEMBERS", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/bulk-ban.ts b/src/api/routes/guilds/#guild_id/bulk-ban.ts index 6de43231e..fde3cd87c 100644 --- a/src/api/routes/guilds/#guild_id/bulk-ban.ts +++ b/src/api/routes/guilds/#guild_id/bulk-ban.ts @@ -40,7 +40,7 @@ router.post( 200: { body: "Ban", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts index af4e029f2..553171b8a 100644 --- a/src/api/routes/guilds/#guild_id/channels.ts +++ b/src/api/routes/guilds/#guild_id/channels.ts @@ -62,7 +62,7 @@ router.post( 201: { body: "Channel", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { @@ -96,7 +96,7 @@ router.patch( permission: "MANAGE_CHANNELS", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts index 446d31d60..01c4aadb6 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts @@ -89,7 +89,7 @@ router.patch( 200: { body: "Member", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts index 5c72429b9..3945637b8 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts @@ -30,7 +30,7 @@ router.patch( 200: { body: "APIPublicMember", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/profile/index.ts b/src/api/routes/guilds/#guild_id/profile/index.ts index 66e223d8e..cbc159bdb 100644 --- a/src/api/routes/guilds/#guild_id/profile/index.ts +++ b/src/api/routes/guilds/#guild_id/profile/index.ts @@ -37,7 +37,7 @@ router.patch( 200: { body: "Member", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts index 4ee632259..67ce9e38b 100644 --- a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts @@ -62,7 +62,7 @@ router.delete( permission: "MANAGE_ROLES", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { @@ -108,7 +108,7 @@ router.patch( 200: { body: "Role", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts index 8f671b15f..0c25ca914 100644 --- a/src/api/routes/guilds/#guild_id/roles/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/index.ts @@ -52,7 +52,7 @@ router.post( 200: { body: "Role", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { @@ -128,7 +128,7 @@ router.patch( 200: { body: "APIRoleArray", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/stickers.ts b/src/api/routes/guilds/#guild_id/stickers.ts index b361f258f..931c3cd55 100644 --- a/src/api/routes/guilds/#guild_id/stickers.ts +++ b/src/api/routes/guilds/#guild_id/stickers.ts @@ -72,7 +72,7 @@ router.post( 200: { body: "Sticker", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { @@ -165,7 +165,7 @@ router.patch( 200: { body: "Sticker", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/templates.ts b/src/api/routes/guilds/#guild_id/templates.ts index ef9d12c60..a17308852 100644 --- a/src/api/routes/guilds/#guild_id/templates.ts +++ b/src/api/routes/guilds/#guild_id/templates.ts @@ -70,7 +70,7 @@ router.post( 200: { body: "Template", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts index 1e6025033..0bfb86a06 100644 --- a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts +++ b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts @@ -37,7 +37,7 @@ router.patch( requestBody: "VoiceStateUpdateSchema", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/#guild_id/welcome-screen.ts b/src/api/routes/guilds/#guild_id/welcome-screen.ts index 03907f60c..ab889b823 100644 --- a/src/api/routes/guilds/#guild_id/welcome-screen.ts +++ b/src/api/routes/guilds/#guild_id/welcome-screen.ts @@ -56,7 +56,7 @@ router.patch( permission: "MANAGE_GUILD", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/guilds/#guild_id/widget.png.ts b/src/api/routes/guilds/#guild_id/widget.png.ts index 005b26725..eeae20cf5 100644 --- a/src/api/routes/guilds/#guild_id/widget.png.ts +++ b/src/api/routes/guilds/#guild_id/widget.png.ts @@ -37,7 +37,7 @@ router.get( route({ responses: { 200: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/guilds/#guild_id/widget.ts b/src/api/routes/guilds/#guild_id/widget.ts index 7ea8dce0d..4bbaee590 100644 --- a/src/api/routes/guilds/#guild_id/widget.ts +++ b/src/api/routes/guilds/#guild_id/widget.ts @@ -58,7 +58,7 @@ router.patch( 200: { body: "WidgetModifySchema", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/guilds/automations/email-domain-lookup.ts b/src/api/routes/guilds/automations/email-domain-lookup.ts index b6d3338bf..800c520f9 100644 --- a/src/api/routes/guilds/automations/email-domain-lookup.ts +++ b/src/api/routes/guilds/automations/email-domain-lookup.ts @@ -35,7 +35,7 @@ router.post( 200: { body: "EmailDomainLookupResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, @@ -70,7 +70,7 @@ router.post( // 200: { // body: "EmailDomainLookupVerifyCodeResponse", // }, - 400: { + "4XX": { body: "APIErrorResponse", }, 501: {}, diff --git a/src/api/routes/guilds/index.ts b/src/api/routes/guilds/index.ts index 0794eaa8d..fca78292f 100644 --- a/src/api/routes/guilds/index.ts +++ b/src/api/routes/guilds/index.ts @@ -40,7 +40,7 @@ router.post( 201: { body: "GuildCreateResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/hub-waitlist.ts b/src/api/routes/hub-waitlist.ts index 2d21ad634..e6d9ebe62 100644 --- a/src/api/routes/hub-waitlist.ts +++ b/src/api/routes/hub-waitlist.ts @@ -32,7 +32,7 @@ router.post( 200: { body: "HubWaitlistSignupResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/oauth2/authorize.ts b/src/api/routes/oauth2/authorize.ts index 54891a51c..67b0713f3 100644 --- a/src/api/routes/oauth2/authorize.ts +++ b/src/api/routes/oauth2/authorize.ts @@ -44,7 +44,7 @@ router.get( responses: { // TODO: I really didn't feel like typing all of it out 200: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { @@ -181,7 +181,7 @@ router.post( 200: { body: "OAuthAuthorizeResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: { diff --git a/src/api/routes/read-states/ack-bulk.ts b/src/api/routes/read-states/ack-bulk.ts index 475b223ad..bd032c087 100644 --- a/src/api/routes/read-states/ack-bulk.ts +++ b/src/api/routes/read-states/ack-bulk.ts @@ -28,7 +28,7 @@ router.post( requestBody: "AckBulkSchema", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/updates.ts b/src/api/routes/updates.ts index 5262dc2d0..919e7443c 100644 --- a/src/api/routes/updates.ts +++ b/src/api/routes/updates.ts @@ -29,7 +29,7 @@ router.get( 200: { body: "UpdatesResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/#user_id/messages.ts b/src/api/routes/users/#user_id/messages.ts index 9ce0b3699..2cad261a2 100644 --- a/src/api/routes/users/#user_id/messages.ts +++ b/src/api/routes/users/#user_id/messages.ts @@ -29,7 +29,7 @@ router.get( 200: { body: "DmMessagesResponseSchema", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/users/@me/disable.ts b/src/api/routes/users/@me/disable.ts index 07e06055d..30d6edfbe 100644 --- a/src/api/routes/users/@me/disable.ts +++ b/src/api/routes/users/@me/disable.ts @@ -28,7 +28,7 @@ router.post( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/guilds.ts b/src/api/routes/users/@me/guilds.ts index 78adbbd4d..6192d49e7 100644 --- a/src/api/routes/users/@me/guilds.ts +++ b/src/api/routes/users/@me/guilds.ts @@ -62,7 +62,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/guilds/#guild_id/settings.ts b/src/api/routes/users/@me/guilds/#guild_id/settings.ts index 593006f6f..adcf0441d 100644 --- a/src/api/routes/users/@me/guilds/#guild_id/settings.ts +++ b/src/api/routes/users/@me/guilds/#guild_id/settings.ts @@ -51,7 +51,7 @@ router.patch( requestBody: "UserGuildSettingsSchema", responses: { 200: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts index cb4bb442b..d79dd0e67 100644 --- a/src/api/routes/users/@me/index.ts +++ b/src/api/routes/users/@me/index.ts @@ -59,7 +59,7 @@ router.patch( 200: { body: "UserUpdateResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts index 6dba4bb08..498c50b3f 100644 --- a/src/api/routes/users/@me/mfa/codes-verification.ts +++ b/src/api/routes/users/@me/mfa/codes-verification.ts @@ -36,7 +36,7 @@ router.post( 200: { body: "APIBackupCodeArray", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/mfa/codes.ts b/src/api/routes/users/@me/mfa/codes.ts index 389dc01d2..0e7e3f568 100644 --- a/src/api/routes/users/@me/mfa/codes.ts +++ b/src/api/routes/users/@me/mfa/codes.ts @@ -42,7 +42,7 @@ router.post( 200: { body: "APIBackupCodeArray", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/mfa/totp/disable.ts b/src/api/routes/users/@me/mfa/totp/disable.ts index b266fcfe8..6d02ba06f 100644 --- a/src/api/routes/users/@me/mfa/totp/disable.ts +++ b/src/api/routes/users/@me/mfa/totp/disable.ts @@ -37,7 +37,7 @@ router.post( 200: { body: "TokenOnlyResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts index 3d6f4a80d..c8a9c0cd1 100644 --- a/src/api/routes/users/@me/mfa/totp/enable.ts +++ b/src/api/routes/users/@me/mfa/totp/enable.ts @@ -38,7 +38,7 @@ router.post( 200: { body: "TokenWithBackupCodesResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts index 1225cd34f..007bebef6 100644 --- a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts +++ b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts @@ -77,7 +77,7 @@ router.post( 200: { body: "WebAuthnCreateResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, }, diff --git a/src/api/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts index 675552750..e5e71997f 100644 --- a/src/api/routes/users/@me/relationships.ts +++ b/src/api/routes/users/@me/relationships.ts @@ -76,7 +76,7 @@ router.put( requestBody: "RelationshipPutSchema", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { @@ -104,7 +104,7 @@ router.post( requestBody: "RelationshipPostSchema", responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { @@ -137,7 +137,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts index 82ca5addb..26dad6a1f 100644 --- a/src/api/routes/users/@me/settings.ts +++ b/src/api/routes/users/@me/settings.ts @@ -49,7 +49,7 @@ router.patch( 200: { body: "UserSettings", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: { diff --git a/src/api/routes/webhooks/#webhook_id/#token/github.ts b/src/api/routes/webhooks/#webhook_id/#token/github.ts index eb9ec4254..4f84b9721 100644 --- a/src/api/routes/webhooks/#webhook_id/#token/github.ts +++ b/src/api/routes/webhooks/#webhook_id/#token/github.ts @@ -541,7 +541,7 @@ router.post( }, responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, diff --git a/src/api/routes/webhooks/#webhook_id/#token/index.ts b/src/api/routes/webhooks/#webhook_id/#token/index.ts index fd9b8c36b..5a45b733b 100644 --- a/src/api/routes/webhooks/#webhook_id/#token/index.ts +++ b/src/api/routes/webhooks/#webhook_id/#token/index.ts @@ -99,7 +99,7 @@ router.post( }, responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -113,7 +113,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -160,7 +160,7 @@ router.patch( 200: { body: "Message", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, diff --git a/src/api/routes/webhooks/#webhook_id/index.ts b/src/api/routes/webhooks/#webhook_id/index.ts index 878985ee2..31ac764cc 100644 --- a/src/api/routes/webhooks/#webhook_id/index.ts +++ b/src/api/routes/webhooks/#webhook_id/index.ts @@ -66,7 +66,7 @@ router.delete( route({ responses: { 204: {}, - 400: { + "4XX": { body: "APIErrorResponse", }, 404: {}, @@ -122,7 +122,7 @@ router.patch( 200: { body: "WebhookCreateResponse", }, - 400: { + "4XX": { body: "APIErrorResponse", }, 403: {}, diff --git a/src/api/util/handlers/route.ts b/src/api/util/handlers/route.ts index 24c3416d1..0d0a616af 100644 --- a/src/api/util/handlers/route.ts +++ b/src/api/util/handlers/route.ts @@ -58,7 +58,7 @@ export interface RouteOptions { right?: RightResolvable; requestBody?: `${string}Schema`; // typescript interface name responses?: { - [status: number]: { + [status: number | string]: { // body?: `${string}Response`; body?: string; }; @@ -75,6 +75,7 @@ export interface RouteOptions { }; }; deprecated?: boolean; + ratelimitBucket?: string; // test?: { // response?: RouteResponse; // body?: unknown;