"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SENSITIVE_OMITTED = void 0;
exports.sanitizeOutputText = sanitizeOutputText;
exports.sanitizeOutputValue = sanitizeOutputValue;
const node_path_1 = __importDefault(require("node:path"));
exports.SENSITIVE_OMITTED = "<sensitive-omitted>";
const SENSITIVE_KEY = /(?:^|[_-])(credential|password|secret|token|api[_-]?key|private[_-]?key|license[_-]?(?:key|material|contents?))(?:$|[_-])/i;
const ANSI_OR_OSC = /(?:\u001b\][^\u0007]*(?:\u0007|\u001b\\)|\u001b\[[0-?]*[ -/]*[@-~])/g;
const UNSAFE_CONTROL = /[\u0000-\u0008\u000b\u000c\u000e-\u001a\u001c-\u001f\u007f-\u009f]/g;
const CREDENTIAL_VALUE = /\b(?:bearer\s+[a-z0-9._~+\/-]{8,}|(?:gh[pousr]|sk|xox[baprs])[-_][a-z0-9_-]{8,})\b/gi;
function sanitizeOutputText(value, options = {}) {
    let safe = value.replace(ANSI_OR_OSC, "").replace(UNSAFE_CONTROL, "");
    safe = safe.replace(CREDENTIAL_VALUE, exports.SENSITIVE_OMITTED);
    const repositoryRoot = normalizeAbsolute(options.repositoryRoot);
    if (repositoryRoot !== null) {
        safe = replacePathPrefix(safe, repositoryRoot, ".");
    }
    const home = normalizeAbsolute(options.homeDirectory ?? options.environment?.HOME ?? options.environment?.USERPROFILE);
    if (home !== null && home !== repositoryRoot) {
        safe = replacePathPrefix(safe, home, exports.SENSITIVE_OMITTED);
    }
    for (const [key, raw] of Object.entries(options.environment ?? {})) {
        if (typeof raw !== "string" || raw.length < 8 || !SENSITIVE_KEY.test(key))
            continue;
        safe = safe.split(raw).join(exports.SENSITIVE_OMITTED);
    }
    return safe;
}
function sanitizeOutputValue(value, options = {}) {
    return visit(value, options, new WeakMap());
}
function visit(value, options, seen) {
    if (typeof value === "string")
        return sanitizeOutputText(value, options);
    if (value === null || typeof value !== "object")
        return value;
    const existing = seen.get(value);
    if (existing !== undefined)
        return existing;
    if (Array.isArray(value)) {
        const result = [];
        seen.set(value, result);
        for (const item of value)
            result.push(visit(item, options, seen));
        return result;
    }
    const result = {};
    seen.set(value, result);
    for (const [key, item] of Object.entries(value)) {
        result[key] = SENSITIVE_KEY.test(key) && item !== null && item !== undefined
            ? exports.SENSITIVE_OMITTED
            : visit(item, options, seen);
    }
    return result;
}
function normalizeAbsolute(value) {
    if (value === undefined || !node_path_1.default.isAbsolute(value))
        return null;
    return node_path_1.default.resolve(value).replace(/[\\/]+$/, "");
}
function replacePathPrefix(value, prefix, replacement) {
    const escaped = prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    return value.replace(new RegExp(`${escaped}(?=[\\/]|$)`, "g"), replacement);
}
