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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.cleanAuthState = exports.getCleanDomains = exports.removeAuthDomain = exports.addAuthDomains = exports.deleteSite = exports.updateSite = exports.createSite = exports.getSite = exports.listSites = exports.createRelease = exports.cloneVersion = exports.listVersions = exports.updateVersion = exports.createVersion = exports.deleteChannel = exports.updateChannelTtl = exports.createChannel = exports.listChannels = exports.getChannel = exports.normalizeName = void 0;
  4. const error_1 = require("../error");
  5. const api_1 = require("../api");
  6. const apiv2_1 = require("../apiv2");
  7. const operationPoller = require("../operation-poller");
  8. const expireUtils_1 = require("../hosting/expireUtils");
  9. const auth_1 = require("../gcp/auth");
  10. const proto = require("../gcp/proto");
  11. const ONE_WEEK_MS = 604800000;
  12. var ReleaseType;
  13. (function (ReleaseType) {
  14. ReleaseType["TYPE_UNSPECIFIED"] = "TYPE_UNSPECIFIED";
  15. ReleaseType["DEPLOY"] = "DEPLOY";
  16. ReleaseType["ROLLBACK"] = "ROLLBACK";
  17. ReleaseType["SITE_DISABLE"] = "SITE_DISABLE";
  18. })(ReleaseType || (ReleaseType = {}));
  19. function normalizeName(s) {
  20. return s.replace(/[/:_#]/g, "-");
  21. }
  22. exports.normalizeName = normalizeName;
  23. const apiClient = new apiv2_1.Client({
  24. urlPrefix: api_1.hostingApiOrigin,
  25. apiVersion: "v1beta1",
  26. auth: true,
  27. });
  28. async function getChannel(project = "-", site, channelId) {
  29. try {
  30. const res = await apiClient.get(`/projects/${project}/sites/${site}/channels/${channelId}`);
  31. return res.body;
  32. }
  33. catch (e) {
  34. if (e instanceof error_1.FirebaseError && e.status === 404) {
  35. return null;
  36. }
  37. throw e;
  38. }
  39. }
  40. exports.getChannel = getChannel;
  41. async function listChannels(project = "-", site) {
  42. const channels = [];
  43. let nextPageToken = "";
  44. for (;;) {
  45. try {
  46. const res = await apiClient.get(`/projects/${project}/sites/${site}/channels`, { queryParams: { pageToken: nextPageToken, pageSize: 10 } });
  47. const c = res.body.channels;
  48. if (c) {
  49. channels.push(...c);
  50. }
  51. nextPageToken = res.body.nextPageToken || "";
  52. if (!nextPageToken) {
  53. return channels;
  54. }
  55. }
  56. catch (e) {
  57. if (e instanceof error_1.FirebaseError && e.status === 404) {
  58. throw new error_1.FirebaseError(`could not find channels for site "${site}"`, {
  59. original: e,
  60. });
  61. }
  62. throw e;
  63. }
  64. }
  65. }
  66. exports.listChannels = listChannels;
  67. async function createChannel(project = "-", site, channelId, ttlMillis = expireUtils_1.DEFAULT_DURATION) {
  68. const res = await apiClient.post(`/projects/${project}/sites/${site}/channels?channelId=${channelId}`, { ttl: `${ttlMillis / 1000}s` });
  69. return res.body;
  70. }
  71. exports.createChannel = createChannel;
  72. async function updateChannelTtl(project = "-", site, channelId, ttlMillis = ONE_WEEK_MS) {
  73. const res = await apiClient.patch(`/projects/${project}/sites/${site}/channels/${channelId}`, { ttl: `${ttlMillis / 1000}s` }, { queryParams: { updateMask: "ttl" } });
  74. return res.body;
  75. }
  76. exports.updateChannelTtl = updateChannelTtl;
  77. async function deleteChannel(project = "-", site, channelId) {
  78. await apiClient.delete(`/projects/${project}/sites/${site}/channels/${channelId}`);
  79. }
  80. exports.deleteChannel = deleteChannel;
  81. async function createVersion(siteId, version) {
  82. const res = await apiClient.post(`projects/-/sites/${siteId}/versions`, version);
  83. return res.body.name;
  84. }
  85. exports.createVersion = createVersion;
  86. async function updateVersion(site, versionId, version) {
  87. const res = await apiClient.patch(`projects/-/sites/${site}/versions/${versionId}`, version, {
  88. queryParams: {
  89. updateMask: proto.fieldMasks(version, "labels", "config").join(","),
  90. },
  91. });
  92. return res.body;
  93. }
  94. exports.updateVersion = updateVersion;
  95. async function listVersions(site) {
  96. let pageToken = undefined;
  97. const versions = [];
  98. do {
  99. const queryParams = {};
  100. if (pageToken) {
  101. queryParams.pageToken = pageToken;
  102. }
  103. const res = await apiClient.get(`projects/-/sites/${site}/versions`, {
  104. queryParams,
  105. });
  106. versions.push(...res.body.versions);
  107. pageToken = res.body.nextPageToken;
  108. } while (pageToken);
  109. return versions;
  110. }
  111. exports.listVersions = listVersions;
  112. async function cloneVersion(site, versionName, finalize = false) {
  113. const res = await apiClient.post(`/projects/-/sites/${site}/versions:clone`, {
  114. sourceVersion: versionName,
  115. finalize,
  116. });
  117. const { name: operationName } = res.body;
  118. const pollRes = await operationPoller.pollOperation({
  119. apiOrigin: api_1.hostingApiOrigin,
  120. apiVersion: "v1beta1",
  121. operationResourceName: operationName,
  122. masterTimeout: 600000,
  123. });
  124. return pollRes;
  125. }
  126. exports.cloneVersion = cloneVersion;
  127. async function createRelease(site, channel, version, partialRelease) {
  128. const res = await apiClient.post(`/projects/-/sites/${site}/channels/${channel}/releases`, partialRelease, { queryParams: { versionName: version } });
  129. return res.body;
  130. }
  131. exports.createRelease = createRelease;
  132. async function listSites(project) {
  133. const sites = [];
  134. let nextPageToken = "";
  135. for (;;) {
  136. try {
  137. const res = await apiClient.get(`/projects/${project}/sites`, { queryParams: { pageToken: nextPageToken, pageSize: 10 } });
  138. const c = res.body.sites;
  139. if (c) {
  140. sites.push(...c);
  141. }
  142. nextPageToken = res.body.nextPageToken || "";
  143. if (!nextPageToken) {
  144. return sites;
  145. }
  146. }
  147. catch (e) {
  148. if (e instanceof error_1.FirebaseError && e.status === 404) {
  149. throw new error_1.FirebaseError(`could not find sites for project "${project}"`, {
  150. original: e,
  151. });
  152. }
  153. throw e;
  154. }
  155. }
  156. }
  157. exports.listSites = listSites;
  158. async function getSite(project, site) {
  159. try {
  160. const res = await apiClient.get(`/projects/${project}/sites/${site}`);
  161. return res.body;
  162. }
  163. catch (e) {
  164. if (e instanceof error_1.FirebaseError && e.status === 404) {
  165. throw new error_1.FirebaseError(`could not find site "${site}" for project "${project}"`, {
  166. original: e,
  167. });
  168. }
  169. throw e;
  170. }
  171. }
  172. exports.getSite = getSite;
  173. async function createSite(project, site, appId = "") {
  174. const res = await apiClient.post(`/projects/${project}/sites`, { appId: appId }, { queryParams: { siteId: site } });
  175. return res.body;
  176. }
  177. exports.createSite = createSite;
  178. async function updateSite(project, site, fields) {
  179. const res = await apiClient.patch(`/projects/${project}/sites/${site.name}`, site, {
  180. queryParams: { updateMask: fields.join(",") },
  181. });
  182. return res.body;
  183. }
  184. exports.updateSite = updateSite;
  185. async function deleteSite(project, site) {
  186. await apiClient.delete(`/projects/${project}/sites/${site}`);
  187. }
  188. exports.deleteSite = deleteSite;
  189. async function addAuthDomains(project, urls) {
  190. const domains = await (0, auth_1.getAuthDomains)(project);
  191. const authDomains = domains || [];
  192. for (const url of urls) {
  193. const domain = url.replace("https://", "");
  194. if (authDomains.includes(domain)) {
  195. continue;
  196. }
  197. authDomains.push(domain);
  198. }
  199. return await (0, auth_1.updateAuthDomains)(project, authDomains);
  200. }
  201. exports.addAuthDomains = addAuthDomains;
  202. async function removeAuthDomain(project, url) {
  203. const domains = await (0, auth_1.getAuthDomains)(project);
  204. if (!domains.length) {
  205. return domains;
  206. }
  207. const targetDomain = url.replace("https://", "");
  208. const authDomains = domains.filter((domain) => domain !== targetDomain);
  209. return (0, auth_1.updateAuthDomains)(project, authDomains);
  210. }
  211. exports.removeAuthDomain = removeAuthDomain;
  212. async function getCleanDomains(project, site) {
  213. const channels = await listChannels(project, site);
  214. const channelMap = channels
  215. .map((channel) => channel.url.replace("https://", ""))
  216. .reduce((acc, current) => {
  217. acc[current] = true;
  218. return acc;
  219. }, {});
  220. const siteMatch = new RegExp(`${site}--`, "i");
  221. const firebaseAppMatch = new RegExp(/firebaseapp.com$/);
  222. const domains = await (0, auth_1.getAuthDomains)(project);
  223. const authDomains = [];
  224. domains.forEach((domain) => {
  225. const endsWithFirebaseApp = firebaseAppMatch.test(domain);
  226. if (endsWithFirebaseApp) {
  227. authDomains.push(domain);
  228. return;
  229. }
  230. const domainWithNoChannel = siteMatch.test(domain) && !channelMap[domain];
  231. if (domainWithNoChannel) {
  232. return;
  233. }
  234. authDomains.push(domain);
  235. });
  236. return authDomains;
  237. }
  238. exports.getCleanDomains = getCleanDomains;
  239. async function cleanAuthState(project, sites) {
  240. const siteDomainMap = new Map();
  241. for (const site of sites) {
  242. const authDomains = await getCleanDomains(project, site);
  243. const updatedDomains = await (0, auth_1.updateAuthDomains)(project, authDomains);
  244. siteDomainMap.set(site, updatedDomains);
  245. }
  246. return siteDomainMap;
  247. }
  248. exports.cleanAuthState = cleanAuthState;