← back to Vendor Recrawl Dispatcher

tools/fix-slack-webhook.js

34 lines

#!/usr/bin/env node
// Fleet fix for the '${SLACK_WEBHOOK_URL}' literal bug: 95 DW scripts have
//   const SLACK_WEBHOOK = '${SLACK_WEBHOOK_URL}';   // shell placeholder never expanded in JS
// so their send functions crash on `new URL(SLACK_WEBHOOK)` AFTER doing their work.
//
// This applies TWO precise, safe transforms per file:
//   1. assignment -> read the real env var:  process.env.SLACK_WEBHOOK_URL || ''
//   2. guard the send: insert `if (!/^https?:\/\//.test(SLACK_WEBHOOK)) return;`
//      immediately before the FIRST `new URL(SLACK_WEBHOOK)` (always inside the async
//      send function, so an early return is valid) — so an unset webhook = clean no-op.
// Idempotent: skips files already carrying the guard marker.
const fs = require('fs');

const files = process.argv.slice(2);
const LIT = "const SLACK_WEBHOOK = '${SLACK_WEBHOOK_URL}';";
const FIXED_ASSIGN = "const SLACK_WEBHOOK = process.env.SLACK_WEBHOOK_URL || '';";
const GUARD = "if (!/^https?:\\/\\//.test(SLACK_WEBHOOK)) return; // slack: no-op when unset";

let changed = 0, skipped = 0;
for (const f of files) {
  let s;
  try { s = fs.readFileSync(f, 'utf8'); } catch { continue; }
  if (s.includes('slack: no-op when unset')) { skipped++; continue; } // already fixed
  if (!s.includes(LIT)) { skipped++; continue; }

  let out = s.replace(LIT, FIXED_ASSIGN);
  // guard the first `new URL(SLACK_WEBHOOK)` occurrence (with or without an assignment prefix)
  out = out.replace(/(^[ \t]*)((?:const |let |var )?[\w$]*\s*=?\s*)?new URL\(SLACK_WEBHOOK\)/m,
    (m, indent) => `${indent}${GUARD}\n${m}`);
  if (out !== s) { fs.writeFileSync(f, out); changed++; console.log(`  fixed ${f.split('/').slice(-2).join('/')}`); }
  else skipped++;
}
console.log(`\n  changed=${changed} skipped=${skipped}`);