Files
RedditBot/apps/dashboard/src/features/settings/settings-api.ts
T

68 lines
2.3 KiB
TypeScript

import type { ZodType } from 'zod';
import {
ConfigResponseSchema,
ConfigUpdateRequestSchema,
ConfigUpdateResponseSchema,
ErrorResponseSchema,
LoginStatusResponseSchema,
RedditAccountsResponseSchema,
RedditCookieImportRequestSchema,
RedditCookieImportResponseSchema,
type ConfigResponse,
type ConfigUpdateRequest,
type LoginStatusResponse,
type RedditAccountSummary,
} from '../../../../../packages/api-contracts/src/index.js';
import { dashboardRequest } from '../../api/request.js';
async function parseResponse<T>(response: Response, schema: ZodType<T>): Promise<T> {
const payload: unknown = await response.json();
if (!response.ok) {
const parsedError = ErrorResponseSchema.safeParse(payload);
throw new Error(parsedError.success ? parsedError.data.error : `Request failed (${response.status})`);
}
return schema.parse(payload);
}
function request(path: string, init?: RequestInit): Promise<Response> {
return dashboardRequest(path, init);
}
export function fetchSettings(): Promise<ConfigResponse> {
return request('/api/config').then((response) => parseResponse(response, ConfigResponseSchema));
}
export async function saveSettings(updates: ConfigUpdateRequest) {
const body = ConfigUpdateRequestSchema.parse(updates);
return parseResponse(
await request('/api/config', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
}),
ConfigUpdateResponseSchema,
);
}
export function fetchLoginStatus(): Promise<LoginStatusResponse> {
return request('/api/login/status').then((response) => parseResponse(response, LoginStatusResponseSchema));
}
export function fetchRedditAccounts(): Promise<RedditAccountSummary[]> {
return request('/api/accounts').then((response) => parseResponse(response, RedditAccountsResponseSchema));
}
export async function importRedditSession(exported: unknown): Promise<RedditAccountSummary> {
const body = RedditCookieImportRequestSchema.parse(exported);
const response = await parseResponse(
await request('/api/login/session-import', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
}),
RedditCookieImportResponseSchema,
);
if (!response.ok) throw new Error(response.error);
return response.account;
}