firebase-tools 10.3.0 → 10.4.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 +95 -84
- package/lib/commands/deploy.js +1 -1
- package/lib/commands/experimental-functions-shell.js +1 -1
- package/lib/commands/ext-configure.js +13 -6
- package/lib/commands/ext-export.js +7 -1
- package/lib/commands/ext-install.js +12 -7
- package/lib/commands/ext-update.js +5 -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/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/runtimes/node/parseTriggers.js +12 -5
- 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 +4 -4
- package/lib/emulator/functionsEmulatorShared.js +17 -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 +103 -28
- package/lib/extensions/manifest.js +38 -6
- package/lib/extensions/paramHelper.js +28 -6
- package/lib/fsutils.js +14 -1
- package/lib/functions/projectConfig.js +34 -0
- package/lib/gcp/cloudfunctions.js +5 -4
- 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/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)
|
|
@@ -18,6 +18,7 @@ const logger_1 = require("../logger");
|
|
|
18
18
|
const refs = require("../extensions/refs");
|
|
19
19
|
const manifest = require("../extensions/manifest");
|
|
20
20
|
const functional_1 = require("../functional");
|
|
21
|
+
const paramHelper_1 = require("../extensions/paramHelper");
|
|
21
22
|
marked.setOptions({
|
|
22
23
|
renderer: new TerminalRenderer(),
|
|
23
24
|
});
|
|
@@ -49,7 +50,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
49
50
|
const [immutableParams, tbdParams] = (0, functional_1.partition)(extensionVersion.spec.params, (param) => { var _a; return (_a = param.immutable) !== null && _a !== void 0 ? _a : false; });
|
|
50
51
|
infoImmutableParams(immutableParams, oldParamValues);
|
|
51
52
|
paramHelper.setNewDefaults(tbdParams, oldParamValues);
|
|
52
|
-
const
|
|
53
|
+
const mutableParamsBindingOptions = await paramHelper.getParams({
|
|
53
54
|
projectId,
|
|
54
55
|
paramSpecs: tbdParams,
|
|
55
56
|
nonInteractive: false,
|
|
@@ -57,12 +58,13 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
57
58
|
instanceId,
|
|
58
59
|
reconfiguring: true,
|
|
59
60
|
});
|
|
60
|
-
const
|
|
61
|
+
const newParamOptions = Object.assign(Object.assign({}, (0, paramHelper_1.buildBindingOptionsWithBaseValue)(oldParamValues)), mutableParamsBindingOptions);
|
|
61
62
|
await manifest.writeToManifest([
|
|
62
63
|
{
|
|
63
64
|
instanceId,
|
|
64
65
|
ref: targetRef,
|
|
65
|
-
params:
|
|
66
|
+
params: newParamOptions,
|
|
67
|
+
paramSpecs: extensionVersion.spec.params,
|
|
66
68
|
},
|
|
67
69
|
], config, {
|
|
68
70
|
nonInteractive: false,
|
|
@@ -87,7 +89,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
87
89
|
}
|
|
88
90
|
const paramSpecWithNewDefaults = paramHelper.getParamsWithCurrentValuesAsDefaults(existingInstance);
|
|
89
91
|
const immutableParams = _.remove(paramSpecWithNewDefaults, (param) => param.immutable);
|
|
90
|
-
const
|
|
92
|
+
const paramBindingOptions = await paramHelper.getParams({
|
|
91
93
|
projectId,
|
|
92
94
|
paramSpecs: paramSpecWithNewDefaults,
|
|
93
95
|
nonInteractive: options.nonInteractive,
|
|
@@ -95,13 +97,14 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
95
97
|
instanceId,
|
|
96
98
|
reconfiguring: true,
|
|
97
99
|
});
|
|
100
|
+
const paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
98
101
|
if (immutableParams.length) {
|
|
99
102
|
const plural = immutableParams.length > 1;
|
|
100
103
|
logger_1.logger.info(`The following param${plural ? "s are" : " is"} immutable:`);
|
|
101
104
|
for (const { param } of immutableParams) {
|
|
102
105
|
const value = _.get(existingInstance, `config.params.${param}`);
|
|
103
106
|
logger_1.logger.info(`param: ${param}, value: ${value}`);
|
|
104
|
-
|
|
107
|
+
paramBindings[param] = value;
|
|
105
108
|
}
|
|
106
109
|
logger_1.logger.info((plural
|
|
107
110
|
? "To set different values for these params"
|
|
@@ -109,7 +112,11 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
109
112
|
", uninstall the extension, then install a new instance of this extension.");
|
|
110
113
|
}
|
|
111
114
|
spinner.start();
|
|
112
|
-
const res = await extensionsApi.configureInstance({
|
|
115
|
+
const res = await extensionsApi.configureInstance({
|
|
116
|
+
projectId,
|
|
117
|
+
instanceId,
|
|
118
|
+
params: paramBindings,
|
|
119
|
+
});
|
|
113
120
|
spinner.stop();
|
|
114
121
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully configured ${clc.bold(instanceId)}.`);
|
|
115
122
|
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your reconfigured instance in the Firebase console: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=config`)}`));
|
|
@@ -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);
|
|
@@ -28,6 +28,7 @@ const track_1 = require("../track");
|
|
|
28
28
|
const logger_1 = require("../logger");
|
|
29
29
|
const previews_1 = require("../previews");
|
|
30
30
|
const manifest = require("../extensions/manifest");
|
|
31
|
+
const paramHelper_1 = require("../extensions/paramHelper");
|
|
31
32
|
marked.setOptions({
|
|
32
33
|
renderer: new TerminalRenderer(),
|
|
33
34
|
});
|
|
@@ -175,7 +176,7 @@ async function installToManifest(options) {
|
|
|
175
176
|
while (manifest.instanceExists(instanceId, config)) {
|
|
176
177
|
instanceId = await (0, extensionsHelper_1.promptForValidInstanceId)(`${spec.name}-${(0, utils_1.getRandomString)(4)}`);
|
|
177
178
|
}
|
|
178
|
-
const
|
|
179
|
+
const paramBindingOptions = await paramHelper.getParams({
|
|
179
180
|
projectId,
|
|
180
181
|
paramSpecs: spec.params,
|
|
181
182
|
nonInteractive,
|
|
@@ -187,7 +188,8 @@ async function installToManifest(options) {
|
|
|
187
188
|
{
|
|
188
189
|
instanceId,
|
|
189
190
|
ref,
|
|
190
|
-
params,
|
|
191
|
+
params: paramBindingOptions,
|
|
192
|
+
paramSpecs: spec.params,
|
|
191
193
|
},
|
|
192
194
|
], config, { nonInteractive, force: force !== null && force !== void 0 ? force : false });
|
|
193
195
|
manifest.showPreviewWarning();
|
|
@@ -259,17 +261,19 @@ async function installExtension(options) {
|
|
|
259
261
|
else {
|
|
260
262
|
choice = "installNew";
|
|
261
263
|
}
|
|
262
|
-
let
|
|
264
|
+
let paramBindingOptions;
|
|
265
|
+
let paramBindings;
|
|
263
266
|
switch (choice) {
|
|
264
267
|
case "installNew":
|
|
265
268
|
instanceId = await (0, extensionsHelper_1.promptForValidInstanceId)(`${instanceId}-${(0, utils_1.getRandomString)(4)}`);
|
|
266
|
-
|
|
269
|
+
paramBindingOptions = await paramHelper.getParams({
|
|
267
270
|
projectId,
|
|
268
271
|
paramSpecs: spec.params,
|
|
269
272
|
nonInteractive,
|
|
270
273
|
paramsEnvPath,
|
|
271
274
|
instanceId,
|
|
272
275
|
});
|
|
276
|
+
paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
273
277
|
spinner.text = "Installing your extension instance. This usually takes 3 to 5 minutes...";
|
|
274
278
|
spinner.start();
|
|
275
279
|
await extensionsApi.createInstance({
|
|
@@ -277,20 +281,21 @@ async function installExtension(options) {
|
|
|
277
281
|
instanceId,
|
|
278
282
|
extensionSource: source,
|
|
279
283
|
extensionVersionRef: extVersion === null || extVersion === void 0 ? void 0 : extVersion.ref,
|
|
280
|
-
params,
|
|
284
|
+
params: paramBindings,
|
|
281
285
|
});
|
|
282
286
|
spinner.stop();
|
|
283
287
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Successfully installed your instance of ${clc.bold(spec.displayName || spec.name)}! ` +
|
|
284
288
|
`Its Instance ID is ${clc.bold(instanceId)}.`);
|
|
285
289
|
break;
|
|
286
290
|
case "updateExisting":
|
|
287
|
-
|
|
291
|
+
paramBindingOptions = await paramHelper.getParams({
|
|
288
292
|
projectId,
|
|
289
293
|
paramSpecs: spec.params,
|
|
290
294
|
nonInteractive,
|
|
291
295
|
paramsEnvPath,
|
|
292
296
|
instanceId,
|
|
293
297
|
});
|
|
298
|
+
paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
|
|
294
299
|
spinner.text = "Updating your extension instance. This usually takes 3 to 5 minutes...";
|
|
295
300
|
spinner.start();
|
|
296
301
|
await (0, updateHelper_1.update)({
|
|
@@ -298,7 +303,7 @@ async function installExtension(options) {
|
|
|
298
303
|
instanceId,
|
|
299
304
|
source,
|
|
300
305
|
extRef: extVersion === null || extVersion === void 0 ? void 0 : extVersion.ref,
|
|
301
|
-
params,
|
|
306
|
+
params: paramBindings,
|
|
302
307
|
});
|
|
303
308
|
spinner.stop();
|
|
304
309
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Successfully updated your instance of ${clc.bold(spec.displayName || spec.name)}! ` +
|
|
@@ -70,7 +70,7 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
70
70
|
instanceId,
|
|
71
71
|
projectDir: config.projectDir,
|
|
72
72
|
});
|
|
73
|
-
const
|
|
73
|
+
const newParamBindingOptions = await paramHelper.getParamsForUpdate({
|
|
74
74
|
spec: oldExtensionVersion.spec,
|
|
75
75
|
newSpec: newExtensionVersion.spec,
|
|
76
76
|
currentParams: oldParamValues,
|
|
@@ -83,7 +83,8 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
83
83
|
{
|
|
84
84
|
instanceId,
|
|
85
85
|
ref: refs.parse(newExtensionVersion.ref),
|
|
86
|
-
params:
|
|
86
|
+
params: newParamBindingOptions,
|
|
87
|
+
paramSpecs: newExtensionVersion.spec.params,
|
|
87
88
|
},
|
|
88
89
|
], config, {
|
|
89
90
|
nonInteractive: options.nonInteractive,
|
|
@@ -195,7 +196,7 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
195
196
|
}
|
|
196
197
|
}
|
|
197
198
|
const oldParamValues = Object.assign({}, existingParams);
|
|
198
|
-
const
|
|
199
|
+
const newParamBindings = await paramHelper.getParamsForUpdate({
|
|
199
200
|
spec: existingSpec,
|
|
200
201
|
newSpec,
|
|
201
202
|
currentParams: existingParams,
|
|
@@ -204,6 +205,7 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
204
205
|
nonInteractive: options.nonInteractive,
|
|
205
206
|
instanceId,
|
|
206
207
|
});
|
|
208
|
+
const newParams = paramHelper.getBaseParamBindings(newParamBindings);
|
|
207
209
|
spinner.start();
|
|
208
210
|
const updateOptions = {
|
|
209
211
|
projectId,
|
|
@@ -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) => {
|