firebase-tools 10.3.1 → 10.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accountExporter.js +95 -84
- package/lib/commands/deploy.js +1 -1
- package/lib/commands/experimental-functions-shell.js +1 -1
- package/lib/commands/ext-configure.js +7 -6
- package/lib/commands/ext-export.js +7 -1
- package/lib/commands/ext-install.js +7 -6
- package/lib/commands/ext-update.js +4 -3
- package/lib/commands/functions-config-export.js +5 -3
- package/lib/commands/functions-shell.js +1 -1
- package/lib/commands/hosting-channel-create.js +2 -2
- package/lib/commands/hosting-channel-delete.js +2 -2
- package/lib/commands/hosting-channel-deploy.js +2 -2
- package/lib/commands/hosting-channel-list.js +2 -2
- package/lib/commands/hosting-channel-open.js +2 -2
- package/lib/commands/hosting-sites-delete.js +2 -2
- package/lib/commands/serve.js +1 -1
- package/lib/commands/target-apply.js +2 -2
- package/lib/commands/target-clear.js +2 -2
- package/lib/commands/target-remove.js +2 -2
- package/lib/commands/target.js +2 -2
- package/lib/config.js +14 -4
- package/lib/deploy/extensions/planner.js +9 -3
- package/lib/deploy/functions/checkIam.js +44 -1
- package/lib/deploy/functions/deploy.js +3 -7
- package/lib/deploy/functions/prepare.js +7 -5
- package/lib/deploy/functions/prepareFunctionsUpload.js +7 -13
- package/lib/deploy/functions/release/fabricator.js +13 -1
- package/lib/deploy/functions/release/index.js +1 -1
- package/lib/deploy/functions/services/firebaseAlerts.js +1 -17
- package/lib/deploy/functions/services/index.js +2 -1
- package/lib/deploy/hosting/deploy.js +10 -0
- package/lib/emulator/auth/apiSpec.js +37 -0
- package/lib/emulator/commandUtils.js +2 -2
- package/lib/emulator/controller.js +14 -8
- package/lib/emulator/downloadableEmulators.js +5 -5
- package/lib/emulator/extensionsEmulator.js +3 -0
- package/lib/emulator/functionsEmulator.js +8 -18
- package/lib/emulator/functionsEmulatorShared.js +31 -1
- package/lib/emulator/storage/apis/firebase.js +4 -6
- package/lib/emulator/storage/files.js +5 -5
- package/lib/emulator/storage/index.js +6 -9
- package/lib/emulator/storage/rules/config.js +6 -5
- package/lib/emulator/storage/rules/manager.js +49 -32
- package/lib/emulator/storage/rules/runtime.js +4 -0
- package/lib/emulator/storage/rules/utils.js +2 -2
- package/lib/emulator/storage/server.js +1 -1
- package/lib/extensions/askUserForParam.js +87 -16
- package/lib/extensions/extensionsHelper.js +11 -2
- package/lib/extensions/manifest.js +36 -4
- package/lib/extensions/paramHelper.js +11 -6
- package/lib/fsutils.js +14 -1
- package/lib/functions/projectConfig.js +34 -0
- package/lib/init/features/functions/index.js +4 -2
- package/lib/init/features/hosting/index.js +32 -41
- package/lib/init/features/index.js +22 -12
- package/lib/init/index.js +28 -11
- package/lib/requireConfig.js +11 -9
- package/lib/requirePermissions.js +4 -1
- package/lib/serve/functions.js +5 -5
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/schema/firebase-config.json +93 -36
- package/lib/prepareUpload.js +0 -44
package/lib/accountExporter.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serialExportUsers = exports.validateOptions = void 0;
|
|
4
|
+
const _ = require("lodash");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const apiv2_1 = require("./apiv2");
|
|
8
|
+
const error_1 = require("./error");
|
|
9
|
+
const api_1 = require("./api");
|
|
10
|
+
const utils = require("./utils");
|
|
11
|
+
const apiClient = new apiv2_1.Client({
|
|
12
|
+
urlPrefix: api_1.googleOrigin,
|
|
11
13
|
});
|
|
12
|
-
|
|
14
|
+
const EXPORTED_JSON_KEYS = [
|
|
13
15
|
"localId",
|
|
14
16
|
"email",
|
|
15
17
|
"emailVerified",
|
|
@@ -23,44 +25,53 @@ var EXPORTED_JSON_KEYS = [
|
|
|
23
25
|
"disabled",
|
|
24
26
|
"customAttributes",
|
|
25
27
|
];
|
|
26
|
-
|
|
28
|
+
const EXPORTED_JSON_KEYS_RENAMING = {
|
|
27
29
|
lastLoginAt: "lastSignedInAt",
|
|
28
30
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
const EXPORTED_PROVIDER_USER_INFO_KEYS = [
|
|
32
|
+
"providerId",
|
|
33
|
+
"rawId",
|
|
34
|
+
"email",
|
|
35
|
+
"displayName",
|
|
36
|
+
"photoUrl",
|
|
37
|
+
];
|
|
38
|
+
const PROVIDER_ID_INDEX_MAP = new Map([
|
|
39
|
+
["google.com", 7],
|
|
40
|
+
["facebook.com", 11],
|
|
41
|
+
["twitter.com", 15],
|
|
42
|
+
["github.com", 19],
|
|
43
|
+
]);
|
|
44
|
+
function escapeComma(str) {
|
|
45
|
+
if (str.includes(",")) {
|
|
38
46
|
return `"${str}"`;
|
|
39
47
|
}
|
|
40
48
|
return str;
|
|
41
|
-
}
|
|
42
|
-
|
|
49
|
+
}
|
|
50
|
+
function convertToNormalBase64(data) {
|
|
43
51
|
return data.replace(/_/g, "/").replace(/-/g, "+");
|
|
44
|
-
}
|
|
45
|
-
|
|
52
|
+
}
|
|
53
|
+
function addProviderUserInfo(providerInfo, arr, startPos) {
|
|
46
54
|
arr[startPos] = providerInfo.rawId;
|
|
47
55
|
arr[startPos + 1] = providerInfo.email || "";
|
|
48
|
-
arr[startPos + 2] =
|
|
56
|
+
arr[startPos + 2] = escapeComma(providerInfo.displayName || "");
|
|
49
57
|
arr[startPos + 3] = providerInfo.photoUrl || "";
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
}
|
|
59
|
+
function transUserToArray(user) {
|
|
60
|
+
const arr = Array(27).fill("");
|
|
53
61
|
arr[0] = user.localId;
|
|
54
62
|
arr[1] = user.email || "";
|
|
55
63
|
arr[2] = user.emailVerified || false;
|
|
56
|
-
arr[3] =
|
|
57
|
-
arr[4] =
|
|
58
|
-
arr[5] =
|
|
64
|
+
arr[3] = convertToNormalBase64(user.passwordHash || "");
|
|
65
|
+
arr[4] = convertToNormalBase64(user.salt || "");
|
|
66
|
+
arr[5] = escapeComma(user.displayName || "");
|
|
59
67
|
arr[6] = user.photoUrl || "";
|
|
60
|
-
for (
|
|
61
|
-
|
|
62
|
-
if (providerInfo
|
|
63
|
-
|
|
68
|
+
for (let i = 0; i < (!user.providerUserInfo ? 0 : user.providerUserInfo.length); i++) {
|
|
69
|
+
const providerInfo = user.providerUserInfo[i];
|
|
70
|
+
if (providerInfo) {
|
|
71
|
+
const providerIndex = PROVIDER_ID_INDEX_MAP.get(providerInfo.providerId);
|
|
72
|
+
if (providerIndex) {
|
|
73
|
+
addProviderUserInfo(providerInfo, arr, providerIndex);
|
|
74
|
+
}
|
|
64
75
|
}
|
|
65
76
|
}
|
|
66
77
|
arr[23] = user.createdAt;
|
|
@@ -69,36 +80,35 @@ var _transUserToArray = function (user) {
|
|
|
69
80
|
arr[26] = user.disabled;
|
|
70
81
|
arr[27] = user.customAttributes;
|
|
71
82
|
return arr;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
_.each(_.pick(user, EXPORTED_JSON_KEYS),
|
|
76
|
-
|
|
83
|
+
}
|
|
84
|
+
function transUserJson(user) {
|
|
85
|
+
const newUser = {};
|
|
86
|
+
_.each(_.pick(user, EXPORTED_JSON_KEYS), (value, key) => {
|
|
87
|
+
const newKey = EXPORTED_JSON_KEYS_RENAMING[key] || key;
|
|
77
88
|
newUser[newKey] = value;
|
|
78
89
|
});
|
|
79
90
|
if (newUser.passwordHash) {
|
|
80
|
-
newUser.passwordHash =
|
|
91
|
+
newUser.passwordHash = convertToNormalBase64(newUser.passwordHash);
|
|
81
92
|
}
|
|
82
93
|
if (newUser.salt) {
|
|
83
|
-
newUser.salt =
|
|
94
|
+
newUser.salt = convertToNormalBase64(newUser.salt);
|
|
84
95
|
}
|
|
85
96
|
if (user.providerUserInfo) {
|
|
86
97
|
newUser.providerUserInfo = [];
|
|
87
|
-
user.providerUserInfo
|
|
88
|
-
if (
|
|
89
|
-
|
|
98
|
+
for (const providerInfo of user.providerUserInfo) {
|
|
99
|
+
if (PROVIDER_ID_INDEX_MAP.has(providerInfo.providerId)) {
|
|
100
|
+
newUser.providerUserInfo.push(_.pick(providerInfo, EXPORTED_PROVIDER_USER_INFO_KEYS));
|
|
90
101
|
}
|
|
91
|
-
|
|
92
|
-
});
|
|
102
|
+
}
|
|
93
103
|
}
|
|
94
104
|
return newUser;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
105
|
+
}
|
|
106
|
+
function validateOptions(options, fileName) {
|
|
107
|
+
const exportOptions = {};
|
|
98
108
|
if (fileName === undefined) {
|
|
99
|
-
throw new FirebaseError("Must specify data file"
|
|
109
|
+
throw new error_1.FirebaseError("Must specify data file");
|
|
100
110
|
}
|
|
101
|
-
|
|
111
|
+
const extName = path.extname(fileName.toLowerCase());
|
|
102
112
|
if (extName === ".csv") {
|
|
103
113
|
exportOptions.format = "csv";
|
|
104
114
|
}
|
|
@@ -106,44 +116,44 @@ var validateOptions = function (options, fileName) {
|
|
|
106
116
|
exportOptions.format = "json";
|
|
107
117
|
}
|
|
108
118
|
else if (options.format) {
|
|
109
|
-
|
|
119
|
+
const format = options.format.toLowerCase();
|
|
110
120
|
if (format === "csv" || format === "json") {
|
|
111
121
|
exportOptions.format = format;
|
|
112
122
|
}
|
|
113
123
|
else {
|
|
114
|
-
throw new FirebaseError("Unsupported data file format, should be csv or json"
|
|
124
|
+
throw new error_1.FirebaseError("Unsupported data file format, should be csv or json");
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
127
|
else {
|
|
118
|
-
throw new FirebaseError("Please specify data file format in file name, or use `format` parameter"
|
|
119
|
-
exit: 1,
|
|
120
|
-
});
|
|
128
|
+
throw new error_1.FirebaseError("Please specify data file format in file name, or use `format` parameter");
|
|
121
129
|
}
|
|
122
130
|
return exportOptions;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
131
|
+
}
|
|
132
|
+
exports.validateOptions = validateOptions;
|
|
133
|
+
function createWriteUsersToFile() {
|
|
134
|
+
let jsonSep = "";
|
|
135
|
+
return (userList, format, writeStream) => {
|
|
136
|
+
userList.map((user) => {
|
|
128
137
|
if (user.passwordHash && user.version !== 0) {
|
|
129
138
|
delete user.passwordHash;
|
|
130
139
|
delete user.salt;
|
|
131
140
|
}
|
|
132
141
|
if (format === "csv") {
|
|
133
|
-
writeStream.write(
|
|
142
|
+
writeStream.write(transUserToArray(user).join(",") + "," + os.EOL, "utf8");
|
|
134
143
|
}
|
|
135
144
|
else {
|
|
136
|
-
writeStream.write(jsonSep + JSON.stringify(
|
|
145
|
+
writeStream.write(jsonSep + JSON.stringify(transUserJson(user), null, 2), "utf8");
|
|
137
146
|
jsonSep = "," + os.EOL;
|
|
138
147
|
}
|
|
139
148
|
});
|
|
140
149
|
};
|
|
141
|
-
}
|
|
142
|
-
|
|
150
|
+
}
|
|
151
|
+
async function serialExportUsers(projectId, options) {
|
|
152
|
+
var _a;
|
|
143
153
|
if (!options.writeUsersToFile) {
|
|
144
|
-
options.writeUsersToFile =
|
|
154
|
+
options.writeUsersToFile = createWriteUsersToFile();
|
|
145
155
|
}
|
|
146
|
-
|
|
156
|
+
const postBody = {
|
|
147
157
|
targetProjectId: projectId,
|
|
148
158
|
maxResults: options.batchSize,
|
|
149
159
|
};
|
|
@@ -153,13 +163,12 @@ var serialExportUsers = function (projectId, options) {
|
|
|
153
163
|
if (!options.timeoutRetryCount) {
|
|
154
164
|
options.timeoutRetryCount = 0;
|
|
155
165
|
}
|
|
156
|
-
|
|
157
|
-
.post("/identitytoolkit/v3/relyingparty/downloadAccount", postBody, {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
.then(function (ret) {
|
|
166
|
+
try {
|
|
167
|
+
const ret = await apiClient.post("/identitytoolkit/v3/relyingparty/downloadAccount", postBody, {
|
|
168
|
+
skipLog: { resBody: true },
|
|
169
|
+
});
|
|
161
170
|
options.timeoutRetryCount = 0;
|
|
162
|
-
|
|
171
|
+
const userList = ret.body.users;
|
|
163
172
|
if (userList && userList.length > 0) {
|
|
164
173
|
options.writeUsersToFile(userList, options.format, options.writeStream);
|
|
165
174
|
utils.logSuccess("Exported " + userList.length + " account(s) successfully.");
|
|
@@ -169,19 +178,21 @@ var serialExportUsers = function (projectId, options) {
|
|
|
169
178
|
options.nextPageToken = ret.body.nextPageToken;
|
|
170
179
|
return serialExportUsers(projectId, options);
|
|
171
180
|
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (err.original.code === "ETIMEDOUT") {
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
if (((_a = err.original) === null || _a === void 0 ? void 0 : _a.code) === "ETIMEDOUT") {
|
|
175
184
|
options.timeoutRetryCount++;
|
|
176
185
|
if (options.timeoutRetryCount > 5) {
|
|
177
186
|
return err;
|
|
178
187
|
}
|
|
179
188
|
return serialExportUsers(projectId, options);
|
|
180
189
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
190
|
+
if (err instanceof error_1.FirebaseError) {
|
|
191
|
+
throw err;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
throw new error_1.FirebaseError(`Failed to export accounts: ${err}`, { original: err });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
exports.serialExportUsers = serialExportUsers;
|
package/lib/commands/deploy.js
CHANGED
|
@@ -6,7 +6,7 @@ const { checkServiceAccountIam } = require("../deploy/functions/checkIam");
|
|
|
6
6
|
const checkValidTargetFilters = require("../checkValidTargetFilters");
|
|
7
7
|
const { Command } = require("../command");
|
|
8
8
|
const deploy = require("../deploy");
|
|
9
|
-
const requireConfig = require("../requireConfig");
|
|
9
|
+
const { requireConfig } = require("../requireConfig");
|
|
10
10
|
const { filterTargets } = require("../filterTargets");
|
|
11
11
|
const { requireHostingSite } = require("../requireHostingSite");
|
|
12
12
|
const VALID_TARGETS = [
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var { Command } = require("../command");
|
|
3
3
|
var { requirePermissions } = require("../requirePermissions");
|
|
4
4
|
var { actionFunction } = require("../functionsShellCommandAction");
|
|
5
|
-
var requireConfig = require("../requireConfig");
|
|
5
|
+
var { requireConfig } = require("../requireConfig");
|
|
6
6
|
module.exports = new Command("experimental:functions:shell")
|
|
7
7
|
.description("launch full Node shell with emulated functions. (Alias for `firebase functions:shell.)")
|
|
8
8
|
.option("-p, --port <port>", "the port on which to emulate functions (default: 5000)", 5000)
|
|
@@ -35,7 +35,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
35
35
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
36
36
|
.action(async (instanceId, options) => {
|
|
37
37
|
var _a;
|
|
38
|
-
const projectId = (0, projectUtils_1.
|
|
38
|
+
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
39
39
|
if (options.local) {
|
|
40
40
|
if (options.nonInteractive) {
|
|
41
41
|
throw new error_1.FirebaseError(`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead`);
|
|
@@ -58,12 +58,13 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
58
58
|
instanceId,
|
|
59
59
|
reconfiguring: true,
|
|
60
60
|
});
|
|
61
|
-
const
|
|
61
|
+
const newParamOptions = Object.assign(Object.assign({}, (0, paramHelper_1.buildBindingOptionsWithBaseValue)(oldParamValues)), mutableParamsBindingOptions);
|
|
62
62
|
await manifest.writeToManifest([
|
|
63
63
|
{
|
|
64
64
|
instanceId,
|
|
65
65
|
ref: targetRef,
|
|
66
|
-
params:
|
|
66
|
+
params: newParamOptions,
|
|
67
|
+
paramSpecs: extensionVersion.spec.params,
|
|
67
68
|
},
|
|
68
69
|
], config, {
|
|
69
70
|
nonInteractive: false,
|
|
@@ -76,7 +77,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
76
77
|
try {
|
|
77
78
|
let existingInstance;
|
|
78
79
|
try {
|
|
79
|
-
existingInstance = await extensionsApi.getInstance(projectId, instanceId);
|
|
80
|
+
existingInstance = await extensionsApi.getInstance((0, projectUtils_1.needProjectId)({ projectId }), instanceId);
|
|
80
81
|
}
|
|
81
82
|
catch (err) {
|
|
82
83
|
if (err.status === 404) {
|
|
@@ -112,13 +113,13 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
112
113
|
}
|
|
113
114
|
spinner.start();
|
|
114
115
|
const res = await extensionsApi.configureInstance({
|
|
115
|
-
projectId,
|
|
116
|
+
projectId: (0, projectUtils_1.needProjectId)({ projectId }),
|
|
116
117
|
instanceId,
|
|
117
118
|
params: paramBindings,
|
|
118
119
|
});
|
|
119
120
|
spinner.stop();
|
|
120
121
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully configured ${clc.bold(instanceId)}.`);
|
|
121
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your reconfigured instance in the Firebase console: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=config`)}`));
|
|
122
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your reconfigured instance in the Firebase console: ${utils.consoleUrl((0, projectUtils_1.needProjectId)({ projectId }), `/extensions/instances/${instanceId}?tab=config`)}`));
|
|
122
123
|
manifest.showDeprecationWarning();
|
|
123
124
|
return res;
|
|
124
125
|
}
|
|
@@ -6,6 +6,7 @@ const planner = require("../deploy/extensions/planner");
|
|
|
6
6
|
const export_1 = require("../extensions/export");
|
|
7
7
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
8
8
|
const manifest = require("../extensions/manifest");
|
|
9
|
+
const paramHelper_1 = require("../extensions/paramHelper");
|
|
9
10
|
const functional_1 = require("../functional");
|
|
10
11
|
const getProjectNumber_1 = require("../getProjectNumber");
|
|
11
12
|
const logger_1 = require("../logger");
|
|
@@ -41,8 +42,13 @@ module.exports = new command_1.Command("ext:export")
|
|
|
41
42
|
logger_1.logger.info("Exiting. No changes made.");
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
45
|
+
const manifestSpecs = withRef.map((spec) => ({
|
|
46
|
+
instanceId: spec.instanceId,
|
|
47
|
+
ref: spec.ref,
|
|
48
|
+
params: (0, paramHelper_1.buildBindingOptionsWithBaseValue)(spec.params),
|
|
49
|
+
}));
|
|
44
50
|
const existingConfig = manifest.loadConfig(options);
|
|
45
|
-
await manifest.writeToManifest(
|
|
51
|
+
await manifest.writeToManifest(manifestSpecs, existingConfig, {
|
|
46
52
|
nonInteractive: options.nonInteractive,
|
|
47
53
|
force: options.force,
|
|
48
54
|
}, true);
|
|
@@ -47,7 +47,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
47
47
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
48
48
|
.action(async (extensionName, options) => {
|
|
49
49
|
var _a;
|
|
50
|
-
const projectId = (0, projectUtils_1.
|
|
50
|
+
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
51
51
|
const paramsEnvPath = ((_a = options.params) !== null && _a !== void 0 ? _a : "");
|
|
52
52
|
let learnMore = false;
|
|
53
53
|
if (!extensionName) {
|
|
@@ -71,7 +71,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
71
71
|
if (options.local) {
|
|
72
72
|
throw new error_1.FirebaseError("Installing a local source locally is not supported yet, please use ext:dev:emulator commands");
|
|
73
73
|
}
|
|
74
|
-
source = await infoInstallBySource(projectId, extensionName);
|
|
74
|
+
source = await infoInstallBySource((0, projectUtils_1.needProjectId)({ projectId }), extensionName);
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
77
|
void (0, track_1.track)("Extension Install", "Install by Extension Ref", options.interactive ? 1 : 0);
|
|
@@ -120,7 +120,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
120
120
|
try {
|
|
121
121
|
return installExtension({
|
|
122
122
|
paramsEnvPath,
|
|
123
|
-
projectId,
|
|
123
|
+
projectId: projectId,
|
|
124
124
|
extensionName,
|
|
125
125
|
source,
|
|
126
126
|
extVersion,
|
|
@@ -183,19 +183,20 @@ async function installToManifest(options) {
|
|
|
183
183
|
paramsEnvPath,
|
|
184
184
|
instanceId,
|
|
185
185
|
});
|
|
186
|
-
const params = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
187
186
|
const ref = refs.parse(extVersion.ref);
|
|
188
187
|
await manifest.writeToManifest([
|
|
189
188
|
{
|
|
190
189
|
instanceId,
|
|
191
190
|
ref,
|
|
192
|
-
params,
|
|
191
|
+
params: paramBindingOptions,
|
|
192
|
+
paramSpecs: spec.params,
|
|
193
193
|
},
|
|
194
194
|
], config, { nonInteractive, force: force !== null && force !== void 0 ? force : false });
|
|
195
195
|
manifest.showPreviewWarning();
|
|
196
196
|
}
|
|
197
197
|
async function installExtension(options) {
|
|
198
|
-
const {
|
|
198
|
+
const { extensionName, source, extVersion, paramsEnvPath, nonInteractive, force } = options;
|
|
199
|
+
const projectId = (0, projectUtils_1.needProjectId)({ projectId: options.projectId });
|
|
199
200
|
const spec = (source === null || source === void 0 ? void 0 : source.spec) || (extVersion === null || extVersion === void 0 ? void 0 : extVersion.spec);
|
|
200
201
|
if (!spec) {
|
|
201
202
|
throw new error_1.FirebaseError(`Could not find the extension.yaml for ${extensionName}. Please make sure this is a valid extension and try again.`);
|
|
@@ -42,8 +42,8 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
42
42
|
.option("--local", "save the update to firebase.json rather than directly update an existing Extension instance on a Firebase project")
|
|
43
43
|
.action(async (instanceId, updateSource, options) => {
|
|
44
44
|
var _a, _b;
|
|
45
|
-
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
46
45
|
if (options.local) {
|
|
46
|
+
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
47
47
|
const config = manifest.loadConfig(options);
|
|
48
48
|
const oldRef = manifest.getInstanceRef(instanceId, config);
|
|
49
49
|
const oldExtensionVersion = await extensionsApi.getExtensionVersion(refs.toExtensionVersionRef(oldRef));
|
|
@@ -79,12 +79,12 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
79
79
|
nonInteractive: options.nonInteractive,
|
|
80
80
|
instanceId,
|
|
81
81
|
});
|
|
82
|
-
const newParamBindings = paramHelper.getBaseParamBindings(newParamBindingOptions);
|
|
83
82
|
await manifest.writeToManifest([
|
|
84
83
|
{
|
|
85
84
|
instanceId,
|
|
86
85
|
ref: refs.parse(newExtensionVersion.ref),
|
|
87
|
-
params:
|
|
86
|
+
params: newParamBindingOptions,
|
|
87
|
+
paramSpecs: newExtensionVersion.spec.params,
|
|
88
88
|
},
|
|
89
89
|
], config, {
|
|
90
90
|
nonInteractive: options.nonInteractive,
|
|
@@ -95,6 +95,7 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
95
95
|
}
|
|
96
96
|
const spinner = ora(`Updating ${clc.bold(instanceId)}. This usually takes 3 to 5 minutes...`);
|
|
97
97
|
try {
|
|
98
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
98
99
|
let existingInstance;
|
|
99
100
|
try {
|
|
100
101
|
existingInstance = await extensionsApi.getInstance(projectId, instanceId);
|
|
@@ -12,7 +12,8 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
const functional_1 = require("../functional");
|
|
14
14
|
const configExport = require("../functions/runtimeConfigExport");
|
|
15
|
-
const
|
|
15
|
+
const requireConfig_1 = require("../requireConfig");
|
|
16
|
+
const projectConfig_1 = require("../functions/projectConfig");
|
|
16
17
|
const REQUIRED_PERMISSIONS = [
|
|
17
18
|
"runtimeconfig.configs.list",
|
|
18
19
|
"runtimeconfig.configs.get",
|
|
@@ -76,9 +77,11 @@ exports.default = new command_1.Command("functions:config:export")
|
|
|
76
77
|
"runtimeconfig.variables.list",
|
|
77
78
|
"runtimeconfig.variables.get",
|
|
78
79
|
])
|
|
79
|
-
.before(requireConfig)
|
|
80
|
+
.before(requireConfig_1.requireConfig)
|
|
80
81
|
.before(requireInteractive_1.default)
|
|
81
82
|
.action(async (options) => {
|
|
83
|
+
const config = (0, projectConfig_1.normalizeAndValidate)(options.config.src.functions)[0];
|
|
84
|
+
const functionsDir = config.source;
|
|
82
85
|
let pInfos = configExport.getProjectInfos(options);
|
|
83
86
|
checkReservedAliases(pInfos);
|
|
84
87
|
(0, utils_1.logBullet)("Importing functions configs from projects [" +
|
|
@@ -108,7 +111,6 @@ exports.default = new command_1.Command("functions:config:export")
|
|
|
108
111
|
const filesToWrite = fromEntries((0, functional_1.zip)(filenames, dotEnvs));
|
|
109
112
|
filesToWrite[".env.local"] = `${header}\n# .env.local file contains environment variables for the Functions Emulator.\n`;
|
|
110
113
|
filesToWrite[".env"] = `${header}# .env file contains environment variables that applies to all projects.\n`;
|
|
111
|
-
const functionsDir = options.config.get("functions.source", ".");
|
|
112
114
|
for (const [filename, content] of Object.entries(filesToWrite)) {
|
|
113
115
|
await options.config.askWriteProjectFile(path.join(functionsDir, filename), content);
|
|
114
116
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var { Command } = require("../command");
|
|
3
3
|
var { requirePermissions } = require("../requirePermissions");
|
|
4
4
|
var { actionFunction } = require("../functionsShellCommandAction");
|
|
5
|
-
var requireConfig = require("../requireConfig");
|
|
5
|
+
var { requireConfig } = require("../requireConfig");
|
|
6
6
|
var commandUtils = require("../emulator/commandUtils");
|
|
7
7
|
module.exports = new Command("functions:shell")
|
|
8
8
|
.description("launch full Node shell with emulated functions")
|
|
@@ -10,7 +10,7 @@ const prompt_1 = require("../prompt");
|
|
|
10
10
|
const requirePermissions_1 = require("../requirePermissions");
|
|
11
11
|
const projectUtils_1 = require("../projectUtils");
|
|
12
12
|
const logger_1 = require("../logger");
|
|
13
|
-
const
|
|
13
|
+
const requireConfig_1 = require("../requireConfig");
|
|
14
14
|
const { marked } = require("marked");
|
|
15
15
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
16
16
|
const LOG_TAG = "hosting:channel";
|
|
@@ -18,7 +18,7 @@ exports.default = new command_1.Command("hosting:channel:create [channelId]")
|
|
|
18
18
|
.description("create a Firebase Hosting channel")
|
|
19
19
|
.option("-e, --expires <duration>", "duration string (e.g. 12h or 30d) for channel expiration, max 30d")
|
|
20
20
|
.option("--site <siteId>", "site for which to create the channel")
|
|
21
|
-
.before(requireConfig)
|
|
21
|
+
.before(requireConfig_1.requireConfig)
|
|
22
22
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
23
23
|
.before(requireHostingSite_1.requireHostingSite)
|
|
24
24
|
.action(async (channelId, options) => {
|
|
@@ -9,13 +9,13 @@ const prompt_1 = require("../prompt");
|
|
|
9
9
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
10
10
|
const requirePermissions_1 = require("../requirePermissions");
|
|
11
11
|
const projectUtils_1 = require("../projectUtils");
|
|
12
|
-
const
|
|
12
|
+
const requireConfig_1 = require("../requireConfig");
|
|
13
13
|
const logger_1 = require("../logger");
|
|
14
14
|
exports.default = new command_1.Command("hosting:channel:delete <channelId>")
|
|
15
15
|
.description("delete a Firebase Hosting channel")
|
|
16
16
|
.withForce()
|
|
17
17
|
.option("--site <siteId>", "site in which the channel exists")
|
|
18
|
-
.before(requireConfig)
|
|
18
|
+
.before(requireConfig_1.requireConfig)
|
|
19
19
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
20
20
|
.before(requireHostingSite_1.requireHostingSite)
|
|
21
21
|
.action(async (channelId, options) => {
|
|
@@ -9,7 +9,7 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
9
9
|
const deploy = require("../deploy");
|
|
10
10
|
const projectUtils_1 = require("../projectUtils");
|
|
11
11
|
const logger_1 = require("../logger");
|
|
12
|
-
const
|
|
12
|
+
const requireConfig_1 = require("../requireConfig");
|
|
13
13
|
const expireUtils_1 = require("../hosting/expireUtils");
|
|
14
14
|
const utils_1 = require("../utils");
|
|
15
15
|
const { marked } = require("marked");
|
|
@@ -21,7 +21,7 @@ exports.default = new command_1.Command("hosting:channel:deploy [channelId]")
|
|
|
21
21
|
.option("--only <target1,target2...>", "only create previews for specified targets")
|
|
22
22
|
.option("--open", "open a browser to the channel after deploying")
|
|
23
23
|
.option("--no-authorized-domains", "do not sync channel domains with Firebase Auth")
|
|
24
|
-
.before(requireConfig)
|
|
24
|
+
.before(requireConfig_1.requireConfig)
|
|
25
25
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
26
26
|
.before(requireHostingSite_1.requireHostingSite)
|
|
27
27
|
.action(async (channelId, options) => {
|
|
@@ -7,14 +7,14 @@ const command_1 = require("../command");
|
|
|
7
7
|
const requirePermissions_1 = require("../requirePermissions");
|
|
8
8
|
const projectUtils_1 = require("../projectUtils");
|
|
9
9
|
const logger_1 = require("../logger");
|
|
10
|
-
const
|
|
10
|
+
const requireConfig_1 = require("../requireConfig");
|
|
11
11
|
const utils_1 = require("../utils");
|
|
12
12
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
13
13
|
const TABLE_HEAD = ["Channel ID", "Last Release Time", "URL", "Expire Time"];
|
|
14
14
|
exports.default = new command_1.Command("hosting:channel:list")
|
|
15
15
|
.description("list all Firebase Hosting channels for your project")
|
|
16
16
|
.option("--site <siteName>", "list channels for the specified site")
|
|
17
|
-
.before(requireConfig)
|
|
17
|
+
.before(requireConfig_1.requireConfig)
|
|
18
18
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
19
19
|
.before(requireHostingSite_1.requireHostingSite)
|
|
20
20
|
.action(async (options) => {
|
|
@@ -8,7 +8,7 @@ const error_1 = require("../error");
|
|
|
8
8
|
const api_1 = require("../hosting/api");
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const projectUtils_1 = require("../projectUtils");
|
|
11
|
-
const
|
|
11
|
+
const requireConfig_1 = require("../requireConfig");
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
const prompt_1 = require("../prompt");
|
|
14
14
|
const requireHostingSite_1 = require("../requireHostingSite");
|
|
@@ -16,7 +16,7 @@ exports.default = new command_1.Command("hosting:channel:open [channelId]")
|
|
|
16
16
|
.description("opens the URL for a Firebase Hosting channel")
|
|
17
17
|
.help("if unable to open the URL in a browser, it will be displayed in the output")
|
|
18
18
|
.option("--site <siteId>", "the site to which the channel belongs")
|
|
19
|
-
.before(requireConfig)
|
|
19
|
+
.before(requireConfig_1.requireConfig)
|
|
20
20
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.get"])
|
|
21
21
|
.before(requireHostingSite_1.requireHostingSite)
|
|
22
22
|
.action(async (channelId, options) => {
|
|
@@ -8,13 +8,13 @@ const prompt_1 = require("../prompt");
|
|
|
8
8
|
const error_1 = require("../error");
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const projectUtils_1 = require("../projectUtils");
|
|
11
|
-
const
|
|
11
|
+
const requireConfig_1 = require("../requireConfig");
|
|
12
12
|
const logger_1 = require("../logger");
|
|
13
13
|
const LOG_TAG = "hosting:sites";
|
|
14
14
|
exports.default = new command_1.Command("hosting:sites:delete <siteId>")
|
|
15
15
|
.description("delete a Firebase Hosting site")
|
|
16
16
|
.withForce()
|
|
17
|
-
.before(requireConfig)
|
|
17
|
+
.before(requireConfig_1.requireConfig)
|
|
18
18
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.delete"])
|
|
19
19
|
.action(async (siteId, options) => {
|
|
20
20
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
package/lib/commands/serve.js
CHANGED
|
@@ -5,7 +5,7 @@ var { Command } = require("../command");
|
|
|
5
5
|
const { logger } = require("../logger");
|
|
6
6
|
var utils = require("../utils");
|
|
7
7
|
var { requirePermissions } = require("../requirePermissions");
|
|
8
|
-
var requireConfig = require("../requireConfig");
|
|
8
|
+
var { requireConfig } = require("../requireConfig");
|
|
9
9
|
var { serve } = require("../serve/index");
|
|
10
10
|
var { filterTargets } = require("../filterTargets");
|
|
11
11
|
var { needProjectNumber } = require("../projectUtils");
|
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const clc = require("cli-color");
|
|
4
4
|
const command_1 = require("../command");
|
|
5
5
|
const logger_1 = require("../logger");
|
|
6
|
-
const
|
|
6
|
+
const requireConfig_1 = require("../requireConfig");
|
|
7
7
|
const utils = require("../utils");
|
|
8
8
|
const error_1 = require("../error");
|
|
9
9
|
exports.default = new command_1.Command("target:apply <type> <name> <resources...>")
|
|
10
10
|
.description("apply a deploy target to a resource")
|
|
11
|
-
.before(requireConfig)
|
|
11
|
+
.before(requireConfig_1.requireConfig)
|
|
12
12
|
.action((type, name, resources, options) => {
|
|
13
13
|
if (!options.project) {
|
|
14
14
|
throw new error_1.FirebaseError(`Must have an active project to set deploy targets. Try ${clc.bold("firebase use --add")}`);
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const clc = require("cli-color");
|
|
4
4
|
const command_1 = require("../command");
|
|
5
|
-
const
|
|
5
|
+
const requireConfig_1 = require("../requireConfig");
|
|
6
6
|
const utils = require("../utils");
|
|
7
7
|
exports.default = new command_1.Command("target:clear <type> <target>")
|
|
8
8
|
.description("clear all resources from a named resource target")
|
|
9
|
-
.before(requireConfig)
|
|
9
|
+
.before(requireConfig_1.requireConfig)
|
|
10
10
|
.action((type, name, options) => {
|
|
11
11
|
const existed = options.rc.clearTarget(options.project, type, name);
|
|
12
12
|
if (existed) {
|