firebase-tools 10.1.1 → 10.1.5
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 +9 -8
- package/lib/accountImporter.js +10 -8
- package/lib/apiv2.js +92 -48
- package/lib/archiveDirectory.js +63 -73
- package/lib/bin/firebase.js +1 -1
- package/lib/commands/auth-export.js +26 -25
- package/lib/commands/auth-import.js +88 -78
- package/lib/commands/ext-configure.js +1 -1
- package/lib/commands/ext-dev-init.js +1 -1
- package/lib/commands/ext-dev-publish.js +1 -1
- package/lib/commands/ext-dev-register.js +1 -1
- package/lib/commands/ext-dev-usage.js +3 -8
- package/lib/commands/ext-info.js +1 -1
- package/lib/commands/ext-install.js +1 -1
- package/lib/commands/ext-uninstall.js +1 -1
- package/lib/commands/ext-update.js +1 -1
- package/lib/commands/functions-config-clone.js +22 -23
- package/lib/commands/functions-config-get.js +22 -22
- package/lib/commands/functions-config-set.js +24 -22
- package/lib/commands/functions-config-unset.js +20 -22
- package/lib/commands/help.js +12 -12
- package/lib/commands/hosting-channel-create.js +1 -1
- package/lib/commands/hosting-channel-delete.js +2 -2
- package/lib/commands/hosting-channel-deploy.js +1 -1
- package/lib/commands/hosting-clone.js +1 -1
- package/lib/commands/login-ci.js +10 -10
- package/lib/commands/remoteconfig-versions-list.js +6 -1
- package/lib/commands/setup-emulators-database.js +8 -7
- package/lib/commands/setup-emulators-firestore.js +8 -7
- package/lib/commands/setup-emulators-pubsub.js +5 -4
- package/lib/commands/setup-emulators-storage.js +3 -2
- package/lib/commands/setup-emulators-ui.js +8 -7
- package/lib/commands/target-apply.js +17 -16
- package/lib/commands/target-clear.js +11 -10
- package/lib/commands/target-remove.js +10 -9
- package/lib/commands/target.js +20 -20
- package/lib/database/metadata.js +16 -24
- package/lib/defaultCredentials.js +3 -3
- package/lib/deploy/functions/backend.js +3 -1
- package/lib/deploy/functions/prepare.js +2 -2
- package/lib/deploy/functions/release/fabricator.js +4 -1
- package/lib/deploy/functions/runtimes/golang/index.js +2 -1
- package/lib/deploy/functions/validate.js +28 -1
- package/lib/deploy/hosting/convertConfig.js +45 -24
- package/lib/deploy/hosting/prepare.js +1 -1
- package/lib/emulator/downloadableEmulators.js +3 -2
- package/lib/emulator/functionsEmulator.js +9 -1
- package/lib/emulator/functionsEmulatorRuntime.js +4 -4
- package/lib/emulator/storage/apis/gcloud.js +2 -2
- package/lib/emulator/storage/files.js +8 -3
- package/lib/emulator/storage/rules/runtime.js +5 -4
- package/lib/extensions/askUserForConsent.js +1 -1
- package/lib/extensions/askUserForParam.js +1 -1
- package/lib/extensions/billingMigrationHelper.js +1 -1
- package/lib/extensions/changelog.js +1 -1
- package/lib/extensions/displayExtensionInfo.js +1 -1
- package/lib/extensions/extensionsApi.js +57 -112
- package/lib/extensions/extensionsHelper.js +20 -32
- package/lib/extensions/provisioningHelper.js +7 -10
- package/lib/extensions/resolveSource.js +5 -57
- package/lib/extensions/updateHelper.js +1 -15
- package/lib/extensions/utils.js +4 -2
- package/lib/extensions/warnings.js +1 -1
- package/lib/functionsConfig.js +4 -5
- package/lib/gcp/cloudbilling.js +8 -19
- package/lib/gcp/cloudfunctions.js +22 -46
- package/lib/gcp/cloudlogging.js +8 -11
- package/lib/gcp/cloudmonitoring.js +8 -5
- package/lib/gcp/cloudscheduler.js +7 -18
- package/lib/gcp/firedata.js +5 -4
- package/lib/gcp/firestore.js +5 -5
- package/lib/gcp/iam.js +18 -33
- package/lib/gcp/resourceManager.js +8 -13
- package/lib/gcp/rules.js +18 -41
- package/lib/gcp/runtimeconfig.js +31 -53
- package/lib/gcp/secretManager.js +21 -43
- package/lib/gcp/storage.js +25 -29
- package/lib/projectUtils.js +1 -1
- package/lib/remoteconfig/get.js +14 -8
- package/lib/remoteconfig/rollback.js +13 -6
- package/lib/remoteconfig/versionslist.js +13 -7
- package/npm-shrinkwrap.json +1706 -2525
- package/package.json +16 -11
- package/schema/firebase-config.json +387 -12
- package/templates/init/hosting/index.html +1 -1
- package/lib/commands/functions-config-legacy.js +0 -45
- package/lib/prepareFirebaseRules.js +0 -58
package/lib/accountExporter.js
CHANGED
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
var os = require("os");
|
|
3
3
|
var path = require("path");
|
|
4
4
|
var _ = require("lodash");
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const { Client } = require("./apiv2");
|
|
6
|
+
const { googleOrigin } = require("./api");
|
|
7
7
|
var { FirebaseError } = require("./error");
|
|
8
|
+
var utils = require("./utils");
|
|
9
|
+
const apiClient = new Client({
|
|
10
|
+
urlPrefix: googleOrigin,
|
|
11
|
+
});
|
|
8
12
|
var EXPORTED_JSON_KEYS = [
|
|
9
13
|
"localId",
|
|
10
14
|
"email",
|
|
@@ -149,12 +153,9 @@ var serialExportUsers = function (projectId, options) {
|
|
|
149
153
|
if (!options.timeoutRetryCount) {
|
|
150
154
|
options.timeoutRetryCount = 0;
|
|
151
155
|
}
|
|
152
|
-
return
|
|
153
|
-
.
|
|
154
|
-
|
|
155
|
-
json: true,
|
|
156
|
-
data: postBody,
|
|
157
|
-
origin: api.googleOrigin,
|
|
156
|
+
return apiClient
|
|
157
|
+
.post("/identitytoolkit/v3/relyingparty/downloadAccount", postBody, {
|
|
158
|
+
skipLog: { resBody: true },
|
|
158
159
|
})
|
|
159
160
|
.then(function (ret) {
|
|
160
161
|
options.timeoutRetryCount = 0;
|
package/lib/accountImporter.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var clc = require("cli-color");
|
|
3
3
|
var _ = require("lodash");
|
|
4
|
-
|
|
4
|
+
const { Client } = require("./apiv2");
|
|
5
|
+
const { googleOrigin } = require("./api");
|
|
5
6
|
const { logger } = require("./logger");
|
|
6
|
-
var utils = require("./utils");
|
|
7
7
|
var { FirebaseError } = require("./error");
|
|
8
|
+
var utils = require("./utils");
|
|
9
|
+
const apiClient = new Client({
|
|
10
|
+
urlPrefix: googleOrigin,
|
|
11
|
+
});
|
|
8
12
|
var ALLOWED_JSON_KEYS = [
|
|
9
13
|
"localId",
|
|
10
14
|
"email",
|
|
@@ -266,12 +270,10 @@ var validateUserJson = function (userJson) {
|
|
|
266
270
|
};
|
|
267
271
|
var _sendRequest = function (projectId, userList, hashOptions) {
|
|
268
272
|
logger.info("Starting importing " + userList.length + " account(s).");
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
data: _genUploadAccountPostBody(projectId, userList, hashOptions),
|
|
274
|
-
origin: api.googleOrigin,
|
|
273
|
+
const postData = _genUploadAccountPostBody(projectId, userList, hashOptions);
|
|
274
|
+
return apiClient
|
|
275
|
+
.post("/identitytoolkit/v3/relyingparty/uploadAccount", postData, {
|
|
276
|
+
skipLog: { body: true },
|
|
275
277
|
})
|
|
276
278
|
.then(function (ret) {
|
|
277
279
|
if (ret.body.error) {
|
package/lib/apiv2.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Client = exports.setAccessToken = exports.setRefreshToken = void 0;
|
|
4
|
-
const stream_1 = require("stream");
|
|
5
4
|
const url_1 = require("url");
|
|
5
|
+
const stream_1 = require("stream");
|
|
6
6
|
const ProxyAgent = require("proxy-agent");
|
|
7
|
+
const retry = require("retry");
|
|
7
8
|
const abort_controller_1 = require("abort-controller");
|
|
8
9
|
const node_fetch_1 = require("node-fetch");
|
|
9
10
|
const util_1 = require("util");
|
|
@@ -151,6 +152,7 @@ class Client {
|
|
|
151
152
|
return `${this.opts.urlPrefix}${versionPath}${options.path}`;
|
|
152
153
|
}
|
|
153
154
|
async doRequest(options) {
|
|
155
|
+
var _a;
|
|
154
156
|
if (!options.path.startsWith("/")) {
|
|
155
157
|
options.path = "/" + options.path;
|
|
156
158
|
}
|
|
@@ -199,53 +201,95 @@ class Client {
|
|
|
199
201
|
else if (options.body !== undefined) {
|
|
200
202
|
fetchOptions.body = JSON.stringify(options.body);
|
|
201
203
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
catch (thrown) {
|
|
208
|
-
const err = thrown instanceof Error ? thrown : new Error(thrown);
|
|
209
|
-
const isAbortError = err.name.includes("AbortError");
|
|
210
|
-
if (isAbortError) {
|
|
211
|
-
throw new error_1.FirebaseError(`Timeout reached making request to ${fetchURL}`, { original: err });
|
|
212
|
-
}
|
|
213
|
-
throw new error_1.FirebaseError(`Failed to make request to ${fetchURL}`, { original: err });
|
|
214
|
-
}
|
|
215
|
-
finally {
|
|
216
|
-
if (reqTimeout) {
|
|
217
|
-
clearTimeout(reqTimeout);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
let body;
|
|
221
|
-
if (options.responseType === "json") {
|
|
222
|
-
const text = await res.text();
|
|
223
|
-
if (!text.length) {
|
|
224
|
-
body = undefined;
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
body = JSON.parse(text);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else if (options.responseType === "stream") {
|
|
231
|
-
body = res.body;
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
throw new error_1.FirebaseError(`Unable to interpret response. Please set responseType.`, {
|
|
235
|
-
exit: 2,
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
this.logResponse(res, body, options);
|
|
239
|
-
if (res.status >= 400) {
|
|
240
|
-
if (!options.resolveOnHTTPError) {
|
|
241
|
-
throw responseToError({ statusCode: res.status }, body);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
status: res.status,
|
|
246
|
-
response: res,
|
|
247
|
-
body,
|
|
204
|
+
const operationOptions = {
|
|
205
|
+
retries: ((_a = options.retryCodes) === null || _a === void 0 ? void 0 : _a.length) ? 1 : 2,
|
|
206
|
+
minTimeout: 1 * 1000,
|
|
207
|
+
maxTimeout: 5 * 1000,
|
|
248
208
|
};
|
|
209
|
+
if (typeof options.retries === "number") {
|
|
210
|
+
operationOptions.retries = options.retries;
|
|
211
|
+
}
|
|
212
|
+
if (typeof options.retryMinTimeout === "number") {
|
|
213
|
+
operationOptions.minTimeout = options.retryMinTimeout;
|
|
214
|
+
}
|
|
215
|
+
if (typeof options.retryMaxTimeout === "number") {
|
|
216
|
+
operationOptions.maxTimeout = options.retryMaxTimeout;
|
|
217
|
+
}
|
|
218
|
+
const operation = retry.operation(operationOptions);
|
|
219
|
+
return await new Promise((resolve, reject) => {
|
|
220
|
+
operation.attempt(async (currentAttempt) => {
|
|
221
|
+
var _a;
|
|
222
|
+
let res;
|
|
223
|
+
let body;
|
|
224
|
+
try {
|
|
225
|
+
if (currentAttempt > 1) {
|
|
226
|
+
logger_1.logger.debug(`*** [apiv2] Attempting the request again. Attempt number ${currentAttempt}`);
|
|
227
|
+
}
|
|
228
|
+
this.logRequest(options);
|
|
229
|
+
try {
|
|
230
|
+
res = await (0, node_fetch_1.default)(fetchURL, fetchOptions);
|
|
231
|
+
}
|
|
232
|
+
catch (thrown) {
|
|
233
|
+
const err = thrown instanceof Error ? thrown : new Error(thrown);
|
|
234
|
+
const isAbortError = err.name.includes("AbortError");
|
|
235
|
+
if (isAbortError) {
|
|
236
|
+
throw new error_1.FirebaseError(`Timeout reached making request to ${fetchURL}`, {
|
|
237
|
+
original: err,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
throw new error_1.FirebaseError(`Failed to make request to ${fetchURL}`, { original: err });
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
if (reqTimeout) {
|
|
244
|
+
clearTimeout(reqTimeout);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (options.responseType === "json") {
|
|
248
|
+
const text = await res.text();
|
|
249
|
+
if (!text.length) {
|
|
250
|
+
body = undefined;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
try {
|
|
254
|
+
body = JSON.parse(text);
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
this.logResponse(res, text, options);
|
|
258
|
+
throw new error_1.FirebaseError(`Unable to parse JSON: ${err}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (options.responseType === "stream") {
|
|
263
|
+
body = res.body;
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
throw new error_1.FirebaseError(`Unable to interpret response. Please set responseType.`, {
|
|
267
|
+
exit: 2,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
return err instanceof error_1.FirebaseError ? reject(err) : reject(new error_1.FirebaseError(`${err}`));
|
|
273
|
+
}
|
|
274
|
+
this.logResponse(res, body, options);
|
|
275
|
+
if (res.status >= 400) {
|
|
276
|
+
if ((_a = options.retryCodes) === null || _a === void 0 ? void 0 : _a.includes(res.status)) {
|
|
277
|
+
const err = responseToError({ statusCode: res.status }, body) || undefined;
|
|
278
|
+
if (operation.retry(err)) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (!options.resolveOnHTTPError) {
|
|
283
|
+
return reject(responseToError({ statusCode: res.status }, body));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
resolve({
|
|
287
|
+
status: res.status,
|
|
288
|
+
response: res,
|
|
289
|
+
body,
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
});
|
|
249
293
|
}
|
|
250
294
|
logRequest(options) {
|
|
251
295
|
var _a, _b;
|
|
@@ -282,7 +326,7 @@ class Client {
|
|
|
282
326
|
}
|
|
283
327
|
exports.Client = Client;
|
|
284
328
|
function isLocalInsecureRequest(urlPrefix) {
|
|
285
|
-
const u =
|
|
329
|
+
const u = new url_1.URL(urlPrefix);
|
|
286
330
|
return u.protocol === "http:";
|
|
287
331
|
}
|
|
288
332
|
function bodyToString(body) {
|
package/lib/archiveDirectory.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.archiveDirectory = void 0;
|
|
3
4
|
const archiver = require("archiver");
|
|
4
5
|
const filesize = require("filesize");
|
|
5
6
|
const fs = require("fs");
|
|
6
7
|
const path = require("path");
|
|
7
8
|
const tar = require("tar");
|
|
8
9
|
const tmp = require("tmp");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
10
|
+
const error_1 = require("./error");
|
|
11
|
+
const listFiles_1 = require("./listFiles");
|
|
12
|
+
const logger_1 = require("./logger");
|
|
11
13
|
const fsAsync = require("./fsAsync");
|
|
12
|
-
|
|
13
|
-
const utils = require("./utils");
|
|
14
|
-
const archiveDirectory = (sourceDirectory, options) => {
|
|
15
|
-
options = options || {};
|
|
14
|
+
async function archiveDirectory(sourceDirectory, options = {}) {
|
|
16
15
|
let postfix = ".tar.gz";
|
|
17
16
|
if (options.type === "zip") {
|
|
18
17
|
postfix = ".zip";
|
|
@@ -26,105 +25,96 @@ const archiveDirectory = (sourceDirectory, options) => {
|
|
|
26
25
|
}
|
|
27
26
|
let makeArchive;
|
|
28
27
|
if (options.type === "zip") {
|
|
29
|
-
makeArchive =
|
|
28
|
+
makeArchive = zipDirectory(sourceDirectory, tempFile, options);
|
|
30
29
|
}
|
|
31
30
|
else {
|
|
32
|
-
makeArchive =
|
|
31
|
+
makeArchive = tarDirectory(sourceDirectory, tempFile, options);
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
logger.debug(`Archived ${filesize(archive.size)} in ${sourceDirectory}.`);
|
|
33
|
+
try {
|
|
34
|
+
const archive = await makeArchive;
|
|
35
|
+
logger_1.logger.debug(`Archived ${filesize(archive.size)} in ${sourceDirectory}.`);
|
|
37
36
|
return archive;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (err instanceof FirebaseError) {
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err instanceof error_1.FirebaseError) {
|
|
41
40
|
throw err;
|
|
42
41
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
const allFiles = listFiles(sourceDirectory, options.ignore);
|
|
42
|
+
throw new error_1.FirebaseError("Failed to create archive.", { original: err });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.archiveDirectory = archiveDirectory;
|
|
46
|
+
async function tarDirectory(sourceDirectory, tempFile, options) {
|
|
47
|
+
const allFiles = (0, listFiles_1.listFiles)(sourceDirectory, options.ignore);
|
|
50
48
|
try {
|
|
51
49
|
fs.statSync(sourceDirectory);
|
|
52
50
|
}
|
|
53
51
|
catch (err) {
|
|
54
52
|
if (err.code === "ENOENT") {
|
|
55
|
-
|
|
53
|
+
throw new error_1.FirebaseError(`Could not read directory "${sourceDirectory}"`);
|
|
56
54
|
}
|
|
57
55
|
throw err;
|
|
58
56
|
}
|
|
59
57
|
if (!allFiles.length) {
|
|
60
|
-
|
|
58
|
+
throw new error_1.FirebaseError(`Cannot create a tar archive with 0 files from directory "${sourceDirectory}"`);
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
.create({
|
|
60
|
+
await tar.create({
|
|
64
61
|
gzip: true,
|
|
65
62
|
file: tempFile.name,
|
|
66
63
|
cwd: sourceDirectory,
|
|
67
64
|
follow: true,
|
|
68
65
|
noDirRecurse: true,
|
|
69
66
|
portable: true,
|
|
70
|
-
}, allFiles)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
};
|
|
82
|
-
const _zipDirectory = (sourceDirectory, tempFile, options) => {
|
|
67
|
+
}, allFiles);
|
|
68
|
+
const stats = fs.statSync(tempFile.name);
|
|
69
|
+
return {
|
|
70
|
+
file: tempFile.name,
|
|
71
|
+
stream: fs.createReadStream(tempFile.name),
|
|
72
|
+
manifest: allFiles,
|
|
73
|
+
size: stats.size,
|
|
74
|
+
source: sourceDirectory,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function zipDirectory(sourceDirectory, tempFile, options) {
|
|
83
78
|
const archiveFileStream = fs.createWriteStream(tempFile.name, {
|
|
84
79
|
flags: "w",
|
|
85
80
|
encoding: "binary",
|
|
86
81
|
});
|
|
87
82
|
const archive = archiver("zip");
|
|
88
|
-
const archiveDone =
|
|
83
|
+
const archiveDone = pipeAsync(archive, archiveFileStream);
|
|
89
84
|
const allFiles = [];
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.
|
|
85
|
+
let files;
|
|
86
|
+
try {
|
|
87
|
+
files = await fsAsync.readdirRecursive({ path: sourceDirectory, ignore: options.ignore });
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
93
90
|
if (err.code === "ENOENT") {
|
|
94
|
-
|
|
91
|
+
throw new error_1.FirebaseError(`Could not read directory "${sourceDirectory}"`, { original: err });
|
|
95
92
|
}
|
|
96
93
|
throw err;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
mode: file.mode,
|
|
105
|
-
});
|
|
94
|
+
}
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
const name = path.relative(sourceDirectory, file.name);
|
|
97
|
+
allFiles.push(name);
|
|
98
|
+
archive.file(file.name, {
|
|
99
|
+
name,
|
|
100
|
+
mode: file.mode,
|
|
106
101
|
});
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const _pipeAsync = function (from, to) {
|
|
122
|
-
return new Promise(function (resolve, reject) {
|
|
102
|
+
}
|
|
103
|
+
void archive.finalize();
|
|
104
|
+
await archiveDone;
|
|
105
|
+
const stats = fs.statSync(tempFile.name);
|
|
106
|
+
return {
|
|
107
|
+
file: tempFile.name,
|
|
108
|
+
stream: fs.createReadStream(tempFile.name),
|
|
109
|
+
manifest: allFiles,
|
|
110
|
+
size: stats.size,
|
|
111
|
+
source: sourceDirectory,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async function pipeAsync(from, to) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
123
116
|
to.on("finish", resolve);
|
|
124
117
|
to.on("error", reject);
|
|
125
118
|
from.pipe(to);
|
|
126
119
|
});
|
|
127
|
-
}
|
|
128
|
-
module.exports = {
|
|
129
|
-
archiveDirectory,
|
|
130
|
-
};
|
|
120
|
+
}
|
package/lib/bin/firebase.js
CHANGED
|
@@ -15,7 +15,7 @@ if (!semver.satisfies(nodeVersion, pkg.engines.node)) {
|
|
|
15
15
|
const updateNotifier = require("update-notifier")({ pkg: pkg });
|
|
16
16
|
const clc = require("cli-color");
|
|
17
17
|
const TerminalRenderer = require("marked-terminal");
|
|
18
|
-
const marked = require("marked");
|
|
18
|
+
const marked = require("marked").marked;
|
|
19
19
|
marked.setOptions({
|
|
20
20
|
renderer: new TerminalRenderer(),
|
|
21
21
|
});
|
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
module.exports = new Command("auth:export [dataFile]")
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const clc = require("cli-color");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
const command_1 = require("../command");
|
|
7
|
+
const logger_1 = require("../logger");
|
|
8
|
+
const projectUtils_1 = require("../projectUtils");
|
|
9
|
+
const requirePermissions_1 = require("../requirePermissions");
|
|
10
|
+
const accountExporter_1 = require("../accountExporter");
|
|
11
|
+
const MAX_BATCH_SIZE = 1000;
|
|
12
|
+
exports.default = new command_1.Command("auth:export [dataFile]")
|
|
14
13
|
.description("Export accounts from your Firebase project into a data file")
|
|
15
|
-
.option("--format <format>", "Format of exported data (csv, json). Ignored if
|
|
16
|
-
.before(requirePermissions, ["firebaseauth.users.get"])
|
|
17
|
-
.action(
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
.option("--format <format>", "Format of exported data (csv, json). Ignored if <dataFile> has format extension.")
|
|
15
|
+
.before(requirePermissions_1.requirePermissions, ["firebaseauth.users.get"])
|
|
16
|
+
.action((dataFile, options) => {
|
|
17
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
18
|
+
const checkRes = (0, accountExporter_1.validateOptions)(options, dataFile);
|
|
20
19
|
if (!checkRes.format) {
|
|
21
20
|
return checkRes;
|
|
22
21
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (exportOptions.format === "json") {
|
|
22
|
+
const writeStream = fs.createWriteStream(dataFile);
|
|
23
|
+
if (checkRes.format === "json") {
|
|
26
24
|
writeStream.write('{"users": [' + os.EOL);
|
|
27
25
|
}
|
|
28
|
-
exportOptions
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
const exportOptions = {
|
|
27
|
+
format: checkRes.format,
|
|
28
|
+
writeStream,
|
|
29
|
+
batchSize: MAX_BATCH_SIZE,
|
|
30
|
+
};
|
|
31
|
+
logger_1.logger.info("Exporting accounts to " + clc.bold(dataFile));
|
|
32
|
+
return (0, accountExporter_1.serialExportUsers)(projectId, exportOptions).then(() => {
|
|
32
33
|
if (exportOptions.format === "json") {
|
|
33
34
|
writeStream.write("]}");
|
|
34
35
|
}
|
|
35
36
|
writeStream.end();
|
|
36
|
-
return new Promise(
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
37
38
|
writeStream.on("finish", resolve);
|
|
38
39
|
writeStream.on("close", resolve);
|
|
39
40
|
writeStream.on("error", reject);
|