firebase-tools 14.23.0 → 14.24.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/appUtils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.detectFiles = exports.extractAppIdentifiersAndroid = exports.extractAppIdentifierIos = exports.extractAppIdentifiersFlutter = exports.detectApps = exports.getPlatformsFromFolder = exports.appDescription = exports.Framework = exports.Platform = void 0;
3
+ exports.detectFiles = exports.extractAppIdentifiersAndroid = exports.extractAppIdentifierIos = exports.extractAppIdentifiersFlutter = exports.getAllDepsFromPackageJson = exports.detectApps = exports.getPlatformsFromFolder = exports.appDescription = exports.Framework = exports.Platform = void 0;
4
4
  const fs = require("fs-extra");
5
5
  const path = require("path");
6
6
  const glob_1 = require("glob");
@@ -10,6 +10,7 @@ var Platform;
10
10
  Platform["WEB"] = "WEB";
11
11
  Platform["IOS"] = "IOS";
12
12
  Platform["FLUTTER"] = "FLUTTER";
13
+ Platform["ADMIN_NODE"] = "ADMIN_NODE";
13
14
  })(Platform = exports.Platform || (exports.Platform = {}));
14
15
  var Framework;
15
16
  (function (Framework) {
@@ -30,7 +31,9 @@ async function detectApps(dirPath) {
30
31
  const pubSpecYamlFiles = await detectFiles(dirPath, "pubspec.yaml");
31
32
  const srcMainFolders = await detectFiles(dirPath, "src/main/");
32
33
  const xCodeProjects = await detectFiles(dirPath, "*.xcodeproj/");
33
- const webApps = await Promise.all(packageJsonFiles.map((p) => packageJsonToWebApp(dirPath, p)));
34
+ const adminAndWebApps = (await Promise.all(packageJsonFiles.map((p) => packageJsonToAdminOrWebApp(dirPath, p)))).flat();
35
+ console.log("packageJsonFiles", packageJsonFiles);
36
+ console.log("adminAndWebApps", adminAndWebApps);
34
37
  const flutterAppPromises = await Promise.all(pubSpecYamlFiles.map((f) => processFlutterDir(dirPath, f)));
35
38
  const flutterApps = flutterAppPromises.flat();
36
39
  const androidAppPromises = await Promise.all(srcMainFolders.map((f) => processAndroidDir(dirPath, f)));
@@ -41,7 +44,7 @@ async function detectApps(dirPath) {
41
44
  const iosApps = iosAppPromises
42
45
  .flat()
43
46
  .filter((a) => !flutterApps.some((f) => isPathInside(f.directory, a.directory)));
44
- return [...webApps, ...flutterApps, ...androidApps, ...iosApps];
47
+ return [...flutterApps, ...androidApps, ...iosApps, ...adminAndWebApps];
45
48
  }
46
49
  exports.detectApps = detectApps;
47
50
  async function processIosDir(dirPath, filePath) {
@@ -108,14 +111,33 @@ function isPathInside(parent, child) {
108
111
  const relativePath = path.relative(parent, child);
109
112
  return !relativePath.startsWith(`..`);
110
113
  }
111
- async function packageJsonToWebApp(dirPath, packageJsonFile) {
114
+ function getAllDepsFromPackageJson(packageJson) {
115
+ var _a, _b;
116
+ const devDependencies = Object.keys((_a = packageJson.devDependencies) !== null && _a !== void 0 ? _a : {});
117
+ const dependencies = Object.keys((_b = packageJson.dependencies) !== null && _b !== void 0 ? _b : {});
118
+ const allDeps = Array.from(new Set([...devDependencies, ...dependencies]));
119
+ return allDeps;
120
+ }
121
+ exports.getAllDepsFromPackageJson = getAllDepsFromPackageJson;
122
+ async function packageJsonToAdminOrWebApp(dirPath, packageJsonFile) {
112
123
  const fullPath = path.join(dirPath, packageJsonFile);
113
124
  const packageJson = JSON.parse((await fs.readFile(fullPath)).toString());
114
- return {
115
- platform: Platform.WEB,
116
- directory: path.dirname(packageJsonFile),
117
- frameworks: getFrameworksFromPackageJson(packageJson),
118
- };
125
+ const allDeps = getAllDepsFromPackageJson(packageJson);
126
+ const detectedApps = [];
127
+ if (allDeps.includes("firebase-admin") || allDeps.includes("firebase-functions")) {
128
+ detectedApps.push({
129
+ platform: Platform.ADMIN_NODE,
130
+ directory: path.dirname(packageJsonFile),
131
+ });
132
+ }
133
+ if (allDeps.includes("firebase") || detectedApps.length === 0) {
134
+ detectedApps.push({
135
+ platform: Platform.WEB,
136
+ directory: path.dirname(packageJsonFile),
137
+ frameworks: getFrameworksFromPackageJson(packageJson),
138
+ });
139
+ }
140
+ return detectedApps;
119
141
  }
120
142
  const WEB_FRAMEWORKS = Object.values(Framework);
121
143
  const WEB_FRAMEWORKS_SIGNALS = {
@@ -148,10 +170,7 @@ async function detectAppIdsForPlatform(dirPath, platform) {
148
170
  return allAppIds.flat();
149
171
  }
150
172
  function getFrameworksFromPackageJson(packageJson) {
151
- var _a, _b;
152
- const devDependencies = Object.keys((_a = packageJson.devDependencies) !== null && _a !== void 0 ? _a : {});
153
- const dependencies = Object.keys((_b = packageJson.dependencies) !== null && _b !== void 0 ? _b : {});
154
- const allDeps = Array.from(new Set([...devDependencies, ...dependencies]));
173
+ const allDeps = getAllDepsFromPackageJson(packageJson);
155
174
  return WEB_FRAMEWORKS.filter((framework) => WEB_FRAMEWORKS_SIGNALS[framework].find((dep) => allDeps.includes(dep)));
156
175
  }
157
176
  function extractAppIdentifiersFlutter(fileContent) {
@@ -72,11 +72,12 @@ exports.command = new command_1.Command("dataconnect:sdk:generate")
72
72
  async function loadAllWithSDKs(projectId, config) {
73
73
  const serviceInfos = await (0, load_1.loadAll)(projectId || hub_1.EmulatorHub.MISSING_PROJECT_PLACEHOLDER, config);
74
74
  return serviceInfos.filter((serviceInfo) => serviceInfo.connectorInfo.some((c) => {
75
- var _a, _b, _c, _d;
75
+ var _a, _b, _c, _d, _e;
76
76
  return (((_a = c.connectorYaml.generate) === null || _a === void 0 ? void 0 : _a.javascriptSdk) ||
77
77
  ((_b = c.connectorYaml.generate) === null || _b === void 0 ? void 0 : _b.kotlinSdk) ||
78
78
  ((_c = c.connectorYaml.generate) === null || _c === void 0 ? void 0 : _c.swiftSdk) ||
79
- ((_d = c.connectorYaml.generate) === null || _d === void 0 ? void 0 : _d.dartSdk));
79
+ ((_d = c.connectorYaml.generate) === null || _d === void 0 ? void 0 : _d.dartSdk) ||
80
+ ((_e = c.connectorYaml.generate) === null || _e === void 0 ? void 0 : _e.adminNodeSdk));
80
81
  }));
81
82
  }
82
83
  async function generateSDKsInAll(options, serviceInfosWithSDKs, justRanInit) {
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureDataConnectTriggerRegion = void 0;
4
+ const error_1 = require("../../../error");
5
+ function ensureDataConnectTriggerRegion(endpoint) {
6
+ if (!endpoint.eventTrigger.region) {
7
+ endpoint.eventTrigger.region = endpoint.region;
8
+ }
9
+ if (endpoint.eventTrigger.region !== endpoint.region) {
10
+ throw new error_1.FirebaseError("The Firebase Data Connect trigger location must match the function region.");
11
+ }
12
+ return Promise.resolve();
13
+ }
14
+ exports.ensureDataConnectTriggerRegion = ensureDataConnectTriggerRegion;
@@ -9,6 +9,7 @@ const database_1 = require("./database");
9
9
  const remoteConfig_1 = require("./remoteConfig");
10
10
  const testLab_1 = require("./testLab");
11
11
  const firestore_1 = require("./firestore");
12
+ const dataconnect_1 = require("./dataconnect");
12
13
  const noop = () => Promise.resolve();
13
14
  exports.noop = noop;
14
15
  const noopProjectBindings = () => Promise.resolve([]);
@@ -85,6 +86,15 @@ const firestoreService = {
85
86
  registerTrigger: exports.noop,
86
87
  unregisterTrigger: exports.noop,
87
88
  };
89
+ const dataconnectService = {
90
+ name: "dataconnect",
91
+ api: "firebasedataconnect.googleapis.com",
92
+ requiredProjectBindings: exports.noopProjectBindings,
93
+ ensureTriggerRegion: dataconnect_1.ensureDataConnectTriggerRegion,
94
+ validateTrigger: exports.noop,
95
+ registerTrigger: exports.noop,
96
+ unregisterTrigger: exports.noop,
97
+ };
88
98
  const EVENT_SERVICE_MAPPING = {
89
99
  "google.cloud.pubsub.topic.v1.messagePublished": pubSubService,
90
100
  "google.cloud.storage.object.v1.finalized": storageService,
@@ -110,6 +120,7 @@ const EVENT_SERVICE_MAPPING = {
110
120
  "google.cloud.firestore.document.v1.created.withAuthContext": firestoreService,
111
121
  "google.cloud.firestore.document.v1.updated.withAuthContext": firestoreService,
112
122
  "google.cloud.firestore.document.v1.deleted.withAuthContext": firestoreService,
123
+ "google.firebase.dataconnect.connector.v1.mutationExecuted": dataconnectService,
113
124
  };
114
125
  function serviceForEndpoint(endpoint) {
115
126
  if (backend.isEventTriggered(endpoint)) {
@@ -54,28 +54,36 @@
54
54
  },
55
55
  "dataconnect": {
56
56
  "darwin": {
57
- "version": "2.16.0",
58
- "expectedSize": 29963104,
59
- "expectedChecksum": "ee4d81abfba3576c7c6c8082313acfd0",
60
- "expectedChecksumSHA256": "8aed1dc6cc8c35ab23fdf10e519e9cf3d93c8a0ccb0ff7d5af3ddc41a4847e3e",
61
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v2.16.0",
62
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.16.0"
57
+ "version": "2.17.0",
58
+ "expectedSize": 29983584,
59
+ "expectedChecksum": "d9a3a5bd575dc24185ad473a440c4738",
60
+ "expectedChecksumSHA256": "da5485e68c7adbf86e3fb2f9ca550e4619f55ae75845009837780fcf16dd05cc",
61
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v2.17.0",
62
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.17.0"
63
+ },
64
+ "darwin_arm64": {
65
+ "version": "2.17.0",
66
+ "expectedSize": 29459746,
67
+ "expectedChecksum": "8362a56419a66507b1aead4630b9033c",
68
+ "expectedChecksumSHA256": "cbb8a3030f69c5aba81d1ef2d64d249f18100915f9738f59b815004b27983dab",
69
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v2.17.0",
70
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.17.0"
63
71
  },
64
72
  "win32": {
65
- "version": "2.16.0",
66
- "expectedSize": 30456320,
67
- "expectedChecksum": "546019a713be28620a3b43d49fc9d4b0",
68
- "expectedChecksumSHA256": "ec1de720e173f0a613fbbb51767c0288121aa2f80e45e6bad0f3d2aff12689ec",
69
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v2.16.0",
70
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.16.0.exe"
73
+ "version": "2.17.0",
74
+ "expectedSize": 30477824,
75
+ "expectedChecksum": "7d8434eee4f3d33cc8ec6c99c6056a77",
76
+ "expectedChecksumSHA256": "051c60be0651be4971409da7ab3a15cdfb693400e9293c89010edcb28016d061",
77
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v2.17.0",
78
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.17.0.exe"
71
79
  },
72
80
  "linux": {
73
- "version": "2.16.0",
74
- "expectedSize": 29888696,
75
- "expectedChecksum": "5ab8da956043a48b43199f07b94ac48c",
76
- "expectedChecksumSHA256": "1a420f3d2672627eae2d9b0b6747b833517cfc08f7e80ae3a79389788691b67a",
77
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v2.16.0",
78
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.16.0"
81
+ "version": "2.17.0",
82
+ "expectedSize": 29905080,
83
+ "expectedChecksum": "ca7003aaee41e3c1261f9655c5f9dd8a",
84
+ "expectedChecksumSHA256": "79efd09f1bd685cbfa0157b2d08e0f6eb085ed82d83b48fabb7d102db6636c6c",
85
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v2.17.0",
86
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-2.17.0"
79
87
  }
80
88
  }
81
89
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isIncomaptibleArchError = exports.start = exports.downloadIfNecessary = exports.stop = exports.getPID = exports.get = exports.getDownloadDetails = exports.requiresJava = exports.handleEmulatorProcessError = exports._getCommand = exports.getLogFileName = exports.DownloadDetails = void 0;
3
+ exports.isIncomaptibleArchError = exports.start = exports.downloadIfNecessary = exports.stop = exports.getPID = exports.get = exports.getDownloadDetails = exports.requiresJava = exports.handleEmulatorProcessError = exports._getCommand = exports.getLogFileName = void 0;
4
4
  const lsofi = require("lsofi");
5
5
  const types_1 = require("./types");
6
6
  const constants_1 = require("./constants");
@@ -20,51 +20,63 @@ const emulatorUpdateDetails = require("./downloadableEmulatorInfo.json");
20
20
  const EMULATOR_INSTANCE_KILL_TIMEOUT = 4000;
21
21
  const CACHE_DIR = process.env.FIREBASE_EMULATORS_PATH || path.join(os.homedir(), ".cache", "firebase", "emulators");
22
22
  const EMULATOR_UPDATE_DETAILS = emulatorUpdateDetails;
23
- const emulatorUiDetails = experiments.isEnabled("emulatoruisnapshot")
24
- ? EMULATOR_UPDATE_DETAILS.ui.snapshot
25
- : EMULATOR_UPDATE_DETAILS.ui.main;
26
- const dataconnectDetails = process.platform === "darwin"
27
- ? EMULATOR_UPDATE_DETAILS.dataconnect.darwin
28
- : process.platform === "win32"
29
- ? EMULATOR_UPDATE_DETAILS.dataconnect.win32
30
- : EMULATOR_UPDATE_DETAILS.dataconnect.linux;
31
- exports.DownloadDetails = {
32
- database: {
33
- downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.database.downloadPathRelativeToCacheDir),
34
- version: EMULATOR_UPDATE_DETAILS.database.version,
35
- opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.database), { cacheDir: CACHE_DIR, namePrefix: "firebase-database-emulator" }),
36
- },
37
- firestore: {
38
- downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.firestore.downloadPathRelativeToCacheDir),
39
- version: EMULATOR_UPDATE_DETAILS.firestore.version,
40
- opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.firestore), { cacheDir: CACHE_DIR, namePrefix: "cloud-firestore-emulator" }),
41
- },
42
- storage: {
43
- downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.storage.downloadPathRelativeToCacheDir),
44
- version: EMULATOR_UPDATE_DETAILS.storage.version,
45
- opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.storage), { cacheDir: CACHE_DIR, namePrefix: "cloud-storage-rules-emulator" }),
46
- },
47
- ui: {
48
- version: emulatorUiDetails.version,
49
- downloadPath: path.join(CACHE_DIR, emulatorUiDetails.downloadPathRelativeToCacheDir),
50
- unzipDir: path.join(CACHE_DIR, `ui-v${emulatorUiDetails.version}`),
51
- binaryPath: path.join(CACHE_DIR, emulatorUiDetails.binaryPathRelativeToCacheDir),
52
- opts: Object.assign(Object.assign({}, emulatorUiDetails), { cacheDir: CACHE_DIR, skipCache: experiments.isEnabled("emulatoruisnapshot"), skipChecksumAndSize: experiments.isEnabled("emulatoruisnapshot"), namePrefix: "ui" }),
53
- },
54
- pubsub: {
55
- downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.pubsub.downloadPathRelativeToCacheDir),
56
- version: EMULATOR_UPDATE_DETAILS.pubsub.version,
57
- unzipDir: path.join(CACHE_DIR, `pubsub-emulator-${EMULATOR_UPDATE_DETAILS.pubsub.version}`),
58
- binaryPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.pubsub.binaryPathRelativeToCacheDir),
59
- opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.pubsub), { cacheDir: CACHE_DIR, namePrefix: "pubsub-emulator" }),
60
- },
61
- dataconnect: {
62
- downloadPath: path.join(CACHE_DIR, dataconnectDetails.downloadPathRelativeToCacheDir),
63
- version: dataconnectDetails.version,
64
- binaryPath: path.join(CACHE_DIR, dataconnectDetails.downloadPathRelativeToCacheDir),
65
- opts: Object.assign(Object.assign({}, dataconnectDetails), { cacheDir: CACHE_DIR, skipChecksumAndSize: false, namePrefix: "dataconnect-emulator", auth: false }),
66
- },
67
- };
23
+ function generateDownloadDetails(emulator) {
24
+ const emulatorUiDetails = experiments.isEnabled("emulatoruisnapshot")
25
+ ? EMULATOR_UPDATE_DETAILS.ui.snapshot
26
+ : EMULATOR_UPDATE_DETAILS.ui.main;
27
+ const dataconnectDetails = process.platform === "darwin"
28
+ ? process.arch === "arm64"
29
+ ? EMULATOR_UPDATE_DETAILS.dataconnect.darwin_arm64
30
+ : EMULATOR_UPDATE_DETAILS.dataconnect.darwin
31
+ : process.platform === "win32"
32
+ ? EMULATOR_UPDATE_DETAILS.dataconnect.win32
33
+ : EMULATOR_UPDATE_DETAILS.dataconnect.linux;
34
+ switch (emulator) {
35
+ case "database":
36
+ return {
37
+ downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.database.downloadPathRelativeToCacheDir),
38
+ version: EMULATOR_UPDATE_DETAILS.database.version,
39
+ opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.database), { cacheDir: CACHE_DIR, namePrefix: "firebase-database-emulator" }),
40
+ };
41
+ case "firestore":
42
+ return {
43
+ downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.firestore.downloadPathRelativeToCacheDir),
44
+ version: EMULATOR_UPDATE_DETAILS.firestore.version,
45
+ opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.firestore), { cacheDir: CACHE_DIR, namePrefix: "cloud-firestore-emulator" }),
46
+ };
47
+ case "storage":
48
+ return {
49
+ downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.storage.downloadPathRelativeToCacheDir),
50
+ version: EMULATOR_UPDATE_DETAILS.storage.version,
51
+ opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.storage), { cacheDir: CACHE_DIR, namePrefix: "cloud-storage-rules-emulator" }),
52
+ };
53
+ case "ui":
54
+ return {
55
+ version: emulatorUiDetails.version,
56
+ downloadPath: path.join(CACHE_DIR, emulatorUiDetails.downloadPathRelativeToCacheDir),
57
+ unzipDir: path.join(CACHE_DIR, `ui-v${emulatorUiDetails.version}`),
58
+ binaryPath: path.join(CACHE_DIR, emulatorUiDetails.binaryPathRelativeToCacheDir),
59
+ opts: Object.assign(Object.assign({}, emulatorUiDetails), { cacheDir: CACHE_DIR, skipCache: experiments.isEnabled("emulatoruisnapshot"), skipChecksumAndSize: experiments.isEnabled("emulatoruisnapshot"), namePrefix: "ui" }),
60
+ };
61
+ case "pubsub":
62
+ return {
63
+ downloadPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.pubsub.downloadPathRelativeToCacheDir),
64
+ version: EMULATOR_UPDATE_DETAILS.pubsub.version,
65
+ unzipDir: path.join(CACHE_DIR, `pubsub-emulator-${EMULATOR_UPDATE_DETAILS.pubsub.version}`),
66
+ binaryPath: path.join(CACHE_DIR, EMULATOR_UPDATE_DETAILS.pubsub.binaryPathRelativeToCacheDir),
67
+ opts: Object.assign(Object.assign({}, EMULATOR_UPDATE_DETAILS.pubsub), { cacheDir: CACHE_DIR, namePrefix: "pubsub-emulator" }),
68
+ };
69
+ case "dataconnect":
70
+ return {
71
+ downloadPath: path.join(CACHE_DIR, dataconnectDetails.downloadPathRelativeToCacheDir),
72
+ version: dataconnectDetails.version,
73
+ binaryPath: path.join(CACHE_DIR, dataconnectDetails.downloadPathRelativeToCacheDir),
74
+ opts: Object.assign(Object.assign({}, dataconnectDetails), { cacheDir: CACHE_DIR, skipChecksumAndSize: false, namePrefix: "dataconnect-emulator", auth: false }),
75
+ };
76
+ default:
77
+ throw new Error(`Invalid downloadable emulator: ${emulator}`);
78
+ }
79
+ }
68
80
  const EmulatorDetails = {
69
81
  database: {
70
82
  name: types_1.Emulators.DATABASE,
@@ -318,7 +330,7 @@ async function _runBinary(emulator, command, extraEnv) {
318
330
  });
319
331
  }
320
332
  function getDownloadDetails(emulator) {
321
- const details = exports.DownloadDetails[emulator];
333
+ const details = generateDownloadDetails(emulator);
322
334
  const pathOverride = process.env[`${emulator.toUpperCase()}_EMULATOR_BINARY_PATH`];
323
335
  if (pathOverride) {
324
336
  const logger = emulatorLogger_1.EmulatorLogger.forEmulator(emulator);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONVERTABLE_EVENTS = exports.FIREALERTS_EVENT = exports.FIRESTORE_EVENTS = exports.TEST_LAB_EVENT = exports.REMOTE_CONFIG_EVENT = exports.DATABASE_EVENTS = exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
3
+ exports.CONVERTABLE_EVENTS = exports.DATACONNECT_EVENT = exports.FIREALERTS_EVENT = exports.FIRESTORE_EVENTS = exports.TEST_LAB_EVENT = exports.REMOTE_CONFIG_EVENT = exports.DATABASE_EVENTS = exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
4
4
  exports.PUBSUB_PUBLISH_EVENT = "google.cloud.pubsub.topic.v1.messagePublished";
5
5
  exports.STORAGE_EVENTS = [
6
6
  "google.cloud.storage.object.v1.finalized",
@@ -28,6 +28,7 @@ exports.FIRESTORE_EVENTS = [
28
28
  "google.cloud.firestore.document.v1.deleted.withAuthContext",
29
29
  ];
30
30
  exports.FIREALERTS_EVENT = "google.firebase.firebasealerts.alerts.v1.published";
31
+ exports.DATACONNECT_EVENT = "google.firebase.dataconnect.connector.v1.mutationExecuted";
31
32
  exports.CONVERTABLE_EVENTS = {
32
33
  "google.cloud.firestore.document.v1.created": "google.cloud.firestore.document.v1.created.withAuthContext",
33
34
  "google.cloud.firestore.document.v1.updated": "google.cloud.firestore.document.v1.updated.withAuthContext",
@@ -145,9 +145,13 @@ function initAppCounters(info) {
145
145
  num_android_apps: 0,
146
146
  num_ios_apps: 0,
147
147
  num_flutter_apps: 0,
148
+ num_admin_node_apps: 0,
148
149
  };
149
150
  for (const app of (_a = info.apps) !== null && _a !== void 0 ? _a : []) {
150
151
  switch (app.platform) {
152
+ case appUtils_1.Platform.ADMIN_NODE:
153
+ counts.num_admin_node_apps++;
154
+ break;
151
155
  case appUtils_1.Platform.WEB:
152
156
  counts.num_web_apps++;
153
157
  break;
@@ -246,6 +250,20 @@ function addSdkGenerateToConnectorYaml(connectorInfo, connectorYaml, app) {
246
250
  }
247
251
  const generate = connectorYaml.generate;
248
252
  switch (app.platform) {
253
+ case appUtils_1.Platform.ADMIN_NODE: {
254
+ const adminNodeSdk = {
255
+ outputDir: path.relative(connectorDir, path.join(appDir, `src/dataconnect-admin-generated`)),
256
+ package: `@dataconnect/admin-generated`,
257
+ packageJsonDir: path.relative(connectorDir, appDir),
258
+ };
259
+ if (!(0, lodash_1.isArray)(generate === null || generate === void 0 ? void 0 : generate.adminNodeSdk)) {
260
+ generate.adminNodeSdk = generate.adminNodeSdk ? [generate.adminNodeSdk] : [];
261
+ }
262
+ if (!generate.adminNodeSdk.some((s) => s.outputDir === adminNodeSdk.outputDir)) {
263
+ generate.adminNodeSdk.push(adminNodeSdk);
264
+ }
265
+ break;
266
+ }
249
267
  case appUtils_1.Platform.WEB: {
250
268
  const javascriptSdk = {
251
269
  outputDir: path.relative(connectorDir, path.join(appDir, `src/dataconnect-generated`)),
@@ -3,16 +3,93 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.batch_get_events = exports.list_events = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const tool_1 = require("../../tool");
6
+ const js_yaml_1 = require("js-yaml");
6
7
  const events_1 = require("../../../crashlytics/events");
7
8
  const types_1 = require("../../../crashlytics/types");
8
9
  const filters_1 = require("../../../crashlytics/filters");
9
10
  const util_1 = require("../../util");
10
- function pruneThreads(sample) {
11
- var _a, _b, _c;
12
- if (((_a = sample.issue) === null || _a === void 0 ? void 0 : _a.errorType) === types_1.ErrorType.FATAL || ((_b = sample.issue) === null || _b === void 0 ? void 0 : _b.errorType) === types_1.ErrorType.ANR) {
13
- sample.threads = (_c = sample.threads) === null || _c === void 0 ? void 0 : _c.filter((t) => t.crashed || t.blamed);
11
+ const DUMP_OPTIONS = { lineWidth: 200 };
12
+ function formatFrames(origFrames, maxFrames = 20) {
13
+ const frames = origFrames || [];
14
+ const shouldTruncate = frames.length > maxFrames;
15
+ const framesToFormat = shouldTruncate ? frames.slice(0, maxFrames - 1) : frames;
16
+ const formatted = framesToFormat.map((frame) => {
17
+ let line = `at`;
18
+ if (frame.symbol) {
19
+ line += ` ${frame.symbol}`;
20
+ }
21
+ if (frame.file) {
22
+ line += ` (${frame.file}`;
23
+ if (frame.line) {
24
+ line += `:${frame.line}`;
25
+ }
26
+ line += ")";
27
+ }
28
+ return line;
29
+ });
30
+ if (shouldTruncate) {
31
+ formatted.push("... frames omitted ...");
14
32
  }
15
- return sample;
33
+ return formatted;
34
+ }
35
+ function toText(event) {
36
+ var _a, _b;
37
+ const result = {};
38
+ for (const [key, value] of Object.entries(event)) {
39
+ if (key === "logs") {
40
+ const logs = value || [];
41
+ const slicedLogs = logs.length > 100 ? logs.slice(logs.length - 100) : logs;
42
+ const logLines = slicedLogs.map((log) => `[${log.logTime}] ${log.message}`);
43
+ result["logs"] = logLines.join("\n");
44
+ }
45
+ else if (key === "breadcrumbs") {
46
+ const breadcrumbs = value || [];
47
+ const slicedBreadcrumbs = breadcrumbs.length > 10 ? breadcrumbs.slice(-10) : breadcrumbs;
48
+ const breadcrumbLines = slicedBreadcrumbs.map((b) => {
49
+ const paramString = Object.entries(b.params)
50
+ .map(([k, v]) => `${k}: ${v}`)
51
+ .join(", ");
52
+ const params = paramString ? ` { ${paramString} }` : "";
53
+ return `[${b.eventTime}] ${b.title}${params}`;
54
+ });
55
+ result["breadcrumbs"] = breadcrumbLines.join("\n");
56
+ }
57
+ else if (key === "threads") {
58
+ let threads = value || [];
59
+ if (((_a = event.issue) === null || _a === void 0 ? void 0 : _a.errorType) === types_1.ErrorType.FATAL || ((_b = event.issue) === null || _b === void 0 ? void 0 : _b.errorType) === types_1.ErrorType.ANR) {
60
+ threads = threads.filter((t) => t.crashed || t.blamed);
61
+ }
62
+ const threadStrings = threads.map((thread) => {
63
+ const header = `Thread: ${thread.name || thread.threadId || ""}${thread.crashed ? " (crashed)" : ""}`;
64
+ const frameStrings = formatFrames(thread.frames || []);
65
+ return [header, ...frameStrings].join("\n");
66
+ });
67
+ result["threads"] = threadStrings.join("\n\n");
68
+ }
69
+ else if (key === "exceptions") {
70
+ const exceptions = value || [];
71
+ const exceptionStrings = exceptions.map((exception) => {
72
+ const header = exception.nested ? "Caused by: " : "";
73
+ const exceptionHeader = `${header}${exception.type || ""}: ${exception.exceptionMessage || ""}`;
74
+ const frameStrings = formatFrames(exception.frames || []);
75
+ return [exceptionHeader, ...frameStrings].join("\n");
76
+ });
77
+ result["exceptions"] = exceptionStrings.join("\n\n");
78
+ }
79
+ else if (key === "errors") {
80
+ const errors = value || [];
81
+ const errorStrings = errors.map((error) => {
82
+ const header = `Error: ${error.title || "error"}`;
83
+ const frameStrings = formatFrames(error.frames || []);
84
+ return [header, ...frameStrings].join("\n");
85
+ });
86
+ result["errors"] = errorStrings.join("\n\n");
87
+ }
88
+ else {
89
+ result[key] = (0, js_yaml_1.dump)(value, DUMP_OPTIONS);
90
+ }
91
+ }
92
+ return result;
16
93
  }
17
94
  exports.list_events = (0, tool_1.tool)("crashlytics", {
18
95
  name: "list_events",
@@ -32,13 +109,16 @@ exports.list_events = (0, tool_1.tool)("crashlytics", {
32
109
  requiresAuth: true,
33
110
  },
34
111
  }, async ({ appId, filter, pageSize }) => {
112
+ var _a;
35
113
  if (!appId)
36
114
  return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
37
115
  if (!filter || (!filter.issueId && !filter.issueVariantId))
38
116
  return (0, util_1.mcpError)(`Must specify 'filter.issueId' or 'filter.issueVariantId' parameters.`);
39
117
  const response = await (0, events_1.listEvents)(appId, filter, pageSize);
40
- response.events = response.events ? response.events.map((e) => pruneThreads(e)) : [];
41
- return (0, util_1.toContent)(response);
118
+ const eventsContent = ((_a = response.events) === null || _a === void 0 ? void 0 : _a.map((e) => toText(e))) || [];
119
+ return {
120
+ content: [{ type: "text", text: (0, js_yaml_1.dump)(eventsContent, DUMP_OPTIONS) }],
121
+ };
42
122
  });
43
123
  exports.batch_get_events = (0, tool_1.tool)("crashlytics", {
44
124
  name: "batch_get_events",
@@ -59,11 +139,14 @@ exports.batch_get_events = (0, tool_1.tool)("crashlytics", {
59
139
  requiresAuth: true,
60
140
  },
61
141
  }, async ({ appId, names }) => {
142
+ var _a;
62
143
  if (!appId)
63
144
  return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
64
145
  if (!names || names.length === 0)
65
146
  return (0, util_1.mcpError)(`Must provide event resource names in name parameter.`);
66
147
  const response = await (0, events_1.batchGetEvents)(appId, names);
67
- response.events = response.events ? response.events.map((e) => pruneThreads(e)) : [];
68
- return (0, util_1.toContent)(response);
148
+ const eventsContent = ((_a = response.events) === null || _a === void 0 ? void 0 : _a.map((e) => toText(e))) || [];
149
+ return {
150
+ content: [{ type: "text", text: (0, js_yaml_1.dump)(eventsContent, DUMP_OPTIONS) }],
151
+ };
69
152
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "14.23.0",
3
+ "version": "14.24.0",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -66,7 +66,7 @@
66
66
  "@electric-sql/pglite": "^0.3.3",
67
67
  "@electric-sql/pglite-tools": "^0.2.8",
68
68
  "@google-cloud/cloud-sql-connector": "^1.3.3",
69
- "@google-cloud/pubsub": "^4.11.0",
69
+ "@google-cloud/pubsub": "^5.2.0",
70
70
  "@inquirer/prompts": "^7.4.0",
71
71
  "@modelcontextprotocol/sdk": "^1.10.2",
72
72
  "abort-controller": "^3.0.0",
@@ -2,6 +2,24 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "additionalProperties": false,
4
4
  "definitions": {
5
+ "adminNodeSdk": {
6
+ "additionalProperties": true,
7
+ "type": "object",
8
+ "properties": {
9
+ "outputDir": {
10
+ "type": "string",
11
+ "description": "Path to the directory where generated files should be written to."
12
+ },
13
+ "package": {
14
+ "type": "string",
15
+ "description": "The package name to use for the generated code."
16
+ },
17
+ "packageJSONDir": {
18
+ "type": "string",
19
+ "description": "The directory containing the package.json to install the generated package in."
20
+ }
21
+ }
22
+ },
5
23
  "javascriptSdk": {
6
24
  "additionalProperties": true,
7
25
  "type": "object",
@@ -90,6 +108,18 @@
90
108
  ],
91
109
  "description": "Configuration for a generated Javascript SDK"
92
110
  },
111
+ "adminNodeSdk": {
112
+ "oneOf": [
113
+ { "$ref": "#/definitions/adminNodeSdk" },
114
+ {
115
+ "type": "array",
116
+ "items": {
117
+ "$ref": "#/definitions/adminNodeSdk"
118
+ }
119
+ }
120
+ ],
121
+ "description": "Configuration for a generated Admin Node SDK"
122
+ },
93
123
  "dartSdk": {
94
124
  "oneOf": [
95
125
  { "$ref": "#/definitions/dartSdk" },