UNPKG

@sitecore-jss/sitecore-jss

Version:

This module is provided as a part of Sitecore JavaScript Rendering SDK. It contains the core JSS APIs (layout service) and utilities.

80 lines (79 loc) 3.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SiteResolver = void 0; // Delimiters for multi-value hostnames const DELIMITERS = /\||,|;/g; /** * Resolves site based on the provided host or site name */ class SiteResolver { /** * @param {SiteInfo[]} sites Array of sites to be used in resolution */ constructor(sites) { this.sites = sites; /** * Resolve site by host name * @param {string} hostName the host name * @returns {SiteInfo} the resolved site * @throws {Error} if a matching site is not found */ this.getByHost = (hostName) => { for (const [hostname, site] of this.getHostMap()) { if (this.matchesPattern(hostName, hostname)) { return site; } } throw new Error(`Could not resolve site for host ${hostName}`); }; /** * Resolve site by site name * @param {string} siteName the site name * @returns {SiteInfo} the resolved site * @throws {Error} if a matching site is not found */ this.getByName = (siteName) => { const siteInfo = this.sites.find((info) => info.name.toLocaleLowerCase() === siteName.toLocaleLowerCase()); if (!siteInfo) { throw new Error(`Could not resolve site for name ${siteName}`); } return siteInfo; }; this.getHostMap = () => { const map = new Map(); // First collect unique hostnames. // For sites with same hostname defined, priority is given to the first encountered. this.sites.forEach((site) => { const hostnames = site.hostName .replace(/\s/g, '') .toLocaleLowerCase() .split(DELIMITERS); hostnames.forEach((hostname) => { if (!map.has(hostname)) { map.set(hostname, site); } }); }); // Now order by specificity. // This equivalates to sorting from longest to shortest with the assumption // that your match is less specific as wildcards are introduced. // E.g. order.eu.site.com → *.eu.site.com → *.site.com → * // In case of a tie (e.g. *.site.com vs i.site.com), prefer one with less wildcards. return new Map(Array.from(map).sort((a, b) => { if (a[0].length === b[0].length) { return (a[0].match(/\*/g) || []).length - (b[0].match(/\*/g) || []).length; } return b[0].length - a[0].length; })); }; } // b[0].match(/\*/g) || []).length matchesPattern(hostname, pattern) { // dots should be treated as chars // stars should be treated as wildcards const regExpPattern = pattern.replace(/\./g, '\\.').replace(/\*/g, '.*'); const regExp = new RegExp(`^${regExpPattern}$`, 'gi'); return !!hostname.match(regExp); } } exports.SiteResolver = SiteResolver;