From 1998f0efc94850ad186256929ee4dd6d92c6ccbd Mon Sep 17 00:00:00 2001 From: Andrei Jiroh Halili Date: Mon, 22 Jul 2024 11:36:49 +0800 Subject: [PATCH] feat(golinks): format with prettier and do more work on database Signed-off-by: Andrei Jiroh Halili --- apps/golinks-v2/src/index.tsx | 4 +- apps/golinks-v2/src/lib/auth.ts | 6 +- apps/golinks-v2/src/lib/db.ts | 252 +++++++++++++++++++++++++------- apps/golinks-v2/src/types.ts | 16 +- 4 files changed, 214 insertions(+), 64 deletions(-) diff --git a/apps/golinks-v2/src/index.tsx b/apps/golinks-v2/src/index.tsx index 4aa8438..80b1e12 100644 --- a/apps/golinks-v2/src/index.tsx +++ b/apps/golinks-v2/src/index.tsx @@ -73,11 +73,11 @@ openapi.get("/api/discord-invites", DiscordInviteLinkList); openapi.post("/api/discord-invites", DiscordInviteLinkCreate); openapi.get("/api/ping", PingPong); openapi.get("/api/commit", CommitHash); -app.post("/api/slack/slash-commands/:command", async (c) => handleSlackCommand(c)) +app.post("/api/slack/slash-commands/:command", async (c) => handleSlackCommand(c)); // Slack bot and slash commands app.get("/slack", async (c) => slackOAuth(c)); -app.get("/slack/callback", async (c) => slackOAuth(c)); +app.get("/auth/slack/callback", async (c) => slackOAuth(c)); app.get("/", (c) => { return c.redirect(homepage); diff --git a/apps/golinks-v2/src/lib/auth.ts b/apps/golinks-v2/src/lib/auth.ts index 41bd282..1788147 100644 --- a/apps/golinks-v2/src/lib/auth.ts +++ b/apps/golinks-v2/src/lib/auth.ts @@ -5,9 +5,9 @@ export async function adminApiKeyAuth(c: Context, next: Next) { return await next(); } - if (c.req.path.startsWith("/api/slack")) { - return await next() - } + if (c.req.path.startsWith("/api/slack")) { + return await next(); + } const adminApiKey = c.env.ADMIN_KEY; const apiKeyHeader = c.req.header("X-Golinks-Admin-Key"); diff --git a/apps/golinks-v2/src/lib/db.ts b/apps/golinks-v2/src/lib/db.ts index b7fde8f..d7d3743 100644 --- a/apps/golinks-v2/src/lib/db.ts +++ b/apps/golinks-v2/src/lib/db.ts @@ -11,7 +11,7 @@ import { getOffset, PAGE_SIZE } from "./utils"; * @param isActive Filter by disabled links * @returns */ -export async function getGoLinks(db: EnvBindings["golinks"], page: number, isActive?: boolean) { +export async function getGoLinks(db: EnvBindings["golinks"], page: number, isActive?: boolean, type?: "golinks" | "wikilinks" | null) { const adapter = new PrismaD1(db); const prisma = new PrismaClient({ adapter }); // Assuming you have a Prisma client instance @@ -19,21 +19,121 @@ export async function getGoLinks(db: EnvBindings["golinks"], page: number, const take = PAGE_SIZE; try { - const result = await prisma.goLink.findMany({ - where: { - is_active: isActive !== undefined ? isActive : undefined, // Filter by isActive if provided - }, - orderBy: { - id: "desc", // Sort by newer IDs - }, - skip, - take, - }); - return result; + if (type == "wikilinks") { + const result = await prisma.wikiLinks.findMany({ + where: { + is_active: isActive !== undefined ? isActive : undefined, // Filter by isActive if provided + }, + orderBy: { + id: "desc", // Sort by newer IDs + }, + skip, + take, + }); + return result; + } else { + const result = await prisma.goLink.findMany({ + where: { + is_active: isActive !== undefined ? isActive : undefined, // Filter by isActive if provided + }, + orderBy: { + id: "desc", // Sort by newer IDs + }, + skip, + take, + }); + return result; + } + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + console.error(`[prisma-client] known client error: ${error.code} - ${error.message}`); + + return Promise.reject(new Error("A error occurred while querying the database.")); + } else { + console.error(`[prisma-client]- Unexpected error`, error); + return Promise.reject(new Error("An unexpected error occurred.")); + } + } +} + +/** + * + * @param db Always point to `c.env.golinks` + * @param slug URL slug to query into + * @param slug Either `golinks` or `wikilinks`, used for handling DB queries. + * @returns + */ +export async function getLink( + db: EnvBindings["golinks"], + slug: string, + type?: "golinks" | "wikilinks" | null, +): Promise | null { + const adapter = new PrismaD1(db); + const prisma = new PrismaClient({ adapter }); + + try { + if (type == "wikilinks") { + const result = prisma.wikiLinks.findUnique({ + where: { + slug: slug, + }, + }); + return result; + } else { + const result = prisma.goLink.findUnique({ + where: { + slug: slug, + }, + }); + return result; + } + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + console.error(`[prisma-client] known client error: ${error.code} - ${error.message}`); + + return Promise.reject(new Error("A error occurred while querying the database.")); + } else { + console.error(`[prisma-client]- Unexpected error`, error); + return Promise.reject(new Error("An unexpected error occurred.")); + } + } +} + +export async function addGoLink( + db: EnvBindings["golinks"], + slug: string, + targetUrl: string, + type?: "golinks" | "wikilinks" | null, +): Promise | null { + const adapter = new PrismaD1(db); + const prisma = new PrismaClient({ adapter }); + + try { + if (type == "wikilinks") { + const result = prisma.wikiLinks.create({ + data: { + slug, + targetUrl, + }, + }); + return result; + } else { + const result = prisma.goLink.create({ + data: { + slug, + targetUrl, + }, + }); + return result; + } } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError) { console.error(`[prisma-client] known client error: ${error.code} - ${error.message}`); + if (error.code === "P2002") { + return Promise.reject(new Error("A Discord invite code with that slug already exists.")); + } + return Promise.reject(new Error("A error occurred while querying the database.")); } else { console.error(`[prisma-client]- Unexpected error`, error); @@ -71,50 +171,31 @@ export async function getDiscordInvites(db: EnvBindings["golinks"], page: n return result; } -/** - * - * @param db Always point to `c.env.golinks` - * @param slug URL slug to query into - * @returns - */ -export async function getLink(db: EnvBindings["golinks"], slug: string): Promise | null { - const adapter = new PrismaD1(db); - const prisma = new PrismaClient({ adapter }); - - const result = prisma.goLink.findUnique({ - where: { - slug: slug, - }, - }); - return result; -} - export async function getDiscordInvite(db: EnvBindings["golinks"], slug: string): Promise | null { const adapter = new PrismaD1(db); const prisma = new PrismaClient({ adapter }); - const result = await prisma.discordInviteLink.findUnique({ - where: { - slug, - }, - }); - return result; -} + try { + const result = await prisma.discordInviteLink.findUnique({ + where: { + slug, + }, + }); + return result; + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + console.error(`[prisma-client] known client error: ${error.code} - ${error.message}`); -export async function addGoLink( - db: EnvBindings["golinks"], - slug: string, - targetUrl: string, -): Promise | null { - const adapter = new PrismaD1(db); - const prisma = new PrismaClient({ adapter }); - const result = prisma.goLink.create({ - data: { - slug, - targetUrl - }, - }); - return result; + if (error.code === "P2002") { + return Promise.reject(new Error("A Discord invite code with that slug already exists.")); + } + + return Promise.reject(new Error("A error occurred while querying the database.")); + } else { + console.error(`[prisma-client]- Unexpected error`, error); + return Promise.reject(new Error("An unexpected error occurred.")); + } + } } export async function addDiscordInvite( @@ -155,3 +236,72 @@ export async function addDiscordInvite( } } } + +export async function updateDiscordLink( + db: EnvBindings["golinks"], + slug: string, + inviteCode: string, + name?: string, + description?: string, +) { + const adapter = new PrismaD1(db); + const prisma = new PrismaClient({ adapter }); + + try { + const existingData = await prisma.discordInviteLink.findUnique({ + where: { slug }, + }); + + if (existingData) { + const result = await prisma.discordInviteLink.update({ + where: { + slug, + }, + data: { + inviteCode, + name: name !== undefined ? name : existingData.name, + description: description !== undefined ? description : existingData.description, + }, + }); + return result; + } + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + console.error(`[prisma-client] known client error: ${error.code} - ${error.message}`); + + if (error.code === "P2002") { + return Promise.reject(new Error("A Discord invite code with that slug already exists.")); + } + + return Promise.reject(new Error("A error occurred while querying the database.")); + } else { + console.error(`[prisma-client]- Unexpected error`, error); + return Promise.reject(new Error("An unexpected error occurred.")); + } + } +} + +export async function deleteDiscordLink(db: EnvBindings["golinks"], slug: string) { + const adapter = new PrismaD1(db); + const prisma = new PrismaClient({ adapter }); + + try { + const result = prisma.discordInviteLink.delete({ + where: { slug }, + }); + return result; + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + console.error(`[prisma-client] known client error: ${error.code} - ${error.message}`); + + if (error.code === "P2002") { + return Promise.reject(new Error("A Discord invite code with that slug already exists.")); + } + + return Promise.reject(new Error("A error occurred while querying the database.")); + } else { + console.error(`[prisma-client]- Unexpected error`, error); + return Promise.reject(new Error("An unexpected error occurred.")); + } + } +} diff --git a/apps/golinks-v2/src/types.ts b/apps/golinks-v2/src/types.ts index 2ec0015..b62c7e9 100644 --- a/apps/golinks-v2/src/types.ts +++ b/apps/golinks-v2/src/types.ts @@ -26,18 +26,18 @@ export const DiscordInvites = z.object({ /** * Just export WikiLinks as same schema as golinks -*/ -export const WikiLinks = GoLinks + */ +export const WikiLinks = GoLinks; export interface Env { DEPLOY_ENV: "production" | "staging" | "development"; GIT_DEPLOY_COMMIT: string; - SLACK_OAUTH_ID: string - SLACK_OAUTH_SECRET: string, - SLACK_OAUTH_CALLBACK_URL: string, - SLACK_SIGNING_SECRET: string, - GITHUB_OAUTH_ID: string, - GITHUB_OAUTH_SECRET: string, + SLACK_OAUTH_ID: string; + SLACK_OAUTH_SECRET: string; + SLACK_OAUTH_CALLBACK_URL: string; + SLACK_SIGNING_SECRET: string; + GITHUB_OAUTH_ID: string; + GITHUB_OAUTH_SECRET: string; golinks: D1Database; ADMIN_KEY: string; } -- 2.51.2