Bez popisu
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.

rc.js 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.RC = exports.loadRC = void 0;
  4. const _ = require("lodash");
  5. const clc = require("colorette");
  6. const cjson = require("cjson");
  7. const fs = require("fs");
  8. const path = require("path");
  9. const detectProjectRoot_1 = require("./detectProjectRoot");
  10. const error_1 = require("./error");
  11. const fsutils = require("./fsutils");
  12. const utils = require("./utils");
  13. const TARGET_TYPES = {
  14. storage: { resource: "bucket", exclusive: true },
  15. database: { resource: "instance", exclusive: true },
  16. hosting: { resource: "site", exclusive: true },
  17. };
  18. function loadRC(options) {
  19. const cwd = options.cwd || process.cwd();
  20. const dir = (0, detectProjectRoot_1.detectProjectRoot)(options);
  21. const potential = path.resolve(dir || cwd, "./.firebaserc");
  22. return RC.loadFile(potential);
  23. }
  24. exports.loadRC = loadRC;
  25. class RC {
  26. constructor(rcpath, data) {
  27. this.path = rcpath;
  28. this.data = Object.assign({ projects: {}, targets: {}, etags: {} }, data);
  29. }
  30. static loadFile(rcpath) {
  31. let data = {};
  32. if (fsutils.fileExistsSync(rcpath)) {
  33. try {
  34. data = cjson.load(rcpath);
  35. }
  36. catch (e) {
  37. utils.logWarning("JSON error trying to load " + clc.bold(rcpath));
  38. }
  39. }
  40. return new RC(rcpath, data);
  41. }
  42. set(key, value) {
  43. _.set(this.data, key, value);
  44. return;
  45. }
  46. unset(key) {
  47. return _.unset(this.data, key);
  48. }
  49. resolveAlias(alias) {
  50. return this.data.projects[alias] || alias;
  51. }
  52. hasProjectAlias(alias) {
  53. return !!this.data.projects[alias];
  54. }
  55. addProjectAlias(alias, project) {
  56. this.set(["projects", alias], project);
  57. return this.save();
  58. }
  59. removeProjectAlias(alias) {
  60. this.unset(["projects", alias]);
  61. return this.save();
  62. }
  63. get hasProjects() {
  64. return Object.keys(this.data.projects).length > 0;
  65. }
  66. get projects() {
  67. return this.data.projects;
  68. }
  69. allTargets(project) {
  70. return this.data.targets[project] || {};
  71. }
  72. targets(project, type) {
  73. var _a;
  74. return ((_a = this.data.targets[project]) === null || _a === void 0 ? void 0 : _a[type]) || {};
  75. }
  76. target(project, type, name) {
  77. var _a, _b;
  78. return ((_b = (_a = this.data.targets[project]) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b[name]) || [];
  79. }
  80. applyTarget(project, type, targetName, resources) {
  81. if (!TARGET_TYPES[type]) {
  82. throw new error_1.FirebaseError(`Unrecognized target type ${clc.bold(type)}. Must be one of ${Object.keys(TARGET_TYPES).join(", ")}`);
  83. }
  84. if (typeof resources === "string") {
  85. resources = [resources];
  86. }
  87. const changed = [];
  88. for (const resource of resources) {
  89. const cur = this.findTarget(project, type, resource);
  90. if (cur && cur !== targetName) {
  91. this.unsetTargetResource(project, type, cur, resource);
  92. changed.push({ resource: resource, target: cur });
  93. }
  94. }
  95. const existing = this.target(project, type, targetName);
  96. const list = Array.from(new Set(existing.concat(resources))).sort();
  97. this.set(["targets", project, type, targetName], list);
  98. this.save();
  99. return changed;
  100. }
  101. removeTarget(project, type, resource) {
  102. const name = this.findTarget(project, type, resource);
  103. if (!name) {
  104. return null;
  105. }
  106. this.unsetTargetResource(project, type, name, resource);
  107. this.save();
  108. return name;
  109. }
  110. clearTarget(project, type, name) {
  111. if (!this.target(project, type, name).length) {
  112. return false;
  113. }
  114. this.unset(["targets", project, type, name]);
  115. this.save();
  116. return true;
  117. }
  118. findTarget(project, type, resource) {
  119. const targets = this.targets(project, type);
  120. for (const targetName in targets) {
  121. if ((targets[targetName] || []).includes(resource)) {
  122. return targetName;
  123. }
  124. }
  125. return null;
  126. }
  127. unsetTargetResource(project, type, name, resource) {
  128. const updatedResources = this.target(project, type, name).filter((r) => r !== resource);
  129. if (updatedResources.length) {
  130. this.set(["targets", project, type, name], updatedResources);
  131. }
  132. else {
  133. this.unset(["targets", project, type, name]);
  134. }
  135. }
  136. requireTarget(project, type, name) {
  137. const target = this.target(project, type, name);
  138. if (!target.length) {
  139. throw new error_1.FirebaseError(`Deploy target ${clc.bold(name)} not configured for project ${clc.bold(project)}. Configure with:
  140. firebase target:apply ${type} ${name} <resources...>`);
  141. }
  142. return target;
  143. }
  144. getEtags(projectId) {
  145. return this.data.etags[projectId] || { extensionInstances: {} };
  146. }
  147. setEtags(projectId, resourceType, etagData) {
  148. if (!this.data.etags[projectId]) {
  149. this.data.etags[projectId] = {};
  150. }
  151. this.data.etags[projectId][resourceType] = etagData;
  152. this.save();
  153. }
  154. save() {
  155. if (this.path) {
  156. fs.writeFileSync(this.path, JSON.stringify(this.data, null, 2), {
  157. encoding: "utf8",
  158. });
  159. return true;
  160. }
  161. return false;
  162. }
  163. }
  164. exports.RC = RC;