import Toast, { type IToastProps } from '@/app/components/base/toast' import { uploadGitHub } from '@/service/plugins' import { compareVersion, getLatestVersion } from '@/utils/semver' import type { GitHubRepoReleaseResponse } from '../types' import { GITHUB_ACCESS_TOKEN } from '@/config' const formatReleases = (releases: any) => { return releases.map((release: any) => ({ tag_name: release.tag_name, assets: release.assets.map((asset: any) => ({ browser_download_url: asset.browser_download_url, name: asset.name, })), })) } export const useGitHubReleases = () => { const fetchReleases = async (owner: string, repo: string) => { try { if (!GITHUB_ACCESS_TOKEN) { // Fetch releases without authentication from client const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases`) if (!res.ok) throw new Error('Failed to fetch repository releases') const data = await res.json() return formatReleases(data) } else { // Fetch releases with authentication from server const res = await fetch(`/repos/${owner}/${repo}/releases`) const bodyJson = await res.json() if (bodyJson.status !== 200) throw new Error(bodyJson.data.message) return formatReleases(bodyJson.data) } } catch (error) { if (error instanceof Error) { Toast.notify({ type: 'error', message: error.message, }) } else { Toast.notify({ type: 'error', message: 'Failed to fetch repository releases', }) } return [] } } const checkForUpdates = (fetchedReleases: GitHubRepoReleaseResponse[], currentVersion: string) => { let needUpdate = false const toastProps: IToastProps = { type: 'info', message: 'No new version available', } if (fetchedReleases.length === 0) { toastProps.type = 'error' toastProps.message = 'Input releases is empty' return { needUpdate, toastProps } } const versions = fetchedReleases.map(release => release.tag_name) const latestVersion = getLatestVersion(versions) try { needUpdate = compareVersion(latestVersion, currentVersion) === 1 if (needUpdate) toastProps.message = `New version available: ${latestVersion}` } catch { needUpdate = false toastProps.type = 'error' toastProps.message = 'Fail to compare versions, please check the version format' } return { needUpdate, toastProps } } return { fetchReleases, checkForUpdates } } export const useGitHubUpload = () => { const handleUpload = async ( repoUrl: string, selectedVersion: string, selectedPackage: string, onSuccess?: (GitHubPackage: { manifest: any; unique_identifier: string }) => void, ) => { try { const response = await uploadGitHub(repoUrl, selectedVersion, selectedPackage) const GitHubPackage = { manifest: response.manifest, unique_identifier: response.unique_identifier, } if (onSuccess) onSuccess(GitHubPackage) return GitHubPackage } catch (error) { Toast.notify({ type: 'error', message: 'Error uploading package', }) throw error } } return { handleUpload } }