1 /**
2 * GitHub Release API Types
3 * Based on GitHub REST API v3
4 * https://docs.github.com/en/rest/releases/releases
5 */
6
7 export interface GitHubUser {
8 login: string
9 id: number
10 node_id: string
11 avatar_url: string
12 url: string
13 html_url: string
14 type: string
15 }
16
17 export interface GitHubAsset {
18 id: number
19 node_id: string
20 name: string
21 label: string | null
22 uploader: GitHubUser
23 content_type: string
24 state: string
25 size: number
26 download_count: number
27 created_at: string
28 updated_at: string
29 browser_download_url: string
30 url: string
31 }
32
33 export interface GitHubRelease {
34 id: number
35 node_id: string
36 tag_name: string
37 target_commitish: string
38 name: string
39 draft: boolean
40 prerelease: boolean
41 created_at: string
42 published_at: string
43 assets: GitHubAsset[]
44 tarball_url: string
45 zipball_url: string
46 body: string
47 author: GitHubUser
48 url: string
49 html_url: string
50 assets_url: string
51 upload_url: string
52 }
53
54 /**
55 * Application-specific types
56 */
57
58 export type PlatformType = 'macOS' | 'Windows' | 'Linux'
59
60 export type ArchitectureType =
61 | 'Apple Silicon'
62 | 'Intel'
63 | 'Universal'
64 | 'x64'
65 | 'ARM64'
66 | 'x86'
67
68 export interface DownloadLink {
69 platform: PlatformType
70 architecture?: ArchitectureType
71 url: string
72 filename: string
73 size: number
74 version: string
75 assetId?: number
76 }
77
78 export interface DownloadsResponse {
79 version: string
80 name: string
81 published_at: string
82 downloads: DownloadLink[]
83 }
84
85 export interface DownloadError {
86 error: string
87 details?: string
88 message?: string
89 }
90
91 /**
92 * Platform detection patterns
93 */
94 export const PLATFORM_PATTERNS = {
95 macOS: {
96 keywords: ['mac', 'darwin'],
97 extensions: ['.dmg', '.pkg'],
98 architectures: {
99 'Apple Silicon': ['arm64', 'aarch64', 'apple'],
100 'Intel': ['x64', 'intel', 'x86_64'],
101 'Universal': ['universal']
102 }
103 },
104 Windows: {
105 keywords: ['win', 'windows'],
106 extensions: ['.exe', '.msi', '.msix'],
107 architectures: {
108 'x64': ['x64', 'x86_64', 'amd64'],
109 'ARM64': ['arm64', 'aarch64'],
110 'x86': ['x86', 'ia32', 'i386']
111 }
112 },
113 Linux: {
114 keywords: ['linux'],
115 extensions: ['.appimage', '.deb', '.rpm', '.tar.gz', '.snap'],
116 architectures: {
117 'x64': ['x64', 'x86_64', 'amd64'],
118 'ARM64': ['arm64', 'aarch64'],
119 'x86': ['x86', 'i386']
120 }
121 }
122 } as const
123
124 /**
125 * Helper type guards
126 */
127 export function isDownloadsResponse(data: unknown): data is DownloadsResponse {
128 return (
129 typeof data === 'object' &&
130 data !== null &&
131 'version' in data &&
132 'downloads' in data &&
133 Array.isArray((data as DownloadsResponse).downloads)
134 )
135 }
136
137 export function isDownloadError(data: unknown): data is DownloadError {
138 return (
139 typeof data === 'object' &&
140 data !== null &&
141 'error' in data
142 )
143 }