firebase-tools 9.16.6 → 9.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +1 -3
  2. package/lib/api.js +1 -0
  3. package/lib/apiv2.js +1 -1
  4. package/lib/appdistribution/client.js +84 -72
  5. package/lib/appdistribution/distribution.js +8 -26
  6. package/lib/appdistribution/options-parser-util.js +51 -0
  7. package/lib/command.js +8 -6
  8. package/lib/commands/appdistribution-distribute.js +74 -91
  9. package/lib/commands/appdistribution-testers-add.js +18 -0
  10. package/lib/commands/appdistribution-testers-remove.js +32 -0
  11. package/lib/commands/crashlytics-symbols-upload.js +146 -0
  12. package/lib/commands/ext-configure.js +9 -1
  13. package/lib/commands/ext-dev-extension-delete.js +2 -1
  14. package/lib/commands/ext-dev-init.js +18 -9
  15. package/lib/commands/ext-dev-publish.js +11 -4
  16. package/lib/commands/ext-dev-unpublish.js +2 -1
  17. package/lib/commands/ext-install.js +115 -48
  18. package/lib/commands/ext-uninstall.js +6 -0
  19. package/lib/commands/ext-update.js +67 -43
  20. package/lib/commands/functions-config-export.js +115 -0
  21. package/lib/commands/functions-delete.js +44 -35
  22. package/lib/commands/functions-list.js +54 -0
  23. package/lib/commands/functions-log.js +5 -22
  24. package/lib/commands/hosting-channel-deploy.js +6 -4
  25. package/lib/commands/index.js +12 -0
  26. package/lib/deploy/functions/backend.js +47 -12
  27. package/lib/deploy/functions/containerCleaner.js +5 -1
  28. package/lib/deploy/functions/deploy.js +7 -5
  29. package/lib/deploy/functions/prepare.js +9 -7
  30. package/lib/deploy/functions/prompts.js +3 -21
  31. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +2 -1
  32. package/lib/deploy/functions/runtimes/index.js +2 -1
  33. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +4 -3
  34. package/lib/deploy/functions/runtimes/node/parseTriggers.js +14 -9
  35. package/lib/deploy/functions/triggerRegionHelper.js +32 -0
  36. package/lib/downloadUtils.js +37 -0
  37. package/lib/emulator/auth/apiSpec.js +1758 -404
  38. package/lib/emulator/auth/handlers.js +6 -5
  39. package/lib/emulator/auth/operations.js +429 -40
  40. package/lib/emulator/auth/server.js +18 -11
  41. package/lib/emulator/auth/state.js +186 -5
  42. package/lib/emulator/auth/widget_ui.js +2 -2
  43. package/lib/emulator/download.js +2 -31
  44. package/lib/emulator/downloadableEmulators.js +7 -7
  45. package/lib/emulator/emulatorLogger.js +0 -3
  46. package/lib/emulator/events/types.js +16 -0
  47. package/lib/emulator/functionsEmulator.js +102 -17
  48. package/lib/emulator/functionsEmulatorRuntime.js +46 -121
  49. package/lib/emulator/functionsEmulatorShared.js +51 -7
  50. package/lib/emulator/functionsEmulatorShell.js +1 -1
  51. package/lib/emulator/pubsubEmulator.js +61 -40
  52. package/lib/extensions/askUserForConsent.js +16 -13
  53. package/lib/extensions/askUserForParam.js +72 -3
  54. package/lib/extensions/billingMigrationHelper.js +1 -11
  55. package/lib/extensions/changelog.js +93 -0
  56. package/lib/extensions/displayExtensionInfo.js +38 -38
  57. package/lib/extensions/emulator/optionsHelper.js +3 -3
  58. package/lib/extensions/emulator/triggerHelper.js +2 -32
  59. package/lib/extensions/extensionsApi.js +69 -95
  60. package/lib/extensions/extensionsHelper.js +75 -50
  61. package/lib/extensions/paramHelper.js +79 -36
  62. package/lib/extensions/refs.js +59 -0
  63. package/lib/extensions/resolveSource.js +2 -20
  64. package/lib/extensions/secretsUtils.js +58 -0
  65. package/lib/extensions/updateHelper.js +39 -105
  66. package/lib/extensions/warnings.js +1 -7
  67. package/lib/functional.js +64 -0
  68. package/lib/functions/env.js +26 -13
  69. package/lib/functions/functionslog.js +40 -0
  70. package/lib/functions/listFunctions.js +10 -0
  71. package/lib/functions/runtimeConfigExport.js +137 -0
  72. package/lib/gcp/cloudfunctions.js +84 -9
  73. package/lib/gcp/cloudfunctionsv2.js +99 -7
  74. package/lib/gcp/cloudlogging.js +27 -21
  75. package/lib/gcp/secretManager.js +111 -0
  76. package/lib/gcp/storage.js +16 -0
  77. package/lib/previews.js +1 -1
  78. package/lib/requireInteractive.js +12 -0
  79. package/package.json +5 -4
  80. package/schema/firebase-config.json +2 -1
  81. package/templates/extensions/CHANGELOG.md +7 -0
  82. package/templates/init/hosting/index.html +10 -10
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkAvailability = exports.existingBackend = exports.scheduleIdForFunction = exports.topicName = exports.scheduleName = exports.sameFunctionName = exports.functionName = exports.isEmptyBackend = exports.empty = exports.SCHEDULED_FUNCTION_LABEL = exports.memoryOptionDisplayName = exports.triggerTag = exports.isEventTrigger = void 0;
3
+ exports.compareFunctions = exports.checkAvailability = exports.existingBackend = exports.scheduleIdForFunction = exports.topicName = exports.scheduleName = exports.sameFunctionName = exports.functionName = exports.isEmptyBackend = exports.empty = exports.isScheduleTriggered = exports.isEventTriggered = exports.isHttpsTriggered = exports.SCHEDULED_FUNCTION_LABEL = exports.memoryOptionDisplayName = exports.triggerTag = exports.isEventTrigger = void 0;
4
4
  const gcf = require("../../gcp/cloudfunctions");
5
5
  const gcfV2 = require("../../gcp/cloudfunctionsv2");
6
6
  const utils = require("../../utils");
@@ -46,9 +46,22 @@ function memoryOptionDisplayName(option) {
46
46
  }
47
47
  exports.memoryOptionDisplayName = memoryOptionDisplayName;
48
48
  exports.SCHEDULED_FUNCTION_LABEL = Object.freeze({ deployment: "firebase-schedule" });
49
+ function isHttpsTriggered(triggered) {
50
+ return {}.hasOwnProperty.call(triggered, "httpsTrigger");
51
+ }
52
+ exports.isHttpsTriggered = isHttpsTriggered;
53
+ function isEventTriggered(triggered) {
54
+ return {}.hasOwnProperty.call(triggered, "eventTrigger");
55
+ }
56
+ exports.isEventTriggered = isEventTriggered;
57
+ function isScheduleTriggered(triggered) {
58
+ return {}.hasOwnProperty.call(triggered, "scheduleTrigger");
59
+ }
60
+ exports.isScheduleTriggered = isScheduleTriggered;
49
61
  function empty() {
50
62
  return {
51
63
  requiredAPIs: {},
64
+ endpoints: [],
52
65
  cloudFunctions: [],
53
66
  schedules: [],
54
67
  topics: [],
@@ -91,15 +104,9 @@ async function existingBackend(context, forceRefresh) {
91
104
  }
92
105
  exports.existingBackend = existingBackend;
93
106
  async function loadExistingBackend(ctx) {
94
- var _a, _b, _c;
107
+ var _a, _b, _c, _d;
95
108
  ctx.loadedExistingBackend = true;
96
- ctx.existingBackend = {
97
- requiredAPIs: {},
98
- cloudFunctions: [],
99
- schedules: [],
100
- topics: [],
101
- environmentVariables: {},
102
- };
109
+ ctx.existingBackend = Object.assign({}, empty());
103
110
  ctx.unreachableRegions = {
104
111
  gcfV1: [],
105
112
  gcfV2: [],
@@ -137,12 +144,21 @@ async function loadExistingBackend(ctx) {
137
144
  if (!previews_1.previews.functionsv2) {
138
145
  return;
139
146
  }
140
- const gcfV2Results = await gcfV2.listAllFunctions(ctx.projectId);
147
+ let gcfV2Results;
148
+ try {
149
+ gcfV2Results = await gcfV2.listAllFunctions(ctx.projectId);
150
+ }
151
+ catch (err) {
152
+ if (err.status === 404 && ((_b = err.message) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes("method not found"))) {
153
+ return;
154
+ }
155
+ throw err;
156
+ }
141
157
  for (const apiFunction of gcfV2Results.functions) {
142
158
  const specFunction = gcfV2.specFromFunction(apiFunction);
143
159
  ctx.existingBackend.cloudFunctions.push(specFunction);
144
- const pubsubScheduled = ((_b = apiFunction.labels) === null || _b === void 0 ? void 0 : _b["deployment-scheduled"]) === "true";
145
- const httpsScheduled = ((_c = apiFunction.labels) === null || _c === void 0 ? void 0 : _c["deployment-scheduled"]) === "https";
160
+ const pubsubScheduled = ((_c = apiFunction.labels) === null || _c === void 0 ? void 0 : _c["deployment-scheduled"]) === "true";
161
+ const httpsScheduled = ((_d = apiFunction.labels) === null || _d === void 0 ? void 0 : _d["deployment-scheduled"]) === "https";
146
162
  if (pubsubScheduled) {
147
163
  const id = scheduleIdForFunction(specFunction);
148
164
  ctx.existingBackend.schedules.push({
@@ -221,3 +237,22 @@ async function checkAvailability(context, want) {
221
237
  }
222
238
  }
223
239
  exports.checkAvailability = checkAvailability;
240
+ function compareFunctions(left, right) {
241
+ if (left.platform != right.platform) {
242
+ return right.platform < left.platform ? -1 : 1;
243
+ }
244
+ if (left.region < right.region) {
245
+ return -1;
246
+ }
247
+ if (left.region > right.region) {
248
+ return 1;
249
+ }
250
+ if (left.id < right.id) {
251
+ return -1;
252
+ }
253
+ if (left.id > right.id) {
254
+ return 1;
255
+ }
256
+ return 0;
257
+ }
258
+ exports.compareFunctions = compareFunctions;
@@ -37,10 +37,14 @@ async function retry(func) {
37
37
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
38
38
  const MAX_RETRIES = 3;
39
39
  const INITIAL_BACKOFF = 100;
40
+ const TIMEOUT_MS = 10000;
40
41
  let retry = 0;
41
42
  while (true) {
42
43
  try {
43
- return await func();
44
+ const timeout = new Promise((resolve, reject) => {
45
+ setTimeout(() => reject(new Error("Timeout")), TIMEOUT_MS);
46
+ });
47
+ return await Promise.race([func(), timeout]);
44
48
  }
45
49
  catch (error) {
46
50
  logger_1.logger.debug("Failed docker command with error", error);
@@ -37,10 +37,10 @@ async function deploy(context, options, payload) {
37
37
  if (!options.config.src.functions) {
38
38
  return;
39
39
  }
40
- await checkIam_1.checkHttpIam(context, options, payload);
41
40
  if (!context.functionsSourceV1 && !context.functionsSourceV2) {
42
41
  return;
43
42
  }
43
+ await checkIam_1.checkHttpIam(context, options, payload);
44
44
  try {
45
45
  const want = payload.functions.backend;
46
46
  const uploads = [];
@@ -61,10 +61,12 @@ async function deploy(context, options, payload) {
61
61
  }
62
62
  await Promise.all(uploads);
63
63
  utils.assertDefined(options.config.src.functions.source, "Error: 'functions.source' is not defined");
64
- utils_1.logSuccess(clc.green.bold("functions:") +
65
- " " +
66
- clc.bold(options.config.src.functions.source) +
67
- " folder uploaded successfully");
64
+ if (uploads.length) {
65
+ utils_1.logSuccess(clc.green.bold("functions:") +
66
+ " " +
67
+ clc.bold(options.config.src.functions.source) +
68
+ " folder uploaded successfully");
69
+ }
68
70
  }
69
71
  catch (err) {
70
72
  utils_1.logWarning(clc.yellow("functions:") + " Upload Error: " + err.message);
@@ -18,6 +18,7 @@ const runtimes = require("./runtimes");
18
18
  const validate = require("./validate");
19
19
  const utils = require("../../utils");
20
20
  const logger_1 = require("../../logger");
21
+ const triggerRegionHelper_1 = require("./triggerRegionHelper");
21
22
  function hasUserConfig(config) {
22
23
  return Object.keys(config).length > 1;
23
24
  }
@@ -64,25 +65,25 @@ async function prepare(context, options, payload) {
64
65
  const wantBackend = await runtimeDelegate.discoverSpec(runtimeConfig, firebaseEnvs);
65
66
  wantBackend.environmentVariables = Object.assign(Object.assign({}, userEnvs), firebaseEnvs);
66
67
  payload.functions = { backend: wantBackend };
67
- if (backend.isEmptyBackend(wantBackend)) {
68
- return;
69
- }
70
68
  if (wantBackend.cloudFunctions.find((f) => f.platform === "gcfv2")) {
71
69
  const V2_APIS = {
72
70
  artifactregistry: "artifactregistry.googleapis.com",
73
71
  cloudrun: "run.googleapis.com",
74
72
  eventarc: "eventarc.googleapis.com",
75
73
  pubsub: "pubsub.googleapis.com",
74
+ storage: "storage.googleapis.com",
76
75
  };
77
76
  const enablements = Object.entries(V2_APIS).map(([tag, api]) => {
78
77
  return ensureApiEnabled.ensure(context.projectId, api, tag);
79
78
  });
80
79
  await Promise.all(enablements);
81
80
  }
82
- utils_1.logBullet(clc.cyan.bold("functions:") +
83
- " preparing " +
84
- clc.bold(options.config.src.functions.source) +
85
- " directory for uploading...");
81
+ if (wantBackend.cloudFunctions.length) {
82
+ utils_1.logBullet(clc.cyan.bold("functions:") +
83
+ " preparing " +
84
+ clc.bold(options.config.src.functions.source) +
85
+ " directory for uploading...");
86
+ }
86
87
  if (wantBackend.cloudFunctions.find((fn) => fn.platform === "gcfv1")) {
87
88
  context.functionsSourceV1 = await prepareFunctionsUpload_1.prepareFunctionsUpload(runtimeConfig, options);
88
89
  }
@@ -101,6 +102,7 @@ async function prepare(context, options, payload) {
101
102
  return functionsDeployHelper_1.functionMatchesAnyGroup(fn, context.filters);
102
103
  });
103
104
  const haveFunctions = (await backend.existingBackend(context)).cloudFunctions;
105
+ await triggerRegionHelper_1.setTriggerRegion(wantFunctions, haveFunctions);
104
106
  await prompts_1.promptForFailurePolicies(options, wantFunctions, haveFunctions);
105
107
  await prompts_1.promptForMinInstances(options, wantFunctions, haveFunctions);
106
108
  await backend.checkAvailability(context, wantBackend);
@@ -9,24 +9,6 @@ const logger_1 = require("../../logger");
9
9
  const backend = require("./backend");
10
10
  const pricing = require("./pricing");
11
11
  const utils = require("../../utils");
12
- function compareFunctions(left, right) {
13
- if (left.platform != right.platform) {
14
- return right.platform < left.platform ? -1 : 1;
15
- }
16
- if (left.region < right.region) {
17
- return -1;
18
- }
19
- if (left.region > right.region) {
20
- return 1;
21
- }
22
- if (left.id < right.id) {
23
- return -1;
24
- }
25
- if (left.id > right.id) {
26
- return 1;
27
- }
28
- return 0;
29
- }
30
12
  async function promptForFailurePolicies(options, want, have) {
31
13
  const retryFunctions = want.filter((fn) => {
32
14
  return backend.isEventTrigger(fn.trigger) && fn.trigger.retry;
@@ -44,7 +26,7 @@ async function promptForFailurePolicies(options, want, have) {
44
26
  return;
45
27
  }
46
28
  const warnMessage = "The following functions will newly be retried in case of failure: " +
47
- clc.bold(newRetryFunctions.sort(compareFunctions).map(functionsDeployHelper_1.getFunctionLabel).join(", ")) +
29
+ clc.bold(newRetryFunctions.sort(backend.compareFunctions).map(functionsDeployHelper_1.getFunctionLabel).join(", ")) +
48
30
  ". " +
49
31
  "Retried executions are billed as any other execution, and functions are retried repeatedly until they either successfully execute or the maximum retry period has elapsed, which can be up to 7 days. " +
50
32
  "For safety, you might want to ensure that your functions are idempotent; see https://firebase.google.com/docs/functions/retries to learn more.";
@@ -74,7 +56,7 @@ async function promptForFunctionDeletion(functionsToDelete, force, nonInteractiv
74
56
  return true;
75
57
  }
76
58
  const deleteList = functionsToDelete
77
- .sort(compareFunctions)
59
+ .sort(backend.compareFunctions)
78
60
  .map((fn) => "\t" + functionsDeployHelper_1.getFunctionLabel(fn))
79
61
  .join("\n");
80
62
  if (nonInteractive) {
@@ -136,7 +118,7 @@ async function promptForMinInstances(options, want, have) {
136
118
  }
137
119
  const functionLines = want
138
120
  .filter((fn) => fn.minInstances)
139
- .sort(compareFunctions)
121
+ .sort(backend.compareFunctions)
140
122
  .map((fn) => {
141
123
  return (`\t${functionsDeployHelper_1.getFunctionLabel(fn)}: ${fn.minInstances} instances, ` +
142
124
  backend.memoryOptionDisplayName(fn.availableMemoryMb || 256) +
@@ -15,6 +15,7 @@ function tryValidate(typed) {
15
15
  var _a, _b;
16
16
  parsing_1.assertKeyTypes("", typed, {
17
17
  requiredAPIs: "object",
18
+ endpoints: "array",
18
19
  cloudFunctions: "array",
19
20
  topics: "array",
20
21
  schedules: "array",
@@ -59,7 +60,6 @@ function tryValidate(typed) {
59
60
  }
60
61
  else {
61
62
  parsing_1.assertKeyTypes(prefix + ".trigger", func.trigger, {
62
- allowInsecure: "boolean",
63
63
  invoker: "array",
64
64
  });
65
65
  }
@@ -115,6 +115,7 @@ function fillDefaults(want, project, region, runtime) {
115
115
  want.environmentVariables = want.environmentVariables || {};
116
116
  want.schedules = want.schedules || [];
117
117
  want.topics = want.topics || [];
118
+ want.endpoints = want.endpoints || [];
118
119
  for (const cloudFunction of want.cloudFunctions) {
119
120
  if (!cloudFunction.project) {
120
121
  cloudFunction.project = project;
@@ -5,7 +5,7 @@ const golang = require("./golang");
5
5
  const node = require("./node");
6
6
  const validate = require("../validate");
7
7
  const error_1 = require("../../../error");
8
- const RUNTIMES = ["nodejs10", "nodejs12", "nodejs14"];
8
+ const RUNTIMES = ["nodejs10", "nodejs12", "nodejs14", "nodejs16"];
9
9
  const EXPERIMENTAL_RUNTIMES = ["go113"];
10
10
  const DEPRECATED_RUNTIMES = ["nodejs6", "nodejs8"];
11
11
  function isDeprecatedRuntime(runtime) {
@@ -22,6 +22,7 @@ const MESSAGE_FRIENDLY_RUNTIMES = {
22
22
  nodejs10: "Node.js 10",
23
23
  nodejs12: "Node.js 12",
24
24
  nodejs14: "Node.js 14",
25
+ nodejs16: "Node.js 16",
25
26
  go113: "Go 1.13",
26
27
  };
27
28
  function getHumanFriendlyRuntimeName(runtime) {
@@ -13,17 +13,18 @@ const ENGINE_RUNTIMES = {
13
13
  10: "nodejs10",
14
14
  12: "nodejs12",
15
15
  14: "nodejs14",
16
+ 16: "nodejs16",
16
17
  };
17
18
  const ENGINE_RUNTIMES_NAMES = Object.values(ENGINE_RUNTIMES);
18
19
  exports.RUNTIME_NOT_SET = "`runtime` field is required but was not found in firebase.json.\n" +
19
20
  "To fix this, add the following lines to the `functions` section of your firebase.json:\n" +
20
21
  '"runtime": "nodejs14"\n';
21
22
  exports.UNSUPPORTED_NODE_VERSION_FIREBASE_JSON_MSG = clc.bold(`functions.runtime value is unsupported. ` +
22
- `Valid choices are: ${clc.bold("nodejs10")}, ${clc.bold("nodejs12")}, and ${clc.bold("nodejs14")}.`);
23
+ `Valid choices are: ${clc.bold("nodejs{10|12|14|16}")}.`);
23
24
  exports.UNSUPPORTED_NODE_VERSION_PACKAGE_JSON_MSG = clc.bold(`package.json in functions directory has an engines field which is unsupported. ` +
24
- `Valid choices are: ${clc.bold('{"node": "10"}')}, ${clc.bold('{"node":"12"}')}, and ${clc.bold('{"node":"14"}')}.`);
25
+ `Valid choices are: ${clc.bold('{"node": 10|12|14|16}')}`);
25
26
  exports.DEPRECATED_NODE_VERSION_INFO = `\n\nDeploys to runtimes below Node.js 10 are now disabled in the Firebase CLI. ` +
26
- `${clc.bold(`Existing Node.js 8 functions ${clc.underline("will stop executing on 2021-03-15")}`)}. Update existing functions to Node.js 10 or greater as soon as possible.`;
27
+ `${clc.bold(`Existing Node.js 8 functions ${clc.underline("will stop executing at a future date")}`)}. Update existing functions to Node.js 10 or greater as soon as possible.`;
27
28
  function getRuntimeChoiceFromPackageJson(sourceDir) {
28
29
  const packageJsonPath = path.join(sourceDir, "package.json");
29
30
  let loaded;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addResourcesToBackend = exports.discoverBackend = exports.useStrategy = void 0;
3
+ exports.addResourcesToBackend = exports.discoverBackend = exports.useStrategy = exports.GCS_EVENTS = void 0;
4
4
  const path = require("path");
5
5
  const _ = require("lodash");
6
6
  const child_process_1 = require("child_process");
@@ -10,6 +10,12 @@ const backend = require("../../backend");
10
10
  const api = require("../../../../api");
11
11
  const proto = require("../../../../gcp/proto");
12
12
  const TRIGGER_PARSER = path.resolve(__dirname, "./triggerParser.js");
13
+ exports.GCS_EVENTS = new Set([
14
+ "google.cloud.storage.object.v1.finalized",
15
+ "google.cloud.storage.object.v1.archived",
16
+ "google.cloud.storage.object.v1.deleted",
17
+ "google.cloud.storage.object.v1.metadataUpdated",
18
+ ]);
13
19
  function removeInspectOptions(options) {
14
20
  return options.filter((opt) => !opt.startsWith("--inspect"));
15
21
  }
@@ -58,6 +64,7 @@ async function discoverBackend(projectId, sourceDir, runtime, configValues, envs
58
64
  }
59
65
  exports.discoverBackend = discoverBackend;
60
66
  function addResourcesToBackend(projectId, runtime, annotation, want) {
67
+ var _a;
61
68
  Object.freeze(annotation);
62
69
  for (const region of annotation.regions || [api.functionsDefaultRegion]) {
63
70
  let trigger;
@@ -65,14 +72,7 @@ function addResourcesToBackend(projectId, runtime, annotation, want) {
65
72
  throw new error_1.FirebaseError("Unexpected annotation generated by the Firebase Functions SDK. This should never happen.");
66
73
  }
67
74
  if (annotation.httpsTrigger) {
68
- let allowInsecure;
69
- if ("allowInsecure" in annotation.httpsTrigger) {
70
- allowInsecure = !!annotation.httpsTrigger.allowInsecure;
71
- }
72
- else {
73
- allowInsecure = !annotation.platform || annotation.platform === "gcfv1";
74
- }
75
- trigger = { allowInsecure };
75
+ trigger = {};
76
76
  if (annotation.failurePolicy) {
77
77
  logger_1.logger.warn(`Ignoring retry policy for HTTPS function ${annotation.name}`);
78
78
  }
@@ -86,6 +86,11 @@ function addResourcesToBackend(projectId, runtime, annotation, want) {
86
86
  },
87
87
  retry: !!annotation.failurePolicy,
88
88
  };
89
+ if (exports.GCS_EVENTS.has(((_a = annotation.eventTrigger) === null || _a === void 0 ? void 0 : _a.eventType) || "")) {
90
+ trigger.eventFilters = {
91
+ bucket: annotation.eventTrigger.resource,
92
+ };
93
+ }
89
94
  }
90
95
  const cloudFunctionName = {
91
96
  id: annotation.name,
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setTriggerRegion = void 0;
4
+ const backend = require("./backend");
5
+ const storage = require("../../gcp/storage");
6
+ const error_1 = require("../../error");
7
+ async function setTriggerRegion(want, have) {
8
+ var _a;
9
+ for (const wantFn of want) {
10
+ if (wantFn.platform === "gcfv1" || !backend.isEventTrigger(wantFn.trigger)) {
11
+ continue;
12
+ }
13
+ const match = (_a = have.find(backend.sameFunctionName(wantFn))) === null || _a === void 0 ? void 0 : _a.trigger;
14
+ if (match === null || match === void 0 ? void 0 : match.region) {
15
+ wantFn.trigger.region = match.region;
16
+ }
17
+ else {
18
+ await setTriggerRegionFromTriggerType(wantFn.trigger);
19
+ }
20
+ }
21
+ }
22
+ exports.setTriggerRegion = setTriggerRegion;
23
+ async function setTriggerRegionFromTriggerType(trigger) {
24
+ if (trigger.eventFilters.bucket) {
25
+ try {
26
+ trigger.region = (await storage.getBucket(trigger.eventFilters.bucket)).location.toLowerCase();
27
+ }
28
+ catch (err) {
29
+ throw new error_1.FirebaseError("Can't find the storage bucket region", { original: err });
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.downloadToTmp = void 0;
4
+ const url_1 = require("url");
5
+ const fs = require("fs-extra");
6
+ const ProgressBar = require("progress");
7
+ const tmp = require("tmp");
8
+ const apiv2_1 = require("./apiv2");
9
+ const error_1 = require("./error");
10
+ async function downloadToTmp(remoteUrl) {
11
+ const u = new url_1.URL(remoteUrl);
12
+ const c = new apiv2_1.Client({ urlPrefix: u.origin, auth: false });
13
+ const tmpfile = tmp.fileSync();
14
+ const writeStream = fs.createWriteStream(tmpfile.name);
15
+ const res = await c.request({
16
+ method: "GET",
17
+ path: u.pathname,
18
+ queryParams: u.searchParams,
19
+ responseType: "stream",
20
+ resolveOnHTTPError: true,
21
+ });
22
+ if (res.status !== 200) {
23
+ throw new error_1.FirebaseError(`download failed, status ${res.status}`, { exit: 1 });
24
+ }
25
+ const total = parseInt(res.response.headers.get("content-length") || "0", 10);
26
+ const totalMb = Math.ceil(total / 1000000);
27
+ const bar = new ProgressBar(`Progress: :bar (:percent of ${totalMb}MB)`, { total, head: ">" });
28
+ res.body.on("data", (chunk) => {
29
+ bar.tick(chunk.length);
30
+ });
31
+ await new Promise((resolve) => {
32
+ writeStream.on("finish", resolve);
33
+ res.body.pipe(writeStream);
34
+ });
35
+ return tmpfile.name;
36
+ }
37
+ exports.downloadToTmp = downloadToTmp;