forked from dienianindya/gsi_ess_mobile
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
5.2 KiB
118 lines
5.2 KiB
"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);
|
|
}
|
|
});
|