firebase-tools 12.3.1 → 12.4.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/api.js +2 -3
- package/lib/appdistribution/client.js +52 -0
- package/lib/commands/appdistribution-group-create.js +19 -0
- package/lib/commands/appdistribution-group-delete.js +24 -0
- package/lib/commands/appdistribution-testers-add.js +6 -1
- package/lib/commands/appdistribution-testers-remove.js +20 -13
- package/lib/commands/experiments-describe.js +1 -1
- package/lib/commands/index.js +3 -0
- package/lib/deploy/storage/prepare.js +1 -1
- package/lib/frameworks/compose/discover/filesystem.js +52 -0
- package/lib/frameworks/compose/discover/frameworkMatcher.js +76 -0
- package/lib/frameworks/compose/discover/frameworkSpec.js +39 -0
- package/lib/frameworks/compose/discover/types.js +2 -0
- package/lib/gcp/storage.js +6 -5
- package/lib/monospace/index.js +82 -0
- package/lib/monospace/interfaces.js +2 -0
- package/lib/requireAuth.js +8 -0
- package/package.json +1 -1
package/lib/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.secretManagerOrigin = exports.githubApiOrigin = exports.githubOrigin = exports.serviceUsageOrigin = exports.cloudRunApiOrigin = exports.hostingApiOrigin = exports.firebaseStorageOrigin = exports.storageOrigin = exports.runtimeconfigOrigin = exports.rulesOrigin = exports.resourceManagerOrigin = exports.remoteConfigApiOrigin = exports.rtdbMetadataOrigin = exports.rtdbManagementOrigin = exports.realtimeOrigin = exports.extensionsTOSOrigin = exports.extensionsPublisherOrigin = exports.extensionsOrigin = exports.iamOrigin = exports.identityOrigin = exports.hostingOrigin = exports.googleOrigin = exports.pubsubOrigin = exports.cloudTasksOrigin = exports.cloudschedulerOrigin = exports.functionsDefaultRegion = exports.runOrigin = exports.functionsV2Origin = exports.functionsOrigin = exports.firestoreOrigin = exports.firestoreOriginOrEmulator = exports.firedataOrigin = exports.firebaseExtensionsRegistryOrigin = exports.firebaseApiOrigin = exports.eventarcOrigin = exports.dynamicLinksKey = exports.dynamicLinksOrigin = exports.deployOrigin = exports.consoleOrigin = exports.authOrigin = exports.
|
|
4
|
-
exports.setScopes = exports.getScopes = exports.githubClientSecret =
|
|
3
|
+
exports.githubClientId = exports.secretManagerOrigin = exports.githubApiOrigin = exports.githubOrigin = exports.serviceUsageOrigin = exports.cloudRunApiOrigin = exports.hostingApiOrigin = exports.firebaseStorageOrigin = exports.storageOrigin = exports.runtimeconfigOrigin = exports.rulesOrigin = exports.resourceManagerOrigin = exports.remoteConfigApiOrigin = exports.rtdbMetadataOrigin = exports.rtdbManagementOrigin = exports.realtimeOrigin = exports.extensionsTOSOrigin = exports.extensionsPublisherOrigin = exports.extensionsOrigin = exports.iamOrigin = exports.identityOrigin = exports.hostingOrigin = exports.googleOrigin = exports.pubsubOrigin = exports.cloudTasksOrigin = exports.cloudschedulerOrigin = exports.functionsDefaultRegion = exports.runOrigin = exports.functionsV2Origin = exports.functionsOrigin = exports.firestoreOrigin = exports.firestoreOriginOrEmulator = exports.firedataOrigin = exports.firebaseExtensionsRegistryOrigin = exports.firebaseApiOrigin = exports.eventarcOrigin = exports.dynamicLinksKey = exports.dynamicLinksOrigin = exports.deployOrigin = exports.consoleOrigin = exports.authOrigin = exports.appDistributionOrigin = exports.artifactRegistryDomain = exports.containerRegistryDomain = exports.cloudMonitoringOrigin = exports.cloudloggingOrigin = exports.cloudbillingOrigin = exports.clientSecret = exports.clientId = exports.authProxyOrigin = void 0;
|
|
4
|
+
exports.setScopes = exports.getScopes = exports.githubClientSecret = void 0;
|
|
5
5
|
const constants_1 = require("./emulator/constants");
|
|
6
6
|
const logger_1 = require("./logger");
|
|
7
7
|
const scopes = require("./scopes");
|
|
@@ -16,7 +16,6 @@ exports.cloudMonitoringOrigin = utils.envOverride("CLOUD_MONITORING_URL", "https
|
|
|
16
16
|
exports.containerRegistryDomain = utils.envOverride("CONTAINER_REGISTRY_DOMAIN", "gcr.io");
|
|
17
17
|
exports.artifactRegistryDomain = utils.envOverride("ARTIFACT_REGISTRY_DOMAIN", "https://artifactregistry.googleapis.com");
|
|
18
18
|
exports.appDistributionOrigin = utils.envOverride("FIREBASE_APP_DISTRIBUTION_URL", "https://firebaseappdistribution.googleapis.com");
|
|
19
|
-
exports.appengineOrigin = utils.envOverride("FIREBASE_APPENGINE_URL", "https://appengine.googleapis.com");
|
|
20
19
|
exports.authOrigin = utils.envOverride("FIREBASE_AUTH_URL", "https://accounts.google.com");
|
|
21
20
|
exports.consoleOrigin = utils.envOverride("FIREBASE_CONSOLE_URL", "https://console.firebase.google.com");
|
|
22
21
|
exports.deployOrigin = utils.envOverride("FIREBASE_DEPLOY_URL", utils.envOverride("FIREBASE_UPLOAD_URL", "https://deploy.firebase.com"));
|
|
@@ -137,5 +137,57 @@ class AppDistributionClient {
|
|
|
137
137
|
}
|
|
138
138
|
return apiResponse.body;
|
|
139
139
|
}
|
|
140
|
+
async createGroup(projectName, displayName, alias) {
|
|
141
|
+
let apiResponse;
|
|
142
|
+
try {
|
|
143
|
+
apiResponse = await this.appDistroV2Client.request({
|
|
144
|
+
method: "POST",
|
|
145
|
+
path: alias === undefined ? `${projectName}/groups` : `${projectName}/groups?groupId=${alias}`,
|
|
146
|
+
body: { displayName: displayName },
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
throw new error_1.FirebaseError(`Failed to create group ${err}`);
|
|
151
|
+
}
|
|
152
|
+
return apiResponse.body;
|
|
153
|
+
}
|
|
154
|
+
async deleteGroup(groupName) {
|
|
155
|
+
try {
|
|
156
|
+
await this.appDistroV2Client.request({
|
|
157
|
+
method: "DELETE",
|
|
158
|
+
path: groupName,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
throw new error_1.FirebaseError(`Failed to delete group ${err}`);
|
|
163
|
+
}
|
|
164
|
+
utils.logSuccess(`Group deleted successfully`);
|
|
165
|
+
}
|
|
166
|
+
async addTestersToGroup(groupName, emails) {
|
|
167
|
+
try {
|
|
168
|
+
await this.appDistroV2Client.request({
|
|
169
|
+
method: "POST",
|
|
170
|
+
path: `${groupName}:batchJoin`,
|
|
171
|
+
body: { emails: emails },
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
throw new error_1.FirebaseError(`Failed to add testers to group ${err}`);
|
|
176
|
+
}
|
|
177
|
+
utils.logSuccess(`Testers added to group successfully`);
|
|
178
|
+
}
|
|
179
|
+
async removeTestersFromGroup(groupName, emails) {
|
|
180
|
+
try {
|
|
181
|
+
await this.appDistroV2Client.request({
|
|
182
|
+
method: "POST",
|
|
183
|
+
path: `${groupName}:batchLeave`,
|
|
184
|
+
body: { emails: emails },
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
throw new error_1.FirebaseError(`Failed to remove testers from group ${err}`);
|
|
189
|
+
}
|
|
190
|
+
utils.logSuccess(`Testers removed from group successfully`);
|
|
191
|
+
}
|
|
140
192
|
}
|
|
141
193
|
exports.AppDistributionClient = AppDistributionClient;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const command_1 = require("../command");
|
|
5
|
+
const utils = require("../utils");
|
|
6
|
+
const requireAuth_1 = require("../requireAuth");
|
|
7
|
+
const client_1 = require("../appdistribution/client");
|
|
8
|
+
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
9
|
+
exports.command = new command_1.Command("appdistribution:group:create <displayName> [alias]")
|
|
10
|
+
.description("create group in project")
|
|
11
|
+
.before(requireAuth_1.requireAuth)
|
|
12
|
+
.action(async (displayName, alias, options) => {
|
|
13
|
+
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
14
|
+
const appDistroClient = new client_1.AppDistributionClient();
|
|
15
|
+
utils.logBullet(`Creating group in project`);
|
|
16
|
+
const group = await appDistroClient.createGroup(projectName, displayName, alias);
|
|
17
|
+
alias = group.name.split("/").pop();
|
|
18
|
+
utils.logSuccess(`Group '${group.displayName}' (alias: ${alias}) created successfully`);
|
|
19
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const command_1 = require("../command");
|
|
5
|
+
const utils = require("../utils");
|
|
6
|
+
const requireAuth_1 = require("../requireAuth");
|
|
7
|
+
const error_1 = require("../error");
|
|
8
|
+
const client_1 = require("../appdistribution/client");
|
|
9
|
+
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
10
|
+
exports.command = new command_1.Command("appdistribution:group:delete <alias>")
|
|
11
|
+
.description("delete group from a project")
|
|
12
|
+
.before(requireAuth_1.requireAuth)
|
|
13
|
+
.action(async (alias, options) => {
|
|
14
|
+
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
15
|
+
const appDistroClient = new client_1.AppDistributionClient();
|
|
16
|
+
try {
|
|
17
|
+
utils.logBullet(`Deleting group from project`);
|
|
18
|
+
await appDistroClient.deleteGroup(`${projectName}/groups/${alias}`);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
throw new error_1.FirebaseError(`Failed to delete group ${err}`);
|
|
22
|
+
}
|
|
23
|
+
utils.logSuccess(`Group ${alias} has successfully been deleted`);
|
|
24
|
+
});
|
|
@@ -7,8 +7,9 @@ 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
9
|
exports.command = new command_1.Command("appdistribution:testers:add [emails...]")
|
|
10
|
-
.description("add testers to project")
|
|
10
|
+
.description("add testers to project (and possibly group)")
|
|
11
11
|
.option("--file <file>", "a path to a file containing a list of tester emails to be added")
|
|
12
|
+
.option("--group-alias <group-alias>", "if specified, the testers are also added to the group identified by this alias")
|
|
12
13
|
.before(requireAuth_1.requireAuth)
|
|
13
14
|
.action(async (emails, options) => {
|
|
14
15
|
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
@@ -16,4 +17,8 @@ exports.command = new command_1.Command("appdistribution:testers:add [emails...]
|
|
|
16
17
|
const emailsToAdd = (0, options_parser_util_1.getEmails)(emails, options.file);
|
|
17
18
|
utils.logBullet(`Adding ${emailsToAdd.length} testers to project`);
|
|
18
19
|
await appDistroClient.addTesters(projectName, emailsToAdd);
|
|
20
|
+
if (options.groupAlias) {
|
|
21
|
+
utils.logBullet(`Adding ${emailsToAdd.length} testers to group`);
|
|
22
|
+
await appDistroClient.addTestersToGroup(`${projectName}/groups/${options.groupAlias}`, emailsToAdd);
|
|
23
|
+
}
|
|
19
24
|
});
|
|
@@ -9,25 +9,32 @@ const client_1 = require("../appdistribution/client");
|
|
|
9
9
|
const options_parser_util_1 = require("../appdistribution/options-parser-util");
|
|
10
10
|
const logger_1 = require("../logger");
|
|
11
11
|
exports.command = new command_1.Command("appdistribution:testers:remove [emails...]")
|
|
12
|
-
.description("remove testers from a project")
|
|
12
|
+
.description("remove testers from a project (or group)")
|
|
13
13
|
.option("--file <file>", "a path to a file containing a list of tester emails to be removed")
|
|
14
|
+
.option("--group-alias <group-alias>", "if specified, the testers are only removed from the group identified by this alias, but not the project")
|
|
14
15
|
.before(requireAuth_1.requireAuth)
|
|
15
16
|
.action(async (emails, options) => {
|
|
16
17
|
const projectName = await (0, options_parser_util_1.getProjectName)(options);
|
|
17
18
|
const appDistroClient = new client_1.AppDistributionClient();
|
|
18
19
|
const emailsArr = (0, options_parser_util_1.getEmails)(emails, options.file);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
deleteResponse = await appDistroClient.removeTesters(projectName, emailsArr);
|
|
20
|
+
if (options.groupAlias) {
|
|
21
|
+
utils.logBullet(`Removing ${emailsArr.length} testers from group`);
|
|
22
|
+
await appDistroClient.removeTestersFromGroup(`${projectName}/groups/${options.groupAlias}`, emailsArr);
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
else {
|
|
25
|
+
let deleteResponse;
|
|
26
|
+
try {
|
|
27
|
+
utils.logBullet(`Deleting ${emailsArr.length} testers from project`);
|
|
28
|
+
deleteResponse = await appDistroClient.removeTesters(projectName, emailsArr);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
throw new error_1.FirebaseError(`Failed to remove testers ${err}`);
|
|
32
|
+
}
|
|
33
|
+
if (!deleteResponse.emails) {
|
|
34
|
+
utils.logSuccess(`Testers did not exist`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
logger_1.logger.debug(`Testers: ${deleteResponse.emails}, have been successfully deleted`);
|
|
38
|
+
utils.logSuccess(`${deleteResponse.emails.length} testers have successfully been deleted`);
|
|
26
39
|
}
|
|
27
|
-
if (!deleteResponse.emails) {
|
|
28
|
-
utils.logSuccess(`Testers did not exist`);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
logger_1.logger.debug(`Testers: ${deleteResponse.emails}, have been successfully deleted`);
|
|
32
|
-
utils.logSuccess(`${deleteResponse.emails.length} testers have successfully been deleted`);
|
|
33
40
|
});
|
|
@@ -8,7 +8,7 @@ const experiments = require("../experiments");
|
|
|
8
8
|
const logger_1 = require("../logger");
|
|
9
9
|
const utils_1 = require("../utils");
|
|
10
10
|
exports.command = new command_1.Command("experiments:describe <experiment>")
|
|
11
|
-
.description("
|
|
11
|
+
.description("describe what an experiment does when enabled")
|
|
12
12
|
.action((experiment) => {
|
|
13
13
|
if (!experiments.isValidExperiment(experiment)) {
|
|
14
14
|
let message = `Cannot find experiment ${(0, colorette_1.bold)(experiment)}`;
|
package/lib/commands/index.js
CHANGED
|
@@ -19,6 +19,9 @@ function load(client) {
|
|
|
19
19
|
client.appdistribution.testers = {};
|
|
20
20
|
client.appdistribution.testers.add = loadCommand("appdistribution-testers-add");
|
|
21
21
|
client.appdistribution.testers.delete = loadCommand("appdistribution-testers-remove");
|
|
22
|
+
client.appdistribution.group = {};
|
|
23
|
+
client.appdistribution.group.create = loadCommand("appdistribution-group-create");
|
|
24
|
+
client.appdistribution.group.delete = loadCommand("appdistribution-group-delete");
|
|
22
25
|
client.apps = {};
|
|
23
26
|
client.apps.create = loadCommand("apps-create");
|
|
24
27
|
client.apps.list = loadCommand("apps-list");
|
|
@@ -26,7 +26,7 @@ async function default_1(context, options) {
|
|
|
26
26
|
}
|
|
27
27
|
const rulesDeploy = new rulesDeploy_1.RulesDeploy(options, rulesDeploy_1.RulesetServiceType.FIREBASE_STORAGE);
|
|
28
28
|
const rulesConfigsToDeploy = [];
|
|
29
|
-
if (!Array.isArray(rulesConfig)) {
|
|
29
|
+
if (!Array.isArray(rulesConfig) && options.project) {
|
|
30
30
|
const defaultBucket = await gcp.storage.getDefaultBucket(options.project);
|
|
31
31
|
rulesConfig = [Object.assign(rulesConfig, { bucket: defaultBucket })];
|
|
32
32
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readOrNull = exports.LocalFileSystem = void 0;
|
|
4
|
+
const fs_extra_1 = require("fs-extra");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const error_1 = require("../../../error");
|
|
7
|
+
const logger_1 = require("../../../../src/logger");
|
|
8
|
+
class LocalFileSystem {
|
|
9
|
+
constructor(cwd) {
|
|
10
|
+
this.cwd = cwd;
|
|
11
|
+
this.existsCache = {};
|
|
12
|
+
this.contentCache = {};
|
|
13
|
+
}
|
|
14
|
+
async exists(file) {
|
|
15
|
+
try {
|
|
16
|
+
if (!(file in this.contentCache)) {
|
|
17
|
+
this.existsCache[file] = await (0, fs_extra_1.pathExists)(path.resolve(this.cwd, file));
|
|
18
|
+
}
|
|
19
|
+
return this.existsCache[file];
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new error_1.FirebaseError(`Error occured while searching for file: ${error}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async read(file) {
|
|
26
|
+
try {
|
|
27
|
+
if (!(file in this.contentCache)) {
|
|
28
|
+
const fileContents = await (0, fs_extra_1.readFile)(path.resolve(this.cwd, file), "utf-8");
|
|
29
|
+
this.contentCache[file] = fileContents;
|
|
30
|
+
}
|
|
31
|
+
return this.contentCache[file];
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
logger_1.logger.error("Error occured while reading file contents.");
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.LocalFileSystem = LocalFileSystem;
|
|
40
|
+
async function readOrNull(fs, path) {
|
|
41
|
+
try {
|
|
42
|
+
return fs.read(path);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (err && typeof err === "object" && (err === null || err === void 0 ? void 0 : err.code) === "ENOENT") {
|
|
46
|
+
logger_1.logger.debug("ENOENT error occured while reading file.");
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Unknown error occured while reading file: ${err}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.readOrNull = readOrNull;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.frameworkMatcher = exports.removeEmbededFrameworks = exports.filterFrameworksWithFiles = exports.filterFrameworksWithDependencies = void 0;
|
|
4
|
+
const error_1 = require("../../../error");
|
|
5
|
+
const logger_1 = require("../../../logger");
|
|
6
|
+
function filterFrameworksWithDependencies(allFrameworkSpecs, dependencies) {
|
|
7
|
+
return allFrameworkSpecs.filter((framework) => {
|
|
8
|
+
return framework.requiredDependencies.every((dependency) => {
|
|
9
|
+
return dependency.name in dependencies;
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
exports.filterFrameworksWithDependencies = filterFrameworksWithDependencies;
|
|
14
|
+
async function filterFrameworksWithFiles(allFrameworkSpecs, fs) {
|
|
15
|
+
try {
|
|
16
|
+
const filteredFrameworks = [];
|
|
17
|
+
for (const framework of allFrameworkSpecs) {
|
|
18
|
+
if (!framework.requiredFiles) {
|
|
19
|
+
filteredFrameworks.push(framework);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
let isRequired = true;
|
|
23
|
+
for (let files of framework.requiredFiles) {
|
|
24
|
+
files = Array.isArray(files) ? files : [files];
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
isRequired = isRequired && (await fs.exists(file));
|
|
27
|
+
if (!isRequired) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (isRequired) {
|
|
33
|
+
filteredFrameworks.push(framework);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return filteredFrameworks;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
logger_1.logger.error("Error: Unable to filter frameworks based on required files", error);
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.filterFrameworksWithFiles = filterFrameworksWithFiles;
|
|
44
|
+
function removeEmbededFrameworks(allFrameworkSpecs) {
|
|
45
|
+
const embededFrameworkSet = new Set();
|
|
46
|
+
for (const framework of allFrameworkSpecs) {
|
|
47
|
+
if (!framework.embedsFrameworks) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
for (const item of framework.embedsFrameworks) {
|
|
51
|
+
embededFrameworkSet.add(item);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return allFrameworkSpecs.filter((item) => !embededFrameworkSet.has(item.id));
|
|
55
|
+
}
|
|
56
|
+
exports.removeEmbededFrameworks = removeEmbededFrameworks;
|
|
57
|
+
async function frameworkMatcher(runtime, fs, frameworks, dependencies) {
|
|
58
|
+
try {
|
|
59
|
+
const filterRuntimeFramework = frameworks.filter((framework) => framework.runtime === runtime);
|
|
60
|
+
const frameworksWithDependencies = filterFrameworksWithDependencies(filterRuntimeFramework, dependencies);
|
|
61
|
+
const frameworkWithFiles = await filterFrameworksWithFiles(frameworksWithDependencies, fs);
|
|
62
|
+
const allMatches = removeEmbededFrameworks(frameworkWithFiles);
|
|
63
|
+
if (allMatches.length === 0) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
if (allMatches.length > 1) {
|
|
67
|
+
const frameworkNames = allMatches.map((framework) => framework.id);
|
|
68
|
+
throw new error_1.FirebaseError(`Multiple Frameworks are matched: ${frameworkNames.join(", ")} Manually set up override commands in firebase.json`);
|
|
69
|
+
}
|
|
70
|
+
return allMatches[0];
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new error_1.FirebaseError(`Failed to match the correct framework: ${error}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.frameworkMatcher = frameworkMatcher;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.frameworkSpecs = void 0;
|
|
4
|
+
exports.frameworkSpecs = [
|
|
5
|
+
{
|
|
6
|
+
id: "express",
|
|
7
|
+
runtime: "nodejs",
|
|
8
|
+
webFrameworkId: "Express.js",
|
|
9
|
+
requiredDependencies: [
|
|
10
|
+
{
|
|
11
|
+
name: "express",
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "nextjs",
|
|
17
|
+
runtime: "nodejs",
|
|
18
|
+
webFrameworkId: "Next.js",
|
|
19
|
+
requiredFiles: ["next.config.js", "next.config.ts"],
|
|
20
|
+
requiredDependencies: [
|
|
21
|
+
{
|
|
22
|
+
name: "next",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
commands: {
|
|
26
|
+
build: {
|
|
27
|
+
cmd: "next build",
|
|
28
|
+
},
|
|
29
|
+
dev: {
|
|
30
|
+
cmd: "next dev",
|
|
31
|
+
env: { NODE_ENV: "dev" },
|
|
32
|
+
},
|
|
33
|
+
run: {
|
|
34
|
+
cmd: "next run",
|
|
35
|
+
env: { NODE_ENV: "production" },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
];
|
package/lib/gcp/storage.js
CHANGED
|
@@ -4,17 +4,18 @@ exports.getServiceAccount = exports.listBuckets = exports.getBucket = exports.de
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const api_1 = require("../api");
|
|
6
6
|
const apiv2_1 = require("../apiv2");
|
|
7
|
-
const logger_1 = require("../logger");
|
|
8
7
|
const error_1 = require("../error");
|
|
8
|
+
const logger_1 = require("../logger");
|
|
9
|
+
const projects_1 = require("../management/projects");
|
|
9
10
|
async function getDefaultBucket(projectId) {
|
|
11
|
+
var _a;
|
|
10
12
|
try {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
if (resp.body.defaultBucket === "undefined") {
|
|
13
|
+
const metadata = await (0, projects_1.getFirebaseProject)(projectId);
|
|
14
|
+
if (!((_a = metadata.resources) === null || _a === void 0 ? void 0 : _a.storageBucket)) {
|
|
14
15
|
logger_1.logger.debug("Default storage bucket is undefined.");
|
|
15
16
|
throw new error_1.FirebaseError("Your project is being set up. Please wait a minute before deploying again.");
|
|
16
17
|
}
|
|
17
|
-
return
|
|
18
|
+
return metadata.resources.storageBucket;
|
|
18
19
|
}
|
|
19
20
|
catch (err) {
|
|
20
21
|
logger_1.logger.info("\n\nThere was an issue deploying your functions. Verify that your project has a Google App Engine instance setup at https://console.cloud.google.com/appengine and try again. If this issue persists, please contact support.");
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isMonospaceEnv = exports.selectProjectInMonospace = void 0;
|
|
4
|
+
const node_fetch_1 = require("node-fetch");
|
|
5
|
+
const error_1 = require("../error");
|
|
6
|
+
const logger_1 = require("../logger");
|
|
7
|
+
const rc_1 = require("../rc");
|
|
8
|
+
const POLL_USER_RESPONSE_MILLIS = 5000;
|
|
9
|
+
async function selectProjectInMonospace({ projectRoot, project, isVSCE, }) {
|
|
10
|
+
const initFirebaseResponse = await initFirebase(project);
|
|
11
|
+
if (initFirebaseResponse.success === false) {
|
|
12
|
+
throw new Error(String(initFirebaseResponse.error));
|
|
13
|
+
}
|
|
14
|
+
const { rid } = initFirebaseResponse;
|
|
15
|
+
const authorizedProject = await pollAuthorizedProject(rid);
|
|
16
|
+
if (!authorizedProject)
|
|
17
|
+
return null;
|
|
18
|
+
if (isVSCE)
|
|
19
|
+
return authorizedProject;
|
|
20
|
+
if (projectRoot)
|
|
21
|
+
createFirebaseRc(projectRoot, authorizedProject);
|
|
22
|
+
}
|
|
23
|
+
exports.selectProjectInMonospace = selectProjectInMonospace;
|
|
24
|
+
async function pollAuthorizedProject(rid) {
|
|
25
|
+
const getInitFirebaseRes = await getInitFirebaseResponse(rid);
|
|
26
|
+
if ("userResponse" in getInitFirebaseRes) {
|
|
27
|
+
if (getInitFirebaseRes.userResponse.success) {
|
|
28
|
+
return getInitFirebaseRes.userResponse.projectId;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const { error } = getInitFirebaseRes;
|
|
35
|
+
if (error === "WAITING_FOR_RESPONSE") {
|
|
36
|
+
await new Promise((res) => setTimeout(res, POLL_USER_RESPONSE_MILLIS));
|
|
37
|
+
return pollAuthorizedProject(rid);
|
|
38
|
+
}
|
|
39
|
+
if (error === "USER_CANCELED") {
|
|
40
|
+
throw new error_1.FirebaseError("User canceled without authorizing any project");
|
|
41
|
+
}
|
|
42
|
+
throw new error_1.FirebaseError(`Unhandled /get-init-firebase-response error: ${error}`);
|
|
43
|
+
}
|
|
44
|
+
async function initFirebase(project) {
|
|
45
|
+
const port = getMonospaceDaemonPort();
|
|
46
|
+
if (!port)
|
|
47
|
+
throw new error_1.FirebaseError("Undefined MONOSPACE_DAEMON_PORT");
|
|
48
|
+
const initFirebaseURL = new URL(`http://localhost:${port}/init-firebase`);
|
|
49
|
+
if (project) {
|
|
50
|
+
initFirebaseURL.searchParams.set("known_project", project);
|
|
51
|
+
}
|
|
52
|
+
const initFirebaseRes = await (0, node_fetch_1.default)(initFirebaseURL.toString(), {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: {
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
const initFirebaseResponse = (await initFirebaseRes.json());
|
|
59
|
+
return initFirebaseResponse;
|
|
60
|
+
}
|
|
61
|
+
async function getInitFirebaseResponse(rid) {
|
|
62
|
+
const port = getMonospaceDaemonPort();
|
|
63
|
+
if (!port)
|
|
64
|
+
throw new error_1.FirebaseError("Undefined MONOSPACE_DAEMON_PORT");
|
|
65
|
+
const getInitFirebaseRes = await (0, node_fetch_1.default)(`http://localhost:${port}/get-init-firebase-response?rid=${rid}`);
|
|
66
|
+
const getInitFirebaseJson = (await getInitFirebaseRes.json());
|
|
67
|
+
logger_1.logger.debug(`/get-init-firebase-response?rid=${rid} response:`);
|
|
68
|
+
logger_1.logger.debug(getInitFirebaseJson);
|
|
69
|
+
return getInitFirebaseJson;
|
|
70
|
+
}
|
|
71
|
+
function createFirebaseRc(projectDir, authorizedProject) {
|
|
72
|
+
const firebaseRc = (0, rc_1.loadRC)({ cwd: projectDir });
|
|
73
|
+
firebaseRc.addProjectAlias("default", authorizedProject);
|
|
74
|
+
return firebaseRc.save();
|
|
75
|
+
}
|
|
76
|
+
async function isMonospaceEnv() {
|
|
77
|
+
return Promise.resolve(Boolean(getMonospaceDaemonPort()));
|
|
78
|
+
}
|
|
79
|
+
exports.isMonospaceEnv = isMonospaceEnv;
|
|
80
|
+
function getMonospaceDaemonPort() {
|
|
81
|
+
return process.env.MONOSPACE_DAEMON_PORT;
|
|
82
|
+
}
|
package/lib/requireAuth.js
CHANGED
|
@@ -10,6 +10,7 @@ const logger_1 = require("./logger");
|
|
|
10
10
|
const utils = require("./utils");
|
|
11
11
|
const scopes = require("./scopes");
|
|
12
12
|
const auth_1 = require("./auth");
|
|
13
|
+
const monospace_1 = require("./monospace");
|
|
13
14
|
const AUTH_ERROR_MESSAGE = `Command requires authentication, please run ${clc.bold("firebase login")}`;
|
|
14
15
|
let authClient;
|
|
15
16
|
function getAuthClient(config) {
|
|
@@ -23,6 +24,13 @@ async function autoAuth(options, authScopes) {
|
|
|
23
24
|
const client = getAuthClient({ scopes: authScopes, projectId: options.project });
|
|
24
25
|
const token = await client.getAccessToken();
|
|
25
26
|
token !== null ? apiv2.setAccessToken(token) : false;
|
|
27
|
+
if (!options.isVSCE && (await (0, monospace_1.isMonospaceEnv)())) {
|
|
28
|
+
await (0, monospace_1.selectProjectInMonospace)({
|
|
29
|
+
projectRoot: options.config.projectDir,
|
|
30
|
+
project: options.project,
|
|
31
|
+
isVSCE: options.isVSCE,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
26
34
|
}
|
|
27
35
|
async function requireAuth(options) {
|
|
28
36
|
api.setScopes([scopes.CLOUD_PLATFORM, scopes.FIREBASE_PLATFORM]);
|