123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.command = void 0;
- const path = require("path");
- const clc = require("colorette");
- const requireInteractive_1 = require("../requireInteractive");
- const command_1 = require("../command");
- const error_1 = require("../error");
- const iam_1 = require("../gcp/iam");
- const logger_1 = require("../logger");
- const prompt_1 = require("../prompt");
- const requirePermissions_1 = require("../requirePermissions");
- const utils_1 = require("../utils");
- const functional_1 = require("../functional");
- const configExport = require("../functions/runtimeConfigExport");
- const requireConfig_1 = require("../requireConfig");
- const projectConfig_1 = require("../functions/projectConfig");
- const REQUIRED_PERMISSIONS = [
- "runtimeconfig.configs.list",
- "runtimeconfig.configs.get",
- "runtimeconfig.variables.list",
- "runtimeconfig.variables.get",
- ];
- const RESERVED_PROJECT_ALIAS = ["local"];
- const MAX_ATTEMPTS = 3;
- function checkReservedAliases(pInfos) {
- for (const pInfo of pInfos) {
- if (pInfo.alias && RESERVED_PROJECT_ALIAS.includes(pInfo.alias)) {
- (0, utils_1.logWarning)(`Project alias (${clc.bold(pInfo.alias)}) is reserved for internal use. ` +
- `Saving exported config in .env.${pInfo.projectId} instead.`);
- delete pInfo.alias;
- }
- }
- }
- async function checkRequiredPermission(pInfos) {
- pInfos = pInfos.filter((pInfo) => !pInfo.config);
- const testPermissions = pInfos.map((pInfo) => (0, iam_1.testIamPermissions)(pInfo.projectId, REQUIRED_PERMISSIONS));
- const results = await Promise.all(testPermissions);
- for (const [pInfo, result] of (0, functional_1.zip)(pInfos, results)) {
- if (result.passed) {
- throw new error_1.FirebaseError(`Unexpectedly failed to fetch runtime config for project ${pInfo.projectId}`);
- }
- (0, utils_1.logWarning)("You are missing the following permissions to read functions config on project " +
- `${clc.bold(pInfo.projectId)}:\n\t${result.missing.join("\n\t")}`);
- const confirm = await (0, prompt_1.promptOnce)({
- type: "confirm",
- name: "skip",
- default: true,
- message: `Continue without importing configs from project ${pInfo.projectId}?`,
- });
- if (!confirm) {
- throw new error_1.FirebaseError("Command aborted!");
- }
- }
- }
- async function promptForPrefix(errMsg) {
- (0, utils_1.logWarning)("The following configs keys could not be exported as environment variables:\n");
- (0, utils_1.logWarning)(errMsg);
- return await (0, prompt_1.promptOnce)({
- type: "input",
- name: "prefix",
- default: "CONFIG_",
- message: "Enter a PREFIX to rename invalid environment variable keys:",
- }, {});
- }
- function fromEntries(itr) {
- const obj = {};
- for (const [k, v] of itr) {
- obj[k] = v;
- }
- return obj;
- }
- exports.command = new command_1.Command("functions:config:export")
- .description("Export environment config as environment variables in dotenv format")
- .before(requirePermissions_1.requirePermissions, [
- "runtimeconfig.configs.list",
- "runtimeconfig.configs.get",
- "runtimeconfig.variables.list",
- "runtimeconfig.variables.get",
- ])
- .before(requireConfig_1.requireConfig)
- .before(requireInteractive_1.default)
- .action(async (options) => {
- const config = (0, projectConfig_1.normalizeAndValidate)(options.config.src.functions)[0];
- const functionsDir = config.source;
- let pInfos = configExport.getProjectInfos(options);
- checkReservedAliases(pInfos);
- (0, utils_1.logBullet)("Importing functions configs from projects [" +
- pInfos.map(({ projectId }) => `${clc.bold(projectId)}`).join(", ") +
- "]");
- await configExport.hydrateConfigs(pInfos);
- await checkRequiredPermission(pInfos);
- pInfos = pInfos.filter((pInfo) => pInfo.config);
- logger_1.logger.debug(`Loaded function configs: ${JSON.stringify(pInfos)}`);
- (0, utils_1.logBullet)(`Importing configs from projects: [${pInfos.map((p) => p.projectId).join(", ")}]`);
- let attempts = 0;
- let prefix = "";
- while (true) {
- if (attempts >= MAX_ATTEMPTS) {
- throw new error_1.FirebaseError("Exceeded max attempts to fix invalid config keys.");
- }
- const errMsg = configExport.hydrateEnvs(pInfos, prefix);
- if (errMsg.length === 0) {
- break;
- }
- prefix = await promptForPrefix(errMsg);
- attempts += 1;
- }
- const header = `# Exported firebase functions:config:export command on ${new Date().toLocaleDateString()}`;
- const dotEnvs = pInfos.map((pInfo) => configExport.toDotenvFormat(pInfo.envs, header));
- const filenames = pInfos.map(configExport.generateDotenvFilename);
- const filesToWrite = fromEntries((0, functional_1.zip)(filenames, dotEnvs));
- filesToWrite[".env.local"] = `${header}\n# .env.local file contains environment variables for the Functions Emulator.\n`;
- filesToWrite[".env"] = `${header}# .env file contains environment variables that applies to all projects.\n`;
- for (const [filename, content] of Object.entries(filesToWrite)) {
- await options.config.askWriteProjectFile(path.join(functionsDir, filename), content);
- }
- });
|