File: //tmp/bm_distribution_freshness_patch.cjs
const fs = require('fs');
function replaceExact(file, from, to) {
let s = fs.readFileSync(file, 'utf8');
if (!s.includes(from)) throw new Error(`Missing expected text in ${file}: ${from.slice(0,180)}`);
s = s.replace(from, to);
fs.writeFileSync(file, s, 'utf8');
}
replaceExact('scripts/growth-distribution-report.mjs',
"import fs from 'node:fs/promises';\n\nconst socialReportPath = process.env.SOCIAL_PREVIEW_REPORT || 'storage/reports/social-preview-latest.json';",
"import fs from 'node:fs/promises';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\nconst socialReportPath = process.env.SOCIAL_PREVIEW_REPORT || 'storage/reports/social-preview-latest.json';");
replaceExact('scripts/growth-distribution-report.mjs',
"const readJson = async (path) => JSON.parse(await fs.readFile(path, 'utf8'));\nconst safe = (value) => String(value || '').replace(/\\s+/g, ' ').trim();",
"const readJson = async (path) => JSON.parse(await fs.readFile(path, 'utf8'));\nconst refreshSocialPreview = async () => {\n if (process.env.GROWTH_DISTRIBUTION_SKIP_SOCIAL_REFRESH === '1') return false;\n await execFileAsync(process.execPath, ['./scripts/social-preview-audit.mjs'], { timeout: 90000, maxBuffer: 1024 * 1024 * 8 });\n return true;\n};\nconst safe = (value) => String(value || '').replace(/\\s+/g, ' ').trim();");
replaceExact('scripts/growth-distribution-report.mjs',
"const social = await readJson(socialReportPath);\nconst queue = [...(social.distributionQueue || [])]",
"const socialPreviewRefreshed = await refreshSocialPreview();\nconst social = await readJson(socialReportPath);\nconst queue = [...(social.distributionQueue || [])]");
replaceExact('scripts/growth-distribution-report.mjs',
" source: {\n socialReportPath,\n generatedAt: social.generatedAt,\n routes: social.routes,\n failedRoutes: social.failedRoutes\n },",
" source: {\n socialReportPath,\n refreshedBeforeBuild: socialPreviewRefreshed,\n generatedAt: social.generatedAt,\n routes: social.routes,\n failedRoutes: social.failedRoutes\n },");
let smoke = fs.readFileSync('scripts/growth-smoke-check.mjs', 'utf8');
if (!smoke.includes('growth-distribution stale social-preview source')) {
smoke = smoke.replace(" if (!distributionReport.ok) failures.push('growth-distribution report not ok');", " if (!distributionReport.ok) failures.push('growth-distribution report not ok');\n if (!distributionReport.source?.refreshedBeforeBuild) failures.push('growth-distribution did not refresh social-preview before build');\n if (distributionReport.source?.generatedAt && distributionReport.generatedAt && Math.abs(Date.parse(distributionReport.generatedAt) - Date.parse(distributionReport.source.generatedAt)) > 5 * 60 * 1000) failures.push('growth-distribution stale social-preview source');");
}
fs.writeFileSync('scripts/growth-smoke-check.mjs', smoke, 'utf8');