const fs = require('node:fs'); const path = require('node:path'); require('node:module').createRequire(require.resolve('next/package.json'))('@next/env').loadEnvConfig(process.cwd()); const sql = require('postgres')(process.env.POSTGRES_URL, { max: 1, prepare: false }); const pattern = '^https?://s3[.]1080p[.]hk([/:?#]|$)'; async function main() { const apply = process.argv.includes('--apply'); const result = await sql.begin(async tx => { const storage = await tx`select id,"isEnabled","isDefault" from "StorageConfig" where endpoint ~* ${pattern} or "publicUrl" ~* ${pattern}`; const featured = await tx`select id,"isFeatured" from "GeneratedImage" where "isFeatured" and "originalUrl" ~* ${pattern}`; const branding = await tx`select id,"siteLogo","siteLogoDark",favicon from "SiteSettings" where "siteLogo" ~* ${pattern} or "siteLogoDark" ~* ${pattern} or favicon ~* ${pattern}`; if (!apply) return { apply, storage: storage.length, featured: featured.length, branding: branding.length }; const directory = process.env.STORAGE_RETIREMENT_BACKUP_DIR || '/var/lib/ai-chatbot/retired-storage-20261103'; fs.mkdirSync(directory, { recursive: true, mode: 0o700 }); const backup = path.join(directory, `before-${Date.now()}.json`); fs.writeFileSync(backup, JSON.stringify({ storage, featured, branding }, null, 2), { flag: 'wx', mode: 0o600 }); const disabled = await tx`update "StorageConfig" set "isEnabled"=false,"isDefault"=false,"updatedAt"=now() where (endpoint ~* ${pattern} or "publicUrl" ~* ${pattern}) and ("isEnabled" or "isDefault") returning id`; const unfeatured = await tx`update "GeneratedImage" set "isFeatured"=false where "isFeatured" and "originalUrl" ~* ${pattern} returning id`; const branded = await tx`update "SiteSettings" set "siteLogo"=case when "siteLogo" ~* ${pattern} then '/brand/logo-black.png' else "siteLogo" end, "siteLogoDark"=case when "siteLogoDark" ~* ${pattern} then '/brand/logo-white.svg' else "siteLogoDark" end, favicon=case when favicon ~* ${pattern} then '/brand/logo-black.png' else favicon end where "siteLogo" ~* ${pattern} or "siteLogoDark" ~* ${pattern} or favicon ~* ${pattern} returning id`; return { apply, backup, disabled: disabled.length, unfeatured: unfeatured.length, branded: branded.length }; }); console.log(JSON.stringify(result)); } main().catch(error => { console.error(error.message); process.exitCode = 1; }).finally(() => sql.end());