mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
191 lines
6.0 KiB
TypeScript
191 lines
6.0 KiB
TypeScript
import type {
|
|
AppSettings,
|
|
AppSettingsUpdate,
|
|
Channel,
|
|
CommandResponse,
|
|
Contact,
|
|
DedupResult,
|
|
HealthStatus,
|
|
MaintenanceResult,
|
|
Message,
|
|
RadioConfig,
|
|
RadioConfigUpdate,
|
|
TelemetryResponse,
|
|
} from './types';
|
|
|
|
const API_BASE = '/api';
|
|
|
|
async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
|
|
const res = await fetch(`${API_BASE}${url}`, {
|
|
...options,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options?.headers,
|
|
},
|
|
});
|
|
if (!res.ok) {
|
|
const error = await res.text();
|
|
throw new Error(error || res.statusText);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
interface DecryptResult {
|
|
started: boolean;
|
|
total_packets: number;
|
|
message: string;
|
|
}
|
|
|
|
export const api = {
|
|
// Health
|
|
getHealth: () => fetchJson<HealthStatus>('/health'),
|
|
|
|
// Radio config
|
|
getRadioConfig: () => fetchJson<RadioConfig>('/radio/config'),
|
|
updateRadioConfig: (config: RadioConfigUpdate) =>
|
|
fetchJson<RadioConfig>('/radio/config', {
|
|
method: 'PATCH',
|
|
body: JSON.stringify(config),
|
|
}),
|
|
setPrivateKey: (privateKey: string) =>
|
|
fetchJson<{ status: string }>('/radio/private-key', {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ private_key: privateKey }),
|
|
}),
|
|
sendAdvertisement: (flood = true) =>
|
|
fetchJson<{ status: string; flood: boolean }>(
|
|
`/radio/advertise?flood=${flood}`,
|
|
{ method: 'POST' }
|
|
),
|
|
rebootRadio: () =>
|
|
fetchJson<{ status: string; message: string }>('/radio/reboot', {
|
|
method: 'POST',
|
|
}),
|
|
reconnectRadio: () =>
|
|
fetchJson<{ status: string; message: string; connected: boolean }>('/radio/reconnect', {
|
|
method: 'POST',
|
|
}),
|
|
|
|
// Contacts
|
|
getContacts: (limit = 100, offset = 0) =>
|
|
fetchJson<Contact[]>(`/contacts?limit=${limit}&offset=${offset}`),
|
|
getContact: (publicKey: string) => fetchJson<Contact>(`/contacts/${publicKey}`),
|
|
syncContacts: () =>
|
|
fetchJson<{ synced: number }>('/contacts/sync', { method: 'POST' }),
|
|
addContactToRadio: (publicKey: string) =>
|
|
fetchJson<{ status: string }>(`/contacts/${publicKey}/add-to-radio`, {
|
|
method: 'POST',
|
|
}),
|
|
removeContactFromRadio: (publicKey: string) =>
|
|
fetchJson<{ status: string }>(`/contacts/${publicKey}/remove-from-radio`, {
|
|
method: 'POST',
|
|
}),
|
|
deleteContact: (publicKey: string) =>
|
|
fetchJson<{ status: string }>(`/contacts/${publicKey}`, {
|
|
method: 'DELETE',
|
|
}),
|
|
markContactRead: (publicKey: string) =>
|
|
fetchJson<{ status: string; public_key: string }>(`/contacts/${publicKey}/mark-read`, {
|
|
method: 'POST',
|
|
}),
|
|
requestTelemetry: (publicKey: string, password: string) =>
|
|
fetchJson<TelemetryResponse>(`/contacts/${publicKey}/telemetry`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ password }),
|
|
}),
|
|
sendRepeaterCommand: (publicKey: string, command: string) =>
|
|
fetchJson<CommandResponse>(`/contacts/${publicKey}/command`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ command }),
|
|
}),
|
|
|
|
// Channels
|
|
getChannels: () => fetchJson<Channel[]>('/channels'),
|
|
getChannel: (key: string) => fetchJson<Channel>(`/channels/${key}`),
|
|
createChannel: (name: string, key?: string) =>
|
|
fetchJson<Channel>('/channels', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ name, key }),
|
|
}),
|
|
syncChannels: () =>
|
|
fetchJson<{ synced: number }>('/channels/sync', { method: 'POST' }),
|
|
deleteChannel: (key: string) =>
|
|
fetchJson<{ status: string }>(`/channels/${key}`, { method: 'DELETE' }),
|
|
markChannelRead: (key: string) =>
|
|
fetchJson<{ status: string; key: string }>(`/channels/${key}/mark-read`, {
|
|
method: 'POST',
|
|
}),
|
|
|
|
// Messages
|
|
getMessages: (params?: {
|
|
limit?: number;
|
|
offset?: number;
|
|
type?: 'PRIV' | 'CHAN';
|
|
conversation_key?: string;
|
|
}) => {
|
|
const searchParams = new URLSearchParams();
|
|
if (params?.limit) searchParams.set('limit', params.limit.toString());
|
|
if (params?.offset) searchParams.set('offset', params.offset.toString());
|
|
if (params?.type) searchParams.set('type', params.type);
|
|
if (params?.conversation_key)
|
|
searchParams.set('conversation_key', params.conversation_key);
|
|
const query = searchParams.toString();
|
|
return fetchJson<Message[]>(`/messages${query ? `?${query}` : ''}`);
|
|
},
|
|
getMessagesBulk: (
|
|
conversations: Array<{ type: 'PRIV' | 'CHAN'; conversation_key: string }>,
|
|
limitPerConversation: number = 100
|
|
) =>
|
|
fetchJson<Record<string, Message[]>>(
|
|
`/messages/bulk?limit_per_conversation=${limitPerConversation}`,
|
|
{
|
|
method: 'POST',
|
|
body: JSON.stringify(conversations),
|
|
}
|
|
),
|
|
sendDirectMessage: (destination: string, text: string) =>
|
|
fetchJson<Message>('/messages/direct', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ destination, text }),
|
|
}),
|
|
sendChannelMessage: (channelKey: string, text: string) =>
|
|
fetchJson<Message>('/messages/channel', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ channel_key: channelKey, text }),
|
|
}),
|
|
|
|
// Packets
|
|
getUndecryptedPacketCount: () =>
|
|
fetchJson<{ count: number }>('/packets/undecrypted/count'),
|
|
decryptHistoricalPackets: (params: {
|
|
key_type: 'channel' | 'contact';
|
|
channel_key?: string;
|
|
channel_name?: string;
|
|
}) =>
|
|
fetchJson<DecryptResult>('/packets/decrypt/historical', {
|
|
method: 'POST',
|
|
body: JSON.stringify(params),
|
|
}),
|
|
runMaintenance: (pruneUndecryptedDays: number) =>
|
|
fetchJson<MaintenanceResult>('/packets/maintenance', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ prune_undecrypted_days: pruneUndecryptedDays }),
|
|
}),
|
|
deduplicatePackets: () =>
|
|
fetchJson<DedupResult>('/packets/dedup', { method: 'POST' }),
|
|
|
|
// Read State
|
|
markAllRead: () =>
|
|
fetchJson<{ status: string; timestamp: number }>('/read-state/mark-all-read', {
|
|
method: 'POST',
|
|
}),
|
|
|
|
// App Settings
|
|
getSettings: () => fetchJson<AppSettings>('/settings'),
|
|
updateSettings: (settings: AppSettingsUpdate) =>
|
|
fetchJson<AppSettings>('/settings', {
|
|
method: 'PATCH',
|
|
body: JSON.stringify(settings),
|
|
}),
|
|
};
|