Files
wehub-resource-sync 70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:11 +08:00

77 lines
1.8 KiB
TypeScript

export const extractPathname = (
path = "/",
includeSearch: boolean,
includeHash: boolean
): string => {
if (!path.startsWith("/")) {
path = `/${path}`;
}
const url = new URL(`//${path}`, "relative://");
return `${url.pathname}${includeSearch ? url.search : ""}${
includeHash ? url.hash : ""
}`;
};
const URL_REGEX = /^https:\/\/+(?<host>[^/]+)\/?(?<path>.*)/;
const HOST_WITH_PORT_REGEX = /.*:\d+$/;
const PATH_REGEX = /^\//;
export const validateUrl = (
token: string,
onlyRelative = false,
disallowPorts = false,
includeSearch = false,
includeHash = false
): [undefined, string] | [string, undefined] => {
const host = URL_REGEX.exec(token);
if (host && host.groups && host.groups.host) {
if (onlyRelative) {
return [
undefined,
`Only relative URLs are allowed. Skipping absolute URL ${token}.`,
];
}
if (disallowPorts && host.groups.host.match(HOST_WITH_PORT_REGEX)) {
return [
undefined,
`Specifying ports is not supported. Skipping absolute URL ${token}.`,
];
}
return [
`https://${host.groups.host}${extractPathname(
host.groups.path,
includeSearch,
includeHash
)}`,
undefined,
];
} else {
if (!token.startsWith("/") && onlyRelative) {
token = `/${token}`;
}
const path = PATH_REGEX.exec(token);
if (path) {
try {
return [extractPathname(token, includeSearch, includeHash), undefined];
} catch {
return [undefined, `Error parsing URL segment ${token}. Skipping.`];
}
}
}
return [
undefined,
onlyRelative
? "URLs should begin with a forward-slash."
: 'URLs should either be relative (e.g. begin with a forward-slash), or use HTTPS (e.g. begin with "https://").',
];
};
export function urlHasHost(token: string): boolean {
const host = URL_REGEX.exec(token);
return Boolean(host && host.groups && host.groups.host);
}