realworld-hono-drizzle
Version:
A RealWorld backend built with Hono and Drizzle
87 lines (71 loc) • 2.23 kB
text/typescript
import { and, eq } from "drizzle-orm";
import { Hono } from "hono";
import { parse } from "valibot";
import { decode } from "hono/jwt";
import { JwtClaims, exposeToken, jwtAuth } from "../../auth.js";
import { userFollowTable, usersTable } from "../../db/schema.js";
import type { ThisAppEnv } from "../../factory.js";
import { ProfileResponse } from "./schema.js";
export const profilesModule = new Hono<ThisAppEnv>();
profilesModule.get("/:username", exposeToken, async (c) => {
const db = c.get("db");
const token = c.get("token");
const self =
token !== undefined ? parse(JwtClaims, decode(token).payload) : null;
const user = await db.query.usersTable.findFirst({
where: eq(usersTable.username, c.req.param("username")),
});
if (user === undefined) {
return c.notFound();
}
const following =
self !== null
? (await db.query.userFollowTable.findFirst({
where: and(
eq(userFollowTable.followerId, self.id),
eq(userFollowTable.followedId, user.id),
),
})) !== undefined
: false;
return c.json(parse(ProfileResponse, { profile: { ...user, following } }));
});
profilesModule.post("/:username/follow", jwtAuth, async (c) => {
const db = c.get("db");
const self = c.get("jwtPayload");
const userToFollow = await db.query.usersTable.findFirst({
where: eq(usersTable.username, c.req.param("username")),
});
if (userToFollow === undefined) {
return c.notFound();
}
await db.insert(userFollowTable).values({
followerId: self.id,
followedId: userToFollow.id,
});
return c.json(
parse(ProfileResponse, { profile: { ...userToFollow, following: true } }),
);
});
profilesModule.delete("/:username/follow", jwtAuth, async (c) => {
const db = c.get("db");
const self = c.get("jwtPayload");
const userToUnfollow = await db.query.usersTable.findFirst({
where: eq(usersTable.username, c.req.param("username")),
});
if (userToUnfollow === undefined) {
return c.notFound();
}
await db
.delete(userFollowTable)
.where(
and(
eq(userFollowTable.followerId, self.id),
eq(userFollowTable.followedId, userToUnfollow.id),
),
);
return c.json(
parse(ProfileResponse, {
profile: { ...userToUnfollow, following: false },
}),
);
});