firebase-tools 11.5.0 → 11.6.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/command.js +33 -7
- package/lib/commands/emulators-exec.js +4 -1
- package/lib/commands/emulators-export.js +5 -2
- package/lib/commands/emulators-start.js +23 -17
- package/lib/commands/ext-dev-publish.js +3 -0
- package/lib/commands/login.js +2 -2
- package/lib/emulator/auth/index.js +7 -2
- package/lib/emulator/auth/operations.js +10 -10
- package/lib/emulator/commandUtils.js +32 -15
- package/lib/emulator/constants.js +14 -6
- package/lib/emulator/controller.js +54 -17
- package/lib/emulator/downloadableEmulators.js +7 -7
- package/lib/emulator/eventarcEmulator.js +148 -0
- package/lib/emulator/extensionsEmulator.js +3 -1
- package/lib/emulator/functionsEmulator.js +44 -4
- package/lib/emulator/functionsEmulatorShared.js +6 -1
- package/lib/emulator/hub.js +7 -3
- package/lib/emulator/hubClient.js +2 -2
- package/lib/emulator/hubExport.js +22 -2
- package/lib/emulator/registry.js +1 -0
- package/lib/emulator/storage/files.js +14 -2
- package/lib/emulator/storage/rules/runtime.js +2 -2
- package/lib/emulator/storage/server.js +2 -1
- package/lib/emulator/storage/upload.js +1 -0
- package/lib/emulator/types.js +3 -0
- package/lib/emulator/ui.js +7 -2
- package/lib/extensions/extensionsApi.js +2 -1
- package/lib/extensions/extensionsHelper.js +29 -1
- package/lib/serve/index.js +15 -0
- package/lib/track.js +119 -3
- package/lib/utils.js +14 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/schema/firebase-config.json +12 -0
- package/templates/extensions/CHANGELOG.md +1 -7
|
@@ -17,6 +17,8 @@ const logger_1 = require("../../logger");
|
|
|
17
17
|
const adminSdkConfig_1 = require("../adminSdkConfig");
|
|
18
18
|
const types_1 = require("./rules/types");
|
|
19
19
|
const upload_1 = require("./upload");
|
|
20
|
+
const track_1 = require("../../track");
|
|
21
|
+
const types_2 = require("../types");
|
|
20
22
|
class StoredFile {
|
|
21
23
|
constructor(metadata) {
|
|
22
24
|
this.metadata = metadata;
|
|
@@ -292,7 +294,7 @@ class StorageLayer {
|
|
|
292
294
|
get dirPath() {
|
|
293
295
|
return this._persistence.dirPath;
|
|
294
296
|
}
|
|
295
|
-
async export(storageExportPath) {
|
|
297
|
+
async export(storageExportPath, options) {
|
|
296
298
|
var e_1, _a;
|
|
297
299
|
const bucketsList = {
|
|
298
300
|
buckets: [],
|
|
@@ -300,6 +302,11 @@ class StorageLayer {
|
|
|
300
302
|
for (const b of await this.listBuckets()) {
|
|
301
303
|
bucketsList.buckets.push({ id: b.id });
|
|
302
304
|
}
|
|
305
|
+
void (0, track_1.trackEmulator)("emulator_export", {
|
|
306
|
+
initiated_by: options.initiatedBy,
|
|
307
|
+
emulator_name: types_2.Emulators.STORAGE,
|
|
308
|
+
count: bucketsList.buckets.length,
|
|
309
|
+
});
|
|
303
310
|
const bucketsFilePath = path.join(storageExportPath, "buckets.json");
|
|
304
311
|
await fse.writeFile(bucketsFilePath, JSON.stringify(bucketsList, undefined, 2));
|
|
305
312
|
const blobsDirPath = path.join(storageExportPath, "blobs");
|
|
@@ -323,9 +330,14 @@ class StorageLayer {
|
|
|
323
330
|
finally { if (e_1) throw e_1.error; }
|
|
324
331
|
}
|
|
325
332
|
}
|
|
326
|
-
import(storageExportPath) {
|
|
333
|
+
import(storageExportPath, options) {
|
|
327
334
|
const bucketsFile = path.join(storageExportPath, "buckets.json");
|
|
328
335
|
const bucketsList = JSON.parse((0, fs_1.readFileSync)(bucketsFile, "utf-8"));
|
|
336
|
+
void (0, track_1.trackEmulator)("emulator_import", {
|
|
337
|
+
initiated_by: options.initiatedBy,
|
|
338
|
+
emulator_name: types_2.Emulators.STORAGE,
|
|
339
|
+
count: bucketsList.buckets.length,
|
|
340
|
+
});
|
|
329
341
|
for (const b of bucketsList.buckets) {
|
|
330
342
|
const bucketMetadata = new metadata_1.CloudStorageBucketMetadata(b.id);
|
|
331
343
|
this._buckets.set(b.id, bucketMetadata);
|
|
@@ -65,12 +65,12 @@ class StorageRulesRuntime {
|
|
|
65
65
|
get alive() {
|
|
66
66
|
return this._alive;
|
|
67
67
|
}
|
|
68
|
-
async start(
|
|
68
|
+
async start(autoDownload = true) {
|
|
69
69
|
var _a, _b;
|
|
70
70
|
const downloadDetails = downloadableEmulators_1.DownloadDetails[types_2.Emulators.STORAGE];
|
|
71
71
|
const hasEmulator = fs.existsSync(downloadDetails.downloadPath);
|
|
72
72
|
if (!hasEmulator) {
|
|
73
|
-
if (
|
|
73
|
+
if (autoDownload) {
|
|
74
74
|
if (process.env.CI) {
|
|
75
75
|
utils.logWarning(`It appears you are running in a CI environment. You can avoid downloading the ${constants_1.Constants.description(types_2.Emulators.STORAGE)} repeatedly by caching the ${downloadDetails.opts.cacheDir} directory.`);
|
|
76
76
|
}
|
|
@@ -36,12 +36,13 @@ function createApp(defaultProjectId, emulator) {
|
|
|
36
36
|
type: ["application/json"],
|
|
37
37
|
}));
|
|
38
38
|
app.post("/internal/export", async (req, res) => {
|
|
39
|
+
const initiatedBy = req.body.initiatedBy || "unknown";
|
|
39
40
|
const path = req.body.path;
|
|
40
41
|
if (!path) {
|
|
41
42
|
res.status(400).send("Export request body must include 'path'.");
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
|
-
await storageLayer.export(path);
|
|
45
|
+
await storageLayer.export(path, { initiatedBy });
|
|
45
46
|
res.sendStatus(200);
|
|
46
47
|
});
|
|
47
48
|
app.put("/internal/setRules", async (req, res) => {
|
package/lib/emulator/types.js
CHANGED
|
@@ -14,6 +14,7 @@ var Emulators;
|
|
|
14
14
|
Emulators["LOGGING"] = "logging";
|
|
15
15
|
Emulators["STORAGE"] = "storage";
|
|
16
16
|
Emulators["EXTENSIONS"] = "extensions";
|
|
17
|
+
Emulators["EVENTARC"] = "eventarc";
|
|
17
18
|
})(Emulators = exports.Emulators || (exports.Emulators = {}));
|
|
18
19
|
exports.DOWNLOADABLE_EMULATORS = [
|
|
19
20
|
Emulators.FIRESTORE,
|
|
@@ -36,12 +37,14 @@ exports.ALL_SERVICE_EMULATORS = [
|
|
|
36
37
|
Emulators.HOSTING,
|
|
37
38
|
Emulators.PUBSUB,
|
|
38
39
|
Emulators.STORAGE,
|
|
40
|
+
Emulators.EVENTARC,
|
|
39
41
|
].filter((v) => v);
|
|
40
42
|
exports.EMULATORS_SUPPORTED_BY_FUNCTIONS = [
|
|
41
43
|
Emulators.FIRESTORE,
|
|
42
44
|
Emulators.DATABASE,
|
|
43
45
|
Emulators.PUBSUB,
|
|
44
46
|
Emulators.STORAGE,
|
|
47
|
+
Emulators.EVENTARC,
|
|
45
48
|
];
|
|
46
49
|
exports.EMULATORS_SUPPORTED_BY_UI = [
|
|
47
50
|
Emulators.AUTH,
|
package/lib/emulator/ui.js
CHANGED
|
@@ -6,6 +6,7 @@ const downloadableEmulators = require("./downloadableEmulators");
|
|
|
6
6
|
const registry_1 = require("./registry");
|
|
7
7
|
const error_1 = require("../error");
|
|
8
8
|
const constants_1 = require("./constants");
|
|
9
|
+
const track_1 = require("../track");
|
|
9
10
|
class EmulatorUI {
|
|
10
11
|
constructor(args) {
|
|
11
12
|
this.args = args;
|
|
@@ -15,14 +16,18 @@ class EmulatorUI {
|
|
|
15
16
|
throw new error_1.FirebaseError(`Cannot start ${constants_1.Constants.description(types_1.Emulators.UI)} without ${constants_1.Constants.description(types_1.Emulators.HUB)}!`);
|
|
16
17
|
}
|
|
17
18
|
const hubInfo = registry_1.EmulatorRegistry.get(types_1.Emulators.HUB).getInfo();
|
|
18
|
-
const { auto_download, host, port, projectId } = this.args;
|
|
19
|
+
const { auto_download: autoDownload, host, port, projectId } = this.args;
|
|
19
20
|
const env = {
|
|
20
21
|
HOST: host.toString(),
|
|
21
22
|
PORT: port.toString(),
|
|
22
23
|
GCLOUD_PROJECT: projectId,
|
|
23
24
|
[constants_1.Constants.FIREBASE_EMULATOR_HUB]: registry_1.EmulatorRegistry.getInfoHostString(hubInfo),
|
|
24
25
|
};
|
|
25
|
-
|
|
26
|
+
const session = (0, track_1.emulatorSession)();
|
|
27
|
+
if (session) {
|
|
28
|
+
env[constants_1.Constants.FIREBASE_GA_SESSION] = JSON.stringify(session);
|
|
29
|
+
}
|
|
30
|
+
return downloadableEmulators.start(types_1.Emulators.UI, { auto_download: autoDownload }, env);
|
|
26
31
|
}
|
|
27
32
|
connect() {
|
|
28
33
|
return Promise.resolve();
|
|
@@ -291,13 +291,14 @@ async function listExtensions(publisherId) {
|
|
|
291
291
|
return extensions;
|
|
292
292
|
}
|
|
293
293
|
exports.listExtensions = listExtensions;
|
|
294
|
-
async function listExtensionVersions(ref, filter = "") {
|
|
294
|
+
async function listExtensionVersions(ref, filter = "", showPrereleases = false) {
|
|
295
295
|
const { publisherId, extensionId } = refs.parse(ref);
|
|
296
296
|
const extensionVersions = [];
|
|
297
297
|
const getNextPage = async (pageToken = "") => {
|
|
298
298
|
const res = await apiClient.get(`/publishers/${publisherId}/extensions/${extensionId}/versions`, {
|
|
299
299
|
queryParams: {
|
|
300
300
|
filter,
|
|
301
|
+
showPrereleases: String(showPrereleases),
|
|
301
302
|
pageSize: PAGE_SIZE_MAX,
|
|
302
303
|
pageToken,
|
|
303
304
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.canonicalizeRefInput = exports.diagnoseAndFixProject = exports.confirm = exports.getSourceOrigin = exports.isLocalOrURLPath = exports.isLocalPath = exports.isUrlPath = exports.instanceIdExists = exports.promptForRepeatInstance = exports.promptForOfficialExtension = exports.displayReleaseNotes = exports.getPublisherProjectFromName = exports.createSourceFromLocation = exports.publishExtensionVersionFromLocalSource = exports.ensureExtensionsApiEnabled = exports.promptForValidInstanceId = exports.validateSpec = exports.validateCommandLineParams = exports.populateDefaultParams = exports.substituteParams = exports.getFirebaseProjectParams = exports.getDBInstanceFromURL = exports.resourceTypeToNiceName = exports.AUTOPOULATED_PARAM_PLACEHOLDERS = exports.EXTENSIONS_BUCKET_NAME = exports.URL_REGEX = exports.logPrefix = exports.SourceOrigin = exports.SpecParamType = void 0;
|
|
3
|
+
exports.canonicalizeRefInput = exports.diagnoseAndFixProject = exports.confirm = exports.getSourceOrigin = exports.isLocalOrURLPath = exports.isLocalPath = exports.isUrlPath = exports.instanceIdExists = exports.promptForRepeatInstance = exports.promptForOfficialExtension = exports.displayReleaseNotes = exports.getPublisherProjectFromName = exports.createSourceFromLocation = exports.publishExtensionVersionFromLocalSource = exports.incrementPrereleaseVersion = exports.ensureExtensionsApiEnabled = exports.promptForValidInstanceId = exports.validateSpec = exports.validateCommandLineParams = exports.populateDefaultParams = exports.substituteParams = exports.getFirebaseProjectParams = exports.getDBInstanceFromURL = exports.resourceTypeToNiceName = exports.AUTOPOULATED_PARAM_PLACEHOLDERS = exports.EXTENSIONS_BUCKET_NAME = exports.URL_REGEX = exports.logPrefix = exports.SourceOrigin = exports.SpecParamType = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const ora = require("ora");
|
|
6
6
|
const semver = require("semver");
|
|
@@ -282,6 +282,33 @@ async function archiveAndUploadSource(extPath, bucketName) {
|
|
|
282
282
|
const res = await (0, storage_1.uploadObject)(zippedSource, bucketName);
|
|
283
283
|
return `/${res.bucket}/${res.object}`;
|
|
284
284
|
}
|
|
285
|
+
async function incrementPrereleaseVersion(ref, extensionVersion, stage) {
|
|
286
|
+
var _a;
|
|
287
|
+
const stageOptions = ["stable", "alpha", "beta", "rc"];
|
|
288
|
+
if (!stageOptions.includes(stage)) {
|
|
289
|
+
throw new error_1.FirebaseError(`--stage flag only supports the following values: ${stageOptions}`);
|
|
290
|
+
}
|
|
291
|
+
if (stage !== "stable") {
|
|
292
|
+
const version = semver.parse(extensionVersion);
|
|
293
|
+
if (version.prerelease.length > 0 || version.build.length > 0) {
|
|
294
|
+
throw new error_1.FirebaseError(`Cannot combine the --stage flag with a version with a prerelease annotation in extension.yaml.`);
|
|
295
|
+
}
|
|
296
|
+
let extensionVersions = [];
|
|
297
|
+
try {
|
|
298
|
+
extensionVersions = await (0, extensionsApi_1.listExtensionVersions)(ref, `id="${version.version}"`, true);
|
|
299
|
+
}
|
|
300
|
+
catch (e) {
|
|
301
|
+
}
|
|
302
|
+
const latestVersion = (_a = extensionVersions
|
|
303
|
+
.map((version) => semver.parse(version.spec.version))
|
|
304
|
+
.filter((version) => version.prerelease.length > 0 && version.prerelease[0] === stage)
|
|
305
|
+
.sort((v1, v2) => semver.compare(v1, v2))
|
|
306
|
+
.pop()) !== null && _a !== void 0 ? _a : `${version}-${stage}`;
|
|
307
|
+
return semver.inc(latestVersion, "prerelease", undefined, stage);
|
|
308
|
+
}
|
|
309
|
+
return extensionVersion;
|
|
310
|
+
}
|
|
311
|
+
exports.incrementPrereleaseVersion = incrementPrereleaseVersion;
|
|
285
312
|
async function publishExtensionVersionFromLocalSource(args) {
|
|
286
313
|
const extensionSpec = await (0, localHelper_1.getLocalExtensionSpec)(args.rootDirectory);
|
|
287
314
|
if (extensionSpec.name !== args.extensionId) {
|
|
@@ -290,6 +317,7 @@ async function publishExtensionVersionFromLocalSource(args) {
|
|
|
290
317
|
const subbedSpec = JSON.parse(JSON.stringify(extensionSpec));
|
|
291
318
|
subbedSpec.params = substituteParams(extensionSpec.params || [], exports.AUTOPOULATED_PARAM_PLACEHOLDERS);
|
|
292
319
|
validateSpec(subbedSpec);
|
|
320
|
+
extensionSpec.version = await incrementPrereleaseVersion(`${args.publisherId}/${args.extensionId}`, extensionSpec.version, args.stage);
|
|
293
321
|
let extension;
|
|
294
322
|
try {
|
|
295
323
|
extension = await (0, extensionsApi_1.getExtension)(`${args.publisherId}/${args.extensionId}`);
|
package/lib/serve/index.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.serve = void 0;
|
|
|
4
4
|
const logger_1 = require("../logger");
|
|
5
5
|
const frameworks_1 = require("../frameworks");
|
|
6
6
|
const previews_1 = require("../previews");
|
|
7
|
+
const track_1 = require("../track");
|
|
8
|
+
const projectUtils_1 = require("../projectUtils");
|
|
9
|
+
const constants_1 = require("../emulator/constants");
|
|
7
10
|
const { FunctionsServer } = require("./functions");
|
|
8
11
|
const TARGETS = {
|
|
9
12
|
hosting: require("./hosting"),
|
|
@@ -17,12 +20,24 @@ async function serve(options) {
|
|
|
17
20
|
[].concat(options.config.get("hosting")).some((it) => it.source)) {
|
|
18
21
|
await (0, frameworks_1.prepareFrameworks)(targetNames, options, options);
|
|
19
22
|
}
|
|
23
|
+
const isDemoProject = constants_1.Constants.isDemoProject((0, projectUtils_1.getProjectId)(options) || "");
|
|
24
|
+
targetNames.forEach((targetName) => {
|
|
25
|
+
void (0, track_1.trackEmulator)("emulator_run", {
|
|
26
|
+
emulator_name: targetName,
|
|
27
|
+
is_demo_project: String(isDemoProject),
|
|
28
|
+
});
|
|
29
|
+
});
|
|
20
30
|
await Promise.all(targetNames.map((targetName) => {
|
|
21
31
|
return TARGETS[targetName].start(options);
|
|
22
32
|
}));
|
|
23
33
|
await Promise.all(targetNames.map((targetName) => {
|
|
24
34
|
return TARGETS[targetName].connect();
|
|
25
35
|
}));
|
|
36
|
+
void (0, track_1.trackEmulator)("emulators_started", {
|
|
37
|
+
count: targetNames.length,
|
|
38
|
+
count_all: targetNames.length,
|
|
39
|
+
is_demo_project: String(isDemoProject),
|
|
40
|
+
});
|
|
26
41
|
await new Promise((resolve) => {
|
|
27
42
|
process.on("SIGINT", () => {
|
|
28
43
|
logger_1.logger.info("Shutting down...");
|
package/lib/track.js
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.track = void 0;
|
|
3
|
+
exports.emulatorSession = exports.trackEmulator = exports.track = exports.usageEnabled = exports.EMULATOR_GA4_MEASUREMENT_ID = void 0;
|
|
4
|
+
const node_fetch_1 = require("node-fetch");
|
|
4
5
|
const ua = require("universal-analytics");
|
|
5
6
|
const uuid_1 = require("uuid");
|
|
7
|
+
const auth_1 = require("./auth");
|
|
6
8
|
const configstore_1 = require("./configstore");
|
|
9
|
+
const logger_1 = require("./logger");
|
|
7
10
|
const pkg = require("../package.json");
|
|
11
|
+
exports.EMULATOR_GA4_MEASUREMENT_ID = process.env.FIREBASE_EMULATOR_GA4_MEASUREMENT_ID || "G-KYP2JMPFC0";
|
|
12
|
+
function usageEnabled() {
|
|
13
|
+
return !!configstore_1.configstore.get("usage");
|
|
14
|
+
}
|
|
15
|
+
exports.usageEnabled = usageEnabled;
|
|
16
|
+
const FIREBASE_ANALYTICS_UA = process.env.FIREBASE_ANALYTICS_UA || "UA-29174744-3";
|
|
8
17
|
let anonId = configstore_1.configstore.get("analytics-uuid");
|
|
9
18
|
if (!anonId) {
|
|
10
19
|
anonId = (0, uuid_1.v4)();
|
|
11
20
|
configstore_1.configstore.set("analytics-uuid", anonId);
|
|
12
21
|
}
|
|
13
|
-
const visitor = ua(
|
|
22
|
+
const visitor = ua(FIREBASE_ANALYTICS_UA, anonId, {
|
|
14
23
|
strictCidFormat: false,
|
|
15
24
|
https: true,
|
|
16
25
|
});
|
|
@@ -19,7 +28,7 @@ visitor.set("cd2", process.version);
|
|
|
19
28
|
visitor.set("cd3", process.env.FIREPIT_VERSION || "none");
|
|
20
29
|
function track(action, label, duration = 0) {
|
|
21
30
|
return new Promise((resolve) => {
|
|
22
|
-
if (configstore_1.configstore.get("tokens") &&
|
|
31
|
+
if (configstore_1.configstore.get("tokens") && usageEnabled()) {
|
|
23
32
|
visitor.event("Firebase CLI " + pkg.version, action, label, duration).send(() => {
|
|
24
33
|
resolve();
|
|
25
34
|
});
|
|
@@ -30,3 +39,110 @@ function track(action, label, duration = 0) {
|
|
|
30
39
|
});
|
|
31
40
|
}
|
|
32
41
|
exports.track = track;
|
|
42
|
+
const EMULATOR_GA4_API_SECRET = process.env.FIREBASE_EMULATOR_GA4_API_SECRET || "2V_zBYc4TdeoppzDaIu0zw";
|
|
43
|
+
const EMULATOR_GA4_USER_PROPS = {
|
|
44
|
+
node_platform: {
|
|
45
|
+
value: process.platform,
|
|
46
|
+
},
|
|
47
|
+
node_version: {
|
|
48
|
+
value: process.version,
|
|
49
|
+
},
|
|
50
|
+
firepit_version: {
|
|
51
|
+
value: process.env.FIREPIT_VERSION || "none",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
async function trackEmulator(eventName, params) {
|
|
55
|
+
const session = emulatorSession();
|
|
56
|
+
if (!session) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const oldTotalEngagementSeconds = session.totalEngagementSeconds;
|
|
60
|
+
session.totalEngagementSeconds = process.uptime();
|
|
61
|
+
session.commandName = (params === null || params === void 0 ? void 0 : params.command_name) || session.commandName;
|
|
62
|
+
const search = `?api_secret=${EMULATOR_GA4_API_SECRET}&measurement_id=${session.measurementId}`;
|
|
63
|
+
const validate = session.validateOnly ? "debug/" : "";
|
|
64
|
+
const url = `https://www.google-analytics.com/${validate}mp/collect${search}`;
|
|
65
|
+
const body = {
|
|
66
|
+
timestamp_micros: `${Date.now()}000`,
|
|
67
|
+
client_id: session.clientId,
|
|
68
|
+
user_properties: Object.assign(Object.assign({}, EMULATOR_GA4_USER_PROPS), { java_major_version: session.javaMajorVersion
|
|
69
|
+
? { value: session.javaMajorVersion }
|
|
70
|
+
: undefined }),
|
|
71
|
+
validationBehavior: session.validateOnly ? "ENFORCE_RECOMMENDATIONS" : undefined,
|
|
72
|
+
events: [
|
|
73
|
+
{
|
|
74
|
+
name: eventName,
|
|
75
|
+
params: Object.assign({ session_id: session.sessionId, engagement_time_msec: (session.totalEngagementSeconds - oldTotalEngagementSeconds)
|
|
76
|
+
.toFixed(3)
|
|
77
|
+
.replace(".", "")
|
|
78
|
+
.replace(/^0+/, ""), debug_mode: session.debugMode ? true : undefined, command_name: session.commandName }, params),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
if (session.validateOnly) {
|
|
83
|
+
logger_1.logger.info(`Sending Analytics for event ${eventName}`, params, body);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {
|
|
89
|
+
"content-type": "application/json;charset=UTF-8",
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify(body),
|
|
92
|
+
});
|
|
93
|
+
if (session.validateOnly) {
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
logger_1.logger.warn(`Analytics validation HTTP error: ${response.status}`);
|
|
96
|
+
}
|
|
97
|
+
const respBody = await response.text();
|
|
98
|
+
logger_1.logger.info(`Analytics validation result: ${respBody}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (session.validateOnly) {
|
|
103
|
+
throw e;
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.trackEmulator = trackEmulator;
|
|
109
|
+
function emulatorSession() {
|
|
110
|
+
const validateOnly = !!process.env.FIREBASE_CLI_MP_VALIDATE;
|
|
111
|
+
if (!usageEnabled()) {
|
|
112
|
+
if (validateOnly) {
|
|
113
|
+
logger_1.logger.warn("Google Analytics is DISABLED. To enable, (re)login and opt in to collection.");
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (!currentEmulatorSession) {
|
|
118
|
+
let clientId = configstore_1.configstore.get("emulator-analytics-clientId");
|
|
119
|
+
if (!clientId) {
|
|
120
|
+
clientId = (0, uuid_1.v4)();
|
|
121
|
+
configstore_1.configstore.set("emulator-analytics-clientId", clientId);
|
|
122
|
+
}
|
|
123
|
+
currentEmulatorSession = {
|
|
124
|
+
measurementId: exports.EMULATOR_GA4_MEASUREMENT_ID,
|
|
125
|
+
clientId,
|
|
126
|
+
sessionId: (Math.random() * Number.MAX_SAFE_INTEGER).toFixed(0),
|
|
127
|
+
totalEngagementSeconds: 0,
|
|
128
|
+
debugMode: isDebugMode(),
|
|
129
|
+
validateOnly,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return currentEmulatorSession;
|
|
133
|
+
}
|
|
134
|
+
exports.emulatorSession = emulatorSession;
|
|
135
|
+
let currentEmulatorSession = undefined;
|
|
136
|
+
function isDebugMode() {
|
|
137
|
+
const account = (0, auth_1.getGlobalDefaultAccount)();
|
|
138
|
+
if (account === null || account === void 0 ? void 0 : account.user.email.endsWith("@google.com")) {
|
|
139
|
+
try {
|
|
140
|
+
require("../tsconfig.json");
|
|
141
|
+
logger_1.logger.info(`Using Google Analytics in DEBUG mode. Emulators (+ UI) events will be shown in GA Debug View only.`);
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
catch (_a) {
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
package/lib/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.assertDefined = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
|
|
3
|
+
exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.assertDefined = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const url = require("url");
|
|
6
6
|
const clc = require("colorette");
|
|
@@ -248,6 +248,19 @@ async function promiseWhile(action, check, interval = 2500) {
|
|
|
248
248
|
});
|
|
249
249
|
}
|
|
250
250
|
exports.promiseWhile = promiseWhile;
|
|
251
|
+
function withTimeout(timeoutMs, promise) {
|
|
252
|
+
return new Promise((resolve, reject) => {
|
|
253
|
+
const timeout = setTimeout(() => reject(new Error("Timed out.")), timeoutMs);
|
|
254
|
+
promise.then((value) => {
|
|
255
|
+
clearTimeout(timeout);
|
|
256
|
+
resolve(value);
|
|
257
|
+
}, (err) => {
|
|
258
|
+
clearTimeout(timeout);
|
|
259
|
+
reject(err);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
exports.withTimeout = withTimeout;
|
|
251
264
|
async function promiseProps(obj) {
|
|
252
265
|
const resultObj = {};
|
|
253
266
|
const promises = Object.keys(obj).map(async (key) => {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-tools",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.6.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "firebase-tools",
|
|
9
|
-
"version": "11.
|
|
9
|
+
"version": "11.6.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@google-cloud/pubsub": "^3.0.1",
|
package/package.json
CHANGED
|
@@ -174,6 +174,18 @@
|
|
|
174
174
|
},
|
|
175
175
|
"type": "object"
|
|
176
176
|
},
|
|
177
|
+
"eventarc": {
|
|
178
|
+
"additionalProperties": false,
|
|
179
|
+
"properties": {
|
|
180
|
+
"host": {
|
|
181
|
+
"type": "string"
|
|
182
|
+
},
|
|
183
|
+
"port": {
|
|
184
|
+
"type": "number"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"type": "object"
|
|
188
|
+
},
|
|
177
189
|
"extensions": {
|
|
178
190
|
"properties": {
|
|
179
191
|
},
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
|
|
2
|
-
When you release a new version, add a new header and release notes for that version.
|
|
3
|
-
When users update their instance, they will see the release notes for all versions
|
|
4
|
-
between the one they were on and the one they are updating to.
|
|
5
|
-
|
|
6
|
-
## Version 0.0.1
|
|
7
|
-
First version
|
|
1
|
+
- Added support for publishing pre-release Extension versions. (#4804)
|