Files
RenewCMS/web/src/composables/useUpdate.ts
T

92 lines
2.0 KiB
TypeScript

import { useApi } from '@/composables/useApi'
export type UpdateState =
| 'idle'
| 'downloading'
| 'verifying'
| 'ready'
| 'restarting'
| 'succeeded'
| 'failed'
export interface UpdateNotes {
version: string
released_at: string
items: string[]
}
export interface UpdateProgress {
percent: number
downloaded_bytes: number
total_bytes: number
}
export type UpdateErrorKind = 'download' | 'verification' | 'rolled_back' | 'install'
export type RestartKind = 'update' | 'restart'
export interface UpdateStatus {
current: string
latest: string
available: boolean
release_url: string | null
notes: UpdateNotes | null
checked_at: string | null
can_apply: boolean
state: UpdateState
progress: UpdateProgress | null
error: UpdateErrorKind | null
started_at: string | null
finished_at: string | null
container: boolean
}
export function useUpdate() {
const { request } = useApi()
function getUpdateStatus(): Promise<UpdateStatus> {
return request<UpdateStatus>('/v1/system/update')
}
function checkForUpdate(): Promise<UpdateStatus> {
return request<UpdateStatus>('/v1/system/update/check', { method: 'POST' })
}
function startUpdateDownload(): Promise<UpdateStatus> {
return request<UpdateStatus>('/v1/system/update/download', { method: 'POST' })
}
function requestRestart(kind: RestartKind): Promise<UpdateStatus> {
return request<UpdateStatus>('/v1/system/update/restart', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ kind }),
})
}
function pollUpdateStatus(): Promise<UpdateStatus> {
return request<UpdateStatus>('/v1/system/update', {
onUnauthorized: 'passthrough',
onForbidden: 'passthrough',
})
}
async function isSiteUp(): Promise<boolean> {
try {
const response = await fetch('/healthz', { cache: 'no-store' })
return response.status === 200
} catch {
return false
}
}
return {
getUpdateStatus,
checkForUpdate,
startUpdateDownload,
requestRestart,
pollUpdateStatus,
isSiteUp,
}
}