firebase-tools 13.5.2 → 13.6.1

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 (116) hide show
  1. package/lib/accountExporter.js +1 -1
  2. package/lib/accountImporter.js +1 -1
  3. package/lib/api.js +112 -58
  4. package/lib/apiv2.js +3 -1
  5. package/lib/appdistribution/client.js +4 -4
  6. package/lib/apphosting/config.js +31 -0
  7. package/lib/apphosting/githubConnections.js +261 -0
  8. package/lib/{init/features/apphosting → apphosting}/index.js +26 -22
  9. package/lib/{init/features/apphosting → apphosting}/repo.js +25 -13
  10. package/lib/apphosting/secrets/dialogs.js +169 -0
  11. package/lib/apphosting/secrets/index.js +98 -0
  12. package/lib/auth.js +17 -17
  13. package/lib/commands/apphosting-backends-create.js +4 -2
  14. package/lib/commands/apphosting-backends-delete.js +1 -1
  15. package/lib/commands/apphosting-secrets-describe.js +29 -0
  16. package/lib/commands/apphosting-secrets-grantaccess.js +45 -0
  17. package/lib/commands/apphosting-secrets-set.js +102 -0
  18. package/lib/commands/functions-secrets-access.js +2 -2
  19. package/lib/commands/functions-secrets-describe.js +14 -0
  20. package/lib/commands/functions-secrets-destroy.js +2 -2
  21. package/lib/commands/functions-secrets-get.js +3 -17
  22. package/lib/commands/functions-secrets-prune.js +2 -1
  23. package/lib/commands/functions-secrets-set.js +2 -2
  24. package/lib/commands/hosting-disable.js +1 -1
  25. package/lib/commands/index.js +5 -0
  26. package/lib/commands/open.js +1 -1
  27. package/lib/database/metadata.js +3 -3
  28. package/lib/defaultCredentials.js +2 -2
  29. package/lib/deploy/extensions/v2FunctionHelper.js +1 -1
  30. package/lib/deploy/functions/build.js +1 -1
  31. package/lib/deploy/functions/checkIam.js +3 -6
  32. package/lib/deploy/functions/containerCleaner.js +5 -15
  33. package/lib/deploy/functions/deploy.js +8 -2
  34. package/lib/deploy/functions/ensure.js +1 -1
  35. package/lib/deploy/functions/params.js +2 -2
  36. package/lib/deploy/functions/prepare.js +16 -7
  37. package/lib/deploy/functions/release/fabricator.js +8 -8
  38. package/lib/deploy/functions/runtimes/discovery/index.js +2 -2
  39. package/lib/deploy/functions/runtimes/index.js +6 -43
  40. package/lib/deploy/functions/runtimes/node/index.js +3 -2
  41. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +15 -34
  42. package/lib/deploy/functions/runtimes/node/parseTriggers.js +2 -2
  43. package/lib/deploy/functions/runtimes/python/index.js +11 -7
  44. package/lib/deploy/functions/runtimes/supported.js +135 -0
  45. package/lib/deploy/hosting/uploader.js +1 -1
  46. package/lib/deploy/index.js +1 -1
  47. package/lib/deploy/remoteconfig/functions.js +1 -1
  48. package/lib/emulator/adminSdkConfig.js +1 -1
  49. package/lib/emulator/controller.js +8 -1
  50. package/lib/emulator/downloadableEmulators.js +6 -6
  51. package/lib/emulator/functionsEmulator.js +2 -2
  52. package/lib/emulator/hub.js +5 -0
  53. package/lib/ensureApiEnabled.js +1 -1
  54. package/lib/extensions/emulator/specHelper.js +4 -3
  55. package/lib/extensions/extensionsApi.js +5 -5
  56. package/lib/extensions/extensionsHelper.js +4 -4
  57. package/lib/extensions/provisioningHelper.js +2 -2
  58. package/lib/extensions/publishHelpers.js +1 -1
  59. package/lib/extensions/publisherApi.js +3 -3
  60. package/lib/extensions/resolveSource.js +1 -1
  61. package/lib/extensions/secretsUtils.js +1 -1
  62. package/lib/extensions/tos.js +1 -1
  63. package/lib/fetchMOTD.js +1 -1
  64. package/lib/fetchWebSetup.js +2 -2
  65. package/lib/firestore/api-sort.js +17 -0
  66. package/lib/firestore/api.js +9 -2
  67. package/lib/firestore/checkDatabaseType.js +1 -1
  68. package/lib/firestore/delete.js +1 -1
  69. package/lib/firestore/pretty-print.js +11 -2
  70. package/lib/functional.js +2 -2
  71. package/lib/functions/secrets.js +42 -24
  72. package/lib/functionsConfig.js +1 -1
  73. package/lib/gcp/apphosting.js +17 -4
  74. package/lib/gcp/artifactregistry.js +1 -1
  75. package/lib/gcp/auth.js +1 -1
  76. package/lib/gcp/cloudbilling.js +1 -1
  77. package/lib/gcp/cloudbuild.js +8 -4
  78. package/lib/gcp/cloudfunctions.js +6 -6
  79. package/lib/gcp/cloudfunctionsv2.js +4 -4
  80. package/lib/gcp/cloudlogging.js +1 -1
  81. package/lib/gcp/cloudmonitoring.js +1 -1
  82. package/lib/gcp/cloudscheduler.js +3 -3
  83. package/lib/gcp/cloudtasks.js +1 -1
  84. package/lib/gcp/computeEngine.js +7 -0
  85. package/lib/gcp/devConnect.js +45 -22
  86. package/lib/gcp/eventarc.js +1 -1
  87. package/lib/gcp/firestore.js +2 -2
  88. package/lib/gcp/iam.js +11 -3
  89. package/lib/gcp/identityPlatform.js +1 -1
  90. package/lib/gcp/pubsub.js +1 -1
  91. package/lib/gcp/resourceManager.js +2 -1
  92. package/lib/gcp/rules.js +1 -1
  93. package/lib/gcp/run.js +1 -1
  94. package/lib/gcp/runtimeconfig.js +1 -1
  95. package/lib/gcp/secretManager.js +54 -14
  96. package/lib/gcp/serviceusage.js +21 -5
  97. package/lib/gcp/storage.js +12 -8
  98. package/lib/hosting/api.js +2 -2
  99. package/lib/hosting/cloudRunProxy.js +1 -1
  100. package/lib/init/features/database.js +1 -1
  101. package/lib/init/features/extensions/index.js +1 -1
  102. package/lib/init/features/functions/index.js +2 -2
  103. package/lib/init/features/functions/python.js +4 -3
  104. package/lib/init/features/hosting/github.js +4 -3
  105. package/lib/init/features/index.js +1 -1
  106. package/lib/management/apps.js +4 -4
  107. package/lib/management/database.js +1 -1
  108. package/lib/management/projects.js +4 -4
  109. package/lib/remoteconfig/get.js +1 -1
  110. package/lib/remoteconfig/rollback.js +1 -1
  111. package/lib/remoteconfig/versionslist.js +1 -1
  112. package/lib/shortenUrl.js +2 -2
  113. package/lib/utils.js +1 -1
  114. package/package.json +1 -1
  115. package/schema/firebase-config.json +12 -2
  116. /package/lib/{init/features/apphosting → apphosting}/constants.js +0 -0
@@ -1,61 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRuntimeDelegate = exports.getHumanFriendlyRuntimeName = exports.isValidRuntime = exports.isDeprecatedRuntime = void 0;
3
+ exports.getRuntimeDelegate = void 0;
4
4
  const node = require("./node");
5
5
  const python = require("./python");
6
6
  const validate = require("../validate");
7
7
  const error_1 = require("../../../error");
8
- const RUNTIMES = [
9
- "nodejs10",
10
- "nodejs12",
11
- "nodejs14",
12
- "nodejs16",
13
- "nodejs18",
14
- "nodejs20",
15
- "python310",
16
- "python311",
17
- "python312",
18
- ];
19
- const EXPERIMENTAL_RUNTIMES = [];
20
- const DEPRECATED_RUNTIMES = ["nodejs6", "nodejs8"];
21
- function isDeprecatedRuntime(runtime) {
22
- return DEPRECATED_RUNTIMES.includes(runtime);
23
- }
24
- exports.isDeprecatedRuntime = isDeprecatedRuntime;
25
- function isValidRuntime(runtime) {
26
- return RUNTIMES.includes(runtime) || EXPERIMENTAL_RUNTIMES.includes(runtime);
27
- }
28
- exports.isValidRuntime = isValidRuntime;
29
- const MESSAGE_FRIENDLY_RUNTIMES = {
30
- nodejs6: "Node.js 6 (Deprecated)",
31
- nodejs8: "Node.js 8 (Deprecated)",
32
- nodejs10: "Node.js 10",
33
- nodejs12: "Node.js 12",
34
- nodejs14: "Node.js 14",
35
- nodejs16: "Node.js 16",
36
- nodejs18: "Node.js 18",
37
- nodejs20: "Node.js 20",
38
- python310: "Python 3.10",
39
- python311: "Python 3.11",
40
- python312: "Python 3.12",
41
- };
42
- function getHumanFriendlyRuntimeName(runtime) {
43
- return MESSAGE_FRIENDLY_RUNTIMES[runtime] || runtime;
44
- }
45
- exports.getHumanFriendlyRuntimeName = getHumanFriendlyRuntimeName;
8
+ const supported = require("./supported");
46
9
  const factories = [node.tryCreateDelegate, python.tryCreateDelegate];
47
10
  async function getRuntimeDelegate(context) {
48
11
  const { projectDir, sourceDir, runtime } = context;
49
- validate.functionsDirectoryExists(sourceDir, projectDir);
50
- if (runtime && !isValidRuntime(runtime)) {
51
- throw new error_1.FirebaseError(`Cannot deploy function with runtime ${runtime}`);
12
+ if (runtime && !supported.isRuntime(runtime)) {
13
+ throw new error_1.FirebaseError(`firebase.json specifies invalid runtime ${runtime} for directory ${sourceDir}`);
52
14
  }
15
+ validate.functionsDirectoryExists(sourceDir, projectDir);
53
16
  for (const factory of factories) {
54
17
  const delegate = await factory(context);
55
18
  if (delegate) {
56
19
  return delegate;
57
20
  }
58
21
  }
59
- throw new error_1.FirebaseError(`Could not detect language for functions at ${sourceDir}`);
22
+ throw new error_1.FirebaseError(`Could not detect runtime for functions at ${sourceDir}`);
60
23
  }
61
24
  exports.getRuntimeDelegate = getRuntimeDelegate;
@@ -13,6 +13,7 @@ const parseRuntimeAndValidateSDK_1 = require("./parseRuntimeAndValidateSDK");
13
13
  const logger_1 = require("../../../../logger");
14
14
  const utils_1 = require("../../../../utils");
15
15
  const discovery = require("../discovery");
16
+ const supported = require("../supported");
16
17
  const validate = require("./validate");
17
18
  const versioning = require("./versioning");
18
19
  const parseTriggers = require("./parseTriggers");
@@ -25,7 +26,7 @@ async function tryCreateDelegate(context) {
25
26
  return undefined;
26
27
  }
27
28
  const runtime = (0, parseRuntimeAndValidateSDK_1.getRuntimeChoice)(context.sourceDir, context.runtime);
28
- if (!runtime.startsWith("nodejs")) {
29
+ if (!supported.runtimeIsLanguage(runtime, "nodejs")) {
29
30
  logger_1.logger.debug("Customer has a package.json but did not get a nodejs runtime. This should not happen");
30
31
  throw new error_1.FirebaseError(`Unexpected runtime ${runtime}`);
31
32
  }
@@ -38,7 +39,7 @@ class Delegate {
38
39
  this.projectDir = projectDir;
39
40
  this.sourceDir = sourceDir;
40
41
  this.runtime = runtime;
41
- this.name = "nodejs";
42
+ this.language = "nodejs";
42
43
  this._sdkVersion = undefined;
43
44
  this._bin = "";
44
45
  }
@@ -1,31 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRuntimeChoice = exports.DEPRECATED_NODE_VERSION_INFO = exports.UNSUPPORTED_NODE_VERSION_PACKAGE_JSON_MSG = exports.UNSUPPORTED_NODE_VERSION_FIREBASE_JSON_MSG = exports.RUNTIME_NOT_SET = void 0;
3
+ exports.getRuntimeChoice = exports.RUNTIME_NOT_SET = void 0;
4
4
  const path = require("path");
5
- const clc = require("colorette");
6
5
  const error_1 = require("../../../../error");
7
- const runtimes = require("../../runtimes");
6
+ const supported = require("../supported");
8
7
  const cjson = require("cjson");
9
- const ENGINE_RUNTIMES = {
10
- 6: "nodejs6",
11
- 8: "nodejs8",
12
- 10: "nodejs10",
13
- 12: "nodejs12",
14
- 14: "nodejs14",
15
- 16: "nodejs16",
16
- 18: "nodejs18",
17
- 20: "nodejs20",
18
- };
19
- const ENGINE_RUNTIMES_NAMES = Object.values(ENGINE_RUNTIMES);
20
- exports.RUNTIME_NOT_SET = "`runtime` field is required but was not found in firebase.json.\n" +
8
+ const supportedNodeVersions = Object.keys(supported.RUNTIMES)
9
+ .filter((s) => supported.runtimeIsLanguage(s, "nodejs"))
10
+ .filter((s) => !supported.isDecommissioned(s))
11
+ .map((s) => s.substring("nodejs".length));
12
+ exports.RUNTIME_NOT_SET = "`runtime` field is required but was not found in firebase.json or package.json.\n" +
21
13
  "To fix this, add the following lines to the `functions` section of your firebase.json:\n" +
22
- '"runtime": "nodejs18"\n';
23
- exports.UNSUPPORTED_NODE_VERSION_FIREBASE_JSON_MSG = clc.bold(`functions.runtime value is unsupported. ` +
24
- `Valid choices are: ${clc.bold("nodejs{10|12|14|16|18|20}")}.`);
25
- exports.UNSUPPORTED_NODE_VERSION_PACKAGE_JSON_MSG = clc.bold(`package.json in functions directory has an engines field which is unsupported. ` +
26
- `Valid choices are: ${clc.bold('{"node": 10|12|14|16|18|20}')}`);
27
- exports.DEPRECATED_NODE_VERSION_INFO = `\n\nDeploys to runtimes below Node.js 10 are now disabled in the Firebase CLI. ` +
28
- `${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.`;
14
+ `"runtime": "${supported.latest("nodejs")}" or set the "engine" field in package.json\n`;
29
15
  function getRuntimeChoiceFromPackageJson(sourceDir) {
30
16
  const packageJsonPath = path.join(sourceDir, "package.json");
31
17
  let loaded;
@@ -39,19 +25,14 @@ function getRuntimeChoiceFromPackageJson(sourceDir) {
39
25
  if (!engines || !engines.node) {
40
26
  throw new error_1.FirebaseError(exports.RUNTIME_NOT_SET);
41
27
  }
42
- return ENGINE_RUNTIMES[engines.node];
43
- }
44
- function getRuntimeChoice(sourceDir, runtimeFromConfig) {
45
- const runtime = runtimeFromConfig || getRuntimeChoiceFromPackageJson(sourceDir);
46
- const errorMessage = (runtimeFromConfig
47
- ? exports.UNSUPPORTED_NODE_VERSION_FIREBASE_JSON_MSG
48
- : exports.UNSUPPORTED_NODE_VERSION_PACKAGE_JSON_MSG) + exports.DEPRECATED_NODE_VERSION_INFO;
49
- if (!runtime || !ENGINE_RUNTIMES_NAMES.includes(runtime)) {
50
- throw new error_1.FirebaseError(errorMessage, { exit: 1 });
51
- }
52
- if (runtimes.isDeprecatedRuntime(runtime) || !runtimes.isValidRuntime(runtime)) {
53
- throw new error_1.FirebaseError(errorMessage, { exit: 1 });
28
+ const runtime = `nodejs${engines.node}`;
29
+ if (!supported.isRuntime(runtime)) {
30
+ throw new error_1.FirebaseError(`Detected node engine ${engines.node} in package.json, which is not a ` +
31
+ `supported version. Valid versions are ${supportedNodeVersions.join(", ")}`);
54
32
  }
55
33
  return runtime;
56
34
  }
35
+ function getRuntimeChoice(sourceDir, runtimeFromConfig) {
36
+ return runtimeFromConfig || getRuntimeChoiceFromPackageJson(sourceDir);
37
+ }
57
38
  exports.getRuntimeChoice = getRuntimeChoice;
@@ -92,7 +92,7 @@ function addResourcesToBuild(projectId, runtime, annotation, want) {
92
92
  var _a, _b;
93
93
  Object.freeze(annotation);
94
94
  const toSeconds = (0, functional_1.nullsafeVisitor)(proto.secondsFromDuration);
95
- const regions = annotation.regions || [api.functionsDefaultRegion];
95
+ const regions = annotation.regions || [api.functionsDefaultRegion()];
96
96
  let triggered;
97
97
  const triggerCount = +!!annotation.httpsTrigger +
98
98
  +!!annotation.eventTrigger +
@@ -214,7 +214,7 @@ exports.addResourcesToBuild = addResourcesToBuild;
214
214
  function addResourcesToBackend(projectId, runtime, annotation, want) {
215
215
  var _a;
216
216
  Object.freeze(annotation);
217
- for (const region of annotation.regions || [api.functionsDefaultRegion]) {
217
+ for (const region of annotation.regions || [api.functionsDefaultRegion()]) {
218
218
  let triggered;
219
219
  const triggerCount = +!!annotation.httpsTrigger +
220
220
  +!!annotation.eventTrigger +
@@ -1,27 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Delegate = exports.getPythonBinary = exports.tryCreateDelegate = exports.LATEST_VERSION = void 0;
3
+ exports.Delegate = exports.getPythonBinary = exports.tryCreateDelegate = void 0;
4
4
  const fs = require("fs");
5
5
  const path = require("path");
6
6
  const node_fetch_1 = require("node-fetch");
7
7
  const util_1 = require("util");
8
8
  const portfinder = require("portfinder");
9
- const runtimes = require("..");
10
9
  const discovery = require("../discovery");
10
+ const supported = require("../supported");
11
11
  const logger_1 = require("../../../../logger");
12
12
  const python_1 = require("../../../../functions/python");
13
13
  const error_1 = require("../../../../error");
14
- exports.LATEST_VERSION = "python312";
14
+ const functional_1 = require("../../../../functional");
15
15
  async function tryCreateDelegate(context) {
16
+ var _a;
16
17
  const requirementsTextPath = path.join(context.sourceDir, "requirements.txt");
17
18
  if (!(await (0, util_1.promisify)(fs.exists)(requirementsTextPath))) {
18
19
  logger_1.logger.debug("Customer code is not Python code.");
19
20
  return;
20
21
  }
21
- const runtime = context.runtime ? context.runtime : exports.LATEST_VERSION;
22
- if (!runtimes.isValidRuntime(runtime)) {
22
+ const runtime = (_a = context.runtime) !== null && _a !== void 0 ? _a : supported.latest("python");
23
+ if (!supported.isRuntime(runtime)) {
23
24
  throw new error_1.FirebaseError(`Runtime ${runtime} is not a valid Python runtime`);
24
25
  }
26
+ if (!supported.runtimeIsLanguage(runtime, "python")) {
27
+ throw new error_1.FirebaseError(`Internal error. Trying to construct a python runtime delegate for runtime ${runtime}`, { exit: 1 });
28
+ }
25
29
  return Promise.resolve(new Delegate(context.projectId, context.sourceDir, runtime));
26
30
  }
27
31
  exports.tryCreateDelegate = tryCreateDelegate;
@@ -38,7 +42,7 @@ function getPythonBinary(runtime) {
38
42
  else if (runtime === "python312") {
39
43
  return "python3.12";
40
44
  }
41
- return "python";
45
+ (0, functional_1.assertExhaustive)(runtime, `Unhandled python runtime ${runtime}`);
42
46
  }
43
47
  exports.getPythonBinary = getPythonBinary;
44
48
  class Delegate {
@@ -46,7 +50,7 @@ class Delegate {
46
50
  this.projectId = projectId;
47
51
  this.sourceDir = sourceDir;
48
52
  this.runtime = runtime;
49
- this.name = "python";
53
+ this.language = "python";
50
54
  this._bin = "";
51
55
  this._modulesDir = "";
52
56
  }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.guardVersionSupport = exports.isDecommissioned = exports.latest = exports.runtimeIsLanguage = exports.isRuntime = exports.RUNTIMES = void 0;
4
+ const error_1 = require("../../../error");
5
+ const utils = require("../../../utils");
6
+ function runtimes(r) {
7
+ return r;
8
+ }
9
+ exports.RUNTIMES = runtimes({
10
+ nodejs6: {
11
+ friendly: "Node.js 6",
12
+ status: "decommissioned",
13
+ deprecationDate: "2019-04-17",
14
+ decommissionDate: "2020-08-01",
15
+ },
16
+ nodejs8: {
17
+ friendly: "Node.js 8",
18
+ status: "decommissioned",
19
+ deprecationDate: "2020-06-05",
20
+ decommissionDate: "2021-02-01",
21
+ },
22
+ nodejs10: {
23
+ friendly: "Node.js 10",
24
+ status: "GA",
25
+ deprecationDate: "2024-01-30",
26
+ decommissionDate: "2025-01-30",
27
+ },
28
+ nodejs12: {
29
+ friendly: "Node.js 12",
30
+ status: "GA",
31
+ deprecationDate: "2024-01-30",
32
+ decommissionDate: "2025-01-30",
33
+ },
34
+ nodejs14: {
35
+ friendly: "Node.js 14",
36
+ status: "GA",
37
+ deprecationDate: "2024-01-30",
38
+ decommissionDate: "2025-01-30",
39
+ },
40
+ nodejs16: {
41
+ friendly: "Node.js 16",
42
+ status: "GA",
43
+ deprecationDate: "2024-01-30",
44
+ decommissionDate: "2025-01-30",
45
+ },
46
+ nodejs18: {
47
+ friendly: "Node.js 18",
48
+ status: "GA",
49
+ deprecationDate: "2025-04-30",
50
+ decommissionDate: "2025-10-31",
51
+ },
52
+ nodejs20: {
53
+ friendly: "Node.js 20",
54
+ status: "GA",
55
+ deprecationDate: "2026-04-30",
56
+ decommissionDate: "2026-10-31",
57
+ },
58
+ python310: {
59
+ friendly: "Python 3.10",
60
+ status: "GA",
61
+ deprecationDate: "2026-10-04",
62
+ decommissionDate: "2027-04-30",
63
+ },
64
+ python311: {
65
+ friendly: "Python 3.11",
66
+ status: "GA",
67
+ deprecationDate: "2027-10-24",
68
+ decommissionDate: "2028-04-30",
69
+ },
70
+ python312: {
71
+ friendly: "Python 3.12",
72
+ status: "GA",
73
+ deprecationDate: "2028-10-02",
74
+ decommissionDate: "2029-04-30",
75
+ },
76
+ });
77
+ function isRuntime(maybe) {
78
+ return maybe in exports.RUNTIMES;
79
+ }
80
+ exports.isRuntime = isRuntime;
81
+ function runtimeIsLanguage(runtime, language) {
82
+ return runtime.startsWith(language);
83
+ }
84
+ exports.runtimeIsLanguage = runtimeIsLanguage;
85
+ function latest(language, runtimes = Object.keys(exports.RUNTIMES)) {
86
+ const sorted = runtimes
87
+ .filter((s) => runtimeIsLanguage(s, language))
88
+ .sort((left, right) => {
89
+ const leftVersion = +left.substring(language.length);
90
+ const rightVersion = +right.substring(language.length);
91
+ if (isNaN(leftVersion) || isNaN(rightVersion)) {
92
+ throw new error_1.FirebaseError("Internal error. Runtime or language names are malformed", {
93
+ exit: 1,
94
+ });
95
+ }
96
+ return leftVersion - rightVersion;
97
+ });
98
+ const latest = utils.last(sorted);
99
+ if (!latest) {
100
+ throw new error_1.FirebaseError(`Internal error trying to find the latest supported runtime for ${language}`, { exit: 1 });
101
+ }
102
+ return latest;
103
+ }
104
+ exports.latest = latest;
105
+ function isDecommissioned(runtime, now = new Date()) {
106
+ const cutoff = new Date(exports.RUNTIMES[runtime].decommissionDate);
107
+ return cutoff < now;
108
+ }
109
+ exports.isDecommissioned = isDecommissioned;
110
+ function guardVersionSupport(runtime, now = new Date()) {
111
+ const { deprecationDate, decommissionDate } = exports.RUNTIMES[runtime];
112
+ const decommission = new Date(decommissionDate);
113
+ if (now >= decommission) {
114
+ throw new error_1.FirebaseError(`Runtime ${exports.RUNTIMES[runtime].friendly} was decommissioned on ${decommissionDate}. To deploy ` +
115
+ "you must first upgrade your runtime version.", { exit: 1 });
116
+ }
117
+ const deprecation = new Date(deprecationDate);
118
+ if (now >= deprecation) {
119
+ utils.logLabeledWarning("functions", `Runtime ${exports.RUNTIMES[runtime].friendly} was deprecated on ${deprecationDate} and will be ` +
120
+ `decommissioned on ${decommissionDate}, after which you will not be able ` +
121
+ "to deploy without upgrading. Consider upgrading now to avoid disruption. See " +
122
+ "https://cloud.google.com/functions/docs/runtime-support for full " +
123
+ "details on the lifecycle policy");
124
+ return;
125
+ }
126
+ const warning = new Date(deprecation.getTime() - 90 * 24 * 60 * 60 * 1000);
127
+ if (now >= warning) {
128
+ utils.logLabeledWarning("functions", `Runtime ${exports.RUNTIMES[runtime].friendly} will be deprecated on ${deprecationDate} and will be ` +
129
+ `decommissioned on ${decommissionDate}, after which you will not be able ` +
130
+ "to deploy without upgrading. Consider upgrading now to avoid disruption. See " +
131
+ "https://cloud.google.com/functions/docs/runtime-support for full " +
132
+ "details on the lifecycle policy");
133
+ }
134
+ }
135
+ exports.guardVersionSupport = guardVersionSupport;
@@ -24,7 +24,7 @@ function progressMessage(message, current, total) {
24
24
  class Uploader {
25
25
  constructor(options) {
26
26
  this.hashClient = new apiv2_1.Client({
27
- urlPrefix: api_1.hostingApiOrigin,
27
+ urlPrefix: (0, api_1.hostingApiOrigin)(),
28
28
  auth: true,
29
29
  apiVersion: "v1beta1",
30
30
  });
@@ -115,7 +115,7 @@ const deploy = async function (targetNames, options, customContext = {}) {
115
115
  logger_1.logger.info((0, colorette_1.bold)("Project Console:"), (0, utils_1.consoleUrl)(options.project, "/overview"));
116
116
  if (deployedHosting) {
117
117
  (0, lodash_1.each)(context.hosting.deploys, (deploy) => {
118
- logger_1.logger.info((0, colorette_1.bold)("Hosting URL:"), (0, utils_1.addSubdomain)(api_1.hostingOrigin, deploy.config.site));
118
+ logger_1.logger.info((0, colorette_1.bold)("Hosting URL:"), (0, utils_1.addSubdomain)((0, api_1.hostingOrigin)(), deploy.config.site));
119
119
  });
120
120
  const versionNames = context.hosting.deploys.map((deploy) => deploy.version);
121
121
  return { hosting: versionNames.length === 1 ? versionNames[0] : versionNames };
@@ -5,7 +5,7 @@ const api_1 = require("../../api");
5
5
  const apiv2_1 = require("../../apiv2");
6
6
  const error_1 = require("../../error");
7
7
  const TIMEOUT = 30000;
8
- const client = new apiv2_1.Client({ urlPrefix: api_1.remoteConfigApiOrigin, apiVersion: "v1" });
8
+ const client = new apiv2_1.Client({ urlPrefix: (0, api_1.remoteConfigApiOrigin)(), apiVersion: "v1" });
9
9
  async function getEtag(projectNumber, versionNumber) {
10
10
  const reqPath = `/projects/${projectNumber}/remoteConfig`;
11
11
  const queryParams = {};
@@ -35,7 +35,7 @@ async function getProjectAdminSdkConfig(projectId) {
35
35
  const apiClient = new apiv2.Client({
36
36
  auth: true,
37
37
  apiVersion: "v1beta1",
38
- urlPrefix: api_1.firebaseApiOrigin,
38
+ urlPrefix: (0, api_1.firebaseApiOrigin)(),
39
39
  });
40
40
  if (projectId.startsWith("demo-")) {
41
41
  logger_1.logger.debug(`Detected demo- project: ${projectId}. Using default adminSdkConfig instead of calling firebase API.`);
@@ -41,6 +41,7 @@ const downloadableEmulators_1 = require("./downloadableEmulators");
41
41
  const frameworks_1 = require("../frameworks");
42
42
  const experiments = require("../experiments");
43
43
  const portUtils_1 = require("./portUtils");
44
+ const supported_1 = require("../deploy/functions/runtimes/supported");
44
45
  const START_LOGGING_EMULATOR = utils.envOverride("START_LOGGING_EMULATOR", "false", (val) => val === "true");
45
46
  async function exportOnExit(options) {
46
47
  const exportOnExitDir = options.exportOnExit;
@@ -308,7 +309,13 @@ async function startAll(options, showUI = true, runningTestScript = false) {
308
309
  utils.assertIsStringOrUndefined(options.extDevDir);
309
310
  for (const cfg of functionsCfg) {
310
311
  const functionsDir = path.join(projectDir, cfg.source);
311
- const runtime = (_e = options.extDevRuntime) !== null && _e !== void 0 ? _e : cfg.runtime;
312
+ let runtime = ((_e = options.extDevRuntime) !== null && _e !== void 0 ? _e : cfg.runtime);
313
+ if (!runtime) {
314
+ runtime = (0, supported_1.latest)("nodejs");
315
+ }
316
+ if (!(0, supported_1.isRuntime)(runtime)) {
317
+ throw new error_1.FirebaseError(`Cannot load functions from ${functionsDir} because it has invalid runtime ${runtime}`);
318
+ }
312
319
  emulatableBackends.push({
313
320
  functionsDir,
314
321
  runtime,
@@ -23,9 +23,9 @@ const EMULATOR_UPDATE_DETAILS = {
23
23
  expectedChecksum: "2fd771101c0e1f7898c04c9204f2ce63",
24
24
  },
25
25
  firestore: {
26
- version: "1.19.3",
27
- expectedSize: 67296394,
28
- expectedChecksum: "08a9b882a5c38570b6333f3931b1e52b",
26
+ version: "1.19.4",
27
+ expectedSize: 65913000,
28
+ expectedChecksum: "a861bfa9d12ef69645b41e2f3bd8db8d",
29
29
  },
30
30
  storage: {
31
31
  version: "1.1.3",
@@ -40,9 +40,9 @@ const EMULATOR_UPDATE_DETAILS = {
40
40
  expectedChecksum: "49f6dc1911dda9d10df62a6c09aaf9a0",
41
41
  },
42
42
  pubsub: {
43
- version: "0.7.1",
44
- expectedSize: 65137179,
45
- expectedChecksum: "b59a6e705031a54a69e5e1dced7ca9bf",
43
+ version: "0.8.2",
44
+ expectedSize: 65611398,
45
+ expectedChecksum: "70bb840321423e6ae621a3ae2f314903",
46
46
  },
47
47
  };
48
48
  exports.DownloadDetails = {
@@ -297,9 +297,9 @@ class FunctionsEmulator {
297
297
  runtime: emulatableBackend.runtime,
298
298
  };
299
299
  const runtimeDelegate = await runtimes.getRuntimeDelegate(runtimeDelegateContext);
300
- logger_1.logger.debug(`Validating ${runtimeDelegate.name} source`);
300
+ logger_1.logger.debug(`Validating ${runtimeDelegate.language} source`);
301
301
  await runtimeDelegate.validate();
302
- logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
302
+ logger_1.logger.debug(`Building ${runtimeDelegate.language} source`);
303
303
  await runtimeDelegate.build();
304
304
  emulatableBackend.runtime = runtimeDelegate.runtime;
305
305
  emulatableBackend.bin = runtimeDelegate.bin;
@@ -53,6 +53,11 @@ class EmulatorHub extends ExpressBasedEmulator_1.ExpressBasedEmulator {
53
53
  res.json(body);
54
54
  });
55
55
  app.post(EmulatorHub.PATH_EXPORT, async (req, res) => {
56
+ if (req.headers.origin) {
57
+ res.status(403).json({
58
+ message: `Export cannot be triggered by external callers.`,
59
+ });
60
+ }
56
61
  const path = req.body.path;
57
62
  const initiatedBy = req.body.initiatedBy || "unknown";
58
63
  utils.logLabeledBullet("emulators", `Received export request. Exporting data to ${path}.`);
@@ -12,7 +12,7 @@ exports.POLL_SETTINGS = {
12
12
  pollsBeforeRetry: 12,
13
13
  };
14
14
  const apiClient = new apiv2_1.Client({
15
- urlPrefix: api_1.serviceUsageOrigin,
15
+ urlPrefix: (0, api_1.serviceUsageOrigin)(),
16
16
  apiVersion: "v1",
17
17
  });
18
18
  async function check(projectId, apiUri, prefix, silent = false) {
@@ -4,6 +4,7 @@ exports.getRuntime = exports.DEFAULT_RUNTIME = exports.getFunctionProperties = e
4
4
  const yaml = require("js-yaml");
5
5
  const path = require("path");
6
6
  const fs = require("fs-extra");
7
+ const supported = require("../../deploy/functions/runtimes/supported");
7
8
  const error_1 = require("../../error");
8
9
  const extensionsHelper_1 = require("../extensionsHelper");
9
10
  const utils_1 = require("../utils");
@@ -77,7 +78,7 @@ function getFunctionProperties(resources) {
77
78
  return resources.map((r) => r.properties);
78
79
  }
79
80
  exports.getFunctionProperties = getFunctionProperties;
80
- exports.DEFAULT_RUNTIME = "nodejs14";
81
+ exports.DEFAULT_RUNTIME = supported.latest("nodejs");
81
82
  function getRuntime(resources) {
82
83
  if (resources.length === 0) {
83
84
  return exports.DEFAULT_RUNTIME;
@@ -88,7 +89,7 @@ function getRuntime(resources) {
88
89
  if (!runtime) {
89
90
  return exports.DEFAULT_RUNTIME;
90
91
  }
91
- if (!/^(nodejs)?([0-9]+)/.test(runtime)) {
92
+ if (!supported.runtimeIsLanguage(runtime, "nodejs")) {
92
93
  invalidRuntimes.push(runtime);
93
94
  return exports.DEFAULT_RUNTIME;
94
95
  }
@@ -97,6 +98,6 @@ function getRuntime(resources) {
97
98
  if (invalidRuntimes.length) {
98
99
  throw new error_1.FirebaseError(`The following runtimes are not supported by the Emulator Suite: ${invalidRuntimes.join(", ")}. \n Only Node runtimes are supported.`);
99
100
  }
100
- return runtimes.sort()[runtimes.length - 1];
101
+ return supported.latest("nodejs", runtimes);
101
102
  }
102
103
  exports.getRuntime = getRuntime;
@@ -12,7 +12,7 @@ const refs = require("./refs");
12
12
  const EXTENSIONS_API_VERSION = "v1beta";
13
13
  const PAGE_SIZE_MAX = 100;
14
14
  const extensionsApiClient = new apiv2_1.Client({
15
- urlPrefix: api_1.extensionsOrigin,
15
+ urlPrefix: (0, api_1.extensionsOrigin)(),
16
16
  apiVersion: EXTENSIONS_API_VERSION,
17
17
  });
18
18
  async function createInstanceHelper(projectId, instanceId, config, validateOnly = false) {
@@ -28,7 +28,7 @@ async function createInstanceHelper(projectId, instanceId, config, validateOnly
28
28
  return createRes.body;
29
29
  }
30
30
  const pollRes = await operationPoller.pollOperation({
31
- apiOrigin: api_1.extensionsOrigin,
31
+ apiOrigin: (0, api_1.extensionsOrigin)(),
32
32
  apiVersion: EXTENSIONS_API_VERSION,
33
33
  operationResourceName: createRes.body.name,
34
34
  masterTimeout: 3600000,
@@ -69,7 +69,7 @@ exports.createInstance = createInstance;
69
69
  async function deleteInstance(projectId, instanceId) {
70
70
  const deleteRes = await extensionsApiClient.delete(`/projects/${projectId}/instances/${instanceId}`);
71
71
  const pollRes = await operationPoller.pollOperation({
72
- apiOrigin: api_1.extensionsOrigin,
72
+ apiOrigin: (0, api_1.extensionsOrigin)(),
73
73
  apiVersion: EXTENSIONS_API_VERSION,
74
74
  operationResourceName: deleteRes.body.name,
75
75
  masterTimeout: 600000,
@@ -217,7 +217,7 @@ async function patchInstance(args) {
217
217
  return updateRes;
218
218
  }
219
219
  const pollRes = await operationPoller.pollOperation({
220
- apiOrigin: api_1.extensionsOrigin,
220
+ apiOrigin: (0, api_1.extensionsOrigin)(),
221
221
  apiVersion: EXTENSIONS_API_VERSION,
222
222
  operationResourceName: updateRes.body.name,
223
223
  masterTimeout: 600000,
@@ -248,7 +248,7 @@ async function createSource(projectId, packageUri, extensionRoot) {
248
248
  extensionRoot,
249
249
  });
250
250
  const pollRes = await operationPoller.pollOperation({
251
- apiOrigin: api_1.extensionsOrigin,
251
+ apiOrigin: (0, api_1.extensionsOrigin)(),
252
252
  apiVersion: EXTENSIONS_API_VERSION,
253
253
  operationResourceName: createRes.body.name,
254
254
  masterTimeout: 600000,
@@ -353,7 +353,7 @@ async function ensureExtensionsApiEnabled(options) {
353
353
  if (!projectId) {
354
354
  return;
355
355
  }
356
- return await (0, ensureApiEnabled_1.ensure)(projectId, api_1.extensionsOrigin, "extensions", options.markdown);
356
+ return await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.extensionsOrigin)(), "extensions", options.markdown);
357
357
  }
358
358
  exports.ensureExtensionsApiEnabled = ensureExtensionsApiEnabled;
359
359
  async function ensureExtensionsPublisherApiEnabled(options) {
@@ -361,7 +361,7 @@ async function ensureExtensionsPublisherApiEnabled(options) {
361
361
  if (!projectId) {
362
362
  return;
363
363
  }
364
- return await (0, ensureApiEnabled_1.ensure)(projectId, api_1.extensionsPublisherOrigin, "extensions", options.markdown);
364
+ return await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.extensionsPublisherOrigin)(), "extensions", options.markdown);
365
365
  }
366
366
  exports.ensureExtensionsPublisherApiEnabled = ensureExtensionsPublisherApiEnabled;
367
367
  async function archiveAndUploadSource(extPath, bucketName) {
@@ -674,7 +674,7 @@ async function uploadExtensionVersionFromLocalSource(args) {
674
674
  uploadSpinner.start();
675
675
  objectPath = await archiveAndUploadSource(args.rootDirectory, exports.EXTENSIONS_BUCKET_NAME);
676
676
  uploadSpinner.succeed("Uploaded extension source code");
677
- packageUri = api_1.storageOrigin + objectPath + "?alt=media";
677
+ packageUri = (0, api_1.storageOrigin)() + objectPath + "?alt=media";
678
678
  }
679
679
  catch (err) {
680
680
  uploadSpinner.fail();
@@ -713,7 +713,7 @@ async function createSourceFromLocation(projectId, sourceUri) {
713
713
  spinner.start();
714
714
  objectPath = await archiveAndUploadSource(sourceUri, exports.EXTENSIONS_BUCKET_NAME);
715
715
  spinner.succeed(" Uploaded extension source code");
716
- packageUri = api_1.storageOrigin + objectPath + "?alt=media";
716
+ packageUri = (0, api_1.storageOrigin)() + objectPath + "?alt=media";
717
717
  const res = await (0, extensionsApi_1.createSource)(projectId, packageUri, extensionRoot);
718
718
  logger_1.logger.debug("Created new Extension Source %s", res.name);
719
719
  await deleteUploadedSource(objectPath);
@@ -92,7 +92,7 @@ function getTriggerType(propertiesYaml) {
92
92
  }
93
93
  async function isStorageProvisioned(projectId) {
94
94
  var _a, _b;
95
- const client = new apiv2_1.Client({ urlPrefix: api_1.firebaseStorageOrigin, apiVersion: "v1beta" });
95
+ const client = new apiv2_1.Client({ urlPrefix: (0, api_1.firebaseStorageOrigin)(), apiVersion: "v1beta" });
96
96
  const resp = await client.get(`/projects/${projectId}/buckets`);
97
97
  return !!((_b = (_a = resp.body) === null || _a === void 0 ? void 0 : _a.buckets) === null || _b === void 0 ? void 0 : _b.find((bucket) => {
98
98
  const bucketResourceName = bucket.name;
@@ -103,7 +103,7 @@ async function isStorageProvisioned(projectId) {
103
103
  }
104
104
  async function isAuthProvisioned(projectId) {
105
105
  var _a, _b;
106
- const client = new apiv2_1.Client({ urlPrefix: api_1.firedataOrigin, apiVersion: "v1" });
106
+ const client = new apiv2_1.Client({ urlPrefix: (0, api_1.firedataOrigin)(), apiVersion: "v1" });
107
107
  const resp = await client.get(`/projects/${projectId}/products`);
108
108
  return !!((_b = (_a = resp.body) === null || _a === void 0 ? void 0 : _a.activation) === null || _b === void 0 ? void 0 : _b.map((a) => a.service).includes("FIREBASE_AUTH"));
109
109
  }
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.consoleInstallLink = void 0;
4
4
  const api_1 = require("../api");
5
5
  function consoleInstallLink(extVersionRef) {
6
- return `${api_1.consoleOrigin}/project/_/extensions/install?ref=${extVersionRef}`;
6
+ return `${(0, api_1.consoleOrigin)()}/project/_/extensions/install?ref=${extVersionRef}`;
7
7
  }
8
8
  exports.consoleInstallLink = consoleInstallLink;