UNPKG

firebase-tools

Version:
123 lines (120 loc) 5.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.enableApiURI = exports.bestEffortEnsure = exports.ensure = exports.check = exports.POLL_SETTINGS = void 0; const colorette_1 = require("colorette"); const track_1 = require("./track"); const api_1 = require("./api"); const apiv2_1 = require("./apiv2"); const utils = require("./utils"); const error_1 = require("./error"); const logger_1 = require("./logger"); exports.POLL_SETTINGS = { pollInterval: 10000, pollsBeforeRetry: 12, }; const apiClient = new apiv2_1.Client({ urlPrefix: (0, api_1.serviceUsageOrigin)(), apiVersion: "v1", }); async function check(projectId, apiUri, prefix, silent = false) { const apiName = apiUri.startsWith("http") ? new URL(apiUri).hostname : apiUri; const res = await apiClient.get(`/projects/${projectId}/services/${apiName}`, { headers: { "x-goog-quota-user": `projects/${projectId}` }, skipLog: { resBody: true }, }); const isEnabled = res.body.state === "ENABLED"; if (isEnabled && !silent) { utils.logLabeledSuccess(prefix, `required API ${(0, colorette_1.bold)(apiName)} is enabled`); } return isEnabled; } exports.check = check; function isPermissionError(e) { var _a, _b, _c; return ((_c = (_b = (_a = e.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.status) === "PERMISSION_DENIED"; } async function enable(projectId, apiName) { try { await apiClient.post(`/projects/${projectId}/services/${apiName}:enable`, undefined, { headers: { "x-goog-quota-user": `projects/${projectId}` }, skipLog: { resBody: true }, }); } catch (err) { if ((0, error_1.isBillingError)(err)) { throw new error_1.FirebaseError(`Your project ${(0, colorette_1.bold)(projectId)} must be on the Blaze (pay-as-you-go) plan to complete this command. Required API ${(0, colorette_1.bold)(apiName)} can't be enabled until the upgrade is complete. To upgrade, visit the following URL: https://console.firebase.google.com/project/${projectId}/usage/details`); } else if (isPermissionError(err)) { const apiPermissionDeniedRegex = new RegExp(/Permission denied to enable service \[([.a-zA-Z]+)\]/); const permissionsError = apiPermissionDeniedRegex.exec(err.message); if (permissionsError && permissionsError[1]) { const serviceUrl = permissionsError[1]; err.message = `Permissions denied enabling ${serviceUrl}. Please ask a project owner to visit the following URL to enable this service: https://console.cloud.google.com/apis/library/${serviceUrl}?project=${projectId}`; throw err; } else { throw err; } } else { throw err; } } } async function pollCheckEnabled(projectId, apiName, prefix, silent, enablementRetries, pollRetries = 0) { if (pollRetries > exports.POLL_SETTINGS.pollsBeforeRetry) { return enableApiWithRetries(projectId, apiName, prefix, silent, enablementRetries + 1); } await new Promise((resolve) => { setTimeout(resolve, exports.POLL_SETTINGS.pollInterval); }); const isEnabled = await check(projectId, apiName, prefix, silent); if (isEnabled) { void (0, track_1.trackGA4)("api_enabled", { api_name: apiName, }); return; } if (!silent) { utils.logLabeledBullet(prefix, `waiting for API ${(0, colorette_1.bold)(apiName)} to activate...`); } return pollCheckEnabled(projectId, apiName, prefix, silent, enablementRetries, pollRetries + 1); } async function enableApiWithRetries(projectId, apiName, prefix, silent, enablementRetries = 0) { if (enablementRetries > 1) { throw new error_1.FirebaseError(`Timed out waiting for API ${(0, colorette_1.bold)(apiName)} to enable. Please try again in a few minutes.`); } await enable(projectId, apiName); return pollCheckEnabled(projectId, apiName, prefix, silent, enablementRetries); } async function ensure(projectId, apiUri, prefix, silent = false) { const hostname = apiUri.startsWith("http") ? new URL(apiUri).hostname : apiUri; if (!silent) { utils.logLabeledBullet(prefix, `ensuring required API ${(0, colorette_1.bold)(hostname)} is enabled...`); } const isEnabled = await check(projectId, hostname, prefix, silent); if (isEnabled) { return; } if (!silent) { utils.logLabeledWarning(prefix, `missing required API ${(0, colorette_1.bold)(hostname)}. Enabling now...`); } return enableApiWithRetries(projectId, hostname, prefix, silent); } exports.ensure = ensure; async function bestEffortEnsure(projectId, apiUri, prefix, silent = false) { try { await ensure(projectId, apiUri, prefix, silent); } catch (err) { logger_1.logger.debug(`Unable to check that ${apiUri} is enabled on ${projectId}. Calls to it will fail if it is not enabled`); } } exports.bestEffortEnsure = bestEffortEnsure; function enableApiURI(projectId, apiName) { return `https://console.cloud.google.com/apis/library/${apiName}?project=${projectId}`; } exports.enableApiURI = enableApiURI;