firebase-tools 10.2.1 → 10.2.2

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 (105) hide show
  1. package/lib/appdistribution/options-parser-util.js +1 -1
  2. package/lib/auth.js +3 -3
  3. package/lib/command.js +1 -1
  4. package/lib/commands/apps-android-sha-create.js +2 -2
  5. package/lib/commands/apps-sdkconfig.js +1 -1
  6. package/lib/commands/database-rules-list.js +2 -2
  7. package/lib/commands/emulators-start.js +1 -1
  8. package/lib/commands/ext-dev-init.js +49 -49
  9. package/lib/commands/ext-export.js +12 -2
  10. package/lib/commands/ext-install.js +104 -104
  11. package/lib/commands/ext-uninstall.js +8 -8
  12. package/lib/commands/ext-update.js +9 -9
  13. package/lib/commands/functions-config-export.js +1 -1
  14. package/lib/commands/hosting-clone.js +3 -3
  15. package/lib/commands/remoteconfig-get.js +1 -1
  16. package/lib/deploy/extensions/deploymentSummary.js +3 -3
  17. package/lib/deploy/extensions/params.js +3 -0
  18. package/lib/deploy/extensions/planner.js +2 -1
  19. package/lib/deploy/extensions/tasks.js +1 -1
  20. package/lib/deploy/functions/backend.js +12 -5
  21. package/lib/deploy/functions/checkIam.js +1 -1
  22. package/lib/deploy/functions/containerCleaner.js +3 -3
  23. package/lib/deploy/functions/ensure.js +3 -3
  24. package/lib/deploy/functions/functionsDeployHelper.js +2 -2
  25. package/lib/deploy/functions/prepare.js +3 -2
  26. package/lib/deploy/functions/pricing.js +1 -1
  27. package/lib/deploy/functions/prompts.js +2 -2
  28. package/lib/deploy/functions/release/fabricator.js +3 -3
  29. package/lib/deploy/functions/release/index.js +1 -1
  30. package/lib/deploy/functions/release/planner.js +11 -8
  31. package/lib/deploy/functions/release/reporter.js +3 -0
  32. package/lib/deploy/functions/runtimes/discovery/index.js +6 -6
  33. package/lib/deploy/functions/runtimes/discovery/parsing.js +1 -1
  34. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +16 -11
  35. package/lib/deploy/functions/runtimes/golang/index.js +2 -2
  36. package/lib/deploy/functions/runtimes/node/index.js +26 -0
  37. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +2 -2
  38. package/lib/deploy/functions/runtimes/node/parseTriggers.js +28 -7
  39. package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
  40. package/lib/deploy/functions/validate.js +3 -3
  41. package/lib/deploy/hosting/deploy.js +2 -2
  42. package/lib/deploy/hosting/hashcache.js +21 -19
  43. package/lib/deploy/hosting/uploader.js +5 -5
  44. package/lib/deploy/remoteconfig/functions.js +2 -2
  45. package/lib/emulator/auth/cloudFunctions.js +1 -1
  46. package/lib/emulator/auth/operations.js +1 -1
  47. package/lib/emulator/constants.js +3 -0
  48. package/lib/emulator/controller.js +47 -19
  49. package/lib/emulator/download.js +18 -1
  50. package/lib/emulator/downloadableEmulators.js +1 -1
  51. package/lib/emulator/emulatorLogger.js +12 -1
  52. package/lib/emulator/extensions/validation.js +35 -0
  53. package/lib/emulator/extensionsEmulator.js +140 -0
  54. package/lib/emulator/functionsEmulator.js +86 -39
  55. package/lib/emulator/functionsEmulatorRuntime.js +44 -36
  56. package/lib/emulator/functionsEmulatorShell.js +1 -1
  57. package/lib/emulator/functionsEmulatorUtils.js +4 -4
  58. package/lib/emulator/functionsRuntimeWorker.js +2 -2
  59. package/lib/emulator/hub.js +4 -3
  60. package/lib/emulator/loggingEmulator.js +1 -1
  61. package/lib/emulator/pubsubEmulator.js +1 -1
  62. package/lib/emulator/registry.js +10 -2
  63. package/lib/emulator/storage/apis/firebase.js +31 -26
  64. package/lib/emulator/storage/apis/gcloud.js +7 -12
  65. package/lib/emulator/storage/files.js +36 -34
  66. package/lib/emulator/storage/index.js +2 -2
  67. package/lib/emulator/storage/metadata.js +2 -2
  68. package/lib/emulator/storage/rules/runtime.js +8 -7
  69. package/lib/emulator/types.js +3 -0
  70. package/lib/ensureApiEnabled.js +5 -1
  71. package/lib/error.js +1 -1
  72. package/lib/extensions/askUserForParam.js +1 -1
  73. package/lib/extensions/changelog.js +3 -1
  74. package/lib/extensions/checkProjectBilling.js +1 -1
  75. package/lib/extensions/displayExtensionInfo.js +1 -1
  76. package/lib/extensions/emulator/optionsHelper.js +24 -8
  77. package/lib/extensions/emulator/specHelper.js +10 -23
  78. package/lib/extensions/export.js +1 -51
  79. package/lib/extensions/extensionsApi.js +1 -1
  80. package/lib/extensions/extensionsHelper.js +13 -9
  81. package/lib/extensions/manifest.js +48 -0
  82. package/lib/extensions/metricsUtils.js +4 -4
  83. package/lib/extensions/paramHelper.js +4 -4
  84. package/lib/extensions/refs.js +1 -1
  85. package/lib/extensions/secretsUtils.js +3 -3
  86. package/lib/functional.js +1 -1
  87. package/lib/functions/env.js +2 -1
  88. package/lib/gcp/cloudfunctions.js +24 -5
  89. package/lib/gcp/cloudfunctionsv2.js +18 -5
  90. package/lib/gcp/cloudtasks.js +1 -1
  91. package/lib/gcp/docker.js +2 -2
  92. package/lib/gcp/run.js +2 -2
  93. package/lib/hosting/api.js +1 -1
  94. package/lib/hosting/proxy.js +2 -2
  95. package/lib/init/features/account.js +1 -1
  96. package/lib/management/database.js +1 -1
  97. package/lib/previews.js +1 -1
  98. package/lib/utils.js +1 -1
  99. package/npm-shrinkwrap.json +786 -393
  100. package/package.json +1 -1
  101. package/schema/firebase-config.json +5 -0
  102. package/templates/init/functions/javascript/package.lint.json +3 -3
  103. package/templates/init/functions/javascript/package.nolint.json +2 -2
  104. package/templates/init/functions/typescript/package.lint.json +7 -7
  105. package/templates/init/functions/typescript/package.nolint.json +3 -3
@@ -2,13 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getNodeVersion = exports.getFunctionProperties = exports.getFunctionResourcesWithParamSubstitution = exports.readFileFromDirectory = exports.readExtensionYaml = void 0;
4
4
  const yaml = require("js-yaml");
5
- const _ = require("lodash");
6
5
  const path = require("path");
7
6
  const fs = require("fs-extra");
8
7
  const error_1 = require("../../error");
9
8
  const extensionsHelper_1 = require("../extensionsHelper");
10
- const emulatorLogger_1 = require("../../emulator/emulatorLogger");
11
- const types_1 = require("../../emulator/types");
9
+ const functionsEmulatorUtils_1 = require("../../emulator/functionsEmulatorUtils");
12
10
  const SPEC_FILE = "extension.yaml";
13
11
  const validFunctionTypes = [
14
12
  "firebaseextensions.v1beta.function",
@@ -62,35 +60,24 @@ function getFunctionProperties(resources) {
62
60
  }
63
61
  exports.getFunctionProperties = getFunctionProperties;
64
62
  function getNodeVersion(resources) {
65
- const functionNamesWithoutRuntime = [];
63
+ const invalidRuntimes = [];
66
64
  const versions = resources.map((r) => {
67
65
  var _a, _b;
68
- if (_.includes(r.type, "function")) {
69
- if ((_a = r.properties) === null || _a === void 0 ? void 0 : _a.runtime) {
70
- return (_b = r.properties) === null || _b === void 0 ? void 0 : _b.runtime;
66
+ if ((_a = r.properties) === null || _a === void 0 ? void 0 : _a.runtime) {
67
+ const runtimeName = (_b = r.properties) === null || _b === void 0 ? void 0 : _b.runtime;
68
+ const runtime = (0, functionsEmulatorUtils_1.parseRuntimeVersion)(runtimeName);
69
+ if (!runtime) {
70
+ invalidRuntimes.push(runtimeName);
71
71
  }
72
72
  else {
73
- functionNamesWithoutRuntime.push(r.name);
73
+ return runtime;
74
74
  }
75
75
  }
76
- return "nodejs8";
77
- });
78
- if (functionNamesWithoutRuntime.length) {
79
- emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS).logLabeled("WARN", "extensions", `No 'runtime' property found for the following functions, defaulting to nodejs8: ${functionNamesWithoutRuntime.join(", ")}`);
80
- }
81
- const invalidRuntimes = _.filter(versions, (v) => {
82
- return !_.includes(v, "nodejs");
76
+ return 14;
83
77
  });
84
78
  if (invalidRuntimes.length) {
85
79
  throw new error_1.FirebaseError(`The following runtimes are not supported by the Emulator Suite: ${invalidRuntimes.join(", ")}. \n Only Node runtimes are supported.`);
86
80
  }
87
- if (_.includes(versions, "nodejs10")) {
88
- return "10";
89
- }
90
- if (_.includes(versions, "nodejs6")) {
91
- emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS).logLabeled("WARN", "extensions", "Node 6 is deprecated. We recommend upgrading to a newer version.");
92
- return "6";
93
- }
94
- return "8";
81
+ return Math.max(...versions);
95
82
  }
96
83
  exports.getNodeVersion = getNodeVersion;
@@ -1,14 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeFiles = exports.displayExportInfo = exports.setSecretParamsToLatest = exports.parameterizeProject = void 0;
4
- const clc = require("cli-color");
5
- const refs = require("./refs");
6
- const config_1 = require("../config");
3
+ exports.displayExportInfo = exports.setSecretParamsToLatest = exports.parameterizeProject = void 0;
7
4
  const planner_1 = require("../deploy/extensions/planner");
8
5
  const deploymentSummary_1 = require("../deploy/extensions/deploymentSummary");
9
6
  const logger_1 = require("../logger");
10
- const error_1 = require("../error");
11
- const prompt_1 = require("../prompt");
12
7
  const secretManager_1 = require("../gcp/secretManager");
13
8
  const secretsUtils_1 = require("./secretsUtils");
14
9
  function parameterizeProject(projectId, projectNumber, spec) {
@@ -60,48 +55,3 @@ function displaySpecs(specs) {
60
55
  logger_1.logger.info("");
61
56
  }
62
57
  }
63
- function writeExtensionsToFirebaseJson(have, existingConfig) {
64
- const extensions = existingConfig.get("extensions", {});
65
- for (const s of have) {
66
- extensions[s.instanceId] = refs.toExtensionVersionRef(s.ref);
67
- }
68
- existingConfig.set("extensions", extensions);
69
- logger_1.logger.info("Adding Extensions to " + clc.bold("firebase.json") + "...");
70
- existingConfig.writeProjectFile("firebase.json", existingConfig.src);
71
- }
72
- async function writeEnvFile(spec, existingConfig, force) {
73
- const content = Object.entries(spec.params)
74
- .map((r) => `${r[0]}=${r[1]}`)
75
- .join("\n");
76
- await existingConfig.askWriteProjectFile(`extensions/${spec.instanceId}.env`, content, force);
77
- }
78
- async function writeFiles(have, options) {
79
- const existingConfig = config_1.Config.load(options, true);
80
- if (!existingConfig) {
81
- throw new error_1.FirebaseError("Not currently in a Firebase directory. Please run `firebase init` to create a Firebase directory.");
82
- }
83
- if (existingConfig.has("extensions") &&
84
- Object.keys(existingConfig.get("extensions")).length &&
85
- !options.nonInteractive &&
86
- !options.force) {
87
- const currentExtensions = Object.entries(existingConfig.get("extensions"))
88
- .map((i) => `${i[0]}: ${i[1]}`)
89
- .join("\n\t");
90
- const overwrite = await (0, prompt_1.promptOnce)({
91
- type: "list",
92
- message: `firebase.json already contains extensions:\n${currentExtensions}\nWould you like to overwrite or merge?`,
93
- choices: [
94
- { name: "Overwrite", value: true },
95
- { name: "Merge", value: false },
96
- ],
97
- });
98
- if (overwrite) {
99
- existingConfig.set("extensions", {});
100
- }
101
- }
102
- writeExtensionsToFirebaseJson(have, existingConfig);
103
- for (const spec of have) {
104
- await writeEnvFile(spec, existingConfig, options.force);
105
- }
106
- }
107
- exports.writeFiles = writeFiles;
@@ -295,7 +295,7 @@ async function listExtensionVersions(ref, filter = "") {
295
295
  exports.listExtensionVersions = listExtensionVersions;
296
296
  async function getPublisherProfile(projectId, publisherId) {
297
297
  const res = await apiClient.get(`/projects/${projectId}/publisherProfile`, {
298
- queryParams: publisherId == undefined
298
+ queryParams: publisherId === undefined
299
299
  ? undefined
300
300
  : {
301
301
  publisherId,
@@ -112,7 +112,7 @@ function populateDefaultParams(paramVars, paramSpecs) {
112
112
  const newParams = paramVars;
113
113
  for (const param of paramSpecs) {
114
114
  if (!paramVars[param.param]) {
115
- if (param.default != undefined && param.required) {
115
+ if (param.default !== undefined && param.required) {
116
116
  newParams[param.param] = param.default;
117
117
  }
118
118
  else if (param.required) {
@@ -197,13 +197,13 @@ function validateSpec(spec) {
197
197
  if (param.type && !_.includes(SpecParamType, param.type)) {
198
198
  errors.push(`Invalid type ${param.type} for param${param.param ? ` ${param.param}` : ""}. Valid types are ${_.values(SpecParamType).join(", ")}`);
199
199
  }
200
- if (!param.type || param.type == SpecParamType.STRING) {
200
+ if (!param.type || param.type === SpecParamType.STRING) {
201
201
  if (param.options) {
202
202
  errors.push(`Param${param.param ? ` ${param.param}` : ""} cannot have options because it is type STRING`);
203
203
  }
204
204
  }
205
205
  if (param.type &&
206
- (param.type == SpecParamType.SELECT || param.type == SpecParamType.MULTISELECT)) {
206
+ (param.type === SpecParamType.SELECT || param.type === SpecParamType.MULTISELECT)) {
207
207
  if (param.validationRegex) {
208
208
  errors.push(`Param${param.param ? ` ${param.param}` : ""} cannot have validationRegex because it is type ${param.type}`);
209
209
  }
@@ -211,12 +211,12 @@ function validateSpec(spec) {
211
211
  errors.push(`Param${param.param ? ` ${param.param}` : ""} requires options because it is type ${param.type}`);
212
212
  }
213
213
  for (const opt of param.options || []) {
214
- if (opt.value == undefined) {
214
+ if (opt.value === undefined) {
215
215
  errors.push(`Option for param${param.param ? ` ${param.param}` : ""} is missing required field: value`);
216
216
  }
217
217
  }
218
218
  }
219
- if (param.type && param.type == SpecParamType.SELECTRESOURCE) {
219
+ if (param.type && param.type === SpecParamType.SELECTRESOURCE) {
220
220
  if (!param.resourceType) {
221
221
  errors.push(`Param${param.param ? ` ${param.param}` : ""} must have resourceType because it is type ${param.type}`);
222
222
  }
@@ -268,7 +268,7 @@ async function archiveAndUploadSource(extPath, bucketName) {
268
268
  }
269
269
  async function publishExtensionVersionFromLocalSource(args) {
270
270
  const extensionSpec = await (0, localHelper_1.getLocalExtensionSpec)(args.rootDirectory);
271
- if (extensionSpec.name != args.extensionId) {
271
+ if (extensionSpec.name !== args.extensionId) {
272
272
  throw new error_1.FirebaseError(`Extension ID '${clc.bold(args.extensionId)}' does not match the name in extension.yaml '${clc.bold(extensionSpec.name)}'.`);
273
273
  }
274
274
  const subbedSpec = JSON.parse(JSON.stringify(extensionSpec));
@@ -325,7 +325,9 @@ async function publishExtensionVersionFromLocalSource(args) {
325
325
  }
326
326
  catch (err) {
327
327
  uploadSpinner.fail();
328
- throw err;
328
+ throw new error_1.FirebaseError(`Failed to archive and upload extension source, ${err}`, {
329
+ original: err,
330
+ });
329
331
  }
330
332
  const publishSpinner = ora(`Publishing ${clc.bold(ref)}`);
331
333
  let res;
@@ -336,7 +338,7 @@ async function publishExtensionVersionFromLocalSource(args) {
336
338
  }
337
339
  catch (err) {
338
340
  publishSpinner.fail();
339
- if (err.status == 404) {
341
+ if (err.status === 404) {
340
342
  throw new error_1.FirebaseError(marked(`Couldn't find publisher ID '${clc.bold(args.publisherId)}'. Please ensure that you have registered this ID. To register as a publisher, you can check out the [Firebase documentation](https://firebase.google.com/docs/extensions/alpha/share#register_as_an_extensions_publisher) for step-by-step instructions.`));
341
343
  }
342
344
  throw err;
@@ -360,7 +362,9 @@ async function createSourceFromLocation(projectId, sourceUri) {
360
362
  }
361
363
  catch (err) {
362
364
  uploadSpinner.fail();
363
- throw err;
365
+ throw new error_1.FirebaseError(`Failed to archive and upload extension source, ${err}`, {
366
+ original: err,
367
+ });
364
368
  }
365
369
  }
366
370
  else {
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeToManifest = void 0;
4
+ const clc = require("cli-color");
5
+ const refs = require("./refs");
6
+ const logger_1 = require("../logger");
7
+ const prompt_1 = require("../prompt");
8
+ async function writeToManifest(specs, config, options) {
9
+ if (config.has("extensions") &&
10
+ Object.keys(config.get("extensions")).length &&
11
+ !options.nonInteractive &&
12
+ !options.force) {
13
+ const currentExtensions = Object.entries(config.get("extensions"))
14
+ .map((i) => `${i[0]}: ${i[1]}`)
15
+ .join("\n\t");
16
+ const overwrite = await (0, prompt_1.promptOnce)({
17
+ type: "list",
18
+ message: `firebase.json already contains extensions:\n${currentExtensions}\nWould you like to overwrite or merge?`,
19
+ choices: [
20
+ { name: "Overwrite", value: true },
21
+ { name: "Merge", value: false },
22
+ ],
23
+ });
24
+ if (overwrite) {
25
+ config.set("extensions", {});
26
+ }
27
+ }
28
+ writeExtensionsToFirebaseJson(specs, config);
29
+ await writeEnvFiles(specs, config, options.force);
30
+ }
31
+ exports.writeToManifest = writeToManifest;
32
+ function writeExtensionsToFirebaseJson(specs, config) {
33
+ const extensions = config.get("extensions", {});
34
+ for (const s of specs) {
35
+ extensions[s.instanceId] = refs.toExtensionVersionRef(s.ref);
36
+ }
37
+ config.set("extensions", extensions);
38
+ logger_1.logger.info("Adding Extensions to " + clc.bold("firebase.json") + "...");
39
+ config.writeProjectFile("firebase.json", config.src);
40
+ }
41
+ async function writeEnvFiles(specs, config, force) {
42
+ for (const spec of specs) {
43
+ const content = Object.entries(spec.params)
44
+ .map((r) => `${r[0]}=${r[1]}`)
45
+ .join("\n");
46
+ await config.askWriteProjectFile(`extensions/${spec.instanceId}.env`, content, force);
47
+ }
48
+ }
@@ -7,19 +7,19 @@ function parseTimeseriesResponse(series) {
7
7
  const ret = [];
8
8
  for (const s of series) {
9
9
  const ref = buildRef(s);
10
- if (ref == undefined) {
10
+ if (ref === undefined) {
11
11
  continue;
12
12
  }
13
13
  let valueToday;
14
14
  let value7dAgo;
15
15
  let value28dAgo;
16
- if (s.points.length >= 28 && s.points[27].value.int64Value != undefined) {
16
+ if (s.points.length >= 28 && s.points[27].value.int64Value !== undefined) {
17
17
  value28dAgo = parseBucket(s.points[27].value.int64Value);
18
18
  }
19
- if (s.points.length >= 7 && s.points[6].value.int64Value != undefined) {
19
+ if (s.points.length >= 7 && s.points[6].value.int64Value !== undefined) {
20
20
  value7dAgo = parseBucket(s.points[6].value.int64Value);
21
21
  }
22
- if (s.points.length >= 1 && s.points[0].value.int64Value != undefined) {
22
+ if (s.points.length >= 1 && s.points[0].value.int64Value !== undefined) {
23
23
  valueToday = parseBucket(s.points[0].value.int64Value);
24
24
  }
25
25
  ret.push({
@@ -49,7 +49,7 @@ async function getParams(args) {
49
49
  const firebaseProjectParams = await (0, extensionsHelper_1.getFirebaseProjectParams)(args.projectId);
50
50
  params = await askUserForParam.ask(args.projectId, args.instanceId, args.paramSpecs, firebaseProjectParams, !!args.reconfiguring);
51
51
  }
52
- track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
52
+ void track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
53
53
  return params;
54
54
  }
55
55
  exports.getParams = getParams;
@@ -82,7 +82,7 @@ async function getParamsForUpdate(args) {
82
82
  instanceId: args.instanceId,
83
83
  });
84
84
  }
85
- track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
85
+ void track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
86
86
  return params;
87
87
  }
88
88
  exports.getParamsForUpdate = getParamsForUpdate;
@@ -116,10 +116,10 @@ function getParamsFromFile(args) {
116
116
  let envParams;
117
117
  try {
118
118
  envParams = readEnvFile(args.paramsEnvPath);
119
- track("Extension Env File", "Present");
119
+ void track("Extension Env File", "Present");
120
120
  }
121
121
  catch (err) {
122
- track("Extension Env File", "Invalid");
122
+ void track("Extension Env File", "Invalid");
123
123
  throw new error_1.FirebaseError(`Error reading env file: ${err.message}\n`, { original: err });
124
124
  }
125
125
  const params = (0, extensionsHelper_1.populateDefaultParams)(envParams, args.paramSpecs);
@@ -20,7 +20,7 @@ function parse(refOrName) {
20
20
  exports.parse = parse;
21
21
  function parseRef(ref) {
22
22
  const parts = refRegex.exec(ref);
23
- if (parts && (parts.length == 5 || parts.length == 7)) {
23
+ if (parts && (parts.length === 5 || parts.length === 7)) {
24
24
  const publisherId = parts[1];
25
25
  const extensionId = parts[2];
26
26
  const version = parts[4];
@@ -15,7 +15,7 @@ async function ensureSecretManagerApiEnabled(options) {
15
15
  }
16
16
  exports.ensureSecretManagerApiEnabled = ensureSecretManagerApiEnabled;
17
17
  function usesSecrets(spec) {
18
- return spec.params && !!spec.params.find((p) => p.type == extensionsApi.ParamType.SECRET);
18
+ return spec.params && !!spec.params.find((p) => p.type === extensionsApi.ParamType.SECRET);
19
19
  }
20
20
  exports.usesSecrets = usesSecrets;
21
21
  async function grantFirexServiceAgentSecretAdminRole(secret) {
@@ -38,7 +38,7 @@ async function getManagedSecrets(instance) {
38
38
  exports.getManagedSecrets = getManagedSecrets;
39
39
  function getActiveSecrets(spec, params) {
40
40
  return spec.params
41
- .map((p) => (p.type == extensionsApi.ParamType.SECRET ? params[p.param] : ""))
41
+ .map((p) => (p.type === extensionsApi.ParamType.SECRET ? params[p.param] : ""))
42
42
  .filter((pv) => !!pv);
43
43
  }
44
44
  exports.getActiveSecrets = getActiveSecrets;
@@ -50,7 +50,7 @@ function getSecretLabels(instanceId) {
50
50
  exports.getSecretLabels = getSecretLabels;
51
51
  function prettySecretName(secretResourceName) {
52
52
  const nameTokens = secretResourceName.split("/");
53
- if (nameTokens.length != 4 && nameTokens.length != 6) {
53
+ if (nameTokens.length !== 4 && nameTokens.length !== 6) {
54
54
  logger_1.logger.debug(`unable to parse secret secretResourceName: ${secretResourceName}`);
55
55
  return secretResourceName;
56
56
  }
package/lib/functional.js CHANGED
@@ -40,7 +40,7 @@ function reduceFlat(accum, next) {
40
40
  }
41
41
  exports.reduceFlat = reduceFlat;
42
42
  function* zip(left, right) {
43
- if (left.length != right.length) {
43
+ if (left.length !== right.length) {
44
44
  throw new Error("Cannot zip between two lists of differen lengths");
45
45
  }
46
46
  for (let i = 0; i < left.length; i++) {
@@ -12,6 +12,7 @@ const RESERVED_PREFIXES = ["X_GOOGLE_", "FIREBASE_", "EXT_"];
12
12
  const RESERVED_KEYS = [
13
13
  "FIREBASE_CONFIG",
14
14
  "CLOUD_RUNTIME_CONFIG",
15
+ "EVENTARC_CLOUD_EVENT_SOURCE",
15
16
  "ENTRY_POINT",
16
17
  "GCP_PROJECT",
17
18
  "GCLOUD_PROJECT",
@@ -141,7 +142,7 @@ exports.hasUserEnvs = hasUserEnvs;
141
142
  function loadUserEnvs({ functionsSource, projectId, projectAlias, isEmulator, }) {
142
143
  var _a;
143
144
  const envFiles = findEnvfiles(functionsSource, projectId, projectAlias, isEmulator);
144
- if (envFiles.length == 0) {
145
+ if (envFiles.length === 0) {
145
146
  return {};
146
147
  }
147
148
  if (projectAlias) {
@@ -92,7 +92,7 @@ async function getIamPolicy(fnName) {
92
92
  }
93
93
  exports.getIamPolicy = getIamPolicy;
94
94
  async function setInvokerCreate(projectId, fnName, invoker) {
95
- if (invoker.length == 0) {
95
+ if (invoker.length === 0) {
96
96
  throw new error_1.FirebaseError("Invoker cannot be an empty array");
97
97
  }
98
98
  const invokerMembers = proto.getInvokerMembers(invoker, projectId);
@@ -108,7 +108,7 @@ async function setInvokerCreate(projectId, fnName, invoker) {
108
108
  exports.setInvokerCreate = setInvokerCreate;
109
109
  async function setInvokerUpdate(projectId, fnName, invoker) {
110
110
  var _a;
111
- if (invoker.length == 0) {
111
+ if (invoker.length === 0) {
112
112
  throw new error_1.FirebaseError("Invoker cannot be an empty array");
113
113
  }
114
114
  const invokerMembers = proto.getInvokerMembers(invoker, projectId);
@@ -206,6 +206,7 @@ function endpointFromFunction(gcfFunction) {
206
206
  const [, project, , region, , id] = gcfFunction.name.split("/");
207
207
  let trigger;
208
208
  let uri;
209
+ let securityLevel;
209
210
  if ((_a = gcfFunction.labels) === null || _a === void 0 ? void 0 : _a["deployment-scheduled"]) {
210
211
  trigger = {
211
212
  scheduleTrigger: {},
@@ -219,6 +220,7 @@ function endpointFromFunction(gcfFunction) {
219
220
  else if (gcfFunction.httpsTrigger) {
220
221
  trigger = { httpsTrigger: {} };
221
222
  uri = gcfFunction.httpsTrigger.url;
223
+ securityLevel = gcfFunction.httpsTrigger.securityLevel;
222
224
  }
223
225
  else {
224
226
  trigger = {
@@ -240,12 +242,19 @@ function endpointFromFunction(gcfFunction) {
240
242
  if (uri) {
241
243
  endpoint.uri = uri;
242
244
  }
243
- proto.copyIfPresent(endpoint, gcfFunction, "serviceAccountEmail", "availableMemoryMb", "timeout", "minInstances", "maxInstances", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "labels", "environmentVariables", "secretEnvironmentVariables", "sourceUploadUrl");
245
+ if (securityLevel) {
246
+ endpoint.securityLevel = securityLevel;
247
+ }
248
+ proto.copyIfPresent(endpoint, gcfFunction, "serviceAccountEmail", "availableMemoryMb", "timeout", "minInstances", "maxInstances", "ingressSettings", "labels", "environmentVariables", "secretEnvironmentVariables", "sourceUploadUrl");
249
+ if (gcfFunction.vpcConnector) {
250
+ endpoint.vpc = { connector: gcfFunction.vpcConnector };
251
+ proto.renameIfPresent(endpoint.vpc, gcfFunction, "egressSettings", "vpcConnectorEgressSettings");
252
+ }
244
253
  return endpoint;
245
254
  }
246
255
  exports.endpointFromFunction = endpointFromFunction;
247
256
  function functionFromEndpoint(endpoint, sourceUploadUrl) {
248
- if (endpoint.platform != "gcfv1") {
257
+ if (endpoint.platform !== "gcfv1") {
249
258
  throw new error_1.FirebaseError("Trying to create a v1 CloudFunction with v2 API. This should never happen");
250
259
  }
251
260
  if (!runtimes.isValidRuntime(endpoint.runtime)) {
@@ -282,8 +291,18 @@ function functionFromEndpoint(endpoint, sourceUploadUrl) {
282
291
  }
283
292
  else {
284
293
  gcfFunction.httpsTrigger = {};
294
+ if (backend.isCallableTriggered(endpoint)) {
295
+ gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-callabled": "true" });
296
+ }
297
+ if (endpoint.securityLevel) {
298
+ gcfFunction.httpsTrigger.securityLevel = endpoint.securityLevel;
299
+ }
300
+ }
301
+ proto.copyIfPresent(gcfFunction, endpoint, "serviceAccountEmail", "timeout", "availableMemoryMb", "minInstances", "maxInstances", "ingressSettings", "environmentVariables", "secretEnvironmentVariables");
302
+ if (endpoint.vpc) {
303
+ proto.renameIfPresent(gcfFunction, endpoint.vpc, "vpcConnector", "connector");
304
+ proto.renameIfPresent(gcfFunction, endpoint.vpc, "vpcConnectorEgressSettings", "egressSettings");
285
305
  }
286
- proto.copyIfPresent(gcfFunction, endpoint, "serviceAccountEmail", "timeout", "availableMemoryMb", "minInstances", "maxInstances", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "environmentVariables", "secretEnvironmentVariables");
287
306
  return gcfFunction;
288
307
  }
289
308
  exports.functionFromEndpoint = functionFromEndpoint;
@@ -106,7 +106,7 @@ async function listFunctionsInternal(projectId, region) {
106
106
  let pageToken = "";
107
107
  while (true) {
108
108
  const url = `projects/${projectId}/locations/${region}/functions`;
109
- const opts = pageToken == "" ? {} : { queryParams: { pageToken } };
109
+ const opts = pageToken === "" ? {} : { queryParams: { pageToken } };
110
110
  const res = await client.get(url, opts);
111
111
  functions.push(...(res.body.functions || []));
112
112
  for (const region of res.body.unreachable || []) {
@@ -122,9 +122,10 @@ async function listFunctionsInternal(projectId, region) {
122
122
  }
123
123
  }
124
124
  async function updateFunction(cloudFunction) {
125
+ const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "serviceConfig.environmentVariables");
125
126
  try {
126
127
  const queryParams = {
127
- updateMask: proto.fieldMasks(cloudFunction).join(","),
128
+ updateMask: fieldMasks.join(","),
128
129
  };
129
130
  const res = await client.patch(cloudFunction.name, cloudFunction, { queryParams });
130
131
  return res.body;
@@ -145,7 +146,7 @@ async function deleteFunction(cloudFunction) {
145
146
  }
146
147
  exports.deleteFunction = deleteFunction;
147
148
  function functionFromEndpoint(endpoint, source) {
148
- if (endpoint.platform != "gcfv2") {
149
+ if (endpoint.platform !== "gcfv2") {
149
150
  throw new error_1.FirebaseError("Trying to create a v2 CloudFunction with v1 API. This should never happen");
150
151
  }
151
152
  if (!runtimes.isValidRuntime(endpoint.runtime)) {
@@ -165,11 +166,15 @@ function functionFromEndpoint(endpoint, source) {
165
166
  serviceConfig: {},
166
167
  };
167
168
  proto.copyIfPresent(gcfFunction, endpoint, "labels");
168
- proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "vpcConnector", "vpcConnectorEgressSettings", "serviceAccountEmail", "ingressSettings");
169
+ proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "serviceAccountEmail", "ingressSettings");
169
170
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "availableMemory", "availableMemoryMb", (mb) => `${mb}M`);
170
171
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "timeoutSeconds", "timeout", proto.secondsFromDuration);
171
172
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "minInstanceCount", "minInstances");
172
173
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "maxInstanceCount", "maxInstances");
174
+ if (endpoint.vpc) {
175
+ proto.renameIfPresent(gcfFunction.serviceConfig, endpoint.vpc, "vpcConnector", "connector");
176
+ proto.renameIfPresent(gcfFunction.serviceConfig, endpoint.vpc, "vpcConnectorEgressSettings", "egressSettings");
177
+ }
173
178
  if (backend.isEventTriggered(endpoint)) {
174
179
  gcfFunction.eventTrigger = {
175
180
  eventType: endpoint.eventTrigger.eventType,
@@ -187,6 +192,7 @@ function functionFromEndpoint(endpoint, source) {
187
192
  if (endpoint.eventTrigger.retry) {
188
193
  logger_1.logger.warn("Cannot set a retry policy on Cloud Function", endpoint.id);
189
194
  }
195
+ gcfFunction.serviceConfig.environmentVariables = Object.assign(Object.assign({}, gcfFunction.serviceConfig.environmentVariables), { FUNCTION_SIGNATURE_TYPE: "cloudevent" });
190
196
  }
191
197
  else if (backend.isScheduleTriggered(endpoint)) {
192
198
  gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-scheduled": "true" });
@@ -194,6 +200,9 @@ function functionFromEndpoint(endpoint, source) {
194
200
  else if (backend.isTaskQueueTriggered(endpoint)) {
195
201
  gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-taskqueue": "true" });
196
202
  }
203
+ else if (backend.isCallableTriggered(endpoint)) {
204
+ gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-callable": "true" });
205
+ }
197
206
  return gcfFunction;
198
207
  }
199
208
  exports.functionFromEndpoint = functionFromEndpoint;
@@ -238,12 +247,16 @@ function endpointFromFunction(gcfFunction) {
238
247
  const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
239
248
  project,
240
249
  region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime, uri: gcfFunction.serviceConfig.uri });
241
- proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "environmentVariables");
250
+ proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "ingressSettings", "environmentVariables");
242
251
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", megabytes);
243
252
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "timeout", "timeoutSeconds", proto.durationFromSeconds);
244
253
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
245
254
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
246
255
  proto.copyIfPresent(endpoint, gcfFunction, "labels");
256
+ if (gcfFunction.serviceConfig.vpcConnector) {
257
+ endpoint.vpc = { connector: gcfFunction.serviceConfig.vpcConnector };
258
+ proto.renameIfPresent(endpoint.vpc, gcfFunction.serviceConfig, "egressSettings", "vpcConnectorEgressSettings");
259
+ }
247
260
  return endpoint;
248
261
  }
249
262
  exports.endpointFromFunction = endpointFromFunction;
@@ -102,7 +102,7 @@ async function setEnqueuer(name, invoker, assumeEmpty = false) {
102
102
  const invokerMembers = proto.getInvokerMembers(invoker, project);
103
103
  while (true) {
104
104
  const policy = {
105
- bindings: existing.bindings.filter((binding) => binding.role != ENQUEUER_ROLE),
105
+ bindings: existing.bindings.filter((binding) => binding.role !== ENQUEUER_ROLE),
106
106
  etag: existing.etag,
107
107
  version: existing.version,
108
108
  };
package/lib/gcp/docker.js CHANGED
@@ -58,7 +58,7 @@ class Client {
58
58
  if (!response.body) {
59
59
  return;
60
60
  }
61
- if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) != 0) {
61
+ if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
62
62
  throw new error_1.FirebaseError(`Failed to delete tag ${tag} at path ${path}`, {
63
63
  children: response.body.errors,
64
64
  });
@@ -70,7 +70,7 @@ class Client {
70
70
  if (!response.body) {
71
71
  return;
72
72
  }
73
- if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) != 0) {
73
+ if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
74
74
  throw new error_1.FirebaseError(`Failed to delete image ${digest} at path ${path}`, {
75
75
  children: response.body.errors,
76
76
  });
package/lib/gcp/run.js CHANGED
@@ -63,7 +63,7 @@ async function getIamPolicy(serviceName, httpClient = client) {
63
63
  }
64
64
  exports.getIamPolicy = getIamPolicy;
65
65
  async function setInvokerCreate(projectId, serviceName, invoker, httpClient = client) {
66
- if (invoker.length == 0) {
66
+ if (invoker.length === 0) {
67
67
  throw new error_1.FirebaseError("Invoker cannot be an empty array");
68
68
  }
69
69
  const invokerMembers = proto.getInvokerMembers(invoker, projectId);
@@ -79,7 +79,7 @@ async function setInvokerCreate(projectId, serviceName, invoker, httpClient = cl
79
79
  exports.setInvokerCreate = setInvokerCreate;
80
80
  async function setInvokerUpdate(projectId, serviceName, invoker, httpClient = client) {
81
81
  var _a;
82
- if (invoker.length == 0) {
82
+ if (invoker.length === 0) {
83
83
  throw new error_1.FirebaseError("Invoker cannot be an empty array");
84
84
  }
85
85
  const invokerMembers = proto.getInvokerMembers(invoker, projectId);
@@ -192,7 +192,7 @@ async function removeAuthDomain(project, url) {
192
192
  return domains;
193
193
  }
194
194
  const targetDomain = url.replace("https://", "");
195
- const authDomains = domains.filter((domain) => domain != targetDomain);
195
+ const authDomains = domains.filter((domain) => domain !== targetDomain);
196
196
  return (0, auth_1.updateAuthDomains)(project, authDomains);
197
197
  }
198
198
  exports.removeAuthDomain = removeAuthDomain;
@@ -54,7 +54,7 @@ function proxyRequestHandler(url, rewriteIdentifier) {
54
54
  continue;
55
55
  }
56
56
  const value = req.headers[key];
57
- if (value == undefined) {
57
+ if (value === undefined) {
58
58
  headers.delete(key);
59
59
  }
60
60
  else if (Array.isArray(value)) {
@@ -115,7 +115,7 @@ function proxyRequestHandler(url, rewriteIdentifier) {
115
115
  if (location) {
116
116
  try {
117
117
  const locationURL = new url_1.URL(location);
118
- if (locationURL.origin == u.origin) {
118
+ if (locationURL.origin === u.origin) {
119
119
  const unborkedLocation = location.replace(locationURL.origin, "");
120
120
  proxyRes.response.headers.set("location", unborkedLocation);
121
121
  }
@@ -27,7 +27,7 @@ async function promptForAccount() {
27
27
  message: "Please select an option:",
28
28
  choices,
29
29
  });
30
- if (emailChoice == "__add__") {
30
+ if (emailChoice === "__add__") {
31
31
  const newAccount = await (0, auth_1.loginAdditionalAccount)(true);
32
32
  if (!newAccount) {
33
33
  throw new error_1.FirebaseError("Failed to add new account", { exit: 1 });
@@ -168,7 +168,7 @@ function convertDatabaseInstance(serverInstance) {
168
168
  throw new error_1.FirebaseError(`DatabaseInstance response is missing field "name"`);
169
169
  }
170
170
  const m = serverInstance.name.match(INSTANCE_RESOURCE_NAME_REGEX);
171
- if (!m || m.length != 4) {
171
+ if (!m || m.length !== 4) {
172
172
  throw new error_1.FirebaseError(`Error parsing instance resource name: ${serverInstance.name}, matches: ${m}`);
173
173
  }
174
174
  return {