firebase-tools 13.25.0 → 13.26.0
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/appdistribution/client.js +62 -8
- package/lib/appdistribution/distribution.js +1 -1
- package/lib/apphosting/backend.js +4 -4
- package/lib/apphosting/config.js +2 -10
- package/lib/apphosting/secrets/index.js +7 -7
- package/lib/archiveDirectory.js +1 -1
- package/lib/auth.js +1 -1
- package/lib/command.js +9 -1
- package/lib/commands/appdistribution-distribute.js +4 -4
- package/lib/commands/{appdistribution-group-create.js → appdistribution-groups-create.js} +2 -1
- package/lib/commands/{appdistribution-group-delete.js → appdistribution-groups-delete.js} +3 -2
- package/lib/commands/appdistribution-groups-list.js +56 -0
- package/lib/commands/appdistribution-testers-list.js +54 -0
- package/lib/commands/appdistribution-testers-remove.js +1 -1
- package/lib/commands/apphosting-backends-delete.js +3 -1
- package/lib/commands/apphosting-backends-get.js +1 -1
- package/lib/commands/database-import.js +4 -2
- package/lib/commands/database-push.js +4 -2
- package/lib/commands/database-set.js +4 -2
- package/lib/commands/database-settings-get.js +1 -1
- package/lib/commands/database-settings-set.js +1 -1
- package/lib/commands/ext-dev-init.js +2 -2
- package/lib/commands/ext-dev-list.js +1 -1
- package/lib/commands/ext-dev-register.js +2 -2
- package/lib/commands/ext-dev-upload.js +2 -2
- package/lib/commands/ext-dev-usage.js +2 -2
- package/lib/commands/ext-install.js +2 -2
- package/lib/commands/index.js +5 -2
- package/lib/commands/use.js +1 -1
- package/lib/deploy/extensions/deploy.js +3 -1
- package/lib/deploy/extensions/deploymentSummary.js +4 -1
- package/lib/deploy/extensions/planner.js +14 -3
- package/lib/deploy/extensions/prepare.js +9 -9
- package/lib/deploy/functions/ensure.js +1 -1
- package/lib/deploy/lifecycleHooks.js +2 -1
- package/lib/emulator/apphosting/config.js +13 -3
- package/lib/emulator/apphosting/index.js +1 -0
- package/lib/emulator/apphosting/serve.js +9 -7
- package/lib/emulator/controller.js +1 -1
- package/lib/emulator/downloadableEmulators.js +11 -11
- package/lib/emulator/hub.js +10 -7
- package/lib/emulator/ui.js +47 -25
- package/lib/error.js +8 -1
- package/lib/getProjectNumber.js +1 -1
- package/lib/init/features/project.js +7 -6
- package/lib/logger.js +2 -2
- package/lib/management/projects.js +24 -4
- package/lib/projectUtils.js +1 -1
- package/lib/requireDatabaseInstance.js +1 -1
- package/lib/requirePermissions.js +1 -1
- package/lib/rulesDeploy.js +1 -1
- package/lib/templates.js +2 -2
- package/lib/utils.js +5 -8
- package/lib/vsCodeUtils.js +8 -0
- package/package.json +2 -2
- package/schema/firebase-config.json +3 -0
|
@@ -65,7 +65,7 @@ class AppDistributionClient {
|
|
|
65
65
|
await this.appDistroV1Client.patch(`/${releaseName}`, data, { queryParams });
|
|
66
66
|
}
|
|
67
67
|
catch (err) {
|
|
68
|
-
throw new error_1.FirebaseError(`failed to update release notes with ${
|
|
68
|
+
throw new error_1.FirebaseError(`failed to update release notes with ${(0, error_1.getErrMsg)(err)}`);
|
|
69
69
|
}
|
|
70
70
|
utils.logSuccess("added release notes successfully");
|
|
71
71
|
}
|
|
@@ -98,6 +98,39 @@ class AppDistributionClient {
|
|
|
98
98
|
}
|
|
99
99
|
utils.logSuccess("distributed to testers/groups successfully");
|
|
100
100
|
}
|
|
101
|
+
async listTesters(projectName, groupName) {
|
|
102
|
+
const listTestersResponse = {
|
|
103
|
+
testers: [],
|
|
104
|
+
};
|
|
105
|
+
const client = this.appDistroV1Client;
|
|
106
|
+
let pageToken;
|
|
107
|
+
const filter = groupName ? `groups=${projectName}/groups/${groupName}` : null;
|
|
108
|
+
do {
|
|
109
|
+
const queryParams = pageToken ? { pageToken } : {};
|
|
110
|
+
if (filter != null) {
|
|
111
|
+
queryParams["filter"] = filter;
|
|
112
|
+
}
|
|
113
|
+
let apiResponse;
|
|
114
|
+
try {
|
|
115
|
+
apiResponse = await client.get(`${projectName}/testers`, {
|
|
116
|
+
queryParams,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
throw new error_1.FirebaseError(`Client request failed to list testers ${err}`);
|
|
121
|
+
}
|
|
122
|
+
for (const t of apiResponse.body.testers) {
|
|
123
|
+
listTestersResponse.testers.push({
|
|
124
|
+
name: t.name,
|
|
125
|
+
displayName: t.displayName,
|
|
126
|
+
groups: t.groups,
|
|
127
|
+
lastActivityTime: new Date(t.lastActivityTime),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
pageToken = apiResponse.body.nextPageToken;
|
|
131
|
+
} while (pageToken);
|
|
132
|
+
return listTestersResponse;
|
|
133
|
+
}
|
|
101
134
|
async addTesters(projectName, emails) {
|
|
102
135
|
try {
|
|
103
136
|
await this.appDistroV1Client.request({
|
|
@@ -107,7 +140,7 @@ class AppDistributionClient {
|
|
|
107
140
|
});
|
|
108
141
|
}
|
|
109
142
|
catch (err) {
|
|
110
|
-
throw new error_1.FirebaseError(`Failed to add testers ${err}`);
|
|
143
|
+
throw new error_1.FirebaseError(`Failed to add testers ${(0, error_1.getErrMsg)(err)}`);
|
|
111
144
|
}
|
|
112
145
|
utils.logSuccess(`Testers created successfully`);
|
|
113
146
|
}
|
|
@@ -121,10 +154,31 @@ class AppDistributionClient {
|
|
|
121
154
|
});
|
|
122
155
|
}
|
|
123
156
|
catch (err) {
|
|
124
|
-
throw new error_1.FirebaseError(`Failed to remove testers ${err}`);
|
|
157
|
+
throw new error_1.FirebaseError(`Failed to remove testers ${(0, error_1.getErrMsg)(err)}`);
|
|
125
158
|
}
|
|
126
159
|
return apiResponse.body;
|
|
127
160
|
}
|
|
161
|
+
async listGroups(projectName) {
|
|
162
|
+
const listGroupsResponse = {
|
|
163
|
+
groups: [],
|
|
164
|
+
};
|
|
165
|
+
const client = this.appDistroV1Client;
|
|
166
|
+
let pageToken;
|
|
167
|
+
do {
|
|
168
|
+
const queryParams = pageToken ? { pageToken } : {};
|
|
169
|
+
try {
|
|
170
|
+
const apiResponse = await client.get(`${projectName}/groups`, {
|
|
171
|
+
queryParams,
|
|
172
|
+
});
|
|
173
|
+
listGroupsResponse.groups.push(...(apiResponse.body.groups || []));
|
|
174
|
+
pageToken = apiResponse.body.nextPageToken;
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
throw new error_1.FirebaseError(`Client failed to list groups ${err}`);
|
|
178
|
+
}
|
|
179
|
+
} while (pageToken);
|
|
180
|
+
return listGroupsResponse;
|
|
181
|
+
}
|
|
128
182
|
async createGroup(projectName, displayName, alias) {
|
|
129
183
|
let apiResponse;
|
|
130
184
|
try {
|
|
@@ -135,7 +189,7 @@ class AppDistributionClient {
|
|
|
135
189
|
});
|
|
136
190
|
}
|
|
137
191
|
catch (err) {
|
|
138
|
-
throw new error_1.FirebaseError(`Failed to create group ${err}`);
|
|
192
|
+
throw new error_1.FirebaseError(`Failed to create group ${(0, error_1.getErrMsg)(err)}`);
|
|
139
193
|
}
|
|
140
194
|
return apiResponse.body;
|
|
141
195
|
}
|
|
@@ -147,7 +201,7 @@ class AppDistributionClient {
|
|
|
147
201
|
});
|
|
148
202
|
}
|
|
149
203
|
catch (err) {
|
|
150
|
-
throw new error_1.FirebaseError(`Failed to delete group ${err}`);
|
|
204
|
+
throw new error_1.FirebaseError(`Failed to delete group ${(0, error_1.getErrMsg)(err)}`);
|
|
151
205
|
}
|
|
152
206
|
utils.logSuccess(`Group deleted successfully`);
|
|
153
207
|
}
|
|
@@ -160,7 +214,7 @@ class AppDistributionClient {
|
|
|
160
214
|
});
|
|
161
215
|
}
|
|
162
216
|
catch (err) {
|
|
163
|
-
throw new error_1.FirebaseError(`Failed to add testers to group ${err}`);
|
|
217
|
+
throw new error_1.FirebaseError(`Failed to add testers to group ${(0, error_1.getErrMsg)(err)}`);
|
|
164
218
|
}
|
|
165
219
|
utils.logSuccess(`Testers added to group successfully`);
|
|
166
220
|
}
|
|
@@ -173,7 +227,7 @@ class AppDistributionClient {
|
|
|
173
227
|
});
|
|
174
228
|
}
|
|
175
229
|
catch (err) {
|
|
176
|
-
throw new error_1.FirebaseError(`Failed to remove testers from group ${err}`);
|
|
230
|
+
throw new error_1.FirebaseError(`Failed to remove testers from group ${(0, error_1.getErrMsg)(err)}`);
|
|
177
231
|
}
|
|
178
232
|
utils.logSuccess(`Testers removed from group successfully`);
|
|
179
233
|
}
|
|
@@ -190,7 +244,7 @@ class AppDistributionClient {
|
|
|
190
244
|
return response.body;
|
|
191
245
|
}
|
|
192
246
|
catch (err) {
|
|
193
|
-
throw new error_1.FirebaseError(`Failed to create release test ${err}`);
|
|
247
|
+
throw new error_1.FirebaseError(`Failed to create release test ${(0, error_1.getErrMsg)(err)}`);
|
|
194
248
|
}
|
|
195
249
|
}
|
|
196
250
|
async getReleaseTest(releaseTestName) {
|
|
@@ -28,7 +28,7 @@ class Distribution {
|
|
|
28
28
|
stat = fs.statSync(path);
|
|
29
29
|
}
|
|
30
30
|
catch (err) {
|
|
31
|
-
logger_1.logger.info(err);
|
|
31
|
+
logger_1.logger.info((0, error_1.getErrMsg)(err));
|
|
32
32
|
throw new error_1.FirebaseError(`File ${path} does not exist: verify that file points to a binary`);
|
|
33
33
|
}
|
|
34
34
|
if (!stat.isFile()) {
|
|
@@ -172,10 +172,10 @@ async function promptNewBackendId(projectId, location, prompt) {
|
|
|
172
172
|
await apphosting.getBackend(projectId, location, backendId);
|
|
173
173
|
}
|
|
174
174
|
catch (err) {
|
|
175
|
-
if (err
|
|
175
|
+
if ((0, error_1.getErrStatus)(err) === 404) {
|
|
176
176
|
return backendId;
|
|
177
177
|
}
|
|
178
|
-
throw new error_1.FirebaseError(`Failed to check if backend with id ${backendId} already exists in ${location}`, { original: err });
|
|
178
|
+
throw new error_1.FirebaseError(`Failed to check if backend with id ${backendId} already exists in ${location}`, { original: (0, error_1.getError)(err) });
|
|
179
179
|
}
|
|
180
180
|
(0, utils_1.logWarning)(`Backend with id ${backendId} already exists in ${location}`);
|
|
181
181
|
}
|
|
@@ -207,7 +207,7 @@ async function provisionDefaultComputeServiceAccount(projectId) {
|
|
|
207
207
|
await iam.createServiceAccount(projectId, DEFAULT_COMPUTE_SERVICE_ACCOUNT_NAME, "Default service account used to run builds and deploys for Firebase App Hosting", "Firebase App Hosting compute service account");
|
|
208
208
|
}
|
|
209
209
|
catch (err) {
|
|
210
|
-
if (err
|
|
210
|
+
if ((0, error_1.getErrStatus)(err) !== 409) {
|
|
211
211
|
throw err;
|
|
212
212
|
}
|
|
213
213
|
}
|
|
@@ -254,7 +254,7 @@ async function getBackendForLocation(projectId, location, backendId) {
|
|
|
254
254
|
}
|
|
255
255
|
catch (err) {
|
|
256
256
|
throw new error_1.FirebaseError(`No backend named "${backendId}" found in ${location}.`, {
|
|
257
|
-
original: err,
|
|
257
|
+
original: (0, error_1.getError)(err),
|
|
258
258
|
});
|
|
259
259
|
}
|
|
260
260
|
}
|
package/lib/apphosting/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadConfigForEnvironment = exports.maybeAddSecretToYaml = exports.upsertEnv = exports.findEnv = exports.store = exports.load = exports.
|
|
3
|
+
exports.loadConfigForEnvironment = exports.maybeAddSecretToYaml = exports.upsertEnv = exports.findEnv = exports.store = exports.load = exports.listAppHostingFilesInPath = exports.discoverBackendRoot = exports.APPHOSTING_YAML_FILE_REGEX = exports.APPHOSTING_LOCAL_YAML_FILE = exports.APPHOSTING_BASE_YAML_FILE = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const yaml = require("yaml");
|
|
@@ -8,7 +8,6 @@ const fs = require("../fsutils");
|
|
|
8
8
|
const prompt = require("../prompt");
|
|
9
9
|
const dialogs = require("./secrets/dialogs");
|
|
10
10
|
const yaml_1 = require("./yaml");
|
|
11
|
-
const error_1 = require("../error");
|
|
12
11
|
exports.APPHOSTING_BASE_YAML_FILE = "apphosting.yaml";
|
|
13
12
|
exports.APPHOSTING_LOCAL_YAML_FILE = "apphosting.local.yaml";
|
|
14
13
|
exports.APPHOSTING_YAML_FILE_REGEX = /^apphosting(\.[a-z0-9_]+)?\.yaml$/;
|
|
@@ -27,20 +26,13 @@ function discoverBackendRoot(cwd) {
|
|
|
27
26
|
return dir;
|
|
28
27
|
}
|
|
29
28
|
exports.discoverBackendRoot = discoverBackendRoot;
|
|
30
|
-
function discoverConfigsAtBackendRoot(cwd) {
|
|
31
|
-
const backendRoot = discoverBackendRoot(cwd);
|
|
32
|
-
if (!backendRoot) {
|
|
33
|
-
throw new error_1.FirebaseError("Unable to find your project's root, ensure the apphosting.yaml config is initialized. Try 'firebase init apphosting'");
|
|
34
|
-
}
|
|
35
|
-
return listAppHostingFilesInPath(backendRoot);
|
|
36
|
-
}
|
|
37
|
-
exports.discoverConfigsAtBackendRoot = discoverConfigsAtBackendRoot;
|
|
38
29
|
function listAppHostingFilesInPath(path) {
|
|
39
30
|
return fs
|
|
40
31
|
.listFiles(path)
|
|
41
32
|
.filter((file) => exports.APPHOSTING_YAML_FILE_REGEX.test(file))
|
|
42
33
|
.map((file) => (0, path_1.join)(path, file));
|
|
43
34
|
}
|
|
35
|
+
exports.listAppHostingFilesInPath = listAppHostingFilesInPath;
|
|
44
36
|
function load(yamlPath) {
|
|
45
37
|
const raw = fs.readFile(yamlPath);
|
|
46
38
|
return yaml.parseDocument(raw);
|
|
@@ -59,14 +59,14 @@ async function grantSecretAccess(projectId, projectNumber, secretName, accounts)
|
|
|
59
59
|
existingBindings = (await gcsm.getIamPolicy({ projectId, name: secretName })).bindings || [];
|
|
60
60
|
}
|
|
61
61
|
catch (err) {
|
|
62
|
-
throw new error_1.FirebaseError(`Failed to get IAM bindings on secret: ${secretName}. Ensure you have the permissions to do so and try again.`, { original: err });
|
|
62
|
+
throw new error_1.FirebaseError(`Failed to get IAM bindings on secret: ${secretName}. Ensure you have the permissions to do so and try again.`, { original: (0, error_1.getError)(err) });
|
|
63
63
|
}
|
|
64
64
|
try {
|
|
65
65
|
const updatedBindings = existingBindings.concat(newBindings);
|
|
66
66
|
await gcsm.setIamPolicy({ projectId, name: secretName }, updatedBindings);
|
|
67
67
|
}
|
|
68
68
|
catch (err) {
|
|
69
|
-
throw new error_1.FirebaseError(`Failed to set IAM bindings ${JSON.stringify(newBindings)} on secret: ${secretName}. Ensure you have the permissions to do so and try again.`, { original: err });
|
|
69
|
+
throw new error_1.FirebaseError(`Failed to set IAM bindings ${JSON.stringify(newBindings)} on secret: ${secretName}. Ensure you have the permissions to do so and try again.`, { original: (0, error_1.getError)(err) });
|
|
70
70
|
}
|
|
71
71
|
utils.logSuccess(`Successfully set IAM bindings on secret ${secretName}.\n`);
|
|
72
72
|
}
|
|
@@ -78,8 +78,8 @@ async function upsertSecret(project, secret, location) {
|
|
|
78
78
|
existing = await gcsm.getSecret(project, secret);
|
|
79
79
|
}
|
|
80
80
|
catch (err) {
|
|
81
|
-
if (err
|
|
82
|
-
throw new error_1.FirebaseError("Unexpected error loading secret", { original: err });
|
|
81
|
+
if ((0, error_1.getErrStatus)(err) !== 404) {
|
|
82
|
+
throw new error_1.FirebaseError("Unexpected error loading secret", { original: (0, error_1.getError)(err) });
|
|
83
83
|
}
|
|
84
84
|
await gcsm.createSecret(project, secret, gcsm.labels("apphosting"), location);
|
|
85
85
|
return true;
|
|
@@ -129,7 +129,7 @@ async function loadConfigToExport(cwd, userGivenConfigFile) {
|
|
|
129
129
|
if (userGivenConfigFile && !config_1.APPHOSTING_YAML_FILE_REGEX.test(userGivenConfigFile)) {
|
|
130
130
|
throw new error_1.FirebaseError("Invalid apphosting yaml config file provided. File must be in format: 'apphosting.yaml' or 'apphosting.<environment>.yaml'");
|
|
131
131
|
}
|
|
132
|
-
const allConfigs =
|
|
132
|
+
const allConfigs = getValidConfigs(cwd);
|
|
133
133
|
let userGivenConfigFilePath;
|
|
134
134
|
if (userGivenConfigFile) {
|
|
135
135
|
if (!allConfigs.has(userGivenConfigFile)) {
|
|
@@ -147,8 +147,8 @@ async function loadConfigToExport(cwd, userGivenConfigFile) {
|
|
|
147
147
|
return await (0, config_1.loadConfigForEnvironment)(userGivenConfigFilePath, baseFilePath);
|
|
148
148
|
}
|
|
149
149
|
exports.loadConfigToExport = loadConfigToExport;
|
|
150
|
-
function
|
|
151
|
-
const appHostingConfigPaths = (0, config_1.
|
|
150
|
+
function getValidConfigs(cwd) {
|
|
151
|
+
const appHostingConfigPaths = (0, config_1.listAppHostingFilesInPath)(cwd).filter((path) => !path.endsWith(config_1.APPHOSTING_LOCAL_YAML_FILE));
|
|
152
152
|
if (appHostingConfigPaths.length === 0) {
|
|
153
153
|
throw new error_1.FirebaseError("No apphosting.*.yaml configs found");
|
|
154
154
|
}
|
package/lib/archiveDirectory.js
CHANGED
|
@@ -39,7 +39,7 @@ async function archiveDirectory(sourceDirectory, options = {}) {
|
|
|
39
39
|
if (err instanceof error_1.FirebaseError) {
|
|
40
40
|
throw err;
|
|
41
41
|
}
|
|
42
|
-
throw new error_1.FirebaseError("Failed to create archive.", { original: err });
|
|
42
|
+
throw new error_1.FirebaseError("Failed to create archive.", { original: (0, error_1.getError)(err) });
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
exports.archiveDirectory = archiveDirectory;
|
package/lib/auth.js
CHANGED
|
@@ -541,7 +541,7 @@ async function getAccessToken(refreshToken, authScopes) {
|
|
|
541
541
|
return (0, requireAuth_1.refreshAuth)();
|
|
542
542
|
}
|
|
543
543
|
catch (err) {
|
|
544
|
-
logger_1.logger.debug(`Unable to refresh token: ${err}`);
|
|
544
|
+
logger_1.logger.debug(`Unable to refresh token: ${(0, error_1.getErrMsg)(err)}`);
|
|
545
545
|
}
|
|
546
546
|
throw new error_1.FirebaseError("Unable to getAccessToken");
|
|
547
547
|
}
|
package/lib/command.js
CHANGED
|
@@ -19,6 +19,7 @@ class Command {
|
|
|
19
19
|
this.name = "";
|
|
20
20
|
this.descriptionText = "";
|
|
21
21
|
this.options = [];
|
|
22
|
+
this.aliases = [];
|
|
22
23
|
this.actionFn = () => {
|
|
23
24
|
};
|
|
24
25
|
this.befores = [];
|
|
@@ -30,6 +31,10 @@ class Command {
|
|
|
30
31
|
this.descriptionText = t;
|
|
31
32
|
return this;
|
|
32
33
|
}
|
|
34
|
+
alias(alias) {
|
|
35
|
+
this.aliases.push(alias);
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
33
38
|
option(...args) {
|
|
34
39
|
this.options.push(args);
|
|
35
40
|
return this;
|
|
@@ -57,6 +62,9 @@ class Command {
|
|
|
57
62
|
if (this.descriptionText) {
|
|
58
63
|
cmd.description(this.descriptionText);
|
|
59
64
|
}
|
|
65
|
+
if (this.aliases) {
|
|
66
|
+
cmd.aliases(this.aliases);
|
|
67
|
+
}
|
|
60
68
|
this.options.forEach((args) => {
|
|
61
69
|
const flags = args.shift();
|
|
62
70
|
cmd.option(flags, ...args);
|
|
@@ -211,7 +219,7 @@ class Command {
|
|
|
211
219
|
var _a;
|
|
212
220
|
if ((_a = options.project) === null || _a === void 0 ? void 0 : _a.match(/^\d+$/)) {
|
|
213
221
|
await (0, requireAuth_1.requireAuth)(options);
|
|
214
|
-
const { projectId, projectNumber } = await (0, projects_1.
|
|
222
|
+
const { projectId, projectNumber } = await (0, projects_1.getProject)(options.project);
|
|
215
223
|
options.projectId = projectId;
|
|
216
224
|
options.projectNumber = projectNumber;
|
|
217
225
|
}
|
|
@@ -61,13 +61,13 @@ exports.command = new command_1.Command("appdistribution:distribute <release-bin
|
|
|
61
61
|
aabInfo = await requests.getAabInfo(appName);
|
|
62
62
|
}
|
|
63
63
|
catch (err) {
|
|
64
|
-
if (err
|
|
64
|
+
if ((0, error_1.getErrStatus)(err) === 404) {
|
|
65
65
|
throw new error_1.FirebaseError(`App Distribution could not find your app ${options.app}. ` +
|
|
66
66
|
`Make sure to onboard your app by pressing the "Get started" ` +
|
|
67
67
|
"button on the App Distribution page in the Firebase console: " +
|
|
68
68
|
"https://console.firebase.google.com/project/_/appdistribution", { exit: 1 });
|
|
69
69
|
}
|
|
70
|
-
throw new error_1.FirebaseError(`failed to determine AAB info. ${err
|
|
70
|
+
throw new error_1.FirebaseError(`failed to determine AAB info. ${(0, error_1.getErrMsg)(err)}`, { exit: 1 });
|
|
71
71
|
}
|
|
72
72
|
if (aabInfo.integrationState !== types_1.IntegrationState.INTEGRATED &&
|
|
73
73
|
aabInfo.integrationState !== types_1.IntegrationState.AAB_STATE_UNAVAILABLE) {
|
|
@@ -115,13 +115,13 @@ exports.command = new command_1.Command("appdistribution:distribute <release-bin
|
|
|
115
115
|
releaseName = uploadResponse.release.name;
|
|
116
116
|
}
|
|
117
117
|
catch (err) {
|
|
118
|
-
if (err
|
|
118
|
+
if ((0, error_1.getErrStatus)(err) === 404) {
|
|
119
119
|
throw new error_1.FirebaseError(`App Distribution could not find your app ${options.app}. ` +
|
|
120
120
|
`Make sure to onboard your app by pressing the "Get started" ` +
|
|
121
121
|
"button on the App Distribution page in the Firebase console: " +
|
|
122
122
|
"https://console.firebase.google.com/project/_/appdistribution", { exit: 1 });
|
|
123
123
|
}
|
|
124
|
-
throw new error_1.FirebaseError(`Failed to upload release. ${err
|
|
124
|
+
throw new error_1.FirebaseError(`Failed to upload release. ${(0, error_1.getErrMsg)(err)}`, { exit: 1 });
|
|
125
125
|
}
|
|
126
126
|
if (aabInfo && !aabInfo.testCertificate) {
|
|
127
127
|
aabInfo = await requests.getAabInfo(appName);
|
|
@@ -6,8 +6,9 @@ const utils = require("../utils");
|
|
|
6
6
|
const requireAuth_1 = require("../requireAuth");
|
|
7
7
|
const client_1 = require("../appdistribution/client");
|
|
8
8
|
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
9
|
-
exports.command = new command_1.Command("appdistribution:
|
|
9
|
+
exports.command = new command_1.Command("appdistribution:groups:create <displayName> [alias]")
|
|
10
10
|
.description("create group in project")
|
|
11
|
+
.alias("appdistribution:group:create")
|
|
11
12
|
.before(requireAuth_1.requireAuth)
|
|
12
13
|
.action(async (displayName, alias, options) => {
|
|
13
14
|
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
@@ -7,8 +7,9 @@ const requireAuth_1 = require("../requireAuth");
|
|
|
7
7
|
const error_1 = require("../error");
|
|
8
8
|
const client_1 = require("../appdistribution/client");
|
|
9
9
|
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
10
|
-
exports.command = new command_1.Command("appdistribution:
|
|
10
|
+
exports.command = new command_1.Command("appdistribution:groups:delete <alias>")
|
|
11
11
|
.description("delete group from a project")
|
|
12
|
+
.alias("appdistribution:group:delete")
|
|
12
13
|
.before(requireAuth_1.requireAuth)
|
|
13
14
|
.action(async (alias, options) => {
|
|
14
15
|
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
@@ -18,7 +19,7 @@ exports.command = new command_1.Command("appdistribution:group:delete <alias>")
|
|
|
18
19
|
await appDistroClient.deleteGroup(`${projectName}/groups/${alias}`);
|
|
19
20
|
}
|
|
20
21
|
catch (err) {
|
|
21
|
-
throw new error_1.FirebaseError(`Failed to delete group ${err}`);
|
|
22
|
+
throw new error_1.FirebaseError(`Failed to delete group ${(0, error_1.getErrMsg)(err)}`);
|
|
22
23
|
}
|
|
23
24
|
utils.logSuccess(`Group ${alias} has successfully been deleted`);
|
|
24
25
|
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const ora = require("ora");
|
|
5
|
+
const client_1 = require("../appdistribution/client");
|
|
6
|
+
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
7
|
+
const command_1 = require("../command");
|
|
8
|
+
const error_1 = require("../error");
|
|
9
|
+
const logger_1 = require("../logger");
|
|
10
|
+
const requireAuth_1 = require("../requireAuth");
|
|
11
|
+
const utils = require("../utils");
|
|
12
|
+
const Table = require("cli-table");
|
|
13
|
+
exports.command = new command_1.Command("appdistribution:groups:list")
|
|
14
|
+
.description("list groups in project")
|
|
15
|
+
.alias("appdistribution:group:list")
|
|
16
|
+
.before(requireAuth_1.requireAuth)
|
|
17
|
+
.action(async (options) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
20
|
+
const appDistroClient = new client_1.AppDistributionClient();
|
|
21
|
+
let groupsResponse;
|
|
22
|
+
const spinner = ora("Preparing the list of your App Distribution Groups").start();
|
|
23
|
+
try {
|
|
24
|
+
groupsResponse = await appDistroClient.listGroups(projectName);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
spinner.fail();
|
|
28
|
+
throw new error_1.FirebaseError("Failed to list groups.", {
|
|
29
|
+
exit: 1,
|
|
30
|
+
original: err,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
spinner.succeed();
|
|
34
|
+
const groups = (_a = groupsResponse.groups) !== null && _a !== void 0 ? _a : [];
|
|
35
|
+
printGroupsTable(groups);
|
|
36
|
+
utils.logSuccess(`Groups listed successfully`);
|
|
37
|
+
return groupsResponse;
|
|
38
|
+
});
|
|
39
|
+
function printGroupsTable(groups) {
|
|
40
|
+
const tableHead = ["Group", "Display Name", "Tester Count", "Release Count", "Invite Link Count"];
|
|
41
|
+
const table = new Table({
|
|
42
|
+
head: tableHead,
|
|
43
|
+
style: { head: ["green"] },
|
|
44
|
+
});
|
|
45
|
+
for (const group of groups) {
|
|
46
|
+
const name = group.name.split("/").pop();
|
|
47
|
+
table.push([
|
|
48
|
+
name,
|
|
49
|
+
group.displayName,
|
|
50
|
+
group.testerCount || 0,
|
|
51
|
+
group.releaseCount || 0,
|
|
52
|
+
group.inviteLinkCount || 0,
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
logger_1.logger.info(table.toString());
|
|
56
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const ora = require("ora");
|
|
5
|
+
const client_1 = require("../appdistribution/client");
|
|
6
|
+
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
7
|
+
const command_1 = require("../command");
|
|
8
|
+
const error_1 = require("../error");
|
|
9
|
+
const logger_1 = require("../logger");
|
|
10
|
+
const requireAuth_1 = require("../requireAuth");
|
|
11
|
+
const utils = require("../utils");
|
|
12
|
+
const Table = require("cli-table");
|
|
13
|
+
exports.command = new command_1.Command("appdistribution:testers:list [group]")
|
|
14
|
+
.description("list testers in project")
|
|
15
|
+
.before(requireAuth_1.requireAuth)
|
|
16
|
+
.action(async (group, options) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
19
|
+
const appDistroClient = new client_1.AppDistributionClient();
|
|
20
|
+
let testersResponse;
|
|
21
|
+
const spinner = ora("Preparing the list of your App Distribution testers").start();
|
|
22
|
+
try {
|
|
23
|
+
testersResponse = await appDistroClient.listTesters(projectName, group);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
spinner.fail();
|
|
27
|
+
throw new error_1.FirebaseError("Failed to list testers.", {
|
|
28
|
+
exit: 1,
|
|
29
|
+
original: err,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
spinner.succeed();
|
|
33
|
+
const testers = (_a = testersResponse.testers) !== null && _a !== void 0 ? _a : [];
|
|
34
|
+
printTestersTable(testers);
|
|
35
|
+
utils.logSuccess(`Testers listed successfully`);
|
|
36
|
+
return testersResponse;
|
|
37
|
+
});
|
|
38
|
+
function printTestersTable(testers) {
|
|
39
|
+
var _a;
|
|
40
|
+
const tableHead = ["Name", "Display Name", "Last Activity Time", "Groups"];
|
|
41
|
+
const table = new Table({
|
|
42
|
+
head: tableHead,
|
|
43
|
+
style: { head: ["green"] },
|
|
44
|
+
});
|
|
45
|
+
for (const tester of testers) {
|
|
46
|
+
const name = tester.name.split("/").pop();
|
|
47
|
+
const groups = tester.groups
|
|
48
|
+
.map((grp) => grp.split("/").pop())
|
|
49
|
+
.sort()
|
|
50
|
+
.join(";");
|
|
51
|
+
table.push([name, (_a = tester.displayName) !== null && _a !== void 0 ? _a : "", tester.lastActivityTime, groups]);
|
|
52
|
+
}
|
|
53
|
+
logger_1.logger.info(table.toString());
|
|
54
|
+
}
|
|
@@ -28,7 +28,7 @@ exports.command = new command_1.Command("appdistribution:testers:remove [emails.
|
|
|
28
28
|
deleteResponse = await appDistroClient.removeTesters(projectName, emailsArr);
|
|
29
29
|
}
|
|
30
30
|
catch (err) {
|
|
31
|
-
throw new error_1.FirebaseError(`Failed to remove testers ${err}`);
|
|
31
|
+
throw new error_1.FirebaseError(`Failed to remove testers ${(0, error_1.getErrMsg)(err)}`);
|
|
32
32
|
}
|
|
33
33
|
if (!deleteResponse.emails) {
|
|
34
34
|
utils.logSuccess(`Testers did not exist`);
|
|
@@ -44,6 +44,8 @@ exports.command = new command_1.Command("apphosting:backends:delete <backend>")
|
|
|
44
44
|
}
|
|
45
45
|
catch (err) {
|
|
46
46
|
spinner.stop();
|
|
47
|
-
throw new error_1.FirebaseError(`Failed to delete backend: ${backendId}.`, {
|
|
47
|
+
throw new error_1.FirebaseError(`Failed to delete backend: ${backendId}.`, {
|
|
48
|
+
original: (0, error_1.getError)(err),
|
|
49
|
+
});
|
|
48
50
|
}
|
|
49
51
|
});
|
|
@@ -27,7 +27,7 @@ exports.command = new command_1.Command("apphosting:backends:get <backend>")
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
catch (err) {
|
|
30
|
-
throw new error_1.FirebaseError(`Failed to get backend: ${backend}. Please check the parameters you have provided.`, { original: err });
|
|
30
|
+
throw new error_1.FirebaseError(`Failed to get backend: ${backend}. Please check the parameters you have provided.`, { original: (0, error_1.getError)(err) });
|
|
31
31
|
}
|
|
32
32
|
if (backendsList.length === 0) {
|
|
33
33
|
(0, utils_1.logWarning)(`Backend "${backend}" not found`);
|
|
@@ -71,8 +71,10 @@ exports.command = new command_1.Command("database:import <path> [infile]")
|
|
|
71
71
|
if (err instanceof error_1.FirebaseError) {
|
|
72
72
|
throw err;
|
|
73
73
|
}
|
|
74
|
-
logger_1.logger.debug(err);
|
|
75
|
-
throw new error_1.FirebaseError(`Unexpected error while importing data: ${err}`, {
|
|
74
|
+
logger_1.logger.debug((0, error_1.getErrMsg)(err));
|
|
75
|
+
throw new error_1.FirebaseError(`Unexpected error while importing data: ${(0, error_1.getErrMsg)(err)}`, {
|
|
76
|
+
exit: 2,
|
|
77
|
+
});
|
|
76
78
|
}
|
|
77
79
|
if (responses.length) {
|
|
78
80
|
utils.logSuccess("Data persisted successfully");
|
|
@@ -49,8 +49,10 @@ exports.command = new command_1.Command("database:push <path> [infile]")
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
catch (err) {
|
|
52
|
-
logger_1.logger.debug(err);
|
|
53
|
-
throw new error_1.FirebaseError(`Unexpected error while pushing data: ${err}`, {
|
|
52
|
+
logger_1.logger.debug((0, error_1.getErrMsg)(err));
|
|
53
|
+
throw new error_1.FirebaseError(`Unexpected error while pushing data: ${(0, error_1.getErrMsg)(err)}`, {
|
|
54
|
+
exit: 2,
|
|
55
|
+
});
|
|
54
56
|
}
|
|
55
57
|
if (!path.endsWith("/")) {
|
|
56
58
|
path += "/";
|
|
@@ -59,8 +59,10 @@ exports.command = new command_1.Command("database:set <path> [infile]")
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
catch (err) {
|
|
62
|
-
logger_1.logger.debug(err);
|
|
63
|
-
throw new error_1.FirebaseError(`Unexpected error while setting data: ${err}`, {
|
|
62
|
+
logger_1.logger.debug((0, error_1.getErrMsg)(err));
|
|
63
|
+
throw new error_1.FirebaseError(`Unexpected error while setting data: ${(0, error_1.getErrMsg)(err)}`, {
|
|
64
|
+
exit: 2,
|
|
65
|
+
});
|
|
64
66
|
}
|
|
65
67
|
utils.logSuccess("Data persisted successfully");
|
|
66
68
|
logger_1.logger.info();
|
|
@@ -34,7 +34,7 @@ exports.command = new command_1.Command("database:settings:get <path>")
|
|
|
34
34
|
catch (err) {
|
|
35
35
|
throw new error_1.FirebaseError(`Unexpected error fetching configs at ${path}`, {
|
|
36
36
|
exit: 2,
|
|
37
|
-
original: err,
|
|
37
|
+
original: (0, error_1.getError)(err),
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
if (typeof res.body === "object") {
|
|
@@ -38,7 +38,7 @@ exports.command = new command_1.Command("database:settings:set <path> <value>")
|
|
|
38
38
|
catch (err) {
|
|
39
39
|
throw new error_1.FirebaseError(`Unexpected error fetching configs at ${path}`, {
|
|
40
40
|
exit: 2,
|
|
41
|
-
original: err,
|
|
41
|
+
original: (0, error_1.getError)(err),
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
utils.logSuccess("Successfully set setting.");
|
|
@@ -66,8 +66,8 @@ exports.command = new command_1.Command("ext:dev:init")
|
|
|
66
66
|
}
|
|
67
67
|
catch (err) {
|
|
68
68
|
if (!(err instanceof error_1.FirebaseError)) {
|
|
69
|
-
throw new error_1.FirebaseError(`Error occurred when initializing files for new extension: ${err
|
|
70
|
-
original: err,
|
|
69
|
+
throw new error_1.FirebaseError(`Error occurred when initializing files for new extension: ${(0, error_1.getErrMsg)(err)}`, {
|
|
70
|
+
original: (0, error_1.getError)(err),
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
throw err;
|
|
@@ -19,7 +19,7 @@ exports.command = new command_1.Command("ext:dev:list <publisherId>")
|
|
|
19
19
|
extensions = await (0, publisherApi_1.listExtensions)(publisherId);
|
|
20
20
|
}
|
|
21
21
|
catch (err) {
|
|
22
|
-
throw new error_1.FirebaseError(err);
|
|
22
|
+
throw new error_1.FirebaseError((0, error_1.getErrMsg)(err));
|
|
23
23
|
}
|
|
24
24
|
if (extensions.length < 1) {
|
|
25
25
|
throw new error_1.FirebaseError(`There are no extensions uploaded under publisher ID ${clc.bold(publisherId)}. This could happen for two reasons:\n` +
|
|
@@ -35,7 +35,7 @@ exports.command = new command_1.Command("ext:dev:register")
|
|
|
35
35
|
profile = await (0, publisherApi_1.registerPublisherProfile)(projectId, publisherId);
|
|
36
36
|
}
|
|
37
37
|
catch (err) {
|
|
38
|
-
if (err
|
|
38
|
+
if ((0, error_1.getErrStatus)(err) === 409) {
|
|
39
39
|
const error = `Couldn't register the publisher ID '${clc.bold(publisherId)}' to the project '${clc.bold(projectId)}'.` +
|
|
40
40
|
" This can happen for either of two reasons:\n\n" +
|
|
41
41
|
` - Publisher ID '${clc.bold(publisherId)}' is registered to another project\n` +
|
|
@@ -43,7 +43,7 @@ exports.command = new command_1.Command("ext:dev:register")
|
|
|
43
43
|
` Try again with a unique publisher ID or a new project. If your business’s name has been registered to another project, contact Firebase support ${(0, marked_1.marked)("(https://firebase.google.com/support/troubleshooter/contact).")}`;
|
|
44
44
|
throw new error_1.FirebaseError(error, { exit: 1 });
|
|
45
45
|
}
|
|
46
|
-
throw new error_1.FirebaseError(`Failed to register publisher ID ${clc.bold(publisherId)} for project ${clc.bold(projectId)}: ${err
|
|
46
|
+
throw new error_1.FirebaseError(`Failed to register publisher ID ${clc.bold(publisherId)} for project ${clc.bold(projectId)}: ${(0, error_1.getErrMsg)(err)}`);
|
|
47
47
|
}
|
|
48
48
|
utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Publisher ID '${clc.bold(publisherId)}' has been registered to project ${clc.bold(projectId)}. View and edit your profile at ${utils.consoleUrl(projectId, `/publisher`)}`);
|
|
49
49
|
return profile;
|
|
@@ -44,13 +44,13 @@ async function uploadExtensionAction(extensionRef, options) {
|
|
|
44
44
|
profile = await (0, publisherApi_1.getPublisherProfile)("-", publisherId);
|
|
45
45
|
}
|
|
46
46
|
catch (err) {
|
|
47
|
-
if (err
|
|
47
|
+
if ((0, error_1.getErrStatus)(err) === 404) {
|
|
48
48
|
throw (0, extensionsHelper_1.getMissingPublisherError)(publisherId);
|
|
49
49
|
}
|
|
50
50
|
throw err;
|
|
51
51
|
}
|
|
52
52
|
const projectNumber = `${(0, extensionsHelper_2.getPublisherProjectFromName)(profile.name)}`;
|
|
53
|
-
const { projectId } = await (0, projects_1.
|
|
53
|
+
const { projectId } = await (0, projects_1.getProject)(projectNumber);
|
|
54
54
|
await (0, tos_1.acceptLatestPublisherTOS)(options, projectNumber);
|
|
55
55
|
let res;
|
|
56
56
|
if (options.local) {
|