/**
 * Finite public projection contract for repository bindings.
 * Bounded enums + sanitized labels only; no tokens, account IDs, repo URLs,
 * matcher keys, or paths.
 */
import { isUnsafePublicString } from "../runs/runProjectionContract.js";
export const REPOSITORY_PROJECTION_PUBLIC_SOURCE = "repositories";
export const REPOSITORY_PROJECTION_STATUSES = [
    "connected",
    "syncing",
    "needs-action",
    "blocked",
    "disconnected",
];
export const REPOSITORY_PROJECTION_PROVIDERS = [
    "github",
    "gitlab",
    "bitbucket",
    "unknown",
];
export const REPOSITORY_PROJECTION_TONES = [
    "primary",
    "success",
    "warning",
    "destructive",
    "muted",
];
export const REPOSITORY_LINK_STATES = ["unlinked", "linked"];
export const REPOSITORY_CLONE_STATES = [
    "idle",
    "cloning",
    "cloned",
    "failed",
];
const MAX_LABEL = 120;
export function readRepositoryLabel(value) {
    if (value === null || value === undefined)
        return null;
    const trimmed = value.trim();
    if (!trimmed)
        return null;
    if (trimmed.length > MAX_LABEL)
        return null;
    if (isUnsafePublicString(trimmed))
        return null;
    return trimmed;
}
const MAX_COORDINATE = 100;
const SAFE_COORDINATE_PATTERN = /^[A-Za-z0-9._/-]+$/u;
/**
 * Read a sanitized public coordinate (owner / repo / branch). Rejects anything
 * that looks like a path, contains traversal, or is unsafe — returns null so
 * the field is omitted from the projection rather than leaking.
 */
export function readRepositoryCoordinate(value) {
    if (value === null || value === undefined)
        return null;
    const trimmed = value.trim();
    if (!trimmed || trimmed.length > MAX_COORDINATE)
        return null;
    if (!SAFE_COORDINATE_PATTERN.test(trimmed))
        return null;
    if (trimmed.includes(".."))
        return null;
    if (isUnsafePublicString(trimmed))
        return null;
    return trimmed;
}
export function toneForRepositoryStatus(status) {
    switch (status) {
        case "connected":
            return "success";
        case "syncing":
            return "primary";
        case "needs-action":
            return "warning";
        case "blocked":
            return "destructive";
        case "disconnected":
            return "muted";
    }
}
