hostdb 0.10.0
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/LICENSE +131 -0
- package/README.md +228 -0
- package/bin/cli.js +75 -0
- package/cli/bin.ts +527 -0
- package/databases.json +943 -0
- package/downloads.json +1766 -0
- package/lib/checksums.ts +98 -0
- package/lib/databases.ts +82 -0
- package/package.json +67 -0
- package/releases.json +658 -0
package/cli/bin.ts
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* hostdb CLI
|
|
4
|
+
*
|
|
5
|
+
* Query and download database binaries from hostdb releases.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
loadDatabasesJson,
|
|
10
|
+
loadReleasesJson,
|
|
11
|
+
type Platform,
|
|
12
|
+
type PlatformAsset,
|
|
13
|
+
} from '../lib/databases.js'
|
|
14
|
+
|
|
15
|
+
// Aliases for databases
|
|
16
|
+
const DATABASE_ALIASES: Record<string, string> = {
|
|
17
|
+
postgres: 'postgresql',
|
|
18
|
+
pg: 'postgresql',
|
|
19
|
+
mongo: 'mongodb',
|
|
20
|
+
maria: 'mariadb',
|
|
21
|
+
ch: 'clickhouse',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Aliases for platforms - maps to array of platforms
|
|
25
|
+
const PLATFORM_ALIASES: Record<string, Platform[]> = {
|
|
26
|
+
// macOS
|
|
27
|
+
mac: ['darwin-arm64', 'darwin-x64'],
|
|
28
|
+
macos: ['darwin-arm64', 'darwin-x64'],
|
|
29
|
+
darwin: ['darwin-arm64', 'darwin-x64'],
|
|
30
|
+
osx: ['darwin-arm64', 'darwin-x64'],
|
|
31
|
+
apple: ['darwin-arm64', 'darwin-x64'],
|
|
32
|
+
// macOS specific
|
|
33
|
+
'mac-arm': ['darwin-arm64'],
|
|
34
|
+
'mac-intel': ['darwin-x64'],
|
|
35
|
+
'm1': ['darwin-arm64'],
|
|
36
|
+
'm2': ['darwin-arm64'],
|
|
37
|
+
'm3': ['darwin-arm64'],
|
|
38
|
+
'm4': ['darwin-arm64'],
|
|
39
|
+
// Windows
|
|
40
|
+
win: ['win32-x64'],
|
|
41
|
+
windows: ['win32-x64'],
|
|
42
|
+
win32: ['win32-x64'],
|
|
43
|
+
win64: ['win32-x64'],
|
|
44
|
+
// Linux
|
|
45
|
+
linux: ['linux-x64', 'linux-arm64'],
|
|
46
|
+
ubuntu: ['linux-x64', 'linux-arm64'],
|
|
47
|
+
debian: ['linux-x64', 'linux-arm64'],
|
|
48
|
+
// Linux specific
|
|
49
|
+
'linux-amd64': ['linux-x64'],
|
|
50
|
+
'linux-aarch64': ['linux-arm64'],
|
|
51
|
+
// Architecture shortcuts
|
|
52
|
+
x64: ['linux-x64', 'darwin-x64', 'win32-x64'],
|
|
53
|
+
arm64: ['linux-arm64', 'darwin-arm64'],
|
|
54
|
+
arm: ['linux-arm64', 'darwin-arm64'],
|
|
55
|
+
amd64: ['linux-x64', 'darwin-x64', 'win32-x64'],
|
|
56
|
+
aarch64: ['linux-arm64', 'darwin-arm64'],
|
|
57
|
+
// Direct platform names
|
|
58
|
+
'linux-x64': ['linux-x64'],
|
|
59
|
+
'linux-arm64': ['linux-arm64'],
|
|
60
|
+
'darwin-x64': ['darwin-x64'],
|
|
61
|
+
'darwin-arm64': ['darwin-arm64'],
|
|
62
|
+
'win32-x64': ['win32-x64'],
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function resolveDatabase(input: string): string | null {
|
|
66
|
+
const lower = input.toLowerCase()
|
|
67
|
+
if (DATABASE_ALIASES[lower]) {
|
|
68
|
+
return DATABASE_ALIASES[lower]
|
|
69
|
+
}
|
|
70
|
+
return lower
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function resolvePlatforms(input: string): Platform[] | null {
|
|
74
|
+
const lower = input.toLowerCase()
|
|
75
|
+
if (PLATFORM_ALIASES[lower]) {
|
|
76
|
+
return PLATFORM_ALIASES[lower]
|
|
77
|
+
}
|
|
78
|
+
return null
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function isVersionString(input: string): boolean {
|
|
82
|
+
// Matches version patterns like 8.4.3, 17.7.0, 25.12.3.21
|
|
83
|
+
return /^\d+(\.\d+)+$/.test(input)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function sortVersionsDesc(versions: string[]): string[] {
|
|
87
|
+
return [...versions].sort((a, b) => {
|
|
88
|
+
const partsA = a.split('.').map((p) => parseInt(p, 10) || 0)
|
|
89
|
+
const partsB = b.split('.').map((p) => parseInt(p, 10) || 0)
|
|
90
|
+
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
|
|
91
|
+
const diff = (partsB[i] || 0) - (partsA[i] || 0)
|
|
92
|
+
if (diff !== 0) return diff
|
|
93
|
+
}
|
|
94
|
+
return 0
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Resolve a platform alias to a single target platform from available platforms
|
|
100
|
+
*/
|
|
101
|
+
function resolveTargetPlatform(
|
|
102
|
+
platformInput: string,
|
|
103
|
+
availablePlatforms: Partial<Record<Platform, PlatformAsset>>,
|
|
104
|
+
): Platform {
|
|
105
|
+
const platforms = resolvePlatforms(platformInput)
|
|
106
|
+
|
|
107
|
+
if (platforms && platforms.length === 1) {
|
|
108
|
+
const target = platforms[0]
|
|
109
|
+
if (!availablePlatforms[target]) {
|
|
110
|
+
console.error(`Error: Platform '${platformInput}' not found`)
|
|
111
|
+
console.error(`\nAvailable: ${Object.keys(availablePlatforms).join(', ')}`)
|
|
112
|
+
process.exit(1)
|
|
113
|
+
}
|
|
114
|
+
return target
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (platforms) {
|
|
118
|
+
// Multiple platforms from alias - find first available
|
|
119
|
+
const target = platforms.find((p) => availablePlatforms[p])
|
|
120
|
+
if (!target) {
|
|
121
|
+
console.error(`Error: No matching platform for '${platformInput}'`)
|
|
122
|
+
console.error(`\nAvailable: ${Object.keys(availablePlatforms).join(', ')}`)
|
|
123
|
+
process.exit(1)
|
|
124
|
+
}
|
|
125
|
+
return target
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Try as direct platform name
|
|
129
|
+
const target = platformInput as Platform
|
|
130
|
+
if (!availablePlatforms[target]) {
|
|
131
|
+
console.error(`Error: Platform '${platformInput}' not found`)
|
|
132
|
+
console.error(`\nAvailable: ${Object.keys(availablePlatforms).join(', ')}`)
|
|
133
|
+
process.exit(1)
|
|
134
|
+
}
|
|
135
|
+
return target
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function printUsage() {
|
|
139
|
+
console.log(`
|
|
140
|
+
hostdb - Query database binaries from hostdb releases
|
|
141
|
+
|
|
142
|
+
Usage:
|
|
143
|
+
hostdb list [filters...] [--json] List/filter databases, versions, platforms
|
|
144
|
+
hostdb url <db> <version> <platform> Get download URL
|
|
145
|
+
hostdb info <db> <version> <platform> Get full release info as JSON
|
|
146
|
+
|
|
147
|
+
Filters (combine any):
|
|
148
|
+
<database> Filter by database (mysql, postgres, mongodb, etc.)
|
|
149
|
+
<version> Filter by version (8.4.3, 17.7.0, etc.)
|
|
150
|
+
<platform> Filter by platform (mac, linux, windows, arm64, etc.)
|
|
151
|
+
|
|
152
|
+
Examples:
|
|
153
|
+
hostdb list List all databases
|
|
154
|
+
hostdb list --json List all databases as JSON
|
|
155
|
+
hostdb list mysql List MySQL versions
|
|
156
|
+
hostdb list mysql --json List MySQL versions as JSON
|
|
157
|
+
hostdb list mac List all versions available on macOS
|
|
158
|
+
hostdb list mysql mac List MySQL versions for macOS
|
|
159
|
+
hostdb list postgres linux arm64 List PostgreSQL for Linux ARM64
|
|
160
|
+
hostdb list mysql 8.4.3 List platforms for MySQL 8.4.3
|
|
161
|
+
hostdb list mysql 8.4.3 mac Show MySQL 8.4.3 for macOS
|
|
162
|
+
|
|
163
|
+
hostdb url mysql 8.4.3 darwin-arm64 Get download URL
|
|
164
|
+
hostdb info mysql 8.4.3 darwin-arm64 Get full info as JSON
|
|
165
|
+
|
|
166
|
+
Platform Aliases:
|
|
167
|
+
mac, macos, darwin, osx → darwin-x64, darwin-arm64
|
|
168
|
+
win, windows → win32-x64
|
|
169
|
+
linux, ubuntu, debian → linux-x64, linux-arm64
|
|
170
|
+
arm64, arm, aarch64 → linux-arm64, darwin-arm64
|
|
171
|
+
x64, amd64 → linux-x64, darwin-x64, win32-x64
|
|
172
|
+
m1, m2, m3, m4 → darwin-arm64
|
|
173
|
+
|
|
174
|
+
Database Aliases:
|
|
175
|
+
postgres, pg → postgresql
|
|
176
|
+
mongo → mongodb
|
|
177
|
+
maria → mariadb
|
|
178
|
+
ch → clickhouse
|
|
179
|
+
`)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function cmdList(filters: string[], jsonOutput: boolean): void {
|
|
183
|
+
const releases = loadReleasesJson()
|
|
184
|
+
const databases = loadDatabasesJson()
|
|
185
|
+
|
|
186
|
+
let dbFilter: string | null = null
|
|
187
|
+
let versionFilter: string | null = null
|
|
188
|
+
let platformFilter: Platform[] | null = null
|
|
189
|
+
|
|
190
|
+
// Parse filters
|
|
191
|
+
for (const filter of filters) {
|
|
192
|
+
const platforms = resolvePlatforms(filter)
|
|
193
|
+
if (platforms) {
|
|
194
|
+
platformFilter = platformFilter
|
|
195
|
+
? platformFilter.filter((p) => platforms.includes(p))
|
|
196
|
+
: platforms
|
|
197
|
+
continue
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (isVersionString(filter)) {
|
|
201
|
+
versionFilter = filter
|
|
202
|
+
continue
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Assume it's a database name
|
|
206
|
+
const resolved = resolveDatabase(filter)
|
|
207
|
+
if (resolved && releases.databases[resolved]) {
|
|
208
|
+
dbFilter = resolved
|
|
209
|
+
} else if (resolved) {
|
|
210
|
+
console.error(`Error: Database '${filter}' not found`)
|
|
211
|
+
console.error(`\nAvailable: ${Object.keys(releases.databases).join(', ')}`)
|
|
212
|
+
process.exit(1)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Determine what to show based on filters
|
|
217
|
+
if (!dbFilter && !versionFilter && !platformFilter) {
|
|
218
|
+
// No filters: show all databases
|
|
219
|
+
const result = Object.keys(releases.databases).sort().map((db) => {
|
|
220
|
+
const versions = Object.keys(releases.databases[db])
|
|
221
|
+
const info = databases.databases[db]
|
|
222
|
+
return {
|
|
223
|
+
database: db,
|
|
224
|
+
displayName: info?.displayName || db,
|
|
225
|
+
type: info?.type || '',
|
|
226
|
+
versions: versions.length,
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
if (jsonOutput) {
|
|
231
|
+
console.log(JSON.stringify(result, null, 2))
|
|
232
|
+
} else {
|
|
233
|
+
console.log('Available databases:\n')
|
|
234
|
+
for (const r of result) {
|
|
235
|
+
console.log(` ${r.database.padEnd(15)} ${r.displayName.padEnd(15)} ${r.type.padEnd(20)} (${r.versions} versions)`)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (dbFilter && !versionFilter) {
|
|
242
|
+
// Database specified, no version: show versions
|
|
243
|
+
const dbReleases = releases.databases[dbFilter]
|
|
244
|
+
let versions = sortVersionsDesc(Object.keys(dbReleases))
|
|
245
|
+
|
|
246
|
+
// Filter by platform if specified
|
|
247
|
+
if (platformFilter) {
|
|
248
|
+
versions = versions.filter((v) => {
|
|
249
|
+
const release = dbReleases[v]
|
|
250
|
+
return platformFilter!.some((p) => release.platforms[p])
|
|
251
|
+
})
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const result = versions.map((v) => {
|
|
255
|
+
const release = dbReleases[v]
|
|
256
|
+
const availablePlatforms = Object.keys(release.platforms) as Platform[]
|
|
257
|
+
const filteredPlatforms = platformFilter
|
|
258
|
+
? availablePlatforms.filter((p) => platformFilter!.includes(p))
|
|
259
|
+
: availablePlatforms
|
|
260
|
+
return {
|
|
261
|
+
version: v,
|
|
262
|
+
platforms: filteredPlatforms,
|
|
263
|
+
releasedAt: release.releasedAt,
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
if (jsonOutput) {
|
|
268
|
+
console.log(JSON.stringify({ database: dbFilter, versions: result }, null, 2))
|
|
269
|
+
} else {
|
|
270
|
+
const platformLabel = platformFilter ? ` (${platformFilter.join(', ')})` : ''
|
|
271
|
+
console.log(`Versions for ${dbFilter}${platformLabel}:\n`)
|
|
272
|
+
for (const r of result) {
|
|
273
|
+
console.log(` ${r.version.padEnd(15)} (${r.platforms.join(', ')})`)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (dbFilter && versionFilter && !platformFilter) {
|
|
280
|
+
// Database and version: show platforms
|
|
281
|
+
const dbReleases = releases.databases[dbFilter]
|
|
282
|
+
if (!dbReleases[versionFilter]) {
|
|
283
|
+
console.error(`Error: Version '${versionFilter}' not found for ${dbFilter}`)
|
|
284
|
+
console.error(`\nAvailable: ${sortVersionsDesc(Object.keys(dbReleases)).join(', ')}`)
|
|
285
|
+
process.exit(1)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const release = dbReleases[versionFilter]
|
|
289
|
+
const result = (Object.keys(release.platforms) as Platform[]).sort().map((p) => {
|
|
290
|
+
const asset = release.platforms[p]!
|
|
291
|
+
return {
|
|
292
|
+
platform: p,
|
|
293
|
+
url: asset.url,
|
|
294
|
+
sha256: asset.sha256,
|
|
295
|
+
size: asset.size,
|
|
296
|
+
sizeMB: (asset.size / 1024 / 1024).toFixed(1),
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
if (jsonOutput) {
|
|
301
|
+
console.log(JSON.stringify({
|
|
302
|
+
database: dbFilter,
|
|
303
|
+
version: versionFilter,
|
|
304
|
+
releaseTag: release.releaseTag,
|
|
305
|
+
releasedAt: release.releasedAt,
|
|
306
|
+
platforms: result,
|
|
307
|
+
}, null, 2))
|
|
308
|
+
} else {
|
|
309
|
+
console.log(`Platforms for ${dbFilter} ${versionFilter}:\n`)
|
|
310
|
+
for (const r of result) {
|
|
311
|
+
console.log(` ${r.platform.padEnd(15)} ${r.sizeMB} MB`)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (dbFilter && versionFilter && platformFilter) {
|
|
318
|
+
// All three: show specific assets
|
|
319
|
+
const dbReleases = releases.databases[dbFilter]
|
|
320
|
+
if (!dbReleases[versionFilter]) {
|
|
321
|
+
console.error(`Error: Version '${versionFilter}' not found for ${dbFilter}`)
|
|
322
|
+
console.error(`\nAvailable: ${sortVersionsDesc(Object.keys(dbReleases)).join(', ')}`)
|
|
323
|
+
process.exit(1)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const release = dbReleases[versionFilter]
|
|
327
|
+
const matchingPlatforms = platformFilter.filter((p) => release.platforms[p])
|
|
328
|
+
|
|
329
|
+
if (matchingPlatforms.length === 0) {
|
|
330
|
+
console.error(`Error: No matching platforms for ${dbFilter} ${versionFilter}`)
|
|
331
|
+
console.error(`\nAvailable: ${Object.keys(release.platforms).join(', ')}`)
|
|
332
|
+
console.error(`Requested: ${platformFilter.join(', ')}`)
|
|
333
|
+
process.exit(1)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const result = matchingPlatforms.map((p) => {
|
|
337
|
+
const asset = release.platforms[p]!
|
|
338
|
+
return {
|
|
339
|
+
database: dbFilter,
|
|
340
|
+
version: versionFilter,
|
|
341
|
+
platform: p,
|
|
342
|
+
url: asset.url,
|
|
343
|
+
sha256: asset.sha256,
|
|
344
|
+
size: asset.size,
|
|
345
|
+
releaseTag: release.releaseTag,
|
|
346
|
+
releasedAt: release.releasedAt,
|
|
347
|
+
}
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
if (jsonOutput) {
|
|
351
|
+
console.log(JSON.stringify(result.length === 1 ? result[0] : result, null, 2))
|
|
352
|
+
} else {
|
|
353
|
+
for (const r of result) {
|
|
354
|
+
const sizeMB = (r.size / 1024 / 1024).toFixed(1)
|
|
355
|
+
console.log(`${r.database} ${r.version} ${r.platform}`)
|
|
356
|
+
console.log(` URL: ${r.url}`)
|
|
357
|
+
console.log(` SHA256: ${r.sha256}`)
|
|
358
|
+
console.log(` Size: ${sizeMB} MB`)
|
|
359
|
+
if (result.length > 1) console.log()
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (!dbFilter && platformFilter) {
|
|
366
|
+
// Platform only: show all databases/versions for that platform
|
|
367
|
+
const result: Array<{ database: string; version: string; platforms: string[] }> = []
|
|
368
|
+
|
|
369
|
+
for (const db of Object.keys(releases.databases).sort()) {
|
|
370
|
+
const dbReleases = releases.databases[db]
|
|
371
|
+
for (const version of sortVersionsDesc(Object.keys(dbReleases))) {
|
|
372
|
+
const release = dbReleases[version]
|
|
373
|
+
const matchingPlatforms = platformFilter.filter((p) => release.platforms[p])
|
|
374
|
+
if (matchingPlatforms.length > 0) {
|
|
375
|
+
result.push({
|
|
376
|
+
database: db,
|
|
377
|
+
version,
|
|
378
|
+
platforms: matchingPlatforms,
|
|
379
|
+
})
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (jsonOutput) {
|
|
385
|
+
console.log(JSON.stringify(result, null, 2))
|
|
386
|
+
} else {
|
|
387
|
+
console.log(`Releases for ${platformFilter.join(', ')}:\n`)
|
|
388
|
+
let currentDb = ''
|
|
389
|
+
for (const r of result) {
|
|
390
|
+
if (r.database !== currentDb) {
|
|
391
|
+
if (currentDb) console.log()
|
|
392
|
+
console.log(` ${r.database}:`)
|
|
393
|
+
currentDb = r.database
|
|
394
|
+
}
|
|
395
|
+
console.log(` ${r.version.padEnd(15)} (${r.platforms.join(', ')})`)
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Fallback
|
|
402
|
+
console.error('Invalid filter combination')
|
|
403
|
+
process.exit(1)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function cmdUrl(database: string, version: string, platform: string) {
|
|
407
|
+
const releases = loadReleasesJson()
|
|
408
|
+
|
|
409
|
+
const db = resolveDatabase(database)
|
|
410
|
+
if (!db || !releases.databases[db]) {
|
|
411
|
+
console.error(`Error: Database '${database}' not found`)
|
|
412
|
+
console.error(`\nAvailable: ${Object.keys(releases.databases).sort().join(', ')}`)
|
|
413
|
+
process.exit(1)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (!releases.databases[db][version]) {
|
|
417
|
+
console.error(`Error: Version '${version}' not found for ${db}`)
|
|
418
|
+
console.error(`\nAvailable: ${sortVersionsDesc(Object.keys(releases.databases[db])).join(', ')}`)
|
|
419
|
+
process.exit(1)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const release = releases.databases[db][version]
|
|
423
|
+
const targetPlatform = resolveTargetPlatform(platform, release.platforms)
|
|
424
|
+
const asset = release.platforms[targetPlatform]!
|
|
425
|
+
|
|
426
|
+
console.log(asset.url)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function cmdInfo(database: string, version: string, platform: string) {
|
|
430
|
+
const releases = loadReleasesJson()
|
|
431
|
+
|
|
432
|
+
const db = resolveDatabase(database)
|
|
433
|
+
if (!db || !releases.databases[db]) {
|
|
434
|
+
console.error(`Error: Database '${database}' not found`)
|
|
435
|
+
console.error(`\nAvailable: ${Object.keys(releases.databases).sort().join(', ')}`)
|
|
436
|
+
process.exit(1)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (!releases.databases[db][version]) {
|
|
440
|
+
console.error(`Error: Version '${version}' not found for ${db}`)
|
|
441
|
+
console.error(`\nAvailable: ${sortVersionsDesc(Object.keys(releases.databases[db])).join(', ')}`)
|
|
442
|
+
process.exit(1)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const release = releases.databases[db][version]
|
|
446
|
+
const targetPlatform = resolveTargetPlatform(platform, release.platforms)
|
|
447
|
+
const asset = release.platforms[targetPlatform]!
|
|
448
|
+
|
|
449
|
+
console.log(JSON.stringify({
|
|
450
|
+
database: db,
|
|
451
|
+
version,
|
|
452
|
+
platform: targetPlatform,
|
|
453
|
+
url: asset.url,
|
|
454
|
+
sha256: asset.sha256,
|
|
455
|
+
size: asset.size,
|
|
456
|
+
releaseTag: release.releaseTag,
|
|
457
|
+
releasedAt: release.releasedAt,
|
|
458
|
+
}, null, 2))
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function main() {
|
|
462
|
+
const args = process.argv.slice(2)
|
|
463
|
+
|
|
464
|
+
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
465
|
+
printUsage()
|
|
466
|
+
process.exit(0)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Check for --json flag
|
|
470
|
+
const jsonOutput = args.includes('--json')
|
|
471
|
+
const filteredArgs = args.filter((a) => a !== '--json')
|
|
472
|
+
|
|
473
|
+
const command = filteredArgs[0]
|
|
474
|
+
|
|
475
|
+
switch (command) {
|
|
476
|
+
case 'list':
|
|
477
|
+
case 'ls':
|
|
478
|
+
cmdList(filteredArgs.slice(1), jsonOutput)
|
|
479
|
+
break
|
|
480
|
+
|
|
481
|
+
case 'url':
|
|
482
|
+
if (!filteredArgs[1] || !filteredArgs[2] || !filteredArgs[3]) {
|
|
483
|
+
console.error('Error: Missing arguments')
|
|
484
|
+
console.error('Usage: hostdb url <database> <version> <platform>')
|
|
485
|
+
process.exit(1)
|
|
486
|
+
}
|
|
487
|
+
cmdUrl(filteredArgs[1], filteredArgs[2], filteredArgs[3])
|
|
488
|
+
break
|
|
489
|
+
|
|
490
|
+
case 'info':
|
|
491
|
+
if (!filteredArgs[1] || !filteredArgs[2] || !filteredArgs[3]) {
|
|
492
|
+
console.error('Error: Missing arguments')
|
|
493
|
+
console.error('Usage: hostdb info <database> <version> <platform>')
|
|
494
|
+
process.exit(1)
|
|
495
|
+
}
|
|
496
|
+
cmdInfo(filteredArgs[1], filteredArgs[2], filteredArgs[3])
|
|
497
|
+
break
|
|
498
|
+
|
|
499
|
+
case 'versions': {
|
|
500
|
+
if (!filteredArgs[1]) {
|
|
501
|
+
console.error('Error: Missing database argument')
|
|
502
|
+
console.error('Usage: hostdb versions <database>')
|
|
503
|
+
process.exit(1)
|
|
504
|
+
}
|
|
505
|
+
const db = resolveDatabase(filteredArgs[1])
|
|
506
|
+
cmdList(db ? [db] : [filteredArgs[1]], jsonOutput)
|
|
507
|
+
break
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
case 'platforms': {
|
|
511
|
+
if (!filteredArgs[1] || !filteredArgs[2]) {
|
|
512
|
+
console.error('Error: Missing arguments')
|
|
513
|
+
console.error('Usage: hostdb platforms <database> <version>')
|
|
514
|
+
process.exit(1)
|
|
515
|
+
}
|
|
516
|
+
const db = resolveDatabase(filteredArgs[1])
|
|
517
|
+
cmdList(db ? [db, filteredArgs[2]] : [filteredArgs[1], filteredArgs[2]], jsonOutput)
|
|
518
|
+
break
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
default:
|
|
522
|
+
// Try to interpret as list with filters
|
|
523
|
+
cmdList(filteredArgs, jsonOutput)
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
main()
|