git0 0.2.12 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +27780 -0
- package/dist/cli.js.map +331 -0
- package/docs/404.html +2 -2
- package/docs/Footer/index.html +2 -2
- package/docs/assets/js/1df93b7f.1385eba0.js +2 -0
- package/docs/assets/js/22dd74f7.e13ac7a4.js +1 -0
- package/docs/assets/js/28ab763d.192aa3bb.js +1 -0
- package/docs/assets/js/299d276b.c9496717.js +1 -0
- package/docs/assets/js/{68cef36b.c312447e.js → 68cef36b.e5b1975b.js} +1 -1
- package/docs/assets/js/a9cef9d5.a7253e41.js +1 -0
- package/docs/assets/js/c3a618e1.1c56fb03.js +590 -0
- package/docs/assets/js/{main.cf858a7d.js → main.1f646b09.js} +2 -2
- package/docs/assets/js/runtime~main.f69f8f44.js +1 -0
- package/docs/functions/fm/index.html +26 -0
- package/docs/functions/git0/index.html +6 -6
- package/docs/functions/github-api/index.html +20 -20
- package/docs/functions/index.html +889 -71
- package/docs/functions/modules/index.html +4 -3
- package/docs/index.html +2 -2
- package/docs/lunr-index-1749760982052.json +1 -0
- package/docs/lunr-index.json +1 -1
- package/docs/search-doc-1749760982052.json +1 -0
- package/docs/search-doc.json +1 -1
- package/docs/sitemap.xml +1 -1
- package/docs-config/.docusaurus/client-manifest.json +36 -24
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/p/index-466.json +1 -1
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-fm-md-a9c.json +19 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-git-0-md-299.json +4 -0
- package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-index-md-c3a.json +1 -1
- package/docs-config/.docusaurus/globalData.json +10 -5
- package/docs-config/.docusaurus/registry.js +1 -0
- package/docs-config/.docusaurus/routes.js +9 -3
- package/docs-config/.docusaurus/routesChunkNames.json +7 -3
- package/docs-config/src/functions/fm.md +1 -0
- package/docs-config/src/functions/git0.md +2 -2
- package/docs-config/src/functions/github-api.md +34 -17
- package/docs-config/src/functions/index.md +19 -30
- package/docs-config/src/functions/modules.md +1 -0
- package/docs-config/src/functions/typedoc-sidebar.cjs +5 -0
- package/docs-config/src/pages/index.tsx +2 -3
- package/package.json +20 -10
- package/readme.md +19 -21
- package/src/cli.ts +150 -0
- package/src/download.ts +240 -0
- package/src/fm.js +5 -5
- package/src/github-api.ts +237 -0
- package/src/ide.ts +141 -0
- package/src/install.ts +147 -0
- package/src/package-menu.ts +183 -0
- package/src/platform.ts +53 -0
- package/src/releases.ts +159 -0
- package/src/setup.ts +9 -0
- package/src/types.ts +97 -0
- package/src/utils.ts +49 -0
- package/test/download.test.ts +48 -0
- package/test/github-api.test.ts +79 -0
- package/test/package-menu.test.ts +134 -0
- package/test/platform.test.ts +64 -0
- package/test/releases.test.ts +169 -0
- package/docs/assets/js/1df93b7f.d8c05d2c.js +0 -2
- package/docs/assets/js/22dd74f7.237398b4.js +0 -1
- package/docs/assets/js/28ab763d.5714aa16.js +0 -1
- package/docs/assets/js/299d276b.1a1baa1c.js +0 -1
- package/docs/assets/js/c3a618e1.965a31da.js +0 -1
- package/docs/assets/js/runtime~main.7520dc36.js +0 -1
- package/docs/lunr-index-1749613752315.json +0 -1
- package/docs/search-doc-1749613752315.json +0 -1
- package/src/git0.js +0 -380
- package/src/github-api.js +0 -472
- /package/docs/assets/js/{1df93b7f.d8c05d2c.js.LICENSE.txt → 1df93b7f.1385eba0.js.LICENSE.txt} +0 -0
- /package/docs/assets/js/{main.cf858a7d.js.LICENSE.txt → main.1f646b09.js.LICENSE.txt} +0 -0
package/src/github-api.js
DELETED
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
import {grab, log} from 'grab-api.js';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import gitUrlParse from 'git-url-parse';
|
|
4
|
-
import os from 'os';
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
import * as tar from 'tar';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* GitHub API client for downloading repositories, searching, and managing releases
|
|
11
|
-
* @class GithubAPI
|
|
12
|
-
* @example
|
|
13
|
-
* const github = new GithubAPI();
|
|
14
|
-
* const repos = await github.searchRepositories('nodejs');
|
|
15
|
-
* await github.downloadRepo('user/repo', './my-downloads');
|
|
16
|
-
*/
|
|
17
|
-
class GithubAPI {
|
|
18
|
-
/** @constant {number} Number of results to return per page for repository searches */
|
|
19
|
-
static DEFAULT_RESULTS_PER_PAGE = 10;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Creates a new GithubAPI instance
|
|
23
|
-
* @param {Object} [options={}] - Configuration options
|
|
24
|
-
* @param {string} [options.token] - GitHub personal access token (defaults to GITHUB_TOKEN env var)
|
|
25
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
26
|
-
* @param {string} [options.baseURL='https://api.github.com'] - GitHub API base URL
|
|
27
|
-
* @example
|
|
28
|
-
* // Use default settings with environment token
|
|
29
|
-
*
|
|
30
|
-
* // Use custom token
|
|
31
|
-
* const github = new GithubAPI({ token: 'ghp_xxxxxxxxxxxx' });
|
|
32
|
-
*
|
|
33
|
-
* // Enable debug mode
|
|
34
|
-
* const github = new GithubAPI({ debug: true });
|
|
35
|
-
*/
|
|
36
|
-
constructor(options = {}) {
|
|
37
|
-
this.token = options.token || process.env.GITHUB_TOKEN;
|
|
38
|
-
this.debug = options.debug || false;
|
|
39
|
-
this.baseURL = options.baseURL || 'https://api.github.com';
|
|
40
|
-
|
|
41
|
-
this.callGithub = grab.instance({
|
|
42
|
-
debug: this.debug,
|
|
43
|
-
baseURL: this.baseURL,
|
|
44
|
-
timeout: 500,
|
|
45
|
-
headers: this.token ? { Authorization: `token ${this.token}` } : {},
|
|
46
|
-
onError: (error) => {
|
|
47
|
-
if (error.includes('403')) {
|
|
48
|
-
const githubHelpUrl = 'https://github.com/settings/personal-access-tokens/new';
|
|
49
|
-
console.log(chalk.red('Rate limit exceeded. Please set env var GITHUB_TOKEN. Help:\n' + githubHelpUrl));
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Downloads a GitHub repository as a tarball and extracts it to a local directory
|
|
58
|
-
* @param {string} repo - Repository URL or owner/name format
|
|
59
|
-
* @param {string|null} [targetDir=null] - Target directory name (defaults to repo name)
|
|
60
|
-
* @returns {Promise<string>} Path to the extracted repository directory
|
|
61
|
-
* @throws {Error} When repository download fails
|
|
62
|
-
* @example
|
|
63
|
-
*
|
|
64
|
-
* // Download repository to current directory
|
|
65
|
-
* const repoPath = await github.downloadRepo('https://github.com/user/repo');
|
|
66
|
-
*
|
|
67
|
-
* // Download to specific directory
|
|
68
|
-
* const repoPath = await github.downloadRepo('user/repo', 'my-custom-dir');
|
|
69
|
-
*/
|
|
70
|
-
async downloadRepo(repo, targetDir = null) {
|
|
71
|
-
const parsed = gitUrlParse(repo);
|
|
72
|
-
const defaultDir = path.resolve(process.cwd(), targetDir?.length ? targetDir : parsed.name);
|
|
73
|
-
const extractPath = this._getAvailableDirectoryName(defaultDir);
|
|
74
|
-
|
|
75
|
-
// if it picks up a larger owner name, slice to the last part
|
|
76
|
-
if (parsed.owner.includes('/')) {
|
|
77
|
-
parsed.owner = parsed.owner.split('/').slice(-1).join('');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
fs.mkdirSync(extractPath, { recursive: true });
|
|
81
|
-
|
|
82
|
-
let url = `/repos/${parsed.owner}/${parsed.name}/tarball/${parsed.default_branch || 'master'}`;
|
|
83
|
-
|
|
84
|
-
console.log(chalk.blue(`📦 Downloading ${parsed.name} into ${path.basename(extractPath)}...`));
|
|
85
|
-
|
|
86
|
-
const params = {
|
|
87
|
-
onStream: async (res) => {
|
|
88
|
-
const nodeStream = (await import('stream'))?.Readable.fromWeb(res);
|
|
89
|
-
await new Promise((resolve, reject) => {
|
|
90
|
-
nodeStream.pipe(tar.x({
|
|
91
|
-
C: extractPath,
|
|
92
|
-
strip: 1
|
|
93
|
-
})).on('finish', resolve).on('error', reject);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
let response = await this.callGithub(url, params);
|
|
99
|
-
|
|
100
|
-
if (response.error) {
|
|
101
|
-
response = await this.callGithub(url.replace("/master", "/main"), params);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return extractPath;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Searches for GitHub repositories by name and enriches results with release information
|
|
109
|
-
* @param {string} query - Search query for repository names
|
|
110
|
-
* @param {Object} [options={}] - Search options
|
|
111
|
-
* @param {number} [options.getReleaseInfo] - Should also check releases for each result
|
|
112
|
-
* @param {number} [options.perPage] - Number of results per page (defaults to DEFAULT_RESULTS_PER_PAGE)
|
|
113
|
-
* @param {string} [options.sort='stars'] - Sort field (stars, forks, updated)
|
|
114
|
-
* @param {string} [options.order='desc'] - Sort order (asc, desc)
|
|
115
|
-
* @returns {Promise<Array<Object>>} Array of repository objects with release information
|
|
116
|
-
* @throws {Error} When search fails
|
|
117
|
-
* @example
|
|
118
|
-
*
|
|
119
|
-
* const repos = await github.searchRepositories('nodejs');
|
|
120
|
-
* repos.forEach(repo => {
|
|
121
|
-
* console.log(`${repo.name}: ${repo.hasReleases ? 'Has releases' : 'No releases'}`);
|
|
122
|
-
* });
|
|
123
|
-
*
|
|
124
|
-
* // Custom search options
|
|
125
|
-
* const repos = await github.searchRepositories('react', {
|
|
126
|
-
* perPage: 5,
|
|
127
|
-
* sort: 'updated',
|
|
128
|
-
* order: 'desc'
|
|
129
|
-
* });
|
|
130
|
-
*/
|
|
131
|
-
async searchRepositories(query, options = {}) {
|
|
132
|
-
try {
|
|
133
|
-
const {
|
|
134
|
-
perPage = GithubAPI.DEFAULT_RESULTS_PER_PAGE,
|
|
135
|
-
sort = 'stars',
|
|
136
|
-
order = 'desc',
|
|
137
|
-
getReleaseInfo = true
|
|
138
|
-
} = options;
|
|
139
|
-
|
|
140
|
-
const response = await this.callGithub('/search/repositories', {
|
|
141
|
-
q: `${query} in:name`,
|
|
142
|
-
sort,
|
|
143
|
-
order,
|
|
144
|
-
per_page: perPage,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
if (response.error || !response.items) {
|
|
148
|
-
console.log("No response");
|
|
149
|
-
return [];
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return !getReleaseInfo ? response :
|
|
153
|
-
// Check for releases for each repository
|
|
154
|
-
await Promise.all(
|
|
155
|
-
response.items.map(async (repo) => {
|
|
156
|
-
const releases = await this.callGithub(`/repos/${repo.owner.login}/${repo.name}/releases`);
|
|
157
|
-
|
|
158
|
-
const currentPlatform = this.getCurrentPlatform();
|
|
159
|
-
const compatibleReleases = this._filterReleasesByPlatform(releases, currentPlatform);
|
|
160
|
-
const categorizedReleases = this._categorizeReleasesByPlatform(releases);
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
...repo,
|
|
164
|
-
hasReleases: releases?.length > 0,
|
|
165
|
-
hasCompatibleReleases: compatibleReleases?.length > 0,
|
|
166
|
-
releases: compatibleReleases,
|
|
167
|
-
allReleases: categorizedReleases
|
|
168
|
-
};
|
|
169
|
-
})
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
} catch (error) {
|
|
173
|
-
console.error(chalk.red('Search failed:'), error.message);
|
|
174
|
-
throw error;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Downloads a release asset from GitHub and provides installation instructions
|
|
180
|
-
* @param {Object} packageURL - Download URL for the asset
|
|
181
|
-
* @param {string} downloadPath - Directory to download the asset to
|
|
182
|
-
* @returns {Promise<string>} Path to the downloaded file
|
|
183
|
-
* @throws {Error} When download fails
|
|
184
|
-
* @example
|
|
185
|
-
*
|
|
186
|
-
* const asset = 'https://github.com/user/repo/releases/download/v1.0.0/myapp-v1.0.0-linux-x64'
|
|
187
|
-
* const downloadPath = await github.downloadPackage(asset, './downloads/myapp');
|
|
188
|
-
*/
|
|
189
|
-
async downloadPackage(packageURL, downloadPath) {
|
|
190
|
-
const fileName = downloadPath.split('/').slice(-1)?.[0];
|
|
191
|
-
|
|
192
|
-
console.log(chalk.blue(`📦 Downloading ${fileName}...`));
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
await this.callGithub(packageURL, {
|
|
196
|
-
onStream: async (res) => {
|
|
197
|
-
const nodeStream = (await import('stream'))?.Readable.fromWeb(res);
|
|
198
|
-
await new Promise((resolve, reject) => {
|
|
199
|
-
nodeStream.pipe(fs.createWriteStream(downloadPath)).on('finish', resolve).on('error', reject);
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
log(`✅ Downloaded ${fileName} to ${downloadPath}`, true, 'color: green');
|
|
204
|
-
|
|
205
|
-
// Try to make executable if it's a binary
|
|
206
|
-
if (process.platform !== 'win32' && !fileName.includes('.')) {
|
|
207
|
-
try {
|
|
208
|
-
fs.chmodSync(downloadPath, '755');
|
|
209
|
-
console.log(chalk.green(`✅ Made ${fileName} executable`));
|
|
210
|
-
} catch (error) {
|
|
211
|
-
console.log(chalk.yellow(`⚠️ Could not make ${fileName} executable`));
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Provide installation instructions
|
|
216
|
-
this._provideInstallationInstructions(downloadPath, fileName);
|
|
217
|
-
|
|
218
|
-
return downloadPath;
|
|
219
|
-
} catch (error) {
|
|
220
|
-
console.error(chalk.red(`❌ Failed to download ${fileName}:`), error.message);
|
|
221
|
-
throw error;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Parses a GitHub URL or shorthand repository reference
|
|
227
|
-
* @param {string} query - GitHub URL or owner/repo format
|
|
228
|
-
* @returns {Object|false} Parsed git URL object or false if invalid
|
|
229
|
-
* @example
|
|
230
|
-
*
|
|
231
|
-
* // Parse full URL
|
|
232
|
-
* const parsed = github.parseURL('https://github.com/user/repo');
|
|
233
|
-
*
|
|
234
|
-
* // Parse shorthand
|
|
235
|
-
* const parsed = github.parseURL('user/repo');
|
|
236
|
-
*
|
|
237
|
-
* if (parsed) {
|
|
238
|
-
* console.log(`Owner: ${parsed.owner}, Name: ${parsed.name}`);
|
|
239
|
-
* }
|
|
240
|
-
*/
|
|
241
|
-
parseURL(query) {
|
|
242
|
-
if (query.includes('github.com') || query.startsWith('git@github.com:') ||
|
|
243
|
-
query.startsWith('https://') || query.startsWith('git://')) {
|
|
244
|
-
return gitUrlParse(query);
|
|
245
|
-
} else if (/^[\w-]+\/[\w.-]+$/.test(query)) {
|
|
246
|
-
return gitUrlParse(`https://github.com/${query}`);
|
|
247
|
-
}
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Detects the current operating system and architecture
|
|
253
|
-
* @returns {Object} Platform information object
|
|
254
|
-
* @returns {string} returns.os - Normalized OS name (windows, macos, linux)
|
|
255
|
-
* @returns {string} returns.arch - Normalized architecture (x86_64, arm64, arm, i386)
|
|
256
|
-
* @returns {string} returns.platform - Raw Node.js platform string
|
|
257
|
-
* @returns {string} returns.architecture - Raw Node.js architecture string
|
|
258
|
-
* @example
|
|
259
|
-
* const platform = github.getCurrentPlatform();
|
|
260
|
-
* console.log(`Running on ${platform.os} ${platform.arch}`);
|
|
261
|
-
*/
|
|
262
|
-
getCurrentPlatform() {
|
|
263
|
-
const platform = os.platform();
|
|
264
|
-
const arch = os.arch();
|
|
265
|
-
|
|
266
|
-
const platformMap = {
|
|
267
|
-
'win32': 'windows',
|
|
268
|
-
'darwin': 'macos',
|
|
269
|
-
'linux': 'linux'
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
const archMap = {
|
|
273
|
-
'x64': 'x86_64',
|
|
274
|
-
'arm64': 'arm64',
|
|
275
|
-
'arm': 'arm',
|
|
276
|
-
'ia32': 'i386'
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
return {
|
|
280
|
-
os: platformMap[platform] || platform,
|
|
281
|
-
arch: archMap[arch] || arch,
|
|
282
|
-
platform,
|
|
283
|
-
architecture: arch
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Gets repository releases with platform categorization
|
|
289
|
-
* @param {string} owner - Repository owner
|
|
290
|
-
* @param {string} repo - Repository name
|
|
291
|
-
* @returns {Promise<Array<Object>>} Array of categorized releases
|
|
292
|
-
* @example
|
|
293
|
-
* const releases = await github.getReleases('microsoft', 'vscode');
|
|
294
|
-
* console.log(`Found ${releases.length} releases`);
|
|
295
|
-
*/
|
|
296
|
-
async getReleases(owner, repo) {
|
|
297
|
-
const releases = await this.callGithub(`/repos/${owner}/${repo}/releases`);
|
|
298
|
-
return this._categorizeReleasesByPlatform(releases);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Gets releases compatible with the current platform
|
|
303
|
-
* @param {string} owner - Repository owner
|
|
304
|
-
* @param {string} repo - Repository name
|
|
305
|
-
* @returns {Promise<Array<Object>>} Array of compatible releases
|
|
306
|
-
* @example
|
|
307
|
-
* const compatible = await github.getCompatibleReleases('user', 'repo');
|
|
308
|
-
* console.log(`Found ${compatible.length} compatible releases`);
|
|
309
|
-
*/
|
|
310
|
-
async getCompatibleReleases(owner, repo) {
|
|
311
|
-
const releases = await this.callGithub(`/repos/${owner}/${repo}/releases`);
|
|
312
|
-
const currentPlatform = this.getCurrentPlatform();
|
|
313
|
-
return this._filterReleasesByPlatform(releases, currentPlatform);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Generates an available directory name by appending a counter if the base path exists
|
|
318
|
-
* @private
|
|
319
|
-
* @param {string} basePath - The desired base directory path
|
|
320
|
-
* @returns {string} An available directory path
|
|
321
|
-
*/
|
|
322
|
-
_getAvailableDirectoryName(basePath) {
|
|
323
|
-
if (!fs.existsSync(basePath)) return basePath;
|
|
324
|
-
let counter = 2;
|
|
325
|
-
let newPath;
|
|
326
|
-
while (true) {
|
|
327
|
-
newPath = `${basePath}-${counter}`;
|
|
328
|
-
if (!fs.existsSync(newPath)) return newPath;
|
|
329
|
-
counter++;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Categorizes GitHub releases by platform and architecture based on asset names
|
|
335
|
-
* @private
|
|
336
|
-
* @param {Array<Object>} releases - Array of GitHub release objects
|
|
337
|
-
* @returns {Array<Object>} Releases with platformAssets property containing categorized assets
|
|
338
|
-
*/
|
|
339
|
-
_categorizeReleasesByPlatform(releases) {
|
|
340
|
-
const platformKeywords = {
|
|
341
|
-
windows: ['win', 'windows', 'win32', 'win64', '.exe', '.msi'],
|
|
342
|
-
macos: ['mac', 'macos', 'darwin', 'osx', '.dmg', '.pkg'],
|
|
343
|
-
linux: ['linux', 'ubuntu', 'debian', '.deb', '.rpm', '.tar.gz', '.AppImage']
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
const archKeywords = {
|
|
347
|
-
x86_64: ['x86_64', 'x64', 'amd64', '64'],
|
|
348
|
-
arm64: ['arm64', 'aarch64'],
|
|
349
|
-
arm: ['arm', 'armv7'],
|
|
350
|
-
i386: ['i386', 'x86', '32']
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const categorizedReleases = [];
|
|
354
|
-
|
|
355
|
-
Object.entries(releases).forEach(([key, release]) => {
|
|
356
|
-
const platformAssets = {
|
|
357
|
-
windows: [],
|
|
358
|
-
macos: [],
|
|
359
|
-
linux: [],
|
|
360
|
-
universal: []
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
release?.assets?.forEach(asset => {
|
|
364
|
-
const name = asset.name.toLowerCase();
|
|
365
|
-
let categorized = false;
|
|
366
|
-
|
|
367
|
-
// Check each platform
|
|
368
|
-
Object.entries(platformKeywords).forEach(([platform, keywords]) => {
|
|
369
|
-
if (keywords.some(keyword => name.includes(keyword.toLowerCase()))) {
|
|
370
|
-
// Determine architecture
|
|
371
|
-
let detectedArch = 'unknown';
|
|
372
|
-
Object.entries(archKeywords).forEach(([arch, archKeys]) => {
|
|
373
|
-
if (archKeys.some(archKey => name.includes(archKey.toLowerCase()))) {
|
|
374
|
-
detectedArch = arch;
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
platformAssets[platform].push({
|
|
379
|
-
...asset,
|
|
380
|
-
detectedArch,
|
|
381
|
-
platform
|
|
382
|
-
});
|
|
383
|
-
categorized = true;
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// If not categorized, check for universal binaries
|
|
388
|
-
if (!categorized && (name.includes('universal') || name.includes('all') ||
|
|
389
|
-
(!name.includes('win') && !name.includes('mac') && !name.includes('linux')))) {
|
|
390
|
-
platformAssets.universal.push({
|
|
391
|
-
...asset,
|
|
392
|
-
detectedArch: 'universal',
|
|
393
|
-
platform: 'universal'
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
// Only include releases that have assets
|
|
399
|
-
const hasAssets = Object.values(platformAssets).some(assets => assets.length > 0);
|
|
400
|
-
if (hasAssets) {
|
|
401
|
-
categorizedReleases.push({
|
|
402
|
-
...release,
|
|
403
|
-
platformAssets
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
return categorizedReleases;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Filters releases to only include those compatible with the specified platform
|
|
413
|
-
* @private
|
|
414
|
-
* @param {Array<Object>} releases - Array of GitHub release objects
|
|
415
|
-
* @param {Object} currentPlatform - Platform information from getCurrentPlatform()
|
|
416
|
-
* @returns {Array<Object>} Filtered array of compatible releases
|
|
417
|
-
*/
|
|
418
|
-
_filterReleasesByPlatform(releases, currentPlatform) {
|
|
419
|
-
const categorized = this._categorizeReleasesByPlatform(releases);
|
|
420
|
-
return categorized.filter(release =>
|
|
421
|
-
release.platformAssets[currentPlatform.os]?.length > 0 ||
|
|
422
|
-
release.platformAssets.universal?.length > 0
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* Provides platform-specific installation instructions for a downloaded asset
|
|
428
|
-
* @private
|
|
429
|
-
* @param {string} filePath - Path to the downloaded file
|
|
430
|
-
* @param {Object} asset - GitHub release asset object
|
|
431
|
-
* @param {string} asset.name - Name of the asset file
|
|
432
|
-
*/
|
|
433
|
-
_provideInstallationInstructions(filePath, fileName) {
|
|
434
|
-
const platform = this.getCurrentPlatform();
|
|
435
|
-
|
|
436
|
-
if (platform.platform === 'win32') {
|
|
437
|
-
if (fileName.endsWith('.exe')) {
|
|
438
|
-
console.log(chalk.white(' Run the executable:'));
|
|
439
|
-
console.log(chalk.gray(` ${filePath}`));
|
|
440
|
-
} else if (fileName.endsWith('.msi')) {
|
|
441
|
-
console.log(chalk.white(' Install the MSI package:'));
|
|
442
|
-
console.log(chalk.gray(` msiexec /i "${filePath}"`));
|
|
443
|
-
}
|
|
444
|
-
} else if (platform.platform === 'darwin') {
|
|
445
|
-
if (fileName.endsWith('.dmg')) {
|
|
446
|
-
console.log(chalk.white(' Mount and install the DMG:'));
|
|
447
|
-
console.log(chalk.gray(` open "${filePath}"`));
|
|
448
|
-
} else if (fileName.endsWith('.pkg')) {
|
|
449
|
-
console.log(chalk.white(' Install the package:'));
|
|
450
|
-
console.log(chalk.gray(` sudo installer -pkg "${filePath}" -target /`));
|
|
451
|
-
}
|
|
452
|
-
} else {
|
|
453
|
-
if (fileName.endsWith('.deb')) {
|
|
454
|
-
console.log(chalk.white(' Install the DEB package:'));
|
|
455
|
-
console.log(chalk.gray(` sudo dpkg -i "${filePath}"`));
|
|
456
|
-
} else if (fileName.endsWith('.rpm')) {
|
|
457
|
-
console.log(chalk.white(' Install the RPM package:'));
|
|
458
|
-
console.log(chalk.gray(` sudo rpm -i "${filePath}"`));
|
|
459
|
-
} else if (fileName.endsWith('.AppImage')) {
|
|
460
|
-
console.log(chalk.white(' Run the AppImage:'));
|
|
461
|
-
console.log(chalk.gray(` chmod +x "${filePath}" && "${filePath}"`));
|
|
462
|
-
} else if (!fileName.includes('.')) {
|
|
463
|
-
console.log(chalk.white(' Binary is ready to use:'));
|
|
464
|
-
console.log(chalk.gray(` "${filePath}"`));
|
|
465
|
-
console.log(chalk.white(' Consider moving to PATH:'));
|
|
466
|
-
console.log(chalk.gray(` sudo mv "${filePath}" /usr/local/bin/`));
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
export default GithubAPI;
|
/package/docs/assets/js/{1df93b7f.d8c05d2c.js.LICENSE.txt → 1df93b7f.1385eba0.js.LICENSE.txt}
RENAMED
|
File without changes
|
|
File without changes
|