Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions common/api-review/util.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,6 @@ export interface Subscribe<T> {
// @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
Expand Down
10 changes: 2 additions & 8 deletions packages/auth/src/core/auth/emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
Expand Down
7 changes: 1 addition & 6 deletions packages/data-connect/src/api/DataConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 });
}
Expand Down
4 changes: 1 addition & 3 deletions packages/database/src/api/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ import {
EmulatorMockTokenOptions,
getDefaultEmulatorHostnameAndPort,
isCloudWorkstation,
pingServer,
updateEmulatorBanner
pingServer
} from '@firebase/util';

import { AppCheckTokenProvider } from '../core/AppCheckTokenProvider';
Expand Down Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions packages/firestore/src/lite-api/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ import {
EmulatorMockTokenOptions,
getDefaultEmulatorHostnameAndPort,
isCloudWorkstation,
pingServer,
updateEmulatorBanner
pingServer
} from '@firebase/util';

import {
Expand Down Expand Up @@ -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(
Expand Down
7 changes: 1 addition & 6 deletions packages/functions/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -186,7 +182,6 @@ export function connectFunctionsEmulator(
// Workaround to get cookies in Firebase Studio
if (useSsl) {
void pingServer(functionsInstance.emulatorOrigin + '/backends');
updateEmulatorBanner('Functions', true);
}
}

Expand Down
4 changes: 1 addition & 3 deletions packages/storage/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ import {
createMockUserToken,
EmulatorMockTokenOptions,
isCloudWorkstation,
pingServer,
updateEmulatorBanner
pingServer
} from '@firebase/util';
import { Connection, ConnectionType } from './implementation/connection';

Expand Down Expand Up @@ -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';
Expand Down
178 changes: 0 additions & 178 deletions packages/util/src/emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 = ' &times;';
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 = `<g clip-path="url(#clip0_6013_33858)">
<path d="M4.8 17.6L12 5.6L19.2 17.6H4.8ZM6.91667 16.4H17.0833L12 7.93333L6.91667 16.4ZM12 15.6C12.1667 15.6 12.3056 15.5444 12.4167 15.4333C12.5389 15.3111 12.6 15.1667 12.6 15C12.6 14.8333 12.5389 14.6944 12.4167 14.5833C12.3056 14.4611 12.1667 14.4 12 14.4C11.8333 14.4 11.6889 14.4611 11.5667 14.5833C11.4556 14.6944 11.4 14.8333 11.4 15C11.4 15.1667 11.4556 15.3111 11.5667 15.4333C11.6889 15.5444 11.8333 15.6 12 15.6ZM11.4 13.6H12.6V10.4H11.4V13.6Z" fill="#212121"/>
</g>
<defs>
<clipPath id="clip0_6013_33858">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>`;
} else {
prependIcon.innerHTML = `<g clip-path="url(#clip0_6083_34804)">
<path d="M11.4 15.2H12.6V11.2H11.4V15.2ZM12 10C12.1667 10 12.3056 9.94444 12.4167 9.83333C12.5389 9.71111 12.6 9.56667 12.6 9.4C12.6 9.23333 12.5389 9.09444 12.4167 8.98333C12.3056 8.86111 12.1667 8.8 12 8.8C11.8333 8.8 11.6889 8.86111 11.5667 8.98333C11.4556 9.09444 11.4 9.23333 11.4 9.4C11.4 9.56667 11.4556 9.71111 11.5667 9.83333C11.6889 9.94444 11.8333 10 12 10ZM12 18.4C11.1222 18.4 10.2944 18.2333 9.51667 17.9C8.73889 17.5667 8.05556 17.1111 7.46667 16.5333C6.88889 15.9444 6.43333 15.2611 6.1 14.4833C5.76667 13.7056 5.6 12.8778 5.6 12C5.6 11.1111 5.76667 10.2833 6.1 9.51667C6.43333 8.73889 6.88889 8.06111 7.46667 7.48333C8.05556 6.89444 8.73889 6.43333 9.51667 6.1C10.2944 5.76667 11.1222 5.6 12 5.6C12.8889 5.6 13.7167 5.76667 14.4833 6.1C15.2611 6.43333 15.9389 6.89444 16.5167 7.48333C17.1056 8.06111 17.5667 8.73889 17.9 9.51667C18.2333 10.2833 18.4 11.1111 18.4 12C18.4 12.8778 18.2333 13.7056 17.9 14.4833C17.5667 15.2611 17.1056 15.9444 16.5167 16.5333C15.9389 17.1111 15.2611 17.5667 14.4833 17.9C13.7167 18.2333 12.8889 18.4 12 18.4ZM12 17.2C13.4444 17.2 14.6722 16.6944 15.6833 15.6833C16.6944 14.6722 17.2 13.4444 17.2 12C17.2 10.5556 16.6944 9.32778 15.6833 8.31667C14.6722 7.30555 13.4444 6.8 12 6.8C10.5556 6.8 9.32778 7.30555 8.31667 8.31667C7.30556 9.32778 6.8 10.5556 6.8 12C6.8 13.4444 7.30556 14.6722 8.31667 15.6833C9.32778 16.6944 10.5556 17.2 12 17.2Z" fill="#212121"/>
</g>
<defs>
<clipPath id="clip0_6083_34804">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>`;
firebaseText.innerText = 'Preview backend running in this workspace.';
}
firebaseText.setAttribute('id', firebaseTextId);
}
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', setupDom);
} else {
setupDom();
}
}
Loading