1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-05 10:22:31 +01:00

fixing lots of openapi crap

This commit is contained in:
Puyodead1 2023-03-24 18:14:47 -04:00
parent 777e7208dc
commit 6b3a3b750f
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
60 changed files with 79183 additions and 79519 deletions

File diff suppressed because it is too large Load Diff

7
openapitools.json Normal file
View File

@ -0,0 +1,7 @@
{
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "6.4.0"
}
}

View File

@ -27,34 +27,46 @@ require("missing-native-js-functions");
const openapiPath = path.join(__dirname, "..", "assets", "openapi.json");
const SchemaPath = path.join(__dirname, "..", "assets", "schemas.json");
let schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
for (var schema in schemas) {
const part = schemas[schema];
for (var key in part.properties) {
if (part.properties[key].anyOf) {
const nullIndex = part.properties[key].anyOf.findIndex(
(x) => x.type == "null",
);
if (nullIndex != -1) {
part.properties[key].nullable = true;
part.properties[key].anyOf.splice(nullIndex, 1);
if (part.properties[key].anyOf.length == 1) {
Object.assign(
part.properties[key],
part.properties[key].anyOf[0],
);
delete part.properties[key].anyOf;
}
}
}
}
}
const specification = JSON.parse(
fs.readFileSync(openapiPath, { encoding: "utf8" }),
);
const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
// const specification = JSON.parse(
// fs.readFileSync(openapiPath, { encoding: "utf8" }),
// );
let specification = {
openapi: "3.1.0",
info: {
title: "Fosscord Server",
description:
"Fosscord is a free open source selfhostable discord compatible chat, voice and video platform",
license: {
name: "AGPLV3",
url: "https://www.gnu.org/licenses/agpl-3.0.en.html",
},
version: "1.0.0",
},
externalDocs: {
description: "Fosscord Docs",
url: "https://docs.fosscord.com",
},
servers: [
{
url: "https://staging.fosscord.com/api/",
description: "Official Fosscord Instance",
},
],
components: {
securitySchemes: {
bearer: {
type: "http",
scheme: "bearer",
description: "Bearer/Bot prefixes are not required.",
bearerFormat: "JWT",
in: "header",
},
},
},
tags: [],
paths: {},
};
function combineSchemas(schemas) {
var definitions = {};
@ -72,6 +84,11 @@ function combineSchemas(schemas) {
}
for (const key in definitions) {
const reg = new RegExp(/^[a-zA-Z0-9\.\-_]+$/, "gm");
if (!reg.test(key)) {
console.error(`Invalid schema name: ${key} (${reg.test(key)})`);
continue;
}
specification.components = specification.components || {};
specification.components.schemas =
specification.components.schemas || {};
@ -102,30 +119,20 @@ function getTag(key) {
function apiRoutes() {
const routes = getRouteDescriptions();
const tags = Array.from(routes.keys()).map((x) => getTag(x));
specification.tags = specification.tags || [];
specification.tags = [...specification.tags.map((x) => x.name), ...tags]
.unique()
.map((x) => ({ name: x }));
specification.components = specification.components || {};
specification.components.securitySchemes = {
bearer: {
type: "http",
scheme: "bearer",
description: "Bearer/Bot prefixes are not required.",
},
};
// populate tags
const tags = Array.from(routes.keys())
.map((x) => getTag(x))
.sort((a, b) => a.localeCompare(b));
specification.tags = tags.unique().map((x) => ({ name: x }));
routes.forEach((route, pathAndMethod) => {
const [p, method] = pathAndMethod.split("|");
const path = p.replace(/:(\w+)/g, "{$1}");
specification.paths = specification.paths || {};
let obj = specification.paths[path]?.[method] || {};
obj["x-right-required"] = route.right;
obj["x-permission-required"] = route.permission;
obj["x-fires-event"] = route.test?.event;
obj["x-fires-event"] = route.event;
if (
!NO_AUTHORIZATION_ROUTES.some((x) => {
@ -136,12 +143,17 @@ function apiRoutes() {
obj.security = [{ bearer: [] }];
}
if (route.body) {
if (route.description) obj.description = route.description;
if (route.summary) obj.summary = route.summary;
if (route.requestBody) {
obj.requestBody = {
required: true,
content: {
"application/json": {
schema: { $ref: `#/components/schemas/${route.body}` },
schema: {
$ref: `#/components/schemas/${route.requestBody}`,
},
},
},
}.merge(obj.requestBody);
@ -150,16 +162,9 @@ function apiRoutes() {
if (route.responses) {
for (const [k, v] of Object.entries(route.responses)) {
let schema = {
allOf: [
{
$ref: `#/components/schemas/${v.body}`,
},
{
example: v.body,
},
],
$ref: `#/components/schemas/${v.body}`,
};
if (!v.body) schema = schema.allOf[0];
// if (!v.body) schema = schema.allOf[0];
obj.responses = {
[k]: {
@ -173,12 +178,16 @@ function apiRoutes() {
},
},
}
: {}),
: {
description: "No description available",
}),
},
}.merge(obj.responses);
delete obj.responses.default;
}
}
// handles path parameters
if (p.includes(":")) {
obj.parameters = p.match(/:\w+/g)?.map((x) => ({
name: x.replace(":", ""),
@ -188,16 +197,17 @@ function apiRoutes() {
description: x.replace(":", ""),
}));
}
obj.tags = [...(obj.tags || []), getTag(p)].unique();
specification.paths[path] = {
...specification.paths[path],
[method]: obj,
};
});
}
function main() {
console.log("Generating OpenAPI Specification...");
combineSchemas(schemas);
apiRoutes();

View File

@ -57,6 +57,8 @@ const Excluded = [
"PropertiesSchema",
"AsyncSchema",
"AnySchema",
"SMTPConnection.CustomAuthenticationResponse",
"TransportMakeRequestResponse",
];
function modify(obj) {

View File

@ -114,7 +114,7 @@ router.post(
router.patch(
"/",
route({
body: "BotModifySchema",
requestBody: "BotModifySchema",
responses: {
200: {
body: "Application",

View File

@ -55,7 +55,7 @@ router.get(
router.patch(
"/",
route({
body: "ApplicationModifySchema",
requestBody: "ApplicationModifySchema",
responses: {
200: {
body: "Application",

View File

@ -48,7 +48,7 @@ router.get(
router.post(
"/",
route({
body: "ApplicationCreateSchema",
requestBody: "ApplicationCreateSchema",
responses: {
200: {
body: "Application",

View File

@ -31,7 +31,7 @@ const router = Router();
router.post(
"/",
route({
body: "ForgotPasswordSchema",
requestBody: "ForgotPasswordSchema",
responses: {
204: {},
400: {

View File

@ -37,7 +37,7 @@ export default router;
router.post(
"/",
route({
body: "LoginSchema",
requestBody: "LoginSchema",
responses: {
200: {
body: "TokenResponse",

View File

@ -26,7 +26,7 @@ const router = Router();
router.post(
"/",
route({
body: "TotpSchema",
requestBody: "TotpSchema",
responses: {
200: {
body: "TokenResponse",

View File

@ -42,7 +42,7 @@ function toArrayBuffer(buf: Buffer) {
router.post(
"/",
route({
body: "WebAuthnTotpSchema",
requestBody: "WebAuthnTotpSchema",
responses: {
200: { body: "TokenResponse" },
400: { body: "APIErrorResponse" },

View File

@ -16,25 +16,25 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import {
Config,
generateToken,
Invite,
FieldErrors,
User,
adjustEmail,
RegisterSchema,
ValidRegistrationToken,
} from "@spacebar/util";
import {
route,
getIpAdress,
IPAnalysis,
getIpAdress,
isProxy,
route,
verifyCaptcha,
} from "@spacebar/api";
import {
Config,
FieldErrors,
Invite,
RegisterSchema,
User,
ValidRegistrationToken,
adjustEmail,
generateToken,
} from "@spacebar/util";
import bcrypt from "bcrypt";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { MoreThan } from "typeorm";
@ -43,7 +43,7 @@ const router: Router = Router();
router.post(
"/",
route({
body: "RegisterSchema",
requestBody: "RegisterSchema",
responses: {
200: { body: "TokenResponse" },
400: { body: "APIErrorOrCaptchaResponse" },

View File

@ -35,7 +35,7 @@ const router = Router();
router.post(
"/",
route({
body: "PasswordResetSchema",
requestBody: "PasswordResetSchema",
responses: {
200: {
body: "TokenResponse",

View File

@ -41,7 +41,7 @@ async function getToken(user: User) {
router.post(
"/",
route({
body: "VerifyEmailSchema",
requestBody: "VerifyEmailSchema",
responses: {
200: {
body: "TokenResponse",

View File

@ -25,7 +25,7 @@ const router = Router();
router.post(
"/",
route({
body: "BackupCodesChallengeSchema",
requestBody: "BackupCodesChallengeSchema",
responses: {
200: { body: "BackupCodesChallengeResponse" },
400: { body: "APIErrorResponse" },

View File

@ -107,7 +107,7 @@ router.delete(
router.patch(
"/",
route({
body: "ChannelModifySchema",
requestBody: "ChannelModifySchema",
permission: "MANAGE_CHANNELS",
responses: {
200: {

View File

@ -35,7 +35,7 @@ const router: Router = Router();
router.post(
"/",
route({
body: "InviteCreateSchema",
requestBody: "InviteCreateSchema",
permission: "CREATE_INSTANT_INVITE",
right: "CREATE_INVITES",
responses: {

View File

@ -34,7 +34,7 @@ const router = Router();
router.post(
"/",
route({
body: "MessageAcknowledgeSchema",
requestBody: "MessageAcknowledgeSchema",
responses: {
200: {},
403: {},

View File

@ -52,7 +52,7 @@ const messageUpload = multer({
router.patch(
"/",
route({
body: "MessageEditSchema",
requestBody: "MessageEditSchema",
permission: "SEND_MESSAGES",
right: "SEND_MESSAGES",
responses: {
@ -152,7 +152,7 @@ router.put(
next();
},
route({
body: "MessageCreateSchema",
requestBody: "MessageCreateSchema",
permission: "SEND_MESSAGES",
right: "SEND_BACKDATED_EVENTS",
responses: {

View File

@ -39,7 +39,7 @@ export default router;
router.post(
"/",
route({
body: "BulkDeleteSchema",
requestBody: "BulkDeleteSchema",
responses: {
204: {},
400: {

View File

@ -220,7 +220,7 @@ router.post(
next();
},
route({
body: "MessageCreateSchema",
requestBody: "MessageCreateSchema",
permission: "SEND_MESSAGES",
right: "SEND_MESSAGES",
responses: {

View File

@ -36,7 +36,7 @@ const router: Router = Router();
router.put(
"/:overwrite_id",
route({
body: "ChannelPermissionOverwriteSchema",
requestBody: "ChannelPermissionOverwriteSchema",
permission: "MANAGE_ROLES",
responses: {
204: {},

View File

@ -54,7 +54,7 @@ router.get(
router.post(
"/",
route({
body: "WebhookCreateSchema",
requestBody: "WebhookCreateSchema",
permission: "MANAGE_WEBHOOKS",
responses: {
200: {

View File

@ -29,7 +29,7 @@ const router = Router();
router.post(
"/",
route({ body: "ConnectionCallbackSchema" }),
route({ requestBody: "ConnectionCallbackSchema" }),
async (req: Request, res: Response) => {
const { connection_name } = req.params;
const connection = ConnectionStore.connections.get(connection_name);

View File

@ -16,20 +16,20 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { getIpAdress, route } from "@spacebar/api";
import {
Ban,
BanModeratorSchema,
BanRegistrySchema,
DiscordApiErrors,
emitEvent,
GuildBanAddEvent,
GuildBanRemoveEvent,
Ban,
User,
Member,
BanRegistrySchema,
BanModeratorSchema,
User,
emitEvent,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { getIpAdress, route } from "@spacebar/api";
const router: Router = Router();
@ -97,7 +97,7 @@ router.get(
router.put(
"/:user_id",
route({ body: "BanCreateSchema", permission: "BAN_MEMBERS" }),
route({ requestBody: "BanCreateSchema", permission: "BAN_MEMBERS" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const banned_user_id = req.params.user_id;
@ -143,7 +143,7 @@ router.put(
router.put(
"/@me",
route({ body: "BanCreateSchema" }),
route({ requestBody: "BanCreateSchema" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;

View File

@ -16,16 +16,16 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api";
import {
Channel,
ChannelUpdateEvent,
emitEvent,
ChannelModifySchema,
ChannelReorderSchema,
ChannelUpdateEvent,
emitEvent,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { route } from "@spacebar/api";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
@ -37,7 +37,10 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }),
route({
requestBody: "ChannelModifySchema",
permission: "MANAGE_CHANNELS",
}),
async (req: Request, res: Response) => {
// creates a new guild channel https://discord.com/developers/docs/resources/guild#create-guild-channel
const { guild_id } = req.params;
@ -54,7 +57,10 @@ router.post(
router.patch(
"/",
route({ body: "ChannelReorderSchema", permission: "MANAGE_CHANNELS" }),
route({
requestBody: "ChannelReorderSchema",
permission: "MANAGE_CHANNELS",
}),
async (req: Request, res: Response) => {
// changes guild channel position
const { guild_id } = req.params;

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
Config,
DiscordApiErrors,
emitEvent,
Emoji,
EmojiCreateSchema,
EmojiModifySchema,
GuildEmojisUpdateEvent,
handleFile,
Member,
Snowflake,
User,
EmojiCreateSchema,
EmojiModifySchema,
emitEvent,
handleFile,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
const router = Router();
@ -63,7 +63,7 @@ router.get("/:emoji_id", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({
body: "EmojiCreateSchema",
requestBody: "EmojiCreateSchema",
permission: "MANAGE_EMOJIS_AND_STICKERS",
}),
async (req: Request, res: Response) => {
@ -113,7 +113,7 @@ router.post(
router.patch(
"/:emoji_id",
route({
body: "EmojiModifySchema",
requestBody: "EmojiModifySchema",
permission: "MANAGE_EMOJIS_AND_STICKERS",
}),
async (req: Request, res: Response) => {

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api";
import {
DiscordApiErrors,
Guild,
GuildUpdateEvent,
GuildUpdateSchema,
Member,
SpacebarApiErrors,
emitEvent,
getPermission,
getRights,
Guild,
GuildUpdateEvent,
handleFile,
Member,
GuildUpdateSchema,
SpacebarApiErrors,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { route } from "@spacebar/api";
const router = Router();
@ -55,7 +55,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.patch(
"/",
route({ body: "GuildUpdateSchema", permission: "MANAGE_GUILD" }),
route({ requestBody: "GuildUpdateSchema", permission: "MANAGE_GUILD" }),
async (req: Request, res: Response) => {
const body = req.body as GuildUpdateSchema;
const { guild_id } = req.params;

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api";
import {
Member,
emitEvent,
Emoji,
getPermission,
getRights,
Role,
GuildMemberUpdateEvent,
emitEvent,
Sticker,
Emoji,
Guild,
GuildMemberUpdateEvent,
handleFile,
Member,
MemberChangeSchema,
Role,
Sticker,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
const router = Router();
@ -47,7 +47,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.patch(
"/",
route({ body: "MemberChangeSchema" }),
route({ requestBody: "MemberChangeSchema" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const member_id =

View File

@ -16,15 +16,15 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { getPermission, Member, PermissionResolvable } from "@spacebar/util";
import { route } from "@spacebar/api";
import { getPermission, Member, PermissionResolvable } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
router.patch(
"/",
route({ body: "MemberNickChangeSchema" }),
route({ requestBody: "MemberNickChangeSchema" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
let permissionString: PermissionResolvable = "MANAGE_NICKNAMES";

View File

@ -31,7 +31,7 @@ const router = Router();
router.patch(
"/:member_id",
route({ body: "MemberChangeProfileSchema" }),
route({ requestBody: "MemberChangeProfileSchema" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
// const member_id =

View File

@ -16,17 +16,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
Role,
Member,
GuildRoleUpdateEvent,
GuildRoleDeleteEvent,
emitEvent,
GuildRoleDeleteEvent,
GuildRoleUpdateEvent,
handleFile,
Member,
Role,
RoleModifySchema,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
const router = Router();
@ -69,7 +69,7 @@ router.delete(
router.patch(
"/",
route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }),
route({ requestBody: "RoleModifySchema", permission: "MANAGE_ROLES" }),
async (req: Request, res: Response) => {
const { role_id, guild_id } = req.params;
const body = req.body as RoleModifySchema;

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api";
import {
Role,
getPermission,
Member,
GuildRoleCreateEvent,
GuildRoleUpdateEvent,
emitEvent,
Config,
DiscordApiErrors,
emitEvent,
getPermission,
GuildRoleCreateEvent,
GuildRoleUpdateEvent,
Member,
Role,
RoleModifySchema,
RolePositionUpdateSchema,
Snowflake,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
import { Not } from "typeorm";
const router: Router = Router();
@ -47,7 +47,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }),
route({ requestBody: "RoleModifySchema", permission: "MANAGE_ROLES" }),
async (req: Request, res: Response) => {
const guild_id = req.params.guild_id;
const body = req.body as RoleModifySchema;
@ -104,7 +104,7 @@ router.post(
router.patch(
"/",
route({ body: "RolePositionUpdateSchema" }),
route({ requestBody: "RolePositionUpdateSchema" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const body = req.body as RolePositionUpdateSchema;

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { route } from "@spacebar/api";
import {
emitEvent,
GuildStickersUpdateEvent,
Member,
ModifyGuildStickerSchema,
Snowflake,
Sticker,
StickerFormatType,
StickerType,
emitEvent,
uploadFile,
ModifyGuildStickerSchema,
} from "@spacebar/util";
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import multer from "multer";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import multer from "multer";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
@ -54,7 +54,7 @@ router.post(
bodyParser,
route({
permission: "MANAGE_EMOJIS_AND_STICKERS",
body: "ModifyGuildStickerSchema",
requestBody: "ModifyGuildStickerSchema",
}),
async (req: Request, res: Response) => {
if (!req.file) throw new HTTPError("missing file");
@ -110,7 +110,7 @@ router.get("/:sticker_id", route({}), async (req: Request, res: Response) => {
router.patch(
"/:sticker_id",
route({
body: "ModifyGuildStickerSchema",
requestBody: "ModifyGuildStickerSchema",
permission: "MANAGE_EMOJIS_AND_STICKERS",
}),
async (req: Request, res: Response) => {

View File

@ -16,11 +16,10 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { generateCode, route } from "@spacebar/api";
import { Guild, Template } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { route } from "@spacebar/api";
import { generateCode } from "@spacebar/api";
const router: Router = Router();
@ -53,7 +52,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({ body: "TemplateCreateSchema", permission: "MANAGE_GUILD" }),
route({ requestBody: "TemplateCreateSchema", permission: "MANAGE_GUILD" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const guild = await Guild.findOneOrFail({
@ -115,7 +114,7 @@ router.put(
router.patch(
"/:code",
route({ body: "TemplateModifySchema", permission: "MANAGE_GUILD" }),
route({ requestBody: "TemplateModifySchema", permission: "MANAGE_GUILD" }),
async (req: Request, res: Response) => {
const { code, guild_id } = req.params;
const { name, description } = req.body;

View File

@ -16,6 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { route } from "@spacebar/api";
import {
Channel,
ChannelType,
@ -23,8 +24,7 @@ import {
Invite,
VanityUrlSchema,
} from "@spacebar/util";
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
const router = Router();
@ -60,7 +60,7 @@ router.get(
router.patch(
"/",
route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }),
route({ requestBody: "VanityUrlSchema", permission: "MANAGE_GUILD" }),
async (req: Request, res: Response) => {
const { guild_id } = req.params;
const body = req.body as VanityUrlSchema;

View File

@ -16,6 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { route } from "@spacebar/api";
import {
Channel,
ChannelType,
@ -26,7 +27,6 @@ import {
VoiceStateUpdateEvent,
VoiceStateUpdateSchema,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
const router = Router();
@ -34,7 +34,7 @@ const router = Router();
router.patch(
"/",
route({ body: "VoiceStateUpdateSchema" }),
route({ requestBody: "VoiceStateUpdateSchema" }),
async (req: Request, res: Response) => {
const body = req.body as VoiceStateUpdateSchema;
const { guild_id } = req.params;

View File

@ -16,10 +16,10 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { Guild, Member, GuildUpdateWelcomeScreenSchema } from "@spacebar/util";
import { HTTPError } from "lambert-server";
import { route } from "@spacebar/api";
import { Guild, GuildUpdateWelcomeScreenSchema, Member } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
const router: Router = Router();
@ -35,7 +35,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.patch(
"/",
route({
body: "GuildUpdateWelcomeScreenSchema",
requestBody: "GuildUpdateWelcomeScreenSchema",
permission: "MANAGE_GUILD",
}),
async (req: Request, res: Response) => {

View File

@ -16,9 +16,9 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { Guild, WidgetModifySchema } from "@spacebar/util";
import { route } from "@spacebar/api";
import { Guild, WidgetModifySchema } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -37,7 +37,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
// https://discord.com/developers/docs/resources/guild#modify-guild-widget
router.patch(
"/",
route({ body: "WidgetModifySchema", permission: "MANAGE_GUILD" }),
route({ requestBody: "WidgetModifySchema", permission: "MANAGE_GUILD" }),
async (req: Request, res: Response) => {
const body = req.body as WidgetModifySchema;
const { guild_id } = req.params;

View File

@ -16,16 +16,16 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import {
Guild,
Config,
getRights,
Member,
DiscordApiErrors,
GuildCreateSchema,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import {
Config,
DiscordApiErrors,
Guild,
GuildCreateSchema,
Member,
getRights,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -33,7 +33,7 @@ const router: Router = Router();
router.post(
"/",
route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }),
route({ requestBody: "GuildCreateSchema", right: "CREATE_GUILDS" }),
async (req: Request, res: Response) => {
const body = req.body as GuildCreateSchema;

View File

@ -16,18 +16,18 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api";
import {
Template,
Config,
DiscordApiErrors,
Guild,
GuildTemplateCreateSchema,
Member,
Role,
Snowflake,
Config,
Member,
GuildTemplateCreateSchema,
Template,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { DiscordApiErrors } from "@spacebar/util";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
const router: Router = Router();
@ -81,7 +81,7 @@ router.get("/:code", route({}), async (req: Request, res: Response) => {
router.post(
"/:code",
route({ body: "GuildTemplateCreateSchema" }),
route({ requestBody: "GuildTemplateCreateSchema" }),
async (req: Request, res: Response) => {
const {
enabled,

View File

@ -16,18 +16,18 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
ApiError,
Application,
ApplicationAuthorizeSchema,
getPermission,
DiscordApiErrors,
Member,
Permissions,
User,
getPermission,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
// TODO: scopes, other oauth types
@ -135,7 +135,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({ body: "ApplicationAuthorizeSchema" }),
route({ requestBody: "ApplicationAuthorizeSchema" }),
async (req: Request, res: Response) => {
const body = req.body as ApplicationAuthorizeSchema;
// const { client_id, scope, response_type, redirect_url } = req.query;

View File

@ -16,14 +16,14 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import { AckBulkSchema, ReadState } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
router.post(
"/",
route({ body: "AckBulkSchema" }),
route({ requestBody: "AckBulkSchema" }),
async (req: Request, res: Response) => {
const body = req.body as AckBulkSchema;

View File

@ -151,7 +151,7 @@ router.get(
router.patch(
"/",
route({ body: "UserProfileModifySchema" }),
route({ requestBody: "UserProfileModifySchema" }),
async (req: Request, res: Response) => {
const body = req.body as UserProfileModifySchema;

View File

@ -16,14 +16,14 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Request, Response, Router } from "express";
import { route } from "@spacebar/api";
import {
Recipient,
DmChannelDTO,
Channel,
DmChannelCreateSchema,
DmChannelDTO,
Recipient,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -41,7 +41,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({ body: "DmChannelCreateSchema" }),
route({ requestBody: "DmChannelCreateSchema" }),
async (req: Request, res: Response) => {
const body = req.body as DmChannelCreateSchema;
res.json(

View File

@ -29,7 +29,7 @@ const router = Router();
// TODO: connection update schema
router.patch(
"/",
route({ body: "ConnectionUpdateSchema" }),
route({ requestBody: "ConnectionUpdateSchema" }),
async (req: Request, res: Response) => {
const { connection_name, connection_id } = req.params;
const body = req.body as ConnectionUpdateSchema;

View File

@ -16,14 +16,14 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api";
import {
Channel,
Member,
OrmUtils,
UserGuildSettingsSchema,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import { Request, Response, Router } from "express";
const router = Router();
@ -38,7 +38,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.patch(
"/",
route({ body: "UserGuildSettingsSchema" }),
route({ requestBody: "UserGuildSettingsSchema" }),
async (req: Request, res: Response) => {
const body = req.body as UserGuildSettingsSchema;

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
User,
PrivateUserProjection,
emitEvent,
UserUpdateEvent,
handleFile,
FieldErrors,
adjustEmail,
Config,
UserModifySchema,
emitEvent,
FieldErrors,
generateToken,
handleFile,
PrivateUserProjection,
User,
UserModifySchema,
UserUpdateEvent,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import bcrypt from "bcrypt";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -45,7 +45,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.patch(
"/",
route({ body: "UserModifySchema" }),
route({ requestBody: "UserModifySchema" }),
async (req: Request, res: Response) => {
const body = req.body as UserModifySchema;

View File

@ -16,21 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
BackupCode,
generateMfaBackupCodes,
User,
CodesVerificationSchema,
DiscordApiErrors,
User,
generateMfaBackupCodes,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
router.post(
"/",
route({ body: "CodesVerificationSchema" }),
route({ requestBody: "CodesVerificationSchema" }),
async (req: Request, res: Response) => {
// const { key, nonce, regenerate } = req.body as CodesVerificationSchema;
const { regenerate } = req.body as CodesVerificationSchema;

View File

@ -16,16 +16,16 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
BackupCode,
FieldErrors,
generateMfaBackupCodes,
User,
MfaCodesSchema,
User,
} from "@spacebar/util";
import bcrypt from "bcrypt";
import { Request, Response, Router } from "express";
const router = Router();
@ -33,7 +33,7 @@ const router = Router();
router.post(
"/",
route({ body: "MfaCodesSchema" }),
route({ requestBody: "MfaCodesSchema" }),
async (req: Request, res: Response) => {
const { password, regenerate } = req.body as MfaCodesSchema;

View File

@ -16,22 +16,22 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import { verifyToken } from "node-2fa";
import { HTTPError } from "lambert-server";
import {
User,
generateToken,
BackupCode,
TotpDisableSchema,
User,
generateToken,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { verifyToken } from "node-2fa";
const router = Router();
router.post(
"/",
route({ body: "TotpDisableSchema" }),
route({ requestBody: "TotpDisableSchema" }),
async (req: Request, res: Response) => {
const body = req.body as TotpDisableSchema;

View File

@ -16,15 +16,15 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Request, Response } from "express";
import {
User,
generateToken,
generateMfaBackupCodes,
TotpEnableSchema,
} from "@spacebar/util";
import { route } from "@spacebar/api";
import {
TotpEnableSchema,
User,
generateMfaBackupCodes,
generateToken,
} from "@spacebar/util";
import bcrypt from "bcrypt";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { verifyToken } from "node-2fa";
@ -32,7 +32,7 @@ const router = Router();
router.post(
"/",
route({ body: "TotpEnableSchema" }),
route({ requestBody: "TotpEnableSchema" }),
async (req: Request, res: Response) => {
const body = req.body as TotpEnableSchema;

View File

@ -73,7 +73,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
route({ body: "WebAuthnPostSchema" }),
route({ requestBody: "WebAuthnPostSchema" }),
async (req: Request, res: Response) => {
if (!WebAuthn.fido2) {
// TODO: I did this for typescript and I can't use !

View File

@ -16,20 +16,20 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {
RelationshipAddEvent,
User,
PublicUserProjection,
RelationshipType,
RelationshipRemoveEvent,
emitEvent,
Relationship,
Config,
} from "@spacebar/util";
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
import { DiscordApiErrors } from "@spacebar/util";
import { route } from "@spacebar/api";
import {
Config,
DiscordApiErrors,
PublicUserProjection,
Relationship,
RelationshipAddEvent,
RelationshipRemoveEvent,
RelationshipType,
User,
emitEvent,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
const router = Router();
@ -60,7 +60,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.put(
"/:id",
route({ body: "RelationshipPutSchema" }),
route({ requestBody: "RelationshipPutSchema" }),
async (req: Request, res: Response) => {
return await updateRelationship(
req,
@ -77,7 +77,7 @@ router.put(
router.post(
"/",
route({ body: "RelationshipPostSchema" }),
route({ requestBody: "RelationshipPostSchema" }),
async (req: Request, res: Response) => {
return await updateRelationship(
req,

View File

@ -16,9 +16,9 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Response, Request } from "express";
import { User, UserSettingsSchema } from "@spacebar/util";
import { route } from "@spacebar/api";
import { User, UserSettingsSchema } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
@ -32,7 +32,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.patch(
"/",
route({ body: "UserSettingsSchema" }),
route({ requestBody: "UserSettingsSchema" }),
async (req: Request, res: Response) => {
const body = req.body as UserSettingsSchema;
if (body.locale === "en") body.locale = "en-US"; // fix discord client crash on unkown locale

View File

@ -52,27 +52,31 @@ export type RouteResponse = {
export interface RouteOptions {
permission?: PermissionResolvable;
right?: RightResolvable;
body?: `${string}Schema`; // typescript interface name
requestBody?: `${string}Schema`; // typescript interface name
responses?: {
[status: number]: {
// body?: `${string}Response`;
body?: string;
};
};
test?: {
response?: RouteResponse;
body?: unknown;
path?: string;
event?: EVENT | EVENT[];
headers?: Record<string, string>;
};
event?: EVENT | EVENT[];
summary?: string;
description?: string;
// test?: {
// response?: RouteResponse;
// body?: unknown;
// path?: string;
// event?: EVENT | EVENT[];
// headers?: Record<string, string>;
// };
}
export function route(opts: RouteOptions) {
let validate: AnyValidateFunction | undefined;
if (opts.body) {
validate = ajv.getSchema(opts.body);
if (!validate) throw new Error(`Body schema ${opts.body} not found`);
if (opts.requestBody) {
validate = ajv.getSchema(opts.requestBody);
if (!validate)
throw new Error(`Body schema ${opts.requestBody} not found`);
}
return async (req: Request, res: Response, next: NextFunction) => {

View File

@ -18,7 +18,9 @@
export interface LazyRequestSchema {
guild_id: string;
channels?: Record<string, [number, number][]>;
channels?: {
[key: string]: [number, number][];
};
activities?: boolean;
threads?: boolean;
typing?: true;

View File

@ -16,12 +16,12 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { UserGuildSettings, ChannelOverride } from "@spacebar/util";
import { ChannelOverride, UserGuildSettings } from "@spacebar/util";
// This sucks. I would use a DeepPartial, my own or typeorms, but they both generate inncorect schema
export interface UserGuildSettingsSchema
extends Partial<Omit<UserGuildSettings, "channel_overrides">> {
channel_overrides?: {
[channel_id: string]: Partial<ChannelOverride>;
[channel_id: string]: ChannelOverride;
};
}

View File

@ -28,9 +28,9 @@ export interface CreateWebAuthnCredentialSchema {
ticket: string;
}
export type WebAuthnPostSchema = Partial<
GenerateWebAuthnCredentialsSchema | CreateWebAuthnCredentialSchema
>;
export type WebAuthnPostSchema =
| GenerateWebAuthnCredentialsSchema
| CreateWebAuthnCredentialSchema;
export interface WebAuthnTotpSchema {
code: string;

View File

@ -58,7 +58,6 @@ export * from "./PurgeSchema";
export * from "./RegisterSchema";
export * from "./RelationshipPostSchema";
export * from "./RelationshipPutSchema";
export * from "./responses";
export * from "./RoleModifySchema";
export * from "./RolePositionUpdateSchema";
export * from "./SelectProtocolSchema";
@ -80,7 +79,4 @@ export * from "./VoiceVideoSchema";
export * from "./WebAuthnSchema";
export * from "./WebhookCreateSchema";
export * from "./WidgetModifySchema";
export * from "./UserRelationsResponse";
export * from "./GatewayResponse";
export * from "./GatewayBotResponse";
export * from "./UserProfileResponse";
export * from "./responses";