76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
/**
|
|
* Types the rows the comment service reads from `comments`, and turns them into
|
|
* the {@link Comment} the comment routes send.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import type { SQLOutputValue } from "node:sqlite";
|
|
import type { Comment } from "../../shared/comment.ts";
|
|
|
|
/**
|
|
* Returned by the comment service's `SELECT`s on `comments`, joined with
|
|
* `users` for the `author_` columns.
|
|
*/
|
|
export interface CommentRow {
|
|
id: string;
|
|
dump_id: string;
|
|
user_id: string;
|
|
/** It is null on a top-level comment. */
|
|
parent_id: string | null;
|
|
body: string;
|
|
created_at: string;
|
|
updated_at: string | null;
|
|
/**
|
|
* 1 once deleted. The body is emptied but the row stays, so its replies keep
|
|
* their place in the thread.
|
|
*/
|
|
deleted: number;
|
|
like_count: number;
|
|
author_username: string;
|
|
author_avatar_mime: string | null;
|
|
[key: string]: SQLOutputValue;
|
|
}
|
|
|
|
/** Checks whether a row `node:sqlite` returned 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 `row` to the {@link Comment} the comment routes send and the
|
|
* WebSocket broadcasts.
|
|
*/
|
|
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,
|
|
};
|
|
}
|