/**
 * [outlook-mcp] structured logger.
 *
 * Every log line is prefixed `[outlook-mcp]` and rendered as `key=value` pairs
 * (Pino-compatible shape). Bearer tokens and `access_token=` query strings are
 * redacted before writing — defense in depth even though tools never log them.
 */
const REDACT_BEARER = /Bearer\s+[A-Za-z0-9._\-+/=]+/g;
const REDACT_ACCESS_TOKEN = /access_token=[A-Za-z0-9._\-+/=]+/g;
export function redact(value) {
    return value
        .replace(REDACT_BEARER, "Bearer <REDACTED>")
        .replace(REDACT_ACCESS_TOKEN, "access_token=<REDACTED>");
}
function fmt(value) {
    if (value === null || value === undefined)
        return "null";
    if (typeof value === "string") {
        if (/[\s"=]/.test(value)) {
            return `"${redact(value).replace(/"/g, '\\"')}"`;
        }
        return redact(value);
    }
    if (typeof value === "number" || typeof value === "boolean")
        return String(value);
    return `"${redact(JSON.stringify(value)).replace(/"/g, '\\"')}"`;
}
/**
 * Log an event line. The first key in `fields` (typically `event`) becomes the
 * top-level event tag; remaining keys are rendered as `k=v` pairs.
 *
 *   log({ event: "mail-list", account: "abc", count: 25, elapsedMs: 320 })
 *     → [outlook-mcp] mail-list account=abc count=25 elapsedMs=320
 */
export function log(fields) {
    const { event, ...rest } = fields;
    const parts = [event];
    for (const [key, value] of Object.entries(rest)) {
        parts.push(`${key}=${fmt(value)}`);
    }
    process.stderr.write(`[outlook-mcp] ${parts.join(" ")}\n`);
}
/** Truncate a string to N chars, replacing the tail with `…` if it overflowed. */
export function trunc(value, max) {
    if (value.length <= max)
        return value;
    return value.slice(0, max - 1) + "…";
}
/** Hex-prefix of a SHA-256 challenge for log identification (8 chars). */
export function challengePrefix(challenge) {
    return challenge.slice(0, 8);
}
//# sourceMappingURL=log.js.map