diff --git a/assets/openapi.json b/assets/openapi.json index 6f5112a0f..298ad18ec 100644 Binary files a/assets/openapi.json and b/assets/openapi.json differ diff --git a/default.nix b/default.nix index af333012d..691162a6b 100644 --- a/default.nix +++ b/default.nix @@ -18,6 +18,7 @@ let ./tsconfig.json ./assets ./patches + ./scripts ] ) ); @@ -41,7 +42,7 @@ pkgs.buildNpmPackage { npmDeps = pkgs.importNpmLock { npmRoot = filteredSrc; }; npmConfigHook = pkgs.importNpmLock.npmConfigHook; - npmBuildScript = "build:src:tsgo"; + npmBuildScript = "build:tsgo"; makeCacheWritable = true; nativeBuildInputs = with pkgs; [ (pkgs.python3.withPackages (ps: with ps; [ setuptools ])) @@ -64,6 +65,7 @@ pkgs.buildNpmPackage { # remove packages not needed for production, or at least try to... npm prune --omit dev --no-save $npmInstallFlags "''${npmInstallFlagsArray[@]}" $npmFlags "''${npmFlagsArray[@]}" rm -v dist/src.tsbuildinfo + rm -rv scripts time ${./nix/trimNodeModules.sh} # Copy outputs diff --git a/scripts/openapi.js b/scripts/openapi.js index 5afee152a..86d502e24 100644 --- a/scripts/openapi.js +++ b/scripts/openapi.js @@ -213,7 +213,7 @@ function apiRoutes(missingRoutes) { obj.tags = [...new Set([...(obj.tags || []), getTag(p)])]; - if (missingRoutes.additional.includes(path.replace(/\/$/, ""))) { + if (route.spacebarOnly === true || missingRoutes?.additional.includes(path.replace(/\/$/, ""))) { obj["x-badges"] = [ { label: "Spacebar-only", @@ -231,12 +231,13 @@ function apiRoutes(missingRoutes) { 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 missingRoutes = await routesRes.json(); + // const routesRes = await fetch("https://github.com/spacebarchat/missing-routes/raw/main/missing.json", { + // headers: { + // Accept: "application/json", + // }, + // }); + // const missingRoutes = await routesRes.json(); + let missingRoutes = undefined; combineSchemas(schemas); apiRoutes(missingRoutes); diff --git a/src/api/routes/-/healthz.ts b/src/api/routes/-/healthz.ts index de45a29c4..90f6054d5 100644 --- a/src/api/routes/-/healthz.ts +++ b/src/api/routes/-/healthz.ts @@ -22,7 +22,7 @@ import { getDatabase } from "@spacebar/util"; const router = Router({ mergeParams: true }); -router.get("/", route({ deprecated: true }), (req: Request, res: Response) => { +router.get("/", route({ deprecated: true, spacebarOnly: true }), (req: Request, res: Response) => { if (!getDatabase()) return res.sendStatus(503); return res.sendStatus(200); diff --git a/src/api/routes/-/readyz.ts b/src/api/routes/-/readyz.ts index de45a29c4..90f6054d5 100644 --- a/src/api/routes/-/readyz.ts +++ b/src/api/routes/-/readyz.ts @@ -22,7 +22,7 @@ import { getDatabase } from "@spacebar/util"; const router = Router({ mergeParams: true }); -router.get("/", route({ deprecated: true }), (req: Request, res: Response) => { +router.get("/", route({ deprecated: true, spacebarOnly: true }), (req: Request, res: Response) => { if (!getDatabase()) return res.sendStatus(503); return res.sendStatus(200); diff --git a/src/api/routes/applications/detectable.ts b/src/api/routes/applications/detectable.ts index 83122e761..688a7d125 100644 --- a/src/api/routes/applications/detectable.ts +++ b/src/api/routes/applications/detectable.ts @@ -34,6 +34,7 @@ router.get( body: "ApplicationDetectableResponse", }, }, + spacebarOnly: false, // not part of public openapi }), async (req: Request, res: Response) => { // cache for 6 hours diff --git a/src/api/routes/auth/fingerprint.ts b/src/api/routes/auth/fingerprint.ts index a4a49d079..2a77d3c7f 100644 --- a/src/api/routes/auth/fingerprint.ts +++ b/src/api/routes/auth/fingerprint.ts @@ -20,10 +20,17 @@ import { createHash } from "node:crypto"; import { Snowflake } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router({ mergeParams: true }); -router.post("/", route({ responses: { 200: { body: "CreateFingerprintResponse" } } }), (req: Request, res: Response) => { - const snowflake = Snowflake.generate(); - return res.json({ - fingerprint: `${snowflake}.${createHash("sha512").update(snowflake).digest("base64")}`, - }); -}); +router.post( + "/", + route({ + responses: { 200: { body: "CreateFingerprintResponse" } }, + spacebarOnly: false, // not part of public openapi + }), + (req: Request, res: Response) => { + const snowflake = Snowflake.generate(); + return res.json({ + fingerprint: `${snowflake}.${createHash("sha512").update(snowflake).digest("base64")}`, + }); + }, +); export default router; diff --git a/src/api/routes/auth/generate-registration-tokens.ts b/src/api/routes/auth/generate-registration-tokens.ts index a6b70c65b..1493c2dcb 100644 --- a/src/api/routes/auth/generate-registration-tokens.ts +++ b/src/api/routes/auth/generate-registration-tokens.ts @@ -38,6 +38,7 @@ router.get( }, right: "CREATE_REGISTRATION_TOKENS", responses: { 200: { body: "GenerateRegistrationTokensResponse" } }, + spacebarOnly: true, }), async (req: Request, res: Response) => { const count = req.query.count ? parseInt(req.query.count as string) : 1; diff --git a/src/api/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts index 366fb1020..d50f2d0ea 100644 --- a/src/api/routes/auth/mfa/totp.ts +++ b/src/api/routes/auth/mfa/totp.ts @@ -36,6 +36,7 @@ router.post( body: "APIErrorResponse", }, }, + spacebarOnly: false, // not part of public openapi }), async (req: Request, res: Response) => { // const { code, ticket, gift_code_sku_id, login_source } = diff --git a/src/api/routes/auth/mfa/webauthn.ts b/src/api/routes/auth/mfa/webauthn.ts index 3359767c3..8e6c5f039 100644 --- a/src/api/routes/auth/mfa/webauthn.ts +++ b/src/api/routes/auth/mfa/webauthn.ts @@ -41,6 +41,7 @@ router.post( 200: { body: "TokenResponse" }, 400: { body: "APIErrorResponse" }, }, + spacebarOnly: false, // not part of public openapi }), async (req: Request, res: Response) => { if (!WebAuthn.fido2) { diff --git a/src/api/routes/auth/whoami.ts b/src/api/routes/auth/whoami.ts index 4d28b9fab..513663761 100644 --- a/src/api/routes/auth/whoami.ts +++ b/src/api/routes/auth/whoami.ts @@ -30,6 +30,7 @@ router.get( body: "WhoAmIResponse", }, }, + spacebarOnly: true, }), /* interface Request { diff --git a/src/api/routes/beaker.ts b/src/api/routes/beaker.ts index 4eb2941a1..22c1904f4 100644 --- a/src/api/routes/beaker.ts +++ b/src/api/routes/beaker.ts @@ -28,6 +28,7 @@ router.post( responses: { 204: {}, }, + spacebarOnly: false, // Not part of public openapi }), (req: Request, res: Response) => { // TODO: diff --git a/src/api/routes/guild-recommendations.ts b/src/api/routes/guild-recommendations.ts index 38ba10257..37ce779e9 100644 --- a/src/api/routes/guild-recommendations.ts +++ b/src/api/routes/guild-recommendations.ts @@ -32,6 +32,7 @@ router.get( body: "GuildRecommendationsResponse", }, }, + spacebarOnly: false, // Not part of public openapi schema }), async (req: Request, res: Response) => { // const { limit, personalization_disabled } = req.query; diff --git a/src/api/routes/ping.ts b/src/api/routes/ping.ts index be737f840..2a5ec6aa5 100644 --- a/src/api/routes/ping.ts +++ b/src/api/routes/ping.ts @@ -30,6 +30,7 @@ router.get( body: "InstancePingResponse", }, }, + spacebarOnly: true, }), (req: Request, res: Response) => { const { general } = Config.get(); diff --git a/src/api/routes/policies/instance/config.ts b/src/api/routes/policies/instance/config.ts index 946ac8aa8..686ecd1e2 100755 --- a/src/api/routes/policies/instance/config.ts +++ b/src/api/routes/policies/instance/config.ts @@ -30,6 +30,7 @@ router.get( body: "Object", }, }, + spacebarOnly: true, }), async (req: Request, res: Response) => { const general = Config.get(); diff --git a/src/api/routes/policies/instance/domains.ts b/src/api/routes/policies/instance/domains.ts index 339eedb1b..3d3303708 100644 --- a/src/api/routes/policies/instance/domains.ts +++ b/src/api/routes/policies/instance/domains.ts @@ -29,6 +29,7 @@ router.get( body: "InstanceDomainsResponse", }, }, + spacebarOnly: true, }), (req: Request, res: Response) => { const { cdn, gateway, api } = Config.get(); diff --git a/src/api/routes/policies/instance/index.ts b/src/api/routes/policies/instance/index.ts index bb04475f9..31e80bdf0 100644 --- a/src/api/routes/policies/instance/index.ts +++ b/src/api/routes/policies/instance/index.ts @@ -29,6 +29,7 @@ router.get( body: "APIGeneralConfiguration", }, }, + spacebarOnly: true, }), (req: Request, res: Response) => { const { general } = Config.get(); diff --git a/src/api/routes/policies/instance/limits.ts b/src/api/routes/policies/instance/limits.ts index 375c72175..380d9e1a5 100644 --- a/src/api/routes/policies/instance/limits.ts +++ b/src/api/routes/policies/instance/limits.ts @@ -29,6 +29,7 @@ router.get( body: "APILimitsConfiguration", }, }, + spacebarOnly: true, }), (req: Request, res: Response) => { const { limits } = Config.get(); diff --git a/src/api/routes/policies/stats.ts b/src/api/routes/policies/stats.ts index 0edcfd68f..9090d787a 100644 --- a/src/api/routes/policies/stats.ts +++ b/src/api/routes/policies/stats.ts @@ -32,6 +32,7 @@ router.get( body: "APIErrorResponse", }, }, + spacebarOnly: true, }), async (req: Request, res: Response) => { if (!Config.get().security.statsWorldReadable) { diff --git a/src/api/routes/reporting/index.ts b/src/api/routes/reporting/index.ts index dbbd0004a..c4ae61169 100644 --- a/src/api/routes/reporting/index.ts +++ b/src/api/routes/reporting/index.ts @@ -57,6 +57,7 @@ for (const type of Object.values(ReportMenuTypeNames)) { }, 204: {}, }, + spacebarOnly: false, // Maps to /reporting/menu/:id }), (req: Request, res: Response) => { // TODO: implement @@ -76,6 +77,7 @@ for (const type of Object.values(ReportMenuTypeNames)) { }, 204: {}, }, + spacebarOnly: false, // Maps to /reporting/:id }), (req: Request, res: Response) => { // TODO: implement diff --git a/src/api/routes/scheduled-maintenances/upcoming.json.ts b/src/api/routes/scheduled-maintenances/upcoming.json.ts index b21507444..bf8fa5587 100644 --- a/src/api/routes/scheduled-maintenances/upcoming.json.ts +++ b/src/api/routes/scheduled-maintenances/upcoming.json.ts @@ -20,11 +20,17 @@ import { Router, Request, Response } from "express"; import { route } from "@spacebar/api"; const router = Router({ mergeParams: true }); -router.get("/", route({}), (req: Request, res: Response) => { - res.json({ - page: {}, - scheduled_maintenances: {}, - }); -}); +router.get( + "/", + route({ + spacebarOnly: false, // not part of public openapi + }), + (req: Request, res: Response) => { + res.json({ + page: {}, + scheduled_maintenances: {}, + }); + }, +); export default router; diff --git a/src/api/routes/track.ts b/src/api/routes/track.ts index d32061388..fe33b5028 100644 --- a/src/api/routes/track.ts +++ b/src/api/routes/track.ts @@ -21,9 +21,15 @@ import { route } from "@spacebar/api"; const router = Router({ mergeParams: true }); -router.post("/", route({}), (req: Request, res: Response) => { - // TODO: - res.sendStatus(204); -}); +router.post( + "/", + route({ + spacebarOnly: false, // Not part of the public OpenAPI schema + }), + (req: Request, res: Response) => { + // TODO: + res.sendStatus(204); + }, +); export default router; diff --git a/src/api/routes/users/@me/settings-proto/1.ts b/src/api/routes/users/@me/settings-proto/1.ts index d54bdf361..6df652a45 100644 --- a/src/api/routes/users/@me/settings-proto/1.ts +++ b/src/api/routes/users/@me/settings-proto/1.ts @@ -40,6 +40,7 @@ router.get( description: "Whether to try to apply the settings update atomically (default false)", }, }, + spacebarOnly: false, // maps to /users/@me/settings-proto/1 }), async (req: Request, res: Response) => { const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); @@ -59,6 +60,7 @@ router.patch( body: "SettingsProtoUpdateResponse", }, }, + spacebarOnly: false, // maps to /users/@me/settings-proto/1 }), async (req: Request, res: Response) => { const { settings, required_data_version } = req.body as SettingsProtoUpdateSchema; @@ -84,6 +86,7 @@ router.get( body: "SettingsProtoJsonResponse", }, }, + spacebarOnly: true, }), async (req: Request, res: Response) => { const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); @@ -109,6 +112,7 @@ router.patch( description: "Whether to try to apply the settings update atomically (default false)", }, }, + spacebarOnly: true, }), async (req: Request, res: Response) => { const { settings, required_data_version } = req.body as SettingsProtoUpdateJsonSchema; diff --git a/src/api/routes/users/@me/settings-proto/2.ts b/src/api/routes/users/@me/settings-proto/2.ts index 809db8487..ac3280e91 100644 --- a/src/api/routes/users/@me/settings-proto/2.ts +++ b/src/api/routes/users/@me/settings-proto/2.ts @@ -40,6 +40,7 @@ router.get( description: "Whether to try to apply the settings update atomically (default false)", }, }, + spacebarOnly: false, // maps to /users/@me/settings-proto/2 }), async (req: Request, res: Response) => { const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); @@ -59,6 +60,7 @@ router.patch( body: "SettingsProtoUpdateResponse", }, }, + spacebarOnly: false, // maps to /users/@me/settings-proto/2 }), async (req: Request, res: Response) => { const { settings, required_data_version } = req.body as SettingsProtoUpdateSchema; @@ -84,6 +86,7 @@ router.get( body: "SettingsProtoJsonResponse", }, }, + spacebarOnly: true, }), async (req: Request, res: Response) => { const userSettings = await UserSettingsProtos.getOrDefault(req.user_id); @@ -109,6 +112,7 @@ router.patch( description: "Whether to try to apply the settings update atomically (default false)", }, }, + spacebarOnly: true, }), async (req: Request, res: Response) => { const { settings, required_data_version } = req.body as SettingsProtoUpdateJsonSchema; diff --git a/src/api/util/handlers/route.ts b/src/api/util/handlers/route.ts index 7ae00a555..022a522a0 100644 --- a/src/api/util/handlers/route.ts +++ b/src/api/util/handlers/route.ts @@ -64,6 +64,7 @@ export interface RouteOptions { }; }; deprecated?: boolean; + spacebarOnly?: boolean; // test?: { // response?: RouteResponse; // body?: unknown;