"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.doSetup = void 0; const clc = require("colorette"); const logger_1 = require("../../../logger"); const prompt_1 = require("../../../prompt"); const requirePermissions_1 = require("../../../requirePermissions"); const ensureApiEnabled_1 = require("../../../ensureApiEnabled"); const projectConfig_1 = require("../../../functions/projectConfig"); const error_1 = require("../../../error"); const MAX_ATTEMPTS = 5; async function doSetup(setup, config, options) { var _a, _b; const projectId = (_b = (_a = setup === null || setup === void 0 ? void 0 : setup.rcfile) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b.default; if (projectId) { await (0, requirePermissions_1.requirePermissions)(Object.assign(Object.assign({}, options), { project: projectId })); await Promise.all([ (0, ensureApiEnabled_1.ensure)(projectId, "cloudfunctions.googleapis.com", "unused", true), (0, ensureApiEnabled_1.ensure)(projectId, "runtimeconfig.googleapis.com", "unused", true), ]); } setup.functions = {}; if (!config.src.functions) { setup.config.functions = []; return initNewCodebase(setup, config); } setup.config.functions = (0, projectConfig_1.normalizeAndValidate)(setup.config.functions); const codebases = setup.config.functions.map((cfg) => clc.bold(cfg.codebase)); logger_1.logger.info(`\nDetected existing codebase(s): ${codebases.join(", ")}\n`); const choices = [ { name: "Initialize", value: "new", }, { name: "Overwrite", value: "overwrite", }, ]; const initOpt = await (0, prompt_1.promptOnce)({ type: "list", message: "Would you like to initialize a new codebase, or overwrite an existing one?", default: "new", choices, }); return initOpt === "new" ? initNewCodebase(setup, config) : overwriteCodebase(setup, config); } exports.doSetup = doSetup; async function initNewCodebase(setup, config) { logger_1.logger.info("Let's create a new codebase for your functions."); logger_1.logger.info("A directory corresponding to the codebase will be created in your project"); logger_1.logger.info("with sample code pre-configured.\n"); logger_1.logger.info("See https://firebase.google.com/docs/functions/organize-functions for"); logger_1.logger.info("more information on organizing your functions using codebases.\n"); logger_1.logger.info(`Functions can be deployed with ${clc.bold("firebase deploy")}.\n`); let source; let codebase; if (setup.config.functions.length === 0) { source = "functions"; codebase = "default"; } else { let attempts = 0; while (true) { if (attempts++ >= MAX_ATTEMPTS) { throw new error_1.FirebaseError("Exceeded max number of attempts to input valid codebase name. Please restart."); } codebase = await (0, prompt_1.promptOnce)({ type: "input", message: "What should be the name of this codebase?", }); try { (0, projectConfig_1.validateCodebase)(codebase); (0, projectConfig_1.assertUnique)(setup.config.functions, "codebase", codebase); break; } catch (err) { logger_1.logger.error(err); } } attempts = 0; while (true) { if (attempts >= MAX_ATTEMPTS) { throw new error_1.FirebaseError("Exceeded max number of attempts to input valid source. Please restart."); } attempts++; source = await (0, prompt_1.promptOnce)({ type: "input", message: `In what sub-directory would you like to initialize your functions for codebase ${clc.bold(codebase)}?`, default: codebase, }); try { (0, projectConfig_1.assertUnique)(setup.config.functions, "source", source); break; } catch (err) { logger_1.logger.error(err); } } } setup.config.functions.push({ source, codebase, }); setup.functions.source = source; setup.functions.codebase = codebase; return languageSetup(setup, config); } async function overwriteCodebase(setup, config) { let codebase; if (setup.config.functions.length > 1) { const choices = setup.config.functions.map((cfg) => ({ name: cfg["codebase"], value: cfg["codebase"], })); codebase = await (0, prompt_1.promptOnce)({ type: "list", message: "Which codebase would you like to overwrite?", choices, }); } else { codebase = setup.config.functions[0].codebase; } const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, codebase); setup.functions.source = cbconfig.source; setup.functions.codebase = cbconfig.codebase; logger_1.logger.info(`\nOverwriting ${clc.bold(`codebase ${codebase}...\n`)}`); return languageSetup(setup, config); } async function languageSetup(setup, config) { const choices = [ { name: "JavaScript", value: "javascript", }, { name: "TypeScript", value: "typescript", }, ]; const language = await (0, prompt_1.promptOnce)({ type: "list", message: "What language would you like to use to write Cloud Functions?", default: "javascript", choices, }); const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase); switch (language) { case "javascript": cbconfig.ignore = ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log"]; break; case "typescript": cbconfig.ignore = ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log"]; break; } return require("./" + language).setup(setup, config); }