/**
 * XSS Sanitizer
 * Recursive, zero-dependency input sanitization utility.
 *
 * This is intentionally conservative for request-body handling:
 * - Strings: strip markup tags but preserve plain text characters.
 * - Arrays/Objects: sanitize recursively.
 */
const stripTags = (value) => {
    // Remove all HTML tags in linear time (no regex backtracking / ReDoS risk).
    let out = '';
    let inTag = false;
    for (const element of value) {
        const ch = element;
        if (ch === '<') {
            inTag = true;
            continue;
        }
        if (inTag) {
            if (ch === '>')
                inTag = false;
            continue;
        }
        out += ch;
    }
    return out;
};
const sanitizeRecursive = (input, seen) => {
    if (typeof input === 'string') {
        return stripTags(input);
    }
    if (Array.isArray(input)) {
        if (seen.has(input))
            return input;
        seen.add(input);
        return input.map((item) => sanitizeRecursive(item, seen));
    }
    if (typeof input === 'object' && input !== null) {
        const obj = input;
        if (seen.has(obj))
            return input;
        seen.add(obj);
        const out = {};
        for (const [key, value] of Object.entries(obj)) {
            out[key] = sanitizeRecursive(value, seen);
        }
        return out;
    }
    return input;
};
export const Xss = Object.freeze({
    sanitize(input) {
        return sanitizeRecursive(input, new WeakSet());
    },
});
export default Xss;
