diff --git a/common/api-review/util.api.md b/common/api-review/util.api.md index 4ac51fda550..96695e78d73 100644 --- a/common/api-review/util.api.md +++ b/common/api-review/util.api.md @@ -487,9 +487,6 @@ export interface Subscribe { // @public (undocumented) export type Unsubscribe = () => void; -// @public -export function updateEmulatorBanner(name: string, isRunningEmulator: boolean): void; - // Warning: (ae-missing-release-tag) "validateArgCount" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public diff --git a/packages/auth/src/core/auth/emulator.ts b/packages/auth/src/core/auth/emulator.ts index 15da907286f..95345269553 100644 --- a/packages/auth/src/core/auth/emulator.ts +++ b/packages/auth/src/core/auth/emulator.ts @@ -18,12 +18,7 @@ import { Auth } from '../../model/public_types'; import { AuthErrorCode } from '../errors'; import { _assert } from '../util/assert'; import { _castAuth } from './auth_impl'; -import { - deepEqual, - isCloudWorkstation, - pingServer, - updateEmulatorBanner -} from '@firebase/util'; +import { deepEqual, isCloudWorkstation, pingServer } from '@firebase/util'; /** * Changes the {@link Auth} instance to communicate with the Firebase Auth Emulator, instead of production @@ -102,10 +97,9 @@ export function connectAuthEmulator( authInternal.emulatorConfig = emulatorConfig; authInternal.settings.appVerificationDisabledForTesting = true; - // Workaround to get cookies in Firebase Studio if (isCloudWorkstation(host)) { + // Workaround to get cookies in Firebase Studio void pingServer(`${protocol}//${host}${portStr}`); - updateEmulatorBanner('Auth', true); } else if (!disableWarnings) { emitEmulatorWarning(); } diff --git a/packages/data-connect/src/api/DataConnect.ts b/packages/data-connect/src/api/DataConnect.ts index b7311363784..c25a09039ac 100644 --- a/packages/data-connect/src/api/DataConnect.ts +++ b/packages/data-connect/src/api/DataConnect.ts @@ -24,11 +24,7 @@ import { import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; import { Provider } from '@firebase/component'; -import { - isCloudWorkstation, - pingServer, - updateEmulatorBanner -} from '@firebase/util'; +import { isCloudWorkstation, pingServer } from '@firebase/util'; import { AppCheckTokenProvider } from '../core/AppCheckTokenProvider'; import { Code, DataConnectError } from '../core/error'; @@ -245,7 +241,6 @@ export function connectDataConnectEmulator( // Workaround to get cookies in Firebase Studio if (isCloudWorkstation(host)) { void pingServer(`https://${host}${port ? `:${port}` : ''}`); - updateEmulatorBanner('Data Connect', true); } dc.enableEmulator({ host, port, sslEnabled }); } diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts index 338255be46f..515e278b5c5 100644 --- a/packages/database/src/api/Database.ts +++ b/packages/database/src/api/Database.ts @@ -31,8 +31,7 @@ import { EmulatorMockTokenOptions, getDefaultEmulatorHostnameAndPort, isCloudWorkstation, - pingServer, - updateEmulatorBanner + pingServer } from '@firebase/util'; import { AppCheckTokenProvider } from '../core/AppCheckTokenProvider'; @@ -394,7 +393,6 @@ export function connectDatabaseEmulator( // Workaround to get cookies in Firebase Studio if (isCloudWorkstation(host)) { void pingServer(host); - updateEmulatorBanner('Database', true); } // Modify the repo to apply emulator settings diff --git a/packages/firestore/src/lite-api/database.ts b/packages/firestore/src/lite-api/database.ts index 6af324e4ba4..8e7fdb27e90 100644 --- a/packages/firestore/src/lite-api/database.ts +++ b/packages/firestore/src/lite-api/database.ts @@ -28,8 +28,7 @@ import { EmulatorMockTokenOptions, getDefaultEmulatorHostnameAndPort, isCloudWorkstation, - pingServer, - updateEmulatorBanner + pingServer } from '@firebase/util'; import { @@ -337,7 +336,6 @@ export function connectFirestoreEmulator( const newHostSetting = `${host}:${port}`; if (useSsl) { void pingServer(`https://${newHostSetting}`); - updateEmulatorBanner('Firestore', true); } if (settings.host !== DEFAULT_HOST && settings.host !== newHostSetting) { logWarn( diff --git a/packages/functions/src/service.ts b/packages/functions/src/service.ts index 6e2eddda3a2..6a0ddeaa8d3 100644 --- a/packages/functions/src/service.ts +++ b/packages/functions/src/service.ts @@ -30,11 +30,7 @@ import { Provider } from '@firebase/component'; import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; import { MessagingInternalComponentName } from '@firebase/messaging-interop-types'; import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; -import { - isCloudWorkstation, - pingServer, - updateEmulatorBanner -} from '@firebase/util'; +import { isCloudWorkstation, pingServer } from '@firebase/util'; export const DEFAULT_REGION = 'us-central1'; @@ -186,7 +182,6 @@ export function connectFunctionsEmulator( // Workaround to get cookies in Firebase Studio if (useSsl) { void pingServer(functionsInstance.emulatorOrigin + '/backends'); - updateEmulatorBanner('Functions', true); } } diff --git a/packages/storage/src/service.ts b/packages/storage/src/service.ts index a4252c77870..7e2090ccd2e 100644 --- a/packages/storage/src/service.ts +++ b/packages/storage/src/service.ts @@ -46,8 +46,7 @@ import { createMockUserToken, EmulatorMockTokenOptions, isCloudWorkstation, - pingServer, - updateEmulatorBanner + pingServer } from '@firebase/util'; import { Connection, ConnectionType } from './implementation/connection'; @@ -151,7 +150,6 @@ export function connectStorageEmulator( // Workaround to get cookies in Firebase Studio if (useSsl) { void pingServer(`https://${storage.host}/b`); - updateEmulatorBanner('Storage', true); } storage._isUsingEmulator = true; storage._protocol = useSsl ? 'https' : 'http'; diff --git a/packages/util/src/emulator.ts b/packages/util/src/emulator.ts index 1c4d4ae7a7d..2850b5be378 100644 --- a/packages/util/src/emulator.ts +++ b/packages/util/src/emulator.ts @@ -16,7 +16,6 @@ */ import { base64urlEncodeWithoutPadding } from './crypt'; -import { isCloudWorkstation } from './url'; // Firebase Auth tokens contain snake_case claims following the JWT standard / convention. /* eslint-disable camelcase */ @@ -141,180 +140,3 @@ export function createMockUserToken( signature ].join('.'); } - -interface EmulatorStatusMap { - [name: string]: boolean; -} -const emulatorStatus: EmulatorStatusMap = {}; - -interface EmulatorSummary { - prod: string[]; - emulator: string[]; -} - -// Checks whether any products are running on an emulator -function getEmulatorSummary(): EmulatorSummary { - const summary: EmulatorSummary = { - prod: [], - emulator: [] - }; - for (const key of Object.keys(emulatorStatus)) { - if (emulatorStatus[key]) { - summary.emulator.push(key); - } else { - summary.prod.push(key); - } - } - return summary; -} - -function getOrCreateEl(id: string): { created: boolean; element: HTMLElement } { - let parentDiv = document.getElementById(id); - let created = false; - if (!parentDiv) { - parentDiv = document.createElement('div'); - parentDiv.setAttribute('id', id); - created = true; - } - return { created, element: parentDiv }; -} - -let previouslyDismissed = false; -/** - * Updates Emulator Banner. Primarily used for Firebase Studio - * @param name - * @param isRunningEmulator - * @public - */ -export function updateEmulatorBanner( - name: string, - isRunningEmulator: boolean -): void { - if ( - typeof window === 'undefined' || - typeof document === 'undefined' || - !isCloudWorkstation(window.location.host) || - emulatorStatus[name] === isRunningEmulator || - emulatorStatus[name] || // If already set to use emulator, can't go back to prod. - previouslyDismissed - ) { - return; - } - - emulatorStatus[name] = isRunningEmulator; - - function prefixedId(id: string): string { - return `__firebase__banner__${id}`; - } - const bannerId = '__firebase__banner'; - const summary = getEmulatorSummary(); - const showError = summary.prod.length > 0; - - function tearDown(): void { - const element = document.getElementById(bannerId); - if (element) { - element.remove(); - } - } - - function setupBannerStyles(bannerEl: HTMLElement): void { - bannerEl.style.display = 'flex'; - bannerEl.style.background = '#7faaf0'; - bannerEl.style.position = 'fixed'; - bannerEl.style.bottom = '5px'; - bannerEl.style.left = '5px'; - bannerEl.style.padding = '.5em'; - bannerEl.style.borderRadius = '5px'; - bannerEl.style.alignItems = 'center'; - } - - function setupIconStyles(prependIcon: SVGElement, iconId: string): void { - prependIcon.setAttribute('width', '24'); - prependIcon.setAttribute('id', iconId); - prependIcon.setAttribute('height', '24'); - prependIcon.setAttribute('viewBox', '0 0 24 24'); - prependIcon.setAttribute('fill', 'none'); - prependIcon.style.marginLeft = '-6px'; - } - - function setupCloseBtn(): HTMLSpanElement { - const closeBtn = document.createElement('span'); - closeBtn.style.cursor = 'pointer'; - closeBtn.style.marginLeft = '16px'; - closeBtn.style.fontSize = '24px'; - closeBtn.innerHTML = ' ×'; - closeBtn.onclick = () => { - previouslyDismissed = true; - tearDown(); - }; - return closeBtn; - } - - function setupLinkStyles( - learnMoreLink: HTMLAnchorElement, - learnMoreId: string - ): void { - learnMoreLink.setAttribute('id', learnMoreId); - learnMoreLink.innerText = 'Learn more'; - learnMoreLink.href = - 'https://firebase.google.com/docs/studio/preview-apps#preview-backend'; - learnMoreLink.setAttribute('target', '__blank'); - learnMoreLink.style.paddingLeft = '5px'; - learnMoreLink.style.textDecoration = 'underline'; - } - - function setupDom(): void { - const banner = getOrCreateEl(bannerId); - const firebaseTextId = prefixedId('text'); - const firebaseText: HTMLSpanElement = - document.getElementById(firebaseTextId) || document.createElement('span'); - const learnMoreId = prefixedId('learnmore'); - const learnMoreLink: HTMLAnchorElement = - (document.getElementById(learnMoreId) as HTMLAnchorElement) || - document.createElement('a'); - const prependIconId = prefixedId('preprendIcon'); - const prependIcon: SVGElement = - (document.getElementById( - prependIconId - ) as HTMLOrSVGElement as SVGElement) || - document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - if (banner.created) { - // update styles - const bannerEl = banner.element; - setupBannerStyles(bannerEl); - setupLinkStyles(learnMoreLink, learnMoreId); - const closeBtn = setupCloseBtn(); - setupIconStyles(prependIcon, prependIconId); - bannerEl.append(prependIcon, firebaseText, learnMoreLink, closeBtn); - document.body.appendChild(bannerEl); - } - - if (showError) { - firebaseText.innerText = `Preview backend disconnected.`; - prependIcon.innerHTML = ` - - - - - - -`; - } else { - prependIcon.innerHTML = ` - - - - - - -`; - firebaseText.innerText = 'Preview backend running in this workspace.'; - } - firebaseText.setAttribute('id', firebaseTextId); - } - if (document.readyState === 'loading') { - window.addEventListener('DOMContentLoaded', setupDom); - } else { - setupDom(); - } -}