Ei kuvausta
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.

database.js 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.listDatabaseInstances = exports.parseDatabaseLocation = exports.checkInstanceNameAvailable = exports.createInstance = exports.getDatabaseInstanceDetails = exports.populateInstanceDetails = exports.DatabaseLocation = exports.DatabaseInstanceState = exports.DatabaseInstanceType = exports.APP_LIST_PAGE_SIZE = exports.MGMT_API_VERSION = void 0;
  4. const apiv2_1 = require("../apiv2");
  5. const constants_1 = require("../emulator/constants");
  6. const error_1 = require("../error");
  7. const logger_1 = require("../logger");
  8. const api_1 = require("../api");
  9. const utils = require("../utils");
  10. exports.MGMT_API_VERSION = "v1beta";
  11. exports.APP_LIST_PAGE_SIZE = 100;
  12. const TIMEOUT_MILLIS = 10000;
  13. const INSTANCE_RESOURCE_NAME_REGEX = /projects\/([^/]+?)\/locations\/([^/]+?)\/instances\/([^/]*)/;
  14. var DatabaseInstanceType;
  15. (function (DatabaseInstanceType) {
  16. DatabaseInstanceType["DATABASE_INSTANCE_TYPE_UNSPECIFIED"] = "unspecified";
  17. DatabaseInstanceType["DEFAULT_DATABASE"] = "default_database";
  18. DatabaseInstanceType["USER_DATABASE"] = "user_database";
  19. })(DatabaseInstanceType = exports.DatabaseInstanceType || (exports.DatabaseInstanceType = {}));
  20. var DatabaseInstanceState;
  21. (function (DatabaseInstanceState) {
  22. DatabaseInstanceState["LIFECYCLE_STATE_UNSPECIFIED"] = "unspecified";
  23. DatabaseInstanceState["ACTIVE"] = "active";
  24. DatabaseInstanceState["DISABLED"] = "disabled";
  25. DatabaseInstanceState["DELETED"] = "deleted";
  26. })(DatabaseInstanceState = exports.DatabaseInstanceState || (exports.DatabaseInstanceState = {}));
  27. var DatabaseLocation;
  28. (function (DatabaseLocation) {
  29. DatabaseLocation["US_CENTRAL1"] = "us-central1";
  30. DatabaseLocation["EUROPE_WEST1"] = "europe-west1";
  31. DatabaseLocation["ASIA_SOUTHEAST1"] = "asia-southeast1";
  32. DatabaseLocation["ANY"] = "-";
  33. })(DatabaseLocation = exports.DatabaseLocation || (exports.DatabaseLocation = {}));
  34. const apiClient = new apiv2_1.Client({ urlPrefix: api_1.rtdbManagementOrigin, apiVersion: exports.MGMT_API_VERSION });
  35. async function populateInstanceDetails(options) {
  36. options.instanceDetails = await getDatabaseInstanceDetails(options.project, options.instance);
  37. return Promise.resolve();
  38. }
  39. exports.populateInstanceDetails = populateInstanceDetails;
  40. async function getDatabaseInstanceDetails(projectId, instanceName) {
  41. try {
  42. const response = await apiClient.request({
  43. method: "GET",
  44. path: `/projects/${projectId}/locations/-/instances/${instanceName}`,
  45. timeout: TIMEOUT_MILLIS,
  46. });
  47. return convertDatabaseInstance(response.body);
  48. }
  49. catch (err) {
  50. logger_1.logger.debug(err.message);
  51. const emulatorHost = process.env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST];
  52. if (emulatorHost) {
  53. return Promise.resolve({
  54. name: instanceName,
  55. project: projectId,
  56. location: DatabaseLocation.ANY,
  57. databaseUrl: utils.getDatabaseUrl(emulatorHost, instanceName, ""),
  58. type: DatabaseInstanceType.DEFAULT_DATABASE,
  59. state: DatabaseInstanceState.ACTIVE,
  60. });
  61. }
  62. throw new error_1.FirebaseError(`Failed to get instance details for instance: ${instanceName}. See firebase-debug.log for more details.`, {
  63. exit: 2,
  64. original: err,
  65. });
  66. }
  67. }
  68. exports.getDatabaseInstanceDetails = getDatabaseInstanceDetails;
  69. async function createInstance(projectId, instanceName, location, databaseType) {
  70. try {
  71. const response = await apiClient.request({
  72. method: "POST",
  73. path: `/projects/${projectId}/locations/${location}/instances`,
  74. queryParams: { databaseId: instanceName },
  75. body: { type: databaseType },
  76. timeout: TIMEOUT_MILLIS,
  77. });
  78. return convertDatabaseInstance(response.body);
  79. }
  80. catch (err) {
  81. logger_1.logger.debug(err.message);
  82. return utils.reject(`Failed to create instance: ${instanceName}. See firebase-debug.log for more details.`, {
  83. code: 2,
  84. original: err,
  85. });
  86. }
  87. }
  88. exports.createInstance = createInstance;
  89. async function checkInstanceNameAvailable(projectId, instanceName, databaseType, location) {
  90. var _a, _b, _c;
  91. if (!location) {
  92. location = DatabaseLocation.US_CENTRAL1;
  93. }
  94. try {
  95. await apiClient.request({
  96. method: "POST",
  97. path: `/projects/${projectId}/locations/${location}/instances`,
  98. queryParams: { databaseId: instanceName, validateOnly: "true" },
  99. body: { type: databaseType },
  100. timeout: TIMEOUT_MILLIS,
  101. });
  102. return { available: true };
  103. }
  104. catch (err) {
  105. logger_1.logger.debug(`Invalid Realtime Database instance name: ${instanceName}.${err.message ? " " + err.message : ""}`);
  106. const errBody = err.context.body.error;
  107. if ((_c = (_b = (_a = errBody === null || errBody === void 0 ? void 0 : errBody.details) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.metadata) === null || _c === void 0 ? void 0 : _c.suggested_database_ids) {
  108. return {
  109. available: false,
  110. suggestedIds: errBody.details[0].metadata.suggested_database_ids.split(","),
  111. };
  112. }
  113. throw new error_1.FirebaseError(`Failed to validate Realtime Database instance name: ${instanceName}.`, {
  114. original: err,
  115. });
  116. }
  117. }
  118. exports.checkInstanceNameAvailable = checkInstanceNameAvailable;
  119. function parseDatabaseLocation(location, defaultLocation) {
  120. if (!location) {
  121. return defaultLocation;
  122. }
  123. switch (location.toLowerCase()) {
  124. case "us-central1":
  125. return DatabaseLocation.US_CENTRAL1;
  126. case "europe-west1":
  127. return DatabaseLocation.EUROPE_WEST1;
  128. case "asia-southeast1":
  129. return DatabaseLocation.ASIA_SOUTHEAST1;
  130. case "":
  131. return defaultLocation;
  132. default:
  133. throw new error_1.FirebaseError(`Unexpected location value: ${location}. Only us-central1, europe-west1, and asia-southeast1 locations are supported`);
  134. }
  135. }
  136. exports.parseDatabaseLocation = parseDatabaseLocation;
  137. async function listDatabaseInstances(projectId, location, pageSize = exports.APP_LIST_PAGE_SIZE) {
  138. const instances = [];
  139. try {
  140. let nextPageToken = "";
  141. do {
  142. const queryParams = { pageSize };
  143. if (nextPageToken) {
  144. queryParams.pageToken = nextPageToken;
  145. }
  146. const response = await apiClient.request({
  147. method: "GET",
  148. path: `/projects/${projectId}/locations/${location}/instances`,
  149. queryParams,
  150. timeout: TIMEOUT_MILLIS,
  151. });
  152. if (response.body.instances) {
  153. instances.push(...response.body.instances.map(convertDatabaseInstance));
  154. }
  155. nextPageToken = response.body.nextPageToken;
  156. } while (nextPageToken);
  157. return instances;
  158. }
  159. catch (err) {
  160. logger_1.logger.debug(err.message);
  161. throw new error_1.FirebaseError(`Failed to list Firebase Realtime Database instances${location === DatabaseLocation.ANY ? "" : ` for location ${location}`}` + ". See firebase-debug.log for more info.", {
  162. exit: 2,
  163. original: err,
  164. });
  165. }
  166. }
  167. exports.listDatabaseInstances = listDatabaseInstances;
  168. function convertDatabaseInstance(serverInstance) {
  169. if (!serverInstance.name) {
  170. throw new error_1.FirebaseError(`DatabaseInstance response is missing field "name"`);
  171. }
  172. const m = serverInstance.name.match(INSTANCE_RESOURCE_NAME_REGEX);
  173. if (!m || m.length !== 4) {
  174. throw new error_1.FirebaseError(`Error parsing instance resource name: ${serverInstance.name}, matches: ${m}`);
  175. }
  176. return {
  177. name: m[3],
  178. location: parseDatabaseLocation(m[2], DatabaseLocation.ANY),
  179. project: serverInstance.project,
  180. databaseUrl: serverInstance.databaseUrl,
  181. type: serverInstance.type,
  182. state: serverInstance.state,
  183. };
  184. }