68 lines
2.3 KiB
TypeScript
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;
|
|
}
|