import { IModelTemplate , IHubRequestOptions , getHubProduct , getProp , cloneObject , deepSet , slugify , stripProtocol , addSolutionResourceUrlToAssets , getHubApiUrl , } from "@esri/hub-common" ; import { createHubTeams } from "@esri/hub-teams" ; import { HubTeamType } from "@esri/hub-teams" ; import { getTheme } from "./get-theme" ; import { getPortalSiteHostname } from "./get-portal-site-hostname" ; import { getPortalSiteUrl } from "./get-portal-site-url" ; import { _createSiteInitiative } from "./_create-site-initiative" ; import { _updateTeamTags } from "./_update-team-tags" ; import { ensureUniqueDomainName } from "@esri/hub-common" ; import { interpolateSite } from "./interpolate-site" ; param { object } template param { object } settings param { object } transforms param { IHubRequestOptions } hubRequestOptions export function createSiteModelFromTemplate ( template , settings , transforms , hubRequestOptions ) { template . assets = addSolutionResourceUrlToAssets ( template , hubRequestOptions ) ; if ( ! template . item . properties ) { template . item . properties = { } ; } [ "customHostname" , "externalUrl" , "contentGroupId" , "followersGroupId" , "collaborationGroupId" , "parentInitiativeId" , ] . forEach ( ( prop ) => { delete template . data . values [ prop ] ; } ) ; const product = getHubProduct ( hubRequestOptions . portalSelf ) ; let title = getProp ( settings , "solution.title" ) || "New Site" ; if ( typeof title === "number" ) { title = title . toString ( ) ; deepSet ( settings , "solution.title" , title ) ; } const state = { } ; const teamsToCreate = [ "core" , "content" , "followers" ] ; return createHubTeams ( { title , types : teamsToCreate , hubRequestOptions , } ) . then ( ( teams ) => { settings . teams = cloneObject ( teams . props ) ; state . teams = teams ; Object . assign ( template . item . properties , teams . props ) ; if ( getProp ( teams , "props.contentGroupId" ) ) { deepSet ( template , "data.catalog.groups" , [ teams . props . contentGroupId ] ) ; } let domainTitle = title ; if ( hasUnicodeChars ( domainTitle ) ) { domainTitle = "site" ; } return ensureUniqueDomainName ( slugify ( domainTitle ) , hubRequestOptions ) ; } ) . then ( ( uniqueSubdomain ) => { const portal = hubRequestOptions . portalSelf ; settings . solution . theme = getTheme ( portal ) ; settings . solution . subdomain = uniqueSubdomain ; if ( hubRequestOptions . isPortal ) { settings . solution . defaultHostname = getPortalSiteHostname ( uniqueSubdomain , portal ) ; settings . solution . url = getPortalSiteUrl ( uniqueSubdomain , portal ) ; } else { const base = stripProtocol ( getHubApiUrl ( hubRequestOptions ) ) ; settings . solution . defaultHostname = `${ uniqueSubdomain }-${ portal . urlKey }.${ base }` ; settings . solution . url = `https://${ uniqueSubdomain }-${ portal . urlKey }.${ base }` ; } let handleInitiative = Promise . resolve ( null ) ; if ( product !== "portal" ) { handleInitiative = _createSiteInitiative ( template , settings , transforms , hubRequestOptions ) ; } return handleInitiative ; } ) . then ( ( maybeInitiative ) => { let teamUpdatePromise = Promise . resolve ( null ) ; if ( maybeInitiative ) { settings . initiative = maybeInitiative ; template . item . properties . parentInitiativeId = maybeInitiative . item . id ; teamUpdatePromise = _updateTeamTags ( maybeInitiative , state . teams , hubRequestOptions ) ; } return teamUpdatePromise ; } ) . then ( ( _ ) => { const siteModel = interpolateSite ( template , settings , transforms ) ; if ( typeof siteModel . item . title === "number" ) { siteModel . item . title = getProp ( settings , "solution.title" ) ; siteModel . data . values . title = getProp ( settings , "solution.title" ) ; } return siteModel ; } ) . catch ( ( ex ) => { throw Error ( `site-utils::createSiteModelFromTemplate Error ${ ex }` ) ; } ) ; } /**
 * From Stackoverflow
 * https://stackoverflow.com/questions/147824/how-to-find-whether-a-particular-string-has-unicode-characters-esp-double-byte
 * This is the highest performance solution, combining three approaches
 */ const unicodeCharRegex = /[^\u0000-\u00ff]/ ; function hasUnicodeChars ( value ) { if ( value . charCodeAt ( 0 ) > 255 ) return true ; return unicodeCharRegex . test ( value ) ; }