const XML_SOAP = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims";
const MICROSOFT = "http://schemas.microsoft.com/ws/2008/06/identity/claims";
const DND_BEYOND = "http://schemas.dndbeyond.com/ws/2019/08/identity/claims";
const KEYS = {
    [`${XML_SOAP}/nameidentifier`]: "id",
    [`${XML_SOAP}/name`]: "name",
    [`${MICROSOFT}/role`]: "roles",
    [`${XML_SOAP}/emailaddress`]: "email",
    [`${DND_BEYOND}/subscriber`]: "isSubscriber",
    [`${DND_BEYOND}/subscriptiontier`]: "subscriptionTier",
};
const VALUES = {
    id: Number,
    roles: (roles) => [roles].flat(),
    isSubscriber: (isSubscriber) => isSubscriber === "True",
};
const identity = (x) => x;
function mapKeys(key, value) {
    const k = KEYS[key] ?? key;
    const v = (VALUES[k] ?? identity)(value);
    if (k === key) {
        return v;
    }
    this[k] = v;
}
const safeParse = (text, reviver) => {
    try {
        return JSON.parse(text, reviver);
    }
    catch (e) { }
};
const regExp = (pattern, flags) => new RegExp(pattern, flags);
const REPLACE = {
    ["-"]: "+",
    ["_"]: "/",
};
const rx = regExp(`[${Object.keys(REPLACE).join("")}]`, "g");
const replacer = (m) => REPLACE[m];
const decode = (s) => s.replace(rx, replacer);
const safeDecode = (s) => {
    try {
        return atob(decode(s));
    }
    catch (e) { }
};
const isUnknownRecord = (x) => !!x && typeof x === "object";
const isTokenHeader = (h) => isUnknownRecord(h) && "alg" in h && !!h.alg;
const currentSeconds = () => Math.floor(Date.now() / 1_000);
const isTokenPayload = (p) => isUnknownRecord(p) &&
    typeof p.id === "number" &&
    p.id > 0 &&
    typeof p.exp === "number";
const isTokenPayloadExpired = (p) => isUnknownRecord(p) && typeof p.exp === "number" && p.exp <= currentSeconds();
const isString = (x) => typeof x === "string";
const isJwtParts = (xs) => xs?.length === 3 && xs.every(isString);
const parseToken = ([h, p]) => {
    const header = safeParse(safeDecode(h) ?? "{}");
    const payload = safeParse(safeDecode(p) ?? p, mapKeys);
    return isTokenHeader(header) && isTokenPayload(payload)
        ? { header, payload, isExpired: isTokenPayloadExpired(payload) }
        : null;
};
const parseJwtParts = (ps) => isJwtParts(ps) ? parseToken(ps) : null;
export const parseJwt = (jwt) => parseJwtParts(jwt?.split("."));
//# sourceMappingURL=parseJwt.js.map