diff --git a/assets/openapi.json b/assets/openapi.json index 23da8478a..c7d9c6f0b 100644 Binary files a/assets/openapi.json and b/assets/openapi.json differ diff --git a/assets/schemas.json b/assets/schemas.json index 97ea6b1b5..8879a307d 100644 Binary files a/assets/schemas.json and b/assets/schemas.json differ diff --git a/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts b/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts index daed64f61..d210709a9 100644 --- a/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts +++ b/src/api/routes_toplevel/%2Ewell-known/spacebar/client.ts @@ -19,6 +19,7 @@ import { Router, Response, Request } from "express"; import { route } from "@spacebar/api/middlewares"; import { Config } from "@spacebar/util"; +import { SpacebarWellKnownClientResponse } from "@spacebar/schemas/api/spacebar/WellKnown"; const router = Router({ mergeParams: true }); @@ -27,21 +28,26 @@ router.get( route({ spacebarOnly: true, authentication: "never", + responses: { + 200: { + body: "SpacebarWellKnownClientResponse", + }, + }, }), (req: Request, res: Response) => { res.json({ api: { - baseUrl: Config.get().api.endpointPublic?.split("/api/")[0], + baseUrl: Config.get().api.endpointPublic!.split("/api/")[0], apiVersions: { default: Config.get().api.defaultVersion, active: Config.get().api.activeVersions, }, }, cdn: { - baseUrl: Config.get().cdn.endpointPublic, + baseUrl: Config.get().cdn.endpointPublic!, }, gateway: { - baseUrl: Config.get().gateway.endpointPublic, + baseUrl: Config.get().gateway.endpointPublic!, encoding: ["etf", "json"], compression: ["zstd-stream", "zlib-stream", null], }, @@ -49,9 +55,9 @@ router.get( Config.get().admin.endpointPublic === null ? undefined : { - baseUrl: Config.get().admin.endpointPublic, + baseUrl: Config.get().admin.endpointPublic!, }, - }); + } satisfies SpacebarWellKnownClientResponse); }, ); diff --git a/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts b/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts index 1a5961362..472571e5d 100644 --- a/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts +++ b/src/api/routes_toplevel/%2Ewell-known/spacebar/index.ts @@ -19,6 +19,7 @@ import { Router, Response, Request } from "express"; import { route } from "@spacebar/api/middlewares"; import { Config } from "@spacebar/util"; +import { SpacebarWellKnownLegacyResponse } from "@spacebar/schemas/api/spacebar/WellKnown"; const router = Router({ mergeParams: true }); @@ -28,11 +29,16 @@ router.get( spacebarOnly: true, authentication: "never", deprecated: true, + responses: { + 200: { + body: "SpacebarWellKnownLegacyResponse", + }, + }, }), (req: Request, res: Response) => { res.json({ api: (Config.get().api.endpointPublic + "/api/").replace("//api/", "/api/"), - }); + } satisfies SpacebarWellKnownLegacyResponse); }, ); diff --git a/src/schemas/api/spacebar/WellKnown.ts b/src/schemas/api/spacebar/WellKnown.ts new file mode 100644 index 000000000..cc21f5d8f --- /dev/null +++ b/src/schemas/api/spacebar/WellKnown.ts @@ -0,0 +1,42 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2026 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 . +*/ + +export interface SpacebarWellKnownLegacyResponse { + api: string; +} + +export interface SpacebarWellKnownClientResponse { + api: { + baseUrl: string; + apiVersions: { + default: string; + active: string[]; + }; + }; + cdn: { + baseUrl: string; + }; + gateway: { + baseUrl: string; + encoding: string[]; + compression: (string | null)[]; + }; + admin?: { + baseUrl: string; + }; +}