109 lines
2.9 KiB
TypeScript
109 lines
2.9 KiB
TypeScript
import { Router } from "@oak/oak";
|
|
import { authMiddleware } from "../middleware/auth.ts";
|
|
import {
|
|
type APIResponse,
|
|
type Dump,
|
|
type FollowStatus,
|
|
type PaginatedData,
|
|
} from "../model/interfaces.ts";
|
|
import {
|
|
followPlaylist,
|
|
followUser,
|
|
getFollowedPlaylistsDumpFeed,
|
|
getFollowedUsersDumpFeed,
|
|
getFollowStatus,
|
|
unfollowPlaylist,
|
|
unfollowUser,
|
|
} from "../services/follow-service.ts";
|
|
|
|
const router = new Router({ prefix: "/api/follows" });
|
|
|
|
// Static routes first to prevent Oak matching "status"/"feed" as a :param
|
|
|
|
// GET /api/follows/status
|
|
router.get("/status", authMiddleware, (ctx) => {
|
|
const status = getFollowStatus(ctx.state.user.userId as string);
|
|
const body: APIResponse<FollowStatus> = { success: true, data: status };
|
|
ctx.response.body = body;
|
|
});
|
|
|
|
// GET /api/follows/feed/users?page=&limit=
|
|
router.get("/feed/users", authMiddleware, (ctx) => {
|
|
const page = Math.max(
|
|
1,
|
|
parseInt(ctx.request.url.searchParams.get("page") ?? "1") || 1,
|
|
);
|
|
const limit = Math.min(
|
|
Math.max(
|
|
1,
|
|
parseInt(ctx.request.url.searchParams.get("limit") ?? "20") || 20,
|
|
),
|
|
100,
|
|
);
|
|
const { items, total } = getFollowedUsersDumpFeed(
|
|
ctx.state.user.userId as string,
|
|
page,
|
|
limit,
|
|
);
|
|
const data: PaginatedData<Dump> = {
|
|
items,
|
|
total,
|
|
hasMore: page * limit < total,
|
|
};
|
|
const body: APIResponse<PaginatedData<Dump>> = { success: true, data };
|
|
ctx.response.body = body;
|
|
});
|
|
|
|
// GET /api/follows/feed/playlists?page=&limit=
|
|
router.get("/feed/playlists", authMiddleware, (ctx) => {
|
|
const page = Math.max(
|
|
1,
|
|
parseInt(ctx.request.url.searchParams.get("page") ?? "1") || 1,
|
|
);
|
|
const limit = Math.min(
|
|
Math.max(
|
|
1,
|
|
parseInt(ctx.request.url.searchParams.get("limit") ?? "20") || 20,
|
|
),
|
|
100,
|
|
);
|
|
const { items, total } = getFollowedPlaylistsDumpFeed(
|
|
ctx.state.user.userId as string,
|
|
page,
|
|
limit,
|
|
);
|
|
const data: PaginatedData<Dump> = {
|
|
items,
|
|
total,
|
|
hasMore: page * limit < total,
|
|
};
|
|
const body: APIResponse<PaginatedData<Dump>> = { success: true, data };
|
|
ctx.response.body = body;
|
|
});
|
|
|
|
// POST /api/follows/users/:userId
|
|
router.post("/users/:userId", authMiddleware, (ctx) => {
|
|
followUser(ctx.state.user.userId as string, ctx.params.userId);
|
|
ctx.response.status = 204;
|
|
});
|
|
|
|
// DELETE /api/follows/users/:userId
|
|
router.delete("/users/:userId", authMiddleware, (ctx) => {
|
|
unfollowUser(ctx.state.user.userId as string, ctx.params.userId);
|
|
ctx.response.status = 204;
|
|
});
|
|
|
|
// POST /api/follows/playlists/:playlistId
|
|
router.post("/playlists/:playlistId", authMiddleware, (ctx) => {
|
|
followPlaylist(ctx.state.user.userId as string, ctx.params.playlistId);
|
|
ctx.response.status = 204;
|
|
});
|
|
|
|
// DELETE /api/follows/playlists/:playlistId
|
|
router.delete("/playlists/:playlistId", authMiddleware, (ctx) => {
|
|
unfollowPlaylist(ctx.state.user.userId as string, ctx.params.playlistId);
|
|
ctx.response.status = 204;
|
|
});
|
|
|
|
export default router;
|