No Description
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.

init.js 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.command = void 0;
  4. const clc = require("colorette");
  5. const fs = require("fs");
  6. const os = require("os");
  7. const path = require("path");
  8. const command_1 = require("../command");
  9. const config_1 = require("../config");
  10. const auth_1 = require("../auth");
  11. const init_1 = require("../init");
  12. const logger_1 = require("../logger");
  13. const prompt_1 = require("../prompt");
  14. const requireAuth_1 = require("../requireAuth");
  15. const fsutils = require("../fsutils");
  16. const utils = require("../utils");
  17. const homeDir = os.homedir();
  18. const TEMPLATE_ROOT = path.resolve(__dirname, "../../templates/");
  19. const BANNER_TEXT = fs.readFileSync(path.join(TEMPLATE_ROOT, "banner.txt"), "utf8");
  20. const GITIGNORE_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "_gitignore"), "utf8");
  21. function isOutside(from, to) {
  22. return !!/^\.\./.exec(path.relative(from, to));
  23. }
  24. const choices = [
  25. {
  26. value: "database",
  27. name: "Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance",
  28. checked: false,
  29. },
  30. {
  31. value: "firestore",
  32. name: "Firestore: Configure security rules and indexes files for Firestore",
  33. checked: false,
  34. },
  35. {
  36. value: "functions",
  37. name: "Functions: Configure a Cloud Functions directory and its files",
  38. checked: false,
  39. },
  40. {
  41. value: "hosting",
  42. name: "Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys",
  43. checked: false,
  44. },
  45. {
  46. value: "hosting:github",
  47. name: "Hosting: Set up GitHub Action deploys",
  48. checked: false,
  49. },
  50. {
  51. value: "storage",
  52. name: "Storage: Configure a security rules file for Cloud Storage",
  53. checked: false,
  54. },
  55. {
  56. value: "emulators",
  57. name: "Emulators: Set up local emulators for Firebase products",
  58. checked: false,
  59. },
  60. {
  61. value: "remoteconfig",
  62. name: "Remote Config: Configure a template file for Remote Config",
  63. checked: false,
  64. },
  65. ];
  66. const featureNames = choices.map((choice) => choice.value);
  67. const DESCRIPTION = `Interactively configure the current directory as a Firebase project or initialize new features in an already configured Firebase project directory.
  68. This command will create or update 'firebase.json' and '.firebaserc' configuration files in the current directory.
  69. To initialize a specific Firebase feature, run 'firebase init [feature]'. Valid features are:
  70. ${[...featureNames]
  71. .sort()
  72. .map((n) => `\n - ${n}`)
  73. .join("")}`;
  74. exports.command = new command_1.Command("init [feature]")
  75. .description(DESCRIPTION)
  76. .before(requireAuth_1.requireAuth)
  77. .action((feature, options) => {
  78. if (feature && !featureNames.includes(feature)) {
  79. return utils.reject(clc.bold(feature) +
  80. " is not a supported feature; must be one of " +
  81. featureNames.join(", ") +
  82. ".");
  83. }
  84. const cwd = options.cwd || process.cwd();
  85. const warnings = [];
  86. let warningText = "";
  87. if (isOutside(homeDir, cwd)) {
  88. warnings.push("You are currently outside your home directory");
  89. }
  90. if (cwd === homeDir) {
  91. warnings.push("You are initializing your home directory as a Firebase project directory");
  92. }
  93. const existingConfig = config_1.Config.load(options, true);
  94. if (existingConfig) {
  95. warnings.push("You are initializing within an existing Firebase project directory");
  96. }
  97. const config = existingConfig !== null ? existingConfig : new config_1.Config({}, { projectDir: cwd, cwd: cwd });
  98. if (warnings.length) {
  99. warningText =
  100. "\nBefore we get started, keep in mind:\n\n " +
  101. clc.yellow(clc.bold("* ")) +
  102. warnings.join("\n " + clc.yellow(clc.bold("* "))) +
  103. "\n";
  104. }
  105. logger_1.logger.info(clc.yellow(clc.bold(BANNER_TEXT)) +
  106. "\nYou're about to initialize a Firebase project in this directory:\n\n " +
  107. clc.bold(config.projectDir) +
  108. "\n" +
  109. warningText);
  110. const setup = {
  111. config: config.src,
  112. rcfile: config.readProjectFile(".firebaserc", {
  113. json: true,
  114. fallback: {},
  115. }),
  116. };
  117. let next;
  118. if (process.platform === "win32") {
  119. next = (0, prompt_1.promptOnce)({
  120. type: "confirm",
  121. message: "Are you ready to proceed?",
  122. });
  123. }
  124. else {
  125. next = Promise.resolve(true);
  126. }
  127. return next
  128. .then((proceed) => {
  129. if (!proceed) {
  130. return utils.reject("Aborted by user.", { exit: 1 });
  131. }
  132. if (feature) {
  133. setup.featureArg = true;
  134. setup.features = [feature];
  135. return undefined;
  136. }
  137. return (0, prompt_1.prompt)(setup, [
  138. {
  139. type: "checkbox",
  140. name: "features",
  141. message: "Which Firebase features do you want to set up for this directory? " +
  142. "Press Space to select features, then Enter to confirm your choices.",
  143. choices: choices,
  144. },
  145. ]);
  146. })
  147. .then(() => {
  148. var _a;
  149. if (!setup.features || ((_a = setup.features) === null || _a === void 0 ? void 0 : _a.length) === 0) {
  150. return utils.reject("Must select at least one feature. Use " +
  151. clc.bold(clc.underline("SPACEBAR")) +
  152. " to select features, or specify a feature by running " +
  153. clc.bold("firebase init [feature_name]"));
  154. }
  155. setup.features.unshift("project");
  156. const allAccounts = (0, auth_1.getAllAccounts)();
  157. if (allAccounts.length > 1) {
  158. setup.features.unshift("account");
  159. }
  160. if (setup.features.includes("hosting") && setup.features.includes("hosting:github")) {
  161. setup.features = setup.features.filter((f) => f !== "hosting:github");
  162. }
  163. return (0, init_1.init)(setup, config, options);
  164. })
  165. .then(() => {
  166. logger_1.logger.info();
  167. utils.logBullet("Writing configuration info to " + clc.bold("firebase.json") + "...");
  168. config.writeProjectFile("firebase.json", setup.config);
  169. utils.logBullet("Writing project information to " + clc.bold(".firebaserc") + "...");
  170. config.writeProjectFile(".firebaserc", setup.rcfile);
  171. if (!fsutils.fileExistsSync(config.path(".gitignore"))) {
  172. utils.logBullet("Writing gitignore file to " + clc.bold(".gitignore") + "...");
  173. config.writeProjectFile(".gitignore", GITIGNORE_TEMPLATE);
  174. }
  175. logger_1.logger.info();
  176. utils.logSuccess("Firebase initialization complete!");
  177. });
  178. });