import fetch from 'node-fetch' import { config } from './config.js' import { getRedisKey, hash } from './util.js' import { logger } from './logger.js' import * as redis from './redis.js' let latestVersion export const fetchLatestVersion = async () => { const infos = await Promise.all(config.urls.map(async baseUrl => { try { const response = await fetch(new URL('meta.json', baseUrl)) if (!response.ok) throw new Error() const meta = await response.json() const version = meta.commitSha || meta.buildDate || meta.version if (!version) throw new Error() return version } catch (err) { logger.debug(`[Version] UI container at ${baseUrl} does not have meta.json. Fall back to version hash based on manifest.`) } try { const response = await fetch(new URL('manifest.json', baseUrl)) if (!response.ok) throw new Error() const manifest = await response.json() return hash(manifest) } catch (err) { logger.error(`[Version] Cannot fetch manifest from ${baseUrl}. Version info will not be correct.`) } })) return hash(infos) } export async function getLatestVersion () { if (latestVersion) return latestVersion if (redis.isEnabled()) { const version = await redis.client.get(getRedisKey({ name: 'latestVersion' })) if (version) return (latestVersion = version) } const newVersion = await fetchLatestVersion() if (redis.isEnabled()) { redis.pubClient.publish(getRedisKey({ name: 'updateLatestVersion' }), newVersion) await redis.client.set(getRedisKey({ name: 'latestVersion' }), newVersion) } return (latestVersion = newVersion) } export function registerLatestVersionListener (client) { if (redis.isEnabled()) { const key = getRedisKey({ name: 'updateLatestVersion' }) client.subscribe(key, (errs, count) => logger.info(`[Redis] Subscribed to ${key}.`)) client.on('message', async (channel, message) => { if (channel !== key) return await config.load() latestVersion = message }) } } export async function updateVersionProcessor () { await config.load() const [storedVersion, fetchedVersion] = await Promise.all([ getLatestVersion(), fetchLatestVersion() ]) if (storedVersion === fetchedVersion) return fetchedVersion if (redis.isEnabled()) { redis.pubClient.publish(getRedisKey({ name: 'updateLatestVersion' }), fetchedVersion) await redis.client.set(getRedisKey({ name: 'latestVersion' }), fetchedVersion) } return (latestVersion = fetchedVersion) }