@@ -76,6 +76,7 @@ async function promptForMissing(args) {
7676 const configuredAnalytics = args . analytics === "disabled" ? wranglerConfig . analyticsProvider || args . analytics : args . analytics ;
7777 const configuredAccessTeamDomain = args . accessTeamDomain || wranglerConfig . accessTeamDomain || "" ;
7878 const configuredOperator = siteConfig . operator || { } ;
79+ const configuredBranding = siteConfig . branding || { } ;
7980 const suggested = suggestWordmarkSplit ( configuredDomain ) ;
8081
8182 const rl = readline . createInterface ( { input, output } ) ;
@@ -119,11 +120,15 @@ async function promptForMissing(args) {
119120 args . operatorAnalyticsDisclosure = args . operatorAnalyticsDisclosure || analyticsDisclosureDefault ( args . analytics ) ;
120121 args . operatorAnalyticsRetention = args . operatorAnalyticsRetention || "" ;
121122 }
122- args . customizePublic = await confirm ( rl , "Copy default web pages to custom/public with a split-color domain wordmark?" , siteConfig . branding ?. custom_public !== false ) ;
123-
124- if ( args . customizePublic ) {
123+ args . configureBranding = await confirm ( rl , "Configure branding now?" , hasConfiguredBranding ( configuredBranding ) ) ;
124+ if ( args . configureBranding ) {
125+ args . brandingSlogan = await question ( rl , "Brand slogan" , args . brandingSlogan || configuredBranding . slogan || defaultBrandingSlogan ( args ) ) ;
126+ args . customizePublic = await confirm ( rl , "Copy default web pages to custom/public with a split-color domain wordmark?" , siteConfig . branding ?. custom_public !== false ) ;
125127 args . wordmarkBlack = await question ( rl , "Black wordmark portion" , args . wordmarkBlack || configuredBrand ?. black || suggested . black ) ;
126128 args . wordmarkGreen = await question ( rl , "Green wordmark portion" , args . wordmarkGreen || configuredBrand ?. green || suggested . green ) ;
129+ } else {
130+ args . customizePublic = args . customizePublic ?? siteConfig . branding ?. custom_public === true ;
131+ args . brandingSlogan = args . brandingSlogan ?? configuredBranding . slogan ?? "" ;
127132 }
128133 } finally {
129134 rl . close ( ) ;
@@ -140,7 +145,15 @@ function normalizeArgs(args) {
140145 args . owner = slugifyOwner ( args . owner ) ;
141146 args . randomSlugLength = normalizeRandomSlugLength ( args . randomSlugLength || DEFAULT_RANDOM_SLUG_LENGTH ) ;
142147 args . languages = normalizeLanguages ( args . languages ) ;
148+ args . configureBranding = args . configureBranding ?? (
149+ args . customizePublic != null
150+ || args . brandingSlogan != null
151+ || args . wordmarkBlack != null
152+ || args . wordmarkGreen != null
153+ ) ;
154+ args . configureBranding = normalizeBoolean ( args . configureBranding ) ;
143155 args . customizePublic = normalizeBoolean ( args . customizePublic ) ;
156+ args . brandingSlogan = String ( args . brandingSlogan || "" ) . trim ( ) ;
144157 args . operator = normalizeOperator ( args ) ;
145158
146159 if ( ! args . domain ) throw new Error ( "Domain cannot be empty." ) ;
@@ -407,6 +420,22 @@ function suggestWordmarkSplit(domain) {
407420 } ;
408421}
409422
423+ function hasConfiguredBranding ( branding ) {
424+ return Boolean (
425+ branding ?. custom_public === true
426+ || String ( branding ?. slogan || "" ) . trim ( )
427+ || String ( branding ?. wordmark ?. black || "" ) . trim ( )
428+ || String ( branding ?. wordmark ?. green || "" ) . trim ( )
429+ ) ;
430+ }
431+
432+ function defaultBrandingSlogan ( args ) {
433+ const operatorName = String ( args . operatorLegalName || "" ) . trim ( ) ;
434+ return operatorName
435+ ? `A short-link service for ${ operatorName } 's projects`
436+ : "A short-link service powered by vanityURLs" ;
437+ }
438+
410439async function confirm ( rl , label , defaultValue ) {
411440 const suffix = defaultValue ? "Y/n" : "y/N" ;
412441 const answer = ( await rl . question ( `${ label } (${ suffix } ): ` ) ) . trim ( ) . toLowerCase ( ) ;
@@ -439,26 +468,33 @@ function createCustomFiles(args) {
439468}
440469
441470function updateSiteConfig ( args ) {
471+ const existingSiteConfig = loadSiteConfig ( ) ;
442472 const siteConfig = mergeSiteConfig ( loadSiteConfig ( ) , {
443473 i18n : {
444474 default_language : args . languages [ 0 ] || "en" ,
445475 supported_languages : args . languages
446476 } ,
447477 operator : args . operator ,
448478 links : {
449- ...( loadSiteConfig ( ) . links || { } ) ,
479+ ...( existingSiteConfig . links || { } ) ,
450480 random_slug_length : args . randomSlugLength
451481 } ,
452- branding : {
453- domain : args . domain ,
454- custom_public : args . customizePublic === true ,
455- wordmark : args . customizePublic
456- ? {
457- black : args . wordmarkBlack ,
458- green : args . wordmarkGreen
459- }
460- : undefined
461- }
482+ branding : args . configureBranding
483+ ? {
484+ domain : args . domain ,
485+ slogan : args . brandingSlogan ,
486+ custom_public : args . customizePublic === true ,
487+ wordmark : args . customizePublic
488+ ? {
489+ black : args . wordmarkBlack ,
490+ green : args . wordmarkGreen
491+ }
492+ : undefined
493+ }
494+ : {
495+ ...( existingSiteConfig . branding || { } ) ,
496+ domain : args . domain
497+ }
462498 } ) ;
463499
464500 writeJson ( CUSTOM_SITE_CONFIG_PATH , siteConfig , args ) ;
@@ -531,6 +567,7 @@ function rewriteHtmlFiles(directory, transform) {
531567function applyBranding ( html , args ) {
532568 const brandLabel = `${ args . wordmarkBlack } ${ args . wordmarkGreen } ` ;
533569 const wordmark = `<h1$1><span>${ escapeHtml ( args . wordmarkBlack ) } </span><span>${ escapeHtml ( args . wordmarkGreen ) } </span></h1>` ;
570+ const slogan = renderBrandingSlogan ( args . brandingSlogan , args . operator ) ;
534571
535572 return html
536573 . replace ( / < h 1 ( [ ^ > ] * ) > < s p a n > V a n i t y < \/ s p a n > < s p a n > U R L s < \/ s p a n > < \/ h 1 > / g, ( _match , attributes ) => wordmark . replace ( "$1" , attributes ) )
@@ -539,7 +576,18 @@ function applyBranding(html, args) {
539576 . replace ( / ( < a c l a s s = " w o r d m a r k " h r e f = ) " h t t p s : \/ \/ v a n i t y u r l s \. l i n k \/ " / gi, `$1"https://${ escapeHtmlAttribute ( args . domain ) } /"` )
540577 . replace ( / ( < a c l a s s = " r e d i r e c t e d - b a d g e " h r e f = ) " h t t p s : \/ \/ v a n i t y U R L s \. l i n k " / g, `$1"${ PROJECT_SITE_URL } "` )
541578 . replace ( / ( < a c l a s s = " r e d i r e c t e d - b a d g e " h r e f = ) " h t t p s : \/ \/ v a n i t y u r l s \. l i n k \/ ? " / gi, `$1"${ PROJECT_SITE_URL } "` )
542- . replace ( / ( < a c l a s s = " r e d i r e c t e d - b a d g e " [ ^ > ] * a r i a - l a b e l = ) " [ ^ " ] * " / g, '$1"VanityURLs"' ) ;
579+ . replace ( / ( < a c l a s s = " r e d i r e c t e d - b a d g e " [ ^ > ] * a r i a - l a b e l = ) " [ ^ " ] * " / g, '$1"VanityURLs"' )
580+ . replace ( / < p c l a s s = " i n s t a n c e - b r a n d - s u b t i t l e " > [ \s \S ] * ?< \/ p > / g, `<p class="instance-brand-subtitle">${ slogan } </p>` ) ;
581+ }
582+
583+ function renderBrandingSlogan ( slogan , operator = { } ) {
584+ const rendered = escapeHtml ( slogan || "" ) ;
585+ const legalName = String ( operator . legal_name || "" ) . trim ( ) ;
586+ const operatorDomain = normalizeDomain ( operator . operator_domain || "" ) ;
587+ if ( ! rendered || ! legalName || ! operatorDomain ) return rendered ;
588+
589+ const escapedName = escapeHtml ( legalName ) ;
590+ return rendered . replace ( escapedName , `<a href="https://${ escapeHtmlAttribute ( operatorDomain ) } ">${ escapedName } </a>` ) ;
543591}
544592
545593function readJson ( filePath , fallback = { } ) {
0 commit comments