Skip to content

Instantly share code, notes, and snippets.

@DavidWells
Created January 2, 2022 07:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidWells/b0e881cd55bd06746447c09b4bcc2cae to your computer and use it in GitHub Desktop.
Save DavidWells/b0e881cd55bd06746447c09b4bcc2cae to your computer and use it in GitHub Desktop.
Parse URL fallback
// https://github.com/shm-open/utilities/blob/master/src/url.ts?cool#L52
function parseURL(url, base) {
let rest = url;
const reProtocol = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i;
// extract protocol
const protocolMatch = reProtocol.exec(url);
let protocol = protocolMatch[1]?.toLowerCase() ?? '';
const hasSlashes = !!protocolMatch[2];
// eslint-disable-next-line prefer-destructuring
rest = protocolMatch[3];
// extract hash & query
let hash;
// eslint-disable-next-line prefer-const
[rest, hash] = sliceBy(rest, '#', true);
let search;
// eslint-disable-next-line prefer-const
[rest, search] = sliceBy(rest, '?', true);
// extract host & auth
let wholeHost = '';
if (hasSlashes) {
[wholeHost, rest] = sliceBy(rest, '/', true);
}
const [auth, host] = sliceBy(wholeHost, '@', false, true);
let [username, password] = sliceBy(auth, ':');
let [hostname, port] = sliceBy(host, ':');
// apply base url
if (!protocol && !hostname && base) {
const ref = parseURL(base);
protocol = ref.protocol;
username = ref.username;
password = ref.password;
hostname = ref.hostname;
port = ref.port;
if (hostname && rest && rest[0] !== '/') {
rest = `/${rest}`;
}
}
return {
protocol,
username,
password,
hostname,
port,
// has hostname, default to '/'
pathname: !rest && hostname ? '/' : rest,
search,
hash,
};
}
function sliceBy(
text,
delimiter,
include = false,
fromBack = false,
) {
const index = text.indexOf(delimiter);
if (index === -1) {
if (fromBack) {
return ['', text];
}
return [text, ''];
}
return [
text.slice(0, index) + (include && fromBack ? delimiter : ''),
(include && !fromBack ? delimiter : '') + text.slice(index + delimiter.length),
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment