import fs from 'fs/promises'; import path from 'path'; import { DATA_ROOT, isPostgresStorageMode } from './dataPaths.js'; import { decryptJsonPayload, encryptJsonPayload, makeLookupToken, pgQuery, } from './postgres.js'; const VERSION_FILE = path.join(DATA_ROOT, 'version.json'); function versionLookup(publicUrl) { return makeLookupToken('app-version', publicUrl); } function versionAad(publicUrl) { return `app-version:${publicUrl}`; } export async function loadStoredSHA(publicUrl) { if (isPostgresStorageMode()) { const { rows } = await pgQuery( 'SELECT payload FROM app_versions WHERE public_url_lookup = $1', [versionLookup(publicUrl)] ); const payload = rows[0] ? decryptJsonPayload(rows[0].payload, versionAad(publicUrl)) : null; return payload?.sha || null; } try { await fs.mkdir(DATA_ROOT, { recursive: true }); const raw = await fs.readFile(VERSION_FILE, 'utf8'); const data = JSON.parse(raw); const obj = Array.isArray(data) ? data.find((item) => item[publicUrl]) : null; return obj ? obj[publicUrl] : null; } catch { return null; } } export async function saveStoredSHA(publicUrl, sha) { if (isPostgresStorageMode()) { await pgQuery( `INSERT INTO app_versions (public_url_lookup, updated_at, payload) VALUES ($1, $2, $3::jsonb) ON CONFLICT (public_url_lookup) DO UPDATE SET updated_at = EXCLUDED.updated_at, payload = EXCLUDED.payload`, [ versionLookup(publicUrl), new Date().toISOString(), JSON.stringify(encryptJsonPayload({ publicUrl, sha }, versionAad(publicUrl))), ] ); return; } await fs.mkdir(DATA_ROOT, { recursive: true }); let data = []; try { const raw = await fs.readFile(VERSION_FILE, 'utf8'); const parsed = JSON.parse(raw); data = Array.isArray(parsed) ? parsed : []; } catch { data = []; } let found = false; for (const entry of data) { if (entry[publicUrl]) { entry[publicUrl] = sha; found = true; break; } } if (!found) { data.push({ [publicUrl]: sha }); } await fs.writeFile(VERSION_FILE, JSON.stringify(data, null, 2), 'utf8'); }