import { AxiosError } from "axios"; import { applyQueryParameters } from "../utilities/url"; import { axios, apiBaseUrl, extractResponseData, convertToIfErrorCodeIs, getHttpToken, } from "./common"; import { HttpUser } from "./user"; export const kTimelineVisibilities = ["Public", "Register", "Private"] as const; export type TimelineVisibility = typeof kTimelineVisibilities[number]; export interface HttpTimelineInfo { uniqueId: string; title: string; name: string; description: string; owner: HttpUser; visibility: TimelineVisibility; color: string; lastModified: string; members: HttpUser[]; isHighlight: boolean; isBookmark: boolean; manageable: boolean; postable: boolean; } export interface HttpTimelineListQuery { visibility?: TimelineVisibility; relate?: string; relateType?: "own" | "join"; } export interface HttpTimelinePostRequest { name: string; } export interface HttpTimelinePostDataDigest { kind: string; eTag: string; lastUpdated: string; } export interface HttpTimelinePostInfo { id: number; time: string; author: HttpUser; dataList: HttpTimelinePostDataDigest[]; color: string; lastUpdated: string; timelineName: string; editable: boolean; } export interface HttpTimelinePostPostRequestData { contentType: string; data: string; } export interface HttpTimelinePostPostRequest { time?: string; color?: string; dataList: HttpTimelinePostPostRequestData[]; } export interface HttpTimelinePatchRequest { name?: string; title?: string; color?: string; visibility?: TimelineVisibility; description?: string; } export interface HttpTimelinePostPatchRequest { time?: string; color?: string; } export class HttpTimelineNameConflictError extends Error { constructor(public innerError?: AxiosError) { super(); } } export interface IHttpTimelineClient { listTimeline(query: HttpTimelineListQuery): Promise; getTimeline(timelineName: string): Promise; postTimeline(req: HttpTimelinePostRequest): Promise; patchTimeline( timelineName: string, req: HttpTimelinePatchRequest ): Promise; deleteTimeline(timelineName: string): Promise; memberPut(timelineName: string, username: string): Promise; memberDelete(timelineName: string, username: string): Promise; listPost(timelineName: string): Promise; generatePostDataUrl(timelineName: string, postId: number): string; getPostDataAsString(timelineName: string, postId: number): Promise; postPost( timelineName: string, req: HttpTimelinePostPostRequest ): Promise; patchPost( timelineName: string, postId: number, req: HttpTimelinePostPatchRequest ): Promise; deletePost(timelineName: string, postId: number): Promise; } export class HttpTimelineClient implements IHttpTimelineClient { listTimeline(query: HttpTimelineListQuery): Promise { return axios .get( applyQueryParameters(`${apiBaseUrl}/timelines`, query) ) .then(extractResponseData); } getTimeline(timelineName: string): Promise { return axios .get(`${apiBaseUrl}/timelines/${timelineName}`) .then(extractResponseData); } postTimeline(req: HttpTimelinePostRequest): Promise { return axios .post(`${apiBaseUrl}/timelines`, req) .then(extractResponseData) .catch(convertToIfErrorCodeIs(11040101, HttpTimelineNameConflictError)); } patchTimeline( timelineName: string, req: HttpTimelinePatchRequest ): Promise { return axios .patch(`${apiBaseUrl}/timelines/${timelineName}`, req) .then(extractResponseData); } deleteTimeline(timelineName: string): Promise { return axios.delete(`${apiBaseUrl}/timelines/${timelineName}`).then(); } memberPut(timelineName: string, username: string): Promise { return axios .put(`${apiBaseUrl}/timelines/${timelineName}/members/${username}`) .then(); } memberDelete(timelineName: string, username: string): Promise { return axios .delete(`${apiBaseUrl}/timelines/${timelineName}/members/${username}`) .then(); } listPost(timelineName: string): Promise { return axios .get( `${apiBaseUrl}/timelines/${timelineName}/posts` ) .then(extractResponseData); } generatePostDataUrl(timelineName: string, postId: number): string { return applyQueryParameters( `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}/data`, { token: getHttpToken() } ); } getPostDataAsString(timelineName: string, postId: number): Promise { return axios .get( `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}/data`, { responseType: "text", } ) .then(extractResponseData); } postPost( timelineName: string, req: HttpTimelinePostPostRequest ): Promise { return axios .post( `${apiBaseUrl}/timelines/${timelineName}/posts`, req ) .then(extractResponseData); } patchPost( timelineName: string, postId: number, req: HttpTimelinePostPatchRequest ): Promise { return axios .patch( `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}`, req ) .then(extractResponseData); } deletePost(timelineName: string, postId: number): Promise { return axios .delete(`${apiBaseUrl}/timelines/${timelineName}/posts/${postId}`) .then(); } } let client: IHttpTimelineClient = new HttpTimelineClient(); export function getHttpTimelineClient(): IHttpTimelineClient { return client; } export function setHttpTimelineClient( newClient: IHttpTimelineClient ): IHttpTimelineClient { const old = client; client = newClient; return old; }