@automattic/calypso-url
Version:
This library provides both generic and Calypso-specific utilities for handling URLs.
78 lines • 2.85 kB
JavaScript
// For complete definitions of these classifications, see:
// https://url.spec.whatwg.org/#urls
export var URL_TYPE;
(function (URL_TYPE) {
// A complete URL, with (at least) protocol and host.
// E.g. `http://example.com` or `http://example.com/path`
URL_TYPE["ABSOLUTE"] = "ABSOLUTE";
// A URL with no protocol, but with a host.
// E.g. `//example.com` or `//example.com/path`
URL_TYPE["SCHEME_RELATIVE"] = "SCHEME_RELATIVE";
// A URL with no protocol or host, but with a path starting at the root.
// E.g. `/` or `/path`
URL_TYPE["PATH_ABSOLUTE"] = "PATH_ABSOLUTE";
// A URL with no protocol or host, but with a path relative to the current resource.
// E.g. `../foo` or `bar`
URL_TYPE["PATH_RELATIVE"] = "PATH_RELATIVE";
// Any invalid URL.
// E.g. `///`
URL_TYPE["INVALID"] = "INVALID";
})(URL_TYPE || (URL_TYPE = {}));
const BASE_HOSTNAME = '__domain__.invalid';
const BASE_URL = `http://${BASE_HOSTNAME}`;
/**
* Determine the type of a URL, with regards to its completeness.
*
* @param url the URL to analyze
* @returns the type of the URL
*/
export function determineUrlType(url) {
// Check for expected parameter types.
if (!(url instanceof URL) && typeof url !== 'string') {
return URL_TYPE.INVALID;
}
// As a URL, the empty string means "the current resource".
if (url === '') {
return URL_TYPE.PATH_RELATIVE;
}
// The native URL object can only represent absolute URLs.
if (url instanceof URL) {
return URL_TYPE.ABSOLUTE;
}
let parsed;
try {
// If we can parse the URL without a base, it's an absolute URL.
// The polyfill works differently, however, so we need to take that into account.
// See https://github.com/webcomponents/polyfills/issues/241
parsed = new URL(url);
if (parsed.protocol && parsed.protocol !== ':') {
return URL_TYPE.ABSOLUTE;
}
}
catch {
// Do nothing.
}
try {
parsed = new URL(url, BASE_URL);
}
catch {
// If it can't be parsed even with a base URL, it's an invalid URL.
return URL_TYPE.INVALID;
}
// The polyfill sometimes doesn't throw an exception for invalid URLs, instead
// leaving the `pathname` blank (which it shouldn't be, at this point).
if (parsed.pathname === '') {
return URL_TYPE.INVALID;
}
// If we couldn't parse it without a base, but it didn't take the hostname we provided, that means
// it's a protocol-relative URL.
if (parsed.hostname !== BASE_HOSTNAME) {
return URL_TYPE.SCHEME_RELATIVE;
}
// Otherwise, it's a relative URL of some sort.
if (url.startsWith('/')) {
return URL_TYPE.PATH_ABSOLUTE;
}
return URL_TYPE.PATH_RELATIVE;
}
//# sourceMappingURL=url-type.js.map