"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeUrl = exports.getEffectivePort = exports.getPathFromAbsoluteUrl = exports.getUrlWithoutProtocol = exports.isAbsoluteProtocollessUrl = exports.isRelativeUrl = exports.isAbsoluteUrl = void 0;
const url = require("url");
const _ = require("lodash");
const util_1 = require("./util");
// Is this URL fully qualified?
// Note that this supports only HTTP - no websockets or anything else.
const isAbsoluteUrl = (url) => url.toLowerCase().startsWith('http://') ||
    url.toLowerCase().startsWith('https://');
exports.isAbsoluteUrl = isAbsoluteUrl;
const isRelativeUrl = (url) => url.startsWith('/');
exports.isRelativeUrl = isRelativeUrl;
const isAbsoluteProtocollessUrl = (url) => !(0, exports.isAbsoluteUrl)(url) && !(0, exports.isRelativeUrl)(url);
exports.isAbsoluteProtocollessUrl = isAbsoluteProtocollessUrl;
const getUrlWithoutProtocol = (url) => {
    return url.split('://', 2).slice(-1).join('');
};
exports.getUrlWithoutProtocol = getUrlWithoutProtocol;
const getPathFromAbsoluteUrl = (url) => {
    const pathIndex = (0, util_1.nthIndexOf)(url, '/', 3);
    if (pathIndex !== -1) {
        return url.slice(pathIndex);
    }
    else {
        return '';
    }
};
exports.getPathFromAbsoluteUrl = getPathFromAbsoluteUrl;
const getEffectivePort = (url) => {
    if (url.port) {
        return parseInt(url.port, 10);
    }
    else if (url.protocol === 'https:' || url.protocol === 'wss:') {
        return 443;
    }
    else {
        return 80;
    }
};
exports.getEffectivePort = getEffectivePort;
/**
 * Normalizes URLs to the form used when matching them.
 *
 * This accepts URLs in all three formats: relative, absolute, and protocolless-absolute,
 * and returns them in the same format but normalized.
 */
exports.normalizeUrl = _.memoize((urlInput) => {
    let parsedUrl;
    let isProtocolless = false;
    try {
        // Strip the query and anything following it
        const queryIndex = urlInput.indexOf('?');
        if (queryIndex !== -1) {
            urlInput = urlInput.slice(0, queryIndex);
        }
        if ((0, exports.isAbsoluteProtocollessUrl)(urlInput)) {
            parsedUrl = url.parse('http://' + urlInput);
            isProtocolless = true;
        }
        else {
            parsedUrl = url.parse(urlInput);
        }
        // Trim out lots of the bits we don't like:
        delete parsedUrl.host;
        delete parsedUrl.query;
        delete parsedUrl.search;
        delete parsedUrl.hash;
        if (parsedUrl.pathname) {
            parsedUrl.pathname = parsedUrl.pathname.replace(/\%[A-Fa-z0-9]{2}/g, (encoded) => encoded.toUpperCase()).replace(/[^\u0000-\u007F]+/g, (unicodeChar) => encodeURIComponent(unicodeChar));
        }
        if (parsedUrl.hostname && parsedUrl.hostname.endsWith('.')) {
            parsedUrl.hostname = parsedUrl.hostname.slice(0, -1);
        }
        if ((parsedUrl.protocol === 'https:' && parsedUrl.port === '443') ||
            (parsedUrl.protocol === 'http:' && parsedUrl.port === '80')) {
            delete parsedUrl.port;
        }
    }
    catch (e) {
        console.log(`Failed to normalize URL ${urlInput}`);
        console.log(e);
        if (!parsedUrl)
            return urlInput; // Totally unparseble: use as-is
        // If we've successfully parsed it, we format what we managed
        // and leave it at that:
    }
    let normalizedUrl = url.format(parsedUrl);
    // If the URL came in with no protocol, it should leave with
    // no protocol (protocol added temporarily above to allow parsing)
    if (isProtocolless) {
        normalizedUrl = normalizedUrl.slice('http://'.length);
    }
    return normalizedUrl;
});
//# sourceMappingURL=url.js.map