/** * The `playlists` table: its row type, its guard, and its mapper to the API's * {@link Playlist}. * * @module */ import type { SQLOutputValue } from "node:sqlite"; import type { Playlist } from "../../shared/playlist.ts"; /** * A row of the `playlists` table. Queries may add `dump_count` and * `owner_username`, which {@link playlistRowToApi} carries over. */ export interface PlaylistRow { /** The playlist's id. */ id: string; /** The owner's id. */ user_id: string; /** The playlist's title. */ title: string; /** The playlist's URL slug. */ slug: string | null; /** The owner's description, in Markdown. */ description: string | null; /** 1 when anyone may see the playlist, 0 when only its owner does. */ is_public: number; /** When the playlist was created. */ created_at: string; /** When the playlist was last changed, if ever. */ updated_at: string | null; /** The cover image's type, null without one. */ image_mime: string | null; /** Any other column the query selects. */ [key: string]: SQLOutputValue; } /** Checks whether `obj` is a {@link PlaylistRow}. */ export function isPlaylistRow( obj: unknown, ): obj is PlaylistRow { return !!obj && typeof obj === "object" && "id" in obj && typeof obj.id === "string" && "user_id" in obj && typeof obj.user_id === "string" && "title" in obj && typeof obj.title === "string" && "slug" in obj && (typeof obj.slug === "string" || obj.slug === null) && "description" in obj && (typeof obj.description === "string" || obj.description === null) && "is_public" in obj && typeof obj.is_public === "number" && "created_at" in obj && typeof obj.created_at === "string" && "updated_at" in obj && (typeof obj.updated_at === "string" || obj.updated_at === null) && "image_mime" in obj && (typeof obj.image_mime === "string" || obj.image_mime === null); } /** Converts a row to the API's {@link Playlist}. */ export function playlistRowToApi(row: PlaylistRow): Playlist { return { id: row.id, userId: row.user_id, title: row.title, slug: row.slug ?? undefined, description: row.description ?? undefined, isPublic: Boolean(row.is_public), createdAt: new Date(row.created_at), updatedAt: row.updated_at ? new Date(row.updated_at) : undefined, imageMime: row.image_mime ?? undefined, dumpCount: typeof row.dump_count === "number" ? row.dump_count : undefined, ownerUsername: typeof row.owner_username === "string" ? row.owner_username : undefined, }; }