firebase-tools
Version:
Command-Line Interface for Firebase
106 lines (105 loc) • 5.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteFunctionsByEndpointFilters = deleteFunctionsByEndpointFilters;
const backend = require("./backend");
const planner = require("./release/planner");
const executor = require("./release/executor");
const fabricator = require("./release/fabricator");
const functionsDeployHelper_1 = require("./functionsDeployHelper");
const getProjectNumber_1 = require("../../getProjectNumber");
const reporter = require("./release/reporter");
const prompt = require("../../prompt");
const functionsConfig = require("../../functionsConfig");
const error_1 = require("../../error");
const projectConfig_1 = require("../../functions/projectConfig");
async function deleteFunctionsByEndpointFilters(context, options) {
const allExistingBackend = await backend.existingBackend(context);
const targetedRegionBackend = options?.region
? backend.matchingBackend(allExistingBackend, (endpoint) => endpoint.region === options.region)
: allExistingBackend;
const codebases = new Set(backend.allEndpoints(allExistingBackend).map((ep) => ep.codebase || projectConfig_1.DEFAULT_CODEBASE));
const deploymentPlan = {};
for (const codebase of codebases) {
const allCodebaseBackend = backend.matchingBackend(allExistingBackend, (ep) => (ep.codebase || projectConfig_1.DEFAULT_CODEBASE) === codebase);
const targetedCodebaseBackend = backend.matchingBackend(targetedRegionBackend, (ep) => (ep.codebase || projectConfig_1.DEFAULT_CODEBASE) === codebase);
const totalEndpointsInGcp = backend.allEndpoints(allCodebaseBackend);
const endpointsToDelete = backend
.allEndpoints(targetedCodebaseBackend)
.filter((e) => (0, functionsDeployHelper_1.endpointMatchesAnyFilter)(e, context.filters));
let existingManagedSA;
if (endpointsToDelete.length > 0 && endpointsToDelete.length === totalEndpointsInGcp.length) {
const ep = totalEndpointsInGcp.find((e) => typeof e.serviceAccount === "string" && e.serviceAccount.startsWith("firebase-fn-"));
existingManagedSA = ep?.serviceAccount;
}
deploymentPlan[codebase] = await planner.createDeploymentPlan({
wantBackend: backend.empty(),
haveBackend: targetedCodebaseBackend,
codebase,
projectId: context.projectId,
filters: context.filters,
deleteAll: true,
existingManagedSA,
});
}
const allEpToDelete = Object.values(deploymentPlan)
.flatMap((plan) => Object.values(plan.regionalChangesets).flatMap((changes) => changes.endpointsToDelete))
.sort(backend.compareFunctions);
if (allEpToDelete.length === 0) {
return 0;
}
const deleteList = allEpToDelete.map((func) => `\t${(0, functionsDeployHelper_1.getFunctionLabel)(func)}`).join("\n");
const saToDelete = Object.values(deploymentPlan)
.map((p) => p.serviceAccountToDelete)
.filter((sa) => !!sa);
let message = "You are about to delete the following Cloud Functions:\n" + deleteList;
if (saToDelete.length > 0) {
const saList = saToDelete.map((sa) => `\t${sa}`).join("\n");
message += "\n\nThe following managed service accounts will also be deleted:\n" + saList;
}
message += "\n Are you sure?";
const confirmDeletion = await prompt.confirm({
message,
default: false,
force: options?.force,
nonInteractive: options?.nonInteractive,
});
if (!confirmDeletion) {
throw new error_1.FirebaseError("Command aborted.");
}
const functionExecutor = new executor.QueueExecutor({
retries: 30,
backoff: 20000,
concurrency: 40,
maxBackoff: 40000,
});
try {
const firebaseConfig = await functionsConfig.getFirebaseConfig({
...options,
projectId: context.projectId,
});
const appEngineLocation = functionsConfig.getAppEngineLocation(firebaseConfig);
const fab = new fabricator.Fabricator({
functionExecutor,
runFunctionExecutor: functionExecutor,
appEngineLocation,
executor: new executor.QueueExecutor({}),
sources: {},
projectNumber: await (0, getProjectNumber_1.getProjectNumber)({ projectId: context.projectId }),
projectId: context.projectId,
});
const summary = await fab.applyPlan(deploymentPlan);
await reporter.logAndTrackDeployStats(summary);
reporter.printErrors(summary);
if (summary.results.some((r) => r.error)) {
throw new error_1.FirebaseError("At least one functions deletion operation failed.");
}
return allEpToDelete.length;
}
catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new error_1.FirebaseError(`Failed to delete functions: ${message}`, {
original: err instanceof Error ? err : undefined,
exit: 1,
});
}
}