mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-14 00:00:30 +00:00
91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
import { apiFetchJSON } from '@/utils/apiClient';
|
|
import type { UpdateChannel } from '@/types/config';
|
|
|
|
export interface UpdateInfo {
|
|
available: boolean;
|
|
currentVersion: string;
|
|
latestVersion: string;
|
|
releaseNotes: string;
|
|
releaseDate: string;
|
|
downloadUrl: string;
|
|
isPrerelease: boolean;
|
|
isMajorUpgrade: boolean;
|
|
warning?: string;
|
|
}
|
|
|
|
export interface UpdateStatus {
|
|
status: string;
|
|
progress: number;
|
|
message: string;
|
|
error?: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface VersionInfo {
|
|
version: string;
|
|
build: string;
|
|
runtime: string;
|
|
channel?: UpdateChannel;
|
|
isDocker: boolean;
|
|
isSourceBuild: boolean;
|
|
isDevelopment: boolean;
|
|
deploymentType?: string;
|
|
}
|
|
|
|
export interface UpdatePlan {
|
|
canAutoUpdate: boolean;
|
|
instructions?: string[];
|
|
prerequisites?: string[];
|
|
estimatedTime?: string;
|
|
requiresRoot: boolean;
|
|
rollbackSupport: boolean;
|
|
downloadUrl?: string;
|
|
}
|
|
|
|
const requireNonEmpty = (value: string, fieldName: string): string => {
|
|
const trimmed = value.trim();
|
|
if (!trimmed) {
|
|
throw new Error(`${fieldName} is required`);
|
|
}
|
|
return trimmed;
|
|
};
|
|
|
|
export class UpdatesAPI {
|
|
static async checkForUpdates(channel?: UpdateChannel): Promise<UpdateInfo> {
|
|
const search = new URLSearchParams();
|
|
const trimmedChannel = channel?.trim();
|
|
if (trimmedChannel) {
|
|
search.set('channel', trimmedChannel);
|
|
}
|
|
const query = search.toString();
|
|
const url = query ? `/api/updates/check?${query}` : '/api/updates/check';
|
|
return apiFetchJSON(url);
|
|
}
|
|
|
|
static async applyUpdate(downloadUrl: string): Promise<{ status: string; message: string }> {
|
|
const normalizedDownloadUrl = requireNonEmpty(downloadUrl, 'Download URL');
|
|
return apiFetchJSON('/api/updates/apply', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ downloadUrl: normalizedDownloadUrl }),
|
|
});
|
|
}
|
|
|
|
static async getUpdateStatus(): Promise<UpdateStatus> {
|
|
return apiFetchJSON('/api/updates/status');
|
|
}
|
|
|
|
static async getVersion(): Promise<VersionInfo> {
|
|
return apiFetchJSON('/api/version');
|
|
}
|
|
|
|
static async getUpdatePlan(version: string, channel?: UpdateChannel): Promise<UpdatePlan> {
|
|
const validatedVersion = requireNonEmpty(version, 'Version');
|
|
const search = new URLSearchParams({ version: validatedVersion });
|
|
if (channel) {
|
|
search.set('channel', channel);
|
|
}
|
|
const url = `/api/updates/plan?${search.toString()}`;
|
|
return apiFetchJSON(url);
|
|
}
|
|
}
|