#!/usr/bin/env bun
/**
* End-to-end check for notification coverage against a running dev server whose email goes to the dev
* mail sink (EMAIL_DEV_SINK=kv, or any localhost PUBLIC_URL without a verified sender). Run it from the
* worktree whose `vite dev` is under test, since it seeds users and sessions in that server's local D1/KV.
*
* BASE_URL=http://localhost:3000 bun scripts/e2e-notify.ts
* BASE_URL=http://localhost:3017 bun scripts/e2e-notify.ts ci security # only some cases
*
* The "digest" case needs NOTIFY_DIGEST_DELAY_MS=0 (dev forges only) so the account alarm flushes it at once.
*
* Each case triggers a real event over HTTP and asserts both the web notification (through the
* listNotifications server function) and the captured email (through /__dev/mail), plus the
* unsubscribe headers, redaction of secret values and send-time access checks.
*/
import { createHash, randomBytes } from "node:crypto";
import { d1Rows, scopedSqlRows, sh as run } from "../e2e/scoped-sql";
import { toJSONAsync } from "seroval";
const BASE = (process.env.BASE_URL ?? "http://localhost:3000").replace(/\/$/, "");
const ROOT = new URL("..", import.meta.url).pathname;
const SESSION_COOKIE = "__Host-gitfor_session";
const POLL_MS = 1000;
const TIMEOUT_MS = Number(process.env.NOTIFY_TIMEOUT_MS ?? 90_000);
const LFS_LIMIT = 10 * 1024 * 1024 * 1024;
const LFS_NEAR_LIMIT = Math.floor(LFS_LIMIT * 0.9);
const STALE_RUNNER_MS = 15 * 60 * 1000;
const HTTP_OK = 200;
const HTTP_CREATED = 201;
const HTTP_NOT_FOUND = 404;
const FAKE_AWS_KEY = `AKIA${"QX7Z".repeat(4)}`;
type User = { id: string; name: string; email: string; token: string; cookie: string };
type Mail = { id: string; to: string; subject: string; text: string; html: string; headers?: Record<string, string> };
type WebNotification = { reason: string; title: string; url: string };
const sh = (cmd: string[]) => run(ROOT, cmd);
const d1 = (sql: string) => d1Rows(ROOT, sql);
const scoped = (scope: "repo" | "account", id: string, sql: string) => scopedSqlRows(BASE, scope, id, sql);