/** * The `comments` table: its row type, its guard, and its mapper to the API's * {@link Comment}. * * @module */ import type { SQLOutputValue } from "node:sqlite"; import type { Comment } from "../../shared/comment.ts"; /** A row of the `comments` table, joined with its author. */ export interface CommentRow { /** The comment's id. */ id: string; /** The id of the dump it is posted under. */ dump_id: string; /** The author's id. */ user_id: string; /** The id of the comment it replies to; null at the top level. */ parent_id: string | null; /** The comment, in Markdown. */ body: string; /** When the comment was posted. */ created_at: string; /** When the comment was last edited, if ever. */ updated_at: string | null; /** * 1 once deleted: the body is emptied but the row stays, so its replies * keep their place. */ deleted: number; /** How many users like the comment. */ like_count: number; /** The author's name (joined). */ author_username: string; /** The author's avatar type, null without one (joined). */ author_avatar_mime: string | null; /** Any other column the query selects. */ [key: string]: SQLOutputValue; } /** Checks whether `obj` is a {@link CommentRow}. */ export function isCommentRow( obj: unknown, ): obj is CommentRow { return !!obj && typeof obj === "object" && "id" in obj && typeof obj.id === "string" && "dump_id" in obj && typeof obj.dump_id === "string" && "user_id" in obj && typeof obj.user_id === "string" && "parent_id" in obj && (typeof obj.parent_id === "string" || obj.parent_id === null) && "body" in obj && typeof obj.body === "string" && "created_at" in obj && typeof obj.created_at === "string" && "updated_at" in obj && (typeof obj.updated_at === "string" || obj.updated_at === null) && "deleted" in obj && typeof obj.deleted === "number" && "like_count" in obj && typeof obj.like_count === "number" && "author_username" in obj && typeof obj.author_username === "string" && "author_avatar_mime" in obj && (typeof obj.author_avatar_mime === "string" || obj.author_avatar_mime === null); } /** Converts a row to the API's {@link Comment}. */ export function commentRowToApi(row: CommentRow): Comment { return { id: row.id, dumpId: row.dump_id, userId: row.user_id, parentId: row.parent_id ?? undefined, body: row.body, createdAt: new Date(row.created_at), updatedAt: row.updated_at ? new Date(row.updated_at) : undefined, deleted: Boolean(row.deleted), likeCount: row.like_count, authorUsername: row.author_username, authorAvatarMime: row.author_avatar_mime ?? undefined, }; }