68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
import { z } from 'zod';
|
|
import {
|
|
ActivityResponseSchema,
|
|
ChatSyncStatusSchema,
|
|
ChatSyncTriggerResponseSchema,
|
|
FetchAllChatsResponseSchema,
|
|
} from '../../../../../packages/api-contracts/src/index.js';
|
|
import { createDashboardRequest } from '../../api/request.js';
|
|
|
|
export const RawLogEntrySchema = z.strictObject({
|
|
timestamp: z.number(),
|
|
level: z.union([z.literal('debug'), z.literal('info'), z.literal('warn'), z.literal('error')]),
|
|
message: z.string(),
|
|
data: z.unknown().optional(),
|
|
});
|
|
export const RawLogsResponseSchema = z.array(RawLogEntrySchema);
|
|
export type RawLogEntry = z.infer<typeof RawLogEntrySchema>;
|
|
|
|
async function parseResponse<T>(
|
|
response: Response,
|
|
schema: { parse(value: unknown): T },
|
|
): Promise<T> {
|
|
const payload: unknown = await response.json();
|
|
if (!response.ok) {
|
|
const message =
|
|
typeof payload === 'object' &&
|
|
payload !== null &&
|
|
'error' in payload &&
|
|
typeof payload.error === 'string'
|
|
? payload.error
|
|
: `Request failed (${response.status})`;
|
|
throw new Error(message);
|
|
}
|
|
return schema.parse(payload);
|
|
}
|
|
|
|
export function createOperationsApi(fetchImplementation?: typeof fetch) {
|
|
const request = createDashboardRequest(fetchImplementation);
|
|
return {
|
|
async getActivity() {
|
|
return parseResponse(await request('/api/activity'), ActivityResponseSchema);
|
|
},
|
|
async getLogs(limit = 200) {
|
|
return parseResponse(
|
|
await request(`/api/logs?limit=${limit}`),
|
|
RawLogsResponseSchema,
|
|
);
|
|
},
|
|
async getSyncStatus() {
|
|
return parseResponse(await request('/api/chats/sync'), ChatSyncStatusSchema);
|
|
},
|
|
async triggerSync(kind: 'delta' | 'full') {
|
|
const result = await parseResponse(
|
|
await request(`/api/chats/sync/${kind}`, { method: 'POST' }),
|
|
ChatSyncTriggerResponseSchema,
|
|
);
|
|
if (!('success' in result)) throw new Error(result.error);
|
|
if (!result.success) throw new Error(result.reason);
|
|
return result;
|
|
},
|
|
async fetchAllChats() {
|
|
return parseResponse(await request('/api/chats/fetch-all', { method: 'POST' }), FetchAllChatsResponseSchema);
|
|
},
|
|
};
|
|
}
|
|
|
|
export const operationsApi = createOperationsApi();
|