import { POLICY_ACTIONS, POLICY_REASONS, ROUTE_KINDS } from "@/lib/types"; import type { PolicyAction, PolicyReason, RouteKind } from "@/lib/types"; /** * Display names for the three stored enums. `Record` over the union, so a value * added to `src/storage/provenance.zig` and mirrored into `lib/types.ts` fails * `tsc` here instead of reaching a cell as a raw tag name. */ const POLICY_ACTION_LABELS: Record = { not_evaluated: "Not evaluated", allow: "Allowed", block: "Blocked", }; const POLICY_REASON_LABELS: Record = { rule_allow_exact: "Allow rule (exact)", rule_block_exact: "Block rule (exact)", rule_allow_wildcard: "Allow rule (wildcard)", rule_block_wildcard: "Block rule (wildcard)", rule_allow_regex: "Allow rule (regex)", rule_block_regex: "Block rule (regex)", blocklist_exception: "Blocklist exception", blocklist_domain: "Blocklist (domain)", blocklist_wildcard: "Blocklist (wildcard)", local_record: "Local record", forward_zone: "Forward zone", non_in_class: "Not class IN", paused: "Filtering paused", snapshot_unavailable: "No filter snapshot", no_match: "No match", protocol_error: "Protocol refusal", }; const ROUTE_KIND_LABELS: Record = { blocked: "Blocked locally", local: "Local record", forward_zone: "Forward zone", upstream: "Upstream resolver", cache: "Cache", rejected: "Rejected", }; export function policyActionLabel(action: PolicyAction): string { return POLICY_ACTION_LABELS[action]; } export function policyReasonLabel(reason: PolicyReason): string { return POLICY_REASON_LABELS[reason]; } export function routeKindLabel(kind: RouteKind): string { return ROUTE_KIND_LABELS[kind]; } /** The enum value sets, for tests that prove the maps exhaustive at runtime too. */ export const ENUM_VALUES = { policyAction: POLICY_ACTIONS, policyReason: POLICY_REASONS, routeKind: ROUTE_KINDS, } as const; const RCODE_NAMES: Record = { 0: "NOERROR", 1: "FORMERR", 2: "SERVFAIL", 3: "NXDOMAIN", 4: "NOTIMP", 5: "REFUSED", 6: "YXDOMAIN", 7: "YXRRSET", 8: "NXRRSET", 9: "NOTAUTH", 10: "NOTZONE", 16: "BADVERS", }; /** * The bare mnemonic, for a table cell with no room for the number. An * unassigned code has no mnemonic to shorten, so it keeps the same `RCODE ` * shape the long form falls back to. */ export function rcodeShortName(rcode: number): string { return RCODE_NAMES[rcode] ?? `RCODE ${rcode}`; } /** The twelve-bit extended code as `NXDOMAIN (3)`; an unassigned code keeps its number. */ export function rcodeName(rcode: number): string { const name = RCODE_NAMES[rcode]; return name === undefined ? `RCODE ${rcode}` : `${name} (${rcode})`; } const QCLASS_NAMES: Record = { 1: "IN", 3: "CH", 4: "HS", 254: "NONE", 255: "ANY", }; export function qclassName(qclass: number): string { const name = QCLASS_NAMES[qclass]; return name === undefined ? `CLASS ${qclass}` : `${name} (${qclass})`; }