hooks.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import Toast, { type IToastProps } from '@/app/components/base/toast'
  2. import { uploadGitHub } from '@/service/plugins'
  3. import { compareVersion, getLatestVersion } from '@/utils/semver'
  4. import type { GitHubRepoReleaseResponse } from '../types'
  5. import { GITHUB_ACCESS_TOKEN } from '@/config'
  6. const formatReleases = (releases: any) => {
  7. return releases.map((release: any) => ({
  8. tag_name: release.tag_name,
  9. assets: release.assets.map((asset: any) => ({
  10. browser_download_url: asset.browser_download_url,
  11. name: asset.name,
  12. })),
  13. }))
  14. }
  15. export const useGitHubReleases = () => {
  16. const fetchReleases = async (owner: string, repo: string) => {
  17. try {
  18. if (!GITHUB_ACCESS_TOKEN) {
  19. // Fetch releases without authentication from client
  20. const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases`)
  21. if (!res.ok) throw new Error('Failed to fetch repository releases')
  22. const data = await res.json()
  23. return formatReleases(data)
  24. }
  25. else {
  26. // Fetch releases with authentication from server
  27. const res = await fetch(`/repos/${owner}/${repo}/releases`)
  28. const bodyJson = await res.json()
  29. if (bodyJson.status !== 200) throw new Error(bodyJson.data.message)
  30. return formatReleases(bodyJson.data)
  31. }
  32. }
  33. catch (error) {
  34. if (error instanceof Error) {
  35. Toast.notify({
  36. type: 'error',
  37. message: error.message,
  38. })
  39. }
  40. else {
  41. Toast.notify({
  42. type: 'error',
  43. message: 'Failed to fetch repository releases',
  44. })
  45. }
  46. return []
  47. }
  48. }
  49. const checkForUpdates = (fetchedReleases: GitHubRepoReleaseResponse[], currentVersion: string) => {
  50. let needUpdate = false
  51. const toastProps: IToastProps = {
  52. type: 'info',
  53. message: 'No new version available',
  54. }
  55. if (fetchedReleases.length === 0) {
  56. toastProps.type = 'error'
  57. toastProps.message = 'Input releases is empty'
  58. return { needUpdate, toastProps }
  59. }
  60. const versions = fetchedReleases.map(release => release.tag_name)
  61. const latestVersion = getLatestVersion(versions)
  62. try {
  63. needUpdate = compareVersion(latestVersion, currentVersion) === 1
  64. if (needUpdate)
  65. toastProps.message = `New version available: ${latestVersion}`
  66. }
  67. catch {
  68. needUpdate = false
  69. toastProps.type = 'error'
  70. toastProps.message = 'Fail to compare versions, please check the version format'
  71. }
  72. return { needUpdate, toastProps }
  73. }
  74. return { fetchReleases, checkForUpdates }
  75. }
  76. export const useGitHubUpload = () => {
  77. const handleUpload = async (
  78. repoUrl: string,
  79. selectedVersion: string,
  80. selectedPackage: string,
  81. onSuccess?: (GitHubPackage: { manifest: any; unique_identifier: string }) => void,
  82. ) => {
  83. try {
  84. const response = await uploadGitHub(repoUrl, selectedVersion, selectedPackage)
  85. const GitHubPackage = {
  86. manifest: response.manifest,
  87. unique_identifier: response.unique_identifier,
  88. }
  89. if (onSuccess) onSuccess(GitHubPackage)
  90. return GitHubPackage
  91. }
  92. catch (error) {
  93. Toast.notify({
  94. type: 'error',
  95. message: 'Error uploading package',
  96. })
  97. throw error
  98. }
  99. }
  100. return { handleUpload }
  101. }