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.
- package/lib/accountExporter.js +1 -1
- package/lib/accountImporter.js +1 -1
- package/lib/api.js +112 -58
- package/lib/apiv2.js +3 -1
- package/lib/appdistribution/client.js +4 -4
- package/lib/apphosting/config.js +31 -0
- package/lib/apphosting/githubConnections.js +261 -0
- package/lib/{init/features/apphosting → apphosting}/index.js +26 -22
- package/lib/{init/features/apphosting → apphosting}/repo.js +25 -13
- package/lib/apphosting/secrets/dialogs.js +169 -0
- package/lib/apphosting/secrets/index.js +98 -0
- package/lib/auth.js +17 -17
- package/lib/commands/apphosting-backends-create.js +4 -2
- package/lib/commands/apphosting-backends-delete.js +1 -1
- package/lib/commands/apphosting-secrets-describe.js +29 -0
- package/lib/commands/apphosting-secrets-grantaccess.js +45 -0
- package/lib/commands/apphosting-secrets-set.js +102 -0
- package/lib/commands/functions-secrets-access.js +2 -2
- package/lib/commands/functions-secrets-describe.js +14 -0
- package/lib/commands/functions-secrets-destroy.js +2 -2
- package/lib/commands/functions-secrets-get.js +3 -17
- package/lib/commands/functions-secrets-prune.js +2 -1
- package/lib/commands/functions-secrets-set.js +2 -2
- package/lib/commands/hosting-disable.js +1 -1
- package/lib/commands/index.js +5 -0
- package/lib/commands/open.js +1 -1
- package/lib/database/metadata.js +3 -3
- package/lib/defaultCredentials.js +2 -2
- package/lib/deploy/extensions/v2FunctionHelper.js +1 -1
- package/lib/deploy/functions/build.js +1 -1
- package/lib/deploy/functions/checkIam.js +3 -6
- package/lib/deploy/functions/containerCleaner.js +5 -15
- package/lib/deploy/functions/deploy.js +8 -2
- package/lib/deploy/functions/ensure.js +1 -1
- package/lib/deploy/functions/params.js +2 -2
- package/lib/deploy/functions/prepare.js +16 -7
- package/lib/deploy/functions/release/fabricator.js +8 -8
- package/lib/deploy/functions/runtimes/discovery/index.js +2 -2
- package/lib/deploy/functions/runtimes/index.js +6 -43
- package/lib/deploy/functions/runtimes/node/index.js +3 -2
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +15 -34
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +2 -2
- package/lib/deploy/functions/runtimes/python/index.js +11 -7
- package/lib/deploy/functions/runtimes/supported.js +135 -0
- package/lib/deploy/hosting/uploader.js +1 -1
- package/lib/deploy/index.js +1 -1
- package/lib/deploy/remoteconfig/functions.js +1 -1
- package/lib/emulator/adminSdkConfig.js +1 -1
- package/lib/emulator/controller.js +8 -1
- package/lib/emulator/downloadableEmulators.js +6 -6
- package/lib/emulator/functionsEmulator.js +2 -2
- package/lib/emulator/hub.js +5 -0
- package/lib/ensureApiEnabled.js +1 -1
- package/lib/extensions/emulator/specHelper.js +4 -3
- package/lib/extensions/extensionsApi.js +5 -5
- package/lib/extensions/extensionsHelper.js +4 -4
- package/lib/extensions/provisioningHelper.js +2 -2
- package/lib/extensions/publishHelpers.js +1 -1
- package/lib/extensions/publisherApi.js +3 -3
- package/lib/extensions/resolveSource.js +1 -1
- package/lib/extensions/secretsUtils.js +1 -1
- package/lib/extensions/tos.js +1 -1
- package/lib/fetchMOTD.js +1 -1
- package/lib/fetchWebSetup.js +2 -2
- package/lib/firestore/api-sort.js +17 -0
- package/lib/firestore/api.js +9 -2
- package/lib/firestore/checkDatabaseType.js +1 -1
- package/lib/firestore/delete.js +1 -1
- package/lib/firestore/pretty-print.js +11 -2
- package/lib/functional.js +2 -2
- package/lib/functions/secrets.js +42 -24
- package/lib/functionsConfig.js +1 -1
- package/lib/gcp/apphosting.js +17 -4
- package/lib/gcp/artifactregistry.js +1 -1
- package/lib/gcp/auth.js +1 -1
- package/lib/gcp/cloudbilling.js +1 -1
- package/lib/gcp/cloudbuild.js +8 -4
- package/lib/gcp/cloudfunctions.js +6 -6
- package/lib/gcp/cloudfunctionsv2.js +4 -4
- package/lib/gcp/cloudlogging.js +1 -1
- package/lib/gcp/cloudmonitoring.js +1 -1
- package/lib/gcp/cloudscheduler.js +3 -3
- package/lib/gcp/cloudtasks.js +1 -1
- package/lib/gcp/computeEngine.js +7 -0
- package/lib/gcp/devConnect.js +45 -22
- package/lib/gcp/eventarc.js +1 -1
- package/lib/gcp/firestore.js +2 -2
- package/lib/gcp/iam.js +11 -3
- package/lib/gcp/identityPlatform.js +1 -1
- package/lib/gcp/pubsub.js +1 -1
- package/lib/gcp/resourceManager.js +2 -1
- package/lib/gcp/rules.js +1 -1
- package/lib/gcp/run.js +1 -1
- package/lib/gcp/runtimeconfig.js +1 -1
- package/lib/gcp/secretManager.js +54 -14
- package/lib/gcp/serviceusage.js +21 -5
- package/lib/gcp/storage.js +12 -8
- package/lib/hosting/api.js +2 -2
- package/lib/hosting/cloudRunProxy.js +1 -1
- package/lib/init/features/database.js +1 -1
- package/lib/init/features/extensions/index.js +1 -1
- package/lib/init/features/functions/index.js +2 -2
- package/lib/init/features/functions/python.js +4 -3
- package/lib/init/features/hosting/github.js +4 -3
- package/lib/init/features/index.js +1 -1
- package/lib/management/apps.js +4 -4
- package/lib/management/database.js +1 -1
- package/lib/management/projects.js +4 -4
- package/lib/remoteconfig/get.js +1 -1
- package/lib/remoteconfig/rollback.js +1 -1
- package/lib/remoteconfig/versionslist.js +1 -1
- package/lib/shortenUrl.js +2 -2
- package/lib/utils.js +1 -1
- package/package.json +1 -1
- package/schema/firebase-config.json +12 -2
- /package/lib/{init/features/apphosting → apphosting}/constants.js +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const tty = require("tty");
|
|
5
|
+
const clc = require("colorette");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const command_1 = require("../command");
|
|
8
|
+
const projectUtils_1 = require("../projectUtils");
|
|
9
|
+
const requireAuth_1 = require("../requireAuth");
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const gcsm = require("../gcp/secretManager");
|
|
12
|
+
const apphosting = require("../gcp/apphosting");
|
|
13
|
+
const requirePermissions_1 = require("../requirePermissions");
|
|
14
|
+
const prompt_1 = require("../prompt");
|
|
15
|
+
const secrets = require("../apphosting/secrets");
|
|
16
|
+
const dialogs = require("../apphosting/secrets/dialogs");
|
|
17
|
+
const config = require("../apphosting/config");
|
|
18
|
+
const utils_1 = require("../utils");
|
|
19
|
+
exports.command = new command_1.Command("apphosting:secrets:set <secretName>")
|
|
20
|
+
.description("grant service accounts permissions to the provided secret")
|
|
21
|
+
.option("-l, --location <location>", "optional location to retrict secret replication")
|
|
22
|
+
.withForce("Automatically create a secret, grant permissions, and add to YAML.")
|
|
23
|
+
.before(requireAuth_1.requireAuth)
|
|
24
|
+
.before(gcsm.ensureApi)
|
|
25
|
+
.before(apphosting.ensureApiEnabled)
|
|
26
|
+
.before(requirePermissions_1.requirePermissions, [
|
|
27
|
+
"secretmanager.secrets.create",
|
|
28
|
+
"secretmanager.secrets.get",
|
|
29
|
+
"secretmanager.secrets.update",
|
|
30
|
+
"secretmanager.versions.add",
|
|
31
|
+
"secretmanager.secrets.getIamPolicy",
|
|
32
|
+
"secretmanager.secrets.setIamPolicy",
|
|
33
|
+
])
|
|
34
|
+
.option("--data-file <dataFile>", 'File path from which to read secret data. Set to "-" to read the secret data from stdin.')
|
|
35
|
+
.action(async (secretName, options) => {
|
|
36
|
+
var _a;
|
|
37
|
+
const howToAccess = `You can access the contents of the secret's latest value with ${clc.bold(`firebase apphosting:secrets:access ${secretName}`)}`;
|
|
38
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
39
|
+
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
40
|
+
const created = secrets.upsertSecret(projectId, secretName, options.location);
|
|
41
|
+
if (created === null) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let secretValue;
|
|
45
|
+
if ((!options.dataFile || options.dataFile === "-") && tty.isatty(0)) {
|
|
46
|
+
secretValue = await (0, prompt_1.promptOnce)({
|
|
47
|
+
type: "password",
|
|
48
|
+
message: `Enter a value for ${secretName}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
let dataFile = 0;
|
|
53
|
+
if (options.dataFile && options.dataFile !== "-") {
|
|
54
|
+
dataFile = options.dataFile;
|
|
55
|
+
}
|
|
56
|
+
secretValue = fs.readFileSync(dataFile, "utf-8");
|
|
57
|
+
}
|
|
58
|
+
if (!created) {
|
|
59
|
+
const version = await gcsm.addVersion(projectId, secretName, secretValue);
|
|
60
|
+
(0, utils_1.logSuccess)(`Created new secret version ${gcsm.toSecretVersionResourceName(version)}`);
|
|
61
|
+
(0, utils_1.logSuccess)(howToAccess);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
(0, utils_1.logSuccess)(`Created new secret projects/${projectId}/secrets/${secretName}`);
|
|
65
|
+
(0, utils_1.logSuccess)(howToAccess);
|
|
66
|
+
const accounts = await dialogs.selectBackendServiceAccounts(projectNumber, projectId, options);
|
|
67
|
+
if (!accounts.buildServiceAccounts.length && !accounts.runServiceAccounts.length) {
|
|
68
|
+
(0, utils_1.logWarning)(`To use this secret your backend, you must grant access. You can do so in the future with ${clc.bold("firebase apphosting:secrets:grantAccess")}`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
await secrets.grantSecretAccess(projectId, secretName, accounts);
|
|
72
|
+
}
|
|
73
|
+
let path = config.yamlPath(process.cwd());
|
|
74
|
+
let yaml = {};
|
|
75
|
+
if (path) {
|
|
76
|
+
yaml = config.load(path);
|
|
77
|
+
if ((_a = yaml.env) === null || _a === void 0 ? void 0 : _a.find((env) => env.variable === secretName)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const addToYaml = await (0, prompt_1.confirm)({
|
|
82
|
+
message: "Would you like to add this secret to apphosting.yaml?",
|
|
83
|
+
default: true,
|
|
84
|
+
});
|
|
85
|
+
if (!addToYaml) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (!path) {
|
|
89
|
+
path = await (0, prompt_1.promptOnce)({
|
|
90
|
+
message: "It looks like you don't have an apphosting.yaml yet. Where would you like to store it?",
|
|
91
|
+
default: process.cwd(),
|
|
92
|
+
});
|
|
93
|
+
path = (0, path_1.join)(path, "apphosting.yaml");
|
|
94
|
+
}
|
|
95
|
+
const envName = await dialogs.envVarForSecret(secretName);
|
|
96
|
+
yaml.env = yaml.env || [];
|
|
97
|
+
yaml.env.push({
|
|
98
|
+
variable: envName,
|
|
99
|
+
secret: secretName,
|
|
100
|
+
});
|
|
101
|
+
config.store(path, yaml);
|
|
102
|
+
});
|
|
@@ -6,11 +6,11 @@ const logger_1 = require("../logger");
|
|
|
6
6
|
const projectUtils_1 = require("../projectUtils");
|
|
7
7
|
const secretManager_1 = require("../gcp/secretManager");
|
|
8
8
|
const requireAuth_1 = require("../requireAuth");
|
|
9
|
-
const
|
|
9
|
+
const secretManager = require("../gcp/secretManager");
|
|
10
10
|
exports.command = new command_1.Command("functions:secrets:access <KEY>[@version]")
|
|
11
11
|
.description("Access secret value given secret and its version. Defaults to accessing the latest version.")
|
|
12
12
|
.before(requireAuth_1.requireAuth)
|
|
13
|
-
.before(
|
|
13
|
+
.before(secretManager.ensureApi)
|
|
14
14
|
.action(async (key, options) => {
|
|
15
15
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
16
16
|
let [name, version] = key.split("@");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const requireAuth_1 = require("../requireAuth");
|
|
5
|
+
const command_1 = require("../command");
|
|
6
|
+
const requirePermissions_1 = require("../requirePermissions");
|
|
7
|
+
const secretManager = require("../gcp/secretManager");
|
|
8
|
+
const secrets = require("../functions/secrets");
|
|
9
|
+
exports.command = new command_1.Command("functions:secrets:describe <KEY>")
|
|
10
|
+
.description("Get metadata for secret and its versions. Alias for functions:secrets:get to align with gcloud")
|
|
11
|
+
.before(requireAuth_1.requireAuth)
|
|
12
|
+
.before(secretManager.ensureApi)
|
|
13
|
+
.before(requirePermissions_1.requirePermissions, ["secretmanager.secrets.get"])
|
|
14
|
+
.action(secrets.describeSecret);
|
|
@@ -13,7 +13,7 @@ exports.command = new command_1.Command("functions:secrets:destroy <KEY>[@versio
|
|
|
13
13
|
.description("Destroy a secret. Defaults to destroying the latest version.")
|
|
14
14
|
.withForce("Destroys a secret without confirmation.")
|
|
15
15
|
.before(requireAuth_1.requireAuth)
|
|
16
|
-
.before(
|
|
16
|
+
.before(secretManager_1.ensureApi)
|
|
17
17
|
.action(async (key, options) => {
|
|
18
18
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
19
19
|
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
@@ -54,7 +54,7 @@ exports.command = new command_1.Command("functions:secrets:destroy <KEY>[@versio
|
|
|
54
54
|
await (0, secretManager_1.destroySecretVersion)(projectId, name, version);
|
|
55
55
|
(0, utils_1.logBullet)(`Destroyed secret version ${name}@${sv.versionId}`);
|
|
56
56
|
const secret = await (0, secretManager_1.getSecret)(projectId, name);
|
|
57
|
-
if (
|
|
57
|
+
if ((0, secretManager_1.isFunctionsManaged)(secret)) {
|
|
58
58
|
const versions = await (0, secretManager_1.listSecretVersions)(projectId, name);
|
|
59
59
|
if (versions.filter((v) => v.state === "ENABLED").length === 0) {
|
|
60
60
|
(0, utils_1.logBullet)(`No active secret versions left. Destroying secret ${name}`);
|
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
|
-
const Table = require("cli-table");
|
|
5
4
|
const requireAuth_1 = require("../requireAuth");
|
|
6
5
|
const command_1 = require("../command");
|
|
7
|
-
const logger_1 = require("../logger");
|
|
8
|
-
const projectUtils_1 = require("../projectUtils");
|
|
9
|
-
const secretManager_1 = require("../gcp/secretManager");
|
|
10
6
|
const requirePermissions_1 = require("../requirePermissions");
|
|
7
|
+
const secretManager = require("../gcp/secretManager");
|
|
11
8
|
const secrets = require("../functions/secrets");
|
|
12
9
|
exports.command = new command_1.Command("functions:secrets:get <KEY>")
|
|
13
10
|
.description("Get metadata for secret and its versions")
|
|
14
11
|
.before(requireAuth_1.requireAuth)
|
|
15
|
-
.before(
|
|
12
|
+
.before(secretManager.ensureApi)
|
|
16
13
|
.before(requirePermissions_1.requirePermissions, ["secretmanager.secrets.get"])
|
|
17
|
-
.action(
|
|
18
|
-
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
19
|
-
const versions = await (0, secretManager_1.listSecretVersions)(projectId, key);
|
|
20
|
-
const table = new Table({
|
|
21
|
-
head: ["Version", "State"],
|
|
22
|
-
style: { head: ["yellow"] },
|
|
23
|
-
});
|
|
24
|
-
for (const version of versions) {
|
|
25
|
-
table.push([version.versionId, version.state]);
|
|
26
|
-
}
|
|
27
|
-
logger_1.logger.info(table.toString());
|
|
28
|
-
});
|
|
14
|
+
.action(secrets.describeSecret);
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.command = void 0;
|
|
4
4
|
const backend = require("../deploy/functions/backend");
|
|
5
5
|
const secrets = require("../functions/secrets");
|
|
6
|
+
const secretManager = require("../gcp/secretManager");
|
|
6
7
|
const command_1 = require("../command");
|
|
7
8
|
const projectUtils_1 = require("../projectUtils");
|
|
8
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
@@ -15,7 +16,7 @@ exports.command = new command_1.Command("functions:secrets:prune")
|
|
|
15
16
|
.withForce("Destroys unused secrets without prompt")
|
|
16
17
|
.description("Destroys unused secrets")
|
|
17
18
|
.before(requireAuth_1.requireAuth)
|
|
18
|
-
.before(
|
|
19
|
+
.before(secretManager.ensureApi)
|
|
19
20
|
.before(requirePermissions_1.requirePermissions, [
|
|
20
21
|
"cloudfunctions.functions.list",
|
|
21
22
|
"secretmanager.secrets.list",
|
|
@@ -20,7 +20,7 @@ exports.command = new command_1.Command("functions:secrets:set <KEY>")
|
|
|
20
20
|
.description("Create or update a secret for use in Cloud Functions for Firebase.")
|
|
21
21
|
.withForce("Automatically updates functions to use the new secret.")
|
|
22
22
|
.before(requireAuth_1.requireAuth)
|
|
23
|
-
.before(
|
|
23
|
+
.before(secretManager_1.ensureApi)
|
|
24
24
|
.before(requirePermissions_1.requirePermissions, [
|
|
25
25
|
"secretmanager.secrets.create",
|
|
26
26
|
"secretmanager.secrets.get",
|
|
@@ -50,7 +50,7 @@ exports.command = new command_1.Command("functions:secrets:set <KEY>")
|
|
|
50
50
|
}
|
|
51
51
|
const secretVersion = await (0, secretManager_1.addVersion)(projectId, key, secretValue);
|
|
52
52
|
(0, utils_1.logSuccess)(`Created a new secret version ${(0, secretManager_1.toSecretVersionResourceName)(secretVersion)}`);
|
|
53
|
-
if (!
|
|
53
|
+
if (!(0, secretManager_1.isFunctionsManaged)(secret)) {
|
|
54
54
|
(0, utils_1.logBullet)("Please deploy your functions for the change to take effect by running:\n\t" +
|
|
55
55
|
clc.bold("firebase deploy --only functions"));
|
|
56
56
|
return;
|
|
@@ -25,7 +25,7 @@ exports.command = new command_1.Command("hosting:disable")
|
|
|
25
25
|
if (!confirm) {
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
-
const c = new apiv2_1.Client({ urlPrefix: api_1.hostingApiOrigin, apiVersion: "v1beta1", auth: true });
|
|
28
|
+
const c = new apiv2_1.Client({ urlPrefix: (0, api_1.hostingApiOrigin)(), apiVersion: "v1beta1", auth: true });
|
|
29
29
|
await c.post(`/sites/${siteToDisable}/releases`, { type: "SITE_DISABLE" });
|
|
30
30
|
utils.logSuccess(`Hosting has been disabled for ${clc.bold(siteToDisable)}. Deploy a new version to re-enable.`);
|
|
31
31
|
});
|
package/lib/commands/index.js
CHANGED
|
@@ -129,6 +129,7 @@ function load(client) {
|
|
|
129
129
|
client.functions.secrets.access = loadCommand("functions-secrets-access");
|
|
130
130
|
client.functions.secrets.destroy = loadCommand("functions-secrets-destroy");
|
|
131
131
|
client.functions.secrets.get = loadCommand("functions-secrets-get");
|
|
132
|
+
client.functions.secrets.describe = loadCommand("functions-secrets-describe");
|
|
132
133
|
client.functions.secrets.prune = loadCommand("functions-secrets-prune");
|
|
133
134
|
client.functions.secrets.set = loadCommand("functions-secrets-set");
|
|
134
135
|
client.help = loadCommand("help");
|
|
@@ -164,6 +165,10 @@ function load(client) {
|
|
|
164
165
|
client.apphosting.builds = {};
|
|
165
166
|
client.apphosting.builds.get = loadCommand("apphosting-builds-get");
|
|
166
167
|
client.apphosting.builds.create = loadCommand("apphosting-builds-create");
|
|
168
|
+
client.apphosting.secrets = {};
|
|
169
|
+
client.apphosting.secrets.set = loadCommand("apphosting-secrets-set");
|
|
170
|
+
client.apphosting.secrets.grantaccess = loadCommand("apphosting-secrets-grantaccess");
|
|
171
|
+
client.apphosting.secrets.describe = loadCommand("apphosting-secrets-describe");
|
|
167
172
|
client.apphosting.rollouts = {};
|
|
168
173
|
client.apphosting.rollouts.create = loadCommand("apphosting-rollouts-create");
|
|
169
174
|
client.apphosting.rollouts.list = loadCommand("apphosting-rollouts-list");
|
package/lib/commands/open.js
CHANGED
|
@@ -82,7 +82,7 @@ exports.command = new command_1.Command("open [link]")
|
|
|
82
82
|
url = link.url;
|
|
83
83
|
}
|
|
84
84
|
else if (link.arg === "hosting:site") {
|
|
85
|
-
url = utils.addSubdomain(api.hostingOrigin, options.site);
|
|
85
|
+
url = utils.addSubdomain(api.hostingOrigin(), options.site);
|
|
86
86
|
}
|
|
87
87
|
else if (link.arg === "functions:log") {
|
|
88
88
|
url = `https://console.developers.google.com/logs/viewer?resource=cloudfunctions.googleapis.com&project=${options.project}`;
|
package/lib/database/metadata.js
CHANGED
|
@@ -14,7 +14,7 @@ function handleErrorResponse(response) {
|
|
|
14
14
|
code: 2,
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
const apiClient = new apiv2_1.Client({ urlPrefix: api_1.rtdbMetadataOrigin });
|
|
17
|
+
const apiClient = new apiv2_1.Client({ urlPrefix: (0, api_1.rtdbMetadataOrigin)() });
|
|
18
18
|
async function listAllRulesets(databaseName) {
|
|
19
19
|
const response = await apiClient.get(`/namespaces/${databaseName}/rulesets`, { resolveOnHTTPError: true });
|
|
20
20
|
if (response.status === 200) {
|
|
@@ -43,7 +43,7 @@ async function getRulesetLabels(databaseName) {
|
|
|
43
43
|
exports.getRulesetLabels = getRulesetLabels;
|
|
44
44
|
async function createRuleset(databaseName, source) {
|
|
45
45
|
const localApiClient = new apiv2_1.Client({
|
|
46
|
-
urlPrefix: utils.addSubdomain(api_1.realtimeOrigin, databaseName),
|
|
46
|
+
urlPrefix: utils.addSubdomain((0, api_1.realtimeOrigin)(), databaseName),
|
|
47
47
|
});
|
|
48
48
|
const response = await localApiClient.post(`/.settings/rulesets.json`, source, { resolveOnHTTPError: true });
|
|
49
49
|
if (response.status === 200) {
|
|
@@ -54,7 +54,7 @@ async function createRuleset(databaseName, source) {
|
|
|
54
54
|
exports.createRuleset = createRuleset;
|
|
55
55
|
async function setRulesetLabels(databaseName, labels) {
|
|
56
56
|
const localApiClient = new apiv2_1.Client({
|
|
57
|
-
urlPrefix: utils.addSubdomain(api_1.realtimeOrigin, databaseName),
|
|
57
|
+
urlPrefix: utils.addSubdomain((0, api_1.realtimeOrigin)(), databaseName),
|
|
58
58
|
});
|
|
59
59
|
const response = await localApiClient.put(`/.settings/ruleset_labels.json`, labels, {
|
|
60
60
|
resolveOnHTTPError: true,
|
|
@@ -43,8 +43,8 @@ exports.clearCredentials = clearCredentials;
|
|
|
43
43
|
function getCredential(tokens) {
|
|
44
44
|
if (tokens.refresh_token) {
|
|
45
45
|
return {
|
|
46
|
-
client_id: api_1.clientId,
|
|
47
|
-
client_secret: api_1.clientSecret,
|
|
46
|
+
client_id: (0, api_1.clientId)(),
|
|
47
|
+
client_secret: (0, api_1.clientSecret)(),
|
|
48
48
|
refresh_token: tokens.refresh_token,
|
|
49
49
|
type: "authorized_user",
|
|
50
50
|
};
|
|
@@ -17,7 +17,7 @@ async function checkSpecForV2Functions(i) {
|
|
|
17
17
|
exports.checkSpecForV2Functions = checkSpecForV2Functions;
|
|
18
18
|
async function ensureNecessaryV2ApisAndRoles(options) {
|
|
19
19
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
20
|
-
await (0, ensureApiEnabled_1.ensure)(projectId, api_1.computeOrigin, "extensions", options.markdown);
|
|
20
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.computeOrigin)(), "extensions", options.markdown);
|
|
21
21
|
await ensureComputeP4SARole(projectId);
|
|
22
22
|
}
|
|
23
23
|
exports.ensureNecessaryV2ApisAndRoles = ensureNecessaryV2ApisAndRoles;
|
|
@@ -171,7 +171,7 @@ function toBackend(build, paramValues) {
|
|
|
171
171
|
}
|
|
172
172
|
let regions = [];
|
|
173
173
|
if (!bdEndpoint.region) {
|
|
174
|
-
regions = [api.functionsDefaultRegion];
|
|
174
|
+
regions = [api.functionsDefaultRegion()];
|
|
175
175
|
}
|
|
176
176
|
else if (Array.isArray(bdEndpoint.region)) {
|
|
177
177
|
regions = params.resolveList(bdEndpoint.region, paramValues);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureServiceAgentRoles = exports.mergeBindings = exports.obtainDefaultComputeServiceAgentBindings = exports.obtainPubSubServiceAgentBindings = exports.
|
|
3
|
+
exports.ensureServiceAgentRoles = exports.mergeBindings = exports.obtainDefaultComputeServiceAgentBindings = exports.obtainPubSubServiceAgentBindings = exports.checkHttpIam = exports.checkServiceAccountIam = exports.EVENTARC_EVENT_RECEIVER_ROLE = exports.RUN_INVOKER_ROLE = exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = void 0;
|
|
4
4
|
const colorette_1 = require("colorette");
|
|
5
5
|
const logger_1 = require("../../logger");
|
|
6
6
|
const functionsDeployHelper_1 = require("./functionsDeployHelper");
|
|
7
7
|
const error_1 = require("../../error");
|
|
8
8
|
const functional_1 = require("../../functional");
|
|
9
9
|
const iam = require("../../gcp/iam");
|
|
10
|
+
const gce = require("../../gcp/computeEngine");
|
|
10
11
|
const backend = require("./backend");
|
|
11
12
|
const track_1 = require("../../track");
|
|
12
13
|
const utils = require("../../utils");
|
|
@@ -73,10 +74,6 @@ exports.checkHttpIam = checkHttpIam;
|
|
|
73
74
|
function getPubsubServiceAgent(projectNumber) {
|
|
74
75
|
return `service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`;
|
|
75
76
|
}
|
|
76
|
-
function getDefaultComputeServiceAgent(projectNumber) {
|
|
77
|
-
return `${projectNumber}-compute@developer.gserviceaccount.com`;
|
|
78
|
-
}
|
|
79
|
-
exports.getDefaultComputeServiceAgent = getDefaultComputeServiceAgent;
|
|
80
77
|
function reduceEventsToServices(services, endpoint) {
|
|
81
78
|
const service = (0, services_1.serviceForEndpoint)(endpoint);
|
|
82
79
|
if (service.requiredProjectBindings && !services.find((s) => s.name === service.name)) {
|
|
@@ -93,7 +90,7 @@ function obtainPubSubServiceAgentBindings(projectNumber) {
|
|
|
93
90
|
}
|
|
94
91
|
exports.obtainPubSubServiceAgentBindings = obtainPubSubServiceAgentBindings;
|
|
95
92
|
function obtainDefaultComputeServiceAgentBindings(projectNumber) {
|
|
96
|
-
const defaultComputeServiceAgent = `serviceAccount:${
|
|
93
|
+
const defaultComputeServiceAgent = `serviceAccount:${gce.getDefaultServiceAccount(projectNumber)}`;
|
|
97
94
|
const runInvokerBinding = {
|
|
98
95
|
role: exports.RUN_INVOKER_ROLE,
|
|
99
96
|
members: [defaultComputeServiceAgent],
|
|
@@ -49,7 +49,7 @@ async function cleanupBuildImages(haveFunctions, deletedFunctions, cleaners = {}
|
|
|
49
49
|
}));
|
|
50
50
|
cleanup.push(...deletedFunctions.map(async (func) => {
|
|
51
51
|
try {
|
|
52
|
-
await
|
|
52
|
+
await arCleaner.cleanupFunction(func);
|
|
53
53
|
}
|
|
54
54
|
catch (err) {
|
|
55
55
|
const path = `${func.project}/${func.region}/gcf-artifacts`;
|
|
@@ -106,17 +106,10 @@ class ArtifactRegistryCleaner {
|
|
|
106
106
|
}
|
|
107
107
|
await poller.pollOperation(Object.assign(Object.assign({}, ArtifactRegistryCleaner.POLLER_OPTIONS), { pollerName: `cleanup-${func.region}-${func.id}`, operationResourceName: op.name }));
|
|
108
108
|
}
|
|
109
|
-
async cleanupFunctionCache(func) {
|
|
110
|
-
const op = await artifactregistry.deletePackage(`${ArtifactRegistryCleaner.packagePath(func)}%2Fcache`);
|
|
111
|
-
if (op.done) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
await poller.pollOperation(Object.assign(Object.assign({}, ArtifactRegistryCleaner.POLLER_OPTIONS), { pollerName: `cleanup-cache-${func.region}-${func.id}`, operationResourceName: op.name }));
|
|
115
|
-
}
|
|
116
109
|
}
|
|
117
110
|
exports.ArtifactRegistryCleaner = ArtifactRegistryCleaner;
|
|
118
111
|
ArtifactRegistryCleaner.POLLER_OPTIONS = {
|
|
119
|
-
apiOrigin: api_1.artifactRegistryDomain,
|
|
112
|
+
apiOrigin: (0, api_1.artifactRegistryDomain)(),
|
|
120
113
|
apiVersion: artifactregistry.API_VERSION,
|
|
121
114
|
masterTimeout: 5 * 60 * 1000,
|
|
122
115
|
};
|
|
@@ -124,9 +117,6 @@ class NoopArtifactRegistryCleaner extends ArtifactRegistryCleaner {
|
|
|
124
117
|
cleanupFunction() {
|
|
125
118
|
return Promise.resolve();
|
|
126
119
|
}
|
|
127
|
-
cleanupFunctionCache() {
|
|
128
|
-
return Promise.resolve();
|
|
129
|
-
}
|
|
130
120
|
}
|
|
131
121
|
exports.NoopArtifactRegistryCleaner = NoopArtifactRegistryCleaner;
|
|
132
122
|
class ContainerRegistryCleaner {
|
|
@@ -136,7 +126,7 @@ class ContainerRegistryCleaner {
|
|
|
136
126
|
helper(location) {
|
|
137
127
|
const subdomain = docker.GCR_SUBDOMAIN_MAPPING[location] || "us";
|
|
138
128
|
if (!this.helpers[subdomain]) {
|
|
139
|
-
const origin = `https://${subdomain}.${api_1.containerRegistryDomain}`;
|
|
129
|
+
const origin = `https://${subdomain}.${(0, api_1.containerRegistryDomain)()}`;
|
|
140
130
|
this.helpers[subdomain] = new DockerHelper(origin);
|
|
141
131
|
}
|
|
142
132
|
return this.helpers[subdomain];
|
|
@@ -168,7 +158,7 @@ class ContainerRegistryCleaner {
|
|
|
168
158
|
exports.ContainerRegistryCleaner = ContainerRegistryCleaner;
|
|
169
159
|
function getHelper(cache, subdomain) {
|
|
170
160
|
if (!cache[subdomain]) {
|
|
171
|
-
cache[subdomain] = new DockerHelper(`https://${subdomain}.${api_1.containerRegistryDomain}`);
|
|
161
|
+
cache[subdomain] = new DockerHelper(`https://${subdomain}.${(0, api_1.containerRegistryDomain)()}`);
|
|
172
162
|
}
|
|
173
163
|
return cache[subdomain];
|
|
174
164
|
}
|
|
@@ -212,7 +202,7 @@ async function listGcfPaths(projectId, locations, dockerHelpers = {}) {
|
|
|
212
202
|
throw new error_1.FirebaseError(`Failed to search the following subdomains: ${failedSubdomains.join(",")}`);
|
|
213
203
|
}
|
|
214
204
|
return gcfDirs.map((loc) => {
|
|
215
|
-
return `${docker.GCR_SUBDOMAIN_MAPPING[loc]}.${api_1.containerRegistryDomain}/${projectId}/gcf/${loc}`;
|
|
205
|
+
return `${docker.GCR_SUBDOMAIN_MAPPING[loc]}.${(0, api_1.containerRegistryDomain)()}/${projectId}/gcf/${loc}`;
|
|
216
206
|
});
|
|
217
207
|
}
|
|
218
208
|
exports.listGcfPaths = listGcfPaths;
|
|
@@ -24,9 +24,12 @@ async function uploadSourceV1(projectId, source, wantBackend) {
|
|
|
24
24
|
file: source.functionsSourceV1,
|
|
25
25
|
stream: fs.createReadStream(source.functionsSourceV1),
|
|
26
26
|
};
|
|
27
|
+
if (process.env.GOOGLE_CLOUD_QUOTA_PROJECT) {
|
|
28
|
+
(0, utils_1.logLabeledWarning)("functions", "GOOGLE_CLOUD_QUTOA_PROJECT is not usable when uploading source for Cloud Functions.");
|
|
29
|
+
}
|
|
27
30
|
await gcs.upload(uploadOpts, uploadUrl, {
|
|
28
31
|
"x-goog-content-length-range": "0,104857600",
|
|
29
|
-
});
|
|
32
|
+
}, true);
|
|
30
33
|
return uploadUrl;
|
|
31
34
|
}
|
|
32
35
|
async function uploadSourceV2(projectId, source, wantBackend) {
|
|
@@ -40,7 +43,10 @@ async function uploadSourceV2(projectId, source, wantBackend) {
|
|
|
40
43
|
file: source.functionsSourceV2,
|
|
41
44
|
stream: fs.createReadStream(source.functionsSourceV2),
|
|
42
45
|
};
|
|
43
|
-
|
|
46
|
+
if (process.env.GOOGLE_CLOUD_QUOTA_PROJECT) {
|
|
47
|
+
(0, utils_1.logLabeledWarning)("functions", "GOOGLE_CLOUD_QUTOA_PROJECT is not usable when uploading source for Cloud Functions.");
|
|
48
|
+
}
|
|
49
|
+
await gcs.upload(uploadOpts, res.uploadUrl, undefined, true);
|
|
44
50
|
return res.storageSource;
|
|
45
51
|
}
|
|
46
52
|
async function uploadCodebase(context, codebase, wantBackend) {
|
|
@@ -54,7 +54,7 @@ function isPermissionError(e) {
|
|
|
54
54
|
}
|
|
55
55
|
async function cloudBuildEnabled(projectId) {
|
|
56
56
|
try {
|
|
57
|
-
await (0, ensureApiEnabled_1.ensure)(projectId, api_1.cloudbuildOrigin, "functions");
|
|
57
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.cloudbuildOrigin)(), "functions");
|
|
58
58
|
}
|
|
59
59
|
catch (e) {
|
|
60
60
|
if ((0, error_1.isBillingError)(e)) {
|
|
@@ -8,7 +8,7 @@ const functional_1 = require("../../functional");
|
|
|
8
8
|
const secretManager = require("../../gcp/secretManager");
|
|
9
9
|
const storage_1 = require("../../gcp/storage");
|
|
10
10
|
const cel_1 = require("./cel");
|
|
11
|
-
const
|
|
11
|
+
const secretManager_1 = require("../../gcp/secretManager");
|
|
12
12
|
function dependenciesCEL(expr) {
|
|
13
13
|
const deps = [];
|
|
14
14
|
const paramCapture = /{{ params\.(\w+) }}/g;
|
|
@@ -222,7 +222,7 @@ async function handleSecret(secretParam, projectId) {
|
|
|
222
222
|
type: "password",
|
|
223
223
|
message: `This secret will be stored in Cloud Secret Manager (https://cloud.google.com/secret-manager/pricing) as ${secretParam.name}. Enter a value for ${secretParam.label || secretParam.name}:`,
|
|
224
224
|
});
|
|
225
|
-
await secretManager.createSecret(projectId, secretParam.name, (0,
|
|
225
|
+
await secretManager.createSecret(projectId, secretParam.name, (0, secretManager_1.labels)());
|
|
226
226
|
await secretManager.addVersion(projectId, secretParam.name, secretValue);
|
|
227
227
|
return secretValue;
|
|
228
228
|
}
|
|
@@ -8,6 +8,7 @@ const ensureApiEnabled = require("../../ensureApiEnabled");
|
|
|
8
8
|
const functionsConfig = require("../../functionsConfig");
|
|
9
9
|
const functionsEnv = require("../../functions/env");
|
|
10
10
|
const runtimes = require("./runtimes");
|
|
11
|
+
const supported = require("./runtimes/supported");
|
|
11
12
|
const validate = require("./validate");
|
|
12
13
|
const ensure = require("./ensure");
|
|
13
14
|
const api_1 = require("../../api");
|
|
@@ -41,10 +42,10 @@ async function prepare(context, options, payload) {
|
|
|
41
42
|
(0, utils_1.logLabeledBullet)("functions", `preparing codebase ${clc.bold(codebase)} for deployment`);
|
|
42
43
|
}
|
|
43
44
|
const checkAPIsEnabled = await Promise.all([
|
|
44
|
-
ensureApiEnabled.ensure(projectId, api_1.functionsOrigin, "functions"),
|
|
45
|
-
ensureApiEnabled.check(projectId, api_1.runtimeconfigOrigin, "runtimeconfig", true),
|
|
45
|
+
ensureApiEnabled.ensure(projectId, (0, api_1.functionsOrigin)(), "functions"),
|
|
46
|
+
ensureApiEnabled.check(projectId, (0, api_1.runtimeconfigOrigin)(), "runtimeconfig", true),
|
|
46
47
|
ensure.cloudBuildEnabled(projectId),
|
|
47
|
-
ensureApiEnabled.ensure(projectId, api_1.artifactRegistryDomain, "artifactregistry"),
|
|
48
|
+
ensureApiEnabled.ensure(projectId, (0, api_1.artifactRegistryDomain)(), "artifactregistry"),
|
|
48
49
|
]);
|
|
49
50
|
const firebaseConfig = await functionsConfig.getFirebaseConfig(options);
|
|
50
51
|
context.firebaseConfig = firebaseConfig;
|
|
@@ -158,7 +159,7 @@ async function prepare(context, options, payload) {
|
|
|
158
159
|
return ensureApiEnabled.ensure(projectId, api, "functions", false);
|
|
159
160
|
}));
|
|
160
161
|
if (backend.someEndpoint(wantBackend, (e) => e.platform === "gcfv2")) {
|
|
161
|
-
const V2_APIS = [api_1.cloudRunApiOrigin, api_1.eventarcOrigin, api_1.pubsubOrigin, api_1.storageOrigin];
|
|
162
|
+
const V2_APIS = [(0, api_1.cloudRunApiOrigin)(), (0, api_1.eventarcOrigin)(), (0, api_1.pubsubOrigin)(), (0, api_1.storageOrigin)()];
|
|
162
163
|
const enablements = V2_APIS.map((api) => {
|
|
163
164
|
return ensureApiEnabled.ensure(context.projectId, api, "functions");
|
|
164
165
|
});
|
|
@@ -284,12 +285,20 @@ async function loadCodebases(config, options, firebaseConfig, runtimeConfig, fil
|
|
|
284
285
|
projectId,
|
|
285
286
|
sourceDir,
|
|
286
287
|
projectDir: options.config.projectDir,
|
|
287
|
-
runtime: codebaseConfig.runtime || "",
|
|
288
288
|
};
|
|
289
|
+
const firebaseJsonRuntime = codebaseConfig.runtime;
|
|
290
|
+
if (firebaseJsonRuntime && !supported.isRuntime(firebaseJsonRuntime)) {
|
|
291
|
+
throw new error_1.FirebaseError(`Functions codebase ${codebase} has invalid runtime ` +
|
|
292
|
+
`${firebaseJsonRuntime} specified in firebase.json. Valid values are: ` +
|
|
293
|
+
Object.keys(supported.RUNTIMES)
|
|
294
|
+
.map((s) => `- ${s}`)
|
|
295
|
+
.join("\n"));
|
|
296
|
+
}
|
|
289
297
|
const runtimeDelegate = await runtimes.getRuntimeDelegate(delegateContext);
|
|
290
|
-
logger_1.logger.debug(`Validating ${runtimeDelegate.
|
|
298
|
+
logger_1.logger.debug(`Validating ${runtimeDelegate.language} source`);
|
|
299
|
+
supported.guardVersionSupport(runtimeDelegate.runtime);
|
|
291
300
|
await runtimeDelegate.validate();
|
|
292
|
-
logger_1.logger.debug(`Building ${runtimeDelegate.
|
|
301
|
+
logger_1.logger.debug(`Building ${runtimeDelegate.language} source`);
|
|
293
302
|
await runtimeDelegate.build();
|
|
294
303
|
const firebaseEnvs = functionsEnv.loadFirebaseEnvs(firebaseConfig, projectId);
|
|
295
304
|
(0, utils_1.logLabeledBullet)("functions", `Loading and analyzing source code for codebase ${codebase} to determine what to deploy`);
|
|
@@ -7,7 +7,7 @@ const error_1 = require("../../../error");
|
|
|
7
7
|
const sourceTokenScraper_1 = require("./sourceTokenScraper");
|
|
8
8
|
const timer_1 = require("./timer");
|
|
9
9
|
const functional_1 = require("../../../functional");
|
|
10
|
-
const
|
|
10
|
+
const supported_1 = require("../runtimes/supported");
|
|
11
11
|
const api_1 = require("../../../api");
|
|
12
12
|
const logger_1 = require("../../../logger");
|
|
13
13
|
const backend = require("../backend");
|
|
@@ -25,22 +25,22 @@ const scheduler = require("../../../gcp/cloudscheduler");
|
|
|
25
25
|
const utils = require("../../../utils");
|
|
26
26
|
const services = require("../services");
|
|
27
27
|
const v1_1 = require("../../../functions/events/v1");
|
|
28
|
-
const
|
|
28
|
+
const gce = require("../../../gcp/computeEngine");
|
|
29
29
|
const functionsDeployHelper_1 = require("../functionsDeployHelper");
|
|
30
30
|
const gcfV1PollerOptions = {
|
|
31
|
-
apiOrigin: api_1.functionsOrigin,
|
|
31
|
+
apiOrigin: (0, api_1.functionsOrigin)(),
|
|
32
32
|
apiVersion: gcf.API_VERSION,
|
|
33
33
|
masterTimeout: 25 * 60 * 1000,
|
|
34
34
|
maxBackoff: 10000,
|
|
35
35
|
};
|
|
36
36
|
const gcfV2PollerOptions = {
|
|
37
|
-
apiOrigin: api_1.functionsV2Origin,
|
|
37
|
+
apiOrigin: (0, api_1.functionsV2Origin)(),
|
|
38
38
|
apiVersion: gcfV2.API_VERSION,
|
|
39
39
|
masterTimeout: 25 * 60 * 1000,
|
|
40
40
|
maxBackoff: 10000,
|
|
41
41
|
};
|
|
42
42
|
const eventarcPollerOptions = {
|
|
43
|
-
apiOrigin: api_1.eventarcOrigin,
|
|
43
|
+
apiOrigin: (0, api_1.eventarcOrigin)(),
|
|
44
44
|
apiVersion: "v1",
|
|
45
45
|
masterTimeout: 25 * 60 * 1000,
|
|
46
46
|
maxBackoff: 10000,
|
|
@@ -332,7 +332,7 @@ class Fabricator {
|
|
|
332
332
|
else if (backend.isScheduleTriggered(endpoint)) {
|
|
333
333
|
const invoker = endpoint.serviceAccount
|
|
334
334
|
? [endpoint.serviceAccount]
|
|
335
|
-
: [
|
|
335
|
+
: [gce.getDefaultServiceAccount(this.projectNumber)];
|
|
336
336
|
await this.executor
|
|
337
337
|
.run(() => run.setInvokerCreate(endpoint.project, serviceName, invoker))
|
|
338
338
|
.catch(rethrowAs(endpoint, "set invoker"));
|
|
@@ -415,7 +415,7 @@ class Fabricator {
|
|
|
415
415
|
else if (backend.isScheduleTriggered(endpoint)) {
|
|
416
416
|
invoker = endpoint.serviceAccount
|
|
417
417
|
? [endpoint.serviceAccount]
|
|
418
|
-
: [
|
|
418
|
+
: [gce.getDefaultServiceAccount(this.projectNumber)];
|
|
419
419
|
}
|
|
420
420
|
if (invoker) {
|
|
421
421
|
await this.executor
|
|
@@ -562,7 +562,7 @@ class Fabricator {
|
|
|
562
562
|
.catch(rethrowAs(endpoint, "unregister blocking trigger"));
|
|
563
563
|
}
|
|
564
564
|
logOpStart(op, endpoint) {
|
|
565
|
-
const runtime =
|
|
565
|
+
const runtime = supported_1.RUNTIMES[endpoint.runtime].friendly;
|
|
566
566
|
const platform = (0, functionsDeployHelper_1.getHumanFriendlyPlatformName)(endpoint.platform);
|
|
567
567
|
const label = helper.getFunctionLabel(endpoint);
|
|
568
568
|
utils.logLabeledBullet("functions", `${op} ${runtime} (${platform}) function ${clc.bold(label)}...`);
|
|
@@ -42,7 +42,7 @@ async function detectFromYaml(directory, project, runtime) {
|
|
|
42
42
|
}
|
|
43
43
|
logger_1.logger.debug("Found functions.yaml. Got spec:", text);
|
|
44
44
|
const parsed = yaml.load(text);
|
|
45
|
-
return yamlToBuild(parsed, project, api.functionsDefaultRegion, runtime);
|
|
45
|
+
return yamlToBuild(parsed, project, api.functionsDefaultRegion(), runtime);
|
|
46
46
|
}
|
|
47
47
|
exports.detectFromYaml = detectFromYaml;
|
|
48
48
|
async function detectFromPort(port, project, runtime, timeout = 10000) {
|
|
@@ -80,6 +80,6 @@ async function detectFromPort(port, project, runtime, timeout = 10000) {
|
|
|
80
80
|
logger_1.logger.debug("Failed to parse functions.yaml", err);
|
|
81
81
|
throw new error_1.FirebaseError(`Failed to load function definition from source: ${text}`);
|
|
82
82
|
}
|
|
83
|
-
return yamlToBuild(parsed, project, api.functionsDefaultRegion, runtime);
|
|
83
|
+
return yamlToBuild(parsed, project, api.functionsDefaultRegion(), runtime);
|
|
84
84
|
}
|
|
85
85
|
exports.detectFromPort = detectFromPort;
|