/** * A dump is what users post: a link or a file, with a title and a note. This * module types it as the API sends it, with its link preview and the bodies * that create and edit it. The backend's `dump-service.ts` produces these types * and the frontend's dump pages and create form consume them. * * @module */ /** * Built by a provider of `rich-content-service.ts` when a link is posted or * previewed, and stored with the dump as JSON. The frontend's * `RichContentCard` and player read it. */ export interface RichContent { /** * The provider that read the page: `youtube`, `bandcamp`, `soundcloud` or * `generic`. The player picks how to play the link by it. */ type: string; url: string; siteName?: string; title?: string; description?: string; /** * A real preview image (og:image, a large content image, a video still). * Never a favicon — an absent value means "this page offers no artwork", * which is what makes the generated placeholder possible. */ thumbnailUrl?: string; /** Used as the placeholder's glyph. */ faviconUrl?: string; /** The page's declared brand color, normalized to `#rrggbb`. */ accentColor?: string; /** Set for a YouTube link only. */ videoId?: string; embedUrl?: string; } /** * Returned by every endpoint that answers dumps, and pushed to clients by the * `dump_created` and `dump_updated` socket messages. A URL dump has `url` and * `richContent`, a file dump the `file…` fields. A private dump reaches its * poster only. */ export interface Dump { id: string; kind: "url" | "file"; title: string; /** Made from the title. The dump's page URL takes it in place of the id. */ slug?: string; /** The poster's note on the dump, in Markdown. */ comment?: string; userId: string; createdAt: Date; updatedAt?: Date; url?: string; richContent?: RichContent; fileName?: string; fileMime?: string; fileSize?: number; voteCount: number; /** Deleted comments are not counted. */ commentCount: number; isPrivate: boolean; /** Set when the poster uploaded a custom thumbnail. */ thumbnailMime?: string; categoryIds?: string[]; } /** * Returned by `GET /api/dumps/by-url` for each dump already posted with the * link being typed, and shown by the create form's `DuplicateNotice`. It holds * only what the notice displays. */ export interface DumpUrlMatch { id: string; slug?: string; title: string; /** The poster's username. */ username: string; createdAt: Date; voteCount: number; commentCount: number; } /** * Returned by `GET /api/preview` to the create form, which shows it before the * link is posted. */ export interface LinkPreview { /** * False when the page couldn't be fetched. `richContent` is then a stub * holding the host name, and this flag is how the form tells a dead link * from a page with no preview. */ reached: boolean; /** * Null only for a link that doesn't parse, which the route rejects before * fetching anyway. */ richContent: RichContent | null; } /** * Passed by the create form to `POST /api/dumps` as a JSON body, to post a * link. A file is posted as a multipart form instead. */ export interface CreateUrlDumpRequest { url: string; /** Replaces the title read from the page, when the poster edited it. */ title?: string; comment?: string; isPrivate?: boolean; categoryIds?: string[]; } /** * Passed to `PUT /api/dumps/:dumpId` by the edit page, and by the dump page's * inline title edit. A field left out stays as it is. */ export interface UpdateDumpRequest { /** Ignored for a file dump. A changed link has its preview fetched again. */ url?: string; title?: string; /** `null` removes the note. */ comment?: string | null; isPrivate?: boolean; /** Replaces the current categories. */ categoryIds?: string[]; } /** * Returned by `POST /api/attachments` to the text editor, which inserts the * image into the body as a link to `GET /api/attachments/:id`. */ export interface AttachmentResponse { id: string; }