firebase-tools 10.1.2 → 10.1.3
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/apiv2.js +91 -48
- package/lib/archiveDirectory.js +63 -73
- package/lib/commands/ext-dev-usage.js +3 -8
- package/lib/database/metadata.js +16 -24
- package/lib/deploy/functions/backend.js +3 -1
- package/lib/deploy/functions/prepare.js +2 -2
- package/lib/deploy/functions/release/fabricator.js +4 -1
- package/lib/deploy/functions/validate.js +28 -1
- package/lib/deploy/hosting/convertConfig.js +45 -24
- package/lib/deploy/hosting/prepare.js +1 -1
- package/lib/emulator/functionsEmulator.js +3 -1
- package/lib/extensions/extensionsApi.js +0 -1
- package/lib/gcp/cloudbilling.js +8 -19
- package/lib/gcp/cloudfunctions.js +22 -46
- package/lib/gcp/cloudlogging.js +8 -11
- package/lib/gcp/cloudmonitoring.js +8 -5
- package/lib/gcp/cloudscheduler.js +7 -18
- package/lib/gcp/firedata.js +5 -4
- package/lib/gcp/firestore.js +5 -5
- package/lib/gcp/iam.js +18 -33
- package/lib/gcp/resourceManager.js +8 -13
- package/lib/gcp/runtimeconfig.js +31 -53
- package/lib/gcp/secretManager.js +21 -43
- package/lib/gcp/storage.js +24 -29
- package/npm-shrinkwrap.json +965 -970
- package/package.json +4 -2
- package/schema/firebase-config.json +387 -12
- package/templates/init/hosting/index.html +1 -1
package/lib/gcp/runtimeconfig.js
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const { runtimeconfigOrigin } = require("../api");
|
|
3
|
+
const { Client } = require("../apiv2");
|
|
4
4
|
const { logger } = require("../logger");
|
|
5
5
|
var _ = require("lodash");
|
|
6
|
-
|
|
6
|
+
const API_VERSION = "v1beta1";
|
|
7
|
+
const apiClient = new Client({ urlPrefix: runtimeconfigOrigin, apiVersion: API_VERSION });
|
|
7
8
|
function _listConfigs(projectId) {
|
|
8
|
-
return
|
|
9
|
-
.
|
|
10
|
-
auth: true,
|
|
11
|
-
origin: api.runtimeconfigOrigin,
|
|
9
|
+
return apiClient
|
|
10
|
+
.get(`/projects/${projectId}/configs`, {
|
|
12
11
|
retryCodes: [500, 503],
|
|
13
12
|
})
|
|
14
13
|
.then(function (resp) {
|
|
15
|
-
return
|
|
14
|
+
return resp.body.configs;
|
|
16
15
|
});
|
|
17
16
|
}
|
|
18
17
|
function _createConfig(projectId, configId) {
|
|
19
18
|
var path = _.join(["projects", projectId, "configs"], "/");
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
origin: api.runtimeconfigOrigin,
|
|
25
|
-
data: {
|
|
26
|
-
name: path + "/" + configId,
|
|
27
|
-
},
|
|
19
|
+
return apiClient
|
|
20
|
+
.post(`/projects/${projectId}/configs`, {
|
|
21
|
+
name: path + "/" + configId,
|
|
22
|
+
}, {
|
|
28
23
|
retryCodes: [500, 503],
|
|
29
24
|
})
|
|
30
25
|
.catch(function (err) {
|
|
@@ -35,10 +30,8 @@ function _createConfig(projectId, configId) {
|
|
|
35
30
|
});
|
|
36
31
|
}
|
|
37
32
|
function _deleteConfig(projectId, configId) {
|
|
38
|
-
return
|
|
39
|
-
.
|
|
40
|
-
auth: true,
|
|
41
|
-
origin: api.runtimeconfigOrigin,
|
|
33
|
+
return apiClient
|
|
34
|
+
.delete(`/projects/${projectId}/configs/${configId}`, {
|
|
42
35
|
retryCodes: [500, 503],
|
|
43
36
|
})
|
|
44
37
|
.catch(function (err) {
|
|
@@ -50,10 +43,8 @@ function _deleteConfig(projectId, configId) {
|
|
|
50
43
|
});
|
|
51
44
|
}
|
|
52
45
|
function _listVariables(configPath) {
|
|
53
|
-
return
|
|
54
|
-
.
|
|
55
|
-
auth: true,
|
|
56
|
-
origin: api.runtimeconfigOrigin,
|
|
46
|
+
return apiClient
|
|
47
|
+
.get(`${configPath}/variables`, {
|
|
57
48
|
retryCodes: [500, 503],
|
|
58
49
|
})
|
|
59
50
|
.then(function (resp) {
|
|
@@ -61,10 +52,8 @@ function _listVariables(configPath) {
|
|
|
61
52
|
});
|
|
62
53
|
}
|
|
63
54
|
function _getVariable(varPath) {
|
|
64
|
-
return
|
|
65
|
-
.
|
|
66
|
-
auth: true,
|
|
67
|
-
origin: api.runtimeconfigOrigin,
|
|
55
|
+
return apiClient
|
|
56
|
+
.get(varPath, {
|
|
68
57
|
retryCodes: [500, 503],
|
|
69
58
|
})
|
|
70
59
|
.then(function (resp) {
|
|
@@ -72,16 +61,12 @@ function _getVariable(varPath) {
|
|
|
72
61
|
});
|
|
73
62
|
}
|
|
74
63
|
function _createVariable(projectId, configId, varId, value) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
data: {
|
|
82
|
-
name: path + "/" + varId,
|
|
83
|
-
text: value,
|
|
84
|
-
},
|
|
64
|
+
const path = `/projects/${projectId}/configs/${configId}/variables`;
|
|
65
|
+
return apiClient
|
|
66
|
+
.post(path, {
|
|
67
|
+
name: `${path}/${varId}`,
|
|
68
|
+
text: value,
|
|
69
|
+
}, {
|
|
85
70
|
retryCodes: [500, 503],
|
|
86
71
|
})
|
|
87
72
|
.catch(function (err) {
|
|
@@ -94,15 +79,11 @@ function _createVariable(projectId, configId, varId, value) {
|
|
|
94
79
|
});
|
|
95
80
|
}
|
|
96
81
|
function _updateVariable(projectId, configId, varId, value) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
data: {
|
|
103
|
-
name: path,
|
|
104
|
-
text: value,
|
|
105
|
-
},
|
|
82
|
+
const path = `/projects/${projectId}/configs/${configId}/variables/${varId}`;
|
|
83
|
+
return apiClient.put(path, {
|
|
84
|
+
name: path,
|
|
85
|
+
text: value,
|
|
86
|
+
}, {
|
|
106
87
|
retryCodes: [500, 503],
|
|
107
88
|
});
|
|
108
89
|
}
|
|
@@ -120,13 +101,10 @@ function _setVariable(projectId, configId, varId, value) {
|
|
|
120
101
|
});
|
|
121
102
|
}
|
|
122
103
|
function _deleteVariable(projectId, configId, varId) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return api
|
|
126
|
-
.request("DELETE", endpoint, {
|
|
127
|
-
auth: true,
|
|
128
|
-
origin: api.runtimeconfigOrigin,
|
|
104
|
+
return apiClient
|
|
105
|
+
.delete(`/projects/${projectId}/configs/${configId}/variables/${varId}`, {
|
|
129
106
|
retryCodes: [500, 503],
|
|
107
|
+
queryParams: { recursive: "true" },
|
|
130
108
|
})
|
|
131
109
|
.catch(function (err) {
|
|
132
110
|
if (_.get(err, "context.response.statusCode") === 404) {
|
package/lib/gcp/secretManager.js
CHANGED
|
@@ -2,33 +2,26 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.grantServiceAgentRole = exports.addVersion = exports.createSecret = exports.toSecretVersionResourceName = exports.parseSecretVersionResourceName = exports.parseSecretResourceName = exports.secretExists = exports.getSecretVersion = exports.getSecret = exports.listSecrets = exports.secretManagerConsoleUri = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
|
-
const
|
|
5
|
+
const api_1 = require("../api");
|
|
6
|
+
const apiv2_1 = require("../apiv2");
|
|
6
7
|
const secretManagerConsoleUri = (projectId) => `https://console.cloud.google.com/security/secret-manager?project=${projectId}`;
|
|
7
8
|
exports.secretManagerConsoleUri = secretManagerConsoleUri;
|
|
9
|
+
const apiClient = new apiv2_1.Client({ urlPrefix: api_1.secretManagerOrigin, apiVersion: "v1beta1" });
|
|
8
10
|
async function listSecrets(projectId) {
|
|
9
|
-
const listRes = await
|
|
10
|
-
auth: true,
|
|
11
|
-
origin: api.secretManagerOrigin,
|
|
12
|
-
});
|
|
11
|
+
const listRes = await apiClient.get(`/projects/${projectId}/secrets`);
|
|
13
12
|
return listRes.body.secrets.map((s) => parseSecretResourceName(s.name));
|
|
14
13
|
}
|
|
15
14
|
exports.listSecrets = listSecrets;
|
|
16
15
|
async function getSecret(projectId, name) {
|
|
17
16
|
var _a;
|
|
18
|
-
const getRes = await
|
|
19
|
-
auth: true,
|
|
20
|
-
origin: api.secretManagerOrigin,
|
|
21
|
-
});
|
|
17
|
+
const getRes = await apiClient.get(`/projects/${projectId}/secrets/${name}`);
|
|
22
18
|
const secret = parseSecretResourceName(getRes.body.name);
|
|
23
19
|
secret.labels = (_a = getRes.body.labels) !== null && _a !== void 0 ? _a : {};
|
|
24
20
|
return secret;
|
|
25
21
|
}
|
|
26
22
|
exports.getSecret = getSecret;
|
|
27
23
|
async function getSecretVersion(projectId, name, version) {
|
|
28
|
-
const getRes = await
|
|
29
|
-
auth: true,
|
|
30
|
-
origin: api.secretManagerOrigin,
|
|
31
|
-
});
|
|
24
|
+
const getRes = await apiClient.get(`/projects/${projectId}/secrets/${name}/versions/${version}`);
|
|
32
25
|
return parseSecretVersionResourceName(getRes.body.name);
|
|
33
26
|
}
|
|
34
27
|
exports.getSecretVersion = getSecretVersion;
|
|
@@ -69,27 +62,19 @@ function toSecretVersionResourceName(secretVersion) {
|
|
|
69
62
|
}
|
|
70
63
|
exports.toSecretVersionResourceName = toSecretVersionResourceName;
|
|
71
64
|
async function createSecret(projectId, name, labels) {
|
|
72
|
-
const createRes = await
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
data: {
|
|
76
|
-
replication: {
|
|
77
|
-
automatic: {},
|
|
78
|
-
},
|
|
79
|
-
labels,
|
|
65
|
+
const createRes = await apiClient.post(`/projects/${projectId}/secrets`, {
|
|
66
|
+
replication: {
|
|
67
|
+
automatic: {},
|
|
80
68
|
},
|
|
81
|
-
|
|
69
|
+
labels,
|
|
70
|
+
}, { queryParams: { secretId: name } });
|
|
82
71
|
return parseSecretResourceName(createRes.body.name);
|
|
83
72
|
}
|
|
84
73
|
exports.createSecret = createSecret;
|
|
85
74
|
async function addVersion(secret, payloadData) {
|
|
86
|
-
const res = await
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
data: {
|
|
90
|
-
payload: {
|
|
91
|
-
data: Buffer.from(payloadData).toString("base64"),
|
|
92
|
-
},
|
|
75
|
+
const res = await apiClient.post(`/projects/${secret.projectId}/secrets/${secret.name}:addVersion`, {
|
|
76
|
+
payload: {
|
|
77
|
+
data: Buffer.from(payloadData).toString("base64"),
|
|
93
78
|
},
|
|
94
79
|
});
|
|
95
80
|
const nameTokens = res.body.name.split("/");
|
|
@@ -103,10 +88,7 @@ async function addVersion(secret, payloadData) {
|
|
|
103
88
|
}
|
|
104
89
|
exports.addVersion = addVersion;
|
|
105
90
|
async function grantServiceAgentRole(secret, serviceAccountEmail, role) {
|
|
106
|
-
const getPolicyRes = await
|
|
107
|
-
auth: true,
|
|
108
|
-
origin: api.secretManagerOrigin,
|
|
109
|
-
});
|
|
91
|
+
const getPolicyRes = await apiClient.get(`/projects/${secret.projectId}/secrets/${secret.name}:getIamPolicy`);
|
|
110
92
|
const bindings = getPolicyRes.body.bindings || [];
|
|
111
93
|
if (bindings.find((b) => b.role == role &&
|
|
112
94
|
b.members.find((m) => m == `serviceAccount:${serviceAccountEmail}`))) {
|
|
@@ -116,16 +98,12 @@ async function grantServiceAgentRole(secret, serviceAccountEmail, role) {
|
|
|
116
98
|
role: role,
|
|
117
99
|
members: [`serviceAccount:${serviceAccountEmail}`],
|
|
118
100
|
});
|
|
119
|
-
await
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
},
|
|
126
|
-
updateMask: {
|
|
127
|
-
paths: "bindings",
|
|
128
|
-
},
|
|
101
|
+
await apiClient.post(`/projects/${secret.projectId}/secrets/${secret.name}:setIamPolicy`, {
|
|
102
|
+
policy: {
|
|
103
|
+
bindings,
|
|
104
|
+
},
|
|
105
|
+
updateMask: {
|
|
106
|
+
paths: "bindings",
|
|
129
107
|
},
|
|
130
108
|
});
|
|
131
109
|
(0, utils_1.logLabeledSuccess)("SecretManager", `Granted ${role} on projects/${secret.projectId}/secrets/${secret.name} to ${serviceAccountEmail}`);
|
package/lib/gcp/storage.js
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getServiceAccount = exports.getBucket = exports.deleteObject = exports.uploadObject = exports.upload = exports.getDefaultBucket = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
|
-
const
|
|
5
|
+
const api_1 = require("../api");
|
|
6
|
+
const apiv2_1 = require("../apiv2");
|
|
6
7
|
const logger_1 = require("../logger");
|
|
7
8
|
const error_1 = require("../error");
|
|
9
|
+
const storageAPIClient = new apiv2_1.Client({ urlPrefix: api_1.storageOrigin, apiVersion: "v1" });
|
|
8
10
|
async function getDefaultBucket(projectId) {
|
|
9
11
|
try {
|
|
10
|
-
const resp = await
|
|
11
|
-
auth: true,
|
|
12
|
-
origin: api.appengineOrigin,
|
|
13
|
-
});
|
|
12
|
+
const resp = await storageAPIClient.get(`/apps/${projectId}`);
|
|
14
13
|
if (resp.body.defaultBucket === "undefined") {
|
|
15
14
|
logger_1.logger.debug("Default storage bucket is undefined.");
|
|
16
15
|
throw new error_1.FirebaseError("Your project is being set up. Please wait a minute before deploying again.");
|
|
@@ -25,15 +24,17 @@ async function getDefaultBucket(projectId) {
|
|
|
25
24
|
exports.getDefaultBucket = getDefaultBucket;
|
|
26
25
|
async function upload(source, uploadUrl, extraHeaders) {
|
|
27
26
|
const url = new URL(uploadUrl);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
const localAPIClient = new apiv2_1.Client({ urlPrefix: url.origin, auth: false });
|
|
28
|
+
const res = await localAPIClient.request({
|
|
29
|
+
method: "PUT",
|
|
30
|
+
path: url.pathname,
|
|
31
|
+
queryParams: url.searchParams,
|
|
32
|
+
headers: Object.assign({ "content-type": "application/zip" }, extraHeaders),
|
|
33
|
+
body: source.stream,
|
|
34
|
+
skipLog: { resBody: true },
|
|
34
35
|
});
|
|
35
36
|
return {
|
|
36
|
-
generation:
|
|
37
|
+
generation: res.response.headers.get("x-goog-generation"),
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
40
|
exports.upload = upload;
|
|
@@ -42,37 +43,33 @@ async function uploadObject(source, bucketName) {
|
|
|
42
43
|
throw new error_1.FirebaseError(`Expected a file name ending in .zip, got ${source.file}`);
|
|
43
44
|
}
|
|
44
45
|
const location = `/${bucketName}/${path.basename(source.file)}`;
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const res = await storageAPIClient.request({
|
|
47
|
+
method: "PUT",
|
|
48
|
+
path: location,
|
|
48
49
|
headers: {
|
|
49
50
|
"Content-Type": "application/zip",
|
|
50
51
|
"x-goog-content-length-range": "0,123289600",
|
|
51
52
|
},
|
|
52
|
-
|
|
53
|
-
origin: api.storageOrigin,
|
|
54
|
-
logOptions: { skipRequestBody: true },
|
|
53
|
+
body: source.stream,
|
|
55
54
|
});
|
|
56
55
|
return {
|
|
57
56
|
bucket: bucketName,
|
|
58
57
|
object: path.basename(source.file),
|
|
59
|
-
generation:
|
|
58
|
+
generation: res.response.headers.get("x-goog-generation"),
|
|
60
59
|
};
|
|
61
60
|
}
|
|
62
61
|
exports.uploadObject = uploadObject;
|
|
63
62
|
function deleteObject(location) {
|
|
64
|
-
return
|
|
63
|
+
return api_1.default.request("DELETE", location, {
|
|
65
64
|
auth: true,
|
|
66
|
-
origin:
|
|
65
|
+
origin: api_1.default.storageOrigin,
|
|
67
66
|
});
|
|
68
67
|
}
|
|
69
68
|
exports.deleteObject = deleteObject;
|
|
70
69
|
async function getBucket(bucketName) {
|
|
71
70
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
origin: api.storageOrigin,
|
|
75
|
-
});
|
|
71
|
+
const localAPIClient = new apiv2_1.Client({ urlPrefix: api_1.storageOrigin });
|
|
72
|
+
const result = await localAPIClient.get(`/storage/v1/b/${bucketName}`);
|
|
76
73
|
return result.body;
|
|
77
74
|
}
|
|
78
75
|
catch (err) {
|
|
@@ -85,10 +82,8 @@ async function getBucket(bucketName) {
|
|
|
85
82
|
exports.getBucket = getBucket;
|
|
86
83
|
async function getServiceAccount(projectId) {
|
|
87
84
|
try {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
origin: api.storageOrigin,
|
|
91
|
-
});
|
|
85
|
+
const localAPIClient = new apiv2_1.Client({ urlPrefix: api_1.storageOrigin });
|
|
86
|
+
const response = await localAPIClient.get(`/storage/v1/projects/${projectId}/serviceAccount`);
|
|
92
87
|
return response.body;
|
|
93
88
|
}
|
|
94
89
|
catch (err) {
|