firebase-tools 11.0.0 → 11.0.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/appdistribution/client.js +16 -25
- package/lib/commands/ext-configure.js +4 -0
- package/lib/commands/ext-install.js +4 -0
- package/lib/commands/ext-uninstall.js +5 -0
- package/lib/commands/ext-update.js +4 -0
- package/lib/deploy/remoteconfig/functions.js +18 -14
- package/lib/emulator/databaseEmulator.js +7 -5
- package/lib/emulator/firestoreEmulator.js +10 -12
- package/lib/emulator/functionsEmulator.js +38 -40
- package/lib/emulator/hubClient.js +11 -22
- package/lib/emulator/hubExport.js +26 -16
- package/lib/firestore/checkDatabaseType.js +4 -5
- package/lib/firestore/indexes.js +17 -34
- package/lib/gcp/storage.js +2 -4
- package/lib/hosting/cloudRunProxy.js +19 -15
- package/lib/init/features/database.js +3 -5
- package/lib/management/apps.js +47 -43
- package/lib/management/database.js +33 -31
- package/lib/management/projects.js +13 -7
- package/lib/rtdb.js +31 -29
- package/npm-shrinkwrap.json +363 -109
- package/package.json +3 -3
- package/standalone/package.json +1 -1
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AppDistributionClient = exports.UploadReleaseResult = exports.IntegrationState = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
|
-
const api = require("../api");
|
|
6
5
|
const utils = require("../utils");
|
|
7
6
|
const operationPoller = require("../operation-poller");
|
|
8
7
|
const error_1 = require("../error");
|
|
9
8
|
const apiv2_1 = require("../apiv2");
|
|
9
|
+
const api_1 = require("../api");
|
|
10
10
|
var IntegrationState;
|
|
11
11
|
(function (IntegrationState) {
|
|
12
12
|
IntegrationState["AAB_INTEGRATION_STATE_UNSPECIFIED"] = "AAB_INTEGRATION_STATE_UNSPECIFIED";
|
|
@@ -27,35 +27,33 @@ var UploadReleaseResult;
|
|
|
27
27
|
class AppDistributionClient {
|
|
28
28
|
constructor() {
|
|
29
29
|
this.appDistroV2Client = new apiv2_1.Client({
|
|
30
|
-
urlPrefix:
|
|
30
|
+
urlPrefix: api_1.appDistributionOrigin,
|
|
31
31
|
apiVersion: "v1",
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
async getAabInfo(appName) {
|
|
35
|
-
const apiResponse = await
|
|
36
|
-
|
|
37
|
-
auth: true,
|
|
38
|
-
});
|
|
39
|
-
return _.get(apiResponse, "body");
|
|
35
|
+
const apiResponse = await this.appDistroV2Client.get(`/${appName}/aabInfo`);
|
|
36
|
+
return apiResponse.body;
|
|
40
37
|
}
|
|
41
38
|
async uploadRelease(appName, distribution) {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
const client = new apiv2_1.Client({ urlPrefix: api_1.appDistributionOrigin });
|
|
40
|
+
const apiResponse = await client.request({
|
|
41
|
+
method: "POST",
|
|
42
|
+
path: `/upload/v1/${appName}/releases:upload`,
|
|
45
43
|
headers: {
|
|
46
44
|
"X-Goog-Upload-File-Name": distribution.getFileName(),
|
|
47
45
|
"X-Goog-Upload-Protocol": "raw",
|
|
48
46
|
"Content-Type": "application/octet-stream",
|
|
49
47
|
},
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
responseType: "json",
|
|
49
|
+
body: distribution.readStream(),
|
|
52
50
|
});
|
|
53
|
-
return
|
|
51
|
+
return apiResponse.body.name;
|
|
54
52
|
}
|
|
55
53
|
async pollUploadStatus(operationName) {
|
|
56
54
|
return operationPoller.pollOperation({
|
|
57
55
|
pollerName: "App Distribution Upload Poller",
|
|
58
|
-
apiOrigin:
|
|
56
|
+
apiOrigin: api_1.appDistributionOrigin,
|
|
59
57
|
apiVersion: "v1",
|
|
60
58
|
operationResourceName: operationName,
|
|
61
59
|
masterTimeout: 5 * 60 * 1000,
|
|
@@ -75,15 +73,12 @@ class AppDistributionClient {
|
|
|
75
73
|
text: releaseNotes,
|
|
76
74
|
},
|
|
77
75
|
};
|
|
76
|
+
const queryParams = { updateMask: "release_notes.text" };
|
|
78
77
|
try {
|
|
79
|
-
await
|
|
80
|
-
origin: api.appDistributionOrigin,
|
|
81
|
-
auth: true,
|
|
82
|
-
data,
|
|
83
|
-
});
|
|
78
|
+
await this.appDistroV2Client.patch(`/${releaseName}`, data, { queryParams });
|
|
84
79
|
}
|
|
85
80
|
catch (err) {
|
|
86
|
-
throw new error_1.FirebaseError(`failed to update release notes with ${err === null || err === void 0 ? void 0 : err.message}
|
|
81
|
+
throw new error_1.FirebaseError(`failed to update release notes with ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
87
82
|
}
|
|
88
83
|
utils.logSuccess("added release notes successfully");
|
|
89
84
|
}
|
|
@@ -98,11 +93,7 @@ class AppDistributionClient {
|
|
|
98
93
|
groupAliases,
|
|
99
94
|
};
|
|
100
95
|
try {
|
|
101
|
-
await
|
|
102
|
-
origin: api.appDistributionOrigin,
|
|
103
|
-
auth: true,
|
|
104
|
-
data,
|
|
105
|
-
});
|
|
96
|
+
await this.appDistroV2Client.post(`/${releaseName}:distribute`, data);
|
|
106
97
|
}
|
|
107
98
|
catch (err) {
|
|
108
99
|
let errorMessage = err.message;
|
|
@@ -23,6 +23,7 @@ marked.setOptions({
|
|
|
23
23
|
exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
24
24
|
.description("configure an existing extension instance")
|
|
25
25
|
.withForce()
|
|
26
|
+
.option("--local", "deprecated")
|
|
26
27
|
.before(requirePermissions_1.requirePermissions, [
|
|
27
28
|
"firebaseextensions.instances.update",
|
|
28
29
|
"firebaseextensions.instances.get",
|
|
@@ -35,6 +36,9 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
|
|
|
35
36
|
throw new error_1.FirebaseError(`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead. ` +
|
|
36
37
|
`See https://firebase.google.com/docs/extensions/manifest for more details.`);
|
|
37
38
|
}
|
|
39
|
+
if (options.local) {
|
|
40
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, "As of firebase-tools@11.0.0, the `--local` flag is no longer required, as it is the default behavior.");
|
|
41
|
+
}
|
|
38
42
|
const config = manifest.loadConfig(options);
|
|
39
43
|
const refOrPath = manifest.getInstanceTarget(instanceId, config);
|
|
40
44
|
const isLocalSource = (0, extensionsHelper_1.isLocalPath)(refOrPath);
|
|
@@ -29,6 +29,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
29
29
|
? "install a local extension if [localPathOrUrl] or [url#root] is provided; install a published extension (not authored by Firebase) if [publisherId/extensionId] is provided "
|
|
30
30
|
: "") +
|
|
31
31
|
"or run with `-i` to see all available extensions.")
|
|
32
|
+
.option("--local", "deprecated")
|
|
32
33
|
.withForce()
|
|
33
34
|
.before(requirePermissions_1.requirePermissions, ["firebaseextensions.instances.create"])
|
|
34
35
|
.before(extensionsHelper_1.ensureExtensionsApiEnabled)
|
|
@@ -55,6 +56,9 @@ exports.default = new command_1.Command("ext:install [extensionName]")
|
|
|
55
56
|
if ((0, extensionsHelper_1.isUrlPath)(extensionName)) {
|
|
56
57
|
throw new error_1.FirebaseError(`Installing with a source url is no longer supported in the CLI. Please use Firebase Console instead.`);
|
|
57
58
|
}
|
|
59
|
+
if (options.local) {
|
|
60
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, "As of firebase-tools@11.0.0, the `--local` flag is no longer required, as it is the default behavior.");
|
|
61
|
+
}
|
|
58
62
|
if ((0, extensionsHelper_1.isLocalPath)(extensionName)) {
|
|
59
63
|
source = await (0, extensionsHelper_1.createSourceFromLocation)((0, projectUtils_1.needProjectId)({ projectId }), extensionName);
|
|
60
64
|
(0, displayExtensionInfo_1.displayExtInfo)(extensionName, "", source.spec);
|
|
@@ -6,18 +6,23 @@ const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
|
|
|
6
6
|
const command_1 = require("../command");
|
|
7
7
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
8
8
|
const requirePermissions_1 = require("../requirePermissions");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
9
10
|
const manifest = require("../extensions/manifest");
|
|
10
11
|
marked.setOptions({
|
|
11
12
|
renderer: new TerminalRenderer(),
|
|
12
13
|
});
|
|
13
14
|
exports.default = new command_1.Command("ext:uninstall <extensionInstanceId>")
|
|
14
15
|
.description("uninstall an extension that is installed in your Firebase project by instance ID")
|
|
16
|
+
.option("--local", "deprecated")
|
|
15
17
|
.withForce()
|
|
16
18
|
.before(requirePermissions_1.requirePermissions, ["firebaseextensions.instances.delete"])
|
|
17
19
|
.before(extensionsHelper_1.ensureExtensionsApiEnabled)
|
|
18
20
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
19
21
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
20
22
|
.action((instanceId, options) => {
|
|
23
|
+
if (options.local) {
|
|
24
|
+
(0, utils_1.logLabeledWarning)(extensionsHelper_1.logPrefix, "As of firebase-tools@11.0.0, the `--local` flag is no longer required, as it is the default behavior.");
|
|
25
|
+
}
|
|
21
26
|
const config = manifest.loadConfig(options);
|
|
22
27
|
manifest.removeFromManifest(instanceId, config);
|
|
23
28
|
manifest.showPostDeprecationNotice();
|
|
@@ -31,10 +31,14 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
|
|
|
31
31
|
.before(extensionsHelper_1.ensureExtensionsApiEnabled)
|
|
32
32
|
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
|
|
33
33
|
.before(extensionsHelper_1.diagnoseAndFixProject)
|
|
34
|
+
.option("--local", "deprecated")
|
|
34
35
|
.withForce()
|
|
35
36
|
.action(async (instanceId, updateSource, options) => {
|
|
36
37
|
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
37
38
|
const config = manifest.loadConfig(options);
|
|
39
|
+
if (options.local) {
|
|
40
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, "As of firebase-tools@11.0.0, the `--local` flag is no longer required, as it is the default behavior.");
|
|
41
|
+
}
|
|
38
42
|
const oldRefOrPath = manifest.getInstanceTarget(instanceId, config);
|
|
39
43
|
if ((0, extensionsHelper_1.isLocalPath)(oldRefOrPath)) {
|
|
40
44
|
throw new error_1.FirebaseError(`Updating an extension with local source is not neccessary. ` +
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.publishTemplate = exports.deployTemplate = exports.validateInputRemoteConfigTemplate = exports.getEtag = void 0;
|
|
4
|
+
const api_1 = require("../../api");
|
|
5
|
+
const apiv2_1 = require("../../apiv2");
|
|
4
6
|
const error_1 = require("../../error");
|
|
5
|
-
const api = require("../../api");
|
|
6
7
|
const TIMEOUT = 30000;
|
|
8
|
+
const client = new apiv2_1.Client({ urlPrefix: api_1.remoteConfigApiOrigin, apiVersion: "v1" });
|
|
7
9
|
async function getEtag(projectNumber, versionNumber) {
|
|
8
|
-
|
|
10
|
+
const reqPath = `/projects/${projectNumber}/remoteConfig`;
|
|
11
|
+
const queryParams = {};
|
|
9
12
|
if (versionNumber) {
|
|
10
|
-
|
|
13
|
+
queryParams.versionNumber = versionNumber;
|
|
11
14
|
}
|
|
12
|
-
const response = await
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const response = await client.request({
|
|
16
|
+
method: "GET",
|
|
17
|
+
path: reqPath,
|
|
18
|
+
queryParams,
|
|
16
19
|
headers: { "Accept-Encoding": "gzip" },
|
|
20
|
+
timeout: TIMEOUT,
|
|
17
21
|
});
|
|
18
|
-
return response.response.headers.etag;
|
|
22
|
+
return response.response.headers.get("etag") || "";
|
|
19
23
|
}
|
|
20
24
|
exports.getEtag = getEtag;
|
|
21
25
|
function validateInputRemoteConfigTemplate(template) {
|
|
@@ -33,20 +37,20 @@ function validateInputRemoteConfigTemplate(template) {
|
|
|
33
37
|
}
|
|
34
38
|
exports.validateInputRemoteConfigTemplate = validateInputRemoteConfigTemplate;
|
|
35
39
|
async function deployTemplate(projectNumber, template, etag, options) {
|
|
36
|
-
const reqPath = `/
|
|
40
|
+
const reqPath = `/projects/${projectNumber}/remoteConfig`;
|
|
37
41
|
if (options === null || options === void 0 ? void 0 : options.force) {
|
|
38
42
|
etag = "*";
|
|
39
43
|
}
|
|
40
|
-
const response = await
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
timeout: TIMEOUT,
|
|
44
|
+
const response = await client.request({
|
|
45
|
+
method: "PUT",
|
|
46
|
+
path: reqPath,
|
|
44
47
|
headers: { "If-Match": etag },
|
|
45
|
-
|
|
48
|
+
body: {
|
|
46
49
|
conditions: template.conditions,
|
|
47
50
|
parameters: template.parameters,
|
|
48
51
|
parameterGroups: template.parameterGroups,
|
|
49
52
|
},
|
|
53
|
+
timeout: TIMEOUT,
|
|
50
54
|
});
|
|
51
55
|
return response.body;
|
|
52
56
|
}
|
|
@@ -6,7 +6,6 @@ const clc = require("cli-color");
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const http = require("http");
|
|
9
|
-
const api = require("../api");
|
|
10
9
|
const downloadableEmulators = require("./downloadableEmulators");
|
|
11
10
|
const types_1 = require("../emulator/types");
|
|
12
11
|
const constants_1 = require("./constants");
|
|
@@ -14,6 +13,7 @@ const registry_1 = require("./registry");
|
|
|
14
13
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
15
14
|
const error_1 = require("../error");
|
|
16
15
|
const parseBoltRules = require("../parseBoltRules");
|
|
16
|
+
const apiv2_1 = require("../apiv2");
|
|
17
17
|
class DatabaseEmulator {
|
|
18
18
|
constructor(args) {
|
|
19
19
|
this.args = args;
|
|
@@ -129,11 +129,13 @@ class DatabaseEmulator {
|
|
|
129
129
|
: fs.readFileSync(rulesPath, "utf8");
|
|
130
130
|
const info = this.getInfo();
|
|
131
131
|
try {
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
const client = new apiv2_1.Client({
|
|
133
|
+
urlPrefix: `http://${registry_1.EmulatorRegistry.getInfoHostString(info)}`,
|
|
134
|
+
auth: false,
|
|
135
|
+
});
|
|
136
|
+
await client.put(`/.settings/rules.json`, content, {
|
|
134
137
|
headers: { Authorization: "Bearer owner" },
|
|
135
|
-
|
|
136
|
-
json: false,
|
|
138
|
+
queryParams: { ns: instance },
|
|
137
139
|
});
|
|
138
140
|
}
|
|
139
141
|
catch (e) {
|
|
@@ -5,12 +5,12 @@ const chokidar = require("chokidar");
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const clc = require("cli-color");
|
|
7
7
|
const path = require("path");
|
|
8
|
-
const api = require("../api");
|
|
9
8
|
const utils = require("../utils");
|
|
10
9
|
const downloadableEmulators = require("./downloadableEmulators");
|
|
11
10
|
const types_1 = require("../emulator/types");
|
|
12
11
|
const registry_1 = require("./registry");
|
|
13
12
|
const constants_1 = require("./constants");
|
|
13
|
+
const apiv2_1 = require("../apiv2");
|
|
14
14
|
class FirestoreEmulator {
|
|
15
15
|
constructor(args) {
|
|
16
16
|
this.args = args;
|
|
@@ -65,7 +65,7 @@ class FirestoreEmulator {
|
|
|
65
65
|
getName() {
|
|
66
66
|
return types_1.Emulators.FIRESTORE;
|
|
67
67
|
}
|
|
68
|
-
updateRules(content) {
|
|
68
|
+
async updateRules(content) {
|
|
69
69
|
const projectId = this.args.projectId;
|
|
70
70
|
const info = this.getInfo();
|
|
71
71
|
const body = {
|
|
@@ -79,17 +79,15 @@ class FirestoreEmulator {
|
|
|
79
79
|
],
|
|
80
80
|
},
|
|
81
81
|
};
|
|
82
|
-
|
|
83
|
-
.
|
|
84
|
-
|
|
85
|
-
data: body,
|
|
86
|
-
})
|
|
87
|
-
.then((res) => {
|
|
88
|
-
if (res.body && res.body.issues) {
|
|
89
|
-
return res.body.issues;
|
|
90
|
-
}
|
|
91
|
-
return [];
|
|
82
|
+
const client = new apiv2_1.Client({
|
|
83
|
+
urlPrefix: `http://${registry_1.EmulatorRegistry.getInfoHostString(info)}`,
|
|
84
|
+
auth: false,
|
|
92
85
|
});
|
|
86
|
+
const res = await client.put(`/emulator/v1/projects/${projectId}:securityRules`, body);
|
|
87
|
+
if (res.body && Array.isArray(res.body.issues)) {
|
|
88
|
+
return res.body.issues;
|
|
89
|
+
}
|
|
90
|
+
return [];
|
|
93
91
|
}
|
|
94
92
|
prettyPrintRulesIssue(filePath, issue) {
|
|
95
93
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
@@ -11,7 +11,6 @@ const jwt = require("jsonwebtoken");
|
|
|
11
11
|
const cors = require("cors");
|
|
12
12
|
const url_1 = require("url");
|
|
13
13
|
const events_1 = require("events");
|
|
14
|
-
const api = require("../api");
|
|
15
14
|
const logger_1 = require("../logger");
|
|
16
15
|
const track_1 = require("../track");
|
|
17
16
|
const constants_1 = require("./constants");
|
|
@@ -34,6 +33,7 @@ const runtimes = require("../deploy/functions/runtimes");
|
|
|
34
33
|
const backend = require("../deploy/functions/backend");
|
|
35
34
|
const functionsEnv = require("../functions/env");
|
|
36
35
|
const v1_1 = require("../functions/events/v1");
|
|
36
|
+
const apiv2_1 = require("../apiv2");
|
|
37
37
|
const EVENT_INVOKE = "functions:invoke";
|
|
38
38
|
const DATABASE_PATH_PATTERN = new RegExp("^projects/[^/]+/instances/([^/]+)/refs(/.*)$");
|
|
39
39
|
class FunctionsEmulator {
|
|
@@ -382,15 +382,12 @@ class FunctionsEmulator {
|
|
|
382
382
|
}
|
|
383
383
|
const path = `/identitytoolkit.googleapis.com/v2/projects/${this.getProjectId()}/config?updateMask=blockingFunctions`;
|
|
384
384
|
try {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
blockingFunctions: this.blockingFunctionsConfig,
|
|
392
|
-
},
|
|
393
|
-
json: true,
|
|
385
|
+
const client = new apiv2_1.Client({
|
|
386
|
+
urlPrefix: `http://${registry_1.EmulatorRegistry.getInfoHostString(authEmu.getInfo())}`,
|
|
387
|
+
auth: false,
|
|
388
|
+
});
|
|
389
|
+
await client.patch(path, { blockingFunctions: this.blockingFunctionsConfig }, {
|
|
390
|
+
headers: { Authorization: "Bearer owner" },
|
|
394
391
|
});
|
|
395
392
|
}
|
|
396
393
|
catch (err) {
|
|
@@ -398,15 +395,15 @@ class FunctionsEmulator {
|
|
|
398
395
|
throw err;
|
|
399
396
|
}
|
|
400
397
|
}
|
|
401
|
-
addRealtimeDatabaseTrigger(projectId, key, eventTrigger) {
|
|
398
|
+
async addRealtimeDatabaseTrigger(projectId, key, eventTrigger) {
|
|
402
399
|
const databaseEmu = registry_1.EmulatorRegistry.get(types_1.Emulators.DATABASE);
|
|
403
400
|
if (!databaseEmu) {
|
|
404
|
-
return
|
|
401
|
+
return false;
|
|
405
402
|
}
|
|
406
403
|
const result = DATABASE_PATH_PATTERN.exec(eventTrigger.resource);
|
|
407
404
|
if (result === null || result.length !== 3) {
|
|
408
405
|
this.logger.log("WARN", `Event function "${key}" has malformed "resource" member. ` + `${eventTrigger.resource}`);
|
|
409
|
-
|
|
406
|
+
throw new error_1.FirebaseError(`Event function ${key} has malformed resource member`);
|
|
410
407
|
}
|
|
411
408
|
const instance = result[1];
|
|
412
409
|
const bundle = JSON.stringify({
|
|
@@ -423,24 +420,20 @@ class FunctionsEmulator {
|
|
|
423
420
|
else {
|
|
424
421
|
this.logger.log("WARN", `No project in use. Registering function for sentinel namespace '${constants_1.Constants.DEFAULT_DATABASE_EMULATOR_NAMESPACE}'`);
|
|
425
422
|
}
|
|
426
|
-
|
|
427
|
-
.
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
})
|
|
435
|
-
.then(() => {
|
|
436
|
-
return true;
|
|
437
|
-
})
|
|
438
|
-
.catch((err) => {
|
|
423
|
+
const client = new apiv2_1.Client({
|
|
424
|
+
urlPrefix: `http://${registry_1.EmulatorRegistry.getInfoHostString(databaseEmu.getInfo())}`,
|
|
425
|
+
auth: false,
|
|
426
|
+
});
|
|
427
|
+
try {
|
|
428
|
+
await client.post(setTriggersPath, bundle, { headers: { Authorization: "Bearer owner" } });
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
439
431
|
this.logger.log("WARN", "Error adding Realtime Database function: " + err);
|
|
440
432
|
throw err;
|
|
441
|
-
}
|
|
433
|
+
}
|
|
434
|
+
return true;
|
|
442
435
|
}
|
|
443
|
-
addFirestoreTrigger(projectId, key, eventTrigger) {
|
|
436
|
+
async addFirestoreTrigger(projectId, key, eventTrigger) {
|
|
444
437
|
const firestoreEmu = registry_1.EmulatorRegistry.get(types_1.Emulators.FIRESTORE);
|
|
445
438
|
if (!firestoreEmu) {
|
|
446
439
|
return Promise.resolve(false);
|
|
@@ -449,19 +442,18 @@ class FunctionsEmulator {
|
|
|
449
442
|
eventTrigger: Object.assign(Object.assign({}, eventTrigger), { service: "firestore.googleapis.com" }),
|
|
450
443
|
});
|
|
451
444
|
logger_1.logger.debug(`addFirestoreTrigger`, JSON.stringify(bundle));
|
|
452
|
-
|
|
453
|
-
.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
})
|
|
461
|
-
.catch((err) => {
|
|
445
|
+
const client = new apiv2_1.Client({
|
|
446
|
+
urlPrefix: `http://${registry_1.EmulatorRegistry.getInfoHostString(firestoreEmu.getInfo())}`,
|
|
447
|
+
auth: false,
|
|
448
|
+
});
|
|
449
|
+
try {
|
|
450
|
+
await client.put(`/emulator/v1/projects/${projectId}/triggers/${key}`, bundle);
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
462
453
|
this.logger.log("WARN", "Error adding firestore function: " + err);
|
|
463
454
|
throw err;
|
|
464
|
-
}
|
|
455
|
+
}
|
|
456
|
+
return true;
|
|
465
457
|
}
|
|
466
458
|
async addPubsubTrigger(triggerName, key, eventTrigger, signatureType, schedule) {
|
|
467
459
|
const pubsubEmulator = registry_1.EmulatorRegistry.get(types_1.Emulators.PUBSUB);
|
|
@@ -617,7 +609,13 @@ class FunctionsEmulator {
|
|
|
617
609
|
this.logger.logLabeled("SUCCESS", "functions", `Using node@${requestedMajorVersion} from host.`);
|
|
618
610
|
}
|
|
619
611
|
else {
|
|
620
|
-
|
|
612
|
+
if (process.env.FIREPIT_VERSION) {
|
|
613
|
+
this.logger.log("WARN", `You've requested "node" version "${requestedMajorVersion}", but the standalone Firebase CLI comes with bundled Node "${hostMajorVersion}".`);
|
|
614
|
+
this.logger.log("INFO", `To use a different Node.js version, consider removing the standalone Firebase CLI and switching to "firebase-tools" on npm.`);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
this.logger.log("WARN", `Your requested "node" version "${requestedMajorVersion}" doesn't match your global version "${hostMajorVersion}". Using node@${hostMajorVersion} from host.`);
|
|
618
|
+
}
|
|
621
619
|
}
|
|
622
620
|
return process.execPath;
|
|
623
621
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EmulatorHubClient = void 0;
|
|
4
|
-
const api = require("../api");
|
|
5
4
|
const hub_1 = require("./hub");
|
|
6
5
|
const error_1 = require("../error");
|
|
6
|
+
const apiv2_1 = require("../apiv2");
|
|
7
7
|
class EmulatorHubClient {
|
|
8
8
|
constructor(projectId) {
|
|
9
9
|
this.projectId = projectId;
|
|
@@ -12,29 +12,18 @@ class EmulatorHubClient {
|
|
|
12
12
|
foundHub() {
|
|
13
13
|
return this.locator !== undefined;
|
|
14
14
|
}
|
|
15
|
-
getStatus() {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
15
|
+
async getStatus() {
|
|
16
|
+
const apiClient = new apiv2_1.Client({ urlPrefix: this.origin, auth: false });
|
|
17
|
+
await apiClient.get("/");
|
|
19
18
|
}
|
|
20
|
-
getEmulators() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
json: true,
|
|
25
|
-
})
|
|
26
|
-
.then((res) => {
|
|
27
|
-
return res.body;
|
|
28
|
-
});
|
|
19
|
+
async getEmulators() {
|
|
20
|
+
const apiClient = new apiv2_1.Client({ urlPrefix: this.origin, auth: false });
|
|
21
|
+
const res = await apiClient.get(hub_1.EmulatorHub.PATH_EMULATORS);
|
|
22
|
+
return res.body;
|
|
29
23
|
}
|
|
30
|
-
postExport(path) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
json: true,
|
|
34
|
-
data: {
|
|
35
|
-
path,
|
|
36
|
-
},
|
|
37
|
-
});
|
|
24
|
+
async postExport(path) {
|
|
25
|
+
const apiClient = new apiv2_1.Client({ urlPrefix: this.origin, auth: false });
|
|
26
|
+
await apiClient.post(hub_1.EmulatorHub.PATH_EXPORT, { path });
|
|
38
27
|
}
|
|
39
28
|
get origin() {
|
|
40
29
|
const locator = this.assertLocator();
|
|
@@ -5,7 +5,6 @@ const path = require("path");
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const fse = require("fs-extra");
|
|
7
7
|
const http = require("http");
|
|
8
|
-
const api = require("../api");
|
|
9
8
|
const logger_1 = require("../logger");
|
|
10
9
|
const types_1 = require("./types");
|
|
11
10
|
const registry_1 = require("./registry");
|
|
@@ -13,6 +12,7 @@ const error_1 = require("../error");
|
|
|
13
12
|
const hub_1 = require("./hub");
|
|
14
13
|
const downloadableEmulators_1 = require("./downloadableEmulators");
|
|
15
14
|
const rimraf = require("rimraf");
|
|
15
|
+
const apiv2_1 = require("../apiv2");
|
|
16
16
|
class HubExport {
|
|
17
17
|
constructor(projectId, exportPath) {
|
|
18
18
|
this.projectId = projectId;
|
|
@@ -80,24 +80,27 @@ class HubExport {
|
|
|
80
80
|
export_directory: this.tmpDir,
|
|
81
81
|
export_name: metadata.firestore.path,
|
|
82
82
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
json: true,
|
|
86
|
-
data: firestoreExportBody,
|
|
87
|
-
});
|
|
83
|
+
const client = new apiv2_1.Client({ urlPrefix: firestoreHost, auth: false });
|
|
84
|
+
await client.post(`/emulator/v1/projects/${this.projectId}:export`, firestoreExportBody);
|
|
88
85
|
}
|
|
89
86
|
async exportDatabase(metadata) {
|
|
90
87
|
const databaseEmulator = registry_1.EmulatorRegistry.get(types_1.Emulators.DATABASE);
|
|
91
88
|
const databaseAddr = `http://${registry_1.EmulatorRegistry.getInfoHostString(databaseEmulator.getInfo())}`;
|
|
92
|
-
const
|
|
93
|
-
const
|
|
89
|
+
const client = new apiv2_1.Client({ urlPrefix: databaseAddr, auth: true });
|
|
90
|
+
const inspectURL = `/.inspect/databases.json`;
|
|
91
|
+
const inspectRes = await client.get(inspectURL, {
|
|
92
|
+
queryParams: { ns: this.projectId },
|
|
93
|
+
});
|
|
94
94
|
const namespaces = inspectRes.body.map((instance) => instance.name);
|
|
95
95
|
const namespacesToExport = [];
|
|
96
96
|
for (const ns of namespaces) {
|
|
97
|
-
const checkDataPath = `/.json
|
|
98
|
-
const checkDataRes = await
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
const checkDataPath = `/.json`;
|
|
98
|
+
const checkDataRes = await client.get(checkDataPath, {
|
|
99
|
+
queryParams: {
|
|
100
|
+
ns,
|
|
101
|
+
shallow: "true",
|
|
102
|
+
limitToFirst: 1,
|
|
103
|
+
},
|
|
101
104
|
});
|
|
102
105
|
if (checkDataRes.body !== null) {
|
|
103
106
|
namespacesToExport.push(ns);
|
|
@@ -162,11 +165,18 @@ class HubExport {
|
|
|
162
165
|
const storageExportBody = {
|
|
163
166
|
path: storageExportPath,
|
|
164
167
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
168
|
+
const client = new apiv2_1.Client({ urlPrefix: storageHost, auth: false });
|
|
169
|
+
const res = await client.request({
|
|
170
|
+
method: "POST",
|
|
171
|
+
path: "/internal/export",
|
|
172
|
+
headers: { "Content-Type": "application/json" },
|
|
173
|
+
body: storageExportBody,
|
|
174
|
+
responseType: "stream",
|
|
175
|
+
resolveOnHTTPError: true,
|
|
169
176
|
});
|
|
177
|
+
if (res.status >= 400) {
|
|
178
|
+
throw new error_1.FirebaseError(`Failed to export storage: ${await res.response.text()}`);
|
|
179
|
+
}
|
|
170
180
|
}
|
|
171
181
|
}
|
|
172
182
|
exports.HubExport = HubExport;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.checkDatabaseType = void 0;
|
|
4
|
-
const
|
|
4
|
+
const api_1 = require("../api");
|
|
5
|
+
const apiv2_1 = require("../apiv2");
|
|
5
6
|
const logger_1 = require("../logger");
|
|
6
7
|
async function checkDatabaseType(projectId) {
|
|
7
8
|
try {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
origin: api.appengineOrigin,
|
|
11
|
-
});
|
|
9
|
+
const client = new apiv2_1.Client({ urlPrefix: api_1.appengineOrigin, apiVersion: "v1" });
|
|
10
|
+
const resp = await client.get(`/apps/${projectId}`);
|
|
12
11
|
return resp.body.databaseType;
|
|
13
12
|
}
|
|
14
13
|
catch (err) {
|