/**
 * branded-string.ts — single, audited cast site for Zod schemas that
 * parse a non-empty string into a {@link Brand}-tagged domain type.
 *
 * Project rule (`.claude/rules/typescript.md`): "Parse, don't validate
 * — use schema libs at boundaries; no `as` on `unknown`." The
 * `Brand<string, "Tag">` utility in `branded-ids.ts` uses a `unique
 * symbol` (`__brand`) that is not structurally identical to Zod 4's
 * `BRAND` symbol, so a direct `.brand<"Tag">()` swap does not produce
 * a compatible type. Wrapping the unavoidable cast in a single typed
 * helper centralizes the rule violation to one auditable place
 * instead of duplicating `as unknown as z.ZodType<Brand<…, …>>` at
 * every adapter branded-field declaration.
 *
 * Usage:
 *
 * ```ts
 * import { brandedString } from "../schemas/index.js"
 *
 * judgmentId: brandedString<"JudgmentId">().optional(),
 * ```
 *
 * This is the **only** allowed place to elide the no-`as`-on-`unknown`
 * rule for branded-string schemas. Phase 7 will reconsider the
 * `Brand<>` shape against Zod 4's `BRAND` so the cast can be retired.
 *
 * @see docs/decisions/D0045-type-architecture-and-contract-enforcement.md
 * @see packages/core/src/types/branded-ids.ts
 */
import { z } from "zod";
/**
 * Schema for a non-empty string typed as `Brand<string, TBrand>`.
 *
 * The single `as unknown as` cast inside this helper is the audited
 * exit from the project's no-`as`-on-`unknown` rule. Adapters MUST
 * NOT replicate the cast at their own call sites — call this helper
 * instead so the rule violation stays centralized.
 *
 * Pass `regex` to enforce a stricter shape than non-empty. The
 * runtime validator becomes `z.string().regex(regex)` instead of
 * `z.string().min(1)`; the brand-cast at the call boundary is
 * unchanged. Callers passing `regex` are responsible for ensuring
 * it rejects the empty string (typically anchor with `^` and
 * require at least one character via `+` or a non-`*` quantifier);
 * the `.min(1)` floor is dropped when `regex` is supplied.
 */
export function brandedString(regex) {
    // The runtime is a plain string (non-empty or regex-validated);
    // the brand is a compile-time-only nominal tag (see `Brand<>` in
    // branded-ids.ts). Zod 4's `.brand()` uses a different symbol
    // shape, so a direct composition does not yield the project's
    // `Brand<…>` type.
    const base = regex === undefined ? z.string().min(1) : z.string().regex(regex);
    return base;
}
