firebase-tools 14.23.0 → 14.24.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/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,7 @@ 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();
34
35
  const flutterAppPromises = await Promise.all(pubSpecYamlFiles.map((f) => processFlutterDir(dirPath, f)));
35
36
  const flutterApps = flutterAppPromises.flat();
36
37
  const androidAppPromises = await Promise.all(srcMainFolders.map((f) => processAndroidDir(dirPath, f)));
@@ -41,7 +42,7 @@ async function detectApps(dirPath) {
41
42
  const iosApps = iosAppPromises
42
43
  .flat()
43
44
  .filter((a) => !flutterApps.some((f) => isPathInside(f.directory, a.directory)));
44
- return [...webApps, ...flutterApps, ...androidApps, ...iosApps];
45
+ return [...flutterApps, ...androidApps, ...iosApps, ...adminAndWebApps];
45
46
  }
46
47
  exports.detectApps = detectApps;
47
48
  async function processIosDir(dirPath, filePath) {
@@ -108,14 +109,33 @@ function isPathInside(parent, child) {
108
109
  const relativePath = path.relative(parent, child);
109
110
  return !relativePath.startsWith(`..`);
110
111
  }
111
- async function packageJsonToWebApp(dirPath, packageJsonFile) {
112
+ function getAllDepsFromPackageJson(packageJson) {
113
+ var _a, _b;
114
+ const devDependencies = Object.keys((_a = packageJson.devDependencies) !== null && _a !== void 0 ? _a : {});
115
+ const dependencies = Object.keys((_b = packageJson.dependencies) !== null && _b !== void 0 ? _b : {});
116
+ const allDeps = Array.from(new Set([...devDependencies, ...dependencies]));
117
+ return allDeps;
118
+ }
119
+ exports.getAllDepsFromPackageJson = getAllDepsFromPackageJson;
120
+ async function packageJsonToAdminOrWebApp(dirPath, packageJsonFile) {
112
121
  const fullPath = path.join(dirPath, packageJsonFile);
113
122
  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
- };
123
+ const allDeps = getAllDepsFromPackageJson(packageJson);
124
+ const detectedApps = [];
125
+ if (allDeps.includes("firebase-admin") || allDeps.includes("firebase-functions")) {
126
+ detectedApps.push({
127
+ platform: Platform.ADMIN_NODE,
128
+ directory: path.dirname(packageJsonFile),
129
+ });
130
+ }
131
+ if (allDeps.includes("firebase") || detectedApps.length === 0) {
132
+ detectedApps.push({
133
+ platform: Platform.WEB,
134
+ directory: path.dirname(packageJsonFile),
135
+ frameworks: getFrameworksFromPackageJson(packageJson),
136
+ });
137
+ }
138
+ return detectedApps;
119
139
  }
120
140
  const WEB_FRAMEWORKS = Object.values(Framework);
121
141
  const WEB_FRAMEWORKS_SIGNALS = {
@@ -148,10 +168,7 @@ async function detectAppIdsForPlatform(dirPath, platform) {
148
168
  return allAppIds.flat();
149
169
  }
150
170
  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]));
171
+ const allDeps = getAllDepsFromPackageJson(packageJson);
155
172
  return WEB_FRAMEWORKS.filter((framework) => WEB_FRAMEWORKS_SIGNALS[framework].find((dep) => allDeps.includes(dep)));
156
173
  }
157
174
  function extractAppIdentifiersFlutter(fileContent) {
@@ -228,7 +228,7 @@ class AppDistributionClient {
228
228
  }
229
229
  utils.logSuccess(`Testers removed from group successfully`);
230
230
  }
231
- async createReleaseTest(releaseName, devices, loginCredential, testCaseName) {
231
+ async createReleaseTest(releaseName, devices, aiInstruction, loginCredential, testCaseName) {
232
232
  try {
233
233
  const response = await this.appDistroV1AlphaClient.request({
234
234
  method: "POST",
@@ -237,6 +237,7 @@ class AppDistributionClient {
237
237
  deviceExecutions: devices.map((device) => ({ device })),
238
238
  loginCredential,
239
239
  testCase: testCaseName,
240
+ aiInstructions: aiInstruction,
240
241
  },
241
242
  });
242
243
  return response.body;
@@ -1,16 +1,55 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Distribution = exports.DistributionFileType = void 0;
3
+ exports.awaitTestResults = exports.Distribution = exports.upload = exports.DistributionFileType = void 0;
4
4
  const fs = require("fs-extra");
5
- const error_1 = require("../error");
6
5
  const logger_1 = require("../logger");
7
6
  const pathUtil = require("path");
7
+ const utils = require("../utils");
8
+ const types_1 = require("../appdistribution/types");
9
+ const error_1 = require("../error");
10
+ const TEST_MAX_POLLING_RETRIES = 40;
11
+ const TEST_POLLING_INTERVAL_MILLIS = 30000;
8
12
  var DistributionFileType;
9
13
  (function (DistributionFileType) {
10
14
  DistributionFileType["IPA"] = "ipa";
11
15
  DistributionFileType["APK"] = "apk";
12
16
  DistributionFileType["AAB"] = "aab";
13
17
  })(DistributionFileType = exports.DistributionFileType || (exports.DistributionFileType = {}));
18
+ async function upload(requests, appName, distribution) {
19
+ utils.logBullet("uploading binary...");
20
+ try {
21
+ const operationName = await requests.uploadRelease(appName, distribution);
22
+ const uploadResponse = await requests.pollUploadStatus(operationName);
23
+ const release = uploadResponse.release;
24
+ switch (uploadResponse.result) {
25
+ case types_1.UploadReleaseResult.RELEASE_CREATED:
26
+ utils.logSuccess(`uploaded new release ${release.displayVersion} (${release.buildVersion}) successfully!`);
27
+ break;
28
+ case types_1.UploadReleaseResult.RELEASE_UPDATED:
29
+ utils.logSuccess(`uploaded update to existing release ${release.displayVersion} (${release.buildVersion}) successfully!`);
30
+ break;
31
+ case types_1.UploadReleaseResult.RELEASE_UNMODIFIED:
32
+ utils.logSuccess(`re-uploaded already existing release ${release.displayVersion} (${release.buildVersion}) successfully!`);
33
+ break;
34
+ default:
35
+ utils.logSuccess(`uploaded release ${release.displayVersion} (${release.buildVersion}) successfully!`);
36
+ }
37
+ utils.logSuccess(`View this release in the Firebase console: ${release.firebaseConsoleUri}`);
38
+ utils.logSuccess(`Share this release with testers who have access: ${release.testingUri}`);
39
+ utils.logSuccess(`Download the release binary (link expires in 1 hour): ${release.binaryDownloadUri}`);
40
+ return uploadResponse.release.name;
41
+ }
42
+ catch (err) {
43
+ if ((0, error_1.getErrStatus)(err) === 404) {
44
+ throw new error_1.FirebaseError(`App Distribution could not find your app ${appName}. ` +
45
+ `Make sure to onboard your app by pressing the "Get started" ` +
46
+ "button on the App Distribution page in the Firebase console: " +
47
+ "https://console.firebase.google.com/project/_/appdistribution", { exit: 1 });
48
+ }
49
+ throw new error_1.FirebaseError(`Failed to upload release. ${(0, error_1.getErrMsg)(err)}`, { exit: 1 });
50
+ }
51
+ }
52
+ exports.upload = upload;
14
53
  class Distribution {
15
54
  constructor(path) {
16
55
  this.path = path;
@@ -49,3 +88,47 @@ class Distribution {
49
88
  }
50
89
  }
51
90
  exports.Distribution = Distribution;
91
+ async function awaitTestResults(releaseTests, requests) {
92
+ const releaseTestNames = new Set(releaseTests.map((rt) => rt.name).filter((n) => !!n));
93
+ for (let i = 0; i < TEST_MAX_POLLING_RETRIES; i++) {
94
+ utils.logBullet(`${releaseTestNames.size} automated test results are pending...`);
95
+ await delay(TEST_POLLING_INTERVAL_MILLIS);
96
+ for (const releaseTestName of releaseTestNames) {
97
+ const releaseTest = await requests.getReleaseTest(releaseTestName);
98
+ if (releaseTest.deviceExecutions.every((e) => e.state === "PASSED")) {
99
+ releaseTestNames.delete(releaseTestName);
100
+ if (releaseTestNames.size === 0) {
101
+ utils.logSuccess("Automated test(s) passed!");
102
+ return;
103
+ }
104
+ else {
105
+ continue;
106
+ }
107
+ }
108
+ for (const execution of releaseTest.deviceExecutions) {
109
+ const device = deviceToString(execution.device);
110
+ switch (execution.state) {
111
+ case "PASSED":
112
+ case "IN_PROGRESS":
113
+ continue;
114
+ case "FAILED":
115
+ throw new error_1.FirebaseError(`Automated test failed for ${device}: ${execution.failedReason}`, { exit: 1 });
116
+ case "INCONCLUSIVE":
117
+ throw new error_1.FirebaseError(`Automated test inconclusive for ${device}: ${execution.inconclusiveReason}`, { exit: 1 });
118
+ default:
119
+ throw new error_1.FirebaseError(`Unsupported automated test state for ${device}: ${execution.state}`, { exit: 1 });
120
+ }
121
+ }
122
+ }
123
+ }
124
+ throw new error_1.FirebaseError("It took longer than expected to run your test(s), please try again.", {
125
+ exit: 1,
126
+ });
127
+ }
128
+ exports.awaitTestResults = awaitTestResults;
129
+ function delay(ms) {
130
+ return new Promise((resolve) => setTimeout(resolve, ms));
131
+ }
132
+ function deviceToString(device) {
133
+ return `${device.model} (${device.version}/${device.orientation}/${device.locale})`;
134
+ }
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLoginCredential = exports.parseTestDevices = exports.getAppName = exports.getProjectName = exports.ensureFileExists = exports.getEmails = exports.parseIntoStringArray = void 0;
3
+ exports.getLoginCredential = exports.parseTestDevices = exports.toAppName = exports.getAppName = exports.getProjectName = exports.ensureFileExists = exports.getEmails = exports.parseIntoStringArray = void 0;
4
4
  const fs = require("fs-extra");
5
5
  const error_1 = require("../error");
6
6
  const projectUtils_1 = require("../projectUtils");
7
- function parseIntoStringArray(value, file) {
7
+ function parseIntoStringArray(value, file = "") {
8
8
  if (!value && file) {
9
9
  ensureFileExists(file);
10
10
  value = fs.readFileSync(file, "utf8");
@@ -45,11 +45,14 @@ function getAppName(options) {
45
45
  if (!options.app) {
46
46
  throw new error_1.FirebaseError("set the --app option to a valid Firebase app id and try again");
47
47
  }
48
- const appId = options.app;
49
- return `projects/${appId.split(":")[1]}/apps/${appId}`;
48
+ return toAppName(options.app);
50
49
  }
51
50
  exports.getAppName = getAppName;
52
- function parseTestDevices(value, file) {
51
+ function toAppName(appId) {
52
+ return `projects/${appId.split(":")[1]}/apps/${appId}`;
53
+ }
54
+ exports.toAppName = toAppName;
55
+ function parseTestDevices(value, file = "") {
53
56
  if (!value && file) {
54
57
  ensureFileExists(file);
55
58
  value = fs.readFileSync(file, "utf8");
@@ -3,15 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const fs = require("fs-extra");
5
5
  const command_1 = require("../command");
6
- const utils = require("../utils");
7
6
  const requireAuth_1 = require("../requireAuth");
8
- const client_1 = require("../appdistribution/client");
9
- const types_1 = require("../appdistribution/types");
10
7
  const error_1 = require("../error");
11
8
  const distribution_1 = require("../appdistribution/distribution");
12
9
  const options_parser_util_1 = require("../appdistribution/options-parser-util");
13
- const TEST_MAX_POLLING_RETRIES = 40;
14
- const TEST_POLLING_INTERVAL_MILLIS = 30000;
10
+ const types_1 = require("../appdistribution/types");
11
+ const client_1 = require("../appdistribution/client");
12
+ const utils = require("../utils");
15
13
  function getReleaseNotes(releaseNotes, releaseNotesFile) {
16
14
  if (releaseNotes) {
17
15
  return releaseNotes.replace(/\\n/g, "\n");
@@ -60,6 +58,9 @@ exports.command = new command_1.Command("appdistribution:distribute <release-bin
60
58
  usernameResourceName: options.testUsernameResource,
61
59
  passwordResourceName: options.testPasswordResource,
62
60
  });
61
+ await distribute(appName, distribution, testCases, testDevices, releaseNotes, testers, groups, options.testNonBlocking, loginCredential);
62
+ });
63
+ async function distribute(appName, distribution, testCases, testDevices, releaseNotes, testers, groups, testNonBlocking, loginCredential) {
63
64
  const requests = new client_1.AppDistributionClient();
64
65
  let aabInfo;
65
66
  if (distribution.distributionFileType() === distribution_1.DistributionFileType.AAB) {
@@ -68,7 +69,7 @@ exports.command = new command_1.Command("appdistribution:distribute <release-bin
68
69
  }
69
70
  catch (err) {
70
71
  if ((0, error_1.getErrStatus)(err) === 404) {
71
- throw new error_1.FirebaseError(`App Distribution could not find your app ${options.app}. ` +
72
+ throw new error_1.FirebaseError(`App Distribution could not find your app ${appName}. ` +
72
73
  `Make sure to onboard your app by pressing the "Get started" ` +
73
74
  "button on the App Distribution page in the Firebase console: " +
74
75
  "https://console.firebase.google.com/project/_/appdistribution", { exit: 1 });
@@ -96,39 +97,7 @@ exports.command = new command_1.Command("appdistribution:distribute <release-bin
96
97
  }
97
98
  }
98
99
  }
99
- utils.logBullet("uploading binary...");
100
- let releaseName;
101
- try {
102
- const operationName = await requests.uploadRelease(appName, distribution);
103
- const uploadResponse = await requests.pollUploadStatus(operationName);
104
- const release = uploadResponse.release;
105
- switch (uploadResponse.result) {
106
- case types_1.UploadReleaseResult.RELEASE_CREATED:
107
- utils.logSuccess(`uploaded new release ${release.displayVersion} (${release.buildVersion}) successfully!`);
108
- break;
109
- case types_1.UploadReleaseResult.RELEASE_UPDATED:
110
- utils.logSuccess(`uploaded update to existing release ${release.displayVersion} (${release.buildVersion}) successfully!`);
111
- break;
112
- case types_1.UploadReleaseResult.RELEASE_UNMODIFIED:
113
- utils.logSuccess(`re-uploaded already existing release ${release.displayVersion} (${release.buildVersion}) successfully!`);
114
- break;
115
- default:
116
- utils.logSuccess(`uploaded release ${release.displayVersion} (${release.buildVersion}) successfully!`);
117
- }
118
- utils.logSuccess(`View this release in the Firebase console: ${release.firebaseConsoleUri}`);
119
- utils.logSuccess(`Share this release with testers who have access: ${release.testingUri}`);
120
- utils.logSuccess(`Download the release binary (link expires in 1 hour): ${release.binaryDownloadUri}`);
121
- releaseName = uploadResponse.release.name;
122
- }
123
- catch (err) {
124
- if ((0, error_1.getErrStatus)(err) === 404) {
125
- throw new error_1.FirebaseError(`App Distribution could not find your app ${options.app}. ` +
126
- `Make sure to onboard your app by pressing the "Get started" ` +
127
- "button on the App Distribution page in the Firebase console: " +
128
- "https://console.firebase.google.com/project/_/appdistribution", { exit: 1 });
129
- }
130
- throw new error_1.FirebaseError(`Failed to upload release. ${(0, error_1.getErrMsg)(err)}`, { exit: 1 });
131
- }
100
+ const releaseName = await (0, distribution_1.upload)(requests, appName, distribution);
132
101
  if (aabInfo && !aabInfo.testCertificate) {
133
102
  aabInfo = await requests.getAabInfo(appName);
134
103
  if (aabInfo.testCertificate) {
@@ -147,59 +116,17 @@ exports.command = new command_1.Command("appdistribution:distribute <release-bin
147
116
  utils.logBullet("starting automated test (note: this feature is in beta)");
148
117
  const releaseTestPromises = [];
149
118
  if (!testCases.length) {
150
- releaseTestPromises.push(requests.createReleaseTest(releaseName, testDevices, loginCredential));
119
+ releaseTestPromises.push(requests.createReleaseTest(releaseName, testDevices, undefined, loginCredential));
151
120
  }
152
121
  else {
153
122
  for (const testCaseId of testCases) {
154
- releaseTestPromises.push(requests.createReleaseTest(releaseName, testDevices, loginCredential, `${appName}/testCases/${testCaseId}`));
123
+ releaseTestPromises.push(requests.createReleaseTest(releaseName, testDevices, undefined, loginCredential, `${appName}/testCases/${testCaseId}`));
155
124
  }
156
125
  }
157
126
  const releaseTests = await Promise.all(releaseTestPromises);
158
127
  utils.logSuccess(`${releaseTests.length} release test(s) started successfully`);
159
- if (!options.testNonBlocking) {
160
- await awaitTestResults(releaseTests, requests);
128
+ if (!testNonBlocking) {
129
+ await (0, distribution_1.awaitTestResults)(releaseTests, requests);
161
130
  }
162
131
  }
163
- });
164
- async function awaitTestResults(releaseTests, requests) {
165
- const releaseTestNames = new Set(releaseTests.map((rt) => rt.name));
166
- for (let i = 0; i < TEST_MAX_POLLING_RETRIES; i++) {
167
- utils.logBullet(`${releaseTestNames.size} automated test results are pending...`);
168
- await delay(TEST_POLLING_INTERVAL_MILLIS);
169
- for (const releaseTestName of releaseTestNames) {
170
- const releaseTest = await requests.getReleaseTest(releaseTestName);
171
- if (releaseTest.deviceExecutions.every((e) => e.state === "PASSED")) {
172
- releaseTestNames.delete(releaseTestName);
173
- if (releaseTestNames.size === 0) {
174
- utils.logSuccess("Automated test(s) passed!");
175
- return;
176
- }
177
- else {
178
- continue;
179
- }
180
- }
181
- for (const execution of releaseTest.deviceExecutions) {
182
- switch (execution.state) {
183
- case "PASSED":
184
- case "IN_PROGRESS":
185
- continue;
186
- case "FAILED":
187
- throw new error_1.FirebaseError(`Automated test failed for ${deviceToString(execution.device)}: ${execution.failedReason}`, { exit: 1 });
188
- case "INCONCLUSIVE":
189
- throw new error_1.FirebaseError(`Automated test inconclusive for ${deviceToString(execution.device)}: ${execution.inconclusiveReason}`, { exit: 1 });
190
- default:
191
- throw new error_1.FirebaseError(`Unsupported automated test state for ${deviceToString(execution.device)}: ${execution.state}`, { exit: 1 });
192
- }
193
- }
194
- }
195
- }
196
- throw new error_1.FirebaseError("It took longer than expected to run your test(s), please try again.", {
197
- exit: 1,
198
- });
199
- }
200
- function delay(ms) {
201
- return new Promise((resolve) => setTimeout(resolve, ms));
202
- }
203
- function deviceToString(device) {
204
- return `${device.model} (${device.version}/${device.orientation}/${device.locale})`;
205
132
  }
@@ -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);