Base utilities, add README, Redis, Discord integration, db keygroup planning

This commit is contained in:
2024-11-18 07:31:25 -05:00
parent ab5907355d
commit d982567c7b
10 changed files with 640 additions and 346 deletions

88
src/apiutils.ts Normal file
View File

@@ -0,0 +1,88 @@
import { Context, Next } from "@oak/oak";
import Logging from "@proxnet/undead-logging";
const log = new Logging('APIUtils');
export function generateRandomString(length: number) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let randomString = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
randomString += characters.charAt(randomIndex);
}
return randomString;
}
const instanceId = generateRandomString(128);
export function checkQueryTypes<T>(typeDef: T) {
return (ctx: Context, nxt: Next) => {
for (const key in typeDef) {
if (typeof Object.fromEntries(ctx.request.url.searchParams)[key] !== typeof (typeDef)[key]) {
ctx.response.status = 400;
setContentType(ctx, 'application/json');
ctx.response.body = JSON.stringify(genericResponseFormat(true, "One or more query parameters were invalid or not found."));
return;
}
}
nxt();
};
}
export function checkBodyTypes<T>(typeDef: T) {
return async (ctx: Context, nxt: Next) => {
for (const key in typeDef) {
if (typeof (await ctx.request.body.json())[key] !== typeof (typeDef)[key]) {
log.e(`Body check for key '${key}' failed.`);
ctx.response.status = 400;
setContentType(ctx, 'application/json');
ctx.response.body = JSON.stringify(genericResponseFormat(true, "One or more body values were invalid or not found."));
return;
}
}
nxt();
};
}
export function genericResponseFormat(failure: boolean, msg: string | null = null, data = null) {
return { failed: failure, instance: instanceId, message: msg, data: data };
}
export function genericResponse(failure: boolean, msg: string | null = null, data = null) {
return (ctx: Context) => {
setContentType(ctx, 'application/json');
ctx.response.body = JSON.stringify({ failed: failure, instance: instanceId, message: msg, data: data });
};
}
type RecNetResponse = {
Success: boolean,
Message: string
};
export function RecNetResponse(success: boolean, message: string) {
const msg: RecNetResponse = { Success: success, Message: message };
return (ctx: Context) => {
setContentType(ctx, 'application/json');
ctx.response.body = JSON.stringify(msg);
}
}
export async function logBody(ctx: Context, nxt: Next) {
nxt();
log.d(`Request body: ${JSON.stringify(await ctx.request.body.text())}`);
}
export function emptyArrayResponse(ctx: Context) {
setContentType(ctx, 'application/json');
ctx.response.body = JSON.stringify([]);
}
export function setJSONBody(ctx: Context, obj: object) {
ctx.response.type = 'json';
ctx.response.body = JSON.stringify(obj);
}
export function setContentType(ctx: Context, type: string) {
ctx.response.headers.set('Content-Type', type);
}
export * as APIUtils from "./apiutils.ts"