"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseUnsetArgs = exports.parseSetArgs = exports.materializeAll = exports.materializeConfig = exports.setVariablesRecursive = exports.getFirebaseConfig = exports.getAppEngineLocation = exports.idsToVarName = exports.varNameToIds = exports.ensureApi = exports.RESERVED_NAMESPACES = void 0; const _ = require("lodash"); const clc = require("colorette"); const api_1 = require("./api"); const apiv2_1 = require("./apiv2"); const ensureApiEnabled_1 = require("./ensureApiEnabled"); const error_1 = require("./error"); const projectUtils_1 = require("./projectUtils"); const runtimeconfig = require("./gcp/runtimeconfig"); exports.RESERVED_NAMESPACES = ["firebase"]; const apiClient = new apiv2_1.Client({ urlPrefix: api_1.firebaseApiOrigin }); function keyToIds(key) { const keyParts = key.split("."); const variable = keyParts.slice(1).join("/"); return { config: keyParts[0], variable: variable, }; } function setVariable(projectId, configId, varPath, val) { if (configId === "" || varPath === "") { const msg = "Invalid argument, each config value must have a 2-part key (e.g. foo.bar)."; throw new error_1.FirebaseError(msg); } return runtimeconfig.variables.set(projectId, configId, varPath, val); } function isReservedNamespace(id) { return exports.RESERVED_NAMESPACES.some((reserved) => { return id.config.toLowerCase().startsWith(reserved); }); } async function ensureApi(options) { const projectId = (0, projectUtils_1.needProjectId)(options); return (0, ensureApiEnabled_1.ensure)(projectId, "runtimeconfig.googleapis.com", "runtimeconfig", true); } exports.ensureApi = ensureApi; function varNameToIds(varName) { return { config: varName.match(new RegExp("/configs/(.+)/variables/"))[1], variable: varName.match(new RegExp("/variables/(.+)"))[1], }; } exports.varNameToIds = varNameToIds; function idsToVarName(projectId, configId, varId) { return ["projects", projectId, "configs", configId, "variables", varId].join("/"); } exports.idsToVarName = idsToVarName; function getAppEngineLocation(config) { let appEngineLocation = config.locationId; if (appEngineLocation && appEngineLocation.match(/[^\d]$/)) { appEngineLocation = appEngineLocation + "1"; } return appEngineLocation || "us-central1"; } exports.getAppEngineLocation = getAppEngineLocation; async function getFirebaseConfig(options) { const projectId = (0, projectUtils_1.needProjectId)(options); const response = await apiClient.get(`/v1beta1/projects/${projectId}/adminSdkConfig`); return response.body; } exports.getFirebaseConfig = getFirebaseConfig; async function setVariablesRecursive(projectId, configId, varPath, val) { let parsed = val; if (typeof val === "string") { try { parsed = JSON.parse(val); } catch (e) { } } if (typeof parsed === "object" && parsed !== null) { return Promise.all(Object.entries(parsed).map(([key, item]) => { const newVarPath = varPath ? [varPath, key].join("/") : key; return setVariablesRecursive(projectId, configId, newVarPath, item); })); } return setVariable(projectId, configId, varPath, val); } exports.setVariablesRecursive = setVariablesRecursive; async function materializeConfig(configName, output) { const materializeVariable = async function (varName) { const variable = await runtimeconfig.variables.get(varName); const id = exports.varNameToIds(variable.name); const key = id.config + "." + id.variable.split("/").join("."); _.set(output, key, variable.text); }; const traverseVariables = async function (variables) { return Promise.all(variables.map((variable) => { return materializeVariable(variable.name); })); }; const variables = await runtimeconfig.variables.list(configName); await traverseVariables(variables); return output; } exports.materializeConfig = materializeConfig; async function materializeAll(projectId) { const output = {}; const configs = await runtimeconfig.configs.list(projectId); if (!Array.isArray(configs) || !configs.length) { return output; } await Promise.all(configs.map((config) => { if (config.name.match(new RegExp("configs/firebase"))) { return; } return exports.materializeConfig(config.name, output); })); return output; } exports.materializeAll = materializeAll; function parseSetArgs(args) { const parsed = []; for (const arg of args) { const parts = arg.split("="); const key = parts[0]; if (parts.length < 2) { throw new error_1.FirebaseError("Invalid argument " + clc.bold(arg) + ", must be in key=val format"); } if (/[A-Z]/.test(key)) { throw new error_1.FirebaseError("Invalid config name " + clc.bold(key) + ", cannot use upper case."); } const id = keyToIds(key); if (isReservedNamespace(id)) { throw new error_1.FirebaseError("Cannot set to reserved namespace " + clc.bold(id.config)); } const val = parts.slice(1).join("="); parsed.push({ configId: id.config, varId: id.variable, val: val, }); } return parsed; } exports.parseSetArgs = parseSetArgs; function parseUnsetArgs(args) { const parsed = []; let splitArgs = []; for (const arg of args) { splitArgs = Array.from(new Set([...splitArgs, ...arg.split(",")])); } for (const key of splitArgs) { const id = keyToIds(key); if (isReservedNamespace(id)) { throw new error_1.FirebaseError("Cannot unset reserved namespace " + clc.bold(id.config)); } parsed.push({ configId: id.config, varId: id.variable, }); } return parsed; } exports.parseUnsetArgs = parseUnsetArgs;