UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

57 lines (56 loc) 2.12 kB
import { isRemotePath } from "@astrojs/internal-helpers/path"; function matchPattern(url, remotePattern) { return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); } function matchPort(url, port) { return !port || port === url.port; } function matchProtocol(url, protocol) { return !protocol || protocol === url.protocol.slice(0, -1); } function matchHostname(url, hostname, allowWildcard) { if (!hostname) { return true; } else if (!allowWildcard || !hostname.startsWith("*")) { return hostname === url.hostname; } else if (hostname.startsWith("**.")) { const slicedHostname = hostname.slice(2); return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); } else if (hostname.startsWith("*.")) { const slicedHostname = hostname.slice(1); const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean); return additionalSubdomains.length === 1; } return false; } function matchPathname(url, pathname, allowWildcard) { if (!pathname) { return true; } else if (!allowWildcard || !pathname.endsWith("*")) { return pathname === url.pathname; } else if (pathname.endsWith("/**")) { const slicedPathname = pathname.slice(0, -2); return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); } else if (pathname.endsWith("/*")) { const slicedPathname = pathname.slice(0, -1); const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean); return additionalPathChunks.length === 1; } return false; } function isRemoteAllowed(src, { domains = [], remotePatterns = [] }) { if (!isRemotePath(src)) return false; const url = new URL(src); return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); } export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol };