fix: harden node upgrades and prepare 1.9.0-alpha
This commit is contained in:
@@ -89,11 +89,25 @@ describe('appsConfig service filtering', () => {
|
||||
const entries: Array<[string, PackageDataEntry]> = [
|
||||
['cuprate', makePkg('cuprate', 'Cuprate', 'money')],
|
||||
['archy-cuprate-ui', makePkg('archy-cuprate-ui', 'Cuprate UI companion', 'money')],
|
||||
['cuprate-ui', makePkg('cuprate-ui', 'Cuprate UI', 'money')],
|
||||
]
|
||||
expect(filterEntriesForTab(entries, 'apps', 'all').map(([id]) => id)).toEqual(['cuprate'])
|
||||
expect(filterEntriesForTab(entries, 'services', 'all').map(([id]) => id)).toEqual([])
|
||||
})
|
||||
|
||||
it('groups NetBird parts and BTCPay aliases without hiding a legacy-only installation', () => {
|
||||
const entries: Array<[string, PackageDataEntry]> = [
|
||||
['netbird', makePkg('netbird', 'NetBird', 'networking')],
|
||||
['netbird-dashboard', makePkg('netbird-dashboard', 'NetBird Dashboard', 'networking')],
|
||||
['netbird-server', makePkg('netbird-server', 'NetBird Server', 'networking')],
|
||||
['btcpay', makePkg('btcpay', 'BTCPay', 'money')],
|
||||
['btcpay-server', makePkg('btcpay-server', 'BTCPay Server', 'commerce')],
|
||||
]
|
||||
expect(filterEntriesForTab(entries, 'apps', 'all').map(([id]) => id)).toEqual(['netbird', 'btcpay-server'])
|
||||
expect(filterEntriesForTab(entries, 'services', 'all')).toEqual([])
|
||||
expect(filterEntriesForTab([entries[3]!], 'apps', 'all').map(([id]) => id)).toEqual(['btcpay'])
|
||||
})
|
||||
|
||||
it('falls back to packaged app icon when static icon token is not a path', () => {
|
||||
const pkg = makePkg('gitea', 'Gitea', 'dev')
|
||||
pkg['static-files']!.icon = 'git-branch'
|
||||
|
||||
@@ -35,7 +35,7 @@ const INTERNAL_TOOLING_NAMES = new Set([
|
||||
// Cuprate's dashboard is bundled as a companion of the primary cuprate
|
||||
// package; showing the generated container as a second Services entry
|
||||
// defeats the one-app presentation.
|
||||
'archy-cuprate-ui',
|
||||
'archy-cuprate-ui', 'cuprate-ui', 'netbird-dashboard', 'netbird-server',
|
||||
])
|
||||
|
||||
export function isInternalToolingPackage(id: string, pkg?: PackageDataEntry): boolean {
|
||||
@@ -54,7 +54,7 @@ export function isServicePackage(id: string, pkg?: PackageDataEntry): boolean {
|
||||
// Known app -> category mappings (matches App Store categorisation)
|
||||
export const APP_CATEGORY_MAP: Record<string, string> = {
|
||||
'bitcoin-core': 'money', 'bitcoin-knots': 'money', 'bitcoin-ui': 'money', 'cuprate': 'money', 'cuprate-ui': 'money', 'electrumx': 'money', 'electrs': 'money',
|
||||
'lnd': 'money', 'mempool': 'money', 'mempool-web': 'money', 'btcpay-server': 'commerce',
|
||||
'lnd': 'money', 'mempool': 'money', 'mempool-web': 'money', 'btcpay-server': 'commerce', 'btcpay': 'commerce', 'btcpayserver': 'commerce',
|
||||
'fedimint': 'money', 'fedimint-gateway': 'money',
|
||||
'indeedhub': 'media', 'jellyfin': 'media', 'photoprism': 'media', 'immich': 'media',
|
||||
'nextcloud': 'data', 'vaultwarden': 'data', 'filebrowser': 'data', 'cryptpad': 'data',
|
||||
@@ -115,11 +115,13 @@ export function filterEntriesForTab(
|
||||
selectedCategory: string,
|
||||
): Array<[string, PackageDataEntry]> {
|
||||
const hasMempool = entries.some(([id]) => id === 'mempool')
|
||||
const hasBtcpay = entries.some(([id]) => id === 'btcpay-server')
|
||||
return entries.filter(([id, pkg]) => {
|
||||
// Older daemons can retain the frontend manifest alias during a restart.
|
||||
// Keep one tile while the updated scanner converges; a legacy-only node
|
||||
// must still be able to see and operate its sole Mempool entry.
|
||||
if (hasMempool && ['mempool-web', 'mempool-frontend', 'archy-mempool-web'].includes(id)) return false
|
||||
if (hasBtcpay && ['btcpay', 'btcpayserver'].includes(id)) return false
|
||||
if (isInternalToolingPackage(id, pkg)) return false
|
||||
const wantsWebsites = activeTab === 'websites' || activeTab === 'services'
|
||||
const isWebsite = isWebsitePackage(id, pkg)
|
||||
|
||||
@@ -29,6 +29,7 @@ export const SERVICE_NAMES = new Set([
|
||||
'mysql-mempool', 'mempool-api', 'archy-mempool-web',
|
||||
'archy-bitcoin-ui', 'archy-lnd-ui', 'archy-electrs-ui',
|
||||
'bitcoin-ui', 'lnd-ui', 'electrs-ui',
|
||||
'cuprate-ui', 'netbird-dashboard', 'netbird-server',
|
||||
'indeedhub-postgres', 'indeedhub-redis', 'indeedhub-minio',
|
||||
'indeedhub-api', 'indeedhub-ffmpeg',
|
||||
'indeedhub-relay', 'indeedhub-build_api_1', 'indeedhub-build_ffmpeg-worker_1',
|
||||
@@ -64,3 +65,15 @@ export function isServiceContainer(id: string): boolean {
|
||||
export function isStoreListedApp(id: string): boolean {
|
||||
return !isServiceContainer(id) && !NODE_INTERNAL_IDS.has(id)
|
||||
}
|
||||
|
||||
/** Normalize every catalog source, including persisted caches from older UIs. */
|
||||
export function normalizeStoreApps<T extends { id: string }>(apps: readonly T[]): T[] {
|
||||
const result = new Map<string, T>()
|
||||
for (const app of apps) {
|
||||
if (!isStoreListedApp(app.id)) continue
|
||||
const id = ['btcpay', 'btcpayserver'].includes(app.id) ? 'btcpay-server' : app.id
|
||||
// Prefer the real app's metadata to a legacy image-pin-only alias.
|
||||
if (!result.has(id) || app.id === id) result.set(id, { ...app, id })
|
||||
}
|
||||
return [...result.values()]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user