firebase-tools 12.4.6 → 12.4.7
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/commands/ext-configure.js +2 -1
- package/lib/commands/functions-secrets-access.js +2 -0
- package/lib/commands/functions-secrets-destroy.js +2 -0
- package/lib/commands/functions-secrets-get.js +2 -0
- package/lib/commands/functions-secrets-prune.js +3 -1
- package/lib/commands/functions-secrets-set.js +2 -0
- package/lib/emulator/functionsEmulatorShell.js +54 -22
- package/lib/extensions/paramHelper.js +24 -16
- package/lib/frameworks/utils.js +2 -3
- package/lib/functions/secrets.js +1 -1
- package/lib/gcp/iam.js +6 -1
- package/lib/init/features/hosting/github.js +9 -0
- package/lib/localFunction.js +27 -9
- package/lib/utils.js +2 -2
- package/package.json +1 -1
|
@@ -58,7 +58,8 @@ exports.command = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
58
58
|
instanceId,
|
|
59
59
|
projectDir: config.projectDir,
|
|
60
60
|
});
|
|
61
|
-
const
|
|
61
|
+
const params = ((_a = spec.params) !== null && _a !== void 0 ? _a : []).concat((_b = spec.systemParams) !== null && _b !== void 0 ? _b : []);
|
|
62
|
+
const [immutableParams, tbdParams] = (0, functional_1.partition)(params, (param) => { var _a; return (_a = (param.immutable && !!oldParamValues[param.param])) !== null && _a !== void 0 ? _a : false; });
|
|
62
63
|
infoImmutableParams(immutableParams, oldParamValues);
|
|
63
64
|
paramHelper.setNewDefaults(tbdParams, oldParamValues);
|
|
64
65
|
const mutableParamsBindingOptions = await paramHelper.getParams({
|
|
@@ -5,9 +5,11 @@ const command_1 = require("../command");
|
|
|
5
5
|
const logger_1 = require("../logger");
|
|
6
6
|
const projectUtils_1 = require("../projectUtils");
|
|
7
7
|
const secretManager_1 = require("../gcp/secretManager");
|
|
8
|
+
const requireAuth_1 = require("../requireAuth");
|
|
8
9
|
const secrets = require("../functions/secrets");
|
|
9
10
|
exports.command = new command_1.Command("functions:secrets:access <KEY>[@version]")
|
|
10
11
|
.description("Access secret value given secret and its version. Defaults to accessing the latest version.")
|
|
12
|
+
.before(requireAuth_1.requireAuth)
|
|
11
13
|
.before(secrets.ensureApi)
|
|
12
14
|
.action(async (key, options) => {
|
|
13
15
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
@@ -6,11 +6,13 @@ const projectUtils_1 = require("../projectUtils");
|
|
|
6
6
|
const secretManager_1 = require("../gcp/secretManager");
|
|
7
7
|
const prompt_1 = require("../prompt");
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
|
+
const requireAuth_1 = require("../requireAuth");
|
|
9
10
|
const secrets = require("../functions/secrets");
|
|
10
11
|
const backend = require("../deploy/functions/backend");
|
|
11
12
|
exports.command = new command_1.Command("functions:secrets:destroy <KEY>[@version]")
|
|
12
13
|
.description("Destroy a secret. Defaults to destroying the latest version.")
|
|
13
14
|
.withForce("Destroys a secret without confirmation.")
|
|
15
|
+
.before(requireAuth_1.requireAuth)
|
|
14
16
|
.before(secrets.ensureApi)
|
|
15
17
|
.action(async (key, options) => {
|
|
16
18
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
4
|
const Table = require("cli-table");
|
|
5
|
+
const requireAuth_1 = require("../requireAuth");
|
|
5
6
|
const command_1 = require("../command");
|
|
6
7
|
const logger_1 = require("../logger");
|
|
7
8
|
const projectUtils_1 = require("../projectUtils");
|
|
@@ -10,6 +11,7 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
10
11
|
const secrets = require("../functions/secrets");
|
|
11
12
|
exports.command = new command_1.Command("functions:secrets:get <KEY>")
|
|
12
13
|
.description("Get metadata for secret and its versions")
|
|
14
|
+
.before(requireAuth_1.requireAuth)
|
|
13
15
|
.before(secrets.ensureApi)
|
|
14
16
|
.before(requirePermissions_1.requirePermissions, ["secretmanager.secrets.get"])
|
|
15
17
|
.action(async (key, options) => {
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
4
|
const backend = require("../deploy/functions/backend");
|
|
5
|
+
const secrets = require("../functions/secrets");
|
|
5
6
|
const command_1 = require("../command");
|
|
6
7
|
const projectUtils_1 = require("../projectUtils");
|
|
7
|
-
const secrets = require("../functions/secrets");
|
|
8
8
|
const requirePermissions_1 = require("../requirePermissions");
|
|
9
9
|
const deploymentTool_1 = require("../deploymentTool");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const prompt_1 = require("../prompt");
|
|
12
12
|
const secretManager_1 = require("../gcp/secretManager");
|
|
13
|
+
const requireAuth_1 = require("../requireAuth");
|
|
13
14
|
exports.command = new command_1.Command("functions:secrets:prune")
|
|
14
15
|
.withForce("Destroys unused secrets without prompt")
|
|
15
16
|
.description("Destroys unused secrets")
|
|
17
|
+
.before(requireAuth_1.requireAuth)
|
|
16
18
|
.before(secrets.ensureApi)
|
|
17
19
|
.before(requirePermissions_1.requirePermissions, [
|
|
18
20
|
"cloudfunctions.functions.list",
|
|
@@ -13,11 +13,13 @@ const utils_1 = require("../utils");
|
|
|
13
13
|
const projectUtils_1 = require("../projectUtils");
|
|
14
14
|
const secretManager_1 = require("../gcp/secretManager");
|
|
15
15
|
const ensureApiEnabled_1 = require("../ensureApiEnabled");
|
|
16
|
+
const requireAuth_1 = require("../requireAuth");
|
|
16
17
|
const secrets = require("../functions/secrets");
|
|
17
18
|
const backend = require("../deploy/functions/backend");
|
|
18
19
|
exports.command = new command_1.Command("functions:secrets:set <KEY>")
|
|
19
20
|
.description("Create or update a secret for use in Cloud Functions for Firebase.")
|
|
20
21
|
.withForce("Automatically updates functions to use the new secret.")
|
|
22
|
+
.before(requireAuth_1.requireAuth)
|
|
21
23
|
.before(secrets.ensureApi)
|
|
22
24
|
.before(requirePermissions_1.requirePermissions, [
|
|
23
25
|
"secretmanager.secrets.create",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FunctionsEmulatorShell = void 0;
|
|
4
4
|
const uuid = require("uuid");
|
|
5
|
-
const functionsEmulator_1 = require("./functionsEmulator");
|
|
6
5
|
const utils = require("../utils");
|
|
6
|
+
const functionsEmulator_1 = require("./functionsEmulator");
|
|
7
7
|
const logger_1 = require("../logger");
|
|
8
8
|
const error_1 = require("../error");
|
|
9
9
|
class FunctionsEmulatorShell {
|
|
@@ -20,37 +20,69 @@ class FunctionsEmulatorShell {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
logger_1.logger.debug(`shell:${name}: trigger=${JSON.stringify(trigger)}`);
|
|
26
|
-
logger_1.logger.debug(`shell:${name}: opts=${JSON.stringify(opts)}, data=${JSON.stringify(data)}`);
|
|
27
|
-
if (!trigger.eventTrigger) {
|
|
28
|
-
throw new error_1.FirebaseError(`Function ${name} is not a background function`);
|
|
29
|
-
}
|
|
30
|
-
const eventType = trigger.eventTrigger.eventType;
|
|
23
|
+
createLegacyEvent(eventTrigger, data, opts) {
|
|
24
|
+
var _a, _b;
|
|
31
25
|
let resource = opts.resource;
|
|
32
26
|
if (typeof resource === "object" && resource.name) {
|
|
33
27
|
resource = resource.name;
|
|
34
28
|
}
|
|
35
|
-
|
|
29
|
+
return {
|
|
36
30
|
eventId: uuid.v4(),
|
|
37
31
|
timestamp: new Date().toISOString(),
|
|
38
|
-
eventType,
|
|
39
|
-
resource,
|
|
32
|
+
eventType: eventTrigger.eventType,
|
|
33
|
+
resource: resource,
|
|
40
34
|
params: opts.params,
|
|
41
|
-
auth: opts.auth,
|
|
35
|
+
auth: { admin: ((_a = opts.auth) === null || _a === void 0 ? void 0 : _a.admin) || false, variable: (_b = opts.auth) === null || _b === void 0 ? void 0 : _b.variable },
|
|
42
36
|
data,
|
|
43
37
|
};
|
|
44
|
-
this.emu.sendRequest(trigger, proto);
|
|
45
38
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
createCloudEvent(eventTrigger, data, opts) {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const ce = {
|
|
42
|
+
specversion: "1.0",
|
|
43
|
+
datacontenttype: "application/json",
|
|
44
|
+
id: uuid.v4(),
|
|
45
|
+
type: eventTrigger.eventType,
|
|
46
|
+
time: new Date().toISOString(),
|
|
47
|
+
source: "",
|
|
48
|
+
data,
|
|
49
|
+
};
|
|
50
|
+
if (eventTrigger.eventType.startsWith("google.cloud.storage")) {
|
|
51
|
+
ce.source = `projects/_/buckets/${(_a = eventTrigger.eventFilters) === null || _a === void 0 ? void 0 : _a.bucket}`;
|
|
52
|
+
}
|
|
53
|
+
else if (eventTrigger.eventType.startsWith("google.cloud.pubsub")) {
|
|
54
|
+
ce.source = eventTrigger.eventFilters.topic;
|
|
55
|
+
data = Object.assign(Object.assign({}, data), { messageId: uuid.v4() });
|
|
56
|
+
}
|
|
57
|
+
else if (eventTrigger.eventType.startsWith("google.cloud.firestore")) {
|
|
58
|
+
ce.source = `projects/_/databases/(default)`;
|
|
59
|
+
if (opts.resource) {
|
|
60
|
+
ce.document = opts.resource;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (eventTrigger.eventType.startsWith("google.firebase.database")) {
|
|
64
|
+
ce.source = `projects/_/locations/_/instances/${(_b = eventTrigger.eventFilterPathPatterns) === null || _b === void 0 ? void 0 : _b.instance}`;
|
|
65
|
+
if (opts.resource) {
|
|
66
|
+
ce.ref = opts.resource;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return ce;
|
|
70
|
+
}
|
|
71
|
+
call(trigger, data, opts) {
|
|
72
|
+
logger_1.logger.debug(`shell:${trigger.name}: trigger=${JSON.stringify(trigger)}`);
|
|
73
|
+
logger_1.logger.debug(`shell:${trigger.name}: opts=${JSON.stringify(opts)}, data=${JSON.stringify(data)}`);
|
|
74
|
+
const eventTrigger = trigger.eventTrigger;
|
|
75
|
+
if (!eventTrigger) {
|
|
76
|
+
throw new error_1.FirebaseError(`Function ${trigger.name} is not a background function`);
|
|
77
|
+
}
|
|
78
|
+
let body;
|
|
79
|
+
if (trigger.platform === "gcfv1") {
|
|
80
|
+
body = this.createLegacyEvent(eventTrigger, data, opts);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
body = this.createCloudEvent(eventTrigger, data, opts);
|
|
84
|
+
}
|
|
85
|
+
this.emu.sendRequest(trigger, body);
|
|
54
86
|
}
|
|
55
87
|
}
|
|
56
88
|
exports.FunctionsEmulatorShell = FunctionsEmulatorShell;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isSystemParam = exports.readEnvFile = exports.promptForNewParams = exports.getParamsForUpdate = exports.getParams = exports.
|
|
3
|
+
exports.isSystemParam = exports.readEnvFile = exports.promptForNewParams = exports.getParamsForUpdate = exports.getParams = exports.setNewDefaults = exports.buildBindingOptionsWithBaseValue = exports.getBaseParamBindings = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const clc = require("colorette");
|
|
6
6
|
const fs = require("fs-extra");
|
|
@@ -9,7 +9,6 @@ const logger_1 = require("../logger");
|
|
|
9
9
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
10
10
|
const askUserForParam = require("./askUserForParam");
|
|
11
11
|
const env = require("../functions/env");
|
|
12
|
-
const utils_1 = require("../utils");
|
|
13
12
|
const NONINTERACTIVE_ERROR_MESSAGE = "As of firebase-tools@11, `ext:install`, `ext:update` and `ext:configure` are interactive only commands. " +
|
|
14
13
|
"To deploy an extension noninteractively, use an extensions manifest and `firebase deploy --only extensions`. " +
|
|
15
14
|
"See https://firebase.google.com/docs/extensions/manifest for more details";
|
|
@@ -30,21 +29,17 @@ function buildBindingOptionsWithBaseValue(baseParams) {
|
|
|
30
29
|
}
|
|
31
30
|
exports.buildBindingOptionsWithBaseValue = buildBindingOptionsWithBaseValue;
|
|
32
31
|
function setNewDefaults(params, newDefaults) {
|
|
33
|
-
|
|
34
|
-
if (newDefaults[param.param
|
|
35
|
-
param.default = newDefaults[param.param
|
|
32
|
+
for (const param of params) {
|
|
33
|
+
if (newDefaults[param.param]) {
|
|
34
|
+
param.default = newDefaults[param.param];
|
|
36
35
|
}
|
|
37
|
-
|
|
36
|
+
else if ((param.param = `firebaseextensions.v1beta.function/location` && newDefaults["LOCATION"])) {
|
|
37
|
+
param.default = newDefaults["LOCATION"];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
38
40
|
return params;
|
|
39
41
|
}
|
|
40
42
|
exports.setNewDefaults = setNewDefaults;
|
|
41
|
-
function getParamsWithCurrentValuesAsDefaults(extensionInstance) {
|
|
42
|
-
var _a, _b, _c, _d;
|
|
43
|
-
const specParams = (0, utils_1.cloneDeep)(((_c = (_b = (_a = extensionInstance === null || extensionInstance === void 0 ? void 0 : extensionInstance.config) === null || _a === void 0 ? void 0 : _a.source) === null || _b === void 0 ? void 0 : _b.spec) === null || _c === void 0 ? void 0 : _c.params) || []);
|
|
44
|
-
const currentParams = (0, utils_1.cloneDeep)(((_d = extensionInstance === null || extensionInstance === void 0 ? void 0 : extensionInstance.config) === null || _d === void 0 ? void 0 : _d.params) || {});
|
|
45
|
-
return setNewDefaults(specParams, currentParams);
|
|
46
|
-
}
|
|
47
|
-
exports.getParamsWithCurrentValuesAsDefaults = getParamsWithCurrentValuesAsDefaults;
|
|
48
43
|
async function getParams(args) {
|
|
49
44
|
let params;
|
|
50
45
|
if (args.nonInteractive) {
|
|
@@ -81,6 +76,7 @@ async function getParamsForUpdate(args) {
|
|
|
81
76
|
}
|
|
82
77
|
exports.getParamsForUpdate = getParamsForUpdate;
|
|
83
78
|
async function promptForNewParams(args) {
|
|
79
|
+
var _a, _b;
|
|
84
80
|
const newParamBindingOptions = buildBindingOptionsWithBaseValue(args.currentParams);
|
|
85
81
|
const firebaseProjectParams = await (0, extensionsHelper_1.getFirebaseProjectParams)(args.projectId);
|
|
86
82
|
const sameParam = (param1) => (param2) => {
|
|
@@ -89,10 +85,22 @@ async function promptForNewParams(args) {
|
|
|
89
85
|
const paramDiff = (left, right) => {
|
|
90
86
|
return left.filter((aLeft) => !right.find(sameParam(aLeft)));
|
|
91
87
|
};
|
|
92
|
-
|
|
93
|
-
let
|
|
88
|
+
let combinedOldParams = args.spec.params.concat((_a = args.spec.systemParams.filter((p) => !p.advanced)) !== null && _a !== void 0 ? _a : []);
|
|
89
|
+
let combinedNewParams = args.newSpec.params.concat((_b = args.newSpec.systemParams.filter((p) => !p.advanced)) !== null && _b !== void 0 ? _b : []);
|
|
90
|
+
if (combinedOldParams.some((p) => p.param === "LOCATION") &&
|
|
91
|
+
combinedNewParams.some((p) => p.param === "firebaseextensions.v1beta.function/location") &&
|
|
92
|
+
!!args.currentParams["LOCATION"]) {
|
|
93
|
+
newParamBindingOptions["firebaseextensions.v1beta.function/location"] = {
|
|
94
|
+
baseValue: args.currentParams["LOCATION"],
|
|
95
|
+
};
|
|
96
|
+
delete newParamBindingOptions["LOCATION"];
|
|
97
|
+
combinedOldParams = combinedOldParams.filter((p) => p.param !== "LOCATION");
|
|
98
|
+
combinedNewParams = combinedNewParams.filter((p) => p.param !== "firebaseextensions.v1beta.function/location");
|
|
99
|
+
}
|
|
100
|
+
const oldParams = combinedOldParams.filter((p) => Object.keys(args.currentParams).includes(p.param));
|
|
101
|
+
let paramsDiffDeletions = paramDiff(oldParams, combinedNewParams);
|
|
94
102
|
paramsDiffDeletions = (0, extensionsHelper_1.substituteParams)(paramsDiffDeletions, firebaseProjectParams);
|
|
95
|
-
let paramsDiffAdditions = paramDiff(
|
|
103
|
+
let paramsDiffAdditions = paramDiff(combinedNewParams, oldParams);
|
|
96
104
|
paramsDiffAdditions = (0, extensionsHelper_1.substituteParams)(paramsDiffAdditions, firebaseProjectParams);
|
|
97
105
|
if (paramsDiffDeletions.length) {
|
|
98
106
|
logger_1.logger.info("The following params will no longer be used:");
|
package/lib/frameworks/utils.js
CHANGED
|
@@ -144,14 +144,13 @@ function getNpmRoot(cwd) {
|
|
|
144
144
|
}
|
|
145
145
|
exports.getNpmRoot = getNpmRoot;
|
|
146
146
|
function getNodeModuleBin(name, cwd) {
|
|
147
|
-
const cantFindExecutable = new error_1.FirebaseError(`Could not find the ${name} executable.`);
|
|
148
147
|
const npmRoot = getNpmRoot(cwd);
|
|
149
148
|
if (!npmRoot) {
|
|
150
|
-
throw
|
|
149
|
+
throw new error_1.FirebaseError(`Error finding ${name} executable: failed to spawn 'npm'`);
|
|
151
150
|
}
|
|
152
151
|
const path = (0, path_1.join)(npmRoot, ".bin", name);
|
|
153
152
|
if (!(0, fsutils_1.fileExistsSync)(path)) {
|
|
154
|
-
throw
|
|
153
|
+
throw new error_1.FirebaseError(`Could not find the ${name} executable.`);
|
|
155
154
|
}
|
|
156
155
|
return path;
|
|
157
156
|
}
|
package/lib/functions/secrets.js
CHANGED
|
@@ -44,7 +44,7 @@ function toUpperSnakeCase(key) {
|
|
|
44
44
|
}
|
|
45
45
|
function ensureApi(options) {
|
|
46
46
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
47
|
-
return ensureApiEnabled.ensure(projectId, "secretmanager.googleapis.com", "
|
|
47
|
+
return ensureApiEnabled.ensure(projectId, "secretmanager.googleapis.com", "secretmanager", true);
|
|
48
48
|
}
|
|
49
49
|
exports.ensureApi = ensureApi;
|
|
50
50
|
async function ensureValidKey(key, options) {
|
package/lib/gcp/iam.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.testIamPermissions = exports.testResourceIamPermissions = exports.getRole = exports.deleteServiceAccount = exports.createServiceAccountKey = exports.getServiceAccount = exports.createServiceAccount = void 0;
|
|
3
|
+
exports.testIamPermissions = exports.testResourceIamPermissions = exports.getRole = exports.listServiceAccountKeys = exports.deleteServiceAccount = exports.createServiceAccountKey = exports.getServiceAccount = exports.createServiceAccount = void 0;
|
|
4
4
|
const api_1 = require("../api");
|
|
5
5
|
const logger_1 = require("../logger");
|
|
6
6
|
const apiv2_1 = require("../apiv2");
|
|
@@ -35,6 +35,11 @@ async function deleteServiceAccount(projectId, accountEmail) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
exports.deleteServiceAccount = deleteServiceAccount;
|
|
38
|
+
async function listServiceAccountKeys(projectId, serviceAccountName) {
|
|
39
|
+
const response = await apiClient.get(`/projects/${projectId}/serviceAccounts/${serviceAccountName}@${projectId}.iam.gserviceaccount.com/keys`);
|
|
40
|
+
return response.body.keys;
|
|
41
|
+
}
|
|
42
|
+
exports.listServiceAccountKeys = listServiceAccountKeys;
|
|
38
43
|
async function getRole(role) {
|
|
39
44
|
const response = await apiClient.get(`/roles/${role}`, {
|
|
40
45
|
retryCodes: [500, 503],
|
|
@@ -17,6 +17,7 @@ const prompt_1 = require("../../../prompt");
|
|
|
17
17
|
const utils_1 = require("../../../utils");
|
|
18
18
|
const api_1 = require("../../../api");
|
|
19
19
|
const apiv2_1 = require("../../../apiv2");
|
|
20
|
+
const error_1 = require("../../../error");
|
|
20
21
|
let GIT_DIR;
|
|
21
22
|
let GITHUB_DIR;
|
|
22
23
|
let WORKFLOW_DIR;
|
|
@@ -26,6 +27,7 @@ const YML_PULL_REQUEST_FILENAME = "firebase-hosting-pull-request.yml";
|
|
|
26
27
|
const YML_MERGE_FILENAME = "firebase-hosting-merge.yml";
|
|
27
28
|
const CHECKOUT_GITHUB_ACTION_NAME = "actions/checkout@v3";
|
|
28
29
|
const HOSTING_GITHUB_ACTION_NAME = "FirebaseExtended/action-hosting-deploy@v0";
|
|
30
|
+
const SERVICE_ACCOUNT_MAX_KEY_NUMBER = 10;
|
|
29
31
|
const githubApiClient = new apiv2_1.Client({ urlPrefix: api_1.githubApiOrigin, auth: false });
|
|
30
32
|
async function initGitHub(setup) {
|
|
31
33
|
if (!setup.projectId) {
|
|
@@ -344,6 +346,13 @@ async function createServiceAccountAndKeyWithRetry(options, repo, accountId) {
|
|
|
344
346
|
catch (e) {
|
|
345
347
|
spinnerServiceAccount.stop();
|
|
346
348
|
if (!e.message.includes("429")) {
|
|
349
|
+
const serviceAccountKeys = await (0, iam_1.listServiceAccountKeys)(options.projectId, accountId);
|
|
350
|
+
if (serviceAccountKeys.length >= SERVICE_ACCOUNT_MAX_KEY_NUMBER) {
|
|
351
|
+
throw new error_1.FirebaseError(`You cannot add another key because the service account ${(0, colorette_1.bold)(accountId)} already contains the max number of keys: ${SERVICE_ACCOUNT_MAX_KEY_NUMBER}.`, {
|
|
352
|
+
original: e,
|
|
353
|
+
exit: 1,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
347
356
|
throw e;
|
|
348
357
|
}
|
|
349
358
|
spinnerServiceAccount.start();
|
package/lib/localFunction.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const uuid = require("uuid");
|
|
3
4
|
const request = require("request");
|
|
4
|
-
const utils = require("./utils");
|
|
5
5
|
const encodeFirestoreValue_1 = require("./firestore/encodeFirestoreValue");
|
|
6
|
+
const utils = require("./utils");
|
|
6
7
|
class LocalFunction {
|
|
7
8
|
constructor(trigger, urls, controller) {
|
|
8
9
|
this.trigger = trigger;
|
|
@@ -17,7 +18,7 @@ class LocalFunction {
|
|
|
17
18
|
return resource.replace(this.paramWildcardRegex, (wildcard) => {
|
|
18
19
|
const wildcardNoBraces = wildcard.slice(1, -1);
|
|
19
20
|
const sub = params === null || params === void 0 ? void 0 : params[wildcardNoBraces];
|
|
20
|
-
return sub ||
|
|
21
|
+
return sub || wildcardNoBraces + utils.randomInt(1, 9);
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
24
|
constructCallableFunc(data, opts) {
|
|
@@ -118,24 +119,30 @@ class LocalFunction {
|
|
|
118
119
|
isFirestoreFunc(eventTrigger) {
|
|
119
120
|
return utils.getFunctionsEventProvider(eventTrigger.eventType) === "Firestore";
|
|
120
121
|
}
|
|
122
|
+
isPubsubFunc(eventTrigger) {
|
|
123
|
+
return utils.getFunctionsEventProvider(eventTrigger.eventType) === "PubSub";
|
|
124
|
+
}
|
|
121
125
|
triggerEvent(data, opts) {
|
|
126
|
+
var _a, _b, _c, _d;
|
|
122
127
|
opts = opts || {};
|
|
123
128
|
let operationType;
|
|
124
129
|
let dataPayload;
|
|
125
130
|
if (this.trigger.httpsTrigger) {
|
|
126
|
-
this.controller.call(this.trigger
|
|
131
|
+
this.controller.call(this.trigger, data || {}, opts);
|
|
127
132
|
}
|
|
128
133
|
else if (this.trigger.eventTrigger) {
|
|
129
134
|
if (this.isDatabaseFn(this.trigger.eventTrigger)) {
|
|
130
135
|
operationType = utils.last(this.trigger.eventTrigger.eventType.split("."));
|
|
131
136
|
switch (operationType) {
|
|
132
137
|
case "create":
|
|
138
|
+
case "created":
|
|
133
139
|
dataPayload = {
|
|
134
140
|
data: null,
|
|
135
141
|
delta: data,
|
|
136
142
|
};
|
|
137
143
|
break;
|
|
138
144
|
case "delete":
|
|
145
|
+
case "deleted":
|
|
139
146
|
dataPayload = {
|
|
140
147
|
data: data,
|
|
141
148
|
delta: null,
|
|
@@ -147,20 +154,23 @@ class LocalFunction {
|
|
|
147
154
|
delta: data.after,
|
|
148
155
|
};
|
|
149
156
|
}
|
|
150
|
-
|
|
157
|
+
const resource = (_a = this.trigger.eventTrigger.resource) !== null && _a !== void 0 ? _a : (_b = this.trigger.eventTrigger.eventFilterPathPatterns) === null || _b === void 0 ? void 0 : _b.ref;
|
|
158
|
+
opts.resource = this.substituteParams(resource, opts.params);
|
|
151
159
|
opts.auth = this.constructAuth(opts.auth, opts.authType);
|
|
152
|
-
this.controller.call(this.trigger
|
|
160
|
+
this.controller.call(this.trigger, dataPayload, opts);
|
|
153
161
|
}
|
|
154
162
|
else if (this.isFirestoreFunc(this.trigger.eventTrigger)) {
|
|
155
163
|
operationType = utils.last(this.trigger.eventTrigger.eventType.split("."));
|
|
156
164
|
switch (operationType) {
|
|
157
165
|
case "create":
|
|
166
|
+
case "created":
|
|
158
167
|
dataPayload = {
|
|
159
168
|
value: this.makeFirestoreValue(data),
|
|
160
169
|
oldValue: {},
|
|
161
170
|
};
|
|
162
171
|
break;
|
|
163
172
|
case "delete":
|
|
173
|
+
case "deleted":
|
|
164
174
|
dataPayload = {
|
|
165
175
|
value: {},
|
|
166
176
|
oldValue: this.makeFirestoreValue(data),
|
|
@@ -172,14 +182,22 @@ class LocalFunction {
|
|
|
172
182
|
oldValue: this.makeFirestoreValue(data.before),
|
|
173
183
|
};
|
|
174
184
|
}
|
|
175
|
-
|
|
176
|
-
this.
|
|
185
|
+
const resource = (_c = this.trigger.eventTrigger.resource) !== null && _c !== void 0 ? _c : (_d = this.trigger.eventTrigger.eventFilterPathPatterns) === null || _d === void 0 ? void 0 : _d.document;
|
|
186
|
+
opts.resource = this.substituteParams(resource, opts.params);
|
|
187
|
+
this.controller.call(this.trigger, dataPayload, opts);
|
|
188
|
+
}
|
|
189
|
+
else if (this.isPubsubFunc(this.trigger.eventTrigger)) {
|
|
190
|
+
dataPayload = data;
|
|
191
|
+
if (this.trigger.platform === "gcfv2") {
|
|
192
|
+
dataPayload = { message: Object.assign(Object.assign({}, data), { messageId: uuid.v4() }) };
|
|
193
|
+
}
|
|
194
|
+
this.controller.call(this.trigger, dataPayload || {}, opts);
|
|
177
195
|
}
|
|
178
196
|
else {
|
|
179
|
-
this.controller.call(this.trigger
|
|
197
|
+
this.controller.call(this.trigger, data || {}, opts);
|
|
180
198
|
}
|
|
181
199
|
}
|
|
182
|
-
return
|
|
200
|
+
return "Successfully invoked function.";
|
|
183
201
|
}
|
|
184
202
|
makeFn() {
|
|
185
203
|
var _a;
|
package/lib/utils.js
CHANGED
|
@@ -194,7 +194,7 @@ function getFunctionsEventProvider(eventType) {
|
|
|
194
194
|
const provider = last(parts[1].split("."));
|
|
195
195
|
return _.capitalize(provider);
|
|
196
196
|
}
|
|
197
|
-
if (/google
|
|
197
|
+
if (/google.*pubsub/.exec(eventType)) {
|
|
198
198
|
return "PubSub";
|
|
199
199
|
}
|
|
200
200
|
else if (/google.storage/.exec(eventType)) {
|
|
@@ -212,7 +212,7 @@ function getFunctionsEventProvider(eventType) {
|
|
|
212
212
|
else if (/google.firebase.crashlytics/.exec(eventType)) {
|
|
213
213
|
return "Crashlytics";
|
|
214
214
|
}
|
|
215
|
-
else if (/google
|
|
215
|
+
else if (/google.*firestore/.exec(eventType)) {
|
|
216
216
|
return "Firestore";
|
|
217
217
|
}
|
|
218
218
|
return _.capitalize(eventType.split(".")[1]);
|