| import { |
| API_V1, |
| CREDENTIALS, |
| UNAUTHORIZED_EVENT, |
| signal, |
| } from "../apiContract"; |
| import type { SurfaceScope } from "./apiBridge"; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function commentsUrl(scope: SurfaceScope, pid: number, suffix = ""): string { |
| return `${API_V1}/customers/${encodeURIComponent(String(pid))}/comments${suffix}` + |
| `?scope=${encodeURIComponent(scope)}`; |
| } |
|
|
| export interface RecordComment { |
| id: string; |
| body: string; |
| authorKey: string; |
| author: string; |
| createdAt: string; |
| } |
|
|
| export class RecordCommentsError extends Error { |
| status: number; |
|
|
| constructor(message: string, status: number) { |
| super(message); |
| this.name = "RecordCommentsError"; |
| this.status = status; |
| } |
| } |
|
|
| async function result<T>(response: Response): Promise<T> { |
| let body: unknown = null; |
| try { |
| body = await response.json(); |
| } catch { |
| |
| } |
| if (response.status === 401) signal(UNAUTHORIZED_EVENT); |
| if (!response.ok) { |
| const shaped = body as { error?: { message?: string } } | null; |
| throw new RecordCommentsError( |
| shaped?.error?.message || `The server answered ${response.status}.`, |
| response.status |
| ); |
| } |
| return body as T; |
| } |
|
|
| export async function fetchRecordComments( |
| scope: SurfaceScope, |
| pid: number, |
| abortSignal?: AbortSignal |
| ): Promise<RecordComment[]> { |
| const response = await fetch(commentsUrl(scope, pid), { |
| credentials: CREDENTIALS, |
| signal: abortSignal, |
| }); |
| const body = await result<{ comments?: RecordComment[] }>(response); |
| return Array.isArray(body.comments) ? body.comments : []; |
| } |
|
|
| export async function postRecordComment( |
| scope: SurfaceScope, |
| pid: number, |
| body: string |
| ): Promise<RecordComment> { |
| const response = await fetch(commentsUrl(scope, pid), { |
| method: "POST", |
| credentials: CREDENTIALS, |
| headers: { "Content-Type": "application/json" }, |
| body: JSON.stringify({ body }), |
| }); |
| const payload = await result<{ comment: RecordComment }>(response); |
| return payload.comment; |
| } |
|
|
| export async function deleteRecordComment( |
| scope: SurfaceScope, |
| pid: number, |
| commentId: string |
| ): Promise<void> { |
| const response = await fetch( |
| commentsUrl(scope, pid, `/${encodeURIComponent(commentId)}`), |
| { |
| method: "DELETE", |
| credentials: CREDENTIALS, |
| } |
| ); |
| await result<{ ok: boolean }>(response); |
| } |
|
|
|
|