"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmulatorRegistry = void 0; const types_1 = require("./types"); const error_1 = require("../error"); const portUtils = require("./portUtils"); const constants_1 = require("./constants"); const emulatorLogger_1 = require("./emulatorLogger"); const utils_1 = require("../utils"); const apiv2_1 = require("../apiv2"); class EmulatorRegistry { static async start(instance) { const description = constants_1.Constants.description(instance.getName()); if (this.isRunning(instance.getName())) { throw new error_1.FirebaseError(`${description} is already running!`, {}); } this.set(instance.getName(), instance); await instance.start(); if (instance.getName() !== types_1.Emulators.EXTENSIONS) { const info = instance.getInfo(); await portUtils.waitForPortClosed(info.port, (0, utils_1.connectableHostname)(info.host)); } } static async stop(name) { emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("BULLET", name, `Stopping ${constants_1.Constants.description(name)}`); const instance = this.get(name); if (!instance) { return; } await instance.stop(); this.clear(instance.getName()); } static async stopAll() { const stopPriority = { ui: 0, extensions: 1, functions: 1.1, hosting: 2, database: 3.0, firestore: 3.1, pubsub: 3.2, auth: 3.3, storage: 3.5, eventarc: 3.6, hub: 4, logging: 5, }; const emulatorsToStop = this.listRunning().sort((a, b) => { return stopPriority[a] - stopPriority[b]; }); for (const name of emulatorsToStop) { try { await this.stop(name); } catch (e) { emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("WARN", name, `Error stopping ${constants_1.Constants.description(name)}`); } } } static isRunning(emulator) { if (emulator === types_1.Emulators.EXTENSIONS) { return this.INSTANCES.get(emulator) !== undefined && this.isRunning(types_1.Emulators.FUNCTIONS); } const instance = this.INSTANCES.get(emulator); return instance !== undefined; } static listRunning() { return types_1.ALL_EMULATORS.filter((name) => this.isRunning(name)); } static listRunningWithInfo() { return this.listRunning() .map((emulator) => this.getInfo(emulator)) .filter((info) => typeof info !== "undefined"); } static get(emulator) { return this.INSTANCES.get(emulator); } static getInfo(emulator) { var _a; const info = (_a = EmulatorRegistry.get(emulator)) === null || _a === void 0 ? void 0 : _a.getInfo(); if (!info) { return undefined; } return Object.assign(Object.assign({}, info), { host: (0, utils_1.connectableHostname)(info.host) }); } static url(emulator, req) { const url = new URL("http://unknown/"); if (req) { url.protocol = req.protocol; const host = req.headers.host; if (host) { url.host = host; return url; } } const info = EmulatorRegistry.getInfo(emulator); if (info) { if (info.host.includes(":")) { url.hostname = `[${info.host}]`; } else { url.hostname = info.host; } url.port = info.port.toString(); } else { console.warn(`Cannot determine host and port of ${emulator}`); } return url; } static client(emulator, options = {}) { return new apiv2_1.Client(Object.assign({ urlPrefix: EmulatorRegistry.url(emulator).toString(), auth: false }, options)); } static set(emulator, instance) { this.INSTANCES.set(emulator, instance); } static clear(emulator) { this.INSTANCES.delete(emulator); } } exports.EmulatorRegistry = EmulatorRegistry; EmulatorRegistry.INSTANCES = new Map();