import { sha256Hex } from "../crypto";
/** `anchor` is a literal the match must contain; the detector is skipped when the text lacks it. */
type Detector = { id: string; name: string; pattern: RegExp; group?: number; anchor?: string };
/** High-confidence token formats; each has a distinctive prefix or structure to keep false positives low. */
const DETECTORS: Detector[] = [
{ id: "aws_access_key_id", name: "AWS access key ID", pattern: /\b((?:AKIA|ASIA)[0-9A-Z]{16})\b/g },
{
id: "aws_secret_access_key",
name: "AWS secret access key",
pattern: /aws_?secret_?access_?key["']?\s*[:=]\s*["']?([A-Za-z0-9/+]{40})(?![A-Za-z0-9/+])/gi,
group: 1,
},
{ id: "github_pat", name: "GitHub personal access token", pattern: /\b(gh[pousr]_[A-Za-z0-9]{36,255})\b/g },
{ id: "github_fine_grained_pat", name: "GitHub fine-grained token", pattern: /\b(github_pat_[A-Za-z0-9_]{82})\b/g },
{ id: "gitlab_pat", name: "GitLab personal access token", pattern: /\b(glpat-[A-Za-z0-9_-]{20})\b/g },
{ id: "gitfor_pat", name: "gitfor personal access token", pattern: /\b(gitfor_pat_[A-Za-z0-9_-]{20,})\b/g },
{ id: "slack_token", name: "Slack token", pattern: /\b(xox[abposr]-[A-Za-z0-9-]{10,72})\b/g },
{
id: "slack_webhook",
name: "Slack incoming webhook",
pattern: /(https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]{24})/g,
},
{ id: "stripe_secret_key", name: "Stripe secret key", pattern: /\b((?:sk|rk)_live_[A-Za-z0-9]{24,99})\b/g },
{ id: "google_api_key", name: "Google API key", pattern: /\b(AIza[0-9A-Za-z_-]{35})(?![0-9A-Za-z_-])/g },
{ id: "npm_token", name: "npm access token", pattern: /\b(npm_[A-Za-z0-9]{36})\b/g },
{ id: "pypi_token", name: "PyPI API token", pattern: /\b(pypi-AgEIcHlwaS5vcmc[A-Za-z0-9_-]{50,})/g },
{
id: "openai_api_key",
name: "OpenAI API key",
/** Both runs are bounded so each `sk-` start costs O(1) instead of scanning to the end of the file (INT-A9). */
pattern: /\b(sk-(?:proj-|svcacct-|admin-)?[A-Za-z0-9_-]{20,96}T3BlbkFJ[A-Za-z0-9_-]{20,96})(?![A-Za-z0-9_-])/g,
anchor: "T3BlbkFJ",
},
{ id: "anthropic_api_key", name: "Anthropic API key", pattern: /\b(sk-ant-(?:api|admin)\d{2}-[A-Za-z0-9_-]{80,})/g },
{ id: "sendgrid_api_key", name: "SendGrid API key", pattern: /\b(SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43})\b/g },
{ id: "twilio_api_key", name: "Twilio API key", pattern: /\b(SK[0-9a-f]{32})\b/g },
{ id: "shopify_token", name: "Shopify access token", pattern: /\b(shp(?:at|ca|pa|ss)_[a-fA-F0-9]{32})\b/g },
{